Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc

Issue 2503443002: Let Opus increase complexity for low bitrates (Closed)
Patch Set: Fixing a typo Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698