commit 5fefd8a3c31124500b239226e3be0e060c980b24
parent 2d2804e92a8f4e374438c81448de9718999f5626
Author: Dan Baker <dbaker@mozilla.com>
Date: Mon, 27 Oct 2025 11:44:05 -0600
Bug 1995393 - Vendor libwebrtc from 8e80e5b0c7
Upstream commit: https://webrtc.googlesource.com/src/+/8e80e5b0c74763cf9cf388c5fe7e08c1560f8231
In RtpPacketizerH265 respect single packet reduction length
When trying to packetize multiple NAL units into single aggregation packet
Bug: chromium:439889659
Change-Id: I394332697d63b78a1cbd5f0bbb97203bb58feffb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/405540
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#45415}
Diffstat:
3 files changed, 57 insertions(+), 28 deletions(-)
diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor
@@ -1,4 +1,4 @@
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
-libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-27T17:41:31.035918+00:00.
+libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-27T17:43:49.272323+00:00.
# base of lastest vendoring
-b62361bfe9
+8e80e5b0c7
diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_packetizer_h265.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_packetizer_h265.cc
@@ -140,12 +140,8 @@ bool RtpPacketizerH265::PacketizeFu(size_t fragment_index) {
int RtpPacketizerH265::PacketizeAp(size_t fragment_index) {
// Aggregate fragments into one packet.
+ const bool includes_first = fragment_index == 0;
size_t payload_size_left = limits_.max_payload_len;
- if (input_fragments_.size() == 1) {
- payload_size_left -= limits_.single_packet_reduction_len;
- } else if (fragment_index == 0) {
- payload_size_left -= limits_.first_packet_reduction_len;
- }
int aggregated_fragments = 0;
size_t fragment_headers_length = 0;
ArrayView<const uint8_t> fragment = input_fragments_[fragment_index];
@@ -154,16 +150,16 @@ int RtpPacketizerH265::PacketizeAp(size_t fragment_index) {
auto payload_size_needed = [&] {
size_t fragment_size = fragment.size() + fragment_headers_length;
- if (input_fragments_.size() == 1) {
- // Single fragment, single packet, payload_size_left already adjusted
- // with limits_.single_packet_reduction_len.
- return fragment_size;
- }
- if (fragment_index == input_fragments_.size() - 1) {
- // Last fragment, so this might be the last packet.
+ bool includes_last = (fragment_index == input_fragments_.size() - 1);
+ if (includes_first && includes_last) {
+ return fragment_size + limits_.single_packet_reduction_len;
+ } else if (includes_first) {
+ return fragment_size + limits_.first_packet_reduction_len;
+ } else if (includes_last) {
return fragment_size + limits_.last_packet_reduction_len;
+ } else {
+ return fragment_size;
}
- return fragment_size;
};
uint16_t header = (fragment[0] << 8) | fragment[1];
diff --git a/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_packetizer_h265_unittest.cc b/third_party/libwebrtc/modules/rtp_rtcp/source/rtp_packetizer_h265_unittest.cc
@@ -210,18 +210,30 @@ TEST(RtpPacketizerH265Test,
EXPECT_THAT(packets[2].payload(), ElementsAreArray(nalus[2]));
}
-TEST(RtpPacketizerH265Test,
- SingleNaluFirstAndLastPacketReductionSumsForSinglePacket) {
+TEST(RtpPacketizerH265Test, SingleNaluUsesSinglePacketReductionLen) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 200;
limits.first_packet_reduction_len = 20;
+ limits.single_packet_reduction_len = 40;
limits.last_packet_reduction_len = 30;
- Buffer frame = CreateFrame({150});
+ Buffer frame = CreateFrame({160});
+
+ RtpPacketizerH265 packetizer(frame, limits);
+
+ EXPECT_THAT(FetchAllPackets(&packetizer), SizeIs(1));
+}
+
+TEST(RtpPacketizerH265Test, FragmentsNalUnitWhenDoesntFitIntoSinglePacket) {
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = 200;
+ limits.first_packet_reduction_len = 10;
+ limits.single_packet_reduction_len = 40;
+ limits.last_packet_reduction_len = 10;
+ Buffer frame = CreateFrame({170});
RtpPacketizerH265 packetizer(frame, limits);
- std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
- EXPECT_THAT(packets, SizeIs(1));
+ EXPECT_THAT(FetchAllPackets(&packetizer), SizeIs(2));
}
// Aggregation tests.
@@ -324,6 +336,19 @@ TEST(RtpPacketizerH265Test, ApRespectsLayerIdAndTemporalId) {
ElementsAreArray(nalus[2]));
}
+TEST(RtpPacketizerH265Test, ApRespectsSinglePacketReduction) {
+ RtpPacketizer::PayloadSizeLimits limits;
+ limits.max_payload_len = 200;
+ limits.first_packet_reduction_len = 5;
+ limits.single_packet_reduction_len = 40;
+ limits.last_packet_reduction_len = 5;
+ Buffer frame = CreateFrame({60, 60, 60});
+
+ RtpPacketizerH265 packetizer(frame, limits);
+
+ EXPECT_THAT(FetchAllPackets(&packetizer), SizeIs(2));
+}
+
TEST(RtpPacketizerH265Test, ApRespectsFirstPacketReduction) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 1000;
@@ -367,7 +392,13 @@ TEST(RtpPacketizerH265Test, ApRespectsLastPacketReduction) {
limits.last_packet_reduction_len = 100;
const size_t kLastFragmentSize =
limits.max_payload_len - limits.last_packet_reduction_len;
- Buffer nalus[] = {GenerateNalUnit({.nal_unit_type = H265::NaluType::kIdrNLp,
+ // First nalu forces packetizer to consider last packet reduction len instead
+ // of single packet reduction len when aggregating last 3 nalus.
+ Buffer nalus[] = {GenerateNalUnit({.nal_unit_type = H265::NaluType::kSps,
+ .nuh_layer_id = 32,
+ .nuh_temporal_id_plus1 = 2},
+ /*size=*/999),
+ GenerateNalUnit({.nal_unit_type = H265::NaluType::kIdrNLp,
.nuh_layer_id = 32,
.nuh_temporal_id_plus1 = 2},
/*size=*/3),
@@ -384,14 +415,16 @@ TEST(RtpPacketizerH265Test, ApRespectsLastPacketReduction) {
RtpPacketizerH265 packetizer(frame, limits);
std::vector<RtpPacketToSend> packets = FetchAllPackets(&packetizer);
- ASSERT_THAT(packets, SizeIs(2));
- // Expect 1st packet is aggregate of 1st two fragments.
- EXPECT_THAT(packets[0].payload(),
+ ASSERT_THAT(packets, SizeIs(3));
+ // Expect 1st packet is single nalu with the 1st fragment.
+ EXPECT_THAT(packets[0].payload(), ElementsAreArray(nalus[0]));
+ // Expect 2nd packet is aggregate of 2nd and 3rd fragments.
+ EXPECT_THAT(packets[1].payload(),
ElementsAre(97, 2, //
- 0, 3, nalus[0][0], nalus[0][1], nalus[0][2], //
- 0, 3, nalus[1][0], nalus[1][1], nalus[1][2]));
- // Expect 2nd packet is single nalu.
- EXPECT_THAT(packets[1].payload(), ElementsAreArray(nalus[2]));
+ 0, 3, nalus[1][0], nalus[1][1], nalus[1][2], //
+ 0, 3, nalus[2][0], nalus[2][1], nalus[2][2]));
+ // Expect 3rd packet is single nalu with the last fragment.
+ EXPECT_THAT(packets[2].payload(), ElementsAreArray(nalus[3]));
}
TEST(RtpPacketizerH265Test, TooSmallForApHeaders) {