// Copyright 2012 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/media/filters/shell_mp4_map.h"

#include <algorithm>

#include "base/strings/stringprintf.h"
#include "cobalt/media/base/endian_util.h"
#include "cobalt/media/filters/shell_mp4_parser.h"

namespace cobalt {
namespace media {

// ==== TableCache =============================================================

ShellMP4Map::TableCache::TableCache(uint64 table_offset, uint32 entry_count,
                                    uint32 entry_size,
                                    uint32 cache_size_entries,
                                    scoped_refptr<ShellDataSourceReader> reader)
    : entry_size_(entry_size),
      entry_count_(entry_count),
      cache_size_entries_(cache_size_entries),
      table_offset_(table_offset),
      reader_(reader),
      cache_first_entry_number_(-1),
      cache_entry_count_(0) {}

uint8* ShellMP4Map::TableCache::GetBytesAtEntry(uint32 entry_number) {
  // don't fetch the unfetchable
  if (entry_number >= entry_count_) {
    return NULL;
  }
  // this query within valid range for the current cache table?
  if (entry_number < cache_first_entry_number_ ||
      entry_number >= cache_first_entry_number_ + cache_entry_count_) {
    // Calculate first entry in table keeping cache size alignment in table.
    // Always cache one more entry as in stss we need to use the first entry
    // of the next cache slot as an upper bound.
    cache_entry_count_ = cache_size_entries_ + 1;
    cache_first_entry_number_ =
        (entry_number / cache_size_entries_) * cache_size_entries_;
    // see if we have exceeded our table bounds
    if (cache_first_entry_number_ + cache_entry_count_ > entry_count_) {
      cache_entry_count_ = entry_count_ - cache_first_entry_number_;
    }
    // drop old data to allow ShellBufferFactory to defrag
    cache_.clear();
    DCHECK_GE(cache_entry_count_, 0);
    int bytes_to_read = cache_entry_count_ * entry_size_;
    cache_.resize(bytes_to_read);
    uint64 file_offset =
        table_offset_ + (cache_first_entry_number_ * entry_size_);
    int bytes_read =
        reader_->BlockingRead(file_offset, bytes_to_read, &cache_[0]);
    if (bytes_read < bytes_to_read) {
      cache_entry_count_ = 0;
      return NULL;
    }
  }
  // cache is assumed to be valid and to contain the entry from here on
  DCHECK_GE(entry_number, cache_first_entry_number_);
  DCHECK_LT(entry_number, cache_first_entry_number_ + cache_entry_count_);

  uint32 cache_offset = entry_number - cache_first_entry_number_;
  return &cache_[0] + (cache_offset * entry_size_);
}

bool ShellMP4Map::TableCache::ReadU32Entry(uint32 entry_number, uint32* entry) {
  if (uint8* data = GetBytesAtEntry(entry_number)) {
    *entry = endian_util::load_uint32_big_endian(data);
    return true;
  }

  return false;
}

bool ShellMP4Map::TableCache::ReadU32PairEntry(uint32 entry_number,
                                               uint32* first, uint32* second) {
  if (uint8* data = GetBytesAtEntry(entry_number)) {
    if (first) *first = endian_util::load_uint32_big_endian(data);
    if (second) *second = endian_util::load_uint32_big_endian(data + 4);
    return true;
  }

  return false;
}

bool ShellMP4Map::TableCache::ReadU32EntryIntoU64(uint32 entry_number,
                                                  uint64* entry) {
  if (uint8* data = GetBytesAtEntry(entry_number)) {
    *entry = endian_util::load_uint32_big_endian(data);
    return true;
  }

  return false;
}

bool ShellMP4Map::TableCache::ReadU64Entry(uint32 entry_number, uint64* entry) {
  if (uint8* data = GetBytesAtEntry(entry_number)) {
    *entry = endian_util::load_uint64_big_endian(data);
    return true;
  }

  return false;
}

// ==== ShellMP4Map ============================================================

// atom | name                  | size | description, (*) means optional table
// -----+-----------------------+------+----------------------------------------
// co64 | chunk offset (64-bit) | 8    | per-chunk list of chunk file offsets
// ctts | composition offset    | 8    | (*) run-length sample number to cts
// stco | chunk offset (32-bit) | 4    | per-chunk list of chunk file offsets
// stsc | sample-to-chunk       | 12   | chunk number to samples per chunk
// stss | sync sample           | 4    | (*) list of keyframe sample numbers
// stts | time-to-sample        | 8    | run-length sample number to duration
// stsz | sample size           | 4    | per-sample list of sample sizes

ShellMP4Map::ShellMP4Map(scoped_refptr<ShellDataSourceReader> reader)
    : reader_(reader),
      current_chunk_sample_(0),
      next_chunk_sample_(0),
      current_chunk_offset_(0),
      highest_valid_sample_number_(UINT32_MAX),
      ctts_first_sample_(0),
      ctts_sample_offset_(0),
      ctts_next_first_sample_(0),
      ctts_table_index_(0),
      stsc_first_chunk_(0),
      stsc_first_chunk_sample_(0),
      stsc_samples_per_chunk_(0),
      stsc_next_first_chunk_(0),
      stsc_next_first_chunk_sample_(0),
      stsc_table_index_(0),
      stss_last_keyframe_(0),
      stss_next_keyframe_(0),
      stss_table_index_(0),
      stts_first_sample_(0),
      stts_first_sample_time_(0),
      stts_sample_duration_(0),
      stts_next_first_sample_(0),
      stts_next_first_sample_time_(0),
      stts_table_index_(0),
      stsz_default_size_(0) {}

bool ShellMP4Map::IsComplete() {
  // all required table pointers must be valid for map to function
  return (co64_ || stco_) && stsc_ && stts_ && (stsz_ || stsz_default_size_);
}

// The sample size is a lookup in the stsz table, which is indexed per sample
// number.
bool ShellMP4Map::GetSize(uint32 sample_number, uint32* size_out) {
  DCHECK(size_out);
  DCHECK(stsz_ || stsz_default_size_);

  if (sample_number > highest_valid_sample_number_) {
    return false;
  }

  if (stsz_default_size_) {
    *size_out = stsz_default_size_;
    return true;
  }

  return stsz_->ReadU32Entry(sample_number, size_out);
}

// We first must integrate the stsc table to find the chunk number that the
// sample resides in, and the first sample number in that chunk. We look up that
// chunk offset from the stco or co64, which are indexed by chunk number. We
// then use the stsz to sum samples to the byte offset with that chunk. The sum
// of the chunk offset and the byte offset within the chunk is the offset of
// the sample.
bool ShellMP4Map::GetOffset(uint32 sample_number, uint64* offset_out) {
  DCHECK(offset_out);
  DCHECK(stsc_);
  DCHECK(stco_ || co64_);
  DCHECK(stsz_ || stsz_default_size_);

  if (sample_number > highest_valid_sample_number_) {
    return false;
  }

  // check for sequential access of sample numbers within the same chunk
  if (sample_number < current_chunk_sample_ ||
      sample_number >= next_chunk_sample_) {
    // integrate through stsc until we find the chunk range containing sample
    if (!stsc_AdvanceToSample(sample_number)) {
      return false;
    }
    // make sure stsc advance did its job correctly
    DCHECK_GE(sample_number, stsc_first_chunk_sample_);

    // calculate chunk number based on chunk sample size for this range
    uint32 sample_offset = sample_number - stsc_first_chunk_sample_;
    uint32 chunk_range_offset = sample_offset / stsc_samples_per_chunk_;
    uint32 chunk_number = stsc_first_chunk_ + chunk_range_offset;
    // should be within the range of chunks with this sample size
    DCHECK_LT(chunk_number, stsc_next_first_chunk_);
    // update first sample number contained within this chunk
    current_chunk_sample_ = stsc_first_chunk_sample_ +
                            (chunk_range_offset * stsc_samples_per_chunk_);
    // update first sample number of next chunk
    next_chunk_sample_ = current_chunk_sample_ + stsc_samples_per_chunk_;
    // find offset of this chunk within the file from co64/stco
    if (co64_) {
      if (!co64_->ReadU64Entry(chunk_number, &current_chunk_offset_))
        return false;
    } else if (!stco_->ReadU32EntryIntoU64(chunk_number,
                                           &current_chunk_offset_)) {
      return false;
    }
  }

  // at this point we should have sample_number within the range of our chunk
  // offset summation saved state
  DCHECK_LE(current_chunk_sample_, sample_number);
  DCHECK_LT(sample_number, next_chunk_sample_);

  if (stsz_default_size_ > 0) {
    current_chunk_offset_ +=
        (sample_number - current_chunk_sample_) * stsz_default_size_;
    current_chunk_sample_ = sample_number;
  } else {
    // sum sample sizes within chunk to get to byte offset of sample
    while (current_chunk_sample_ < sample_number) {
      uint32 sample_size = 0;
      if (!GetSize(current_chunk_sample_, &sample_size)) {
        return false;
      }
      current_chunk_offset_ += sample_size;
      current_chunk_sample_++;
    }
  }

  *offset_out = current_chunk_offset_;
  return true;
}

// Given a current sample number we integrate through the stts to find the
// duration of the current sample, and at the same time integrate through the
// durations to find the dts of that sample number. We then integrate sample
// numbers through the ctts to find the composition time offset, which we add to
// the dts to return the pts.
bool ShellMP4Map::GetTimestamp(uint32 sample_number, uint64* timestamp_out) {
  DCHECK(timestamp_out);
  if (sample_number > highest_valid_sample_number_) {
    return false;
  }

  if (!stts_AdvanceToSample(sample_number)) {
    return false;
  }
  DCHECK_LT(sample_number, stts_next_first_sample_);
  DCHECK_GE(sample_number, stts_first_sample_);
  uint64 dts = stts_first_sample_time_ +
               (sample_number - stts_first_sample_) * stts_sample_duration_;
  if (ctts_) {
    if (!ctts_AdvanceToSample(sample_number)) {
      return false;
    }
    DCHECK_LT(sample_number, ctts_next_first_sample_);
    DCHECK_GE(sample_number, ctts_first_sample_);
  }
  *timestamp_out = dts + ctts_sample_offset_;
  return true;
}

// Sum through the stts to find the duration of the given sample_number.
bool ShellMP4Map::GetDuration(uint32 sample_number, uint32* duration_out) {
  DCHECK(duration_out);
  if (sample_number > highest_valid_sample_number_) {
    return false;
  }

  if (!stts_AdvanceToSample(sample_number)) {
    return false;
  }
  DCHECK_LT(sample_number, stts_next_first_sample_);
  DCHECK_GE(sample_number, stts_first_sample_);
  *duration_out = stts_sample_duration_;
  return true;
}

bool ShellMP4Map::GetIsKeyframe(uint32 sample_number, bool* is_keyframe_out) {
  DCHECK(is_keyframe_out);
  if (sample_number > highest_valid_sample_number_) {
    return false;
  }

  // no stts means every frame is a keyframe
  if (!stss_) {
    *is_keyframe_out = true;
    return true;
  }

  // check for keyframe match on either range value
  if (sample_number == stss_next_keyframe_) {
    *is_keyframe_out = true;
    return stss_AdvanceStep();
  } else if (sample_number == stss_last_keyframe_) {
    *is_keyframe_out = true;
    return true;
  }

  // this could be for a much earlier sample number, check if we are within
  // current range of sample numbers
  if (sample_number < stss_last_keyframe_ ||
      sample_number > stss_next_keyframe_) {
    // search for containing entry
    if (!stss_FindNearestKeyframe(sample_number)) {
      return false;
    }
  }
  // sample number must be in range of keyframe states
  DCHECK_GE(sample_number, stss_last_keyframe_);
  DCHECK_LT(sample_number, stss_next_keyframe_);
  // stss_FindNearestKeyframe returns exact matches to
  // sample_number in the stss_last_keyframe_ variable, so
  // we check that for equality
  *is_keyframe_out = (sample_number == stss_last_keyframe_);

  return true;
}

bool ShellMP4Map::IsEOS(uint32 sample_number) {
  return (sample_number > highest_valid_sample_number_);
}

// First look up the sample number for the provided timestamp by integrating
// timestamps through the stts. Then do a binary search on the stss to find the
// keyframe nearest that sample number.
bool ShellMP4Map::GetKeyframe(uint64 timestamp, uint32* sample_out) {
  DCHECK(sample_out);
  // Advance stts to the provided timestamp range
  if (!stts_AdvanceToTime(timestamp)) {
    return false;
  }
  // ensure we got the correct sample duration range
  DCHECK_LT(timestamp, stts_next_first_sample_time_);
  DCHECK_GE(timestamp, stts_first_sample_time_);
  // calculate sample number containing this timestamp
  uint64 time_offset_within_range = timestamp - stts_first_sample_time_;
  uint32 sample_number =
      stts_first_sample_ + (time_offset_within_range / stts_sample_duration_);

  // TODO: ctts?

  // binary search on stts to find nearest keyframe beneath this sample number
  if (stss_) {
    if (!stss_FindNearestKeyframe(sample_number)) {
      return false;
    }
    *sample_out = stss_last_keyframe_;
  } else {
    // an absent stts means every frame is a key frame, we can provide sample
    // directly.
    *sample_out = sample_number;
  }
  return true;
}

// Set up map state and load first part of table, or entire table if it is small
// enough, for each of the supporated atoms.
bool ShellMP4Map::SetAtom(uint32 four_cc, uint64 offset, uint64 size,
                          uint32 cache_size_entries, const uint8* atom) {
  // All map atoms are variable-length tables starting with 4 bytes of
  // version/flag info followed by a uint32 indicating the number of items in
  // table. The stsz atom bucks tradition by putting an optional default value
  // at index 4.
  uint32 count = 0;
  uint64 table_offset = offset + 8;
  if (four_cc == kAtomType_stsz) {
    if (size < 12) {
      return false;
    }
    stsz_default_size_ = endian_util::load_uint32_big_endian(atom + 4);
    count = endian_util::load_uint32_big_endian(atom + 8);
    highest_valid_sample_number_ =
        std::min(count - 1, highest_valid_sample_number_);
    // if a non-zero default size is provided don't bother loading the table
    if (stsz_default_size_) {
      stsz_ = NULL;
      return true;
    }

    table_offset += 4;
  } else {
    if (size < 8) {
      return false;
    }
    count = endian_util::load_uint32_big_endian(atom + 4);
  }

  // if cache_size_entries is 0 we are to cache the entire table
  if (cache_size_entries == 0) {
    cache_size_entries = count;
  }

  bool atom_init = false;
  // initialize the appropriate table cache dependent on table type
  switch (four_cc) {
    case kAtomType_co64:
      co64_ = new TableCache(table_offset, count, kEntrySize_co64,
                             cache_size_entries, reader_);
      if (co64_) atom_init = co64_Init();
      break;

    case kAtomType_ctts:
      ctts_ = new TableCache(table_offset, count, kEntrySize_ctts,
                             cache_size_entries, reader_);
      if (ctts_) atom_init = ctts_Init();
      break;

    case kAtomType_stco:
      stco_ = new TableCache(table_offset, count, kEntrySize_stco,
                             cache_size_entries, reader_);
      if (stco_) atom_init = stco_Init();
      break;

    case kAtomType_stsc:
      stsc_ = new TableCache(table_offset, count, kEntrySize_stsc,
                             cache_size_entries, reader_);
      if (stsc_) atom_init = stsc_Init();
      break;

    case kAtomType_stss:
      stss_ = new TableCache(table_offset, count, kEntrySize_stss,
                             cache_size_entries, reader_);
      if (stss_) atom_init = stss_Init();
      break;

    case kAtomType_stts:
      stts_ = new TableCache(table_offset, count, kEntrySize_stts,
                             cache_size_entries, reader_);
      if (stts_) atom_init = stts_Init();
      break;

    case kAtomType_stsz:
      stsz_ = new TableCache(table_offset, count, kEntrySize_stsz,
                             cache_size_entries, reader_);
      if (stsz_) atom_init = stsz_Init();
      break;

    default:
      NOTREACHED() << "unknown atom type provided to mp4 map";
      break;
  }

  return atom_init;
}

bool ShellMP4Map::co64_Init() {
  DCHECK(co64_);
  // load offset of first chunk into current_chunk_offset_
  if (co64_->GetEntryCount() > 0) {
    // can drop any stco table already allocated
    stco_ = NULL;
    // load initial value of current_chunk_offset_ for 0th chunk
    return co64_->ReadU64Entry(0, &current_chunk_offset_);
  }

  co64_ = NULL;

  return true;
}

// The ctts table has the following per-entry layout:
// uint32 sample count
// uint32 composition offset in ticks
//
bool ShellMP4Map::ctts_Init() {
  DCHECK(ctts_);
  // get cache segment vector to reserve table entries in advance
  int cache_segments =
      (ctts_->GetEntryCount() / ctts_->GetCacheSizeEntries()) + 1;
  ctts_samples_.reserve(cache_segments);
  if (ctts_->GetEntryCount() > 0) {
    // save the start of the first table integration at 0
    ctts_samples_.push_back(0);
    ctts_table_index_ = 0;
    ctts_first_sample_ = 0;
    // load first entry in table, to start integration
    return ctts_->ReadU32PairEntry(0, &ctts_next_first_sample_,
                                   &ctts_sample_offset_);
  }
  // drop empty ctts_ table
  ctts_ = NULL;

  return true;
}

// To find the composition offset of a given sample number we must integrate
// through the ctts to find the range of samples containing sample_number. Note
// that the ctts is an optional table.
bool ShellMP4Map::ctts_AdvanceToSample(uint32 sample_number) {
  // ctts table is optional, so treat not having one as non-fatal
  if (!ctts_) {
    return true;
  }
  // sample number could be before our saved first sample, meaning we've
  // gone backward in sample numbers and will need to restart integration at
  // the nearest saved sample count starting at a cache entry
  if (sample_number < ctts_first_sample_) {
    if (!ctts_SlipCacheToSample(sample_number, 0)) {
      return false;
    }
  }

  // sample_number could also be ahead of our current range, for example when
  // seeking forward. See if we've calculated these values ahead of us before,
  // and if we can slip forward to them
  int next_cache_index = (ctts_table_index_ / ctts_->GetCacheSizeEntries()) + 1;
  if ((next_cache_index < ctts_samples_.size()) &&
      (sample_number >= ctts_samples_[next_cache_index])) {
    if (!ctts_SlipCacheToSample(sample_number, next_cache_index)) {
      return false;
    }
  }

  // perform integration until sample number is within correct ctts range
  while (ctts_next_first_sample_ <= sample_number) {
    // next first sample is now our the first sample
    ctts_first_sample_ = ctts_next_first_sample_;
    // advance to next entry in table
    ctts_table_index_++;
    // If this would be a new cache entry, keep a record of integration up
    // to this point so we don't have to start from 0 on seeking back
    if (!(ctts_table_index_ % ctts_->GetCacheSizeEntries())) {
      int cache_index = ctts_table_index_ / ctts_->GetCacheSizeEntries();
      // check that this is our first time with these data
      if (cache_index == ctts_samples_.size()) {
        ctts_samples_.push_back(ctts_first_sample_);
      }
      // our integration at this point should always match any stored record
      DCHECK_EQ(ctts_first_sample_, ctts_samples_[cache_index]);
    }

    if (ctts_table_index_ < ctts_->GetEntryCount()) {
      // load the sample count to determine next first sample
      uint32 sample_count;
      if (!ctts_->ReadU32PairEntry(ctts_table_index_, &sample_count,
                                   &ctts_sample_offset_))
        return false;
      ctts_next_first_sample_ = ctts_first_sample_ + sample_count;
    } else {
      // This means that the last entry in the table specified a sample range
      // that this sample number has exceeded, and so the ctts of this sample
      // number is undefined. While not a fatal error it's kind of a weird
      // state, we set the offset back to zero and extend the next_first_sample
      // to infinity
      DLOG(WARNING) << base::StringPrintf(
          "out of range sample number %d in ctts, last valid sample number: %d",
          sample_number, ctts_next_first_sample_);
      ctts_sample_offset_ = 0;
      ctts_next_first_sample_ = UINT32_MAX;
      break;
    }
  }
  return true;
}

bool ShellMP4Map::ctts_SlipCacheToSample(uint32 sample_number,
                                         int starting_cache_index) {
  DCHECK_LT(starting_cache_index, ctts_samples_.size());
  int cache_index = starting_cache_index;
  for (; cache_index + 1 < ctts_samples_.size(); cache_index++) {
    if (sample_number < ctts_samples_[cache_index + 1]) {
      break;
    }
  }
  ctts_first_sample_ = ctts_samples_[cache_index];
  ctts_table_index_ = cache_index * ctts_->GetCacheSizeEntries();
  // read sample count and duration to set next values
  uint32 sample_count;
  if (!ctts_->ReadU32PairEntry(ctts_table_index_, &sample_count,
                               &ctts_sample_offset_))
    return false;
  ctts_next_first_sample_ = ctts_first_sample_ + sample_count;
  return true;
}

bool ShellMP4Map::stco_Init() {
  DCHECK(stco_);
  // load offset of first chunk into current_chunk_offset_
  if (stco_->GetEntryCount() > 0) {
    co64_ = NULL;
    return stco_->ReadU32EntryIntoU64(0, &current_chunk_offset_);
  }

  stco_ = NULL;

  return true;
}

// The stsc table has the following per-entry layout:
// uint32 first chunk number with this sample count
// uint32 samples-per-chunk
// uint32 sample description id (unused)
bool ShellMP4Map::stsc_Init() {
  DCHECK(stsc_);
  // set up vector to correct final size
  int cache_segments =
      (stsc_->GetEntryCount() / stsc_->GetCacheSizeEntries()) + 1;
  stsc_sample_sums_.reserve(cache_segments);
  // there must always be at least 1 entry in a valid stsc table
  if (stsc_->GetEntryCount() > 0) {
    stsc_first_chunk_ = 0;
    stsc_first_chunk_sample_ = 0;
    // first cached entry is always 0
    stsc_sample_sums_.push_back(0);
    if (!stsc_->ReadU32PairEntry(0, NULL, &stsc_samples_per_chunk_)) {
      stsc_ = NULL;
      return false;
    }
    // look up next first chunk at next index in table
    if (stsc_->GetEntryCount() > 1) {
      if (!stsc_->ReadU32PairEntry(1, &stsc_next_first_chunk_, NULL)) {
        stsc_ = NULL;
        return false;
      }
      --stsc_next_first_chunk_;
      stsc_next_first_chunk_sample_ =
          stsc_next_first_chunk_ * stsc_samples_per_chunk_;
    } else {
      // every chunk in the file has the sample sample count, set next first
      // chunk to highest valid chunk number.
      stsc_next_first_chunk_ = UINT32_MAX;
      stsc_next_first_chunk_sample_ = UINT32_MAX;
    }
    stsc_table_index_ = 0;

    // since we known the size of the first chunk we can set next_chunk_sample_
    next_chunk_sample_ = stsc_samples_per_chunk_;

  } else {
    stsc_ = NULL;
  }

  return true;
}

// To find the chunk number of an abritrary sample we have to sum the
// samples-per-chunk value multiplied by the number of chunks with that sample
// count until the sum exceeds the sample number, then calculate the chunk
// number from that range of per-sample chunk sizes. Since this map is meant
// to be consumed incrementally and with minimal memory consumption we calculate
// this integration step only when needed, and save results for each cached
// piece of the table, to avoid having to recalculate needed data.
bool ShellMP4Map::stsc_AdvanceToSample(uint32 sample_number) {
  DCHECK(stsc_);
  // sample_number could be before first chunk, meaning that we are seeking
  // backwards and have left the current chunk. Find the closest part of the
  // cached table and integrate forward from there.
  if (sample_number < stsc_first_chunk_sample_) {
    if (!stsc_SlipCacheToSample(sample_number, 0)) {
      return false;
    }
  }

  // sample_number could also be well head of our current piece of the
  // cache, so see if we can re-use any previously calculated summations to
  // skip to the nearest cache entry
  int next_cache_index = (stsc_table_index_ / stsc_->GetCacheSizeEntries()) + 1;
  if ((next_cache_index < stsc_sample_sums_.size()) &&
      (sample_number >= stsc_sample_sums_[next_cache_index])) {
    if (!stsc_SlipCacheToSample(sample_number, next_cache_index)) {
      return false;
    }
  }

  // Integrate through each table entry until we find sample_number in range
  while (stsc_next_first_chunk_sample_ <= sample_number) {
    // advance to next chunk sample range
    stsc_first_chunk_sample_ = stsc_next_first_chunk_sample_;
    // our next_first_chunk is now our first chunk
    stsc_first_chunk_ = stsc_next_first_chunk_;
    // advance to next entry in table
    stsc_table_index_++;
    // if we've advanced to a new segment of the cache, update the saved
    // integration values
    if (!(stsc_table_index_ % stsc_->GetCacheSizeEntries())) {
      int cache_index = stsc_table_index_ / stsc_->GetCacheSizeEntries();
      // check that this is our first time with these data
      if (cache_index == stsc_sample_sums_.size()) {
        stsc_sample_sums_.push_back(stsc_first_chunk_sample_);
      }
      // our integration at this point should always match any stored record
      DCHECK_EQ(stsc_first_chunk_sample_, stsc_sample_sums_[cache_index]);
    }
    if (stsc_table_index_ < stsc_->GetEntryCount()) {
      // look up our new sample rate
      if (!stsc_->ReadU32PairEntry(stsc_table_index_, NULL,
                                   &stsc_samples_per_chunk_)) {
        return false;
      }
      // we need to look up next table entry to determine next first chunk
      if (stsc_table_index_ + 1 < stsc_->GetEntryCount()) {
        // look up next first chunk
        if (!stsc_->ReadU32PairEntry(stsc_table_index_ + 1,
                                     &stsc_next_first_chunk_, NULL)) {
          return false;
        }
        --stsc_next_first_chunk_;
        // carry sum of first_samples forward to next chunk range
        stsc_next_first_chunk_sample_ +=
            (stsc_next_first_chunk_ - stsc_first_chunk_) *
            stsc_samples_per_chunk_;
      } else {
        // this is the normal place to encounter the end of the chunk table.
        // set the next chunk to the highest valid chunk number
        stsc_next_first_chunk_ = UINT32_MAX;
        stsc_next_first_chunk_sample_ = UINT32_MAX;
      }
    } else {
      // We should normally encounter the end of the chunk table on lookup
      // of the next_first_chunk_ within the if clause associated with this
      // else. Something has gone wrong.
      NOTREACHED();
      return false;
    }
  }
  return true;
}

bool ShellMP4Map::stsc_SlipCacheToSample(uint32 sample_number,
                                         int starting_cache_index) {
  DCHECK_LT(starting_cache_index, stsc_sample_sums_.size());
  // look through old sample sums for the first entry that exceeds sample
  // sample_number, we want the entry right before that
  int cache_index = starting_cache_index;
  for (; cache_index + 1 < stsc_sample_sums_.size(); cache_index++) {
    if (sample_number < stsc_sample_sums_[cache_index + 1]) {
      break;
    }
  }
  // jump to new spot in table
  stsc_first_chunk_sample_ = stsc_sample_sums_[cache_index];
  stsc_table_index_ = cache_index * stsc_->GetCacheSizeEntries();
  if (!stsc_->ReadU32PairEntry(stsc_table_index_, &stsc_first_chunk_,
                               &stsc_samples_per_chunk_)) {
    return false;
  }
  // load current and next values
  --stsc_first_chunk_;
  if (stsc_table_index_ + 1 < stsc_->GetEntryCount()) {
    if (!stsc_->ReadU32PairEntry(stsc_table_index_ + 1, &stsc_next_first_chunk_,
                                 NULL)) {
      return false;
    }
    --stsc_next_first_chunk_;
    stsc_next_first_chunk_sample_ =
        stsc_first_chunk_sample_ +
        ((stsc_next_first_chunk_ - stsc_first_chunk_) *
         stsc_samples_per_chunk_);
  } else {
    // We seem to have cached an entry 1 entry before end of the table, and
    // are seeking to a region contained in that last entry in the table.
    stsc_next_first_chunk_ = UINT32_MAX;
    stsc_next_first_chunk_sample_ = UINT32_MAX;
  }
  return true;
}

// stss is a list of sample numbers that are keyframes.
bool ShellMP4Map::stss_Init() {
  int cache_segments =
      (stss_->GetEntryCount() / stss_->GetCacheSizeEntries()) + 1;
  stss_keyframes_.reserve(cache_segments);
  // empty stss means every frame is a keyframe, same as not
  // providing one
  if (stss_->GetEntryCount() > 0) {
    // identify first keyframe from first entry in stss
    if (!stss_->ReadU32Entry(0, &stss_last_keyframe_)) {
      stss_ = NULL;
      return false;
    }
    --stss_last_keyframe_;
    stss_keyframes_.push_back(stss_last_keyframe_);
    stss_next_keyframe_ = stss_last_keyframe_;
    stss_table_index_ = 0;
  } else {
    stss_ = NULL;
  }

  return true;
}

// advance by one table entry through stss, updating cache if necessary
bool ShellMP4Map::stss_AdvanceStep() {
  DCHECK(stss_);
  stss_last_keyframe_ = stss_next_keyframe_;
  stss_table_index_++;
  if (stss_table_index_ < stss_->GetEntryCount()) {
    if (!stss_->ReadU32Entry(stss_table_index_, &stss_next_keyframe_)) {
      return false;
    }
    --stss_next_keyframe_;
    if (!(stss_table_index_ % stss_->GetCacheSizeEntries())) {
      int cache_index = stss_table_index_ / stss_->GetCacheSizeEntries();
      // only add if this is the first time we've encountered this number
      if (cache_index == stss_keyframes_.size()) {
        stss_keyframes_.push_back(stss_next_keyframe_);
      }
      DCHECK_EQ(stss_next_keyframe_, stss_keyframes_[cache_index]);
    }
  } else {
    stss_next_keyframe_ = UINT32_MAX;
  }
  return true;
}

bool ShellMP4Map::stss_FindNearestKeyframe(uint32 sample_number) {
  DCHECK(stss_);
  // it is assumed that there's at least one cache entry created by
  // stss_Init();
  DCHECK_GT(stss_keyframes_.size(), 0);
  int cache_entry_number = stss_keyframes_.size() - 1;
  int total_cache_entries =
      (stss_->GetEntryCount() + stss_->GetCacheSizeEntries() - 1) /
      stss_->GetCacheSizeEntries();
  // if there's more than one cache entry we can search the cached
  // entries for the entry containing our keyframe, otherwise we skip
  // directly to the binary search of the single cached entry
  if (total_cache_entries > 1) {
    // if the sample number resides within the range of cached entries
    // we search those to find right table cache entry to load
    if (sample_number < stss_keyframes_[cache_entry_number]) {
      int lower_bound = 0;
      int upper_bound = stss_keyframes_.size();
      // binary search to find range
      while (lower_bound <= upper_bound) {
        cache_entry_number = lower_bound + ((upper_bound - lower_bound) / 2);
        if (sample_number < stss_keyframes_[cache_entry_number]) {
          upper_bound = cache_entry_number - 1;
        } else {  // sample_number >= stss_keyframes_[cache_entry_number]
          // if we are at end of list or next cache entry is higher than sample
          // number we consider it a match
          if (cache_entry_number == stss_keyframes_.size() - 1 ||
              sample_number < stss_keyframes_[cache_entry_number + 1]) {
            break;
          }
          lower_bound = cache_entry_number + 1;
        }
      }
    }
    // We've gotten as close as we can using the cached values and must handle
    // two cases. (a) is that we know that sample_number is contained in the
    // cache_entry_number, because we know that:
    // stts_keyframes_[cache_entry_number] <= sample_number <
    //                              stts_keyframes_[cache_entry_number + 1]
    // (b) is that we only know:
    // stts_keyframes_[stts_keyframes_.size() - 1] <= sample_number
    // because we have not cached an upper bound to sample_number.
    // First step is to make (b) in to (a) by advancing through cache entries
    // until last table entry in cache > sample_number or until we arrive
    // at the cache entry in the table.
    while ((cache_entry_number == stss_keyframes_.size() - 1) &&
           cache_entry_number < total_cache_entries - 1) {
      // Use the first key frame in next cache as upper bound.
      int next_cached_entry_number =
          (cache_entry_number + 1) * stss_->GetCacheSizeEntries();
      uint32 next_cached_keyframe;
      if (!stss_->ReadU32Entry(next_cached_entry_number,
                               &next_cached_keyframe)) {
        return false;
      }
      --next_cached_keyframe;
      // if this keyframe is higher than our sample number we're in the right
      // table, stop
      if (sample_number < next_cached_keyframe) {
        break;
      }
      // ok, we need to look in to the next cache entry, advance
      cache_entry_number++;
      int first_table_entry_number =
          cache_entry_number * stss_->GetCacheSizeEntries();
      uint32 first_keyframe_in_cache_entry;
      if (!stss_->ReadU32Entry(first_table_entry_number,
                               &first_keyframe_in_cache_entry)) {
        return false;
      }
      --first_keyframe_in_cache_entry;
      // save first entry in keyframe cache
      stss_keyframes_.push_back(first_keyframe_in_cache_entry);
    }
    // make sure we have an upper bound
    if (cache_entry_number != total_cache_entries - 1 &&
        cache_entry_number == stss_keyframes_.size() - 1) {
      int next_cached_entry_number =
          ((cache_entry_number + 1) * stss_->GetCacheSizeEntries());
      uint32 next_cached_keyframe;
      if (!stss_->ReadU32Entry(next_cached_entry_number,
                               &next_cached_keyframe)) {
        return false;
      }
      --next_cached_keyframe;
      stss_keyframes_.push_back(next_cached_keyframe);
    }
    // ok, now we assume we are in state (a), and that we're either
    // at the end of the table or within the cache entry bounds for our
    // sample number
    DCHECK(stss_keyframes_[cache_entry_number] <= sample_number &&
           (cache_entry_number == total_cache_entries - 1 ||
            sample_number < stss_keyframes_[cache_entry_number + 1]));
  }
  // binary search within stss cache entry for keyframes bounding sample_number
  int lower_bound = cache_entry_number * stss_->GetCacheSizeEntries();
  int upper_bound = std::min(lower_bound + stss_->GetCacheSizeEntries(),
                             stss_->GetEntryCount());

  while (lower_bound <= upper_bound) {
    stss_table_index_ = lower_bound + ((upper_bound - lower_bound) / 2);
    if (!stss_->ReadU32Entry(stss_table_index_, &stss_last_keyframe_)) {
      return false;
    }
    --stss_last_keyframe_;
    if (sample_number < stss_last_keyframe_) {
      upper_bound = stss_table_index_ - 1;
    } else {  // sample_number >= last_keyframe
      lower_bound = stss_table_index_ + 1;
      // if this is the last entry in the table, we can stop here.
      if (lower_bound == stss_->GetEntryCount()) {
        stss_next_keyframe_ = UINT32_MAX;
        break;
      }
      // load next entry in table, see if we actually found the upper bound
      if (!stss_->ReadU32Entry(lower_bound, &stss_next_keyframe_)) {
        return false;
      }
      --stss_next_keyframe_;
      if (sample_number < stss_next_keyframe_) {
        stss_table_index_ = lower_bound;
        break;
      }
    }
  }
  return sample_number >= stss_last_keyframe_ &&
         sample_number < stss_next_keyframe_;
}

// The stts table has the following per-entry layout:
// uint32 sample count - number of sequential samples with this duration
// uint32 sample duration - duration in ticks of this sample range
bool ShellMP4Map::stts_Init() {
  int cache_segments =
      (stts_->GetEntryCount() / stts_->GetCacheSizeEntries()) + 1;
  stts_samples_.reserve(cache_segments);
  stts_timestamps_.reserve(cache_segments);
  // need at least one entry in valid stts
  if (stts_->GetEntryCount() > 0) {
    // integration starts at 0 for both cache entries
    stts_samples_.push_back(0);
    stts_timestamps_.push_back(0);
    if (!stts_->ReadU32PairEntry(0, &stts_next_first_sample_,
                                 &stts_sample_duration_)) {
      stts_ = NULL;
      return false;
    }
    stts_first_sample_ = 0;
    stts_first_sample_time_ = 0;
    stts_next_first_sample_time_ =
        stts_next_first_sample_ * stts_sample_duration_;
    stts_table_index_ = 0;
  } else {
    stts_ = NULL;
  }

  return true;
}

bool ShellMP4Map::stts_AdvanceToSample(uint32 sample_number) {
  DCHECK(stts_);
  // sample_number could be before our current sample range, in which case
  // we skip to the nearest table entry before sample_number and integrate
  // forward to the sample_number again.
  if (sample_number < stts_first_sample_) {
    if (!stts_SlipCacheToSample(sample_number, 0)) {
      return false;
    }
  }

  // sample number could also be well ahead of this cache segment, if we've
  // previously calculated summations ahead let's skip to the correct one
  int next_cache_index = (stts_table_index_ / stts_->GetCacheSizeEntries()) + 1;
  if ((next_cache_index < stts_samples_.size()) &&
      (sample_number >= stts_samples_[next_cache_index])) {
    if (!stts_SlipCacheToSample(sample_number, next_cache_index)) {
      return false;
    }
  }

  // integrate through the stts until sample_number is within current range
  while (stts_next_first_sample_ <= sample_number) {
    if (!stts_IntegrateStep()) {
      return false;
    }
  }
  return true;
}

// Move our integration steps to a previously saved entry in the cache tables.
// Searches linearly through the vector of old cached values, so can accept a
// starting index to do the search from.
bool ShellMP4Map::stts_SlipCacheToSample(uint32 sample_number,
                                         int starting_cache_index) {
  DCHECK_LT(starting_cache_index, stts_samples_.size());
  int cache_index = starting_cache_index;
  for (; cache_index + 1 < stts_samples_.size(); cache_index++) {
    if (sample_number < stts_samples_[cache_index + 1]) {
      break;
    }
  }
  stts_first_sample_ = stts_samples_[cache_index];
  stts_first_sample_time_ = stts_timestamps_[cache_index];
  stts_table_index_ = cache_index * stts_->GetCacheSizeEntries();
  uint32 sample_count;
  // read sample count and duration to set next values
  if (!stts_->ReadU32PairEntry(stts_table_index_, &sample_count,
                               &stts_sample_duration_)) {
    return false;
  }
  stts_next_first_sample_ = stts_first_sample_ + sample_count;
  stts_next_first_sample_time_ =
      stts_first_sample_time_ + (sample_count * stts_sample_duration_);
  return true;
}

bool ShellMP4Map::stts_AdvanceToTime(uint64 timestamp) {
  DCHECK(stts_);

  if (timestamp < stts_first_sample_time_) {
    if (!stts_SlipCacheToTime(timestamp, 0)) {
      return false;
    }
  }

  // sample number could also be well ahead of this cache segment, if we've
  // previously calculated summations ahead let's skip to the correct one
  int next_cache_index = (stts_table_index_ / stts_->GetCacheSizeEntries()) + 1;
  if ((next_cache_index < stts_timestamps_.size()) &&
      (timestamp >= stts_timestamps_[next_cache_index])) {
    if (!stts_SlipCacheToTime(timestamp, next_cache_index)) {
      return false;
    }
  }

  // integrate through the stts until sample_number is within current range
  while (stts_next_first_sample_time_ <= timestamp) {
    if (!stts_IntegrateStep()) {
      return false;
    }
  }
  return true;
}

bool ShellMP4Map::stts_IntegrateStep() {
  // advance time to next sample range
  uint32 range_size = stts_next_first_sample_ - stts_first_sample_;
  stts_first_sample_time_ += (range_size * stts_sample_duration_);
  // advance sample counter to next range
  stts_first_sample_ = stts_next_first_sample_;
  // bump table counter to next entry
  stts_table_index_++;
  // see if we just crossed a cache boundary and should cache results
  if (!(stts_table_index_ % stts_->GetCacheSizeEntries())) {
    int cache_index = stts_table_index_ / stts_->GetCacheSizeEntries();
    // check that this is our first time with these data
    if (cache_index == stts_samples_.size()) {
      // both tables should always grow together
      DCHECK_EQ(stts_samples_.size(), stts_timestamps_.size());
      stts_samples_.push_back(stts_first_sample_);
      stts_timestamps_.push_back(stts_first_sample_time_);
    }
    // our integration at this point should always match any stored record
    DCHECK_EQ(stts_first_sample_, stts_samples_[cache_index]);
    DCHECK_EQ(stts_first_sample_time_, stts_timestamps_[cache_index]);
  }
  if (stts_table_index_ < stts_->GetEntryCount()) {
    // load next entry data
    uint32 sample_count;
    if (!stts_->ReadU32PairEntry(stts_table_index_, &sample_count,
                                 &stts_sample_duration_)) {
      return false;
    }
    // calculate next sample number from range size
    stts_next_first_sample_ = stts_first_sample_ + sample_count;
    // and load duration of this sample range
    stts_next_first_sample_time_ =
        stts_first_sample_time_ + (sample_count * stts_sample_duration_);
  } else {
    // We've gone beyond the range defined by the last entry in the stts.
    // this is an error.
    highest_valid_sample_number_ =
        std::min(highest_valid_sample_number_, stts_first_sample_ - 1);
    return false;
  }
  return true;
}

bool ShellMP4Map::stts_SlipCacheToTime(uint64 timestamp,
                                       int starting_cache_index) {
  DCHECK_LT(starting_cache_index, stts_timestamps_.size());
  int cache_index = starting_cache_index;
  for (; cache_index + 1 < stts_timestamps_.size(); cache_index++) {
    if (timestamp < stts_timestamps_[cache_index + 1]) {
      break;
    }
  }
  stts_first_sample_ = stts_samples_[cache_index];
  stts_first_sample_time_ = stts_timestamps_[cache_index];
  stts_table_index_ = cache_index * stts_->GetCacheSizeEntries();
  // read sample count and duration to set next values
  uint32 sample_count;
  if (!stts_->ReadU32PairEntry(stts_table_index_, &sample_count,
                               &stts_sample_duration_)) {
    return false;
  }
  stts_next_first_sample_ = stts_first_sample_ + sample_count;
  stts_next_first_sample_time_ =
      stts_first_sample_time_ + (sample_count * stts_sample_duration_);
  return true;
}

bool ShellMP4Map::stsz_Init() { return stsz_->GetBytesAtEntry(0) != NULL; }

}  // namespace media
}  // namespace cobalt
