Chromium Code Reviews| 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/acm2/rent_a_codec.h" |
|
the sun
2017/04/07 11:52:56
remove?
ossu
2017/04/10 10:18:39
Oh, yes!
| |
| 41 #include "webrtc/modules/audio_coding/codecs/builtin_audio_encoder_factory.h" | |
| 41 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" | 42 #include "webrtc/modules/audio_mixer/audio_mixer_impl.h" |
| 42 #include "webrtc/modules/audio_processing/include/audio_processing.h" | 43 #include "webrtc/modules/audio_processing/include/audio_processing.h" |
| 43 #include "webrtc/system_wrappers/include/field_trial.h" | 44 #include "webrtc/system_wrappers/include/field_trial.h" |
| 44 #include "webrtc/system_wrappers/include/metrics.h" | 45 #include "webrtc/system_wrappers/include/metrics.h" |
| 45 #include "webrtc/system_wrappers/include/trace.h" | 46 #include "webrtc/system_wrappers/include/trace.h" |
| 46 #include "webrtc/voice_engine/transmit_mixer.h" | 47 #include "webrtc/voice_engine/transmit_mixer.h" |
| 47 | 48 |
| 48 namespace cricket { | 49 namespace cricket { |
| 49 namespace { | 50 namespace { |
| 50 | 51 |
| 51 constexpr size_t kMaxUnsignaledRecvStreams = 1; | 52 constexpr size_t kMaxUnsignaledRecvStreams = 1; |
| 52 | 53 |
| 53 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | | 54 const int kDefaultTraceFilter = webrtc::kTraceNone | webrtc::kTraceTerseInfo | |
| 54 webrtc::kTraceWarning | webrtc::kTraceError | | 55 webrtc::kTraceWarning | webrtc::kTraceError | |
| 55 webrtc::kTraceCritical; | 56 webrtc::kTraceCritical; |
| 56 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | | 57 const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo | |
| 57 webrtc::kTraceInfo; | 58 webrtc::kTraceInfo; |
| 58 | 59 |
| 59 constexpr int kNackRtpHistoryMs = 5000; | 60 constexpr int kNackRtpHistoryMs = 5000; |
| 60 | 61 |
| 61 // Check to verify that the define for the intelligibility enhancer is properly | 62 // Check to verify that the define for the intelligibility enhancer is properly |
| 62 // set. | 63 // set. |
| 63 #if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \ | 64 #if !defined(WEBRTC_INTELLIGIBILITY_ENHANCER) || \ |
| 64 (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \ | 65 (WEBRTC_INTELLIGIBILITY_ENHANCER != 0 && \ |
| 65 WEBRTC_INTELLIGIBILITY_ENHANCER != 1) | 66 WEBRTC_INTELLIGIBILITY_ENHANCER != 1) |
| 66 #error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1" | 67 #error "Set WEBRTC_INTELLIGIBILITY_ENHANCER to either 0 or 1" |
| 67 #endif | 68 #endif |
| 68 | 69 |
| 69 // Codec parameters for Opus. | 70 // For SendSideBwe, Opus bitrate should be in the range between 6000 and 32000. |
| 70 // draft-spittka-payload-rtp-opus-03 | 71 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; | 72 const int kOpusBitrateFbBps = 32000; |
| 83 | 73 |
| 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. | 74 // Default audio dscp value. |
| 92 // See http://tools.ietf.org/html/rfc2474 for details. | 75 // See http://tools.ietf.org/html/rfc2474 for details. |
| 93 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 | 76 // See also http://tools.ietf.org/html/draft-jennings-rtcweb-qos-00 |
| 94 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; | 77 const rtc::DiffServCodePoint kAudioDscpValue = rtc::DSCP_EF; |
| 95 | 78 |
| 96 // Constants from voice_engine_defines.h. | 79 // Constants from voice_engine_defines.h. |
| 97 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) | 80 const int kMinTelephoneEventCode = 0; // RFC4733 (Section 2.3.1) |
| 98 const int kMaxTelephoneEventCode = 255; | 81 const int kMaxTelephoneEventCode = 255; |
| 99 | 82 |
| 100 const int kMinPayloadType = 0; | 83 const int kMinPayloadType = 0; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 118 if (sp.ssrcs.size() > 1) { | 101 if (sp.ssrcs.size() > 1) { |
| 119 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); | 102 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); |
| 120 return false; | 103 return false; |
| 121 } | 104 } |
| 122 return true; | 105 return true; |
| 123 } | 106 } |
| 124 | 107 |
| 125 // Dumps an AudioCodec in RFC 2327-ish format. | 108 // Dumps an AudioCodec in RFC 2327-ish format. |
| 126 std::string ToString(const AudioCodec& codec) { | 109 std::string ToString(const AudioCodec& codec) { |
| 127 std::stringstream ss; | 110 std::stringstream ss; |
| 128 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels | 111 ss << codec.name << "/" << codec.clockrate << "/" << codec.channels; |
| 129 << " (" << codec.id << ")"; | 112 if (!codec.params.empty()) { |
| 113 ss << " {"; | |
| 114 for (const auto& param : codec.params) { | |
| 115 ss << " " << param.first << "=" << param.second; | |
| 116 } | |
| 117 ss << " }"; | |
| 118 } | |
| 119 ss << " (" << codec.id << ")"; | |
| 130 return ss.str(); | 120 return ss.str(); |
| 131 } | 121 } |
| 132 | 122 |
| 133 bool IsCodec(const AudioCodec& codec, const char* ref_name) { | 123 bool IsCodec(const AudioCodec& codec, const char* ref_name) { |
| 134 return (_stricmp(codec.name.c_str(), ref_name) == 0); | 124 return (_stricmp(codec.name.c_str(), ref_name) == 0); |
| 135 } | 125 } |
| 136 | 126 |
| 137 bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) { | 127 bool IsCodec(const webrtc::CodecInst& codec, const char* ref_name) { |
| 138 return (_stricmp(codec.plname, ref_name) == 0); | 128 return (_stricmp(codec.plname, ref_name) == 0); |
| 139 } | 129 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 158 } | 148 } |
| 159 std::vector<int> payload_types; | 149 std::vector<int> payload_types; |
| 160 for (const AudioCodec& codec : codecs) { | 150 for (const AudioCodec& codec : codecs) { |
| 161 payload_types.push_back(codec.id); | 151 payload_types.push_back(codec.id); |
| 162 } | 152 } |
| 163 std::sort(payload_types.begin(), payload_types.end()); | 153 std::sort(payload_types.begin(), payload_types.end()); |
| 164 auto it = std::unique(payload_types.begin(), payload_types.end()); | 154 auto it = std::unique(payload_types.begin(), payload_types.end()); |
| 165 return it == payload_types.end(); | 155 return it == payload_types.end(); |
| 166 } | 156 } |
| 167 | 157 |
| 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( | 158 rtc::Optional<std::string> GetAudioNetworkAdaptorConfig( |
| 175 const AudioOptions& options) { | 159 const AudioOptions& options) { |
| 176 if (options.audio_network_adaptor && *options.audio_network_adaptor && | 160 if (options.audio_network_adaptor && *options.audio_network_adaptor && |
| 177 options.audio_network_adaptor_config) { | 161 options.audio_network_adaptor_config) { |
| 178 // Turn on audio network adaptor only when |options_.audio_network_adaptor| | 162 // Turn on audio network adaptor only when |options_.audio_network_adaptor| |
| 179 // equals true and |options_.audio_network_adaptor_config| has a value. | 163 // equals true and |options_.audio_network_adaptor_config| has a value. |
| 180 return options.audio_network_adaptor_config; | 164 return options.audio_network_adaptor_config; |
| 181 } | 165 } |
| 182 return rtc::Optional<std::string>(); | 166 return rtc::Optional<std::string>(); |
| 183 } | 167 } |
| 184 | 168 |
| 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( | 169 webrtc::AudioState::Config MakeAudioStateConfig( |
| 265 VoEWrapper* voe_wrapper, | 170 VoEWrapper* voe_wrapper, |
| 266 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) { | 171 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) { |
| 267 webrtc::AudioState::Config config; | 172 webrtc::AudioState::Config config; |
| 268 config.voice_engine = voe_wrapper->engine(); | 173 config.voice_engine = voe_wrapper->engine(); |
| 269 if (audio_mixer) { | 174 if (audio_mixer) { |
| 270 config.audio_mixer = audio_mixer; | 175 config.audio_mixer = audio_mixer; |
| 271 } else { | 176 } else { |
| 272 config.audio_mixer = webrtc::AudioMixerImpl::Create(); | 177 config.audio_mixer = webrtc::AudioMixerImpl::Create(); |
| 273 } | 178 } |
| 274 return config; | 179 return config; |
| 275 } | 180 } |
| 276 | 181 |
| 277 class WebRtcVoiceCodecs final { | 182 class WebRtcVoiceCodecs final { |
| 278 public: | 183 public: |
| 279 // TODO(solenberg): Do this filtering once off-line, add a simple AudioCodec | 184 static bool ToCodecInst(const AudioCodec& in, webrtc::CodecInst* out) { |
| 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()) { | 185 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { |
| 335 // Change the sample rate of G722 to 8000 to match SDP. | 186 // Change the sample rate of G722 to 8000 to match SDP. |
| 336 MaybeFixupG722(&voe_codec, 8000); | 187 MaybeFixupG722(&voe_codec, 8000); |
| 337 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, | 188 AudioCodec codec(voe_codec.pltype, voe_codec.plname, voe_codec.plfreq, |
| 338 voe_codec.rate, voe_codec.channels); | 189 voe_codec.rate, voe_codec.channels); |
| 339 bool multi_rate = IsCodecMultiRate(voe_codec); | 190 const bool multi_rate = |
| 191 IsCodec(codec, kIsacCodecName) || IsCodec(codec, kOpusCodecName); | |
| 340 // Allow arbitrary rates for ISAC to be specified. | 192 // Allow arbitrary rates for ISAC to be specified. |
| 341 if (multi_rate) { | 193 if (multi_rate) { |
| 342 // Set codec.bitrate to 0 so the check for codec.Matches() passes. | 194 // Set codec.bitrate to 0 so the check for codec.Matches() passes. |
| 343 codec.bitrate = 0; | 195 codec.bitrate = 0; |
| 344 } | 196 } |
| 345 if (codec.Matches(in)) { | 197 if (codec.Matches(in)) { |
| 346 if (out) { | 198 if (out) { |
| 347 // Fixup the payload type. | 199 // Fixup the payload type. |
| 348 voe_codec.pltype = in.id; | 200 voe_codec.pltype = in.id; |
| 349 | 201 |
| 350 // Set bitrate if specified. | 202 // Set bitrate if specified. |
| 351 if (multi_rate && in.bitrate != 0) { | 203 if (multi_rate && in.bitrate != 0) { |
| 352 voe_codec.rate = in.bitrate; | 204 voe_codec.rate = in.bitrate; |
| 353 } | 205 } |
| 354 | 206 |
| 355 // Reset G722 sample rate to 16000 to match WebRTC. | 207 // Reset G722 sample rate to 16000 to match WebRTC. |
| 356 MaybeFixupG722(&voe_codec, 16000); | 208 MaybeFixupG722(&voe_codec, 16000); |
| 357 | 209 |
| 358 *out = voe_codec; | 210 *out = voe_codec; |
| 359 } | 211 } |
| 360 return true; | 212 return true; |
| 361 } | 213 } |
| 362 } | 214 } |
| 363 return false; | 215 return false; |
| 364 } | 216 } |
| 365 | 217 |
| 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 | 218 // 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 | 219 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz |
| 474 // codec. | 220 // codec. |
| 475 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { | 221 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { |
| 476 if (IsCodec(*voe_codec, kG722CodecName)) { | 222 if (IsCodec(*voe_codec, kG722CodecName)) { |
| 477 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine | 223 // If the DCHECK triggers, the codec definition in WebRTC VoiceEngine |
| 478 // has changed, and this special case is no longer needed. | 224 // has changed, and this special case is no longer needed. |
| 479 RTC_DCHECK(voe_codec->plfreq != new_plfreq); | 225 RTC_DCHECK(voe_codec->plfreq != new_plfreq); |
| 480 voe_codec->plfreq = new_plfreq; | 226 voe_codec->plfreq = new_plfreq; |
| 481 } | 227 } |
| 482 } | 228 } |
| 483 }; | 229 }; |
| 484 | 230 |
| 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. | 231 // |max_send_bitrate_bps| is the bitrate from "b=" in SDP. |
| 509 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters. | 232 // |rtp_max_bitrate_bps| is the bitrate from RtpSender::SetParameters. |
| 510 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, | 233 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, |
| 511 rtc::Optional<int> rtp_max_bitrate_bps, | 234 rtc::Optional<int> rtp_max_bitrate_bps, |
| 512 const webrtc::CodecInst& codec_inst) { | 235 const webrtc::AudioCodecSpec& spec) { |
| 513 // If application-configured bitrate is set, take minimum of that and SDP | 236 // If application-configured bitrate is set, take minimum of that and SDP |
| 514 // bitrate. | 237 // bitrate. |
| 515 const int bps = rtp_max_bitrate_bps | 238 const int bps = rtp_max_bitrate_bps |
| 516 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps) | 239 ? MinPositive(max_send_bitrate_bps, *rtp_max_bitrate_bps) |
| 517 : max_send_bitrate_bps; | 240 : max_send_bitrate_bps; |
| 518 const int codec_rate = codec_inst.rate; | |
| 519 | |
| 520 if (bps <= 0) { | 241 if (bps <= 0) { |
| 521 return rtc::Optional<int>(codec_rate); | 242 return rtc::Optional<int>(spec.info.default_bitrate_bps); |
| 522 } | 243 } |
| 523 | 244 |
| 524 if (codec_inst.pltype == -1) { | 245 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 | 246 // 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 | 247 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed |
| 538 // bitrate then ignore. | 248 // bitrate then ignore. |
| 539 LOG(LS_ERROR) << "Failed to set codec " << codec_inst.plname | 249 LOG(LS_ERROR) << "Failed to set codec " << spec.format.name |
| 540 << " to bitrate " << bps << " bps" | 250 << " to bitrate " << bps << " bps" |
| 541 << ", requires at least " << codec_inst.rate << " bps."; | 251 << ", requires at least " << spec.info.min_bitrate_bps |
| 252 << " bps."; | |
| 542 return rtc::Optional<int>(); | 253 return rtc::Optional<int>(); |
| 543 } | 254 } |
| 544 return rtc::Optional<int>(codec_rate); | 255 |
| 256 if (spec.info.HasFixedBitrate()) { | |
| 257 return rtc::Optional<int>(spec.info.default_bitrate_bps); | |
| 258 } else { | |
| 259 // If codec is multi-rate then just set the bitrate. | |
| 260 return rtc::Optional<int>(std::min(bps, spec.info.max_bitrate_bps)); | |
| 261 } | |
| 545 } | 262 } |
| 546 | 263 |
| 547 } // namespace | 264 } // namespace |
| 548 | 265 |
| 549 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 266 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, |
| 550 webrtc::CodecInst* out) { | 267 webrtc::CodecInst* out) { |
| 551 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 268 return WebRtcVoiceCodecs::ToCodecInst(in, out); |
| 552 } | 269 } |
| 553 | 270 |
| 554 WebRtcVoiceEngine::WebRtcVoiceEngine( | 271 WebRtcVoiceEngine::WebRtcVoiceEngine( |
| 555 webrtc::AudioDeviceModule* adm, | 272 webrtc::AudioDeviceModule* adm, |
| 556 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, | 273 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, |
| 557 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) | 274 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) |
| 558 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) { | 275 : WebRtcVoiceEngine(adm, decoder_factory, audio_mixer, new VoEWrapper()) { |
| 559 audio_state_ = | 276 audio_state_ = |
| 560 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer)); | 277 webrtc::AudioState::Create(MakeAudioStateConfig(voe(), audio_mixer)); |
| 561 } | 278 } |
| 562 | 279 |
| 563 WebRtcVoiceEngine::WebRtcVoiceEngine( | 280 WebRtcVoiceEngine::WebRtcVoiceEngine( |
| 564 webrtc::AudioDeviceModule* adm, | 281 webrtc::AudioDeviceModule* adm, |
| 565 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, | 282 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory, |
| 566 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, | 283 rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, |
| 567 VoEWrapper* voe_wrapper) | 284 VoEWrapper* voe_wrapper) |
| 568 : adm_(adm), decoder_factory_(decoder_factory), voe_wrapper_(voe_wrapper) { | 285 : adm_(adm), |
| 286 encoder_factory_(webrtc::CreateBuiltinAudioEncoderFactory()), | |
| 287 decoder_factory_(decoder_factory), | |
| 288 voe_wrapper_(voe_wrapper) { | |
| 569 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 289 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 570 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; | 290 LOG(LS_INFO) << "WebRtcVoiceEngine::WebRtcVoiceEngine"; |
| 571 RTC_DCHECK(voe_wrapper); | 291 RTC_DCHECK(voe_wrapper); |
| 572 RTC_DCHECK(decoder_factory); | 292 RTC_DCHECK(decoder_factory); |
| 573 | 293 |
| 574 signal_thread_checker_.DetachFromThread(); | 294 signal_thread_checker_.DetachFromThread(); |
| 575 | 295 |
| 576 // Load our audio codec list. | 296 // Load our audio codec list. |
| 577 LOG(LS_INFO) << "Supported send codecs in order of preference:"; | 297 LOG(LS_INFO) << "Supported send codecs in order of preference:"; |
| 578 send_codecs_ = WebRtcVoiceCodecs::SupportedSendCodecs(); | 298 send_codecs_ = CollectCodecs(encoder_factory_->GetSupportedEncoders()); |
| 579 for (const AudioCodec& codec : send_codecs_) { | 299 for (const AudioCodec& codec : send_codecs_) { |
| 580 LOG(LS_INFO) << ToString(codec); | 300 LOG(LS_INFO) << ToString(codec); |
| 581 } | 301 } |
| 582 | 302 |
| 583 LOG(LS_INFO) << "Supported recv codecs in order of preference:"; | 303 LOG(LS_INFO) << "Supported recv codecs in order of preference:"; |
| 584 recv_codecs_ = CollectRecvCodecs(); | 304 recv_codecs_ = CollectCodecs(decoder_factory_->GetSupportedDecoders()); |
| 585 for (const AudioCodec& codec : recv_codecs_) { | 305 for (const AudioCodec& codec : recv_codecs_) { |
| 586 LOG(LS_INFO) << ToString(codec); | 306 LOG(LS_INFO) << ToString(codec); |
| 587 } | 307 } |
| 588 | 308 |
| 589 channel_config_.enable_voice_pacing = true; | 309 channel_config_.enable_voice_pacing = true; |
| 590 | 310 |
| 591 // Temporarily turn logging level up for the Init() call. | 311 // Temporarily turn logging level up for the Init() call. |
| 592 webrtc::Trace::SetTraceCallback(this); | 312 webrtc::Trace::SetTraceCallback(this); |
| 593 webrtc::Trace::set_level_filter(kElevatedTraceFilter); | 313 webrtc::Trace::set_level_filter(kElevatedTraceFilter); |
| 594 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString(); | 314 LOG(LS_INFO) << webrtc::VoiceEngine::GetVersionString(); |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1049 RTC_DCHECK(apm_); | 769 RTC_DCHECK(apm_); |
| 1050 return apm_; | 770 return apm_; |
| 1051 } | 771 } |
| 1052 | 772 |
| 1053 webrtc::voe::TransmitMixer* WebRtcVoiceEngine::transmit_mixer() { | 773 webrtc::voe::TransmitMixer* WebRtcVoiceEngine::transmit_mixer() { |
| 1054 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 774 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1055 RTC_DCHECK(transmit_mixer_); | 775 RTC_DCHECK(transmit_mixer_); |
| 1056 return transmit_mixer_; | 776 return transmit_mixer_; |
| 1057 } | 777 } |
| 1058 | 778 |
| 1059 AudioCodecs WebRtcVoiceEngine::CollectRecvCodecs() const { | 779 AudioCodecs WebRtcVoiceEngine::CollectCodecs( |
| 780 const std::vector<webrtc::AudioCodecSpec>& specs) const { | |
| 1060 PayloadTypeMapper mapper; | 781 PayloadTypeMapper mapper; |
| 1061 AudioCodecs out; | 782 AudioCodecs out; |
| 1062 const std::vector<webrtc::AudioCodecSpec>& specs = | |
| 1063 decoder_factory_->GetSupportedDecoders(); | |
| 1064 | 783 |
| 1065 // Only generate CN payload types for these clockrates: | 784 // Only generate CN payload types for these clockrates: |
| 1066 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, | 785 std::map<int, bool, std::greater<int>> generate_cn = {{ 8000, false }, |
| 1067 { 16000, false }, | 786 { 16000, false }, |
| 1068 { 32000, false }}; | 787 { 32000, false }}; |
| 1069 // Only generate telephone-event payload types for these clockrates: | 788 // Only generate telephone-event payload types for these clockrates: |
| 1070 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, | 789 std::map<int, bool, std::greater<int>> generate_dtmf = {{ 8000, false }, |
| 1071 { 16000, false }, | 790 { 16000, false }, |
| 1072 { 32000, false }, | 791 { 32000, false }, |
| 1073 { 48000, false }}; | 792 { 48000, false }}; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1133 } | 852 } |
| 1134 | 853 |
| 1135 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 854 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
| 1136 : public AudioSource::Sink { | 855 : public AudioSource::Sink { |
| 1137 public: | 856 public: |
| 1138 WebRtcAudioSendStream( | 857 WebRtcAudioSendStream( |
| 1139 int ch, | 858 int ch, |
| 1140 webrtc::AudioTransport* voe_audio_transport, | 859 webrtc::AudioTransport* voe_audio_transport, |
| 1141 uint32_t ssrc, | 860 uint32_t ssrc, |
| 1142 const std::string& c_name, | 861 const std::string& c_name, |
| 1143 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, | 862 const rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>& |
| 863 send_codec_spec, | |
| 1144 const std::vector<webrtc::RtpExtension>& extensions, | 864 const std::vector<webrtc::RtpExtension>& extensions, |
| 1145 int max_send_bitrate_bps, | 865 int max_send_bitrate_bps, |
| 1146 const rtc::Optional<std::string>& audio_network_adaptor_config, | 866 const rtc::Optional<std::string>& audio_network_adaptor_config, |
| 1147 webrtc::Call* call, | 867 webrtc::Call* call, |
| 1148 webrtc::Transport* send_transport) | 868 webrtc::Transport* send_transport, |
| 869 const rtc::scoped_refptr<webrtc::AudioEncoderFactory>& encoder_factory) | |
| 1149 : voe_audio_transport_(voe_audio_transport), | 870 : voe_audio_transport_(voe_audio_transport), |
| 1150 call_(call), | 871 call_(call), |
| 1151 config_(send_transport), | 872 config_(send_transport), |
| 1152 send_side_bwe_with_overhead_( | 873 send_side_bwe_with_overhead_( |
| 1153 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), | 874 webrtc::field_trial::IsEnabled("WebRTC-SendSideBwe-WithOverhead")), |
| 1154 max_send_bitrate_bps_(max_send_bitrate_bps), | 875 max_send_bitrate_bps_(max_send_bitrate_bps), |
| 1155 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 876 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { |
| 1156 RTC_DCHECK_GE(ch, 0); | 877 RTC_DCHECK_GE(ch, 0); |
| 1157 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 878 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
| 1158 // RTC_DCHECK(voe_audio_transport); | 879 // RTC_DCHECK(voe_audio_transport); |
| 1159 RTC_DCHECK(call); | 880 RTC_DCHECK(call); |
| 881 RTC_DCHECK(encoder_factory); | |
| 1160 config_.rtp.ssrc = ssrc; | 882 config_.rtp.ssrc = ssrc; |
| 1161 config_.rtp.c_name = c_name; | 883 config_.rtp.c_name = c_name; |
| 1162 config_.voe_channel_id = ch; | 884 config_.voe_channel_id = ch; |
| 1163 config_.rtp.extensions = extensions; | 885 config_.rtp.extensions = extensions; |
| 1164 config_.audio_network_adaptor_config = audio_network_adaptor_config; | 886 config_.audio_network_adaptor_config = audio_network_adaptor_config; |
| 887 config_.encoder_factory = encoder_factory; | |
| 1165 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc); | 888 rtp_parameters_.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc); |
| 1166 RecreateAudioSendStream(send_codec_spec); | 889 |
| 890 UpdateAllowedBitrateRange(); | |
| 891 if (send_codec_spec) { | |
| 892 UpdateSendCodecSpec(*send_codec_spec); | |
| 893 } | |
| 894 | |
| 895 CreateAudioSendStream(); | |
| 1167 } | 896 } |
| 1168 | 897 |
| 1169 ~WebRtcAudioSendStream() override { | 898 ~WebRtcAudioSendStream() override { |
| 1170 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 899 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1171 ClearSource(); | 900 ClearSource(); |
| 1172 call_->DestroyAudioSendStream(stream_); | 901 call_->DestroyAudioSendStream(stream_); |
| 1173 } | 902 } |
| 1174 | 903 |
| 1175 void RecreateAudioSendStream( | 904 void SetSendCodecSpec( |
| 1176 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { | 905 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { |
| 1177 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 906 UpdateSendCodecSpec(send_codec_spec); |
| 1178 send_codec_spec_ = send_codec_spec; | 907 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 } | 908 } |
| 1192 | 909 |
| 1193 void RecreateAudioSendStream( | 910 void SetRtpExtensions(const std::vector<webrtc::RtpExtension>& extensions) { |
| 1194 const std::vector<webrtc::RtpExtension>& extensions) { | |
| 1195 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 911 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1196 config_.rtp.extensions = extensions; | 912 config_.rtp.extensions = extensions; |
| 1197 RecreateAudioSendStream(); | 913 ReconfigureAudioSendStream(); |
| 1198 } | 914 } |
| 1199 | 915 |
| 1200 void RecreateAudioSendStream( | 916 void SetAudioNetworkAdaptorConfig( |
| 1201 const rtc::Optional<std::string>& audio_network_adaptor_config) { | 917 const rtc::Optional<std::string>& audio_network_adaptor_config) { |
| 1202 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 918 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1203 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { | 919 if (config_.audio_network_adaptor_config == audio_network_adaptor_config) { |
| 1204 return; | 920 return; |
| 1205 } | 921 } |
| 1206 config_.audio_network_adaptor_config = audio_network_adaptor_config; | 922 config_.audio_network_adaptor_config = audio_network_adaptor_config; |
| 1207 RecreateAudioSendStream(); | 923 UpdateAllowedBitrateRange(); |
| 924 ReconfigureAudioSendStream(); | |
| 1208 } | 925 } |
| 1209 | 926 |
| 1210 bool SetMaxSendBitrate(int bps) { | 927 bool SetMaxSendBitrate(int bps) { |
| 1211 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 928 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1212 auto send_rate = | 929 RTC_DCHECK(config_.send_codec_spec); |
| 1213 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps, | 930 RTC_DCHECK(audio_codec_spec_); |
| 1214 send_codec_spec_.codec_inst); | 931 auto send_rate = ComputeSendBitrate( |
| 932 bps, rtp_parameters_.encodings[0].max_bitrate_bps, *audio_codec_spec_); | |
| 933 | |
| 1215 if (!send_rate) { | 934 if (!send_rate) { |
| 1216 return false; | 935 return false; |
| 1217 } | 936 } |
| 1218 | 937 |
| 1219 max_send_bitrate_bps_ = bps; | 938 max_send_bitrate_bps_ = bps; |
| 1220 | 939 |
| 1221 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { | 940 if (send_rate != config_.send_codec_spec->target_bitrate_bps) { |
| 1222 // Recreate AudioSendStream with new bit rate. | 941 config_.send_codec_spec->target_bitrate_bps = send_rate; |
| 1223 config_.send_codec_spec.codec_inst.rate = *send_rate; | 942 ReconfigureAudioSendStream(); |
| 1224 RecreateAudioSendStream(); | |
| 1225 } | 943 } |
| 1226 return true; | 944 return true; |
| 1227 } | 945 } |
| 1228 | 946 |
| 1229 bool SendTelephoneEvent(int payload_type, int payload_freq, int event, | 947 bool SendTelephoneEvent(int payload_type, int payload_freq, int event, |
| 1230 int duration_ms) { | 948 int duration_ms) { |
| 1231 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 949 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1232 RTC_DCHECK(stream_); | 950 RTC_DCHECK(stream_); |
| 1233 return stream_->SendTelephoneEvent(payload_type, payload_freq, event, | 951 return stream_->SendTelephoneEvent(payload_type, payload_freq, event, |
| 1234 duration_ms); | 952 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"; | 1048 LOG(LS_ERROR) << "Attempted to set RtpParameters with modified SSRC"; |
| 1331 return false; | 1049 return false; |
| 1332 } | 1050 } |
| 1333 return true; | 1051 return true; |
| 1334 } | 1052 } |
| 1335 | 1053 |
| 1336 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { | 1054 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { |
| 1337 if (!ValidateRtpParameters(parameters)) { | 1055 if (!ValidateRtpParameters(parameters)) { |
| 1338 return false; | 1056 return false; |
| 1339 } | 1057 } |
| 1340 auto send_rate = ComputeSendBitrate(max_send_bitrate_bps_, | 1058 |
| 1341 parameters.encodings[0].max_bitrate_bps, | 1059 rtc::Optional<int> send_rate; |
| 1342 send_codec_spec_.codec_inst); | 1060 if (audio_codec_spec_) { |
| 1343 if (!send_rate) { | 1061 send_rate = ComputeSendBitrate(max_send_bitrate_bps_, |
| 1344 return false; | 1062 parameters.encodings[0].max_bitrate_bps, |
| 1063 *audio_codec_spec_); | |
| 1064 if (!send_rate) { | |
| 1065 return false; | |
| 1066 } | |
| 1345 } | 1067 } |
| 1346 | 1068 |
| 1347 const rtc::Optional<int> old_rtp_max_bitrate = | 1069 const rtc::Optional<int> old_rtp_max_bitrate = |
| 1348 rtp_parameters_.encodings[0].max_bitrate_bps; | 1070 rtp_parameters_.encodings[0].max_bitrate_bps; |
| 1349 | 1071 |
| 1350 rtp_parameters_ = parameters; | 1072 rtp_parameters_ = parameters; |
| 1351 | 1073 |
| 1352 if (rtp_parameters_.encodings[0].max_bitrate_bps != old_rtp_max_bitrate) { | 1074 if (rtp_parameters_.encodings[0].max_bitrate_bps != old_rtp_max_bitrate) { |
| 1353 // Recreate AudioSendStream with new bit rate. | 1075 // Reconfigure AudioSendStream with new bit rate. |
| 1354 config_.send_codec_spec.codec_inst.rate = *send_rate; | 1076 if (send_rate) { |
| 1355 RecreateAudioSendStream(); | 1077 config_.send_codec_spec->target_bitrate_bps = send_rate; |
| 1078 } | |
| 1079 UpdateAllowedBitrateRange(); | |
| 1080 ReconfigureAudioSendStream(); | |
| 1356 } else { | 1081 } else { |
| 1357 // parameters.encodings[0].active could have changed. | 1082 // parameters.encodings[0].active could have changed. |
| 1358 UpdateSendState(); | 1083 UpdateSendState(); |
| 1359 } | 1084 } |
| 1360 return true; | 1085 return true; |
| 1361 } | 1086 } |
| 1362 | 1087 |
| 1363 private: | 1088 private: |
| 1364 void UpdateSendState() { | 1089 void UpdateSendState() { |
| 1365 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1090 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1366 RTC_DCHECK(stream_); | 1091 RTC_DCHECK(stream_); |
| 1367 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); | 1092 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); |
| 1368 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { | 1093 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { |
| 1369 stream_->Start(); | 1094 stream_->Start(); |
| 1370 } else { // !send || source_ = nullptr | 1095 } else { // !send || source_ = nullptr |
| 1371 stream_->Stop(); | 1096 stream_->Stop(); |
| 1372 } | 1097 } |
| 1373 } | 1098 } |
| 1374 | 1099 |
| 1375 void RecreateAudioSendStream() { | 1100 void UpdateAllowedBitrateRange() { |
| 1376 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1101 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")) { | 1102 if (webrtc::field_trial::IsEnabled("WebRTC-Audio-SendSideBwe")) { |
| 1383 config_.min_bitrate_bps = kOpusMinBitrateBps; | 1103 config_.min_bitrate_bps = kOpusMinBitrateBps; |
| 1384 | 1104 |
| 1385 // This means that when RtpParameters is reset, we may change the | 1105 // This means that when RtpParameters is reset, we may change the |
| 1386 // encoder's bit rate immediately (through call_->CreateAudioSendStream), | 1106 // encoder's bit rate immediately (through call_->CreateAudioSendStream), |
| 1387 // meanwhile change the cap to the output of BWE. | 1107 // meanwhile change the cap to the output of BWE. |
| 1388 config_.max_bitrate_bps = | 1108 config_.max_bitrate_bps = |
| 1389 rtp_parameters_.encodings[0].max_bitrate_bps | 1109 rtp_parameters_.encodings[0].max_bitrate_bps |
| 1390 ? *rtp_parameters_.encodings[0].max_bitrate_bps | 1110 ? *rtp_parameters_.encodings[0].max_bitrate_bps |
| 1391 : kOpusBitrateFbBps; | 1111 : kOpusBitrateFbBps; |
| 1392 | 1112 |
| 1393 // TODO(mflodman): Keep testing this and set proper values. | 1113 // TODO(mflodman): Keep testing this and set proper values. |
| 1394 // Note: This is an early experiment currently only supported by Opus. | 1114 // Note: This is an early experiment currently only supported by Opus. |
| 1395 if (send_side_bwe_with_overhead_) { | 1115 if (send_side_bwe_with_overhead_) { |
| 1396 auto packet_sizes_ms = WebRtcVoiceCodecs::GetPacketSizesMs( | 1116 const bool is_opus_with_ana = |
| 1397 config_.send_codec_spec.codec_inst); | 1117 config_.audio_network_adaptor_config && |
| 1398 if (!packet_sizes_ms.empty()) { | 1118 !STR_CASE_CMP(config_.send_codec_spec->format.name.c_str(), |
| 1399 int max_packet_size_ms = | 1119 kOpusCodecName); |
| 1400 *std::max_element(packet_sizes_ms.begin(), packet_sizes_ms.end()); | 1120 const int max_packet_size_ms = |
| 1121 (is_opus_with_ana && WEBRTC_OPUS_SUPPORT_120MS_PTIME) ? 120 : 60; | |
| 1401 | 1122 |
| 1402 // Audio network adaptor will just use 20ms and 60ms frame lengths. | 1123 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12) |
| 1403 // The adaptor will only be active for the Opus encoder. | 1124 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 | 1125 |
| 1413 // OverheadPerPacket = Ipv4(20B) + UDP(8B) + SRTP(10B) + RTP(12) | 1126 int min_overhead_bps = |
| 1414 constexpr int kOverheadPerPacket = 20 + 8 + 10 + 12; | 1127 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms; |
| 1415 | |
| 1416 int min_overhead_bps = | |
| 1417 kOverheadPerPacket * 8 * 1000 / max_packet_size_ms; | |
| 1418 | 1128 |
| 1419 // We assume that |config_.max_bitrate_bps| before the next line is | 1129 // We assume that |config_.max_bitrate_bps| before the next line is |
| 1420 // a hard limit on the payload bitrate, so we add min_overhead_bps to | 1130 // a hard limit on the payload bitrate, so we add min_overhead_bps to |
| 1421 // it to ensure that, when overhead is deducted, the payload rate | 1131 // it to ensure that, when overhead is deducted, the payload rate |
| 1422 // never goes beyond the limit. | 1132 // never goes beyond the limit. |
| 1423 // Note: this also means that if a higher overhead is forced, we | 1133 // Note: this also means that if a higher overhead is forced, we |
| 1424 // cannot reach the limit. | 1134 // cannot reach the limit. |
| 1425 // TODO(minyue): Reconsider this when the signaling to BWE is done | 1135 // TODO(minyue): Reconsider this when the signaling to BWE is done |
| 1426 // through a dedicated API. | 1136 // through a dedicated API. |
| 1427 config_.max_bitrate_bps += min_overhead_bps; | 1137 config_.max_bitrate_bps += min_overhead_bps; |
| 1428 | 1138 |
| 1429 // In contrast to max_bitrate_bps, we let min_bitrate_bps always be | 1139 // In contrast to max_bitrate_bps, we let min_bitrate_bps always be |
| 1430 // reachable. | 1140 // reachable. |
| 1431 config_.min_bitrate_bps += min_overhead_bps; | 1141 config_.min_bitrate_bps += min_overhead_bps; |
| 1432 } | |
| 1433 } | 1142 } |
| 1434 } | 1143 } |
| 1144 } | |
| 1145 | |
| 1146 void UpdateSendCodecSpec( | |
| 1147 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { | |
| 1148 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
| 1149 config_.rtp.nack.rtp_history_ms = | |
| 1150 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; | |
| 1151 config_.send_codec_spec = | |
| 1152 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>( | |
| 1153 send_codec_spec); | |
| 1154 auto info = | |
| 1155 config_.encoder_factory->QueryAudioEncoder(send_codec_spec.format); | |
| 1156 RTC_DCHECK(info); | |
| 1157 // If a specific target bitrate has been set for the stream, use that as | |
| 1158 // the new default bitrate when computing send bitrate. | |
| 1159 if (send_codec_spec.target_bitrate_bps) { | |
| 1160 info->default_bitrate_bps = std::max( | |
| 1161 info->min_bitrate_bps, | |
| 1162 std::min(info->max_bitrate_bps, *send_codec_spec.target_bitrate_bps)); | |
| 1163 } | |
| 1164 | |
| 1165 audio_codec_spec_.emplace( | |
| 1166 webrtc::AudioCodecSpec{send_codec_spec.format, *info}); | |
| 1167 | |
| 1168 config_.send_codec_spec->target_bitrate_bps = ComputeSendBitrate( | |
| 1169 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, | |
| 1170 *audio_codec_spec_); | |
| 1171 } | |
| 1172 | |
| 1173 void CreateAudioSendStream() { | |
| 1174 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
| 1175 RTC_DCHECK(!stream_); | |
| 1435 stream_ = call_->CreateAudioSendStream(config_); | 1176 stream_ = call_->CreateAudioSendStream(config_); |
| 1436 RTC_CHECK(stream_); | 1177 RTC_CHECK(stream_); |
| 1178 } | |
| 1179 | |
| 1180 void ReconfigureAudioSendStream() { | |
| 1181 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
| 1182 RTC_DCHECK(stream_); | |
| 1183 stream_->Reconfigure(config_); | |
| 1437 UpdateSendState(); | 1184 UpdateSendState(); |
| 1438 } | 1185 } |
| 1439 | 1186 |
| 1440 rtc::ThreadChecker worker_thread_checker_; | 1187 rtc::ThreadChecker worker_thread_checker_; |
| 1441 rtc::RaceChecker audio_capture_race_checker_; | 1188 rtc::RaceChecker audio_capture_race_checker_; |
| 1442 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; | 1189 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; |
| 1443 webrtc::Call* call_ = nullptr; | 1190 webrtc::Call* call_ = nullptr; |
| 1444 webrtc::AudioSendStream::Config config_; | 1191 webrtc::AudioSendStream::Config config_; |
| 1445 const bool send_side_bwe_with_overhead_; | 1192 const bool send_side_bwe_with_overhead_; |
| 1446 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 1193 // The stream is owned by WebRtcAudioSendStream and may be reallocated if |
| 1447 // configuration changes. | 1194 // configuration changes. |
| 1448 webrtc::AudioSendStream* stream_ = nullptr; | 1195 webrtc::AudioSendStream* stream_ = nullptr; |
| 1449 | 1196 |
| 1450 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. | 1197 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. |
| 1451 // PeerConnection will make sure invalidating the pointer before the object | 1198 // PeerConnection will make sure invalidating the pointer before the object |
| 1452 // goes away. | 1199 // goes away. |
| 1453 AudioSource* source_ = nullptr; | 1200 AudioSource* source_ = nullptr; |
| 1454 bool send_ = false; | 1201 bool send_ = false; |
| 1455 bool muted_ = false; | 1202 bool muted_ = false; |
| 1456 int max_send_bitrate_bps_; | 1203 int max_send_bitrate_bps_; |
| 1457 webrtc::RtpParameters rtp_parameters_; | 1204 webrtc::RtpParameters rtp_parameters_; |
| 1458 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec_; | 1205 rtc::Optional<webrtc::AudioCodecSpec> audio_codec_spec_; |
| 1459 | 1206 |
| 1460 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1207 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); |
| 1461 }; | 1208 }; |
| 1462 | 1209 |
| 1463 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1210 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { |
| 1464 public: | 1211 public: |
| 1465 WebRtcAudioReceiveStream( | 1212 WebRtcAudioReceiveStream( |
| 1466 int ch, | 1213 int ch, |
| 1467 uint32_t remote_ssrc, | 1214 uint32_t remote_ssrc, |
| 1468 uint32_t local_ssrc, | 1215 uint32_t local_ssrc, |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1648 | 1395 |
| 1649 if (!ValidateRtpExtensions(params.extensions)) { | 1396 if (!ValidateRtpExtensions(params.extensions)) { |
| 1650 return false; | 1397 return false; |
| 1651 } | 1398 } |
| 1652 std::vector<webrtc::RtpExtension> filtered_extensions = | 1399 std::vector<webrtc::RtpExtension> filtered_extensions = |
| 1653 FilterRtpExtensions(params.extensions, | 1400 FilterRtpExtensions(params.extensions, |
| 1654 webrtc::RtpExtension::IsSupportedForAudio, true); | 1401 webrtc::RtpExtension::IsSupportedForAudio, true); |
| 1655 if (send_rtp_extensions_ != filtered_extensions) { | 1402 if (send_rtp_extensions_ != filtered_extensions) { |
| 1656 send_rtp_extensions_.swap(filtered_extensions); | 1403 send_rtp_extensions_.swap(filtered_extensions); |
| 1657 for (auto& it : send_streams_) { | 1404 for (auto& it : send_streams_) { |
| 1658 it.second->RecreateAudioSendStream(send_rtp_extensions_); | 1405 it.second->SetRtpExtensions(send_rtp_extensions_); |
| 1659 } | 1406 } |
| 1660 } | 1407 } |
| 1661 | 1408 |
| 1662 if (!SetMaxSendBitrate(params.max_bandwidth_bps)) { | 1409 if (!SetMaxSendBitrate(params.max_bandwidth_bps)) { |
| 1663 return false; | 1410 return false; |
| 1664 } | 1411 } |
| 1665 return SetOptions(params.options); | 1412 return SetOptions(params.options); |
| 1666 } | 1413 } |
| 1667 | 1414 |
| 1668 bool WebRtcVoiceMediaChannel::SetRecvParameters( | 1415 bool WebRtcVoiceMediaChannel::SetRecvParameters( |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1793 // We retain all of the existing options, and apply the given ones | 1540 // We retain all of the existing options, and apply the given ones |
| 1794 // on top. This means there is no way to "clear" options such that | 1541 // on top. This means there is no way to "clear" options such that |
| 1795 // they go back to the engine default. | 1542 // they go back to the engine default. |
| 1796 options_.SetAll(options); | 1543 options_.SetAll(options); |
| 1797 if (!engine()->ApplyOptions(options_)) { | 1544 if (!engine()->ApplyOptions(options_)) { |
| 1798 LOG(LS_WARNING) << | 1545 LOG(LS_WARNING) << |
| 1799 "Failed to apply engine options during channel SetOptions."; | 1546 "Failed to apply engine options during channel SetOptions."; |
| 1800 return false; | 1547 return false; |
| 1801 } | 1548 } |
| 1802 | 1549 |
| 1803 rtc::Optional<std::string> audio_network_adatptor_config = | 1550 rtc::Optional<std::string> audio_network_adaptor_config = |
| 1804 GetAudioNetworkAdaptorConfig(options_); | 1551 GetAudioNetworkAdaptorConfig(options_); |
| 1805 for (auto& it : send_streams_) { | 1552 for (auto& it : send_streams_) { |
| 1806 it.second->RecreateAudioSendStream(audio_network_adatptor_config); | 1553 it.second->SetAudioNetworkAdaptorConfig(audio_network_adaptor_config); |
| 1807 } | 1554 } |
| 1808 | 1555 |
| 1809 LOG(LS_INFO) << "Set voice channel options. Current options: " | 1556 LOG(LS_INFO) << "Set voice channel options. Current options: " |
| 1810 << options_.ToString(); | 1557 << options_.ToString(); |
| 1811 return true; | 1558 return true; |
| 1812 } | 1559 } |
| 1813 | 1560 |
| 1814 bool WebRtcVoiceMediaChannel::SetRecvCodecs( | 1561 bool WebRtcVoiceMediaChannel::SetRecvCodecs( |
| 1815 const std::vector<AudioCodec>& codecs) { | 1562 const std::vector<AudioCodec>& codecs) { |
| 1816 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1563 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1906 for (const AudioCodec& codec : codecs) { | 1653 for (const AudioCodec& codec : codecs) { |
| 1907 if (IsCodec(codec, kDtmfCodecName)) { | 1654 if (IsCodec(codec, kDtmfCodecName)) { |
| 1908 dtmf_codecs.push_back(codec); | 1655 dtmf_codecs.push_back(codec); |
| 1909 if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) { | 1656 if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) { |
| 1910 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 1657 dtmf_payload_type_ = rtc::Optional<int>(codec.id); |
| 1911 dtmf_payload_freq_ = codec.clockrate; | 1658 dtmf_payload_freq_ = codec.clockrate; |
| 1912 } | 1659 } |
| 1913 } | 1660 } |
| 1914 } | 1661 } |
| 1915 | 1662 |
| 1916 // Scan through the list to figure out the codec to use for sending, along | 1663 // Scan through the list to figure out the codec to use for sending. |
| 1917 // with the proper configuration for VAD, CNG, NACK and Opus-specific | 1664 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec> send_codec_spec; |
| 1918 // parameters. | |
| 1919 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. | |
| 1920 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec; | |
| 1921 webrtc::Call::Config::BitrateConfig bitrate_config; | 1665 webrtc::Call::Config::BitrateConfig bitrate_config; |
| 1922 { | 1666 rtc::Optional<webrtc::AudioCodecInfo> voice_codec_info; |
| 1923 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 1667 for (const AudioCodec& voice_codec : codecs) { |
| 1668 if (!(IsCodec(voice_codec, kCnCodecName) || | |
| 1669 IsCodec(voice_codec, kDtmfCodecName) || | |
| 1670 IsCodec(voice_codec, kRedCodecName))) { | |
| 1671 webrtc::SdpAudioFormat format(voice_codec.name, voice_codec.clockrate, | |
| 1672 voice_codec.channels, voice_codec.params); | |
| 1924 | 1673 |
| 1925 // Find send codec (the first non-telephone-event/CN codec). | 1674 voice_codec_info = engine()->encoder_factory_->QueryAudioEncoder(format); |
| 1926 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 1675 if (!voice_codec_info) { |
| 1927 codecs, &send_codec_spec.codec_inst); | 1676 LOG(LS_WARNING) << "Unknown codec " << ToString(voice_codec); |
| 1928 if (!codec) { | 1677 continue; |
| 1929 LOG(LS_WARNING) << "Received empty list of codecs."; | 1678 } |
| 1930 return false; | 1679 |
| 1680 send_codec_spec = | |
| 1681 rtc::Optional<webrtc::AudioSendStream::Config::SendCodecSpec>( | |
| 1682 {voice_codec.id, format}); | |
| 1683 if (voice_codec.bitrate > 0) { | |
| 1684 send_codec_spec->target_bitrate_bps = | |
| 1685 rtc::Optional<int>(voice_codec.bitrate); | |
| 1686 } | |
| 1687 send_codec_spec->transport_cc_enabled = HasTransportCc(voice_codec); | |
| 1688 send_codec_spec->nack_enabled = HasNack(voice_codec); | |
| 1689 bitrate_config = GetBitrateConfigForCodec(voice_codec); | |
| 1690 break; | |
| 1931 } | 1691 } |
| 1692 } | |
| 1932 | 1693 |
| 1933 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec); | 1694 if (!send_codec_spec) |
| 1934 send_codec_spec.nack_enabled = HasNack(*codec); | 1695 return false; |
| 1935 bitrate_config = GetBitrateConfigForCodec(*codec); | |
| 1936 | 1696 |
| 1937 // For Opus as the send codec, we are to determine inband FEC, maximum | 1697 RTC_DCHECK(voice_codec_info); |
| 1938 // playback rate, and opus internal dtx. | 1698 if (voice_codec_info->allow_comfort_noise) { |
| 1939 if (IsCodec(*codec, kOpusCodecName)) { | |
| 1940 GetOpusConfig(*codec, &send_codec_spec.codec_inst, | |
| 1941 &send_codec_spec.enable_codec_fec, | |
| 1942 &send_codec_spec.opus_max_playback_rate, | |
| 1943 &send_codec_spec.enable_opus_dtx, | |
| 1944 &send_codec_spec.min_ptime_ms, | |
| 1945 &send_codec_spec.max_ptime_ms); | |
| 1946 } | |
| 1947 | |
| 1948 // Set packet size if the AudioCodec param kCodecParamPTime is set. | |
| 1949 int ptime_ms = 0; | |
| 1950 if (codec->GetParam(kCodecParamPTime, &ptime_ms)) { | |
| 1951 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize( | |
| 1952 &send_codec_spec.codec_inst, ptime_ms)) { | |
| 1953 LOG(LS_WARNING) << "Failed to set packet size for codec " | |
| 1954 << send_codec_spec.codec_inst.plname; | |
| 1955 return false; | |
| 1956 } | |
| 1957 } | |
| 1958 | |
| 1959 // Loop through the codecs list again to find the CN codec. | 1699 // Loop through the codecs list again to find the CN codec. |
| 1960 // TODO(solenberg): Break out into a separate function? | 1700 // TODO(solenberg): Break out into a separate function? |
| 1961 for (const AudioCodec& cn_codec : codecs) { | 1701 for (const AudioCodec& cn_codec : codecs) { |
| 1962 // Ignore codecs we don't know about. The negotiation step should prevent | |
| 1963 // this, but double-check to be sure. | |
| 1964 webrtc::CodecInst voe_codec = {0}; | |
| 1965 if (!WebRtcVoiceEngine::ToCodecInst(cn_codec, &voe_codec)) { | |
| 1966 LOG(LS_WARNING) << "Unknown codec " << ToString(cn_codec); | |
| 1967 continue; | |
| 1968 } | |
| 1969 | |
| 1970 if (IsCodec(cn_codec, kCnCodecName) && | 1702 if (IsCodec(cn_codec, kCnCodecName) && |
| 1971 cn_codec.clockrate == codec->clockrate) { | 1703 cn_codec.clockrate == send_codec_spec->format.clockrate_hz) { |
| 1972 // Turn voice activity detection/comfort noise on if supported. | |
| 1973 // Set the wideband CN payload type appropriately. | |
| 1974 // (narrowband always uses the static payload type 13). | |
| 1975 int cng_plfreq = -1; | |
| 1976 switch (cn_codec.clockrate) { | 1704 switch (cn_codec.clockrate) { |
| 1977 case 8000: | 1705 case 8000: |
| 1978 case 16000: | 1706 case 16000: |
| 1979 case 32000: | 1707 case 32000: |
| 1980 cng_plfreq = cn_codec.clockrate; | 1708 send_codec_spec->cng_payload_type = rtc::Optional<int>(cn_codec.id); |
| 1981 break; | 1709 break; |
| 1982 default: | 1710 default: |
| 1983 LOG(LS_WARNING) << "CN frequency " << cn_codec.clockrate | 1711 LOG(LS_WARNING) << "CN frequency " << cn_codec.clockrate |
| 1984 << " not supported."; | 1712 << " not supported."; |
| 1985 continue; | 1713 break; |
| 1986 } | 1714 } |
| 1987 send_codec_spec.cng_payload_type = cn_codec.id; | |
| 1988 send_codec_spec.cng_plfreq = cng_plfreq; | |
| 1989 break; | 1715 break; |
| 1990 } | 1716 } |
| 1991 } | 1717 } |
| 1992 | 1718 |
| 1993 // Find the telephone-event PT exactly matching the preferred send codec. | 1719 // Find the telephone-event PT exactly matching the preferred send codec. |
| 1994 for (const AudioCodec& dtmf_codec : dtmf_codecs) { | 1720 for (const AudioCodec& dtmf_codec : dtmf_codecs) { |
| 1995 if (dtmf_codec.clockrate == codec->clockrate) { | 1721 if (dtmf_codec.clockrate == send_codec_spec->format.clockrate_hz) { |
| 1996 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id); | 1722 dtmf_payload_type_ = rtc::Optional<int>(dtmf_codec.id); |
| 1997 dtmf_payload_freq_ = dtmf_codec.clockrate; | 1723 dtmf_payload_freq_ = dtmf_codec.clockrate; |
| 1998 break; | 1724 break; |
| 1999 } | 1725 } |
| 2000 } | 1726 } |
| 2001 } | 1727 } |
| 2002 | 1728 |
| 2003 if (send_codec_spec_ != send_codec_spec) { | 1729 if (send_codec_spec_ != send_codec_spec) { |
| 2004 send_codec_spec_ = std::move(send_codec_spec); | 1730 send_codec_spec_ = std::move(send_codec_spec); |
| 2005 // Apply new settings to all streams. | 1731 // Apply new settings to all streams. |
| 2006 for (const auto& kv : send_streams_) { | 1732 for (const auto& kv : send_streams_) { |
| 2007 kv.second->RecreateAudioSendStream(send_codec_spec_); | 1733 kv.second->SetSendCodecSpec(*send_codec_spec_); |
| 2008 } | 1734 } |
| 2009 } else { | 1735 } else { |
| 2010 // If the codec isn't changing, set the start bitrate to -1 which means | 1736 // If the codec isn't changing, set the start bitrate to -1 which means |
| 2011 // "unchanged" so that BWE isn't affected. | 1737 // "unchanged" so that BWE isn't affected. |
| 2012 bitrate_config.start_bitrate_bps = -1; | 1738 bitrate_config.start_bitrate_bps = -1; |
| 2013 } | 1739 } |
| 2014 call_->SetBitrateConfig(bitrate_config); | 1740 call_->SetBitrateConfig(bitrate_config); |
| 2015 | 1741 |
| 2016 // Check if the transport cc feedback or NACK status has changed on the | 1742 // Check if the transport cc feedback or NACK status has changed on the |
| 2017 // preferred send codec, and in that case reconfigure all receive streams. | 1743 // preferred send codec, and in that case reconfigure all receive streams. |
| 2018 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || | 1744 if (recv_transport_cc_enabled_ != send_codec_spec_->transport_cc_enabled || |
| 2019 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { | 1745 recv_nack_enabled_ != send_codec_spec_->nack_enabled) { |
| 2020 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1746 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
| 2021 "codec has changed."; | 1747 "codec has changed."; |
| 2022 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1748 recv_transport_cc_enabled_ = send_codec_spec_->transport_cc_enabled; |
| 2023 recv_nack_enabled_ = send_codec_spec_.nack_enabled; | 1749 recv_nack_enabled_ = send_codec_spec_->nack_enabled; |
| 2024 for (auto& kv : recv_streams_) { | 1750 for (auto& kv : recv_streams_) { |
| 2025 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, | 1751 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, |
| 2026 recv_nack_enabled_); | 1752 recv_nack_enabled_); |
| 2027 } | 1753 } |
| 2028 } | 1754 } |
| 2029 | 1755 |
| 2030 send_codecs_ = codecs; | 1756 send_codecs_ = codecs; |
| 2031 return true; | 1757 return true; |
| 2032 } | 1758 } |
| 2033 | 1759 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2136 // Save the channel to send_streams_, so that RemoveSendStream() can still | 1862 // Save the channel to send_streams_, so that RemoveSendStream() can still |
| 2137 // delete the channel in case failure happens below. | 1863 // delete the channel in case failure happens below. |
| 2138 webrtc::AudioTransport* audio_transport = | 1864 webrtc::AudioTransport* audio_transport = |
| 2139 engine()->voe()->base()->audio_transport(); | 1865 engine()->voe()->base()->audio_transport(); |
| 2140 | 1866 |
| 2141 rtc::Optional<std::string> audio_network_adaptor_config = | 1867 rtc::Optional<std::string> audio_network_adaptor_config = |
| 2142 GetAudioNetworkAdaptorConfig(options_); | 1868 GetAudioNetworkAdaptorConfig(options_); |
| 2143 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 1869 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( |
| 2144 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, | 1870 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, |
| 2145 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, | 1871 send_rtp_extensions_, max_send_bitrate_bps_, audio_network_adaptor_config, |
| 2146 call_, this); | 1872 call_, this, engine()->encoder_factory_); |
| 2147 send_streams_.insert(std::make_pair(ssrc, stream)); | 1873 send_streams_.insert(std::make_pair(ssrc, stream)); |
| 2148 | 1874 |
| 2149 // At this point the stream's local SSRC has been updated. If it is the first | 1875 // At this point the stream's local SSRC has been updated. If it is the first |
| 2150 // send stream, make sure that all the receive streams are updated with the | 1876 // send stream, make sure that all the receive streams are updated with the |
| 2151 // same SSRC in order to send receiver reports. | 1877 // same SSRC in order to send receiver reports. |
| 2152 if (send_streams_.size() == 1) { | 1878 if (send_streams_.size() == 1) { |
| 2153 receiver_reports_ssrc_ = ssrc; | 1879 receiver_reports_ssrc_ = ssrc; |
| 2154 for (const auto& kv : recv_streams_) { | 1880 for (const auto& kv : recv_streams_) { |
| 2155 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive | 1881 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive |
| 2156 // streams instead, so we can avoid recreating the streams here. | 1882 // streams instead, so we can avoid recreating the streams here. |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2626 ssrc); | 2352 ssrc); |
| 2627 if (it != unsignaled_recv_ssrcs_.end()) { | 2353 if (it != unsignaled_recv_ssrcs_.end()) { |
| 2628 unsignaled_recv_ssrcs_.erase(it); | 2354 unsignaled_recv_ssrcs_.erase(it); |
| 2629 return true; | 2355 return true; |
| 2630 } | 2356 } |
| 2631 return false; | 2357 return false; |
| 2632 } | 2358 } |
| 2633 } // namespace cricket | 2359 } // namespace cricket |
| 2634 | 2360 |
| 2635 #endif // HAVE_WEBRTC_VOICE | 2361 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |