nack_requester_unittest.cc (9929B)
1 /* 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 11 #include "modules/video_coding/nack_requester.h" 12 13 #include <algorithm> 14 #include <cstdint> 15 #include <cstring> 16 #include <memory> 17 #include <vector> 18 19 #include "api/task_queue/task_queue_base.h" 20 #include "api/units/time_delta.h" 21 #include "modules/include/module_common_types.h" 22 #include "rtc_base/checks.h" 23 #include "rtc_base/thread.h" 24 #include "system_wrappers/include/clock.h" 25 #include "test/create_test_field_trials.h" 26 #include "test/gtest.h" 27 #include "test/run_loop.h" 28 29 namespace webrtc { 30 // TODO(bugs.webrtc.org/11594): Use the use the GlobalSimulatedTimeController 31 // instead of RunLoop. At the moment we mix use of the Clock and the underlying 32 // implementation of RunLoop, which is realtime. 33 class TestNackRequester : public ::testing::Test, 34 public NackSender, 35 public KeyFrameRequestSender { 36 protected: 37 TestNackRequester() 38 : clock_(new SimulatedClock(0)), keyframes_requested_(0) {} 39 40 void SetUp() override {} 41 42 void SendNack(const std::vector<uint16_t>& sequence_numbers, 43 bool /* buffering_allowed */) override { 44 sent_nacks_.insert(sent_nacks_.end(), sequence_numbers.begin(), 45 sequence_numbers.end()); 46 if (waiting_for_send_nack_) { 47 waiting_for_send_nack_ = false; 48 loop_.Quit(); 49 } 50 } 51 52 void RequestKeyFrame() override { ++keyframes_requested_; } 53 54 void Flush() { 55 // nack_module.Process(); 56 loop_.Flush(); 57 } 58 59 bool WaitForSendNack() { 60 if (timed_out_) { 61 RTC_DCHECK_NOTREACHED(); 62 return false; 63 } 64 65 RTC_DCHECK(!waiting_for_send_nack_); 66 67 waiting_for_send_nack_ = true; 68 loop_.task_queue()->PostDelayedTask( 69 [this]() { 70 timed_out_ = true; 71 loop_.Quit(); 72 }, 73 TimeDelta::Seconds(1)); 74 75 loop_.Run(); 76 77 if (timed_out_) 78 return false; 79 80 RTC_DCHECK(!waiting_for_send_nack_); 81 return true; 82 } 83 84 NackRequester& CreateNackModule( 85 TimeDelta interval = NackPeriodicProcessor::kUpdateInterval) { 86 RTC_DCHECK(!nack_module_.get()); 87 nack_periodic_processor_ = 88 std::make_unique<NackPeriodicProcessor>(interval); 89 nack_module_ = std::make_unique<NackRequester>( 90 TaskQueueBase::Current(), nack_periodic_processor_.get(), clock_.get(), 91 this, this, CreateTestFieldTrials()); 92 nack_module_->UpdateRtt(kDefaultRttMs); 93 return *nack_module_; 94 } 95 96 static constexpr int64_t kDefaultRttMs = 20; 97 AutoThread main_thread_; 98 test::RunLoop loop_; 99 std::unique_ptr<SimulatedClock> clock_; 100 std::unique_ptr<NackPeriodicProcessor> nack_periodic_processor_; 101 std::unique_ptr<NackRequester> nack_module_; 102 std::vector<uint16_t> sent_nacks_; 103 int keyframes_requested_; 104 bool waiting_for_send_nack_ = false; 105 bool timed_out_ = false; 106 }; 107 108 TEST_F(TestNackRequester, NackOnePacket) { 109 NackRequester& nack_module = CreateNackModule(); 110 nack_module.OnReceivedPacket(1); 111 nack_module.OnReceivedPacket(3); 112 ASSERT_EQ(1u, sent_nacks_.size()); 113 EXPECT_EQ(2, sent_nacks_[0]); 114 } 115 116 TEST_F(TestNackRequester, WrappingSeqNum) { 117 NackRequester& nack_module = CreateNackModule(); 118 nack_module.OnReceivedPacket(0xfffe); 119 nack_module.OnReceivedPacket(1); 120 ASSERT_EQ(2u, sent_nacks_.size()); 121 EXPECT_EQ(0xffff, sent_nacks_[0]); 122 EXPECT_EQ(0, sent_nacks_[1]); 123 } 124 125 TEST_F(TestNackRequester, ResendNack) { 126 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1)); 127 nack_module.OnReceivedPacket(1); 128 nack_module.OnReceivedPacket(3); 129 size_t expected_nacks_sent = 1; 130 ASSERT_EQ(expected_nacks_sent, sent_nacks_.size()); 131 EXPECT_EQ(2, sent_nacks_[0]); 132 133 nack_module.UpdateRtt(1); 134 clock_->AdvanceTimeMilliseconds(1); 135 WaitForSendNack(); // Fast retransmit allowed. 136 EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size()); 137 138 // Each try has to wait rtt by default. 139 for (int i = 2; i < 10; ++i) { 140 // Change RTT, above the 40ms max for exponential backoff. 141 TimeDelta rtt = TimeDelta::Millis(160); // + (i * 10 - 40) 142 nack_module.UpdateRtt(rtt.ms()); 143 144 // RTT gets capped at 160ms in backoff calculations. 145 TimeDelta expected_backoff_delay = 146 (i - 1) * std::min(rtt, TimeDelta::Millis(160)); 147 148 // Move to one millisecond before next allowed NACK. 149 clock_->AdvanceTimeMilliseconds(expected_backoff_delay.ms() - 1); 150 Flush(); 151 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size()); 152 153 // Move to one millisecond after next allowed NACK. 154 // After rather than on to avoid rounding errors. 155 clock_->AdvanceTimeMilliseconds(2); 156 WaitForSendNack(); // Now allowed. 157 EXPECT_EQ(++expected_nacks_sent, sent_nacks_.size()); 158 } 159 160 // Giving up after 10 tries. 161 clock_->AdvanceTimeMilliseconds(3000); 162 Flush(); 163 EXPECT_EQ(expected_nacks_sent, sent_nacks_.size()); 164 } 165 166 TEST_F(TestNackRequester, ResendPacketMaxRetries) { 167 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1)); 168 nack_module.OnReceivedPacket(1); 169 nack_module.OnReceivedPacket(3); 170 ASSERT_EQ(1u, sent_nacks_.size()); 171 EXPECT_EQ(2, sent_nacks_[0]); 172 173 int backoff_factor = 1; 174 for (size_t retries = 1; retries < 10; ++retries) { 175 // Exponential backoff, so that we don't reject NACK because of time. 176 clock_->AdvanceTimeMilliseconds(backoff_factor * kDefaultRttMs); 177 backoff_factor *= 2; 178 WaitForSendNack(); 179 EXPECT_EQ(retries + 1, sent_nacks_.size()); 180 } 181 182 clock_->AdvanceTimeMilliseconds(backoff_factor * kDefaultRttMs); 183 Flush(); 184 EXPECT_EQ(10u, sent_nacks_.size()); 185 } 186 187 TEST_F(TestNackRequester, TooLargeNackList) { 188 NackRequester& nack_module = CreateNackModule(); 189 nack_module.OnReceivedPacket(0); 190 nack_module.OnReceivedPacket(1001); 191 EXPECT_EQ(1000u, sent_nacks_.size()); 192 EXPECT_EQ(0, keyframes_requested_); 193 nack_module.OnReceivedPacket(1003); 194 EXPECT_EQ(1000u, sent_nacks_.size()); 195 EXPECT_EQ(1, keyframes_requested_); 196 nack_module.OnReceivedPacket(1004); 197 EXPECT_EQ(1000u, sent_nacks_.size()); 198 EXPECT_EQ(1, keyframes_requested_); 199 } 200 201 TEST_F(TestNackRequester, ClearUpTo) { 202 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1)); 203 nack_module.OnReceivedPacket(0); 204 nack_module.OnReceivedPacket(100); 205 EXPECT_EQ(99u, sent_nacks_.size()); 206 207 sent_nacks_.clear(); 208 clock_->AdvanceTimeMilliseconds(100); 209 nack_module.ClearUpTo(50); 210 WaitForSendNack(); 211 ASSERT_EQ(50u, sent_nacks_.size()); 212 EXPECT_EQ(50, sent_nacks_[0]); 213 } 214 215 TEST_F(TestNackRequester, ClearUpToWrap) { 216 NackRequester& nack_module = CreateNackModule(); 217 nack_module.OnReceivedPacket(0xfff0); 218 nack_module.OnReceivedPacket(0xf); 219 EXPECT_EQ(30u, sent_nacks_.size()); 220 221 sent_nacks_.clear(); 222 clock_->AdvanceTimeMilliseconds(100); 223 nack_module.ClearUpTo(0); 224 WaitForSendNack(); 225 ASSERT_EQ(15u, sent_nacks_.size()); 226 EXPECT_EQ(0, sent_nacks_[0]); 227 } 228 229 TEST_F(TestNackRequester, PacketNackCount) { 230 NackRequester& nack_module = CreateNackModule(TimeDelta::Millis(1)); 231 EXPECT_EQ(0, nack_module.OnReceivedPacket(0)); 232 EXPECT_EQ(0, nack_module.OnReceivedPacket(2)); 233 EXPECT_EQ(1, nack_module.OnReceivedPacket(1)); 234 235 sent_nacks_.clear(); 236 nack_module.UpdateRtt(100); 237 EXPECT_EQ(0, nack_module.OnReceivedPacket(5)); 238 clock_->AdvanceTimeMilliseconds(100); 239 WaitForSendNack(); 240 EXPECT_EQ(4u, sent_nacks_.size()); 241 242 clock_->AdvanceTimeMilliseconds(125); 243 WaitForSendNack(); 244 245 EXPECT_EQ(6u, sent_nacks_.size()); 246 247 EXPECT_EQ(3, nack_module.OnReceivedPacket(3)); 248 EXPECT_EQ(3, nack_module.OnReceivedPacket(4)); 249 EXPECT_EQ(0, nack_module.OnReceivedPacket(4)); 250 } 251 252 TEST_F(TestNackRequester, HandleFecRecoveredPacket) { 253 NackRequester& nack_module = CreateNackModule(); 254 nack_module.OnReceivedPacket(1); 255 nack_module.OnReceivedPacket(4, /*is_recovered=*/true); 256 EXPECT_EQ(0u, sent_nacks_.size()); 257 nack_module.OnReceivedPacket(5); 258 EXPECT_EQ(2u, sent_nacks_.size()); 259 } 260 261 TEST_F(TestNackRequester, SendNackWithoutDelay) { 262 NackRequester& nack_module = CreateNackModule(); 263 nack_module.OnReceivedPacket(0); 264 nack_module.OnReceivedPacket(100); 265 EXPECT_EQ(99u, sent_nacks_.size()); 266 } 267 268 class TestNackRequesterWithFieldTrial : public ::testing::Test, 269 public NackSender, 270 public KeyFrameRequestSender { 271 protected: 272 TestNackRequesterWithFieldTrial() 273 : clock_(new SimulatedClock(0)), 274 nack_module_(TaskQueueBase::Current(), 275 &nack_periodic_processor_, 276 clock_.get(), 277 this, 278 this, 279 CreateTestFieldTrials("WebRTC-SendNackDelayMs/10/")), 280 keyframes_requested_(0) {} 281 282 void SendNack(const std::vector<uint16_t>& sequence_numbers, 283 bool /* buffering_allowed */) override { 284 sent_nacks_.insert(sent_nacks_.end(), sequence_numbers.begin(), 285 sequence_numbers.end()); 286 } 287 288 void RequestKeyFrame() override { ++keyframes_requested_; } 289 290 AutoThread main_thread_; 291 std::unique_ptr<SimulatedClock> clock_; 292 NackPeriodicProcessor nack_periodic_processor_; 293 NackRequester nack_module_; 294 std::vector<uint16_t> sent_nacks_; 295 int keyframes_requested_; 296 }; 297 298 TEST_F(TestNackRequesterWithFieldTrial, SendNackWithDelay) { 299 nack_module_.OnReceivedPacket(0); 300 nack_module_.OnReceivedPacket(100); 301 EXPECT_EQ(0u, sent_nacks_.size()); 302 clock_->AdvanceTimeMilliseconds(10); 303 nack_module_.OnReceivedPacket(106); 304 EXPECT_EQ(99u, sent_nacks_.size()); 305 clock_->AdvanceTimeMilliseconds(10); 306 nack_module_.OnReceivedPacket(109); 307 EXPECT_EQ(104u, sent_nacks_.size()); 308 } 309 } // namespace webrtc