Chromium Code Reviews| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 // Returns true if the end of this range contains buffers that overlaps with | 147 // Returns true if the end of this range contains buffers that overlaps with |
| 148 // the beginning of |range|. | 148 // the beginning of |range|. |
| 149 bool EndOverlaps(const SourceBufferRange& range) const; | 149 bool EndOverlaps(const SourceBufferRange& range) const; |
| 150 | 150 |
| 151 // Returns true if |timestamp| is the timestamp of the next buffer in | 151 // Returns true if |timestamp| is the timestamp of the next buffer in |
| 152 // sequence after |buffer|, false otherwise. | 152 // sequence after |buffer|, false otherwise. |
| 153 bool IsNextInSequence( | 153 bool IsNextInSequence( |
| 154 const scoped_refptr<media::StreamParserBuffer>& buffer, | 154 const scoped_refptr<media::StreamParserBuffer>& buffer, |
| 155 base::TimeDelta timestamp) const; | 155 base::TimeDelta timestamp) const; |
| 156 | 156 |
| 157 // Returns true if |second_timestamp| is the timestamp of the next buffer in | |
| 158 // sequence after |first_timestamp|, false otherwise. | |
| 159 bool AreAdjacentInSequence( | |
| 160 base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const; | |
| 161 | |
| 157 int size_in_bytes() const { return size_in_bytes_; } | 162 int size_in_bytes() const { return size_in_bytes_; } |
| 158 | 163 |
| 159 private: | 164 private: |
| 160 typedef std::map<base::TimeDelta, size_t> KeyframeMap; | 165 typedef std::map<base::TimeDelta, size_t> KeyframeMap; |
| 161 | 166 |
| 162 // Seeks the range to the next keyframe after |timestamp|. If | 167 // 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 | 168 // |skip_given_timestamp| is true, the seek will go to a keyframe with a |
| 164 // timestamp strictly greater than |timestamp|. | 169 // timestamp strictly greater than |timestamp|. |
| 165 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp); | 170 void SeekAhead(base::TimeDelta timestamp, bool skip_given_timestamp); |
| 166 | 171 |
| 172 // Returns an iterator in |buffers_| pointing to the buffer at |timestamp|. | |
| 173 // If |skip_given_timestamp| is true, this returns the first buffer with | |
| 174 // timestamp greater than |timestamp|. | |
| 175 BufferQueue::iterator GetBufferItrAt( | |
| 176 base::TimeDelta timestamp, bool skip_given_timestamp); | |
| 177 | |
| 167 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after | 178 // Returns an iterator in |keyframe_map_| pointing to the next keyframe after |
| 168 // |timestamp|. If |skip_given_timestamp| is true, this returns the first | 179 // |timestamp|. If |skip_given_timestamp| is true, this returns the first |
| 169 // keyframe with a timestamp strictly greater than |timestamp|. | 180 // keyframe with a timestamp strictly greater than |timestamp|. |
| 170 KeyframeMap::iterator GetFirstKeyframeAt( | 181 KeyframeMap::iterator GetFirstKeyframeAt( |
| 171 base::TimeDelta timestamp, bool skip_given_timestamp); | 182 base::TimeDelta timestamp, bool skip_given_timestamp); |
| 172 | 183 |
| 173 // Returns an iterator in |keyframe_map_| pointing to the first keyframe | 184 // Returns an iterator in |keyframe_map_| pointing to the first keyframe |
| 174 // before or at |timestamp|. | 185 // before or at |timestamp|. |
| 175 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp); | 186 KeyframeMap::iterator GetFirstKeyframeBefore(base::TimeDelta timestamp); |
| 176 | 187 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 310 ranges_.pop_front(); | 321 ranges_.pop_front(); |
| 311 } | 322 } |
| 312 | 323 |
| 313 STLDeleteElements(&audio_configs_); | 324 STLDeleteElements(&audio_configs_); |
| 314 STLDeleteElements(&video_configs_); | 325 STLDeleteElements(&video_configs_); |
| 315 } | 326 } |
| 316 | 327 |
| 317 void SourceBufferStream::OnNewMediaSegment( | 328 void SourceBufferStream::OnNewMediaSegment( |
| 318 base::TimeDelta media_segment_start_time) { | 329 base::TimeDelta media_segment_start_time) { |
| 319 media_segment_start_time_ = media_segment_start_time; | 330 media_segment_start_time_ = media_segment_start_time; |
| 331 new_media_segment_ = true; | |
| 320 | 332 |
| 321 // Find the range that will house the buffers appended through the next | 333 RangeList::iterator last_range = range_for_next_append_; |
| 322 // Append() call. | |
| 323 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); | 334 range_for_next_append_ = FindExistingRangeFor(media_segment_start_time); |
| 324 new_media_segment_ = true; | 335 |
| 325 last_buffer_timestamp_ = kNoTimestamp(); | 336 // Only reset |last_buffer_timestamp_| if this new media segment is not |
| 337 // adjacent to the previous media segment appended to the stream. | |
| 338 if (range_for_next_append_ == ranges_.end() || | |
| 339 !(*range_for_next_append_)->AreAdjacentInSequence( | |
| 340 last_buffer_timestamp_, media_segment_start_time)) { | |
| 341 last_buffer_timestamp_ = kNoTimestamp(); | |
| 342 } else { | |
| 343 DCHECK(last_range == range_for_next_append_); | |
| 344 } | |
| 326 } | 345 } |
| 327 | 346 |
| 328 bool SourceBufferStream::Append( | 347 bool SourceBufferStream::Append( |
| 329 const SourceBufferStream::BufferQueue& buffers) { | 348 const SourceBufferStream::BufferQueue& buffers) { |
| 330 DCHECK(!buffers.empty()); | 349 DCHECK(!buffers.empty()); |
| 331 DCHECK(media_segment_start_time_ != kNoTimestamp()); | 350 DCHECK(media_segment_start_time_ != kNoTimestamp()); |
| 332 | 351 |
| 333 // New media segments must begin with a keyframe. | 352 // New media segments must begin with a keyframe. |
| 334 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { | 353 if (new_media_segment_ && !buffers.front()->IsKeyframe()) { |
| 335 DVLOG(1) << "Media segment did not begin with keyframe."; | 354 DVLOG(1) << "Media segment did not begin with keyframe."; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 | 551 |
| 533 void SourceBufferStream::InsertIntoExistingRange( | 552 void SourceBufferStream::InsertIntoExistingRange( |
| 534 const RangeList::iterator& range_for_new_buffers_itr, | 553 const RangeList::iterator& range_for_new_buffers_itr, |
| 535 const BufferQueue& new_buffers, | 554 const BufferQueue& new_buffers, |
| 536 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { | 555 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
| 537 DCHECK(deleted_next_buffer); | 556 DCHECK(deleted_next_buffer); |
| 538 DCHECK(deleted_buffers); | 557 DCHECK(deleted_buffers); |
| 539 | 558 |
| 540 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; | 559 SourceBufferRange* range_for_new_buffers = *range_for_new_buffers_itr; |
| 541 | 560 |
| 542 // If this is a simple case where we can just append to the end of the range, | 561 if (last_buffer_timestamp_ != kNoTimestamp()) { |
| 543 // do so and return. | 562 // Clean up the old buffers between the last appended buffer and the |
| 544 if (range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) { | 563 // beginning of |new_buffers|. |
| 545 range_for_new_buffers->AppendBuffersToEnd(new_buffers); | 564 *deleted_next_buffer = |
| 546 return; | 565 DeleteBetween( |
| 566 range_for_new_buffers, last_buffer_timestamp_, | |
| 567 new_buffers.front()->GetDecodeTimestamp(), true, | |
| 568 deleted_buffers); | |
| 547 } | 569 } |
| 548 | 570 |
| 549 // Otherwise, this is either a start overlap or an middle overlap. | 571 // If we cannot append the |new_buffers| to the end of the existing range, |
| 572 // this is either a start overlap or an middle overlap. Delete the buffers | |
| 573 // that |new_buffers| overlaps. | |
| 574 if (!range_for_new_buffers->CanAppendBuffersToEnd(new_buffers)) { | |
| 575 *deleted_next_buffer |= | |
| 576 DeleteBetween( | |
| 577 range_for_new_buffers, new_buffers.front()->GetDecodeTimestamp(), | |
| 578 new_buffers.back()->GetDecodeTimestamp(), false, | |
| 579 deleted_buffers); | |
| 580 } | |
| 550 | 581 |
| 551 // In case this is a middle overlap, save the buffers that come after the end | 582 range_for_new_buffers->AppendBuffersToEnd(new_buffers); |
| 552 // of |new_buffers|, and add them into a new range. | 583 } |
| 584 | |
| 585 bool SourceBufferStream::DeleteBetween( | |
| 586 SourceBufferRange* range, base::TimeDelta start_timestamp, | |
| 587 base::TimeDelta end_timestamp, bool is_range_exclusive, | |
| 588 BufferQueue* deleted_buffers) { | |
| 553 SourceBufferRange* new_next_range = | 589 SourceBufferRange* new_next_range = |
| 554 range_for_new_buffers->SplitRange( | 590 range->SplitRange(end_timestamp, is_range_exclusive); |
| 555 new_buffers.back()->GetDecodeTimestamp()); | |
| 556 | 591 |
| 557 if (new_next_range) | 592 if (new_next_range) |
| 558 AddToRanges(new_next_range); | 593 AddToRanges(new_next_range); |
| 559 | 594 |
| 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; | 595 BufferQueue saved_buffers; |
| 563 bool deleted_next_buffer_from_range = | 596 bool deleted_next_buffer = |
| 564 range_for_new_buffers->TruncateAt(new_buffers.front(), &saved_buffers); | 597 range->TruncateAt(start_timestamp, &saved_buffers, is_range_exclusive); |
| 565 range_for_new_buffers->AppendBuffersToEnd(new_buffers); | |
| 566 | 598 |
| 567 if (selected_range_ != range_for_new_buffers) | 599 if (selected_range_ != range) |
| 568 return; | 600 return deleted_next_buffer; |
| 569 | 601 |
| 570 DCHECK(!*deleted_next_buffer); | |
| 571 *deleted_buffers = saved_buffers; | 602 *deleted_buffers = saved_buffers; |
|
acolwell GONE FROM CHROMIUM
2012/09/19 23:15:51
DCHECK(deleted_buffers->empty()) right before this
vrk (LEFT CHROMIUM)
2012/09/20 00:00:59
Good idea, done.
| |
| 572 *deleted_next_buffer = deleted_next_buffer_from_range; | |
| 573 | 603 |
| 574 // If this was a middle overlap resulting in a new range, and the next buffer | 604 // 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 | 605 // selected range accordingly. |
| 576 // |selected_range_| accordingly. | |
| 577 if (new_next_range && new_next_range->HasNextBufferPosition()) { | 606 if (new_next_range && new_next_range->HasNextBufferPosition()) { |
| 578 DCHECK(!range_for_new_buffers->HasNextBufferPosition()); | 607 DCHECK(!range->HasNextBufferPosition()); |
| 579 DCHECK(!*deleted_next_buffer); | 608 DCHECK(!deleted_next_buffer); |
| 580 SetSelectedRange(new_next_range); | 609 SetSelectedRange(new_next_range); |
| 581 } | 610 } |
| 611 return deleted_next_buffer; | |
| 582 } | 612 } |
| 583 | 613 |
| 584 void SourceBufferStream::ResolveCompleteOverlaps( | 614 void SourceBufferStream::ResolveCompleteOverlaps( |
| 585 const RangeList::iterator& range_with_new_buffers_itr, | 615 const RangeList::iterator& range_with_new_buffers_itr, |
| 586 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { | 616 bool* deleted_next_buffer, BufferQueue* deleted_buffers) { |
| 587 DCHECK(deleted_next_buffer); | 617 DCHECK(deleted_next_buffer); |
| 588 DCHECK(deleted_buffers); | 618 DCHECK(deleted_buffers); |
| 589 | 619 |
| 590 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; | 620 SourceBufferRange* range_with_new_buffers = *range_with_new_buffers_itr; |
| 591 RangeList::iterator next_range_itr = range_with_new_buffers_itr; | 621 RangeList::iterator next_range_itr = range_with_new_buffers_itr; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 620 } | 650 } |
| 621 | 651 |
| 622 // Split the overlapped range after |range_with_new_buffers|'s last buffer | 652 // Split the overlapped range after |range_with_new_buffers|'s last buffer |
| 623 // overlaps. Now |overlapped_range| contains only the buffers that do not | 653 // overlaps. Now |overlapped_range| contains only the buffers that do not |
| 624 // belong in |ranges_| anymore, and |new_next_range| contains buffers that | 654 // belong in |ranges_| anymore, and |new_next_range| contains buffers that |
| 625 // go after |range_with_new_buffers| (without overlap). | 655 // go after |range_with_new_buffers| (without overlap). |
| 626 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr); | 656 scoped_ptr<SourceBufferRange> overlapped_range(*next_range_itr); |
| 627 next_range_itr = ranges_.erase(next_range_itr); | 657 next_range_itr = ranges_.erase(next_range_itr); |
| 628 | 658 |
| 629 SourceBufferRange* new_next_range = | 659 SourceBufferRange* new_next_range = |
| 630 overlapped_range->SplitRange(range_with_new_buffers->GetEndTimestamp()); | 660 overlapped_range->SplitRange( |
| 661 range_with_new_buffers->GetEndTimestamp(), true); | |
| 631 | 662 |
| 632 // If there were non-overlapped buffers, add the new range to |ranges_|. | 663 // If there were non-overlapped buffers, add the new range to |ranges_|. |
| 633 if (new_next_range) | 664 if (new_next_range) |
| 634 AddToRanges(new_next_range); | 665 AddToRanges(new_next_range); |
| 635 | 666 |
| 636 // If we didn't overlap a selected range, return. | 667 // If we didn't overlap a selected range, return. |
| 637 if (selected_range_ != overlapped_range.get()) | 668 if (selected_range_ != overlapped_range.get()) |
| 638 return; | 669 return; |
| 639 | 670 |
| 640 // If the |overlapped_range| transfers its next buffer position to | 671 // If the |overlapped_range| transfers its next buffer position to |
| 641 // |new_next_range|, make |new_next_range| the |selected_range_|. | 672 // |new_next_range|, make |new_next_range| the |selected_range_|. |
| 642 if (new_next_range && new_next_range->HasNextBufferPosition()) { | 673 if (new_next_range && new_next_range->HasNextBufferPosition()) { |
| 643 DCHECK(!overlapped_range->HasNextBufferPosition()); | 674 DCHECK(!overlapped_range->HasNextBufferPosition()); |
| 644 SetSelectedRange(new_next_range); | 675 SetSelectedRange(new_next_range); |
| 645 return; | 676 return; |
| 646 } | 677 } |
| 647 | 678 |
| 648 // Save the buffers in |overlapped_range|. | 679 // Save the buffers in |overlapped_range|. |
| 649 DCHECK(!*deleted_next_buffer); | 680 DCHECK(!*deleted_next_buffer); |
| 650 DCHECK_EQ(overlapped_range.get(), selected_range_); | 681 DCHECK_EQ(overlapped_range.get(), selected_range_); |
| 651 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers); | 682 *deleted_next_buffer = overlapped_range->DeleteAll(deleted_buffers); |
| 652 DCHECK(*deleted_next_buffer); | 683 DCHECK(*deleted_next_buffer); |
| 653 | 684 |
| 654 // |overlapped_range| will be deleted, so set |selected_range_| to NULL. | 685 // |overlapped_range| will be deleted, so set |selected_range_| to NULL. |
| 655 SetSelectedRange(NULL); | 686 SetSelectedRange(NULL); |
| 656 } | 687 } |
| 657 | 688 |
| 658 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { | 689 void SourceBufferStream::UpdateTrackBuffer(const BufferQueue& deleted_buffers) { |
| 659 DCHECK(!deleted_buffers.empty()); | 690 DCHECK(!deleted_buffers.empty()); |
| 660 if (!track_buffer_.empty()) | |
| 661 return; | |
| 662 | |
| 663 DCHECK(selected_range_); | 691 DCHECK(selected_range_); |
| 664 DCHECK(selected_range_->HasNextBufferPosition()); | 692 DCHECK(selected_range_->HasNextBufferPosition()); |
| 665 | 693 |
| 666 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); | 694 base::TimeDelta next_keyframe_timestamp = selected_range_->GetNextTimestamp(); |
| 667 | 695 |
| 668 // If there is no gap between what was deleted and what was added, nothing | 696 // If there is no gap between what was deleted and what was added, nothing |
| 669 // should be added to the track buffer. | 697 // should be added to the track buffer. |
| 670 if (selected_range_->HasNextBuffer() && | 698 if (selected_range_->HasNextBuffer() && |
| 671 (next_keyframe_timestamp == | 699 (next_keyframe_timestamp == |
| 672 deleted_buffers.front()->GetDecodeTimestamp())) { | 700 deleted_buffers.front()->GetDecodeTimestamp())) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 762 RangeList::iterator itr = ranges_.end(); | 790 RangeList::iterator itr = ranges_.end(); |
| 763 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { | 791 for (itr = ranges_.begin(); itr != ranges_.end(); ++itr) { |
| 764 if ((*itr)->GetEndTimestamp() > duration) | 792 if ((*itr)->GetEndTimestamp() > duration) |
| 765 break; | 793 break; |
| 766 } | 794 } |
| 767 if (itr == ranges_.end()) | 795 if (itr == ranges_.end()) |
| 768 return; | 796 return; |
| 769 | 797 |
| 770 // Need to partially truncate this range. | 798 // Need to partially truncate this range. |
| 771 if ((*itr)->GetStartTimestamp() < duration) { | 799 if ((*itr)->GetStartTimestamp() < duration) { |
| 772 bool deleted_seek_point = (*itr)->TruncateAt(duration); | 800 bool deleted_seek_point = (*itr)->TruncateAt(duration, NULL, false); |
| 773 if (deleted_seek_point) | 801 if (deleted_seek_point) |
| 774 ResetSeekState(); | 802 ResetSeekState(); |
| 775 ++itr; | 803 ++itr; |
| 776 } | 804 } |
| 777 | 805 |
| 778 // Delete all ranges that begin after |duration|. | 806 // Delete all ranges that begin after |duration|. |
| 779 while (itr != ranges_.end()) { | 807 while (itr != ranges_.end()) { |
| 780 // If we're about to delete the selected range, also reset the seek state. | 808 // If we're about to delete the selected range, also reset the seek state. |
| 781 DCHECK((*itr)->GetStartTimestamp() >= duration); | 809 DCHECK((*itr)->GetStartTimestamp() >= duration); |
| 782 if (*itr== selected_range_) | 810 if (*itr== selected_range_) |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1051 } | 1079 } |
| 1052 next_buffer_index_ = result->second; | 1080 next_buffer_index_ = result->second; |
| 1053 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); | 1081 DCHECK_LT(next_buffer_index_, static_cast<int>(buffers_.size())); |
| 1054 } | 1082 } |
| 1055 | 1083 |
| 1056 void SourceBufferRange::SeekToStart() { | 1084 void SourceBufferRange::SeekToStart() { |
| 1057 DCHECK(!buffers_.empty()); | 1085 DCHECK(!buffers_.empty()); |
| 1058 next_buffer_index_ = 0; | 1086 next_buffer_index_ = 0; |
| 1059 } | 1087 } |
| 1060 | 1088 |
| 1061 SourceBufferRange* SourceBufferRange::SplitRange(base::TimeDelta timestamp) { | 1089 SourceBufferRange* SourceBufferRange::SplitRange( |
| 1062 // Find the first keyframe after |timestamp|, not including |timestamp|. | 1090 base::TimeDelta timestamp, bool is_exclusive) { |
| 1091 // Find the first keyframe after |timestamp|. If |is_exclusive|, do not | |
| 1092 // include keyframes at |timestamp|. | |
| 1063 KeyframeMap::iterator new_beginning_keyframe = | 1093 KeyframeMap::iterator new_beginning_keyframe = |
| 1064 GetFirstKeyframeAt(timestamp, true); | 1094 GetFirstKeyframeAt(timestamp, is_exclusive); |
| 1065 | 1095 |
| 1066 // If there is no keyframe after |timestamp|, we can't split the range. | 1096 // If there is no keyframe after |timestamp|, we can't split the range. |
| 1067 if (new_beginning_keyframe == keyframe_map_.end()) | 1097 if (new_beginning_keyframe == keyframe_map_.end()) |
| 1068 return NULL; | 1098 return NULL; |
| 1069 | 1099 |
| 1070 // Remove the data beginning at |keyframe_index| from |buffers_| and save it | 1100 // Remove the data beginning at |keyframe_index| from |buffers_| and save it |
| 1071 // into |removed_buffers|. | 1101 // into |removed_buffers|. |
| 1072 int keyframe_index = new_beginning_keyframe->second; | 1102 int keyframe_index = new_beginning_keyframe->second; |
| 1073 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); | 1103 DCHECK_LT(keyframe_index, static_cast<int>(buffers_.size())); |
| 1074 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; | 1104 BufferQueue::iterator starting_point = buffers_.begin() + keyframe_index; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1089 ResetNextBufferPosition(); | 1119 ResetNextBufferPosition(); |
| 1090 } else if (waiting_for_keyframe_) { | 1120 } else if (waiting_for_keyframe_) { |
| 1091 split_range->waiting_for_keyframe_ = true; | 1121 split_range->waiting_for_keyframe_ = true; |
| 1092 split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_; | 1122 split_range->next_keyframe_timestamp_ = next_keyframe_timestamp_; |
| 1093 ResetNextBufferPosition(); | 1123 ResetNextBufferPosition(); |
| 1094 } | 1124 } |
| 1095 | 1125 |
| 1096 return split_range; | 1126 return split_range; |
| 1097 } | 1127 } |
| 1098 | 1128 |
| 1129 SourceBufferRange::BufferQueue::iterator SourceBufferRange::GetBufferItrAt( | |
| 1130 base::TimeDelta timestamp, bool skip_given_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 | |
| 1137 if (skip_given_timestamp) { | |
| 1138 return std::upper_bound( | |
| 1139 buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator); | |
| 1140 } else { | |
|
acolwell GONE FROM CHROMIUM
2012/09/19 23:15:51
nit: drop else and deindent
vrk (LEFT CHROMIUM)
2012/09/20 00:00:59
Done.
| |
| 1141 return std::lower_bound( | |
| 1142 buffers_.begin(), buffers_.end(), dummy_buffer, BufferComparator); | |
| 1143 } | |
| 1144 } | |
| 1145 | |
| 1099 SourceBufferRange::KeyframeMap::iterator | 1146 SourceBufferRange::KeyframeMap::iterator |
| 1100 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp, | 1147 SourceBufferRange::GetFirstKeyframeAt(base::TimeDelta timestamp, |
| 1101 bool skip_given_timestamp) { | 1148 bool skip_given_timestamp) { |
| 1102 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | 1149 return skip_given_timestamp ? |
| 1103 // lower_bound() returns the first element >= |timestamp|, so if we don't want | 1150 keyframe_map_.upper_bound(timestamp) : |
| 1104 // to include keyframes == |timestamp|, we have to increment the iterator | 1151 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 } | 1152 } |
| 1112 | 1153 |
| 1113 SourceBufferRange::KeyframeMap::iterator | 1154 SourceBufferRange::KeyframeMap::iterator |
| 1114 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) { | 1155 SourceBufferRange::GetFirstKeyframeBefore(base::TimeDelta timestamp) { |
| 1115 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); | 1156 KeyframeMap::iterator result = keyframe_map_.lower_bound(timestamp); |
| 1116 // lower_bound() returns the first element >= |timestamp|, so we want the | 1157 // lower_bound() returns the first element >= |timestamp|, so we want the |
| 1117 // previous element if it did not return the element exactly equal to | 1158 // previous element if it did not return the element exactly equal to |
| 1118 // |timestamp|. | 1159 // |timestamp|. |
| 1119 if (result != keyframe_map_.begin() && | 1160 if (result != keyframe_map_.begin() && |
| 1120 (result == keyframe_map_.end() || result->first != timestamp)) { | 1161 (result == keyframe_map_.end() || result->first != timestamp)) { |
| 1121 --result; | 1162 --result; |
| 1122 } | 1163 } |
| 1123 return result; | 1164 return result; |
| 1124 } | 1165 } |
| 1125 | 1166 |
| 1126 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { | 1167 bool SourceBufferRange::DeleteAll(BufferQueue* removed_buffers) { |
| 1127 return TruncateAt(buffers_.begin(), removed_buffers); | 1168 return TruncateAt(buffers_.begin(), removed_buffers); |
| 1128 } | 1169 } |
| 1129 | 1170 |
| 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( | 1171 bool SourceBufferRange::TruncateAt( |
| 1140 scoped_refptr<StreamParserBuffer> buffer, BufferQueue* removed_buffers) { | 1172 base::TimeDelta timestamp, BufferQueue* removed_buffers, |
| 1173 bool is_exclusive) { | |
| 1141 // Find the place in |buffers_| where we will begin deleting data. | 1174 // Find the place in |buffers_| where we will begin deleting data. |
| 1142 BufferQueue::iterator starting_point = | 1175 BufferQueue::iterator starting_point = |
| 1143 std::lower_bound(buffers_.begin(), buffers_.end(), | 1176 GetBufferItrAt(timestamp, is_exclusive); |
| 1144 buffer, | |
| 1145 BufferComparator); | |
| 1146 return TruncateAt(starting_point, removed_buffers); | 1177 return TruncateAt(starting_point, removed_buffers); |
| 1147 } | 1178 } |
| 1148 | 1179 |
| 1149 int SourceBufferRange::FreeFromStart(int bytes) { | 1180 int SourceBufferRange::FreeFromStart(int bytes) { |
| 1150 KeyframeMap::iterator deletion_limit = keyframe_map_.end(); | 1181 KeyframeMap::iterator deletion_limit = keyframe_map_.end(); |
| 1151 if (HasNextBufferPosition()) { | 1182 if (HasNextBufferPosition()) { |
| 1152 base::TimeDelta next_timestamp = GetNextTimestamp(); | 1183 base::TimeDelta next_timestamp = GetNextTimestamp(); |
| 1153 if (next_timestamp != kNoTimestamp()) { | 1184 if (next_timestamp != kNoTimestamp()) { |
| 1154 deletion_limit = GetFirstKeyframeBefore(next_timestamp); | 1185 deletion_limit = GetFirstKeyframeBefore(next_timestamp); |
| 1155 } else { | 1186 } else { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1402 DCHECK(!buffers_.empty()); | 1433 DCHECK(!buffers_.empty()); |
| 1403 base::TimeDelta duration = buffers_.back()->GetDuration(); | 1434 base::TimeDelta duration = buffers_.back()->GetDuration(); |
| 1404 if (duration == kNoTimestamp() || duration == base::TimeDelta()) | 1435 if (duration == kNoTimestamp() || duration == base::TimeDelta()) |
| 1405 duration = GetApproximateDuration(); | 1436 duration = GetApproximateDuration(); |
| 1406 return GetEndTimestamp() + duration; | 1437 return GetEndTimestamp() + duration; |
| 1407 } | 1438 } |
| 1408 | 1439 |
| 1409 bool SourceBufferRange::IsNextInSequence( | 1440 bool SourceBufferRange::IsNextInSequence( |
| 1410 const scoped_refptr<media::StreamParserBuffer>& buffer, | 1441 const scoped_refptr<media::StreamParserBuffer>& buffer, |
| 1411 base::TimeDelta timestamp) const { | 1442 base::TimeDelta timestamp) const { |
| 1412 return buffer->GetDecodeTimestamp() < timestamp && | 1443 return AreAdjacentInSequence(buffer->GetDecodeTimestamp(), timestamp); |
| 1413 timestamp <= buffer->GetDecodeTimestamp() + GetFudgeRoom(); | 1444 } |
| 1445 | |
| 1446 bool SourceBufferRange::AreAdjacentInSequence( | |
| 1447 base::TimeDelta first_timestamp, base::TimeDelta second_timestamp) const { | |
| 1448 return first_timestamp < second_timestamp && | |
| 1449 second_timestamp <= first_timestamp + GetFudgeRoom(); | |
| 1414 } | 1450 } |
| 1415 | 1451 |
| 1416 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { | 1452 base::TimeDelta SourceBufferRange::GetFudgeRoom() const { |
| 1417 // Because we do not know exactly when is the next timestamp, any buffer | 1453 // Because we do not know exactly when is the next timestamp, any buffer |
| 1418 // that starts within 2x the approximate duration of a buffer is considered | 1454 // that starts within 2x the approximate duration of a buffer is considered |
| 1419 // within this range. | 1455 // within this range. |
| 1420 return 2 * GetApproximateDuration(); | 1456 return 2 * GetApproximateDuration(); |
| 1421 } | 1457 } |
| 1422 | 1458 |
| 1423 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { | 1459 base::TimeDelta SourceBufferRange::GetApproximateDuration() const { |
| 1424 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); | 1460 base::TimeDelta max_interbuffer_distance = interbuffer_distance_cb_.Run(); |
| 1425 DCHECK(max_interbuffer_distance != kNoTimestamp()); | 1461 DCHECK(max_interbuffer_distance != kNoTimestamp()); |
| 1426 return max_interbuffer_distance; | 1462 return max_interbuffer_distance; |
| 1427 } | 1463 } |
| 1428 | 1464 |
| 1429 } // namespace media | 1465 } // namespace media |
| OLD | NEW |