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 |
(...skipping 26 matching lines...) Expand all Loading... |
37 | 37 |
38 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { | 38 AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) { |
39 AudioEncoderOpus::Config config; | 39 AudioEncoderOpus::Config config; |
40 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); | 40 config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48); |
41 config.num_channels = codec_inst.channels; | 41 config.num_channels = codec_inst.channels; |
42 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); | 42 config.bitrate_bps = rtc::Optional<int>(codec_inst.rate); |
43 config.payload_type = codec_inst.pltype; | 43 config.payload_type = codec_inst.pltype; |
44 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip | 44 config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip |
45 : AudioEncoderOpus::kAudio; | 45 : AudioEncoderOpus::kAudio; |
46 config.supported_frame_lengths_ms.push_back(config.frame_size_ms); | 46 config.supported_frame_lengths_ms.push_back(config.frame_size_ms); |
| 47 #if WEBRTC_OPUS_VARIABLE_COMPLEXITY |
| 48 config.low_rate_complexity = 9; |
| 49 #endif |
47 return config; | 50 return config; |
48 } | 51 } |
49 | 52 |
50 // Optimize the loss rate to configure Opus. Basically, optimized loss rate is | 53 // Optimize the loss rate to configure Opus. Basically, optimized loss rate is |
51 // the input loss rate rounded down to various levels, because a robustly good | 54 // the input loss rate rounded down to various levels, because a robustly good |
52 // audio quality is achieved by lowering the packet loss down. | 55 // audio quality is achieved by lowering the packet loss down. |
53 // Additionally, to prevent toggling, margins are used, i.e., when jumping to | 56 // Additionally, to prevent toggling, margins are used, i.e., when jumping to |
54 // a loss rate from below, a higher threshold is used than jumping to the same | 57 // a loss rate from below, a higher threshold is used than jumping to the same |
55 // level from above. | 58 // level from above. |
56 double OptimizePacketLossRate(double new_loss_rate, double old_loss_rate) { | 59 double OptimizePacketLossRate(double new_loss_rate, double old_loss_rate) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 } | 114 } |
112 | 115 |
113 private: | 116 private: |
114 const Clock* const clock_; | 117 const Clock* const clock_; |
115 int64_t last_sample_time_ms_; | 118 int64_t last_sample_time_ms_; |
116 | 119 |
117 // An exponential filter is used to smooth the packet loss fraction. | 120 // An exponential filter is used to smooth the packet loss fraction. |
118 rtc::ExpFilter smoother_; | 121 rtc::ExpFilter smoother_; |
119 }; | 122 }; |
120 | 123 |
121 AudioEncoderOpus::Config::Config() = default; | 124 AudioEncoderOpus::Config::Config() { |
| 125 #if WEBRTC_OPUS_VARIABLE_COMPLEXITY |
| 126 low_rate_complexity = 9; |
| 127 #endif |
| 128 } |
122 AudioEncoderOpus::Config::Config(const Config&) = default; | 129 AudioEncoderOpus::Config::Config(const Config&) = default; |
123 AudioEncoderOpus::Config::~Config() = default; | 130 AudioEncoderOpus::Config::~Config() = default; |
124 auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default; | 131 auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default; |
125 | 132 |
126 bool AudioEncoderOpus::Config::IsOk() const { | 133 bool AudioEncoderOpus::Config::IsOk() const { |
127 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) | 134 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) |
128 return false; | 135 return false; |
129 if (num_channels != 1 && num_channels != 2) | 136 if (num_channels != 1 && num_channels != 2) |
130 return false; | 137 return false; |
131 if (bitrate_bps && | 138 if (bitrate_bps && |
132 (*bitrate_bps < kMinBitrateBps || *bitrate_bps > kMaxBitrateBps)) | 139 (*bitrate_bps < kMinBitrateBps || *bitrate_bps > kMaxBitrateBps)) |
133 return false; | 140 return false; |
134 if (complexity < 0 || complexity > 10) | 141 if (complexity < 0 || complexity > 10) |
135 return false; | 142 return false; |
| 143 if (low_rate_complexity < 0 || low_rate_complexity > 10) |
| 144 return false; |
136 return true; | 145 return true; |
137 } | 146 } |
138 | 147 |
139 int AudioEncoderOpus::Config::GetBitrateBps() const { | 148 int AudioEncoderOpus::Config::GetBitrateBps() const { |
140 RTC_DCHECK(IsOk()); | 149 RTC_DCHECK(IsOk()); |
141 if (bitrate_bps) | 150 if (bitrate_bps) |
142 return *bitrate_bps; // Explicitly set value. | 151 return *bitrate_bps; // Explicitly set value. |
143 else | 152 else |
144 return num_channels == 1 ? 32000 : 64000; // Default value. | 153 return num_channels == 1 ? 32000 : 64000; // Default value. |
145 } | 154 } |
146 | 155 |
| 156 rtc::Optional<int> AudioEncoderOpus::Config::GetNewComplexity() const { |
| 157 RTC_DCHECK(IsOk()); |
| 158 const int bitrate_bps = GetBitrateBps(); |
| 159 if (bitrate_bps >= |
| 160 complexity_threshold_bps - complexity_threshold_window_bps && |
| 161 bitrate_bps <= |
| 162 complexity_threshold_bps + complexity_threshold_window_bps) { |
| 163 // Within the hysteresis window; make no change. |
| 164 return rtc::Optional<int>(); |
| 165 } |
| 166 return bitrate_bps <= complexity_threshold_bps |
| 167 ? rtc::Optional<int>(low_rate_complexity) |
| 168 : rtc::Optional<int>(complexity); |
| 169 } |
| 170 |
147 AudioEncoderOpus::AudioEncoderOpus( | 171 AudioEncoderOpus::AudioEncoderOpus( |
148 const Config& config, | 172 const Config& config, |
149 AudioNetworkAdaptorCreator&& audio_network_adaptor_creator) | 173 AudioNetworkAdaptorCreator&& audio_network_adaptor_creator) |
150 : packet_loss_rate_(0.0), | 174 : packet_loss_rate_(0.0), |
151 inst_(nullptr), | 175 inst_(nullptr), |
152 packet_loss_fraction_smoother_(new PacketLossFractionSmoother( | 176 packet_loss_fraction_smoother_(new PacketLossFractionSmoother( |
153 config.clock ? config.clock : Clock::GetRealTimeClock())), | 177 config.clock ? config.clock : Clock::GetRealTimeClock())), |
154 audio_network_adaptor_creator_( | 178 audio_network_adaptor_creator_( |
155 audio_network_adaptor_creator | 179 audio_network_adaptor_creator |
156 ? std::move(audio_network_adaptor_creator) | 180 ? std::move(audio_network_adaptor_creator) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 0, WebRtcOpus_SetPacketLossRate( | 267 0, WebRtcOpus_SetPacketLossRate( |
244 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); | 268 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); |
245 } | 269 } |
246 } | 270 } |
247 | 271 |
248 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { | 272 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { |
249 config_.bitrate_bps = rtc::Optional<int>( | 273 config_.bitrate_bps = rtc::Optional<int>( |
250 std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps)); | 274 std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps)); |
251 RTC_DCHECK(config_.IsOk()); | 275 RTC_DCHECK(config_.IsOk()); |
252 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps())); | 276 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps())); |
| 277 const auto new_complexity = config_.GetNewComplexity(); |
| 278 if (new_complexity && complexity_ != *new_complexity) { |
| 279 complexity_ = *new_complexity; |
| 280 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); |
| 281 } |
253 } | 282 } |
254 | 283 |
255 bool AudioEncoderOpus::EnableAudioNetworkAdaptor( | 284 bool AudioEncoderOpus::EnableAudioNetworkAdaptor( |
256 const std::string& config_string, | 285 const std::string& config_string, |
257 const Clock* clock) { | 286 const Clock* clock) { |
258 audio_network_adaptor_ = audio_network_adaptor_creator_(config_string, clock); | 287 audio_network_adaptor_ = audio_network_adaptor_creator_(config_string, clock); |
259 return audio_network_adaptor_.get() != nullptr; | 288 return audio_network_adaptor_.get() != nullptr; |
260 } | 289 } |
261 | 290 |
262 void AudioEncoderOpus::DisableAudioNetworkAdaptor() { | 291 void AudioEncoderOpus::DisableAudioNetworkAdaptor() { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, config.num_channels, | 421 RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, config.num_channels, |
393 config.application)); | 422 config.application)); |
394 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.GetBitrateBps())); | 423 RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.GetBitrateBps())); |
395 if (config.fec_enabled) { | 424 if (config.fec_enabled) { |
396 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); | 425 RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); |
397 } else { | 426 } else { |
398 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_)); | 427 RTC_CHECK_EQ(0, WebRtcOpus_DisableFec(inst_)); |
399 } | 428 } |
400 RTC_CHECK_EQ( | 429 RTC_CHECK_EQ( |
401 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz)); | 430 0, WebRtcOpus_SetMaxPlaybackRate(inst_, config.max_playback_rate_hz)); |
402 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, config.complexity)); | 431 // Use the default complexity if the start bitrate is within the hysteresis |
| 432 // window. |
| 433 complexity_ = config.GetNewComplexity().value_or(config.complexity); |
| 434 RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_)); |
403 if (config.dtx_enabled) { | 435 if (config.dtx_enabled) { |
404 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); | 436 RTC_CHECK_EQ(0, WebRtcOpus_EnableDtx(inst_)); |
405 } else { | 437 } else { |
406 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); | 438 RTC_CHECK_EQ(0, WebRtcOpus_DisableDtx(inst_)); |
407 } | 439 } |
408 RTC_CHECK_EQ(0, | 440 RTC_CHECK_EQ(0, |
409 WebRtcOpus_SetPacketLossRate( | 441 WebRtcOpus_SetPacketLossRate( |
410 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); | 442 inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5))); |
411 config_ = config; | 443 config_ = config; |
412 | 444 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 AudioNetworkAdaptorImpl::Config config; | 490 AudioNetworkAdaptorImpl::Config config; |
459 config.clock = clock; | 491 config.clock = clock; |
460 return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl( | 492 return std::unique_ptr<AudioNetworkAdaptor>(new AudioNetworkAdaptorImpl( |
461 config, ControllerManagerImpl::Create( | 493 config, ControllerManagerImpl::Create( |
462 config_string, NumChannels(), supported_frame_lengths_ms(), | 494 config_string, NumChannels(), supported_frame_lengths_ms(), |
463 num_channels_to_encode_, next_frame_length_ms_, | 495 num_channels_to_encode_, next_frame_length_ms_, |
464 GetTargetBitrate(), config_.fec_enabled, GetDtx(), clock))); | 496 GetTargetBitrate(), config_.fec_enabled, GetDtx(), clock))); |
465 } | 497 } |
466 | 498 |
467 } // namespace webrtc | 499 } // namespace webrtc |
OLD | NEW |