 Chromium Code Reviews
 Chromium Code Reviews Issue 227743004:
  Added a kEchoCancellation constraint to turn off the audio processing.  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@master
    
  
    Issue 227743004:
  Added a kEchoCancellation constraint to turn off the audio processing.  (Closed) 
  Base URL: http://git.chromium.org/chromium/src.git@master| Index: content/renderer/media/media_stream_audio_processor_options.cc | 
| diff --git a/content/renderer/media/media_stream_audio_processor_options.cc b/content/renderer/media/media_stream_audio_processor_options.cc | 
| index 320d1a6ba31d8296160a2a67b1c07523aa4d12ef..1707f7dbd6c9e6bb302fcf2b9741a0bd2d71c81c 100644 | 
| --- a/content/renderer/media/media_stream_audio_processor_options.cc | 
| +++ b/content/renderer/media/media_stream_audio_processor_options.cc | 
| @@ -7,57 +7,93 @@ | 
| #include "base/files/file_path.h" | 
| #include "base/logging.h" | 
| #include "base/path_service.h" | 
| +#include "base/strings/string_number_conversions.h" | 
| #include "base/strings/utf_string_conversions.h" | 
| #include "content/common/media/media_stream_options.h" | 
| +#include "content/renderer/media/media_stream_constraints_util.h" | 
| #include "content/renderer/media/rtc_media_constraints.h" | 
| #include "media/audio/audio_parameters.h" | 
| -#include "third_party/WebKit/public/platform/WebMediaConstraints.h" | 
| -#include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.h" | 
| #include "third_party/webrtc/modules/audio_processing/include/audio_processing.h" | 
| #include "third_party/webrtc/modules/audio_processing/typing_detection.h" | 
| namespace content { | 
| +const char MediaAudioConstraints::kEchoCancellation[] = "echoCancellation"; | 
| +const char MediaAudioConstraints::kGoogEchoCancellation[] = | 
| + "googEchoCancellation"; | 
| +const char MediaAudioConstraints::kGoogExperimentalEchoCancellation[] = | 
| + "googEchoCancellation2"; | 
| +const char MediaAudioConstraints::kGoogAutoGainControl[] = | 
| + "googAutoGainControl"; | 
| +const char MediaAudioConstraints::kGoogExperimentalAutoGainControl[] = | 
| + "googAutoGainControl2"; | 
| +const char MediaAudioConstraints::kGoogNoiseSuppression[] = | 
| + "googNoiseSuppression"; | 
| +const char MediaAudioConstraints::kGoogExperimentalNoiseSuppression[] = | 
| + "googNoiseSuppression2"; | 
| +const char MediaAudioConstraints::kGoogHighpassFilter[] = "googHighpassFilter"; | 
| +const char MediaAudioConstraints::kGoogTypingNoiseDetection[] = | 
| + "googTypingNoiseDetection"; | 
| +const char MediaAudioConstraints::kGoogAudioMirroring[] = "googAudioMirroring"; | 
| + | 
| namespace { | 
| // Constant constraint keys which enables default audio constraints on | 
| // mediastreams with audio. | 
| struct { | 
| const char* key; | 
| - const char* value; | 
| + bool value; | 
| } const kDefaultAudioConstraints[] = { | 
| - { webrtc::MediaConstraintsInterface::kEchoCancellation, | 
| - webrtc::MediaConstraintsInterface::kValueTrue }, | 
| + { MediaAudioConstraints::kEchoCancellation, true }, | 
| + { MediaAudioConstraints::kGoogEchoCancellation, true }, | 
| #if defined(OS_CHROMEOS) || defined(OS_MACOSX) | 
| // Enable the extended filter mode AEC on platforms with known echo issues. | 
| - { webrtc::MediaConstraintsInterface::kExperimentalEchoCancellation, | 
| - webrtc::MediaConstraintsInterface::kValueTrue }, | 
| + { MediaAudioConstraints::kGoogExperimentalEchoCancellation, true }, | 
| +#else | 
| + { MediaAudioConstraints::kGoogExperimentalEchoCancellation, false }, | 
| #endif | 
| - { webrtc::MediaConstraintsInterface::kAutoGainControl, | 
| - webrtc::MediaConstraintsInterface::kValueTrue }, | 
| - { webrtc::MediaConstraintsInterface::kExperimentalAutoGainControl, | 
| - webrtc::MediaConstraintsInterface::kValueTrue }, | 
| - { webrtc::MediaConstraintsInterface::kNoiseSuppression, | 
| - webrtc::MediaConstraintsInterface::kValueTrue }, | 
| - { webrtc::MediaConstraintsInterface::kHighpassFilter, | 
| - webrtc::MediaConstraintsInterface::kValueTrue }, | 
| - { webrtc::MediaConstraintsInterface::kTypingNoiseDetection, | 
| - webrtc::MediaConstraintsInterface::kValueTrue }, | 
| + { MediaAudioConstraints::kGoogAutoGainControl, true }, | 
| + { MediaAudioConstraints::kGoogExperimentalAutoGainControl, true }, | 
| + { MediaAudioConstraints::kGoogNoiseSuppression, true }, | 
| + { MediaAudioConstraints::kGoogHighpassFilter, true }, | 
| + { MediaAudioConstraints::kGoogTypingNoiseDetection, true }, | 
| + { MediaAudioConstraints::kGoogExperimentalNoiseSuppression, false }, | 
| #if defined(OS_WIN) | 
| - { content::kMediaStreamAudioDucking, | 
| - webrtc::MediaConstraintsInterface::kValueTrue }, | 
| + { kMediaStreamAudioDucking, true }, | 
| +#else | 
| + { kMediaStreamAudioDucking, false }, | 
| #endif | 
| }; | 
| +bool GetDefaultValueForConstraint(const blink::WebMediaConstraints& constraints, | 
| + const std::string& key) { | 
| + // The default audio processing is false for gUM with a specific | 
| + // kMediaStreamSource, which is used by tab capture and screen capture. | 
| + std::string value; | 
| + if (GetConstraintValue(constraints, kMediaStreamSource, &value)) | 
| + return false; | 
| + | 
| + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { | 
| + if (kDefaultAudioConstraints[i].key == key) | 
| + return kDefaultAudioConstraints[i].value; | 
| + } | 
| + | 
| + return false; | 
| +} | 
| + | 
| } // namespace | 
| -void ApplyFixedAudioConstraints(RTCMediaConstraints* constraints) { | 
| +// TODO(xians): Remove this method after the APM in WebRtc is deprecated. | 
| +void MediaAudioConstraints::ApplyFixedAudioConstraints( | 
| + RTCMediaConstraints* constraints) { | 
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { | 
| bool already_set_value; | 
| if (!webrtc::FindConstraint(constraints, kDefaultAudioConstraints[i].key, | 
| &already_set_value, NULL)) { | 
| - constraints->AddOptional(kDefaultAudioConstraints[i].key, | 
| - kDefaultAudioConstraints[i].value, false); | 
| + const std::string value = kDefaultAudioConstraints[i].value ? | 
| + webrtc::MediaConstraintsInterface::kValueTrue : | 
| + webrtc::MediaConstraintsInterface::kValueFalse; | 
| + constraints->AddOptional(kDefaultAudioConstraints[i].key, value, false); | 
| } else { | 
| DVLOG(1) << "Constraint " << kDefaultAudioConstraints[i].key | 
| << " already set to " << already_set_value; | 
| @@ -65,21 +101,18 @@ void ApplyFixedAudioConstraints(RTCMediaConstraints* constraints) { | 
| } | 
| } | 
| -bool NeedsAudioProcessing(const blink::WebMediaConstraints& constraints, | 
| - int effects) { | 
| - RTCMediaConstraints native_constraints(constraints); | 
| - ApplyFixedAudioConstraints(&native_constraints); | 
| - if (effects & media::AudioParameters::ECHO_CANCELLER) { | 
| - // If platform echo canceller is enabled, disable the software AEC. | 
| - native_constraints.AddOptional( | 
| - MediaConstraintsInterface::kEchoCancellation, | 
| - MediaConstraintsInterface::kValueFalse, true); | 
| - } | 
| +MediaAudioConstraints::MediaAudioConstraints( | 
| + const blink::WebMediaConstraints& constraints, int effects) | 
| + : constraints_(constraints), effects_(effects) {} | 
| + | 
| +MediaAudioConstraints::~MediaAudioConstraints() {} | 
| + | 
| +// TODO(xians): Remove this method after the APM in WebRtc is deprecated. | 
| +bool MediaAudioConstraints::NeedsAudioProcessing() { | 
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { | 
| - bool value = false; | 
| - if (webrtc::FindConstraint(&native_constraints, | 
| - kDefaultAudioConstraints[i].key, &value, NULL) && | 
| - value) { | 
| + // |kMediaStreamAudioDucking| does not require audio processing. | 
| + if (kDefaultAudioConstraints[i].key != kMediaStreamAudioDucking && | 
| + GetProperty(kDefaultAudioConstraints[i].key)) { | 
| return true; | 
| } | 
| } | 
| @@ -87,10 +120,50 @@ bool NeedsAudioProcessing(const blink::WebMediaConstraints& constraints, | 
| return false; | 
| } | 
| -bool GetPropertyFromConstraints(const MediaConstraintsInterface* constraints, | 
| - const std::string& key) { | 
| +bool MediaAudioConstraints::GetProperty(const std::string& key) { | 
| bool value = false; | 
| - return webrtc::FindConstraint(constraints, key, &value, NULL) && value; | 
| + if (key == kGoogEchoCancellation) { | 
| + // If platform echo canceller is enabled, disable the software AEC. | 
| + if (effects_ & media::AudioParameters::ECHO_CANCELLER) | 
| 
ajm
2014/04/24 21:39:12
You'll need to apply this to kEchoCancellation if
 
no longer working on chromium
2014/04/28 12:42:54
Yes, I will keep it in mind.
And I think we have
 | 
| + return false; | 
| + | 
| + // If |kEchoCancellation| is specified in the constraints, it will | 
| + // overwrite the value of |kGoogEchoCancellation|. | 
| + if (GetConstraintValue(constraints_, kEchoCancellation, &value)) | 
| 
ajm
2014/04/24 21:39:12
Not sure we want to make GetProperty this "smart",
 
tommi (sloooow) - chröme
2014/04/25 15:09:31
I don't think that checking kEchoCancellation or k
 
no longer working on chromium
2014/04/28 12:42:54
As offline discussed, I added a GetEchoCancellatio
 | 
| + return value; | 
| + } | 
| + | 
| + // Return the value if the constraint is specified in |constraints|, | 
| + // otherwise return the default value. | 
| + if (!GetConstraintValue(constraints_, key, &value)) | 
| + value = GetDefaultValueForConstraint(constraints_, key); | 
| + | 
| + return value; | 
| +} | 
| + | 
| +bool MediaAudioConstraints::IsValid() { | 
| + blink::WebVector<blink::WebMediaConstraint> mandatory; | 
| + constraints_.getMandatoryConstraints(mandatory); | 
| + for (size_t i = 0; i < mandatory.size(); ++i) { | 
| + if (mandatory[i].m_name.utf8() == kMediaStreamSource) | 
| + continue; | 
| + | 
| + bool valid = false; | 
| + for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++j) { | 
| + if (mandatory[i].m_name.utf8() == kDefaultAudioConstraints[j].key) { | 
| + valid = true; | 
| + break; | 
| + } | 
| + } | 
| + | 
| + if (!valid) { | 
| + DLOG(ERROR) << "Invalid MediaStream constraint. Name:" | 
| + << mandatory[i].m_name.utf8(); | 
| + return false; | 
| + } | 
| + } | 
| + | 
| + return true; | 
| } | 
| void EnableEchoCancellation(AudioProcessing* audio_processing) { |