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

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

Issue 2847673002: [Chromecast] Complete PostProcessingPipeline changes (Closed)
Patch Set: Add more test Created 3 years, 7 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 <unordered_map>
10 #include <utility> 11 #include <utility>
11 12
12 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
13 #include "base/memory/scoped_vector.h" 14 #include "base/memory/scoped_vector.h"
14 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h" 16 #include "base/run_loop.h"
16 #include "base/threading/thread_task_runner_handle.h" 17 #include "base/threading/thread_task_runner_handle.h"
18 #include "base/values.h"
17 #include "chromecast/media/cma/backend/alsa/mock_alsa_wrapper.h" 19 #include "chromecast/media/cma/backend/alsa/mock_alsa_wrapper.h"
20 #include "chromecast/media/cma/backend/alsa/post_processing_pipeline.h"
18 #include "media/audio/audio_device_description.h" 21 #include "media/audio/audio_device_description.h"
19 #include "media/base/audio_bus.h" 22 #include "media/base/audio_bus.h"
20 #include "media/base/vector_math.h" 23 #include "media/base/vector_math.h"
21 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
23 26
24 using testing::_; 27 using testing::_;
25 28
26 namespace chromecast { 29 namespace chromecast {
27 namespace media { 30 namespace media {
28 31
29 namespace { 32 namespace {
30 33
31 // Testing constants that are common to multiple test cases. 34 // Testing constants that are common to multiple test cases.
32 const size_t kBytesPerSample = sizeof(int32_t); 35 const size_t kBytesPerSample = sizeof(int32_t);
33 const int kNumChannels = 2; 36 const int kNumChannels = 2;
34 const int kTestMaxReadSize = 4096; 37 const int kTestMaxReadSize = 4096;
35 38
36 // kTestSamplesPerSecond needs to be higher than kLowSampleRateCutoff for the 39 // kTestSamplesPerSecond needs to be higher than kLowSampleRateCutoff for the
37 // mixer to use it. 40 // mixer to use it.
38 const int kTestSamplesPerSecond = 48000; 41 const int kTestSamplesPerSecond = 48000;
39 42
40 // Stream mixer alsa will never pull more than this many frames at a time. 43 // Stream mixer alsa will never pull more than this many frames at a time.
41 const int kMaxWriteSizeMs = 20; 44 const int kMaxWriteSizeMs = 20;
42 const int kMaxChunkSize = kTestSamplesPerSecond * kMaxWriteSizeMs / 1000; 45 const int kMaxChunkSize = kTestSamplesPerSecond * kMaxWriteSizeMs / 1000;
43 46
47 // The number of frames of silence to write (to prevent underrun) when no inputs
48 // are present.
49 const int kPreventUnderrunChunkSize = 512;
50
44 // This array holds |NUM_DATA_SETS| sets of arbitrary interleaved float data. 51 // This array holds |NUM_DATA_SETS| sets of arbitrary interleaved float data.
45 // Each set holds |NUM_SAMPLES| / kNumChannels frames of data. 52 // Each set holds |NUM_SAMPLES| / kNumChannels frames of data.
46 #define NUM_DATA_SETS 2u 53 #define NUM_DATA_SETS 2u
47 #define NUM_SAMPLES 64u 54 #define NUM_SAMPLES 64u
48 55
49 // Note: Test data should be represented as 32-bit integers and copied into 56 // Note: Test data should be represented as 32-bit integers and copied into
50 // ::media::AudioBus instances, rather than wrapping statically declared float 57 // ::media::AudioBus instances, rather than wrapping statically declared float
51 // arrays. The latter method is brittle, as ::media::AudioBus requires 16-bit 58 // arrays. The latter method is brittle, as ::media::AudioBus requires 16-bit
52 // alignment for internal data. 59 // alignment for internal data.
53 const int32_t kTestData[NUM_DATA_SETS][NUM_SAMPLES] = { 60 const int32_t kTestData[NUM_DATA_SETS][NUM_SAMPLES] = {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 1340850135, -1616803932, 120 1340850135, -1616803932,
114 -850779335, 1666492408, 121 -850779335, 1666492408,
115 1290349909, -492418001, 122 1290349909, -492418001,
116 659200170, -542374913, 123 659200170, -542374913,
117 -120005682, 1030923147, 124 -120005682, 1030923147,
118 -877887021, -870241979, 125 -877887021, -870241979,
119 1322678128, -344799975, 126 1322678128, -344799975,
120 } 127 }
121 }; 128 };
122 129
130 // Compensate for integer arithmatic errors.
131 const int kMaxDelayErrorUs = 2;
132
133 const char kDelayModuleSolib[] = "delay.so";
134
135 // Should match # of "processors" blocks below.
136 const int kNumPostProcessors = 5;
137 const char kTestPipelineJsonTemplate[] = R"json(
138 {
139 "output_streams": [{
140 "streams": [ "default" ],
141 "processors": [{
142 "processor": "%s",
143 "config": { "delay": %d }
144 }]
145 }, {
146 "streams": [ "assistant-tts" ],
147 "processors": [{
148 "processor": "%s",
149 "config": { "delay": %d }
150 }]
151 }, {
152 "streams": [ "communications" ],
153 "processors": []
154 }],
155 "mix": {
156 "processors": [{
157 "processor": "%s",
158 "config": { "delay": %d }
159 }]
160 },
161 "linearize": {
162 "processors": [{
163 "processor": "%s",
164 "config": { "delay": %d }
165 }]
166 }
167 }
168 )json";
169
170 const int kDefaultProcessorDelay = 10;
171 const int kTtsProcessorDelay = 100;
172 const int kMixProcessorDelay = 1000;
173 const int kLinearizeProcessorDelay = 10000;
174
123 // Return a scoped pointer filled with the data laid out at |index| above. 175 // Return a scoped pointer filled with the data laid out at |index| above.
124 std::unique_ptr<::media::AudioBus> GetTestData(size_t index) { 176 std::unique_ptr<::media::AudioBus> GetTestData(size_t index) {
125 CHECK_LT(index, NUM_DATA_SETS); 177 CHECK_LT(index, NUM_DATA_SETS);
126 int frames = NUM_SAMPLES / kNumChannels; 178 int frames = NUM_SAMPLES / kNumChannels;
127 auto data = ::media::AudioBus::Create(kNumChannels, frames); 179 auto data = ::media::AudioBus::Create(kNumChannels, frames);
128 data->FromInterleaved(kTestData[index], frames, kBytesPerSample); 180 data->FromInterleaved(kTestData[index], frames, kBytesPerSample);
129 return data; 181 return data;
130 } 182 }
131 183
132 class MockInputQueue : public StreamMixerAlsa::InputQueue { 184 class MockInputQueue : public StreamMixerAlsa::InputQueue {
133 public: 185 public:
134 explicit MockInputQueue(int samples_per_second, 186 MockInputQueue(int samples_per_second,
135 const std::string& device_id = 187 const std::string& device_id =
136 ::media::AudioDeviceDescription::kDefaultDeviceId) 188 ::media::AudioDeviceDescription::kDefaultDeviceId)
137 : paused_(true), 189 : paused_(true),
138 samples_per_second_(samples_per_second), 190 samples_per_second_(samples_per_second),
139 max_read_size_(kTestMaxReadSize), 191 max_read_size_(kTestMaxReadSize),
140 multiplier_(1.0), 192 multiplier_(1.0),
141 primary_(true), 193 primary_(true),
142 deleting_(false), 194 deleting_(false),
143 device_id_(device_id), 195 device_id_(device_id),
144 filter_group_(nullptr) { 196 filter_group_(nullptr) {
145 ON_CALL(*this, GetResampledData(_, _)).WillByDefault( 197 ON_CALL(*this, GetResampledData(_, _)).WillByDefault(
146 testing::Invoke(this, &MockInputQueue::DoGetResampledData)); 198 testing::Invoke(this, &MockInputQueue::DoGetResampledData));
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 bool primary_; 286 bool primary_;
235 bool deleting_; 287 bool deleting_;
236 const std::string device_id_; 288 const std::string device_id_;
237 FilterGroup* filter_group_; 289 FilterGroup* filter_group_;
238 290
239 std::unique_ptr<::media::AudioBus> data_; 291 std::unique_ptr<::media::AudioBus> data_;
240 292
241 DISALLOW_COPY_AND_ASSIGN(MockInputQueue); 293 DISALLOW_COPY_AND_ASSIGN(MockInputQueue);
242 }; 294 };
243 295
296 class MockPostProcessor : public PostProcessingPipeline {
297 public:
298 MockPostProcessor(const std::string& name,
299 const base::ListValue* filter_description_list,
300 int channels)
301 : name_(name) {
302 CHECK(instances_.insert({name_, this}).second);
303
304 if (!filter_description_list) {
305 // This happens for PostProcessingPipeline with no post-processors.
306 return;
307 }
308
309 // Parse |filter_description_list| for parameters.
310 for (size_t i = 0; i < filter_description_list->GetSize(); ++i) {
311 const base::DictionaryValue* description_dict;
312 CHECK(filter_description_list->GetDictionary(i, &description_dict));
313 std::string solib;
314 CHECK(description_dict->GetString("processor", &solib));
315 // This will initially be called with the actual pipeline on creation.
316 // Ignore and wait for the call to ResetPostProcessorsForTest.
317 if (solib == kDelayModuleSolib) {
318 const base::DictionaryValue* processor_config_dict;
319 CHECK(
320 description_dict->GetDictionary("config", &processor_config_dict));
321 int module_delay;
322 CHECK(processor_config_dict->GetInteger("delay", &module_delay));
323 rendering_delay_ += module_delay;
324 processor_config_dict->GetBoolean("ringing", &ringing_);
325 }
326 }
327 ON_CALL(*this, ProcessFrames(_, _, _, _))
328 .WillByDefault(
329 testing::Invoke(this, &MockPostProcessor::DoProcessFrames));
330 }
331 ~MockPostProcessor() override { instances_.erase(name_); }
332 MOCK_METHOD4(ProcessFrames,
333 int(const std::vector<float*>& data,
334 int num_frames,
335 float current_volume,
336 bool is_silence));
337 bool SetSampleRate(int sample_rate) override { return false; }
338 bool IsRinging() override { return ringing_; }
339 std::string name() const { return name_; }
340
341 static std::unordered_map<std::string, MockPostProcessor*>* instances() {
342 return &instances_;
343 }
344
345 private:
346 int DoProcessFrames(const std::vector<float*>& data,
347 int num_frames,
348 float current_volume,
349 bool is_sience) {
350 return rendering_delay_;
351 }
352
353 static std::unordered_map<std::string, MockPostProcessor*> instances_;
354 std::string name_;
355 int rendering_delay_ = 0;
356 bool ringing_ = false;
357
358 DISALLOW_COPY_AND_ASSIGN(MockPostProcessor);
359 };
360
361 std::unordered_map<std::string, MockPostProcessor*>
362 MockPostProcessor::instances_;
363
244 // Given |inputs|, returns mixed audio data according to the mixing method used 364 // Given |inputs|, returns mixed audio data according to the mixing method used
245 // by the mixer. 365 // by the mixer.
246 std::unique_ptr<::media::AudioBus> GetMixedAudioData( 366 std::unique_ptr<::media::AudioBus> GetMixedAudioData(
247 const std::vector<testing::StrictMock<MockInputQueue>*>& inputs) { 367 const std::vector<testing::StrictMock<MockInputQueue>*>& inputs) {
248 int read_size = std::numeric_limits<int>::max(); 368 int read_size = std::numeric_limits<int>::max();
249 for (auto* input : inputs) { 369 for (auto* input : inputs) {
250 CHECK(input); 370 CHECK(input);
251 read_size = std::min(input->MaxReadSize(), read_size); 371 read_size = std::min(input->MaxReadSize(), read_size);
252 } 372 }
253 373
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 ASSERT_EQ(expected.channels(), actual.channels()); 410 ASSERT_EQ(expected.channels(), actual.channels());
291 ASSERT_EQ(expected.frames(), actual.frames()); 411 ASSERT_EQ(expected.frames(), actual.frames());
292 for (int c = 0; c < expected.channels(); ++c) { 412 for (int c = 0; c < expected.channels(); ++c) {
293 const float* expected_data = expected.channel(c); 413 const float* expected_data = expected.channel(c);
294 const float* actual_data = actual.channel(c); 414 const float* actual_data = actual.channel(c);
295 for (int f = 0; f < expected.frames(); ++f) 415 for (int f = 0; f < expected.frames(); ++f)
296 ASSERT_FLOAT_EQ(*expected_data++, *actual_data++) << c << " " << f; 416 ASSERT_FLOAT_EQ(*expected_data++, *actual_data++) << c << " " << f;
297 } 417 }
298 } 418 }
299 419
420 // Check that MediaPipelineBackendAlsa::RenderingDelay.delay_microseconds is
421 // within kMaxDelayErrorUs of |delay|
422 MATCHER_P2(MatchDelay, delay, id, "") {
423 bool result = std::abs(arg.delay_microseconds - delay) < kMaxDelayErrorUs;
424 if (!result) {
425 LOG(ERROR) << "Expected delay_microseconds for " << id << " to be " << delay
426 << " but got " << arg.delay_microseconds;
427 }
428 return result;
429 }
430
431 // Convert a number of frames at kTestSamplesPerSecond to microseconds
432 int64_t FramesToDelayUs(int64_t frames) {
433 return frames * base::Time::kMicrosecondsPerSecond / kTestSamplesPerSecond;
434 }
435
300 } // namespace 436 } // namespace
301 437
438 std::unique_ptr<PostProcessingPipeline> PostProcessingPipeline::Create(
439 const std::string& name,
440 const base::ListValue* filter_description_list,
441 int channels) {
442 return base::MakeUnique<testing::NiceMock<MockPostProcessor>>(
443 name, filter_description_list, channels);
444 }
445
302 class StreamMixerAlsaTest : public testing::Test { 446 class StreamMixerAlsaTest : public testing::Test {
303 protected: 447 protected:
304 StreamMixerAlsaTest() 448 StreamMixerAlsaTest()
305 : message_loop_(new base::MessageLoop()), 449 : message_loop_(new base::MessageLoop()),
306 mock_alsa_(new testing::NiceMock<MockAlsaWrapper>()) { 450 mock_alsa_(new testing::NiceMock<MockAlsaWrapper>()) {
307 StreamMixerAlsa::MakeSingleThreadedForTest(); 451 StreamMixerAlsa::MakeSingleThreadedForTest();
308 StreamMixerAlsa::Get()->DisablePostProcessingForTest(); 452 char test_pipeline_json[sizeof(kTestPipelineJsonTemplate) * 2];
453 snprintf(test_pipeline_json, sizeof(test_pipeline_json),
454 kTestPipelineJsonTemplate, kDelayModuleSolib,
455 kDefaultProcessorDelay, kDelayModuleSolib, kTtsProcessorDelay,
456 kDelayModuleSolib, kMixProcessorDelay, kDelayModuleSolib,
457 kLinearizeProcessorDelay);
458 StreamMixerAlsa::Get()->ResetPostProcessorsForTest(test_pipeline_json);
459 CHECK_EQ(MockPostProcessor::instances()->size(),
460 static_cast<size_t>(kNumPostProcessors));
309 StreamMixerAlsa::Get()->SetAlsaWrapperForTest(base::WrapUnique(mock_alsa_)); 461 StreamMixerAlsa::Get()->SetAlsaWrapperForTest(base::WrapUnique(mock_alsa_));
310 } 462 }
311 463
312 ~StreamMixerAlsaTest() override { 464 ~StreamMixerAlsaTest() override {
313 StreamMixerAlsa::Get()->ClearInputsForTest(); 465 StreamMixerAlsa::Get()->ClearInputsForTest();
314 StreamMixerAlsa::Get()->SetAlsaWrapperForTest(nullptr); 466 StreamMixerAlsa::Get()->SetAlsaWrapperForTest(nullptr);
315 } 467 }
316 468
317 MockAlsaWrapper* mock_alsa() { return mock_alsa_; } 469 MockAlsaWrapper* mock_alsa() { return mock_alsa_; }
318 470
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 EXPECT_CALL(*inputs[0], AfterWriteFrames(_)); 948 EXPECT_CALL(*inputs[0], AfterWriteFrames(_));
797 EXPECT_CALL(*inputs[1], GetResampledData(_, _)).Times(0); 949 EXPECT_CALL(*inputs[1], GetResampledData(_, _)).Times(0);
798 EXPECT_CALL(*inputs[1], VolumeScaleAccumulate(_, _, _, _)).Times(0); 950 EXPECT_CALL(*inputs[1], VolumeScaleAccumulate(_, _, _, _)).Times(0);
799 EXPECT_CALL(*inputs[1], OnSkipped()); 951 EXPECT_CALL(*inputs[1], OnSkipped());
800 EXPECT_CALL(*inputs[1], AfterWriteFrames(_)); 952 EXPECT_CALL(*inputs[1], AfterWriteFrames(_));
801 953
802 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1); 954 EXPECT_CALL(*mock_alsa(), PcmWritei(_, _, kNumFrames)).Times(1);
803 mixer->WriteFramesForTest(); 955 mixer->WriteFramesForTest();
804 } 956 }
805 957
958 #define EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(map, name, times, frames, \
959 silence) \
960 do { \
961 auto itr = map->find(name); \
962 CHECK(itr != map->end()) << "Could not find processor for " << name; \
963 EXPECT_CALL(*(itr->second), ProcessFrames(_, frames, _, silence)) \
964 .Times(times); \
965 } while (0);
966
967 TEST_F(StreamMixerAlsaTest, PostProcessorDelayListedDeviceId) {
968 int common_delay = kMixProcessorDelay + kLinearizeProcessorDelay;
969 std::vector<testing::StrictMock<MockInputQueue>*> inputs;
970 std::vector<int64_t> delays;
971 inputs.push_back(new testing::StrictMock<MockInputQueue>(
972 kTestSamplesPerSecond, "default"));
973 delays.push_back(common_delay + kDefaultProcessorDelay);
974
975 inputs.push_back(new testing::StrictMock<MockInputQueue>(
976 kTestSamplesPerSecond, "communications"));
977 delays.push_back(common_delay);
978
979 inputs.push_back(new testing::StrictMock<MockInputQueue>(
980 kTestSamplesPerSecond, "assistant-tts"));
981 delays.push_back(common_delay + kTtsProcessorDelay);
982
983 // Convert delay from frames to microseconds.
984 std::transform(delays.begin(), delays.end(), delays.begin(),
985 &FramesToDelayUs);
986
987 const int kNumFrames = 10;
988 for (auto* input : inputs) {
989 input->SetMaxReadSize(kNumFrames);
990 input->SetPaused(false);
991 }
992
993 StreamMixerAlsa* mixer = StreamMixerAlsa::Get();
994 for (size_t i = 0; i < inputs.size(); ++i) {
995 EXPECT_CALL(*inputs[i], Initialize(_)).Times(1);
996 mixer->AddInput(base::WrapUnique(inputs[i]));
997 }
998
999 mock_alsa()->set_avail(4086);
1000
1001 auto* post_processors = MockPostProcessor::instances();
1002 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "default", 1,
1003 kNumFrames, false);
1004 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "mix", 1, kNumFrames,
1005 false);
1006 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "linearize", 1,
1007 kNumFrames, false);
1008 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "communications", 1,
1009 kNumFrames, false);
1010 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "assistant-tts", 1,
1011 kNumFrames, false);
1012
1013 // Poll the inputs for data. Each input will get a different
1014 // rendering delay based on their device type.
1015 for (size_t i = 0; i < inputs.size(); ++i) {
1016 EXPECT_CALL(*inputs[i], GetResampledData(_, kNumFrames));
1017 EXPECT_CALL(*inputs[i], VolumeScaleAccumulate(_, _, kNumFrames, _))
1018 .Times(kNumChannels);
1019 EXPECT_CALL(*inputs[i], AfterWriteFrames(
1020 MatchDelay(delays[i], inputs[i]->device_id())));
1021 }
1022 mixer->WriteFramesForTest();
1023 }
1024
1025 TEST_F(StreamMixerAlsaTest, PostProcessorDelayUnlistedDevice) {
1026 const std::string device_id = "not-a-device-id";
1027 testing::StrictMock<MockInputQueue>* input =
1028 new testing::StrictMock<MockInputQueue>(kTestSamplesPerSecond, device_id);
1029
1030 // Delay should be based on default processor
1031 int64_t delay = FramesToDelayUs(
1032 kDefaultProcessorDelay + kLinearizeProcessorDelay + kMixProcessorDelay);
1033 const int kNumFrames = 10;
1034 input->SetMaxReadSize(kNumFrames);
1035 input->SetPaused(false);
1036
1037 auto* post_processors = MockPostProcessor::instances();
1038 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "default", 1,
1039 kNumFrames, false);
1040 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "mix", 1, kNumFrames,
1041 false);
1042 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "linearize", 1,
1043 kNumFrames, false);
1044 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "communications", 0,
1045 _, _);
1046 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "assistant-tts", 0,
1047 _, _);
1048
1049 StreamMixerAlsa* mixer = StreamMixerAlsa::Get();
1050 EXPECT_CALL(*input, Initialize(_));
1051 mixer->AddInput(base::WrapUnique(input));
1052
1053 EXPECT_CALL(*input, GetResampledData(_, kNumFrames));
1054 EXPECT_CALL(*input, VolumeScaleAccumulate(_, _, kNumFrames, _))
1055 .Times(kNumChannels);
1056 EXPECT_CALL(*input, AfterWriteFrames(MatchDelay(delay, device_id)));
1057 mixer->WriteFramesForTest();
1058 }
1059
1060 TEST_F(StreamMixerAlsaTest, PostProcessorRingingWithoutInputs) {
1061 const char kTestPipelineJson[] = R"json(
1062 {
1063 "output_streams": [{
1064 "streams": [ "default" ],
1065 "processors": [{
1066 "processor": "%s",
1067 "config": { "delay": 0, "ringing": true}
1068 }]
1069 }, {
1070 "streams": [ "foobar" ],
1071 "processors": [{
1072 "processor": "%s",
1073 "config": { "delay": 0, "ringing": true}
1074 }]
1075 }]
1076 }
1077 )json";
1078
1079 StreamMixerAlsa* mixer = StreamMixerAlsa::Get();
1080 char test_pipeline_json[sizeof(kTestPipelineJson) * 2];
1081 snprintf(test_pipeline_json, sizeof(test_pipeline_json), kTestPipelineJson,
1082 kDelayModuleSolib, kDelayModuleSolib);
1083 mixer->ResetPostProcessorsForTest(test_pipeline_json);
1084 // "mix" + "linearize" should be automatic
1085 CHECK_EQ(MockPostProcessor::instances()->size(), 4u);
1086
1087 mock_alsa()->set_avail(4086);
1088
1089 auto* post_processors = MockPostProcessor::instances();
1090 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "default", 1,
1091 kPreventUnderrunChunkSize, true);
1092 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "mix", 1,
1093 kPreventUnderrunChunkSize, true);
1094 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "linearize", 1,
1095 kPreventUnderrunChunkSize, true);
1096 EXPECT_POSTPROCESSOR_CALL_PROCESSFRAMES(post_processors, "foobar", 0, _, _);
1097
1098 mixer->WriteFramesForTest();
1099 }
1100
806 } // namespace media 1101 } // namespace media
807 } // namespace chromecast 1102 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698