OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... | |
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/adm_helpers.h" | 35 #include "webrtc/media/engine/adm_helpers.h" |
36 #include "webrtc/media/engine/apm_helpers.h" | 36 #include "webrtc/media/engine/apm_helpers.h" |
37 #include "webrtc/media/engine/payload_type_mapper.h" | 37 #include "webrtc/media/engine/payload_type_mapper.h" |
38 #include "webrtc/media/engine/webrtcmediaengine.h" | 38 #include "webrtc/media/engine/webrtcmediaengine.h" |
39 #include "webrtc/media/engine/webrtcvoe.h" | 39 #include "webrtc/media/engine/webrtcvoe.h" |
40 #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h" | 40 #include "webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory.h" |
41 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" | 41 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" |
42 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 42 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
43 #include "webrtc/system_wrappers/include/field_trial.h" | 43 #include "webrtc/system_wrappers/include/field_trial.h" |
44 #include "webrtc/system_wrappers/include/metrics.h" | 44 #include "webrtc/system_wrappers/include/metrics.h" |
45 #include "webrtc/system_wrappers/include/trace.h" | 45 #include "webrtc/system_wrappers/include/trace.h" |
46 #include "webrtc/voice_engine/transmit_mixer.h" | 46 #include "webrtc/voice_engine/transmit_mixer.h" |
47 | 47 |
48 namespace cricket { | 48 namespace cricket { |
49 namespace { | 49 namespace { |
50 | 50 |
51 constexpr size_t kMaxUnsignaledRecvStreams = 1; | 51 constexpr size_t kMaxUnsignaledRecvStreams = 1; |
52 | 52 |
53 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | | 53 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | |
54 webrtc::kTraceWarning | webrtc::kTraceError | | 54 webrtc::kTraceWarning | webrtc::kTraceError | |
55 webrtc::kTraceCritical; | 55 webrtc::kTraceCritical; |
56 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | | 56 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | |
57 webrtc::kTraceInfo; | 57 webrtc::kTraceInfo; |
58 | 58 |
59 constexpr int kNackRtpHistoryMs = 5000; | 59 constexpr int kNackRtpHistoryMs = 5000; |
60 | 60 |
61 // Check to verify that the define for the intelligibility enhancer is properly | 61 // Check to verify that the define for the intelligibility enhancer is properly |
62 // set. | 62 // set. |
63 #if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \ | 63 #if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \ |
64 (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \ | 64 (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \ |
65 WEBRTC_INTELLIGIBILITY_ENHANCER != 1) | 65 WEBRTC_INTELLIGIBILITY_ENHANCER != 1) |
66 #error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1" | 66 #error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1" |
67 #endif | 67 #endif |
68 | 68 |
69 // Codec parameters for Opus. | 69 // For SendSideBwe, Opus bitrate should be in the range between 6000 and 32000. |
70 // draft-spittka-payload-rtp-opus-03 | 70 const int kOpusMinBitrateBps = 6000; |
71 | |
72 // Recommended bitrates: | |
73 // 8-12 kb/s for NB speech, | |
74 // 16-20 kb/s for WB speech, | |
75 // 28-40 kb/s for FB speech, | |
76 // 48-64 kb/s for FB mono music, and | |
77 // 64-128 kb/s for FB stereo music. | |
78 // The current implementation applies the following values to mono signals, | |
79 // and multiplies them by 2 for stereo. | |
80 const int kOpusBitrateNbBps = 12000; | |
81 const int kOpusBitrateWbBps = 20000; | |
82 const int kOpusBitrateFbBps = 32000; | 71 const int kOpusBitrateFbBps = 32000; |
83 | 72 |
84 // Opus bitrate should be in the range between 6000 and 510000. | |
85 const int kOpusMinBitrateBps = 6000; | |
86 const int kOpusMaxBitrateBps = 510000; | |
87 | |
88 // iSAC bitrate should be <= 56000. | |
89 const int kIsacMaxBitrateBps = 56000; | |
90 | |
91 // Default audio dscp value. | 73 // Default audio dscp value. |
92 // See http://tools.ietf.org/html/rfc2474 for details. | 74 // See http://tools.ietf.org/html/rfc2474 for details. |
93 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 | 75 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 |
94 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; | 76 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; |
95 | 77 |
96 // Constants from voice_engine_defines.h. | 78 // Constants from voice_engine_defines.h. |
97 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) | 79 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) |
98 const int kMaxTelephoneEventCode = 255; | 80 const int kMaxTelephoneEventCode = 255; |
99 | 81 |
100 const int kMinPayloadType = 0; | 82 const int kMinPayloadType = 0; |
(...skipping 14 matching lines...) Expand all Loading... | |
115 LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); | 97 LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); |
116 return false; | 98 return false; |
117 } | 99 } |
118 if (sp.ssrcs.size() > 1) { | 100 if (sp.ssrcs.size() > 1) { |
119 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); | 101 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); |
120 return false; | 102 return false; |
121 } | 103 } |
122 return true; | 104 return true; |
123 } | 105 } |
124 | 106 |
125 // Dumps an AudioCodec in RFC 2327-ish format. | 107 // Dumps an AudioCodec in RFC 2327-ish format. |
the sun
2017/04/25 11:38:53
nit: does this comment really apply anymore?
ossu
2017/04/25 17:10:06
Depends on how far one's willing to stretch that "
| |
126 std::string ToString(const AudioCodec& codec) { | 108 std::string ToString(const AudioCodec& codec) { |
127 std::stringstream ss; | 109 std::stringstream ss; |
128 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels | 110 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels; |
129 << " (" << codec.id << ")"; | 111 if (!codec.params.empty()) { |
112 ss << " {"; | |
113 for (const auto& param : codec.params) { | |
114 ss << " " << param.first << "=" << param.second; | |
115 } | |
116 ss << " }"; | |
117 } | |
118 ss << " (" << codec.id << ")"; | |
130 return ss.str(); | 119 return ss.str(); |
131 } | 120 } |
132 | 121 |
133 bool IsCodec(const AudioCodec& codec, const char* ref_name) { | 122 bool IsCodec(const AudioCodec& codec, const char* ref_name) { |
134 return (_stricmp(codec.name.c_str(), ref_name) == 0); | 123 return (_stricmp(codec.name.c_str(), ref_name) == 0); |
135 } | 124 } |
136 | 125 |
137 bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) { | |
138 return (_stricmp(codec.plname, ref_name) == 0); | |
139 } | |
140 | |
141 bool FindCodec(const std::vector<AudioCodec>& codecs, | 126 bool FindCodec(const std::vector<AudioCodec>& codecs, |
142 const AudioCodec& codec, | 127 const AudioCodec& codec, |
143 AudioCodec* found_codec) { | 128 AudioCodec* found_codec) { |
144 for (const AudioCodec& c : codecs) { | 129 for (const AudioCodec& c : codecs) { |
145 if (c.Matches(codec)) { | 130 if (c.Matches(codec)) { |
146 if (found_codec != NULL) { | 131 if (found_codec != NULL) { |
147 *found_codec = c; | 132 *found_codec = c; |
148 } | 133 } |
149 return true; | 134 return true; |
150 } | 135 } |
151 } | 136 } |
152 return false; | 137 return false; |
153 } | 138 } |
154 | 139 |
155 bool VerifyUniquePayloadTypes(const std::vector<AudioCodec>& codecs) { | 140 bool VerifyUniquePayloadTypes(const std::vector<AudioCodec>& codecs) { |
156 if (codecs.empty()) { | 141 if (codecs.empty()) { |
157 return true; | 142 return true; |
158 } | 143 } |
159 std::vector<int> payload_types; | 144 std::vector<int> payload_types; |
160 for (const AudioCodec& codec : codecs) { | 145 for (const AudioCodec& codec : codecs) { |
161 payload_types.push_back(codec.id); | 146 payload_types.push_back(codec.id); |
162 } | 147 } |
163 std::sort(payload_types.begin(), payload_types.end()); | 148 std::sort(payload_types.begin(), payload_types.end()); |
164 auto it = std::unique(payload_types.begin(), payload_types.end()); | 149 auto it = std::unique(payload_types.begin(), payload_types.end()); |
165 return it == payload_types.end(); | 150 return it == payload_types.end(); |
166 } | 151 } |
167 | 152 |
168 // Return true if codec.params[feature] == "1", false otherwise. | |
169 bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) { | |
170 int value; | |
171 return codec.GetParam(feature, &value) && value == 1; | |
172 } | |
173 | |
174 rtc::Optional<std::string> GetAudioNetworkAdaptorConfig( | 153 rtc::Optional<std::string> GetAudioNetworkAdaptorConfig( |
175 const AudioOptions& options) { | 154 const AudioOptions& options) { |
176 if (options.audio_network_adaptor && *options.audio_network_adaptor && | 155 if (options.audio_network_adaptor && *options.audio_network_adaptor && |
177 options.audio_network_adaptor_config) { | 156 options.audio_network_adaptor_config) { |
178 // Turn on audio network adaptor only when |options_.audio_network_adaptor| | 157 // Turn on audio network adaptor only when |options_.audio_network_adaptor| |
179 // equals true and |options_.audio_network_adaptor_config| has a value. | 158 // equals true and |options_.audio_network_adaptor_config| has a value. |
180 return options.audio_network_adaptor_config; | 159 return options.audio_network_adaptor_config; |
181 } | 160 } |
182 return rtc::Optional<std::string>(); | 161 return rtc::Optional<std::string>(); |
183 } | 162 } |
184 | 163 |
185 // Returns integer parameter params[feature] if it is defined. Returns | |
186 // |default_value| otherwise. | |
187 int GetCodecFeatureInt(const AudioCodec& codec, | |
188 const char* feature, | |
189 int default_value) { | |
190 int value = 0; | |
191 if (codec.GetParam(feature, &value)) { | |
192 return value; | |
193 } | |
194 return default_value; | |
195 } | |
196 | |
197 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate | |
198 // otherwise. If the value (either from params or codec.bitrate) <=0, use the | |
199 // default configuration. If the value is beyond feasible bit rate of Opus, | |
200 // clamp it. Returns the Opus bit rate for operation. | |
201 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { | |
202 int bitrate = 0; | |
203 bool use_param = true; | |
204 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) { | |
205 bitrate = codec.bitrate; | |
206 use_param = false; | |
207 } | |
208 if (bitrate <= 0) { | |
209 if (max_playback_rate <= 8000) { | |
210 bitrate = kOpusBitrateNbBps; | |
211 } else if (max_playback_rate <= 16000) { | |
212 bitrate = kOpusBitrateWbBps; | |
213 } else { | |
214 bitrate = kOpusBitrateFbBps; | |
215 } | |
216 | |
217 if (IsCodecFeatureEnabled(codec, kCodecParamStereo)) { | |
218 bitrate *= 2; | |
219 } | |
220 } else if (bitrate < kOpusMinBitrateBps || bitrate > kOpusMaxBitrateBps) { | |
221 bitrate = (bitrate < kOpusMinBitrateBps) ? kOpusMinBitrateBps | |
222 : kOpusMaxBitrateBps; | |
223 std::string rate_source = | |
224 use_param ? "Codec parameter \"maxaveragebitrate\"" : | |
225 "Supplied Opus bitrate"; | |
226 LOG(LS_WARNING) << rate_source | |
227 << " is invalid and is replaced by: " | |
228 << bitrate; | |
229 } | |
230 return bitrate; | |
231 } | |
232 | |
233 void GetOpusConfig(const AudioCodec& codec, | |
234 webrtc::CodecInst* voe_codec, | |
235 bool* enable_codec_fec, | |
236 int* max_playback_rate, | |
237 bool* enable_codec_dtx, | |
238 int* min_ptime_ms, | |
239 int* max_ptime_ms) { | |
240 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec); | |
241 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx); | |
242 *max_playback_rate = GetCodecFeatureInt(codec, kCodecParamMaxPlaybackRate, | |
243 kOpusDefaultMaxPlaybackRate); | |
244 *max_ptime_ms = | |
245 GetCodecFeatureInt(codec, kCodecParamMaxPTime, kOpusDefaultMaxPTime); | |
246 *min_ptime_ms = | |
247 GetCodecFeatureInt(codec, kCodecParamMinPTime, kOpusDefaultMinPTime); | |
248 if (*max_ptime_ms < *min_ptime_ms) { | |
249 // If min ptime or max ptime defined by codec parameter is wrong, we use | |
250 // the default values. | |
251 *max_ptime_ms = kOpusDefaultMaxPTime; | |
252 *min_ptime_ms = kOpusDefaultMinPTime; | |
253 } | |
254 | |
255 // If OPUS, change what we send according to the "stereo" codec | |
256 // parameter, and not the "channels" parameter. We set | |
257 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If | |
258 // the bitrate is not specified, i.e. is <= zero, we set it to the | |
259 // appropriate default value for mono or stereo Opus. | |
260 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; | |
261 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); | |
262 } | |
263 | |
264 webrtc::AudioState::Config MakeAudioStateConfig( | 164 webrtc::AudioState::Config MakeAudioStateConfig( |
265 VoEWrapper* voe_wrapper, | 165 VoEWrapper* voe_wrapper, |
266 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) { | 166 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) { |
267 webrtc::AudioState::Config config; | 167 webrtc::AudioState::Config config; |
268 config.voice_engine = voe_wrapper->engine(); | 168 config.voice_engine = voe_wrapper->engine(); |
269 if (audio_mixer) { | 169 if (audio_mixer) { |
270 config.audio_mixer = audio_mixer; | 170 config.audio_mixer = audio_mixer; |
271 } else { | 171 } else { |
272 config.audio_mixer = webrtc::AudioMixerImpl::Create(); | 172 config.audio_mixer = webrtc::AudioMixerImpl::Create(); |
273 } | 173 } |
274 return config; | 174 return config; |
275 } | 175 } |
276 | 176 |
277 class WebRtcVoiceCodecs final { | |
278 public: | |
279 // TODO(solenberg): Do this filtering once off-line, add a simple AudioCodec | |
280 // list and add a test which verifies VoE supports the listed codecs. | |
281 static std::vector<AudioCodec> SupportedSendCodecs() { | |
282 std::vector<AudioCodec> result; | |
283 // Iterate first over our preferred codecs list, so that the results are | |
284 // added in order of preference. | |
285 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | |
286 const CodecPref* pref = &kCodecPrefs[i]; | |
287 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { | |
288 // Change the sample rate of G722 to 8000 to match SDP. | |
289 MaybeFixupG722(&voe_codec, 8000); | |
290 // Skip uncompressed formats. | |
291 if (IsCodec(voe_codec, kL16CodecName)) { | |
292 continue; | |
293 } | |
294 | |
295 if (!IsCodec(voe_codec, pref->name) || | |
296 pref->clockrate != voe_codec.plfreq || | |
297 pref->channels != voe_codec.channels) { | |
298 // Not a match. | |
299 continue; | |
300 } | |
301 | |
302 AudioCodec codec(pref->payload_type, voe_codec.plname, voe_codec.plfreq, | |
303 voe_codec.rate, voe_codec.channels); | |
304 LOG(LS_INFO) << "Adding supported codec: " << ToString(codec); | |
305 if (IsCodec(codec, kIsacCodecName)) { | |
306 // Indicate auto-bitrate in signaling. | |
307 codec.bitrate = 0; | |
308 } | |
309 if (IsCodec(codec, kOpusCodecName)) { | |
310 // Only add fmtp parameters that differ from the spec. | |
311 if (kPreferredMinPTime != kOpusDefaultMinPTime) { | |
312 codec.params[kCodecParamMinPTime] = | |
313 rtc::ToString(kPreferredMinPTime); | |
314 } | |
315 if (kPreferredMaxPTime != kOpusDefaultMaxPTime) { | |
316 codec.params[kCodecParamMaxPTime] = | |
317 rtc::ToString(kPreferredMaxPTime); | |
318 } | |
319 codec.SetParam(kCodecParamUseInbandFec, 1); | |
320 codec.AddFeedbackParam( | |
321 FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); | |
322 | |
323 // TODO(hellner): Add ptime, sprop-stereo, and stereo | |
324 // when they can be set to values other than the default. | |
325 } | |
326 result.push_back(codec); | |
327 } | |
328 } | |
329 return result; | |
330 } | |
331 | |
332 static bool ToCodecInst(const AudioCodec& in, | |
333 webrtc::CodecInst* out) { | |
334 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { | |
335 // Change the sample rate of G722 to 8000 to match SDP. | |
336 MaybeFixupG722(&voe_codec, 8000); | |
337 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, | |
338 voe_codec.rate, voe_codec.channels); | |
339 bool multi_rate = IsCodecMultiRate(voe_codec); | |
340 // Allow arbitrary rates for ISAC to be specified. | |
341 if (multi_rate) { | |
342 // Set codec.bitrate to 0 so the check for codec.Matches() passes. | |
343 codec.bitrate = 0; | |
344 } | |
345 if (codec.Matches(in)) { | |
346 if (out) { | |
347 // Fixup the payload type. | |
348 voe_codec.pltype = in.id; | |
349 | |
350 // Set bitrate if specified. | |
351 if (multi_rate && in.bitrate != 0) { | |
352 voe_codec.rate = in.bitrate; | |
353 } | |
354 | |
355 // Reset G722 sample rate to 16000 to match WebRTC. | |
356 MaybeFixupG722(&voe_codec, 16000); | |
357 | |
358 *out = voe_codec; | |
359 } | |
360 return true; | |
361 } | |
362 } | |
363 return false; | |
364 } | |
365 | |
366 static bool IsCodecMultiRate(const webrtc::CodecInst& codec) { | |
367 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | |
368 if (IsCodec(codec, kCodecPrefs[i].name) && | |
369 kCodecPrefs[i].clockrate == codec.plfreq) { | |
370 return kCodecPrefs[i].is_multi_rate; | |
371 } | |
372 } | |
373 return false; | |
374 } | |
375 | |
376 static int MaxBitrateBps(const webrtc::CodecInst& codec) { | |
377 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | |
378 if (IsCodec(codec, kCodecPrefs[i].name) && | |
379 kCodecPrefs[i].clockrate == codec.plfreq) { | |
380 return kCodecPrefs[i].max_bitrate_bps; | |
381 } | |
382 } | |
383 return 0; | |
384 } | |
385 | |
386 static rtc::ArrayView<const int> GetPacketSizesMs( | |
387 const webrtc::CodecInst& codec) { | |
388 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { | |
389 if (IsCodec(codec, kCodecPrefs[i].name)) { | |
390 size_t num_packet_sizes = kMaxNumPacketSize; | |
391 for (int index = 0; index < kMaxNumPacketSize; index++) { | |
392 if (kCodecPrefs[i].packet_sizes_ms[index] == 0) { | |
393 num_packet_sizes = index; | |
394 break; | |
395 } | |
396 } | |
397 return rtc::ArrayView<const int>(kCodecPrefs[i].packet_sizes_ms, | |
398 num_packet_sizes); | |
399 } | |
400 } | |
401 return rtc::ArrayView<const int>(); | |
402 } | |
403 | |
404 // If the AudioCodec param kCodecParamPTime is set, then we will set it to | |
405 // codec pacsize if it's valid, or we will pick the next smallest value we | |
406 // support. | |
407 // TODO(Brave): Query supported packet sizes from ACM when the API is ready. | |
408 static bool SetPTimeAsPacketSize(webrtc::CodecInst* codec, int ptime_ms) { | |
409 for (const CodecPref& codec_pref : kCodecPrefs) { | |
410 if ((IsCodec(*codec, codec_pref.name) && | |
411 codec_pref.clockrate == codec->plfreq) || | |
412 IsCodec(*codec, kG722CodecName)) { | |
413 int packet_size_ms = SelectPacketSize(codec_pref, ptime_ms); | |
414 if (packet_size_ms) { | |
415 // Convert unit from milli-seconds to samples. | |
416 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms; | |
417 return true; | |
418 } | |
419 } | |
420 } | |
421 return false; | |
422 } | |
423 | |
424 static const AudioCodec* GetPreferredCodec( | |
425 const std::vector<AudioCodec>& codecs, | |
426 webrtc::CodecInst* out) { | |
427 RTC_DCHECK(out); | |
428 // Select the preferred send codec (the first non-telephone-event/CN codec). | |
429 for (const AudioCodec& codec : codecs) { | |
430 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) { | |
431 // Skip telephone-event/CN codecs - they will be handled later. | |
432 continue; | |
433 } | |
434 | |
435 // We'll use the first codec in the list to actually send audio data. | |
436 // Be sure to use the payload type requested by the remote side. | |
437 // Ignore codecs we don't know about. The negotiation step should prevent | |
438 // this, but double-check to be sure. | |
439 if (!ToCodecInst(codec, out)) { | |
440 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | |
441 continue; | |
442 } | |
443 return &codec; | |
444 } | |
445 return nullptr; | |
446 } | |
447 | |
448 private: | |
449 static const int kMaxNumPacketSize = 6; | |
450 struct CodecPref { | |
451 const char* name; | |
452 int clockrate; | |
453 size_t channels; | |
454 int payload_type; | |
455 bool is_multi_rate; | |
456 int packet_sizes_ms[kMaxNumPacketSize]; | |
457 int max_bitrate_bps; | |
458 }; | |
459 // Note: keep the supported packet sizes in ascending order. | |
460 static const CodecPref kCodecPrefs[14]; | |
461 | |
462 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { | |
463 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; | |
464 for (int packet_size_ms : codec_pref.packet_sizes_ms) { | |
465 if (packet_size_ms && packet_size_ms <= ptime_ms) { | |
466 selected_packet_size_ms = packet_size_ms; | |
467 } | |
468 } | |
469 return selected_packet_size_ms; | |
470 } | |
471 | |
472 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC | |
473 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz | |
474 // codec. | |
475 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { | |
476 if (IsCodec(*voe_codec, kG722CodecName)) { | |
477 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine | |
478 // has changed, and this special case is no longer needed. | |
479 RTC_DCHECK(voe_codec->plfreq != new_plfreq); | |
480 voe_codec->plfreq = new_plfreq; | |
481 } | |
482 } | |
483 }; | |
484 | |
485 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[14] = { | |
486 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME | |
487 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60, 120}, | |
488 kOpusMaxBitrateBps}, | |
489 #else | |
490 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrateBps}, | |
491 #endif | |
492 {kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrateBps}, | |
493 {kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrateBps}, | |
494 // G722 should be advertised as 8000 Hz because of the RFC "bug". | |
495 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, | |
496 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, | |
497 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, | |
498 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, | |
499 {kCnCodecName, 32000, 1, 106, false, {}}, | |
500 {kCnCodecName, 16000, 1, 105, false, {}}, | |
501 {kCnCodecName, 8000, 1, 13, false, {}}, | |
502 {kDtmfCodecName, 48000, 1, 110, false, {}}, | |
503 {kDtmfCodecName, 32000, 1, 112, false, {}}, | |
504 {kDtmfCodecName, 16000, 1, 113, false, {}}, | |
505 {kDtmfCodecName, 8000, 1, 126, false, {}} | |
506 }; | |
507 | |
508 // |max_send_bitrate_bps| is the bitrate from "b=" in SDP. | 177 // |max_send_bitrate_bps| is the bitrate from "b=" in SDP. |
509 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters. | 178 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters. |
510 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, | 179 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, |
511 rtc::Optional<int> rtp_max_bitrate_bps, | 180 rtc::Optional<int> rtp_max_bitrate_bps, |
512 const webrtc::CodecInst& codec_inst) { | 181 const webrtc::AudioCodecSpec& spec) { |
513 // If application-configured bitrate is set, take minimum of that and SDP | 182 // If application-configured bitrate is set, take minimum of that and SDP |
514 // bitrate. | 183 // bitrate. |
515 const int bps = rtp_max_bitrate_bps | 184 const int bps = rtp_max_bitrate_bps |
516 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps) | 185 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps) |
517 : max_send_bitrate_bps; | 186 : max_send_bitrate_bps; |
518 const int codec_rate = codec_inst.rate; | |
519 | |
520 if (bps <= 0) { | 187 if (bps <= 0) { |
521 return rtc::Optional<int>(codec_rate); | 188 return rtc::Optional<int>(spec.info.default_bitrate_bps); |
522 } | 189 } |
523 | 190 |
524 if (codec_inst.pltype == -1) { | 191 if (bps < spec.info.min_bitrate_bps) { |
525 return rtc::Optional<int>(codec_rate); | |
526 ; | |
527 } | |
528 | |
529 if (WebRtcVoiceCodecs::IsCodecMultiRate(codec_inst)) { | |
530 // If codec is multi-rate then just set the bitrate. | |
531 return rtc::Optional<int>( | |
532 std::min(bps, WebRtcVoiceCodecs::MaxBitrateBps(codec_inst))); | |
533 } | |
534 | |
535 if (bps < codec_inst.rate) { | |
536 // If codec is not multi-rate and |bps| is less than the fixed bitrate then | 192 // If codec is not multi-rate and |bps| is less than the fixed bitrate then |
537 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed | 193 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed |
538 // bitrate then ignore. | 194 // bitrate then ignore. |
539 LOG(LS_ERROR) << "Failed to set codec " << codec_inst.plname | 195 LOG(LS_ERROR) << "Failed to set codec " << spec.format.name |
540 << " to bitrate " << bps << " bps" | 196 << " to bitrate " << bps << " bps" |
541 << ", requires at least " << codec_inst.rate << " bps."; | 197 << ", requires at least " << spec.info.min_bitrate_bps |
198 << " bps."; | |
542 return rtc::Optional<int>(); | 199 return rtc::Optional<int>(); |
543 } | 200 } |
544 return rtc::Optional<int>(codec_rate); | 201 |
202 if (spec.info.HasFixedBitrate()) { | |
203 return rtc::Optional<int>(spec.info.default_bitrate_bps); | |
204 } else { | |
205 // If codec is multi-rate then just set the bitrate. | |
206 return rtc::Optional<int>(std::min(bps, spec.info.max_bitrate_bps)); | |
207 } | |
545 } | 208 } |
546 | 209 |
547 } // namespace | 210 } // namespace |
548 | 211 |
549 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | |
550 webrtc::CodecInst* out) { | |
551 return WebRtcVoiceCodecs::ToCodecInst(in, out); | |
552 } | |
553 | |
554 WebRtcVoiceEngine::WebRtcVoiceEngine( | 212 WebRtcVoiceEngine::WebRtcVoiceEngine( |
555 webrtc::AudioDeviceModule* adm, | 213 webrtc::AudioDeviceModule* adm, |
556 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, | 214 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, |
557 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) | 215 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) |
558 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) { | 216 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) { |
559 audio_state_ = | 217 audio_state_ = |
560 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer)); | 218 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer)); |
561 } | 219 } |
562 | 220 |
563 WebRtcVoiceEngine::WebRtcVoiceEngine( | 221 WebRtcVoiceEngine::WebRtcVoiceEngine( |
564 webrtc::AudioDeviceModule* adm, | 222 webrtc::AudioDeviceModule* adm, |
565 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, | 223 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, |
566 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, | 224 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, |
567 VoEWrapper* voe_wrapper) | 225 VoEWrapper* voe_wrapper) |
568 : adm_(adm), decoder_factory_(decoder_factory), voe_wrapper_(voe_wrapper) { | 226 : adm_(adm), |
227 encoder_factory_(webrtc::CreateBuiltinAudioEncoderFactory()), | |
228 decoder_factory_(decoder_factory), | |
229 voe_wrapper_(voe_wrapper) { | |
569 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 230 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
570 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; | 231 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; |
571 RTC_DCHECK(voe_wrapper); | 232 RTC_DCHECK(voe_wrapper); |
572 RTC_DCHECK(decoder_factory); | 233 RTC_DCHECK(decoder_factory); |
573 | 234 |
574 signal_thread_checker_.DetachFromThread(); | 235 signal_thread_checker_.DetachFromThread(); |
575 | 236 |
576 // Load our audio codec list. | 237 // Load our audio codec list. |
577 LOG(LS_INFO) << "Supported send codecs in order of preference:"; | 238 LOG(LS_INFO) << "Supported send codecs in order of preference:"; |
578 send_codecs_ = WebRtcVoiceCodecs::SupportedSendCodecs(); | 239 send_codecs_ = CollectCodecs(encoder_factory_->GetSupportedEncoders()); |
579 for (const AudioCodec& codec : send_codecs_) { | 240 for (const AudioCodec& codec : send_codecs_) { |
580 LOG(LS_INFO) << ToString(codec); | 241 LOG(LS_INFO) << ToString(codec); |
581 } | 242 } |
582 | 243 |
583 LOG(LS_INFO) << "Supported recv codecs in order of preference:"; | 244 LOG(LS_INFO) << "Supported recv codecs in order of preference:"; |
584 recv_codecs_ = CollectRecvCodecs(); | 245 recv_codecs_ = CollectCodecs(decoder_factory_->GetSupportedDecoders()); |
585 for (const AudioCodec& codec : recv_codecs_) { | 246 for (const AudioCodec& codec : recv_codecs_) { |
586 LOG(LS_INFO) << ToString(codec); | 247 LOG(LS_INFO) << ToString(codec); |
587 } | 248 } |
588 | 249 |
589 channel_config_.enable_voice_pacing = true; | 250 channel_config_.enable_voice_pacing = true; |
590 | 251 |
591 // Temporarily turn logging level up for the Init() call. | 252 // Temporarily turn logging level up for the Init() call. |
592 webrtc::Trace::SetTraceCallback(this); | 253 webrtc::Trace::SetTraceCallback(this); |
593 webrtc::Trace::set_level_filter(kElevatedTraceFilter); | 254 webrtc::Trace::set_level_filter(kElevatedTraceFilter); |
594 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString(); | 255 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString(); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1049 RTC_DCHECK(apm_); | 710 RTC_DCHECK(apm_); |
1050 return apm_; | 711 return apm_; |
1051 } | 712 } |
1052 | 713 |
1053 webrtc::voe::TransmitMixer* WebRtcVoiceEngine::transmit_mixer() { | 714 webrtc::voe::TransmitMixer* WebRtcVoiceEngine::transmit_mixer() { |
1054 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 715 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1055 RTC_DCHECK(transmit_mixer_); | 716 RTC_DCHECK(transmit_mixer_); |
1056 return transmit_mixer_; | 717 return transmit_mixer_; |
1057 } | 718 } |
1058 | 719 |
1059 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { | 720 AudioCodecs WebRtcVoiceEngine::CollectCodecs( |
721 const std::vector<webrtc::AudioCodecSpec>& specs) const { | |
1060 PayloadTypeMapper mapper; | 722 PayloadTypeMapper mapper; |
1061 AudioCodecs out; | 723 AudioCodecs out; |
1062 const std::vector<webrtc::AudioCodecSpec>& specs = | |
1063 decoder_factory_->GetSupportedDecoders(); | |
1064 | 724 |
1065 // Only generate CN payload types for these clockrates: | 725 // Only generate CN payload types for these clockrates: |
1066 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, | 726 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, |
1067 { 16000, false }, | 727 { 16000, false }, |
1068 { 32000, false }}; | 728 { 32000, false }}; |
1069 // Only generate telephone-event payload types for these clockrates: | 729 // Only generate telephone-event payload types for these clockrates: |
1070 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, | 730 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, |
1071 { 16000, false }, | 731 { 16000, false }, |
1072 { 32000, false }, | 732 { 32000, false }, |
1073 { 48000, false }}; | 733 { 48000, false }}; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1133 } | 793 } |
1134 | 794 |
1135 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 795 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
1136 : public AudioSource::Sink { | 796 : public AudioSource::Sink { |
1137 public: | 797 public: |
1138 WebRtcAudioSendStream( | 798 WebRtcAudioSendStream( |
1139 int ch, | 799 int ch, |
1140 webrtc::AudioTransport* voe_audio_transport, | 800 webrtc::AudioTransport* voe_audio_transport, |
1141 uint32_t ssrc, | 801 uint32_t ssrc, |
1142 const std::string& c_name, | 802 const std::string& c_name, |
1143 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, | 803 const rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>& |
804 send_codec_spec, | |
1144 const std::vector<webrtc::RtpExtension>& extensions, | 805 const std::vector<webrtc::RtpExtension>& extensions, |
1145 int max_send_bitrate_bps, | 806 int max_send_bitrate_bps, |
1146 const rtc::Optional<std::string>& audio_network_adaptor_config, | 807 const rtc::Optional<std::string>& audio_network_adaptor_config, |
1147 webrtc::Call* call, | 808 webrtc::Call* call, |
1148 webrtc::Transport* send_transport) | 809 webrtc::Transport* send_transport, |
810 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& encoder_factory) | |
1149 : voe_audio_transport_(voe_audio_transport), | 811 : voe_audio_transport_(voe_audio_transport), |
1150 call_(call), | 812 call_(call), |
1151 config_(send_transport), | 813 config_(send_transport), |
1152 send_side_bwe_with_overhead_( | 814 send_side_bwe_with_overhead_( |
1153 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), | 815 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), |
1154 max_send_bitrate_bps_(max_send_bitrate_bps), | 816 max_send_bitrate_bps_(max_send_bitrate_bps), |
1155 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 817 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { |
1156 RTC_DCHECK_GE(ch, 0); | 818 RTC_DCHECK_GE(ch, 0); |
1157 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 819 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
1158 // RTC_DCHECK(voe_audio_transport); | 820 // RTC_DCHECK(voe_audio_transport); |
1159 RTC_DCHECK(call); | 821 RTC_DCHECK(call); |
822 RTC_DCHECK(encoder_factory); | |
1160 config_.rtp.ssrc = ssrc; | 823 config_.rtp.ssrc = ssrc; |
1161 config_.rtp.c_name = c_name; | 824 config_.rtp.c_name = c_name; |
1162 config_.voe_channel_id = ch; | 825 config_.voe_channel_id = ch; |
1163 config_.rtp.extensions = extensions; | 826 config_.rtp.extensions = extensions; |
1164 config_.audio_network_adaptor_config = audio_network_adaptor_config; | 827 config_.audio_network_adaptor_config = audio_network_adaptor_config; |
828 config_.encoder_factory = encoder_factory; | |
1165 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc); | 829 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc); |
1166 RecreateAudioSendStream(send_codec_spec); | 830 |
831 UpdateAllowedBitrateRange(); | |
832 if (send_codec_spec) { | |
833 UpdateSendCodecSpec(*send_codec_spec); | |
834 } | |
835 | |
836 CreateAudioSendStream(); | |
1167 } | 837 } |
1168 | 838 |
1169 ~WebRtcAudioSendStream() override { | 839 ~WebRtcAudioSendStream() override { |
1170 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 840 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1171 ClearSource(); | 841 ClearSource(); |
1172 call_->DestroyAudioSendStream(stream_); | 842 call_->DestroyAudioSendStream(stream_); |
1173 } | 843 } |
1174 | 844 |
1175 void RecreateAudioSendStream( | 845 void SetSendCodecSpec( |
1176 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { | 846 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { |
1177 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 847 UpdateSendCodecSpec(send_codec_spec); |
1178 send_codec_spec_ = send_codec_spec; | 848 ReconfigureAudioSendStream(); |
1179 config_.rtp.nack.rtp_history_ms = | |
1180 send_codec_spec_.nack_enabled ? kNackRtpHistoryMs : 0; | |
1181 config_.send_codec_spec = send_codec_spec_; | |
1182 auto send_rate = ComputeSendBitrate( | |
1183 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, | |
1184 send_codec_spec.codec_inst); | |
1185 if (send_rate) { | |
1186 // Apply a send rate that abides by |max_send_bitrate_bps_| and | |
1187 // |rtp_parameters_| when possible. Otherwise use the codec rate. | |
1188 config_.send_codec_spec.codec_inst.rate = *send_rate; | |
1189 } | |
1190 RecreateAudioSendStream(); | |
1191 } | 849 } |
1192 | 850 |
1193 void RecreateAudioSendStream( | 851 void SetRtpExtensions(const std::vector<webrtc::RtpExtension>& extensions) { |
1194 const std::vector<webrtc::RtpExtension>& extensions) { | |
1195 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 852 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1196 config_.rtp.extensions = extensions; | 853 config_.rtp.extensions = extensions; |
1197 RecreateAudioSendStream(); | 854 ReconfigureAudioSendStream(); |
1198 } | 855 } |
1199 | 856 |
1200 void RecreateAudioSendStream( | 857 void SetAudioNetworkAdaptorConfig( |
1201 const rtc::Optional<std::string>& audio_network_adaptor_config) { | 858 const rtc::Optional<std::string>& audio_network_adaptor_config) { |
1202 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 859 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1203 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { | 860 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { |
1204 return; | 861 return; |
1205 } | 862 } |
1206 config_.audio_network_adaptor_config = audio_network_adaptor_config; | 863 config_.audio_network_adaptor_config = audio_network_adaptor_config; |
1207 RecreateAudioSendStream(); | 864 UpdateAllowedBitrateRange(); |
865 ReconfigureAudioSendStream(); | |
1208 } | 866 } |
1209 | 867 |
1210 bool SetMaxSendBitrate(int bps) { | 868 bool SetMaxSendBitrate(int bps) { |
1211 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 869 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1212 auto send_rate = | 870 RTC_DCHECK(config_.send_codec_spec); |
1213 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps, | 871 RTC_DCHECK(audio_codec_spec_); |
1214 send_codec_spec_.codec_inst); | 872 auto send_rate = ComputeSendBitrate( |
873 bps, rtp_parameters_.encodings[0].max_bitrate_bps, *audio_codec_spec_); | |
874 | |
1215 if (!send_rate) { | 875 if (!send_rate) { |
1216 return false; | 876 return false; |
1217 } | 877 } |
1218 | 878 |
1219 max_send_bitrate_bps_ = bps; | 879 max_send_bitrate_bps_ = bps; |
1220 | 880 |
1221 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { | 881 if (send_rate != config_.send_codec_spec->target_bitrate_bps) { |
1222 // Recreate AudioSendStream with new bit rate. | 882 config_.send_codec_spec->target_bitrate_bps = send_rate; |
1223 config_.send_codec_spec.codec_inst.rate = *send_rate; | 883 ReconfigureAudioSendStream(); |
1224 RecreateAudioSendStream(); | |
1225 } | 884 } |
1226 return true; | 885 return true; |
1227 } | 886 } |
1228 | 887 |
1229 bool SendTelephoneEvent(int payload_type, int payload_freq, int event, | 888 bool SendTelephoneEvent(int payload_type, int payload_freq, int event, |
1230 int duration_ms) { | 889 int duration_ms) { |
1231 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 890 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1232 RTC_DCHECK(stream_); | 891 RTC_DCHECK(stream_); |
1233 return stream_->SendTelephoneEvent(payload_type, payload_freq, event, | 892 return stream_->SendTelephoneEvent(payload_type, payload_freq, event, |
1234 duration_ms); | 893 duration_ms); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1330 LOG(LS_ERROR) << "Attempted to set RtpParameters with modified SSRC"; | 989 LOG(LS_ERROR) << "Attempted to set RtpParameters with modified SSRC"; |
1331 return false; | 990 return false; |
1332 } | 991 } |
1333 return true; | 992 return true; |
1334 } | 993 } |
1335 | 994 |
1336 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { | 995 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { |
1337 if (!ValidateRtpParameters(parameters)) { | 996 if (!ValidateRtpParameters(parameters)) { |
1338 return false; | 997 return false; |
1339 } | 998 } |
1340 auto send_rate = ComputeSendBitrate(max_send_bitrate_bps_, | 999 |
1341 parameters.encodings[0].max_bitrate_bps, | 1000 rtc::Optional<int> send_rate; |
1342 send_codec_spec_.codec_inst); | 1001 if (audio_codec_spec_) { |
1343 if (!send_rate) { | 1002 send_rate = ComputeSendBitrate(max_send_bitrate_bps_, |
1344 return false; | 1003 parameters.encodings[0].max_bitrate_bps, |
1004 *audio_codec_spec_); | |
1005 if (!send_rate) { | |
1006 return false; | |
1007 } | |
1345 } | 1008 } |
1346 | 1009 |
1347 const rtc::Optional<int> old_rtp_max_bitrate = | 1010 const rtc::Optional<int> old_rtp_max_bitrate = |
1348 rtp_parameters_.encodings[0].max_bitrate_bps; | 1011 rtp_parameters_.encodings[0].max_bitrate_bps; |
1349 | 1012 |
1350 rtp_parameters_ = parameters; | 1013 rtp_parameters_ = parameters; |
1351 | 1014 |
1352 if (rtp_parameters_.encodings[0].max_bitrate_bps != old_rtp_max_bitrate) { | 1015 if (rtp_parameters_.encodings[0].max_bitrate_bps != old_rtp_max_bitrate) { |
1353 // Recreate AudioSendStream with new bit rate. | 1016 // Reconfigure AudioSendStream with new bit rate. |
1354 config_.send_codec_spec.codec_inst.rate = *send_rate; | 1017 if (send_rate) { |
1355 RecreateAudioSendStream(); | 1018 config_.send_codec_spec->target_bitrate_bps = send_rate; |
1019 } | |
1020 UpdateAllowedBitrateRange(); | |
1021 ReconfigureAudioSendStream(); | |
1356 } else { | 1022 } else { |
1357 // parameters.encodings[0].active could have changed. | 1023 // parameters.encodings[0].active could have changed. |
1358 UpdateSendState(); | 1024 UpdateSendState(); |
1359 } | 1025 } |
1360 return true; | 1026 return true; |
1361 } | 1027 } |
1362 | 1028 |
1363 private: | 1029 private: |
1364 void UpdateSendState() { | 1030 void UpdateSendState() { |
1365 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1031 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1366 RTC_DCHECK(stream_); | 1032 RTC_DCHECK(stream_); |
1367 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); | 1033 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); |
1368 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { | 1034 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { |
1369 stream_->Start(); | 1035 stream_->Start(); |
1370 } else { // !send || source_ = nullptr | 1036 } else { // !send || source_ = nullptr |
1371 stream_->Stop(); | 1037 stream_->Stop(); |
1372 } | 1038 } |
1373 } | 1039 } |
1374 | 1040 |
1375 void RecreateAudioSendStream() { | 1041 void UpdateAllowedBitrateRange() { |
1376 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1042 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1377 if (stream_) { | |
1378 call_->DestroyAudioSendStream(stream_); | |
1379 stream_ = nullptr; | |
1380 } | |
1381 RTC_DCHECK(!stream_); | |
1382 if (webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe")) { | 1043 if (webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe")) { |
1383 config_.min_bitrate_bps = kOpusMinBitrateBps; | 1044 config_.min_bitrate_bps = kOpusMinBitrateBps; |
1384 | 1045 |
1385 // This means that when RtpParameters is reset, we may change the | 1046 // This means that when RtpParameters is reset, we may change the |
1386 // encoder's bit rate immediately (through call_->CreateAudioSendStream), | 1047 // encoder's bit rate immediately (through call_->CreateAudioSendStream), |
the sun
2017/04/25 11:38:53
bad comment
ossu
2017/04/25 17:10:07
Done.
| |
1387 // meanwhile change the cap to the output of BWE. | 1048 // meanwhile change the cap to the output of BWE. |
1388 config_.max_bitrate_bps = | 1049 config_.max_bitrate_bps = |
1389 rtp_parameters_.encodings[0].max_bitrate_bps | 1050 rtp_parameters_.encodings[0].max_bitrate_bps |
1390 ? *rtp_parameters_.encodings[0].max_bitrate_bps | 1051 ? *rtp_parameters_.encodings[0].max_bitrate_bps |
1391 : kOpusBitrateFbBps; | 1052 : kOpusBitrateFbBps; |
1392 | 1053 |
1393 // TODO(mflodman): Keep testing this and set proper values. | 1054 // TODO(mflodman): Keep testing this and set proper values. |
1394 // Note: This is an early experiment currently only supported by Opus. | 1055 // Note: This is an early experiment currently only supported by Opus. |
1395 if (send_side_bwe_with_overhead_) { | 1056 if (send_side_bwe_with_overhead_) { |
1396 auto packet_sizes_ms = WebRtcVoiceCodecs::GetPacketSizesMs( | 1057 const bool is_opus_with_ana = |
1397 config_.send_codec_spec.codec_inst); | 1058 config_.audio_network_adaptor_config && |
1398 if (!packet_sizes_ms.empty()) { | 1059 !STR_CASE_CMP(config_.send_codec_spec->format.name.c_str(), |
1399 int max_packet_size_ms = | 1060 kOpusCodecName); |
1400 *std::max_element(packet_sizes_ms.begin(), packet_sizes_ms.end()); | 1061 const int max_packet_size_ms = |
1062 (is_opus_with_ana && WEBRTC_OPUS_SUPPORT_120MS_PTIME) ? 120 : 60; | |
1401 | 1063 |
1402 // Audio network adaptor will just use 20ms and 60ms frame lengths. | 1064 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12) |
1403 // The adaptor will only be active for the Opus encoder. | 1065 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12; |
1404 if (config_.audio_network_adaptor_config && | |
1405 IsCodec(config_.send_codec_spec.codec_inst, kOpusCodecName)) { | |
1406 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME | |
1407 max_packet_size_ms = 120; | |
1408 #else | |
1409 max_packet_size_ms = 60; | |
1410 #endif | |
1411 } | |
1412 | 1066 |
1413 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12) | 1067 int min_overhead_bps = |
1414 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12; | 1068 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms; |
1415 | 1069 |
1416 int min_overhead_bps = | 1070 // We assume that |config_.max_bitrate_bps| before the next line is |
1417 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms; | 1071 // a hard limit on the payload bitrate, so we add min_overhead_bps to |
1072 // it to ensure that, when overhead is deducted, the payload rate | |
1073 // never goes beyond the limit. | |
1074 // Note: this also means that if a higher overhead is forced, we | |
1075 // cannot reach the limit. | |
1076 // TODO(minyue): Reconsider this when the signaling to BWE is done | |
1077 // through a dedicated API. | |
1078 config_.max_bitrate_bps += min_overhead_bps; | |
1418 | 1079 |
1419 // We assume that |config_.max_bitrate_bps| before the next line is | 1080 // In contrast to max_bitrate_bps, we let min_bitrate_bps always be |
1420 // a hard limit on the payload bitrate, so we add min_overhead_bps to | 1081 // reachable. |
1421 // it to ensure that, when overhead is deducted, the payload rate | 1082 config_.min_bitrate_bps += min_overhead_bps; |
1422 // never goes beyond the limit. | |
1423 // Note: this also means that if a higher overhead is forced, we | |
1424 // cannot reach the limit. | |
1425 // TODO(minyue): Reconsider this when the signaling to BWE is done | |
1426 // through a dedicated API. | |
1427 config_.max_bitrate_bps += min_overhead_bps; | |
1428 | |
1429 // In contrast to max_bitrate_bps, we let min_bitrate_bps always be | |
1430 // reachable. | |
1431 config_.min_bitrate_bps += min_overhead_bps; | |
1432 } | |
1433 } | 1083 } |
1434 } | 1084 } |
1085 } | |
1086 | |
1087 void UpdateSendCodecSpec( | |
1088 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { | |
1089 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1090 config_.rtp.nack.rtp_history_ms = | |
1091 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; | |
1092 config_.send_codec_spec = | |
1093 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>( | |
1094 send_codec_spec); | |
1095 auto info = | |
1096 config_.encoder_factory->QueryAudioEncoder(send_codec_spec.format); | |
1097 RTC_DCHECK(info); | |
1098 // If a specific target bitrate has been set for the stream, use that as | |
1099 // the new default bitrate when computing send bitrate. | |
1100 if (send_codec_spec.target_bitrate_bps) { | |
1101 info->default_bitrate_bps = std::max( | |
1102 info->min_bitrate_bps, | |
1103 std::min(info->max_bitrate_bps, *send_codec_spec.target_bitrate_bps)); | |
1104 } | |
1105 | |
1106 audio_codec_spec_.emplace( | |
1107 webrtc::AudioCodecSpec{send_codec_spec.format, *info}); | |
1108 | |
1109 config_.send_codec_spec->target_bitrate_bps = ComputeSendBitrate( | |
1110 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, | |
1111 *audio_codec_spec_); | |
1112 } | |
1113 | |
1114 void CreateAudioSendStream() { | |
the sun
2017/04/25 11:38:53
Don't need a function for this anymore
ossu
2017/04/25 17:10:07
Done.
| |
1115 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1116 RTC_DCHECK(!stream_); | |
1435 stream_ = call_->CreateAudioSendStream(config_); | 1117 stream_ = call_->CreateAudioSendStream(config_); |
1436 RTC_CHECK(stream_); | 1118 RTC_CHECK(stream_); |
1119 } | |
1120 | |
1121 void ReconfigureAudioSendStream() { | |
1122 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1123 RTC_DCHECK(stream_); | |
1124 stream_->Reconfigure(config_); | |
1437 UpdateSendState(); | 1125 UpdateSendState(); |
the sun
2017/04/25 11:38:53
Should no longer be needed - the stream already ha
ossu
2017/04/25 17:10:07
Done.
| |
1438 } | 1126 } |
1439 | 1127 |
1440 rtc::ThreadChecker worker_thread_checker_; | 1128 rtc::ThreadChecker worker_thread_checker_; |
1441 rtc::RaceChecker audio_capture_race_checker_; | 1129 rtc::RaceChecker audio_capture_race_checker_; |
1442 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; | 1130 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; |
1443 webrtc::Call* call_ = nullptr; | 1131 webrtc::Call* call_ = nullptr; |
1444 webrtc::AudioSendStream::Config config_; | 1132 webrtc::AudioSendStream::Config config_; |
1445 const bool send_side_bwe_with_overhead_; | 1133 const bool send_side_bwe_with_overhead_; |
1446 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 1134 // The stream is owned by WebRtcAudioSendStream and may be reallocated if |
1447 // configuration changes. | 1135 // configuration changes. |
1448 webrtc::AudioSendStream* stream_ = nullptr; | 1136 webrtc::AudioSendStream* stream_ = nullptr; |
1449 | 1137 |
1450 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. | 1138 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. |
1451 // PeerConnection will make sure invalidating the pointer before the object | 1139 // PeerConnection will make sure invalidating the pointer before the object |
1452 // goes away. | 1140 // goes away. |
1453 AudioSource* source_ = nullptr; | 1141 AudioSource* source_ = nullptr; |
1454 bool send_ = false; | 1142 bool send_ = false; |
1455 bool muted_ = false; | 1143 bool muted_ = false; |
1456 int max_send_bitrate_bps_; | 1144 int max_send_bitrate_bps_; |
1457 webrtc::RtpParameters rtp_parameters_; | 1145 webrtc::RtpParameters rtp_parameters_; |
1458 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec_; | 1146 rtc::Optional<webrtc::AudioCodecSpec> audio_codec_spec_; |
1459 | 1147 |
1460 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1148 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); |
1461 }; | 1149 }; |
1462 | 1150 |
1463 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1151 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { |
1464 public: | 1152 public: |
1465 WebRtcAudioReceiveStream( | 1153 WebRtcAudioReceiveStream( |
1466 int ch, | 1154 int ch, |
1467 uint32_t remote_ssrc, | 1155 uint32_t remote_ssrc, |
1468 uint32_t local_ssrc, | 1156 uint32_t local_ssrc, |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1654 | 1342 |
1655 if (!ValidateRtpExtensions(params.extensions)) { | 1343 if (!ValidateRtpExtensions(params.extensions)) { |
1656 return false; | 1344 return false; |
1657 } | 1345 } |
1658 std::vector<webrtc::RtpExtension> filtered_extensions = | 1346 std::vector<webrtc::RtpExtension> filtered_extensions = |
1659 FilterRtpExtensions(params.extensions, | 1347 FilterRtpExtensions(params.extensions, |
1660 webrtc::RtpExtension::IsSupportedForAudio, true); | 1348 webrtc::RtpExtension::IsSupportedForAudio, true); |
1661 if (send_rtp_extensions_ != filtered_extensions) { | 1349 if (send_rtp_extensions_ != filtered_extensions) { |
1662 send_rtp_extensions_.swap(filtered_extensions); | 1350 send_rtp_extensions_.swap(filtered_extensions); |
1663 for (auto& it : send_streams_) { | 1351 for (auto& it : send_streams_) { |
1664 it.second->RecreateAudioSendStream(send_rtp_extensions_); | 1352 it.second->SetRtpExtensions(send_rtp_extensions_); |
1665 } | 1353 } |
1666 } | 1354 } |
1667 | 1355 |
1668 if (!SetMaxSendBitrate(params.max_bandwidth_bps)) { | 1356 if (!SetMaxSendBitrate(params.max_bandwidth_bps)) { |
1669 return false; | 1357 return false; |
1670 } | 1358 } |
1671 return SetOptions(params.options); | 1359 return SetOptions(params.options); |
1672 } | 1360 } |
1673 | 1361 |
1674 bool WebRtcVoiceMediaChannel::SetRecvParameters( | 1362 bool WebRtcVoiceMediaChannel::SetRecvParameters( |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1821 // We retain all of the existing options, and apply the given ones | 1509 // We retain all of the existing options, and apply the given ones |
1822 // on top. This means there is no way to "clear" options such that | 1510 // on top. This means there is no way to "clear" options such that |
1823 // they go back to the engine default. | 1511 // they go back to the engine default. |
1824 options_.SetAll(options); | 1512 options_.SetAll(options); |
1825 if (!engine()->ApplyOptions(options_)) { | 1513 if (!engine()->ApplyOptions(options_)) { |
1826 LOG(LS_WARNING) << | 1514 LOG(LS_WARNING) << |
1827 "Failed to apply engine options during channel SetOptions."; | 1515 "Failed to apply engine options during channel SetOptions."; |
1828 return false; | 1516 return false; |
1829 } | 1517 } |
1830 | 1518 |
1831 rtc::Optional<std::string> audio_network_adatptor_config = | 1519 rtc::Optional<std::string> audio_network_adaptor_config = |
1832 GetAudioNetworkAdaptorConfig(options_); | 1520 GetAudioNetworkAdaptorConfig(options_); |
1833 for (auto& it : send_streams_) { | 1521 for (auto& it : send_streams_) { |
1834 it.second->RecreateAudioSendStream(audio_network_adatptor_config); | 1522 it.second->SetAudioNetworkAdaptorConfig(audio_network_adaptor_config); |
1835 } | 1523 } |
1836 | 1524 |
1837 LOG(LS_INFO) << "Set voice channel options. Current options: " | 1525 LOG(LS_INFO) << "Set voice channel options. Current options: " |
1838 << options_.ToString(); | 1526 << options_.ToString(); |
1839 return true; | 1527 return true; |
1840 } | 1528 } |
1841 | 1529 |
1842 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1530 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
1843 const std::vector<AudioCodec>& codecs) { | 1531 const std::vector<AudioCodec>& codecs) { |
1844 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1532 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1934 for (const AudioCodec& codec : codecs) { | 1622 for (const AudioCodec& codec : codecs) { |
1935 if (IsCodec(codec, kDtmfCodecName)) { | 1623 if (IsCodec(codec, kDtmfCodecName)) { |
1936 dtmf_codecs.push_back(codec); | 1624 dtmf_codecs.push_back(codec); |
1937 if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) { | 1625 if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) { |
1938 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 1626 dtmf_payload_type_ = rtc::Optional<int>(codec.id); |
1939 dtmf_payload_freq_ = codec.clockrate; | 1627 dtmf_payload_freq_ = codec.clockrate; |
1940 } | 1628 } |
1941 } | 1629 } |
1942 } | 1630 } |
1943 | 1631 |
1944 // Scan through the list to figure out the codec to use for sending, along | 1632 // Scan through the list to figure out the codec to use for sending. |
1945 // with the proper configuration for VAD, CNG, NACK and Opus-specific | 1633 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec> send_codec_spec; |
1946 // parameters. | |
1947 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. | |
1948 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec; | |
1949 webrtc::Call::Config::BitrateConfig bitrate_config; | 1634 webrtc::Call::Config::BitrateConfig bitrate_config; |
1950 { | 1635 rtc::Optional<webrtc::AudioCodecInfo> voice_codec_info; |
1951 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 1636 for (const AudioCodec& voice_codec : codecs) { |
1637 if (!(IsCodec(voice_codec, kCnCodecName) || | |
1638 IsCodec(voice_codec, kDtmfCodecName) || | |
1639 IsCodec(voice_codec, kRedCodecName))) { | |
1640 webrtc::SdpAudioFormat format(voice_codec.name, voice_codec.clockrate, | |
1641 voice_codec.channels, voice_codec.params); | |
1952 | 1642 |
1953 // Find send codec (the first non-telephone-event/CN codec). | 1643 voice_codec_info = engine()->encoder_factory_->QueryAudioEncoder(format); |
1954 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 1644 if (!voice_codec_info) { |
1955 codecs, &send_codec_spec.codec_inst); | 1645 LOG(LS_WARNING) << "Unknown codec " << ToString(voice_codec); |
1956 if (!codec) { | 1646 continue; |
1957 LOG(LS_WARNING) << "Received empty list of codecs."; | 1647 } |
1958 return false; | 1648 |
1649 send_codec_spec = | |
1650 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>( | |
1651 {voice_codec.id, format}); | |
1652 if (voice_codec.bitrate > 0) { | |
1653 send_codec_spec->target_bitrate_bps = | |
1654 rtc::Optional<int>(voice_codec.bitrate); | |
1655 } | |
1656 send_codec_spec->transport_cc_enabled = HasTransportCc(voice_codec); | |
1657 send_codec_spec->nack_enabled = HasNack(voice_codec); | |
1658 bitrate_config = GetBitrateConfigForCodec(voice_codec); | |
1659 break; | |
1959 } | 1660 } |
1661 } | |
1960 | 1662 |
1961 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec); | 1663 if (!send_codec_spec) |
the sun
2017/04/25 11:38:53
nit: use {} like elsewhere in this file
ossu
2017/04/25 17:10:07
Done.
| |
1962 send_codec_spec.nack_enabled = HasNack(*codec); | 1664 return false; |
1963 bitrate_config = GetBitrateConfigForCodec(*codec); | |
1964 | 1665 |
1965 // For Opus as the send codec, we are to determine inband FEC, maximum | 1666 RTC_DCHECK(voice_codec_info); |
1966 // playback rate, and opus internal dtx. | 1667 if (voice_codec_info->allow_comfort_noise) { |
1967 if (IsCodec(*codec, kOpusCodecName)) { | |
1968 GetOpusConfig(*codec, &send_codec_spec.codec_inst, | |
1969 &send_codec_spec.enable_codec_fec, | |
1970 &send_codec_spec.opus_max_playback_rate, | |
1971 &send_codec_spec.enable_opus_dtx, | |
1972 &send_codec_spec.min_ptime_ms, | |
1973 &send_codec_spec.max_ptime_ms); | |
1974 } | |
1975 | |
1976 // Set packet size if the AudioCodec param kCodecParamPTime is set. | |
1977 int ptime_ms = 0; | |
1978 if (codec->GetParam(kCodecParamPTime, &ptime_ms)) { | |
1979 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize( | |
1980 &send_codec_spec.codec_inst, ptime_ms)) { | |
1981 LOG(LS_WARNING) << "Failed to set packet size for codec " | |
1982 << send_codec_spec.codec_inst.plname; | |
1983 return false; | |
1984 } | |
1985 } | |
1986 | |
1987 // Loop through the codecs list again to find the CN codec. | 1668 // Loop through the codecs list again to find the CN codec. |
1988 // TODO(solenberg): Break out into a separate function? | 1669 // TODO(solenberg): Break out into a separate function? |
1989 for (const AudioCodec& cn_codec : codecs) { | 1670 for (const AudioCodec& cn_codec : codecs) { |
1990 // Ignore codecs we don't know about. The negotiation step should prevent | |
1991 // this, but double-check to be sure. | |
1992 webrtc::CodecInst voe_codec = {0}; | |
1993 if (!WebRtcVoiceEngine::ToCodecInst(cn_codec, &voe_codec)) { | |
1994 LOG(LS_WARNING) << "Unknown codec " << ToString(cn_codec); | |
1995 continue; | |
1996 } | |
1997 | |
1998 if (IsCodec(cn_codec, kCnCodecName) && | 1671 if (IsCodec(cn_codec, kCnCodecName) && |
1999 cn_codec.clockrate == codec->clockrate) { | 1672 cn_codec.clockrate == send_codec_spec->format.clockrate_hz) { |
2000 // Turn voice activity detection/comfort noise on if supported. | |
2001 // Set the wideband CN payload type appropriately. | |
2002 // (narrowband always uses the static payload type 13). | |
2003 int cng_plfreq = -1; | |
2004 switch (cn_codec.clockrate) { | 1673 switch (cn_codec.clockrate) { |
2005 case 8000: | 1674 case 8000: |
2006 case 16000: | 1675 case 16000: |
2007 case 32000: | 1676 case 32000: |
2008 cng_plfreq = cn_codec.clockrate; | 1677 send_codec_spec->cng_payload_type = rtc::Optional<int>(cn_codec.id); |
2009 break; | 1678 break; |
2010 default: | 1679 default: |
2011 LOG(LS_WARNING) << "CN frequency " << cn_codec.clockrate | 1680 LOG(LS_WARNING) << "CN frequency " << cn_codec.clockrate |
2012 << " not supported."; | 1681 << " not supported."; |
2013 continue; | 1682 break; |
2014 } | 1683 } |
2015 send_codec_spec.cng_payload_type = cn_codec.id; | |
2016 send_codec_spec.cng_plfreq = cng_plfreq; | |
2017 break; | 1684 break; |
2018 } | 1685 } |
2019 } | 1686 } |
2020 | 1687 |
2021 // Find the telephone-event PT exactly matching the preferred send codec. | 1688 // Find the telephone-event PT exactly matching the preferred send codec. |
2022 for (const AudioCodec& dtmf_codec : dtmf_codecs) { | 1689 for (const AudioCodec& dtmf_codec : dtmf_codecs) { |
2023 if (dtmf_codec.clockrate == codec->clockrate) { | 1690 if (dtmf_codec.clockrate == send_codec_spec->format.clockrate_hz) { |
2024 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id); | 1691 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id); |
2025 dtmf_payload_freq_ = dtmf_codec.clockrate; | 1692 dtmf_payload_freq_ = dtmf_codec.clockrate; |
2026 break; | 1693 break; |
2027 } | 1694 } |
2028 } | 1695 } |
2029 } | 1696 } |
2030 | 1697 |
2031 if (send_codec_spec_ != send_codec_spec) { | 1698 if (send_codec_spec_ != send_codec_spec) { |
2032 send_codec_spec_ = std::move(send_codec_spec); | 1699 send_codec_spec_ = std::move(send_codec_spec); |
2033 // Apply new settings to all streams. | 1700 // Apply new settings to all streams. |
2034 for (const auto& kv : send_streams_) { | 1701 for (const auto& kv : send_streams_) { |
2035 kv.second->RecreateAudioSendStream(send_codec_spec_); | 1702 kv.second->SetSendCodecSpec(*send_codec_spec_); |
2036 } | 1703 } |
2037 } else { | 1704 } else { |
2038 // If the codec isn't changing, set the start bitrate to -1 which means | 1705 // If the codec isn't changing, set the start bitrate to -1 which means |
2039 // "unchanged" so that BWE isn't affected. | 1706 // "unchanged" so that BWE isn't affected. |
2040 bitrate_config.start_bitrate_bps = -1; | 1707 bitrate_config.start_bitrate_bps = -1; |
2041 } | 1708 } |
2042 call_->SetBitrateConfig(bitrate_config); | 1709 call_->SetBitrateConfig(bitrate_config); |
2043 | 1710 |
2044 // Check if the transport cc feedback or NACK status has changed on the | 1711 // Check if the transport cc feedback or NACK status has changed on the |
2045 // preferred send codec, and in that case reconfigure all receive streams. | 1712 // preferred send codec, and in that case reconfigure all receive streams. |
2046 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || | 1713 if (recv_transport_cc_enabled_ != send_codec_spec_->transport_cc_enabled || |
2047 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { | 1714 recv_nack_enabled_ != send_codec_spec_->nack_enabled) { |
2048 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1715 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
2049 "codec has changed."; | 1716 "codec has changed."; |
2050 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1717 recv_transport_cc_enabled_ = send_codec_spec_->transport_cc_enabled; |
2051 recv_nack_enabled_ = send_codec_spec_.nack_enabled; | 1718 recv_nack_enabled_ = send_codec_spec_->nack_enabled; |
2052 for (auto& kv : recv_streams_) { | 1719 for (auto& kv : recv_streams_) { |
2053 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, | 1720 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, |
2054 recv_nack_enabled_); | 1721 recv_nack_enabled_); |
2055 } | 1722 } |
2056 } | 1723 } |
2057 | 1724 |
2058 send_codecs_ = codecs; | 1725 send_codecs_ = codecs; |
2059 return true; | 1726 return true; |
2060 } | 1727 } |
2061 | 1728 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2164 // Save the channel to send_streams_, so that RemoveSendStream() can still | 1831 // Save the channel to send_streams_, so that RemoveSendStream() can still |
2165 // delete the channel in case failure happens below. | 1832 // delete the channel in case failure happens below. |
2166 webrtc::AudioTransport* audio_transport = | 1833 webrtc::AudioTransport* audio_transport = |
2167 engine()->voe()->base()->audio_transport(); | 1834 engine()->voe()->base()->audio_transport(); |
2168 | 1835 |
2169 rtc::Optional<std::string> audio_network_adaptor_config = | 1836 rtc::Optional<std::string> audio_network_adaptor_config = |
2170 GetAudioNetworkAdaptorConfig(options_); | 1837 GetAudioNetworkAdaptorConfig(options_); |
2171 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 1838 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( |
2172 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, | 1839 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, |
2173 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, | 1840 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, |
2174 call_, this); | 1841 call_, this, engine()->encoder_factory_); |
2175 send_streams_.insert(std::make_pair(ssrc, stream)); | 1842 send_streams_.insert(std::make_pair(ssrc, stream)); |
2176 | 1843 |
2177 // At this point the stream's local SSRC has been updated. If it is the first | 1844 // At this point the stream's local SSRC has been updated. If it is the first |
2178 // send stream, make sure that all the receive streams are updated with the | 1845 // send stream, make sure that all the receive streams are updated with the |
2179 // same SSRC in order to send receiver reports. | 1846 // same SSRC in order to send receiver reports. |
2180 if (send_streams_.size() == 1) { | 1847 if (send_streams_.size() == 1) { |
2181 receiver_reports_ssrc_ = ssrc; | 1848 receiver_reports_ssrc_ = ssrc; |
2182 for (const auto& kv : recv_streams_) { | 1849 for (const auto& kv : recv_streams_) { |
2183 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive | 1850 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive |
2184 // streams instead, so we can avoid recreating the streams here. | 1851 // streams instead, so we can avoid recreating the streams here. |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2664 ssrc); | 2331 ssrc); |
2665 if (it != unsignaled_recv_ssrcs_.end()) { | 2332 if (it != unsignaled_recv_ssrcs_.end()) { |
2666 unsignaled_recv_ssrcs_.erase(it); | 2333 unsignaled_recv_ssrcs_.erase(it); |
2667 return true; | 2334 return true; |
2668 } | 2335 } |
2669 return false; | 2336 return false; |
2670 } | 2337 } |
2671 } // namespace cricket | 2338 } // namespace cricket |
2672 | 2339 |
2673 #endif // HAVE_WEBRTC_VOICE | 2340 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |