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/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> |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 continue; | 275 continue; |
276 } | 276 } |
277 size_t desc_idx = traf.header.sample_description_index; | 277 size_t desc_idx = traf.header.sample_description_index; |
278 if (!desc_idx) desc_idx = trex->default_sample_description_index; | 278 if (!desc_idx) desc_idx = trex->default_sample_description_index; |
279 RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file | 279 RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file |
280 desc_idx -= 1; | 280 desc_idx -= 1; |
281 | 281 |
282 const std::vector<uint8_t>& sample_encryption_data = | 282 const std::vector<uint8_t>& sample_encryption_data = |
283 traf.sample_encryption.sample_encryption_data; | 283 traf.sample_encryption.sample_encryption_data; |
284 std::unique_ptr<BufferReader> sample_encryption_reader; | 284 std::unique_ptr<BufferReader> sample_encryption_reader; |
285 uint32_t sample_encrytion_entries_count = 0; | 285 uint32_t sample_encryption_entries_count = 0; |
286 if (!sample_encryption_data.empty()) { | 286 if (!sample_encryption_data.empty()) { |
287 sample_encryption_reader.reset(new BufferReader( | 287 sample_encryption_reader.reset(new BufferReader( |
288 sample_encryption_data.data(), sample_encryption_data.size())); | 288 sample_encryption_data.data(), sample_encryption_data.size())); |
289 RCHECK(sample_encryption_reader->Read4(&sample_encrytion_entries_count)); | 289 RCHECK(sample_encryption_reader->Read4(&sample_encryption_entries_count)); |
290 } | 290 } |
291 | 291 |
292 // Process edit list to remove CTS offset introduced in the presence of | 292 // 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 | 293 // 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 | 294 // time). Other uses of edit lists are not supported, as they are |
295 // both uncommon and better served by higher-level protocols. | 295 // both uncommon and better served by higher-level protocols. |
296 int64_t edit_list_offset = 0; | 296 int64_t edit_list_offset = 0; |
297 const std::vector<EditListEntry>& edits = trak->edit.list.edits; | 297 const std::vector<EditListEntry>& edits = trak->edit.list.edits; |
298 if (!edits.empty()) { | 298 if (!edits.empty()) { |
299 if (edits.size() > 1) | 299 if (edits.size() > 1) |
300 DVLOG(1) << "Multi-entry edit box detected; some components ignored."; | 300 DVLOG(1) << "Multi-entry edit box detected; some components ignored."; |
301 | 301 |
302 if (edits[0].media_time < 0) { | 302 if (edits[0].media_time < 0) { |
303 DVLOG(1) << "Empty edit list entry ignored."; | 303 DVLOG(1) << "Empty edit list entry ignored."; |
304 } else { | 304 } else { |
305 edit_list_offset = -edits[0].media_time; | 305 edit_list_offset = -edits[0].media_time; |
306 } | 306 } |
307 } | 307 } |
308 | 308 |
309 SampleToGroupIterator sample_to_group_itr(traf.sample_to_group); | 309 SampleToGroupIterator sample_to_group_itr(traf.sample_to_group); |
310 bool is_sample_to_group_valid = sample_to_group_itr.IsValid(); | 310 bool is_sample_to_group_valid = sample_to_group_itr.IsValid(); |
311 | 311 |
312 int64_t run_start_dts = traf.decode_time.decode_time; | 312 int64_t run_start_dts = traf.decode_time.decode_time; |
313 int sample_count_sum = 0; | 313 uint64_t sample_count_sum = 0; |
314 for (size_t j = 0; j < traf.runs.size(); j++) { | 314 for (size_t j = 0; j < traf.runs.size(); j++) { |
315 const TrackFragmentRun& trun = traf.runs[j]; | 315 const TrackFragmentRun& trun = traf.runs[j]; |
316 TrackRunInfo tri; | 316 TrackRunInfo tri; |
317 tri.track_id = traf.header.track_id; | 317 tri.track_id = traf.header.track_id; |
318 tri.timescale = trak->media.header.timescale; | 318 tri.timescale = trak->media.header.timescale; |
319 tri.start_dts = run_start_dts; | 319 tri.start_dts = run_start_dts; |
320 tri.sample_start_offset = trun.data_offset; | 320 tri.sample_start_offset = trun.data_offset; |
321 tri.track_sample_encryption_group = | 321 tri.track_sample_encryption_group = |
322 &trak->media.information.sample_table.sample_group_description; | 322 &trak->media.information.sample_table.sample_group_description; |
323 tri.fragment_sample_encryption_info = | 323 tri.fragment_sample_encryption_info = |
(...skipping 11 matching lines...) Expand all Loading... |
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 default_iv_size = |
341 tri.video_description->sinf.info.track_encryption.default_iv_size; | 341 tri.video_description->sinf.info.track_encryption.default_iv_size; |
342 } | 342 } |
343 | 343 |
344 // Initialize aux_info variables only if no sample encryption entries. | 344 // Initialize aux_info variables only if no sample encryption entries. |
345 if (sample_encrytion_entries_count == 0 && | 345 if (sample_encryption_entries_count == 0 && |
346 traf.auxiliary_offset.offsets.size() > j) { | 346 traf.auxiliary_offset.offsets.size() > j) { |
347 // Collect information from the auxiliary_offset entry with the same | 347 // Collect information from the auxiliary_offset entry with the same |
348 // index in the 'saiz' container as the current run's index in the | 348 // index in the 'saiz' container as the current run's index in the |
349 // 'trun' container, if it is present. | 349 // 'trun' container, if it is present. |
350 // There should be an auxiliary info entry corresponding to each sample | 350 // There should be an auxiliary info entry corresponding to each sample |
351 // in the auxiliary offset entry's corresponding track run. | 351 // in the auxiliary offset entry's corresponding track run. |
352 RCHECK(traf.auxiliary_size.sample_count >= | 352 RCHECK(traf.auxiliary_size.sample_count >= |
353 sample_count_sum + trun.sample_count); | 353 sample_count_sum + trun.sample_count); |
354 tri.aux_info_start_offset = traf.auxiliary_offset.offsets[j]; | 354 tri.aux_info_start_offset = traf.auxiliary_offset.offsets[j]; |
355 tri.aux_info_default_size = | 355 tri.aux_info_default_size = |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 tri.samples[k].cenc_group_description_index = 0; | 395 tri.samples[k].cenc_group_description_index = 0; |
396 continue; | 396 continue; |
397 } | 397 } |
398 | 398 |
399 uint32_t index = sample_to_group_itr.group_description_index(); | 399 uint32_t index = sample_to_group_itr.group_description_index(); |
400 tri.samples[k].cenc_group_description_index = index; | 400 tri.samples[k].cenc_group_description_index = index; |
401 if (index != 0) | 401 if (index != 0) |
402 RCHECK(GetSampleEncryptionInfoEntry(tri, index)); | 402 RCHECK(GetSampleEncryptionInfoEntry(tri, index)); |
403 is_sample_to_group_valid = sample_to_group_itr.Advance(); | 403 is_sample_to_group_valid = sample_to_group_itr.Advance(); |
404 } | 404 } |
405 if (sample_encrytion_entries_count > 0) { | 405 if (sample_encryption_entries_count > 0) { |
406 RCHECK(sample_encrytion_entries_count >= | 406 RCHECK(sample_encryption_entries_count >= |
407 sample_count_sum + trun.sample_count); | 407 sample_count_sum + trun.sample_count); |
408 tri.sample_encryption_entries.resize(trun.sample_count); | 408 tri.sample_encryption_entries.resize(trun.sample_count); |
409 for (size_t k = 0; k < trun.sample_count; k++) { | 409 for (size_t k = 0; k < trun.sample_count; k++) { |
410 uint32_t index = tri.samples[k].cenc_group_description_index; | 410 uint32_t index = tri.samples[k].cenc_group_description_index; |
411 const uint8_t iv_size = | 411 const uint8_t iv_size = |
412 index == 0 ? default_iv_size | 412 index == 0 ? default_iv_size |
413 : GetSampleEncryptionInfoEntry(tri, index)->iv_size; | 413 : GetSampleEncryptionInfoEntry(tri, index)->iv_size; |
414 RCHECK(tri.sample_encryption_entries[k].Parse( | 414 RCHECK(tri.sample_encryption_entries[k].Parse( |
415 sample_encryption_reader.get(), iv_size, | 415 sample_encryption_reader.get(), iv_size, |
416 traf.sample_encryption.use_subsample_encryption)); | 416 traf.sample_encryption.use_subsample_encryption)); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 } | 643 } |
644 | 644 |
645 uint8_t TrackRunIterator::GetIvSize(size_t sample_index) const { | 645 uint8_t TrackRunIterator::GetIvSize(size_t sample_index) const { |
646 uint32_t index = GetGroupDescriptionIndex(sample_index); | 646 uint32_t index = GetGroupDescriptionIndex(sample_index); |
647 return (index == 0) ? track_encryption().default_iv_size | 647 return (index == 0) ? track_encryption().default_iv_size |
648 : GetSampleEncryptionInfoEntry(*run_itr_, index)->iv_size; | 648 : GetSampleEncryptionInfoEntry(*run_itr_, index)->iv_size; |
649 } | 649 } |
650 | 650 |
651 } // namespace mp4 | 651 } // namespace mp4 |
652 } // namespace media | 652 } // namespace media |
OLD | NEW |