AudioEncoderOpus: Default to 32 kbit/s for mono, 64 kbit/s for stereo

When this class was created, we inadvertently set the default to 64
kbit/s for both cases, failing to preserve the previous behavior. This
patch restores the old behavior.

From what I've been able to dig up, this problem did not affect Opus
encoders created internally in the Audio Coding Module. Those have
always used the bitrate from the supplied CodecInst.

Review-Url: https://codereview.webrtc.org/1942193002
Cr-Commit-Position: refs/heads/master@{#12827}
This commit is contained in:
kwiberg 2016-05-20 04:57:01 -07:00 committed by Commit bot
parent 3fc8e8dde3
commit 2036135620
2 changed files with 31 additions and 9 deletions

View File

@ -29,7 +29,7 @@ AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) {
AudioEncoderOpus::Config config;
config.frame_size_ms = rtc::CheckedDivExact(codec_inst.pacsize, 48);
config.num_channels = codec_inst.channels;
config.bitrate_bps = codec_inst.rate;
config.bitrate_bps = rtc::Optional<int>(codec_inst.rate);
config.payload_type = codec_inst.pltype;
config.application = config.num_channels == 1 ? AudioEncoderOpus::kVoip
: AudioEncoderOpus::kAudio;
@ -78,18 +78,32 @@ double OptimizePacketLossRate(double new_loss_rate, double old_loss_rate) {
} // namespace
AudioEncoderOpus::Config::Config() = default;
AudioEncoderOpus::Config::Config(const Config&) = default;
AudioEncoderOpus::Config::~Config() = default;
auto AudioEncoderOpus::Config::operator=(const Config&) -> Config& = default;
bool AudioEncoderOpus::Config::IsOk() const {
if (frame_size_ms <= 0 || frame_size_ms % 10 != 0)
return false;
if (num_channels != 1 && num_channels != 2)
return false;
if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps)
if (bitrate_bps &&
(*bitrate_bps < kMinBitrateBps || *bitrate_bps > kMaxBitrateBps))
return false;
if (complexity < 0 || complexity > 10)
return false;
return true;
}
int AudioEncoderOpus::Config::GetBitrateBps() const {
RTC_DCHECK(IsOk());
if (bitrate_bps)
return *bitrate_bps; // Explicitly set value.
else
return num_channels == 1 ? 32000 : 64000; // Default value.
}
AudioEncoderOpus::AudioEncoderOpus(const Config& config)
: packet_loss_rate_(0.0), inst_(nullptr) {
RTC_CHECK(RecreateEncoderInstance(config));
@ -119,7 +133,7 @@ size_t AudioEncoderOpus::Max10MsFramesInAPacket() const {
}
int AudioEncoderOpus::GetTargetBitrate() const {
return config_.bitrate_bps;
return config_.GetBitrateBps();
}
void AudioEncoderOpus::Reset() {
@ -168,10 +182,10 @@ void AudioEncoderOpus::SetProjectedPacketLossRate(double fraction) {
}
void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) {
config_.bitrate_bps =
std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps);
config_.bitrate_bps = rtc::Optional<int>(
std::max(std::min(bits_per_second, kMaxBitrateBps), kMinBitrateBps));
RTC_DCHECK(config_.IsOk());
RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.bitrate_bps));
RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config_.GetBitrateBps()));
}
AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeImpl(
@ -228,7 +242,7 @@ size_t AudioEncoderOpus::SufficientOutputBufferSize() const {
// Calculate the number of bytes we expect the encoder to produce,
// then multiply by two to give a wide margin for error.
const size_t bytes_per_millisecond =
static_cast<size_t>(config_.bitrate_bps / (1000 * 8) + 1);
static_cast<size_t>(config_.GetBitrateBps() / (1000 * 8) + 1);
const size_t approx_encoded_bytes =
Num10msFramesPerPacket() * 10 * bytes_per_millisecond;
return 2 * approx_encoded_bytes;
@ -246,7 +260,7 @@ bool AudioEncoderOpus::RecreateEncoderInstance(const Config& config) {
input_buffer_.reserve(Num10msFramesPerPacket() * SamplesPer10msFrame());
RTC_CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, config.num_channels,
config.application));
RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.bitrate_bps));
RTC_CHECK_EQ(0, WebRtcOpus_SetBitRate(inst_, config.GetBitrateBps()));
if (config.fec_enabled) {
RTC_CHECK_EQ(0, WebRtcOpus_EnableFec(inst_));
} else {

View File

@ -14,6 +14,7 @@
#include <vector>
#include "webrtc/base/constructormagic.h"
#include "webrtc/base/optional.h"
#include "webrtc/modules/audio_coding/codecs/opus/opus_interface.h"
#include "webrtc/modules/audio_coding/codecs/audio_encoder.h"
@ -29,12 +30,19 @@ class AudioEncoderOpus final : public AudioEncoder {
};
struct Config {
Config();
Config(const Config&);
~Config();
Config& operator=(const Config&);
bool IsOk() const;
int GetBitrateBps() const;
int frame_size_ms = 20;
size_t num_channels = 1;
int payload_type = 120;
ApplicationMode application = kVoip;
int bitrate_bps = 64000;
rtc::Optional<int> bitrate_bps; // Unset means to use default value.
bool fec_enabled = false;
int max_playback_rate_hz = 48000;
int complexity = kDefaultComplexity;