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

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

#include <algorithm>
#include <map>
#include <sstream>

#include "base/bind.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "cobalt/media/base/timestamp_constants.h"
#include "cobalt/media/base/video_resolution.h"
#include "cobalt/media/filters/source_buffer_range.h"

namespace cobalt {
namespace media {

namespace {

// The number of ms to crossfade before trimming when buffers overlap.
// Note that this was defined inside AudioSplicer.  Re-define it here to avoid
// dependency on AudioSplicer.
const int kCrossfadeDurationInMilliseconds = 5;

// An arbitrarily-chosen number to estimate the duration of a buffer if none is
// set and there's not enough information to get a better estimate.
const int kDefaultBufferDurationInMs = 125;

// Limit the number of MEDIA_LOG() logs for splice buffer generation warnings
// and successes. Though these values are high enough to possibly exhaust the
// media internals event cache (along with other events), these logs are
// important for debugging splice generation.
const int kMaxSpliceGenerationWarningLogs = 50;
const int kMaxSpliceGenerationSuccessLogs = 20;

// Limit the number of MEDIA_LOG() logs for track buffer time gaps.
const int kMaxTrackBufferGapWarningLogs = 20;

// Limit the number of MEDIA_LOG() logs for MSE GC algorithm warnings.
const int kMaxGarbageCollectAlgorithmWarningLogs = 20;

// Limit the number of MEDIA_LOG() logs for same DTS for non-keyframe followed
// by keyframe. Prior to relaxing the "media segments must begin with a
// keyframe" requirement, we issued decode error for this situation. That was
// likely too strict, and now that the keyframe requirement is relaxed, we have
// no knowledge of media segment boundaries here. Now, we log but don't trigger
// decode error, since we allow these sequences which may cause extra decoder
// work or other side-effects.
const int kMaxStrangeSameTimestampsLogs = 20;

// Helper method that returns true if |ranges| is sorted in increasing order,
// false otherwise.
bool IsRangeListSorted(const std::list<media::SourceBufferRange*>& ranges) {
  DecodeTimestamp prev = kNoDecodeTimestamp();
  for (std::list<SourceBufferRange*>::const_iterator itr = ranges.begin();
       itr != ranges.end(); ++itr) {
    if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp())
      return false;
    prev = (*itr)->GetEndTimestamp();
  }
  return true;
}

// Returns an estimate of how far from the beginning or end of a range a buffer
// can be to still be considered in the range, given the |approximate_duration|
// of a buffer in the stream.
// TODO: Once all stream parsers emit accurate frame durations, use logic like
// FrameProcessor (2*last_frame_duration + last_decode_timestamp) instead of an
// overall maximum interbuffer delta for range discontinuity detection, and
// adjust similarly for splice frame discontinuity detection.
// See http://crbug.com/351489 and http://crbug.com/351166.
base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) {
  // Because we do not know exactly when is the next timestamp, any buffer
  // that starts within 2x the approximate duration of a buffer is considered
  // within this range.
  return 2 * approximate_duration;
}

// The amount of time the beginning of the buffered data can differ from the
// start time in order to still be considered the start of stream.
base::TimeDelta kSeekToStartFudgeRoom() {
  return base::TimeDelta::FromMilliseconds(1000);
}

// Helper method for logging, converts a range into a readable string.
std::string RangeToString(const SourceBufferRange& range) {
  if (range.size_in_bytes() == 0) {
    return "[]";
  }
  std::stringstream ss;
  ss << "[" << range.GetStartTimestamp().InSecondsF() << ";"
     << range.GetEndTimestamp().InSecondsF() << "("
     << range.GetBufferedEndTimestamp().InSecondsF() << ")]";
  return ss.str();
}

// Helper method for logging, converts a set of ranges into a readable string.
std::string RangesToString(const SourceBufferStream::RangeList& ranges) {
  if (ranges.empty()) return "<EMPTY>";

  std::stringstream ss;
  for (SourceBufferStream::RangeList::const_iterator iter = ranges.begin();
       iter != ranges.end(); ++iter) {
    if (iter != ranges.begin()) ss << " ";
    ss << RangeToString(**iter);
  }
  return ss.str();
}

std::string BufferQueueToLogString(
    const SourceBufferStream::BufferQueue& buffers) {
  std::stringstream result;
  if (buffers.front()->GetDecodeTimestamp().InMicroseconds() ==
          buffers.front()->timestamp().InMicroseconds() &&
      buffers.back()->GetDecodeTimestamp().InMicroseconds() ==
          buffers.back()->timestamp().InMicroseconds()) {
    result << "dts/pts=[" << buffers.front()->timestamp().InSecondsF() << ";"
           << buffers.back()->timestamp().InSecondsF()
           << "(last frame dur=" << buffers.back()->duration().InSecondsF()
           << ")]";
  } else {
    result << "dts=[" << buffers.front()->GetDecodeTimestamp().InSecondsF()
           << ";" << buffers.back()->GetDecodeTimestamp().InSecondsF()
           << "] pts=[" << buffers.front()->timestamp().InSecondsF() << ";"
           << buffers.back()->timestamp().InSecondsF()
           << "(last frame dur=" << buffers.back()->duration().InSecondsF()
           << ")]";
  }
  return result.str();
}

SourceBufferRange::GapPolicy TypeToGapPolicy(SourceBufferStream::Type type) {
  switch (type) {
    case SourceBufferStream::kAudio:
    case SourceBufferStream::kVideo:
      return SourceBufferRange::NO_GAPS_ALLOWED;
    case SourceBufferStream::kText:
      return SourceBufferRange::ALLOW_GAPS;
  }

  NOTREACHED();
  return SourceBufferRange::NO_GAPS_ALLOWED;
}

}  // namespace

SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
                                       const scoped_refptr<MediaLog>& media_log,
                                       bool splice_frames_enabled)
    : SourceBufferStreamState(splice_frames_enabled),
      media_log_(media_log),
      seek_buffer_timestamp_(kNoTimestamp),
      coded_frame_group_start_time_(kNoDecodeTimestamp()),
      range_for_next_append_(ranges_.end()),
      last_output_buffer_timestamp_(kNoDecodeTimestamp()),
      max_interbuffer_distance_(kNoTimestamp),
      memory_limit_(COBALT_MEDIA_BUFFER_NON_VIDEO_BUDGET) {
  DCHECK(audio_config.IsValidConfig());
  audio_configs_.push_back(audio_config);
}

SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
                                       const scoped_refptr<MediaLog>& media_log,
                                       bool splice_frames_enabled)
    : SourceBufferStreamState(splice_frames_enabled),
      media_log_(media_log),
      seek_buffer_timestamp_(kNoTimestamp),
      coded_frame_group_start_time_(kNoDecodeTimestamp()),
      range_for_next_append_(ranges_.end()),
      last_output_buffer_timestamp_(kNoDecodeTimestamp()),
      max_interbuffer_distance_(kNoTimestamp) {
  DCHECK(video_config.IsValidConfig());
  video_configs_.push_back(video_config);
  VideoResolution resolution =
      GetVideoResolution(video_config.visible_rect().size());
  memory_limit_ = resolution <= kVideoResolution1080p
                      ? COBALT_MEDIA_BUFFER_VIDEO_BUDGET_1080P
                      : COBALT_MEDIA_BUFFER_VIDEO_BUDGET_4K;
}

SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
                                       const scoped_refptr<MediaLog>& media_log,
                                       bool splice_frames_enabled)
    : SourceBufferStreamState(splice_frames_enabled),
      media_log_(media_log),
      text_track_config_(text_config),
      seek_buffer_timestamp_(kNoTimestamp),
      coded_frame_group_start_time_(kNoDecodeTimestamp()),
      range_for_next_append_(ranges_.end()),
      last_output_buffer_timestamp_(kNoDecodeTimestamp()),
      max_interbuffer_distance_(kNoTimestamp),
      memory_limit_(COBALT_MEDIA_BUFFER_NON_VIDEO_BUDGET) {}

SourceBufferStream::~SourceBufferStream() {
  while (!ranges_.empty()) {
    delete ranges_.front();
    ranges_.pop_front();
  }
}

void SourceBufferStream::OnStartOfCodedFrameGroup(
    DecodeTimestamp coded_frame_group_start_time) {
  DVLOG(1) << __func__ << " " << GetStreamTypeName() << " ("
           << coded_frame_group_start_time.InSecondsF() << ")";
  DCHECK(!end_of_stream_);
  coded_frame_group_start_time_ = coded_frame_group_start_time;
  new_coded_frame_group_ = true;

  RangeList::iterator last_range = range_for_next_append_;
  range_for_next_append_ = FindExistingRangeFor(coded_frame_group_start_time);

  // Only reset |last_appended_buffer_timestamp_| if this new coded frame group
  // is not adjacent to the previous coded frame group appended to the stream.
  if (range_for_next_append_ == ranges_.end() ||
      !AreAdjacentInSequence(last_appended_buffer_timestamp_,
                             coded_frame_group_start_time)) {
    ResetLastAppendedState();
    DVLOG(3) << __func__ << " next appended buffers will "
             << (range_for_next_append_ == ranges_.end()
                     ? "be in a new range"
                     : "overlap an existing range");
  } else if (last_range != ranges_.end()) {
    DCHECK(last_range == range_for_next_append_);
    DVLOG(3) << __func__ << " next appended buffers will continue range unless "
             << "intervening remove makes discontinuity";
  }
}

