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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_split.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/mp4/box_definitions.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/mp4/rcheck.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/mp4/track_run_iterator.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The sum of the elements in a vector initialized with SumAscending,
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// less the value of the last element.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSumAscending1 = 45;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kAudioScale = 48000;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kVideoScale = 25;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const uint8 kAuxInfo[] = {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x00, 0x02,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x00, 0x03, 0x00, 0x00, 0x00, 0x04
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kIv1[] = {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const uint8 kKeyId[] = {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x41, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x54,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x44
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)static const uint8 kCencSampleGroupKeyId[] = {
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  0x46, 0x72, 0x61, 0x67, 0x53, 0x61, 0x6d, 0x70,
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace mp4 {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TrackRunIteratorTest : public testing::Test {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TrackRunIteratorTest() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMovie();
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Movie moov_;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LogCB log_cb_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TrackRunIterator> iter_;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateMovie() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.header.timescale = 1000;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.tracks.resize(3);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.extends.tracks.resize(2);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.tracks[0].header.track_id = 1;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.tracks[0].media.header.timescale = kAudioScale;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SampleDescription& desc1 =
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        moov_.tracks[0].media.information.sample_table.description;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AudioSampleEntry aud_desc;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aud_desc.format = FOURCC_MP4A;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aud_desc.sinf.info.track_encryption.is_encrypted = false;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desc1.type = kAudio;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desc1.audio_entries.push_back(aud_desc);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.extends.tracks[0].track_id = 1;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.extends.tracks[0].default_sample_description_index = 1;
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    moov_.tracks[0].media.information.sample_table.sync_sample.is_present =
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        false;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.tracks[1].header.track_id = 2;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.tracks[1].media.header.timescale = kVideoScale;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SampleDescription& desc2 =
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        moov_.tracks[1].media.information.sample_table.description;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VideoSampleEntry vid_desc;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vid_desc.format = FOURCC_AVC1;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vid_desc.sinf.info.track_encryption.is_encrypted = false;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desc2.type = kVideo;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desc2.video_entries.push_back(vid_desc);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.extends.tracks[1].track_id = 2;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.extends.tracks[1].default_sample_description_index = 1;
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SyncSample& video_sync_sample =
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        moov_.tracks[1].media.information.sample_table.sync_sample;
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    video_sync_sample.is_present = true;
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    video_sync_sample.entries.resize(1);
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    video_sync_sample.entries[0] = 0;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.tracks[2].header.track_id = 3;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moov_.tracks[2].media.information.sample_table.description.type = kHint;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  uint32 ToSampleFlags(const std::string& str) {
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CHECK_EQ(str.length(), 2u);
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SampleDependsOn sample_depends_on = kSampleDependsOnReserved;
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool is_non_sync_sample = false;
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    switch(str[0]) {
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'U':
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        sample_depends_on = kSampleDependsOnUnknown;
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'O':
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        sample_depends_on = kSampleDependsOnOthers;
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'N':
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        sample_depends_on = kSampleDependsOnNoOther;
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      case 'R':
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        sample_depends_on = kSampleDependsOnReserved;
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      default:
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        CHECK(false) << "Invalid sample dependency character '"
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     << str[0] << "'";
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    switch(str[1]) {
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'S':
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        is_non_sync_sample = false;
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      case 'N':
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        is_non_sync_sample = true;
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      default:
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        CHECK(false) << "Invalid sync sample character '"
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     << str[1] << "'";
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        break;
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    uint32 flags = static_cast<uint32>(sample_depends_on) << 24;
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (is_non_sync_sample)
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      flags |= kSampleIsNonSyncSample;
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return flags;
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void SetFlagsOnSamples(const std::string& sample_info,
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                         TrackFragmentRun* trun) {
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // US - SampleDependsOnUnknown & IsSyncSample
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // UN - SampleDependsOnUnknown & IsNonSyncSample
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // OS - SampleDependsOnOthers & IsSyncSample
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // ON - SampleDependsOnOthers & IsNonSyncSample
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // NS - SampleDependsOnNoOthers & IsSyncSample
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // NN - SampleDependsOnNoOthers & IsNonSyncSample
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<std::string> flags_data;
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::SplitString(sample_info, ' ', &flags_data);
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (flags_data.size() == 1u) {
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Simulates the first_sample_flags_present set scenario,
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // where only one sample_flag value is set and the default
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // flags are used for everything else.
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ASSERT_GE(trun->sample_count, flags_data.size());
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } else {
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ASSERT_EQ(trun->sample_count, flags_data.size());
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    trun->sample_flags.resize(flags_data.size());
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (size_t i = 0; i < flags_data.size(); i++)
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      trun->sample_flags[i] = ToSampleFlags(flags_data[i]);
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string KeyframeAndRAPInfo(TrackRunIterator* iter) {
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CHECK(iter->IsRunValid());
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::stringstream ss;
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ss << iter->track_id();
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    while (iter->IsSampleValid()) {
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ss << " " << (iter->is_keyframe() ? "K" : "P");
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (iter->is_random_access_point())
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ss << "R";
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      iter->AdvanceSample();
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return ss.str();
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment CreateFragment() {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MovieFragment moof;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks.resize(2);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].decode_time.decode_time = 0;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].header.track_id = 1;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].header.has_default_sample_flags = true;
184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    moof.tracks[0].header.default_sample_flags = ToSampleFlags("US");
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].header.default_sample_duration = 1024;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].header.default_sample_size = 4;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].runs.resize(2);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].runs[0].sample_count = 10;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].runs[0].data_offset = 100;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetAscending(&moof.tracks[0].runs[0].sample_sizes);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].runs[1].sample_count = 10;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[0].runs[1].data_offset = 10000;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[1].header.track_id = 2;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[1].header.has_default_sample_flags = false;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[1].decode_time.decode_time = 10;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[1].runs.resize(1);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[1].runs[0].sample_count = 10;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[1].runs[0].data_offset = 200;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetAscending(&moof.tracks[1].runs[0].sample_sizes);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetAscending(&moof.tracks[1].runs[0].sample_durations);
203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SetFlagsOnSamples("US UN UN UN UN UN UN UN UN UN", &moof.tracks[1].runs[0]);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return moof;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the first sample description of a Track to indicate encryption
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddEncryption(Track* track) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SampleDescription* stsd =
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &track->media.information.sample_table.description;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProtectionSchemeInfo* sinf;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!stsd->video_entries.empty()) {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       sinf = &stsd->video_entries[0].sinf;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       sinf = &stsd->audio_entries[0].sinf;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sinf->type.type = FOURCC_CENC;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sinf->info.track_encryption.is_encrypted = true;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sinf->info.track_encryption.default_iv_size = 8;
222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    sinf->info.track_encryption.default_kid.assign(kKeyId,
223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                   kKeyId + arraysize(kKeyId));
224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Add SampleGroupDescription Box with two entries (an unencrypted entry and
227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // an encrypted entry). Populate SampleToGroup Box from input array.
228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void AddCencSampleGroup(TrackFragment* frag,
229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                          const SampleToGroupEntry* sample_to_group_entries,
230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                          size_t num_entries) {
231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_group_description.grouping_type = FOURCC_SEIG;
232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_group_description.entries.resize(2);
233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_group_description.entries[0].is_encrypted = false;
234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_group_description.entries[0].iv_size = 0;
235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_group_description.entries[1].is_encrypted = true;
236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_group_description.entries[1].iv_size = 8;
237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_group_description.entries[1].key_id.assign(
238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        kCencSampleGroupKeyId,
239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        kCencSampleGroupKeyId + arraysize(kCencSampleGroupKeyId));
240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_to_group.grouping_type = FOURCC_SEIG;
242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    frag->sample_to_group.entries.assign(sample_to_group_entries,
243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                         sample_to_group_entries + num_entries);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add aux info covering the first track run to a TrackFragment, and update
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the run to ensure it matches length and subsample information.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddAuxInfoHeaders(int offset, TrackFragment* frag) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frag->auxiliary_offset.offsets.push_back(offset);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frag->auxiliary_size.sample_count = 2;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frag->auxiliary_size.sample_info_sizes.push_back(8);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frag->auxiliary_size.sample_info_sizes.push_back(22);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frag->runs[0].sample_count = 2;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    frag->runs[0].sample_sizes[1] = 10;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool InitMoofWithArbitraryAuxInfo(MovieFragment* moof) {
258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // Add aux info header (equal sized aux info for every sample).
259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    for (uint32 i = 0; i < moof->tracks.size(); ++i) {
260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      moof->tracks[i].auxiliary_offset.offsets.push_back(50);
261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      moof->tracks[i].auxiliary_size.sample_count = 10;
262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      moof->tracks[i].auxiliary_size.default_sample_info_size = 8;
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    // We don't care about the actual data in aux.
266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    std::vector<uint8> aux_info(1000);
267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return iter_->Init(*moof) &&
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)           iter_->CacheAuxInfo(&aux_info[0], aux_info.size());
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetAscending(std::vector<uint32>* vec) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vec->resize(10);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < vec->size(); i++)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (*vec)[i] = i+1;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, NoRunsTest) {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(MovieFragment()));
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->IsRunValid());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->IsSampleValid());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, BasicOperationTest) {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment moof = CreateFragment();
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test that runs are sorted correctly, and that properties of the initial
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sample of the first run are correct
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->IsRunValid());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->is_encrypted());
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 1u);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_offset(), 100);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_size(), 1);
2976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(0, kAudioScale));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(0, kAudioScale));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1024, kAudioScale));
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->is_keyframe());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Advance to the last sample in the current run, and test its properties
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 9; i++) iter_->AdvanceSample();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 1u);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_offset(), 100 + kSumAscending1);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_size(), 10);
3076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(1024 * 9, kAudioScale));
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1024, kAudioScale));
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->is_keyframe());
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test end-of-run
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->IsSampleValid());
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test last sample of next run
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->is_keyframe());
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 9; i++) iter_->AdvanceSample();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 2u);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_offset(), 200 + kSumAscending1);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_size(), 10);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 base_dts = kSumAscending1 + moof.tracks[1].decode_time.decode_time;
3236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(base_dts, kVideoScale));
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(10, kVideoScale));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->is_keyframe());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test final run
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 1u);
3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(1024 * 10, kAudioScale));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(moof.tracks[0].runs[1].data_offset +
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            moof.tracks[0].header.default_sample_size,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            iter_->sample_offset());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->IsRunValid());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, TrackExtendsDefaultsTest) {
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moov_.extends.tracks[0].default_sample_duration = 50;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moov_.extends.tracks[0].default_sample_size = 3;
342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moov_.extends.tracks[0].default_sample_flags = ToSampleFlags("UN");
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment moof = CreateFragment();
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].header.has_default_sample_flags = false;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].header.default_sample_size = 0;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].header.default_sample_duration = 0;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].runs[0].sample_sizes.clear();
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->is_keyframe());
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_size(), 3);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_offset(), moof.tracks[0].runs[0].data_offset + 3);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(50, kAudioScale));
3556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(50, kAudioScale));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, FirstSampleFlagTest) {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that keyframes are flagged correctly in the face of BMFF boxes which
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // explicitly specify the flags for the first sample in a run and rely on
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // defaults for all subsequent samples
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment moof = CreateFragment();
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[1].header.has_default_sample_flags = true;
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moof.tracks[1].header.default_sample_flags = ToSampleFlags("UN");
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetFlagsOnSamples("US", &moof.tracks[1].runs[0]);
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ("1 KR KR KR KR KR KR KR KR KR KR", KeyframeAndRAPInfo(iter_.get()));
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
372cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ("2 KR P P P P P P P P P", KeyframeAndRAPInfo(iter_.get()));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Verify that parsing fails if a reserved value is in the sample flags.
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(TrackRunIteratorTest, SampleInfoTest_ReservedInSampleFlags) {
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MovieFragment moof = CreateFragment();
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Change the "depends on" field on one of the samples to a
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // reserved value.
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  moof.tracks[1].runs[0].sample_flags[0] = ToSampleFlags("RS");
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(iter_->Init(moof));
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Verify that parsing fails if a reserved value is in the default sample flags.
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(TrackRunIteratorTest, SampleInfoTest_ReservedInDefaultSampleFlags) {
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MovieFragment moof = CreateFragment();
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Set the default flag to contain a reserved "depends on" value.
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  moof.tracks[0].header.default_sample_flags = ToSampleFlags("RN");
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(iter_->Init(moof));
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, ReorderingTest) {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test frame reordering and edit list support. The frames have the following
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // decode timestamps:
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   0ms 40ms   120ms     240ms
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   | 0 | 1  - | 2  -  - |
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ...and these composition timestamps, after edit list adjustment:
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   0ms 40ms       160ms  240ms
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   | 0 | 2  -  -  | 1 - |
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create an edit list with one entry, with an initial start time of 80ms
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (that is, 2 / kVideoTimescale) and a duration of zero (which is treated as
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // infinite according to 14496-12:2012). This will cause the first 80ms of the
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // media timeline - which will be empty, due to CTS biasing - to be discarded.
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EditListEntry entry;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.segment_duration = 0;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.media_time = 2;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.media_rate_integer = 1;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry.media_rate_fraction = 0;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moov_.tracks[1].edit.list.edits.push_back(entry);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add CTS offsets. Without bias, the CTS offsets for the first three frames
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would simply be [0, 3, -2]. Since CTS offsets should be non-negative for
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // maximum compatibility, these values are biased up to [2, 5, 0], and the
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // extra 80ms is removed via the edit list.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment moof = CreateFragment();
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int32>& cts_offsets =
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moof.tracks[1].runs[0].sample_composition_time_offsets;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cts_offsets.resize(10);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cts_offsets[0] = 2;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cts_offsets[1] = 5;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cts_offsets[2] = 0;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[1].decode_time.decode_time = 0;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
4336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(0, kVideoScale));
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(0, kVideoScale));
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1, kVideoScale));
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(1, kVideoScale));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(4, kVideoScale));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(2, kVideoScale));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
4416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(3, kVideoScale));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(1, kVideoScale));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(3, kVideoScale));
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, IgnoreUnknownAuxInfoTest) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment moof = CreateFragment();
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[1].auxiliary_offset.offsets.push_back(50);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[1].auxiliary_size.default_sample_info_size = 2;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[1].auxiliary_size.sample_count = 2;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[1].runs[0].sample_count = 2;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached());
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, DecryptConfigTest) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddEncryption(&moov_.tracks[1]);
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment moof = CreateFragment();
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuxInfoHeaders(50, &moof.tracks[1]);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The run for track 2 will be first, since its aux info offset is the first
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // element in the file.
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 2u);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->is_encrypted());
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->AuxInfoNeedsToBeCached());
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(static_cast<uint32>(iter_->aux_info_size()), arraysize(kAuxInfo));
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->aux_info_offset(), 50);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 50);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->CacheAuxInfo(NULL, 0));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->CacheAuxInfo(kAuxInfo, 3));
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->AuxInfoNeedsToBeCached());
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached());
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_offset(), 200);
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), moof.tracks[0].runs[0].data_offset);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DecryptConfig> config = iter_->GetDecryptConfig();
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(arraysize(kKeyId), config->key_id().size());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!memcmp(kKeyId, config->key_id().data(),
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      config->key_id().size()));
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(arraysize(kIv1), config->iv().size());
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!memcmp(kIv1, config->iv().data(), config->iv().size()));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(config->subsamples().empty());
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config = iter_->GetDecryptConfig();
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(config->subsamples().size(), 2u);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(config->subsamples()[1].cypher_bytes, 4u);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
496010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(TrackRunIteratorTest, CencSampleGroupTest) {
497010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MovieFragment moof = CreateFragment();
498010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
499010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const SampleToGroupEntry kSampleToGroupTable[] = {
500010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // Associated with the second entry in SampleGroupDescription Box.
501010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2},
502010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // Associated with the first entry in SampleGroupDescription Box.
503010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 1}};
504010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AddCencSampleGroup(
505010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &moof.tracks[0], kSampleToGroupTable, arraysize(kSampleToGroupTable));
506010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
507010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
508010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ASSERT_TRUE(InitMoofWithArbitraryAuxInfo(&moof));
509010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
510010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::string cenc_sample_group_key_id(
511010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      kCencSampleGroupKeyId,
512010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      kCencSampleGroupKeyId + arraysize(kCencSampleGroupKeyId));
513010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // The first sample is encrypted and the second sample is unencrypted.
514010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_TRUE(iter_->is_encrypted());
515010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(cenc_sample_group_key_id, iter_->GetDecryptConfig()->key_id());
516010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  iter_->AdvanceSample();
517010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_FALSE(iter_->is_encrypted());
518010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
519010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
520010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(TrackRunIteratorTest, CencSampleGroupWithTrackEncryptionBoxTest) {
521010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Add TrackEncryption Box.
522010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AddEncryption(&moov_.tracks[0]);
523010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
524010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MovieFragment moof = CreateFragment();
525010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
526010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const SampleToGroupEntry kSampleToGroupTable[] = {
527010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // Associated with the second entry in SampleGroupDescription Box.
528010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      {2, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2},
529010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // Associated with the default values specified in TrackEncryption Box.
530010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      {4, 0},
531010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      // Associated with the first entry in SampleGroupDescription Box.
532010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      {3, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 1}};
533010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  AddCencSampleGroup(
534010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      &moof.tracks[0], kSampleToGroupTable, arraysize(kSampleToGroupTable));
535010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
536010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
537010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ASSERT_TRUE(InitMoofWithArbitraryAuxInfo(&moof));
538010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
539010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::string track_encryption_key_id(kKeyId, kKeyId + arraysize(kKeyId));
540010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::string cenc_sample_group_key_id(
541010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      kCencSampleGroupKeyId,
542010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      kCencSampleGroupKeyId + arraysize(kCencSampleGroupKeyId));
543010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
544010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < kSampleToGroupTable[0].sample_count; ++i) {
545010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_TRUE(iter_->is_encrypted());
546010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(cenc_sample_group_key_id, iter_->GetDecryptConfig()->key_id());
547010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    iter_->AdvanceSample();
548010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
549010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
550010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < kSampleToGroupTable[1].sample_count; ++i) {
551010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_TRUE(iter_->is_encrypted());
552010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(track_encryption_key_id, iter_->GetDecryptConfig()->key_id());
553010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    iter_->AdvanceSample();
554010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
555010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
556010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < kSampleToGroupTable[2].sample_count; ++i) {
557010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_FALSE(iter_->is_encrypted());
558010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    iter_->AdvanceSample();
559010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
560010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
561010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // The remaining samples should be associated with the default values
562010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // specified in TrackEncryption Box.
563010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_TRUE(iter_->is_encrypted());
564010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(track_encryption_key_id, iter_->GetDecryptConfig()->key_id());
565010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
566010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is legal for aux info blocks to be shared among multiple formats.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, SharedAuxInfoTest) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddEncryption(&moov_.tracks[0]);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddEncryption(&moov_.tracks[1]);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment moof = CreateFragment();
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].runs.resize(1);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuxInfoHeaders(50, &moof.tracks[0]);
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuxInfoHeaders(50, &moof.tracks[1]);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].auxiliary_size.default_sample_info_size = 8;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 1u);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->aux_info_offset(), 50);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DecryptConfig> config = iter_->GetDecryptConfig();
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(arraysize(kIv1), config->iv().size());
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!memcmp(kIv1, config->iv().data(), config->iv().size()));
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 50);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 50);
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->aux_info_offset(), 50);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 200);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(arraysize(kIv1), config->iv().size());
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(!memcmp(kIv1, config->iv().data(), config->iv().size()));
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 201);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sensible files are expected to place auxiliary information for a run
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// immediately before the main data for that run. Alternative schemes are
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// possible, however, including the somewhat reasonable behavior of placing all
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// aux info at the head of the 'mdat' box together, and the completely
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unreasonable behavior demonstrated here:
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  byte 50: track 2, run 1 aux info
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  byte 100: track 1, run 1 data
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  byte 200: track 2, run 1 data
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  byte 201: track 1, run 2 aux info (*inside* track 2, run 1 data)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  byte 10000: track 1, run 2 data
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  byte 20000: track 1, run 1 aux info
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TrackRunIteratorTest, UnexpectedOrderingTest) {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddEncryption(&moov_.tracks[0]);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddEncryption(&moov_.tracks[1]);
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MovieFragment moof = CreateFragment();
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuxInfoHeaders(20000, &moof.tracks[0]);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].auxiliary_offset.offsets.push_back(201);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].auxiliary_size.sample_count += 2;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].auxiliary_size.default_sample_info_size = 8;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[0].runs[1].sample_count = 2;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddAuxInfoHeaders(50, &moof.tracks[1]);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  moof.tracks[1].runs[0].sample_sizes[0] = 5;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 2u);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->aux_info_offset(), 50);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_offset(), 200);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 100);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 1u);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->aux_info_offset(), 20000);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_offset(), 100);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 100);
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceSample();
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 101);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_->AdvanceRun();
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->track_id(), 1u);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->aux_info_offset(), 201);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->sample_offset(), 10000);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 201);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(iter_->GetMaxClearOffset(), 10000);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(TrackRunIteratorTest, MissingAndEmptyStss) {
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MovieFragment moof = CreateFragment();
6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Setup track 0 to not have an stss box, which means that all samples should
651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // be marked as random access points unless the kSampleIsNonSyncSample flag is
652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // set in the sample flags.
653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moov_.tracks[0].media.information.sample_table.sync_sample.is_present = false;
654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moov_.tracks[0].media.information.sample_table.sync_sample.entries.resize(0);
655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moof.tracks[0].runs.resize(1);
656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moof.tracks[0].runs[0].sample_count = 6;
657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moof.tracks[0].runs[0].data_offset = 100;
658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetFlagsOnSamples("US UN OS ON NS NN", &moof.tracks[0].runs[0]);
659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Setup track 1 to have an stss box with no entries, which normally means
661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // that none of the samples should be random access points. If the
662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // kSampleIsNonSyncSample flag is NOT set though, the sample should be
663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // considered a random access point.
664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moov_.tracks[1].media.information.sample_table.sync_sample.is_present = true;
665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moov_.tracks[1].media.information.sample_table.sync_sample.entries.resize(0);
666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moof.tracks[1].runs.resize(1);
667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moof.tracks[1].runs[0].sample_count = 6;
668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  moof.tracks[1].runs[0].data_offset = 200;
669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetFlagsOnSamples("US UN OS ON NS NN", &moof.tracks[1].runs[0]);
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  iter_.reset(new TrackRunIterator(&moov_, log_cb_));
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(iter_->Init(moof));
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(iter_->IsRunValid());
675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Verify that all samples except for the ones that have the
677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // kSampleIsNonSyncSample flag set are marked as random access points.
678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ("1 KR P PR P KR K", KeyframeAndRAPInfo(iter_.get()));
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  iter_->AdvanceRun();
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Verify that nothing is marked as a random access point.
683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ("2 KR P PR P KR K", KeyframeAndRAPInfo(iter_.get()));
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace mp4
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
689