source_buffer_stream.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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/logging.h"
12#include "base/stl_util.h"
13
14namespace media {
15
16// Helper class representing a range of buffered data. All buffers in a
17// SourceBufferRange are ordered sequentially in presentation order with no
18// gaps.
19class SourceBufferRange {
20 public:
21  typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
22
23  // Returns the maximum distance in time between any buffer seen in this
24  // stream. Used to estimate the duration of a buffer if its duration is not
25  // known.
26  typedef base::Callback<base::TimeDelta()> InterbufferDistanceCB;
27
28  // Creates a source buffer range with |new_buffers|. |new_buffers| cannot be
29  // empty and the front of |new_buffers| must be a keyframe.
30  // |media_segment_start_time| refers to the starting timestamp for the media
31  // segment to which these buffers belong.
32  SourceBufferRange(const BufferQueue& new_buffers,
33                    base::TimeDelta media_segment_start_time,
34                    const InterbufferDistanceCB& interbuffer_distance_cb);
35
36  // Appends |buffers| to the end of the range and updates |keyframe_map_| as
37  // it encounters new keyframes. Assumes |buffers| belongs at the end of the
38  // range.
39  void AppendBuffersToEnd(const BufferQueue& buffers);
40  bool CanAppendBuffersToEnd(const BufferQueue& buffers) const;
41
42  // Appends the buffers from |range| into this range.
43  // The first buffer in |range| must come directly after the last buffer
44  // in this range.
45  // If |transfer_current_position| is true, |range|'s |next_buffer_index_|
46  // is transfered to this SourceBufferRange.
47  void AppendRangeToEnd(const SourceBufferRange& range,
48                        bool transfer_current_position);
49  bool CanAppendRangeToEnd(const SourceBufferRange& range) const;
50
51  // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|.
52  // Assumes |timestamp| is valid and in this range.
53  void Seek(base::TimeDelta timestamp);
54
55  // Updates |next_buffer_index_| to point to next keyframe after or equal to
56  // |timestamp|.
57  void SeekAheadTo(base::TimeDelta timestamp);
58
59  // Updates |next_buffer_index_| to point to next keyframe strictly after
60  // |timestamp|.
61  void SeekAheadPast(base::TimeDelta timestamp);
62
63  // Seeks to the beginning of the range.
64  void SeekToStart();
65
66  // Finds the next keyframe from |buffers_| after |timestamp| (or at
67  // |timestamp| if |is_exclusive| is false) and creates and returns a new
68  // SourceBufferRange with the buffers from that keyframe onward.
69  // The buffers in the new SourceBufferRange are moved out of this range. If
70  // there is no keyframe after |timestamp|, SplitRange() returns null and this
71  // range is unmodified.
72  SourceBufferRange* SplitRange(base::TimeDelta timestamp, bool is_exclusive);
73
74  // Deletes the buffers from this range starting at |timestamp|, exclusive if
75  // |is_exclusive| is true, inclusive otherwise.
76  // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was
77  // deleted, and deletes the |keyframe_map_| entries for the buffers that
78  // were removed.
79  // |deleted_buffers| contains the buffers that were deleted from this range,
80  // starting at the buffer that had been at |next_buffer_index_|.
81  // Returns true if the |next_buffer_index_| is reset. Note that this method
82  // may return true even if it does not add any buffers to |deleted_buffers|.
83  // This indicates that the range had not buffered |next_buffer_index_|, but
84  // a buffer at that position would have been deleted.
85  bool TruncateAt(base::TimeDelta timestamp,
86                  BufferQueue* deleted_buffers, bool is_exclusive);
87  // Deletes all buffers in range.
88  bool DeleteAll(BufferQueue* deleted_buffers);
89
90  // Deletes a GOP from the front or back of the range and moves these
91  // buffers into |deleted_buffers|. Returns the number of bytes deleted from
92  // the range (i.e. the size in bytes of |deleted_buffers|).
93  int DeleteGOPFromFront(BufferQueue* deleted_buffers);
94  int DeleteGOPFromBack(BufferQueue* deleted_buffers);
95
96  // Indicates whether the GOP at the beginning or end of the range contains the
97  // next buffer position.
98  bool FirstGOPContainsNextBufferPosition() const;
99  bool LastGOPContainsNextBufferPosition() const;
100
101  // Updates |out_buffer| with the next buffer in presentation order. Seek()
102  // must be called before calls to GetNextBuffer(), and buffers are returned
103  // in order from the last call to Seek(). Returns true if |out_buffer| is
104  // filled with a valid buffer, false if there is not enough data to fulfill
105  // the request.
106  bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer);
107  bool HasNextBuffer() const;
108
109  // Returns the config ID for the buffer that will be returned by
110  // GetNextBuffer().
111  int GetNextConfigId() const;
112
113  // Returns true if the range knows the position of the next buffer it should
114  // return, i.e. it has been Seek()ed. This does not necessarily mean that it
115  // has the next buffer yet.
116  bool HasNextBufferPosition() const;
117
118  // Resets this range to an "unseeked" state.
119  void ResetNextBufferPosition();
120
121  // Returns the timestamp of the next buffer that will be returned from
122  // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown.
123  base::TimeDelta GetNextTimestamp() const;
124
125  // Returns the start timestamp of the range.
126  base::TimeDelta GetStartTimestamp() const;
127
128  // Returns the timestamp of the last buffer in the range.
129  base::TimeDelta GetEndTimestamp() const;
130
131  // Returns the timestamp for the end of the buffered region in this range.
132  // This is an approximation if the duration for the last buffer in the range
133  // is unset.
134  base::TimeDelta GetBufferedEndTimestamp() const;
135
136  // Returns whether a buffer with a starting timestamp of |timestamp| would
137  // belong in this range. This includes a buffer that would be appended to
138  // the end of the range.
139  bool BelongsToRange(base::TimeDelta timestamp) const;
140
141  // Returns true if the range has enough data to seek to the specified
142  // |timestamp|, false otherwise.
143  bool CanSeekTo(base::TimeDelta timestamp) const;
144
145  // Returns true if this range's buffered timespan completely overlaps the
146  // buffered timespan of |range|.
147  bool CompletelyOverlaps(const SourceBufferRange& range) const;
148
149  // Returns true if the end of this range contains buffers that overlaps with
150  // the beginning of |range|.
151  bool EndOverlaps(const SourceBufferRange& range) const;
152
153  // Returns true if |timestamp| is the timestamp of the next buffer in
154  // sequence after |buffer|, false otherwise.
155  bool IsNextInSequence(
156      const scoped_refptr<media::StreamParserBuffer>& buffer,
157      base::TimeDelta timestamp) const;
158
159  int size_in_bytes() const { return size_in_bytes_; }
160
161 private:
162  typedef std::map<base::TimeDelta, int> KeyframeMap;
163
164  // Seeks the range to the next keyframe after |timestamp|. If
165  // |skip_given_timestamp| is true, the seek will go to a keyframe with a
166  // timestamp strictly greater than |timestamp|.
167  void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp);
168
169  // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|.
170  // If |skip_given_timestamp| is true, this returns the first buffer with
171  // timestamp greater than |timestamp|.
172  BufferQueue::iterator GetBufferItrAt(
173      base::TimeDelta timestamp, bool skip_given_timestamp);
174
175  // Returns an iterator in |keyframe_map_| pointing to the next keyframe after
176  // |timestamp|. If |skip_given_timestamp| is true, this returns the first
177  // keyframe with a timestamp strictly greater than |timestamp|.
178  KeyframeMap::iterator GetFirstKeyframeAt(
179      base::TimeDelta timestamp, bool skip_given_timestamp);
180
181  // Returns an iterator in |keyframe_map_| pointing to the first keyframe
182  // before or at |timestamp|.
183  KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp);
184
185  // Helper method to delete buffers in |buffers_| starting at
186  // |starting_point|, an iterator in |buffers_|.
187  bool TruncateAt(const BufferQueue::iterator& starting_point,
188                  BufferQueue* deleted_buffers);
189
190  // Frees the buffers in |buffers_| from [|start_point|,|ending_point|) and
191  // updates the |size_in_bytes_| accordingly. Does not update |keyframe_map_|.
192  void FreeBufferRange(const BufferQueue::iterator& starting_point,
193                       const BufferQueue::iterator& ending_point);
194
195  // Returns the distance in time estimating how far from the beginning or end
196  // of this range a buffer can be to considered in the range.
197  base::TimeDelta GetFudgeRoom() const;
198
199  // Returns the approximate duration of a buffer in this range.
200  base::TimeDelta GetApproximateDuration() const;
201
202  // An ordered list of buffers in this range.
203  BufferQueue buffers_;
204
205  // Maps keyframe timestamps to its index position in |buffers_|.
206  KeyframeMap keyframe_map_;
207
208  // Index into |buffers_| for the next buffer to be returned by
209  // GetNextBuffer(), set to -1 before Seek().
210  int next_buffer_index_;
211
212  // True if the range needs to wait for the next keyframe to be appended before
213  // returning buffers from GetNextBuffer().
214  bool waiting_for_keyframe_;
215
216  // If |waiting_for_keyframe_| is true, this range will wait for the next
217  // keyframe with timestamp >= |next_keyframe_timestamp_|.
218  base::TimeDelta next_keyframe_timestamp_;
219
220  // If the first buffer in this range is the beginning of a media segment,
221  // |media_segment_start_time_| is the time when the media segment begins.
222  // |media_segment_start_time_| may be <= the timestamp of the first buffer in
223  // |buffers_|. |media_segment_start_time_| is kNoTimestamp() if this range
224  // does not start at the beginning of a media segment, which can only happen
225  // garbage collection or after an end overlap that results in a split range
226  // (we don't have a way of knowing the media segment timestamp for the new
227  // range).
228  base::TimeDelta media_segment_start_time_;
229
230  // Called to get the largest interbuffer distance seen so far in the stream.
231  InterbufferDistanceCB interbuffer_distance_cb_;
232
233  // Stores the amount of memory taken up by the data in |buffers_|.
234  int size_in_bytes_;
235
236  DISALLOW_COPY_AND_ASSIGN(SourceBufferRange);
237};
238
239}  // namespace media
240
241// Helper method that returns true if |ranges| is sorted in increasing order,
242// false otherwise.
243static bool IsRangeListSorted(
244    const std::list<media::SourceBufferRange*>& ranges) {
245  base::TimeDelta prev = media::kNoTimestamp();
246  for (std::list<media::SourceBufferRange*>::const_iterator itr =
247       ranges.begin(); itr != ranges.end(); ++itr) {
248    if (prev != media::kNoTimestamp() && prev >= (*itr)->GetStartTimestamp())
249      return false;
250    prev = (*itr)->GetEndTimestamp();
251  }
252  return true;
253}
254
255// Comparison function for two Buffers based on timestamp.
256static bool BufferComparator(
257    const scoped_refptr<media::StreamParserBuffer>& first,
258    const scoped_refptr<media::StreamParserBuffer>& second) {
259  return first->GetDecodeTimestamp() < second->GetDecodeTimestamp();
260}
261
262// Returns an estimate of how far from the beginning or end of a range a buffer
263// can be to still be considered in the range, given the |approximate_duration|
264// of a buffer in the stream.
265static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) {
266  // Because we do not know exactly when is the next timestamp, any buffer
267  // that starts within 2x the approximate duration of a buffer is considered
268  // within this range.
269  return 2 * approximate_duration;
270}
271
272// An arbitrarily-chosen number to estimate the duration of a buffer if none
273// is set and there's not enough information to get a better estimate.
274static int kDefaultBufferDurationInMs = 125;
275
276// The amount of time the beginning of the buffered data can differ from the
277// start time in order to still be considered the start of stream.
278static base::TimeDelta kSeekToStartFudgeRoom() {
279  return base::TimeDelta::FromMilliseconds(1000);
280}
281// The maximum amount of data in bytes the stream will keep in memory.
282// 12MB: approximately 5 minutes of 320Kbps content.
283// 150MB: approximately 5 minutes of 4Mbps content.
284static int kDefaultAudioMemoryLimit = 12 * 1024 * 1024;
285static int kDefaultVideoMemoryLimit = 150 * 1024 * 1024;
286
287namespace media {
288
289SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config)
290    : current_config_index_(0),
291      append_config_index_(0),
292      seek_pending_(false),
293      seek_buffer_timestamp_(kNoTimestamp()),
294      selected_range_(NULL),
295      media_segment_start_time_(kNoTimestamp()),
296      range_for_next_append_(ranges_.end()),
297      new_media_segment_(false),
298      last_buffer_timestamp_(kNoTimestamp()),
299      max_interbuffer_distance_(kNoTimestamp()),
300      memory_limit_(kDefaultAudioMemoryLimit),
301      config_change_pending_(false) {
302  DCHECK(audio_config.IsValidConfig());
303  audio_configs_.push_back(new AudioDecoderConfig());
304  audio_configs_.back()->CopyFrom(audio_config);
305}
306
307SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config)
308    : current_config_index_(0),
309      append_config_index_(0),
310      seek_pending_(false),
311      seek_buffer_timestamp_(kNoTimestamp()),
312      selected_range_(NULL),
313      media_segment_start_time_(kNoTimestamp()),
314      range_for_next_append_(ranges_.end()),
315      new_media_segment_(false),
316      last_buffer_timestamp_(kNoTimestamp()),
317      max_interbuffer_distance_(kNoTimestamp()),
318      memory_limit_(kDefaultVideoMemoryLimit),
319      config_change_pending_(false) {
320  DCHECK(video_config.IsValidConfig());
321  video_configs_.push_back(new VideoDecoderConfig());
322  video_configs_.back()->CopyFrom(video_config);
323}
324
325SourceBufferStream::~SourceBufferStream() {
326  while (!ranges_.empty()) {
327    delete ranges_.front();
328    ranges_.pop_front();
329  }
330
331  STLDeleteElements(&audio_configs_);
332  STLDeleteElements(&video_configs_);
333}
334
335void SourceBufferStream::OnNewMediaSegment(
336    base::TimeDelta media_segment_start_time) {
337  media_segment_start_time_ = media_segment_start_time;
338  new_media_segment_ = true;
339
340  RangeList::iterator last_range = range_for_next_append_;
341  range_for_next_append_ = FindExistingRangeFor(media_segment_start_time);
342
343  // Only reset |last_buffer_timestamp_| if this new media segment is not
344  // adjacent to the previous media segment appended to the stream.
345  if (range_for_next_append_ == ranges_.end() ||
346      !AreAdjacentInSequence(
347          last_buffer_timestamp_, media_segment_start_time)) {
348    last_buffer_timestamp_ = kNoTimestamp();
349  } else {
350    DCHECK(last_range == range_for_next_append_);
351  }
352}
353
354bool SourceBufferStream::Append(
355    const SourceBufferStream::BufferQueue& buffers) {
356  DCHECK(!buffers.empty());
357  DCHECK(media_segment_start_time_ != kNoTimestamp());
358
359  // New media segments must begin with a keyframe.
360  if (new_media_segment_ && !buffers.front()->IsKeyframe()) {
361    DVLOG(1) << "Media segment did not begin with keyframe.";
362    return false;
363  }
364
365  // Buffers within a media segment should be monotonically increasing.
366  if (!IsMonotonicallyIncreasing(buffers)) {
367    DVLOG(1) << "Buffers were not monotonically increasing.";
368    return false;
369  }
370
371  if (media_segment_start_time_ < base::TimeDelta() ||
372      buffers.front()->GetDecodeTimestamp() < base::TimeDelta()) {
373    DVLOG(1) << "Cannot append a media segment with negative timestamps.";
374    return false;
375  }
376
377  UpdateMaxInterbufferDistance(buffers);
378  SetConfigIds(buffers);
379
380  // Save a snapshot of stream state before range modifications are made.
381  base::TimeDelta next_buffer_timestamp = GetNextBufferTimestamp();
382  base::TimeDelta end_buffer_timestamp = GetEndBufferTimestamp();
383
384  bool deleted_next_buffer = false;
385  BufferQueue deleted_buffers;
386
387  RangeList::iterator range_for_new_buffers = range_for_next_append_;
388  // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
389  // create a new range with |buffers|.
390  if (range_for_new_buffers != ranges_.end()) {
391    InsertIntoExistingRange(range_for_new_buffers, buffers,
392                            &deleted_next_buffer, &deleted_buffers);
393  } else {
394    DCHECK(new_media_segment_);
395    range_for_new_buffers =
396        AddToRanges(new SourceBufferRange(
397            buffers, media_segment_start_time_,
398            base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
399                       base::Unretained(this))));
400  }
401
402  range_for_next_append_ = range_for_new_buffers;
403  new_media_segment_ = false;
404  last_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
405
406  // Resolve overlaps.
407  ResolveCompleteOverlaps(
408      range_for_new_buffers, &deleted_next_buffer, &deleted_buffers);
409  ResolveEndOverlap(
410      range_for_new_buffers, &deleted_next_buffer, &deleted_buffers);
411  MergeWithAdjacentRangeIfNecessary(range_for_new_buffers);
412
413  // Seek to try to fulfill a previous call to Seek().
414  if (seek_pending_) {
415    DCHECK(!selected_range_);
416    DCHECK(!deleted_next_buffer);
417    Seek(seek_buffer_timestamp_);
418  }
419
420  // Seek because the Append() has deleted the buffer that would have been
421  // returned in the next call to GetNextBuffer().
422  if (deleted_next_buffer) {
423    DCHECK(!seek_pending_);
424    SetSelectedRange(*range_for_new_buffers);
425    if (next_buffer_timestamp != kNoTimestamp()) {
426      // Seek ahead to the keyframe at or after |next_buffer_timestamp|, the
427      // timestamp of the deleted next buffer.
428      selected_range_->SeekAheadTo(next_buffer_timestamp);
429      // Update track buffer with non-keyframe buffers leading up to the current
430      // position of |selected_range_|.
431      PruneTrackBuffer();
432      if (!deleted_buffers.empty())
433        UpdateTrackBuffer(deleted_buffers);
434    } else {
435      // If |next_buffer_timestamp| is kNoTimestamp(), it means the range
436      // we've overlapped didn't actually have the next buffer buffered, and it
437      // was waiting for the next buffer whose timestamp was greater than
438      // |end_buffer_timestamp|. Seek the |selected_range_| to the next keyframe
439      // after |end_buffer_timestamp|.
440      DCHECK(track_buffer_.empty());
441      DCHECK(deleted_buffers.empty());
442      selected_range_->SeekAheadPast(end_buffer_timestamp);
443    }
444  }
445
446  GarbageCollectIfNeeded();
447
448  DCHECK(IsRangeListSorted(ranges_));
449  DCHECK(OnlySelectedRangeIsSeeked());
450  return true;
451}
452
453void SourceBufferStream::ResetSeekState() {
454  SetSelectedRange(NULL);
455  track_buffer_.clear();
456  config_change_pending_ = false;
457}
458
459bool SourceBufferStream::ShouldSeekToStartOfBuffered(
460    base::TimeDelta seek_timestamp) const {
461  if (ranges_.empty())
462    return false;
463  base::TimeDelta beginning_of_buffered =
464      ranges_.front()->GetStartTimestamp();
465  return (seek_timestamp <= beginning_of_buffered &&
466          beginning_of_buffered < kSeekToStartFudgeRoom());
467}
468
469bool SourceBufferStream::IsMonotonicallyIncreasing(
470    const BufferQueue& buffers) const {
471  DCHECK(!buffers.empty());
472  base::TimeDelta prev_timestamp = last_buffer_timestamp_;
473  for (BufferQueue::const_iterator itr = buffers.begin();
474       itr != buffers.end(); ++itr) {
475    base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp();
476    DCHECK(current_timestamp != kNoTimestamp());
477
478    if (prev_timestamp != kNoTimestamp() && current_timestamp < prev_timestamp)
479      return false;
480
481    prev_timestamp = current_timestamp;
482  }
483  return true;
484}
485
486bool SourceBufferStream::OnlySelectedRangeIsSeeked() const {
487  for (RangeList::const_iterator itr = ranges_.begin();
488       itr != ranges_.end(); ++itr) {
489    if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_)
490      return false;
491  }
492  return !selected_range_ || selected_range_->HasNextBufferPosition();
493}
494
495void SourceBufferStream::UpdateMaxInterbufferDistance(
496    const BufferQueue& buffers) {
497  DCHECK(!buffers.empty());
498  base::TimeDelta prev_timestamp = last_buffer_timestamp_;
499  for (BufferQueue::const_iterator itr = buffers.begin();
500       itr != buffers.end(); ++itr) {
501    base::TimeDelta current_timestamp = (*itr)->GetDecodeTimestamp();
502    DCHECK(current_timestamp != kNoTimestamp());
503
504    if (prev_timestamp != kNoTimestamp()) {
505      base::TimeDelta interbuffer_distance = current_timestamp - prev_timestamp;
506      if (max_interbuffer_distance_ == kNoTimestamp()) {
507        max_interbuffer_distance_ = interbuffer_distance;
508      } else {
509        max_interbuffer_distance_ =
510            std::max(max_interbuffer_distance_, interbuffer_distance);
511      }
512    }
513    prev_timestamp = current_timestamp;
514  }
515}
516
517void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) {
518  for (BufferQueue::const_iterator itr = buffers.begin();
519       itr != buffers.end(); ++itr) {
520    (*itr)->SetConfigId(append_config_index_);
521  }
522}
523
524void SourceBufferStream::GarbageCollectIfNeeded() {
525  // Compute size of |ranges_|.
526  int ranges_size = 0;
527  for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr)
528    ranges_size += (*itr)->size_in_bytes();
529
530  // Return if we're under or at the memory limit.
531  if (ranges_size <= memory_limit_)
532    return;
533
534  int bytes_to_free = ranges_size - memory_limit_;
535
536  // Begin deleting from the front.
537  int bytes_freed = FreeBuffers(bytes_to_free, false);
538
539  // Begin deleting from the back.
540  if (bytes_to_free - bytes_freed > 0)
541    FreeBuffers(bytes_to_free - bytes_freed, true);
542}
543
544int SourceBufferStream::FreeBuffers(int total_bytes_to_free,
545                                    bool reverse_direction) {
546  DCHECK_GT(total_bytes_to_free, 0);
547  int bytes_to_free = total_bytes_to_free;
548  int bytes_freed = 0;
549
550  // This range will save the last GOP appended to |range_for_next_append_|
551  // if the buffers surrounding it get deleted during garbage collection.
552  SourceBufferRange* new_range_for_append = NULL;
553
554  while (!ranges_.empty() && bytes_to_free > 0) {
555
556    SourceBufferRange* current_range = NULL;
557    BufferQueue buffers;
558    int bytes_deleted = 0;
559
560    if (reverse_direction) {
561      current_range = ranges_.back();
562      if (current_range->LastGOPContainsNextBufferPosition()) {
563        DCHECK_EQ(current_range, selected_range_);
564        break;
565      }
566      bytes_deleted = current_range->DeleteGOPFromBack(&buffers);
567    } else {
568      current_range = ranges_.front();
569      if (current_range->FirstGOPContainsNextBufferPosition()) {
570        DCHECK_EQ(current_range, selected_range_);
571        break;
572      }
573      bytes_deleted = current_range->DeleteGOPFromFront(&buffers);
574    }
575
576    // Check to see if we've just deleted the GOP that was last appended.
577    if (buffers.back()->GetDecodeTimestamp() == last_buffer_timestamp_) {
578      DCHECK(last_buffer_timestamp_ != kNoTimestamp());
579      DCHECK(!new_range_for_append);
580      // Create a new range containing these buffers.
581      new_range_for_append = new SourceBufferRange(
582            buffers, kNoTimestamp(),
583            base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
584                       base::Unretained(this)));
585      range_for_next_append_ = ranges_.end();
586    } else {
587      bytes_to_free -= bytes_deleted;
588      bytes_freed += bytes_deleted;
589    }
590
591    if (current_range->size_in_bytes() == 0) {
592      DCHECK_NE(current_range, selected_range_);
593      DCHECK(range_for_next_append_ == ranges_.end() ||
594             *range_for_next_append_ != current_range);
595      delete current_range;
596      reverse_direction ? ranges_.pop_back() : ranges_.pop_front();
597    }
598  }
599
600  // Insert |new_range_for_append| into |ranges_|, if applicable.
601  if (new_range_for_append) {
602    range_for_next_append_ = AddToRanges(new_range_for_append);
603    DCHECK(range_for_next_append_ != ranges_.end());
604
605    // Check to see if we need to merge |new_range_for_append| with the range
606    // before or after it. |new_range_for_append| is created whenever the last
607    // GOP appended is encountered, regardless of whether any buffers after it
608    // are ultimately deleted. Merging is necessary if there were no buffers
609    // (or very few buffers) deleted after creating |new_range_for_append|.
610    if (range_for_next_append_ != ranges_.begin()) {
611      RangeList::iterator range_before_next = range_for_next_append_;
612      --range_before_next;
613      MergeWithAdjacentRangeIfNecessary(range_before_next);
614    }
615    MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
616  }
617  return bytes_freed;
618}
619
620void SourceBufferStream::InsertIntoExistingRange(
621    const RangeList::iterator& range_for_new_buffers_itr,
622    const BufferQueue& new_buffers,
623    bool* deleted_next_buffer, BufferQueue* deleted_buffers) {
624  DCHECK(deleted_next_buffer);
625  DCHECK(deleted_buffers);
626
627  SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr;
628
629  if (last_buffer_timestamp_ != kNoTimestamp()) {
630    // Clean up the old buffers between the last appended buffer and the
631    // beginning of |new_buffers|.
632    *deleted_next_buffer =
633        DeleteBetween(
634            range_for_new_buffers, last_buffer_timestamp_,
635            new_buffers.front()->GetDecodeTimestamp(), true,
636            deleted_buffers);
637  }
638
639  // If we cannot append the |new_buffers| to the end of the existing range,
640  // this is either a start overlap or an middle overlap. Delete the buffers
641  // that |new_buffers| overlaps.
642  if (!range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) {
643    *deleted_next_buffer |=
644        DeleteBetween(
645            range_for_new_buffers, new_buffers.front()->GetDecodeTimestamp(),
646            new_buffers.back()->GetDecodeTimestamp(), false,
647            deleted_buffers);
648  }
649
650  range_for_new_buffers->AppendBuffersToEnd(new_buffers);
651}
652
653bool SourceBufferStream::DeleteBetween(
654    SourceBufferRange* range, base::TimeDelta start_timestamp,
655    base::TimeDelta end_timestamp, bool is_range_exclusive,
656    BufferQueue* deleted_buffers) {
657  SourceBufferRange* new_next_range =
658      range->SplitRange(end_timestamp, is_range_exclusive);
659
660  if (new_next_range)
661    AddToRanges(new_next_range);
662
663  BufferQueue saved_buffers;
664  bool deleted_next_buffer =
665      range->TruncateAt(start_timestamp, &saved_buffers, is_range_exclusive);
666
667  if (selected_range_ != range)
668    return deleted_next_buffer;
669
670  DCHECK(deleted_buffers->empty());
671  *deleted_buffers = saved_buffers;
672
673  // If the next buffer position has transferred to the split range, set the
674  // selected range accordingly.
675  if (new_next_range && new_next_range->HasNextBufferPosition()) {
676    DCHECK(!range->HasNextBufferPosition());
677    DCHECK(!deleted_next_buffer);
678    SetSelectedRange(new_next_range);
679  }
680  return deleted_next_buffer;
681}
682
683bool SourceBufferStream::AreAdjacentInSequence(
684    base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const {
685  return first_timestamp < second_timestamp &&
686      second_timestamp <=
687      first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
688}
689
690void SourceBufferStream::ResolveCompleteOverlaps(
691    const RangeList::iterator& range_with_new_buffers_itr,
692    bool* deleted_next_buffer, BufferQueue* deleted_buffers) {
693  DCHECK(deleted_next_buffer);
694  DCHECK(deleted_buffers);
695
696  SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
697  RangeList::iterator next_range_itr = range_with_new_buffers_itr;
698  ++next_range_itr;
699
700  while (next_range_itr != ranges_.end() &&
701         range_with_new_buffers->CompletelyOverlaps(**next_range_itr)) {
702    if (*next_range_itr == selected_range_) {
703      DCHECK(!*deleted_next_buffer);
704      *deleted_next_buffer = selected_range_->DeleteAll(deleted_buffers);
705      DCHECK(*deleted_next_buffer);
706      SetSelectedRange(NULL);
707    }
708    delete *next_range_itr;
709    next_range_itr = ranges_.erase(next_range_itr);
710  }
711}
712
713void SourceBufferStream::ResolveEndOverlap(
714    const RangeList::iterator& range_with_new_buffers_itr,
715    bool* deleted_next_buffer, BufferQueue* deleted_buffers) {
716  DCHECK(deleted_next_buffer);
717  DCHECK(deleted_buffers);
718
719  SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
720  RangeList::iterator next_range_itr = range_with_new_buffers_itr;
721  ++next_range_itr;
722
723  if (next_range_itr == ranges_.end() ||
724      !range_with_new_buffers->EndOverlaps(**next_range_itr)) {
725    return;
726  }
727
728  // Split the overlapped range after |range_with_new_buffers|'s last buffer
729  // overlaps. Now |overlapped_range| contains only the buffers that do not
730  // belong in |ranges_| anymore, and |new_next_range| contains buffers that
731  // go after |range_with_new_buffers| (without overlap).
732  scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr);
733  next_range_itr = ranges_.erase(next_range_itr);
734
735  SourceBufferRange* new_next_range =
736      overlapped_range->SplitRange(
737          range_with_new_buffers->GetEndTimestamp(), true);
738
739  // If there were non-overlapped buffers, add the new range to |ranges_|.
740  if (new_next_range)
741    AddToRanges(new_next_range);
742
743  // If we didn't overlap a selected range, return.
744  if (selected_range_ != overlapped_range.get())
745    return;
746
747  // If the |overlapped_range| transfers its next buffer position to
748  // |new_next_range|, make |new_next_range| the |selected_range_|.
749  if (new_next_range && new_next_range->HasNextBufferPosition()) {
750    DCHECK(!overlapped_range->HasNextBufferPosition());
751    SetSelectedRange(new_next_range);
752    return;
753  }
754
755  // Save the buffers in |overlapped_range|.
756  DCHECK(!*deleted_next_buffer);
757  DCHECK_EQ(overlapped_range.get(), selected_range_);
758  *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers);
759  DCHECK(*deleted_next_buffer);
760
761  // |overlapped_range| will be deleted, so set |selected_range_| to NULL.
762  SetSelectedRange(NULL);
763}
764
765void SourceBufferStream::PruneTrackBuffer() {
766  DCHECK(selected_range_);
767  DCHECK(selected_range_->HasNextBufferPosition());
768  base::TimeDelta next_timestamp = selected_range_->GetNextTimestamp();
769
770  // If we don't have the next timestamp, we don't have anything to delete.
771  if (next_timestamp == kNoTimestamp())
772    return;
773
774  while (!track_buffer_.empty() &&
775         track_buffer_.back()->GetDecodeTimestamp() >= next_timestamp) {
776    track_buffer_.pop_back();
777  }
778}
779
780void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) {
781  DCHECK(!deleted_buffers.empty());
782  DCHECK(selected_range_);
783  DCHECK(selected_range_->HasNextBufferPosition());
784
785  base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp();
786  base::TimeDelta start_of_deleted =
787      deleted_buffers.front()->GetDecodeTimestamp();
788
789  // |deleted_buffers| should always come after the buffers in |track_buffer|.
790  if (!track_buffer_.empty())
791    DCHECK(track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted);
792
793  // If there is no gap between what was deleted and what was added, nothing
794  // should be added to the track buffer.
795  if (selected_range_->HasNextBuffer() &&
796      next_keyframe_timestamp <= start_of_deleted) {
797    return;
798  }
799
800  // If the |selected_range_| is ready to return data, fill the track buffer
801  // with all buffers that come before |next_keyframe_timestamp| and return.
802  if (selected_range_->HasNextBuffer()) {
803    for (BufferQueue::const_iterator itr = deleted_buffers.begin();
804         itr != deleted_buffers.end() &&
805         (*itr)->GetDecodeTimestamp() < next_keyframe_timestamp; ++itr) {
806      track_buffer_.push_back(*itr);
807    }
808    return;
809  }
810
811  // Otherwise, the |selected_range_| is not ready to return data, so add all
812  // the deleted buffers into the |track_buffer_|.
813  track_buffer_.insert(track_buffer_.end(),
814                       deleted_buffers.begin(), deleted_buffers.end());
815
816  // See if the next range contains the keyframe after the end of the
817  // |track_buffer_|, and if so, change |selected_range_|.
818  RangeList::iterator next_range_itr = ++(GetSelectedRangeItr());
819  if (next_range_itr == ranges_.end())
820    return;
821
822  (*next_range_itr)->SeekAheadPast(
823      track_buffer_.back()->GetDecodeTimestamp());
824
825  if (!(*next_range_itr)->HasNextBuffer())
826    return;
827
828  if (!selected_range_->IsNextInSequence(
829          track_buffer_.back(), (*next_range_itr)->GetNextTimestamp())) {
830    (*next_range_itr)->ResetNextBufferPosition();
831    return;
832  }
833  SetSelectedRange(*next_range_itr);
834}
835
836void SourceBufferStream::MergeWithAdjacentRangeIfNecessary(
837    const RangeList::iterator& range_with_new_buffers_itr) {
838  SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
839  RangeList::iterator next_range_itr = range_with_new_buffers_itr;
840  ++next_range_itr;
841
842  if (next_range_itr != ranges_.end() &&
843      range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) {
844    bool transfer_current_position = selected_range_ == *next_range_itr;
845    range_with_new_buffers->AppendRangeToEnd(**next_range_itr,
846                                             transfer_current_position);
847    // Update |selected_range_| pointer if |range| has become selected after
848    // merges.
849    if (transfer_current_position)
850      SetSelectedRange(range_with_new_buffers);
851
852    if (next_range_itr == range_for_next_append_)
853      range_for_next_append_ = range_with_new_buffers_itr;
854
855    delete *next_range_itr;
856    ranges_.erase(next_range_itr);
857  }
858}
859
860void SourceBufferStream::Seek(base::TimeDelta timestamp) {
861  DCHECK(timestamp >= base::TimeDelta());
862  ResetSeekState();
863
864  if (ShouldSeekToStartOfBuffered(timestamp)) {
865    SetSelectedRange(ranges_.front());
866    ranges_.front()->SeekToStart();
867    seek_pending_ = false;
868    return;
869  }
870
871  seek_buffer_timestamp_ = timestamp;
872  seek_pending_ = true;
873
874  RangeList::iterator itr = ranges_.end();
875  for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
876    if ((*itr)->CanSeekTo(timestamp))
877      break;
878  }
879
880  if (itr == ranges_.end())
881    return;
882
883  SetSelectedRange(*itr);
884  selected_range_->Seek(timestamp);
885  seek_pending_ = false;
886}
887
888bool SourceBufferStream::IsSeekPending() const {
889  return seek_pending_;
890}
891
892void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
893  RangeList::iterator itr = ranges_.end();
894  for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
895    if ((*itr)->GetEndTimestamp() > duration)
896      break;
897  }
898  if (itr == ranges_.end())
899    return;
900
901  // Need to partially truncate this range.
902  if ((*itr)->GetStartTimestamp() < duration) {
903    bool deleted_seek_point = (*itr)->TruncateAt(duration, NULL, false);
904    if (deleted_seek_point)
905      ResetSeekState();
906    ++itr;
907  }
908
909  // Delete all ranges that begin after |duration|.
910  while (itr != ranges_.end()) {
911    // If we're about to delete the selected range, also reset the seek state.
912    DCHECK((*itr)->GetStartTimestamp() >= duration);
913    if (*itr== selected_range_)
914      ResetSeekState();
915    delete *itr;
916    itr = ranges_.erase(itr);
917  }
918}
919
920SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
921    scoped_refptr<StreamParserBuffer>* out_buffer) {
922  CHECK(!config_change_pending_);
923
924  if (!track_buffer_.empty()) {
925    DCHECK(selected_range_);
926    if (track_buffer_.front()->GetConfigId() != current_config_index_) {
927      config_change_pending_ = true;
928      return kConfigChange;
929    }
930
931    *out_buffer = track_buffer_.front();
932    track_buffer_.pop_front();
933    return kSuccess;
934  }
935
936  if (!selected_range_ || !selected_range_->HasNextBuffer())
937    return kNeedBuffer;
938
939  if (selected_range_->GetNextConfigId() != current_config_index_) {
940    config_change_pending_ = true;
941    return kConfigChange;
942  }
943
944  CHECK(selected_range_->GetNextBuffer(out_buffer));
945  return kSuccess;
946}
947
948base::TimeDelta SourceBufferStream::GetNextBufferTimestamp() {
949  if (!selected_range_) {
950    DCHECK(track_buffer_.empty());
951    return kNoTimestamp();
952  }
953
954  DCHECK(selected_range_->HasNextBufferPosition());
955  if (!track_buffer_.empty())
956    return track_buffer_.front()->GetDecodeTimestamp();
957  return selected_range_->GetNextTimestamp();
958}
959
960base::TimeDelta SourceBufferStream::GetEndBufferTimestamp() {
961  if (!selected_range_)
962    return kNoTimestamp();
963  return selected_range_->GetEndTimestamp();
964}
965
966SourceBufferStream::RangeList::iterator
967SourceBufferStream::FindExistingRangeFor(base::TimeDelta start_timestamp) {
968  for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
969    if ((*itr)->BelongsToRange(start_timestamp))
970      return itr;
971  }
972  return ranges_.end();
973}
974
975SourceBufferStream::RangeList::iterator
976SourceBufferStream::AddToRanges(SourceBufferRange* new_range) {
977  base::TimeDelta start_timestamp = new_range->GetStartTimestamp();
978  RangeList::iterator itr = ranges_.end();
979  for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
980    if ((*itr)->GetStartTimestamp() > start_timestamp)
981      break;
982  }
983  return ranges_.insert(itr, new_range);
984}
985
986SourceBufferStream::RangeList::iterator
987SourceBufferStream::GetSelectedRangeItr() {
988  DCHECK(selected_range_);
989  RangeList::iterator itr = ranges_.end();
990  for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
991    if (*itr == selected_range_)
992      break;
993  }
994  DCHECK(itr != ranges_.end());
995  return itr;
996}
997
998void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) {
999  if (selected_range_)
1000    selected_range_->ResetNextBufferPosition();
1001  selected_range_ = range;
1002}
1003
1004Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const {
1005  Ranges<base::TimeDelta> ranges;
1006  for (RangeList::const_iterator itr = ranges_.begin();
1007       itr != ranges_.end(); ++itr) {
1008    ranges.Add((*itr)->GetStartTimestamp(), (*itr)->GetBufferedEndTimestamp());
1009  }
1010  return ranges;
1011}
1012
1013bool SourceBufferStream::IsEndSelected() const {
1014  return ranges_.empty() || selected_range_ == ranges_.back();
1015}
1016
1017const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() {
1018  if (config_change_pending_)
1019    CompleteConfigChange();
1020  return *audio_configs_[current_config_index_];
1021}
1022
1023const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() {
1024  if (config_change_pending_)
1025    CompleteConfigChange();
1026  return *video_configs_[current_config_index_];
1027}
1028
1029base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const {
1030  if (max_interbuffer_distance_ == kNoTimestamp())
1031    return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs);
1032  return max_interbuffer_distance_;
1033}
1034
1035bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
1036  DCHECK(!audio_configs_.empty());
1037  DCHECK(video_configs_.empty());
1038
1039  if (audio_configs_[0]->codec() != config.codec()) {
1040    DVLOG(1) << "UpdateAudioConfig() : Codec changes not allowed.";
1041    return false;
1042  }
1043
1044  if (audio_configs_[0]->samples_per_second() != config.samples_per_second()) {
1045    DVLOG(1) << "UpdateAudioConfig() : Sample rate changes not allowed.";
1046    return false;
1047  }
1048
1049  if (audio_configs_[0]->channel_layout() != config.channel_layout()) {
1050    DVLOG(1) << "UpdateAudioConfig() : Channel layout changes not allowed.";
1051    return false;
1052  }
1053
1054  if (audio_configs_[0]->bits_per_channel() != config.bits_per_channel()) {
1055    DVLOG(1) << "UpdateAudioConfig() : Bits per channel changes not allowed.";
1056    return false;
1057  }
1058
1059  // Check to see if the new config matches an existing one.
1060  for (size_t i = 0; i < audio_configs_.size(); ++i) {
1061    if (config.Matches(*audio_configs_[i])) {
1062      append_config_index_ = i;
1063      return true;
1064    }
1065  }
1066
1067  // No matches found so let's add this one to the list.
1068  append_config_index_ = audio_configs_.size();
1069  audio_configs_.resize(audio_configs_.size() + 1);
1070  audio_configs_[append_config_index_] = new AudioDecoderConfig();
1071  audio_configs_[append_config_index_]->CopyFrom(config);
1072  return true;
1073}
1074
1075bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) {
1076  DCHECK(!video_configs_.empty());
1077  DCHECK(audio_configs_.empty());
1078
1079  if (video_configs_[0]->is_encrypted() != config.is_encrypted()) {
1080    DVLOG(1) << "UpdateVideoConfig() : Encryption changes not allowed.";
1081    return false;
1082  }
1083
1084  if (video_configs_[0]->codec() != config.codec()) {
1085    DVLOG(1) << "UpdateVideoConfig() : Codec changes not allowed.";
1086    return false;
1087  }
1088
1089  // Check to see if the new config matches an existing one.
1090  for (size_t i = 0; i < video_configs_.size(); ++i) {
1091    if (config.Matches(*video_configs_[i])) {
1092      append_config_index_ = i;
1093      return true;
1094    }
1095  }
1096
1097  // No matches found so let's add this one to the list.
1098  append_config_index_ = video_configs_.size();
1099  video_configs_.resize(video_configs_.size() + 1);
1100  video_configs_[append_config_index_] = new VideoDecoderConfig();
1101  video_configs_[append_config_index_]->CopyFrom(config);
1102  return true;
1103}
1104
1105void SourceBufferStream::CompleteConfigChange() {
1106  config_change_pending_ = false;
1107
1108  if (!track_buffer_.empty()) {
1109    current_config_index_ = track_buffer_.front()->GetConfigId();
1110    return;
1111  }
1112
1113  if (selected_range_ && selected_range_->HasNextBuffer())
1114    current_config_index_ = selected_range_->GetNextConfigId();
1115}
1116
1117SourceBufferRange::SourceBufferRange(
1118    const BufferQueue& new_buffers, base::TimeDelta media_segment_start_time,
1119    const InterbufferDistanceCB& interbuffer_distance_cb)
1120    : next_buffer_index_(-1),
1121      waiting_for_keyframe_(false),
1122      next_keyframe_timestamp_(kNoTimestamp()),
1123      media_segment_start_time_(media_segment_start_time),
1124      interbuffer_distance_cb_(interbuffer_distance_cb),
1125      size_in_bytes_(0) {
1126  DCHECK(!new_buffers.empty());
1127  DCHECK(new_buffers.front()->IsKeyframe());
1128  DCHECK(!interbuffer_distance_cb.is_null());
1129  AppendBuffersToEnd(new_buffers);
1130}
1131
1132void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) {
1133  for (BufferQueue::const_iterator itr = new_buffers.begin();
1134       itr != new_buffers.end(); ++itr) {
1135    DCHECK((*itr)->GetDecodeTimestamp() != kNoTimestamp());
1136    buffers_.push_back(*itr);
1137    size_in_bytes_ += (*itr)->GetDataSize();
1138
1139    if ((*itr)->IsKeyframe()) {
1140      keyframe_map_.insert(
1141          std::make_pair((*itr)->GetDecodeTimestamp(), buffers_.size() - 1));
1142
1143      if (waiting_for_keyframe_ &&
1144          (*itr)->GetDecodeTimestamp() >= next_keyframe_timestamp_) {
1145        next_buffer_index_ = buffers_.size() - 1;
1146        next_keyframe_timestamp_ = kNoTimestamp();
1147        waiting_for_keyframe_ = false;
1148      }
1149    }
1150  }
1151}
1152
1153void SourceBufferRange::Seek(base::TimeDelta timestamp) {
1154  DCHECK(CanSeekTo(timestamp));
1155  DCHECK(!keyframe_map_.empty());
1156
1157  next_keyframe_timestamp_ = kNoTimestamp();
1158  waiting_for_keyframe_ = false;
1159
1160  KeyframeMap::iterator result = GetFirstKeyframeBefore(timestamp);
1161  next_buffer_index_ = result->second;
1162  DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
1163}
1164
1165void SourceBufferRange::SeekAheadTo(base::TimeDelta timestamp) {
1166  SeekAhead(timestamp, false);
1167}
1168
1169void SourceBufferRange::SeekAheadPast(base::TimeDelta timestamp) {
1170  SeekAhead(timestamp, true);
1171}
1172
1173void SourceBufferRange::SeekAhead(base::TimeDelta timestamp,
1174                                  bool skip_given_timestamp) {
1175  DCHECK(!keyframe_map_.empty());
1176
1177  KeyframeMap::iterator result =
1178      GetFirstKeyframeAt(timestamp, skip_given_timestamp);
1179
1180  // If there isn't a keyframe after |timestamp|, then seek to end and return
1181  // kNoTimestamp to signal such.
1182  if (result == keyframe_map_.end()) {
1183    waiting_for_keyframe_ = true;
1184    next_buffer_index_ = -1;
1185    next_keyframe_timestamp_ = timestamp;
1186    return;
1187  }
1188  next_buffer_index_ = result->second;
1189  DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
1190}
1191
1192void SourceBufferRange::SeekToStart() {
1193  DCHECK(!buffers_.empty());
1194  next_buffer_index_ = 0;
1195}
1196
1197SourceBufferRange* SourceBufferRange::SplitRange(
1198    base::TimeDelta timestamp, bool is_exclusive) {
1199  // Find the first keyframe after |timestamp|. If |is_exclusive|, do not
1200  // include keyframes at |timestamp|.
1201  KeyframeMap::iterator new_beginning_keyframe =
1202      GetFirstKeyframeAt(timestamp, is_exclusive);
1203
1204  // If there is no keyframe after |timestamp|, we can't split the range.
1205  if (new_beginning_keyframe == keyframe_map_.end())
1206    return NULL;
1207
1208  // Remove the data beginning at |keyframe_index| from |buffers_| and save it
1209  // into |removed_buffers|.
1210  int keyframe_index = new_beginning_keyframe->second;
1211  DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
1212  BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
1213  BufferQueue removed_buffers(starting_point, buffers_.end());
1214  keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end());
1215  FreeBufferRange(starting_point, buffers_.end());
1216
1217  // Create a new range with |removed_buffers|.
1218  SourceBufferRange* split_range =
1219      new SourceBufferRange(
1220          removed_buffers, kNoTimestamp(), interbuffer_distance_cb_);
1221
1222  // If the next buffer position is now in |split_range|, update the state of
1223  // this range and |split_range| accordingly.
1224  if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
1225    DCHECK(!waiting_for_keyframe_);
1226    split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index;
1227    ResetNextBufferPosition();
1228  } else if (waiting_for_keyframe_) {
1229    split_range->waiting_for_keyframe_ = true;
1230    split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_;
1231    ResetNextBufferPosition();
1232  }
1233
1234  return split_range;
1235}
1236
1237SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt(
1238    base::TimeDelta timestamp, bool skip_given_timestamp) {
1239  // Need to make a dummy buffer with timestamp |timestamp| in order to search
1240  // the |buffers_| container.
1241  scoped_refptr<StreamParserBuffer> dummy_buffer =
1242      StreamParserBuffer::CopyFrom(NULL, 0, false);
1243  dummy_buffer->SetDecodeTimestamp(timestamp);
1244
1245  if (skip_given_timestamp) {
1246    return std::upper_bound(
1247        buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator);
1248  }
1249  return std::lower_bound(
1250      buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator);
1251}
1252
1253SourceBufferRange::KeyframeMap::iterator
1254SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp,
1255                                      bool skip_given_timestamp) {
1256  return skip_given_timestamp ?
1257      keyframe_map_.upper_bound(timestamp) :
1258      keyframe_map_.lower_bound(timestamp);
1259}
1260
1261SourceBufferRange::KeyframeMap::iterator
1262SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) {
1263  KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp);
1264  // lower_bound() returns the first element >= |timestamp|, so we want the
1265  // previous element if it did not return the element exactly equal to
1266  // |timestamp|.
1267  if (result != keyframe_map_.begin() &&
1268      (result == keyframe_map_.end() || result->first != timestamp)) {
1269    --result;
1270  }
1271  return result;
1272}
1273
1274bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) {
1275  return TruncateAt(buffers_.begin(), removed_buffers);
1276}
1277
1278bool SourceBufferRange::TruncateAt(
1279    base::TimeDelta timestamp, BufferQueue* removed_buffers,
1280    bool is_exclusive) {
1281  // Find the place in |buffers_| where we will begin deleting data.
1282  BufferQueue::iterator starting_point =
1283      GetBufferItrAt(timestamp, is_exclusive);
1284  return TruncateAt(starting_point, removed_buffers);
1285}
1286
1287int SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) {
1288  DCHECK(!FirstGOPContainsNextBufferPosition());
1289  DCHECK(deleted_buffers);
1290
1291  int buffers_deleted = 0;
1292  int total_bytes_deleted = 0;
1293
1294  KeyframeMap::iterator front = keyframe_map_.begin();
1295  DCHECK(front != keyframe_map_.end());
1296
1297  // Delete the keyframe at the start of |keyframe_map_|.
1298  keyframe_map_.erase(front);
1299
1300  // Now we need to delete all the buffers that depend on the keyframe we've
1301  // just deleted.
1302  int end_index = keyframe_map_.size() > 0 ?
1303      keyframe_map_.begin()->second : buffers_.size();
1304
1305  // Delete buffers from the beginning of the buffered range up until (but not
1306  // including) the next keyframe.
1307  for (int i = 0; i < end_index; i++) {
1308    int bytes_deleted = buffers_.front()->GetDataSize();
1309    size_in_bytes_ -= bytes_deleted;
1310    total_bytes_deleted += bytes_deleted;
1311    deleted_buffers->push_back(buffers_.front());
1312    buffers_.pop_front();
1313    ++buffers_deleted;
1314  }
1315
1316  // Update indices to account for the deleted buffers.
1317  for (KeyframeMap::iterator itr = keyframe_map_.begin();
1318       itr != keyframe_map_.end(); ++itr) {
1319    itr->second -= buffers_deleted;
1320    DCHECK_GE(itr->second, 0);
1321  }
1322  if (next_buffer_index_ > -1) {
1323    next_buffer_index_ -= buffers_deleted;
1324    DCHECK_GE(next_buffer_index_, 0);
1325  }
1326
1327  // Invalidate media segment start time if we've deleted the first buffer of
1328  // the range.
1329  if (buffers_deleted > 0)
1330    media_segment_start_time_ = kNoTimestamp();
1331
1332  return total_bytes_deleted;
1333}
1334
1335int SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) {
1336  DCHECK(!LastGOPContainsNextBufferPosition());
1337  DCHECK(deleted_buffers);
1338
1339  // Remove the last GOP's keyframe from the |keyframe_map_|.
1340  KeyframeMap::iterator back = keyframe_map_.end();
1341  DCHECK_GT(keyframe_map_.size(), 0u);
1342  --back;
1343
1344  // The index of the first buffer in the last GOP is equal to the new size of
1345  // |buffers_| after that GOP is deleted.
1346  size_t goal_size = back->second;
1347  keyframe_map_.erase(back);
1348
1349  int total_bytes_deleted = 0;
1350  while (buffers_.size() != goal_size) {
1351    int bytes_deleted = buffers_.back()->GetDataSize();
1352    size_in_bytes_ -= bytes_deleted;
1353    total_bytes_deleted += bytes_deleted;
1354    // We're removing buffers from the back, so push each removed buffer to the
1355    // front of |deleted_buffers| so that |deleted_buffers| are in nondecreasing
1356    // order.
1357    deleted_buffers->push_front(buffers_.back());
1358    buffers_.pop_back();
1359  }
1360
1361  return total_bytes_deleted;
1362}
1363
1364bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const {
1365  if (!HasNextBufferPosition())
1366    return false;
1367
1368  // If there is only one GOP, it must contain the next buffer position.
1369  if (keyframe_map_.size() == 1u)
1370    return true;
1371
1372  KeyframeMap::const_iterator second_gop = keyframe_map_.begin();
1373  ++second_gop;
1374  return !waiting_for_keyframe_ && next_buffer_index_ < second_gop->second;
1375}
1376
1377bool SourceBufferRange::LastGOPContainsNextBufferPosition() const {
1378  if (!HasNextBufferPosition())
1379    return false;
1380
1381  // If there is only one GOP, it must contain the next buffer position.
1382  if (keyframe_map_.size() == 1u)
1383    return true;
1384
1385  KeyframeMap::const_iterator last_gop = keyframe_map_.end();
1386  --last_gop;
1387  return waiting_for_keyframe_ || last_gop->second <= next_buffer_index_;
1388}
1389
1390void SourceBufferRange::FreeBufferRange(
1391    const BufferQueue::iterator& starting_point,
1392    const BufferQueue::iterator& ending_point) {
1393  for (BufferQueue::iterator itr = starting_point;
1394       itr != ending_point; ++itr) {
1395    size_in_bytes_ -= (*itr)->GetDataSize();
1396    DCHECK_GE(size_in_bytes_, 0);
1397  }
1398  buffers_.erase(starting_point, ending_point);
1399}
1400
1401bool SourceBufferRange::TruncateAt(
1402    const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) {
1403  DCHECK(!removed_buffers || removed_buffers->empty());
1404
1405  // Return if we're not deleting anything.
1406  if (starting_point == buffers_.end())
1407    return false;
1408
1409  // Reset the next buffer index if we will be deleting the buffer that's next
1410  // in sequence.
1411  bool removed_next_buffer = false;
1412  if (HasNextBufferPosition()) {
1413    base::TimeDelta next_buffer_timestamp = GetNextTimestamp();
1414    if (next_buffer_timestamp == kNoTimestamp() ||
1415        next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) {
1416      if (HasNextBuffer() && removed_buffers) {
1417        int starting_offset = starting_point - buffers_.begin();
1418        int next_buffer_offset = next_buffer_index_ - starting_offset;
1419        DCHECK_GE(next_buffer_offset, 0);
1420        BufferQueue saved(starting_point + next_buffer_offset, buffers_.end());
1421        removed_buffers->swap(saved);
1422      }
1423      ResetNextBufferPosition();
1424      removed_next_buffer = true;
1425    }
1426  }
1427
1428  // Remove keyframes from |starting_point| onward.
1429  KeyframeMap::iterator starting_point_keyframe =
1430      keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp());
1431  keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end());
1432
1433  // Remove everything from |starting_point| onward.
1434  FreeBufferRange(starting_point, buffers_.end());
1435  return removed_next_buffer;
1436}
1437
1438bool SourceBufferRange::GetNextBuffer(
1439    scoped_refptr<StreamParserBuffer>* out_buffer) {
1440  if (!HasNextBuffer())
1441    return false;
1442
1443  *out_buffer = buffers_.at(next_buffer_index_);
1444  next_buffer_index_++;
1445  return true;
1446}
1447
1448bool SourceBufferRange::HasNextBuffer() const {
1449  return next_buffer_index_ >= 0 &&
1450      next_buffer_index_ < static_cast<int>(buffers_.size()) &&
1451      !waiting_for_keyframe_;
1452}
1453
1454int SourceBufferRange::GetNextConfigId() const {
1455  DCHECK(HasNextBuffer());
1456  return buffers_.at(next_buffer_index_)->GetConfigId();
1457}
1458
1459
1460base::TimeDelta SourceBufferRange::GetNextTimestamp() const {
1461  DCHECK(!buffers_.empty());
1462  DCHECK(HasNextBufferPosition());
1463
1464  if (waiting_for_keyframe_ ||
1465      next_buffer_index_ >= static_cast<int>(buffers_.size())) {
1466    return kNoTimestamp();
1467  }
1468
1469  return buffers_.at(next_buffer_index_)->GetDecodeTimestamp();
1470}
1471
1472bool SourceBufferRange::HasNextBufferPosition() const {
1473  return next_buffer_index_ >= 0 || waiting_for_keyframe_;
1474}
1475
1476void SourceBufferRange::ResetNextBufferPosition() {
1477  next_buffer_index_ = -1;
1478  waiting_for_keyframe_ = false;
1479  next_keyframe_timestamp_ = kNoTimestamp();
1480}
1481
1482void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range,
1483                                         bool transfer_current_position) {
1484  DCHECK(CanAppendRangeToEnd(range));
1485  DCHECK(!buffers_.empty());
1486
1487  if (transfer_current_position)
1488    next_buffer_index_ = range.next_buffer_index_ + buffers_.size();
1489
1490  AppendBuffersToEnd(range.buffers_);
1491}
1492
1493bool SourceBufferRange::CanAppendRangeToEnd(
1494    const SourceBufferRange& range) const {
1495  return CanAppendBuffersToEnd(range.buffers_);
1496}
1497
1498bool SourceBufferRange::CanAppendBuffersToEnd(
1499    const BufferQueue& buffers) const {
1500  DCHECK(!buffers_.empty());
1501  return IsNextInSequence(buffers_.back(),
1502                          buffers.front()->GetDecodeTimestamp());
1503}
1504
1505bool SourceBufferRange::BelongsToRange(base::TimeDelta timestamp) const {
1506  DCHECK(!buffers_.empty());
1507
1508  return (IsNextInSequence(buffers_.back(), timestamp) ||
1509          (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
1510}
1511
1512bool SourceBufferRange::CanSeekTo(base::TimeDelta timestamp) const {
1513  base::TimeDelta start_timestamp =
1514      std::max(base::TimeDelta(), GetStartTimestamp() - GetFudgeRoom());
1515  return !keyframe_map_.empty() && start_timestamp <= timestamp &&
1516      timestamp < GetBufferedEndTimestamp();
1517}
1518
1519bool SourceBufferRange::CompletelyOverlaps(
1520    const SourceBufferRange& range) const {
1521  return GetStartTimestamp() <= range.GetStartTimestamp() &&
1522      GetEndTimestamp() >= range.GetEndTimestamp();
1523}
1524
1525bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const {
1526  return range.GetStartTimestamp() <= GetEndTimestamp() &&
1527      GetEndTimestamp() < range.GetEndTimestamp();
1528}
1529
1530base::TimeDelta SourceBufferRange::GetStartTimestamp() const {
1531  DCHECK(!buffers_.empty());
1532  base::TimeDelta start_timestamp = media_segment_start_time_;
1533  if (start_timestamp == kNoTimestamp())
1534    start_timestamp = buffers_.front()->GetDecodeTimestamp();
1535  return start_timestamp;
1536}
1537
1538base::TimeDelta SourceBufferRange::GetEndTimestamp() const {
1539  DCHECK(!buffers_.empty());
1540  return buffers_.back()->GetDecodeTimestamp();
1541}
1542
1543base::TimeDelta SourceBufferRange::GetBufferedEndTimestamp() const {
1544  DCHECK(!buffers_.empty());
1545  base::TimeDelta duration = buffers_.back()->GetDuration();
1546  if (duration == kNoTimestamp() || duration == base::TimeDelta())
1547    duration = GetApproximateDuration();
1548  return GetEndTimestamp() + duration;
1549}
1550
1551bool SourceBufferRange::IsNextInSequence(
1552    const scoped_refptr<media::StreamParserBuffer>& buffer,
1553    base::TimeDelta timestamp) const {
1554  return buffer->GetDecodeTimestamp() < timestamp &&
1555      timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom();
1556}
1557
1558base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
1559  return ComputeFudgeRoom(GetApproximateDuration());
1560}
1561
1562base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
1563  base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run();
1564  DCHECK(max_interbuffer_distance != kNoTimestamp());
1565  return max_interbuffer_distance;
1566}
1567
1568}  // namespace media
1569