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