| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 |
| 11 #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" | 11 #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <iterator> | 14 #include <iterator> |
| 15 #include <utility> | 15 #include <utility> |
| 16 | 16 |
| 17 #include "webrtc/base/arraysize.h" | 17 #include "webrtc/base/arraysize.h" |
| 18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
| 20 #include "webrtc/base/numerics/exp_filter.h" | 20 #include "webrtc/base/numerics/exp_filter.h" |
| 21 #include "webrtc/base/protobuf_utils.h" | 21 #include "webrtc/base/protobuf_utils.h" |
| 22 #include "webrtc/base/ptr_util.h" |
| 22 #include "webrtc/base/safe_conversions.h" | 23 #include "webrtc/base/safe_conversions.h" |
| 23 #include "webrtc/base/safe_minmax.h" | 24 #include "webrtc/base/safe_minmax.h" |
| 24 #include "webrtc/base/string_to_number.h" | 25 #include "webrtc/base/string_to_number.h" |
| 25 #include "webrtc/base/timeutils.h" | 26 #include "webrtc/base/timeutils.h" |
| 26 #include "webrtc/common_types.h" | 27 #include "webrtc/common_types.h" |
| 27 #include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adapto
r_impl.h" | 28 #include "webrtc/modules/audio_coding/audio_network_adaptor/audio_network_adapto
r_impl.h" |
| 28 #include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h
" | 29 #include "webrtc/modules/audio_coding/audio_network_adaptor/controller_manager.h
" |
| 29 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" | 30 #include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h" |
| 30 #include "webrtc/system_wrappers/include/field_trial.h" | 31 #include "webrtc/system_wrappers/include/field_trial.h" |
| 31 | 32 |
| 32 namespace webrtc { | 33 namespace webrtc { |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 36 // Codec parameters for Opus. | 37 // Codec parameters for Opus. |
| 37 // draft-spittka-payload-rtp-opus-03 | 38 // draft-spittka-payload-rtp-opus-03 |
| 38 | 39 |
| 39 // Recommended bitrates: | 40 // Recommended bitrates: |
| 40 // 8-12 kb/s for NB speech, | 41 // 8-12 kb/s for NB speech, |
| 41 // 16-20 kb/s for WB speech, | 42 // 16-20 kb/s for WB speech, |
| 42 // 28-40 kb/s for FB speech, | 43 // 28-40 kb/s for FB speech, |
| 43 // 48-64 kb/s for FB mono music, and | 44 // 48-64 kb/s for FB mono music, and |
| 44 // 64-128 kb/s for FB stereo music. | 45 // 64-128 kb/s for FB stereo music. |
| 45 // The current implementation applies the following values to mono signals, | 46 // The current implementation applies the following values to mono signals, |
| 46 // and multiplies them by 2 for stereo. | 47 // and multiplies them by 2 for stereo. |
| 47 constexpr int kOpusBitrateNbBps = 12000; | 48 constexpr int kOpusBitrateNbBps = 12000; |
| 48 constexpr int kOpusBitrateWbBps = 20000; | 49 constexpr int kOpusBitrateWbBps = 20000; |
| 49 constexpr int kOpusBitrateFbBps = 32000; | 50 constexpr int kOpusBitrateFbBps = 32000; |
| 50 | 51 |
| 51 // Opus API allows a min bitrate of 500bps, but Opus documentation suggests | |
| 52 // bitrate should be in the range of 6000 to 510000, inclusive. | |
| 53 constexpr int kOpusMinBitrateBps = 6000; | |
| 54 constexpr int kOpusMaxBitrateBps = 510000; | |
| 55 | |
| 56 constexpr int kSampleRateHz = 48000; | 52 constexpr int kSampleRateHz = 48000; |
| 57 constexpr int kDefaultMaxPlaybackRate = 48000; | 53 constexpr int kDefaultMaxPlaybackRate = 48000; |
| 58 | 54 |
| 59 // These two lists must be sorted from low to high | 55 // These two lists must be sorted from low to high |
| 60 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME | 56 #if WEBRTC_OPUS_SUPPORT_120MS_PTIME |
| 61 constexpr int kANASupportedFrameLengths[] = {20, 60, 120}; | 57 constexpr int kANASupportedFrameLengths[] = {20, 60, 120}; |
| 62 constexpr int kOpusSupportedFrameLengths[] = {10, 20, 40, 60, 120}; | 58 constexpr int kOpusSupportedFrameLengths[] = {10, 20, 40, 60, 120}; |
| 63 #else | 59 #else |
| 64 constexpr int kANASupportedFrameLengths[] = {20, 60}; | 60 constexpr int kANASupportedFrameLengths[] = {20, 60}; |
| 65 constexpr int kOpusSupportedFrameLengths[] = {10, 20, 40, 60}; | 61 constexpr int kOpusSupportedFrameLengths[] = {10, 20, 40, 60}; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 int CalculateDefaultBitrate(int max_playback_rate, size_t num_channels) { | 122 int CalculateDefaultBitrate(int max_playback_rate, size_t num_channels) { |
| 127 const int bitrate = [&] { | 123 const int bitrate = [&] { |
| 128 if (max_playback_rate <= 8000) { | 124 if (max_playback_rate <= 8000) { |
| 129 return kOpusBitrateNbBps * rtc::dchecked_cast<int>(num_channels); | 125 return kOpusBitrateNbBps * rtc::dchecked_cast<int>(num_channels); |
| 130 } else if (max_playback_rate <= 16000) { | 126 } else if (max_playback_rate <= 16000) { |
| 131 return kOpusBitrateWbBps * rtc::dchecked_cast<int>(num_channels); | 127 return kOpusBitrateWbBps * rtc::dchecked_cast<int>(num_channels); |
| 132 } else { | 128 } else { |
| 133 return kOpusBitrateFbBps * rtc::dchecked_cast<int>(num_channels); | 129 return kOpusBitrateFbBps * rtc::dchecked_cast<int>(num_channels); |
| 134 } | 130 } |
| 135 }(); | 131 }(); |
| 136 RTC_DCHECK_GE(bitrate, kOpusMinBitrateBps); | 132 RTC_DCHECK_GE(bitrate, AudioEncoderOpusConfig::kMinBitrateBps); |
| 137 RTC_DCHECK_LE(bitrate, kOpusMaxBitrateBps); | 133 RTC_DCHECK_LE(bitrate, AudioEncoderOpusConfig::kMaxBitrateBps); |
| 138 return bitrate; | 134 return bitrate; |
| 139 } | 135 } |
| 140 | 136 |
| 141 // Get the maxaveragebitrate parameter in string-form, so we can properly figure | 137 // Get the maxaveragebitrate parameter in string-form, so we can properly figure |
| 142 // out how invalid it is and accurately log invalid values. | 138 // out how invalid it is and accurately log invalid values. |
| 143 int CalculateBitrate(int max_playback_rate_hz, | 139 int CalculateBitrate(int max_playback_rate_hz, |
| 144 size_t num_channels, | 140 size_t num_channels, |
| 145 rtc::Optional<std::string> bitrate_param) { | 141 rtc::Optional<std::string> bitrate_param) { |
| 146 const int default_bitrate = | 142 const int default_bitrate = |
| 147 CalculateDefaultBitrate(max_playback_rate_hz, num_channels); | 143 CalculateDefaultBitrate(max_playback_rate_hz, num_channels); |
| 148 | 144 |
| 149 if (bitrate_param) { | 145 if (bitrate_param) { |
| 150 const auto bitrate = rtc::StringToNumber<int>(*bitrate_param); | 146 const auto bitrate = rtc::StringToNumber<int>(*bitrate_param); |
| 151 if (bitrate) { | 147 if (bitrate) { |
| 152 const int chosen_bitrate = | 148 const int chosen_bitrate = |
| 153 std::max(kOpusMinBitrateBps, std::min(*bitrate, kOpusMaxBitrateBps)); | 149 std::max(AudioEncoderOpusConfig::kMinBitrateBps, |
| 150 std::min(*bitrate, AudioEncoderOpusConfig::kMaxBitrateBps)); |
| 154 if (bitrate != chosen_bitrate) { | 151 if (bitrate != chosen_bitrate) { |
| 155 LOG(LS_WARNING) << "Invalid maxaveragebitrate " << *bitrate | 152 LOG(LS_WARNING) << "Invalid maxaveragebitrate " << *bitrate |
| 156 << " clamped to " << chosen_bitrate; | 153 << " clamped to " << chosen_bitrate; |
| 157 } | 154 } |
| 158 return chosen_bitrate; | 155 return chosen_bitrate; |
| 159 } | 156 } |
| 160 LOG(LS_WARNING) << "Invalid maxaveragebitrate \"" << *bitrate_param | 157 LOG(LS_WARNING) << "Invalid maxaveragebitrate \"" << *bitrate_param |
| 161 << "\" replaced by default bitrate " << default_bitrate; | 158 << "\" replaced by default bitrate " << default_bitrate; |
| 162 } | 159 } |
| 163 | 160 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 188 // kOpusSupportedFrameLengths. | 185 // kOpusSupportedFrameLengths. |
| 189 for (const int supported_frame_length : kOpusSupportedFrameLengths) { | 186 for (const int supported_frame_length : kOpusSupportedFrameLengths) { |
| 190 if (supported_frame_length >= *ptime) { | 187 if (supported_frame_length >= *ptime) { |
| 191 return supported_frame_length; | 188 return supported_frame_length; |
| 192 } | 189 } |
| 193 } | 190 } |
| 194 // If none was found, return the largest supported frame length. | 191 // If none was found, return the largest supported frame length. |
| 195 return *(std::end(kOpusSupportedFrameLengths) - 1); | 192 return *(std::end(kOpusSupportedFrameLengths) - 1); |
| 196 } | 193 } |
| 197 | 194 |
| 198 return AudioEncoderOpus::Config::kDefaultFrameSizeMs; | 195 return AudioEncoderOpusConfig::kDefaultFrameSizeMs; |
| 199 } | 196 } |
| 200 | 197 |
| 201 void FindSupportedFrameLengths(int min_frame_length_ms, | 198 void FindSupportedFrameLengths(int min_frame_length_ms, |
| 202 int max_frame_length_ms, | 199 int max_frame_length_ms, |
| 203 std::vector<int>* out) { | 200 std::vector<int>* out) { |
| 204 out->clear(); | 201 out->clear(); |
| 205 std::copy_if(std::begin(kANASupportedFrameLengths), | 202 std::copy_if(std::begin(kANASupportedFrameLengths), |
| 206 std::end(kANASupportedFrameLengths), std::back_inserter(*out), | 203 std::end(kANASupportedFrameLengths), std::back_inserter(*out), |
| 207 [&](int frame_length_ms) { | 204 [&](int frame_length_ms) { |
| 208 return frame_length_ms >= min_frame_length_ms && | 205 return frame_length_ms >= min_frame_length_ms && |
| 209 frame_length_ms <= max_frame_length_ms; | 206 frame_length_ms <= max_frame_length_ms; |
| 210 }); | 207 }); |
| 211 RTC_DCHECK(std::is_sorted(out->begin(), out->end())); | 208 RTC_DCHECK(std::is_sorted(out->begin(), out->end())); |
| 212 } | 209 } |
| 213 | 210 |
| 211 int GetBitrateBps(const AudioEncoderOpusConfig& config) { |
| 212 RTC_DCHECK(config.IsOk()); |
| 213 return *config.bitrate_bps; |
| 214 } |
| 215 |
| 214 } // namespace | 216 } // namespace |
| 215 | 217 |
| 218 void AudioEncoderOpus::AppendSupportedEncoders( |
| 219 std::vector<AudioCodecSpec>* specs) { |
| 220 const SdpAudioFormat fmt = { |
| 221 "opus", 48000, 2, {{"minptime", "10"}, {"useinbandfec", "1"}}}; |
| 222 const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt)); |
| 223 specs->push_back({fmt, info}); |
| 224 } |
| 225 |
| 226 AudioCodecInfo AudioEncoderOpus::QueryAudioEncoder( |
| 227 const AudioEncoderOpusConfig& config) { |
| 228 RTC_DCHECK(config.IsOk()); |
| 229 AudioCodecInfo info(48000, config.num_channels, *config.bitrate_bps, |
| 230 AudioEncoderOpusConfig::kMinBitrateBps, |
| 231 AudioEncoderOpusConfig::kMaxBitrateBps); |
| 232 info.allow_comfort_noise = false; |
| 233 info.supports_network_adaption = true; |
| 234 return info; |
| 235 } |
| 236 |
| 237 std::unique_ptr<AudioEncoder> AudioEncoderOpus::MakeAudioEncoder( |
| 238 const AudioEncoderOpusConfig& config, |
| 239 int payload_type) { |
| 240 RTC_DCHECK(config.IsOk()); |
| 241 return rtc::MakeUnique<AudioEncoderOpus>(config, payload_type); |
| 242 } |
| 243 |
| 216 rtc::Optional<AudioCodecInfo> AudioEncoderOpus::QueryAudioEncoder( | 244 rtc::Optional<AudioCodecInfo> AudioEncoderOpus::QueryAudioEncoder( |
| 217 const SdpAudioFormat& format) { | 245 const SdpAudioFormat& format) { |
| 218 if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0 && | 246 if (STR_CASE_CMP(format.name.c_str(), GetPayloadName()) == 0 && |
| 219 format.clockrate_hz == 48000 && format.num_channels == 2) { | 247 format.clockrate_hz == 48000 && format.num_channels == 2) { |
| 220 const size_t num_channels = GetChannelCount(format); | 248 const size_t num_channels = GetChannelCount(format); |
| 221 const int bitrate = | 249 const int bitrate = |
| 222 CalculateBitrate(GetMaxPlaybackRate(format), num_channels, | 250 CalculateBitrate(GetMaxPlaybackRate(format), num_channels, |
| 223 GetFormatParameter(format, "maxaveragebitrate")); | 251 GetFormatParameter(format, "maxaveragebitrate")); |
| 224 AudioCodecInfo info(48000, num_channels, bitrate, kOpusMinBitrateBps, | 252 AudioCodecInfo info(48000, num_channels, bitrate, |
| 225 kOpusMaxBitrateBps); | 253 AudioEncoderOpusConfig::kMinBitrateBps, |
| 254 AudioEncoderOpusConfig::kMaxBitrateBps); |
| 226 info.allow_comfort_noise = false; | 255 info.allow_comfort_noise = false; |
| 227 info.supports_network_adaption = true; | 256 info.supports_network_adaption = true; |
| 228 | 257 |
| 229 return rtc::Optional<AudioCodecInfo>(info); | 258 return rtc::Optional<AudioCodecInfo>(info); |
| 230 } | 259 } |
| 231 return rtc::Optional<AudioCodecInfo>(); | 260 return rtc::Optional<AudioCodecInfo>(); |
| 232 } | 261 } |
| 233 | 262 |
| 234 AudioEncoderOpus::Config AudioEncoderOpus::CreateConfig( | 263 AudioEncoderOpusConfig AudioEncoderOpus::CreateConfig( |
| 264 int payload_type, |
| 265 const SdpAudioFormat& format) { |
| 266 auto opt_config = SdpToConfig(format); |
| 267 RTC_CHECK(opt_config); |
| 268 opt_config->payload_type = payload_type; |
| 269 return *opt_config; |
| 270 } |
| 271 |
| 272 AudioEncoderOpusConfig AudioEncoderOpus::CreateConfig( |
| 235 const CodecInst& codec_inst) { | 273 const CodecInst& codec_inst) { |
| 236 AudioEncoderOpus::Config config; | 274 AudioEncoderOpusConfig config; |
| 237 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); | 275 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); |
| 238 config.num_channels = codec_inst.channels; | 276 config.num_channels = codec_inst.channels; |
| 239 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); | 277 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); |
| 240 config.payload_type = codec_inst.pltype; | 278 config.application = config.num_channels == 1 |
| 241 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip | 279 ? AudioEncoderOpusConfig::ApplicationMode::kVoip |
| 242 : AudioEncoderOpus::kAudio; | 280 : AudioEncoderOpusConfig::ApplicationMode::kAudio; |
| 243 config.supported_frame_lengths_ms.push_back(config.frame_size_ms); | 281 config.supported_frame_lengths_ms.push_back(config.frame_size_ms); |
| 244 #if WEBRTC_OPUS_VARIABLE_COMPLEXITY | |
| 245 config.low_rate_complexity = 9; | |
| 246 #endif | |
| 247 return config; | 282 return config; |
| 248 } | 283 } |
| 249 | 284 |
| 250 AudioEncoderOpus::Config AudioEncoderOpus::CreateConfig( | 285 rtc::Optional<AudioEncoderOpusConfig> AudioEncoderOpus::SdpToConfig( |
| 251 int payload_type, | |
| 252 const SdpAudioFormat& format) { | 286 const SdpAudioFormat& format) { |
| 253 AudioEncoderOpus::Config config; | 287 if (STR_CASE_CMP(format.name.c_str(), "opus") != 0 || |
| 288 format.clockrate_hz != 48000 || format.num_channels != 2) { |
| 289 return rtc::Optional<AudioEncoderOpusConfig>(); |
| 290 } |
| 254 | 291 |
| 292 AudioEncoderOpusConfig config; |
| 255 config.num_channels = GetChannelCount(format); | 293 config.num_channels = GetChannelCount(format); |
| 256 config.frame_size_ms = GetFrameSizeMs(format); | 294 config.frame_size_ms = GetFrameSizeMs(format); |
| 257 config.max_playback_rate_hz = GetMaxPlaybackRate(format); | 295 config.max_playback_rate_hz = GetMaxPlaybackRate(format); |
| 258 config.fec_enabled = (GetFormatParameter(format, "useinbandfec") == "1"); | 296 config.fec_enabled = (GetFormatParameter(format, "useinbandfec") == "1"); |
| 259 config.dtx_enabled = (GetFormatParameter(format, "usedtx") == "1"); | 297 config.dtx_enabled = (GetFormatParameter(format, "usedtx") == "1"); |
| 260 config.cbr_enabled = (GetFormatParameter(format, "cbr") == "1"); | 298 config.cbr_enabled = (GetFormatParameter(format, "cbr") == "1"); |
| 261 config.bitrate_bps = rtc::Optional<int>( | 299 config.bitrate_bps = rtc::Optional<int>( |
| 262 CalculateBitrate(config.max_playback_rate_hz, config.num_channels, | 300 CalculateBitrate(config.max_playback_rate_hz, config.num_channels, |
| 263 GetFormatParameter(format, "maxaveragebitrate"))); | 301 GetFormatParameter(format, "maxaveragebitrate"))); |
| 264 config.payload_type = payload_type; | 302 config.application = config.num_channels == 1 |
| 265 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip | 303 ? AudioEncoderOpusConfig::ApplicationMode::kVoip |
| 266 : AudioEncoderOpus::kAudio; | 304 : AudioEncoderOpusConfig::ApplicationMode::kAudio; |
| 267 #if WEBRTC_OPUS_VARIABLE_COMPLEXITY | |
| 268 config.low_rate_complexity = 9; | |
| 269 #endif | |
| 270 | 305 |
| 271 constexpr int kMinANAFrameLength = kANASupportedFrameLengths[0]; | 306 constexpr int kMinANAFrameLength = kANASupportedFrameLengths[0]; |
| 272 constexpr int kMaxANAFrameLength = | 307 constexpr int kMaxANAFrameLength = |
| 273 kANASupportedFrameLengths[arraysize(kANASupportedFrameLengths) - 1]; | 308 kANASupportedFrameLengths[arraysize(kANASupportedFrameLengths) - 1]; |
| 309 |
| 274 // For now, minptime and maxptime are only used with ANA. If ptime is outside | 310 // For now, minptime and maxptime are only used with ANA. If ptime is outside |
| 275 // of this range, it will get adjusted once ANA takes hold. Ideally, we'd know | 311 // of this range, it will get adjusted once ANA takes hold. Ideally, we'd know |
| 276 // if ANA was to be used when setting up the config, and adjust accordingly. | 312 // if ANA was to be used when setting up the config, and adjust accordingly. |
| 277 const int min_frame_length_ms = | 313 const int min_frame_length_ms = |
| 278 GetFormatParameter<int>(format, "minptime").value_or(kMinANAFrameLength); | 314 GetFormatParameter<int>(format, "minptime").value_or(kMinANAFrameLength); |
| 279 const int max_frame_length_ms = | 315 const int max_frame_length_ms = |
| 280 GetFormatParameter<int>(format, "maxptime").value_or(kMaxANAFrameLength); | 316 GetFormatParameter<int>(format, "maxptime").value_or(kMaxANAFrameLength); |
| 281 | 317 |
| 282 FindSupportedFrameLengths(min_frame_length_ms, max_frame_length_ms, | 318 FindSupportedFrameLengths(min_frame_length_ms, max_frame_length_ms, |
| 283 &config.supported_frame_lengths_ms); | 319 &config.supported_frame_lengths_ms); |
| 284 return config; | 320 RTC_DCHECK(config.IsOk()); |
| 321 return rtc::Optional<AudioEncoderOpusConfig>(config); |
| 322 } |
| 323 |
| 324 rtc::Optional<int> AudioEncoderOpus::GetNewComplexity( |
| 325 const AudioEncoderOpusConfig& config) { |
| 326 RTC_DCHECK(config.IsOk()); |
| 327 const int bitrate_bps = GetBitrateBps(config); |
| 328 if (bitrate_bps >= config.complexity_threshold_bps - |
| 329 config.complexity_threshold_window_bps && |
| 330 bitrate_bps <= config.complexity_threshold_bps + |
| 331 config.complexity_threshold_window_bps) { |
| 332 // Within the hysteresis window; make no change. |
| 333 return rtc::Optional<int>(); |
| 334 } else { |
| 335 return rtc::Optional<int>(bitrate_bps <= config.complexity_threshold_bps |
| 336 ? config.low_rate_complexity |
| 337 : config.complexity); |
| 338 } |
| 285 } | 339 } |
| 286 | 340 |
| 287 class AudioEncoderOpus::PacketLossFractionSmoother { | 341 class AudioEncoderOpus::PacketLossFractionSmoother { |
| 288 public: | 342 public: |
| 289 explicit PacketLossFractionSmoother() | 343 explicit PacketLossFractionSmoother() |
| 290 : last_sample_time_ms_(rtc::TimeMillis()), | 344 : last_sample_time_ms_(rtc::TimeMillis()), |
| 291 smoother_(kAlphaForPacketLossFractionSmoother) {} | 345 smoother_(kAlphaForPacketLossFractionSmoother) {} |
| 292 | 346 |
| 293 // Gets the smoothed packet loss fraction. | 347 // Gets the smoothed packet loss fraction. |
| 294 float GetAverage() const { | 348 float GetAverage() const { |
| 295 float value = smoother_.filtered(); | 349 float value = smoother_.filtered(); |
| 296 return (value == rtc::ExpFilter::kValueUndefined) ? 0.0f : value; | 350 return (value == rtc::ExpFilter::kValueUndefined) ? 0.0f : value; |
| 297 } | 351 } |
| 298 | 352 |
| 299 // Add new observation to the packet loss fraction smoother. | 353 // Add new observation to the packet loss fraction smoother. |
| 300 void AddSample(float packet_loss_fraction) { | 354 void AddSample(float packet_loss_fraction) { |
| 301 int64_t now_ms = rtc::TimeMillis(); | 355 int64_t now_ms = rtc::TimeMillis(); |
| 302 smoother_.Apply(static_cast<float>(now_ms - last_sample_time_ms_), | 356 smoother_.Apply(static_cast<float>(now_ms - last_sample_time_ms_), |
| 303 packet_loss_fraction); | 357 packet_loss_fraction); |
| 304 last_sample_time_ms_ = now_ms; | 358 last_sample_time_ms_ = now_ms; |
| 305 } | 359 } |
| 306 | 360 |
| 307 private: | 361 private: |
| 308 int64_t last_sample_time_ms_; | 362 int64_t last_sample_time_ms_; |
| 309 | 363 |
| 310 // An exponential filter is used to smooth the packet loss fraction. | 364 // An exponential filter is used to smooth the packet loss fraction. |
| 311 rtc::ExpFilter smoother_; | 365 rtc::ExpFilter smoother_; |
| 312 }; | 366 }; |
| 313 | 367 |
| 314 AudioEncoderOpus::Config::Config() { | 368 AudioEncoderOpus::AudioEncoderOpus(const AudioEncoderOpusConfig& config) |
| 315 #if WEBRTC_OPUS_VARIABLE_COMPLEXITY | 369 : AudioEncoderOpus(config, config.payload_type) {} |
| 316 low_rate_complexity = 9; | |
| 317 #endif | |
| 318 } | |
| 319 AudioEncoderOpus::Config::Config(const Config&) = default; | |
| 320 AudioEncoderOpus::Config::~Config() = default; | |
| 321 auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default; | |
| 322 | |
| 323 bool AudioEncoderOpus::Config::IsOk() const { | |
| 324 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) | |
| 325 return false; | |
| 326 if (num_channels != 1 && num_channels != 2) | |
| 327 return false; | |
| 328 if (bitrate_bps && | |
| 329 (*bitrate_bps < kOpusMinBitrateBps || *bitrate_bps > kOpusMaxBitrateBps)) | |
| 330 return false; | |
| 331 if (complexity < 0 || complexity > 10) | |
| 332 return false; | |
| 333 if (low_rate_complexity < 0 || low_rate_complexity > 10) | |
| 334 return false; | |
| 335 return true; | |
| 336 } | |
| 337 | |
| 338 int AudioEncoderOpus::Config::GetBitrateBps() const { | |
| 339 RTC_DCHECK(IsOk()); | |
| 340 if (bitrate_bps) | |
| 341 return *bitrate_bps; // Explicitly set value. | |
| 342 else | |
| 343 return num_channels == 1 ? 32000 : 64000; // Default value. | |
| 344 } | |
| 345 | |
| 346 rtc::Optional<int> AudioEncoderOpus::Config::GetNewComplexity() const { | |
| 347 RTC_DCHECK(IsOk()); | |
| 348 const int bitrate_bps = GetBitrateBps(); | |
| 349 if (bitrate_bps >= | |
| 350 complexity_threshold_bps - complexity_threshold_window_bps && | |
| 351 bitrate_bps <= | |
| 352 complexity_threshold_bps + complexity_threshold_window_bps) { | |
| 353 // Within the hysteresis window; make no change. | |
| 354 return rtc::Optional<int>(); | |
| 355 } | |
| 356 return bitrate_bps <= complexity_threshold_bps | |
| 357 ? rtc::Optional<int>(low_rate_complexity) | |
| 358 : rtc::Optional<int>(complexity); | |
| 359 } | |
| 360 | 370 |
| 361 AudioEncoderOpus::AudioEncoderOpus( | 371 AudioEncoderOpus::AudioEncoderOpus( |
| 362 const Config& config, | 372 const AudioEncoderOpusConfig& config, |
| 373 int payload_type, |
| 363 AudioNetworkAdaptorCreator&& audio_network_adaptor_creator, | 374 AudioNetworkAdaptorCreator&& audio_network_adaptor_creator, |
| 364 std::unique_ptr<SmoothingFilter> bitrate_smoother) | 375 std::unique_ptr<SmoothingFilter> bitrate_smoother) |
| 365 : send_side_bwe_with_overhead_(webrtc::field_trial::IsEnabled( | 376 : payload_type_(payload_type), |
| 377 send_side_bwe_with_overhead_(webrtc::field_trial::IsEnabled( |
| 366 "WebRTC-SendSideBwe-WithOverhead")), | 378 "WebRTC-SendSideBwe-WithOverhead")), |
| 367 packet_loss_rate_(0.0), | 379 packet_loss_rate_(0.0), |
| 368 inst_(nullptr), | 380 inst_(nullptr), |
| 369 packet_loss_fraction_smoother_(new PacketLossFractionSmoother()), | 381 packet_loss_fraction_smoother_(new PacketLossFractionSmoother()), |
| 370 audio_network_adaptor_creator_( | 382 audio_network_adaptor_creator_( |
| 371 audio_network_adaptor_creator | 383 audio_network_adaptor_creator |
| 372 ? std::move(audio_network_adaptor_creator) | 384 ? std::move(audio_network_adaptor_creator) |
| 373 : [this](const ProtoString& config_string, | 385 : [this](const ProtoString& config_string, |
| 374 RtcEventLog* event_log) { | 386 RtcEventLog* event_log) { |
| 375 return DefaultAudioNetworkAdaptorCreator(config_string, | 387 return DefaultAudioNetworkAdaptorCreator(config_string, |
| 376 event_log); | 388 event_log); |
| 377 }), | 389 }), |
| 378 bitrate_smoother_(bitrate_smoother | 390 bitrate_smoother_(bitrate_smoother |
| 379 ? std::move(bitrate_smoother) : std::unique_ptr<SmoothingFilter>( | 391 ? std::move(bitrate_smoother) : std::unique_ptr<SmoothingFilter>( |
| 380 // We choose 5sec as initial time constant due to empirical data. | 392 // We choose 5sec as initial time constant due to empirical data. |
| 381 new SmoothingFilterImpl(5000))) { | 393 new SmoothingFilterImpl(5000))) { |
| 394 RTC_DCHECK(0 <= payload_type && payload_type <= 127); |
| 395 |
| 396 // Sanity check of the redundant payload type field that we want to get rid |
| 397 // of. See https://bugs.chromium.org/p/webrtc/issues/detail?id=7847 |
| 398 RTC_CHECK(config.payload_type == -1 || config.payload_type == payload_type); |
| 399 |
| 382 RTC_CHECK(RecreateEncoderInstance(config)); | 400 RTC_CHECK(RecreateEncoderInstance(config)); |
| 383 } | 401 } |
| 384 | 402 |
| 385 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) | 403 AudioEncoderOpus::AudioEncoderOpus(const CodecInst& codec_inst) |
| 386 : AudioEncoderOpus(CreateConfig(codec_inst), nullptr) {} | 404 : AudioEncoderOpus(CreateConfig(codec_inst), codec_inst.pltype) {} |
| 387 | 405 |
| 388 AudioEncoderOpus::AudioEncoderOpus(int payload_type, | 406 AudioEncoderOpus::AudioEncoderOpus(int payload_type, |
| 389 const SdpAudioFormat& format) | 407 const SdpAudioFormat& format) |
| 390 : AudioEncoderOpus(CreateConfig(payload_type, format), nullptr) {} | 408 : AudioEncoderOpus(*SdpToConfig(format), payload_type) {} |
| 391 | 409 |
| 392 AudioEncoderOpus::~AudioEncoderOpus() { | 410 AudioEncoderOpus::~AudioEncoderOpus() { |
| 393 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); | 411 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); |
| 394 } | 412 } |
| 395 | 413 |
| 396 int AudioEncoderOpus::SampleRateHz() const { | 414 int AudioEncoderOpus::SampleRateHz() const { |
| 397 return kSampleRateHz; | 415 return kSampleRateHz; |
| 398 } | 416 } |
| 399 | 417 |
| 400 size_t AudioEncoderOpus::NumChannels() const { | 418 size_t AudioEncoderOpus::NumChannels() const { |
| 401 return config_.num_channels; | 419 return config_.num_channels; |
| 402 } | 420 } |
| 403 | 421 |
| 404 size_t AudioEncoderOpus::Num10MsFramesInNextPacket() const { | 422 size_t AudioEncoderOpus::Num10MsFramesInNextPacket() const { |
| 405 return Num10msFramesPerPacket(); | 423 return Num10msFramesPerPacket(); |
| 406 } | 424 } |
| 407 | 425 |
| 408 size_t AudioEncoderOpus::Max10MsFramesInAPacket() const { | 426 size_t AudioEncoderOpus::Max10MsFramesInAPacket() const { |
| 409 return Num10msFramesPerPacket(); | 427 return Num10msFramesPerPacket(); |
| 410 } | 428 } |
| 411 | 429 |
| 412 int AudioEncoderOpus::GetTargetBitrate() const { | 430 int AudioEncoderOpus::GetTargetBitrate() const { |
| 413 return config_.GetBitrateBps(); | 431 return GetBitrateBps(config_); |
| 414 } | 432 } |
| 415 | 433 |
| 416 void AudioEncoderOpus::Reset() { | 434 void AudioEncoderOpus::Reset() { |
| 417 RTC_CHECK(RecreateEncoderInstance(config_)); | 435 RTC_CHECK(RecreateEncoderInstance(config_)); |
| 418 } | 436 } |
| 419 | 437 |
| 420 bool AudioEncoderOpus::SetFec(bool enable) { | 438 bool AudioEncoderOpus::SetFec(bool enable) { |
| 421 if (enable) { | 439 if (enable) { |
| 422 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); | 440 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); |
| 423 } else { | 441 } else { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 438 } | 456 } |
| 439 | 457 |
| 440 bool AudioEncoderOpus::GetDtx() const { | 458 bool AudioEncoderOpus::GetDtx() const { |
| 441 return config_.dtx_enabled; | 459 return config_.dtx_enabled; |
| 442 } | 460 } |
| 443 | 461 |
| 444 bool AudioEncoderOpus::SetApplication(Application application) { | 462 bool AudioEncoderOpus::SetApplication(Application application) { |
| 445 auto conf = config_; | 463 auto conf = config_; |
| 446 switch (application) { | 464 switch (application) { |
| 447 case Application::kSpeech: | 465 case Application::kSpeech: |
| 448 conf.application = AudioEncoderOpus::kVoip; | 466 conf.application = AudioEncoderOpusConfig::ApplicationMode::kVoip; |
| 449 break; | 467 break; |
| 450 case Application::kAudio: | 468 case Application::kAudio: |
| 451 conf.application = AudioEncoderOpus::kAudio; | 469 conf.application = AudioEncoderOpusConfig::ApplicationMode::kAudio; |
| 452 break; | 470 break; |
| 453 } | 471 } |
| 454 return RecreateEncoderInstance(conf); | 472 return RecreateEncoderInstance(conf); |
| 455 } | 473 } |
| 456 | 474 |
| 457 void AudioEncoderOpus::SetMaxPlaybackRate(int frequency_hz) { | 475 void AudioEncoderOpus::SetMaxPlaybackRate(int frequency_hz) { |
| 458 auto conf = config_; | 476 auto conf = config_; |
| 459 conf.max_playback_rate_hz = frequency_hz; | 477 conf.max_playback_rate_hz = frequency_hz; |
| 460 RTC_CHECK(RecreateEncoderInstance(conf)); | 478 RTC_CHECK(RecreateEncoderInstance(conf)); |
| 461 } | 479 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 ApplyAudioNetworkAdaptor(); | 534 ApplyAudioNetworkAdaptor(); |
| 517 } else if (send_side_bwe_with_overhead_) { | 535 } else if (send_side_bwe_with_overhead_) { |
| 518 if (!overhead_bytes_per_packet_) { | 536 if (!overhead_bytes_per_packet_) { |
| 519 LOG(LS_INFO) | 537 LOG(LS_INFO) |
| 520 << "AudioEncoderOpus: Overhead unknown, target audio bitrate " | 538 << "AudioEncoderOpus: Overhead unknown, target audio bitrate " |
| 521 << target_audio_bitrate_bps << " bps is ignored."; | 539 << target_audio_bitrate_bps << " bps is ignored."; |
| 522 return; | 540 return; |
| 523 } | 541 } |
| 524 const int overhead_bps = static_cast<int>( | 542 const int overhead_bps = static_cast<int>( |
| 525 *overhead_bytes_per_packet_ * 8 * 100 / Num10MsFramesInNextPacket()); | 543 *overhead_bytes_per_packet_ * 8 * 100 / Num10MsFramesInNextPacket()); |
| 526 SetTargetBitrate(std::min( | 544 SetTargetBitrate( |
| 527 kOpusMaxBitrateBps, | 545 std::min(AudioEncoderOpusConfig::kMaxBitrateBps, |
| 528 std::max(kOpusMinBitrateBps, target_audio_bitrate_bps - overhead_bps))); | 546 std::max(AudioEncoderOpusConfig::kMinBitrateBps, |
| 547 target_audio_bitrate_bps - overhead_bps))); |
| 529 } else { | 548 } else { |
| 530 SetTargetBitrate(target_audio_bitrate_bps); | 549 SetTargetBitrate(target_audio_bitrate_bps); |
| 531 } | 550 } |
| 532 } | 551 } |
| 533 | 552 |
| 534 void AudioEncoderOpus::OnReceivedRtt(int rtt_ms) { | 553 void AudioEncoderOpus::OnReceivedRtt(int rtt_ms) { |
| 535 if (!audio_network_adaptor_) | 554 if (!audio_network_adaptor_) |
| 536 return; | 555 return; |
| 537 audio_network_adaptor_->SetRtt(rtt_ms); | 556 audio_network_adaptor_->SetRtt(rtt_ms); |
| 538 ApplyAudioNetworkAdaptor(); | 557 ApplyAudioNetworkAdaptor(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 RTC_CHECK_GE(status, 0); // Fails only if fed invalid data. | 609 RTC_CHECK_GE(status, 0); // Fails only if fed invalid data. |
| 591 | 610 |
| 592 return static_cast<size_t>(status); | 611 return static_cast<size_t>(status); |
| 593 }); | 612 }); |
| 594 input_buffer_.clear(); | 613 input_buffer_.clear(); |
| 595 | 614 |
| 596 // Will use new packet size for next encoding. | 615 // Will use new packet size for next encoding. |
| 597 config_.frame_size_ms = next_frame_length_ms_; | 616 config_.frame_size_ms = next_frame_length_ms_; |
| 598 | 617 |
| 599 info.encoded_timestamp = first_timestamp_in_buffer_; | 618 info.encoded_timestamp = first_timestamp_in_buffer_; |
| 600 info.payload_type = config_.payload_type; | 619 info.payload_type = payload_type_; |
| 601 info.send_even_if_empty = true; // Allows Opus to send empty packets. | 620 info.send_even_if_empty = true; // Allows Opus to send empty packets. |
| 602 info.speech = (info.encoded_bytes > 0); | 621 info.speech = (info.encoded_bytes > 0); |
| 603 info.encoder_type = CodecType::kOpus; | 622 info.encoder_type = CodecType::kOpus; |
| 604 return info; | 623 return info; |
| 605 } | 624 } |
| 606 | 625 |
| 607 size_t AudioEncoderOpus::Num10msFramesPerPacket() const { | 626 size_t AudioEncoderOpus::Num10msFramesPerPacket() const { |
| 608 return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10)); | 627 return static_cast<size_t>(rtc::CheckedDivExact(config_.frame_size_ms, 10)); |
| 609 } | 628 } |
| 610 | 629 |
| 611 size_t AudioEncoderOpus::SamplesPer10msFrame() const { | 630 size_t AudioEncoderOpus::SamplesPer10msFrame() const { |
| 612 return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels; | 631 return rtc::CheckedDivExact(kSampleRateHz, 100) * config_.num_channels; |
| 613 } | 632 } |
| 614 | 633 |
| 615 size_t AudioEncoderOpus::SufficientOutputBufferSize() const { | 634 size_t AudioEncoderOpus::SufficientOutputBufferSize() const { |
| 616 // Calculate the number of bytes we expect the encoder to produce, | 635 // Calculate the number of bytes we expect the encoder to produce, |
| 617 // then multiply by two to give a wide margin for error. | 636 // then multiply by two to give a wide margin for error. |
| 618 const size_t bytes_per_millisecond = | 637 const size_t bytes_per_millisecond = |
| 619 static_cast<size_t>(config_.GetBitrateBps() / (1000 * 8) + 1); | 638 static_cast<size_t>(GetBitrateBps(config_) / (1000 * 8) + 1); |
| 620 const size_t approx_encoded_bytes = | 639 const size_t approx_encoded_bytes = |
| 621 Num10msFramesPerPacket() * 10 * bytes_per_millisecond; | 640 Num10msFramesPerPacket() * 10 * bytes_per_millisecond; |
| 622 return 2 * approx_encoded_bytes; | 641 return 2 * approx_encoded_bytes; |
| 623 } | 642 } |
| 624 | 643 |
| 625 // If the given config is OK, recreate the Opus encoder instance with those | 644 // If the given config is OK, recreate the Opus encoder instance with those |
| 626 // settings, save the config, and return true. Otherwise, do nothing and return | 645 // settings, save the config, and return true. Otherwise, do nothing and return |
| 627 // false. | 646 // false. |
| 628 bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) { | 647 bool AudioEncoderOpus::RecreateEncoderInstance( |
| 648 const AudioEncoderOpusConfig& config) { |
| 629 if (!config.IsOk()) | 649 if (!config.IsOk()) |
| 630 return false; | 650 return false; |
| 631 config_ = config; | 651 config_ = config; |
| 632 if (inst_) | 652 if (inst_) |
| 633 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); | 653 RTC_CHECK_EQ(0, WebRtcOpus_EncoderFree(inst_)); |
| 634 input_buffer_.clear(); | 654 input_buffer_.clear(); |
| 635 input_buffer_.reserve(Num10msFramesPerPacket() * SamplesPer10msFrame()); | 655 input_buffer_.reserve(Num10msFramesPerPacket() * SamplesPer10msFrame()); |
| 636 RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, config.num_channels, | 656 RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate( |
| 637 config.application)); | 657 &inst_, config.num_channels, |
| 638 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.GetBitrateBps())); | 658 config.application == |
| 659 AudioEncoderOpusConfig::ApplicationMode::kVoip |
| 660 ? 0 |
| 661 : 1)); |
| 662 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, GetBitrateBps(config))); |
| 639 if (config.fec_enabled) { | 663 if (config.fec_enabled) { |
| 640 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); | 664 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); |
| 641 } else { | 665 } else { |
| 642 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_)); | 666 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_)); |
| 643 } | 667 } |
| 644 RTC_CHECK_EQ( | 668 RTC_CHECK_EQ( |
| 645 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz)); | 669 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz)); |
| 646 // Use the default complexity if the start bitrate is within the hysteresis | 670 // Use the default complexity if the start bitrate is within the hysteresis |
| 647 // window. | 671 // window. |
| 648 complexity_ = config.GetNewComplexity().value_or(config.complexity); | 672 complexity_ = GetNewComplexity(config).value_or(config.complexity); |
| 649 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); | 673 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); |
| 650 if (config.dtx_enabled) { | 674 if (config.dtx_enabled) { |
| 651 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); | 675 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); |
| 652 } else { | 676 } else { |
| 653 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); | 677 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); |
| 654 } | 678 } |
| 655 RTC_CHECK_EQ(0, | 679 RTC_CHECK_EQ(0, |
| 656 WebRtcOpus_SetPacketLossRate( | 680 WebRtcOpus_SetPacketLossRate( |
| 657 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); | 681 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); |
| 658 if (config.cbr_enabled) { | 682 if (config.cbr_enabled) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 685 if (packet_loss_rate_ != opt_loss_rate) { | 709 if (packet_loss_rate_ != opt_loss_rate) { |
| 686 packet_loss_rate_ = opt_loss_rate; | 710 packet_loss_rate_ = opt_loss_rate; |
| 687 RTC_CHECK_EQ( | 711 RTC_CHECK_EQ( |
| 688 0, WebRtcOpus_SetPacketLossRate( | 712 0, WebRtcOpus_SetPacketLossRate( |
| 689 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); | 713 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); |
| 690 } | 714 } |
| 691 } | 715 } |
| 692 | 716 |
| 693 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { | 717 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { |
| 694 config_.bitrate_bps = rtc::Optional<int>(rtc::SafeClamp<int>( | 718 config_.bitrate_bps = rtc::Optional<int>(rtc::SafeClamp<int>( |
| 695 bits_per_second, kOpusMinBitrateBps, kOpusMaxBitrateBps)); | 719 bits_per_second, AudioEncoderOpusConfig::kMinBitrateBps, |
| 720 AudioEncoderOpusConfig::kMaxBitrateBps)); |
| 696 RTC_DCHECK(config_.IsOk()); | 721 RTC_DCHECK(config_.IsOk()); |
| 697 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps())); | 722 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, GetBitrateBps(config_))); |
| 698 const auto new_complexity = config_.GetNewComplexity(); | 723 const auto new_complexity = GetNewComplexity(config_); |
| 699 if (new_complexity && complexity_ != *new_complexity) { | 724 if (new_complexity && complexity_ != *new_complexity) { |
| 700 complexity_ = *new_complexity; | 725 complexity_ = *new_complexity; |
| 701 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); | 726 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); |
| 702 } | 727 } |
| 703 } | 728 } |
| 704 | 729 |
| 705 void AudioEncoderOpus::ApplyAudioNetworkAdaptor() { | 730 void AudioEncoderOpus::ApplyAudioNetworkAdaptor() { |
| 706 auto config = audio_network_adaptor_->GetEncoderRuntimeConfig(); | 731 auto config = audio_network_adaptor_->GetEncoderRuntimeConfig(); |
| 707 RTC_DCHECK(!config.frame_length_ms || *config.frame_length_ms == 20 || | 732 RTC_DCHECK(!config.frame_length_ms || *config.frame_length_ms == 20 || |
| 708 *config.frame_length_ms == 60); | 733 *config.frame_length_ms == 60); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 721 SetNumChannelsToEncode(*config.num_channels); | 746 SetNumChannelsToEncode(*config.num_channels); |
| 722 } | 747 } |
| 723 | 748 |
| 724 std::unique_ptr<AudioNetworkAdaptor> | 749 std::unique_ptr<AudioNetworkAdaptor> |
| 725 AudioEncoderOpus::DefaultAudioNetworkAdaptorCreator( | 750 AudioEncoderOpus::DefaultAudioNetworkAdaptorCreator( |
| 726 const ProtoString& config_string, | 751 const ProtoString& config_string, |
| 727 RtcEventLog* event_log) const { | 752 RtcEventLog* event_log) const { |
| 728 AudioNetworkAdaptorImpl::Config config; | 753 AudioNetworkAdaptorImpl::Config config; |
| 729 config.event_log = event_log; | 754 config.event_log = event_log; |
| 730 return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl( | 755 return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl( |
| 731 config, | 756 config, ControllerManagerImpl::Create( |
| 732 ControllerManagerImpl::Create( | 757 config_string, NumChannels(), supported_frame_lengths_ms(), |
| 733 config_string, NumChannels(), supported_frame_lengths_ms(), | 758 AudioEncoderOpusConfig::kMinBitrateBps, |
| 734 kOpusMinBitrateBps, num_channels_to_encode_, next_frame_length_ms_, | 759 num_channels_to_encode_, next_frame_length_ms_, |
| 735 GetTargetBitrate(), config_.fec_enabled, GetDtx()))); | 760 GetTargetBitrate(), config_.fec_enabled, GetDtx()))); |
| 736 } | 761 } |
| 737 | 762 |
| 738 void AudioEncoderOpus::MaybeUpdateUplinkBandwidth() { | 763 void AudioEncoderOpus::MaybeUpdateUplinkBandwidth() { |
| 739 if (audio_network_adaptor_) { | 764 if (audio_network_adaptor_) { |
| 740 int64_t now_ms = rtc::TimeMillis(); | 765 int64_t now_ms = rtc::TimeMillis(); |
| 741 if (!bitrate_smoother_last_update_time_ || | 766 if (!bitrate_smoother_last_update_time_ || |
| 742 now_ms - *bitrate_smoother_last_update_time_ >= | 767 now_ms - *bitrate_smoother_last_update_time_ >= |
| 743 config_.uplink_bandwidth_update_interval_ms) { | 768 config_.uplink_bandwidth_update_interval_ms) { |
| 744 rtc::Optional<float> smoothed_bitrate = bitrate_smoother_->GetAverage(); | 769 rtc::Optional<float> smoothed_bitrate = bitrate_smoother_->GetAverage(); |
| 745 if (smoothed_bitrate) | 770 if (smoothed_bitrate) |
| 746 audio_network_adaptor_->SetUplinkBandwidth(*smoothed_bitrate); | 771 audio_network_adaptor_->SetUplinkBandwidth(*smoothed_bitrate); |
| 747 bitrate_smoother_last_update_time_ = rtc::Optional<int64_t>(now_ms); | 772 bitrate_smoother_last_update_time_ = rtc::Optional<int64_t>(now_ms); |
| 748 } | 773 } |
| 749 } | 774 } |
| 750 } | 775 } |
| 751 | 776 |
| 752 } // namespace webrtc | 777 } // namespace webrtc |
| OLD | NEW |