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