bool SourceBufferStream::Append(const BufferQueue& buffers) {
  TRACE_EVENT2("media", "SourceBufferStream::Append", "stream type",
               GetStreamTypeName(), "buffers to append", buffers.size());

  DCHECK(!buffers.empty());
  DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp());
  DCHECK(coded_frame_group_start_time_ <=
         buffers.front()->GetDecodeTimestamp());
  DCHECK(!end_of_stream_);

  DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": buffers "
           << BufferQueueToLogString(buffers);

  // New coded frame groups emitted by the coded frame processor must begin with
  // a keyframe. TODO(wolenetz): Change this to [DCHECK + MEDIA_LOG(ERROR...) +
  // return false] once the CHECK has baked in a stable release. See
  // https://crbug.com/580621.
  CHECK(!new_coded_frame_group_ || buffers.front()->is_key_frame());

  // Buffers within a coded frame group should be monotonically increasing.
  if (!IsMonotonicallyIncreasing(buffers)) {
    return false;
  }

  if (coded_frame_group_start_time_ < DecodeTimestamp() ||
      buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) {
    MEDIA_LOG(ERROR, media_log_)
        << "Cannot append a coded frame group with negative timestamps.";
    return false;
  }

  UpdateMaxInterbufferDistance(buffers);
  SetConfigIds(buffers);

  // Save a snapshot of stream state before range modifications are made.
  DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
  BufferQueue deleted_buffers;

  PrepareRangesForNextAppend(buffers, &deleted_buffers);

  // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
  // create a new range with |buffers|.
  if (range_for_next_append_ != ranges_.end()) {
    if (new_coded_frame_group_ && (!splice_frames_enabled_ ||
                                   buffers.front()->splice_buffers().empty())) {
      // If the first append to this stream in a new coded frame group continues
      // a previous range, use the new group's start time instead of the first
      // new buffer's timestamp as the proof of adjacency to the existing range.
      // A large gap (larger than our normal buffer adjacency test) can occur in
      // a muxed set of streams (which share a common coded frame group start
      // time) with a significantly jagged start across the streams.
      // Don't do this logic if there was a splice frame generated for the first
      // new buffer, since splices are guaranteed to be in the same range and
      // adjacent, and since the splice frame's timestamp can be less than
      // |coded_frame_group_start_time_| due to the splicing.
      (*range_for_next_append_)
          ->AppendBuffersToEnd(buffers, coded_frame_group_start_time_);
    } else {
      // Otherwise, use the first new buffer's timestamp as the proof of
      // adjacency.
      (*range_for_next_append_)
          ->AppendBuffersToEnd(buffers, kNoDecodeTimestamp());
    }

    last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
    last_appended_buffer_duration_ = buffers.back()->duration();
    last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame();
  } else {
    DecodeTimestamp new_range_start_time = std::min(
        coded_frame_group_start_time_, buffers.front()->GetDecodeTimestamp());
    const BufferQueue* buffers_for_new_range = &buffers;
    BufferQueue trimmed_buffers;

    // If the new range is not being created because of a new coded frame group,
    // then we must make sure that we start with a key frame.  This can happen
    // if the GOP in the previous append gets destroyed by a Remove() call.
    if (!new_coded_frame_group_) {
      BufferQueue::const_iterator itr = buffers.begin();

      // Scan past all the non-key-frames.
      while (itr != buffers.end() && !(*itr)->is_key_frame()) {
        ++itr;
      }

      // If we didn't find a key frame, then update the last appended
      // buffer state and return.
      if (itr == buffers.end()) {
        last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
        last_appended_buffer_duration_ = buffers.back()->duration();
        last_appended_buffer_is_keyframe_ = buffers.back()->is_key_frame();
        DVLOG(1) << __func__ << " " << GetStreamTypeName()
                 << ": new buffers in the middle of coded frame group depend on"
                    "keyframe that has been removed, and contain no keyframes."
                    "Skipping further processing.";
        DVLOG(1) << __func__ << " " << GetStreamTypeName()
                 << ": done. ranges_=" << RangesToString(ranges_);
        return true;
      } else if (itr != buffers.begin()) {
        // Copy the first key frame and everything after it into
        // |trimmed_buffers|.
        trimmed_buffers.assign(itr, buffers.end());
        buffers_for_new_range = &trimmed_buffers;
      }

      new_range_start_time =
          buffers_for_new_range->front()->GetDecodeTimestamp();
    }

    range_for_next_append_ = AddToRanges(new SourceBufferRange(
        TypeToGapPolicy(GetType()), *buffers_for_new_range,
        new_range_start_time,
        base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
                   base::Unretained(this))));
    last_appended_buffer_timestamp_ =
        buffers_for_new_range->back()->GetDecodeTimestamp();
    last_appended_buffer_duration_ = buffers_for_new_range->back()->duration();
    last_appended_buffer_is_keyframe_ =
        buffers_for_new_range->back()->is_key_frame();
  }

  new_coded_frame_group_ = false;

  MergeWithAdjacentRangeIfNecessary(range_for_next_append_);

  // Seek to try to fulfill a previous call to Seek().
  if (seek_pending_) {
    DCHECK(!selected_range_);
    DCHECK(deleted_buffers.empty());
    Seek(seek_buffer_timestamp_);
  }

  if (!deleted_buffers.empty()) {
    DecodeTimestamp start_of_deleted =
        deleted_buffers.front()->GetDecodeTimestamp();

    DCHECK(track_buffer_.empty() ||
           track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted)
        << "decode timestamp "
        << track_buffer_.back()->GetDecodeTimestamp().InSecondsF() << " sec"
        << ", start_of_deleted " << start_of_deleted.InSecondsF() << " sec";

    track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(),
                         deleted_buffers.end());
    DVLOG(3) << __func__ << " " << GetStreamTypeName() << " Added "
             << deleted_buffers.size()
             << " buffers to track buffer. TB size is now "
             << track_buffer_.size();
  } else {
    DVLOG(3) << __func__ << " " << GetStreamTypeName()
             << " No deleted buffers for track buffer";
  }

  // Prune any extra buffers in |track_buffer_| if new keyframes
  // are appended to the range covered by |track_buffer_|.
  if (!track_buffer_.empty()) {
    DecodeTimestamp keyframe_timestamp =
        FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp());
    if (keyframe_timestamp != kNoDecodeTimestamp())
      PruneTrackBuffer(keyframe_timestamp);
  }

  SetSelectedRangeIfNeeded(next_buffer_timestamp);

  DVLOG(1) << __func__ << " " << GetStreamTypeName()
           << ": done. ranges_=" << RangesToString(ranges_);
  // TODO: Investigate if the following DCHECK should be restored.
  // DCHECK(IsRangeListSorted(ranges_));
  DCHECK(OnlySelectedRangeIsSeeked());
  return true;
}

void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end,
                                base::TimeDelta duration) {
  DVLOG(1) << __func__ << " " << GetStreamTypeName() << " ("
           << start.InSecondsF() << ", " << end.InSecondsF() << ", "
           << duration.InSecondsF() << ")";
  DCHECK(start >= base::TimeDelta()) << start.InSecondsF();
  DCHECK(start < end) << "start " << start.InSecondsF() << " end "
                      << end.InSecondsF();
  DCHECK(duration != kNoTimestamp);

  DecodeTimestamp start_dts = DecodeTimestamp::FromPresentationTime(start);
  DecodeTimestamp end_dts = DecodeTimestamp::FromPresentationTime(end);
  DecodeTimestamp remove_end_timestamp =
      DecodeTimestamp::FromPresentationTime(duration);
  DecodeTimestamp keyframe_timestamp = FindKeyframeAfterTimestamp(end_dts);
  if (keyframe_timestamp != kNoDecodeTimestamp()) {
    remove_end_timestamp = keyframe_timestamp;
  } else if (end_dts < remove_end_timestamp) {
    remove_end_timestamp = end_dts;
  }

  BufferQueue deleted_buffers;
  RemoveInternal(start_dts, remove_end_timestamp, false, &deleted_buffers);

  if (!deleted_buffers.empty()) {
    // Buffers for the current position have been removed.
    SetSelectedRangeIfNeeded(deleted_buffers.front()->GetDecodeTimestamp());
    if (last_output_buffer_timestamp_ == kNoDecodeTimestamp()) {
      // We just removed buffers for the current playback position for this
      // stream, yet we also had output no buffer since the last Seek.
      // Re-seek to prevent stall.
      DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": re-seeking to "
               << seek_buffer_timestamp_
               << " to prevent stall if this time becomes buffered again";
      Seek(seek_buffer_timestamp_);
    }
  }
}

