// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cobalt/media/formats/mp4/track_run_iterator.h"

#include <memory>
#include <string>

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/string_split.h"
#include "cobalt/media/base/mock_media_log.h"
#include "cobalt/media/formats/mp4/box_definitions.h"
#include "cobalt/media/formats/mp4/rcheck.h"
#include "starboard/memory.h"
#include "starboard/types.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::StrictMock;

namespace {

// The sum of the elements in a vector initialized with SumAscending,
// less the value of the last element.
const int kSumAscending1 = 45;

const int kAudioScale = 48000;
const int kVideoScale = 25;

const uint8_t kAuxInfo[] = {
    0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31, 0x41, 0x54,
    0x65, 0x73, 0x74, 0x49, 0x76, 0x32, 0x00, 0x02, 0x00, 0x01,
    0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
};

// Sample encryption data for two samples, one with 8 byte IV, one with 16 byte
// IV. This data is generated for testing. It should be very unlikely to see
// IV of mixed size in actual media files, though it is permitted by spec.
const uint8_t kSampleEncryptionDataWithSubsamples[] = {
    // Sample count.
    0x00, 0x00, 0x00, 0x02,
    // Sample 1: IV (8 Bytes).
    0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31,
    // Sample 1: Subsample count.
    0x00, 0x01,
    // Sample 1: Subsample 1.
    0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
    // Sample 2: IV (16 bytes).
    0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32, 0x41, 0x42, 0x43, 0x44,
    0x45, 0x46, 0x47, 0x48,
    // Sample 2: Subsample count.
    0x00, 0x02,
    // Sample 2: Subsample 1.
    0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
    // Sample 2: Subsample 2.
    0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
};

const uint8_t kSampleEncryptionDataWithoutSubsamples[] = {
    // Sample count.
    0x00, 0x00, 0x00, 0x02,
    // Sample 1: IV.
    0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31,
    // Sample 2: IV.
    0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32,
};

// Size of these two IVs are 8 bytes. They are padded with 0 to 16 bytes.
const char kIv1[] = {
    0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x31,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const char kIv2[] = {
    0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// Size of this IV is 16 bytes.
const char kIv3[] = {
    0x41, 0x54, 0x65, 0x73, 0x74, 0x49, 0x76, 0x32,
    0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
};

const uint8_t kKeyId[] = {
    0x41, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x54,
    0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x44,
};

const uint8_t kTrackCencSampleGroupKeyId[] = {
    0x46, 0x72, 0x61, 0x67, 0x53, 0x61, 0x6d, 0x70,
    0x6c, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b,
};

const uint8_t kFragmentCencSampleGroupKeyId[] = {
    0x6b, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e,
    0x74, 0x43, 0x65, 0x6e, 0x63, 0x53, 0x61, 0x6d,
};

}  // namespace

namespace cobalt {
namespace media {
namespace mp4 {

MATCHER(ReservedValueInSampleDependencyInfo, "") {
  return CONTAINS_STRING(arg, "Reserved value used in sample dependency info.");
}

class TrackRunIteratorTest : public testing::Test {
 public:
  TrackRunIteratorTest() : media_log_(new StrictMock<MockMediaLog>()) {
    CreateMovie();
  }

 protected:
  Movie moov_;
  scoped_refptr<StrictMock<MockMediaLog>> media_log_;
  std::unique_ptr<TrackRunIterator> iter_;

  void CreateMovie() {
    moov_.header.timescale = 1000;
    moov_.tracks.resize(3);
    moov_.extends.tracks.resize(2);
    moov_.tracks[0].header.track_id = 1;
    moov_.tracks[0].media.header.timescale = kAudioScale;
    SampleDescription& desc1 =
        moov_.tracks[0].media.information.sample_table.description;
    AudioSampleEntry aud_desc;
    aud_desc.format = FOURCC_MP4A;
    aud_desc.sinf.info.track_encryption.is_encrypted = false;
    desc1.type = kAudio;
    desc1.audio_entries.push_back(aud_desc);
    moov_.extends.tracks[0].track_id = 1;
    moov_.extends.tracks[0].default_sample_description_index = 1;
    moov_.tracks[1].header.track_id = 2;
    moov_.tracks[1].media.header.timescale = kVideoScale;
    SampleDescription& desc2 =
        moov_.tracks[1].media.information.sample_table.description;
    VideoSampleEntry vid_desc;
    vid_desc.format = FOURCC_AVC1;
    vid_desc.sinf.info.track_encryption.is_encrypted = false;
    desc2.type = kVideo;
    desc2.video_entries.push_back(vid_desc);
    moov_.extends.tracks[1].track_id = 2;
    moov_.extends.tracks[1].default_sample_description_index = 1;

    moov_.tracks[2].header.track_id = 3;
    moov_.tracks[2].media.information.sample_table.description.type = kHint;
  }

  uint32_t ToSampleFlags(const std::string& str) {
    CHECK_EQ(str.length(), 2u);

    SampleDependsOn sample_depends_on = kSampleDependsOnReserved;
    bool is_non_sync_sample = false;
    switch (str[0]) {
      case 'U':
        sample_depends_on = kSampleDependsOnUnknown;
        break;
      case 'O':
        sample_depends_on = kSampleDependsOnOthers;
        break;
      case 'N':
        sample_depends_on = kSampleDependsOnNoOther;
        break;
      case 'R':
        sample_depends_on = kSampleDependsOnReserved;
        break;
      default:
        CHECK(false) << "Invalid sample dependency character '" << str[0]
                     << "'";
        break;
    }

    switch (str[1]) {
      case 'S':
        is_non_sync_sample = false;
        break;
      case 'N':
        is_non_sync_sample = true;
        break;
      default:
        CHECK(false) << "Invalid sync sample character '" << str[1] << "'";
        break;
    }
    uint32_t flags = static_cast<uint32_t>(sample_depends_on) << 24;
    if (is_non_sync_sample) flags |= kSampleIsNonSyncSample;
    return flags;
  }

  void SetFlagsOnSamples(const std::string& sample_info,
                         TrackFragmentRun* trun) {
    // US - SampleDependsOnUnknown & IsSyncSample
    // UN - SampleDependsOnUnknown & IsNonSyncSample
    // OS - SampleDependsOnOthers & IsSyncSample
    // ON - SampleDependsOnOthers & IsNonSyncSample
    // NS - SampleDependsOnNoOthers & IsSyncSample
    // NN - SampleDependsOnNoOthers & IsNonSyncSample
    std::vector<std::string> flags_data = base::SplitString(
        sample_info, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

    if (flags_data.size() == 1u) {
      // Simulates the first_sample_flags_present set scenario,
      // where only one sample_flag value is set and the default
      // flags are used for everything else.
      ASSERT_GE(trun->sample_count, flags_data.size());
    } else {
      ASSERT_EQ(trun->sample_count, flags_data.size());
    }

    trun->sample_flags.resize(flags_data.size());
    for (size_t i = 0; i < flags_data.size(); i++)
      trun->sample_flags[i] = ToSampleFlags(flags_data[i]);
  }

  std::string KeyframeAndRAPInfo(TrackRunIterator* iter) {
    CHECK(iter->IsRunValid());
    std::stringstream ss;
    ss << iter->track_id();

    while (iter->IsSampleValid()) {
      ss << " " << (iter->is_keyframe() ? "K" : "P");
      iter->AdvanceSample();
    }

    return ss.str();
  }

  MovieFragment CreateFragment() {
    MovieFragment moof;
    moof.tracks.resize(2);
    moof.tracks[0].decode_time.decode_time = 0;
    moof.tracks[0].header.track_id = 1;
    moof.tracks[0].header.has_default_sample_flags = true;
    moof.tracks[0].header.default_sample_flags = ToSampleFlags("US");
    moof.tracks[0].header.default_sample_duration = 1024;
    moof.tracks[0].header.default_sample_size = 4;
    moof.tracks[0].runs.resize(2);
    moof.tracks[0].runs[0].sample_count = 10;
    moof.tracks[0].runs[0].data_offset = 100;
    SetAscending(&moof.tracks[0].runs[0].sample_sizes);

    moof.tracks[0].runs[1].sample_count = 10;
    moof.tracks[0].runs[1].data_offset = 10000;

    moof.tracks[1].header.track_id = 2;
    moof.tracks[1].header.has_default_sample_flags = false;
    moof.tracks[1].decode_time.decode_time = 10;
    moof.tracks[1].runs.resize(1);
    moof.tracks[1].runs[0].sample_count = 10;
    moof.tracks[1].runs[0].data_offset = 200;
    SetAscending(&moof.tracks[1].runs[0].sample_sizes);
    SetAscending(&moof.tracks[1].runs[0].sample_durations);
    SetFlagsOnSamples("US UN UN UN UN UN UN UN UN UN", &moof.tracks[1].runs[0]);

    return moof;
  }

  // Update the first sample description of a Track to indicate encryption
  void AddEncryption(Track* track) {
    SampleDescription* stsd =
        &track->media.information.sample_table.description;
    ProtectionSchemeInfo* sinf;
    if (!stsd->video_entries.empty()) {
      sinf = &stsd->video_entries[0].sinf;
    } else {
      sinf = &stsd->audio_entries[0].sinf;
    }

    sinf->type.type = FOURCC_CENC;
    sinf->info.track_encryption.is_encrypted = true;
    sinf->info.track_encryption.default_iv_size = 8;
    sinf->info.track_encryption.default_kid.assign(kKeyId,
                                                   kKeyId + arraysize(kKeyId));
  }

  // Add SampleGroupDescription Box to track level sample table and to
  // fragment. Populate SampleToGroup Box from input array.
  void AddCencSampleGroup(Track* track, TrackFragment* frag,
                          const SampleToGroupEntry* sample_to_group_entries,
                          size_t num_entries) {
    auto& track_cenc_group =
        track->media.information.sample_table.sample_group_description;
    track_cenc_group.grouping_type = FOURCC_SEIG;
    track_cenc_group.entries.resize(1);
    track_cenc_group.entries[0].is_encrypted = true;
    track_cenc_group.entries[0].iv_size = 8;
    track_cenc_group.entries[0].key_id.assign(
        kTrackCencSampleGroupKeyId,
        kTrackCencSampleGroupKeyId + arraysize(kTrackCencSampleGroupKeyId));

    frag->sample_group_description.grouping_type = FOURCC_SEIG;
    frag->sample_group_description.entries.resize(3);
    frag->sample_group_description.entries[0].is_encrypted = false;
    frag->sample_group_description.entries[0].iv_size = 0;
    frag->sample_group_description.entries[1].is_encrypted = true;
    frag->sample_group_description.entries[1].iv_size = 8;
    frag->sample_group_description.entries[1].key_id.assign(
        kFragmentCencSampleGroupKeyId,
        kFragmentCencSampleGroupKeyId +
            arraysize(kFragmentCencSampleGroupKeyId));
    frag->sample_group_description.entries[2].is_encrypted = true;
    frag->sample_group_description.entries[2].iv_size = 16;
    frag->sample_group_description.entries[2].key_id.assign(
        kKeyId, kKeyId + arraysize(kKeyId));

    frag->sample_to_group.grouping_type = FOURCC_SEIG;
    frag->sample_to_group.entries.assign(sample_to_group_entries,
                                         sample_to_group_entries + num_entries);
  }

  // Add aux info covering the first track run to a TrackFragment, and update
  // the run to ensure it matches length and subsample information.
  void AddAuxInfoHeaders(int offset, TrackFragment* frag) {
    frag->auxiliary_offset.offsets.push_back(offset);
    frag->auxiliary_size.sample_count = 2;
    frag->auxiliary_size.sample_info_sizes.push_back(8);
    frag->auxiliary_size.sample_info_sizes.push_back(22);
    frag->runs[0].sample_count = 2;
    frag->runs[0].sample_sizes[1] = 10;
  }

  void AddSampleEncryption(uint8_t use_subsample_flag, TrackFragment* frag) {
    frag->sample_encryption.use_subsample_encryption = use_subsample_flag;
    if (use_subsample_flag) {
      frag->sample_encryption.sample_encryption_data.assign(
          kSampleEncryptionDataWithSubsamples,
          kSampleEncryptionDataWithSubsamples +
              arraysize(kSampleEncryptionDataWithSubsamples));
    } else {
      frag->sample_encryption.sample_encryption_data.assign(
          kSampleEncryptionDataWithoutSubsamples,
          kSampleEncryptionDataWithoutSubsamples +
              arraysize(kSampleEncryptionDataWithoutSubsamples));
    }

    // Update sample sizes and aux info header.
    frag->runs.resize(1);
    frag->runs[0].sample_count = 2;
    frag->auxiliary_offset.offsets.push_back(0);
    frag->auxiliary_size.sample_count = 2;
    if (use_subsample_flag) {
      // Update sample sizes to match with subsample entries above.
      frag->runs[0].sample_sizes[0] = 3;
      frag->runs[0].sample_sizes[1] = 10;
      // Set aux info header.
      frag->auxiliary_size.sample_info_sizes.push_back(16);
      frag->auxiliary_size.sample_info_sizes.push_back(30);
    } else {
      frag->auxiliary_size.default_sample_info_size = 8;
    }
  }

  bool InitMoofWithArbitraryAuxInfo(MovieFragment* moof) {
    // Add aux info header (equal sized aux info for every sample).
    for (uint32_t i = 0; i < moof->tracks.size(); ++i) {
      moof->tracks[i].auxiliary_offset.offsets.push_back(50);
      moof->tracks[i].auxiliary_size.sample_count = 10;
      moof->tracks[i].auxiliary_size.default_sample_info_size = 8;
    }

    // We don't care about the actual data in aux.
    std::vector<uint8_t> aux_info(1000);
    return iter_->Init(*moof) &&
           iter_->CacheAuxInfo(&aux_info[0], aux_info.size());
  }

  void SetAscending(std::vector<uint32_t>* vec) {
    vec->resize(10);
    for (size_t i = 0; i < vec->size(); i++) (*vec)[i] = i + 1;
  }
};

TEST_F(TrackRunIteratorTest, NoRunsTest) {
  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  ASSERT_TRUE(iter_->Init(MovieFragment()));
  EXPECT_FALSE(iter_->IsRunValid());
  EXPECT_FALSE(iter_->IsSampleValid());
}

TEST_F(TrackRunIteratorTest, BasicOperationTest) {
  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  MovieFragment moof = CreateFragment();

  // Test that runs are sorted correctly, and that properties of the initial
  // sample of the first run are correct
  ASSERT_TRUE(iter_->Init(moof));
  EXPECT_TRUE(iter_->IsRunValid());
  EXPECT_FALSE(iter_->is_encrypted());
  EXPECT_EQ(iter_->track_id(), 1u);
  EXPECT_EQ(iter_->sample_offset(), 100);
  EXPECT_EQ(iter_->sample_size(), 1);
  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(0, kAudioScale));
  EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(0, kAudioScale));
  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1024, kAudioScale));
  EXPECT_TRUE(iter_->is_keyframe());

  // Advance to the last sample in the current run, and test its properties
  for (int i = 0; i < 9; i++) iter_->AdvanceSample();
  EXPECT_EQ(iter_->track_id(), 1u);
  EXPECT_EQ(iter_->sample_offset(), 100 + kSumAscending1);
  EXPECT_EQ(iter_->sample_size(), 10);
  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(1024 * 9, kAudioScale));
  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1024, kAudioScale));
  EXPECT_TRUE(iter_->is_keyframe());

  // Test end-of-run
  iter_->AdvanceSample();
  EXPECT_FALSE(iter_->IsSampleValid());

  // Test last sample of next run
  iter_->AdvanceRun();
  EXPECT_TRUE(iter_->is_keyframe());
  for (int i = 0; i < 9; i++) iter_->AdvanceSample();
  EXPECT_EQ(iter_->track_id(), 2u);
  EXPECT_EQ(iter_->sample_offset(), 200 + kSumAscending1);
  EXPECT_EQ(iter_->sample_size(), 10);
  int64_t base_dts = kSumAscending1 + moof.tracks[1].decode_time.decode_time;
  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(base_dts, kVideoScale));
  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(10, kVideoScale));
  EXPECT_FALSE(iter_->is_keyframe());

  // Test final run
  iter_->AdvanceRun();
  EXPECT_EQ(iter_->track_id(), 1u);
  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(1024 * 10, kAudioScale));
  iter_->AdvanceSample();
  EXPECT_EQ(moof.tracks[0].runs[1].data_offset +
                moof.tracks[0].header.default_sample_size,
            iter_->sample_offset());
  iter_->AdvanceRun();
  EXPECT_FALSE(iter_->IsRunValid());
}

