| Index: media/filters/chunk_demuxer_unittest.cc
|
| diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
|
| index 3d99e3d4fd353920b285e7d36fc01f8c2cf47375..bfe2842a8515b8f795e8b0b6e7582fc10a0a3193 100644
|
| --- a/media/filters/chunk_demuxer_unittest.cc
|
| +++ b/media/filters/chunk_demuxer_unittest.cc
|
| @@ -3334,7 +3334,7 @@ TEST_F(ChunkDemuxerTest, SetMemoryLimitType) {
|
|
|
| // Set different memory limits for audio and video.
|
| demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize);
|
| - demuxer_->SetMemoryLimits(DemuxerStream::VIDEO, 5 * kBlockSize);
|
| + demuxer_->SetMemoryLimits(DemuxerStream::VIDEO, 5 * kBlockSize + 1);
|
|
|
| base::TimeDelta seek_time = base::TimeDelta::FromMilliseconds(1000);
|
|
|
| @@ -3342,6 +3342,10 @@ TEST_F(ChunkDemuxerTest, SetMemoryLimitType) {
|
| AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10);
|
| AppendSingleStreamCluster(kSourceId, kVideoTrackNum, 0, 5);
|
|
|
| + // We should be right at buffer limit, should pass
|
| + EXPECT_TRUE(demuxer_->EvictCodedFrames(
|
| + kSourceId, base::TimeDelta::FromMilliseconds(0), 0));
|
| +
|
| CheckExpectedRanges(DemuxerStream::AUDIO, "{ [0,230) }");
|
| CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,165) }");
|
|
|
| @@ -3354,6 +3358,9 @@ TEST_F(ChunkDemuxerTest, SetMemoryLimitType) {
|
| AppendSingleStreamCluster(kSourceId, kVideoTrackNum,
|
| seek_time.InMilliseconds(), 5);
|
|
|
| + // We should delete first append, and be exactly at buffer limit
|
| + EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time, 0));
|
| +
|
| // Verify that the old data, and nothing more, has been garbage collected.
|
| CheckExpectedRanges(DemuxerStream::AUDIO, "{ [1000,1230) }");
|
| CheckExpectedRanges(DemuxerStream::VIDEO, "{ [1000,1165) }");
|
| @@ -3375,31 +3382,72 @@ TEST_F(ChunkDemuxerTest, GCDuringSeek) {
|
| seek_time1.InMilliseconds(), 5);
|
| CheckExpectedRanges(kSourceId, "{ [1000,1115) }");
|
|
|
| + // We are under memory limit, so Evict should be a no-op.
|
| + EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time1, 0));
|
| + CheckExpectedRanges(kSourceId, "{ [1000,1115) }");
|
| +
|
| // Signal that the second seek is starting.
|
| demuxer_->StartWaitingForSeek(seek_time2);
|
|
|
| - // Append data to satisfy the second seek. This append triggers
|
| - // the garbage collection logic since we set the memory limit to
|
| - // 5 blocks.
|
| + // Append data to satisfy the second seek.
|
| AppendSingleStreamCluster(kSourceId, kAudioTrackNum,
|
| seek_time2.InMilliseconds(), 5);
|
| + CheckExpectedRanges(kSourceId, "{ [500,615) [1000,1115) }");
|
|
|
| - // Verify that the buffers that cover |seek_time2| do not get
|
| - // garbage collected.
|
| + // We are now over our memory usage limit. We have just seeked to |seek_time2|
|
| + // so data around 500ms position should be preserved, while the previous
|
| + // append at 1000ms should be removed.
|
| + EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time2, 0));
|
| CheckExpectedRanges(kSourceId, "{ [500,615) }");
|
|
|
| // Complete the seek.
|
| demuxer_->Seek(seek_time2, NewExpectedStatusCB(PIPELINE_OK));
|
|
|
| -
|
| - // Append more data and make sure that the blocks for |seek_time2|
|
| - // don't get removed.
|
| - //
|
| - // NOTE: The current GC algorithm tries to preserve the GOP at the
|
| - // current position as well as the last appended GOP. This is
|
| - // why there are 2 ranges in the expectations.
|
| + // Append more data and make sure that we preserve both the buffered range
|
| + // around |seek_time2|, because that's the current playback position,
|
| + // and the newly appended range, since this is the most recent append.
|
| AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 700, 5);
|
| - CheckExpectedRanges(kSourceId, "{ [500,592) [792,815) }");
|
| + EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, seek_time2, 0));
|
| + CheckExpectedRanges(kSourceId, "{ [500,615) [700,815) }");
|
| +}
|
| +
|
| +TEST_F(ChunkDemuxerTest, GCKeepPlayhead) {
|
| + ASSERT_TRUE(InitDemuxer(HAS_AUDIO));
|
| +
|
| + demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 5 * kBlockSize);
|
| +
|
| + // Append data at the start that can be garbage collected:
|
| + AppendSingleStreamCluster(kSourceId, kAudioTrackNum, 0, 10);
|
| + CheckExpectedRanges(kSourceId, "{ [0,230) }");
|
| +
|
| + // We expect garbage collection to fail, as we don't want to spontaneously
|
| + // create gaps in source buffer stream. Gaps could break playback for many
|
| + // clients, who don't bother to check ranges after append.
|
| + EXPECT_FALSE(demuxer_->EvictCodedFrames(
|
| + kSourceId, base::TimeDelta::FromMilliseconds(0), 0));
|
| + CheckExpectedRanges(kSourceId, "{ [0,230) }");
|
| +
|
| + // Increase media_time a bit, this will allow some data to be collected, but
|
| + // we are still over memory usage limit.
|
| + base::TimeDelta seek_time1 = base::TimeDelta::FromMilliseconds(23*2);
|
| + Seek(seek_time1);
|
| + EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, seek_time1, 0));
|
| + CheckExpectedRanges(kSourceId, "{ [46,230) }");
|
| +
|
| + base::TimeDelta seek_time2 = base::TimeDelta::FromMilliseconds(23*4);
|
| + Seek(seek_time2);
|
| + EXPECT_FALSE(demuxer_->EvictCodedFrames(kSourceId, seek_time2, 0));
|
| + CheckExpectedRanges(kSourceId, "{ [92,230) }");
|
| +
|
| + // media_time has progressed to a point where we can collect enough data to
|
| + // be under memory limit, so Evict should return true.
|
| + base::TimeDelta seek_time3 = base::TimeDelta::FromMilliseconds(23*6);
|
| + Seek(seek_time3);
|
| + EXPECT_TRUE(demuxer_->EvictCodedFrames(kSourceId, seek_time3, 0));
|
| + // Strictly speaking the current playback time is 23*6==138ms, so we could
|
| + // release data up to 138ms, but we only release as much data as necessary
|
| + // to bring memory usage under the limit, so we release only up to 115ms.
|
| + CheckExpectedRanges(kSourceId, "{ [115,230) }");
|
| }
|
|
|
| TEST_F(ChunkDemuxerTest, AppendWindow_Video) {
|
| @@ -3754,4 +3802,55 @@ TEST_F(ChunkDemuxerTest, CuesBetweenClusters) {
|
| CheckExpectedRanges(kSourceId, "{ [0,115) }");
|
| }
|
|
|
| +TEST_F(ChunkDemuxerTest, EvictCodedFramesTest) {
|
| + ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO));
|
| + demuxer_->SetMemoryLimits(DemuxerStream::AUDIO, 10 * kBlockSize);
|
| + demuxer_->SetMemoryLimits(DemuxerStream::VIDEO, 15 * kBlockSize);
|
| + DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO);
|
| + DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO);
|
| +
|
| + const char* kAudioStreamInfo = "0K 40K 80K 120K 160K 200K 240K 280K";
|
| + const char* kVideoStreamInfo = "0K 10 20K 30 40K 50 60K 70 80K 90 100K "
|
| + "110 120K 130 140K";
|
| + // Append 8 blocks (80 bytes) of data to audio stream and 15 blocks (150
|
| + // bytes) to video stream.
|
| + AppendMuxedCluster(
|
| + MuxedStreamInfo(kAudioTrackNum, kAudioStreamInfo),
|
| + MuxedStreamInfo(kVideoTrackNum, kVideoStreamInfo));
|
| + CheckExpectedBuffers(audio_stream, kAudioStreamInfo);
|
| + CheckExpectedBuffers(video_stream, kVideoStreamInfo);
|
| +
|
| + // If we want to append 80 more blocks of muxed a+v data and the current
|
| + // position is 0, that will fail, because EvictCodedFrames won't remove the
|
| + // data after the current playback position.
|
| + ASSERT_FALSE(demuxer_->EvictCodedFrames(kSourceId,
|
| + base::TimeDelta::FromMilliseconds(0),
|
| + 80));
|
| + // EvictCodedFrames has failed, so data should be unchanged.
|
| + Seek(base::TimeDelta::FromMilliseconds(0));
|
| + CheckExpectedBuffers(audio_stream, kAudioStreamInfo);
|
| + CheckExpectedBuffers(video_stream, kVideoStreamInfo);
|
| +
|
| + // But if we pretend that playback position has moved to 120ms, that allows
|
| + // EvictCodedFrames to garbage-collect enough data to succeed.
|
| + ASSERT_TRUE(demuxer_->EvictCodedFrames(kSourceId,
|
| + base::TimeDelta::FromMilliseconds(120),
|
| + 80));
|
| +
|
| + Seek(base::TimeDelta::FromMilliseconds(0));
|
| + // Audio stream had 8 buffers, video stream had 15. We told EvictCodedFrames
|
| + // that the new data size is 8 blocks muxed, i.e. 80 bytes. Given the current
|
| + // ratio of video to the total data size (15 : (8+15) ~= 0.65) the estimated
|
| + // sizes of video and audio data in the new 80 byte chunk are 52 bytes for
|
| + // video (80*0.65 = 52) and 28 bytes for audio (80 - 52).
|
| + // Given these numbers MSE GC will remove just one audio block (since current
|
| + // audio size is 80 bytes, new data is 28 bytes, we need to remove just one 10
|
| + // byte block to stay under 100 bytes memory limit after append
|
| + // 80 - 10 + 28 = 98).
|
| + // For video stream 150 + 52 = 202. Video limit is 150 bytes. We need to
|
| + // remove at least 6 blocks to stay under limit.
|
| + CheckExpectedBuffers(audio_stream, "40K 80K 120K 160K 200K 240K 280K");
|
| + CheckExpectedBuffers(video_stream, "60K 70 80K 90 100K 110 120K 130 140K");
|
| +}
|
| +
|
| } // namespace media
|
|
|