Chromium Code Reviews| Index: media/base/pipeline_unittest.cc |
| diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc |
| index 70c35bbbabba456dea91fe5810056f4a6d2990e5..3e5145e8ee4ec3c87c6f8a6e1f05c60bdd8ad5bd 100644 |
| --- a/media/base/pipeline_unittest.cc |
| +++ b/media/base/pipeline_unittest.cc |
| @@ -55,26 +55,6 @@ ACTION_P2(SetBufferingState, cb, buffering_state) { |
| cb->Run(buffering_state); |
| } |
| -// Used for setting expectations on pipeline callbacks. Using a StrictMock |
| -// also lets us test for missing callbacks. |
| -class CallbackHelper { |
| - public: |
| - CallbackHelper() {} |
| - virtual ~CallbackHelper() {} |
| - |
| - MOCK_METHOD1(OnStart, void(PipelineStatus)); |
| - MOCK_METHOD1(OnSeek, void(PipelineStatus)); |
| - MOCK_METHOD0(OnStop, void()); |
| - MOCK_METHOD0(OnEnded, void()); |
| - MOCK_METHOD1(OnError, void(PipelineStatus)); |
| - MOCK_METHOD1(OnMetadata, void(PipelineMetadata)); |
| - MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); |
| - MOCK_METHOD0(OnDurationChange, void()); |
| - |
| - private: |
| - DISALLOW_COPY_AND_ASSIGN(CallbackHelper); |
| -}; |
| - |
| // TODO(scherkus): even though some filters are initialized on separate |
| // threads these test aren't flaky... why? It's because filters' Initialize() |
| // is executed on |message_loop_| and the mock filters instantly call |
| @@ -83,6 +63,26 @@ class CallbackHelper { |
| // initialization is moved to a separate thread this test will become flaky. |
| class PipelineTest : public ::testing::Test { |
| public: |
| + // Used for setting expectations on pipeline callbacks. Using a StrictMock |
| + // also lets us test for missing callbacks. |
| + class CallbackHelper { |
|
scherkus (not reviewing)
2014/08/21 21:17:00
OOC why move here? so it doesn't pollute namespace
xhwang
2014/08/22 19:11:31
Yep. RendererImplTest is also using CallbackHelp,
|
| + public: |
| + CallbackHelper() {} |
| + virtual ~CallbackHelper() {} |
| + |
| + MOCK_METHOD1(OnStart, void(PipelineStatus)); |
| + MOCK_METHOD1(OnSeek, void(PipelineStatus)); |
| + MOCK_METHOD0(OnStop, void()); |
| + MOCK_METHOD0(OnEnded, void()); |
| + MOCK_METHOD1(OnError, void(PipelineStatus)); |
| + MOCK_METHOD1(OnMetadata, void(PipelineMetadata)); |
| + MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); |
| + MOCK_METHOD0(OnDurationChange, void()); |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(CallbackHelper); |
| + }; |
| + |
| PipelineTest() |
| : pipeline_(new Pipeline(message_loop_.message_loop_proxy(), |
| new MediaLog())), |
| @@ -90,13 +90,9 @@ class PipelineTest : public ::testing::Test { |
| demuxer_(new StrictMock<MockDemuxer>()) { |
| filter_collection_->SetDemuxer(demuxer_.get()); |
| - video_renderer_ = new StrictMock<MockVideoRenderer>(); |
| - scoped_ptr<VideoRenderer> video_renderer(video_renderer_); |
| - filter_collection_->SetVideoRenderer(video_renderer.Pass()); |
| - |
| - audio_renderer_ = new StrictMock<MockAudioRenderer>(); |
| - scoped_ptr<AudioRenderer> audio_renderer(audio_renderer_); |
| - filter_collection_->SetAudioRenderer(audio_renderer.Pass()); |
| + renderer_ = new StrictMock<MockRenderer>(); |
| + scoped_ptr<Renderer> renderer(renderer_); |
| + filter_collection_->SetRenderer(renderer.Pass()); |
| text_renderer_ = new TextRenderer( |
| message_loop_.message_loop_proxy(), |
| @@ -116,6 +112,9 @@ class PipelineTest : public ::testing::Test { |
| EXPECT_CALL(*demuxer_, GetLiveness()) |
| .WillRepeatedly(Return(Demuxer::LIVENESS_UNKNOWN)); |
| + |
| + EXPECT_CALL(*renderer_, GetMediaTime()) |
| + .WillRepeatedly(Return(base::TimeDelta())); |
| } |
| virtual ~PipelineTest() { |
| @@ -175,20 +174,13 @@ class PipelineTest : public ::testing::Test { |
| } |
| // Sets up expectations to allow the video renderer to initialize. |
| - void SetVideoRendererExpectations(DemuxerStream* stream) { |
| - EXPECT_CALL(*video_renderer_, Initialize(stream, _, _, _, _, _, _, _, _, _)) |
| - .WillOnce(DoAll(SaveArg<5>(&video_buffering_state_cb_), |
| - SaveArg<6>(&video_ended_cb_), |
| - RunCallback<2>(PIPELINE_OK))); |
| - } |
| - |
| - // Sets up expectations to allow the audio renderer to initialize. |
| - void SetAudioRendererExpectations(DemuxerStream* stream) { |
| - EXPECT_CALL(*audio_renderer_, Initialize(stream, _, _, _, _, _, _)) |
| - .WillOnce(DoAll(SaveArg<3>(&audio_time_cb_), |
| - SaveArg<4>(&audio_buffering_state_cb_), |
| - SaveArg<5>(&audio_ended_cb_), |
| - RunCallback<1>(PIPELINE_OK))); |
| + void SetRendererExpectations() { |
| + EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _)) |
| + .WillOnce(DoAll(SaveArg<2>(&ended_cb_), |
| + SaveArg<4>(&buffering_state_cb_), |
| + RunCallback<0>(PIPELINE_OK))); |
| + EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(audio_stream())); |
| + EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(video_stream())); |
| } |
| void AddTextStream() { |
| @@ -196,6 +188,7 @@ class PipelineTest : public ::testing::Test { |
| .WillOnce(Invoke(this, &PipelineTest::DoOnAddTextTrack)); |
| static_cast<DemuxerHost*>(pipeline_.get())->AddTextStream(text_stream(), |
| TextTrackConfig(kTextSubtitles, "", "", "")); |
| + message_loop_.RunUntilIdle(); |
| } |
| // Sets up expectations on the callback and initializes the pipeline. Called |
| @@ -205,25 +198,11 @@ class PipelineTest : public ::testing::Test { |
| if (start_status == PIPELINE_OK) { |
| EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_)); |
| - |
| - if (audio_stream_) { |
| - EXPECT_CALL(*audio_renderer_, GetTimeSource()) |
| - .WillOnce(Return(&time_source_)); |
| - EXPECT_CALL(time_source_, SetPlaybackRate(0.0f)); |
| - EXPECT_CALL(time_source_, SetMediaTime(base::TimeDelta())); |
| - EXPECT_CALL(time_source_, StartTicking()); |
| - EXPECT_CALL(*audio_renderer_, SetVolume(1.0f)); |
| - EXPECT_CALL(*audio_renderer_, StartPlaying()) |
| - .WillOnce(SetBufferingState(&audio_buffering_state_cb_, |
| - BUFFERING_HAVE_ENOUGH)); |
| - } |
| - |
| - if (video_stream_) { |
| - EXPECT_CALL(*video_renderer_, StartPlaying()) |
| - .WillOnce(SetBufferingState(&video_buffering_state_cb_, |
| - BUFFERING_HAVE_ENOUGH)); |
| - } |
| - |
| + EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f)); |
| + EXPECT_CALL(*renderer_, SetVolume(1.0f)); |
| + EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) |
| + .WillOnce(SetBufferingState(&buffering_state_cb_, |
| + BUFFERING_HAVE_ENOUGH)); |
| EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
| } |
| @@ -268,35 +247,19 @@ class PipelineTest : public ::testing::Test { |
| } |
| void ExpectSeek(const base::TimeDelta& seek_time, bool underflowed) { |
| - // Every filter should receive a call to Seek(). |
| EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
| .WillOnce(RunCallback<1>(PIPELINE_OK)); |
| - 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), |
| - RunClosure<0>())); |
| - EXPECT_CALL(time_source_, SetMediaTime(seek_time)); |
| - EXPECT_CALL(time_source_, SetPlaybackRate(_)); |
| - EXPECT_CALL(time_source_, StartTicking()); |
| - EXPECT_CALL(*audio_renderer_, StartPlaying()) |
| - .WillOnce(SetBufferingState(&audio_buffering_state_cb_, |
| - BUFFERING_HAVE_ENOUGH)); |
| - EXPECT_CALL(*audio_renderer_, SetVolume(_)); |
| - } |
| - |
| - if (video_stream_) { |
| - EXPECT_CALL(*video_renderer_, Flush(_)) |
| - .WillOnce(DoAll(SetBufferingState(&video_buffering_state_cb_, |
| - BUFFERING_HAVE_NOTHING), |
| - RunClosure<0>())); |
| - EXPECT_CALL(*video_renderer_, StartPlaying()) |
| - .WillOnce(SetBufferingState(&video_buffering_state_cb_, |
| - BUFFERING_HAVE_ENOUGH)); |
| - } |
| + EXPECT_CALL(*renderer_, Flush(_)) |
| + .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, |
| + BUFFERING_HAVE_NOTHING), |
| + RunClosure<0>())); |
| + EXPECT_CALL(*renderer_, SetPlaybackRate(_)); |
| + EXPECT_CALL(*renderer_, SetVolume(_)); |
| + EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time)) |
| + .WillOnce(SetBufferingState(&buffering_state_cb_, |
| + BUFFERING_HAVE_ENOUGH)); |
| + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| // We expect a successful seek callback followed by a buffering update. |
| EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
| @@ -307,11 +270,7 @@ class PipelineTest : public ::testing::Test { |
| pipeline_->Seek(seek_time, |
| base::Bind(&CallbackHelper::OnSeek, |
| base::Unretained(&callbacks_))); |
| - |
| - // We expect the time to be updated only after the seek has completed. |
| - EXPECT_NE(seek_time, pipeline_->GetMediaTime()); |
| message_loop_.RunUntilIdle(); |
| - EXPECT_EQ(seek_time, pipeline_->GetMediaTime()); |
| } |
| void ExpectStop() { |
| @@ -336,19 +295,14 @@ class PipelineTest : public ::testing::Test { |
| scoped_ptr<FilterCollection> filter_collection_; |
| scoped_ptr<StrictMock<MockDemuxer> > demuxer_; |
| - StrictMock<MockVideoRenderer>* video_renderer_; |
| - StrictMock<MockAudioRenderer>* audio_renderer_; |
| - StrictMock<MockTimeSource> time_source_; |
| + StrictMock<MockRenderer>* renderer_; |
| StrictMock<CallbackHelper> text_renderer_callbacks_; |
| TextRenderer* text_renderer_; |
| scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_; |
| scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_; |
| scoped_ptr<FakeTextTrackStream> text_stream_; |
| - AudioRenderer::TimeCB audio_time_cb_; |
| - BufferingStateCB audio_buffering_state_cb_; |
| - BufferingStateCB video_buffering_state_cb_; |
| - base::Closure audio_ended_cb_; |
| - base::Closure video_ended_cb_; |
| + BufferingStateCB buffering_state_cb_; |
| + base::Closure ended_cb_; |
| VideoDecoderConfig video_decoder_config_; |
| PipelineMetadata metadata_; |
| @@ -447,7 +401,7 @@ TEST_F(PipelineTest, DemuxerErrorDuringStop) { |
| streams.push_back(audio_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| @@ -485,7 +439,7 @@ TEST_F(PipelineTest, AudioStream) { |
| streams.push_back(audio_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| EXPECT_TRUE(metadata_.has_audio); |
| @@ -498,7 +452,7 @@ TEST_F(PipelineTest, VideoStream) { |
| streams.push_back(video_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetVideoRendererExpectations(video_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| EXPECT_FALSE(metadata_.has_audio); |
| @@ -513,8 +467,7 @@ TEST_F(PipelineTest, AudioVideoStream) { |
| streams.push_back(video_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| - SetVideoRendererExpectations(video_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| EXPECT_TRUE(metadata_.has_audio); |
| @@ -528,14 +481,13 @@ TEST_F(PipelineTest, VideoTextStream) { |
| streams.push_back(video_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetVideoRendererExpectations(video_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| EXPECT_FALSE(metadata_.has_audio); |
| EXPECT_TRUE(metadata_.has_video); |
| AddTextStream(); |
| - message_loop_.RunUntilIdle(); |
| } |
| TEST_F(PipelineTest, VideoAudioTextStream) { |
| @@ -547,15 +499,13 @@ TEST_F(PipelineTest, VideoAudioTextStream) { |
| streams.push_back(audio_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetVideoRendererExpectations(video_stream()); |
| - SetAudioRendererExpectations(audio_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| EXPECT_TRUE(metadata_.has_audio); |
| EXPECT_TRUE(metadata_.has_video); |
| AddTextStream(); |
| - message_loop_.RunUntilIdle(); |
| } |
| TEST_F(PipelineTest, Seek) { |
| @@ -567,8 +517,7 @@ TEST_F(PipelineTest, Seek) { |
| streams.push_back(video_stream()); |
| SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
| - SetAudioRendererExpectations(audio_stream()); |
| - SetVideoRendererExpectations(video_stream()); |
| + SetRendererExpectations(); |
| // Initialize then seek! |
| StartPipeline(PIPELINE_OK); |
| @@ -585,7 +534,7 @@ TEST_F(PipelineTest, SeekAfterError) { |
| streams.push_back(audio_stream()); |
| SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
| - SetAudioRendererExpectations(audio_stream()); |
| + SetRendererExpectations(); |
| // Initialize then seek! |
| StartPipeline(PIPELINE_OK); |
| @@ -610,11 +559,11 @@ TEST_F(PipelineTest, SetVolume) { |
| streams.push_back(audio_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| + SetRendererExpectations(); |
| // The audio renderer should receive a call to SetVolume(). |
| float expected = 0.5f; |
| - EXPECT_CALL(*audio_renderer_, SetVolume(expected)); |
| + EXPECT_CALL(*renderer_, SetVolume(expected)); |
| // Initialize then set volume! |
| StartPipeline(PIPELINE_OK); |
| @@ -628,7 +577,7 @@ TEST_F(PipelineTest, Properties) { |
| const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
| SetDemuxerExpectations(&streams, kDuration); |
| - SetVideoRendererExpectations(video_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| EXPECT_EQ(kDuration.ToInternalValue(), |
| @@ -643,7 +592,7 @@ TEST_F(PipelineTest, GetBufferedTimeRanges) { |
| const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100); |
| SetDemuxerExpectations(&streams, kDuration); |
| - SetVideoRendererExpectations(video_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| @@ -673,93 +622,39 @@ TEST_F(PipelineTest, EndedCallback) { |
| streams.push_back(video_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| - SetVideoRendererExpectations(video_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| AddTextStream(); |
| // The ended callback shouldn't run until all renderers have ended. |
| - audio_ended_cb_.Run(); |
| - message_loop_.RunUntilIdle(); |
| - |
| - video_ended_cb_.Run(); |
| + ended_cb_.Run(); |
| message_loop_.RunUntilIdle(); |
| - EXPECT_CALL(time_source_, StopTicking()); |
| EXPECT_CALL(callbacks_, OnEnded()); |
| text_stream()->SendEosNotification(); |
| message_loop_.RunUntilIdle(); |
| } |
| -TEST_F(PipelineTest, AudioStreamShorterThanVideo) { |
| - base::TimeDelta duration = base::TimeDelta::FromSeconds(10); |
| - |
| - CreateAudioStream(); |
| - CreateVideoStream(); |
| - MockDemuxerStreamVector streams; |
| - streams.push_back(audio_stream()); |
| - streams.push_back(video_stream()); |
| - |
| - // Replace what's used for interpolating to simulate wall clock time. |
| - pipeline_->SetTimeDeltaInterpolatorForTesting( |
| - new TimeDeltaInterpolator(&test_tick_clock_)); |
| - |
| - SetDemuxerExpectations(&streams, duration); |
| - SetAudioRendererExpectations(audio_stream()); |
| - SetVideoRendererExpectations(video_stream()); |
| - StartPipeline(PIPELINE_OK); |
| - |
| - EXPECT_EQ(0, pipeline_->GetMediaTime().ToInternalValue()); |
| - |
| - float playback_rate = 1.0f; |
| - EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate)); |
| - pipeline_->SetPlaybackRate(playback_rate); |
| - message_loop_.RunUntilIdle(); |
| - |
| - InSequence s; |
| - |
| - // Verify that the clock doesn't advance since it hasn't been started by |
| - // a time update from the audio stream. |
| - int64 start_time = pipeline_->GetMediaTime().ToInternalValue(); |
| - test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(100)); |
| - EXPECT_EQ(pipeline_->GetMediaTime().ToInternalValue(), start_time); |
| - |
| - // Signal end of audio stream. |
| - audio_ended_cb_.Run(); |
| - message_loop_.RunUntilIdle(); |
| - |
| - // Verify that the clock advances. |
| - start_time = pipeline_->GetMediaTime().ToInternalValue(); |
| - test_tick_clock_.Advance(base::TimeDelta::FromMilliseconds(100)); |
| - EXPECT_GT(pipeline_->GetMediaTime().ToInternalValue(), start_time); |
| - |
| - // Signal end of video stream and make sure OnEnded() callback occurs. |
| - EXPECT_CALL(time_source_, StopTicking()); |
| - EXPECT_CALL(callbacks_, OnEnded()); |
| - video_ended_cb_.Run(); |
| -} |
| - |
| TEST_F(PipelineTest, ErrorDuringSeek) { |
| CreateAudioStream(); |
| MockDemuxerStreamVector streams; |
| streams.push_back(audio_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| float playback_rate = 1.0f; |
| - EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate)); |
| + EXPECT_CALL(*renderer_, SetPlaybackRate(playback_rate)); |
| pipeline_->SetPlaybackRate(playback_rate); |
| message_loop_.RunUntilIdle(); |
| base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| - // Preroll() isn't called as the demuxer errors out first. |
| - EXPECT_CALL(time_source_, StopTicking()); |
| - EXPECT_CALL(*audio_renderer_, Flush(_)) |
| - .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_, |
| + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| + EXPECT_CALL(*renderer_, Flush(_)) |
| + .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, |
| BUFFERING_HAVE_NOTHING), |
| RunClosure<0>())); |
| @@ -799,7 +694,7 @@ TEST_F(PipelineTest, NoMessageDuringTearDownFromError) { |
| streams.push_back(audio_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| // Trigger additional requests on the pipeline during tear down from error. |
| @@ -811,11 +706,11 @@ TEST_F(PipelineTest, NoMessageDuringTearDownFromError) { |
| base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| // Seek() isn't called as the demuxer errors out first. |
| - EXPECT_CALL(time_source_, StopTicking()); |
| - EXPECT_CALL(*audio_renderer_, Flush(_)) |
| - .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_, |
| + EXPECT_CALL(*renderer_, Flush(_)) |
| + .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, |
| BUFFERING_HAVE_NOTHING), |
| RunClosure<0>())); |
| + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
| .WillOnce(RunCallback<1>(PIPELINE_ERROR_READ)); |
| @@ -828,69 +723,6 @@ TEST_F(PipelineTest, NoMessageDuringTearDownFromError) { |
| message_loop_.RunUntilIdle(); |
| } |
| -static void RunTimeCB(const AudioRenderer::TimeCB& time_cb, |
| - int time_in_ms, |
| - int max_time_in_ms) { |
| - time_cb.Run(base::TimeDelta::FromMilliseconds(time_in_ms), |
| - base::TimeDelta::FromMilliseconds(max_time_in_ms)); |
| -} |
| - |
| -TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) { |
| - CreateAudioStream(); |
| - MockDemuxerStreamVector streams; |
| - streams.push_back(audio_stream()); |
| - |
| - SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| - StartPipeline(PIPELINE_OK); |
| - |
| - float playback_rate = 1.0f; |
| - EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate)); |
| - pipeline_->SetPlaybackRate(playback_rate); |
| - message_loop_.RunUntilIdle(); |
| - |
| - // Provide an initial time update so that the pipeline transitions out of the |
| - // "waiting for time update" state. |
| - audio_time_cb_.Run(base::TimeDelta::FromMilliseconds(100), |
| - base::TimeDelta::FromMilliseconds(500)); |
| - |
| - base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5); |
| - |
| - // Arrange to trigger a time update while the demuxer is in the middle of |
| - // seeking. This update should be ignored by the pipeline and the clock should |
| - // not get updated. |
| - base::Closure closure = base::Bind(&RunTimeCB, audio_time_cb_, 300, 700); |
| - EXPECT_CALL(*demuxer_, Seek(seek_time, _)) |
| - .WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run), |
| - RunCallback<1>(PIPELINE_OK))); |
| - |
| - EXPECT_CALL(time_source_, StopTicking()); |
| - EXPECT_CALL(*audio_renderer_, Flush(_)) |
| - .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_, |
| - BUFFERING_HAVE_NOTHING), |
| - RunClosure<0>())); |
| - EXPECT_CALL(time_source_, SetMediaTime(seek_time)); |
| - EXPECT_CALL(time_source_, SetPlaybackRate(_)); |
| - EXPECT_CALL(time_source_, StartTicking()); |
| - EXPECT_CALL(*audio_renderer_, StartPlaying()) |
| - .WillOnce(SetBufferingState(&audio_buffering_state_cb_, |
| - BUFFERING_HAVE_ENOUGH)); |
| - EXPECT_CALL(*audio_renderer_, SetVolume(_)); |
| - |
| - EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK)); |
| - EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
| - DoSeek(seek_time); |
| - |
| - EXPECT_EQ(pipeline_->GetMediaTime(), seek_time); |
| - |
| - // Now that the seek is complete, verify that time updates advance the current |
| - // time. |
| - base::TimeDelta new_time = seek_time + base::TimeDelta::FromMilliseconds(100); |
| - audio_time_cb_.Run(new_time, new_time); |
| - |
| - EXPECT_EQ(pipeline_->GetMediaTime(), new_time); |
| -} |
| - |
| static void DeletePipeline(scoped_ptr<Pipeline> pipeline) { |
| // |pipeline| will go out of scope. |
| } |
| @@ -900,7 +732,7 @@ TEST_F(PipelineTest, DeleteAfterStop) { |
| MockDemuxerStreamVector streams; |
| streams.push_back(audio_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| ExpectStop(); |
| @@ -918,58 +750,24 @@ TEST_F(PipelineTest, Underflow) { |
| streams.push_back(video_stream()); |
| SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| - SetVideoRendererExpectations(video_stream()); |
| + SetRendererExpectations(); |
| StartPipeline(PIPELINE_OK); |
| // Simulate underflow. |
| - EXPECT_CALL(time_source_, StopTicking()); |
| - audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); |
| + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| + buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING); |
| - // Seek while underflowed. We shouldn't call StopTicking() again. |
| + // Seek while underflowed. |
| base::TimeDelta expected = base::TimeDelta::FromSeconds(5); |
| ExpectSeek(expected, true); |
| DoSeek(expected); |
| } |
| -static void PostTimeCB(base::MessageLoop* message_loop, |
| - const AudioRenderer::TimeCB& time_cb) { |
| - base::TimeDelta new_time = base::TimeDelta::FromMilliseconds(100); |
| - message_loop->PostTask(FROM_HERE, base::Bind(time_cb, new_time, new_time)); |
| -} |
| - |
| -TEST_F(PipelineTest, TimeUpdateAfterStop) { |
| - CreateAudioStream(); |
| - CreateVideoStream(); |
| - MockDemuxerStreamVector streams; |
| - streams.push_back(audio_stream()); |
| - streams.push_back(video_stream()); |
| - |
| - SetDemuxerExpectations(&streams); |
| - SetAudioRendererExpectations(audio_stream()); |
| - SetVideoRendererExpectations(video_stream()); |
| - StartPipeline(PIPELINE_OK); |
| - |
| - // Double post here! This is a hack to simulate the case where TimeCB is |
| - // posted during ~AudioRenderer(), which is triggered in Pipeline::DoStop. |
| - // Since we can't EXPECT_CALL the dtor and Pipeline::DoStop() is posted |
| - // as well, we need to post twice here. |
| - message_loop_.PostTask( |
| - FROM_HERE, base::Bind(&PostTimeCB, &message_loop_, audio_time_cb_)); |
| - |
| - EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>()); |
| - |
| - Pipeline* pipeline = pipeline_.get(); |
| - pipeline->Stop(base::Bind(&DeletePipeline, base::Passed(&pipeline_))); |
| - message_loop_.RunUntilIdle(); |
| -} |
| - |
| class PipelineTeardownTest : public PipelineTest { |
| public: |
| enum TeardownState { |
| kInitDemuxer, |
| - kInitAudioRenderer, |
| - kInitVideoRenderer, |
| + kInitRenderer, |
| kFlushing, |
| kSeeking, |
| kPlaying, |
| @@ -987,8 +785,7 @@ class PipelineTeardownTest : public PipelineTest { |
| void RunTest(TeardownState state, StopOrError stop_or_error) { |
| switch (state) { |
| case kInitDemuxer: |
| - case kInitAudioRenderer: |
| - case kInitVideoRenderer: |
| + case kInitRenderer: |
| DoInitialize(state, stop_or_error); |
| break; |
| @@ -1056,60 +853,36 @@ class PipelineTeardownTest : public PipelineTest { |
| streams.push_back(video_stream()); |
| SetDemuxerExpectations(&streams, base::TimeDelta::FromSeconds(3000)); |
| - if (state == kInitAudioRenderer) { |
| - if (stop_or_error == kStop) { |
| - EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _)) |
| - .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), |
| - RunCallback<1>(PIPELINE_OK))); |
| - EXPECT_CALL(callbacks_, OnStop()); |
| - } else { |
| - status = PIPELINE_ERROR_INITIALIZATION_FAILED; |
| - EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _)) |
| - .WillOnce(RunCallback<1>(status)); |
| - } |
| - |
| - EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>()); |
| - return status; |
| - } |
| - |
| - EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _)) |
| - .WillOnce(DoAll(SaveArg<4>(&audio_buffering_state_cb_), |
| - RunCallback<1>(PIPELINE_OK))); |
| + EXPECT_CALL(*renderer_, HasAudio()).WillRepeatedly(Return(true)); |
| + EXPECT_CALL(*renderer_, HasVideo()).WillRepeatedly(Return(true)); |
| - if (state == kInitVideoRenderer) { |
| + if (state == kInitRenderer) { |
| if (stop_or_error == kStop) { |
| - EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _)) |
| + EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _)) |
| .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), |
| - RunCallback<2>(PIPELINE_OK))); |
| + RunCallback<0>(PIPELINE_OK))); |
| EXPECT_CALL(callbacks_, OnStop()); |
| } else { |
| status = PIPELINE_ERROR_INITIALIZATION_FAILED; |
| - EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _)) |
| - .WillOnce(RunCallback<2>(status)); |
| + EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _)) |
| + .WillOnce(RunCallback<0>(status)); |
| } |
| EXPECT_CALL(*demuxer_, Stop(_)).WillOnce(RunClosure<0>()); |
| return status; |
| } |
| - EXPECT_CALL(*video_renderer_, Initialize(_, _, _, _, _, _, _, _, _, _)) |
| - .WillOnce(DoAll(SaveArg<5>(&video_buffering_state_cb_), |
| - RunCallback<2>(PIPELINE_OK))); |
| + EXPECT_CALL(*renderer_, Initialize(_, _, _, _, _, _)) |
| + .WillOnce(DoAll(SaveArg<4>(&buffering_state_cb_), |
| + RunCallback<0>(PIPELINE_OK))); |
| EXPECT_CALL(callbacks_, OnMetadata(_)); |
| // If we get here it's a successful initialization. |
| - EXPECT_CALL(*audio_renderer_, GetTimeSource()) |
| - .WillOnce(Return(&time_source_)); |
| - EXPECT_CALL(time_source_, SetMediaTime(base::TimeDelta())); |
| - EXPECT_CALL(time_source_, SetPlaybackRate(0.0f)); |
| - EXPECT_CALL(time_source_, StartTicking()); |
| - EXPECT_CALL(*audio_renderer_, SetVolume(1.0f)); |
| - EXPECT_CALL(*audio_renderer_, StartPlaying()) |
| - .WillOnce(SetBufferingState(&audio_buffering_state_cb_, |
| - BUFFERING_HAVE_ENOUGH)); |
| - EXPECT_CALL(*video_renderer_, StartPlaying()) |
| - .WillOnce(SetBufferingState(&video_buffering_state_cb_, |
| + EXPECT_CALL(*renderer_, SetPlaybackRate(0.0f)); |
| + EXPECT_CALL(*renderer_, SetVolume(1.0f)); |
| + EXPECT_CALL(*renderer_, StartPlayingFrom(base::TimeDelta())) |
| + .WillOnce(SetBufferingState(&buffering_state_cb_, |
| BUFFERING_HAVE_ENOUGH)); |
| if (status == PIPELINE_OK) |
| @@ -1140,35 +913,32 @@ class PipelineTeardownTest : public PipelineTest { |
| base::Closure stop_cb = base::Bind( |
| &CallbackHelper::OnStop, base::Unretained(&callbacks_)); |
| - EXPECT_CALL(time_source_, StopTicking()); |
| - |
| if (state == kFlushing) { |
| if (stop_or_error == kStop) { |
| - EXPECT_CALL(*audio_renderer_, Flush(_)) |
| + EXPECT_CALL(*renderer_, Flush(_)) |
| .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), |
| - SetBufferingState(&audio_buffering_state_cb_, |
| + SetBufferingState(&buffering_state_cb_, |
| BUFFERING_HAVE_NOTHING), |
| RunClosure<0>())); |
| + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| } else { |
| status = PIPELINE_ERROR_READ; |
| - EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce( |
| - DoAll(SetError(pipeline_.get(), status), |
| - SetBufferingState(&audio_buffering_state_cb_, |
| - BUFFERING_HAVE_NOTHING), |
| - RunClosure<0>())); |
| + EXPECT_CALL(*renderer_, Flush(_)) |
| + .WillOnce(DoAll(SetError(pipeline_.get(), status), |
| + SetBufferingState(&buffering_state_cb_, |
| + BUFFERING_HAVE_NOTHING), |
| + RunClosure<0>())); |
| + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| } |
| return status; |
| } |
| - EXPECT_CALL(*audio_renderer_, Flush(_)) |
| - .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_, |
| - BUFFERING_HAVE_NOTHING), |
| - RunClosure<0>())); |
| - EXPECT_CALL(*video_renderer_, Flush(_)) |
| - .WillOnce(DoAll(SetBufferingState(&video_buffering_state_cb_, |
| + EXPECT_CALL(*renderer_, Flush(_)) |
| + .WillOnce(DoAll(SetBufferingState(&buffering_state_cb_, |
| BUFFERING_HAVE_NOTHING), |
| RunClosure<0>())); |
| + EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
| if (state == kSeeking) { |
| if (stop_or_error == kStop) { |
| @@ -1226,15 +996,13 @@ class PipelineTeardownTest : public PipelineTest { |
| } |
| INSTANTIATE_TEARDOWN_TEST(Stop, InitDemuxer); |
| -INSTANTIATE_TEARDOWN_TEST(Stop, InitAudioRenderer); |
| -INSTANTIATE_TEARDOWN_TEST(Stop, InitVideoRenderer); |
| +INSTANTIATE_TEARDOWN_TEST(Stop, InitRenderer); |
| INSTANTIATE_TEARDOWN_TEST(Stop, Flushing); |
| INSTANTIATE_TEARDOWN_TEST(Stop, Seeking); |
| INSTANTIATE_TEARDOWN_TEST(Stop, Playing); |
| INSTANTIATE_TEARDOWN_TEST(Error, InitDemuxer); |
| -INSTANTIATE_TEARDOWN_TEST(Error, InitAudioRenderer); |
| -INSTANTIATE_TEARDOWN_TEST(Error, InitVideoRenderer); |
| +INSTANTIATE_TEARDOWN_TEST(Error, InitRenderer); |
| INSTANTIATE_TEARDOWN_TEST(Error, Flushing); |
| INSTANTIATE_TEARDOWN_TEST(Error, Seeking); |
| INSTANTIATE_TEARDOWN_TEST(Error, Playing); |