Revert "Refactor FEC code to use COW buffers"

This reverts commit 7325bc3917e6dd4c92e7a18fd879ba91f0b2851f.

Reason for revert: FecTest.UlpfecTest is consistently failing.

Original change's description:
> Refactor FEC code to use COW buffers
> 
> This refactoring helps to reduce unnecessary memcpy calls on the receive
> side.
> 
> This CL is the first stage of refactoring: it only replaces
> |uint8 data[IP_PACKET_SIZE]| with |rtc::CopyOnWriteBuffer data| and does
> necessary changes.
> 
> A follow-up CL will remove length field of the Packet class.
> 
> 
> Bug: webrtc:10750
> Change-Id: Ie233da83ff33f6370f511955e4c65d59522389a7
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144881
> Reviewed-by: Artem Titov <titovartem@webrtc.org>
> Reviewed-by: Stefan Holmer <stefan@webrtc.org>
> Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#28539}

TBR=brandtr@webrtc.org,ilnik@webrtc.org,asapersson@webrtc.org,stefan@webrtc.org,titovartem@webrtc.org

Change-Id: I07c34256a76174f09a0d27eacbae6488e66f4b43
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:10750
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/145340
Reviewed-by: Qingsi Wang <qingsi@webrtc.org>
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28545}
This commit is contained in:
Qingsi Wang 2019-07-11 19:50:15 +00:00 committed by Commit Bot
parent 0f0668e328
commit 6ff9ebd070
24 changed files with 159 additions and 199 deletions

View File

