OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... | |
31 #include "webrtc/base/trace_event.h" | 31 #include "webrtc/base/trace_event.h" |
32 #include "webrtc/media/base/audiosource.h" | 32 #include "webrtc/media/base/audiosource.h" |
33 #include "webrtc/media/base/mediaconstants.h" | 33 #include "webrtc/media/base/mediaconstants.h" |
34 #include "webrtc/media/base/streamparams.h" | 34 #include "webrtc/media/base/streamparams.h" |
35 #include "webrtc/media/engine/apm_helpers.h" | 35 #include "webrtc/media/engine/apm_helpers.h" |
36 #include "webrtc/media/engine/payload_type_mapper.h" | 36 #include "webrtc/media/engine/payload_type_mapper.h" |
37 #include "webrtc/media/engine/webrtcmediaengine.h" | 37 #include "webrtc/media/engine/webrtcmediaengine.h" |
38 #include "webrtc/media/engine/webrtcvoe.h" | 38 #include "webrtc/media/engine/webrtcvoe.h" |
39 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" | 39 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" |
40 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" | 40 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" |
41 #include "webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory.h" | |
41 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 42 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
42 #include "webrtc/system_wrappers/include/field_trial.h" | 43 #include "webrtc/system_wrappers/include/field_trial.h" |
43 #include "webrtc/system_wrappers/include/metrics.h" | 44 #include "webrtc/system_wrappers/include/metrics.h" |
44 #include "webrtc/system_wrappers/include/trace.h" | 45 #include "webrtc/system_wrappers/include/trace.h" |
45 #include "webrtc/voice_engine/transmit_mixer.h" | 46 #include "webrtc/voice_engine/transmit_mixer.h" |
46 | 47 |
47 namespace cricket { | 48 namespace cricket { |
48 namespace { | 49 namespace { |
49 | 50 |
50 constexpr size_t kMaxUnsignaledRecvStreams = 1; | 51 constexpr size_t kMaxUnsignaledRecvStreams = 1; |
(...skipping 19 matching lines...) Expand all Loading... | |
70 constexpr int kNackRtpHistoryMs = 5000; | 71 constexpr int kNackRtpHistoryMs = 5000; |
71 | 72 |
72 // Check to verify that the define for the intelligibility enhancer is properly | 73 // Check to verify that the define for the intelligibility enhancer is properly |
73 // set. | 74 // set. |
74 #if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \ | 75 #if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \ |
75 (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \ | 76 (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \ |
76 WEBRTC_INTELLIGIBILITY_ENHANCER != 1) | 77 WEBRTC_INTELLIGIBILITY_ENHANCER != 1) |
77 #error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1" | 78 #error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1" |
78 #endif | 79 #endif |
79 | 80 |
80 // Codec parameters for Opus. | 81 // For SendSideBwe, Opus bitrate should be in the range between 6000 and 32000. |
81 // draft-spittka-payload-rtp-opus-03 | 82 const int kOpusMinBitrateBps = 6000; |
82 | |
83 // Recommended bitrates: | |
84 // 8-12 kb/s for NB speech, | |
85 // 16-20 kb/s for WB speech, | |
86 // 28-40 kb/s for FB speech, | |
87 // 48-64 kb/s for FB mono music, and | |
88 // 64-128 kb/s for FB stereo music. | |
89 // The current implementation applies the following values to mono signals, | |
90 // and multiplies them by 2 for stereo. | |
91 const int kOpusBitrateNbBps = 12000; | |
92 const int kOpusBitrateWbBps = 20000; | |
93 const int kOpusBitrateFbBps = 32000; | 83 const int kOpusBitrateFbBps = 32000; |
94 | 84 |
95 // Opus bitrate should be in the range between 6000 and 510000. | |
96 const int kOpusMinBitrateBps = 6000; | |
97 const int kOpusMaxBitrateBps = 510000; | |
98 | |
99 // iSAC bitrate should be <= 56000. | |
100 const int kIsacMaxBitrateBps = 56000; | |
101 | |
102 // Default audio dscp value. | 85 // Default audio dscp value. |
103 // See http://tools.ietf.org/html/rfc2474 for details. | 86 // See http://tools.ietf.org/html/rfc2474 for details. |
104 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 | 87 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 |
105 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; | 88 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; |
106 | 89 |
107 // Constants from voice_engine_defines.h. | 90 // Constants from voice_engine_defines.h. |
108 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) | 91 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) |
109 const int kMaxTelephoneEventCode = 255; | 92 const int kMaxTelephoneEventCode = 255; |
110 const int kMinTelephoneEventDuration = 100; | 93 const int kMinTelephoneEventDuration = 100; |
111 const int kMaxTelephoneEventDuration = 60000; // Actual limit is 2^16 | 94 const int kMaxTelephoneEventDuration = 60000; // Actual limit is 2^16 |
(...skipping 19 matching lines...) Expand all Loading... | |
131 if (sp.ssrcs.size() > 1) { | 114 if (sp.ssrcs.size() > 1) { |
132 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); | 115 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); |
133 return false; | 116 return false; |
134 } | 117 } |
135 return true; | 118 return true; |
136 } | 119 } |
137 | 120 |
138 // Dumps an AudioCodec in RFC 2327-ish format. | 121 // Dumps an AudioCodec in RFC 2327-ish format. |
139 std::string ToString(const AudioCodec& codec) { | 122 std::string ToString(const AudioCodec& codec) { |
140 std::stringstream ss; | 123 std::stringstream ss; |
141 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels | 124 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels; |
142 << " (" << codec.id << ")"; | 125 if (!codec.params.empty()) { |
126 ss << " {"; | |
127 for (const auto& param : codec.params) { | |
128 ss << " " << param.first << "=" << param.second; | |
129 } | |
130 ss << " }"; | |
131 } | |
132 ss << " (" << codec.id << ")"; | |
143 return ss.str(); | 133 return ss.str(); |
144 } | 134 } |
145 | 135 |
146 std::string ToString(const webrtc::CodecInst& codec) { | 136 std::string ToString(const webrtc::CodecInst& codec) { |
147 std::stringstream ss; | 137 std::stringstream ss; |
148 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels | 138 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels |
149 << " (" << codec.pltype << ")"; | 139 << " (" << codec.pltype << ")"; |
150 return ss.str(); | 140 return ss.str(); |
151 } | 141 } |
152 | 142 |
(...skipping 25 matching lines...) Expand all Loading... | |
178 } | 168 } |
179 std::vector<int> payload_types; | 169 std::vector<int> payload_types; |
180 for (const AudioCodec& codec : codecs) { | 170 for (const AudioCodec& codec : codecs) { |
181 payload_types.push_back(codec.id); | 171 payload_types.push_back(codec.id); |
182 } | 172 } |
183 std::sort(payload_types.begin(), payload_types.end()); | 173 std::sort(payload_types.begin(), payload_types.end()); |
184 auto it = std::unique(payload_types.begin(), payload_types.end()); | 174 auto it = std::unique(payload_types.begin(), payload_types.end()); |
185 return it == payload_types.end(); | 175 return it == payload_types.end(); |
186 } | 176 } |
187 | 177 |
188 // Return true if codec.params[feature] == "1", false otherwise. | |
189 bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) { | |
190 int value; | |
191 return codec.GetParam(feature, &value) && value == 1; | |
192 } | |
193 | |
194 rtc::Optional<std::string> GetAudioNetworkAdaptorConfig( | 178 rtc::Optional<std::string> GetAudioNetworkAdaptorConfig( |
195 const AudioOptions& options) { | 179 const AudioOptions& options) { |
196 if (options.audio_network_adaptor && *options.audio_network_adaptor && | 180 if (options.audio_network_adaptor && *options.audio_network_adaptor && |
197 options.audio_network_adaptor_config) { | 181 options.audio_network_adaptor_config) { |
198 // Turn on audio network adaptor only when |options_.audio_network_adaptor| | 182 // Turn on audio network adaptor only when |options_.audio_network_adaptor| |
199 // equals true and |options_.audio_network_adaptor_config| has a value. | 183 // equals true and |options_.audio_network_adaptor_config| has a value. |
200 return options.audio_network_adaptor_config; | 184 return options.audio_network_adaptor_config; |
201 } | 185 } |
202 return rtc::Optional<std::string>(); | 186 return rtc::Optional<std::string>(); |
203 } | 187 } |
204 | 188 |
205 // Returns integer parameter params[feature] if it is defined. Returns | |
206 // |default_value| otherwise. | |
207 int GetCodecFeatureInt(const AudioCodec& codec, | |
208 const char* feature, | |
209 int default_value) { | |
210 int value = 0; | |
211 if (codec.GetParam(feature, &value)) { | |
212 return value; | |
213 } | |
214 return default_value; | |
215 } | |
216 | |
217 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate | |
218 // otherwise. If the value (either from params or codec.bitrate) <=0, use the | |
219 // default configuration. If the value is beyond feasible bit rate of Opus, | |
220 // clamp it. Returns the Opus bit rate for operation. | |
221 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { | |
222 int bitrate = 0; | |
223 bool use_param = true; | |
224 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) { | |
225 bitrate = codec.bitrate; | |
226 use_param = false; | |
227 } | |
228 if (bitrate <= 0) { | |
229 if (max_playback_rate <= 8000) { | |
230 bitrate = kOpusBitrateNbBps; | |
231 } else if (max_playback_rate <= 16000) { | |
232 bitrate = kOpusBitrateWbBps; | |
233 } else { | |
234 bitrate = kOpusBitrateFbBps; | |
235 } | |
236 | |
237 if (IsCodecFeatureEnabled(codec, kCodecParamStereo)) { | |
238 bitrate *= 2; | |
239 } | |
240 } else if (bitrate < kOpusMinBitrateBps || bitrate > kOpusMaxBitrateBps) { | |
241 bitrate = (bitrate < kOpusMinBitrateBps) ? kOpusMinBitrateBps | |
242 : kOpusMaxBitrateBps; | |
243 std::string rate_source = | |
244 use_param ? "Codec parameter \"maxaveragebitrate\"" : | |
245 "Supplied Opus bitrate"; | |
246 LOG(LS_WARNING) << rate_source | |
247 << " is invalid and is replaced by: " | |
248 << bitrate; | |
249 } | |
250 return bitrate; | |
251 } | |
252 | |
253 void GetOpusConfig(const AudioCodec& codec, | |
254 webrtc::CodecInst* voe_codec, | |
255 bool* enable_codec_fec, | |
256 int* max_playback_rate, | |
257 bool* enable_codec_dtx, | |
258 int* min_ptime_ms, | |
259 int* max_ptime_ms) { | |
260 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec); | |
261 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx); | |
262 *max_playback_rate = GetCodecFeatureInt(codec, kCodecParamMaxPlaybackRate, | |
263 kOpusDefaultMaxPlaybackRate); | |
264 *max_ptime_ms = | |
265 GetCodecFeatureInt(codec, kCodecParamMaxPTime, kOpusDefaultMaxPTime); | |
266 *min_ptime_ms = | |
267 GetCodecFeatureInt(codec, kCodecParamMinPTime, kOpusDefaultMinPTime); | |
268 if (*max_ptime_ms < *min_ptime_ms) { | |
269 // If min ptime or max ptime defined by codec parameter is wrong, we use | |
270 // the default values. | |
271 *max_ptime_ms = kOpusDefaultMaxPTime; | |
272 *min_ptime_ms = kOpusDefaultMinPTime; | |
273 } | |
274 | |
275 // If OPUS, change what we send according to the "stereo" codec | |
276 // parameter, and not the "channels" parameter. We set | |
277 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If | |
278 // the bitrate is not specified, i.e. is <= zero, we set it to the | |
279 // appropriate default value for mono or stereo Opus. | |
280 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; | |
281 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); | |
282 } | |
283 | |
284 webrtc::AudioState::Config MakeAudioStateConfig( | 189 webrtc::AudioState::Config MakeAudioStateConfig( |
285 VoEWrapper* voe_wrapper, | 190 VoEWrapper* voe_wrapper, |
286 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) { | 191 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) { |
287 webrtc::AudioState::Config config; | 192 webrtc::AudioState::Config config; |
288 config.voice_engine = voe_wrapper->engine(); | 193 config.voice_engine = voe_wrapper->engine(); |
289 if (audio_mixer) { | 194 if (audio_mixer) { |
290 config.audio_mixer = audio_mixer; | 195 config.audio_mixer = audio_mixer; |
291 } else { | 196 } else { |
292 config.audio_mixer = webrtc::AudioMixerImpl::Create(); | 197 config.audio_mixer = webrtc::AudioMixerImpl::Create(); |
293 } | 198 } |
294 return config; | 199 return config; |
295 } | 200 } |
296 | 201 |
297 class WebRtcVoiceCodecs final { | 202 class WebRtcVoiceCodecs final { |
298 public: | 203 public: |
299 // TODO(solenberg): Do this filtering once off-line, add a simple AudioCodec | 204 static bool ToCodecInst(const AudioCodec& in, webrtc::CodecInst* out) { |
300 // list and add a test which verifies VoE supports the listed codecs. | |
301 static std::vector<AudioCodec> SupportedSendCodecs() { | |
302 std::vector<AudioCodec> result; | |
303 // Iterate first over our preferred codecs list, so that the results are | |
304 // added in order of preference. | |
305 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | |
306 const CodecPref* pref = &kCodecPrefs[i]; | |
307 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { | |
308 // Change the sample rate of G722 to 8000 to match SDP. | |
309 MaybeFixupG722(&voe_codec, 8000); | |
310 // Skip uncompressed formats. | |
311 if (IsCodec(voe_codec, kL16CodecName)) { | |
312 continue; | |
313 } | |
314 | |
315 if (!IsCodec(voe_codec, pref->name) || | |
316 pref->clockrate != voe_codec.plfreq || | |
317 pref->channels != voe_codec.channels) { | |
318 // Not a match. | |
319 continue; | |
320 } | |
321 | |
322 AudioCodec codec(pref->payload_type, voe_codec.plname, voe_codec.plfreq, | |
323 voe_codec.rate, voe_codec.channels); | |
324 LOG(LS_INFO) << "Adding supported codec: " << ToString(codec); | |
325 if (IsCodec(codec, kIsacCodecName)) { | |
326 // Indicate auto-bitrate in signaling. | |
327 codec.bitrate = 0; | |
328 } | |
329 if (IsCodec(codec, kOpusCodecName)) { | |
330 // Only add fmtp parameters that differ from the spec. | |
331 if (kPreferredMinPTime != kOpusDefaultMinPTime) { | |
332 codec.params[kCodecParamMinPTime] = | |
333 rtc::ToString(kPreferredMinPTime); | |
334 } | |
335 if (kPreferredMaxPTime != kOpusDefaultMaxPTime) { | |
336 codec.params[kCodecParamMaxPTime] = | |
337 rtc::ToString(kPreferredMaxPTime); | |
338 } | |
339 codec.SetParam(kCodecParamUseInbandFec, 1); | |
340 codec.AddFeedbackParam( | |
341 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); | |
342 | |
343 // TODO(hellner): Add ptime, sprop-stereo, and stereo | |
344 // when they can be set to values other than the default. | |
345 } | |
346 result.push_back(codec); | |
347 } | |
348 } | |
349 return result; | |
350 } | |
351 | |
352 static bool ToCodecInst(const AudioCodec& in, | |
353 webrtc::CodecInst* out) { | |
354 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { | 205 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { |
355 // Change the sample rate of G722 to 8000 to match SDP. | 206 // Change the sample rate of G722 to 8000 to match SDP. |
356 MaybeFixupG722(&voe_codec, 8000); | 207 MaybeFixupG722(&voe_codec, 8000); |
357 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, | 208 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, |
358 voe_codec.rate, voe_codec.channels); | 209 voe_codec.rate, voe_codec.channels); |
359 bool multi_rate = IsCodecMultiRate(voe_codec); | 210 const bool multi_rate = |
211 IsCodec(codec, kIsacCodecName) || IsCodec(codec, kOpusCodecName); | |
360 // Allow arbitrary rates for ISAC to be specified. | 212 // Allow arbitrary rates for ISAC to be specified. |
361 if (multi_rate) { | 213 if (multi_rate) { |
362 // Set codec.bitrate to 0 so the check for codec.Matches() passes. | 214 // Set codec.bitrate to 0 so the check for codec.Matches() passes. |
363 codec.bitrate = 0; | 215 codec.bitrate = 0; |
364 } | 216 } |
365 if (codec.Matches(in)) { | 217 if (codec.Matches(in)) { |
366 if (out) { | 218 if (out) { |
367 // Fixup the payload type. | 219 // Fixup the payload type. |
368 voe_codec.pltype = in.id; | 220 voe_codec.pltype = in.id; |
369 | 221 |
370 // Set bitrate if specified. | 222 // Set bitrate if specified. |
371 if (multi_rate && in.bitrate != 0) { | 223 if (multi_rate && in.bitrate != 0) { |
372 voe_codec.rate = in.bitrate; | 224 voe_codec.rate = in.bitrate; |
373 } | 225 } |
374 | 226 |
375 // Reset G722 sample rate to 16000 to match WebRTC. | 227 // Reset G722 sample rate to 16000 to match WebRTC. |
376 MaybeFixupG722(&voe_codec, 16000); | 228 MaybeFixupG722(&voe_codec, 16000); |
377 | 229 |
378 *out = voe_codec; | 230 *out = voe_codec; |
379 } | 231 } |
380 return true; | 232 return true; |
381 } | 233 } |
382 } | 234 } |
383 return false; | 235 return false; |
384 } | 236 } |
385 | 237 |
386 static bool IsCodecMultiRate(const webrtc::CodecInst& codec) { | |
387 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | |
388 if (IsCodec(codec, kCodecPrefs[i].name) && | |
389 kCodecPrefs[i].clockrate == codec.plfreq) { | |
390 return kCodecPrefs[i].is_multi_rate; | |
391 } | |
392 } | |
393 return false; | |
394 } | |
395 | |
396 static int MaxBitrateBps(const webrtc::CodecInst& codec) { | |
397 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | |
398 if (IsCodec(codec, kCodecPrefs[i].name) && | |
399 kCodecPrefs[i].clockrate == codec.plfreq) { | |
400 return kCodecPrefs[i].max_bitrate_bps; | |
401 } | |
402 } | |
403 return 0; | |
404 } | |
405 | |
406 static rtc::ArrayView<const int> GetPacketSizesMs( | |
407 const webrtc::CodecInst& codec) { | |
408 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | |
409 if (IsCodec(codec, kCodecPrefs[i].name)) { | |
410 size_t num_packet_sizes = kMaxNumPacketSize; | |
411 for (int index = 0; index < kMaxNumPacketSize; index++) { | |
412 if (kCodecPrefs[i].packet_sizes_ms[index] == 0) { | |
413 num_packet_sizes = index; | |
414 break; | |
415 } | |
416 } | |
417 return rtc::ArrayView<const int>(kCodecPrefs[i].packet_sizes_ms, | |
418 num_packet_sizes); | |
419 } | |
420 } | |
421 return rtc::ArrayView<const int>(); | |
422 } | |
423 | |
424 // If the AudioCodec param kCodecParamPTime is set, then we will set it to | |
425 // codec pacsize if it's valid, or we will pick the next smallest value we | |
426 // support. | |
427 // TODO(Brave): Query supported packet sizes from ACM when the API is ready. | |
428 static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) { | |
429 for (const CodecPref& codec_pref : kCodecPrefs) { | |
430 if ((IsCodec(*codec, codec_pref.name) && | |
431 codec_pref.clockrate == codec->plfreq) || | |
432 IsCodec(*codec, kG722CodecName)) { | |
433 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms); | |
434 if (packet_size_ms) { | |
435 // Convert unit from milli-seconds to samples. | |
436 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms; | |
437 return true; | |
438 } | |
439 } | |
440 } | |
441 return false; | |
442 } | |
443 | |
444 static const AudioCodec* GetPreferredCodec( | |
445 const std::vector<AudioCodec>& codecs, | |
446 webrtc::CodecInst* out) { | |
447 RTC_DCHECK(out); | |
448 // Select the preferred send codec (the first non-telephone-event/CN codec). | |
449 for (const AudioCodec& codec : codecs) { | |
450 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) { | |
451 // Skip telephone-event/CN codecs - they will be handled later. | |
452 continue; | |
453 } | |
454 | |
455 // We'll use the first codec in the list to actually send audio data. | |
456 // Be sure to use the payload type requested by the remote side. | |
457 // Ignore codecs we don't know about. The negotiation step should prevent | |
458 // this, but double-check to be sure. | |
459 if (!ToCodecInst(codec, out)) { | |
460 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | |
461 continue; | |
462 } | |
463 return &codec; | |
464 } | |
465 return nullptr; | |
466 } | |
467 | |
468 private: | |
469 static const int kMaxNumPacketSize = 6; | |
470 struct CodecPref { | |
471 const char* name; | |
472 int clockrate; | |
473 size_t channels; | |
474 int payload_type; | |
475 bool is_multi_rate; | |
476 int packet_sizes_ms[kMaxNumPacketSize]; | |
477 int max_bitrate_bps; | |
478 }; | |
479 // Note: keep the supported packet sizes in ascending order. | |
480 static const CodecPref kCodecPrefs[14]; | |
481 | |
482 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { | |
483 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; | |
484 for (int packet_size_ms : codec_pref.packet_sizes_ms) { | |
485 if (packet_size_ms && packet_size_ms <= ptime_ms) { | |
486 selected_packet_size_ms = packet_size_ms; | |
487 } | |
488 } | |
489 return selected_packet_size_ms; | |
490 } | |
491 | |
492 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC | 238 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC |
493 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz | 239 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz |
494 // codec. | 240 // codec. |
495 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { | 241 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { |
496 if (IsCodec(*voe_codec, kG722CodecName)) { | 242 if (IsCodec(*voe_codec, kG722CodecName)) { |
497 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine | 243 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine |
498 // has changed, and this special case is no longer needed. | 244 // has changed, and this special case is no longer needed. |
499 RTC_DCHECK(voe_codec->plfreq != new_plfreq); | 245 RTC_DCHECK(voe_codec->plfreq != new_plfreq); |
500 voe_codec->plfreq = new_plfreq; | 246 voe_codec->plfreq = new_plfreq; |
501 } | 247 } |
502 } | 248 } |
503 }; | 249 }; |
504 | 250 |
505 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[14] = { | |
506 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME | |
507 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60, 120}, | |
508 kOpusMaxBitrateBps}, | |
509 #else | |
510 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrateBps}, | |
511 #endif | |
512 {kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrateBps}, | |
513 {kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrateBps}, | |
514 // G722 should be advertised as 8000 Hz because of the RFC "bug". | |
515 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, | |
516 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, | |
517 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, | |
518 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, | |
519 {kCnCodecName, 32000, 1, 106, false, {}}, | |
520 {kCnCodecName, 16000, 1, 105, false, {}}, | |
521 {kCnCodecName, 8000, 1, 13, false, {}}, | |
522 {kDtmfCodecName, 48000, 1, 110, false, {}}, | |
523 {kDtmfCodecName, 32000, 1, 112, false, {}}, | |
524 {kDtmfCodecName, 16000, 1, 113, false, {}}, | |
525 {kDtmfCodecName, 8000, 1, 126, false, {}} | |
526 }; | |
527 | |
528 // |max_send_bitrate_bps| is the bitrate from "b=" in SDP. | 251 // |max_send_bitrate_bps| is the bitrate from "b=" in SDP. |
529 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters. | 252 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters. |
530 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, | 253 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, |
531 rtc::Optional<int> rtp_max_bitrate_bps, | 254 rtc::Optional<int> rtp_max_bitrate_bps, |
532 const webrtc::CodecInst& codec_inst) { | 255 const webrtc::AudioCodecSpec& spec) { |
533 // If application-configured bitrate is set, take minimum of that and SDP | 256 // If application-configured bitrate is set, take minimum of that and SDP |
534 // bitrate. | 257 // bitrate. |
535 const int bps = rtp_max_bitrate_bps | 258 const int bps = rtp_max_bitrate_bps |
536 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps) | 259 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps) |
537 : max_send_bitrate_bps; | 260 : max_send_bitrate_bps; |
538 const int codec_rate = codec_inst.rate; | |
539 | |
540 if (bps <= 0) { | 261 if (bps <= 0) { |
541 return rtc::Optional<int>(codec_rate); | 262 return rtc::Optional<int>(spec.info.default_bitrate_bps); |
542 } | 263 } |
543 | 264 |
544 if (codec_inst.pltype == -1) { | 265 if (bps < spec.info.min_bitrate_bps) { |
545 return rtc::Optional<int>(codec_rate); | |
546 ; | |
547 } | |
548 | |
549 if (WebRtcVoiceCodecs::IsCodecMultiRate(codec_inst)) { | |
550 // If codec is multi-rate then just set the bitrate. | |
551 return rtc::Optional<int>( | |
552 std::min(bps, WebRtcVoiceCodecs::MaxBitrateBps(codec_inst))); | |
553 } | |
554 | |
555 if (bps < codec_inst.rate) { | |
556 // If codec is not multi-rate and |bps| is less than the fixed bitrate then | 266 // If codec is not multi-rate and |bps| is less than the fixed bitrate then |
557 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed | 267 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed |
558 // bitrate then ignore. | 268 // bitrate then ignore. |
559 LOG(LS_ERROR) << "Failed to set codec " << codec_inst.plname | 269 LOG(LS_ERROR) << "Failed to set codec " << spec.format.name |
560 << " to bitrate " << bps << " bps" | 270 << " to bitrate " << bps << " bps" |
561 << ", requires at least " << codec_inst.rate << " bps."; | 271 << ", requires at least " << spec.info.min_bitrate_bps |
272 << " bps."; | |
562 return rtc::Optional<int>(); | 273 return rtc::Optional<int>(); |
563 } | 274 } |
564 return rtc::Optional<int>(codec_rate); | 275 |
276 if (spec.info.HasFixedBitrate()) { | |
277 return rtc::Optional<int>(spec.info.default_bitrate_bps); | |
278 } else { | |
279 // If codec is multi-rate then just set the bitrate. | |
280 return rtc::Optional<int>(std::min(bps, spec.info.max_bitrate_bps)); | |
281 } | |
565 } | 282 } |
566 | 283 |
567 } // namespace | 284 } // namespace |
568 | 285 |
569 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 286 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, |
570 webrtc::CodecInst* out) { | 287 webrtc::CodecInst* out) { |
571 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 288 return WebRtcVoiceCodecs::ToCodecInst(in, out); |
572 } | 289 } |
573 | 290 |
574 WebRtcVoiceEngine::WebRtcVoiceEngine( | 291 WebRtcVoiceEngine::WebRtcVoiceEngine( |
575 webrtc::AudioDeviceModule* adm, | 292 webrtc::AudioDeviceModule* adm, |
576 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, | 293 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, |
577 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) | 294 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) |
578 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) { | 295 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) { |
579 audio_state_ = | 296 audio_state_ = |
580 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer)); | 297 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer)); |
581 } | 298 } |
582 | 299 |
583 WebRtcVoiceEngine::WebRtcVoiceEngine( | 300 WebRtcVoiceEngine::WebRtcVoiceEngine( |
584 webrtc::AudioDeviceModule* adm, | 301 webrtc::AudioDeviceModule* adm, |
585 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, | 302 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, |
586 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, | 303 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, |
587 VoEWrapper* voe_wrapper) | 304 VoEWrapper* voe_wrapper) |
588 : adm_(adm), decoder_factory_(decoder_factory), voe_wrapper_(voe_wrapper) { | 305 : adm_(adm), |
306 encoder_factory_(webrtc::CreateBuiltinAudioEncoderFactory()), | |
307 decoder_factory_(decoder_factory), | |
308 voe_wrapper_(voe_wrapper) { | |
589 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 309 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
590 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; | 310 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; |
591 RTC_DCHECK(voe_wrapper); | 311 RTC_DCHECK(voe_wrapper); |
592 RTC_DCHECK(decoder_factory); | 312 RTC_DCHECK(decoder_factory); |
593 | 313 |
594 signal_thread_checker_.DetachFromThread(); | 314 signal_thread_checker_.DetachFromThread(); |
595 | 315 |
596 // Load our audio codec list. | 316 // Load our audio codec list. |
597 LOG(LS_INFO) << "Supported send codecs in order of preference:"; | 317 LOG(LS_INFO) << "Supported send codecs in order of preference:"; |
598 send_codecs_ = WebRtcVoiceCodecs::SupportedSendCodecs(); | 318 send_codecs_ = CollectCodecs(encoder_factory_->GetSupportedEncoders()); |
599 for (const AudioCodec& codec : send_codecs_) { | 319 for (const AudioCodec& codec : send_codecs_) { |
600 LOG(LS_INFO) << ToString(codec); | 320 LOG(LS_INFO) << ToString(codec); |
601 } | 321 } |
602 | 322 |
603 LOG(LS_INFO) << "Supported recv codecs in order of preference:"; | 323 LOG(LS_INFO) << "Supported recv codecs in order of preference:"; |
604 recv_codecs_ = CollectRecvCodecs(); | 324 recv_codecs_ = CollectCodecs(decoder_factory_->GetSupportedDecoders()); |
605 for (const AudioCodec& codec : recv_codecs_) { | 325 for (const AudioCodec& codec : recv_codecs_) { |
606 LOG(LS_INFO) << ToString(codec); | 326 LOG(LS_INFO) << ToString(codec); |
607 } | 327 } |
608 | 328 |
609 channel_config_.enable_voice_pacing = true; | 329 channel_config_.enable_voice_pacing = true; |
610 | 330 |
611 // Temporarily turn logging level up for the Init() call. | 331 // Temporarily turn logging level up for the Init() call. |
612 webrtc::Trace::SetTraceCallback(this); | 332 webrtc::Trace::SetTraceCallback(this); |
613 webrtc::Trace::set_level_filter(kElevatedTraceFilter); | 333 webrtc::Trace::set_level_filter(kElevatedTraceFilter); |
614 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString(); | 334 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString(); |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1097 RTC_DCHECK(apm_); | 817 RTC_DCHECK(apm_); |
1098 return apm_; | 818 return apm_; |
1099 } | 819 } |
1100 | 820 |
1101 webrtc::voe::TransmitMixer* WebRtcVoiceEngine::transmit_mixer() { | 821 webrtc::voe::TransmitMixer* WebRtcVoiceEngine::transmit_mixer() { |
1102 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 822 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1103 RTC_DCHECK(transmit_mixer_); | 823 RTC_DCHECK(transmit_mixer_); |
1104 return transmit_mixer_; | 824 return transmit_mixer_; |
1105 } | 825 } |
1106 | 826 |
1107 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { | 827 AudioCodecs WebRtcVoiceEngine::CollectCodecs( |
828 const std::vector<webrtc::AudioCodecSpec>& specs) const { | |
1108 PayloadTypeMapper mapper; | 829 PayloadTypeMapper mapper; |
1109 AudioCodecs out; | 830 AudioCodecs out; |
1110 const std::vector<webrtc::AudioCodecSpec>& specs = | |
1111 decoder_factory_->GetSupportedDecoders(); | |
1112 | 831 |
1113 // Only generate CN payload types for these clockrates: | 832 // Only generate CN payload types for these clockrates: |
1114 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, | 833 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, |
1115 { 16000, false }, | 834 { 16000, false }, |
1116 { 32000, false }}; | 835 { 32000, false }}; |
1117 // Only generate telephone-event payload types for these clockrates: | 836 // Only generate telephone-event payload types for these clockrates: |
1118 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, | 837 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, |
1119 { 16000, false }, | 838 { 16000, false }, |
1120 { 32000, false }, | 839 { 32000, false }, |
1121 { 48000, false }}; | 840 { 48000, false }}; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1181 } | 900 } |
1182 | 901 |
1183 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 902 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
1184 : public AudioSource::Sink { | 903 : public AudioSource::Sink { |
1185 public: | 904 public: |
1186 WebRtcAudioSendStream( | 905 WebRtcAudioSendStream( |
1187 int ch, | 906 int ch, |
1188 webrtc::AudioTransport* voe_audio_transport, | 907 webrtc::AudioTransport* voe_audio_transport, |
1189 uint32_t ssrc, | 908 uint32_t ssrc, |
1190 const std::string& c_name, | 909 const std::string& c_name, |
1191 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, | 910 const rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>& |
911 send_codec_spec, | |
1192 const std::vector<webrtc::RtpExtension>& extensions, | 912 const std::vector<webrtc::RtpExtension>& extensions, |
1193 int max_send_bitrate_bps, | 913 int max_send_bitrate_bps, |
1194 const rtc::Optional<std::string>& audio_network_adaptor_config, | 914 const rtc::Optional<std::string>& audio_network_adaptor_config, |
1195 webrtc::Call* call, | 915 webrtc::Call* call, |
1196 webrtc::Transport* send_transport) | 916 webrtc::Transport* send_transport, |
917 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& encoder_factory) | |
1197 : voe_audio_transport_(voe_audio_transport), | 918 : voe_audio_transport_(voe_audio_transport), |
1198 call_(call), | 919 call_(call), |
1199 config_(send_transport), | 920 config_(send_transport), |
1200 send_side_bwe_with_overhead_( | 921 send_side_bwe_with_overhead_( |
1201 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), | 922 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), |
1202 max_send_bitrate_bps_(max_send_bitrate_bps), | 923 max_send_bitrate_bps_(max_send_bitrate_bps), |
1203 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 924 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { |
1204 RTC_DCHECK_GE(ch, 0); | 925 RTC_DCHECK_GE(ch, 0); |
1205 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 926 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
1206 // RTC_DCHECK(voe_audio_transport); | 927 // RTC_DCHECK(voe_audio_transport); |
1207 RTC_DCHECK(call); | 928 RTC_DCHECK(call); |
929 RTC_DCHECK(encoder_factory); | |
1208 config_.rtp.ssrc = ssrc; | 930 config_.rtp.ssrc = ssrc; |
1209 config_.rtp.c_name = c_name; | 931 config_.rtp.c_name = c_name; |
1210 config_.voe_channel_id = ch; | 932 config_.voe_channel_id = ch; |
1211 config_.rtp.extensions = extensions; | 933 config_.rtp.extensions = extensions; |
1212 config_.audio_network_adaptor_config = audio_network_adaptor_config; | 934 config_.audio_network_adaptor_config = audio_network_adaptor_config; |
935 config_.encoder_factory = encoder_factory; | |
1213 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc); | 936 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc); |
1214 RecreateAudioSendStream(send_codec_spec); | 937 if (send_codec_spec) { |
938 RecreateAudioSendStream(*send_codec_spec); | |
939 } else { | |
940 RecreateAudioSendStream(); | |
941 } | |
1215 } | 942 } |
1216 | 943 |
1217 ~WebRtcAudioSendStream() override { | 944 ~WebRtcAudioSendStream() override { |
1218 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 945 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1219 ClearSource(); | 946 ClearSource(); |
1220 call_->DestroyAudioSendStream(stream_); | 947 call_->DestroyAudioSendStream(stream_); |
1221 } | 948 } |
1222 | 949 |
1223 void RecreateAudioSendStream( | 950 void RecreateAudioSendStream( |
1224 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { | 951 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { |
1225 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 952 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1226 send_codec_spec_ = send_codec_spec; | |
1227 config_.rtp.nack.rtp_history_ms = | 953 config_.rtp.nack.rtp_history_ms = |
1228 send_codec_spec_.nack_enabled ? kNackRtpHistoryMs : 0; | 954 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; |
1229 config_.send_codec_spec = send_codec_spec_; | 955 config_.send_codec_spec = |
1230 auto send_rate = ComputeSendBitrate( | 956 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>( |
957 send_codec_spec); | |
958 auto info = | |
959 config_.encoder_factory->QueryAudioEncoder(send_codec_spec.format); | |
960 RTC_DCHECK(info); | |
961 // If a specific target bitrate has been set for the stream, use that as | |
962 // the new default bitrate when computing send bitrate. | |
963 if (send_codec_spec.target_bitrate_bps) { | |
964 info->default_bitrate_bps = | |
965 std::max(info->min_bitrate_bps, | |
966 std::min(info->max_bitrate_bps, | |
967 *send_codec_spec.target_bitrate_bps)); | |
968 } | |
969 | |
970 audio_codec_spec_.emplace( | |
971 webrtc::AudioCodecSpec{send_codec_spec.format, *info}); | |
972 | |
973 config_.send_codec_spec->target_bitrate_bps = ComputeSendBitrate( | |
1231 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, | 974 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, |
1232 send_codec_spec.codec_inst); | 975 *audio_codec_spec_); |
1233 if (send_rate) { | |
1234 // Apply a send rate that abides by |max_send_bitrate_bps_| and | |
1235 // |rtp_parameters_| when possible. Otherwise use the codec rate. | |
1236 config_.send_codec_spec.codec_inst.rate = *send_rate; | |
1237 } | |
1238 RecreateAudioSendStream(); | 976 RecreateAudioSendStream(); |
1239 } | 977 } |
1240 | 978 |
1241 void RecreateAudioSendStream( | 979 void RecreateAudioSendStream( |
1242 const std::vector<webrtc::RtpExtension>& extensions) { | 980 const std::vector<webrtc::RtpExtension>& extensions) { |
1243 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 981 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1244 config_.rtp.extensions = extensions; | 982 config_.rtp.extensions = extensions; |
1245 RecreateAudioSendStream(); | 983 RecreateAudioSendStream(); |
1246 } | 984 } |
1247 | 985 |
1248 void RecreateAudioSendStream( | 986 void RecreateAudioSendStream( |
1249 const rtc::Optional<std::string>& audio_network_adaptor_config) { | 987 const rtc::Optional<std::string>& audio_network_adaptor_config) { |
1250 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 988 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1251 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { | 989 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { |
1252 return; | 990 return; |
1253 } | 991 } |
1254 config_.audio_network_adaptor_config = audio_network_adaptor_config; | 992 config_.audio_network_adaptor_config = audio_network_adaptor_config; |
1255 RecreateAudioSendStream(); | 993 RecreateAudioSendStream(); |
1256 } | 994 } |
1257 | 995 |
1258 bool SetMaxSendBitrate(int bps) { | 996 bool SetMaxSendBitrate(int bps) { |
1259 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 997 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
998 RTC_DCHECK(config_.send_codec_spec); | |
999 RTC_DCHECK(audio_codec_spec_); | |
1260 auto send_rate = | 1000 auto send_rate = |
1261 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps, | 1001 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps, |
1262 send_codec_spec_.codec_inst); | 1002 *audio_codec_spec_); |
1003 | |
1263 if (!send_rate) { | 1004 if (!send_rate) { |
1264 return false; | 1005 return false; |
1265 } | 1006 } |
1266 | 1007 |
1267 max_send_bitrate_bps_ = bps; | 1008 max_send_bitrate_bps_ = bps; |
1268 | 1009 |
1269 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { | 1010 if (send_rate != config_.send_codec_spec->target_bitrate_bps) { |
1270 // Recreate AudioSendStream with new bit rate. | 1011 // TODO(ossu): Should not need to recreate stream. |
1271 config_.send_codec_spec.codec_inst.rate = *send_rate; | 1012 config_.send_codec_spec->target_bitrate_bps = send_rate; |
1272 RecreateAudioSendStream(); | 1013 RecreateAudioSendStream(); |
1273 } | 1014 } |
1274 return true; | 1015 return true; |
1275 } | 1016 } |
1276 | 1017 |
1277 bool SendTelephoneEvent(int payload_type, int payload_freq, int event, | 1018 bool SendTelephoneEvent(int payload_type, int payload_freq, int event, |
1278 int duration_ms) { | 1019 int duration_ms) { |
1279 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1020 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1280 RTC_DCHECK(stream_); | 1021 RTC_DCHECK(stream_); |
1281 return stream_->SendTelephoneEvent(payload_type, payload_freq, event, | 1022 return stream_->SendTelephoneEvent(payload_type, payload_freq, event, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1378 LOG(LS_ERROR) << "Attempted to set RtpParameters with modified SSRC"; | 1119 LOG(LS_ERROR) << "Attempted to set RtpParameters with modified SSRC"; |
1379 return false; | 1120 return false; |
1380 } | 1121 } |
1381 return true; | 1122 return true; |
1382 } | 1123 } |
1383 | 1124 |
1384 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { | 1125 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { |
1385 if (!ValidateRtpParameters(parameters)) { | 1126 if (!ValidateRtpParameters(parameters)) { |
1386 return false; | 1127 return false; |
1387 } | 1128 } |
1388 auto send_rate = ComputeSendBitrate(max_send_bitrate_bps_, | 1129 |
1389 parameters.encodings[0].max_bitrate_bps, | 1130 rtc::Optional<int> send_rate; |
1390 send_codec_spec_.codec_inst); | 1131 if (audio_codec_spec_) { |
1391 if (!send_rate) { | 1132 send_rate = ComputeSendBitrate(max_send_bitrate_bps_, |
1392 return false; | 1133 parameters.encodings[0].max_bitrate_bps, |
1134 *audio_codec_spec_); | |
1135 if (!send_rate) { | |
1136 return false; | |
1137 } | |
1393 } | 1138 } |
1394 | 1139 |
1395 rtp_parameters_ = parameters; | 1140 rtp_parameters_ = parameters; |
1396 | 1141 |
1397 // parameters.encodings[0].encodings[0].max_bitrate_bps could have changed. | 1142 // parameters.encodings[0].encodings[0].max_bitrate_bps could have changed. |
1398 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { | 1143 if (send_rate && send_rate != config_.send_codec_spec->target_bitrate_bps) { |
1144 // TODO(ossu): Should not need to recreate stream. | |
1399 // Recreate AudioSendStream with new bit rate. | 1145 // Recreate AudioSendStream with new bit rate. |
1400 config_.send_codec_spec.codec_inst.rate = *send_rate; | 1146 config_.send_codec_spec->target_bitrate_bps = send_rate; |
1401 RecreateAudioSendStream(); | 1147 RecreateAudioSendStream(); |
1402 } else { | 1148 } else { |
1403 // parameters.encodings[0].active could have changed. | 1149 // parameters.encodings[0].active could have changed. |
1404 UpdateSendState(); | 1150 UpdateSendState(); |
1405 } | 1151 } |
1406 return true; | 1152 return true; |
1407 } | 1153 } |
1408 | 1154 |
1409 private: | 1155 private: |
1410 void UpdateSendState() { | 1156 void UpdateSendState() { |
(...skipping 13 matching lines...) Expand all Loading... | |
1424 call_->DestroyAudioSendStream(stream_); | 1170 call_->DestroyAudioSendStream(stream_); |
1425 stream_ = nullptr; | 1171 stream_ = nullptr; |
1426 } | 1172 } |
1427 RTC_DCHECK(!stream_); | 1173 RTC_DCHECK(!stream_); |
1428 if (webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe")) { | 1174 if (webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe")) { |
1429 config_.min_bitrate_bps = kOpusMinBitrateBps; | 1175 config_.min_bitrate_bps = kOpusMinBitrateBps; |
1430 config_.max_bitrate_bps = kOpusBitrateFbBps; | 1176 config_.max_bitrate_bps = kOpusBitrateFbBps; |
1431 // TODO(mflodman): Keep testing this and set proper values. | 1177 // TODO(mflodman): Keep testing this and set proper values. |
1432 // Note: This is an early experiment currently only supported by Opus. | 1178 // Note: This is an early experiment currently only supported by Opus. |
1433 if (send_side_bwe_with_overhead_) { | 1179 if (send_side_bwe_with_overhead_) { |
1434 auto packet_sizes_ms = WebRtcVoiceCodecs::GetPacketSizesMs( | 1180 const bool is_opus_with_ana = |
1435 config_.send_codec_spec.codec_inst); | 1181 config_.audio_network_adaptor_config && |
1436 if (!packet_sizes_ms.empty()) { | 1182 !STR_CASE_CMP(config_.send_codec_spec->format.name.c_str(), |
1437 int max_packet_size_ms = | 1183 kOpusCodecName); |
1438 *std::max_element(packet_sizes_ms.begin(), packet_sizes_ms.end()); | 1184 const int max_packet_size_ms = |
1439 int min_packet_size_ms = | 1185 (is_opus_with_ana && WEBRTC_OPUS_SUPPORT_120MS_PTIME) ? 120 : 60; |
1440 *std::min_element(packet_sizes_ms.begin(), packet_sizes_ms.end()); | 1186 // Audio network adaptor will just use 20ms and 60ms frame lengths. |
1187 // The adaptor will only be active for the Opus encoder. | |
1188 const int min_packet_size_ms = is_opus_with_ana ? 20 : 10; | |
1441 | 1189 |
1442 // Audio network adaptor will just use 20ms and 60ms frame lengths. | 1190 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12) |
1443 // The adaptor will only be active for the Opus encoder. | 1191 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12; |
1444 if (config_.audio_network_adaptor_config && | |
1445 IsCodec(config_.send_codec_spec.codec_inst, kOpusCodecName)) { | |
1446 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME | |
1447 max_packet_size_ms = 120; | |
1448 #else | |
1449 max_packet_size_ms = 60; | |
1450 #endif | |
1451 min_packet_size_ms = 20; | |
1452 } | |
1453 | 1192 |
1454 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12) | 1193 int min_overhead_bps = |
1455 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12; | 1194 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms; |
1456 | 1195 |
1457 int min_overhead_bps = | 1196 int max_overhead_bps = |
1458 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms; | 1197 kOverheadPerPacket * 8 * 1000 / min_packet_size_ms; |
1459 | 1198 |
1460 int max_overhead_bps = | 1199 config_.min_bitrate_bps = kOpusMinBitrateBps + min_overhead_bps; |
1461 kOverheadPerPacket * 8 * 1000 / min_packet_size_ms; | 1200 config_.max_bitrate_bps = kOpusBitrateFbBps + max_overhead_bps; |
1462 | |
1463 config_.min_bitrate_bps = kOpusMinBitrateBps + min_overhead_bps; | |
1464 config_.max_bitrate_bps = kOpusBitrateFbBps + max_overhead_bps; | |
1465 } | |
1466 } | 1201 } |
1467 } | 1202 } |
1468 stream_ = call_->CreateAudioSendStream(config_); | 1203 stream_ = call_->CreateAudioSendStream(config_); |
1469 RTC_CHECK(stream_); | 1204 RTC_CHECK(stream_); |
1470 UpdateSendState(); | 1205 UpdateSendState(); |
1471 } | 1206 } |
1472 | 1207 |
1473 rtc::ThreadChecker worker_thread_checker_; | 1208 rtc::ThreadChecker worker_thread_checker_; |
1474 rtc::RaceChecker audio_capture_race_checker_; | 1209 rtc::RaceChecker audio_capture_race_checker_; |
1475 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; | 1210 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; |
1476 webrtc::Call* call_ = nullptr; | 1211 webrtc::Call* call_ = nullptr; |
1477 webrtc::AudioSendStream::Config config_; | 1212 webrtc::AudioSendStream::Config config_; |
1478 const bool send_side_bwe_with_overhead_; | 1213 const bool send_side_bwe_with_overhead_; |
1479 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 1214 // The stream is owned by WebRtcAudioSendStream and may be reallocated if |
1480 // configuration changes. | 1215 // configuration changes. |
1481 webrtc::AudioSendStream* stream_ = nullptr; | 1216 webrtc::AudioSendStream* stream_ = nullptr; |
1482 | 1217 |
1483 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. | 1218 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. |
1484 // PeerConnection will make sure invalidating the pointer before the object | 1219 // PeerConnection will make sure invalidating the pointer before the object |
1485 // goes away. | 1220 // goes away. |
1486 AudioSource* source_ = nullptr; | 1221 AudioSource* source_ = nullptr; |
1487 bool send_ = false; | 1222 bool send_ = false; |
1488 bool muted_ = false; | 1223 bool muted_ = false; |
1489 int max_send_bitrate_bps_; | 1224 int max_send_bitrate_bps_; |
1490 webrtc::RtpParameters rtp_parameters_; | 1225 webrtc::RtpParameters rtp_parameters_; |
1491 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec_; | 1226 rtc::Optional<webrtc::AudioCodecSpec> audio_codec_spec_; |
1492 | 1227 |
1493 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1228 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); |
1494 }; | 1229 }; |
1495 | 1230 |
1496 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1231 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { |
1497 public: | 1232 public: |
1498 WebRtcAudioReceiveStream( | 1233 WebRtcAudioReceiveStream( |
1499 int ch, | 1234 int ch, |
1500 uint32_t remote_ssrc, | 1235 uint32_t remote_ssrc, |
1501 uint32_t local_ssrc, | 1236 uint32_t local_ssrc, |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1944 for (const AudioCodec& codec : codecs) { | 1679 for (const AudioCodec& codec : codecs) { |
1945 if (IsCodec(codec, kDtmfCodecName)) { | 1680 if (IsCodec(codec, kDtmfCodecName)) { |
1946 dtmf_codecs.push_back(codec); | 1681 dtmf_codecs.push_back(codec); |
1947 if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) { | 1682 if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) { |
1948 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 1683 dtmf_payload_type_ = rtc::Optional<int>(codec.id); |
1949 dtmf_payload_freq_ = codec.clockrate; | 1684 dtmf_payload_freq_ = codec.clockrate; |
1950 } | 1685 } |
1951 } | 1686 } |
1952 } | 1687 } |
1953 | 1688 |
1954 // Scan through the list to figure out the codec to use for sending, along | 1689 // Scan through the list to figure out the codec to use for sending. |
1955 // with the proper configuration for VAD, CNG, NACK and Opus-specific | 1690 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec> send_codec_spec; |
1956 // parameters. | 1691 rtc::Optional<webrtc::AudioCodecInfo> voice_codec_info; |
1957 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. | 1692 for (const AudioCodec& voice_codec : codecs) { |
the sun
2017/03/20 20:17:25
voice_codec -> audio_codec?
ossu
2017/03/21 14:53:25
I wanted to separate the main codec from auxiliary
| |
1958 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec; | 1693 if (!(IsCodec(voice_codec, kCnCodecName) || |
1959 { | 1694 IsCodec(voice_codec, kDtmfCodecName) || |
1960 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 1695 IsCodec(voice_codec, kRedCodecName))) { |
1696 webrtc::SdpAudioFormat format(voice_codec.name, voice_codec.clockrate, | |
1697 voice_codec.channels, | |
1698 CodecParameterMap(voice_codec.params)); | |
the sun
2017/03/20 20:17:25
Is there any parsing going on in CodecParameterMap
ossu
2017/03/21 14:53:25
Nope, it's just a copy. When I started this, SdpAu
| |
1961 | 1699 |
1962 // Find send codec (the first non-telephone-event/CN codec). | 1700 voice_codec_info = engine()->encoder_factory_->QueryAudioEncoder(format); |
the sun
2017/03/20 20:17:25
voice_codec_info -> audio_codec_info?
| |
1963 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 1701 if (!voice_codec_info) { |
1964 codecs, &send_codec_spec.codec_inst); | 1702 LOG(LS_WARNING) << "Unknown codec " << ToString(voice_codec); |
1965 if (!codec) { | 1703 continue; |
1966 LOG(LS_WARNING) << "Received empty list of codecs."; | 1704 } |
1967 return false; | 1705 |
1706 send_codec_spec = | |
1707 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>( | |
1708 {voice_codec.id, format}); | |
1709 if (voice_codec.bitrate > 0) { | |
1710 send_codec_spec->target_bitrate_bps = | |
1711 rtc::Optional<int>(voice_codec.bitrate); | |
1712 } | |
1713 send_codec_spec->transport_cc_enabled = HasTransportCc(voice_codec); | |
1714 send_codec_spec->nack_enabled = HasNack(voice_codec); | |
1715 bitrate_config_ = GetBitrateConfigForCodec(voice_codec); | |
1716 break; | |
1968 } | 1717 } |
1718 } | |
1969 | 1719 |
1970 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec); | 1720 if (!send_codec_spec) |
1971 send_codec_spec.nack_enabled = HasNack(*codec); | 1721 return false; |
1972 bitrate_config_ = GetBitrateConfigForCodec(*codec); | |
1973 | 1722 |
1974 // For Opus as the send codec, we are to determine inband FEC, maximum | 1723 RTC_DCHECK(voice_codec_info); |
1975 // playback rate, and opus internal dtx. | 1724 if (voice_codec_info->allow_comfort_noise) { |
1976 if (IsCodec(*codec, kOpusCodecName)) { | |
1977 GetOpusConfig(*codec, &send_codec_spec.codec_inst, | |
1978 &send_codec_spec.enable_codec_fec, | |
1979 &send_codec_spec.opus_max_playback_rate, | |
1980 &send_codec_spec.enable_opus_dtx, | |
1981 &send_codec_spec.min_ptime_ms, | |
1982 &send_codec_spec.max_ptime_ms); | |
1983 } | |
1984 | |
1985 // Set packet size if the AudioCodec param kCodecParamPTime is set. | |
1986 int ptime_ms = 0; | |
1987 if (codec->GetParam(kCodecParamPTime, &ptime_ms)) { | |
1988 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize( | |
1989 &send_codec_spec.codec_inst, ptime_ms)) { | |
1990 LOG(LS_WARNING) << "Failed to set packet size for codec " | |
1991 << send_codec_spec.codec_inst.plname; | |
1992 return false; | |
1993 } | |
1994 } | |
1995 | |
1996 // Loop through the codecs list again to find the CN codec. | 1725 // Loop through the codecs list again to find the CN codec. |
1997 // TODO(solenberg): Break out into a separate function? | 1726 // TODO(solenberg): Break out into a separate function? |
1998 for (const AudioCodec& cn_codec : codecs) { | 1727 for (const AudioCodec& cn_codec : codecs) { |
1999 // Ignore codecs we don't know about. The negotiation step should prevent | |
2000 // this, but double-check to be sure. | |
2001 webrtc::CodecInst voe_codec = {0}; | |
2002 if (!WebRtcVoiceEngine::ToCodecInst(cn_codec, &voe_codec)) { | |
2003 LOG(LS_WARNING) << "Unknown codec " << ToString(cn_codec); | |
2004 continue; | |
2005 } | |
2006 | |
2007 if (IsCodec(cn_codec, kCnCodecName) && | 1728 if (IsCodec(cn_codec, kCnCodecName) && |
2008 cn_codec.clockrate == codec->clockrate) { | 1729 cn_codec.clockrate == send_codec_spec->format.clockrate_hz) { |
2009 // Turn voice activity detection/comfort noise on if supported. | |
2010 // Set the wideband CN payload type appropriately. | |
2011 // (narrowband always uses the static payload type 13). | |
2012 int cng_plfreq = -1; | |
2013 switch (cn_codec.clockrate) { | 1730 switch (cn_codec.clockrate) { |
2014 case 8000: | 1731 case 8000: |
2015 case 16000: | 1732 case 16000: |
2016 case 32000: | 1733 case 32000: |
2017 cng_plfreq = cn_codec.clockrate; | 1734 send_codec_spec->cng_payload_type = cn_codec.id; |
2018 break; | 1735 break; |
2019 default: | 1736 default: |
2020 LOG(LS_WARNING) << "CN frequency " << cn_codec.clockrate | 1737 LOG(LS_WARNING) << "CN frequency " << cn_codec.clockrate |
2021 << " not supported."; | 1738 << " not supported."; |
2022 continue; | 1739 break; |
2023 } | 1740 } |
2024 send_codec_spec.cng_payload_type = cn_codec.id; | |
2025 send_codec_spec.cng_plfreq = cng_plfreq; | |
2026 break; | 1741 break; |
2027 } | 1742 } |
2028 } | 1743 } |
2029 | 1744 |
2030 // Find the telephone-event PT exactly matching the preferred send codec. | 1745 // Find the telephone-event PT exactly matching the preferred send codec. |
2031 for (const AudioCodec& dtmf_codec : dtmf_codecs) { | 1746 for (const AudioCodec& dtmf_codec : dtmf_codecs) { |
2032 if (dtmf_codec.clockrate == codec->clockrate) { | 1747 if (dtmf_codec.clockrate == send_codec_spec->format.clockrate_hz) { |
2033 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id); | 1748 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id); |
2034 dtmf_payload_freq_ = dtmf_codec.clockrate; | 1749 dtmf_payload_freq_ = dtmf_codec.clockrate; |
2035 break; | 1750 break; |
2036 } | 1751 } |
2037 } | 1752 } |
2038 } | 1753 } |
2039 | 1754 |
2040 if (send_codec_spec_ != send_codec_spec) { | 1755 if (send_codec_spec_ != send_codec_spec) { |
2041 send_codec_spec_ = std::move(send_codec_spec); | 1756 send_codec_spec_ = std::move(send_codec_spec); |
2042 // Apply new settings to all streams. | 1757 // Apply new settings to all streams. |
2043 for (const auto& kv : send_streams_) { | 1758 for (const auto& kv : send_streams_) { |
2044 kv.second->RecreateAudioSendStream(send_codec_spec_); | 1759 kv.second->RecreateAudioSendStream(*send_codec_spec_); |
2045 } | 1760 } |
2046 } else { | 1761 } else { |
2047 // If the codec isn't changing, set the start bitrate to -1 which means | 1762 // If the codec isn't changing, set the start bitrate to -1 which means |
2048 // "unchanged" so that BWE isn't affected. | 1763 // "unchanged" so that BWE isn't affected. |
2049 bitrate_config_.start_bitrate_bps = -1; | 1764 bitrate_config_.start_bitrate_bps = -1; |
2050 } | 1765 } |
2051 | 1766 |
2052 // Check if the transport cc feedback or NACK status has changed on the | 1767 // Check if the transport cc feedback or NACK status has changed on the |
2053 // preferred send codec, and in that case reconfigure all receive streams. | 1768 // preferred send codec, and in that case reconfigure all receive streams. |
2054 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || | 1769 if (recv_transport_cc_enabled_ != send_codec_spec_->transport_cc_enabled || |
2055 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { | 1770 recv_nack_enabled_ != send_codec_spec_->nack_enabled) { |
2056 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1771 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
2057 "codec has changed."; | 1772 "codec has changed."; |
2058 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1773 recv_transport_cc_enabled_ = send_codec_spec_->transport_cc_enabled; |
2059 recv_nack_enabled_ = send_codec_spec_.nack_enabled; | 1774 recv_nack_enabled_ = send_codec_spec_->nack_enabled; |
2060 for (auto& kv : recv_streams_) { | 1775 for (auto& kv : recv_streams_) { |
2061 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, | 1776 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, |
2062 recv_nack_enabled_); | 1777 recv_nack_enabled_); |
2063 } | 1778 } |
2064 } | 1779 } |
2065 | 1780 |
2066 send_codecs_ = codecs; | 1781 send_codecs_ = codecs; |
2067 return true; | 1782 return true; |
2068 } | 1783 } |
2069 | 1784 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2172 // Save the channel to send_streams_, so that RemoveSendStream() can still | 1887 // Save the channel to send_streams_, so that RemoveSendStream() can still |
2173 // delete the channel in case failure happens below. | 1888 // delete the channel in case failure happens below. |
2174 webrtc::AudioTransport* audio_transport = | 1889 webrtc::AudioTransport* audio_transport = |
2175 engine()->voe()->base()->audio_transport(); | 1890 engine()->voe()->base()->audio_transport(); |
2176 | 1891 |
2177 rtc::Optional<std::string> audio_network_adaptor_config = | 1892 rtc::Optional<std::string> audio_network_adaptor_config = |
2178 GetAudioNetworkAdaptorConfig(options_); | 1893 GetAudioNetworkAdaptorConfig(options_); |
2179 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 1894 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( |
2180 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, | 1895 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, |
2181 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, | 1896 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, |
2182 call_, this); | 1897 call_, this, engine()->encoder_factory_); |
2183 send_streams_.insert(std::make_pair(ssrc, stream)); | 1898 send_streams_.insert(std::make_pair(ssrc, stream)); |
2184 | 1899 |
2185 // At this point the stream's local SSRC has been updated. If it is the first | 1900 // At this point the stream's local SSRC has been updated. If it is the first |
2186 // send stream, make sure that all the receive streams are updated with the | 1901 // send stream, make sure that all the receive streams are updated with the |
2187 // same SSRC in order to send receiver reports. | 1902 // same SSRC in order to send receiver reports. |
2188 if (send_streams_.size() == 1) { | 1903 if (send_streams_.size() == 1) { |
2189 receiver_reports_ssrc_ = ssrc; | 1904 receiver_reports_ssrc_ = ssrc; |
2190 for (const auto& kv : recv_streams_) { | 1905 for (const auto& kv : recv_streams_) { |
2191 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive | 1906 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive |
2192 // streams instead, so we can avoid recreating the streams here. | 1907 // streams instead, so we can avoid recreating the streams here. |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2693 ssrc); | 2408 ssrc); |
2694 if (it != unsignaled_recv_ssrcs_.end()) { | 2409 if (it != unsignaled_recv_ssrcs_.end()) { |
2695 unsignaled_recv_ssrcs_.erase(it); | 2410 unsignaled_recv_ssrcs_.erase(it); |
2696 return true; | 2411 return true; |
2697 } | 2412 } |
2698 return false; | 2413 return false; |
2699 } | 2414 } |
2700 } // namespace cricket | 2415 } // namespace cricket |
2701 | 2416 |
2702 #endif // HAVE_WEBRTC_VOICE | 2417 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |