Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(389)

Side by Side Diff: media/formats/mp4/avc.cc

Issue 379983002: Fix AnnexB validation logic to work with encrypted content. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698