@ -54,7 +54,6 @@ ForwardErrorCorrection::PacketList MediaPacketGenerator::ConstructMediaPackets(
std::unique_ptr<ForwardErrorCorrection::Packet> media_packet( std::unique_ptr<ForwardErrorCorrection::Packet> media_packet(
new ForwardErrorCorrection::Packet()); new ForwardErrorCorrection::Packet());
media_packet->length = random_->Rand(min_packet_size_, max_packet_size_); media_packet->length = random_->Rand(min_packet_size_, max_packet_size_);
media_packet->data.SetSize(media_packet->length);
// Generate random values for the first 2 bytes // Generate random values for the first 2 bytes
media_packet->data[0] = random_->Rand<uint8_t>(); media_packet->data[0] = random_->Rand<uint8_t>();
@ -121,18 +120,16 @@ std::unique_ptr<AugmentedPacket> AugmentedPacketGenerator::NextPacket(
size_t length) { size_t length) {
std::unique_ptr<AugmentedPacket> packet(new AugmentedPacket()); std::unique_ptr<AugmentedPacket> packet(new AugmentedPacket());
packet->data.SetSize(length + kRtpHeaderSize);
for (size_t i = 0; i < length; ++i) for (size_t i = 0; i < length; ++i)
packet->data[i + kRtpHeaderSize] = offset + i; packet->data[i + kRtpHeaderSize] = offset + i;
packet->length = length + kRtpHeaderSize; packet->length = length + kRtpHeaderSize;
packet->data.SetSize(packet->length);
packet->header.headerLength = kRtpHeaderSize; packet->header.headerLength = kRtpHeaderSize;
packet->header.markerBit = (num_packets_ == 1); packet->header.markerBit = (num_packets_ == 1);
packet->header.payloadType = kVp8PayloadType; packet->header.payloadType = kVp8PayloadType;
packet->header.sequenceNumber = seq_num_; packet->header.sequenceNumber = seq_num_;
packet->header.timestamp = timestamp_; packet->header.timestamp = timestamp_;
packet->header.ssrc = ssrc_; packet->header.ssrc = ssrc_;
WriteRtpHeader(packet->header, packet->data.data()); WriteRtpHeader(packet->header, packet->data);
++seq_num_; ++seq_num_;
--num_packets_; --num_packets_;
@ -170,10 +167,9 @@ std::unique_ptr<AugmentedPacket> FlexfecPacketGenerator::BuildFlexfecPacket(
std::unique_ptr<AugmentedPacket> packet_with_rtp_header( std::unique_ptr<AugmentedPacket> packet_with_rtp_header(
new AugmentedPacket()); new AugmentedPacket());
packet_with_rtp_header->data.SetSize(kRtpHeaderSize + packet.length); WriteRtpHeader(header, packet_with_rtp_header->data);
WriteRtpHeader(header, packet_with_rtp_header->data.data()); memcpy(packet_with_rtp_header->data + kRtpHeaderSize, packet.data,
memcpy(packet_with_rtp_header->data.data() + kRtpHeaderSize, packet.length);
packet.data.cdata(), packet.length);
packet_with_rtp_header->length = kRtpHeaderSize + packet.length; packet_with_rtp_header->length = kRtpHeaderSize + packet.length;
return packet_with_rtp_header; return packet_with_rtp_header;
@ -189,12 +185,11 @@ std::unique_ptr<AugmentedPacket> UlpfecPacketGenerator::BuildMediaRedPacket(
const size_t kHeaderLength = packet.header.headerLength; const size_t kHeaderLength = packet.header.headerLength;
red_packet->header = packet.header; red_packet->header = packet.header;
red_packet->length = packet.length + 1; // 1 byte RED header. red_packet->length = packet.length + 1; // 1 byte RED header.
red_packet->data.SetSize(packet.length + 1);
// Copy RTP header. // Copy RTP header.
memcpy(red_packet->data.data(), packet.data.cdata(), kHeaderLength); memcpy(red_packet->data, packet.data, kHeaderLength);
SetRedHeader(red_packet->data[1] & 0x7f, kHeaderLength, red_packet.get()); SetRedHeader(red_packet->data[1] & 0x7f, kHeaderLength, red_packet.get());
memcpy(red_packet->data.data() + kHeaderLength + 1, memcpy(red_packet->data + kHeaderLength + 1, packet.data + kHeaderLength,
packet.data.cdata() + kHeaderLength, packet.length - kHeaderLength); packet.length - kHeaderLength);
return red_packet; return red_packet;
} }
@ -208,10 +203,8 @@ std::unique_ptr<AugmentedPacket> UlpfecPacketGenerator::BuildUlpfecRedPacket(
red_packet->data[1] &= ~0x80; // Clear marker bit. red_packet->data[1] &= ~0x80; // Clear marker bit.
const size_t kHeaderLength = red_packet->header.headerLength; const size_t kHeaderLength = red_packet->header.headerLength;
red_packet->data.SetSize(kHeaderLength + 1 + packet.length);
SetRedHeader(kFecPayloadType, kHeaderLength, red_packet.get()); SetRedHeader(kFecPayloadType, kHeaderLength, red_packet.get());
memcpy(red_packet->data.data() + kHeaderLength + 1, packet.data.cdata(), memcpy(red_packet->data + kHeaderLength + 1, packet.data, packet.length);
packet.length);
red_packet->length = kHeaderLength + 1 + packet.length; red_packet->length = kHeaderLength + 1 + packet.length;
return red_packet; return red_packet;

View File

@ -125,7 +125,7 @@ bool FlexfecHeaderReader::ReadFecHeader(
RTC_LOG(LS_WARNING) << "Discarding truncated FlexFEC packet."; RTC_LOG(LS_WARNING) << "Discarding truncated FlexFEC packet.";
return false; return false;
} }
uint8_t* const packet_mask = fec_packet->pkt->data.data() + kPacketMaskOffset; uint8_t* const packet_mask = fec_packet->pkt->data + kPacketMaskOffset;
bool k_bit0 = (packet_mask[0] & 0x80) != 0; bool k_bit0 = (packet_mask[0] & 0x80) != 0;
uint16_t mask_part0 = ByteReader<uint16_t>::ReadBigEndian(&packet_mask[0]); uint16_t mask_part0 = ByteReader<uint16_t>::ReadBigEndian(&packet_mask[0]);
// Shift away K-bit 0, implicitly clearing the last bit. // Shift away K-bit 0, implicitly clearing the last bit.
@ -260,8 +260,7 @@ void FlexfecHeaderWriter::FinalizeFecHeader(
// //
// We treat the mask parts as unsigned integers with host order endianness // We treat the mask parts as unsigned integers with host order endianness
// in order to simplify the bit shifting between bytes. // in order to simplify the bit shifting between bytes.
uint8_t* const written_packet_mask = uint8_t* const written_packet_mask = fec_packet->data + kPacketMaskOffset;
fec_packet->data.data() + kPacketMaskOffset;
if (packet_mask_size == kUlpfecPacketMaskSizeLBitSet) { if (packet_mask_size == kUlpfecPacketMaskSizeLBitSet) {
// The packet mask is 48 bits long. // The packet mask is 48 bits long.
uint16_t tmp_mask_part0 = uint16_t tmp_mask_part0 =

View File

@ -78,7 +78,6 @@ rtc::scoped_refptr<Packet> WriteHeader(const uint8_t* packet_mask,
FlexfecHeaderWriter writer; FlexfecHeaderWriter writer;
rtc::scoped_refptr<Packet> written_packet(new Packet()); rtc::scoped_refptr<Packet> written_packet(new Packet());
written_packet->length = kMediaPacketLength; written_packet->length = kMediaPacketLength;
written_packet->data.SetSize(kMediaPacketLength);
for (size_t i = 0; i < written_packet->length; ++i) { for (size_t i = 0; i < written_packet->length; ++i) {
written_packet->data[i] = i; // Actual content doesn't matter. written_packet->data[i] = i; // Actual content doesn't matter.
} }
@ -92,7 +91,7 @@ std::unique_ptr<ReceivedFecPacket> ReadHeader(const Packet& written_packet) {
std::unique_ptr<ReceivedFecPacket> read_packet(new ReceivedFecPacket()); std::unique_ptr<ReceivedFecPacket> read_packet(new ReceivedFecPacket());
read_packet->ssrc = kFlexfecSsrc; read_packet->ssrc = kFlexfecSsrc;
read_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); read_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
read_packet->pkt->data = written_packet.data; memcpy(read_packet->pkt->data, written_packet.data, written_packet.length);
read_packet->pkt->length = written_packet.length; read_packet->pkt->length = written_packet.length;
EXPECT_TRUE(reader.ReadFecHeader(read_packet.get())); EXPECT_TRUE(reader.ReadFecHeader(read_packet.get()));
return read_packet; return read_packet;
@ -113,8 +112,7 @@ void VerifyReadHeaders(size_t expected_fec_header_size,
EXPECT_EQ(read_packet.pkt->length - expected_fec_header_size, EXPECT_EQ(read_packet.pkt->length - expected_fec_header_size,
read_packet.protection_length); read_packet.protection_length);
// Ensure that the K-bits are removed and the packet mask has been packed. // Ensure that the K-bits are removed and the packet mask has been packed.
EXPECT_THAT( EXPECT_THAT(::testing::make_tuple(read_packet.pkt->data + packet_mask_offset,
::testing::make_tuple(read_packet.pkt->data.cdata() + packet_mask_offset,
read_packet.packet_mask_size), read_packet.packet_mask_size),
::testing::ElementsAreArray(expected_packet_mask, ::testing::ElementsAreArray(expected_packet_mask,
expected_packet_mask_size)); expected_packet_mask_size));
@ -123,7 +121,7 @@ void VerifyReadHeaders(size_t expected_fec_header_size,
void VerifyFinalizedHeaders(const uint8_t* expected_packet_mask, void VerifyFinalizedHeaders(const uint8_t* expected_packet_mask,
size_t expected_packet_mask_size, size_t expected_packet_mask_size,
const Packet& written_packet) { const Packet& written_packet) {
const uint8_t* packet = written_packet.data.cdata(); const uint8_t* packet = written_packet.data;
EXPECT_EQ(0x00, packet[0] & 0x80); // F bit clear. EXPECT_EQ(0x00, packet[0] & 0x80); // F bit clear.
EXPECT_EQ(0x00, packet[0] & 0x40); // R bit clear. EXPECT_EQ(0x00, packet[0] & 0x40); // R bit clear.
EXPECT_EQ(0x01, packet[8]); // SSRCCount = 1. EXPECT_EQ(0x01, packet[8]); // SSRCCount = 1.
@ -150,17 +148,17 @@ void VerifyWrittenAndReadHeaders(size_t expected_fec_header_size,
EXPECT_EQ(written_packet.length - expected_fec_header_size, EXPECT_EQ(written_packet.length - expected_fec_header_size,
read_packet.protection_length); read_packet.protection_length);
// Verify that the call to ReadFecHeader did normalize the packet masks. // Verify that the call to ReadFecHeader did normalize the packet masks.
EXPECT_THAT(::testing::make_tuple( EXPECT_THAT(
read_packet.pkt->data.cdata() + kFlexfecPacketMaskOffset, ::testing::make_tuple(read_packet.pkt->data + kFlexfecPacketMaskOffset,
read_packet.packet_mask_size), read_packet.packet_mask_size),
::testing::ElementsAreArray(expected_packet_mask, ::testing::ElementsAreArray(expected_packet_mask,
expected_packet_mask_size)); expected_packet_mask_size));
// Verify that the call to ReadFecHeader did not tamper with the payload. // Verify that the call to ReadFecHeader did not tamper with the payload.
EXPECT_THAT(::testing::make_tuple( EXPECT_THAT(::testing::make_tuple(
read_packet.pkt->data.cdata() + read_packet.fec_header_size, read_packet.pkt->data + read_packet.fec_header_size,
read_packet.pkt->length - read_packet.fec_header_size), read_packet.pkt->length - read_packet.fec_header_size),
::testing::ElementsAreArray( ::testing::ElementsAreArray(
written_packet.data.cdata() + expected_fec_header_size, written_packet.data + expected_fec_header_size,
written_packet.length - expected_fec_header_size)); written_packet.length - expected_fec_header_size));
} }
@ -184,7 +182,7 @@ TEST(FlexfecHeaderReaderTest, ReadsHeaderWithKBit0Set) {
const size_t packet_length = sizeof(kPacketData); const size_t packet_length = sizeof(kPacketData);
ReceivedFecPacket read_packet; ReceivedFecPacket read_packet;
read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet()); read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
read_packet.pkt->data.SetData(kPacketData, packet_length); memcpy(read_packet.pkt->data, kPacketData, packet_length);
read_packet.pkt->length = packet_length; read_packet.pkt->length = packet_length;
FlexfecHeaderReader reader; FlexfecHeaderReader reader;
@ -216,7 +214,7 @@ TEST(FlexfecHeaderReaderTest, ReadsHeaderWithKBit1Set) {
const size_t packet_length = sizeof(kPacketData); const size_t packet_length = sizeof(kPacketData);
ReceivedFecPacket read_packet; ReceivedFecPacket read_packet;
read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet()); read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
read_packet.pkt->data.SetData(kPacketData, packet_length); memcpy(read_packet.pkt->data, kPacketData, packet_length);
read_packet.pkt->length = packet_length; read_packet.pkt->length = packet_length;
FlexfecHeaderReader reader; FlexfecHeaderReader reader;
@ -255,7 +253,7 @@ TEST(FlexfecHeaderReaderTest, ReadsHeaderWithKBit2Set) {
const size_t packet_length = sizeof(kPacketData); const size_t packet_length = sizeof(kPacketData);
ReceivedFecPacket read_packet; ReceivedFecPacket read_packet;
read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet()); read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
read_packet.pkt->data.SetData(kPacketData, packet_length); memcpy(read_packet.pkt->data, kPacketData, packet_length);
read_packet.pkt->length = packet_length; read_packet.pkt->length = packet_length;
FlexfecHeaderReader reader; FlexfecHeaderReader reader;
@ -275,7 +273,6 @@ TEST(FlexfecHeaderReaderTest, ReadPacketWithoutStreamSpecificHeaderShouldFail) {
read_packet.ssrc = kFlexfecSsrc; read_packet.ssrc = kFlexfecSsrc;
read_packet.pkt = std::move(written_packet); read_packet.pkt = std::move(written_packet);
read_packet.pkt->length = 12; read_packet.pkt->length = 12;
read_packet.pkt->data.SetSize(read_packet.pkt->length);
FlexfecHeaderReader reader; FlexfecHeaderReader reader;
EXPECT_FALSE(reader.ReadFecHeader(&read_packet)); EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
@ -291,7 +288,6 @@ TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit0SetShouldFail) {
read_packet.ssrc = kFlexfecSsrc; read_packet.ssrc = kFlexfecSsrc;
read_packet.pkt = std::move(written_packet); read_packet.pkt = std::move(written_packet);
read_packet.pkt->length = 18; read_packet.pkt->length = 18;
read_packet.pkt->data.SetSize(read_packet.pkt->length);
FlexfecHeaderReader reader; FlexfecHeaderReader reader;
EXPECT_FALSE(reader.ReadFecHeader(&read_packet)); EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
@ -308,7 +304,6 @@ TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit1SetShouldFail) {
read_packet.ssrc = kFlexfecSsrc; read_packet.ssrc = kFlexfecSsrc;
read_packet.pkt = std::move(written_packet); read_packet.pkt = std::move(written_packet);
read_packet.pkt->length = 20; read_packet.pkt->length = 20;
read_packet.pkt->data.SetSize(read_packet.pkt->length);
FlexfecHeaderReader reader; FlexfecHeaderReader reader;
EXPECT_FALSE(reader.ReadFecHeader(&read_packet)); EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
@ -325,7 +320,6 @@ TEST(FlexfecHeaderReaderTest, ReadShortPacketWithKBit2SetShouldFail) {
read_packet.ssrc = kFlexfecSsrc; read_packet.ssrc = kFlexfecSsrc;
read_packet.pkt = std::move(written_packet); read_packet.pkt = std::move(written_packet);
read_packet.pkt->length = 24; read_packet.pkt->length = 24;
read_packet.pkt->data.SetSize(read_packet.pkt->length);
FlexfecHeaderReader reader; FlexfecHeaderReader reader;
EXPECT_FALSE(reader.ReadFecHeader(&read_packet)); EXPECT_FALSE(reader.ReadFecHeader(&read_packet));
@ -337,7 +331,6 @@ TEST(FlexfecHeaderWriterTest, FinalizesHeaderWithKBit0Set) {
constexpr uint8_t kUlpfecPacketMask[] = {0x11, 0x02}; constexpr uint8_t kUlpfecPacketMask[] = {0x11, 0x02};
Packet written_packet; Packet written_packet;
written_packet.length = kMediaPacketLength; written_packet.length = kMediaPacketLength;
written_packet.data.SetSize(written_packet.length);
for (size_t i = 0; i < written_packet.length; ++i) { for (size_t i = 0; i < written_packet.length; ++i) {
written_packet.data[i] = i; written_packet.data[i] = i;
} }
@ -356,7 +349,6 @@ TEST(FlexfecHeaderWriterTest, FinalizesHeaderWithKBit1Set) {
constexpr uint8_t kUlpfecPacketMask[] = {0x91, 0x02, 0x08, 0x44, 0x00, 0x84}; constexpr uint8_t kUlpfecPacketMask[] = {0x91, 0x02, 0x08, 0x44, 0x00, 0x84};
Packet written_packet; Packet written_packet;
written_packet.length = kMediaPacketLength; written_packet.length = kMediaPacketLength;
written_packet.data.SetSize(written_packet.length);
for (size_t i = 0; i < written_packet.length; ++i) { for (size_t i = 0; i < written_packet.length; ++i) {
written_packet.data[i] = i; written_packet.data[i] = i;
} }
@ -379,7 +371,6 @@ TEST(FlexfecHeaderWriterTest, FinalizesHeaderWithKBit2Set) {
constexpr uint8_t kUlpfecPacketMask[] = {0x22, 0x22, 0x44, 0x44, 0x44, 0x41}; constexpr uint8_t kUlpfecPacketMask[] = {0x22, 0x22, 0x44, 0x44, 0x44, 0x41};
Packet written_packet; Packet written_packet;
written_packet.length = kMediaPacketLength; written_packet.length = kMediaPacketLength;
written_packet.data.SetSize(written_packet.length);
for (size_t i = 0; i < written_packet.length; ++i) { for (size_t i = 0; i < written_packet.length; ++i) {
written_packet.data[i] = i; written_packet.data[i] = i;
} }

View File

@ -107,12 +107,12 @@ FlexfecReceiver::AddReceivedPacket(const RtpPacketReceived& packet) {
++packet_counter_.num_fec_packets; ++packet_counter_.num_fec_packets;
// Insert packet payload into erasure code. // Insert packet payload into erasure code.
// TODO(brandtr): Remove this memcpy when the FEC packet classes
// are using COW buffers internally.
received_packet->pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>( received_packet->pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>(
new ForwardErrorCorrection::Packet()); new ForwardErrorCorrection::Packet());
// TODO(ilnik): after slice capability is added to COW, use it here instead
// of initializing COW buffer with ArrayView.
auto payload = packet.payload(); auto payload = packet.payload();
received_packet->pkt->data.SetData(payload.data(), payload.size()); memcpy(received_packet->pkt->data, payload.data(), payload.size());
received_packet->pkt->length = payload.size(); received_packet->pkt->length = payload.size();
} else { } else {
// This is a media packet, or a FlexFEC packet belonging to some // This is a media packet, or a FlexFEC packet belonging to some
@ -123,13 +123,11 @@ FlexfecReceiver::AddReceivedPacket(const RtpPacketReceived& packet) {
received_packet->is_fec = false; received_packet->is_fec = false;
// Insert entire packet into erasure code. // Insert entire packet into erasure code.
// Create a copy and fill with zeros all mutable extensions.
received_packet->pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>( received_packet->pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>(
new ForwardErrorCorrection::Packet()); new ForwardErrorCorrection::Packet());
RtpPacketReceived packet_copy(packet); // Create a copy and fill with zeros all mutable extensions.
packet_copy.ZeroMutableExtensions(); packet.CopyAndZeroMutableExtensions(received_packet->pkt->data);
received_packet->pkt->data = packet_copy.Buffer(); received_packet->pkt->length = packet.size();
received_packet->pkt->length = received_packet->pkt->data.size();
} }
++packet_counter_.num_packets; ++packet_counter_.num_packets;
@ -163,14 +161,14 @@ void FlexfecReceiver::ProcessReceivedPacket(
// Set this flag first, since OnRecoveredPacket may end up here // Set this flag first, since OnRecoveredPacket may end up here
// again, with the same packet. // again, with the same packet.
recovered_packet->returned = true; recovered_packet->returned = true;
RTC_CHECK_GT(recovered_packet->pkt->data.size(), 0); RTC_CHECK(recovered_packet->pkt);
recovered_packet_receiver_->OnRecoveredPacket( recovered_packet_receiver_->OnRecoveredPacket(
recovered_packet->pkt->data.cdata(), recovered_packet->pkt->length); recovered_packet->pkt->data, recovered_packet->pkt->length);
// Periodically log the incoming packets. // Periodically log the incoming packets.
int64_t now_ms = clock_->TimeInMilliseconds(); int64_t now_ms = clock_->TimeInMilliseconds();
if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) { if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) {
uint32_t media_ssrc = uint32_t media_ssrc =
ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data.data()); ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data);
RTC_LOG(LS_VERBOSE) << "Recovered media packet with SSRC: " << media_ssrc RTC_LOG(LS_VERBOSE) << "Recovered media packet with SSRC: " << media_ssrc
<< " from FlexFEC stream with SSRC: " << ssrc_ << "."; << " from FlexFEC stream with SSRC: " << ssrc_ << ".";
last_recovered_packet_ms_ = now_ms; last_recovered_packet_ms_ = now_ms;

View File

@ -39,7 +39,7 @@ constexpr uint32_t kMediaSsrc = 8353;
RtpPacketReceived ParsePacket(const Packet& packet) { RtpPacketReceived ParsePacket(const Packet& packet) {
RtpPacketReceived parsed_packet; RtpPacketReceived parsed_packet;
EXPECT_TRUE(parsed_packet.Parse(packet.data)); EXPECT_TRUE(parsed_packet.Parse(packet.data, packet.length));
return parsed_packet; return parsed_packet;
} }
@ -241,8 +241,8 @@ TEST_F(FlexfecReceiverTest, RecoversFromSingleMediaLoss) {
media_it++; media_it++;
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_it)->length)) OnRecoveredPacket(_, (*media_it)->length))
.With(Args<0, 1>( .With(
ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length))); Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header)); receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
} }
@ -263,8 +263,8 @@ TEST_F(FlexfecReceiverTest, RecoversFromDoubleMediaLoss) {
auto media_it = media_packets.begin(); auto media_it = media_packets.begin();
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_it)->length)) OnRecoveredPacket(_, (*media_it)->length))
.With(Args<0, 1>( .With(
ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length))); Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header)); receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
// Receive second FEC packet and recover second lost media packet. // Receive second FEC packet and recover second lost media packet.
@ -273,8 +273,8 @@ TEST_F(FlexfecReceiverTest, RecoversFromDoubleMediaLoss) {
media_it++; media_it++;
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_it)->length)) OnRecoveredPacket(_, (*media_it)->length))
.With(Args<0, 1>( .With(
ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length))); Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header)); receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
} }
@ -312,8 +312,8 @@ TEST_F(FlexfecReceiverTest, DoesNotCallbackTwice) {
media_it++; media_it++;
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_it)->length)) OnRecoveredPacket(_, (*media_it)->length))
.With(Args<0, 1>( .With(
ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length))); Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header)); receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
// Receive the FEC packet again, but do not call back. // Receive the FEC packet again, but do not call back.
@ -366,7 +366,7 @@ TEST_F(FlexfecReceiverTest, RecoversFrom50PercentLoss) {
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_it)->length)) OnRecoveredPacket(_, (*media_it)->length))
.With(Args<0, 1>( .With(Args<0, 1>(
ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length))); ElementsAreArray((*media_it)->data, (*media_it)->length)));
receiver_.OnRtpPacket(ParsePacket(*fec_packet_with_rtp_header)); receiver_.OnRtpPacket(ParsePacket(*fec_packet_with_rtp_header));
++media_it; ++media_it;
} }
@ -405,8 +405,8 @@ TEST_F(FlexfecReceiverTest, DelayedFecPacketDoesHelp) {
media_it = media_packets.begin(); media_it = media_packets.begin();
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_it)->length)) OnRecoveredPacket(_, (*media_it)->length))
.With(Args<0, 1>( .With(
ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length))); Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header)); receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
} }
@ -534,12 +534,12 @@ TEST_F(FlexfecReceiverTest, RecoversWithMediaPacketsOutOfOrder) {
// Expect to recover lost media packets. // Expect to recover lost media packets.
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_packet1)->length)) OnRecoveredPacket(_, (*media_packet1)->length))
.With(Args<0, 1>(ElementsAreArray((*media_packet1)->data.cdata(), .With(Args<0, 1>(
(*media_packet1)->length))); ElementsAreArray((*media_packet1)->data, (*media_packet1)->length)));
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_packet4)->length)) OnRecoveredPacket(_, (*media_packet4)->length))
.With(Args<0, 1>(ElementsAreArray((*media_packet4)->data.cdata(), .With(Args<0, 1>(
(*media_packet4)->length))); ElementsAreArray((*media_packet4)->data, (*media_packet4)->length)));
// Add FEC packets. // Add FEC packets.
auto fec_it = fec_packets.begin(); auto fec_it = fec_packets.begin();
@ -636,8 +636,8 @@ TEST_F(FlexfecReceiverTest, CalculatesNumberOfPackets) {
media_it++; media_it++;
EXPECT_CALL(recovered_packet_receiver_, EXPECT_CALL(recovered_packet_receiver_,
OnRecoveredPacket(_, (*media_it)->length)) OnRecoveredPacket(_, (*media_it)->length))
.With(Args<0, 1>( .With(
ElementsAreArray((*media_it)->data.cdata(), (*media_it)->length))); Args<0, 1>(ElementsAreArray((*media_it)->data, (*media_it)->length)));
receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header)); receiver_.OnRtpPacket(ParsePacket(*packet_with_rtp_header));
// Check stats calculations. // Check stats calculations.

