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, which is used by tab capture and screen capture. |
| 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) { |
| 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) { |
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 (kDefaultAudioConstraints[i].key == kGoogEchoCancellation) { |
80 if (webrtc::FindConstraint(&native_constraints, | 114 if (GetEchoCancellationProperty()) |
81 kDefaultAudioConstraints[i].key, &value, NULL) && | 115 return true; |
82 value) { | 116 } else { |
83 return true; | 117 // |kMediaStreamAudioDucking| does not require audio processing. |
| 118 if (kDefaultAudioConstraints[i].key != kMediaStreamAudioDucking && |
| 119 GetProperty(kDefaultAudioConstraints[i].key)) { |
| 120 return true; |
| 121 } |
84 } | 122 } |
85 } | 123 } |
86 | 124 |
87 return false; | 125 return false; |
88 } | 126 } |
89 | 127 |
90 bool GetPropertyFromConstraints(const MediaConstraintsInterface* constraints, | 128 bool MediaAudioConstraints::GetProperty(const std::string& key) { |
91 const std::string& key) { | 129 // Return the value if the constraint is specified in |constraints|, |
| 130 // otherwise return the default value. |
92 bool value = false; | 131 bool value = false; |
93 return webrtc::FindConstraint(constraints, key, &value, NULL) && value; | 132 if (!GetConstraintValue(constraints_, key, &value)) |
| 133 value = GetDefaultValueForConstraint(constraints_, key); |
| 134 |
| 135 return value; |
| 136 } |
| 137 |
| 138 bool MediaAudioConstraints::GetEchoCancellationProperty() { |
| 139 // If platform echo canceller is enabled, disable the software AEC. |
| 140 if (effects_ & media::AudioParameters::ECHO_CANCELLER) |
| 141 return false; |
| 142 |
| 143 // If |kEchoCancellation| is specified in the constraints, it will |
| 144 // overwrite the value of |kGoogEchoCancellation|. |
| 145 bool value = false; |
| 146 if (GetConstraintValue(constraints_, kEchoCancellation, &value)) |
| 147 return value; |
| 148 |
| 149 return GetProperty(kGoogEchoCancellation); |
| 150 } |
| 151 |
| 152 bool MediaAudioConstraints::IsValid() { |
| 153 blink::WebVector<blink::WebMediaConstraint> mandatory; |
| 154 constraints_.getMandatoryConstraints(mandatory); |
| 155 for (size_t i = 0; i < mandatory.size(); ++i) { |
| 156 if (mandatory[i].m_name.utf8() == kMediaStreamSource) |
| 157 continue; |
| 158 |
| 159 bool valid = false; |
| 160 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++j) { |
| 161 if (mandatory[i].m_name.utf8() == kDefaultAudioConstraints[j].key) { |
| 162 valid = true; |
| 163 break; |
| 164 } |
| 165 } |
| 166 |
| 167 if (!valid) { |
| 168 DLOG(ERROR) << "Invalid MediaStream constraint. Name:" |
| 169 << mandatory[i].m_name.utf8(); |
| 170 return false; |
| 171 } |
| 172 } |
| 173 |
| 174 return true; |
94 } | 175 } |
95 | 176 |
96 void EnableEchoCancellation(AudioProcessing* audio_processing) { | 177 void EnableEchoCancellation(AudioProcessing* audio_processing) { |
97 #if defined(OS_ANDROID) | 178 #if defined(OS_ANDROID) |
98 // Mobile devices are using AECM. | 179 // Mobile devices are using AECM. |
99 int err = audio_processing->echo_control_mobile()->set_routing_mode( | 180 int err = audio_processing->echo_control_mobile()->set_routing_mode( |
100 webrtc::EchoControlMobile::kSpeakerphone); | 181 webrtc::EchoControlMobile::kSpeakerphone); |
101 err |= audio_processing->echo_control_mobile()->Enable(true); | 182 err |= audio_processing->echo_control_mobile()->Enable(true); |
102 CHECK_EQ(err, 0); | 183 CHECK_EQ(err, 0); |
103 #else | 184 #else |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 } | 288 } |
208 | 289 |
209 int median = 0, std = 0; | 290 int median = 0, std = 0; |
210 if (!audio_processing->echo_cancellation()->GetDelayMetrics(&median, &std)) { | 291 if (!audio_processing->echo_cancellation()->GetDelayMetrics(&median, &std)) { |
211 stats->echo_delay_median_ms = median; | 292 stats->echo_delay_median_ms = median; |
212 stats->echo_delay_std_ms = std; | 293 stats->echo_delay_std_ms = std; |
213 } | 294 } |
214 } | 295 } |
215 | 296 |
216 } // namespace content | 297 } // namespace content |
OLD | NEW |