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