Index: media/filters/audio_renderer_impl_unittest.cc |
diff --git a/media/filters/audio_renderer_impl_unittest.cc b/media/filters/audio_renderer_impl_unittest.cc |
index 1fa27230f021b6b338fe9b7b8897db245f1852de..92391f83859a5f21a936541c176a4544b5d07654 100644 |
--- a/media/filters/audio_renderer_impl_unittest.cc |
+++ b/media/filters/audio_renderer_impl_unittest.cc |
@@ -117,7 +117,7 @@ |
} |
MOCK_METHOD1(OnStatistics, void(const PipelineStatistics&)); |
- MOCK_METHOD1(OnBufferingStateChange, void(BufferingState)); |
+ MOCK_METHOD0(OnUnderflow, void()); |
MOCK_METHOD1(OnError, void(PipelineStatus)); |
void OnAudioTimeCallback(TimeDelta current_time, TimeDelta max_time) { |
@@ -131,9 +131,9 @@ |
pipeline_status_cb, |
base::Bind(&AudioRendererImplTest::OnStatistics, |
base::Unretained(this)), |
+ base::Bind(&AudioRendererImplTest::OnUnderflow, |
+ base::Unretained(this)), |
base::Bind(&AudioRendererImplTest::OnAudioTimeCallback, |
- base::Unretained(this)), |
- base::Bind(&AudioRendererImplTest::OnBufferingStateChange, |
base::Unretained(this)), |
ended_event_.GetClosure(), |
base::Bind(&AudioRendererImplTest::OnError, |
@@ -200,7 +200,6 @@ |
} |
void Flush() { |
- SCOPED_TRACE("Flush()"); |
WaitableMessageLoopEvent flush_event; |
renderer_->Flush(flush_event.GetClosure()); |
flush_event.RunAndWait(); |
@@ -219,10 +218,11 @@ |
next_timestamp_->SetBaseTimestamp(timestamp); |
// Fill entire buffer to complete prerolling. |
- renderer_->StartPlayingFrom(timestamp); |
+ WaitableMessageLoopEvent event; |
+ renderer_->Preroll(timestamp, event.GetPipelineStatusCB()); |
WaitForPendingRead(); |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
DeliverRemainingAudio(); |
+ event.RunAndWaitForStatus(PIPELINE_OK); |
// We should have no reads. |
EXPECT_TRUE(decode_cb_.is_null()); |
@@ -360,6 +360,10 @@ |
return buffer_capacity() - frames_buffered(); |
} |
+ void CallResumeAfterUnderflow() { |
+ renderer_->ResumeAfterUnderflow(); |
+ } |
+ |
TimeDelta CalculatePlayTime(int frames_filled) { |
return TimeDelta::FromMicroseconds( |
frames_filled * Time::kMicrosecondsPerSecond / |
@@ -373,7 +377,6 @@ |
renderer_->SetPlaybackRate(playback_rate); |
// Drain internal buffer, we should have a pending read. |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
int total_frames = frames_buffered(); |
int frames_filled = ConsumeAllBufferedData(); |
WaitForPendingRead(); |
@@ -391,7 +394,6 @@ |
// Fulfill the read with an end-of-stream packet. We shouldn't report ended |
// nor have a read until we drain the internal buffer. |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
DeliverEndOfStream(); |
// Advance time half way without an ended expectation. |
@@ -537,28 +539,33 @@ |
TEST_F(AudioRendererImplTest, Underflow) { |
Initialize(); |
Preroll(); |
+ |
+ int initial_capacity = buffer_capacity(); |
+ |
StartRendering(); |
// Drain internal buffer, we should have a pending read. |
EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); |
WaitForPendingRead(); |
- // Verify the next FillBuffer() call triggers a buffering state change |
- // update. |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
+ // Verify the next FillBuffer() call triggers the underflow callback |
+ // since the decoder hasn't delivered any data after it was drained. |
+ EXPECT_CALL(*this, OnUnderflow()); |
EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
- // Verify we're still not getting audio data. |
+ renderer_->ResumeAfterUnderflow(); |
+ |
+ // Verify after resuming that we're still not getting data. |
bool muted = false; |
EXPECT_EQ(0, frames_buffered()); |
EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); |
EXPECT_TRUE(muted); |
- // Deliver enough data to have enough for buffering. |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
+ // Verify that the buffer capacity increased as a result of the underflow. |
+ EXPECT_GT(buffer_capacity(), initial_capacity); |
+ |
+ // Deliver data, we should get non-muted audio. |
DeliverRemainingAudio(); |
- |
- // Verify we're getting audio data. |
EXPECT_TRUE(ConsumeBufferedData(kDataSize, &muted)); |
EXPECT_FALSE(muted); |
} |
@@ -566,6 +573,9 @@ |
TEST_F(AudioRendererImplTest, Underflow_CapacityResetsAfterFlush) { |
Initialize(); |
Preroll(); |
+ |
+ int initial_capacity = buffer_capacity(); |
+ |
StartRendering(); |
// Drain internal buffer, we should have a pending read. |
@@ -574,11 +584,13 @@ |
// Verify the next FillBuffer() call triggers the underflow callback |
// since the decoder hasn't delivered any data after it was drained. |
- int initial_capacity = buffer_capacity(); |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
+ EXPECT_CALL(*this, OnUnderflow()); |
EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
- // Verify that the buffer capacity increased as a result of underflowing. |
+ // Verify that the buffer capacity increased as a result of resuming after |
+ // underflow. |
+ EXPECT_EQ(buffer_capacity(), initial_capacity); |
+ renderer_->ResumeAfterUnderflow(); |
EXPECT_GT(buffer_capacity(), initial_capacity); |
// Verify that the buffer capacity is restored to the |initial_capacity|. |
@@ -587,33 +599,177 @@ |
EXPECT_EQ(buffer_capacity(), initial_capacity); |
} |
-TEST_F(AudioRendererImplTest, Underflow_Flush) { |
- Initialize(); |
- Preroll(); |
- StartRendering(); |
- |
- // Force underflow. |
+TEST_F(AudioRendererImplTest, Underflow_FlushWhileUnderflowed) { |
+ Initialize(); |
+ Preroll(); |
+ StartRendering(); |
+ |
+ // Drain internal buffer, we should have a pending read. |
EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); |
WaitForPendingRead(); |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
+ |
+ // Verify the next FillBuffer() call triggers the underflow callback |
+ // since the decoder hasn't delivered any data after it was drained. |
+ EXPECT_CALL(*this, OnUnderflow()); |
EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
- WaitForPendingRead(); |
- StopRendering(); |
- |
- // We shouldn't expect another buffering state change whenn flushing. |
+ |
+ // Verify that we can still Flush() before entering the rebuffering state. |
AbortPendingRead(); |
Flush(); |
} |
+TEST_F(AudioRendererImplTest, Underflow_EndOfStream) { |
+ Initialize(); |
+ Preroll(); |
+ StartRendering(); |
+ |
+ // Figure out how long until the ended event should fire. Since |
+ // ConsumeBufferedData() doesn't provide audio delay information, the time |
+ // until the ended event fires is equivalent to the longest buffered section, |
+ // which is the initial frames_buffered() read. |
+ TimeDelta time_until_ended = CalculatePlayTime(frames_buffered()); |
+ |
+ // Drain internal buffer, we should have a pending read. |
+ EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); |
+ WaitForPendingRead(); |
+ |
+ // Verify the next FillBuffer() call triggers the underflow callback |
+ // since the decoder hasn't delivered any data after it was drained. |
+ EXPECT_CALL(*this, OnUnderflow()); |
+ EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
+ |
+ // Deliver a little bit of data. |
+ SatisfyPendingRead(kDataSize); |
+ WaitForPendingRead(); |
+ |
+ // Verify we're getting muted audio during underflow. Note: Since resampling |
+ // is active, the number of frames_buffered() won't always match kDataSize. |
+ bool muted = false; |
+ const int kInitialFramesBuffered = 1114; |
+ EXPECT_EQ(kInitialFramesBuffered, frames_buffered()); |
+ EXPECT_FALSE(ConsumeBufferedData(kInitialFramesBuffered, &muted)); |
+ EXPECT_TRUE(muted); |
+ |
+ // Now deliver end of stream, we should get our little bit of data back. |
+ DeliverEndOfStream(); |
+ const int kNextFramesBuffered = 1408; |
+ EXPECT_EQ(kNextFramesBuffered, frames_buffered()); |
+ EXPECT_TRUE(ConsumeBufferedData(kNextFramesBuffered, &muted)); |
+ EXPECT_FALSE(muted); |
+ |
+ // Attempt to read to make sure we're truly at the end of stream. |
+ AdvanceTime(time_until_ended); |
+ EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); |
+ EXPECT_TRUE(muted); |
+ WaitForEnded(); |
+} |
+ |
+TEST_F(AudioRendererImplTest, Underflow_ResumeFromCallback) { |
+ Initialize(); |
+ Preroll(); |
+ StartRendering(); |
+ |
+ // Drain internal buffer, we should have a pending read. |
+ EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); |
+ WaitForPendingRead(); |
+ |
+ // Verify the next FillBuffer() call triggers the underflow callback |
+ // since the decoder hasn't delivered any data after it was drained. |
+ EXPECT_CALL(*this, OnUnderflow()) |
+ .WillOnce(Invoke(this, &AudioRendererImplTest::CallResumeAfterUnderflow)); |
+ EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
+ |
+ // Verify after resuming that we're still not getting data. |
+ bool muted = false; |
+ EXPECT_EQ(0, frames_buffered()); |
+ EXPECT_FALSE(ConsumeBufferedData(kDataSize, &muted)); |
+ EXPECT_TRUE(muted); |
+ |
+ // Deliver data, we should get non-muted audio. |
+ DeliverRemainingAudio(); |
+ EXPECT_TRUE(ConsumeBufferedData(kDataSize, &muted)); |
+ EXPECT_FALSE(muted); |
+} |
+ |
+TEST_F(AudioRendererImplTest, Underflow_SetPlaybackRate) { |
+ Initialize(); |
+ Preroll(); |
+ StartRendering(); |
+ |
+ // Drain internal buffer, we should have a pending read. |
+ EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); |
+ WaitForPendingRead(); |
+ |
+ EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); |
+ |
+ // Verify the next FillBuffer() call triggers the underflow callback |
+ // since the decoder hasn't delivered any data after it was drained. |
+ EXPECT_CALL(*this, OnUnderflow()) |
+ .WillOnce(Invoke(this, &AudioRendererImplTest::CallResumeAfterUnderflow)); |
+ EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
+ EXPECT_EQ(0, frames_buffered()); |
+ |
+ EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); |
+ |
+ // Simulate playback being paused. |
+ renderer_->SetPlaybackRate(0); |
+ |
+ EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state()); |
+ |
+ // Deliver data to resolve the underflow. |
+ DeliverRemainingAudio(); |
+ |
+ EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state()); |
+ |
+ // Simulate playback being resumed. |
+ renderer_->SetPlaybackRate(1); |
+ |
+ EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); |
+} |
+ |
+TEST_F(AudioRendererImplTest, Underflow_PausePlay) { |
+ Initialize(); |
+ Preroll(); |
+ StartRendering(); |
+ |
+ // Drain internal buffer, we should have a pending read. |
+ EXPECT_TRUE(ConsumeBufferedData(frames_buffered(), NULL)); |
+ WaitForPendingRead(); |
+ |
+ EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); |
+ |
+ // Verify the next FillBuffer() call triggers the underflow callback |
+ // since the decoder hasn't delivered any data after it was drained. |
+ EXPECT_CALL(*this, OnUnderflow()) |
+ .WillOnce(Invoke(this, &AudioRendererImplTest::CallResumeAfterUnderflow)); |
+ EXPECT_FALSE(ConsumeBufferedData(kDataSize, NULL)); |
+ EXPECT_EQ(0, frames_buffered()); |
+ |
+ EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); |
+ |
+ // Simulate playback being paused, and then played again. |
+ renderer_->SetPlaybackRate(0.0); |
+ renderer_->SetPlaybackRate(1.0); |
+ |
+ // Deliver data to resolve the underflow. |
+ DeliverRemainingAudio(); |
+ |
+ // We should have resumed playing now. |
+ EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state()); |
+} |
+ |
TEST_F(AudioRendererImplTest, AbortPendingRead_Preroll) { |
Initialize(); |
// Start prerolling and wait for a read. |
- renderer_->StartPlayingFrom(TimeDelta()); |
+ WaitableMessageLoopEvent event; |
+ renderer_->Preroll(TimeDelta(), event.GetPipelineStatusCB()); |
WaitForPendingRead(); |
// Simulate the decoder aborting the pending read. |
AbortPendingRead(); |
+ event.RunAndWaitForStatus(PIPELINE_OK); |
+ |
Flush(); |
// Preroll again to a different timestamp and verify it completed normally. |
@@ -640,7 +796,6 @@ |
// Simulate the decoder aborting the pending read. |
AbortPendingRead(); |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
flush_event.RunAndWait(); |
EXPECT_FALSE(IsReadPending()); |
@@ -668,7 +823,7 @@ |
renderer_->Flush(flush_event.GetClosure()); |
SatisfyPendingRead(kDataSize); |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING)); |
+ |
flush_event.RunAndWait(); |
EXPECT_FALSE(IsReadPending()); |
@@ -787,10 +942,11 @@ |
Initialize(); |
{ |
SCOPED_TRACE("Preroll()"); |
- renderer_->StartPlayingFrom(base::TimeDelta()); |
+ WaitableMessageLoopEvent event; |
+ renderer_->Preroll(base::TimeDelta(), event.GetPipelineStatusCB()); |
WaitForPendingRead(); |
- EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH)); |
DeliverEndOfStream(); |
+ event.RunAndWaitForStatus(PIPELINE_OK); |
} |
StartRendering(); |