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}
This commit is contained in:
Ilya Nikolaevskiy
2019-07-10 11:28:04 +02:00
committed by Commit Bot
parent 1300ce12e8
commit 7325bc3917
24 changed files with 199 additions and 159 deletions

View File

@ -130,26 +130,28 @@ int32_t UlpfecReceiverImpl::AddReceivedRedPacket(
++packet_counter_.num_fec_packets;
// everything behind the RED header
memcpy(received_packet->pkt->data,
incoming_rtp_packet + header.headerLength + red_header_length,
payload_data_length - red_header_length);
received_packet->pkt->data.SetData(
incoming_rtp_packet + header.headerLength + red_header_length,
payload_data_length - red_header_length);
received_packet->pkt->length = payload_data_length - red_header_length;
received_packet->ssrc =
ByteReader<uint32_t>::ReadBigEndian(&incoming_rtp_packet[8]);
} else {
received_packet->pkt->data.SetSize(header.headerLength +
payload_data_length - red_header_length);
// Copy RTP header.
memcpy(received_packet->pkt->data, incoming_rtp_packet,
memcpy(received_packet->pkt->data.data(), incoming_rtp_packet,
header.headerLength);
// Set payload type.
received_packet->pkt->data[1] &= 0x80; // Reset RED payload type.
received_packet->pkt->data[1] += payload_type; // Set media payload type.
// Copy payload data.
memcpy(received_packet->pkt->data + header.headerLength,
incoming_rtp_packet + header.headerLength + red_header_length,
payload_data_length - red_header_length);
if (payload_data_length > red_header_length) {
memcpy(received_packet->pkt->data.data() + header.headerLength,
incoming_rtp_packet + header.headerLength + red_header_length,
payload_data_length - red_header_length);
}
received_packet->pkt->length =
header.headerLength + payload_data_length - red_header_length;
}
@ -182,16 +184,18 @@ int32_t UlpfecReceiverImpl::ProcessReceivedFec() {
if (!received_packet->is_fec) {
ForwardErrorCorrection::Packet* packet = received_packet->pkt;
crit_sect_.Leave();
recovered_packet_callback_->OnRecoveredPacket(packet->data,
recovered_packet_callback_->OnRecoveredPacket(packet->data.data(),
packet->length);
crit_sect_.Enter();
// Create a packet with the buffer to modify it.
RtpPacketReceived rtp_packet;
// 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.Parse(packet->data);
rtp_packet.IdentifyExtensions(extensions_);
rtp_packet.CopyAndZeroMutableExtensions( // Does memcopy.
rtc::MakeArrayView(packet->data, packet->length));
// Reset buffer reference, so zeroing would work on a buffer with a
// single reference.
packet->data = rtc::CopyOnWriteBuffer(0);
rtp_packet.ZeroMutableExtensions();
packet->data = rtp_packet.Buffer();
}
fec_->DecodeFec(*received_packet, &recovered_packets_);
}
@ -208,7 +212,8 @@ int32_t UlpfecReceiverImpl::ProcessReceivedFec() {
// header, OnRecoveredPacket will recurse back here.
recovered_packet->returned = true;
crit_sect_.Leave();
recovered_packet_callback_->OnRecoveredPacket(packet->data, packet->length);
recovered_packet_callback_->OnRecoveredPacket(packet->data.data(),
packet->length);
crit_sect_.Enter();
}