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/source/flexfec_header_reader_writer.h"
12 
13 #include <string.h>
14 
15 #include <memory>
16 #include <utility>
17 
18 #include "api/scoped_refptr.h"
19 #include "modules/rtp_rtcp/source/byte_io.h"
20 #include "modules/rtp_rtcp/source/forward_error_correction.h"
21 #include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
22 #include "rtc_base/checks.h"
23 #include "rtc_base/random.h"
24 #include "test/gmock.h"
25 #include "test/gtest.h"
26 
27 namespace webrtc {
28 
29 namespace {
30 
31 using Packet = ForwardErrorCorrection::Packet;
32 using ReceivedFecPacket = ForwardErrorCorrection::ReceivedFecPacket;
33 
34 // General. Assume single-stream protection.
35 constexpr uint32_t kMediaSsrc = 1254983;
36 constexpr uint16_t kMediaStartSeqNum = 825;
37 constexpr size_t kMediaPacketLength = 1234;
38 constexpr uint32_t kFlexfecSsrc = 52142;
39 
40 constexpr size_t kFlexfecHeaderSizes[] = {20, 24, 32};
41 constexpr size_t kFlexfecPacketMaskOffset = 18;
42 constexpr size_t kFlexfecPacketMaskSizes[] = {2, 6, 14};
43 constexpr size_t kFlexfecMaxPacketSize = kFlexfecPacketMaskSizes[2];
44 
45 // Reader tests.
46 constexpr uint8_t kNoRBit = 0 << 7;
47 constexpr uint8_t kNoFBit = 0 << 6;
48 constexpr uint8_t kPtRecovery = 123;
49 constexpr uint8_t kLengthRecov[] = {0xab, 0xcd};
50 constexpr uint8_t kTsRecovery[] = {0x01, 0x23, 0x45, 0x67};
51 constexpr uint8_t kSsrcCount = 1;
52 constexpr uint8_t kReservedBits = 0x00;
53 constexpr uint8_t kProtSsrc[] = {0x11, 0x22, 0x33, 0x44};
54 constexpr uint8_t kSnBase[] = {0xaa, 0xbb};
55 constexpr uint8_t kPayloadBits = 0x00;
56 
GeneratePacketMask(size_t packet_mask_size,uint64_t seed)57 std::unique_ptr<uint8_t[]> GeneratePacketMask(size_t packet_mask_size,
58                                               uint64_t seed) {
59   Random random(seed);
60   std::unique_ptr<uint8_t[]> packet_mask(new uint8_t[kFlexfecMaxPacketSize]);
61   memset(packet_mask.get(), 0, kFlexfecMaxPacketSize);
62   for (size_t i = 0; i < packet_mask_size; ++i) {
63     packet_mask[i] = random.Rand<uint8_t>();
64   }
65   return packet_mask;
66 }
67 
ClearBit(size_t index,uint8_t * packet_mask)68 void ClearBit(size_t index, uint8_t* packet_mask) {
69   packet_mask[index / 8] &= ~(1 << (7 - index % 8));
70 }
71 
SetBit(size_t index,uint8_t * packet_mask)72 void SetBit(size_t index, uint8_t* packet_mask) {
73   packet_mask[index / 8] |= (1 << (7 - index % 8));
74 }
75 
WriteHeader(const uint8_t * packet_mask,size_t packet_mask_size)76 rtc::scoped_refptr<Packet> WriteHeader(const uint8_t* packet_mask,
77                                        size_t packet_mask_size) {
78   FlexfecHeaderWriter writer;
79   rtc::scoped_refptr<Packet> written_packet(new Packet());
80   written_packet->data.SetSize(kMediaPacketLength);
81   uint8_t* data = written_packet->data.MutableData();
82   for (size_t i = 0; i < written_packet->data.size(); ++i) {
83     data[i] = i;  // Actual content doesn't matter.
84   }
85   writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask,
86                            packet_mask_size, written_packet.get());
87   return written_packet;
88 }
89 
ReadHeader(const Packet & written_packet)90 std::unique_ptr<ReceivedFecPacket> ReadHeader(const Packet& written_packet) {
91   FlexfecHeaderReader reader;
92   std::unique_ptr<ReceivedFecPacket> read_packet(new ReceivedFecPacket());
93   read_packet->ssrc = kFlexfecSsrc;
94   read_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
95   read_packet->pkt->data = written_packet.data;
96   EXPECT_TRUE(reader.ReadFecHeader(read_packet.get()));
97   return read_packet;
98 }
99 
VerifyReadHeaders(size_t expected_fec_header_size,const uint8_t * expected_packet_mask,size_t expected_packet_mask_size,const ReceivedFecPacket & read_packet)100 void VerifyReadHeaders(size_t expected_fec_header_size,
101                        const uint8_t* expected_packet_mask,
102                        size_t expected_packet_mask_size,
103                        const ReceivedFecPacket& read_packet) {
104   EXPECT_EQ(expected_fec_header_size, read_packet.fec_header_size);
105   EXPECT_EQ(ByteReader<uint32_t>::ReadBigEndian(kProtSsrc),
106             read_packet.protected_ssrc);
107   EXPECT_EQ(ByteReader<uint16_t>::ReadBigEndian(kSnBase),
108             read_packet.seq_num_base);
109   const size_t packet_mask_offset = read_packet.packet_mask_offset;
110   EXPECT_EQ(kFlexfecPacketMaskOffset, packet_mask_offset);
111   EXPECT_EQ(expected_packet_mask_size, read_packet.packet_mask_size);
112   EXPECT_EQ(read_packet.pkt->data.size() - expected_fec_header_size,
113             read_packet.protection_length);
114   // Ensure that the K-bits are removed and the packet mask has been packed.
115   EXPECT_THAT(
116       ::testing::make_tuple(read_packet.pkt->data.cdata() + packet_mask_offset,
117                             read_packet.packet_mask_size),
118       ::testing::ElementsAreArray(expected_packet_mask,
119                                   expected_packet_mask_size));
120 }
121 
VerifyFinalizedHeaders(const uint8_t * expected_packet_mask,size_t expected_packet_mask_size,const Packet & written_packet)122 void VerifyFinalizedHeaders(const uint8_t* expected_packet_mask,
123                             size_t expected_packet_mask_size,
124                             const Packet& written_packet) {
125   const uint8_t* packet = written_packet.data.cdata();
126   EXPECT_EQ(0x00, packet[0] & 0x80);  // F bit clear.
127   EXPECT_EQ(0x00, packet[0] & 0x40);  // R bit clear.
128   EXPECT_EQ(0x01, packet[8]);         // SSRCCount = 1.
129   EXPECT_EQ(kMediaSsrc, ByteReader<uint32_t>::ReadBigEndian(packet + 12));
130   EXPECT_EQ(kMediaStartSeqNum,
131             ByteReader<uint16_t>::ReadBigEndian(packet + 16));
132   EXPECT_THAT(::testing::make_tuple(packet + kFlexfecPacketMaskOffset,
133                                     expected_packet_mask_size),
134               ::testing::ElementsAreArray(expected_packet_mask,
135                                           expected_packet_mask_size));
136 }
137 
VerifyWrittenAndReadHeaders(size_t expected_fec_header_size,const uint8_t * expected_packet_mask,size_t expected_packet_mask_size,const Packet & written_packet,const ReceivedFecPacket & read_packet)138 void VerifyWrittenAndReadHeaders(size_t expected_fec_header_size,
139                                  const uint8_t* expected_packet_mask,
140                                  size_t expected_packet_mask_size,
141                                  const Packet& written_packet,
142                                  const ReceivedFecPacket& read_packet) {
143   EXPECT_EQ(kFlexfecSsrc, read_packet.ssrc);
144   EXPECT_EQ(expected_fec_header_size, read_packet.fec_header_size);
145   EXPECT_EQ(kMediaSsrc, read_packet.protected_ssrc);
146   EXPECT_EQ(kMediaStartSeqNum, read_packet.seq_num_base);
147   EXPECT_EQ(kFlexfecPacketMaskOffset, read_packet.packet_mask_offset);
148   ASSERT_EQ(expected_packet_mask_size, read_packet.packet_mask_size);
149   EXPECT_EQ(written_packet.data.size() - expected_fec_header_size,
150             read_packet.protection_length);
151   // Verify that the call to ReadFecHeader did normalize the packet masks.
152   EXPECT_THAT(::testing::make_tuple(
153                   read_packet.pkt->data.cdata() + kFlexfecPacketMaskOffset,
154                   read_packet.packet_mask_size),
155               ::testing::ElementsAreArray(expected_packet_mask,
156                                           expected_packet_mask_size));
157   // Verify that the call to ReadFecHeader did not tamper with the payload.
158   EXPECT_THAT(::testing::make_tuple(
159                   read_packet.pkt->data.cdata() + read_packet.fec_header_size,
160                   read_packet.pkt->data.size() - read_packet.fec_header_size),
161               ::testing::ElementsAreArray(
162                   written_packet.data.cdata() + expected_fec_header_size,
163                   written_packet.data.size() - expected_fec_header_size));
164 }
165 
166 }  // namespace
167 
TEST(FlexfecHeaderReaderTest,ReadsHeaderWithKBit0Set)168 TEST(FlexfecHeaderReaderTest, ReadsHeaderWithKBit0Set) {
169   constexpr uint8_t kKBit0 = 1 << 7;
170   constexpr size_t kExpectedPacketMaskSize = 2;
171   constexpr size_t kExpectedFecHeaderSize = 20;
172   // clang-format off
173   constexpr uint8_t kFlexfecPktMask[] = {kKBit0 | 0x08, 0x81};
174   constexpr uint8_t kUlpfecPacketMask[] =        {0x11, 0x02};
175   // clang-format on
176   constexpr uint8_t kPacketData[] = {
177       kNoRBit | kNoFBit, kPtRecovery,    kLengthRecov[0],    kLengthRecov[1],
178       kTsRecovery[0],    kTsRecovery[1], kTsRecovery[2],     kTsRecovery[3],
179       kSsrcCount,        kReservedBits,  kReservedBits,      kReservedBits,
180       kProtSsrc[0],      kProtSsrc[1],   kProtSsrc[2],       kProtSsrc[3],
181       kSnBase[0],        kSnBase[1],     kFlexfecPktMask[0], kFlexfecPktMask[1],
182       kPayloadBits,      kPayloadBits,   kPayloadBits,       kPayloadBits};
183   const size_t packet_length = sizeof(kPacketData);
184   ReceivedFecPacket read_packet;
185   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
186   read_packet.pkt->data.SetData(kPacketData, packet_length);
187 
188   FlexfecHeaderReader reader;
189   EXPECT_TRUE(reader.ReadFecHeader(&read_packet));
190 
191   VerifyReadHeaders(kExpectedFecHeaderSize, kUlpfecPacketMask,
192                     kExpectedPacketMaskSize, read_packet);
193 }
194 
TEST(FlexfecHeaderReaderTest,ReadsHeaderWithKBit1Set)195 TEST(FlexfecHeaderReaderTest, ReadsHeaderWithKBit1Set) {
196   constexpr uint8_t kKBit0 = 0 << 7;
197   constexpr uint8_t kKBit1 = 1 << 7;
198   constexpr size_t kExpectedPacketMaskSize = 6;
199   constexpr size_t kExpectedFecHeaderSize = 24;
200   // clang-format off
201   constexpr uint8_t kFlxfecPktMsk[] = {kKBit0 | 0x48, 0x81,
202                                        kKBit1 | 0x02, 0x11, 0x00, 0x21};
203   constexpr uint8_t kUlpfecPacketMask[] =      {0x91, 0x02,
204                                                 0x08, 0x44, 0x00, 0x84};
205   // clang-format on
206   constexpr uint8_t kPacketData[] = {
207       kNoRBit | kNoFBit, kPtRecovery,      kLengthRecov[0],  kLengthRecov[1],
208       kTsRecovery[0],    kTsRecovery[1],   kTsRecovery[2],   kTsRecovery[3],
209       kSsrcCount,        kReservedBits,    kReservedBits,    kReservedBits,
210       kProtSsrc[0],      kProtSsrc[1],     kProtSsrc[2],     kProtSsrc[3],
211       kSnBase[0],        kSnBase[1],       kFlxfecPktMsk[0], kFlxfecPktMsk[1],
212       kFlxfecPktMsk[2],  kFlxfecPktMsk[3], kFlxfecPktMsk[4], kFlxfecPktMsk[5],
213       kPayloadBits,      kPayloadBits,     kPayloadBits,     kPayloadBits};
214   const size_t packet_length = sizeof(kPacketData);
215   ReceivedFecPacket read_packet;
216   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
217   read_packet.pkt->data.SetData(kPacketData, packet_length);
218 
219   FlexfecHeaderReader reader;
220   EXPECT_TRUE(reader.ReadFecHeader(&read_packet));
221 
222   VerifyReadHeaders(kExpectedFecHeaderSize, kUlpfecPacketMask,
223                     kExpectedPacketMaskSize, read_packet);
224 }
225 
TEST(FlexfecHeaderReaderTest,ReadsHeaderWithKBit2Set)226 TEST(FlexfecHeaderReaderTest, ReadsHeaderWithKBit2Set) {
227   constexpr uint8_t kKBit0 = 0 << 7;
228   constexpr uint8_t kKBit1 = 0 << 7;
229   constexpr uint8_t kKBit2 = 1 << 7;
230   constexpr size_t kExpectedPacketMaskSize = 14;
231   constexpr size_t kExpectedFecHeaderSize = 32;
232   // clang-format off
233   constexpr uint8_t kFlxfcPktMsk[] = {kKBit0 | 0x48, 0x81,
234                                       kKBit1 | 0x02, 0x11, 0x00, 0x21,
235                                       kKBit2 | 0x01, 0x11, 0x11, 0x11,
236                                                0x11, 0x11, 0x11, 0x11};
237   constexpr uint8_t kUlpfecPacketMask[] =     {0x91, 0x02,
238                                                0x08, 0x44, 0x00, 0x84,
239                                                0x08, 0x88, 0x88, 0x88,
240                                                0x88, 0x88, 0x88, 0x88};
241   // clang-format on
242   constexpr uint8_t kPacketData[] = {
243       kNoRBit | kNoFBit, kPtRecovery,      kLengthRecov[0],  kLengthRecov[1],
244       kTsRecovery[0],    kTsRecovery[1],   kTsRecovery[2],   kTsRecovery[3],
245       kSsrcCount,        kReservedBits,    kReservedBits,    kReservedBits,
246       kProtSsrc[0],      kProtSsrc[1],     kProtSsrc[2],     kProtSsrc[3],
247       kSnBase[0],        kSnBase[1],       kFlxfcPktMsk[0],  kFlxfcPktMsk[1],
248       kFlxfcPktMsk[2],   kFlxfcPktMsk[3],  kFlxfcPktMsk[4],  kFlxfcPktMsk[5],
249       kFlxfcPktMsk[6],   kFlxfcPktMsk[7],  kFlxfcPktMsk[8],  kFlxfcPktMsk[9],
250       kFlxfcPktMsk[10],  kFlxfcPktMsk[11], kFlxfcPktMsk[12], kFlxfcPktMsk[13],
251       kPayloadBits,      kPayloadBits,     kPayloadBits,     kPayloadBits};
252   const size_t packet_length = sizeof(kPacketData);
253   ReceivedFecPacket read_packet;
254   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
255   read_packet.pkt->data.SetData(kPacketData, packet_length);
256 
257   FlexfecHeaderReader reader;
258   EXPECT_TRUE(reader.ReadFecHeader(&read_packet));
259 
260   VerifyReadHeaders(kExpectedFecHeaderSize, kUlpfecPacketMask,
261                     kExpectedPacketMaskSize, read_packet);
262 }
263 
TEST(FlexfecHeaderReaderTest,ReadPacketWithoutStreamSpecificHeaderShouldFail)264 TEST(FlexfecHeaderReaderTest, ReadPacketWithoutStreamSpecificHeaderShouldFail) {
265   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
266   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
267   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
268 
269   // Simulate short received packet.
270   ReceivedFecPacket read_packet;
271   read_packet.ssrc = kFlexfecSsrc;
272   read_packet.pkt = std::move(written_packet);
273   read_packet.pkt->data.SetSize(12);
274 
275   FlexfecHeaderReader reader;
276   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
277 }
278 
TEST(FlexfecHeaderReaderTest,ReadShortPacketWithKBit0SetShouldFail)279 TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit0SetShouldFail) {
280   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
281   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
282   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
283 
284   // Simulate short received packet.
285   ReceivedFecPacket read_packet;
286   read_packet.ssrc = kFlexfecSsrc;
287   read_packet.pkt = std::move(written_packet);
288   read_packet.pkt->data.SetSize(18);
289 
290   FlexfecHeaderReader reader;
291   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
292 }
293 
TEST(FlexfecHeaderReaderTest,ReadShortPacketWithKBit1SetShouldFail)294 TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit1SetShouldFail) {
295   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
296   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
297   SetBit(15, packet_mask.get());  // This expands the packet mask "once".
298   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
299 
300   // Simulate short received packet.
301   ReceivedFecPacket read_packet;
302   read_packet.ssrc = kFlexfecSsrc;
303   read_packet.pkt = std::move(written_packet);
304   read_packet.pkt->data.SetSize(20);
305 
306   FlexfecHeaderReader reader;
307   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
308 }
309 
TEST(FlexfecHeaderReaderTest,ReadShortPacketWithKBit2SetShouldFail)310 TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit2SetShouldFail) {
311   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
312   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
313   SetBit(47, packet_mask.get());  // This expands the packet mask "twice".
314   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
315 
316   // Simulate short received packet.
317   ReceivedFecPacket read_packet;
318   read_packet.ssrc = kFlexfecSsrc;
319   read_packet.pkt = std::move(written_packet);
320   read_packet.pkt->data.SetSize(24);
321 
322   FlexfecHeaderReader reader;
323   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
324 }
325 
TEST(FlexfecHeaderWriterTest,FinalizesHeaderWithKBit0Set)326 TEST(FlexfecHeaderWriterTest, FinalizesHeaderWithKBit0Set) {
327   constexpr size_t kExpectedPacketMaskSize = 2;
328   constexpr uint8_t kFlexfecPacketMask[] = {0x88, 0x81};
329   constexpr uint8_t kUlpfecPacketMask[] = {0x11, 0x02};
330   Packet written_packet;
331   written_packet.data.SetSize(kMediaPacketLength);
332   uint8_t* data = written_packet.data.MutableData();
333   for (size_t i = 0; i < written_packet.data.size(); ++i) {
334     data[i] = i;
335   }
336 
337   FlexfecHeaderWriter writer;
338   writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask,
339                            sizeof(kUlpfecPacketMask), &written_packet);
340 
341   VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
342                          written_packet);
343 }
344 
TEST(FlexfecHeaderWriterTest,FinalizesHeaderWithKBit1Set)345 TEST(FlexfecHeaderWriterTest, FinalizesHeaderWithKBit1Set) {
346   constexpr size_t kExpectedPacketMaskSize = 6;
347   constexpr uint8_t kFlexfecPacketMask[] = {0x48, 0x81, 0x82, 0x11, 0x00, 0x21};
348   constexpr uint8_t kUlpfecPacketMask[] = {0x91, 0x02, 0x08, 0x44, 0x00, 0x84};
349   Packet written_packet;
350   written_packet.data.SetSize(kMediaPacketLength);
351   uint8_t* data = written_packet.data.MutableData();
352   for (size_t i = 0; i < written_packet.data.size(); ++i) {
353     data[i] = i;
354   }
355 
356   FlexfecHeaderWriter writer;
357   writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask,
358                            sizeof(kUlpfecPacketMask), &written_packet);
359 
360   VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
361                          written_packet);
362 }
363 
TEST(FlexfecHeaderWriterTest,FinalizesHeaderWithKBit2Set)364 TEST(FlexfecHeaderWriterTest, FinalizesHeaderWithKBit2Set) {
365   constexpr size_t kExpectedPacketMaskSize = 14;
366   constexpr uint8_t kFlexfecPacketMask[] = {
367       0x11, 0x11,                                     // K-bit 0 clear.
368       0x11, 0x11, 0x11, 0x10,                         // K-bit 1 clear.
369       0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // K-bit 2 set.
370   };
371   constexpr uint8_t kUlpfecPacketMask[] = {0x22, 0x22, 0x44, 0x44, 0x44, 0x41};
372   Packet written_packet;
373   written_packet.data.SetSize(kMediaPacketLength);
374   uint8_t* data = written_packet.data.MutableData();
375   for (size_t i = 0; i < written_packet.data.size(); ++i) {
376     data[i] = i;
377   }
378 
379   FlexfecHeaderWriter writer;
380   writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask,
381                            sizeof(kUlpfecPacketMask), &written_packet);
382 
383   VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
384                          written_packet);
385 }
386 
TEST(FlexfecHeaderWriterTest,ContractsShortUlpfecPacketMaskWithBit15Clear)387 TEST(FlexfecHeaderWriterTest, ContractsShortUlpfecPacketMaskWithBit15Clear) {
388   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
389   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
390   ClearBit(15, packet_mask.get());
391 
392   FlexfecHeaderWriter writer;
393   size_t min_packet_mask_size =
394       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
395 
396   EXPECT_EQ(kFlexfecPacketMaskSizes[0], min_packet_mask_size);
397   EXPECT_EQ(kFlexfecHeaderSizes[0], writer.FecHeaderSize(min_packet_mask_size));
398 }
399 
TEST(FlexfecHeaderWriterTest,ExpandsShortUlpfecPacketMaskWithBit15Set)400 TEST(FlexfecHeaderWriterTest, ExpandsShortUlpfecPacketMaskWithBit15Set) {
401   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
402   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
403   SetBit(15, packet_mask.get());
404 
405   FlexfecHeaderWriter writer;
406   size_t min_packet_mask_size =
407       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
408 
409   EXPECT_EQ(kFlexfecPacketMaskSizes[1], min_packet_mask_size);
410   EXPECT_EQ(kFlexfecHeaderSizes[1], writer.FecHeaderSize(min_packet_mask_size));
411 }
412 
TEST(FlexfecHeaderWriterTest,ContractsLongUlpfecPacketMaskWithBit46ClearBit47Clear)413 TEST(FlexfecHeaderWriterTest,
414      ContractsLongUlpfecPacketMaskWithBit46ClearBit47Clear) {
415   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
416   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
417   ClearBit(46, packet_mask.get());
418   ClearBit(47, packet_mask.get());
419 
420   FlexfecHeaderWriter writer;
421   size_t min_packet_mask_size =
422       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
423 
424   EXPECT_EQ(kFlexfecPacketMaskSizes[1], min_packet_mask_size);
425   EXPECT_EQ(kFlexfecHeaderSizes[1], writer.FecHeaderSize(min_packet_mask_size));
426 }
427 
TEST(FlexfecHeaderWriterTest,ExpandsLongUlpfecPacketMaskWithBit46SetBit47Clear)428 TEST(FlexfecHeaderWriterTest,
429      ExpandsLongUlpfecPacketMaskWithBit46SetBit47Clear) {
430   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
431   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
432   SetBit(46, packet_mask.get());
433   ClearBit(47, packet_mask.get());
434 
435   FlexfecHeaderWriter writer;
436   size_t min_packet_mask_size =
437       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
438 
439   EXPECT_EQ(kFlexfecPacketMaskSizes[2], min_packet_mask_size);
440   EXPECT_EQ(kFlexfecHeaderSizes[2], writer.FecHeaderSize(min_packet_mask_size));
441 }
442 
TEST(FlexfecHeaderWriterTest,ExpandsLongUlpfecPacketMaskWithBit46ClearBit47Set)443 TEST(FlexfecHeaderWriterTest,
444      ExpandsLongUlpfecPacketMaskWithBit46ClearBit47Set) {
445   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
446   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
447   ClearBit(46, packet_mask.get());
448   SetBit(47, packet_mask.get());
449 
450   FlexfecHeaderWriter writer;
451   size_t min_packet_mask_size =
452       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
453 
454   EXPECT_EQ(kFlexfecPacketMaskSizes[2], min_packet_mask_size);
455   EXPECT_EQ(kFlexfecHeaderSizes[2], writer.FecHeaderSize(min_packet_mask_size));
456 }
457 
TEST(FlexfecHeaderWriterTest,ExpandsLongUlpfecPacketMaskWithBit46SetBit47Set)458 TEST(FlexfecHeaderWriterTest, ExpandsLongUlpfecPacketMaskWithBit46SetBit47Set) {
459   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
460   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
461   SetBit(46, packet_mask.get());
462   SetBit(47, packet_mask.get());
463 
464   FlexfecHeaderWriter writer;
465   size_t min_packet_mask_size =
466       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
467 
468   EXPECT_EQ(kFlexfecPacketMaskSizes[2], min_packet_mask_size);
469   EXPECT_EQ(kFlexfecHeaderSizes[2], writer.FecHeaderSize(min_packet_mask_size));
470 }
471 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadSmallUlpfecPacketHeaderWithMaskBit15Clear)472 TEST(FlexfecHeaderReaderWriterTest,
473      WriteAndReadSmallUlpfecPacketHeaderWithMaskBit15Clear) {
474   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
475   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
476   ClearBit(15, packet_mask.get());
477 
478   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
479   auto read_packet = ReadHeader(*written_packet);
480 
481   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[0], packet_mask.get(),
482                               kFlexfecPacketMaskSizes[0], *written_packet,
483                               *read_packet);
484 }
485 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadSmallUlpfecPacketHeaderWithMaskBit15Set)486 TEST(FlexfecHeaderReaderWriterTest,
487      WriteAndReadSmallUlpfecPacketHeaderWithMaskBit15Set) {
488   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
489   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
490   SetBit(15, packet_mask.get());
491 
492   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
493   auto read_packet = ReadHeader(*written_packet);
494 
495   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[1], packet_mask.get(),
496                               kFlexfecPacketMaskSizes[1], *written_packet,
497                               *read_packet);
498 }
499 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadLargeUlpfecPacketHeaderWithMaskBits46And47Clear)500 TEST(FlexfecHeaderReaderWriterTest,
501      WriteAndReadLargeUlpfecPacketHeaderWithMaskBits46And47Clear) {
502   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
503   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
504   ClearBit(46, packet_mask.get());
505   ClearBit(47, packet_mask.get());
506 
507   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
508   auto read_packet = ReadHeader(*written_packet);
509 
510   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[1], packet_mask.get(),
511                               kFlexfecPacketMaskSizes[1], *written_packet,
512                               *read_packet);
513 }
514 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadLargeUlpfecPacketHeaderWithMaskBit46SetBit47Clear)515 TEST(FlexfecHeaderReaderWriterTest,
516      WriteAndReadLargeUlpfecPacketHeaderWithMaskBit46SetBit47Clear) {
517   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
518   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
519   SetBit(46, packet_mask.get());
520   ClearBit(47, packet_mask.get());
521 
522   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
523   auto read_packet = ReadHeader(*written_packet);
524 
525   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[2], packet_mask.get(),
526                               kFlexfecPacketMaskSizes[2], *written_packet,
527                               *read_packet);
528 }
529 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadLargeUlpfecPacketHeaderMaskWithBit46ClearBit47Set)530 TEST(FlexfecHeaderReaderWriterTest,
531      WriteAndReadLargeUlpfecPacketHeaderMaskWithBit46ClearBit47Set) {
532   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
533   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
534   ClearBit(46, packet_mask.get());
535   SetBit(47, packet_mask.get());
536 
537   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
538   auto read_packet = ReadHeader(*written_packet);
539 
540   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[2], packet_mask.get(),
541                               kFlexfecPacketMaskSizes[2], *written_packet,
542                               *read_packet);
543 }
544 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadLargeUlpfecPacketHeaderWithMaskBits46And47Set)545 TEST(FlexfecHeaderReaderWriterTest,
546      WriteAndReadLargeUlpfecPacketHeaderWithMaskBits46And47Set) {
547   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
548   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
549   SetBit(46, packet_mask.get());
550   SetBit(47, packet_mask.get());
551 
552   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
553   auto read_packet = ReadHeader(*written_packet);
554 
555   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[2], packet_mask.get(),
556                               kFlexfecPacketMaskSizes[2], *written_packet,
557                               *read_packet);
558 }
559 
560 }  // namespace webrtc
561