DecodeTimestamp SourceBufferStream::PotentialNextAppendTimestamp() const {
  // The next potential append will either be just at or after
  // |last_appended_buffer_timestamp_| (if known), or if unknown and we are
  // still at the beginning of a new coded frame group, then will be into the
  // range (if any) to which |coded_frame_group_start_time_| belongs.
  if (last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) {
    // TODO(wolenetz): Determine if this +1us is still necessary. See
    // https://crbug.com/589295.
    return last_appended_buffer_timestamp_ +
           base::TimeDelta::FromInternalValue(1);
  }

  if (new_coded_frame_group_) return coded_frame_group_start_time_;

  // If we still don't know a potential next append timestamp, then we have
  // removed the ranged to which it previously belonged and have not completed a
  // subsequent append or received a subsequent OnStartOfCodedFrameGroup()
  // signal.
  return kNoDecodeTimestamp();
}

void SourceBufferStream::UpdateLastAppendStateForRemove(
    DecodeTimestamp remove_start, DecodeTimestamp remove_end,
    bool exclude_start) {
  // TODO(chcunningham): change exclude_start to include_start in this class and
  // SourceBufferRange. Negatives are hard to reason about.
  bool include_start = !exclude_start;

  // No need to check previous append's GOP if starting a new CFG. New CFG is
  // already required to begin with a key frame.
  if (new_coded_frame_group_) return;

  if (range_for_next_append_ != ranges_.end()) {
    if (last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) {
      DCHECK((*range_for_next_append_)
                 ->BelongsToRange(last_appended_buffer_timestamp_));

      // Note start and end of last appended GOP.
      DecodeTimestamp gop_end = last_appended_buffer_timestamp_;
      DecodeTimestamp gop_start =
          (*range_for_next_append_)->KeyframeBeforeTimestamp(gop_end);

      // If last append is about to be disrupted, reset associated state so we
      // know to create a new range for future appends and require an initial
      // key frame.
      if (((include_start && remove_start == gop_end) ||
           remove_start < gop_end) &&
          remove_end > gop_start) {
        DVLOG(2) << __func__ << " " << GetStreamTypeName()
                 << " Resetting next append state for remove ("
                 << remove_start.InSecondsF() << ", " << remove_end.InSecondsF()
                 << ", " << exclude_start << ")";
        range_for_next_append_ = ranges_.end();
        ResetLastAppendedState();
      }
    } else {
      NOTREACHED() << __func__ << " " << GetStreamTypeName()
                   << " range_for_next_append_ set, but not tracking last"
                   << " append nor new coded frame group.";
    }
  }
}

void SourceBufferStream::RemoveInternal(DecodeTimestamp start,
                                        DecodeTimestamp end, bool exclude_start,
                                        BufferQueue* deleted_buffers) {
  DVLOG(2) << __func__ << " " << GetStreamTypeName() << " ("
           << start.InSecondsF() << ", " << end.InSecondsF() << ", "
           << exclude_start << ")";
  DVLOG(3) << __func__ << " " << GetStreamTypeName()
           << ": before remove ranges_=" << RangesToString(ranges_);

  DCHECK(start >= DecodeTimestamp());
  DCHECK(start < end) << "start " << start.InSecondsF() << " end "
                      << end.InSecondsF();
  DCHECK(deleted_buffers);

  // Doing this upfront simplifies decisions about range_for_next_append_ below.
  UpdateLastAppendStateForRemove(start, end, exclude_start);

  RangeList::iterator itr = ranges_.begin();
  while (itr != ranges_.end()) {
    SourceBufferRange* range = *itr;
    if (range->GetStartTimestamp() >= end) break;

    // Split off any remaining GOPs starting at or after |end| and add it to
    // |ranges_|.
    SourceBufferRange* new_range = range->SplitRange(end);
    if (new_range) {
      itr = ranges_.insert(++itr, new_range);

      // Update |range_for_next_append_| if it was previously |range| and should
      // be |new_range| now.
      if (range_for_next_append_ != ranges_.end() &&
          *range_for_next_append_ == range) {
        DecodeTimestamp potential_next_append_timestamp =
            PotentialNextAppendTimestamp();
        if (potential_next_append_timestamp != kNoDecodeTimestamp() &&
            new_range->BelongsToRange(potential_next_append_timestamp)) {
          range_for_next_append_ = itr;
        }
      }

      --itr;

      // Update the selected range if the next buffer position was transferred
      // to |new_range|.
      if (new_range->HasNextBufferPosition()) SetSelectedRange(new_range);
    }

    // Truncate the current range so that it only contains data before
    // the removal range.
    BufferQueue saved_buffers;
    bool delete_range = range->TruncateAt(start, &saved_buffers, exclude_start);

    // Check to see if the current playback position was removed and
    // update the selected range appropriately.
    if (!saved_buffers.empty()) {
      DCHECK(!range->HasNextBufferPosition());
      DCHECK(deleted_buffers->empty());

      *deleted_buffers = saved_buffers;
    }

    if (range == selected_range_ && !range->HasNextBufferPosition())
      SetSelectedRange(NULL);

    // If the current range now is completely covered by the removal
    // range then delete it and move on.
    if (delete_range) {
      DeleteAndRemoveRange(&itr);
      continue;
    }

    // Clear |range_for_next_append_| if we determine that the removal
    // operation makes it impossible for the next append to be added
    // to the current range.
    if (range_for_next_append_ != ranges_.end() &&
        *range_for_next_append_ == range) {
      DecodeTimestamp potential_next_append_timestamp =
          PotentialNextAppendTimestamp();

      if (!range->BelongsToRange(potential_next_append_timestamp)) {
        DVLOG(1) << "Resetting range_for_next_append_ since the next append"
                 << " can't add to the current range.";
        range_for_next_append_ =
            FindExistingRangeFor(potential_next_append_timestamp);
      }
    }

    // Move on to the next range.
    ++itr;
  }

  DVLOG(3) << __func__ << " " << GetStreamTypeName()
           << ": after remove ranges_=" << RangesToString(ranges_);

  DCHECK(IsRangeListSorted(ranges_));
  DCHECK(OnlySelectedRangeIsSeeked());
}

void SourceBufferStream::ResetSeekState() {
  SetSelectedRange(NULL);
  track_buffer_.clear();
  config_change_pending_ = false;
  last_output_buffer_timestamp_ = kNoDecodeTimestamp();
  just_exhausted_track_buffer_ = false;
  splice_buffers_index_ = 0;
  pending_buffer_ = NULL;
  pending_buffers_complete_ = false;
}

void SourceBufferStream::ResetLastAppendedState() {
  last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
  last_appended_buffer_duration_ = kNoTimestamp;
  last_appended_buffer_is_keyframe_ = false;
}

bool SourceBufferStream::ShouldSeekToStartOfBuffered(
    base::TimeDelta seek_timestamp) const {
  if (ranges_.empty()) return false;
  base::TimeDelta beginning_of_buffered =
      ranges_.front()->GetStartTimestamp().ToPresentationTime();
  return (seek_timestamp <= beginning_of_buffered &&
          beginning_of_buffered < kSeekToStartFudgeRoom());
}

bool SourceBufferStream::IsMonotonicallyIncreasing(const BufferQueue& buffers) {
  DCHECK(!buffers.empty());
  DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
  bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
  for (BufferQueue::const_iterator itr = buffers.begin(); itr != buffers.end();
       ++itr) {
    DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp();
    bool current_is_keyframe = (*itr)->is_key_frame();
    DCHECK(current_timestamp != kNoDecodeTimestamp());
    DCHECK((*itr)->duration() >= base::TimeDelta())
        << "Packet with invalid duration."
        << " pts " << (*itr)->timestamp().InSecondsF() << " dts "
        << (*itr)->GetDecodeTimestamp().InSecondsF() << " dur "
        << (*itr)->duration().InSecondsF();

    if (prev_timestamp != kNoDecodeTimestamp()) {
      if (current_timestamp < prev_timestamp) {
        MEDIA_LOG(ERROR, media_log_)
            << "Buffers did not monotonically increase.";
        return false;
      }

      if (current_timestamp == prev_timestamp &&
          SourceBufferRange::IsUncommonSameTimestampSequence(
              prev_is_keyframe, current_is_keyframe)) {
        LIMITED_MEDIA_LOG(DEBUG, media_log_, num_strange_same_timestamps_logs_,
                          kMaxStrangeSameTimestampsLogs)
            << "Detected an append sequence with keyframe following a "
               "non-keyframe, both with the same decode timestamp of "
            << current_timestamp.InSecondsF();
      }
    }

    prev_timestamp = current_timestamp;
    prev_is_keyframe = current_is_keyframe;
  }
  return true;
}

