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

Unified Diff: media/base/pipeline_unittest.cc

Issue 10828045: Rewrite media::Pipeline state transition machinery. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: stuff Created 8 years, 5 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 1ff12c23d8b6e136059add328593151ab85bbbfb..683f870d5acbcb9e0b565e706bc985b41508d0f9 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -42,6 +42,14 @@ ACTION_P(SetDemuxerProperties, duration) {
arg0->SetDuration(duration);
}
+ACTION_P2(Stop, pipeline, stop_cb) {
+ pipeline->Stop(stop_cb);
+}
+
+ACTION_P2(SetError, pipeline, status) {
+ pipeline->SetErrorForTesting(status);
+}
+
ACTION(RunPipelineStatusCB1) {
arg1.Run(PIPELINE_OK);
}
@@ -90,35 +98,23 @@ class PipelineTest : public ::testing::Test {
}
virtual ~PipelineTest() {
- if (!pipeline_->IsRunning()) {
- return;
- }
-
// Shutdown sequence.
- if (pipeline_->IsInitialized()) {
+ if (pipeline_->IsRunning()) {
EXPECT_CALL(*mocks_->demuxer(), Stop(_))
.WillOnce(RunClosure());
if (audio_stream_) {
- EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
scherkus (not reviewing) 2012/07/28 02:26:07 Note lack of Pause/Flush prior to Stop!
- .WillOnce(RunClosure());
- EXPECT_CALL(*mocks_->audio_renderer(), Flush(_))
- .WillOnce(RunClosure());
EXPECT_CALL(*mocks_->audio_renderer(), Stop(_))
.WillOnce(RunClosure());
}
if (video_stream_) {
- EXPECT_CALL(*mocks_->video_renderer(), Pause(_))
- .WillOnce(RunClosure());
- EXPECT_CALL(*mocks_->video_renderer(), Flush(_))
- .WillOnce(RunClosure());
EXPECT_CALL(*mocks_->video_renderer(), Stop(_))
.WillOnce(RunClosure());
}
}
- // Expect a stop callback if we were started.
+ // Stop() callbacks are always executed regardless of run state.
EXPECT_CALL(callbacks_, OnStop());
pipeline_->Stop(base::Bind(&CallbackHelper::OnStop,
base::Unretained(&callbacks_)));
@@ -250,6 +246,7 @@ class PipelineTest : public ::testing::Test {
// Every filter should receive a call to Seek().
EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _))
.WillOnce(RunPipelineStatusCB1());
+ EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(_));
if (audio_stream_) {
EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
@@ -258,6 +255,8 @@ class PipelineTest : public ::testing::Test {
.WillOnce(RunClosure());
EXPECT_CALL(*mocks_->audio_renderer(), Preroll(seek_time, _))
.WillOnce(RunPipelineStatusCB1());
+ EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(_));
+ EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(_));
scherkus (not reviewing) 2012/07/28 02:26:07 note new calls to SPR/SV()
EXPECT_CALL(*mocks_->audio_renderer(), Play(_))
.WillOnce(RunClosure());
}
@@ -269,6 +268,7 @@ class PipelineTest : public ::testing::Test {
.WillOnce(RunClosure());
EXPECT_CALL(*mocks_->video_renderer(), Preroll(seek_time, _))
.WillOnce(RunPipelineStatusCB1());
+ EXPECT_CALL(*mocks_->video_renderer(), SetPlaybackRate(_));
EXPECT_CALL(*mocks_->video_renderer(), Play(_))
.WillOnce(RunClosure());
}
@@ -288,6 +288,17 @@ class PipelineTest : public ::testing::Test {
EXPECT_EQ(seek_time, pipeline_->GetMediaTime());
}
+ void SetupErrorTest() {
+ CreateAudioStream();
+ MockDemuxerStreamVector streams;
+ streams.push_back(audio_stream());
+
+ InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(3000));
+ InitializeAudioDecoder(audio_stream());
+ InitializeAudioRenderer();
+ InitializePipeline(PIPELINE_OK);
+ }
+
// Fixture members.
StrictMock<CallbackHelper> callbacks_;
MessageLoop message_loop_;
@@ -307,7 +318,6 @@ TEST_F(PipelineTest, NotStarted) {
const base::TimeDelta kZero;
EXPECT_FALSE(pipeline_->IsRunning());
- EXPECT_FALSE(pipeline_->IsInitialized());
EXPECT_FALSE(pipeline_->HasAudio());
EXPECT_FALSE(pipeline_->HasVideo());
@@ -338,31 +348,6 @@ TEST_F(PipelineTest, NotStarted) {
EXPECT_EQ(0, size.height());
}
-TEST_F(PipelineTest, NeverInitializes) {
scherkus (not reviewing) 2012/07/28 02:26:07 this test hangs with the new pipeline because insi
acolwell GONE FROM CHROMIUM 2012/07/30 18:33:10 Doesn't this essentially test the case where the p
- // Don't execute the callback passed into Initialize().
- EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _));
- EXPECT_CALL(*mocks_->demuxer(), Stop(_))
- .WillOnce(RunClosure());
-
- // This test hangs during initialization by never calling
- // InitializationComplete(). StrictMock<> will ensure that the callback is
- // never executed.
- pipeline_->Start(
- mocks_->Create().Pass(),
- base::Bind(&CallbackHelper::OnEnded, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
- base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)));
- message_loop_.RunAllPending();
-
- EXPECT_FALSE(pipeline_->IsInitialized());
-
- // Because our callback will get executed when the test tears down, we'll
- // verify that nothing has been called, then set our expectation for the call
- // made during tear down.
- Mock::VerifyAndClear(&callbacks_);
- EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK));
-}
-
TEST_F(PipelineTest, RequiredFilterMissing) {
// Create a filter collection with missing filter.
scoped_ptr<FilterCollection> collection(mocks_->Create());
@@ -375,7 +360,6 @@ TEST_F(PipelineTest, RequiredFilterMissing) {
base::Bind(&CallbackHelper::OnError, base::Unretained(&callbacks_)),
base::Bind(&CallbackHelper::OnStart, base::Unretained(&callbacks_)));
message_loop_.RunAllPending();
- EXPECT_FALSE(pipeline_->IsInitialized());
}
TEST_F(PipelineTest, URLNotFound) {
@@ -385,7 +369,6 @@ TEST_F(PipelineTest, URLNotFound) {
.WillOnce(RunClosure());
InitializePipeline(PIPELINE_ERROR_URL_NOT_FOUND);
- EXPECT_FALSE(pipeline_->IsInitialized());
}
TEST_F(PipelineTest, NoStreams) {
@@ -395,7 +378,6 @@ TEST_F(PipelineTest, NoStreams) {
.WillOnce(RunClosure());
InitializePipeline(PIPELINE_ERROR_COULD_NOT_RENDER);
- EXPECT_FALSE(pipeline_->IsInitialized());
}
TEST_F(PipelineTest, AudioStream) {
@@ -408,7 +390,6 @@ TEST_F(PipelineTest, AudioStream) {
InitializeAudioRenderer();
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_TRUE(pipeline_->HasAudio());
EXPECT_FALSE(pipeline_->HasVideo());
}
@@ -423,7 +404,6 @@ TEST_F(PipelineTest, VideoStream) {
InitializeVideoRenderer();
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_FALSE(pipeline_->HasAudio());
EXPECT_TRUE(pipeline_->HasVideo());
}
@@ -442,7 +422,6 @@ TEST_F(PipelineTest, AudioVideoStream) {
InitializeVideoRenderer();
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_TRUE(pipeline_->HasAudio());
EXPECT_TRUE(pipeline_->HasVideo());
}
@@ -469,6 +448,177 @@ TEST_F(PipelineTest, Seek) {
DoSeek(expected);
}
+TEST_F(PipelineTest, Stop_DuringStart) {
+ base::Closure stop_cb = base::Bind(
+ &CallbackHelper::OnStop, base::Unretained(&callbacks_));
+
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _))
+ .WillOnce(DoAll(Stop(pipeline_, stop_cb), RunPipelineStatusCB1()));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_))
+ .WillOnce(RunClosure());
+
+ // Start and stop callback should fire.
+ EXPECT_CALL(callbacks_, OnStop());
+ InitializePipeline(PIPELINE_OK);
+}
+
+TEST_F(PipelineTest, Stop_DuringPause) {
+ SetupErrorTest();
+ base::Closure stop_cb = base::Bind(
+ &CallbackHelper::OnStop, base::Unretained(&callbacks_));
+
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
+ .WillOnce(DoAll(Stop(pipeline_, stop_cb), RunClosure()));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // Seek and stop callbacks should fire.
+ EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
+ EXPECT_CALL(callbacks_, OnStop());
+ pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind(
+ &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
+ message_loop_.RunAllPending();
+}
+
+TEST_F(PipelineTest, Stop_DuringFlush) {
+ SetupErrorTest();
+ base::Closure stop_cb = base::Bind(
+ &CallbackHelper::OnStop, base::Unretained(&callbacks_));
+
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Flush(_))
+ .WillOnce(DoAll(Stop(pipeline_, stop_cb), RunClosure()));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // Seek and stop callbacks should fire.
+ EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
+ EXPECT_CALL(callbacks_, OnStop());
+ pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind(
+ &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
+ message_loop_.RunAllPending();
+}
+
+TEST_F(PipelineTest, Stop_DuringSeek) {
+ SetupErrorTest();
+ base::Closure stop_cb = base::Bind(
+ &CallbackHelper::OnStop, base::Unretained(&callbacks_));
+
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->demuxer(), Seek(_, _))
+ .WillOnce(DoAll(Stop(pipeline_, stop_cb),
+ RunPipelineStatusCB1WithStatus(PIPELINE_OK)));
+ EXPECT_CALL(*mocks_->audio_renderer(), Preroll(_, _))
+ .WillOnce(RunPipelineStatusCB1());
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // Seek and stop callbacks should fire.
+ EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
+ EXPECT_CALL(callbacks_, OnStop());
+ pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind(
+ &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
+ message_loop_.RunAllPending();
+}
+
+TEST_F(PipelineTest, Stop_DuringPlayback) {
+ SetupErrorTest();
+
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // Stop callback should fire but nothing else.
+ EXPECT_CALL(callbacks_, OnStop());
+ pipeline_->Stop(base::Bind(
+ &CallbackHelper::OnStop, base::Unretained(&callbacks_)));
+ message_loop_.RunAllPending();
+}
+
+TEST_F(PipelineTest, Error_DuringStart) {
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(_, _))
+ .WillOnce(RunPipelineStatusCB1WithStatus(PIPELINE_ERROR_READ));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_))
+ .WillOnce(RunClosure());
+
+ // Start callback should fire with error but nothing else.
+ InitializePipeline(PIPELINE_ERROR_READ);
+}
+
+TEST_F(PipelineTest, Error_DuringPause) {
+ SetupErrorTest();
+
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
+ .WillOnce(DoAll(SetError(pipeline_, PIPELINE_ERROR_READ), RunClosure()));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // Seek callback should fire with error but nothing else.
+ EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
+ pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind(
+ &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
+ message_loop_.RunAllPending();
+}
+
+TEST_F(PipelineTest, Error_DuringFlush) {
+ SetupErrorTest();
+
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Flush(_))
+ .WillOnce(DoAll(SetError(pipeline_, PIPELINE_ERROR_READ), RunClosure()));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // Seek callback should fire with error but nothing else.
+ EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
+ pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind(
+ &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
+ message_loop_.RunAllPending();
+}
+
+TEST_F(PipelineTest, Error_DuringSeek) {
+ SetupErrorTest();
+
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Flush(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->demuxer(), Seek(_, _))
+ .WillOnce(RunPipelineStatusCB1WithStatus(PIPELINE_ERROR_READ));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // Seek callback fire with error but nothing else.
+ EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
+ pipeline_->Seek(base::TimeDelta::FromSeconds(10), base::Bind(
+ &CallbackHelper::OnSeek, base::Unretained(&callbacks_)));
+ message_loop_.RunAllPending();
+}
+
+TEST_F(PipelineTest, Error_DuringPlayback) {
+ SetupErrorTest();
+
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_)).WillOnce(RunClosure());
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // Error callback should fire but nothing else.
+ EXPECT_CALL(callbacks_, OnError(PIPELINE_ERROR_READ));
+ pipeline_->SetErrorForTesting(PIPELINE_ERROR_READ);
+ message_loop_.RunAllPending();
+}
+
+TEST_F(PipelineTest, Error_DuringStop) {
+ SetupErrorTest();
+
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_))
+ .WillOnce(DoAll(SetError(pipeline_, PIPELINE_ERROR_READ), RunClosure()));
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_)).WillOnce(RunClosure());
+
+ // No error callback should fire.
+ EXPECT_CALL(callbacks_, OnStop());
+ pipeline_->Stop(base::Bind(&CallbackHelper::OnStop,
+ base::Unretained(&callbacks_)));
+ message_loop_.RunAllPending();
+}
+
TEST_F(PipelineTest, SetVolume) {
CreateAudioStream();
MockDemuxerStreamVector streams;
@@ -498,7 +648,6 @@ TEST_F(PipelineTest, Properties) {
InitializeVideoRenderer();
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_EQ(kDuration.ToInternalValue(),
pipeline_->GetMediaDuration().ToInternalValue());
EXPECT_EQ(kTotalBytes, pipeline_->GetTotalBytes());
@@ -516,7 +665,6 @@ TEST_F(PipelineTest, GetBufferedTimeRanges) {
InitializeVideoRenderer();
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_EQ(0u, pipeline_->GetBufferedTimeRanges().size());
@@ -572,7 +720,6 @@ TEST_F(PipelineTest, DisableAudioRenderer) {
InitializeVideoRenderer();
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_TRUE(pipeline_->HasAudio());
EXPECT_TRUE(pipeline_->HasVideo());
@@ -603,7 +750,6 @@ TEST_F(PipelineTest, DisableAudioRendererDuringInit) {
OnAudioRendererDisabled());
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_FALSE(pipeline_->HasAudio());
EXPECT_TRUE(pipeline_->HasVideo());
@@ -715,43 +861,6 @@ TEST_F(PipelineTest, AudioStreamShorterThanVideo) {
pipeline_->OnRendererEnded();
}
-TEST_F(PipelineTest, ErrorDuringSeek) {
scherkus (not reviewing) 2012/07/28 02:26:07 test moved up above
- CreateAudioStream();
- MockDemuxerStreamVector streams;
- streams.push_back(audio_stream());
-
- InitializeDemuxer(&streams, base::TimeDelta::FromSeconds(10));
- InitializeAudioDecoder(audio_stream());
- InitializeAudioRenderer();
- InitializePipeline(PIPELINE_OK);
-
- float playback_rate = 1.0f;
- EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(playback_rate));
- EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(playback_rate));
- pipeline_->SetPlaybackRate(playback_rate);
- message_loop_.RunAllPending();
-
- base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
-
- // Seek() isn't called as the demuxer errors out first.
- EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
- .WillOnce(RunClosure());
- EXPECT_CALL(*mocks_->audio_renderer(), Flush(_))
- .WillOnce(RunClosure());
- EXPECT_CALL(*mocks_->audio_renderer(), Stop(_))
- .WillOnce(RunClosure());
-
- EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _))
- .WillOnce(RunPipelineStatusCB1WithStatus(PIPELINE_ERROR_READ));
- EXPECT_CALL(*mocks_->demuxer(), Stop(_))
- .WillOnce(RunClosure());
-
- pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
- base::Unretained(&callbacks_)));
- EXPECT_CALL(callbacks_, OnSeek(PIPELINE_ERROR_READ));
- message_loop_.RunAllPending();
-}
-
// Invoked function OnError. This asserts that the pipeline does not enqueue
// non-teardown related tasks while tearing down.
static void TestNoCallsAfterError(
@@ -819,7 +928,6 @@ TEST_F(PipelineTest, StartTimeIsZero) {
InitializeVideoRenderer();
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_FALSE(pipeline_->HasAudio());
EXPECT_TRUE(pipeline_->HasVideo());
@@ -842,7 +950,6 @@ TEST_F(PipelineTest, StartTimeIsNonZero) {
InitializeVideoRenderer();
InitializePipeline(PIPELINE_OK);
- EXPECT_TRUE(pipeline_->IsInitialized());
EXPECT_FALSE(pipeline_->HasAudio());
EXPECT_TRUE(pipeline_->HasVideo());
@@ -886,6 +993,7 @@ TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _))
.WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run),
RunPipelineStatusCB1()));
+ EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(playback_rate));
EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
.WillOnce(RunClosure());
@@ -893,6 +1001,8 @@ TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
.WillOnce(RunClosure());
EXPECT_CALL(*mocks_->audio_renderer(), Preroll(seek_time, _))
.WillOnce(RunPipelineStatusCB1());
+ EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(playback_rate));
+ EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(_));
EXPECT_CALL(*mocks_->audio_renderer(), Play(_))
.WillOnce(RunClosure());

Powered by Google App Engine
This is Rietveld 408576698