Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(365)

Side by Side Diff: talk/media/webrtc/webrtcvoiceengine.cc

Issue 1315903004: ABANDONED: Remove the default receive channel in WVoE. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@mediacontroller
Patch Set: test Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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) {
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
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
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
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());
pthatcher1 2015/10/02 02:33:31 This is called in the following methods: WebRtcVo
the sun 2015/10/02 11:34:19 Done.
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 // TODO(solenberg): !!!!!!
1496 SetRecvOptions(voe_channel());
pthatcher1 2015/10/02 02:33:31 Why do we have to call SetRecvOptions with the def
the sun 2015/10/02 11:34:20 Sorry; debugging left overs.
1497 for (const auto& ch : receive_channels_) {
1498 if (!SetRecvOptions(ch.second->channel())) {
1499 return false;
1500 }
1501 }
1502 if (dscp_option_changed) {
1503 rtc::DiffServCodePoint dscp = rtc::DSCP_DEFAULT;
1504 if (options_.dscp.GetWithDefaultIfUnset(false))
1505 dscp = kAudioDscpValue;
1506 if (MediaChannel::SetDscp(dscp) != 0) {
1507 LOG(LS_WARNING) << "Failed to set DSCP settings for audio channel";
1508 }
1509 }
1510
1511 RecreateAudioReceiveStreams();
1512
1513 LOG(LS_INFO) << "Set voice channel options. Current options: "
1514 << options_.ToString();
1515 return true;
1516 }
1517
1518 bool WebRtcVoiceMediaChannel::SetRecvOptions(int channel_id) {
pthatcher1 2015/10/02 02:33:31 Can you please pass option into here as well?
the sun 2015/10/02 11:34:20 Done.
1519 RTC_DCHECK(thread_checker_.CalledOnValidThread());
1520
1489 // Receiver-side auto gain control happens per channel, so set it here from 1521 // 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 1522 // 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 1523 // 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; 1524 bool rx_auto_gain_control;
1494 if (options.rx_auto_gain_control.Get(&rx_auto_gain_control)) { 1525 if (options_.rx_auto_gain_control.Get(&rx_auto_gain_control)) {
1495 if (engine()->voe()->processing()->SetRxAgcStatus( 1526 if (engine()->voe()->processing()->SetRxAgcStatus(
1496 voe_channel(), rx_auto_gain_control, 1527 channel_id, rx_auto_gain_control,
1497 webrtc::kAgcFixedDigital) == -1) { 1528 webrtc::kAgcFixedDigital) == -1) {
1498 LOG_RTCERR1(SetRxAgcStatus, rx_auto_gain_control); 1529 LOG_RTCERR1(SetRxAgcStatus, rx_auto_gain_control);
1499 return false; 1530 return false;
1500 } else { 1531 } else {
1501 LOG(LS_VERBOSE) << "Rx auto gain set to " << rx_auto_gain_control 1532 LOG(LS_VERBOSE) << "Rx auto gain set to " << rx_auto_gain_control
1502 << " with mode " << webrtc::kAgcFixedDigital; 1533 << " with mode " << webrtc::kAgcFixedDigital;
1503 } 1534 }
1504 } 1535 }
1505 if (options.rx_agc_target_dbov.IsSet() || 1536 if (options_.rx_agc_target_dbov.IsSet() ||
1506 options.rx_agc_digital_compression_gain.IsSet() || 1537 options_.rx_agc_digital_compression_gain.IsSet() ||
1507 options.rx_agc_limiter.IsSet()) { 1538 options_.rx_agc_limiter.IsSet()) {
1508 webrtc::AgcConfig config; 1539 webrtc::AgcConfig config;
1509 // If only some of the options are being overridden, get the current 1540 // If only some of the options are being overridden, get the current
1510 // settings for the channel and bail if they aren't available. 1541 // settings for the channel and bail if they aren't available.
1511 if (!options.rx_agc_target_dbov.IsSet() || 1542 if (!options_.rx_agc_target_dbov.IsSet() ||
1512 !options.rx_agc_digital_compression_gain.IsSet() || 1543 !options_.rx_agc_digital_compression_gain.IsSet() ||
1513 !options.rx_agc_limiter.IsSet()) { 1544 !options_.rx_agc_limiter.IsSet()) {
1514 if (engine()->voe()->processing()->GetRxAgcConfig( 1545 if (engine()->voe()->processing()->GetRxAgcConfig(
1515 voe_channel(), config) != 0) { 1546 channel_id, config) != 0) {
1516 LOG(LS_ERROR) << "Failed to get default rx agc configuration for " 1547 LOG(LS_ERROR) << "Failed to get default rx agc configuration for "
1517 << "channel " << voe_channel() << ". Since not all rx " 1548 << "channel " << channel_id << ". Since not all rx "
1518 << "agc options are specified, unable to safely set rx " 1549 << "agc options are specified, unable to safely set rx "
1519 << "agc options."; 1550 << "agc options.";
1520 return false; 1551 return false;
1521 } 1552 }
1522 } 1553 }
1523 config.targetLeveldBOv = 1554 config.targetLeveldBOv =
1524 options.rx_agc_target_dbov.GetWithDefaultIfUnset( 1555 options_.rx_agc_target_dbov.GetWithDefaultIfUnset(
1525 config.targetLeveldBOv); 1556 config.targetLeveldBOv);
1526 config.digitalCompressionGaindB = 1557 config.digitalCompressionGaindB =
1527 options.rx_agc_digital_compression_gain.GetWithDefaultIfUnset( 1558 options_.rx_agc_digital_compression_gain.GetWithDefaultIfUnset(
1528 config.digitalCompressionGaindB); 1559 config.digitalCompressionGaindB);
1529 config.limiterEnable = options.rx_agc_limiter.GetWithDefaultIfUnset( 1560 config.limiterEnable = options_.rx_agc_limiter.GetWithDefaultIfUnset(
1530 config.limiterEnable); 1561 config.limiterEnable);
1531 if (engine()->voe()->processing()->SetRxAgcConfig( 1562 if (engine()->voe()->processing()->SetRxAgcConfig(
1532 voe_channel(), config) == -1) { 1563 channel_id, config) == -1) {
1533 LOG_RTCERR4(SetRxAgcConfig, voe_channel(), config.targetLeveldBOv, 1564 LOG_RTCERR4(SetRxAgcConfig, channel_id, config.targetLeveldBOv,
1534 config.digitalCompressionGaindB, config.limiterEnable); 1565 config.digitalCompressionGaindB, config.limiterEnable);
1535 return false; 1566 return false;
1536 } 1567 }
1537 } 1568 }
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; 1569 return true;
1552 } 1570 }
1553 1571
1554 bool WebRtcVoiceMediaChannel::SetRecvCodecs( 1572 bool WebRtcVoiceMediaChannel::SetRecvCodecs(
1555 const std::vector<AudioCodec>& codecs) { 1573 const std::vector<AudioCodec>& codecs) {
1556 // Set the payload types to be used for incoming media. 1574 // Set the payload types to be used for incoming media.
1557 LOG(LS_INFO) << "Setting receive voice codecs:"; 1575 LOG(LS_INFO) << "Setting receive voice codecs:";
1558 1576
1577 std::vector<int> payload_types;
1559 std::vector<AudioCodec> new_codecs; 1578 std::vector<AudioCodec> new_codecs;
1560 // Find all new codecs. We allow adding new codecs but don't allow changing 1579 // 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 1580 // the payload type of codecs that is already configured since we might
1562 // already be receiving packets with that payload type. 1581 // already be receiving packets with that payload type.
1563 for (const AudioCodec& codec : codecs) { 1582 for (const auto& codec : codecs) {
1564 AudioCodec old_codec; 1583 AudioCodec old_codec;
1565 if (FindCodec(recv_codecs_, codec, &old_codec)) { 1584 if (FindCodec(recv_codecs_, codec, &old_codec)) {
1566 if (old_codec.id != codec.id) { 1585 if (old_codec.id != codec.id) {
1567 LOG(LS_ERROR) << codec.name << " payload type changed."; 1586 LOG(LS_ERROR) << codec.name << " payload type changed.";
1568 return false; 1587 return false;
1569 } 1588 }
1570 } else { 1589 } else {
1590 payload_types.push_back(codec.id);
1571 new_codecs.push_back(codec); 1591 new_codecs.push_back(codec);
1572 } 1592 }
1573 } 1593 }
1574 if (new_codecs.empty()) { 1594 if (new_codecs.empty()) {
1575 // There are no new codecs to configure. Already configured codecs are 1595 // There are no new codecs to configure. Already configured codecs are
1576 // never removed. 1596 // never removed.
1577 return true; 1597 return true;
1578 } 1598 }
1579 1599
1600 // Verify no codecs have the same payload type.
pthatcher1 2015/10/02 02:33:31 Can you put this in its own helper function?
the sun 2015/10/02 11:34:20 Done.
1601 std::sort(payload_types.begin(), payload_types.end());
1602 auto it = std::unique(payload_types.begin(), payload_types.end());
1603 if (payload_types.end() != it) {
1604 return false;
1605 }
1606
1580 if (playout_) { 1607 if (playout_) {
1581 // Receive codecs can not be changed while playing. So we temporarily 1608 // Receive codecs can not be changed while playing. So we temporarily
1582 // pause playout. 1609 // pause playout.
1583 PausePlayout(); 1610 PausePlayout();
1584 } 1611 }
1585 1612
1586 bool result = SetRecvCodecsInternal(new_codecs); 1613 bool result = SetRecvCodecsInternal(new_codecs);
1587 if (result) { 1614 if (result) {
1588 recv_codecs_ = codecs; 1615 recv_codecs_ = codecs;
1589 } 1616 }
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 return false; 1824 return false;
1798 } 1825 }
1799 } 1826 }
1800 } 1827 }
1801 } 1828 }
1802 return true; 1829 return true;
1803 } 1830 }
1804 1831
1805 bool WebRtcVoiceMediaChannel::SetSendCodecs( 1832 bool WebRtcVoiceMediaChannel::SetSendCodecs(
1806 const std::vector<AudioCodec>& codecs) { 1833 const std::vector<AudioCodec>& codecs) {
1834 RTC_DCHECK(thread_checker_.CalledOnValidThread());
pthatcher1 2015/10/02 02:33:31 This is called by WebRtcVoiceMediaChannel::SetSe
the sun 2015/10/02 11:34:20 Done.
1807 dtmf_allowed_ = false; 1835 dtmf_allowed_ = false;
1808 for (const AudioCodec& codec : codecs) { 1836 for (const AudioCodec& codec : codecs) {
1809 // Find the DTMF telephone event "codec". 1837 // Find the DTMF telephone event "codec".
1810 if (IsCodec(codec, kDtmfCodecName)) { 1838 if (IsCodec(codec, kDtmfCodecName)) {
1811 dtmf_allowed_ = true; 1839 dtmf_allowed_ = true;
1812 } 1840 }
1813 } 1841 }
1814 1842
1815 // Cache the codecs in order to configure the channel created later. 1843 // Cache the codecs in order to configure the channel created later.
1816 send_codecs_ = codecs; 1844 send_codecs_ = codecs;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 1896
1869 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { 1897 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) {
1870 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); 1898 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec));
1871 return false; 1899 return false;
1872 } 1900 }
1873 return true; 1901 return true;
1874 } 1902 }
1875 1903
1876 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions( 1904 bool WebRtcVoiceMediaChannel::SetRecvRtpHeaderExtensions(
1877 const std::vector<RtpHeaderExtension>& extensions) { 1905 const std::vector<RtpHeaderExtension>& extensions) {
1906 RTC_DCHECK(thread_checker_.CalledOnValidThread());
pthatcher1 2015/10/02 02:33:31 This is called by WebRtcVoiceMediaChannel::SetRecv
the sun 2015/10/02 11:34:19 Done.
1878 if (receive_extensions_ == extensions) { 1907 if (receive_extensions_ == extensions) {
1879 return true; 1908 return true;
1880 } 1909 }
1881 1910
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_) { 1911 for (const auto& ch : receive_channels_) {
1890 if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) { 1912 if (!SetChannelRecvRtpHeaderExtensions(ch.second->channel(), extensions)) {
1891 return false; 1913 return false;
1892 } 1914 }
1893 } 1915 }
1894 1916
1895 receive_extensions_ = extensions; 1917 receive_extensions_ = extensions;
1896 1918
1897 // Recreate AudioReceiveStream:s. 1919 // Recreate AudioReceiveStream:s.
1898 { 1920 {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 2015
1994 bool WebRtcVoiceMediaChannel::PausePlayout() { 2016 bool WebRtcVoiceMediaChannel::PausePlayout() {
1995 return ChangePlayout(false); 2017 return ChangePlayout(false);
1996 } 2018 }
1997 2019
1998 bool WebRtcVoiceMediaChannel::ResumePlayout() { 2020 bool WebRtcVoiceMediaChannel::ResumePlayout() {
1999 return ChangePlayout(desired_playout_); 2021 return ChangePlayout(desired_playout_);
2000 } 2022 }
2001 2023
2002 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { 2024 bool WebRtcVoiceMediaChannel::ChangePlayout(bool playout) {
2025 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2003 if (playout_ == playout) { 2026 if (playout_ == playout) {
2004 return true; 2027 return true;
2005 } 2028 }
2006 2029
2007 // Change the playout of all channels to the new state. 2030 // Change the playout of all channels to the new state.
2008 bool result = true; 2031 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_) { 2032 for (const auto& ch : receive_channels_) {
2014 if (!SetPlayout(ch.second->channel(), playout)) { 2033 if (!SetPlayout(ch.second->channel(), playout)) {
2015 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel " 2034 LOG(LS_ERROR) << "SetPlayout " << playout << " on channel "
2016 << ch.second->channel() << " failed"; 2035 << ch.second->channel() << " failed";
2017 result = false; 2036 result = false;
2018 break; 2037 break;
2019 } 2038 }
2020 } 2039 }
2021 2040
2022 if (result) { 2041 if (result) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2105 // TODO(ronghuawu): Change this method to return bool. 2124 // TODO(ronghuawu): Change this method to return bool.
2106 void WebRtcVoiceMediaChannel::ConfigureSendChannel(int channel) { 2125 void WebRtcVoiceMediaChannel::ConfigureSendChannel(int channel) {
2107 if (engine()->voe()->network()->RegisterExternalTransport( 2126 if (engine()->voe()->network()->RegisterExternalTransport(
2108 channel, *this) == -1) { 2127 channel, *this) == -1) {
2109 LOG_RTCERR2(RegisterExternalTransport, channel, this); 2128 LOG_RTCERR2(RegisterExternalTransport, channel, this);
2110 } 2129 }
2111 2130
2112 // Enable RTCP (for quality stats and feedback messages) 2131 // Enable RTCP (for quality stats and feedback messages)
2113 EnableRtcp(channel); 2132 EnableRtcp(channel);
2114 2133
2115 // Reset all recv codecs; they will be enabled via SetRecvCodecs.
2116 ResetRecvCodecs(channel);
2117
2118 // Set RTP header extension for the new channel. 2134 // Set RTP header extension for the new channel.
2119 SetChannelSendRtpHeaderExtensions(channel, send_extensions_); 2135 SetChannelSendRtpHeaderExtensions(channel, send_extensions_);
2120 } 2136 }
2121 2137
2122 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { 2138 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) {
2123 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { 2139 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) {
2124 LOG_RTCERR1(DeRegisterExternalTransport, channel); 2140 LOG_RTCERR1(DeRegisterExternalTransport, channel);
2125 } 2141 }
2126 2142
2127 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { 2143 if (engine()->voe()->base()->DeleteChannel(channel) == -1) {
2128 LOG_RTCERR1(DeleteChannel, channel); 2144 LOG_RTCERR1(DeleteChannel, channel);
2129 return false; 2145 return false;
2130 } 2146 }
2131 2147
2132 return true; 2148 return true;
2133 } 2149 }
2134 2150
2135 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { 2151 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) {
2152 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2136 // If the default channel is already used for sending create a new channel 2153 // If the default channel is already used for sending create a new channel
2137 // otherwise use the default channel for sending. 2154 // otherwise use the default channel for sending.
2138 int channel = GetSendChannelNum(sp.first_ssrc()); 2155 int channel = GetSendChannelNum(sp.first_ssrc());
2139 if (channel != -1) { 2156 if (channel != -1) {
2140 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); 2157 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc();
2141 return false; 2158 return false;
2142 } 2159 }
2143 2160
2144 bool default_channel_is_available = true; 2161 bool default_channel_is_available = true;
2145 for (const auto& ch : send_channels_) { 2162 for (const auto& ch : send_channels_) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc()); 2194 LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc());
2178 return false; 2195 return false;
2179 } 2196 }
2180 2197
2181 // At this point the channel's local SSRC has been updated. If the channel is 2198 // 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 2199 // 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 2200 // well. Receive channels have to have the same SSRC as the default channel in
2184 // order to send receiver reports with this SSRC. 2201 // order to send receiver reports with this SSRC.
2185 if (IsDefaultChannel(channel)) { 2202 if (IsDefaultChannel(channel)) {
2186 for (const auto& ch : receive_channels_) { 2203 for (const auto& ch : receive_channels_) {
2187 // Only update the SSRC for non-default channels. 2204 if (engine()->voe()->rtp()->SetLocalSSRC(ch.second->channel(),
2188 if (!IsDefaultChannel(ch.second->channel())) { 2205 sp.first_ssrc()) != 0) {
2189 if (engine()->voe()->rtp()->SetLocalSSRC(ch.second->channel(), 2206 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), sp.first_ssrc());
2190 sp.first_ssrc()) != 0) { 2207 return false;
2191 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), sp.first_ssrc());
2192 return false;
2193 }
2194 } 2208 }
2195 } 2209 }
2196 } 2210 }
2197 2211
2198 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { 2212 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) {
2199 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); 2213 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname);
2200 return false; 2214 return false;
2201 } 2215 }
2202 2216
2203 // Set the current codecs to be used for the new channel. 2217 // Set the current codecs to be used for the new channel.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 } 2250 }
2237 2251
2238 if (send_channels_.empty()) 2252 if (send_channels_.empty())
2239 ChangeSend(SEND_NOTHING); 2253 ChangeSend(SEND_NOTHING);
2240 2254
2241 return true; 2255 return true;
2242 } 2256 }
2243 2257
2244 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { 2258 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) {
2245 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 2259 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2246 rtc::CritScope lock(&receive_channels_cs_); 2260 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString();
2247 2261
2248 if (!VERIFY(sp.ssrcs.size() == 1)) 2262 if (!ValidateStreamParams(sp)) {
2249 return false; 2263 return false;
2264 }
2265
2250 uint32 ssrc = sp.first_ssrc(); 2266 uint32 ssrc = sp.first_ssrc();
2267 if (ssrc == 0) {
2268 LOG(LS_WARNING) << "AddRecvStream with ssrc==0 is not supported.";
2269 return false;
2270 }
2251 2271
2252 if (ssrc == 0) { 2272 // Remove the default receive stream if one had been created with this ssrc;
2253 LOG(LS_WARNING) << "AddRecvStream with 0 ssrc is not supported."; 2273 // we'll recreate it then.
2254 return false; 2274 if (-1 != default_recv_channel_id_ && ssrc == default_recv_ssrc_) {
2275 RemoveRecvStream(ssrc);
pthatcher1 2015/10/02 02:33:30 Why remove it and re-add it? Why not just keep us
the sun 2015/10/02 11:34:19 Because we need to recreate the AudioReceiveStream
2255 } 2276 }
2256 2277
2257 if (receive_channels_.find(ssrc) != receive_channels_.end()) { 2278 if (receive_channels_.find(ssrc) != receive_channels_.end()) {
2258 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; 2279 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc;
2259 return false; 2280 return false;
2260 } 2281 }
2261
2262 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); 2282 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end());
2263 2283
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. 2284 // Create a new channel for receiving audio data.
2280 int channel = engine()->CreateMediaVoiceChannel(); 2285 int channel = engine()->CreateMediaVoiceChannel();
2281 if (channel == -1) { 2286 if (channel == -1) {
2282 LOG_RTCERR0(CreateChannel); 2287 LOG_RTCERR0(CreateChannel);
2283 return false; 2288 return false;
2284 } 2289 }
2285
2286 if (!ConfigureRecvChannel(channel)) { 2290 if (!ConfigureRecvChannel(channel)) {
2287 DeleteChannel(channel); 2291 DeleteChannel(channel);
2288 return false; 2292 return false;
2289 } 2293 }
2290 2294
2295 webrtc::AudioTransport* audio_transport =
2296 engine()->voe()->base()->audio_transport();
2291 WebRtcVoiceChannelRenderer* channel_renderer = 2297 WebRtcVoiceChannelRenderer* channel_renderer =
2292 new WebRtcVoiceChannelRenderer(channel, audio_transport); 2298 new WebRtcVoiceChannelRenderer(channel, audio_transport);
2293 receive_channels_.insert(std::make_pair(ssrc, channel_renderer)); 2299 receive_channels_.insert(std::make_pair(ssrc, channel_renderer));
2294 receive_stream_params_[ssrc] = sp; 2300 receive_stream_params_[ssrc] = sp;
2295 AddAudioReceiveStream(ssrc); 2301 AddAudioReceiveStream(ssrc);
2296 2302
2297 LOG(LS_INFO) << "New audio stream " << ssrc 2303 LOG(LS_INFO) << "New audio stream " << ssrc
2298 << " registered to VoiceEngine channel #" 2304 << " registered to VoiceEngine channel #"
2299 << channel << "."; 2305 << channel << ".";
2300 return true; 2306 return true;
2301 } 2307 }
2302 2308
2303 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { 2309 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) {
2304 // Configure to use external transport, like our default channel. 2310 // Configure to use external transport.
2305 if (engine()->voe()->network()->RegisterExternalTransport( 2311 if (engine()->voe()->network()->RegisterExternalTransport(
2306 channel, *this) == -1) { 2312 channel, *this) == -1) {
2307 LOG_RTCERR2(SetExternalTransport, channel, this); 2313 LOG_RTCERR2(SetExternalTransport, channel, this);
2308 return false; 2314 return false;
2309 } 2315 }
2310 2316
2311 // Use the same SSRC as our default channel (so the RTCP reports are correct). 2317 if (!SetRecvOptions(channel)) {
2318 return false;
2319 }
2320
2321 // Use the same SSRC as our default (send) channel, so the RTCP reports are
2322 // correct.
2312 unsigned int send_ssrc = 0; 2323 unsigned int send_ssrc = 0;
2313 webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp(); 2324 webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp();
2314 if (rtp->GetLocalSSRC(voe_channel(), send_ssrc) == -1) { 2325 if (rtp->GetLocalSSRC(voe_channel(), send_ssrc) == -1) {
2315 LOG_RTCERR1(GetSendSSRC, channel); 2326 LOG_RTCERR1(GetSendSSRC, channel);
2316 return false; 2327 return false;
2317 } 2328 }
2318 if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) { 2329 if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) {
2319 LOG_RTCERR1(SetSendSSRC, channel); 2330 LOG_RTCERR1(SetSendSSRC, channel);
2320 return false; 2331 return false;
2321 } 2332 }
2322 2333
2323 // Associate receive channel to default channel (so the receive channel can 2334 // Associate receive channel to default send channel (so the receive channel
2324 // obtain RTT from the send channel) 2335 // can obtain RTT from the send channel)
2325 engine()->voe()->base()->AssociateSendChannel(channel, voe_channel()); 2336 engine()->voe()->base()->AssociateSendChannel(channel, voe_channel());
2326 LOG(LS_INFO) << "VoiceEngine channel #" 2337 LOG(LS_INFO) << "VoiceEngine channel #"
2327 << channel << " is associated with channel #" 2338 << channel << " is associated with channel #"
2328 << voe_channel() << "."; 2339 << voe_channel() << ".";
2329 2340
2330 // Use the same recv payload types as our default channel. 2341 // Turn off all supported codecs.
pthatcher1 2015/10/02 02:33:30 I like this in a helper method. But instead "Rese
the sun 2015/10/02 11:34:20 Personally I have a problem with "helper" methods.
2331 ResetRecvCodecs(channel); 2342 int ncodecs = engine()->voe()->codec()->NumOfCodecs();
2332 if (!recv_codecs_.empty()) { 2343 for (int i = 0; i < ncodecs; ++i) {
2333 for (const auto& codec : recv_codecs_) { 2344 webrtc::CodecInst voe_codec;
2334 webrtc::CodecInst voe_codec; 2345 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) {
2335 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { 2346 voe_codec.pltype = -1;
2336 voe_codec.pltype = codec.id; 2347 if (engine()->voe()->codec()->SetRecPayloadType(
2337 voe_codec.rate = 0; // Needed to make GetRecPayloadType work for ISAC 2348 channel, voe_codec) == -1) {
2338 if (engine()->voe()->codec()->GetRecPayloadType( 2349 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
2339 voe_channel(), voe_codec) != -1) { 2350 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 } 2351 }
2347 } 2352 }
2348 } 2353 }
2349 2354
2350 if (InConferenceMode()) { 2355 // Only enable those configured for this channel.
2351 // To be in par with the video, voe_channel() is not used for receiving in 2356 for (const auto& codec : recv_codecs_) {
2352 // a conference call. 2357 webrtc::CodecInst voe_codec;
2353 if (receive_channels_.empty() && default_receive_ssrc_ == 0 && playout_) { 2358 if (engine()->FindWebRtcCodec(codec, &voe_codec)) {
2354 // This is the first stream in a multi user meeting. We can now 2359 voe_codec.pltype = codec.id;
pthatcher1 2015/10/02 02:33:31 Why did you remove .rate = 0?
the sun 2015/10/02 11:34:20 It said in a comment: "// Needed to make GetRecPay
2355 // disable playback of the default stream. This since the default 2360 if (engine()->voe()->codec()->SetRecPayloadType(
2356 // stream will probably have received some initial packets before 2361 channel, voe_codec) == -1) {
2357 // the new stream was added. This will mean that the CN state from 2362 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
2358 // the default channel will be mixed in with the other streams 2363 return false;
2359 // throughout the whole meeting, which might be disturbing. 2364 }
2360 LOG(LS_INFO) << "Disabling playback on the default voice channel";
2361 SetPlayout(voe_channel(), false);
2362 } 2365 }
2363 } 2366 }
2367
2364 SetNack(channel, nack_enabled_); 2368 SetNack(channel, nack_enabled_);
2365 2369
2366 // Set RTP header extension for the new channel. 2370 // Set RTP header extension for the new channel.
2367 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) { 2371 if (!SetChannelRecvRtpHeaderExtensions(channel, receive_extensions_)) {
2368 return false; 2372 return false;
2369 } 2373 }
2370 2374
2371 return SetPlayout(channel, playout_); 2375 return SetPlayout(channel, playout_);
2372 } 2376 }
2373 2377
2374 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32 ssrc) { 2378 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32 ssrc) {
2375 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 2379 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2376 rtc::CritScope lock(&receive_channels_cs_); 2380 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc;
2381
2377 ChannelMap::iterator it = receive_channels_.find(ssrc); 2382 ChannelMap::iterator it = receive_channels_.find(ssrc);
2378 if (it == receive_channels_.end()) { 2383 if (it == receive_channels_.end()) {
2379 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc 2384 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc
2380 << " which doesn't exist."; 2385 << " which doesn't exist.";
2381 return false; 2386 return false;
2382 } 2387 }
2383 2388
2384 RemoveAudioReceiveStream(ssrc); 2389 RemoveAudioReceiveStream(ssrc);
2385 receive_stream_params_.erase(ssrc); 2390 receive_stream_params_.erase(ssrc);
2386 2391
2387 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, this 2392 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, this
2388 // will disconnect the audio renderer with the receive channel. 2393 // will disconnect the audio renderer with the receive channel.
2389 // Cache the channel before the deletion. 2394 // Cache the channel before the deletion.
2390 const int channel = it->second->channel(); 2395 const int channel = it->second->channel();
2391 delete it->second; 2396 delete it->second;
2392 receive_channels_.erase(it); 2397 receive_channels_.erase(it);
2393 2398
2394 if (ssrc == default_receive_ssrc_) { 2399 // Deregister default channel, if that's the one being destroyed.
2395 RTC_DCHECK(IsDefaultChannel(channel)); 2400 if (-1 != default_recv_channel_id_ && ssrc == default_recv_ssrc_) {
2396 // Recycle the default channel is for recv stream. 2401 RTC_DCHECK(channel == default_recv_channel_id_);
2397 if (playout_) 2402 default_recv_ssrc_ = 0;
2398 SetPlayout(voe_channel(), false); 2403 default_recv_channel_id_ = -1;
2399
2400 default_receive_ssrc_ = 0;
2401 return true;
2402 } 2404 }
2403 2405
2404 LOG(LS_INFO) << "Removing audio stream " << ssrc 2406 LOG(LS_INFO) << "Removing audio stream " << ssrc
2405 << " with VoiceEngine channel #" << channel << "."; 2407 << " with VoiceEngine channel #" << channel << ".";
2406 if (!DeleteChannel(channel)) 2408 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 } 2409 }
2431 2410
2432 bool WebRtcVoiceMediaChannel::SetRemoteRenderer(uint32 ssrc, 2411 bool WebRtcVoiceMediaChannel::SetRemoteRenderer(uint32 ssrc,
2433 AudioRenderer* renderer) { 2412 AudioRenderer* renderer) {
2413 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2434 ChannelMap::iterator it = receive_channels_.find(ssrc); 2414 ChannelMap::iterator it = receive_channels_.find(ssrc);
2435 if (it == receive_channels_.end()) { 2415 if (it == receive_channels_.end()) {
2436 if (renderer) { 2416 if (renderer) {
2437 // Return an error if trying to set a valid renderer with an invalid ssrc. 2417 // Return an error if trying to set a valid renderer with an invalid ssrc.
2438 LOG(LS_ERROR) << "SetRemoteRenderer failed with ssrc "<< ssrc; 2418 LOG(LS_ERROR) << "SetRemoteRenderer failed with ssrc "<< ssrc;
2439 return false; 2419 return false;
2440 } 2420 }
2441 2421
2442 // The channel likely has gone away, do nothing. 2422 // The channel likely has gone away, do nothing.
2443 return true; 2423 return true;
(...skipping 24 matching lines...) Expand all
2468 if (renderer) 2448 if (renderer)
2469 it->second->Start(renderer); 2449 it->second->Start(renderer);
2470 else 2450 else
2471 it->second->Stop(); 2451 it->second->Stop();
2472 2452
2473 return true; 2453 return true;
2474 } 2454 }
2475 2455
2476 bool WebRtcVoiceMediaChannel::GetActiveStreams( 2456 bool WebRtcVoiceMediaChannel::GetActiveStreams(
2477 AudioInfo::StreamList* actives) { 2457 AudioInfo::StreamList* actives) {
2478 // In conference mode, the default channel should not be in 2458 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2479 // |receive_channels_|.
2480 actives->clear(); 2459 actives->clear();
2481 for (const auto& ch : receive_channels_) { 2460 for (const auto& ch : receive_channels_) {
2482 int level = GetOutputLevel(ch.second->channel()); 2461 int level = GetOutputLevel(ch.second->channel());
2483 if (level > 0) { 2462 if (level > 0) {
2484 actives->push_back(std::make_pair(ch.first, level)); 2463 actives->push_back(std::make_pair(ch.first, level));
2485 } 2464 }
2486 } 2465 }
2487 return true; 2466 return true;
2488 } 2467 }
2489 2468
2490 int WebRtcVoiceMediaChannel::GetOutputLevel() { 2469 int WebRtcVoiceMediaChannel::GetOutputLevel() {
2491 // return the highest output level of all streams 2470 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2492 int highest = GetOutputLevel(voe_channel()); 2471 int highest = 0;
2493 for (const auto& ch : receive_channels_) { 2472 for (const auto& ch : receive_channels_) {
2494 int level = GetOutputLevel(ch.second->channel()); 2473 highest = std::max(GetOutputLevel(ch.second->channel()), highest);
2495 highest = std::max(level, highest);
2496 } 2474 }
2497 return highest; 2475 return highest;
2498 } 2476 }
2499 2477
2500 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() { 2478 int WebRtcVoiceMediaChannel::GetTimeSinceLastTyping() {
2501 int ret; 2479 int ret;
2502 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) { 2480 if (engine()->voe()->processing()->TimeSinceLastTyping(ret) == -1) {
2503 // In case of error, log the info and continue 2481 // In case of error, log the info and continue
2504 LOG_RTCERR0(TimeSinceLastTyping); 2482 LOG_RTCERR0(TimeSinceLastTyping);
2505 ret = -1; 2483 ret = -1;
(...skipping 11 matching lines...) Expand all
2517 reporting_threshold, penalty_decay, type_event_delay) == -1) { 2495 reporting_threshold, penalty_decay, type_event_delay) == -1) {
2518 // In case of error, log the info and continue 2496 // In case of error, log the info and continue
2519 LOG_RTCERR5(SetTypingDetectionParameters, time_window, 2497 LOG_RTCERR5(SetTypingDetectionParameters, time_window,
2520 cost_per_typing, reporting_threshold, penalty_decay, 2498 cost_per_typing, reporting_threshold, penalty_decay,
2521 type_event_delay); 2499 type_event_delay);
2522 } 2500 }
2523 } 2501 }
2524 2502
2525 bool WebRtcVoiceMediaChannel::SetOutputScaling( 2503 bool WebRtcVoiceMediaChannel::SetOutputScaling(
2526 uint32 ssrc, double left, double right) { 2504 uint32 ssrc, double left, double right) {
2527 rtc::CritScope lock(&receive_channels_cs_); 2505 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2528 // Collect the channels to scale the output volume. 2506 // Collect channels to scale output volume for (ssrc == 0 means all channels).
pthatcher1 2015/10/02 02:33:31 This "ssrc == 0 means all" was just a GTP thing.
the sun 2015/10/02 11:34:20 But we still need to support "ssrc == 0 means defa
2529 std::vector<int> channels; 2507 std::vector<int> channels;
2530 if (0 == ssrc) { // Collect all channels, including the default one. 2508 for (const auto& ch : receive_channels_) {
2531 // Default channel is not in receive_channels_ if it is not being used for 2509 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()); 2510 channels.push_back(ch.second->channel());
2537 } 2511 }
2538 } else { // Collect only the channel of the specified ssrc. 2512 }
2539 int channel = GetReceiveChannelNum(ssrc); 2513 if (0 != ssrc && channels.empty()) {
2540 if (-1 == channel) { 2514 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc;
2541 LOG(LS_WARNING) << "Cannot find channel for ssrc:" << ssrc; 2515 return false;
2542 return false;
2543 }
2544 channels.push_back(channel);
2545 } 2516 }
2546 2517
2547 // Scale the output volume for the collected channels. We first normalize to 2518 // Scale the output volume for the collected channels. We first normalize to
2548 // scale the volume and then set the left and right pan. 2519 // scale the volume and then set the left and right pan.
2549 float scale = static_cast<float>(std::max(left, right)); 2520 float scale = static_cast<float>(std::max(left, right));
2550 if (scale > 0.0001f) { 2521 if (scale > 0.0001f) {
2551 left /= scale; 2522 left /= scale;
2552 right /= scale; 2523 right /= scale;
2553 } 2524 }
2554 for (int ch_id : channels) { 2525 for (int ch_id : channels) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2621 } 2592 }
2622 } 2593 }
2623 2594
2624 return true; 2595 return true;
2625 } 2596 }
2626 2597
2627 void WebRtcVoiceMediaChannel::OnPacketReceived( 2598 void WebRtcVoiceMediaChannel::OnPacketReceived(
2628 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { 2599 rtc::Buffer* packet, const rtc::PacketTime& packet_time) {
2629 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 2600 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2630 2601
2631 // Forward packet to Call as well. 2602 uint32 ssrc = 0;
2603 if (!GetRtpSsrc(packet->data(), packet->size(), &ssrc)) {
2604 return;
2605 }
2606
2607 if (receive_channels_.empty()) {
2608 // Create new channel, which will be the default receive channel.
2609 StreamParams sp;
2610 sp.ssrcs.push_back(ssrc);
2611 LOG(LS_INFO) << "Creating default receive stream for SSRC=" << ssrc << ".";
2612 if (!AddRecvStream(sp)) {
2613 LOG(LS_WARNING) << "Could not create default receive stream.";
2614 return;
2615 }
2616 default_recv_ssrc_ = ssrc;
2617 default_recv_channel_id_ = receive_channels_[ssrc]->channel();
pthatcher1 2015/10/02 02:33:30 Why not just call GetRecvChannelNum?
the sun 2015/10/02 11:34:19 Done.
2618 RTC_DCHECK(-1 != default_recv_channel_id_);
2619 }
2620
2621 // Forward packet to Call. If the SSRC is unknown we'll return after this.
2632 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, 2622 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp,
2633 packet_time.not_before); 2623 packet_time.not_before);
2634 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, 2624 webrtc::PacketReceiver::DeliveryStatus delivery_result =
2635 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), 2625 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO,
2636 webrtc_packet_time); 2626 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(),
2627 webrtc_packet_time);
2628 if (webrtc::PacketReceiver::DELIVERY_OK != delivery_result) {
2629 return;
2630 }
2637 2631
2638 // Pick which channel to send this packet to. If this packet doesn't match 2632 // 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, 2633 // was able to demux the packet.
2640 // send it to the specific decoder instance for that stream. 2634 int channel = GetReceiveChannelNum(ssrc);
2641 int which_channel = 2635 RTC_DCHECK(channel != -1);
2642 GetReceiveChannelNum(ParseSsrc(packet->data(), packet->size(), false));
2643 if (which_channel == -1) {
2644 which_channel = voe_channel();
2645 }
2646 2636
2647 // Pass it off to the decoder. 2637 // Pass it off to the decoder.
2648 engine()->voe()->network()->ReceivedRTPPacket( 2638 engine()->voe()->network()->ReceivedRTPPacket(
2649 which_channel, packet->data(), packet->size(), 2639 channel, packet->data(), packet->size(), webrtc_packet_time);
2650 webrtc::PacketTime(packet_time.timestamp, packet_time.not_before));
2651 } 2640 }
2652 2641
2653 void WebRtcVoiceMediaChannel::OnRtcpReceived( 2642 void WebRtcVoiceMediaChannel::OnRtcpReceived(
2654 rtc::Buffer* packet, const rtc::PacketTime& packet_time) { 2643 rtc::Buffer* packet, const rtc::PacketTime& packet_time) {
2655 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 2644 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2656 2645
2657 // Forward packet to Call as well. 2646 // Forward packet to Call as well.
2658 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp, 2647 const webrtc::PacketTime webrtc_packet_time(packet_time.timestamp,
2659 packet_time.not_before); 2648 packet_time.not_before);
2660 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO, 2649 call_->Receiver()->DeliverPacket(webrtc::MediaType::AUDIO,
2661 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(), 2650 reinterpret_cast<const uint8_t*>(packet->data()), packet->size(),
2662 webrtc_packet_time); 2651 webrtc_packet_time);
2663 2652
2664 // Sending channels need all RTCP packets with feedback information. 2653 // Sending channels need all RTCP packets with feedback information.
2665 // Even sender reports can contain attached report blocks. 2654 // Even sender reports can contain attached report blocks.
2666 // Receiving channels need sender reports in order to create 2655 // Receiving channels need sender reports in order to create
2667 // correct receiver reports. 2656 // correct receiver reports.
2668 int type = 0; 2657 int type = 0;
2669 if (!GetRtcpType(packet->data(), packet->size(), &type)) { 2658 if (!GetRtcpType(packet->data(), packet->size(), &type)) {
2670 LOG(LS_WARNING) << "Failed to parse type from received RTCP packet"; 2659 LOG(LS_WARNING) << "Failed to parse type from received RTCP packet";
2671 return; 2660 return;
2672 } 2661 }
2673 2662
2674 // If it is a sender report, find the channel that is listening. 2663 // 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) { 2664 if (type == kRtcpTypeSR) {
2677 int which_channel = 2665 uint32 ssrc = 0;
2678 GetReceiveChannelNum(ParseSsrc(packet->data(), packet->size(), true)); 2666 if (!GetRtcpSsrc(packet->data(), packet->size(), &ssrc)) {
2679 if (which_channel != -1) { 2667 return;
2668 }
2669 int channel = GetReceiveChannelNum(ssrc);
pthatcher1 2015/10/02 02:33:31 Should this be recv_channel_id to be consistent?
the sun 2015/10/02 11:34:20 Done.
2670 if (channel != -1) {
2680 engine()->voe()->network()->ReceivedRTCPPacket( 2671 engine()->voe()->network()->ReceivedRTCPPacket(
2681 which_channel, packet->data(), packet->size()); 2672 channel, packet->data(), packet->size());
2682
2683 if (IsDefaultChannel(which_channel))
2684 has_sent_to_default_channel = true;
2685 } 2673 }
2686 } 2674 }
2687 2675
2688 // SR may continue RR and any RR entry may correspond to any one of the send 2676 // 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 2677 // channels. So all RTCP packets must be forwarded all send channels. VoE
2690 // will filter out RR internally. 2678 // will filter out RR internally.
2691 for (const auto& ch : send_channels_) { 2679 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( 2680 engine()->voe()->network()->ReceivedRTCPPacket(
2698 ch.second->channel(), packet->data(), packet->size()); 2681 ch.second->channel(), packet->data(), packet->size());
2699 } 2682 }
2700 } 2683 }
2701 2684
2702 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) { 2685 bool WebRtcVoiceMediaChannel::MuteStream(uint32 ssrc, bool muted) {
2703 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc); 2686 int channel = (ssrc == 0) ? voe_channel() : GetSendChannelNum(ssrc);
2704 if (channel == -1) { 2687 if (channel == -1) {
2705 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; 2688 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use.";
2706 return false; 2689 return false;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2777 LOG(LS_INFO) << "Failed to set codec " << codec.plname 2760 LOG(LS_INFO) << "Failed to set codec " << codec.plname
2778 << " to bitrate " << bps << " bps" 2761 << " to bitrate " << bps << " bps"
2779 << ", requires at least " << codec.rate << " bps."; 2762 << ", requires at least " << codec.rate << " bps.";
2780 return false; 2763 return false;
2781 } 2764 }
2782 return true; 2765 return true;
2783 } 2766 }
2784 } 2767 }
2785 2768
2786 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { 2769 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) {
2770 RTC_DCHECK(thread_checker_.CalledOnValidThread());
2771
2787 bool echo_metrics_on = false; 2772 bool echo_metrics_on = false;
2788 // These can take on valid negative values, so use the lowest possible level 2773 // These can take on valid negative values, so use the lowest possible level
2789 // as default rather than -1. 2774 // as default rather than -1.
2790 int echo_return_loss = -100; 2775 int echo_return_loss = -100;
2791 int echo_return_loss_enhancement = -100; 2776 int echo_return_loss_enhancement = -100;
2792 // These can also be negative, but in practice -1 is only used to signal 2777 // 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. 2778 // insufficient data, since the resolution is limited to multiples of 4 ms.
2794 int echo_delay_median_ms = -1; 2779 int echo_delay_median_ms = -1;
2795 int echo_delay_std_ms = -1; 2780 int echo_delay_std_ms = -1;
2796 if (engine()->voe()->processing()->GetEcMetricsStatus( 2781 if (engine()->voe()->processing()->GetEcMetricsStatus(
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement; 2863 sinfo.echo_return_loss_enhancement = echo_return_loss_enhancement;
2879 sinfo.echo_delay_median_ms = echo_delay_median_ms; 2864 sinfo.echo_delay_median_ms = echo_delay_median_ms;
2880 sinfo.echo_delay_std_ms = echo_delay_std_ms; 2865 sinfo.echo_delay_std_ms = echo_delay_std_ms;
2881 // TODO(ajm): Re-enable this metric once we have a reliable implementation. 2866 // TODO(ajm): Re-enable this metric once we have a reliable implementation.
2882 sinfo.aec_quality_min = -1; 2867 sinfo.aec_quality_min = -1;
2883 sinfo.typing_noise_detected = typing_noise_detected_; 2868 sinfo.typing_noise_detected = typing_noise_detected_;
2884 2869
2885 info->senders.push_back(sinfo); 2870 info->senders.push_back(sinfo);
2886 } 2871 }
2887 2872
2888 // Build the list of receivers, one for each receiving channel, or 1 in 2873 // 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_) { 2874 for (const auto& ch : receive_channels_) {
2892 channels.push_back(ch.second->channel()); 2875 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)); 2876 memset(&cs, 0, sizeof(cs));
2901 if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 && 2877 if (engine()->voe()->rtp()->GetRemoteSSRC(ch_id, ssrc) != -1 &&
2902 engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 && 2878 engine()->voe()->rtp()->GetRTCPStatistics(ch_id, cs) != -1 &&
2903 engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) { 2879 engine()->voe()->codec()->GetRecCodec(ch_id, codec) != -1) {
2904 VoiceReceiverInfo rinfo; 2880 VoiceReceiverInfo rinfo;
2905 rinfo.add_ssrc(ssrc); 2881 rinfo.add_ssrc(ssrc);
2906 rinfo.bytes_rcvd = cs.bytesReceived; 2882 rinfo.bytes_rcvd = cs.bytesReceived;
2907 rinfo.packets_rcvd = cs.packetsReceived; 2883 rinfo.packets_rcvd = cs.packetsReceived;
2908 // The next four fields are from the most recently sent RTCP report. 2884 // The next four fields are from the most recently sent RTCP report.
2909 // Convert Q8 to floating point. 2885 // Convert Q8 to floating point.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2964 rinfo.audio_level = (engine()->voe()->volume()-> 2940 rinfo.audio_level = (engine()->voe()->volume()->
2965 GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1; 2941 GetSpeechOutputLevelFullRange(ch_id, level) != -1) ? level : -1;
2966 info->receivers.push_back(rinfo); 2942 info->receivers.push_back(rinfo);
2967 } 2943 }
2968 } 2944 }
2969 2945
2970 return true; 2946 return true;
2971 } 2947 }
2972 2948
2973 bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) { 2949 bool WebRtcVoiceMediaChannel::FindSsrc(int channel_num, uint32* ssrc) {
2974 rtc::CritScope lock(&receive_channels_cs_); 2950 RTC_DCHECK(thread_checker_.CalledOnValidThread());
pthatcher1 2015/10/02 02:33:31 This is called by WebRtcVoiceEngine::CallbackOnErr
the sun 2015/10/02 11:34:20 Good point. Actually, AFAICT VoE only calls Callba
2975 RTC_DCHECK(ssrc != NULL); 2951 RTC_DCHECK(ssrc != NULL);
2976 if (channel_num == -1 && send_ != SEND_NOTHING) { 2952 if (channel_num == -1 && send_ != SEND_NOTHING) {
2977 // Sometimes the VoiceEngine core will throw error with channel_num = -1. 2953 // Sometimes the VoiceEngine core will throw error with channel_num = -1.
2978 // This means the error is not limited to a specific channel. Signal the 2954 // This means the error is not limited to a specific channel. Signal the
2979 // message using ssrc=0. If the current channel is sending, use this 2955 // message using ssrc=0. If the current channel is sending, use this
2980 // channel for sending the message. 2956 // channel for sending the message.
2981 *ssrc = 0; 2957 *ssrc = 0;
2982 return true; 2958 return true;
2983 } else { 2959 } else {
2984 // Check whether this is a sending channel. 2960 // Check whether this is a sending channel.
(...skipping 28 matching lines...) Expand all
3013 } 2989 }
3014 } 2990 }
3015 2991
3016 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) { 2992 int WebRtcVoiceMediaChannel::GetOutputLevel(int channel) {
3017 unsigned int ulevel; 2993 unsigned int ulevel;
3018 int ret = 2994 int ret =
3019 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel); 2995 engine()->voe()->volume()->GetSpeechOutputLevel(channel, ulevel);
3020 return (ret == 0) ? static_cast<int>(ulevel) : -1; 2996 return (ret == 0) ? static_cast<int>(ulevel) : -1;
3021 } 2997 }
3022 2998
3023 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const { 2999 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) const {
pthatcher1 2015/10/02 02:33:31 Can you rename this GetReceiveChannelId?
the sun 2015/10/02 11:34:19 Yes, also renamed GetSendChannelNum() similarly.
3000 RTC_DCHECK(thread_checker_.CalledOnValidThread());
3024 ChannelMap::const_iterator it = receive_channels_.find(ssrc); 3001 ChannelMap::const_iterator it = receive_channels_.find(ssrc);
3025 if (it != receive_channels_.end()) 3002 if (it != receive_channels_.end())
3026 return it->second->channel(); 3003 return it->second->channel();
3027 return (ssrc == default_receive_ssrc_) ? voe_channel() : -1; 3004 return -1;
3028 } 3005 }
3029 3006
3030 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const { 3007 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) const {
3031 ChannelMap::const_iterator it = send_channels_.find(ssrc); 3008 ChannelMap::const_iterator it = send_channels_.find(ssrc);
3032 if (it != send_channels_.end()) 3009 if (it != send_channels_.end())
3033 return it->second->channel(); 3010 return it->second->channel();
3034
3035 return -1; 3011 return -1;
3036 } 3012 }
3037 3013
3038 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec, 3014 bool WebRtcVoiceMediaChannel::GetRedSendCodec(const AudioCodec& red_codec,
3039 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) { 3015 const std::vector<AudioCodec>& all_codecs, webrtc::CodecInst* send_codec) {
3040 // Get the RED encodings from the parameter with no name. This may 3016 // Get the RED encodings from the parameter with no name. This may
3041 // change based on what is discussed on the Jingle list. 3017 // change based on what is discussed on the Jingle list.
3042 // The encoding parameter is of the form "a/b"; we only support where 3018 // The encoding parameter is of the form "a/b"; we only support where
3043 // a == b. Verify this and parse out the value into red_pt. 3019 // a == b. Verify this and parse out the value into red_pt.
3044 // If the parameter value is absent (as it will be until we wire up the 3020 // 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
3084 LOG_RTCERR2(SetRTCPStatus, channel, 1); 3060 LOG_RTCERR2(SetRTCPStatus, channel, 1);
3085 return false; 3061 return false;
3086 } 3062 }
3087 // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what 3063 // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what
3088 // what we want to do with them. 3064 // what we want to do with them.
3089 // engine()->voe().EnableVQMon(voe_channel(), true); 3065 // engine()->voe().EnableVQMon(voe_channel(), true);
3090 // engine()->voe().EnableRTCP_XR(voe_channel(), true); 3066 // engine()->voe().EnableRTCP_XR(voe_channel(), true);
3091 return true; 3067 return true;
3092 } 3068 }
3093 3069
3094 bool WebRtcVoiceMediaChannel::ResetRecvCodecs(int channel) {
3095 int ncodecs = engine()->voe()->codec()->NumOfCodecs();
3096 for (int i = 0; i < ncodecs; ++i) {
3097 webrtc::CodecInst voe_codec;
3098 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) {
3099 voe_codec.pltype = -1;
3100 if (engine()->voe()->codec()->SetRecPayloadType(
3101 channel, voe_codec) == -1) {
3102 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec));
3103 return false;
3104 }
3105 }
3106 }
3107 return true;
3108 }
3109
3110 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { 3070 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) {
3111 if (playout) { 3071 if (playout) {
3112 LOG(LS_INFO) << "Starting playout for channel #" << channel; 3072 LOG(LS_INFO) << "Starting playout for channel #" << channel;
3113 if (engine()->voe()->base()->StartPlayout(channel) == -1) { 3073 if (engine()->voe()->base()->StartPlayout(channel) == -1) {
3114 LOG_RTCERR1(StartPlayout, channel); 3074 LOG_RTCERR1(StartPlayout, channel);
3115 return false; 3075 return false;
3116 } 3076 }
3117 } else { 3077 } else {
3118 LOG(LS_INFO) << "Stopping playout for channel #" << channel; 3078 LOG(LS_INFO) << "Stopping playout for channel #" << channel;
3119 engine()->voe()->base()->StopPlayout(channel); 3079 engine()->voe()->base()->StopPlayout(channel);
3120 } 3080 }
3121 return true; 3081 return true;
3122 } 3082 }
3123 3083
3124 uint32 WebRtcVoiceMediaChannel::ParseSsrc(const void* data, size_t len,
3125 bool rtcp) {
3126 size_t ssrc_pos = (!rtcp) ? 8 : 4;
3127 uint32 ssrc = 0;
3128 if (len >= (ssrc_pos + sizeof(ssrc))) {
3129 ssrc = rtc::GetBE32(static_cast<const char*>(data) + ssrc_pos);
3130 }
3131 return ssrc;
3132 }
3133
3134 // Convert VoiceEngine error code into VoiceMediaChannel::Error enum. 3084 // Convert VoiceEngine error code into VoiceMediaChannel::Error enum.
3135 VoiceMediaChannel::Error 3085 VoiceMediaChannel::Error
3136 WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) { 3086 WebRtcVoiceMediaChannel::WebRtcErrorToChannelError(int err_code) {
3137 switch (err_code) { 3087 switch (err_code) {
3138 case 0: 3088 case 0:
3139 return ERROR_NONE; 3089 return ERROR_NONE;
3140 case VE_CANNOT_START_RECORDING: 3090 case VE_CANNOT_START_RECORDING:
3141 case VE_MIC_VOL_ERROR: 3091 case VE_MIC_VOL_ERROR:
3142 case VE_GET_MIC_VOL_ERROR: 3092 case VE_GET_MIC_VOL_ERROR:
3143 case VE_CANNOT_ACCESS_MIC_VOL: 3093 case VE_CANNOT_ACCESS_MIC_VOL:
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3212 RTC_DCHECK(thread_checker_.CalledOnValidThread()); 3162 RTC_DCHECK(thread_checker_.CalledOnValidThread());
3213 auto stream_it = receive_streams_.find(ssrc); 3163 auto stream_it = receive_streams_.find(ssrc);
3214 if (stream_it != receive_streams_.end()) { 3164 if (stream_it != receive_streams_.end()) {
3215 call_->DestroyAudioReceiveStream(stream_it->second); 3165 call_->DestroyAudioReceiveStream(stream_it->second);
3216 receive_streams_.erase(stream_it); 3166 receive_streams_.erase(stream_it);
3217 } 3167 }
3218 } 3168 }
3219 3169
3220 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal( 3170 bool WebRtcVoiceMediaChannel::SetRecvCodecsInternal(
3221 const std::vector<AudioCodec>& new_codecs) { 3171 const std::vector<AudioCodec>& new_codecs) {
3222 for (const AudioCodec& codec : new_codecs) { 3172 RTC_DCHECK(thread_checker_.CalledOnValidThread());
pthatcher1 2015/10/02 02:33:30 This is called by WebRtcVoiceMediaChannel::SetRec
the sun 2015/10/02 11:34:20 Done.
3173 for (const auto& codec : new_codecs) {
pthatcher1 2015/10/02 02:33:30 I prefer having the (non-auto) type on for loops
the sun 2015/10/02 11:34:20 Done.
3223 webrtc::CodecInst voe_codec; 3174 webrtc::CodecInst voe_codec;
3224 if (engine()->FindWebRtcCodec(codec, &voe_codec)) { 3175 if (engine()->FindWebRtcCodec(codec, &voe_codec)) {
3225 LOG(LS_INFO) << ToString(codec); 3176 LOG(LS_INFO) << ToString(codec);
3226 voe_codec.pltype = codec.id; 3177 voe_codec.pltype = codec.id;
3227 if (default_receive_ssrc_ == 0) {
3228 // Set the receive codecs on the default channel explicitly if the
3229 // default channel is not used by |receive_channels_|, this happens in
3230 // conference mode or in non-conference mode when there is no playout
3231 // channel.
3232 // TODO(xians): Figure out how we use the default channel in conference
3233 // mode.
3234 if (engine()->voe()->codec()->SetRecPayloadType(
3235 voe_channel(), voe_codec) == -1) {
3236 LOG_RTCERR2(SetRecPayloadType, voe_channel(), ToString(voe_codec));
3237 return false;
3238 }
3239 }
3240
3241 // Set the receive codecs on all receiving channels.
3242 for (const auto& ch : receive_channels_) { 3178 for (const auto& ch : receive_channels_) {
3243 if (engine()->voe()->codec()->SetRecPayloadType( 3179 if (engine()->voe()->codec()->SetRecPayloadType(
3244 ch.second->channel(), voe_codec) == -1) { 3180 ch.second->channel(), voe_codec) == -1) {
3245 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), 3181 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(),
3246 ToString(voe_codec)); 3182 ToString(voe_codec));
3247 return false; 3183 return false;
3248 } 3184 }
3249 } 3185 }
3250 } else { 3186 } else {
3251 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); 3187 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
3252 return false; 3188 return false;
3253 } 3189 }
3254 } 3190 }
3255 return true; 3191 return true;
3256 } 3192 }
3257 3193
3258 } // namespace cricket 3194 } // namespace cricket
3259 3195
3260 #endif // HAVE_WEBRTC_VOICE 3196 #endif // HAVE_WEBRTC_VOICE
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698