Reland "Reland "Refactor NetEq delay manager logic.""
This is a reland of 2a7c57c34f323ee1977f6e7809ee23bfcf9a7459
Original change's description:
> Reland "Refactor NetEq delay manager logic."
>
> This is a reland of f8e62fcb14e37a5be4f1e4f599d34c8483fea8e9
>
> Original change's description:
> > Refactor NetEq delay manager logic.
> >
> > - Removes dependence on sequence number for calculating target delay.
> > - Changes target delay unit to milliseconds instead of number of
> > packets.
> > - Moves acceleration/preemptive expand thresholds to decision logic.
> > Tests for this will be added in a follow up cl.
> >
> > Bug: webrtc:10333
> > Change-Id: If690aae4abf41ef1d9353f0ff01fb7d121cf8a26
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/186265
> > Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org>
> > Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> > Cr-Commit-Position: refs/heads/master@{#32326}
>
> Bug: webrtc:10333
> Change-Id: Iad5e7063f63b84762959ee5b412f5f14a7b2cd06
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/186943
> Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org>
> Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#32332}
Bug: webrtc:10333
Change-Id: If2244ee9a3d56a0cfa9b602e7bdf448dc6340147
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/187356
Reviewed-by: Ivo Creusen <ivoc@webrtc.org>
Commit-Queue: Jakob Ivarsson <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32367}
diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
index 4e7493e..590dc30 100644
--- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc
+++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc
@@ -939,58 +939,58 @@
defined(WEBRTC_CODEC_ILBC)
TEST_F(AcmReceiverBitExactnessOldApi, 8kHzOutput) {
std::string others_checksum_reference =
- GetCPUInfo(kAVX2) != 0 ? "6edbfe69b965a8687b8744ed1b8eb5a7"
- : "6c204b289486b0695b08a9e94fab1948";
+ GetCPUInfo(kAVX2) != 0 ? "1d7b784031599e2c01a3f575f8439f2f"
+ : "c119fda4ea2c119ff2a720fd0c289071";
std::string win64_checksum_reference =
GetCPUInfo(kAVX2) != 0 ? "405a50f0bcb8827e20aa944299fc59f6"
- : "ff5ffee2ee92f8fe61d9f2010b8a68a3";
+ : "38e70d4e186f8e1a56b929fafcb7c379";
Run(8000,
PlatformChecksum(others_checksum_reference, win64_checksum_reference,
- "53494a96f3db4a5b07d723e0cbac0ad7",
+ "3b03e41731e1cef5ae2b9f9618660b42",
"4598140b5e4f7ee66c5adad609e65a3e",
- "516c2859126ea4913f30d51af4a4f3dc"));
+ "da7e76687c8c0a9509cd1d57ee1aba3b"));
}
TEST_F(AcmReceiverBitExactnessOldApi, 16kHzOutput) {
std::string others_checksum_reference =
- GetCPUInfo(kAVX2) != 0 ? "295f031e051f1770b4ab4107dba768b5"
- : "226dbdbce2354399c6df05371042cda3";
+ GetCPUInfo(kAVX2) != 0 ? "8884d910e443c244d8593c2e3cef5e63"
+ : "36dc8c0532ba0efa099e2b6a689cde40";
std::string win64_checksum_reference =
GetCPUInfo(kAVX2) != 0 ? "58fd62a5c49ee513f9fa6fe7dbf62c97"
- : "9c80bf5ec496c41ce8112e1523bf8c83";
+ : "07e4b388168e273fa19da0a167aff782";
Run(16000,
PlatformChecksum(others_checksum_reference, win64_checksum_reference,
- "11a6f170fdaffa81a2948af121f370af",
+ "06b08d14a72f6e7c72840b1cc9ad204d",
"f2aad418af974a3b1694d5ae5cc2c3c7",
- "6133301a18be95c416984182816d859f"));
+ "1d5f9a93f3975e7e491373b81eb5fd14"));
}
TEST_F(AcmReceiverBitExactnessOldApi, 32kHzOutput) {
std::string others_checksum_reference =
- GetCPUInfo(kAVX2) != 0 ? "2895e5ab3146eaa78fa6843ed60e7e37"
- : "f94665cc0e904d5d5cf0394e30ee4edd";
+ GetCPUInfo(kAVX2) != 0 ? "73f4fe21996c0af495e2c47e3708e519"
+ : "c848ce9002d3825056a1eac2a067c0d3";
std::string win64_checksum_reference =
GetCPUInfo(kAVX2) != 0 ? "04ce6a1dac5ffdd8438d804623d0132f"
- : "697934bcf0849f80d76ce20854161220";
+ : "0e705f6844c75fd57a84734f7c30af87";
Run(32000,
PlatformChecksum(others_checksum_reference, win64_checksum_reference,
- "3609aa5288c1d512e8e652ceabecb495",
+ "c18e98e5701ec91bba5c026b720d1790",
"100869c8dcde51346c2073e52a272d98",
- "55363bc9cdda6464a58044919157827b"));
+ "e35df943bfa3ca32e86b26bf1e37ed8f"));
}
TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutput) {
std::string others_checksum_reference =
- GetCPUInfo(kAVX2) != 0 ? "640bca210e1b8dd229224d2a0c79ff1f"
- : "2955d0b83602541fd92d9b820ebce68d";
+ GetCPUInfo(kAVX2) != 0 ? "884243f7e1476931e93eda5de88d1326"
+ : "ba0f66d538487bba377e721cfac62d1e";
std::string win64_checksum_reference =
GetCPUInfo(kAVX2) != 0 ? "f59833d9b0924f4b0704707dd3589f80"
- : "f4a8386a6a49439ced60ed9a7c7f75fd";
+ : "6a480541fb86faa95c7563b9de08104d";
Run(48000,
PlatformChecksum(others_checksum_reference, win64_checksum_reference,
- "d8169dfeba708b5212bdc365e08aee9d",
+ "30e617e4b3c9ba1979d1b2e8eba3519b",
"bd44bf97e7899186532f91235cef444d",
- "47594deaab5d9166cfbf577203b2563e"));
+ "90158462a1853b1de50873eebd68dba7"));
}
TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) {
@@ -1069,16 +1069,16 @@
rtc::scoped_refptr<rtc::RefCountedObject<ADFactory>> factory(
new rtc::RefCountedObject<ADFactory>);
std::string others_checksum_reference =
- GetCPUInfo(kAVX2) != 0 ? "640bca210e1b8dd229224d2a0c79ff1f"
- : "2955d0b83602541fd92d9b820ebce68d";
+ GetCPUInfo(kAVX2) != 0 ? "884243f7e1476931e93eda5de88d1326"
+ : "ba0f66d538487bba377e721cfac62d1e";
std::string win64_checksum_reference =
GetCPUInfo(kAVX2) != 0 ? "f59833d9b0924f4b0704707dd3589f80"
- : "f4a8386a6a49439ced60ed9a7c7f75fd";
+ : "6a480541fb86faa95c7563b9de08104d";
Run(48000,
PlatformChecksum(others_checksum_reference, win64_checksum_reference,
- "d8169dfeba708b5212bdc365e08aee9d",
+ "30e617e4b3c9ba1979d1b2e8eba3519b",
"bd44bf97e7899186532f91235cef444d",
- "47594deaab5d9166cfbf577203b2563e"),
+ "90158462a1853b1de50873eebd68dba7"),
factory, [](AudioCodingModule* acm) {
acm->SetReceiveCodecs({{0, {"MockPCMu", 8000, 1}},
{103, {"ISAC", 16000, 1}},
@@ -1312,11 +1312,11 @@
TEST_F(AcmSenderBitExactnessOldApi, IsacWb60ms) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("ISAC", 16000, 1, 103, 960, 960));
Run(AcmReceiverBitExactnessOldApi::PlatformChecksum(
- "f59760fa000991ee5fa81f2e607db254",
- "986aa16d7097a26e32e212e39ec58517",
+ "1ad29139a04782a33daad8c2b9b35875",
+ "14d63c5f08127d280e722e3191b73bdd",
"9a81e467eb1485f84aca796f8ea65011",
"ef75e900e6f375e3061163c53fd09a63",
- "f59760fa000991ee5fa81f2e607db254"),
+ "1ad29139a04782a33daad8c2b9b35875"),
AcmReceiverBitExactnessOldApi::PlatformChecksum(
"9e0a0ab743ad987b55b8e14802769c56",
"ebe04a819d3a9d83a83a17f271e1139a",
@@ -1349,37 +1349,37 @@
TEST_F(AcmSenderBitExactnessOldApi, Pcm16_8000khz_10ms) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 1, 107, 80, 80));
- Run("de4a98e1406f8b798d99cd0704e862e2", "c1edd36339ce0326cc4550041ad719a0",
+ Run("15396f66b5b0ab6842e151c807395e4c", "c1edd36339ce0326cc4550041ad719a0",
100, test::AcmReceiveTestOldApi::kMonoOutput);
}
TEST_F(AcmSenderBitExactnessOldApi, Pcm16_16000khz_10ms) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 16000, 1, 108, 160, 160));
- Run("ae646d7b68384a1269cc080dd4501916", "ad786526383178b08d80d6eee06e9bad",
+ Run("54ae004529874c2b362c7f0ccd19cb99", "ad786526383178b08d80d6eee06e9bad",
100, test::AcmReceiveTestOldApi::kMonoOutput);
}
TEST_F(AcmSenderBitExactnessOldApi, Pcm16_32000khz_10ms) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 32000, 1, 109, 320, 320));
- Run("7fe325e8fbaf755e3c5df0b11a4774fb", "5ef82ea885e922263606c6fdbc49f651",
+ Run("d6a4a68b8c838dcc1e7ae7136467cdf0", "5ef82ea885e922263606c6fdbc49f651",
100, test::AcmReceiveTestOldApi::kMonoOutput);
}
TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_8000khz_10ms) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 8000, 2, 111, 80, 80));
- Run("fb263b74e7ac3de915474d77e4744ceb", "62ce5adb0d4965d0a52ec98ae7f98974",
+ Run("6b011dab43e3a8a46ccff7e4412ed8a2", "62ce5adb0d4965d0a52ec98ae7f98974",
100, test::AcmReceiveTestOldApi::kStereoOutput);
}
TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_16000khz_10ms) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 16000, 2, 112, 160, 160));
- Run("d09e9239553649d7ac93e19d304281fd", "41ca8edac4b8c71cd54fd9f25ec14870",
+ Run("17fc9854358bfe0419408290664bd78e", "41ca8edac4b8c71cd54fd9f25ec14870",
100, test::AcmReceiveTestOldApi::kStereoOutput);
}
TEST_F(AcmSenderBitExactnessOldApi, Pcm16_stereo_32000khz_10ms) {
ASSERT_NO_FATAL_FAILURE(SetUpTest("L16", 32000, 2, 113, 320, 320));
- Run("5f025d4f390982cc26b3d92fe02e3044", "50e58502fb04421bf5b857dda4c96879",
+ Run("9ac9a1f64d55da2fc9f3167181cc511d", "50e58502fb04421bf5b857dda4c96879",
100, test::AcmReceiveTestOldApi::kStereoOutput);
}
diff --git a/modules/audio_coding/neteq/buffer_level_filter.cc b/modules/audio_coding/neteq/buffer_level_filter.cc
index d238665..7ad0065 100644
--- a/modules/audio_coding/neteq/buffer_level_filter.cc
+++ b/modules/audio_coding/neteq/buffer_level_filter.cc
@@ -45,12 +45,12 @@
filtered_current_level - (int64_t{time_stretched_samples} * (1 << 8))));
}
-void BufferLevelFilter::SetTargetBufferLevel(int target_buffer_level) {
- if (target_buffer_level <= 1) {
+void BufferLevelFilter::SetTargetBufferLevel(int target_buffer_level_ms) {
+ if (target_buffer_level_ms <= 20) {
level_factor_ = 251;
- } else if (target_buffer_level <= 3) {
+ } else if (target_buffer_level_ms <= 60) {
level_factor_ = 252;
- } else if (target_buffer_level <= 7) {
+ } else if (target_buffer_level_ms <= 140) {
level_factor_ = 253;
} else {
level_factor_ = 254;
diff --git a/modules/audio_coding/neteq/buffer_level_filter.h b/modules/audio_coding/neteq/buffer_level_filter.h
index 6dd4249..bb31856 100644
--- a/modules/audio_coding/neteq/buffer_level_filter.h
+++ b/modules/audio_coding/neteq/buffer_level_filter.h
@@ -23,15 +23,13 @@
virtual ~BufferLevelFilter() {}
virtual void Reset();
- // Updates the filter. Current buffer size is |buffer_size_packets| (Q0).
+ // Updates the filter. Current buffer size is |buffer_size_samples|.
// |time_stretched_samples| is subtracted from the filtered value (thus
// bypassing the filter operation).
virtual void Update(size_t buffer_size_samples, int time_stretched_samples);
- // Set the current target buffer level in number of packets (obtained from
- // DelayManager::base_target_level()). Used to select the appropriate
- // filter coefficient.
- virtual void SetTargetBufferLevel(int target_buffer_level_packets);
+ // The target level is used to select the appropriate filter coefficient.
+ virtual void SetTargetBufferLevel(int target_buffer_level_ms);
// Returns filtered current level in number of samples.
virtual int filtered_current_level() const {
diff --git a/modules/audio_coding/neteq/buffer_level_filter_unittest.cc b/modules/audio_coding/neteq/buffer_level_filter_unittest.cc
index bc42595..63fc83b 100644
--- a/modules/audio_coding/neteq/buffer_level_filter_unittest.cc
+++ b/modules/audio_coding/neteq/buffer_level_filter_unittest.cc
@@ -30,7 +30,7 @@
for (int times = 10; times <= 50; times += 10) {
for (int value = 100; value <= 200; value += 10) {
filter.Reset();
- filter.SetTargetBufferLevel(1); // Makes filter coefficient 251/256.
+ filter.SetTargetBufferLevel(20); // Makes filter coefficient 251/256.
rtc::StringBuilder ss;
ss << "times = " << times << ", value = " << value;
SCOPED_TRACE(ss.str()); // Print out the parameter values on failure.
@@ -57,7 +57,7 @@
const int kTimes = 10;
const int kValue = 100;
- filter.SetTargetBufferLevel(3); // Makes filter coefficient 252/256.
+ filter.SetTargetBufferLevel(60); // Makes filter coefficient 252/256.
for (int i = 0; i < kTimes; ++i) {
filter.Update(kValue, 0 /* time_stretched_samples */);
}
@@ -67,7 +67,7 @@
EXPECT_EQ(expected_value, filter.filtered_current_level());
filter.Reset();
- filter.SetTargetBufferLevel(7); // Makes filter coefficient 253/256.
+ filter.SetTargetBufferLevel(140); // Makes filter coefficient 253/256.
for (int i = 0; i < kTimes; ++i) {
filter.Update(kValue, 0 /* time_stretched_samples */);
}
@@ -77,7 +77,7 @@
EXPECT_EQ(expected_value, filter.filtered_current_level());
filter.Reset();
- filter.SetTargetBufferLevel(8); // Makes filter coefficient 254/256.
+ filter.SetTargetBufferLevel(160); // Makes filter coefficient 254/256.
for (int i = 0; i < kTimes; ++i) {
filter.Update(kValue, 0 /* time_stretched_samples */);
}
@@ -89,7 +89,7 @@
TEST(BufferLevelFilter, TimeStretchedSamples) {
BufferLevelFilter filter;
- filter.SetTargetBufferLevel(1); // Makes filter coefficient 251/256.
+ filter.SetTargetBufferLevel(20); // Makes filter coefficient 251/256.
// Update 10 times with value 100.
const int kTimes = 10;
const int kValue = 100;
diff --git a/modules/audio_coding/neteq/decision_logic.cc b/modules/audio_coding/neteq/decision_logic.cc
index 8e1ffaf..a4de9b8 100644
--- a/modules/audio_coding/neteq/decision_logic.cc
+++ b/modules/audio_coding/neteq/decision_logic.cc
@@ -27,6 +27,7 @@
constexpr int kPostponeDecodingLevel = 50;
constexpr int kDefaultTargetLevelWindowMs = 100;
+constexpr int kDecelerationTargetLevelOffsetMs = 85;
} // namespace
@@ -35,7 +36,6 @@
DecisionLogic::DecisionLogic(NetEqController::Config config)
: delay_manager_(DelayManager::Create(config.max_packets_in_buffer,
config.base_min_delay_ms,
- config.enable_rtx_handling,
config.tick_timer)),
tick_timer_(config.tick_timer),
disallow_time_stretching_(!config.allow_time_stretching),
@@ -67,6 +67,7 @@
packet_length_samples_ = 0;
sample_memory_ = 0;
prev_time_scale_ = false;
+ last_pack_cng_or_dtmf_ = true;
timescale_countdown_.reset();
num_consecutive_expands_ = 0;
time_stretched_cn_samples_ = 0;
@@ -76,6 +77,7 @@
packet_length_samples_ = 0;
sample_memory_ = 0;
prev_time_scale_ = false;
+ last_pack_cng_or_dtmf_ = true;
timescale_countdown_ =
tick_timer_->GetNewCountdown(kMinTimescaleInterval + 1);
time_stretched_cn_samples_ = 0;
@@ -158,12 +160,13 @@
const size_t current_span =
estimate_dtx_delay_ ? status.packet_buffer_info.span_samples
: status.packet_buffer_info.span_samples_no_dtx;
+ const int target_level_samples =
+ delay_manager_->TargetDelayMs() * sample_rate_ / 1000;
if ((status.last_mode == NetEq::Mode::kExpand ||
status.last_mode == NetEq::Mode::kCodecPlc) &&
status.expand_mutefactor < 16384 / 2 &&
- current_span<static_cast<size_t>(delay_manager_->TargetLevel() *
- packet_length_samples_ *
- kPostponeDecodingLevel / 100)>> 8 &&
+ current_span < static_cast<size_t>(target_level_samples *
+ kPostponeDecodingLevel / 100) &&
!status.packet_buffer_info.dtx_or_cng) {
return NetEq::Operation::kExpand;
}
@@ -195,41 +198,32 @@
}
}
-absl::optional<int> DecisionLogic::PacketArrived(bool last_cng_or_dtmf,
+absl::optional<int> DecisionLogic::PacketArrived(bool is_cng_or_dtmf,
size_t packet_length_samples,
bool should_update_stats,
uint16_t main_sequence_number,
uint32_t main_timestamp,
int fs_hz) {
- delay_manager_->LastDecodedWasCngOrDtmf(last_cng_or_dtmf);
- absl::optional<int> relative_delay;
- if (delay_manager_->last_pack_cng_or_dtmf() == 0) {
- // Calculate the total speech length carried in each packet.
- if (packet_length_samples > 0 &&
- packet_length_samples != packet_length_samples_) {
- packet_length_samples_ = packet_length_samples;
- delay_manager_->SetPacketAudioLength(
- rtc::dchecked_cast<int>((1000 * packet_length_samples) / fs_hz));
- }
-
- // Update statistics.
- if (should_update_stats) {
- relative_delay =
- delay_manager_->Update(main_sequence_number, main_timestamp, fs_hz);
- }
- } else if (delay_manager_->last_pack_cng_or_dtmf() == -1) {
- // This is first "normal" packet after CNG or DTMF.
- // Reset packet time counter and measure time until next packet,
- // but don't update statistics.
- delay_manager_->set_last_pack_cng_or_dtmf(0);
- delay_manager_->ResetPacketIatCount();
+ if (is_cng_or_dtmf) {
+ last_pack_cng_or_dtmf_ = true;
+ return absl::nullopt;
}
+ if (!should_update_stats) {
+ return absl::nullopt;
+ }
+ if (packet_length_samples > 0 && fs_hz > 0 &&
+ packet_length_samples != packet_length_samples_) {
+ packet_length_samples_ = packet_length_samples;
+ delay_manager_->SetPacketAudioLength(packet_length_samples_ * 1000 / fs_hz);
+ }
+ auto relative_delay = delay_manager_->Update(
+ main_timestamp, fs_hz, /*reset=*/last_pack_cng_or_dtmf_);
+ last_pack_cng_or_dtmf_ = false;
return relative_delay;
}
void DecisionLogic::FilterBufferLevel(size_t buffer_size_samples) {
- buffer_level_filter_.SetTargetBufferLevel(
- delay_manager_->base_target_level());
+ buffer_level_filter_.SetTargetBufferLevel(delay_manager_->TargetDelayMs());
int time_stretched_samples = time_stretched_cn_samples_;
if (prev_time_scale_) {
@@ -250,8 +244,8 @@
int32_t timestamp_diff = static_cast<int32_t>(
static_cast<uint32_t>(generated_noise_samples + target_timestamp) -
available_timestamp);
- int32_t optimal_level_samp = static_cast<int32_t>(
- (delay_manager_->TargetLevel() * packet_length_samples_) >> 8);
+ int optimal_level_samp =
+ delay_manager_->TargetDelayMs() * sample_rate_ / 1000;
const int64_t excess_waiting_time_samp =
-static_cast<int64_t>(timestamp_diff) - optimal_level_samp;
@@ -295,22 +289,26 @@
bool play_dtmf) {
if (!disallow_time_stretching_ && prev_mode != NetEq::Mode::kExpand &&
!play_dtmf) {
- // Check criterion for time-stretching. The values are in number of packets
- // in Q8.
- int low_limit, high_limit;
- delay_manager_->BufferLimits(&low_limit, &high_limit);
- int buffer_level_packets = 0;
- if (packet_length_samples_ > 0) {
- buffer_level_packets =
- ((1 << 8) * buffer_level_filter_.filtered_current_level()) /
- packet_length_samples_;
- }
- if (buffer_level_packets >= high_limit << 2)
+ const int samples_per_ms = sample_rate_ / 1000;
+ const int target_level_samples =
+ delay_manager_->TargetDelayMs() * samples_per_ms;
+ const int low_limit =
+ std::max(target_level_samples * 3 / 4,
+ target_level_samples -
+ kDecelerationTargetLevelOffsetMs * samples_per_ms);
+ // |higher_limit| is equal to |target_level|, but should at
+ // least be 20 ms higher than |lower_limit|.
+ const int high_limit =
+ std::max(target_level_samples, low_limit + 20 * samples_per_ms);
+
+ const int buffer_level_samples =
+ buffer_level_filter_.filtered_current_level();
+ if (buffer_level_samples >= high_limit << 2)
return NetEq::Operation::kFastAccelerate;
if (TimescaleAllowed()) {
- if (buffer_level_packets >= high_limit)
+ if (buffer_level_samples >= high_limit)
return NetEq::Operation::kAccelerate;
- if (buffer_level_packets < low_limit)
+ if (buffer_level_samples < low_limit)
return NetEq::Operation::kPreemptiveExpand;
}
}
@@ -352,11 +350,11 @@
prev_mode == NetEq::Mode::kCodecInternalCng) {
size_t cur_size_samples =
estimate_dtx_delay_
- ? cur_size_samples = span_samples_in_packet_buffer
+ ? span_samples_in_packet_buffer
: num_packets_in_packet_buffer * decoder_frame_length;
// Target level is in number of packets in Q8.
const size_t target_level_samples =
- (delay_manager_->TargetLevel() * packet_length_samples_) >> 8;
+ delay_manager_->TargetDelayMs() * sample_rate_ / 1000;
const bool generated_enough_noise =
static_cast<uint32_t>(generated_noise_samples + target_timestamp) >=
available_timestamp;
@@ -406,13 +404,8 @@
}
bool DecisionLogic::UnderTargetLevel() const {
- int buffer_level_packets = 0;
- if (packet_length_samples_ > 0) {
- buffer_level_packets =
- ((1 << 8) * buffer_level_filter_.filtered_current_level()) /
- packet_length_samples_;
- }
- return buffer_level_packets <= delay_manager_->TargetLevel();
+ return buffer_level_filter_.filtered_current_level() <
+ delay_manager_->TargetDelayMs() * sample_rate_ / 1000;
}
bool DecisionLogic::ReinitAfterExpands(uint32_t timestamp_leap) const {
diff --git a/modules/audio_coding/neteq/decision_logic.h b/modules/audio_coding/neteq/decision_logic.h
index c3d82eb..d4d69ed 100644
--- a/modules/audio_coding/neteq/decision_logic.h
+++ b/modules/audio_coding/neteq/decision_logic.h
@@ -70,19 +70,16 @@
// Adds |value| to |sample_memory_|.
void AddSampleMemory(int32_t value) override { sample_memory_ += value; }
- int TargetLevelMs() const override {
- return ((delay_manager_->TargetLevel() * packet_length_samples_) >> 8) /
- rtc::CheckedDivExact(sample_rate_, 1000);
- }
+ int TargetLevelMs() const override { return delay_manager_->TargetDelayMs(); }
- absl::optional<int> PacketArrived(bool last_cng_or_dtmf,
+ absl::optional<int> PacketArrived(bool is_cng_or_dtmf,
size_t packet_length_samples,
bool should_update_stats,
uint16_t main_sequence_number,
uint32_t main_timestamp,
int fs_hz) override;
- void RegisterEmptyPacket() override { delay_manager_->RegisterEmptyPacket(); }
+ void RegisterEmptyPacket() override {}
void NotifyMutedState() override {}
@@ -122,8 +119,8 @@
enum CngState { kCngOff, kCngRfc3389On, kCngInternalOn };
// Updates the |buffer_level_filter_| with the current buffer level
- // |buffer_size_packets|.
- void FilterBufferLevel(size_t buffer_size_packets);
+ // |buffer_size_samples|.
+ void FilterBufferLevel(size_t buffer_size_samples);
// Returns the operation given that the next available packet is a comfort
// noise payload (RFC 3389 only, not codec-internal).
@@ -188,6 +185,7 @@
std::unique_ptr<TickTimer::Countdown> timescale_countdown_;
int num_consecutive_expands_ = 0;
int time_stretched_cn_samples_ = 0;
+ bool last_pack_cng_or_dtmf_ = true;
FieldTrialParameter<bool> estimate_dtx_delay_;
FieldTrialParameter<bool> time_stretch_cn_;
FieldTrialConstrained<int> target_level_window_ms_;
diff --git a/modules/audio_coding/neteq/decision_logic_unittest.cc b/modules/audio_coding/neteq/decision_logic_unittest.cc
index a5b6712..56e8b84 100644
--- a/modules/audio_coding/neteq/decision_logic_unittest.cc
+++ b/modules/audio_coding/neteq/decision_logic_unittest.cc
@@ -43,6 +43,6 @@
logic->SetSampleRate(fs_hz, output_size_samples);
}
-// TODO(hlundin): Write more tests.
+// TODO(jakobi): Write more tests.
} // namespace webrtc
diff --git a/modules/audio_coding/neteq/delay_manager.cc b/modules/audio_coding/neteq/delay_manager.cc
index 4ae6d10..6b10d33 100644
--- a/modules/audio_coding/neteq/delay_manager.cc
+++ b/modules/audio_coding/neteq/delay_manager.cc
@@ -27,17 +27,17 @@
#include "rtc_base/numerics/safe_minmax.h"
#include "system_wrappers/include/field_trial.h"
+namespace webrtc {
namespace {
constexpr int kMinBaseMinimumDelayMs = 0;
constexpr int kMaxBaseMinimumDelayMs = 10000;
-constexpr int kMaxReorderedPackets =
- 10; // Max number of consecutive reordered packets.
constexpr int kMaxHistoryMs = 2000; // Oldest packet to include in history to
// calculate relative packet arrival delay.
constexpr int kDelayBuckets = 100;
constexpr int kBucketSizeMs = 20;
-constexpr int kDecelerationTargetLevelOffsetMs = 85 << 8; // In Q8.
+constexpr int kStartDelayMs = 80;
+constexpr int kMaxNumReorderedPackets = 5;
int PercentileToQuantile(double percentile) {
return static_cast<int>((1 << 30) * percentile / 100.0 + 0.5);
@@ -49,6 +49,7 @@
absl::optional<double> start_forget_weight = 2;
};
+// TODO(jakobi): Remove legacy field trial.
DelayHistogramConfig GetDelayHistogramConfig() {
constexpr char kDelayHistogramFieldTrial[] =
"WebRTC-Audio-NetEqDelayHistogram";
@@ -81,12 +82,9 @@
} // namespace
-namespace webrtc {
-
-DelayManager::DelayManager(size_t max_packets_in_buffer,
+DelayManager::DelayManager(int max_packets_in_buffer,
int base_minimum_delay_ms,
int histogram_quantile,
- bool enable_rtx_handling,
const TickTimer* tick_timer,
std::unique_ptr<Histogram> histogram)
: first_packet_received_(false),
@@ -96,15 +94,10 @@
tick_timer_(tick_timer),
base_minimum_delay_ms_(base_minimum_delay_ms),
effective_minimum_delay_ms_(base_minimum_delay_ms),
- base_target_level_(4), // In Q0 domain.
- target_level_(base_target_level_ << 8), // In Q8 domain.
- packet_len_ms_(0),
- last_seq_no_(0),
- last_timestamp_(0),
minimum_delay_ms_(0),
maximum_delay_ms_(0),
- last_pack_cng_or_dtmf_(1),
- enable_rtx_handling_(enable_rtx_handling) {
+ target_level_ms_(kStartDelayMs),
+ last_timestamp_(0) {
RTC_CHECK(histogram_);
RTC_DCHECK_GE(base_minimum_delay_ms_, 0);
@@ -112,102 +105,80 @@
}
std::unique_ptr<DelayManager> DelayManager::Create(
- size_t max_packets_in_buffer,
+ int max_packets_in_buffer,
int base_minimum_delay_ms,
- bool enable_rtx_handling,
const TickTimer* tick_timer) {
- DelayHistogramConfig config = GetDelayHistogramConfig();
- const int quantile = config.quantile;
+ auto config = GetDelayHistogramConfig();
std::unique_ptr<Histogram> histogram = std::make_unique<Histogram>(
kDelayBuckets, config.forget_factor, config.start_forget_weight);
- return std::make_unique<DelayManager>(
- max_packets_in_buffer, base_minimum_delay_ms, quantile,
- enable_rtx_handling, tick_timer, std::move(histogram));
+ return std::make_unique<DelayManager>(max_packets_in_buffer,
+ base_minimum_delay_ms, config.quantile,
+ tick_timer, std::move(histogram));
}
DelayManager::~DelayManager() {}
-absl::optional<int> DelayManager::Update(uint16_t sequence_number,
- uint32_t timestamp,
- int sample_rate_hz) {
+absl::optional<int> DelayManager::Update(uint32_t timestamp,
+ int sample_rate_hz,
+ bool reset) {
if (sample_rate_hz <= 0) {
return absl::nullopt;
}
- if (!first_packet_received_) {
- // Prepare for next packet arrival.
+ if (!first_packet_received_ || reset) {
+ // Restart relative delay esimation from this packet.
+ delay_history_.clear();
packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch();
- last_seq_no_ = sequence_number;
last_timestamp_ = timestamp;
first_packet_received_ = true;
+ num_reordered_packets_ = 0;
return absl::nullopt;
}
- // Try calculating packet length from current and previous timestamps.
- int packet_len_ms;
- if (!IsNewerTimestamp(timestamp, last_timestamp_) ||
- !IsNewerSequenceNumber(sequence_number, last_seq_no_)) {
- // Wrong timestamp or sequence order; use stored value.
- packet_len_ms = packet_len_ms_;
+ const int expected_iat_ms =
+ 1000 * static_cast<int32_t>(timestamp - last_timestamp_) / sample_rate_hz;
+ const int iat_ms = packet_iat_stopwatch_->ElapsedMs();
+ const int iat_delay_ms = iat_ms - expected_iat_ms;
+ absl::optional<int> relative_delay;
+ bool reordered = !IsNewerTimestamp(timestamp, last_timestamp_);
+ if (reordered) {
+ relative_delay = std::max(iat_delay_ms, 0);
} else {
- // Calculate timestamps per packet and derive packet length in ms.
- int64_t packet_len_samp =
- static_cast<uint32_t>(timestamp - last_timestamp_) /
- static_cast<uint16_t>(sequence_number - last_seq_no_);
- packet_len_ms =
- rtc::saturated_cast<int>(1000 * packet_len_samp / sample_rate_hz);
+ UpdateDelayHistory(iat_delay_ms, timestamp, sample_rate_hz);
+ relative_delay = CalculateRelativePacketArrivalDelay();
+ }
+ const int index = relative_delay.value() / kBucketSizeMs;
+ if (index < histogram_->NumBuckets()) {
+ // Maximum delay to register is 2000 ms.
+ histogram_->Add(index);
+ }
+ // Calculate new |target_level_ms_| based on updated statistics.
+ int bucket_index = histogram_->Quantile(histogram_quantile_);
+ target_level_ms_ = (1 + bucket_index) * kBucketSizeMs;
+ target_level_ms_ = std::max(target_level_ms_, effective_minimum_delay_ms_);
+ if (maximum_delay_ms_ > 0) {
+ target_level_ms_ = std::min(target_level_ms_, maximum_delay_ms_);
+ }
+ if (packet_len_ms_ > 0) {
+ // Target level should be at least one packet.
+ target_level_ms_ = std::max(target_level_ms_, packet_len_ms_);
+ // Limit to 75% of maximum buffer size.
+ target_level_ms_ = std::min(
+ target_level_ms_, 3 * max_packets_in_buffer_ * packet_len_ms_ / 4);
}
- bool reordered = false;
- absl::optional<int> relative_delay;
- if (packet_len_ms > 0) {
- // Cannot update statistics unless |packet_len_ms| is valid.
-
- // Inter-arrival time (IAT) in integer "packet times" (rounding down). This
- // is the value added to the inter-arrival time histogram.
- int iat_ms = packet_iat_stopwatch_->ElapsedMs();
- // Check for discontinuous packet sequence and re-ordering.
- if (IsNewerSequenceNumber(sequence_number, last_seq_no_ + 1)) {
- // Compensate for gap in the sequence numbers. Reduce IAT with the
- // expected extra time due to lost packets.
- int packet_offset =
- static_cast<uint16_t>(sequence_number - last_seq_no_ - 1);
- iat_ms -= packet_offset * packet_len_ms;
- } else if (!IsNewerSequenceNumber(sequence_number, last_seq_no_)) {
- int packet_offset =
- static_cast<uint16_t>(last_seq_no_ + 1 - sequence_number);
- iat_ms += packet_offset * packet_len_ms;
- reordered = true;
+ // 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;
}
-
- int iat_delay = iat_ms - packet_len_ms;
- if (reordered) {
- relative_delay = std::max(iat_delay, 0);
- } else {
- UpdateDelayHistory(iat_delay, timestamp, sample_rate_hz);
- relative_delay = CalculateRelativePacketArrivalDelay();
- }
-
- const int index = relative_delay.value() / kBucketSizeMs;
- if (index < histogram_->NumBuckets()) {
- // Maximum delay to register is 2000 ms.
- histogram_->Add(index);
- }
- // Calculate new |target_level_| based on updated statistics.
- target_level_ = CalculateTargetLevel();
-
- LimitTargetLevel();
- } // End if (packet_len_ms > 0).
-
- if (enable_rtx_handling_ && reordered &&
- num_reordered_packets_ < kMaxReorderedPackets) {
- ++num_reordered_packets_;
- return relative_delay;
+ delay_history_.clear();
}
num_reordered_packets_ = 0;
- // Prepare for next packet arrival.
packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch();
- last_seq_no_ = sequence_number;
last_timestamp_ = timestamp;
return relative_delay;
}
@@ -238,128 +209,27 @@
return relative_delay;
}
-// Enforces upper and lower limits for |target_level_|. The upper limit is
-// chosen to be minimum of i) 75% of |max_packets_in_buffer_|, to leave some
-// headroom for natural fluctuations around the target, and ii) equivalent of
-// |maximum_delay_ms_| in packets. Note that in practice, if no
-// |maximum_delay_ms_| is specified, this does not have any impact, since the
-// target level is far below the buffer capacity in all reasonable cases.
-// The lower limit is equivalent of |effective_minimum_delay_ms_| in packets.
-// We update |least_required_level_| while the above limits are applied.
-// TODO(hlundin): Move this check to the buffer logistics class.
-void DelayManager::LimitTargetLevel() {
- if (packet_len_ms_ > 0 && effective_minimum_delay_ms_ > 0) {
- int minimum_delay_packet_q8 =
- (effective_minimum_delay_ms_ << 8) / packet_len_ms_;
- target_level_ = std::max(target_level_, minimum_delay_packet_q8);
- }
-
- if (maximum_delay_ms_ > 0 && packet_len_ms_ > 0) {
- int maximum_delay_packet_q8 = (maximum_delay_ms_ << 8) / packet_len_ms_;
- target_level_ = std::min(target_level_, maximum_delay_packet_q8);
- }
-
- // Shift to Q8, then 75%.;
- int max_buffer_packets_q8 =
- static_cast<int>((3 * (max_packets_in_buffer_ << 8)) / 4);
- target_level_ = std::min(target_level_, max_buffer_packets_q8);
-
- // Sanity check, at least 1 packet (in Q8).
- target_level_ = std::max(target_level_, 1 << 8);
-}
-
-int DelayManager::CalculateTargetLevel() {
- int limit_probability = histogram_quantile_;
-
- int bucket_index = histogram_->Quantile(limit_probability);
- int target_level = 1;
- if (packet_len_ms_ > 0) {
- target_level += bucket_index * kBucketSizeMs / packet_len_ms_;
- }
- base_target_level_ = target_level;
-
- // Sanity check. |target_level| must be strictly positive.
- target_level = std::max(target_level, 1);
- // Scale to Q8 and assign to member variable.
- target_level_ = target_level << 8;
- return target_level_;
-}
-
int DelayManager::SetPacketAudioLength(int length_ms) {
if (length_ms <= 0) {
RTC_LOG_F(LS_ERROR) << "length_ms = " << length_ms;
return -1;
}
-
packet_len_ms_ = length_ms;
- packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch();
- last_pack_cng_or_dtmf_ = 1; // TODO(hlundin): Legacy. Remove?
return 0;
}
void DelayManager::Reset() {
- packet_len_ms_ = 0; // Packet size unknown.
+ packet_len_ms_ = 0;
histogram_->Reset();
delay_history_.clear();
- base_target_level_ = 4;
- target_level_ = base_target_level_ << 8;
+ target_level_ms_ = kStartDelayMs;
packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch();
- last_pack_cng_or_dtmf_ = 1;
+ first_packet_received_ = false;
+ num_reordered_packets_ = 0;
}
-void DelayManager::ResetPacketIatCount() {
- packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch();
-}
-
-void DelayManager::BufferLimits(int* lower_limit, int* higher_limit) const {
- BufferLimits(target_level_, lower_limit, higher_limit);
-}
-
-// Note that |low_limit| and |higher_limit| are not assigned to
-// |minimum_delay_ms_| and |maximum_delay_ms_| defined by the client of this
-// class. They are computed from |target_level| in Q8 and used for decision
-// making.
-void DelayManager::BufferLimits(int target_level,
- int* lower_limit,
- int* higher_limit) const {
- if (!lower_limit || !higher_limit) {
- RTC_LOG_F(LS_ERROR) << "NULL pointers supplied as input";
- assert(false);
- return;
- }
-
- // |target_level| is in Q8 already.
- *lower_limit = (target_level * 3) / 4;
-
- if (packet_len_ms_ > 0) {
- *lower_limit =
- std::max(*lower_limit, target_level - kDecelerationTargetLevelOffsetMs /
- packet_len_ms_);
- }
-
- int window_20ms = 0x7FFF; // Default large value for legacy bit-exactness.
- if (packet_len_ms_ > 0) {
- window_20ms = (20 << 8) / packet_len_ms_;
- }
- // |higher_limit| is equal to |target_level|, but should at
- // least be 20 ms higher than |lower_limit|.
- *higher_limit = std::max(target_level, *lower_limit + window_20ms);
-}
-
-int DelayManager::TargetLevel() const {
- return target_level_;
-}
-
-void DelayManager::LastDecodedWasCngOrDtmf(bool it_was) {
- if (it_was) {
- last_pack_cng_or_dtmf_ = 1;
- } else if (last_pack_cng_or_dtmf_ != 0) {
- last_pack_cng_or_dtmf_ = -1;
- }
-}
-
-void DelayManager::RegisterEmptyPacket() {
- ++last_seq_no_;
+int DelayManager::TargetDelayMs() const {
+ return target_level_ms_;
}
bool DelayManager::IsValidMinimumDelay(int delay_ms) const {
@@ -409,17 +279,6 @@
return base_minimum_delay_ms_;
}
-int DelayManager::base_target_level() const {
- return base_target_level_;
-}
-int DelayManager::last_pack_cng_or_dtmf() const {
- return last_pack_cng_or_dtmf_;
-}
-
-void DelayManager::set_last_pack_cng_or_dtmf(int value) {
- last_pack_cng_or_dtmf_ = value;
-}
-
void DelayManager::UpdateEffectiveMinimumDelay() {
// Clamp |base_minimum_delay_ms_| into the range which can be effectively
// used.
@@ -432,16 +291,11 @@
int DelayManager::MinimumDelayUpperBound() const {
// Choose the lowest possible bound discarding 0 cases which mean the value
// is not set and unconstrained.
- int q75 = MaxBufferTimeQ75();
+ int q75 = max_packets_in_buffer_ * packet_len_ms_ * 3 / 4;
q75 = q75 > 0 ? q75 : kMaxBaseMinimumDelayMs;
const int maximum_delay_ms =
maximum_delay_ms_ > 0 ? maximum_delay_ms_ : kMaxBaseMinimumDelayMs;
return std::min(maximum_delay_ms, q75);
}
-int DelayManager::MaxBufferTimeQ75() const {
- const int max_buffer_time = max_packets_in_buffer_ * packet_len_ms_;
- return rtc::dchecked_cast<int>(3 * max_buffer_time / 4);
-}
-
} // namespace webrtc
diff --git a/modules/audio_coding/neteq/delay_manager.h b/modules/audio_coding/neteq/delay_manager.h
index ab9ba34..d5cea45 100644
--- a/modules/audio_coding/neteq/delay_manager.h
+++ b/modules/audio_coding/neteq/delay_manager.h
@@ -25,10 +25,9 @@
class DelayManager {
public:
- DelayManager(size_t max_packets_in_buffer,
+ DelayManager(int max_packets_in_buffer,
int base_minimum_delay_ms,
int histogram_quantile,
- bool enable_rtx_handling,
const TickTimer* tick_timer,
std::unique_ptr<Histogram> histogram);
@@ -37,58 +36,29 @@
// is the number of packet slots in the buffer) and that the target delay
// should be greater than or equal to |base_minimum_delay_ms|. Supply a
// PeakDetector object to the DelayManager.
- static std::unique_ptr<DelayManager> Create(size_t max_packets_in_buffer,
+ static std::unique_ptr<DelayManager> Create(int max_packets_in_buffer,
int base_minimum_delay_ms,
- bool enable_rtx_handling,
const TickTimer* tick_timer);
virtual ~DelayManager();
- // Updates the delay manager with a new incoming packet, with
- // |sequence_number| and |timestamp| from the RTP header. This updates the
- // inter-arrival time histogram and other statistics, as well as the
- // associated DelayPeakDetector. A new target buffer level is calculated.
- // Returns the relative delay if it can be calculated.
- virtual absl::optional<int> Update(uint16_t sequence_number,
- uint32_t timestamp,
- int sample_rate_hz);
+ // Updates the delay manager with a new incoming packet, with |timestamp| from
+ // the RTP header. This updates the statistics and a new target buffer level
+ // is calculated. Returns the relative delay if it can be calculated. If
+ // |reset| is true, restarts the relative arrival delay calculation from this
+ // packet.
+ virtual absl::optional<int> Update(uint32_t timestamp,
+ int sample_rate_hz,
+ bool reset = false);
- // Calculates a new target buffer level. Called from the Update() method.
- // Sets target_level_ (in Q8) and returns the same value. Also calculates
- // and updates base_target_level_, which is the target buffer level before
- // taking delay peaks into account.
- virtual int CalculateTargetLevel();
-
- // Notifies the DelayManager of how much audio data is carried in each packet.
- // The method updates the DelayPeakDetector too, and resets the inter-arrival
- // time counter. Returns 0 on success, -1 on failure.
- virtual int SetPacketAudioLength(int length_ms);
-
- // Resets the DelayManager and the associated DelayPeakDetector.
+ // Resets all state.
virtual void Reset();
- // Reset the inter-arrival time counter to 0.
- virtual void ResetPacketIatCount();
+ // Gets the target buffer level in milliseconds.
+ virtual int TargetDelayMs() const;
- // Writes the lower and higher limits which the buffer level should stay
- // within to the corresponding pointers. The values are in (fractions of)
- // packets in Q8.
- virtual void BufferLimits(int* lower_limit, int* higher_limit) const;
- virtual void BufferLimits(int target_level,
- int* lower_limit,
- int* higher_limit) const;
-
- // Gets the target buffer level, in (fractions of) packets in Q8.
- virtual int TargetLevel() const;
-
- // Informs the delay manager whether or not the last decoded packet contained
- // speech.
- virtual void LastDecodedWasCngOrDtmf(bool it_was);
-
- // Notify the delay manager that empty packets have been received. These are
- // packets that are part of the sequence number series, so that an empty
- // packet will shift the sequence numbers for the following packets.
- virtual void RegisterEmptyPacket();
+ // Notifies the DelayManager of how much audio data is carried in each packet.
+ virtual int SetPacketAudioLength(int length_ms);
// Accessors and mutators.
// Assuming |delay| is in valid range.
@@ -96,16 +66,11 @@
virtual bool SetMaximumDelay(int delay_ms);
virtual bool SetBaseMinimumDelay(int delay_ms);
virtual int GetBaseMinimumDelay() const;
- virtual int base_target_level() const;
- virtual int last_pack_cng_or_dtmf() const;
- virtual void set_last_pack_cng_or_dtmf(int value);
- // This accessor is only intended for testing purposes.
+ // These accessors are only intended for testing purposes.
int effective_minimum_delay_ms_for_test() const {
return effective_minimum_delay_ms_;
}
-
- // These accessors are only intended for testing purposes.
int histogram_quantile() const { return histogram_quantile_; }
Histogram* histogram() const { return histogram_.get(); }
@@ -114,9 +79,6 @@
// size and given |maximum_delay_ms_|. Lower bound is a constant 0.
int MinimumDelayUpperBound() const;
- // Provides 75% of currently possible maximum buffer size in milliseconds.
- int MaxBufferTimeQ75() const;
-
// Updates |delay_history_|.
void UpdateDelayHistory(int iat_delay_ms,
uint32_t timestamp,
@@ -130,10 +92,6 @@
// and buffer size.
void UpdateEffectiveMinimumDelay();
- // Makes sure that |target_level_| is not too large, taking
- // |max_packets_in_buffer_| into account. This method is called by Update().
- void LimitTargetLevel();
-
// Makes sure that |delay_ms| is less than maximum delay, if any maximum
// is set. Also, if possible check |delay_ms| to be less than 75% of
// |max_packets_in_buffer_|.
@@ -142,31 +100,22 @@
bool IsValidBaseMinimumDelay(int delay_ms) const;
bool first_packet_received_;
- const size_t max_packets_in_buffer_; // Capacity of the packet buffer.
+ // TODO(jakobi): set maximum buffer delay instead of number of packets.
+ const int max_packets_in_buffer_;
std::unique_ptr<Histogram> histogram_;
const int histogram_quantile_;
const TickTimer* tick_timer_;
int base_minimum_delay_ms_;
- // Provides delay which is used by LimitTargetLevel as lower bound on target
- // delay.
- int effective_minimum_delay_ms_;
+ int effective_minimum_delay_ms_; // Used as lower bound for target delay.
+ int minimum_delay_ms_; // Externally set minimum delay.
+ int maximum_delay_ms_; // Externally set maximum allowed delay.
- // Time elapsed since last packet.
- std::unique_ptr<TickTimer::Stopwatch> packet_iat_stopwatch_;
- int base_target_level_; // Currently preferred buffer level before peak
- // detection and streaming mode (Q0).
- // TODO(turajs) change the comment according to the implementation of
- // minimum-delay.
- int target_level_; // Currently preferred buffer level in (fractions)
- // of packets (Q8), before adding any extra delay.
- int packet_len_ms_; // Length of audio in each incoming packet [ms].
- uint16_t last_seq_no_; // Sequence number for last received packet.
- uint32_t last_timestamp_; // Timestamp for the last received packet.
- int minimum_delay_ms_; // Externally set minimum delay.
- int maximum_delay_ms_; // Externally set maximum allowed delay.
- int last_pack_cng_or_dtmf_;
- const bool enable_rtx_handling_;
- int num_reordered_packets_ = 0; // Number of consecutive reordered packets.
+ int packet_len_ms_ = 0;
+ std::unique_ptr<TickTimer::Stopwatch>
+ 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;
struct PacketDelay {
int iat_delay_ms;
diff --git a/modules/audio_coding/neteq/delay_manager_unittest.cc b/modules/audio_coding/neteq/delay_manager_unittest.cc
index 4a118f7..a6a38b6 100644
--- a/modules/audio_coding/neteq/delay_manager_unittest.cc
+++ b/modules/audio_coding/neteq/delay_manager_unittest.cc
@@ -35,19 +35,15 @@
constexpr int kTsIncrement = kFrameSizeMs * kFs / 1000;
constexpr int kMaxBufferSizeMs = kMaxNumberOfPackets * kFrameSizeMs;
constexpr int kDefaultHistogramQuantile = 1020054733;
-constexpr int kMaxIat = 64;
+constexpr int kNumBuckets = 100;
constexpr int kForgetFactor = 32745;
} // namespace
-using ::testing::_;
-using ::testing::Return;
-
class DelayManagerTest : public ::testing::Test {
protected:
DelayManagerTest();
virtual void SetUp();
void RecreateDelayManager();
- void SetPacketAudioLength(int lengt_ms);
absl::optional<int> InsertNextPacket();
void IncreaseTime(int inc_ms);
@@ -55,15 +51,12 @@
TickTimer tick_timer_;
MockStatisticsCalculator stats_;
MockHistogram* mock_histogram_;
- uint16_t seq_no_;
uint32_t ts_;
- bool enable_rtx_handling_ = false;
bool use_mock_histogram_ = false;
};
DelayManagerTest::DelayManagerTest()
: dm_(nullptr),
- seq_no_(0x1234),
ts_(0x12345678) {}
void DelayManagerTest::SetUp() {
@@ -72,24 +65,19 @@
void DelayManagerTest::RecreateDelayManager() {
if (use_mock_histogram_) {
- mock_histogram_ = new MockHistogram(kMaxIat, kForgetFactor);
+ mock_histogram_ = new MockHistogram(kNumBuckets, kForgetFactor);
std::unique_ptr<Histogram> histogram(mock_histogram_);
- dm_ = std::make_unique<DelayManager>(
- kMaxNumberOfPackets, kMinDelayMs, kDefaultHistogramQuantile,
- enable_rtx_handling_, &tick_timer_, std::move(histogram));
+ dm_ = std::make_unique<DelayManager>(kMaxNumberOfPackets, kMinDelayMs,
+ kDefaultHistogramQuantile,
+ &tick_timer_, std::move(histogram));
} else {
- dm_ = DelayManager::Create(kMaxNumberOfPackets, kMinDelayMs,
- enable_rtx_handling_, &tick_timer_);
+ dm_ = DelayManager::Create(kMaxNumberOfPackets, kMinDelayMs, &tick_timer_);
}
-}
-
-void DelayManagerTest::SetPacketAudioLength(int lengt_ms) {
- dm_->SetPacketAudioLength(lengt_ms);
+ dm_->SetPacketAudioLength(kFrameSizeMs);
}
absl::optional<int> DelayManagerTest::InsertNextPacket() {
- auto relative_delay = dm_->Update(seq_no_, ts_, kFs);
- seq_no_ += 1;
+ auto relative_delay = dm_->Update(ts_, kFs);
ts_ += kTsIncrement;
return relative_delay;
}
@@ -105,98 +93,66 @@
// object.
}
-TEST_F(DelayManagerTest, SetPacketAudioLength) {
- const int kLengthMs = 30;
- EXPECT_EQ(0, dm_->SetPacketAudioLength(kLengthMs));
- EXPECT_EQ(-1, dm_->SetPacketAudioLength(-1)); // Illegal parameter value.
-}
-
TEST_F(DelayManagerTest, UpdateNormal) {
- SetPacketAudioLength(kFrameSizeMs);
// First packet arrival.
InsertNextPacket();
// Advance time by one frame size.
IncreaseTime(kFrameSizeMs);
// Second packet arrival.
InsertNextPacket();
- EXPECT_EQ(1 << 8, dm_->TargetLevel()); // In Q8.
- EXPECT_EQ(1, dm_->base_target_level());
- int lower, higher;
- dm_->BufferLimits(&lower, &higher);
- // Expect |lower| to be 75% of target level, and |higher| to be target level,
- // but also at least 20 ms higher than |lower|, which is the limiting case
- // here.
- EXPECT_EQ((1 << 8) * 3 / 4, lower);
- EXPECT_EQ(lower + (20 << 8) / kFrameSizeMs, higher);
+ EXPECT_EQ(20, dm_->TargetDelayMs());
}
TEST_F(DelayManagerTest, UpdateLongInterArrivalTime) {
- SetPacketAudioLength(kFrameSizeMs);
// First packet arrival.
InsertNextPacket();
// Advance time by two frame size.
IncreaseTime(2 * kFrameSizeMs);
// Second packet arrival.
InsertNextPacket();
- EXPECT_EQ(2 << 8, dm_->TargetLevel()); // In Q8.
- EXPECT_EQ(2, dm_->base_target_level());
- int lower, higher;
- dm_->BufferLimits(&lower, &higher);
- // Expect |lower| to be 75% of target level, and |higher| to be target level,
- // but also at least 20 ms higher than |lower|, which is the limiting case
- // here.
- EXPECT_EQ((2 << 8) * 3 / 4, lower);
- EXPECT_EQ(lower + (20 << 8) / kFrameSizeMs, higher);
+ EXPECT_EQ(40, dm_->TargetDelayMs());
}
TEST_F(DelayManagerTest, MaxDelay) {
- const int kExpectedTarget = 5;
- const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
- SetPacketAudioLength(kFrameSizeMs);
+ const int kExpectedTarget = 5 * kFrameSizeMs;
// First packet arrival.
InsertNextPacket();
// Second packet arrival.
- IncreaseTime(kTimeIncrement);
+ IncreaseTime(kExpectedTarget);
InsertNextPacket();
// No limit is set.
- EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel());
+ EXPECT_EQ(kExpectedTarget, dm_->TargetDelayMs());
- int kMaxDelayPackets = kExpectedTarget - 2;
- int kMaxDelayMs = kMaxDelayPackets * kFrameSizeMs;
+ const int kMaxDelayMs = 3 * kFrameSizeMs;
EXPECT_TRUE(dm_->SetMaximumDelay(kMaxDelayMs));
- IncreaseTime(kTimeIncrement);
+ IncreaseTime(kFrameSizeMs);
InsertNextPacket();
- EXPECT_EQ(kMaxDelayPackets << 8, dm_->TargetLevel());
+ EXPECT_EQ(kMaxDelayMs, dm_->TargetDelayMs());
// Target level at least should be one packet.
EXPECT_FALSE(dm_->SetMaximumDelay(kFrameSizeMs - 1));
}
TEST_F(DelayManagerTest, MinDelay) {
- const int kExpectedTarget = 5;
- const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
- SetPacketAudioLength(kFrameSizeMs);
+ const int kExpectedTarget = 5 * kFrameSizeMs;
// First packet arrival.
InsertNextPacket();
// Second packet arrival.
- IncreaseTime(kTimeIncrement);
+ IncreaseTime(kExpectedTarget);
InsertNextPacket();
// No limit is applied.
- EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel());
+ EXPECT_EQ(kExpectedTarget, dm_->TargetDelayMs());
- int kMinDelayPackets = kExpectedTarget + 2;
- int kMinDelayMs = kMinDelayPackets * kFrameSizeMs;
+ int kMinDelayMs = 7 * kFrameSizeMs;
dm_->SetMinimumDelay(kMinDelayMs);
IncreaseTime(kFrameSizeMs);
InsertNextPacket();
- EXPECT_EQ(kMinDelayPackets << 8, dm_->TargetLevel());
+ EXPECT_EQ(kMinDelayMs, dm_->TargetDelayMs());
}
TEST_F(DelayManagerTest, BaseMinimumDelayCheckValidRange) {
- SetPacketAudioLength(kFrameSizeMs);
-
// Base minimum delay should be between [0, 10000] milliseconds.
EXPECT_FALSE(dm_->SetBaseMinimumDelay(-1));
EXPECT_FALSE(dm_->SetBaseMinimumDelay(10001));
@@ -207,7 +163,6 @@
}
TEST_F(DelayManagerTest, BaseMinimumDelayLowerThanMinimumDelay) {
- SetPacketAudioLength(kFrameSizeMs);
constexpr int kBaseMinimumDelayMs = 100;
constexpr int kMinimumDelayMs = 200;
@@ -221,7 +176,6 @@
}
TEST_F(DelayManagerTest, BaseMinimumDelayGreaterThanMinimumDelay) {
- SetPacketAudioLength(kFrameSizeMs);
constexpr int kBaseMinimumDelayMs = 70;
constexpr int kMinimumDelayMs = 30;
@@ -235,7 +189,6 @@
}
TEST_F(DelayManagerTest, BaseMinimumDelayGreaterThanBufferSize) {
- SetPacketAudioLength(kFrameSizeMs);
constexpr int kBaseMinimumDelayMs = kMaxBufferSizeMs + 1;
constexpr int kMinimumDelayMs = 12;
constexpr int kMaximumDelayMs = 20;
@@ -262,7 +215,6 @@
}
TEST_F(DelayManagerTest, BaseMinimumDelayGreaterThanMaximumDelay) {
- SetPacketAudioLength(kFrameSizeMs);
constexpr int kMaximumDelayMs = 400;
constexpr int kBaseMinimumDelayMs = kMaximumDelayMs + 1;
constexpr int kMinimumDelayMs = 20;
@@ -280,7 +232,6 @@
}
TEST_F(DelayManagerTest, BaseMinimumDelayLowerThanMaxSize) {
- SetPacketAudioLength(kFrameSizeMs);
constexpr int kMaximumDelayMs = 400;
constexpr int kBaseMinimumDelayMs = kMaximumDelayMs - 1;
constexpr int kMinimumDelayMs = 20;
@@ -301,8 +252,6 @@
// minimum delay then minimum delay is still memorized. This allows to
// restore effective minimum delay to memorized minimum delay value when we
// decrease base minimum delay.
- SetPacketAudioLength(kFrameSizeMs);
-
constexpr int kBaseMinimumDelayMsLow = 10;
constexpr int kMinimumDelayMs = 20;
constexpr int kBaseMinimumDelayMsHigh = 30;
@@ -323,33 +272,29 @@
}
TEST_F(DelayManagerTest, BaseMinimumDelay) {
- const int kExpectedTarget = 5;
- const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
- SetPacketAudioLength(kFrameSizeMs);
+ const int kExpectedTarget = 5 * kFrameSizeMs;
// First packet arrival.
InsertNextPacket();
// Second packet arrival.
- IncreaseTime(kTimeIncrement);
+ IncreaseTime(kExpectedTarget);
InsertNextPacket();
// No limit is applied.
- EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel());
+ EXPECT_EQ(kExpectedTarget, dm_->TargetDelayMs());
- constexpr int kBaseMinimumDelayPackets = kExpectedTarget + 2;
- constexpr int kBaseMinimumDelayMs = kBaseMinimumDelayPackets * kFrameSizeMs;
+ constexpr int kBaseMinimumDelayMs = 7 * kFrameSizeMs;
EXPECT_TRUE(dm_->SetBaseMinimumDelay(kBaseMinimumDelayMs));
EXPECT_EQ(dm_->GetBaseMinimumDelay(), kBaseMinimumDelayMs);
IncreaseTime(kFrameSizeMs);
InsertNextPacket();
EXPECT_EQ(dm_->GetBaseMinimumDelay(), kBaseMinimumDelayMs);
- EXPECT_EQ(kBaseMinimumDelayPackets << 8, dm_->TargetLevel());
+ EXPECT_EQ(kBaseMinimumDelayMs, dm_->TargetDelayMs());
}
-TEST_F(DelayManagerTest, BaseMinimumDealyAffectTargetLevel) {
+TEST_F(DelayManagerTest, BaseMinimumDelayAffectsTargetDelay) {
const int kExpectedTarget = 5;
const int kTimeIncrement = kExpectedTarget * kFrameSizeMs;
- SetPacketAudioLength(kFrameSizeMs);
// First packet arrival.
InsertNextPacket();
// Second packet arrival.
@@ -357,7 +302,7 @@
InsertNextPacket();
// No limit is applied.
- EXPECT_EQ(kExpectedTarget << 8, dm_->TargetLevel());
+ EXPECT_EQ(kTimeIncrement, dm_->TargetDelayMs());
// Minimum delay is lower than base minimum delay, that is why base minimum
// delay is used to calculate target level.
@@ -375,88 +320,19 @@
IncreaseTime(kFrameSizeMs);
InsertNextPacket();
EXPECT_EQ(dm_->GetBaseMinimumDelay(), kBaseMinimumDelayMs);
- EXPECT_EQ(kBaseMinimumDelayPackets << 8, dm_->TargetLevel());
-}
-
-TEST_F(DelayManagerTest, EnableRtxHandling) {
- enable_rtx_handling_ = true;
- use_mock_histogram_ = true;
- RecreateDelayManager();
- EXPECT_TRUE(mock_histogram_);
-
- // Insert first packet.
- SetPacketAudioLength(kFrameSizeMs);
- InsertNextPacket();
-
- // Insert reordered packet.
- EXPECT_CALL(*mock_histogram_, Add(2));
- dm_->Update(seq_no_ - 3, ts_ - 3 * kFrameSizeMs, kFs);
-
- // Insert another reordered packet.
- EXPECT_CALL(*mock_histogram_, Add(1));
- dm_->Update(seq_no_ - 2, ts_ - 2 * kFrameSizeMs, kFs);
-
- // Insert the next packet in order and verify that the inter-arrival time is
- // estimated correctly.
- IncreaseTime(kFrameSizeMs);
- EXPECT_CALL(*mock_histogram_, Add(0));
- InsertNextPacket();
-}
-
-// Tests that skipped sequence numbers (simulating empty packets) are handled
-// correctly.
-// TODO(jakobi): Make delay manager independent of sequence numbers.
-TEST_F(DelayManagerTest, EmptyPacketsReported) {
- SetPacketAudioLength(kFrameSizeMs);
- // First packet arrival.
- InsertNextPacket();
-
- // Advance time by one frame size.
- IncreaseTime(kFrameSizeMs);
-
- // Advance the sequence number by 5, simulating that 5 empty packets were
- // received, but never inserted.
- seq_no_ += 10;
- for (int j = 0; j < 10; ++j) {
- dm_->RegisterEmptyPacket();
- }
-
- // Second packet arrival.
- InsertNextPacket();
-
- EXPECT_EQ(1 << 8, dm_->TargetLevel()); // In Q8.
-}
-
-// Same as above, but do not call RegisterEmptyPacket. Target level stays the
-// same.
-TEST_F(DelayManagerTest, EmptyPacketsNotReported) {
- SetPacketAudioLength(kFrameSizeMs);
- // First packet arrival.
- InsertNextPacket();
-
- // Advance time by one frame size.
- IncreaseTime(kFrameSizeMs);
-
- // Advance the sequence number by 10, simulating that 10 empty packets were
- // received, but never inserted.
- seq_no_ += 10;
-
- // Second packet arrival.
- InsertNextPacket();
-
- EXPECT_EQ(1 << 8, dm_->TargetLevel()); // In Q8.
+ EXPECT_EQ(kBaseMinimumDelayMs, dm_->TargetDelayMs());
}
TEST_F(DelayManagerTest, Failures) {
// Wrong sample rate.
- EXPECT_EQ(absl::nullopt, dm_->Update(0, 0, -1));
+ EXPECT_EQ(absl::nullopt, dm_->Update(0, -1));
// Wrong packet size.
EXPECT_EQ(-1, dm_->SetPacketAudioLength(0));
EXPECT_EQ(-1, dm_->SetPacketAudioLength(-1));
// Minimum delay higher than a maximum delay is not accepted.
- EXPECT_TRUE(dm_->SetMaximumDelay(10));
- EXPECT_FALSE(dm_->SetMinimumDelay(20));
+ EXPECT_TRUE(dm_->SetMaximumDelay(20));
+ EXPECT_FALSE(dm_->SetMinimumDelay(40));
// Maximum delay less than minimum delay is not accepted.
EXPECT_TRUE(dm_->SetMaximumDelay(100));
@@ -510,7 +386,6 @@
use_mock_histogram_ = true;
RecreateDelayManager();
- SetPacketAudioLength(kFrameSizeMs);
InsertNextPacket();
IncreaseTime(kFrameSizeMs);
@@ -519,21 +394,42 @@
IncreaseTime(2 * kFrameSizeMs);
EXPECT_CALL(*mock_histogram_, Add(1)); // 20ms delayed.
- dm_->Update(seq_no_, ts_, kFs);
+ dm_->Update(ts_, kFs);
IncreaseTime(2 * kFrameSizeMs);
EXPECT_CALL(*mock_histogram_, Add(2)); // 40ms delayed.
- dm_->Update(seq_no_ + 1, ts_ + kTsIncrement, kFs);
+ dm_->Update(ts_ + kTsIncrement, kFs);
EXPECT_CALL(*mock_histogram_, Add(1)); // Reordered, 20ms delayed.
- dm_->Update(seq_no_, ts_, kFs);
+ dm_->Update(ts_, kFs);
+}
+
+TEST_F(DelayManagerTest, ReorderedPackets) {
+ use_mock_histogram_ = true;
+ RecreateDelayManager();
+
+ // Insert first packet.
+ InsertNextPacket();
+
+ // Insert reordered packet.
+ EXPECT_CALL(*mock_histogram_, Add(4));
+ dm_->Update(ts_ - 5 * kTsIncrement, kFs);
+
+ // Insert another reordered packet.
+ EXPECT_CALL(*mock_histogram_, Add(1));
+ dm_->Update(ts_ - 2 * kTsIncrement, kFs);
+
+ // Insert the next packet in order and verify that the relative delay is
+ // estimated based on the first inserted packet.
+ IncreaseTime(4 * kFrameSizeMs);
+ EXPECT_CALL(*mock_histogram_, Add(3));
+ InsertNextPacket();
}
TEST_F(DelayManagerTest, MaxDelayHistory) {
use_mock_histogram_ = true;
RecreateDelayManager();
- SetPacketAudioLength(kFrameSizeMs);
InsertNextPacket();
// Insert 20 ms iat delay in the delay history.
@@ -547,11 +443,10 @@
IncreaseTime(kMaxHistoryMs + kFrameSizeMs);
ts_ += kFs * kMaxHistoryMs / 1000;
EXPECT_CALL(*mock_histogram_, Add(0)); // Not delayed.
- dm_->Update(seq_no_, ts_, kFs);
+ dm_->Update(ts_, kFs);
}
TEST_F(DelayManagerTest, RelativeArrivalDelayStatistic) {
- SetPacketAudioLength(kFrameSizeMs);
EXPECT_EQ(absl::nullopt, InsertNextPacket());
IncreaseTime(kFrameSizeMs);
EXPECT_EQ(0, InsertNextPacket());
@@ -560,38 +455,4 @@
EXPECT_EQ(20, InsertNextPacket());
}
-TEST_F(DelayManagerTest, DecelerationTargetLevelOffset) {
- SetPacketAudioLength(kFrameSizeMs);
-
- // Deceleration target level offset follows the value hardcoded in
- // delay_manager.cc.
- constexpr int kDecelerationTargetLevelOffsetMs = 85 << 8; // In Q8.
- // Border value where |x * 3/4 = target_level - x|.
- constexpr int kBoarderTargetLevel = kDecelerationTargetLevelOffsetMs * 4;
- {
- // Test that for a low target level, default behaviour is intact.
- const int target_level_ms = kBoarderTargetLevel / kFrameSizeMs - 1;
-
- int lower, higher; // In Q8.
- dm_->BufferLimits(target_level_ms, &lower, &higher);
-
- // Default behaviour of taking 75% of target level.
- EXPECT_EQ(target_level_ms * 3 / 4, lower);
- EXPECT_EQ(target_level_ms, higher);
- }
-
- {
- // Test that for the high target level, |lower| is below target level by
- // fixed |kOffset|.
- const int target_level_ms = kBoarderTargetLevel / kFrameSizeMs + 1;
-
- int lower, higher; // In Q8.
- dm_->BufferLimits(target_level_ms, &lower, &higher);
-
- EXPECT_EQ(target_level_ms - kDecelerationTargetLevelOffsetMs / kFrameSizeMs,
- lower);
- EXPECT_EQ(target_level_ms, higher);
- }
-}
-
} // namespace webrtc
diff --git a/modules/audio_coding/neteq/neteq_impl_unittest.cc b/modules/audio_coding/neteq/neteq_impl_unittest.cc
index 5c7259f..44660fc 100644
--- a/modules/audio_coding/neteq/neteq_impl_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_impl_unittest.cc
@@ -804,8 +804,10 @@
EXPECT_EQ(NetEq::kOK, neteq_->GetAudio(&output, &muted));
}
- // Insert one more packet.
- insert_packet();
+ // Insert a few packets to avoid postpone decoding after expand.
+ for (size_t i = 0; i < 5; ++i) {
+ insert_packet();
+ }
// Pull audio until the newly inserted packet is decoded and the PLC ends.
while (output.speech_type_ != AudioFrame::kNormalSpeech) {
@@ -881,8 +883,10 @@
EXPECT_NE(AudioFrame::kNormalSpeech, output.speech_type_);
}
- // Insert one more packet.
- insert_packet();
+ // Insert a few packets to avoid postpone decoding after expand.
+ for (size_t i = 0; i < 5; ++i) {
+ insert_packet();
+ }
// Pull audio until the newly inserted packet is decoded and the PLC ends.
while (output.speech_type_ != AudioFrame::kNormalSpeech) {
@@ -1299,7 +1303,7 @@
SdpAudioFormat("L16", 8000, 1)));
// Insert packets.
- for (int i = 0; i < 6; ++i) {
+ for (int i = 0; i < 20; ++i) {
rtp_header.sequenceNumber += 1;
rtp_header.timestamp += kFrameLengthSamples;
EXPECT_EQ(NetEq::kOK, neteq_->InsertPacket(rtp_header, payload));
diff --git a/modules/audio_coding/neteq/neteq_unittest.cc b/modules/audio_coding/neteq/neteq_unittest.cc
index d7030bf..c6d514d 100644
--- a/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/modules/audio_coding/neteq/neteq_unittest.cc
@@ -84,16 +84,16 @@
webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp");
const std::string output_checksum =
- PlatformChecksum("6ae9f643dc3e5f3452d28a772eef7e00e74158bc",
- "f4374430e870d66268c1b8e22fb700eb072d567e", "not used",
- "6ae9f643dc3e5f3452d28a772eef7e00e74158bc",
- "8d73c98645917cdeaaa01c20cf095ccc5a10b2b5");
+ PlatformChecksum("68ec266d2d152dfc0d938484e7936f6af4f803e3",
+ "1c243feb35e3e9ab37039eddf5b3c3ecfca3c60c", "not used",
+ "68ec266d2d152dfc0d938484e7936f6af4f803e3",
+ "f68c546a43bb25743297c9c0c9027e8424b8e10b");
const std::string network_stats_checksum =
- PlatformChecksum("8e50f528f245b7957db20ab406a72d81be60f5f4",
- "4260b22ea6d2723b2d573e50d2c1476680c7fa4c", "not used",
- "8e50f528f245b7957db20ab406a72d81be60f5f4",
- "8e50f528f245b7957db20ab406a72d81be60f5f4");
+ PlatformChecksum("2a5516cdc1c6af9f1d9d3c2f95ed292f509311c7",
+ "e96a7f081ebc111f49c7373d3728274057012ae9", "not used",
+ "2a5516cdc1c6af9f1d9d3c2f95ed292f509311c7",
+ "2a5516cdc1c6af9f1d9d3c2f95ed292f509311c7");
DecodeAndCompare(input_rtp_file, output_checksum, network_stats_checksum,
absl::GetFlag(FLAGS_gen_ref));
@@ -113,13 +113,13 @@
"554ad4133934e3920f97575579a46f674683d77c"
"|de316e2bfb15192edb820fe5fb579d11ff5a524b";
const std::string output_checksum = PlatformChecksum(
- maybe_sse, "459c356a0ef245ddff381f7d82d205d426ef2002",
- "625055e5eb0e6de2c9d170b4494eadc5afab08c8", maybe_sse, maybe_sse);
+ maybe_sse, "b3fac4ad4f6ea384aff676ee1ea816bd70415490",
+ "373ccd99c147cd3fcef0e7dcad6f87d0f8e5a1c0", maybe_sse, maybe_sse);
const std::string network_stats_checksum =
PlatformChecksum("ec29e047b019a86ec06e2c40643143dc1975c69f",
- "0c24649824eb7147d4891b0767e86e732dd6ecc8",
- "10f3e0b66c6947f78d60301454f2841033a6fcc0",
+ "ce6f519bc1220b003944ac5d9db077665a06834e",
+ "abb686d3ac6fac0001ca8d45a6ca6f5aefb2f9d6",
"ec29e047b019a86ec06e2c40643143dc1975c69f",
"ec29e047b019a86ec06e2c40643143dc1975c69f");
@@ -138,14 +138,14 @@
webrtc::test::ResourcePath("audio_coding/neteq_opus_dtx", "rtp");
const std::string maybe_sse =
- "df5d1d3019bf3764829b84f4fb315721f4adde29"
- "|5935d2fad14a69a8b61dbc8e6f2d37c8c0814925";
+ "0fb0a3d6b3758ca6e108368bb777cd38d0a865af"
+ "|79cfb99a21338ba977eb0e15eb8464e2db9436f8";
const std::string output_checksum = PlatformChecksum(
- maybe_sse, "551df04e8f45cd99eff28503edf0cf92974898ac",
- "709a3f0f380393d3a67bace10e2265b90a6ebbeb", maybe_sse, maybe_sse);
+ maybe_sse, "b6632690f8d7c2340c838df2821fc014f1cc8360",
+ "f890b9eb9bc5ab8313489230726b297f6a0825af", maybe_sse, maybe_sse);
const std::string network_stats_checksum =
- "80f5283ac71b27596204210152927666c1732de4";
+ "18983bb67a57628c604dbdefa99574c6e0c5bb48";
DecodeAndCompare(input_rtp_file, output_checksum, network_stats_checksum,
absl::GetFlag(FLAGS_gen_ref));
@@ -737,8 +737,10 @@
GetAudioUntilMuted();
EXPECT_NE(AudioFrame::kNormalSpeech, out_frame_.speech_type_);
- // Insert packet which is older than the first packet.
- InsertPacket(kSamples * (counter_ - 1000));
+ // Insert a few packets which are older than the first packet.
+ for (int i = 0; i < 5; ++i) {
+ InsertPacket(kSamples * (i - 1000));
+ }
EXPECT_FALSE(GetAudioReturnMuted());
EXPECT_EQ(AudioFrame::kNormalSpeech, out_frame_.speech_type_);
}
@@ -853,9 +855,11 @@
// Insert new data. Timestamp is corrected for the time elapsed since the last
// packet.
- PopulateRtpInfo(0, kSamples * 1000, &rtp_info);
- EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload));
- EXPECT_EQ(0, neteq2_->InsertPacket(rtp_info, payload));
+ for (int i = 0; i < 5; ++i) {
+ PopulateRtpInfo(0, kSamples * 1000 + kSamples * i, &rtp_info);
+ EXPECT_EQ(0, neteq_->InsertPacket(rtp_info, payload));
+ EXPECT_EQ(0, neteq2_->InsertPacket(rtp_info, payload));
+ }
int counter = 0;
while (out_frame1.speech_type_ != AudioFrame::kNormalSpeech) {
@@ -1264,7 +1268,7 @@
// The base delay values are taken from the resuts of the non-delayed case in
// NetEqOutputDelayTest.RunTest above.
- EXPECT_EQ(10 + kExpectedDelayMs, result.target_delay_ms);
+ EXPECT_EQ(20 + kExpectedDelayMs, result.target_delay_ms);
EXPECT_EQ(24 + kExpectedDelayMs, result.filtered_current_delay_ms);
}
@@ -1279,7 +1283,7 @@
// The base delay values are taken from the resuts of the non-delayed case in
// NetEqOutputDelayTest.RunTest above.
- EXPECT_EQ(10 + kRoundedDelayMs, result.target_delay_ms);
+ EXPECT_EQ(20 + kRoundedDelayMs, result.target_delay_ms);
EXPECT_EQ(24 + kRoundedDelayMs, result.filtered_current_delay_ms);
}