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