From 25edb62a94447bcd5ddb2c0f6f07f3f0c47a7830 Mon Sep 17 00:00:00 2001 From: Jakob Ivarsson Date: Mon, 30 Aug 2021 18:13:18 +0200 Subject: [PATCH] Calculate relative arrival delay for reordered packets. This changes behavior slightly but results in a better delay estimate and cleaner code. Bug: webrtc:10178 Change-Id: If150258bc1ea58149940f17c5660733ff61159c3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/230740 Reviewed-by: Ivo Creusen Commit-Queue: Jakob Ivarsson Cr-Commit-Position: refs/heads/main@{#34883} --- modules/audio_coding/neteq/delay_manager.cc | 40 +++++-------------- modules/audio_coding/neteq/delay_manager.h | 5 +-- .../neteq/delay_manager_unittest.cc | 6 +-- 3 files changed, 14 insertions(+), 37 deletions(-) diff --git a/modules/audio_coding/neteq/delay_manager.cc b/modules/audio_coding/neteq/delay_manager.cc index c244902434..c2509773f1 100644 --- a/modules/audio_coding/neteq/delay_manager.cc +++ b/modules/audio_coding/neteq/delay_manager.cc @@ -35,7 +35,6 @@ constexpr int kMaxBaseMinimumDelayMs = 10000; constexpr int kDelayBuckets = 100; constexpr int kBucketSizeMs = 20; constexpr int kStartDelayMs = 80; -constexpr int kMaxNumReorderedPackets = 5; struct DelayManagerConfig { double quantile = 0.97; @@ -101,8 +100,7 @@ DelayManager::DelayManager(int max_packets_in_buffer, int max_history_ms, const TickTimer* tick_timer, std::unique_ptr histogram) - : first_packet_received_(false), - max_packets_in_buffer_(max_packets_in_buffer), + : max_packets_in_buffer_(max_packets_in_buffer), histogram_(std::move(histogram)), histogram_quantile_(histogram_quantile), tick_timer_(tick_timer), @@ -112,8 +110,7 @@ DelayManager::DelayManager(int max_packets_in_buffer, effective_minimum_delay_ms_(base_minimum_delay_ms), minimum_delay_ms_(0), maximum_delay_ms_(0), - target_level_ms_(kStartDelayMs), - last_timestamp_(0) { + target_level_ms_(kStartDelayMs) { RTC_CHECK(histogram_); RTC_DCHECK_GE(base_minimum_delay_ms_, 0); @@ -144,31 +141,23 @@ absl::optional DelayManager::Update(uint32_t timestamp, return absl::nullopt; } - if (!first_packet_received_ || reset) { + if (!last_timestamp_ || reset) { // Restart relative delay esimation from this packet. delay_history_.clear(); packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); last_timestamp_ = timestamp; - first_packet_received_ = true; - num_reordered_packets_ = 0; resample_stopwatch_ = tick_timer_->GetNewStopwatch(); max_delay_in_interval_ms_ = 0; return absl::nullopt; } const int expected_iat_ms = - 1000ll * static_cast(timestamp - last_timestamp_) / + 1000ll * static_cast(timestamp - *last_timestamp_) / sample_rate_hz; const int iat_ms = packet_iat_stopwatch_->ElapsedMs(); const int iat_delay_ms = iat_ms - expected_iat_ms; - int relative_delay; - bool reordered = !IsNewerTimestamp(timestamp, last_timestamp_); - if (reordered) { - relative_delay = std::max(iat_delay_ms, 0); - } else { - UpdateDelayHistory(iat_delay_ms, timestamp, sample_rate_hz); - relative_delay = CalculateRelativePacketArrivalDelay(); - } + UpdateDelayHistory(iat_delay_ms, timestamp, sample_rate_hz); + int relative_delay = CalculateRelativePacketArrivalDelay(); absl::optional histogram_update; if (resample_interval_ms_) { @@ -207,16 +196,6 @@ absl::optional DelayManager::Update(uint32_t timestamp, } // Prepare for next packet arrival. - if (reordered) { - // Allow a small number of reordered packets before resetting the delay - // estimation. - if (num_reordered_packets_ < kMaxNumReorderedPackets) { - ++num_reordered_packets_; - return relative_delay; - } - delay_history_.clear(); - } - num_reordered_packets_ = 0; packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); last_timestamp_ = timestamp; return relative_delay; @@ -229,8 +208,8 @@ void DelayManager::UpdateDelayHistory(int iat_delay_ms, delay.iat_delay_ms = iat_delay_ms; delay.timestamp = timestamp; delay_history_.push_back(delay); - while (timestamp - delay_history_.front().timestamp > - static_cast(max_history_ms_ * sample_rate_hz / 1000)) { + while (static_cast(timestamp - delay_history_.front().timestamp) > + max_history_ms_ * sample_rate_hz / 1000) { delay_history_.pop_front(); } } @@ -263,8 +242,7 @@ void DelayManager::Reset() { delay_history_.clear(); target_level_ms_ = kStartDelayMs; packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); - first_packet_received_ = false; - num_reordered_packets_ = 0; + last_timestamp_ = absl::nullopt; resample_stopwatch_ = tick_timer_->GetNewStopwatch(); max_delay_in_interval_ms_ = 0; } diff --git a/modules/audio_coding/neteq/delay_manager.h b/modules/audio_coding/neteq/delay_manager.h index cb35274424..cc9820393c 100644 --- a/modules/audio_coding/neteq/delay_manager.h +++ b/modules/audio_coding/neteq/delay_manager.h @@ -101,7 +101,6 @@ class DelayManager { bool IsValidBaseMinimumDelay(int delay_ms) const; - bool first_packet_received_; // TODO(jakobi): set maximum buffer delay instead of number of packets. const int max_packets_in_buffer_; std::unique_ptr histogram_; @@ -119,8 +118,8 @@ class DelayManager { std::unique_ptr packet_iat_stopwatch_; // Time elapsed since last packet. int target_level_ms_; // Currently preferred buffer level. - uint32_t last_timestamp_; // Timestamp for the last received packet. - int num_reordered_packets_ = 0; + absl::optional + last_timestamp_; // Timestamp for the last received packet. int max_delay_in_interval_ms_ = 0; std::unique_ptr resample_stopwatch_; diff --git a/modules/audio_coding/neteq/delay_manager_unittest.cc b/modules/audio_coding/neteq/delay_manager_unittest.cc index 9678151dfa..427386e06d 100644 --- a/modules/audio_coding/neteq/delay_manager_unittest.cc +++ b/modules/audio_coding/neteq/delay_manager_unittest.cc @@ -400,12 +400,12 @@ TEST_F(DelayManagerTest, RelativeArrivalDelay) { EXPECT_CALL(*mock_histogram_, Add(1)); // 20ms delayed. dm_->Update(ts_, kFs); + EXPECT_CALL(*mock_histogram_, Add(3)); // Reordered, 60ms delayed. + dm_->Update(ts_ - 2 * kTsIncrement, kFs); + IncreaseTime(2 * kFrameSizeMs); EXPECT_CALL(*mock_histogram_, Add(2)); // 40ms delayed. dm_->Update(ts_ + kTsIncrement, kFs); - - EXPECT_CALL(*mock_histogram_, Add(1)); // Reordered, 20ms delayed. - dm_->Update(ts_, kFs); } TEST_F(DelayManagerTest, ReorderedPackets) {