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

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: fix tests 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
« no previous file with comments | « talk/media/webrtc/webrtcvoiceengine.h ('k') | talk/media/webrtc/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
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
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());
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « talk/media/webrtc/webrtcvoiceengine.h ('k') | talk/media/webrtc/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698