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

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: GetEchoCancellationProperty handles both kEchoCancellation and kGoogEchoCancellation 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.GetEchoCancellationProperty(
311 // If platform echo canceller is enabled, disable the software AEC. 308 MediaAudioConstraints::kEchoCancellation);
tommi (sloooow) - chröme 2014/04/30 10:58:44 Here I was thinking that GetEchoCancellationProper
no longer working on chromium 2014/05/02 12:24:02 I think Andrew had already asked similar questions
tommi (sloooow) - chröme 2014/05/03 10:26:28 Would we still have that problem if GetEchoCancell
no longer working on chromium 2014/05/05 12:55:56 nit, tab capture needs a "false" as value if expli
tommi (sloooow) - chröme 2014/05/05 13:58:13 I don't think echo cancellation applies to tab cap
312 native_constraints.AddMandatory( 309 #if defined(OS_IOS)
313 MediaConstraintsInterface::kEchoCancellation, 310 // On iOS, VPIO provides built-in AEC.
314 MediaConstraintsInterface::kValueFalse, true); 311 const bool goog_aec = false;
312 #else
313 // TODO(xians): goog_aec should just be echo_cancellation.
314 const bool goog_aec = audio_constraints.GetEchoCancellationProperty(
315 MediaAudioConstraints::kGoogEchoCancellation);
316 #endif
317 if (!echo_cancellation) {
318 RecordProcessingState(AUDIO_PROCESSING_DISABLED);
319 return;
315 } 320 }
316 321
317 #if defined(OS_IOS) 322 #if defined(OS_IOS)
318 // On iOS, VPIO provides built-in AEC and AGC. 323 // On iOS, VPIO provides built-in AGC.
319 const bool enable_aec = false; 324 const bool goog_agc = false;
320 const bool enable_agc = false;
321 #else 325 #else
322 const bool enable_aec = GetPropertyFromConstraints( 326 const bool goog_agc = audio_constraints.GetProperty(
323 &native_constraints, MediaConstraintsInterface::kEchoCancellation); 327 MediaAudioConstraints::kGoogAutoGainControl);
324 const bool enable_agc = GetPropertyFromConstraints(
325 &native_constraints, webrtc::MediaConstraintsInterface::kAutoGainControl);
326 #endif 328 #endif
327 329
328 #if defined(OS_IOS) || defined(OS_ANDROID) 330 #if defined(OS_IOS) || defined(OS_ANDROID)
329 const bool enable_experimental_aec = false; 331 const bool goog_experimental_aec = false;
330 const bool enable_typing_detection = false; 332 const bool goog_typing_detection = false;
331 #else 333 #else
332 const bool enable_experimental_aec = GetPropertyFromConstraints( 334 const bool goog_experimental_aec = audio_constraints.GetProperty(
333 &native_constraints, 335 MediaAudioConstraints::kGoogExperimentalEchoCancellation);
334 MediaConstraintsInterface::kExperimentalEchoCancellation); 336 const bool goog_typing_detection = audio_constraints.GetProperty(
335 const bool enable_typing_detection = GetPropertyFromConstraints( 337 MediaAudioConstraints::kGoogTypingNoiseDetection);
336 &native_constraints, MediaConstraintsInterface::kTypingNoiseDetection);
337 #endif 338 #endif
338 339
339 const bool enable_ns = GetPropertyFromConstraints( 340 const bool goog_ns = audio_constraints.GetProperty(
340 &native_constraints, MediaConstraintsInterface::kNoiseSuppression); 341 MediaAudioConstraints::kGoogNoiseSuppression);
341 const bool enable_experimental_ns = GetPropertyFromConstraints( 342 const bool goog_experimental_ns = audio_constraints.GetProperty(
342 &native_constraints, 343 MediaAudioConstraints::kGoogExperimentalNoiseSuppression);
343 MediaConstraintsInterface::kExperimentalNoiseSuppression); 344 const bool goog_high_pass_filter = audio_constraints.GetProperty(
344 const bool enable_high_pass_filter = GetPropertyFromConstraints( 345 MediaAudioConstraints::kGoogHighpassFilter);
345 &native_constraints, MediaConstraintsInterface::kHighpassFilter);
346 346
347 // Return immediately if no audio processing component is enabled. 347 // Return immediately if no goog constraint is enabled.
348 if (!enable_aec && !enable_experimental_aec && !enable_ns && 348 if (!goog_aec && !goog_experimental_aec && !goog_ns &&
349 !enable_high_pass_filter && !enable_typing_detection && !enable_agc && 349 !goog_high_pass_filter && !goog_typing_detection &&
350 !enable_experimental_ns) { 350 !goog_agc && !goog_experimental_ns) {
351 RecordProcessingState(AUDIO_PROCESSING_DISABLED); 351 RecordProcessingState(AUDIO_PROCESSING_DISABLED);
352 return; 352 return;
353 } 353 }
354 354
355 // Create and configure the webrtc::AudioProcessing. 355 // Create and configure the webrtc::AudioProcessing.
356 audio_processing_.reset(webrtc::AudioProcessing::Create()); 356 audio_processing_.reset(webrtc::AudioProcessing::Create());
357 CHECK_EQ(0, audio_processing_->Initialize(kAudioProcessingSampleRate, 357 CHECK_EQ(0, audio_processing_->Initialize(kAudioProcessingSampleRate,
358 kAudioProcessingSampleRate, 358 kAudioProcessingSampleRate,
359 kAudioProcessingSampleRate, 359 kAudioProcessingSampleRate,
360 kAudioProcessingChannelLayout, 360 kAudioProcessingChannelLayout,
361 kAudioProcessingChannelLayout, 361 kAudioProcessingChannelLayout,
362 kAudioProcessingChannelLayout)); 362 kAudioProcessingChannelLayout));
363 363
364 // Enable the audio processing components. 364 // Enable the audio processing components.
365 if (enable_aec) { 365 if (goog_aec) {
366 EnableEchoCancellation(audio_processing_.get()); 366 EnableEchoCancellation(audio_processing_.get());
367 if (enable_experimental_aec) 367
368 if (goog_experimental_aec)
368 EnableExperimentalEchoCancellation(audio_processing_.get()); 369 EnableExperimentalEchoCancellation(audio_processing_.get());
369 370
370 if (playout_data_source_) 371 if (playout_data_source_)
371 playout_data_source_->AddPlayoutSink(this); 372 playout_data_source_->AddPlayoutSink(this);
372 } 373 }
373 374
374 if (enable_ns) 375 if (goog_ns)
375 EnableNoiseSuppression(audio_processing_.get()); 376 EnableNoiseSuppression(audio_processing_.get());
376 377
377 if (enable_experimental_ns) 378 if (goog_experimental_ns)
378 EnableExperimentalNoiseSuppression(audio_processing_.get()); 379 EnableExperimentalNoiseSuppression(audio_processing_.get());
379 380
380 if (enable_high_pass_filter) 381 if (goog_high_pass_filter)
381 EnableHighPassFilter(audio_processing_.get()); 382 EnableHighPassFilter(audio_processing_.get());
382 383
383 if (enable_typing_detection) { 384 if (goog_typing_detection) {
384 // TODO(xians): Remove this |typing_detector_| after the typing suppression 385 // TODO(xians): Remove this |typing_detector_| after the typing suppression
385 // is enabled by default. 386 // is enabled by default.
386 typing_detector_.reset(new webrtc::TypingDetection()); 387 typing_detector_.reset(new webrtc::TypingDetection());
387 EnableTypingDetection(audio_processing_.get(), typing_detector_.get()); 388 EnableTypingDetection(audio_processing_.get(), typing_detector_.get());
388 } 389 }
389 390
390 if (enable_agc) 391 if (goog_agc)
391 EnableAutomaticGainControl(audio_processing_.get()); 392 EnableAutomaticGainControl(audio_processing_.get());
392 393
393 RecordProcessingState(AUDIO_PROCESSING_ENABLED); 394 RecordProcessingState(AUDIO_PROCESSING_ENABLED);
394 } 395 }
395 396
396 void MediaStreamAudioProcessor::InitializeCaptureConverter( 397 void MediaStreamAudioProcessor::InitializeCaptureConverter(
397 const media::AudioParameters& source_params) { 398 const media::AudioParameters& source_params) {
398 DCHECK(main_thread_checker_.CalledOnValidThread()); 399 DCHECK(main_thread_checker_.CalledOnValidThread());
399 DCHECK(source_params.IsValid()); 400 DCHECK(source_params.IsValid());
400 401
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 514
514 StopAecDump(); 515 StopAecDump();
515 516
516 if (playout_data_source_) 517 if (playout_data_source_)
517 playout_data_source_->RemovePlayoutSink(this); 518 playout_data_source_->RemovePlayoutSink(this);
518 519
519 audio_processing_.reset(); 520 audio_processing_.reset();
520 } 521 }
521 522
522 } // namespace content 523 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698