diff options
author | dalecurtis <dalecurtis@chromium.org> | 2015-04-02 22:07:08 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-03 05:08:02 +0000 |
commit | c11e7bb244652731cc67c023bd2cf39e52df3544 (patch) | |
tree | 8f2469e39ebaf83c4ce70c81f0604663b5533640 /media/renderers/renderer_impl_unittest.cc | |
parent | 65cd862d0ba40f3fc93e5910aa8a81819748393b (diff) | |
download | chromium_src-c11e7bb244652731cc67c023bd2cf39e52df3544.zip chromium_src-c11e7bb244652731cc67c023bd2cf39e52df3544.tar.gz chromium_src-c11e7bb244652731cc67c023bd2cf39e52df3544.tar.bz2 |
Move underflow threshold limits out of the video renderer.
The threshold logic is incorrect when there's no audio track, which
the VideoRendererImpl has no knowledge of, so this logic needs to
live in the RendererImpl.
As a consequence of this, the underflow threshold is now based on
wall clock time instead of media time; which means non-realtime
playback will allow more or less media time to elapse before
underflow occurs.
Exposes a new command line flag --video-underflow-threshold-ms to
allow for experiments varying the threshold for YouTube.
BUG=423801, 470940
TEST=new unittests.
Review URL: https://codereview.chromium.org/1034233002
Cr-Commit-Position: refs/heads/master@{#323599}
Diffstat (limited to 'media/renderers/renderer_impl_unittest.cc')
-rw-r--r-- | media/renderers/renderer_impl_unittest.cc | 96 |
1 files changed, 91 insertions, 5 deletions
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc index 30bad2fe..1dacbcc 100644 --- a/media/renderers/renderer_impl_unittest.cc +++ b/media/renderers/renderer_impl_unittest.cc @@ -110,6 +110,8 @@ class RendererImplTest : public ::testing::Test { if (start_status == PIPELINE_OK && audio_stream_) { EXPECT_CALL(*audio_renderer_, GetTimeSource()) .WillOnce(Return(&time_source_)); + } else { + renderer_impl_->set_time_source_for_testing(&time_source_); } renderer_impl_->Initialize( @@ -174,10 +176,10 @@ class RendererImplTest : public ::testing::Test { base::TimeDelta start_time( base::TimeDelta::FromMilliseconds(kStartPlayingTimeInMs)); + EXPECT_CALL(time_source_, SetMediaTime(start_time)); + EXPECT_CALL(time_source_, StartTicking()); if (audio_stream_) { - EXPECT_CALL(time_source_, SetMediaTime(start_time)); - EXPECT_CALL(time_source_, StartTicking()); EXPECT_CALL(*audio_renderer_, StartPlaying()) .WillOnce(SetBufferingState(&audio_buffering_state_cb_, BUFFERING_HAVE_ENOUGH)); @@ -194,9 +196,10 @@ class RendererImplTest : public ::testing::Test { } void Flush(bool underflowed) { + if (!underflowed) + EXPECT_CALL(time_source_, StopTicking()); + if (audio_stream_) { - if (!underflowed) - EXPECT_CALL(time_source_, StopTicking()); EXPECT_CALL(*audio_renderer_, Flush(_)) .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_, BUFFERING_HAVE_NOTHING), @@ -367,7 +370,7 @@ TEST_F(RendererImplTest, VideoStreamEnded) { InitializeWithVideo(); Play(); - // Video ended won't affect |time_source_|. + EXPECT_CALL(time_source_, StopTicking()); EXPECT_CALL(callbacks_, OnEnded()); video_ended_cb_.Run(); @@ -446,4 +449,87 @@ TEST_F(RendererImplTest, ErrorDuringInitialize) { InitializeAndExpect(PIPELINE_ERROR_DECODE); } +TEST_F(RendererImplTest, AudioUnderflow) { + InitializeWithAudio(); + Play(); + + // Underflow should occur immediately with a single audio track. + EXPECT_CALL(time_source_, StopTicking()); + audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); +} + +TEST_F(RendererImplTest, AudioUnderflowWithVideo) { + InitializeWithAudioAndVideo(); + Play(); + + // Underflow should be immediate when both audio and video are present and + // audio underflows. + EXPECT_CALL(time_source_, StopTicking()); + audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); +} + +TEST_F(RendererImplTest, VideoUnderflow) { + InitializeWithVideo(); + Play(); + + // Underflow should occur immediately with a single video track. + EXPECT_CALL(time_source_, StopTicking()); + video_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); +} + +TEST_F(RendererImplTest, VideoUnderflowWithAudio) { + InitializeWithAudioAndVideo(); + Play(); + + // Set a zero threshold such that the underflow will be executed on the next + // run of the message loop. + renderer_impl_->set_video_underflow_threshold_for_testing(base::TimeDelta()); + + // Underflow should be delayed when both audio and video are present and video + // underflows. + video_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); + Mock::VerifyAndClearExpectations(&time_source_); + + EXPECT_CALL(time_source_, StopTicking()); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(RendererImplTest, VideoUnderflowWithAudioVideoRecovers) { + InitializeWithAudioAndVideo(); + Play(); + + // Set a zero threshold such that the underflow will be executed on the next + // run of the message loop. + renderer_impl_->set_video_underflow_threshold_for_testing(base::TimeDelta()); + + // Underflow should be delayed when both audio and video are present and video + // underflows. + video_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); + Mock::VerifyAndClearExpectations(&time_source_); + + // If video recovers, the underflow should never occur. + video_buffering_state_cb_.Run(BUFFERING_HAVE_ENOUGH); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(RendererImplTest, VideoAndAudioUnderflow) { + InitializeWithAudioAndVideo(); + Play(); + + // Set a zero threshold such that the underflow will be executed on the next + // run of the message loop. + renderer_impl_->set_video_underflow_threshold_for_testing(base::TimeDelta()); + + // Underflow should be delayed when both audio and video are present and video + // underflows. + video_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); + Mock::VerifyAndClearExpectations(&time_source_); + + EXPECT_CALL(time_source_, StopTicking()); + audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); + + // Nothing else should primed on the message loop. + base::RunLoop().RunUntilIdle(); +} + } // namespace media |