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/gtest.h"
20 #include "typedefs.h"  // NOLINT(build/include)
21 
22 namespace webrtc {
23 
24 class RtpPacketHistoryTest : public ::testing::Test {
25  protected:
26   static constexpr uint16_t kSeqNum = 88;
27 
RtpPacketHistoryTest()28   RtpPacketHistoryTest() : fake_clock_(123456), hist_(&fake_clock_) {}
29 
30   SimulatedClock fake_clock_;
31   RtpPacketHistory hist_;
32 
CreateRtpPacket(uint16_t seq_num)33   std::unique_ptr<RtpPacketToSend> CreateRtpPacket(uint16_t seq_num) {
34     // Payload, ssrc, timestamp and extensions are irrelevant for this tests.
35     std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(nullptr));
36     packet->SetSequenceNumber(seq_num);
37     packet->set_capture_time_ms(fake_clock_.TimeInMilliseconds());
38     return packet;
39   }
40 };
41 
TEST_F(RtpPacketHistoryTest,SetStoreStatus)42 TEST_F(RtpPacketHistoryTest, SetStoreStatus) {
43   EXPECT_FALSE(hist_.StorePackets());
44   hist_.SetStorePacketsStatus(true, 10);
45   EXPECT_TRUE(hist_.StorePackets());
46   hist_.SetStorePacketsStatus(false, 0);
47   EXPECT_FALSE(hist_.StorePackets());
48 }
49 
TEST_F(RtpPacketHistoryTest,NoStoreStatus)50 TEST_F(RtpPacketHistoryTest, NoStoreStatus) {
51   EXPECT_FALSE(hist_.StorePackets());
52   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum);
53   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
54   // Packet should not be stored.
55   EXPECT_FALSE(hist_.GetPacketAndSetSendTime(kSeqNum, 0, false));
56 }
57 
TEST_F(RtpPacketHistoryTest,GetRtpPacket_NotStored)58 TEST_F(RtpPacketHistoryTest, GetRtpPacket_NotStored) {
59   hist_.SetStorePacketsStatus(true, 10);
60   EXPECT_FALSE(hist_.GetPacketAndSetSendTime(0, 0, false));
61 }
62 
TEST_F(RtpPacketHistoryTest,PutRtpPacket)63 TEST_F(RtpPacketHistoryTest, PutRtpPacket) {
64   hist_.SetStorePacketsStatus(true, 10);
65   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum);
66 
67   EXPECT_FALSE(hist_.HasRtpPacket(kSeqNum));
68   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
69   EXPECT_TRUE(hist_.HasRtpPacket(kSeqNum));
70 }
71 
TEST_F(RtpPacketHistoryTest,GetRtpPacket)72 TEST_F(RtpPacketHistoryTest, GetRtpPacket) {
73   hist_.SetStorePacketsStatus(true, 10);
74   int64_t capture_time_ms = 1;
75   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum);
76   packet->set_capture_time_ms(capture_time_ms);
77   rtc::CopyOnWriteBuffer buffer = packet->Buffer();
78   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
79 
80   std::unique_ptr<RtpPacketToSend> packet_out =
81       hist_.GetPacketAndSetSendTime(kSeqNum, 0, false);
82   EXPECT_TRUE(packet_out);
83   EXPECT_EQ(buffer, packet_out->Buffer());
84   EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
85 }
86 
TEST_F(RtpPacketHistoryTest,NoCaptureTime)87 TEST_F(RtpPacketHistoryTest, NoCaptureTime) {
88   hist_.SetStorePacketsStatus(true, 10);
89   fake_clock_.AdvanceTimeMilliseconds(1);
90   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
91   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum);
92   packet->set_capture_time_ms(-1);
93   rtc::CopyOnWriteBuffer buffer = packet->Buffer();
94   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
95 
96   std::unique_ptr<RtpPacketToSend> packet_out =
97       hist_.GetPacketAndSetSendTime(kSeqNum, 0, false);
98   EXPECT_TRUE(packet_out);
99   EXPECT_EQ(buffer, packet_out->Buffer());
100   EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
101 }
102 
TEST_F(RtpPacketHistoryTest,DontRetransmit)103 TEST_F(RtpPacketHistoryTest, DontRetransmit) {
104   hist_.SetStorePacketsStatus(true, 10);
105   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
106   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum);
107   rtc::CopyOnWriteBuffer buffer = packet->Buffer();
108   hist_.PutRtpPacket(std::move(packet), kDontRetransmit, false);
109 
110   std::unique_ptr<RtpPacketToSend> packet_out;
111   packet_out = hist_.GetPacketAndSetSendTime(kSeqNum, 0, true);
112   EXPECT_FALSE(packet_out);
113 
114   packet_out = hist_.GetPacketAndSetSendTime(kSeqNum, 0, false);
115   EXPECT_TRUE(packet_out);
116 
117   EXPECT_EQ(buffer.size(), packet_out->size());
118   EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
119 }
120 
TEST_F(RtpPacketHistoryTest,MinResendTime)121 TEST_F(RtpPacketHistoryTest, MinResendTime) {
122   static const int64_t kMinRetransmitIntervalMs = 100;
123 
124   hist_.SetStorePacketsStatus(true, 10);
125   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
126   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum);
127   size_t len = packet->size();
128   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
129 
130   // First transmission: TimeToSendPacket() call from pacer.
131   EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kSeqNum, 0, false));
132 
133   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs);
134   // Time has elapsed.
135   std::unique_ptr<RtpPacketToSend> packet_out =
136       hist_.GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs, true);
137   EXPECT_TRUE(packet_out);
138   EXPECT_EQ(len, packet_out->size());
139   EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
140 
141   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1);
142   // Time has not elapsed. Packet should be found, but no bytes copied.
143   EXPECT_TRUE(hist_.HasRtpPacket(kSeqNum));
144   EXPECT_FALSE(
145       hist_.GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs, true));
146 }
147 
TEST_F(RtpPacketHistoryTest,EarlyFirstResend)148 TEST_F(RtpPacketHistoryTest, EarlyFirstResend) {
149   static const int64_t kMinRetransmitIntervalMs = 100;
150 
151   hist_.SetStorePacketsStatus(true, 10);
152   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
153   std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum);
154   rtc::CopyOnWriteBuffer buffer = packet->Buffer();
155   hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
156 
157   // First transmission: TimeToSendPacket() call from pacer.
158   EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kSeqNum, 0, false));
159 
160   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1);
161   // Time has not elapsed, but this is the first retransmission request so
162   // allow anyway.
163   std::unique_ptr<RtpPacketToSend> packet_out =
164       hist_.GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs, true);
165   EXPECT_TRUE(packet_out);
166   EXPECT_EQ(buffer, packet_out->Buffer());
167   EXPECT_EQ(capture_time_ms, packet_out->capture_time_ms());
168 
169   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1);
170   // Time has not elapsed. Packet should be found, but no bytes copied.
171   EXPECT_TRUE(hist_.HasRtpPacket(kSeqNum));
172   EXPECT_FALSE(
173       hist_.GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs, true));
174 }
175 
TEST_F(RtpPacketHistoryTest,DynamicExpansion)176 TEST_F(RtpPacketHistoryTest, DynamicExpansion) {
177   hist_.SetStorePacketsStatus(true, 10);
178 
179   // Add 4 packets, and then send them.
180   for (int i = 0; i < 4; ++i) {
181     std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum + i);
182     hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
183   }
184   for (int i = 0; i < 4; ++i) {
185     EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kSeqNum + i, 100, false));
186   }
187   fake_clock_.AdvanceTimeMilliseconds(33);
188 
189   // Add 16 packets, and then send them. History should expand to make this
190   // work.
191   for (int i = 4; i < 20; ++i) {
192     std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum + i);
193     hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
194   }
195   for (int i = 4; i < 20; ++i) {
196     EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kSeqNum + i, 100, false));
197   }
198 
199   fake_clock_.AdvanceTimeMilliseconds(100);
200 
201   // Retransmit last 16 packets.
202   for (int i = 4; i < 20; ++i) {
203     EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kSeqNum + i, 100, false));
204   }
205 }
206 
TEST_F(RtpPacketHistoryTest,FullExpansion)207 TEST_F(RtpPacketHistoryTest, FullExpansion) {
208   static const int kSendSidePacketHistorySize = 600;
209   hist_.SetStorePacketsStatus(true, kSendSidePacketHistorySize);
210   for (size_t i = 0; i < RtpPacketHistory::kMaxCapacity + 1; ++i) {
211     std::unique_ptr<RtpPacketToSend> packet = CreateRtpPacket(kSeqNum + i);
212     hist_.PutRtpPacket(std::move(packet), kAllowRetransmission, false);
213   }
214 
215   fake_clock_.AdvanceTimeMilliseconds(100);
216 
217   // Retransmit all packets currently in buffer.
218   for (size_t i = 1; i < RtpPacketHistory::kMaxCapacity + 1; ++i) {
219     EXPECT_TRUE(hist_.GetPacketAndSetSendTime(kSeqNum + i, 100, false));
220   }
221 }
222 
223 }  // namespace webrtc
224