Bug 1952339 - Vendor libwebrtc from 9be7d14046

Upstream commit: https://webrtc.googlesource.com/src/+/9be7d14046b45d84e8466d85369395fdf77ef105
    Clean up AV1 packetization

    now that the "even split" has launched successfully.
    Renames
      Packetize to PacketizeInternal
    and
      PacketizeAboutEqually to Packetize

    BUG=webrtc:42226301

    Change-Id: I6ef6382a690b5f6dc2e8809ae80f9bf99dd38a75
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/378780
    Commit-Queue: Erik Språng <sprang@webrtc.org>
    Reviewed-by: Erik Språng <sprang@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#43996}

Differential Revision: https://phabricator.services.mozilla.com/D244004
This commit is contained in:
Michael Froman
2025-03-07 16:46:44 -06:00
parent 85ee873b2b
commit 684c3771a8
13 changed files with 79 additions and 105 deletions

View File

@@ -1,4 +1,4 @@
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-03-07T22:45:41.458126+00:00.
libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-03-07T22:46:33.385029+00:00.
# base of lastest vendoring
f30c044cf9
9be7d14046

View File

@@ -170,9 +170,6 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([
FieldTrial('WebRTC-VP9-SvcForSimulcast',
347737882,
date(2024, 10, 1)),
FieldTrial('WebRTC-Video-AV1EvenPayloadSizes',
42226301,
date(2024, 11, 1)),
FieldTrial('WebRTC-Video-EnableRetransmitAllLayers',
42225262,
date(2024, 4, 1)),

View File

@@ -10,9 +10,14 @@
#include "modules/rtp_rtcp/source/rtp_format.h"
#include <cstdint>
#include <memory>
#include <optional>
#include <vector>
#include "absl/types/variant.h"
#include "api/array_view.h"
#include "api/video/video_codec_type.h"
#include "modules/rtp_rtcp/source/rtp_format_h264.h"
#include "modules/rtp_rtcp/source/rtp_format_video_generic.h"
#include "modules/rtp_rtcp/source/rtp_format_vp8.h"
@@ -33,8 +38,7 @@ std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
// Codec-specific details.
const RTPVideoHeader& rtp_video_header,
bool enable_av1_even_split) {
const RTPVideoHeader& rtp_video_header) {
if (!type) {
// Use raw packetizer.
return std::make_unique<RtpPacketizerGeneric>(payload, limits);
@@ -60,7 +64,7 @@ std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
case kVideoCodecAV1:
return std::make_unique<RtpPacketizerAv1>(
payload, limits, rtp_video_header.frame_type,
rtp_video_header.is_last_frame_in_picture, enable_av1_even_split);
rtp_video_header.is_last_frame_in_picture);
#ifdef RTC_ENABLE_H265
case kVideoCodecH265: {
return std::make_unique<RtpPacketizerH265>(payload, limits);

View File

@@ -13,11 +13,13 @@
#include <stdint.h>
#include <cstddef>
#include <memory>
#include <optional>
#include <vector>
#include "api/array_view.h"
#include "api/video/video_codec_type.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
namespace webrtc {
@@ -40,9 +42,7 @@ class RtpPacketizer {
rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
// Codec-specific details.
const RTPVideoHeader& rtp_video_header,
// TODO: bugs.webrtc.org/42226301 - remove after rollout.
bool enable_av1_even_split = true);
const RTPVideoHeader& rtp_video_header);
virtual ~RtpPacketizer() = default;

View File

@@ -13,10 +13,13 @@
#include <stdint.h>
#include <algorithm>
#include <cstring>
#include <vector>
#include "api/array_view.h"
#include "api/video/video_frame_type.h"
#include "modules/rtp_rtcp/source/leb128.h"
#include "modules/rtp_rtcp/source/rtp_format.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "rtc_base/byte_buffer.h"
#include "rtc_base/checks.h"
@@ -71,12 +74,10 @@ int MaxFragmentSize(int remaining_bytes) {
RtpPacketizerAv1::RtpPacketizerAv1(rtc::ArrayView<const uint8_t> payload,
RtpPacketizer::PayloadSizeLimits limits,
VideoFrameType frame_type,
bool is_last_frame_in_picture,
bool even_distribution)
bool is_last_frame_in_picture)
: frame_type_(frame_type),
obus_(ParseObus(payload)),
packets_(even_distribution ? PacketizeAboutEqually(obus_, limits)
: Packetize(obus_, limits)),
packets_(Packetize(obus_, limits)),
is_last_frame_in_picture_(is_last_frame_in_picture) {}
std::vector<RtpPacketizerAv1::Obu> RtpPacketizerAv1::ParseObus(
@@ -146,7 +147,7 @@ int RtpPacketizerAv1::AdditionalBytesForPreviousObuElement(
return Leb128Size(packet.last_obu_size);
}
std::vector<RtpPacketizerAv1::Packet> RtpPacketizerAv1::Packetize(
std::vector<RtpPacketizerAv1::Packet> RtpPacketizerAv1::PacketizeInternal(
rtc::ArrayView<const Obu> obus,
PayloadSizeLimits limits) {
std::vector<Packet> packets;
@@ -299,10 +300,10 @@ std::vector<RtpPacketizerAv1::Packet> RtpPacketizerAv1::Packetize(
return packets;
}
std::vector<RtpPacketizerAv1::Packet> RtpPacketizerAv1::PacketizeAboutEqually(
std::vector<RtpPacketizerAv1::Packet> RtpPacketizerAv1::Packetize(
rtc::ArrayView<const Obu> obus,
PayloadSizeLimits limits) {
std::vector<Packet> packets = Packetize(obus, limits);
std::vector<Packet> packets = PacketizeInternal(obus, limits);
if (packets.size() <= 1) {
return packets;
}
@@ -334,7 +335,7 @@ std::vector<RtpPacketizerAv1::Packet> RtpPacketizerAv1::PacketizeAboutEqually(
limits.max_payload_len - limits.first_packet_reduction_len < 3) {
return packets;
}
std::vector<Packet> packets_even = Packetize(obus, limits);
std::vector<Packet> packets_even = PacketizeInternal(obus, limits);
// The number of packets should not change in the second pass. If it does,
// conservatively return the original packets.
if (packets_even.size() == packets.size()) {

View File

@@ -27,8 +27,7 @@ class RtpPacketizerAv1 : public RtpPacketizer {
RtpPacketizerAv1(rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
VideoFrameType frame_type,
bool is_last_frame_in_picture,
bool even_distribution = true);
bool is_last_frame_in_picture);
~RtpPacketizerAv1() override = default;
size_t NumPackets() const override { return packets_.size() - packet_index_; }
@@ -58,10 +57,9 @@ class RtpPacketizerAv1 : public RtpPacketizer {
// Returns the number of additional bytes needed to store the previous OBU
// element if an additonal OBU element is added to the packet.
static int AdditionalBytesForPreviousObuElement(const Packet& packet);
static std::vector<Packet> PacketizeInternal(rtc::ArrayView<const Obu> obus,
PayloadSizeLimits limits);
// Packetize and try to distribute the payload evenly across packets.
static std::vector<Packet> PacketizeAboutEqually(
rtc::ArrayView<const Obu> obus,
PayloadSizeLimits limits);
static std::vector<Packet> Packetize(rtc::ArrayView<const Obu> obus,
PayloadSizeLimits limits);

View File

@@ -14,6 +14,7 @@
#include <stdint.h>
#include <initializer_list>
#include <utility>
#include <vector>
namespace webrtc {

View File

@@ -14,7 +14,6 @@
#include <stdint.h>
#include <initializer_list>
#include <utility>
#include <vector>
namespace webrtc {

View File

@@ -20,6 +20,8 @@
#include "api/array_view.h"
#include "api/scoped_refptr.h"
#include "api/video/encoded_image.h"
#include "api/video/video_frame_type.h"
#include "modules/rtp_rtcp/source/rtp_format.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "modules/rtp_rtcp/source/rtp_packetizer_av1_test_helper.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h"
@@ -78,12 +80,11 @@ class Av1Frame {
std::vector<RtpPayload> Packetize(
rtc::ArrayView<const uint8_t> payload,
RtpPacketizer::PayloadSizeLimits limits,
bool even_distribution,
VideoFrameType frame_type = VideoFrameType::kVideoFrameDelta,
bool is_last_frame_in_picture = true) {
// Run code under test.
RtpPacketizerAv1 packetizer(payload, limits, frame_type,
is_last_frame_in_picture, even_distribution);
is_last_frame_in_picture);
// Convert result into structure that is easier to run expectation against.
std::vector<RtpPayload> result(packetizer.NumPackets());
for (RtpPayload& rtp_payload : result) {
@@ -100,63 +101,59 @@ Av1Frame ReassembleFrame(rtc::ArrayView<const RtpPayload> rtp_payloads) {
return Av1Frame(VideoRtpDepacketizerAv1().AssembleFrame(payloads));
}
class RtpPacketizerAv1Test : public ::testing::TestWithParam<bool> {};
TEST_P(RtpPacketizerAv1Test, EmptyPayload) {
TEST(RtpPacketizerAv1Test, EmptyPayload) {
RtpPacketizer::PayloadSizeLimits limits;
RtpPacketizerAv1 packetizer({}, limits, VideoFrameType::kVideoFrameKey, true,
GetParam());
RtpPacketizerAv1 packetizer({}, limits, VideoFrameType::kVideoFrameKey, true);
EXPECT_EQ(packetizer.NumPackets(), 0u);
}
TEST_P(RtpPacketizerAv1Test, PacketizeOneObuWithoutSizeAndExtension) {
TEST(RtpPacketizerAv1Test, PacketizeOneObuWithoutSizeAndExtension) {
auto kFrame = BuildAv1Frame({Av1Obu(kAv1ObuTypeFrame)
.WithoutSize()
.WithPayload({1, 2, 3, 4, 5, 6, 7})});
EXPECT_THAT(Packetize(kFrame, {}, GetParam()),
EXPECT_THAT(Packetize(kFrame, {}),
ElementsAre(ElementsAre(0b00'01'0000, // aggregation header
kAv1ObuTypeFrame, 1, 2, 3, 4, 5, 6, 7)));
}
TEST_P(RtpPacketizerAv1Test, PacketizeOneObuWithoutSizeWithExtension) {
TEST(RtpPacketizerAv1Test, PacketizeOneObuWithoutSizeWithExtension) {
auto kFrame = BuildAv1Frame({Av1Obu(kAv1ObuTypeFrame)
.WithoutSize()
.WithExtension(kAv1ObuExtensionS1T1)
.WithPayload({2, 3, 4, 5, 6, 7})});
EXPECT_THAT(
Packetize(kFrame, {}, GetParam()),
Packetize(kFrame, {}),
ElementsAre(ElementsAre(0b00'01'0000, // aggregation header
kAv1ObuTypeFrame | kAv1ObuExtensionPresentBit,
kAv1ObuExtensionS1T1, 2, 3, 4, 5, 6, 7)));
}
TEST_P(RtpPacketizerAv1Test, RemovesObuSizeFieldWithoutExtension) {
TEST(RtpPacketizerAv1Test, RemovesObuSizeFieldWithoutExtension) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeFrame).WithPayload({11, 12, 13, 14, 15, 16, 17})});
EXPECT_THAT(
Packetize(kFrame, {}, GetParam()),
Packetize(kFrame, {}),
ElementsAre(ElementsAre(0b00'01'0000, // aggregation header
kAv1ObuTypeFrame, 11, 12, 13, 14, 15, 16, 17)));
}
TEST_P(RtpPacketizerAv1Test, RemovesObuSizeFieldWithExtension) {
TEST(RtpPacketizerAv1Test, RemovesObuSizeFieldWithExtension) {
auto kFrame = BuildAv1Frame({Av1Obu(kAv1ObuTypeFrame)
.WithExtension(kAv1ObuExtensionS1T1)
.WithPayload({1, 2, 3, 4, 5, 6, 7})});
EXPECT_THAT(
Packetize(kFrame, {}, GetParam()),
Packetize(kFrame, {}),
ElementsAre(ElementsAre(0b00'01'0000, // aggregation header
kAv1ObuTypeFrame | kAv1ObuExtensionPresentBit,
kAv1ObuExtensionS1T1, 1, 2, 3, 4, 5, 6, 7)));
}
TEST_P(RtpPacketizerAv1Test,
OmitsSizeForLastObuWhenThreeObusFitsIntoThePacket) {
TEST(RtpPacketizerAv1Test, OmitsSizeForLastObuWhenThreeObusFitsIntoThePacket) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeSequenceHeader).WithPayload({1, 2, 3, 4, 5, 6}),
Av1Obu(kAv1ObuTypeMetadata).WithPayload({11, 12, 13, 14}),
Av1Obu(kAv1ObuTypeFrame).WithPayload({21, 22, 23, 24, 25, 26})});
EXPECT_THAT(Packetize(kFrame, {}, GetParam()),
EXPECT_THAT(Packetize(kFrame, {}),
ElementsAre(ElementsAre(
0b00'11'0000, // aggregation header
7, kAv1ObuTypeSequenceHeader, 1, 2, 3, 4, 5, 6, //
@@ -164,13 +161,13 @@ TEST_P(RtpPacketizerAv1Test,
kAv1ObuTypeFrame, 21, 22, 23, 24, 25, 26)));
}
TEST_P(RtpPacketizerAv1Test, UseSizeForAllObusWhenFourObusFitsIntoThePacket) {
TEST(RtpPacketizerAv1Test, UseSizeForAllObusWhenFourObusFitsIntoThePacket) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeSequenceHeader).WithPayload({1, 2, 3, 4, 5, 6}),
Av1Obu(kAv1ObuTypeMetadata).WithPayload({11, 12, 13, 14}),
Av1Obu(kAv1ObuTypeFrameHeader).WithPayload({21, 22, 23}),
Av1Obu(kAv1ObuTypeTileGroup).WithPayload({31, 32, 33, 34, 35, 36})});
EXPECT_THAT(Packetize(kFrame, {}, GetParam()),
EXPECT_THAT(Packetize(kFrame, {}),
ElementsAre(ElementsAre(
0b00'00'0000, // aggregation header
7, kAv1ObuTypeSequenceHeader, 1, 2, 3, 4, 5, 6, //
@@ -179,7 +176,7 @@ TEST_P(RtpPacketizerAv1Test, UseSizeForAllObusWhenFourObusFitsIntoThePacket) {
7, kAv1ObuTypeTileGroup, 31, 32, 33, 34, 35, 36)));
}
TEST_P(RtpPacketizerAv1Test, DiscardsTemporalDelimiterAndTileListObu) {
TEST(RtpPacketizerAv1Test, DiscardsTemporalDelimiterAndTileListObu) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeTemporalDelimiter), Av1Obu(kAv1ObuTypeMetadata),
Av1Obu(kAv1ObuTypeTileList).WithPayload({1, 2, 3, 4, 5, 6}),
@@ -187,7 +184,7 @@ TEST_P(RtpPacketizerAv1Test, DiscardsTemporalDelimiterAndTileListObu) {
Av1Obu(kAv1ObuTypeTileGroup).WithPayload({31, 32, 33, 34, 35, 36})});
EXPECT_THAT(
Packetize(kFrame, {}, GetParam()),
Packetize(kFrame, {}),
ElementsAre(ElementsAre(0b00'11'0000, // aggregation header
1,
kAv1ObuTypeMetadata, //
@@ -196,7 +193,7 @@ TEST_P(RtpPacketizerAv1Test, DiscardsTemporalDelimiterAndTileListObu) {
kAv1ObuTypeTileGroup, 31, 32, 33, 34, 35, 36)));
}
TEST_P(RtpPacketizerAv1Test, SplitTwoObusIntoTwoPacketForceSplitObuHeader) {
TEST(RtpPacketizerAv1Test, SplitTwoObusIntoTwoPacketForceSplitObuHeader) {
// Craft expected payloads so that there is only one way to split original
// frame into two packets.
const uint8_t kExpectPayload1[6] = {
@@ -217,45 +214,42 @@ TEST_P(RtpPacketizerAv1Test, SplitTwoObusIntoTwoPacketForceSplitObuHeader) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 6;
auto payloads = Packetize(kFrame, limits, GetParam());
auto payloads = Packetize(kFrame, limits);
EXPECT_THAT(payloads, ElementsAre(ElementsAreArray(kExpectPayload1),
ElementsAreArray(kExpectPayload2)));
}
TEST_P(RtpPacketizerAv1Test,
SetsNbitAtTheFirstPacketOfAKeyFrameWithSequenceHeader) {
TEST(RtpPacketizerAv1Test,
SetsNbitAtTheFirstPacketOfAKeyFrameWithSequenceHeader) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeSequenceHeader).WithPayload({1, 2, 3, 4, 5, 6, 7})});
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 6;
auto packets =
Packetize(kFrame, limits, GetParam(), VideoFrameType::kVideoFrameKey);
auto packets = Packetize(kFrame, limits, VideoFrameType::kVideoFrameKey);
ASSERT_THAT(packets, SizeIs(2));
EXPECT_TRUE(packets[0].aggregation_header() & kNewCodedVideoSequenceBit);
EXPECT_FALSE(packets[1].aggregation_header() & kNewCodedVideoSequenceBit);
}
TEST_P(RtpPacketizerAv1Test,
DoesntSetNbitAtThePacketsOfAKeyFrameWithoutSequenceHeader) {
TEST(RtpPacketizerAv1Test,
DoesntSetNbitAtThePacketsOfAKeyFrameWithoutSequenceHeader) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeFrame).WithPayload({1, 2, 3, 4, 5, 6, 7})});
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 6;
auto packets =
Packetize(kFrame, limits, GetParam(), VideoFrameType::kVideoFrameKey);
auto packets = Packetize(kFrame, limits, VideoFrameType::kVideoFrameKey);
ASSERT_THAT(packets, SizeIs(2));
EXPECT_FALSE(packets[0].aggregation_header() & kNewCodedVideoSequenceBit);
EXPECT_FALSE(packets[1].aggregation_header() & kNewCodedVideoSequenceBit);
}
TEST_P(RtpPacketizerAv1Test, DoesntSetNbitAtThePacketsOfADeltaFrame) {
TEST(RtpPacketizerAv1Test, DoesntSetNbitAtThePacketsOfADeltaFrame) {
// Even when that delta frame starts with a (redundant) sequence header.
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeSequenceHeader).WithPayload({1, 2, 3, 4, 5, 6, 7})});
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 6;
auto packets =
Packetize(kFrame, limits, GetParam(), VideoFrameType::kVideoFrameDelta);
auto packets = Packetize(kFrame, limits, VideoFrameType::kVideoFrameDelta);
ASSERT_THAT(packets, SizeIs(2));
EXPECT_FALSE(packets[0].aggregation_header() & kNewCodedVideoSequenceBit);
EXPECT_FALSE(packets[1].aggregation_header() & kNewCodedVideoSequenceBit);
@@ -266,27 +260,27 @@ TEST_P(RtpPacketizerAv1Test, DoesntSetNbitAtThePacketsOfADeltaFrame) {
// to validate frame is reconstracted to the same one. Note: since
// RtpDepacketizer always inserts obu_size fields in the output, use frame where
// each obu has obu_size fields for more streight forward validation.
TEST_P(RtpPacketizerAv1Test, SplitSingleObuIntoTwoPackets) {
TEST(RtpPacketizerAv1Test, SplitSingleObuIntoTwoPackets) {
auto kFrame =
BuildAv1Frame({Av1Obu(kAv1ObuTypeFrame)
.WithPayload({11, 12, 13, 14, 15, 16, 17, 18, 19})});
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 8;
auto payloads = Packetize(kFrame, limits, GetParam());
auto payloads = Packetize(kFrame, limits);
EXPECT_THAT(payloads, ElementsAre(SizeIs(Le(8u)), SizeIs(Le(8u))));
// Use RtpDepacketizer to validate the split.
EXPECT_THAT(ReassembleFrame(payloads), ElementsAreArray(kFrame));
}
TEST_P(RtpPacketizerAv1Test, SplitSingleObuIntoManyPackets) {
TEST(RtpPacketizerAv1Test, SplitSingleObuIntoManyPackets) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeFrame).WithPayload(std::vector<uint8_t>(1200, 27))});
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 100;
auto payloads = Packetize(kFrame, limits, GetParam());
auto payloads = Packetize(kFrame, limits);
EXPECT_THAT(payloads, SizeIs(13u));
EXPECT_THAT(payloads, Each(SizeIs(Le(100u))));
@@ -294,38 +288,35 @@ TEST_P(RtpPacketizerAv1Test, SplitSingleObuIntoManyPackets) {
EXPECT_THAT(ReassembleFrame(payloads), ElementsAreArray(kFrame));
}
TEST_P(RtpPacketizerAv1Test, SetMarkerBitForLastPacketInEndOfPictureFrame) {
TEST(RtpPacketizerAv1Test, SetMarkerBitForLastPacketInEndOfPictureFrame) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeFrame).WithPayload(std::vector<uint8_t>(200, 27))});
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 100;
auto payloads =
Packetize(kFrame, limits, GetParam(), VideoFrameType::kVideoFrameDelta,
/*is_last_frame_in_picture=*/true);
auto payloads = Packetize(kFrame, limits, VideoFrameType::kVideoFrameDelta,
/*is_last_frame_in_picture=*/true);
ASSERT_THAT(payloads, SizeIs(3u));
EXPECT_FALSE(payloads[0].rtp_packet.Marker());
EXPECT_FALSE(payloads[1].rtp_packet.Marker());
EXPECT_TRUE(payloads[2].rtp_packet.Marker());
}
TEST_P(RtpPacketizerAv1Test,
DoesntSetMarkerBitForPacketsNotInEndOfPictureFrame) {
TEST(RtpPacketizerAv1Test, DoesntSetMarkerBitForPacketsNotInEndOfPictureFrame) {
auto kFrame = BuildAv1Frame(
{Av1Obu(kAv1ObuTypeFrame).WithPayload(std::vector<uint8_t>(200, 27))});
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 100;
auto payloads =
Packetize(kFrame, limits, GetParam(), VideoFrameType::kVideoFrameDelta,
/*is_last_frame_in_picture=*/false);
auto payloads = Packetize(kFrame, limits, VideoFrameType::kVideoFrameDelta,
/*is_last_frame_in_picture=*/false);
ASSERT_THAT(payloads, SizeIs(3u));
EXPECT_FALSE(payloads[0].rtp_packet.Marker());
EXPECT_FALSE(payloads[1].rtp_packet.Marker());
EXPECT_FALSE(payloads[2].rtp_packet.Marker());
}
TEST_P(RtpPacketizerAv1Test, SplitTwoObusIntoTwoPackets) {
TEST(RtpPacketizerAv1Test, SplitTwoObusIntoTwoPackets) {
// 2nd OBU is too large to fit into one packet, so its head would be in the
// same packet as the 1st OBU.
auto kFrame = BuildAv1Frame(
@@ -334,42 +325,35 @@ TEST_P(RtpPacketizerAv1Test, SplitTwoObusIntoTwoPackets) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 8;
auto payloads = Packetize(kFrame, limits, GetParam());
auto payloads = Packetize(kFrame, limits);
EXPECT_THAT(payloads, ElementsAre(SizeIs(Le(8u)), SizeIs(Le(8u))));
// Use RtpDepacketizer to validate the split.
EXPECT_THAT(ReassembleFrame(payloads), ElementsAreArray(kFrame));
}
TEST_P(RtpPacketizerAv1Test,
SplitSingleObuIntoTwoPacketsBecauseOfSinglePacketLimit) {
TEST(RtpPacketizerAv1Test,
SplitSingleObuIntoTwoPacketsBecauseOfSinglePacketLimit) {
auto kFrame =
BuildAv1Frame({Av1Obu(kAv1ObuTypeFrame)
.WithPayload({11, 12, 13, 14, 15, 16, 17, 18, 19})});
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = 10;
limits.single_packet_reduction_len = 8;
auto payloads = Packetize(kFrame, limits, GetParam());
auto payloads = Packetize(kFrame, limits);
EXPECT_THAT(payloads, ElementsAre(SizeIs(Le(10u)), SizeIs(Le(10u))));
EXPECT_THAT(ReassembleFrame(payloads), ElementsAreArray(kFrame));
}
INSTANTIATE_TEST_SUITE_P(bool, RtpPacketizerAv1Test, ::testing::Bool());
TEST(RtpPacketizerAv1TestEven, EvenDistributionDiffers) {
TEST(RtpPacketizerAv1TestEven, EvenDistribution) {
auto kFrame = BuildAv1Frame({
Av1Obu(kAv1ObuTypeFrame).WithPayload(std::vector<uint8_t>(1206, 0)),
Av1Obu(kAv1ObuTypeFrame).WithPayload(std::vector<uint8_t>(1476, 0)),
Av1Obu(kAv1ObuTypeFrame).WithPayload(std::vector<uint8_t>(1431, 0)),
});
EXPECT_THAT(
Packetize(kFrame, {}, /*even_distribution=*/false),
ElementsAre(SizeIs(1200), SizeIs(1200), SizeIs(1200), SizeIs(523)));
EXPECT_THAT(
Packetize(kFrame, {}, /*even_distribution=*/true),
ElementsAre(SizeIs(1032), SizeIs(1032), SizeIs(1032), SizeIs(1028)));
EXPECT_THAT(Packetize(kFrame, {}), ElementsAre(SizeIs(1032), SizeIs(1032),
SizeIs(1032), SizeIs(1028)));
}
} // namespace

View File

@@ -191,10 +191,7 @@ RTPSenderVideo::RTPSenderVideo(const Config& config)
rtp_sender_->SSRC(),
rtp_sender_->Rid(),
config.task_queue_factory)
: nullptr),
// TODO: bugs.webrtc.org/42226301 - Remove when fully launched.
enable_av1_even_split_(!config.field_trials->IsDisabled(
"WebRTC-Video-AV1EvenPayloadSizes")) {
: nullptr) {
if (frame_transformer_delegate_)
frame_transformer_delegate_->Init();
}
@@ -699,8 +696,8 @@ bool RTPSenderVideo::SendVideo(int payload_type,
"one is required since require_frame_encryptor is set";
}
std::unique_ptr<RtpPacketizer> packetizer = RtpPacketizer::Create(
codec_type, payload, limits, video_header, enable_av1_even_split_);
std::unique_ptr<RtpPacketizer> packetizer =
RtpPacketizer::Create(codec_type, payload, limits, video_header);
const size_t num_packets = packetizer->NumPackets();

View File

@@ -256,10 +256,6 @@ class RTPSenderVideo : public RTPVideoFrameSenderInterface {
const rtc::scoped_refptr<RTPSenderVideoFrameTransformerDelegate>
frame_transformer_delegate_;
// Whether to do two-pass packetization for AV1 which leads to a set of
// packets with more even size distribution.
const bool enable_av1_even_split_;
};
} // namespace webrtc

View File

@@ -45,7 +45,7 @@ index 0a29968b0c..c23051401e 100644
return flexfec_ssrc_;
}
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index 9ba860836a..27f262f880 100644
index 7fbfe65099..ca2f0168c9 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -189,6 +189,7 @@ RTPSenderVideo::RTPSenderVideo(const Config& config)
@@ -54,8 +54,8 @@ index 9ba860836a..27f262f880 100644
rtp_sender_->SSRC(),
+ rtp_sender_->Rid(),
config.task_queue_factory)
: nullptr),
// TODO: bugs.webrtc.org/42226301 - Remove when fully launched.
: nullptr) {
if (frame_transformer_delegate_)
diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc
index d119fdcecf..3ebfe1c742 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.cc

View File

@@ -35,12 +35,9 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
VideoFrameType frame_type = fuzz_input.SelectOneOf(kFrameTypes);
// Main function under test: RtpPacketizerAv1's constructor.
// "even distribution" is transitional and still exercises the other code path
// so does not require another fuzzer.
RtpPacketizerAv1 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()),
limits, frame_type,
/*is_last_frame_in_picture=*/true,
/*even_distribution=*/true);
/*is_last_frame_in_picture=*/true);
size_t num_packets = packetizer.NumPackets();
if (num_packets == 0) {