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

Side by Side Diff: webrtc/modules/audio_processing/gain_control_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/gain_control_impl.h" 11 #include "webrtc/modules/audio_processing/gain_control_impl.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 14
15 #include "webrtc/base/criticalsection.h"
15 #include "webrtc/modules/audio_processing/audio_buffer.h" 16 #include "webrtc/modules/audio_processing/audio_buffer.h"
16 #include "webrtc/modules/audio_processing/agc/legacy/gain_control.h" 17 #include "webrtc/modules/audio_processing/agc/legacy/gain_control.h"
17 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
18 18
19 namespace webrtc { 19 namespace webrtc {
20 20
21 typedef void Handle; 21 typedef void Handle;
22 22
23 namespace { 23 namespace {
24 int16_t MapSetting(GainControl::Mode mode) { 24 int16_t MapSetting(GainControl::Mode mode) {
25 switch (mode) { 25 switch (mode) {
26 case GainControl::kAdaptiveAnalog: 26 case GainControl::kAdaptiveAnalog:
27 return kAgcModeAdaptiveAnalog; 27 return kAgcModeAdaptiveAnalog;
28 case GainControl::kAdaptiveDigital: 28 case GainControl::kAdaptiveDigital:
29 return kAgcModeAdaptiveDigital; 29 return kAgcModeAdaptiveDigital;
30 case GainControl::kFixedDigital: 30 case GainControl::kFixedDigital:
31 return kAgcModeFixedDigital; 31 return kAgcModeFixedDigital;
32 } 32 }
33 assert(false); 33 assert(false);
34 return -1; 34 return -1;
35 } 35 }
36 } // namespace 36 } // namespace
37 37
38 const size_t GainControlImpl::kAllowedValuesOfSamplesPerFrame1; 38 const size_t GainControlImpl::kAllowedValuesOfSamplesPerFrame1;
39 const size_t GainControlImpl::kAllowedValuesOfSamplesPerFrame2; 39 const size_t GainControlImpl::kAllowedValuesOfSamplesPerFrame2;
40 40
41 GainControlImpl::GainControlImpl(const AudioProcessing* apm, 41 GainControlImpl::GainControlImpl(const AudioProcessing* apm,
42 CriticalSectionWrapper* crit, 42 rtc::CriticalSection* crit_render,
43 rtc::CriticalSection* crit_capture,
43 rtc::ThreadChecker* render_thread_checker, 44 rtc::ThreadChecker* render_thread_checker,
44 rtc::ThreadChecker* capture_thread_checker) 45 rtc::ThreadChecker* capture_thread_checker)
45 : ProcessingComponent(), 46 : ProcessingComponent(),
46 apm_(apm), 47 apm_(apm),
47 crit_(crit), 48 crit_render_(crit_render),
49 crit_capture_(crit_capture),
48 render_thread_checker_(render_thread_checker), 50 render_thread_checker_(render_thread_checker),
49 capture_thread_checker_(capture_thread_checker), 51 capture_thread_checker_(capture_thread_checker),
50 mode_(kAdaptiveAnalog), 52 mode_(kAdaptiveAnalog),
51 minimum_capture_level_(0), 53 minimum_capture_level_(0),
52 maximum_capture_level_(255), 54 maximum_capture_level_(255),
53 limiter_enabled_(true), 55 limiter_enabled_(true),
54 target_level_dbfs_(3), 56 target_level_dbfs_(3),
55 compression_gain_db_(9), 57 compression_gain_db_(9),
56 analog_capture_level_(0), 58 analog_capture_level_(0),
57 was_analog_level_set_(false), 59 was_analog_level_set_(false),
(...skipping 20 matching lines...) Expand all
78 80
79 if (err != apm_->kNoError) 81 if (err != apm_->kNoError)
80 return GetHandleError(my_handle); 82 return GetHandleError(my_handle);
81 83
82 // Buffer the samples in the render queue. 84 // Buffer the samples in the render queue.
83 render_queue_buffer_.insert( 85 render_queue_buffer_.insert(
84 render_queue_buffer_.end(), audio->mixed_low_pass_data(), 86 render_queue_buffer_.end(), audio->mixed_low_pass_data(),
85 (audio->mixed_low_pass_data() + audio->num_frames_per_band())); 87 (audio->mixed_low_pass_data() + audio->num_frames_per_band()));
86 } 88 }
87 89
88 // Check of success is temporarily disabled as it breaks a unit test. 90 // Insert the samples into the queue.
89 // TODO(peah): Will be fixed in the next CL. 91 bool success = render_signal_queue_->Insert(&render_queue_buffer_);
hlundin-webrtc 2015/11/05 16:11:22 if (!render_signal_queue_->Insert(&render_queue_bu
peah-webrtc 2015/11/06 09:54:32 Done.
90 (void)render_signal_queue_->Insert(&render_queue_buffer_); 92 if (!success) {
93 // The data queue is full and needs to be emptied.
94 {
95 rtc::CritScope cs_capture(crit_capture_);
96 ReadQueuedRenderData();
97 }
98
99 // Retry the insert (should always work).
100 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true);
101 }
91 102
92 return apm_->kNoError; 103 return apm_->kNoError;
93 } 104 }
94 105
95 // Read chunks of data that were received and queued on the render side from 106 // Read chunks of data that were received and queued on the render side from
96 // a queue. All the data chunks are buffered into the farend signal of the AGC. 107 // a queue. All the data chunks are buffered into the farend signal of the AGC.
97 void GainControlImpl::ReadQueuedRenderData() { 108 void GainControlImpl::ReadQueuedRenderData() {
98 if (!is_component_enabled()) { 109 if (!is_component_enabled()) {
99 return; 110 return;
100 } 111 }
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 229
219 // TODO(ajm): ensure this is called under kAdaptiveAnalog. 230 // TODO(ajm): ensure this is called under kAdaptiveAnalog.
220 int GainControlImpl::set_stream_analog_level(int level) { 231 int GainControlImpl::set_stream_analog_level(int level) {
221 RTC_DCHECK(capture_thread_checker_->CalledOnValidThread()); 232 RTC_DCHECK(capture_thread_checker_->CalledOnValidThread());
222 // TODO(peah): Verify that this is really needed to do the reading. 233 // TODO(peah): Verify that this is really needed to do the reading.
223 // here as well as in ProcessStream. It works since these functions 234 // here as well as in ProcessStream. It works since these functions
224 // are called from the same thread, but it is not nice to do it in two 235 // are called from the same thread, but it is not nice to do it in two
225 // places if not needed. 236 // places if not needed.
226 ReadQueuedRenderData(); 237 ReadQueuedRenderData();
227 238
228 CriticalSectionScoped crit_scoped(crit_); 239 rtc::CritScope cs(crit_capture_);
229 was_analog_level_set_ = true; 240 was_analog_level_set_ = true;
230 if (level < minimum_capture_level_ || level > maximum_capture_level_) { 241 if (level < minimum_capture_level_ || level > maximum_capture_level_) {
231 return apm_->kBadParameterError; 242 return apm_->kBadParameterError;
232 } 243 }
233 analog_capture_level_ = level; 244 analog_capture_level_ = level;
234 245
235 return apm_->kNoError; 246 return apm_->kNoError;
236 } 247 }
237 248
238 int GainControlImpl::stream_analog_level() { 249 int GainControlImpl::stream_analog_level() {
250 rtc::CritScope cs(crit_capture_);
239 RTC_DCHECK(capture_thread_checker_->CalledOnValidThread()); 251 RTC_DCHECK(capture_thread_checker_->CalledOnValidThread());
240 // TODO(ajm): enable this assertion? 252 // TODO(ajm): enable this assertion?
241 //assert(mode_ == kAdaptiveAnalog); 253 //assert(mode_ == kAdaptiveAnalog);
242 254
243 return analog_capture_level_; 255 return analog_capture_level_;
244 } 256 }
245 257
246 int GainControlImpl::Enable(bool enable) { 258 int GainControlImpl::Enable(bool enable) {
247 CriticalSectionScoped crit_scoped(crit_); 259 rtc::CritScope cs_render(crit_render_);
260 rtc::CritScope cs(crit_capture_);
248 return EnableComponent(enable); 261 return EnableComponent(enable);
249 } 262 }
250 263
251 bool GainControlImpl::is_enabled() const { 264 bool GainControlImpl::is_enabled() const {
265 rtc::CritScope cs(crit_capture_);
252 return is_component_enabled(); 266 return is_component_enabled();
253 } 267 }
254 268
255 int GainControlImpl::set_mode(Mode mode) { 269 int GainControlImpl::set_mode(Mode mode) {
256 CriticalSectionScoped crit_scoped(crit_); 270 rtc::CritScope cs_render(crit_render_);
271 rtc::CritScope cs_capture(crit_capture_);
257 if (MapSetting(mode) == -1) { 272 if (MapSetting(mode) == -1) {
258 return apm_->kBadParameterError; 273 return apm_->kBadParameterError;
259 } 274 }
260 275
261 mode_ = mode; 276 mode_ = mode;
262 return Initialize(); 277 return Initialize();
263 } 278 }
264 279
265 GainControl::Mode GainControlImpl::mode() const { 280 GainControl::Mode GainControlImpl::mode() const {
281 rtc::CritScope cs(crit_capture_);
266 return mode_; 282 return mode_;
267 } 283 }
268 284
269 int GainControlImpl::set_analog_level_limits(int minimum, 285 int GainControlImpl::set_analog_level_limits(int minimum,
270 int maximum) { 286 int maximum) {
271 CriticalSectionScoped crit_scoped(crit_); 287 rtc::CritScope cs(crit_capture_);
272 if (minimum < 0) { 288 if (minimum < 0) {
273 return apm_->kBadParameterError; 289 return apm_->kBadParameterError;
274 } 290 }
275 291
276 if (maximum > 65535) { 292 if (maximum > 65535) {
277 return apm_->kBadParameterError; 293 return apm_->kBadParameterError;
278 } 294 }
279 295
280 if (maximum < minimum) { 296 if (maximum < minimum) {
281 return apm_->kBadParameterError; 297 return apm_->kBadParameterError;
282 } 298 }
283 299
284 minimum_capture_level_ = minimum; 300 minimum_capture_level_ = minimum;
285 maximum_capture_level_ = maximum; 301 maximum_capture_level_ = maximum;
286 302
287 return Initialize(); 303 return Initialize();
288 } 304 }
289 305
290 int GainControlImpl::analog_level_minimum() const { 306 int GainControlImpl::analog_level_minimum() const {
307 rtc::CritScope cs(crit_capture_);
291 return minimum_capture_level_; 308 return minimum_capture_level_;
292 } 309 }
293 310
294 int GainControlImpl::analog_level_maximum() const { 311 int GainControlImpl::analog_level_maximum() const {
312 rtc::CritScope cs(crit_capture_);
295 return maximum_capture_level_; 313 return maximum_capture_level_;
296 } 314 }
297 315
298 bool GainControlImpl::stream_is_saturated() const { 316 bool GainControlImpl::stream_is_saturated() const {
317 rtc::CritScope cs(crit_capture_);
299 return stream_is_saturated_; 318 return stream_is_saturated_;
300 } 319 }
301 320
302 int GainControlImpl::set_target_level_dbfs(int level) { 321 int GainControlImpl::set_target_level_dbfs(int level) {
303 CriticalSectionScoped crit_scoped(crit_); 322 rtc::CritScope cs(crit_capture_);
304 if (level > 31 || level < 0) { 323 if (level > 31 || level < 0) {
305 return apm_->kBadParameterError; 324 return apm_->kBadParameterError;
306 } 325 }
307 326
308 target_level_dbfs_ = level; 327 target_level_dbfs_ = level;
309 return Configure(); 328 return Configure();
310 } 329 }
311 330
312 int GainControlImpl::target_level_dbfs() const { 331 int GainControlImpl::target_level_dbfs() const {
332 rtc::CritScope cs(crit_capture_);
313 return target_level_dbfs_; 333 return target_level_dbfs_;
314 } 334 }
315 335
316 int GainControlImpl::set_compression_gain_db(int gain) { 336 int GainControlImpl::set_compression_gain_db(int gain) {
317 CriticalSectionScoped crit_scoped(crit_); 337 rtc::CritScope cs(crit_capture_);
318 if (gain < 0 || gain > 90) { 338 if (gain < 0 || gain > 90) {
319 return apm_->kBadParameterError; 339 return apm_->kBadParameterError;
320 } 340 }
321 341
322 compression_gain_db_ = gain; 342 compression_gain_db_ = gain;
323 return Configure(); 343 return Configure();
324 } 344 }
325 345
326 int GainControlImpl::compression_gain_db() const { 346 int GainControlImpl::compression_gain_db() const {
347 rtc::CritScope cs(crit_capture_);
327 return compression_gain_db_; 348 return compression_gain_db_;
328 } 349 }
329 350
330 int GainControlImpl::enable_limiter(bool enable) { 351 int GainControlImpl::enable_limiter(bool enable) {
331 CriticalSectionScoped crit_scoped(crit_); 352 rtc::CritScope cs(crit_capture_);
332 limiter_enabled_ = enable; 353 limiter_enabled_ = enable;
333 return Configure(); 354 return Configure();
334 } 355 }
335 356
336 bool GainControlImpl::is_limiter_enabled() const { 357 bool GainControlImpl::is_limiter_enabled() const {
358 rtc::CritScope cs(crit_capture_);
337 return limiter_enabled_; 359 return limiter_enabled_;
338 } 360 }
339 361
340 int GainControlImpl::Initialize() { 362 int GainControlImpl::Initialize() {
341 int err = ProcessingComponent::Initialize(); 363 int err = ProcessingComponent::Initialize();
342 if (err != apm_->kNoError || !is_component_enabled()) { 364 if (err != apm_->kNoError || !is_component_enabled()) {
343 return err; 365 return err;
344 } 366 }
345 367
346 AllocateRenderQueue(); 368 AllocateRenderQueue();
347 369
348 capture_levels_.assign(num_handles(), analog_capture_level_); 370 capture_levels_.assign(num_handles(), analog_capture_level_);
349 return apm_->kNoError; 371 return apm_->kNoError;
350 } 372 }
351 373
352 void GainControlImpl::AllocateRenderQueue() { 374 void GainControlImpl::AllocateRenderQueue() {
375 // Only called from within APM, hence no locking is needed.
353 const size_t max_frame_size = std::max(kAllowedValuesOfSamplesPerFrame1, 376 const size_t max_frame_size = std::max(kAllowedValuesOfSamplesPerFrame1,
354 kAllowedValuesOfSamplesPerFrame2); 377 kAllowedValuesOfSamplesPerFrame2);
355 378
356 const size_t new_render_queue_element_max_size = 379 const size_t new_render_queue_element_max_size =
357 std::max(1UL, (max_frame_size * num_handles())); 380 std::max(1UL, (max_frame_size * num_handles()));
358 381
359 if (new_render_queue_element_max_size > render_queue_element_max_size_) { 382 if (new_render_queue_element_max_size > render_queue_element_max_size_) {
360 std::vector<int16_t> template_queue_element(render_queue_element_max_size_); 383 std::vector<int16_t> template_queue_element(render_queue_element_max_size_);
361 384
362 render_signal_queue_.reset( 385 render_signal_queue_.reset(
363 new SwapQueue<std::vector<int16_t>, AgcRenderQueueItemVerifier>( 386 new SwapQueue<std::vector<int16_t>, AgcRenderQueueItemVerifier>(
364 kMaxNumFramesToBuffer, 387 kMaxNumFramesToBuffer,
365 AgcRenderQueueItemVerifier(render_queue_element_max_size_), 388 AgcRenderQueueItemVerifier(render_queue_element_max_size_),
366 template_queue_element)); 389 template_queue_element));
367 } else { 390 } else {
368 render_signal_queue_->Clear(); 391 render_signal_queue_->Clear();
369 } 392 }
370 393
371 render_queue_buffer_.resize(new_render_queue_element_max_size); 394 render_queue_buffer_.resize(new_render_queue_element_max_size);
372 capture_queue_buffer_.resize(new_render_queue_element_max_size); 395 capture_queue_buffer_.resize(new_render_queue_element_max_size);
373 } 396 }
374 397
375 void* GainControlImpl::CreateHandle() const { 398 void* GainControlImpl::CreateHandle() const {
399 // Only called from within APM, hence no locking is needed.
376 return WebRtcAgc_Create(); 400 return WebRtcAgc_Create();
377 } 401 }
378 402
379 void GainControlImpl::DestroyHandle(void* handle) const { 403 void GainControlImpl::DestroyHandle(void* handle) const {
404 // Only called from within APM, hence no locking is needed.
380 WebRtcAgc_Free(static_cast<Handle*>(handle)); 405 WebRtcAgc_Free(static_cast<Handle*>(handle));
381 } 406 }
382 407
383 int GainControlImpl::InitializeHandle(void* handle) const { 408 int GainControlImpl::InitializeHandle(void* handle) const {
409 // Only called from within APM, hence no locking is needed.
384 return WebRtcAgc_Init(static_cast<Handle*>(handle), 410 return WebRtcAgc_Init(static_cast<Handle*>(handle),
385 minimum_capture_level_, 411 minimum_capture_level_,
386 maximum_capture_level_, 412 maximum_capture_level_,
387 MapSetting(mode_), 413 MapSetting(mode_),
388 apm_->proc_sample_rate_hz()); 414 apm_->proc_sample_rate_hz());
389 } 415 }
390 416
391 int GainControlImpl::ConfigureHandle(void* handle) const { 417 int GainControlImpl::ConfigureHandle(void* handle) const {
418 // Only called from within APM, hence no locking is needed.
392 WebRtcAgcConfig config; 419 WebRtcAgcConfig config;
393 // TODO(ajm): Flip the sign here (since AGC expects a positive value) if we 420 // TODO(ajm): Flip the sign here (since AGC expects a positive value) if we
394 // change the interface. 421 // change the interface.
395 //assert(target_level_dbfs_ <= 0); 422 //assert(target_level_dbfs_ <= 0);
396 //config.targetLevelDbfs = static_cast<int16_t>(-target_level_dbfs_); 423 //config.targetLevelDbfs = static_cast<int16_t>(-target_level_dbfs_);
397 config.targetLevelDbfs = static_cast<int16_t>(target_level_dbfs_); 424 config.targetLevelDbfs = static_cast<int16_t>(target_level_dbfs_);
398 config.compressionGaindB = 425 config.compressionGaindB =
399 static_cast<int16_t>(compression_gain_db_); 426 static_cast<int16_t>(compression_gain_db_);
400 config.limiterEnable = limiter_enabled_; 427 config.limiterEnable = limiter_enabled_;
401 428
402 return WebRtcAgc_set_config(static_cast<Handle*>(handle), config); 429 return WebRtcAgc_set_config(static_cast<Handle*>(handle), config);
403 } 430 }
404 431
405 int GainControlImpl::num_handles_required() const { 432 int GainControlImpl::num_handles_required() const {
433 // Only called from within APM, hence no locking is needed.
406 return apm_->num_output_channels(); 434 return apm_->num_output_channels();
407 } 435 }
408 436
409 int GainControlImpl::GetHandleError(void* handle) const { 437 int GainControlImpl::GetHandleError(void* handle) const {
438 // Only called from within APM, hence no locking is needed.
410 // The AGC has no get_error() function. 439 // The AGC has no get_error() function.
411 // (Despite listing errors in its interface...) 440 // (Despite listing errors in its interface...)
412 assert(handle != NULL); 441 assert(handle != NULL);
413 return apm_->kUnspecifiedError; 442 return apm_->kUnspecifiedError;
414 } 443 }
415 } // namespace webrtc 444 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698