Chromium Code Reviews| 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 |