Change H264 depacketizer to implement VideoRtpDepacketizer interface
Bug: webrtc:11152
Change-Id: If5169f47d85918356fa66e2bf3422d722044aa1f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/165581
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Markus Handell <handellm@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30264}
diff --git a/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc b/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc
index d96741b..724ad8c 100644
--- a/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc
+++ b/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc
@@ -12,49 +12,21 @@
#include <memory>
-#include "absl/memory/memory.h"
-#include "absl/types/optional.h"
+#include "api/video/video_codec_type.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"
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h"
-#include "rtc_base/checks.h"
-#include "rtc_base/copy_on_write_buffer.h"
namespace webrtc {
-namespace {
-
-// Wrapper over legacy RtpDepacketizer interface.
-// TODO(bugs.webrtc.org/11152): Delete when all RtpDepacketizers updated to
-// the VideoRtpDepacketizer interface.
-template <typename Depacketizer>
-class Legacy : public VideoRtpDepacketizer {
- public:
- absl::optional<ParsedRtpPayload> Parse(
- rtc::CopyOnWriteBuffer rtp_payload) override {
- Depacketizer depacketizer;
- RtpDepacketizer::ParsedPayload parsed_payload;
- if (!depacketizer.Parse(&parsed_payload, rtp_payload.cdata(),
- rtp_payload.size())) {
- return absl::nullopt;
- }
- absl::optional<ParsedRtpPayload> result(absl::in_place);
- result->video_header = parsed_payload.video;
- result->video_payload.SetData(parsed_payload.payload,
- parsed_payload.payload_length);
- return result;
- }
-};
-
-} // namespace
std::unique_ptr<VideoRtpDepacketizer> CreateVideoRtpDepacketizer(
VideoCodecType codec) {
switch (codec) {
case kVideoCodecH264:
- return std::make_unique<Legacy<RtpDepacketizerH264>>();
+ return std::make_unique<VideoRtpDepacketizerH264>();
case kVideoCodecVP8:
return std::make_unique<VideoRtpDepacketizerVp8>();
case kVideoCodecVP9:
diff --git a/modules/rtp_rtcp/source/rtp_format_h264.h b/modules/rtp_rtcp/source/rtp_format_h264.h
index fdea9a7..4661dc2 100644
--- a/modules/rtp_rtcp/source/rtp_format_h264.h
+++ b/modules/rtp_rtcp/source/rtp_format_h264.h
@@ -22,7 +22,6 @@
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/source/rtp_format.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
-#include "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h"
#include "modules/video_coding/codecs/h264/include/h264_globals.h"
#include "rtc_base/buffer.h"
#include "rtc_base/constructor_magic.h"
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
index 9babc67..a0bd8fb 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.cc
@@ -10,11 +10,8 @@
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h"
-#include <string.h>
-
#include <cstddef>
#include <cstdint>
-#include <memory>
#include <utility>
#include <vector>
@@ -25,17 +22,19 @@
#include "common_video/h264/sps_parser.h"
#include "common_video/h264/sps_vui_rewriter.h"
#include "modules/rtp_rtcp/source/byte_io.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
#include "rtc_base/checks.h"
+#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/logging.h"
#include "rtc_base/system/fallthrough.h"
namespace webrtc {
namespace {
-static const size_t kNalHeaderSize = 1;
-static const size_t kFuAHeaderSize = 2;
-static const size_t kLengthFieldSize = 2;
-static const size_t kStapAHeaderSize = kNalHeaderSize + kLengthFieldSize;
+constexpr size_t kNalHeaderSize = 1;
+constexpr size_t kFuAHeaderSize = 2;
+constexpr size_t kLengthFieldSize = 2;
+constexpr size_t kStapAHeaderSize = kNalHeaderSize + kLengthFieldSize;
// Bit masks for FU (A and B) indicators.
enum NalDefs : uint8_t { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F };
@@ -66,36 +65,35 @@
return true;
}
-} // namespace
-
-RtpDepacketizerH264::RtpDepacketizerH264() : offset_(0), length_(0) {}
-RtpDepacketizerH264::~RtpDepacketizerH264() {}
-
-bool RtpDepacketizerH264::ProcessStapAOrSingleNalu(
- ParsedPayload* parsed_payload,
- const uint8_t* payload_data) {
- parsed_payload->video_header().width = 0;
- parsed_payload->video_header().height = 0;
- parsed_payload->video_header().codec = kVideoCodecH264;
- parsed_payload->video_header().simulcastIdx = 0;
- parsed_payload->video_header().is_first_packet_in_frame = true;
- auto& h264_header = absl::get<RTPVideoHeaderH264>(
- parsed_payload->video_header().video_type_header);
+absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> ProcessStapAOrSingleNalu(
+ rtc::CopyOnWriteBuffer rtp_payload) {
+ const uint8_t* const payload_data = rtp_payload.cdata();
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
+ absl::in_place);
+ bool modified_buffer = false;
+ parsed_payload->video_payload = rtp_payload;
+ parsed_payload->video_header.width = 0;
+ parsed_payload->video_header.height = 0;
+ parsed_payload->video_header.codec = kVideoCodecH264;
+ parsed_payload->video_header.simulcastIdx = 0;
+ parsed_payload->video_header.is_first_packet_in_frame = true;
+ auto& h264_header = parsed_payload->video_header.video_type_header
+ .emplace<RTPVideoHeaderH264>();
const uint8_t* nalu_start = payload_data + kNalHeaderSize;
- const size_t nalu_length = length_ - kNalHeaderSize;
+ const size_t nalu_length = rtp_payload.size() - kNalHeaderSize;
uint8_t nal_type = payload_data[0] & kTypeMask;
std::vector<size_t> nalu_start_offsets;
if (nal_type == H264::NaluType::kStapA) {
// Skip the StapA header (StapA NAL type + length).
- if (length_ <= kStapAHeaderSize) {
+ if (rtp_payload.size() <= kStapAHeaderSize) {
RTC_LOG(LS_ERROR) << "StapA header truncated.";
- return false;
+ return absl::nullopt;
}
if (!ParseStapAStartOffsets(nalu_start, nalu_length, &nalu_start_offsets)) {
RTC_LOG(LS_ERROR) << "StapA packet with incorrect NALU packet lengths.";
- return false;
+ return absl::nullopt;
}
h264_header.packetization_type = kH264StapA;
@@ -105,9 +103,10 @@
nalu_start_offsets.push_back(0);
}
h264_header.nalu_type = nal_type;
- parsed_payload->video_header().frame_type = VideoFrameType::kVideoFrameDelta;
+ parsed_payload->video_header.frame_type = VideoFrameType::kVideoFrameDelta;
- nalu_start_offsets.push_back(length_ + kLengthFieldSize); // End offset.
+ nalu_start_offsets.push_back(rtp_payload.size() +
+ kLengthFieldSize); // End offset.
for (size_t i = 0; i < nalu_start_offsets.size() - 1; ++i) {
size_t start_offset = nalu_start_offsets[i];
// End offset is actually start offset for next unit, excluding length field
@@ -115,7 +114,7 @@
size_t end_offset = nalu_start_offsets[i + 1] - kLengthFieldSize;
if (end_offset - start_offset < H264::kNaluTypeSize) {
RTC_LOG(LS_ERROR) << "STAP-A packet too short";
- return false;
+ return absl::nullopt;
}
NaluInfo nalu;
@@ -131,18 +130,18 @@
// excessive decoder latency.
// Copy any previous data first (likely just the first header).
- std::unique_ptr<rtc::Buffer> output_buffer(new rtc::Buffer());
+ rtc::Buffer output_buffer;
if (start_offset)
- output_buffer->AppendData(payload_data, start_offset);
+ output_buffer.AppendData(payload_data, start_offset);
absl::optional<SpsParser::SpsState> sps;
SpsVuiRewriter::ParseResult result = SpsVuiRewriter::ParseAndRewriteSps(
&payload_data[start_offset], end_offset - start_offset, &sps,
- nullptr, output_buffer.get(), SpsVuiRewriter::Direction::kIncoming);
+ nullptr, &output_buffer, SpsVuiRewriter::Direction::kIncoming);
if (result == SpsVuiRewriter::ParseResult::kVuiRewritten) {
- if (modified_buffer_) {
+ if (modified_buffer) {
RTC_LOG(LS_WARNING)
<< "More than one H264 SPS NAL units needing "
"rewriting found within a single STAP-A packet. "
@@ -155,27 +154,29 @@
start_offset - (H264::kNaluTypeSize + kLengthFieldSize);
// Stap-A Length includes payload data and type header.
size_t rewritten_size =
- output_buffer->size() - start_offset + H264::kNaluTypeSize;
+ output_buffer.size() - start_offset + H264::kNaluTypeSize;
ByteWriter<uint16_t>::WriteBigEndian(
- &(*output_buffer)[length_field_offset], rewritten_size);
+ &output_buffer[length_field_offset], rewritten_size);
}
+ parsed_payload->video_payload.SetData(output_buffer.data(),
+ output_buffer.size());
// Append rest of packet.
- output_buffer->AppendData(&payload_data[end_offset],
- nalu_length + kNalHeaderSize - end_offset);
+ parsed_payload->video_payload.AppendData(
+ &payload_data[end_offset],
+ nalu_length + kNalHeaderSize - end_offset);
- modified_buffer_ = std::move(output_buffer);
- length_ = modified_buffer_->size();
+ modified_buffer = true;
}
if (sps) {
- parsed_payload->video_header().width = sps->width;
- parsed_payload->video_header().height = sps->height;
+ parsed_payload->video_header.width = sps->width;
+ parsed_payload->video_header.height = sps->height;
nalu.sps_id = sps->id;
} else {
RTC_LOG(LS_WARNING) << "Failed to parse SPS id from SPS slice.";
}
- parsed_payload->video_header().frame_type =
+ parsed_payload->video_header.frame_type =
VideoFrameType::kVideoFrameKey;
break;
}
@@ -194,7 +195,7 @@
break;
}
case H264::NaluType::kIdr:
- parsed_payload->video_header().frame_type =
+ parsed_payload->video_header.frame_type =
VideoFrameType::kVideoFrameKey;
RTC_FALLTHROUGH();
case H264::NaluType::kSlice: {
@@ -218,7 +219,7 @@
case H264::NaluType::kStapA:
case H264::NaluType::kFuA:
RTC_LOG(LS_WARNING) << "Unexpected STAP-A or FU-A received.";
- return false;
+ return absl::nullopt;
}
if (h264_header.nalus_length == kMaxNalusPerPacket) {
@@ -230,28 +231,28 @@
}
}
- return true;
+ return parsed_payload;
}
-bool RtpDepacketizerH264::ParseFuaNalu(
- RtpDepacketizer::ParsedPayload* parsed_payload,
- const uint8_t* payload_data) {
- if (length_ < kFuAHeaderSize) {
+absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> ParseFuaNalu(
+ rtc::CopyOnWriteBuffer rtp_payload) {
+ if (rtp_payload.size() < kFuAHeaderSize) {
RTC_LOG(LS_ERROR) << "FU-A NAL units truncated.";
- return false;
+ return absl::nullopt;
}
- uint8_t fnri = payload_data[0] & (kFBit | kNriMask);
- uint8_t original_nal_type = payload_data[1] & kTypeMask;
- bool first_fragment = (payload_data[1] & kSBit) > 0;
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed_payload(
+ absl::in_place);
+ uint8_t fnri = rtp_payload.cdata()[0] & (kFBit | kNriMask);
+ uint8_t original_nal_type = rtp_payload.cdata()[1] & kTypeMask;
+ bool first_fragment = (rtp_payload.cdata()[1] & kSBit) > 0;
NaluInfo nalu;
nalu.type = original_nal_type;
nalu.sps_id = -1;
nalu.pps_id = -1;
if (first_fragment) {
- offset_ = 0;
- length_ -= kNalHeaderSize;
- absl::optional<uint32_t> pps_id = PpsParser::ParsePpsIdFromSlice(
- payload_data + 2 * kNalHeaderSize, length_ - kNalHeaderSize);
+ absl::optional<uint32_t> pps_id =
+ PpsParser::ParsePpsIdFromSlice(rtp_payload.cdata() + 2 * kNalHeaderSize,
+ rtp_payload.size() - 2 * kNalHeaderSize);
if (pps_id) {
nalu.pps_id = *pps_id;
} else {
@@ -261,70 +262,55 @@
<< static_cast<int>(nalu.type);
}
uint8_t original_nal_header = fnri | original_nal_type;
- modified_buffer_.reset(new rtc::Buffer());
- modified_buffer_->AppendData(payload_data + kNalHeaderSize, length_);
- (*modified_buffer_)[0] = original_nal_header;
+ rtp_payload =
+ rtp_payload.Slice(kNalHeaderSize, rtp_payload.size() - kNalHeaderSize);
+ rtp_payload[0] = original_nal_header;
+ parsed_payload->video_payload = std::move(rtp_payload);
} else {
- offset_ = kFuAHeaderSize;
- length_ -= kFuAHeaderSize;
+ parsed_payload->video_payload =
+ rtp_payload.Slice(kFuAHeaderSize, rtp_payload.size() - kFuAHeaderSize);
}
if (original_nal_type == H264::NaluType::kIdr) {
- parsed_payload->video_header().frame_type = VideoFrameType::kVideoFrameKey;
+ parsed_payload->video_header.frame_type = VideoFrameType::kVideoFrameKey;
} else {
- parsed_payload->video_header().frame_type =
- VideoFrameType::kVideoFrameDelta;
+ parsed_payload->video_header.frame_type = VideoFrameType::kVideoFrameDelta;
}
- parsed_payload->video_header().width = 0;
- parsed_payload->video_header().height = 0;
- parsed_payload->video_header().codec = kVideoCodecH264;
- parsed_payload->video_header().simulcastIdx = 0;
- parsed_payload->video_header().is_first_packet_in_frame = first_fragment;
- auto& h264_header = absl::get<RTPVideoHeaderH264>(
- parsed_payload->video_header().video_type_header);
+ parsed_payload->video_header.width = 0;
+ parsed_payload->video_header.height = 0;
+ parsed_payload->video_header.codec = kVideoCodecH264;
+ parsed_payload->video_header.simulcastIdx = 0;
+ parsed_payload->video_header.is_first_packet_in_frame = first_fragment;
+ auto& h264_header = parsed_payload->video_header.video_type_header
+ .emplace<RTPVideoHeaderH264>();
h264_header.packetization_type = kH264FuA;
h264_header.nalu_type = original_nal_type;
if (first_fragment) {
h264_header.nalus[h264_header.nalus_length] = nalu;
h264_header.nalus_length = 1;
}
- return true;
+ return parsed_payload;
}
-bool RtpDepacketizerH264::Parse(ParsedPayload* parsed_payload,
- const uint8_t* payload_data,
- size_t payload_data_length) {
- RTC_CHECK(parsed_payload != nullptr);
- if (payload_data_length == 0) {
+} // namespace
+
+absl::optional<VideoRtpDepacketizer::ParsedRtpPayload>
+VideoRtpDepacketizerH264::Parse(rtc::CopyOnWriteBuffer rtp_payload) {
+ if (rtp_payload.size() == 0) {
RTC_LOG(LS_ERROR) << "Empty payload.";
- return false;
+ return absl::nullopt;
}
- offset_ = 0;
- length_ = payload_data_length;
- modified_buffer_.reset();
+ uint8_t nal_type = rtp_payload.cdata()[0] & kTypeMask;
- uint8_t nal_type = payload_data[0] & kTypeMask;
- parsed_payload->video_header()
- .video_type_header.emplace<RTPVideoHeaderH264>();
if (nal_type == H264::NaluType::kFuA) {
// Fragmented NAL units (FU-A).
- if (!ParseFuaNalu(parsed_payload, payload_data))
- return false;
+ return ParseFuaNalu(std::move(rtp_payload));
} else {
// We handle STAP-A and single NALU's the same way here. The jitter buffer
// will depacketize the STAP-A into NAL units later.
- // TODO(sprang): Parse STAP-A offsets here and store in fragmentation vec.
- if (!ProcessStapAOrSingleNalu(parsed_payload, payload_data))
- return false;
+ return ProcessStapAOrSingleNalu(std::move(rtp_payload));
}
-
- const uint8_t* payload =
- modified_buffer_ ? modified_buffer_->data() : payload_data;
-
- parsed_payload->payload = payload + offset_;
- parsed_payload->payload_length = length_;
- return true;
}
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h
index 044ad03..cbea860 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h
@@ -11,33 +11,17 @@
#ifndef MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H264_H_
#define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H264_H_
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-
-#include "modules/rtp_rtcp/source/rtp_format.h"
-#include "rtc_base/buffer.h"
+#include "absl/types/optional.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h"
+#include "rtc_base/copy_on_write_buffer.h"
namespace webrtc {
-class RtpDepacketizerH264 : public RtpDepacketizer {
+class VideoRtpDepacketizerH264 : public VideoRtpDepacketizer {
public:
- RtpDepacketizerH264();
- ~RtpDepacketizerH264() override;
+ ~VideoRtpDepacketizerH264() override = default;
- bool Parse(ParsedPayload* parsed_payload,
- const uint8_t* payload_data,
- size_t payload_data_length) override;
-
- private:
- bool ParseFuaNalu(RtpDepacketizer::ParsedPayload* parsed_payload,
- const uint8_t* payload_data);
- bool ProcessStapAOrSingleNalu(RtpDepacketizer::ParsedPayload* parsed_payload,
- const uint8_t* payload_data);
-
- size_t offset_;
- size_t length_;
- std::unique_ptr<rtc::Buffer> modified_buffer_;
+ absl::optional<ParsedRtpPayload> Parse(
+ rtc::CopyOnWriteBuffer rtp_payload) override;
};
} // namespace webrtc
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264_unittest.cc
index d4467aa..d7e6147 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_h264_unittest.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h264_unittest.cc
@@ -10,14 +10,16 @@
#include "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h"
-#include <memory>
+#include <cstdint>
#include <vector>
+#include "absl/types/optional.h"
#include "api/array_view.h"
#include "common_video/h264/h264_common.h"
#include "modules/include/module_common_types.h"
#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "modules/rtp_rtcp/source/byte_io.h"
+#include "rtc_base/copy_on_write_buffer.h"
#include "test/gmock.h"
#include "test/gtest.h"
@@ -47,67 +49,56 @@
// Bit masks for FU (A and B) headers.
enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 };
-const uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03,
- 0xF4, 0x05, 0x03, 0xC7, 0xC0};
-const uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, 0xF4, 0x05, 0x03,
- 0xC7, 0xE0, 0x1B, 0x41, 0x10, 0x8D, 0x00};
-const uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04};
-const uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11};
+constexpr uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03,
+ 0xF4, 0x05, 0x03, 0xC7, 0xC0};
+constexpr uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03,
+ 0xF4, 0x05, 0x03, 0xC7, 0xE0,
+ 0x1B, 0x41, 0x10, 0x8D, 0x00};
+constexpr uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04};
+constexpr uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11};
-struct H264ParsedPayload : public RtpDepacketizer::ParsedPayload {
- RTPVideoHeaderH264& h264() {
- return absl::get<RTPVideoHeaderH264>(video.video_type_header);
- }
-};
-
-class RtpDepacketizerH264Test : public ::testing::Test {
- protected:
- RtpDepacketizerH264Test()
- : depacketizer_(std::make_unique<RtpDepacketizerH264>()) {}
-
- void ExpectPacket(H264ParsedPayload* parsed_payload,
- const uint8_t* data,
- size_t length) {
- ASSERT_TRUE(parsed_payload != NULL);
- EXPECT_THAT(std::vector<uint8_t>(
- parsed_payload->payload,
- parsed_payload->payload + parsed_payload->payload_length),
- ::testing::ElementsAreArray(data, length));
- }
-
- std::unique_ptr<RtpDepacketizer> depacketizer_;
-};
-
-TEST_F(RtpDepacketizerH264Test, TestSingleNalu) {
+TEST(VideoRtpDepacketizerH264Test, SingleNalu) {
uint8_t packet[2] = {0x05, 0xFF}; // F=0, NRI=0, Type=5 (IDR).
- H264ParsedPayload payload;
+ rtc::CopyOnWriteBuffer rtp_payload(packet);
- ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
- ExpectPacket(&payload, packet, sizeof(packet));
- EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type);
- EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
- EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- EXPECT_EQ(kH264SingleNalu, payload.h264().packetization_type);
- EXPECT_EQ(kIdr, payload.h264().nalu_type);
+ VideoRtpDepacketizerH264 depacketizer;
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+ depacketizer.Parse(rtp_payload);
+ ASSERT_TRUE(parsed);
+
+ EXPECT_EQ(parsed->video_payload, rtp_payload);
+ EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey);
+ EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
+ EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
+ const RTPVideoHeaderH264& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
+ EXPECT_EQ(h264.packetization_type, kH264SingleNalu);
+ EXPECT_EQ(h264.nalu_type, kIdr);
}
-TEST_F(RtpDepacketizerH264Test, TestSingleNaluSpsWithResolution) {
+TEST(VideoRtpDepacketizerH264Test, SingleNaluSpsWithResolution) {
uint8_t packet[] = {kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40, 0x50,
0x05, 0xBA, 0x10, 0x00, 0x00, 0x03, 0x00, 0xC0,
0x00, 0x00, 0x03, 0x2A, 0xE0, 0xF1, 0x83, 0x25};
- H264ParsedPayload payload;
+ rtc::CopyOnWriteBuffer rtp_payload(packet);
- ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
- ExpectPacket(&payload, packet, sizeof(packet));
- EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type);
- EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
- EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- EXPECT_EQ(kH264SingleNalu, payload.h264().packetization_type);
- EXPECT_EQ(1280u, payload.video_header().width);
- EXPECT_EQ(720u, payload.video_header().height);
+ VideoRtpDepacketizerH264 depacketizer;
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+ depacketizer.Parse(rtp_payload);
+ ASSERT_TRUE(parsed);
+
+ EXPECT_EQ(parsed->video_payload, rtp_payload);
+ EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey);
+ EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
+ EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
+ EXPECT_EQ(parsed->video_header.width, 1280u);
+ EXPECT_EQ(parsed->video_header.height, 720u);
+ const auto& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
+ EXPECT_EQ(h264.packetization_type, kH264SingleNalu);
}
-TEST_F(RtpDepacketizerH264Test, TestStapAKey) {
+TEST(VideoRtpDepacketizerH264Test, StapAKey) {
// clang-format off
const NaluInfo kExpectedNalus[] = { {H264::kSps, 0, -1},
{H264::kPps, 1, 2},
@@ -124,29 +115,34 @@
0, 0xB, kExpectedNalus[2].type,
0x85, 0xB8, 0x0, 0x4, 0x0, 0x0, 0x13, 0x93, 0x12, 0x0};
// clang-format on
+ rtc::CopyOnWriteBuffer rtp_payload(packet);
- H264ParsedPayload payload;
- ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
- ExpectPacket(&payload, packet, sizeof(packet));
- EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type);
- EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
- EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- const RTPVideoHeaderH264& h264 = payload.h264();
- EXPECT_EQ(kH264StapA, h264.packetization_type);
+ VideoRtpDepacketizerH264 depacketizer;
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+ depacketizer.Parse(rtp_payload);
+ ASSERT_TRUE(parsed);
+
+ EXPECT_EQ(parsed->video_payload, rtp_payload);
+ EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey);
+ EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
+ EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
+ const auto& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
+ EXPECT_EQ(h264.packetization_type, kH264StapA);
// NALU type for aggregated packets is the type of the first packet only.
- EXPECT_EQ(kSps, h264.nalu_type);
- ASSERT_EQ(3u, h264.nalus_length);
+ EXPECT_EQ(h264.nalu_type, kSps);
+ ASSERT_EQ(h264.nalus_length, 3u);
for (size_t i = 0; i < h264.nalus_length; ++i) {
- EXPECT_EQ(kExpectedNalus[i].type, h264.nalus[i].type)
+ EXPECT_EQ(h264.nalus[i].type, kExpectedNalus[i].type)
<< "Failed parsing nalu " << i;
- EXPECT_EQ(kExpectedNalus[i].sps_id, h264.nalus[i].sps_id)
+ EXPECT_EQ(h264.nalus[i].sps_id, kExpectedNalus[i].sps_id)
<< "Failed parsing nalu " << i;
- EXPECT_EQ(kExpectedNalus[i].pps_id, h264.nalus[i].pps_id)
+ EXPECT_EQ(h264.nalus[i].pps_id, kExpectedNalus[i].pps_id)
<< "Failed parsing nalu " << i;
}
}
-TEST_F(RtpDepacketizerH264Test, TestStapANaluSpsWithResolution) {
+TEST(VideoRtpDepacketizerH264Test, StapANaluSpsWithResolution) {
uint8_t packet[] = {kStapA, // F=0, NRI=0, Type=24.
// Length (2 bytes), nal header, payload.
0x00, 0x19, kSps, 0x7A, 0x00, 0x1F, 0xBC, 0xD9, 0x40,
@@ -154,45 +150,44 @@
0x00, 0x00, 0x03, 0x2A, 0xE0, 0xF1, 0x83, 0x25, 0x80,
0x00, 0x03, kIdr, 0xFF, 0x00, 0x00, 0x04, kIdr, 0xFF,
0x00, 0x11};
+ rtc::CopyOnWriteBuffer rtp_payload(packet);
- H264ParsedPayload payload;
+ VideoRtpDepacketizerH264 depacketizer;
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+ depacketizer.Parse(rtp_payload);
+ ASSERT_TRUE(parsed);
- ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
- ExpectPacket(&payload, packet, sizeof(packet));
- EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type);
- EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
- EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- EXPECT_EQ(kH264StapA, payload.h264().packetization_type);
- EXPECT_EQ(1280u, payload.video_header().width);
- EXPECT_EQ(720u, payload.video_header().height);
+ EXPECT_EQ(parsed->video_payload, rtp_payload);
+ EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey);
+ EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
+ EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
+ EXPECT_EQ(parsed->video_header.width, 1280u);
+ EXPECT_EQ(parsed->video_header.height, 720u);
+ const auto& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
+ EXPECT_EQ(h264.packetization_type, kH264StapA);
}
-TEST_F(RtpDepacketizerH264Test, TestEmptyStapARejected) {
+TEST(VideoRtpDepacketizerH264Test, EmptyStapARejected) {
uint8_t lone_empty_packet[] = {kStapA, 0x00, 0x00};
-
uint8_t leading_empty_packet[] = {kStapA, 0x00, 0x00, 0x00, 0x04,
kIdr, 0xFF, 0x00, 0x11};
-
uint8_t middle_empty_packet[] = {kStapA, 0x00, 0x03, kIdr, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x04, kIdr, 0xFF, 0x00, 0x11};
-
uint8_t trailing_empty_packet[] = {kStapA, 0x00, 0x03, kIdr,
0xFF, 0x00, 0x00, 0x00};
- H264ParsedPayload payload;
-
- EXPECT_FALSE(depacketizer_->Parse(&payload, lone_empty_packet,
- sizeof(lone_empty_packet)));
- EXPECT_FALSE(depacketizer_->Parse(&payload, leading_empty_packet,
- sizeof(leading_empty_packet)));
- EXPECT_FALSE(depacketizer_->Parse(&payload, middle_empty_packet,
- sizeof(middle_empty_packet)));
- EXPECT_FALSE(depacketizer_->Parse(&payload, trailing_empty_packet,
- sizeof(trailing_empty_packet)));
+ VideoRtpDepacketizerH264 depacketizer;
+ EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(lone_empty_packet)));
+ EXPECT_FALSE(
+ depacketizer.Parse(rtc::CopyOnWriteBuffer(leading_empty_packet)));
+ EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(middle_empty_packet)));
+ EXPECT_FALSE(
+ depacketizer.Parse(rtc::CopyOnWriteBuffer(trailing_empty_packet)));
}
-TEST_F(RtpDepacketizerH264Test, DepacketizeWithRewriting) {
- rtc::Buffer in_buffer;
+TEST(VideoRtpDepacketizerH264Test, DepacketizeWithRewriting) {
+ rtc::CopyOnWriteBuffer in_buffer;
rtc::Buffer out_buffer;
uint8_t kHeader[2] = {kStapA};
@@ -218,20 +213,16 @@
out_buffer.AppendData(kHeader, 2);
out_buffer.AppendData(kIdrTwo);
- H264ParsedPayload payload;
- EXPECT_TRUE(
- depacketizer_->Parse(&payload, in_buffer.data(), in_buffer.size()));
-
- std::vector<uint8_t> expected_packet_payload(
- out_buffer.data(), &out_buffer.data()[out_buffer.size()]);
-
- EXPECT_THAT(
- expected_packet_payload,
- ::testing::ElementsAreArray(payload.payload, payload.payload_length));
+ VideoRtpDepacketizerH264 depacketizer;
+ auto parsed = depacketizer.Parse(in_buffer);
+ ASSERT_TRUE(parsed);
+ EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(),
+ parsed->video_payload.size()),
+ ElementsAreArray(out_buffer));
}
-TEST_F(RtpDepacketizerH264Test, DepacketizeWithDoubleRewriting) {
- rtc::Buffer in_buffer;
+TEST(VideoRtpDepacketizerH264Test, DepacketizeWithDoubleRewriting) {
+ rtc::CopyOnWriteBuffer in_buffer;
rtc::Buffer out_buffer;
uint8_t kHeader[2] = {kStapA};
@@ -265,37 +256,42 @@
out_buffer.AppendData(kHeader, 2);
out_buffer.AppendData(kIdrTwo);
- H264ParsedPayload payload;
- EXPECT_TRUE(
- depacketizer_->Parse(&payload, in_buffer.data(), in_buffer.size()));
-
+ VideoRtpDepacketizerH264 depacketizer;
+ auto parsed = depacketizer.Parse(in_buffer);
+ ASSERT_TRUE(parsed);
std::vector<uint8_t> expected_packet_payload(
out_buffer.data(), &out_buffer.data()[out_buffer.size()]);
-
- EXPECT_THAT(
- expected_packet_payload,
- ::testing::ElementsAreArray(payload.payload, payload.payload_length));
+ EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(),
+ parsed->video_payload.size()),
+ ElementsAreArray(out_buffer));
}
-TEST_F(RtpDepacketizerH264Test, TestStapADelta) {
+TEST(VideoRtpDepacketizerH264Test, StapADelta) {
uint8_t packet[16] = {kStapA, // F=0, NRI=0, Type=24.
// Length, nal header, payload.
0, 0x02, kSlice, 0xFF, 0, 0x03, kSlice, 0xFF, 0x00, 0,
0x04, kSlice, 0xFF, 0x00, 0x11};
- H264ParsedPayload payload;
+ rtc::CopyOnWriteBuffer rtp_payload(packet);
- ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet)));
- ExpectPacket(&payload, packet, sizeof(packet));
- EXPECT_EQ(VideoFrameType::kVideoFrameDelta,
- payload.video_header().frame_type);
- EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
- EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- EXPECT_EQ(kH264StapA, payload.h264().packetization_type);
+ VideoRtpDepacketizerH264 depacketizer;
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed =
+ depacketizer.Parse(rtp_payload);
+ ASSERT_TRUE(parsed);
+
+ EXPECT_EQ(parsed->video_payload.size(), rtp_payload.size());
+ EXPECT_EQ(parsed->video_payload.cdata(), rtp_payload.cdata());
+
+ EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameDelta);
+ EXPECT_EQ(parsed->video_header.codec, kVideoCodecH264);
+ EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame);
+ const RTPVideoHeaderH264& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
+ EXPECT_EQ(h264.packetization_type, kH264StapA);
// NALU type for aggregated packets is the type of the first packet only.
- EXPECT_EQ(kSlice, payload.h264().nalu_type);
+ EXPECT_EQ(h264.nalu_type, kSlice);
}
-TEST_F(RtpDepacketizerH264Test, TestFuA) {
+TEST(VideoRtpDepacketizerH264Test, FuA) {
// clang-format off
uint8_t packet1[] = {
kFuA, // F=0, NRI=0, Type=28.
@@ -320,107 +316,115 @@
};
const uint8_t kExpected3[] = {0x03};
- H264ParsedPayload payload;
-
+ VideoRtpDepacketizerH264 depacketizer;
+ absl::optional<VideoRtpDepacketizer::ParsedRtpPayload> parsed1 =
+ depacketizer.Parse(rtc::CopyOnWriteBuffer(packet1));
+ ASSERT_TRUE(parsed1);
// We expect that the first packet is one byte shorter since the FU-A header
// has been replaced by the original nal header.
- ASSERT_TRUE(depacketizer_->Parse(&payload, packet1, sizeof(packet1)));
- ExpectPacket(&payload, kExpected1, sizeof(kExpected1));
- EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type);
- EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
- EXPECT_TRUE(payload.video_header().is_first_packet_in_frame);
- const RTPVideoHeaderH264& h264 = payload.h264();
- EXPECT_EQ(kH264FuA, h264.packetization_type);
- EXPECT_EQ(kIdr, h264.nalu_type);
- ASSERT_EQ(1u, h264.nalus_length);
- EXPECT_EQ(static_cast<H264::NaluType>(kIdr), h264.nalus[0].type);
- EXPECT_EQ(-1, h264.nalus[0].sps_id);
- EXPECT_EQ(0, h264.nalus[0].pps_id);
+ EXPECT_THAT(rtc::MakeArrayView(parsed1->video_payload.cdata(),
+ parsed1->video_payload.size()),
+ ElementsAreArray(kExpected1));
+ EXPECT_EQ(parsed1->video_header.frame_type, VideoFrameType::kVideoFrameKey);
+ EXPECT_EQ(parsed1->video_header.codec, kVideoCodecH264);
+ EXPECT_TRUE(parsed1->video_header.is_first_packet_in_frame);
+ {
+ const RTPVideoHeaderH264& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed1->video_header.video_type_header);
+ EXPECT_EQ(h264.packetization_type, kH264FuA);
+ EXPECT_EQ(h264.nalu_type, kIdr);
+ ASSERT_EQ(h264.nalus_length, 1u);
+ EXPECT_EQ(h264.nalus[0].type, static_cast<H264::NaluType>(kIdr));
+ EXPECT_EQ(h264.nalus[0].sps_id, -1);
+ EXPECT_EQ(h264.nalus[0].pps_id, 0);
+ }
// Following packets will be 2 bytes shorter since they will only be appended
// onto the first packet.
- payload = H264ParsedPayload();
- ASSERT_TRUE(depacketizer_->Parse(&payload, packet2, sizeof(packet2)));
- ExpectPacket(&payload, kExpected2, sizeof(kExpected2));
- EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type);
- EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
- EXPECT_FALSE(payload.video_header().is_first_packet_in_frame);
+ auto parsed2 = depacketizer.Parse(rtc::CopyOnWriteBuffer(packet2));
+ EXPECT_THAT(rtc::MakeArrayView(parsed2->video_payload.cdata(),
+ parsed2->video_payload.size()),
+ ElementsAreArray(kExpected2));
+ EXPECT_FALSE(parsed2->video_header.is_first_packet_in_frame);
+ EXPECT_EQ(parsed2->video_header.codec, kVideoCodecH264);
{
- const RTPVideoHeaderH264& h264 = payload.h264();
- EXPECT_EQ(kH264FuA, h264.packetization_type);
- EXPECT_EQ(kIdr, h264.nalu_type);
+ const RTPVideoHeaderH264& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed2->video_header.video_type_header);
+ EXPECT_EQ(h264.packetization_type, kH264FuA);
+ EXPECT_EQ(h264.nalu_type, kIdr);
// NALU info is only expected for the first FU-A packet.
- EXPECT_EQ(0u, h264.nalus_length);
+ EXPECT_EQ(h264.nalus_length, 0u);
}
- payload = H264ParsedPayload();
- ASSERT_TRUE(depacketizer_->Parse(&payload, packet3, sizeof(packet3)));
- ExpectPacket(&payload, kExpected3, sizeof(kExpected3));
- EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type);
- EXPECT_EQ(kVideoCodecH264, payload.video_header().codec);
- EXPECT_FALSE(payload.video_header().is_first_packet_in_frame);
+ auto parsed3 = depacketizer.Parse(rtc::CopyOnWriteBuffer(packet3));
+ EXPECT_THAT(rtc::MakeArrayView(parsed3->video_payload.cdata(),
+ parsed3->video_payload.size()),
+ ElementsAreArray(kExpected3));
+ EXPECT_FALSE(parsed3->video_header.is_first_packet_in_frame);
+ EXPECT_EQ(parsed3->video_header.codec, kVideoCodecH264);
{
- const RTPVideoHeaderH264& h264 = payload.h264();
- EXPECT_EQ(kH264FuA, h264.packetization_type);
- EXPECT_EQ(kIdr, h264.nalu_type);
+ const RTPVideoHeaderH264& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed3->video_header.video_type_header);
+ EXPECT_EQ(h264.packetization_type, kH264FuA);
+ EXPECT_EQ(h264.nalu_type, kIdr);
// NALU info is only expected for the first FU-A packet.
- ASSERT_EQ(0u, h264.nalus_length);
+ ASSERT_EQ(h264.nalus_length, 0u);
}
}
-TEST_F(RtpDepacketizerH264Test, TestEmptyPayload) {
- // Using a wild pointer to crash on accesses from inside the depacketizer.
- uint8_t* garbage_ptr = reinterpret_cast<uint8_t*>(0x4711);
- H264ParsedPayload payload;
- EXPECT_FALSE(depacketizer_->Parse(&payload, garbage_ptr, 0));
+TEST(VideoRtpDepacketizerH264Test, EmptyPayload) {
+ rtc::CopyOnWriteBuffer empty;
+ VideoRtpDepacketizerH264 depacketizer;
+ EXPECT_FALSE(depacketizer.Parse(empty));
}
-TEST_F(RtpDepacketizerH264Test, TestTruncatedFuaNalu) {
+TEST(VideoRtpDepacketizerH264Test, TruncatedFuaNalu) {
const uint8_t kPayload[] = {0x9c};
- H264ParsedPayload payload;
- EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
+ VideoRtpDepacketizerH264 depacketizer;
+ EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
}
-TEST_F(RtpDepacketizerH264Test, TestTruncatedSingleStapANalu) {
+TEST(VideoRtpDepacketizerH264Test, TruncatedSingleStapANalu) {
const uint8_t kPayload[] = {0xd8, 0x27};
- H264ParsedPayload payload;
- EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
+ VideoRtpDepacketizerH264 depacketizer;
+ EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
}
-TEST_F(RtpDepacketizerH264Test, TestStapAPacketWithTruncatedNalUnits) {
+TEST(VideoRtpDepacketizerH264Test, StapAPacketWithTruncatedNalUnits) {
const uint8_t kPayload[] = {0x58, 0xCB, 0xED, 0xDF};
- H264ParsedPayload payload;
- EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
+ VideoRtpDepacketizerH264 depacketizer;
+ EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
}
-TEST_F(RtpDepacketizerH264Test, TestTruncationJustAfterSingleStapANalu) {
+TEST(VideoRtpDepacketizerH264Test, TruncationJustAfterSingleStapANalu) {
const uint8_t kPayload[] = {0x38, 0x27, 0x27};
- H264ParsedPayload payload;
- EXPECT_FALSE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
+ VideoRtpDepacketizerH264 depacketizer;
+ EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
}
-TEST_F(RtpDepacketizerH264Test, TestShortSpsPacket) {
+TEST(VideoRtpDepacketizerH264Test, ShortSpsPacket) {
const uint8_t kPayload[] = {0x27, 0x80, 0x00};
- H264ParsedPayload payload;
- EXPECT_TRUE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
+ VideoRtpDepacketizerH264 depacketizer;
+ EXPECT_TRUE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)));
}
-TEST_F(RtpDepacketizerH264Test, TestSeiPacket) {
+TEST(VideoRtpDepacketizerH264Test, SeiPacket) {
const uint8_t kPayload[] = {
kSei, // F=0, NRI=0, Type=6.
0x03, 0x03, 0x03, 0x03 // Payload.
};
- H264ParsedPayload payload;
- ASSERT_TRUE(depacketizer_->Parse(&payload, kPayload, sizeof(kPayload)));
- const RTPVideoHeaderH264& h264 = payload.h264();
- EXPECT_EQ(VideoFrameType::kVideoFrameDelta,
- payload.video_header().frame_type);
- EXPECT_EQ(kH264SingleNalu, h264.packetization_type);
- EXPECT_EQ(kSei, h264.nalu_type);
- ASSERT_EQ(1u, h264.nalus_length);
- EXPECT_EQ(static_cast<H264::NaluType>(kSei), h264.nalus[0].type);
- EXPECT_EQ(-1, h264.nalus[0].sps_id);
- EXPECT_EQ(-1, h264.nalus[0].pps_id);
+ VideoRtpDepacketizerH264 depacketizer;
+ auto parsed = depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload));
+ ASSERT_TRUE(parsed);
+ const RTPVideoHeaderH264& h264 =
+ absl::get<RTPVideoHeaderH264>(parsed->video_header.video_type_header);
+ EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameDelta);
+ EXPECT_EQ(h264.packetization_type, kH264SingleNalu);
+ EXPECT_EQ(h264.nalu_type, kSei);
+ ASSERT_EQ(h264.nalus_length, 1u);
+ EXPECT_EQ(h264.nalus[0].type, static_cast<H264::NaluType>(kSei));
+ EXPECT_EQ(h264.nalus[0].sps_id, -1);
+ EXPECT_EQ(h264.nalus[0].pps_id, -1);
}
} // namespace
diff --git a/test/fuzzers/h264_depacketizer_fuzzer.cc b/test/fuzzers/h264_depacketizer_fuzzer.cc
index 9b6455b..9712722 100644
--- a/test/fuzzers/h264_depacketizer_fuzzer.cc
+++ b/test/fuzzers/h264_depacketizer_fuzzer.cc
@@ -7,14 +7,13 @@
* 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_format_h264.h"
+#include "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h"
namespace webrtc {
void FuzzOneInput(const uint8_t* data, size_t size) {
if (size > 200000)
return;
- RtpDepacketizerH264 depacketizer;
- RtpDepacketizer::ParsedPayload parsed_payload;
- depacketizer.Parse(&parsed_payload, data, size);
+ VideoRtpDepacketizerH264 depacketizer;
+ depacketizer.Parse(rtc::CopyOnWriteBuffer(data, size));
}
} // namespace webrtc