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

Side by Side Diff: webrtc/modules/audio_processing/audio_processing_performance_unittest.cc

Issue 1473733004: Revert of Created a test that reports the statistics for the duration of APM stream processing ... (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « no previous file | webrtc/webrtc_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10 #include "webrtc/modules/audio_processing/audio_processing_impl.h"
11
12 #include <math.h>
13
14 #include <algorithm>
15 #include <vector>
16
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "webrtc/base/array_view.h"
19 #include "webrtc/base/criticalsection.h"
20 #include "webrtc/base/platform_thread.h"
21 #include "webrtc/base/safe_conversions.h"
22 #include "webrtc/config.h"
23 #include "webrtc/modules/audio_processing/test/test_utils.h"
24 #include "webrtc/modules/include/module_common_types.h"
25 #include "webrtc/system_wrappers/include/clock.h"
26 #include "webrtc/system_wrappers/include/event_wrapper.h"
27 #include "webrtc/system_wrappers/include/sleep.h"
28 #include "webrtc/test/random.h"
29 #include "webrtc/test/testsupport/perf_test.h"
30
31 namespace webrtc {
32
33 namespace {
34
35 static const bool kPrintAllDurations = false;
36
37 class CallSimulator;
38
39 // Type of the render thread APM API call to use in the test.
40 enum class ProcessorType { kRender, kCapture };
41
42 // Variant of APM processing settings to use in the test.
43 enum class SettingsType {
44 kDefaultApmDesktop,
45 kDefaultApmMobile,
46 kDefaultApmDesktopAndBeamformer,
47 kDefaultApmDesktopAndIntelligibilityEnhancer,
48 kAllSubmodulesTurnedOff,
49 kDefaultDesktopApmWithoutDelayAgnostic,
50 kDefaultDesktopApmWithoutExtendedFilter
51 };
52
53 // Variables related to the audio data and formats.
54 struct AudioFrameData {
55 explicit AudioFrameData(size_t max_frame_size) {
56 // Set up the two-dimensional arrays needed for the APM API calls.
57 input_framechannels.resize(2 * max_frame_size);
58 input_frame.resize(2);
59 input_frame[0] = &input_framechannels[0];
60 input_frame[1] = &input_framechannels[max_frame_size];
61
62 output_frame_channels.resize(2 * max_frame_size);
63 output_frame.resize(2);
64 output_frame[0] = &output_frame_channels[0];
65 output_frame[1] = &output_frame_channels[max_frame_size];
66 }
67
68 std::vector<float> output_frame_channels;
69 std::vector<float*> output_frame;
70 std::vector<float> input_framechannels;
71 std::vector<float*> input_frame;
72 StreamConfig input_stream_config;
73 StreamConfig output_stream_config;
74 };
75
76 // The configuration for the test.
77 struct SimulationConfig {
78 SimulationConfig(int sample_rate_hz, SettingsType simulation_settings)
79 : sample_rate_hz(sample_rate_hz),
80 simulation_settings(simulation_settings) {}
81
82 static std::vector<SimulationConfig> GenerateSimulationConfigs() {
83 std::vector<SimulationConfig> simulation_configs;
84 #ifndef WEBRTC_ANDROID
85 const SettingsType desktop_settings[] = {
86 SettingsType::kDefaultApmDesktop, SettingsType::kAllSubmodulesTurnedOff,
87 SettingsType::kDefaultDesktopApmWithoutDelayAgnostic,
88 SettingsType::kDefaultDesktopApmWithoutExtendedFilter};
89
90 const int desktop_sample_rates[] = {8000, 16000, 32000, 48000};
91
92 for (auto sample_rate : desktop_sample_rates) {
93 for (auto settings : desktop_settings) {
94 simulation_configs.push_back(SimulationConfig(sample_rate, settings));
95 }
96 }
97
98 const SettingsType intelligibility_enhancer_settings[] = {
99 SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer};
100
101 const int intelligibility_enhancer_sample_rates[] = {8000, 16000, 32000,
102 48000};
103
104 for (auto sample_rate : intelligibility_enhancer_sample_rates) {
105 for (auto settings : intelligibility_enhancer_settings) {
106 simulation_configs.push_back(SimulationConfig(sample_rate, settings));
107 }
108 }
109
110 const SettingsType beamformer_settings[] = {
111 SettingsType::kDefaultApmDesktopAndBeamformer};
112
113 const int beamformer_sample_rates[] = {8000, 16000, 32000, 48000};
114
115 for (auto sample_rate : beamformer_sample_rates) {
116 for (auto settings : beamformer_settings) {
117 simulation_configs.push_back(SimulationConfig(sample_rate, settings));
118 }
119 }
120 #endif
121
122 const SettingsType mobile_settings[] = {SettingsType::kDefaultApmMobile};
123
124 const int mobile_sample_rates[] = {8000, 16000};
125
126 for (auto sample_rate : mobile_sample_rates) {
127 for (auto settings : mobile_settings) {
128 simulation_configs.push_back(SimulationConfig(sample_rate, settings));
129 }
130 }
131
132 return simulation_configs;
133 }
134
135 std::string SettingsDescription() const {
136 std::string description;
137 switch (simulation_settings) {
138 case SettingsType::kDefaultApmMobile:
139 description = "DefaultApmMobile";
140 break;
141 case SettingsType::kDefaultApmDesktop:
142 description = "DefaultApmDesktop";
143 break;
144 case SettingsType::kDefaultApmDesktopAndBeamformer:
145 description = "DefaultApmDesktopAndBeamformer";
146 break;
147 case SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer:
148 description = "DefaultApmDesktopAndIntelligibilityEnhancer";
149 break;
150 case SettingsType::kAllSubmodulesTurnedOff:
151 description = "AllSubmodulesOff";
152 break;
153 case SettingsType::kDefaultDesktopApmWithoutDelayAgnostic:
154 description = "DefaultDesktopApmWithoutDelayAgnostic";
155 break;
156 case SettingsType::kDefaultDesktopApmWithoutExtendedFilter:
157 description = "DefaultDesktopApmWithoutExtendedFilter";
158 break;
159 }
160 return description;
161 }
162
163 int sample_rate_hz = 16000;
164 SettingsType simulation_settings = SettingsType::kDefaultApmDesktop;
165 };
166
167 // Handler for the frame counters.
168 class FrameCounters {
169 public:
170 void IncreaseRenderCounter() {
171 rtc::CritScope cs(&crit_);
172 render_count_++;
173 }
174
175 void IncreaseCaptureCounter() {
176 rtc::CritScope cs(&crit_);
177 capture_count_++;
178 }
179
180 int GetCaptureCounter() const {
181 rtc::CritScope cs(&crit_);
182 return capture_count_;
183 }
184
185 int GetRenderCounter() const {
186 rtc::CritScope cs(&crit_);
187 return render_count_;
188 }
189
190 int CaptureMinusRenderCounters() const {
191 rtc::CritScope cs(&crit_);
192 return capture_count_ - render_count_;
193 }
194
195 int RenderMinusCaptureCounters() const {
196 return -CaptureMinusRenderCounters();
197 }
198
199 bool BothCountersExceedeThreshold(int threshold) const {
200 rtc::CritScope cs(&crit_);
201 return (render_count_ > threshold && capture_count_ > threshold);
202 }
203
204 private:
205 mutable rtc::CriticalSection crit_;
206 int render_count_ GUARDED_BY(crit_) = 0;
207 int capture_count_ GUARDED_BY(crit_) = 0;
208 };
209
210 // Class that protects a flag using a lock.
211 class LockedFlag {
212 public:
213 bool get_flag() const {
214 rtc::CritScope cs(&crit_);
215 return flag_;
216 }
217
218 void set_flag() {
219 rtc::CritScope cs(&crit_);
220 flag_ = true;
221 }
222
223 private:
224 mutable rtc::CriticalSection crit_;
225 bool flag_ GUARDED_BY(crit_) = false;
226 };
227
228 // Parent class for the thread processors.
229 class TimedThreadApiProcessor {
230 public:
231 TimedThreadApiProcessor(ProcessorType processor_type,
232 test::Random* rand_gen,
233 FrameCounters* shared_counters_state,
234 LockedFlag* capture_call_checker,
235 CallSimulator* test_framework,
236 const SimulationConfig* simulation_config,
237 AudioProcessing* apm,
238 int num_durations_to_store,
239 float input_level,
240 int num_channels)
241 : rand_gen_(rand_gen),
242 frame_counters_(shared_counters_state),
243 capture_call_checker_(capture_call_checker),
244 test_(test_framework),
245 simulation_config_(simulation_config),
246 apm_(apm),
247 frame_data_(kMaxFrameSize),
248 clock_(webrtc::Clock::GetRealTimeClock()),
249 num_durations_to_store_(num_durations_to_store),
250 input_level_(input_level),
251 processor_type_(processor_type),
252 num_channels_(num_channels) {
253 api_call_durations_.reserve(num_durations_to_store_);
254 }
255
256 // Implements the callback functionality for the threads.
257 bool Process();
258
259 // Method for printing out the simulation statistics.
260 void print_processor_statistics(std::string processor_name) const {
261 const std::string modifier = "_api_call_duration";
262
263 // Lambda function for creating a test printout string.
264 auto create_mean_and_std_string = [](int64_t average,
265 int64_t standard_dev) {
266 std::string s = std::to_string(average);
267 s += ", ";
268 s += std::to_string(standard_dev);
269 return s;
270 };
271
272 const std::string sample_rate_name =
273 "_" + std::to_string(simulation_config_->sample_rate_hz) + "Hz";
274
275 webrtc::test::PrintResultMeanAndError(
276 "apm_timing", sample_rate_name, processor_name,
277 create_mean_and_std_string(GetDurationAverage(),
278 GetDurationStandardDeviation()),
279 "us", false);
280
281 if (kPrintAllDurations) {
282 std::string value_string = "";
283 for (int64_t duration : api_call_durations_) {
284 value_string += std::to_string(duration) + ",";
285 }
286 webrtc::test::PrintResultList("apm_call_durations", sample_rate_name,
287 processor_name, value_string, "us", false);
288 }
289 }
290
291 void AddDuration(int64_t duration) {
292 if (api_call_durations_.size() < num_durations_to_store_) {
293 api_call_durations_.push_back(duration);
294 }
295 }
296
297 private:
298 static const int kMaxCallDifference = 10;
299 static const int kMaxFrameSize = 480;
300 static const int kNumInitializationFrames = 5;
301
302 int64_t GetDurationStandardDeviation() const {
303 double variance = 0;
304 const int64_t average_duration = GetDurationAverage();
305 for (size_t k = kNumInitializationFrames; k < api_call_durations_.size();
306 k++) {
307 int64_t tmp = api_call_durations_[k] - average_duration;
308 variance += static_cast<double>(tmp * tmp);
309 }
310 const int denominator = rtc::checked_cast<int>(api_call_durations_.size()) -
311 kNumInitializationFrames;
312 return (denominator > 0
313 ? rtc::checked_cast<int64_t>(sqrt(variance / denominator))
314 : -1);
315 }
316
317 int64_t GetDurationAverage() const {
318 int64_t average_duration = 0;
319 for (size_t k = kNumInitializationFrames; k < api_call_durations_.size();
320 k++) {
321 average_duration += api_call_durations_[k];
322 }
323 const int denominator = rtc::checked_cast<int>(api_call_durations_.size()) -
324 kNumInitializationFrames;
325 return (denominator > 0 ? average_duration / denominator : -1);
326 }
327
328 int ProcessCapture() {
329 // Set the stream delay.
330 apm_->set_stream_delay_ms(30);
331
332 // Call and time the specified capture side API processing method.
333 const int64_t start_time = clock_->TimeInMicroseconds();
334 const int result = apm_->ProcessStream(
335 &frame_data_.input_frame[0], frame_data_.input_stream_config,
336 frame_data_.output_stream_config, &frame_data_.output_frame[0]);
337 const int64_t end_time = clock_->TimeInMicroseconds();
338
339 frame_counters_->IncreaseCaptureCounter();
340
341 AddDuration(end_time - start_time);
342
343 if (first_process_call_) {
344 // Flag that the capture side has been called at least once
345 // (needed to ensure that a capture call has been done
346 // before the first render call is performed (implicitly
347 // required by the APM API).
348 capture_call_checker_->set_flag();
349 first_process_call_ = false;
350 }
351 return result;
352 }
353
354 bool ReadyToProcessCapture() {
355 return (frame_counters_->CaptureMinusRenderCounters() <=
356 kMaxCallDifference);
357 }
358
359 int ProcessRender() {
360 // Call and time the specified render side API processing method.
361 const int64_t start_time = clock_->TimeInMicroseconds();
362 const int result = apm_->ProcessReverseStream(
363 &frame_data_.input_frame[0], frame_data_.input_stream_config,
364 frame_data_.output_stream_config, &frame_data_.output_frame[0]);
365 const int64_t end_time = clock_->TimeInMicroseconds();
366 frame_counters_->IncreaseRenderCounter();
367
368 AddDuration(end_time - start_time);
369
370 return result;
371 }
372
373 bool ReadyToProcessRender() {
374 // Do not process until at least one capture call has been done.
375 // (implicitly required by the APM API).
376 if (first_process_call_ && !capture_call_checker_->get_flag()) {
377 return false;
378 }
379
380 // Ensure that the number of render and capture calls do not differ too
381 // much.
382 if (frame_counters_->RenderMinusCaptureCounters() > kMaxCallDifference) {
383 return false;
384 }
385
386 first_process_call_ = false;
387 return true;
388 }
389
390 void PrepareFrame() {
391 // Lambda function for populating a float multichannel audio frame
392 // with random data.
393 auto populate_audio_frame = [](float amplitude, size_t num_channels,
394 size_t samples_per_channel,
395 test::Random* rand_gen, float** frame) {
396 for (size_t ch = 0; ch < num_channels; ch++) {
397 for (size_t k = 0; k < samples_per_channel; k++) {
398 // Store random float number with a value between +-amplitude.
399 frame[ch][k] = amplitude * (2 * rand_gen->Rand<float>() - 1);
400 }
401 }
402 };
403
404 // Prepare the audio input data and metadata.
405 frame_data_.input_stream_config.set_sample_rate_hz(
406 simulation_config_->sample_rate_hz);
407 frame_data_.input_stream_config.set_num_channels(num_channels_);
408 frame_data_.input_stream_config.set_has_keyboard(false);
409 populate_audio_frame(input_level_, num_channels_,
410 (simulation_config_->sample_rate_hz *
411 AudioProcessing::kChunkSizeMs / 1000),
412 rand_gen_, &frame_data_.input_frame[0]);
413
414 // Prepare the float audio output data and metadata.
415 frame_data_.output_stream_config.set_sample_rate_hz(
416 simulation_config_->sample_rate_hz);
417 frame_data_.output_stream_config.set_num_channels(1);
418 frame_data_.output_stream_config.set_has_keyboard(false);
419 }
420
421 bool ReadyToProcess() {
422 switch (processor_type_) {
423 case ProcessorType::kRender:
424 return ReadyToProcessRender();
425 break;
426 case ProcessorType::kCapture:
427 return ReadyToProcessCapture();
428 break;
429 }
430
431 // Should not be reached, but the return statement is needed for the code to
432 // build successfully on Android.
433 RTC_NOTREACHED();
434 return false;
435 }
436
437 test::Random* rand_gen_ = nullptr;
438 FrameCounters* frame_counters_ = nullptr;
439 LockedFlag* capture_call_checker_ = nullptr;
440 CallSimulator* test_ = nullptr;
441 const SimulationConfig* const simulation_config_ = nullptr;
442 AudioProcessing* apm_ = nullptr;
443 AudioFrameData frame_data_;
444 webrtc::Clock* clock_;
445 const size_t num_durations_to_store_;
446 std::vector<int64_t> api_call_durations_;
447 const float input_level_;
448 bool first_process_call_ = true;
449 const ProcessorType processor_type_;
450 const int num_channels_ = 1;
451 };
452
453 // Class for managing the test simulation.
454 class CallSimulator : public ::testing::TestWithParam<SimulationConfig> {
455 public:
456 CallSimulator()
457 : test_complete_(EventWrapper::Create()),
458 render_thread_(PlatformThread::CreateThread(RenderProcessorThreadFunc,
459 this,
460 "render")),
461 capture_thread_(PlatformThread::CreateThread(CaptureProcessorThreadFunc,
462 this,
463 "capture")),
464 rand_gen_(42U),
465 simulation_config_(static_cast<SimulationConfig>(GetParam())) {}
466
467 // Run the call simulation with a timeout.
468 EventTypeWrapper Run() {
469 StartThreads();
470
471 EventTypeWrapper result = test_complete_->Wait(kTestTimeout);
472
473 render_thread_state_->print_processor_statistics(
474 simulation_config_.SettingsDescription() + "_render");
475 capture_thread_state_->print_processor_statistics(
476 simulation_config_.SettingsDescription() + "_capture");
477
478 return result;
479 }
480
481 // Tests whether all the required render and capture side calls have been
482 // done.
483 void MaybeEndTest() {
484 if (frame_counters_.BothCountersExceedeThreshold(kMinNumFramesToProcess)) {
485 test_complete_->Set();
486 }
487 }
488
489 private:
490 static const float kCaptureInputFloatLevel;
491 static const float kRenderInputFloatLevel;
492 static const int kMinNumFramesToProcess = 150;
493 static const int32_t kTestTimeout = 3 * 10 * kMinNumFramesToProcess;
494
495 // ::testing::TestWithParam<> implementation.
496 void TearDown() override {
497 render_thread_->Stop();
498 capture_thread_->Stop();
499 }
500
501 // Simulator and APM setup.
502 void SetUp() override {
503 // Lambda function for setting the default APM runtime settings for desktop.
504 auto set_default_desktop_apm_runtime_settings = [](AudioProcessing* apm) {
505 ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(true));
506 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
507 ASSERT_EQ(apm->kNoError,
508 apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
509 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
510 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
511 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
512 ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(false));
513 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(true));
514 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->enable_metrics(true));
515 ASSERT_EQ(apm->kNoError,
516 apm->echo_cancellation()->enable_delay_logging(true));
517 };
518
519 // Lambda function for setting the default APM runtime settings for mobile.
520 auto set_default_mobile_apm_runtime_settings = [](AudioProcessing* apm) {
521 ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(true));
522 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
523 ASSERT_EQ(apm->kNoError,
524 apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
525 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(true));
526 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(true));
527 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(true));
528 ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(true));
529 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(false));
530 };
531
532 // Lambda function for turning off all of the APM runtime settings
533 // submodules.
534 auto turn_off_default_apm_runtime_settings = [](AudioProcessing* apm) {
535 ASSERT_EQ(apm->kNoError, apm->level_estimator()->Enable(false));
536 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false));
537 ASSERT_EQ(apm->kNoError,
538 apm->gain_control()->set_mode(GainControl::kAdaptiveDigital));
539 ASSERT_EQ(apm->kNoError, apm->gain_control()->Enable(false));
540 ASSERT_EQ(apm->kNoError, apm->noise_suppression()->Enable(false));
541 ASSERT_EQ(apm->kNoError, apm->voice_detection()->Enable(false));
542 ASSERT_EQ(apm->kNoError, apm->echo_control_mobile()->Enable(false));
543 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->Enable(false));
544 ASSERT_EQ(apm->kNoError, apm->echo_cancellation()->enable_metrics(false));
545 ASSERT_EQ(apm->kNoError,
546 apm->echo_cancellation()->enable_delay_logging(false));
547 };
548
549 // Lambda function for adding default desktop APM settings to a config.
550 auto add_default_desktop_config = [](Config* config) {
551 config->Set<ExtendedFilter>(new ExtendedFilter(true));
552 config->Set<DelayAgnostic>(new DelayAgnostic(true));
553 };
554
555 // Lambda function for adding beamformer settings to a config.
556 auto add_beamformer_config = [](Config* config) {
557 const size_t num_mics = 2;
558 const std::vector<Point> array_geometry =
559 ParseArrayGeometry("0 0 0 0.05 0 0", num_mics);
560 RTC_CHECK_EQ(array_geometry.size(), num_mics);
561
562 config->Set<Beamforming>(
563 new Beamforming(true, array_geometry,
564 SphericalPointf(DegreesToRadians(90), 0.f, 1.f)));
565 };
566
567 int num_capture_channels = 1;
568 switch (simulation_config_.simulation_settings) {
569 case SettingsType::kDefaultApmMobile: {
570 apm_.reset(AudioProcessingImpl::Create());
571 ASSERT_TRUE(!!apm_);
572 set_default_mobile_apm_runtime_settings(apm_.get());
573 break;
574 }
575 case SettingsType::kDefaultApmDesktop: {
576 Config config;
577 add_default_desktop_config(&config);
578 apm_.reset(AudioProcessingImpl::Create(config));
579 ASSERT_TRUE(!!apm_);
580 set_default_desktop_apm_runtime_settings(apm_.get());
581 apm_->SetExtraOptions(config);
582 break;
583 }
584 case SettingsType::kDefaultApmDesktopAndBeamformer: {
585 Config config;
586 add_beamformer_config(&config);
587 add_default_desktop_config(&config);
588 apm_.reset(AudioProcessingImpl::Create(config));
589 ASSERT_TRUE(!!apm_);
590 set_default_desktop_apm_runtime_settings(apm_.get());
591 apm_->SetExtraOptions(config);
592 num_capture_channels = 2;
593 break;
594 }
595 case SettingsType::kDefaultApmDesktopAndIntelligibilityEnhancer: {
596 Config config;
597 config.Set<Intelligibility>(new Intelligibility(true));
598 add_default_desktop_config(&config);
599 apm_.reset(AudioProcessingImpl::Create(config));
600 ASSERT_TRUE(!!apm_);
601 set_default_desktop_apm_runtime_settings(apm_.get());
602 apm_->SetExtraOptions(config);
603 break;
604 }
605 case SettingsType::kAllSubmodulesTurnedOff: {
606 apm_.reset(AudioProcessingImpl::Create());
607 ASSERT_TRUE(!!apm_);
608 turn_off_default_apm_runtime_settings(apm_.get());
609 break;
610 }
611 case SettingsType::kDefaultDesktopApmWithoutDelayAgnostic: {
612 Config config;
613 config.Set<ExtendedFilter>(new ExtendedFilter(true));
614 config.Set<DelayAgnostic>(new DelayAgnostic(false));
615 apm_.reset(AudioProcessingImpl::Create(config));
616 ASSERT_TRUE(!!apm_);
617 set_default_desktop_apm_runtime_settings(apm_.get());
618 apm_->SetExtraOptions(config);
619 break;
620 }
621 case SettingsType::kDefaultDesktopApmWithoutExtendedFilter: {
622 Config config;
623 config.Set<ExtendedFilter>(new ExtendedFilter(false));
624 config.Set<DelayAgnostic>(new DelayAgnostic(true));
625 apm_.reset(AudioProcessingImpl::Create(config));
626 ASSERT_TRUE(!!apm_);
627 set_default_desktop_apm_runtime_settings(apm_.get());
628 apm_->SetExtraOptions(config);
629 break;
630 }
631 }
632
633 render_thread_state_.reset(new TimedThreadApiProcessor(
634 ProcessorType::kRender, &rand_gen_, &frame_counters_,
635 &capture_call_checker_, this, &simulation_config_, apm_.get(),
636 kMinNumFramesToProcess, kRenderInputFloatLevel, 1));
637 capture_thread_state_.reset(new TimedThreadApiProcessor(
638 ProcessorType::kCapture, &rand_gen_, &frame_counters_,
639 &capture_call_checker_, this, &simulation_config_, apm_.get(),
640 kMinNumFramesToProcess, kCaptureInputFloatLevel, num_capture_channels));
641 }
642
643 // Thread callback for the render thread.
644 static bool RenderProcessorThreadFunc(void* context) {
645 return reinterpret_cast<CallSimulator*>(context)
646 ->render_thread_state_->Process();
647 }
648
649 // Thread callback for the capture thread.
650 static bool CaptureProcessorThreadFunc(void* context) {
651 return reinterpret_cast<CallSimulator*>(context)
652 ->capture_thread_state_->Process();
653 }
654
655 // Start the threads used in the test.
656 void StartThreads() {
657 ASSERT_NO_FATAL_FAILURE(render_thread_->Start());
658 render_thread_->SetPriority(kRealtimePriority);
659 ASSERT_NO_FATAL_FAILURE(capture_thread_->Start());
660 capture_thread_->SetPriority(kRealtimePriority);
661 }
662
663 // Event handler for the test.
664 const rtc::scoped_ptr<EventWrapper> test_complete_;
665
666 // Thread related variables.
667 rtc::scoped_ptr<PlatformThread> render_thread_;
668 rtc::scoped_ptr<PlatformThread> capture_thread_;
669 test::Random rand_gen_;
670
671 rtc::scoped_ptr<AudioProcessing> apm_;
672 const SimulationConfig simulation_config_;
673 FrameCounters frame_counters_;
674 LockedFlag capture_call_checker_;
675 rtc::scoped_ptr<TimedThreadApiProcessor> render_thread_state_;
676 rtc::scoped_ptr<TimedThreadApiProcessor> capture_thread_state_;
677 };
678
679 // Implements the callback functionality for the threads.
680 bool TimedThreadApiProcessor::Process() {
681 PrepareFrame();
682
683 // Wait in a spinlock manner until it is ok to start processing.
684 // Note that SleepMs is not applicable since it only allows sleeping
685 // on a millisecond basis which is too long.
686 while (!ReadyToProcess()) {
687 }
688
689 int result = AudioProcessing::kNoError;
690 switch (processor_type_) {
691 case ProcessorType::kRender:
692 result = ProcessRender();
693 break;
694 case ProcessorType::kCapture:
695 result = ProcessCapture();
696 break;
697 }
698
699 EXPECT_EQ(result, AudioProcessing::kNoError);
700
701 test_->MaybeEndTest();
702
703 return true;
704 }
705
706 const float CallSimulator::kRenderInputFloatLevel = 0.5f;
707 const float CallSimulator::kCaptureInputFloatLevel = 0.03125f;
708 } // anonymous namespace
709
710 TEST_P(CallSimulator, ApiCallDurationTest) {
711 // Run test and verify that it did not time out.
712 EXPECT_EQ(kEventSignaled, Run());
713 }
714
715 INSTANTIATE_TEST_CASE_P(
716 AudioProcessingPerformanceTest,
717 CallSimulator,
718 ::testing::ValuesIn(SimulationConfig::GenerateSimulationConfigs()));
719
720 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | webrtc/webrtc_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698