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 <string.h>
12 
13 #include <memory>
14 #include <utility>
15 
16 #include "modules/rtp_rtcp/source/byte_io.h"
17 #include "modules/rtp_rtcp/source/flexfec_header_reader_writer.h"
18 #include "modules/rtp_rtcp/source/forward_error_correction.h"
19 #include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
20 #include "rtc_base/basictypes.h"
21 #include "rtc_base/checks.h"
22 #include "rtc_base/random.h"
23 #include "rtc_base/scoped_ref_ptr.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->length = kMediaPacketLength;
81   for (size_t i = 0; i < written_packet->length; ++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   memcpy(read_packet->pkt->data, written_packet.data, written_packet.length);
95   read_packet->pkt->length = written_packet.length;
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->length - 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(::testing::make_tuple(read_packet.pkt->data + 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;
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.length - expected_fec_header_size,
149             read_packet.protection_length);
150   // Verify that the call to ReadFecHeader did normalize the packet masks.
151   EXPECT_THAT(
152       ::testing::make_tuple(read_packet.pkt->data + 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 + read_packet.fec_header_size,
159                   read_packet.pkt->length - read_packet.fec_header_size),
160               ::testing::ElementsAreArray(
161                   written_packet.data + expected_fec_header_size,
162                   written_packet.length - 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   memcpy(read_packet.pkt->data, kPacketData, packet_length);
186   read_packet.pkt->length = 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   memcpy(read_packet.pkt->data, kPacketData, packet_length);
218   read_packet.pkt->length = packet_length;
219 
220   FlexfecHeaderReader reader;
221   EXPECT_TRUE(reader.ReadFecHeader(&read_packet));
222 
223   VerifyReadHeaders(kExpectedFecHeaderSize, kUlpfecPacketMask,
224                     kExpectedPacketMaskSize, read_packet);
225 }
226 
TEST(FlexfecHeaderReaderTest,ReadsHeaderWithKBit2Set)227 TEST(FlexfecHeaderReaderTest, ReadsHeaderWithKBit2Set) {
228   constexpr uint8_t kKBit0 = 0 << 7;
229   constexpr uint8_t kKBit1 = 0 << 7;
230   constexpr uint8_t kKBit2 = 1 << 7;
231   constexpr size_t kExpectedPacketMaskSize = 14;
232   constexpr size_t kExpectedFecHeaderSize = 32;
233   // clang-format off
234   constexpr uint8_t kFlxfcPktMsk[] = {kKBit0 | 0x48, 0x81,
235                                       kKBit1 | 0x02, 0x11, 0x00, 0x21,
236                                       kKBit2 | 0x01, 0x11, 0x11, 0x11,
237                                                0x11, 0x11, 0x11, 0x11};
238   constexpr uint8_t kUlpfecPacketMask[] =     {0x91, 0x02,
239                                                0x08, 0x44, 0x00, 0x84,
240                                                0x08, 0x88, 0x88, 0x88,
241                                                0x88, 0x88, 0x88, 0x88};
242   // clang-format on
243   constexpr uint8_t kPacketData[] = {
244       kNoRBit | kNoFBit, kPtRecovery,      kLengthRecov[0],  kLengthRecov[1],
245       kTsRecovery[0],    kTsRecovery[1],   kTsRecovery[2],   kTsRecovery[3],
246       kSsrcCount,        kReservedBits,    kReservedBits,    kReservedBits,
247       kProtSsrc[0],      kProtSsrc[1],     kProtSsrc[2],     kProtSsrc[3],
248       kSnBase[0],        kSnBase[1],       kFlxfcPktMsk[0],  kFlxfcPktMsk[1],
249       kFlxfcPktMsk[2],   kFlxfcPktMsk[3],  kFlxfcPktMsk[4],  kFlxfcPktMsk[5],
250       kFlxfcPktMsk[6],   kFlxfcPktMsk[7],  kFlxfcPktMsk[8],  kFlxfcPktMsk[9],
251       kFlxfcPktMsk[10],  kFlxfcPktMsk[11], kFlxfcPktMsk[12], kFlxfcPktMsk[13],
252       kPayloadBits,      kPayloadBits,     kPayloadBits,     kPayloadBits};
253   const size_t packet_length = sizeof(kPacketData);
254   ReceivedFecPacket read_packet;
255   read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
256   memcpy(read_packet.pkt->data, kPacketData, packet_length);
257   read_packet.pkt->length = packet_length;
258 
259   FlexfecHeaderReader reader;
260   EXPECT_TRUE(reader.ReadFecHeader(&read_packet));
261 
262   VerifyReadHeaders(kExpectedFecHeaderSize, kUlpfecPacketMask,
263                     kExpectedPacketMaskSize, read_packet);
264 }
265 
TEST(FlexfecHeaderReaderTest,ReadPacketWithoutStreamSpecificHeaderShouldFail)266 TEST(FlexfecHeaderReaderTest, ReadPacketWithoutStreamSpecificHeaderShouldFail) {
267   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
268   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
269   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
270 
271   // Simulate short received packet.
272   ReceivedFecPacket read_packet;
273   read_packet.ssrc = kFlexfecSsrc;
274   read_packet.pkt = std::move(written_packet);
275   read_packet.pkt->length = 12;
276 
277   FlexfecHeaderReader reader;
278   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
279 }
280 
TEST(FlexfecHeaderReaderTest,ReadShortPacketWithKBit0SetShouldFail)281 TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit0SetShouldFail) {
282   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
283   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
284   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
285 
286   // Simulate short received packet.
287   ReceivedFecPacket read_packet;
288   read_packet.ssrc = kFlexfecSsrc;
289   read_packet.pkt = std::move(written_packet);
290   read_packet.pkt->length = 18;
291 
292   FlexfecHeaderReader reader;
293   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
294 }
295 
TEST(FlexfecHeaderReaderTest,ReadShortPacketWithKBit1SetShouldFail)296 TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit1SetShouldFail) {
297   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
298   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
299   SetBit(15, packet_mask.get());  // This expands the packet mask "once".
300   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
301 
302   // Simulate short received packet.
303   ReceivedFecPacket read_packet;
304   read_packet.ssrc = kFlexfecSsrc;
305   read_packet.pkt = std::move(written_packet);
306   read_packet.pkt->length = 20;
307 
308   FlexfecHeaderReader reader;
309   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
310 }
311 
TEST(FlexfecHeaderReaderTest,ReadShortPacketWithKBit2SetShouldFail)312 TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit2SetShouldFail) {
313   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
314   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
315   SetBit(47, packet_mask.get());  // This expands the packet mask "twice".
316   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
317 
318   // Simulate short received packet.
319   ReceivedFecPacket read_packet;
320   read_packet.ssrc = kFlexfecSsrc;
321   read_packet.pkt = std::move(written_packet);
322   read_packet.pkt->length = 24;
323 
324   FlexfecHeaderReader reader;
325   EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
326 }
327 
TEST(FlexfecHeaderWriterTest,FinalizesHeaderWithKBit0Set)328 TEST(FlexfecHeaderWriterTest, FinalizesHeaderWithKBit0Set) {
329   constexpr size_t kExpectedPacketMaskSize = 2;
330   constexpr uint8_t kFlexfecPacketMask[] = {0x88, 0x81};
331   constexpr uint8_t kUlpfecPacketMask[] = {0x11, 0x02};
332   Packet written_packet;
333   written_packet.length = kMediaPacketLength;
334   for (size_t i = 0; i < written_packet.length; ++i) {
335     written_packet.data[i] = i;
336   }
337 
338   FlexfecHeaderWriter writer;
339   writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask,
340                            sizeof(kUlpfecPacketMask), &written_packet);
341 
342   VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
343                          written_packet);
344 }
345 
TEST(FlexfecHeaderWriterTest,FinalizesHeaderWithKBit1Set)346 TEST(FlexfecHeaderWriterTest, FinalizesHeaderWithKBit1Set) {
347   constexpr size_t kExpectedPacketMaskSize = 6;
348   constexpr uint8_t kFlexfecPacketMask[] = {0x48, 0x81, 0x82, 0x11, 0x00, 0x21};
349   constexpr uint8_t kUlpfecPacketMask[] = {0x91, 0x02, 0x08, 0x44, 0x00, 0x84};
350   Packet written_packet;
351   written_packet.length = kMediaPacketLength;
352   for (size_t i = 0; i < written_packet.length; ++i) {
353     written_packet.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.length = kMediaPacketLength;
374   for (size_t i = 0; i < written_packet.length; ++i) {
375     written_packet.data[i] = i;
376   }
377 
378   FlexfecHeaderWriter writer;
379   writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask,
380                            sizeof(kUlpfecPacketMask), &written_packet);
381 
382   VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
383                          written_packet);
384 }
385 
TEST(FlexfecHeaderWriterTest,ContractsShortUlpfecPacketMaskWithBit15Clear)386 TEST(FlexfecHeaderWriterTest, ContractsShortUlpfecPacketMaskWithBit15Clear) {
387   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
388   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
389   ClearBit(15, packet_mask.get());
390 
391   FlexfecHeaderWriter writer;
392   size_t min_packet_mask_size =
393       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
394 
395   EXPECT_EQ(kFlexfecPacketMaskSizes[0], min_packet_mask_size);
396   EXPECT_EQ(kFlexfecHeaderSizes[0], writer.FecHeaderSize(min_packet_mask_size));
397 }
398 
TEST(FlexfecHeaderWriterTest,ExpandsShortUlpfecPacketMaskWithBit15Set)399 TEST(FlexfecHeaderWriterTest, ExpandsShortUlpfecPacketMaskWithBit15Set) {
400   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
401   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
402   SetBit(15, packet_mask.get());
403 
404   FlexfecHeaderWriter writer;
405   size_t min_packet_mask_size =
406       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
407 
408   EXPECT_EQ(kFlexfecPacketMaskSizes[1], min_packet_mask_size);
409   EXPECT_EQ(kFlexfecHeaderSizes[1], writer.FecHeaderSize(min_packet_mask_size));
410 }
411 
TEST(FlexfecHeaderWriterTest,ContractsLongUlpfecPacketMaskWithBit46ClearBit47Clear)412 TEST(FlexfecHeaderWriterTest,
413      ContractsLongUlpfecPacketMaskWithBit46ClearBit47Clear) {
414   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
415   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
416   ClearBit(46, packet_mask.get());
417   ClearBit(47, packet_mask.get());
418 
419   FlexfecHeaderWriter writer;
420   size_t min_packet_mask_size =
421       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
422 
423   EXPECT_EQ(kFlexfecPacketMaskSizes[1], min_packet_mask_size);
424   EXPECT_EQ(kFlexfecHeaderSizes[1], writer.FecHeaderSize(min_packet_mask_size));
425 }
426 
TEST(FlexfecHeaderWriterTest,ExpandsLongUlpfecPacketMaskWithBit46SetBit47Clear)427 TEST(FlexfecHeaderWriterTest,
428      ExpandsLongUlpfecPacketMaskWithBit46SetBit47Clear) {
429   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
430   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
431   SetBit(46, packet_mask.get());
432   ClearBit(47, packet_mask.get());
433 
434   FlexfecHeaderWriter writer;
435   size_t min_packet_mask_size =
436       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
437 
438   EXPECT_EQ(kFlexfecPacketMaskSizes[2], min_packet_mask_size);
439   EXPECT_EQ(kFlexfecHeaderSizes[2], writer.FecHeaderSize(min_packet_mask_size));
440 }
441 
TEST(FlexfecHeaderWriterTest,ExpandsLongUlpfecPacketMaskWithBit46ClearBit47Set)442 TEST(FlexfecHeaderWriterTest,
443      ExpandsLongUlpfecPacketMaskWithBit46ClearBit47Set) {
444   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
445   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
446   ClearBit(46, packet_mask.get());
447   SetBit(47, packet_mask.get());
448 
449   FlexfecHeaderWriter writer;
450   size_t min_packet_mask_size =
451       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
452 
453   EXPECT_EQ(kFlexfecPacketMaskSizes[2], min_packet_mask_size);
454   EXPECT_EQ(kFlexfecHeaderSizes[2], writer.FecHeaderSize(min_packet_mask_size));
455 }
456 
TEST(FlexfecHeaderWriterTest,ExpandsLongUlpfecPacketMaskWithBit46SetBit47Set)457 TEST(FlexfecHeaderWriterTest, ExpandsLongUlpfecPacketMaskWithBit46SetBit47Set) {
458   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
459   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
460   SetBit(46, packet_mask.get());
461   SetBit(47, packet_mask.get());
462 
463   FlexfecHeaderWriter writer;
464   size_t min_packet_mask_size =
465       writer.MinPacketMaskSize(packet_mask.get(), packet_mask_size);
466 
467   EXPECT_EQ(kFlexfecPacketMaskSizes[2], min_packet_mask_size);
468   EXPECT_EQ(kFlexfecHeaderSizes[2], writer.FecHeaderSize(min_packet_mask_size));
469 }
470 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadSmallUlpfecPacketHeaderWithMaskBit15Clear)471 TEST(FlexfecHeaderReaderWriterTest,
472      WriteAndReadSmallUlpfecPacketHeaderWithMaskBit15Clear) {
473   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
474   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
475   ClearBit(15, packet_mask.get());
476 
477   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
478   auto read_packet = ReadHeader(*written_packet);
479 
480   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[0], packet_mask.get(),
481                               kFlexfecPacketMaskSizes[0], *written_packet,
482                               *read_packet);
483 }
484 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadSmallUlpfecPacketHeaderWithMaskBit15Set)485 TEST(FlexfecHeaderReaderWriterTest,
486      WriteAndReadSmallUlpfecPacketHeaderWithMaskBit15Set) {
487   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitClear;
488   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
489   SetBit(15, packet_mask.get());
490 
491   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
492   auto read_packet = ReadHeader(*written_packet);
493 
494   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[1], packet_mask.get(),
495                               kFlexfecPacketMaskSizes[1], *written_packet,
496                               *read_packet);
497 }
498 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadLargeUlpfecPacketHeaderWithMaskBits46And47Clear)499 TEST(FlexfecHeaderReaderWriterTest,
500      WriteAndReadLargeUlpfecPacketHeaderWithMaskBits46And47Clear) {
501   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
502   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
503   ClearBit(46, packet_mask.get());
504   ClearBit(47, packet_mask.get());
505 
506   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
507   auto read_packet = ReadHeader(*written_packet);
508 
509   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[1], packet_mask.get(),
510                               kFlexfecPacketMaskSizes[1], *written_packet,
511                               *read_packet);
512 }
513 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadLargeUlpfecPacketHeaderWithMaskBit46SetBit47Clear)514 TEST(FlexfecHeaderReaderWriterTest,
515      WriteAndReadLargeUlpfecPacketHeaderWithMaskBit46SetBit47Clear) {
516   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
517   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
518   SetBit(46, packet_mask.get());
519   ClearBit(47, packet_mask.get());
520 
521   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
522   auto read_packet = ReadHeader(*written_packet);
523 
524   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[2], packet_mask.get(),
525                               kFlexfecPacketMaskSizes[2], *written_packet,
526                               *read_packet);
527 }
528 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadLargeUlpfecPacketHeaderMaskWithBit46ClearBit47Set)529 TEST(FlexfecHeaderReaderWriterTest,
530      WriteAndReadLargeUlpfecPacketHeaderMaskWithBit46ClearBit47Set) {
531   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
532   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
533   ClearBit(46, packet_mask.get());
534   SetBit(47, packet_mask.get());
535 
536   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
537   auto read_packet = ReadHeader(*written_packet);
538 
539   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[2], packet_mask.get(),
540                               kFlexfecPacketMaskSizes[2], *written_packet,
541                               *read_packet);
542 }
543 
TEST(FlexfecHeaderReaderWriterTest,WriteAndReadLargeUlpfecPacketHeaderWithMaskBits46And47Set)544 TEST(FlexfecHeaderReaderWriterTest,
545      WriteAndReadLargeUlpfecPacketHeaderWithMaskBits46And47Set) {
546   const size_t packet_mask_size = kUlpfecPacketMaskSizeLBitSet;
547   auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
548   SetBit(46, packet_mask.get());
549   SetBit(47, packet_mask.get());
550 
551   auto written_packet = WriteHeader(packet_mask.get(), packet_mask_size);
552   auto read_packet = ReadHeader(*written_packet);
553 
554   VerifyWrittenAndReadHeaders(kFlexfecHeaderSizes[2], packet_mask.get(),
555                               kFlexfecPacketMaskSizes[2], *written_packet,
556                               *read_packet);
557 }
558 
559 }  // namespace webrtc
560