Index: media/audio/linux/alsa_output_unittest.cc |
diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc |
index 26237cabea2b4e7422a2be9254112d3a02bad6d5..ce4c1e66af5f24755f2a945dc7369a2358e18504 100644 |
--- a/media/audio/linux/alsa_output_unittest.cc |
+++ b/media/audio/linux/alsa_output_unittest.cc |
@@ -8,6 +8,8 @@ |
#include "media/audio/linux/alsa_output.h" |
#include "media/audio/linux/alsa_wrapper.h" |
#include "media/audio/linux/audio_manager_linux.h" |
+#include "media/base/data_buffer.h" |
+#include "media/base/seekable_buffer.h" |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -46,6 +48,8 @@ class MockAlsaWrapper : public AlsaWrapper { |
snd_pcm_access_t access, unsigned int channels, |
unsigned int rate, int soft_resample, |
unsigned int latency)); |
+ MOCK_METHOD3(PcmGetParams, int(snd_pcm_t* handle, snd_pcm_uframes_t* buffer_size, |
scherkus (not reviewing)
2010/05/14 21:28:50
>80 chars
|
+ snd_pcm_uframes_t* period_size)); |
MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); |
MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); |
MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); |
@@ -76,10 +80,8 @@ class MockAudioManagerLinux : public AudioManagerLinux { |
class AlsaPcmOutputStreamTest : public testing::Test { |
protected: |
- AlsaPcmOutputStreamTest() |
- : packet_(kTestPacketSize + 1) { |
+ AlsaPcmOutputStreamTest() { |
test_stream_ = CreateStreamWithChannels(kTestChannels); |
- packet_.size = kTestPacketSize; |
} |
virtual ~AlsaPcmOutputStreamTest() { |
@@ -107,6 +109,15 @@ class AlsaPcmOutputStreamTest : public testing::Test { |
return strdup("Output"); |
} |
+ // Helper function to initialize |test_stream_->buffer_|. Must be called |
+ // in all tests that use buffer_ without opening the stream. |
+ void InitBuffer() { |
+ packet_ = new media::DataBuffer(kTestPacketSize); |
+ packet_->SetDataSize(kTestPacketSize); |
+ test_stream_->buffer_.reset(new media::SeekableBuffer(0, kTestPacketSize)); |
+ test_stream_->buffer_->Append(packet_.get()); |
+ } |
+ |
static const int kTestChannels; |
static const int kTestSampleRate; |
static const int kTestBitsPerSample; |
@@ -132,7 +143,7 @@ class AlsaPcmOutputStreamTest : public testing::Test { |
StrictMock<MockAudioManagerLinux> mock_manager_; |
MessageLoop message_loop_; |
scoped_refptr<AlsaPcmOutputStream> test_stream_; |
- AlsaPcmOutputStream::Packet packet_; |
+ scoped_refptr<media::DataBuffer> packet_; |
private: |
DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStreamTest); |
@@ -224,6 +235,10 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { |
PcmSetParams(_, _, _, _, _, _, |
AlsaPcmOutputStream::kMinLatencyMicros)) |
.WillOnce(Return(0)); |
+ EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) |
+ .WillOnce(DoAll(SetArgumentPointee<1>(kTestPacketSize), |
+ SetArgumentPointee<2>(kTestPacketSize / 2), |
+ Return(0))); |
ASSERT_TRUE(test_stream_->Open(kMinLatencyPacketSize)); |
message_loop_.RunAllPending(); |
@@ -255,6 +270,10 @@ TEST_F(AlsaPcmOutputStreamTest, LatencyFloor) { |
EXPECT_CALL(mock_alsa_wrapper_, |
PcmSetParams(_, _, _, _, _, _, expected_micros)) |
.WillOnce(Return(0)); |
+ EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) |
+ .WillOnce(DoAll(SetArgumentPointee<1>(kTestPacketSize), |
+ SetArgumentPointee<2>(kTestPacketSize / 2), |
+ Return(0))); |
ASSERT_TRUE(test_stream_->Open(kOverMinLatencyPacketSize)); |
message_loop_.RunAllPending(); |
@@ -294,6 +313,10 @@ TEST_F(AlsaPcmOutputStreamTest, OpenClose) { |
1, |
expected_micros)) |
.WillOnce(Return(0)); |
+ EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(kFakeHandle, _, _)) |
+ .WillOnce(DoAll(SetArgumentPointee<1>(kTestPacketSize), |
+ SetArgumentPointee<2>(kTestPacketSize/2), |
+ Return(0))); |
// Open the stream. |
ASSERT_TRUE(test_stream_->Open(kTestPacketSize)); |
@@ -303,7 +326,7 @@ TEST_F(AlsaPcmOutputStreamTest, OpenClose) { |
test_stream_->shared_data_.state()); |
EXPECT_EQ(kFakeHandle, test_stream_->playback_handle_); |
EXPECT_EQ(kTestFramesPerPacket, test_stream_->frames_per_packet_); |
- EXPECT_TRUE(test_stream_->packet_.get()); |
+ EXPECT_TRUE(test_stream_->buffer_.get()); |
EXPECT_FALSE(test_stream_->stop_stream_); |
// Now close it and test that everything was released. |
@@ -316,7 +339,7 @@ TEST_F(AlsaPcmOutputStreamTest, OpenClose) { |
message_loop_.RunAllPending(); |
EXPECT_TRUE(test_stream_->playback_handle_ == NULL); |
- EXPECT_FALSE(test_stream_->packet_.get()); |
+ EXPECT_FALSE(test_stream_->buffer_.get()); |
EXPECT_TRUE(test_stream_->stop_stream_); |
} |
@@ -338,7 +361,7 @@ TEST_F(AlsaPcmOutputStreamTest, PcmOpenFailed) { |
test_stream_->shared_data_.state()); |
EXPECT_TRUE(test_stream_->stop_stream_); |
EXPECT_TRUE(test_stream_->playback_handle_ == NULL); |
- EXPECT_FALSE(test_stream_->packet_.get()); |
+ EXPECT_FALSE(test_stream_->buffer_.get()); |
// Close the stream since we opened it to make destruction happy. |
EXPECT_CALL(mock_manager_, ReleaseStream(test_stream_.get())); |
@@ -372,7 +395,7 @@ TEST_F(AlsaPcmOutputStreamTest, PcmSetParamsFailed) { |
test_stream_->shared_data_.state()); |
EXPECT_TRUE(test_stream_->stop_stream_); |
EXPECT_TRUE(test_stream_->playback_handle_ == NULL); |
- EXPECT_FALSE(test_stream_->packet_.get()); |
+ EXPECT_FALSE(test_stream_->buffer_.get()); |
// Close the stream since we opened it to make destruction happy. |
EXPECT_CALL(mock_manager_, ReleaseStream(test_stream_.get())); |
@@ -389,6 +412,10 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) { |
Return(0))); |
EXPECT_CALL(mock_alsa_wrapper_, PcmSetParams(_, _, _, _, _, _, _)) |
.WillOnce(Return(0)); |
+ EXPECT_CALL(mock_alsa_wrapper_, PcmGetParams(_, _, _)) |
+ .WillOnce(DoAll(SetArgumentPointee<1>(kTestPacketSize), |
+ SetArgumentPointee<2>(kTestPacketSize / 2), |
+ Return(0))); |
// Open the stream. |
ASSERT_TRUE(test_stream_->Open(kTestPacketSize)); |
@@ -400,26 +427,11 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) { |
EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)) |
.WillOnce(Return(0)); |
- // Expect the pre-roll. |
- MockAudioSourceCallback mock_callback; |
- EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) |
- .Times(2) |
- .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); |
- EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) |
- .Times(2) |
- .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); |
- EXPECT_CALL(mock_callback, |
- OnMoreData(test_stream_.get(), _, kTestPacketSize, 0)) |
- .Times(2) |
- .WillRepeatedly(Return(kTestPacketSize)); |
- EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) |
- .Times(2) |
- .WillRepeatedly(Return(kTestPacketSize)); |
- |
// Expect scheduling. |
EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) |
.WillOnce(Return(1)); |
+ MockAudioSourceCallback mock_callback; |
test_stream_->Start(&mock_callback); |
message_loop_.RunAllPending(); |
@@ -434,46 +446,52 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) { |
} |
TEST_F(AlsaPcmOutputStreamTest, WritePacket_FinishedPacket) { |
+ InitBuffer(); |
+ |
// Nothing should happen. Don't set any expectations and Our strict mocks |
// should verify most of this. |
- // Test regular used-up packet. |
- packet_.used = packet_.size; |
- test_stream_->WritePacket(&packet_); |
- |
- // Test empty packet. |
- packet_.used = packet_.size = 0; |
- test_stream_->WritePacket(&packet_); |
+ // Test empty buffer. |
+ test_stream_->buffer_->Clear(); |
+ test_stream_->WritePacket(); |
} |
TEST_F(AlsaPcmOutputStreamTest, WritePacket_NormalPacket) { |
+ InitBuffer(); |
+ |
// Write a little less than half the data. |
- EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, packet_.buffer.get(), _)) |
- .WillOnce(Return(packet_.size / kTestBytesPerFrame / 2 - 1)); |
+ int written = packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1; |
+ EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, packet_->GetData(), _)) |
+ .WillOnce(Return(written)); |
- test_stream_->WritePacket(&packet_); |
+ test_stream_->WritePacket(); |
- ASSERT_EQ(packet_.size / 2 - kTestBytesPerFrame, packet_.used); |
+ ASSERT_EQ(test_stream_->buffer_->forward_bytes(), |
+ packet_->GetDataSize() - written * kTestBytesPerFrame); |
// Write the rest. |
EXPECT_CALL(mock_alsa_wrapper_, |
- PcmWritei(_, packet_.buffer.get() + packet_.used, _)) |
- .WillOnce(Return(packet_.size / kTestBytesPerFrame / 2 + 1)); |
- test_stream_->WritePacket(&packet_); |
- EXPECT_EQ(packet_.size, packet_.used); |
+ PcmWritei(_, packet_->GetData() + written * kTestBytesPerFrame, |
+ _)) |
+ .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame - written)); |
+ test_stream_->WritePacket(); |
+ EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes()); |
} |
TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) { |
+ InitBuffer(); |
+ |
// Fail due to a recoverable error and see that PcmRecover code path |
// continues normally. |
EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, _, _)) |
.WillOnce(Return(-EINTR)); |
EXPECT_CALL(mock_alsa_wrapper_, PcmRecover(_, _, _)) |
- .WillOnce(Return(packet_.size / kTestBytesPerFrame / 2 - 1)); |
+ .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame / 2 - 1)); |
- test_stream_->WritePacket(&packet_); |
+ test_stream_->WritePacket(); |
- ASSERT_EQ(packet_.size / 2 - kTestBytesPerFrame, packet_.used); |
+ ASSERT_EQ(test_stream_->buffer_->forward_bytes(), |
+ packet_->GetDataSize() / 2 + kTestBytesPerFrame); |
// Fail the next write, and see that stop_stream_ is set. |
EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, _, _)) |
@@ -482,20 +500,24 @@ TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) { |
.WillOnce(Return(kTestFailedErrno)); |
EXPECT_CALL(mock_alsa_wrapper_, StrError(kTestFailedErrno)) |
.WillOnce(Return(kDummyMessage)); |
- test_stream_->WritePacket(&packet_); |
- EXPECT_EQ(packet_.size / 2 - kTestBytesPerFrame, packet_.used); |
+ test_stream_->WritePacket(); |
+ EXPECT_EQ(test_stream_->buffer_->forward_bytes(), |
+ packet_->GetDataSize() / 2 + kTestBytesPerFrame); |
EXPECT_TRUE(test_stream_->stop_stream_); |
} |
TEST_F(AlsaPcmOutputStreamTest, WritePacket_StopStream) { |
+ InitBuffer(); |
+ |
// No expectations set on the strict mock because nothing should be called. |
test_stream_->stop_stream_ = true; |
- test_stream_->WritePacket(&packet_); |
- EXPECT_EQ(packet_.size, packet_.used); |
+ test_stream_->WritePacket(); |
+ EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes()); |
} |
TEST_F(AlsaPcmOutputStreamTest, BufferPacket) { |
- packet_.used = packet_.size; |
+ InitBuffer(); |
+ test_stream_->buffer_->Clear(); |
// Return a partially filled packet. |
MockAudioSourceCallback mock_callback; |
@@ -504,19 +526,18 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket) { |
EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
.WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); |
EXPECT_CALL(mock_callback, |
- OnMoreData(test_stream_.get(), packet_.buffer.get(), |
- packet_.capacity, kTestBytesPerFrame)) |
+ OnMoreData(test_stream_.get(), _, _, kTestBytesPerFrame)) |
.WillOnce(Return(10)); |
test_stream_->shared_data_.set_source_callback(&mock_callback); |
- test_stream_->BufferPacket(&packet_); |
+ test_stream_->BufferPacket(); |
- EXPECT_EQ(0u, packet_.used); |
- EXPECT_EQ(10u, packet_.size); |
+ EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); |
} |
TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { |
- packet_.used = packet_.size; |
+ InitBuffer(); |
+ test_stream_->buffer_->Clear(); |
// Simulate where the underrun has occurred right after checking the delay. |
MockAudioSourceCallback mock_callback; |
@@ -525,41 +546,38 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { |
EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
.WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); |
EXPECT_CALL(mock_callback, |
- OnMoreData(test_stream_.get(), packet_.buffer.get(), |
- packet_.capacity, 0)) |
+ OnMoreData(test_stream_.get(), _, _, 0)) |
.WillOnce(Return(10)); |
test_stream_->shared_data_.set_source_callback(&mock_callback); |
- test_stream_->BufferPacket(&packet_); |
+ test_stream_->BufferPacket(); |
- EXPECT_EQ(0u, packet_.used); |
- EXPECT_EQ(10u, packet_.size); |
+ EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); |
} |
TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { |
- packet_.used = packet_.size; |
+ InitBuffer(); |
+ test_stream_->buffer_->Clear(); |
// If ALSA has underrun then we should assume a delay of zero. |
MockAudioSourceCallback mock_callback; |
EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
.WillOnce(Return(SND_PCM_STATE_XRUN)); |
EXPECT_CALL(mock_callback, |
- OnMoreData(test_stream_.get(), packet_.buffer.get(), |
- packet_.capacity, 0)) |
+ OnMoreData(test_stream_.get(), _, _, 0)) |
.WillOnce(Return(10)); |
test_stream_->shared_data_.set_source_callback(&mock_callback); |
- test_stream_->BufferPacket(&packet_); |
+ test_stream_->BufferPacket(); |
- EXPECT_EQ(0u, packet_.used); |
- EXPECT_EQ(10u, packet_.size); |
+ EXPECT_EQ(10u, test_stream_->buffer_->forward_bytes()); |
} |
-TEST_F(AlsaPcmOutputStreamTest, BufferPacket_UnfinishedPacket) { |
+TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { |
+ InitBuffer(); |
// No expectations set on the strict mock because nothing should be called. |
- test_stream_->BufferPacket(&packet_); |
- EXPECT_EQ(0u, packet_.used); |
- EXPECT_EQ(kTestPacketSize, packet_.size); |
+ test_stream_->BufferPacket(); |
+ EXPECT_EQ(kTestPacketSize, test_stream_->buffer_->forward_bytes()); |
} |
TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { |
@@ -684,19 +702,21 @@ TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail) { |
} |
TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { |
+ InitBuffer(); |
test_stream_->stop_stream_ = true; |
- test_stream_->BufferPacket(&packet_); |
- EXPECT_EQ(0u, packet_.used); |
- EXPECT_EQ(0u, packet_.size); |
+ test_stream_->BufferPacket(); |
+ EXPECT_EQ(0u, test_stream_->buffer_->forward_bytes()); |
} |
TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { |
test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsOpened); |
test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
+ InitBuffer(); |
+ |
EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
.WillOnce(Return(10)); |
- test_stream_->ScheduleNextWrite(&packet_); |
+ test_stream_->ScheduleNextWrite(); |
test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsClosed); |
} |
@@ -705,8 +725,10 @@ TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite_StopStream) { |
test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsOpened); |
test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
+ InitBuffer(); |
+ |
test_stream_->stop_stream_ = true; |
- test_stream_->ScheduleNextWrite(&packet_); |
+ test_stream_->ScheduleNextWrite(); |
// TODO(ajwong): Find a way to test whether or not another task has been |
// posted so we can verify that the Alsa code will indeed break the task |