Change FinalizeFecHeader to receive list of streams

Changed FinalizeFecHeader to recieve a list of `ProtectedStream` struct,
in order to prepare for receiving multiple ssrcs to protect in the same
FEC packet header. Implementation of the multistream case will follow in
next CL.

Change-Id: I697ef9172a07797a6f500b9ec3a9916f8f45bc04
Bug: webrtc:15002
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/307620
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40269}
This commit is contained in:
Yosef Twaik 2023-06-07 20:31:54 +03:00 committed by WebRTC LUCI CQ
parent cfa0f817b7
commit bde7c6ad11
10 changed files with 85 additions and 59 deletions

View File

@ -245,16 +245,16 @@ size_t Flexfec03HeaderWriter::FecHeaderSize(size_t packet_mask_size) const {
// FlexFEC header standard. Note that the header size is computed by
// FecHeaderSize(), so in this function we can be sure that we are
// writing in space that is intended for the header.
//
// TODO(brandtr): Update this function when we support offset-based masks,
// retransmissions, and protecting multiple SSRCs.
void Flexfec03HeaderWriter::FinalizeFecHeader(
uint32_t media_ssrc,
uint16_t seq_num_base,
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const {
uint8_t* data = fec_packet->data.MutableData();
rtc::ArrayView<const ProtectedStream> protected_streams,
ForwardErrorCorrection::Packet& fec_packet) const {
RTC_CHECK_EQ(protected_streams.size(), 1);
uint32_t media_ssrc = protected_streams[0].ssrc;
uint16_t seq_num_base = protected_streams[0].seq_num_base;
const uint8_t* packet_mask = protected_streams[0].packet_mask.data();
size_t packet_mask_size = protected_streams[0].packet_mask.size();
uint8_t* data = fec_packet.data.MutableData();
data[0] &= 0x7f; // Clear R bit.
data[0] &= 0xbf; // Clear F bit.
ByteWriter<uint8_t>::WriteBigEndian(&data[8], kSsrcCount);

View File

@ -76,11 +76,8 @@ class Flexfec03HeaderWriter : public FecHeaderWriter {
size_t FecHeaderSize(size_t packet_mask_row_size) const override;
void FinalizeFecHeader(
uint32_t media_ssrc,
uint16_t seq_num_base,
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const override;
rtc::ArrayView<const ProtectedStream> protected_streams,
ForwardErrorCorrection::Packet& fec_packet) const override;
};
} // namespace webrtc

View File

@ -85,8 +85,11 @@ rtc::scoped_refptr<Packet> WriteHeader(const uint8_t* packet_mask,
for (size_t i = 0; i < written_packet->data.size(); ++i) {
data[i] = i; // Actual content doesn't matter.
}
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask,
packet_mask_size, written_packet.get());
const FecHeaderWriter::ProtectedStream protected_streams[] = {
{.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = {packet_mask, packet_mask_size}}};
writer.FinalizeFecHeader(protected_streams, *written_packet);
return written_packet;
}
@ -339,8 +342,11 @@ TEST(Flexfec03HeaderWriterTest, FinalizesHeaderWithKBit0Set) {
}
Flexfec03HeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask,
sizeof(kUlpfecPacketMask), &written_packet);
const FecHeaderWriter::ProtectedStream protected_streams[] = {
{.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = kUlpfecPacketMask}};
writer.FinalizeFecHeader(protected_streams, written_packet);
VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
written_packet);
@ -358,8 +364,11 @@ TEST(Flexfec03HeaderWriterTest, FinalizesHeaderWithKBit1Set) {
}
Flexfec03HeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask,
sizeof(kUlpfecPacketMask), &written_packet);
const FecHeaderWriter::ProtectedStream protected_streams[] = {
{.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = kUlpfecPacketMask}};
writer.FinalizeFecHeader(protected_streams, written_packet);
VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
written_packet);
@ -381,8 +390,11 @@ TEST(Flexfec03HeaderWriterTest, FinalizesHeaderWithKBit2Set) {
}
Flexfec03HeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask,
sizeof(kUlpfecPacketMask), &written_packet);
const FecHeaderWriter::ProtectedStream protected_streams[] = {
{.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = kUlpfecPacketMask}};
writer.FinalizeFecHeader(protected_streams, written_packet);
VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
written_packet);

View File

