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