Chromium Code Reviews| OLD | NEW | 
|---|---|
| 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_options.h" | 5 #include "content/renderer/media/media_stream_audio_processor_options.h" | 
| 6 | 6 | 
| 7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" | 
| 8 #include "base/logging.h" | 8 #include "base/logging.h" | 
| 9 #include "base/path_service.h" | 9 #include "base/path_service.h" | 
| 10 #include "base/strings/string_number_conversions.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" | 
| 11 #include "content/common/media/media_stream_options.h" | 12 #include "content/common/media/media_stream_options.h" | 
| 13 #include "content/renderer/media/media_stream_constraints_util.h" | |
| 12 #include "content/renderer/media/rtc_media_constraints.h" | 14 #include "content/renderer/media/rtc_media_constraints.h" | 
| 13 #include "media/audio/audio_parameters.h" | 15 #include "media/audio/audio_parameters.h" | 
| 14 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" | |
| 15 #include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface .h" | |
| 16 #include "third_party/webrtc/modules/audio_processing/include/audio_processing.h " | 16 #include "third_party/webrtc/modules/audio_processing/include/audio_processing.h " | 
| 17 #include "third_party/webrtc/modules/audio_processing/typing_detection.h" | 17 #include "third_party/webrtc/modules/audio_processing/typing_detection.h" | 
| 18 | 18 | 
| 19 namespace content { | 19 namespace content { | 
| 20 | 20 | 
| 21 const char MediaAudioConstraints::kEchoCancellation[] = "echoCancellation"; | |
| 22 const char MediaAudioConstraints::kGoogEchoCancellation[] = | |
| 23 "googEchoCancellation"; | |
| 24 const char MediaAudioConstraints::kGoogExperimentalEchoCancellation[] = | |
| 25 "googEchoCancellation2"; | |
| 26 const char MediaAudioConstraints::kGoogAutoGainControl[] = | |
| 27 "googAutoGainControl"; | |
| 28 const char MediaAudioConstraints::kGoogExperimentalAutoGainControl[] = | |
| 29 "googAutoGainControl2"; | |
| 30 const char MediaAudioConstraints::kGoogNoiseSuppression[] = | |
| 31 "googNoiseSuppression"; | |
| 32 const char MediaAudioConstraints::kGoogExperimentalNoiseSuppression[] = | |
| 33 "googNoiseSuppression2"; | |
| 34 const char MediaAudioConstraints::kGoogHighpassFilter[] = "googHighpassFilter"; | |
| 35 const char MediaAudioConstraints::kGoogTypingNoiseDetection[] = | |
| 36 "googTypingNoiseDetection"; | |
| 37 const char MediaAudioConstraints::kGoogAudioMirroring[] = "googAudioMirroring"; | |
| 38 | |
| 21 namespace { | 39 namespace { | 
| 22 | 40 | 
| 23 // Constant constraint keys which enables default audio constraints on | 41 // Constant constraint keys which enables default audio constraints on | 
| 24 // mediastreams with audio. | 42 // mediastreams with audio. | 
| 25 struct { | 43 struct { | 
| 26 const char* key; | 44 const char* key; | 
| 27 const char* value; | 45 bool value; | 
| 28 } const kDefaultAudioConstraints[] = { | 46 } const kDefaultAudioConstraints[] = { | 
| 29 { webrtc::MediaConstraintsInterface::kEchoCancellation, | 47 { MediaAudioConstraints::kEchoCancellation, true }, | 
| 30 webrtc::MediaConstraintsInterface::kValueTrue }, | 48 { MediaAudioConstraints::kGoogEchoCancellation, true }, | 
| 31 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) | 49 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) | 
| 32 // Enable the extended filter mode AEC on platforms with known echo issues. | 50 // Enable the extended filter mode AEC on platforms with known echo issues. | 
| 33 { webrtc::MediaConstraintsInterface::kExperimentalEchoCancellation, | 51 { MediaAudioConstraints::kGoogExperimentalEchoCancellation, true }, | 
| 34 webrtc::MediaConstraintsInterface::kValueTrue }, | 52 #else | 
| 53 { MediaAudioConstraints::kGoogExperimentalEchoCancellation, false }, | |
| 35 #endif | 54 #endif | 
| 36 { webrtc::MediaConstraintsInterface::kAutoGainControl, | 55 { MediaAudioConstraints::kGoogAutoGainControl, true }, | 
| 37 webrtc::MediaConstraintsInterface::kValueTrue }, | 56 { MediaAudioConstraints::kGoogExperimentalAutoGainControl, true }, | 
| 38 { webrtc::MediaConstraintsInterface::kExperimentalAutoGainControl, | 57 { MediaAudioConstraints::kGoogNoiseSuppression, true }, | 
| 39 webrtc::MediaConstraintsInterface::kValueTrue }, | 58 { MediaAudioConstraints::kGoogHighpassFilter, true }, | 
| 40 { webrtc::MediaConstraintsInterface::kNoiseSuppression, | 59 { MediaAudioConstraints::kGoogTypingNoiseDetection, true }, | 
| 41 webrtc::MediaConstraintsInterface::kValueTrue }, | 60 { MediaAudioConstraints::kGoogExperimentalNoiseSuppression, false }, | 
| 42 { webrtc::MediaConstraintsInterface::kHighpassFilter, | |
| 43 webrtc::MediaConstraintsInterface::kValueTrue }, | |
| 44 { webrtc::MediaConstraintsInterface::kTypingNoiseDetection, | |
| 45 webrtc::MediaConstraintsInterface::kValueTrue }, | |
| 46 #if defined(OS_WIN) | 61 #if defined(OS_WIN) | 
| 47 { content::kMediaStreamAudioDucking, | 62 { kMediaStreamAudioDucking, true }, | 
| 48 webrtc::MediaConstraintsInterface::kValueTrue }, | 63 #else | 
| 64 { kMediaStreamAudioDucking, false }, | |
| 49 #endif | 65 #endif | 
| 50 }; | 66 }; | 
| 51 | 67 | 
| 68 bool GetDefaultValueForConstraint(const blink::WebMediaConstraints& constraints, | |
| 69 const std::string& key) { | |
| 70 // The default audio processing is false for gUM with a specific | |
| 71 // kMediaStreamSource. | |
| 
 
perkj_chrome
2014/04/14 12:15:19
Please explain what kMediaSource is.
 
no longer working on chromium
2014/04/14 14:40:50
Done with adding "which is used by tab capture and
 
 | |
| 72 std::string value; | |
| 73 if (GetConstraintValue(constraints, kMediaStreamSource, &value)) | |
| 74 return false; | |
| 75 | |
| 76 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { | |
| 
 
perkj_chrome
2014/04/14 12:15:19
arraysize ?
 
no longer working on chromium
2014/04/14 14:40:50
It is not possible before of the struct type used
 
 | |
| 77 if (kDefaultAudioConstraints[i].key == key) | |
| 78 return kDefaultAudioConstraints[i].value; | |
| 79 } | |
| 80 | |
| 81 return false; | |
| 82 } | |
| 83 | |
| 52 } // namespace | 84 } // namespace | 
| 53 | 85 | 
| 54 void ApplyFixedAudioConstraints(RTCMediaConstraints* constraints) { | 86 // TODO(xians): Remove this method after the APM in WebRtc is deprecated. | 
| 87 void MediaAudioConstraints::ApplyFixedAudioConstraints( | |
| 88 RTCMediaConstraints* constraints) { | |
| 55 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { | 89 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { | 
| 
 
perkj_chrome
2014/04/14 12:15:19
arraysize ?
 
no longer working on chromium
2014/04/14 14:40:50
ditto.
 
 | |
| 56 bool already_set_value; | 90 bool already_set_value; | 
| 57 if (!webrtc::FindConstraint(constraints, kDefaultAudioConstraints[i].key, | 91 if (!webrtc::FindConstraint(constraints, kDefaultAudioConstraints[i].key, | 
| 58 &already_set_value, NULL)) { | 92 &already_set_value, NULL)) { | 
| 59 constraints->AddOptional(kDefaultAudioConstraints[i].key, | 93 const std::string value = kDefaultAudioConstraints[i].value ? | 
| 60 kDefaultAudioConstraints[i].value, false); | 94 webrtc::MediaConstraintsInterface::kValueTrue : | 
| 95 webrtc::MediaConstraintsInterface::kValueFalse; | |
| 96 constraints->AddOptional(kDefaultAudioConstraints[i].key, value, false); | |
| 61 } else { | 97 } else { | 
| 62 DVLOG(1) << "Constraint " << kDefaultAudioConstraints[i].key | 98 DVLOG(1) << "Constraint " << kDefaultAudioConstraints[i].key | 
| 63 << " already set to " << already_set_value; | 99 << " already set to " << already_set_value; | 
| 64 } | 100 } | 
| 65 } | 101 } | 
| 66 } | 102 } | 
| 67 | 103 | 
| 68 bool NeedsAudioProcessing(const blink::WebMediaConstraints& constraints, | 104 MediaAudioConstraints::MediaAudioConstraints( | 
| 69 int effects) { | 105 const blink::WebMediaConstraints& constraints, int effects) | 
| 70 RTCMediaConstraints native_constraints(constraints); | 106 : constraints_(constraints), effects_(effects) {} | 
| 71 ApplyFixedAudioConstraints(&native_constraints); | 107 | 
| 72 if (effects & media::AudioParameters::ECHO_CANCELLER) { | 108 MediaAudioConstraints::~MediaAudioConstraints() {} | 
| 73 // If platform echo canceller is enabled, disable the software AEC. | 109 | 
| 74 native_constraints.AddOptional( | 110 // TODO(xians): Remove this method after the APM in WebRtc is deprecated. | 
| 75 MediaConstraintsInterface::kEchoCancellation, | 111 bool MediaAudioConstraints::NeedsAudioProcessing() { | 
| 76 MediaConstraintsInterface::kValueFalse, true); | |
| 77 } | |
| 78 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { | 112 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { | 
| 79 bool value = false; | 113 if (GetProperty(kDefaultAudioConstraints[i].key)) | 
| 80 if (webrtc::FindConstraint(&native_constraints, | |
| 81 kDefaultAudioConstraints[i].key, &value, NULL) && | |
| 82 value) { | |
| 83 return true; | 114 return true; | 
| 84 } | |
| 85 } | 115 } | 
| 86 | 116 | 
| 87 return false; | 117 return false; | 
| 88 } | 118 } | 
| 89 | 119 | 
| 90 bool GetPropertyFromConstraints(const MediaConstraintsInterface* constraints, | 120 bool MediaAudioConstraints::GetProperty(const std::string& key) { | 
| 91 const std::string& key) { | 121 if (effects_ & media::AudioParameters::ECHO_CANCELLER && | 
| 
 
no longer working on chromium
2014/04/11 16:47:05
Andrew, could you please take a look at this?
Pre
 
 | |
| 122 key == kGoogEchoCancellation) { | |
| 123 // If platform echo canceller is enabled, disable the software AEC. | |
| 124 return false; | |
| 125 } | |
| 126 | |
| 127 // Return the value if the constraint is specified in |constraints|, | |
| 128 // otherwise return the default value. | |
| 92 bool value = false; | 129 bool value = false; | 
| 93 return webrtc::FindConstraint(constraints, key, &value, NULL) && value; | 130 if (!GetConstraintValue(constraints_, key, &value)) | 
| 131 value = GetDefaultValueForConstraint(constraints_, key); | |
| 132 | |
| 133 return value; | |
| 134 } | |
| 135 | |
| 136 bool MediaAudioConstraints::IsValid() { | |
| 137 blink::WebVector<blink::WebMediaConstraint> mandatory; | |
| 138 constraints_.getMandatoryConstraints(mandatory); | |
| 139 for (size_t i = 0; i < mandatory.size(); ++i) { | |
| 140 if (mandatory[i].m_name.utf8() == kMediaStreamSource) | |
| 141 continue; | |
| 142 | |
| 143 bool valid = false; | |
| 144 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++j) { | |
| 145 if (mandatory[i].m_name.utf8() == kDefaultAudioConstraints[j].key) { | |
| 146 valid = true; | |
| 147 break; | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 if (!valid) { | |
| 152 DLOG(ERROR) << "Invalid MediaStream constraint. Name:" | |
| 153 << mandatory[i].m_name.utf8(); | |
| 154 return false; | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 return true; | |
| 94 } | 159 } | 
| 95 | 160 | 
| 96 void EnableEchoCancellation(AudioProcessing* audio_processing) { | 161 void EnableEchoCancellation(AudioProcessing* audio_processing) { | 
| 97 #if defined(OS_ANDROID) | 162 #if defined(OS_ANDROID) | 
| 98 // Mobile devices are using AECM. | 163 // Mobile devices are using AECM. | 
| 99 int err = audio_processing->echo_control_mobile()->set_routing_mode( | 164 int err = audio_processing->echo_control_mobile()->set_routing_mode( | 
| 100 webrtc::EchoControlMobile::kSpeakerphone); | 165 webrtc::EchoControlMobile::kSpeakerphone); | 
| 101 err |= audio_processing->echo_control_mobile()->Enable(true); | 166 err |= audio_processing->echo_control_mobile()->Enable(true); | 
| 102 CHECK_EQ(err, 0); | 167 CHECK_EQ(err, 0); | 
| 103 #else | 168 #else | 
| (...skipping 16 matching lines...) Expand all Loading... | |
| 120 } | 185 } | 
| 121 | 186 | 
| 122 void EnableExperimentalNoiseSuppression(AudioProcessing* audio_processing) { | 187 void EnableExperimentalNoiseSuppression(AudioProcessing* audio_processing) { | 
| 123 CHECK_EQ(audio_processing->EnableExperimentalNs(true), 0); | 188 CHECK_EQ(audio_processing->EnableExperimentalNs(true), 0); | 
| 124 } | 189 } | 
| 125 | 190 | 
| 126 void EnableHighPassFilter(AudioProcessing* audio_processing) { | 191 void EnableHighPassFilter(AudioProcessing* audio_processing) { | 
| 127 CHECK_EQ(audio_processing->high_pass_filter()->Enable(true), 0); | 192 CHECK_EQ(audio_processing->high_pass_filter()->Enable(true), 0); | 
| 128 } | 193 } | 
| 129 | 194 | 
| 130 void EnableTypingDetection(AudioProcessing* audio_processing, | 195 void EnableTypingDetection(AudioProcessing* audio_processing, | 
| 
 
perkj_chrome
2014/04/14 12:15:19
nit: allign paramers or move audio_processing to n
 
no longer working on chromium
2014/04/14 14:40:50
Done.
 
 | |
| 131 webrtc::TypingDetection* typing_detector) { | 196 webrtc::TypingDetection* typing_detector) { | 
| 132 int err = audio_processing->voice_detection()->Enable(true); | 197 int err = audio_processing->voice_detection()->Enable(true); | 
| 133 err |= audio_processing->voice_detection()->set_likelihood( | 198 err |= audio_processing->voice_detection()->set_likelihood( | 
| 134 webrtc::VoiceDetection::kVeryLowLikelihood); | 199 webrtc::VoiceDetection::kVeryLowLikelihood); | 
| 135 CHECK_EQ(err, 0); | 200 CHECK_EQ(err, 0); | 
| 136 | 201 | 
| 137 // Configure the update period to 1s (100 * 10ms) in the typing detector. | 202 // Configure the update period to 1s (100 * 10ms) in the typing detector. | 
| 138 typing_detector->SetParameters(0, 0, 0, 0, 0, 100); | 203 typing_detector->SetParameters(0, 0, 0, 0, 0, 100); | 
| 139 } | 204 } | 
| 140 | 205 | 
| 141 void EnableExperimentalEchoCancellation(AudioProcessing* audio_processing) { | 206 void EnableExperimentalEchoCancellation(AudioProcessing* audio_processing) { | 
| 142 webrtc::Config config; | 207 webrtc::Config config; | 
| 143 config.Set<webrtc::DelayCorrection>(new webrtc::DelayCorrection(true)); | 208 config.Set<webrtc::DelayCorrection>(new webrtc::DelayCorrection(true)); | 
| 144 audio_processing->SetExtraOptions(config); | 209 audio_processing->SetExtraOptions(config); | 
| 145 } | 210 } | 
| 146 | 211 | 
| 147 void StartEchoCancellationDump(AudioProcessing* audio_processing, | 212 void StartEchoCancellationDump(AudioProcessing* audio_processing, | 
| 148 const base::PlatformFile& aec_dump_file) { | 213 const base::PlatformFile& aec_dump_file) { | 
| 
 
perkj_chrome
2014/04/14 12:15:19
dio
 
no longer working on chromium
2014/04/14 14:40:50
Done.
 
 | |
| 149 DCHECK_NE(aec_dump_file, base::kInvalidPlatformFileValue); | 214 DCHECK_NE(aec_dump_file, base::kInvalidPlatformFileValue); | 
| 150 | 215 | 
| 151 FILE* stream = base::FdopenPlatformFile(aec_dump_file, "w"); | 216 FILE* stream = base::FdopenPlatformFile(aec_dump_file, "w"); | 
| 152 if (!stream) { | 217 if (!stream) { | 
| 153 LOG(ERROR) << "Failed to open AEC dump file"; | 218 LOG(ERROR) << "Failed to open AEC dump file"; | 
| 154 return; | 219 return; | 
| 155 } | 220 } | 
| 156 | 221 | 
| 157 if (audio_processing->StartDebugRecording(stream)) | 222 if (audio_processing->StartDebugRecording(stream)) | 
| 158 DLOG(ERROR) << "Fail to start AEC debug recording"; | 223 DLOG(ERROR) << "Fail to start AEC debug recording"; | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 } | 272 } | 
| 208 | 273 | 
| 209 int median = 0, std = 0; | 274 int median = 0, std = 0; | 
| 210 if (!audio_processing->echo_cancellation()->GetDelayMetrics(&median, &std)) { | 275 if (!audio_processing->echo_cancellation()->GetDelayMetrics(&median, &std)) { | 
| 211 stats->echo_delay_median_ms = median; | 276 stats->echo_delay_median_ms = median; | 
| 212 stats->echo_delay_std_ms = std; | 277 stats->echo_delay_std_ms = std; | 
| 213 } | 278 } | 
| 214 } | 279 } | 
| 215 | 280 | 
| 216 } // namespace content | 281 } // namespace content | 
| OLD | NEW |