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