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