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