15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/mp4/track_run_iterator.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/buffers.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/mp4/rcheck.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "media/formats/mp4/sample_to_group_iterator.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace mp4 { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SampleInfo { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int duration; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cts_offset; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_keyframe; 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool is_random_access_point; 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 cenc_group_description_index; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct TrackRunInfo { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 track_id; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SampleInfo> samples; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 timescale; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 start_dts; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 sample_start_offset; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_audio; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AudioSampleEntry* audio_description; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const VideoSampleEntry* video_description; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 aux_info_start_offset; // Only valid if aux_info_total_size > 0. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int aux_info_default_size; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<uint8> aux_info_sizes; // Populated if default_size == 0. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int aux_info_total_size; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::vector<CencSampleEncryptionInfoEntry> sample_encryption_info; 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrackRunInfo(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TrackRunInfo(); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrackRunInfo::TrackRunInfo() 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : track_id(0), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timescale(-1), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_dts(-1), 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_start_offset(-1), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_audio(false), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aux_info_start_offset(-1), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aux_info_default_size(-1), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aux_info_total_size(-1) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrackRunInfo::~TrackRunInfo() {} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)base::TimeDelta TimeDeltaFromRational(int64 numer, int64 denom) { 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // To avoid overflow, split the following calculation: 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (numer * base::Time::kMicrosecondsPerSecond) / denom 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // into: 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // (numer / denom) * base::Time::kMicrosecondsPerSecond + 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // ((numer % denom) * base::Time::kMicrosecondsPerSecond) / denom 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 a = numer / denom; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_LE((a > 0 ? a : -a), kint64max / base::Time::kMicrosecondsPerSecond); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 timea_in_us = a * base::Time::kMicrosecondsPerSecond; 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 b = numer % denom; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_LE((b > 0 ? b : -b), kint64max / base::Time::kMicrosecondsPerSecond); 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int64 timeb_in_us = (b * base::Time::kMicrosecondsPerSecond) / denom; 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK((timeb_in_us < 0) || (timea_in_us <= kint64max - timeb_in_us)); 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK((timeb_in_us > 0) || (timea_in_us >= kint64min - timeb_in_us)); 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return base::TimeDelta::FromMicroseconds(timea_in_us + timeb_in_us); 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)DecodeTimestamp DecodeTimestampFromRational(int64 numer, int64 denom) { 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return DecodeTimestamp::FromPresentationTime( 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) TimeDeltaFromRational(numer, denom)); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TrackRunIterator::TrackRunIterator(const Movie* moov, 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LogCB& log_cb) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : moov_(moov), log_cb_(log_cb), sample_offset_(0) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(moov); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TrackRunIterator::~TrackRunIterator() {} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic bool PopulateSampleInfo(const TrackExtends& trex, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TrackFragmentHeader& tfhd, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TrackFragmentRun& trun, 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int64 edit_list_offset, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 i, 961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SampleInfo* sample_info, 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const SampleDependsOn sdtp_sample_depends_on, 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const LogCB& log_cb) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < trun.sample_sizes.size()) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->size = trun.sample_sizes[i]; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (tfhd.default_sample_size > 0) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->size = tfhd.default_sample_size; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->size = trex.default_sample_size; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < trun.sample_durations.size()) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->duration = trun.sample_durations[i]; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (tfhd.default_sample_duration > 0) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->duration = tfhd.default_sample_duration; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->duration = trex.default_sample_duration; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < trun.sample_composition_time_offsets.size()) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->cts_offset = trun.sample_composition_time_offsets[i]; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->cts_offset = 0; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_info->cts_offset += edit_list_offset; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 flags; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < trun.sample_flags.size()) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = trun.sample_flags[i]; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (tfhd.has_default_sample_flags) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = tfhd.default_sample_flags; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = trex.default_sample_flags; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SampleDependsOn sample_depends_on = 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static_cast<SampleDependsOn>((flags >> 24) & 0x3); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (sample_depends_on == kSampleDependsOnUnknown) 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample_depends_on = sdtp_sample_depends_on; 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // ISO/IEC 14496-12 Section 8.8.3.1 : The negation of |sample_is_sync_sample| 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // provides the same information as the sync sample table [8.6.2]. When 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // |sample_is_sync_sample| is true for a sample, it is the same as if the 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // sample were not in a movie fragment and marked with an entry in the sync 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // sample table (or, if all samples are sync samples, the sync sample table 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // were absent). 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool sample_is_sync_sample = !(flags & kSampleIsNonSyncSample); 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample_info->is_random_access_point = sample_is_sync_sample; 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (sample_depends_on) { 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case kSampleDependsOnUnknown: 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) sample_info->is_keyframe = sample_is_sync_sample; 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 1501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case kSampleDependsOnOthers: 1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sample_info->is_keyframe = false; 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case kSampleDependsOnNoOther: 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sample_info->is_keyframe = true; 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 1581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) case kSampleDependsOnReserved: 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MEDIA_LOG(log_cb) << "Reserved value used in sample dependency info."; 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In well-structured encrypted media, each track run will be immediately 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// preceded by its auxiliary information; this is the only optimal storage 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pattern in terms of minimum number of bytes from a serial stream needed to 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// begin playback. It also allows us to optimize caching on memory-constrained 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// architectures, because we can cache the relatively small auxiliary 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// information for an entire run and then discard data from the input stream, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead of retaining the entire 'mdat' box. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We optimize for this situation (with no loss of generality) by sorting track 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// runs during iteration in order of their first data offset (either sample data 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// or auxiliary data). 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CompareMinTrackRunDataOffset { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator()(const TrackRunInfo& a, const TrackRunInfo& b) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 a_aux = a.aux_info_total_size ? a.aux_info_start_offset : kint64max; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 b_aux = b.aux_info_total_size ? b.aux_info_start_offset : kint64max; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 a_lesser = std::min(a_aux, a.sample_start_offset); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 a_greater = std::max(a_aux, a.sample_start_offset); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 b_lesser = std::min(b_aux, b.sample_start_offset); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 b_greater = std::max(b_aux, b.sample_start_offset); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a_lesser == b_lesser) return a_greater < b_greater; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a_lesser < b_lesser; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TrackRunIterator::Init(const MovieFragment& moof) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) runs_.clear(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < moof.tracks.size(); i++) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TrackFragment& traf = moof.tracks[i]; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Track* trak = NULL; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t t = 0; t < moov_->tracks.size(); t++) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (moov_->tracks[t].header.track_id == traf.header.track_id) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trak = &moov_->tracks[t]; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RCHECK(trak); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TrackExtends* trex = NULL; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t t = 0; t < moov_->extends.tracks.size(); t++) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (moov_->extends.tracks[t].track_id == traf.header.track_id) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trex = &moov_->extends.tracks[t]; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RCHECK(trex); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SampleDescription& stsd = 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) trak->media.information.sample_table.description; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stsd.type != kAudio && stsd.type != kVideo) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Skipping unhandled track type"; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t desc_idx = traf.header.sample_description_index; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!desc_idx) desc_idx = trex->default_sample_description_index; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RCHECK(desc_idx > 0); // Descriptions are one-indexed in the file 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc_idx -= 1; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Process edit list to remove CTS offset introduced in the presence of 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // B-frames (those that contain a single edit with a nonnegative media 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // time). Other uses of edit lists are not supported, as they are 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // both uncommon and better served by higher-level protocols. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 edit_list_offset = 0; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<EditListEntry>& edits = trak->edit.list.edits; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!edits.empty()) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (edits.size() > 1) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Multi-entry edit box detected; some components ignored."; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (edits[0].media_time < 0) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Empty edit list entry ignored."; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) edit_list_offset = -edits[0].media_time; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SampleToGroupIterator sample_to_group_itr(traf.sample_to_group); 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool is_sample_to_group_valid = sample_to_group_itr.IsValid(); 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 run_start_dts = traf.decode_time.decode_time; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sample_count_sum = 0; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < traf.runs.size(); j++) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TrackFragmentRun& trun = traf.runs[j]; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TrackRunInfo tri; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.track_id = traf.header.track_id; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.timescale = trak->media.header.timescale; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.start_dts = run_start_dts; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.sample_start_offset = trun.data_offset; 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tri.sample_encryption_info = traf.sample_group_description.entries; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.is_audio = (stsd.type == kAudio); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tri.is_audio) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RCHECK(!stsd.audio_entries.empty()); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (desc_idx > stsd.audio_entries.size()) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc_idx = 0; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.audio_description = &stsd.audio_entries[desc_idx]; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RCHECK(!stsd.video_entries.empty()); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (desc_idx > stsd.video_entries.size()) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) desc_idx = 0; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.video_description = &stsd.video_entries[desc_idx]; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Collect information from the auxiliary_offset entry with the same index 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the 'saiz' container as the current run's index in the 'trun' 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // container, if it is present. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (traf.auxiliary_offset.offsets.size() > j) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There should be an auxiliary info entry corresponding to each sample 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the auxiliary offset entry's corresponding track run. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RCHECK(traf.auxiliary_size.sample_count >= 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_count_sum + trun.sample_count); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_start_offset = traf.auxiliary_offset.offsets[j]; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_default_size = 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) traf.auxiliary_size.default_sample_info_size; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tri.aux_info_default_size == 0) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<uint8>& sizes = 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) traf.auxiliary_size.sample_info_sizes; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_sizes.insert(tri.aux_info_sizes.begin(), 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizes.begin() + sample_count_sum, 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizes.begin() + sample_count_sum + trun.sample_count); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the default info size is positive, find the total size of the aux 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // info block from it, otherwise sum over the individual sizes of each 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // aux info entry in the aux_offset entry. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tri.aux_info_default_size) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_total_size = 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_default_size * trun.sample_count; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_total_size = 0; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t k = 0; k < trun.sample_count; k++) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_total_size += tri.aux_info_sizes[k]; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_start_offset = -1; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.aux_info_total_size = 0; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tri.samples.resize(trun.sample_count); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t k = 0; k < trun.sample_count; k++) { 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!PopulateSampleInfo(*trex, traf.header, trun, edit_list_offset, 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci k, &tri.samples[k], 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci traf.sdtp.sample_depends_on(k), 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_cb_)) { 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_start_dts += tri.samples[k].duration; 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!is_sample_to_group_valid) { 316010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Set group description index to 0 to read encryption information 317010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // from TrackEncryption Box. 318010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tri.samples[k].cenc_group_description_index = 0; 319010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) continue; 320010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 321010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 322010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // ISO-14496-12 Section 8.9.2.3 and 8.9.4 : group description index 323010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // (1) ranges from 1 to the number of sample group entries in the track 324010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // level SampleGroupDescription Box, or (2) takes the value 0 to 325010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // indicate that this sample is a member of no group, in this case, the 326010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // sample is associated with the default values specified in 327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TrackEncryption Box, or (3) starts at 0x10001, i.e. the index value 328010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // 1, with the value 1 in the top 16 bits, to reference fragment-local 329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // SampleGroupDescription Box. 330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Case (1) is not supported currently. We might not need it either as 331010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the same functionality can be better achieved using (2). 332010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 index = sample_to_group_itr.group_description_index(); 333010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (index >= SampleToGroupEntry::kFragmentGroupDescriptionIndexBase) { 334010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index -= SampleToGroupEntry::kFragmentGroupDescriptionIndexBase; 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RCHECK(index != 0 && index <= tri.sample_encryption_info.size()); 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else if (index != 0) { 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NOTIMPLEMENTED() << "'sgpd' box in 'moov' is not supported."; 338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 339010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 340010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tri.samples[k].cenc_group_description_index = index; 341010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) is_sample_to_group_valid = sample_to_group_itr.Advance(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) runs_.push_back(tri); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_count_sum += trun.sample_count; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We should have iterated through all samples in SampleToGroup Box. 348010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RCHECK(!sample_to_group_itr.IsValid()); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset()); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_itr_ = runs_.begin(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetRun(); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrackRunIterator::AdvanceRun() { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++run_itr_; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetRun(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrackRunIterator::ResetRun() { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsRunValid()) return; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_dts_ = run_itr_->start_dts; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_offset_ = run_itr_->sample_start_offset; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_itr_ = run_itr_->samples.begin(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cenc_info_.clear(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TrackRunIterator::AdvanceSample() { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsSampleValid()); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_dts_ += sample_itr_->duration; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sample_offset_ += sample_itr_->size; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++sample_itr_; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This implementation only indicates a need for caching if CENC auxiliary 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// info is available in the stream. 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TrackRunIterator::AuxInfoNeedsToBeCached() { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsRunValid()); 381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return aux_info_size() > 0 && cenc_info_.size() == 0; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This implementation currently only caches CENC auxiliary info. 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TrackRunIterator::CacheAuxInfo(const uint8* buf, int buf_size) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RCHECK(AuxInfoNeedsToBeCached() && buf_size >= aux_info_size()); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cenc_info_.resize(run_itr_->samples.size()); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 pos = 0; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < run_itr_->samples.size(); i++) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int info_size = run_itr_->aux_info_default_size; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info_size) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_size = run_itr_->aux_info_sizes[i]; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (IsSampleEncrypted(i)) { 396010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) BufferReader reader(buf + pos, info_size); 397010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) RCHECK(cenc_info_[i].Parse(GetIvSize(i), &reader)); 398010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos += info_size; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TrackRunIterator::IsRunValid() const { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return run_itr_ != runs_.end(); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TrackRunIterator::IsSampleValid() const { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsRunValid() && (sample_itr_ != run_itr_->samples.end()); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Because tracks are in sorted order and auxiliary information is cached when 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returning samples, it is guaranteed that no data will be required before the 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// lesser of the minimum data offset of this track and the next in sequence. 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (The stronger condition - that no data is required before the minimum data 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// offset of this track alone - is not guaranteed, because the BMFF spec does 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not have any inter-run ordering restrictions.) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 TrackRunIterator::GetMaxClearOffset() { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 offset = kint64max; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsSampleValid()) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = std::min(offset, sample_offset_); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (AuxInfoNeedsToBeCached()) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = std::min(offset, aux_info_offset()); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (run_itr_ != runs_.end()) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<TrackRunInfo>::const_iterator next_run = run_itr_ + 1; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_run != runs_.end()) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = std::min(offset, next_run->sample_start_offset); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (next_run->aux_info_total_size) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offset = std::min(offset, next_run->aux_info_start_offset); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset == kint64max) return 0; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return offset; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 TrackRunIterator::track_id() const { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsRunValid()); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return run_itr_->track_id; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TrackRunIterator::is_encrypted() const { 445010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(IsSampleValid()); 446010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return IsSampleEncrypted(sample_itr_ - run_itr_->samples.begin()); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 TrackRunIterator::aux_info_offset() const { 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return run_itr_->aux_info_start_offset; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TrackRunIterator::aux_info_size() const { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return run_itr_->aux_info_total_size; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TrackRunIterator::is_audio() const { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsRunValid()); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return run_itr_->is_audio; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const AudioSampleEntry& TrackRunIterator::audio_description() const { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(is_audio()); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(run_itr_->audio_description); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *run_itr_->audio_description; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const VideoSampleEntry& TrackRunIterator::video_description() const { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_audio()); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(run_itr_->video_description); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *run_itr_->video_description; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 TrackRunIterator::sample_offset() const { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsSampleValid()); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sample_offset_; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int TrackRunIterator::sample_size() const { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsSampleValid()); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sample_itr_->size; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)DecodeTimestamp TrackRunIterator::dts() const { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsSampleValid()); 4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return DecodeTimestampFromRational(sample_dts_, run_itr_->timescale); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)base::TimeDelta TrackRunIterator::cts() const { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsSampleValid()); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDeltaFromRational(sample_dts_ + sample_itr_->cts_offset, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_itr_->timescale); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)base::TimeDelta TrackRunIterator::duration() const { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsSampleValid()); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDeltaFromRational(sample_itr_->duration, run_itr_->timescale); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TrackRunIterator::is_keyframe() const { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsSampleValid()); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sample_itr_->is_keyframe; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool TrackRunIterator::is_random_access_point() const { 506cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(IsSampleValid()); 507cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return sample_itr_->is_random_access_point; 508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const TrackEncryption& TrackRunIterator::track_encryption() const { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_audio()) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return audio_description().sinf.info.track_encryption; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return video_description().sinf.info.track_encryption; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() { 517010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(is_encrypted()); 518010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 519010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (cenc_info_.empty()) { 520010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_EQ(0, aux_info_size()); 521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MEDIA_LOG(log_cb_) << "Aux Info is not available."; 522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return scoped_ptr<DecryptConfig>(); 523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 524010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t sample_idx = sample_itr_ - run_itr_->samples.begin(); 526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_LT(sample_idx, cenc_info_.size()); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FrameCENCInfo& cenc_info = cenc_info_[sample_idx]; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) size_t total_size = 0; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cenc_info.subsamples.empty() && 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (!cenc_info.GetTotalSizeOfSubsamples(&total_size) || 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) total_size != static_cast<size_t>(sample_size()))) { 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MEDIA_LOG(log_cb_) << "Incorrect CENC subsample size."; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_ptr<DecryptConfig>(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::vector<uint8>& kid = GetKeyId(sample_idx); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_ptr<DecryptConfig>(new DecryptConfig( 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string(reinterpret_cast<const char*>(&kid[0]), kid.size()), 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string(reinterpret_cast<const char*>(cenc_info.iv), 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arraysize(cenc_info.iv)), 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cenc_info.subsamples)); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)uint32 TrackRunIterator::GetGroupDescriptionIndex(uint32 sample_index) const { 546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(IsRunValid()); 547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_LT(sample_index, run_itr_->samples.size()); 548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return run_itr_->samples[sample_index].cenc_group_description_index; 549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 550010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const CencSampleEncryptionInfoEntry& 552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TrackRunIterator::GetSampleEncryptionInfoEntry( 553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 group_description_index) const { 554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(IsRunValid()); 555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_NE(group_description_index, 0u); 556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK_LE(group_description_index, run_itr_->sample_encryption_info.size()); 557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // |group_description_index| is 1-based. Subtract by 1 to index the vector. 558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return run_itr_->sample_encryption_info[group_description_index - 1]; 559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 560010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 561010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool TrackRunIterator::IsSampleEncrypted(size_t sample_index) const { 562010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 index = GetGroupDescriptionIndex(sample_index); 563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return (index == 0) ? track_encryption().is_encrypted 564010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : GetSampleEncryptionInfoEntry(index).is_encrypted; 565010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 567010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const std::vector<uint8>& TrackRunIterator::GetKeyId( 568010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) size_t sample_index) const { 569010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 index = GetGroupDescriptionIndex(sample_index); 570010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return (index == 0) ? track_encryption().default_kid 571010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : GetSampleEncryptionInfoEntry(index).key_id; 572010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 573010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 574010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)uint8 TrackRunIterator::GetIvSize(size_t sample_index) const { 575010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) uint32 index = GetGroupDescriptionIndex(sample_index); 576010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return (index == 0) ? track_encryption().default_iv_size 577010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : GetSampleEncryptionInfoEntry(index).iv_size; 578010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 579010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace mp4 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 582