Support header only parsing by RtpPacket

It is not uncommon to save rtp header of an rtp packet for later parsing
(e.g. rtc event log does that)
Such header is invalid as an rtp packet when padding bit is set.
This change suggest to treat header only packets with padding as valid.

Bug: webrtc:5261
Change-Id: If61d84fc37383d2e9cfaf9b618276983d334702e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/225265
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34438}
This commit is contained in:
Danil Chapovalov 2021-07-08 13:03:38 +00:00 committed by WebRTC LUCI CQ
parent ea9ae5b8bc
commit 44450a073b
3 changed files with 81 additions and 10 deletions

View File

@ -466,16 +466,6 @@ bool RtpPacket::ParseBuffer(const uint8_t* buffer, size_t size) {
}
payload_offset_ = kFixedHeaderSize + number_of_crcs * 4;
if (has_padding) {
padding_size_ = buffer[size - 1];
if (padding_size_ == 0) {
RTC_LOG(LS_WARNING) << "Padding was set, but padding size is zero";
return false;
}
} else {
padding_size_ = 0;
}
extensions_size_ = 0;
extension_entries_.clear();
if (has_extension) {
@ -556,6 +546,16 @@ bool RtpPacket::ParseBuffer(const uint8_t* buffer, size_t size) {
payload_offset_ = extension_offset + extensions_capacity;
}
if (has_padding && payload_offset_ < size) {
padding_size_ = buffer[size - 1];
if (padding_size_ == 0) {
RTC_LOG(LS_WARNING) << "Padding was set, but padding size is zero";
return false;
}
} else {
padding_size_ = 0;
}
if (payload_offset_ + padding_size_ > size) {
return false;
}

View File

@ -65,6 +65,7 @@ class RtpPacket {
// Payload.
size_t payload_size() const { return payload_size_; }
bool has_padding() const { return buffer_[0] & 0x20; }
size_t padding_size() const { return padding_size_; }
rtc::ArrayView<const uint8_t> payload() const {
return rtc::MakeArrayView(data() + payload_offset_, payload_size_);

View File

@ -504,6 +504,76 @@ TEST(RtpPacketTest, ParseWithExtension) {
EXPECT_EQ(0u, packet.padding_size());
}
TEST(RtpPacketTest, ParseHeaderOnly) {
// clang-format off
constexpr uint8_t kPaddingHeader[] = {
0x80, 0x62, 0x35, 0x79,
0x65, 0x43, 0x12, 0x78,
0x12, 0x34, 0x56, 0x78};
// clang-format on
RtpPacket packet;
EXPECT_TRUE(packet.Parse(rtc::CopyOnWriteBuffer(kPaddingHeader)));
EXPECT_EQ(packet.PayloadType(), 0x62u);
EXPECT_EQ(packet.SequenceNumber(), 0x3579u);
EXPECT_EQ(packet.Timestamp(), 0x65431278u);
EXPECT_EQ(packet.Ssrc(), 0x12345678u);
EXPECT_FALSE(packet.has_padding());
EXPECT_EQ(packet.padding_size(), 0u);
EXPECT_EQ(packet.payload_size(), 0u);
}
TEST(RtpPacketTest, ParseHeaderOnlyWithPadding) {
// clang-format off
constexpr uint8_t kPaddingHeader[] = {
0xa0, 0x62, 0x35, 0x79,
0x65, 0x43, 0x12, 0x78,
0x12, 0x34, 0x56, 0x78};
// clang-format on
RtpPacket packet;
EXPECT_TRUE(packet.Parse(rtc::CopyOnWriteBuffer(kPaddingHeader)));
EXPECT_TRUE(packet.has_padding());
EXPECT_EQ(packet.padding_size(), 0u);
EXPECT_EQ(packet.payload_size(), 0u);
}
TEST(RtpPacketTest, ParseHeaderOnlyWithExtensionAndPadding) {
// clang-format off
constexpr uint8_t kPaddingHeader[] = {
0xb0, 0x62, 0x35, 0x79,
0x65, 0x43, 0x12, 0x78,
0x12, 0x34, 0x56, 0x78,
0xbe, 0xde, 0x00, 0x01,
0x11, 0x00, 0x00, 0x00};
// clang-format on
RtpHeaderExtensionMap extensions;
extensions.Register<TransmissionOffset>(1);
RtpPacket packet(&extensions);
EXPECT_TRUE(packet.Parse(rtc::CopyOnWriteBuffer(kPaddingHeader)));
EXPECT_TRUE(packet.has_padding());
EXPECT_TRUE(packet.HasExtension<TransmissionOffset>());
EXPECT_EQ(packet.padding_size(), 0u);
}
TEST(RtpPacketTest, ParsePaddingOnlyPacket) {
// clang-format off
constexpr uint8_t kPaddingHeader[] = {
0xa0, 0x62, 0x35, 0x79,
0x65, 0x43, 0x12, 0x78,
0x12, 0x34, 0x56, 0x78,
0, 0, 3};
// clang-format on
RtpPacket packet;
EXPECT_TRUE(packet.Parse(rtc::CopyOnWriteBuffer(kPaddingHeader)));
EXPECT_TRUE(packet.has_padding());
EXPECT_EQ(packet.padding_size(), 3u);
}
TEST(RtpPacketTest, GetExtensionWithoutParametersReturnsOptionalValue) {
RtpPacket::ExtensionManager extensions;
extensions.Register<TransmissionOffset>(kTransmissionOffsetExtensionId);