Chromium Code Reviews| Index: media/filters/source_buffer_stream_unittest.cc |
| diff --git a/media/filters/source_buffer_stream_unittest.cc b/media/filters/source_buffer_stream_unittest.cc |
| index c539839e1eb718a9cba1551d81ca330b2bff163b..71bf36e90b13f6a9babfdcb746172a0e1b82b915 100644 |
| --- a/media/filters/source_buffer_stream_unittest.cc |
| +++ b/media/filters/source_buffer_stream_unittest.cc |
| @@ -16,9 +16,11 @@ |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_split.h" |
| #include "base/strings/string_util.h" |
| +#include "base/test/scoped_feature_list.h" |
| #include "media/base/data_buffer.h" |
| #include "media/base/decoder_buffer.h" |
| #include "media/base/media_log.h" |
| +#include "media/base/media_switches.h" |
| #include "media/base/media_util.h" |
| #include "media/base/mock_media_log.h" |
| #include "media/base/test_helpers.h" |
| @@ -171,6 +173,11 @@ class SourceBufferStreamTest : public testing::Test { |
| stream_->Seek(base::TimeDelta::FromMilliseconds(timestamp_ms)); |
| } |
| + bool GarbageCollect(base::TimeDelta media_time, int newDataSize) { |
|
Alexei Svitkine (slow)
2017/01/27 18:03:19
new_data_size
servolk
2017/01/28 02:23:57
Done.
|
| + return stream_->GarbageCollectIfNeeded( |
| + DecodeTimestamp::FromPresentationTime(media_time), newDataSize); |
| + } |
| + |
| bool GarbageCollectWithPlaybackAtBuffer(int position, int newDataBuffers) { |
| return stream_->GarbageCollectIfNeeded( |
| DecodeTimestamp::FromPresentationTime(position * frame_duration_), |
| @@ -4752,6 +4759,77 @@ TEST_F(SourceBufferStreamTest, GetHighestPresentationTimestamp) { |
| EXPECT_EQ(base::TimeDelta(), stream_->GetHighestPresentationTimestamp()); |
| } |
| +TEST_F(SourceBufferStreamTest, GarbageCollectionUnderMemoryPressure) { |
| + SetMemoryLimit(16); |
| + NewCodedFrameGroupAppend("0K 1 2 3K 4 5 6K 7 8 9K 10 11 12K 13 14 15K"); |
| + CheckExpectedRangesByTimestamp("{ [0,16) }"); |
| + |
| + // This feature is disabled by default, so by default memory pressure |
| + // notification takes no effect and the memory limits and won't remove |
| + // anything from buffered ranges, since we are under the limit of 20 bytes. |
| + stream_->OnMemoryPressure( |
| + DecodeTimestamp::FromMilliseconds(0), |
| + base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE, false); |
| + EXPECT_TRUE(GarbageCollect(base::TimeDelta::FromMilliseconds(8), 0)); |
| + CheckExpectedRangesByTimestamp("{ [0,16) }"); |
| + |
| + // Now enable the feature. |
| + base::test::ScopedFeatureList scoped_feature_list; |
| + scoped_feature_list.InitAndEnableFeature(kMemoryPressureBasedSourceBufferGC); |
| + |
| + // Verify that effective MSE memory limit is reduced under memory pressure. |
| + stream_->OnMemoryPressure( |
| + DecodeTimestamp::FromMilliseconds(0), |
| + base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE, false); |
| + |
| + // Effective memory limit is now 8 buffers, but we still will not collect any |
| + // data between the current playback position 3 and last append position 15. |
| + EXPECT_TRUE(GarbageCollect(base::TimeDelta::FromMilliseconds(4), 0)); |
| + CheckExpectedRangesByTimestamp("{ [3,16) }"); |
| + |
| + // As playback proceeds further to time 9 we should be able to collect |
| + // enough data to bring us back under memory limit of 8 buffers. |
| + EXPECT_TRUE(GarbageCollect(base::TimeDelta::FromMilliseconds(9), 0)); |
| + CheckExpectedRangesByTimestamp("{ [9,16) }"); |
| + |
| + // If memory pressure becomes critical, the garbage collection algorithm |
| + // becomes even more aggressive and collects everything up to the current |
| + // playback position. |
| + stream_->OnMemoryPressure( |
| + DecodeTimestamp::FromMilliseconds(0), |
| + base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL, false); |
| + EXPECT_TRUE(GarbageCollect(base::TimeDelta::FromMilliseconds(13), 0)); |
| + CheckExpectedRangesByTimestamp("{ [12,16) }"); |
| + |
| + // But even under critical memory pressure the MSE memory limit imposed by the |
| + // memory pressure is soft, i.e. we should be able to append more data |
| + // successfully up to the hard limit of 16 bytes. |
| + NewCodedFrameGroupAppend("16K 17 18 19 20 21 22 23 24 25 26 27"); |
| + CheckExpectedRangesByTimestamp("{ [12,28) }"); |
| + EXPECT_TRUE(GarbageCollect(base::TimeDelta::FromMilliseconds(13), 0)); |
| + CheckExpectedRangesByTimestamp("{ [12,28) }"); |
| +} |
| + |
| +TEST_F(SourceBufferStreamTest, InstantGarbageCollectionUnderMemoryPressure) { |
| + SetMemoryLimit(16); |
| + NewCodedFrameGroupAppend("0K 1 2 3K 4 5 6K 7 8 9K 10 11 12K 13 14 15K"); |
| + CheckExpectedRangesByTimestamp("{ [0,16) }"); |
| + |
| + // Verify that garbage collection happens immediately on critical memory |
| + // pressure notification, even without explicit GarbageCollect invocation, |
| + // when the immediate GC is allowed. |
| + base::test::ScopedFeatureList scoped_feature_list; |
| + scoped_feature_list.InitAndEnableFeature(kMemoryPressureBasedSourceBufferGC); |
| + stream_->OnMemoryPressure( |
| + DecodeTimestamp::FromMilliseconds(7), |
| + base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL, true); |
| + CheckExpectedRangesByTimestamp("{ [6,16) }"); |
| + stream_->OnMemoryPressure( |
| + DecodeTimestamp::FromMilliseconds(9), |
| + base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL, true); |
| + CheckExpectedRangesByTimestamp("{ [9,16) }"); |
| +} |
| + |
| // TODO(vrk): Add unit tests where keyframes are unaligned between streams. |
| // (crbug.com/133557) |