bool SourceBufferStream::OnlySelectedRangeIsSeeked() const {
  for (RangeList::const_iterator itr = ranges_.begin(); itr != ranges_.end();
       ++itr) {
    if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_)
      return false;
  }
  return !selected_range_ || selected_range_->HasNextBufferPosition();
}

void SourceBufferStream::UpdateMaxInterbufferDistance(
    const BufferQueue& buffers) {
  DCHECK(!buffers.empty());
  DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
  for (BufferQueue::const_iterator itr = buffers.begin(); itr != buffers.end();
       ++itr) {
    DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp();
    DCHECK(current_timestamp != kNoDecodeTimestamp());

    base::TimeDelta interbuffer_distance = (*itr)->duration();
    DCHECK(interbuffer_distance >= base::TimeDelta());

    if (prev_timestamp != kNoDecodeTimestamp()) {
      interbuffer_distance =
          std::max(current_timestamp - prev_timestamp, interbuffer_distance);
    }

    if (interbuffer_distance > base::TimeDelta()) {
      if (max_interbuffer_distance_ == kNoTimestamp) {
        max_interbuffer_distance_ = interbuffer_distance;
      } else {
        max_interbuffer_distance_ =
            std::max(max_interbuffer_distance_, interbuffer_distance);
      }
    }
    prev_timestamp = current_timestamp;
  }
}

void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) {
  for (BufferQueue::const_iterator itr = buffers.begin(); itr != buffers.end();
       ++itr) {
    (*itr)->SetConfigId(append_config_index_);
  }
}

bool SourceBufferStream::GarbageCollectIfNeeded(DecodeTimestamp media_time,
                                                size_t newDataSize) {
  DCHECK(media_time != kNoDecodeTimestamp());
  // Garbage collection should only happen before/during appending new data,
  // which should not happen in end-of-stream state.
  DCHECK(!end_of_stream_);
  // Compute size of |ranges_|.
  size_t ranges_size = GetBufferedSize();

  // Sanity and overflow checks
  if ((newDataSize > memory_limit_) ||
      (ranges_size + newDataSize < ranges_size)) {
    LIMITED_MEDIA_LOG(DEBUG, media_log_, num_garbage_collect_algorithm_logs_,
                      kMaxGarbageCollectAlgorithmWarningLogs)
        << GetStreamTypeName() << " stream: "
        << "new append of newDataSize=" << newDataSize
        << " bytes exceeds memory_limit_=" << memory_limit_
        << ", currently buffered ranges_size=" << ranges_size;
    return false;
  }

  // Return if we're under or at the memory limit.
  if (ranges_size + newDataSize <= memory_limit_) return true;

  size_t bytes_to_free = ranges_size + newDataSize - memory_limit_;

  DVLOG(2) << __func__ << " " << GetStreamTypeName()
           << ": Before GC media_time=" << media_time.InSecondsF()
           << " ranges_=" << RangesToString(ranges_)
           << " seek_pending_=" << seek_pending_
           << " ranges_size=" << ranges_size << " newDataSize=" << newDataSize
           << " memory_limit_=" << memory_limit_
           << " last_appended_buffer_timestamp_="
           << last_appended_buffer_timestamp_.InSecondsF();

  if (selected_range_ && !seek_pending_ &&
      media_time > selected_range_->GetBufferedEndTimestamp()) {
    // Strictly speaking |media_time| (taken from HTMLMediaElement::currentTime)
    // should always be in the buffered ranges, but media::Pipeline uses audio
    // stream as the main time source, when audio is present.
    // In cases when audio and video streams have different buffered ranges, the
    // |media_time| value might be slightly outside of the video stream buffered
    // range. In those cases we need to clamp |media_time| value to the current
    // stream buffered ranges, to ensure the MSE garbage collection algorithm
    // works correctly (see crbug.com/563292 for details).
    DecodeTimestamp selected_buffered_end =
        selected_range_->GetBufferedEndTimestamp();

    DVLOG(2) << __func__ << " media_time " << media_time.InSecondsF()
             << " is outside of selected_range_=["
             << selected_range_->GetStartTimestamp().InSecondsF() << ";"
             << selected_buffered_end.InSecondsF()
             << "] clamping media_time to be "
             << selected_buffered_end.InSecondsF();
    media_time = selected_buffered_end;
  }

  size_t bytes_freed = 0;

  // If last appended buffer position was earlier than the current playback time
  // then try deleting data between last append and current media_time.
  if (last_appended_buffer_timestamp_ != kNoDecodeTimestamp() &&
      last_appended_buffer_duration_ != kNoTimestamp &&
      media_time >
          last_appended_buffer_timestamp_ + last_appended_buffer_duration_) {
    size_t between = FreeBuffersAfterLastAppended(bytes_to_free, media_time);
    DVLOG(3) << __func__ << " FreeBuffersAfterLastAppended "
             << " released " << between << " bytes"
             << " ranges_=" << RangesToString(ranges_);
    bytes_freed += between;

    // Some players start appending data at the new seek target position before
    // actually initiating the seek operation (i.e. they try to improve seek
    // performance by prebuffering some data at the seek target position and
    // initiating seek once enough data is pre-buffered. In those cases we'll
    // see that data is being appended at some new position, but there is no
    // pending seek reported yet. In this situation we need to try preserving
    // the most recently appended data, i.e. data belonging to the same buffered
    // range as the most recent append.
    if (range_for_next_append_ != ranges_.end()) {
      DCHECK((*range_for_next_append_)->GetStartTimestamp() <= media_time);
      media_time = (*range_for_next_append_)->GetStartTimestamp();
      DVLOG(3) << __func__ << " media_time adjusted to "
               << media_time.InSecondsF();
    }
  }

  // If there is an unsatisfied pending seek, we can safely remove all data that
  // is earlier than seek target, then remove from the back until we reach the
  // most recently appended GOP and then remove from the front if we still don't
  // have enough space for the upcoming append.
  if (bytes_freed < bytes_to_free && seek_pending_) {
    DCHECK(!ranges_.empty());
    // All data earlier than the seek target |media_time| can be removed safely
    size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false);
    DVLOG(3) << __func__ << " Removed " << front
             << " bytes from the front. ranges_=" << RangesToString(ranges_);
    bytes_freed += front;

    // If removing data earlier than |media_time| didn't free up enough space,
    // then try deleting from the back until we reach most recently appended GOP
    if (bytes_freed < bytes_to_free) {
      size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true);
      DVLOG(3) << __func__ << " Removed " << back
               << " bytes from the back. ranges_=" << RangesToString(ranges_);
      bytes_freed += back;
    }

    // If even that wasn't enough, then try greedily deleting from the front,
    // that should allow us to remove as much data as necessary to succeed.
    if (bytes_freed < bytes_to_free) {
      size_t front2 = FreeBuffers(bytes_to_free - bytes_freed,
                                  ranges_.back()->GetEndTimestamp(), false);
      DVLOG(3) << __func__ << " Removed " << front2
               << " bytes from the front. ranges_=" << RangesToString(ranges_);
      bytes_freed += front2;
    }
    DCHECK(bytes_freed >= bytes_to_free);
  }

  // Try removing data from the front of the SourceBuffer up to |media_time|
  // position.
  if (bytes_freed < bytes_to_free) {
    size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false);
    DVLOG(3) << __func__ << " Removed " << front
             << " bytes from the front. ranges_=" << RangesToString(ranges_);
    bytes_freed += front;
  }

  // Try removing data from the back of the SourceBuffer, until we reach the
  // most recent append position.
  if (bytes_freed < bytes_to_free) {
    size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true);
    DVLOG(3) << __func__ << " Removed " << back
             << " bytes from the back. ranges_=" << RangesToString(ranges_);
    bytes_freed += back;
  }

  DVLOG(2) << __func__ << " " << GetStreamTypeName()
           << ": After GC bytes_to_free=" << bytes_to_free
           << " bytes_freed=" << bytes_freed
           << " ranges_=" << RangesToString(ranges_);

  return bytes_freed >= bytes_to_free;
}

