Updates ulpfec reader to accept padding on media packets.

Bug: webrtc:12530
Change-Id: I659c430d50a88d49cb4c3c21d00710fac78f1e0d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/212081
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33483}
This commit is contained in:
Erik Språng
2021-03-16 19:24:58 +01:00
committed by Commit Bot
parent 87dbe9a14f
commit f19aec829b
3 changed files with 46 additions and 17 deletions

View File

@ -184,19 +184,21 @@ UlpfecPacketGenerator::UlpfecPacketGenerator(uint32_t ssrc)
RtpPacketReceived UlpfecPacketGenerator::BuildMediaRedPacket( RtpPacketReceived UlpfecPacketGenerator::BuildMediaRedPacket(
const AugmentedPacket& packet, const AugmentedPacket& packet,
bool is_recovered) { bool is_recovered) {
RtpPacketReceived red_packet; // Create a temporary buffer used to wrap the media packet in RED.
// Copy RTP header. rtc::CopyOnWriteBuffer red_buffer;
const size_t kHeaderLength = packet.header.headerLength; const size_t kHeaderLength = packet.header.headerLength;
red_packet.Parse(packet.data.cdata(), kHeaderLength); // Append header.
RTC_DCHECK_EQ(red_packet.headers_size(), kHeaderLength); red_buffer.SetData(packet.data.data(), kHeaderLength);
uint8_t* rtp_payload = // Find payload type and add it as RED header.
red_packet.AllocatePayload(packet.data.size() + 1 - kHeaderLength); uint8_t media_payload_type = red_buffer[1] & 0x7F;
// Move payload type into rtp payload. red_buffer.AppendData({media_payload_type});
rtp_payload[0] = red_packet.PayloadType(); // Append rest of payload/padding.
red_buffer.AppendData(
packet.data.Slice(kHeaderLength, packet.data.size() - kHeaderLength));
RtpPacketReceived red_packet;
RTC_CHECK(red_packet.Parse(std::move(red_buffer)));
red_packet.SetPayloadType(kRedPayloadType); red_packet.SetPayloadType(kRedPayloadType);
// Copy the payload.
memcpy(rtp_payload + 1, packet.data.cdata() + kHeaderLength,
packet.data.size() - kHeaderLength);
red_packet.set_recovered(is_recovered); red_packet.set_recovered(is_recovered);
return red_packet; return red_packet;

View File

@ -132,9 +132,8 @@ bool UlpfecReceiverImpl::AddReceivedRedPacket(
rtp_packet.Buffer().Slice(rtp_packet.headers_size() + kRedHeaderLength, rtp_packet.Buffer().Slice(rtp_packet.headers_size() + kRedHeaderLength,
rtp_packet.payload_size() - kRedHeaderLength); rtp_packet.payload_size() - kRedHeaderLength);
} else { } else {
auto red_payload = rtp_packet.payload().subview(kRedHeaderLength); received_packet->pkt->data.EnsureCapacity(rtp_packet.size() -
received_packet->pkt->data.EnsureCapacity(rtp_packet.headers_size() + kRedHeaderLength);
red_payload.size());
// Copy RTP header. // Copy RTP header.
received_packet->pkt->data.SetData(rtp_packet.data(), received_packet->pkt->data.SetData(rtp_packet.data(),
rtp_packet.headers_size()); rtp_packet.headers_size());
@ -142,9 +141,10 @@ bool UlpfecReceiverImpl::AddReceivedRedPacket(
uint8_t& payload_type_byte = received_packet->pkt->data.MutableData()[1]; uint8_t& payload_type_byte = received_packet->pkt->data.MutableData()[1];
payload_type_byte &= 0x80; // Reset RED payload type. payload_type_byte &= 0x80; // Reset RED payload type.
payload_type_byte += payload_type; // Set media payload type. payload_type_byte += payload_type; // Set media payload type.
// Copy payload data. // Copy payload and padding data, after the RED header.
received_packet->pkt->data.AppendData(red_payload.data(), received_packet->pkt->data.AppendData(
red_payload.size()); rtp_packet.data() + rtp_packet.headers_size() + kRedHeaderLength,
rtp_packet.size() - rtp_packet.headers_size() - kRedHeaderLength);
} }
if (received_packet->pkt->data.size() > 0) { if (received_packet->pkt->data.size() > 0) {

View File

@ -512,4 +512,31 @@ TEST_F(UlpfecReceiverTest, TruncatedPacketWithoutDataPastFirstBlock) {
SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100); SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100);
} }
TEST_F(UlpfecReceiverTest, MediaWithPadding) {
const size_t kNumFecPackets = 1;
std::list<AugmentedPacket*> augmented_media_packets;
ForwardErrorCorrection::PacketList media_packets;
PacketizeFrame(2, 0, &augmented_media_packets, &media_packets);
// Append four bytes of padding to the first media packet.
const uint8_t kPadding[] = {0, 0, 0, 4};
augmented_media_packets.front()->data.AppendData(kPadding);
augmented_media_packets.front()->data.MutableData()[0] |= 1 << 5; // P bit.
augmented_media_packets.front()->header.paddingLength = 4;
std::list<ForwardErrorCorrection::Packet*> fec_packets;
EncodeFec(media_packets, kNumFecPackets, &fec_packets);
auto it = augmented_media_packets.begin();
BuildAndAddRedMediaPacket(augmented_media_packets.front());
VerifyReconstructedMediaPacket(**it, 1);
EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
BuildAndAddRedFecPacket(fec_packets.front());
++it;
VerifyReconstructedMediaPacket(**it, 1);
EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
}
} // namespace webrtc } // namespace webrtc