OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/logging.h" | 5 #include "base/logging.h" |
6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 | 8 |
9 #include "media/base/decrypt_config.h" | |
9 #include "media/filters/h264_parser.h" | 10 #include "media/filters/h264_parser.h" |
10 | 11 |
11 namespace media { | 12 namespace media { |
12 | 13 |
13 bool H264SliceHeader::IsPSlice() const { | 14 bool H264SliceHeader::IsPSlice() const { |
14 return (slice_type % 5 == kPSlice); | 15 return (slice_type % 5 == kPSlice); |
15 } | 16 } |
16 | 17 |
17 bool H264SliceHeader::IsBSlice() const { | 18 bool H264SliceHeader::IsBSlice() const { |
18 return (slice_type % 5 == kBSlice); | 19 return (slice_type % 5 == kBSlice); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 } | 123 } |
123 | 124 |
124 H264Parser::~H264Parser() { | 125 H264Parser::~H264Parser() { |
125 STLDeleteValues(&active_SPSes_); | 126 STLDeleteValues(&active_SPSes_); |
126 STLDeleteValues(&active_PPSes_); | 127 STLDeleteValues(&active_PPSes_); |
127 } | 128 } |
128 | 129 |
129 void H264Parser::Reset() { | 130 void H264Parser::Reset() { |
130 stream_ = NULL; | 131 stream_ = NULL; |
131 bytes_left_ = 0; | 132 bytes_left_ = 0; |
133 clear_ranges_.clear(); | |
134 clear_range_index_ = 0; | |
132 } | 135 } |
133 | 136 |
134 void H264Parser::SetStream(const uint8* stream, off_t stream_size) { | 137 void H264Parser::SetStream(const uint8* stream, off_t stream_size) { |
138 std::vector<SubsampleEntry> subsamples; | |
139 SetEncryptedStream(stream, stream_size, subsamples); | |
140 } | |
141 | |
142 void H264Parser::SetEncryptedStream( | |
143 const uint8* stream, off_t stream_size, | |
144 const std::vector<SubsampleEntry>& subsamples) { | |
135 DCHECK(stream); | 145 DCHECK(stream); |
136 DCHECK_GT(stream_size, 0); | 146 DCHECK_GT(stream_size, 0); |
137 | 147 |
138 stream_ = stream; | 148 stream_ = stream; |
139 bytes_left_ = stream_size; | 149 bytes_left_ = stream_size; |
150 | |
151 clear_ranges_.clear(); | |
152 clear_range_index_ = 0; | |
153 const uint8* start = stream; | |
154 const uint8* stream_end = stream_ + bytes_left_; | |
155 for (size_t i = 0; i < subsamples.size() && start < stream_end; ++i) { | |
156 const uint8* end = std::min(start + subsamples[i].clear_bytes, stream_end); | |
xhwang
2014/07/16 05:06:13
It seems possible that
start + subsamples[i].clear
acolwell GONE FROM CHROMIUM
2014/07/28 19:43:12
This is to protect this code from invalid subsampl
| |
157 clear_ranges_.Add(start, end); | |
158 start += subsamples[i].clear_bytes + subsamples[i].cypher_bytes; | |
159 } | |
140 } | 160 } |
141 | 161 |
142 const H264PPS* H264Parser::GetPPS(int pps_id) { | 162 const H264PPS* H264Parser::GetPPS(int pps_id) { |
143 return active_PPSes_[pps_id]; | 163 return active_PPSes_[pps_id]; |
144 } | 164 } |
145 | 165 |
146 const H264SPS* H264Parser::GetSPS(int sps_id) { | 166 const H264SPS* H264Parser::GetSPS(int sps_id) { |
147 return active_SPSes_[sps_id]; | 167 return active_SPSes_[sps_id]; |
148 } | 168 } |
149 | 169 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 // |*offset| is equal to 0 (valid offset). | 204 // |*offset| is equal to 0 (valid offset). |
185 *offset = data_size - bytes_left; | 205 *offset = data_size - bytes_left; |
186 *start_code_size = 0; | 206 *start_code_size = 0; |
187 return false; | 207 return false; |
188 } | 208 } |
189 | 209 |
190 bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) { | 210 bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) { |
191 // Find the start code of next NALU. | 211 // Find the start code of next NALU. |
192 off_t nalu_start_off = 0; | 212 off_t nalu_start_off = 0; |
193 off_t annexb_start_code_size = 0; | 213 off_t annexb_start_code_size = 0; |
194 if (!FindStartCode(stream_, bytes_left_, | 214 |
195 &nalu_start_off, &annexb_start_code_size)) { | 215 if (!FindStartCodeInClearRanges(stream_, bytes_left_, |
216 &nalu_start_off, &annexb_start_code_size)) { | |
196 DVLOG(4) << "Could not find start code, end of stream?"; | 217 DVLOG(4) << "Could not find start code, end of stream?"; |
197 return false; | 218 return false; |
198 } | 219 } |
199 | 220 |
200 // Move the stream to the beginning of the NALU (pointing at the start code). | 221 // Move the stream to the beginning of the NALU (pointing at the start code). |
201 stream_ += nalu_start_off; | 222 stream_ += nalu_start_off; |
202 bytes_left_ -= nalu_start_off; | 223 bytes_left_ -= nalu_start_off; |
203 | 224 |
204 const uint8* nalu_data = stream_ + annexb_start_code_size; | 225 const uint8* nalu_data = stream_ + annexb_start_code_size; |
205 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; | 226 off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size; |
206 if (max_nalu_data_size <= 0) { | 227 if (max_nalu_data_size <= 0) { |
207 DVLOG(3) << "End of stream"; | 228 DVLOG(3) << "End of stream"; |
208 return false; | 229 return false; |
209 } | 230 } |
210 | 231 |
211 // Find the start code of next NALU; | 232 // Find the start code of next NALU; |
212 // if successful, |nalu_size_without_start_code| is the number of bytes from | 233 // if successful, |nalu_size_without_start_code| is the number of bytes from |
213 // after previous start code to before this one; | 234 // after previous start code to before this one; |
214 // if next start code is not found, it is still a valid NALU since there | 235 // if next start code is not found, it is still a valid NALU since there |
215 // are some bytes left after the first start code: all the remaining bytes | 236 // are some bytes left after the first start code: all the remaining bytes |
216 // belong to the current NALU. | 237 // belong to the current NALU. |
217 off_t next_start_code_size = 0; | 238 off_t next_start_code_size = 0; |
218 off_t nalu_size_without_start_code = 0; | 239 off_t nalu_size_without_start_code = 0; |
219 if (!FindStartCode(nalu_data, max_nalu_data_size, | 240 if (!FindStartCodeInClearRanges(nalu_data, max_nalu_data_size, |
220 &nalu_size_without_start_code, &next_start_code_size)) { | 241 &nalu_size_without_start_code, |
242 &next_start_code_size)) { | |
221 nalu_size_without_start_code = max_nalu_data_size; | 243 nalu_size_without_start_code = max_nalu_data_size; |
222 } | 244 } |
223 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; | 245 *nalu_size = nalu_size_without_start_code + annexb_start_code_size; |
224 *start_code_size = annexb_start_code_size; | 246 *start_code_size = annexb_start_code_size; |
225 return true; | 247 return true; |
226 } | 248 } |
227 | 249 |
250 bool H264Parser::FindStartCodeInClearRanges( | |
damienv1
2014/07/16 14:33:17
The likelihood of a start code emulation (although
acolwell GONE FROM CHROMIUM
2014/07/28 19:43:12
I've restored the code to what I had in Patch Set
| |
251 const uint8* data, | |
252 off_t data_size, | |
253 off_t* offset, | |
254 off_t* start_code_size) { | |
255 if (clear_ranges_.size() == 0) | |
256 return FindStartCode(data, data_size, offset, start_code_size); | |
xhwang
2014/07/16 05:06:13
If there's no clear ranges, we don't need to searc
acolwell GONE FROM CHROMIUM
2014/07/28 19:43:12
Yes. A lack of clear ranges, or now encrypted rang
| |
257 | |
258 if (clear_range_index_ >= clear_ranges_.size()) | |
259 return false; | |
260 | |
261 DCHECK_GE(data_size, 0); | |
262 const uint8* start = data; | |
263 const uint8* end = data + data_size; | |
264 while (start < end) { | |
265 while (start >= clear_ranges_.end(clear_range_index_)) { | |
266 clear_range_index_++; | |
267 if (clear_range_index_ >= clear_ranges_.size()) | |
268 return false; | |
269 if (start < clear_ranges_.start(clear_range_index_)) | |
270 start = clear_ranges_.start(clear_range_index_); | |
271 } | |
xhwang
2014/07/16 05:06:13
This seems complicated. Can you add some comments
acolwell GONE FROM CHROMIUM
2014/07/28 19:43:12
Code is no longer here anymore.
| |
272 | |
273 DCHECK_LT(start, end); | |
274 DCHECK_GE(start, clear_ranges_.start(clear_range_index_)); | |
275 DCHECK_LT(start, clear_ranges_.end(clear_range_index_)); | |
276 off_t clear_bytes_left = | |
277 clear_ranges_.end(clear_range_index_) - start; | |
278 off_t bytes_left = std::min(end - start, clear_bytes_left); | |
279 | |
280 if (FindStartCode(start, bytes_left, offset, start_code_size)) | |
281 break; | |
282 | |
283 start += bytes_left; | |
284 } | |
285 | |
286 if (start >= end) | |
287 return false; | |
288 | |
289 // Update |*offset| to include the data we skipped over. | |
290 *offset += start - data; | |
291 return true; | |
292 } | |
293 | |
228 H264Parser::Result H264Parser::ReadUE(int* val) { | 294 H264Parser::Result H264Parser::ReadUE(int* val) { |
229 int num_bits = -1; | 295 int num_bits = -1; |
230 int bit; | 296 int bit; |
231 int rest; | 297 int rest; |
232 | 298 |
233 // Count the number of contiguous zero bits. | 299 // Count the number of contiguous zero bits. |
234 do { | 300 do { |
235 READ_BITS_OR_RETURN(1, &bit); | 301 READ_BITS_OR_RETURN(1, &bit); |
236 num_bits++; | 302 num_bits++; |
237 } while (bit == 0); | 303 } while (bit == 0); |
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1251 | 1317 |
1252 default: | 1318 default: |
1253 DVLOG(4) << "Unsupported SEI message"; | 1319 DVLOG(4) << "Unsupported SEI message"; |
1254 break; | 1320 break; |
1255 } | 1321 } |
1256 | 1322 |
1257 return kOk; | 1323 return kOk; |
1258 } | 1324 } |
1259 | 1325 |
1260 } // namespace media | 1326 } // namespace media |
OLD | NEW |