TEST_F(TrackRunIteratorTest, TrackExtendsDefaultsTest) {
  moov_.extends.tracks[0].default_sample_duration = 50;
  moov_.extends.tracks[0].default_sample_size = 3;
  moov_.extends.tracks[0].default_sample_flags = ToSampleFlags("UN");
  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  MovieFragment moof = CreateFragment();
  moof.tracks[0].header.has_default_sample_flags = false;
  moof.tracks[0].header.default_sample_size = 0;
  moof.tracks[0].header.default_sample_duration = 0;
  moof.tracks[0].runs[0].sample_sizes.clear();
  ASSERT_TRUE(iter_->Init(moof));
  iter_->AdvanceSample();
  EXPECT_FALSE(iter_->is_keyframe());
  EXPECT_EQ(iter_->sample_size(), 3);
  EXPECT_EQ(iter_->sample_offset(), moof.tracks[0].runs[0].data_offset + 3);
  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(50, kAudioScale));
  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(50, kAudioScale));
}

TEST_F(TrackRunIteratorTest, FirstSampleFlagTest) {
  // Ensure that keyframes are flagged correctly in the face of BMFF boxes which
  // explicitly specify the flags for the first sample in a run and rely on
  // defaults for all subsequent samples
  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  MovieFragment moof = CreateFragment();
  moof.tracks[1].header.has_default_sample_flags = true;
  moof.tracks[1].header.default_sample_flags = ToSampleFlags("UN");
  SetFlagsOnSamples("US", &moof.tracks[1].runs[0]);

  ASSERT_TRUE(iter_->Init(moof));
  EXPECT_EQ("1 K K K K K K K K K K", KeyframeAndRAPInfo(iter_.get()));

  iter_->AdvanceRun();
  EXPECT_EQ("2 K P P P P P P P P P", KeyframeAndRAPInfo(iter_.get()));
}

