Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(594)

Unified Diff: media/base/pipeline_unittest.cc

Issue 418143005: media: Introduce Renderer interface and RendererImpl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase only Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
« no previous file with comments | « media/base/pipeline.cc ('k') | media/base/renderer.h » ('j') | media/base/renderer.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698