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