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