Reland "Renaming AudioEncoder::SetTargetBitrate and SetProjectedPacketLossRate."
The earlier attempt of this was in https://codereview.webrtc.org/2411613002/ It was reverted due to failures on internal bots, showing that we cannot deprecate one method. BUG=webrtc:6303 Review-Url: https://codereview.webrtc.org/2538493006 Cr-Commit-Position: refs/heads/master@{#15333}
This commit is contained in:
@ -407,12 +407,6 @@ class RawAudioEncoderWrapper final : public AudioEncoder {
|
|||||||
void SetMaxPlaybackRate(int frequency_hz) override {
|
void SetMaxPlaybackRate(int frequency_hz) override {
|
||||||
return enc_->SetMaxPlaybackRate(frequency_hz);
|
return enc_->SetMaxPlaybackRate(frequency_hz);
|
||||||
}
|
}
|
||||||
void SetProjectedPacketLossRate(double fraction) override {
|
|
||||||
return enc_->SetProjectedPacketLossRate(fraction);
|
|
||||||
}
|
|
||||||
void SetTargetBitrate(int target_bps) override {
|
|
||||||
return enc_->SetTargetBitrate(target_bps);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AudioEncoder* enc_;
|
AudioEncoder* enc_;
|
||||||
@ -654,7 +648,7 @@ int AudioCodingModuleImpl::SendFrequency() const {
|
|||||||
void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) {
|
void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) {
|
||||||
rtc::CritScope lock(&acm_crit_sect_);
|
rtc::CritScope lock(&acm_crit_sect_);
|
||||||
if (encoder_stack_) {
|
if (encoder_stack_) {
|
||||||
encoder_stack_->SetTargetBitrate(bitrate_bps);
|
encoder_stack_->OnReceivedTargetAudioBitrate(bitrate_bps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,7 +900,7 @@ int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) {
|
|||||||
int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) {
|
int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) {
|
||||||
rtc::CritScope lock(&acm_crit_sect_);
|
rtc::CritScope lock(&acm_crit_sect_);
|
||||||
if (HaveValidEncoder("SetPacketLossRate")) {
|
if (HaveValidEncoder("SetPacketLossRate")) {
|
||||||
encoder_stack_->SetProjectedPacketLossRate(loss_rate / 100.0);
|
encoder_stack_->OnReceivedUplinkPacketLossFraction(loss_rate / 100.0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,8 +60,6 @@ bool AudioEncoder::SetApplication(Application application) {
|
|||||||
|
|
||||||
void AudioEncoder::SetMaxPlaybackRate(int frequency_hz) {}
|
void AudioEncoder::SetMaxPlaybackRate(int frequency_hz) {}
|
||||||
|
|
||||||
void AudioEncoder::SetProjectedPacketLossRate(double fraction) {}
|
|
||||||
|
|
||||||
void AudioEncoder::SetTargetBitrate(int target_bps) {}
|
void AudioEncoder::SetTargetBitrate(int target_bps) {}
|
||||||
|
|
||||||
rtc::ArrayView<std::unique_ptr<AudioEncoder>>
|
rtc::ArrayView<std::unique_ptr<AudioEncoder>>
|
||||||
@ -77,13 +75,9 @@ void AudioEncoder::DisableAudioNetworkAdaptor() {}
|
|||||||
void AudioEncoder::OnReceivedUplinkBandwidth(int uplink_bandwidth_bps) {}
|
void AudioEncoder::OnReceivedUplinkBandwidth(int uplink_bandwidth_bps) {}
|
||||||
|
|
||||||
void AudioEncoder::OnReceivedUplinkPacketLossFraction(
|
void AudioEncoder::OnReceivedUplinkPacketLossFraction(
|
||||||
float uplink_packet_loss_fraction) {
|
float uplink_packet_loss_fraction) {}
|
||||||
SetProjectedPacketLossRate(uplink_packet_loss_fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioEncoder::OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) {
|
void AudioEncoder::OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) {}
|
||||||
SetTargetBitrate(target_audio_bitrate_bps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioEncoder::OnReceivedRtt(int rtt_ms) {}
|
void AudioEncoder::OnReceivedRtt(int rtt_ms) {}
|
||||||
|
|
||||||
|
|||||||
@ -144,16 +144,12 @@ class AudioEncoder {
|
|||||||
// implementation does nothing.
|
// implementation does nothing.
|
||||||
virtual void SetMaxPlaybackRate(int frequency_hz);
|
virtual void SetMaxPlaybackRate(int frequency_hz);
|
||||||
|
|
||||||
// Tells the encoder what the projected packet loss rate is. The rate is in
|
// This is to be deprecated. Please use |OnReceivedTargetAudioBitrate|
|
||||||
// the range [0.0, 1.0]. The encoder would typically use this information to
|
// instead.
|
||||||
// adjust channel coding efforts, such as FEC. The default implementation
|
|
||||||
// does nothing.
|
|
||||||
virtual void SetProjectedPacketLossRate(double fraction);
|
|
||||||
|
|
||||||
// Tells the encoder what average bitrate we'd like it to produce. The
|
// Tells the encoder what average bitrate we'd like it to produce. The
|
||||||
// encoder is free to adjust or disregard the given bitrate (the default
|
// encoder is free to adjust or disregard the given bitrate (the default
|
||||||
// implementation does the latter).
|
// implementation does the latter).
|
||||||
virtual void SetTargetBitrate(int target_bps);
|
RTC_DEPRECATED virtual void SetTargetBitrate(int target_bps);
|
||||||
|
|
||||||
// Causes this encoder to let go of any other encoders it contains, and
|
// Causes this encoder to let go of any other encoders it contains, and
|
||||||
// returns a pointer to an array where they are stored (which is required to
|
// returns a pointer to an array where they are stored (which is required to
|
||||||
@ -175,6 +171,7 @@ class AudioEncoder {
|
|||||||
virtual void OnReceivedUplinkBandwidth(int uplink_bandwidth_bps);
|
virtual void OnReceivedUplinkBandwidth(int uplink_bandwidth_bps);
|
||||||
|
|
||||||
// Provides uplink packet loss fraction to this encoder to allow it to adapt.
|
// Provides uplink packet loss fraction to this encoder to allow it to adapt.
|
||||||
|
// |uplink_packet_loss_fraction| is in the range [0.0, 1.0].
|
||||||
virtual void OnReceivedUplinkPacketLossFraction(
|
virtual void OnReceivedUplinkPacketLossFraction(
|
||||||
float uplink_packet_loss_fraction);
|
float uplink_packet_loss_fraction);
|
||||||
|
|
||||||
|
|||||||
@ -179,19 +179,22 @@ void AudioEncoderCng::SetMaxPlaybackRate(int frequency_hz) {
|
|||||||
speech_encoder_->SetMaxPlaybackRate(frequency_hz);
|
speech_encoder_->SetMaxPlaybackRate(frequency_hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEncoderCng::SetProjectedPacketLossRate(double fraction) {
|
|
||||||
speech_encoder_->SetProjectedPacketLossRate(fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioEncoderCng::SetTargetBitrate(int bits_per_second) {
|
|
||||||
speech_encoder_->SetTargetBitrate(bits_per_second);
|
|
||||||
}
|
|
||||||
|
|
||||||
rtc::ArrayView<std::unique_ptr<AudioEncoder>>
|
rtc::ArrayView<std::unique_ptr<AudioEncoder>>
|
||||||
AudioEncoderCng::ReclaimContainedEncoders() {
|
AudioEncoderCng::ReclaimContainedEncoders() {
|
||||||
return rtc::ArrayView<std::unique_ptr<AudioEncoder>>(&speech_encoder_, 1);
|
return rtc::ArrayView<std::unique_ptr<AudioEncoder>>(&speech_encoder_, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioEncoderCng::OnReceivedUplinkPacketLossFraction(
|
||||||
|
float uplink_packet_loss_fraction) {
|
||||||
|
speech_encoder_->OnReceivedUplinkPacketLossFraction(
|
||||||
|
uplink_packet_loss_fraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEncoderCng::OnReceivedTargetAudioBitrate(
|
||||||
|
int target_audio_bitrate_bps) {
|
||||||
|
speech_encoder_->OnReceivedTargetAudioBitrate(target_audio_bitrate_bps);
|
||||||
|
}
|
||||||
|
|
||||||
AudioEncoder::EncodedInfo AudioEncoderCng::EncodePassive(
|
AudioEncoder::EncodedInfo AudioEncoderCng::EncodePassive(
|
||||||
size_t frames_to_encode,
|
size_t frames_to_encode,
|
||||||
rtc::Buffer* encoded) {
|
rtc::Buffer* encoded) {
|
||||||
|
|||||||
@ -61,10 +61,11 @@ class AudioEncoderCng final : public AudioEncoder {
|
|||||||
bool SetDtx(bool enable) override;
|
bool SetDtx(bool enable) override;
|
||||||
bool SetApplication(Application application) override;
|
bool SetApplication(Application application) override;
|
||||||
void SetMaxPlaybackRate(int frequency_hz) override;
|
void SetMaxPlaybackRate(int frequency_hz) override;
|
||||||
void SetProjectedPacketLossRate(double fraction) override;
|
|
||||||
void SetTargetBitrate(int target_bps) override;
|
|
||||||
rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders()
|
rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders()
|
||||||
override;
|
override;
|
||||||
|
void OnReceivedUplinkPacketLossFraction(
|
||||||
|
float uplink_packet_loss_fraction) override;
|
||||||
|
void OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EncodedInfo EncodePassive(size_t frames_to_encode,
|
EncodedInfo EncodePassive(size_t frames_to_encode,
|
||||||
|
|||||||
@ -217,16 +217,16 @@ TEST_F(AudioEncoderCngTest, CheckFrameSizePropagation) {
|
|||||||
EXPECT_EQ(17U, cng_->Num10MsFramesInNextPacket());
|
EXPECT_EQ(17U, cng_->Num10MsFramesInNextPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AudioEncoderCngTest, CheckChangeBitratePropagation) {
|
TEST_F(AudioEncoderCngTest, CheckTargetAudioBitratePropagation) {
|
||||||
CreateCng(MakeCngConfig());
|
CreateCng(MakeCngConfig());
|
||||||
EXPECT_CALL(*mock_encoder_, SetTargetBitrate(4711));
|
EXPECT_CALL(*mock_encoder_, OnReceivedTargetAudioBitrate(4711));
|
||||||
cng_->SetTargetBitrate(4711);
|
cng_->OnReceivedTargetAudioBitrate(4711);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AudioEncoderCngTest, CheckProjectedPacketLossRatePropagation) {
|
TEST_F(AudioEncoderCngTest, CheckPacketLossFractionPropagation) {
|
||||||
CreateCng(MakeCngConfig());
|
CreateCng(MakeCngConfig());
|
||||||
EXPECT_CALL(*mock_encoder_, SetProjectedPacketLossRate(0.5));
|
EXPECT_CALL(*mock_encoder_, OnReceivedUplinkPacketLossFraction(0.5));
|
||||||
cng_->SetProjectedPacketLossRate(0.5);
|
cng_->OnReceivedUplinkPacketLossFraction(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AudioEncoderCngTest, EncodeCallsVad) {
|
TEST_F(AudioEncoderCngTest, EncodeCallsVad) {
|
||||||
|
|||||||
@ -39,10 +39,12 @@ class MockAudioEncoder : public AudioEncoder {
|
|||||||
MOCK_METHOD1(SetDtx, bool(bool enable));
|
MOCK_METHOD1(SetDtx, bool(bool enable));
|
||||||
MOCK_METHOD1(SetApplication, bool(Application application));
|
MOCK_METHOD1(SetApplication, bool(Application application));
|
||||||
MOCK_METHOD1(SetMaxPlaybackRate, void(int frequency_hz));
|
MOCK_METHOD1(SetMaxPlaybackRate, void(int frequency_hz));
|
||||||
MOCK_METHOD1(SetProjectedPacketLossRate, void(double fraction));
|
|
||||||
MOCK_METHOD1(SetTargetBitrate, void(int target_bps));
|
|
||||||
MOCK_METHOD1(SetMaxBitrate, void(int max_bps));
|
MOCK_METHOD1(SetMaxBitrate, void(int max_bps));
|
||||||
MOCK_METHOD1(SetMaxPayloadSize, void(int max_payload_size_bytes));
|
MOCK_METHOD1(SetMaxPayloadSize, void(int max_payload_size_bytes));
|
||||||
|
MOCK_METHOD1(OnReceivedTargetAudioBitrate,
|
||||||
|
void(int target_audio_bitrate_bps));
|
||||||
|
MOCK_METHOD1(OnReceivedUplinkPacketLossFraction,
|
||||||
|
void(float uplink_packet_loss_fraction));
|
||||||
|
|
||||||
// Note, we explicitly chose not to create a mock for the Encode method.
|
// Note, we explicitly chose not to create a mock for the Encode method.
|
||||||
MOCK_METHOD3(EncodeImpl,
|
MOCK_METHOD3(EncodeImpl,
|
||||||
|
|||||||
@ -56,18 +56,18 @@ AudioEncoderOpus::Config CreateConfig(const CodecInst& codec_inst) {
|
|||||||
// Additionally, to prevent toggling, margins are used, i.e., when jumping to
|
// Additionally, to prevent toggling, margins are used, i.e., when jumping to
|
||||||
// a loss rate from below, a higher threshold is used than jumping to the same
|
// a loss rate from below, a higher threshold is used than jumping to the same
|
||||||
// level from above.
|
// level from above.
|
||||||
double OptimizePacketLossRate(double new_loss_rate, double old_loss_rate) {
|
float OptimizePacketLossRate(float new_loss_rate, float old_loss_rate) {
|
||||||
RTC_DCHECK_GE(new_loss_rate, 0.0);
|
RTC_DCHECK_GE(new_loss_rate, 0.0f);
|
||||||
RTC_DCHECK_LE(new_loss_rate, 1.0);
|
RTC_DCHECK_LE(new_loss_rate, 1.0f);
|
||||||
RTC_DCHECK_GE(old_loss_rate, 0.0);
|
RTC_DCHECK_GE(old_loss_rate, 0.0f);
|
||||||
RTC_DCHECK_LE(old_loss_rate, 1.0);
|
RTC_DCHECK_LE(old_loss_rate, 1.0f);
|
||||||
const double kPacketLossRate20 = 0.20;
|
constexpr float kPacketLossRate20 = 0.20f;
|
||||||
const double kPacketLossRate10 = 0.10;
|
constexpr float kPacketLossRate10 = 0.10f;
|
||||||
const double kPacketLossRate5 = 0.05;
|
constexpr float kPacketLossRate5 = 0.05f;
|
||||||
const double kPacketLossRate1 = 0.01;
|
constexpr float kPacketLossRate1 = 0.01f;
|
||||||
const double kLossRate20Margin = 0.02;
|
constexpr float kLossRate20Margin = 0.02f;
|
||||||
const double kLossRate10Margin = 0.01;
|
constexpr float kLossRate10Margin = 0.01f;
|
||||||
const double kLossRate5Margin = 0.01;
|
constexpr float kLossRate5Margin = 0.01f;
|
||||||
if (new_loss_rate >=
|
if (new_loss_rate >=
|
||||||
kPacketLossRate20 +
|
kPacketLossRate20 +
|
||||||
kLossRate20Margin *
|
kLossRate20Margin *
|
||||||
@ -86,7 +86,7 @@ double OptimizePacketLossRate(double new_loss_rate, double old_loss_rate) {
|
|||||||
} else if (new_loss_rate >= kPacketLossRate1) {
|
} else if (new_loss_rate >= kPacketLossRate1) {
|
||||||
return kPacketLossRate1;
|
return kPacketLossRate1;
|
||||||
} else {
|
} else {
|
||||||
return 0.0;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,28 +259,6 @@ void AudioEncoderOpus::SetMaxPlaybackRate(int frequency_hz) {
|
|||||||
RTC_CHECK(RecreateEncoderInstance(conf));
|
RTC_CHECK(RecreateEncoderInstance(conf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEncoderOpus::SetProjectedPacketLossRate(double fraction) {
|
|
||||||
double opt_loss_rate = OptimizePacketLossRate(fraction, packet_loss_rate_);
|
|
||||||
if (packet_loss_rate_ != opt_loss_rate) {
|
|
||||||
packet_loss_rate_ = opt_loss_rate;
|
|
||||||
RTC_CHECK_EQ(
|
|
||||||
0, WebRtcOpus_SetPacketLossRate(
|
|
||||||
inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) {
|
|
||||||
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_.GetBitrateBps()));
|
|
||||||
const auto new_complexity = config_.GetNewComplexity();
|
|
||||||
if (new_complexity && complexity_ != *new_complexity) {
|
|
||||||
complexity_ = *new_complexity;
|
|
||||||
RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioEncoderOpus::EnableAudioNetworkAdaptor(
|
bool AudioEncoderOpus::EnableAudioNetworkAdaptor(
|
||||||
const std::string& config_string,
|
const std::string& config_string,
|
||||||
const Clock* clock) {
|
const Clock* clock) {
|
||||||
@ -462,6 +440,28 @@ void AudioEncoderOpus::SetNumChannelsToEncode(size_t num_channels_to_encode) {
|
|||||||
num_channels_to_encode_ = num_channels_to_encode;
|
num_channels_to_encode_ = num_channels_to_encode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioEncoderOpus::SetProjectedPacketLossRate(float fraction) {
|
||||||
|
float opt_loss_rate = OptimizePacketLossRate(fraction, packet_loss_rate_);
|
||||||
|
if (packet_loss_rate_ != opt_loss_rate) {
|
||||||
|
packet_loss_rate_ = opt_loss_rate;
|
||||||
|
RTC_CHECK_EQ(
|
||||||
|
0, WebRtcOpus_SetPacketLossRate(
|
||||||
|
inst_, static_cast<int32_t>(packet_loss_rate_ * 100 + .5)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) {
|
||||||
|
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_.GetBitrateBps()));
|
||||||
|
const auto new_complexity = config_.GetNewComplexity();
|
||||||
|
if (new_complexity && complexity_ != *new_complexity) {
|
||||||
|
complexity_ = *new_complexity;
|
||||||
|
RTC_CHECK_EQ(0, WebRtcOpus_SetComplexity(inst_, complexity_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AudioEncoderOpus::ApplyAudioNetworkAdaptor() {
|
void AudioEncoderOpus::ApplyAudioNetworkAdaptor() {
|
||||||
auto config = audio_network_adaptor_->GetEncoderRuntimeConfig();
|
auto config = audio_network_adaptor_->GetEncoderRuntimeConfig();
|
||||||
// |audio_network_adaptor_| is supposed to be configured to output all
|
// |audio_network_adaptor_| is supposed to be configured to output all
|
||||||
|
|||||||
@ -102,9 +102,6 @@ class AudioEncoderOpus final : public AudioEncoder {
|
|||||||
|
|
||||||
bool SetApplication(Application application) override;
|
bool SetApplication(Application application) override;
|
||||||
void SetMaxPlaybackRate(int frequency_hz) override;
|
void SetMaxPlaybackRate(int frequency_hz) override;
|
||||||
void SetProjectedPacketLossRate(double fraction) override;
|
|
||||||
void SetTargetBitrate(int target_bps) override;
|
|
||||||
|
|
||||||
bool EnableAudioNetworkAdaptor(const std::string& config_string,
|
bool EnableAudioNetworkAdaptor(const std::string& config_string,
|
||||||
const Clock* clock) override;
|
const Clock* clock) override;
|
||||||
void DisableAudioNetworkAdaptor() override;
|
void DisableAudioNetworkAdaptor() override;
|
||||||
@ -120,7 +117,7 @@ class AudioEncoderOpus final : public AudioEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getters for testing.
|
// Getters for testing.
|
||||||
double packet_loss_rate() const { return packet_loss_rate_; }
|
float packet_loss_rate() const { return packet_loss_rate_; }
|
||||||
ApplicationMode application() const { return config_.application; }
|
ApplicationMode application() const { return config_.application; }
|
||||||
bool fec_enabled() const { return config_.fec_enabled; }
|
bool fec_enabled() const { return config_.fec_enabled; }
|
||||||
size_t num_channels_to_encode() const { return num_channels_to_encode_; }
|
size_t num_channels_to_encode() const { return num_channels_to_encode_; }
|
||||||
@ -140,13 +137,19 @@ class AudioEncoderOpus final : public AudioEncoder {
|
|||||||
bool RecreateEncoderInstance(const Config& config);
|
bool RecreateEncoderInstance(const Config& config);
|
||||||
void SetFrameLength(int frame_length_ms);
|
void SetFrameLength(int frame_length_ms);
|
||||||
void SetNumChannelsToEncode(size_t num_channels_to_encode);
|
void SetNumChannelsToEncode(size_t num_channels_to_encode);
|
||||||
|
void SetProjectedPacketLossRate(float fraction);
|
||||||
|
|
||||||
|
// TODO(minyue): remove "override" when we can deprecate
|
||||||
|
// |AudioEncoder::SetTargetBitrate|.
|
||||||
|
void SetTargetBitrate(int target_bps) override;
|
||||||
|
|
||||||
void ApplyAudioNetworkAdaptor();
|
void ApplyAudioNetworkAdaptor();
|
||||||
std::unique_ptr<AudioNetworkAdaptor> DefaultAudioNetworkAdaptorCreator(
|
std::unique_ptr<AudioNetworkAdaptor> DefaultAudioNetworkAdaptorCreator(
|
||||||
const std::string& config_string,
|
const std::string& config_string,
|
||||||
const Clock* clock) const;
|
const Clock* clock) const;
|
||||||
|
|
||||||
Config config_;
|
Config config_;
|
||||||
double packet_loss_rate_;
|
float packet_loss_rate_;
|
||||||
std::vector<int16_t> input_buffer_;
|
std::vector<int16_t> input_buffer_;
|
||||||
OpusEncInst* inst_;
|
OpusEncInst* inst_;
|
||||||
uint32_t first_timestamp_in_buffer_;
|
uint32_t first_timestamp_in_buffer_;
|
||||||
|
|||||||
@ -151,26 +151,27 @@ TEST(AudioEncoderOpusTest, ToggleDtx) {
|
|||||||
EXPECT_TRUE(states.encoder->SetDtx(false));
|
EXPECT_TRUE(states.encoder->SetDtx(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(AudioEncoderOpusTest, SetBitrate) {
|
TEST(AudioEncoderOpusTest,
|
||||||
|
OnReceivedTargetAudioBitrateWithoutAudioNetworkAdaptor) {
|
||||||
auto states = CreateCodec(1);
|
auto states = CreateCodec(1);
|
||||||
// Constants are replicated from audio_states.encoderopus.cc.
|
// Constants are replicated from audio_states.encoderopus.cc.
|
||||||
const int kMinBitrateBps = 500;
|
const int kMinBitrateBps = 500;
|
||||||
const int kMaxBitrateBps = 512000;
|
const int kMaxBitrateBps = 512000;
|
||||||
// Set a too low bitrate.
|
// Set a too low bitrate.
|
||||||
states.encoder->SetTargetBitrate(kMinBitrateBps - 1);
|
states.encoder->OnReceivedTargetAudioBitrate(kMinBitrateBps - 1);
|
||||||
EXPECT_EQ(kMinBitrateBps, states.encoder->GetTargetBitrate());
|
EXPECT_EQ(kMinBitrateBps, states.encoder->GetTargetBitrate());
|
||||||
// Set a too high bitrate.
|
// Set a too high bitrate.
|
||||||
states.encoder->SetTargetBitrate(kMaxBitrateBps + 1);
|
states.encoder->OnReceivedTargetAudioBitrate(kMaxBitrateBps + 1);
|
||||||
EXPECT_EQ(kMaxBitrateBps, states.encoder->GetTargetBitrate());
|
EXPECT_EQ(kMaxBitrateBps, states.encoder->GetTargetBitrate());
|
||||||
// Set the minimum rate.
|
// Set the minimum rate.
|
||||||
states.encoder->SetTargetBitrate(kMinBitrateBps);
|
states.encoder->OnReceivedTargetAudioBitrate(kMinBitrateBps);
|
||||||
EXPECT_EQ(kMinBitrateBps, states.encoder->GetTargetBitrate());
|
EXPECT_EQ(kMinBitrateBps, states.encoder->GetTargetBitrate());
|
||||||
// Set the maximum rate.
|
// Set the maximum rate.
|
||||||
states.encoder->SetTargetBitrate(kMaxBitrateBps);
|
states.encoder->OnReceivedTargetAudioBitrate(kMaxBitrateBps);
|
||||||
EXPECT_EQ(kMaxBitrateBps, states.encoder->GetTargetBitrate());
|
EXPECT_EQ(kMaxBitrateBps, states.encoder->GetTargetBitrate());
|
||||||
// Set rates from 1000 up to 32000 bps.
|
// Set rates from 1000 up to 32000 bps.
|
||||||
for (int rate = 1000; rate <= 32000; rate += 1000) {
|
for (int rate = 1000; rate <= 32000; rate += 1000) {
|
||||||
states.encoder->SetTargetBitrate(rate);
|
states.encoder->OnReceivedTargetAudioBitrate(rate);
|
||||||
EXPECT_EQ(rate, states.encoder->GetTargetBitrate());
|
EXPECT_EQ(rate, states.encoder->GetTargetBitrate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,24 +180,31 @@ namespace {
|
|||||||
|
|
||||||
// Returns a vector with the n evenly-spaced numbers a, a + (b - a)/(n - 1),
|
// Returns a vector with the n evenly-spaced numbers a, a + (b - a)/(n - 1),
|
||||||
// ..., b.
|
// ..., b.
|
||||||
std::vector<double> IntervalSteps(double a, double b, size_t n) {
|
std::vector<float> IntervalSteps(float a, float b, size_t n) {
|
||||||
RTC_DCHECK_GT(n, 1);
|
RTC_DCHECK_GT(n, 1u);
|
||||||
const double step = (b - a) / (n - 1);
|
const float step = (b - a) / (n - 1);
|
||||||
std::vector<double> points;
|
std::vector<float> points;
|
||||||
for (size_t i = 0; i < n; ++i)
|
points.push_back(a);
|
||||||
|
for (size_t i = 1; i < n - 1; ++i)
|
||||||
points.push_back(a + i * step);
|
points.push_back(a + i * step);
|
||||||
|
points.push_back(b);
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the packet loss rate to each number in the vector in turn, and verifies
|
// Sets the packet loss rate to each number in the vector in turn, and verifies
|
||||||
// that the loss rate as reported by the encoder is |expected_return| for all
|
// that the loss rate as reported by the encoder is |expected_return| for all
|
||||||
// of them.
|
// of them.
|
||||||
void TestSetPacketLossRate(AudioEncoderOpus* encoder,
|
void TestSetPacketLossRate(AudioEncoderOpusStates* states,
|
||||||
const std::vector<double>& losses,
|
const std::vector<float>& losses,
|
||||||
double expected_return) {
|
float expected_return) {
|
||||||
for (double loss : losses) {
|
// |kSampleIntervalMs| is chosen to ease the calculation since
|
||||||
encoder->SetProjectedPacketLossRate(loss);
|
// 0.9999 ^ 184198 = 1e-8. Which minimizes the effect of
|
||||||
EXPECT_DOUBLE_EQ(expected_return, encoder->packet_loss_rate());
|
// PacketLossFractionSmoother used in AudioEncoderOpus.
|
||||||
|
constexpr int64_t kSampleIntervalMs = 184198;
|
||||||
|
for (float loss : losses) {
|
||||||
|
states->encoder->OnReceivedUplinkPacketLossFraction(loss);
|
||||||
|
states->simulated_clock->AdvanceTimeMilliseconds(kSampleIntervalMs);
|
||||||
|
EXPECT_FLOAT_EQ(expected_return, states->encoder->packet_loss_rate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,23 +212,23 @@ void TestSetPacketLossRate(AudioEncoderOpus* encoder,
|
|||||||
|
|
||||||
TEST(AudioEncoderOpusTest, PacketLossRateOptimized) {
|
TEST(AudioEncoderOpusTest, PacketLossRateOptimized) {
|
||||||
auto states = CreateCodec(1);
|
auto states = CreateCodec(1);
|
||||||
auto I = [](double a, double b) { return IntervalSteps(a, b, 10); };
|
auto I = [](float a, float b) { return IntervalSteps(a, b, 10); };
|
||||||
const double eps = 1e-15;
|
constexpr float eps = 1e-8f;
|
||||||
|
|
||||||
// Note that the order of the following calls is critical.
|
// Note that the order of the following calls is critical.
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.00 , 0.01 - eps), 0.00);
|
TestSetPacketLossRate(&states, I(0.00f , 0.01f - eps), 0.00f);
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.01 + eps, 0.06 - eps), 0.01);
|
TestSetPacketLossRate(&states, I(0.01f + eps, 0.06f - eps), 0.01f);
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.06 + eps, 0.11 - eps), 0.05);
|
TestSetPacketLossRate(&states, I(0.06f + eps, 0.11f - eps), 0.05f);
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.11 + eps, 0.22 - eps), 0.10);
|
TestSetPacketLossRate(&states, I(0.11f + eps, 0.22f - eps), 0.10f);
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.22 + eps, 1.00 ), 0.20);
|
TestSetPacketLossRate(&states, I(0.22f + eps, 1.00f ), 0.20f);
|
||||||
|
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(1.00 , 0.18 + eps), 0.20);
|
TestSetPacketLossRate(&states, I(1.00f , 0.18f + eps), 0.20f);
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.18 - eps, 0.09 + eps), 0.10);
|
TestSetPacketLossRate(&states, I(0.18f - eps, 0.09f + eps), 0.10f);
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.09 - eps, 0.04 + eps), 0.05);
|
TestSetPacketLossRate(&states, I(0.09f - eps, 0.04f + eps), 0.05f);
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.04 - eps, 0.01 + eps), 0.01);
|
TestSetPacketLossRate(&states, I(0.04f - eps, 0.01f + eps), 0.01f);
|
||||||
TestSetPacketLossRate(states.encoder.get(), I(0.01 - eps, 0.00 ), 0.00);
|
TestSetPacketLossRate(&states, I(0.01f - eps, 0.00f ), 0.00f);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,13 +325,13 @@ TEST(AudioEncoderOpusTest,
|
|||||||
// will fail.
|
// will fail.
|
||||||
constexpr float kPacketLossFraction_1 = 0.02f;
|
constexpr float kPacketLossFraction_1 = 0.02f;
|
||||||
constexpr float kPacketLossFraction_2 = 0.198f;
|
constexpr float kPacketLossFraction_2 = 0.198f;
|
||||||
// |kSecondSampleTimeMs| is chose to ease the calculation since
|
// |kSecondSampleTimeMs| is chosen to ease the calculation since
|
||||||
// 0.9999 ^ 6931 = 0.5.
|
// 0.9999 ^ 6931 = 0.5.
|
||||||
constexpr float kSecondSampleTimeMs = 6931;
|
constexpr int64_t kSecondSampleTimeMs = 6931;
|
||||||
|
|
||||||
// First time, no filtering.
|
// First time, no filtering.
|
||||||
states.encoder->OnReceivedUplinkPacketLossFraction(kPacketLossFraction_1);
|
states.encoder->OnReceivedUplinkPacketLossFraction(kPacketLossFraction_1);
|
||||||
EXPECT_DOUBLE_EQ(0.01, states.encoder->packet_loss_rate());
|
EXPECT_FLOAT_EQ(0.01f, states.encoder->packet_loss_rate());
|
||||||
|
|
||||||
states.simulated_clock->AdvanceTimeMilliseconds(kSecondSampleTimeMs);
|
states.simulated_clock->AdvanceTimeMilliseconds(kSecondSampleTimeMs);
|
||||||
states.encoder->OnReceivedUplinkPacketLossFraction(kPacketLossFraction_2);
|
states.encoder->OnReceivedUplinkPacketLossFraction(kPacketLossFraction_2);
|
||||||
@ -332,7 +340,7 @@ TEST(AudioEncoderOpusTest,
|
|||||||
// (0.02 + 0.198) / 2 = 0.109, which reach the threshold for the optimized
|
// (0.02 + 0.198) / 2 = 0.109, which reach the threshold for the optimized
|
||||||
// packet loss rate to increase to 0.05. If no smoothing has been made, the
|
// packet loss rate to increase to 0.05. If no smoothing has been made, the
|
||||||
// optimized packet loss rate should have been increase to 0.1.
|
// optimized packet loss rate should have been increase to 0.1.
|
||||||
EXPECT_DOUBLE_EQ(0.05, states.encoder->packet_loss_rate());
|
EXPECT_FLOAT_EQ(0.05f, states.encoder->packet_loss_rate());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -115,17 +115,20 @@ void AudioEncoderCopyRed::SetMaxPlaybackRate(int frequency_hz) {
|
|||||||
speech_encoder_->SetMaxPlaybackRate(frequency_hz);
|
speech_encoder_->SetMaxPlaybackRate(frequency_hz);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEncoderCopyRed::SetProjectedPacketLossRate(double fraction) {
|
|
||||||
speech_encoder_->SetProjectedPacketLossRate(fraction);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioEncoderCopyRed::SetTargetBitrate(int bits_per_second) {
|
|
||||||
speech_encoder_->SetTargetBitrate(bits_per_second);
|
|
||||||
}
|
|
||||||
|
|
||||||
rtc::ArrayView<std::unique_ptr<AudioEncoder>>
|
rtc::ArrayView<std::unique_ptr<AudioEncoder>>
|
||||||
AudioEncoderCopyRed::ReclaimContainedEncoders() {
|
AudioEncoderCopyRed::ReclaimContainedEncoders() {
|
||||||
return rtc::ArrayView<std::unique_ptr<AudioEncoder>>(&speech_encoder_, 1);
|
return rtc::ArrayView<std::unique_ptr<AudioEncoder>>(&speech_encoder_, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioEncoderCopyRed::OnReceivedUplinkPacketLossFraction(
|
||||||
|
float uplink_packet_loss_fraction) {
|
||||||
|
speech_encoder_->OnReceivedUplinkPacketLossFraction(
|
||||||
|
uplink_packet_loss_fraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioEncoderCopyRed::OnReceivedTargetAudioBitrate(
|
||||||
|
int target_audio_bitrate_bps) {
|
||||||
|
speech_encoder_->OnReceivedTargetAudioBitrate(target_audio_bitrate_bps);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
@ -49,10 +49,11 @@ class AudioEncoderCopyRed final : public AudioEncoder {
|
|||||||
bool SetDtx(bool enable) override;
|
bool SetDtx(bool enable) override;
|
||||||
bool SetApplication(Application application) override;
|
bool SetApplication(Application application) override;
|
||||||
void SetMaxPlaybackRate(int frequency_hz) override;
|
void SetMaxPlaybackRate(int frequency_hz) override;
|
||||||
void SetProjectedPacketLossRate(double fraction) override;
|
|
||||||
void SetTargetBitrate(int target_bps) override;
|
|
||||||
rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders()
|
rtc::ArrayView<std::unique_ptr<AudioEncoder>> ReclaimContainedEncoders()
|
||||||
override;
|
override;
|
||||||
|
void OnReceivedUplinkPacketLossFraction(
|
||||||
|
float uplink_packet_loss_fraction) override;
|
||||||
|
void OnReceivedTargetAudioBitrate(int target_audio_bitrate_bps) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
|
EncodedInfo EncodeImpl(uint32_t rtp_timestamp,
|
||||||
|
|||||||
@ -97,14 +97,14 @@ TEST_F(AudioEncoderCopyRedTest, CheckMaxFrameSizePropagation) {
|
|||||||
EXPECT_EQ(17U, red_->Max10MsFramesInAPacket());
|
EXPECT_EQ(17U, red_->Max10MsFramesInAPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AudioEncoderCopyRedTest, CheckSetBitratePropagation) {
|
TEST_F(AudioEncoderCopyRedTest, CheckTargetAudioBitratePropagation) {
|
||||||
EXPECT_CALL(*mock_encoder_, SetTargetBitrate(4711));
|
EXPECT_CALL(*mock_encoder_, OnReceivedTargetAudioBitrate(4711));
|
||||||
red_->SetTargetBitrate(4711);
|
red_->OnReceivedTargetAudioBitrate(4711);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AudioEncoderCopyRedTest, CheckProjectedPacketLossRatePropagation) {
|
TEST_F(AudioEncoderCopyRedTest, CheckPacketLossFractionPropagation) {
|
||||||
EXPECT_CALL(*mock_encoder_, SetProjectedPacketLossRate(0.5));
|
EXPECT_CALL(*mock_encoder_, OnReceivedUplinkPacketLossFraction(0.5));
|
||||||
red_->SetProjectedPacketLossRate(0.5);
|
red_->OnReceivedUplinkPacketLossFraction(0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that the an Encode() call is immediately propagated to the speech
|
// Checks that the an Encode() call is immediately propagated to the speech
|
||||||
|
|||||||
@ -469,7 +469,7 @@ TEST_F(AudioDecoderPcmUTest, EncodeDecode) {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int SetAndGetTargetBitrate(AudioEncoder* audio_encoder, int rate) {
|
int SetAndGetTargetBitrate(AudioEncoder* audio_encoder, int rate) {
|
||||||
audio_encoder->SetTargetBitrate(rate);
|
audio_encoder->OnReceivedTargetAudioBitrate(rate);
|
||||||
return audio_encoder->GetTargetBitrate();
|
return audio_encoder->GetTargetBitrate();
|
||||||
}
|
}
|
||||||
void TestSetAndGetTargetBitratesWithFixedCodec(AudioEncoder* audio_encoder,
|
void TestSetAndGetTargetBitratesWithFixedCodec(AudioEncoder* audio_encoder,
|
||||||
|
|||||||
Reference in New Issue
Block a user