// Copyright 2012 Google Inc. 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/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
