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