| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); | 61 MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); |
| 62 MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); | 62 MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t(snd_pcm_t* handle)); |
| 63 MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); | 63 MOCK_METHOD1(PcmState, snd_pcm_state_t(snd_pcm_t* handle)); |
| 64 MOCK_METHOD1(PcmStart, int(snd_pcm_t* handle)); | 64 MOCK_METHOD1(PcmStart, int(snd_pcm_t* handle)); |
| 65 | 65 |
| 66 MOCK_METHOD1(StrError, const char*(int errnum)); | 66 MOCK_METHOD1(StrError, const char*(int errnum)); |
| 67 }; | 67 }; |
| 68 | 68 |
| 69 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { | 69 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { |
| 70 public: | 70 public: |
| 71 MOCK_METHOD3(OnMoreData, uint32(uint8* dest, uint32 max_size, | 71 MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus, |
| 72 AudioBuffersState buffers_state)); | 72 AudioBuffersState buffers_state)); |
| 73 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); | 73 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 class MockAudioManagerLinux : public AudioManagerLinux { | 76 class MockAudioManagerLinux : public AudioManagerLinux { |
| 77 public: | 77 public: |
| 78 MOCK_METHOD0(Init, void()); | 78 MOCK_METHOD0(Init, void()); |
| 79 MOCK_METHOD0(HasAudioOutputDevices, bool()); | 79 MOCK_METHOD0(HasAudioOutputDevices, bool()); |
| 80 MOCK_METHOD0(HasAudioInputDevices, bool()); | 80 MOCK_METHOD0(HasAudioInputDevices, bool()); |
| 81 MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*( | 81 MOCK_METHOD1(MakeLinearOutputStream, AudioOutputStream*( |
| 82 const AudioParameters& params)); | 82 const AudioParameters& params)); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 .WillOnce(Return(0)); | 421 .WillOnce(Return(0)); |
| 422 EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)) | 422 EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)) |
| 423 .WillOnce(Return(0)); | 423 .WillOnce(Return(0)); |
| 424 | 424 |
| 425 // Expect the pre-roll. | 425 // Expect the pre-roll. |
| 426 MockAudioSourceCallback mock_callback; | 426 MockAudioSourceCallback mock_callback; |
| 427 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) | 427 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) |
| 428 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); | 428 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); |
| 429 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) | 429 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) |
| 430 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); | 430 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); |
| 431 EXPECT_CALL(mock_callback, OnMoreData(_, kTestPacketSize, _)) | 431 EXPECT_CALL(mock_callback, OnMoreData(_, _)) |
| 432 .WillRepeatedly(Return(kTestPacketSize)); | 432 .WillRepeatedly(Return(kTestFramesPerPacket)); |
| 433 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) | 433 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) |
| 434 .WillRepeatedly(Return(kTestFramesPerPacket)); | 434 .WillRepeatedly(Return(kTestFramesPerPacket)); |
| 435 | 435 |
| 436 // Expect scheduling. | 436 // Expect scheduling. |
| 437 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) | 437 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle)) |
| 438 .Times(AtLeast(2)) | 438 .Times(AtLeast(2)) |
| 439 .WillRepeatedly(Return(kTestFramesPerPacket)); | 439 .WillRepeatedly(Return(kTestFramesPerPacket)); |
| 440 | 440 |
| 441 test_stream->Start(&mock_callback); | 441 test_stream->Start(&mock_callback); |
| 442 message_loop_.RunAllPending(); | 442 message_loop_.RunAllPending(); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 | 580 |
| 581 MockAudioSourceCallback mock_callback; | 581 MockAudioSourceCallback mock_callback; |
| 582 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 582 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 583 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 583 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
| 584 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 584 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
| 585 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); | 585 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); |
| 586 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 586 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 587 .WillRepeatedly(Return(0)); // Buffer is full. | 587 .WillRepeatedly(Return(0)); // Buffer is full. |
| 588 | 588 |
| 589 // Return a partially filled packet. | 589 // Return a partially filled packet. |
| 590 EXPECT_CALL(mock_callback, OnMoreData(_, _, _)) | 590 EXPECT_CALL(mock_callback, OnMoreData(_, _)) |
| 591 .WillOnce(Return(10)); | 591 .WillOnce(Return(kTestFramesPerPacket / 2)); |
| 592 | 592 |
| 593 bool source_exhausted; | 593 bool source_exhausted; |
| 594 test_stream->set_source_callback(&mock_callback); | 594 test_stream->set_source_callback(&mock_callback); |
| 595 test_stream->packet_size_ = kTestPacketSize; | 595 test_stream->packet_size_ = kTestPacketSize; |
| 596 test_stream->BufferPacket(&source_exhausted); | 596 test_stream->BufferPacket(&source_exhausted); |
| 597 | 597 |
| 598 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); | 598 EXPECT_EQ(kTestPacketSize / 2, test_stream->buffer_->forward_bytes()); |
| 599 EXPECT_FALSE(source_exhausted); | 599 EXPECT_FALSE(source_exhausted); |
| 600 test_stream->Close(); | 600 test_stream->Close(); |
| 601 } | 601 } |
| 602 | 602 |
| 603 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { | 603 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { |
| 604 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 604 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 605 InitBuffer(test_stream); | 605 InitBuffer(test_stream); |
| 606 test_stream->buffer_->Clear(); | 606 test_stream->buffer_->Clear(); |
| 607 | 607 |
| 608 // Simulate where the underrun has occurred right after checking the delay. | 608 // Simulate where the underrun has occurred right after checking the delay. |
| 609 MockAudioSourceCallback mock_callback; | 609 MockAudioSourceCallback mock_callback; |
| 610 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 610 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 611 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 611 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
| 612 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 612 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
| 613 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); | 613 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); |
| 614 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 614 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 615 .WillRepeatedly(Return(0)); // Buffer is full. | 615 .WillRepeatedly(Return(0)); // Buffer is full. |
| 616 EXPECT_CALL(mock_callback, OnMoreData(_, _, _)) | 616 EXPECT_CALL(mock_callback, OnMoreData(_, _)) |
| 617 .WillOnce(Return(10)); | 617 .WillOnce(Return(kTestFramesPerPacket / 2)); |
| 618 | 618 |
| 619 bool source_exhausted; | 619 bool source_exhausted; |
| 620 test_stream->set_source_callback(&mock_callback); | 620 test_stream->set_source_callback(&mock_callback); |
| 621 test_stream->packet_size_ = kTestPacketSize; | 621 test_stream->packet_size_ = kTestPacketSize; |
| 622 test_stream->BufferPacket(&source_exhausted); | 622 test_stream->BufferPacket(&source_exhausted); |
| 623 | 623 |
| 624 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); | 624 EXPECT_EQ(kTestPacketSize / 2, test_stream->buffer_->forward_bytes()); |
| 625 EXPECT_FALSE(source_exhausted); | 625 EXPECT_FALSE(source_exhausted); |
| 626 test_stream->Close(); | 626 test_stream->Close(); |
| 627 } | 627 } |
| 628 | 628 |
| 629 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { | 629 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { |
| 630 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 630 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 631 InitBuffer(test_stream); | 631 InitBuffer(test_stream); |
| 632 test_stream->buffer_->Clear(); | 632 test_stream->buffer_->Clear(); |
| 633 | 633 |
| 634 // If ALSA has underrun then we should assume a delay of zero. | 634 // If ALSA has underrun then we should assume a delay of zero. |
| 635 MockAudioSourceCallback mock_callback; | 635 MockAudioSourceCallback mock_callback; |
| 636 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 636 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 637 .WillOnce(Return(SND_PCM_STATE_XRUN)); | 637 .WillOnce(Return(SND_PCM_STATE_XRUN)); |
| 638 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 638 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 639 .WillRepeatedly(Return(0)); // Buffer is full. | 639 .WillRepeatedly(Return(0)); // Buffer is full. |
| 640 EXPECT_CALL(mock_callback, | 640 EXPECT_CALL(mock_callback, |
| 641 OnMoreData(_, _, AllOf( | 641 OnMoreData(_, AllOf( |
| 642 Field(&AudioBuffersState::pending_bytes, 0), | 642 Field(&AudioBuffersState::pending_bytes, 0), |
| 643 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) | 643 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) |
| 644 .WillOnce(Return(10)); | 644 .WillOnce(Return(kTestFramesPerPacket / 2)); |
| 645 | 645 |
| 646 bool source_exhausted; | 646 bool source_exhausted; |
| 647 test_stream->set_source_callback(&mock_callback); | 647 test_stream->set_source_callback(&mock_callback); |
| 648 test_stream->packet_size_ = kTestPacketSize; | 648 test_stream->packet_size_ = kTestPacketSize; |
| 649 test_stream->BufferPacket(&source_exhausted); | 649 test_stream->BufferPacket(&source_exhausted); |
| 650 | 650 |
| 651 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); | 651 EXPECT_EQ(kTestPacketSize / 2, test_stream->buffer_->forward_bytes()); |
| 652 EXPECT_FALSE(source_exhausted); | 652 EXPECT_FALSE(source_exhausted); |
| 653 test_stream->Close(); | 653 test_stream->Close(); |
| 654 } | 654 } |
| 655 | 655 |
| 656 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { | 656 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { |
| 657 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 657 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 658 InitBuffer(test_stream); | 658 InitBuffer(test_stream); |
| 659 // No expectations set on the strict mock because nothing should be called. | 659 // No expectations set on the strict mock because nothing should be called. |
| 660 bool source_exhausted; | 660 bool source_exhausted; |
| 661 test_stream->packet_size_ = kTestPacketSize; | 661 test_stream->packet_size_ = kTestPacketSize; |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 | 847 |
| 848 // TODO(ajwong): Find a way to test whether or not another task has been | 848 // TODO(ajwong): Find a way to test whether or not another task has been |
| 849 // posted so we can verify that the Alsa code will indeed break the task | 849 // posted so we can verify that the Alsa code will indeed break the task |
| 850 // posting loop. | 850 // posting loop. |
| 851 | 851 |
| 852 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); | 852 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); |
| 853 test_stream->Close(); | 853 test_stream->Close(); |
| 854 } | 854 } |
| 855 | 855 |
| 856 } // namespace media | 856 } // namespace media |
| OLD | NEW |