xref: /aosp_15_r20/external/webrtc/modules/video_coding/packet_buffer_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 #include "modules/video_coding/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 "common_video/h264/h264_common.h"
20 #include "modules/video_coding/frame_object.h"
21 #include "rtc_base/random.h"
22 #include "test/field_trial.h"
23 #include "test/gmock.h"
24 #include "test/gtest.h"
25 
26 namespace webrtc {
27 namespace video_coding {
28 namespace {
29 
30 using ::testing::ElementsAre;
31 using ::testing::ElementsAreArray;
32 using ::testing::IsEmpty;
33 using ::testing::Matches;
34 using ::testing::Pointee;
35 using ::testing::SizeIs;
36 
37 constexpr int kStartSize = 16;
38 constexpr int kMaxSize = 64;
39 
IgnoreResult(PacketBuffer::InsertResult)40 void IgnoreResult(PacketBuffer::InsertResult /*result*/) {}
41 
42 // Validates frame boundaries are valid and returns first sequence_number for
43 // each frame.
StartSeqNums(rtc::ArrayView<const std::unique_ptr<PacketBuffer::Packet>> packets)44 std::vector<uint16_t> StartSeqNums(
45     rtc::ArrayView<const std::unique_ptr<PacketBuffer::Packet>> packets) {
46   std::vector<uint16_t> result;
47   bool frame_boundary = true;
48   for (const auto& packet : packets) {
49     EXPECT_EQ(frame_boundary, packet->is_first_packet_in_frame());
50     if (packet->is_first_packet_in_frame()) {
51       result.push_back(packet->seq_num);
52     }
53     frame_boundary = packet->is_last_packet_in_frame();
54   }
55   EXPECT_TRUE(frame_boundary);
56   return result;
57 }
58 
59 MATCHER_P(StartSeqNumsAre, seq_num, "") {
60   return Matches(ElementsAre(seq_num))(StartSeqNums(arg.packets));
61 }
62 
63 MATCHER_P2(StartSeqNumsAre, seq_num1, seq_num2, "") {
64   return Matches(ElementsAre(seq_num1, seq_num2))(StartSeqNums(arg.packets));
65 }
66 
67 MATCHER(KeyFrame, "") {
68   return arg->is_first_packet_in_frame() &&
69          arg->video_header.frame_type == VideoFrameType::kVideoFrameKey;
70 }
71 
72 MATCHER(DeltaFrame, "") {
73   return arg->is_first_packet_in_frame() &&
74          arg->video_header.frame_type == VideoFrameType::kVideoFrameDelta;
75 }
76 
77 struct PacketBufferInsertResult : public PacketBuffer::InsertResult {
PacketBufferInsertResultwebrtc::video_coding::__anon5ed2caa20111::PacketBufferInsertResult78   explicit PacketBufferInsertResult(PacketBuffer::InsertResult result)
79       : InsertResult(std::move(result)) {}
80 };
81 
PrintTo(const PacketBufferInsertResult & result,std::ostream * os)82 void PrintTo(const PacketBufferInsertResult& result, std::ostream* os) {
83   *os << "frames: { ";
84   for (const auto& packet : result.packets) {
85     if (packet->is_first_packet_in_frame() &&
86         packet->is_last_packet_in_frame()) {
87       *os << "{sn: " << packet->seq_num << " }";
88     } else if (packet->is_first_packet_in_frame()) {
89       *os << "{sn: [" << packet->seq_num << "-";
90     } else if (packet->is_last_packet_in_frame()) {
91       *os << packet->seq_num << "] }, ";
92     }
93   }
94   *os << " }";
95   if (result.buffer_cleared) {
96     *os << ", buffer_cleared";
97   }
98 }
99 
100 class PacketBufferTest : public ::testing::Test {
101  protected:
PacketBufferTest()102   PacketBufferTest() : rand_(0x7732213), packet_buffer_(kStartSize, kMaxSize) {}
103 
Rand()104   uint16_t Rand() { return rand_.Rand<uint16_t>(); }
105 
106   enum IsKeyFrame { kKeyFrame, kDeltaFrame };
107   enum IsFirst { kFirst, kNotFirst };
108   enum IsLast { kLast, kNotLast };
109 
Insert(uint16_t seq_num,IsKeyFrame keyframe,IsFirst first,IsLast last,rtc::ArrayView<const uint8_t> data={},uint32_t timestamp=123u)110   PacketBufferInsertResult Insert(uint16_t seq_num,  // packet sequence number
111                                   IsKeyFrame keyframe,  // is keyframe
112                                   IsFirst first,  // is first packet of frame
113                                   IsLast last,    // is last packet of frame
114                                   rtc::ArrayView<const uint8_t> data = {},
115                                   uint32_t timestamp = 123u) {  // rtp timestamp
116     auto packet = std::make_unique<PacketBuffer::Packet>();
117     packet->video_header.codec = kVideoCodecGeneric;
118     packet->timestamp = timestamp;
119     packet->seq_num = seq_num;
120     packet->video_header.frame_type = keyframe == kKeyFrame
121                                           ? VideoFrameType::kVideoFrameKey
122                                           : VideoFrameType::kVideoFrameDelta;
123     packet->video_header.is_first_packet_in_frame = first == kFirst;
124     packet->video_header.is_last_packet_in_frame = last == kLast;
125     packet->video_payload.SetData(data.data(), data.size());
126 
127     return PacketBufferInsertResult(
128         packet_buffer_.InsertPacket(std::move(packet)));
129   }
130 
131   Random rand_;
132   PacketBuffer packet_buffer_;
133 };
134 
TEST_F(PacketBufferTest,InsertOnePacket)135 TEST_F(PacketBufferTest, InsertOnePacket) {
136   const uint16_t seq_num = Rand();
137   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
138 }
139 
TEST_F(PacketBufferTest,InsertMultiplePackets)140 TEST_F(PacketBufferTest, InsertMultiplePackets) {
141   const uint16_t seq_num = Rand();
142   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
143   EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
144   EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
145   EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
146 }
147 
TEST_F(PacketBufferTest,InsertDuplicatePacket)148 TEST_F(PacketBufferTest, InsertDuplicatePacket) {
149   const uint16_t seq_num = Rand();
150   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
151   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
152   EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast).packets,
153               SizeIs(2));
154 }
155 
TEST_F(PacketBufferTest,SeqNumWrapOneFrame)156 TEST_F(PacketBufferTest, SeqNumWrapOneFrame) {
157   Insert(0xFFFF, kKeyFrame, kFirst, kNotLast);
158   EXPECT_THAT(Insert(0x0, kKeyFrame, kNotFirst, kLast),
159               StartSeqNumsAre(0xFFFF));
160 }
161 
TEST_F(PacketBufferTest,SeqNumWrapTwoFrames)162 TEST_F(PacketBufferTest, SeqNumWrapTwoFrames) {
163   EXPECT_THAT(Insert(0xFFFF, kKeyFrame, kFirst, kLast),
164               StartSeqNumsAre(0xFFFF));
165   EXPECT_THAT(Insert(0x0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0x0));
166 }
167 
TEST_F(PacketBufferTest,InsertOldPackets)168 TEST_F(PacketBufferTest, InsertOldPackets) {
169   EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
170   EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
171   EXPECT_THAT(Insert(101, kKeyFrame, kNotFirst, kLast).packets, SizeIs(2));
172 
173   EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
174   EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
175   EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
176 
177   packet_buffer_.ClearTo(102);
178   EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, IsEmpty());
179   EXPECT_THAT(Insert(103, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
180 }
181 
TEST_F(PacketBufferTest,FrameSize)182 TEST_F(PacketBufferTest, FrameSize) {
183   const uint16_t seq_num = Rand();
184   uint8_t data1[5] = {};
185   uint8_t data2[5] = {};
186   uint8_t data3[5] = {};
187   uint8_t data4[5] = {};
188 
189   Insert(seq_num, kKeyFrame, kFirst, kNotLast, data1);
190   Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast, data2);
191   Insert(seq_num + 2, kKeyFrame, kNotFirst, kNotLast, data3);
192   auto packets =
193       Insert(seq_num + 3, kKeyFrame, kNotFirst, kLast, data4).packets;
194   // Expect one frame of 4 packets.
195   EXPECT_THAT(StartSeqNums(packets), ElementsAre(seq_num));
196   EXPECT_THAT(packets, SizeIs(4));
197 }
198 
TEST_F(PacketBufferTest,ExpandBuffer)199 TEST_F(PacketBufferTest, ExpandBuffer) {
200   const uint16_t seq_num = Rand();
201 
202   Insert(seq_num, kKeyFrame, kFirst, kNotLast);
203   for (int i = 1; i < kStartSize; ++i)
204     EXPECT_FALSE(
205         Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
206 
207   // Already inserted kStartSize number of packets, inserting the last packet
208   // should increase the buffer size and also result in an assembled frame.
209   EXPECT_FALSE(
210       Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
211 }
212 
TEST_F(PacketBufferTest,SingleFrameExpandsBuffer)213 TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
214   const uint16_t seq_num = Rand();
215 
216   Insert(seq_num, kKeyFrame, kFirst, kNotLast);
217   for (int i = 1; i < kStartSize; ++i)
218     Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast);
219   EXPECT_THAT(Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast),
220               StartSeqNumsAre(seq_num));
221 }
222 
TEST_F(PacketBufferTest,ExpandBufferOverflow)223 TEST_F(PacketBufferTest, ExpandBufferOverflow) {
224   const uint16_t seq_num = Rand();
225 
226   EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared);
227   for (int i = 1; i < kMaxSize; ++i)
228     EXPECT_FALSE(
229         Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
230 
231   // Already inserted kMaxSize number of packets, inserting the last packet
232   // should overflow the buffer and result in false being returned.
233   EXPECT_TRUE(
234       Insert(seq_num + kMaxSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
235 }
236 
TEST_F(PacketBufferTest,OnePacketOneFrame)237 TEST_F(PacketBufferTest, OnePacketOneFrame) {
238   const uint16_t seq_num = Rand();
239   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
240               StartSeqNumsAre(seq_num));
241 }
242 
TEST_F(PacketBufferTest,TwoPacketsTwoFrames)243 TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
244   const uint16_t seq_num = Rand();
245 
246   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
247               StartSeqNumsAre(seq_num));
248   EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast),
249               StartSeqNumsAre(seq_num + 1));
250 }
251 
TEST_F(PacketBufferTest,TwoPacketsOneFrames)252 TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
253   const uint16_t seq_num = Rand();
254 
255   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
256   EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast),
257               StartSeqNumsAre(seq_num));
258 }
259 
TEST_F(PacketBufferTest,ThreePacketReorderingOneFrame)260 TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
261   const uint16_t seq_num = Rand();
262 
263   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
264   EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).packets,
265               IsEmpty());
266   EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast),
267               StartSeqNumsAre(seq_num));
268 }
269 
TEST_F(PacketBufferTest,Frames)270 TEST_F(PacketBufferTest, Frames) {
271   const uint16_t seq_num = Rand();
272 
273   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
274               StartSeqNumsAre(seq_num));
275   EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
276               StartSeqNumsAre(seq_num + 1));
277   EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
278               StartSeqNumsAre(seq_num + 2));
279   EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
280               StartSeqNumsAre(seq_num + 3));
281 }
282 
TEST_F(PacketBufferTest,ClearSinglePacket)283 TEST_F(PacketBufferTest, ClearSinglePacket) {
284   const uint16_t seq_num = Rand();
285 
286   for (int i = 0; i < kMaxSize; ++i)
287     Insert(seq_num + i, kDeltaFrame, kFirst, kLast);
288 
289   packet_buffer_.ClearTo(seq_num);
290   EXPECT_FALSE(
291       Insert(seq_num + kMaxSize, kDeltaFrame, kFirst, kLast).buffer_cleared);
292 }
293 
TEST_F(PacketBufferTest,ClearPacketBeforeFullyReceivedFrame)294 TEST_F(PacketBufferTest, ClearPacketBeforeFullyReceivedFrame) {
295   Insert(0, kKeyFrame, kFirst, kNotLast);
296   Insert(1, kKeyFrame, kNotFirst, kNotLast);
297   packet_buffer_.ClearTo(0);
298   EXPECT_THAT(Insert(2, kKeyFrame, kNotFirst, kLast).packets, IsEmpty());
299 }
300 
TEST_F(PacketBufferTest,ClearFullBuffer)301 TEST_F(PacketBufferTest, ClearFullBuffer) {
302   for (int i = 0; i < kMaxSize; ++i)
303     Insert(i, kDeltaFrame, kFirst, kLast);
304 
305   packet_buffer_.ClearTo(kMaxSize - 1);
306 
307   for (int i = kMaxSize; i < 2 * kMaxSize; ++i)
308     EXPECT_FALSE(Insert(i, kDeltaFrame, kFirst, kLast).buffer_cleared);
309 }
310 
TEST_F(PacketBufferTest,DontClearNewerPacket)311 TEST_F(PacketBufferTest, DontClearNewerPacket) {
312   EXPECT_THAT(Insert(0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0));
313   packet_buffer_.ClearTo(0);
314   EXPECT_THAT(Insert(2 * kStartSize, kKeyFrame, kFirst, kLast),
315               StartSeqNumsAre(2 * kStartSize));
316   EXPECT_THAT(Insert(3 * kStartSize + 1, kKeyFrame, kFirst, kNotLast).packets,
317               IsEmpty());
318   packet_buffer_.ClearTo(2 * kStartSize);
319   EXPECT_THAT(Insert(3 * kStartSize + 2, kKeyFrame, kNotFirst, kLast),
320               StartSeqNumsAre(3 * kStartSize + 1));
321 }
322 
TEST_F(PacketBufferTest,OneIncompleteFrame)323 TEST_F(PacketBufferTest, OneIncompleteFrame) {
324   const uint16_t seq_num = Rand();
325 
326   EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).packets,
327               IsEmpty());
328   EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kNotFirst, kLast),
329               StartSeqNumsAre(seq_num));
330   EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).packets,
331               IsEmpty());
332 }
333 
TEST_F(PacketBufferTest,TwoIncompleteFramesFullBuffer)334 TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
335   const uint16_t seq_num = Rand();
336 
337   for (int i = 1; i < kMaxSize - 1; ++i)
338     Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast);
339   EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).packets,
340               IsEmpty());
341   EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).packets,
342               IsEmpty());
343 }
344 
TEST_F(PacketBufferTest,FramesReordered)345 TEST_F(PacketBufferTest, FramesReordered) {
346   const uint16_t seq_num = Rand();
347 
348   EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
349               StartSeqNumsAre(seq_num + 1));
350   EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
351               StartSeqNumsAre(seq_num));
352   EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
353               StartSeqNumsAre(seq_num + 3));
354   EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
355               StartSeqNumsAre(seq_num + 2));
356 }
357 
TEST_F(PacketBufferTest,InsertPacketAfterSequenceNumberWrapAround)358 TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
359   uint16_t kFirstSeqNum = 0;
360   uint32_t kTimestampDelta = 100;
361   uint32_t timestamp = 10000;
362   uint16_t seq_num = kFirstSeqNum;
363 
364   // Loop until seq_num wraps around.
365   SeqNumUnwrapper<uint16_t> unwrapper;
366   while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
367     Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
368     for (int i = 0; i < 5; ++i) {
369       Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
370     }
371     Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp);
372     timestamp += kTimestampDelta;
373   }
374 
375   // Receive frame with overlapping sequence numbers.
376   Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
377   for (int i = 0; i < 5; ++i) {
378     Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
379   }
380   auto packets =
381       Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp).packets;
382   // One frame of 7 packets.
383   EXPECT_THAT(StartSeqNums(packets), SizeIs(1));
384   EXPECT_THAT(packets, SizeIs(7));
385 }
386 
387 // If `sps_pps_idr_is_keyframe` is true, we require keyframes to contain
388 // SPS/PPS/IDR and the keyframes we create as part of the test do contain
389 // SPS/PPS/IDR. If `sps_pps_idr_is_keyframe` is false, we only require and
390 // create keyframes containing only IDR.
391 class PacketBufferH264Test : public PacketBufferTest {
392  protected:
PacketBufferH264Test(bool sps_pps_idr_is_keyframe)393   explicit PacketBufferH264Test(bool sps_pps_idr_is_keyframe)
394       : PacketBufferTest(), sps_pps_idr_is_keyframe_(sps_pps_idr_is_keyframe) {
395     if (sps_pps_idr_is_keyframe) {
396       packet_buffer_.ForceSpsPpsIdrIsH264Keyframe();
397     }
398   }
399 
InsertH264(uint16_t seq_num,IsKeyFrame keyframe,IsFirst first,IsLast last,uint32_t timestamp,rtc::ArrayView<const uint8_t> data={},uint32_t width=0,uint32_t height=0)400   PacketBufferInsertResult InsertH264(
401       uint16_t seq_num,     // packet sequence number
402       IsKeyFrame keyframe,  // is keyframe
403       IsFirst first,        // is first packet of frame
404       IsLast last,          // is last packet of frame
405       uint32_t timestamp,   // rtp timestamp
406       rtc::ArrayView<const uint8_t> data = {},
407       uint32_t width = 0,     // width of frame (SPS/IDR)
408       uint32_t height = 0) {  // height of frame (SPS/IDR)
409     auto packet = std::make_unique<PacketBuffer::Packet>();
410     packet->video_header.codec = kVideoCodecH264;
411     auto& h264_header =
412         packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
413     packet->seq_num = seq_num;
414     packet->timestamp = timestamp;
415     if (keyframe == kKeyFrame) {
416       if (sps_pps_idr_is_keyframe_) {
417         h264_header.nalus[0].type = H264::NaluType::kSps;
418         h264_header.nalus[1].type = H264::NaluType::kPps;
419         h264_header.nalus[2].type = H264::NaluType::kIdr;
420         h264_header.nalus_length = 3;
421       } else {
422         h264_header.nalus[0].type = H264::NaluType::kIdr;
423         h264_header.nalus_length = 1;
424       }
425     }
426     packet->video_header.width = width;
427     packet->video_header.height = height;
428     packet->video_header.is_first_packet_in_frame = first == kFirst;
429     packet->video_header.is_last_packet_in_frame = last == kLast;
430     packet->video_payload.SetData(data.data(), data.size());
431 
432     return PacketBufferInsertResult(
433         packet_buffer_.InsertPacket(std::move(packet)));
434   }
435 
InsertH264KeyFrameWithAud(uint16_t seq_num,IsKeyFrame keyframe,IsFirst first,IsLast last,uint32_t timestamp,rtc::ArrayView<const uint8_t> data={},uint32_t width=0,uint32_t height=0)436   PacketBufferInsertResult InsertH264KeyFrameWithAud(
437       uint16_t seq_num,     // packet sequence number
438       IsKeyFrame keyframe,  // is keyframe
439       IsFirst first,        // is first packet of frame
440       IsLast last,          // is last packet of frame
441       uint32_t timestamp,   // rtp timestamp
442       rtc::ArrayView<const uint8_t> data = {},
443       uint32_t width = 0,     // width of frame (SPS/IDR)
444       uint32_t height = 0) {  // height of frame (SPS/IDR)
445     auto packet = std::make_unique<PacketBuffer::Packet>();
446     packet->video_header.codec = kVideoCodecH264;
447     auto& h264_header =
448         packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
449     packet->seq_num = seq_num;
450     packet->timestamp = timestamp;
451 
452     // this should be the start of frame.
453     RTC_CHECK(first == kFirst);
454 
455     // Insert a AUD NALU / packet without width/height.
456     h264_header.nalus[0].type = H264::NaluType::kAud;
457     h264_header.nalus_length = 1;
458     packet->video_header.is_first_packet_in_frame = true;
459     packet->video_header.is_last_packet_in_frame = false;
460     IgnoreResult(packet_buffer_.InsertPacket(std::move(packet)));
461     // insert IDR
462     return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp, data,
463                       width, height);
464   }
465 
466   const bool sps_pps_idr_is_keyframe_;
467 };
468 
469 // This fixture is used to test the general behaviour of the packet buffer
470 // in both configurations.
471 class PacketBufferH264ParameterizedTest
472     : public ::testing::WithParamInterface<bool>,
473       public PacketBufferH264Test {
474  protected:
PacketBufferH264ParameterizedTest()475   PacketBufferH264ParameterizedTest() : PacketBufferH264Test(GetParam()) {}
476 };
477 
478 INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
479                          PacketBufferH264ParameterizedTest,
480                          ::testing::Bool());
481 
TEST_P(PacketBufferH264ParameterizedTest,DontRemoveMissingPacketOnClearTo)482 TEST_P(PacketBufferH264ParameterizedTest, DontRemoveMissingPacketOnClearTo) {
483   InsertH264(0, kKeyFrame, kFirst, kLast, 0);
484   InsertH264(2, kDeltaFrame, kFirst, kNotLast, 2);
485   packet_buffer_.ClearTo(0);
486   // Expect no frame because of missing of packet #1
487   EXPECT_THAT(InsertH264(3, kDeltaFrame, kNotFirst, kLast, 2).packets,
488               IsEmpty());
489 }
490 
TEST_P(PacketBufferH264ParameterizedTest,GetBitstreamOneFrameFullBuffer)491 TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
492   uint8_t data_arr[kStartSize][1];
493   uint8_t expected[kStartSize];
494 
495   for (uint8_t i = 0; i < kStartSize; ++i) {
496     data_arr[i][0] = i;
497     expected[i] = i;
498   }
499 
500   InsertH264(0, kKeyFrame, kFirst, kNotLast, 1, data_arr[0]);
501   for (uint8_t i = 1; i < kStartSize - 1; ++i) {
502     InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1, data_arr[i]);
503   }
504 
505   auto packets = InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1,
506                             data_arr[kStartSize - 1])
507                      .packets;
508   ASSERT_THAT(StartSeqNums(packets), ElementsAre(0));
509   EXPECT_THAT(packets, SizeIs(kStartSize));
510   for (size_t i = 0; i < packets.size(); ++i) {
511     EXPECT_THAT(packets[i]->video_payload, SizeIs(1)) << "Packet #" << i;
512   }
513 }
514 
TEST_P(PacketBufferH264ParameterizedTest,GetBitstreamBufferPadding)515 TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
516   uint16_t seq_num = Rand();
517   rtc::CopyOnWriteBuffer data = "some plain old data";
518 
519   auto packet = std::make_unique<PacketBuffer::Packet>();
520   auto& h264_header =
521       packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
522   h264_header.nalus_length = 1;
523   h264_header.nalus[0].type = H264::NaluType::kIdr;
524   h264_header.packetization_type = kH264SingleNalu;
525   packet->seq_num = seq_num;
526   packet->video_header.codec = kVideoCodecH264;
527   packet->video_payload = data;
528   packet->video_header.is_first_packet_in_frame = true;
529   packet->video_header.is_last_packet_in_frame = true;
530   auto frames = packet_buffer_.InsertPacket(std::move(packet)).packets;
531 
532   ASSERT_THAT(frames, SizeIs(1));
533   EXPECT_EQ(frames[0]->seq_num, seq_num);
534   EXPECT_EQ(frames[0]->video_payload, data);
535 }
536 
TEST_P(PacketBufferH264ParameterizedTest,FrameResolution)537 TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
538   uint16_t seq_num = 100;
539   uint8_t data[] = "some plain old data";
540   uint32_t width = 640;
541   uint32_t height = 360;
542   uint32_t timestamp = 1000;
543 
544   auto packets = InsertH264(seq_num, kKeyFrame, kFirst, kLast, timestamp, data,
545                             width, height)
546                      .packets;
547 
548   ASSERT_THAT(packets, SizeIs(1));
549   EXPECT_EQ(packets[0]->video_header.width, width);
550   EXPECT_EQ(packets[0]->video_header.height, height);
551 }
552 
TEST_P(PacketBufferH264ParameterizedTest,FrameResolutionNaluBeforeSPS)553 TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
554   uint16_t seq_num = 100;
555   uint8_t data[] = "some plain old data";
556   uint32_t width = 640;
557   uint32_t height = 360;
558   uint32_t timestamp = 1000;
559 
560   auto packets = InsertH264KeyFrameWithAud(seq_num, kKeyFrame, kFirst, kLast,
561                                            timestamp, data, width, height)
562                      .packets;
563 
564   ASSERT_THAT(StartSeqNums(packets), ElementsAre(seq_num));
565   EXPECT_EQ(packets[0]->video_header.width, width);
566   EXPECT_EQ(packets[0]->video_header.height, height);
567 }
568 
TEST_F(PacketBufferTest,FreeSlotsOnFrameCreation)569 TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
570   const uint16_t seq_num = Rand();
571 
572   Insert(seq_num, kKeyFrame, kFirst, kNotLast);
573   Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
574   EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
575               StartSeqNumsAre(seq_num));
576 
577   // Insert frame that fills the whole buffer.
578   Insert(seq_num + 3, kKeyFrame, kFirst, kNotLast);
579   for (int i = 0; i < kMaxSize - 2; ++i)
580     Insert(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
581   EXPECT_THAT(Insert(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast),
582               StartSeqNumsAre(seq_num + 3));
583 }
584 
TEST_F(PacketBufferTest,Clear)585 TEST_F(PacketBufferTest, Clear) {
586   const uint16_t seq_num = Rand();
587 
588   Insert(seq_num, kKeyFrame, kFirst, kNotLast);
589   Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
590   EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
591               StartSeqNumsAre(seq_num));
592 
593   packet_buffer_.Clear();
594 
595   Insert(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
596   Insert(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
597   EXPECT_THAT(Insert(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast),
598               StartSeqNumsAre(seq_num + kStartSize));
599 }
600 
TEST_F(PacketBufferTest,FramesAfterClear)601 TEST_F(PacketBufferTest, FramesAfterClear) {
602   Insert(9025, kDeltaFrame, kFirst, kLast);
603   Insert(9024, kKeyFrame, kFirst, kLast);
604   packet_buffer_.ClearTo(9025);
605   EXPECT_THAT(Insert(9057, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
606   EXPECT_THAT(Insert(9026, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
607 }
608 
TEST_F(PacketBufferTest,SameFrameDifferentTimestamps)609 TEST_F(PacketBufferTest, SameFrameDifferentTimestamps) {
610   Insert(0, kKeyFrame, kFirst, kNotLast, {}, 1000);
611   EXPECT_THAT(Insert(1, kKeyFrame, kNotFirst, kLast, {}, 1001).packets,
612               IsEmpty());
613 }
614 
TEST_F(PacketBufferTest,ContinuousSeqNumDoubleMarkerBit)615 TEST_F(PacketBufferTest, ContinuousSeqNumDoubleMarkerBit) {
616   Insert(2, kKeyFrame, kNotFirst, kNotLast);
617   Insert(1, kKeyFrame, kFirst, kLast);
618   EXPECT_THAT(Insert(3, kKeyFrame, kNotFirst, kLast).packets, IsEmpty());
619 }
620 
TEST_F(PacketBufferTest,IncomingCodecChange)621 TEST_F(PacketBufferTest, IncomingCodecChange) {
622   auto packet = std::make_unique<PacketBuffer::Packet>();
623   packet->video_header.is_first_packet_in_frame = true;
624   packet->video_header.is_last_packet_in_frame = true;
625   packet->video_header.codec = kVideoCodecVP8;
626   packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
627   packet->timestamp = 1;
628   packet->seq_num = 1;
629   packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
630   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
631               SizeIs(1));
632 
633   packet = std::make_unique<PacketBuffer::Packet>();
634   packet->video_header.is_first_packet_in_frame = true;
635   packet->video_header.is_last_packet_in_frame = true;
636   packet->video_header.codec = kVideoCodecH264;
637   auto& h264_header =
638       packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
639   h264_header.nalus_length = 1;
640   packet->timestamp = 3;
641   packet->seq_num = 3;
642   packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
643   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
644               IsEmpty());
645 
646   packet = std::make_unique<PacketBuffer::Packet>();
647   packet->video_header.is_first_packet_in_frame = true;
648   packet->video_header.is_last_packet_in_frame = true;
649   packet->video_header.codec = kVideoCodecVP8;
650   packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
651   packet->timestamp = 2;
652   packet->seq_num = 2;
653   packet->video_header.frame_type = VideoFrameType::kVideoFrameDelta;
654   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
655               SizeIs(2));
656 }
657 
TEST_F(PacketBufferTest,TooManyNalusInPacket)658 TEST_F(PacketBufferTest, TooManyNalusInPacket) {
659   auto packet = std::make_unique<PacketBuffer::Packet>();
660   packet->video_header.codec = kVideoCodecH264;
661   packet->timestamp = 1;
662   packet->seq_num = 1;
663   packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
664   packet->video_header.is_first_packet_in_frame = true;
665   packet->video_header.is_last_packet_in_frame = true;
666   auto& h264_header =
667       packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
668   h264_header.nalus_length = kMaxNalusPerPacket;
669   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
670               IsEmpty());
671 }
672 
TEST_P(PacketBufferH264ParameterizedTest,OneFrameFillBuffer)673 TEST_P(PacketBufferH264ParameterizedTest, OneFrameFillBuffer) {
674   InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
675   for (int i = 1; i < kStartSize - 1; ++i)
676     InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
677   EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000),
678               StartSeqNumsAre(0));
679 }
680 
TEST_P(PacketBufferH264ParameterizedTest,CreateFramesAfterFilledBuffer)681 TEST_P(PacketBufferH264ParameterizedTest, CreateFramesAfterFilledBuffer) {
682   EXPECT_THAT(InsertH264(kStartSize - 2, kKeyFrame, kFirst, kLast, 0).packets,
683               SizeIs(1));
684 
685   InsertH264(kStartSize, kDeltaFrame, kFirst, kNotLast, 2000);
686   for (int i = 1; i < kStartSize; ++i)
687     InsertH264(kStartSize + i, kDeltaFrame, kNotFirst, kNotLast, 2000);
688   EXPECT_THAT(
689       InsertH264(kStartSize + kStartSize, kDeltaFrame, kNotFirst, kLast, 2000)
690           .packets,
691       IsEmpty());
692 
693   EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kFirst, kLast, 1000),
694               StartSeqNumsAre(kStartSize - 1, kStartSize));
695 }
696 
TEST_P(PacketBufferH264ParameterizedTest,OneFrameMaxSeqNum)697 TEST_P(PacketBufferH264ParameterizedTest, OneFrameMaxSeqNum) {
698   InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
699   EXPECT_THAT(InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000),
700               StartSeqNumsAre(65534));
701 }
702 
TEST_P(PacketBufferH264ParameterizedTest,ClearMissingPacketsOnKeyframe)703 TEST_P(PacketBufferH264ParameterizedTest, ClearMissingPacketsOnKeyframe) {
704   InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
705   InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
706   InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
707   InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
708 
709   EXPECT_THAT(InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000),
710               StartSeqNumsAre(kStartSize + 1));
711 }
712 
TEST_P(PacketBufferH264ParameterizedTest,FindFramesOnPadding)713 TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnPadding) {
714   EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1000),
715               StartSeqNumsAre(0));
716   EXPECT_THAT(InsertH264(2, kDeltaFrame, kFirst, kLast, 1000).packets,
717               IsEmpty());
718 
719   EXPECT_THAT(packet_buffer_.InsertPadding(1), StartSeqNumsAre(2));
720 }
721 
TEST_P(PacketBufferH264ParameterizedTest,FindFramesOnReorderedPadding)722 TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnReorderedPadding) {
723   EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1001),
724               StartSeqNumsAre(0));
725   EXPECT_THAT(InsertH264(1, kDeltaFrame, kFirst, kNotLast, 1002).packets,
726               IsEmpty());
727   EXPECT_THAT(packet_buffer_.InsertPadding(3).packets, IsEmpty());
728   EXPECT_THAT(InsertH264(4, kDeltaFrame, kFirst, kLast, 1003).packets,
729               IsEmpty());
730   EXPECT_THAT(InsertH264(2, kDeltaFrame, kNotFirst, kLast, 1002),
731               StartSeqNumsAre(1, 4));
732 }
733 
734 class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
735  protected:
736   const uint16_t kSeqNum = 5;
737 
PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)738   explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
739       : PacketBufferH264Test(sps_pps_idr_is_keyframe) {}
740 
CreatePacket()741   std::unique_ptr<PacketBuffer::Packet> CreatePacket() {
742     auto packet = std::make_unique<PacketBuffer::Packet>();
743     packet->video_header.codec = kVideoCodecH264;
744     packet->seq_num = kSeqNum;
745 
746     packet->video_header.is_first_packet_in_frame = true;
747     packet->video_header.is_last_packet_in_frame = true;
748     return packet;
749   }
750 };
751 
752 class PacketBufferH264IdrIsKeyframeTest
753     : public PacketBufferH264XIsKeyframeTest {
754  protected:
PacketBufferH264IdrIsKeyframeTest()755   PacketBufferH264IdrIsKeyframeTest()
756       : PacketBufferH264XIsKeyframeTest(false) {}
757 };
758 
TEST_F(PacketBufferH264IdrIsKeyframeTest,IdrIsKeyframe)759 TEST_F(PacketBufferH264IdrIsKeyframeTest, IdrIsKeyframe) {
760   auto packet = CreatePacket();
761   auto& h264_header =
762       packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
763   h264_header.nalus[0].type = H264::NaluType::kIdr;
764   h264_header.nalus_length = 1;
765   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
766               ElementsAre(KeyFrame()));
767 }
768 
TEST_F(PacketBufferH264IdrIsKeyframeTest,SpsPpsIdrIsKeyframe)769 TEST_F(PacketBufferH264IdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
770   auto packet = CreatePacket();
771   auto& h264_header =
772       packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
773   h264_header.nalus[0].type = H264::NaluType::kSps;
774   h264_header.nalus[1].type = H264::NaluType::kPps;
775   h264_header.nalus[2].type = H264::NaluType::kIdr;
776   h264_header.nalus_length = 3;
777 
778   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
779               ElementsAre(KeyFrame()));
780 }
781 
782 class PacketBufferH264SpsPpsIdrIsKeyframeTest
783     : public PacketBufferH264XIsKeyframeTest {
784  protected:
PacketBufferH264SpsPpsIdrIsKeyframeTest()785   PacketBufferH264SpsPpsIdrIsKeyframeTest()
786       : PacketBufferH264XIsKeyframeTest(true) {}
787 };
788 
TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest,IdrIsNotKeyframe)789 TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, IdrIsNotKeyframe) {
790   auto packet = CreatePacket();
791   auto& h264_header =
792       packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
793   h264_header.nalus[0].type = H264::NaluType::kIdr;
794   h264_header.nalus_length = 1;
795 
796   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
797               ElementsAre(DeltaFrame()));
798 }
799 
TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest,SpsPpsIsNotKeyframe)800 TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIsNotKeyframe) {
801   auto packet = CreatePacket();
802   auto& h264_header =
803       packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
804   h264_header.nalus[0].type = H264::NaluType::kSps;
805   h264_header.nalus[1].type = H264::NaluType::kPps;
806   h264_header.nalus_length = 2;
807 
808   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
809               ElementsAre(DeltaFrame()));
810 }
811 
TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest,SpsPpsIdrIsKeyframe)812 TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
813   auto packet = CreatePacket();
814   auto& h264_header =
815       packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
816   h264_header.nalus[0].type = H264::NaluType::kSps;
817   h264_header.nalus[1].type = H264::NaluType::kPps;
818   h264_header.nalus[2].type = H264::NaluType::kIdr;
819   h264_header.nalus_length = 3;
820 
821   EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
822               ElementsAre(KeyFrame()));
823 }
824 
825 }  // namespace
826 }  // namespace video_coding
827 }  // namespace webrtc
828