Fix is_first_packet_in_frame flag for h26x_packet_buffer_unittests.

Update unit tests to follow video_rtp_depacketizer_h264's behavior of
setting is_first_packet_in_frame. This flag might be used to determine
if a frame can be assembled.

Bug: webrtc:384391181
Change-Id: I6750c20056e426e12c1d4e21eea4c641def7cfbd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/373168
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43669}
This commit is contained in:
Jianjun Zhu 2025-01-03 21:30:22 +08:00 committed by WebRTC LUCI CQ
parent 80344a0a5c
commit a23fbc694f

View File

@ -75,6 +75,7 @@ class H264Packet {
H264Packet& Aud(); H264Packet& Aud();
H264Packet& Marker(); H264Packet& Marker();
H264Packet& AsFirstFragment(); H264Packet& AsFirstFragment();
H264Packet& AsFirstPacket();
H264Packet& Time(uint32_t rtp_timestamp); H264Packet& Time(uint32_t rtp_timestamp);
H264Packet& SeqNum(int64_t rtp_seq_num); H264Packet& SeqNum(int64_t rtp_seq_num);
@ -95,6 +96,7 @@ class H264Packet {
H264PacketizationTypes type_; H264PacketizationTypes type_;
RTPVideoHeader video_header_; RTPVideoHeader video_header_;
bool first_fragment_ = false; bool first_fragment_ = false;
bool first_packet_ = false;
bool marker_bit_ = false; bool marker_bit_ = false;
uint32_t rtp_timestamp_ = 0; uint32_t rtp_timestamp_ = 0;
int64_t rtp_seq_num_ = 0; int64_t rtp_seq_num_ = 0;
@ -169,6 +171,11 @@ H264Packet& H264Packet::AsFirstFragment() {
return *this; return *this;
} }
H264Packet& H264Packet::AsFirstPacket() {
first_packet_ = true;
return *this;
}
H264Packet& H264Packet::Time(uint32_t rtp_timestamp) { H264Packet& H264Packet::Time(uint32_t rtp_timestamp) {
rtp_timestamp_ = rtp_timestamp; rtp_timestamp_ = rtp_timestamp;
return *this; return *this;
@ -211,6 +218,7 @@ std::unique_ptr<H26xPacketBuffer::Packet> H264Packet::Build() {
res->timestamp = rtp_timestamp_; res->timestamp = rtp_timestamp_;
res->sequence_number = rtp_seq_num_; res->sequence_number = rtp_seq_num_;
res->video_header.codec = kVideoCodecH264; res->video_header.codec = kVideoCodecH264;
res->video_header.is_first_packet_in_frame = first_packet_;
return res; return res;
} }
@ -262,6 +270,7 @@ class H265Packet {
H265Packet& Aud(); H265Packet& Aud();
H265Packet& Marker(); H265Packet& Marker();
H265Packet& AsFirstFragment(); H265Packet& AsFirstFragment();
H265Packet& AsFirstPacket();
H265Packet& Time(uint32_t rtp_timestamp); H265Packet& Time(uint32_t rtp_timestamp);
H265Packet& SeqNum(int64_t rtp_seq_num); H265Packet& SeqNum(int64_t rtp_seq_num);
@ -272,6 +281,7 @@ class H265Packet {
RTPVideoHeader video_header_; RTPVideoHeader video_header_;
bool first_fragment_ = false; bool first_fragment_ = false;
bool first_packet_ = false;
bool marker_bit_ = false; bool marker_bit_ = false;
uint32_t rtp_timestamp_ = 0; uint32_t rtp_timestamp_ = 0;
uint16_t rtp_seq_num_ = 0; uint16_t rtp_seq_num_ = 0;
@ -332,6 +342,7 @@ std::unique_ptr<H26xPacketBuffer::Packet> H265Packet::Build() {
res->sequence_number = rtp_seq_num_; res->sequence_number = rtp_seq_num_;
res->video_header.codec = kVideoCodecH265; res->video_header.codec = kVideoCodecH265;
res->video_payload = rtc::CopyOnWriteBuffer(); res->video_payload = rtc::CopyOnWriteBuffer();
res->video_header.is_first_packet_in_frame = first_packet_;
for (const auto& payload : nalu_payloads_) { for (const auto& payload : nalu_payloads_) {
res->video_payload.AppendData(payload); res->video_payload.AppendData(payload);
} }
@ -344,6 +355,11 @@ H265Packet& H265Packet::AsFirstFragment() {
return *this; return *this;
} }
H265Packet& H265Packet::AsFirstPacket() {
first_packet_ = true;
return *this;
}
H265Packet& H265Packet::Time(uint32_t rtp_timestamp) { H265Packet& H265Packet::Time(uint32_t rtp_timestamp) {
rtp_timestamp_ = rtp_timestamp; rtp_timestamp_ = rtp_timestamp;
return *this; return *this;
@ -373,10 +389,12 @@ TEST(H26xPacketBufferTest, IdrOnlyKeyframeWithSprop) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true);
packet_buffer.SetSpropParameterSets(kExampleSpropString); packet_buffer.SetSpropParameterSets(kExampleSpropString);
auto packets = auto packets = packet_buffer
packet_buffer .InsertPacket(H264Packet(kH264SingleNalu)
.InsertPacket( .Idr({1, 2, 3}, 0)
H264Packet(kH264SingleNalu).Idr({1, 2, 3}, 0).Marker().Build()) .AsFirstPacket()
.Marker()
.Build())
.packets; .packets;
EXPECT_THAT(packets, SizeIs(1)); EXPECT_THAT(packets, SizeIs(1));
EXPECT_THAT(PacketPayload(packets[0]), EXPECT_THAT(PacketPayload(packets[0]),
@ -393,10 +411,12 @@ TEST(H26xPacketBufferTest, IdrOnlyKeyframeWithoutSprop) {
// Cannot fix biststream by prepending SPS and PPS because no sprop string is // Cannot fix biststream by prepending SPS and PPS because no sprop string is
// available. Request a key frame. // available. Request a key frame.
EXPECT_TRUE( EXPECT_TRUE(packet_buffer
packet_buffer .InsertPacket(H264Packet(kH264SingleNalu)
.InsertPacket( .Idr({9, 9, 9}, 0)
H264Packet(kH264SingleNalu).Idr({9, 9, 9}, 0).Marker().Build()) .AsFirstPacket()
.Marker()
.Build())
.buffer_cleared); .buffer_cleared);
} }
@ -406,10 +426,12 @@ TEST(H26xPacketBufferTest, IdrOnlyKeyframeWithSpropAndUnknownPpsId) {
// Cannot fix biststream because sprop string doesn't contain a PPS with given // Cannot fix biststream because sprop string doesn't contain a PPS with given
// ID. Request a key frame. // ID. Request a key frame.
EXPECT_TRUE( EXPECT_TRUE(packet_buffer
packet_buffer .InsertPacket(H264Packet(kH264SingleNalu)
.InsertPacket( .Idr({9, 9, 9}, 1)
H264Packet(kH264SingleNalu).Idr({9, 9, 9}, 1).Marker().Build()) .AsFirstPacket()
.Marker()
.Build())
.buffer_cleared); .buffer_cleared);
} }
@ -417,18 +439,24 @@ TEST(H26xPacketBufferTest, IdrOnlyKeyframeInTheMiddle) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true);
packet_buffer.SetSpropParameterSets(kExampleSpropString); packet_buffer.SetSpropParameterSets(kExampleSpropString);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Sps({1, 2, 3}, 1).SeqNum(0).Time(0).Build())); .Sps({1, 2, 3}, 1)
.SeqNum(0)
.Time(0)
.AsFirstPacket()
.Build()));
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu) RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
.Pps({4, 5, 6}, 1, 1) .Pps({4, 5, 6}, 1, 1)
.SeqNum(1) .SeqNum(1)
.Time(0) .Time(0)
.AsFirstPacket()
.Build())); .Build()));
EXPECT_THAT(packet_buffer EXPECT_THAT(packet_buffer
.InsertPacket(H264Packet(kH264SingleNalu) .InsertPacket(H264Packet(kH264SingleNalu)
.Idr({7, 8, 9}, 1) .Idr({7, 8, 9}, 1)
.SeqNum(2) .SeqNum(2)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -439,6 +467,7 @@ TEST(H26xPacketBufferTest, IdrOnlyKeyframeInTheMiddle) {
.Slice() .Slice()
.SeqNum(3) .SeqNum(3)
.Time(1) .Time(1)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -449,6 +478,7 @@ TEST(H26xPacketBufferTest, IdrOnlyKeyframeInTheMiddle) {
.Idr({10, 11, 12}, 0) .Idr({10, 11, 12}, 0)
.SeqNum(4) .SeqNum(4)
.Time(2) .Time(2)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets; .packets;
@ -465,9 +495,12 @@ TEST(H26xPacketBufferTest, IdrOnlyKeyframeInTheMiddle) {
TEST(H26xPacketBufferTest, IdrIsNotKeyframe) { TEST(H26xPacketBufferTest, IdrIsNotKeyframe) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer .InsertPacket(H264Packet(kH264SingleNalu)
.InsertPacket(H264Packet(kH264SingleNalu).Idr().Marker().Build()) .Idr()
.AsFirstPacket()
.Marker()
.Build())
.packets, .packets,
IsEmpty()); IsEmpty());
} }
@ -477,9 +510,13 @@ TEST(H26xPacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) {
packet_buffer.SetSpropParameterSets(kExampleSpropString); packet_buffer.SetSpropParameterSets(kExampleSpropString);
// Not marked as the first fragment // Not marked as the first fragment
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer .InsertPacket(H264Packet(kH264FuA)
.InsertPacket(H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build()) .Idr()
.SeqNum(0)
.Time(0)
.AsFirstPacket()
.Build())
.packets, .packets,
IsEmpty()); IsEmpty());
@ -497,6 +534,7 @@ TEST(H26xPacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) {
.SeqNum(2) .SeqNum(2)
.Time(1) .Time(1)
.AsFirstFragment() .AsFirstFragment()
.AsFirstPacket()
.Build()) .Build())
.packets, .packets,
IsEmpty()); IsEmpty());
@ -512,8 +550,12 @@ TEST(H26xPacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) {
TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) { TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); .Sps()
.SeqNum(0)
.Time(0)
.AsFirstPacket()
.Build()));
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(
H264Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build())); H264Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build()));
EXPECT_THAT(packet_buffer EXPECT_THAT(packet_buffer
@ -521,6 +563,7 @@ TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) {
.Idr() .Idr()
.SeqNum(2) .SeqNum(2)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -534,18 +577,24 @@ TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeIgnoresSprop) {
// ignored. Use in band parameter sets. // ignored. Use in band parameter sets.
packet_buffer.SetSpropParameterSets(kExampleSpropString); packet_buffer.SetSpropParameterSets(kExampleSpropString);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Sps({1, 2, 3}, 0).SeqNum(0).Time(0).Build())); .Sps({1, 2, 3}, 0)
.SeqNum(0)
.Time(0)
.AsFirstPacket()
.Build()));
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu) RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
.Pps({4, 5, 6}, 0, 0) .Pps({4, 5, 6}, 0, 0)
.SeqNum(1) .SeqNum(1)
.Time(0) .Time(0)
.AsFirstPacket()
.Build())); .Build()));
auto packets = packet_buffer auto packets = packet_buffer
.InsertPacket(H264Packet(kH264SingleNalu) .InsertPacket(H264Packet(kH264SingleNalu)
.Idr({7, 8, 9}, 0) .Idr({7, 8, 9}, 0)
.SeqNum(2) .SeqNum(2)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets; .packets;
@ -561,13 +610,18 @@ TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeIgnoresSprop) {
TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) { TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build())); .Pps()
.SeqNum(0)
.Time(0)
.AsFirstPacket()
.Build()));
EXPECT_THAT(packet_buffer EXPECT_THAT(packet_buffer
.InsertPacket(H264Packet(kH264SingleNalu) .InsertPacket(H264Packet(kH264SingleNalu)
.Idr() .Idr()
.SeqNum(1) .SeqNum(1)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -577,13 +631,18 @@ TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) {
TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) { TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); .Sps()
.SeqNum(0)
.Time(0)
.AsFirstPacket()
.Build()));
EXPECT_THAT(packet_buffer EXPECT_THAT(packet_buffer
.InsertPacket(H264Packet(kH264SingleNalu) .InsertPacket(H264Packet(kH264SingleNalu)
.Idr() .Idr()
.SeqNum(1) .SeqNum(1)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -600,6 +659,7 @@ TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeStapA) {
.Idr() .Idr()
.SeqNum(0) .SeqNum(0)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -615,6 +675,7 @@ TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeStapA) {
.Idr() .Idr()
.SeqNum(0) .SeqNum(0)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -630,6 +691,7 @@ TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeStapA) {
.Idr() .Idr()
.SeqNum(2) .SeqNum(2)
.Time(2) .Time(2)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -642,6 +704,7 @@ TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeStapA) {
.Idr() .Idr()
.SeqNum(3) .SeqNum(3)
.Time(3) .Time(3)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -651,13 +714,22 @@ TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeStapA) {
TEST(H26xPacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) { TEST(H26xPacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build())); .Idr()
.SeqNum(2)
.Time(1)
.AsFirstPacket()
.Marker()
.Build()));
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer .InsertPacket(H264Packet(kH264StapA)
.InsertPacket( .Sps()
H264Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build()) .Pps()
.SeqNum(1)
.Time(1)
.AsFirstPacket()
.Build())
.packets, .packets,
SizeIs(2)); SizeIs(2));
} }
@ -672,6 +744,7 @@ TEST(H26xPacketBufferTest, InsertingMidFuaCompletesFrame) {
.Idr() .Idr()
.SeqNum(0) .SeqNum(0)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -682,6 +755,7 @@ TEST(H26xPacketBufferTest, InsertingMidFuaCompletesFrame) {
.SeqNum(1) .SeqNum(1)
.Time(1) .Time(1)
.AsFirstFragment() .AsFirstFragment()
.AsFirstPacket()
.Build())); .Build()));
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(
H264Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build())); H264Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build()));
@ -702,14 +776,19 @@ TEST(H26xPacketBufferTest, SeqNumJumpDoesNotCompleteFrame) {
.Idr() .Idr()
.SeqNum(0) .SeqNum(0)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
SizeIs(1)); SizeIs(1));
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer .InsertPacket(H264Packet(kH264FuA)
.InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build()) .Slice()
.SeqNum(1)
.Time(1)
.AsFirstPacket()
.Build())
.packets, .packets,
IsEmpty()); IsEmpty());
@ -734,6 +813,7 @@ TEST(H26xPacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) {
.Slice() .Slice()
.SeqNum(1) .SeqNum(1)
.Time(1) .Time(1)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -747,6 +827,7 @@ TEST(H26xPacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) {
.Idr() .Idr()
.SeqNum(kBufferSize) .SeqNum(kBufferSize)
.Time(kBufferSize) .Time(kBufferSize)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -762,6 +843,7 @@ TEST(H26xPacketBufferTest, OldPacketsDontBlockNewPackets) {
.Idr() .Idr()
.SeqNum(kBufferSize) .SeqNum(kBufferSize)
.Time(kBufferSize) .Time(kBufferSize)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -772,6 +854,7 @@ TEST(H26xPacketBufferTest, OldPacketsDontBlockNewPackets) {
.SeqNum(kBufferSize + 1) .SeqNum(kBufferSize + 1)
.Time(kBufferSize + 1) .Time(kBufferSize + 1)
.AsFirstFragment() .AsFirstFragment()
.AsFirstPacket()
.Build())); .Build()));
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA)
@ -806,6 +889,7 @@ TEST(H26xPacketBufferTest, OldPacketDoesntCompleteFrame) {
.Idr() .Idr()
.SeqNum(kBufferSize) .SeqNum(kBufferSize)
.Time(kBufferSize) .Time(kBufferSize)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -834,6 +918,7 @@ TEST(H26xPacketBufferTest, OldPacketDoesntCompleteFrame) {
.SeqNum(kBufferSize + 1) .SeqNum(kBufferSize + 1)
.Time(kBufferSize + 1) .Time(kBufferSize + 1)
.AsFirstFragment() .AsFirstFragment()
.AsFirstPacket()
.Build()) .Build())
.packets, .packets,
IsEmpty()); IsEmpty());
@ -876,13 +961,18 @@ TEST(H26xPacketBufferTest, FrameBoundariesAreSet) {
TEST(H26xPacketBufferTest, ResolutionSetOnFirstPacket) { TEST(H26xPacketBufferTest, ResolutionSetOnFirstPacket) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); .Aud()
.SeqNum(1)
.AsFirstPacket()
.Time(1)
.Build()));
auto res = packet_buffer.InsertPacket(H264Packet(kH264StapA) auto res = packet_buffer.InsertPacket(H264Packet(kH264StapA)
.SpsWithResolution({320, 240}) .SpsWithResolution({320, 240})
.Pps() .Pps()
.Idr() .Idr()
.SeqNum(2) .SeqNum(2)
.AsFirstPacket()
.Time(1) .Time(1)
.Marker() .Marker()
.Build()); .Build());
@ -895,19 +985,29 @@ TEST(H26xPacketBufferTest, ResolutionSetOnFirstPacket) {
TEST(H26xPacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) { TEST(H26xPacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); .Aud()
.SeqNum(1)
.AsFirstPacket()
.Time(1)
.Build()));
auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA) auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA)
.Sps() .Sps()
.Pps() .Pps()
.Idr() .Idr()
.SeqNum(2) .SeqNum(2)
.AsFirstPacket()
.Time(1) .Time(1)
.Marker() .Marker()
.Build()); .Build());
auto delta = packet_buffer.InsertPacket( auto delta = packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build()); .Slice()
.SeqNum(3)
.Time(2)
.AsFirstPacket()
.Marker()
.Build());
ASSERT_THAT(key.packets, SizeIs(2)); ASSERT_THAT(key.packets, SizeIs(2));
EXPECT_THAT(key.packets[0]->video_header.frame_type, EXPECT_THAT(key.packets[0]->video_header.frame_type,
@ -920,11 +1020,20 @@ TEST(H26xPacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) {
TEST(H26xPacketBufferTest, RtpSeqNumWrap) { TEST(H26xPacketBufferTest, RtpSeqNumWrap) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264StapA)
H264Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build())); .Sps()
.Pps()
.SeqNum(0xffff)
.Time(0)
.AsFirstPacket()
.Build()));
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA)
H264Packet(kH264FuA).Idr().SeqNum(0x1'0000).Time(0).Build())); .Idr()
.SeqNum(0x1'0000)
.Time(0)
.AsFirstPacket()
.Build()));
EXPECT_THAT(packet_buffer EXPECT_THAT(packet_buffer
.InsertPacket(H264Packet(kH264FuA) .InsertPacket(H264Packet(kH264FuA)
.Idr() .Idr()
@ -946,6 +1055,7 @@ TEST(H26xPacketBufferTest, StapAFixedBitstream) {
.Idr({7, 8, 9}) .Idr({7, 8, 9})
.SeqNum(0) .SeqNum(0)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets; .packets;
@ -963,15 +1073,24 @@ TEST(H26xPacketBufferTest, StapAFixedBitstream) {
TEST(H26xPacketBufferTest, SingleNaluFixedBitstream) { TEST(H26xPacketBufferTest, SingleNaluFixedBitstream) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED(packet_buffer.InsertPacket( RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
H264Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build())); .Sps({1, 2, 3})
RTC_UNUSED(packet_buffer.InsertPacket( .SeqNum(0)
H264Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build())); .Time(0)
.AsFirstPacket()
.Build()));
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
.Pps({4, 5, 6})
.SeqNum(1)
.Time(0)
.AsFirstPacket()
.Build()));
auto packets = packet_buffer auto packets = packet_buffer
.InsertPacket(H264Packet(kH264SingleNalu) .InsertPacket(H264Packet(kH264SingleNalu)
.Idr({7, 8, 9}) .Idr({7, 8, 9})
.SeqNum(2) .SeqNum(2)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets; .packets;
@ -993,12 +1112,14 @@ TEST(H26xPacketBufferTest, StapaAndFuaFixedBitstream) {
.Pps({4, 5, 6}) .Pps({4, 5, 6})
.SeqNum(0) .SeqNum(0)
.Time(0) .Time(0)
.AsFirstPacket()
.Build())); .Build()));
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA)
.Idr({8, 8, 8}) .Idr({8, 8, 8})
.SeqNum(1) .SeqNum(1)
.Time(0) .Time(0)
.AsFirstFragment() .AsFirstFragment()
.AsFirstPacket()
.Build())); .Build()));
auto packets = packet_buffer auto packets = packet_buffer
.InsertPacket(H264Packet(kH264FuA) .InsertPacket(H264Packet(kH264FuA)
@ -1040,6 +1161,7 @@ TEST(H26xPacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) {
.Idr() .Idr()
.SeqNum(kBufferSize) .SeqNum(kBufferSize)
.Time(1) .Time(1)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -1056,6 +1178,7 @@ TEST(H26xPacketBufferTest, AssembleFrameAfterReordering) {
.Idr() .Idr()
.SeqNum(2) .SeqNum(2)
.Time(2) .Time(2)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -1066,6 +1189,7 @@ TEST(H26xPacketBufferTest, AssembleFrameAfterReordering) {
.Slice() .Slice()
.SeqNum(1) .SeqNum(1)
.Time(1) .Time(1)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -1078,6 +1202,7 @@ TEST(H26xPacketBufferTest, AssembleFrameAfterReordering) {
.Idr() .Idr()
.SeqNum(0) .SeqNum(0)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -1094,6 +1219,7 @@ TEST(H26xPacketBufferTest, AssembleFrameAfterLoss) {
.Idr() .Idr()
.SeqNum(0) .SeqNum(0)
.Time(0) .Time(0)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -1106,6 +1232,7 @@ TEST(H26xPacketBufferTest, AssembleFrameAfterLoss) {
.Idr() .Idr()
.SeqNum(2) .SeqNum(2)
.Time(2) .Time(2)
.AsFirstPacket()
.Marker() .Marker()
.Build()) .Build())
.packets, .packets,
@ -1116,9 +1243,15 @@ TEST(H26xPacketBufferTest, AssembleFrameAfterLoss) {
TEST(H26xPacketBufferTest, H265VpsSpsPpsIdrIsKeyframe) { TEST(H26xPacketBufferTest, H265VpsSpsPpsIdrIsKeyframe) {
H26xPacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer .InsertPacket(H265Packet()
.InsertPacket(H265Packet().Vps().Sps().Pps().Idr().Marker().Build()) .Vps()
.Sps()
.Pps()
.Idr()
.AsFirstPacket()
.Marker()
.Build())
.packets, .packets,
SizeIs(1)); SizeIs(1));
} }
@ -1133,7 +1266,9 @@ TEST(H26xPacketBufferTest, H265IrapIsNotKeyframe) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT( EXPECT_THAT(
packet_buffer.InsertPacket(H265Packet().Slice(type).Marker().Build()) packet_buffer
.InsertPacket(
H265Packet().Slice(type).AsFirstPacket().Marker().Build())
.packets, .packets,
IsEmpty()); IsEmpty());
} }
@ -1143,7 +1278,9 @@ TEST(H26xPacketBufferTest, H265IdrIsNotKeyFrame) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT( EXPECT_THAT(
packet_buffer.InsertPacket(H265Packet().Idr().Marker().Build()).packets, packet_buffer
.InsertPacket(H265Packet().Idr().AsFirstPacket().Marker().Build())
.packets,
IsEmpty()); IsEmpty());
} }
@ -1152,15 +1289,19 @@ TEST(H26xPacketBufferTest, H265IdrIsNotKeyFrameEvenWithSprop) {
packet_buffer.SetSpropParameterSets(kExampleSpropString); packet_buffer.SetSpropParameterSets(kExampleSpropString);
EXPECT_THAT( EXPECT_THAT(
packet_buffer.InsertPacket(H265Packet().Idr().Marker().Build()).packets, packet_buffer
.InsertPacket(H265Packet().Idr().AsFirstPacket().Marker().Build())
.packets,
IsEmpty()); IsEmpty());
} }
TEST(H26xPacketBufferTest, H265SpsPpsIdrIsNotKeyFrame) { TEST(H26xPacketBufferTest, H265SpsPpsIdrIsNotKeyFrame) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT(packet_buffer EXPECT_THAT(
.InsertPacket(H265Packet().Sps().Pps().Idr().Marker().Build()) packet_buffer
.InsertPacket(
H265Packet().Sps().Pps().Idr().AsFirstPacket().Marker().Build())
.packets, .packets,
IsEmpty()); IsEmpty());
} }
@ -1168,8 +1309,10 @@ TEST(H26xPacketBufferTest, H265SpsPpsIdrIsNotKeyFrame) {
TEST(H26xPacketBufferTest, H265VpsPpsIdrIsNotKeyFrame) { TEST(H26xPacketBufferTest, H265VpsPpsIdrIsNotKeyFrame) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT(packet_buffer EXPECT_THAT(
.InsertPacket(H265Packet().Vps().Pps().Idr().Marker().Build()) packet_buffer
.InsertPacket(
H265Packet().Vps().Pps().Idr().AsFirstPacket().Marker().Build())
.packets, .packets,
IsEmpty()); IsEmpty());
} }
@ -1177,8 +1320,10 @@ TEST(H26xPacketBufferTest, H265VpsPpsIdrIsNotKeyFrame) {
TEST(H26xPacketBufferTest, H265VpsSpsIdrIsNotKeyFrame) { TEST(H26xPacketBufferTest, H265VpsSpsIdrIsNotKeyFrame) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT(packet_buffer EXPECT_THAT(
.InsertPacket(H265Packet().Vps().Sps().Idr().Marker().Build()) packet_buffer
.InsertPacket(
H265Packet().Vps().Sps().Idr().AsFirstPacket().Marker().Build())
.packets, .packets,
IsEmpty()); IsEmpty());
} }
@ -1186,8 +1331,9 @@ TEST(H26xPacketBufferTest, H265VpsSpsIdrIsNotKeyFrame) {
TEST(H26xPacketBufferTest, H265VpsIdrIsNotKeyFrame) { TEST(H26xPacketBufferTest, H265VpsIdrIsNotKeyFrame) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer.InsertPacket(H265Packet().Vps().Idr().Marker().Build()) .InsertPacket(
H265Packet().Vps().Idr().AsFirstPacket().Marker().Build())
.packets, .packets,
IsEmpty()); IsEmpty());
} }
@ -1195,8 +1341,9 @@ TEST(H26xPacketBufferTest, H265VpsIdrIsNotKeyFrame) {
TEST(H26xPacketBufferTest, H265SpsIdrIsNotKeyFrame) { TEST(H26xPacketBufferTest, H265SpsIdrIsNotKeyFrame) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer.InsertPacket(H265Packet().Sps().Idr().Marker().Build()) .InsertPacket(
H265Packet().Sps().Idr().AsFirstPacket().Marker().Build())
.packets, .packets,
IsEmpty()); IsEmpty());
} }
@ -1204,8 +1351,9 @@ TEST(H26xPacketBufferTest, H265SpsIdrIsNotKeyFrame) {
TEST(H26xPacketBufferTest, H265PpsIdrIsNotKeyFrame) { TEST(H26xPacketBufferTest, H265PpsIdrIsNotKeyFrame) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
EXPECT_THAT( EXPECT_THAT(packet_buffer
packet_buffer.InsertPacket(H265Packet().Pps().Idr().Marker().Build()) .InsertPacket(
H265Packet().Pps().Idr().AsFirstPacket().Marker().Build())
.packets, .packets,
IsEmpty()); IsEmpty());
} }
@ -1213,8 +1361,8 @@ TEST(H26xPacketBufferTest, H265PpsIdrIsNotKeyFrame) {
TEST(H26xPacketBufferTest, H265ResolutionSetOnSpsPacket) { TEST(H26xPacketBufferTest, H265ResolutionSetOnSpsPacket) {
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
RTC_UNUSED( RTC_UNUSED(packet_buffer.InsertPacket(
packet_buffer.InsertPacket(H265Packet().Aud().SeqNum(1).Time(1).Build())); H265Packet().Aud().SeqNum(1).Time(1).AsFirstPacket().Build()));
auto res = packet_buffer.InsertPacket(H265Packet() auto res = packet_buffer.InsertPacket(H265Packet()
.Vps() .Vps()
.SpsWithResolution({320, 240}) .SpsWithResolution({320, 240})
@ -1222,6 +1370,7 @@ TEST(H26xPacketBufferTest, H265ResolutionSetOnSpsPacket) {
.Idr() .Idr()
.SeqNum(2) .SeqNum(2)
.Time(1) .Time(1)
.AsFirstPacket()
.Marker() .Marker()
.Build()); .Build());
@ -1237,8 +1386,14 @@ TEST(H26xPacketBufferTest, H265InsertingVpsSpsPpsLastCompletesKeyframe) {
H265Packet().Idr().SeqNum(2).Time(1).Marker().Build())); H265Packet().Idr().SeqNum(2).Time(1).Marker().Build()));
EXPECT_THAT(packet_buffer EXPECT_THAT(packet_buffer
.InsertPacket( .InsertPacket(H265Packet()
H265Packet().Vps().Sps().Pps().SeqNum(1).Time(1).Build()) .Vps()
.Sps()
.Pps()
.SeqNum(1)
.Time(1)
.AsFirstPacket()
.Build())
.packets, .packets,
SizeIs(2)); SizeIs(2));
} }