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 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 // are appended to the range covered by |track_buffer_|. | 394 // are appended to the range covered by |track_buffer_|. |
| 395 if (!track_buffer_.empty()) { | 395 if (!track_buffer_.empty()) { |
| 396 DecodeTimestamp keyframe_timestamp = | 396 DecodeTimestamp keyframe_timestamp = |
| 397 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp()); | 397 FindKeyframeAfterTimestamp(track_buffer_.front()->GetDecodeTimestamp()); |
| 398 if (keyframe_timestamp != kNoDecodeTimestamp()) | 398 if (keyframe_timestamp != kNoDecodeTimestamp()) |
| 399 PruneTrackBuffer(keyframe_timestamp); | 399 PruneTrackBuffer(keyframe_timestamp); |
| 400 } | 400 } |
| 401 | 401 |
| 402 SetSelectedRangeIfNeeded(next_buffer_timestamp); | 402 SetSelectedRangeIfNeeded(next_buffer_timestamp); |
| 403 | 403 |
| 404 GarbageCollectIfNeeded(); | |
| 405 | |
| 406 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 404 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() |
| 407 << ": done. ranges_=" << RangesToString(ranges_); | 405 << ": done. ranges_=" << RangesToString(ranges_); |
| 408 DCHECK(IsRangeListSorted(ranges_)); | 406 DCHECK(IsRangeListSorted(ranges_)); |
| 409 DCHECK(OnlySelectedRangeIsSeeked()); | 407 DCHECK(OnlySelectedRangeIsSeeked()); |
| 410 return true; | 408 return true; |
| 411 } | 409 } |
| 412 | 410 |
| 413 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end, | 411 void SourceBufferStream::Remove(base::TimeDelta start, base::TimeDelta end, |
| 414 base::TimeDelta duration) { | 412 base::TimeDelta duration) { |
| 415 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 413 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 } | 642 } |
| 645 } | 643 } |
| 646 | 644 |
| 647 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { | 645 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { |
| 648 for (BufferQueue::const_iterator itr = buffers.begin(); | 646 for (BufferQueue::const_iterator itr = buffers.begin(); |
| 649 itr != buffers.end(); ++itr) { | 647 itr != buffers.end(); ++itr) { |
| 650 (*itr)->SetConfigId(append_config_index_); | 648 (*itr)->SetConfigId(append_config_index_); |
| 651 } | 649 } |
| 652 } | 650 } |
| 653 | 651 |
| 654 void SourceBufferStream::GarbageCollectIfNeeded() { | 652 bool SourceBufferStream::GarbageCollectIfNeeded(DecodeTimestamp media_time, |
| 653 size_t newDataSize) { | |
| 654 DCHECK(media_time != kNoDecodeTimestamp()); | |
| 655 // Compute size of |ranges_|. | 655 // Compute size of |ranges_|. |
| 656 size_t ranges_size = 0; | 656 size_t ranges_size = 0; |
| 657 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) | 657 for (RangeList::iterator itr = ranges_.begin(); itr != ranges_.end(); ++itr) |
|
wolenetz
2015/08/20 23:23:37
instead, use GetBufferedSize() ?
servolk
2015/08/21 01:32:08
Done.
| |
| 658 ranges_size += (*itr)->size_in_bytes(); | 658 ranges_size += (*itr)->size_in_bytes(); |
| 659 | 659 |
| 660 // Return if we're under or at the memory limit. | 660 // Return if we're under or at the memory limit. |
| 661 if (ranges_size <= memory_limit_) | 661 if (ranges_size + newDataSize <= memory_limit_) |
|
wolenetz
2015/08/20 23:23:37
this can overflow
servolk
2015/08/21 01:32:08
Done, added a sanity and overflow check
| |
| 662 return; | 662 return true; |
| 663 | 663 |
| 664 size_t bytes_to_free = ranges_size - memory_limit_; | 664 size_t bytes_to_free = ranges_size + newDataSize - memory_limit_; |
|
wolenetz
2015/08/20 23:23:37
If newDataSize > memory_limit, trivially return fa
servolk
2015/08/21 01:32:08
Done.
| |
| 665 | 665 |
| 666 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": Before GC" | 666 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": Before GC" |
| 667 << " media_time=" << media_time.InSecondsF() | |
| 668 << " ranges_=" << RangesToString(ranges_) | |
| 667 << " ranges_size=" << ranges_size | 669 << " ranges_size=" << ranges_size |
| 668 << " ranges_=" << RangesToString(ranges_) | 670 << " newDataSize=" << newDataSize |
| 669 << " memory_limit_=" << memory_limit_; | 671 << " memory_limit_=" << memory_limit_ |
| 672 << " last_appended_buffer_timestamp_=" | |
| 673 << last_appended_buffer_timestamp_.InSecondsF(); | |
| 670 | 674 |
| 671 // Begin deleting after the last appended buffer. | 675 size_t bytes_freed = 0; |
| 672 size_t bytes_freed = FreeBuffersAfterLastAppended(bytes_to_free); | |
| 673 | 676 |
| 674 // Begin deleting from the front. | 677 // If last appended buffer position was earlier than the current playback time |
| 675 if (bytes_freed < bytes_to_free) | 678 // then try deleting data between last append and current media_time. |
| 676 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, false); | 679 if (last_appended_buffer_timestamp_ != kNoDecodeTimestamp() && |
| 680 last_appended_buffer_timestamp_ < media_time) { | |
| 681 size_t between = FreeBuffersAfterLastAppended(bytes_to_free, media_time); | |
| 682 DVLOG(3) << __FUNCTION__ << " FreeBuffersAfterLastAppended " | |
| 683 << " released " << between << " bytes" | |
| 684 << " ranges_=" << RangesToString(ranges_); | |
| 685 bytes_freed += between; | |
| 677 | 686 |
| 678 // Begin deleting from the back. | 687 // If the last append happened before the current playback position |
| 679 if (bytes_freed < bytes_to_free) | 688 // |media_time|, then JS player is probably preparing to seek back and we |
| 680 bytes_freed += FreeBuffers(bytes_to_free - bytes_freed, true); | 689 // should try to preserve all most recently appended data (which is in |
| 690 // range_for_next_append_) from being removed by GC (see crbug.com/440173) | |
| 691 if (range_for_next_append_ != ranges_.end()) { | |
| 692 DCHECK((*range_for_next_append_)->GetStartTimestamp() <= media_time); | |
| 693 media_time = (*range_for_next_append_)->GetStartTimestamp(); | |
| 694 } | |
| 695 } | |
| 696 | |
| 697 // Try removing data from the front of the SourceBuffer up to |media_time| | |
| 698 // position. | |
| 699 if (bytes_freed < bytes_to_free) { | |
| 700 size_t front = FreeBuffers(bytes_to_free - bytes_freed, media_time, false); | |
| 701 DVLOG(3) << __FUNCTION__ << " Removed " << front << " bytes from the front" | |
| 702 << " ranges_=" << RangesToString(ranges_); | |
| 703 bytes_freed += front; | |
| 704 } | |
| 705 | |
| 706 // Try removing data from the back of the SourceBuffer, until we reach the | |
| 707 // most recent append position. | |
| 708 if (bytes_freed < bytes_to_free) { | |
| 709 size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true); | |
| 710 DVLOG(3) << __FUNCTION__ << " Removed " << back << " bytes from the back" | |
| 711 << " ranges_=" << RangesToString(ranges_); | |
| 712 bytes_freed += back; | |
| 713 } | |
| 681 | 714 |
| 682 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": After GC" | 715 DVLOG(2) << __FUNCTION__ << " " << GetStreamTypeName() << ": After GC" |
| 716 << " bytes_to_free=" << bytes_to_free | |
| 683 << " bytes_freed=" << bytes_freed | 717 << " bytes_freed=" << bytes_freed |
| 684 << " ranges_=" << RangesToString(ranges_); | 718 << " ranges_=" << RangesToString(ranges_); |
| 719 | |
| 720 return bytes_freed >= bytes_to_free; | |
| 685 } | 721 } |
| 686 | 722 |
| 687 size_t SourceBufferStream::FreeBuffersAfterLastAppended( | 723 size_t SourceBufferStream::FreeBuffersAfterLastAppended( |
| 688 size_t total_bytes_to_free) { | 724 size_t total_bytes_to_free, DecodeTimestamp media_time) { |
| 689 DecodeTimestamp next_buffer_timestamp = GetNextBufferTimestamp(); | 725 DVLOG(4) << __FUNCTION__ << " last_appended_buffer_timestamp_=" |
| 690 if (last_appended_buffer_timestamp_ == kNoDecodeTimestamp() || | 726 << last_appended_buffer_timestamp_.InSecondsF() |
| 691 next_buffer_timestamp == kNoDecodeTimestamp() || | 727 << " media_time=" << media_time.InSecondsF(); |
| 692 last_appended_buffer_timestamp_ >= next_buffer_timestamp) { | |
| 693 return 0; | |
| 694 } | |
| 695 | 728 |
| 696 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_; | 729 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_; |
| 697 if (last_appended_buffer_is_keyframe_) | 730 if (last_appended_buffer_is_keyframe_) |
| 698 remove_range_start += GetMaxInterbufferDistance(); | 731 remove_range_start += GetMaxInterbufferDistance(); |
| 699 | 732 |
| 700 DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp( | 733 DecodeTimestamp remove_range_start_keyframe = FindKeyframeAfterTimestamp( |
| 701 remove_range_start); | 734 remove_range_start); |
| 702 if (remove_range_start_keyframe != kNoDecodeTimestamp()) | 735 if (remove_range_start_keyframe != kNoDecodeTimestamp()) |
| 703 remove_range_start = remove_range_start_keyframe; | 736 remove_range_start = remove_range_start_keyframe; |
| 704 if (remove_range_start >= next_buffer_timestamp) | 737 if (remove_range_start >= media_time) |
| 705 return 0; | 738 return 0; |
| 706 | 739 |
| 707 DecodeTimestamp remove_range_end; | 740 DecodeTimestamp remove_range_end; |
| 708 size_t bytes_freed = GetRemovalRange(remove_range_start, | 741 size_t bytes_freed = GetRemovalRange(remove_range_start, |
| 709 next_buffer_timestamp, | 742 media_time, |
| 710 total_bytes_to_free, | 743 total_bytes_to_free, |
| 711 &remove_range_end); | 744 &remove_range_end); |
| 712 if (bytes_freed > 0) { | 745 if (bytes_freed > 0) { |
| 746 DVLOG(4) << __FUNCTION__ << " removing [" | |
| 747 << remove_range_start.ToPresentationTime().InSecondsF() << ";" | |
| 748 << remove_range_end.ToPresentationTime().InSecondsF() << "]"; | |
| 713 Remove(remove_range_start.ToPresentationTime(), | 749 Remove(remove_range_start.ToPresentationTime(), |
| 714 remove_range_end.ToPresentationTime(), | 750 remove_range_end.ToPresentationTime(), |
| 715 next_buffer_timestamp.ToPresentationTime()); | 751 media_time.ToPresentationTime()); |
| 716 } | 752 } |
| 717 | 753 |
| 718 return bytes_freed; | 754 return bytes_freed; |
| 719 } | 755 } |
| 720 | 756 |
| 721 size_t SourceBufferStream::GetRemovalRange( | 757 size_t SourceBufferStream::GetRemovalRange( |
| 722 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, | 758 DecodeTimestamp start_timestamp, DecodeTimestamp end_timestamp, |
| 723 size_t total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) { | 759 size_t total_bytes_to_free, DecodeTimestamp* removal_end_timestamp) { |
| 724 DCHECK(start_timestamp >= DecodeTimestamp()) << start_timestamp.InSecondsF(); | 760 DCHECK(start_timestamp >= DecodeTimestamp()) << start_timestamp.InSecondsF(); |
| 725 DCHECK(start_timestamp < end_timestamp) | 761 DCHECK(start_timestamp < end_timestamp) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 738 | 774 |
| 739 size_t bytes_to_free = total_bytes_to_free - bytes_freed; | 775 size_t bytes_to_free = total_bytes_to_free - bytes_freed; |
| 740 size_t bytes_removed = range->GetRemovalGOP( | 776 size_t bytes_removed = range->GetRemovalGOP( |
| 741 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp); | 777 start_timestamp, end_timestamp, bytes_to_free, removal_end_timestamp); |
| 742 bytes_freed += bytes_removed; | 778 bytes_freed += bytes_removed; |
| 743 } | 779 } |
| 744 return bytes_freed; | 780 return bytes_freed; |
| 745 } | 781 } |
| 746 | 782 |
| 747 size_t SourceBufferStream::FreeBuffers(size_t total_bytes_to_free, | 783 size_t SourceBufferStream::FreeBuffers(size_t total_bytes_to_free, |
| 784 DecodeTimestamp media_time, | |
| 748 bool reverse_direction) { | 785 bool reverse_direction) { |
| 749 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers", | 786 TRACE_EVENT2("media", "SourceBufferStream::FreeBuffers", |
| 750 "total bytes to free", total_bytes_to_free, | 787 "total bytes to free", total_bytes_to_free, |
| 751 "reverse direction", reverse_direction); | 788 "reverse direction", reverse_direction); |
| 752 | 789 |
| 753 DCHECK_GT(total_bytes_to_free, 0u); | 790 DCHECK_GT(total_bytes_to_free, 0u); |
| 754 size_t bytes_freed = 0; | 791 size_t bytes_freed = 0; |
| 755 | 792 |
| 756 // This range will save the last GOP appended to |range_for_next_append_| | 793 // This range will save the last GOP appended to |range_for_next_append_| |
| 757 // if the buffers surrounding it get deleted during garbage collection. | 794 // if the buffers surrounding it get deleted during garbage collection. |
| 758 SourceBufferRange* new_range_for_append = NULL; | 795 SourceBufferRange* new_range_for_append = NULL; |
| 759 | 796 |
| 760 while (!ranges_.empty() && bytes_freed < total_bytes_to_free) { | 797 while (!ranges_.empty() && bytes_freed < total_bytes_to_free) { |
| 761 SourceBufferRange* current_range = NULL; | 798 SourceBufferRange* current_range = NULL; |
| 762 BufferQueue buffers; | 799 BufferQueue buffers; |
| 763 size_t bytes_deleted = 0; | 800 size_t bytes_deleted = 0; |
| 764 | 801 |
| 765 if (reverse_direction) { | 802 if (reverse_direction) { |
| 766 current_range = ranges_.back(); | 803 current_range = ranges_.back(); |
| 804 DVLOG(5) << "current_range=" << RangeToString(*current_range); | |
| 767 if (current_range->LastGOPContainsNextBufferPosition()) { | 805 if (current_range->LastGOPContainsNextBufferPosition()) { |
| 768 DCHECK_EQ(current_range, selected_range_); | 806 DCHECK_EQ(current_range, selected_range_); |
| 807 DVLOG(5) << "current_range contains next read position, stopping GC"; | |
| 769 break; | 808 break; |
| 770 } | 809 } |
| 810 DVLOG(5) << "Deleting GOP from back: " << RangeToString(*current_range); | |
| 771 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); | 811 bytes_deleted = current_range->DeleteGOPFromBack(&buffers); |
| 772 } else { | 812 } else { |
| 773 current_range = ranges_.front(); | 813 current_range = ranges_.front(); |
| 774 if (current_range->FirstGOPContainsNextBufferPosition()) { | 814 DVLOG(5) << "current_range=" << RangeToString(*current_range); |
| 775 DCHECK_EQ(current_range, selected_range_); | 815 if (!current_range->FirstGOPEarlierThanMediaTime(media_time)) { |
| 816 // We have removed all data up to the GOP that contains current playback | |
| 817 // position, we can't delete any further. | |
| 818 DVLOG(5) << "current_range contains playback position, stopping GC"; | |
| 776 break; | 819 break; |
| 777 } | 820 } |
| 821 DVLOG(4) << "Deleting GOP from front: " << RangeToString(*current_range); | |
| 778 bytes_deleted = current_range->DeleteGOPFromFront(&buffers); | 822 bytes_deleted = current_range->DeleteGOPFromFront(&buffers); |
| 779 } | 823 } |
| 780 | 824 |
| 781 // Check to see if we've just deleted the GOP that was last appended. | 825 // Check to see if we've just deleted the GOP that was last appended. |
| 782 DecodeTimestamp end_timestamp = buffers.back()->GetDecodeTimestamp(); | 826 DecodeTimestamp end_timestamp = buffers.back()->GetDecodeTimestamp(); |
| 783 if (end_timestamp == last_appended_buffer_timestamp_) { | 827 if (end_timestamp == last_appended_buffer_timestamp_) { |
| 784 DCHECK(last_appended_buffer_timestamp_ != kNoDecodeTimestamp()); | 828 DCHECK(last_appended_buffer_timestamp_ != kNoDecodeTimestamp()); |
| 785 DCHECK(!new_range_for_append); | 829 DCHECK(!new_range_for_append); |
| 830 | |
| 786 // Create a new range containing these buffers. | 831 // Create a new range containing these buffers. |
| 787 new_range_for_append = new SourceBufferRange( | 832 new_range_for_append = new SourceBufferRange( |
| 788 TypeToGapPolicy(GetType()), | 833 TypeToGapPolicy(GetType()), |
| 789 buffers, kNoDecodeTimestamp(), | 834 buffers, kNoDecodeTimestamp(), |
| 790 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, | 835 base::Bind(&SourceBufferStream::GetMaxInterbufferDistance, |
| 791 base::Unretained(this))); | 836 base::Unretained(this))); |
| 792 range_for_next_append_ = ranges_.end(); | 837 range_for_next_append_ = ranges_.end(); |
| 793 } else { | 838 } else { |
| 794 bytes_freed += bytes_deleted; | 839 bytes_freed += bytes_deleted; |
| 795 } | 840 } |
| 796 | 841 |
| 797 if (current_range->size_in_bytes() == 0) { | 842 if (current_range->size_in_bytes() == 0) { |
| 798 DCHECK_NE(current_range, selected_range_); | 843 DCHECK_NE(current_range, selected_range_); |
| 799 DCHECK(range_for_next_append_ == ranges_.end() || | 844 DCHECK(range_for_next_append_ == ranges_.end() || |
| 800 *range_for_next_append_ != current_range); | 845 *range_for_next_append_ != current_range); |
| 801 delete current_range; | 846 delete current_range; |
| 802 reverse_direction ? ranges_.pop_back() : ranges_.pop_front(); | 847 reverse_direction ? ranges_.pop_back() : ranges_.pop_front(); |
| 803 } | 848 } |
| 849 | |
| 850 if (reverse_direction && new_range_for_append) { | |
| 851 // We don't want to delete any further, or we'll be creating gaps | |
| 852 break; | |
| 853 } | |
| 804 } | 854 } |
| 805 | 855 |
| 806 // Insert |new_range_for_append| into |ranges_|, if applicable. | 856 // Insert |new_range_for_append| into |ranges_|, if applicable. |
| 807 if (new_range_for_append) { | 857 if (new_range_for_append) { |
| 808 range_for_next_append_ = AddToRanges(new_range_for_append); | 858 range_for_next_append_ = AddToRanges(new_range_for_append); |
| 809 DCHECK(range_for_next_append_ != ranges_.end()); | 859 DCHECK(range_for_next_append_ != ranges_.end()); |
| 810 | 860 |
| 811 // Check to see if we need to merge |new_range_for_append| with the range | 861 // Check to see if we need to merge |new_range_for_append| with the range |
| 812 // before or after it. |new_range_for_append| is created whenever the last | 862 // before or after it. |new_range_for_append| is created whenever the last |
| 813 // GOP appended is encountered, regardless of whether any buffers after it | 863 // GOP appended is encountered, regardless of whether any buffers after it |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1253 } | 1303 } |
| 1254 | 1304 |
| 1255 void SourceBufferStream::SeekAndSetSelectedRange( | 1305 void SourceBufferStream::SeekAndSetSelectedRange( |
| 1256 SourceBufferRange* range, DecodeTimestamp seek_timestamp) { | 1306 SourceBufferRange* range, DecodeTimestamp seek_timestamp) { |
| 1257 if (range) | 1307 if (range) |
| 1258 range->Seek(seek_timestamp); | 1308 range->Seek(seek_timestamp); |
| 1259 SetSelectedRange(range); | 1309 SetSelectedRange(range); |
| 1260 } | 1310 } |
| 1261 | 1311 |
| 1262 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) { | 1312 void SourceBufferStream::SetSelectedRange(SourceBufferRange* range) { |
| 1263 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() | 1313 DVLOG(1) << __FUNCTION__ << " " << GetStreamTypeName() << ": " |
| 1264 << ": " << selected_range_ << " -> " << range; | 1314 << selected_range_ << " " |
| 1315 << (selected_range_ ? RangeToString(*selected_range_) : "") | |
| 1316 << " -> " << range << " " << (range ? RangeToString(*range) : ""); | |
| 1265 if (selected_range_) | 1317 if (selected_range_) |
| 1266 selected_range_->ResetNextBufferPosition(); | 1318 selected_range_->ResetNextBufferPosition(); |
| 1267 DCHECK(!range || range->HasNextBufferPosition()); | 1319 DCHECK(!range || range->HasNextBufferPosition()); |
| 1268 selected_range_ = range; | 1320 selected_range_ = range; |
| 1269 } | 1321 } |
| 1270 | 1322 |
| 1271 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { | 1323 Ranges<base::TimeDelta> SourceBufferStream::GetBufferedTime() const { |
| 1272 Ranges<base::TimeDelta> ranges; | 1324 Ranges<base::TimeDelta> ranges; |
| 1273 for (RangeList::const_iterator itr = ranges_.begin(); | 1325 for (RangeList::const_iterator itr = ranges_.begin(); |
| 1274 itr != ranges_.end(); ++itr) { | 1326 itr != ranges_.end(); ++itr) { |
| 1275 ranges.Add((*itr)->GetStartTimestamp().ToPresentationTime(), | 1327 ranges.Add((*itr)->GetStartTimestamp().ToPresentationTime(), |
| 1276 (*itr)->GetBufferedEndTimestamp().ToPresentationTime()); | 1328 (*itr)->GetBufferedEndTimestamp().ToPresentationTime()); |
| 1277 } | 1329 } |
| 1278 return ranges; | 1330 return ranges; |
| 1279 } | 1331 } |
| 1280 | 1332 |
| 1281 base::TimeDelta SourceBufferStream::GetBufferedDuration() const { | 1333 base::TimeDelta SourceBufferStream::GetBufferedDuration() const { |
| 1282 if (ranges_.empty()) | 1334 if (ranges_.empty()) |
| 1283 return base::TimeDelta(); | 1335 return base::TimeDelta(); |
| 1284 | 1336 |
| 1285 return ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime(); | 1337 return ranges_.back()->GetBufferedEndTimestamp().ToPresentationTime(); |
| 1286 } | 1338 } |
| 1287 | 1339 |
| 1340 size_t SourceBufferStream::GetBufferedSize() const { | |
| 1341 size_t ranges_size = 0; | |
| 1342 for (const auto& range : ranges_) | |
| 1343 ranges_size += range->size_in_bytes(); | |
| 1344 return ranges_size; | |
| 1345 } | |
| 1346 | |
| 1288 void SourceBufferStream::MarkEndOfStream() { | 1347 void SourceBufferStream::MarkEndOfStream() { |
| 1289 DCHECK(!end_of_stream_); | 1348 DCHECK(!end_of_stream_); |
| 1290 end_of_stream_ = true; | 1349 end_of_stream_ = true; |
| 1291 } | 1350 } |
| 1292 | 1351 |
| 1293 void SourceBufferStream::UnmarkEndOfStream() { | 1352 void SourceBufferStream::UnmarkEndOfStream() { |
| 1294 DCHECK(end_of_stream_); | 1353 DCHECK(end_of_stream_); |
| 1295 end_of_stream_ = false; | 1354 end_of_stream_ = false; |
| 1296 } | 1355 } |
| 1297 | 1356 |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1707 return false; | 1766 return false; |
| 1708 | 1767 |
| 1709 DCHECK_NE(have_splice_buffers, have_preroll_buffer); | 1768 DCHECK_NE(have_splice_buffers, have_preroll_buffer); |
| 1710 splice_buffers_index_ = 0; | 1769 splice_buffers_index_ = 0; |
| 1711 pending_buffer_.swap(*out_buffer); | 1770 pending_buffer_.swap(*out_buffer); |
| 1712 pending_buffers_complete_ = false; | 1771 pending_buffers_complete_ = false; |
| 1713 return true; | 1772 return true; |
| 1714 } | 1773 } |
| 1715 | 1774 |
| 1716 } // namespace media | 1775 } // namespace media |
| OLD | NEW |