1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 // Unit tests for DelayManager class.
12
13 #include "modules/audio_coding/neteq/delay_manager.h"
14
15 #include <math.h>
16
17 #include <memory>
18
19 #include "absl/types/optional.h"
20 #include "modules/audio_coding/neteq/histogram.h"
21 #include "modules/audio_coding/neteq/mock/mock_histogram.h"
22 #include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
23 #include "rtc_base/checks.h"
24 #include "test/field_trial.h"
25 #include "test/gmock.h"
26 #include "test/gtest.h"
27
28 namespace webrtc {
29
30 namespace {
31 constexpr int kMaxNumberOfPackets = 200;
32 constexpr int kTimeStepMs = 10;
33 constexpr int kFrameSizeMs = 20;
34 constexpr int kMaxBufferSizeMs = kMaxNumberOfPackets * kFrameSizeMs;
35
36 } // namespace
37
38 class DelayManagerTest : public ::testing::Test {
39 protected:
40 DelayManagerTest();
41 virtual void SetUp();
42 void Update(int delay);
43 void IncreaseTime(int inc_ms);
44
45 TickTimer tick_timer_;
46 DelayManager dm_;
47 };
48
DelayManagerTest()49 DelayManagerTest::DelayManagerTest()
50 : dm_(DelayManager::Config(), &tick_timer_) {}
51
SetUp()52 void DelayManagerTest::SetUp() {
53 dm_.SetPacketAudioLength(kFrameSizeMs);
54 }
55
Update(int delay)56 void DelayManagerTest::Update(int delay) {
57 dm_.Update(delay, false);
58 }
59
IncreaseTime(int inc_ms)60 void DelayManagerTest::IncreaseTime(int inc_ms) {
61 for (int t = 0; t < inc_ms; t += kTimeStepMs) {
62 tick_timer_.Increment();
63 }
64 }
65
TEST_F(DelayManagerTest,CreateAndDestroy)66 TEST_F(DelayManagerTest, CreateAndDestroy) {
67 // Nothing to do here. The test fixture creates and destroys the DelayManager
68 // object.
69 }
70
TEST_F(DelayManagerTest,UpdateNormal)71 TEST_F(DelayManagerTest, UpdateNormal) {
72 for (int i = 0; i < 50; ++i) {
73 Update(0);
74 IncreaseTime(kFrameSizeMs);
75 }
76 EXPECT_EQ(20, dm_.TargetDelayMs());
77 }
78
TEST_F(DelayManagerTest,MaxDelay)79 TEST_F(DelayManagerTest, MaxDelay) {
80 Update(0);
81 const int kMaxDelayMs = 60;
82 EXPECT_GT(dm_.TargetDelayMs(), kMaxDelayMs);
83 EXPECT_TRUE(dm_.SetMaximumDelay(kMaxDelayMs));
84 Update(0);
85 EXPECT_EQ(kMaxDelayMs, dm_.TargetDelayMs());
86 }
87
TEST_F(DelayManagerTest,MinDelay)88 TEST_F(DelayManagerTest, MinDelay) {
89 Update(0);
90 int kMinDelayMs = 7 * kFrameSizeMs;
91 EXPECT_LT(dm_.TargetDelayMs(), kMinDelayMs);
92 dm_.SetMinimumDelay(kMinDelayMs);
93 IncreaseTime(kFrameSizeMs);
94 Update(0);
95 EXPECT_EQ(kMinDelayMs, dm_.TargetDelayMs());
96 }
97
TEST_F(DelayManagerTest,BaseMinimumDelayCheckValidRange)98 TEST_F(DelayManagerTest, BaseMinimumDelayCheckValidRange) {
99 // Base minimum delay should be between [0, 10000] milliseconds.
100 EXPECT_FALSE(dm_.SetBaseMinimumDelay(-1));
101 EXPECT_FALSE(dm_.SetBaseMinimumDelay(10001));
102 EXPECT_EQ(dm_.GetBaseMinimumDelay(), 0);
103
104 EXPECT_TRUE(dm_.SetBaseMinimumDelay(7999));
105 EXPECT_EQ(dm_.GetBaseMinimumDelay(), 7999);
106 }
107
TEST_F(DelayManagerTest,BaseMinimumDelayLowerThanMinimumDelay)108 TEST_F(DelayManagerTest, BaseMinimumDelayLowerThanMinimumDelay) {
109 constexpr int kBaseMinimumDelayMs = 100;
110 constexpr int kMinimumDelayMs = 200;
111
112 // Base minimum delay sets lower bound on minimum. That is why when base
113 // minimum delay is lower than minimum delay we use minimum delay.
114 RTC_DCHECK_LT(kBaseMinimumDelayMs, kMinimumDelayMs);
115
116 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMs));
117 EXPECT_TRUE(dm_.SetMinimumDelay(kMinimumDelayMs));
118 EXPECT_EQ(dm_.effective_minimum_delay_ms_for_test(), kMinimumDelayMs);
119 }
120
TEST_F(DelayManagerTest,BaseMinimumDelayGreaterThanMinimumDelay)121 TEST_F(DelayManagerTest, BaseMinimumDelayGreaterThanMinimumDelay) {
122 constexpr int kBaseMinimumDelayMs = 70;
123 constexpr int kMinimumDelayMs = 30;
124
125 // Base minimum delay sets lower bound on minimum. That is why when base
126 // minimum delay is greater than minimum delay we use base minimum delay.
127 RTC_DCHECK_GT(kBaseMinimumDelayMs, kMinimumDelayMs);
128
129 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMs));
130 EXPECT_TRUE(dm_.SetMinimumDelay(kMinimumDelayMs));
131 EXPECT_EQ(dm_.effective_minimum_delay_ms_for_test(), kBaseMinimumDelayMs);
132 }
133
TEST_F(DelayManagerTest,BaseMinimumDelayGreaterThanBufferSize)134 TEST_F(DelayManagerTest, BaseMinimumDelayGreaterThanBufferSize) {
135 constexpr int kBaseMinimumDelayMs = kMaxBufferSizeMs + 1;
136 constexpr int kMinimumDelayMs = 12;
137 constexpr int kMaximumDelayMs = 20;
138 constexpr int kMaxBufferSizeMsQ75 = 3 * kMaxBufferSizeMs / 4;
139
140 EXPECT_TRUE(dm_.SetMaximumDelay(kMaximumDelayMs));
141
142 // Base minimum delay is greater than minimum delay, that is why we clamp
143 // it to current the highest possible value which is maximum delay.
144 RTC_DCHECK_GT(kBaseMinimumDelayMs, kMinimumDelayMs);
145 RTC_DCHECK_GT(kBaseMinimumDelayMs, kMaxBufferSizeMs);
146 RTC_DCHECK_GT(kBaseMinimumDelayMs, kMaximumDelayMs);
147 RTC_DCHECK_LT(kMaximumDelayMs, kMaxBufferSizeMsQ75);
148
149 EXPECT_TRUE(dm_.SetMinimumDelay(kMinimumDelayMs));
150 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMs));
151
152 // Unset maximum value.
153 EXPECT_TRUE(dm_.SetMaximumDelay(0));
154
155 // With maximum value unset, the highest possible value now is 75% of
156 // currently possible maximum buffer size.
157 EXPECT_EQ(dm_.effective_minimum_delay_ms_for_test(), kMaxBufferSizeMsQ75);
158 }
159
TEST_F(DelayManagerTest,BaseMinimumDelayGreaterThanMaximumDelay)160 TEST_F(DelayManagerTest, BaseMinimumDelayGreaterThanMaximumDelay) {
161 constexpr int kMaximumDelayMs = 400;
162 constexpr int kBaseMinimumDelayMs = kMaximumDelayMs + 1;
163 constexpr int kMinimumDelayMs = 20;
164
165 // Base minimum delay is greater than minimum delay, that is why we clamp
166 // it to current the highest possible value which is kMaximumDelayMs.
167 RTC_DCHECK_GT(kBaseMinimumDelayMs, kMinimumDelayMs);
168 RTC_DCHECK_GT(kBaseMinimumDelayMs, kMaximumDelayMs);
169 RTC_DCHECK_LT(kMaximumDelayMs, kMaxBufferSizeMs);
170
171 EXPECT_TRUE(dm_.SetMaximumDelay(kMaximumDelayMs));
172 EXPECT_TRUE(dm_.SetMinimumDelay(kMinimumDelayMs));
173 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMs));
174 EXPECT_EQ(dm_.effective_minimum_delay_ms_for_test(), kMaximumDelayMs);
175 }
176
TEST_F(DelayManagerTest,BaseMinimumDelayLowerThanMaxSize)177 TEST_F(DelayManagerTest, BaseMinimumDelayLowerThanMaxSize) {
178 constexpr int kMaximumDelayMs = 400;
179 constexpr int kBaseMinimumDelayMs = kMaximumDelayMs - 1;
180 constexpr int kMinimumDelayMs = 20;
181
182 // Base minimum delay is greater than minimum delay, and lower than maximum
183 // delays that is why it is used.
184 RTC_DCHECK_GT(kBaseMinimumDelayMs, kMinimumDelayMs);
185 RTC_DCHECK_LT(kBaseMinimumDelayMs, kMaximumDelayMs);
186
187 EXPECT_TRUE(dm_.SetMaximumDelay(kMaximumDelayMs));
188 EXPECT_TRUE(dm_.SetMinimumDelay(kMinimumDelayMs));
189 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMs));
190 EXPECT_EQ(dm_.effective_minimum_delay_ms_for_test(), kBaseMinimumDelayMs);
191 }
192
TEST_F(DelayManagerTest,MinimumDelayMemorization)193 TEST_F(DelayManagerTest, MinimumDelayMemorization) {
194 // Check that when we increase base minimum delay to value higher than
195 // minimum delay then minimum delay is still memorized. This allows to
196 // restore effective minimum delay to memorized minimum delay value when we
197 // decrease base minimum delay.
198 constexpr int kBaseMinimumDelayMsLow = 10;
199 constexpr int kMinimumDelayMs = 20;
200 constexpr int kBaseMinimumDelayMsHigh = 30;
201
202 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMsLow));
203 EXPECT_TRUE(dm_.SetMinimumDelay(kMinimumDelayMs));
204 // Minimum delay is used as it is higher than base minimum delay.
205 EXPECT_EQ(dm_.effective_minimum_delay_ms_for_test(), kMinimumDelayMs);
206
207 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMsHigh));
208 // Base minimum delay is used as it is now higher than minimum delay.
209 EXPECT_EQ(dm_.effective_minimum_delay_ms_for_test(), kBaseMinimumDelayMsHigh);
210
211 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMsLow));
212 // Check that minimum delay is memorized and is used again.
213 EXPECT_EQ(dm_.effective_minimum_delay_ms_for_test(), kMinimumDelayMs);
214 }
215
TEST_F(DelayManagerTest,BaseMinimumDelay)216 TEST_F(DelayManagerTest, BaseMinimumDelay) {
217 // First packet arrival.
218 Update(0);
219
220 constexpr int kBaseMinimumDelayMs = 7 * kFrameSizeMs;
221 EXPECT_LT(dm_.TargetDelayMs(), kBaseMinimumDelayMs);
222 EXPECT_TRUE(dm_.SetBaseMinimumDelay(kBaseMinimumDelayMs));
223 EXPECT_EQ(dm_.GetBaseMinimumDelay(), kBaseMinimumDelayMs);
224
225 IncreaseTime(kFrameSizeMs);
226 Update(0);
227 EXPECT_EQ(dm_.GetBaseMinimumDelay(), kBaseMinimumDelayMs);
228 EXPECT_EQ(kBaseMinimumDelayMs, dm_.TargetDelayMs());
229 }
230
TEST_F(DelayManagerTest,Failures)231 TEST_F(DelayManagerTest, Failures) {
232 // Wrong packet size.
233 EXPECT_EQ(-1, dm_.SetPacketAudioLength(0));
234 EXPECT_EQ(-1, dm_.SetPacketAudioLength(-1));
235
236 // Minimum delay higher than a maximum delay is not accepted.
237 EXPECT_TRUE(dm_.SetMaximumDelay(20));
238 EXPECT_FALSE(dm_.SetMinimumDelay(40));
239
240 // Maximum delay less than minimum delay is not accepted.
241 EXPECT_TRUE(dm_.SetMaximumDelay(100));
242 EXPECT_TRUE(dm_.SetMinimumDelay(80));
243 EXPECT_FALSE(dm_.SetMaximumDelay(60));
244 }
245
246 } // namespace webrtc
247