webrtc/modules/audio_coding/neteq/delay_peak_detector_unittest.cc
Jakob Ivarsson 39b934ba2e Add NetEq config flag that enables RTX handling.
When enabled, the delay manager is updated with reordered packets. It also makes the peak detector ignore the reordered packets.

Change-Id: I2bdc99764cc76b15e613ed3dc75f83aaf66eee4e
Bug: webrtc:10178
Reviewed-on: https://webrtc-review.googlesource.com/c/116481
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Reviewed-by: Minyue Li <minyue@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26187}
2019-01-10 10:04:34 +00:00

161 lines
6 KiB
C++

/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Unit tests for DelayPeakDetector class.
#include "modules/audio_coding/neteq/delay_peak_detector.h"
#include "test/gtest.h"
namespace webrtc {
TEST(DelayPeakDetector, CreateAndDestroy) {
TickTimer tick_timer;
DelayPeakDetector* detector = new DelayPeakDetector(&tick_timer, false);
EXPECT_FALSE(detector->peak_found());
delete detector;
}
TEST(DelayPeakDetector, EmptyHistory) {
TickTimer tick_timer;
DelayPeakDetector detector(&tick_timer, false);
EXPECT_EQ(-1, detector.MaxPeakHeight());
EXPECT_EQ(0u, detector.MaxPeakPeriod());
}
// Inject a series of packet arrivals into the detector. Three of the packets
// have suffered delays. After the third delay peak, peak-mode is expected to
// start. This should then continue until it is disengaged due to lack of peaks.
TEST(DelayPeakDetector, TriggerPeakMode) {
TickTimer tick_timer;
DelayPeakDetector detector(&tick_timer, false);
const int kPacketSizeMs = 30;
detector.SetPacketAudioLength(kPacketSizeMs);
// Load up normal arrival times; 0 ms, 30 ms, 60 ms, 90 ms, ...
const int kNumPackets = 1000;
int arrival_times_ms[kNumPackets];
for (int i = 0; i < kNumPackets; ++i) {
arrival_times_ms[i] = i * kPacketSizeMs;
}
// Delay three packets.
const int kPeakDelayMs = 100;
// First delay peak.
arrival_times_ms[100] += kPeakDelayMs;
// Second delay peak.
arrival_times_ms[200] += kPeakDelayMs;
// Third delay peak. Trigger peak-mode after this packet.
arrival_times_ms[400] += kPeakDelayMs;
// The second peak period is the longest, 200 packets.
const uint64_t kWorstPeakPeriod = 200 * kPacketSizeMs;
int peak_mode_start_ms = arrival_times_ms[400];
// Expect to disengage after no peaks are observed for two period times.
int peak_mode_end_ms = peak_mode_start_ms + 2 * kWorstPeakPeriod;
// Load into detector.
int time = 0;
int next = 1; // Start with the second packet to get a proper IAT.
while (next < kNumPackets) {
while (next < kNumPackets && arrival_times_ms[next] <= time) {
int iat_packets =
(arrival_times_ms[next] - arrival_times_ms[next - 1]) / kPacketSizeMs;
const int kTargetBufferLevel = 1; // Define peaks to be iat > 2.
if (time < peak_mode_start_ms || time > peak_mode_end_ms) {
EXPECT_FALSE(detector.Update(iat_packets, false, kTargetBufferLevel));
} else {
EXPECT_TRUE(detector.Update(iat_packets, false, kTargetBufferLevel));
EXPECT_EQ(kWorstPeakPeriod, detector.MaxPeakPeriod());
EXPECT_EQ(kPeakDelayMs / kPacketSizeMs + 1, detector.MaxPeakHeight());
}
++next;
}
tick_timer.Increment();
time += 10; // Increase time 10 ms.
}
}
// Same test as TriggerPeakMode, but with base target buffer level increased to
// 2, in order to raise the bar for delay peaks to inter-arrival times > 4.
// The delay pattern has peaks with delay = 3, thus should not trigger.
TEST(DelayPeakDetector, DoNotTriggerPeakMode) {
TickTimer tick_timer;
DelayPeakDetector detector(&tick_timer, false);
const int kPacketSizeMs = 30;
detector.SetPacketAudioLength(kPacketSizeMs);
// Load up normal arrival times; 0 ms, 30 ms, 60 ms, 90 ms, ...
const int kNumPackets = 1000;
int arrival_times_ms[kNumPackets];
for (int i = 0; i < kNumPackets; ++i) {
arrival_times_ms[i] = i * kPacketSizeMs;
}
// Delay three packets.
const int kPeakDelayMs = 100;
// First delay peak.
arrival_times_ms[100] += kPeakDelayMs;
// Second delay peak.
arrival_times_ms[200] += kPeakDelayMs;
// Third delay peak.
arrival_times_ms[400] += kPeakDelayMs;
// Load into detector.
int time = 0;
int next = 1; // Start with the second packet to get a proper IAT.
while (next < kNumPackets) {
while (next < kNumPackets && arrival_times_ms[next] <= time) {
int iat_packets =
(arrival_times_ms[next] - arrival_times_ms[next - 1]) / kPacketSizeMs;
const int kTargetBufferLevel = 2; // Define peaks to be iat > 4.
EXPECT_FALSE(detector.Update(iat_packets, false, kTargetBufferLevel));
++next;
}
tick_timer.Increment();
time += 10; // Increase time 10 ms.
}
}
// In situations with reordered packets, the DelayPeakDetector may be updated
// back-to-back (i.e., without the tick_timer moving) but still with non-zero
// inter-arrival time. This test is to make sure that this does not cause
// problems.
TEST(DelayPeakDetector, ZeroDistancePeaks) {
TickTimer tick_timer;
DelayPeakDetector detector(&tick_timer, false);
const int kPacketSizeMs = 30;
detector.SetPacketAudioLength(kPacketSizeMs);
const int kTargetBufferLevel = 2; // Define peaks to be iat > 4.
const int kInterArrivalTime =
3 * kTargetBufferLevel; // Above peak threshold.
EXPECT_FALSE(detector.Update(kInterArrivalTime, false, kTargetBufferLevel));
tick_timer.Increment();
EXPECT_FALSE(detector.Update(kInterArrivalTime, false, kTargetBufferLevel));
// The following would fail if there were non-zero time between the updates.
EXPECT_FALSE(detector.Update(kInterArrivalTime, false, kTargetBufferLevel));
}
TEST(DelayPeakDetector, IgnoreReorderedPacket) {
TickTimer tick_timer;
DelayPeakDetector detector(&tick_timer, true);
const int kTargetBufferLevel = 2; // Define peaks to be iat > 4.
const int kInterArrivalTime =
3 * kTargetBufferLevel; // Above peak threshold.
EXPECT_FALSE(detector.Update(kInterArrivalTime, false, kTargetBufferLevel));
tick_timer.Increment();
EXPECT_FALSE(detector.Update(kInterArrivalTime, false, kTargetBufferLevel));
tick_timer.Increment();
// The following would fail if the packet was not reordered.
EXPECT_FALSE(detector.Update(kInterArrivalTime, true, kTargetBufferLevel));
}
} // namespace webrtc