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

Side by Side Diff: content/renderer/media/media_stream_audio_processor.cc

Issue 227743004: Added a kEchoCancellation constraint to turn off the audio processing. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: added a GetEchoCancellationProperty method. Created 6 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/renderer/media/media_stream_audio_processor.h" 5 #include "content/renderer/media/media_stream_audio_processor.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/metrics/field_trial.h" 9 #include "base/metrics/field_trial.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "content/public/common/content_switches.h" 11 #include "content/public/common/content_switches.h"
12 #include "content/renderer/media/media_stream_audio_processor_options.h" 12 #include "content/renderer/media/media_stream_audio_processor_options.h"
13 #include "content/renderer/media/rtc_media_constraints.h" 13 #include "content/renderer/media/rtc_media_constraints.h"
14 #include "content/renderer/media/webrtc_audio_device_impl.h" 14 #include "content/renderer/media/webrtc_audio_device_impl.h"
15 #include "media/audio/audio_parameters.h" 15 #include "media/audio/audio_parameters.h"
16 #include "media/base/audio_converter.h" 16 #include "media/base/audio_converter.h"
17 #include "media/base/audio_fifo.h" 17 #include "media/base/audio_fifo.h"
18 #include "media/base/channel_layout.h" 18 #include "media/base/channel_layout.h"
19 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 19 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
20 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface .h" 20 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface .h"
21 #include "third_party/webrtc/modules/audio_processing/typing_detection.h" 21 #include "third_party/webrtc/modules/audio_processing/typing_detection.h"
22 22
23 namespace content { 23 namespace content {
24 24
25 namespace { 25 namespace {
26 26
27 using webrtc::AudioProcessing; 27 using webrtc::AudioProcessing;
28 using webrtc::MediaConstraintsInterface;
29 28
30 #if defined(OS_ANDROID) 29 #if defined(OS_ANDROID)
31 const int kAudioProcessingSampleRate = 16000; 30 const int kAudioProcessingSampleRate = 16000;
32 #else 31 #else
33 const int kAudioProcessingSampleRate = 32000; 32 const int kAudioProcessingSampleRate = 32000;
34 #endif 33 #endif
35 const int kAudioProcessingNumberOfChannels = 1; 34 const int kAudioProcessingNumberOfChannels = 1;
36 const AudioProcessing::ChannelLayout kAudioProcessingChannelLayout = 35 const AudioProcessing::ChannelLayout kAudioProcessingChannelLayout =
37 AudioProcessing::kMono; 36 AudioProcessing::kMono;
38 37
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 bool MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled() { 159 bool MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled() {
161 const std::string group_name = 160 const std::string group_name =
162 base::FieldTrialList::FindFullName("MediaStreamAudioTrackProcessing"); 161 base::FieldTrialList::FindFullName("MediaStreamAudioTrackProcessing");
163 return group_name == "Enabled" || CommandLine::ForCurrentProcess()->HasSwitch( 162 return group_name == "Enabled" || CommandLine::ForCurrentProcess()->HasSwitch(
164 switches::kEnableAudioTrackProcessing); 163 switches::kEnableAudioTrackProcessing);
165 } 164 }
166 165
167 MediaStreamAudioProcessor::MediaStreamAudioProcessor( 166 MediaStreamAudioProcessor::MediaStreamAudioProcessor(
168 const blink::WebMediaConstraints& constraints, 167 const blink::WebMediaConstraints& constraints,
169 int effects, 168 int effects,
170 MediaStreamType type,
171 WebRtcPlayoutDataSource* playout_data_source) 169 WebRtcPlayoutDataSource* playout_data_source)
172 : render_delay_ms_(0), 170 : render_delay_ms_(0),
173 playout_data_source_(playout_data_source), 171 playout_data_source_(playout_data_source),
174 audio_mirroring_(false), 172 audio_mirroring_(false),
175 typing_detected_(false) { 173 typing_detected_(false) {
176 capture_thread_checker_.DetachFromThread(); 174 capture_thread_checker_.DetachFromThread();
177 render_thread_checker_.DetachFromThread(); 175 render_thread_checker_.DetachFromThread();
178 InitializeAudioProcessingModule(constraints, effects, type); 176 InitializeAudioProcessingModule(constraints, effects);
179 } 177 }
180 178
181 MediaStreamAudioProcessor::~MediaStreamAudioProcessor() { 179 MediaStreamAudioProcessor::~MediaStreamAudioProcessor() {
182 DCHECK(main_thread_checker_.CalledOnValidThread()); 180 DCHECK(main_thread_checker_.CalledOnValidThread());
183 StopAudioProcessing(); 181 StopAudioProcessing();
184 } 182 }
185 183
186 void MediaStreamAudioProcessor::OnCaptureFormatChanged( 184 void MediaStreamAudioProcessor::OnCaptureFormatChanged(
187 const media::AudioParameters& source_params) { 185 const media::AudioParameters& source_params) {
188 DCHECK(main_thread_checker_.CalledOnValidThread()); 186 DCHECK(main_thread_checker_.CalledOnValidThread());
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 render_converter_.reset(); 277 render_converter_.reset();
280 } 278 }
281 279
282 void MediaStreamAudioProcessor::GetStats(AudioProcessorStats* stats) { 280 void MediaStreamAudioProcessor::GetStats(AudioProcessorStats* stats) {
283 stats->typing_noise_detected = 281 stats->typing_noise_detected =
284 (base::subtle::Acquire_Load(&typing_detected_) != false); 282 (base::subtle::Acquire_Load(&typing_detected_) != false);
285 GetAecStats(audio_processing_.get(), stats); 283 GetAecStats(audio_processing_.get(), stats);
286 } 284 }
287 285
288 void MediaStreamAudioProcessor::InitializeAudioProcessingModule( 286 void MediaStreamAudioProcessor::InitializeAudioProcessingModule(
289 const blink::WebMediaConstraints& constraints, int effects, 287 const blink::WebMediaConstraints& constraints, int effects) {
290 MediaStreamType type) {
291 DCHECK(!audio_processing_); 288 DCHECK(!audio_processing_);
292 289
293 RTCMediaConstraints native_constraints(constraints); 290 MediaAudioConstraints audio_constraints(constraints, effects);
294 291
295 // Audio mirroring can be enabled even though audio processing is otherwise 292 // Audio mirroring can be enabled even though audio processing is otherwise
296 // disabled. 293 // disabled.
297 audio_mirroring_ = GetPropertyFromConstraints( 294 audio_mirroring_ = audio_constraints.GetProperty(
298 &native_constraints, webrtc::MediaConstraintsInterface::kAudioMirroring); 295 MediaAudioConstraints::kGoogAudioMirroring);
299 296
300 if (!IsAudioTrackProcessingEnabled()) { 297 if (!IsAudioTrackProcessingEnabled()) {
301 RecordProcessingState(AUDIO_PROCESSING_IN_WEBRTC); 298 RecordProcessingState(AUDIO_PROCESSING_IN_WEBRTC);
302 return; 299 return;
303 } 300 }
304 301
305 // Only apply the fixed constraints for gUM of MEDIA_DEVICE_AUDIO_CAPTURE. 302 // |kEchoCancellation| is used as a master control on enabling/disabling
306 DCHECK(IsAudioMediaType(type)); 303 // the audio processing.
307 if (type == MEDIA_DEVICE_AUDIO_CAPTURE) 304 // If |kEchoCancellation| is specified in |audio_constraints|, it will use
308 ApplyFixedAudioConstraints(&native_constraints); 305 // the defined value there, otherwise use the default value defined by
309 306 // kDefaultAudioConstraints in media_stream_audio_processor_options.cc.
310 if (effects & media::AudioParameters::ECHO_CANCELLER) { 307 const bool echo_cancellation = audio_constraints.GetProperty(
tommi (sloooow) - chröme 2014/04/29 09:27:04 Can we just do audio_constraints.GetEchoCancellati
311 // If platform echo canceller is enabled, disable the software AEC. 308 MediaAudioConstraints::kEchoCancellation);
312 native_constraints.AddMandatory( 309 if (!echo_cancellation) {
313 MediaConstraintsInterface::kEchoCancellation, 310 RecordProcessingState(AUDIO_PROCESSING_DISABLED);
314 MediaConstraintsInterface::kValueFalse, true); 311 return;
315 } 312 }
316 313
317 #if defined(OS_IOS) 314 #if defined(OS_IOS)
318 // On iOS, VPIO provides built-in AEC and AGC. 315 // On iOS, VPIO provides built-in AEC and AGC.
319 const bool enable_aec = false; 316 const bool goog_aec = false;
320 const bool enable_agc = false; 317 const bool goog_agc = false;
321 #else 318 #else
322 const bool enable_aec = GetPropertyFromConstraints( 319 // TODO(xians): goog_aec should just be echo_cancellation.
323 &native_constraints, MediaConstraintsInterface::kEchoCancellation); 320 const bool goog_aec = audio_constraints.GetEchoCancellationProperty();
324 const bool enable_agc = GetPropertyFromConstraints( 321 const bool goog_agc = audio_constraints.GetProperty(
325 &native_constraints, webrtc::MediaConstraintsInterface::kAutoGainControl); 322 MediaAudioConstraints::kGoogAutoGainControl);
326 #endif 323 #endif
327 324
328 #if defined(OS_IOS) || defined(OS_ANDROID) 325 #if defined(OS_IOS) || defined(OS_ANDROID)
329 const bool enable_experimental_aec = false; 326 const bool goog_experimental_aec = false;
330 const bool enable_typing_detection = false; 327 const bool goog_typing_detection = false;
331 #else 328 #else
332 const bool enable_experimental_aec = GetPropertyFromConstraints( 329 const bool goog_experimental_aec = audio_constraints.GetProperty(
333 &native_constraints, 330 MediaAudioConstraints::kGoogExperimentalEchoCancellation);
334 MediaConstraintsInterface::kExperimentalEchoCancellation); 331 const bool goog_typing_detection = audio_constraints.GetProperty(
335 const bool enable_typing_detection = GetPropertyFromConstraints( 332 MediaAudioConstraints::kGoogTypingNoiseDetection);
336 &native_constraints, MediaConstraintsInterface::kTypingNoiseDetection);
337 #endif 333 #endif
338 334
339 const bool enable_ns = GetPropertyFromConstraints( 335 const bool goog_ns = audio_constraints.GetProperty(
340 &native_constraints, MediaConstraintsInterface::kNoiseSuppression); 336 MediaAudioConstraints::kGoogNoiseSuppression);
341 const bool enable_experimental_ns = GetPropertyFromConstraints( 337 const bool goog_experimental_ns = audio_constraints.GetProperty(
342 &native_constraints, 338 MediaAudioConstraints::kGoogExperimentalNoiseSuppression);
343 MediaConstraintsInterface::kExperimentalNoiseSuppression); 339 const bool goog_high_pass_filter = audio_constraints.GetProperty(
344 const bool enable_high_pass_filter = GetPropertyFromConstraints( 340 MediaAudioConstraints::kGoogHighpassFilter);
345 &native_constraints, MediaConstraintsInterface::kHighpassFilter);
346 341
347 // Return immediately if no audio processing component is enabled. 342 // Return immediately if no goog constraint is enabled.
348 if (!enable_aec && !enable_experimental_aec && !enable_ns && 343 if (!goog_aec && !goog_experimental_aec && !goog_ns &&
349 !enable_high_pass_filter && !enable_typing_detection && !enable_agc && 344 !goog_high_pass_filter && !goog_typing_detection &&
350 !enable_experimental_ns) { 345 !goog_agc && !goog_experimental_ns) {
351 RecordProcessingState(AUDIO_PROCESSING_DISABLED); 346 RecordProcessingState(AUDIO_PROCESSING_DISABLED);
352 return; 347 return;
353 } 348 }
354 349
355 // Create and configure the webrtc::AudioProcessing. 350 // Create and configure the webrtc::AudioProcessing.
356 audio_processing_.reset(webrtc::AudioProcessing::Create()); 351 audio_processing_.reset(webrtc::AudioProcessing::Create());
357 CHECK_EQ(0, audio_processing_->Initialize(kAudioProcessingSampleRate, 352 CHECK_EQ(0, audio_processing_->Initialize(kAudioProcessingSampleRate,
358 kAudioProcessingSampleRate, 353 kAudioProcessingSampleRate,
359 kAudioProcessingSampleRate, 354 kAudioProcessingSampleRate,
360 kAudioProcessingChannelLayout, 355 kAudioProcessingChannelLayout,
361 kAudioProcessingChannelLayout, 356 kAudioProcessingChannelLayout,
362 kAudioProcessingChannelLayout)); 357 kAudioProcessingChannelLayout));
363 358
364 // Enable the audio processing components. 359 // Enable the audio processing components.
365 if (enable_aec) { 360 if (goog_aec) {
366 EnableEchoCancellation(audio_processing_.get()); 361 EnableEchoCancellation(audio_processing_.get());
367 if (enable_experimental_aec) 362
363 if (goog_experimental_aec)
368 EnableExperimentalEchoCancellation(audio_processing_.get()); 364 EnableExperimentalEchoCancellation(audio_processing_.get());
369 365
370 if (playout_data_source_) 366 if (playout_data_source_)
371 playout_data_source_->AddPlayoutSink(this); 367 playout_data_source_->AddPlayoutSink(this);
372 } 368 }
373 369
374 if (enable_ns) 370 if (goog_ns)
375 EnableNoiseSuppression(audio_processing_.get()); 371 EnableNoiseSuppression(audio_processing_.get());
376 372
377 if (enable_experimental_ns) 373 if (goog_experimental_ns)
378 EnableExperimentalNoiseSuppression(audio_processing_.get()); 374 EnableExperimentalNoiseSuppression(audio_processing_.get());
379 375
380 if (enable_high_pass_filter) 376 if (goog_high_pass_filter)
381 EnableHighPassFilter(audio_processing_.get()); 377 EnableHighPassFilter(audio_processing_.get());
382 378
383 if (enable_typing_detection) { 379 if (goog_typing_detection) {
384 // TODO(xians): Remove this |typing_detector_| after the typing suppression 380 // TODO(xians): Remove this |typing_detector_| after the typing suppression
385 // is enabled by default. 381 // is enabled by default.
386 typing_detector_.reset(new webrtc::TypingDetection()); 382 typing_detector_.reset(new webrtc::TypingDetection());
387 EnableTypingDetection(audio_processing_.get(), typing_detector_.get()); 383 EnableTypingDetection(audio_processing_.get(), typing_detector_.get());
388 } 384 }
389 385
390 if (enable_agc) 386 if (goog_agc)
391 EnableAutomaticGainControl(audio_processing_.get()); 387 EnableAutomaticGainControl(audio_processing_.get());
392 388
393 RecordProcessingState(AUDIO_PROCESSING_ENABLED); 389 RecordProcessingState(AUDIO_PROCESSING_ENABLED);
394 } 390 }
395 391
396 void MediaStreamAudioProcessor::InitializeCaptureConverter( 392 void MediaStreamAudioProcessor::InitializeCaptureConverter(
397 const media::AudioParameters& source_params) { 393 const media::AudioParameters& source_params) {
398 DCHECK(main_thread_checker_.CalledOnValidThread()); 394 DCHECK(main_thread_checker_.CalledOnValidThread());
399 DCHECK(source_params.IsValid()); 395 DCHECK(source_params.IsValid());
400 396
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 509
514 StopAecDump(); 510 StopAecDump();
515 511
516 if (playout_data_source_) 512 if (playout_data_source_)
517 playout_data_source_->RemovePlayoutSink(this); 513 playout_data_source_->RemovePlayoutSink(this);
518 514
519 audio_processing_.reset(); 515 audio_processing_.reset();
520 } 516 }
521 517
522 } // namespace content 518 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/media_stream_audio_processor.h ('k') | content/renderer/media/media_stream_audio_processor_options.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698