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

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

Issue 1424663003: Lock scheme #8: Introduced the new locking scheme (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@add_threadcheckers_CL
Patch Set: Major general updates, completing the locking scheme, and increasing readability Created 5 years, 1 month 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/audio_processing/echo_cancellation_impl.h" 11 #include "webrtc/modules/audio_processing/echo_cancellation_impl.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <string.h> 14 #include <string.h>
15 15
16 extern "C" { 16 extern "C" {
17 #include "webrtc/modules/audio_processing/aec/aec_core.h" 17 #include "webrtc/modules/audio_processing/aec/aec_core.h"
18 } 18 }
19 #include "webrtc/base/criticalsection.h"
19 #include "webrtc/modules/audio_processing/aec/include/echo_cancellation.h" 20 #include "webrtc/modules/audio_processing/aec/include/echo_cancellation.h"
20 #include "webrtc/modules/audio_processing/audio_buffer.h" 21 #include "webrtc/modules/audio_processing/audio_buffer.h"
21 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
22 22
23 namespace webrtc { 23 namespace webrtc {
24 24
25 typedef void Handle; 25 typedef void Handle;
26 26
27 namespace { 27 namespace {
28 int16_t MapSetting(EchoCancellation::SuppressionLevel level) { 28 int16_t MapSetting(EchoCancellation::SuppressionLevel level) {
29 switch (level) { 29 switch (level) {
30 case EchoCancellation::kLowSuppression: 30 case EchoCancellation::kLowSuppression:
31 return kAecNlpConservative; 31 return kAecNlpConservative;
(...skipping 21 matching lines...) Expand all
53 return AudioProcessing::kUnspecifiedError; 53 return AudioProcessing::kUnspecifiedError;
54 } 54 }
55 } 55 }
56 } // namespace 56 } // namespace
57 57
58 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame1; 58 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame1;
59 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame2; 59 const size_t EchoCancellationImpl::kAllowedValuesOfSamplesPerFrame2;
60 60
61 EchoCancellationImpl::EchoCancellationImpl( 61 EchoCancellationImpl::EchoCancellationImpl(
62 const AudioProcessing* apm, 62 const AudioProcessing* apm,
63 CriticalSectionWrapper* crit, 63 rtc::CriticalSection* crit_render,
64 rtc::CriticalSection* crit_capture,
64 rtc::ThreadChecker* render_thread_checker) 65 rtc::ThreadChecker* render_thread_checker)
65 : ProcessingComponent(), 66 : ProcessingComponent(),
66 apm_(apm), 67 apm_(apm),
67 crit_(crit), 68 crit_render_(crit_render),
69 crit_capture_(crit_capture),
68 render_thread_checker_(render_thread_checker), 70 render_thread_checker_(render_thread_checker),
69 drift_compensation_enabled_(false), 71 drift_compensation_enabled_(false),
70 metrics_enabled_(false), 72 metrics_enabled_(false),
71 suppression_level_(kModerateSuppression), 73 suppression_level_(kModerateSuppression),
72 stream_drift_samples_(0), 74 stream_drift_samples_(0),
73 was_stream_drift_set_(false), 75 was_stream_drift_set_(false),
74 stream_has_echo_(false), 76 stream_has_echo_(false),
75 delay_logging_enabled_(false), 77 delay_logging_enabled_(false),
76 extended_filter_enabled_(false), 78 extended_filter_enabled_(false),
77 delay_agnostic_enabled_(false), 79 delay_agnostic_enabled_(false),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 111 }
110 112
111 // Buffer the samples in the render queue. 113 // Buffer the samples in the render queue.
112 render_queue_buffer_.insert(render_queue_buffer_.end(), 114 render_queue_buffer_.insert(render_queue_buffer_.end(),
113 audio->split_bands_const_f(j)[kBand0To8kHz], 115 audio->split_bands_const_f(j)[kBand0To8kHz],
114 (audio->split_bands_const_f(j)[kBand0To8kHz] + 116 (audio->split_bands_const_f(j)[kBand0To8kHz] +
115 audio->num_frames_per_band())); 117 audio->num_frames_per_band()));
116 } 118 }
117 } 119 }
118 120
119 // Check of success is temporarily disabled as it breaks a unit test. 121 // Insert the samples into the queue.
120 // TODO(peah): Will be fixed in the next CL. 122 bool success = render_signal_queue_->Insert(&render_queue_buffer_);
hlundin-webrtc 2015/11/05 16:11:22 You don't need success. if (!render_signal_queue_-
peah-webrtc 2015/11/06 09:54:32 Done.
121 (void)render_signal_queue_->Insert(&render_queue_buffer_); 123 if (!success) {
124 // The data queue is full and needs to be emptied.
125 {
126 rtc::CritScope cs_capture(crit_capture_);
127 ReadQueuedRenderData();
128 }
129
130 // Retry the insert (should always work).
131 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true);
132 }
122 133
123 return apm_->kNoError; 134 return apm_->kNoError;
124 } 135 }
125 136
126 // Read chunks of data that were received and queued on the render side from 137 // Read chunks of data that were received and queued on the render side from
127 // a queue. All the data chunks are buffered into the farend signal of the AEC. 138 // a queue. All the data chunks are buffered into the farend signal of the AEC.
128 void EchoCancellationImpl::ReadQueuedRenderData() { 139 void EchoCancellationImpl::ReadQueuedRenderData() {
129 if (!is_component_enabled()) { 140 if (!is_component_enabled()) {
130 return; 141 return;
131 } 142 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 214
204 handle_index++; 215 handle_index++;
205 } 216 }
206 } 217 }
207 218
208 was_stream_drift_set_ = false; 219 was_stream_drift_set_ = false;
209 return apm_->kNoError; 220 return apm_->kNoError;
210 } 221 }
211 222
212 int EchoCancellationImpl::Enable(bool enable) { 223 int EchoCancellationImpl::Enable(bool enable) {
213 CriticalSectionScoped crit_scoped(crit_); 224 // Run in a single-threaded manner.
225 rtc::CritScope cs_render(crit_render_);
226 rtc::CritScope cs_capture(crit_capture_);
214 // Ensure AEC and AECM are not both enabled. 227 // Ensure AEC and AECM are not both enabled.
215 if (enable && apm_->echo_control_mobile()->is_enabled()) { 228 if (enable && apm_->echo_control_mobile()->is_enabled()) {
216 return apm_->kBadParameterError; 229 return apm_->kBadParameterError;
217 } 230 }
218 231
219 return EnableComponent(enable); 232 return EnableComponent(enable);
220 } 233 }
221 234
222 bool EchoCancellationImpl::is_enabled() const { 235 bool EchoCancellationImpl::is_enabled() const {
236 rtc::CritScope cs(crit_capture_);
223 return is_component_enabled(); 237 return is_component_enabled();
224 } 238 }
225 239
226 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) { 240 int EchoCancellationImpl::set_suppression_level(SuppressionLevel level) {
227 CriticalSectionScoped crit_scoped(crit_); 241 rtc::CritScope cs(crit_capture_);
228 if (MapSetting(level) == -1) { 242 if (MapSetting(level) == -1) {
229 return apm_->kBadParameterError; 243 return apm_->kBadParameterError;
230 } 244 }
231 245
232 suppression_level_ = level; 246 suppression_level_ = level;
233 return Configure(); 247 return Configure();
234 } 248 }
235 249
236 EchoCancellation::SuppressionLevel EchoCancellationImpl::suppression_level() 250 EchoCancellation::SuppressionLevel EchoCancellationImpl::suppression_level()
237 const { 251 const {
252 rtc::CritScope cs(crit_capture_);
238 return suppression_level_; 253 return suppression_level_;
239 } 254 }
240 255
241 int EchoCancellationImpl::enable_drift_compensation(bool enable) { 256 int EchoCancellationImpl::enable_drift_compensation(bool enable) {
242 CriticalSectionScoped crit_scoped(crit_); 257 rtc::CritScope cs(crit_capture_);
243 drift_compensation_enabled_ = enable; 258 drift_compensation_enabled_ = enable;
244 return Configure(); 259 return Configure();
245 } 260 }
246 261
247 bool EchoCancellationImpl::is_drift_compensation_enabled() const { 262 bool EchoCancellationImpl::is_drift_compensation_enabled() const {
263 rtc::CritScope cs(crit_capture_);
248 return drift_compensation_enabled_; 264 return drift_compensation_enabled_;
249 } 265 }
250 266
251 void EchoCancellationImpl::set_stream_drift_samples(int drift) { 267 void EchoCancellationImpl::set_stream_drift_samples(int drift) {
268 rtc::CritScope cs(crit_capture_);
252 was_stream_drift_set_ = true; 269 was_stream_drift_set_ = true;
253 stream_drift_samples_ = drift; 270 stream_drift_samples_ = drift;
254 } 271 }
255 272
256 int EchoCancellationImpl::stream_drift_samples() const { 273 int EchoCancellationImpl::stream_drift_samples() const {
274 rtc::CritScope cs(crit_capture_);
257 return stream_drift_samples_; 275 return stream_drift_samples_;
258 } 276 }
259 277
260 int EchoCancellationImpl::enable_metrics(bool enable) { 278 int EchoCancellationImpl::enable_metrics(bool enable) {
261 CriticalSectionScoped crit_scoped(crit_); 279 rtc::CritScope cs(crit_capture_);
262 metrics_enabled_ = enable; 280 metrics_enabled_ = enable;
263 return Configure(); 281 return Configure();
264 } 282 }
265 283
266 bool EchoCancellationImpl::are_metrics_enabled() const { 284 bool EchoCancellationImpl::are_metrics_enabled() const {
285 rtc::CritScope cs(crit_capture_);
267 return metrics_enabled_; 286 return metrics_enabled_;
268 } 287 }
269 288
270 // TODO(ajm): we currently just use the metrics from the first AEC. Think more 289 // TODO(ajm): we currently just use the metrics from the first AEC. Think more
271 // aboue the best way to extend this to multi-channel. 290 // aboue the best way to extend this to multi-channel.
272 int EchoCancellationImpl::GetMetrics(Metrics* metrics) { 291 int EchoCancellationImpl::GetMetrics(Metrics* metrics) {
273 CriticalSectionScoped crit_scoped(crit_); 292 rtc::CritScope cs(crit_capture_);
274 if (metrics == NULL) { 293 if (metrics == NULL) {
275 return apm_->kNullPointerError; 294 return apm_->kNullPointerError;
276 } 295 }
277 296
278 if (!is_component_enabled() || !metrics_enabled_) { 297 if (!is_component_enabled() || !metrics_enabled_) {
279 return apm_->kNotEnabledError; 298 return apm_->kNotEnabledError;
280 } 299 }
281 300
282 AecMetrics my_metrics; 301 AecMetrics my_metrics;
283 memset(&my_metrics, 0, sizeof(my_metrics)); 302 memset(&my_metrics, 0, sizeof(my_metrics));
(...skipping 22 matching lines...) Expand all
306 325
307 metrics->a_nlp.instant = my_metrics.aNlp.instant; 326 metrics->a_nlp.instant = my_metrics.aNlp.instant;
308 metrics->a_nlp.average = my_metrics.aNlp.average; 327 metrics->a_nlp.average = my_metrics.aNlp.average;
309 metrics->a_nlp.maximum = my_metrics.aNlp.max; 328 metrics->a_nlp.maximum = my_metrics.aNlp.max;
310 metrics->a_nlp.minimum = my_metrics.aNlp.min; 329 metrics->a_nlp.minimum = my_metrics.aNlp.min;
311 330
312 return apm_->kNoError; 331 return apm_->kNoError;
313 } 332 }
314 333
315 bool EchoCancellationImpl::stream_has_echo() const { 334 bool EchoCancellationImpl::stream_has_echo() const {
316 return stream_has_echo_; 335 // This is called both from within and from outside of APM, with and
336 // without locks set. Hence the conditional lock handling below.
337 bool stream_has_echo;
338 if (crit_capture_->TryEnter()) {
hlundin-webrtc 2015/11/05 16:11:22 I don't understand this code, but I wonder if rtc:
peah-webrtc 2015/11/06 09:54:32 Sounds like that! Thanks! Done.
339 stream_has_echo = stream_has_echo_;
340 crit_capture_->Leave();
341 } else {
342 stream_has_echo = stream_has_echo_;
343 }
344 return stream_has_echo;
317 } 345 }
318 346
319 int EchoCancellationImpl::enable_delay_logging(bool enable) { 347 int EchoCancellationImpl::enable_delay_logging(bool enable) {
320 CriticalSectionScoped crit_scoped(crit_); 348 rtc::CritScope cs(crit_capture_);
321 delay_logging_enabled_ = enable; 349 delay_logging_enabled_ = enable;
322 return Configure(); 350 return Configure();
323 } 351 }
324 352
325 bool EchoCancellationImpl::is_delay_logging_enabled() const { 353 bool EchoCancellationImpl::is_delay_logging_enabled() const {
354 rtc::CritScope cs(crit_capture_);
326 return delay_logging_enabled_; 355 return delay_logging_enabled_;
327 } 356 }
328 357
329 bool EchoCancellationImpl::is_delay_agnostic_enabled() const { 358 bool EchoCancellationImpl::is_delay_agnostic_enabled() const {
359 // Only called from within APM, hence no locking is needed.
330 return delay_agnostic_enabled_; 360 return delay_agnostic_enabled_;
331 } 361 }
332 362
333 bool EchoCancellationImpl::is_extended_filter_enabled() const { 363 bool EchoCancellationImpl::is_extended_filter_enabled() const {
364 // Only called from within APM, hence no locking is needed.
334 return extended_filter_enabled_; 365 return extended_filter_enabled_;
335 } 366 }
336 367
337 // TODO(bjornv): How should we handle the multi-channel case? 368 // TODO(bjornv): How should we handle the multi-channel case?
338 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) { 369 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std) {
370 rtc::CritScope cs(crit_capture_);
339 float fraction_poor_delays = 0; 371 float fraction_poor_delays = 0;
340 return GetDelayMetrics(median, std, &fraction_poor_delays); 372 return GetDelayMetrics(median, std, &fraction_poor_delays);
341 } 373 }
342 374
343 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std, 375 int EchoCancellationImpl::GetDelayMetrics(int* median, int* std,
344 float* fraction_poor_delays) { 376 float* fraction_poor_delays) {
345 CriticalSectionScoped crit_scoped(crit_); 377 rtc::CritScope cs(crit_capture_);
346 if (median == NULL) { 378 if (median == NULL) {
347 return apm_->kNullPointerError; 379 return apm_->kNullPointerError;
348 } 380 }
349 if (std == NULL) { 381 if (std == NULL) {
350 return apm_->kNullPointerError; 382 return apm_->kNullPointerError;
351 } 383 }
352 384
353 if (!is_component_enabled() || !delay_logging_enabled_) { 385 if (!is_component_enabled() || !delay_logging_enabled_) {
354 return apm_->kNotEnabledError; 386 return apm_->kNotEnabledError;
355 } 387 }
356 388
357 Handle* my_handle = static_cast<Handle*>(handle(0)); 389 Handle* my_handle = static_cast<Handle*>(handle(0));
358 const int err = 390 const int err =
359 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays); 391 WebRtcAec_GetDelayMetrics(my_handle, median, std, fraction_poor_delays);
360 if (err != apm_->kNoError) { 392 if (err != apm_->kNoError) {
361 return MapError(err); 393 return MapError(err);
362 } 394 }
363 395
364 return apm_->kNoError; 396 return apm_->kNoError;
365 } 397 }
366 398
367 struct AecCore* EchoCancellationImpl::aec_core() const { 399 struct AecCore* EchoCancellationImpl::aec_core() const {
368 CriticalSectionScoped crit_scoped(crit_); 400 // Only called from within APM, hence no locking is needed.
369 if (!is_component_enabled()) { 401 if (!is_component_enabled()) {
370 return NULL; 402 return NULL;
371 } 403 }
372 Handle* my_handle = static_cast<Handle*>(handle(0)); 404 Handle* my_handle = static_cast<Handle*>(handle(0));
373 return WebRtcAec_aec_core(my_handle); 405 return WebRtcAec_aec_core(my_handle);
374 } 406 }
375 407
376 int EchoCancellationImpl::Initialize() { 408 int EchoCancellationImpl::Initialize() {
409 // Only called from within APM, hence no locking is needed.
377 int err = ProcessingComponent::Initialize(); 410 int err = ProcessingComponent::Initialize();
378 if (err != apm_->kNoError || !is_component_enabled()) { 411 if (err != apm_->kNoError || !is_component_enabled()) {
379 return err; 412 return err;
380 } 413 }
381 414
382 AllocateRenderQueue(); 415 AllocateRenderQueue();
383 416
384 return apm_->kNoError; 417 return apm_->kNoError;
385 } 418 }
386 419
387 void EchoCancellationImpl::AllocateRenderQueue() { 420 void EchoCancellationImpl::AllocateRenderQueue() {
421 // Only called from within APM, hence no locking is needed.
388 const size_t max_frame_size = std::max(kAllowedValuesOfSamplesPerFrame1, 422 const size_t max_frame_size = std::max(kAllowedValuesOfSamplesPerFrame1,
389 kAllowedValuesOfSamplesPerFrame2); 423 kAllowedValuesOfSamplesPerFrame2);
390 424
391 const size_t new_render_queue_element_max_size = 425 const size_t new_render_queue_element_max_size =
392 std::max(1UL, max_frame_size * num_handles_required()); 426 std::max(1UL, max_frame_size * num_handles_required());
393 427
394 // Reallocate the queue if the queue item size is too small to fit the 428 // Reallocate the queue if the queue item size is too small to fit the
395 // data to put in the queue. 429 // data to put in the queue.
396 if (new_render_queue_element_max_size > render_queue_element_max_size_) { 430 if (new_render_queue_element_max_size > render_queue_element_max_size_) {
397 render_queue_element_max_size_ = new_render_queue_element_max_size; 431 render_queue_element_max_size_ = new_render_queue_element_max_size;
398 432
399 std::vector<float> template_queue_element(render_queue_element_max_size_); 433 std::vector<float> template_queue_element(render_queue_element_max_size_);
400 434
401 render_signal_queue_.reset( 435 render_signal_queue_.reset(
402 new SwapQueue<std::vector<float>, AecRenderQueueItemVerifier>( 436 new SwapQueue<std::vector<float>, AecRenderQueueItemVerifier>(
403 kMaxNumFramesToBuffer, 437 kMaxNumFramesToBuffer,
404 AecRenderQueueItemVerifier(render_queue_element_max_size_), 438 AecRenderQueueItemVerifier(render_queue_element_max_size_),
405 template_queue_element)); 439 template_queue_element));
406 } else { 440 } else {
407 render_signal_queue_->Clear(); 441 render_signal_queue_->Clear();
408 } 442 }
409 443
410 render_queue_buffer_.resize(new_render_queue_element_max_size); 444 render_queue_buffer_.resize(new_render_queue_element_max_size);
411 capture_queue_buffer_.resize(new_render_queue_element_max_size); 445 capture_queue_buffer_.resize(new_render_queue_element_max_size);
412 } 446 }
413 447
414 void EchoCancellationImpl::SetExtraOptions(const Config& config) { 448 void EchoCancellationImpl::SetExtraOptions(const Config& config) {
449 // This is called both from within and from outside of APM, with and
450 // without locks set. Hence the conditional lock handling below.
451 bool locked_locally = crit_capture_->TryEnter();
415 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled; 452 extended_filter_enabled_ = config.Get<ExtendedFilter>().enabled;
416 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled; 453 delay_agnostic_enabled_ = config.Get<DelayAgnostic>().enabled;
417 Configure(); 454 Configure();
455 if (locked_locally) {
456 crit_capture_->Leave();
457 }
418 } 458 }
419 459
420 void* EchoCancellationImpl::CreateHandle() const { 460 void* EchoCancellationImpl::CreateHandle() const {
461 // Only called from within APM, hence no locking is needed.
421 return WebRtcAec_Create(); 462 return WebRtcAec_Create();
422 } 463 }
423 464
424 void EchoCancellationImpl::DestroyHandle(void* handle) const { 465 void EchoCancellationImpl::DestroyHandle(void* handle) const {
466 // Only called from within APM, hence no locking is needed.
425 assert(handle != NULL); 467 assert(handle != NULL);
426 WebRtcAec_Free(static_cast<Handle*>(handle)); 468 WebRtcAec_Free(static_cast<Handle*>(handle));
427 } 469 }
428 470
429 int EchoCancellationImpl::InitializeHandle(void* handle) const { 471 int EchoCancellationImpl::InitializeHandle(void* handle) const {
472 // Only called from within APM, hence no locking is needed.
430 assert(handle != NULL); 473 assert(handle != NULL);
431 // TODO(ajm): Drift compensation is disabled in practice. If restored, it 474 // TODO(ajm): Drift compensation is disabled in practice. If restored, it
432 // should be managed internally and not depend on the hardware sample rate. 475 // should be managed internally and not depend on the hardware sample rate.
433 // For now, just hardcode a 48 kHz value. 476 // For now, just hardcode a 48 kHz value.
434 return WebRtcAec_Init(static_cast<Handle*>(handle), 477 return WebRtcAec_Init(static_cast<Handle*>(handle),
435 apm_->proc_sample_rate_hz(), 478 apm_->proc_sample_rate_hz(),
436 48000); 479 48000);
437 } 480 }
438 481
439 int EchoCancellationImpl::ConfigureHandle(void* handle) const { 482 int EchoCancellationImpl::ConfigureHandle(void* handle) const {
483 // Only called from within APM, hence no locking is needed.
440 assert(handle != NULL); 484 assert(handle != NULL);
441 AecConfig config; 485 AecConfig config;
442 config.metricsMode = metrics_enabled_; 486 config.metricsMode = metrics_enabled_;
443 config.nlpMode = MapSetting(suppression_level_); 487 config.nlpMode = MapSetting(suppression_level_);
444 config.skewMode = drift_compensation_enabled_; 488 config.skewMode = drift_compensation_enabled_;
445 config.delay_logging = delay_logging_enabled_; 489 config.delay_logging = delay_logging_enabled_;
446 490
447 WebRtcAec_enable_extended_filter( 491 WebRtcAec_enable_extended_filter(
448 WebRtcAec_aec_core(static_cast<Handle*>(handle)), 492 WebRtcAec_aec_core(static_cast<Handle*>(handle)),
449 extended_filter_enabled_ ? 1 : 0); 493 extended_filter_enabled_ ? 1 : 0);
450 WebRtcAec_enable_delay_agnostic( 494 WebRtcAec_enable_delay_agnostic(
451 WebRtcAec_aec_core(static_cast<Handle*>(handle)), 495 WebRtcAec_aec_core(static_cast<Handle*>(handle)),
452 delay_agnostic_enabled_ ? 1 : 0); 496 delay_agnostic_enabled_ ? 1 : 0);
453 return WebRtcAec_set_config(static_cast<Handle*>(handle), config); 497 return WebRtcAec_set_config(static_cast<Handle*>(handle), config);
454 } 498 }
455 499
456 int EchoCancellationImpl::num_handles_required() const { 500 int EchoCancellationImpl::num_handles_required() const {
501 // Only called from within APM, hence no locking is needed.
457 return apm_->num_output_channels() * 502 return apm_->num_output_channels() *
458 apm_->num_reverse_channels(); 503 apm_->num_reverse_channels();
459 } 504 }
460 505
461 int EchoCancellationImpl::GetHandleError(void* handle) const { 506 int EchoCancellationImpl::GetHandleError(void* handle) const {
507 // Only called from within APM, hence no locking is needed.
462 assert(handle != NULL); 508 assert(handle != NULL);
463 return AudioProcessing::kUnspecifiedError; 509 return AudioProcessing::kUnspecifiedError;
464 } 510 }
465 511
466 } // namespace webrtc 512 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698