| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/filters/source_buffer_stream.h" | 5 #include "media/filters/source_buffer_stream.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 // |timestamp|. | 56 // |timestamp|. |
| 57 void SeekAheadTo(base::TimeDelta timestamp); | 57 void SeekAheadTo(base::TimeDelta timestamp); |
| 58 | 58 |
| 59 // Updates |next_buffer_index_| to point to next keyframe strictly after | 59 // Updates |next_buffer_index_| to point to next keyframe strictly after |
| 60 // |timestamp|. | 60 // |timestamp|. |
| 61 void SeekAheadPast(base::TimeDelta timestamp); | 61 void SeekAheadPast(base::TimeDelta timestamp); |
| 62 | 62 |
| 63 // Seeks to the beginning of the range. | 63 // Seeks to the beginning of the range. |
| 64 void SeekToStart(); | 64 void SeekToStart(); |
| 65 | 65 |
| 66 // Finds the next keyframe from |buffers_| after |timestamp|, and creates and | 66 // Finds the next keyframe from |buffers_| after |timestamp| (or at |
| 67 // returns a new SourceBufferRange with the buffers from that keyframe onward. | 67 // |timestamp| if |is_exclusive| is false) and creates and returns a new |
| 68 // SourceBufferRange with the buffers from that keyframe onward. |
| 68 // The buffers in the new SourceBufferRange are moved out of this range. If | 69 // 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 // there is no keyframe after |timestamp|, SplitRange() returns null and this |
| 70 // range is unmodified. | 71 // range is unmodified. |
| 71 SourceBufferRange* SplitRange(base::TimeDelta timestamp); | 72 SourceBufferRange* SplitRange(base::TimeDelta timestamp, bool is_exclusive); |
| 72 | 73 |
| 73 // Deletes the buffers from this range whose timestamps are greater than or | 74 // Deletes the buffers from this range starting at |timestamp|, exclusive if |
| 74 // equal to |buffer|'s timestamp. | 75 // |is_exclusive| is true, inclusive otherwise. |
| 75 // Resets |next_buffer_index_| if the buffer at |next_buffer_index_| was | 76 // 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 // deleted, and deletes the |keyframe_map_| entries for the buffers that |
| 77 // were removed. | 78 // were removed. |
| 78 // |deleted_buffers| contains the buffers that were deleted from this range, | 79 // |deleted_buffers| contains the buffers that were deleted from this range, |
| 79 // starting at the buffer that had been at |next_buffer_index_|. | 80 // starting at the buffer that had been at |next_buffer_index_|. |
| 80 // Returns true if the |next_buffer_index_| is reset. Note that this method | 81 // Returns true if the |next_buffer_index_| is reset. Note that this method |
| 81 // may return true even if it does not add any buffers to |deleted_buffers|. | 82 // may return true even if it does not add any buffers to |deleted_buffers|. |
| 82 // This indicates that the range had not buffered |next_buffer_index_|, but | 83 // This indicates that the range had not buffered |next_buffer_index_|, but |
| 83 // a buffer at that position would have been deleted. | 84 // a buffer at that position would have been deleted. |
| 84 bool TruncateAt(scoped_refptr<StreamParserBuffer> buffer, | 85 bool TruncateAt(base::TimeDelta timestamp, |
| 85 BufferQueue* deleted_buffers); | 86 BufferQueue* deleted_buffers, bool is_exclusive); |
| 86 bool TruncateAt(base::TimeDelta timestamp); | |
| 87 // Deletes all buffers in range. | 87 // Deletes all buffers in range. |
| 88 bool DeleteAll(BufferQueue* deleted_buffers); | 88 bool DeleteAll(BufferQueue* deleted_buffers); |
| 89 | 89 |
| 90 // Attempts to free |bytes| data from the range, preferring to delete at the | 90 // Attempts to free |bytes| data from the range, preferring to delete at the |
| 91 // beginning of the range. Deletes data in GOPS at a time so that the range | 91 // beginning of the range. Deletes data in GOPS at a time so that the range |
| 92 // always begins with a keyframe. Returns the number of bytes freed. | 92 // always begins with a keyframe. Returns the number of bytes freed. |
| 93 int FreeFromStart(int bytes); | 93 int FreeFromStart(int bytes); |
| 94 | 94 |
| 95 // Attempts to free |bytes| data from the range, preferring to delete at the | 95 // Attempts to free |bytes| data from the range, preferring to delete at the |
| 96 // end of the range. Returns the number of bytes freed. | 96 // end of the range. Returns the number of bytes freed. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 int size_in_bytes() const { return size_in_bytes_; } | 157 int size_in_bytes() const { return size_in_bytes_; } |
| 158 | 158 |
| 159 private: | 159 private: |
| 160 typedef std::map<base::TimeDelta, size_t> KeyframeMap; | 160 typedef std::map<base::TimeDelta, size_t> KeyframeMap; |
| 161 | 161 |
| 162 // Seeks the range to the next keyframe after |timestamp|. If | 162 // Seeks the range to the next keyframe after |timestamp|. If |
| 163 // |skip_given_timestamp| is true, the seek will go to a keyframe with a | 163 // |skip_given_timestamp| is true, the seek will go to a keyframe with a |
| 164 // timestamp strictly greater than |timestamp|. | 164 // timestamp strictly greater than |timestamp|. |
| 165 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp); | 165 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp); |
| 166 | 166 |
| 167 // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|. |
| 168 // If |skip_given_timestamp| is true, this returns the first buffer with |
| 169 // timestamp greater than |timestamp|. |
| 170 BufferQueue::iterator GetBufferItrAt( |
| 171 base::TimeDelta timestamp, bool skip_given_timestamp); |
| 172 |
| 167 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after | 173 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after |
| 168 // |timestamp|. If |skip_given_timestamp| is true, this returns the first | 174 // |timestamp|. If |skip_given_timestamp| is true, this returns the first |
| 169 // keyframe with a timestamp strictly greater than |timestamp|. | 175 // keyframe with a timestamp strictly greater than |timestamp|. |
| 170 KeyframeMap::iterator GetFirstKeyframeAt( | 176 KeyframeMap::iterator GetFirstKeyframeAt( |
| 171 base::TimeDelta timestamp, bool skip_given_timestamp); | 177 base::TimeDelta timestamp, bool skip_given_timestamp); |
| 172 | 178 |
| 173 // Returns an iterator in |keyframe_map_| pointing to the first keyframe | 179 // Returns an iterator in |keyframe_map_| pointing to the first keyframe |
| 174 // before or at |timestamp|. | 180 // before or at |timestamp|. |
| 175 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp); | 181 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp); |
| 176 | 182 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 return true; | 250 return true; |
| 245 } | 251 } |
| 246 | 252 |
| 247 // Comparison function for two Buffers based on timestamp. | 253 // Comparison function for two Buffers based on timestamp. |
| 248 static bool BufferComparator( | 254 static bool BufferComparator( |
| 249 const scoped_refptr<media::StreamParserBuffer>& first, | 255 const scoped_refptr<media::StreamParserBuffer>& first, |
| 250 const scoped_refptr<media::StreamParserBuffer>& second) { | 256 const scoped_refptr<media::StreamParserBuffer>& second) { |
| 251 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); | 257 return first->GetDecodeTimestamp() < second->GetDecodeTimestamp(); |
| 252 } | 258 } |
| 253 | 259 |
| 260 // Returns an estimate of how far from the beginning or end of a range a buffer |
| 261 // can be to still be considered in the range, given the |approximate_duration| |
| 262 // of a buffer in the stream. |
| 263 static base::TimeDelta ComputeFudgeRoom(base::TimeDelta approximate_duration) { |
| 264 // Because we do not know exactly when is the next timestamp, any buffer |
| 265 // that starts within 2x the approximate duration of a buffer is considered |
| 266 // within this range. |
| 267 return 2 * approximate_duration; |
| 268 } |
| 269 |
| 254 // An arbitrarily-chosen number to estimate the duration of a buffer if none | 270 // An arbitrarily-chosen number to estimate the duration of a buffer if none |
| 255 // is set and there's not enough information to get a better estimate. | 271 // is set and there's not enough information to get a better estimate. |
| 256 static int kDefaultBufferDurationInMs = 125; | 272 static int kDefaultBufferDurationInMs = 125; |
| 257 | 273 |
| 258 // The amount of time the beginning of the buffered data can differ from the | 274 // The amount of time the beginning of the buffered data can differ from the |
| 259 // start time in order to still be considered the start of stream. | 275 // start time in order to still be considered the start of stream. |
| 260 static base::TimeDelta kSeekToStartFudgeRoom() { | 276 static base::TimeDelta kSeekToStartFudgeRoom() { |
| 261 return base::TimeDelta::FromMilliseconds(1000); | 277 return base::TimeDelta::FromMilliseconds(1000); |
| 262 } | 278 } |
| 263 // The maximum amount of data in bytes the stream will keep in memory. | 279 // The maximum amount of data in bytes the stream will keep in memory. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 ranges_.pop_front(); | 326 ranges_.pop_front(); |
| 311 } | 327 } |
| 312 | 328 |
| 313 STLDeleteElements(&audio_configs_); | 329 STLDeleteElements(&audio_configs_); |
| 314 STLDeleteElements(&video_configs_); | 330 STLDeleteElements(&video_configs_); |
| 315 } | 331 } |
| 316 | 332 |
| 317 void SourceBufferStream::OnNewMediaSegment( | 333 void SourceBufferStream::OnNewMediaSegment( |
| 318 base::TimeDelta media_segment_start_time) { | 334 base::TimeDelta media_segment_start_time) { |
| 319 media_segment_start_time_ = media_segment_start_time; | 335 media_segment_start_time_ = media_segment_start_time; |
| 336 new_media_segment_ = true; |
| 320 | 337 |
| 321 // Find the range that will house the buffers appended through the next | 338 RangeList::iterator last_range = range_for_next_append_; |
| 322 // Append() call. | |
| 323 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); | 339 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); |
| 324 new_media_segment_ = true; | 340 |
| 325 last_buffer_timestamp_ = kNoTimestamp(); | 341 // Only reset |last_buffer_timestamp_| if this new media segment is not |
| 342 // adjacent to the previous media segment appended to the stream. |
| 343 if (range_for_next_append_ == ranges_.end() || |
| 344 !AreAdjacentInSequence( |
| 345 last_buffer_timestamp_, media_segment_start_time)) { |
| 346 last_buffer_timestamp_ = kNoTimestamp(); |
| 347 } else { |
| 348 DCHECK(last_range == range_for_next_append_); |
| 349 } |
| 326 } | 350 } |
| 327 | 351 |
| 328 bool SourceBufferStream::Append( | 352 bool SourceBufferStream::Append( |
| 329 const SourceBufferStream::BufferQueue& buffers) { | 353 const SourceBufferStream::BufferQueue& buffers) { |
| 330 DCHECK(!buffers.empty()); | 354 DCHECK(!buffers.empty()); |
| 331 DCHECK(media_segment_start_time_ != kNoTimestamp()); | 355 DCHECK(media_segment_start_time_ != kNoTimestamp()); |
| 332 | 356 |
| 333 // New media segments must begin with a keyframe. | 357 // New media segments must begin with a keyframe. |
| 334 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { | 358 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { |
| 335 DVLOG(1) << "Media segment did not begin with keyframe."; | 359 DVLOG(1) << "Media segment did not begin with keyframe."; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 | 556 |
| 533 void SourceBufferStream::InsertIntoExistingRange( | 557 void SourceBufferStream::InsertIntoExistingRange( |
| 534 const RangeList::iterator& range_for_new_buffers_itr, | 558 const RangeList::iterator& range_for_new_buffers_itr, |
| 535 const BufferQueue& new_buffers, | 559 const BufferQueue& new_buffers, |
| 536 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { | 560 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
| 537 DCHECK(deleted_next_buffer); | 561 DCHECK(deleted_next_buffer); |
| 538 DCHECK(deleted_buffers); | 562 DCHECK(deleted_buffers); |
| 539 | 563 |
| 540 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; | 564 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; |
| 541 | 565 |
| 542 // If this is a simple case where we can just append to the end of the range, | 566 if (last_buffer_timestamp_ != kNoTimestamp()) { |
| 543 // do so and return. | 567 // Clean up the old buffers between the last appended buffer and the |
| 544 if (range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) { | 568 // beginning of |new_buffers|. |
| 545 range_for_new_buffers->AppendBuffersToEnd(new_buffers); | 569 *deleted_next_buffer = |
| 546 return; | 570 DeleteBetween( |
| 571 range_for_new_buffers, last_buffer_timestamp_, |
| 572 new_buffers.front()->GetDecodeTimestamp(), true, |
| 573 deleted_buffers); |
| 547 } | 574 } |
| 548 | 575 |
| 549 // Otherwise, this is either a start overlap or an middle overlap. | 576 // If we cannot append the |new_buffers| to the end of the existing range, |
| 577 // this is either a start overlap or an middle overlap. Delete the buffers |
| 578 // that |new_buffers| overlaps. |
| 579 if (!range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) { |
| 580 *deleted_next_buffer |= |
| 581 DeleteBetween( |
| 582 range_for_new_buffers, new_buffers.front()->GetDecodeTimestamp(), |
| 583 new_buffers.back()->GetDecodeTimestamp(), false, |
| 584 deleted_buffers); |
| 585 } |
| 550 | 586 |
| 551 // In case this is a middle overlap, save the buffers that come after the end | 587 range_for_new_buffers->AppendBuffersToEnd(new_buffers); |
| 552 // of |new_buffers|, and add them into a new range. | 588 } |
| 589 |
| 590 bool SourceBufferStream::DeleteBetween( |
| 591 SourceBufferRange* range, base::TimeDelta start_timestamp, |
| 592 base::TimeDelta end_timestamp, bool is_range_exclusive, |
| 593 BufferQueue* deleted_buffers) { |
| 553 SourceBufferRange* new_next_range = | 594 SourceBufferRange* new_next_range = |
| 554 range_for_new_buffers->SplitRange( | 595 range->SplitRange(end_timestamp, is_range_exclusive); |
| 555 new_buffers.back()->GetDecodeTimestamp()); | |
| 556 | 596 |
| 557 if (new_next_range) | 597 if (new_next_range) |
| 558 AddToRanges(new_next_range); | 598 AddToRanges(new_next_range); |
| 559 | 599 |
| 560 // Delete the buffers that are overlapped by |new_buffers|, then append | |
| 561 // |new_buffers| to the end of the range. | |
| 562 BufferQueue saved_buffers; | 600 BufferQueue saved_buffers; |
| 563 bool deleted_next_buffer_from_range = | 601 bool deleted_next_buffer = |
| 564 range_for_new_buffers->TruncateAt(new_buffers.front(), &saved_buffers); | 602 range->TruncateAt(start_timestamp, &saved_buffers, is_range_exclusive); |
| 565 range_for_new_buffers->AppendBuffersToEnd(new_buffers); | |
| 566 | 603 |
| 567 if (selected_range_ != range_for_new_buffers) | 604 if (selected_range_ != range) |
| 568 return; | 605 return deleted_next_buffer; |
| 569 | 606 |
| 570 DCHECK(!*deleted_next_buffer); | 607 DCHECK(deleted_buffers->empty()); |
| 571 *deleted_buffers = saved_buffers; | 608 *deleted_buffers = saved_buffers; |
| 572 *deleted_next_buffer = deleted_next_buffer_from_range; | |
| 573 | 609 |
| 574 // If this was a middle overlap resulting in a new range, and the next buffer | 610 // If the next buffer position has transferred to the split range, set the |
| 575 // position has been transferred to the newly created range, update the | 611 // selected range accordingly. |
| 576 // |selected_range_| accordingly. | |
| 577 if (new_next_range && new_next_range->HasNextBufferPosition()) { | 612 if (new_next_range && new_next_range->HasNextBufferPosition()) { |
| 578 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); | 613 DCHECK(!range->HasNextBufferPosition()); |
| 579 DCHECK(!*deleted_next_buffer); | 614 DCHECK(!deleted_next_buffer); |
| 580 SetSelectedRange(new_next_range); | 615 SetSelectedRange(new_next_range); |
| 581 } | 616 } |
| 617 return deleted_next_buffer; |
| 618 } |
| 619 |
| 620 bool SourceBufferStream::AreAdjacentInSequence( |
| 621 base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const { |
| 622 return first_timestamp < second_timestamp && |
| 623 second_timestamp <= |
| 624 first_timestamp + ComputeFudgeRoom(GetMaxInterbufferDistance()); |
| 582 } | 625 } |
| 583 | 626 |
| 584 void SourceBufferStream::ResolveCompleteOverlaps( | 627 void SourceBufferStream::ResolveCompleteOverlaps( |
| 585 const RangeList::iterator& range_with_new_buffers_itr, | 628 const RangeList::iterator& range_with_new_buffers_itr, |
| 586 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { | 629 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
| 587 DCHECK(deleted_next_buffer); | 630 DCHECK(deleted_next_buffer); |
| 588 DCHECK(deleted_buffers); | 631 DCHECK(deleted_buffers); |
| 589 | 632 |
| 590 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; | 633 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
| 591 RangeList::iterator next_range_itr = range_with_new_buffers_itr; | 634 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 620 } | 663 } |
| 621 | 664 |
| 622 // Split the overlapped range after |range_with_new_buffers|'s last buffer | 665 // Split the overlapped range after |range_with_new_buffers|'s last buffer |
| 623 // overlaps. Now |overlapped_range| contains only the buffers that do not | 666 // overlaps. Now |overlapped_range| contains only the buffers that do not |
| 624 // belong in |ranges_| anymore, and |new_next_range| contains buffers that | 667 // belong in |ranges_| anymore, and |new_next_range| contains buffers that |
| 625 // go after |range_with_new_buffers| (without overlap). | 668 // go after |range_with_new_buffers| (without overlap). |
| 626 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr); | 669 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr); |
| 627 next_range_itr = ranges_.erase(next_range_itr); | 670 next_range_itr = ranges_.erase(next_range_itr); |
| 628 | 671 |
| 629 SourceBufferRange* new_next_range = | 672 SourceBufferRange* new_next_range = |
| 630 overlapped_range->SplitRange(range_with_new_buffers->GetEndTimestamp()); | 673 overlapped_range->SplitRange( |
| 674 range_with_new_buffers->GetEndTimestamp(), true); |
| 631 | 675 |
| 632 // If there were non-overlapped buffers, add the new range to |ranges_|. | 676 // If there were non-overlapped buffers, add the new range to |ranges_|. |
| 633 if (new_next_range) | 677 if (new_next_range) |
| 634 AddToRanges(new_next_range); | 678 AddToRanges(new_next_range); |
| 635 | 679 |
| 636 // If we didn't overlap a selected range, return. | 680 // If we didn't overlap a selected range, return. |
| 637 if (selected_range_ != overlapped_range.get()) | 681 if (selected_range_ != overlapped_range.get()) |
| 638 return; | 682 return; |
| 639 | 683 |
| 640 // If the |overlapped_range| transfers its next buffer position to | 684 // If the |overlapped_range| transfers its next buffer position to |
| 641 // |new_next_range|, make |new_next_range| the |selected_range_|. | 685 // |new_next_range|, make |new_next_range| the |selected_range_|. |
| 642 if (new_next_range && new_next_range->HasNextBufferPosition()) { | 686 if (new_next_range && new_next_range->HasNextBufferPosition()) { |
| 643 DCHECK(!overlapped_range->HasNextBufferPosition()); | 687 DCHECK(!overlapped_range->HasNextBufferPosition()); |
| 644 SetSelectedRange(new_next_range); | 688 SetSelectedRange(new_next_range); |
| 645 return; | 689 return; |
| 646 } | 690 } |
| 647 | 691 |
| 648 // Save the buffers in |overlapped_range|. | 692 // Save the buffers in |overlapped_range|. |
| 649 DCHECK(!*deleted_next_buffer); | 693 DCHECK(!*deleted_next_buffer); |
| 650 DCHECK_EQ(overlapped_range.get(), selected_range_); | 694 DCHECK_EQ(overlapped_range.get(), selected_range_); |
| 651 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers); | 695 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers); |
| 652 DCHECK(*deleted_next_buffer); | 696 DCHECK(*deleted_next_buffer); |
| 653 | 697 |
| 654 // |overlapped_range| will be deleted, so set |selected_range_| to NULL. | 698 // |overlapped_range| will be deleted, so set |selected_range_| to NULL. |
| 655 SetSelectedRange(NULL); | 699 SetSelectedRange(NULL); |
| 656 } | 700 } |
| 657 | 701 |
| 658 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { | 702 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { |
| 659 DCHECK(!deleted_buffers.empty()); | 703 DCHECK(!deleted_buffers.empty()); |
| 660 if (!track_buffer_.empty()) | |
| 661 return; | |
| 662 | |
| 663 DCHECK(selected_range_); | 704 DCHECK(selected_range_); |
| 664 DCHECK(selected_range_->HasNextBufferPosition()); | 705 DCHECK(selected_range_->HasNextBufferPosition()); |
| 665 | 706 |
| 666 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); | 707 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); |
| 667 | 708 |
| 668 // If there is no gap between what was deleted and what was added, nothing | 709 // If there is no gap between what was deleted and what was added, nothing |
| 669 // should be added to the track buffer. | 710 // should be added to the track buffer. |
| 670 if (selected_range_->HasNextBuffer() && | 711 if (selected_range_->HasNextBuffer() && |
| 671 (next_keyframe_timestamp == | 712 (next_keyframe_timestamp == |
| 672 deleted_buffers.front()->GetDecodeTimestamp())) { | 713 deleted_buffers.front()->GetDecodeTimestamp())) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 RangeList::iterator itr = ranges_.end(); | 803 RangeList::iterator itr = ranges_.end(); |
| 763 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { | 804 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { |
| 764 if ((*itr)->GetEndTimestamp() > duration) | 805 if ((*itr)->GetEndTimestamp() > duration) |
| 765 break; | 806 break; |
| 766 } | 807 } |
| 767 if (itr == ranges_.end()) | 808 if (itr == ranges_.end()) |
| 768 return; | 809 return; |
| 769 | 810 |
| 770 // Need to partially truncate this range. | 811 // Need to partially truncate this range. |
| 771 if ((*itr)->GetStartTimestamp() < duration) { | 812 if ((*itr)->GetStartTimestamp() < duration) { |
| 772 bool deleted_seek_point = (*itr)->TruncateAt(duration); | 813 bool deleted_seek_point = (*itr)->TruncateAt(duration, NULL, false); |
| 773 if (deleted_seek_point) | 814 if (deleted_seek_point) |
| 774 ResetSeekState(); | 815 ResetSeekState(); |
| 775 ++itr; | 816 ++itr; |
| 776 } | 817 } |
| 777 | 818 |
| 778 // Delete all ranges that begin after |duration|. | 819 // Delete all ranges that begin after |duration|. |
| 779 while (itr != ranges_.end()) { | 820 while (itr != ranges_.end()) { |
| 780 // If we're about to delete the selected range, also reset the seek state. | 821 // If we're about to delete the selected range, also reset the seek state. |
| 781 DCHECK((*itr)->GetStartTimestamp() >= duration); | 822 DCHECK((*itr)->GetStartTimestamp() >= duration); |
| 782 if (*itr== selected_range_) | 823 if (*itr== selected_range_) |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 } | 1092 } |
| 1052 next_buffer_index_ = result->second; | 1093 next_buffer_index_ = result->second; |
| 1053 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 1094 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
| 1054 } | 1095 } |
| 1055 | 1096 |
| 1056 void SourceBufferRange::SeekToStart() { | 1097 void SourceBufferRange::SeekToStart() { |
| 1057 DCHECK(!buffers_.empty()); | 1098 DCHECK(!buffers_.empty()); |
| 1058 next_buffer_index_ = 0; | 1099 next_buffer_index_ = 0; |
| 1059 } | 1100 } |
| 1060 | 1101 |
| 1061 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) { | 1102 SourceBufferRange* SourceBufferRange::SplitRange( |
| 1062 // Find the first keyframe after |timestamp|, not including |timestamp|. | 1103 base::TimeDelta timestamp, bool is_exclusive) { |
| 1104 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not |
| 1105 // include keyframes at |timestamp|. |
| 1063 KeyframeMap::iterator new_beginning_keyframe = | 1106 KeyframeMap::iterator new_beginning_keyframe = |
| 1064 GetFirstKeyframeAt(timestamp, true); | 1107 GetFirstKeyframeAt(timestamp, is_exclusive); |
| 1065 | 1108 |
| 1066 // If there is no keyframe after |timestamp|, we can't split the range. | 1109 // If there is no keyframe after |timestamp|, we can't split the range. |
| 1067 if (new_beginning_keyframe == keyframe_map_.end()) | 1110 if (new_beginning_keyframe == keyframe_map_.end()) |
| 1068 return NULL; | 1111 return NULL; |
| 1069 | 1112 |
| 1070 // Remove the data beginning at |keyframe_index| from |buffers_| and save it | 1113 // Remove the data beginning at |keyframe_index| from |buffers_| and save it |
| 1071 // into |removed_buffers|. | 1114 // into |removed_buffers|. |
| 1072 int keyframe_index = new_beginning_keyframe->second; | 1115 int keyframe_index = new_beginning_keyframe->second; |
| 1073 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); | 1116 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); |
| 1074 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; | 1117 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1089 ResetNextBufferPosition(); | 1132 ResetNextBufferPosition(); |
| 1090 } else if (waiting_for_keyframe_) { | 1133 } else if (waiting_for_keyframe_) { |
| 1091 split_range->waiting_for_keyframe_ = true; | 1134 split_range->waiting_for_keyframe_ = true; |
| 1092 split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_; | 1135 split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_; |
| 1093 ResetNextBufferPosition(); | 1136 ResetNextBufferPosition(); |
| 1094 } | 1137 } |
| 1095 | 1138 |
| 1096 return split_range; | 1139 return split_range; |
| 1097 } | 1140 } |
| 1098 | 1141 |
| 1142 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt( |
| 1143 base::TimeDelta timestamp, bool skip_given_timestamp) { |
| 1144 // Need to make a dummy buffer with timestamp |timestamp| in order to search |
| 1145 // the |buffers_| container. |
| 1146 scoped_refptr<StreamParserBuffer> dummy_buffer = |
| 1147 StreamParserBuffer::CopyFrom(NULL, 0, false); |
| 1148 dummy_buffer->SetDecodeTimestamp(timestamp); |
| 1149 |
| 1150 if (skip_given_timestamp) { |
| 1151 return std::upper_bound( |
| 1152 buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator); |
| 1153 } |
| 1154 return std::lower_bound( |
| 1155 buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator); |
| 1156 } |
| 1157 |
| 1099 SourceBufferRange::KeyframeMap::iterator | 1158 SourceBufferRange::KeyframeMap::iterator |
| 1100 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp, | 1159 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp, |
| 1101 bool skip_given_timestamp) { | 1160 bool skip_given_timestamp) { |
| 1102 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | 1161 return skip_given_timestamp ? |
| 1103 // lower_bound() returns the first element >= |timestamp|, so if we don't want | 1162 keyframe_map_.upper_bound(timestamp) : |
| 1104 // to include keyframes == |timestamp|, we have to increment the iterator | 1163 keyframe_map_.lower_bound(timestamp); |
| 1105 // accordingly. | |
| 1106 if (skip_given_timestamp && | |
| 1107 result != keyframe_map_.end() && result->first == timestamp) { | |
| 1108 ++result; | |
| 1109 } | |
| 1110 return result; | |
| 1111 } | 1164 } |
| 1112 | 1165 |
| 1113 SourceBufferRange::KeyframeMap::iterator | 1166 SourceBufferRange::KeyframeMap::iterator |
| 1114 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) { | 1167 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) { |
| 1115 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | 1168 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); |
| 1116 // lower_bound() returns the first element >= |timestamp|, so we want the | 1169 // lower_bound() returns the first element >= |timestamp|, so we want the |
| 1117 // previous element if it did not return the element exactly equal to | 1170 // previous element if it did not return the element exactly equal to |
| 1118 // |timestamp|. | 1171 // |timestamp|. |
| 1119 if (result != keyframe_map_.begin() && | 1172 if (result != keyframe_map_.begin() && |
| 1120 (result == keyframe_map_.end() || result->first != timestamp)) { | 1173 (result == keyframe_map_.end() || result->first != timestamp)) { |
| 1121 --result; | 1174 --result; |
| 1122 } | 1175 } |
| 1123 return result; | 1176 return result; |
| 1124 } | 1177 } |
| 1125 | 1178 |
| 1126 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { | 1179 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { |
| 1127 return TruncateAt(buffers_.begin(), removed_buffers); | 1180 return TruncateAt(buffers_.begin(), removed_buffers); |
| 1128 } | 1181 } |
| 1129 | 1182 |
| 1130 bool SourceBufferRange::TruncateAt(base::TimeDelta timestamp) { | |
| 1131 // Need to make a dummy buffer with timestamp |timestamp| in order to search | |
| 1132 // the |buffers_| container. | |
| 1133 scoped_refptr<StreamParserBuffer> dummy_buffer = | |
| 1134 StreamParserBuffer::CopyFrom(NULL, 0, false); | |
| 1135 dummy_buffer->SetDecodeTimestamp(timestamp); | |
| 1136 return TruncateAt(dummy_buffer, NULL); | |
| 1137 } | |
| 1138 | |
| 1139 bool SourceBufferRange::TruncateAt( | 1183 bool SourceBufferRange::TruncateAt( |
| 1140 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) { | 1184 base::TimeDelta timestamp, BufferQueue* removed_buffers, |
| 1185 bool is_exclusive) { |
| 1141 // Find the place in |buffers_| where we will begin deleting data. | 1186 // Find the place in |buffers_| where we will begin deleting data. |
| 1142 BufferQueue::iterator starting_point = | 1187 BufferQueue::iterator starting_point = |
| 1143 std::lower_bound(buffers_.begin(), buffers_.end(), | 1188 GetBufferItrAt(timestamp, is_exclusive); |
| 1144 buffer, | |
| 1145 BufferComparator); | |
| 1146 return TruncateAt(starting_point, removed_buffers); | 1189 return TruncateAt(starting_point, removed_buffers); |
| 1147 } | 1190 } |
| 1148 | 1191 |
| 1149 int SourceBufferRange::FreeFromStart(int bytes) { | 1192 int SourceBufferRange::FreeFromStart(int bytes) { |
| 1150 KeyframeMap::iterator deletion_limit = keyframe_map_.end(); | 1193 KeyframeMap::iterator deletion_limit = keyframe_map_.end(); |
| 1151 if (HasNextBufferPosition()) { | 1194 if (HasNextBufferPosition()) { |
| 1152 base::TimeDelta next_timestamp = GetNextTimestamp(); | 1195 base::TimeDelta next_timestamp = GetNextTimestamp(); |
| 1153 if (next_timestamp != kNoTimestamp()) { | 1196 if (next_timestamp != kNoTimestamp()) { |
| 1154 deletion_limit = GetFirstKeyframeBefore(next_timestamp); | 1197 deletion_limit = GetFirstKeyframeBefore(next_timestamp); |
| 1155 } else { | 1198 } else { |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1407 } | 1450 } |
| 1408 | 1451 |
| 1409 bool SourceBufferRange::IsNextInSequence( | 1452 bool SourceBufferRange::IsNextInSequence( |
| 1410 const scoped_refptr<media::StreamParserBuffer>& buffer, | 1453 const scoped_refptr<media::StreamParserBuffer>& buffer, |
| 1411 base::TimeDelta timestamp) const { | 1454 base::TimeDelta timestamp) const { |
| 1412 return buffer->GetDecodeTimestamp() < timestamp && | 1455 return buffer->GetDecodeTimestamp() < timestamp && |
| 1413 timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom(); | 1456 timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom(); |
| 1414 } | 1457 } |
| 1415 | 1458 |
| 1416 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { | 1459 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { |
| 1417 // Because we do not know exactly when is the next timestamp, any buffer | 1460 return ComputeFudgeRoom(GetApproximateDuration()); |
| 1418 // that starts within 2x the approximate duration of a buffer is considered | |
| 1419 // within this range. | |
| 1420 return 2 * GetApproximateDuration(); | |
| 1421 } | 1461 } |
| 1422 | 1462 |
| 1423 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 1463 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
| 1424 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 1464 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
| 1425 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 1465 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
| 1426 return max_interbuffer_distance; | 1466 return max_interbuffer_distance; |
| 1427 } | 1467 } |
| 1428 | 1468 |
| 1429 } // namespace media | 1469 } // namespace media |
| OLD | NEW |