// Verify that parsing fails if a reserved value is in the sample flags.
TEST_F(TrackRunIteratorTest, SampleInfoTest_ReservedInSampleFlags) {
  EXPECT_MEDIA_LOG(ReservedValueInSampleDependencyInfo());
  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  MovieFragment moof = CreateFragment();
  // Change the "depends on" field on one of the samples to a
  // reserved value.
  moof.tracks[1].runs[0].sample_flags[0] = ToSampleFlags("RS");
  ASSERT_FALSE(iter_->Init(moof));
}

// Verify that parsing fails if a reserved value is in the default sample flags.
TEST_F(TrackRunIteratorTest, SampleInfoTest_ReservedInDefaultSampleFlags) {
  EXPECT_MEDIA_LOG(ReservedValueInSampleDependencyInfo());
  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  MovieFragment moof = CreateFragment();
  // Set the default flag to contain a reserved "depends on" value.
  moof.tracks[0].header.default_sample_flags = ToSampleFlags("RN");
  ASSERT_FALSE(iter_->Init(moof));
}

TEST_F(TrackRunIteratorTest, ReorderingTest) {
  // Test frame reordering and edit list support. The frames have the following
  // decode timestamps:
  //
  //   0ms 40ms   120ms     240ms
  //   | 0 | 1  - | 2  -  - |
  //
  // ...and these composition timestamps, after edit list adjustment:
  //
  //   0ms 40ms       160ms  240ms
  //   | 0 | 2  -  -  | 1 - |

  // Create an edit list with one entry, with an initial start time of 80ms
  // (that is, 2 / kVideoTimescale) and a duration of zero (which is treated as
  // infinite according to 14496-12:2012). This will cause the first 80ms of the
  // media timeline - which will be empty, due to CTS biasing - to be discarded.
  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  EditListEntry entry;
  entry.segment_duration = 0;
  entry.media_time = 2;
  entry.media_rate_integer = 1;
  entry.media_rate_fraction = 0;
  moov_.tracks[1].edit.list.edits.push_back(entry);

  // Add CTS offsets. Without bias, the CTS offsets for the first three frames
  // would simply be [0, 3, -2]. Since CTS offsets should be non-negative for
  // maximum compatibility, these values are biased up to [2, 5, 0], and the
  // extra 80ms is removed via the edit list.
  MovieFragment moof = CreateFragment();
  std::vector<int32_t>& cts_offsets =
      moof.tracks[1].runs[0].sample_composition_time_offsets;
  cts_offsets.resize(10);
  cts_offsets[0] = 2;
  cts_offsets[1] = 5;
  cts_offsets[2] = 0;
  moof.tracks[1].decode_time.decode_time = 0;

  ASSERT_TRUE(iter_->Init(moof));
  iter_->AdvanceRun();
  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(0, kVideoScale));
  EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(0, kVideoScale));
  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(1, kVideoScale));
  iter_->AdvanceSample();
  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(1, kVideoScale));
  EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(4, kVideoScale));
  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(2, kVideoScale));
  iter_->AdvanceSample();
  EXPECT_EQ(iter_->dts(), DecodeTimestampFromRational(3, kVideoScale));
  EXPECT_EQ(iter_->cts(), TimeDeltaFromRational(1, kVideoScale));
  EXPECT_EQ(iter_->duration(), TimeDeltaFromRational(3, kVideoScale));
}

