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 #include "modules/rtp_rtcp/source/rtp_packet_history.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
17 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
18 #include "system_wrappers/include/clock.h"
19 #include "test/gmock.h"
20 #include "test/gtest.h"
21
22 namespace webrtc {
23 namespace {
24 // Set a high sequence number so we'll suffer a wrap-around.
25 constexpr uint16_t kStartSeqNum = 65534u;
26
27 // Utility method for truncating sequence numbers to uint16.
To16u(size_t sequence_number)28 uint16_t To16u(size_t sequence_number) {
29 return static_cast<uint16_t>(sequence_number & 0xFFFF);
30 }
31 } // namespace
32
33 using StorageMode = RtpPacketHistory::StorageMode;
34
35 class RtpPacketHistoryTest : public ::testing::TestWithParam<bool> {
36 protected:
RtpPacketHistoryTest()37 RtpPacketHistoryTest()
38 : fake_clock_(123456),
39 hist_(&fake_clock_, /*enable_padding_prio=*/GetParam()) {}
40
41 SimulatedClock fake_clock_;
42 RtpPacketHistory hist_;
43
CreateRtpPacket(uint16_t seq_num)44 std::unique_ptr<RtpPacketToSend> CreateRtpPacket(uint16_t seq_num) {
45 // Payload, ssrc, timestamp and extensions are irrelevant for this tests.
46 std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(nullptr));
47 packet->SetSequenceNumber(seq_num);
48 packet->set_capture_time(fake_clock_.CurrentTime());
49 packet->set_allow_retransmission(true);
50 return packet;
51 }
52 };
53
TEST_P(RtpPacketHistoryTest,SetStoreStatus)54 TEST_P(RtpPacketHistoryTest, SetStoreStatus) {
55 EXPECT_EQ(StorageMode::kDisabled, hist_.GetStorageMode());
56 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
57 EXPECT_EQ(StorageMode::kStoreAndCull, hist_.GetStorageMode());
58 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
59 EXPECT_EQ(StorageMode::kStoreAndCull, hist_.GetStorageMode());
60 hist_.SetStorePacketsStatus(StorageMode::kDisabled, 0);
61 EXPECT_EQ(StorageMode::kDisabled, hist_.GetStorageMode());
62 }
63
TEST_P(RtpPacketHistoryTest,ClearsHistoryAfterSetStoreStatus)64 TEST_P(RtpPacketHistoryTest, ClearsHistoryAfterSetStoreStatus) {
65 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
66 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum),
67 /*send_time=*/fake_clock_.CurrentTime());
68 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
69
70 // Changing store status, even to the current one, will clear the history.
71 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
72 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
73 }
74
TEST_P(RtpPacketHistoryTest,StartSeqResetAfterReset)75 TEST_P(RtpPacketHistoryTest, StartSeqResetAfterReset) {
76 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
77 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum),
78 /*send_time=*/fake_clock_.CurrentTime());
79 // Mark packet as pending so it won't be removed.
80 EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
81
82 // Changing store status, to clear the history.
83 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
84 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
85
86 // Add a new packet.
87 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 1)),
88 /*send_time=*/fake_clock_.CurrentTime());
89 EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(To16u(kStartSeqNum + 1)));
90
91 // Advance time past where packet expires.
92 fake_clock_.AdvanceTime(RtpPacketHistory::kPacketCullingDelayFactor *
93 RtpPacketHistory::kMinPacketDuration);
94
95 // Add one more packet and verify no state left from packet before reset.
96 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 2)),
97 /*send_time=*/fake_clock_.CurrentTime());
98 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
99 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
100 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
101 }
102
TEST_P(RtpPacketHistoryTest,NoStoreStatus)103 TEST_P(RtpPacketHistoryTest, NoStoreStatus) {
104 EXPECT_EQ(StorageMode::kDisabled, hist_.GetStorageMode());
105 std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
106 hist_.PutRtpPacket(std::move(packet),
107 /*send_time=*/fake_clock_.CurrentTime());
108 // Packet should not be stored.
109 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
110 }
111
TEST_P(RtpPacketHistoryTest,GetRtpPacket_NotStored)112 TEST_P(RtpPacketHistoryTest, GetRtpPacket_NotStored) {
113 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
114 EXPECT_FALSE(hist_.GetPacketState(0));
115 }
116
TEST_P(RtpPacketHistoryTest,PutRtpPacket)117 TEST_P(RtpPacketHistoryTest, PutRtpPacket) {
118 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
119 std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
120
121 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
122 hist_.PutRtpPacket(std::move(packet),
123 /*send_time=*/fake_clock_.CurrentTime());
124 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
125 }
126
TEST_P(RtpPacketHistoryTest,GetRtpPacket)127 TEST_P(RtpPacketHistoryTest, GetRtpPacket) {
128 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
129 Timestamp capture_time = Timestamp::Millis(1);
130 std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
131 packet->set_capture_time(capture_time);
132 rtc::CopyOnWriteBuffer buffer = packet->Buffer();
133 hist_.PutRtpPacket(std::move(packet),
134 /*send_time=*/fake_clock_.CurrentTime());
135
136 std::unique_ptr<RtpPacketToSend> packet_out =
137 hist_.GetPacketAndMarkAsPending(kStartSeqNum);
138 ASSERT_TRUE(packet_out);
139 EXPECT_EQ(buffer, packet_out->Buffer());
140 EXPECT_EQ(capture_time, packet_out->capture_time());
141 }
142
TEST_P(RtpPacketHistoryTest,MinResendTime)143 TEST_P(RtpPacketHistoryTest, MinResendTime) {
144 static const TimeDelta kMinRetransmitInterval = TimeDelta::Millis(100);
145
146 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
147 hist_.SetRtt(kMinRetransmitInterval);
148 Timestamp capture_time = fake_clock_.CurrentTime();
149 std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
150 size_t len = packet->size();
151 hist_.PutRtpPacket(std::move(packet), fake_clock_.CurrentTime());
152
153 // First retransmission - allow early retransmission.
154 fake_clock_.AdvanceTimeMilliseconds(1);
155 packet = hist_.GetPacketAndMarkAsPending(kStartSeqNum);
156 ASSERT_TRUE(packet);
157 EXPECT_EQ(len, packet->size());
158 EXPECT_EQ(packet->capture_time(), capture_time);
159 hist_.MarkPacketAsSent(kStartSeqNum);
160
161 // Second retransmission - advance time to just before retransmission OK.
162 fake_clock_.AdvanceTime(kMinRetransmitInterval - TimeDelta::Millis(1));
163 EXPECT_FALSE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
164
165 // Advance time to just after retransmission OK.
166 fake_clock_.AdvanceTimeMilliseconds(1);
167 EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
168 }
169
TEST_P(RtpPacketHistoryTest,RemovesOldestSentPacketWhenAtMaxSize)170 TEST_P(RtpPacketHistoryTest, RemovesOldestSentPacketWhenAtMaxSize) {
171 const size_t kMaxNumPackets = 10;
172 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kMaxNumPackets);
173
174 // History does not allow removing packets within kMinPacketDuration,
175 // so in order to test capacity, make sure insertion spans this time.
176 const TimeDelta kPacketInterval =
177 RtpPacketHistory::kMinPacketDuration / kMaxNumPackets;
178
179 // Add packets until the buffer is full.
180 for (size_t i = 0; i < kMaxNumPackets; ++i) {
181 std::unique_ptr<RtpPacketToSend> packet =
182 CreateRtpPacket(To16u(kStartSeqNum + i));
183 // Immediate mark packet as sent.
184 hist_.PutRtpPacket(std::move(packet), fake_clock_.CurrentTime());
185 fake_clock_.AdvanceTime(kPacketInterval);
186 }
187
188 // First packet should still be there.
189 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
190
191 // History is full, oldest one should be overwritten.
192 std::unique_ptr<RtpPacketToSend> packet =
193 CreateRtpPacket(To16u(kStartSeqNum + kMaxNumPackets));
194 hist_.PutRtpPacket(std::move(packet), fake_clock_.CurrentTime());
195
196 // Oldest packet should be gone, but packet after than one still present.
197 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
198 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
199 }
200
TEST_P(RtpPacketHistoryTest,RemovesOldestPacketWhenAtMaxCapacity)201 TEST_P(RtpPacketHistoryTest, RemovesOldestPacketWhenAtMaxCapacity) {
202 // Tests the absolute upper bound on number of stored packets. Don't allow
203 // storing more than this, even if packets have not yet been sent.
204 const size_t kMaxNumPackets = RtpPacketHistory::kMaxCapacity;
205 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull,
206 RtpPacketHistory::kMaxCapacity);
207
208 // Add packets until the buffer is full.
209 for (size_t i = 0; i < kMaxNumPackets; ++i) {
210 std::unique_ptr<RtpPacketToSend> packet =
211 CreateRtpPacket(To16u(kStartSeqNum + i));
212 hist_.PutRtpPacket(std::move(packet),
213 /*send_time=*/fake_clock_.CurrentTime());
214 // Mark packets as pending, preventing it from being removed.
215 hist_.GetPacketAndMarkAsPending(To16u(kStartSeqNum + i));
216 }
217
218 // First packet should still be there.
219 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
220
221 // History is full, oldest one should be overwritten.
222 std::unique_ptr<RtpPacketToSend> packet =
223 CreateRtpPacket(To16u(kStartSeqNum + kMaxNumPackets));
224 hist_.PutRtpPacket(std::move(packet), fake_clock_.CurrentTime());
225
226 // Oldest packet should be gone, but packet after than one still present.
227 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
228 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
229 }
230
TEST_P(RtpPacketHistoryTest,RemovesLowestPrioPaddingWhenAtMaxCapacity)231 TEST_P(RtpPacketHistoryTest, RemovesLowestPrioPaddingWhenAtMaxCapacity) {
232 if (!GetParam()) {
233 // Padding prioritization is off, ignore this test.
234 return;
235 }
236
237 // Tests the absolute upper bound on number of packets in the prioritized
238 // set of potential padding packets.
239 const size_t kMaxNumPackets = RtpPacketHistory::kMaxPaddingHistory;
240 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kMaxNumPackets * 2);
241 hist_.SetRtt(TimeDelta::Millis(1));
242
243 // Add packets until the max is reached, and then yet another one.
244 for (size_t i = 0; i < kMaxNumPackets + 1; ++i) {
245 std::unique_ptr<RtpPacketToSend> packet =
246 CreateRtpPacket(To16u(kStartSeqNum + i));
247 // Don't mark packets as sent, preventing them from being removed.
248 hist_.PutRtpPacket(std::move(packet), fake_clock_.CurrentTime());
249 }
250
251 // Advance time to allow retransmission/padding.
252 fake_clock_.AdvanceTimeMilliseconds(1);
253
254 // The oldest packet will be least prioritized and has fallen out of the
255 // priority set.
256 for (size_t i = kMaxNumPackets - 1; i > 0; --i) {
257 auto packet = hist_.GetPayloadPaddingPacket();
258 ASSERT_TRUE(packet);
259 EXPECT_EQ(packet->SequenceNumber(), To16u(kStartSeqNum + i + 1));
260 }
261
262 // Wrap around to newest padding packet again.
263 auto packet = hist_.GetPayloadPaddingPacket();
264 ASSERT_TRUE(packet);
265 EXPECT_EQ(packet->SequenceNumber(), To16u(kStartSeqNum + kMaxNumPackets));
266 }
267
TEST_P(RtpPacketHistoryTest,DontRemoveTooRecentlyTransmittedPackets)268 TEST_P(RtpPacketHistoryTest, DontRemoveTooRecentlyTransmittedPackets) {
269 // Set size to remove old packets as soon as possible.
270 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
271
272 // Add a packet, marked as send, and advance time to just before removal time.
273 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
274 fake_clock_.AdvanceTime(RtpPacketHistory::kMinPacketDuration -
275 TimeDelta::Millis(1));
276
277 // Add a new packet to trigger culling.
278 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 1)),
279 fake_clock_.CurrentTime());
280 // First packet should still be there.
281 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
282
283 // Advance time to where packet will be eligible for removal and try again.
284 fake_clock_.AdvanceTimeMilliseconds(1);
285 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 2)),
286 fake_clock_.CurrentTime());
287 // First packet should no be gone, but next one still there.
288 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
289 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
290 }
291
TEST_P(RtpPacketHistoryTest,DontRemoveTooRecentlyTransmittedPacketsHighRtt)292 TEST_P(RtpPacketHistoryTest, DontRemoveTooRecentlyTransmittedPacketsHighRtt) {
293 const TimeDelta kRtt = RtpPacketHistory::kMinPacketDuration * 2;
294 const TimeDelta kPacketTimeout =
295 kRtt * RtpPacketHistory::kMinPacketDurationRtt;
296
297 // Set size to remove old packets as soon as possible.
298 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
299 hist_.SetRtt(kRtt);
300
301 // Add a packet, marked as send, and advance time to just before removal time.
302 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
303 fake_clock_.AdvanceTime(kPacketTimeout - TimeDelta::Millis(1));
304
305 // Add a new packet to trigger culling.
306 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 1)),
307 fake_clock_.CurrentTime());
308 // First packet should still be there.
309 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
310
311 // Advance time to where packet will be eligible for removal and try again.
312 fake_clock_.AdvanceTimeMilliseconds(1);
313 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 2)),
314 fake_clock_.CurrentTime());
315 // First packet should no be gone, but next one still there.
316 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
317 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
318 }
319
TEST_P(RtpPacketHistoryTest,RemovesOldWithCulling)320 TEST_P(RtpPacketHistoryTest, RemovesOldWithCulling) {
321 const size_t kMaxNumPackets = 10;
322 // Enable culling. Even without feedback, this can trigger early removal.
323 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kMaxNumPackets);
324
325 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
326
327 TimeDelta kMaxPacketDuration = RtpPacketHistory::kMinPacketDuration *
328 RtpPacketHistory::kPacketCullingDelayFactor;
329 fake_clock_.AdvanceTime(kMaxPacketDuration - TimeDelta::Millis(1));
330
331 // First packet should still be there.
332 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
333
334 // Advance to where packet can be culled, even if buffer is not full.
335 fake_clock_.AdvanceTimeMilliseconds(1);
336 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 1)),
337 fake_clock_.CurrentTime());
338
339 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
340 }
341
TEST_P(RtpPacketHistoryTest,RemovesOldWithCullingHighRtt)342 TEST_P(RtpPacketHistoryTest, RemovesOldWithCullingHighRtt) {
343 const size_t kMaxNumPackets = 10;
344 const TimeDelta kRtt = RtpPacketHistory::kMinPacketDuration * 2;
345 // Enable culling. Even without feedback, this can trigger early removal.
346 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kMaxNumPackets);
347 hist_.SetRtt(kRtt);
348
349 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
350
351 TimeDelta kMaxPacketDuration = kRtt *
352 RtpPacketHistory::kMinPacketDurationRtt *
353 RtpPacketHistory::kPacketCullingDelayFactor;
354 fake_clock_.AdvanceTime(kMaxPacketDuration - TimeDelta::Millis(1));
355
356 // First packet should still be there.
357 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
358
359 // Advance to where packet can be culled, even if buffer is not full.
360 fake_clock_.AdvanceTimeMilliseconds(1);
361 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + 1)),
362 fake_clock_.CurrentTime());
363
364 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
365 }
366
TEST_P(RtpPacketHistoryTest,CullWithAcks)367 TEST_P(RtpPacketHistoryTest, CullWithAcks) {
368 const TimeDelta kPacketLifetime = RtpPacketHistory::kMinPacketDuration *
369 RtpPacketHistory::kPacketCullingDelayFactor;
370
371 const Timestamp start_time = fake_clock_.CurrentTime();
372 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
373
374 // Insert three packets 33ms apart, immediately mark them as sent.
375 std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
376 packet->SetPayloadSize(50);
377 hist_.PutRtpPacket(std::move(packet),
378 /*send_time=*/fake_clock_.CurrentTime());
379 fake_clock_.AdvanceTimeMilliseconds(33);
380 packet = CreateRtpPacket(To16u(kStartSeqNum + 1));
381 packet->SetPayloadSize(50);
382 hist_.PutRtpPacket(std::move(packet),
383 /*send_time=*/fake_clock_.CurrentTime());
384 fake_clock_.AdvanceTimeMilliseconds(33);
385 packet = CreateRtpPacket(To16u(kStartSeqNum + 2));
386 packet->SetPayloadSize(50);
387 hist_.PutRtpPacket(std::move(packet),
388 /*send_time=*/fake_clock_.CurrentTime());
389
390 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
391 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
392 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
393
394 // Remove middle one using ack, check that only that one is gone.
395 std::vector<uint16_t> acked_sequence_numbers = {To16u(kStartSeqNum + 1)};
396 hist_.CullAcknowledgedPackets(acked_sequence_numbers);
397
398 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
399 EXPECT_FALSE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
400 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
401
402 // Advance time to where second packet would have expired, verify first packet
403 // is removed.
404 Timestamp second_packet_expiry_time =
405 start_time + kPacketLifetime + TimeDelta::Millis(33 + 1);
406 fake_clock_.AdvanceTime(second_packet_expiry_time -
407 fake_clock_.CurrentTime());
408 hist_.SetRtt(TimeDelta::Millis(1)); // Trigger culling of old packets.
409 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
410 EXPECT_FALSE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
411 EXPECT_TRUE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
412
413 // Advance to where last packet expires, verify all gone.
414 fake_clock_.AdvanceTimeMilliseconds(33);
415 hist_.SetRtt(TimeDelta::Millis(1)); // Trigger culling of old packets.
416 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
417 EXPECT_FALSE(hist_.GetPacketState(To16u(kStartSeqNum + 1)));
418 EXPECT_FALSE(hist_.GetPacketState(To16u(kStartSeqNum + 2)));
419 }
420
TEST_P(RtpPacketHistoryTest,GetPacketAndSetSent)421 TEST_P(RtpPacketHistoryTest, GetPacketAndSetSent) {
422 const TimeDelta kRtt = RtpPacketHistory::kMinPacketDuration * 2;
423 hist_.SetRtt(kRtt);
424
425 // Set size to remove old packets as soon as possible.
426 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
427
428 // Add a sent packet to the history.
429 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
430
431 // Retransmission request, first retransmission is allowed immediately.
432 EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
433
434 // Packet not yet sent, new retransmission not allowed.
435 fake_clock_.AdvanceTime(kRtt);
436 EXPECT_FALSE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
437
438 // Mark as sent, but too early for retransmission.
439 hist_.MarkPacketAsSent(kStartSeqNum);
440 EXPECT_FALSE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
441
442 // Enough time has passed, retransmission is allowed again.
443 fake_clock_.AdvanceTime(kRtt);
444 EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
445 }
446
TEST_P(RtpPacketHistoryTest,GetPacketWithEncapsulation)447 TEST_P(RtpPacketHistoryTest, GetPacketWithEncapsulation) {
448 const uint32_t kSsrc = 92384762;
449 const TimeDelta kRtt = RtpPacketHistory::kMinPacketDuration * 2;
450 hist_.SetRtt(kRtt);
451
452 // Set size to remove old packets as soon as possible.
453 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
454
455 // Add a sent packet to the history, with a set SSRC.
456 std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kStartSeqNum);
457 packet->SetSsrc(kSsrc);
458 hist_.PutRtpPacket(std::move(packet), fake_clock_.CurrentTime());
459
460 // Retransmission request, simulate an RTX-like encapsulation, were the packet
461 // is sent on a different SSRC.
462 std::unique_ptr<RtpPacketToSend> retransmit_packet =
463 hist_.GetPacketAndMarkAsPending(
464 kStartSeqNum, [](const RtpPacketToSend& packet) {
465 auto encapsulated_packet =
466 std::make_unique<RtpPacketToSend>(packet);
467 encapsulated_packet->SetSsrc(packet.Ssrc() + 1);
468 return encapsulated_packet;
469 });
470 ASSERT_TRUE(retransmit_packet);
471 EXPECT_EQ(retransmit_packet->Ssrc(), kSsrc + 1);
472 }
473
TEST_P(RtpPacketHistoryTest,GetPacketWithEncapsulationAbortOnNullptr)474 TEST_P(RtpPacketHistoryTest, GetPacketWithEncapsulationAbortOnNullptr) {
475 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
476
477 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
478
479 // Retransmission request, but the encapsulator determines that this packet is
480 // not suitable for retransmission (bandwidth exhausted?) so the retransmit is
481 // aborted and the packet is not marked as pending.
482 EXPECT_FALSE(hist_.GetPacketAndMarkAsPending(
483 kStartSeqNum, [](const RtpPacketToSend&) { return nullptr; }));
484
485 // New try, this time getting the packet should work, and it should not be
486 // blocked due to any pending status.
487 EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
488 }
489
TEST_P(RtpPacketHistoryTest,DontRemovePendingTransmissions)490 TEST_P(RtpPacketHistoryTest, DontRemovePendingTransmissions) {
491 const TimeDelta kRtt = RtpPacketHistory::kMinPacketDuration * 2;
492 const TimeDelta kPacketTimeout =
493 kRtt * RtpPacketHistory::kMinPacketDurationRtt;
494
495 // Set size to remove old packets as soon as possible.
496 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
497 hist_.SetRtt(kRtt);
498
499 // Add a sent packet.
500 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
501
502 // Advance clock to just before packet timeout.
503 fake_clock_.AdvanceTime(kPacketTimeout - TimeDelta::Millis(1));
504 // Mark as enqueued in pacer.
505 EXPECT_TRUE(hist_.GetPacketAndMarkAsPending(kStartSeqNum));
506
507 // Advance clock to where packet would have timed out. It should still
508 // be there and pending.
509 fake_clock_.AdvanceTimeMilliseconds(1);
510 EXPECT_TRUE(hist_.GetPacketState(kStartSeqNum));
511
512 // Packet sent. Now it can be removed.
513 hist_.MarkPacketAsSent(kStartSeqNum);
514 hist_.SetRtt(kRtt); // Force culling of old packets.
515 EXPECT_FALSE(hist_.GetPacketState(kStartSeqNum));
516 }
517
TEST_P(RtpPacketHistoryTest,PrioritizedPayloadPadding)518 TEST_P(RtpPacketHistoryTest, PrioritizedPayloadPadding) {
519 if (!GetParam()) {
520 // Padding prioritization is off, ignore this test.
521 return;
522 }
523
524 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
525
526 // Add two sent packets, one millisecond apart.
527 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
528 fake_clock_.AdvanceTimeMilliseconds(1);
529
530 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum + 1),
531 fake_clock_.CurrentTime());
532 fake_clock_.AdvanceTimeMilliseconds(1);
533
534 // Latest packet given equal retransmission count.
535 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
536 kStartSeqNum + 1);
537
538 // Older packet has lower retransmission count.
539 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(), kStartSeqNum);
540
541 // Equal retransmission count again, use newest packet.
542 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
543 kStartSeqNum + 1);
544
545 // Older packet has lower retransmission count.
546 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(), kStartSeqNum);
547
548 // Remove newest packet.
549 hist_.CullAcknowledgedPackets(std::vector<uint16_t>{kStartSeqNum + 1});
550
551 // Only older packet left.
552 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(), kStartSeqNum);
553
554 hist_.CullAcknowledgedPackets(std::vector<uint16_t>{kStartSeqNum});
555
556 EXPECT_EQ(hist_.GetPayloadPaddingPacket(), nullptr);
557 }
558
TEST_P(RtpPacketHistoryTest,NoPendingPacketAsPadding)559 TEST_P(RtpPacketHistoryTest, NoPendingPacketAsPadding) {
560 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
561
562 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
563 fake_clock_.AdvanceTimeMilliseconds(1);
564
565 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(), kStartSeqNum);
566
567 // If packet is pending retransmission, don't try to use it as padding.
568 hist_.GetPacketAndMarkAsPending(kStartSeqNum);
569 EXPECT_EQ(nullptr, hist_.GetPayloadPaddingPacket());
570
571 // Market it as no longer pending, should be usable as padding again.
572 hist_.MarkPacketAsSent(kStartSeqNum);
573 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(), kStartSeqNum);
574 }
575
TEST_P(RtpPacketHistoryTest,PayloadPaddingWithEncapsulation)576 TEST_P(RtpPacketHistoryTest, PayloadPaddingWithEncapsulation) {
577 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 1);
578
579 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
580 fake_clock_.AdvanceTimeMilliseconds(1);
581
582 // Aborted padding.
583 EXPECT_EQ(nullptr, hist_.GetPayloadPaddingPacket(
584 [](const RtpPacketToSend&) { return nullptr; }));
585
586 // Get copy of packet, but with sequence number modified.
587 auto padding_packet =
588 hist_.GetPayloadPaddingPacket([&](const RtpPacketToSend& packet) {
589 auto encapsulated_packet = std::make_unique<RtpPacketToSend>(packet);
590 encapsulated_packet->SetSequenceNumber(kStartSeqNum + 1);
591 return encapsulated_packet;
592 });
593 ASSERT_TRUE(padding_packet);
594 EXPECT_EQ(padding_packet->SequenceNumber(), kStartSeqNum + 1);
595 }
596
TEST_P(RtpPacketHistoryTest,NackAfterAckIsNoop)597 TEST_P(RtpPacketHistoryTest, NackAfterAckIsNoop) {
598 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 2);
599 // Add two sent packets.
600 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum), fake_clock_.CurrentTime());
601 hist_.PutRtpPacket(CreateRtpPacket(kStartSeqNum + 1),
602 fake_clock_.CurrentTime());
603 // Remove newest one.
604 hist_.CullAcknowledgedPackets(std::vector<uint16_t>{kStartSeqNum + 1});
605 // Retransmission request for already acked packet, should be noop.
606 auto packet = hist_.GetPacketAndMarkAsPending(kStartSeqNum + 1);
607 EXPECT_EQ(packet.get(), nullptr);
608 }
609
TEST_P(RtpPacketHistoryTest,OutOfOrderInsertRemoval)610 TEST_P(RtpPacketHistoryTest, OutOfOrderInsertRemoval) {
611 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, 10);
612
613 // Insert packets, out of order, including both forwards and backwards
614 // sequence number wraps.
615 const int seq_offsets[] = {0, 1, -1, 2, -2, 3, -3};
616
617 for (int offset : seq_offsets) {
618 uint16_t seq_no = To16u(kStartSeqNum + offset);
619 std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(seq_no);
620 packet->SetPayloadSize(50);
621 hist_.PutRtpPacket(std::move(packet), fake_clock_.CurrentTime());
622 fake_clock_.AdvanceTimeMilliseconds(33);
623 }
624
625 // Check packet are there and remove them in the same out-of-order fashion.
626 for (int offset : seq_offsets) {
627 uint16_t seq_no = To16u(kStartSeqNum + offset);
628 EXPECT_TRUE(hist_.GetPacketState(seq_no));
629 std::vector<uint16_t> acked_sequence_numbers = {seq_no};
630 hist_.CullAcknowledgedPackets(acked_sequence_numbers);
631 EXPECT_FALSE(hist_.GetPacketState(seq_no));
632 }
633 }
634
TEST_P(RtpPacketHistoryTest,UsesLastPacketAsPaddingWithPrioOff)635 TEST_P(RtpPacketHistoryTest, UsesLastPacketAsPaddingWithPrioOff) {
636 if (GetParam()) {
637 // Padding prioritization is enabled, ignore this test.
638 return;
639 }
640
641 const size_t kHistorySize = 10;
642 hist_.SetStorePacketsStatus(StorageMode::kStoreAndCull, kHistorySize);
643
644 EXPECT_EQ(hist_.GetPayloadPaddingPacket(), nullptr);
645
646 for (size_t i = 0; i < kHistorySize; ++i) {
647 hist_.PutRtpPacket(CreateRtpPacket(To16u(kStartSeqNum + i)),
648 fake_clock_.CurrentTime());
649 hist_.MarkPacketAsSent(To16u(kStartSeqNum + i));
650 fake_clock_.AdvanceTimeMilliseconds(1);
651
652 // Last packet always returned.
653 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
654 To16u(kStartSeqNum + i));
655 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
656 To16u(kStartSeqNum + i));
657 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
658 To16u(kStartSeqNum + i));
659 }
660
661 // Remove packets from the end, last in the list should be returned.
662 for (size_t i = kHistorySize - 1; i > 0; --i) {
663 hist_.CullAcknowledgedPackets(
664 std::vector<uint16_t>{To16u(kStartSeqNum + i)});
665
666 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
667 To16u(kStartSeqNum + i - 1));
668 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
669 To16u(kStartSeqNum + i - 1));
670 EXPECT_EQ(hist_.GetPayloadPaddingPacket()->SequenceNumber(),
671 To16u(kStartSeqNum + i - 1));
672 }
673
674 hist_.CullAcknowledgedPackets(std::vector<uint16_t>{kStartSeqNum});
675 EXPECT_EQ(hist_.GetPayloadPaddingPacket(), nullptr);
676 }
677
678 INSTANTIATE_TEST_SUITE_P(WithAndWithoutPaddingPrio,
679 RtpPacketHistoryTest,
680 ::testing::Bool());
681 } // namespace webrtc
682