Change Av1 depacketizer to implement VideoRtpDepacketizer interface

Bug: webrtc:11152
Change-Id: I322115263f60439bee36277157a0acef9bd28e3e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/165343
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30260}
This commit is contained in:
Danil Chapovalov 2020-01-10 17:26:53 +01:00 committed by Commit Bot
parent f1173f46e5
commit d06588a758
10 changed files with 128 additions and 140 deletions

View File

@ -167,8 +167,6 @@ rtc_library("rtp_rtcp") {
"source/rtcp_receiver.h",
"source/rtcp_sender.cc",
"source/rtcp_sender.h",
"source/rtp_depacketizer_av1.cc",
"source/rtp_depacketizer_av1.h",
"source/rtp_format.cc",
"source/rtp_format.h",
"source/rtp_format_h264.cc",
@ -213,6 +211,8 @@ rtc_library("rtp_rtcp") {
"source/ulpfec_receiver_impl.cc",
"source/ulpfec_receiver_impl.h",
"source/video_rtp_depacketizer.h",
"source/video_rtp_depacketizer_av1.cc",
"source/video_rtp_depacketizer_av1.h",
"source/video_rtp_depacketizer_generic.cc",
"source/video_rtp_depacketizer_generic.h",
"source/video_rtp_depacketizer_h264.cc",
@ -461,7 +461,6 @@ if (rtc_include_tests) {
"source/rtcp_sender_unittest.cc",
"source/rtcp_transceiver_impl_unittest.cc",
"source/rtcp_transceiver_unittest.cc",
"source/rtp_depacketizer_av1_unittest.cc",
"source/rtp_fec_unittest.cc",
"source/rtp_format_h264_unittest.cc",
"source/rtp_format_unittest.cc",
@ -487,6 +486,7 @@ if (rtc_include_tests) {
"source/ulpfec_generator_unittest.cc",
"source/ulpfec_header_reader_writer_unittest.cc",
"source/ulpfec_receiver_unittest.cc",
"source/video_rtp_depacketizer_av1_unittest.cc",
"source/video_rtp_depacketizer_generic_unittest.cc",
"source/video_rtp_depacketizer_h264_unittest.cc",
"source/video_rtp_depacketizer_raw_unittest.cc",

View File

@ -14,8 +14,8 @@
#include "absl/memory/memory.h"
#include "absl/types/optional.h"
#include "modules/rtp_rtcp/source/rtp_depacketizer_av1.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_generic.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h"
@ -60,7 +60,7 @@ std::unique_ptr<VideoRtpDepacketizer> CreateVideoRtpDepacketizer(
case kVideoCodecVP9:
return std::make_unique<VideoRtpDepacketizerVp9>();
case kVideoCodecAV1:
return std::make_unique<Legacy<RtpDepacketizerAv1>>();
return std::make_unique<VideoRtpDepacketizerAv1>();
case kVideoCodecGeneric:
case kVideoCodecMultiplex:
return std::make_unique<VideoRtpDepacketizerGeneric>();

View File

@ -20,8 +20,8 @@
#include "api/array_view.h"
#include "api/scoped_refptr.h"
#include "api/video/encoded_image.h"
#include "modules/rtp_rtcp/source/rtp_depacketizer_av1.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h"
#include "test/gmock.h"
#include "test/gtest.h"
@ -104,7 +104,7 @@ Av1Frame ReassembleFrame(rtc::ArrayView<const RtpPayload> rtp_payloads) {
for (size_t i = 0; i < rtp_payloads.size(); ++i) {
payloads[i] = rtp_payloads[i];
}
return Av1Frame(RtpDepacketizerAv1::AssembleFrame(payloads));
return Av1Frame(VideoRtpDepacketizerAv1::AssembleFrame(payloads));
}
class Obu {

View File

@ -8,11 +8,13 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/rtp_rtcp/source/rtp_depacketizer_av1.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h"
#include <stddef.h>
#include <stdint.h>
#include <utility>
#include "modules/rtp_rtcp/source/rtp_video_header.h"
#include "rtc_base/byte_buffer.h"
#include "rtc_base/checks.h"
@ -333,7 +335,7 @@ bool CalculateObuSizes(ObuInfo* obu_info) {
} // namespace
rtc::scoped_refptr<EncodedImageBuffer> RtpDepacketizerAv1::AssembleFrame(
rtc::scoped_refptr<EncodedImageBuffer> VideoRtpDepacketizerAv1::AssembleFrame(
rtc::ArrayView<const rtc::ArrayView<const uint8_t>> rtp_payloads) {
VectorObuInfo obu_infos = ParseObus(rtp_payloads);
if (obu_infos.empty()) {
@ -363,42 +365,40 @@ rtc::scoped_refptr<EncodedImageBuffer> RtpDepacketizerAv1::AssembleFrame(
return bitstream;
}
bool RtpDepacketizerAv1::Parse(ParsedPayload* parsed_payload,
const uint8_t* payload_data,
size_t payload_data_length) {
RTC_DCHECK(parsed_payload);
if (payload_data_length == 0) {
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
VideoRtpDepacketizerAv1::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
if (rtp_payload.size() == 0) {
RTC_DLOG(LS_ERROR) << "Empty rtp payload.";
return false;
return absl::nullopt;
}
uint8_t aggregation_header = payload_data[0];
uint8_t aggregation_header = rtp_payload.cdata()[0];
if (RtpStartsNewCodedVideoSequence(aggregation_header) &&
RtpStartsWithFragment(aggregation_header)) {
// new coded video sequence can't start from an OBU fragment.
return false;
return absl::nullopt;
}
absl::optional<ParsedRtpPayload> parsed(absl::in_place);
// To assemble frame, all of the rtp payload is required, including
// aggregation header.
parsed_payload->payload = payload_data;
parsed_payload->payload_length = payload_data_length;
parsed->video_payload = std::move(rtp_payload);
parsed_payload->video.codec = VideoCodecType::kVideoCodecAV1;
parsed->video_header.codec = VideoCodecType::kVideoCodecAV1;
// These are not accurate since frame may consist of several packet aligned
// chunks of obus, but should be good enough for most cases. It might produce
// frame that do not map to any real frame, but av1 decoder should be able to
// handle it since it promise to handle individual obus rather than full
// frames.
parsed_payload->video.is_first_packet_in_frame =
parsed->video_header.is_first_packet_in_frame =
!RtpStartsWithFragment(aggregation_header);
parsed_payload->video.is_last_packet_in_frame =
parsed->video_header.is_last_packet_in_frame =
!RtpEndsWithFragment(aggregation_header);
parsed_payload->video.frame_type =
parsed->video_header.frame_type =
RtpStartsNewCodedVideoSequence(aggregation_header)
? VideoFrameType::kVideoFrameKey
: VideoFrameType::kVideoFrameDelta;
return true;
return parsed;
}
} // namespace webrtc

View File

@ -8,33 +8,34 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef MODULES_RTP_RTCP_SOURCE_RTP_DEPACKETIZER_AV1_H_
#define MODULES_RTP_RTCP_SOURCE_RTP_DEPACKETIZER_AV1_H_
#ifndef MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_AV1_H_
#define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_AV1_H_
#include <stddef.h>
#include <stdint.h>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/scoped_refptr.h"
#include "api/video/encoded_image.h"
#include "modules/rtp_rtcp/source/rtp_format.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
#include "rtc_base/copy_on_write_buffer.h"
namespace webrtc {
class RtpDepacketizerAv1 : public RtpDepacketizer {
class VideoRtpDepacketizerAv1 : public VideoRtpDepacketizer {
public:
RtpDepacketizerAv1() = default;
RtpDepacketizerAv1(const RtpDepacketizerAv1&) = delete;
RtpDepacketizerAv1& operator=(const RtpDepacketizerAv1&) = delete;
~RtpDepacketizerAv1() override = default;
VideoRtpDepacketizerAv1() = default;
VideoRtpDepacketizerAv1(const VideoRtpDepacketizerAv1&) = delete;
VideoRtpDepacketizerAv1& operator=(const VideoRtpDepacketizerAv1&) = delete;
~VideoRtpDepacketizerAv1() override = default;
static rtc::scoped_refptr<EncodedImageBuffer> AssembleFrame(
rtc::ArrayView<const rtc::ArrayView<const uint8_t>> rtp_payloads);
bool Parse(ParsedPayload* parsed_payload,
const uint8_t* payload_data,
size_t payload_data_length) override;
absl::optional<ParsedRtpPayload> Parse(
rtc::CopyOnWriteBuffer rtp_payload) override;
};
} // namespace webrtc
#endif // MODULES_RTP_RTCP_SOURCE_RTP_DEPACKETIZER_AV1_H_
#endif // MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_AV1_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/rtp_rtcp/source/rtp_depacketizer_av1.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h"
#include "test/gmock.h"
#include "test/gtest.h"
@ -26,94 +26,106 @@ constexpr uint8_t kObuHeaderFrame = 0b0'0110'000;
constexpr uint8_t kObuHeaderHasSize = 0b0'0000'010;
TEST(RtpDepacketizerAv1Test, ParsePassFullRtpPayloadAsCodecPayload) {
TEST(VideoRtpDepacketizerAv1Test, ParsePassFullRtpPayloadAsCodecPayload) {
const uint8_t packet[] = {(uint8_t{1} << 7) | kObuCountOne, 1, 2, 3, 4};
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed;
ASSERT_TRUE(depacketizer.Parse(&parsed, packet, sizeof(packet)));
EXPECT_EQ(parsed.payload_length, sizeof(packet));
EXPECT_TRUE(parsed.payload == packet);
rtc::CopyOnWriteBuffer rtp_payload(packet);
VideoRtpDepacketizerAv1 depacketizer;
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
depacketizer.Parse(rtp_payload);
ASSERT_TRUE(parsed);
EXPECT_EQ(parsed->video_payload.size(), sizeof(packet));
EXPECT_TRUE(parsed->video_payload.cdata() == rtp_payload.cdata());
}
TEST(RtpDepacketizerAv1Test, ParseTreatsContinuationFlagAsNotBeginningOfFrame) {
TEST(VideoRtpDepacketizerAv1Test,
ParseTreatsContinuationFlagAsNotBeginningOfFrame) {
const uint8_t packet[] = {
(uint8_t{1} << 7) | kObuCountOne,
kObuHeaderFrame}; // Value doesn't matter since it is a
// continuation of the OBU from previous packet.
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed;
ASSERT_TRUE(depacketizer.Parse(&parsed, packet, sizeof(packet)));
EXPECT_FALSE(parsed.video.is_first_packet_in_frame);
VideoRtpDepacketizerAv1 depacketizer;
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
ASSERT_TRUE(parsed);
EXPECT_FALSE(parsed->video_header.is_first_packet_in_frame);
}
TEST(RtpDepacketizerAv1Test, ParseTreatsNoContinuationFlagAsBeginningOfFrame) {
TEST(VideoRtpDepacketizerAv1Test,
ParseTreatsNoContinuationFlagAsBeginningOfFrame) {
const uint8_t packet[] = {(uint8_t{0} << 7) | kObuCountOne, kObuHeaderFrame};
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed;
ASSERT_TRUE(depacketizer.Parse(&parsed, packet, sizeof(packet)));
EXPECT_TRUE(parsed.video.is_first_packet_in_frame);
VideoRtpDepacketizerAv1 depacketizer;
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
ASSERT_TRUE(parsed);
EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
}
TEST(RtpDepacketizerAv1Test, ParseTreatsWillContinueFlagAsNotEndOfFrame) {
TEST(VideoRtpDepacketizerAv1Test, ParseTreatsWillContinueFlagAsNotEndOfFrame) {
const uint8_t packet[] = {(uint8_t{1} << 6) | kObuCountOne, kObuHeaderFrame};
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed;
ASSERT_TRUE(depacketizer.Parse(&parsed, packet, sizeof(packet)));
EXPECT_FALSE(parsed.video.is_last_packet_in_frame);
rtc::CopyOnWriteBuffer rtp_payload(packet);
VideoRtpDepacketizerAv1 depacketizer;
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
depacketizer.Parse(rtp_payload);
ASSERT_TRUE(parsed);
EXPECT_FALSE(parsed->video_header.is_last_packet_in_frame);
}
TEST(RtpDepacketizerAv1Test, ParseTreatsNoWillContinueFlagAsEndOfFrame) {
TEST(VideoRtpDepacketizerAv1Test, ParseTreatsNoWillContinueFlagAsEndOfFrame) {
const uint8_t packet[] = {(uint8_t{0} << 6) | kObuCountOne, kObuHeaderFrame};
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed;
ASSERT_TRUE(depacketizer.Parse(&parsed, packet, sizeof(packet)));
EXPECT_TRUE(parsed.video.is_last_packet_in_frame);
VideoRtpDepacketizerAv1 depacketizer;
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
ASSERT_TRUE(parsed);
EXPECT_TRUE(parsed->video_header.is_last_packet_in_frame);
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
ParseUsesNewCodedVideoSequenceBitAsKeyFrameIndidcator) {
const uint8_t packet[] = {(uint8_t{1} << 3) | kObuCountOne,
kObuHeaderSequenceHeader};
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed;
ASSERT_TRUE(depacketizer.Parse(&parsed, packet, sizeof(packet)));
EXPECT_TRUE(parsed.video.is_first_packet_in_frame);
EXPECT_TRUE(parsed.video.frame_type == VideoFrameType::kVideoFrameKey);
VideoRtpDepacketizerAv1 depacketizer;
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
ASSERT_TRUE(parsed);
EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
EXPECT_TRUE(parsed->video_header.frame_type ==
VideoFrameType::kVideoFrameKey);
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
ParseUsesUnsetNewCodedVideoSequenceBitAsDeltaFrameIndidcator) {
const uint8_t packet[] = {(uint8_t{0} << 3) | kObuCountOne,
kObuHeaderSequenceHeader};
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed;
ASSERT_TRUE(depacketizer.Parse(&parsed, packet, sizeof(packet)));
EXPECT_TRUE(parsed.video.is_first_packet_in_frame);
EXPECT_TRUE(parsed.video.frame_type == VideoFrameType::kVideoFrameDelta);
VideoRtpDepacketizerAv1 depacketizer;
absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
depacketizer.Parse(rtc::CopyOnWriteBuffer(packet));
ASSERT_TRUE(parsed);
EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
EXPECT_TRUE(parsed->video_header.frame_type ==
VideoFrameType::kVideoFrameDelta);
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
ParseRejectsPacketWithNewCVSAndContinuationFlagsBothSet) {
const uint8_t packet[] = {0b10'00'1000 | kObuCountOne,
kObuHeaderSequenceHeader};
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed;
EXPECT_FALSE(depacketizer.Parse(&parsed, packet, sizeof(packet)));
VideoRtpDepacketizerAv1 depacketizer;
ASSERT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(packet)));
}
TEST(RtpDepacketizerAv1Test, AssembleFrameSetsOBUPayloadSizeWhenAbsent) {
TEST(VideoRtpDepacketizerAv1Test, AssembleFrameSetsOBUPayloadSizeWhenAbsent) {
const uint8_t payload1[] = {0b00'01'0000, // aggregation header
0b0'0110'000, // / Frame
20, 30, 40}; // \ OBU
rtc::ArrayView<const uint8_t> payloads[] = {payload1};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
rtc::ArrayView<const uint8_t> frame_view(*frame);
EXPECT_TRUE(frame_view[0] & kObuHeaderHasSize);
EXPECT_EQ(frame_view[1], 3);
}
TEST(RtpDepacketizerAv1Test, AssembleFrameSetsOBUPayloadSizeWhenPresent) {
TEST(VideoRtpDepacketizerAv1Test, AssembleFrameSetsOBUPayloadSizeWhenPresent) {
const uint8_t payload1[] = {0b00'01'0000, // aggregation header
0b0'0110'010, // / Frame OBU header
3, // obu_size
@ -121,28 +133,28 @@ TEST(RtpDepacketizerAv1Test, AssembleFrameSetsOBUPayloadSizeWhenPresent) {
30,
40}; // \ obu_payload
rtc::ArrayView<const uint8_t> payloads[] = {payload1};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
rtc::ArrayView<const uint8_t> frame_view(*frame);
EXPECT_TRUE(frame_view[0] & kObuHeaderHasSize);
EXPECT_EQ(frame_view[1], 3);
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
AssembleFrameSetsOBUPayloadSizeAfterExtensionWhenAbsent) {
const uint8_t payload1[] = {0b00'01'0000, // aggregation header
0b0'0110'100, // / Frame
0b010'01'000, // | extension_header
20, 30, 40}; // \ OBU
rtc::ArrayView<const uint8_t> payloads[] = {payload1};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
rtc::ArrayView<const uint8_t> frame_view(*frame);
EXPECT_TRUE(frame_view[0] & kObuHeaderHasSize);
EXPECT_EQ(frame_view[2], 3);
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
AssembleFrameSetsOBUPayloadSizeAfterExtensionWhenPresent) {
const uint8_t payload1[] = {0b00'01'0000, // aggregation header
0b0'0110'110, // / Frame OBU header
@ -152,25 +164,25 @@ TEST(RtpDepacketizerAv1Test,
30,
40}; // \ obu_payload
rtc::ArrayView<const uint8_t> payloads[] = {payload1};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
rtc::ArrayView<const uint8_t> frame_view(*frame);
EXPECT_TRUE(frame_view[0] & kObuHeaderHasSize);
EXPECT_EQ(frame_view[2], 3);
}
TEST(RtpDepacketizerAv1Test, AssembleFrameFromOnePacketWithOneObu) {
TEST(VideoRtpDepacketizerAv1Test, AssembleFrameFromOnePacketWithOneObu) {
const uint8_t payload1[] = {0b00'01'0000, // aggregation header
0b0'0110'000, // / Frame
20}; // \ OBU
rtc::ArrayView<const uint8_t> payloads[] = {payload1};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre(0b0'0110'010, 1, 20));
}
TEST(RtpDepacketizerAv1Test, AssembleFrameFromOnePacketWithTwoObus) {
TEST(VideoRtpDepacketizerAv1Test, AssembleFrameFromOnePacketWithTwoObus) {
const uint8_t payload1[] = {0b00'10'0000, // aggregation header
2, // / Sequence
0b0'0001'000, // | Header
@ -178,26 +190,26 @@ TEST(RtpDepacketizerAv1Test, AssembleFrameFromOnePacketWithTwoObus) {
0b0'0110'000, // / Frame
20}; // \ OBU
rtc::ArrayView<const uint8_t> payloads[] = {payload1};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre(0b0'0001'010, 1, 10, // Sequence Header OBU
0b0'0110'010, 1, 20)); // Frame OBU
}
TEST(RtpDepacketizerAv1Test, AssembleFrameFromTwoPacketsWithOneObu) {
TEST(VideoRtpDepacketizerAv1Test, AssembleFrameFromTwoPacketsWithOneObu) {
const uint8_t payload1[] = {0b01'01'0000, // aggregation header
0b0'0110'000, 20, 30};
const uint8_t payload2[] = {0b10'01'0000, // aggregation header
40};
rtc::ArrayView<const uint8_t> payloads[] = {payload1, payload2};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre(0b0'0110'010, 3, 20, 30, 40));
}
TEST(RtpDepacketizerAv1Test, AssembleFrameFromTwoPacketsWithTwoObu) {
TEST(VideoRtpDepacketizerAv1Test, AssembleFrameFromTwoPacketsWithTwoObu) {
const uint8_t payload1[] = {0b01'10'0000, // aggregation header
2, // / Sequence
0b0'0001'000, // | Header
@ -208,14 +220,14 @@ TEST(RtpDepacketizerAv1Test, AssembleFrameFromTwoPacketsWithTwoObu) {
const uint8_t payload2[] = {0b10'01'0000, // aggregation header
40}; //
rtc::ArrayView<const uint8_t> payloads[] = {payload1, payload2};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre(0b0'0001'010, 1, 10, // SH
0b0'0110'010, 3, 20, 30, 40)); // Frame
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
AssembleFrameFromTwoPacketsWithManyObusSomeWithExtensions) {
const uint8_t payload1[] = {0b01'00'0000, // aggregation header
2, // /
@ -239,7 +251,7 @@ TEST(RtpDepacketizerAv1Test,
70, 80, 90}; // \ tail of the frame OBU
rtc::ArrayView<const uint8_t> payloads[] = {payload1, payload2};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre( // Sequence header OBU
@ -252,7 +264,7 @@ TEST(RtpDepacketizerAv1Test,
0b0'0110'110, 0b001'10'000, 6, 40, 50, 60, 70, 80, 90));
}
TEST(RtpDepacketizerAv1Test, AssembleFrameWithOneObuFromManyPackets) {
TEST(VideoRtpDepacketizerAv1Test, AssembleFrameWithOneObuFromManyPackets) {
const uint8_t payload1[] = {0b01'01'0000, // aggregation header
0b0'0110'000, 11, 12};
const uint8_t payload2[] = {0b11'01'0000, // aggregation header
@ -264,13 +276,13 @@ TEST(RtpDepacketizerAv1Test, AssembleFrameWithOneObuFromManyPackets) {
rtc::ArrayView<const uint8_t> payloads[] = {payload1, payload2, payload3,
payload4};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre(0b0'0110'010, 8, 11, 12, 13, 14, 15, 16, 17, 18));
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
AssembleFrameFromManyPacketsWithSomeObuBorderAligned) {
const uint8_t payload1[] = {0b01'10'0000, // aggregation header
3, // size of the 1st fragment
@ -296,7 +308,7 @@ TEST(RtpDepacketizerAv1Test,
33, 34, 35, 36};
rtc::ArrayView<const uint8_t> payloads[] = {payload1, payload2, payload3,
payload4};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre(0b0'0011'010, 2, 11, 12, // Frame header
@ -305,7 +317,7 @@ TEST(RtpDepacketizerAv1Test,
0b0'0100'010, 6, 31, 32, 33, 34, 35, 36));
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
AssembleFrameFromOnePacketsOneObuPayloadSize127Bytes) {
uint8_t payload1[4 + 127];
memset(payload1, 0, sizeof(payload1));
@ -315,7 +327,7 @@ TEST(RtpDepacketizerAv1Test,
payload1[3] = 0b0'0110'000; // obu_header with size and extension bits unset.
payload1[4 + 42] = 0x42;
rtc::ArrayView<const uint8_t> payloads[] = {payload1};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_EQ(frame->size(), 2 + 127u);
rtc::ArrayView<const uint8_t> frame_view(*frame);
@ -325,7 +337,7 @@ TEST(RtpDepacketizerAv1Test,
EXPECT_EQ(frame_view[2 + 42], 0x42);
}
TEST(RtpDepacketizerAv1Test,
TEST(VideoRtpDepacketizerAv1Test,
AssembleFrameFromTwoPacketsOneObuPayloadSize128Bytes) {
uint8_t payload1[3 + 32];
memset(payload1, 0, sizeof(payload1));
@ -340,7 +352,7 @@ TEST(RtpDepacketizerAv1Test,
payload2[2 + 20] = 0x20;
rtc::ArrayView<const uint8_t> payloads[] = {payload1, payload2};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_EQ(frame->size(), 3 + 128u);
rtc::ArrayView<const uint8_t> frame_view(*frame);
@ -352,23 +364,25 @@ TEST(RtpDepacketizerAv1Test,
EXPECT_EQ(frame_view[3 + 32 + 20], 0x20);
}
TEST(RtpDepacketizerAv1Test, AssembleFrameFromAlmostEmptyPacketStartingAnOBU) {
TEST(VideoRtpDepacketizerAv1Test,
AssembleFrameFromAlmostEmptyPacketStartingAnOBU) {
const uint8_t payload1[] = {0b01'01'0000};
const uint8_t payload2[] = {0b10'01'0000, 0b0'0110'000, 10, 20, 30};
rtc::ArrayView<const uint8_t> payloads[] = {payload1, payload2};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre(0b0'0110'010, 3, 10, 20, 30));
}
TEST(RtpDepacketizerAv1Test, AssembleFrameFromAlmostEmptyPacketFinishingAnOBU) {
TEST(VideoRtpDepacketizerAv1Test,
AssembleFrameFromAlmostEmptyPacketFinishingAnOBU) {
const uint8_t payload1[] = {0b01'01'0000, 0b0'0110'000, 10, 20, 30};
const uint8_t payload2[] = {0b10'01'0000};
rtc::ArrayView<const uint8_t> payloads[] = {payload1, payload2};
auto frame = RtpDepacketizerAv1::AssembleFrame(payloads);
auto frame = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
ASSERT_TRUE(frame);
EXPECT_THAT(rtc::ArrayView<const uint8_t>(*frame),
ElementsAre(0b0'0110'010, 3, 10, 20, 30));

View File

@ -24,10 +24,10 @@
#include "api/video/encoded_frame.h"
#include "api/video/video_frame_type.h"
#include "common_video/h264/h264_common.h"
#include "modules/rtp_rtcp/source/rtp_depacketizer_av1.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_video_header.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h"
#include "modules/video_coding/codecs/h264/include/h264_globals.h"
#include "modules/video_coding/frame_object.h"
#include "rtc_base/checks.h"
@ -441,7 +441,7 @@ std::unique_ptr<RtpFrameObject> PacketBuffer::AssembleFrame(
rtc::scoped_refptr<EncodedImageBuffer> bitstream;
// TODO(danilchap): Hide codec-specific code paths behind an interface.
if (first_packet.codec() == VideoCodecType::kVideoCodecAV1) {
bitstream = RtpDepacketizerAv1::AssembleFrame(payloads);
bitstream = VideoRtpDepacketizerAv1::AssembleFrame(payloads);
if (!bitstream) {
// Failed to assemble a frame. Discard and continue.
return nullptr;

View File

@ -562,15 +562,6 @@ webrtc_fuzzer_test("comfort_noise_decoder_fuzzer") {
]
}
webrtc_fuzzer_test("rtp_depacketizer_av1_parse_fuzzer") {
sources = [
"rtp_depacketizer_av1_parse_fuzzer.cc",
]
deps = [
"../../modules/rtp_rtcp",
]
}
webrtc_fuzzer_test("rtp_depacketizer_av1_assemble_frame_fuzzer") {
sources = [
"rtp_depacketizer_av1_assemble_frame_fuzzer.cc",

View File

@ -7,7 +7,7 @@
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/rtp_rtcp/source/rtp_depacketizer_av1.h"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_av1.h"
#include <stddef.h>
#include <stdint.h>
@ -34,6 +34,6 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
rtp_payloads.push_back(fuzz_input.ReadByteArray(next_size));
}
// Run code under test.
RtpDepacketizerAv1::AssembleFrame(rtp_payloads);
VideoRtpDepacketizerAv1::AssembleFrame(rtp_payloads);
}
} // namespace webrtc

View File

@ -1,18 +0,0 @@
/*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/rtp_rtcp/source/rtp_depacketizer_av1.h"
namespace webrtc {
void FuzzOneInput(const uint8_t* data, size_t size) {
RtpDepacketizerAv1 depacketizer;
RtpDepacketizer::ParsedPayload parsed_payload;
depacketizer.Parse(&parsed_payload, data, size);
}
} // namespace webrtc