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:
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user