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:
minyue
2016-11-30 06:49:59 -08:00
committed by Commit bot
parent 26bddb92f0
commit 4b9a2cb0d8
14 changed files with 137 additions and 131 deletions

View File

@ -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;
} }

View File

@ -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) {}

View File

@ -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);

View File

@ -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) {

View File

@ -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,

View File

@ -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) {

View File

@ -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,

View File

@ -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

View File

@ -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_;

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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,