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