Create field trial for setting a minimum value for Opus encoder packet loss rate

Bug: webrtc:9848
Change-Id: I0663ee3af7729a220de7aff08cd74545e1a7409a
Reviewed-on: https://webrtc-review.googlesource.com/c/104800
Reviewed-by: Minyue Li <minyue@webrtc.org>
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25081}
This commit is contained in:
Jakob Ivarsson
2018-10-10 10:15:06 +02:00
committed by Commit Bot
parent f08dd9db34
commit 88b68ace17
3 changed files with 70 additions and 0 deletions

View File

@ -214,6 +214,27 @@ int GetBitrateBps(const AudioEncoderOpusConfig& config) {
return *config.bitrate_bps;
}
float GetMinPacketLossRate() {
constexpr char kPacketLossFieldTrial[] = "WebRTC-Audio-OpusMinPacketLossRate";
const bool use_opus_min_packet_loss_rate =
webrtc::field_trial::IsEnabled(kPacketLossFieldTrial);
if (use_opus_min_packet_loss_rate) {
const std::string field_trial_string =
webrtc::field_trial::FindFullName(kPacketLossFieldTrial);
constexpr int kDefaultMinPacketLossRate = 1;
int value = kDefaultMinPacketLossRate;
if (sscanf(field_trial_string.c_str(), "Enabled-%d", &value) == 1 &&
(value < 0 || value > 100)) {
RTC_LOG(LS_WARNING) << "Invalid parameter for " << kPacketLossFieldTrial
<< ", using default value: "
<< kDefaultMinPacketLossRate;
value = kDefaultMinPacketLossRate;
}
return static_cast<float>(value) / 100;
}
return 0.0;
}
} // namespace
void AudioEncoderOpusImpl::AppendSupportedEncoders(
@ -402,6 +423,7 @@ AudioEncoderOpusImpl::AudioEncoderOpusImpl(
webrtc::field_trial::IsEnabled("WebRTC-AdjustOpusBandwidth")),
bitrate_changed_(true),
packet_loss_rate_(0.0),
min_packet_loss_rate_(GetMinPacketLossRate()),
inst_(nullptr),
packet_loss_fraction_smoother_(new PacketLossFractionSmoother()),
audio_network_adaptor_creator_(audio_network_adaptor_creator),
@ -414,6 +436,7 @@ AudioEncoderOpusImpl::AudioEncoderOpusImpl(
RTC_CHECK(config.payload_type == -1 || config.payload_type == payload_type);
RTC_CHECK(RecreateEncoderInstance(config));
SetProjectedPacketLossRate(packet_loss_rate_);
}
AudioEncoderOpusImpl::AudioEncoderOpusImpl(const CodecInst& codec_inst)
@ -739,6 +762,7 @@ void AudioEncoderOpusImpl::SetNumChannelsToEncode(
void AudioEncoderOpusImpl::SetProjectedPacketLossRate(float fraction) {
float opt_loss_rate = OptimizePacketLossRate(fraction, packet_loss_rate_);
opt_loss_rate = std::max(opt_loss_rate, min_packet_loss_rate_);
if (packet_loss_rate_ != opt_loss_rate) {
packet_loss_rate_ = opt_loss_rate;
RTC_CHECK_EQ(

View File

@ -158,6 +158,7 @@ class AudioEncoderOpusImpl final : public AudioEncoder {
const bool adjust_bandwidth_;
bool bitrate_changed_;
float packet_loss_rate_;
const float min_packet_loss_rate_;
std::vector<int16_t> input_buffer_;
OpusEncInst* inst_;
uint32_t first_timestamp_in_buffer_;

View File

@ -272,6 +272,28 @@ TEST(AudioEncoderOpusTest, PacketLossRateOptimized) {
// clang-format on
}
TEST(AudioEncoderOpusTest, PacketLossRateLowerBounded) {
test::ScopedFieldTrials override_field_trails(
"WebRTC-Audio-OpusMinPacketLossRate/Enabled-5/");
auto states = CreateCodec(1);
auto I = [](float a, float b) { return IntervalSteps(a, b, 10); };
constexpr float eps = 1e-8f;
// clang-format off
TestSetPacketLossRate(states.get(), I(0.00f , 0.01f - eps), 0.05f);
TestSetPacketLossRate(states.get(), I(0.01f + eps, 0.06f - eps), 0.05f);
TestSetPacketLossRate(states.get(), I(0.06f + eps, 0.11f - eps), 0.05f);
TestSetPacketLossRate(states.get(), I(0.11f + eps, 0.22f - eps), 0.10f);
TestSetPacketLossRate(states.get(), I(0.22f + eps, 1.00f ), 0.20f);
TestSetPacketLossRate(states.get(), I(1.00f , 0.18f + eps), 0.20f);
TestSetPacketLossRate(states.get(), I(0.18f - eps, 0.09f + eps), 0.10f);
TestSetPacketLossRate(states.get(), I(0.09f - eps, 0.04f + eps), 0.05f);
TestSetPacketLossRate(states.get(), I(0.04f - eps, 0.01f + eps), 0.05f);
TestSetPacketLossRate(states.get(), I(0.01f - eps, 0.00f ), 0.05f);
// clang-format on
}
TEST(AudioEncoderOpusTest, SetReceiverFrameLengthRange) {
auto states = CreateCodec(2);
// Before calling to |SetReceiverFrameLengthRange|,
@ -446,6 +468,29 @@ TEST(AudioEncoderOpusTest, BitrateBounded) {
EXPECT_EQ(kMaxBitrateBps, states->encoder->GetTargetBitrate());
}
TEST(AudioEncoderOpusTest, MinPacketLossRate) {
constexpr float kDefaultMinPacketLossRate = 0.01;
{
test::ScopedFieldTrials override_field_trails(
"WebRTC-Audio-OpusMinPacketLossRate/Enabled/");
auto states = CreateCodec(1);
EXPECT_EQ(kDefaultMinPacketLossRate, states->encoder->packet_loss_rate());
}
{
test::ScopedFieldTrials override_field_trails(
"WebRTC-Audio-OpusMinPacketLossRate/Enabled-200/");
auto states = CreateCodec(1);
EXPECT_EQ(kDefaultMinPacketLossRate, states->encoder->packet_loss_rate());
}
{
test::ScopedFieldTrials override_field_trails(
"WebRTC-Audio-OpusMinPacketLossRate/Enabled-50/");
constexpr float kMinPacketLossRate = 0.5;
auto states = CreateCodec(1);
EXPECT_EQ(kMinPacketLossRate, states->encoder->packet_loss_rate());
}
}
// Verifies that the complexity adaptation in the config works as intended.
TEST(AudioEncoderOpusTest, ConfigComplexityAdaptation) {
AudioEncoderOpusConfig config;