OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 #include "webrtc/base/byteorder.h" | 47 #include "webrtc/base/byteorder.h" |
48 #include "webrtc/base/common.h" | 48 #include "webrtc/base/common.h" |
49 #include "webrtc/base/helpers.h" | 49 #include "webrtc/base/helpers.h" |
50 #include "webrtc/base/logging.h" | 50 #include "webrtc/base/logging.h" |
51 #include "webrtc/base/stringencode.h" | 51 #include "webrtc/base/stringencode.h" |
52 #include "webrtc/base/stringutils.h" | 52 #include "webrtc/base/stringutils.h" |
53 #include "webrtc/common.h" | 53 #include "webrtc/common.h" |
54 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 54 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
55 | 55 |
56 namespace cricket { | 56 namespace cricket { |
| 57 namespace { |
57 | 58 |
58 static const int kMaxNumPacketSize = 6; | 59 const int kMaxNumPacketSize = 6; |
59 struct CodecPref { | 60 struct CodecPref { |
60 const char* name; | 61 const char* name; |
61 int clockrate; | 62 int clockrate; |
62 int channels; | 63 int channels; |
63 int payload_type; | 64 int payload_type; |
64 bool is_multi_rate; | 65 bool is_multi_rate; |
65 int packet_sizes_ms[kMaxNumPacketSize]; | 66 int packet_sizes_ms[kMaxNumPacketSize]; |
66 }; | 67 }; |
67 // Note: keep the supported packet sizes in ascending order. | 68 // Note: keep the supported packet sizes in ascending order. |
68 static const CodecPref kCodecPrefs[] = { | 69 const CodecPref kCodecPrefs[] = { |
69 { kOpusCodecName, 48000, 2, 111, true, { 10, 20, 40, 60 } }, | 70 { kOpusCodecName, 48000, 2, 111, true, { 10, 20, 40, 60 } }, |
70 { kIsacCodecName, 16000, 1, 103, true, { 30, 60 } }, | 71 { kIsacCodecName, 16000, 1, 103, true, { 30, 60 } }, |
71 { kIsacCodecName, 32000, 1, 104, true, { 30 } }, | 72 { kIsacCodecName, 32000, 1, 104, true, { 30 } }, |
72 // G722 should be advertised as 8000 Hz because of the RFC "bug". | 73 // G722 should be advertised as 8000 Hz because of the RFC "bug". |
73 { kG722CodecName, 8000, 1, 9, false, { 10, 20, 30, 40, 50, 60 } }, | 74 { kG722CodecName, 8000, 1, 9, false, { 10, 20, 30, 40, 50, 60 } }, |
74 { kIlbcCodecName, 8000, 1, 102, false, { 20, 30, 40, 60 } }, | 75 { kIlbcCodecName, 8000, 1, 102, false, { 20, 30, 40, 60 } }, |
75 { kPcmuCodecName, 8000, 1, 0, false, { 10, 20, 30, 40, 50, 60 } }, | 76 { kPcmuCodecName, 8000, 1, 0, false, { 10, 20, 30, 40, 50, 60 } }, |
76 { kPcmaCodecName, 8000, 1, 8, false, { 10, 20, 30, 40, 50, 60 } }, | 77 { kPcmaCodecName, 8000, 1, 8, false, { 10, 20, 30, 40, 50, 60 } }, |
77 { kCnCodecName, 32000, 1, 106, false, { } }, | 78 { kCnCodecName, 32000, 1, 106, false, { } }, |
78 { kCnCodecName, 16000, 1, 105, false, { } }, | 79 { kCnCodecName, 16000, 1, 105, false, { } }, |
(...skipping 11 matching lines...) Expand all Loading... |
90 // | 91 // |
91 // On Windows systems which only support Wave Audio style default, uses either | 92 // On Windows systems which only support Wave Audio style default, uses either |
92 // -1 or 0 to select the default device. | 93 // -1 or 0 to select the default device. |
93 // | 94 // |
94 // On Windows systems which support both "Default Communication Device" and | 95 // On Windows systems which support both "Default Communication Device" and |
95 // old Wave Audio style default, use -1 for Default Communications Device and | 96 // old Wave Audio style default, use -1 for Default Communications Device and |
96 // -2 for Wave Audio style default, which is what we want to use for clips. | 97 // -2 for Wave Audio style default, which is what we want to use for clips. |
97 // It's not clear yet whether the -2 index is handled properly on other OSes. | 98 // It's not clear yet whether the -2 index is handled properly on other OSes. |
98 | 99 |
99 #ifdef WIN32 | 100 #ifdef WIN32 |
100 static const int kDefaultAudioDeviceId = -1; | 101 const int kDefaultAudioDeviceId = -1; |
101 #else | 102 #else |
102 static const int kDefaultAudioDeviceId = 0; | 103 const int kDefaultAudioDeviceId = 0; |
103 #endif | 104 #endif |
104 | 105 |
105 // Parameter used for NACK. | 106 // Parameter used for NACK. |
106 // This value is equivalent to 5 seconds of audio data at 20 ms per packet. | 107 // This value is equivalent to 5 seconds of audio data at 20 ms per packet. |
107 static const int kNackMaxPackets = 250; | 108 const int kNackMaxPackets = 250; |
108 | 109 |
109 // Codec parameters for Opus. | 110 // Codec parameters for Opus. |
110 // draft-spittka-payload-rtp-opus-03 | 111 // draft-spittka-payload-rtp-opus-03 |
111 | 112 |
112 // Recommended bitrates: | 113 // Recommended bitrates: |
113 // 8-12 kb/s for NB speech, | 114 // 8-12 kb/s for NB speech, |
114 // 16-20 kb/s for WB speech, | 115 // 16-20 kb/s for WB speech, |
115 // 28-40 kb/s for FB speech, | 116 // 28-40 kb/s for FB speech, |
116 // 48-64 kb/s for FB mono music, and | 117 // 48-64 kb/s for FB mono music, and |
117 // 64-128 kb/s for FB stereo music. | 118 // 64-128 kb/s for FB stereo music. |
118 // The current implementation applies the following values to mono signals, | 119 // The current implementation applies the following values to mono signals, |
119 // and multiplies them by 2 for stereo. | 120 // and multiplies them by 2 for stereo. |
120 static const int kOpusBitrateNb = 12000; | 121 const int kOpusBitrateNb = 12000; |
121 static const int kOpusBitrateWb = 20000; | 122 const int kOpusBitrateWb = 20000; |
122 static const int kOpusBitrateFb = 32000; | 123 const int kOpusBitrateFb = 32000; |
123 | 124 |
124 // Opus bitrate should be in the range between 6000 and 510000. | 125 // Opus bitrate should be in the range between 6000 and 510000. |
125 static const int kOpusMinBitrate = 6000; | 126 const int kOpusMinBitrate = 6000; |
126 static const int kOpusMaxBitrate = 510000; | 127 const int kOpusMaxBitrate = 510000; |
127 | 128 |
128 // Default audio dscp value. | 129 // Default audio dscp value. |
129 // See http://tools.ietf.org/html/rfc2474 for details. | 130 // See http://tools.ietf.org/html/rfc2474 for details. |
130 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 | 131 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 |
131 static const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; | 132 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; |
132 | 133 |
133 // Ensure we open the file in a writeable path on ChromeOS and Android. This | 134 // Ensure we open the file in a writeable path on ChromeOS and Android. This |
134 // workaround can be removed when it's possible to specify a filename for audio | 135 // workaround can be removed when it's possible to specify a filename for audio |
135 // option based AEC dumps. | 136 // option based AEC dumps. |
136 // | 137 // |
137 // TODO(grunell): Use a string in the options instead of hardcoding it here | 138 // TODO(grunell): Use a string in the options instead of hardcoding it here |
138 // and let the embedder choose the filename (crbug.com/264223). | 139 // and let the embedder choose the filename (crbug.com/264223). |
139 // | 140 // |
140 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified | 141 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified |
141 // below. | 142 // below. |
142 #if defined(CHROMEOS) | 143 #if defined(CHROMEOS) |
143 static const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; | 144 const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; |
144 #elif defined(ANDROID) | 145 #elif defined(ANDROID) |
145 static const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; | 146 const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; |
146 #else | 147 #else |
147 static const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; | 148 const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; |
148 #endif | 149 #endif |
149 | 150 |
150 // Dumps an AudioCodec in RFC 2327-ish format. | 151 // Dumps an AudioCodec in RFC 2327-ish format. |
151 static std::string ToString(const AudioCodec& codec) { | 152 std::string ToString(const AudioCodec& codec) { |
152 std::stringstream ss; | 153 std::stringstream ss; |
153 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels | 154 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels |
154 << " (" << codec.id << ")"; | 155 << " (" << codec.id << ")"; |
155 return ss.str(); | 156 return ss.str(); |
156 } | 157 } |
157 | 158 |
158 static std::string ToString(const webrtc::CodecInst& codec) { | 159 std::string ToString(const webrtc::CodecInst& codec) { |
159 std::stringstream ss; | 160 std::stringstream ss; |
160 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels | 161 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels |
161 << " (" << codec.pltype << ")"; | 162 << " (" << codec.pltype << ")"; |
162 return ss.str(); | 163 return ss.str(); |
163 } | 164 } |
164 | 165 |
165 static void LogMultiline(rtc::LoggingSeverity sev, char* text) { | 166 void LogMultiline(rtc::LoggingSeverity sev, char* text) { |
166 const char* delim = "\r\n"; | 167 const char* delim = "\r\n"; |
167 for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) { | 168 for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) { |
168 LOG_V(sev) << tok; | 169 LOG_V(sev) << tok; |
169 } | 170 } |
170 } | 171 } |
171 | 172 |
172 // Severity is an integer because it comes is assumed to be from command line. | 173 // Severity is an integer because it comes is assumed to be from command line. |
173 static int SeverityToFilter(int severity) { | 174 int SeverityToFilter(int severity) { |
174 int filter = webrtc::kTraceNone; | 175 int filter = webrtc::kTraceNone; |
175 switch (severity) { | 176 switch (severity) { |
176 case rtc::LS_VERBOSE: | 177 case rtc::LS_VERBOSE: |
177 filter |= webrtc::kTraceAll; | 178 filter |= webrtc::kTraceAll; |
178 FALLTHROUGH(); | 179 FALLTHROUGH(); |
179 case rtc::LS_INFO: | 180 case rtc::LS_INFO: |
180 filter |= (webrtc::kTraceStateInfo | webrtc::kTraceInfo); | 181 filter |= (webrtc::kTraceStateInfo | webrtc::kTraceInfo); |
181 FALLTHROUGH(); | 182 FALLTHROUGH(); |
182 case rtc::LS_WARNING: | 183 case rtc::LS_WARNING: |
183 filter |= (webrtc::kTraceTerseInfo | webrtc::kTraceWarning); | 184 filter |= (webrtc::kTraceTerseInfo | webrtc::kTraceWarning); |
184 FALLTHROUGH(); | 185 FALLTHROUGH(); |
185 case rtc::LS_ERROR: | 186 case rtc::LS_ERROR: |
186 filter |= (webrtc::kTraceError | webrtc::kTraceCritical); | 187 filter |= (webrtc::kTraceError | webrtc::kTraceCritical); |
187 } | 188 } |
188 return filter; | 189 return filter; |
189 } | 190 } |
190 | 191 |
191 static bool IsCodec(const AudioCodec& codec, const char* ref_name) { | 192 bool IsCodec(const AudioCodec& codec, const char* ref_name) { |
192 return (_stricmp(codec.name.c_str(), ref_name) == 0); | 193 return (_stricmp(codec.name.c_str(), ref_name) == 0); |
193 } | 194 } |
194 | 195 |
195 static bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) { | 196 bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) { |
196 return (_stricmp(codec.plname, ref_name) == 0); | 197 return (_stricmp(codec.plname, ref_name) == 0); |
197 } | 198 } |
198 | 199 |
199 static bool IsCodecMultiRate(const webrtc::CodecInst& codec) { | 200 bool IsCodecMultiRate(const webrtc::CodecInst& codec) { |
200 for (size_t i = 0; i < ARRAY_SIZE(kCodecPrefs); ++i) { | 201 for (size_t i = 0; i < ARRAY_SIZE(kCodecPrefs); ++i) { |
201 if (IsCodec(codec, kCodecPrefs[i].name) && | 202 if (IsCodec(codec, kCodecPrefs[i].name) && |
202 kCodecPrefs[i].clockrate == codec.plfreq) { | 203 kCodecPrefs[i].clockrate == codec.plfreq) { |
203 return kCodecPrefs[i].is_multi_rate; | 204 return kCodecPrefs[i].is_multi_rate; |
204 } | 205 } |
205 } | 206 } |
206 return false; | 207 return false; |
207 } | 208 } |
208 | 209 |
209 static bool FindCodec(const std::vector<AudioCodec>& codecs, | 210 bool FindCodec(const std::vector<AudioCodec>& codecs, |
210 const AudioCodec& codec, | 211 const AudioCodec& codec, |
211 AudioCodec* found_codec) { | 212 AudioCodec* found_codec) { |
212 for (const AudioCodec& c : codecs) { | 213 for (const AudioCodec& c : codecs) { |
213 if (c.Matches(codec)) { | 214 if (c.Matches(codec)) { |
214 if (found_codec != NULL) { | 215 if (found_codec != NULL) { |
215 *found_codec = c; | 216 *found_codec = c; |
216 } | 217 } |
217 return true; | 218 return true; |
218 } | 219 } |
219 } | 220 } |
220 return false; | 221 return false; |
221 } | 222 } |
222 | 223 |
223 static bool IsNackEnabled(const AudioCodec& codec) { | 224 bool IsNackEnabled(const AudioCodec& codec) { |
224 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, | 225 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, |
225 kParamValueEmpty)); | 226 kParamValueEmpty)); |
226 } | 227 } |
227 | 228 |
228 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { | 229 int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { |
229 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; | 230 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; |
230 for (int packet_size_ms : codec_pref.packet_sizes_ms) { | 231 for (int packet_size_ms : codec_pref.packet_sizes_ms) { |
231 if (packet_size_ms && packet_size_ms <= ptime_ms) { | 232 if (packet_size_ms && packet_size_ms <= ptime_ms) { |
232 selected_packet_size_ms = packet_size_ms; | 233 selected_packet_size_ms = packet_size_ms; |
233 } | 234 } |
234 } | 235 } |
235 return selected_packet_size_ms; | 236 return selected_packet_size_ms; |
236 } | 237 } |
237 | 238 |
238 // If the AudioCodec param kCodecParamPTime is set, then we will set it to codec | 239 // If the AudioCodec param kCodecParamPTime is set, then we will set it to codec |
239 // pacsize if it's valid, or we will pick the next smallest value we support. | 240 // pacsize if it's valid, or we will pick the next smallest value we support. |
240 // TODO(Brave): Query supported packet sizes from ACM when the API is ready. | 241 // TODO(Brave): Query supported packet sizes from ACM when the API is ready. |
241 static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) { | 242 bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) { |
242 for (const CodecPref& codec_pref : kCodecPrefs) { | 243 for (const CodecPref& codec_pref : kCodecPrefs) { |
243 if ((IsCodec(*codec, codec_pref.name) && | 244 if ((IsCodec(*codec, codec_pref.name) && |
244 codec_pref.clockrate == codec->plfreq) || | 245 codec_pref.clockrate == codec->plfreq) || |
245 IsCodec(*codec, kG722CodecName)) { | 246 IsCodec(*codec, kG722CodecName)) { |
246 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms); | 247 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms); |
247 if (packet_size_ms) { | 248 if (packet_size_ms) { |
248 // Convert unit from milli-seconds to samples. | 249 // Convert unit from milli-seconds to samples. |
249 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms; | 250 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms; |
250 return true; | 251 return true; |
251 } | 252 } |
252 } | 253 } |
253 } | 254 } |
254 return false; | 255 return false; |
255 } | 256 } |
256 | 257 |
257 // Return true if codec.params[feature] == "1", false otherwise. | 258 // Return true if codec.params[feature] == "1", false otherwise. |
258 static bool IsCodecFeatureEnabled(const AudioCodec& codec, | 259 bool IsCodecFeatureEnabled(const AudioCodec& codec, |
259 const char* feature) { | 260 const char* feature) { |
260 int value; | 261 int value; |
261 return codec.GetParam(feature, &value) && value == 1; | 262 return codec.GetParam(feature, &value) && value == 1; |
262 } | 263 } |
263 | 264 |
264 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate | 265 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate |
265 // otherwise. If the value (either from params or codec.bitrate) <=0, use the | 266 // otherwise. If the value (either from params or codec.bitrate) <=0, use the |
266 // default configuration. If the value is beyond feasible bit rate of Opus, | 267 // default configuration. If the value is beyond feasible bit rate of Opus, |
267 // clamp it. Returns the Opus bit rate for operation. | 268 // clamp it. Returns the Opus bit rate for operation. |
268 static int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { | 269 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { |
269 int bitrate = 0; | 270 int bitrate = 0; |
270 bool use_param = true; | 271 bool use_param = true; |
271 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) { | 272 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) { |
272 bitrate = codec.bitrate; | 273 bitrate = codec.bitrate; |
273 use_param = false; | 274 use_param = false; |
274 } | 275 } |
275 if (bitrate <= 0) { | 276 if (bitrate <= 0) { |
276 if (max_playback_rate <= 8000) { | 277 if (max_playback_rate <= 8000) { |
277 bitrate = kOpusBitrateNb; | 278 bitrate = kOpusBitrateNb; |
278 } else if (max_playback_rate <= 16000) { | 279 } else if (max_playback_rate <= 16000) { |
(...skipping 12 matching lines...) Expand all Loading... |
291 "Supplied Opus bitrate"; | 292 "Supplied Opus bitrate"; |
292 LOG(LS_WARNING) << rate_source | 293 LOG(LS_WARNING) << rate_source |
293 << " is invalid and is replaced by: " | 294 << " is invalid and is replaced by: " |
294 << bitrate; | 295 << bitrate; |
295 } | 296 } |
296 return bitrate; | 297 return bitrate; |
297 } | 298 } |
298 | 299 |
299 // Returns kOpusDefaultPlaybackRate if params[kCodecParamMaxPlaybackRate] is not | 300 // Returns kOpusDefaultPlaybackRate if params[kCodecParamMaxPlaybackRate] is not |
300 // defined. Returns the value of params[kCodecParamMaxPlaybackRate] otherwise. | 301 // defined. Returns the value of params[kCodecParamMaxPlaybackRate] otherwise. |
301 static int GetOpusMaxPlaybackRate(const AudioCodec& codec) { | 302 int GetOpusMaxPlaybackRate(const AudioCodec& codec) { |
302 int value; | 303 int value; |
303 if (codec.GetParam(kCodecParamMaxPlaybackRate, &value)) { | 304 if (codec.GetParam(kCodecParamMaxPlaybackRate, &value)) { |
304 return value; | 305 return value; |
305 } | 306 } |
306 return kOpusDefaultMaxPlaybackRate; | 307 return kOpusDefaultMaxPlaybackRate; |
307 } | 308 } |
308 | 309 |
309 static void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, | 310 void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, |
310 bool* enable_codec_fec, int* max_playback_rate, | 311 bool* enable_codec_fec, int* max_playback_rate, |
311 bool* enable_codec_dtx) { | 312 bool* enable_codec_dtx) { |
312 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec); | 313 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec); |
313 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx); | 314 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx); |
314 *max_playback_rate = GetOpusMaxPlaybackRate(codec); | 315 *max_playback_rate = GetOpusMaxPlaybackRate(codec); |
315 | 316 |
316 // If OPUS, change what we send according to the "stereo" codec | 317 // If OPUS, change what we send according to the "stereo" codec |
317 // parameter, and not the "channels" parameter. We set | 318 // parameter, and not the "channels" parameter. We set |
318 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If | 319 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If |
319 // the bitrate is not specified, i.e. is <= zero, we set it to the | 320 // the bitrate is not specified, i.e. is <= zero, we set it to the |
320 // appropriate default value for mono or stereo Opus. | 321 // appropriate default value for mono or stereo Opus. |
321 | 322 |
322 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; | 323 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; |
323 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); | 324 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); |
324 } | 325 } |
325 | 326 |
326 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC | 327 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC |
327 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz | 328 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz |
328 // codec. | 329 // codec. |
329 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { | 330 void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { |
330 if (IsCodec(*voe_codec, kG722CodecName)) { | 331 if (IsCodec(*voe_codec, kG722CodecName)) { |
331 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine | 332 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine |
332 // has changed, and this special case is no longer needed. | 333 // has changed, and this special case is no longer needed. |
333 RTC_DCHECK(voe_codec->plfreq != new_plfreq); | 334 RTC_DCHECK(voe_codec->plfreq != new_plfreq); |
334 voe_codec->plfreq = new_plfreq; | 335 voe_codec->plfreq = new_plfreq; |
335 } | 336 } |
336 } | 337 } |
337 | 338 |
338 // Gets the default set of options applied to the engine. Historically, these | 339 // Gets the default set of options applied to the engine. Historically, these |
339 // were supplied as a combination of flags from the channel manager (ec, agc, | 340 // were supplied as a combination of flags from the channel manager (ec, agc, |
340 // ns, and highpass) and the rest hardcoded in InitInternal. | 341 // ns, and highpass) and the rest hardcoded in InitInternal. |
341 static AudioOptions GetDefaultEngineOptions() { | 342 AudioOptions GetDefaultEngineOptions() { |
342 AudioOptions options; | 343 AudioOptions options; |
343 options.echo_cancellation.Set(true); | 344 options.echo_cancellation.Set(true); |
344 options.auto_gain_control.Set(true); | 345 options.auto_gain_control.Set(true); |
345 options.noise_suppression.Set(true); | 346 options.noise_suppression.Set(true); |
346 options.highpass_filter.Set(true); | 347 options.highpass_filter.Set(true); |
347 options.stereo_swapping.Set(false); | 348 options.stereo_swapping.Set(false); |
348 options.audio_jitter_buffer_max_packets.Set(50); | 349 options.audio_jitter_buffer_max_packets.Set(50); |
349 options.audio_jitter_buffer_fast_accelerate.Set(false); | 350 options.audio_jitter_buffer_fast_accelerate.Set(false); |
350 options.typing_detection.Set(true); | 351 options.typing_detection.Set(true); |
351 options.conference_mode.Set(false); | 352 options.conference_mode.Set(false); |
352 options.adjust_agc_delta.Set(0); | 353 options.adjust_agc_delta.Set(0); |
353 options.experimental_agc.Set(false); | 354 options.experimental_agc.Set(false); |
354 options.extended_filter_aec.Set(false); | 355 options.extended_filter_aec.Set(false); |
355 options.delay_agnostic_aec.Set(false); | 356 options.delay_agnostic_aec.Set(false); |
356 options.experimental_ns.Set(false); | 357 options.experimental_ns.Set(false); |
357 options.aec_dump.Set(false); | 358 options.aec_dump.Set(false); |
358 return options; | 359 return options; |
359 } | 360 } |
360 | 361 |
361 static std::string GetEnableString(bool enable) { | 362 std::string GetEnableString(bool enable) { |
362 return enable ? "enable" : "disable"; | 363 return enable ? "enable" : "disable"; |
363 } | 364 } |
| 365 } // namespace { |
364 | 366 |
365 WebRtcVoiceEngine::WebRtcVoiceEngine() | 367 WebRtcVoiceEngine::WebRtcVoiceEngine() |
366 : voe_wrapper_(new VoEWrapper()), | 368 : voe_wrapper_(new VoEWrapper()), |
367 tracing_(new VoETraceWrapper()), | 369 tracing_(new VoETraceWrapper()), |
368 adm_(NULL), | 370 adm_(NULL), |
369 log_filter_(SeverityToFilter(kDefaultLogSeverity)), | 371 log_filter_(SeverityToFilter(kDefaultLogSeverity)), |
370 is_dumping_aec_(false) { | 372 is_dumping_aec_(false) { |
371 Construct(); | 373 Construct(); |
372 } | 374 } |
373 | 375 |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 if (options.playout_sample_rate.Get(&playout_sample_rate)) { | 857 if (options.playout_sample_rate.Get(&playout_sample_rate)) { |
856 LOG(LS_INFO) << "Playout sample rate is " << playout_sample_rate; | 858 LOG(LS_INFO) << "Playout sample rate is " << playout_sample_rate; |
857 if (voe_wrapper_->hw()->SetPlayoutSampleRate(playout_sample_rate)) { | 859 if (voe_wrapper_->hw()->SetPlayoutSampleRate(playout_sample_rate)) { |
858 LOG_RTCERR1(SetPlayoutSampleRate, playout_sample_rate); | 860 LOG_RTCERR1(SetPlayoutSampleRate, playout_sample_rate); |
859 } | 861 } |
860 } | 862 } |
861 | 863 |
862 return true; | 864 return true; |
863 } | 865 } |
864 | 866 |
865 struct ResumeEntry { | |
866 ResumeEntry(WebRtcVoiceMediaChannel *c, bool p, SendFlags s) | |
867 : channel(c), | |
868 playout(p), | |
869 send(s) { | |
870 } | |
871 | |
872 WebRtcVoiceMediaChannel *channel; | |
873 bool playout; | |
874 SendFlags send; | |
875 }; | |
876 | |
877 // TODO(juberti): Refactor this so that the core logic can be used to set the | 867 // TODO(juberti): Refactor this so that the core logic can be used to set the |
878 // soundclip device. At that time, reinstate the soundclip pause/resume code. | 868 // soundclip device. At that time, reinstate the soundclip pause/resume code. |
879 bool WebRtcVoiceEngine::SetDevices(const Device* in_device, | 869 bool WebRtcVoiceEngine::SetDevices(const Device* in_device, |
880 const Device* out_device) { | 870 const Device* out_device) { |
881 #if !defined(IOS) | 871 #if !defined(IOS) |
882 int in_id = in_device ? rtc::FromString<int>(in_device->id) : | 872 int in_id = in_device ? rtc::FromString<int>(in_device->id) : |
883 kDefaultAudioDeviceId; | 873 kDefaultAudioDeviceId; |
884 int out_id = out_device ? rtc::FromString<int>(out_device->id) : | 874 int out_id = out_device ? rtc::FromString<int>(out_device->id) : |
885 kDefaultAudioDeviceId; | 875 kDefaultAudioDeviceId; |
886 // The device manager uses -1 as the default device, which was the case for | 876 // The device manager uses -1 as the default device, which was the case for |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 if (length < 72) { | 1169 if (length < 72) { |
1180 std::string msg(trace, length); | 1170 std::string msg(trace, length); |
1181 LOG(LS_ERROR) << "Malformed webrtc log message: "; | 1171 LOG(LS_ERROR) << "Malformed webrtc log message: "; |
1182 LOG_V(sev) << msg; | 1172 LOG_V(sev) << msg; |
1183 } else { | 1173 } else { |
1184 std::string msg(trace + 71, length - 72); | 1174 std::string msg(trace + 71, length - 72); |
1185 LOG_V(sev) << "webrtc: " << msg; | 1175 LOG_V(sev) << "webrtc: " << msg; |
1186 } | 1176 } |
1187 } | 1177 } |
1188 | 1178 |
1189 void WebRtcVoiceEngine::CallbackOnError(int channel_num, int err_code) { | 1179 void WebRtcVoiceEngine::CallbackOnError(int channel_id, int err_code) { |
| 1180 RTC_DCHECK(channel_id == -1); |
| 1181 LOG(LS_WARNING) << "VoiceEngine error " << err_code << " reported on channel " |
| 1182 << channel_id << "."; |
1190 rtc::CritScope lock(&channels_cs_); | 1183 rtc::CritScope lock(&channels_cs_); |
1191 WebRtcVoiceMediaChannel* channel = NULL; | 1184 for (WebRtcVoiceMediaChannel* channel : channels_) { |
1192 uint32 ssrc = 0; | 1185 channel->OnError(err_code); |
1193 LOG(LS_WARNING) << "VoiceEngine error " << err_code << " reported on channel " | |
1194 << channel_num << "."; | |
1195 if (FindChannelAndSsrc(channel_num, &channel, &ssrc)) { | |
1196 RTC_DCHECK(channel != NULL); | |
1197 channel->OnError(ssrc, err_code); | |
1198 } else { | |
1199 LOG(LS_ERROR) << "VoiceEngine channel " << channel_num | |
1200 << " could not be found in channel list when error reported."; | |
1201 } | 1186 } |
1202 } | 1187 } |
1203 | 1188 |
1204 bool WebRtcVoiceEngine::FindChannelAndSsrc( | |
1205 int channel_num, WebRtcVoiceMediaChannel** channel, uint32* ssrc) const { | |
1206 RTC_DCHECK(channel != NULL && ssrc != NULL); | |
1207 | |
1208 *channel = NULL; | |
1209 *ssrc = 0; | |
1210 // Find corresponding channel and ssrc | |
1211 for (WebRtcVoiceMediaChannel* ch : channels_) { | |
1212 RTC_DCHECK(ch != NULL); | |
1213 if (ch->FindSsrc(channel_num, ssrc)) { | |
1214 *channel = ch; | |
1215 return true; | |
1216 } | |
1217 } | |
1218 | |
1219 return false; | |
1220 } | |
1221 | |
1222 void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel* channel) { | 1189 void WebRtcVoiceEngine::RegisterChannel(WebRtcVoiceMediaChannel* channel) { |
| 1190 RTC_DCHECK(channel != NULL); |
1223 rtc::CritScope lock(&channels_cs_); | 1191 rtc::CritScope lock(&channels_cs_); |
1224 channels_.push_back(channel); | 1192 channels_.push_back(channel); |
1225 } | 1193 } |
1226 | 1194 |
1227 void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) { | 1195 void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel* channel) { |
1228 rtc::CritScope lock(&channels_cs_); | 1196 rtc::CritScope lock(&channels_cs_); |
1229 auto it = std::find(channels_.begin(), channels_.end(), channel); | 1197 auto it = std::find(channels_.begin(), channels_.end(), channel); |
1230 if (it != channels_.end()) { | 1198 if (it != channels_.end()) { |
1231 channels_.erase(it); | 1199 channels_.erase(it); |
1232 } | 1200 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 options_(), | 1377 options_(), |
1410 dtmf_allowed_(false), | 1378 dtmf_allowed_(false), |
1411 desired_playout_(false), | 1379 desired_playout_(false), |
1412 nack_enabled_(false), | 1380 nack_enabled_(false), |
1413 playout_(false), | 1381 playout_(false), |
1414 typing_noise_detected_(false), | 1382 typing_noise_detected_(false), |
1415 desired_send_(SEND_NOTHING), | 1383 desired_send_(SEND_NOTHING), |
1416 send_(SEND_NOTHING), | 1384 send_(SEND_NOTHING), |
1417 call_(call), | 1385 call_(call), |
1418 default_receive_ssrc_(0) { | 1386 default_receive_ssrc_(0) { |
| 1387 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1419 engine->RegisterChannel(this); | 1388 engine->RegisterChannel(this); |
1420 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel " | 1389 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel " |
1421 << voe_channel(); | 1390 << voe_channel(); |
1422 RTC_DCHECK(nullptr != call); | 1391 RTC_DCHECK(nullptr != call); |
1423 ConfigureSendChannel(voe_channel()); | 1392 ConfigureSendChannel(voe_channel()); |
1424 SetOptions(options); | 1393 SetOptions(options); |
1425 } | 1394 } |
1426 | 1395 |
1427 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { | 1396 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { |
| 1397 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1428 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel " | 1398 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel " |
1429 << voe_channel(); | 1399 << voe_channel(); |
1430 | 1400 |
1431 // Remove any remaining send streams, the default channel will be deleted | 1401 // Remove any remaining send streams, the default channel will be deleted |
1432 // later. | 1402 // later. |
1433 while (!send_channels_.empty()) | 1403 while (!send_channels_.empty()) { |
1434 RemoveSendStream(send_channels_.begin()->first); | 1404 RemoveSendStream(send_channels_.begin()->first); |
| 1405 } |
1435 | 1406 |
1436 // Unregister ourselves from the engine. | 1407 // Unregister ourselves from the engine. |
1437 engine()->UnregisterChannel(this); | 1408 engine()->UnregisterChannel(this); |
| 1409 |
1438 // Remove any remaining streams. | 1410 // Remove any remaining streams. |
1439 while (!receive_channels_.empty()) { | 1411 while (!receive_channels_.empty()) { |
1440 RemoveRecvStream(receive_channels_.begin()->first); | 1412 RemoveRecvStream(receive_channels_.begin()->first); |
1441 } | 1413 } |
1442 RTC_DCHECK(receive_streams_.empty()); | 1414 RTC_DCHECK(receive_streams_.empty()); |
1443 | 1415 |
1444 // Delete the default channel. | 1416 // Delete the default channel. |
1445 DeleteChannel(voe_channel()); | 1417 DeleteChannel(voe_channel()); |
1446 } | 1418 } |
1447 | 1419 |
1448 bool WebRtcVoiceMediaChannel::SetSendParameters( | 1420 bool WebRtcVoiceMediaChannel::SetSendParameters( |
1449 const AudioSendParameters& params) { | 1421 const AudioSendParameters& params) { |
| 1422 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1450 // TODO(pthatcher): Refactor this to be more clean now that we have | 1423 // TODO(pthatcher): Refactor this to be more clean now that we have |
1451 // all the information at once. | 1424 // all the information at once. |
1452 return (SetSendCodecs(params.codecs) && | 1425 return (SetSendCodecs(params.codecs) && |
1453 SetSendRtpHeaderExtensions(params.extensions) && | 1426 SetSendRtpHeaderExtensions(params.extensions) && |
1454 SetMaxSendBandwidth(params.max_bandwidth_bps) && | 1427 SetMaxSendBandwidth(params.max_bandwidth_bps) && |
1455 SetOptions(params.options)); | 1428 SetOptions(params.options)); |
1456 } | 1429 } |
1457 | 1430 |
1458 bool WebRtcVoiceMediaChannel::SetRecvParameters( | 1431 bool WebRtcVoiceMediaChannel::SetRecvParameters( |
1459 const AudioRecvParameters& params) { | 1432 const AudioRecvParameters& params) { |
| 1433 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1460 // TODO(pthatcher): Refactor this to be more clean now that we have | 1434 // TODO(pthatcher): Refactor this to be more clean now that we have |
1461 // all the information at once. | 1435 // all the information at once. |
1462 return (SetRecvCodecs(params.codecs) && | 1436 return (SetRecvCodecs(params.codecs) && |
1463 SetRecvRtpHeaderExtensions(params.extensions)); | 1437 SetRecvRtpHeaderExtensions(params.extensions)); |
1464 } | 1438 } |
1465 | 1439 |
1466 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { | 1440 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { |
| 1441 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1467 LOG(LS_INFO) << "Setting voice channel options: " | 1442 LOG(LS_INFO) << "Setting voice channel options: " |
1468 << options.ToString(); | 1443 << options.ToString(); |
1469 | 1444 |
1470 // Check if DSCP value is changed from previous. | 1445 // Check if DSCP value is changed from previous. |
1471 bool dscp_option_changed = (options_.dscp != options.dscp); | 1446 bool dscp_option_changed = (options_.dscp != options.dscp); |
1472 | 1447 |
1473 // TODO(xians): Add support to set different options for different send | 1448 // TODO(xians): Add support to set different options for different send |
1474 // streams after we support multiple APMs. | 1449 // streams after we support multiple APMs. |
1475 | 1450 |
1476 // We retain all of the existing options, and apply the given ones | 1451 // We retain all of the existing options, and apply the given ones |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1546 | 1521 |
1547 RecreateAudioReceiveStreams(); | 1522 RecreateAudioReceiveStreams(); |
1548 | 1523 |
1549 LOG(LS_INFO) << "Set voice channel options. Current options: " | 1524 LOG(LS_INFO) << "Set voice channel options. Current options: " |
1550 << options_.ToString(); | 1525 << options_.ToString(); |
1551 return true; | 1526 return true; |
1552 } | 1527 } |
1553 | 1528 |
1554 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1529 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
1555 const std::vector<AudioCodec>& codecs) { | 1530 const std::vector<AudioCodec>& codecs) { |
| 1531 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1556 // Set the payload types to be used for incoming media. | 1532 // Set the payload types to be used for incoming media. |
1557 LOG(LS_INFO) << "Setting receive voice codecs:"; | 1533 LOG(LS_INFO) << "Setting receive voice codecs:"; |
1558 | 1534 |
1559 std::vector<AudioCodec> new_codecs; | 1535 std::vector<AudioCodec> new_codecs; |
1560 // Find all new codecs. We allow adding new codecs but don't allow changing | 1536 // Find all new codecs. We allow adding new codecs but don't allow changing |
1561 // the payload type of codecs that is already configured since we might | 1537 // the payload type of codecs that is already configured since we might |
1562 // already be receiving packets with that payload type. | 1538 // already be receiving packets with that payload type. |
1563 for (const AudioCodec& codec : codecs) { | 1539 for (const AudioCodec& codec : codecs) { |
1564 AudioCodec old_codec; | 1540 AudioCodec old_codec; |
1565 if (FindCodec(recv_codecs_, codec, &old_codec)) { | 1541 if (FindCodec(recv_codecs_, codec, &old_codec)) { |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1797 return false; | 1773 return false; |
1798 } | 1774 } |
1799 } | 1775 } |
1800 } | 1776 } |
1801 } | 1777 } |
1802 return true; | 1778 return true; |
1803 } | 1779 } |
1804 | 1780 |
1805 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1781 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1806 const std::vector<AudioCodec>& codecs) { | 1782 const std::vector<AudioCodec>& codecs) { |
| 1783 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 1784 |
1807 dtmf_allowed_ = false; | 1785 dtmf_allowed_ = false; |
1808 for (const AudioCodec& codec : codecs) { | 1786 for (const AudioCodec& codec : codecs) { |
1809 // Find the DTMF telephone event "codec". | 1787 // Find the DTMF telephone event "codec". |
1810 if (IsCodec(codec, kDtmfCodecName)) { | 1788 if (IsCodec(codec, kDtmfCodecName)) { |
1811 dtmf_allowed_ = true; | 1789 dtmf_allowed_ = true; |
1812 } | 1790 } |
1813 } | 1791 } |
1814 | 1792 |
1815 // Cache the codecs in order to configure the channel created later. | 1793 // Cache the codecs in order to configure the channel created later. |
1816 send_codecs_ = codecs; | 1794 send_codecs_ = codecs; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1868 | 1846 |
1869 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { | 1847 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { |
1870 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); | 1848 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); |
1871 return false; | 1849 return false; |
1872 } | 1850 } |
1873 return true; | 1851 return true; |
1874 } | 1852 } |
1875 | 1853 |
1876 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( | 1854 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( |
1877 const std::vector<RtpHeaderExtension>& extensions) { | 1855 const std::vector<RtpHeaderExtension>& extensions) { |
| 1856 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1878 if (receive_extensions_ == extensions) { | 1857 if (receive_extensions_ == extensions) { |
1879 return true; | 1858 return true; |
1880 } | 1859 } |
1881 | 1860 |
1882 // The default channel may or may not be in |receive_channels_|. Set the rtp | 1861 // The default channel may or may not be in |receive_channels_|. Set the rtp |
1883 // header extensions for default channel regardless. | 1862 // header extensions for default channel regardless. |
1884 if (!SetChannelRecvRtpHeaderExtensions(voe_channel(), extensions)) { | 1863 if (!SetChannelRecvRtpHeaderExtensions(voe_channel(), extensions)) { |
1885 return false; | 1864 return false; |
1886 } | 1865 } |
1887 | 1866 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1935 &webrtc::VoERTP_RTCP::SetReceiveAbsoluteSenderTimeStatus, channel_id, | 1914 &webrtc::VoERTP_RTCP::SetReceiveAbsoluteSenderTimeStatus, channel_id, |
1936 send_time_extension)) { | 1915 send_time_extension)) { |
1937 return false; | 1916 return false; |
1938 } | 1917 } |
1939 | 1918 |
1940 return true; | 1919 return true; |
1941 } | 1920 } |
1942 | 1921 |
1943 bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( | 1922 bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( |
1944 const std::vector<RtpHeaderExtension>& extensions) { | 1923 const std::vector<RtpHeaderExtension>& extensions) { |
| 1924 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1945 if (send_extensions_ == extensions) { | 1925 if (send_extensions_ == extensions) { |
1946 return true; | 1926 return true; |
1947 } | 1927 } |
1948 | 1928 |
1949 // The default channel may or may not be in |send_channels_|. Set the rtp | 1929 // The default channel may or may not be in |send_channels_|. Set the rtp |
1950 // header extensions for default channel regardless. | 1930 // header extensions for default channel regardless. |
1951 | 1931 |
1952 if (!SetChannelSendRtpHeaderExtensions(voe_channel(), extensions)) { | 1932 if (!SetChannelSendRtpHeaderExtensions(voe_channel(), extensions)) { |
1953 return false; | 1933 return false; |
1954 } | 1934 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 | 1973 |
1994 bool WebRtcVoiceMediaChannel::PausePlayout() { | 1974 bool WebRtcVoiceMediaChannel::PausePlayout() { |
1995 return ChangePlayout(false); | 1975 return ChangePlayout(false); |
1996 } | 1976 } |
1997 | 1977 |
1998 bool WebRtcVoiceMediaChannel::ResumePlayout() { | 1978 bool WebRtcVoiceMediaChannel::ResumePlayout() { |
1999 return ChangePlayout(desired_playout_); | 1979 return ChangePlayout(desired_playout_); |
2000 } | 1980 } |
2001 | 1981 |
2002 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { | 1982 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { |
| 1983 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2003 if (playout_ == playout) { | 1984 if (playout_ == playout) { |
2004 return true; | 1985 return true; |
2005 } | 1986 } |
2006 | 1987 |
2007 // Change the playout of all channels to the new state. | 1988 // Change the playout of all channels to the new state. |
2008 bool result = true; | 1989 bool result = true; |
2009 if (receive_channels_.empty()) { | 1990 if (receive_channels_.empty()) { |
2010 // Only toggle the default channel if we don't have any other channels. | 1991 // Only toggle the default channel if we don't have any other channels. |
2011 result = SetPlayout(voe_channel(), playout); | 1992 result = SetPlayout(voe_channel(), playout); |
2012 } | 1993 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2081 return false; | 2062 return false; |
2082 } | 2063 } |
2083 } | 2064 } |
2084 | 2065 |
2085 return true; | 2066 return true; |
2086 } | 2067 } |
2087 | 2068 |
2088 bool WebRtcVoiceMediaChannel::SetAudioSend(uint32 ssrc, bool enable, | 2069 bool WebRtcVoiceMediaChannel::SetAudioSend(uint32 ssrc, bool enable, |
2089 const AudioOptions* options, | 2070 const AudioOptions* options, |
2090 AudioRenderer* renderer) { | 2071 AudioRenderer* renderer) { |
| 2072 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2091 // TODO(solenberg): The state change should be fully rolled back if any one of | 2073 // TODO(solenberg): The state change should be fully rolled back if any one of |
2092 // these calls fail. | 2074 // these calls fail. |
2093 if (!SetLocalRenderer(ssrc, renderer)) { | 2075 if (!SetLocalRenderer(ssrc, renderer)) { |
2094 return false; | 2076 return false; |
2095 } | 2077 } |
2096 if (!MuteStream(ssrc, !enable)) { | 2078 if (!MuteStream(ssrc, !enable)) { |
2097 return false; | 2079 return false; |
2098 } | 2080 } |
2099 if (enable && options) { | 2081 if (enable && options) { |
2100 return SetOptions(*options); | 2082 return SetOptions(*options); |
(...skipping 25 matching lines...) Expand all Loading... |
2126 | 2108 |
2127 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { | 2109 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { |
2128 LOG_RTCERR1(DeleteChannel, channel); | 2110 LOG_RTCERR1(DeleteChannel, channel); |
2129 return false; | 2111 return false; |
2130 } | 2112 } |
2131 | 2113 |
2132 return true; | 2114 return true; |
2133 } | 2115 } |
2134 | 2116 |
2135 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { | 2117 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { |
| 2118 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2136 // If the default channel is already used for sending create a new channel | 2119 // If the default channel is already used for sending create a new channel |
2137 // otherwise use the default channel for sending. | 2120 // otherwise use the default channel for sending. |
2138 int channel = GetSendChannelNum(sp.first_ssrc()); | 2121 int channel = GetSendChannelId(sp.first_ssrc()); |
2139 if (channel != -1) { | 2122 if (channel != -1) { |
2140 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); | 2123 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); |
2141 return false; | 2124 return false; |
2142 } | 2125 } |
2143 | 2126 |
2144 bool default_channel_is_available = true; | 2127 bool default_channel_is_available = true; |
2145 for (const auto& ch : send_channels_) { | 2128 for (const auto& ch : send_channels_) { |
2146 if (IsDefaultChannel(ch.second->channel())) { | 2129 if (IsDefaultChannel(ch.second->channel())) { |
2147 default_channel_is_available = false; | 2130 default_channel_is_available = false; |
2148 break; | 2131 break; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2236 } | 2219 } |
2237 | 2220 |
2238 if (send_channels_.empty()) | 2221 if (send_channels_.empty()) |
2239 ChangeSend(SEND_NOTHING); | 2222 ChangeSend(SEND_NOTHING); |
2240 | 2223 |
2241 return true; | 2224 return true; |
2242 } | 2225 } |
2243 | 2226 |
2244 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { | 2227 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { |
2245 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2228 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2229 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); |
| 2230 |
2246 rtc::CritScope lock(&receive_channels_cs_); | 2231 rtc::CritScope lock(&receive_channels_cs_); |
2247 | 2232 |
2248 if (!VERIFY(sp.ssrcs.size() == 1)) | 2233 if (!VERIFY(sp.ssrcs.size() == 1)) |
2249 return false; | 2234 return false; |
2250 uint32 ssrc = sp.first_ssrc(); | 2235 uint32 ssrc = sp.first_ssrc(); |
2251 | 2236 |
2252 if (ssrc == 0) { | 2237 if (ssrc == 0) { |
2253 LOG(LS_WARNING) << "AddRecvStream with 0 ssrc is not supported."; | 2238 LOG(LS_WARNING) << "AddRecvStream with 0 ssrc is not supported."; |
2254 return false; | 2239 return false; |
2255 } | 2240 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2294 receive_stream_params_[ssrc] = sp; | 2279 receive_stream_params_[ssrc] = sp; |
2295 AddAudioReceiveStream(ssrc); | 2280 AddAudioReceiveStream(ssrc); |
2296 | 2281 |
2297 LOG(LS_INFO) << "New audio stream " << ssrc | 2282 LOG(LS_INFO) << "New audio stream " << ssrc |
2298 << " registered to VoiceEngine channel #" | 2283 << " registered to VoiceEngine channel #" |
2299 << channel << "."; | 2284 << channel << "."; |
2300 return true; | 2285 return true; |
2301 } | 2286 } |
2302 | 2287 |
2303 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { | 2288 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { |
| 2289 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2304 // Configure to use external transport, like our default channel. | 2290 // Configure to use external transport, like our default channel. |
2305 if (engine()->voe()->network()->RegisterExternalTransport( | 2291 if (engine()->voe()->network()->RegisterExternalTransport( |
2306 channel, *this) == -1) { | 2292 channel, *this) == -1) { |
2307 LOG_RTCERR2(SetExternalTransport, channel, this); | 2293 LOG_RTCERR2(SetExternalTransport, channel, this); |
2308 return false; | 2294 return false; |
2309 } | 2295 } |
2310 | 2296 |
2311 // Use the same SSRC as our default channel (so the RTCP reports are correct). | 2297 // Use the same SSRC as our default channel (so the RTCP reports are correct). |
2312 unsigned int send_ssrc = 0; | 2298 unsigned int send_ssrc = 0; |
2313 webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp(); | 2299 webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2366 // Set RTP header extension for the new channel. | 2352 // Set RTP header extension for the new channel. |
2367 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { | 2353 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { |
2368 return false; | 2354 return false; |
2369 } | 2355 } |
2370 | 2356 |
2371 return SetPlayout(channel, playout_); | 2357 return SetPlayout(channel, playout_); |
2372 } | 2358 } |
2373 | 2359 |
2374 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32 ssrc) { | 2360 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32 ssrc) { |
2375 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2361 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2362 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
| 2363 |
2376 rtc::CritScope lock(&receive_channels_cs_); | 2364 rtc::CritScope lock(&receive_channels_cs_); |
2377 ChannelMap::iterator it = receive_channels_.find(ssrc); | 2365 ChannelMap::iterator it = receive_channels_.find(ssrc); |
2378 if (it == receive_channels_.end()) { | 2366 if (it == receive_channels_.end()) { |
2379 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2367 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2380 << " which doesn't exist."; | 2368 << " which doesn't exist."; |
2381 return false; | 2369 return false; |
2382 } | 2370 } |
2383 | 2371 |
2384 RemoveAudioReceiveStream(ssrc); | 2372 RemoveAudioReceiveStream(ssrc); |
2385 receive_stream_params_.erase(ssrc); | 2373 receive_stream_params_.erase(ssrc); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2424 if (enable_default_channel_playout && playout_) { | 2412 if (enable_default_channel_playout && playout_) { |
2425 LOG(LS_INFO) << "Enabling playback on the default voice channel"; | 2413 LOG(LS_INFO) << "Enabling playback on the default voice channel"; |
2426 SetPlayout(voe_channel(), true); | 2414 SetPlayout(voe_channel(), true); |
2427 } | 2415 } |
2428 | 2416 |
2429 return true; | 2417 return true; |
2430 } | 2418 } |
2431 | 2419 |
2432 bool WebRtcVoiceMediaChannel::SetRemoteRenderer(uint32 ssrc, | 2420 bool WebRtcVoiceMediaChannel::SetRemoteRenderer(uint32 ssrc, |
2433 AudioRenderer* renderer) { | 2421 AudioRenderer* renderer) { |
| 2422 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2434 ChannelMap::iterator it = receive_channels_.find(ssrc); | 2423 ChannelMap::iterator it = receive_channels_.find(ssrc); |
2435 if (it == receive_channels_.end()) { | 2424 if (it == receive_channels_.end()) { |
2436 if (renderer) { | 2425 if (renderer) { |
2437 // Return an error if trying to set a valid renderer with an invalid ssrc. | 2426 // Return an error if trying to set a valid renderer with an invalid ssrc. |
2438 LOG(LS_ERROR) << "SetRemoteRenderer failed with ssrc "<< ssrc; | 2427 LOG(LS_ERROR) << "SetRemoteRenderer failed with ssrc "<< ssrc; |
2439 return false; | 2428 return false; |
2440 } | 2429 } |
2441 | 2430 |
2442 // The channel likely has gone away, do nothing. | 2431 // The channel likely has gone away, do nothing. |
2443 return true; | 2432 return true; |
(...skipping 24 matching lines...) Expand all Loading... |
2468 if (renderer) | 2457 if (renderer) |
2469 it->second->Start(renderer); | 2458 it->second->Start(renderer); |
2470 else | 2459 else |
2471 it->second->Stop(); | 2460 it->second->Stop(); |
2472 | 2461 |
2473 return true; | 2462 return true; |
2474 } | 2463 } |
2475 | 2464 |
2476 bool WebRtcVoiceMediaChannel::GetActiveStreams( | 2465 bool WebRtcVoiceMediaChannel::GetActiveStreams( |
2477 AudioInfo::StreamList* actives) { | 2466 AudioInfo::StreamList* actives) { |
| 2467 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2478 // In conference mode, the default channel should not be in | 2468 // In conference mode, the default channel should not be in |
2479 // |receive_channels_|. | 2469 // |receive_channels_|. |
2480 actives->clear(); | 2470 actives->clear(); |
2481 for (const auto& ch : receive_channels_) { | 2471 for (const auto& ch : receive_channels_) { |
2482 int level = GetOutputLevel(ch.second->channel()); | 2472 int level = GetOutputLevel(ch.second->channel()); |
2483 if (level > 0) { | 2473 if (level > 0) { |
2484 actives->push_back(std::make_pair(ch.first, level)); | 2474 actives->push_back(std::make_pair(ch.first, level)); |
2485 } | 2475 } |
2486 } | 2476 } |
2487 return true; | 2477 return true; |
2488 } | 2478 } |
2489 | 2479 |
2490 int WebRtcVoiceMediaChannel::GetOutputLevel() { | 2480 int WebRtcVoiceMediaChannel::GetOutputLevel() { |
| 2481 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2491 // return the highest output level of all streams | 2482 // return the highest output level of all streams |
2492 int highest = GetOutputLevel(voe_channel()); | 2483 int highest = GetOutputLevel(voe_channel()); |
2493 for (const auto& ch : receive_channels_) { | 2484 for (const auto& ch : receive_channels_) { |
2494 int level = GetOutputLevel(ch.second->channel()); | 2485 int level = GetOutputLevel(ch.second->channel()); |
2495 highest = std::max(level, highest); | 2486 highest = std::max(level, highest); |
2496 } | 2487 } |
2497 return highest; | 2488 return highest; |
2498 } | 2489 } |
2499 | 2490 |
2500 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { | 2491 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { |
(...skipping 16 matching lines...) Expand all Loading... |
2517 reporting_threshold, penalty_decay, type_event_delay) == -1) { | 2508 reporting_threshold, penalty_decay, type_event_delay) == -1) { |
2518 // In case of error, log the info and continue | 2509 // In case of error, log the info and continue |
2519 LOG_RTCERR5(SetTypingDetectionParameters, time_window, | 2510 LOG_RTCERR5(SetTypingDetectionParameters, time_window, |
2520 cost_per_typing, reporting_threshold, penalty_decay, | 2511 cost_per_typing, reporting_threshold, penalty_decay, |
2521 type_event_delay); | 2512 type_event_delay); |
2522 } | 2513 } |
2523 } | 2514 } |
2524 | 2515 |
2525 bool WebRtcVoiceMediaChannel::SetOutputScaling( | 2516 bool WebRtcVoiceMediaChannel::SetOutputScaling( |
2526 uint32 ssrc, double left, double right) { | 2517 uint32 ssrc, double left, double right) { |
| 2518 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2527 rtc::CritScope lock(&receive_channels_cs_); | 2519 rtc::CritScope lock(&receive_channels_cs_); |
2528 // Collect the channels to scale the output volume. | 2520 // Collect the channels to scale the output volume. |
2529 std::vector<int> channels; | 2521 std::vector<int> channels; |
2530 if (0 == ssrc) { // Collect all channels, including the default one. | 2522 if (0 == ssrc) { // Collect all channels, including the default one. |
2531 // Default channel is not in receive_channels_ if it is not being used for | 2523 // Default channel is not in receive_channels_ if it is not being used for |
2532 // playout. | 2524 // playout. |
2533 if (default_receive_ssrc_ == 0) | 2525 if (default_receive_ssrc_ == 0) |
2534 channels.push_back(voe_channel()); | 2526 channels.push_back(voe_channel()); |
2535 for (const auto& ch : receive_channels_) { | 2527 for (const auto& ch : receive_channels_) { |
2536 channels.push_back(ch.second->channel()); | 2528 channels.push_back(ch.second->channel()); |
2537 } | 2529 } |
2538 } else { // Collect only the channel of the specified ssrc. | 2530 } else { // Collect only the channel of the specified ssrc. |
2539 int channel = GetReceiveChannelNum(ssrc); | 2531 int channel = GetReceiveChannelId(ssrc); |
2540 if (-1 == channel) { | 2532 if (-1 == channel) { |
2541 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; | 2533 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; |
2542 return false; | 2534 return false; |
2543 } | 2535 } |
2544 channels.push_back(channel); | 2536 channels.push_back(channel); |
2545 } | 2537 } |
2546 | 2538 |
2547 // Scale the output volume for the collected channels. We first normalize to | 2539 // Scale the output volume for the collected channels. We first normalize to |
2548 // scale the volume and then set the left and right pan. | 2540 // scale the volume and then set the left and right pan. |
2549 float scale = static_cast<float>(std::max(left, right)); | 2541 float scale = static_cast<float>(std::max(left, right)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2590 default_channel_is_inuse = true; | 2582 default_channel_is_inuse = true; |
2591 break; | 2583 break; |
2592 } | 2584 } |
2593 } | 2585 } |
2594 if (default_channel_is_inuse) { | 2586 if (default_channel_is_inuse) { |
2595 channel = voe_channel(); | 2587 channel = voe_channel(); |
2596 } else if (!send_channels_.empty()) { | 2588 } else if (!send_channels_.empty()) { |
2597 channel = send_channels_.begin()->second->channel(); | 2589 channel = send_channels_.begin()->second->channel(); |
2598 } | 2590 } |
2599 } else { | 2591 } else { |
2600 channel = GetSendChannelNum(ssrc); | 2592 channel = GetSendChannelId(ssrc); |
2601 } | 2593 } |
2602 if (channel == -1) { | 2594 if (channel == -1) { |
2603 LOG(LS_WARNING) << "InsertDtmf - The specified ssrc " | 2595 LOG(LS_WARNING) << "InsertDtmf - The specified ssrc " |
2604 << ssrc << " is not in use."; | 2596 << ssrc << " is not in use."; |
2605 return false; | 2597 return false; |
2606 } | 2598 } |
2607 // Send DTMF using out-of-band DTMF. ("true", as 3rd arg) | 2599 // Send DTMF using out-of-band DTMF. ("true", as 3rd arg) |
2608 if (engine()->voe()->dtmf()->SendTelephoneEvent( | 2600 if (engine()->voe()->dtmf()->SendTelephoneEvent( |
2609 channel, event, true, duration) == -1) { | 2601 channel, event, true, duration) == -1) { |
2610 LOG_RTCERR4(SendTelephoneEvent, channel, event, true, duration); | 2602 LOG_RTCERR4(SendTelephoneEvent, channel, event, true, duration); |
(...skipping 21 matching lines...) Expand all Loading... |
2632 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, | 2624 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, |
2633 packet_time.not_before); | 2625 packet_time.not_before); |
2634 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2626 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
2635 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), | 2627 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), |
2636 webrtc_packet_time); | 2628 webrtc_packet_time); |
2637 | 2629 |
2638 // Pick which channel to send this packet to. If this packet doesn't match | 2630 // Pick which channel to send this packet to. If this packet doesn't match |
2639 // any multiplexed streams, just send it to the default channel. Otherwise, | 2631 // any multiplexed streams, just send it to the default channel. Otherwise, |
2640 // send it to the specific decoder instance for that stream. | 2632 // send it to the specific decoder instance for that stream. |
2641 int which_channel = | 2633 int which_channel = |
2642 GetReceiveChannelNum(ParseSsrc(packet->data(), packet->size(), false)); | 2634 GetReceiveChannelId(ParseSsrc(packet->data(), packet->size(), false)); |
2643 if (which_channel == -1) { | 2635 if (which_channel == -1) { |
2644 which_channel = voe_channel(); | 2636 which_channel = voe_channel(); |
2645 } | 2637 } |
2646 | 2638 |
2647 // Pass it off to the decoder. | 2639 // Pass it off to the decoder. |
2648 engine()->voe()->network()->ReceivedRTPPacket( | 2640 engine()->voe()->network()->ReceivedRTPPacket( |
2649 which_channel, packet->data(), packet->size(), | 2641 which_channel, packet->data(), packet->size(), |
2650 webrtc::PacketTime(packet_time.timestamp, packet_time.not_before)); | 2642 webrtc::PacketTime(packet_time.timestamp, packet_time.not_before)); |
2651 } | 2643 } |
2652 | 2644 |
(...skipping 15 matching lines...) Expand all Loading... |
2668 int type = 0; | 2660 int type = 0; |
2669 if (!GetRtcpType(packet->data(), packet->size(), &type)) { | 2661 if (!GetRtcpType(packet->data(), packet->size(), &type)) { |
2670 LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; | 2662 LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; |
2671 return; | 2663 return; |
2672 } | 2664 } |
2673 | 2665 |
2674 // If it is a sender report, find the channel that is listening. | 2666 // If it is a sender report, find the channel that is listening. |
2675 bool has_sent_to_default_channel = false; | 2667 bool has_sent_to_default_channel = false; |
2676 if (type == kRtcpTypeSR) { | 2668 if (type == kRtcpTypeSR) { |
2677 int which_channel = | 2669 int which_channel = |
2678 GetReceiveChannelNum(ParseSsrc(packet->data(), packet->size(), true)); | 2670 GetReceiveChannelId(ParseSsrc(packet->data(), packet->size(), true)); |
2679 if (which_channel != -1) { | 2671 if (which_channel != -1) { |
2680 engine()->voe()->network()->ReceivedRTCPPacket( | 2672 engine()->voe()->network()->ReceivedRTCPPacket( |
2681 which_channel, packet->data(), packet->size()); | 2673 which_channel, packet->data(), packet->size()); |
2682 | 2674 |
2683 if (IsDefaultChannel(which_channel)) | 2675 if (IsDefaultChannel(which_channel)) |
2684 has_sent_to_default_channel = true; | 2676 has_sent_to_default_channel = true; |
2685 } | 2677 } |
2686 } | 2678 } |
2687 | 2679 |
2688 // SR may continue RR and any RR entry may correspond to any one of the send | 2680 // SR may continue RR and any RR entry may correspond to any one of the send |
2689 // channels. So all RTCP packets must be forwarded all send channels. VoE | 2681 // channels. So all RTCP packets must be forwarded all send channels. VoE |
2690 // will filter out RR internally. | 2682 // will filter out RR internally. |
2691 for (const auto& ch : send_channels_) { | 2683 for (const auto& ch : send_channels_) { |
2692 // Make sure not sending the same packet to default channel more than once. | 2684 // Make sure not sending the same packet to default channel more than once. |
2693 if (IsDefaultChannel(ch.second->channel()) && | 2685 if (IsDefaultChannel(ch.second->channel()) && |
2694 has_sent_to_default_channel) | 2686 has_sent_to_default_channel) |
2695 continue; | 2687 continue; |
2696 | 2688 |
2697 engine()->voe()->network()->ReceivedRTCPPacket( | 2689 engine()->voe()->network()->ReceivedRTCPPacket( |
2698 ch.second->channel(), packet->data(), packet->size()); | 2690 ch.second->channel(), packet->data(), packet->size()); |
2699 } | 2691 } |
2700 } | 2692 } |
2701 | 2693 |
2702 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { | 2694 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { |
2703 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc); | 2695 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelId(ssrc); |
2704 if (channel == -1) { | 2696 if (channel == -1) { |
2705 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; | 2697 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; |
2706 return false; | 2698 return false; |
2707 } | 2699 } |
2708 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { | 2700 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { |
2709 LOG_RTCERR2(SetInputMute, channel, muted); | 2701 LOG_RTCERR2(SetInputMute, channel, muted); |
2710 return false; | 2702 return false; |
2711 } | 2703 } |
2712 // We set the AGC to mute state only when all the channels are muted. | 2704 // We set the AGC to mute state only when all the channels are muted. |
2713 // This implementation is not ideal, instead we should signal the AGC when | 2705 // This implementation is not ideal, instead we should signal the AGC when |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2777 LOG(LS_INFO) << "Failed to set codec " << codec.plname | 2769 LOG(LS_INFO) << "Failed to set codec " << codec.plname |
2778 << " to bitrate " << bps << " bps" | 2770 << " to bitrate " << bps << " bps" |
2779 << ", requires at least " << codec.rate << " bps."; | 2771 << ", requires at least " << codec.rate << " bps."; |
2780 return false; | 2772 return false; |
2781 } | 2773 } |
2782 return true; | 2774 return true; |
2783 } | 2775 } |
2784 } | 2776 } |
2785 | 2777 |
2786 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { | 2778 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { |
| 2779 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 2780 |
2787 bool echo_metrics_on = false; | 2781 bool echo_metrics_on = false; |
2788 // These can take on valid negative values, so use the lowest possible level | 2782 // These can take on valid negative values, so use the lowest possible level |
2789 // as default rather than -1. | 2783 // as default rather than -1. |
2790 int echo_return_loss = -100; | 2784 int echo_return_loss = -100; |
2791 int echo_return_loss_enhancement = -100; | 2785 int echo_return_loss_enhancement = -100; |
2792 // These can also be negative, but in practice -1 is only used to signal | 2786 // These can also be negative, but in practice -1 is only used to signal |
2793 // insufficient data, since the resolution is limited to multiples of 4 ms. | 2787 // insufficient data, since the resolution is limited to multiples of 4 ms. |
2794 int echo_delay_median_ms = -1; | 2788 int echo_delay_median_ms = -1; |
2795 int echo_delay_std_ms = -1; | 2789 int echo_delay_std_ms = -1; |
2796 if (engine()->voe()->processing()->GetEcMetricsStatus( | 2790 if (engine()->voe()->processing()->GetEcMetricsStatus( |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2963 // Get speech level. | 2957 // Get speech level. |
2964 rinfo.audio_level = (engine()->voe()->volume()-> | 2958 rinfo.audio_level = (engine()->voe()->volume()-> |
2965 GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1; | 2959 GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1; |
2966 info->receivers.push_back(rinfo); | 2960 info->receivers.push_back(rinfo); |
2967 } | 2961 } |
2968 } | 2962 } |
2969 | 2963 |
2970 return true; | 2964 return true; |
2971 } | 2965 } |
2972 | 2966 |
2973 bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) { | 2967 void WebRtcVoiceMediaChannel::OnError(int error) { |
2974 rtc::CritScope lock(&receive_channels_cs_); | 2968 if (send_ == SEND_NOTHING) { |
2975 RTC_DCHECK(ssrc != NULL); | 2969 return; |
2976 if (channel_num == -1 && send_ != SEND_NOTHING) { | |
2977 // Sometimes the VoiceEngine core will throw error with channel_num = -1. | |
2978 // This means the error is not limited to a specific channel. Signal the | |
2979 // message using ssrc=0. If the current channel is sending, use this | |
2980 // channel for sending the message. | |
2981 *ssrc = 0; | |
2982 return true; | |
2983 } else { | |
2984 // Check whether this is a sending channel. | |
2985 for (const auto& ch : send_channels_) { | |
2986 if (ch.second->channel() == channel_num) { | |
2987 // This is a sending channel. | |
2988 uint32 local_ssrc = 0; | |
2989 if (engine()->voe()->rtp()->GetLocalSSRC( | |
2990 channel_num, local_ssrc) != -1) { | |
2991 *ssrc = local_ssrc; | |
2992 } | |
2993 return true; | |
2994 } | |
2995 } | |
2996 | |
2997 // Check whether this is a receiving channel. | |
2998 for (const auto& ch : receive_channels_) { | |
2999 if (ch.second->channel() == channel_num) { | |
3000 *ssrc = ch.first; | |
3001 return true; | |
3002 } | |
3003 } | |
3004 } | 2970 } |
3005 return false; | |
3006 } | |
3007 | |
3008 void WebRtcVoiceMediaChannel::OnError(uint32 ssrc, int error) { | |
3009 if (error == VE_TYPING_NOISE_WARNING) { | 2971 if (error == VE_TYPING_NOISE_WARNING) { |
3010 typing_noise_detected_ = true; | 2972 typing_noise_detected_ = true; |
3011 } else if (error == VE_TYPING_NOISE_OFF_WARNING) { | 2973 } else if (error == VE_TYPING_NOISE_OFF_WARNING) { |
3012 typing_noise_detected_ = false; | 2974 typing_noise_detected_ = false; |
3013 } | 2975 } |
3014 } | 2976 } |
3015 | 2977 |
3016 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2978 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
3017 unsigned int ulevel; | 2979 unsigned int ulevel = 0; |
3018 int ret = | 2980 int ret = engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
3019 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | |
3020 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 2981 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
3021 } | 2982 } |
3022 | 2983 |
3023 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const { | 2984 int WebRtcVoiceMediaChannel::GetReceiveChannelId(uint32 ssrc) const { |
| 2985 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
3024 ChannelMap::const_iterator it = receive_channels_.find(ssrc); | 2986 ChannelMap::const_iterator it = receive_channels_.find(ssrc); |
3025 if (it != receive_channels_.end()) | 2987 if (it != receive_channels_.end()) |
3026 return it->second->channel(); | 2988 return it->second->channel(); |
3027 return (ssrc == default_receive_ssrc_) ? voe_channel() : -1; | 2989 return (ssrc == default_receive_ssrc_) ? voe_channel() : -1; |
3028 } | 2990 } |
3029 | 2991 |
3030 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const { | 2992 int WebRtcVoiceMediaChannel::GetSendChannelId(uint32 ssrc) const { |
| 2993 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
3031 ChannelMap::const_iterator it = send_channels_.find(ssrc); | 2994 ChannelMap::const_iterator it = send_channels_.find(ssrc); |
3032 if (it != send_channels_.end()) | 2995 if (it != send_channels_.end()) |
3033 return it->second->channel(); | 2996 return it->second->channel(); |
3034 | 2997 |
3035 return -1; | 2998 return -1; |
3036 } | 2999 } |
3037 | 3000 |
3038 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, | 3001 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, |
3039 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { | 3002 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { |
3040 // Get the RED encodings from the parameter with no name. This may | 3003 // Get the RED encodings from the parameter with no name. This may |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3212 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 3175 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
3213 auto stream_it = receive_streams_.find(ssrc); | 3176 auto stream_it = receive_streams_.find(ssrc); |
3214 if (stream_it != receive_streams_.end()) { | 3177 if (stream_it != receive_streams_.end()) { |
3215 call_->DestroyAudioReceiveStream(stream_it->second); | 3178 call_->DestroyAudioReceiveStream(stream_it->second); |
3216 receive_streams_.erase(stream_it); | 3179 receive_streams_.erase(stream_it); |
3217 } | 3180 } |
3218 } | 3181 } |
3219 | 3182 |
3220 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( | 3183 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( |
3221 const std::vector<AudioCodec>& new_codecs) { | 3184 const std::vector<AudioCodec>& new_codecs) { |
| 3185 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
3222 for (const AudioCodec& codec : new_codecs) { | 3186 for (const AudioCodec& codec : new_codecs) { |
3223 webrtc::CodecInst voe_codec; | 3187 webrtc::CodecInst voe_codec; |
3224 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { | 3188 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { |
3225 LOG(LS_INFO) << ToString(codec); | 3189 LOG(LS_INFO) << ToString(codec); |
3226 voe_codec.pltype = codec.id; | 3190 voe_codec.pltype = codec.id; |
3227 if (default_receive_ssrc_ == 0) { | 3191 if (default_receive_ssrc_ == 0) { |
3228 // Set the receive codecs on the default channel explicitly if the | 3192 // Set the receive codecs on the default channel explicitly if the |
3229 // default channel is not used by |receive_channels_|, this happens in | 3193 // default channel is not used by |receive_channels_|, this happens in |
3230 // conference mode or in non-conference mode when there is no playout | 3194 // conference mode or in non-conference mode when there is no playout |
3231 // channel. | 3195 // channel. |
(...skipping 19 matching lines...) Expand all Loading... |
3251 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 3215 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
3252 return false; | 3216 return false; |
3253 } | 3217 } |
3254 } | 3218 } |
3255 return true; | 3219 return true; |
3256 } | 3220 } |
3257 | 3221 |
3258 } // namespace cricket | 3222 } // namespace cricket |
3259 | 3223 |
3260 #endif // HAVE_WEBRTC_VOICE | 3224 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |