1 /*
2 * Copyright (c) 2021 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 #include "modules/video_coding/h264_packet_buffer.h"
11
12 #include <cstring>
13 #include <limits>
14 #include <ostream>
15 #include <string>
16 #include <utility>
17
18 #include "api/array_view.h"
19 #include "api/video/render_resolution.h"
20 #include "common_video/h264/h264_common.h"
21 #include "rtc_base/system/unused.h"
22 #include "test/gmock.h"
23 #include "test/gtest.h"
24
25 namespace webrtc {
26 namespace {
27
28 using ::testing::ElementsAreArray;
29 using ::testing::Eq;
30 using ::testing::IsEmpty;
31 using ::testing::SizeIs;
32
33 using H264::NaluType::kAud;
34 using H264::NaluType::kFuA;
35 using H264::NaluType::kIdr;
36 using H264::NaluType::kPps;
37 using H264::NaluType::kSlice;
38 using H264::NaluType::kSps;
39 using H264::NaluType::kStapA;
40
41 constexpr int kBufferSize = 2048;
42
StartCode()43 std::vector<uint8_t> StartCode() {
44 return {0, 0, 0, 1};
45 }
46
MakeNaluInfo(uint8_t type)47 NaluInfo MakeNaluInfo(uint8_t type) {
48 NaluInfo res;
49 res.type = type;
50 res.sps_id = -1;
51 res.pps_id = -1;
52 return res;
53 }
54
55 class Packet {
56 public:
57 explicit Packet(H264PacketizationTypes type);
58
59 Packet& Idr(std::vector<uint8_t> payload = {9, 9, 9});
60 Packet& Slice(std::vector<uint8_t> payload = {9, 9, 9});
61 Packet& Sps(std::vector<uint8_t> payload = {9, 9, 9});
62 Packet& SpsWithResolution(RenderResolution resolution,
63 std::vector<uint8_t> payload = {9, 9, 9});
64 Packet& Pps(std::vector<uint8_t> payload = {9, 9, 9});
65 Packet& Aud();
66 Packet& Marker();
67 Packet& AsFirstFragment();
68 Packet& Time(uint32_t rtp_timestamp);
69 Packet& SeqNum(uint16_t rtp_seq_num);
70
71 std::unique_ptr<H264PacketBuffer::Packet> Build();
72
73 private:
74 rtc::CopyOnWriteBuffer BuildFuaPayload() const;
75 rtc::CopyOnWriteBuffer BuildSingleNaluPayload() const;
76 rtc::CopyOnWriteBuffer BuildStapAPayload() const;
77
H264Header()78 RTPVideoHeaderH264& H264Header() {
79 return absl::get<RTPVideoHeaderH264>(video_header_.video_type_header);
80 }
H264Header() const81 const RTPVideoHeaderH264& H264Header() const {
82 return absl::get<RTPVideoHeaderH264>(video_header_.video_type_header);
83 }
84
85 H264PacketizationTypes type_;
86 RTPVideoHeader video_header_;
87 bool first_fragment_ = false;
88 bool marker_bit_ = false;
89 uint32_t rtp_timestamp_ = 0;
90 uint16_t rtp_seq_num_ = 0;
91 std::vector<std::vector<uint8_t>> nalu_payloads_;
92 };
93
Packet(H264PacketizationTypes type)94 Packet::Packet(H264PacketizationTypes type) : type_(type) {
95 video_header_.video_type_header.emplace<RTPVideoHeaderH264>();
96 }
97
Idr(std::vector<uint8_t> payload)98 Packet& Packet::Idr(std::vector<uint8_t> payload) {
99 auto& h264_header = H264Header();
100 h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kIdr);
101 nalu_payloads_.push_back(std::move(payload));
102 return *this;
103 }
104
Slice(std::vector<uint8_t> payload)105 Packet& Packet::Slice(std::vector<uint8_t> payload) {
106 auto& h264_header = H264Header();
107 h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSlice);
108 nalu_payloads_.push_back(std::move(payload));
109 return *this;
110 }
111
Sps(std::vector<uint8_t> payload)112 Packet& Packet::Sps(std::vector<uint8_t> payload) {
113 auto& h264_header = H264Header();
114 h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps);
115 nalu_payloads_.push_back(std::move(payload));
116 return *this;
117 }
118
SpsWithResolution(RenderResolution resolution,std::vector<uint8_t> payload)119 Packet& Packet::SpsWithResolution(RenderResolution resolution,
120 std::vector<uint8_t> payload) {
121 auto& h264_header = H264Header();
122 h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps);
123 video_header_.width = resolution.Width();
124 video_header_.height = resolution.Height();
125 nalu_payloads_.push_back(std::move(payload));
126 return *this;
127 }
128
Pps(std::vector<uint8_t> payload)129 Packet& Packet::Pps(std::vector<uint8_t> payload) {
130 auto& h264_header = H264Header();
131 h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kPps);
132 nalu_payloads_.push_back(std::move(payload));
133 return *this;
134 }
135
Aud()136 Packet& Packet::Aud() {
137 auto& h264_header = H264Header();
138 h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kAud);
139 nalu_payloads_.push_back({});
140 return *this;
141 }
142
Marker()143 Packet& Packet::Marker() {
144 marker_bit_ = true;
145 return *this;
146 }
147
AsFirstFragment()148 Packet& Packet::AsFirstFragment() {
149 first_fragment_ = true;
150 return *this;
151 }
152
Time(uint32_t rtp_timestamp)153 Packet& Packet::Time(uint32_t rtp_timestamp) {
154 rtp_timestamp_ = rtp_timestamp;
155 return *this;
156 }
157
SeqNum(uint16_t rtp_seq_num)158 Packet& Packet::SeqNum(uint16_t rtp_seq_num) {
159 rtp_seq_num_ = rtp_seq_num;
160 return *this;
161 }
162
Build()163 std::unique_ptr<H264PacketBuffer::Packet> Packet::Build() {
164 auto res = std::make_unique<H264PacketBuffer::Packet>();
165
166 auto& h264_header = H264Header();
167 switch (type_) {
168 case kH264FuA: {
169 RTC_CHECK_EQ(h264_header.nalus_length, 1);
170 res->video_payload = BuildFuaPayload();
171 break;
172 }
173 case kH264SingleNalu: {
174 RTC_CHECK_EQ(h264_header.nalus_length, 1);
175 res->video_payload = BuildSingleNaluPayload();
176 break;
177 }
178 case kH264StapA: {
179 RTC_CHECK_GT(h264_header.nalus_length, 1);
180 RTC_CHECK_LE(h264_header.nalus_length, kMaxNalusPerPacket);
181 res->video_payload = BuildStapAPayload();
182 break;
183 }
184 }
185
186 if (type_ == kH264FuA && !first_fragment_) {
187 h264_header.nalus_length = 0;
188 }
189
190 h264_header.packetization_type = type_;
191 res->marker_bit = marker_bit_;
192 res->video_header = video_header_;
193 res->timestamp = rtp_timestamp_;
194 res->seq_num = rtp_seq_num_;
195 res->video_header.codec = kVideoCodecH264;
196
197 return res;
198 }
199
BuildFuaPayload() const200 rtc::CopyOnWriteBuffer Packet::BuildFuaPayload() const {
201 return rtc::CopyOnWriteBuffer(nalu_payloads_[0]);
202 }
203
BuildSingleNaluPayload() const204 rtc::CopyOnWriteBuffer Packet::BuildSingleNaluPayload() const {
205 rtc::CopyOnWriteBuffer res;
206 auto& h264_header = H264Header();
207 res.AppendData(&h264_header.nalus[0].type, 1);
208 res.AppendData(nalu_payloads_[0]);
209 return res;
210 }
211
BuildStapAPayload() const212 rtc::CopyOnWriteBuffer Packet::BuildStapAPayload() const {
213 rtc::CopyOnWriteBuffer res;
214
215 const uint8_t indicator = H264::NaluType::kStapA;
216 res.AppendData(&indicator, 1);
217
218 auto& h264_header = H264Header();
219 for (size_t i = 0; i < h264_header.nalus_length; ++i) {
220 // The two first bytes indicates the nalu segment size.
221 uint8_t length_as_array[2] = {
222 0, static_cast<uint8_t>(nalu_payloads_[i].size() + 1)};
223 res.AppendData(length_as_array);
224
225 res.AppendData(&h264_header.nalus[i].type, 1);
226 res.AppendData(nalu_payloads_[i]);
227 }
228 return res;
229 }
230
PacketPayload(const std::unique_ptr<H264PacketBuffer::Packet> & packet)231 rtc::ArrayView<const uint8_t> PacketPayload(
232 const std::unique_ptr<H264PacketBuffer::Packet>& packet) {
233 return packet->video_payload;
234 }
235
FlatVector(const std::vector<std::vector<uint8_t>> & elems)236 std::vector<uint8_t> FlatVector(
237 const std::vector<std::vector<uint8_t>>& elems) {
238 std::vector<uint8_t> res;
239 for (const auto& elem : elems) {
240 res.insert(res.end(), elem.begin(), elem.end());
241 }
242 return res;
243 }
244
TEST(H264PacketBufferTest,IdrIsKeyframe)245 TEST(H264PacketBufferTest, IdrIsKeyframe) {
246 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/true);
247
248 EXPECT_THAT(
249 packet_buffer.InsertPacket(Packet(kH264SingleNalu).Idr().Marker().Build())
250 .packets,
251 SizeIs(1));
252 }
253
TEST(H264PacketBufferTest,IdrIsNotKeyframe)254 TEST(H264PacketBufferTest, IdrIsNotKeyframe) {
255 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
256
257 EXPECT_THAT(
258 packet_buffer.InsertPacket(Packet(kH264SingleNalu).Idr().Marker().Build())
259 .packets,
260 IsEmpty());
261 }
262
TEST(H264PacketBufferTest,IdrIsKeyframeFuaRequiresFirstFragmet)263 TEST(H264PacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) {
264 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/true);
265
266 // Not marked as the first fragment
267 EXPECT_THAT(
268 packet_buffer
269 .InsertPacket(Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())
270 .packets,
271 IsEmpty());
272
273 EXPECT_THAT(packet_buffer
274 .InsertPacket(
275 Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build())
276 .packets,
277 IsEmpty());
278
279 // Marked as first fragment
280 EXPECT_THAT(packet_buffer
281 .InsertPacket(Packet(kH264FuA)
282 .Idr()
283 .SeqNum(2)
284 .Time(1)
285 .AsFirstFragment()
286 .Build())
287 .packets,
288 IsEmpty());
289
290 EXPECT_THAT(packet_buffer
291 .InsertPacket(
292 Packet(kH264FuA).Idr().SeqNum(3).Time(1).Marker().Build())
293 .packets,
294 SizeIs(2));
295 }
296
TEST(H264PacketBufferTest,SpsPpsIdrIsKeyframeSingleNalus)297 TEST(H264PacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) {
298 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
299
300 RTC_UNUSED(packet_buffer.InsertPacket(
301 Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build()));
302 RTC_UNUSED(packet_buffer.InsertPacket(
303 Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build()));
304 EXPECT_THAT(
305 packet_buffer
306 .InsertPacket(
307 Packet(kH264SingleNalu).Idr().SeqNum(2).Time(0).Marker().Build())
308 .packets,
309 SizeIs(3));
310 }
311
TEST(H264PacketBufferTest,PpsIdrIsNotKeyframeSingleNalus)312 TEST(H264PacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) {
313 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
314
315 RTC_UNUSED(packet_buffer.InsertPacket(
316 Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build()));
317 EXPECT_THAT(
318 packet_buffer
319 .InsertPacket(
320 Packet(kH264SingleNalu).Idr().SeqNum(1).Time(0).Marker().Build())
321 .packets,
322 IsEmpty());
323 }
324
TEST(H264PacketBufferTest,SpsIdrIsNotKeyframeSingleNalus)325 TEST(H264PacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) {
326 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
327
328 RTC_UNUSED(packet_buffer.InsertPacket(
329 Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build()));
330 EXPECT_THAT(
331 packet_buffer
332 .InsertPacket(
333 Packet(kH264SingleNalu).Idr().SeqNum(1).Time(0).Marker().Build())
334 .packets,
335 IsEmpty());
336 }
337
TEST(H264PacketBufferTest,SpsPpsIdrIsKeyframeStapA)338 TEST(H264PacketBufferTest, SpsPpsIdrIsKeyframeStapA) {
339 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
340
341 EXPECT_THAT(packet_buffer
342 .InsertPacket(Packet(kH264StapA)
343 .Sps()
344 .Pps()
345 .Idr()
346 .SeqNum(0)
347 .Time(0)
348 .Marker()
349 .Build())
350 .packets,
351 SizeIs(1));
352 }
353
TEST(H264PacketBufferTest,PpsIdrIsNotKeyframeStapA)354 TEST(H264PacketBufferTest, PpsIdrIsNotKeyframeStapA) {
355 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
356
357 EXPECT_THAT(
358 packet_buffer
359 .InsertPacket(
360 Packet(kH264StapA).Pps().Idr().SeqNum(0).Time(0).Marker().Build())
361 .packets,
362 IsEmpty());
363 }
364
TEST(H264PacketBufferTest,SpsIdrIsNotKeyframeStapA)365 TEST(H264PacketBufferTest, SpsIdrIsNotKeyframeStapA) {
366 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
367
368 EXPECT_THAT(
369 packet_buffer
370 .InsertPacket(
371 Packet(kH264StapA).Sps().Idr().SeqNum(2).Time(2).Marker().Build())
372 .packets,
373 IsEmpty());
374
375 EXPECT_THAT(packet_buffer
376 .InsertPacket(Packet(kH264StapA)
377 .Sps()
378 .Pps()
379 .Idr()
380 .SeqNum(3)
381 .Time(3)
382 .Marker()
383 .Build())
384 .packets,
385 SizeIs(1));
386 }
387
TEST(H264PacketBufferTest,InsertingSpsPpsLastCompletesKeyframe)388 TEST(H264PacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) {
389 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
390
391 RTC_UNUSED(packet_buffer.InsertPacket(
392 Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build()));
393
394 EXPECT_THAT(packet_buffer
395 .InsertPacket(
396 Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build())
397 .packets,
398 SizeIs(2));
399 }
400
TEST(H264PacketBufferTest,InsertingMidFuaCompletesFrame)401 TEST(H264PacketBufferTest, InsertingMidFuaCompletesFrame) {
402 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
403
404 EXPECT_THAT(packet_buffer
405 .InsertPacket(Packet(kH264StapA)
406 .Sps()
407 .Pps()
408 .Idr()
409 .SeqNum(0)
410 .Time(0)
411 .Marker()
412 .Build())
413 .packets,
414 SizeIs(1));
415
416 RTC_UNUSED(packet_buffer.InsertPacket(
417 Packet(kH264FuA).Slice().SeqNum(1).Time(1).AsFirstFragment().Build()));
418 RTC_UNUSED(packet_buffer.InsertPacket(
419 Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build()));
420 EXPECT_THAT(
421 packet_buffer
422 .InsertPacket(Packet(kH264FuA).Slice().SeqNum(2).Time(1).Build())
423 .packets,
424 SizeIs(3));
425 }
426
TEST(H264PacketBufferTest,SeqNumJumpDoesNotCompleteFrame)427 TEST(H264PacketBufferTest, SeqNumJumpDoesNotCompleteFrame) {
428 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
429
430 EXPECT_THAT(packet_buffer
431 .InsertPacket(Packet(kH264StapA)
432 .Sps()
433 .Pps()
434 .Idr()
435 .SeqNum(0)
436 .Time(0)
437 .Marker()
438 .Build())
439 .packets,
440 SizeIs(1));
441
442 EXPECT_THAT(
443 packet_buffer
444 .InsertPacket(Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build())
445 .packets,
446 IsEmpty());
447
448 // Add `kBufferSize` to make the index of the sequence number wrap and end up
449 // where the packet with sequence number 2 would have ended up.
450 EXPECT_THAT(packet_buffer
451 .InsertPacket(Packet(kH264FuA)
452 .Slice()
453 .SeqNum(2 + kBufferSize)
454 .Time(3)
455 .Marker()
456 .Build())
457 .packets,
458 IsEmpty());
459 }
460
TEST(H264PacketBufferTest,OldFramesAreNotCompletedAfterBufferWrap)461 TEST(H264PacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) {
462 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
463
464 EXPECT_THAT(packet_buffer
465 .InsertPacket(Packet(kH264SingleNalu)
466 .Slice()
467 .SeqNum(1)
468 .Time(1)
469 .Marker()
470 .Build())
471 .packets,
472 IsEmpty());
473
474 // New keyframe, preceedes packet with sequence number 1 in the buffer.
475 EXPECT_THAT(packet_buffer
476 .InsertPacket(Packet(kH264StapA)
477 .Sps()
478 .Pps()
479 .Idr()
480 .SeqNum(kBufferSize)
481 .Time(kBufferSize)
482 .Marker()
483 .Build())
484 .packets,
485 SizeIs(1));
486 }
487
TEST(H264PacketBufferTest,OldPacketsDontBlockNewPackets)488 TEST(H264PacketBufferTest, OldPacketsDontBlockNewPackets) {
489 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
490 EXPECT_THAT(packet_buffer
491 .InsertPacket(Packet(kH264StapA)
492 .Sps()
493 .Pps()
494 .Idr()
495 .SeqNum(kBufferSize)
496 .Time(kBufferSize)
497 .Marker()
498 .Build())
499 .packets,
500 SizeIs(1));
501
502 RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA)
503 .Slice()
504 .SeqNum(kBufferSize + 1)
505 .Time(kBufferSize + 1)
506 .AsFirstFragment()
507 .Build()));
508
509 RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA)
510 .Slice()
511 .SeqNum(kBufferSize + 3)
512 .Time(kBufferSize + 1)
513 .Marker()
514 .Build()));
515 EXPECT_THAT(
516 packet_buffer
517 .InsertPacket(Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build())
518 .packets,
519 IsEmpty());
520
521 EXPECT_THAT(packet_buffer
522 .InsertPacket(Packet(kH264FuA)
523 .Slice()
524 .SeqNum(kBufferSize + 2)
525 .Time(kBufferSize + 1)
526 .Build())
527 .packets,
528 SizeIs(3));
529 }
530
TEST(H264PacketBufferTest,OldPacketDoesntCompleteFrame)531 TEST(H264PacketBufferTest, OldPacketDoesntCompleteFrame) {
532 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
533
534 EXPECT_THAT(packet_buffer
535 .InsertPacket(Packet(kH264StapA)
536 .Sps()
537 .Pps()
538 .Idr()
539 .SeqNum(kBufferSize)
540 .Time(kBufferSize)
541 .Marker()
542 .Build())
543 .packets,
544 SizeIs(1));
545
546 EXPECT_THAT(packet_buffer
547 .InsertPacket(Packet(kH264FuA)
548 .Slice()
549 .SeqNum(kBufferSize + 3)
550 .Time(kBufferSize + 1)
551 .Marker()
552 .Build())
553 .packets,
554 IsEmpty());
555
556 EXPECT_THAT(
557 packet_buffer
558 .InsertPacket(
559 Packet(kH264FuA).Slice().SeqNum(2).Time(2).Marker().Build())
560 .packets,
561 IsEmpty());
562
563 EXPECT_THAT(packet_buffer
564 .InsertPacket(Packet(kH264FuA)
565 .Slice()
566 .SeqNum(kBufferSize + 1)
567 .Time(kBufferSize + 1)
568 .AsFirstFragment()
569 .Build())
570 .packets,
571 IsEmpty());
572 }
573
TEST(H264PacketBufferTest,FrameBoundariesAreSet)574 TEST(H264PacketBufferTest, FrameBoundariesAreSet) {
575 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
576
577 auto key = packet_buffer.InsertPacket(
578 Packet(kH264StapA).Sps().Pps().Idr().SeqNum(1).Time(1).Marker().Build());
579
580 ASSERT_THAT(key.packets, SizeIs(1));
581 EXPECT_TRUE(key.packets[0]->video_header.is_first_packet_in_frame);
582 EXPECT_TRUE(key.packets[0]->video_header.is_last_packet_in_frame);
583
584 RTC_UNUSED(packet_buffer.InsertPacket(
585 Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build()));
586 RTC_UNUSED(packet_buffer.InsertPacket(
587 Packet(kH264FuA).Slice().SeqNum(3).Time(2).Build()));
588 auto delta = packet_buffer.InsertPacket(
589 Packet(kH264FuA).Slice().SeqNum(4).Time(2).Marker().Build());
590
591 ASSERT_THAT(delta.packets, SizeIs(3));
592 EXPECT_TRUE(delta.packets[0]->video_header.is_first_packet_in_frame);
593 EXPECT_FALSE(delta.packets[0]->video_header.is_last_packet_in_frame);
594
595 EXPECT_FALSE(delta.packets[1]->video_header.is_first_packet_in_frame);
596 EXPECT_FALSE(delta.packets[1]->video_header.is_last_packet_in_frame);
597
598 EXPECT_FALSE(delta.packets[2]->video_header.is_first_packet_in_frame);
599 EXPECT_TRUE(delta.packets[2]->video_header.is_last_packet_in_frame);
600 }
601
TEST(H264PacketBufferTest,ResolutionSetOnFirstPacket)602 TEST(H264PacketBufferTest, ResolutionSetOnFirstPacket) {
603 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
604
605 RTC_UNUSED(packet_buffer.InsertPacket(
606 Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build()));
607 auto res = packet_buffer.InsertPacket(Packet(kH264StapA)
608 .SpsWithResolution({320, 240})
609 .Pps()
610 .Idr()
611 .SeqNum(2)
612 .Time(1)
613 .Marker()
614 .Build());
615
616 ASSERT_THAT(res.packets, SizeIs(2));
617 EXPECT_THAT(res.packets[0]->video_header.width, Eq(320));
618 EXPECT_THAT(res.packets[0]->video_header.height, Eq(240));
619 }
620
TEST(H264PacketBufferTest,KeyframeAndDeltaFrameSetOnFirstPacket)621 TEST(H264PacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) {
622 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
623
624 RTC_UNUSED(packet_buffer.InsertPacket(
625 Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build()));
626 auto key = packet_buffer.InsertPacket(
627 Packet(kH264StapA).Sps().Pps().Idr().SeqNum(2).Time(1).Marker().Build());
628
629 auto delta = packet_buffer.InsertPacket(
630 Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build());
631
632 ASSERT_THAT(key.packets, SizeIs(2));
633 EXPECT_THAT(key.packets[0]->video_header.frame_type,
634 Eq(VideoFrameType::kVideoFrameKey));
635 ASSERT_THAT(delta.packets, SizeIs(1));
636 EXPECT_THAT(delta.packets[0]->video_header.frame_type,
637 Eq(VideoFrameType::kVideoFrameDelta));
638 }
639
TEST(H264PacketBufferTest,RtpSeqNumWrap)640 TEST(H264PacketBufferTest, RtpSeqNumWrap) {
641 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
642
643 RTC_UNUSED(packet_buffer.InsertPacket(
644 Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build()));
645
646 RTC_UNUSED(packet_buffer.InsertPacket(
647 Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build()));
648 EXPECT_THAT(packet_buffer
649 .InsertPacket(
650 Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build())
651 .packets,
652 SizeIs(3));
653 }
654
TEST(H264PacketBufferTest,StapAFixedBitstream)655 TEST(H264PacketBufferTest, StapAFixedBitstream) {
656 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
657
658 auto packets = packet_buffer
659 .InsertPacket(Packet(kH264StapA)
660 .Sps({1, 2, 3})
661 .Pps({4, 5, 6})
662 .Idr({7, 8, 9})
663 .SeqNum(0)
664 .Time(0)
665 .Marker()
666 .Build())
667 .packets;
668
669 ASSERT_THAT(packets, SizeIs(1));
670 EXPECT_THAT(PacketPayload(packets[0]),
671 ElementsAreArray(FlatVector({StartCode(),
672 {kSps, 1, 2, 3},
673 StartCode(),
674 {kPps, 4, 5, 6},
675 StartCode(),
676 {kIdr, 7, 8, 9}})));
677 }
678
TEST(H264PacketBufferTest,SingleNaluFixedBitstream)679 TEST(H264PacketBufferTest, SingleNaluFixedBitstream) {
680 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
681
682 RTC_UNUSED(packet_buffer.InsertPacket(
683 Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build()));
684 RTC_UNUSED(packet_buffer.InsertPacket(
685 Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build()));
686 auto packets = packet_buffer
687 .InsertPacket(Packet(kH264SingleNalu)
688 .Idr({7, 8, 9})
689 .SeqNum(2)
690 .Time(0)
691 .Marker()
692 .Build())
693 .packets;
694
695 ASSERT_THAT(packets, SizeIs(3));
696 EXPECT_THAT(PacketPayload(packets[0]),
697 ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}})));
698 EXPECT_THAT(PacketPayload(packets[1]),
699 ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}})));
700 EXPECT_THAT(PacketPayload(packets[2]),
701 ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}})));
702 }
703
TEST(H264PacketBufferTest,StapaAndFuaFixedBitstream)704 TEST(H264PacketBufferTest, StapaAndFuaFixedBitstream) {
705 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
706
707 RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264StapA)
708 .Sps({1, 2, 3})
709 .Pps({4, 5, 6})
710 .SeqNum(0)
711 .Time(0)
712 .Build()));
713 RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA)
714 .Idr({8, 8, 8})
715 .SeqNum(1)
716 .Time(0)
717 .AsFirstFragment()
718 .Build()));
719 auto packets = packet_buffer
720 .InsertPacket(Packet(kH264FuA)
721 .Idr({9, 9, 9})
722 .SeqNum(2)
723 .Time(0)
724 .Marker()
725 .Build())
726 .packets;
727
728 ASSERT_THAT(packets, SizeIs(3));
729 EXPECT_THAT(
730 PacketPayload(packets[0]),
731 ElementsAreArray(FlatVector(
732 {StartCode(), {kSps, 1, 2, 3}, StartCode(), {kPps, 4, 5, 6}})));
733 EXPECT_THAT(PacketPayload(packets[1]),
734 ElementsAreArray(FlatVector({StartCode(), {8, 8, 8}})));
735 // Third is a continuation of second, so only the payload is expected.
736 EXPECT_THAT(PacketPayload(packets[2]),
737 ElementsAreArray(FlatVector({{9, 9, 9}})));
738 }
739
TEST(H264PacketBufferTest,FullPacketBufferDoesNotBlockKeyframe)740 TEST(H264PacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) {
741 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
742
743 for (int i = 0; i < kBufferSize; ++i) {
744 EXPECT_THAT(
745 packet_buffer
746 .InsertPacket(
747 Packet(kH264SingleNalu).Slice().SeqNum(i).Time(0).Build())
748 .packets,
749 IsEmpty());
750 }
751
752 EXPECT_THAT(packet_buffer
753 .InsertPacket(Packet(kH264StapA)
754 .Sps()
755 .Pps()
756 .Idr()
757 .SeqNum(kBufferSize)
758 .Time(1)
759 .Marker()
760 .Build())
761 .packets,
762 SizeIs(1));
763 }
764
TEST(H264PacketBufferTest,TooManyNalusInPacket)765 TEST(H264PacketBufferTest, TooManyNalusInPacket) {
766 H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
767
768 std::unique_ptr<H264PacketBuffer::Packet> packet(
769 Packet(kH264StapA).Sps().Pps().Idr().SeqNum(1).Time(1).Marker().Build());
770 auto& h264_header =
771 absl::get<RTPVideoHeaderH264>(packet->video_header.video_type_header);
772 h264_header.nalus_length = kMaxNalusPerPacket + 1;
773
774 EXPECT_THAT(packet_buffer.InsertPacket(std::move(packet)).packets, IsEmpty());
775 }
776
777 } // namespace
778 } // namespace webrtc
779