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(
const AugmentedPacket& packet,
bool is_recovered) {
RtpPacketReceived red_packet;
// Copy RTP header.
// Create a temporary buffer used to wrap the media packet in RED.
rtc::CopyOnWriteBuffer red_buffer;
const size_t kHeaderLength = packet.header.headerLength;
red_packet.Parse(packet.data.cdata(), kHeaderLength);
RTC_DCHECK_EQ(red_packet.headers_size(), kHeaderLength);
uint8_t* rtp_payload =
red_packet.AllocatePayload(packet.data.size() + 1 - kHeaderLength);
// Move payload type into rtp payload.
rtp_payload[0] = red_packet.PayloadType();
// Append header.
red_buffer.SetData(packet.data.data(), kHeaderLength);
// Find payload type and add it as RED header.
uint8_t media_payload_type = red_buffer[1] & 0x7F;
red_buffer.AppendData({media_payload_type});
// 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);
// Copy the payload.
memcpy(rtp_payload + 1, packet.data.cdata() + kHeaderLength,
packet.data.size() - kHeaderLength);
red_packet.set_recovered(is_recovered);
return red_packet;

View File

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

View File

@ -512,4 +512,31 @@ TEST_F(UlpfecReceiverTest, TruncatedPacketWithoutDataPastFirstBlock) {
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