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