xref: /aosp_15_r20/external/webrtc/modules/rtp_rtcp/source/rtp_packet_history_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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