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); |