/* * Copyright (c) 2022 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. */ #include "modules/audio_coding/neteq/packet_arrival_history.h" #include #include #include "test/gtest.h" namespace webrtc { namespace { constexpr int kFs = 8000; constexpr int kFsKhz = kFs / 1000; constexpr int kFrameSizeMs = 20; constexpr int kWindowSizeMs = 1000; class PacketArrivalHistoryTest : public testing::Test { public: PacketArrivalHistoryTest() : history_(kWindowSizeMs) { history_.set_sample_rate(kFs); } void IncrementTime(int delta_ms) { time_ms_ += delta_ms; } int InsertPacketAndGetDelay(int timestamp_delta_ms) { uint32_t timestamp = timestamp_ + timestamp_delta_ms * kFsKhz; if (timestamp_delta_ms > 0) { timestamp_ = timestamp; } history_.Insert(timestamp, time_ms_); EXPECT_EQ(history_.IsNewestRtpTimestamp(timestamp), timestamp_delta_ms >= 0); return history_.GetDelayMs(timestamp, time_ms_); } protected: int64_t time_ms_ = 0; PacketArrivalHistory history_; uint32_t timestamp_ = 0x12345678; }; TEST_F(PacketArrivalHistoryTest, RelativeArrivalDelay) { EXPECT_EQ(InsertPacketAndGetDelay(0), 0); IncrementTime(kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 0); IncrementTime(2 * kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 20); // Reordered packet. EXPECT_EQ(InsertPacketAndGetDelay(-2 * kFrameSizeMs), 60); IncrementTime(2 * kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 40); // Move reference packet forward. EXPECT_EQ(InsertPacketAndGetDelay(4 * kFrameSizeMs), 0); IncrementTime(2 * kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 20); // Earlier packet is now more delayed due to the new reference packet. EXPECT_EQ(history_.GetMaxDelayMs(), 100); } TEST_F(PacketArrivalHistoryTest, ReorderedPackets) { // Insert first packet. EXPECT_EQ(InsertPacketAndGetDelay(0), 0); // Insert reordered packet. EXPECT_EQ(InsertPacketAndGetDelay(-80), 80); // Insert another reordered packet. EXPECT_EQ(InsertPacketAndGetDelay(-kFrameSizeMs), 20); // Insert the next packet in order and verify that the relative delay is // estimated based on the first inserted packet. IncrementTime(4 * kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 60); EXPECT_EQ(history_.GetMaxDelayMs(), 80); } TEST_F(PacketArrivalHistoryTest, MaxHistorySize) { EXPECT_EQ(InsertPacketAndGetDelay(0), 0); IncrementTime(2 * kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 20); EXPECT_EQ(history_.GetMaxDelayMs(), 20); // Insert next packet with a timestamp difference larger than maximum history // size. This removes the previously inserted packet from the history. IncrementTime(kWindowSizeMs + kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs + kWindowSizeMs), 0); EXPECT_EQ(history_.GetMaxDelayMs(), 0); } TEST_F(PacketArrivalHistoryTest, TimestampWraparound) { timestamp_ = std::numeric_limits::max(); EXPECT_EQ(InsertPacketAndGetDelay(0), 0); IncrementTime(2 * kFrameSizeMs); // Insert timestamp that will wrap around. EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), kFrameSizeMs); // Insert reordered packet before the wraparound. EXPECT_EQ(InsertPacketAndGetDelay(-2 * kFrameSizeMs), 3 * kFrameSizeMs); // Insert another in-order packet after the wraparound. EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 0); EXPECT_EQ(history_.GetMaxDelayMs(), 3 * kFrameSizeMs); } TEST_F(PacketArrivalHistoryTest, TimestampWraparoundBackwards) { timestamp_ = 0; EXPECT_EQ(InsertPacketAndGetDelay(0), 0); IncrementTime(2 * kFrameSizeMs); // Insert timestamp that will wrap around. EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), kFrameSizeMs); // Insert reordered packet before the wraparound. EXPECT_EQ(InsertPacketAndGetDelay(-2 * kFrameSizeMs), 3 * kFrameSizeMs); // Insert another in-order packet after the wraparound. EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 0); EXPECT_EQ(history_.GetMaxDelayMs(), 3 * kFrameSizeMs); } } // namespace } // namespace webrtc