Add RELATIVE_ARRIVAL_DELAY histogram mode to DelayManager.
- This mode estimates relative packet arrival delay for each incoming packet and adds that value to the histogram.
- The histogram buckets are 20 milliseconds each instead of whole packets.
- The functionality is enabled with a field trial for experimentation.
Bug: webrtc:10333
Change-Id: I8f7499c56802fc1aa1ced2f5310fdd2ef1403515
Reviewed-on: https://webrtc-review.googlesource.com/c/123923
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Reviewed-by: Minyue Li <minyue@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26871}
diff --git a/modules/audio_coding/neteq/delay_manager_unittest.cc b/modules/audio_coding/neteq/delay_manager_unittest.cc
index b3797e2..7b57324 100644
--- a/modules/audio_coding/neteq/delay_manager_unittest.cc
+++ b/modules/audio_coding/neteq/delay_manager_unittest.cc
@@ -25,19 +25,24 @@
namespace webrtc {
+namespace {
+constexpr int kMaxNumberOfPackets = 240;
+constexpr int kMinDelayMs = 0;
+constexpr int kTimeStepMs = 10;
+constexpr int kFs = 8000;
+constexpr int kFrameSizeMs = 20;
+constexpr int kTsIncrement = kFrameSizeMs * kFs / 1000;
+constexpr int kMaxBufferSizeMs = kMaxNumberOfPackets * kFrameSizeMs;
+constexpr int kDefaultHistogramQuantile = 1020054733;
+constexpr int kMaxIat = 64;
+constexpr int kForgetFactor = 32745;
+} // namespace
+
using ::testing::Return;
using ::testing::_;
class DelayManagerTest : public ::testing::Test {
protected:
- static const int kMaxNumberOfPackets = 240;
- static const int kMinDelayMs = 0;
- static const int kTimeStepMs = 10;
- static const int kFs = 8000;
- static const int kFrameSizeMs = 20;
- static const int kTsIncrement = kFrameSizeMs * kFs / 1000;
- static const int kMaxBufferSizeMs = kMaxNumberOfPackets * kFrameSizeMs;
-
DelayManagerTest();
virtual void SetUp();
virtual void TearDown();
@@ -49,11 +54,13 @@
std::unique_ptr<DelayManager> dm_;
TickTimer tick_timer_;
MockDelayPeakDetector detector_;
- bool use_mock_histogram_ = false;
MockHistogram* mock_histogram_;
uint16_t seq_no_;
uint32_t ts_;
bool enable_rtx_handling_ = false;
+ bool use_mock_histogram_ = false;
+ DelayManager::HistogramMode histogram_mode_ =
+ DelayManager::HistogramMode::INTER_ARRIVAL_TIME;
};
DelayManagerTest::DelayManagerTest()
@@ -68,18 +75,17 @@
void DelayManagerTest::RecreateDelayManager() {
EXPECT_CALL(detector_, Reset()).Times(1);
- std::unique_ptr<Histogram> histogram;
- static const int kMaxIat = 64;
- static const int kForgetFactor = 32745;
if (use_mock_histogram_) {
mock_histogram_ = new MockHistogram(kMaxIat, kForgetFactor);
- histogram.reset(mock_histogram_);
+ std::unique_ptr<Histogram> histogram(mock_histogram_);
+ dm_ = absl::make_unique<DelayManager>(
+ kMaxNumberOfPackets, kMinDelayMs, kDefaultHistogramQuantile,
+ histogram_mode_, enable_rtx_handling_, &detector_, &tick_timer_,
+ std::move(histogram));
} else {
- histogram = absl::make_unique<Histogram>(kMaxIat, kForgetFactor);
+ dm_ = DelayManager::Create(kMaxNumberOfPackets, kMinDelayMs,
+ enable_rtx_handling_, &detector_, &tick_timer_);
}
- dm_.reset(new DelayManager(kMaxNumberOfPackets, kMinDelayMs,
- enable_rtx_handling_, &detector_, &tick_timer_,
- std::move(histogram)));
}
void DelayManagerTest::SetPacketAudioLength(int lengt_ms) {
@@ -577,8 +583,7 @@
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-0/");
RecreateDelayManager();
- EXPECT_EQ(absl::make_optional<int>(0),
- dm_->forced_limit_probability_for_test());
+ EXPECT_EQ(0, dm_->histogram_quantile());
SetPacketAudioLength(kFrameSizeMs);
// First packet arrival.
@@ -599,33 +604,109 @@
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-95/");
RecreateDelayManager();
- EXPECT_EQ(absl::make_optional<int>(1020054733),
- dm_->forced_limit_probability_for_test()); // 1/20 in Q30
+ EXPECT_EQ(kDefaultHistogramQuantile, dm_->histogram_quantile());
}
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-99.95/");
RecreateDelayManager();
- EXPECT_EQ(absl::make_optional<int>(1073204953),
- dm_->forced_limit_probability_for_test()); // 1/2000 in Q30
+ EXPECT_EQ(1073204953, dm_->histogram_quantile()); // 0.9995 in Q30.
}
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Disabled/");
RecreateDelayManager();
- EXPECT_EQ(absl::nullopt, dm_->forced_limit_probability_for_test());
+ EXPECT_EQ(kDefaultHistogramQuantile, dm_->histogram_quantile());
}
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled--1/");
- EXPECT_EQ(absl::nullopt, dm_->forced_limit_probability_for_test());
+ EXPECT_EQ(kDefaultHistogramQuantile, dm_->histogram_quantile());
}
{
test::ScopedFieldTrials field_trial(
"WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-100.1/");
RecreateDelayManager();
- EXPECT_EQ(absl::nullopt, dm_->forced_limit_probability_for_test());
+ EXPECT_EQ(kDefaultHistogramQuantile, dm_->histogram_quantile());
}
}
+TEST_F(DelayManagerTest, DelayHistogramFieldTrial) {
+ {
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqDelayHistogram/Enabled-96-0.998/");
+ RecreateDelayManager();
+ EXPECT_EQ(DelayManager::HistogramMode::RELATIVE_ARRIVAL_DELAY,
+ dm_->histogram_mode());
+ EXPECT_EQ(1030792151, dm_->histogram_quantile()); // 0.96 in Q30.
+ EXPECT_EQ(32702, dm_->histogram_forget_factor()); // 0.998 in Q15.
+ }
+ {
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqDelayHistogram/Enabled-97.5-0.998/");
+ RecreateDelayManager();
+ EXPECT_EQ(DelayManager::HistogramMode::RELATIVE_ARRIVAL_DELAY,
+ dm_->histogram_mode());
+ EXPECT_EQ(1046898278, dm_->histogram_quantile()); // 0.975 in Q30.
+ EXPECT_EQ(32702, dm_->histogram_forget_factor()); // 0.998 in Q15.
+ }
+ {
+ // NetEqDelayHistogram should take precedence over
+ // NetEqForceTargetDelayPercentile.
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqForceTargetDelayPercentile/Enabled-99.95/"
+ "WebRTC-Audio-NetEqDelayHistogram/Enabled-96-0.998/");
+ RecreateDelayManager();
+ EXPECT_EQ(DelayManager::HistogramMode::RELATIVE_ARRIVAL_DELAY,
+ dm_->histogram_mode());
+ EXPECT_EQ(1030792151, dm_->histogram_quantile()); // 0.96 in Q30.
+ EXPECT_EQ(32702, dm_->histogram_forget_factor()); // 0.998 in Q15.
+ }
+ {
+ // Invalid parameters.
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqDelayHistogram/Enabled-96/");
+ RecreateDelayManager();
+ EXPECT_EQ(DelayManager::HistogramMode::RELATIVE_ARRIVAL_DELAY,
+ dm_->histogram_mode());
+ EXPECT_EQ(kDefaultHistogramQuantile,
+ dm_->histogram_quantile()); // 0.95 in Q30.
+ EXPECT_EQ(kForgetFactor, dm_->histogram_forget_factor()); // 0.9993 in Q15.
+ }
+ {
+ test::ScopedFieldTrials field_trial(
+ "WebRTC-Audio-NetEqDelayHistogram/Disabled/");
+ RecreateDelayManager();
+ EXPECT_EQ(DelayManager::HistogramMode::INTER_ARRIVAL_TIME,
+ dm_->histogram_mode());
+ EXPECT_EQ(kDefaultHistogramQuantile,
+ dm_->histogram_quantile()); // 0.95 in Q30.
+ EXPECT_EQ(kForgetFactor, dm_->histogram_forget_factor()); // 0.9993 in Q15.
+ }
+}
+
+TEST_F(DelayManagerTest, RelativeArrivalDelayMode) {
+ histogram_mode_ = DelayManager::HistogramMode::RELATIVE_ARRIVAL_DELAY;
+ use_mock_histogram_ = true;
+ RecreateDelayManager();
+
+ SetPacketAudioLength(kFrameSizeMs);
+ InsertNextPacket();
+
+ IncreaseTime(kFrameSizeMs);
+ EXPECT_CALL(*mock_histogram_, Add(0)); // Not delayed.
+ InsertNextPacket();
+
+ IncreaseTime(2 * kFrameSizeMs);
+ EXPECT_CALL(*mock_histogram_, Add(1)); // 20ms delayed.
+ EXPECT_EQ(0, dm_->Update(seq_no_, ts_, kFs));
+
+ IncreaseTime(2 * kFrameSizeMs);
+ EXPECT_CALL(*mock_histogram_, Add(2)); // 40ms delayed.
+ EXPECT_EQ(0, dm_->Update(seq_no_ + 1, ts_ + kTsIncrement, kFs));
+
+ EXPECT_CALL(*mock_histogram_, Add(1)); // Reordered, 20ms delayed.
+ EXPECT_EQ(0, dm_->Update(seq_no_, ts_, kFs));
+}
+
} // namespace webrtc