Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(598)

Side by Side Diff: chromecast/media/cma/backend/alsa/stream_mixer_alsa_unittest.cc

Issue 2722833003: Reland of [Chromecast] Process streams with different post-processing. (Closed)
Patch Set: Handle empty device_id as DefaultDevice Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/audio/audio_device_description.h"
18 #include "media/base/audio_bus.h" 19 #include "media/base/audio_bus.h"
19 #include "media/base/vector_math.h" 20 #include "media/base/vector_math.h"
20 #include "testing/gmock/include/gmock/gmock.h" 21 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
22 23
23 using testing::_; 24 using testing::_;
24 25
25 namespace chromecast { 26 namespace chromecast {
26 namespace media { 27 namespace media {
27 28
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 std::unique_ptr<::media::AudioBus> GetTestData(size_t index) { 120 std::unique_ptr<::media::AudioBus> GetTestData(size_t index) {
120 CHECK_LT(index, NUM_DATA_SETS); 121 CHECK_LT(index, NUM_DATA_SETS);
121 int frames = NUM_SAMPLES / kNumChannels; 122 int frames = NUM_SAMPLES / kNumChannels;
122 auto data = ::media::AudioBus::Create(kNumChannels, frames); 123 auto data = ::media::AudioBus::Create(kNumChannels, frames);
123 data->FromInterleaved(kTestData[index], frames, kBytesPerSample); 124 data->FromInterleaved(kTestData[index], frames, kBytesPerSample);
124 return data; 125 return data;
125 } 126 }
126 127
127 class MockInputQueue : public StreamMixerAlsa::InputQueue { 128 class MockInputQueue : public StreamMixerAlsa::InputQueue {
128 public: 129 public:
129 explicit MockInputQueue(int samples_per_second) 130 explicit MockInputQueue(int samples_per_second,
131 const std::string& device_id =
132 ::media::AudioDeviceDescription::kDefaultDeviceId)
130 : paused_(true), 133 : paused_(true),
131 samples_per_second_(samples_per_second), 134 samples_per_second_(samples_per_second),
132 max_read_size_(kTestMaxReadSize), 135 max_read_size_(kTestMaxReadSize),
133 multiplier_(1.0), 136 multiplier_(1.0),
134 primary_(true), 137 primary_(true),
135 deleting_(false) { 138 deleting_(false),
139 device_id_(device_id),
140 filter_group_(nullptr) {
136 ON_CALL(*this, GetResampledData(_, _)).WillByDefault( 141 ON_CALL(*this, GetResampledData(_, _)).WillByDefault(
137 testing::Invoke(this, &MockInputQueue::DoGetResampledData)); 142 testing::Invoke(this, &MockInputQueue::DoGetResampledData));
138 ON_CALL(*this, VolumeScaleAccumulate(_, _, _, _)).WillByDefault( 143 ON_CALL(*this, VolumeScaleAccumulate(_, _, _, _)).WillByDefault(
139 testing::Invoke(this, &MockInputQueue::DoVolumeScaleAccumulate)); 144 testing::Invoke(this, &MockInputQueue::DoVolumeScaleAccumulate));
140 ON_CALL(*this, PrepareToDelete(_)).WillByDefault( 145 ON_CALL(*this, PrepareToDelete(_)).WillByDefault(
141 testing::Invoke(this, &MockInputQueue::DoPrepareToDelete)); 146 testing::Invoke(this, &MockInputQueue::DoPrepareToDelete));
142 } 147 }
143 ~MockInputQueue() override {} 148 ~MockInputQueue() override {}
144 149
145 bool paused() const { return paused_; } 150 bool paused() const { return paused_; }
146 151
147 // StreamMixerAlsa::InputQueue implementation: 152 // StreamMixerAlsa::InputQueue implementation:
148 int input_samples_per_second() const override { return samples_per_second_; } 153 int input_samples_per_second() const override { return samples_per_second_; }
149 bool primary() const override { return primary_; } 154 bool primary() const override { return primary_; }
150 bool IsDeleting() const override { return deleting_; } 155 bool IsDeleting() const override { return deleting_; }
151 MOCK_METHOD1(Initialize, 156 MOCK_METHOD1(Initialize,
152 void(const MediaPipelineBackendAlsa::RenderingDelay& 157 void(const MediaPipelineBackendAlsa::RenderingDelay&
153 mixer_rendering_delay)); 158 mixer_rendering_delay));
159 std::string device_id() const override { return device_id_; }
160 void set_filter_group(FilterGroup* group) override { filter_group_ = group; }
161 FilterGroup* filter_group() override { return filter_group_; }
154 int MaxReadSize() override { return max_read_size_; } 162 int MaxReadSize() override { return max_read_size_; }
155 MOCK_METHOD2(GetResampledData, void(::media::AudioBus* dest, int frames)); 163 MOCK_METHOD2(GetResampledData, void(::media::AudioBus* dest, int frames));
156 MOCK_METHOD4( 164 MOCK_METHOD4(
157 VolumeScaleAccumulate, 165 VolumeScaleAccumulate,
158 void(bool repeat_transition, const float* src, int frames, float* dest)); 166 void(bool repeat_transition, const float* src, int frames, float* dest));
159 MOCK_METHOD0(OnSkipped, void()); 167 MOCK_METHOD0(OnSkipped, void());
160 MOCK_METHOD1(AfterWriteFrames, 168 MOCK_METHOD1(AfterWriteFrames,
161 void(const MediaPipelineBackendAlsa::RenderingDelay& 169 void(const MediaPipelineBackendAlsa::RenderingDelay&
162 mixer_rendering_delay)); 170 mixer_rendering_delay));
163 MOCK_METHOD1(SignalError, void(StreamMixerAlsaInput::MixerError error)); 171 MOCK_METHOD1(SignalError, void(StreamMixerAlsaInput::MixerError error));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 deleting_ = true; 215 deleting_ = true;
208 delete_cb.Run(this); 216 delete_cb.Run(this);
209 } 217 }
210 218
211 bool paused_; 219 bool paused_;
212 int samples_per_second_; 220 int samples_per_second_;
213 int max_read_size_; 221 int max_read_size_;
214 float multiplier_; 222 float multiplier_;
215 bool primary_; 223 bool primary_;
216 bool deleting_; 224 bool deleting_;
225 const std::string device_id_;
226 FilterGroup* filter_group_;
227
217 std::unique_ptr<::media::AudioBus> data_; 228 std::unique_ptr<::media::AudioBus> data_;
218 229
219 DISALLOW_COPY_AND_ASSIGN(MockInputQueue); 230 DISALLOW_COPY_AND_ASSIGN(MockInputQueue);
220 }; 231 };
221 232
222 // Given |inputs|, returns mixed audio data according to the mixing method used 233 // Given |inputs|, returns mixed audio data according to the mixing method used
223 // by the mixer. 234 // by the mixer.
224 std::unique_ptr<::media::AudioBus> GetMixedAudioData( 235 std::unique_ptr<::media::AudioBus> GetMixedAudioData(
225 const std::vector<testing::StrictMock<MockInputQueue>*>& inputs) { 236 const std::vector<testing::StrictMock<MockInputQueue>*>& inputs) {
226 int read_size = std::numeric_limits<int>::max(); 237 int read_size = std::numeric_limits<int>::max();
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 518
508 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); 519 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1);
509 mixer->WriteFramesForTest(); 520 mixer->WriteFramesForTest();
510 521
511 // Mix the inputs manually. 522 // Mix the inputs manually.
512 auto expected = GetMixedAudioData(inputs); 523 auto expected = GetMixedAudioData(inputs);
513 524
514 // Get the actual stream rendered to ALSA, and compare it against the 525 // Get the actual stream rendered to ALSA, and compare it against the
515 // expected stream. The stream should match exactly. 526 // expected stream. The stream should match exactly.
516 auto actual = ::media::AudioBus::Create(kNumChannels, kNumFrames); 527 auto actual = ::media::AudioBus::Create(kNumChannels, kNumFrames);
528 actual->FromInterleaved(&(mock_alsa()->data()[0]), kNumFrames,
529 kBytesPerSample);
530 CompareAudioData(*expected, *actual);
531 }
532
533 TEST_F(StreamMixerAlsaTest, TwoUnscaledStreamsWithDifferentIdsMixProperly) {
534 // Create a group of input streams.
535 std::vector<testing::StrictMock<MockInputQueue>*> inputs;
536 inputs.push_back(new testing::StrictMock<MockInputQueue>(
537 kTestSamplesPerSecond,
538 ::media::AudioDeviceDescription::kDefaultDeviceId));
539 inputs.back()->SetPaused(false);
540 inputs.push_back(new testing::StrictMock<MockInputQueue>(
541 kTestSamplesPerSecond,
542 ::media::AudioDeviceDescription::kCommunicationsDeviceId));
543 inputs.back()->SetPaused(false);
544
545 StreamMixerAlsa* mixer = StreamMixerAlsa::Get();
546 for (size_t i = 0; i < inputs.size(); ++i) {
547 EXPECT_CALL(*inputs[i], Initialize(_)).Times(1);
548 mixer->AddInput(base::WrapUnique(inputs[i]));
549 }
550
551 // Poll the inputs for data.
552 const int kNumFrames = 32;
553 for (size_t i = 0; i < inputs.size(); ++i) {
554 inputs[i]->SetData(GetTestData(i));
555 EXPECT_CALL(*inputs[i], GetResampledData(_, kNumFrames));
556 EXPECT_CALL(*inputs[i], VolumeScaleAccumulate(_, _, kNumFrames, _))
557 .Times(kNumChannels);
558 EXPECT_CALL(*inputs[i], AfterWriteFrames(_));
559 }
560
561 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1);
562 mixer->WriteFramesForTest();
563
564 // Mix the inputs manually.
565 auto expected = GetMixedAudioData(inputs);
566
567 // Get the actual stream rendered to ALSA, and compare it against the
568 // expected stream. The stream should match exactly.
569 auto actual = ::media::AudioBus::Create(kNumChannels, kNumFrames);
517 actual->FromInterleaved( 570 actual->FromInterleaved(
518 &(mock_alsa()->data()[0]), kNumFrames, kBytesPerSample); 571 &(mock_alsa()->data()[0]), kNumFrames, kBytesPerSample);
519 CompareAudioData(*expected, *actual); 572 CompareAudioData(*expected, *actual);
520 } 573 }
521 574
522 TEST_F(StreamMixerAlsaTest, TwoUnscaledStreamsMixProperlyWithEdgeCases) { 575 TEST_F(StreamMixerAlsaTest, TwoUnscaledStreamsMixProperlyWithEdgeCases) {
523 // Create a group of input streams. 576 // Create a group of input streams.
524 std::vector<testing::StrictMock<MockInputQueue>*> inputs; 577 std::vector<testing::StrictMock<MockInputQueue>*> inputs;
525 const int kNumInputs = 2; 578 const int kNumInputs = 2;
526 for (int i = 0; i < kNumInputs; ++i) { 579 for (int i = 0; i < kNumInputs; ++i) {
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 EXPECT_CALL(*inputs[1], VolumeScaleAccumulate(_, _, _, _)).Times(0); 785 EXPECT_CALL(*inputs[1], VolumeScaleAccumulate(_, _, _, _)).Times(0);
733 EXPECT_CALL(*inputs[1], OnSkipped()); 786 EXPECT_CALL(*inputs[1], OnSkipped());
734 EXPECT_CALL(*inputs[1], AfterWriteFrames(_)); 787 EXPECT_CALL(*inputs[1], AfterWriteFrames(_));
735 788
736 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); 789 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1);
737 mixer->WriteFramesForTest(); 790 mixer->WriteFramesForTest();
738 } 791 }
739 792
740 } // namespace media 793 } // namespace media
741 } // namespace chromecast 794 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698