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 "media/formats/mp4/avc.h" | 5 #include "media/formats/mp4/avc.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 temp.begin() + pos + nal_size); | 69 temp.begin() + pos + nal_size); |
70 pos += nal_size; | 70 pos += nal_size; |
71 } | 71 } |
72 return pos == temp.size(); | 72 return pos == temp.size(); |
73 } | 73 } |
74 | 74 |
75 // static | 75 // static |
76 bool AVC::InsertParamSetsAnnexB(const AVCDecoderConfigurationRecord& avc_config, | 76 bool AVC::InsertParamSetsAnnexB(const AVCDecoderConfigurationRecord& avc_config, |
77 std::vector<uint8>* buffer, | 77 std::vector<uint8>* buffer, |
78 std::vector<SubsampleEntry>* subsamples) { | 78 std::vector<SubsampleEntry>* subsamples) { |
79 DCHECK(AVC::IsValidAnnexB(*buffer)); | 79 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); |
80 | 80 |
81 scoped_ptr<H264Parser> parser(new H264Parser()); | 81 scoped_ptr<H264Parser> parser(new H264Parser()); |
82 const uint8* start = &(*buffer)[0]; | 82 const uint8* start = &(*buffer)[0]; |
83 parser->SetStream(start, buffer->size()); | 83 parser->SetStream(start, buffer->size(), *subsamples); |
84 | 84 |
85 H264NALU nalu; | 85 H264NALU nalu; |
86 if (parser->AdvanceToNextNALU(&nalu) != H264Parser::kOk) | 86 if (parser->AdvanceToNextNALU(&nalu) != H264Parser::kOk) |
87 return false; | 87 return false; |
88 | 88 |
89 std::vector<uint8>::iterator config_insert_point = buffer->begin(); | 89 std::vector<uint8>::iterator config_insert_point = buffer->begin(); |
90 std::vector<SubsampleEntry>::iterator subsamples_insert_point = | 90 std::vector<SubsampleEntry>::iterator subsamples_insert_point = |
91 subsamples->begin(); | 91 subsamples->begin(); |
92 | 92 |
93 if (nalu.nal_unit_type == H264NALU::kAUD) { | 93 if (nalu.nal_unit_type == H264NALU::kAUD) { |
(...skipping 25 matching lines...) Expand all Loading... | |
119 | 119 |
120 if (!subsamples->empty()) { | 120 if (!subsamples->empty()) { |
121 subsamples->insert(subsamples_insert_point, | 121 subsamples->insert(subsamples_insert_point, |
122 config_subsamples.begin(), | 122 config_subsamples.begin(), |
123 config_subsamples.end()); | 123 config_subsamples.end()); |
124 } | 124 } |
125 | 125 |
126 buffer->insert(config_insert_point, | 126 buffer->insert(config_insert_point, |
127 param_sets.begin(), param_sets.end()); | 127 param_sets.begin(), param_sets.end()); |
128 | 128 |
129 DCHECK(AVC::IsValidAnnexB(*buffer)); | 129 DCHECK(AVC::IsValidAnnexB(*buffer, *subsamples)); |
130 return true; | 130 return true; |
131 } | 131 } |
132 | 132 |
133 // static | 133 // static |
134 bool AVC::ConvertConfigToAnnexB( | 134 bool AVC::ConvertConfigToAnnexB( |
135 const AVCDecoderConfigurationRecord& avc_config, | 135 const AVCDecoderConfigurationRecord& avc_config, |
136 std::vector<uint8>* buffer, | 136 std::vector<uint8>* buffer, |
137 std::vector<SubsampleEntry>* subsamples) { | 137 std::vector<SubsampleEntry>* subsamples) { |
138 DCHECK(buffer->empty()); | 138 DCHECK(buffer->empty()); |
139 buffer->clear(); | 139 buffer->clear(); |
(...skipping 24 matching lines...) Expand all Loading... | |
164 | 164 |
165 SubsampleEntry entry; | 165 SubsampleEntry entry; |
166 entry.clear_bytes = kAnnexBStartCodeSize + avc_config.pps_list[i].size(); | 166 entry.clear_bytes = kAnnexBStartCodeSize + avc_config.pps_list[i].size(); |
167 entry.cypher_bytes = 0; | 167 entry.cypher_bytes = 0; |
168 subsamples->push_back(entry); | 168 subsamples->push_back(entry); |
169 } | 169 } |
170 return true; | 170 return true; |
171 } | 171 } |
172 | 172 |
173 // Verifies AnnexB NALU order according to ISO/IEC 14496-10 Section 7.4.1.2.3 | 173 // Verifies AnnexB NALU order according to ISO/IEC 14496-10 Section 7.4.1.2.3 |
174 bool AVC::IsValidAnnexB(const std::vector<uint8>& buffer) { | 174 bool AVC::IsValidAnnexB(const std::vector<uint8>& buffer, |
175 return IsValidAnnexB(&buffer[0], buffer.size()); | 175 const std::vector<SubsampleEntry>& subsamples) { |
176 return IsValidAnnexB(&buffer[0], buffer.size(), subsamples); | |
176 } | 177 } |
177 | 178 |
178 bool AVC::IsValidAnnexB(const uint8* buffer, size_t size) { | 179 bool AVC::IsValidAnnexB(const uint8* buffer, size_t size, |
180 const std::vector<SubsampleEntry>& subsamples) { | |
179 DVLOG(1) << __FUNCTION__; | 181 DVLOG(1) << __FUNCTION__; |
180 DCHECK(buffer); | 182 DCHECK(buffer); |
181 | 183 |
182 if (size == 0) | 184 if (size == 0) |
183 return true; | 185 return true; |
184 | 186 |
185 H264Parser parser; | 187 H264Parser parser; |
186 parser.SetStream(buffer, size); | 188 parser.SetStream(buffer, size, subsamples); |
187 | 189 |
188 typedef enum { | 190 typedef enum { |
189 kAUDAllowed, | 191 kAUDAllowed, |
190 kBeforeFirstVCL, // VCL == nal_unit_types 1-5 | 192 kBeforeFirstVCL, // VCL == nal_unit_types 1-5 |
191 kAfterFirstVCL, | 193 kAfterFirstVCL, |
192 kEOStreamAllowed, | 194 kEOStreamAllowed, |
193 kNoMoreDataAllowed, | 195 kNoMoreDataAllowed, |
194 } NALUOrderState; | 196 } NALUOrderState; |
195 | 197 |
196 H264NALU nalu; | 198 H264NALU nalu; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 NOTREACHED() << "AdvanceToNextNALU() returned kUnsupportedStream!"; | 300 NOTREACHED() << "AdvanceToNextNALU() returned kUnsupportedStream!"; |
299 return false; | 301 return false; |
300 | 302 |
301 case H264Parser::kEOStream: | 303 case H264Parser::kEOStream: |
302 done = true; | 304 done = true; |
303 } | 305 } |
304 } | 306 } |
305 | 307 |
306 return order_state >= kAfterFirstVCL; | 308 return order_state >= kAfterFirstVCL; |
307 } | 309 } |
310 /* | |
311 AVC::NALUIterator::NALUIterator(const uint8* buffer, size_t size, | |
xhwang
2014/07/10 06:23:01
Remove?
acolwell GONE FROM CHROMIUM
2014/07/15 22:10:44
Oops. Done.
| |
312 const std::vector<SubsampleEntry>& subsamples) | |
313 : buffer_(buffer), | |
314 subsamples_(subsamples), | |
315 subsample_index_(0), | |
316 subsample_offset_(0) { | |
317 parser_.SetStream(buffer, size); | |
318 } | |
308 | 319 |
320 AVC::NALUIterator::Result AVC::NALUIterator::AdvanceToNextNALU(H264NALU* nalu) { | |
321 for (;;) { | |
322 switch (parser_.AdvanceToNextNALU(nalu)) { | |
323 case H264Parser::kOk : { | |
324 if (subsamples_.empty()) | |
325 return NALUIterator::OK; | |
326 | |
327 // Compute the offset of they type field. | |
328 size_t nalu_type_offset = (nalu->data - buffer_); | |
329 bool is_inside_encrypted_section = false; | |
330 for(;;) { | |
331 if (subsample_index_ >= subsamples_.size()) { | |
332 DVLOG(1) << "Went beyond the end of the subsample info."; | |
333 return NALUIterator::ERROR; | |
334 } | |
335 | |
336 size_t encrypted_start_offset = | |
337 subsample_offset_ + subsamples_[subsample_index_].clear_bytes; | |
338 size_t subsample_end_offset = encrypted_start_offset + | |
339 subsamples_[subsample_index_].cypher_bytes; | |
340 | |
341 if (nalu_type_offset >= subsample_end_offset) { | |
342 // |nalu_type_offset| is beyond the current subsample. Move | |
343 // on to the next one. | |
344 subsample_offset_ = subsample_end_offset; | |
345 subsample_index_++; | |
346 continue; | |
347 } | |
348 | |
349 is_inside_encrypted_section = | |
350 (nalu_type_offset >= encrypted_start_offset && | |
351 nalu_type_offset < subsample_end_offset); | |
352 break; | |
353 } | |
354 | |
355 if (is_inside_encrypted_section) { | |
356 DVLOG(1) << "Detected a start code inside an encrypted section." | |
357 << " Looking for the next start code."; | |
358 continue; | |
359 } | |
360 | |
361 return NALUIterator::OK; | |
362 } break; | |
363 | |
364 case H264Parser::kInvalidStream: | |
365 return NALUIterator::ERROR; | |
366 | |
367 case H264Parser::kUnsupportedStream: | |
368 return NALUIterator::ERROR; | |
369 | |
370 case H264Parser::kEOStream: | |
371 return END_OF_STREAM; | |
372 } | |
373 } | |
374 | |
375 return NALUIterator::OK; | |
376 } | |
377 */ | |
309 } // namespace mp4 | 378 } // namespace mp4 |
310 } // namespace media | 379 } // namespace media |
OLD | NEW |