size_t SourceBufferStream::FreeBuffersAfterLastAppended(
    size_t total_bytes_to_free, DecodeTimestamp media_time) {
  DVLOG(4) << __func__ << " last_appended_buffer_timestamp_="
           << last_appended_buffer_timestamp_.InSecondsF()
           << " media_time=" << media_time.InSecondsF();

  DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_;
  if (last_appended_buffer_is_keyframe_)
    remove_range_start += GetMaxInterbufferDistance();

  DecodeTimestamp remove_range_start_keyframe =
      FindKeyframeAfterTimestamp(remove_range_start);
  if (remove_range_start_keyframe != kNoDecodeTimestamp())
    remove_range_start = remove_range_start_keyframe;
  if (remove_range_start >= media_time) return 0;

  DecodeTimestamp remove_range_end;
  size_t bytes_freed = GetRemovalRange(remove_range_start, media_time,
                                       total_bytes_to_free, &remove_range_end);
  if (bytes_freed > 0) {
    DVLOG(4) << __func__ << " removing ["
             << remove_range_start.ToPresentationTime().InSecondsF() << ";"
             << remove_range_end.ToPresentationTime().InSecondsF() << "]";
    Remove(remove_range_start.ToPresentationTime(),
           remove_range_end.ToPresentationTime(),
           media_time.ToPresentationTime());
  }

  return bytes_freed;
}

size_t SourceBufferStream::GetRemovalRange(
    DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp,
    size_t total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) {
  DCHECK(start_timestamp >= DecodeTimestamp()) << start_timestamp.InSecondsF();
  DCHECK(start_timestamp < end_timestamp)
      << "start " << start_timestamp.InSecondsF() << ", end "
      << end_timestamp.InSecondsF();

  size_t bytes_freed = 0;

  for (RangeList::iterator itr = ranges_.begin();
       itr != ranges_.end() && bytes_freed < total_bytes_to_free; ++itr) {
    SourceBufferRange* range = *itr;
    if (range->GetStartTimestamp() >= end_timestamp) break;
    if (range->GetEndTimestamp() < start_timestamp) continue;

    size_t bytes_to_free = total_bytes_to_free - bytes_freed;
    size_t bytes_removed = range->GetRemovalGOP(
        start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp);
    bytes_freed += bytes_removed;
  }
  return bytes_freed;
}

size_t SourceBufferStream::FreeBuffers(size_t total_bytes_to_free,
                                       DecodeTimestamp media_time,
                                       bool reverse_direction) {
  TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers",
               "total bytes to free", total_bytes_to_free, "reverse direction",
               reverse_direction);

  DCHECK_GT(total_bytes_to_free, 0u);
  size_t bytes_freed = 0;

  // This range will save the last GOP appended to |range_for_next_append_|
  // if the buffers surrounding it get deleted during garbage collection.
  SourceBufferRange* new_range_for_append = NULL;

  while (!ranges_.empty() && bytes_freed < total_bytes_to_free) {
    SourceBufferRange* current_range = NULL;
    BufferQueue buffers;
    size_t bytes_deleted = 0;

    if (reverse_direction) {
      current_range = ranges_.back();
      DVLOG(5) << "current_range=" << RangeToString(*current_range);
      if (current_range->LastGOPContainsNextBufferPosition()) {
        DCHECK_EQ(current_range, selected_range_);
        DVLOG(5) << "current_range contains next read position, stopping GC";
        break;
      }
      DVLOG(5) << "Deleting GOP from back: " << RangeToString(*current_range);
      bytes_deleted = current_range->DeleteGOPFromBack(&buffers);
    } else {
      current_range = ranges_.front();
      DVLOG(5) << "current_range=" << RangeToString(*current_range);

      // FirstGOPEarlierThanMediaTime() is useful here especially if
      // |seek_pending_| (such that no range contains next buffer
      // position).
      // FirstGOPContainsNextBufferPosition() is useful here especially if
      // |!seek_pending_| to protect against DeleteGOPFromFront() if
      // FirstGOPEarlierThanMediaTime() was insufficient alone.
      if (!current_range->FirstGOPEarlierThanMediaTime(media_time) ||
          current_range->FirstGOPContainsNextBufferPosition()) {
        // We have removed all data up to the GOP that contains current playback
        // position, we can't delete any further.
        DVLOG(5) << "current_range contains playback position, stopping GC";
        break;
      }
      DVLOG(4) << "Deleting GOP from front: " << RangeToString(*current_range)
               << ", media_time: " << media_time.InMicroseconds()
               << ", current_range->HasNextBufferPosition(): "
               << current_range->HasNextBufferPosition();
      bytes_deleted = current_range->DeleteGOPFromFront(&buffers);
    }

    // Check to see if we've just deleted the GOP that was last appended.
    DecodeTimestamp end_timestamp = buffers.back()->GetDecodeTimestamp();
    if (end_timestamp == last_appended_buffer_timestamp_) {
      DCHECK(last_appended_buffer_timestamp_ != kNoDecodeTimestamp());
      DCHECK(!new_range_for_append);

      // Create a new range containing these buffers.
      new_range_for_append = new SourceBufferRange(
          TypeToGapPolicy(GetType()), buffers, kNoDecodeTimestamp(),
          base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
                     base::Unretained(this)));
      range_for_next_append_ = ranges_.end();
    } else {
      bytes_freed += bytes_deleted;
    }

    if (current_range->size_in_bytes() == 0) {
      DCHECK_NE(current_range, selected_range_);
      DCHECK(range_for_next_append_ == ranges_.end() ||
             *range_for_next_append_ != current_range);
      delete current_range;
      reverse_direction ? ranges_.pop_back() : ranges_.pop_front();
    }

    if (reverse_direction && new_range_for_append) {
      // We don't want to delete any further, or we'll be creating gaps
      break;
    }
  }

  // Insert |new_range_for_append| into |ranges_|, if applicable.
  if (new_range_for_append) {
    range_for_next_append_ = AddToRanges(new_range_for_append);
    DCHECK(range_for_next_append_ != ranges_.end());

    // Check to see if we need to merge |new_range_for_append| with the range
    // before or after it. |new_range_for_append| is created whenever the last
    // GOP appended is encountered, regardless of whether any buffers after it
    // are ultimately deleted. Merging is necessary if there were no buffers
    // (or very few buffers) deleted after creating |new_range_for_append|.
    if (range_for_next_append_ != ranges_.begin()) {
      RangeList::iterator range_before_next = range_for_next_append_;
      --range_before_next;
      MergeWithAdjacentRangeIfNecessary(range_before_next);
    }
    MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
  }
  return bytes_freed;
}

void SourceBufferStream::PrepareRangesForNextAppend(
    const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
  DCHECK(deleted_buffers);

  // Handle splices between the existing buffers and the new buffers.  If a
  // splice is generated the timestamp and duration of the first buffer in
  // |new_buffers| will be modified.
  if (splice_frames_enabled_) GenerateSpliceFrame(new_buffers);

  DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
  DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp();

  if (prev_timestamp != kNoDecodeTimestamp() &&
      prev_timestamp != next_timestamp) {
    // Clean up the old buffers between the last appended buffer and the
    // beginning of |new_buffers|.
    RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers);
  }

  // Always make the start of the delete range exclusive for same timestamp
  // across the last buffer in the previous append and the first buffer in the
  // current append. Never be exclusive if a splice frame was generated because
  // we don't generate splice frames for same timestamp situations.
  DCHECK(new_buffers.front()->splice_timestamp() !=
         new_buffers.front()->timestamp());
  const bool exclude_start = new_buffers.front()->splice_buffers().empty() &&
                             prev_timestamp == next_timestamp;

  // Delete the buffers that |new_buffers| overlaps.
  DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp();
  if (new_coded_frame_group_) {
    // Extend the deletion range earlier to the coded frame group start time if
    // this is the first append in a new coded frame group. Note that |start|
    // could already be less than |coded_frame_group_start_time_| if a splice
    // was generated.
    DCHECK(coded_frame_group_start_time_ != kNoDecodeTimestamp());
    start = std::min(coded_frame_group_start_time_, start);
  }
  DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp();
  base::TimeDelta duration = new_buffers.back()->duration();

  // Set end time for remove to include the duration of last buffer. If the
  // duration is estimated, use 1 microsecond instead to ensure frames are not
  // accidentally removed due to over-estimation.
  if (duration != kNoTimestamp && duration > base::TimeDelta() &&
      !new_buffers.back()->is_duration_estimated()) {
    end += duration;
  } else {
    // TODO(chcunningham): Emit warning when 0ms durations are not expected.
    // http://crbug.com/312836
    end += base::TimeDelta::FromInternalValue(1);
  }

  RemoveInternal(start, end, exclude_start, deleted_buffers);
}

bool SourceBufferStream::AreAdjacentInSequence(
    DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const {
  return first_timestamp < second_timestamp &&
         second_timestamp <=
             first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
}

void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) {
  // If we don't have the next timestamp, we don't have anything to delete.
  if (timestamp == kNoDecodeTimestamp()) return;

  while (!track_buffer_.empty() &&
         track_buffer_.back()->GetDecodeTimestamp() >= timestamp) {
    track_buffer_.pop_back();
  }
  DVLOG(3) << __func__ << " " << GetStreamTypeName()
           << " Removed all buffers with DTS >= " << timestamp.InSecondsF()
           << ". New track buffer size:" << track_buffer_.size();
}