TEST_F(TrackRunIteratorTest, IgnoreUnknownAuxInfoTest) {
  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  MovieFragment moof = CreateFragment();
  moof.tracks[1].auxiliary_offset.offsets.push_back(50);
  moof.tracks[1].auxiliary_size.default_sample_info_size = 2;
  moof.tracks[1].auxiliary_size.sample_count = 2;
  moof.tracks[1].runs[0].sample_count = 2;
  ASSERT_TRUE(iter_->Init(moof));
  iter_->AdvanceRun();
  EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached());
}

TEST_F(TrackRunIteratorTest,
       DecryptConfigTestWithSampleEncryptionAndNoSubsample) {
  AddEncryption(&moov_.tracks[1]);
  iter_.reset(new TrackRunIterator(&moov_, media_log_));

  MovieFragment moof = CreateFragment();
  AddSampleEncryption(!SampleEncryption::kUseSubsampleEncryption,
                      &moof.tracks[1]);

  ASSERT_TRUE(iter_->Init(moof));
  // The run for track 2 will be the second, which is parsed according to
  // data_offset.
  iter_->AdvanceRun();
  EXPECT_EQ(iter_->track_id(), 2u);

  EXPECT_TRUE(iter_->is_encrypted());
  // No need to cache aux info as it is already available in SampleEncryption.
  EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached());
  EXPECT_EQ(iter_->aux_info_size(), 0);
  EXPECT_EQ(iter_->sample_offset(), 200);
  EXPECT_EQ(iter_->GetMaxClearOffset(), moof.tracks[1].runs[0].data_offset);
  std::unique_ptr<DecryptConfig> config = iter_->GetDecryptConfig();
  EXPECT_EQ(
      std::string(reinterpret_cast<const char*>(kKeyId), arraysize(kKeyId)),
      config->key_id());
  EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv1), arraysize(kIv1)),
            config->iv());
  EXPECT_EQ(config->subsamples().size(), 0u);
  iter_->AdvanceSample();
  config = iter_->GetDecryptConfig();
  EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv2), arraysize(kIv2)),
            config->iv());
  EXPECT_EQ(config->subsamples().size(), 0u);
}

