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 
     14 namespace media {
     15 // Helper class representing a range of buffered data. All buffers in a
     16 // SourceBufferRange are ordered sequentially in presentation order with no
     17 // gaps.
     18 class SourceBufferRange {
     19  public:
     20   typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
     21 
     22   // Returns the maximum distance in time between any buffer seen in this
     23   // stream. Used to estimate the duration of a buffer if its duration is not
     24   // known.
     25   typedef base::Callback<base::TimeDelta()> InterbufferDistanceCB;
     26 
     27   // Creates a source buffer range with |new_buffers|. |new_buffers| cannot be
     28   // empty and the front of |new_buffers| must be a keyframe.
     29   // |media_segment_start_time| refers to the starting timestamp for the media
     30   // segment to which these buffers belong.
     31   SourceBufferRange(const BufferQueue& new_buffers,
     32                     base::TimeDelta media_segment_start_time,
     33                     const InterbufferDistanceCB& interbuffer_distance_cb);
     34 
     35   // Appends |buffers| to the end of the range and updates |keyframe_map_| as
     36   // it encounters new keyframes. Assumes |buffers| belongs at the end of the
     37   // range.
     38   void AppendBuffersToEnd(const BufferQueue& buffers);
     39   bool CanAppendBuffersToEnd(const BufferQueue& buffers) const;
     40 
     41   // Appends the buffers from |range| into this range.
     42   // The first buffer in |range| must come directly after the last buffer
     43   // in this range.
     44   // If |transfer_current_position| is true, |range|'s |next_buffer_index_|
     45   // is transfered to this SourceBufferRange.
     46   void AppendRangeToEnd(const SourceBufferRange& range,
     47                         bool transfer_current_position);
     48   bool CanAppendRangeToEnd(const SourceBufferRange& range) const;
     49 
     50   // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|.
     51   // Assumes |timestamp| is valid and in this range.
     52   void Seek(base::TimeDelta timestamp);
     53 
     54   // Updates |next_buffer_index_| to point to next keyframe after or equal to
     55   // |timestamp|.
     56   void SeekAheadTo(base::TimeDelta timestamp);
     57 
     58   // Updates |next_buffer_index_| to point to next keyframe strictly after
     59   // |timestamp|.
     60   void SeekAheadPast(base::TimeDelta timestamp);
     61 
     62   // Seeks to the beginning of the range.
     63   void SeekToStart();
     64 
     65   // Finds the next keyframe from |buffers_| after |timestamp| (or at
     66   // |timestamp| if |is_exclusive| is false) and creates and returns a new
     67   // SourceBufferRange with the buffers from that keyframe onward.
     68   // The buffers in the new SourceBufferRange are moved out of this range. If
     69   // there is no keyframe after |timestamp|, SplitRange() returns null and this
     70   // range is unmodified.
     71   SourceBufferRange* SplitRange(base::TimeDelta timestamp, bool is_exclusive);
     72 
     73   // Deletes the buffers from this range starting at |timestamp|, exclusive if
     74   // |is_exclusive| is true, inclusive otherwise.
     75   // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was
     76   // deleted, and deletes the |keyframe_map_| entries for the buffers that
     77   // were removed.
     78   // |deleted_buffers| contains the buffers that were deleted from this range,
     79   // starting at the buffer that had been at |next_buffer_index_|.
     80   void TruncateAt(base::TimeDelta timestamp,
     81                   BufferQueue* deleted_buffers, bool is_exclusive);
     82   // Deletes all buffers in range.
     83   void DeleteAll(BufferQueue* deleted_buffers);
     84 
     85   // Deletes a GOP from the front or back of the range and moves these
     86   // buffers into |deleted_buffers|. Returns the number of bytes deleted from
     87   // the range (i.e. the size in bytes of |deleted_buffers|).
     88   int DeleteGOPFromFront(BufferQueue* deleted_buffers);
     89   int DeleteGOPFromBack(BufferQueue* deleted_buffers);
     90 
     91   // Indicates whether the GOP at the beginning or end of the range contains the
     92   // next buffer position.
     93   bool FirstGOPContainsNextBufferPosition() const;
     94   bool LastGOPContainsNextBufferPosition() const;
     95 
     96   // Updates |out_buffer| with the next buffer in presentation order. Seek()
     97   // must be called before calls to GetNextBuffer(), and buffers are returned
     98   // in order from the last call to Seek(). Returns true if |out_buffer| is
     99   // filled with a valid buffer, false if there is not enough data to fulfill
    100   // the request.
    101   bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer);
    102   bool HasNextBuffer() const;
    103 
    104   // Returns the config ID for the buffer that will be returned by
    105   // GetNextBuffer().
    106   int GetNextConfigId() const;
    107 
    108   // Returns true if the range knows the position of the next buffer it should
    109   // return, i.e. it has been Seek()ed. This does not necessarily mean that it
    110   // has the next buffer yet.
    111   bool HasNextBufferPosition() const;
    112 
    113   // Resets this range to an "unseeked" state.
    114   void ResetNextBufferPosition();
    115 
    116   // Returns the timestamp of the next buffer that will be returned from
    117   // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown.
    118   base::TimeDelta GetNextTimestamp() const;
    119 
    120   // Returns the start timestamp of the range.
    121   base::TimeDelta GetStartTimestamp() const;
    122 
    123   // Returns the timestamp of the last buffer in the range.
    124   base::TimeDelta GetEndTimestamp() const;
    125 
    126   // Returns the timestamp for the end of the buffered region in this range.
    127   // This is an approximation if the duration for the last buffer in the range
    128   // is unset.
    129   base::TimeDelta GetBufferedEndTimestamp() const;
    130 
    131   // Gets the timestamp for the keyframe that is after |timestamp|. If
    132   // there isn't a keyframe in the range after |timestamp| then kNoTimestamp()
    133   // is returned.
    134   base::TimeDelta NextKeyframeTimestamp(base::TimeDelta timestamp);
    135 
    136   // Gets the timestamp for the closest keyframe that is <= |timestamp|. If
    137   // there isn't a keyframe before |timestamp| or |timestamp| is outside
    138   // this range, then kNoTimestamp() is returned.
    139   base::TimeDelta KeyframeBeforeTimestamp(base::TimeDelta timestamp);
    140 
    141   // Returns whether a buffer with a starting timestamp of |timestamp| would
    142   // belong in this range. This includes a buffer that would be appended to
    143   // the end of the range.
    144   bool BelongsToRange(base::TimeDelta timestamp) const;
    145 
    146   // Returns true if the range has enough data to seek to the specified
    147   // |timestamp|, false otherwise.
    148   bool CanSeekTo(base::TimeDelta timestamp) const;
    149 
    150   // Returns true if this range's buffered timespan completely overlaps the
    151   // buffered timespan of |range|.
    152   bool CompletelyOverlaps(const SourceBufferRange& range) const;
    153 
    154   // Returns true if the end of this range contains buffers that overlaps with
    155   // the beginning of |range|.
    156   bool EndOverlaps(const SourceBufferRange& range) const;
    157 
    158   // Returns true if |timestamp| is the timestamp of the next buffer in
    159   // sequence after |buffer|, false otherwise.
    160   bool IsNextInSequence(
    161       const scoped_refptr<media::StreamParserBuffer>& buffer,
    162       base::TimeDelta timestamp) const;
    163 
    164   int size_in_bytes() const { return size_in_bytes_; }
    165 
    166  private:
    167   typedef std::map<base::TimeDelta, int> KeyframeMap;
    168 
    169   // Seeks the range to the next keyframe after |timestamp|. If
    170   // |skip_given_timestamp| is true, the seek will go to a keyframe with a
    171   // timestamp strictly greater than |timestamp|.
    172   void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp);
    173 
    174   // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|.
    175   // If |skip_given_timestamp| is true, this returns the first buffer with
    176   // timestamp greater than |timestamp|.
    177   BufferQueue::iterator GetBufferItrAt(
    178       base::TimeDelta timestamp, bool skip_given_timestamp);
    179 
    180   // Returns an iterator in |keyframe_map_| pointing to the next keyframe after
    181   // |timestamp|. If |skip_given_timestamp| is true, this returns the first
    182   // keyframe with a timestamp strictly greater than |timestamp|.
    183   KeyframeMap::iterator GetFirstKeyframeAt(
    184       base::TimeDelta timestamp, bool skip_given_timestamp);
    185 
    186   // Returns an iterator in |keyframe_map_| pointing to the first keyframe
    187   // before or at |timestamp|.
    188   KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp);
    189 
    190   // Helper method to delete buffers in |buffers_| starting at
    191   // |starting_point|, an iterator in |buffers_|.
    192   void TruncateAt(const BufferQueue::iterator& starting_point,
    193                   BufferQueue* deleted_buffers);
    194 
    195   // Frees the buffers in |buffers_| from [|start_point|,|ending_point|) and
    196   // updates the |size_in_bytes_| accordingly. Does not update |keyframe_map_|.
    197   void FreeBufferRange(const BufferQueue::iterator& starting_point,
    198                        const BufferQueue::iterator& ending_point);
    199 
    200   // Returns the distance in time estimating how far from the beginning or end
    201   // of this range a buffer can be to considered in the range.
    202   base::TimeDelta GetFudgeRoom() const;
    203 
    204   // Returns the approximate duration of a buffer in this range.
    205   base::TimeDelta GetApproximateDuration() const;
    206 
    207   // An ordered list of buffers in this range.
    208   BufferQueue buffers_;
    209 
    210   // Maps keyframe timestamps to its index position in |buffers_|.
    211   KeyframeMap keyframe_map_;
    212 
    213   // Index base of all positions in |keyframe_map_|. In other words, the
    214   // real position of entry |k| of |keyframe_map_| in the range is:
    215   //   keyframe_map_[k] - keyframe_map_index_base_
    216   int keyframe_map_index_base_;
    217 
    218   // Index into |buffers_| for the next buffer to be returned by
    219   // GetNextBuffer(), set to -1 before Seek().
    220   int next_buffer_index_;
    221 
    222   // If the first buffer in this range is the beginning of a media segment,
    223   // |media_segment_start_time_| is the time when the media segment begins.
    224   // |media_segment_start_time_| may be <= the timestamp of the first buffer in
    225   // |buffers_|. |media_segment_start_time_| is kNoTimestamp() if this range
    226   // does not start at the beginning of a media segment, which can only happen
    227   // garbage collection or after an end overlap that results in a split range
    228   // (we don't have a way of knowing the media segment timestamp for the new
    229   // range).
    230   base::TimeDelta media_segment_start_time_;
    231 
    232   // Called to get the largest interbuffer distance seen so far in the stream.
    233   InterbufferDistanceCB interbuffer_distance_cb_;
    234 
    235   // Stores the amount of memory taken up by the data in |buffers_|.
    236   int size_in_bytes_;
    237 
    238   DISALLOW_COPY_AND_ASSIGN(SourceBufferRange);
    239 };
    240 
    241 }  // namespace media
    242 
    243 // Helper method that returns true if |ranges| is sorted in increasing order,
    244 // false otherwise.
    245 static bool IsRangeListSorted(
    246     const std::list<media::SourceBufferRange*>& ranges) {
    247   base::TimeDelta prev = media::kNoTimestamp();
    248   for (std::list<media::SourceBufferRange*>::const_iterator itr =
    249        ranges.begin(); itr != ranges.end(); ++itr) {
    250     if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp())
    251       return false;
    252     prev = (*itr)->GetEndTimestamp();
    253   }
    254   return true;
    255 }
    256 
    257 // Comparison function for two Buffers based on timestamp.
    258 static bool BufferComparator(
    259     const scoped_refptr<media::StreamParserBuffer>& first,
    260     const scoped_refptr<media::StreamParserBuffer>& second) {
    261   return first->GetDecodeTimestamp() < second->GetDecodeTimestamp();
    262 }
    263 
    264 // Returns an estimate of how far from the beginning or end of a range a buffer
    265 // can be to still be considered in the range, given the |approximate_duration|
    266 // of a buffer in the stream.
    267 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) {
    268   // Because we do not know exactly when is the next timestamp, any buffer
    269   // that starts within 2x the approximate duration of a buffer is considered
    270   // within this range.
    271   return 2 * approximate_duration;
    272 }
    273 
    274 // An arbitrarily-chosen number to estimate the duration of a buffer if none
    275 // is set and there's not enough information to get a better estimate.
    276 static int kDefaultBufferDurationInMs = 125;
    277 
    278 // The amount of time the beginning of the buffered data can differ from the
    279 // start time in order to still be considered the start of stream.
    280 static base::TimeDelta kSeekToStartFudgeRoom() {
    281   return base::TimeDelta::FromMilliseconds(1000);
    282 }
    283 // The maximum amount of data in bytes the stream will keep in memory.
    284 #if defined(GOOGLE_TV)
    285 // In Google TV, set the size of the buffer to 1 min because of
    286 // the limited memory of the embedded system.
    287 // 2MB: approximately 1 minutes of 256Kbps content.
    288 // 30MB: approximately 1 minutes of 4Mbps content.
    289 static int kDefaultAudioMemoryLimit = 2 * 1024 * 1024;
    290 static int kDefaultVideoMemoryLimit = 30 * 1024 * 1024;
    291 #else
    292 // 12MB: approximately 5 minutes of 320Kbps content.
    293 // 150MB: approximately 5 minutes of 4Mbps content.
    294 static int kDefaultAudioMemoryLimit = 12 * 1024 * 1024;
    295 static int kDefaultVideoMemoryLimit = 150 * 1024 * 1024;
    296 #endif
    297 
    298 namespace media {
    299 
    300 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
    301                                        const LogCB& log_cb)
    302     : log_cb_(log_cb),
    303       current_config_index_(0),
    304       append_config_index_(0),
    305       seek_pending_(false),
    306       end_of_stream_(false),
    307       seek_buffer_timestamp_(kNoTimestamp()),
    308       selected_range_(NULL),
    309       media_segment_start_time_(kNoTimestamp()),
    310       range_for_next_append_(ranges_.end()),
    311       new_media_segment_(false),
    312       last_appended_buffer_timestamp_(kNoTimestamp()),
    313       last_appended_buffer_is_keyframe_(false),
    314       last_output_buffer_timestamp_(kNoTimestamp()),
    315       max_interbuffer_distance_(kNoTimestamp()),
    316       memory_limit_(kDefaultAudioMemoryLimit),
    317       config_change_pending_(false) {
    318   DCHECK(audio_config.IsValidConfig());
    319   audio_configs_.push_back(audio_config);
    320 }
    321 
    322 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
    323                                        const LogCB& log_cb)
    324     : log_cb_(log_cb),
    325       current_config_index_(0),
    326       append_config_index_(0),
    327       seek_pending_(false),
    328       end_of_stream_(false),
    329       seek_buffer_timestamp_(kNoTimestamp()),
    330       selected_range_(NULL),
    331       media_segment_start_time_(kNoTimestamp()),
    332       range_for_next_append_(ranges_.end()),
    333       new_media_segment_(false),
    334       last_appended_buffer_timestamp_(kNoTimestamp()),
    335       last_appended_buffer_is_keyframe_(false),
    336       last_output_buffer_timestamp_(kNoTimestamp()),
    337       max_interbuffer_distance_(kNoTimestamp()),
    338       memory_limit_(kDefaultVideoMemoryLimit),
    339       config_change_pending_(false) {
    340   DCHECK(video_config.IsValidConfig());
    341   video_configs_.push_back(video_config);
    342 }
    343 
    344 SourceBufferStream::~SourceBufferStream() {
    345   while (!ranges_.empty()) {
    346     delete ranges_.front();
    347     ranges_.pop_front();
    348   }
    349 }
    350 
    351 void SourceBufferStream::OnNewMediaSegment(
    352     base::TimeDelta media_segment_start_time) {
    353   DCHECK(!end_of_stream_);
    354   media_segment_start_time_ = media_segment_start_time;
    355   new_media_segment_ = true;
    356 
    357   RangeList::iterator last_range = range_for_next_append_;
    358   range_for_next_append_ = FindExistingRangeFor(media_segment_start_time);
    359 
    360   // Only reset |last_appended_buffer_timestamp_| if this new media segment is
    361   // not adjacent to the previous media segment appended to the stream.
    362   if (range_for_next_append_ == ranges_.end() ||
    363       !AreAdjacentInSequence(last_appended_buffer_timestamp_,
    364                              media_segment_start_time)) {
    365     last_appended_buffer_timestamp_ = kNoTimestamp();
    366     last_appended_buffer_is_keyframe_ = false;
    367   } else {
    368     DCHECK(last_range == range_for_next_append_);
    369   }
    370 }
    371 
    372 bool SourceBufferStream::Append(
    373     const SourceBufferStream::BufferQueue& buffers) {
    374   TRACE_EVENT2("mse", "SourceBufferStream::Append",
    375                "stream type", GetStreamTypeName(),
    376                "buffers to append", buffers.size());
    377 
    378   DCHECK(!buffers.empty());
    379   DCHECK(media_segment_start_time_ != kNoTimestamp());
    380   DCHECK(!end_of_stream_);
    381 
    382   // New media segments must begin with a keyframe.
    383   if (new_media_segment_ && !buffers.front()->IsKeyframe()) {
    384     MEDIA_LOG(log_cb_) << "Media segment did not begin with keyframe.";
    385     return false;
    386   }
    387 
    388   // Buffers within a media segment should be monotonically increasing.
    389   if (!IsMonotonicallyIncreasing(buffers))
    390     return false;
    391 
    392   if (media_segment_start_time_ < base::TimeDelta() ||
    393       buffers.front()->GetDecodeTimestamp() < base::TimeDelta()) {
    394     MEDIA_LOG(log_cb_)
    395         << "Cannot append a media segment with negative timestamps.";
    396     return false;
    397   }
    398 
    399   UpdateMaxInterbufferDistance(buffers);
    400   SetConfigIds(buffers);
    401 
    402   // Save a snapshot of stream state before range modifications are made.
    403   base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp();
    404   BufferQueue deleted_buffers;
    405 
    406   RangeList::iterator range_for_new_buffers = range_for_next_append_;
    407   // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
    408   // create a new range with |buffers|.
    409   if (range_for_new_buffers != ranges_.end()) {
    410     if (!InsertIntoExistingRange(range_for_new_buffers, buffers,
    411                                  &deleted_buffers)) {
    412       return false;
    413     }
    414   } else {
    415     DCHECK(new_media_segment_);
    416     range_for_new_buffers =
    417         AddToRanges(new SourceBufferRange(
    418             buffers, media_segment_start_time_,
    419             base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
    420                        base::Unretained(this))));
    421   }
    422 
    423   range_for_next_append_ = range_for_new_buffers;
    424   new_media_segment_ = false;
    425   last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
    426   last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe();
    427 
    428   // Resolve overlaps.
    429   ResolveCompleteOverlaps(range_for_new_buffers, &deleted_buffers);
    430   ResolveEndOverlap(range_for_new_buffers, &deleted_buffers);
    431   MergeWithAdjacentRangeIfNecessary(range_for_new_buffers);
    432 
    433   // Seek to try to fulfill a previous call to Seek().
    434   if (seek_pending_) {
    435     DCHECK(!selected_range_);
    436     DCHECK(deleted_buffers.empty());
    437     Seek(seek_buffer_timestamp_);
    438   }
    439 
    440   if (!deleted_buffers.empty()) {
    441     base::TimeDelta start_of_deleted =
    442         deleted_buffers.front()->GetDecodeTimestamp();
    443 
    444     DCHECK(track_buffer_.empty() ||
    445            track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted)
    446         << "decode timestamp "
    447         << track_buffer_.back()->GetDecodeTimestamp().InSecondsF() << " sec"
    448         << ", start_of_deleted " << start_of_deleted.InSecondsF()<< " sec";
    449 
    450     track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(),
    451                          deleted_buffers.end());
    452   }
    453 
    454   // Prune any extra buffers in |track_buffer_| if new keyframes
    455   // are appended to the range covered by |track_buffer_|.
    456   if (!track_buffer_.empty()) {
    457     base::TimeDelta keyframe_timestamp =
    458         FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp());
    459     if (keyframe_timestamp != kNoTimestamp())
    460       PruneTrackBuffer(keyframe_timestamp);
    461   }
    462 
    463   SetSelectedRangeIfNeeded(next_buffer_timestamp);
    464 
    465   GarbageCollectIfNeeded();
    466 
    467   DCHECK(IsRangeListSorted(ranges_));
    468   DCHECK(OnlySelectedRangeIsSeeked());
    469   return true;
    470 }
    471 
    472 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end,
    473                                 base::TimeDelta duration) {
    474   DCHECK(start >= base::TimeDelta()) << start.InSecondsF();
    475   DCHECK(start < end) << "start " << start.InSecondsF()
    476                       << " end " << end.InSecondsF();
    477   DCHECK(duration != kNoTimestamp());
    478 
    479   base::TimeDelta remove_end_timestamp = duration;
    480   base::TimeDelta keyframe_timestamp = FindKeyframeAfterTimestamp(end);
    481   if (keyframe_timestamp != kNoTimestamp()) {
    482     remove_end_timestamp = keyframe_timestamp;
    483   } else if (end < remove_end_timestamp) {
    484     remove_end_timestamp = end;
    485   }
    486 
    487   RangeList::iterator itr = ranges_.begin();
    488 
    489   while (itr != ranges_.end()) {
    490     SourceBufferRange* range = *itr;
    491     if (range->GetStartTimestamp() >= remove_end_timestamp)
    492       break;
    493 
    494     // Split off any remaining end piece and add it to |ranges_|.
    495     SourceBufferRange* new_range =
    496         range->SplitRange(remove_end_timestamp, false);
    497     if (new_range) {
    498       itr = ranges_.insert(++itr, new_range);
    499       --itr;
    500     }
    501 
    502     // If the current range now is completely covered by the removal
    503     // range then delete it and move on.
    504     if (start <= range->GetStartTimestamp()) {
    505       if (selected_range_ == range)
    506           SetSelectedRange(NULL);
    507 
    508         delete range;
    509         itr = ranges_.erase(itr);
    510         continue;
    511     }
    512 
    513     // Truncate the current range so that it only contains data before
    514     // the removal range.
    515     BufferQueue saved_buffers;
    516     range->TruncateAt(start, &saved_buffers, false);
    517 
    518     // Check to see if the current playback position was removed and
    519     // update the selected range appropriately.
    520     if (!saved_buffers.empty()) {
    521       SetSelectedRange(NULL);
    522       SetSelectedRangeIfNeeded(saved_buffers.front()->GetDecodeTimestamp());
    523     }
    524 
    525     // Move on to the next range.
    526     ++itr;
    527   }
    528 }
    529 
    530 void SourceBufferStream::ResetSeekState() {
    531   SetSelectedRange(NULL);
    532   track_buffer_.clear();
    533   config_change_pending_ = false;
    534   last_output_buffer_timestamp_ = kNoTimestamp();
    535 }
    536 
    537 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
    538     base::TimeDelta seek_timestamp) const {
    539   if (ranges_.empty())
    540     return false;
    541   base::TimeDelta beginning_of_buffered =
    542       ranges_.front()->GetStartTimestamp();
    543   return (seek_timestamp <= beginning_of_buffered &&
    544           beginning_of_buffered < kSeekToStartFudgeRoom());
    545 }
    546 
    547 // Buffers with the same timestamp are only allowed under certain conditions.
    548 // Video: Allowed when the previous frame and current frame are NOT keyframes.
    549 //        This is the situation for VP8 Alt-Ref frames.
    550 // Otherwise: Allowed in all situations except where a non-keyframe is followed
    551 //            by a keyframe.
    552 // Returns true if |prev_is_keyframe| and |current_is_keyframe| indicate a
    553 // same timestamp situation that is allowed. False is returned otherwise.
    554 bool SourceBufferStream::AllowSameTimestamp(
    555     bool prev_is_keyframe, bool current_is_keyframe) const {
    556   if (video_configs_.size() > 0)
    557     return !prev_is_keyframe && !current_is_keyframe;
    558 
    559   return prev_is_keyframe || !current_is_keyframe;
    560 }
    561 
    562 bool SourceBufferStream::IsMonotonicallyIncreasing(
    563     const BufferQueue& buffers) const {
    564   DCHECK(!buffers.empty());
    565   base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_;
    566   bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
    567   for (BufferQueue::const_iterator itr = buffers.begin();
    568        itr != buffers.end(); ++itr) {
    569     base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp();
    570     bool current_is_keyframe = (*itr)->IsKeyframe();
    571     DCHECK(current_timestamp != kNoTimestamp());
    572 
    573     if (prev_timestamp != kNoTimestamp()) {
    574       if (current_timestamp < prev_timestamp) {
    575         MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing.";
    576         return false;
    577       }
    578 
    579       if (current_timestamp == prev_timestamp &&
    580           !AllowSameTimestamp(prev_is_keyframe, current_is_keyframe)) {
    581         MEDIA_LOG(log_cb_) << "Unexpected combination of buffers with the"
    582                            << " same timestamp detected at "
    583                            << current_timestamp.InSecondsF();
    584         return false;
    585       }
    586     }
    587 
    588     prev_timestamp = current_timestamp;
    589     prev_is_keyframe = current_is_keyframe;
    590   }
    591   return true;
    592 }
    593 
    594 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const {
    595   for (RangeList::const_iterator itr = ranges_.begin();
    596        itr != ranges_.end(); ++itr) {
    597     if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_)
    598       return false;
    599   }
    600   return !selected_range_ || selected_range_->HasNextBufferPosition();
    601 }
    602 
    603 void SourceBufferStream::UpdateMaxInterbufferDistance(
    604     const BufferQueue& buffers) {
    605   DCHECK(!buffers.empty());
    606   base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_;
    607   for (BufferQueue::const_iterator itr = buffers.begin();
    608        itr != buffers.end(); ++itr) {
    609     base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp();
    610     DCHECK(current_timestamp != kNoTimestamp());
    611 
    612     if (prev_timestamp != kNoTimestamp()) {
    613       base::TimeDelta interbuffer_distance = current_timestamp - prev_timestamp;
    614       if (max_interbuffer_distance_ == kNoTimestamp()) {
    615         max_interbuffer_distance_ = interbuffer_distance;
    616       } else {
    617         max_interbuffer_distance_ =
    618             std::max(max_interbuffer_distance_, interbuffer_distance);
    619       }
    620     }
    621     prev_timestamp = current_timestamp;
    622   }
    623 }
    624 
    625 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) {
    626   for (BufferQueue::const_iterator itr = buffers.begin();
    627        itr != buffers.end(); ++itr) {
    628     (*itr)->SetConfigId(append_config_index_);
    629   }
    630 }
    631 
    632 void SourceBufferStream::GarbageCollectIfNeeded() {
    633   // Compute size of |ranges_|.
    634   int ranges_size = 0;
    635   for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr)
    636     ranges_size += (*itr)->size_in_bytes();
    637 
    638   // Return if we're under or at the memory limit.
    639   if (ranges_size <= memory_limit_)
    640     return;
    641 
    642   int bytes_to_free = ranges_size - memory_limit_;
    643 
    644   // Begin deleting from the front.
    645   int bytes_freed = FreeBuffers(bytes_to_free, false);
    646 
    647   // Begin deleting from the back.
    648   if (bytes_to_free - bytes_freed > 0)
    649     FreeBuffers(bytes_to_free - bytes_freed, true);
    650 }
    651 
    652 int SourceBufferStream::FreeBuffers(int total_bytes_to_free,
    653                                     bool reverse_direction) {
    654   TRACE_EVENT2("mse", "SourceBufferStream::FreeBuffers",
    655                "total bytes to free", total_bytes_to_free,
    656                "reverse direction", reverse_direction);
    657 
    658   DCHECK_GT(total_bytes_to_free, 0);
    659   int bytes_to_free = total_bytes_to_free;
    660   int bytes_freed = 0;
    661 
    662   // This range will save the last GOP appended to |range_for_next_append_|
    663   // if the buffers surrounding it get deleted during garbage collection.
    664   SourceBufferRange* new_range_for_append = NULL;
    665 
    666   while (!ranges_.empty() && bytes_to_free > 0) {
    667     SourceBufferRange* current_range = NULL;
    668     BufferQueue buffers;
    669     int bytes_deleted = 0;
    670 
    671     if (reverse_direction) {
    672       current_range = ranges_.back();
    673       if (current_range->LastGOPContainsNextBufferPosition()) {
    674         DCHECK_EQ(current_range, selected_range_);
    675         break;
    676       }
    677       bytes_deleted = current_range->DeleteGOPFromBack(&buffers);
    678     } else {
    679       current_range = ranges_.front();
    680       if (current_range->FirstGOPContainsNextBufferPosition()) {
    681         DCHECK_EQ(current_range, selected_range_);
    682         break;
    683       }
    684       bytes_deleted = current_range->DeleteGOPFromFront(&buffers);
    685     }
    686 
    687     // Check to see if we've just deleted the GOP that was last appended.
    688     base::TimeDelta end_timestamp = buffers.back()->GetDecodeTimestamp();
    689     if (end_timestamp == last_appended_buffer_timestamp_) {
    690       DCHECK(last_appended_buffer_timestamp_ != kNoTimestamp());
    691       DCHECK(!new_range_for_append);
    692       // Create a new range containing these buffers.
    693       new_range_for_append = new SourceBufferRange(
    694             buffers, kNoTimestamp(),
    695             base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
    696                        base::Unretained(this)));
    697       range_for_next_append_ = ranges_.end();
    698     } else {
    699       bytes_to_free -= bytes_deleted;
    700       bytes_freed += bytes_deleted;
    701     }
    702 
    703     if (current_range->size_in_bytes() == 0) {
    704       DCHECK_NE(current_range, selected_range_);
    705       DCHECK(range_for_next_append_ == ranges_.end() ||
    706              *range_for_next_append_ != current_range);
    707       delete current_range;
    708       reverse_direction ? ranges_.pop_back() : ranges_.pop_front();
    709     }
    710   }
    711 
    712   // Insert |new_range_for_append| into |ranges_|, if applicable.
    713   if (new_range_for_append) {
    714     range_for_next_append_ = AddToRanges(new_range_for_append);
    715     DCHECK(range_for_next_append_ != ranges_.end());
    716 
    717     // Check to see if we need to merge |new_range_for_append| with the range
    718     // before or after it. |new_range_for_append| is created whenever the last
    719     // GOP appended is encountered, regardless of whether any buffers after it
    720     // are ultimately deleted. Merging is necessary if there were no buffers
    721     // (or very few buffers) deleted after creating |new_range_for_append|.
    722     if (range_for_next_append_ != ranges_.begin()) {
    723       RangeList::iterator range_before_next = range_for_next_append_;
    724       --range_before_next;
    725       MergeWithAdjacentRangeIfNecessary(range_before_next);
    726     }
    727     MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
    728   }
    729   return bytes_freed;
    730 }
    731 
    732 bool SourceBufferStream::InsertIntoExistingRange(
    733     const RangeList::iterator& range_for_new_buffers_itr,
    734     const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
    735   DCHECK(deleted_buffers);
    736 
    737   SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr;
    738 
    739   bool temporarily_select_range = false;
    740   if (!track_buffer_.empty()) {
    741     base::TimeDelta tb_timestamp = track_buffer_.back()->GetDecodeTimestamp();
    742     base::TimeDelta seek_timestamp = FindKeyframeAfterTimestamp(tb_timestamp);
    743     if (seek_timestamp != kNoTimestamp() &&
    744         seek_timestamp < new_buffers.front()->GetDecodeTimestamp() &&
    745         range_for_new_buffers->BelongsToRange(seek_timestamp)) {
    746       DCHECK(tb_timestamp < seek_timestamp);
    747       DCHECK(!selected_range_);
    748       DCHECK(!range_for_new_buffers->HasNextBufferPosition());
    749 
    750       // If there are GOPs between the end of the track buffer and the
    751       // beginning of the new buffers, then temporarily seek the range
    752       // so that the buffers between these two times will be deposited in
    753       // |deleted_buffers| as if they were part of the current playback
    754       // position.
    755       // TODO(acolwell): Figure out a more elegant way to do this.
    756       SeekAndSetSelectedRange(range_for_new_buffers, seek_timestamp);
    757       temporarily_select_range = true;
    758     }
    759   }
    760 
    761   base::TimeDelta prev_timestamp = last_appended_buffer_timestamp_;
    762   bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
    763   base::TimeDelta next_timestamp = new_buffers.front()->GetDecodeTimestamp();
    764   bool next_is_keyframe = new_buffers.front()->IsKeyframe();
    765 
    766   if (prev_timestamp != kNoTimestamp() && prev_timestamp != next_timestamp) {
    767     // Clean up the old buffers between the last appended buffer and the
    768     // beginning of |new_buffers|.
    769     DeleteBetween(
    770         range_for_new_buffers_itr, prev_timestamp, next_timestamp, true,
    771         deleted_buffers);
    772   }
    773 
    774   bool is_exclusive = false;
    775   if (prev_timestamp == next_timestamp) {
    776     if (!new_media_segment_ &&
    777         !AllowSameTimestamp(prev_is_keyframe, next_is_keyframe)) {
    778       MEDIA_LOG(log_cb_) << "Invalid same timestamp construct detected at time "
    779                          << prev_timestamp.InSecondsF();
    780       return false;
    781     }
    782 
    783     // Make the delete range exclusive if we are dealing with an allowed same
    784     // timestamp situation so that the buffer with the same timestamp that is
    785     // already stored in |*range_for_new_buffers_itr| doesn't get deleted.
    786     is_exclusive = AllowSameTimestamp(prev_is_keyframe, next_is_keyframe);
    787   }
    788 
    789   // If we cannot append the |new_buffers| to the end of the existing range,
    790   // this is either a start overlap or a middle overlap. Delete the buffers
    791   // that |new_buffers| overlaps.
    792   if (!range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) {
    793     DeleteBetween(
    794         range_for_new_buffers_itr, new_buffers.front()->GetDecodeTimestamp(),
    795         new_buffers.back()->GetDecodeTimestamp(), is_exclusive,
    796         deleted_buffers);
    797   }
    798 
    799   // Restore the range seek state if necessary.
    800   if (temporarily_select_range)
    801     SetSelectedRange(NULL);
    802 
    803   range_for_new_buffers->AppendBuffersToEnd(new_buffers);
    804   return true;
    805 }
    806 
    807 void SourceBufferStream::DeleteBetween(
    808     const RangeList::iterator& range_itr, base::TimeDelta start_timestamp,
    809     base::TimeDelta end_timestamp, bool is_range_exclusive,
    810     BufferQueue* deleted_buffers) {
    811   SourceBufferRange* new_next_range =
    812       (*range_itr)->SplitRange(end_timestamp, is_range_exclusive);
    813 
    814   // Insert the |new_next_range| into |ranges_| after |range|.
    815   if (new_next_range) {
    816     RangeList::iterator next_range_itr = range_itr;
    817     ranges_.insert(++next_range_itr, new_next_range);
    818   }
    819 
    820   BufferQueue saved_buffers;
    821   (*range_itr)->TruncateAt(start_timestamp, &saved_buffers, is_range_exclusive);
    822 
    823   if (selected_range_ != *range_itr)
    824     return;
    825 
    826   DCHECK(deleted_buffers->empty());
    827   *deleted_buffers = saved_buffers;
    828 
    829   // If the next buffer position has transferred to the split range, set the
    830   // selected range accordingly.
    831   if (new_next_range && new_next_range->HasNextBufferPosition()) {
    832     DCHECK(!(*range_itr)->HasNextBufferPosition());
    833     SetSelectedRange(new_next_range);
    834   } else if (!selected_range_->HasNextBufferPosition()) {
    835     SetSelectedRange(NULL);
    836   }
    837 }
    838 
    839 bool SourceBufferStream::AreAdjacentInSequence(
    840     base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const {
    841   return first_timestamp < second_timestamp &&
    842       second_timestamp <=
    843       first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
    844 }
    845 
    846 void SourceBufferStream::ResolveCompleteOverlaps(
    847     const RangeList::iterator& range_with_new_buffers_itr,
    848     BufferQueue* deleted_buffers) {
    849   DCHECK(deleted_buffers);
    850 
    851   SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
    852   RangeList::iterator next_range_itr = range_with_new_buffers_itr;
    853   ++next_range_itr;
    854 
    855   while (next_range_itr != ranges_.end() &&
    856          range_with_new_buffers->CompletelyOverlaps(**next_range_itr)) {
    857     if (*next_range_itr == selected_range_) {
    858       DCHECK(deleted_buffers->empty());
    859       selected_range_->DeleteAll(deleted_buffers);
    860       SetSelectedRange(NULL);
    861     }
    862     delete *next_range_itr;
    863     next_range_itr = ranges_.erase(next_range_itr);
    864   }
    865 }
    866 
    867 void SourceBufferStream::ResolveEndOverlap(
    868     const RangeList::iterator& range_with_new_buffers_itr,
    869     BufferQueue* deleted_buffers) {
    870   DCHECK(deleted_buffers);
    871 
    872   SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
    873   RangeList::iterator next_range_itr = range_with_new_buffers_itr;
    874   ++next_range_itr;
    875 
    876   if (next_range_itr == ranges_.end() ||
    877       !range_with_new_buffers->EndOverlaps(**next_range_itr)) {
    878     return;
    879   }
    880 
    881   // Split the overlapped range after |range_with_new_buffers|'s last buffer
    882   // overlaps. Now |overlapped_range| contains only the buffers that do not
    883   // belong in |ranges_| anymore, and |new_next_range| contains buffers that
    884   // go after |range_with_new_buffers| (without overlap).
    885   scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr);
    886   next_range_itr = ranges_.erase(next_range_itr);
    887 
    888   SourceBufferRange* new_next_range =
    889       overlapped_range->SplitRange(
    890           range_with_new_buffers->GetEndTimestamp(), true);
    891 
    892   // If there were non-overlapped buffers, add the new range to |ranges_|.
    893   if (new_next_range)
    894     AddToRanges(new_next_range);
    895 
    896   // If we didn't overlap a selected range, return.
    897   if (selected_range_ != overlapped_range)
    898     return;
    899 
    900   // If the |overlapped_range| transfers its next buffer position to
    901   // |new_next_range|, make |new_next_range| the |selected_range_|.
    902   if (new_next_range && new_next_range->HasNextBufferPosition()) {
    903     DCHECK(!overlapped_range->HasNextBufferPosition());
    904     SetSelectedRange(new_next_range);
    905     return;
    906   }
    907 
    908   // Save the buffers in |overlapped_range|.
    909   DCHECK(deleted_buffers->empty());
    910   DCHECK_EQ(overlapped_range.get(), selected_range_);
    911   overlapped_range->DeleteAll(deleted_buffers);
    912 
    913   // |overlapped_range| will be deleted, so set |selected_range_| to NULL.
    914   SetSelectedRange(NULL);
    915 }
    916 
    917 void SourceBufferStream::PruneTrackBuffer(const base::TimeDelta timestamp) {
    918   // If we don't have the next timestamp, we don't have anything to delete.
    919   if (timestamp == kNoTimestamp())
    920     return;
    921 
    922   while (!track_buffer_.empty() &&
    923          track_buffer_.back()->GetDecodeTimestamp() >= timestamp) {
    924     track_buffer_.pop_back();
    925   }
    926 }
    927 
    928 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary(
    929     const RangeList::iterator& range_with_new_buffers_itr) {
    930   SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
    931   RangeList::iterator next_range_itr = range_with_new_buffers_itr;
    932   ++next_range_itr;
    933 
    934   if (next_range_itr != ranges_.end() &&
    935       range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) {
    936     bool transfer_current_position = selected_range_ == *next_range_itr;
    937     range_with_new_buffers->AppendRangeToEnd(**next_range_itr,
    938                                              transfer_current_position);
    939     // Update |selected_range_| pointer if |range| has become selected after
    940     // merges.
    941     if (transfer_current_position)
    942       SetSelectedRange(range_with_new_buffers);
    943 
    944     if (next_range_itr == range_for_next_append_)
    945       range_for_next_append_ = range_with_new_buffers_itr;
    946 
    947     delete *next_range_itr;
    948     ranges_.erase(next_range_itr);
    949   }
    950 }
    951 
    952 void SourceBufferStream::Seek(base::TimeDelta timestamp) {
    953   DCHECK(timestamp >= base::TimeDelta());
    954   ResetSeekState();
    955 
    956   if (ShouldSeekToStartOfBuffered(timestamp)) {
    957     ranges_.front()->SeekToStart();
    958     SetSelectedRange(ranges_.front());
    959     seek_pending_ = false;
    960     return;
    961   }
    962 
    963   seek_buffer_timestamp_ = timestamp;
    964   seek_pending_ = true;
    965 
    966   RangeList::iterator itr = ranges_.end();
    967   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
    968     if ((*itr)->CanSeekTo(timestamp))
    969       break;
    970   }
    971 
    972   if (itr == ranges_.end())
    973     return;
    974 
    975   SeekAndSetSelectedRange(*itr, timestamp);
    976   seek_pending_ = false;
    977 }
    978 
    979 bool SourceBufferStream::IsSeekPending() const {
    980   return !(end_of_stream_ && IsEndSelected()) && seek_pending_;
    981 }
    982 
    983 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
    984   RangeList::iterator itr = ranges_.end();
    985   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
    986     if ((*itr)->GetEndTimestamp() > duration)
    987       break;
    988   }
    989   if (itr == ranges_.end())
    990     return;
    991 
    992   // Need to partially truncate this range.
    993   if ((*itr)->GetStartTimestamp() < duration) {
    994     (*itr)->TruncateAt(duration, NULL, false);
    995     ++itr;
    996   }
    997 
    998   // Delete all ranges that begin after |duration|.
    999   while (itr != ranges_.end()) {
   1000     // If we're about to delete the selected range, also reset the seek state.
   1001     DCHECK((*itr)->GetStartTimestamp() >= duration);
   1002     if (*itr== selected_range_)
   1003       ResetSeekState();
   1004     delete *itr;
   1005     itr = ranges_.erase(itr);
   1006   }
   1007 }
   1008 
   1009 SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
   1010     scoped_refptr<StreamParserBuffer>* out_buffer) {
   1011   CHECK(!config_change_pending_);
   1012 
   1013   if (!track_buffer_.empty()) {
   1014     DCHECK(!selected_range_);
   1015     if (track_buffer_.front()->GetConfigId() != current_config_index_) {
   1016       config_change_pending_ = true;
   1017       DVLOG(1) << "Config change (track buffer config ID does not match).";
   1018       return kConfigChange;
   1019     }
   1020 
   1021     *out_buffer = track_buffer_.front();
   1022     track_buffer_.pop_front();
   1023     last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
   1024 
   1025     // If the track buffer becomes empty, then try to set the selected range
   1026     // based on the timestamp of this buffer being returned.
   1027     if (track_buffer_.empty())
   1028       SetSelectedRangeIfNeeded(last_output_buffer_timestamp_);
   1029 
   1030     return kSuccess;
   1031   }
   1032 
   1033   if (!selected_range_ || !selected_range_->HasNextBuffer()) {
   1034     if (end_of_stream_ && IsEndSelected())
   1035       return kEndOfStream;
   1036     return kNeedBuffer;
   1037   }
   1038 
   1039   if (selected_range_->GetNextConfigId() != current_config_index_) {
   1040     config_change_pending_ = true;
   1041     DVLOG(1) << "Config change (selected range config ID does not match).";
   1042     return kConfigChange;
   1043   }
   1044 
   1045   CHECK(selected_range_->GetNextBuffer(out_buffer));
   1046   last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
   1047   return kSuccess;
   1048 }
   1049 
   1050 base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() {
   1051   if (!track_buffer_.empty())
   1052     return track_buffer_.front()->GetDecodeTimestamp();
   1053 
   1054   if (!selected_range_)
   1055     return kNoTimestamp();
   1056 
   1057   DCHECK(selected_range_->HasNextBufferPosition());
   1058   return selected_range_->GetNextTimestamp();
   1059 }
   1060 
   1061 base::TimeDelta SourceBufferStream::GetEndBufferTimestamp() {
   1062   if (!selected_range_)
   1063     return kNoTimestamp();
   1064   return selected_range_->GetEndTimestamp();
   1065 }
   1066 
   1067 SourceBufferStream::RangeList::iterator
   1068 SourceBufferStream::FindExistingRangeFor(base::TimeDelta start_timestamp) {
   1069   for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
   1070     if ((*itr)->BelongsToRange(start_timestamp))
   1071       return itr;
   1072   }
   1073   return ranges_.end();
   1074 }
   1075 
   1076 SourceBufferStream::RangeList::iterator
   1077 SourceBufferStream::AddToRanges(SourceBufferRange* new_range) {
   1078   base::TimeDelta start_timestamp = new_range->GetStartTimestamp();
   1079   RangeList::iterator itr = ranges_.end();
   1080   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
   1081     if ((*itr)->GetStartTimestamp() > start_timestamp)
   1082       break;
   1083   }
   1084   return ranges_.insert(itr, new_range);
   1085 }
   1086 
   1087 SourceBufferStream::RangeList::iterator
   1088 SourceBufferStream::GetSelectedRangeItr() {
   1089   DCHECK(selected_range_);
   1090   RangeList::iterator itr = ranges_.end();
   1091   for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
   1092     if (*itr == selected_range_)
   1093       break;
   1094   }
   1095   DCHECK(itr != ranges_.end());
   1096   return itr;
   1097 }
   1098 
   1099 void SourceBufferStream::SeekAndSetSelectedRange(
   1100     SourceBufferRange* range, base::TimeDelta seek_timestamp) {
   1101   if (range)
   1102     range->Seek(seek_timestamp);
   1103   SetSelectedRange(range);
   1104 }
   1105 
   1106 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) {
   1107   if (selected_range_)
   1108     selected_range_->ResetNextBufferPosition();
   1109   DCHECK(!range || range->HasNextBufferPosition());
   1110   selected_range_ = range;
   1111 }
   1112 
   1113 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const {
   1114   Ranges<base::TimeDelta> ranges;
   1115   for (RangeList::const_iterator itr = ranges_.begin();
   1116        itr != ranges_.end(); ++itr) {
   1117     ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp());
   1118   }
   1119   return ranges;
   1120 }
   1121 
   1122 void SourceBufferStream::MarkEndOfStream() {
   1123   DCHECK(!end_of_stream_);
   1124   end_of_stream_ = true;
   1125 }
   1126 
   1127 void SourceBufferStream::UnmarkEndOfStream() {
   1128   DCHECK(end_of_stream_);
   1129   end_of_stream_ = false;
   1130 }
   1131 
   1132 bool SourceBufferStream::IsEndSelected() const {
   1133   if (ranges_.empty())
   1134     return true;
   1135 
   1136   if (seek_pending_)
   1137     return seek_buffer_timestamp_ >= ranges_.back()->GetBufferedEndTimestamp();
   1138 
   1139   return selected_range_ == ranges_.back();
   1140 }
   1141 
   1142 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() {
   1143   if (config_change_pending_)
   1144     CompleteConfigChange();
   1145   return audio_configs_[current_config_index_];
   1146 }
   1147 
   1148 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() {
   1149   if (config_change_pending_)
   1150     CompleteConfigChange();
   1151   return video_configs_[current_config_index_];
   1152 }
   1153 
   1154 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const {
   1155   if (max_interbuffer_distance_ == kNoTimestamp())
   1156     return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs);
   1157   return max_interbuffer_distance_;
   1158 }
   1159 
   1160 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
   1161   DCHECK(!audio_configs_.empty());
   1162   DCHECK(video_configs_.empty());
   1163   DVLOG(3) << "UpdateAudioConfig.";
   1164 
   1165   if (audio_configs_[0].codec() != config.codec()) {
   1166     MEDIA_LOG(log_cb_) << "Audio codec changes not allowed.";
   1167     return false;
   1168   }
   1169 
   1170   if (audio_configs_[0].samples_per_second() != config.samples_per_second()) {
   1171     MEDIA_LOG(log_cb_) << "Audio sample rate changes not allowed.";
   1172     return false;
   1173   }
   1174 
   1175   if (audio_configs_[0].channel_layout() != config.channel_layout()) {
   1176     MEDIA_LOG(log_cb_) << "Audio channel layout changes not allowed.";
   1177     return false;
   1178   }
   1179 
   1180   if (audio_configs_[0].bits_per_channel() != config.bits_per_channel()) {
   1181     MEDIA_LOG(log_cb_) << "Audio bits per channel changes not allowed.";
   1182     return false;
   1183   }
   1184 
   1185   if (audio_configs_[0].is_encrypted() != config.is_encrypted()) {
   1186     MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed.";
   1187     return false;
   1188   }
   1189 
   1190   // Check to see if the new config matches an existing one.
   1191   for (size_t i = 0; i < audio_configs_.size(); ++i) {
   1192     if (config.Matches(audio_configs_[i])) {
   1193       append_config_index_ = i;
   1194       return true;
   1195     }
   1196   }
   1197 
   1198   // No matches found so let's add this one to the list.
   1199   append_config_index_ = audio_configs_.size();
   1200   DVLOG(2) << "New audio config - index: " << append_config_index_;
   1201   audio_configs_.resize(audio_configs_.size() + 1);
   1202   audio_configs_[append_config_index_] = config;
   1203   return true;
   1204 }
   1205 
   1206 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) {
   1207   DCHECK(!video_configs_.empty());
   1208   DCHECK(audio_configs_.empty());
   1209   DVLOG(3) << "UpdateVideoConfig.";
   1210 
   1211   if (video_configs_[0].is_encrypted() != config.is_encrypted()) {
   1212     MEDIA_LOG(log_cb_) << "Video Encryption changes not allowed.";
   1213     return false;
   1214   }
   1215 
   1216   if (video_configs_[0].codec() != config.codec()) {
   1217     MEDIA_LOG(log_cb_) << "Video codec changes not allowed.";
   1218     return false;
   1219   }
   1220 
   1221   if (video_configs_[0].is_encrypted() != config.is_encrypted()) {
   1222     MEDIA_LOG(log_cb_) << "Video encryption changes not allowed.";
   1223     return false;
   1224   }
   1225 
   1226   // Check to see if the new config matches an existing one.
   1227   for (size_t i = 0; i < video_configs_.size(); ++i) {
   1228     if (config.Matches(video_configs_[i])) {
   1229       append_config_index_ = i;
   1230       return true;
   1231     }
   1232   }
   1233 
   1234   // No matches found so let's add this one to the list.
   1235   append_config_index_ = video_configs_.size();
   1236   DVLOG(2) << "New video config - index: " << append_config_index_;
   1237   video_configs_.resize(video_configs_.size() + 1);
   1238   video_configs_[append_config_index_] = config;
   1239   return true;
   1240 }
   1241 
   1242 void SourceBufferStream::CompleteConfigChange() {
   1243   config_change_pending_ = false;
   1244 
   1245   if (!track_buffer_.empty()) {
   1246     current_config_index_ = track_buffer_.front()->GetConfigId();
   1247     return;
   1248   }
   1249 
   1250   if (selected_range_ && selected_range_->HasNextBuffer())
   1251     current_config_index_ = selected_range_->GetNextConfigId();
   1252 }
   1253 
   1254 void SourceBufferStream::SetSelectedRangeIfNeeded(
   1255     const base::TimeDelta timestamp) {
   1256   if (selected_range_) {
   1257     DCHECK(track_buffer_.empty());
   1258     return;
   1259   }
   1260 
   1261   if (!track_buffer_.empty()) {
   1262     DCHECK(!selected_range_);
   1263     return;
   1264   }
   1265 
   1266   base::TimeDelta start_timestamp = timestamp;
   1267 
   1268   // If the next buffer timestamp is not known then use a timestamp just after
   1269   // the timestamp on the last buffer returned by GetNextBuffer().
   1270   if (start_timestamp == kNoTimestamp()) {
   1271     if (last_output_buffer_timestamp_ == kNoTimestamp())
   1272       return;
   1273 
   1274     start_timestamp = last_output_buffer_timestamp_ +
   1275         base::TimeDelta::FromInternalValue(1);
   1276   }
   1277 
   1278   base::TimeDelta seek_timestamp =
   1279       FindNewSelectedRangeSeekTimestamp(start_timestamp);
   1280 
   1281   // If we don't have buffered data to seek to, then return.
   1282   if (seek_timestamp == kNoTimestamp())
   1283     return;
   1284 
   1285   DCHECK(track_buffer_.empty());
   1286   SeekAndSetSelectedRange(*FindExistingRangeFor(seek_timestamp),
   1287                           seek_timestamp);
   1288 }
   1289 
   1290 base::TimeDelta SourceBufferStream::FindNewSelectedRangeSeekTimestamp(
   1291     const base::TimeDelta start_timestamp) {
   1292   DCHECK(start_timestamp != kNoTimestamp());
   1293   DCHECK(start_timestamp >= base::TimeDelta());
   1294 
   1295   RangeList::iterator itr = ranges_.begin();
   1296 
   1297   for (; itr != ranges_.end(); ++itr) {
   1298     if ((*itr)->GetEndTimestamp() >= start_timestamp) {
   1299       break;
   1300     }
   1301   }
   1302 
   1303   if (itr == ranges_.end())
   1304     return kNoTimestamp();
   1305 
   1306   // First check for a keyframe timestamp >= |start_timestamp|
   1307   // in the current range.
   1308   base::TimeDelta keyframe_timestamp =
   1309       (*itr)->NextKeyframeTimestamp(start_timestamp);
   1310 
   1311   if (keyframe_timestamp != kNoTimestamp())
   1312     return keyframe_timestamp;
   1313 
   1314   // If a keyframe was not found then look for a keyframe that is
   1315   // "close enough" in the current or next range.
   1316   base::TimeDelta end_timestamp =
   1317       start_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
   1318   DCHECK(start_timestamp < end_timestamp);
   1319 
   1320   // Make sure the current range doesn't start beyond |end_timestamp|.
   1321   if ((*itr)->GetStartTimestamp() >= end_timestamp)
   1322     return kNoTimestamp();
   1323 
   1324   keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp);
   1325 
   1326   // Check to see if the keyframe is within the acceptable range
   1327   // (|start_timestamp|, |end_timestamp|].
   1328   if (keyframe_timestamp != kNoTimestamp() &&
   1329       start_timestamp < keyframe_timestamp  &&
   1330       keyframe_timestamp <= end_timestamp) {
   1331     return keyframe_timestamp;
   1332   }
   1333 
   1334   // If |end_timestamp| is within this range, then no other checks are
   1335   // necessary.
   1336   if (end_timestamp <= (*itr)->GetEndTimestamp())
   1337     return kNoTimestamp();
   1338 
   1339   // Move on to the next range.
   1340   ++itr;
   1341 
   1342   // Return early if the next range does not contain |end_timestamp|.
   1343   if (itr == ranges_.end() || (*itr)->GetStartTimestamp() >= end_timestamp)
   1344     return kNoTimestamp();
   1345 
   1346   keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp);
   1347 
   1348   // Check to see if the keyframe is within the acceptable range
   1349   // (|start_timestamp|, |end_timestamp|].
   1350   if (keyframe_timestamp != kNoTimestamp() &&
   1351       start_timestamp < keyframe_timestamp  &&
   1352       keyframe_timestamp <= end_timestamp) {
   1353     return keyframe_timestamp;
   1354   }
   1355 
   1356   return kNoTimestamp();
   1357 }
   1358 
   1359 base::TimeDelta SourceBufferStream::FindKeyframeAfterTimestamp(
   1360     const base::TimeDelta timestamp) {
   1361   DCHECK(timestamp != kNoTimestamp());
   1362 
   1363   RangeList::iterator itr = FindExistingRangeFor(timestamp);
   1364 
   1365   if (itr == ranges_.end())
   1366     return kNoTimestamp();
   1367 
   1368   // First check for a keyframe timestamp >= |timestamp|
   1369   // in the current range.
   1370   return (*itr)->NextKeyframeTimestamp(timestamp);
   1371 }
   1372 
   1373 std::string SourceBufferStream::GetStreamTypeName() const {
   1374   if (!video_configs_.empty()) {
   1375     DCHECK(audio_configs_.empty());
   1376     return "VIDEO";
   1377   }
   1378 
   1379   DCHECK(!audio_configs_.empty());
   1380   return "AUDIO";
   1381 }
   1382 
   1383 SourceBufferRange::SourceBufferRange(
   1384     const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time,
   1385     const InterbufferDistanceCB& interbuffer_distance_cb)
   1386     : keyframe_map_index_base_(0),
   1387       next_buffer_index_(-1),
   1388       media_segment_start_time_(media_segment_start_time),
   1389       interbuffer_distance_cb_(interbuffer_distance_cb),
   1390       size_in_bytes_(0) {
   1391   DCHECK(!new_buffers.empty());
   1392   DCHECK(new_buffers.front()->IsKeyframe());
   1393   DCHECK(!interbuffer_distance_cb.is_null());
   1394   AppendBuffersToEnd(new_buffers);
   1395 }
   1396 
   1397 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) {
   1398   DCHECK(buffers_.empty() ||
   1399          buffers_.back()->GetDecodeTimestamp() <=
   1400          new_buffers.front()->GetDecodeTimestamp());
   1401 
   1402   for (BufferQueue::const_iterator itr = new_buffers.begin();
   1403        itr != new_buffers.end(); ++itr) {
   1404     DCHECK((*itr)->GetDecodeTimestamp() != kNoTimestamp());
   1405     buffers_.push_back(*itr);
   1406     size_in_bytes_ += (*itr)->data_size();
   1407 
   1408     if ((*itr)->IsKeyframe()) {
   1409       keyframe_map_.insert(
   1410           std::make_pair((*itr)->GetDecodeTimestamp(),
   1411                          buffers_.size() - 1 + keyframe_map_index_base_));
   1412     }
   1413   }
   1414 }
   1415 
   1416 void SourceBufferRange::Seek(base::TimeDelta timestamp) {
   1417   DCHECK(CanSeekTo(timestamp));
   1418   DCHECK(!keyframe_map_.empty());
   1419 
   1420   KeyframeMap::iterator result = GetFirstKeyframeBefore(timestamp);
   1421   next_buffer_index_ = result->second - keyframe_map_index_base_;
   1422   DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
   1423 }
   1424 
   1425 void SourceBufferRange::SeekAheadTo(base::TimeDelta timestamp) {
   1426   SeekAhead(timestamp, false);
   1427 }
   1428 
   1429 void SourceBufferRange::SeekAheadPast(base::TimeDelta timestamp) {
   1430   SeekAhead(timestamp, true);
   1431 }
   1432 
   1433 void SourceBufferRange::SeekAhead(base::TimeDelta timestamp,
   1434                                   bool skip_given_timestamp) {
   1435   DCHECK(!keyframe_map_.empty());
   1436 
   1437   KeyframeMap::iterator result =
   1438       GetFirstKeyframeAt(timestamp, skip_given_timestamp);
   1439 
   1440   // If there isn't a keyframe after |timestamp|, then seek to end and return
   1441   // kNoTimestamp to signal such.
   1442   if (result == keyframe_map_.end()) {
   1443     next_buffer_index_ = -1;
   1444     return;
   1445   }
   1446   next_buffer_index_ = result->second - keyframe_map_index_base_;
   1447   DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
   1448 }
   1449 
   1450 void SourceBufferRange::SeekToStart() {
   1451   DCHECK(!buffers_.empty());
   1452   next_buffer_index_ = 0;
   1453 }
   1454 
   1455 SourceBufferRange* SourceBufferRange::SplitRange(
   1456     base::TimeDelta timestamp, bool is_exclusive) {
   1457   // Find the first keyframe after |timestamp|. If |is_exclusive|, do not
   1458   // include keyframes at |timestamp|.
   1459   KeyframeMap::iterator new_beginning_keyframe =
   1460       GetFirstKeyframeAt(timestamp, is_exclusive);
   1461 
   1462   // If there is no keyframe after |timestamp|, we can't split the range.
   1463   if (new_beginning_keyframe == keyframe_map_.end())
   1464     return NULL;
   1465 
   1466   // Remove the data beginning at |keyframe_index| from |buffers_| and save it
   1467   // into |removed_buffers|.
   1468   int keyframe_index =
   1469       new_beginning_keyframe->second - keyframe_map_index_base_;
   1470   DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
   1471   BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
   1472   BufferQueue removed_buffers(starting_point, buffers_.end());
   1473   keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end());
   1474   FreeBufferRange(starting_point, buffers_.end());
   1475 
   1476   // Create a new range with |removed_buffers|.
   1477   SourceBufferRange* split_range =
   1478       new SourceBufferRange(
   1479           removed_buffers, kNoTimestamp(), interbuffer_distance_cb_);
   1480 
   1481   // If the next buffer position is now in |split_range|, update the state of
   1482   // this range and |split_range| accordingly.
   1483   if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
   1484     split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index;
   1485     ResetNextBufferPosition();
   1486   }
   1487 
   1488   return split_range;
   1489 }
   1490 
   1491 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt(
   1492     base::TimeDelta timestamp, bool skip_given_timestamp) {
   1493   // Need to make a dummy buffer with timestamp |timestamp| in order to search
   1494   // the |buffers_| container.
   1495   scoped_refptr<StreamParserBuffer> dummy_buffer =
   1496       StreamParserBuffer::CopyFrom(NULL, 0, false);
   1497   dummy_buffer->SetDecodeTimestamp(timestamp);
   1498 
   1499   if (skip_given_timestamp) {
   1500     return std::upper_bound(
   1501         buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator);
   1502   }
   1503   return std::lower_bound(
   1504       buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator);
   1505 }
   1506 
   1507 SourceBufferRange::KeyframeMap::iterator
   1508 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp,
   1509                                       bool skip_given_timestamp) {
   1510   return skip_given_timestamp ?
   1511       keyframe_map_.upper_bound(timestamp) :
   1512       keyframe_map_.lower_bound(timestamp);
   1513 }
   1514 
   1515 SourceBufferRange::KeyframeMap::iterator
   1516 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) {
   1517   KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp);
   1518   // lower_bound() returns the first element >= |timestamp|, so we want the
   1519   // previous element if it did not return the element exactly equal to
   1520   // |timestamp|.
   1521   if (result != keyframe_map_.begin() &&
   1522       (result == keyframe_map_.end() || result->first != timestamp)) {
   1523     --result;
   1524   }
   1525   return result;
   1526 }
   1527 
   1528 void SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) {
   1529   TruncateAt(buffers_.begin(), removed_buffers);
   1530 }
   1531 
   1532 void SourceBufferRange::TruncateAt(
   1533     base::TimeDelta timestamp, BufferQueue* removed_buffers,
   1534     bool is_exclusive) {
   1535   // Find the place in |buffers_| where we will begin deleting data.
   1536   BufferQueue::iterator starting_point =
   1537       GetBufferItrAt(timestamp, is_exclusive);
   1538   TruncateAt(starting_point, removed_buffers);
   1539 }
   1540 
   1541 int SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) {
   1542   DCHECK(!FirstGOPContainsNextBufferPosition());
   1543   DCHECK(deleted_buffers);
   1544 
   1545   int buffers_deleted = 0;
   1546   int total_bytes_deleted = 0;
   1547 
   1548   KeyframeMap::iterator front = keyframe_map_.begin();
   1549   DCHECK(front != keyframe_map_.end());
   1550 
   1551   // Delete the keyframe at the start of |keyframe_map_|.
   1552   keyframe_map_.erase(front);
   1553 
   1554   // Now we need to delete all the buffers that depend on the keyframe we've
   1555   // just deleted.
   1556   int end_index = keyframe_map_.size() > 0 ?
   1557       keyframe_map_.begin()->second - keyframe_map_index_base_ :
   1558       buffers_.size();
   1559 
   1560   // Delete buffers from the beginning of the buffered range up until (but not
   1561   // including) the next keyframe.
   1562   for (int i = 0; i < end_index; i++) {
   1563     int bytes_deleted = buffers_.front()->data_size();
   1564     size_in_bytes_ -= bytes_deleted;
   1565     total_bytes_deleted += bytes_deleted;
   1566     deleted_buffers->push_back(buffers_.front());
   1567     buffers_.pop_front();
   1568     ++buffers_deleted;
   1569   }
   1570 
   1571   // Update |keyframe_map_index_base_| to account for the deleted buffers.
   1572   keyframe_map_index_base_ += buffers_deleted;
   1573 
   1574   if (next_buffer_index_ > -1) {
   1575     next_buffer_index_ -= buffers_deleted;
   1576     DCHECK_GE(next_buffer_index_, 0);
   1577   }
   1578 
   1579   // Invalidate media segment start time if we've deleted the first buffer of
   1580   // the range.
   1581   if (buffers_deleted > 0)
   1582     media_segment_start_time_ = kNoTimestamp();
   1583 
   1584   return total_bytes_deleted;
   1585 }
   1586 
   1587 int SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) {
   1588   DCHECK(!LastGOPContainsNextBufferPosition());
   1589   DCHECK(deleted_buffers);
   1590 
   1591   // Remove the last GOP's keyframe from the |keyframe_map_|.
   1592   KeyframeMap::iterator back = keyframe_map_.end();
   1593   DCHECK_GT(keyframe_map_.size(), 0u);
   1594   --back;
   1595 
   1596   // The index of the first buffer in the last GOP is equal to the new size of
   1597   // |buffers_| after that GOP is deleted.
   1598   size_t goal_size = back->second - keyframe_map_index_base_;
   1599   keyframe_map_.erase(back);
   1600 
   1601   int total_bytes_deleted = 0;
   1602   while (buffers_.size() != goal_size) {
   1603     int bytes_deleted = buffers_.back()->data_size();
   1604     size_in_bytes_ -= bytes_deleted;
   1605     total_bytes_deleted += bytes_deleted;
   1606     // We're removing buffers from the back, so push each removed buffer to the
   1607     // front of |deleted_buffers| so that |deleted_buffers| are in nondecreasing
   1608     // order.
   1609     deleted_buffers->push_front(buffers_.back());
   1610     buffers_.pop_back();
   1611   }
   1612 
   1613   return total_bytes_deleted;
   1614 }
   1615 
   1616 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const {
   1617   if (!HasNextBufferPosition())
   1618     return false;
   1619 
   1620   // If there is only one GOP, it must contain the next buffer position.
   1621   if (keyframe_map_.size() == 1u)
   1622     return true;
   1623 
   1624   KeyframeMap::const_iterator second_gop = keyframe_map_.begin();
   1625   ++second_gop;
   1626   return next_buffer_index_ < second_gop->second - keyframe_map_index_base_;
   1627 }
   1628 
   1629 bool SourceBufferRange::LastGOPContainsNextBufferPosition() const {
   1630   if (!HasNextBufferPosition())
   1631     return false;
   1632 
   1633   // If there is only one GOP, it must contain the next buffer position.
   1634   if (keyframe_map_.size() == 1u)
   1635     return true;
   1636 
   1637   KeyframeMap::const_iterator last_gop = keyframe_map_.end();
   1638   --last_gop;
   1639   return last_gop->second - keyframe_map_index_base_ <= next_buffer_index_;
   1640 }
   1641 
   1642 void SourceBufferRange::FreeBufferRange(
   1643     const BufferQueue::iterator& starting_point,
   1644     const BufferQueue::iterator& ending_point) {
   1645   for (BufferQueue::iterator itr = starting_point;
   1646        itr != ending_point; ++itr) {
   1647     size_in_bytes_ -= (*itr)->data_size();
   1648     DCHECK_GE(size_in_bytes_, 0);
   1649   }
   1650   buffers_.erase(starting_point, ending_point);
   1651 }
   1652 
   1653 void SourceBufferRange::TruncateAt(
   1654     const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) {
   1655   DCHECK(!removed_buffers || removed_buffers->empty());
   1656 
   1657   // Return if we're not deleting anything.
   1658   if (starting_point == buffers_.end())
   1659     return;
   1660 
   1661   // Reset the next buffer index if we will be deleting the buffer that's next
   1662   // in sequence.
   1663   if (HasNextBufferPosition()) {
   1664     base::TimeDelta next_buffer_timestamp = GetNextTimestamp();
   1665     if (next_buffer_timestamp == kNoTimestamp() ||
   1666         next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) {
   1667       if (HasNextBuffer() && removed_buffers) {
   1668         int starting_offset = starting_point - buffers_.begin();
   1669         int next_buffer_offset = next_buffer_index_ - starting_offset;
   1670         DCHECK_GE(next_buffer_offset, 0);
   1671         BufferQueue saved(starting_point + next_buffer_offset, buffers_.end());
   1672         removed_buffers->swap(saved);
   1673       }
   1674       ResetNextBufferPosition();
   1675     }
   1676   }
   1677 
   1678   // Remove keyframes from |starting_point| onward.
   1679   KeyframeMap::iterator starting_point_keyframe =
   1680       keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp());
   1681   keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end());
   1682 
   1683   // Remove everything from |starting_point| onward.
   1684   FreeBufferRange(starting_point, buffers_.end());
   1685 }
   1686 
   1687 bool SourceBufferRange::GetNextBuffer(
   1688     scoped_refptr<StreamParserBuffer>* out_buffer) {
   1689   if (!HasNextBuffer())
   1690     return false;
   1691 
   1692   *out_buffer = buffers_.at(next_buffer_index_);
   1693   next_buffer_index_++;
   1694   return true;
   1695 }
   1696 
   1697 bool SourceBufferRange::HasNextBuffer() const {
   1698   return next_buffer_index_ >= 0 &&
   1699       next_buffer_index_ < static_cast<int>(buffers_.size());
   1700 }
   1701 
   1702 int SourceBufferRange::GetNextConfigId() const {
   1703   DCHECK(HasNextBuffer());
   1704   return buffers_.at(next_buffer_index_)->GetConfigId();
   1705 }
   1706 
   1707 
   1708 base::TimeDelta SourceBufferRange::GetNextTimestamp() const {
   1709   DCHECK(!buffers_.empty());
   1710   DCHECK(HasNextBufferPosition());
   1711 
   1712   if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
   1713     return kNoTimestamp();
   1714   }
   1715 
   1716   return buffers_.at(next_buffer_index_)->GetDecodeTimestamp();
   1717 }
   1718 
   1719 bool SourceBufferRange::HasNextBufferPosition() const {
   1720   return next_buffer_index_ >= 0;
   1721 }
   1722 
   1723 void SourceBufferRange::ResetNextBufferPosition() {
   1724   next_buffer_index_ = -1;
   1725 }
   1726 
   1727 void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range,
   1728                                          bool transfer_current_position) {
   1729   DCHECK(CanAppendRangeToEnd(range));
   1730   DCHECK(!buffers_.empty());
   1731 
   1732   if (transfer_current_position && range.next_buffer_index_ >= 0)
   1733     next_buffer_index_ = range.next_buffer_index_ + buffers_.size();
   1734 
   1735   AppendBuffersToEnd(range.buffers_);
   1736 }
   1737 
   1738 bool SourceBufferRange::CanAppendRangeToEnd(
   1739     const SourceBufferRange& range) const {
   1740   return CanAppendBuffersToEnd(range.buffers_);
   1741 }
   1742 
   1743 bool SourceBufferRange::CanAppendBuffersToEnd(
   1744     const BufferQueue& buffers) const {
   1745   DCHECK(!buffers_.empty());
   1746   return IsNextInSequence(buffers_.back(),
   1747                           buffers.front()->GetDecodeTimestamp());
   1748 }
   1749 
   1750 bool SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const {
   1751   DCHECK(!buffers_.empty());
   1752 
   1753   return (IsNextInSequence(buffers_.back(), timestamp) ||
   1754           (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
   1755 }
   1756 
   1757 bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const {
   1758   base::TimeDelta start_timestamp =
   1759       std::max(base::TimeDelta(), GetStartTimestamp() - GetFudgeRoom());
   1760   return !keyframe_map_.empty() && start_timestamp <= timestamp &&
   1761       timestamp < GetBufferedEndTimestamp();
   1762 }
   1763 
   1764 bool SourceBufferRange::CompletelyOverlaps(
   1765     const SourceBufferRange& range) const {
   1766   return GetStartTimestamp() <= range.GetStartTimestamp() &&
   1767       GetEndTimestamp() >= range.GetEndTimestamp();
   1768 }
   1769 
   1770 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const {
   1771   return range.GetStartTimestamp() <= GetEndTimestamp() &&
   1772       GetEndTimestamp() < range.GetEndTimestamp();
   1773 }
   1774 
   1775 base::TimeDelta SourceBufferRange::GetStartTimestamp() const {
   1776   DCHECK(!buffers_.empty());
   1777   base::TimeDelta start_timestamp = media_segment_start_time_;
   1778   if (start_timestamp == kNoTimestamp())
   1779     start_timestamp = buffers_.front()->GetDecodeTimestamp();
   1780   return start_timestamp;
   1781 }
   1782 
   1783 base::TimeDelta SourceBufferRange::GetEndTimestamp() const {
   1784   DCHECK(!buffers_.empty());
   1785   return buffers_.back()->GetDecodeTimestamp();
   1786 }
   1787 
   1788 base::TimeDelta SourceBufferRange::GetBufferedEndTimestamp() const {
   1789   DCHECK(!buffers_.empty());
   1790   base::TimeDelta duration = buffers_.back()->duration();
   1791   if (duration == kNoTimestamp() || duration == base::TimeDelta())
   1792     duration = GetApproximateDuration();
   1793   return GetEndTimestamp() + duration;
   1794 }
   1795 
   1796 base::TimeDelta SourceBufferRange::NextKeyframeTimestamp(
   1797     base::TimeDelta timestamp) {
   1798   DCHECK(!keyframe_map_.empty());
   1799 
   1800   if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
   1801     return kNoTimestamp();
   1802 
   1803   KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false);
   1804   if (itr == keyframe_map_.end())
   1805     return kNoTimestamp();
   1806   return itr->first;
   1807 }
   1808 
   1809 base::TimeDelta SourceBufferRange::KeyframeBeforeTimestamp(
   1810     base::TimeDelta timestamp) {
   1811   DCHECK(!keyframe_map_.empty());
   1812 
   1813   if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
   1814     return kNoTimestamp();
   1815 
   1816   return GetFirstKeyframeBefore(timestamp)->first;
   1817 }
   1818 
   1819 bool SourceBufferRange::IsNextInSequence(
   1820     const scoped_refptr<media::StreamParserBuffer>& buffer,
   1821     base::TimeDelta timestamp) const {
   1822   return buffer->GetDecodeTimestamp() < timestamp &&
   1823       timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom();
   1824 }
   1825 
   1826 base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
   1827   return ComputeFudgeRoom(GetApproximateDuration());
   1828 }
   1829 
   1830 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
   1831   base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run();
   1832   DCHECK(max_interbuffer_distance != kNoTimestamp());
   1833   return max_interbuffer_distance;
   1834 }
   1835 
   1836 }  // namespace media
   1837