// 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 "media/formats/mp4/track_run_iterator.h"

#include <algorithm>
#include <iomanip>
#include <limits>
#include <memory>

#include "base/metrics/histogram_macros.h"
#include "base/numerics/checked_math.h"
#include "base/numerics/safe_conversions.h"
#include "base/stl_util.h"
#include "media/base/demuxer_memory_limit.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_util.h"
#include "media/base/timestamp_constants.h"
#include "media/formats/mp4/rcheck.h"
#include "media/formats/mp4/sample_to_group_iterator.h"
#include "media/media_buildflags.h"

namespace media {
namespace mp4 {

struct SampleInfo {
  uint32_t size;
  uint32_t duration;
  int64_t cts_offset;
  bool is_keyframe;
  uint32_t cenc_group_description_index;
};

struct TrackRunInfo {
  uint32_t track_id;
  std::vector<SampleInfo> samples;
  int64_t timescale;
  int64_t start_dts;
  int64_t sample_start_offset;

  bool is_audio;
  const AudioSampleEntry* audio_description;
  const VideoSampleEntry* video_description;
  const SampleGroupDescription* track_sample_encryption_group;

  // Stores sample encryption entries, which is populated from 'senc' box if it
  // is available, otherwise will try to load from cenc auxiliary information.
  std::vector<SampleEncryptionEntry> sample_encryption_entries;

  // These variables are useful to load |sample_encryption_entries| from cenc
  // auxiliary information when 'senc' box is not available.
  int64_t aux_info_start_offset;  // Only valid if aux_info_total_size > 0.
  int aux_info_default_size;
  std::vector<uint8_t> aux_info_sizes;  // Populated if default_size == 0.
  int aux_info_total_size;

  EncryptionScheme encryption_scheme;

  std::vector<CencSampleEncryptionInfoEntry> fragment_sample_encryption_info;

