blob: c9a2023104b16033ef4404fcd8892785fa9de4f0 [file] [log] [blame]
philipel5ab4c6d2016-03-08 03:36:15 -08001/*
2 * Copyright (c) 2016 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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "modules/video_coding/nack_module.h"
12
Erik Språng3eae7e42019-10-25 09:24:45 +020013#include <algorithm>
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <cstdint>
philipel5ab4c6d2016-03-08 03:36:15 -080015#include <cstring>
kwiberg22feaa32016-03-17 09:17:43 -070016#include <memory>
17
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020018#include "system_wrappers/include/clock.h"
Ying Wang0367d1a2018-11-02 14:51:15 +010019#include "test/field_trial.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "test/gtest.h"
philipel5ab4c6d2016-03-08 03:36:15 -080021
22namespace webrtc {
Erik Språng3eae7e42019-10-25 09:24:45 +020023class TestNackModule : public ::testing::TestWithParam<bool>,
philipel5ab4c6d2016-03-08 03:36:15 -080024 public NackSender,
25 public KeyFrameRequestSender {
26 protected:
27 TestNackModule()
28 : clock_(new SimulatedClock(0)),
Erik Språng3eae7e42019-10-25 09:24:45 +020029 field_trial_(GetParam()
30 ? "WebRTC-ExponentialNackBackoff/enabled:true/"
31 : "WebRTC-ExponentialNackBackoff/enabled:false/"),
philipel5ab4c6d2016-03-08 03:36:15 -080032 nack_module_(clock_.get(), this, this),
33 keyframes_requested_(0) {}
34
Erik Språng3eae7e42019-10-25 09:24:45 +020035 void SetUp() override { nack_module_.UpdateRtt(kDefaultRttMs); }
36
Elad Alonef09c5b2019-05-31 13:25:50 +020037 void SendNack(const std::vector<uint16_t>& sequence_numbers,
38 bool buffering_allowed) override {
philipel5ab4c6d2016-03-08 03:36:15 -080039 sent_nacks_.insert(sent_nacks_.end(), sequence_numbers.begin(),
40 sequence_numbers.end());
41 }
42
43 void RequestKeyFrame() override { ++keyframes_requested_; }
44
Erik Språng3eae7e42019-10-25 09:24:45 +020045 static constexpr int64_t kDefaultRttMs = 20;
philipel5ab4c6d2016-03-08 03:36:15 -080046 std::unique_ptr<SimulatedClock> clock_;
Erik Språng3eae7e42019-10-25 09:24:45 +020047 test::ScopedFieldTrials field_trial_;
philipel5ab4c6d2016-03-08 03:36:15 -080048 NackModule nack_module_;
49 std::vector<uint16_t> sent_nacks_;
50 int keyframes_requested_;
51};
52
Erik Språng3eae7e42019-10-25 09:24:45 +020053TEST_P(TestNackModule, NackOnePacket) {
Ying Wangb32bb952018-10-31 10:12:27 +010054 nack_module_.OnReceivedPacket(1, false, false);
55 nack_module_.OnReceivedPacket(3, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -080056 EXPECT_EQ(1u, sent_nacks_.size());
57 EXPECT_EQ(2, sent_nacks_[0]);
58}
59
Erik Språng3eae7e42019-10-25 09:24:45 +020060TEST_P(TestNackModule, WrappingSeqNum) {
Ying Wangb32bb952018-10-31 10:12:27 +010061 nack_module_.OnReceivedPacket(0xfffe, false, false);
62 nack_module_.OnReceivedPacket(1, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -080063 EXPECT_EQ(2u, sent_nacks_.size());
64 EXPECT_EQ(0xffff, sent_nacks_[0]);
65 EXPECT_EQ(0, sent_nacks_[1]);
66}
67
Erik Språng3eae7e42019-10-25 09:24:45 +020068TEST_P(TestNackModule, WrappingSeqNumClearToKeyframe) {
Ying Wangb32bb952018-10-31 10:12:27 +010069 nack_module_.OnReceivedPacket(0xfffe, false, false);
70 nack_module_.OnReceivedPacket(1, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -080071 EXPECT_EQ(2u, sent_nacks_.size());
72 EXPECT_EQ(0xffff, sent_nacks_[0]);
73 EXPECT_EQ(0, sent_nacks_[1]);
74
75 sent_nacks_.clear();
Ying Wangb32bb952018-10-31 10:12:27 +010076 nack_module_.OnReceivedPacket(2, true, false);
philipel5ab4c6d2016-03-08 03:36:15 -080077 EXPECT_EQ(0u, sent_nacks_.size());
78
Ying Wangb32bb952018-10-31 10:12:27 +010079 nack_module_.OnReceivedPacket(501, true, false);
philipel5ab4c6d2016-03-08 03:36:15 -080080 EXPECT_EQ(498u, sent_nacks_.size());
81 for (int seq_num = 3; seq_num < 501; ++seq_num)
82 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 3]);
83
84 sent_nacks_.clear();
Ying Wangb32bb952018-10-31 10:12:27 +010085 nack_module_.OnReceivedPacket(1001, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -080086 EXPECT_EQ(499u, sent_nacks_.size());
87 for (int seq_num = 502; seq_num < 1001; ++seq_num)
88 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 502]);
89
90 sent_nacks_.clear();
91 clock_->AdvanceTimeMilliseconds(100);
92 nack_module_.Process();
93 EXPECT_EQ(999u, sent_nacks_.size());
94 EXPECT_EQ(0xffff, sent_nacks_[0]);
95 EXPECT_EQ(0, sent_nacks_[1]);
96 for (int seq_num = 3; seq_num < 501; ++seq_num)
97 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 1]);
98 for (int seq_num = 502; seq_num < 1001; ++seq_num)
99 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 2]);
100
101 // Adding packet 1004 will cause the nack list to reach it's max limit.
102 // It will then clear all nacks up to the next keyframe (seq num 2),
103 // thus removing 0xffff and 0 from the nack list.
104 sent_nacks_.clear();
Ying Wangb32bb952018-10-31 10:12:27 +0100105 nack_module_.OnReceivedPacket(1004, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800106 EXPECT_EQ(2u, sent_nacks_.size());
107 EXPECT_EQ(1002, sent_nacks_[0]);
108 EXPECT_EQ(1003, sent_nacks_[1]);
109
110 sent_nacks_.clear();
111 clock_->AdvanceTimeMilliseconds(100);
112 nack_module_.Process();
113 EXPECT_EQ(999u, sent_nacks_.size());
114 for (int seq_num = 3; seq_num < 501; ++seq_num)
115 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 3]);
116 for (int seq_num = 502; seq_num < 1001; ++seq_num)
117 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 4]);
118
119 // Adding packet 1007 will cause the nack module to overflow again, thus
120 // clearing everything up to 501 which is the next keyframe.
Ying Wangb32bb952018-10-31 10:12:27 +0100121 nack_module_.OnReceivedPacket(1007, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800122 sent_nacks_.clear();
123 clock_->AdvanceTimeMilliseconds(100);
124 nack_module_.Process();
125 EXPECT_EQ(503u, sent_nacks_.size());
126 for (int seq_num = 502; seq_num < 1001; ++seq_num)
127 EXPECT_EQ(seq_num, sent_nacks_[seq_num - 502]);
128 EXPECT_EQ(1005, sent_nacks_[501]);
129 EXPECT_EQ(1006, sent_nacks_[502]);
130}
131
Erik Språng3eae7e42019-10-25 09:24:45 +0200132TEST_P(TestNackModule, DontBurstOnTimeSkip) {
philipel5ab4c6d2016-03-08 03:36:15 -0800133 nack_module_.Process();
134 clock_->AdvanceTimeMilliseconds(20);
135 EXPECT_EQ(0, nack_module_.TimeUntilNextProcess());
136 nack_module_.Process();
137
138 clock_->AdvanceTimeMilliseconds(100);
139 EXPECT_EQ(0, nack_module_.TimeUntilNextProcess());
140 nack_module_.Process();
141 EXPECT_EQ(20, nack_module_.TimeUntilNextProcess());
142
143 clock_->AdvanceTimeMilliseconds(19);
144 EXPECT_EQ(1, nack_module_.TimeUntilNextProcess());
145 clock_->AdvanceTimeMilliseconds(2);
146 nack_module_.Process();
147 EXPECT_EQ(19, nack_module_.TimeUntilNextProcess());
148
149 clock_->AdvanceTimeMilliseconds(19);
150 EXPECT_EQ(0, nack_module_.TimeUntilNextProcess());
151 nack_module_.Process();
152
153 clock_->AdvanceTimeMilliseconds(21);
154 EXPECT_EQ(0, nack_module_.TimeUntilNextProcess());
155 nack_module_.Process();
156 EXPECT_EQ(19, nack_module_.TimeUntilNextProcess());
157}
158
Erik Språng3eae7e42019-10-25 09:24:45 +0200159TEST_P(TestNackModule, ResendNack) {
Ying Wangb32bb952018-10-31 10:12:27 +0100160 nack_module_.OnReceivedPacket(1, false, false);
161 nack_module_.OnReceivedPacket(3, false, false);
Erik Språng3eae7e42019-10-25 09:24:45 +0200162 size_t expected_nacks_sent = 1;
163 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
philipel5ab4c6d2016-03-08 03:36:15 -0800164 EXPECT_EQ(2, sent_nacks_[0]);
165
Erik Språng3eae7e42019-10-25 09:24:45 +0200166 if (GetParam()) {
167 // Retry has to wait at least 5ms by default.
168 nack_module_.UpdateRtt(1);
169 clock_->AdvanceTimeMilliseconds(4);
170 nack_module_.Process(); // Too early.
171 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
philipel5ab4c6d2016-03-08 03:36:15 -0800172
Erik Språng3eae7e42019-10-25 09:24:45 +0200173 clock_->AdvanceTimeMilliseconds(1);
174 nack_module_.Process(); // Now allowed.
175 EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size());
176 } else {
177 nack_module_.UpdateRtt(1);
178 clock_->AdvanceTimeMilliseconds(1);
179 nack_module_.Process(); // Fast retransmit allowed.
180 EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size());
181 }
philipel5ab4c6d2016-03-08 03:36:15 -0800182
Erik Språng3eae7e42019-10-25 09:24:45 +0200183 // N:th try has to wait b^(N-1) * rtt by default.
184 const double b = GetParam() ? 1.25 : 1.0;
185 for (int i = 2; i < 10; ++i) {
186 // Change RTT, above the 40ms max for exponential backoff.
187 TimeDelta rtt = TimeDelta::ms(160); // + (i * 10 - 40)
188 nack_module_.UpdateRtt(rtt.ms());
philipel5ab4c6d2016-03-08 03:36:15 -0800189
Erik Språng3eae7e42019-10-25 09:24:45 +0200190 // RTT gets capped at 160ms in backoff calculations.
191 TimeDelta expected_backoff_delay =
192 std::pow(b, i - 1) * std::min(rtt, TimeDelta::ms(160));
philipel5ab4c6d2016-03-08 03:36:15 -0800193
Erik Språng3eae7e42019-10-25 09:24:45 +0200194 // Move to one millisecond before next allowed NACK.
195 clock_->AdvanceTimeMilliseconds(expected_backoff_delay.ms() - 1);
196 nack_module_.Process();
197 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
198
199 // Move to one millisecond after next allowed NACK.
200 // After rather than on to avoid rounding errors.
201 clock_->AdvanceTimeMilliseconds(2);
202 nack_module_.Process(); // Now allowed.
203 EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size());
204 }
205
206 // Giving up after 10 tries.
207 clock_->AdvanceTimeMilliseconds(3000);
philipel5ab4c6d2016-03-08 03:36:15 -0800208 nack_module_.Process();
Erik Språng3eae7e42019-10-25 09:24:45 +0200209 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size());
philipel5ab4c6d2016-03-08 03:36:15 -0800210}
211
Erik Språng3eae7e42019-10-25 09:24:45 +0200212TEST_P(TestNackModule, ResendPacketMaxRetries) {
Ying Wangb32bb952018-10-31 10:12:27 +0100213 nack_module_.OnReceivedPacket(1, false, false);
214 nack_module_.OnReceivedPacket(3, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800215 EXPECT_EQ(1u, sent_nacks_.size());
216 EXPECT_EQ(2, sent_nacks_[0]);
217
Erik Språng3eae7e42019-10-25 09:24:45 +0200218 int backoff_factor = 1;
philipel5ab4c6d2016-03-08 03:36:15 -0800219 for (size_t retries = 1; retries < 10; ++retries) {
Erik Språng3eae7e42019-10-25 09:24:45 +0200220 // Exponential backoff, so that we don't reject NACK because of time.
221 clock_->AdvanceTimeMilliseconds(backoff_factor * kDefaultRttMs);
222 backoff_factor *= 2;
philipel5ab4c6d2016-03-08 03:36:15 -0800223 nack_module_.Process();
224 EXPECT_EQ(retries + 1, sent_nacks_.size());
225 }
226
Erik Språng3eae7e42019-10-25 09:24:45 +0200227 clock_->AdvanceTimeMilliseconds(backoff_factor * kDefaultRttMs);
philipel5ab4c6d2016-03-08 03:36:15 -0800228 nack_module_.Process();
229 EXPECT_EQ(10u, sent_nacks_.size());
230}
231
Erik Språng3eae7e42019-10-25 09:24:45 +0200232TEST_P(TestNackModule, TooLargeNackList) {
Ying Wangb32bb952018-10-31 10:12:27 +0100233 nack_module_.OnReceivedPacket(0, false, false);
234 nack_module_.OnReceivedPacket(1001, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800235 EXPECT_EQ(1000u, sent_nacks_.size());
236 EXPECT_EQ(0, keyframes_requested_);
Ying Wangb32bb952018-10-31 10:12:27 +0100237 nack_module_.OnReceivedPacket(1003, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800238 EXPECT_EQ(1000u, sent_nacks_.size());
239 EXPECT_EQ(1, keyframes_requested_);
Ying Wangb32bb952018-10-31 10:12:27 +0100240 nack_module_.OnReceivedPacket(1004, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800241 EXPECT_EQ(1000u, sent_nacks_.size());
242 EXPECT_EQ(1, keyframes_requested_);
243}
244
Erik Språng3eae7e42019-10-25 09:24:45 +0200245TEST_P(TestNackModule, TooLargeNackListWithKeyFrame) {
Ying Wangb32bb952018-10-31 10:12:27 +0100246 nack_module_.OnReceivedPacket(0, false, false);
247 nack_module_.OnReceivedPacket(1, true, false);
248 nack_module_.OnReceivedPacket(1001, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800249 EXPECT_EQ(999u, sent_nacks_.size());
250 EXPECT_EQ(0, keyframes_requested_);
Ying Wangb32bb952018-10-31 10:12:27 +0100251 nack_module_.OnReceivedPacket(1003, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800252 EXPECT_EQ(1000u, sent_nacks_.size());
253 EXPECT_EQ(0, keyframes_requested_);
Ying Wangb32bb952018-10-31 10:12:27 +0100254 nack_module_.OnReceivedPacket(1005, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800255 EXPECT_EQ(1000u, sent_nacks_.size());
256 EXPECT_EQ(1, keyframes_requested_);
257}
258
Erik Språng3eae7e42019-10-25 09:24:45 +0200259TEST_P(TestNackModule, ClearUpTo) {
Ying Wangb32bb952018-10-31 10:12:27 +0100260 nack_module_.OnReceivedPacket(0, false, false);
261 nack_module_.OnReceivedPacket(100, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800262 EXPECT_EQ(99u, sent_nacks_.size());
263
264 sent_nacks_.clear();
265 clock_->AdvanceTimeMilliseconds(100);
266 nack_module_.ClearUpTo(50);
267 nack_module_.Process();
268 EXPECT_EQ(50u, sent_nacks_.size());
269 EXPECT_EQ(50, sent_nacks_[0]);
270}
271
Erik Språng3eae7e42019-10-25 09:24:45 +0200272TEST_P(TestNackModule, ClearUpToWrap) {
Ying Wangb32bb952018-10-31 10:12:27 +0100273 nack_module_.OnReceivedPacket(0xfff0, false, false);
274 nack_module_.OnReceivedPacket(0xf, false, false);
philipel5ab4c6d2016-03-08 03:36:15 -0800275 EXPECT_EQ(30u, sent_nacks_.size());
276
277 sent_nacks_.clear();
278 clock_->AdvanceTimeMilliseconds(100);
279 nack_module_.ClearUpTo(0);
280 nack_module_.Process();
281 EXPECT_EQ(15u, sent_nacks_.size());
282 EXPECT_EQ(0, sent_nacks_[0]);
283}
284
Erik Språng3eae7e42019-10-25 09:24:45 +0200285TEST_P(TestNackModule, PacketNackCount) {
Ying Wangb32bb952018-10-31 10:12:27 +0100286 EXPECT_EQ(0, nack_module_.OnReceivedPacket(0, false, false));
287 EXPECT_EQ(0, nack_module_.OnReceivedPacket(2, false, false));
288 EXPECT_EQ(1, nack_module_.OnReceivedPacket(1, false, false));
philipel1a830c22016-05-13 11:12:00 +0200289
290 sent_nacks_.clear();
291 nack_module_.UpdateRtt(100);
Ying Wangb32bb952018-10-31 10:12:27 +0100292 EXPECT_EQ(0, nack_module_.OnReceivedPacket(5, false, false));
philipel1a830c22016-05-13 11:12:00 +0200293 clock_->AdvanceTimeMilliseconds(100);
294 nack_module_.Process();
Erik Språng3eae7e42019-10-25 09:24:45 +0200295 clock_->AdvanceTimeMilliseconds(125);
philipel1a830c22016-05-13 11:12:00 +0200296 nack_module_.Process();
Ying Wangb32bb952018-10-31 10:12:27 +0100297 EXPECT_EQ(3, nack_module_.OnReceivedPacket(3, false, false));
298 EXPECT_EQ(3, nack_module_.OnReceivedPacket(4, false, false));
299 EXPECT_EQ(0, nack_module_.OnReceivedPacket(4, false, false));
philipel1a830c22016-05-13 11:12:00 +0200300}
301
Erik Språng3eae7e42019-10-25 09:24:45 +0200302TEST_P(TestNackModule, NackListFullAndNoOverlapWithKeyframes) {
Johannes Kron6fbeeeb2018-09-27 11:49:22 +0200303 const int kMaxNackPackets = 1000;
304 const unsigned int kFirstGap = kMaxNackPackets - 20;
305 const unsigned int kSecondGap = 200;
306 uint16_t seq_num = 0;
Ying Wangb32bb952018-10-31 10:12:27 +0100307 nack_module_.OnReceivedPacket(seq_num++, true, false);
Johannes Kron6fbeeeb2018-09-27 11:49:22 +0200308 seq_num += kFirstGap;
Ying Wangb32bb952018-10-31 10:12:27 +0100309 nack_module_.OnReceivedPacket(seq_num++, true, false);
Johannes Kron6fbeeeb2018-09-27 11:49:22 +0200310 EXPECT_EQ(kFirstGap, sent_nacks_.size());
311 sent_nacks_.clear();
312 seq_num += kSecondGap;
Ying Wangb32bb952018-10-31 10:12:27 +0100313 nack_module_.OnReceivedPacket(seq_num, true, false);
Johannes Kron6fbeeeb2018-09-27 11:49:22 +0200314 EXPECT_EQ(kSecondGap, sent_nacks_.size());
315}
316
Erik Språng3eae7e42019-10-25 09:24:45 +0200317TEST_P(TestNackModule, HandleFecRecoveredPacket) {
Ying Wangb32bb952018-10-31 10:12:27 +0100318 nack_module_.OnReceivedPacket(1, false, false);
319 nack_module_.OnReceivedPacket(4, false, true);
320 EXPECT_EQ(0u, sent_nacks_.size());
321 nack_module_.OnReceivedPacket(5, false, false);
322 EXPECT_EQ(2u, sent_nacks_.size());
323}
324
Erik Språng3eae7e42019-10-25 09:24:45 +0200325TEST_P(TestNackModule, SendNackWithoutDelay) {
Ying Wang0367d1a2018-11-02 14:51:15 +0100326 nack_module_.OnReceivedPacket(0, false, false);
327 nack_module_.OnReceivedPacket(100, false, false);
328 EXPECT_EQ(99u, sent_nacks_.size());
329}
330
Erik Språng3eae7e42019-10-25 09:24:45 +0200331INSTANTIATE_TEST_SUITE_P(WithAndWithoutBackoff,
332 TestNackModule,
333 ::testing::Values(true, false));
334
Ying Wang0367d1a2018-11-02 14:51:15 +0100335class TestNackModuleWithFieldTrial : public ::testing::Test,
336 public NackSender,
337 public KeyFrameRequestSender {
338 protected:
339 TestNackModuleWithFieldTrial()
340 : nack_delay_field_trial_("WebRTC-SendNackDelayMs/10/"),
341 clock_(new SimulatedClock(0)),
342 nack_module_(clock_.get(), this, this),
343 keyframes_requested_(0) {}
344
Elad Alonef09c5b2019-05-31 13:25:50 +0200345 void SendNack(const std::vector<uint16_t>& sequence_numbers,
346 bool buffering_allowed) override {
Ying Wang0367d1a2018-11-02 14:51:15 +0100347 sent_nacks_.insert(sent_nacks_.end(), sequence_numbers.begin(),
348 sequence_numbers.end());
349 }
350
351 void RequestKeyFrame() override { ++keyframes_requested_; }
352
353 test::ScopedFieldTrials nack_delay_field_trial_;
354 std::unique_ptr<SimulatedClock> clock_;
355 NackModule nack_module_;
356 std::vector<uint16_t> sent_nacks_;
357 int keyframes_requested_;
358};
359
360TEST_F(TestNackModuleWithFieldTrial, SendNackWithDelay) {
361 nack_module_.OnReceivedPacket(0, false, false);
362 nack_module_.OnReceivedPacket(100, false, false);
363 EXPECT_EQ(0u, sent_nacks_.size());
364 clock_->AdvanceTimeMilliseconds(10);
365 nack_module_.OnReceivedPacket(106, false, false);
366 EXPECT_EQ(99u, sent_nacks_.size());
367 clock_->AdvanceTimeMilliseconds(10);
368 nack_module_.OnReceivedPacket(109, false, false);
369 EXPECT_EQ(104u, sent_nacks_.size());
370}
philipel5ab4c6d2016-03-08 03:36:15 -0800371} // namespace webrtc