summaryrefslogtreecommitdiffstats
path: root/media/base/pipeline_unittest.cc
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-26 10:29:02 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-26 10:29:02 +0000
commit92b6b424f65f5bbeded0995ea89f2e0f5bc72919 (patch)
treec4d4049e9c63cb36b41032ab2329c30013ab879c /media/base/pipeline_unittest.cc
parent8c8b3db8212e7323b28d7aca0a08de61264ae5b7 (diff)
downloadchromium_src-92b6b424f65f5bbeded0995ea89f2e0f5bc72919.zip
chromium_src-92b6b424f65f5bbeded0995ea89f2e0f5bc72919.tar.gz
chromium_src-92b6b424f65f5bbeded0995ea89f2e0f5bc72919.tar.bz2
Update AudioRenderer API to fire changes in BufferingState (round 2).
As a result, Pipeline now handles prerolling and underflow/rebuffering by listening for BUFFERING_HAVE_NOTHING/ENOUGH callbacks. Preroll() is renamed StartPlayingFrom() and no longer accepts a completion callback. In this new model, AudioRenderers immediately enter and remain in the "playing" state and fire buffering state callbacks to let Pipeline know when to start/stop the clock. BUG=144683 Review URL: https://codereview.chromium.org/354673007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@279977 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/base/pipeline_unittest.cc')
-rw-r--r--media/base/pipeline_unittest.cc107
1 files changed, 76 insertions, 31 deletions
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index a877143..d9f2f1f 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -51,6 +51,10 @@ ACTION_P2(SetError, pipeline, status) {
pipeline->SetErrorForTesting(status);
}
+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 {
@@ -180,7 +184,8 @@ class PipelineTest : public ::testing::Test {
// Sets up expectations to allow the audio renderer to initialize.
void InitializeAudioRenderer(DemuxerStream* stream) {
EXPECT_CALL(*audio_renderer_, Initialize(stream, _, _, _, _, _, _))
- .WillOnce(DoAll(SaveArg<4>(&audio_time_cb_),
+ .WillOnce(DoAll(SaveArg<3>(&audio_time_cb_),
+ SaveArg<4>(&audio_buffering_state_cb_),
RunCallback<1>(PIPELINE_OK)));
}
@@ -202,10 +207,9 @@ class PipelineTest : public ::testing::Test {
if (audio_stream_) {
EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f));
EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
-
- // Startup sequence.
- EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _))
- .WillOnce(RunCallback<1>(PIPELINE_OK));
+ EXPECT_CALL(*audio_renderer_, StartPlayingFrom(base::TimeDelta()))
+ .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_ENOUGH));
EXPECT_CALL(*audio_renderer_, StartRendering());
}
EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
@@ -251,17 +255,21 @@ class PipelineTest : public ::testing::Test {
return text_stream_.get();
}
- void ExpectSeek(const base::TimeDelta& seek_time) {
+ 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_) {
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ if (!underflowed)
+ EXPECT_CALL(*audio_renderer_, StopRendering());
EXPECT_CALL(*audio_renderer_, Flush(_))
- .WillOnce(RunClosure<0>());
- EXPECT_CALL(*audio_renderer_, Preroll(seek_time, _))
- .WillOnce(RunCallback<1>(PIPELINE_OK));
+ .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_NOTHING),
+ RunClosure<0>()));
+ EXPECT_CALL(*audio_renderer_, StartPlayingFrom(seek_time))
+ .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_ENOUGH));
EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_));
EXPECT_CALL(*audio_renderer_, SetVolume(_));
EXPECT_CALL(*audio_renderer_, StartRendering());
@@ -329,6 +337,7 @@ class PipelineTest : public ::testing::Test {
scoped_ptr<StrictMock<MockDemuxerStream> > video_stream_;
scoped_ptr<FakeTextTrackStream> text_stream_;
AudioRenderer::TimeCB audio_time_cb_;
+ AudioRenderer::BufferingStateCB audio_buffering_state_cb_;
VideoDecoderConfig video_decoder_config_;
PipelineMetadata metadata_;
@@ -506,7 +515,7 @@ TEST_F(PipelineTest, Seek) {
// Every filter should receive a call to Seek().
base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
- ExpectSeek(expected);
+ ExpectSeek(expected, false);
DoSeek(expected);
}
@@ -564,7 +573,7 @@ TEST_F(PipelineTest, GetBufferedTimeRanges) {
EXPECT_EQ(kDuration / 8, pipeline_->GetBufferedTimeRanges().end(0));
base::TimeDelta kSeekTime = kDuration / 2;
- ExpectSeek(kSeekTime);
+ ExpectSeek(kSeekTime, false);
DoSeek(kSeekTime);
EXPECT_FALSE(pipeline_->DidLoadingProgress());
@@ -666,7 +675,9 @@ TEST_F(PipelineTest, ErrorDuringSeek) {
// Preroll() isn't called as the demuxer errors out first.
EXPECT_CALL(*audio_renderer_, StopRendering());
EXPECT_CALL(*audio_renderer_, Flush(_))
- .WillOnce(RunClosure<0>());
+ .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_NOTHING),
+ RunClosure<0>()));
EXPECT_CALL(*audio_renderer_, Stop(_))
.WillOnce(RunClosure<0>());
@@ -720,7 +731,9 @@ TEST_F(PipelineTest, NoMessageDuringTearDownFromError) {
// Seek() isn't called as the demuxer errors out first.
EXPECT_CALL(*audio_renderer_, StopRendering());
EXPECT_CALL(*audio_renderer_, Flush(_))
- .WillOnce(RunClosure<0>());
+ .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_NOTHING),
+ RunClosure<0>()));
EXPECT_CALL(*audio_renderer_, Stop(_))
.WillOnce(RunClosure<0>());
@@ -773,9 +786,12 @@ TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
EXPECT_CALL(*audio_renderer_, StopRendering());
EXPECT_CALL(*audio_renderer_, Flush(_))
- .WillOnce(RunClosure<0>());
- EXPECT_CALL(*audio_renderer_, Preroll(seek_time, _))
- .WillOnce(RunCallback<1>(PIPELINE_OK));
+ .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_NOTHING),
+ RunClosure<0>()));
+ EXPECT_CALL(*audio_renderer_, StartPlayingFrom(seek_time))
+ .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_ENOUGH));
EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_));
EXPECT_CALL(*audio_renderer_, SetVolume(_));
EXPECT_CALL(*audio_renderer_, StartRendering());
@@ -813,6 +829,28 @@ TEST_F(PipelineTest, DeleteAfterStop) {
message_loop_.RunUntilIdle();
}
+TEST_F(PipelineTest, Underflow) {
+ CreateAudioStream();
+ CreateVideoStream();
+ MockDemuxerStreamVector streams;
+ streams.push_back(audio_stream());
+ streams.push_back(video_stream());
+
+ InitializeDemuxer(&streams);
+ InitializeAudioRenderer(audio_stream());
+ InitializeVideoRenderer(video_stream());
+ InitializePipeline(PIPELINE_OK);
+
+ // Simulate underflow.
+ EXPECT_CALL(*audio_renderer_, StopRendering());
+ audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING);
+
+ // Seek while underflowed. We shouldn't call StopRendering() again.
+ base::TimeDelta expected = base::TimeDelta::FromSeconds(5);
+ ExpectSeek(expected, true);
+ DoSeek(expected);
+}
+
class PipelineTeardownTest : public PipelineTest {
public:
enum TeardownState {
@@ -925,7 +963,8 @@ class PipelineTeardownTest : public PipelineTest {
}
EXPECT_CALL(*audio_renderer_, Initialize(_, _, _, _, _, _, _))
- .WillOnce(RunCallback<1>(PIPELINE_OK));
+ .WillOnce(DoAll(SaveArg<4>(&audio_buffering_state_cb_),
+ RunCallback<1>(PIPELINE_OK)));
if (state == kInitVideoRenderer) {
if (stop_or_error == kStop) {
@@ -951,8 +990,9 @@ class PipelineTeardownTest : public PipelineTest {
EXPECT_CALL(callbacks_, OnMetadata(_));
// If we get here it's a successful initialization.
- EXPECT_CALL(*audio_renderer_, Preroll(base::TimeDelta(), _))
- .WillOnce(RunCallback<1>(PIPELINE_OK));
+ EXPECT_CALL(*audio_renderer_, StartPlayingFrom(base::TimeDelta()))
+ .WillOnce(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_ENOUGH));
EXPECT_CALL(*video_renderer_, Preroll(base::TimeDelta(), _))
.WillOnce(RunCallback<1>(PIPELINE_OK));
@@ -999,17 +1039,26 @@ class PipelineTeardownTest : public PipelineTest {
if (state == kFlushing) {
if (stop_or_error == kStop) {
EXPECT_CALL(*audio_renderer_, Flush(_))
- .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb), RunClosure<0>()));
+ .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
+ SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_NOTHING),
+ RunClosure<0>()));
} else {
status = PIPELINE_ERROR_READ;
EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(
- DoAll(SetError(pipeline_.get(), status), RunClosure<0>()));
+ DoAll(SetError(pipeline_.get(), status),
+ SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_NOTHING),
+ RunClosure<0>()));
}
return status;
}
- EXPECT_CALL(*audio_renderer_, Flush(_)).WillOnce(RunClosure<0>());
+ EXPECT_CALL(*audio_renderer_, Flush(_))
+ .WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
+ BUFFERING_HAVE_NOTHING),
+ RunClosure<0>()));
EXPECT_CALL(*video_renderer_, Flush(_)).WillOnce(RunClosure<0>());
if (state == kSeeking) {
@@ -1031,22 +1080,18 @@ class PipelineTeardownTest : public PipelineTest {
if (state == kPrerolling) {
if (stop_or_error == kStop) {
- EXPECT_CALL(*audio_renderer_, Preroll(_, _))
- .WillOnce(DoAll(Stop(pipeline_.get(), stop_cb),
- RunCallback<1>(PIPELINE_OK)));
+ EXPECT_CALL(*video_renderer_, Preroll(_, _))
+ .WillOnce(Stop(pipeline_.get(), stop_cb));
} else {
status = PIPELINE_ERROR_READ;
- EXPECT_CALL(*audio_renderer_, Preroll(_, _))
+ EXPECT_CALL(*video_renderer_, Preroll(_, _))
.WillOnce(RunCallback<1>(status));
}
return status;
}
- EXPECT_CALL(*audio_renderer_, Preroll(_, _))
- .WillOnce(RunCallback<1>(PIPELINE_OK));
- EXPECT_CALL(*video_renderer_, Preroll(_, _))
- .WillOnce(RunCallback<1>(PIPELINE_OK));
+ EXPECT_CALL(*audio_renderer_, StartPlayingFrom(_));
// Playback rate and volume are updated prior to starting.
EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f));