diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.cc b/modules/rtp_rtcp/source/rtp_format_vp8.cc index c31be7db8c..5005c00fb6 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp8.cc +++ b/modules/rtp_rtcp/source/rtp_format_vp8.cc @@ -163,19 +163,4 @@ RtpPacketizerVp8::RawHeader RtpPacketizerVp8::BuildHeader( return result; } -bool RtpDepacketizerVp8::Parse(ParsedPayload* parsed_payload, - const uint8_t* payload_data, - size_t payload_data_length) { - RTC_DCHECK(parsed_payload); - int offset = VideoRtpDepacketizerVp8::ParseRtpPayload( - rtc::MakeArrayView(payload_data, payload_data_length), - &parsed_payload->video); - if (offset == 0) { - return false; - } - parsed_payload->payload = payload_data + offset; - parsed_payload->payload_length = payload_data_length - offset; - return true; -} - } // namespace webrtc diff --git a/modules/rtp_rtcp/source/rtp_format_vp8.h b/modules/rtp_rtcp/source/rtp_format_vp8.h index 6e9cbb41d6..4250736582 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp8.h +++ b/modules/rtp_rtcp/source/rtp_format_vp8.h @@ -70,14 +70,5 @@ class RtpPacketizerVp8 : public RtpPacketizer { RTC_DISALLOW_COPY_AND_ASSIGN(RtpPacketizerVp8); }; -// Depacketizer for VP8. -class RtpDepacketizerVp8 : public RtpDepacketizer { - public: - ~RtpDepacketizerVp8() override = default; - - bool Parse(ParsedPayload* parsed_payload, - const uint8_t* payload_data, - size_t payload_data_length) override; -}; } // namespace webrtc #endif // MODULES_RTP_RTCP_SOURCE_RTP_FORMAT_VP8_H_ diff --git a/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc b/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc index 2baf90937a..7934ff8ea9 100644 --- a/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_format_vp8_unittest.cc @@ -13,73 +13,13 @@ #include #include "modules/rtp_rtcp/source/rtp_format_vp8_test_helper.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" #include "test/gmock.h" #include "test/gtest.h" namespace webrtc { namespace { -using ::testing::ElementsAreArray; -using ::testing::make_tuple; - -constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr; constexpr RtpPacketizer::PayloadSizeLimits kNoSizeLimits; -// Payload descriptor -// 0 1 2 3 4 5 6 7 -// +-+-+-+-+-+-+-+-+ -// |X|R|N|S|PartID | (REQUIRED) -// +-+-+-+-+-+-+-+-+ -// X: |I|L|T|K| RSV | (OPTIONAL) -// +-+-+-+-+-+-+-+-+ -// I: | PictureID | (OPTIONAL) -// +-+-+-+-+-+-+-+-+ -// L: | TL0PICIDX | (OPTIONAL) -// +-+-+-+-+-+-+-+-+ -// T/K: |TID:Y| KEYIDX | (OPTIONAL) -// +-+-+-+-+-+-+-+-+ -// -// Payload header -// 0 1 2 3 4 5 6 7 -// +-+-+-+-+-+-+-+-+ -// |Size0|H| VER |P| -// +-+-+-+-+-+-+-+-+ -// | Size1 | -// +-+-+-+-+-+-+-+-+ -// | Size2 | -// +-+-+-+-+-+-+-+-+ -// | Bytes 4..N of | -// | VP8 payload | -// : : -// +-+-+-+-+-+-+-+-+ -// | OPTIONAL RTP | -// | padding | -// : : -// +-+-+-+-+-+-+-+-+ -void VerifyBasicHeader(RTPVideoHeader* header, bool N, bool S, int part_id) { - ASSERT_TRUE(header != NULL); - const auto& vp8_header = - absl::get(header->video_type_header); - EXPECT_EQ(N, vp8_header.nonReference); - EXPECT_EQ(S, vp8_header.beginningOfPartition); - EXPECT_EQ(part_id, vp8_header.partitionId); -} - -void VerifyExtensions(RTPVideoHeader* header, - int16_t picture_id, /* I */ - int16_t tl0_pic_idx, /* L */ - uint8_t temporal_idx, /* T */ - int key_idx /* K */) { - ASSERT_TRUE(header != NULL); - const auto& vp8_header = - absl::get(header->video_type_header); - EXPECT_EQ(picture_id, vp8_header.pictureId); - EXPECT_EQ(tl0_pic_idx, vp8_header.tl0PicIdx); - EXPECT_EQ(temporal_idx, vp8_header.temporalIdx); - EXPECT_EQ(key_idx, vp8_header.keyIdx); -} - -} // namespace TEST(RtpPacketizerVp8Test, ResultPacketsAreAlmostEqualSize) { RTPVideoHeaderVP8 hdr_info; @@ -171,208 +111,5 @@ TEST(RtpPacketizerVp8Test, TIDAndKeyIdx) { helper.GetAllPacketsAndCheck(&packetizer, kExpectedSizes); } -class RtpDepacketizerVp8Test : public ::testing::Test { - protected: - RtpDepacketizerVp8Test() - : depacketizer_(std::make_unique()) {} - - void ExpectPacket(RtpDepacketizer::ParsedPayload* parsed_payload, - const uint8_t* data, - size_t length) { - ASSERT_TRUE(parsed_payload != NULL); - EXPECT_THAT( - make_tuple(parsed_payload->payload, parsed_payload->payload_length), - ElementsAreArray(data, length)); - } - - std::unique_ptr depacketizer_; -}; - -TEST_F(RtpDepacketizerVp8Test, BasicHeader) { - const uint8_t kHeaderLength = 1; - uint8_t packet[4] = {0}; - packet[0] = 0x14; // Binary 0001 0100; S = 1, PartID = 4. - packet[1] = 0x01; // P frame. - RtpDepacketizer::ParsedPayload payload; - - ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); - ExpectPacket(&payload, packet + kHeaderLength, - sizeof(packet) - kHeaderLength); - - EXPECT_EQ(VideoFrameType::kVideoFrameDelta, - payload.video_header().frame_type); - EXPECT_EQ(kVideoCodecVP8, payload.video_header().codec); - VerifyBasicHeader(&payload.video_header(), 0, 1, 4); - VerifyExtensions(&payload.video_header(), kNoPictureId, kNoTl0PicIdx, - kNoTemporalIdx, kNoKeyIdx); -} - -TEST_F(RtpDepacketizerVp8Test, PictureID) { - const uint8_t kHeaderLength1 = 3; - const uint8_t kHeaderLength2 = 4; - const uint8_t kPictureId = 17; - uint8_t packet[10] = {0}; - packet[0] = 0xA0; - packet[1] = 0x80; - packet[2] = kPictureId; - RtpDepacketizer::ParsedPayload payload; - - ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); - ExpectPacket(&payload, packet + kHeaderLength1, - sizeof(packet) - kHeaderLength1); - EXPECT_EQ(VideoFrameType::kVideoFrameDelta, - payload.video_header().frame_type); - EXPECT_EQ(kVideoCodecVP8, payload.video_header().codec); - VerifyBasicHeader(&payload.video_header(), 1, 0, 0); - VerifyExtensions(&payload.video_header(), kPictureId, kNoTl0PicIdx, - kNoTemporalIdx, kNoKeyIdx); - - // Re-use packet, but change to long PictureID. - packet[2] = 0x80 | kPictureId; - packet[3] = kPictureId; - - payload = RtpDepacketizer::ParsedPayload(); - ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); - ExpectPacket(&payload, packet + kHeaderLength2, - sizeof(packet) - kHeaderLength2); - VerifyBasicHeader(&payload.video_header(), 1, 0, 0); - VerifyExtensions(&payload.video_header(), (kPictureId << 8) + kPictureId, - kNoTl0PicIdx, kNoTemporalIdx, kNoKeyIdx); -} - -TEST_F(RtpDepacketizerVp8Test, Tl0PicIdx) { - const uint8_t kHeaderLength = 3; - const uint8_t kTl0PicIdx = 17; - uint8_t packet[13] = {0}; - packet[0] = 0x90; - packet[1] = 0x40; - packet[2] = kTl0PicIdx; - RtpDepacketizer::ParsedPayload payload; - - ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); - ExpectPacket(&payload, packet + kHeaderLength, - sizeof(packet) - kHeaderLength); - EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type); - EXPECT_EQ(kVideoCodecVP8, payload.video_header().codec); - VerifyBasicHeader(&payload.video_header(), 0, 1, 0); - VerifyExtensions(&payload.video_header(), kNoPictureId, kTl0PicIdx, - kNoTemporalIdx, kNoKeyIdx); -} - -TEST_F(RtpDepacketizerVp8Test, TIDAndLayerSync) { - const uint8_t kHeaderLength = 3; - uint8_t packet[10] = {0}; - packet[0] = 0x88; - packet[1] = 0x20; - packet[2] = 0x80; // TID(2) + LayerSync(false) - RtpDepacketizer::ParsedPayload payload; - - ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); - ExpectPacket(&payload, packet + kHeaderLength, - sizeof(packet) - kHeaderLength); - EXPECT_EQ(VideoFrameType::kVideoFrameDelta, - payload.video_header().frame_type); - EXPECT_EQ(kVideoCodecVP8, payload.video_header().codec); - VerifyBasicHeader(&payload.video_header(), 0, 0, 8); - VerifyExtensions(&payload.video_header(), kNoPictureId, kNoTl0PicIdx, 2, - kNoKeyIdx); - EXPECT_FALSE( - absl::get(payload.video_header().video_type_header) - .layerSync); -} - -TEST_F(RtpDepacketizerVp8Test, KeyIdx) { - const uint8_t kHeaderLength = 3; - const uint8_t kKeyIdx = 17; - uint8_t packet[10] = {0}; - packet[0] = 0x88; - packet[1] = 0x10; // K = 1. - packet[2] = kKeyIdx; - RtpDepacketizer::ParsedPayload payload; - - ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); - ExpectPacket(&payload, packet + kHeaderLength, - sizeof(packet) - kHeaderLength); - EXPECT_EQ(VideoFrameType::kVideoFrameDelta, - payload.video_header().frame_type); - EXPECT_EQ(kVideoCodecVP8, payload.video_header().codec); - VerifyBasicHeader(&payload.video_header(), 0, 0, 8); - VerifyExtensions(&payload.video_header(), kNoPictureId, kNoTl0PicIdx, - kNoTemporalIdx, kKeyIdx); -} - -TEST_F(RtpDepacketizerVp8Test, MultipleExtensions) { - const uint8_t kHeaderLength = 6; - uint8_t packet[10] = {0}; - packet[0] = 0x88; - packet[1] = 0x80 | 0x40 | 0x20 | 0x10; - packet[2] = 0x80 | 17; // PictureID, high 7 bits. - packet[3] = 17; // PictureID, low 8 bits. - packet[4] = 42; // Tl0PicIdx. - packet[5] = 0x40 | 0x20 | 0x11; // TID(1) + LayerSync(true) + KEYIDX(17). - RtpDepacketizer::ParsedPayload payload; - - ASSERT_TRUE(depacketizer_->Parse(&payload, packet, sizeof(packet))); - ExpectPacket(&payload, packet + kHeaderLength, - sizeof(packet) - kHeaderLength); - EXPECT_EQ(VideoFrameType::kVideoFrameDelta, - payload.video_header().frame_type); - EXPECT_EQ(kVideoCodecVP8, payload.video_header().codec); - VerifyBasicHeader(&payload.video_header(), 0, 0, 8); - VerifyExtensions(&payload.video_header(), (17 << 8) + 17, 42, 1, 17); -} - -TEST_F(RtpDepacketizerVp8Test, TooShortHeader) { - uint8_t packet[4] = {0}; - packet[0] = 0x88; - packet[1] = 0x80 | 0x40 | 0x20 | 0x10; // All extensions are enabled... - packet[2] = 0x80 | 17; // ... but only 2 bytes PictureID is provided. - packet[3] = 17; // PictureID, low 8 bits. - RtpDepacketizer::ParsedPayload payload; - - EXPECT_FALSE(depacketizer_->Parse(&payload, packet, sizeof(packet))); -} - -TEST_F(RtpDepacketizerVp8Test, TestWithPacketizer) { - const uint8_t kHeaderLength = 5; - uint8_t data[10] = {0}; - RtpPacketToSend packet(kNoExtensions); - RTPVideoHeaderVP8 input_header; - input_header.nonReference = true; - input_header.pictureId = 300; - input_header.temporalIdx = 1; - input_header.layerSync = false; - input_header.tl0PicIdx = kNoTl0PicIdx; // Disable. - input_header.keyIdx = 31; - RtpPacketizer::PayloadSizeLimits limits; - limits.max_payload_len = 20; - RtpPacketizerVp8 packetizer(data, limits, input_header); - EXPECT_EQ(packetizer.NumPackets(), 1u); - ASSERT_TRUE(packetizer.NextPacket(&packet)); - EXPECT_TRUE(packet.Marker()); - - auto rtp_payload = packet.payload(); - RtpDepacketizer::ParsedPayload payload; - ASSERT_TRUE( - depacketizer_->Parse(&payload, rtp_payload.data(), rtp_payload.size())); - auto vp8_payload = rtp_payload.subview(kHeaderLength); - ExpectPacket(&payload, vp8_payload.data(), vp8_payload.size()); - EXPECT_EQ(VideoFrameType::kVideoFrameKey, payload.video_header().frame_type); - EXPECT_EQ(kVideoCodecVP8, payload.video_header().codec); - VerifyBasicHeader(&payload.video_header(), 1, 1, 0); - VerifyExtensions(&payload.video_header(), input_header.pictureId, - input_header.tl0PicIdx, input_header.temporalIdx, - input_header.keyIdx); - EXPECT_EQ( - absl::get(payload.video_header().video_type_header) - .layerSync, - input_header.layerSync); -} - -TEST_F(RtpDepacketizerVp8Test, TestEmptyPayload) { - // Using a wild pointer to crash on accesses from inside the depacketizer. - uint8_t* garbage_ptr = reinterpret_cast(0x4711); - RtpDepacketizer::ParsedPayload payload; - EXPECT_FALSE(depacketizer_->Parse(&payload, garbage_ptr, 0)); -} +} // namespace } // namespace webrtc diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn index b95773d533..b405d78c28 100644 --- a/test/fuzzers/BUILD.gn +++ b/test/fuzzers/BUILD.gn @@ -77,7 +77,9 @@ webrtc_fuzzer_test("vp8_depacketizer_fuzzer") { "vp8_depacketizer_fuzzer.cc", ] deps = [ + "../../api:array_view", "../../modules/rtp_rtcp", + "../../modules/rtp_rtcp:rtp_video_header", ] } diff --git a/test/fuzzers/vp8_depacketizer_fuzzer.cc b/test/fuzzers/vp8_depacketizer_fuzzer.cc index bd9ac8ffb2..1691b55cc0 100644 --- a/test/fuzzers/vp8_depacketizer_fuzzer.cc +++ b/test/fuzzers/vp8_depacketizer_fuzzer.cc @@ -7,12 +7,14 @@ * 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_vp8.h" +#include "api/array_view.h" +#include "modules/rtp_rtcp/source/rtp_video_header.h" +#include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h" namespace webrtc { void FuzzOneInput(const uint8_t* data, size_t size) { - RtpDepacketizerVp8 depacketizer; - RtpDepacketizer::ParsedPayload parsed_payload; - depacketizer.Parse(&parsed_payload, data, size); + RTPVideoHeader video_header; + VideoRtpDepacketizerVp8::ParseRtpPayload(rtc::MakeArrayView(data, size), + &video_header); } } // namespace webrtc