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