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