Home | History | Annotate | Download | only in filters
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "media/filters/source_buffer_stream.h"
      6 
      7 #include <algorithm>
      8 #include <map>
      9 
     10 #include "base/bind.h"
     11 #include "base/debug/trace_event.h"
     12 #include "base/logging.h"
     13 #include "media/base/audio_splicer.h"
     14 #include "media/filters/source_buffer_platform.h"
     15 #include "media/filters/source_buffer_range.h"
     16 
     17 namespace media {
     18 
     19 // Helper method that returns true if |ranges| is sorted in increasing order,
     20 // false otherwise.
     21 static bool IsRangeListSorted(
     22     const std::list<media::SourceBufferRange*>& ranges) {
     23   DecodeTimestamp prev = kNoDecodeTimestamp();
     24   for (std::list<SourceBufferRange*>::const_iterator itr =
     25        ranges.begin(); itr != ranges.end(); ++itr) {
     26     if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp())
     27       return false;
     28     prev = (*itr)->GetEndTimestamp();
     29   }
     30   return true;
     31 }
     32 
     33 // Returns an estimate of how far from the beginning or end of a range a buffer
     34 // can be to still be considered in the range, given the |approximate_duration|
     35 // of a buffer in the stream.
     36 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use
     37 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp)
     38 // instead of an overall maximum interbuffer delta for range discontinuity
     39 // detection, and adjust similarly for splice frame discontinuity detection.
     40 // See http://crbug.com/351489 and http://crbug.com/351166.
     41 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) {
     42   // Because we do not know exactly when is the next timestamp, any buffer
     43   // that starts within 2x the approximate duration of a buffer is considered
     44   // within this range.
     45   return 2 * approximate_duration;
     46 }
     47 
     48 // An arbitrarily-chosen number to estimate the duration of a buffer if none
     49 // is set and there's not enough information to get a better estimate.
     50 static int kDefaultBufferDurationInMs = 125;
     51 
     52 // The amount of time the beginning of the buffered data can differ from the
     53 // start time in order to still be considered the start of stream.
     54 static base::TimeDelta kSeekToStartFudgeRoom() {
     55   return base::TimeDelta::FromMilliseconds(1000);
     56 }
     57 
     58 static SourceBufferRange::GapPolicy TypeToGapPolicy(
     59     SourceBufferStream::Type type) {
     60   switch (type) {
     61     case SourceBufferStream::kAudio:
     62     case SourceBufferStream::kVideo:
     63       return SourceBufferRange::NO_GAPS_ALLOWED;
     64     case SourceBufferStream::kText:
     65       return SourceBufferRange::ALLOW_GAPS;
     66   }
     67 
     68   NOTREACHED();
     69   return SourceBufferRange::NO_GAPS_ALLOWED;
     70 }
     71 
     72 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
     73                                        const LogCB& log_cb,
     74                                        bool splice_frames_enabled)
     75     : log_cb_(log_cb),
     76       current_config_index_(0),
     77       append_config_index_(0),
     78       seek_pending_(false),
     79       end_of_stream_(false),
     80       seek_buffer_timestamp_(kNoTimestamp()),
     81       selected_range_(NULL),
     82       media_segment_start_time_(kNoDecodeTimestamp()),
     83       range_for_next_append_(ranges_.end()),
     84       new_media_segment_(false),
     85       last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
     86       last_appended_buffer_is_keyframe_(false),
     87       last_output_buffer_timestamp_(kNoDecodeTimestamp()),
     88       max_interbuffer_distance_(kNoTimestamp()),
     89       memory_limit_(kSourceBufferAudioMemoryLimit),
     90       config_change_pending_(false),
     91       splice_buffers_index_(0),
     92       pending_buffers_complete_(false),
     93       splice_frames_enabled_(splice_frames_enabled) {
     94   DCHECK(audio_config.IsValidConfig());
     95   audio_configs_.push_back(audio_config);
     96 }
     97 
     98 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
     99                                        const LogCB& log_cb,
    100                                        bool splice_frames_enabled)
    101     : log_cb_(log_cb),
    102       current_config_index_(0),
    103       append_config_index_(0),
    104       seek_pending_(false),
    105       end_of_stream_(false),
    106       seek_buffer_timestamp_(kNoTimestamp()),
    107       selected_range_(NULL),
    108       media_segment_start_time_(kNoDecodeTimestamp()),
    109       range_for_next_append_(ranges_.end()),
    110       new_media_segment_(false),
    111       last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
    112       last_appended_buffer_is_keyframe_(false),
    113       last_output_buffer_timestamp_(kNoDecodeTimestamp()),
    114       max_interbuffer_distance_(kNoTimestamp()),
    115       memory_limit_(kSourceBufferVideoMemoryLimit),
    116       config_change_pending_(false),
    117       splice_buffers_index_(0),
    118       pending_buffers_complete_(false),
    119       splice_frames_enabled_(splice_frames_enabled) {
    120   DCHECK(video_config.IsValidConfig());
    121   video_configs_.push_back(video_config);
    122 }
    123 
    124 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
    125                                        const LogCB& log_cb,
    126                                        bool splice_frames_enabled)
    127     : log_cb_(log_cb),
    128       current_config_index_(0),
    129       append_config_index_(0),
    130       text_track_config_(text_config),
    131       seek_pending_(false),
    132       end_of_stream_(false),
    133       seek_buffer_timestamp_(kNoTimestamp()),
    134       selected_range_(NULL),
    135       media_segment_start_time_(kNoDecodeTimestamp()),
    136       range_for_next_append_(ranges_.end()),
    137       new_media_segment_(false),
    138       last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
    139       last_appended_buffer_is_keyframe_(false),
    140       last_output_buffer_timestamp_(kNoDecodeTimestamp()),
    141       max_interbuffer_distance_(kNoTimestamp()),
    142       memory_limit_(kSourceBufferAudioMemoryLimit),
    143       config_change_pending_(false),
    144       splice_buffers_index_(0),
    145       pending_buffers_complete_(false),
    146       splice_frames_enabled_(splice_frames_enabled) {}
    147 
    148 SourceBufferStream::~SourceBufferStream() {
    149   while (!ranges_.empty()) {
    150     delete ranges_.front();
    151     ranges_.pop_front();
    152   }
    153 }
    154 
    155 void SourceBufferStream::OnNewMediaSegment(
    156     DecodeTimestamp media_segment_start_time) {
    157   DVLOG(1) << __FUNCTION__ << "(" << media_segment_start_time.InSecondsF()
    158            << ")";
    159   DCHECK(!end_of_stream_);
    160   media_segment_start_time_ = media_segment_start_time;
    161   new_media_segment_ = true;
    162 
    163   RangeList::iterator last_range = range_for_next_append_;
    164   range_for_next_append_ = FindExistingRangeFor(media_segment_start_time);
    165 
    166   // Only reset |last_appended_buffer_timestamp_| if this new media segment is
    167   // not adjacent to the previous media segment appended to the stream.
    168   if (range_for_next_append_ == ranges_.end() ||
    169       !AreAdjacentInSequence(last_appended_buffer_timestamp_,
    170                              media_segment_start_time)) {
    171     last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
    172     last_appended_buffer_is_keyframe_ = false;
    173     DVLOG(3) << __FUNCTION__ << " next appended buffers will be in a new range";
    174   } else if (last_range != ranges_.end()) {
    175     DCHECK(last_range == range_for_next_append_);
    176     DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range "
    177              << "unless intervening remove makes discontinuity";
    178   }
    179 }
    180 
    181 bool SourceBufferStream::Append(const BufferQueue& buffers) {
    182   TRACE_EVENT2("media", "SourceBufferStream::Append",
    183                "stream type", GetStreamTypeName(),
    184                "buffers to append", buffers.size());
    185 
    186   DCHECK(!buffers.empty());
    187   DCHECK(media_segment_start_time_ != kNoDecodeTimestamp());
    188   DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp());
    189   DCHECK(!end_of_stream_);
    190 
    191   // New media segments must begin with a keyframe.
    192   if (new_media_segment_ && !buffers.front()->IsKeyframe()) {
    193     MEDIA_LOG(log_cb_) << "Media segment did not begin with keyframe.";
    194     return false;
    195   }
    196 
    197   // Buffers within a media segment should be monotonically increasing.
    198   if (!IsMonotonicallyIncreasing(buffers))
    199     return false;
    200 
    201   if (media_segment_start_time_ < DecodeTimestamp() ||
    202       buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) {
    203     MEDIA_LOG(log_cb_)
    204         << "Cannot append a media segment with negative timestamps.";
    205     return false;
    206   }
    207 
    208   if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(),
    209                             buffers.front()->IsKeyframe())) {
    210     MEDIA_LOG(log_cb_) << "Invalid same timestamp construct detected at time "
    211                        << buffers.front()->GetDecodeTimestamp().InSecondsF();
    212 
    213     return false;
    214   }
    215 
    216   UpdateMaxInterbufferDistance(buffers);
    217   SetConfigIds(buffers);
    218 
    219   // Save a snapshot of stream state before range modifications are made.
    220   DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
    221   BufferQueue deleted_buffers;
    222 
    223   PrepareRangesForNextAppend(buffers, &deleted_buffers);
    224 
    225   // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
    226   // create a new range with |buffers|.
    227   if (range_for_next_append_ != ranges_.end()) {
    228     (*range_for_next_append_)->AppendBuffersToEnd(buffers);
    229     last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
    230     last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe();
    231   } else {
    232     DecodeTimestamp new_range_start_time = std::min(
    233         media_segment_start_time_, buffers.front()->GetDecodeTimestamp());
    234     const BufferQueue* buffers_for_new_range = &buffers;
    235     BufferQueue trimmed_buffers;
    236 
    237     // If the new range is not being created because of a new media
    238     // segment, then we must make sure that we start with a keyframe.
    239     // This can happen if the GOP in the previous append gets destroyed
    240     // by a Remove() call.
    241     if (!new_media_segment_) {
    242       BufferQueue::const_iterator itr = buffers.begin();
    243 
    244       // Scan past all the non-keyframes.
    245       while (itr != buffers.end() && !(*itr)->IsKeyframe()) {
    246         ++itr;
    247       }
    248 
    249       // If we didn't find a keyframe, then update the last appended
    250       // buffer state and return.
    251       if (itr == buffers.end()) {
    252         last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
    253         last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe();
    254         return true;
    255       } else if (itr != buffers.begin()) {
    256         // Copy the first keyframe and everything after it into
    257         // |trimmed_buffers|.
    258         trimmed_buffers.assign(itr, buffers.end());
    259         buffers_for_new_range = &trimmed_buffers;
    260       }
    261 
    262       new_range_start_time =
    263           buffers_for_new_range->front()->GetDecodeTimestamp();
    264     }
    265 
    266     range_for_next_append_ =
    267         AddToRanges(new SourceBufferRange(
    268             TypeToGapPolicy(GetType()),
    269             *buffers_for_new_range, new_range_start_time,
    270             base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
    271                        base::Unretained(this))));
    272     last_appended_buffer_timestamp_ =
    273         buffers_for_new_range->back()->GetDecodeTimestamp();
    274     last_appended_buffer_is_keyframe_ =
    275         buffers_for_new_range->back()->IsKeyframe();
    276   }
    277 
    278   new_media_segment_ = false;
    279 
    280   MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
    281 
    282   // Seek to try to fulfill a previous call to Seek().
    283   if (seek_pending_) {
    284     DCHECK(!selected_range_);
    285     DCHECK(deleted_buffers.empty());
    286     Seek(seek_buffer_timestamp_);
    287   }
    288 
    289   if (!deleted_buffers.empty()) {
    290     DecodeTimestamp start_of_deleted =
    291         deleted_buffers.front()->GetDecodeTimestamp();
    292 
    293     DCHECK(track_buffer_.empty() ||
    294            track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted)
    295         << "decode timestamp "
    296         << track_buffer_.back()->GetDecodeTimestamp().InSecondsF() << " sec"
    297         << ", start_of_deleted " << start_of_deleted.InSecondsF()<< " sec";
    298 
    299     track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(),
    300                          deleted_buffers.end());
    301   }
    302 
    303   // Prune any extra buffers in |track_buffer_| if new keyframes
    304   // are appended to the range covered by |track_buffer_|.
    305   if (!track_buffer_.empty()) {
    306     DecodeTimestamp keyframe_timestamp =
    307         FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp());
    308     if (keyframe_timestamp != kNoDecodeTimestamp())
    309       PruneTrackBuffer(keyframe_timestamp);
    310   }
    311 
    312   SetSelectedRangeIfNeeded(next_buffer_timestamp);
    313 
    314   GarbageCollectIfNeeded();
    315 
    316   DCHECK(IsRangeListSorted(ranges_));
    317   DCHECK(OnlySelectedRangeIsSeeked());
    318   return true;
    319 }
    320 
    321 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end,
    322                                 base::TimeDelta duration) {
    323   DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF()
    324            << ", " << end.InSecondsF()
    325            << ", " << duration.InSecondsF() << ")";
    326   DCHECK(start >= base::TimeDelta()) << start.InSecondsF();
    327   DCHECK(start < end) << "start " << start.InSecondsF()
    328                       << " end " << end.InSecondsF();
    329   DCHECK(duration != kNoTimestamp());
    330 
    331   DecodeTimestamp start_dts = DecodeTimestamp::FromPresentationTime(start);
    332   DecodeTimestamp end_dts = DecodeTimestamp::FromPresentationTime(end);
    333   DecodeTimestamp remove_end_timestamp =
    334       DecodeTimestamp::FromPresentationTime(duration);
    335   DecodeTimestamp keyframe_timestamp = FindKeyframeAfterTimestamp(end_dts);
    336   if (keyframe_timestamp != kNoDecodeTimestamp()) {
    337     remove_end_timestamp = keyframe_timestamp;
    338   } else if (end_dts < remove_end_timestamp) {
    339     remove_end_timestamp = end_dts;
    340   }
    341 
    342   BufferQueue deleted_buffers;
    343   RemoveInternal(start_dts, remove_end_timestamp, false, &deleted_buffers);
    344 
    345   if (!deleted_buffers.empty())
    346     SetSelectedRangeIfNeeded(deleted_buffers.front()->GetDecodeTimestamp());
    347 }
    348 
    349 void SourceBufferStream::RemoveInternal(
    350     DecodeTimestamp start, DecodeTimestamp end, bool is_exclusive,
    351     BufferQueue* deleted_buffers) {
    352   DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF()
    353            << ", " << end.InSecondsF()
    354            << ", " << is_exclusive << ")";
    355 
    356   DCHECK(start >= DecodeTimestamp());
    357   DCHECK(start < end) << "start " << start.InSecondsF()
    358                       << " end " << end.InSecondsF();
    359   DCHECK(deleted_buffers);
    360 
    361   RangeList::iterator itr = ranges_.begin();
    362 
    363   while (itr != ranges_.end()) {
    364     SourceBufferRange* range = *itr;
    365     if (range->GetStartTimestamp() >= end)
    366       break;
    367 
    368     // Split off any remaining end piece and add it to |ranges_|.
    369     SourceBufferRange* new_range = range->SplitRange(end, is_exclusive);
    370     if (new_range) {
    371       itr = ranges_.insert(++itr, new_range);
    372       --itr;
    373 
    374       // Update the selected range if the next buffer position was transferred
    375       // to |new_range|.
    376       if (new_range->HasNextBufferPosition())
    377         SetSelectedRange(new_range);
    378     }
    379 
    380     // Truncate the current range so that it only contains data before
    381     // the removal range.
    382     BufferQueue saved_buffers;
    383     bool delete_range = range->TruncateAt(start, &saved_buffers, is_exclusive);
    384 
    385     // Check to see if the current playback position was removed and
    386     // update the selected range appropriately.
    387     if (!saved_buffers.empty()) {
    388       DCHECK(!range->HasNextBufferPosition());
    389       DCHECK(deleted_buffers->empty());
    390 
    391       *deleted_buffers = saved_buffers;
    392     }
    393 
    394     if (range == selected_range_ && !range->HasNextBufferPosition())
    395       SetSelectedRange(NULL);
    396 
    397     // If the current range now is completely covered by the removal
    398     // range then delete it and move on.
    399     if (delete_range) {
    400       DeleteAndRemoveRange(&itr);
    401       continue;
    402     }
    403 
    404     // Clear |range_for_next_append_| if we determine that the removal
    405     // operation makes it impossible for the next append to be added
    406     // to the current range.
    407     if (range_for_next_append_ != ranges_.end() &&
    408         *range_for_next_append_ == range &&
    409         last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) {
    410       DecodeTimestamp potential_next_append_timestamp =
    411           last_appended_buffer_timestamp_ +
    412           base::TimeDelta::FromInternalValue(1);
    413 
    414       if (!range->BelongsToRange(potential_next_append_timestamp)) {
    415         DVLOG(1) << "Resetting range_for_next_append_ since the next append"
    416                  <<  " can't add to the current range.";
    417         range_for_next_append_ =
    418             FindExistingRangeFor(potential_next_append_timestamp);
    419       }
    420     }
    421 
    422     // Move on to the next range.
    423     ++itr;
    424   }
    425 
    426   DCHECK(IsRangeListSorted(ranges_));
    427   DCHECK(OnlySelectedRangeIsSeeked());
    428   DVLOG(1) << __FUNCTION__ << " : done";
    429 }
    430 
    431 void SourceBufferStream::ResetSeekState() {
    432   SetSelectedRange(NULL);
    433   track_buffer_.clear();
    434   config_change_pending_ = false;
    435   last_output_buffer_timestamp_ = kNoDecodeTimestamp();
    436   splice_buffers_index_ = 0;
    437   pending_buffer_ = NULL;
    438   pending_buffers_complete_ = false;
    439 }
    440 
    441 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
    442     base::TimeDelta seek_timestamp) const {
    443   if (ranges_.empty())
    444     return false;
    445   base::TimeDelta beginning_of_buffered =
    446       ranges_.front()->GetStartTimestamp().ToPresentationTime();
    447   return (seek_timestamp <= beginning_of_buffered &&
    448           beginning_of_buffered < kSeekToStartFudgeRoom());
    449 }
    450 
    451 bool SourceBufferStream::IsMonotonicallyIncreasing(
    452     const BufferQueue& buffers) const {
    453   DCHECK(!buffers.empty());
    454   DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
    455   bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
    456   for (BufferQueue::const_iterator itr = buffers.begin();
    457        itr != buffers.end(); ++itr) {
    458     DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp();
    459     bool current_is_keyframe = (*itr)->IsKeyframe();
    460     DCHECK(current_timestamp != kNoDecodeTimestamp());
    461     DCHECK((*itr)->duration() >= base::TimeDelta())
    462         << "Packet with invalid duration."
    463         << " pts " << (*itr)->timestamp().InSecondsF()
    464         << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF()
    465         << " dur " << (*itr)->duration().InSecondsF();
    466 
    467     if (prev_timestamp != kNoDecodeTimestamp()) {
    468       if (current_timestamp < prev_timestamp) {
    469         MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing.";
    470         return false;
    471       }
    472 
    473       if (current_timestamp == prev_timestamp &&
    474           !SourceBufferRange::AllowSameTimestamp(prev_is_keyframe,
    475                                                  current_is_keyframe)) {
    476         MEDIA_LOG(log_cb_) << "Unexpected combination of buffers with the"
    477                            << " same timestamp detected at "
    478                            << current_timestamp.InSecondsF();
    479         return false;
    480       }
    481     }
    482 
    483     prev_timestamp = current_timestamp;
    484     prev_is_keyframe = current_is_keyframe;
    485   }
    486   return true;
    487 }
    488 
    489 bool SourceBufferStream::IsNextTimestampValid(
    490     DecodeTimestamp next_timestamp, bool next_is_keyframe) const {
    491   return (last_appended_buffer_timestamp_ != next_timestamp) ||
    492       new_media_segment_ ||
    493       SourceBufferRange::AllowSameTimestamp(last_appended_buffer_is_keyframe_,
    494                                             next_is_keyframe);
    495 }
    496 
    497 
    498 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const {
    499   for (RangeList::const_iterator itr = ranges_.begin();
    500        itr != ranges_.end(); ++itr) {
    501     if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_)
    502       return false;
    503   }
    504   return !selected_range_ || selected_range_->HasNextBufferPosition();
    505 }
    506 
    507 void SourceBufferStream::UpdateMaxInterbufferDistance(
    508     const BufferQueue& buffers) {
    509   DCHECK(!buffers.empty());
    510   DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
    511   for (BufferQueue::const_iterator itr = buffers.begin();
    512        itr != buffers.end(); ++itr) {
    513     DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp();
    514     DCHECK(current_timestamp != kNoDecodeTimestamp());
    515 
    516     base::TimeDelta interbuffer_distance = (*itr)->duration();
    517     DCHECK(interbuffer_distance >= base::TimeDelta());
    518 
    519     if (prev_timestamp != kNoDecodeTimestamp()) {
    520       interbuffer_distance =
    521           std::max(current_timestamp - prev_timestamp, interbuffer_distance);
    522     }
    523 
    524     if (interbuffer_distance > base::TimeDelta()) {
    525       if (max_interbuffer_distance_ == kNoTimestamp()) {
    526         max_interbuffer_distance_ = interbuffer_distance;
    527       } else {
    528         max_interbuffer_distance_ =
    529             std::max(max_interbuffer_distance_, interbuffer_distance);
    530       }
    531     }
    532     prev_timestamp = current_timestamp;
    533   }
    534 }
    535 
    536 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) {
    537   for (BufferQueue::const_iterator itr = buffers.begin();
    538        itr != buffers.end(); ++itr) {
    539     (*itr)->SetConfigId(append_config_index_);
    540   }
    541 }
    542 
    543 void SourceBufferStream::GarbageCollectIfNeeded() {
    544   // Compute size of |ranges_|.
    545   int ranges_size = 0;
    546   for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr)
    547     ranges_size += (*itr)->size_in_bytes();
    548 
    549   // Return if we're under or at the memory limit.
    550   if (ranges_size <= memory_limit_)
    551     return;
    552 
    553   int bytes_to_free = ranges_size - memory_limit_;
    554 
    555   // Begin deleting after the last appended buffer.
    556   int bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free);
    557 
    558   // Begin deleting from the front.
    559   if (bytes_to_free - bytes_freed > 0)
    560     bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false);
    561 
    562   // Begin deleting from the back.
    563   if (bytes_to_free - bytes_freed > 0)
    564     FreeBuffers(bytes_to_free - bytes_freed, true);
    565 }
    566 
    567 int SourceBufferStream::FreeBuffersAfterLastAppended(int total_bytes_to_free) {
    568   DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
    569   if (last_appended_buffer_timestamp_ == kNoDecodeTimestamp() ||
    570       next_buffer_timestamp == kNoDecodeTimestamp() ||
    571       last_appended_buffer_timestamp_ >= next_buffer_timestamp) {
    572     return 0;
    573   }
    574 
    575   DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_;
    576   if (last_appended_buffer_is_keyframe_)
    577     remove_range_start += GetMaxInterbufferDistance();
    578 
    579   DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp(
    580       remove_range_start);
    581   if (remove_range_start_keyframe != kNoDecodeTimestamp())
    582     remove_range_start = remove_range_start_keyframe;
    583   if (remove_range_start >= next_buffer_timestamp)
    584     return 0;
    585 
    586   DecodeTimestamp remove_range_end;
    587   int bytes_freed = GetRemovalRange(
    588       remove_range_start, next_buffer_timestamp, total_bytes_to_free,
    589       &remove_range_end);
    590   if (bytes_freed > 0) {
    591     Remove(remove_range_start.ToPresentationTime(),
    592            remove_range_end.ToPresentationTime(),
    593            next_buffer_timestamp.ToPresentationTime());
    594   }
    595 
    596   return bytes_freed;
    597 }
    598 
    599 int SourceBufferStream::GetRemovalRange(
    600     DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp,
    601     int total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) {
    602   DCHECK(start_timestamp >= DecodeTimestamp()) << start_timestamp.InSecondsF();
    603   DCHECK(start_timestamp < end_timestamp)
    604       << "start " << start_timestamp.InSecondsF()
    605       << ", end " << end_timestamp.InSecondsF();
    606 
    607   int bytes_to_free = total_bytes_to_free;
    608   int bytes_freed = 0;
    609 
    610   for (RangeList::iterator itr = ranges_.begin();
    611        itr != ranges_.end() && bytes_to_free > 0; ++itr) {
    612     SourceBufferRange* range = *itr;
    613     if (range->GetStartTimestamp() >= end_timestamp)
    614       break;
    615     if (range->GetEndTimestamp() < start_timestamp)
    616       continue;
    617 
    618     int bytes_removed = range->GetRemovalGOP(
    619         start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp);
    620     bytes_to_free -= bytes_removed;
    621     bytes_freed += bytes_removed;
    622   }
    623   return bytes_freed;
    624 }
    625 
    626 int SourceBufferStream::FreeBuffers(int total_bytes_to_free,
    627                                     bool reverse_direction) {
    628   TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers",
    629                "total bytes to free", total_bytes_to_free,
    630                "reverse direction", reverse_direction);
    631 
    632   DCHECK_GT(total_bytes_to_free, 0);
    633   int bytes_to_free = total_bytes_to_free;
    634   int bytes_freed = 0;
    635 
    636   // This range will save the last GOP appended to |range_for_next_append_|
    637   // if the buffers surrounding it get deleted during garbage collection.
    638   SourceBufferRange* new_range_for_append = NULL;
    639 
    640   while (!ranges_.empty() && bytes_to_free > 0) {
    641     SourceBufferRange* current_range = NULL;
    642     BufferQueue buffers;
    643     int bytes_deleted = 0;
    644 
    645     if (reverse_direction) {
    646       current_range = ranges_.back();
    647       if (current_range->LastGOPContainsNextBufferPosition()) {
    648         DCHECK_EQ(current_range, selected_range_);
    649         break;
    650       }
    651       bytes_deleted = current_range->DeleteGOPFromBack(&buffers);
    652     } else {
    653       current_range = ranges_.front();
    654       if (current_range->FirstGOPContainsNextBufferPosition()) {
    655         DCHECK_EQ(current_range, selected_range_);
    656         break;
    657       }
    658       bytes_deleted = current_range->DeleteGOPFromFront(&buffers);
    659     }
    660 
    661     // Check to see if we've just deleted the GOP that was last appended.
    662     DecodeTimestamp end_timestamp = buffers.back()->GetDecodeTimestamp();
    663     if (end_timestamp == last_appended_buffer_timestamp_) {
    664       DCHECK(last_appended_buffer_timestamp_ != kNoDecodeTimestamp());
    665       DCHECK(!new_range_for_append);
    666       // Create a new range containing these buffers.
    667       new_range_for_append = new SourceBufferRange(
    668           TypeToGapPolicy(GetType()),
    669           buffers, kNoDecodeTimestamp(),
    670           base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
    671                      base::Unretained(this)));
    672       range_for_next_append_ = ranges_.end();
    673     } else {
    674       bytes_to_free -= bytes_deleted;
    675       bytes_freed += bytes_deleted;
    676     }
    677 
    678     if (current_range->size_in_bytes() == 0) {
    679       DCHECK_NE(current_range, selected_range_);
    680       DCHECK(range_for_next_append_ == ranges_.end() ||
    681              *range_for_next_append_ != current_range);
    682       delete current_range;
    683       reverse_direction ? ranges_.pop_back() : ranges_.pop_front();
    684     }
    685   }
    686 
    687   // Insert |new_range_for_append| into |ranges_|, if applicable.
    688   if (new_range_for_append) {
    689     range_for_next_append_ = AddToRanges(new_range_for_append);
    690     DCHECK(range_for_next_append_ != ranges_.end());
    691 
    692     // Check to see if we need to merge |new_range_for_append| with the range
    693     // before or after it. |new_range_for_append| is created whenever the last
    694     // GOP appended is encountered, regardless of whether any buffers after it
    695     // are ultimately deleted. Merging is necessary if there were no buffers
    696     // (or very few buffers) deleted after creating |new_range_for_append|.
    697     if (range_for_next_append_ != ranges_.begin()) {
    698       RangeList::iterator range_before_next = range_for_next_append_;
    699       --range_before_next;
    700       MergeWithAdjacentRangeIfNecessary(range_before_next);
    701     }
    702     MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
    703   }
    704   return bytes_freed;
    705 }
    706 
    707 void SourceBufferStream::PrepareRangesForNextAppend(
    708     const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
    709   DCHECK(deleted_buffers);
    710 
    711   bool temporarily_select_range = false;
    712   if (!track_buffer_.empty()) {
    713     DecodeTimestamp tb_timestamp = track_buffer_.back()->GetDecodeTimestamp();
    714     DecodeTimestamp seek_timestamp = FindKeyframeAfterTimestamp(tb_timestamp);
    715     if (seek_timestamp != kNoDecodeTimestamp() &&
    716         seek_timestamp < new_buffers.front()->GetDecodeTimestamp() &&
    717         range_for_next_append_ != ranges_.end() &&
    718         (*range_for_next_append_)->BelongsToRange(seek_timestamp)) {
    719       DCHECK(tb_timestamp < seek_timestamp);
    720       DCHECK(!selected_range_);
    721       DCHECK(!(*range_for_next_append_)->HasNextBufferPosition());
    722 
    723       // If there are GOPs between the end of the track buffer and the
    724       // beginning of the new buffers, then temporarily seek the range
    725       // so that the buffers between these two times will be deposited in
    726       // |deleted_buffers| as if they were part of the current playback
    727       // position.
    728       // TODO(acolwell): Figure out a more elegant way to do this.
    729       SeekAndSetSelectedRange(*range_for_next_append_, seek_timestamp);
    730       temporarily_select_range = true;
    731     }
    732   }
    733 
    734   // Handle splices between the existing buffers and the new buffers.  If a
    735   // splice is generated the timestamp and duration of the first buffer in
    736   // |new_buffers| will be modified.
    737   if (splice_frames_enabled_)
    738     GenerateSpliceFrame(new_buffers);
    739 
    740   DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
    741   bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
    742   DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp();
    743   bool next_is_keyframe = new_buffers.front()->IsKeyframe();
    744 
    745   if (prev_timestamp != kNoDecodeTimestamp() &&
    746       prev_timestamp != next_timestamp) {
    747     // Clean up the old buffers between the last appended buffer and the
    748     // beginning of |new_buffers|.
    749     RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers);
    750   }
    751 
    752   // Make the delete range exclusive if we are dealing with an allowed same
    753   // timestamp situation. This prevents the first buffer in the current append
    754   // from deleting the last buffer in the previous append if both buffers
    755   // have the same timestamp.
    756   //
    757   // The delete range should never be exclusive if a splice frame was generated
    758   // because we don't generate splice frames for same timestamp situations.
    759   DCHECK(new_buffers.front()->splice_timestamp() !=
    760          new_buffers.front()->timestamp());
    761   const bool is_exclusive =
    762       new_buffers.front()->splice_buffers().empty() &&
    763       prev_timestamp == next_timestamp &&
    764       SourceBufferRange::AllowSameTimestamp(prev_is_keyframe, next_is_keyframe);
    765 
    766   // Delete the buffers that |new_buffers| overlaps.
    767   DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp();
    768   DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp();
    769   base::TimeDelta duration = new_buffers.back()->duration();
    770 
    771   if (duration != kNoTimestamp() && duration > base::TimeDelta()) {
    772     end += duration;
    773   } else {
    774     // TODO(acolwell): Ensure all buffers actually have proper
    775     // duration info so that this hack isn't needed.
    776     // http://crbug.com/312836
    777     end += base::TimeDelta::FromInternalValue(1);
    778   }
    779 
    780   RemoveInternal(start, end, is_exclusive, deleted_buffers);
    781 
    782   // Restore the range seek state if necessary.
    783   if (temporarily_select_range)
    784     SetSelectedRange(NULL);
    785 }
    786 
    787 bool SourceBufferStream::AreAdjacentInSequence(
    788     DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const {
    789   return first_timestamp < second_timestamp &&
    790       second_timestamp <=
    791       first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
    792 }
    793 
    794 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) {
    795   // If we don't have the next timestamp, we don't have anything to delete.
    796   if (timestamp == kNoDecodeTimestamp())
    797     return;
    798 
    799   while (!track_buffer_.empty() &&
    800          track_buffer_.back()->GetDecodeTimestamp() >= timestamp) {
    801     track_buffer_.pop_back();
    802   }
    803 }
    804 
    805 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary(
    806     const RangeList::iterator& range_with_new_buffers_itr) {
    807   DCHECK(range_with_new_buffers_itr != ranges_.end());
    808 
    809   SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
    810   RangeList::iterator next_range_itr = range_with_new_buffers_itr;
    811   ++next_range_itr;
    812 
    813   if (next_range_itr == ranges_.end() ||
    814       !range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) {
    815     return;
    816   }
    817 
    818   bool transfer_current_position = selected_range_ == *next_range_itr;
    819   range_with_new_buffers->AppendRangeToEnd(**next_range_itr,
    820                                            transfer_current_position);
    821   // Update |selected_range_| pointer if |range| has become selected after
    822   // merges.
    823   if (transfer_current_position)
    824     SetSelectedRange(range_with_new_buffers);
    825 
    826   if (next_range_itr == range_for_next_append_)
    827     range_for_next_append_ = range_with_new_buffers_itr;
    828 
    829   DeleteAndRemoveRange(&next_range_itr);
    830 }
    831 
    832 void SourceBufferStream::Seek(base::TimeDelta timestamp) {
    833   DCHECK(timestamp >= base::TimeDelta());
    834   ResetSeekState();
    835 
    836   if (ShouldSeekToStartOfBuffered(timestamp)) {
    837     ranges_.front()->SeekToStart();
    838     SetSelectedRange(ranges_.front());
    839     seek_pending_ = false;
    840     return;
    841   }
    842 
    843   seek_buffer_timestamp_ = timestamp;
    844   seek_pending_ = true;
    845 
    846   DecodeTimestamp seek_dts = DecodeTimestamp::FromPresentationTime(timestamp);
    847 
    848   RangeList::iterator itr = ranges_.end();
    849   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
    850     if ((*itr)->CanSeekTo(seek_dts))
    851       break;
    852   }
    853 
    854   if (itr == ranges_.end())
    855     return;
    856 
    857   SeekAndSetSelectedRange(*itr, seek_dts);
    858   seek_pending_ = false;
    859 }
    860 
    861 bool SourceBufferStream::IsSeekPending() const {
    862   return !(end_of_stream_ && IsEndSelected()) && seek_pending_;
    863 }
    864 
    865 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
    866   DecodeTimestamp duration_dts =
    867       DecodeTimestamp::FromPresentationTime(duration);
    868 
    869   RangeList::iterator itr = ranges_.end();
    870   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
    871     if ((*itr)->GetEndTimestamp() > duration_dts)
    872       break;
    873   }
    874   if (itr == ranges_.end())
    875     return;
    876 
    877   // Need to partially truncate this range.
    878   if ((*itr)->GetStartTimestamp() < duration_dts) {
    879     bool delete_range = (*itr)->TruncateAt(duration_dts, NULL, false);
    880     if ((*itr == selected_range_) && !selected_range_->HasNextBufferPosition())
    881       SetSelectedRange(NULL);
    882 
    883     if (delete_range) {
    884       DeleteAndRemoveRange(&itr);
    885     } else {
    886       ++itr;
    887     }
    888   }
    889 
    890   // Delete all ranges that begin after |duration_dts|.
    891   while (itr != ranges_.end()) {
    892     // If we're about to delete the selected range, also reset the seek state.
    893     DCHECK((*itr)->GetStartTimestamp() >= duration_dts);
    894     if (*itr == selected_range_)
    895       ResetSeekState();
    896     DeleteAndRemoveRange(&itr);
    897   }
    898 }
    899 
    900 SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
    901     scoped_refptr<StreamParserBuffer>* out_buffer) {
    902   if (!pending_buffer_.get()) {
    903     const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer);
    904     if (status != SourceBufferStream::kSuccess || !SetPendingBuffer(out_buffer))
    905       return status;
    906   }
    907 
    908   if (!pending_buffer_->splice_buffers().empty())
    909     return HandleNextBufferWithSplice(out_buffer);
    910 
    911   DCHECK(pending_buffer_->preroll_buffer().get());
    912   return HandleNextBufferWithPreroll(out_buffer);
    913 }
    914 
    915 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice(
    916     scoped_refptr<StreamParserBuffer>* out_buffer) {
    917   const BufferQueue& splice_buffers = pending_buffer_->splice_buffers();
    918   const size_t last_splice_buffer_index = splice_buffers.size() - 1;
    919 
    920   // Are there any splice buffers left to hand out?  The last buffer should be
    921   // handed out separately since it represents the first post-splice buffer.
    922   if (splice_buffers_index_ < last_splice_buffer_index) {
    923     // Account for config changes which occur between fade out buffers.
    924     if (current_config_index_ !=
    925         splice_buffers[splice_buffers_index_]->GetConfigId()) {
    926       config_change_pending_ = true;
    927       DVLOG(1) << "Config change (splice buffer config ID does not match).";
    928       return SourceBufferStream::kConfigChange;
    929     }
    930 
    931     // Every pre splice buffer must have the same splice_timestamp().
    932     DCHECK(pending_buffer_->splice_timestamp() ==
    933            splice_buffers[splice_buffers_index_]->splice_timestamp());
    934 
    935     // No pre splice buffers should have preroll.
    936     DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer().get());
    937 
    938     *out_buffer = splice_buffers[splice_buffers_index_++];
    939     return SourceBufferStream::kSuccess;
    940   }
    941 
    942   // Did we hand out the last pre-splice buffer on the previous call?
    943   if (!pending_buffers_complete_) {
    944     DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index);
    945     pending_buffers_complete_ = true;
    946     config_change_pending_ = true;
    947     DVLOG(1) << "Config change (forced for fade in of splice frame).";
    948     return SourceBufferStream::kConfigChange;
    949   }
    950 
    951   // All pre-splice buffers have been handed out and a config change completed,
    952   // so hand out the final buffer for fade in.  Because a config change is
    953   // always issued prior to handing out this buffer, any changes in config id
    954   // have been inherently handled.
    955   DCHECK(pending_buffers_complete_);
    956   DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1);
    957   DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp());
    958   *out_buffer = splice_buffers.back();
    959   pending_buffer_ = NULL;
    960 
    961   // If the last splice buffer has preroll, hand off to the preroll handler.
    962   return SetPendingBuffer(out_buffer) ? HandleNextBufferWithPreroll(out_buffer)
    963                                       : SourceBufferStream::kSuccess;
    964 }
    965 
    966 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll(
    967     scoped_refptr<StreamParserBuffer>* out_buffer) {
    968   // Any config change should have already been handled.
    969   DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId());
    970 
    971   // Check if the preroll buffer has already been handed out.
    972   if (!pending_buffers_complete_) {
    973     pending_buffers_complete_ = true;
    974     *out_buffer = pending_buffer_->preroll_buffer();
    975     return SourceBufferStream::kSuccess;
    976   }
    977 
    978   // Preroll complete, hand out the final buffer.
    979   *out_buffer = pending_buffer_;
    980   pending_buffer_ = NULL;
    981   return SourceBufferStream::kSuccess;
    982 }
    983 
    984 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal(
    985     scoped_refptr<StreamParserBuffer>* out_buffer) {
    986   CHECK(!config_change_pending_);
    987 
    988   if (!track_buffer_.empty()) {
    989     DCHECK(!selected_range_);
    990     scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front();
    991 
    992     // If the next buffer is an audio splice frame, the next effective config id
    993     // comes from the first splice buffer.
    994     if (next_buffer->GetSpliceBufferConfigId(0) != current_config_index_) {
    995       config_change_pending_ = true;
    996       DVLOG(1) << "Config change (track buffer config ID does not match).";
    997       return kConfigChange;
    998     }
    999 
   1000     *out_buffer = next_buffer;
   1001     track_buffer_.pop_front();
   1002     last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
   1003 
   1004     // If the track buffer becomes empty, then try to set the selected range
   1005     // based on the timestamp of this buffer being returned.
   1006     if (track_buffer_.empty())
   1007       SetSelectedRangeIfNeeded(last_output_buffer_timestamp_);
   1008 
   1009     return kSuccess;
   1010   }
   1011 
   1012   if (!selected_range_ || !selected_range_->HasNextBuffer()) {
   1013     if (end_of_stream_ && IsEndSelected())
   1014       return kEndOfStream;
   1015     return kNeedBuffer;
   1016   }
   1017 
   1018   if (selected_range_->GetNextConfigId() != current_config_index_) {
   1019     config_change_pending_ = true;
   1020     DVLOG(1) << "Config change (selected range config ID does not match).";
   1021     return kConfigChange;
   1022   }
   1023 
   1024   CHECK(selected_range_->GetNextBuffer(out_buffer));
   1025   last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
   1026   return kSuccess;
   1027 }
   1028 
   1029 DecodeTimestamp SourceBufferStream::GetNextBufferTimestamp() {
   1030   if (!track_buffer_.empty())
   1031     return track_buffer_.front()->GetDecodeTimestamp();
   1032 
   1033   if (!selected_range_)
   1034     return kNoDecodeTimestamp();
   1035 
   1036   DCHECK(selected_range_->HasNextBufferPosition());
   1037   return selected_range_->GetNextTimestamp();
   1038 }
   1039 
   1040 SourceBufferStream::RangeList::iterator
   1041 SourceBufferStream::FindExistingRangeFor(DecodeTimestamp start_timestamp) {
   1042   for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
   1043     if ((*itr)->BelongsToRange(start_timestamp))
   1044       return itr;
   1045   }
   1046   return ranges_.end();
   1047 }
   1048 
   1049 SourceBufferStream::RangeList::iterator
   1050 SourceBufferStream::AddToRanges(SourceBufferRange* new_range) {
   1051   DecodeTimestamp start_timestamp = new_range->GetStartTimestamp();
   1052   RangeList::iterator itr = ranges_.end();
   1053   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
   1054     if ((*itr)->GetStartTimestamp() > start_timestamp)
   1055       break;
   1056   }
   1057   return ranges_.insert(itr, new_range);
   1058 }
   1059 
   1060 SourceBufferStream::RangeList::iterator
   1061 SourceBufferStream::GetSelectedRangeItr() {
   1062   DCHECK(selected_range_);
   1063   RangeList::iterator itr = ranges_.end();
   1064   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
   1065     if (*itr == selected_range_)
   1066       break;
   1067   }
   1068   DCHECK(itr != ranges_.end());
   1069   return itr;
   1070 }
   1071 
   1072 void SourceBufferStream::SeekAndSetSelectedRange(
   1073     SourceBufferRange* range, DecodeTimestamp seek_timestamp) {
   1074   if (range)
   1075     range->Seek(seek_timestamp);
   1076   SetSelectedRange(range);
   1077 }
   1078 
   1079 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) {
   1080   DVLOG(1) << __FUNCTION__ << " : " << selected_range_ << " -> " << range;
   1081   if (selected_range_)
   1082     selected_range_->ResetNextBufferPosition();
   1083   DCHECK(!range || range->HasNextBufferPosition());
   1084   selected_range_ = range;
   1085 }
   1086 
   1087 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const {
   1088   Ranges<base::TimeDelta> ranges;
   1089   for (RangeList::const_iterator itr = ranges_.begin();
   1090        itr != ranges_.end(); ++itr) {
   1091     ranges.Add((*itr)->GetStartTimestamp().ToPresentationTime(),
   1092                (*itr)->GetBufferedEndTimestamp().ToPresentationTime());
   1093   }
   1094   return ranges;
   1095 }
   1096 
   1097 base::TimeDelta SourceBufferStream::GetBufferedDuration() const {
   1098   if (ranges_.empty())
   1099     return base::TimeDelta();
   1100 
   1101   return ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime();
   1102 }
   1103 
   1104 void SourceBufferStream::MarkEndOfStream() {
   1105   DCHECK(!end_of_stream_);
   1106   end_of_stream_ = true;
   1107 }
   1108 
   1109 void SourceBufferStream::UnmarkEndOfStream() {
   1110   DCHECK(end_of_stream_);
   1111   end_of_stream_ = false;
   1112 }
   1113 
   1114 bool SourceBufferStream::IsEndSelected() const {
   1115   if (ranges_.empty())
   1116     return true;
   1117 
   1118   if (seek_pending_) {
   1119     base::TimeDelta last_range_end_time =
   1120         ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime();
   1121     return seek_buffer_timestamp_ >= last_range_end_time;
   1122   }
   1123 
   1124   return selected_range_ == ranges_.back();
   1125 }
   1126 
   1127 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() {
   1128   if (config_change_pending_)
   1129     CompleteConfigChange();
   1130   return audio_configs_[current_config_index_];
   1131 }
   1132 
   1133 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() {
   1134   if (config_change_pending_)
   1135     CompleteConfigChange();
   1136   return video_configs_[current_config_index_];
   1137 }
   1138 
   1139 const TextTrackConfig& SourceBufferStream::GetCurrentTextTrackConfig() {
   1140   return text_track_config_;
   1141 }
   1142 
   1143 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const {
   1144   if (max_interbuffer_distance_ == kNoTimestamp())
   1145     return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs);
   1146   return max_interbuffer_distance_;
   1147 }
   1148 
   1149 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
   1150   DCHECK(!audio_configs_.empty());
   1151   DCHECK(video_configs_.empty());
   1152   DVLOG(3) << "UpdateAudioConfig.";
   1153 
   1154   if (audio_configs_[0].codec() != config.codec()) {
   1155     MEDIA_LOG(log_cb_) << "Audio codec changes not allowed.";
   1156     return false;
   1157   }
   1158 
   1159   if (audio_configs_[0].is_encrypted() != config.is_encrypted()) {
   1160     MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed.";
   1161     return false;
   1162   }
   1163 
   1164   // Check to see if the new config matches an existing one.
   1165   for (size_t i = 0; i < audio_configs_.size(); ++i) {
   1166     if (config.Matches(audio_configs_[i])) {
   1167       append_config_index_ = i;
   1168       return true;
   1169     }
   1170   }
   1171 
   1172   // No matches found so let's add this one to the list.
   1173   append_config_index_ = audio_configs_.size();
   1174   DVLOG(2) << "New audio config - index: " << append_config_index_;
   1175   audio_configs_.resize(audio_configs_.size() + 1);
   1176   audio_configs_[append_config_index_] = config;
   1177   return true;
   1178 }
   1179 
   1180 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) {
   1181   DCHECK(!video_configs_.empty());
   1182   DCHECK(audio_configs_.empty());
   1183   DVLOG(3) << "UpdateVideoConfig.";
   1184 
   1185   if (video_configs_[0].codec() != config.codec()) {
   1186     MEDIA_LOG(log_cb_) << "Video codec changes not allowed.";
   1187     return false;
   1188   }
   1189 
   1190   if (video_configs_[0].is_encrypted() != config.is_encrypted()) {
   1191     MEDIA_LOG(log_cb_) << "Video encryption changes not allowed.";
   1192     return false;
   1193   }
   1194 
   1195   // Check to see if the new config matches an existing one.
   1196   for (size_t i = 0; i < video_configs_.size(); ++i) {
   1197     if (config.Matches(video_configs_[i])) {
   1198       append_config_index_ = i;
   1199       return true;
   1200     }
   1201   }
   1202 
   1203   // No matches found so let's add this one to the list.
   1204   append_config_index_ = video_configs_.size();
   1205   DVLOG(2) << "New video config - index: " << append_config_index_;
   1206   video_configs_.resize(video_configs_.size() + 1);
   1207   video_configs_[append_config_index_] = config;
   1208   return true;
   1209 }
   1210 
   1211 void SourceBufferStream::CompleteConfigChange() {
   1212   config_change_pending_ = false;
   1213 
   1214   if (pending_buffer_.get()) {
   1215     current_config_index_ =
   1216         pending_buffer_->GetSpliceBufferConfigId(splice_buffers_index_);
   1217     return;
   1218   }
   1219 
   1220   if (!track_buffer_.empty()) {
   1221     current_config_index_ = track_buffer_.front()->GetSpliceBufferConfigId(0);
   1222     return;
   1223   }
   1224 
   1225   if (selected_range_ && selected_range_->HasNextBuffer())
   1226     current_config_index_ = selected_range_->GetNextConfigId();
   1227 }
   1228 
   1229 void SourceBufferStream::SetSelectedRangeIfNeeded(
   1230     const DecodeTimestamp timestamp) {
   1231   DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")";
   1232 
   1233   if (selected_range_) {
   1234     DCHECK(track_buffer_.empty());
   1235     return;
   1236   }
   1237 
   1238   if (!track_buffer_.empty()) {
   1239     DCHECK(!selected_range_);
   1240     return;
   1241   }
   1242 
   1243   DecodeTimestamp start_timestamp = timestamp;
   1244 
   1245   // If the next buffer timestamp is not known then use a timestamp just after
   1246   // the timestamp on the last buffer returned by GetNextBuffer().
   1247   if (start_timestamp == kNoDecodeTimestamp()) {
   1248     if (last_output_buffer_timestamp_ == kNoDecodeTimestamp())
   1249       return;
   1250 
   1251     start_timestamp = last_output_buffer_timestamp_ +
   1252         base::TimeDelta::FromInternalValue(1);
   1253   }
   1254 
   1255   DecodeTimestamp seek_timestamp =
   1256       FindNewSelectedRangeSeekTimestamp(start_timestamp);
   1257 
   1258   // If we don't have buffered data to seek to, then return.
   1259   if (seek_timestamp == kNoDecodeTimestamp())
   1260     return;
   1261 
   1262   DCHECK(track_buffer_.empty());
   1263   SeekAndSetSelectedRange(*FindExistingRangeFor(seek_timestamp),
   1264                           seek_timestamp);
   1265 }
   1266 
   1267 DecodeTimestamp SourceBufferStream::FindNewSelectedRangeSeekTimestamp(
   1268     const DecodeTimestamp start_timestamp) {
   1269   DCHECK(start_timestamp != kNoDecodeTimestamp());
   1270   DCHECK(start_timestamp >= DecodeTimestamp());
   1271 
   1272   RangeList::iterator itr = ranges_.begin();
   1273 
   1274   for (; itr != ranges_.end(); ++itr) {
   1275     if ((*itr)->GetEndTimestamp() >= start_timestamp) {
   1276       break;
   1277     }
   1278   }
   1279 
   1280   if (itr == ranges_.end())
   1281     return kNoDecodeTimestamp();
   1282 
   1283   // First check for a keyframe timestamp >= |start_timestamp|
   1284   // in the current range.
   1285   DecodeTimestamp keyframe_timestamp =
   1286       (*itr)->NextKeyframeTimestamp(start_timestamp);
   1287 
   1288   if (keyframe_timestamp != kNoDecodeTimestamp())
   1289     return keyframe_timestamp;
   1290 
   1291   // If a keyframe was not found then look for a keyframe that is
   1292   // "close enough" in the current or next range.
   1293   DecodeTimestamp end_timestamp =
   1294       start_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
   1295   DCHECK(start_timestamp < end_timestamp);
   1296 
   1297   // Make sure the current range doesn't start beyond |end_timestamp|.
   1298   if ((*itr)->GetStartTimestamp() >= end_timestamp)
   1299     return kNoDecodeTimestamp();
   1300 
   1301   keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp);
   1302 
   1303   // Check to see if the keyframe is within the acceptable range
   1304   // (|start_timestamp|, |end_timestamp|].
   1305   if (keyframe_timestamp != kNoDecodeTimestamp() &&
   1306       start_timestamp < keyframe_timestamp  &&
   1307       keyframe_timestamp <= end_timestamp) {
   1308     return keyframe_timestamp;
   1309   }
   1310 
   1311   // If |end_timestamp| is within this range, then no other checks are
   1312   // necessary.
   1313   if (end_timestamp <= (*itr)->GetEndTimestamp())
   1314     return kNoDecodeTimestamp();
   1315 
   1316   // Move on to the next range.
   1317   ++itr;
   1318 
   1319   // Return early if the next range does not contain |end_timestamp|.
   1320   if (itr == ranges_.end() || (*itr)->GetStartTimestamp() >= end_timestamp)
   1321     return kNoDecodeTimestamp();
   1322 
   1323   keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp);
   1324 
   1325   // Check to see if the keyframe is within the acceptable range
   1326   // (|start_timestamp|, |end_timestamp|].
   1327   if (keyframe_timestamp != kNoDecodeTimestamp() &&
   1328       start_timestamp < keyframe_timestamp  &&
   1329       keyframe_timestamp <= end_timestamp) {
   1330     return keyframe_timestamp;
   1331   }
   1332 
   1333   return kNoDecodeTimestamp();
   1334 }
   1335 
   1336 DecodeTimestamp SourceBufferStream::FindKeyframeAfterTimestamp(
   1337     const DecodeTimestamp timestamp) {
   1338   DCHECK(timestamp != kNoDecodeTimestamp());
   1339 
   1340   RangeList::iterator itr = FindExistingRangeFor(timestamp);
   1341 
   1342   if (itr == ranges_.end())
   1343     return kNoDecodeTimestamp();
   1344 
   1345   // First check for a keyframe timestamp >= |timestamp|
   1346   // in the current range.
   1347   return (*itr)->NextKeyframeTimestamp(timestamp);
   1348 }
   1349 
   1350 std::string SourceBufferStream::GetStreamTypeName() const {
   1351   switch (GetType()) {
   1352     case kAudio:
   1353       return "AUDIO";
   1354     case kVideo:
   1355       return "VIDEO";
   1356     case kText:
   1357       return "TEXT";
   1358   }
   1359   NOTREACHED();
   1360   return "";
   1361 }
   1362 
   1363 SourceBufferStream::Type SourceBufferStream::GetType() const {
   1364   if (!audio_configs_.empty())
   1365     return kAudio;
   1366   if (!video_configs_.empty())
   1367     return kVideo;
   1368   DCHECK_NE(text_track_config_.kind(), kTextNone);
   1369   return kText;
   1370 }
   1371 
   1372 void SourceBufferStream::DeleteAndRemoveRange(RangeList::iterator* itr) {
   1373   DVLOG(1) << __FUNCTION__;
   1374 
   1375   DCHECK(*itr != ranges_.end());
   1376   if (**itr == selected_range_) {
   1377     DVLOG(1) << __FUNCTION__ << " deleting selected range.";
   1378     SetSelectedRange(NULL);
   1379   }
   1380 
   1381   if (*itr == range_for_next_append_) {
   1382     DVLOG(1) << __FUNCTION__ << " deleting range_for_next_append_.";
   1383     range_for_next_append_ = ranges_.end();
   1384     last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
   1385     last_appended_buffer_is_keyframe_ = false;
   1386   }
   1387 
   1388   delete **itr;
   1389   *itr = ranges_.erase(*itr);
   1390 }
   1391 
   1392 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) {
   1393   DCHECK(!new_buffers.empty());
   1394 
   1395   // Splice frames are only supported for audio.
   1396   if (GetType() != kAudio)
   1397     return;
   1398 
   1399   // Find the overlapped range (if any).
   1400   const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
   1401   const DecodeTimestamp splice_dts =
   1402       DecodeTimestamp::FromPresentationTime(splice_timestamp);
   1403   RangeList::iterator range_itr = FindExistingRangeFor(splice_dts);
   1404   if (range_itr == ranges_.end())
   1405     return;
   1406 
   1407   const DecodeTimestamp max_splice_end_dts =
   1408       splice_dts + base::TimeDelta::FromMilliseconds(
   1409           AudioSplicer::kCrossfadeDurationInMilliseconds);
   1410 
   1411   // Find all buffers involved before the splice point.
   1412   BufferQueue pre_splice_buffers;
   1413   if (!(*range_itr)->GetBuffersInRange(
   1414           splice_dts, max_splice_end_dts, &pre_splice_buffers)) {
   1415     return;
   1416   }
   1417 
   1418   // If there are gaps in the timeline, it's possible that we only find buffers
   1419   // after the splice point but within the splice range.  For simplicity, we do
   1420   // not generate splice frames in this case.
   1421   //
   1422   // We also do not want to generate splices if the first new buffer replaces an
   1423   // existing buffer exactly.
   1424   if (pre_splice_buffers.front()->timestamp() >= splice_timestamp)
   1425     return;
   1426 
   1427   // If any |pre_splice_buffers| are already splices or preroll, do not generate
   1428   // a splice.
   1429   for (size_t i = 0; i < pre_splice_buffers.size(); ++i) {
   1430     const BufferQueue& original_splice_buffers =
   1431         pre_splice_buffers[i]->splice_buffers();
   1432     if (!original_splice_buffers.empty()) {
   1433       DVLOG(1) << "Can't generate splice: overlapped buffers contain a "
   1434                   "pre-existing splice.";
   1435       return;
   1436     }
   1437 
   1438     if (pre_splice_buffers[i]->preroll_buffer().get()) {
   1439       DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll.";
   1440       return;
   1441     }
   1442   }
   1443 
   1444   // Don't generate splice frames which represent less than two frames, since we
   1445   // need at least that much to generate a crossfade.  Per the spec, make this
   1446   // check using the sample rate of the overlapping buffers.
   1447   const base::TimeDelta splice_duration =
   1448       pre_splice_buffers.back()->timestamp() +
   1449       pre_splice_buffers.back()->duration() - splice_timestamp;
   1450   const base::TimeDelta minimum_splice_duration = base::TimeDelta::FromSecondsD(
   1451       2.0 / audio_configs_[append_config_index_].samples_per_second());
   1452   if (splice_duration < minimum_splice_duration) {
   1453     DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have "
   1454              << splice_duration.InMicroseconds() << " us, but need "
   1455              << minimum_splice_duration.InMicroseconds() << " us.";
   1456     return;
   1457   }
   1458 
   1459   new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers);
   1460 }
   1461 
   1462 bool SourceBufferStream::SetPendingBuffer(
   1463     scoped_refptr<StreamParserBuffer>* out_buffer) {
   1464   DCHECK(out_buffer->get());
   1465   DCHECK(!pending_buffer_.get());
   1466 
   1467   const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty();
   1468   const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer().get();
   1469 
   1470   if (!have_splice_buffers && !have_preroll_buffer)
   1471     return false;
   1472 
   1473   DCHECK_NE(have_splice_buffers, have_preroll_buffer);
   1474   splice_buffers_index_ = 0;
   1475   pending_buffer_.swap(*out_buffer);
   1476   pending_buffers_complete_ = false;
   1477   return true;
   1478 }
   1479 
   1480 }  // namespace media
   1481