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