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