TEST_F(TrackRunIteratorTest,
       DecryptConfigTestWithSampleEncryptionAndSubsample) {
  AddEncryption(&moov_.tracks[1]);
  iter_.reset(new TrackRunIterator(&moov_, media_log_));

  MovieFragment moof = CreateFragment();
  AddSampleEncryption(SampleEncryption::kUseSubsampleEncryption,
                      &moof.tracks[1]);
  const SampleToGroupEntry kSampleToGroupTable[] = {
      // Associated with the second entry in SampleGroupDescription Box.
      // With Iv size 8 bytes.
      {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2},
      // Associated with the third entry in SampleGroupDescription Box.
      // With Iv size 16 bytes.
      {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 3}};
  AddCencSampleGroup(&moov_.tracks[1], &moof.tracks[1], kSampleToGroupTable,
                     arraysize(kSampleToGroupTable));

  ASSERT_TRUE(iter_->Init(moof));
  // The run for track 2 will be the second, which is parsed according to
  // data_offset.
  iter_->AdvanceRun();
  EXPECT_EQ(iter_->track_id(), 2u);

  EXPECT_TRUE(iter_->is_encrypted());
  // No need to cache aux info as it is already available in SampleEncryption.
  EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached());
  EXPECT_EQ(iter_->aux_info_size(), 0);
  EXPECT_EQ(iter_->sample_offset(), 200);
  EXPECT_EQ(iter_->GetMaxClearOffset(), moof.tracks[1].runs[0].data_offset);
  std::unique_ptr<DecryptConfig> config = iter_->GetDecryptConfig();
  EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv1), arraysize(kIv1)),
            config->iv());
  EXPECT_EQ(config->subsamples().size(), 1u);
  EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u);
  EXPECT_EQ(config->subsamples()[0].cypher_bytes, 2u);
  iter_->AdvanceSample();
  config = iter_->GetDecryptConfig();
  EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv3), arraysize(kIv3)),
            config->iv());
  EXPECT_EQ(config->subsamples().size(), 2u);
  EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u);
  EXPECT_EQ(config->subsamples()[0].cypher_bytes, 2u);
  EXPECT_EQ(config->subsamples()[1].clear_bytes, 3u);
  EXPECT_EQ(config->subsamples()[1].cypher_bytes, 4u);
}

