rtp_video_frame_assembler_unittests.cc (23009B)
1 /* 2 * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include <cstdint> 12 #include <iterator> 13 #include <memory> 14 #include <optional> 15 #include <vector> 16 17 #include "api/array_view.h" 18 #include "api/transport/rtp/dependency_descriptor.h" 19 #include "api/video/encoded_frame.h" 20 #include "api/video/rtp_video_frame_assembler.h" 21 #include "api/video/video_codec_type.h" 22 #include "api/video/video_frame_type.h" 23 #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" 24 #include "modules/rtp_rtcp/source/rtp_format.h" 25 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor.h" 26 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h" 27 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 28 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" 29 #include "modules/rtp_rtcp/source/rtp_packetizer_av1_test_helper.h" 30 #include "modules/rtp_rtcp/source/rtp_video_header.h" 31 #include "modules/video_coding/codecs/vp8/include/vp8_globals.h" 32 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h" 33 #include "rtc_base/checks.h" 34 #include "test/gmock.h" 35 #include "test/gtest.h" 36 37 namespace webrtc { 38 namespace { 39 40 using ::testing::ElementsAreArray; 41 using ::testing::Eq; 42 using ::testing::IsEmpty; 43 using ::testing::Matches; 44 using ::testing::SizeIs; 45 using ::testing::UnorderedElementsAre; 46 using ::testing::UnorderedElementsAreArray; 47 using PayloadFormat = RtpVideoFrameAssembler::PayloadFormat; 48 49 class PacketBuilder { 50 public: 51 explicit PacketBuilder(PayloadFormat format) 52 : format_(format), packet_to_send_(&extension_manager_) {} 53 54 PacketBuilder& WithSeqNum(uint16_t seq_num) { 55 seq_num_ = seq_num; 56 return *this; 57 } 58 59 PacketBuilder& WithPayload(ArrayView<const uint8_t> payload) { 60 payload_.assign(payload.begin(), payload.end()); 61 return *this; 62 } 63 64 PacketBuilder& WithVideoHeader(const RTPVideoHeader& video_header) { 65 video_header_ = video_header; 66 return *this; 67 } 68 69 template <typename T, typename... Args> 70 PacketBuilder& WithExtension(int id, const Args&... args) { 71 extension_manager_.Register<T>(id); 72 packet_to_send_.IdentifyExtensions(extension_manager_); 73 packet_to_send_.SetExtension<T>(std::forward<const Args>(args)...); 74 return *this; 75 } 76 77 RtpPacketReceived Build() { 78 auto packetizer = 79 RtpPacketizer::Create(GetVideoCodecType(), payload_, {}, video_header_); 80 packetizer->NextPacket(&packet_to_send_); 81 packet_to_send_.SetSequenceNumber(seq_num_); 82 83 RtpPacketReceived received(&extension_manager_); 84 received.Parse(packet_to_send_.Buffer()); 85 return received; 86 } 87 88 private: 89 std::optional<VideoCodecType> GetVideoCodecType() { 90 switch (format_) { 91 case PayloadFormat::kRaw: { 92 return std::nullopt; 93 } 94 case PayloadFormat::kH264: { 95 return kVideoCodecH264; 96 } 97 case PayloadFormat::kVp8: { 98 return kVideoCodecVP8; 99 } 100 case PayloadFormat::kVp9: { 101 return kVideoCodecVP9; 102 } 103 case PayloadFormat::kAv1: { 104 return kVideoCodecAV1; 105 } 106 case PayloadFormat::kH265: { 107 return kVideoCodecH265; 108 } 109 case PayloadFormat::kGeneric: { 110 return kVideoCodecGeneric; 111 } 112 } 113 RTC_DCHECK_NOTREACHED(); 114 return std::nullopt; 115 } 116 117 const RtpVideoFrameAssembler::PayloadFormat format_; 118 uint16_t seq_num_ = 0; 119 std::vector<uint8_t> payload_; 120 RTPVideoHeader video_header_; 121 RtpPacketReceived::ExtensionManager extension_manager_; 122 RtpPacketToSend packet_to_send_; 123 }; 124 125 RtpPacketReceived PaddingPacket(uint16_t seq_num) { 126 RtpPacketReceived padding_packet; 127 padding_packet.SetSequenceNumber(seq_num); 128 padding_packet.SetPadding(224); 129 return padding_packet; 130 } 131 132 void AppendFrames(RtpVideoFrameAssembler::FrameVector from, 133 RtpVideoFrameAssembler::FrameVector& to) { 134 to.insert(to.end(), std::make_move_iterator(from.begin()), 135 std::make_move_iterator(from.end())); 136 } 137 138 ArrayView<int64_t> References(const std::unique_ptr<EncodedFrame>& frame) { 139 return MakeArrayView(frame->references, frame->num_references); 140 } 141 142 ArrayView<const uint8_t> Payload(const std::unique_ptr<EncodedFrame>& frame) { 143 return *frame->GetEncodedData(); 144 } 145 146 TEST(RtpVideoFrameAssembler, Vp8Packetization) { 147 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kVp8); 148 149 // When sending VP8 over RTP parts of the payload is actually inspected at the 150 // RTP level. It just so happen that the initial 'V' sets the keyframe bit 151 // (0x01) to the correct value. 152 uint8_t kKeyframePayload[] = "Vp8Keyframe"; 153 ASSERT_EQ(kKeyframePayload[0] & 0x01, 0); 154 155 uint8_t kDeltaframePayload[] = "SomeFrame"; 156 ASSERT_EQ(kDeltaframePayload[0] & 0x01, 1); 157 158 RtpVideoFrameAssembler::FrameVector frames; 159 160 RTPVideoHeader video_header; 161 auto& vp8_header = 162 video_header.video_type_header.emplace<RTPVideoHeaderVP8>(); 163 164 vp8_header.pictureId = 10; 165 vp8_header.tl0PicIdx = 0; 166 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kVp8) 167 .WithPayload(kKeyframePayload) 168 .WithVideoHeader(video_header) 169 .Build()), 170 frames); 171 172 vp8_header.pictureId = 11; 173 vp8_header.tl0PicIdx = 1; 174 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kVp8) 175 .WithPayload(kDeltaframePayload) 176 .WithVideoHeader(video_header) 177 .Build()), 178 frames); 179 180 ASSERT_THAT(frames, SizeIs(2)); 181 182 auto first_frame = frames[0].ExtractFrame(); 183 EXPECT_THAT(first_frame->Id(), Eq(10)); 184 EXPECT_THAT(References(first_frame), IsEmpty()); 185 EXPECT_THAT(Payload(first_frame), ElementsAreArray(kKeyframePayload)); 186 187 auto second_frame = frames[1].ExtractFrame(); 188 EXPECT_THAT(second_frame->Id(), Eq(11)); 189 EXPECT_THAT(References(second_frame), UnorderedElementsAre(10)); 190 EXPECT_THAT(Payload(second_frame), ElementsAreArray(kDeltaframePayload)); 191 } 192 193 TEST(RtpVideoFrameAssembler, Vp9Packetization) { 194 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kVp9); 195 RtpVideoFrameAssembler::FrameVector frames; 196 197 uint8_t kPayload[] = "SomePayload"; 198 199 RTPVideoHeader video_header; 200 auto& vp9_header = 201 video_header.video_type_header.emplace<RTPVideoHeaderVP9>(); 202 vp9_header.InitRTPVideoHeaderVP9(); 203 204 vp9_header.picture_id = 10; 205 vp9_header.tl0_pic_idx = 0; 206 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kVp9) 207 .WithPayload(kPayload) 208 .WithVideoHeader(video_header) 209 .Build()), 210 frames); 211 212 vp9_header.picture_id = 11; 213 vp9_header.tl0_pic_idx = 1; 214 vp9_header.inter_pic_predicted = true; 215 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kVp9) 216 .WithPayload(kPayload) 217 .WithVideoHeader(video_header) 218 .Build()), 219 frames); 220 221 ASSERT_THAT(frames, SizeIs(2)); 222 223 auto first_frame = frames[0].ExtractFrame(); 224 EXPECT_THAT(first_frame->Id(), Eq(10)); 225 EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload)); 226 EXPECT_THAT(References(first_frame), IsEmpty()); 227 228 auto second_frame = frames[1].ExtractFrame(); 229 EXPECT_THAT(second_frame->Id(), Eq(11)); 230 EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload)); 231 EXPECT_THAT(References(second_frame), UnorderedElementsAre(10)); 232 } 233 234 TEST(RtpVideoFrameAssembler, Av1Packetization) { 235 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kAv1); 236 RtpVideoFrameAssembler::FrameVector frames; 237 238 auto kKeyframePayload = 239 BuildAv1Frame({Av1Obu(kAv1ObuTypeSequenceHeader).WithPayload({1, 2, 3}), 240 Av1Obu(kAv1ObuTypeFrame).WithPayload({4, 5, 6})}); 241 242 auto kDeltaframePayload = 243 BuildAv1Frame({Av1Obu(kAv1ObuTypeFrame).WithPayload({7, 8, 9})}); 244 245 RTPVideoHeader video_header; 246 247 video_header.frame_type = VideoFrameType::kVideoFrameKey; 248 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kAv1) 249 .WithPayload(kKeyframePayload) 250 .WithVideoHeader(video_header) 251 .WithSeqNum(20) 252 .Build()), 253 frames); 254 255 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kAv1) 256 .WithPayload(kDeltaframePayload) 257 .WithSeqNum(21) 258 .Build()), 259 frames); 260 261 ASSERT_THAT(frames, SizeIs(2)); 262 263 auto first_frame = frames[0].ExtractFrame(); 264 EXPECT_THAT(first_frame->Id(), Eq(20)); 265 EXPECT_THAT(Payload(first_frame), ElementsAreArray(kKeyframePayload)); 266 EXPECT_THAT(References(first_frame), IsEmpty()); 267 268 auto second_frame = frames[1].ExtractFrame(); 269 EXPECT_THAT(second_frame->Id(), Eq(21)); 270 EXPECT_THAT(Payload(second_frame), ElementsAreArray(kDeltaframePayload)); 271 EXPECT_THAT(References(second_frame), UnorderedElementsAre(20)); 272 } 273 274 TEST(RtpVideoFrameAssembler, RawPacketizationDependencyDescriptorExtension) { 275 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kRaw); 276 RtpVideoFrameAssembler::FrameVector frames; 277 uint8_t kPayload[] = "SomePayload"; 278 279 FrameDependencyStructure dependency_structure; 280 dependency_structure.num_decode_targets = 1; 281 dependency_structure.num_chains = 1; 282 dependency_structure.decode_target_protected_by_chain.push_back(0); 283 dependency_structure.templates.push_back( 284 FrameDependencyTemplate().S(0).T(0).Dtis("S").ChainDiffs({0})); 285 dependency_structure.templates.push_back( 286 FrameDependencyTemplate().S(0).T(0).Dtis("S").ChainDiffs({10}).FrameDiffs( 287 {10})); 288 289 DependencyDescriptor dependency_descriptor; 290 291 dependency_descriptor.frame_number = 10; 292 dependency_descriptor.frame_dependencies = dependency_structure.templates[0]; 293 dependency_descriptor.attached_structure = 294 std::make_unique<FrameDependencyStructure>(dependency_structure); 295 AppendFrames(assembler.InsertPacket( 296 PacketBuilder(PayloadFormat::kRaw) 297 .WithPayload(kPayload) 298 .WithExtension<RtpDependencyDescriptorExtension>( 299 1, dependency_structure, dependency_descriptor) 300 .Build()), 301 frames); 302 303 dependency_descriptor.frame_number = 20; 304 dependency_descriptor.frame_dependencies = dependency_structure.templates[1]; 305 dependency_descriptor.attached_structure.reset(); 306 AppendFrames(assembler.InsertPacket( 307 PacketBuilder(PayloadFormat::kRaw) 308 .WithPayload(kPayload) 309 .WithExtension<RtpDependencyDescriptorExtension>( 310 1, dependency_structure, dependency_descriptor) 311 .Build()), 312 frames); 313 314 ASSERT_THAT(frames, SizeIs(2)); 315 316 auto first_frame = frames[0].ExtractFrame(); 317 EXPECT_THAT(first_frame->Id(), Eq(10)); 318 EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload)); 319 EXPECT_THAT(References(first_frame), IsEmpty()); 320 321 auto second_frame = frames[1].ExtractFrame(); 322 EXPECT_THAT(second_frame->Id(), Eq(20)); 323 EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload)); 324 EXPECT_THAT(References(second_frame), UnorderedElementsAre(10)); 325 } 326 327 TEST(RtpVideoFrameAssembler, RawPacketizationGenericDescriptor00Extension) { 328 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kRaw); 329 RtpVideoFrameAssembler::FrameVector frames; 330 uint8_t kPayload[] = "SomePayload"; 331 332 RtpGenericFrameDescriptor generic; 333 334 generic.SetFirstPacketInSubFrame(true); 335 generic.SetLastPacketInSubFrame(true); 336 generic.SetFrameId(100); 337 AppendFrames( 338 assembler.InsertPacket( 339 PacketBuilder(PayloadFormat::kRaw) 340 .WithPayload(kPayload) 341 .WithExtension<RtpGenericFrameDescriptorExtension00>(1, generic) 342 .Build()), 343 frames); 344 345 generic.SetFrameId(102); 346 generic.AddFrameDependencyDiff(2); 347 AppendFrames( 348 assembler.InsertPacket( 349 PacketBuilder(PayloadFormat::kRaw) 350 .WithPayload(kPayload) 351 .WithExtension<RtpGenericFrameDescriptorExtension00>(1, generic) 352 .Build()), 353 frames); 354 355 ASSERT_THAT(frames, SizeIs(2)); 356 357 auto first_frame = frames[0].ExtractFrame(); 358 EXPECT_THAT(first_frame->Id(), Eq(100)); 359 EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload)); 360 EXPECT_THAT(References(first_frame), IsEmpty()); 361 362 auto second_frame = frames[1].ExtractFrame(); 363 EXPECT_THAT(second_frame->Id(), Eq(102)); 364 EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload)); 365 EXPECT_THAT(References(second_frame), UnorderedElementsAre(100)); 366 } 367 368 TEST(RtpVideoFrameAssembler, RawPacketizationGenericPayloadDescriptor) { 369 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric); 370 RtpVideoFrameAssembler::FrameVector frames; 371 uint8_t kPayload[] = "SomePayload"; 372 373 RTPVideoHeader video_header; 374 375 video_header.frame_type = VideoFrameType::kVideoFrameKey; 376 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 377 .WithPayload(kPayload) 378 .WithVideoHeader(video_header) 379 .WithSeqNum(123) 380 .Build()), 381 frames); 382 383 video_header.frame_type = VideoFrameType::kVideoFrameDelta; 384 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 385 .WithPayload(kPayload) 386 .WithVideoHeader(video_header) 387 .WithSeqNum(124) 388 .Build()), 389 frames); 390 391 ASSERT_THAT(frames, SizeIs(2)); 392 393 auto first_frame = frames[0].ExtractFrame(); 394 EXPECT_THAT(first_frame->Id(), Eq(123)); 395 EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload)); 396 EXPECT_THAT(References(first_frame), IsEmpty()); 397 398 auto second_frame = frames[1].ExtractFrame(); 399 EXPECT_THAT(second_frame->Id(), Eq(124)); 400 EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload)); 401 EXPECT_THAT(References(second_frame), UnorderedElementsAre(123)); 402 } 403 404 TEST(RtpVideoFrameAssembler, Padding) { 405 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric); 406 RtpVideoFrameAssembler::FrameVector frames; 407 uint8_t kPayload[] = "SomePayload"; 408 409 RTPVideoHeader video_header; 410 411 video_header.frame_type = VideoFrameType::kVideoFrameKey; 412 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 413 .WithPayload(kPayload) 414 .WithVideoHeader(video_header) 415 .WithSeqNum(123) 416 .Build()), 417 frames); 418 419 video_header.frame_type = VideoFrameType::kVideoFrameDelta; 420 AppendFrames(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 421 .WithPayload(kPayload) 422 .WithVideoHeader(video_header) 423 .WithSeqNum(125) 424 .Build()), 425 frames); 426 427 ASSERT_THAT(frames, SizeIs(1)); 428 auto first_frame = frames[0].ExtractFrame(); 429 EXPECT_THAT(first_frame->Id(), Eq(123)); 430 EXPECT_THAT(Payload(first_frame), ElementsAreArray(kPayload)); 431 EXPECT_THAT(References(first_frame), IsEmpty()); 432 433 AppendFrames(assembler.InsertPacket(PaddingPacket(/*seq_num=*/124)), frames); 434 435 ASSERT_THAT(frames, SizeIs(2)); 436 auto second_frame = frames[1].ExtractFrame(); 437 EXPECT_THAT(second_frame->Id(), Eq(125)); 438 EXPECT_THAT(Payload(second_frame), ElementsAreArray(kPayload)); 439 EXPECT_THAT(References(second_frame), UnorderedElementsAre(123)); 440 } 441 442 TEST(RtpVideoFrameAssembler, ClearOldPackets) { 443 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric); 444 445 // If we don't have a payload the packet will be counted as a padding packet. 446 uint8_t kPayload[] = "DontCare"; 447 448 RTPVideoHeader video_header; 449 video_header.frame_type = VideoFrameType::kVideoFrameKey; 450 EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 451 .WithPayload(kPayload) 452 .WithVideoHeader(video_header) 453 .WithSeqNum(0) 454 .Build()), 455 SizeIs(1)); 456 457 EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 458 .WithPayload(kPayload) 459 .WithVideoHeader(video_header) 460 .WithSeqNum(2000) 461 .Build()), 462 SizeIs(1)); 463 464 EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 465 .WithPayload(kPayload) 466 .WithVideoHeader(video_header) 467 .WithSeqNum(0) 468 .Build()), 469 SizeIs(0)); 470 471 EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 472 .WithPayload(kPayload) 473 .WithVideoHeader(video_header) 474 .WithSeqNum(1) 475 .Build()), 476 SizeIs(1)); 477 } 478 479 TEST(RtpVideoFrameAssembler, ClearOldPacketsWithPadding) { 480 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric); 481 uint8_t kPayload[] = "DontCare"; 482 483 RTPVideoHeader video_header; 484 video_header.frame_type = VideoFrameType::kVideoFrameKey; 485 EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 486 .WithPayload(kPayload) 487 .WithVideoHeader(video_header) 488 .WithSeqNum(0) 489 .Build()), 490 SizeIs(1)); 491 492 EXPECT_THAT(assembler.InsertPacket(PaddingPacket(/*seq_num=*/2000)), 493 SizeIs(0)); 494 495 EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 496 .WithPayload(kPayload) 497 .WithVideoHeader(video_header) 498 .WithSeqNum(0) 499 .Build()), 500 SizeIs(0)); 501 502 EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 503 .WithPayload(kPayload) 504 .WithVideoHeader(video_header) 505 .WithSeqNum(1) 506 .Build()), 507 SizeIs(1)); 508 } 509 510 TEST(RtpVideoFrameAssembler, SeqNumStartAndSeqNumEndSet) { 511 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric); 512 RtpVideoFrameAssembler::FrameVector frames; 513 uint8_t kPayload[] = 514 "Some payload that will get split into two when packetized."; 515 516 RTPVideoHeader video_header; 517 video_header.frame_type = VideoFrameType::kVideoFrameKey; 518 RtpPacketizer::PayloadSizeLimits limits; 519 limits.max_payload_len = sizeof(kPayload) - 1; 520 521 auto packetizer = 522 RtpPacketizer::Create(kVideoCodecGeneric, kPayload, limits, video_header); 523 ASSERT_THAT(packetizer->NumPackets(), Eq(2U)); 524 525 RtpPacketReceived::ExtensionManager extension_manager; 526 { 527 RtpPacketToSend send_packet(&extension_manager); 528 packetizer->NextPacket(&send_packet); 529 send_packet.SetSequenceNumber(123); 530 RtpPacketReceived received_packet(&extension_manager); 531 received_packet.Parse(send_packet.Buffer()); 532 assembler.InsertPacket(received_packet); 533 } 534 535 { 536 RtpPacketToSend send_packet(&extension_manager); 537 packetizer->NextPacket(&send_packet); 538 send_packet.SetSequenceNumber(124); 539 RtpPacketReceived received_packet(&extension_manager); 540 received_packet.Parse(send_packet.Buffer()); 541 AppendFrames(assembler.InsertPacket(received_packet), frames); 542 } 543 544 ASSERT_THAT(frames, SizeIs(1)); 545 EXPECT_THAT(frames[0].RtpSeqNumStart(), Eq(123)); 546 EXPECT_THAT(frames[0].RtpSeqNumEnd(), Eq(124)); 547 } 548 549 TEST(RtpVideoFrameAssembler, SeqNumStartAndSeqNumEndSetWhenPaddingReceived) { 550 RtpVideoFrameAssembler assembler(RtpVideoFrameAssembler::kGeneric); 551 RtpVideoFrameAssembler::FrameVector frames; 552 uint8_t kPayload[] = 553 "Some payload that will get split into two when packetized."; 554 555 RTPVideoHeader video_header; 556 video_header.frame_type = VideoFrameType::kVideoFrameKey; 557 558 EXPECT_THAT(assembler.InsertPacket(PacketBuilder(PayloadFormat::kGeneric) 559 .WithPayload(kPayload) 560 .WithVideoHeader(video_header) 561 .WithSeqNum(121) 562 .Build()), 563 SizeIs(1)); 564 565 video_header.frame_type = VideoFrameType::kVideoFrameDelta; 566 RtpPacketReceived::ExtensionManager extension_manager; 567 RtpPacketizer::PayloadSizeLimits limits; 568 limits.max_payload_len = sizeof(kPayload) - 1; 569 570 auto packetizer = 571 RtpPacketizer::Create(kVideoCodecGeneric, kPayload, limits, video_header); 572 ASSERT_THAT(packetizer->NumPackets(), Eq(2U)); 573 574 { 575 RtpPacketToSend send_packet(&extension_manager); 576 packetizer->NextPacket(&send_packet); 577 send_packet.SetSequenceNumber(123); 578 RtpPacketReceived received_packet(&extension_manager); 579 received_packet.Parse(send_packet.Buffer()); 580 assembler.InsertPacket(received_packet); 581 } 582 583 { 584 RtpPacketToSend send_packet(&extension_manager); 585 packetizer->NextPacket(&send_packet); 586 send_packet.SetSequenceNumber(124); 587 RtpPacketReceived received_packet(&extension_manager); 588 received_packet.Parse(send_packet.Buffer()); 589 assembler.InsertPacket(received_packet); 590 } 591 592 AppendFrames(assembler.InsertPacket(PaddingPacket(/*seq_num=*/122)), frames); 593 594 ASSERT_THAT(frames, SizeIs(1)); 595 EXPECT_THAT(frames[0].RtpSeqNumStart(), Eq(123)); 596 EXPECT_THAT(frames[0].RtpSeqNumEnd(), Eq(124)); 597 } 598 599 } // namespace 600 } // namespace webrtc