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