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