Adding field trial to force target level percentile in NetEQ.

Bug: webrtc:9822
Change-Id: I636f75de10851729825311ee5783e836f3b583cd
Reviewed-on: https://webrtc-review.googlesource.com/c/101220
Commit-Queue: Minyue Li <minyue@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24975}
This commit is contained in:
Minyue Li
2018-10-04 11:31:03 +02:00
committed by Commit Bot
parent 2ea9af2275
commit 002fbb8c7d
3 changed files with 111 additions and 15 deletions

View File

@ -23,6 +23,41 @@
#include "rtc_base/numerics/safe_conversions.h"
#include "system_wrappers/include/field_trial.h"
namespace {
constexpr int kLimitProbability = 53687091; // 1/20 in Q30.
constexpr int kLimitProbabilityStreaming = 536871; // 1/2000 in Q30.
constexpr int kMaxStreamingPeakPeriodMs = 600000; // 10 minutes in ms.
constexpr int kCumulativeSumDrift = 2; // Drift term for cumulative sum
// |iat_cumulative_sum_|.
// Steady-state forgetting factor for |iat_vector_|, 0.9993 in Q15.
constexpr int kIatFactor_ = 32745;
constexpr int kMaxIat = 64; // Max inter-arrival time to register.
absl::optional<int> GetForcedLimitProbability() {
constexpr char kForceTargetDelayPercentileFieldTrial[] =
"WebRTC-Audio-NetEqForceTargetDelayPercentile";
const bool use_forced_target_delay_percentile =
webrtc::field_trial::IsEnabled(kForceTargetDelayPercentileFieldTrial);
if (use_forced_target_delay_percentile) {
const std::string field_trial_string = webrtc::field_trial::FindFullName(
kForceTargetDelayPercentileFieldTrial);
double percentile = -1.0;
if (sscanf(field_trial_string.c_str(), "Enabled-%lf", &percentile) == 1 &&
percentile >= 0.0 && percentile <= 100.0) {
return absl::make_optional<int>(static_cast<int>(
(1 << 30) * (100.0 - percentile) / 100.0 + 0.5)); // in Q30.
} else {
RTC_LOG(LS_WARNING) << "Invalid parameter for "
<< kForceTargetDelayPercentileFieldTrial
<< ", ignored.";
}
}
return absl::nullopt;
}
} // namespace
namespace webrtc {
DelayManager::DelayManager(size_t max_packets_in_buffer,
@ -46,8 +81,10 @@ DelayManager::DelayManager(size_t max_packets_in_buffer,
peak_detector_(*peak_detector),
last_pack_cng_or_dtmf_(1),
frame_length_change_experiment_(
field_trial::IsEnabled("WebRTC-Audio-NetEqFramelengthExperiment")) {
field_trial::IsEnabled("WebRTC-Audio-NetEqFramelengthExperiment")),
forced_limit_probability_(GetForcedLimitProbability()) {
assert(peak_detector); // Should never be NULL.
Reset();
}
@ -253,7 +290,7 @@ void DelayManager::LimitTargetLevel() {
}
int DelayManager::CalculateTargetLevel(int iat_packets) {
int limit_probability = kLimitProbability;
int limit_probability = forced_limit_probability_.value_or(kLimitProbability);
if (streaming_mode_) {
limit_probability = kLimitProbabilityStreaming;
}

View File

@ -16,6 +16,7 @@
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "modules/audio_coding/neteq/tick_timer.h"
#include "rtc_base/constructormagic.h"
@ -114,16 +115,12 @@ class DelayManager {
virtual int last_pack_cng_or_dtmf() const;
virtual void set_last_pack_cng_or_dtmf(int value);
private:
static const int kLimitProbability = 53687091; // 1/20 in Q30.
static const int kLimitProbabilityStreaming = 536871; // 1/2000 in Q30.
static const int kMaxStreamingPeakPeriodMs = 600000; // 10 minutes in ms.
static const int kCumulativeSumDrift = 2; // Drift term for cumulative sum
// |iat_cumulative_sum_|.
// Steady-state forgetting factor for |iat_vector_|, 0.9993 in Q15.
static const int kIatFactor_ = 32745;
static const int kMaxIat = 64; // Max inter-arrival time to register.
// This accessor is only intended for testing purposes.
const absl::optional<int>& forced_limit_probability_for_test() const {
return forced_limit_probability_;
}
private:
// Sets |iat_vector_| to the default start distribution and sets the
// |base_target_level_| and |target_level_| to the corresponding values.
void ResetHistogram();
@ -168,6 +165,7 @@ class DelayManager {
DelayPeakDetector& peak_detector_;
int last_pack_cng_or_dtmf_;
const bool frame_length_change_experiment_;
const absl::optional<int> forced_limit_probability_;
RTC_DISALLOW_COPY_AND_ASSIGN(DelayManager);
};

View File

@ -15,6 +15,7 @@
#include <math.h>
#include "modules/audio_coding/neteq/mock/mock_delay_peak_detector.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
@ -34,11 +35,12 @@ class DelayManagerTest : public ::testing::Test {
DelayManagerTest();
virtual void SetUp();
virtual void TearDown();
void RecreateDelayManager();
void SetPacketAudioLength(int lengt_ms);
void InsertNextPacket();
void IncreaseTime(int inc_ms);
DelayManager* dm_;
std::unique_ptr<DelayManager> dm_;
TickTimer tick_timer_;
MockDelayPeakDetector detector_;
uint16_t seq_no_;
@ -46,11 +48,15 @@ class DelayManagerTest : public ::testing::Test {
};
DelayManagerTest::DelayManagerTest()
: dm_(NULL), detector_(&tick_timer_), seq_no_(0x1234), ts_(0x12345678) {}
: dm_(nullptr), detector_(&tick_timer_), seq_no_(0x1234), ts_(0x12345678) {}
void DelayManagerTest::SetUp() {
RecreateDelayManager();
}
void DelayManagerTest::RecreateDelayManager() {
EXPECT_CALL(detector_, Reset()).Times(1);
dm_ = new DelayManager(kMaxNumberOfPackets, &detector_, &tick_timer_);
dm_.reset(new DelayManager(kMaxNumberOfPackets, &detector_, &tick_timer_));
}
void DelayManagerTest::SetPacketAudioLength(int lengt_ms) {
@ -71,7 +77,6 @@ void DelayManagerTest::IncreaseTime(int inc_ms) {
}
void DelayManagerTest::TearDown() {
EXPECT_CALL(detector_, Die());
delete dm_;
}
TEST_F(DelayManagerTest, CreateAndDestroy) {
@ -326,6 +331,61 @@ TEST_F(DelayManagerTest, Failures) {
EXPECT_FALSE(dm_->SetMaximumDelay(60));
}
TEST_F(DelayManagerTest, TargetDelayGreaterThanOne) {
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-0/");
RecreateDelayManager();
EXPECT_EQ(absl::make_optional<int>(1 << 30),
dm_->forced_limit_probability_for_test());
SetPacketAudioLength(kFrameSizeMs);
// First packet arrival.
InsertNextPacket();
// Advance time by one frame size.
IncreaseTime(kFrameSizeMs);
// Second packet arrival.
// Expect detector update method to be called once with inter-arrival time
// equal to 1 packet.
EXPECT_CALL(detector_, Update(1, 1)).WillOnce(Return(false));
InsertNextPacket();
constexpr int kExpectedTarget = 1;
EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel()); // In Q8.
}
TEST_F(DelayManagerTest, ForcedTargetDelayPercentile) {
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-95/");
RecreateDelayManager();
EXPECT_EQ(absl::make_optional<int>(53687091),
dm_->forced_limit_probability_for_test()); // 1/20 in Q30
}
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-99.95/");
RecreateDelayManager();
EXPECT_EQ(absl::make_optional<int>(536871),
dm_->forced_limit_probability_for_test()); // 1/2000 in Q30
}
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Disabled/");
RecreateDelayManager();
EXPECT_EQ(absl::nullopt, dm_->forced_limit_probability_for_test());
}
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled--1/");
EXPECT_EQ(absl::nullopt, dm_->forced_limit_probability_for_test());
}
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-100.1/");
RecreateDelayManager();
EXPECT_EQ(absl::nullopt, dm_->forced_limit_probability_for_test());
}
}
// Test if the histogram is stretched correctly if the packet size is decreased.
TEST(DelayManagerIATScalingTest, StretchTest) {
using IATVector = DelayManager::IATVector;
@ -437,4 +497,5 @@ TEST(DelayManagerIATScalingTest, OverflowTest) {
scaled_iat = DelayManager::ScaleHistogram(iat, 20, 60);
EXPECT_EQ(scaled_iat, expected_result);
}
} // namespace webrtc