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