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