TEST_F(TrackRunIteratorTest, DecryptConfigTestWithAuxInfo) {
  AddEncryption(&moov_.tracks[1]);
  iter_.reset(new TrackRunIterator(&moov_, media_log_));

  MovieFragment moof = CreateFragment();
  AddAuxInfoHeaders(50, &moof.tracks[1]);

  ASSERT_TRUE(iter_->Init(moof));

  // The run for track 2 will be first, since its aux info offset is the first
  // element in the file.
  EXPECT_EQ(iter_->track_id(), 2u);
  EXPECT_TRUE(iter_->is_encrypted());
  ASSERT_TRUE(iter_->AuxInfoNeedsToBeCached());
  EXPECT_EQ(static_cast<uint32_t>(iter_->aux_info_size()), arraysize(kAuxInfo));
  EXPECT_EQ(iter_->aux_info_offset(), 50);
  EXPECT_EQ(iter_->GetMaxClearOffset(), 50);
  EXPECT_FALSE(iter_->CacheAuxInfo(NULL, 0));
  EXPECT_FALSE(iter_->CacheAuxInfo(kAuxInfo, 3));
  EXPECT_TRUE(iter_->AuxInfoNeedsToBeCached());
  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
  EXPECT_FALSE(iter_->AuxInfoNeedsToBeCached());
  EXPECT_EQ(iter_->sample_offset(), 200);
  EXPECT_EQ(iter_->GetMaxClearOffset(), moof.tracks[0].runs[0].data_offset);
  std::unique_ptr<DecryptConfig> config = iter_->GetDecryptConfig();
  EXPECT_EQ(
      std::string(reinterpret_cast<const char*>(kKeyId), arraysize(kKeyId)),
      config->key_id());
  EXPECT_EQ(std::string(reinterpret_cast<const char*>(kIv1), arraysize(kIv1)),
            config->iv());
  EXPECT_TRUE(config->subsamples().empty());
  iter_->AdvanceSample();
  config = iter_->GetDecryptConfig();
  EXPECT_EQ(config->subsamples().size(), 2u);
  EXPECT_EQ(config->subsamples()[0].clear_bytes, 1u);
  EXPECT_EQ(config->subsamples()[1].cypher_bytes, 4u);
}

TEST_F(TrackRunIteratorTest, CencSampleGroupTest) {
  MovieFragment moof = CreateFragment();

  const SampleToGroupEntry kSampleToGroupTable[] = {
      // Associated with the second entry in SampleGroupDescription Box.
      {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2},
      // Associated with the first entry in SampleGroupDescription Box.
      {1, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 1}};
  AddCencSampleGroup(&moov_.tracks[0], &moof.tracks[0], kSampleToGroupTable,
                     arraysize(kSampleToGroupTable));

  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  ASSERT_TRUE(InitMoofWithArbitraryAuxInfo(&moof));

  std::string cenc_sample_group_key_id(
      kFragmentCencSampleGroupKeyId,
      kFragmentCencSampleGroupKeyId + arraysize(kFragmentCencSampleGroupKeyId));
  // The first sample is encrypted and the second sample is unencrypted.
  EXPECT_TRUE(iter_->is_encrypted());
  EXPECT_EQ(cenc_sample_group_key_id, iter_->GetDecryptConfig()->key_id());
  iter_->AdvanceSample();
  EXPECT_FALSE(iter_->is_encrypted());
}