View File

@ -114,7 +114,7 @@ bool FlexfecSender::AddRtpPacketAndGenerateFec(const RtpPacketToSend& packet) {
// protection. // protection.
RTC_DCHECK_EQ(packet.Ssrc(), protected_media_ssrc_); RTC_DCHECK_EQ(packet.Ssrc(), protected_media_ssrc_);
return ulpfec_generator_.AddRtpPacketAndGenerateFec( return ulpfec_generator_.AddRtpPacketAndGenerateFec(
packet.Buffer(), packet.headers_size()) == 0; packet.data(), packet.payload_size(), packet.headers_size()) == 0;
} }
bool FlexfecSender::FecAvailable() const { bool FlexfecSender::FecAvailable() const {
@ -154,7 +154,7 @@ std::vector<std::unique_ptr<RtpPacketToSend>> FlexfecSender::GetFecPackets() {
// RTP payload. // RTP payload.
uint8_t* payload = fec_packet_to_send->AllocatePayload(fec_packet->length); uint8_t* payload = fec_packet_to_send->AllocatePayload(fec_packet->length);
memcpy(payload, fec_packet->data.cdata(), fec_packet->length); memcpy(payload, fec_packet->data, fec_packet->length);
fec_packets_to_send.push_back(std::move(fec_packet_to_send)); fec_packets_to_send.push_back(std::move(fec_packet_to_send));
} }

View File

@ -62,7 +62,7 @@ std::unique_ptr<RtpPacketToSend> GenerateSingleFlexfecPacket(
std::unique_ptr<AugmentedPacket> packet = std::unique_ptr<AugmentedPacket> packet =
packet_generator.NextPacket(i, kPayloadLength); packet_generator.NextPacket(i, kPayloadLength);
RtpPacketToSend rtp_packet(nullptr); // No header extensions. RtpPacketToSend rtp_packet(nullptr); // No header extensions.
rtp_packet.Parse(packet->data); rtp_packet.Parse(packet->data, packet->length);
EXPECT_TRUE(sender->AddRtpPacketAndGenerateFec(rtp_packet)); EXPECT_TRUE(sender->AddRtpPacketAndGenerateFec(rtp_packet));
} }
EXPECT_TRUE(sender->FecAvailable()); EXPECT_TRUE(sender->FecAvailable());
@ -133,7 +133,7 @@ TEST(FlexfecSenderTest, ProtectTwoFramesWithOneFecPacket) {
std::unique_ptr<AugmentedPacket> packet = std::unique_ptr<AugmentedPacket> packet =
packet_generator.NextPacket(i, kPayloadLength); packet_generator.NextPacket(i, kPayloadLength);
RtpPacketToSend rtp_packet(nullptr); RtpPacketToSend rtp_packet(nullptr);
rtp_packet.Parse(packet->data); rtp_packet.Parse(packet->data, packet->length);
EXPECT_TRUE(sender.AddRtpPacketAndGenerateFec(rtp_packet)); EXPECT_TRUE(sender.AddRtpPacketAndGenerateFec(rtp_packet));
} }
} }
@ -173,7 +173,7 @@ TEST(FlexfecSenderTest, ProtectTwoFramesWithTwoFecPackets) {
std::unique_ptr<AugmentedPacket> packet = std::unique_ptr<AugmentedPacket> packet =
packet_generator.NextPacket(i, kPayloadLength); packet_generator.NextPacket(i, kPayloadLength);
RtpPacketToSend rtp_packet(nullptr); RtpPacketToSend rtp_packet(nullptr);
rtp_packet.Parse(packet->data); rtp_packet.Parse(packet->data, packet->length);
EXPECT_TRUE(sender.AddRtpPacketAndGenerateFec(rtp_packet)); EXPECT_TRUE(sender.AddRtpPacketAndGenerateFec(rtp_packet));
} }
EXPECT_TRUE(sender.FecAvailable()); EXPECT_TRUE(sender.FecAvailable());

