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/rtp_rtcp/include/flexfec_sender.h"
12
13 #include <vector>
14
15 #include "api/rtp_parameters.h"
16 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
17 #include "modules/rtp_rtcp/source/fec_test_helper.h"
18 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
19 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
20 #include "modules/rtp_rtcp/source/rtp_sender.h"
21 #include "system_wrappers/include/clock.h"
22 #include "test/gtest.h"
23
24 namespace webrtc {
25
26 namespace {
27
28 using test::fec::AugmentedPacket;
29 using test::fec::AugmentedPacketGenerator;
30
31 constexpr int kFlexfecPayloadType = 123;
32 constexpr uint32_t kMediaSsrc = 1234;
33 constexpr uint32_t kFlexfecSsrc = 5678;
34 const char kNoMid[] = "";
35 const std::vector<RtpExtension> kNoRtpHeaderExtensions;
36 const std::vector<RtpExtensionSize> kNoRtpHeaderExtensionSizes;
37 // Assume a single protected media SSRC.
38 constexpr size_t kFlexfecMaxHeaderSize = 32;
39 constexpr size_t kPayloadLength = 50;
40
41 constexpr int64_t kInitialSimulatedClockTime = 1;
42 // These values are deterministically given by the PRNG, due to our fixed seed.
43 // They should be updated if the PRNG implementation changes.
44 constexpr uint16_t kDeterministicSequenceNumber = 28732;
45 constexpr uint32_t kDeterministicTimestamp = 2305613085;
46
47 // Round up to the nearest size that is a multiple of 4.
Word32Align(size_t size)48 size_t Word32Align(size_t size) {
49 uint32_t remainder = size % 4;
50 if (remainder != 0)
51 return size + 4 - remainder;
52 return size;
53 }
54
GenerateSingleFlexfecPacket(FlexfecSender * sender)55 std::unique_ptr<RtpPacketToSend> GenerateSingleFlexfecPacket(
56 FlexfecSender* sender) {
57 // Parameters selected to generate a single FEC packet.
58 FecProtectionParams params;
59 params.fec_rate = 15;
60 params.max_fec_frames = 1;
61 params.fec_mask_type = kFecMaskRandom;
62 constexpr size_t kNumPackets = 4;
63
64 sender->SetProtectionParameters(params, params);
65 AugmentedPacketGenerator packet_generator(kMediaSsrc);
66 packet_generator.NewFrame(kNumPackets);
67 for (size_t i = 0; i < kNumPackets; ++i) {
68 std::unique_ptr<AugmentedPacket> packet =
69 packet_generator.NextPacket(i, kPayloadLength);
70 RtpPacketToSend rtp_packet(nullptr); // No header extensions.
71 rtp_packet.Parse(packet->data);
72 sender->AddPacketAndGenerateFec(rtp_packet);
73 }
74 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
75 sender->GetFecPackets();
76 EXPECT_EQ(1U, fec_packets.size());
77 EXPECT_TRUE(sender->GetFecPackets().empty());
78
79 return std::move(fec_packets.front());
80 }
81
82 } // namespace
83
TEST(FlexfecSenderTest,Ssrc)84 TEST(FlexfecSenderTest, Ssrc) {
85 SimulatedClock clock(kInitialSimulatedClockTime);
86 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
87 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
88 nullptr /* rtp_state */, &clock);
89
90 EXPECT_EQ(kFlexfecSsrc, sender.FecSsrc());
91 }
92
TEST(FlexfecSenderTest,NoFecAvailableBeforeMediaAdded)93 TEST(FlexfecSenderTest, NoFecAvailableBeforeMediaAdded) {
94 SimulatedClock clock(kInitialSimulatedClockTime);
95 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
96 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
97 nullptr /* rtp_state */, &clock);
98
99 EXPECT_TRUE(sender.GetFecPackets().empty());
100 }
101
TEST(FlexfecSenderTest,ProtectOneFrameWithOneFecPacket)102 TEST(FlexfecSenderTest, ProtectOneFrameWithOneFecPacket) {
103 SimulatedClock clock(kInitialSimulatedClockTime);
104 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
105 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
106 nullptr /* rtp_state */, &clock);
107 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
108
109 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
110 EXPECT_FALSE(fec_packet->Marker());
111 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
112 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
113 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
114 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
115 EXPECT_LE(kPayloadLength, fec_packet->payload_size());
116 }
117
TEST(FlexfecSenderTest,ProtectTwoFramesWithOneFecPacket)118 TEST(FlexfecSenderTest, ProtectTwoFramesWithOneFecPacket) {
119 // FEC parameters selected to generate a single FEC packet per frame.
120 FecProtectionParams params;
121 params.fec_rate = 15;
122 params.max_fec_frames = 2;
123 params.fec_mask_type = kFecMaskRandom;
124 constexpr size_t kNumFrames = 2;
125 constexpr size_t kNumPacketsPerFrame = 2;
126 SimulatedClock clock(kInitialSimulatedClockTime);
127 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
128 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
129 nullptr /* rtp_state */, &clock);
130 sender.SetProtectionParameters(params, params);
131
132 AugmentedPacketGenerator packet_generator(kMediaSsrc);
133 for (size_t i = 0; i < kNumFrames; ++i) {
134 packet_generator.NewFrame(kNumPacketsPerFrame);
135 for (size_t j = 0; j < kNumPacketsPerFrame; ++j) {
136 std::unique_ptr<AugmentedPacket> packet =
137 packet_generator.NextPacket(i, kPayloadLength);
138 RtpPacketToSend rtp_packet(nullptr);
139 rtp_packet.Parse(packet->data);
140 sender.AddPacketAndGenerateFec(rtp_packet);
141 }
142 }
143 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
144 sender.GetFecPackets();
145 ASSERT_EQ(1U, fec_packets.size());
146 EXPECT_TRUE(sender.GetFecPackets().empty());
147
148 RtpPacketToSend* fec_packet = fec_packets.front().get();
149 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
150 EXPECT_FALSE(fec_packet->Marker());
151 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
152 EXPECT_EQ(kDeterministicSequenceNumber, fec_packet->SequenceNumber());
153 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
154 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
155 }
156
TEST(FlexfecSenderTest,ProtectTwoFramesWithTwoFecPackets)157 TEST(FlexfecSenderTest, ProtectTwoFramesWithTwoFecPackets) {
158 // FEC parameters selected to generate a single FEC packet per frame.
159 FecProtectionParams params;
160 params.fec_rate = 30;
161 params.max_fec_frames = 1;
162 params.fec_mask_type = kFecMaskRandom;
163 constexpr size_t kNumFrames = 2;
164 constexpr size_t kNumPacketsPerFrame = 2;
165 SimulatedClock clock(kInitialSimulatedClockTime);
166 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
167 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
168 nullptr /* rtp_state */, &clock);
169 sender.SetProtectionParameters(params, params);
170
171 AugmentedPacketGenerator packet_generator(kMediaSsrc);
172 for (size_t i = 0; i < kNumFrames; ++i) {
173 packet_generator.NewFrame(kNumPacketsPerFrame);
174 for (size_t j = 0; j < kNumPacketsPerFrame; ++j) {
175 std::unique_ptr<AugmentedPacket> packet =
176 packet_generator.NextPacket(i, kPayloadLength);
177 RtpPacketToSend rtp_packet(nullptr);
178 rtp_packet.Parse(packet->data);
179 sender.AddPacketAndGenerateFec(rtp_packet);
180 }
181 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets =
182 sender.GetFecPackets();
183 ASSERT_EQ(1U, fec_packets.size());
184 EXPECT_TRUE(sender.GetFecPackets().empty());
185
186 RtpPacketToSend* fec_packet = fec_packets.front().get();
187 EXPECT_EQ(kRtpHeaderSize, fec_packet->headers_size());
188 EXPECT_FALSE(fec_packet->Marker());
189 EXPECT_EQ(kFlexfecPayloadType, fec_packet->PayloadType());
190 EXPECT_EQ(static_cast<uint16_t>(kDeterministicSequenceNumber + i),
191 fec_packet->SequenceNumber());
192 EXPECT_EQ(kDeterministicTimestamp, fec_packet->Timestamp());
193 EXPECT_EQ(kFlexfecSsrc, fec_packet->Ssrc());
194 }
195 }
196
197 // In the tests, we only consider RTP header extensions that are useful for BWE.
TEST(FlexfecSenderTest,NoRtpHeaderExtensionsForBweByDefault)198 TEST(FlexfecSenderTest, NoRtpHeaderExtensionsForBweByDefault) {
199 const std::vector<RtpExtension> kRtpHeaderExtensions{};
200 SimulatedClock clock(kInitialSimulatedClockTime);
201 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
202 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
203 nullptr /* rtp_state */, &clock);
204 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
205
206 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
207 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
208 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
209 }
210
TEST(FlexfecSenderTest,RegisterAbsoluteSendTimeRtpHeaderExtension)211 TEST(FlexfecSenderTest, RegisterAbsoluteSendTimeRtpHeaderExtension) {
212 const std::vector<RtpExtension> kRtpHeaderExtensions{
213 {RtpExtension::kAbsSendTimeUri, 1}};
214 SimulatedClock clock(kInitialSimulatedClockTime);
215 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
216 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
217 nullptr /* rtp_state */, &clock);
218 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
219
220 EXPECT_TRUE(fec_packet->HasExtension<AbsoluteSendTime>());
221 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
222 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
223 }
224
TEST(FlexfecSenderTest,RegisterTransmissionOffsetRtpHeaderExtension)225 TEST(FlexfecSenderTest, RegisterTransmissionOffsetRtpHeaderExtension) {
226 const std::vector<RtpExtension> kRtpHeaderExtensions{
227 {RtpExtension::kTimestampOffsetUri, 1}};
228 SimulatedClock clock(kInitialSimulatedClockTime);
229 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
230 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
231 nullptr /* rtp_state */, &clock);
232 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
233
234 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
235 EXPECT_TRUE(fec_packet->HasExtension<TransmissionOffset>());
236 EXPECT_FALSE(fec_packet->HasExtension<TransportSequenceNumber>());
237 }
238
TEST(FlexfecSenderTest,RegisterTransportSequenceNumberRtpHeaderExtension)239 TEST(FlexfecSenderTest, RegisterTransportSequenceNumberRtpHeaderExtension) {
240 const std::vector<RtpExtension> kRtpHeaderExtensions{
241 {RtpExtension::kTransportSequenceNumberUri, 1}};
242 SimulatedClock clock(kInitialSimulatedClockTime);
243 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
244 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
245 nullptr /* rtp_state */, &clock);
246 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
247
248 EXPECT_FALSE(fec_packet->HasExtension<AbsoluteSendTime>());
249 EXPECT_FALSE(fec_packet->HasExtension<TransmissionOffset>());
250 EXPECT_TRUE(fec_packet->HasExtension<TransportSequenceNumber>());
251 }
252
TEST(FlexfecSenderTest,RegisterAllRtpHeaderExtensionsForBwe)253 TEST(FlexfecSenderTest, RegisterAllRtpHeaderExtensionsForBwe) {
254 const std::vector<RtpExtension> kRtpHeaderExtensions{
255 {RtpExtension::kAbsSendTimeUri, 1},
256 {RtpExtension::kTimestampOffsetUri, 2},
257 {RtpExtension::kTransportSequenceNumberUri, 3}};
258 SimulatedClock clock(kInitialSimulatedClockTime);
259 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
260 kRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
261 nullptr /* rtp_state */, &clock);
262 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
263
264 EXPECT_TRUE(fec_packet->HasExtension<AbsoluteSendTime>());
265 EXPECT_TRUE(fec_packet->HasExtension<TransmissionOffset>());
266 EXPECT_TRUE(fec_packet->HasExtension<TransportSequenceNumber>());
267 }
268
TEST(FlexfecSenderTest,MaxPacketOverhead)269 TEST(FlexfecSenderTest, MaxPacketOverhead) {
270 SimulatedClock clock(kInitialSimulatedClockTime);
271 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
272 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
273 nullptr /* rtp_state */, &clock);
274
275 EXPECT_EQ(kFlexfecMaxHeaderSize, sender.MaxPacketOverhead());
276 }
277
TEST(FlexfecSenderTest,MaxPacketOverheadWithExtensions)278 TEST(FlexfecSenderTest, MaxPacketOverheadWithExtensions) {
279 const std::vector<RtpExtension> kRtpHeaderExtensions{
280 {RtpExtension::kAbsSendTimeUri, 1},
281 {RtpExtension::kTimestampOffsetUri, 2},
282 {RtpExtension::kTransportSequenceNumberUri, 3}};
283 SimulatedClock clock(kInitialSimulatedClockTime);
284 const size_t kExtensionHeaderLength = 1;
285 const size_t kRtpOneByteHeaderLength = 4;
286 const size_t kExtensionsTotalSize =
287 Word32Align(kRtpOneByteHeaderLength + kExtensionHeaderLength +
288 AbsoluteSendTime::kValueSizeBytes + kExtensionHeaderLength +
289 TransmissionOffset::kValueSizeBytes + kExtensionHeaderLength +
290 TransportSequenceNumber::kValueSizeBytes);
291 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
292 kRtpHeaderExtensions, RTPSender::FecExtensionSizes(),
293 nullptr /* rtp_state */, &clock);
294
295 EXPECT_EQ(kExtensionsTotalSize + kFlexfecMaxHeaderSize,
296 sender.MaxPacketOverhead());
297 }
298
TEST(FlexfecSenderTest,MidIncludedInPacketsWhenSet)299 TEST(FlexfecSenderTest, MidIncludedInPacketsWhenSet) {
300 const std::vector<RtpExtension> kRtpHeaderExtensions{
301 {RtpExtension::kMidUri, 1}};
302 const char kMid[] = "mid";
303 SimulatedClock clock(kInitialSimulatedClockTime);
304 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kMid,
305 kRtpHeaderExtensions, RTPSender::FecExtensionSizes(),
306 nullptr /* rtp_state */, &clock);
307
308 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
309
310 std::string mid;
311 ASSERT_TRUE(fec_packet->GetExtension<RtpMid>(&mid));
312 EXPECT_EQ(kMid, mid);
313 }
314
TEST(FlexfecSenderTest,SetsAndGetsRtpState)315 TEST(FlexfecSenderTest, SetsAndGetsRtpState) {
316 RtpState initial_rtp_state;
317 initial_rtp_state.sequence_number = 100;
318 initial_rtp_state.start_timestamp = 200;
319 SimulatedClock clock(kInitialSimulatedClockTime);
320 FlexfecSender sender(kFlexfecPayloadType, kFlexfecSsrc, kMediaSsrc, kNoMid,
321 kNoRtpHeaderExtensions, kNoRtpHeaderExtensionSizes,
322 &initial_rtp_state, &clock);
323
324 auto fec_packet = GenerateSingleFlexfecPacket(&sender);
325 EXPECT_EQ(initial_rtp_state.sequence_number, fec_packet->SequenceNumber());
326 EXPECT_EQ(initial_rtp_state.start_timestamp, fec_packet->Timestamp());
327
328 clock.AdvanceTimeMilliseconds(1000);
329 fec_packet = GenerateSingleFlexfecPacket(&sender);
330 EXPECT_EQ(initial_rtp_state.sequence_number + 1,
331 fec_packet->SequenceNumber());
332 EXPECT_EQ(initial_rtp_state.start_timestamp + 1 * kVideoPayloadTypeFrequency,
333 fec_packet->Timestamp());
334
335 RtpState updated_rtp_state = sender.GetRtpState().value();
336 EXPECT_EQ(initial_rtp_state.sequence_number + 2,
337 updated_rtp_state.sequence_number);
338 EXPECT_EQ(initial_rtp_state.start_timestamp,
339 updated_rtp_state.start_timestamp);
340 }
341
342 } // namespace webrtc
343