void SourceBufferStream::MergeWithAdjacentRangeIfNecessary(
    const RangeList::iterator& range_with_new_buffers_itr) {
  DCHECK(range_with_new_buffers_itr != ranges_.end());

  SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
  RangeList::iterator next_range_itr = range_with_new_buffers_itr;
  ++next_range_itr;

  if (next_range_itr == ranges_.end() ||
      !range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) {
    return;
  }

  bool transfer_current_position = selected_range_ == *next_range_itr;
  DVLOG(3) << __func__ << " " << GetStreamTypeName() << " merging "
           << RangeToString(*range_with_new_buffers) << " into "
           << RangeToString(**next_range_itr);
  range_with_new_buffers->AppendRangeToEnd(**next_range_itr,
                                           transfer_current_position);
  // Update |selected_range_| pointer if |range| has become selected after
  // merges.
  if (transfer_current_position) SetSelectedRange(range_with_new_buffers);

  if (next_range_itr == range_for_next_append_)
    range_for_next_append_ = range_with_new_buffers_itr;

  DeleteAndRemoveRange(&next_range_itr);
}

void SourceBufferStream::Seek(base::TimeDelta timestamp) {
  DCHECK(timestamp >= base::TimeDelta());
  DVLOG(1) << __func__ << " " << GetStreamTypeName() << " ("
           << timestamp.InSecondsF() << ")";
  ResetSeekState();

  seek_buffer_timestamp_ = timestamp;
  seek_pending_ = true;

  if (ShouldSeekToStartOfBuffered(timestamp)) {
    ranges_.front()->SeekToStart();
    SetSelectedRange(ranges_.front());
    seek_pending_ = false;
    seek_buffer_timestamp_ = GetNextBufferTimestamp().ToPresentationTime();
    return;
  }

  DecodeTimestamp seek_dts = DecodeTimestamp::FromPresentationTime(timestamp);

  RangeList::iterator itr = ranges_.end();
  for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
    if ((*itr)->CanSeekTo(seek_dts)) break;
  }

  if (itr == ranges_.end()) return;

  SeekAndSetSelectedRange(*itr, seek_dts);
  seek_pending_ = false;
  seek_buffer_timestamp_ = GetNextBufferTimestamp().ToPresentationTime();
}

bool SourceBufferStream::IsSeekPending() const {
  return seek_pending_ && !IsEndOfStreamReached();
}

base::TimeDelta SourceBufferStream::GetSeekKeyframeTimestamp() const {
  DCHECK(!IsSeekPending());
  return seek_buffer_timestamp_;
}

void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
  DVLOG(1) << __func__ << " " << GetStreamTypeName() << " ("
           << duration.InSecondsF() << ")";
  DCHECK(!end_of_stream_);

  if (ranges_.empty()) return;

  DecodeTimestamp start = DecodeTimestamp::FromPresentationTime(duration);
  DecodeTimestamp end = ranges_.back()->GetBufferedEndTimestamp();

  // Trim the end if it exceeds the new duration.
  if (start < end) {
    BufferQueue deleted_buffers;
    RemoveInternal(start, end, false, &deleted_buffers);

    if (!deleted_buffers.empty()) {
      // Truncation removed current position. Clear selected range.
      SetSelectedRange(NULL);
    }
  }
}

SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
    scoped_refptr<StreamParserBuffer>* out_buffer) {
  DVLOG(2) << __func__ << " " << GetStreamTypeName();
  if (!pending_buffer_.get()) {
    const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer);
    if (status != SourceBufferStream::kSuccess ||
        !SetPendingBuffer(out_buffer)) {
      DVLOG(2) << __func__ << " " << GetStreamTypeName()
               << ": no pending buffer, returning status " << status;
      return status;
    }
  }

  if (!pending_buffer_->splice_buffers().empty()) {
    const SourceBufferStream::Status status =
        HandleNextBufferWithSplice(out_buffer);
    DVLOG(2) << __func__ << " " << GetStreamTypeName()
             << ": handled next buffer with splice, returning status "
             << status;
    return status;
  }

  DCHECK(pending_buffer_->preroll_buffer().get());

  const SourceBufferStream::Status status =
      HandleNextBufferWithPreroll(out_buffer);
  DVLOG(2) << __func__ << " " << GetStreamTypeName()
           << ": handled next buffer with preroll, returning status " << status;
  return status;
}

SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice(
    scoped_refptr<StreamParserBuffer>* out_buffer) {
  const BufferQueue& splice_buffers = pending_buffer_->splice_buffers();
  const size_t last_splice_buffer_index = splice_buffers.size() - 1;

  // Are there any splice buffers left to hand out?  The last buffer should be
  // handed out separately since it represents the first post-splice buffer.
  if (splice_buffers_index_ < last_splice_buffer_index) {
    // Account for config changes which occur between fade out buffers.
    if (current_config_index_ !=
        splice_buffers[splice_buffers_index_]->GetConfigId()) {
      config_change_pending_ = true;
      DVLOG(1) << "Config change (splice buffer config ID does not match).";
      return SourceBufferStream::kConfigChange;
    }

    // Every pre splice buffer must have the same splice_timestamp().
    DCHECK(pending_buffer_->splice_timestamp() ==
           splice_buffers[splice_buffers_index_]->splice_timestamp());

    // No pre splice buffers should have preroll.
    DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer().get());

    *out_buffer = splice_buffers[splice_buffers_index_++];
    return SourceBufferStream::kSuccess;
  }

  // Did we hand out the last pre-splice buffer on the previous call?
  if (!pending_buffers_complete_) {
    DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index);
    pending_buffers_complete_ = true;
    config_change_pending_ = true;
    DVLOG(1) << "Config change (forced for fade in of splice frame).";
    return SourceBufferStream::kConfigChange;
  }

  // All pre-splice buffers have been handed out and a config change completed,
  // so hand out the final buffer for fade in.  Because a config change is
  // always issued prior to handing out this buffer, any changes in config id
  // have been inherently handled.
  DCHECK(pending_buffers_complete_);
  DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1);
  DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp);
  *out_buffer = splice_buffers.back();
  pending_buffer_ = NULL;

  // If the last splice buffer has preroll, hand off to the preroll handler.
  return SetPendingBuffer(out_buffer) ? HandleNextBufferWithPreroll(out_buffer)
                                      : SourceBufferStream::kSuccess;
}

SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll(
    scoped_refptr<StreamParserBuffer>* out_buffer) {
  // Any config change should have already been handled.
  DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId());

  // Check if the preroll buffer has already been handed out.
  if (!pending_buffers_complete_) {
    pending_buffers_complete_ = true;
    *out_buffer = pending_buffer_->preroll_buffer();
    return SourceBufferStream::kSuccess;
  }

  // Preroll complete, hand out the final buffer.
  *out_buffer = pending_buffer_;
  pending_buffer_ = NULL;
  return SourceBufferStream::kSuccess;
}

SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal(
    scoped_refptr<StreamParserBuffer>* out_buffer) {
  CHECK(!config_change_pending_);

  if (!track_buffer_.empty()) {
    DCHECK(!selected_range_);
    scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front();

    // If the next buffer is an audio splice frame, the next effective config id
    // comes from the first splice buffer.
    if (next_buffer->GetSpliceBufferConfigId(0) != current_config_index_) {
      config_change_pending_ = true;
      DVLOG(1) << "Config change (track buffer config ID does not match).";
      return kConfigChange;
    }

    DVLOG(3) << __func__ << " Next buffer coming from track_buffer_";
    *out_buffer = next_buffer;
    track_buffer_.pop_front();
    WarnIfTrackBufferExhaustionSkipsForward(*out_buffer);
    last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();

    // If the track buffer becomes empty, then try to set the selected range
    // based on the timestamp of this buffer being returned.
    if (track_buffer_.empty()) {
      just_exhausted_track_buffer_ = true;
      SetSelectedRangeIfNeeded(last_output_buffer_timestamp_);
    }

    return kSuccess;
  }

  DCHECK(track_buffer_.empty());
  if (!selected_range_ || !selected_range_->HasNextBuffer()) {
    if (IsEndOfStreamReached()) {
      return kEndOfStream;
    }
    DVLOG(3) << __func__ << " " << GetStreamTypeName()
             << ": returning kNeedBuffer "
             << (selected_range_ ? "(selected range has no next buffer)"
                                 : "(no selected range)");
    return kNeedBuffer;
  }

  if (selected_range_->GetNextConfigId() != current_config_index_) {
    config_change_pending_ = true;
    DVLOG(1) << "Config change (selected range config ID does not match).";
    return kConfigChange;
  }

  CHECK(selected_range_->GetNextBuffer(out_buffer));
  WarnIfTrackBufferExhaustionSkipsForward(*out_buffer);
  last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
  return kSuccess;
}

