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

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

Issue 2705093002: Injectable audio encoders: WebRtcVoiceEngine and company (Closed)
Patch Set: audio_send_spec made optional<>, EnableAudioNetworkAdapter now called directly on encoder, VAD supp… Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * 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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698