View File

@ -150,11 +150,9 @@ int ForwardErrorCorrection::EncodeFec(const PacketList& media_packets,
return 0; return 0;
} }
for (int i = 0; i < num_fec_packets; ++i) { for (int i = 0; i < num_fec_packets; ++i) {
generated_fec_packets_[i].data.EnsureCapacity(IP_PACKET_SIZE); memset(generated_fec_packets_[i].data, 0, IP_PACKET_SIZE);
memset(generated_fec_packets_[i].data.data(), 0, IP_PACKET_SIZE);
// Use this as a marker for untouched packets. // Use this as a marker for untouched packets.
generated_fec_packets_[i].length = 0; generated_fec_packets_[i].length = 0;
generated_fec_packets_[i].data.SetSize(0);
fec_packets->push_back(&generated_fec_packets_[i]); fec_packets->push_back(&generated_fec_packets_[i]);
} }
@ -179,9 +177,9 @@ int ForwardErrorCorrection::EncodeFec(const PacketList& media_packets,
GenerateFecPayloads(media_packets, num_fec_packets); GenerateFecPayloads(media_packets, num_fec_packets);
// TODO(brandtr): Generalize this when multistream protection support is // TODO(brandtr): Generalize this when multistream protection support is
// added. // added.
const uint32_t media_ssrc = ParseSsrc(media_packets.front()->data.data()); const uint32_t media_ssrc = ParseSsrc(media_packets.front()->data);
const uint16_t seq_num_base = const uint16_t seq_num_base =
ParseSequenceNumber(media_packets.front()->data.data()); ParseSequenceNumber(media_packets.front()->data);
FinalizeFecHeaders(num_fec_packets, media_ssrc, seq_num_base); FinalizeFecHeaders(num_fec_packets, media_ssrc, seq_num_base);
return 0; return 0;
@ -213,8 +211,7 @@ void ForwardErrorCorrection::GenerateFecPayloads(
size_t media_pkt_idx = 0; size_t media_pkt_idx = 0;
auto media_packets_it = media_packets.cbegin(); auto media_packets_it = media_packets.cbegin();
uint16_t prev_seq_num = uint16_t prev_seq_num = ParseSequenceNumber((*media_packets_it)->data);
ParseSequenceNumber((*media_packets_it)->data.data());
while (media_packets_it != media_packets.end()) { while (media_packets_it != media_packets.end()) {
Packet* const media_packet = media_packets_it->get(); Packet* const media_packet = media_packets_it->get();
// Should |media_packet| be protected by |fec_packet|? // Should |media_packet| be protected by |fec_packet|?
@ -228,7 +225,6 @@ void ForwardErrorCorrection::GenerateFecPayloads(
// with) is the identity operator, thus all prior XORs are // with) is the identity operator, thus all prior XORs are
// still correct even though we expand the packet length here. // still correct even though we expand the packet length here.
fec_packet->length = fec_packet_length; fec_packet->length = fec_packet_length;
fec_packet->data.SetSize(fec_packet->length);
} }
if (first_protected_packet) { if (first_protected_packet) {
// Write P, X, CC, M, and PT recovery fields. // Write P, X, CC, M, and PT recovery fields.
@ -241,10 +237,8 @@ void ForwardErrorCorrection::GenerateFecPayloads(
// Write timestamp recovery field. // Write timestamp recovery field.
memcpy(&fec_packet->data[4], &media_packet->data[4], 4); memcpy(&fec_packet->data[4], &media_packet->data[4], 4);
// Write payload. // Write payload.
if (media_payload_length > 0) {
memcpy(&fec_packet->data[fec_header_size], memcpy(&fec_packet->data[fec_header_size],
&media_packet->data[kRtpHeaderSize], media_payload_length); &media_packet->data[kRtpHeaderSize], media_payload_length);
}
} else { } else {
XorHeaders(*media_packet, fec_packet); XorHeaders(*media_packet, fec_packet);
XorPayloads(*media_packet, media_payload_length, fec_header_size, XorPayloads(*media_packet, media_payload_length, fec_header_size,
@ -253,8 +247,7 @@ void ForwardErrorCorrection::GenerateFecPayloads(
} }
media_packets_it++; media_packets_it++;
if (media_packets_it != media_packets.end()) { if (media_packets_it != media_packets.end()) {
uint16_t seq_num = uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data);
ParseSequenceNumber((*media_packets_it)->data.data());
media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num); media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num);
prev_seq_num = seq_num; prev_seq_num = seq_num;
} }
@ -273,10 +266,8 @@ int ForwardErrorCorrection::InsertZerosInPacketMasks(
if (num_media_packets <= 1) { if (num_media_packets <= 1) {
return num_media_packets; return num_media_packets;
} }
uint16_t last_seq_num = uint16_t last_seq_num = ParseSequenceNumber(media_packets.back()->data);
ParseSequenceNumber(media_packets.back()->data.data()); uint16_t first_seq_num = ParseSequenceNumber(media_packets.front()->data);
uint16_t first_seq_num =
ParseSequenceNumber(media_packets.front()->data.data());
size_t total_missing_seq_nums = size_t total_missing_seq_nums =
static_cast<uint16_t>(last_seq_num - first_seq_num) - num_media_packets + static_cast<uint16_t>(last_seq_num - first_seq_num) - num_media_packets +
1; 1;
@ -309,7 +300,7 @@ int ForwardErrorCorrection::InsertZerosInPacketMasks(
// We can only cover up to 48 packets. // We can only cover up to 48 packets.
break; break;
} }
uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data.data()); uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data);
const int num_zeros_to_insert = const int num_zeros_to_insert =
static_cast<uint16_t>(seq_num - prev_seq_num - 1); static_cast<uint16_t>(seq_num - prev_seq_num - 1);
if (num_zeros_to_insert > 0) { if (num_zeros_to_insert > 0) {
@ -544,29 +535,25 @@ bool ForwardErrorCorrection::StartPacketRecovery(
<< "for its own header."; << "for its own header.";
return false; return false;
} }
if (fec_packet.protection_length >
std::min(size_t{IP_PACKET_SIZE - kRtpHeaderSize},
IP_PACKET_SIZE - fec_packet.fec_header_size)) {
RTC_LOG(LS_WARNING) << "Incorrect protection length, dropping FEC packet.";
return false;
}
// Initialize recovered packet data. // Initialize recovered packet data.
recovered_packet->pkt = new Packet(); recovered_packet->pkt = new Packet();
recovered_packet->pkt->data.SetSize(fec_packet.protection_length + memset(recovered_packet->pkt->data, 0, IP_PACKET_SIZE);
kRtpHeaderSize);
recovered_packet->returned = false; recovered_packet->returned = false;
recovered_packet->was_recovered = true; recovered_packet->was_recovered = true;
// Copy bytes corresponding to minimum RTP header size. // Copy bytes corresponding to minimum RTP header size.
// Note that the sequence number and SSRC fields will be overwritten // Note that the sequence number and SSRC fields will be overwritten
// at the end of packet recovery. // at the end of packet recovery.
memcpy(recovered_packet->pkt->data.data(), fec_packet.pkt->data.cdata(), memcpy(&recovered_packet->pkt->data, fec_packet.pkt->data, kRtpHeaderSize);
kRtpHeaderSize);
// Copy remaining FEC payload. // Copy remaining FEC payload.
if (fec_packet.protection_length > 0) { if (fec_packet.protection_length >
memcpy(recovered_packet->pkt->data.data() + kRtpHeaderSize, std::min(sizeof(recovered_packet->pkt->data) - kRtpHeaderSize,
fec_packet.pkt->data.cdata() + fec_packet.fec_header_size, sizeof(fec_packet.pkt->data) - fec_packet.fec_header_size)) {
fec_packet.protection_length); RTC_LOG(LS_WARNING) << "Incorrect protection length, dropping FEC packet.";
return false;
} }
memcpy(&recovered_packet->pkt->data[kRtpHeaderSize],
&fec_packet.pkt->data[fec_packet.fec_header_size],
fec_packet.protection_length);
return true; return true;
} }
@ -577,16 +564,15 @@ bool ForwardErrorCorrection::FinishPacketRecovery(
recovered_packet->pkt->data[0] |= 0x80; // Set the 1st bit. recovered_packet->pkt->data[0] |= 0x80; // Set the 1st bit.
recovered_packet->pkt->data[0] &= 0xbf; // Clear the 2nd bit. recovered_packet->pkt->data[0] &= 0xbf; // Clear the 2nd bit.
// Recover the packet length, from temporary location. // Recover the packet length, from temporary location.
const size_t new_size = recovered_packet->pkt->length =
ByteReader<uint16_t>::ReadBigEndian(&recovered_packet->pkt->data[2]) + ByteReader<uint16_t>::ReadBigEndian(&recovered_packet->pkt->data[2]) +
kRtpHeaderSize; kRtpHeaderSize;
if (new_size > size_t{IP_PACKET_SIZE - kRtpHeaderSize}) { if (recovered_packet->pkt->length >
sizeof(recovered_packet->pkt->data) - kRtpHeaderSize) {
RTC_LOG(LS_WARNING) << "The recovered packet had a length larger than a " RTC_LOG(LS_WARNING) << "The recovered packet had a length larger than a "
<< "typical IP packet, and is thus dropped."; << "typical IP packet, and is thus dropped.";
return false; return false;
} }
recovered_packet->pkt->length = new_size;
recovered_packet->pkt->data.SetSize(new_size);
// Set the SN field. // Set the SN field.
ByteWriter<uint16_t>::WriteBigEndian(&recovered_packet->pkt->data[2], ByteWriter<uint16_t>::WriteBigEndian(&recovered_packet->pkt->data[2],
recovered_packet->seq_num); recovered_packet->seq_num);
@ -623,8 +609,8 @@ void ForwardErrorCorrection::XorPayloads(const Packet& src,
size_t dst_offset, size_t dst_offset,
Packet* dst) { Packet* dst) {
// XOR the payload. // XOR the payload.
RTC_DCHECK_LE(kRtpHeaderSize + payload_length, src.data.size()); RTC_DCHECK_LE(kRtpHeaderSize + payload_length, sizeof(src.data));
RTC_DCHECK_LE(dst_offset + payload_length, dst->data.size()); RTC_DCHECK_LE(dst_offset + payload_length, sizeof(dst->data));
for (size_t i = 0; i < payload_length; ++i) { for (size_t i = 0; i < payload_length; ++i) {
dst->data[dst_offset + i] ^= src.data[kRtpHeaderSize + i]; dst->data[dst_offset + i] ^= src.data[kRtpHeaderSize + i];
} }
@ -641,8 +627,7 @@ bool ForwardErrorCorrection::RecoverPacket(const ReceivedFecPacket& fec_packet,
recovered_packet->seq_num = protected_packet->seq_num; recovered_packet->seq_num = protected_packet->seq_num;
} else { } else {
XorHeaders(*protected_packet->pkt, recovered_packet->pkt); XorHeaders(*protected_packet->pkt, recovered_packet->pkt);
XorPayloads(*protected_packet->pkt, XorPayloads(*protected_packet->pkt, protected_packet->pkt->length,
protected_packet->pkt->length - kRtpHeaderSize,
kRtpHeaderSize, recovered_packet->pkt); kRtpHeaderSize, recovered_packet->pkt);
} }
} }