void SourceBufferStream::WarnIfTrackBufferExhaustionSkipsForward(
    const scoped_refptr<StreamParserBuffer>& next_buffer) {
  if (!just_exhausted_track_buffer_) return;

  just_exhausted_track_buffer_ = false;
  DCHECK(next_buffer->is_key_frame());
  DecodeTimestamp next_output_buffer_timestamp =
      next_buffer->GetDecodeTimestamp();
  base::TimeDelta delta =
      next_output_buffer_timestamp - last_output_buffer_timestamp_;
  DCHECK_GE(delta, base::TimeDelta());
  if (delta > GetMaxInterbufferDistance()) {
    LIMITED_MEDIA_LOG(DEBUG, media_log_, num_track_buffer_gap_warning_logs_,
                      kMaxTrackBufferGapWarningLogs)
        << "Media append that overlapped current playback position caused time "
           "gap in playing "
        << GetStreamTypeName() << " stream because the next keyframe is "
        << delta.InMilliseconds() << "ms beyond last overlapped frame. Media "
                                     "may appear temporarily frozen.";
  }
}

DecodeTimestamp SourceBufferStream::GetNextBufferTimestamp() {
  if (!track_buffer_.empty())
    return track_buffer_.front()->GetDecodeTimestamp();

  if (!selected_range_) return kNoDecodeTimestamp();

  DCHECK(selected_range_->HasNextBufferPosition());
  return selected_range_->GetNextTimestamp();
}

SourceBufferStream::RangeList::iterator
SourceBufferStream::FindExistingRangeFor(DecodeTimestamp start_timestamp) {
  for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
    if ((*itr)->BelongsToRange(start_timestamp)) return itr;
  }
  return ranges_.end();
}

SourceBufferStream::RangeList::iterator SourceBufferStream::AddToRanges(
    SourceBufferRange* new_range) {
  DecodeTimestamp start_timestamp = new_range->GetStartTimestamp();
  RangeList::iterator itr = ranges_.end();
  for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
    if ((*itr)->GetStartTimestamp() > start_timestamp) break;
  }
  return ranges_.insert(itr, new_range);
}

SourceBufferStream::RangeList::iterator
SourceBufferStream::GetSelectedRangeItr() {
  DCHECK(selected_range_);
  RangeList::iterator itr = ranges_.end();
  for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
    if (*itr == selected_range_) break;
  }
  DCHECK(itr != ranges_.end());
  return itr;
}

void SourceBufferStream::SeekAndSetSelectedRange(
    SourceBufferRange* range, DecodeTimestamp seek_timestamp) {
  if (range) range->Seek(seek_timestamp);
  SetSelectedRange(range);
}

void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) {
  DVLOG(1) << __func__ << " " << GetStreamTypeName() << ": " << selected_range_
           << " " << (selected_range_ ? RangeToString(*selected_range_) : "")
           << " -> " << range << " " << (range ? RangeToString(*range) : "");
  if (selected_range_) selected_range_->ResetNextBufferPosition();
  DCHECK(!range || range->HasNextBufferPosition());
  selected_range_ = range;
}

Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const {
  Ranges<base::TimeDelta> ranges;
  for (RangeList::const_iterator itr = ranges_.begin(); itr != ranges_.end();
       ++itr) {
    ranges.Add((*itr)->GetStartTimestamp().ToPresentationTime(),
               (*itr)->GetBufferedEndTimestamp().ToPresentationTime());
  }
  return ranges;
}

base::TimeDelta SourceBufferStream::GetHighestPresentationTimestamp() const {
  if (ranges_.empty()) return base::TimeDelta();

  // TODO(wolenetz): Report actual highest PTS here, not DTS cast to PTS. See
  // https://crbug.com/398130.
  return ranges_.back()->GetEndTimestamp().ToPresentationTime();
}

base::TimeDelta SourceBufferStream::GetBufferedDuration() const {
  if (ranges_.empty()) return base::TimeDelta();

  return ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime();
}

size_t SourceBufferStream::GetBufferedSize() const {
  size_t ranges_size = 0;
  for (RangeList::const_iterator iter = ranges_.begin(); iter != ranges_.end();
       ++iter)
    ranges_size += (*iter)->size_in_bytes();
  return ranges_size;
}

void SourceBufferStream::MarkEndOfStream() {
  DCHECK(!end_of_stream_);
  end_of_stream_ = true;
}

void SourceBufferStream::UnmarkEndOfStream() {
  DCHECK(end_of_stream_);
  end_of_stream_ = false;
}

bool SourceBufferStream::IsEndOfStreamReached() const {
  if (!end_of_stream_ || !track_buffer_.empty()) return false;

  if (ranges_.empty()) return true;

  if (seek_pending_) {
    base::TimeDelta last_range_end_time =
        ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime();
    return seek_buffer_timestamp_ >= last_range_end_time;
  }

  if (!selected_range_) return true;

  return selected_range_ == ranges_.back();
}

const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() {
  if (config_change_pending_) CompleteConfigChange();
  return audio_configs_[current_config_index_];
}

const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() {
  if (config_change_pending_) CompleteConfigChange();
  return video_configs_[current_config_index_];
}

const TextTrackConfig& SourceBufferStream::GetCurrentTextTrackConfig() {
  return text_track_config_;
}

base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const {
  if (max_interbuffer_distance_ == kNoTimestamp)
    return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs);
  return max_interbuffer_distance_;
}

bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
  DCHECK(!audio_configs_.empty());
  DCHECK(video_configs_.empty());
  DVLOG(3) << "UpdateAudioConfig.";

  if (audio_configs_[0].codec() != config.codec()) {
    MEDIA_LOG(ERROR, media_log_) << "Audio codec changes not allowed.";
    return false;
  }

  if (!audio_configs_[0].encryption_scheme().Matches(
          config.encryption_scheme())) {
    MEDIA_LOG(ERROR, media_log_) << "Audio encryption changes not allowed.";
    return false;
  }

  // Check to see if the new config matches an existing one.
  for (size_t i = 0; i < audio_configs_.size(); ++i) {
    if (config.Matches(audio_configs_[i])) {
      append_config_index_ = i;
      return true;
    }
  }

  // No matches found so let's add this one to the list.
  append_config_index_ = audio_configs_.size();
  DVLOG(2) << "New audio config - index: " << append_config_index_;
  audio_configs_.resize(audio_configs_.size() + 1);
  audio_configs_[append_config_index_] = config;
  return true;
}

bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) {
  DCHECK(!video_configs_.empty());
  DCHECK(audio_configs_.empty());
  DVLOG(3) << "UpdateVideoConfig.";

  if (video_configs_[0].codec() != config.codec()) {
    MEDIA_LOG(ERROR, media_log_) << "Video codec changes not allowed.";
    return false;
  }

  if (!video_configs_[0].encryption_scheme().Matches(
          config.encryption_scheme())) {
    MEDIA_LOG(ERROR, media_log_) << "Video encryption changes not allowed.";
    return false;
  }

  // Check to see if the new config matches an existing one.
  for (size_t i = 0; i < video_configs_.size(); ++i) {
    if (config.Matches(video_configs_[i])) {
      append_config_index_ = i;
      return true;
    }
  }

  // No matches found so let's add this one to the list.
  append_config_index_ = video_configs_.size();
  DVLOG(2) << "New video config - index: " << append_config_index_;
  video_configs_.resize(video_configs_.size() + 1);
  video_configs_[append_config_index_] = config;

  VideoResolution resolution = GetVideoResolution(config.visible_rect().size());

  // TODO: Reduce the memory limit when there is no more 4k samples cached.
  if (resolution > kVideoResolution1080p) {
    memory_limit_ = COBALT_MEDIA_BUFFER_VIDEO_BUDGET_4K;
  }

  return true;
}

void SourceBufferStream::CompleteConfigChange() {
  config_change_pending_ = false;

  if (pending_buffer_.get()) {
    current_config_index_ =
        pending_buffer_->GetSpliceBufferConfigId(splice_buffers_index_);
    return;
  }

  if (!track_buffer_.empty()) {
    current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0);
    return;
  }

  if (selected_range_ && selected_range_->HasNextBuffer())
    current_config_index_ = selected_range_->GetNextConfigId();
}

