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 |