Fix handling of large packets in RtxReceiveStream
Bug: webrtc:10999
Change-Id: If0c93d2b6c2ea957ac5dcc51dd69b71d2f5306a2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/156168
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29426}
diff --git a/call/rtx_receive_stream_unittest.cc b/call/rtx_receive_stream_unittest.cc
index 79dc2f1..90027bb 100644
--- a/call/rtx_receive_stream_unittest.cc
+++ b/call/rtx_receive_stream_unittest.cc
@@ -50,6 +50,26 @@
0xee,
};
+constexpr uint8_t kRtxPacketWithPadding[] = {
+ 0xa0, // Version 2, P set
+ 98, // Payload type.
+ 0x12,
+ 0x34, // Seqno.
+ 0x11,
+ 0x11,
+ 0x11,
+ 0x11, // Timestamp.
+ 0x22,
+ 0x22,
+ 0x22,
+ 0x22, // SSRC.
+ // RTX header.
+ 0x56,
+ 0x57, // Orig seqno.
+ // Padding
+ 0x1,
+};
+
constexpr uint8_t kRtxPacketWithCVO[] = {
0x90, // Version 2, X set.
98, // Payload type.
@@ -96,13 +116,13 @@
RtpPacketReceived rtx_packet;
EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView<const uint8_t>(kRtxPacket)));
- EXPECT_CALL(media_sink, OnRtpPacket(_))
- .WillOnce(::testing::Invoke([](const RtpPacketReceived& packet) {
+ EXPECT_CALL(media_sink, OnRtpPacket)
+ .WillOnce([](const RtpPacketReceived& packet) {
EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
EXPECT_THAT(packet.payload(), ::testing::ElementsAre(0xee));
- }));
+ });
rtx_sink.OnRtpPacket(rtx_packet);
}
@@ -113,10 +133,10 @@
RtpPacketReceived rtx_packet;
EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView<const uint8_t>(kRtxPacket)));
EXPECT_FALSE(rtx_packet.recovered());
- EXPECT_CALL(media_sink, OnRtpPacket(_))
- .WillOnce(::testing::Invoke([](const RtpPacketReceived& packet) {
+ EXPECT_CALL(media_sink, OnRtpPacket)
+ .WillOnce([](const RtpPacketReceived& packet) {
EXPECT_TRUE(packet.recovered());
- }));
+ });
rtx_sink.OnRtpPacket(rtx_packet);
}
@@ -154,8 +174,8 @@
EXPECT_TRUE(rtx_packet.GetExtension<VideoOrientation>(&rotation));
EXPECT_EQ(kVideoRotation_90, rotation);
- EXPECT_CALL(media_sink, OnRtpPacket(_))
- .WillOnce(::testing::Invoke([](const RtpPacketReceived& packet) {
+ EXPECT_CALL(media_sink, OnRtpPacket)
+ .WillOnce([](const RtpPacketReceived& packet) {
EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
@@ -163,7 +183,75 @@
VideoRotation rotation = kVideoRotation_0;
EXPECT_TRUE(packet.GetExtension<VideoOrientation>(&rotation));
EXPECT_EQ(rotation, kVideoRotation_90);
- }));
+ });
+
+ rtx_sink.OnRtpPacket(rtx_packet);
+}
+
+TEST(RtxReceiveStreamTest, SupportsLargePacket) {
+ StrictMock<MockRtpPacketSink> media_sink;
+ RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
+ RtpPacketReceived rtx_packet;
+ constexpr int kRtxPacketSize = 2000;
+ constexpr int kRtxPayloadOffset = 14;
+ uint8_t large_rtx_packet[kRtxPacketSize];
+ memcpy(large_rtx_packet, kRtxPacket, sizeof(kRtxPacket));
+ rtc::ArrayView<uint8_t> payload(large_rtx_packet + kRtxPayloadOffset,
+ kRtxPacketSize - kRtxPayloadOffset);
+
+ // Fill payload.
+ for (size_t i = 0; i < payload.size(); i++) {
+ payload[i] = i;
+ }
+ EXPECT_TRUE(
+ rtx_packet.Parse(rtc::ArrayView<const uint8_t>(large_rtx_packet)));
+
+ EXPECT_CALL(media_sink, OnRtpPacket)
+ .WillOnce([&](const RtpPacketReceived& packet) {
+ EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
+ EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
+ EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
+ EXPECT_THAT(packet.payload(), ::testing::ElementsAreArray(payload));
+ });
+
+ rtx_sink.OnRtpPacket(rtx_packet);
+}
+
+TEST(RtxReceiveStreamTest, SupportsLargePacketWithPadding) {
+ StrictMock<MockRtpPacketSink> media_sink;
+ RtxReceiveStream rtx_sink(&media_sink, PayloadTypeMapping(), kMediaSSRC);
+ RtpPacketReceived rtx_packet;
+ constexpr int kRtxPacketSize = 2000;
+ constexpr int kRtxPayloadOffset = 14;
+ constexpr int kRtxPaddingSize = 50;
+ uint8_t large_rtx_packet[kRtxPacketSize];
+ memcpy(large_rtx_packet, kRtxPacketWithPadding,
+ sizeof(kRtxPacketWithPadding));
+ rtc::ArrayView<uint8_t> payload(
+ large_rtx_packet + kRtxPayloadOffset,
+ kRtxPacketSize - kRtxPayloadOffset - kRtxPaddingSize);
+ rtc::ArrayView<uint8_t> padding(
+ large_rtx_packet + kRtxPacketSize - kRtxPaddingSize, kRtxPaddingSize);
+
+ // Fill payload.
+ for (size_t i = 0; i < payload.size(); i++) {
+ payload[i] = i;
+ }
+ // Fill padding. Only value of last padding byte matters.
+ for (size_t i = 0; i < padding.size(); i++) {
+ padding[i] = kRtxPaddingSize;
+ }
+
+ EXPECT_TRUE(
+ rtx_packet.Parse(rtc::ArrayView<const uint8_t>(large_rtx_packet)));
+
+ EXPECT_CALL(media_sink, OnRtpPacket)
+ .WillOnce([&](const RtpPacketReceived& packet) {
+ EXPECT_EQ(packet.SequenceNumber(), kMediaSeqno);
+ EXPECT_EQ(packet.Ssrc(), kMediaSSRC);
+ EXPECT_EQ(packet.PayloadType(), kMediaPayloadType);
+ EXPECT_THAT(packet.payload(), ::testing::ElementsAreArray(payload));
+ });
rtx_sink.OnRtpPacket(rtx_packet);
}
diff --git a/modules/rtp_rtcp/source/rtp_packet.cc b/modules/rtp_rtcp/source/rtp_packet.cc
index b9c7e54..557edf0 100644
--- a/modules/rtp_rtcp/source/rtp_packet.cc
+++ b/modules/rtp_rtcp/source/rtp_packet.cc
@@ -121,7 +121,7 @@
extensions_ = packet.extensions_;
extension_entries_ = packet.extension_entries_;
extensions_size_ = packet.extensions_size_;
- buffer_.SetData(packet.data(), packet.headers_size());
+ buffer_ = packet.buffer_.Slice(0, packet.headers_size());
// Reset payload and padding.
payload_size_ = 0;
padding_size_ = 0;