In Av1 packetizer set marker bit with respect of end_of_picture flag
Bug: webrtc:12167 Change-Id: If14fdd7144951c7aa7e48efd390637dd66201bf7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/192791 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32612}
This commit is contained in:
parent
a87cea746d
commit
62a9a32937
@ -36,6 +36,7 @@ void PopulateRtpWithCodecSpecifics(const CodecSpecificInfo& info,
|
||||
absl::optional<int> spatial_index,
|
||||
RTPVideoHeader* rtp) {
|
||||
rtp->codec = info.codecType;
|
||||
rtp->is_last_frame_in_picture = info.end_of_picture;
|
||||
switch (info.codecType) {
|
||||
case kVideoCodecVP8: {
|
||||
auto& vp8_header = rtp->video_type_header.emplace<RTPVideoHeaderVP8>();
|
||||
|
||||
@ -54,8 +54,9 @@ std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
|
||||
return std::make_unique<RtpPacketizerVp9>(payload, limits, vp9);
|
||||
}
|
||||
case kVideoCodecAV1:
|
||||
return std::make_unique<RtpPacketizerAv1>(payload, limits,
|
||||
rtp_video_header.frame_type);
|
||||
return std::make_unique<RtpPacketizerAv1>(
|
||||
payload, limits, rtp_video_header.frame_type,
|
||||
rtp_video_header.is_last_frame_in_picture);
|
||||
default: {
|
||||
return std::make_unique<RtpPacketizerGeneric>(payload, limits,
|
||||
rtp_video_header);
|
||||
|
||||
@ -88,10 +88,12 @@ int MaxFragmentSize(int remaining_bytes) {
|
||||
|
||||
RtpPacketizerAv1::RtpPacketizerAv1(rtc::ArrayView<const uint8_t> payload,
|
||||
RtpPacketizer::PayloadSizeLimits limits,
|
||||
VideoFrameType frame_type)
|
||||
VideoFrameType frame_type,
|
||||
bool is_last_frame_in_picture)
|
||||
: frame_type_(frame_type),
|
||||
obus_(ParseObus(payload)),
|
||||
packets_(Packetize(obus_, limits)) {}
|
||||
packets_(Packetize(obus_, limits)),
|
||||
is_last_frame_in_picture_(is_last_frame_in_picture) {}
|
||||
|
||||
std::vector<RtpPacketizerAv1::Obu> RtpPacketizerAv1::ParseObus(
|
||||
rtc::ArrayView<const uint8_t> payload) {
|
||||
@ -414,11 +416,8 @@ bool RtpPacketizerAv1::NextPacket(RtpPacketToSend* packet) {
|
||||
kAggregationHeaderSize + next_packet.packet_size);
|
||||
|
||||
++packet_index_;
|
||||
if (packet_index_ == packets_.size()) {
|
||||
// TODO(danilchap): To support spatial scalability pass and use information
|
||||
// if this frame is the last in the temporal unit.
|
||||
packet->SetMarker(true);
|
||||
}
|
||||
bool is_last_packet_in_frame = packet_index_ == packets_.size();
|
||||
packet->SetMarker(is_last_packet_in_frame && is_last_frame_in_picture_);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,8 @@ class RtpPacketizerAv1 : public RtpPacketizer {
|
||||
public:
|
||||
RtpPacketizerAv1(rtc::ArrayView<const uint8_t> payload,
|
||||
PayloadSizeLimits limits,
|
||||
VideoFrameType frame_type);
|
||||
VideoFrameType frame_type,
|
||||
bool is_last_frame_in_picture);
|
||||
~RtpPacketizerAv1() override = default;
|
||||
|
||||
size_t NumPackets() const override { return packets_.size() - packet_index_; }
|
||||
@ -63,6 +64,7 @@ class RtpPacketizerAv1 : public RtpPacketizer {
|
||||
const VideoFrameType frame_type_;
|
||||
const std::vector<Obu> obus_;
|
||||
const std::vector<Packet> packets_;
|
||||
const bool is_last_frame_in_picture_;
|
||||
size_t packet_index_ = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -88,9 +88,11 @@ class Av1Frame {
|
||||
std::vector<RtpPayload> Packetize(
|
||||
rtc::ArrayView<const uint8_t> payload,
|
||||
RtpPacketizer::PayloadSizeLimits limits,
|
||||
VideoFrameType frame_type = VideoFrameType::kVideoFrameDelta) {
|
||||
VideoFrameType frame_type = VideoFrameType::kVideoFrameDelta,
|
||||
bool is_last_frame_in_picture = true) {
|
||||
// Run code under test.
|
||||
RtpPacketizerAv1 packetizer(payload, limits, frame_type);
|
||||
RtpPacketizerAv1 packetizer(payload, limits, frame_type,
|
||||
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) {
|
||||
@ -332,6 +334,34 @@ TEST(RtpPacketizerAv1Test, SplitSingleObuIntoManyPackets) {
|
||||
EXPECT_THAT(ReassembleFrame(payloads), ElementsAreArray(kFrame));
|
||||
}
|
||||
|
||||
TEST(RtpPacketizerAv1Test, SetMarkerBitForLastPacketInEndOfPictureFrame) {
|
||||
auto kFrame = BuildAv1Frame(
|
||||
{Obu(kObuTypeFrame).WithPayload(std::vector<uint8_t>(200, 27))});
|
||||
|
||||
RtpPacketizer::PayloadSizeLimits limits;
|
||||
limits.max_payload_len = 100;
|
||||
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(RtpPacketizerAv1Test, DoesntSetMarkerBitForPacketsNotInEndOfPictureFrame) {
|
||||
auto kFrame = BuildAv1Frame(
|
||||
{Obu(kObuTypeFrame).WithPayload(std::vector<uint8_t>(200, 27))});
|
||||
|
||||
RtpPacketizer::PayloadSizeLimits limits;
|
||||
limits.max_payload_len = 100;
|
||||
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(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.
|
||||
|
||||
@ -70,6 +70,7 @@ struct RTPVideoHeader {
|
||||
VideoContentType content_type = VideoContentType::UNSPECIFIED;
|
||||
bool is_first_packet_in_frame = false;
|
||||
bool is_last_packet_in_frame = false;
|
||||
bool is_last_frame_in_picture = true;
|
||||
uint8_t simulcastIdx = 0;
|
||||
VideoCodecType codec = VideoCodecType::kVideoCodecGeneric;
|
||||
|
||||
|
||||
@ -35,7 +35,8 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
|
||||
|
||||
// Main function under test: RtpPacketizerAv1's constructor.
|
||||
RtpPacketizerAv1 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()),
|
||||
limits, frame_type);
|
||||
limits, frame_type,
|
||||
/*is_last_frame_in_picture=*/true);
|
||||
|
||||
size_t num_packets = packetizer.NumPackets();
|
||||
if (num_packets == 0) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user