void SourceBufferStream::SetSelectedRangeIfNeeded(
    const DecodeTimestamp timestamp) {
  DVLOG(2) << __func__ << " " << GetStreamTypeName() << "("
           << timestamp.InSecondsF() << ")";

  if (selected_range_) {
    DCHECK(track_buffer_.empty());
    return;
  }

  if (!track_buffer_.empty()) {
    DCHECK(!selected_range_);
    return;
  }

  DecodeTimestamp start_timestamp = timestamp;

  // If the next buffer timestamp is not known then use a timestamp just after
  // the timestamp on the last buffer returned by GetNextBuffer().
  if (start_timestamp == kNoDecodeTimestamp()) {
    if (last_output_buffer_timestamp_ == kNoDecodeTimestamp()) {
      DVLOG(2) << __func__ << " " << GetStreamTypeName()
               << " no previous output timestamp";
      return;
    }

    start_timestamp =
        last_output_buffer_timestamp_ + base::TimeDelta::FromInternalValue(1);
  }

  DecodeTimestamp seek_timestamp =
      FindNewSelectedRangeSeekTimestamp(start_timestamp);

  // If we don't have buffered data to seek to, then return.
  if (seek_timestamp == kNoDecodeTimestamp()) {
    DVLOG(2) << __func__ << " " << GetStreamTypeName()
             << " couldn't find new selected range seek timestamp";
    return;
  }

  DCHECK(track_buffer_.empty());
  SeekAndSetSelectedRange(*FindExistingRangeFor(seek_timestamp),
                          seek_timestamp);
}

DecodeTimestamp SourceBufferStream::FindNewSelectedRangeSeekTimestamp(
    const DecodeTimestamp start_timestamp) {
  DCHECK(start_timestamp != kNoDecodeTimestamp());
  DCHECK(start_timestamp >= DecodeTimestamp());

  RangeList::iterator itr = ranges_.begin();

  // When checking a range to see if it has or begins soon enough after
  // |start_timestamp|, use the fudge room to determine "soon enough".
  DecodeTimestamp start_timestamp_plus_fudge =
      start_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());

  // Multiple ranges could be within the fudge room, because the fudge room is
  // dynamic based on max inter-buffer distance seen so far. Optimistically
  // check the earliest ones first.
  for (; itr != ranges_.end(); ++itr) {
    DecodeTimestamp range_start = (*itr)->GetStartTimestamp();
    if (range_start >= start_timestamp_plus_fudge) break;
    if ((*itr)->GetEndTimestamp() < start_timestamp) continue;
    DecodeTimestamp search_timestamp = start_timestamp;
    if (start_timestamp < range_start &&
        start_timestamp_plus_fudge >= range_start) {
      search_timestamp = range_start;
    }
    DecodeTimestamp keyframe_timestamp =
        (*itr)->NextKeyframeTimestamp(search_timestamp);
    if (keyframe_timestamp != kNoDecodeTimestamp()) return keyframe_timestamp;
  }

  DVLOG(2) << __func__ << " " << GetStreamTypeName()
           << " no buffered data for dts=" << start_timestamp.InSecondsF();
  return kNoDecodeTimestamp();
}

DecodeTimestamp SourceBufferStream::FindKeyframeAfterTimestamp(
    const DecodeTimestamp timestamp) {
  DCHECK(timestamp != kNoDecodeTimestamp());

  RangeList::iterator itr = FindExistingRangeFor(timestamp);

  if (itr == ranges_.end()) return kNoDecodeTimestamp();

  // First check for a keyframe timestamp >= |timestamp|
  // in the current range.
  return (*itr)->NextKeyframeTimestamp(timestamp);
}

std::string SourceBufferStream::GetStreamTypeName() const {
  switch (GetType()) {
    case kAudio:
      return "AUDIO";
    case kVideo:
      return "VIDEO";
    case kText:
      return "TEXT";
  }
  NOTREACHED();
  return "";
}

SourceBufferStream::Type SourceBufferStream::GetType() const {
  if (!audio_configs_.empty()) return kAudio;
  if (!video_configs_.empty()) return kVideo;
  DCHECK_NE(text_track_config_.kind(), kTextNone);
  return kText;
}

void SourceBufferStream::DeleteAndRemoveRange(RangeList::iterator* itr) {
  DVLOG(1) << __func__;

  DCHECK(*itr != ranges_.end());
  if (**itr == selected_range_) {
    DVLOG(1) << __func__ << " deleting selected range.";
    SetSelectedRange(NULL);
  }

  if (*itr == range_for_next_append_) {
    DVLOG(1) << __func__ << " deleting range_for_next_append_.";
    range_for_next_append_ = ranges_.end();
    ResetLastAppendedState();
  }

  delete **itr;
  *itr = ranges_.erase(*itr);
}

void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) {
  DCHECK(!new_buffers.empty());

  // Splice frames are only supported for audio.
  if (GetType() != kAudio) return;

  // Find the overlapped range (if any).
  const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
  const DecodeTimestamp splice_dts =
      DecodeTimestamp::FromPresentationTime(splice_timestamp);
  RangeList::iterator range_itr = FindExistingRangeFor(splice_dts);
  if (range_itr == ranges_.end()) return;

  const DecodeTimestamp max_splice_end_dts =
      splice_dts +
      base::TimeDelta::FromMilliseconds(kCrossfadeDurationInMilliseconds);

  // Find all buffers involved before the splice point.
  BufferQueue pre_splice_buffers;
  if (!(*range_itr)
           ->GetBuffersInRange(splice_dts, max_splice_end_dts,
                               &pre_splice_buffers)) {
    return;
  }

  // If there are gaps in the timeline, it's possible that we only find buffers
  // after the splice point but within the splice range.  For simplicity, we do
  // not generate splice frames in this case.
  //
  // We also do not want to generate splices if the first new buffer replaces an
  // existing buffer exactly.
  if (pre_splice_buffers.front()->timestamp() >= splice_timestamp) {
    LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
                      kMaxSpliceGenerationWarningLogs)
        << "Skipping splice frame generation: first new buffer at "
        << splice_timestamp.InMicroseconds()
        << "us begins at or before existing buffer at "
        << pre_splice_buffers.front()->timestamp().InMicroseconds() << "us.";
    DVLOG(1) << "Skipping splice: overlapped buffers begin at or after the "
                "first new buffer.";
    return;
  }

  // If any |pre_splice_buffers| are already splices or preroll, do not generate
  // a splice.
  for (size_t i = 0; i < pre_splice_buffers.size(); ++i) {
    const BufferQueue& original_splice_buffers =
        pre_splice_buffers[i]->splice_buffers();
    if (!original_splice_buffers.empty()) {
      LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
                        kMaxSpliceGenerationWarningLogs)
          << "Skipping splice frame generation: overlapped buffers at "
          << pre_splice_buffers[i]->timestamp().InMicroseconds()
          << "us are in a previously buffered splice.";
      DVLOG(1) << "Can't generate splice: overlapped buffers contain a "
                  "pre-existing splice.";
      return;
    }

    if (pre_splice_buffers[i]->preroll_buffer().get()) {
      LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
                        kMaxSpliceGenerationWarningLogs)
          << "Skipping splice frame generation: overlapped buffers at "
          << pre_splice_buffers[i]->timestamp().InMicroseconds()
          << "us contain preroll.";
      DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll.";
      return;
    }
  }

  // Don't generate splice frames which represent less than a millisecond (which
  // is frequently the extent of timestamp resolution for poorly encoded media)
  // or less than two samples (need at least two to crossfade).
  const base::TimeDelta splice_duration =
      pre_splice_buffers.back()->timestamp() +
      pre_splice_buffers.back()->duration() - splice_timestamp;
  const base::TimeDelta minimum_splice_duration = std::max(
      base::TimeDelta::FromMilliseconds(1),
      base::TimeDelta::FromSecondsD(
          2.0 / audio_configs_[append_config_index_].samples_per_second()));
  if (splice_duration < minimum_splice_duration) {
    LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_warning_logs_,
                      kMaxSpliceGenerationWarningLogs)
        << "Skipping splice frame generation: not enough samples for splicing "
           "new buffer at "
        << splice_timestamp.InMicroseconds() << "us. Have "
        << splice_duration.InMicroseconds() << "us, but need "
        << minimum_splice_duration.InMicroseconds() << "us.";
    DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have "
             << splice_duration.InMicroseconds() << "us, but need "
             << minimum_splice_duration.InMicroseconds() << "us.";
    return;
  }

  DVLOG(1) << "Generating splice frame @ " << new_buffers.front()->timestamp()
           << ", splice duration: " << splice_duration.InMicroseconds()
           << " us";
  LIMITED_MEDIA_LOG(DEBUG, media_log_, num_splice_generation_success_logs_,
                    kMaxSpliceGenerationSuccessLogs)
      << "Generated splice of overlap duration "
      << splice_duration.InMicroseconds() << "us into new buffer at "
      << splice_timestamp.InMicroseconds() << "us.";
  new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers);
}

bool SourceBufferStream::SetPendingBuffer(
    scoped_refptr<StreamParserBuffer>* out_buffer) {
  DCHECK(out_buffer->get());
  DCHECK(!pending_buffer_.get());

  const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty();
  const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get();

  if (!have_splice_buffers && !have_preroll_buffer) return false;

  DCHECK_NE(have_splice_buffers, have_preroll_buffer);
  splice_buffers_index_ = 0;
  pending_buffer_.swap(*out_buffer);
  pending_buffers_complete_ = false;
  return true;
}

}  // namespace media
}  // namespace cobalt
