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

Side by Side Diff: webrtc/modules/audio_processing/echo_control_mobile_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: Fixed a bad merge error for the beamformer settings and updated with the latest merge from master 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_control_mobile_impl.h" 11 #include "webrtc/modules/audio_processing/echo_control_mobile_impl.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <string.h> 14 #include <string.h>
15 15
16 #include "webrtc/modules/audio_processing/aecm/echo_control_mobile.h" 16 #include "webrtc/modules/audio_processing/aecm/echo_control_mobile.h"
17 #include "webrtc/modules/audio_processing/audio_buffer.h" 17 #include "webrtc/modules/audio_processing/audio_buffer.h"
18 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
19 #include "webrtc/system_wrappers/include/logging.h" 18 #include "webrtc/system_wrappers/include/logging.h"
20 19
21 namespace webrtc { 20 namespace webrtc {
22 21
23 typedef void Handle; 22 typedef void Handle;
24 23
25 namespace { 24 namespace {
26 int16_t MapSetting(EchoControlMobile::RoutingMode mode) { 25 int16_t MapSetting(EchoControlMobile::RoutingMode mode) {
27 switch (mode) { 26 switch (mode) {
28 case EchoControlMobile::kQuietEarpieceOrHeadset: 27 case EchoControlMobile::kQuietEarpieceOrHeadset:
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 // reverse and forward call numbers. 62 // reverse and forward call numbers.
64 static const size_t kMaxNumFramesToBuffer = 100; 63 static const size_t kMaxNumFramesToBuffer = 100;
65 } // namespace 64 } // namespace
66 65
67 size_t EchoControlMobile::echo_path_size_bytes() { 66 size_t EchoControlMobile::echo_path_size_bytes() {
68 return WebRtcAecm_echo_path_size_bytes(); 67 return WebRtcAecm_echo_path_size_bytes();
69 } 68 }
70 69
71 EchoControlMobileImpl::EchoControlMobileImpl( 70 EchoControlMobileImpl::EchoControlMobileImpl(
72 const AudioProcessing* apm, 71 const AudioProcessing* apm,
73 CriticalSectionWrapper* crit, 72 rtc::CriticalSection* crit_render,
73 rtc::CriticalSection* crit_capture,
74 const rtc::ThreadChecker* render_thread_checker) 74 const rtc::ThreadChecker* render_thread_checker)
75 : ProcessingComponent(), 75 : ProcessingComponent(),
76 apm_(apm), 76 apm_(apm),
77 crit_(crit), 77 crit_render_(crit_render),
78 crit_capture_(crit_capture),
78 render_thread_checker_(render_thread_checker), 79 render_thread_checker_(render_thread_checker),
79 routing_mode_(kSpeakerphone), 80 routing_mode_(kSpeakerphone),
80 comfort_noise_enabled_(true), 81 comfort_noise_enabled_(true),
81 external_echo_path_(NULL), 82 external_echo_path_(NULL),
82 render_queue_element_max_size_(0) {} 83 render_queue_element_max_size_(0) {}
83 84
84 EchoControlMobileImpl::~EchoControlMobileImpl() { 85 EchoControlMobileImpl::~EchoControlMobileImpl() {
85 if (external_echo_path_ != NULL) { 86 if (external_echo_path_ != NULL) {
86 delete [] external_echo_path_; 87 delete [] external_echo_path_;
87 external_echo_path_ = NULL; 88 external_echo_path_ = NULL;
(...skipping 29 matching lines...) Expand all
117 audio->split_bands_const(j)[kBand0To8kHz], 118 audio->split_bands_const(j)[kBand0To8kHz],
118 (audio->split_bands_const(j)[kBand0To8kHz] + 119 (audio->split_bands_const(j)[kBand0To8kHz] +
119 audio->num_frames_per_band())); 120 audio->num_frames_per_band()));
120 121
121 handle_index++; 122 handle_index++;
122 } 123 }
123 } 124 }
124 125
125 // Insert the samples into the queue. 126 // Insert the samples into the queue.
126 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { 127 if (!render_signal_queue_->Insert(&render_queue_buffer_)) {
127 ReadQueuedRenderData(); 128 // The data queue is full and needs to be emptied.
129 {
130 rtc::CritScope cs_capture(crit_capture_);
131 ReadQueuedRenderData();
132 }
128 133
129 // Retry the insert (should always work). 134 // Retry the insert (should always work).
130 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); 135 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true);
131 } 136 }
132 137
133 return apm_->kNoError; 138 return apm_->kNoError;
134 } 139 }
135 140
136 // Read chunks of data that were received and queued on the render side from 141 // Read chunks of data that were received and queued on the render side from
137 // a queue. All the data chunks are buffered into the farend signal of the AEC. 142 // a queue. All the data chunks are buffered into the farend signal of the AEC.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 return MapError(err); 203 return MapError(err);
199 204
200 handle_index++; 205 handle_index++;
201 } 206 }
202 } 207 }
203 208
204 return apm_->kNoError; 209 return apm_->kNoError;
205 } 210 }
206 211
207 int EchoControlMobileImpl::Enable(bool enable) { 212 int EchoControlMobileImpl::Enable(bool enable) {
208 CriticalSectionScoped crit_scoped(crit_); 213 // Run in a single-threaded manner
214 rtc::CritScope cs_render(crit_render_);
215 rtc::CritScope cs_capture(crit_capture_);
209 // Ensure AEC and AECM are not both enabled. 216 // Ensure AEC and AECM are not both enabled.
210 if (enable && apm_->echo_cancellation()->is_enabled()) { 217 if (enable && apm_->echo_cancellation()->is_enabled()) {
211 return apm_->kBadParameterError; 218 return apm_->kBadParameterError;
212 } 219 }
213 220
214 return EnableComponent(enable); 221 return EnableComponent(enable);
215 } 222 }
216 223
217 bool EchoControlMobileImpl::is_enabled() const { 224 bool EchoControlMobileImpl::is_enabled() const {
225 rtc::CritScope cs(crit_capture_);
218 return is_component_enabled(); 226 return is_component_enabled();
219 } 227 }
220 228
221 int EchoControlMobileImpl::set_routing_mode(RoutingMode mode) { 229 int EchoControlMobileImpl::set_routing_mode(RoutingMode mode) {
222 CriticalSectionScoped crit_scoped(crit_); 230 rtc::CritScope cs(crit_capture_);
223 if (MapSetting(mode) == -1) { 231 if (MapSetting(mode) == -1) {
224 return apm_->kBadParameterError; 232 return apm_->kBadParameterError;
225 } 233 }
226 234
227 routing_mode_ = mode; 235 routing_mode_ = mode;
228 return Configure(); 236 return Configure();
229 } 237 }
230 238
231 EchoControlMobile::RoutingMode EchoControlMobileImpl::routing_mode() 239 EchoControlMobile::RoutingMode EchoControlMobileImpl::routing_mode()
232 const { 240 const {
241 rtc::CritScope cs(crit_capture_);
233 return routing_mode_; 242 return routing_mode_;
234 } 243 }
235 244
236 int EchoControlMobileImpl::enable_comfort_noise(bool enable) { 245 int EchoControlMobileImpl::enable_comfort_noise(bool enable) {
237 CriticalSectionScoped crit_scoped(crit_); 246 rtc::CritScope cs(crit_capture_);
238 comfort_noise_enabled_ = enable; 247 comfort_noise_enabled_ = enable;
239 return Configure(); 248 return Configure();
240 } 249 }
241 250
242 bool EchoControlMobileImpl::is_comfort_noise_enabled() const { 251 bool EchoControlMobileImpl::is_comfort_noise_enabled() const {
252 rtc::CritScope cs(crit_capture_);
243 return comfort_noise_enabled_; 253 return comfort_noise_enabled_;
244 } 254 }
245 255
246 int EchoControlMobileImpl::SetEchoPath(const void* echo_path, 256 int EchoControlMobileImpl::SetEchoPath(const void* echo_path,
247 size_t size_bytes) { 257 size_t size_bytes) {
248 CriticalSectionScoped crit_scoped(crit_); 258 rtc::CritScope cs_render(crit_render_);
259 rtc::CritScope cs_capture(crit_capture_);
249 if (echo_path == NULL) { 260 if (echo_path == NULL) {
250 return apm_->kNullPointerError; 261 return apm_->kNullPointerError;
251 } 262 }
252 if (size_bytes != echo_path_size_bytes()) { 263 if (size_bytes != echo_path_size_bytes()) {
253 // Size mismatch 264 // Size mismatch
254 return apm_->kBadParameterError; 265 return apm_->kBadParameterError;
255 } 266 }
256 267
257 if (external_echo_path_ == NULL) { 268 if (external_echo_path_ == NULL) {
258 external_echo_path_ = new unsigned char[size_bytes]; 269 external_echo_path_ = new unsigned char[size_bytes];
259 } 270 }
260 memcpy(external_echo_path_, echo_path, size_bytes); 271 memcpy(external_echo_path_, echo_path, size_bytes);
261 272
262 return Initialize(); 273 return Initialize();
263 } 274 }
264 275
265 int EchoControlMobileImpl::GetEchoPath(void* echo_path, 276 int EchoControlMobileImpl::GetEchoPath(void* echo_path,
266 size_t size_bytes) const { 277 size_t size_bytes) const {
267 CriticalSectionScoped crit_scoped(crit_); 278 rtc::CritScope cs(crit_capture_);
268 if (echo_path == NULL) { 279 if (echo_path == NULL) {
269 return apm_->kNullPointerError; 280 return apm_->kNullPointerError;
270 } 281 }
271 if (size_bytes != echo_path_size_bytes()) { 282 if (size_bytes != echo_path_size_bytes()) {
272 // Size mismatch 283 // Size mismatch
273 return apm_->kBadParameterError; 284 return apm_->kBadParameterError;
274 } 285 }
275 if (!is_component_enabled()) { 286 if (!is_component_enabled()) {
276 return apm_->kNotEnabledError; 287 return apm_->kNotEnabledError;
277 } 288 }
278 289
279 // Get the echo path from the first channel 290 // Get the echo path from the first channel
280 Handle* my_handle = static_cast<Handle*>(handle(0)); 291 Handle* my_handle = static_cast<Handle*>(handle(0));
281 int32_t err = WebRtcAecm_GetEchoPath(my_handle, echo_path, size_bytes); 292 int32_t err = WebRtcAecm_GetEchoPath(my_handle, echo_path, size_bytes);
282 if (err != 0) 293 if (err != 0)
283 return MapError(err); 294 return MapError(err);
284 295
285 return apm_->kNoError; 296 return apm_->kNoError;
286 } 297 }
287 298
288 int EchoControlMobileImpl::Initialize() { 299 int EchoControlMobileImpl::Initialize() {
300 // Only called from within APM, hence no locking is needed.
289 if (!is_component_enabled()) { 301 if (!is_component_enabled()) {
290 return apm_->kNoError; 302 return apm_->kNoError;
291 } 303 }
292 304
293 if (apm_->proc_sample_rate_hz() > apm_->kSampleRate16kHz) { 305 if (apm_->proc_sample_rate_hz() > apm_->kSampleRate16kHz) {
294 LOG(LS_ERROR) << "AECM only supports 16 kHz or lower sample rates"; 306 LOG(LS_ERROR) << "AECM only supports 16 kHz or lower sample rates";
295 return apm_->kBadSampleRateError; 307 return apm_->kBadSampleRateError;
296 } 308 }
297 309
298 int err = ProcessingComponent::Initialize(); 310 int err = ProcessingComponent::Initialize();
(...skipping 24 matching lines...) Expand all
323 RenderQueueItemVerifier<int16_t>(render_queue_element_max_size_))); 335 RenderQueueItemVerifier<int16_t>(render_queue_element_max_size_)));
324 336
325 render_queue_buffer_.resize(render_queue_element_max_size_); 337 render_queue_buffer_.resize(render_queue_element_max_size_);
326 capture_queue_buffer_.resize(render_queue_element_max_size_); 338 capture_queue_buffer_.resize(render_queue_element_max_size_);
327 } else { 339 } else {
328 render_signal_queue_->Clear(); 340 render_signal_queue_->Clear();
329 } 341 }
330 } 342 }
331 343
332 void* EchoControlMobileImpl::CreateHandle() const { 344 void* EchoControlMobileImpl::CreateHandle() const {
345 // Only called from within APM, hence no locking is needed.
333 return WebRtcAecm_Create(); 346 return WebRtcAecm_Create();
334 } 347 }
335 348
336 void EchoControlMobileImpl::DestroyHandle(void* handle) const { 349 void EchoControlMobileImpl::DestroyHandle(void* handle) const {
350 // Only called from within APM, hence no locking is needed.
337 WebRtcAecm_Free(static_cast<Handle*>(handle)); 351 WebRtcAecm_Free(static_cast<Handle*>(handle));
338 } 352 }
339 353
340 int EchoControlMobileImpl::InitializeHandle(void* handle) const { 354 int EchoControlMobileImpl::InitializeHandle(void* handle) const {
355 // Only called from within APM, hence no locking is needed.
341 assert(handle != NULL); 356 assert(handle != NULL);
342 Handle* my_handle = static_cast<Handle*>(handle); 357 Handle* my_handle = static_cast<Handle*>(handle);
343 if (WebRtcAecm_Init(my_handle, apm_->proc_sample_rate_hz()) != 0) { 358 if (WebRtcAecm_Init(my_handle, apm_->proc_sample_rate_hz()) != 0) {
344 return GetHandleError(my_handle); 359 return GetHandleError(my_handle);
345 } 360 }
346 if (external_echo_path_ != NULL) { 361 if (external_echo_path_ != NULL) {
347 if (WebRtcAecm_InitEchoPath(my_handle, 362 if (WebRtcAecm_InitEchoPath(my_handle,
348 external_echo_path_, 363 external_echo_path_,
349 echo_path_size_bytes()) != 0) { 364 echo_path_size_bytes()) != 0) {
350 return GetHandleError(my_handle); 365 return GetHandleError(my_handle);
351 } 366 }
352 } 367 }
353 368
354 return apm_->kNoError; 369 return apm_->kNoError;
355 } 370 }
356 371
357 int EchoControlMobileImpl::ConfigureHandle(void* handle) const { 372 int EchoControlMobileImpl::ConfigureHandle(void* handle) const {
373 // Only called from within APM, hence no locking is needed.
358 AecmConfig config; 374 AecmConfig config;
359 config.cngMode = comfort_noise_enabled_; 375 config.cngMode = comfort_noise_enabled_;
360 config.echoMode = MapSetting(routing_mode_); 376 config.echoMode = MapSetting(routing_mode_);
361 377
362 return WebRtcAecm_set_config(static_cast<Handle*>(handle), config); 378 return WebRtcAecm_set_config(static_cast<Handle*>(handle), config);
363 } 379 }
364 380
365 int EchoControlMobileImpl::num_handles_required() const { 381 int EchoControlMobileImpl::num_handles_required() const {
382 // Only called from within APM, hence no locking is needed.
366 return apm_->num_output_channels() * 383 return apm_->num_output_channels() *
367 apm_->num_reverse_channels(); 384 apm_->num_reverse_channels();
368 } 385 }
369 386
370 int EchoControlMobileImpl::GetHandleError(void* handle) const { 387 int EchoControlMobileImpl::GetHandleError(void* handle) const {
388 // Only called from within APM, hence no locking is needed.
371 assert(handle != NULL); 389 assert(handle != NULL);
372 return AudioProcessing::kUnspecifiedError; 390 return AudioProcessing::kUnspecifiedError;
373 } 391 }
374 } // namespace webrtc 392 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698