  TrackRunInfo();
  ~TrackRunInfo();
};

TrackRunInfo::TrackRunInfo()
    : track_id(0),
      timescale(-1),
      start_dts(-1),
      sample_start_offset(-1),
      is_audio(false),
      aux_info_start_offset(-1),
      aux_info_default_size(-1),
      aux_info_total_size(-1) {
}
TrackRunInfo::~TrackRunInfo() = default;

base::TimeDelta TimeDeltaFromRational(int64_t numer, int64_t denom) {
  // TODO(sandersd): Change all callers to pass a |denom| as a uint32_t. This is
  // the correct (and sufficient) type in all cases, but some intermediaries
  // currently store -1 as a default value.
  // TODO(sandersd): Change all callers to pass |numer| as a uint64_t. The few
  // cases that could theoretically be negative would result in negative PTS
  // anyway, and there are cases where an int64_t is not sufficient to store the
  // entire representable range.
  DCHECK_GT(denom, 0);
  DCHECK_LE(denom, std::numeric_limits<uint32_t>::max());

  // The maximum number of seconds that a TimeDelta can hold (about 300,000
  // years worth). There is a (t ~= 0.775)-second fraction that is ignored.
  const int64_t max_seconds =
      std::numeric_limits<int64_t>::max() / base::Time::kMicrosecondsPerSecond;

  // The integer part of the result, in seconds. There is a (0 <= f < 1)-second
  // fraction that is not computed. (Also true for negative |numer|, since
  // rounding of integer division is towards zero in C++.)
  const int64_t result_seconds = numer / denom;

  // Reject |actual_seconds == max_seconds| under the assumption that f > t.
  // This rejects valid times that are within t seconds of the limit.
  if (result_seconds >= max_seconds || result_seconds <= -max_seconds)
    return kNoTimestamp;

  // Since (denom <= 2 ** 32), the multiplication fits in 52 bits.
  // Note: When |numer| is negative, (numer % denom) is also negative. C++
  // guarantees that ((numer / denom) * denom + (numer % denom) == numer).
  // TODO(sandersd): Is round-toward-zero the best possible computation here?
  const int64_t result_microseconds =
      base::Time::kMicrosecondsPerSecond * (numer % denom) / denom;

  const int64_t total_microseconds =
      base::Time::kMicrosecondsPerSecond * result_seconds + result_microseconds;
  return base::TimeDelta::FromMicroseconds(total_microseconds);
}

DecodeTimestamp DecodeTimestampFromRational(int64_t numer, int64_t denom) {
  return DecodeTimestamp::FromPresentationTime(
      TimeDeltaFromRational(numer, denom));
}

TrackRunIterator::TrackRunIterator(const Movie* moov, MediaLog* media_log)
    : moov_(moov), media_log_(media_log), sample_offset_(0) {
  CHECK(moov);
}

TrackRunIterator::~TrackRunIterator() = default;

static std::string HexFlags(uint32_t flags) {
  std::stringstream stream;
  stream << std::setfill('0') << std::setw(sizeof(flags)*2) << std::hex
         << flags;
  return stream.str();
}

static bool PopulateSampleInfo(const TrackExtends& trex,
                               const TrackFragmentHeader& tfhd,
                               const TrackFragmentRun& trun,
                               const int64_t edit_list_offset,
                               const uint32_t i,
                               SampleInfo* sample_info,
                               const SampleDependsOn sdtp_sample_depends_on,
                               bool is_audio,
                               MediaLog* media_log) {
  if (i < trun.sample_sizes.size()) {
    sample_info->size = trun.sample_sizes[i];
  } else if (tfhd.default_sample_size > 0) {
    sample_info->size = tfhd.default_sample_size;
  } else {
    sample_info->size = trex.default_sample_size;
  }

  if (i < trun.sample_durations.size()) {
    sample_info->duration = trun.sample_durations[i];
  } else if (tfhd.default_sample_duration > 0) {
    sample_info->duration = tfhd.default_sample_duration;
  } else {
    sample_info->duration = trex.default_sample_duration;
  }

  auto cts_offset = -base::CheckedNumeric<int64_t>(edit_list_offset);
  if (i < trun.sample_composition_time_offsets.size())
    cts_offset += trun.sample_composition_time_offsets[i];
  if (!cts_offset.AssignIfValid(&sample_info->cts_offset)) {
    MEDIA_LOG(ERROR, media_log) << "PTS offset exceeds representable range.";
    return false;
  }

  uint32_t flags;
  if (i < trun.sample_flags.size()) {
    flags = trun.sample_flags[i];
    DVLOG(4) << __func__ << " trun sample flags " << HexFlags(flags);
  } else if (tfhd.has_default_sample_flags) {
    flags = tfhd.default_sample_flags;
    DVLOG(4) << __func__ << " tfhd sample flags " << HexFlags(flags);
  } else {
    flags = trex.default_sample_flags;
    DVLOG(4) << __func__ << " trex sample flags " << HexFlags(flags);
  }

  SampleDependsOn sample_depends_on =
      static_cast<SampleDependsOn>((flags >> 24) & 0x3);
  if (sample_depends_on == kSampleDependsOnUnknown) {
    sample_depends_on = sdtp_sample_depends_on;
  }
  DVLOG(4) << __func__ << " sample_depends_on " << sample_depends_on;
  if (sample_depends_on == kSampleDependsOnReserved) {
    MEDIA_LOG(ERROR, media_log) << "Reserved value used in sample dependency"
                                   " info.";
    return false;
  }

  // Per spec (ISO 14496-12:2012), the definition for a "sync sample" is
  // equivalent to the downstream code's "is keyframe" concept. But media exists
  // that marks non-key video frames as sync samples (http://crbug.com/507916
  // and http://crbug.com/310712). Hence, for video we additionally check that
  // the sample does not depend on others (FFmpeg does too, see mov_read_trun).
  // Sample dependency is ignored for audio because encoded audio samples can
  // depend on other samples and still be used for random access. Generally all
  // audio samples are expected to be sync samples, but we  prefer to check the
  // flags to catch badly muxed audio (for now anyway ;P). History of attempts
  // to get this right discussed in http://crrev.com/1319813002
  bool sample_is_sync_sample = !(flags & kSampleIsNonSyncSample);
  bool sample_depends_on_others = sample_depends_on == kSampleDependsOnOthers;
  sample_info->is_keyframe = sample_is_sync_sample &&
                             (!sample_depends_on_others || is_audio);

  DVLOG(4) << __func__ << " is_kf:" << sample_info->is_keyframe
           << " is_sync:" << sample_is_sync_sample
           << " deps:" << sample_depends_on_others << " audio:" << is_audio;

  return true;
}

static const CencSampleEncryptionInfoEntry* GetSampleEncryptionInfoEntry(
    const TrackRunInfo& run_info,
    uint32_t group_description_index) {
  const std::vector<CencSampleEncryptionInfoEntry>* entries = nullptr;

  // ISO-14496-12 Section 8.9.2.3 and 8.9.4 : group description index
  // (1) ranges from 1 to the number of sample group entries in the track
  // level SampleGroupDescription Box, or (2) takes the value 0 to
  // indicate that this sample is a member of no group, in this case, the
  // sample is associated with the default values specified in
  // TrackEncryption Box, or (3) starts at 0x10001, i.e. the index value
  // 1, with the value 1 in the top 16 bits, to reference fragment-local
  // SampleGroupDescription Box.
  // Case (2) is not supported here. The caller must handle it externally
  // before invoking this function.
  DCHECK_NE(group_description_index, 0u);
  if (group_description_index >
      SampleToGroupEntry::kFragmentGroupDescriptionIndexBase) {
    group_description_index -=
        SampleToGroupEntry::kFragmentGroupDescriptionIndexBase;
    entries = &run_info.fragment_sample_encryption_info;
  } else {
    entries = &run_info.track_sample_encryption_group->entries;
  }

  // |group_description_index| is 1-based.
  return (group_description_index > entries->size())
             ? nullptr
             : &(*entries)[group_description_index - 1];
}

// In well-structured encrypted media, each track run will be immediately
// preceded by its auxiliary information; this is the only optimal storage
// pattern in terms of minimum number of bytes from a serial stream needed to
// begin playback. It also allows us to optimize caching on memory-constrained
// architectures, because we can cache the relatively small auxiliary
// information for an entire run and then discard data from the input stream,
// instead of retaining the entire 'mdat' box.
//
// We optimize for this situation (with no loss of generality) by sorting track
// runs during iteration in order of their first data offset (either sample data
// or auxiliary data).
class CompareMinTrackRunDataOffset {
 public:
  bool operator()(const TrackRunInfo& a, const TrackRunInfo& b) {
    int64_t a_aux = a.aux_info_total_size ? a.aux_info_start_offset
                                          : std::numeric_limits<int64_t>::max();
    int64_t b_aux = b.aux_info_total_size ? b.aux_info_start_offset
                                          : std::numeric_limits<int64_t>::max();

    int64_t a_lesser = std::min(a_aux, a.sample_start_offset);
    int64_t a_greater = std::max(a_aux, a.sample_start_offset);
    int64_t b_lesser = std::min(b_aux, b.sample_start_offset);
    int64_t b_greater = std::max(b_aux, b.sample_start_offset);

    if (a_lesser == b_lesser) return a_greater < b_greater;
    return a_lesser < b_lesser;
  }
};

bool TrackRunIterator::Init(const MovieFragment& moof) {
  runs_.clear();

  for (size_t i = 0; i < moof.tracks.size(); i++) {
    const TrackFragment& traf = moof.tracks[i];

    const Track* trak = NULL;
    for (size_t t = 0; t < moov_->tracks.size(); t++) {
      if (moov_->tracks[t].header.track_id == traf.header.track_id)
        trak = &moov_->tracks[t];
    }
    RCHECK(trak);

    const TrackExtends* trex = NULL;
    for (size_t t = 0; t < moov_->extends.tracks.size(); t++) {
      if (moov_->extends.tracks[t].track_id == traf.header.track_id)
        trex = &moov_->extends.tracks[t];
    }
    RCHECK(trex);

    const SampleDescription& stsd =
        trak->media.information.sample_table.description;
    if (stsd.type != kAudio && stsd.type != kVideo) {
      DVLOG(1) << "Skipping unhandled track type";
      continue;
    }
    size_t desc_idx = traf.header.sample_description_index;
    if (!desc_idx) desc_idx = trex->default_sample_description_index;
    RCHECK(desc_idx > 0);  // Descriptions are one-indexed in the file
    desc_idx -= 1;

    const std::vector<uint8_t>& sample_encryption_data =
        traf.sample_encryption.sample_encryption_data;
    std::unique_ptr<BufferReader> sample_encryption_reader;
    uint32_t sample_encryption_entries_count = 0;
    if (!sample_encryption_data.empty()) {
      sample_encryption_reader.reset(new BufferReader(
          sample_encryption_data.data(), sample_encryption_data.size()));
      RCHECK(sample_encryption_reader->Read4(&sample_encryption_entries_count));
    }

    // Process edit list to remove CTS offset introduced in the presence of
    // B-frames (those that contain a single edit with a nonnegative media
    // time). Other uses of edit lists are not supported, as they are
    // both uncommon and better served by higher-level protocols.
    int64_t edit_list_offset = 0;
    const std::vector<EditListEntry>& edits = trak->edit.list.edits;
    if (!edits.empty()) {
      if (edits.size() > 1)
        DVLOG(1) << "Multi-entry edit box detected; some components ignored.";

      if (edits[0].media_time < 0) {
        DVLOG(1) << "Empty edit list entry ignored.";
      } else {
        edit_list_offset = edits[0].media_time;
      }
    }

    SampleToGroupIterator sample_to_group_itr(traf.sample_to_group);
    bool is_sample_to_group_valid = sample_to_group_itr.IsValid();

    int64_t run_start_dts = traf.decode_time.decode_time;
    uint64_t sample_count_sum = 0;
    for (size_t j = 0; j < traf.runs.size(); j++) {
      const TrackFragmentRun& trun = traf.runs[j];
      TrackRunInfo tri;
      tri.track_id = traf.header.track_id;
      tri.timescale = trak->media.header.timescale;
      tri.start_dts = run_start_dts;
      tri.sample_start_offset = trun.data_offset;
      tri.track_sample_encryption_group =
          &trak->media.information.sample_table.sample_group_description;
      tri.fragment_sample_encryption_info =
          traf.sample_group_description.entries;

      const TrackEncryption* track_encryption;
      const ProtectionSchemeInfo* sinf;
      tri.is_audio = (stsd.type == kAudio);
      if (tri.is_audio) {
        RCHECK(!stsd.audio_entries.empty());
        if (desc_idx >= stsd.audio_entries.size())
          desc_idx = 0;
        tri.audio_description = &stsd.audio_entries[desc_idx];
        sinf = &tri.audio_description->sinf;
        track_encryption = &tri.audio_description->sinf.info.track_encryption;
      } else {
        RCHECK(!stsd.video_entries.empty());
        if (desc_idx >= stsd.video_entries.size())
          desc_idx = 0;
        tri.video_description = &stsd.video_entries[desc_idx];
        sinf = &tri.video_description->sinf;
        track_encryption = &tri.video_description->sinf.info.track_encryption;
      }

      if (!sinf->HasSupportedScheme()) {
        tri.encryption_scheme = Unencrypted();
      } else {
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
        tri.encryption_scheme = EncryptionScheme(
            sinf->IsCbcsEncryptionScheme()
                ? EncryptionScheme::CIPHER_MODE_AES_CBC
                : EncryptionScheme::CIPHER_MODE_AES_CTR,
            EncryptionPattern(track_encryption->default_crypt_byte_block,
                              track_encryption->default_skip_byte_block));
#else
        DCHECK(!sinf->IsCbcsEncryptionScheme());
        tri.encryption_scheme = AesCtrEncryptionScheme();
#endif
      }

      // Initialize aux_info variables only if no sample encryption entries.
      if (sample_encryption_entries_count == 0 &&
          traf.auxiliary_offset.offsets.size() > j) {
        // Collect information from the auxiliary_offset entry with the same
        // index in the 'saiz' container as the current run's index in the
        // 'trun' container, if it is present.
        // There should be an auxiliary info entry corresponding to each sample
        // in the auxiliary offset entry's corresponding track run.
        RCHECK(traf.auxiliary_size.sample_count >=
               sample_count_sum + trun.sample_count);
        tri.aux_info_start_offset = traf.auxiliary_offset.offsets[j];
        tri.aux_info_default_size =
            traf.auxiliary_size.default_sample_info_size;
        if (tri.aux_info_default_size == 0) {
          const std::vector<uint8_t>& sizes =
              traf.auxiliary_size.sample_info_sizes;
          tri.aux_info_sizes.insert(
              tri.aux_info_sizes.begin(), sizes.begin() + sample_count_sum,
              sizes.begin() + sample_count_sum + trun.sample_count);
        }

        // If the default info size is positive, find the total size of the aux
        // info block from it, otherwise sum over the individual sizes of each
        // aux info entry in the aux_offset entry.
        if (tri.aux_info_default_size) {
          tri.aux_info_total_size =
              tri.aux_info_default_size * trun.sample_count;
        } else {
          tri.aux_info_total_size = 0;
          for (size_t k = 0; k < trun.sample_count; k++) {
            tri.aux_info_total_size += tri.aux_info_sizes[k];
          }
        }
      } else {
        tri.aux_info_start_offset = -1;
        tri.aux_info_total_size = 0;
      }

      // Avoid allocating insane sample counts for invalid media.
      const size_t max_sample_count =
          GetDemuxerMemoryLimit() / sizeof(decltype(tri.samples)::value_type);
      RCHECK_MEDIA_LOGGED(
          base::strict_cast<size_t>(trun.sample_count) <= max_sample_count,
          media_log_, "Metadata overhead exceeds storage limit.");
      tri.samples.resize(trun.sample_count);

      int empty_sample_count = 0;
      int empty_samples_in_sequence_count = 0;

      UMA_HISTOGRAM_COUNTS_1M("Media.MSE.Mp4TrunSampleCount",
                              trun.sample_count);

      for (size_t k = 0; k < trun.sample_count; k++) {
        if (!PopulateSampleInfo(*trex, traf.header, trun, edit_list_offset, k,
                                &tri.samples[k], traf.sdtp.sample_depends_on(k),
                                tri.is_audio, media_log_)) {
          return false;
        }

        UMA_HISTOGRAM_COUNTS_1M("Media.MSE.Mp4SampleSize", tri.samples[k].size);

        if (tri.samples[k].size == 0) {
          empty_sample_count++;
          empty_samples_in_sequence_count++;
        }

        // Report the number of consecutive zero-sized samples seen in a
        // sequence. Can report counts for 1 or more such sequences within the
        // same trun, and a sequence can be as short as just 1 empty sample.
        if (empty_samples_in_sequence_count &&
            (tri.samples[k].size != 0 || k == trun.sample_count - 1)) {
          UMA_HISTOGRAM_COUNTS_1M("Media.MSE.Mp4ConsecutiveEmptySamples",
                                  empty_samples_in_sequence_count);
          empty_samples_in_sequence_count = 0;
        }

        RCHECK(std::numeric_limits<int64_t>::max() - tri.samples[k].duration >
               run_start_dts);

        run_start_dts += tri.samples[k].duration;

        if (!is_sample_to_group_valid) {
          // Set group description index to 0 to read encryption information
          // from TrackEncryption Box.
          tri.samples[k].cenc_group_description_index = 0;
          continue;
        }

        uint32_t index = sample_to_group_itr.group_description_index();
        tri.samples[k].cenc_group_description_index = index;
        if (index != 0)
          RCHECK(GetSampleEncryptionInfoEntry(tri, index));
        is_sample_to_group_valid = sample_to_group_itr.Advance();
      }

      UMA_HISTOGRAM_COUNTS_1M("Media.MSE.Mp4EmptySamplesInTRun",
                              empty_sample_count);

      if (sample_encryption_entries_count > 0) {
        RCHECK(sample_encryption_entries_count >=
               sample_count_sum + trun.sample_count);
        tri.sample_encryption_entries.resize(trun.sample_count);
        for (size_t k = 0; k < trun.sample_count; k++) {
          uint32_t index = tri.samples[k].cenc_group_description_index;
          const CencSampleEncryptionInfoEntry* info_entry =
              index == 0 ? nullptr : GetSampleEncryptionInfoEntry(tri, index);
          const uint8_t iv_size = index == 0 ? track_encryption->default_iv_size
                                             : info_entry->iv_size;
          SampleEncryptionEntry& entry = tri.sample_encryption_entries[k];
          RCHECK(entry.Parse(sample_encryption_reader.get(), iv_size,
                             traf.sample_encryption.use_subsample_encryption));
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
          // If we don't have a per-sample IV, get the constant IV.
          bool is_encrypted = index == 0 ? track_encryption->is_encrypted
                                         : info_entry->is_encrypted;
#if defined(IS_CHROMECAST)
          // On Chromecast, we only support setting the pattern values in the
          // 'tenc' box for the track (not varying on per sample group basis).
          // Thus we need to verify that the settings in the sample group
          // match those in the 'tenc'.
          if (is_encrypted && index != 0) {
            RCHECK_MEDIA_LOGGED(info_entry->crypt_byte_block ==
                                    track_encryption->default_crypt_byte_block,
                                media_log_,
                                "Pattern value (crypt byte block) for the "
                                "sample group does not match that in the tenc "
                                "box . This is not currently supported.");
            RCHECK_MEDIA_LOGGED(info_entry->skip_byte_block ==
                                    track_encryption->default_skip_byte_block,
                                media_log_,
                                "Pattern value (skip byte block) for the "
                                "sample group does not match that in the tenc "
                                "box . This is not currently supported.");
          }
#endif  // defined(IS_CHROMECAST)
          if (is_encrypted && !iv_size) {
            const uint8_t constant_iv_size =
                index == 0 ? track_encryption->default_constant_iv_size
                           : info_entry->constant_iv_size;
            RCHECK(constant_iv_size != 0);
            const uint8_t* constant_iv =
                index == 0 ? track_encryption->default_constant_iv
                           : info_entry->constant_iv;
            memcpy(entry.initialization_vector, constant_iv, constant_iv_size);
          }
#endif  // BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
        }
      }
      runs_.push_back(tri);
      sample_count_sum += trun.sample_count;
    }

    // We should have iterated through all samples in SampleToGroup Box.
    RCHECK(!sample_to_group_itr.IsValid());
  }

  std::sort(runs_.begin(), runs_.end(), CompareMinTrackRunDataOffset());
  run_itr_ = runs_.begin();
  return ResetRun();
}

bool TrackRunIterator::UpdateCts() {
  // TODO(sandersd): Should |sample_cts_| be cleared in this case?
  if (!IsSampleValid())
    return true;
  auto cts = base::CheckAdd(sample_dts_, sample_itr_->cts_offset);
  if (!cts.AssignIfValid(&sample_cts_)) {
    MEDIA_LOG(ERROR, media_log_) << "Sample PTS exceeds representable range.";
    return false;
  }
  return true;
}

bool TrackRunIterator::AdvanceRun() {
  ++run_itr_;
  return ResetRun();
}

bool TrackRunIterator::ResetRun() {
  // TODO(sandersd): Should we clear all the values if the run is not valid?
  if (!IsRunValid())
    return true;
  sample_dts_ = run_itr_->start_dts;
  sample_offset_ = run_itr_->sample_start_offset;
  sample_itr_ = run_itr_->samples.begin();
  // UpdateCts() must run after |sample_itr_| is updated to the current run.
  return UpdateCts();
}

bool TrackRunIterator::AdvanceSample() {
  DCHECK(IsSampleValid());
  auto dts = base::CheckAdd(sample_dts_, sample_itr_->duration);
  if (!dts.AssignIfValid(&sample_dts_)) {
    MEDIA_LOG(ERROR, media_log_) << "Sample DTS exceeds representable range.";
    return false;
  }
  sample_offset_ += sample_itr_->size;
  ++sample_itr_;
  // UpdateCts() must run after |sample_itr_| is updated to the current sample.
  return UpdateCts();
}

// This implementation only indicates a need for caching if CENC auxiliary
// info is available in the stream.
bool TrackRunIterator::AuxInfoNeedsToBeCached() {
  DCHECK(IsRunValid());
  return is_encrypted() && aux_info_size() > 0 &&
         run_itr_->sample_encryption_entries.size() == 0;
}

// This implementation currently only caches CENC auxiliary info.
bool TrackRunIterator::CacheAuxInfo(const uint8_t* buf, int buf_size) {
  RCHECK(AuxInfoNeedsToBeCached() && buf_size >= aux_info_size());

  std::vector<SampleEncryptionEntry>& sample_encryption_entries =
      runs_[run_itr_ - runs_.begin()].sample_encryption_entries;
  sample_encryption_entries.resize(run_itr_->samples.size());
  int64_t pos = 0;
  for (size_t i = 0; i < run_itr_->samples.size(); i++) {
    int info_size = run_itr_->aux_info_default_size;
    if (!info_size)
      info_size = run_itr_->aux_info_sizes[i];

    if (IsSampleEncrypted(i)) {
      BufferReader reader(buf + pos, info_size);
      const uint8_t iv_size = GetIvSize(i);
      const bool has_subsamples = info_size > iv_size;
      SampleEncryptionEntry& entry = sample_encryption_entries[i];
      RCHECK_MEDIA_LOGGED(
          entry.Parse(&reader, iv_size, has_subsamples), media_log_,
          "SampleEncryptionEntry parse failed when caching aux info");
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
      // if we don't have a per-sample IV, get the constant IV.
      if (!iv_size) {
        RCHECK(ApplyConstantIv(i, &entry));
      }
#endif
    }
    pos += info_size;
  }

  return true;
}

bool TrackRunIterator::IsRunValid() const {
  return run_itr_ != runs_.end();
}

bool TrackRunIterator::IsSampleValid() const {
  return IsRunValid() && (sample_itr_ != run_itr_->samples.end());
}

// Because tracks are in sorted order and auxiliary information is cached when
// returning samples, it is guaranteed that no data will be required before the
// lesser of the minimum data offset of this track and the next in sequence.
// (The stronger condition - that no data is required before the minimum data
// offset of this track alone - is not guaranteed, because the BMFF spec does
// not have any inter-run ordering restrictions.)
int64_t TrackRunIterator::GetMaxClearOffset() {
  int64_t offset = std::numeric_limits<int64_t>::max();

  if (IsSampleValid()) {
    offset = std::min(offset, sample_offset_);
    if (AuxInfoNeedsToBeCached())
      offset = std::min(offset, aux_info_offset());
  }
  if (run_itr_ != runs_.end()) {
    auto next_run = run_itr_ + 1;
    if (next_run != runs_.end()) {
      offset = std::min(offset, next_run->sample_start_offset);
      if (next_run->aux_info_total_size)
        offset = std::min(offset, next_run->aux_info_start_offset);
    }
  }
  if (offset == std::numeric_limits<int64_t>::max())
    return 0;
  return offset;
}

uint32_t TrackRunIterator::track_id() const {
  DCHECK(IsRunValid());
  return run_itr_->track_id;
}

bool TrackRunIterator::is_encrypted() const {
  DCHECK(IsSampleValid());
  return IsSampleEncrypted(sample_itr_ - run_itr_->samples.begin());
}

int64_t TrackRunIterator::aux_info_offset() const {
  return run_itr_->aux_info_start_offset;
}

int TrackRunIterator::aux_info_size() const {
  return run_itr_->aux_info_total_size;
}

bool TrackRunIterator::is_audio() const {
  DCHECK(IsRunValid());
  return run_itr_->is_audio;
}

const AudioSampleEntry& TrackRunIterator::audio_description() const {
  DCHECK(is_audio());
  DCHECK(run_itr_->audio_description);
  return *run_itr_->audio_description;
}

const VideoSampleEntry& TrackRunIterator::video_description() const {
  DCHECK(!is_audio());
  DCHECK(run_itr_->video_description);
  return *run_itr_->video_description;
}

int64_t TrackRunIterator::sample_offset() const {
  DCHECK(IsSampleValid());
  return sample_offset_;
}

uint32_t TrackRunIterator::sample_size() const {
  DCHECK(IsSampleValid());
  return sample_itr_->size;
}

DecodeTimestamp TrackRunIterator::dts() const {
  DCHECK(IsSampleValid());
  return DecodeTimestampFromRational(sample_dts_, run_itr_->timescale);
}

base::TimeDelta TrackRunIterator::cts() const {
  DCHECK(IsSampleValid());
  return TimeDeltaFromRational(sample_cts_, run_itr_->timescale);
}

base::TimeDelta TrackRunIterator::duration() const {
  DCHECK(IsSampleValid());
  return TimeDeltaFromRational(sample_itr_->duration, run_itr_->timescale);
}

bool TrackRunIterator::is_keyframe() const {
  DCHECK(IsSampleValid());
  return sample_itr_->is_keyframe;
}

const ProtectionSchemeInfo& TrackRunIterator::protection_scheme_info() const {
  if (is_audio())
    return audio_description().sinf;
  return video_description().sinf;
}

const TrackEncryption& TrackRunIterator::track_encryption() const {
  return protection_scheme_info().info.track_encryption;
}

std::unique_ptr<DecryptConfig> TrackRunIterator::GetDecryptConfig() {
  DCHECK(is_encrypted());
  size_t sample_idx = sample_itr_ - run_itr_->samples.begin();
  const std::vector<uint8_t>& kid = GetKeyId(sample_idx);
  std::string key_id(kid.begin(), kid.end());

  if (run_itr_->sample_encryption_entries.empty()) {
    DCHECK_EQ(0, aux_info_size());
#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
    // The 'cbcs' scheme allows empty aux info when a constant IV is in use
    // with full sample encryption. That case will fall through to here.
    SampleEncryptionEntry sample_encryption_entry;
    if (ApplyConstantIv(sample_idx, &sample_encryption_entry)) {
      std::string iv(reinterpret_cast<const char*>(
                         sample_encryption_entry.initialization_vector),
                     base::size(sample_encryption_entry.initialization_vector));
      switch (run_itr_->encryption_scheme.mode()) {
        case EncryptionScheme::CIPHER_MODE_UNENCRYPTED:
          return nullptr;
        case EncryptionScheme::CIPHER_MODE_AES_CTR:
          return DecryptConfig::CreateCencConfig(
              key_id, iv, sample_encryption_entry.subsamples);
        case EncryptionScheme::CIPHER_MODE_AES_CBC:
          return DecryptConfig::CreateCbcsConfig(
              key_id, iv, sample_encryption_entry.subsamples,
              run_itr_->encryption_scheme.pattern());
      }
    }
#endif
    MEDIA_LOG(ERROR, media_log_) << "Sample encryption info is not available.";
    return nullptr;
  }

  DCHECK_LT(sample_idx, run_itr_->sample_encryption_entries.size());
  const SampleEncryptionEntry& sample_encryption_entry =
      run_itr_->sample_encryption_entries[sample_idx];
  std::string iv(reinterpret_cast<const char*>(
                     sample_encryption_entry.initialization_vector),
                 base::size(sample_encryption_entry.initialization_vector));

  size_t total_size = 0;
  if (!sample_encryption_entry.subsamples.empty() &&
      (!sample_encryption_entry.GetTotalSizeOfSubsamples(&total_size) ||
       total_size != static_cast<size_t>(sample_size()))) {
    MEDIA_LOG(ERROR, media_log_) << "Incorrect CENC subsample size.";
    return nullptr;
  }

#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
  if (protection_scheme_info().IsCbcsEncryptionScheme()) {
    uint32_t index = GetGroupDescriptionIndex(sample_idx);
    uint32_t encrypt_blocks =
        (index == 0)
            ? track_encryption().default_crypt_byte_block
            : GetSampleEncryptionInfoEntry(*run_itr_, index)->crypt_byte_block;
    uint32_t skip_blocks =
        (index == 0)
            ? track_encryption().default_skip_byte_block
            : GetSampleEncryptionInfoEntry(*run_itr_, index)->skip_byte_block;
    return DecryptConfig::CreateCbcsConfig(
        key_id, iv, sample_encryption_entry.subsamples,
        EncryptionPattern(encrypt_blocks, skip_blocks));
  }
#endif

  return DecryptConfig::CreateCencConfig(key_id, iv,
                                         sample_encryption_entry.subsamples);
}

uint32_t TrackRunIterator::GetGroupDescriptionIndex(
    uint32_t sample_index) const {
  DCHECK(IsRunValid());
  DCHECK_LT(sample_index, run_itr_->samples.size());
  return run_itr_->samples[sample_index].cenc_group_description_index;
}

bool TrackRunIterator::IsSampleEncrypted(size_t sample_index) const {
  uint32_t index = GetGroupDescriptionIndex(sample_index);
  return (index == 0)
             ? track_encryption().is_encrypted
             : GetSampleEncryptionInfoEntry(*run_itr_, index)->is_encrypted;
}

const std::vector<uint8_t>& TrackRunIterator::GetKeyId(
    size_t sample_index) const {
  uint32_t index = GetGroupDescriptionIndex(sample_index);
  return (index == 0) ? track_encryption().default_kid
                      : GetSampleEncryptionInfoEntry(*run_itr_, index)->key_id;
}

uint8_t TrackRunIterator::GetIvSize(size_t sample_index) const {
  uint32_t index = GetGroupDescriptionIndex(sample_index);
  return (index == 0) ? track_encryption().default_iv_size
                      : GetSampleEncryptionInfoEntry(*run_itr_, index)->iv_size;
}

#if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
bool TrackRunIterator::ApplyConstantIv(size_t sample_index,
                                       SampleEncryptionEntry* entry) const {
  DCHECK(IsSampleEncrypted(sample_index));
  uint32_t index = GetGroupDescriptionIndex(sample_index);
  const uint8_t constant_iv_size =
      index == 0
          ? track_encryption().default_constant_iv_size
          : GetSampleEncryptionInfoEntry(*run_itr_, index)->constant_iv_size;
  RCHECK(constant_iv_size != 0);
  const uint8_t* constant_iv =
      index == 0 ? track_encryption().default_constant_iv
                 : GetSampleEncryptionInfoEntry(*run_itr_, index)->constant_iv;
  RCHECK(constant_iv != nullptr);
  memcpy(entry->initialization_vector, constant_iv, kInitializationVectorSize);
  return true;
}
#endif

}  // namespace mp4
}  // namespace media
