| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chromecast/media/cma/backend/alsa/stream_mixer_alsa.h" | 5 #include "chromecast/media/cma/backend/alsa/stream_mixer_alsa.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/memory/scoped_vector.h" | 13 #include "base/memory/scoped_vector.h" |
| 14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
| 15 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
| 16 #include "base/threading/thread_task_runner_handle.h" | 16 #include "base/threading/thread_task_runner_handle.h" |
| 17 #include "chromecast/media/cma/backend/alsa/mock_alsa_wrapper.h" | 17 #include "chromecast/media/cma/backend/alsa/mock_alsa_wrapper.h" |
| 18 #include "media/base/audio_bus.h" | 18 #include "media/base/audio_bus.h" |
| 19 #include "media/base/vector_math.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 22 |
| 22 using testing::_; | 23 using testing::_; |
| 23 | 24 |
| 24 namespace chromecast { | 25 namespace chromecast { |
| 25 namespace media { | 26 namespace media { |
| 26 | 27 |
| 27 namespace { | 28 namespace { |
| 28 | 29 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 public: | 128 public: |
| 128 explicit MockInputQueue(int samples_per_second) | 129 explicit MockInputQueue(int samples_per_second) |
| 129 : paused_(true), | 130 : paused_(true), |
| 130 samples_per_second_(samples_per_second), | 131 samples_per_second_(samples_per_second), |
| 131 max_read_size_(kTestMaxReadSize), | 132 max_read_size_(kTestMaxReadSize), |
| 132 multiplier_(1.0), | 133 multiplier_(1.0), |
| 133 primary_(true), | 134 primary_(true), |
| 134 deleting_(false) { | 135 deleting_(false) { |
| 135 ON_CALL(*this, GetResampledData(_, _)).WillByDefault( | 136 ON_CALL(*this, GetResampledData(_, _)).WillByDefault( |
| 136 testing::Invoke(this, &MockInputQueue::DoGetResampledData)); | 137 testing::Invoke(this, &MockInputQueue::DoGetResampledData)); |
| 138 ON_CALL(*this, VolumeScaleAccumulate(_, _, _, _)).WillByDefault( |
| 139 testing::Invoke(this, &MockInputQueue::DoVolumeScaleAccumulate)); |
| 137 ON_CALL(*this, PrepareToDelete(_)).WillByDefault( | 140 ON_CALL(*this, PrepareToDelete(_)).WillByDefault( |
| 138 testing::Invoke(this, &MockInputQueue::DoPrepareToDelete)); | 141 testing::Invoke(this, &MockInputQueue::DoPrepareToDelete)); |
| 139 } | 142 } |
| 140 ~MockInputQueue() override {} | 143 ~MockInputQueue() override {} |
| 141 | 144 |
| 142 bool paused() const { return paused_; } | 145 bool paused() const { return paused_; } |
| 143 | 146 |
| 144 // StreamMixerAlsa::InputQueue implementation: | 147 // StreamMixerAlsa::InputQueue implementation: |
| 145 int input_samples_per_second() const override { return samples_per_second_; } | 148 int input_samples_per_second() const override { return samples_per_second_; } |
| 146 float volume_multiplier() const override { return multiplier_; } | |
| 147 bool primary() const override { return primary_; } | 149 bool primary() const override { return primary_; } |
| 148 bool IsDeleting() const override { return deleting_; } | 150 bool IsDeleting() const override { return deleting_; } |
| 149 MOCK_METHOD1(Initialize, | 151 MOCK_METHOD1(Initialize, |
| 150 void(const MediaPipelineBackendAlsa::RenderingDelay& | 152 void(const MediaPipelineBackendAlsa::RenderingDelay& |
| 151 mixer_rendering_delay)); | 153 mixer_rendering_delay)); |
| 152 int MaxReadSize() override { return max_read_size_; } | 154 int MaxReadSize() override { return max_read_size_; } |
| 153 MOCK_METHOD2(GetResampledData, void(::media::AudioBus* dest, int frames)); | 155 MOCK_METHOD2(GetResampledData, void(::media::AudioBus* dest, int frames)); |
| 156 MOCK_METHOD4( |
| 157 VolumeScaleAccumulate, |
| 158 void(bool repeat_transition, const float* src, int frames, float* dest)); |
| 154 MOCK_METHOD1(AfterWriteFrames, | 159 MOCK_METHOD1(AfterWriteFrames, |
| 155 void(const MediaPipelineBackendAlsa::RenderingDelay& | 160 void(const MediaPipelineBackendAlsa::RenderingDelay& |
| 156 mixer_rendering_delay)); | 161 mixer_rendering_delay)); |
| 157 MOCK_METHOD1(SignalError, void(StreamMixerAlsaInput::MixerError error)); | 162 MOCK_METHOD1(SignalError, void(StreamMixerAlsaInput::MixerError error)); |
| 158 MOCK_METHOD1(PrepareToDelete, void(const OnReadyToDeleteCb& delete_cb)); | 163 MOCK_METHOD1(PrepareToDelete, void(const OnReadyToDeleteCb& delete_cb)); |
| 159 | 164 |
| 160 // Setters and getters for test control. | 165 // Setters and getters for test control. |
| 161 void SetPaused(bool paused) { paused_ = paused; } | 166 void SetPaused(bool paused) { paused_ = paused; } |
| 162 void SetMaxReadSize(int max_read_size) { max_read_size_ = max_read_size; } | 167 void SetMaxReadSize(int max_read_size) { max_read_size_ = max_read_size; } |
| 163 void SetData(std::unique_ptr<::media::AudioBus> data) { | 168 void SetData(std::unique_ptr<::media::AudioBus> data) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 180 void DoGetResampledData(::media::AudioBus* dest, int frames) { | 185 void DoGetResampledData(::media::AudioBus* dest, int frames) { |
| 181 CHECK(dest); | 186 CHECK(dest); |
| 182 CHECK_GE(dest->frames(), frames); | 187 CHECK_GE(dest->frames(), frames); |
| 183 if (data_) { | 188 if (data_) { |
| 184 data_->CopyPartialFramesTo(0, frames, 0, dest); | 189 data_->CopyPartialFramesTo(0, frames, 0, dest); |
| 185 } else { | 190 } else { |
| 186 dest->ZeroFramesPartial(0, frames); | 191 dest->ZeroFramesPartial(0, frames); |
| 187 } | 192 } |
| 188 } | 193 } |
| 189 | 194 |
| 195 void DoVolumeScaleAccumulate(bool repeat_transition, |
| 196 const float* src, |
| 197 int frames, |
| 198 float* dest) { |
| 199 CHECK(src); |
| 200 CHECK(dest); |
| 201 CHECK(multiplier_ >= 0.0 && multiplier_ <= 1.0); |
| 202 ::media::vector_math::FMAC(src, multiplier_, frames, dest); |
| 203 } |
| 204 |
| 190 void DoPrepareToDelete(const OnReadyToDeleteCb& delete_cb) { | 205 void DoPrepareToDelete(const OnReadyToDeleteCb& delete_cb) { |
| 191 deleting_ = true; | 206 deleting_ = true; |
| 192 delete_cb.Run(this); | 207 delete_cb.Run(this); |
| 193 } | 208 } |
| 194 | 209 |
| 195 bool paused_; | 210 bool paused_; |
| 196 int samples_per_second_; | 211 int samples_per_second_; |
| 197 int max_read_size_; | 212 int max_read_size_; |
| 198 float multiplier_; | 213 float multiplier_; |
| 199 bool primary_; | 214 bool primary_; |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 | 372 |
| 358 // The mixer should pull data from all streams, using the smallest | 373 // The mixer should pull data from all streams, using the smallest |
| 359 // MaxReadSize provided by any of the channels. | 374 // MaxReadSize provided by any of the channels. |
| 360 // TODO(slan): Check that the proper number of frames is pulled. | 375 // TODO(slan): Check that the proper number of frames is pulled. |
| 361 ASSERT_EQ(3u, inputs.size()); | 376 ASSERT_EQ(3u, inputs.size()); |
| 362 inputs[0]->SetMaxReadSize(1024); | 377 inputs[0]->SetMaxReadSize(1024); |
| 363 inputs[1]->SetMaxReadSize(512); | 378 inputs[1]->SetMaxReadSize(512); |
| 364 inputs[2]->SetMaxReadSize(2048); | 379 inputs[2]->SetMaxReadSize(2048); |
| 365 for (auto* input : inputs) { | 380 for (auto* input : inputs) { |
| 366 EXPECT_CALL(*input, GetResampledData(_, 512)).Times(1); | 381 EXPECT_CALL(*input, GetResampledData(_, 512)).Times(1); |
| 382 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, 512, _)) |
| 383 .Times(kNumChannels); |
| 367 EXPECT_CALL(*input, AfterWriteFrames(_)).Times(1); | 384 EXPECT_CALL(*input, AfterWriteFrames(_)).Times(1); |
| 368 } | 385 } |
| 369 | 386 |
| 370 // TODO(slan): Verify that the data is mixed properly with math. | 387 // TODO(slan): Verify that the data is mixed properly with math. |
| 371 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 512)).Times(1); | 388 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 512)).Times(1); |
| 372 mixer->WriteFramesForTest(); | 389 mixer->WriteFramesForTest(); |
| 373 | 390 |
| 374 // Make two of these streams non-primary, and exhaust a non-primary stream. | 391 // Make two of these streams non-primary, and exhaust a non-primary stream. |
| 375 // All non-empty streams shall be polled for data and the mixer shall write | 392 // All non-empty streams shall be polled for data and the mixer shall write |
| 376 // to ALSA. | 393 // to ALSA. |
| 377 inputs[1]->SetPrimary(false); | 394 inputs[1]->SetPrimary(false); |
| 378 inputs[1]->SetMaxReadSize(0); | 395 inputs[1]->SetMaxReadSize(0); |
| 379 inputs[2]->SetPrimary(false); | 396 inputs[2]->SetPrimary(false); |
| 380 for (auto* input : inputs) { | 397 for (auto* input : inputs) { |
| 381 if (input != inputs[1]) | 398 if (input != inputs[1]) { |
| 382 EXPECT_CALL(*input, GetResampledData(_, 1024)).Times(1); | 399 EXPECT_CALL(*input, GetResampledData(_, 1024)).Times(1); |
| 400 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, 1024, _)) |
| 401 .Times(kNumChannels); |
| 402 } |
| 383 EXPECT_CALL(*input, AfterWriteFrames(_)).Times(1); | 403 EXPECT_CALL(*input, AfterWriteFrames(_)).Times(1); |
| 384 } | 404 } |
| 385 // Note that the new smallest stream shall dictate the length of the write. | 405 // Note that the new smallest stream shall dictate the length of the write. |
| 386 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 1024)).Times(1); | 406 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 1024)).Times(1); |
| 387 mixer->WriteFramesForTest(); | 407 mixer->WriteFramesForTest(); |
| 388 | 408 |
| 389 // Exhaust a primary stream. No streams shall be polled for data, and no | 409 // Exhaust a primary stream. No streams shall be polled for data, and no |
| 390 // data shall be written to ALSA. | 410 // data shall be written to ALSA. |
| 391 inputs[0]->SetMaxReadSize(0); | 411 inputs[0]->SetMaxReadSize(0); |
| 392 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, _)).Times(0); | 412 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, _)).Times(0); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 403 EXPECT_EQ(StreamMixerAlsa::kStateNormalPlayback, mixer->state()); | 423 EXPECT_EQ(StreamMixerAlsa::kStateNormalPlayback, mixer->state()); |
| 404 | 424 |
| 405 // Populate the stream with data. | 425 // Populate the stream with data. |
| 406 const int kNumFrames = 32; | 426 const int kNumFrames = 32; |
| 407 input->SetData(GetTestData(0)); | 427 input->SetData(GetTestData(0)); |
| 408 | 428 |
| 409 ASSERT_EQ(mock_alsa()->data().size(), 0u); | 429 ASSERT_EQ(mock_alsa()->data().size(), 0u); |
| 410 | 430 |
| 411 // Write the stream to ALSA. | 431 // Write the stream to ALSA. |
| 412 EXPECT_CALL(*input, GetResampledData(_, kNumFrames)); | 432 EXPECT_CALL(*input, GetResampledData(_, kNumFrames)); |
| 433 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, kNumFrames, _)) |
| 434 .Times(kNumChannels); |
| 413 EXPECT_CALL(*input, AfterWriteFrames(_)); | 435 EXPECT_CALL(*input, AfterWriteFrames(_)); |
| 414 mixer->WriteFramesForTest(); | 436 mixer->WriteFramesForTest(); |
| 415 | 437 |
| 416 // Get the actual stream rendered to ALSA, and compare it against the | 438 // Get the actual stream rendered to ALSA, and compare it against the |
| 417 // expected stream. The stream should match exactly. | 439 // expected stream. The stream should match exactly. |
| 418 auto actual = ::media::AudioBus::Create(kNumChannels, kNumFrames); | 440 auto actual = ::media::AudioBus::Create(kNumChannels, kNumFrames); |
| 419 ASSERT_GT(mock_alsa()->data().size(), 0u); | 441 ASSERT_GT(mock_alsa()->data().size(), 0u); |
| 420 actual->FromInterleaved( | 442 actual->FromInterleaved( |
| 421 &(mock_alsa()->data()[0]), kNumFrames, kBytesPerSample); | 443 &(mock_alsa()->data()[0]), kNumFrames, kBytesPerSample); |
| 422 CompareAudioData(input->data(), *actual); | 444 CompareAudioData(input->data(), *actual); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 435 const int kNumFrames = 32; | 457 const int kNumFrames = 32; |
| 436 ASSERT_EQ(sizeof(kTestData[0]), kNumChannels * kNumFrames * kBytesPerSample); | 458 ASSERT_EQ(sizeof(kTestData[0]), kNumChannels * kNumFrames * kBytesPerSample); |
| 437 auto data = GetTestData(0); | 459 auto data = GetTestData(0); |
| 438 input->SetData(std::move(data)); | 460 input->SetData(std::move(data)); |
| 439 | 461 |
| 440 // Set a volume multiplier on the stream. | 462 // Set a volume multiplier on the stream. |
| 441 input->SetVolumeMultiplier(0.75); | 463 input->SetVolumeMultiplier(0.75); |
| 442 | 464 |
| 443 // Write the stream to ALSA. | 465 // Write the stream to ALSA. |
| 444 EXPECT_CALL(*input, GetResampledData(_, kNumFrames)); | 466 EXPECT_CALL(*input, GetResampledData(_, kNumFrames)); |
| 467 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, kNumFrames, _)) |
| 468 .Times(kNumChannels); |
| 445 EXPECT_CALL(*input, AfterWriteFrames(_)); | 469 EXPECT_CALL(*input, AfterWriteFrames(_)); |
| 446 mixer->WriteFramesForTest(); | 470 mixer->WriteFramesForTest(); |
| 447 | 471 |
| 448 // Check that the retrieved stream is scaled correctly. | 472 // Check that the retrieved stream is scaled correctly. |
| 449 auto actual = ::media::AudioBus::Create(kNumChannels, kNumFrames); | 473 auto actual = ::media::AudioBus::Create(kNumChannels, kNumFrames); |
| 450 actual->FromInterleaved( | 474 actual->FromInterleaved( |
| 451 &(mock_alsa()->data()[0]), kNumFrames, kBytesPerSample); | 475 &(mock_alsa()->data()[0]), kNumFrames, kBytesPerSample); |
| 452 auto expected = GetMixedAudioData(input); | 476 auto expected = GetMixedAudioData(input); |
| 453 CompareAudioData(*expected, *actual); | 477 CompareAudioData(*expected, *actual); |
| 454 } | 478 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 467 for (size_t i = 0; i < inputs.size(); ++i) { | 491 for (size_t i = 0; i < inputs.size(); ++i) { |
| 468 EXPECT_CALL(*inputs[i], Initialize(_)).Times(1); | 492 EXPECT_CALL(*inputs[i], Initialize(_)).Times(1); |
| 469 mixer->AddInput(base::WrapUnique(inputs[i])); | 493 mixer->AddInput(base::WrapUnique(inputs[i])); |
| 470 } | 494 } |
| 471 | 495 |
| 472 // Poll the inputs for data. | 496 // Poll the inputs for data. |
| 473 const int kNumFrames = 32; | 497 const int kNumFrames = 32; |
| 474 for (size_t i = 0; i < inputs.size(); ++i) { | 498 for (size_t i = 0; i < inputs.size(); ++i) { |
| 475 inputs[i]->SetData(GetTestData(i)); | 499 inputs[i]->SetData(GetTestData(i)); |
| 476 EXPECT_CALL(*inputs[i], GetResampledData(_, kNumFrames)); | 500 EXPECT_CALL(*inputs[i], GetResampledData(_, kNumFrames)); |
| 501 EXPECT_CALL(*inputs[i], VolumeScaleAccumulate(_, _, kNumFrames, _)) |
| 502 .Times(kNumChannels); |
| 477 EXPECT_CALL(*inputs[i], AfterWriteFrames(_)); | 503 EXPECT_CALL(*inputs[i], AfterWriteFrames(_)); |
| 478 } | 504 } |
| 479 | 505 |
| 480 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); | 506 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); |
| 481 mixer->WriteFramesForTest(); | 507 mixer->WriteFramesForTest(); |
| 482 | 508 |
| 483 // Mix the inputs manually. | 509 // Mix the inputs manually. |
| 484 auto expected = GetMixedAudioData(inputs); | 510 auto expected = GetMixedAudioData(inputs); |
| 485 | 511 |
| 486 // Get the actual stream rendered to ALSA, and compare it against the | 512 // Get the actual stream rendered to ALSA, and compare it against the |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 0.0, 0.0, | 565 0.0, 0.0, |
| 540 kMaxSample, kMaxSample, | 566 kMaxSample, kMaxSample, |
| 541 0.0, 0.0, | 567 0.0, 0.0, |
| 542 }; | 568 }; |
| 543 | 569 |
| 544 for (size_t i = 0; i < inputs.size(); ++i) { | 570 for (size_t i = 0; i < inputs.size(); ++i) { |
| 545 auto test_data = ::media::AudioBus::Create(kNumChannels, kNumFrames); | 571 auto test_data = ::media::AudioBus::Create(kNumChannels, kNumFrames); |
| 546 test_data->FromInterleaved(kEdgeData[i], kNumFrames, kBytesPerSample); | 572 test_data->FromInterleaved(kEdgeData[i], kNumFrames, kBytesPerSample); |
| 547 inputs[i]->SetData(std::move(test_data)); | 573 inputs[i]->SetData(std::move(test_data)); |
| 548 EXPECT_CALL(*inputs[i], GetResampledData(_, kNumFrames)); | 574 EXPECT_CALL(*inputs[i], GetResampledData(_, kNumFrames)); |
| 575 EXPECT_CALL(*inputs[i], VolumeScaleAccumulate(_, _, kNumFrames, _)) |
| 576 .Times(kNumChannels); |
| 549 EXPECT_CALL(*inputs[i], AfterWriteFrames(_)); | 577 EXPECT_CALL(*inputs[i], AfterWriteFrames(_)); |
| 550 } | 578 } |
| 551 | 579 |
| 552 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); | 580 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); |
| 553 mixer->WriteFramesForTest(); | 581 mixer->WriteFramesForTest(); |
| 554 | 582 |
| 555 // Use the hand-calculated results above. | 583 // Use the hand-calculated results above. |
| 556 auto expected = ::media::AudioBus::Create(kNumChannels, kNumFrames); | 584 auto expected = ::media::AudioBus::Create(kNumChannels, kNumFrames); |
| 557 expected->FromInterleaved(kResult, kNumFrames, kBytesPerSample); | 585 expected->FromInterleaved(kResult, kNumFrames, kBytesPerSample); |
| 558 | 586 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 569 input->SetPaused(false); | 597 input->SetPaused(false); |
| 570 | 598 |
| 571 StreamMixerAlsa* mixer = StreamMixerAlsa::Get(); | 599 StreamMixerAlsa* mixer = StreamMixerAlsa::Get(); |
| 572 EXPECT_CALL(*input, Initialize(_)).Times(1); | 600 EXPECT_CALL(*input, Initialize(_)).Times(1); |
| 573 mixer->AddInput(base::WrapUnique(input)); | 601 mixer->AddInput(base::WrapUnique(input)); |
| 574 EXPECT_EQ(StreamMixerAlsa::kStateNormalPlayback, mixer->state()); | 602 EXPECT_EQ(StreamMixerAlsa::kStateNormalPlayback, mixer->state()); |
| 575 | 603 |
| 576 // The input stream will provide buffers of several different lengths. | 604 // The input stream will provide buffers of several different lengths. |
| 577 input->SetMaxReadSize(7); | 605 input->SetMaxReadSize(7); |
| 578 EXPECT_CALL(*input, GetResampledData(_, 7)); | 606 EXPECT_CALL(*input, GetResampledData(_, 7)); |
| 607 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, 7, _)).Times(kNumChannels); |
| 579 EXPECT_CALL(*input, AfterWriteFrames(_)); | 608 EXPECT_CALL(*input, AfterWriteFrames(_)); |
| 580 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 7)).Times(1); | 609 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 7)).Times(1); |
| 581 mixer->WriteFramesForTest(); | 610 mixer->WriteFramesForTest(); |
| 582 | 611 |
| 583 input->SetMaxReadSize(100); | 612 input->SetMaxReadSize(100); |
| 584 EXPECT_CALL(*input, GetResampledData(_, 100)); | 613 EXPECT_CALL(*input, GetResampledData(_, 100)); |
| 614 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, 100, _)).Times(kNumChannels); |
| 585 EXPECT_CALL(*input, AfterWriteFrames(_)); | 615 EXPECT_CALL(*input, AfterWriteFrames(_)); |
| 586 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 100)).Times(1); | 616 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 100)).Times(1); |
| 587 mixer->WriteFramesForTest(); | 617 mixer->WriteFramesForTest(); |
| 588 | 618 |
| 589 input->SetMaxReadSize(32); | 619 input->SetMaxReadSize(32); |
| 590 EXPECT_CALL(*input, GetResampledData(_, 32)); | 620 EXPECT_CALL(*input, GetResampledData(_, 32)); |
| 621 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, 32, _)).Times(kNumChannels); |
| 591 EXPECT_CALL(*input, AfterWriteFrames(_)); | 622 EXPECT_CALL(*input, AfterWriteFrames(_)); |
| 592 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 32)).Times(1); | 623 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 32)).Times(1); |
| 593 mixer->WriteFramesForTest(); | 624 mixer->WriteFramesForTest(); |
| 594 | 625 |
| 595 input->SetMaxReadSize(1024); | 626 input->SetMaxReadSize(1024); |
| 596 EXPECT_CALL(*input, GetResampledData(_, 1024)); | 627 EXPECT_CALL(*input, GetResampledData(_, 1024)); |
| 628 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, 1024, _)).Times(kNumChannels); |
| 597 EXPECT_CALL(*input, AfterWriteFrames(_)); | 629 EXPECT_CALL(*input, AfterWriteFrames(_)); |
| 598 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 1024)).Times(1); | 630 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, 1024)).Times(1); |
| 599 mixer->WriteFramesForTest(); | 631 mixer->WriteFramesForTest(); |
| 600 } | 632 } |
| 601 | 633 |
| 602 TEST_F(StreamMixerAlsaTest, StuckStreamWithoutUnderrun) { | 634 TEST_F(StreamMixerAlsaTest, StuckStreamWithoutUnderrun) { |
| 603 // Create a group of input streams. | 635 // Create a group of input streams. |
| 604 std::vector<testing::StrictMock<MockInputQueue>*> inputs; | 636 std::vector<testing::StrictMock<MockInputQueue>*> inputs; |
| 605 const int kNumInputs = 2; | 637 const int kNumInputs = 2; |
| 606 for (int i = 0; i < kNumInputs; ++i) { | 638 for (int i = 0; i < kNumInputs; ++i) { |
| 607 inputs.push_back( | 639 inputs.push_back( |
| 608 new testing::StrictMock<MockInputQueue>(kTestSamplesPerSecond)); | 640 new testing::StrictMock<MockInputQueue>(kTestSamplesPerSecond)); |
| 609 inputs.back()->SetMaxReadSize(0); | 641 inputs.back()->SetMaxReadSize(0); |
| 610 inputs.back()->SetPaused(false); | 642 inputs.back()->SetPaused(false); |
| 611 } | 643 } |
| 612 | 644 |
| 613 StreamMixerAlsa* mixer = StreamMixerAlsa::Get(); | 645 StreamMixerAlsa* mixer = StreamMixerAlsa::Get(); |
| 614 for (size_t i = 0; i < inputs.size(); ++i) { | 646 for (size_t i = 0; i < inputs.size(); ++i) { |
| 615 EXPECT_CALL(*inputs[i], Initialize(_)).Times(1); | 647 EXPECT_CALL(*inputs[i], Initialize(_)).Times(1); |
| 616 mixer->AddInput(base::WrapUnique(inputs[i])); | 648 mixer->AddInput(base::WrapUnique(inputs[i])); |
| 617 } | 649 } |
| 618 | 650 |
| 619 // Poll the inputs for data. Should not pull any data since one input has none | 651 // Poll the inputs for data. Should not pull any data since one input has none |
| 620 // to give. | 652 // to give. |
| 621 inputs[0]->SetData(GetTestData(0)); | 653 inputs[0]->SetData(GetTestData(0)); |
| 622 EXPECT_CALL(*inputs[0], GetResampledData(_, _)).Times(0); | 654 EXPECT_CALL(*inputs[0], GetResampledData(_, _)).Times(0); |
| 655 EXPECT_CALL(*inputs[0], VolumeScaleAccumulate(_, _, _, _)).Times(0); |
| 623 EXPECT_CALL(*inputs[0], AfterWriteFrames(_)).Times(0); | 656 EXPECT_CALL(*inputs[0], AfterWriteFrames(_)).Times(0); |
| 624 | 657 |
| 625 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, _)).Times(0); | 658 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, _)).Times(0); |
| 626 mixer->WriteFramesForTest(); | 659 mixer->WriteFramesForTest(); |
| 627 } | 660 } |
| 628 | 661 |
| 629 TEST_F(StreamMixerAlsaTest, StuckStreamWithUnderrun) { | 662 TEST_F(StreamMixerAlsaTest, StuckStreamWithUnderrun) { |
| 630 // Create a group of input streams. | 663 // Create a group of input streams. |
| 631 std::vector<testing::StrictMock<MockInputQueue>*> inputs; | 664 std::vector<testing::StrictMock<MockInputQueue>*> inputs; |
| 632 const int kNumInputs = 2; | 665 const int kNumInputs = 2; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 645 | 678 |
| 646 mock_alsa()->set_state(SND_PCM_STATE_XRUN); | 679 mock_alsa()->set_state(SND_PCM_STATE_XRUN); |
| 647 | 680 |
| 648 // Poll the inputs for data. The first input will provide data (since the | 681 // Poll the inputs for data. The first input will provide data (since the |
| 649 // output is in an underrun condition); the second input can't provide any | 682 // output is in an underrun condition); the second input can't provide any |
| 650 // data, but AfterWriteFrames() will still be called on it so that it has the | 683 // data, but AfterWriteFrames() will still be called on it so that it has the |
| 651 // correct rendering delay. | 684 // correct rendering delay. |
| 652 const int kNumFrames = 32; | 685 const int kNumFrames = 32; |
| 653 inputs[0]->SetData(GetTestData(0)); | 686 inputs[0]->SetData(GetTestData(0)); |
| 654 EXPECT_CALL(*inputs[0], GetResampledData(_, kNumFrames)); | 687 EXPECT_CALL(*inputs[0], GetResampledData(_, kNumFrames)); |
| 688 EXPECT_CALL(*inputs[0], VolumeScaleAccumulate(_, _, kNumFrames, _)) |
| 689 .Times(kNumChannels); |
| 655 EXPECT_CALL(*inputs[0], AfterWriteFrames(_)); | 690 EXPECT_CALL(*inputs[0], AfterWriteFrames(_)); |
| 656 EXPECT_CALL(*inputs[1], GetResampledData(_, _)).Times(0); | 691 EXPECT_CALL(*inputs[1], GetResampledData(_, _)).Times(0); |
| 692 EXPECT_CALL(*inputs[1], VolumeScaleAccumulate(_, _, kNumFrames, _)).Times(0); |
| 657 EXPECT_CALL(*inputs[1], AfterWriteFrames(_)); | 693 EXPECT_CALL(*inputs[1], AfterWriteFrames(_)); |
| 658 | 694 |
| 659 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); | 695 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); |
| 660 mixer->WriteFramesForTest(); | 696 mixer->WriteFramesForTest(); |
| 661 } | 697 } |
| 662 | 698 |
| 663 TEST_F(StreamMixerAlsaTest, StuckStreamWithLowBuffer) { | 699 TEST_F(StreamMixerAlsaTest, StuckStreamWithLowBuffer) { |
| 664 // Create a group of input streams. | 700 // Create a group of input streams. |
| 665 std::vector<testing::StrictMock<MockInputQueue>*> inputs; | 701 std::vector<testing::StrictMock<MockInputQueue>*> inputs; |
| 666 const int kNumInputs = 2; | 702 const int kNumInputs = 2; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 679 | 715 |
| 680 mock_alsa()->set_avail(4086); | 716 mock_alsa()->set_avail(4086); |
| 681 | 717 |
| 682 // Poll the inputs for data. The first input will provide data (since the | 718 // Poll the inputs for data. The first input will provide data (since the |
| 683 // output is in an low buffer condition); the second input can't provide any | 719 // output is in an low buffer condition); the second input can't provide any |
| 684 // data, but AfterWriteFrames() will still be called on it so that it has the | 720 // data, but AfterWriteFrames() will still be called on it so that it has the |
| 685 // correct rendering delay. | 721 // correct rendering delay. |
| 686 const int kNumFrames = 32; | 722 const int kNumFrames = 32; |
| 687 inputs[0]->SetData(GetTestData(0)); | 723 inputs[0]->SetData(GetTestData(0)); |
| 688 EXPECT_CALL(*inputs[0], GetResampledData(_, kNumFrames)); | 724 EXPECT_CALL(*inputs[0], GetResampledData(_, kNumFrames)); |
| 725 EXPECT_CALL(*inputs[0], VolumeScaleAccumulate(_, _, kNumFrames, _)) |
| 726 .Times(kNumChannels); |
| 689 EXPECT_CALL(*inputs[0], AfterWriteFrames(_)); | 727 EXPECT_CALL(*inputs[0], AfterWriteFrames(_)); |
| 690 EXPECT_CALL(*inputs[1], GetResampledData(_, _)).Times(0); | 728 EXPECT_CALL(*inputs[1], GetResampledData(_, _)).Times(0); |
| 729 EXPECT_CALL(*inputs[1], VolumeScaleAccumulate(_, _, _, _)).Times(0); |
| 691 EXPECT_CALL(*inputs[1], AfterWriteFrames(_)); | 730 EXPECT_CALL(*inputs[1], AfterWriteFrames(_)); |
| 692 | 731 |
| 693 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); | 732 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); |
| 694 mixer->WriteFramesForTest(); | 733 mixer->WriteFramesForTest(); |
| 695 } | 734 } |
| 696 | 735 |
| 697 } // namespace media | 736 } // namespace media |
| 698 } // namespace chromecast | 737 } // namespace chromecast |
| OLD | NEW |