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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified | 140 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified |
141 // below. | 141 // below. |
142 #if defined(CHROMEOS) | 142 #if defined(CHROMEOS) |
143 static const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; | 143 static const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; |
144 #elif defined(ANDROID) | 144 #elif defined(ANDROID) |
145 static const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; | 145 static const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; |
146 #else | 146 #else |
147 static const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; | 147 static const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; |
148 #endif | 148 #endif |
149 | 149 |
150 namespace { | |
151 | |
152 bool ValidateStreamParams(const StreamParams& sp) { | |
pthatcher1
2015/10/02 02:33:30
static?
the sun
2015/10/02 11:34:19
Nope, it's in an anonymous namespace.
http://goog
| |
153 if (sp.ssrcs.empty()) { | |
154 LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); | |
155 return false; | |
156 } | |
157 if (sp.ssrcs.size() > 1) { | |
158 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); | |
159 return false; | |
160 } | |
161 return true; | |
162 } | |
163 | |
150 // Dumps an AudioCodec in RFC 2327-ish format. | 164 // Dumps an AudioCodec in RFC 2327-ish format. |
151 static std::string ToString(const AudioCodec& codec) { | 165 std::string ToString(const AudioCodec& codec) { |
152 std::stringstream ss; | 166 std::stringstream ss; |
153 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels | 167 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels |
154 << " (" << codec.id << ")"; | 168 << " (" << codec.id << ")"; |
155 return ss.str(); | 169 return ss.str(); |
156 } | 170 } |
157 | 171 |
158 static std::string ToString(const webrtc::CodecInst& codec) { | 172 std::string ToString(const webrtc::CodecInst& codec) { |
159 std::stringstream ss; | 173 std::stringstream ss; |
160 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels | 174 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels |
161 << " (" << codec.pltype << ")"; | 175 << " (" << codec.pltype << ")"; |
162 return ss.str(); | 176 return ss.str(); |
163 } | 177 } |
164 | 178 |
165 static void LogMultiline(rtc::LoggingSeverity sev, char* text) { | 179 void LogMultiline(rtc::LoggingSeverity sev, char* text) { |
166 const char* delim = "\r\n"; | 180 const char* delim = "\r\n"; |
167 for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) { | 181 for (char* tok = strtok(text, delim); tok; tok = strtok(NULL, delim)) { |
168 LOG_V(sev) << tok; | 182 LOG_V(sev) << tok; |
169 } | 183 } |
170 } | 184 } |
171 | 185 |
172 // Severity is an integer because it comes is assumed to be from command line. | 186 // Severity is an integer because it comes is assumed to be from command line. |
173 static int SeverityToFilter(int severity) { | 187 int SeverityToFilter(int severity) { |
174 int filter = webrtc::kTraceNone; | 188 int filter = webrtc::kTraceNone; |
175 switch (severity) { | 189 switch (severity) { |
176 case rtc::LS_VERBOSE: | 190 case rtc::LS_VERBOSE: |
177 filter |= webrtc::kTraceAll; | 191 filter |= webrtc::kTraceAll; |
178 FALLTHROUGH(); | 192 FALLTHROUGH(); |
179 case rtc::LS_INFO: | 193 case rtc::LS_INFO: |
180 filter |= (webrtc::kTraceStateInfo | webrtc::kTraceInfo); | 194 filter |= (webrtc::kTraceStateInfo | webrtc::kTraceInfo); |
181 FALLTHROUGH(); | 195 FALLTHROUGH(); |
182 case rtc::LS_WARNING: | 196 case rtc::LS_WARNING: |
183 filter |= (webrtc::kTraceTerseInfo | webrtc::kTraceWarning); | 197 filter |= (webrtc::kTraceTerseInfo | webrtc::kTraceWarning); |
184 FALLTHROUGH(); | 198 FALLTHROUGH(); |
185 case rtc::LS_ERROR: | 199 case rtc::LS_ERROR: |
186 filter |= (webrtc::kTraceError | webrtc::kTraceCritical); | 200 filter |= (webrtc::kTraceError | webrtc::kTraceCritical); |
187 } | 201 } |
188 return filter; | 202 return filter; |
189 } | 203 } |
190 | 204 |
191 static bool IsCodec(const AudioCodec& codec, const char* ref_name) { | 205 bool IsCodec(const AudioCodec& codec, const char* ref_name) { |
192 return (_stricmp(codec.name.c_str(), ref_name) == 0); | 206 return (_stricmp(codec.name.c_str(), ref_name) == 0); |
193 } | 207 } |
194 | 208 |
195 static bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) { | 209 bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) { |
196 return (_stricmp(codec.plname, ref_name) == 0); | 210 return (_stricmp(codec.plname, ref_name) == 0); |
197 } | 211 } |
198 | 212 |
199 static bool IsCodecMultiRate(const webrtc::CodecInst& codec) { | 213 bool IsCodecMultiRate(const webrtc::CodecInst& codec) { |
200 for (size_t i = 0; i < ARRAY_SIZE(kCodecPrefs); ++i) { | 214 for (size_t i = 0; i < ARRAY_SIZE(kCodecPrefs); ++i) { |
201 if (IsCodec(codec, kCodecPrefs[i].name) && | 215 if (IsCodec(codec, kCodecPrefs[i].name) && |
202 kCodecPrefs[i].clockrate == codec.plfreq) { | 216 kCodecPrefs[i].clockrate == codec.plfreq) { |
203 return kCodecPrefs[i].is_multi_rate; | 217 return kCodecPrefs[i].is_multi_rate; |
204 } | 218 } |
205 } | 219 } |
206 return false; | 220 return false; |
207 } | 221 } |
208 | 222 |
209 static bool FindCodec(const std::vector<AudioCodec>& codecs, | 223 bool FindCodec(const std::vector<AudioCodec>& codecs, |
210 const AudioCodec& codec, | 224 const AudioCodec& codec, |
211 AudioCodec* found_codec) { | 225 AudioCodec* found_codec) { |
212 for (const AudioCodec& c : codecs) { | 226 for (const AudioCodec& c : codecs) { |
213 if (c.Matches(codec)) { | 227 if (c.Matches(codec)) { |
214 if (found_codec != NULL) { | 228 if (found_codec != NULL) { |
215 *found_codec = c; | 229 *found_codec = c; |
216 } | 230 } |
217 return true; | 231 return true; |
218 } | 232 } |
219 } | 233 } |
220 return false; | 234 return false; |
221 } | 235 } |
222 | 236 |
223 static bool IsNackEnabled(const AudioCodec& codec) { | 237 bool IsNackEnabled(const AudioCodec& codec) { |
224 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, | 238 return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack, |
225 kParamValueEmpty)); | 239 kParamValueEmpty)); |
226 } | 240 } |
227 | 241 |
228 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { | 242 int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { |
229 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; | 243 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; |
230 for (int packet_size_ms : codec_pref.packet_sizes_ms) { | 244 for (int packet_size_ms : codec_pref.packet_sizes_ms) { |
231 if (packet_size_ms && packet_size_ms <= ptime_ms) { | 245 if (packet_size_ms && packet_size_ms <= ptime_ms) { |
232 selected_packet_size_ms = packet_size_ms; | 246 selected_packet_size_ms = packet_size_ms; |
233 } | 247 } |
234 } | 248 } |
235 return selected_packet_size_ms; | 249 return selected_packet_size_ms; |
236 } | 250 } |
237 | 251 |
238 // If the AudioCodec param kCodecParamPTime is set, then we will set it to codec | 252 // 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. | 253 // 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. | 254 // TODO(Brave): Query supported packet sizes from ACM when the API is ready. |
241 static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) { | 255 bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) { |
242 for (const CodecPref& codec_pref : kCodecPrefs) { | 256 for (const CodecPref& codec_pref : kCodecPrefs) { |
243 if ((IsCodec(*codec, codec_pref.name) && | 257 if ((IsCodec(*codec, codec_pref.name) && |
244 codec_pref.clockrate == codec->plfreq) || | 258 codec_pref.clockrate == codec->plfreq) || |
245 IsCodec(*codec, kG722CodecName)) { | 259 IsCodec(*codec, kG722CodecName)) { |
246 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms); | 260 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms); |
247 if (packet_size_ms) { | 261 if (packet_size_ms) { |
248 // Convert unit from milli-seconds to samples. | 262 // Convert unit from milli-seconds to samples. |
249 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms; | 263 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms; |
250 return true; | 264 return true; |
251 } | 265 } |
252 } | 266 } |
253 } | 267 } |
254 return false; | 268 return false; |
255 } | 269 } |
256 | 270 |
257 // Return true if codec.params[feature] == "1", false otherwise. | 271 // Return true if codec.params[feature] == "1", false otherwise. |
258 static bool IsCodecFeatureEnabled(const AudioCodec& codec, | 272 bool IsCodecFeatureEnabled(const AudioCodec& codec, |
259 const char* feature) { | 273 const char* feature) { |
260 int value; | 274 int value; |
261 return codec.GetParam(feature, &value) && value == 1; | 275 return codec.GetParam(feature, &value) && value == 1; |
262 } | 276 } |
263 | 277 |
264 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate | 278 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate |
265 // otherwise. If the value (either from params or codec.bitrate) <=0, use the | 279 // 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, | 280 // default configuration. If the value is beyond feasible bit rate of Opus, |
267 // clamp it. Returns the Opus bit rate for operation. | 281 // clamp it. Returns the Opus bit rate for operation. |
268 static int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { | 282 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { |
269 int bitrate = 0; | 283 int bitrate = 0; |
270 bool use_param = true; | 284 bool use_param = true; |
271 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) { | 285 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) { |
272 bitrate = codec.bitrate; | 286 bitrate = codec.bitrate; |
273 use_param = false; | 287 use_param = false; |
274 } | 288 } |
275 if (bitrate <= 0) { | 289 if (bitrate <= 0) { |
276 if (max_playback_rate <= 8000) { | 290 if (max_playback_rate <= 8000) { |
277 bitrate = kOpusBitrateNb; | 291 bitrate = kOpusBitrateNb; |
278 } else if (max_playback_rate <= 16000) { | 292 } else if (max_playback_rate <= 16000) { |
(...skipping 12 matching lines...) Expand all Loading... | |
291 "Supplied Opus bitrate"; | 305 "Supplied Opus bitrate"; |
292 LOG(LS_WARNING) << rate_source | 306 LOG(LS_WARNING) << rate_source |
293 << " is invalid and is replaced by: " | 307 << " is invalid and is replaced by: " |
294 << bitrate; | 308 << bitrate; |
295 } | 309 } |
296 return bitrate; | 310 return bitrate; |
297 } | 311 } |
298 | 312 |
299 // Returns kOpusDefaultPlaybackRate if params[kCodecParamMaxPlaybackRate] is not | 313 // Returns kOpusDefaultPlaybackRate if params[kCodecParamMaxPlaybackRate] is not |
300 // defined. Returns the value of params[kCodecParamMaxPlaybackRate] otherwise. | 314 // defined. Returns the value of params[kCodecParamMaxPlaybackRate] otherwise. |
301 static int GetOpusMaxPlaybackRate(const AudioCodec& codec) { | 315 int GetOpusMaxPlaybackRate(const AudioCodec& codec) { |
302 int value; | 316 int value; |
303 if (codec.GetParam(kCodecParamMaxPlaybackRate, &value)) { | 317 if (codec.GetParam(kCodecParamMaxPlaybackRate, &value)) { |
304 return value; | 318 return value; |
305 } | 319 } |
306 return kOpusDefaultMaxPlaybackRate; | 320 return kOpusDefaultMaxPlaybackRate; |
307 } | 321 } |
308 | 322 |
309 static void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, | 323 void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec, |
310 bool* enable_codec_fec, int* max_playback_rate, | 324 bool* enable_codec_fec, int* max_playback_rate, |
311 bool* enable_codec_dtx) { | 325 bool* enable_codec_dtx) { |
312 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec); | 326 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec); |
313 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx); | 327 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx); |
314 *max_playback_rate = GetOpusMaxPlaybackRate(codec); | 328 *max_playback_rate = GetOpusMaxPlaybackRate(codec); |
315 | 329 |
316 // If OPUS, change what we send according to the "stereo" codec | 330 // If OPUS, change what we send according to the "stereo" codec |
317 // parameter, and not the "channels" parameter. We set | 331 // parameter, and not the "channels" parameter. We set |
318 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If | 332 // 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 | 333 // the bitrate is not specified, i.e. is <= zero, we set it to the |
320 // appropriate default value for mono or stereo Opus. | 334 // appropriate default value for mono or stereo Opus. |
321 | 335 |
322 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; | 336 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; |
323 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); | 337 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); |
324 } | 338 } |
325 | 339 |
326 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC | 340 // 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 | 341 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz |
328 // codec. | 342 // codec. |
329 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { | 343 void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { |
330 if (IsCodec(*voe_codec, kG722CodecName)) { | 344 if (IsCodec(*voe_codec, kG722CodecName)) { |
331 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine | 345 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine |
332 // has changed, and this special case is no longer needed. | 346 // has changed, and this special case is no longer needed. |
333 RTC_DCHECK(voe_codec->plfreq != new_plfreq); | 347 RTC_DCHECK(voe_codec->plfreq != new_plfreq); |
334 voe_codec->plfreq = new_plfreq; | 348 voe_codec->plfreq = new_plfreq; |
335 } | 349 } |
336 } | 350 } |
337 | 351 |
338 // Gets the default set of options applied to the engine. Historically, these | 352 // 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, | 353 // were supplied as a combination of flags from the channel manager (ec, agc, |
340 // ns, and highpass) and the rest hardcoded in InitInternal. | 354 // ns, and highpass) and the rest hardcoded in InitInternal. |
341 static AudioOptions GetDefaultEngineOptions() { | 355 AudioOptions GetDefaultEngineOptions() { |
342 AudioOptions options; | 356 AudioOptions options; |
343 options.echo_cancellation.Set(true); | 357 options.echo_cancellation.Set(true); |
344 options.auto_gain_control.Set(true); | 358 options.auto_gain_control.Set(true); |
345 options.noise_suppression.Set(true); | 359 options.noise_suppression.Set(true); |
346 options.highpass_filter.Set(true); | 360 options.highpass_filter.Set(true); |
347 options.stereo_swapping.Set(false); | 361 options.stereo_swapping.Set(false); |
348 options.audio_jitter_buffer_max_packets.Set(50); | 362 options.audio_jitter_buffer_max_packets.Set(50); |
349 options.audio_jitter_buffer_fast_accelerate.Set(false); | 363 options.audio_jitter_buffer_fast_accelerate.Set(false); |
350 options.typing_detection.Set(true); | 364 options.typing_detection.Set(true); |
351 options.conference_mode.Set(false); | |
352 options.adjust_agc_delta.Set(0); | 365 options.adjust_agc_delta.Set(0); |
353 options.experimental_agc.Set(false); | 366 options.experimental_agc.Set(false); |
354 options.extended_filter_aec.Set(false); | 367 options.extended_filter_aec.Set(false); |
355 options.delay_agnostic_aec.Set(false); | 368 options.delay_agnostic_aec.Set(false); |
356 options.experimental_ns.Set(false); | 369 options.experimental_ns.Set(false); |
357 options.aec_dump.Set(false); | 370 options.aec_dump.Set(false); |
358 return options; | 371 return options; |
359 } | 372 } |
360 | 373 |
361 static std::string GetEnableString(bool enable) { | 374 std::string GetEnableString(bool enable) { |
362 return enable ? "enable" : "disable"; | 375 return enable ? "enable" : "disable"; |
363 } | 376 } |
377 } // namespace { | |
364 | 378 |
365 WebRtcVoiceEngine::WebRtcVoiceEngine() | 379 WebRtcVoiceEngine::WebRtcVoiceEngine() |
366 : voe_wrapper_(new VoEWrapper()), | 380 : voe_wrapper_(new VoEWrapper()), |
367 tracing_(new VoETraceWrapper()), | 381 tracing_(new VoETraceWrapper()), |
368 adm_(NULL), | 382 adm_(NULL), |
369 log_filter_(SeverityToFilter(kDefaultLogSeverity)), | 383 log_filter_(SeverityToFilter(kDefaultLogSeverity)), |
370 is_dumping_aec_(false) { | 384 is_dumping_aec_(false) { |
371 Construct(); | 385 Construct(); |
372 } | 386 } |
373 | 387 |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
855 if (options.playout_sample_rate.Get(&playout_sample_rate)) { | 869 if (options.playout_sample_rate.Get(&playout_sample_rate)) { |
856 LOG(LS_INFO) << "Playout sample rate is " << playout_sample_rate; | 870 LOG(LS_INFO) << "Playout sample rate is " << playout_sample_rate; |
857 if (voe_wrapper_->hw()->SetPlayoutSampleRate(playout_sample_rate)) { | 871 if (voe_wrapper_->hw()->SetPlayoutSampleRate(playout_sample_rate)) { |
858 LOG_RTCERR1(SetPlayoutSampleRate, playout_sample_rate); | 872 LOG_RTCERR1(SetPlayoutSampleRate, playout_sample_rate); |
859 } | 873 } |
860 } | 874 } |
861 | 875 |
862 return true; | 876 return true; |
863 } | 877 } |
864 | 878 |
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 | 879 // 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. | 880 // soundclip device. At that time, reinstate the soundclip pause/resume code. |
879 bool WebRtcVoiceEngine::SetDevices(const Device* in_device, | 881 bool WebRtcVoiceEngine::SetDevices(const Device* in_device, |
880 const Device* out_device) { | 882 const Device* out_device) { |
881 #if !defined(IOS) | 883 #if !defined(IOS) |
882 int in_id = in_device ? rtc::FromString<int>(in_device->id) : | 884 int in_id = in_device ? rtc::FromString<int>(in_device->id) : |
883 kDefaultAudioDeviceId; | 885 kDefaultAudioDeviceId; |
884 int out_id = out_device ? rtc::FromString<int>(out_device->id) : | 886 int out_id = out_device ? rtc::FromString<int>(out_device->id) : |
885 kDefaultAudioDeviceId; | 887 kDefaultAudioDeviceId; |
886 // The device manager uses -1 as the default device, which was the case for | 888 // The device manager uses -1 as the default device, which was the case for |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1408 send_bitrate_bps_(0), | 1410 send_bitrate_bps_(0), |
1409 options_(), | 1411 options_(), |
1410 dtmf_allowed_(false), | 1412 dtmf_allowed_(false), |
1411 desired_playout_(false), | 1413 desired_playout_(false), |
1412 nack_enabled_(false), | 1414 nack_enabled_(false), |
1413 playout_(false), | 1415 playout_(false), |
1414 typing_noise_detected_(false), | 1416 typing_noise_detected_(false), |
1415 desired_send_(SEND_NOTHING), | 1417 desired_send_(SEND_NOTHING), |
1416 send_(SEND_NOTHING), | 1418 send_(SEND_NOTHING), |
1417 call_(call), | 1419 call_(call), |
1418 default_receive_ssrc_(0) { | 1420 default_recv_ssrc_(0), |
1421 default_recv_channel_id_(-1) { | |
1419 engine->RegisterChannel(this); | 1422 engine->RegisterChannel(this); |
1420 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel " | 1423 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel " |
1421 << voe_channel(); | 1424 << voe_channel(); |
1422 RTC_DCHECK(nullptr != call); | 1425 RTC_DCHECK(nullptr != call); |
1423 ConfigureSendChannel(voe_channel()); | 1426 ConfigureSendChannel(voe_channel()); |
1424 SetOptions(options); | 1427 SetOptions(options); |
1425 } | 1428 } |
1426 | 1429 |
1427 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { | 1430 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { |
1428 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel " | 1431 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel " |
1429 << voe_channel(); | 1432 << voe_channel(); |
1430 | 1433 |
1431 // Remove any remaining send streams, the default channel will be deleted | 1434 // Remove any remaining send streams, the default channel will be deleted |
1432 // later. | 1435 // later. |
1433 while (!send_channels_.empty()) | 1436 while (!send_channels_.empty()) { |
1434 RemoveSendStream(send_channels_.begin()->first); | 1437 RemoveSendStream(send_channels_.begin()->first); |
1438 } | |
1435 | 1439 |
1436 // Unregister ourselves from the engine. | 1440 // Unregister ourselves from the engine. |
1437 engine()->UnregisterChannel(this); | 1441 engine()->UnregisterChannel(this); |
1442 | |
1438 // Remove any remaining streams. | 1443 // Remove any remaining streams. |
1439 while (!receive_channels_.empty()) { | 1444 while (!receive_channels_.empty()) { |
1440 RemoveRecvStream(receive_channels_.begin()->first); | 1445 RemoveRecvStream(receive_channels_.begin()->first); |
1441 } | 1446 } |
1442 RTC_DCHECK(receive_streams_.empty()); | 1447 RTC_DCHECK(receive_streams_.empty()); |
1443 | 1448 |
1444 // Delete the default channel. | 1449 // Delete the default channel. |
1445 DeleteChannel(voe_channel()); | 1450 DeleteChannel(voe_channel()); |
1446 } | 1451 } |
1447 | 1452 |
1448 bool WebRtcVoiceMediaChannel::SetSendParameters( | 1453 bool WebRtcVoiceMediaChannel::SetSendParameters( |
1449 const AudioSendParameters& params) { | 1454 const AudioSendParameters& params) { |
1450 // TODO(pthatcher): Refactor this to be more clean now that we have | 1455 // TODO(pthatcher): Refactor this to be more clean now that we have |
1451 // all the information at once. | 1456 // all the information at once. |
1452 return (SetSendCodecs(params.codecs) && | 1457 return (SetSendCodecs(params.codecs) && |
1453 SetSendRtpHeaderExtensions(params.extensions) && | 1458 SetSendRtpHeaderExtensions(params.extensions) && |
1454 SetMaxSendBandwidth(params.max_bandwidth_bps) && | 1459 SetMaxSendBandwidth(params.max_bandwidth_bps) && |
1455 SetOptions(params.options)); | 1460 SetOptions(params.options)); |
1456 } | 1461 } |
1457 | 1462 |
1458 bool WebRtcVoiceMediaChannel::SetRecvParameters( | 1463 bool WebRtcVoiceMediaChannel::SetRecvParameters( |
1459 const AudioRecvParameters& params) { | 1464 const AudioRecvParameters& params) { |
1460 // TODO(pthatcher): Refactor this to be more clean now that we have | 1465 // TODO(pthatcher): Refactor this to be more clean now that we have |
1461 // all the information at once. | 1466 // all the information at once. |
1462 return (SetRecvCodecs(params.codecs) && | 1467 return (SetRecvCodecs(params.codecs) && |
1463 SetRecvRtpHeaderExtensions(params.extensions)); | 1468 SetRecvRtpHeaderExtensions(params.extensions)); |
1464 } | 1469 } |
1465 | 1470 |
1466 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { | 1471 bool WebRtcVoiceMediaChannel::SetOptions(const AudioOptions& options) { |
1472 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
1467 LOG(LS_INFO) << "Setting voice channel options: " | 1473 LOG(LS_INFO) << "Setting voice channel options: " |
1468 << options.ToString(); | 1474 << options.ToString(); |
1469 | 1475 |
1470 // Check if DSCP value is changed from previous. | 1476 // Check if DSCP value is changed from previous. |
1471 bool dscp_option_changed = (options_.dscp != options.dscp); | 1477 bool dscp_option_changed = (options_.dscp != options.dscp); |
1472 | 1478 |
1473 // TODO(xians): Add support to set different options for different send | 1479 // TODO(xians): Add support to set different options for different send |
1474 // streams after we support multiple APMs. | 1480 // streams after we support multiple APMs. |
1475 | 1481 |
1476 // We retain all of the existing options, and apply the given ones | 1482 // We retain all of the existing options, and apply the given ones |
1477 // on top. This means there is no way to "clear" options such that | 1483 // on top. This means there is no way to "clear" options such that |
1478 // they go back to the engine default. | 1484 // they go back to the engine default. |
1479 options_.SetAll(options); | 1485 options_.SetAll(options); |
1480 | 1486 |
1481 if (send_ != SEND_NOTHING) { | 1487 if (send_ != SEND_NOTHING) { |
1482 if (!engine()->ApplyOptions(options_)) { | 1488 if (!engine()->ApplyOptions(options_)) { |
1483 LOG(LS_WARNING) << | 1489 LOG(LS_WARNING) << |
1484 "Failed to apply engine options during channel SetOptions."; | 1490 "Failed to apply engine options during channel SetOptions."; |
1485 return false; | 1491 return false; |
1486 } | 1492 } |
1487 } | 1493 } |
1488 | 1494 |
1495 for (const auto& ch : receive_channels_) { | |
1496 if (!SetRecvOptions(ch.second->channel())) { | |
1497 return false; | |
1498 } | |
1499 } | |
1500 if (dscp_option_changed) { | |
1501 rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT; | |
1502 if (options_.dscp.GetWithDefaultIfUnset(false)) | |
1503 dscp = kAudioDscpValue; | |
1504 if (MediaChannel::SetDscp(dscp) != 0) { | |
1505 LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel"; | |
1506 } | |
1507 } | |
1508 | |
1509 RecreateAudioReceiveStreams(); | |
1510 | |
1511 LOG(LS_INFO) << "Set voice channel options. Current options: " | |
1512 << options_.ToString(); | |
1513 return true; | |
1514 } | |
1515 | |
1516 bool WebRtcVoiceMediaChannel::SetRecvOptions(int channel_id) { | |
pthatcher1
2015/10/02 02:33:30
I think this method would be cleaner if you passed
the sun
2015/10/02 11:34:19
Done.
| |
1517 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
1518 | |
1489 // Receiver-side auto gain control happens per channel, so set it here from | 1519 // Receiver-side auto gain control happens per channel, so set it here from |
1490 // options. Note that, like conference mode, setting it on the engine won't | 1520 // options. Note that voice channels don't inherit options from the media |
1491 // have the desired effect, since voice channels don't inherit options from | 1521 // engine when those options are applied per-channel. |
1492 // the media engine when those options are applied per-channel. | |
1493 bool rx_auto_gain_control; | 1522 bool rx_auto_gain_control; |
1494 if (options.rx_auto_gain_control.Get(&rx_auto_gain_control)) { | 1523 if (options_.rx_auto_gain_control.Get(&rx_auto_gain_control)) { |
1495 if (engine()->voe()->processing()->SetRxAgcStatus( | 1524 if (engine()->voe()->processing()->SetRxAgcStatus( |
pthatcher1
2015/10/02 02:33:30
Are sure we want to set this for all receive chann
the sun
2015/10/02 11:34:19
No, but it seems really weird that we don't. I'm a
| |
1496 voe_channel(), rx_auto_gain_control, | 1525 channel_id, rx_auto_gain_control, |
1497 webrtc::kAgcFixedDigital) == -1) { | 1526 webrtc::kAgcFixedDigital) == -1) { |
1498 LOG_RTCERR1(SetRxAgcStatus, rx_auto_gain_control); | 1527 LOG_RTCERR1(SetRxAgcStatus, rx_auto_gain_control); |
1499 return false; | 1528 return false; |
1500 } else { | 1529 } else { |
1501 LOG(LS_VERBOSE) << "Rx auto gain set to " << rx_auto_gain_control | 1530 LOG(LS_VERBOSE) << "Rx auto gain set to " << rx_auto_gain_control |
1502 << " with mode " << webrtc::kAgcFixedDigital; | 1531 << " with mode " << webrtc::kAgcFixedDigital; |
1503 } | 1532 } |
1504 } | 1533 } |
1505 if (options.rx_agc_target_dbov.IsSet() || | 1534 if (options_.rx_agc_target_dbov.IsSet() || |
1506 options.rx_agc_digital_compression_gain.IsSet() || | 1535 options_.rx_agc_digital_compression_gain.IsSet() || |
1507 options.rx_agc_limiter.IsSet()) { | 1536 options_.rx_agc_limiter.IsSet()) { |
1508 webrtc::AgcConfig config; | 1537 webrtc::AgcConfig config; |
1509 // If only some of the options are being overridden, get the current | 1538 // If only some of the options are being overridden, get the current |
1510 // settings for the channel and bail if they aren't available. | 1539 // settings for the channel and bail if they aren't available. |
1511 if (!options.rx_agc_target_dbov.IsSet() || | 1540 if (!options_.rx_agc_target_dbov.IsSet() || |
1512 !options.rx_agc_digital_compression_gain.IsSet() || | 1541 !options_.rx_agc_digital_compression_gain.IsSet() || |
1513 !options.rx_agc_limiter.IsSet()) { | 1542 !options_.rx_agc_limiter.IsSet()) { |
1514 if (engine()->voe()->processing()->GetRxAgcConfig( | 1543 if (engine()->voe()->processing()->GetRxAgcConfig( |
1515 voe_channel(), config) != 0) { | 1544 channel_id, config) != 0) { |
1516 LOG(LS_ERROR) << "Failed to get default rx agc configuration for " | 1545 LOG(LS_ERROR) << "Failed to get default rx agc configuration for " |
1517 << "channel " << voe_channel() << ". Since not all rx " | 1546 << "channel " << channel_id << ". Since not all rx " |
1518 << "agc options are specified, unable to safely set rx " | 1547 << "agc options are specified, unable to safely set rx " |
1519 << "agc options."; | 1548 << "agc options."; |
1520 return false; | 1549 return false; |
1521 } | 1550 } |
1522 } | 1551 } |
1523 config.targetLeveldBOv = | 1552 config.targetLeveldBOv = |
1524 options.rx_agc_target_dbov.GetWithDefaultIfUnset( | 1553 options_.rx_agc_target_dbov.GetWithDefaultIfUnset( |
1525 config.targetLeveldBOv); | 1554 config.targetLeveldBOv); |
1526 config.digitalCompressionGaindB = | 1555 config.digitalCompressionGaindB = |
1527 options.rx_agc_digital_compression_gain.GetWithDefaultIfUnset( | 1556 options_.rx_agc_digital_compression_gain.GetWithDefaultIfUnset( |
1528 config.digitalCompressionGaindB); | 1557 config.digitalCompressionGaindB); |
1529 config.limiterEnable = options.rx_agc_limiter.GetWithDefaultIfUnset( | 1558 config.limiterEnable = options_.rx_agc_limiter.GetWithDefaultIfUnset( |
1530 config.limiterEnable); | 1559 config.limiterEnable); |
1531 if (engine()->voe()->processing()->SetRxAgcConfig( | 1560 if (engine()->voe()->processing()->SetRxAgcConfig( |
1532 voe_channel(), config) == -1) { | 1561 channel_id, config) == -1) { |
1533 LOG_RTCERR4(SetRxAgcConfig, voe_channel(), config.targetLeveldBOv, | 1562 LOG_RTCERR4(SetRxAgcConfig, channel_id, config.targetLeveldBOv, |
1534 config.digitalCompressionGaindB, config.limiterEnable); | 1563 config.digitalCompressionGaindB, config.limiterEnable); |
1535 return false; | 1564 return false; |
1536 } | 1565 } |
1537 } | 1566 } |
1538 if (dscp_option_changed) { | |
1539 rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT; | |
1540 if (options_.dscp.GetWithDefaultIfUnset(false)) | |
1541 dscp = kAudioDscpValue; | |
1542 if (MediaChannel::SetDscp(dscp) != 0) { | |
1543 LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel"; | |
1544 } | |
1545 } | |
1546 | |
1547 RecreateAudioReceiveStreams(); | |
1548 | |
1549 LOG(LS_INFO) << "Set voice channel options. Current options: " | |
1550 << options_.ToString(); | |
1551 return true; | 1567 return true; |
1552 } | 1568 } |
1553 | 1569 |
1554 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1570 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
1555 const std::vector<AudioCodec>& codecs) { | 1571 const std::vector<AudioCodec>& codecs) { |
1556 // Set the payload types to be used for incoming media. | 1572 // Set the payload types to be used for incoming media. |
1557 LOG(LS_INFO) << "Setting receive voice codecs:"; | 1573 LOG(LS_INFO) << "Setting receive voice codecs:"; |
1558 | 1574 |
1575 std::vector<int> payload_types; | |
1559 std::vector<AudioCodec> new_codecs; | 1576 std::vector<AudioCodec> new_codecs; |
1560 // Find all new codecs. We allow adding new codecs but don't allow changing | 1577 // 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 | 1578 // the payload type of codecs that is already configured since we might |
1562 // already be receiving packets with that payload type. | 1579 // already be receiving packets with that payload type. |
1563 for (const AudioCodec& codec : codecs) { | 1580 for (const auto& codec : codecs) { |
1564 AudioCodec old_codec; | 1581 AudioCodec old_codec; |
1565 if (FindCodec(recv_codecs_, codec, &old_codec)) { | 1582 if (FindCodec(recv_codecs_, codec, &old_codec)) { |
1566 if (old_codec.id != codec.id) { | 1583 if (old_codec.id != codec.id) { |
1567 LOG(LS_ERROR) << codec.name << " payload type changed."; | 1584 LOG(LS_ERROR) << codec.name << " payload type changed."; |
1568 return false; | 1585 return false; |
1569 } | 1586 } |
1570 } else { | 1587 } else { |
1588 payload_types.push_back(codec.id); | |
1571 new_codecs.push_back(codec); | 1589 new_codecs.push_back(codec); |
1572 } | 1590 } |
1573 } | 1591 } |
1574 if (new_codecs.empty()) { | 1592 if (new_codecs.empty()) { |
1575 // There are no new codecs to configure. Already configured codecs are | 1593 // There are no new codecs to configure. Already configured codecs are |
1576 // never removed. | 1594 // never removed. |
1577 return true; | 1595 return true; |
1578 } | 1596 } |
1579 | 1597 |
1598 // Verify no codecs have the same payload type. | |
1599 std::sort(payload_types.begin(), payload_types.end()); | |
1600 auto it = std::unique(payload_types.begin(), payload_types.end()); | |
1601 if (payload_types.end() != it) { | |
1602 return false; | |
1603 } | |
pthatcher1
2015/10/02 02:33:30
Can you move this into a separate static helper me
the sun
2015/10/02 11:34:19
Done.
| |
1604 | |
1580 if (playout_) { | 1605 if (playout_) { |
1581 // Receive codecs can not be changed while playing. So we temporarily | 1606 // Receive codecs can not be changed while playing. So we temporarily |
1582 // pause playout. | 1607 // pause playout. |
1583 PausePlayout(); | 1608 PausePlayout(); |
1584 } | 1609 } |
1585 | 1610 |
1586 bool result = SetRecvCodecsInternal(new_codecs); | 1611 bool result = SetRecvCodecsInternal(new_codecs); |
1587 if (result) { | 1612 if (result) { |
1588 recv_codecs_ = codecs; | 1613 recv_codecs_ = codecs; |
1589 } | 1614 } |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1797 return false; | 1822 return false; |
1798 } | 1823 } |
1799 } | 1824 } |
1800 } | 1825 } |
1801 } | 1826 } |
1802 return true; | 1827 return true; |
1803 } | 1828 } |
1804 | 1829 |
1805 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1830 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1806 const std::vector<AudioCodec>& codecs) { | 1831 const std::vector<AudioCodec>& codecs) { |
1832 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
1807 dtmf_allowed_ = false; | 1833 dtmf_allowed_ = false; |
1808 for (const AudioCodec& codec : codecs) { | 1834 for (const AudioCodec& codec : codecs) { |
1809 // Find the DTMF telephone event "codec". | 1835 // Find the DTMF telephone event "codec". |
1810 if (IsCodec(codec, kDtmfCodecName)) { | 1836 if (IsCodec(codec, kDtmfCodecName)) { |
1811 dtmf_allowed_ = true; | 1837 dtmf_allowed_ = true; |
1812 } | 1838 } |
1813 } | 1839 } |
1814 | 1840 |
1815 // Cache the codecs in order to configure the channel created later. | 1841 // Cache the codecs in order to configure the channel created later. |
1816 send_codecs_ = codecs; | 1842 send_codecs_ = codecs; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1868 | 1894 |
1869 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { | 1895 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { |
1870 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); | 1896 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); |
1871 return false; | 1897 return false; |
1872 } | 1898 } |
1873 return true; | 1899 return true; |
1874 } | 1900 } |
1875 | 1901 |
1876 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( | 1902 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( |
1877 const std::vector<RtpHeaderExtension>& extensions) { | 1903 const std::vector<RtpHeaderExtension>& extensions) { |
1904 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
1878 if (receive_extensions_ == extensions) { | 1905 if (receive_extensions_ == extensions) { |
1879 return true; | 1906 return true; |
1880 } | 1907 } |
1881 | 1908 |
1882 // The default channel may or may not be in |receive_channels_|. Set the rtp | |
1883 // header extensions for default channel regardless. | |
1884 if (!SetChannelRecvRtpHeaderExtensions(voe_channel(), extensions)) { | |
1885 return false; | |
1886 } | |
1887 | |
1888 // Loop through all receive channels and enable/disable the extensions. | |
1889 for (const auto& ch : receive_channels_) { | 1909 for (const auto& ch : receive_channels_) { |
1890 if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) { | 1910 if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) { |
1891 return false; | 1911 return false; |
1892 } | 1912 } |
1893 } | 1913 } |
1894 | 1914 |
1895 receive_extensions_ = extensions; | 1915 receive_extensions_ = extensions; |
1896 | 1916 |
1897 // Recreate AudioReceiveStream:s. | 1917 // Recreate AudioReceiveStream:s. |
1898 { | 1918 { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1993 | 2013 |
1994 bool WebRtcVoiceMediaChannel::PausePlayout() { | 2014 bool WebRtcVoiceMediaChannel::PausePlayout() { |
1995 return ChangePlayout(false); | 2015 return ChangePlayout(false); |
1996 } | 2016 } |
1997 | 2017 |
1998 bool WebRtcVoiceMediaChannel::ResumePlayout() { | 2018 bool WebRtcVoiceMediaChannel::ResumePlayout() { |
1999 return ChangePlayout(desired_playout_); | 2019 return ChangePlayout(desired_playout_); |
2000 } | 2020 } |
2001 | 2021 |
2002 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { | 2022 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { |
2023 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
2003 if (playout_ == playout) { | 2024 if (playout_ == playout) { |
2004 return true; | 2025 return true; |
2005 } | 2026 } |
2006 | 2027 |
2007 // Change the playout of all channels to the new state. | 2028 // Change the playout of all channels to the new state. |
2008 bool result = true; | 2029 bool result = true; |
2009 if (receive_channels_.empty()) { | |
2010 // Only toggle the default channel if we don't have any other channels. | |
2011 result = SetPlayout(voe_channel(), playout); | |
2012 } | |
2013 for (const auto& ch : receive_channels_) { | 2030 for (const auto& ch : receive_channels_) { |
2014 if (!SetPlayout(ch.second->channel(), playout)) { | 2031 if (!SetPlayout(ch.second->channel(), playout)) { |
2015 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " | 2032 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " |
2016 << ch.second->channel() << " failed"; | 2033 << ch.second->channel() << " failed"; |
2017 result = false; | 2034 result = false; |
2018 break; | 2035 break; |
2019 } | 2036 } |
2020 } | 2037 } |
2021 | 2038 |
2022 if (result) { | 2039 if (result) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2105 // TODO(ronghuawu): Change this method to return bool. | 2122 // TODO(ronghuawu): Change this method to return bool. |
2106 void WebRtcVoiceMediaChannel::ConfigureSendChannel(int channel) { | 2123 void WebRtcVoiceMediaChannel::ConfigureSendChannel(int channel) { |
2107 if (engine()->voe()->network()->RegisterExternalTransport( | 2124 if (engine()->voe()->network()->RegisterExternalTransport( |
2108 channel, *this) == -1) { | 2125 channel, *this) == -1) { |
2109 LOG_RTCERR2(RegisterExternalTransport, channel, this); | 2126 LOG_RTCERR2(RegisterExternalTransport, channel, this); |
2110 } | 2127 } |
2111 | 2128 |
2112 // Enable RTCP (for quality stats and feedback messages) | 2129 // Enable RTCP (for quality stats and feedback messages) |
2113 EnableRtcp(channel); | 2130 EnableRtcp(channel); |
2114 | 2131 |
2115 // Reset all recv codecs; they will be enabled via SetRecvCodecs. | |
2116 ResetRecvCodecs(channel); | |
2117 | |
2118 // Set RTP header extension for the new channel. | 2132 // Set RTP header extension for the new channel. |
2119 SetChannelSendRtpHeaderExtensions(channel, send_extensions_); | 2133 SetChannelSendRtpHeaderExtensions(channel, send_extensions_); |
2120 } | 2134 } |
2121 | 2135 |
2122 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { | 2136 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { |
2123 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { | 2137 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { |
2124 LOG_RTCERR1(DeRegisterExternalTransport, channel); | 2138 LOG_RTCERR1(DeRegisterExternalTransport, channel); |
2125 } | 2139 } |
2126 | 2140 |
2127 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { | 2141 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { |
2128 LOG_RTCERR1(DeleteChannel, channel); | 2142 LOG_RTCERR1(DeleteChannel, channel); |
2129 return false; | 2143 return false; |
2130 } | 2144 } |
2131 | 2145 |
2132 return true; | 2146 return true; |
2133 } | 2147 } |
2134 | 2148 |
2135 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { | 2149 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { |
2150 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
2136 // If the default channel is already used for sending create a new channel | 2151 // If the default channel is already used for sending create a new channel |
2137 // otherwise use the default channel for sending. | 2152 // otherwise use the default channel for sending. |
2138 int channel = GetSendChannelNum(sp.first_ssrc()); | 2153 int channel = GetSendChannelNum(sp.first_ssrc()); |
2139 if (channel != -1) { | 2154 if (channel != -1) { |
2140 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); | 2155 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); |
2141 return false; | 2156 return false; |
2142 } | 2157 } |
2143 | 2158 |
2144 bool default_channel_is_available = true; | 2159 bool default_channel_is_available = true; |
2145 for (const auto& ch : send_channels_) { | 2160 for (const auto& ch : send_channels_) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2177 LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc()); | 2192 LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc()); |
2178 return false; | 2193 return false; |
2179 } | 2194 } |
2180 | 2195 |
2181 // At this point the channel's local SSRC has been updated. If the channel is | 2196 // At this point the channel's local SSRC has been updated. If the channel is |
2182 // the default channel make sure that all the receive channels are updated as | 2197 // the default channel make sure that all the receive channels are updated as |
2183 // well. Receive channels have to have the same SSRC as the default channel in | 2198 // well. Receive channels have to have the same SSRC as the default channel in |
2184 // order to send receiver reports with this SSRC. | 2199 // order to send receiver reports with this SSRC. |
2185 if (IsDefaultChannel(channel)) { | 2200 if (IsDefaultChannel(channel)) { |
2186 for (const auto& ch : receive_channels_) { | 2201 for (const auto& ch : receive_channels_) { |
2187 // Only update the SSRC for non-default channels. | 2202 if (engine()->voe()->rtp()->SetLocalSSRC(ch.second->channel(), |
2188 if (!IsDefaultChannel(ch.second->channel())) { | 2203 sp.first_ssrc()) != 0) { |
2189 if (engine()->voe()->rtp()->SetLocalSSRC(ch.second->channel(), | 2204 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), sp.first_ssrc()); |
2190 sp.first_ssrc()) != 0) { | 2205 return false; |
2191 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), sp.first_ssrc()); | |
2192 return false; | |
2193 } | |
2194 } | 2206 } |
2195 } | 2207 } |
2196 } | 2208 } |
2197 | 2209 |
2198 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { | 2210 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { |
2199 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); | 2211 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); |
2200 return false; | 2212 return false; |
2201 } | 2213 } |
2202 | 2214 |
2203 // Set the current codecs to be used for the new channel. | 2215 // Set the current codecs to be used for the new channel. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2236 } | 2248 } |
2237 | 2249 |
2238 if (send_channels_.empty()) | 2250 if (send_channels_.empty()) |
2239 ChangeSend(SEND_NOTHING); | 2251 ChangeSend(SEND_NOTHING); |
2240 | 2252 |
2241 return true; | 2253 return true; |
2242 } | 2254 } |
2243 | 2255 |
2244 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { | 2256 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { |
2245 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2257 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2246 rtc::CritScope lock(&receive_channels_cs_); | 2258 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); |
2247 | 2259 |
2248 if (!VERIFY(sp.ssrcs.size() == 1)) | 2260 if (!ValidateStreamParams(sp)) { |
2249 return false; | 2261 return false; |
2262 } | |
2263 | |
2250 uint32 ssrc = sp.first_ssrc(); | 2264 uint32 ssrc = sp.first_ssrc(); |
2265 if (ssrc == 0) { | |
2266 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported."; | |
2267 return false; | |
2268 } | |
2251 | 2269 |
2252 if (ssrc == 0) { | 2270 // Remove the default receive stream if one had been created with this ssrc; |
2253 LOG(LS_WARNING) << "AddRecvStream with 0 ssrc is not supported."; | 2271 // we'll recreate it then. |
2254 return false; | 2272 if (-1 != default_recv_channel_id_ && ssrc == default_recv_ssrc_) { |
2273 RemoveRecvStream(ssrc); | |
2255 } | 2274 } |
2256 | 2275 |
2257 if (receive_channels_.find(ssrc) != receive_channels_.end()) { | 2276 if (receive_channels_.find(ssrc) != receive_channels_.end()) { |
2258 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; | 2277 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
2259 return false; | 2278 return false; |
2260 } | 2279 } |
2261 | |
2262 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); | 2280 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); |
2263 | 2281 |
2264 // Reuse default channel for recv stream in non-conference mode call | |
2265 // when the default channel is not being used. | |
2266 webrtc::AudioTransport* audio_transport = | |
2267 engine()->voe()->base()->audio_transport(); | |
2268 if (!InConferenceMode() && default_receive_ssrc_ == 0) { | |
2269 LOG(LS_INFO) << "Recv stream " << ssrc << " reuse default channel"; | |
2270 default_receive_ssrc_ = ssrc; | |
2271 WebRtcVoiceChannelRenderer* channel_renderer = | |
2272 new WebRtcVoiceChannelRenderer(voe_channel(), audio_transport); | |
2273 receive_channels_.insert(std::make_pair(ssrc, channel_renderer)); | |
2274 receive_stream_params_[ssrc] = sp; | |
2275 AddAudioReceiveStream(ssrc); | |
2276 return SetPlayout(voe_channel(), playout_); | |
2277 } | |
2278 | |
2279 // Create a new channel for receiving audio data. | 2282 // Create a new channel for receiving audio data. |
2280 int channel = engine()->CreateMediaVoiceChannel(); | 2283 int channel = engine()->CreateMediaVoiceChannel(); |
2281 if (channel == -1) { | 2284 if (channel == -1) { |
2282 LOG_RTCERR0(CreateChannel); | 2285 LOG_RTCERR0(CreateChannel); |
2283 return false; | 2286 return false; |
2284 } | 2287 } |
2285 | |
2286 if (!ConfigureRecvChannel(channel)) { | 2288 if (!ConfigureRecvChannel(channel)) { |
2287 DeleteChannel(channel); | 2289 DeleteChannel(channel); |
2288 return false; | 2290 return false; |
2289 } | 2291 } |
2290 | 2292 |
2293 webrtc::AudioTransport* audio_transport = | |
2294 engine()->voe()->base()->audio_transport(); | |
2291 WebRtcVoiceChannelRenderer* channel_renderer = | 2295 WebRtcVoiceChannelRenderer* channel_renderer = |
2292 new WebRtcVoiceChannelRenderer(channel, audio_transport); | 2296 new WebRtcVoiceChannelRenderer(channel, audio_transport); |
2293 receive_channels_.insert(std::make_pair(ssrc, channel_renderer)); | 2297 receive_channels_.insert(std::make_pair(ssrc, channel_renderer)); |
2294 receive_stream_params_[ssrc] = sp; | 2298 receive_stream_params_[ssrc] = sp; |
2295 AddAudioReceiveStream(ssrc); | 2299 AddAudioReceiveStream(ssrc); |
2296 | 2300 |
2297 LOG(LS_INFO) << "New audio stream " << ssrc | 2301 LOG(LS_INFO) << "New audio stream " << ssrc |
2298 << " registered to VoiceEngine channel #" | 2302 << " registered to VoiceEngine channel #" |
2299 << channel << "."; | 2303 << channel << "."; |
2300 return true; | 2304 return true; |
2301 } | 2305 } |
2302 | 2306 |
2303 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { | 2307 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { |
2304 // Configure to use external transport, like our default channel. | 2308 // Configure to use external transport. |
2305 if (engine()->voe()->network()->RegisterExternalTransport( | 2309 if (engine()->voe()->network()->RegisterExternalTransport( |
2306 channel, *this) == -1) { | 2310 channel, *this) == -1) { |
2307 LOG_RTCERR2(SetExternalTransport, channel, this); | 2311 LOG_RTCERR2(SetExternalTransport, channel, this); |
2308 return false; | 2312 return false; |
2309 } | 2313 } |
2310 | 2314 |
2311 // Use the same SSRC as our default channel (so the RTCP reports are correct). | 2315 if (!SetRecvOptions(channel)) { |
2316 return false; | |
2317 } | |
2318 | |
2319 // Use the same SSRC as our default (send) channel, so the RTCP reports are | |
pthatcher1
2015/10/02 02:33:30
"default (send) channel" or "default send channel"
the sun
2015/10/02 11:34:19
Done.
| |
2320 // correct. | |
2312 unsigned int send_ssrc = 0; | 2321 unsigned int send_ssrc = 0; |
2313 webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp(); | 2322 webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp(); |
2314 if (rtp->GetLocalSSRC(voe_channel(), send_ssrc) == -1) { | 2323 if (rtp->GetLocalSSRC(voe_channel(), send_ssrc) == -1) { |
2315 LOG_RTCERR1(GetSendSSRC, channel); | 2324 LOG_RTCERR1(GetSendSSRC, channel); |
2316 return false; | 2325 return false; |
2317 } | 2326 } |
2318 if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) { | 2327 if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) { |
2319 LOG_RTCERR1(SetSendSSRC, channel); | 2328 LOG_RTCERR1(SetSendSSRC, channel); |
2320 return false; | 2329 return false; |
2321 } | 2330 } |
2322 | 2331 |
2323 // Associate receive channel to default channel (so the receive channel can | 2332 // Associate receive channel to default send channel (so the receive channel |
2324 // obtain RTT from the send channel) | 2333 // can obtain RTT from the send channel) |
2325 engine()->voe()->base()->AssociateSendChannel(channel, voe_channel()); | 2334 engine()->voe()->base()->AssociateSendChannel(channel, voe_channel()); |
2326 LOG(LS_INFO) << "VoiceEngine channel #" | 2335 LOG(LS_INFO) << "VoiceEngine channel #" |
2327 << channel << " is associated with channel #" | 2336 << channel << " is associated with channel #" |
2328 << voe_channel() << "."; | 2337 << voe_channel() << "."; |
2329 | 2338 |
2330 // Use the same recv payload types as our default channel. | 2339 // Turn off all supported codecs. |
2331 ResetRecvCodecs(channel); | 2340 int ncodecs = engine()->voe()->codec()->NumOfCodecs(); |
2332 if (!recv_codecs_.empty()) { | 2341 for (int i = 0; i < ncodecs; ++i) { |
2333 for (const auto& codec : recv_codecs_) { | 2342 webrtc::CodecInst voe_codec; |
2334 webrtc::CodecInst voe_codec; | 2343 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { |
2335 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { | 2344 voe_codec.pltype = -1; |
2336 voe_codec.pltype = codec.id; | 2345 if (engine()->voe()->codec()->SetRecPayloadType( |
2337 voe_codec.rate = 0; // Needed to make GetRecPayloadType work for ISAC | 2346 channel, voe_codec) == -1) { |
2338 if (engine()->voe()->codec()->GetRecPayloadType( | 2347 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); |
2339 voe_channel(), voe_codec) != -1) { | 2348 return false; |
2340 if (engine()->voe()->codec()->SetRecPayloadType( | |
2341 channel, voe_codec) == -1) { | |
2342 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); | |
2343 return false; | |
2344 } | |
2345 } | |
2346 } | 2349 } |
2347 } | 2350 } |
2348 } | 2351 } |
2349 | 2352 |
2350 if (InConferenceMode()) { | 2353 // Only enable those configured for this channel. |
2351 // To be in par with the video, voe_channel() is not used for receiving in | 2354 for (const auto& codec : recv_codecs_) { |
2352 // a conference call. | 2355 webrtc::CodecInst voe_codec; |
2353 if (receive_channels_.empty() && default_receive_ssrc_ == 0 && playout_) { | 2356 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { |
2354 // This is the first stream in a multi user meeting. We can now | 2357 voe_codec.pltype = codec.id; |
2355 // disable playback of the default stream. This since the default | 2358 if (engine()->voe()->codec()->SetRecPayloadType( |
2356 // stream will probably have received some initial packets before | 2359 channel, voe_codec) == -1) { |
2357 // the new stream was added. This will mean that the CN state from | 2360 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); |
2358 // the default channel will be mixed in with the other streams | 2361 return false; |
2359 // throughout the whole meeting, which might be disturbing. | 2362 } |
2360 LOG(LS_INFO) << "Disabling playback on the default voice channel"; | |
2361 SetPlayout(voe_channel(), false); | |
2362 } | 2363 } |
2363 } | 2364 } |
2365 | |
2364 SetNack(channel, nack_enabled_); | 2366 SetNack(channel, nack_enabled_); |
2365 | 2367 |
2366 // Set RTP header extension for the new channel. | 2368 // Set RTP header extension for the new channel. |
2367 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { | 2369 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { |
2368 return false; | 2370 return false; |
2369 } | 2371 } |
2370 | 2372 |
2371 return SetPlayout(channel, playout_); | 2373 return SetPlayout(channel, playout_); |
2372 } | 2374 } |
2373 | 2375 |
2374 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32 ssrc) { | 2376 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32 ssrc) { |
2375 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2377 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2376 rtc::CritScope lock(&receive_channels_cs_); | 2378 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
2379 | |
2377 ChannelMap::iterator it = receive_channels_.find(ssrc); | 2380 ChannelMap::iterator it = receive_channels_.find(ssrc); |
2378 if (it == receive_channels_.end()) { | 2381 if (it == receive_channels_.end()) { |
2379 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2382 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2380 << " which doesn't exist."; | 2383 << " which doesn't exist."; |
2381 return false; | 2384 return false; |
2382 } | 2385 } |
2383 | 2386 |
2384 RemoveAudioReceiveStream(ssrc); | 2387 RemoveAudioReceiveStream(ssrc); |
2385 receive_stream_params_.erase(ssrc); | 2388 receive_stream_params_.erase(ssrc); |
2386 | 2389 |
2387 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, this | 2390 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, this |
2388 // will disconnect the audio renderer with the receive channel. | 2391 // will disconnect the audio renderer with the receive channel. |
2389 // Cache the channel before the deletion. | 2392 // Cache the channel before the deletion. |
2390 const int channel = it->second->channel(); | 2393 const int channel = it->second->channel(); |
2391 delete it->second; | 2394 delete it->second; |
2392 receive_channels_.erase(it); | 2395 receive_channels_.erase(it); |
2393 | 2396 |
2394 if (ssrc == default_receive_ssrc_) { | 2397 // Deregister default channel, if that's the one being destroyed. |
2395 RTC_DCHECK(IsDefaultChannel(channel)); | 2398 if (-1 != default_recv_channel_id_ && ssrc == default_recv_ssrc_) { |
2396 // Recycle the default channel is for recv stream. | 2399 RTC_DCHECK(channel == default_recv_channel_id_); |
2397 if (playout_) | 2400 default_recv_ssrc_ = 0; |
2398 SetPlayout(voe_channel(), false); | 2401 default_recv_channel_id_ = -1; |
2399 | |
2400 default_receive_ssrc_ = 0; | |
2401 return true; | |
2402 } | 2402 } |
2403 | 2403 |
2404 LOG(LS_INFO) << "Removing audio stream " << ssrc | 2404 LOG(LS_INFO) << "Removing audio stream " << ssrc |
2405 << " with VoiceEngine channel #" << channel << "."; | 2405 << " with VoiceEngine channel #" << channel << "."; |
2406 if (!DeleteChannel(channel)) | 2406 return DeleteChannel(channel); |
2407 return false; | |
2408 | |
2409 bool enable_default_channel_playout = false; | |
2410 if (receive_channels_.empty()) { | |
2411 // The last stream was removed. We can now enable the default | |
2412 // channel for new channels to be played out immediately without | |
2413 // waiting for AddStream messages. | |
2414 // We do this for both conference mode and non-conference mode. | |
2415 // TODO(oja): Does the default channel still have it's CN state? | |
2416 enable_default_channel_playout = true; | |
2417 } | |
2418 if (!InConferenceMode() && receive_channels_.size() == 1 && | |
2419 default_receive_ssrc_ != 0) { | |
2420 // Only the default channel is active, enable the playout on default | |
2421 // channel. | |
2422 enable_default_channel_playout = true; | |
2423 } | |
2424 if (enable_default_channel_playout && playout_) { | |
2425 LOG(LS_INFO) << "Enabling playback on the default voice channel"; | |
2426 SetPlayout(voe_channel(), true); | |
2427 } | |
2428 | |
2429 return true; | |
2430 } | 2407 } |
2431 | 2408 |
2432 bool WebRtcVoiceMediaChannel::SetRemoteRenderer(uint32 ssrc, | 2409 bool WebRtcVoiceMediaChannel::SetRemoteRenderer(uint32 ssrc, |
2433 AudioRenderer* renderer) { | 2410 AudioRenderer* renderer) { |
2411 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
2434 ChannelMap::iterator it = receive_channels_.find(ssrc); | 2412 ChannelMap::iterator it = receive_channels_.find(ssrc); |
2435 if (it == receive_channels_.end()) { | 2413 if (it == receive_channels_.end()) { |
2436 if (renderer) { | 2414 if (renderer) { |
2437 // Return an error if trying to set a valid renderer with an invalid ssrc. | 2415 // Return an error if trying to set a valid renderer with an invalid ssrc. |
2438 LOG(LS_ERROR) << "SetRemoteRenderer failed with ssrc "<< ssrc; | 2416 LOG(LS_ERROR) << "SetRemoteRenderer failed with ssrc "<< ssrc; |
2439 return false; | 2417 return false; |
2440 } | 2418 } |
2441 | 2419 |
2442 // The channel likely has gone away, do nothing. | 2420 // The channel likely has gone away, do nothing. |
2443 return true; | 2421 return true; |
(...skipping 24 matching lines...) Expand all Loading... | |
2468 if (renderer) | 2446 if (renderer) |
2469 it->second->Start(renderer); | 2447 it->second->Start(renderer); |
2470 else | 2448 else |
2471 it->second->Stop(); | 2449 it->second->Stop(); |
2472 | 2450 |
2473 return true; | 2451 return true; |
2474 } | 2452 } |
2475 | 2453 |
2476 bool WebRtcVoiceMediaChannel::GetActiveStreams( | 2454 bool WebRtcVoiceMediaChannel::GetActiveStreams( |
2477 AudioInfo::StreamList* actives) { | 2455 AudioInfo::StreamList* actives) { |
2478 // In conference mode, the default channel should not be in | 2456 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2479 // |receive_channels_|. | |
2480 actives->clear(); | 2457 actives->clear(); |
2481 for (const auto& ch : receive_channels_) { | 2458 for (const auto& ch : receive_channels_) { |
2482 int level = GetOutputLevel(ch.second->channel()); | 2459 int level = GetOutputLevel(ch.second->channel()); |
2483 if (level > 0) { | 2460 if (level > 0) { |
2484 actives->push_back(std::make_pair(ch.first, level)); | 2461 actives->push_back(std::make_pair(ch.first, level)); |
2485 } | 2462 } |
2486 } | 2463 } |
2487 return true; | 2464 return true; |
2488 } | 2465 } |
2489 | 2466 |
2490 int WebRtcVoiceMediaChannel::GetOutputLevel() { | 2467 int WebRtcVoiceMediaChannel::GetOutputLevel() { |
2491 // return the highest output level of all streams | 2468 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2492 int highest = GetOutputLevel(voe_channel()); | 2469 int highest = 0; |
2493 for (const auto& ch : receive_channels_) { | 2470 for (const auto& ch : receive_channels_) { |
2494 int level = GetOutputLevel(ch.second->channel()); | 2471 highest = std::max(GetOutputLevel(ch.second->channel()), highest); |
2495 highest = std::max(level, highest); | |
2496 } | 2472 } |
2497 return highest; | 2473 return highest; |
2498 } | 2474 } |
2499 | 2475 |
2500 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { | 2476 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { |
2501 int ret; | 2477 int ret; |
2502 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { | 2478 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { |
2503 // In case of error, log the info and continue | 2479 // In case of error, log the info and continue |
2504 LOG_RTCERR0(TimeSinceLastTyping); | 2480 LOG_RTCERR0(TimeSinceLastTyping); |
2505 ret = -1; | 2481 ret = -1; |
(...skipping 11 matching lines...) Expand all Loading... | |
2517 reporting_threshold, penalty_decay, type_event_delay) == -1) { | 2493 reporting_threshold, penalty_decay, type_event_delay) == -1) { |
2518 // In case of error, log the info and continue | 2494 // In case of error, log the info and continue |
2519 LOG_RTCERR5(SetTypingDetectionParameters, time_window, | 2495 LOG_RTCERR5(SetTypingDetectionParameters, time_window, |
2520 cost_per_typing, reporting_threshold, penalty_decay, | 2496 cost_per_typing, reporting_threshold, penalty_decay, |
2521 type_event_delay); | 2497 type_event_delay); |
2522 } | 2498 } |
2523 } | 2499 } |
2524 | 2500 |
2525 bool WebRtcVoiceMediaChannel::SetOutputScaling( | 2501 bool WebRtcVoiceMediaChannel::SetOutputScaling( |
2526 uint32 ssrc, double left, double right) { | 2502 uint32 ssrc, double left, double right) { |
2527 rtc::CritScope lock(&receive_channels_cs_); | 2503 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2528 // Collect the channels to scale the output volume. | 2504 // Collect channels to scale output volume for (ssrc == 0 means all channels). |
2529 std::vector<int> channels; | 2505 std::vector<int> channels; |
2530 if (0 == ssrc) { // Collect all channels, including the default one. | 2506 for (const auto& ch : receive_channels_) { |
2531 // Default channel is not in receive_channels_ if it is not being used for | 2507 if (0 == ssrc || ch.first == ssrc) { |
2532 // playout. | |
2533 if (default_receive_ssrc_ == 0) | |
2534 channels.push_back(voe_channel()); | |
2535 for (const auto& ch : receive_channels_) { | |
2536 channels.push_back(ch.second->channel()); | 2508 channels.push_back(ch.second->channel()); |
2537 } | 2509 } |
2538 } else { // Collect only the channel of the specified ssrc. | 2510 } |
2539 int channel = GetReceiveChannelNum(ssrc); | 2511 if (0 != ssrc && channels.empty()) { |
2540 if (-1 == channel) { | 2512 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; |
2541 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; | 2513 return false; |
2542 return false; | |
2543 } | |
2544 channels.push_back(channel); | |
2545 } | 2514 } |
2546 | 2515 |
2547 // Scale the output volume for the collected channels. We first normalize to | 2516 // Scale the output volume for the collected channels. We first normalize to |
2548 // scale the volume and then set the left and right pan. | 2517 // scale the volume and then set the left and right pan. |
2549 float scale = static_cast<float>(std::max(left, right)); | 2518 float scale = static_cast<float>(std::max(left, right)); |
2550 if (scale > 0.0001f) { | 2519 if (scale > 0.0001f) { |
2551 left /= scale; | 2520 left /= scale; |
2552 right /= scale; | 2521 right /= scale; |
2553 } | 2522 } |
2554 for (int ch_id : channels) { | 2523 for (int ch_id : channels) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2621 } | 2590 } |
2622 } | 2591 } |
2623 | 2592 |
2624 return true; | 2593 return true; |
2625 } | 2594 } |
2626 | 2595 |
2627 void WebRtcVoiceMediaChannel::OnPacketReceived( | 2596 void WebRtcVoiceMediaChannel::OnPacketReceived( |
2628 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { | 2597 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { |
2629 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2598 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2630 | 2599 |
2631 // Forward packet to Call as well. | 2600 uint32 ssrc = 0; |
2601 if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) { | |
2602 return; | |
2603 } | |
2604 | |
2605 if (receive_channels_.empty()) { | |
2606 // Create new channel, which will be the default receive channel. | |
2607 StreamParams sp; | |
2608 sp.ssrcs.push_back(ssrc); | |
2609 LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << "."; | |
2610 if (!AddRecvStream(sp)) { | |
2611 LOG(LS_WARNING) << "Could not create default receive stream."; | |
2612 return; | |
2613 } | |
2614 default_recv_ssrc_ = ssrc; | |
2615 default_recv_channel_id_ = receive_channels_[ssrc]->channel(); | |
2616 RTC_DCHECK(-1 != default_recv_channel_id_); | |
2617 } | |
2618 | |
2619 // Forward packet to Call. If the SSRC is unknown we'll return after this. | |
2632 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, | 2620 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, |
2633 packet_time.not_before); | 2621 packet_time.not_before); |
2634 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2622 webrtc::PacketReceiver::DeliveryStatus delivery_result = |
2635 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), | 2623 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
2636 webrtc_packet_time); | 2624 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), |
2625 webrtc_packet_time); | |
2626 if (webrtc::PacketReceiver::DELIVERY_OK != delivery_result) { | |
2627 return; | |
2628 } | |
2637 | 2629 |
2638 // Pick which channel to send this packet to. If this packet doesn't match | 2630 // Find the channel to send this packet to. It must exist since webrtc::Call |
2639 // any multiplexed streams, just send it to the default channel. Otherwise, | 2631 // was able to demux the packet. |
2640 // send it to the specific decoder instance for that stream. | 2632 int channel = GetReceiveChannelNum(ssrc); |
2641 int which_channel = | 2633 RTC_DCHECK(channel != -1); |
2642 GetReceiveChannelNum(ParseSsrc(packet->data(), packet->size(), false)); | |
2643 if (which_channel == -1) { | |
2644 which_channel = voe_channel(); | |
2645 } | |
2646 | 2634 |
2647 // Pass it off to the decoder. | 2635 // Pass it off to the decoder. |
2648 engine()->voe()->network()->ReceivedRTPPacket( | 2636 engine()->voe()->network()->ReceivedRTPPacket( |
2649 which_channel, packet->data(), packet->size(), | 2637 channel, packet->data(), packet->size(), webrtc_packet_time); |
2650 webrtc::PacketTime(packet_time.timestamp, packet_time.not_before)); | |
2651 } | 2638 } |
2652 | 2639 |
2653 void WebRtcVoiceMediaChannel::OnRtcpReceived( | 2640 void WebRtcVoiceMediaChannel::OnRtcpReceived( |
2654 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { | 2641 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { |
2655 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2642 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2656 | 2643 |
2657 // Forward packet to Call as well. | 2644 // Forward packet to Call as well. |
2658 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, | 2645 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, |
2659 packet_time.not_before); | 2646 packet_time.not_before); |
2660 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, | 2647 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, |
2661 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), | 2648 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), |
2662 webrtc_packet_time); | 2649 webrtc_packet_time); |
2663 | 2650 |
2664 // Sending channels need all RTCP packets with feedback information. | 2651 // Sending channels need all RTCP packets with feedback information. |
2665 // Even sender reports can contain attached report blocks. | 2652 // Even sender reports can contain attached report blocks. |
2666 // Receiving channels need sender reports in order to create | 2653 // Receiving channels need sender reports in order to create |
2667 // correct receiver reports. | 2654 // correct receiver reports. |
2668 int type = 0; | 2655 int type = 0; |
2669 if (!GetRtcpType(packet->data(), packet->size(), &type)) { | 2656 if (!GetRtcpType(packet->data(), packet->size(), &type)) { |
2670 LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; | 2657 LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; |
2671 return; | 2658 return; |
2672 } | 2659 } |
2673 | 2660 |
2674 // If it is a sender report, find the channel that is listening. | 2661 // If it is a sender report, find the receive channel that is listening. |
2675 bool has_sent_to_default_channel = false; | |
2676 if (type == kRtcpTypeSR) { | 2662 if (type == kRtcpTypeSR) { |
2677 int which_channel = | 2663 uint32 ssrc = 0; |
2678 GetReceiveChannelNum(ParseSsrc(packet->data(), packet->size(), true)); | 2664 if (!GetRtcpSsrc(packet->data(), packet->size(), &ssrc)) { |
2679 if (which_channel != -1) { | 2665 return; |
2666 } | |
2667 int channel = GetReceiveChannelNum(ssrc); | |
2668 if (channel != -1) { | |
2680 engine()->voe()->network()->ReceivedRTCPPacket( | 2669 engine()->voe()->network()->ReceivedRTCPPacket( |
2681 which_channel, packet->data(), packet->size()); | 2670 channel, packet->data(), packet->size()); |
2682 | |
2683 if (IsDefaultChannel(which_channel)) | |
2684 has_sent_to_default_channel = true; | |
2685 } | 2671 } |
2686 } | 2672 } |
2687 | 2673 |
2688 // SR may continue RR and any RR entry may correspond to any one of the send | 2674 // 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 | 2675 // channels. So all RTCP packets must be forwarded all send channels. VoE |
2690 // will filter out RR internally. | 2676 // will filter out RR internally. |
2691 for (const auto& ch : send_channels_) { | 2677 for (const auto& ch : send_channels_) { |
2692 // Make sure not sending the same packet to default channel more than once. | |
2693 if (IsDefaultChannel(ch.second->channel()) && | |
2694 has_sent_to_default_channel) | |
2695 continue; | |
2696 | |
2697 engine()->voe()->network()->ReceivedRTCPPacket( | 2678 engine()->voe()->network()->ReceivedRTCPPacket( |
2698 ch.second->channel(), packet->data(), packet->size()); | 2679 ch.second->channel(), packet->data(), packet->size()); |
2699 } | 2680 } |
2700 } | 2681 } |
2701 | 2682 |
2702 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { | 2683 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { |
2703 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc); | 2684 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc); |
2704 if (channel == -1) { | 2685 if (channel == -1) { |
2705 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; | 2686 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; |
2706 return false; | 2687 return false; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2777 LOG(LS_INFO) << "Failed to set codec " << codec.plname | 2758 LOG(LS_INFO) << "Failed to set codec " << codec.plname |
2778 << " to bitrate " << bps << " bps" | 2759 << " to bitrate " << bps << " bps" |
2779 << ", requires at least " << codec.rate << " bps."; | 2760 << ", requires at least " << codec.rate << " bps."; |
2780 return false; | 2761 return false; |
2781 } | 2762 } |
2782 return true; | 2763 return true; |
2783 } | 2764 } |
2784 } | 2765 } |
2785 | 2766 |
2786 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { | 2767 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { |
2768 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
2769 | |
2787 bool echo_metrics_on = false; | 2770 bool echo_metrics_on = false; |
2788 // These can take on valid negative values, so use the lowest possible level | 2771 // These can take on valid negative values, so use the lowest possible level |
2789 // as default rather than -1. | 2772 // as default rather than -1. |
2790 int echo_return_loss = -100; | 2773 int echo_return_loss = -100; |
2791 int echo_return_loss_enhancement = -100; | 2774 int echo_return_loss_enhancement = -100; |
2792 // These can also be negative, but in practice -1 is only used to signal | 2775 // 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. | 2776 // insufficient data, since the resolution is limited to multiples of 4 ms. |
2794 int echo_delay_median_ms = -1; | 2777 int echo_delay_median_ms = -1; |
2795 int echo_delay_std_ms = -1; | 2778 int echo_delay_std_ms = -1; |
2796 if (engine()->voe()->processing()->GetEcMetricsStatus( | 2779 if (engine()->voe()->processing()->GetEcMetricsStatus( |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2878 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; | 2861 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; |
2879 sinfo.echo_delay_median_ms = echo_delay_median_ms; | 2862 sinfo.echo_delay_median_ms = echo_delay_median_ms; |
2880 sinfo.echo_delay_std_ms = echo_delay_std_ms; | 2863 sinfo.echo_delay_std_ms = echo_delay_std_ms; |
2881 // TODO(ajm): Re-enable this metric once we have a reliable implementation. | 2864 // TODO(ajm): Re-enable this metric once we have a reliable implementation. |
2882 sinfo.aec_quality_min = -1; | 2865 sinfo.aec_quality_min = -1; |
2883 sinfo.typing_noise_detected = typing_noise_detected_; | 2866 sinfo.typing_noise_detected = typing_noise_detected_; |
2884 | 2867 |
2885 info->senders.push_back(sinfo); | 2868 info->senders.push_back(sinfo); |
2886 } | 2869 } |
2887 | 2870 |
2888 // Build the list of receivers, one for each receiving channel, or 1 in | 2871 // Get the SSRC and stats for each receiver. |
2889 // a 1:1 call. | |
2890 std::vector<int> channels; | |
2891 for (const auto& ch : receive_channels_) { | 2872 for (const auto& ch : receive_channels_) { |
2892 channels.push_back(ch.second->channel()); | 2873 int ch_id = ch.second->channel(); |
2893 } | |
2894 if (channels.empty()) { | |
2895 channels.push_back(voe_channel()); | |
2896 } | |
2897 | |
2898 // Get the SSRC and stats for each receiver, based on our own calculations. | |
2899 for (int ch_id : channels) { | |
2900 memset(&cs, 0, sizeof(cs)); | 2874 memset(&cs, 0, sizeof(cs)); |
2901 if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 && | 2875 if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 && |
2902 engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 && | 2876 engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 && |
2903 engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) { | 2877 engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) { |
2904 VoiceReceiverInfo rinfo; | 2878 VoiceReceiverInfo rinfo; |
2905 rinfo.add_ssrc(ssrc); | 2879 rinfo.add_ssrc(ssrc); |
2906 rinfo.bytes_rcvd = cs.bytesReceived; | 2880 rinfo.bytes_rcvd = cs.bytesReceived; |
2907 rinfo.packets_rcvd = cs.packetsReceived; | 2881 rinfo.packets_rcvd = cs.packetsReceived; |
2908 // The next four fields are from the most recently sent RTCP report. | 2882 // The next four fields are from the most recently sent RTCP report. |
2909 // Convert Q8 to floating point. | 2883 // Convert Q8 to floating point. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2972 | 2946 |
2973 void WebRtcVoiceMediaChannel::GetLastMediaError( | 2947 void WebRtcVoiceMediaChannel::GetLastMediaError( |
2974 uint32* ssrc, VoiceMediaChannel::Error* error) { | 2948 uint32* ssrc, VoiceMediaChannel::Error* error) { |
2975 RTC_DCHECK(ssrc != NULL); | 2949 RTC_DCHECK(ssrc != NULL); |
2976 RTC_DCHECK(error != NULL); | 2950 RTC_DCHECK(error != NULL); |
2977 FindSsrc(voe_channel(), ssrc); | 2951 FindSsrc(voe_channel(), ssrc); |
2978 *error = WebRtcErrorToChannelError(GetLastEngineError()); | 2952 *error = WebRtcErrorToChannelError(GetLastEngineError()); |
2979 } | 2953 } |
2980 | 2954 |
2981 bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) { | 2955 bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) { |
2982 rtc::CritScope lock(&receive_channels_cs_); | 2956 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2983 RTC_DCHECK(ssrc != NULL); | 2957 RTC_DCHECK(ssrc != NULL); |
2984 if (channel_num == -1 && send_ != SEND_NOTHING) { | 2958 if (channel_num == -1 && send_ != SEND_NOTHING) { |
2985 // Sometimes the VoiceEngine core will throw error with channel_num = -1. | 2959 // Sometimes the VoiceEngine core will throw error with channel_num = -1. |
2986 // This means the error is not limited to a specific channel. Signal the | 2960 // This means the error is not limited to a specific channel. Signal the |
2987 // message using ssrc=0. If the current channel is sending, use this | 2961 // message using ssrc=0. If the current channel is sending, use this |
2988 // channel for sending the message. | 2962 // channel for sending the message. |
2989 *ssrc = 0; | 2963 *ssrc = 0; |
2990 return true; | 2964 return true; |
2991 } else { | 2965 } else { |
2992 // Check whether this is a sending channel. | 2966 // Check whether this is a sending channel. |
(...skipping 30 matching lines...) Expand all Loading... | |
3023 } | 2997 } |
3024 | 2998 |
3025 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { | 2999 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { |
3026 unsigned int ulevel; | 3000 unsigned int ulevel; |
3027 int ret = | 3001 int ret = |
3028 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); | 3002 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); |
3029 return (ret == 0) ? static_cast<int>(ulevel) : -1; | 3003 return (ret == 0) ? static_cast<int>(ulevel) : -1; |
3030 } | 3004 } |
3031 | 3005 |
3032 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const { | 3006 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const { |
3007 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
3033 ChannelMap::const_iterator it = receive_channels_.find(ssrc); | 3008 ChannelMap::const_iterator it = receive_channels_.find(ssrc); |
3034 if (it != receive_channels_.end()) | 3009 if (it != receive_channels_.end()) |
3035 return it->second->channel(); | 3010 return it->second->channel(); |
3036 return (ssrc == default_receive_ssrc_) ? voe_channel() : -1; | 3011 return -1; |
3037 } | 3012 } |
3038 | 3013 |
3039 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const { | 3014 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const { |
3040 ChannelMap::const_iterator it = send_channels_.find(ssrc); | 3015 ChannelMap::const_iterator it = send_channels_.find(ssrc); |
3041 if (it != send_channels_.end()) | 3016 if (it != send_channels_.end()) |
3042 return it->second->channel(); | 3017 return it->second->channel(); |
3043 | |
3044 return -1; | 3018 return -1; |
3045 } | 3019 } |
3046 | 3020 |
3047 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, | 3021 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, |
3048 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { | 3022 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { |
3049 // Get the RED encodings from the parameter with no name. This may | 3023 // Get the RED encodings from the parameter with no name. This may |
3050 // change based on what is discussed on the Jingle list. | 3024 // change based on what is discussed on the Jingle list. |
3051 // The encoding parameter is of the form "a/b"; we only support where | 3025 // The encoding parameter is of the form "a/b"; we only support where |
3052 // a == b. Verify this and parse out the value into red_pt. | 3026 // a == b. Verify this and parse out the value into red_pt. |
3053 // If the parameter value is absent (as it will be until we wire up the | 3027 // If the parameter value is absent (as it will be until we wire up the |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3093 LOG_RTCERR2(SetRTCPStatus, channel, 1); | 3067 LOG_RTCERR2(SetRTCPStatus, channel, 1); |
3094 return false; | 3068 return false; |
3095 } | 3069 } |
3096 // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what | 3070 // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what |
3097 // what we want to do with them. | 3071 // what we want to do with them. |
3098 // engine()->voe().EnableVQMon(voe_channel(), true); | 3072 // engine()->voe().EnableVQMon(voe_channel(), true); |
3099 // engine()->voe().EnableRTCP_XR(voe_channel(), true); | 3073 // engine()->voe().EnableRTCP_XR(voe_channel(), true); |
3100 return true; | 3074 return true; |
3101 } | 3075 } |
3102 | 3076 |
3103 bool WebRtcVoiceMediaChannel::ResetRecvCodecs(int channel) { | |
3104 int ncodecs = engine()->voe()->codec()->NumOfCodecs(); | |
3105 for (int i = 0; i < ncodecs; ++i) { | |
3106 webrtc::CodecInst voe_codec; | |
3107 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { | |
3108 voe_codec.pltype = -1; | |
3109 if (engine()->voe()->codec()->SetRecPayloadType( | |
3110 channel, voe_codec) == -1) { | |
3111 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); | |
3112 return false; | |
3113 } | |
3114 } | |
3115 } | |
3116 return true; | |
3117 } | |
3118 | |
3119 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { | 3077 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { |
3120 if (playout) { | 3078 if (playout) { |
3121 LOG(LS_INFO) << "Starting playout for channel #" << channel; | 3079 LOG(LS_INFO) << "Starting playout for channel #" << channel; |
3122 if (engine()->voe()->base()->StartPlayout(channel) == -1) { | 3080 if (engine()->voe()->base()->StartPlayout(channel) == -1) { |
3123 LOG_RTCERR1(StartPlayout, channel); | 3081 LOG_RTCERR1(StartPlayout, channel); |
3124 return false; | 3082 return false; |
3125 } | 3083 } |
3126 } else { | 3084 } else { |
3127 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 3085 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
3128 engine()->voe()->base()->StopPlayout(channel); | 3086 engine()->voe()->base()->StopPlayout(channel); |
3129 } | 3087 } |
3130 return true; | 3088 return true; |
3131 } | 3089 } |
3132 | 3090 |
3133 uint32 WebRtcVoiceMediaChannel::ParseSsrc(const void* data, size_t len, | |
3134 bool rtcp) { | |
3135 size_t ssrc_pos = (!rtcp) ? 8 : 4; | |
3136 uint32 ssrc = 0; | |
3137 if (len >= (ssrc_pos + sizeof(ssrc))) { | |
3138 ssrc = rtc::GetBE32(static_cast<const char*>(data) + ssrc_pos); | |
3139 } | |
3140 return ssrc; | |
3141 } | |
3142 | |
3143 // Convert VoiceEngine error code into VoiceMediaChannel::Error enum. | 3091 // Convert VoiceEngine error code into VoiceMediaChannel::Error enum. |
3144 VoiceMediaChannel::Error | 3092 VoiceMediaChannel::Error |
3145 WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) { | 3093 WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) { |
3146 switch (err_code) { | 3094 switch (err_code) { |
3147 case 0: | 3095 case 0: |
3148 return ERROR_NONE; | 3096 return ERROR_NONE; |
3149 case VE_CANNOT_START_RECORDING: | 3097 case VE_CANNOT_START_RECORDING: |
3150 case VE_MIC_VOL_ERROR: | 3098 case VE_MIC_VOL_ERROR: |
3151 case VE_GET_MIC_VOL_ERROR: | 3099 case VE_GET_MIC_VOL_ERROR: |
3152 case VE_CANNOT_ACCESS_MIC_VOL: | 3100 case VE_CANNOT_ACCESS_MIC_VOL: |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3221 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 3169 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
3222 auto stream_it = receive_streams_.find(ssrc); | 3170 auto stream_it = receive_streams_.find(ssrc); |
3223 if (stream_it != receive_streams_.end()) { | 3171 if (stream_it != receive_streams_.end()) { |
3224 call_->DestroyAudioReceiveStream(stream_it->second); | 3172 call_->DestroyAudioReceiveStream(stream_it->second); |
3225 receive_streams_.erase(stream_it); | 3173 receive_streams_.erase(stream_it); |
3226 } | 3174 } |
3227 } | 3175 } |
3228 | 3176 |
3229 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( | 3177 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( |
3230 const std::vector<AudioCodec>& new_codecs) { | 3178 const std::vector<AudioCodec>& new_codecs) { |
3231 for (const AudioCodec& codec : new_codecs) { | 3179 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
3180 for (const auto& codec : new_codecs) { | |
3232 webrtc::CodecInst voe_codec; | 3181 webrtc::CodecInst voe_codec; |
3233 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { | 3182 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { |
3234 LOG(LS_INFO) << ToString(codec); | 3183 LOG(LS_INFO) << ToString(codec); |
3235 voe_codec.pltype = codec.id; | 3184 voe_codec.pltype = codec.id; |
3236 if (default_receive_ssrc_ == 0) { | |
3237 // Set the receive codecs on the default channel explicitly if the | |
3238 // default channel is not used by |receive_channels_|, this happens in | |
3239 // conference mode or in non-conference mode when there is no playout | |
3240 // channel. | |
3241 // TODO(xians): Figure out how we use the default channel in conference | |
3242 // mode. | |
3243 if (engine()->voe()->codec()->SetRecPayloadType( | |
3244 voe_channel(), voe_codec) == -1) { | |
3245 LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec)); | |
3246 return false; | |
3247 } | |
3248 } | |
3249 | |
3250 // Set the receive codecs on all receiving channels. | |
3251 for (const auto& ch : receive_channels_) { | 3185 for (const auto& ch : receive_channels_) { |
3252 if (engine()->voe()->codec()->SetRecPayloadType( | 3186 if (engine()->voe()->codec()->SetRecPayloadType( |
3253 ch.second->channel(), voe_codec) == -1) { | 3187 ch.second->channel(), voe_codec) == -1) { |
3254 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), | 3188 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), |
3255 ToString(voe_codec)); | 3189 ToString(voe_codec)); |
3256 return false; | 3190 return false; |
3257 } | 3191 } |
3258 } | 3192 } |
3259 } else { | 3193 } else { |
3260 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 3194 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
3261 return false; | 3195 return false; |
3262 } | 3196 } |
3263 } | 3197 } |
3264 return true; | 3198 return true; |
3265 } | 3199 } |
3266 | 3200 |
3267 } // namespace cricket | 3201 } // namespace cricket |
3268 | 3202 |
3269 #endif // HAVE_WEBRTC_VOICE | 3203 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |