Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(199)

Side by Side Diff: media/filters/source_buffer_stream.cc

Issue 2605993002: Experiment with more aggressive MSE GC on memory pressure (Closed)
Patch Set: Improve feature handling (CR feedback) Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include <string> 10 #include <string>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "media/base/media_switches.h"
15 #include "media/base/timestamp_constants.h" 16 #include "media/base/timestamp_constants.h"
16 #include "media/filters/source_buffer_platform.h" 17 #include "media/filters/source_buffer_platform.h"
17 #include "media/filters/source_buffer_range.h" 18 #include "media/filters/source_buffer_range.h"
18 19
19 namespace media { 20 namespace media {
20 21
21 namespace { 22 namespace {
22 23
23 // An arbitrarily-chosen number to estimate the duration of a buffer if none is 24 // An arbitrarily-chosen number to estimate the duration of a buffer if none is
24 // set and there's not enough information to get a better estimate. 25 // set and there's not enough information to get a better estimate.
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 } 686 }
686 } 687 }
687 688
688 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) { 689 void SourceBufferStream::SetConfigIds(const BufferQueue& buffers) {
689 for (BufferQueue::const_iterator itr = buffers.begin(); 690 for (BufferQueue::const_iterator itr = buffers.begin();
690 itr != buffers.end(); ++itr) { 691 itr != buffers.end(); ++itr) {
691 (*itr)->SetConfigId(append_config_index_); 692 (*itr)->SetConfigId(append_config_index_);
692 } 693 }
693 } 694 }
694 695
696 void SourceBufferStream::OnMemoryPressure(
697 DecodeTimestamp media_time,
698 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level,
699 bool force_gc) {
700 DVLOG(4) << __func__ << " level=" << memory_pressure_level;
701 memory_pressure_level_ = memory_pressure_level;
702
703 // The new value of |memory_pressure_level_| updated set above will take
704 // effect on the next SourceBuffer append operation. But if we are notified
DaleCurtis 2017/01/26 23:07:37 Comment talks about critical but if force is enabl
servolk 2017/01/27 00:52:13 Updated the comment and moved it closer to where w
705 // that memory pressure is critical, we might want to perform a GC right away,
706 // to release some memory immediately. Strictly speaking MSE apps expect
707 // buffered ranges only at well-defined points, like SourceBuffer append
708 // operation, and may not expect this. But it might still be better than being
709 // killed due to OOM, so might be worth the risk.
710 if (force_gc) {
711 GarbageCollectIfNeeded(media_time, 0);
712 }
713 }
714
695 bool SourceBufferStream::GarbageCollectIfNeeded(DecodeTimestamp media_time, 715 bool SourceBufferStream::GarbageCollectIfNeeded(DecodeTimestamp media_time,
696 size_t newDataSize) { 716 size_t newDataSize) {
697 DCHECK(media_time != kNoDecodeTimestamp()); 717 DCHECK(media_time != kNoDecodeTimestamp());
698 // Garbage collection should only happen before/during appending new data, 718 // Garbage collection should only happen before/during appending new data,
699 // which should not happen in end-of-stream state. 719 // which should not happen in end-of-stream state. Unless we also allow GC to
700 DCHECK(!end_of_stream_); 720 // happen on memory pressure notifications, which might happen even in EOS
721 // state.
722 if (!base::FeatureList::IsEnabled(kReduceMSEBuffersOnMemoryPressure)) {
DaleCurtis 2017/01/26 23:08:42 Also drop {} from single line if statements (here
servolk 2017/01/27 00:52:13 Done.
723 DCHECK(!end_of_stream_);
724 }
701 // Compute size of |ranges_|. 725 // Compute size of |ranges_|.
702 size_t ranges_size = GetBufferedSize(); 726 size_t ranges_size = GetBufferedSize();
703 727
704 // Sanity and overflow checks 728 // Sanity and overflow checks
705 if ((newDataSize > memory_limit_) || 729 if ((newDataSize > memory_limit_) ||
706 (ranges_size + newDataSize < ranges_size)) { 730 (ranges_size + newDataSize < ranges_size)) {
707 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_garbage_collect_algorithm_logs_, 731 LIMITED_MEDIA_LOG(DEBUG, media_log_, num_garbage_collect_algorithm_logs_,
708 kMaxGarbageCollectAlgorithmWarningLogs) 732 kMaxGarbageCollectAlgorithmWarningLogs)
709 << GetStreamTypeName() << " stream: " 733 << GetStreamTypeName() << " stream: "
710 << "new append of newDataSize=" << newDataSize 734 << "new append of newDataSize=" << newDataSize
711 << " bytes exceeds memory_limit_=" << memory_limit_ 735 << " bytes exceeds memory_limit_=" << memory_limit_
712 << ", currently buffered ranges_size=" << ranges_size; 736 << ", currently buffered ranges_size=" << ranges_size;
713 return false; 737 return false;
714 } 738 }
715 739
740 size_t effective_memory_limit = memory_limit_;
741 if (base::FeatureList::IsEnabled(kReduceMSEBuffersOnMemoryPressure)) {
742 switch (memory_pressure_level_) {
743 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
744 effective_memory_limit = memory_limit_ / 2;
745 break;
746 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
747 effective_memory_limit = 0;
748 break;
749 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
750 break;
751 }
752 }
753
716 // Return if we're under or at the memory limit. 754 // Return if we're under or at the memory limit.
717 if (ranges_size + newDataSize <= memory_limit_) 755 if (ranges_size + newDataSize <= effective_memory_limit)
718 return true; 756 return true;
719 757
720 size_t bytes_to_free = ranges_size + newDataSize - memory_limit_; 758 size_t bytes_over_hard_memory_limit = 0;
759 if (ranges_size + newDataSize > memory_limit_)
760 bytes_over_hard_memory_limit = ranges_size + newDataSize - memory_limit_;
761
762 size_t bytes_to_free = ranges_size + newDataSize - effective_memory_limit;
721 763
722 DVLOG(2) << __func__ << " " << GetStreamTypeName() 764 DVLOG(2) << __func__ << " " << GetStreamTypeName()
723 << ": Before GC media_time=" << media_time.InSecondsF() 765 << ": Before GC media_time=" << media_time.InSecondsF()
724 << " ranges_=" << RangesToString(ranges_) 766 << " ranges_=" << RangesToString(ranges_)
725 << " seek_pending_=" << seek_pending_ 767 << " seek_pending_=" << seek_pending_
726 << " ranges_size=" << ranges_size << " newDataSize=" << newDataSize 768 << " ranges_size=" << ranges_size << " newDataSize=" << newDataSize
727 << " memory_limit_=" << memory_limit_ 769 << " memory_limit_=" << memory_limit_
770 << " effective_memory_limit=" << effective_memory_limit
728 << " last_appended_buffer_timestamp_=" 771 << " last_appended_buffer_timestamp_="
729 << last_appended_buffer_timestamp_.InSecondsF(); 772 << last_appended_buffer_timestamp_.InSecondsF();
730 773
731 if (selected_range_ && !seek_pending_ && 774 if (selected_range_ && !seek_pending_ &&
732 media_time > selected_range_->GetBufferedEndTimestamp()) { 775 media_time > selected_range_->GetBufferedEndTimestamp()) {
733 // Strictly speaking |media_time| (taken from HTMLMediaElement::currentTime) 776 // Strictly speaking |media_time| (taken from HTMLMediaElement::currentTime)
734 // should always be in the buffered ranges, but media::Pipeline uses audio 777 // should always be in the buffered ranges, but media::Pipeline uses audio
735 // stream as the main time source, when audio is present. 778 // stream as the main time source, when audio is present.
736 // In cases when audio and video streams have different buffered ranges, the 779 // In cases when audio and video streams have different buffered ranges, the
737 // |media_time| value might be slightly outside of the video stream buffered 780 // |media_time| value might be slightly outside of the video stream buffered
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 if (bytes_freed < bytes_to_free) { 870 if (bytes_freed < bytes_to_free) {
828 size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true); 871 size_t back = FreeBuffers(bytes_to_free - bytes_freed, media_time, true);
829 DVLOG(3) << __func__ << " Removed " << back 872 DVLOG(3) << __func__ << " Removed " << back
830 << " bytes from the back. ranges_=" << RangesToString(ranges_); 873 << " bytes from the back. ranges_=" << RangesToString(ranges_);
831 bytes_freed += back; 874 bytes_freed += back;
832 } 875 }
833 876
834 DVLOG(2) << __func__ << " " << GetStreamTypeName() 877 DVLOG(2) << __func__ << " " << GetStreamTypeName()
835 << ": After GC bytes_to_free=" << bytes_to_free 878 << ": After GC bytes_to_free=" << bytes_to_free
836 << " bytes_freed=" << bytes_freed 879 << " bytes_freed=" << bytes_freed
880 << " bytes_over_hard_memory_limit=" << bytes_over_hard_memory_limit
837 << " ranges_=" << RangesToString(ranges_); 881 << " ranges_=" << RangesToString(ranges_);
838 882
839 return bytes_freed >= bytes_to_free; 883 return bytes_freed >= bytes_over_hard_memory_limit;
840 } 884 }
841 885
842 size_t SourceBufferStream::FreeBuffersAfterLastAppended( 886 size_t SourceBufferStream::FreeBuffersAfterLastAppended(
843 size_t total_bytes_to_free, DecodeTimestamp media_time) { 887 size_t total_bytes_to_free, DecodeTimestamp media_time) {
844 DVLOG(4) << __func__ << " last_appended_buffer_timestamp_=" 888 DVLOG(4) << __func__ << " last_appended_buffer_timestamp_="
845 << last_appended_buffer_timestamp_.InSecondsF() 889 << last_appended_buffer_timestamp_.InSecondsF()
846 << " media_time=" << media_time.InSecondsF(); 890 << " media_time=" << media_time.InSecondsF();
847 891
848 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_; 892 DecodeTimestamp remove_range_start = last_appended_buffer_timestamp_;
849 if (last_appended_buffer_is_keyframe_) 893 if (last_appended_buffer_is_keyframe_)
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 1801
1758 if (!have_preroll_buffer) 1802 if (!have_preroll_buffer)
1759 return false; 1803 return false;
1760 1804
1761 pending_buffer_.swap(*out_buffer); 1805 pending_buffer_.swap(*out_buffer);
1762 pending_buffers_complete_ = false; 1806 pending_buffers_complete_ = false;
1763 return true; 1807 return true;
1764 } 1808 }
1765 1809
1766 } // namespace media 1810 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698