diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc index 4e7493e9d7..590dc30f47 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 @@ class AcmReceiverBitExactnessOldApi : public ::testing::Test { 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 @@ TEST_F(AcmReceiverBitExactnessOldApi, 48kHzOutputExternalDecoder) { rtc::scoped_refptr> factory( new rtc::RefCountedObject); 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, IsacWb30ms) { 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, MAYBE_IsacSwb30ms) { 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 d238665ba2..7ad006545d 100644 --- a/modules/audio_coding/neteq/buffer_level_filter.cc +++ b/modules/audio_coding/neteq/buffer_level_filter.cc @@ -45,12 +45,12 @@ void BufferLevelFilter::Update(size_t buffer_size_samples, 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 6dd424991b..bb3185667c 100644 --- a/modules/audio_coding/neteq/buffer_level_filter.h +++ b/modules/audio_coding/neteq/buffer_level_filter.h @@ -23,15 +23,13 @@ class BufferLevelFilter { 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 bc42595cd1..63fc83be67 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 @@ TEST(BufferLevelFilter, ConvergenceTest) { 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 @@ TEST(BufferLevelFilter, FilterFactor) { 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 @@ TEST(BufferLevelFilter, FilterFactor) { 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 @@ TEST(BufferLevelFilter, FilterFactor) { 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, FilterFactor) { 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 8e1ffaf9fe..a4de9b8bb4 100644 --- a/modules/audio_coding/neteq/decision_logic.cc +++ b/modules/audio_coding/neteq/decision_logic.cc @@ -27,6 +27,7 @@ namespace { constexpr int kPostponeDecodingLevel = 50; constexpr int kDefaultTargetLevelWindowMs = 100; +constexpr int kDecelerationTargetLevelOffsetMs = 85; } // namespace @@ -35,7 +36,6 @@ namespace webrtc { 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 @@ void DecisionLogic::Reset() { 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 @@ void DecisionLogic::SoftReset() { 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 @@ NetEq::Operation DecisionLogic::GetDecision(const NetEqStatus& status, 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(delay_manager_->TargetLevel() * - packet_length_samples_ * - kPostponeDecodingLevel / 100)>> 8 && + current_span < static_cast(target_level_samples * + kPostponeDecodingLevel / 100) && !status.packet_buffer_info.dtx_or_cng) { return NetEq::Operation::kExpand; } @@ -195,41 +198,32 @@ void DecisionLogic::ExpandDecision(NetEq::Operation operation) { } } -absl::optional DecisionLogic::PacketArrived(bool last_cng_or_dtmf, +absl::optional 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 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((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 @@ NetEq::Operation DecisionLogic::CngOperation(NetEq::Mode prev_mode, int32_t timestamp_diff = static_cast( static_cast(generated_noise_samples + target_timestamp) - available_timestamp); - int32_t optimal_level_samp = static_cast( - (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(timestamp_diff) - optimal_level_samp; @@ -295,22 +289,26 @@ NetEq::Operation DecisionLogic::ExpectedPacketAvailable(NetEq::Mode prev_mode, 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 @@ NetEq::Operation DecisionLogic::FuturePacketAvailable( 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(generated_noise_samples + target_timestamp) >= available_timestamp; @@ -406,13 +404,8 @@ NetEq::Operation DecisionLogic::FuturePacketAvailable( } 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 c3d82eb52f..d4d69edb04 100644 --- a/modules/audio_coding/neteq/decision_logic.h +++ b/modules/audio_coding/neteq/decision_logic.h @@ -70,19 +70,16 @@ class DecisionLogic : public NetEqController { // 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 PacketArrived(bool last_cng_or_dtmf, + absl::optional 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 @@ class DecisionLogic : public NetEqController { 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 @@ class DecisionLogic : public NetEqController { std::unique_ptr timescale_countdown_; int num_consecutive_expands_ = 0; int time_stretched_cn_samples_ = 0; + bool last_pack_cng_or_dtmf_ = true; FieldTrialParameter estimate_dtx_delay_; FieldTrialParameter time_stretch_cn_; FieldTrialConstrained 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 a5b6712e73..56e8b84722 100644 --- a/modules/audio_coding/neteq/decision_logic_unittest.cc +++ b/modules/audio_coding/neteq/decision_logic_unittest.cc @@ -43,6 +43,6 @@ TEST(DecisionLogic, CreateAndDestroy) { 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 4ae6d108cb..5b541867a3 100644 --- a/modules/audio_coding/neteq/delay_manager.cc +++ b/modules/audio_coding/neteq/delay_manager.cc @@ -27,17 +27,16 @@ #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; int PercentileToQuantile(double percentile) { return static_cast((1 << 30) * percentile / 100.0 + 0.5); @@ -49,6 +48,7 @@ struct DelayHistogramConfig { absl::optional start_forget_weight = 2; }; +// TODO(jakobi): Remove legacy field trial. DelayHistogramConfig GetDelayHistogramConfig() { constexpr char kDelayHistogramFieldTrial[] = "WebRTC-Audio-NetEqDelayHistogram"; @@ -81,12 +81,9 @@ DelayHistogramConfig GetDelayHistogramConfig() { } // 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) : first_packet_received_(false), @@ -96,15 +93,10 @@ DelayManager::DelayManager(size_t max_packets_in_buffer, 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 +104,70 @@ DelayManager::DelayManager(size_t max_packets_in_buffer, } std::unique_ptr 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 = std::make_unique( kDelayBuckets, config.forget_factor, config.start_forget_weight); - return std::make_unique( - max_packets_in_buffer, base_minimum_delay_ms, quantile, - enable_rtx_handling, tick_timer, std::move(histogram)); + return std::make_unique(max_packets_in_buffer, + base_minimum_delay_ms, config.quantile, + tick_timer, std::move(histogram)); } DelayManager::~DelayManager() {} -absl::optional DelayManager::Update(uint16_t sequence_number, - uint32_t timestamp, - int sample_rate_hz) { +absl::optional 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; 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_; - } else { - // Calculate timestamps per packet and derive packet length in ms. - int64_t packet_len_samp = - static_cast(timestamp - last_timestamp_) / - static_cast(sequence_number - last_seq_no_); - packet_len_ms = - rtc::saturated_cast(1000 * packet_len_samp / sample_rate_hz); - } - - bool reordered = false; + const int expected_iat_ms = + 1000 * 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; absl::optional 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(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(last_seq_no_ + 1 - sequence_number); - iat_ms += packet_offset * packet_len_ms; - reordered = true; - } - - 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; + if (!IsNewerTimestamp(timestamp, last_timestamp_)) { + relative_delay = std::max(iat_delay_ms, 0); + // Reset the history and restart delay estimation from this packet. + delay_history_.clear(); + } else { + UpdateDelayHistory(iat_delay_ms, timestamp, sample_rate_hz); + relative_delay = CalculateRelativePacketArrivalDelay(); } - num_reordered_packets_ = 0; + 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); + } + // Prepare for next packet arrival. packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch(); - last_seq_no_ = sequence_number; last_timestamp_ = timestamp; return relative_delay; } @@ -238,128 +198,26 @@ int DelayManager::CalculateRelativePacketArrivalDelay() const { 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((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; } -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 +267,6 @@ int DelayManager::GetBaseMinimumDelay() const { 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 +279,11 @@ void DelayManager::UpdateEffectiveMinimumDelay() { 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(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 ab9ba34167..d503e0239f 100644 --- a/modules/audio_coding/neteq/delay_manager.h +++ b/modules/audio_coding/neteq/delay_manager.h @@ -25,10 +25,9 @@ namespace webrtc { 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); @@ -37,58 +36,29 @@ class DelayManager { // 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 Create(size_t max_packets_in_buffer, + static std::unique_ptr 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 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 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 @@ class DelayManager { 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 @@ class DelayManager { // 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 @@ class DelayManager { // 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,21 @@ class DelayManager { 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_; 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 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 + 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. 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 4a118f765f..50939461f1 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 kFrameSizeMs = 20; 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 InsertNextPacket(); void IncreaseTime(int inc_ms); @@ -55,15 +51,12 @@ class DelayManagerTest : public ::testing::Test { 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::SetUp() { void DelayManagerTest::RecreateDelayManager() { if (use_mock_histogram_) { - mock_histogram_ = new MockHistogram(kMaxIat, kForgetFactor); + mock_histogram_ = new MockHistogram(kNumBuckets, kForgetFactor); std::unique_ptr histogram(mock_histogram_); - dm_ = std::make_unique( - kMaxNumberOfPackets, kMinDelayMs, kDefaultHistogramQuantile, - enable_rtx_handling_, &tick_timer_, std::move(histogram)); + dm_ = std::make_unique(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 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 @@ TEST_F(DelayManagerTest, CreateAndDestroy) { // 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, BaseMinimumDelayCheckValidRange) { } TEST_F(DelayManagerTest, BaseMinimumDelayLowerThanMinimumDelay) { - SetPacketAudioLength(kFrameSizeMs); constexpr int kBaseMinimumDelayMs = 100; constexpr int kMinimumDelayMs = 200; @@ -221,7 +176,6 @@ TEST_F(DelayManagerTest, BaseMinimumDelayLowerThanMinimumDelay) { } TEST_F(DelayManagerTest, BaseMinimumDelayGreaterThanMinimumDelay) { - SetPacketAudioLength(kFrameSizeMs); constexpr int kBaseMinimumDelayMs = 70; constexpr int kMinimumDelayMs = 30; @@ -235,7 +189,6 @@ TEST_F(DelayManagerTest, BaseMinimumDelayGreaterThanMinimumDelay) { } 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, BaseMinimumDelayGreaterThanBufferSize) { } 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, BaseMinimumDelayGreaterThanMaximumDelay) { } TEST_F(DelayManagerTest, BaseMinimumDelayLowerThanMaxSize) { - SetPacketAudioLength(kFrameSizeMs); constexpr int kMaximumDelayMs = 400; constexpr int kBaseMinimumDelayMs = kMaximumDelayMs - 1; constexpr int kMinimumDelayMs = 20; @@ -301,8 +252,6 @@ TEST_F(DelayManagerTest, MinimumDelayMemorization) { // 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, MinimumDelayMemorization) { } 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 @@ TEST_F(DelayManagerTest, BaseMinimumDealyAffectTargetLevel) { 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 @@ TEST_F(DelayManagerTest, BaseMinimumDealyAffectTargetLevel) { 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 @@ TEST_F(DelayManagerTest, RelativeArrivalDelay) { use_mock_histogram_ = true; RecreateDelayManager(); - SetPacketAudioLength(kFrameSizeMs); InsertNextPacket(); IncreaseTime(kFrameSizeMs); @@ -519,21 +394,20 @@ TEST_F(DelayManagerTest, RelativeArrivalDelay) { 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, MaxDelayHistory) { use_mock_histogram_ = true; RecreateDelayManager(); - SetPacketAudioLength(kFrameSizeMs); InsertNextPacket(); // Insert 20 ms iat delay in the delay history. @@ -547,11 +421,10 @@ TEST_F(DelayManagerTest, MaxDelayHistory) { 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 +433,4 @@ TEST_F(DelayManagerTest, RelativeArrivalDelayStatistic) { 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 5c7259f00b..44660fc483 100644 --- a/modules/audio_coding/neteq/neteq_impl_unittest.cc +++ b/modules/audio_coding/neteq/neteq_impl_unittest.cc @@ -804,8 +804,10 @@ TEST_P(NetEqImplTestSampleRateParameter, 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 @@ TEST_P(NetEqImplTestSampleRateParameter, AudioInterruptionLogged) { 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 @@ TEST_F(NetEqImplTest, DecodingError) { 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 d7030bfd64..c6d514d827 100644 --- a/modules/audio_coding/neteq/neteq_unittest.cc +++ b/modules/audio_coding/neteq/neteq_unittest.cc @@ -84,16 +84,16 @@ TEST_F(NetEqDecodingTest, MAYBE_TestBitExactness) { 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 @@ TEST_F(NetEqDecodingTest, MAYBE_TestOpusBitExactness) { "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 @@ TEST_F(NetEqDecodingTest, MAYBE_TestOpusDtxBitExactness) { 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 @@ TEST_F(NetEqDecodingTestWithMutedState, MutedStateOldPacket) { 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 @@ TEST_F(NetEqDecodingTestTwoInstances, CompareMutedStateOnOff) { // 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 @@ TEST(NetEqOutputDelayTest, RunTestWithFieldTrial) { // 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 @@ TEST(NetEqOutputDelayTest, RunTestWithFieldTrialOddValue) { // 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); }