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