View File

@ -22,7 +22,6 @@
#include "modules/include/module_fec_types.h" #include "modules/include/module_fec_types.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/source/forward_error_correction_internal.h" #include "modules/rtp_rtcp/source/forward_error_correction_internal.h"
#include "rtc_base/copy_on_write_buffer.h"
namespace webrtc { namespace webrtc {
@ -54,7 +53,7 @@ class ForwardErrorCorrection {
virtual int32_t Release(); virtual int32_t Release();
size_t length; // Length of packet in bytes. size_t length; // Length of packet in bytes.
rtc::CopyOnWriteBuffer data; // Packet data. uint8_t data[IP_PACKET_SIZE]; // Packet data.
private: private:
int32_t ref_count_; // Counts the number of references to a packet. int32_t ref_count_; // Counts the number of references to a packet.

View File

@ -121,7 +121,7 @@ void RtpFecTest<ForwardErrorCorrectionType>::ReceivedPackets(
new ForwardErrorCorrection::ReceivedPacket()); new ForwardErrorCorrection::ReceivedPacket());
received_packet->pkt = new ForwardErrorCorrection::Packet(); received_packet->pkt = new ForwardErrorCorrection::Packet();
received_packet->pkt->length = packet->length; received_packet->pkt->length = packet->length;
received_packet->pkt->data = packet->data; memcpy(received_packet->pkt->data, packet->data, packet->length);
received_packet->is_fec = is_fec; received_packet->is_fec = is_fec;
if (!is_fec) { if (!is_fec) {
received_packet->ssrc = kMediaSsrc; received_packet->ssrc = kMediaSsrc;
@ -158,8 +158,7 @@ bool RtpFecTest<ForwardErrorCorrectionType>::IsRecoveryComplete() {
if (media_packet->length != recovered_packet->pkt->length) { if (media_packet->length != recovered_packet->pkt->length) {
return false; return false;
} }
if (memcmp(media_packet->data.cdata(), if (memcmp(media_packet->data, recovered_packet->pkt->data,
recovered_packet->pkt->data.cdata(),
media_packet->length) != 0) { media_packet->length) != 0) {
return false; return false;
} }

View File

@ -157,7 +157,10 @@ void RtpPacket::SetSsrc(uint32_t ssrc) {
ByteWriter<uint32_t>::WriteBigEndian(WriteAt(8), ssrc); ByteWriter<uint32_t>::WriteBigEndian(WriteAt(8), ssrc);
} }
void RtpPacket::ZeroMutableExtensions() { void RtpPacket::CopyAndZeroMutableExtensions(
rtc::ArrayView<uint8_t> buffer) const {
RTC_CHECK_GE(buffer.size(), buffer_.size());
memcpy(buffer.data(), buffer_.cdata(), buffer_.size());
for (const ExtensionInfo& extension : extension_entries_) { for (const ExtensionInfo& extension : extension_entries_) {
switch (extensions_.GetType(extension.id)) { switch (extensions_.GetType(extension.id)) {
case RTPExtensionType::kRtpExtensionNone: { case RTPExtensionType::kRtpExtensionNone: {
@ -167,8 +170,8 @@ void RtpPacket::ZeroMutableExtensions() {
case RTPExtensionType::kRtpExtensionVideoTiming: { case RTPExtensionType::kRtpExtensionVideoTiming: {
// Nullify 3 last entries: packetization delay and 2 network timestamps. // Nullify 3 last entries: packetization delay and 2 network timestamps.
// Each of them is 2 bytes. // Each of them is 2 bytes.
memset( memset(buffer.data() + extension.offset +
WriteAt(extension.offset + VideoSendTiming::kPacerExitDeltaOffset), VideoSendTiming::kPacerExitDeltaOffset,
0, 6); 0, 6);
break; break;
} }
@ -177,7 +180,7 @@ void RtpPacket::ZeroMutableExtensions() {
case RTPExtensionType::kRtpExtensionTransmissionTimeOffset: case RTPExtensionType::kRtpExtensionTransmissionTimeOffset:
case RTPExtensionType::kRtpExtensionAbsoluteSendTime: { case RTPExtensionType::kRtpExtensionAbsoluteSendTime: {
// Nullify whole extension, as it's filled in the pacer. // Nullify whole extension, as it's filled in the pacer.
memset(WriteAt(extension.offset), 0, extension.length); memset(buffer.data() + extension.offset, 0, extension.length);
break; break;
} }
case RTPExtensionType::kRtpExtensionAudioLevel: case RTPExtensionType::kRtpExtensionAudioLevel:

View File

@ -89,9 +89,9 @@ class RtpPacket {
void SetTimestamp(uint32_t timestamp); void SetTimestamp(uint32_t timestamp);
void SetSsrc(uint32_t ssrc); void SetSsrc(uint32_t ssrc);
// Fills with zeroes mutable extensions, // Copies the buffer with zero-ed mutable extensions,
// which are modified after FEC protection is generated. // which are modified after FEC protection is generated.
void ZeroMutableExtensions(); void CopyAndZeroMutableExtensions(rtc::ArrayView<uint8_t> buffer) const;
// Removes extension of given |type|, returns false is extension was not // Removes extension of given |type|, returns false is extension was not
// registered in packet's extension map or not present in the packet. Only // registered in packet's extension map or not present in the packet. Only

View File

@ -278,7 +278,8 @@ void RTPSenderVideo::SendVideoPacketAsRedMaybeWithUlpfec(
if (ulpfec_enabled()) { if (ulpfec_enabled()) {
if (protect_media_packet) { if (protect_media_packet) {
ulpfec_generator_.AddRtpPacketAndGenerateFec( ulpfec_generator_.AddRtpPacketAndGenerateFec(
media_packet->Buffer(), media_packet->headers_size()); media_packet->data(), media_packet->payload_size(),
media_packet->headers_size());
} }
uint16_t num_fec_packets = ulpfec_generator_.NumAvailableFecPackets(); uint16_t num_fec_packets = ulpfec_generator_.NumAvailableFecPackets();
if (num_fec_packets > 0) { if (num_fec_packets > 0) {

View File

@ -133,8 +133,8 @@ void UlpfecGenerator::SetFecParameters(const FecProtectionParams& params) {
} }
} }
int UlpfecGenerator::AddRtpPacketAndGenerateFec( int UlpfecGenerator::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer,
const rtc::CopyOnWriteBuffer& data_buffer, size_t payload_length,
size_t rtp_header_length) { size_t rtp_header_length) {
RTC_DCHECK(generated_fec_packets_.empty()); RTC_DCHECK(generated_fec_packets_.empty());
if (media_packets_.empty()) { if (media_packets_.empty()) {
@ -146,9 +146,8 @@ int UlpfecGenerator::AddRtpPacketAndGenerateFec(
// Our packet masks can only protect up to |kUlpfecMaxMediaPackets| packets. // Our packet masks can only protect up to |kUlpfecMaxMediaPackets| packets.
std::unique_ptr<ForwardErrorCorrection::Packet> packet( std::unique_ptr<ForwardErrorCorrection::Packet> packet(
new ForwardErrorCorrection::Packet()); new ForwardErrorCorrection::Packet());
RTC_DCHECK_GE(data_buffer.size(), rtp_header_length); packet->length = payload_length + rtp_header_length;
packet->data = data_buffer; memcpy(packet->data, data_buffer, packet->length);
packet->length = packet->data.size();
media_packets_.push_back(std::move(packet)); media_packets_.push_back(std::move(packet));
// Keep track of the RTP header length, so we can copy the RTP header // Keep track of the RTP header length, so we can copy the RTP header
// from |packet| to newly generated ULPFEC+RED packets. // from |packet| to newly generated ULPFEC+RED packets.
@ -227,12 +226,12 @@ std::vector<std::unique_ptr<RedPacket>> UlpfecGenerator::GetUlpfecPacketsAsRed(
std::unique_ptr<RedPacket> red_packet( std::unique_ptr<RedPacket> red_packet(
new RedPacket(last_media_packet_rtp_header_length_ + new RedPacket(last_media_packet_rtp_header_length_ +
kRedForFecHeaderLength + fec_packet->length)); kRedForFecHeaderLength + fec_packet->length));
red_packet->CreateHeader(last_media_packet->data.data(), red_packet->CreateHeader(last_media_packet->data,
last_media_packet_rtp_header_length_, last_media_packet_rtp_header_length_,
red_payload_type, ulpfec_payload_type); red_payload_type, ulpfec_payload_type);
red_packet->SetSeqNum(seq_num++); red_packet->SetSeqNum(seq_num++);
red_packet->ClearMarkerBit(); red_packet->ClearMarkerBit();
red_packet->AssignPayload(fec_packet->data.data(), fec_packet->length); red_packet->AssignPayload(fec_packet->data, fec_packet->length);
red_packets.push_back(std::move(red_packet)); red_packets.push_back(std::move(red_packet));
} }

View File

@ -58,7 +58,8 @@ class UlpfecGenerator {
// Adds a media packet to the internal buffer. When enough media packets // Adds a media packet to the internal buffer. When enough media packets
// have been added, the FEC packets are generated and stored internally. // have been added, the FEC packets are generated and stored internally.
// These FEC packets are then obtained by calling GetFecPacketsAsRed(). // These FEC packets are then obtained by calling GetFecPacketsAsRed().
int AddRtpPacketAndGenerateFec(const rtc::CopyOnWriteBuffer& data_buffer, int AddRtpPacketAndGenerateFec(const uint8_t* data_buffer,
size_t payload_length,
size_t rtp_header_length); size_t rtp_header_length);
// Returns true if there are generated FEC packets available. // Returns true if there are generated FEC packets available.

View File

@ -90,8 +90,7 @@ TEST_F(UlpfecGeneratorTest, NoEmptyFecWithSeqNumGaps) {
packet[1] &= ~0x80; packet[1] &= ~0x80;
} }
ByteWriter<uint16_t>::WriteBigEndian(&packet[2], p.seq_num); ByteWriter<uint16_t>::WriteBigEndian(&packet[2], p.seq_num);
ulpfec_generator_.AddRtpPacketAndGenerateFec( ulpfec_generator_.AddRtpPacketAndGenerateFec(packet, p.payload_size,
rtc::CopyOnWriteBuffer(packet, p.payload_size + p.header_size),
p.header_size); p.header_size);
size_t num_fec_packets = ulpfec_generator_.NumAvailableFecPackets(); size_t num_fec_packets = ulpfec_generator_.NumAvailableFecPackets();
if (num_fec_packets > 0) { if (num_fec_packets > 0) {
@ -118,8 +117,8 @@ TEST_F(UlpfecGeneratorTest, OneFrameFec) {
for (size_t i = 0; i < kNumPackets; ++i) { for (size_t i = 0; i < kNumPackets; ++i) {
std::unique_ptr<AugmentedPacket> packet = std::unique_ptr<AugmentedPacket> packet =
packet_generator_.NextPacket(i, 10); packet_generator_.NextPacket(i, 10);
EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(packet->data, EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(
kRtpHeaderSize)); packet->data, packet->length, kRtpHeaderSize));
last_timestamp = packet->header.timestamp; last_timestamp = packet->header.timestamp;
} }
EXPECT_TRUE(ulpfec_generator_.FecAvailable()); EXPECT_TRUE(ulpfec_generator_.FecAvailable());
@ -153,7 +152,7 @@ TEST_F(UlpfecGeneratorTest, TwoFrameFec) {
std::unique_ptr<AugmentedPacket> packet = std::unique_ptr<AugmentedPacket> packet =
packet_generator_.NextPacket(i * kNumPackets + j, 10); packet_generator_.NextPacket(i * kNumPackets + j, 10);
EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec( EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(
packet->data, kRtpHeaderSize)); packet->data, packet->length, kRtpHeaderSize));
last_timestamp = packet->header.timestamp; last_timestamp = packet->header.timestamp;
} }
} }
@ -182,7 +181,7 @@ TEST_F(UlpfecGeneratorTest, MixedMediaRtpHeaderLengths) {
std::unique_ptr<AugmentedPacket> packet = std::unique_ptr<AugmentedPacket> packet =
packet_generator_.NextPacket(i, 10); packet_generator_.NextPacket(i, 10);
EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec( EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(
packet->data, kShortRtpHeaderLength)); packet->data, packet->length, kShortRtpHeaderLength));
EXPECT_FALSE(ulpfec_generator_.FecAvailable()); EXPECT_FALSE(ulpfec_generator_.FecAvailable());
} }
@ -191,7 +190,7 @@ TEST_F(UlpfecGeneratorTest, MixedMediaRtpHeaderLengths) {
std::unique_ptr<AugmentedPacket> packet = std::unique_ptr<AugmentedPacket> packet =
packet_generator_.NextPacket(kUlpfecMaxMediaPackets, 10); packet_generator_.NextPacket(kUlpfecMaxMediaPackets, 10);
EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec( EXPECT_EQ(0, ulpfec_generator_.AddRtpPacketAndGenerateFec(
packet->data, kLongRtpHeaderLength)); packet->data, packet->length, kLongRtpHeaderLength));
EXPECT_TRUE(ulpfec_generator_.FecAvailable()); EXPECT_TRUE(ulpfec_generator_.FecAvailable());
// Ensure that the RED header is placed correctly, i.e. the correct // Ensure that the RED header is placed correctly, i.e. the correct

View File

@ -53,7 +53,6 @@ std::unique_ptr<Packet> WriteHeader(const uint8_t* packet_mask,
UlpfecHeaderWriter writer; UlpfecHeaderWriter writer;
std::unique_ptr<Packet> written_packet(new Packet()); std::unique_ptr<Packet> written_packet(new Packet());
written_packet->length = kMediaPacketLength; written_packet->length = kMediaPacketLength;
written_packet->data.SetSize(written_packet->length);
for (size_t i = 0; i < written_packet->length; ++i) { for (size_t i = 0; i < written_packet->length; ++i) {
written_packet->data[i] = i; // Actual content doesn't matter. written_packet->data[i] = i; // Actual content doesn't matter.
} }
@ -67,7 +66,7 @@ std::unique_ptr<ReceivedFecPacket> ReadHeader(const Packet& written_packet) {
std::unique_ptr<ReceivedFecPacket> read_packet(new ReceivedFecPacket()); std::unique_ptr<ReceivedFecPacket> read_packet(new ReceivedFecPacket());
read_packet->ssrc = kMediaSsrc; read_packet->ssrc = kMediaSsrc;
read_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); read_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
read_packet->pkt->data = written_packet.data; memcpy(read_packet->pkt->data, written_packet.data, written_packet.length);
read_packet->pkt->length = written_packet.length; read_packet->pkt->length = written_packet.length;
EXPECT_TRUE(reader.ReadFecHeader(read_packet.get())); EXPECT_TRUE(reader.ReadFecHeader(read_packet.get()));
return read_packet; return read_packet;
@ -90,8 +89,8 @@ void VerifyHeaders(size_t expected_fec_header_size,
&read_packet.pkt->data[read_packet.packet_mask_offset], &read_packet.pkt->data[read_packet.packet_mask_offset],
read_packet.packet_mask_size)); read_packet.packet_mask_size));
// Verify that the call to ReadFecHeader did not tamper with the payload. // Verify that the call to ReadFecHeader did not tamper with the payload.
EXPECT_EQ(0, memcmp(written_packet.data.data() + expected_fec_header_size, EXPECT_EQ(0, memcmp(&written_packet.data[expected_fec_header_size],
read_packet.pkt->data.cdata() + expected_fec_header_size, &read_packet.pkt->data[expected_fec_header_size],
written_packet.length - expected_fec_header_size)); written_packet.length - expected_fec_header_size));
} }
@ -108,7 +107,7 @@ TEST(UlpfecHeaderReaderTest, ReadsSmallHeader) {
const size_t packet_length = sizeof(packet); const size_t packet_length = sizeof(packet);
ReceivedFecPacket read_packet; ReceivedFecPacket read_packet;
read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet()); read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
read_packet.pkt->data.SetData(packet, packet_length); memcpy(read_packet.pkt->data, packet, packet_length);
read_packet.pkt->length = packet_length; read_packet.pkt->length = packet_length;
UlpfecHeaderReader reader; UlpfecHeaderReader reader;
@ -133,7 +132,7 @@ TEST(UlpfecHeaderReaderTest, ReadsLargeHeader) {
const size_t packet_length = sizeof(packet); const size_t packet_length = sizeof(packet);
ReceivedFecPacket read_packet; ReceivedFecPacket read_packet;
read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet()); read_packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
read_packet.pkt->data.SetData(packet, packet_length); memcpy(read_packet.pkt->data, packet, packet_length);
read_packet.pkt->length = packet_length; read_packet.pkt->length = packet_length;
UlpfecHeaderReader reader; UlpfecHeaderReader reader;
@ -151,7 +150,6 @@ TEST(UlpfecHeaderWriterTest, FinalizesSmallHeader) {
auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd); auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
Packet written_packet; Packet written_packet;
written_packet.length = kMediaPacketLength; written_packet.length = kMediaPacketLength;
written_packet.data.SetSize(written_packet.length);
for (size_t i = 0; i < written_packet.length; ++i) { for (size_t i = 0; i < written_packet.length; ++i) {
written_packet.data[i] = i; written_packet.data[i] = i;
} }
@ -160,7 +158,7 @@ TEST(UlpfecHeaderWriterTest, FinalizesSmallHeader) {
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(), writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(),
packet_mask_size, &written_packet); packet_mask_size, &written_packet);
const uint8_t* packet = written_packet.data.cdata(); const uint8_t* packet = written_packet.data;
EXPECT_EQ(0x00, packet[0] & 0x80); // E bit. EXPECT_EQ(0x00, packet[0] & 0x80); // E bit.
EXPECT_EQ(0x00, packet[0] & 0x40); // L bit. EXPECT_EQ(0x00, packet[0] & 0x40); // L bit.
EXPECT_EQ(kMediaStartSeqNum, ByteReader<uint16_t>::ReadBigEndian(packet + 2)); EXPECT_EQ(kMediaStartSeqNum, ByteReader<uint16_t>::ReadBigEndian(packet + 2));
@ -176,7 +174,6 @@ TEST(UlpfecHeaderWriterTest, FinalizesLargeHeader) {
auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd); auto packet_mask = GeneratePacketMask(packet_mask_size, 0xabcd);
Packet written_packet; Packet written_packet;
written_packet.length = kMediaPacketLength; written_packet.length = kMediaPacketLength;
written_packet.data.SetSize(written_packet.length);
for (size_t i = 0; i < written_packet.length; ++i) { for (size_t i = 0; i < written_packet.length; ++i) {
written_packet.data[i] = i; written_packet.data[i] = i;
} }
@ -185,7 +182,7 @@ TEST(UlpfecHeaderWriterTest, FinalizesLargeHeader) {
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(), writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(),
packet_mask_size, &written_packet); packet_mask_size, &written_packet);
const uint8_t* packet = written_packet.data.cdata(); const uint8_t* packet = written_packet.data;
EXPECT_EQ(0x00, packet[0] & 0x80); // E bit. EXPECT_EQ(0x00, packet[0] & 0x80); // E bit.
EXPECT_EQ(0x40, packet[0] & 0x40); // L bit. EXPECT_EQ(0x40, packet[0] & 0x40); // L bit.
EXPECT_EQ(kMediaStartSeqNum, ByteReader<uint16_t>::ReadBigEndian(packet + 2)); EXPECT_EQ(kMediaStartSeqNum, ByteReader<uint16_t>::ReadBigEndian(packet + 2));

View File

@ -130,7 +130,7 @@ int32_t UlpfecReceiverImpl::AddReceivedRedPacket(
++packet_counter_.num_fec_packets; ++packet_counter_.num_fec_packets;
// everything behind the RED header // everything behind the RED header
received_packet->pkt->data.SetData( memcpy(received_packet->pkt->data,
incoming_rtp_packet + header.headerLength + red_header_length, incoming_rtp_packet + header.headerLength + red_header_length,
payload_data_length - red_header_length); payload_data_length - red_header_length);
received_packet->pkt->length = payload_data_length - red_header_length; received_packet->pkt->length = payload_data_length - red_header_length;
@ -138,20 +138,18 @@ int32_t UlpfecReceiverImpl::AddReceivedRedPacket(
ByteReader<uint32_t>::ReadBigEndian(&incoming_rtp_packet[8]); ByteReader<uint32_t>::ReadBigEndian(&incoming_rtp_packet[8]);
} else { } else {
received_packet->pkt->data.SetSize(header.headerLength +
payload_data_length - red_header_length);
// Copy RTP header. // Copy RTP header.
memcpy(received_packet->pkt->data.data(), incoming_rtp_packet, memcpy(received_packet->pkt->data, incoming_rtp_packet,
header.headerLength); header.headerLength);
// Set payload type. // Set payload type.
received_packet->pkt->data[1] &= 0x80; // Reset RED payload type. received_packet->pkt->data[1] &= 0x80; // Reset RED payload type.
received_packet->pkt->data[1] += payload_type; // Set media payload type. received_packet->pkt->data[1] += payload_type; // Set media payload type.
// Copy payload data. // Copy payload data.
if (payload_data_length > red_header_length) { memcpy(received_packet->pkt->data + header.headerLength,
memcpy(received_packet->pkt->data.data() + header.headerLength,
incoming_rtp_packet + header.headerLength + red_header_length, incoming_rtp_packet + header.headerLength + red_header_length,
payload_data_length - red_header_length); payload_data_length - red_header_length);
}
received_packet->pkt->length = received_packet->pkt->length =
header.headerLength + payload_data_length - red_header_length; header.headerLength + payload_data_length - red_header_length;
} }
@ -184,18 +182,16 @@ int32_t UlpfecReceiverImpl::ProcessReceivedFec() {
if (!received_packet->is_fec) { if (!received_packet->is_fec) {
ForwardErrorCorrection::Packet* packet = received_packet->pkt; ForwardErrorCorrection::Packet* packet = received_packet->pkt;
crit_sect_.Leave(); crit_sect_.Leave();
recovered_packet_callback_->OnRecoveredPacket(packet->data.data(), recovered_packet_callback_->OnRecoveredPacket(packet->data,
packet->length); packet->length);
crit_sect_.Enter(); crit_sect_.Enter();
// Create a packet with the buffer to modify it.
RtpPacketReceived rtp_packet; RtpPacketReceived rtp_packet;
rtp_packet.Parse(packet->data); // TODO(ilnik): move extension nullifying out of RtpPacket, so there's no
// need to create one here, and avoid two memcpy calls below.
rtp_packet.Parse(packet->data, packet->length); // Does memcopy.
rtp_packet.IdentifyExtensions(extensions_); rtp_packet.IdentifyExtensions(extensions_);
// Reset buffer reference, so zeroing would work on a buffer with a rtp_packet.CopyAndZeroMutableExtensions( // Does memcopy.
// single reference. rtc::MakeArrayView(packet->data, packet->length));
packet->data = rtc::CopyOnWriteBuffer(0);
rtp_packet.ZeroMutableExtensions();
packet->data = rtp_packet.Buffer();
} }
fec_->DecodeFec(*received_packet, &recovered_packets_); fec_->DecodeFec(*received_packet, &recovered_packets_);
} }
@ -212,8 +208,7 @@ int32_t UlpfecReceiverImpl::ProcessReceivedFec() {
// header, OnRecoveredPacket will recurse back here. // header, OnRecoveredPacket will recurse back here.
recovered_packet->returned = true; recovered_packet->returned = true;
crit_sect_.Leave(); crit_sect_.Leave();
recovered_packet_callback_->OnRecoveredPacket(packet->data.data(), recovered_packet_callback_->OnRecoveredPacket(packet->data, packet->length);
packet->length);
crit_sect_.Enter(); crit_sect_.Enter();
} }

View File

@ -126,16 +126,16 @@ void UlpfecReceiverTest::BuildAndAddRedMediaPacket(AugmentedPacket* packet) {
std::unique_ptr<AugmentedPacket> red_packet( std::unique_ptr<AugmentedPacket> red_packet(
packet_generator_.BuildMediaRedPacket(*packet)); packet_generator_.BuildMediaRedPacket(*packet));
EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket(
red_packet->header, red_packet->data.cdata(), red_packet->header, red_packet->data, red_packet->length,
red_packet->length, kFecPayloadType)); kFecPayloadType));
} }
void UlpfecReceiverTest::BuildAndAddRedFecPacket(Packet* packet) { void UlpfecReceiverTest::BuildAndAddRedFecPacket(Packet* packet) {
std::unique_ptr<AugmentedPacket> red_packet( std::unique_ptr<AugmentedPacket> red_packet(
packet_generator_.BuildUlpfecRedPacket(*packet)); packet_generator_.BuildUlpfecRedPacket(*packet));
EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket( EXPECT_EQ(0, receiver_fec_->AddReceivedRedPacket(
red_packet->header, red_packet->data.cdata(), red_packet->header, red_packet->data, red_packet->length,
red_packet->length, kFecPayloadType)); kFecPayloadType));
} }
void UlpfecReceiverTest::VerifyReconstructedMediaPacket( void UlpfecReceiverTest::VerifyReconstructedMediaPacket(
@ -145,7 +145,7 @@ void UlpfecReceiverTest::VerifyReconstructedMediaPacket(
// content of |packet|, and that the same content is received |times| number // content of |packet|, and that the same content is received |times| number
// of times in a row. // of times in a row.
EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, packet.length)) EXPECT_CALL(recovered_packet_receiver_, OnRecoveredPacket(_, packet.length))
.With(Args<0, 1>(ElementsAreArray(packet.data.cdata(), packet.length))) .With(Args<0, 1>(ElementsAreArray(packet.data, packet.length)))
.Times(times); .Times(times);
} }

