Index: media/filters/audio_renderer_base_unittest.cc |
diff --git a/media/filters/audio_renderer_base_unittest.cc b/media/filters/audio_renderer_base_unittest.cc |
index 76b1915c5fd4233e0fd50c26197c6e2535b0f76b..5682d37508e103384d7d542a0b3dda9a9f2392d3 100644 |
--- a/media/filters/audio_renderer_base_unittest.cc |
+++ b/media/filters/audio_renderer_base_unittest.cc |
@@ -42,6 +42,8 @@ class MockAudioRendererBase : public AudioRendererBase { |
private: |
FRIEND_TEST(AudioRendererBaseTest, OneCompleteReadCycle); |
FRIEND_TEST(AudioRendererBaseTest, Underflow); |
+ FRIEND_TEST(AudioRendererBaseTest, Underflow_EndOfStream); |
+ friend class AudioRendererBaseTest; |
DISALLOW_COPY_AND_ASSIGN(MockAudioRendererBase); |
}; |
@@ -88,18 +90,49 @@ class AudioRendererBaseTest : public ::testing::Test { |
base::Unretained(this)); |
} |
+ scoped_refptr<DataBuffer> CreateBuffer(int data_size, uint8 value) { |
+ scoped_refptr<DataBuffer> buffer(new DataBuffer(data_size)); |
+ buffer->SetDataSize(data_size); |
+ memset(buffer->GetWritableData(), value, buffer->GetDataSize()); |
+ return buffer; |
+ } |
+ |
void WriteUntilNoPendingReads(int data_size, uint8 value, |
uint32* bytes_buffered) { |
while (pending_reads_ > 0) { |
- scoped_refptr<DataBuffer> buffer(new DataBuffer(data_size)); |
- buffer->SetDataSize(data_size); |
- memset(buffer->GetWritableData(), value, buffer->GetDataSize()); |
--pending_reads_; |
*bytes_buffered += data_size; |
- decoder_->ConsumeAudioSamplesForTest(buffer); |
+ decoder_->ConsumeAudioSamplesForTest(CreateBuffer(data_size, value)); |
+ } |
+ } |
+ |
+ void ConsumeBufferedData(uint32 data_size, uint8 expected_value, |
+ uint32* bytes_buffered) { |
+ DCHECK(bytes_buffered); |
+ DCHECK_GT(*bytes_buffered, 0u); |
+ |
+ base::TimeDelta playback_delay(base::TimeDelta::FromSeconds(1)); |
+ scoped_array<uint8> buffer(new uint8[data_size]); |
+ while (*bytes_buffered > 0) { |
+ EXPECT_EQ(data_size, renderer_->FillBuffer(buffer.get(), data_size, |
+ playback_delay, false)); |
+ EXPECT_EQ(expected_value, buffer[0]); |
+ *bytes_buffered -= data_size; |
} |
} |
+ void ExpectUnderflow(uint32 data_size, int checkpoint_value) { |
+ scoped_array<uint8> buffer(new uint8[data_size]); |
+ base::TimeDelta playback_delay(base::TimeDelta::FromSeconds(1)); |
+ |
+ EXPECT_CALL(*this, OnUnderflow()); |
+ EXPECT_CALL(*renderer_, CheckPoint(checkpoint_value)); |
+ EXPECT_EQ(0u, renderer_->FillBuffer(buffer.get(), data_size, playback_delay, |
+ false)); |
+ renderer_->CheckPoint(checkpoint_value); |
+ } |
+ |
+ |
protected: |
static const size_t kMaxQueueSize; |
@@ -283,41 +316,25 @@ TEST_F(AudioRendererBaseTest, Underflow) { |
EXPECT_EQ(1.0f, renderer_->GetPlaybackRate()); |
// Consume all of the data passed into the renderer. |
- uint8 buffer[kDataSize]; |
- while (bytes_buffered > 0) { |
- EXPECT_EQ(kDataSize, |
- renderer_->FillBuffer(buffer, kDataSize, playback_delay, false)); |
- EXPECT_EQ(1, buffer[0]); |
- bytes_buffered -= kDataSize; |
- } |
+ ConsumeBufferedData(kDataSize, 1, &bytes_buffered); |
// Make sure there are read requests pending. |
EXPECT_GT(pending_reads_, 0u); |
// Verify the next FillBuffer() call triggers calls the underflow callback |
// since the queue is empty. |
- EXPECT_CALL(*this, OnUnderflow()); |
- EXPECT_CALL(*renderer_, CheckPoint(1)); |
- EXPECT_EQ(0u, renderer_->FillBuffer(buffer, kDataSize, playback_delay, |
- false)); |
- renderer_->CheckPoint(1); |
+ ExpectUnderflow(kDataSize, 1); |
// Verify that zeroed out buffers are being returned during the underflow. |
- for (int i = 0; i < 5; ++i) { |
- EXPECT_EQ(kDataSize, |
- renderer_->FillBuffer(buffer, kDataSize, playback_delay, false)); |
- EXPECT_EQ(0, buffer[0]); |
- } |
+ uint32 zeros_to_read = 5 * kDataSize; |
+ ConsumeBufferedData(kDataSize, 0, &zeros_to_read); |
renderer_->ResumeAfterUnderflow(false); |
// Verify we are still getting zeroed out buffers since no new data has been |
// pushed to the renderer. |
- for (int i = 0; i < 5; ++i) { |
- EXPECT_EQ(kDataSize, |
- renderer_->FillBuffer(buffer, kDataSize, playback_delay, false)); |
- EXPECT_EQ(0, buffer[0]); |
- } |
+ zeros_to_read = 5 * kDataSize; |
+ ConsumeBufferedData(kDataSize, 0, &zeros_to_read); |
// Satisfy all pending read requests. |
WriteUntilNoPendingReads(kDataSize, 2, &bytes_buffered); |
@@ -325,12 +342,73 @@ TEST_F(AudioRendererBaseTest, Underflow) { |
EXPECT_GE(bytes_buffered, bytes_for_preroll); |
// Verify that we are now getting the new data. |
- while (bytes_buffered > 0) { |
- EXPECT_EQ(kDataSize, |
- renderer_->FillBuffer(buffer, kDataSize, playback_delay, false)); |
- EXPECT_EQ(2, buffer[0]); |
- bytes_buffered -= kDataSize; |
+ ConsumeBufferedData(kDataSize, 2, &bytes_buffered); |
+} |
+ |
+ |
+TEST_F(AudioRendererBaseTest, Underflow_EndOfStream) { |
+ InSequence s; |
+ |
+ base::TimeDelta playback_delay(base::TimeDelta::FromSeconds(1)); |
+ |
+ // Then our subclass will be asked to initialize. |
+ EXPECT_CALL(*renderer_, OnInitialize(_, _, _)) |
+ .WillOnce(Return(true)); |
+ |
+ // Initialize, we shouldn't have any reads. |
+ renderer_->Initialize(decoder_, NewExpectedClosure(), NewUnderflowClosure()); |
+ EXPECT_EQ(0u, pending_reads_); |
+ |
+ // Now seek to trigger prerolling, verifying the callback hasn't been |
+ // executed yet. |
+ EXPECT_CALL(*renderer_, CheckPoint(0)); |
+ renderer_->Seek(base::TimeDelta(), NewExpectedStatusCB(PIPELINE_OK)); |
+ EXPECT_EQ(kMaxQueueSize, pending_reads_); |
+ renderer_->CheckPoint(0); |
+ |
+ // Now satisfy the read requests. Our callback should be executed after |
+ // exiting this loop. |
+ const uint32 kDataSize = 1024; |
+ uint32 bytes_buffered = 0; |
+ |
+ WriteUntilNoPendingReads(kDataSize, 1, &bytes_buffered); |
+ |
+ // Then set the renderer to play state. |
+ renderer_->Play(NewExpectedClosure()); |
+ renderer_->SetPlaybackRate(1.0f); |
+ EXPECT_EQ(1.0f, renderer_->GetPlaybackRate()); |
+ |
+ // Consume all of the data passed into the renderer. |
+ ConsumeBufferedData(kDataSize, 1, &bytes_buffered); |
+ |
+ // Make sure there are read requests pending. |
+ EXPECT_GT(pending_reads_, 0u); |
+ |
+ // Verify the next FillBuffer() call triggers calls the underflow callback |
+ // since the queue is empty. |
+ ExpectUnderflow(kDataSize, 1); |
+ |
+ DCHECK_GE(pending_reads_, 2u); |
+ |
+ // Write a buffer. |
+ bytes_buffered += kDataSize; |
+ --pending_reads_; |
+ decoder_->ConsumeAudioSamplesForTest(CreateBuffer(kDataSize, 3)); |
+ |
+ // Verify we are getting zeroed out buffers since we haven't pushed enough |
+ // data to satisfy preroll. |
+ uint32 zeros_to_read = 5 * kDataSize; |
+ ConsumeBufferedData(kDataSize, 0, &zeros_to_read); |
+ |
+ // Send end of stream buffers for all pending reads. |
+ while (pending_reads_ > 0) { |
+ scoped_refptr<DataBuffer> buffer(new DataBuffer(0)); |
+ --pending_reads_; |
+ decoder_->ConsumeAudioSamplesForTest(buffer); |
} |
+ |
+ // Verify that we are now getting the new data. |
+ ConsumeBufferedData(kDataSize, 3, &bytes_buffered); |
} |
} // namespace media |