@ -258,12 +258,17 @@ size_t FlexfecHeaderWriter::FecHeaderSize(size_t packet_mask_size) const {
// TODO(brandtr): Update this function when we support offset-based masks,
// retransmissions, and protecting multiple SSRCs.
void FlexfecHeaderWriter::FinalizeFecHeader(
uint32_t media_ssrc,
uint16_t seq_num_base,
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const {
uint8_t* data = fec_packet->data.MutableData();
rtc::ArrayView<const ProtectedStream> protected_streams,
ForwardErrorCorrection::Packet& fec_packet) const {
// TODO(bugs.webrtc.org/15002): Iterate over all streams and update FlexFEC
// header accordingly.
RTC_CHECK_EQ(protected_streams.size(), 1);
uint32_t media_ssrc = protected_streams[0].ssrc;
uint16_t seq_num_base = protected_streams[0].seq_num_base;
const uint8_t* packet_mask = protected_streams[0].packet_mask.data();
size_t packet_mask_size = protected_streams[0].packet_mask.size();
uint8_t* data = fec_packet.data.MutableData();
data[0] &= 0x7f; // Clear R bit.
data[0] &= 0xbf; // Clear F bit.
ByteWriter<uint8_t>::WriteBigEndian(&data[8], kSsrcCount);

View File

@ -58,11 +58,8 @@ class FlexfecHeaderWriter : public FecHeaderWriter {
size_t FecHeaderSize(size_t packet_mask_row_size) const override;
void FinalizeFecHeader(
uint32_t media_ssrc,
uint16_t seq_num_base,
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const override;
rtc::ArrayView<const ProtectedStream> protected_streams,
ForwardErrorCorrection::Packet& fec_packet) const override;
};
} // namespace webrtc

View File

@ -328,9 +328,13 @@ void ForwardErrorCorrection::FinalizeFecHeaders(size_t num_fec_packets,
uint32_t media_ssrc,
uint16_t seq_num_base) {
for (size_t i = 0; i < num_fec_packets; ++i) {
fec_header_writer_->FinalizeFecHeader(
media_ssrc, seq_num_base, &packet_masks_[i * packet_mask_size_],
packet_mask_size_, &generated_fec_packets_[i]);
const FecHeaderWriter::ProtectedStream protected_streams[] = {
{.ssrc = media_ssrc,
.seq_num_base = seq_num_base,
.packet_mask = {&packet_masks_[i * packet_mask_size_],
packet_mask_size_}}};
fec_header_writer_->FinalizeFecHeader(protected_streams,
generated_fec_packets_[i]);
}
}

View File

@ -391,6 +391,12 @@ class FecHeaderReader {
class FecHeaderWriter {
public:
struct ProtectedStream {
uint32_t ssrc = 0;
uint16_t seq_num_base = 0;
rtc::ArrayView<const uint8_t> packet_mask;
};
virtual ~FecHeaderWriter();
// The maximum number of media packets that can be covered by one FEC packet.
@ -414,11 +420,8 @@ class FecHeaderWriter {
// Writes FEC header.
virtual void FinalizeFecHeader(
uint32_t media_ssrc,
uint16_t seq_num_base,
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const = 0;
rtc::ArrayView<const ProtectedStream> protected_streams,
ForwardErrorCorrection::Packet& fec_packet) const = 0;
protected:
FecHeaderWriter(size_t max_media_packets,

View File

@ -108,12 +108,14 @@ size_t UlpfecHeaderWriter::FecHeaderSize(size_t packet_mask_size) const {
}
void UlpfecHeaderWriter::FinalizeFecHeader(
uint32_t /* media_ssrc */,
uint16_t seq_num_base,
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const {
uint8_t* data = fec_packet->data.MutableData();
rtc::ArrayView<const ProtectedStream> protected_streams,
ForwardErrorCorrection::Packet& fec_packet) const {
RTC_CHECK_EQ(protected_streams.size(), 1);
uint16_t seq_num_base = protected_streams[0].seq_num_base;
const uint8_t* packet_mask = protected_streams[0].packet_mask.data();
size_t packet_mask_size = protected_streams[0].packet_mask.size();
uint8_t* data = fec_packet.data.MutableData();
// Set E bit to zero.
data[0] &= 0x7f;
// Set L bit based on packet mask size. (Note that the packet mask
@ -133,7 +135,7 @@ void UlpfecHeaderWriter::FinalizeFecHeader(
// required in general.)
const size_t fec_header_size = FecHeaderSize(packet_mask_size);
ByteWriter<uint16_t>::WriteBigEndian(
&data[10], fec_packet->data.size() - fec_header_size);
&data[10], fec_packet.data.size() - fec_header_size);
// Copy the packet mask.
memcpy(&data[12], packet_mask, packet_mask_size);
}

View File

@ -57,11 +57,8 @@ class UlpfecHeaderWriter : public FecHeaderWriter {
size_t FecHeaderSize(size_t packet_mask_row_size) const override;
void FinalizeFecHeader(
uint32_t media_ssrc, // Unused by ULPFEC.
uint16_t seq_num_base,
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const override;
rtc::ArrayView<const ProtectedStream> protected_streams,
ForwardErrorCorrection::Packet& fec_packet) const override;
};
} // namespace webrtc

View File

@ -59,8 +59,11 @@ std::unique_ptr<Packet> WriteHeader(const uint8_t* packet_mask,
for (size_t i = 0; i < written_packet->data.size(); ++i) {
data[i] = i; // Actual content doesn't matter.
}
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask,
packet_mask_size, written_packet.get());
const FecHeaderWriter::ProtectedStream protected_streams[] = {
{.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = {packet_mask, packet_mask_size}}};
writer.FinalizeFecHeader(protected_streams, *written_packet);
return written_packet;
}
@ -160,8 +163,11 @@ TEST(UlpfecHeaderWriterTest, FinalizesSmallHeader) {
}
UlpfecHeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(),
packet_mask_size, &written_packet);
const FecHeaderWriter::ProtectedStream protected_streams[] = {
{.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = {packet_mask.get(), packet_mask_size}}};
writer.FinalizeFecHeader(protected_streams, written_packet);
const uint8_t* packet = written_packet.data.cdata();
EXPECT_EQ(0x00, packet[0] & 0x80); // E bit.
@ -185,8 +191,11 @@ TEST(UlpfecHeaderWriterTest, FinalizesLargeHeader) {
}
UlpfecHeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(),
packet_mask_size, &written_packet);
const FecHeaderWriter::ProtectedStream protected_streams[] = {
{.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = {packet_mask.get(), packet_mask_size}}};
writer.FinalizeFecHeader(protected_streams, written_packet);
const uint8_t* packet = written_packet.data.cdata();
EXPECT_EQ(0x00, packet[0] & 0x80); // E bit.