OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/logging.h" | 5 #include "base/logging.h" |
6 #include "base/string_util.h" | 6 #include "base/string_util.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 "testing/gmock/include/gmock/gmock.h" | 10 #include "testing/gmock/include/gmock/gmock.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 MOCK_METHOD3(PcmWritei, snd_pcm_sframes_t(snd_pcm_t* handle, | 40 MOCK_METHOD3(PcmWritei, snd_pcm_sframes_t(snd_pcm_t* handle, |
41 const void* buffer, | 41 const void* buffer, |
42 snd_pcm_uframes_t size)); | 42 snd_pcm_uframes_t size)); |
43 MOCK_METHOD3(PcmRecover, int(snd_pcm_t* handle, int err, int silent)); | 43 MOCK_METHOD3(PcmRecover, int(snd_pcm_t* handle, int err, int silent)); |
44 MOCK_METHOD7(PcmSetParams, int(snd_pcm_t* handle, snd_pcm_format_t format, | 44 MOCK_METHOD7(PcmSetParams, int(snd_pcm_t* handle, snd_pcm_format_t format, |
45 snd_pcm_access_t access, unsigned int channels, | 45 snd_pcm_access_t access, unsigned int channels, |
46 unsigned int rate, int soft_resample, | 46 unsigned int rate, int soft_resample, |
47 unsigned int latency)); | 47 unsigned int latency)); |
48 MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); | 48 MOCK_METHOD1(PcmName, const char*(snd_pcm_t* handle)); |
49 MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t (snd_pcm_t* handle)); | 49 MOCK_METHOD1(PcmAvailUpdate, snd_pcm_sframes_t (snd_pcm_t* handle)); |
| 50 MOCK_METHOD1(PcmState, snd_pcm_state_t (snd_pcm_t* handle)); |
50 | 51 |
51 MOCK_METHOD1(StrError, const char*(int errnum)); | 52 MOCK_METHOD1(StrError, const char*(int errnum)); |
52 }; | 53 }; |
53 | 54 |
54 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { | 55 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { |
55 public: | 56 public: |
56 MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, void* dest, | 57 MOCK_METHOD4(OnMoreData, uint32(AudioOutputStream* stream, void* dest, |
57 uint32 max_size, uint32 pending_bytes)); | 58 uint32 max_size, uint32 pending_bytes)); |
58 MOCK_METHOD1(OnClose, void(AudioOutputStream* stream)); | 59 MOCK_METHOD1(OnClose, void(AudioOutputStream* stream)); |
59 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); | 60 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 message_loop_.RunAllPending(); | 394 message_loop_.RunAllPending(); |
394 | 395 |
395 // Expect Device setup. | 396 // Expect Device setup. |
396 EXPECT_CALL(mock_alsa_wrapper_, PcmDrop(kFakeHandle)) | 397 EXPECT_CALL(mock_alsa_wrapper_, PcmDrop(kFakeHandle)) |
397 .WillOnce(Return(0)); | 398 .WillOnce(Return(0)); |
398 EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)) | 399 EXPECT_CALL(mock_alsa_wrapper_, PcmPrepare(kFakeHandle)) |
399 .WillOnce(Return(0)); | 400 .WillOnce(Return(0)); |
400 | 401 |
401 // Expect the pre-roll. | 402 // Expect the pre-roll. |
402 MockAudioSourceCallback mock_callback; | 403 MockAudioSourceCallback mock_callback; |
| 404 EXPECT_CALL(mock_alsa_wrapper_, PcmState(kFakeHandle)) |
| 405 .Times(2) |
| 406 .WillRepeatedly(Return(SND_PCM_STATE_RUNNING)); |
403 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) | 407 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _)) |
404 .Times(2) | 408 .Times(2) |
405 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); | 409 .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0))); |
406 EXPECT_CALL(mock_callback, | 410 EXPECT_CALL(mock_callback, |
407 OnMoreData(test_stream_.get(), _, kTestPacketSize, 0)) | 411 OnMoreData(test_stream_.get(), _, kTestPacketSize, 0)) |
408 .Times(2) | 412 .Times(2) |
409 .WillRepeatedly(Return(kTestPacketSize)); | 413 .WillRepeatedly(Return(kTestPacketSize)); |
410 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) | 414 EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _)) |
411 .Times(2) | 415 .Times(2) |
412 .WillRepeatedly(Return(kTestPacketSize)); | 416 .WillRepeatedly(Return(kTestPacketSize)); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 test_stream_->stop_stream_ = true; | 491 test_stream_->stop_stream_ = true; |
488 test_stream_->WritePacket(&packet_); | 492 test_stream_->WritePacket(&packet_); |
489 EXPECT_EQ(packet_.size, packet_.used); | 493 EXPECT_EQ(packet_.size, packet_.used); |
490 } | 494 } |
491 | 495 |
492 TEST_F(AlsaPcmOutputStreamTest, BufferPacket) { | 496 TEST_F(AlsaPcmOutputStreamTest, BufferPacket) { |
493 packet_.used = packet_.size; | 497 packet_.used = packet_.size; |
494 | 498 |
495 // Return a partially filled packet. | 499 // Return a partially filled packet. |
496 MockAudioSourceCallback mock_callback; | 500 MockAudioSourceCallback mock_callback; |
| 501 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 502 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
497 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) | 503 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
498 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); | 504 .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0))); |
499 EXPECT_CALL(mock_callback, | 505 EXPECT_CALL(mock_callback, |
500 OnMoreData(test_stream_.get(), packet_.buffer.get(), | 506 OnMoreData(test_stream_.get(), packet_.buffer.get(), |
501 packet_.capacity, kTestBytesPerFrame)) | 507 packet_.capacity, kTestBytesPerFrame)) |
502 .WillOnce(Return(10)); | 508 .WillOnce(Return(10)); |
503 | 509 |
504 test_stream_->shared_data_.set_source_callback(&mock_callback); | 510 test_stream_->shared_data_.set_source_callback(&mock_callback); |
505 test_stream_->BufferPacket(&packet_); | 511 test_stream_->BufferPacket(&packet_); |
506 | 512 |
507 EXPECT_EQ(0u, packet_.used); | 513 EXPECT_EQ(0u, packet_.used); |
508 EXPECT_EQ(10u, packet_.size); | 514 EXPECT_EQ(10u, packet_.size); |
509 } | 515 } |
510 | 516 |
| 517 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Negative) { |
| 518 packet_.used = packet_.size; |
| 519 |
| 520 // Simulate where the underrun has occurred right after checking the delay. |
| 521 MockAudioSourceCallback mock_callback; |
| 522 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 523 .WillOnce(Return(SND_PCM_STATE_RUNNING)); |
| 524 EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _)) |
| 525 .WillOnce(DoAll(SetArgumentPointee<1>(-1), Return(0))); |
| 526 EXPECT_CALL(mock_callback, |
| 527 OnMoreData(test_stream_.get(), packet_.buffer.get(), |
| 528 packet_.capacity, 0)) |
| 529 .WillOnce(Return(10)); |
| 530 |
| 531 test_stream_->shared_data_.set_source_callback(&mock_callback); |
| 532 test_stream_->BufferPacket(&packet_); |
| 533 |
| 534 EXPECT_EQ(0u, packet_.used); |
| 535 EXPECT_EQ(10u, packet_.size); |
| 536 } |
| 537 |
| 538 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_Underrun) { |
| 539 packet_.used = packet_.size; |
| 540 |
| 541 // If ALSA has underrun then we should assume a delay of zero. |
| 542 MockAudioSourceCallback mock_callback; |
| 543 EXPECT_CALL(mock_alsa_wrapper_, PcmState(_)) |
| 544 .WillOnce(Return(SND_PCM_STATE_XRUN)); |
| 545 EXPECT_CALL(mock_callback, |
| 546 OnMoreData(test_stream_.get(), packet_.buffer.get(), |
| 547 packet_.capacity, 0)) |
| 548 .WillOnce(Return(10)); |
| 549 |
| 550 test_stream_->shared_data_.set_source_callback(&mock_callback); |
| 551 test_stream_->BufferPacket(&packet_); |
| 552 |
| 553 EXPECT_EQ(0u, packet_.used); |
| 554 EXPECT_EQ(10u, packet_.size); |
| 555 } |
| 556 |
511 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_UnfinishedPacket) { | 557 TEST_F(AlsaPcmOutputStreamTest, BufferPacket_UnfinishedPacket) { |
512 // No expectations set on the strict mock because nothing should be called. | 558 // No expectations set on the strict mock because nothing should be called. |
513 test_stream_->BufferPacket(&packet_); | 559 test_stream_->BufferPacket(&packet_); |
514 EXPECT_EQ(0u, packet_.used); | 560 EXPECT_EQ(0u, packet_.used); |
515 EXPECT_EQ(kTestPacketSize, packet_.size); | 561 EXPECT_EQ(kTestPacketSize, packet_.size); |
516 } | 562 } |
517 | 563 |
518 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { | 564 TEST_F(AlsaPcmOutputStreamTest, AutoSelectDevice_DeviceSelect) { |
519 // Try channels from 1 -> 9. and see that we get the more specific surroundXX | 565 // Try channels from 1 -> 9. and see that we get the more specific surroundXX |
520 // device opened for channels 4-8. For all other channels, the device should | 566 // device opened for channels 4-8. For all other channels, the device should |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 | 706 |
661 test_stream_->stop_stream_ = true; | 707 test_stream_->stop_stream_ = true; |
662 test_stream_->ScheduleNextWrite(&packet_); | 708 test_stream_->ScheduleNextWrite(&packet_); |
663 | 709 |
664 // TODO(ajwong): Find a way to test whether or not another task has been | 710 // TODO(ajwong): Find a way to test whether or not another task has been |
665 // posted so we can verify that the Alsa code will indeed break the task | 711 // posted so we can verify that the Alsa code will indeed break the task |
666 // posting loop. | 712 // posting loop. |
667 | 713 |
668 test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsClosed); | 714 test_stream_->shared_data_.TransitionTo(AlsaPcmOutputStream::kIsClosed); |
669 } | 715 } |
OLD | NEW |