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

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

Issue 1998333002: MP4 support for Common Encryption 'cbcs' scheme. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix a problem in hasty change before upload Created 4 years, 7 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/track_run_iterator.h" 5 #include "media/formats/mp4/track_run_iterator.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iomanip> 8 #include <iomanip>
9 #include <limits> 9 #include <limits>
10 #include <memory> 10 #include <memory>
11 11
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "media/formats/mp4/rcheck.h" 13 #include "media/formats/mp4/rcheck.h"
14 #include "media/formats/mp4/sample_to_group_iterator.h" 14 #include "media/formats/mp4/sample_to_group_iterator.h"
15 #include "media/media_features.h"
15 16
16 namespace media { 17 namespace media {
17 namespace mp4 { 18 namespace mp4 {
18 19
19 struct SampleInfo { 20 struct SampleInfo {
20 int size; 21 int size;
21 int duration; 22 int duration;
22 int cts_offset; 23 int cts_offset;
23 bool is_keyframe; 24 bool is_keyframe;
24 uint32_t cenc_group_description_index; 25 uint32_t cenc_group_description_index;
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 continue; 276 continue;
276 } 277 }
277 size_t desc_idx = traf.header.sample_description_index; 278 size_t desc_idx = traf.header.sample_description_index;
278 if (!desc_idx) desc_idx = trex->default_sample_description_index; 279 if (!desc_idx) desc_idx = trex->default_sample_description_index;
279 RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file 280 RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file
280 desc_idx -= 1; 281 desc_idx -= 1;
281 282
282 const std::vector<uint8_t>& sample_encryption_data = 283 const std::vector<uint8_t>& sample_encryption_data =
283 traf.sample_encryption.sample_encryption_data; 284 traf.sample_encryption.sample_encryption_data;
284 std::unique_ptr<BufferReader> sample_encryption_reader; 285 std::unique_ptr<BufferReader> sample_encryption_reader;
285 uint32_t sample_encrytion_entries_count = 0; 286 uint32_t sample_encryption_entries_count = 0;
286 if (!sample_encryption_data.empty()) { 287 if (!sample_encryption_data.empty()) {
287 sample_encryption_reader.reset(new BufferReader( 288 sample_encryption_reader.reset(new BufferReader(
288 sample_encryption_data.data(), sample_encryption_data.size())); 289 sample_encryption_data.data(), sample_encryption_data.size()));
289 RCHECK(sample_encryption_reader->Read4(&sample_encrytion_entries_count)); 290 RCHECK(sample_encryption_reader->Read4(&sample_encryption_entries_count));
290 } 291 }
291 292
292 // Process edit list to remove CTS offset introduced in the presence of 293 // Process edit list to remove CTS offset introduced in the presence of
293 // B-frames (those that contain a single edit with a nonnegative media 294 // B-frames (those that contain a single edit with a nonnegative media
294 // time). Other uses of edit lists are not supported, as they are 295 // time). Other uses of edit lists are not supported, as they are
295 // both uncommon and better served by higher-level protocols. 296 // both uncommon and better served by higher-level protocols.
296 int64_t edit_list_offset = 0; 297 int64_t edit_list_offset = 0;
297 const std::vector<EditListEntry>& edits = trak->edit.list.edits; 298 const std::vector<EditListEntry>& edits = trak->edit.list.edits;
298 if (!edits.empty()) { 299 if (!edits.empty()) {
299 if (edits.size() > 1) 300 if (edits.size() > 1)
(...skipping 16 matching lines...) Expand all
316 TrackRunInfo tri; 317 TrackRunInfo tri;
317 tri.track_id = traf.header.track_id; 318 tri.track_id = traf.header.track_id;
318 tri.timescale = trak->media.header.timescale; 319 tri.timescale = trak->media.header.timescale;
319 tri.start_dts = run_start_dts; 320 tri.start_dts = run_start_dts;
320 tri.sample_start_offset = trun.data_offset; 321 tri.sample_start_offset = trun.data_offset;
321 tri.track_sample_encryption_group = 322 tri.track_sample_encryption_group =
322 &trak->media.information.sample_table.sample_group_description; 323 &trak->media.information.sample_table.sample_group_description;
323 tri.fragment_sample_encryption_info = 324 tri.fragment_sample_encryption_info =
324 traf.sample_group_description.entries; 325 traf.sample_group_description.entries;
325 326
326 uint8_t default_iv_size = 0; 327 const TrackEncryption* track_encryption;
327 tri.is_audio = (stsd.type == kAudio); 328 tri.is_audio = (stsd.type == kAudio);
328 if (tri.is_audio) { 329 if (tri.is_audio) {
329 RCHECK(!stsd.audio_entries.empty()); 330 RCHECK(!stsd.audio_entries.empty());
330 if (desc_idx > stsd.audio_entries.size()) 331 if (desc_idx > stsd.audio_entries.size())
331 desc_idx = 0; 332 desc_idx = 0;
332 tri.audio_description = &stsd.audio_entries[desc_idx]; 333 tri.audio_description = &stsd.audio_entries[desc_idx];
333 default_iv_size = 334 track_encryption = &tri.audio_description->sinf.info.track_encryption;
334 tri.audio_description->sinf.info.track_encryption.default_iv_size;
335 } else { 335 } else {
336 RCHECK(!stsd.video_entries.empty()); 336 RCHECK(!stsd.video_entries.empty());
337 if (desc_idx > stsd.video_entries.size()) 337 if (desc_idx > stsd.video_entries.size())
338 desc_idx = 0; 338 desc_idx = 0;
339 tri.video_description = &stsd.video_entries[desc_idx]; 339 tri.video_description = &stsd.video_entries[desc_idx];
340 default_iv_size = 340 track_encryption = &tri.video_description->sinf.info.track_encryption;
341 tri.video_description->sinf.info.track_encryption.default_iv_size;
342 } 341 }
343
344 // Initialize aux_info variables only if no sample encryption entries. 342 // Initialize aux_info variables only if no sample encryption entries.
345 if (sample_encrytion_entries_count == 0 && 343 if (sample_encryption_entries_count == 0 &&
346 traf.auxiliary_offset.offsets.size() > j) { 344 traf.auxiliary_offset.offsets.size() > j) {
347 // Collect information from the auxiliary_offset entry with the same 345 // Collect information from the auxiliary_offset entry with the same
348 // index in the 'saiz' container as the current run's index in the 346 // index in the 'saiz' container as the current run's index in the
349 // 'trun' container, if it is present. 347 // 'trun' container, if it is present.
350 // There should be an auxiliary info entry corresponding to each sample 348 // There should be an auxiliary info entry corresponding to each sample
351 // in the auxiliary offset entry's corresponding track run. 349 // in the auxiliary offset entry's corresponding track run.
352 RCHECK(traf.auxiliary_size.sample_count >= 350 RCHECK(traf.auxiliary_size.sample_count >=
353 sample_count_sum + trun.sample_count); 351 sample_count_sum + trun.sample_count);
354 tri.aux_info_start_offset = traf.auxiliary_offset.offsets[j]; 352 tri.aux_info_start_offset = traf.auxiliary_offset.offsets[j];
355 tri.aux_info_default_size = 353 tri.aux_info_default_size =
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 tri.samples[k].cenc_group_description_index = 0; 393 tri.samples[k].cenc_group_description_index = 0;
396 continue; 394 continue;
397 } 395 }
398 396
399 uint32_t index = sample_to_group_itr.group_description_index(); 397 uint32_t index = sample_to_group_itr.group_description_index();
400 tri.samples[k].cenc_group_description_index = index; 398 tri.samples[k].cenc_group_description_index = index;
401 if (index != 0) 399 if (index != 0)
402 RCHECK(GetSampleEncryptionInfoEntry(tri, index)); 400 RCHECK(GetSampleEncryptionInfoEntry(tri, index));
403 is_sample_to_group_valid = sample_to_group_itr.Advance(); 401 is_sample_to_group_valid = sample_to_group_itr.Advance();
404 } 402 }
405 if (sample_encrytion_entries_count > 0) { 403 if (sample_encryption_entries_count > 0) {
406 RCHECK(sample_encrytion_entries_count >= 404 RCHECK(sample_encryption_entries_count >=
407 sample_count_sum + trun.sample_count); 405 sample_count_sum + trun.sample_count);
408 tri.sample_encryption_entries.resize(trun.sample_count); 406 tri.sample_encryption_entries.resize(trun.sample_count);
409 for (size_t k = 0; k < trun.sample_count; k++) { 407 for (size_t k = 0; k < trun.sample_count; k++) {
410 uint32_t index = tri.samples[k].cenc_group_description_index; 408 uint32_t index = tri.samples[k].cenc_group_description_index;
411 const uint8_t iv_size = 409 const CencSampleEncryptionInfoEntry* info_entry =
412 index == 0 ? default_iv_size 410 index == 0 ? nullptr : GetSampleEncryptionInfoEntry(tri, index);
413 : GetSampleEncryptionInfoEntry(tri, index)->iv_size; 411 const uint8_t iv_size = index == 0 ? track_encryption->default_iv_size
414 RCHECK(tri.sample_encryption_entries[k].Parse( 412 : info_entry->iv_size;
415 sample_encryption_reader.get(), iv_size, 413 SampleEncryptionEntry& entry = tri.sample_encryption_entries[k];
416 traf.sample_encryption.use_subsample_encryption)); 414 RCHECK(entry.Parse(sample_encryption_reader.get(), iv_size,
415 traf.sample_encryption.use_subsample_encryption));
416 #if BUILDFLAG(ENABLE_CENC_NEW_EDITIONS)
417 // if we don't have a per-sample IV, get the constant IV.
418 if (!iv_size) {
419 const uint8_t constant_iv_size =
420 index == 0 ? track_encryption->default_constant_iv_size
421 : info_entry->constant_iv_size;
422 const uint8_t* constant_iv =
423 index == 0 ? track_encryption->default_constant_iv
424 : info_entry->constant_iv;
kqyang 2016/05/23 20:57:34 Add a RCHECK or DCHECK that constant_iv_size != 0?
dougsteed 2016/05/25 17:23:21 Done.
425 memcpy(entry.initialization_vector, constant_iv, constant_iv_size);
426 }
427 // We only support setting the pattern values in the 'tenc' box for
428 // the track (not varying on per sample group basis).
429 // Thus we need to verify that the settings in the sample group match
430 // those in the 'tenc'.
431 RCHECK(info_entry->crypt_byte_block ==
432 track_encryption->default_crypt_byte_block);
433 RCHECK(info_entry->skip_byte_block ==
434 track_encryption->default_skip_byte_block);
kqyang 2016/05/23 20:57:34 The two RCHECKs should be enclosed in index != 0 o
dougsteed 2016/05/25 17:23:21 good catch, thank you.
435 #endif
417 } 436 }
418 } 437 }
419 runs_.push_back(tri); 438 runs_.push_back(tri);
420 sample_count_sum += trun.sample_count; 439 sample_count_sum += trun.sample_count;
421 } 440 }
422 441
423 // We should have iterated through all samples in SampleToGroup Box. 442 // We should have iterated through all samples in SampleToGroup Box.
424 RCHECK(!sample_to_group_itr.IsValid()); 443 RCHECK(!sample_to_group_itr.IsValid());
425 } 444 }
426 445
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 } 662 }
644 663
645 uint8_t TrackRunIterator::GetIvSize(size_t sample_index) const { 664 uint8_t TrackRunIterator::GetIvSize(size_t sample_index) const {
646 uint32_t index = GetGroupDescriptionIndex(sample_index); 665 uint32_t index = GetGroupDescriptionIndex(sample_index);
647 return (index == 0) ? track_encryption().default_iv_size 666 return (index == 0) ? track_encryption().default_iv_size
648 : GetSampleEncryptionInfoEntry(*run_itr_, index)->iv_size; 667 : GetSampleEncryptionInfoEntry(*run_itr_, index)->iv_size;
649 } 668 }
650 669
651 } // namespace mp4 670 } // namespace mp4
652 } // namespace media 671 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698