View File

@ -70,7 +70,8 @@ void ReceivePackets(
new ForwardErrorCorrection::ReceivedPacket()); new ForwardErrorCorrection::ReceivedPacket());
*duplicate_packet = *received_packet; *duplicate_packet = *received_packet;
duplicate_packet->pkt = new ForwardErrorCorrection::Packet(); duplicate_packet->pkt = new ForwardErrorCorrection::Packet();
duplicate_packet->pkt->data = received_packet->pkt->data; memcpy(duplicate_packet->pkt->data, received_packet->pkt->data,
received_packet->pkt->length);
duplicate_packet->pkt->length = received_packet->pkt->length; duplicate_packet->pkt->length = received_packet->pkt->length;
to_decode_list->push_back(std::move(duplicate_packet)); to_decode_list->push_back(std::move(duplicate_packet));
@ -253,7 +254,6 @@ void RunTest(bool use_flexfec) {
IP_PACKET_SIZE - 12 - 28 - fec->MaxPacketOverhead()); IP_PACKET_SIZE - 12 - 28 - fec->MaxPacketOverhead());
media_packet->length = media_packet->length =
random.Rand(kMinPacketSize, kMaxPacketSize); random.Rand(kMinPacketSize, kMaxPacketSize);
media_packet->data.SetSize(media_packet->length);
// Generate random values for the first 2 bytes. // Generate random values for the first 2 bytes.
media_packet->data[0] = random.Rand<uint8_t>(); media_packet->data[0] = random.Rand<uint8_t>();
@ -312,7 +312,8 @@ void RunTest(bool use_flexfec) {
new ForwardErrorCorrection::ReceivedPacket()); new ForwardErrorCorrection::ReceivedPacket());
received_packet->pkt = new ForwardErrorCorrection::Packet(); received_packet->pkt = new ForwardErrorCorrection::Packet();
received_packet->pkt->length = media_packet->length; received_packet->pkt->length = media_packet->length;
received_packet->pkt->data = media_packet->data; memcpy(received_packet->pkt->data, media_packet->data,
media_packet->length);
received_packet->ssrc = media_ssrc; received_packet->ssrc = media_ssrc;
received_packet->seq_num = received_packet->seq_num =
ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]); ByteReader<uint16_t>::ReadBigEndian(&media_packet->data[2]);
@ -333,7 +334,8 @@ void RunTest(bool use_flexfec) {
new ForwardErrorCorrection::ReceivedPacket()); new ForwardErrorCorrection::ReceivedPacket());
received_packet->pkt = new ForwardErrorCorrection::Packet(); received_packet->pkt = new ForwardErrorCorrection::Packet();
received_packet->pkt->length = fec_packet->length; received_packet->pkt->length = fec_packet->length;
received_packet->pkt->data = fec_packet->data; memcpy(received_packet->pkt->data, fec_packet->data,
fec_packet->length);
received_packet->seq_num = fec_seq_num_offset + seq_num; received_packet->seq_num = fec_seq_num_offset + seq_num;
received_packet->is_fec = true; received_packet->is_fec = true;
received_packet->ssrc = fec_ssrc; received_packet->ssrc = fec_ssrc;
@ -424,9 +426,8 @@ void RunTest(bool use_flexfec) {
ASSERT_EQ(recovered_packet->pkt->length, media_packet->length) ASSERT_EQ(recovered_packet->pkt->length, media_packet->length)
<< "Recovered packet length not identical to original " << "Recovered packet length not identical to original "
<< "media packet"; << "media packet";
ASSERT_EQ( ASSERT_EQ(0, memcmp(recovered_packet->pkt->data,
0, memcmp(recovered_packet->pkt->data.cdata(), media_packet->data, media_packet->length))
media_packet->data.cdata(), media_packet->length))
<< "Recovered packet payload not identical to original " << "Recovered packet payload not identical to original "
<< "media packet"; << "media packet";
recovered_packet_list.pop_front(); recovered_packet_list.pop_front();

View File

@ -25,8 +25,7 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
packet.pkt = rtc::scoped_refptr<Packet>(new Packet()); packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
const size_t packet_size = const size_t packet_size =
std::min(size, static_cast<size_t>(IP_PACKET_SIZE)); std::min(size, static_cast<size_t>(IP_PACKET_SIZE));
packet.pkt->data.SetSize(packet_size); memcpy(packet.pkt->data, data, packet_size);
memcpy(packet.pkt->data.data(), data, packet_size);
packet.pkt->length = packet_size; packet.pkt->length = packet_size;
FlexfecHeaderReader flexfec_reader; FlexfecHeaderReader flexfec_reader;

View File

@ -67,7 +67,7 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
received_packet.pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>( received_packet.pkt = rtc::scoped_refptr<ForwardErrorCorrection::Packet>(
new ForwardErrorCorrection::Packet()); new ForwardErrorCorrection::Packet());
received_packet.pkt->length = kPacketSize; received_packet.pkt->length = kPacketSize;
uint8_t* packet_buffer = received_packet.pkt->data.data(); uint8_t* packet_buffer = received_packet.pkt->data;
uint8_t reordering; uint8_t reordering;
uint16_t seq_num_diff; uint16_t seq_num_diff;
uint8_t packet_type; uint8_t packet_type;

View File

@ -15,7 +15,6 @@
#include "modules/rtp_rtcp/source/fec_test_helper.h" #include "modules/rtp_rtcp/source/fec_test_helper.h"
#include "modules/rtp_rtcp/source/ulpfec_generator.h" #include "modules/rtp_rtcp/source/ulpfec_generator.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/copy_on_write_buffer.h"
namespace webrtc { namespace webrtc {
@ -39,7 +38,9 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
size_t payload_size = data[i++] % 10; size_t payload_size = data[i++] % 10;
if (i + payload_size + rtp_header_length + 2 > size) if (i + payload_size + rtp_header_length + 2 > size)
break; break;
rtc::CopyOnWriteBuffer packet(&data[i], payload_size + rtp_header_length); std::unique_ptr<uint8_t[]> packet(
new uint8_t[payload_size + rtp_header_length]);
memcpy(packet.get(), &data[i], payload_size + rtp_header_length);
// Make sure sequence numbers are increasing. // Make sure sequence numbers are increasing.
ByteWriter<uint16_t>::WriteBigEndian(&packet[2], seq_num++); ByteWriter<uint16_t>::WriteBigEndian(&packet[2], seq_num++);
@ -51,7 +52,8 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
// number became out of order. // number became out of order.
if (protect && IsNewerSequenceNumber(seq_num, prev_seq_num) && if (protect && IsNewerSequenceNumber(seq_num, prev_seq_num) &&
seq_num < prev_seq_num + kUlpfecMaxMediaPackets) { seq_num < prev_seq_num + kUlpfecMaxMediaPackets) {
generator.AddRtpPacketAndGenerateFec(packet, rtp_header_length); generator.AddRtpPacketAndGenerateFec(packet.get(), payload_size,
rtp_header_length);
prev_seq_num = seq_num; prev_seq_num = seq_num;
} }
const size_t num_fec_packets = generator.NumAvailableFecPackets(); const size_t num_fec_packets = generator.NumAvailableFecPackets();

View File

@ -25,8 +25,7 @@ void FuzzOneInput(const uint8_t* data, size_t size) {
packet.pkt = rtc::scoped_refptr<Packet>(new Packet()); packet.pkt = rtc::scoped_refptr<Packet>(new Packet());
const size_t packet_size = const size_t packet_size =
std::min(size, static_cast<size_t>(IP_PACKET_SIZE)); std::min(size, static_cast<size_t>(IP_PACKET_SIZE));
packet.pkt->data.SetSize(packet_size); memcpy(packet.pkt->data, data, packet_size);
memcpy(packet.pkt->data.data(), data, packet_size);
packet.pkt->length = packet_size; packet.pkt->length = packet_size;
UlpfecHeaderReader ulpfec_reader; UlpfecHeaderReader ulpfec_reader;