| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/message_loop.h" | 5 #include "base/message_loop.h" |
| 6 #include "base/stringprintf.h" | 6 #include "base/stringprintf.h" |
| 7 #include "media/audio/linux/alsa_output.h" | 7 #include "media/audio/linux/alsa_output.h" |
| 8 #include "media/audio/linux/alsa_wrapper.h" | 8 #include "media/audio/linux/alsa_wrapper.h" |
| 9 #include "media/audio/linux/audio_manager_linux.h" | 9 #include "media/audio/linux/audio_manager_linux.h" |
| 10 #include "media/base/data_buffer.h" | 10 #include "media/base/data_buffer.h" |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); | 62 MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); |
| 63 MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); | 63 MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); |
| 64 MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); | 64 MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); |
| 65 MOCK_METHOD1(PcmStart, int(snd_pcm_t* handle)); | 65 MOCK_METHOD1(PcmStart, int(snd_pcm_t* handle)); |
| 66 | 66 |
| 67 MOCK_METHOD1(StrError, const char*(int errnum)); | 67 MOCK_METHOD1(StrError, const char*(int errnum)); |
| 68 }; | 68 }; |
| 69 | 69 |
| 70 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { | 70 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { |
| 71 public: | 71 public: |
| 72 MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, | 72 MOCK_METHOD3(OnMoreData, uint32(uint8* dest, uint32 max_size, |
| 73 uint8* dest, uint32 max_size, | |
| 74 AudioBuffersState buffers_state)); | 73 AudioBuffersState buffers_state)); |
| 75 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); | 74 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); |
| 76 }; | 75 }; |
| 77 | 76 |
| 78 class MockAudioManagerLinux : public AudioManagerLinux { | 77 class MockAudioManagerLinux : public AudioManagerLinux { |
| 79 public: | 78 public: |
| 80 MOCK_METHOD0(Init, void()); | 79 MOCK_METHOD0(Init, void()); |
| 81 MOCK_METHOD0(HasAudioOutputDevices, bool()); | 80 MOCK_METHOD0(HasAudioOutputDevices, bool()); |
| 82 MOCK_METHOD0(HasAudioInputDevices, bool()); | 81 MOCK_METHOD0(HasAudioInputDevices, bool()); |
| 83 MOCK_METHOD0(MuteAll, void()); | 82 MOCK_METHOD0(MuteAll, void()); |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 .WillOnce(Return(0)); | 432 .WillOnce(Return(0)); |
| 434 | 433 |
| 435 // Expect the pre-roll. | 434 // Expect the pre-roll. |
| 436 MockAudioSourceCallback mock_callback; | 435 MockAudioSourceCallback mock_callback; |
| 437 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) | 436 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) |
| 438 .Times(3) | 437 .Times(3) |
| 439 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); | 438 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); |
| 440 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) | 439 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) |
| 441 .Times(2) | 440 .Times(2) |
| 442 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); | 441 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); |
| 443 EXPECT_CALL(mock_callback, | 442 EXPECT_CALL(mock_callback, OnMoreData(_, kTestPacketSize, _)) |
| 444 OnMoreData(test_stream, _, kTestPacketSize, _)) | |
| 445 .Times(2) | 443 .Times(2) |
| 446 .WillOnce(Return(kTestPacketSize)) | 444 .WillOnce(Return(kTestPacketSize)) |
| 447 .WillOnce(Return(0)); | 445 .WillOnce(Return(0)); |
| 448 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) | 446 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) |
| 449 .WillOnce(Return(kTestFramesPerPacket)); | 447 .WillOnce(Return(kTestFramesPerPacket)); |
| 450 | 448 |
| 451 // Expect scheduling. | 449 // Expect scheduling. |
| 452 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) | 450 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) |
| 453 .Times(AtLeast(3)) | 451 .Times(AtLeast(3)) |
| 454 .WillOnce(Return(kTestFramesPerPacket)) // Buffer is empty. | 452 .WillOnce(Return(kTestFramesPerPacket)) // Buffer is empty. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 | 550 |
| 553 MockAudioSourceCallback mock_callback; | 551 MockAudioSourceCallback mock_callback; |
| 554 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 552 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 555 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 553 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
| 556 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 554 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
| 557 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); | 555 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); |
| 558 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 556 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 559 .WillRepeatedly(Return(0)); // Buffer is full. | 557 .WillRepeatedly(Return(0)); // Buffer is full. |
| 560 | 558 |
| 561 // Return a partially filled packet. | 559 // Return a partially filled packet. |
| 562 EXPECT_CALL(mock_callback, | 560 EXPECT_CALL(mock_callback, OnMoreData(_, _, _)) |
| 563 OnMoreData(test_stream, _, _, _)) | |
| 564 .WillOnce(Return(10)); | 561 .WillOnce(Return(10)); |
| 565 | 562 |
| 566 bool source_exhausted; | 563 bool source_exhausted; |
| 567 test_stream->set_source_callback(&mock_callback); | 564 test_stream->set_source_callback(&mock_callback); |
| 568 test_stream->packet_size_ = kTestPacketSize; | 565 test_stream->packet_size_ = kTestPacketSize; |
| 569 test_stream->BufferPacket(&source_exhausted); | 566 test_stream->BufferPacket(&source_exhausted); |
| 570 | 567 |
| 571 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); | 568 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); |
| 572 EXPECT_FALSE(source_exhausted); | 569 EXPECT_FALSE(source_exhausted); |
| 573 test_stream->Close(); | 570 test_stream->Close(); |
| 574 } | 571 } |
| 575 | 572 |
| 576 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { | 573 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { |
| 577 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 574 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 578 InitBuffer(test_stream); | 575 InitBuffer(test_stream); |
| 579 test_stream->buffer_->Clear(); | 576 test_stream->buffer_->Clear(); |
| 580 | 577 |
| 581 // Simulate where the underrun has occurred right after checking the delay. | 578 // Simulate where the underrun has occurred right after checking the delay. |
| 582 MockAudioSourceCallback mock_callback; | 579 MockAudioSourceCallback mock_callback; |
| 583 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 580 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 584 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 581 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
| 585 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 582 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
| 586 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); | 583 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); |
| 587 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 584 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 588 .WillRepeatedly(Return(0)); // Buffer is full. | 585 .WillRepeatedly(Return(0)); // Buffer is full. |
| 589 EXPECT_CALL(mock_callback, OnMoreData(test_stream, _, _, _)) | 586 EXPECT_CALL(mock_callback, OnMoreData(_, _, _)) |
| 590 .WillOnce(Return(10)); | 587 .WillOnce(Return(10)); |
| 591 | 588 |
| 592 bool source_exhausted; | 589 bool source_exhausted; |
| 593 test_stream->set_source_callback(&mock_callback); | 590 test_stream->set_source_callback(&mock_callback); |
| 594 test_stream->packet_size_ = kTestPacketSize; | 591 test_stream->packet_size_ = kTestPacketSize; |
| 595 test_stream->BufferPacket(&source_exhausted); | 592 test_stream->BufferPacket(&source_exhausted); |
| 596 | 593 |
| 597 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); | 594 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); |
| 598 EXPECT_FALSE(source_exhausted); | 595 EXPECT_FALSE(source_exhausted); |
| 599 test_stream->Close(); | 596 test_stream->Close(); |
| 600 } | 597 } |
| 601 | 598 |
| 602 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { | 599 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { |
| 603 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 600 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 604 InitBuffer(test_stream); | 601 InitBuffer(test_stream); |
| 605 test_stream->buffer_->Clear(); | 602 test_stream->buffer_->Clear(); |
| 606 | 603 |
| 607 // If ALSA has underrun then we should assume a delay of zero. | 604 // If ALSA has underrun then we should assume a delay of zero. |
| 608 MockAudioSourceCallback mock_callback; | 605 MockAudioSourceCallback mock_callback; |
| 609 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 606 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 610 .WillOnce(Return(SND_PCM_STATE_XRUN)); | 607 .WillOnce(Return(SND_PCM_STATE_XRUN)); |
| 611 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 608 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 612 .WillRepeatedly(Return(0)); // Buffer is full. | 609 .WillRepeatedly(Return(0)); // Buffer is full. |
| 613 EXPECT_CALL(mock_callback, | 610 EXPECT_CALL(mock_callback, |
| 614 OnMoreData(test_stream, _, _, AllOf( | 611 OnMoreData(_, _, AllOf( |
| 615 Field(&AudioBuffersState::pending_bytes, 0), | 612 Field(&AudioBuffersState::pending_bytes, 0), |
| 616 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) | 613 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) |
| 617 .WillOnce(Return(10)); | 614 .WillOnce(Return(10)); |
| 618 | 615 |
| 619 bool source_exhausted; | 616 bool source_exhausted; |
| 620 test_stream->set_source_callback(&mock_callback); | 617 test_stream->set_source_callback(&mock_callback); |
| 621 test_stream->packet_size_ = kTestPacketSize; | 618 test_stream->packet_size_ = kTestPacketSize; |
| 622 test_stream->BufferPacket(&source_exhausted); | 619 test_stream->BufferPacket(&source_exhausted); |
| 623 | 620 |
| 624 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); | 621 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 | 818 |
| 822 // TODO(ajwong): Find a way to test whether or not another task has been | 819 // TODO(ajwong): Find a way to test whether or not another task has been |
| 823 // posted so we can verify that the Alsa code will indeed break the task | 820 // posted so we can verify that the Alsa code will indeed break the task |
| 824 // posting loop. | 821 // posting loop. |
| 825 | 822 |
| 826 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); | 823 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); |
| 827 test_stream->Close(); | 824 test_stream->Close(); |
| 828 } | 825 } |
| 829 | 826 |
| 830 } // namespace media | 827 } // namespace media |
| OLD | NEW |