diff --git a/call/rtx_receive_stream_unittest.cc b/call/rtx_receive_stream_unittest.cc index 79dc2f1b61..90027bbc48 100644 --- a/call/rtx_receive_stream_unittest.cc +++ b/call/rtx_receive_stream_unittest.cc @@ -50,6 +50,26 @@ constexpr uint8_t kRtxPacket[] = { 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 @@ TEST(RtxReceiveStreamTest, RestoresPacketPayload) { RtpPacketReceived rtx_packet; EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView(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 @@ TEST(RtxReceiveStreamTest, SetsRecoveredFlag) { RtpPacketReceived rtx_packet; EXPECT_TRUE(rtx_packet.Parse(rtc::ArrayView(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 @@ TEST(RtxReceiveStreamTest, CopiesRtpHeaderExtensions) { EXPECT_TRUE(rtx_packet.GetExtension(&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 @@ TEST(RtxReceiveStreamTest, CopiesRtpHeaderExtensions) { VideoRotation rotation = kVideoRotation_0; EXPECT_TRUE(packet.GetExtension(&rotation)); EXPECT_EQ(rotation, kVideoRotation_90); - })); + }); + + rtx_sink.OnRtpPacket(rtx_packet); +} + +TEST(RtxReceiveStreamTest, SupportsLargePacket) { + StrictMock 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 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(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 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 payload( + large_rtx_packet + kRtxPayloadOffset, + kRtxPacketSize - kRtxPayloadOffset - kRtxPaddingSize); + rtc::ArrayView 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(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 b9c7e54c26..557edf0915 100644 --- a/modules/rtp_rtcp/source/rtp_packet.cc +++ b/modules/rtp_rtcp/source/rtp_packet.cc @@ -121,7 +121,7 @@ void RtpPacket::CopyHeaderFrom(const RtpPacket& packet) { 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;