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

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

Issue 2705093002: Injectable audio encoders: WebRtcVoiceEngine and company (Closed)
Patch Set: Moved encoder creation up into AudioSendStream, bypassing most of Channel. 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.
the sun 2017/03/16 08:48:19 32000?
ossu 2017/03/20 18:19:48 Yup, seems so. I've just rearranged the code a bit
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 if (!codec.params.empty()) {
121 ss << " {";
122 for (const auto& param : codec.params) {
123 ss << " " << param.first << "=" << param.second;
124 }
kwiberg-webrtc 2017/03/01 12:26:47 Broken indentation. Also, isn't there a second par
ossu 2017/03/02 01:30:28 Wow, what happened here? :) I guess you're talking
125 ss << " }";
126 }
127 ss << " (" << codec.id << ")";
138 return ss.str(); 128 return ss.str();
139 } 129 }
140 130
141 std::string ToString(const webrtc::CodecInst& codec) { 131 std::string ToString(const webrtc::CodecInst& codec) {
142 std::stringstream ss; 132 std::stringstream ss;
143 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels 133 ss << codec.plname << "/" << codec.plfreq << "/" << codec.channels
144 << " (" << codec.pltype << ")"; 134 << " (" << codec.pltype << ")";
145 return ss.str(); 135 return ss.str();
146 } 136 }
147 137
(...skipping 25 matching lines...) Expand all
173 } 163 }
174 std::vector<int> payload_types; 164 std::vector<int> payload_types;
175 for (const AudioCodec& codec : codecs) { 165 for (const AudioCodec& codec : codecs) {
176 payload_types.push_back(codec.id); 166 payload_types.push_back(codec.id);
177 } 167 }
178 std::sort(payload_types.begin(), payload_types.end()); 168 std::sort(payload_types.begin(), payload_types.end());
179 auto it = std::unique(payload_types.begin(), payload_types.end()); 169 auto it = std::unique(payload_types.begin(), payload_types.end());
180 return it == payload_types.end(); 170 return it == payload_types.end();
181 } 171 }
182 172
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( 173 rtc::Optional<std::string> GetAudioNetworkAdaptorConfig(
190 const AudioOptions& options) { 174 const AudioOptions& options) {
191 if (options.audio_network_adaptor && *options.audio_network_adaptor && 175 if (options.audio_network_adaptor && *options.audio_network_adaptor &&
192 options.audio_network_adaptor_config) { 176 options.audio_network_adaptor_config) {
193 // Turn on audio network adaptor only when |options_.audio_network_adaptor| 177 // Turn on audio network adaptor only when |options_.audio_network_adaptor|
194 // equals true and |options_.audio_network_adaptor_config| has a value. 178 // equals true and |options_.audio_network_adaptor_config| has a value.
195 return options.audio_network_adaptor_config; 179 return options.audio_network_adaptor_config;
196 } 180 }
197 return rtc::Optional<std::string>(); 181 return rtc::Optional<std::string>();
198 } 182 }
199 183
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( 184 webrtc::AudioState::Config MakeAudioStateConfig(
280 VoEWrapper* voe_wrapper, 185 VoEWrapper* voe_wrapper,
281 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) { 186 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) {
282 webrtc::AudioState::Config config; 187 webrtc::AudioState::Config config;
283 config.voice_engine = voe_wrapper->engine(); 188 config.voice_engine = voe_wrapper->engine();
284 if (audio_mixer) { 189 if (audio_mixer) {
285 config.audio_mixer = audio_mixer; 190 config.audio_mixer = audio_mixer;
286 } else { 191 } else {
287 config.audio_mixer = webrtc::AudioMixerImpl::Create(); 192 config.audio_mixer = webrtc::AudioMixerImpl::Create();
288 } 193 }
289 return config; 194 return config;
290 } 195 }
291 196
292 class WebRtcVoiceCodecs final { 197 class WebRtcVoiceCodecs final {
293 public: 198 public:
294 // TODO(solenberg): Do this filtering once off-line, add a simple AudioCodec 199 static bool ToCodecInst(const AudioCodec& in, webrtc::CodecInst* out) {
the sun 2017/03/02 20:37:24 So this is just needed for tests now? And it is st
ossu 2017/03/02 20:43:27 I'll try to clean up the tests, so we won't need t
ossu 2017/03/20 18:19:48 Cleaned up (or plain removed) all remaining tests
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()) { 200 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) {
350 // Change the sample rate of G722 to 8000 to match SDP. 201 // Change the sample rate of G722 to 8000 to match SDP.
351 MaybeFixupG722(&voe_codec, 8000); 202 MaybeFixupG722(&voe_codec, 8000);
352 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, 203 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq,
353 voe_codec.rate, voe_codec.channels); 204 voe_codec.rate, voe_codec.channels);
354 bool multi_rate = IsCodecMultiRate(voe_codec); 205 const bool multi_rate =
206 IsCodec(codec, kIsacCodecName) || IsCodec(codec, kOpusCodecName);
355 // Allow arbitrary rates for ISAC to be specified. 207 // Allow arbitrary rates for ISAC to be specified.
356 if (multi_rate) { 208 if (multi_rate) {
357 // Set codec.bitrate to 0 so the check for codec.Matches() passes. 209 // Set codec.bitrate to 0 so the check for codec.Matches() passes.
358 codec.bitrate = 0; 210 codec.bitrate = 0;
359 } 211 }
360 if (codec.Matches(in)) { 212 if (codec.Matches(in)) {
361 if (out) { 213 if (out) {
362 // Fixup the payload type. 214 // Fixup the payload type.
363 voe_codec.pltype = in.id; 215 voe_codec.pltype = in.id;
364 216
365 // Set bitrate if specified. 217 // Set bitrate if specified.
366 if (multi_rate && in.bitrate != 0) { 218 if (multi_rate && in.bitrate != 0) {
367 voe_codec.rate = in.bitrate; 219 voe_codec.rate = in.bitrate;
368 } 220 }
369 221
370 // Reset G722 sample rate to 16000 to match WebRTC. 222 // Reset G722 sample rate to 16000 to match WebRTC.
371 MaybeFixupG722(&voe_codec, 16000); 223 MaybeFixupG722(&voe_codec, 16000);
372 224
373 *out = voe_codec; 225 *out = voe_codec;
374 } 226 }
375 return true; 227 return true;
376 } 228 }
377 } 229 }
378 return false; 230 return false;
379 } 231 }
380 232
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 233 // 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 234 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz
489 // codec. 235 // codec.
490 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { 236 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) {
491 if (IsCodec(*voe_codec, kG722CodecName)) { 237 if (IsCodec(*voe_codec, kG722CodecName)) {
492 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine 238 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine
493 // has changed, and this special case is no longer needed. 239 // has changed, and this special case is no longer needed.
494 RTC_DCHECK(voe_codec->plfreq != new_plfreq); 240 RTC_DCHECK(voe_codec->plfreq != new_plfreq);
495 voe_codec->plfreq = new_plfreq; 241 voe_codec->plfreq = new_plfreq;
496 } 242 }
497 } 243 }
498 }; 244 };
499 245
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. 246 // |max_send_bitrate_bps| is the bitrate from "b=" in SDP.
524 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters. 247 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters.
525 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, 248 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps,
526 rtc::Optional<int> rtp_max_bitrate_bps, 249 rtc::Optional<int> rtp_max_bitrate_bps,
527 const webrtc::CodecInst& codec_inst) { 250 const webrtc::AudioCodecSpec& spec) {
528 // If application-configured bitrate is set, take minimum of that and SDP 251 // If application-configured bitrate is set, take minimum of that and SDP
529 // bitrate. 252 // bitrate.
530 const int bps = rtp_max_bitrate_bps 253 const int bps = rtp_max_bitrate_bps
531 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps) 254 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps)
532 : max_send_bitrate_bps; 255 : max_send_bitrate_bps;
533 const int codec_rate = codec_inst.rate;
534
535 if (bps <= 0) { 256 if (bps <= 0) {
536 return rtc::Optional<int>(codec_rate); 257 return rtc::Optional<int>(spec.info.default_bitrate_bps);
537 } 258 }
538 259
539 if (codec_inst.pltype == -1) { 260 if (bps < spec.info.min_bitrate_bps) {
540 return rtc::Optional<int>(codec_rate);
541 ;
542 }
543
544 if (WebRtcVoiceCodecs::IsCodecMultiRate(codec_inst)) {
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 261 // 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 262 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed
553 // bitrate then ignore. 263 // bitrate then ignore.
554 LOG(LS_ERROR) << "Failed to set codec " << codec_inst.plname 264 LOG(LS_ERROR) << "Failed to set codec " << spec.format.name
555 << " to bitrate " << bps << " bps" 265 << " to bitrate " << bps << " bps"
556 << ", requires at least " << codec_inst.rate << " bps."; 266 << ", requires at least " << spec.info.min_bitrate_bps
267 << " bps.";
557 return rtc::Optional<int>(); 268 return rtc::Optional<int>();
558 } 269 }
559 return rtc::Optional<int>(codec_rate); 270
271 if (spec.info.HasFixedBitrate()) {
272 return rtc::Optional<int>(spec.info.default_bitrate_bps);
273 } else {
274 // If codec is multi-rate then just set the bitrate.
275 return rtc::Optional<int>(std::min(bps, spec.info.max_bitrate_bps));
276 }
560 } 277 }
561 278
562 } // namespace { 279 } // namespace
563 280
564 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, 281 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in,
565 webrtc::CodecInst* out) { 282 webrtc::CodecInst* out) {
566 return WebRtcVoiceCodecs::ToCodecInst(in, out); 283 return WebRtcVoiceCodecs::ToCodecInst(in, out);
567 } 284 }
568 285
569 WebRtcVoiceEngine::WebRtcVoiceEngine( 286 WebRtcVoiceEngine::WebRtcVoiceEngine(
570 webrtc::AudioDeviceModule* adm, 287 webrtc::AudioDeviceModule* adm,
571 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, 288 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory,
572 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) 289 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer)
573 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) { 290 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) {
574 audio_state_ = 291 audio_state_ =
575 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer)); 292 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer));
576 } 293 }
577 294
578 WebRtcVoiceEngine::WebRtcVoiceEngine( 295 WebRtcVoiceEngine::WebRtcVoiceEngine(
579 webrtc::AudioDeviceModule* adm, 296 webrtc::AudioDeviceModule* adm,
580 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, 297 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory,
581 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, 298 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer,
582 VoEWrapper* voe_wrapper) 299 VoEWrapper* voe_wrapper)
583 : adm_(adm), decoder_factory_(decoder_factory), voe_wrapper_(voe_wrapper) { 300 : adm_(adm),
301 encoder_factory_(webrtc::CreateBuiltinAudioEncoderFactory()),
302 decoder_factory_(decoder_factory),
303 voe_wrapper_(voe_wrapper) {
584 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 304 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
585 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; 305 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine";
586 RTC_DCHECK(voe_wrapper); 306 RTC_DCHECK(voe_wrapper);
587 RTC_DCHECK(decoder_factory); 307 RTC_DCHECK(decoder_factory);
588 308
589 signal_thread_checker_.DetachFromThread(); 309 signal_thread_checker_.DetachFromThread();
590 310
591 // Load our audio codec list. 311 // Load our audio codec list.
592 LOG(LS_INFO) << "Supported send codecs in order of preference:"; 312 LOG(LS_INFO) << "Supported send codecs in order of preference:";
593 send_codecs_ = WebRtcVoiceCodecs::SupportedSendCodecs(); 313 send_codecs_ = CollectCodecs(encoder_factory_->GetSupportedEncoders());
594 for (const AudioCodec& codec : send_codecs_) { 314 for (const AudioCodec& codec : send_codecs_) {
595 LOG(LS_INFO) << ToString(codec); 315 LOG(LS_INFO) << ToString(codec);
596 } 316 }
597 317
598 LOG(LS_INFO) << "Supported recv codecs in order of preference:"; 318 LOG(LS_INFO) << "Supported recv codecs in order of preference:";
599 recv_codecs_ = CollectRecvCodecs(); 319 recv_codecs_ = CollectCodecs(decoder_factory_->GetSupportedDecoders());
600 for (const AudioCodec& codec : recv_codecs_) { 320 for (const AudioCodec& codec : recv_codecs_) {
601 LOG(LS_INFO) << ToString(codec); 321 LOG(LS_INFO) << ToString(codec);
602 } 322 }
603 323
604 channel_config_.enable_voice_pacing = true; 324 channel_config_.enable_voice_pacing = true;
605 325
606 // Temporarily turn logging level up for the Init() call. 326 // Temporarily turn logging level up for the Init() call.
607 webrtc::Trace::SetTraceCallback(this); 327 webrtc::Trace::SetTraceCallback(this);
608 webrtc::Trace::set_level_filter(kElevatedTraceFilter); 328 webrtc::Trace::set_level_filter(kElevatedTraceFilter);
609 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString(); 329 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString();
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 RTC_DCHECK(adm_); 861 RTC_DCHECK(adm_);
1142 return adm_; 862 return adm_;
1143 } 863 }
1144 864
1145 webrtc::AudioProcessing* WebRtcVoiceEngine::apm() { 865 webrtc::AudioProcessing* WebRtcVoiceEngine::apm() {
1146 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 866 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1147 RTC_DCHECK(apm_); 867 RTC_DCHECK(apm_);
1148 return apm_; 868 return apm_;
1149 } 869 }
1150 870
1151 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { 871 AudioCodecs WebRtcVoiceEngine::CollectCodecs(
872 const std::vector<webrtc::AudioCodecSpec>& specs) const {
1152 PayloadTypeMapper mapper; 873 PayloadTypeMapper mapper;
1153 AudioCodecs out; 874 AudioCodecs out;
1154 const std::vector<webrtc::AudioCodecSpec>& specs =
1155 decoder_factory_->GetSupportedDecoders();
1156 875
1157 // Only generate CN payload types for these clockrates: 876 // Only generate CN payload types for these clockrates:
1158 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, 877 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false },
1159 { 16000, false }, 878 { 16000, false },
1160 { 32000, false }}; 879 { 32000, false }};
1161 // Only generate telephone-event payload types for these clockrates: 880 // Only generate telephone-event payload types for these clockrates:
1162 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, 881 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false },
1163 { 16000, false }, 882 { 16000, false },
1164 { 32000, false }, 883 { 32000, false },
1165 { 48000, false }}; 884 { 48000, false }};
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 WebRtcAudioSendStream( 949 WebRtcAudioSendStream(
1231 int ch, 950 int ch,
1232 webrtc::AudioTransport* voe_audio_transport, 951 webrtc::AudioTransport* voe_audio_transport,
1233 uint32_t ssrc, 952 uint32_t ssrc,
1234 const std::string& c_name, 953 const std::string& c_name,
1235 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, 954 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec,
1236 const std::vector<webrtc::RtpExtension>& extensions, 955 const std::vector<webrtc::RtpExtension>& extensions,
1237 int max_send_bitrate_bps, 956 int max_send_bitrate_bps,
1238 const rtc::Optional<std::string>& audio_network_adaptor_config, 957 const rtc::Optional<std::string>& audio_network_adaptor_config,
1239 webrtc::Call* call, 958 webrtc::Call* call,
1240 webrtc::Transport* send_transport) 959 webrtc::Transport* send_transport,
960 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& encoder_factory)
1241 : voe_audio_transport_(voe_audio_transport), 961 : voe_audio_transport_(voe_audio_transport),
1242 call_(call), 962 call_(call),
1243 config_(send_transport), 963 config_(send_transport),
1244 send_side_bwe_with_overhead_(webrtc::field_trial::FindFullName( 964 send_side_bwe_with_overhead_(webrtc::field_trial::FindFullName(
1245 "WebRTC-SendSideBwe-WithOverhead") == "Enabled"), 965 "WebRTC-SendSideBwe-WithOverhead") == "Enabled"),
1246 max_send_bitrate_bps_(max_send_bitrate_bps), 966 max_send_bitrate_bps_(max_send_bitrate_bps),
1247 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { 967 rtp_parameters_(CreateRtpParametersWithOneEncoding()) {
1248 RTC_DCHECK_GE(ch, 0); 968 RTC_DCHECK_GE(ch, 0);
1249 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: 969 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore:
1250 // RTC_DCHECK(voe_audio_transport); 970 // RTC_DCHECK(voe_audio_transport);
1251 RTC_DCHECK(call); 971 RTC_DCHECK(call);
972 RTC_DCHECK(encoder_factory);
1252 config_.rtp.ssrc = ssrc; 973 config_.rtp.ssrc = ssrc;
1253 config_.rtp.c_name = c_name; 974 config_.rtp.c_name = c_name;
1254 config_.voe_channel_id = ch; 975 config_.voe_channel_id = ch;
1255 config_.rtp.extensions = extensions; 976 config_.rtp.extensions = extensions;
1256 config_.audio_network_adaptor_config = audio_network_adaptor_config; 977 config_.audio_network_adaptor_config = audio_network_adaptor_config;
978 config_.encoder_factory = encoder_factory;
1257 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc); 979 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc);
1258 RecreateAudioSendStream(send_codec_spec); 980 RecreateAudioSendStream(send_codec_spec);
1259 } 981 }
1260 982
1261 ~WebRtcAudioSendStream() override { 983 ~WebRtcAudioSendStream() override {
1262 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 984 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1263 ClearSource(); 985 ClearSource();
1264 call_->DestroyAudioSendStream(stream_); 986 call_->DestroyAudioSendStream(stream_);
1265 } 987 }
1266 988
1267 void RecreateAudioSendStream( 989 void RecreateAudioSendStream(
1268 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { 990 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) {
1269 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 991 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1270 send_codec_spec_ = send_codec_spec; 992 send_codec_spec_ = send_codec_spec;
1271 config_.rtp.nack.rtp_history_ms = 993 config_.rtp.nack.rtp_history_ms =
1272 send_codec_spec_.nack_enabled ? kNackRtpHistoryMs : 0; 994 send_codec_spec_.nack_enabled ? kNackRtpHistoryMs : 0;
1273 config_.send_codec_spec = send_codec_spec_; 995 config_.send_codec_spec = send_codec_spec_;
1274 auto send_rate = ComputeSendBitrate( 996 if (send_codec_spec_.format.name != "") {
kwiberg-webrtc 2017/03/01 12:26:47 One of these again...
ossu 2017/03/02 01:30:28 Yes. This is the most important one. There are two
kwiberg-webrtc 2017/03/02 02:17:55 Dealing with it when cleaning up sounds OK.
ossu 2017/03/20 18:19:48 SendCodecSpec is now optional. No more string comp
1275 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, 997 auto info =
1276 send_codec_spec.codec_inst); 998 config_.encoder_factory->QueryAudioFormat(send_codec_spec_.format);
1277 if (send_rate) { 999 RTC_DCHECK(info);
1278 // Apply a send rate that abides by |max_send_bitrate_bps_| and 1000 // If a specific target bitrate has been set for the stream, use that as
1279 // |rtp_parameters_| when possible. Otherwise use the codec rate. 1001 // the new default bitrate when computing send bitrate.
1280 config_.send_codec_spec.codec_inst.rate = *send_rate; 1002 if (send_codec_spec_.target_bitrate_bps) {
1003 info->default_bitrate_bps =
1004 std::max(info->min_bitrate_bps,
1005 std::min(info->max_bitrate_bps,
1006 *send_codec_spec.target_bitrate_bps));
1007 }
1008
1009 audio_codec_spec_.emplace(
1010 webrtc::AudioCodecSpec{send_codec_spec_.format, *info});
1011
1012 config_.send_codec_spec.target_bitrate_bps = ComputeSendBitrate(
1013 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps,
1014 *audio_codec_spec_);
1281 } 1015 }
1282 RecreateAudioSendStream(); 1016 RecreateAudioSendStream();
1283 } 1017 }
1284 1018
1285 void RecreateAudioSendStream( 1019 void RecreateAudioSendStream(
1286 const std::vector<webrtc::RtpExtension>& extensions) { 1020 const std::vector<webrtc::RtpExtension>& extensions) {
1287 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1021 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1288 config_.rtp.extensions = extensions; 1022 config_.rtp.extensions = extensions;
1289 RecreateAudioSendStream(); 1023 RecreateAudioSendStream();
1290 } 1024 }
1291 1025
1292 void RecreateAudioSendStream( 1026 void RecreateAudioSendStream(
1293 const rtc::Optional<std::string>& audio_network_adaptor_config) { 1027 const rtc::Optional<std::string>& audio_network_adaptor_config) {
1294 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1028 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1295 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { 1029 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) {
1296 return; 1030 return;
1297 } 1031 }
1298 config_.audio_network_adaptor_config = audio_network_adaptor_config; 1032 config_.audio_network_adaptor_config = audio_network_adaptor_config;
1299 RecreateAudioSendStream(); 1033 RecreateAudioSendStream();
1300 } 1034 }
1301 1035
1302 bool SetMaxSendBitrate(int bps) { 1036 bool SetMaxSendBitrate(int bps) {
1303 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1037 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1038 RTC_DCHECK(audio_codec_spec_);
1304 auto send_rate = 1039 auto send_rate =
1305 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps, 1040 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps,
1306 send_codec_spec_.codec_inst); 1041 *audio_codec_spec_);
1042
1307 if (!send_rate) { 1043 if (!send_rate) {
1308 return false; 1044 return false;
1309 } 1045 }
1310 1046
1311 max_send_bitrate_bps_ = bps; 1047 max_send_bitrate_bps_ = bps;
1312 1048
1313 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { 1049 if (send_rate != config_.send_codec_spec.target_bitrate_bps) {
1314 // Recreate AudioSendStream with new bit rate. 1050 // TODO(ossu): Should not recreate stream!
1315 config_.send_codec_spec.codec_inst.rate = *send_rate; 1051 config_.send_codec_spec.target_bitrate_bps = send_rate;
1316 RecreateAudioSendStream(); 1052 RecreateAudioSendStream();
1317 } 1053 }
1318 return true; 1054 return true;
1319 } 1055 }
1320 1056
1321 bool SendTelephoneEvent(int payload_type, int payload_freq, int event, 1057 bool SendTelephoneEvent(int payload_type, int payload_freq, int event,
1322 int duration_ms) { 1058 int duration_ms) {
1323 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1059 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1324 RTC_DCHECK(stream_); 1060 RTC_DCHECK(stream_);
1325 return stream_->SendTelephoneEvent(payload_type, payload_freq, event, 1061 return stream_->SendTelephoneEvent(payload_type, payload_freq, event,
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 LOG(LS_ERROR) << "Attempted to set RtpParameters with modified SSRC"; 1158 LOG(LS_ERROR) << "Attempted to set RtpParameters with modified SSRC";
1423 return false; 1159 return false;
1424 } 1160 }
1425 return true; 1161 return true;
1426 } 1162 }
1427 1163
1428 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { 1164 bool SetRtpParameters(const webrtc::RtpParameters& parameters) {
1429 if (!ValidateRtpParameters(parameters)) { 1165 if (!ValidateRtpParameters(parameters)) {
1430 return false; 1166 return false;
1431 } 1167 }
1432 auto send_rate = ComputeSendBitrate(max_send_bitrate_bps_, 1168
1433 parameters.encodings[0].max_bitrate_bps, 1169 rtc::Optional<int> send_rate;
1434 send_codec_spec_.codec_inst); 1170 if (audio_codec_spec_) {
1435 if (!send_rate) { 1171 send_rate = ComputeSendBitrate(max_send_bitrate_bps_,
1436 return false; 1172 parameters.encodings[0].max_bitrate_bps,
1173 *audio_codec_spec_);
1174 if (!send_rate) {
1175 return false;
1176 }
1437 } 1177 }
1438 1178
1439 rtp_parameters_ = parameters; 1179 rtp_parameters_ = parameters;
1440 1180
1441 // parameters.encodings[0].encodings[0].max_bitrate_bps could have changed. 1181 // parameters.encodings[0].encodings[0].max_bitrate_bps could have changed.
1442 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { 1182 if (send_rate && send_rate != config_.send_codec_spec.target_bitrate_bps) {
1183 // TODO(ossu): Should not recreate stream!
1443 // Recreate AudioSendStream with new bit rate. 1184 // Recreate AudioSendStream with new bit rate.
1444 config_.send_codec_spec.codec_inst.rate = *send_rate; 1185 config_.send_codec_spec.target_bitrate_bps = send_rate;
1445 RecreateAudioSendStream(); 1186 RecreateAudioSendStream();
1446 } else { 1187 } else {
1447 // parameters.encodings[0].active could have changed. 1188 // parameters.encodings[0].active could have changed.
1448 UpdateSendState(); 1189 UpdateSendState();
1449 } 1190 }
1450 return true; 1191 return true;
1451 } 1192 }
1452 1193
1453 private: 1194 private:
1454 void UpdateSendState() { 1195 void UpdateSendState() {
(...skipping 14 matching lines...) Expand all
1469 stream_ = nullptr; 1210 stream_ = nullptr;
1470 } 1211 }
1471 RTC_DCHECK(!stream_); 1212 RTC_DCHECK(!stream_);
1472 if (webrtc::field_trial::FindFullName("WebRTC-Audio-SendSideBwe") == 1213 if (webrtc::field_trial::FindFullName("WebRTC-Audio-SendSideBwe") ==
1473 "Enabled") { 1214 "Enabled") {
1474 config_.min_bitrate_bps = kOpusMinBitrateBps; 1215 config_.min_bitrate_bps = kOpusMinBitrateBps;
1475 config_.max_bitrate_bps = kOpusBitrateFbBps; 1216 config_.max_bitrate_bps = kOpusBitrateFbBps;
1476 // TODO(mflodman): Keep testing this and set proper values. 1217 // TODO(mflodman): Keep testing this and set proper values.
1477 // Note: This is an early experiment currently only supported by Opus. 1218 // Note: This is an early experiment currently only supported by Opus.
1478 if (send_side_bwe_with_overhead_) { 1219 if (send_side_bwe_with_overhead_) {
1479 auto packet_sizes_ms = WebRtcVoiceCodecs::GetPacketSizesMs( 1220 const bool is_opus_with_ana =
1480 config_.send_codec_spec.codec_inst); 1221 config_.audio_network_adaptor_config &&
1481 if (!packet_sizes_ms.empty()) { 1222 !STR_CASE_CMP(config_.send_codec_spec.format.name.c_str(),
1482 int max_packet_size_ms = 1223 kOpusCodecName);
1483 *std::max_element(packet_sizes_ms.begin(), packet_sizes_ms.end()); 1224 const int max_packet_size_ms =
1484 int min_packet_size_ms = 1225 (is_opus_with_ana && WEBRTC_OPUS_SUPPORT_120MS_PTIME) ? 120 : 60;
1485 *std::min_element(packet_sizes_ms.begin(), packet_sizes_ms.end()); 1226 // Audio network adaptor will just use 20ms and 60ms frame lengths.
1227 // The adaptor will only be active for the Opus encoder.
1228 const int min_packet_size_ms = is_opus_with_ana ? 20 : 10;
1486 1229
1487 // Audio network adaptor will just use 20ms and 60ms frame lengths. 1230 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12)
1488 // The adaptor will only be active for the Opus encoder. 1231 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 1232
1499 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12) 1233 int min_overhead_bps =
1500 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12; 1234 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms;
1501 1235
1502 int min_overhead_bps = 1236 int max_overhead_bps =
1503 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms; 1237 kOverheadPerPacket * 8 * 1000 / min_packet_size_ms;
1504 1238
1505 int max_overhead_bps = 1239 config_.min_bitrate_bps = kOpusMinBitrateBps + min_overhead_bps;
1506 kOverheadPerPacket * 8 * 1000 / min_packet_size_ms; 1240 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 } 1241 }
1512 } 1242 }
1513 stream_ = call_->CreateAudioSendStream(config_); 1243 stream_ = call_->CreateAudioSendStream(config_);
1514 RTC_CHECK(stream_); 1244 RTC_CHECK(stream_);
1515 UpdateSendState(); 1245 UpdateSendState();
1516 } 1246 }
1517 1247
1518 rtc::ThreadChecker worker_thread_checker_; 1248 rtc::ThreadChecker worker_thread_checker_;
1519 rtc::RaceChecker audio_capture_race_checker_; 1249 rtc::RaceChecker audio_capture_race_checker_;
1520 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; 1250 webrtc::AudioTransport* const voe_audio_transport_ = nullptr;
1521 webrtc::Call* call_ = nullptr; 1251 webrtc::Call* call_ = nullptr;
1522 webrtc::AudioSendStream::Config config_; 1252 webrtc::AudioSendStream::Config config_;
1523 const bool send_side_bwe_with_overhead_; 1253 const bool send_side_bwe_with_overhead_;
1524 // The stream is owned by WebRtcAudioSendStream and may be reallocated if 1254 // The stream is owned by WebRtcAudioSendStream and may be reallocated if
1525 // configuration changes. 1255 // configuration changes.
1526 webrtc::AudioSendStream* stream_ = nullptr; 1256 webrtc::AudioSendStream* stream_ = nullptr;
1527 1257
1528 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. 1258 // Raw pointer to AudioSource owned by LocalAudioTrackHandler.
1529 // PeerConnection will make sure invalidating the pointer before the object 1259 // PeerConnection will make sure invalidating the pointer before the object
1530 // goes away. 1260 // goes away.
1531 AudioSource* source_ = nullptr; 1261 AudioSource* source_ = nullptr;
1532 bool send_ = false; 1262 bool send_ = false;
1533 bool muted_ = false; 1263 bool muted_ = false;
1534 int max_send_bitrate_bps_; 1264 int max_send_bitrate_bps_;
1535 webrtc::RtpParameters rtp_parameters_; 1265 webrtc::RtpParameters rtp_parameters_;
1536 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec_; 1266 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec_;
1267 // TODO(ossu): Worst. Names. Ever.
1268 rtc::Optional<webrtc::AudioCodecSpec> audio_codec_spec_;
1537 1269
1538 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); 1270 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream);
1539 }; 1271 };
1540 1272
1541 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { 1273 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
1542 public: 1274 public:
1543 WebRtcAudioReceiveStream( 1275 WebRtcAudioReceiveStream(
1544 int ch, 1276 int ch,
1545 uint32_t remote_ssrc, 1277 uint32_t remote_ssrc,
1546 uint32_t local_ssrc, 1278 uint32_t local_ssrc,
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
1978 if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) { 1710 if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) {
1979 dtmf_payload_type_ = rtc::Optional<int>(codec.id); 1711 dtmf_payload_type_ = rtc::Optional<int>(codec.id);
1980 dtmf_payload_freq_ = codec.clockrate; 1712 dtmf_payload_freq_ = codec.clockrate;
1981 } 1713 }
1982 } 1714 }
1983 } 1715 }
1984 1716
1985 // Scan through the list to figure out the codec to use for sending, along 1717 // 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 1718 // with the proper configuration for VAD, CNG, NACK and Opus-specific
1987 // parameters. 1719 // parameters.
1988 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. 1720 // TODO(solenberg): Refactor this logic once we create AudioEncoders here.
the sun 2017/03/16 08:48:19 Comment doesn't apply anymore?
ossu 2017/03/20 18:19:48 Acknowledged.
1989 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec; 1721 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec;
1990 { 1722 {
1991 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; 1723 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled;
1992 1724
1993 // Find send codec (the first non-telephone-event/CN codec). 1725 const AudioCodec* voice_codec = nullptr;
1994 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( 1726 for (const AudioCodec& codec : codecs) {
1995 codecs, &send_codec_spec.codec_inst); 1727 if (!(IsCodec(codec, kCnCodecName) ||
1996 if (!codec) { 1728 IsCodec(codec, kDtmfCodecName) ||
1997 LOG(LS_WARNING) << "Received empty list of codecs."; 1729 IsCodec(codec, kRedCodecName))) {
1998 return false; 1730 webrtc::SdpAudioFormat format(codec.name, codec.clockrate,
1731 codec.channels,
1732 CodecParameterMap(codec.params));
1733
1734 if (!engine()->encoder_factory_->IsSupportedEncoder(format)) {
1735 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
1736 continue;
1737 }
1738
1739 voice_codec = &codec;
1740 send_codec_spec.payload_type = voice_codec->id;
1741 send_codec_spec.format = format;
1742 if (codec.bitrate > 0) {
1743 send_codec_spec.target_bitrate_bps =
1744 rtc::Optional<int>(codec.bitrate);
1745 }
1746 send_codec_spec.transport_cc_enabled = HasTransportCc(*voice_codec);
1747 send_codec_spec.nack_enabled = HasNack(*voice_codec);
1748 bitrate_config_ = GetBitrateConfigForCodec(*voice_codec);
1749 break;
1750 }
1999 } 1751 }
2000 1752
2001 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec); 1753 if (!voice_codec)
2002 send_codec_spec.nack_enabled = HasNack(*codec); 1754 return false;
2003 bitrate_config_ = GetBitrateConfigForCodec(*codec);
2004
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 1755
2027 // Loop through the codecs list again to find the CN codec. 1756 // Loop through the codecs list again to find the CN codec.
2028 // TODO(solenberg): Break out into a separate function? 1757 // TODO(solenberg): Break out into a separate function?
2029 for (const AudioCodec& codec : codecs) { 1758 for (const AudioCodec& codec : codecs) {
2030 // Ignore codecs we don't know about. The negotiation step should prevent 1759 if (IsCodec(codec, kCnCodecName) &&
2031 // this, but double-check to be sure. 1760 codec.clockrate == voice_codec->clockrate) {
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)) {
2039 // Turn voice activity detection/comfort noise on if supported. 1761 // Turn voice activity detection/comfort noise on if supported.
2040 // Set the wideband CN payload type appropriately. 1762 // Set the wideband CN payload type appropriately.
2041 // (narrowband always uses the static payload type 13). 1763 // (narrowband always uses the static payload type 13).
2042 int cng_plfreq = -1;
2043 switch (codec.clockrate) { 1764 switch (codec.clockrate) {
2044 case 8000: 1765 case 8000:
2045 case 16000: 1766 case 16000:
2046 case 32000: 1767 case 32000:
2047 cng_plfreq = codec.clockrate; 1768 send_codec_spec.cng_payload_type = codec.id;
2048 break; 1769 break;
2049 default: 1770 default:
2050 LOG(LS_WARNING) << "CN frequency " << codec.clockrate 1771 LOG(LS_WARNING) << "CN frequency " << codec.clockrate
2051 << " not supported."; 1772 << " not supported.";
2052 continue; 1773 continue;
2053 } 1774 }
2054 send_codec_spec.cng_payload_type = codec.id;
2055 send_codec_spec.cng_plfreq = cng_plfreq;
2056 break; 1775 break;
2057 } 1776 }
2058 } 1777 }
2059 1778
2060 // Find the telephone-event PT exactly matching the preferred send codec. 1779 // Find the telephone-event PT exactly matching the preferred send codec.
2061 for (const AudioCodec& dtmf_codec : dtmf_codecs) { 1780 for (const AudioCodec& dtmf_codec : dtmf_codecs) {
2062 if (dtmf_codec.clockrate == codec->clockrate) { 1781 if (dtmf_codec.clockrate == voice_codec->clockrate) {
2063 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id); 1782 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id);
2064 dtmf_payload_freq_ = dtmf_codec.clockrate; 1783 dtmf_payload_freq_ = dtmf_codec.clockrate;
2065 break; 1784 break;
2066 } 1785 }
2067 } 1786 }
2068 } 1787 }
2069 1788
2070 if (send_codec_spec_ != send_codec_spec) { 1789 if (send_codec_spec_ != send_codec_spec) {
2071 send_codec_spec_ = std::move(send_codec_spec); 1790 send_codec_spec_ = std::move(send_codec_spec);
2072 // Apply new settings to all streams. 1791 // 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 1921 // Save the channel to send_streams_, so that RemoveSendStream() can still
2203 // delete the channel in case failure happens below. 1922 // delete the channel in case failure happens below.
2204 webrtc::AudioTransport* audio_transport = 1923 webrtc::AudioTransport* audio_transport =
2205 engine()->voe()->base()->audio_transport(); 1924 engine()->voe()->base()->audio_transport();
2206 1925
2207 rtc::Optional<std::string> audio_network_adaptor_config = 1926 rtc::Optional<std::string> audio_network_adaptor_config =
2208 GetAudioNetworkAdaptorConfig(options_); 1927 GetAudioNetworkAdaptorConfig(options_);
2209 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( 1928 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream(
2210 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, 1929 channel, audio_transport, ssrc, sp.cname, send_codec_spec_,
2211 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, 1930 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config,
2212 call_, this); 1931 call_, this, engine()->encoder_factory_);
2213 send_streams_.insert(std::make_pair(ssrc, stream)); 1932 send_streams_.insert(std::make_pair(ssrc, stream));
2214 1933
2215 // At this point the stream's local SSRC has been updated. If it is the first 1934 // 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 1935 // send stream, make sure that all the receive streams are updated with the
2217 // same SSRC in order to send receiver reports. 1936 // same SSRC in order to send receiver reports.
2218 if (send_streams_.size() == 1) { 1937 if (send_streams_.size() == 1) {
2219 receiver_reports_ssrc_ = ssrc; 1938 receiver_reports_ssrc_ = ssrc;
2220 for (const auto& kv : recv_streams_) { 1939 for (const auto& kv : recv_streams_) {
2221 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive 1940 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive
2222 // streams instead, so we can avoid recreating the streams here. 1941 // 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()); 2417 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
2699 const auto it = send_streams_.find(ssrc); 2418 const auto it = send_streams_.find(ssrc);
2700 if (it != send_streams_.end()) { 2419 if (it != send_streams_.end()) {
2701 return it->second->channel(); 2420 return it->second->channel();
2702 } 2421 }
2703 return -1; 2422 return -1;
2704 } 2423 }
2705 } // namespace cricket 2424 } // namespace cricket
2706 2425
2707 #endif // HAVE_WEBRTC_VOICE 2426 #endif // HAVE_WEBRTC_VOICE
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698