Source code

Revision control

Copy as Markdown

Other Tools

/*
* Copyright (c) 2024 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/delay_constraints.h"
#include "rtc_base/checks.h"
#include "test/gtest.h"
namespace webrtc {
namespace {
constexpr int kMaxNumberOfPackets = 200;
constexpr int kFrameSizeMs = 20;
constexpr int kMaxBufferSizeMs = kMaxNumberOfPackets * kFrameSizeMs;
TEST(DelayConstraintsTest, NoConstraints) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
EXPECT_EQ(constraints.Clamp(100), 100);
EXPECT_EQ(constraints.Clamp(0), 0);
}
TEST(DelayConstraintsTest, MaxDelay) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
constexpr int kMaxDelayMs = 60;
EXPECT_TRUE(constraints.SetMaximumDelay(kMaxDelayMs));
EXPECT_EQ(constraints.Clamp(100), kMaxDelayMs);
}
TEST(DelayConstraintsTest, MinDelay) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
constexpr int kMinDelayMs = 7 * kFrameSizeMs;
constraints.SetMinimumDelay(kMinDelayMs);
EXPECT_EQ(constraints.Clamp(20), kMinDelayMs);
}
TEST(DelayConstraintsTest, BaseMinimumDelayCheckValidRange) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
// Base minimum delay should be between [0, 10000] milliseconds.
EXPECT_FALSE(constraints.SetBaseMinimumDelay(-1));
EXPECT_FALSE(constraints.SetBaseMinimumDelay(10001));
EXPECT_EQ(constraints.GetBaseMinimumDelay(), 0);
EXPECT_TRUE(constraints.SetBaseMinimumDelay(7999));
EXPECT_EQ(constraints.GetBaseMinimumDelay(), 7999);
}
TEST(DelayConstraintsTest, BaseMinimumDelayLowerThanMinimumDelay) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
constexpr int kBaseMinimumDelayMs = 100;
constexpr int kMinimumDelayMs = 200;
// Base minimum delay sets lower bound on minimum. That is why when base
// minimum delay is lower than minimum delay we use minimum delay.
RTC_DCHECK_LT(kBaseMinimumDelayMs, kMinimumDelayMs);
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMs));
EXPECT_TRUE(constraints.SetMinimumDelay(kMinimumDelayMs));
EXPECT_EQ(constraints.effective_minimum_delay_ms_for_test(), kMinimumDelayMs);
}
TEST(DelayConstraintsTest, BaseMinimumDelayGreaterThanMinimumDelay) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
constexpr int kBaseMinimumDelayMs = 70;
constexpr int kMinimumDelayMs = 30;
// Base minimum delay sets lower bound on minimum. That is why when base
// minimum delay is greater than minimum delay we use base minimum delay.
RTC_DCHECK_GT(kBaseMinimumDelayMs, kMinimumDelayMs);
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMs));
EXPECT_TRUE(constraints.SetMinimumDelay(kMinimumDelayMs));
EXPECT_EQ(constraints.effective_minimum_delay_ms_for_test(),
kBaseMinimumDelayMs);
}
TEST(DelayConstraintsTest, BaseMinimumDelayGreaterThanBufferSize) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
constexpr int kBaseMinimumDelayMs = kMaxBufferSizeMs + 1;
constexpr int kMinimumDelayMs = 12;
constexpr int kMaximumDelayMs = 20;
constexpr int kMaxBufferSizeMsQ75 = 3 * kMaxBufferSizeMs / 4;
EXPECT_TRUE(constraints.SetPacketAudioLength(kFrameSizeMs));
EXPECT_TRUE(constraints.SetMaximumDelay(kMaximumDelayMs));
// Base minimum delay is greater than minimum delay, that is why we clamp
// it to current the highest possible value which is maximum delay.
RTC_DCHECK_GT(kBaseMinimumDelayMs, kMinimumDelayMs);
RTC_DCHECK_GT(kBaseMinimumDelayMs, kMaxBufferSizeMs);
RTC_DCHECK_GT(kBaseMinimumDelayMs, kMaximumDelayMs);
RTC_DCHECK_LT(kMaximumDelayMs, kMaxBufferSizeMsQ75);
EXPECT_TRUE(constraints.SetMinimumDelay(kMinimumDelayMs));
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMs));
// Unset maximum value.
EXPECT_TRUE(constraints.SetMaximumDelay(0));
// With maximum value unset, the highest possible value now is 75% of
// currently possible maximum buffer size.
EXPECT_EQ(constraints.effective_minimum_delay_ms_for_test(),
kMaxBufferSizeMsQ75);
}
TEST(DelayConstraintsTest, BaseMinimumDelayGreaterThanMaximumDelay) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
constexpr int kMaximumDelayMs = 400;
constexpr int kBaseMinimumDelayMs = kMaximumDelayMs + 1;
constexpr int kMinimumDelayMs = 20;
// Base minimum delay is greater than minimum delay, that is why we clamp
// it to current the highest possible value which is kMaximumDelayMs.
RTC_DCHECK_GT(kBaseMinimumDelayMs, kMinimumDelayMs);
RTC_DCHECK_GT(kBaseMinimumDelayMs, kMaximumDelayMs);
RTC_DCHECK_LT(kMaximumDelayMs, kMaxBufferSizeMs);
EXPECT_TRUE(constraints.SetMaximumDelay(kMaximumDelayMs));
EXPECT_TRUE(constraints.SetMinimumDelay(kMinimumDelayMs));
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMs));
EXPECT_EQ(constraints.effective_minimum_delay_ms_for_test(), kMaximumDelayMs);
}
TEST(DelayConstraintsTest, BaseMinimumDelayLowerThanMaxSize) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
constexpr int kMaximumDelayMs = 400;
constexpr int kBaseMinimumDelayMs = kMaximumDelayMs - 1;
constexpr int kMinimumDelayMs = 20;
// Base minimum delay is greater than minimum delay, and lower than maximum
// delays that is why it is used.
RTC_DCHECK_GT(kBaseMinimumDelayMs, kMinimumDelayMs);
RTC_DCHECK_LT(kBaseMinimumDelayMs, kMaximumDelayMs);
EXPECT_TRUE(constraints.SetMaximumDelay(kMaximumDelayMs));
EXPECT_TRUE(constraints.SetMinimumDelay(kMinimumDelayMs));
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMs));
EXPECT_EQ(constraints.effective_minimum_delay_ms_for_test(),
kBaseMinimumDelayMs);
}
TEST(DelayConstraintsTest, MinimumDelayMemorization) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
// Check that when we increase base minimum delay to value higher than
// 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.
constexpr int kBaseMinimumDelayMsLow = 10;
constexpr int kMinimumDelayMs = 20;
constexpr int kBaseMinimumDelayMsHigh = 30;
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMsLow));
EXPECT_TRUE(constraints.SetMinimumDelay(kMinimumDelayMs));
// Minimum delay is used as it is higher than base minimum delay.
EXPECT_EQ(constraints.effective_minimum_delay_ms_for_test(), kMinimumDelayMs);
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMsHigh));
// Base minimum delay is used as it is now higher than minimum delay.
EXPECT_EQ(constraints.effective_minimum_delay_ms_for_test(),
kBaseMinimumDelayMsHigh);
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMsLow));
// Check that minimum delay is memorized and is used again.
EXPECT_EQ(constraints.effective_minimum_delay_ms_for_test(), kMinimumDelayMs);
}
TEST(DelayConstraintsTest, BaseMinimumDelay) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
constexpr int kBaseMinimumDelayMs = 7 * kFrameSizeMs;
EXPECT_TRUE(constraints.SetBaseMinimumDelay(kBaseMinimumDelayMs));
EXPECT_EQ(constraints.GetBaseMinimumDelay(), kBaseMinimumDelayMs);
EXPECT_EQ(constraints.Clamp(20), kBaseMinimumDelayMs);
}
TEST(DelayConstraintsTest, Failures) {
DelayConstraints constraints(kMaxNumberOfPackets, 0);
// Wrong packet size.
EXPECT_FALSE(constraints.SetPacketAudioLength(0));
EXPECT_FALSE(constraints.SetPacketAudioLength(-1));
// Minimum delay higher than a maximum delay is not accepted.
EXPECT_TRUE(constraints.SetMaximumDelay(20));
EXPECT_FALSE(constraints.SetMinimumDelay(40));
// Maximum delay less than minimum delay is not accepted.
EXPECT_TRUE(constraints.SetMaximumDelay(100));
EXPECT_TRUE(constraints.SetMinimumDelay(80));
EXPECT_FALSE(constraints.SetMaximumDelay(60));
}
} // namespace
} // namespace webrtc