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