TEST_F(TrackRunIteratorTest, CencSampleGroupWithTrackEncryptionBoxTest) {
  // Add TrackEncryption Box.
  AddEncryption(&moov_.tracks[0]);

  MovieFragment moof = CreateFragment();

  const SampleToGroupEntry kSampleToGroupTable[] = {
      // Associated with the 2nd entry in fragment SampleGroupDescription Box.
      {2, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 2},
      // Associated with the default values specified in TrackEncryption Box.
      {1, 0},
      // Associated with the 1st entry in fragment SampleGroupDescription Box.
      {3, SampleToGroupEntry::kFragmentGroupDescriptionIndexBase + 1},
      // Associated with the 1st entry in track SampleGroupDescription Box.
      {2, 1}};
  AddCencSampleGroup(&moov_.tracks[0], &moof.tracks[0], kSampleToGroupTable,
                     arraysize(kSampleToGroupTable));

  iter_.reset(new TrackRunIterator(&moov_, media_log_));
  ASSERT_TRUE(InitMoofWithArbitraryAuxInfo(&moof));

  std::string track_encryption_key_id(kKeyId, kKeyId + arraysize(kKeyId));
  std::string track_cenc_sample_group_key_id(
      kTrackCencSampleGroupKeyId,
      kTrackCencSampleGroupKeyId + arraysize(kTrackCencSampleGroupKeyId));
  std::string fragment_cenc_sample_group_key_id(
      kFragmentCencSampleGroupKeyId,
      kFragmentCencSampleGroupKeyId + arraysize(kFragmentCencSampleGroupKeyId));

  for (size_t i = 0; i < kSampleToGroupTable[0].sample_count; ++i) {
    EXPECT_TRUE(iter_->is_encrypted());
    EXPECT_EQ(fragment_cenc_sample_group_key_id,
              iter_->GetDecryptConfig()->key_id());
    iter_->AdvanceSample();
  }

  for (size_t i = 0; i < kSampleToGroupTable[1].sample_count; ++i) {
    EXPECT_TRUE(iter_->is_encrypted());
    EXPECT_EQ(track_encryption_key_id, iter_->GetDecryptConfig()->key_id());
    iter_->AdvanceSample();
  }

  for (size_t i = 0; i < kSampleToGroupTable[2].sample_count; ++i) {
    EXPECT_FALSE(iter_->is_encrypted());
    iter_->AdvanceSample();
  }

  for (size_t i = 0; i < kSampleToGroupTable[3].sample_count; ++i) {
    EXPECT_TRUE(iter_->is_encrypted());
    EXPECT_EQ(track_cenc_sample_group_key_id,
              iter_->GetDecryptConfig()->key_id());
    iter_->AdvanceSample();
  }

  // The remaining samples should be associated with the default values
  // specified in TrackEncryption Box.
  EXPECT_TRUE(iter_->is_encrypted());
  EXPECT_EQ(track_encryption_key_id, iter_->GetDecryptConfig()->key_id());
}

// It is legal for aux info blocks to be shared among multiple formats.
TEST_F(TrackRunIteratorTest, SharedAuxInfoTest) {
  AddEncryption(&moov_.tracks[0]);
  AddEncryption(&moov_.tracks[1]);
  iter_.reset(new TrackRunIterator(&moov_, media_log_));

  MovieFragment moof = CreateFragment();
  moof.tracks[0].runs.resize(1);
  AddAuxInfoHeaders(50, &moof.tracks[0]);
  AddAuxInfoHeaders(50, &moof.tracks[1]);
  moof.tracks[0].auxiliary_size.default_sample_info_size = 8;

  ASSERT_TRUE(iter_->Init(moof));
  EXPECT_EQ(iter_->track_id(), 1u);
  EXPECT_EQ(iter_->aux_info_offset(), 50);
  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
  std::unique_ptr<DecryptConfig> config = iter_->GetDecryptConfig();
  ASSERT_EQ(arraysize(kIv1), config->iv().size());
  EXPECT_TRUE(!SbMemoryCompare(kIv1, config->iv().data(), config->iv().size()));
  iter_->AdvanceSample();
  EXPECT_EQ(iter_->GetMaxClearOffset(), 50);
  iter_->AdvanceRun();
  EXPECT_EQ(iter_->GetMaxClearOffset(), 50);
  EXPECT_EQ(iter_->aux_info_offset(), 50);
  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
  EXPECT_EQ(iter_->GetMaxClearOffset(), 200);
  ASSERT_EQ(arraysize(kIv1), config->iv().size());
  EXPECT_TRUE(!SbMemoryCompare(kIv1, config->iv().data(), config->iv().size()));
  iter_->AdvanceSample();
  EXPECT_EQ(iter_->GetMaxClearOffset(), 201);
}

