1 /*
2 * Copyright (c) 2014 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/rtp_format_h264.h"
12
13 #include <memory>
14 #include <vector>
15
16 #include "absl/algorithm/container.h"
17 #include "api/array_view.h"
18 #include "common_video/h264/h264_common.h"
19 #include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
20 #include "modules/rtp_rtcp/source/byte_io.h"
21 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
22 #include "test/gmock.h"
23 #include "test/gtest.h"
24
25 namespace webrtc {
26 namespace {
27
28 using ::testing::Each;
29 using ::testing::ElementsAre;
30 using ::testing::ElementsAreArray;
31 using ::testing::Eq;
32 using ::testing::IsEmpty;
33 using ::testing::SizeIs;
34
35 constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;
36 constexpr size_t kMaxPayloadSize = 1200;
37 constexpr size_t kLengthFieldLength = 2;
38 constexpr RtpPacketizer::PayloadSizeLimits kNoLimits;
39
40 enum Nalu {
41 kSlice = 1,
42 kIdr = 5,
43 kSei = 6,
44 kSps = 7,
45 kPps = 8,
46 kStapA = 24,
47 kFuA = 28
48 };
49
50 static const size_t kNalHeaderSize = 1;
51 static const size_t kFuAHeaderSize = 2;
52
53 // Bit masks for FU (A and B) indicators.
54 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F };
55
56 // Bit masks for FU (A and B) headers.
57 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 };
58
59 // Creates Buffer that looks like nal unit of given size.
GenerateNalUnit(size_t size)60 rtc::Buffer GenerateNalUnit(size_t size) {
61 RTC_CHECK_GT(size, 0);
62 rtc::Buffer buffer(size);
63 // Set some valid header.
64 buffer[0] = kSlice;
65 for (size_t i = 1; i < size; ++i) {
66 buffer[i] = static_cast<uint8_t>(i);
67 }
68 // Last byte shouldn't be 0, or it may be counted as part of next 4-byte start
69 // sequence.
70 buffer[size - 1] |= 0x10;
71 return buffer;
72 }
73
74 // Create frame consisting of nalus of given size.
CreateFrame(std::initializer_list<size_t> nalu_sizes)75 rtc::Buffer CreateFrame(std::initializer_list<size_t> nalu_sizes) {
76 static constexpr int kStartCodeSize = 3;
77 rtc::Buffer frame(absl::c_accumulate(nalu_sizes, 0) +
78 kStartCodeSize * nalu_sizes.size());
79 size_t offset = 0;
80 for (size_t nalu_size : nalu_sizes) {
81 EXPECT_GE(nalu_size, 1u);
82 // Insert nalu start code
83 frame[offset] = 0;
84 frame[offset + 1] = 0;
85 frame[offset + 2] = 1;
86 // Set some valid header.
87 frame[offset + 3] = 1;
88 // Fill payload avoiding accidental start codes
89 if (nalu_size > 1) {
90 memset(frame.data() + offset + 4, 0x3f, nalu_size - 1);
91 }
92 offset += (kStartCodeSize + nalu_size);
93 }
94 return frame;
95 }
96
97 // Create frame consisting of given nalus.
CreateFrame(rtc::ArrayView<const rtc::Buffer> nalus)98 rtc::Buffer CreateFrame(rtc::ArrayView<const rtc::Buffer> nalus) {
99 static constexpr int kStartCodeSize = 3;
100 int frame_size = 0;
101 for (const rtc::Buffer& nalu : nalus) {
102 frame_size += (kStartCodeSize + nalu.size());
103 }
104 rtc::Buffer frame(frame_size);
105 size_t offset = 0;
106 for (const rtc::Buffer& nalu : nalus) {
107 // Insert nalu start code
108 frame[offset] = 0;
109 frame[offset + 1] = 0;
110 frame[offset + 2] = 1;
111 // Copy the nalu unit.
112 memcpy(frame.data() + offset + 3, nalu.data(), nalu.size());
113 offset += (kStartCodeSize + nalu.size());
114 }
115 return frame;
116 }
117
FetchAllPackets(RtpPacketizerH264 * packetizer)118 std::vector<RtpPacketToSend> FetchAllPackets(RtpPacketizerH264* packetizer) {
119 std::vector<RtpPacketToSend> result;
120 size_t num_packets = packetizer->NumPackets();
121 result.reserve(num_packets);
122 RtpPacketToSend packet(kNoExtensions);
123 while (packetizer->NextPacket(&packet)) {
124 result.push_back(packet);
125 }
126 EXPECT_THAT(result, SizeIs(num_packets));
127 return result;
128 }
129
130 // Tests that should work with both packetization mode 0 and
131 // packetization mode 1.
132 class RtpPacketizerH264ModeTest
133 : public ::testing::TestWithParam<H264PacketizationMode> {};
134
TEST_P(RtpPacketizerH264ModeTest,SingleNalu)135 TEST_P(RtpPacketizerH264ModeTest, SingleNalu) {
136 const uint8_t frame[] = {0, 0, 1, kIdr, 0xFF};
137
138 RtpPacketizerH264 packetizer(frame, kNoLimits, GetParam());
139 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
140
141 ASSERT_THAT(packets, SizeIs(1));
142 EXPECT_THAT(packets[0].payload(), ElementsAre(kIdr, 0xFF));
143 }
144
TEST_P(RtpPacketizerH264ModeTest,SingleNaluTwoPackets)145 TEST_P(RtpPacketizerH264ModeTest, SingleNaluTwoPackets) {
146 RtpPacketizer::PayloadSizeLimits limits;
147 limits.max_payload_len = kMaxPayloadSize;
148 rtc::Buffer nalus[] = {GenerateNalUnit(kMaxPayloadSize),
149 GenerateNalUnit(100)};
150 rtc::Buffer frame = CreateFrame(nalus);
151
152 RtpPacketizerH264 packetizer(frame, limits, GetParam());
153 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
154
155 ASSERT_THAT(packets, SizeIs(2));
156 EXPECT_THAT(packets[0].payload(), ElementsAreArray(nalus[0]));
157 EXPECT_THAT(packets[1].payload(), ElementsAreArray(nalus[1]));
158 }
159
TEST_P(RtpPacketizerH264ModeTest,SingleNaluFirstPacketReductionAppliesOnlyToFirstFragment)160 TEST_P(RtpPacketizerH264ModeTest,
161 SingleNaluFirstPacketReductionAppliesOnlyToFirstFragment) {
162 RtpPacketizer::PayloadSizeLimits limits;
163 limits.max_payload_len = 200;
164 limits.first_packet_reduction_len = 5;
165 rtc::Buffer nalus[] = {GenerateNalUnit(/*size=*/195),
166 GenerateNalUnit(/*size=*/200),
167 GenerateNalUnit(/*size=*/200)};
168 rtc::Buffer frame = CreateFrame(nalus);
169
170 RtpPacketizerH264 packetizer(frame, limits, GetParam());
171 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
172
173 ASSERT_THAT(packets, SizeIs(3));
174 EXPECT_THAT(packets[0].payload(), ElementsAreArray(nalus[0]));
175 EXPECT_THAT(packets[1].payload(), ElementsAreArray(nalus[1]));
176 EXPECT_THAT(packets[2].payload(), ElementsAreArray(nalus[2]));
177 }
178
TEST_P(RtpPacketizerH264ModeTest,SingleNaluLastPacketReductionAppliesOnlyToLastFragment)179 TEST_P(RtpPacketizerH264ModeTest,
180 SingleNaluLastPacketReductionAppliesOnlyToLastFragment) {
181 RtpPacketizer::PayloadSizeLimits limits;
182 limits.max_payload_len = 200;
183 limits.last_packet_reduction_len = 5;
184 rtc::Buffer nalus[] = {GenerateNalUnit(/*size=*/200),
185 GenerateNalUnit(/*size=*/200),
186 GenerateNalUnit(/*size=*/195)};
187 rtc::Buffer frame = CreateFrame(nalus);
188
189 RtpPacketizerH264 packetizer(frame, limits, GetParam());
190 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
191
192 ASSERT_THAT(packets, SizeIs(3));
193 EXPECT_THAT(packets[0].payload(), ElementsAreArray(nalus[0]));
194 EXPECT_THAT(packets[1].payload(), ElementsAreArray(nalus[1]));
195 EXPECT_THAT(packets[2].payload(), ElementsAreArray(nalus[2]));
196 }
197
TEST_P(RtpPacketizerH264ModeTest,SingleNaluFirstAndLastPacketReductionSumsForSinglePacket)198 TEST_P(RtpPacketizerH264ModeTest,
199 SingleNaluFirstAndLastPacketReductionSumsForSinglePacket) {
200 RtpPacketizer::PayloadSizeLimits limits;
201 limits.max_payload_len = 200;
202 limits.first_packet_reduction_len = 20;
203 limits.last_packet_reduction_len = 30;
204 rtc::Buffer frame = CreateFrame({150});
205
206 RtpPacketizerH264 packetizer(frame, limits, GetParam());
207 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
208
209 EXPECT_THAT(packets, SizeIs(1));
210 }
211
212 INSTANTIATE_TEST_SUITE_P(
213 PacketMode,
214 RtpPacketizerH264ModeTest,
215 ::testing::Values(H264PacketizationMode::SingleNalUnit,
216 H264PacketizationMode::NonInterleaved));
217
218 // Aggregation tests.
TEST(RtpPacketizerH264Test,StapA)219 TEST(RtpPacketizerH264Test, StapA) {
220 rtc::Buffer nalus[] = {GenerateNalUnit(/*size=*/2),
221 GenerateNalUnit(/*size=*/2),
222 GenerateNalUnit(/*size=*/0x123)};
223 rtc::Buffer frame = CreateFrame(nalus);
224
225 RtpPacketizerH264 packetizer(frame, kNoLimits,
226 H264PacketizationMode::NonInterleaved);
227 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
228
229 ASSERT_THAT(packets, SizeIs(1));
230 auto payload = packets[0].payload();
231 EXPECT_EQ(payload.size(),
232 kNalHeaderSize + 3 * kLengthFieldLength + 2 + 2 + 0x123);
233
234 EXPECT_EQ(payload[0], kStapA);
235 payload = payload.subview(kNalHeaderSize);
236 // 1st fragment.
237 EXPECT_THAT(payload.subview(0, kLengthFieldLength),
238 ElementsAre(0, 2)); // Size.
239 EXPECT_THAT(payload.subview(kLengthFieldLength, 2),
240 ElementsAreArray(nalus[0]));
241 payload = payload.subview(kLengthFieldLength + 2);
242 // 2nd fragment.
243 EXPECT_THAT(payload.subview(0, kLengthFieldLength),
244 ElementsAre(0, 2)); // Size.
245 EXPECT_THAT(payload.subview(kLengthFieldLength, 2),
246 ElementsAreArray(nalus[1]));
247 payload = payload.subview(kLengthFieldLength + 2);
248 // 3rd fragment.
249 EXPECT_THAT(payload.subview(0, kLengthFieldLength),
250 ElementsAre(0x1, 0x23)); // Size.
251 EXPECT_THAT(payload.subview(kLengthFieldLength), ElementsAreArray(nalus[2]));
252 }
253
TEST(RtpPacketizerH264Test,SingleNalUnitModeHasNoStapA)254 TEST(RtpPacketizerH264Test, SingleNalUnitModeHasNoStapA) {
255 // This is the same setup as for the StapA test.
256 rtc::Buffer frame = CreateFrame({2, 2, 0x123});
257
258 RtpPacketizerH264 packetizer(frame, kNoLimits,
259 H264PacketizationMode::SingleNalUnit);
260 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
261
262 // The three fragments should be returned as three packets.
263 ASSERT_THAT(packets, SizeIs(3));
264 EXPECT_EQ(packets[0].payload_size(), 2u);
265 EXPECT_EQ(packets[1].payload_size(), 2u);
266 EXPECT_EQ(packets[2].payload_size(), 0x123u);
267 }
268
TEST(RtpPacketizerH264Test,StapARespectsFirstPacketReduction)269 TEST(RtpPacketizerH264Test, StapARespectsFirstPacketReduction) {
270 RtpPacketizer::PayloadSizeLimits limits;
271 limits.max_payload_len = 1000;
272 limits.first_packet_reduction_len = 100;
273 const size_t kFirstFragmentSize =
274 limits.max_payload_len - limits.first_packet_reduction_len;
275 rtc::Buffer nalus[] = {GenerateNalUnit(/*size=*/kFirstFragmentSize),
276 GenerateNalUnit(/*size=*/2),
277 GenerateNalUnit(/*size=*/2)};
278 rtc::Buffer frame = CreateFrame(nalus);
279
280 RtpPacketizerH264 packetizer(frame, limits,
281 H264PacketizationMode::NonInterleaved);
282 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
283
284 ASSERT_THAT(packets, SizeIs(2));
285 // Expect 1st packet is single nalu.
286 EXPECT_THAT(packets[0].payload(), ElementsAreArray(nalus[0]));
287 // Expect 2nd packet is aggregate of last two fragments.
288 EXPECT_THAT(packets[1].payload(),
289 ElementsAre(kStapA, //
290 0, 2, nalus[1][0], nalus[1][1], //
291 0, 2, nalus[2][0], nalus[2][1]));
292 }
293
TEST(RtpPacketizerH264Test,StapARespectsLastPacketReduction)294 TEST(RtpPacketizerH264Test, StapARespectsLastPacketReduction) {
295 RtpPacketizer::PayloadSizeLimits limits;
296 limits.max_payload_len = 1000;
297 limits.last_packet_reduction_len = 100;
298 const size_t kLastFragmentSize =
299 limits.max_payload_len - limits.last_packet_reduction_len;
300 rtc::Buffer nalus[] = {GenerateNalUnit(/*size=*/2),
301 GenerateNalUnit(/*size=*/2),
302 GenerateNalUnit(/*size=*/kLastFragmentSize)};
303 rtc::Buffer frame = CreateFrame(nalus);
304
305 RtpPacketizerH264 packetizer(frame, limits,
306 H264PacketizationMode::NonInterleaved);
307 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
308
309 ASSERT_THAT(packets, SizeIs(2));
310 // Expect 1st packet is aggregate of 1st two fragments.
311 EXPECT_THAT(packets[0].payload(),
312 ElementsAre(kStapA, //
313 0, 2, nalus[0][0], nalus[0][1], //
314 0, 2, nalus[1][0], nalus[1][1]));
315 // Expect 2nd packet is single nalu.
316 EXPECT_THAT(packets[1].payload(), ElementsAreArray(nalus[2]));
317 }
318
TEST(RtpPacketizerH264Test,TooSmallForStapAHeaders)319 TEST(RtpPacketizerH264Test, TooSmallForStapAHeaders) {
320 RtpPacketizer::PayloadSizeLimits limits;
321 limits.max_payload_len = 1000;
322 const size_t kLastFragmentSize =
323 limits.max_payload_len - 3 * kLengthFieldLength - 4;
324 rtc::Buffer nalus[] = {GenerateNalUnit(/*size=*/2),
325 GenerateNalUnit(/*size=*/2),
326 GenerateNalUnit(/*size=*/kLastFragmentSize)};
327 rtc::Buffer frame = CreateFrame(nalus);
328
329 RtpPacketizerH264 packetizer(frame, limits,
330 H264PacketizationMode::NonInterleaved);
331 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
332
333 ASSERT_THAT(packets, SizeIs(2));
334 // Expect 1st packet is aggregate of 1st two fragments.
335 EXPECT_THAT(packets[0].payload(),
336 ElementsAre(kStapA, //
337 0, 2, nalus[0][0], nalus[0][1], //
338 0, 2, nalus[1][0], nalus[1][1]));
339 // Expect 2nd packet is single nalu.
340 EXPECT_THAT(packets[1].payload(), ElementsAreArray(nalus[2]));
341 }
342
343 // Fragmentation + aggregation.
TEST(RtpPacketizerH264Test,MixedStapAFUA)344 TEST(RtpPacketizerH264Test, MixedStapAFUA) {
345 RtpPacketizer::PayloadSizeLimits limits;
346 limits.max_payload_len = 100;
347 const size_t kFuaPayloadSize = 70;
348 const size_t kFuaNaluSize = kNalHeaderSize + 2 * kFuaPayloadSize;
349 const size_t kStapANaluSize = 20;
350 rtc::Buffer nalus[] = {GenerateNalUnit(kFuaNaluSize),
351 GenerateNalUnit(kStapANaluSize),
352 GenerateNalUnit(kStapANaluSize)};
353 rtc::Buffer frame = CreateFrame(nalus);
354
355 RtpPacketizerH264 packetizer(frame, limits,
356 H264PacketizationMode::NonInterleaved);
357 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
358
359 ASSERT_THAT(packets, SizeIs(3));
360 // First expect two FU-A packets.
361 EXPECT_THAT(packets[0].payload().subview(0, kFuAHeaderSize),
362 ElementsAre(kFuA, FuDefs::kSBit | nalus[0][0]));
363 EXPECT_THAT(
364 packets[0].payload().subview(kFuAHeaderSize),
365 ElementsAreArray(nalus[0].data() + kNalHeaderSize, kFuaPayloadSize));
366
367 EXPECT_THAT(packets[1].payload().subview(0, kFuAHeaderSize),
368 ElementsAre(kFuA, FuDefs::kEBit | nalus[0][0]));
369 EXPECT_THAT(
370 packets[1].payload().subview(kFuAHeaderSize),
371 ElementsAreArray(nalus[0].data() + kNalHeaderSize + kFuaPayloadSize,
372 kFuaPayloadSize));
373
374 // Then expect one STAP-A packet with two nal units.
375 EXPECT_THAT(packets[2].payload()[0], kStapA);
376 auto payload = packets[2].payload().subview(kNalHeaderSize);
377 EXPECT_THAT(payload.subview(0, kLengthFieldLength),
378 ElementsAre(0, kStapANaluSize));
379 EXPECT_THAT(payload.subview(kLengthFieldLength, kStapANaluSize),
380 ElementsAreArray(nalus[1]));
381 payload = payload.subview(kLengthFieldLength + kStapANaluSize);
382 EXPECT_THAT(payload.subview(0, kLengthFieldLength),
383 ElementsAre(0, kStapANaluSize));
384 EXPECT_THAT(payload.subview(kLengthFieldLength), ElementsAreArray(nalus[2]));
385 }
386
TEST(RtpPacketizerH264Test,LastFragmentFitsInSingleButNotLastPacket)387 TEST(RtpPacketizerH264Test, LastFragmentFitsInSingleButNotLastPacket) {
388 RtpPacketizer::PayloadSizeLimits limits;
389 limits.max_payload_len = 1178;
390 limits.first_packet_reduction_len = 0;
391 limits.last_packet_reduction_len = 20;
392 limits.single_packet_reduction_len = 20;
393 // Actual sizes, which triggered this bug.
394 rtc::Buffer frame = CreateFrame({20, 8, 18, 1161});
395
396 RtpPacketizerH264 packetizer(frame, limits,
397 H264PacketizationMode::NonInterleaved);
398 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
399
400 // Last packet has to be of correct size.
401 // Incorrect implementation might miss this constraint and not split the last
402 // fragment in two packets.
403 EXPECT_LE(static_cast<int>(packets.back().payload_size()),
404 limits.max_payload_len - limits.last_packet_reduction_len);
405 }
406
407 // Splits frame with payload size |frame_payload_size| without fragmentation,
408 // Returns sizes of the payloads excluding fua headers.
TestFua(size_t frame_payload_size,const RtpPacketizer::PayloadSizeLimits & limits)409 std::vector<int> TestFua(size_t frame_payload_size,
410 const RtpPacketizer::PayloadSizeLimits& limits) {
411 rtc::Buffer nalu[] = {GenerateNalUnit(kNalHeaderSize + frame_payload_size)};
412 rtc::Buffer frame = CreateFrame(nalu);
413
414 RtpPacketizerH264 packetizer(frame, limits,
415 H264PacketizationMode::NonInterleaved);
416 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
417
418 EXPECT_GE(packets.size(), 2u); // Single packet indicates it is not FuA.
419 std::vector<uint16_t> fua_header;
420 std::vector<int> payload_sizes;
421
422 for (const RtpPacketToSend& packet : packets) {
423 auto payload = packet.payload();
424 EXPECT_GT(payload.size(), kFuAHeaderSize);
425 fua_header.push_back((payload[0] << 8) | payload[1]);
426 payload_sizes.push_back(payload.size() - kFuAHeaderSize);
427 }
428
429 EXPECT_TRUE(fua_header.front() & FuDefs::kSBit);
430 EXPECT_TRUE(fua_header.back() & FuDefs::kEBit);
431 // Clear S and E bits before testing all are duplicating same original header.
432 fua_header.front() &= ~FuDefs::kSBit;
433 fua_header.back() &= ~FuDefs::kEBit;
434 EXPECT_THAT(fua_header, Each(Eq((kFuA << 8) | nalu[0][0])));
435
436 return payload_sizes;
437 }
438
439 // Fragmentation tests.
TEST(RtpPacketizerH264Test,FUAOddSize)440 TEST(RtpPacketizerH264Test, FUAOddSize) {
441 RtpPacketizer::PayloadSizeLimits limits;
442 limits.max_payload_len = 1200;
443 EXPECT_THAT(TestFua(1200, limits), ElementsAre(600, 600));
444 }
445
TEST(RtpPacketizerH264Test,FUAWithFirstPacketReduction)446 TEST(RtpPacketizerH264Test, FUAWithFirstPacketReduction) {
447 RtpPacketizer::PayloadSizeLimits limits;
448 limits.max_payload_len = 1200;
449 limits.first_packet_reduction_len = 4;
450 limits.single_packet_reduction_len = 4;
451 EXPECT_THAT(TestFua(1198, limits), ElementsAre(597, 601));
452 }
453
TEST(RtpPacketizerH264Test,FUAWithLastPacketReduction)454 TEST(RtpPacketizerH264Test, FUAWithLastPacketReduction) {
455 RtpPacketizer::PayloadSizeLimits limits;
456 limits.max_payload_len = 1200;
457 limits.last_packet_reduction_len = 4;
458 limits.single_packet_reduction_len = 4;
459 EXPECT_THAT(TestFua(1198, limits), ElementsAre(601, 597));
460 }
461
TEST(RtpPacketizerH264Test,FUAWithSinglePacketReduction)462 TEST(RtpPacketizerH264Test, FUAWithSinglePacketReduction) {
463 RtpPacketizer::PayloadSizeLimits limits;
464 limits.max_payload_len = 1199;
465 limits.single_packet_reduction_len = 200;
466 EXPECT_THAT(TestFua(1000, limits), ElementsAre(500, 500));
467 }
468
TEST(RtpPacketizerH264Test,FUAEvenSize)469 TEST(RtpPacketizerH264Test, FUAEvenSize) {
470 RtpPacketizer::PayloadSizeLimits limits;
471 limits.max_payload_len = 1200;
472 EXPECT_THAT(TestFua(1201, limits), ElementsAre(600, 601));
473 }
474
TEST(RtpPacketizerH264Test,FUARounding)475 TEST(RtpPacketizerH264Test, FUARounding) {
476 RtpPacketizer::PayloadSizeLimits limits;
477 limits.max_payload_len = 1448;
478 EXPECT_THAT(TestFua(10123, limits),
479 ElementsAre(1265, 1265, 1265, 1265, 1265, 1266, 1266, 1266));
480 }
481
TEST(RtpPacketizerH264Test,FUABig)482 TEST(RtpPacketizerH264Test, FUABig) {
483 RtpPacketizer::PayloadSizeLimits limits;
484 limits.max_payload_len = 1200;
485 // Generate 10 full sized packets, leave room for FU-A headers.
486 EXPECT_THAT(
487 TestFua(10 * (1200 - kFuAHeaderSize), limits),
488 ElementsAre(1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198, 1198));
489 }
490
TEST(RtpPacketizerH264Test,RejectsOverlongDataInPacketizationMode0)491 TEST(RtpPacketizerH264Test, RejectsOverlongDataInPacketizationMode0) {
492 RtpPacketizer::PayloadSizeLimits limits;
493 rtc::Buffer frame = CreateFrame({kMaxPayloadSize + 1});
494
495 RtpPacketizerH264 packetizer(frame, limits,
496 H264PacketizationMode::SingleNalUnit);
497 std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
498
499 EXPECT_THAT(packets, IsEmpty());
500 }
501 } // namespace
502 } // namespace webrtc
503