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

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

Issue 2705093002: Injectable audio encoders: WebRtcVoiceEngine and company (Closed)
Patch Set: Created 3 years, 10 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 19 matching lines...) Expand all
30 #include "webrtc/base/stringutils.h" 30 #include "webrtc/base/stringutils.h"
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/payload_type_mapper.h" 35 #include "webrtc/media/engine/payload_type_mapper.h"
36 #include "webrtc/media/engine/webrtcmediaengine.h" 36 #include "webrtc/media/engine/webrtcmediaengine.h"
37 #include "webrtc/media/engine/webrtcvoe.h" 37 #include "webrtc/media/engine/webrtcvoe.h"
38 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" 38 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h"
39 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" 39 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h"
40 #include "webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory.h"
40 #include "webrtc/modules/audio_processing/include/audio_processing.h" 41 #include "webrtc/modules/audio_processing/include/audio_processing.h"
41 #include "webrtc/system_wrappers/include/field_trial.h" 42 #include "webrtc/system_wrappers/include/field_trial.h"
42 #include "webrtc/system_wrappers/include/trace.h" 43 #include "webrtc/system_wrappers/include/trace.h"
43 44
44 namespace cricket { 45 namespace cricket {
45 namespace { 46 namespace {
46 47
47 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | 48 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo |
48 webrtc::kTraceWarning | webrtc::kTraceError | 49 webrtc::kTraceWarning | webrtc::kTraceError |
49 webrtc::kTraceCritical; 50 webrtc::kTraceCritical;
(...skipping 15 matching lines...) Expand all
65 constexpr int kNackRtpHistoryMs = 5000; 66 constexpr int kNackRtpHistoryMs = 5000;
66 67
67 // Check to verify that the define for the intelligibility enhancer is properly 68 // Check to verify that the define for the intelligibility enhancer is properly
68 // set. 69 // set.
69 #if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \ 70 #if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \
70 (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \ 71 (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \
71 WEBRTC_INTELLIGIBILITY_ENHANCER != 1) 72 WEBRTC_INTELLIGIBILITY_ENHANCER != 1)
72 #error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1" 73 #error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1"
73 #endif 74 #endif
74 75
75 // Codec parameters for Opus. 76 // For SendSideBwe, Opus bitrate should be in the range between 6000 and 32000.
76 // draft-spittka-payload-rtp-opus-03 77 const int kOpusMinBitrateBps = 6000;
77
78 // Recommended bitrates:
79 // 8-12 kb/s for NB speech,
80 // 16-20 kb/s for WB speech,
81 // 28-40 kb/s for FB speech,
82 // 48-64 kb/s for FB mono music, and
83 // 64-128 kb/s for FB stereo music.
84 // The current implementation applies the following values to mono signals,
85 // and multiplies them by 2 for stereo.
86 const int kOpusBitrateNbBps = 12000;
87 const int kOpusBitrateWbBps = 20000;
88 const int kOpusBitrateFbBps = 32000; 78 const int kOpusBitrateFbBps = 32000;
89 79
90 // Opus bitrate should be in the range between 6000 and 510000.
91 const int kOpusMinBitrateBps = 6000;
92 const int kOpusMaxBitrateBps = 510000;
93
94 // iSAC bitrate should be <= 56000.
95 const int kIsacMaxBitrateBps = 56000;
96
97 // Default audio dscp value. 80 // Default audio dscp value.
98 // See http://tools.ietf.org/html/rfc2474 for details. 81 // See http://tools.ietf.org/html/rfc2474 for details.
99 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 82 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00
100 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; 83 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF;
101 84
102 // Constants from voice_engine_defines.h. 85 // Constants from voice_engine_defines.h.
103 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) 86 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1)
104 const int kMaxTelephoneEventCode = 255; 87 const int kMaxTelephoneEventCode = 255;
105 const int kMinTelephoneEventDuration = 100; 88 const int kMinTelephoneEventDuration = 100;
106 const int kMaxTelephoneEventDuration = 60000; // Actual limit is 2^16 89 const int kMaxTelephoneEventDuration = 60000; // Actual limit is 2^16
(...skipping 19 matching lines...) Expand all
126 if (sp.ssrcs.size() > 1) { 109 if (sp.ssrcs.size() > 1) {
127 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); 110 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString();
128 return false; 111 return false;
129 } 112 }
130 return true; 113 return true;
131 } 114 }
132 115
133 // Dumps an AudioCodec in RFC 2327-ish format. 116 // Dumps an AudioCodec in RFC 2327-ish format.
134 std::string ToString(const AudioCodec& codec) { 117 std::string ToString(const AudioCodec& codec) {
135 std::stringstream ss; 118 std::stringstream ss;
136 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels 119 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels;
137 << " (" << codec.id << ")"; 120 ss << " {";
121 for (const auto& param : codec.params) {
122 ss << " " << param.first << "=" << param.second;
123 }
124 ss << " }";
125 ss << " (" << codec.id << ")";
138 return ss.str(); 126 return ss.str();
139 } 127 }
140 128
141 std::string ToString(const webrtc::CodecInst& codec) { 129 std::string ToString(const webrtc::CodecInst& codec) {
142 std::stringstream ss; 130 std::stringstream ss;
143 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels 131 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels
144 << " (" << codec.pltype << ")"; 132 << " (" << codec.pltype << ")";
145 return ss.str(); 133 return ss.str();
146 } 134 }
147 135
(...skipping 25 matching lines...) Expand all
173 } 161 }
174 std::vector<int> payload_types; 162 std::vector<int> payload_types;
175 for (const AudioCodec& codec : codecs) { 163 for (const AudioCodec& codec : codecs) {
176 payload_types.push_back(codec.id); 164 payload_types.push_back(codec.id);
177 } 165 }
178 std::sort(payload_types.begin(), payload_types.end()); 166 std::sort(payload_types.begin(), payload_types.end());
179 auto it = std::unique(payload_types.begin(), payload_types.end()); 167 auto it = std::unique(payload_types.begin(), payload_types.end());
180 return it == payload_types.end(); 168 return it == payload_types.end();
181 } 169 }
182 170
183 // Return true if codec.params[feature] == "1", false otherwise.
184 bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) {
185 int value;
186 return codec.GetParam(feature, &value) && value == 1;
187 }
188
189 rtc::Optional<std::string> GetAudioNetworkAdaptorConfig( 171 rtc::Optional<std::string> GetAudioNetworkAdaptorConfig(
190 const AudioOptions& options) { 172 const AudioOptions& options) {
191 if (options.audio_network_adaptor && *options.audio_network_adaptor && 173 if (options.audio_network_adaptor && *options.audio_network_adaptor &&
192 options.audio_network_adaptor_config) { 174 options.audio_network_adaptor_config) {
193 // Turn on audio network adaptor only when |options_.audio_network_adaptor| 175 // Turn on audio network adaptor only when |options_.audio_network_adaptor|
194 // equals true and |options_.audio_network_adaptor_config| has a value. 176 // equals true and |options_.audio_network_adaptor_config| has a value.
195 return options.audio_network_adaptor_config; 177 return options.audio_network_adaptor_config;
196 } 178 }
197 return rtc::Optional<std::string>(); 179 return rtc::Optional<std::string>();
198 } 180 }
199 181
200 // Returns integer parameter params[feature] if it is defined. Returns
201 // |default_value| otherwise.
202 int GetCodecFeatureInt(const AudioCodec& codec,
203 const char* feature,
204 int default_value) {
205 int value = 0;
206 if (codec.GetParam(feature, &value)) {
207 return value;
208 }
209 return default_value;
210 }
211
212 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate
213 // otherwise. If the value (either from params or codec.bitrate) <=0, use the
214 // default configuration. If the value is beyond feasible bit rate of Opus,
215 // clamp it. Returns the Opus bit rate for operation.
216 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) {
217 int bitrate = 0;
218 bool use_param = true;
219 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) {
220 bitrate = codec.bitrate;
221 use_param = false;
222 }
223 if (bitrate <= 0) {
224 if (max_playback_rate <= 8000) {
225 bitrate = kOpusBitrateNbBps;
226 } else if (max_playback_rate <= 16000) {
227 bitrate = kOpusBitrateWbBps;
228 } else {
229 bitrate = kOpusBitrateFbBps;
230 }
231
232 if (IsCodecFeatureEnabled(codec, kCodecParamStereo)) {
233 bitrate *= 2;
234 }
235 } else if (bitrate < kOpusMinBitrateBps || bitrate > kOpusMaxBitrateBps) {
236 bitrate = (bitrate < kOpusMinBitrateBps) ? kOpusMinBitrateBps
237 : kOpusMaxBitrateBps;
238 std::string rate_source =
239 use_param ? "Codec parameter \"maxaveragebitrate\"" :
240 "Supplied Opus bitrate";
241 LOG(LS_WARNING) << rate_source
242 << " is invalid and is replaced by: "
243 << bitrate;
244 }
245 return bitrate;
246 }
247
248 void GetOpusConfig(const AudioCodec& codec,
249 webrtc::CodecInst* voe_codec,
250 bool* enable_codec_fec,
251 int* max_playback_rate,
252 bool* enable_codec_dtx,
253 int* min_ptime_ms,
254 int* max_ptime_ms) {
255 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec);
256 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx);
257 *max_playback_rate = GetCodecFeatureInt(codec, kCodecParamMaxPlaybackRate,
258 kOpusDefaultMaxPlaybackRate);
259 *max_ptime_ms =
260 GetCodecFeatureInt(codec, kCodecParamMaxPTime, kOpusDefaultMaxPTime);
261 *min_ptime_ms =
262 GetCodecFeatureInt(codec, kCodecParamMinPTime, kOpusDefaultMinPTime);
263 if (*max_ptime_ms < *min_ptime_ms) {
264 // If min ptime or max ptime defined by codec parameter is wrong, we use
265 // the default values.
266 *max_ptime_ms = kOpusDefaultMaxPTime;
267 *min_ptime_ms = kOpusDefaultMinPTime;
268 }
269
270 // If OPUS, change what we send according to the "stereo" codec
271 // parameter, and not the "channels" parameter. We set
272 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If
273 // the bitrate is not specified, i.e. is <= zero, we set it to the
274 // appropriate default value for mono or stereo Opus.
275 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1;
276 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate);
277 }
278
279 webrtc::AudioState::Config MakeAudioStateConfig( 182 webrtc::AudioState::Config MakeAudioStateConfig(
280 VoEWrapper* voe_wrapper, 183 VoEWrapper* voe_wrapper,
281 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) { 184 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) {
282 webrtc::AudioState::Config config; 185 webrtc::AudioState::Config config;
283 config.voice_engine = voe_wrapper->engine(); 186 config.voice_engine = voe_wrapper->engine();
284 if (audio_mixer) { 187 if (audio_mixer) {
285 config.audio_mixer = audio_mixer; 188 config.audio_mixer = audio_mixer;
286 } else { 189 } else {
287 config.audio_mixer = webrtc::AudioMixerImpl::Create(); 190 config.audio_mixer = webrtc::AudioMixerImpl::Create();
288 } 191 }
289 return config; 192 return config;
290 } 193 }
291 194
292 class WebRtcVoiceCodecs final { 195 class WebRtcVoiceCodecs final {
293 public: 196 public:
294 // TODO(solenberg): Do this filtering once off-line, add a simple AudioCodec 197 static bool ToCodecInst(const AudioCodec& in, webrtc::CodecInst* out) {
ossu 2017/02/21 11:04:14 With the cleanup of a couple of more tests, this o
295 // list and add a test which verifies VoE supports the listed codecs.
296 static std::vector<AudioCodec> SupportedSendCodecs() {
297 std::vector<AudioCodec> result;
298 // Iterate first over our preferred codecs list, so that the results are
299 // added in order of preference.
300 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) {
301 const CodecPref* pref = &kCodecPrefs[i];
302 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
303 // Change the sample rate of G722 to 8000 to match SDP.
304 MaybeFixupG722(&voe_codec, 8000);
305 // Skip uncompressed formats.
306 if (IsCodec(voe_codec, kL16CodecName)) {
307 continue;
308 }
309
310 if (!IsCodec(voe_codec, pref->name) ||
311 pref->clockrate != voe_codec.plfreq ||
312 pref->channels != voe_codec.channels) {
313 // Not a match.
314 continue;
315 }
316
317 AudioCodec codec(pref->payload_type, voe_codec.plname, voe_codec.plfreq,
318 voe_codec.rate, voe_codec.channels);
319 LOG(LS_INFO) << "Adding supported codec: " << ToString(codec);
320 if (IsCodec(codec, kIsacCodecName)) {
321 // Indicate auto-bitrate in signaling.
322 codec.bitrate = 0;
323 }
324 if (IsCodec(codec, kOpusCodecName)) {
325 // Only add fmtp parameters that differ from the spec.
326 if (kPreferredMinPTime != kOpusDefaultMinPTime) {
327 codec.params[kCodecParamMinPTime] =
328 rtc::ToString(kPreferredMinPTime);
329 }
330 if (kPreferredMaxPTime != kOpusDefaultMaxPTime) {
331 codec.params[kCodecParamMaxPTime] =
332 rtc::ToString(kPreferredMaxPTime);
333 }
334 codec.SetParam(kCodecParamUseInbandFec, 1);
335 codec.AddFeedbackParam(
336 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty));
337
338 // TODO(hellner): Add ptime, sprop-stereo, and stereo
339 // when they can be set to values other than the default.
340 }
341 result.push_back(codec);
342 }
343 }
344 return result;
345 }
346
347 static bool ToCodecInst(const AudioCodec& in,
348 webrtc::CodecInst* out) {
349 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { 198 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
350 // Change the sample rate of G722 to 8000 to match SDP. 199 // Change the sample rate of G722 to 8000 to match SDP.
351 MaybeFixupG722(&voe_codec, 8000); 200 MaybeFixupG722(&voe_codec, 8000);
352 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, 201 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq,
353 voe_codec.rate, voe_codec.channels); 202 voe_codec.rate, voe_codec.channels);
354 bool multi_rate = IsCodecMultiRate(voe_codec); 203 const bool multi_rate =
204 IsCodec(codec, kIsacCodecName) || IsCodec(codec, kOpusCodecName);
355 // Allow arbitrary rates for ISAC to be specified. 205 // Allow arbitrary rates for ISAC to be specified.
356 if (multi_rate) { 206 if (multi_rate) {
357 // Set codec.bitrate to 0 so the check for codec.Matches() passes. 207 // Set codec.bitrate to 0 so the check for codec.Matches() passes.
358 codec.bitrate = 0; 208 codec.bitrate = 0;
359 } 209 }
360 if (codec.Matches(in)) { 210 if (codec.Matches(in)) {
361 if (out) { 211 if (out) {
362 // Fixup the payload type. 212 // Fixup the payload type.
363 voe_codec.pltype = in.id; 213 voe_codec.pltype = in.id;
364 214
365 // Set bitrate if specified. 215 // Set bitrate if specified.
366 if (multi_rate && in.bitrate != 0) { 216 if (multi_rate && in.bitrate != 0) {
367 voe_codec.rate = in.bitrate; 217 voe_codec.rate = in.bitrate;
368 } 218 }
369 219
370 // Reset G722 sample rate to 16000 to match WebRTC. 220 // Reset G722 sample rate to 16000 to match WebRTC.
371 MaybeFixupG722(&voe_codec, 16000); 221 MaybeFixupG722(&voe_codec, 16000);
372 222
373 *out = voe_codec; 223 *out = voe_codec;
374 } 224 }
375 return true; 225 return true;
376 } 226 }
377 } 227 }
378 return false; 228 return false;
379 } 229 }
380 230
381 static bool IsCodecMultiRate(const webrtc::CodecInst& codec) {
382 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) {
383 if (IsCodec(codec, kCodecPrefs[i].name) &&
384 kCodecPrefs[i].clockrate == codec.plfreq) {
385 return kCodecPrefs[i].is_multi_rate;
386 }
387 }
388 return false;
389 }
390
391 static int MaxBitrateBps(const webrtc::CodecInst& codec) {
392 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) {
393 if (IsCodec(codec, kCodecPrefs[i].name) &&
394 kCodecPrefs[i].clockrate == codec.plfreq) {
395 return kCodecPrefs[i].max_bitrate_bps;
396 }
397 }
398 return 0;
399 }
400
401 static rtc::ArrayView<const int> GetPacketSizesMs(
402 const webrtc::CodecInst& codec) {
403 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) {
404 if (IsCodec(codec, kCodecPrefs[i].name)) {
405 size_t num_packet_sizes = kMaxNumPacketSize;
406 for (int index = 0; index < kMaxNumPacketSize; index++) {
407 if (kCodecPrefs[i].packet_sizes_ms[index] == 0) {
408 num_packet_sizes = index;
409 break;
410 }
411 }
412 return rtc::ArrayView<const int>(kCodecPrefs[i].packet_sizes_ms,
413 num_packet_sizes);
414 }
415 }
416 return rtc::ArrayView<const int>();
417 }
418
419 // If the AudioCodec param kCodecParamPTime is set, then we will set it to
420 // codec pacsize if it's valid, or we will pick the next smallest value we
421 // support.
422 // TODO(Brave): Query supported packet sizes from ACM when the API is ready.
423 static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) {
424 for (const CodecPref& codec_pref : kCodecPrefs) {
425 if ((IsCodec(*codec, codec_pref.name) &&
426 codec_pref.clockrate == codec->plfreq) ||
427 IsCodec(*codec, kG722CodecName)) {
428 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms);
429 if (packet_size_ms) {
430 // Convert unit from milli-seconds to samples.
431 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms;
432 return true;
433 }
434 }
435 }
436 return false;
437 }
438
439 static const AudioCodec* GetPreferredCodec(
440 const std::vector<AudioCodec>& codecs,
441 webrtc::CodecInst* out) {
442 RTC_DCHECK(out);
443 // Select the preferred send codec (the first non-telephone-event/CN codec).
444 for (const AudioCodec& codec : codecs) {
445 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) {
446 // Skip telephone-event/CN codecs - they will be handled later.
447 continue;
448 }
449
450 // We'll use the first codec in the list to actually send audio data.
451 // Be sure to use the payload type requested by the remote side.
452 // Ignore codecs we don't know about. The negotiation step should prevent
453 // this, but double-check to be sure.
454 if (!ToCodecInst(codec, out)) {
455 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
456 continue;
457 }
458 return &codec;
459 }
460 return nullptr;
461 }
462
463 private:
464 static const int kMaxNumPacketSize = 6;
465 struct CodecPref {
466 const char* name;
467 int clockrate;
468 size_t channels;
469 int payload_type;
470 bool is_multi_rate;
471 int packet_sizes_ms[kMaxNumPacketSize];
472 int max_bitrate_bps;
473 };
474 // Note: keep the supported packet sizes in ascending order.
475 static const CodecPref kCodecPrefs[14];
476
477 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) {
478 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0];
479 for (int packet_size_ms : codec_pref.packet_sizes_ms) {
480 if (packet_size_ms && packet_size_ms <= ptime_ms) {
481 selected_packet_size_ms = packet_size_ms;
482 }
483 }
484 return selected_packet_size_ms;
485 }
486
487 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC 231 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC
488 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz 232 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz
489 // codec. 233 // codec.
490 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { 234 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) {
491 if (IsCodec(*voe_codec, kG722CodecName)) { 235 if (IsCodec(*voe_codec, kG722CodecName)) {
492 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine 236 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine
493 // has changed, and this special case is no longer needed. 237 // has changed, and this special case is no longer needed.
494 RTC_DCHECK(voe_codec->plfreq != new_plfreq); 238 RTC_DCHECK(voe_codec->plfreq != new_plfreq);
495 voe_codec->plfreq = new_plfreq; 239 voe_codec->plfreq = new_plfreq;
496 } 240 }
497 } 241 }
498 }; 242 };
499 243
500 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[14] = {
501 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME
502 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60, 120},
503 kOpusMaxBitrateBps},
504 #else
505 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrateBps},
506 #endif
507 {kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrateBps},
508 {kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrateBps},
509 // G722 should be advertised as 8000 Hz because of the RFC "bug".
510 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}},
511 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}},
512 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}},
513 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}},
514 {kCnCodecName, 32000, 1, 106, false, {}},
515 {kCnCodecName, 16000, 1, 105, false, {}},
516 {kCnCodecName, 8000, 1, 13, false, {}},
517 {kDtmfCodecName, 48000, 1, 110, false, {}},
518 {kDtmfCodecName, 32000, 1, 112, false, {}},
519 {kDtmfCodecName, 16000, 1, 113, false, {}},
520 {kDtmfCodecName, 8000, 1, 126, false, {}}
521 };
522
523 // |max_send_bitrate_bps| is the bitrate from "b=" in SDP. 244 // |max_send_bitrate_bps| is the bitrate from "b=" in SDP.
524 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters. 245 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters.
525 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, 246 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps,
526 rtc::Optional<int> rtp_max_bitrate_bps, 247 rtc::Optional<int> rtp_max_bitrate_bps,
527 const webrtc::CodecInst& codec_inst) { 248 const webrtc::AudioCodecSpec& spec) {
528 // If application-configured bitrate is set, take minimum of that and SDP 249 // If application-configured bitrate is set, take minimum of that and SDP
529 // bitrate. 250 // bitrate.
530 const int bps = rtp_max_bitrate_bps 251 const int bps = rtp_max_bitrate_bps
531 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps) 252 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps)
532 : max_send_bitrate_bps; 253 : max_send_bitrate_bps;
533 const int codec_rate = codec_inst.rate;
534
535 if (bps <= 0) { 254 if (bps <= 0) {
536 return rtc::Optional<int>(codec_rate); 255 return rtc::Optional<int>(spec.info.default_bitrate_bps);
537 } 256 }
538 257
539 if (codec_inst.pltype == -1) { 258 // TODO(ossu): ????
ossu 2017/02/21 11:04:14 I ... don't know why this early-out was here befor
540 return rtc::Optional<int>(codec_rate); 259 // if (codec_inst.pltype == -1) {
541 ; 260 // return rtc::Optional<int>(codec_rate);
542 } 261 // }
543 262
544 if (WebRtcVoiceCodecs::IsCodecMultiRate(codec_inst)) { 263 if (bps < spec.info.min_bitrate_bps) {
545 // If codec is multi-rate then just set the bitrate.
546 return rtc::Optional<int>(
547 std::min(bps, WebRtcVoiceCodecs::MaxBitrateBps(codec_inst)));
548 }
549
550 if (bps < codec_inst.rate) {
551 // If codec is not multi-rate and |bps| is less than the fixed bitrate then 264 // If codec is not multi-rate and |bps| is less than the fixed bitrate then
552 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed 265 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed
553 // bitrate then ignore. 266 // bitrate then ignore.
kwiberg-webrtc 2017/02/21 23:35:03 This comment doesn't seem entirely accurate. And i
554 LOG(LS_ERROR) << "Failed to set codec " << codec_inst.plname 267 LOG(LS_ERROR) << "Failed to set codec " << spec.format.name
555 << " to bitrate " << bps << " bps" 268 << " to bitrate " << bps << " bps"
556 << ", requires at least " << codec_inst.rate << " bps."; 269 << ", requires at least " << spec.info.min_bitrate_bps
270 << " bps.";
557 return rtc::Optional<int>(); 271 return rtc::Optional<int>();
558 } 272 }
559 return rtc::Optional<int>(codec_rate); 273
274 if (spec.info.HasFixedBitrate()) {
275 return rtc::Optional<int>(spec.info.default_bitrate_bps);
276 } else {
277 // If codec is multi-rate then just set the bitrate.
278 return rtc::Optional<int>(std::min(bps, spec.info.max_bitrate_bps));
279 }
560 } 280 }
561 281
562 } // namespace { 282 } // namespace
563 283
564 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, 284 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in,
565 webrtc::CodecInst* out) { 285 webrtc::CodecInst* out) {
566 return WebRtcVoiceCodecs::ToCodecInst(in, out); 286 return WebRtcVoiceCodecs::ToCodecInst(in, out);
567 } 287 }
568 288
569 WebRtcVoiceEngine::WebRtcVoiceEngine( 289 WebRtcVoiceEngine::WebRtcVoiceEngine(
570 webrtc::AudioDeviceModule* adm, 290 webrtc::AudioDeviceModule* adm,
571 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, 291 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory,
572 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) 292 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer)
573 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) { 293 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) {
574 audio_state_ = 294 audio_state_ =
575 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer)); 295 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer));
576 } 296 }
577 297
578 WebRtcVoiceEngine::WebRtcVoiceEngine( 298 WebRtcVoiceEngine::WebRtcVoiceEngine(
579 webrtc::AudioDeviceModule* adm, 299 webrtc::AudioDeviceModule* adm,
580 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, 300 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory,
581 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, 301 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
582 VoEWrapper* voe_wrapper) 302 VoEWrapper* voe_wrapper)
583 : adm_(adm), decoder_factory_(decoder_factory), voe_wrapper_(voe_wrapper) { 303 : adm_(adm),
304 encoder_factory_(webrtc::CreateBuiltinAudioEncoderFactory()),
305 decoder_factory_(decoder_factory),
306 voe_wrapper_(voe_wrapper) {
584 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 307 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
585 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; 308 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
586 RTC_DCHECK(voe_wrapper); 309 RTC_DCHECK(voe_wrapper);
587 RTC_DCHECK(decoder_factory); 310 RTC_DCHECK(decoder_factory);
588 311
589 signal_thread_checker_.DetachFromThread(); 312 signal_thread_checker_.DetachFromThread();
590 313
591 // Load our audio codec list. 314 // Load our audio codec list.
592 LOG(LS_INFO) << "Supported send codecs in order of preference:"; 315 LOG(LS_INFO) << "Supported send codecs in order of preference:";
593 send_codecs_ = WebRtcVoiceCodecs::SupportedSendCodecs(); 316 send_codecs_ = CollectCodecs(encoder_factory_->GetSupportedEncoders());
594 for (const AudioCodec& codec : send_codecs_) { 317 for (const AudioCodec& codec : send_codecs_) {
595 LOG(LS_INFO) << ToString(codec); 318 LOG(LS_INFO) << ToString(codec);
596 } 319 }
597 320
598 LOG(LS_INFO) << "Supported recv codecs in order of preference:"; 321 LOG(LS_INFO) << "Supported recv codecs in order of preference:";
599 recv_codecs_ = CollectRecvCodecs(); 322 recv_codecs_ = CollectCodecs(decoder_factory_->GetSupportedDecoders());
600 for (const AudioCodec& codec : recv_codecs_) { 323 for (const AudioCodec& codec : recv_codecs_) {
601 LOG(LS_INFO) << ToString(codec); 324 LOG(LS_INFO) << ToString(codec);
602 } 325 }
603 326
604 channel_config_.enable_voice_pacing = true; 327 channel_config_.enable_voice_pacing = true;
605 328
606 // Temporarily turn logging level up for the Init() call. 329 // Temporarily turn logging level up for the Init() call.
607 webrtc::Trace::SetTraceCallback(this); 330 webrtc::Trace::SetTraceCallback(this);
608 webrtc::Trace::set_level_filter(kElevatedTraceFilter); 331 webrtc::Trace::set_level_filter(kElevatedTraceFilter);
609 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString(); 332 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString();
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 RTC_DCHECK(adm_); 864 RTC_DCHECK(adm_);
1142 return adm_; 865 return adm_;
1143 } 866 }
1144 867
1145 webrtc::AudioProcessing* WebRtcVoiceEngine::apm() { 868 webrtc::AudioProcessing* WebRtcVoiceEngine::apm() {
1146 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 869 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1147 RTC_DCHECK(apm_); 870 RTC_DCHECK(apm_);
1148 return apm_; 871 return apm_;
1149 } 872 }
1150 873
1151 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { 874 AudioCodecs WebRtcVoiceEngine::CollectCodecs(
875 const std::vector<webrtc::AudioCodecSpec>& specs) const {
1152 PayloadTypeMapper mapper; 876 PayloadTypeMapper mapper;
1153 AudioCodecs out; 877 AudioCodecs out;
1154 const std::vector<webrtc::AudioCodecSpec>& specs =
1155 decoder_factory_->GetSupportedDecoders();
1156 878
1157 // Only generate CN payload types for these clockrates: 879 // Only generate CN payload types for these clockrates:
1158 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, 880 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false },
1159 { 16000, false }, 881 { 16000, false },
1160 { 32000, false }}; 882 { 32000, false }};
1161 // Only generate telephone-event payload types for these clockrates: 883 // Only generate telephone-event payload types for these clockrates:
1162 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, 884 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false },
1163 { 16000, false }, 885 { 16000, false },
1164 { 32000, false }, 886 { 32000, false },
1165 { 48000, false }}; 887 { 48000, false }};
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 WebRtcAudioSendStream( 952 WebRtcAudioSendStream(
1231 int ch, 953 int ch,
1232 webrtc::AudioTransport* voe_audio_transport, 954 webrtc::AudioTransport* voe_audio_transport,
1233 uint32_t ssrc, 955 uint32_t ssrc,
1234 const std::string& c_name, 956 const std::string& c_name,
1235 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, 957 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec,
1236 const std::vector<webrtc::RtpExtension>& extensions, 958 const std::vector<webrtc::RtpExtension>& extensions,
1237 int max_send_bitrate_bps, 959 int max_send_bitrate_bps,
1238 const rtc::Optional<std::string>& audio_network_adaptor_config, 960 const rtc::Optional<std::string>& audio_network_adaptor_config,
1239 webrtc::Call* call, 961 webrtc::Call* call,
1240 webrtc::Transport* send_transport) 962 webrtc::Transport* send_transport,
963 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& encoder_factory)
1241 : voe_audio_transport_(voe_audio_transport), 964 : voe_audio_transport_(voe_audio_transport),
1242 call_(call), 965 call_(call),
1243 config_(send_transport), 966 config_(send_transport),
1244 send_side_bwe_with_overhead_(webrtc::field_trial::FindFullName( 967 send_side_bwe_with_overhead_(webrtc::field_trial::FindFullName(
1245 "WebRTC-SendSideBwe-WithOverhead") == "Enabled"), 968 "WebRTC-SendSideBwe-WithOverhead") == "Enabled"),
1246 max_send_bitrate_bps_(max_send_bitrate_bps), 969 max_send_bitrate_bps_(max_send_bitrate_bps),
1247 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { 970 rtp_parameters_(CreateRtpParametersWithOneEncoding()) {
1248 RTC_DCHECK_GE(ch, 0); 971 RTC_DCHECK_GE(ch, 0);
1249 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: 972 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore:
1250 // RTC_DCHECK(voe_audio_transport); 973 // RTC_DCHECK(voe_audio_transport);
1251 RTC_DCHECK(call); 974 RTC_DCHECK(call);
975 RTC_DCHECK(encoder_factory);
1252 config_.rtp.ssrc = ssrc; 976 config_.rtp.ssrc = ssrc;
1253 config_.rtp.c_name = c_name; 977 config_.rtp.c_name = c_name;
1254 config_.voe_channel_id = ch; 978 config_.voe_channel_id = ch;
1255 config_.rtp.extensions = extensions; 979 config_.rtp.extensions = extensions;
1256 config_.audio_network_adaptor_config = audio_network_adaptor_config; 980 config_.audio_network_adaptor_config = audio_network_adaptor_config;
981 config_.encoder_factory = encoder_factory;
1257 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc); 982 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc);
1258 RecreateAudioSendStream(send_codec_spec); 983 RecreateAudioSendStream(send_codec_spec);
1259 } 984 }
1260 985
1261 ~WebRtcAudioSendStream() override { 986 ~WebRtcAudioSendStream() override {
1262 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 987 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1263 ClearSource(); 988 ClearSource();
1264 call_->DestroyAudioSendStream(stream_); 989 call_->DestroyAudioSendStream(stream_);
1265 } 990 }
1266 991
1267 void RecreateAudioSendStream( 992 void RecreateAudioSendStream(
1268 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { 993 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) {
1269 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 994 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1270 send_codec_spec_ = send_codec_spec; 995 send_codec_spec_ = send_codec_spec;
1271 config_.rtp.nack.rtp_history_ms = 996 config_.rtp.nack.rtp_history_ms =
1272 send_codec_spec_.nack_enabled ? kNackRtpHistoryMs : 0; 997 send_codec_spec_.nack_enabled ? kNackRtpHistoryMs : 0;
1273 config_.send_codec_spec = send_codec_spec_; 998 config_.send_codec_spec = send_codec_spec_;
1274 auto send_rate = ComputeSendBitrate( 999 // TODO(ossu): This is strange, since we're changing our send_codec_spec,
1000 // overwriting values we just got.
1001 config_.send_codec_spec.target_bitrate_bps = ComputeSendBitrate(
1275 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, 1002 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps,
1276 send_codec_spec.codec_inst); 1003 config_.send_codec_spec.format);
1277 if (send_rate) {
1278 // Apply a send rate that abides by |max_send_bitrate_bps_| and
1279 // |rtp_parameters_| when possible. Otherwise use the codec rate.
1280 config_.send_codec_spec.codec_inst.rate = *send_rate;
1281 }
1282 RecreateAudioSendStream(); 1004 RecreateAudioSendStream();
1283 } 1005 }
1284 1006
1285 void RecreateAudioSendStream( 1007 void RecreateAudioSendStream(
1286 const std::vector<webrtc::RtpExtension>& extensions) { 1008 const std::vector<webrtc::RtpExtension>& extensions) {
1287 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1009 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1288 config_.rtp.extensions = extensions; 1010 config_.rtp.extensions = extensions;
1289 RecreateAudioSendStream(); 1011 RecreateAudioSendStream();
1290 } 1012 }
1291 1013
1292 void RecreateAudioSendStream( 1014 void RecreateAudioSendStream(
1293 const rtc::Optional<std::string>& audio_network_adaptor_config) { 1015 const rtc::Optional<std::string>& audio_network_adaptor_config) {
1294 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1016 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1295 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { 1017 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) {
1296 return; 1018 return;
1297 } 1019 }
1298 config_.audio_network_adaptor_config = audio_network_adaptor_config; 1020 config_.audio_network_adaptor_config = audio_network_adaptor_config;
1299 RecreateAudioSendStream(); 1021 RecreateAudioSendStream();
1300 } 1022 }
1301 1023
1302 bool SetMaxSendBitrate(int bps) { 1024 bool SetMaxSendBitrate(int bps) {
1303 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1025 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1304 auto send_rate = 1026 auto send_rate =
1305 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps, 1027 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps,
1306 send_codec_spec_.codec_inst); 1028 config_.send_codec_spec.format);
1029
1307 if (!send_rate) { 1030 if (!send_rate) {
1308 return false; 1031 return false;
1309 } 1032 }
1310 1033
1311 max_send_bitrate_bps_ = bps; 1034 max_send_bitrate_bps_ = bps;
1312 1035
1313 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { 1036 if (send_rate != config_.send_codec_spec.target_bitrate_bps) {
1314 // Recreate AudioSendStream with new bit rate. 1037 // TODO(ossu): Should not recreate stream!
kwiberg-webrtc 2017/02/21 23:35:03 Because we should mutate the one we have?
1315 config_.send_codec_spec.codec_inst.rate = *send_rate; 1038 config_.send_codec_spec.target_bitrate_bps = send_rate;
1316 RecreateAudioSendStream(); 1039 RecreateAudioSendStream();
1317 } 1040 }
1318 return true; 1041 return true;
1319 } 1042 }
1320 1043
1321 bool SendTelephoneEvent(int payload_type, int payload_freq, int event, 1044 bool SendTelephoneEvent(int payload_type, int payload_freq, int event,
1322 int duration_ms) { 1045 int duration_ms) {
1323 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1046 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1324 RTC_DCHECK(stream_); 1047 RTC_DCHECK(stream_);
1325 return stream_->SendTelephoneEvent(payload_type, payload_freq, event, 1048 return stream_->SendTelephoneEvent(payload_type, payload_freq, event,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 } 1147 }
1425 return true; 1148 return true;
1426 } 1149 }
1427 1150
1428 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { 1151 bool SetRtpParameters(const webrtc::RtpParameters& parameters) {
1429 if (!ValidateRtpParameters(parameters)) { 1152 if (!ValidateRtpParameters(parameters)) {
1430 return false; 1153 return false;
1431 } 1154 }
1432 auto send_rate = ComputeSendBitrate(max_send_bitrate_bps_, 1155 auto send_rate = ComputeSendBitrate(max_send_bitrate_bps_,
1433 parameters.encodings[0].max_bitrate_bps, 1156 parameters.encodings[0].max_bitrate_bps,
1434 send_codec_spec_.codec_inst); 1157 config_.send_codec_spec.format);
1435 if (!send_rate) { 1158 if (!send_rate) {
1436 return false; 1159 return false;
1437 } 1160 }
1438 1161
1439 rtp_parameters_ = parameters; 1162 rtp_parameters_ = parameters;
1440 1163
1441 // parameters.encodings[0].encodings[0].max_bitrate_bps could have changed. 1164 // parameters.encodings[0].encodings[0].max_bitrate_bps could have changed.
1442 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { 1165 if (send_rate != config_.send_codec_spec.target_bitrate_bps) {
1166 // TODO(ossu): Should not recreate stream!
1443 // Recreate AudioSendStream with new bit rate. 1167 // Recreate AudioSendStream with new bit rate.
1444 config_.send_codec_spec.codec_inst.rate = *send_rate; 1168 config_.send_codec_spec.target_bitrate_bps = send_rate;
1445 RecreateAudioSendStream(); 1169 RecreateAudioSendStream();
1446 } else { 1170 } else {
1447 // parameters.encodings[0].active could have changed. 1171 // parameters.encodings[0].active could have changed.
1448 UpdateSendState(); 1172 UpdateSendState();
1449 } 1173 }
1450 return true; 1174 return true;
1451 } 1175 }
1452 1176
1453 private: 1177 private:
1454 void UpdateSendState() { 1178 void UpdateSendState() {
(...skipping 14 matching lines...) Expand all
1469 stream_ = nullptr; 1193 stream_ = nullptr;
1470 } 1194 }
1471 RTC_DCHECK(!stream_); 1195 RTC_DCHECK(!stream_);
1472 if (webrtc::field_trial::FindFullName("WebRTC-Audio-SendSideBwe") == 1196 if (webrtc::field_trial::FindFullName("WebRTC-Audio-SendSideBwe") ==
1473 "Enabled") { 1197 "Enabled") {
1474 config_.min_bitrate_bps = kOpusMinBitrateBps; 1198 config_.min_bitrate_bps = kOpusMinBitrateBps;
1475 config_.max_bitrate_bps = kOpusBitrateFbBps; 1199 config_.max_bitrate_bps = kOpusBitrateFbBps;
1476 // TODO(mflodman): Keep testing this and set proper values. 1200 // TODO(mflodman): Keep testing this and set proper values.
1477 // Note: This is an early experiment currently only supported by Opus. 1201 // Note: This is an early experiment currently only supported by Opus.
1478 if (send_side_bwe_with_overhead_) { 1202 if (send_side_bwe_with_overhead_) {
1479 auto packet_sizes_ms = WebRtcVoiceCodecs::GetPacketSizesMs( 1203 const bool is_opus_with_ana =
1480 config_.send_codec_spec.codec_inst); 1204 config_.audio_network_adaptor_config &&
1481 if (!packet_sizes_ms.empty()) { 1205 !STR_CASE_CMP(config_.send_codec_spec.format.format.name.c_str(),
1482 int max_packet_size_ms = 1206 kOpusCodecName);
1483 *std::max_element(packet_sizes_ms.begin(), packet_sizes_ms.end()); 1207 const int max_packet_size_ms =
1484 int min_packet_size_ms = 1208 (is_opus_with_ana && WEBRTC_OPUS_SUPPORT_120MS_PTIME) ? 120 : 60;
1485 *std::min_element(packet_sizes_ms.begin(), packet_sizes_ms.end()); 1209 // Audio network adaptor will just use 20ms and 60ms frame lengths.
1210 // The adaptor will only be active for the Opus encoder.
1211 const int min_packet_size_ms = is_opus_with_ana ? 20 : 10;
1486 1212
1487 // Audio network adaptor will just use 20ms and 60ms frame lengths. 1213 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
kwiberg-webrtc 2017/02/21 23:35:03 Missing B
1488 // The adaptor will only be active for the Opus encoder. 1214 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12;
1489 if (config_.audio_network_adaptor_config &&
1490 IsCodec(config_.send_codec_spec.codec_inst, kOpusCodecName)) {
1491 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME
1492 max_packet_size_ms = 120;
1493 #else
1494 max_packet_size_ms = 60;
1495 #endif
1496 min_packet_size_ms = 20;
1497 }
1498 1215
1499 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12) 1216 int min_overhead_bps =
1500 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12; 1217 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms;
1501 1218
1502 int min_overhead_bps = 1219 int max_overhead_bps =
1503 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms; 1220 kOverheadPerPacket * 8 * 1000 / min_packet_size_ms;
1504 1221
1505 int max_overhead_bps = 1222 config_.min_bitrate_bps = kOpusMinBitrateBps + min_overhead_bps;
1506 kOverheadPerPacket * 8 * 1000 / min_packet_size_ms; 1223 config_.max_bitrate_bps = kOpusBitrateFbBps + max_overhead_bps;
1507
1508 config_.min_bitrate_bps = kOpusMinBitrateBps + min_overhead_bps;
1509 config_.max_bitrate_bps = kOpusBitrateFbBps + max_overhead_bps;
1510 }
1511 } 1224 }
1512 } 1225 }
1513 stream_ = call_->CreateAudioSendStream(config_); 1226 stream_ = call_->CreateAudioSendStream(config_);
1514 RTC_CHECK(stream_); 1227 RTC_CHECK(stream_);
1515 UpdateSendState(); 1228 UpdateSendState();
1516 } 1229 }
1517 1230
1518 rtc::ThreadChecker worker_thread_checker_; 1231 rtc::ThreadChecker worker_thread_checker_;
1519 rtc::RaceChecker audio_capture_race_checker_; 1232 rtc::RaceChecker audio_capture_race_checker_;
1520 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; 1233 webrtc::AudioTransport* const voe_audio_transport_ = nullptr;
1521 webrtc::Call* call_ = nullptr; 1234 webrtc::Call* call_ = nullptr;
1522 webrtc::AudioSendStream::Config config_; 1235 webrtc::AudioSendStream::Config config_;
1523 const bool send_side_bwe_with_overhead_; 1236 const bool send_side_bwe_with_overhead_;
1524 // The stream is owned by WebRtcAudioSendStream and may be reallocated if 1237 // The stream is owned by WebRtcAudioSendStream and may be reallocated if
1525 // configuration changes. 1238 // configuration changes.
1526 webrtc::AudioSendStream* stream_ = nullptr; 1239 webrtc::AudioSendStream* stream_ = nullptr;
1527 1240
1528 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. 1241 // Raw pointer to AudioSource owned by LocalAudioTrackHandler.
1529 // PeerConnection will make sure invalidating the pointer before the object 1242 // PeerConnection will make sure invalidating the pointer before the object
1530 // goes away. 1243 // goes away.
1531 AudioSource* source_ = nullptr; 1244 AudioSource* source_ = nullptr;
1532 bool send_ = false; 1245 bool send_ = false;
1533 bool muted_ = false; 1246 bool muted_ = false;
1534 int max_send_bitrate_bps_; 1247 int max_send_bitrate_bps_;
1535 webrtc::RtpParameters rtp_parameters_; 1248 webrtc::RtpParameters rtp_parameters_;
1536 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec_; 1249 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec_;
1250 webrtc::AudioFormatInfo audio_format_info_;
ossu 2017/02/21 11:04:14 Not used. Will remove.
1537 1251
1538 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); 1252 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream);
1539 }; 1253 };
1540 1254
1541 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { 1255 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
1542 public: 1256 public:
1543 WebRtcAudioReceiveStream( 1257 WebRtcAudioReceiveStream(
1544 int ch, 1258 int ch,
1545 uint32_t remote_ssrc, 1259 uint32_t remote_ssrc,
1546 uint32_t local_ssrc, 1260 uint32_t local_ssrc,
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
1983 } 1697 }
1984 1698
1985 // Scan through the list to figure out the codec to use for sending, along 1699 // Scan through the list to figure out the codec to use for sending, along
1986 // with the proper configuration for VAD, CNG, NACK and Opus-specific 1700 // with the proper configuration for VAD, CNG, NACK and Opus-specific
1987 // parameters. 1701 // parameters.
1988 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. 1702 // TODO(solenberg): Refactor this logic once we create AudioEncoders here.
1989 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec; 1703 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec;
1990 { 1704 {
1991 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; 1705 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled;
1992 1706
1993 // Find send codec (the first non-telephone-event/CN codec). 1707 const AudioCodec* chosen_codec = nullptr;
1994 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( 1708 for (const auto& codec : codecs) {
1995 codecs, &send_codec_spec.codec_inst); 1709 if (!(IsCodec(codec, kCnCodecName) ||
1996 if (!codec) { 1710 IsCodec(codec, kDtmfCodecName) ||
1997 LOG(LS_WARNING) << "Received empty list of codecs."; 1711 IsCodec(codec, kRedCodecName))) {
kwiberg-webrtc 2017/02/21 23:35:03 To reduce indentation, invert this condition and "
1998 return false; 1712 webrtc::SdpAudioFormat format(codec.name, codec.clockrate,
1713 codec.channels,
1714 CodecParameterMap(codec.params));
1715
1716 auto info = engine()->encoder_factory_->QueryAudioFormat(format);
kwiberg-webrtc 2017/02/21 23:35:03 It may be useful to write out this type.
1717 // Ignore codecs we don't know about. The negotiation step should
1718 // prevent this, but double-check to be sure.
1719 if (!info) {
1720 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
1721 continue;
1722 }
1723
1724 // If a bitrate has been specified for the codec, use it over the
1725 // codec's default.
1726 if (codec.bitrate > 0) {
1727 info->default_bitrate_bps =
1728 std::max(info->min_bitrate_bps,
1729 std::min(info->max_bitrate_bps, codec.bitrate));
1730 }
1731
1732 chosen_codec = &codec;
1733 send_codec_spec.payload_type = chosen_codec->id;
1734 send_codec_spec.format.format = format;
1735 send_codec_spec.format.info = *info;
1736 send_codec_spec.transport_cc_enabled = HasTransportCc(*chosen_codec);
1737 send_codec_spec.nack_enabled = HasNack(*chosen_codec);
1738 bitrate_config_ = GetBitrateConfigForCodec(*chosen_codec);
1739 break;
1740 }
1999 } 1741 }
2000 1742
2001 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec); 1743 if (!chosen_codec)
2002 send_codec_spec.nack_enabled = HasNack(*codec); 1744 return false;
2003 bitrate_config_ = GetBitrateConfigForCodec(*codec);
2004 1745
2005 // For Opus as the send codec, we are to determine inband FEC, maximum
2006 // playback rate, and opus internal dtx.
2007 if (IsCodec(*codec, kOpusCodecName)) {
2008 GetOpusConfig(*codec, &send_codec_spec.codec_inst,
2009 &send_codec_spec.enable_codec_fec,
2010 &send_codec_spec.opus_max_playback_rate,
2011 &send_codec_spec.enable_opus_dtx,
2012 &send_codec_spec.min_ptime_ms,
2013 &send_codec_spec.max_ptime_ms);
2014 }
2015
2016 // Set packet size if the AudioCodec param kCodecParamPTime is set.
2017 int ptime_ms = 0;
2018 if (codec->GetParam(kCodecParamPTime, &ptime_ms)) {
2019 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize(
2020 &send_codec_spec.codec_inst, ptime_ms)) {
2021 LOG(LS_WARNING) << "Failed to set packet size for codec "
2022 << send_codec_spec.codec_inst.plname;
2023 return false;
2024 }
2025 }
2026 1746
2027 // Loop through the codecs list again to find the CN codec. 1747 // Loop through the codecs list again to find the CN codec.
2028 // TODO(solenberg): Break out into a separate function? 1748 // TODO(solenberg): Break out into a separate function?
2029 for (const AudioCodec& codec : codecs) { 1749 for (const AudioCodec& codec : codecs) {
2030 // Ignore codecs we don't know about. The negotiation step should prevent
2031 // this, but double-check to be sure.
2032 webrtc::CodecInst voe_codec = {0};
2033 if (!WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
2034 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
2035 continue;
2036 }
2037
2038 if (IsCodec(codec, kCnCodecName)) { 1750 if (IsCodec(codec, kCnCodecName)) {
2039 // Turn voice activity detection/comfort noise on if supported. 1751 // Turn voice activity detection/comfort noise on if supported.
2040 // Set the wideband CN payload type appropriately. 1752 // Set the wideband CN payload type appropriately.
2041 // (narrowband always uses the static payload type 13). 1753 // (narrowband always uses the static payload type 13).
2042 int cng_plfreq = -1; 1754 int cng_plfreq = -1;
2043 switch (codec.clockrate) { 1755 switch (codec.clockrate) {
2044 case 8000: 1756 case 8000:
2045 case 16000: 1757 case 16000:
2046 case 32000: 1758 case 32000:
2047 cng_plfreq = codec.clockrate; 1759 cng_plfreq = codec.clockrate;
2048 break; 1760 break;
2049 default: 1761 default:
2050 LOG(LS_WARNING) << "CN frequency " << codec.clockrate 1762 LOG(LS_WARNING) << "CN frequency " << codec.clockrate
2051 << " not supported."; 1763 << " not supported.";
2052 continue; 1764 continue;
2053 } 1765 }
2054 send_codec_spec.cng_payload_type = codec.id; 1766 send_codec_spec.cng_payload_type = codec.id;
2055 send_codec_spec.cng_plfreq = cng_plfreq; 1767 send_codec_spec.cng_plfreq = cng_plfreq;
2056 break; 1768 break;
2057 } 1769 }
2058 } 1770 }
2059 1771
2060 // Find the telephone-event PT exactly matching the preferred send codec. 1772 // Find the telephone-event PT exactly matching the preferred send codec.
2061 for (const AudioCodec& dtmf_codec : dtmf_codecs) { 1773 for (const AudioCodec& dtmf_codec : dtmf_codecs) {
2062 if (dtmf_codec.clockrate == codec->clockrate) { 1774 if (dtmf_codec.clockrate == chosen_codec->clockrate) {
2063 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id); 1775 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id);
2064 dtmf_payload_freq_ = dtmf_codec.clockrate; 1776 dtmf_payload_freq_ = dtmf_codec.clockrate;
2065 break; 1777 break;
2066 } 1778 }
2067 } 1779 }
2068 } 1780 }
2069 1781
2070 if (send_codec_spec_ != send_codec_spec) { 1782 if (send_codec_spec_ != send_codec_spec) {
2071 send_codec_spec_ = std::move(send_codec_spec); 1783 send_codec_spec_ = std::move(send_codec_spec);
2072 // Apply new settings to all streams. 1784 // Apply new settings to all streams.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2202 // Save the channel to send_streams_, so that RemoveSendStream() can still 1914 // Save the channel to send_streams_, so that RemoveSendStream() can still
2203 // delete the channel in case failure happens below. 1915 // delete the channel in case failure happens below.
2204 webrtc::AudioTransport* audio_transport = 1916 webrtc::AudioTransport* audio_transport =
2205 engine()->voe()->base()->audio_transport(); 1917 engine()->voe()->base()->audio_transport();
2206 1918
2207 rtc::Optional<std::string> audio_network_adaptor_config = 1919 rtc::Optional<std::string> audio_network_adaptor_config =
2208 GetAudioNetworkAdaptorConfig(options_); 1920 GetAudioNetworkAdaptorConfig(options_);
2209 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( 1921 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream(
2210 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, 1922 channel, audio_transport, ssrc, sp.cname, send_codec_spec_,
2211 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, 1923 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config,
2212 call_, this); 1924 call_, this, engine()->encoder_factory_);
2213 send_streams_.insert(std::make_pair(ssrc, stream)); 1925 send_streams_.insert(std::make_pair(ssrc, stream));
2214 1926
2215 // At this point the stream's local SSRC has been updated. If it is the first 1927 // At this point the stream's local SSRC has been updated. If it is the first
2216 // send stream, make sure that all the receive streams are updated with the 1928 // send stream, make sure that all the receive streams are updated with the
2217 // same SSRC in order to send receiver reports. 1929 // same SSRC in order to send receiver reports.
2218 if (send_streams_.size() == 1) { 1930 if (send_streams_.size() == 1) {
2219 receiver_reports_ssrc_ = ssrc; 1931 receiver_reports_ssrc_ = ssrc;
2220 for (const auto& kv : recv_streams_) { 1932 for (const auto& kv : recv_streams_) {
2221 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive 1933 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive
2222 // streams instead, so we can avoid recreating the streams here. 1934 // streams instead, so we can avoid recreating the streams here.
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
2698 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 2410 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
2699 const auto it = send_streams_.find(ssrc); 2411 const auto it = send_streams_.find(ssrc);
2700 if (it != send_streams_.end()) { 2412 if (it != send_streams_.end()) {
2701 return it->second->channel(); 2413 return it->second->channel();
2702 } 2414 }
2703 return -1; 2415 return -1;
2704 } 2416 }
2705 } // namespace cricket 2417 } // namespace cricket
2706 2418
2707 #endif // HAVE_WEBRTC_VOICE 2419 #endif // HAVE_WEBRTC_VOICE
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698