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