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.
5 #include "media/filters/source_buffer_stream.h"
10 #include "base/bind.h"
11 #include "base/debug/trace_event.h"
12 #include "base/logging.h"
13 #include "media/base/audio_splicer.h"
14 #include "media/filters/source_buffer_platform.h"
18 typedef StreamParser::BufferQueue BufferQueue;
20 // Buffers with the same timestamp are only allowed under certain conditions.
21 // More precisely, it is allowed in all situations except when the previous
22 // frame is not a key frame and the current is a key frame.
23 // Examples of situations where DTS of two consecutive frames can be equal:
24 // - Video: VP8 Alt-Ref frames.
25 // - Video: IPBPBP...: DTS for I frame and for P frame can be equal.
26 // - Text track cues that start at same time.
27 // Returns true if |prev_is_keyframe| and |current_is_keyframe| indicate a
28 // same timestamp situation that is allowed. False is returned otherwise.
29 static bool AllowSameTimestamp(
30 bool prev_is_keyframe, bool current_is_keyframe,
31 SourceBufferStream::Type type) {
32 return prev_is_keyframe || !current_is_keyframe;
35 // Returns the config ID of |buffer| if |buffer| has no splice buffers or
36 // |index| is out of range. Otherwise returns the config ID for the fade out
37 // preroll buffer at position |index|.
38 static int GetConfigId(StreamParserBuffer* buffer, size_t index) {
39 return index < buffer->splice_buffers().size()
40 ? buffer->splice_buffers()[index]->GetConfigId()
41 : buffer->GetConfigId();
44 // Helper class representing a range of buffered data. All buffers in a
45 // SourceBufferRange are ordered sequentially in presentation order with no
47 class SourceBufferRange {
49 // Returns the maximum distance in time between any buffer seen in this
50 // stream. Used to estimate the duration of a buffer if its duration is not
52 typedef base::Callback<base::TimeDelta()> InterbufferDistanceCB;
54 // Creates a source buffer range with |new_buffers|. |new_buffers| cannot be
55 // empty and the front of |new_buffers| must be a keyframe.
56 // |media_segment_start_time| refers to the starting timestamp for the media
57 // segment to which these buffers belong.
58 SourceBufferRange(SourceBufferStream::Type type,
59 const BufferQueue& new_buffers,
60 DecodeTimestamp media_segment_start_time,
61 const InterbufferDistanceCB& interbuffer_distance_cb);
63 // Appends |buffers| to the end of the range and updates |keyframe_map_| as
64 // it encounters new keyframes. Assumes |buffers| belongs at the end of the
66 void AppendBuffersToEnd(const BufferQueue& buffers);
67 bool CanAppendBuffersToEnd(const BufferQueue& buffers) const;
69 // Appends the buffers from |range| into this range.
70 // The first buffer in |range| must come directly after the last buffer
72 // If |transfer_current_position| is true, |range|'s |next_buffer_index_|
73 // is transfered to this SourceBufferRange.
74 void AppendRangeToEnd(const SourceBufferRange& range,
75 bool transfer_current_position);
76 bool CanAppendRangeToEnd(const SourceBufferRange& range) const;
78 // Updates |next_buffer_index_| to point to the Buffer containing |timestamp|.
79 // Assumes |timestamp| is valid and in this range.
80 void Seek(DecodeTimestamp timestamp);
82 // Updates |next_buffer_index_| to point to next keyframe after or equal to
84 void SeekAheadTo(DecodeTimestamp timestamp);
86 // Updates |next_buffer_index_| to point to next keyframe strictly after
88 void SeekAheadPast(DecodeTimestamp timestamp);
90 // Seeks to the beginning of the range.
93 // Finds the next keyframe from |buffers_| after |timestamp| (or at
94 // |timestamp| if |is_exclusive| is false) and creates and returns a new
95 // SourceBufferRange with the buffers from that keyframe onward.
96 // The buffers in the new SourceBufferRange are moved out of this range. If
97 // there is no keyframe after |timestamp|, SplitRange() returns null and this
98 // range is unmodified.
99 SourceBufferRange* SplitRange(DecodeTimestamp timestamp, bool is_exclusive);
101 // Deletes the buffers from this range starting at |timestamp|, exclusive if
102 // |is_exclusive| is true, inclusive otherwise.
103 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was
104 // deleted, and deletes the |keyframe_map_| entries for the buffers that
106 // |deleted_buffers| contains the buffers that were deleted from this range,
107 // starting at the buffer that had been at |next_buffer_index_|.
108 // Returns true if everything in the range was deleted. Otherwise
110 bool TruncateAt(DecodeTimestamp timestamp,
111 BufferQueue* deleted_buffers, bool is_exclusive);
112 // Deletes all buffers in range.
113 void DeleteAll(BufferQueue* deleted_buffers);
115 // Deletes a GOP from the front or back of the range and moves these
116 // buffers into |deleted_buffers|. Returns the number of bytes deleted from
117 // the range (i.e. the size in bytes of |deleted_buffers|).
118 int DeleteGOPFromFront(BufferQueue* deleted_buffers);
119 int DeleteGOPFromBack(BufferQueue* deleted_buffers);
121 // Gets the range of GOP to secure at least |bytes_to_free| from
122 // [|start_timestamp|, |end_timestamp|).
123 // Returns the size of the buffers to secure if the buffers of
124 // [|start_timestamp|, |end_removal_timestamp|) is removed.
125 // Will not update |end_removal_timestamp| if the returned size is 0.
127 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp,
128 int bytes_to_free, DecodeTimestamp* end_removal_timestamp);
130 // Indicates whether the GOP at the beginning or end of the range contains the
131 // next buffer position.
132 bool FirstGOPContainsNextBufferPosition() const;
133 bool LastGOPContainsNextBufferPosition() const;
135 // Updates |out_buffer| with the next buffer in presentation order. Seek()
136 // must be called before calls to GetNextBuffer(), and buffers are returned
137 // in order from the last call to Seek(). Returns true if |out_buffer| is
138 // filled with a valid buffer, false if there is not enough data to fulfill
140 bool GetNextBuffer(scoped_refptr<StreamParserBuffer>* out_buffer);
141 bool HasNextBuffer() const;
143 // Returns the config ID for the buffer that will be returned by
145 int GetNextConfigId() const;
147 // Returns true if the range knows the position of the next buffer it should
148 // return, i.e. it has been Seek()ed. This does not necessarily mean that it
149 // has the next buffer yet.
150 bool HasNextBufferPosition() const;
152 // Resets this range to an "unseeked" state.
153 void ResetNextBufferPosition();
155 // Returns the timestamp of the next buffer that will be returned from
156 // GetNextBuffer(), or kNoTimestamp() if the timestamp is unknown.
157 DecodeTimestamp GetNextTimestamp() const;
159 // Returns the start timestamp of the range.
160 DecodeTimestamp GetStartTimestamp() const;
162 // Returns the timestamp of the last buffer in the range.
163 DecodeTimestamp GetEndTimestamp() const;
165 // Returns the timestamp for the end of the buffered region in this range.
166 // This is an approximation if the duration for the last buffer in the range
168 DecodeTimestamp GetBufferedEndTimestamp() const;
170 // Gets the timestamp for the keyframe that is after |timestamp|. If
171 // there isn't a keyframe in the range after |timestamp| then kNoTimestamp()
172 // is returned. If |timestamp| is in the "gap" between the value returned by
173 // GetStartTimestamp() and the timestamp on the first buffer in |buffers_|,
174 // then |timestamp| is returned.
175 DecodeTimestamp NextKeyframeTimestamp(DecodeTimestamp timestamp);
177 // Gets the timestamp for the closest keyframe that is <= |timestamp|. If
178 // there isn't a keyframe before |timestamp| or |timestamp| is outside
179 // this range, then kNoTimestamp() is returned.
180 DecodeTimestamp KeyframeBeforeTimestamp(DecodeTimestamp timestamp);
182 // Returns whether a buffer with a starting timestamp of |timestamp| would
183 // belong in this range. This includes a buffer that would be appended to
184 // the end of the range.
185 bool BelongsToRange(DecodeTimestamp timestamp) const;
187 // Returns true if the range has enough data to seek to the specified
188 // |timestamp|, false otherwise.
189 bool CanSeekTo(DecodeTimestamp timestamp) const;
191 // Returns true if this range's buffered timespan completely overlaps the
192 // buffered timespan of |range|.
193 bool CompletelyOverlaps(const SourceBufferRange& range) const;
195 // Returns true if the end of this range contains buffers that overlaps with
196 // the beginning of |range|.
197 bool EndOverlaps(const SourceBufferRange& range) const;
199 // Returns true if |timestamp| is the timestamp of the next buffer in
200 // sequence after |buffers_.back()|, false otherwise.
201 bool IsNextInSequence(DecodeTimestamp timestamp, bool is_keyframe) const;
203 // Adds all buffers which overlap [start, end) to the end of |buffers|. If
204 // no buffers exist in the range returns false, true otherwise.
205 bool GetBuffersInRange(DecodeTimestamp start, DecodeTimestamp end,
206 BufferQueue* buffers);
208 int size_in_bytes() const { return size_in_bytes_; }
211 typedef std::map<DecodeTimestamp, int> KeyframeMap;
213 // Seeks the range to the next keyframe after |timestamp|. If
214 // |skip_given_timestamp| is true, the seek will go to a keyframe with a
215 // timestamp strictly greater than |timestamp|.
216 void SeekAhead(DecodeTimestamp timestamp, bool skip_given_timestamp);
218 // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|.
219 // If |skip_given_timestamp| is true, this returns the first buffer with
220 // timestamp greater than |timestamp|.
221 BufferQueue::iterator GetBufferItrAt(
222 DecodeTimestamp timestamp, bool skip_given_timestamp);
224 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after
225 // |timestamp|. If |skip_given_timestamp| is true, this returns the first
226 // keyframe with a timestamp strictly greater than |timestamp|.
227 KeyframeMap::iterator GetFirstKeyframeAt(
228 DecodeTimestamp timestamp, bool skip_given_timestamp);
230 // Returns an iterator in |keyframe_map_| pointing to the first keyframe
231 // before or at |timestamp|.
232 KeyframeMap::iterator GetFirstKeyframeBefore(DecodeTimestamp timestamp);
234 // Helper method to delete buffers in |buffers_| starting at
235 // |starting_point|, an iterator in |buffers_|.
236 // Returns true if everything in the range was removed. Returns
237 // false if the range still contains buffers.
238 bool TruncateAt(const BufferQueue::iterator& starting_point,
239 BufferQueue* deleted_buffers);
241 // Frees the buffers in |buffers_| from [|start_point|,|ending_point|) and
242 // updates the |size_in_bytes_| accordingly. Does not update |keyframe_map_|.
243 void FreeBufferRange(const BufferQueue::iterator& starting_point,
244 const BufferQueue::iterator& ending_point);
246 // Returns the distance in time estimating how far from the beginning or end
247 // of this range a buffer can be to considered in the range.
248 base::TimeDelta GetFudgeRoom() const;
250 // Returns the approximate duration of a buffer in this range.
251 base::TimeDelta GetApproximateDuration() const;
253 // Type of this stream.
254 const SourceBufferStream::Type type_;
256 // An ordered list of buffers in this range.
257 BufferQueue buffers_;
259 // Maps keyframe timestamps to its index position in |buffers_|.
260 KeyframeMap keyframe_map_;
262 // Index base of all positions in |keyframe_map_|. In other words, the
263 // real position of entry |k| of |keyframe_map_| in the range is:
264 // keyframe_map_[k] - keyframe_map_index_base_
265 int keyframe_map_index_base_;
267 // Index into |buffers_| for the next buffer to be returned by
268 // GetNextBuffer(), set to -1 before Seek().
269 int next_buffer_index_;
271 // If the first buffer in this range is the beginning of a media segment,
272 // |media_segment_start_time_| is the time when the media segment begins.
273 // |media_segment_start_time_| may be <= the timestamp of the first buffer in
274 // |buffers_|. |media_segment_start_time_| is kNoTimestamp() if this range
275 // does not start at the beginning of a media segment, which can only happen
276 // garbage collection or after an end overlap that results in a split range
277 // (we don't have a way of knowing the media segment timestamp for the new
279 DecodeTimestamp media_segment_start_time_;
281 // Called to get the largest interbuffer distance seen so far in the stream.
282 InterbufferDistanceCB interbuffer_distance_cb_;
284 // Stores the amount of memory taken up by the data in |buffers_|.
287 DISALLOW_COPY_AND_ASSIGN(SourceBufferRange);
290 // Helper method that returns true if |ranges| is sorted in increasing order,
292 static bool IsRangeListSorted(
293 const std::list<media::SourceBufferRange*>& ranges) {
294 DecodeTimestamp prev = kNoDecodeTimestamp();
295 for (std::list<SourceBufferRange*>::const_iterator itr =
296 ranges.begin(); itr != ranges.end(); ++itr) {
297 if (prev != kNoDecodeTimestamp() && prev >= (*itr)->GetStartTimestamp())
299 prev = (*itr)->GetEndTimestamp();
304 // Comparison operators for std::upper_bound() and std::lower_bound().
305 static bool CompareTimeDeltaToStreamParserBuffer(
306 const DecodeTimestamp& decode_timestamp,
307 const scoped_refptr<StreamParserBuffer>& buffer) {
308 return decode_timestamp < buffer->GetDecodeTimestamp();
310 static bool CompareStreamParserBufferToTimeDelta(
311 const scoped_refptr<StreamParserBuffer>& buffer,
312 const DecodeTimestamp& decode_timestamp) {
313 return buffer->GetDecodeTimestamp() < decode_timestamp;
316 // Returns an estimate of how far from the beginning or end of a range a buffer
317 // can be to still be considered in the range, given the |approximate_duration|
318 // of a buffer in the stream.
319 // TODO(wolenetz): Once all stream parsers emit accurate frame durations, use
320 // logic like FrameProcessor (2*last_frame_duration + last_decode_timestamp)
321 // instead of an overall maximum interbuffer delta for range discontinuity
322 // detection, and adjust similarly for splice frame discontinuity detection.
323 // See http://crbug.com/351489 and http://crbug.com/351166.
324 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) {
325 // Because we do not know exactly when is the next timestamp, any buffer
326 // that starts within 2x the approximate duration of a buffer is considered
327 // within this range.
328 return 2 * approximate_duration;
331 // An arbitrarily-chosen number to estimate the duration of a buffer if none
332 // is set and there's not enough information to get a better estimate.
333 static int kDefaultBufferDurationInMs = 125;
335 // The amount of time the beginning of the buffered data can differ from the
336 // start time in order to still be considered the start of stream.
337 static base::TimeDelta kSeekToStartFudgeRoom() {
338 return base::TimeDelta::FromMilliseconds(1000);
341 SourceBufferStream::SourceBufferStream(const AudioDecoderConfig& audio_config,
343 bool splice_frames_enabled)
345 current_config_index_(0),
346 append_config_index_(0),
347 seek_pending_(false),
348 end_of_stream_(false),
349 seek_buffer_timestamp_(kNoTimestamp()),
350 selected_range_(NULL),
351 media_segment_start_time_(kNoDecodeTimestamp()),
352 range_for_next_append_(ranges_.end()),
353 new_media_segment_(false),
354 last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
355 last_appended_buffer_is_keyframe_(false),
356 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
357 max_interbuffer_distance_(kNoTimestamp()),
358 memory_limit_(kSourceBufferAudioMemoryLimit),
359 config_change_pending_(false),
360 splice_buffers_index_(0),
361 pending_buffers_complete_(false),
362 splice_frames_enabled_(splice_frames_enabled) {
363 DCHECK(audio_config.IsValidConfig());
364 audio_configs_.push_back(audio_config);
367 SourceBufferStream::SourceBufferStream(const VideoDecoderConfig& video_config,
369 bool splice_frames_enabled)
371 current_config_index_(0),
372 append_config_index_(0),
373 seek_pending_(false),
374 end_of_stream_(false),
375 seek_buffer_timestamp_(kNoTimestamp()),
376 selected_range_(NULL),
377 media_segment_start_time_(kNoDecodeTimestamp()),
378 range_for_next_append_(ranges_.end()),
379 new_media_segment_(false),
380 last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
381 last_appended_buffer_is_keyframe_(false),
382 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
383 max_interbuffer_distance_(kNoTimestamp()),
384 memory_limit_(kSourceBufferVideoMemoryLimit),
385 config_change_pending_(false),
386 splice_buffers_index_(0),
387 pending_buffers_complete_(false),
388 splice_frames_enabled_(splice_frames_enabled) {
389 DCHECK(video_config.IsValidConfig());
390 video_configs_.push_back(video_config);
393 SourceBufferStream::SourceBufferStream(const TextTrackConfig& text_config,
395 bool splice_frames_enabled)
397 current_config_index_(0),
398 append_config_index_(0),
399 text_track_config_(text_config),
400 seek_pending_(false),
401 end_of_stream_(false),
402 seek_buffer_timestamp_(kNoTimestamp()),
403 selected_range_(NULL),
404 media_segment_start_time_(kNoDecodeTimestamp()),
405 range_for_next_append_(ranges_.end()),
406 new_media_segment_(false),
407 last_appended_buffer_timestamp_(kNoDecodeTimestamp()),
408 last_appended_buffer_is_keyframe_(false),
409 last_output_buffer_timestamp_(kNoDecodeTimestamp()),
410 max_interbuffer_distance_(kNoTimestamp()),
411 memory_limit_(kSourceBufferAudioMemoryLimit),
412 config_change_pending_(false),
413 splice_buffers_index_(0),
414 pending_buffers_complete_(false),
415 splice_frames_enabled_(splice_frames_enabled) {}
417 SourceBufferStream::~SourceBufferStream() {
418 while (!ranges_.empty()) {
419 delete ranges_.front();
424 void SourceBufferStream::OnNewMediaSegment(
425 DecodeTimestamp media_segment_start_time) {
426 DVLOG(1) << __FUNCTION__ << "(" << media_segment_start_time.InSecondsF()
428 DCHECK(!end_of_stream_);
429 media_segment_start_time_ = media_segment_start_time;
430 new_media_segment_ = true;
432 RangeList::iterator last_range = range_for_next_append_;
433 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time);
435 // Only reset |last_appended_buffer_timestamp_| if this new media segment is
436 // not adjacent to the previous media segment appended to the stream.
437 if (range_for_next_append_ == ranges_.end() ||
438 !AreAdjacentInSequence(last_appended_buffer_timestamp_,
439 media_segment_start_time)) {
440 last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
441 last_appended_buffer_is_keyframe_ = false;
442 DVLOG(3) << __FUNCTION__ << " next appended buffers will be in a new range";
443 } else if (last_range != ranges_.end()) {
444 DCHECK(last_range == range_for_next_append_);
445 DVLOG(3) << __FUNCTION__ << " next appended buffers will continue range "
446 << "unless intervening remove makes discontinuity";
450 bool SourceBufferStream::Append(const BufferQueue& buffers) {
451 TRACE_EVENT2("media", "SourceBufferStream::Append",
452 "stream type", GetStreamTypeName(),
453 "buffers to append", buffers.size());
455 DCHECK(!buffers.empty());
456 DCHECK(media_segment_start_time_ != kNoDecodeTimestamp());
457 DCHECK(media_segment_start_time_ <= buffers.front()->GetDecodeTimestamp());
458 DCHECK(!end_of_stream_);
460 // New media segments must begin with a keyframe.
461 if (new_media_segment_ && !buffers.front()->IsKeyframe()) {
462 MEDIA_LOG(log_cb_) << "Media segment did not begin with keyframe.";
466 // Buffers within a media segment should be monotonically increasing.
467 if (!IsMonotonicallyIncreasing(buffers))
470 if (media_segment_start_time_ < DecodeTimestamp() ||
471 buffers.front()->GetDecodeTimestamp() < DecodeTimestamp()) {
473 << "Cannot append a media segment with negative timestamps.";
477 if (!IsNextTimestampValid(buffers.front()->GetDecodeTimestamp(),
478 buffers.front()->IsKeyframe())) {
479 MEDIA_LOG(log_cb_) << "Invalid same timestamp construct detected at time "
480 << buffers.front()->GetDecodeTimestamp().InSecondsF();
485 UpdateMaxInterbufferDistance(buffers);
486 SetConfigIds(buffers);
488 // Save a snapshot of stream state before range modifications are made.
489 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
490 BufferQueue deleted_buffers;
492 PrepareRangesForNextAppend(buffers, &deleted_buffers);
494 // If there's a range for |buffers|, insert |buffers| accordingly. Otherwise,
495 // create a new range with |buffers|.
496 if (range_for_next_append_ != ranges_.end()) {
497 (*range_for_next_append_)->AppendBuffersToEnd(buffers);
498 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
499 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe();
501 DecodeTimestamp new_range_start_time = std::min(
502 media_segment_start_time_, buffers.front()->GetDecodeTimestamp());
503 const BufferQueue* buffers_for_new_range = &buffers;
504 BufferQueue trimmed_buffers;
506 // If the new range is not being created because of a new media
507 // segment, then we must make sure that we start with a keyframe.
508 // This can happen if the GOP in the previous append gets destroyed
509 // by a Remove() call.
510 if (!new_media_segment_) {
511 BufferQueue::const_iterator itr = buffers.begin();
513 // Scan past all the non-keyframes.
514 while (itr != buffers.end() && !(*itr)->IsKeyframe()) {
518 // If we didn't find a keyframe, then update the last appended
519 // buffer state and return.
520 if (itr == buffers.end()) {
521 last_appended_buffer_timestamp_ = buffers.back()->GetDecodeTimestamp();
522 last_appended_buffer_is_keyframe_ = buffers.back()->IsKeyframe();
524 } else if (itr != buffers.begin()) {
525 // Copy the first keyframe and everything after it into
526 // |trimmed_buffers|.
527 trimmed_buffers.assign(itr, buffers.end());
528 buffers_for_new_range = &trimmed_buffers;
531 new_range_start_time =
532 buffers_for_new_range->front()->GetDecodeTimestamp();
535 range_for_next_append_ =
536 AddToRanges(new SourceBufferRange(
537 GetType(), *buffers_for_new_range, new_range_start_time,
538 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
539 base::Unretained(this))));
540 last_appended_buffer_timestamp_ =
541 buffers_for_new_range->back()->GetDecodeTimestamp();
542 last_appended_buffer_is_keyframe_ =
543 buffers_for_new_range->back()->IsKeyframe();
546 new_media_segment_ = false;
548 MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
550 // Seek to try to fulfill a previous call to Seek().
552 DCHECK(!selected_range_);
553 DCHECK(deleted_buffers.empty());
554 Seek(seek_buffer_timestamp_);
557 if (!deleted_buffers.empty()) {
558 DecodeTimestamp start_of_deleted =
559 deleted_buffers.front()->GetDecodeTimestamp();
561 DCHECK(track_buffer_.empty() ||
562 track_buffer_.back()->GetDecodeTimestamp() < start_of_deleted)
563 << "decode timestamp "
564 << track_buffer_.back()->GetDecodeTimestamp().InSecondsF() << " sec"
565 << ", start_of_deleted " << start_of_deleted.InSecondsF()<< " sec";
567 track_buffer_.insert(track_buffer_.end(), deleted_buffers.begin(),
568 deleted_buffers.end());
571 // Prune any extra buffers in |track_buffer_| if new keyframes
572 // are appended to the range covered by |track_buffer_|.
573 if (!track_buffer_.empty()) {
574 DecodeTimestamp keyframe_timestamp =
575 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp());
576 if (keyframe_timestamp != kNoDecodeTimestamp())
577 PruneTrackBuffer(keyframe_timestamp);
580 SetSelectedRangeIfNeeded(next_buffer_timestamp);
582 GarbageCollectIfNeeded();
584 DCHECK(IsRangeListSorted(ranges_));
585 DCHECK(OnlySelectedRangeIsSeeked());
589 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end,
590 base::TimeDelta duration) {
591 DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF()
592 << ", " << end.InSecondsF()
593 << ", " << duration.InSecondsF() << ")";
594 DCHECK(start >= base::TimeDelta()) << start.InSecondsF();
595 DCHECK(start < end) << "start " << start.InSecondsF()
596 << " end " << end.InSecondsF();
597 DCHECK(duration != kNoTimestamp());
599 DecodeTimestamp start_dts = DecodeTimestamp::FromPresentationTime(start);
600 DecodeTimestamp end_dts = DecodeTimestamp::FromPresentationTime(end);
601 DecodeTimestamp remove_end_timestamp =
602 DecodeTimestamp::FromPresentationTime(duration);
603 DecodeTimestamp keyframe_timestamp = FindKeyframeAfterTimestamp(end_dts);
604 if (keyframe_timestamp != kNoDecodeTimestamp()) {
605 remove_end_timestamp = keyframe_timestamp;
606 } else if (end_dts < remove_end_timestamp) {
607 remove_end_timestamp = end_dts;
610 BufferQueue deleted_buffers;
611 RemoveInternal(start_dts, remove_end_timestamp, false, &deleted_buffers);
613 if (!deleted_buffers.empty())
614 SetSelectedRangeIfNeeded(deleted_buffers.front()->GetDecodeTimestamp());
617 void SourceBufferStream::RemoveInternal(
618 DecodeTimestamp start, DecodeTimestamp end, bool is_exclusive,
619 BufferQueue* deleted_buffers) {
620 DVLOG(1) << __FUNCTION__ << "(" << start.InSecondsF()
621 << ", " << end.InSecondsF()
622 << ", " << is_exclusive << ")";
624 DCHECK(start >= DecodeTimestamp());
625 DCHECK(start < end) << "start " << start.InSecondsF()
626 << " end " << end.InSecondsF();
627 DCHECK(deleted_buffers);
629 RangeList::iterator itr = ranges_.begin();
631 while (itr != ranges_.end()) {
632 SourceBufferRange* range = *itr;
633 if (range->GetStartTimestamp() >= end)
636 // Split off any remaining end piece and add it to |ranges_|.
637 SourceBufferRange* new_range = range->SplitRange(end, is_exclusive);
639 itr = ranges_.insert(++itr, new_range);
642 // Update the selected range if the next buffer position was transferred
644 if (new_range->HasNextBufferPosition())
645 SetSelectedRange(new_range);
648 // Truncate the current range so that it only contains data before
649 // the removal range.
650 BufferQueue saved_buffers;
651 bool delete_range = range->TruncateAt(start, &saved_buffers, is_exclusive);
653 // Check to see if the current playback position was removed and
654 // update the selected range appropriately.
655 if (!saved_buffers.empty()) {
656 DCHECK(!range->HasNextBufferPosition());
657 DCHECK(deleted_buffers->empty());
659 *deleted_buffers = saved_buffers;
662 if (range == selected_range_ && !range->HasNextBufferPosition())
663 SetSelectedRange(NULL);
665 // If the current range now is completely covered by the removal
666 // range then delete it and move on.
668 DeleteAndRemoveRange(&itr);
672 // Clear |range_for_next_append_| if we determine that the removal
673 // operation makes it impossible for the next append to be added
674 // to the current range.
675 if (range_for_next_append_ != ranges_.end() &&
676 *range_for_next_append_ == range &&
677 last_appended_buffer_timestamp_ != kNoDecodeTimestamp()) {
678 DecodeTimestamp potential_next_append_timestamp =
679 last_appended_buffer_timestamp_ +
680 base::TimeDelta::FromInternalValue(1);
682 if (!range->BelongsToRange(potential_next_append_timestamp)) {
683 DVLOG(1) << "Resetting range_for_next_append_ since the next append"
684 << " can't add to the current range.";
685 range_for_next_append_ =
686 FindExistingRangeFor(potential_next_append_timestamp);
690 // Move on to the next range.
694 DCHECK(IsRangeListSorted(ranges_));
695 DCHECK(OnlySelectedRangeIsSeeked());
696 DVLOG(1) << __FUNCTION__ << " : done";
699 void SourceBufferStream::ResetSeekState() {
700 SetSelectedRange(NULL);
701 track_buffer_.clear();
702 config_change_pending_ = false;
703 last_output_buffer_timestamp_ = kNoDecodeTimestamp();
704 splice_buffers_index_ = 0;
705 pending_buffer_ = NULL;
706 pending_buffers_complete_ = false;
709 bool SourceBufferStream::ShouldSeekToStartOfBuffered(
710 base::TimeDelta seek_timestamp) const {
713 base::TimeDelta beginning_of_buffered =
714 ranges_.front()->GetStartTimestamp().ToPresentationTime();
715 return (seek_timestamp <= beginning_of_buffered &&
716 beginning_of_buffered < kSeekToStartFudgeRoom());
719 bool SourceBufferStream::IsMonotonicallyIncreasing(
720 const BufferQueue& buffers) const {
721 DCHECK(!buffers.empty());
722 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
723 bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
724 for (BufferQueue::const_iterator itr = buffers.begin();
725 itr != buffers.end(); ++itr) {
726 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp();
727 bool current_is_keyframe = (*itr)->IsKeyframe();
728 DCHECK(current_timestamp != kNoDecodeTimestamp());
729 DCHECK((*itr)->duration() >= base::TimeDelta())
730 << "Packet with invalid duration."
731 << " pts " << (*itr)->timestamp().InSecondsF()
732 << " dts " << (*itr)->GetDecodeTimestamp().InSecondsF()
733 << " dur " << (*itr)->duration().InSecondsF();
735 if (prev_timestamp != kNoDecodeTimestamp()) {
736 if (current_timestamp < prev_timestamp) {
737 MEDIA_LOG(log_cb_) << "Buffers were not monotonically increasing.";
741 if (current_timestamp == prev_timestamp &&
742 !AllowSameTimestamp(prev_is_keyframe, current_is_keyframe,
744 MEDIA_LOG(log_cb_) << "Unexpected combination of buffers with the"
745 << " same timestamp detected at "
746 << current_timestamp.InSecondsF();
751 prev_timestamp = current_timestamp;
752 prev_is_keyframe = current_is_keyframe;
757 bool SourceBufferStream::IsNextTimestampValid(
758 DecodeTimestamp next_timestamp, bool next_is_keyframe) const {
759 return (last_appended_buffer_timestamp_ != next_timestamp) ||
760 new_media_segment_ ||
761 AllowSameTimestamp(last_appended_buffer_is_keyframe_, next_is_keyframe,
766 bool SourceBufferStream::OnlySelectedRangeIsSeeked() const {
767 for (RangeList::const_iterator itr = ranges_.begin();
768 itr != ranges_.end(); ++itr) {
769 if ((*itr)->HasNextBufferPosition() && (*itr) != selected_range_)
772 return !selected_range_ || selected_range_->HasNextBufferPosition();
775 void SourceBufferStream::UpdateMaxInterbufferDistance(
776 const BufferQueue& buffers) {
777 DCHECK(!buffers.empty());
778 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
779 for (BufferQueue::const_iterator itr = buffers.begin();
780 itr != buffers.end(); ++itr) {
781 DecodeTimestamp current_timestamp = (*itr)->GetDecodeTimestamp();
782 DCHECK(current_timestamp != kNoDecodeTimestamp());
784 base::TimeDelta interbuffer_distance = (*itr)->duration();
785 DCHECK(interbuffer_distance >= base::TimeDelta());
787 if (prev_timestamp != kNoDecodeTimestamp()) {
788 interbuffer_distance =
789 std::max(current_timestamp - prev_timestamp, interbuffer_distance);
792 if (interbuffer_distance > base::TimeDelta()) {
793 if (max_interbuffer_distance_ == kNoTimestamp()) {
794 max_interbuffer_distance_ = interbuffer_distance;
796 max_interbuffer_distance_ =
797 std::max(max_interbuffer_distance_, interbuffer_distance);
800 prev_timestamp = current_timestamp;
804 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) {
805 for (BufferQueue::const_iterator itr = buffers.begin();
806 itr != buffers.end(); ++itr) {
807 (*itr)->SetConfigId(append_config_index_);
811 void SourceBufferStream::GarbageCollectIfNeeded() {
812 // Compute size of |ranges_|.
814 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr)
815 ranges_size += (*itr)->size_in_bytes();
817 // Return if we're under or at the memory limit.
818 if (ranges_size <= memory_limit_)
821 int bytes_to_free = ranges_size - memory_limit_;
823 // Begin deleting after the last appended buffer.
824 int bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free);
826 // Begin deleting from the front.
827 if (bytes_to_free - bytes_freed > 0)
828 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false);
830 // Begin deleting from the back.
831 if (bytes_to_free - bytes_freed > 0)
832 FreeBuffers(bytes_to_free - bytes_freed, true);
835 int SourceBufferStream::FreeBuffersAfterLastAppended(int total_bytes_to_free) {
836 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp();
837 if (last_appended_buffer_timestamp_ == kNoDecodeTimestamp() ||
838 next_buffer_timestamp == kNoDecodeTimestamp() ||
839 last_appended_buffer_timestamp_ >= next_buffer_timestamp) {
843 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_;
844 if (last_appended_buffer_is_keyframe_)
845 remove_range_start += GetMaxInterbufferDistance();
847 DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp(
849 if (remove_range_start_keyframe != kNoDecodeTimestamp())
850 remove_range_start = remove_range_start_keyframe;
851 if (remove_range_start >= next_buffer_timestamp)
854 DecodeTimestamp remove_range_end;
855 int bytes_freed = GetRemovalRange(
856 remove_range_start, next_buffer_timestamp, total_bytes_to_free,
858 if (bytes_freed > 0) {
859 Remove(remove_range_start.ToPresentationTime(),
860 remove_range_end.ToPresentationTime(),
861 next_buffer_timestamp.ToPresentationTime());
867 int SourceBufferStream::GetRemovalRange(
868 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp,
869 int total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) {
870 DCHECK(start_timestamp >= DecodeTimestamp()) << start_timestamp.InSecondsF();
871 DCHECK(start_timestamp < end_timestamp)
872 << "start " << start_timestamp.InSecondsF()
873 << ", end " << end_timestamp.InSecondsF();
875 int bytes_to_free = total_bytes_to_free;
878 for (RangeList::iterator itr = ranges_.begin();
879 itr != ranges_.end() && bytes_to_free > 0; ++itr) {
880 SourceBufferRange* range = *itr;
881 if (range->GetStartTimestamp() >= end_timestamp)
883 if (range->GetEndTimestamp() < start_timestamp)
886 int bytes_removed = range->GetRemovalGOP(
887 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp);
888 bytes_to_free -= bytes_removed;
889 bytes_freed += bytes_removed;
894 int SourceBufferStream::FreeBuffers(int total_bytes_to_free,
895 bool reverse_direction) {
896 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers",
897 "total bytes to free", total_bytes_to_free,
898 "reverse direction", reverse_direction);
900 DCHECK_GT(total_bytes_to_free, 0);
901 int bytes_to_free = total_bytes_to_free;
904 // This range will save the last GOP appended to |range_for_next_append_|
905 // if the buffers surrounding it get deleted during garbage collection.
906 SourceBufferRange* new_range_for_append = NULL;
908 while (!ranges_.empty() && bytes_to_free > 0) {
909 SourceBufferRange* current_range = NULL;
911 int bytes_deleted = 0;
913 if (reverse_direction) {
914 current_range = ranges_.back();
915 if (current_range->LastGOPContainsNextBufferPosition()) {
916 DCHECK_EQ(current_range, selected_range_);
919 bytes_deleted = current_range->DeleteGOPFromBack(&buffers);
921 current_range = ranges_.front();
922 if (current_range->FirstGOPContainsNextBufferPosition()) {
923 DCHECK_EQ(current_range, selected_range_);
926 bytes_deleted = current_range->DeleteGOPFromFront(&buffers);
929 // Check to see if we've just deleted the GOP that was last appended.
930 DecodeTimestamp end_timestamp = buffers.back()->GetDecodeTimestamp();
931 if (end_timestamp == last_appended_buffer_timestamp_) {
932 DCHECK(last_appended_buffer_timestamp_ != kNoDecodeTimestamp());
933 DCHECK(!new_range_for_append);
934 // Create a new range containing these buffers.
935 new_range_for_append = new SourceBufferRange(
936 GetType(), buffers, kNoDecodeTimestamp(),
937 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance,
938 base::Unretained(this)));
939 range_for_next_append_ = ranges_.end();
941 bytes_to_free -= bytes_deleted;
942 bytes_freed += bytes_deleted;
945 if (current_range->size_in_bytes() == 0) {
946 DCHECK_NE(current_range, selected_range_);
947 DCHECK(range_for_next_append_ == ranges_.end() ||
948 *range_for_next_append_ != current_range);
949 delete current_range;
950 reverse_direction ? ranges_.pop_back() : ranges_.pop_front();
954 // Insert |new_range_for_append| into |ranges_|, if applicable.
955 if (new_range_for_append) {
956 range_for_next_append_ = AddToRanges(new_range_for_append);
957 DCHECK(range_for_next_append_ != ranges_.end());
959 // Check to see if we need to merge |new_range_for_append| with the range
960 // before or after it. |new_range_for_append| is created whenever the last
961 // GOP appended is encountered, regardless of whether any buffers after it
962 // are ultimately deleted. Merging is necessary if there were no buffers
963 // (or very few buffers) deleted after creating |new_range_for_append|.
964 if (range_for_next_append_ != ranges_.begin()) {
965 RangeList::iterator range_before_next = range_for_next_append_;
967 MergeWithAdjacentRangeIfNecessary(range_before_next);
969 MergeWithAdjacentRangeIfNecessary(range_for_next_append_);
974 void SourceBufferStream::PrepareRangesForNextAppend(
975 const BufferQueue& new_buffers, BufferQueue* deleted_buffers) {
976 DCHECK(deleted_buffers);
978 bool temporarily_select_range = false;
979 if (!track_buffer_.empty()) {
980 DecodeTimestamp tb_timestamp = track_buffer_.back()->GetDecodeTimestamp();
981 DecodeTimestamp seek_timestamp = FindKeyframeAfterTimestamp(tb_timestamp);
982 if (seek_timestamp != kNoDecodeTimestamp() &&
983 seek_timestamp < new_buffers.front()->GetDecodeTimestamp() &&
984 range_for_next_append_ != ranges_.end() &&
985 (*range_for_next_append_)->BelongsToRange(seek_timestamp)) {
986 DCHECK(tb_timestamp < seek_timestamp);
987 DCHECK(!selected_range_);
988 DCHECK(!(*range_for_next_append_)->HasNextBufferPosition());
990 // If there are GOPs between the end of the track buffer and the
991 // beginning of the new buffers, then temporarily seek the range
992 // so that the buffers between these two times will be deposited in
993 // |deleted_buffers| as if they were part of the current playback
995 // TODO(acolwell): Figure out a more elegant way to do this.
996 SeekAndSetSelectedRange(*range_for_next_append_, seek_timestamp);
997 temporarily_select_range = true;
1001 // Handle splices between the existing buffers and the new buffers. If a
1002 // splice is generated the timestamp and duration of the first buffer in
1003 // |new_buffers| will be modified.
1004 if (splice_frames_enabled_)
1005 GenerateSpliceFrame(new_buffers);
1007 DecodeTimestamp prev_timestamp = last_appended_buffer_timestamp_;
1008 bool prev_is_keyframe = last_appended_buffer_is_keyframe_;
1009 DecodeTimestamp next_timestamp = new_buffers.front()->GetDecodeTimestamp();
1010 bool next_is_keyframe = new_buffers.front()->IsKeyframe();
1012 if (prev_timestamp != kNoDecodeTimestamp() &&
1013 prev_timestamp != next_timestamp) {
1014 // Clean up the old buffers between the last appended buffer and the
1015 // beginning of |new_buffers|.
1016 RemoveInternal(prev_timestamp, next_timestamp, true, deleted_buffers);
1019 // Make the delete range exclusive if we are dealing with an allowed same
1020 // timestamp situation. This prevents the first buffer in the current append
1021 // from deleting the last buffer in the previous append if both buffers
1022 // have the same timestamp.
1024 // The delete range should never be exclusive if a splice frame was generated
1025 // because we don't generate splice frames for same timestamp situations.
1026 DCHECK(new_buffers.front()->splice_timestamp() !=
1027 new_buffers.front()->timestamp());
1028 const bool is_exclusive =
1029 new_buffers.front()->splice_buffers().empty() &&
1030 prev_timestamp == next_timestamp &&
1031 AllowSameTimestamp(prev_is_keyframe, next_is_keyframe, GetType());
1033 // Delete the buffers that |new_buffers| overlaps.
1034 DecodeTimestamp start = new_buffers.front()->GetDecodeTimestamp();
1035 DecodeTimestamp end = new_buffers.back()->GetDecodeTimestamp();
1036 base::TimeDelta duration = new_buffers.back()->duration();
1038 if (duration != kNoTimestamp() && duration > base::TimeDelta()) {
1041 // TODO(acolwell): Ensure all buffers actually have proper
1042 // duration info so that this hack isn't needed.
1043 // http://crbug.com/312836
1044 end += base::TimeDelta::FromInternalValue(1);
1047 RemoveInternal(start, end, is_exclusive, deleted_buffers);
1049 // Restore the range seek state if necessary.
1050 if (temporarily_select_range)
1051 SetSelectedRange(NULL);
1054 bool SourceBufferStream::AreAdjacentInSequence(
1055 DecodeTimestamp first_timestamp, DecodeTimestamp second_timestamp) const {
1056 return first_timestamp < second_timestamp &&
1058 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
1061 void SourceBufferStream::PruneTrackBuffer(const DecodeTimestamp timestamp) {
1062 // If we don't have the next timestamp, we don't have anything to delete.
1063 if (timestamp == kNoDecodeTimestamp())
1066 while (!track_buffer_.empty() &&
1067 track_buffer_.back()->GetDecodeTimestamp() >= timestamp) {
1068 track_buffer_.pop_back();
1072 void SourceBufferStream::MergeWithAdjacentRangeIfNecessary(
1073 const RangeList::iterator& range_with_new_buffers_itr) {
1074 DCHECK(range_with_new_buffers_itr != ranges_.end());
1076 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr;
1077 RangeList::iterator next_range_itr = range_with_new_buffers_itr;
1080 if (next_range_itr == ranges_.end() ||
1081 !range_with_new_buffers->CanAppendRangeToEnd(**next_range_itr)) {
1085 bool transfer_current_position = selected_range_ == *next_range_itr;
1086 range_with_new_buffers->AppendRangeToEnd(**next_range_itr,
1087 transfer_current_position);
1088 // Update |selected_range_| pointer if |range| has become selected after
1090 if (transfer_current_position)
1091 SetSelectedRange(range_with_new_buffers);
1093 if (next_range_itr == range_for_next_append_)
1094 range_for_next_append_ = range_with_new_buffers_itr;
1096 DeleteAndRemoveRange(&next_range_itr);
1099 void SourceBufferStream::Seek(base::TimeDelta timestamp) {
1100 DCHECK(timestamp >= base::TimeDelta());
1103 if (ShouldSeekToStartOfBuffered(timestamp)) {
1104 ranges_.front()->SeekToStart();
1105 SetSelectedRange(ranges_.front());
1106 seek_pending_ = false;
1110 seek_buffer_timestamp_ = timestamp;
1111 seek_pending_ = true;
1113 DecodeTimestamp seek_dts = DecodeTimestamp::FromPresentationTime(timestamp);
1115 RangeList::iterator itr = ranges_.end();
1116 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1117 if ((*itr)->CanSeekTo(seek_dts))
1121 if (itr == ranges_.end())
1124 SeekAndSetSelectedRange(*itr, seek_dts);
1125 seek_pending_ = false;
1128 bool SourceBufferStream::IsSeekPending() const {
1129 return !(end_of_stream_ && IsEndSelected()) && seek_pending_;
1132 void SourceBufferStream::OnSetDuration(base::TimeDelta duration) {
1133 DecodeTimestamp duration_dts =
1134 DecodeTimestamp::FromPresentationTime(duration);
1136 RangeList::iterator itr = ranges_.end();
1137 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1138 if ((*itr)->GetEndTimestamp() > duration_dts)
1141 if (itr == ranges_.end())
1144 // Need to partially truncate this range.
1145 if ((*itr)->GetStartTimestamp() < duration_dts) {
1146 bool delete_range = (*itr)->TruncateAt(duration_dts, NULL, false);
1147 if ((*itr == selected_range_) && !selected_range_->HasNextBufferPosition())
1148 SetSelectedRange(NULL);
1151 DeleteAndRemoveRange(&itr);
1157 // Delete all ranges that begin after |duration_dts|.
1158 while (itr != ranges_.end()) {
1159 // If we're about to delete the selected range, also reset the seek state.
1160 DCHECK((*itr)->GetStartTimestamp() >= duration_dts);
1161 if (*itr == selected_range_)
1163 DeleteAndRemoveRange(&itr);
1167 SourceBufferStream::Status SourceBufferStream::GetNextBuffer(
1168 scoped_refptr<StreamParserBuffer>* out_buffer) {
1169 if (!pending_buffer_) {
1170 const SourceBufferStream::Status status = GetNextBufferInternal(out_buffer);
1171 if (status != SourceBufferStream::kSuccess || !SetPendingBuffer(out_buffer))
1175 if (!pending_buffer_->splice_buffers().empty())
1176 return HandleNextBufferWithSplice(out_buffer);
1178 DCHECK(pending_buffer_->preroll_buffer());
1179 return HandleNextBufferWithPreroll(out_buffer);
1182 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithSplice(
1183 scoped_refptr<StreamParserBuffer>* out_buffer) {
1184 const BufferQueue& splice_buffers = pending_buffer_->splice_buffers();
1185 const size_t last_splice_buffer_index = splice_buffers.size() - 1;
1187 // Are there any splice buffers left to hand out? The last buffer should be
1188 // handed out separately since it represents the first post-splice buffer.
1189 if (splice_buffers_index_ < last_splice_buffer_index) {
1190 // Account for config changes which occur between fade out buffers.
1191 if (current_config_index_ !=
1192 splice_buffers[splice_buffers_index_]->GetConfigId()) {
1193 config_change_pending_ = true;
1194 DVLOG(1) << "Config change (splice buffer config ID does not match).";
1195 return SourceBufferStream::kConfigChange;
1198 // Every pre splice buffer must have the same splice_timestamp().
1199 DCHECK(pending_buffer_->splice_timestamp() ==
1200 splice_buffers[splice_buffers_index_]->splice_timestamp());
1202 // No pre splice buffers should have preroll.
1203 DCHECK(!splice_buffers[splice_buffers_index_]->preroll_buffer());
1205 *out_buffer = splice_buffers[splice_buffers_index_++];
1206 return SourceBufferStream::kSuccess;
1209 // Did we hand out the last pre-splice buffer on the previous call?
1210 if (!pending_buffers_complete_) {
1211 DCHECK_EQ(splice_buffers_index_, last_splice_buffer_index);
1212 pending_buffers_complete_ = true;
1213 config_change_pending_ = true;
1214 DVLOG(1) << "Config change (forced for fade in of splice frame).";
1215 return SourceBufferStream::kConfigChange;
1218 // All pre-splice buffers have been handed out and a config change completed,
1219 // so hand out the final buffer for fade in. Because a config change is
1220 // always issued prior to handing out this buffer, any changes in config id
1221 // have been inherently handled.
1222 DCHECK(pending_buffers_complete_);
1223 DCHECK_EQ(splice_buffers_index_, splice_buffers.size() - 1);
1224 DCHECK(splice_buffers.back()->splice_timestamp() == kNoTimestamp());
1225 *out_buffer = splice_buffers.back();
1226 pending_buffer_ = NULL;
1228 // If the last splice buffer has preroll, hand off to the preroll handler.
1229 return SetPendingBuffer(out_buffer) ? HandleNextBufferWithPreroll(out_buffer)
1230 : SourceBufferStream::kSuccess;
1233 SourceBufferStream::Status SourceBufferStream::HandleNextBufferWithPreroll(
1234 scoped_refptr<StreamParserBuffer>* out_buffer) {
1235 // Any config change should have already been handled.
1236 DCHECK_EQ(current_config_index_, pending_buffer_->GetConfigId());
1238 // Check if the preroll buffer has already been handed out.
1239 if (!pending_buffers_complete_) {
1240 pending_buffers_complete_ = true;
1241 *out_buffer = pending_buffer_->preroll_buffer();
1242 return SourceBufferStream::kSuccess;
1245 // Preroll complete, hand out the final buffer.
1246 *out_buffer = pending_buffer_;
1247 pending_buffer_ = NULL;
1248 return SourceBufferStream::kSuccess;
1251 SourceBufferStream::Status SourceBufferStream::GetNextBufferInternal(
1252 scoped_refptr<StreamParserBuffer>* out_buffer) {
1253 CHECK(!config_change_pending_);
1255 if (!track_buffer_.empty()) {
1256 DCHECK(!selected_range_);
1257 scoped_refptr<StreamParserBuffer>& next_buffer = track_buffer_.front();
1259 // If the next buffer is an audio splice frame, the next effective config id
1260 // comes from the first splice buffer.
1261 if (GetConfigId(next_buffer, 0) != current_config_index_) {
1262 config_change_pending_ = true;
1263 DVLOG(1) << "Config change (track buffer config ID does not match).";
1264 return kConfigChange;
1267 *out_buffer = next_buffer;
1268 track_buffer_.pop_front();
1269 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
1271 // If the track buffer becomes empty, then try to set the selected range
1272 // based on the timestamp of this buffer being returned.
1273 if (track_buffer_.empty())
1274 SetSelectedRangeIfNeeded(last_output_buffer_timestamp_);
1279 if (!selected_range_ || !selected_range_->HasNextBuffer()) {
1280 if (end_of_stream_ && IsEndSelected())
1281 return kEndOfStream;
1285 if (selected_range_->GetNextConfigId() != current_config_index_) {
1286 config_change_pending_ = true;
1287 DVLOG(1) << "Config change (selected range config ID does not match).";
1288 return kConfigChange;
1291 CHECK(selected_range_->GetNextBuffer(out_buffer));
1292 last_output_buffer_timestamp_ = (*out_buffer)->GetDecodeTimestamp();
1296 DecodeTimestamp SourceBufferStream::GetNextBufferTimestamp() {
1297 if (!track_buffer_.empty())
1298 return track_buffer_.front()->GetDecodeTimestamp();
1300 if (!selected_range_)
1301 return kNoDecodeTimestamp();
1303 DCHECK(selected_range_->HasNextBufferPosition());
1304 return selected_range_->GetNextTimestamp();
1307 SourceBufferStream::RangeList::iterator
1308 SourceBufferStream::FindExistingRangeFor(DecodeTimestamp start_timestamp) {
1309 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1310 if ((*itr)->BelongsToRange(start_timestamp))
1313 return ranges_.end();
1316 SourceBufferStream::RangeList::iterator
1317 SourceBufferStream::AddToRanges(SourceBufferRange* new_range) {
1318 DecodeTimestamp start_timestamp = new_range->GetStartTimestamp();
1319 RangeList::iterator itr = ranges_.end();
1320 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1321 if ((*itr)->GetStartTimestamp() > start_timestamp)
1324 return ranges_.insert(itr, new_range);
1327 SourceBufferStream::RangeList::iterator
1328 SourceBufferStream::GetSelectedRangeItr() {
1329 DCHECK(selected_range_);
1330 RangeList::iterator itr = ranges_.end();
1331 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) {
1332 if (*itr == selected_range_)
1335 DCHECK(itr != ranges_.end());
1339 void SourceBufferStream::SeekAndSetSelectedRange(
1340 SourceBufferRange* range, DecodeTimestamp seek_timestamp) {
1342 range->Seek(seek_timestamp);
1343 SetSelectedRange(range);
1346 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) {
1347 DVLOG(1) << __FUNCTION__ << " : " << selected_range_ << " -> " << range;
1348 if (selected_range_)
1349 selected_range_->ResetNextBufferPosition();
1350 DCHECK(!range || range->HasNextBufferPosition());
1351 selected_range_ = range;
1354 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const {
1355 Ranges<base::TimeDelta> ranges;
1356 for (RangeList::const_iterator itr = ranges_.begin();
1357 itr != ranges_.end(); ++itr) {
1358 ranges.Add((*itr)->GetStartTimestamp().ToPresentationTime(),
1359 (*itr)->GetBufferedEndTimestamp().ToPresentationTime());
1364 base::TimeDelta SourceBufferStream::GetBufferedDuration() const {
1365 if (ranges_.empty())
1366 return base::TimeDelta();
1368 return ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime();
1371 void SourceBufferStream::MarkEndOfStream() {
1372 DCHECK(!end_of_stream_);
1373 end_of_stream_ = true;
1376 void SourceBufferStream::UnmarkEndOfStream() {
1377 DCHECK(end_of_stream_);
1378 end_of_stream_ = false;
1381 bool SourceBufferStream::IsEndSelected() const {
1382 if (ranges_.empty())
1385 if (seek_pending_) {
1386 base::TimeDelta last_range_end_time =
1387 ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime();
1388 return seek_buffer_timestamp_ >= last_range_end_time;
1391 return selected_range_ == ranges_.back();
1394 const AudioDecoderConfig& SourceBufferStream::GetCurrentAudioDecoderConfig() {
1395 if (config_change_pending_)
1396 CompleteConfigChange();
1397 return audio_configs_[current_config_index_];
1400 const VideoDecoderConfig& SourceBufferStream::GetCurrentVideoDecoderConfig() {
1401 if (config_change_pending_)
1402 CompleteConfigChange();
1403 return video_configs_[current_config_index_];
1406 const TextTrackConfig& SourceBufferStream::GetCurrentTextTrackConfig() {
1407 return text_track_config_;
1410 base::TimeDelta SourceBufferStream::GetMaxInterbufferDistance() const {
1411 if (max_interbuffer_distance_ == kNoTimestamp())
1412 return base::TimeDelta::FromMilliseconds(kDefaultBufferDurationInMs);
1413 return max_interbuffer_distance_;
1416 bool SourceBufferStream::UpdateAudioConfig(const AudioDecoderConfig& config) {
1417 DCHECK(!audio_configs_.empty());
1418 DCHECK(video_configs_.empty());
1419 DVLOG(3) << "UpdateAudioConfig.";
1421 if (audio_configs_[0].codec() != config.codec()) {
1422 MEDIA_LOG(log_cb_) << "Audio codec changes not allowed.";
1426 if (audio_configs_[0].is_encrypted() != config.is_encrypted()) {
1427 MEDIA_LOG(log_cb_) << "Audio encryption changes not allowed.";
1431 // Check to see if the new config matches an existing one.
1432 for (size_t i = 0; i < audio_configs_.size(); ++i) {
1433 if (config.Matches(audio_configs_[i])) {
1434 append_config_index_ = i;
1439 // No matches found so let's add this one to the list.
1440 append_config_index_ = audio_configs_.size();
1441 DVLOG(2) << "New audio config - index: " << append_config_index_;
1442 audio_configs_.resize(audio_configs_.size() + 1);
1443 audio_configs_[append_config_index_] = config;
1447 bool SourceBufferStream::UpdateVideoConfig(const VideoDecoderConfig& config) {
1448 DCHECK(!video_configs_.empty());
1449 DCHECK(audio_configs_.empty());
1450 DVLOG(3) << "UpdateVideoConfig.";
1452 if (video_configs_[0].codec() != config.codec()) {
1453 MEDIA_LOG(log_cb_) << "Video codec changes not allowed.";
1457 if (video_configs_[0].is_encrypted() != config.is_encrypted()) {
1458 MEDIA_LOG(log_cb_) << "Video encryption changes not allowed.";
1462 // Check to see if the new config matches an existing one.
1463 for (size_t i = 0; i < video_configs_.size(); ++i) {
1464 if (config.Matches(video_configs_[i])) {
1465 append_config_index_ = i;
1470 // No matches found so let's add this one to the list.
1471 append_config_index_ = video_configs_.size();
1472 DVLOG(2) << "New video config - index: " << append_config_index_;
1473 video_configs_.resize(video_configs_.size() + 1);
1474 video_configs_[append_config_index_] = config;
1478 void SourceBufferStream::CompleteConfigChange() {
1479 config_change_pending_ = false;
1481 if (pending_buffer_) {
1482 current_config_index_ =
1483 GetConfigId(pending_buffer_, splice_buffers_index_);
1487 if (!track_buffer_.empty()) {
1488 current_config_index_ = GetConfigId(track_buffer_.front(), 0);
1492 if (selected_range_ && selected_range_->HasNextBuffer())
1493 current_config_index_ = selected_range_->GetNextConfigId();
1496 void SourceBufferStream::SetSelectedRangeIfNeeded(
1497 const DecodeTimestamp timestamp) {
1498 DVLOG(1) << __FUNCTION__ << "(" << timestamp.InSecondsF() << ")";
1500 if (selected_range_) {
1501 DCHECK(track_buffer_.empty());
1505 if (!track_buffer_.empty()) {
1506 DCHECK(!selected_range_);
1510 DecodeTimestamp start_timestamp = timestamp;
1512 // If the next buffer timestamp is not known then use a timestamp just after
1513 // the timestamp on the last buffer returned by GetNextBuffer().
1514 if (start_timestamp == kNoDecodeTimestamp()) {
1515 if (last_output_buffer_timestamp_ == kNoDecodeTimestamp())
1518 start_timestamp = last_output_buffer_timestamp_ +
1519 base::TimeDelta::FromInternalValue(1);
1522 DecodeTimestamp seek_timestamp =
1523 FindNewSelectedRangeSeekTimestamp(start_timestamp);
1525 // If we don't have buffered data to seek to, then return.
1526 if (seek_timestamp == kNoDecodeTimestamp())
1529 DCHECK(track_buffer_.empty());
1530 SeekAndSetSelectedRange(*FindExistingRangeFor(seek_timestamp),
1534 DecodeTimestamp SourceBufferStream::FindNewSelectedRangeSeekTimestamp(
1535 const DecodeTimestamp start_timestamp) {
1536 DCHECK(start_timestamp != kNoDecodeTimestamp());
1537 DCHECK(start_timestamp >= DecodeTimestamp());
1539 RangeList::iterator itr = ranges_.begin();
1541 for (; itr != ranges_.end(); ++itr) {
1542 if ((*itr)->GetEndTimestamp() >= start_timestamp) {
1547 if (itr == ranges_.end())
1548 return kNoDecodeTimestamp();
1550 // First check for a keyframe timestamp >= |start_timestamp|
1551 // in the current range.
1552 DecodeTimestamp keyframe_timestamp =
1553 (*itr)->NextKeyframeTimestamp(start_timestamp);
1555 if (keyframe_timestamp != kNoDecodeTimestamp())
1556 return keyframe_timestamp;
1558 // If a keyframe was not found then look for a keyframe that is
1559 // "close enough" in the current or next range.
1560 DecodeTimestamp end_timestamp =
1561 start_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance());
1562 DCHECK(start_timestamp < end_timestamp);
1564 // Make sure the current range doesn't start beyond |end_timestamp|.
1565 if ((*itr)->GetStartTimestamp() >= end_timestamp)
1566 return kNoDecodeTimestamp();
1568 keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp);
1570 // Check to see if the keyframe is within the acceptable range
1571 // (|start_timestamp|, |end_timestamp|].
1572 if (keyframe_timestamp != kNoDecodeTimestamp() &&
1573 start_timestamp < keyframe_timestamp &&
1574 keyframe_timestamp <= end_timestamp) {
1575 return keyframe_timestamp;
1578 // If |end_timestamp| is within this range, then no other checks are
1580 if (end_timestamp <= (*itr)->GetEndTimestamp())
1581 return kNoDecodeTimestamp();
1583 // Move on to the next range.
1586 // Return early if the next range does not contain |end_timestamp|.
1587 if (itr == ranges_.end() || (*itr)->GetStartTimestamp() >= end_timestamp)
1588 return kNoDecodeTimestamp();
1590 keyframe_timestamp = (*itr)->KeyframeBeforeTimestamp(end_timestamp);
1592 // Check to see if the keyframe is within the acceptable range
1593 // (|start_timestamp|, |end_timestamp|].
1594 if (keyframe_timestamp != kNoDecodeTimestamp() &&
1595 start_timestamp < keyframe_timestamp &&
1596 keyframe_timestamp <= end_timestamp) {
1597 return keyframe_timestamp;
1600 return kNoDecodeTimestamp();
1603 DecodeTimestamp SourceBufferStream::FindKeyframeAfterTimestamp(
1604 const DecodeTimestamp timestamp) {
1605 DCHECK(timestamp != kNoDecodeTimestamp());
1607 RangeList::iterator itr = FindExistingRangeFor(timestamp);
1609 if (itr == ranges_.end())
1610 return kNoDecodeTimestamp();
1612 // First check for a keyframe timestamp >= |timestamp|
1613 // in the current range.
1614 return (*itr)->NextKeyframeTimestamp(timestamp);
1617 std::string SourceBufferStream::GetStreamTypeName() const {
1618 switch (GetType()) {
1630 SourceBufferStream::Type SourceBufferStream::GetType() const {
1631 if (!audio_configs_.empty())
1633 if (!video_configs_.empty())
1635 DCHECK_NE(text_track_config_.kind(), kTextNone);
1639 void SourceBufferStream::DeleteAndRemoveRange(RangeList::iterator* itr) {
1640 DVLOG(1) << __FUNCTION__;
1642 DCHECK(*itr != ranges_.end());
1643 if (**itr == selected_range_) {
1644 DVLOG(1) << __FUNCTION__ << " deleting selected range.";
1645 SetSelectedRange(NULL);
1648 if (*itr == range_for_next_append_) {
1649 DVLOG(1) << __FUNCTION__ << " deleting range_for_next_append_.";
1650 range_for_next_append_ = ranges_.end();
1651 last_appended_buffer_timestamp_ = kNoDecodeTimestamp();
1652 last_appended_buffer_is_keyframe_ = false;
1656 *itr = ranges_.erase(*itr);
1659 void SourceBufferStream::GenerateSpliceFrame(const BufferQueue& new_buffers) {
1660 DCHECK(!new_buffers.empty());
1662 // Splice frames are only supported for audio.
1663 if (GetType() != kAudio)
1666 // Find the overlapped range (if any).
1667 const base::TimeDelta splice_timestamp = new_buffers.front()->timestamp();
1668 const DecodeTimestamp splice_dts =
1669 DecodeTimestamp::FromPresentationTime(splice_timestamp);
1670 RangeList::iterator range_itr = FindExistingRangeFor(splice_dts);
1671 if (range_itr == ranges_.end())
1674 const DecodeTimestamp max_splice_end_dts =
1675 splice_dts + base::TimeDelta::FromMilliseconds(
1676 AudioSplicer::kCrossfadeDurationInMilliseconds);
1678 // Find all buffers involved before the splice point.
1679 BufferQueue pre_splice_buffers;
1680 if (!(*range_itr)->GetBuffersInRange(
1681 splice_dts, max_splice_end_dts, &pre_splice_buffers)) {
1685 // If there are gaps in the timeline, it's possible that we only find buffers
1686 // after the splice point but within the splice range. For simplicity, we do
1687 // not generate splice frames in this case.
1689 // We also do not want to generate splices if the first new buffer replaces an
1690 // existing buffer exactly.
1691 if (pre_splice_buffers.front()->timestamp() >= splice_timestamp)
1694 // If any |pre_splice_buffers| are already splices or preroll, do not generate
1696 for (size_t i = 0; i < pre_splice_buffers.size(); ++i) {
1697 const BufferQueue& original_splice_buffers =
1698 pre_splice_buffers[i]->splice_buffers();
1699 if (!original_splice_buffers.empty()) {
1700 DVLOG(1) << "Can't generate splice: overlapped buffers contain a "
1701 "pre-existing splice.";
1705 if (pre_splice_buffers[i]->preroll_buffer()) {
1706 DVLOG(1) << "Can't generate splice: overlapped buffers contain preroll.";
1711 // Don't generate splice frames which represent less than two frames, since we
1712 // need at least that much to generate a crossfade. Per the spec, make this
1713 // check using the sample rate of the overlapping buffers.
1714 const base::TimeDelta splice_duration =
1715 pre_splice_buffers.back()->timestamp() +
1716 pre_splice_buffers.back()->duration() - splice_timestamp;
1717 const base::TimeDelta minimum_splice_duration = base::TimeDelta::FromSecondsD(
1718 2.0 / audio_configs_[append_config_index_].samples_per_second());
1719 if (splice_duration < minimum_splice_duration) {
1720 DVLOG(1) << "Can't generate splice: not enough samples for crossfade; have "
1721 << splice_duration.InMicroseconds() << " us, but need "
1722 << minimum_splice_duration.InMicroseconds() << " us.";
1726 new_buffers.front()->ConvertToSpliceBuffer(pre_splice_buffers);
1729 SourceBufferRange::SourceBufferRange(
1730 SourceBufferStream::Type type, const BufferQueue& new_buffers,
1731 DecodeTimestamp media_segment_start_time,
1732 const InterbufferDistanceCB& interbuffer_distance_cb)
1734 keyframe_map_index_base_(0),
1735 next_buffer_index_(-1),
1736 media_segment_start_time_(media_segment_start_time),
1737 interbuffer_distance_cb_(interbuffer_distance_cb),
1739 CHECK(!new_buffers.empty());
1740 DCHECK(new_buffers.front()->IsKeyframe());
1741 DCHECK(!interbuffer_distance_cb.is_null());
1742 AppendBuffersToEnd(new_buffers);
1745 void SourceBufferRange::AppendBuffersToEnd(const BufferQueue& new_buffers) {
1746 DCHECK(buffers_.empty() || CanAppendBuffersToEnd(new_buffers));
1747 DCHECK(media_segment_start_time_ == kNoDecodeTimestamp() ||
1748 media_segment_start_time_ <=
1749 new_buffers.front()->GetDecodeTimestamp());
1750 for (BufferQueue::const_iterator itr = new_buffers.begin();
1751 itr != new_buffers.end();
1753 DCHECK((*itr)->GetDecodeTimestamp() != kNoDecodeTimestamp());
1754 buffers_.push_back(*itr);
1755 size_in_bytes_ += (*itr)->data_size();
1757 if ((*itr)->IsKeyframe()) {
1758 keyframe_map_.insert(
1759 std::make_pair((*itr)->GetDecodeTimestamp(),
1760 buffers_.size() - 1 + keyframe_map_index_base_));
1765 void SourceBufferRange::Seek(DecodeTimestamp timestamp) {
1766 DCHECK(CanSeekTo(timestamp));
1767 DCHECK(!keyframe_map_.empty());
1769 KeyframeMap::iterator result = GetFirstKeyframeBefore(timestamp);
1770 next_buffer_index_ = result->second - keyframe_map_index_base_;
1771 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
1774 void SourceBufferRange::SeekAheadTo(DecodeTimestamp timestamp) {
1775 SeekAhead(timestamp, false);
1778 void SourceBufferRange::SeekAheadPast(DecodeTimestamp timestamp) {
1779 SeekAhead(timestamp, true);
1782 void SourceBufferRange::SeekAhead(DecodeTimestamp timestamp,
1783 bool skip_given_timestamp) {
1784 DCHECK(!keyframe_map_.empty());
1786 KeyframeMap::iterator result =
1787 GetFirstKeyframeAt(timestamp, skip_given_timestamp);
1789 // If there isn't a keyframe after |timestamp|, then seek to end and return
1790 // kNoTimestamp to signal such.
1791 if (result == keyframe_map_.end()) {
1792 next_buffer_index_ = -1;
1795 next_buffer_index_ = result->second - keyframe_map_index_base_;
1796 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size()));
1799 void SourceBufferRange::SeekToStart() {
1800 DCHECK(!buffers_.empty());
1801 next_buffer_index_ = 0;
1804 SourceBufferRange* SourceBufferRange::SplitRange(
1805 DecodeTimestamp timestamp, bool is_exclusive) {
1806 CHECK(!buffers_.empty());
1808 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not
1809 // include keyframes at |timestamp|.
1810 KeyframeMap::iterator new_beginning_keyframe =
1811 GetFirstKeyframeAt(timestamp, is_exclusive);
1813 // If there is no keyframe after |timestamp|, we can't split the range.
1814 if (new_beginning_keyframe == keyframe_map_.end())
1817 // Remove the data beginning at |keyframe_index| from |buffers_| and save it
1818 // into |removed_buffers|.
1819 int keyframe_index =
1820 new_beginning_keyframe->second - keyframe_map_index_base_;
1821 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size()));
1822 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index;
1823 BufferQueue removed_buffers(starting_point, buffers_.end());
1825 DecodeTimestamp new_range_start_timestamp = kNoDecodeTimestamp();
1826 if (GetStartTimestamp() < buffers_.front()->GetDecodeTimestamp() &&
1827 timestamp < removed_buffers.front()->GetDecodeTimestamp()) {
1828 // The split is in the gap between |media_segment_start_time_| and
1829 // the first buffer of the new range so we should set the start
1830 // time of the new range to |timestamp| so we preserve part of the
1831 // gap in the new range.
1832 new_range_start_timestamp = timestamp;
1835 keyframe_map_.erase(new_beginning_keyframe, keyframe_map_.end());
1836 FreeBufferRange(starting_point, buffers_.end());
1838 // Create a new range with |removed_buffers|.
1839 SourceBufferRange* split_range =
1840 new SourceBufferRange(
1841 type_, removed_buffers, new_range_start_timestamp,
1842 interbuffer_distance_cb_);
1844 // If the next buffer position is now in |split_range|, update the state of
1845 // this range and |split_range| accordingly.
1846 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
1847 split_range->next_buffer_index_ = next_buffer_index_ - keyframe_index;
1848 ResetNextBufferPosition();
1854 BufferQueue::iterator SourceBufferRange::GetBufferItrAt(
1855 DecodeTimestamp timestamp,
1856 bool skip_given_timestamp) {
1857 return skip_given_timestamp
1858 ? std::upper_bound(buffers_.begin(),
1861 CompareTimeDeltaToStreamParserBuffer)
1862 : std::lower_bound(buffers_.begin(),
1865 CompareStreamParserBufferToTimeDelta);
1868 SourceBufferRange::KeyframeMap::iterator
1869 SourceBufferRange::GetFirstKeyframeAt(DecodeTimestamp timestamp,
1870 bool skip_given_timestamp) {
1871 return skip_given_timestamp ?
1872 keyframe_map_.upper_bound(timestamp) :
1873 keyframe_map_.lower_bound(timestamp);
1876 SourceBufferRange::KeyframeMap::iterator
1877 SourceBufferRange::GetFirstKeyframeBefore(DecodeTimestamp timestamp) {
1878 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp);
1879 // lower_bound() returns the first element >= |timestamp|, so we want the
1880 // previous element if it did not return the element exactly equal to
1882 if (result != keyframe_map_.begin() &&
1883 (result == keyframe_map_.end() || result->first != timestamp)) {
1889 void SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) {
1890 TruncateAt(buffers_.begin(), removed_buffers);
1893 bool SourceBufferRange::TruncateAt(
1894 DecodeTimestamp timestamp, BufferQueue* removed_buffers,
1895 bool is_exclusive) {
1896 // Find the place in |buffers_| where we will begin deleting data.
1897 BufferQueue::iterator starting_point =
1898 GetBufferItrAt(timestamp, is_exclusive);
1899 return TruncateAt(starting_point, removed_buffers);
1902 int SourceBufferRange::DeleteGOPFromFront(BufferQueue* deleted_buffers) {
1903 DCHECK(!FirstGOPContainsNextBufferPosition());
1904 DCHECK(deleted_buffers);
1906 int buffers_deleted = 0;
1907 int total_bytes_deleted = 0;
1909 KeyframeMap::iterator front = keyframe_map_.begin();
1910 DCHECK(front != keyframe_map_.end());
1912 // Delete the keyframe at the start of |keyframe_map_|.
1913 keyframe_map_.erase(front);
1915 // Now we need to delete all the buffers that depend on the keyframe we've
1917 int end_index = keyframe_map_.size() > 0 ?
1918 keyframe_map_.begin()->second - keyframe_map_index_base_ :
1921 // Delete buffers from the beginning of the buffered range up until (but not
1922 // including) the next keyframe.
1923 for (int i = 0; i < end_index; i++) {
1924 int bytes_deleted = buffers_.front()->data_size();
1925 size_in_bytes_ -= bytes_deleted;
1926 total_bytes_deleted += bytes_deleted;
1927 deleted_buffers->push_back(buffers_.front());
1928 buffers_.pop_front();
1932 // Update |keyframe_map_index_base_| to account for the deleted buffers.
1933 keyframe_map_index_base_ += buffers_deleted;
1935 if (next_buffer_index_ > -1) {
1936 next_buffer_index_ -= buffers_deleted;
1937 DCHECK_GE(next_buffer_index_, 0);
1940 // Invalidate media segment start time if we've deleted the first buffer of
1942 if (buffers_deleted > 0)
1943 media_segment_start_time_ = kNoDecodeTimestamp();
1945 return total_bytes_deleted;
1948 int SourceBufferRange::DeleteGOPFromBack(BufferQueue* deleted_buffers) {
1949 DCHECK(!LastGOPContainsNextBufferPosition());
1950 DCHECK(deleted_buffers);
1952 // Remove the last GOP's keyframe from the |keyframe_map_|.
1953 KeyframeMap::iterator back = keyframe_map_.end();
1954 DCHECK_GT(keyframe_map_.size(), 0u);
1957 // The index of the first buffer in the last GOP is equal to the new size of
1958 // |buffers_| after that GOP is deleted.
1959 size_t goal_size = back->second - keyframe_map_index_base_;
1960 keyframe_map_.erase(back);
1962 int total_bytes_deleted = 0;
1963 while (buffers_.size() != goal_size) {
1964 int bytes_deleted = buffers_.back()->data_size();
1965 size_in_bytes_ -= bytes_deleted;
1966 total_bytes_deleted += bytes_deleted;
1967 // We're removing buffers from the back, so push each removed buffer to the
1968 // front of |deleted_buffers| so that |deleted_buffers| are in nondecreasing
1970 deleted_buffers->push_front(buffers_.back());
1971 buffers_.pop_back();
1974 return total_bytes_deleted;
1977 int SourceBufferRange::GetRemovalGOP(
1978 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp,
1979 int total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) {
1980 int bytes_to_free = total_bytes_to_free;
1981 int bytes_removed = 0;
1983 KeyframeMap::iterator gop_itr = GetFirstKeyframeAt(start_timestamp, false);
1984 if (gop_itr == keyframe_map_.end())
1986 int keyframe_index = gop_itr->second - keyframe_map_index_base_;
1987 BufferQueue::iterator buffer_itr = buffers_.begin() + keyframe_index;
1988 KeyframeMap::iterator gop_end = keyframe_map_.end();
1989 if (end_timestamp < GetBufferedEndTimestamp())
1990 gop_end = GetFirstKeyframeBefore(end_timestamp);
1992 // Check if the removal range is within a GOP and skip the loop if so.
1993 // [keyframe]...[start_timestamp]...[end_timestamp]...[keyframe]
1994 KeyframeMap::iterator gop_itr_prev = gop_itr;
1995 if (gop_itr_prev != keyframe_map_.begin() && --gop_itr_prev == gop_end)
1998 while (gop_itr != gop_end && bytes_to_free > 0) {
2002 int next_gop_index = gop_itr == keyframe_map_.end() ?
2003 buffers_.size() : gop_itr->second - keyframe_map_index_base_;
2004 BufferQueue::iterator next_gop_start = buffers_.begin() + next_gop_index;
2005 for (; buffer_itr != next_gop_start; ++buffer_itr)
2006 gop_size += (*buffer_itr)->data_size();
2008 bytes_removed += gop_size;
2009 bytes_to_free -= gop_size;
2011 if (bytes_removed > 0) {
2012 *removal_end_timestamp = gop_itr == keyframe_map_.end() ?
2013 GetBufferedEndTimestamp() : gop_itr->first;
2015 return bytes_removed;
2018 bool SourceBufferRange::FirstGOPContainsNextBufferPosition() const {
2019 if (!HasNextBufferPosition())
2022 // If there is only one GOP, it must contain the next buffer position.
2023 if (keyframe_map_.size() == 1u)
2026 KeyframeMap::const_iterator second_gop = keyframe_map_.begin();
2028 return next_buffer_index_ < second_gop->second - keyframe_map_index_base_;
2031 bool SourceBufferRange::LastGOPContainsNextBufferPosition() const {
2032 if (!HasNextBufferPosition())
2035 // If there is only one GOP, it must contain the next buffer position.
2036 if (keyframe_map_.size() == 1u)
2039 KeyframeMap::const_iterator last_gop = keyframe_map_.end();
2041 return last_gop->second - keyframe_map_index_base_ <= next_buffer_index_;
2044 void SourceBufferRange::FreeBufferRange(
2045 const BufferQueue::iterator& starting_point,
2046 const BufferQueue::iterator& ending_point) {
2047 for (BufferQueue::iterator itr = starting_point;
2048 itr != ending_point; ++itr) {
2049 size_in_bytes_ -= (*itr)->data_size();
2050 DCHECK_GE(size_in_bytes_, 0);
2052 buffers_.erase(starting_point, ending_point);
2055 bool SourceBufferRange::TruncateAt(
2056 const BufferQueue::iterator& starting_point, BufferQueue* removed_buffers) {
2057 DCHECK(!removed_buffers || removed_buffers->empty());
2059 // Return if we're not deleting anything.
2060 if (starting_point == buffers_.end())
2061 return buffers_.empty();
2063 // Reset the next buffer index if we will be deleting the buffer that's next
2065 if (HasNextBufferPosition()) {
2066 DecodeTimestamp next_buffer_timestamp = GetNextTimestamp();
2067 if (next_buffer_timestamp == kNoDecodeTimestamp() ||
2068 next_buffer_timestamp >= (*starting_point)->GetDecodeTimestamp()) {
2069 if (HasNextBuffer() && removed_buffers) {
2070 int starting_offset = starting_point - buffers_.begin();
2071 int next_buffer_offset = next_buffer_index_ - starting_offset;
2072 DCHECK_GE(next_buffer_offset, 0);
2073 BufferQueue saved(starting_point + next_buffer_offset, buffers_.end());
2074 removed_buffers->swap(saved);
2076 ResetNextBufferPosition();
2080 // Remove keyframes from |starting_point| onward.
2081 KeyframeMap::iterator starting_point_keyframe =
2082 keyframe_map_.lower_bound((*starting_point)->GetDecodeTimestamp());
2083 keyframe_map_.erase(starting_point_keyframe, keyframe_map_.end());
2085 // Remove everything from |starting_point| onward.
2086 FreeBufferRange(starting_point, buffers_.end());
2087 return buffers_.empty();
2090 bool SourceBufferRange::GetNextBuffer(
2091 scoped_refptr<StreamParserBuffer>* out_buffer) {
2092 if (!HasNextBuffer())
2095 *out_buffer = buffers_[next_buffer_index_];
2096 next_buffer_index_++;
2100 bool SourceBufferRange::HasNextBuffer() const {
2101 return next_buffer_index_ >= 0 &&
2102 next_buffer_index_ < static_cast<int>(buffers_.size());
2105 int SourceBufferRange::GetNextConfigId() const {
2106 DCHECK(HasNextBuffer());
2107 // If the next buffer is an audio splice frame, the next effective config id
2108 // comes from the first fade out preroll buffer.
2109 return GetConfigId(buffers_[next_buffer_index_], 0);
2112 DecodeTimestamp SourceBufferRange::GetNextTimestamp() const {
2113 DCHECK(!buffers_.empty());
2114 DCHECK(HasNextBufferPosition());
2116 if (next_buffer_index_ >= static_cast<int>(buffers_.size())) {
2117 return kNoDecodeTimestamp();
2120 return buffers_[next_buffer_index_]->GetDecodeTimestamp();
2123 bool SourceBufferRange::HasNextBufferPosition() const {
2124 return next_buffer_index_ >= 0;
2127 void SourceBufferRange::ResetNextBufferPosition() {
2128 next_buffer_index_ = -1;
2131 void SourceBufferRange::AppendRangeToEnd(const SourceBufferRange& range,
2132 bool transfer_current_position) {
2133 DCHECK(CanAppendRangeToEnd(range));
2134 DCHECK(!buffers_.empty());
2136 if (transfer_current_position && range.next_buffer_index_ >= 0)
2137 next_buffer_index_ = range.next_buffer_index_ + buffers_.size();
2139 AppendBuffersToEnd(range.buffers_);
2142 bool SourceBufferRange::CanAppendRangeToEnd(
2143 const SourceBufferRange& range) const {
2144 return CanAppendBuffersToEnd(range.buffers_);
2147 bool SourceBufferRange::CanAppendBuffersToEnd(
2148 const BufferQueue& buffers) const {
2149 DCHECK(!buffers_.empty());
2150 return IsNextInSequence(buffers.front()->GetDecodeTimestamp(),
2151 buffers.front()->IsKeyframe());
2154 bool SourceBufferRange::BelongsToRange(DecodeTimestamp timestamp) const {
2155 DCHECK(!buffers_.empty());
2157 return (IsNextInSequence(timestamp, false) ||
2158 (GetStartTimestamp() <= timestamp && timestamp <= GetEndTimestamp()));
2161 bool SourceBufferRange::CanSeekTo(DecodeTimestamp timestamp) const {
2162 DecodeTimestamp start_timestamp =
2163 std::max(DecodeTimestamp(), GetStartTimestamp() - GetFudgeRoom());
2164 return !keyframe_map_.empty() && start_timestamp <= timestamp &&
2165 timestamp < GetBufferedEndTimestamp();
2168 bool SourceBufferRange::CompletelyOverlaps(
2169 const SourceBufferRange& range) const {
2170 return GetStartTimestamp() <= range.GetStartTimestamp() &&
2171 GetEndTimestamp() >= range.GetEndTimestamp();
2174 bool SourceBufferRange::EndOverlaps(const SourceBufferRange& range) const {
2175 return range.GetStartTimestamp() <= GetEndTimestamp() &&
2176 GetEndTimestamp() < range.GetEndTimestamp();
2179 DecodeTimestamp SourceBufferRange::GetStartTimestamp() const {
2180 DCHECK(!buffers_.empty());
2181 DecodeTimestamp start_timestamp = media_segment_start_time_;
2182 if (start_timestamp == kNoDecodeTimestamp())
2183 start_timestamp = buffers_.front()->GetDecodeTimestamp();
2184 return start_timestamp;
2187 DecodeTimestamp SourceBufferRange::GetEndTimestamp() const {
2188 DCHECK(!buffers_.empty());
2189 return buffers_.back()->GetDecodeTimestamp();
2192 DecodeTimestamp SourceBufferRange::GetBufferedEndTimestamp() const {
2193 DCHECK(!buffers_.empty());
2194 base::TimeDelta duration = buffers_.back()->duration();
2195 if (duration == kNoTimestamp() || duration == base::TimeDelta())
2196 duration = GetApproximateDuration();
2197 return GetEndTimestamp() + duration;
2200 DecodeTimestamp SourceBufferRange::NextKeyframeTimestamp(
2201 DecodeTimestamp timestamp) {
2202 DCHECK(!keyframe_map_.empty());
2204 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
2205 return kNoDecodeTimestamp();
2207 KeyframeMap::iterator itr = GetFirstKeyframeAt(timestamp, false);
2208 if (itr == keyframe_map_.end())
2209 return kNoDecodeTimestamp();
2211 // If the timestamp is inside the gap between the start of the media
2212 // segment and the first buffer, then just pretend there is a
2213 // keyframe at the specified timestamp.
2214 if (itr == keyframe_map_.begin() &&
2215 timestamp > media_segment_start_time_ &&
2216 timestamp < itr->first) {
2223 DecodeTimestamp SourceBufferRange::KeyframeBeforeTimestamp(
2224 DecodeTimestamp timestamp) {
2225 DCHECK(!keyframe_map_.empty());
2227 if (timestamp < GetStartTimestamp() || timestamp >= GetBufferedEndTimestamp())
2228 return kNoDecodeTimestamp();
2230 return GetFirstKeyframeBefore(timestamp)->first;
2233 bool SourceBufferRange::IsNextInSequence(
2234 DecodeTimestamp timestamp, bool is_keyframe) const {
2235 DecodeTimestamp end = buffers_.back()->GetDecodeTimestamp();
2236 if (end < timestamp &&
2237 (type_ == SourceBufferStream::kText ||
2238 timestamp <= end + GetFudgeRoom())) {
2242 return timestamp == end && AllowSameTimestamp(
2243 buffers_.back()->IsKeyframe(), is_keyframe, type_);
2246 base::TimeDelta SourceBufferRange::GetFudgeRoom() const {
2247 return ComputeFudgeRoom(GetApproximateDuration());
2250 base::TimeDelta SourceBufferRange::GetApproximateDuration() const {
2251 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run();
2252 DCHECK(max_interbuffer_distance != kNoTimestamp());
2253 return max_interbuffer_distance;
2256 bool SourceBufferRange::GetBuffersInRange(DecodeTimestamp start,
2257 DecodeTimestamp end,
2258 BufferQueue* buffers) {
2259 // Find the nearest buffer with a decode timestamp <= start.
2260 const DecodeTimestamp first_timestamp = KeyframeBeforeTimestamp(start);
2261 if (first_timestamp == kNoDecodeTimestamp())
2264 // Find all buffers involved in the range.
2265 const size_t previous_size = buffers->size();
2266 for (BufferQueue::iterator it = GetBufferItrAt(first_timestamp, false);
2267 it != buffers_.end();
2269 const scoped_refptr<StreamParserBuffer>& buffer = *it;
2270 // Buffers without duration are not supported, so bail if we encounter any.
2271 if (buffer->duration() == kNoTimestamp() ||
2272 buffer->duration() <= base::TimeDelta()) {
2275 if (buffer->end_of_stream() ||
2276 buffer->timestamp() >= end.ToPresentationTime()) {
2280 if (buffer->timestamp() + buffer->duration() <= start.ToPresentationTime())
2282 buffers->push_back(buffer);
2284 return previous_size < buffers->size();
2287 bool SourceBufferStream::SetPendingBuffer(
2288 scoped_refptr<StreamParserBuffer>* out_buffer) {
2289 DCHECK(*out_buffer);
2290 DCHECK(!pending_buffer_);
2292 const bool have_splice_buffers = !(*out_buffer)->splice_buffers().empty();
2293 const bool have_preroll_buffer = !!(*out_buffer)->preroll_buffer();
2295 if (!have_splice_buffers && !have_preroll_buffer)
2298 DCHECK_NE(have_splice_buffers, have_preroll_buffer);
2299 splice_buffers_index_ = 0;
2300 pending_buffer_.swap(*out_buffer);
2301 pending_buffers_complete_ = false;
2305 } // namespace media