| 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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 } | 153 } |
| 154 | 154 |
| 155 static const ChannelLayout kTestChannelLayout; | 155 static const ChannelLayout kTestChannelLayout; |
| 156 static const int kTestSampleRate; | 156 static const int kTestSampleRate; |
| 157 static const int kTestBitsPerSample; | 157 static const int kTestBitsPerSample; |
| 158 static const int kTestBytesPerFrame; | 158 static const int kTestBytesPerFrame; |
| 159 static const AudioParameters::Format kTestFormat; | 159 static const AudioParameters::Format kTestFormat; |
| 160 static const char kTestDeviceName[]; | 160 static const char kTestDeviceName[]; |
| 161 static const char kDummyMessage[]; | 161 static const char kDummyMessage[]; |
| 162 static const uint32 kTestFramesPerPacket; | 162 static const uint32 kTestFramesPerPacket; |
| 163 static const uint32 kTestPacketSize; | 163 static const int kTestPacketSize; |
| 164 static const int kTestFailedErrno; | 164 static const int kTestFailedErrno; |
| 165 static snd_pcm_t* const kFakeHandle; | 165 static snd_pcm_t* const kFakeHandle; |
| 166 | 166 |
| 167 // Used to simulate DeviceNameHint. | 167 // Used to simulate DeviceNameHint. |
| 168 static char kSurround40[]; | 168 static char kSurround40[]; |
| 169 static char kSurround41[]; | 169 static char kSurround41[]; |
| 170 static char kSurround50[]; | 170 static char kSurround50[]; |
| 171 static char kSurround51[]; | 171 static char kSurround51[]; |
| 172 static char kSurround70[]; | 172 static char kSurround70[]; |
| 173 static char kSurround71[]; | 173 static char kSurround71[]; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 188 AudioParameters::kAudioCDSampleRate; | 188 AudioParameters::kAudioCDSampleRate; |
| 189 const int AlsaPcmOutputStreamTest::kTestBitsPerSample = 8; | 189 const int AlsaPcmOutputStreamTest::kTestBitsPerSample = 8; |
| 190 const int AlsaPcmOutputStreamTest::kTestBytesPerFrame = | 190 const int AlsaPcmOutputStreamTest::kTestBytesPerFrame = |
| 191 AlsaPcmOutputStreamTest::kTestBitsPerSample / 8 * | 191 AlsaPcmOutputStreamTest::kTestBitsPerSample / 8 * |
| 192 ChannelLayoutToChannelCount(AlsaPcmOutputStreamTest::kTestChannelLayout); | 192 ChannelLayoutToChannelCount(AlsaPcmOutputStreamTest::kTestChannelLayout); |
| 193 const AudioParameters::Format AlsaPcmOutputStreamTest::kTestFormat = | 193 const AudioParameters::Format AlsaPcmOutputStreamTest::kTestFormat = |
| 194 AudioParameters::AUDIO_PCM_LINEAR; | 194 AudioParameters::AUDIO_PCM_LINEAR; |
| 195 const char AlsaPcmOutputStreamTest::kTestDeviceName[] = "TestDevice"; | 195 const char AlsaPcmOutputStreamTest::kTestDeviceName[] = "TestDevice"; |
| 196 const char AlsaPcmOutputStreamTest::kDummyMessage[] = "dummy"; | 196 const char AlsaPcmOutputStreamTest::kDummyMessage[] = "dummy"; |
| 197 const uint32 AlsaPcmOutputStreamTest::kTestFramesPerPacket = 1000; | 197 const uint32 AlsaPcmOutputStreamTest::kTestFramesPerPacket = 1000; |
| 198 const uint32 AlsaPcmOutputStreamTest::kTestPacketSize = | 198 const int AlsaPcmOutputStreamTest::kTestPacketSize = |
| 199 AlsaPcmOutputStreamTest::kTestFramesPerPacket * | 199 AlsaPcmOutputStreamTest::kTestFramesPerPacket * |
| 200 AlsaPcmOutputStreamTest::kTestBytesPerFrame; | 200 AlsaPcmOutputStreamTest::kTestBytesPerFrame; |
| 201 const int AlsaPcmOutputStreamTest::kTestFailedErrno = -EACCES; | 201 const int AlsaPcmOutputStreamTest::kTestFailedErrno = -EACCES; |
| 202 snd_pcm_t* const AlsaPcmOutputStreamTest::kFakeHandle = | 202 snd_pcm_t* const AlsaPcmOutputStreamTest::kFakeHandle = |
| 203 reinterpret_cast<snd_pcm_t*>(1); | 203 reinterpret_cast<snd_pcm_t*>(1); |
| 204 | 204 |
| 205 char AlsaPcmOutputStreamTest::kSurround40[] = "surround40:CARD=foo,DEV=0"; | 205 char AlsaPcmOutputStreamTest::kSurround40[] = "surround40:CARD=foo,DEV=0"; |
| 206 char AlsaPcmOutputStreamTest::kSurround41[] = "surround41:CARD=foo,DEV=0"; | 206 char AlsaPcmOutputStreamTest::kSurround41[] = "surround41:CARD=foo,DEV=0"; |
| 207 char AlsaPcmOutputStreamTest::kSurround50[] = "surround50:CARD=foo,DEV=0"; | 207 char AlsaPcmOutputStreamTest::kSurround50[] = "surround50:CARD=foo,DEV=0"; |
| 208 char AlsaPcmOutputStreamTest::kSurround51[] = "surround51:CARD=foo,DEV=0"; | 208 char AlsaPcmOutputStreamTest::kSurround51[] = "surround51:CARD=foo,DEV=0"; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 | 491 |
| 492 ASSERT_EQ(test_stream->buffer_->forward_bytes(), | 492 ASSERT_EQ(test_stream->buffer_->forward_bytes(), |
| 493 packet_->GetDataSize() - written * kTestBytesPerFrame); | 493 packet_->GetDataSize() - written * kTestBytesPerFrame); |
| 494 | 494 |
| 495 // Write the rest. | 495 // Write the rest. |
| 496 EXPECT_CALL(mock_alsa_wrapper_, | 496 EXPECT_CALL(mock_alsa_wrapper_, |
| 497 PcmWritei(_, packet_->GetData() + written * kTestBytesPerFrame, | 497 PcmWritei(_, packet_->GetData() + written * kTestBytesPerFrame, |
| 498 _)) | 498 _)) |
| 499 .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame - written)); | 499 .WillOnce(Return(packet_->GetDataSize() / kTestBytesPerFrame - written)); |
| 500 test_stream->WritePacket(); | 500 test_stream->WritePacket(); |
| 501 EXPECT_EQ(0u, test_stream->buffer_->forward_bytes()); | 501 EXPECT_EQ(0, test_stream->buffer_->forward_bytes()); |
| 502 test_stream->Close(); | 502 test_stream->Close(); |
| 503 } | 503 } |
| 504 | 504 |
| 505 TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) { | 505 TEST_F(AlsaPcmOutputStreamTest, WritePacket_WriteFails) { |
| 506 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 506 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 507 InitBuffer(test_stream); | 507 InitBuffer(test_stream); |
| 508 | 508 |
| 509 // Fail due to a recoverable error and see that PcmRecover code path | 509 // Fail due to a recoverable error and see that PcmRecover code path |
| 510 // continues normally. | 510 // continues normally. |
| 511 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, _, _)) | 511 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(_, _, _)) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 532 test_stream->Close(); | 532 test_stream->Close(); |
| 533 } | 533 } |
| 534 | 534 |
| 535 TEST_F(AlsaPcmOutputStreamTest, WritePacket_StopStream) { | 535 TEST_F(AlsaPcmOutputStreamTest, WritePacket_StopStream) { |
| 536 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 536 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 537 InitBuffer(test_stream); | 537 InitBuffer(test_stream); |
| 538 | 538 |
| 539 // No expectations set on the strict mock because nothing should be called. | 539 // No expectations set on the strict mock because nothing should be called. |
| 540 test_stream->stop_stream_ = true; | 540 test_stream->stop_stream_ = true; |
| 541 test_stream->WritePacket(); | 541 test_stream->WritePacket(); |
| 542 EXPECT_EQ(0u, test_stream->buffer_->forward_bytes()); | 542 EXPECT_EQ(0, test_stream->buffer_->forward_bytes()); |
| 543 test_stream->Close(); | 543 test_stream->Close(); |
| 544 } | 544 } |
| 545 | 545 |
| 546 TEST_F(AlsaPcmOutputStreamTest, BufferPacket) { | 546 TEST_F(AlsaPcmOutputStreamTest, BufferPacket) { |
| 547 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 547 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 548 InitBuffer(test_stream); | 548 InitBuffer(test_stream); |
| 549 test_stream->buffer_->Clear(); | 549 test_stream->buffer_->Clear(); |
| 550 | 550 |
| 551 MockAudioSourceCallback mock_callback; | 551 MockAudioSourceCallback mock_callback; |
| 552 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 552 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 553 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 553 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
| 554 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 554 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
| 555 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); | 555 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); |
| 556 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 556 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 557 .WillRepeatedly(Return(0)); // Buffer is full. | 557 .WillRepeatedly(Return(0)); // Buffer is full. |
| 558 | 558 |
| 559 // Return a partially filled packet. | 559 // Return a partially filled packet. |
| 560 EXPECT_CALL(mock_callback, | 560 EXPECT_CALL(mock_callback, |
| 561 OnMoreData(test_stream, _, _, _)) | 561 OnMoreData(test_stream, _, _, _)) |
| 562 .WillOnce(Return(10)); | 562 .WillOnce(Return(10)); |
| 563 | 563 |
| 564 bool source_exhausted; | 564 bool source_exhausted; |
| 565 test_stream->set_source_callback(&mock_callback); | 565 test_stream->set_source_callback(&mock_callback); |
| 566 test_stream->packet_size_ = kTestPacketSize; | 566 test_stream->packet_size_ = kTestPacketSize; |
| 567 test_stream->BufferPacket(&source_exhausted); | 567 test_stream->BufferPacket(&source_exhausted); |
| 568 | 568 |
| 569 EXPECT_EQ(10u, test_stream->buffer_->forward_bytes()); | 569 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); |
| 570 EXPECT_FALSE(source_exhausted); | 570 EXPECT_FALSE(source_exhausted); |
| 571 test_stream->Close(); | 571 test_stream->Close(); |
| 572 } | 572 } |
| 573 | 573 |
| 574 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { | 574 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { |
| 575 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 575 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 576 InitBuffer(test_stream); | 576 InitBuffer(test_stream); |
| 577 test_stream->buffer_->Clear(); | 577 test_stream->buffer_->Clear(); |
| 578 | 578 |
| 579 // Simulate where the underrun has occurred right after checking the delay. | 579 // Simulate where the underrun has occurred right after checking the delay. |
| 580 MockAudioSourceCallback mock_callback; | 580 MockAudioSourceCallback mock_callback; |
| 581 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 581 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 582 .WillOnce(Return(SND_PCM_STATE_RUNNING)); | 582 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
| 583 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 583 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
| 584 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); | 584 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); |
| 585 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 585 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 586 .WillRepeatedly(Return(0)); // Buffer is full. | 586 .WillRepeatedly(Return(0)); // Buffer is full. |
| 587 EXPECT_CALL(mock_callback, OnMoreData(test_stream, _, _, _)) | 587 EXPECT_CALL(mock_callback, OnMoreData(test_stream, _, _, _)) |
| 588 .WillOnce(Return(10)); | 588 .WillOnce(Return(10)); |
| 589 | 589 |
| 590 bool source_exhausted; | 590 bool source_exhausted; |
| 591 test_stream->set_source_callback(&mock_callback); | 591 test_stream->set_source_callback(&mock_callback); |
| 592 test_stream->packet_size_ = kTestPacketSize; | 592 test_stream->packet_size_ = kTestPacketSize; |
| 593 test_stream->BufferPacket(&source_exhausted); | 593 test_stream->BufferPacket(&source_exhausted); |
| 594 | 594 |
| 595 EXPECT_EQ(10u, test_stream->buffer_->forward_bytes()); | 595 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); |
| 596 EXPECT_FALSE(source_exhausted); | 596 EXPECT_FALSE(source_exhausted); |
| 597 test_stream->Close(); | 597 test_stream->Close(); |
| 598 } | 598 } |
| 599 | 599 |
| 600 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { | 600 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { |
| 601 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 601 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 602 InitBuffer(test_stream); | 602 InitBuffer(test_stream); |
| 603 test_stream->buffer_->Clear(); | 603 test_stream->buffer_->Clear(); |
| 604 | 604 |
| 605 // If ALSA has underrun then we should assume a delay of zero. | 605 // If ALSA has underrun then we should assume a delay of zero. |
| 606 MockAudioSourceCallback mock_callback; | 606 MockAudioSourceCallback mock_callback; |
| 607 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) | 607 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 608 .WillOnce(Return(SND_PCM_STATE_XRUN)); | 608 .WillOnce(Return(SND_PCM_STATE_XRUN)); |
| 609 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) | 609 EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(_)) |
| 610 .WillRepeatedly(Return(0)); // Buffer is full. | 610 .WillRepeatedly(Return(0)); // Buffer is full. |
| 611 EXPECT_CALL(mock_callback, | 611 EXPECT_CALL(mock_callback, |
| 612 OnMoreData(test_stream, _, _, AllOf( | 612 OnMoreData(test_stream, _, _, AllOf( |
| 613 Field(&AudioBuffersState::pending_bytes, 0), | 613 Field(&AudioBuffersState::pending_bytes, 0), |
| 614 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) | 614 Field(&AudioBuffersState::hardware_delay_bytes, 0)))) |
| 615 .WillOnce(Return(10)); | 615 .WillOnce(Return(10)); |
| 616 | 616 |
| 617 bool source_exhausted; | 617 bool source_exhausted; |
| 618 test_stream->set_source_callback(&mock_callback); | 618 test_stream->set_source_callback(&mock_callback); |
| 619 test_stream->packet_size_ = kTestPacketSize; | 619 test_stream->packet_size_ = kTestPacketSize; |
| 620 test_stream->BufferPacket(&source_exhausted); | 620 test_stream->BufferPacket(&source_exhausted); |
| 621 | 621 |
| 622 EXPECT_EQ(10u, test_stream->buffer_->forward_bytes()); | 622 EXPECT_EQ(10, test_stream->buffer_->forward_bytes()); |
| 623 EXPECT_FALSE(source_exhausted); | 623 EXPECT_FALSE(source_exhausted); |
| 624 test_stream->Close(); | 624 test_stream->Close(); |
| 625 } | 625 } |
| 626 | 626 |
| 627 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { | 627 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer) { |
| 628 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 628 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 629 InitBuffer(test_stream); | 629 InitBuffer(test_stream); |
| 630 // No expectations set on the strict mock because nothing should be called. | 630 // No expectations set on the strict mock because nothing should be called. |
| 631 bool source_exhausted; | 631 bool source_exhausted; |
| 632 test_stream->packet_size_ = kTestPacketSize; | 632 test_stream->packet_size_ = kTestPacketSize; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 EXPECT_TRUE(test_stream->should_downmix_); | 770 EXPECT_TRUE(test_stream->should_downmix_); |
| 771 test_stream->Close(); | 771 test_stream->Close(); |
| 772 } | 772 } |
| 773 | 773 |
| 774 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { | 774 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_StopStream) { |
| 775 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 775 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 776 InitBuffer(test_stream); | 776 InitBuffer(test_stream); |
| 777 test_stream->stop_stream_ = true; | 777 test_stream->stop_stream_ = true; |
| 778 bool source_exhausted; | 778 bool source_exhausted; |
| 779 test_stream->BufferPacket(&source_exhausted); | 779 test_stream->BufferPacket(&source_exhausted); |
| 780 EXPECT_EQ(0u, test_stream->buffer_->forward_bytes()); | 780 EXPECT_EQ(0, test_stream->buffer_->forward_bytes()); |
| 781 EXPECT_TRUE(source_exhausted); | 781 EXPECT_TRUE(source_exhausted); |
| 782 test_stream->Close(); | 782 test_stream->Close(); |
| 783 } | 783 } |
| 784 | 784 |
| 785 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { | 785 TEST_F(AlsaPcmOutputStreamTest, ScheduleNextWrite) { |
| 786 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); | 786 AlsaPcmOutputStream* test_stream = CreateStream(kTestChannelLayout); |
| 787 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); | 787 test_stream->TransitionTo(AlsaPcmOutputStream::kIsOpened); |
| 788 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); | 788 test_stream->TransitionTo(AlsaPcmOutputStream::kIsPlaying); |
| 789 DLOG(WARNING) << test_stream->state(); | 789 DLOG(WARNING) << test_stream->state(); |
| 790 InitBuffer(test_stream); | 790 InitBuffer(test_stream); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 817 test_stream->stop_stream_ = true; | 817 test_stream->stop_stream_ = true; |
| 818 test_stream->ScheduleNextWrite(true); | 818 test_stream->ScheduleNextWrite(true); |
| 819 | 819 |
| 820 // TODO(ajwong): Find a way to test whether or not another task has been | 820 // TODO(ajwong): Find a way to test whether or not another task has been |
| 821 // posted so we can verify that the Alsa code will indeed break the task | 821 // posted so we can verify that the Alsa code will indeed break the task |
| 822 // posting loop. | 822 // posting loop. |
| 823 | 823 |
| 824 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); | 824 test_stream->TransitionTo(AlsaPcmOutputStream::kIsClosed); |
| 825 test_stream->Close(); | 825 test_stream->Close(); |
| 826 } | 826 } |
| OLD | NEW |