| Index: media/base/pipeline_unittest.cc
|
| diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
|
| index 4eb84f62c3f98eaa88a37c0dca1a1674527e546a..c064df4c3c130635380f33bd05fccbfa86ef25e0 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 {
|
| + 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 DestroyPipeline() {
|
| @@ -350,19 +309,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_;
|
|
|
| @@ -461,7 +415,7 @@ TEST_F(PipelineTest, DemuxerErrorDuringStop) {
|
| streams.push_back(audio_stream());
|
|
|
| SetDemuxerExpectations(&streams);
|
| - SetAudioRendererExpectations(audio_stream());
|
| + SetRendererExpectations();
|
|
|
| StartPipeline(PIPELINE_OK);
|
|
|
| @@ -499,7 +453,7 @@ TEST_F(PipelineTest, AudioStream) {
|
| streams.push_back(audio_stream());
|
|
|
| SetDemuxerExpectations(&streams);
|
| - SetAudioRendererExpectations(audio_stream());
|
| + SetRendererExpectations();
|
|
|
| StartPipeline(PIPELINE_OK);
|
| EXPECT_TRUE(metadata_.has_audio);
|
| @@ -512,7 +466,7 @@ TEST_F(PipelineTest, VideoStream) {
|
| streams.push_back(video_stream());
|
|
|
| SetDemuxerExpectations(&streams);
|
| - SetVideoRendererExpectations(video_stream());
|
| + SetRendererExpectations();
|
|
|
| StartPipeline(PIPELINE_OK);
|
| EXPECT_FALSE(metadata_.has_audio);
|
| @@ -527,8 +481,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);
|
| @@ -542,14 +495,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) {
|
| @@ -561,15 +513,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) {
|
| @@ -581,8 +531,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);
|
| @@ -599,7 +548,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);
|
| @@ -624,11 +573,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);
|
| @@ -642,7 +591,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(),
|
| @@ -657,7 +606,7 @@ TEST_F(PipelineTest, GetBufferedTimeRanges) {
|
|
|
| const base::TimeDelta kDuration = base::TimeDelta::FromSeconds(100);
|
| SetDemuxerExpectations(&streams, kDuration);
|
| - SetVideoRendererExpectations(video_stream());
|
| + SetRendererExpectations();
|
|
|
| StartPipeline(PIPELINE_OK);
|
|
|
| @@ -687,93 +636,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>()));
|
|
|
| @@ -813,7 +708,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.
|
| @@ -825,11 +720,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));
|
| @@ -842,75 +737,12 @@ 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);
|
| -}
|
| -
|
| TEST_F(PipelineTest, DestroyAfterStop) {
|
| CreateAudioStream();
|
| MockDemuxerStreamVector streams;
|
| streams.push_back(audio_stream());
|
| SetDemuxerExpectations(&streams);
|
| - SetAudioRendererExpectations(audio_stream());
|
| + SetRendererExpectations();
|
| StartPipeline(PIPELINE_OK);
|
|
|
| ExpectDemuxerStop();
|
| @@ -929,59 +761,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>());
|
| -
|
| - ExpectPipelineStopAndDestroyPipeline();
|
| - pipeline_->Stop(
|
| - base::Bind(&CallbackHelper::OnStop, base::Unretained(&callbacks_)));
|
| - message_loop_.RunUntilIdle();
|
| -}
|
| -
|
| class PipelineTeardownTest : public PipelineTest {
|
| public:
|
| enum TeardownState {
|
| kInitDemuxer,
|
| - kInitAudioRenderer,
|
| - kInitVideoRenderer,
|
| + kInitRenderer,
|
| kFlushing,
|
| kSeeking,
|
| kPlaying,
|
| @@ -999,8 +796,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;
|
|
|
| @@ -1068,60 +864,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)));
|
| - ExpectPipelineStopAndDestroyPipeline();
|
| - } 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)));
|
| ExpectPipelineStopAndDestroyPipeline();
|
| } 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)
|
| @@ -1152,35 +924,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) {
|
| @@ -1238,15 +1007,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);
|
|
|