// Sensible files are expected to place auxiliary information for a run
// immediately before the main data for that run. Alternative schemes are
// possible, however, including the somewhat reasonable behavior of placing all
// aux info at the head of the 'mdat' box together, and the completely
// unreasonable behavior demonstrated here:
//  byte 50: track 2, run 1 aux info
//  byte 100: track 1, run 1 data
//  byte 200: track 2, run 1 data
//  byte 201: track 1, run 2 aux info (*inside* track 2, run 1 data)
//  byte 10000: track 1, run 2 data
//  byte 20000: track 1, run 1 aux info
TEST_F(TrackRunIteratorTest, UnexpectedOrderingTest) {
  AddEncryption(&moov_.tracks[0]);
  AddEncryption(&moov_.tracks[1]);
  iter_.reset(new TrackRunIterator(&moov_, media_log_));

  MovieFragment moof = CreateFragment();
  AddAuxInfoHeaders(20000, &moof.tracks[0]);
  moof.tracks[0].auxiliary_offset.offsets.push_back(201);
  moof.tracks[0].auxiliary_size.sample_count += 2;
  moof.tracks[0].auxiliary_size.default_sample_info_size = 8;
  moof.tracks[0].runs[1].sample_count = 2;
  AddAuxInfoHeaders(50, &moof.tracks[1]);
  moof.tracks[1].runs[0].sample_sizes[0] = 5;

  ASSERT_TRUE(iter_->Init(moof));
  EXPECT_EQ(iter_->track_id(), 2u);
  EXPECT_EQ(iter_->aux_info_offset(), 50);
  EXPECT_EQ(iter_->sample_offset(), 200);
  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
  EXPECT_EQ(iter_->GetMaxClearOffset(), 100);
  iter_->AdvanceRun();
  EXPECT_EQ(iter_->track_id(), 1u);
  EXPECT_EQ(iter_->aux_info_offset(), 20000);
  EXPECT_EQ(iter_->sample_offset(), 100);
  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
  EXPECT_EQ(iter_->GetMaxClearOffset(), 100);
  iter_->AdvanceSample();
  EXPECT_EQ(iter_->GetMaxClearOffset(), 101);
  iter_->AdvanceRun();
  EXPECT_EQ(iter_->track_id(), 1u);
  EXPECT_EQ(iter_->aux_info_offset(), 201);
  EXPECT_EQ(iter_->sample_offset(), 10000);
  EXPECT_EQ(iter_->GetMaxClearOffset(), 201);
  EXPECT_TRUE(iter_->CacheAuxInfo(kAuxInfo, arraysize(kAuxInfo)));
  EXPECT_EQ(iter_->GetMaxClearOffset(), 10000);
}

TEST_F(TrackRunIteratorTest, KeyFrameFlagCombinations) {
  // Setup both audio and video tracks to each have 6 samples covering all the
  // combinations of mp4 "sync sample" and "depends on" relationships.
  MovieFragment moof = CreateFragment();
  moof.tracks[0].runs.resize(1);
  moof.tracks[1].runs.resize(1);
  moof.tracks[0].runs[0].sample_count = 6;
  moof.tracks[1].runs[0].sample_count = 6;
  SetFlagsOnSamples("US UN OS ON NS NN", &moof.tracks[0].runs[0]);
  SetFlagsOnSamples("US UN OS ON NS NN", &moof.tracks[1].runs[0]);
  iter_.reset(new TrackRunIterator(&moov_, media_log_));

  ASSERT_TRUE(iter_->Init(moof));
  EXPECT_TRUE(iter_->IsRunValid());

  // Keyframes should be marked according to downstream's expectations that
  // keyframes serve as points of random access for seeking.

  // For audio, any sync sample should be marked as a key frame. Whether a
  // sample "depends on" other samples is not considered. Unlike video samples,
  // audio samples are often marked as depending on other samples but are still
  // workable for random access. While we allow for parsing of audio samples
  // that are non-sync samples, we generally expect all audio samples to be sync
  // samples and downstream will log and discard any non-sync audio samples.
  EXPECT_EQ("1 K P K P K P", KeyframeAndRAPInfo(iter_.get()));

  iter_->AdvanceRun();

  // For video, any key frame should be both a sync sample and have no known
  // dependents. Ideally, a video sync sample should always be marked as having
  // no dependents, but we occasionally encounter media where all samples are
  // marked "sync" and we must rely on combining the two flags to pick out the
  // true key frames. See http://crbug.com/310712 and http://crbug.com/507916.
  // Realiably knowing the keyframes for video is also critical to SPS PPS
  // insertion.
  EXPECT_EQ("2 K P P P K P", KeyframeAndRAPInfo(iter_.get()));
}

}  // namespace mp4
}  // namespace media
}  // namespace cobalt
