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 // FlexFEC header standard. Note that the header size is computed by
// FecHeaderSize(), so in this function we can be sure that we are // FecHeaderSize(), so in this function we can be sure that we are
// writing in space that is intended for the header. // 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( void Flexfec03HeaderWriter::FinalizeFecHeader(
uint32_t media_ssrc, rtc::ArrayView<const ProtectedStream> protected_streams,
uint16_t seq_num_base, ForwardErrorCorrection::Packet& fec_packet) const {
const uint8_t* packet_mask, RTC_CHECK_EQ(protected_streams.size(), 1);
size_t packet_mask_size, uint32_t media_ssrc = protected_streams[0].ssrc;
ForwardErrorCorrection::Packet* fec_packet) const { uint16_t seq_num_base = protected_streams[0].seq_num_base;
uint8_t* data = fec_packet->data.MutableData(); 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] &= 0x7f; // Clear R bit.
data[0] &= 0xbf; // Clear F bit. data[0] &= 0xbf; // Clear F bit.
ByteWriter<uint8_t>::WriteBigEndian(&data[8], kSsrcCount); 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; size_t FecHeaderSize(size_t packet_mask_row_size) const override;
void FinalizeFecHeader( void FinalizeFecHeader(
uint32_t media_ssrc, rtc::ArrayView<const ProtectedStream> protected_streams,
uint16_t seq_num_base, ForwardErrorCorrection::Packet& fec_packet) const override;
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const override;
}; };
} // namespace webrtc } // 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) { for (size_t i = 0; i < written_packet->data.size(); ++i) {
data[i] = i; // Actual content doesn't matter. data[i] = i; // Actual content doesn't matter.
} }
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask, const FecHeaderWriter::ProtectedStream protected_streams[] = {
packet_mask_size, written_packet.get()); {.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = {packet_mask, packet_mask_size}}};
writer.FinalizeFecHeader(protected_streams, *written_packet);
return written_packet; return written_packet;
} }
@ -339,8 +342,11 @@ TEST(Flexfec03HeaderWriterTest, FinalizesHeaderWithKBit0Set) {
} }
Flexfec03HeaderWriter writer; Flexfec03HeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask, const FecHeaderWriter::ProtectedStream protected_streams[] = {
sizeof(kUlpfecPacketMask), &written_packet); {.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = kUlpfecPacketMask}};
writer.FinalizeFecHeader(protected_streams, written_packet);
VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize, VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
written_packet); written_packet);
@ -358,8 +364,11 @@ TEST(Flexfec03HeaderWriterTest, FinalizesHeaderWithKBit1Set) {
} }
Flexfec03HeaderWriter writer; Flexfec03HeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask, const FecHeaderWriter::ProtectedStream protected_streams[] = {
sizeof(kUlpfecPacketMask), &written_packet); {.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = kUlpfecPacketMask}};
writer.FinalizeFecHeader(protected_streams, written_packet);
VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize, VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
written_packet); written_packet);
@ -381,8 +390,11 @@ TEST(Flexfec03HeaderWriterTest, FinalizesHeaderWithKBit2Set) {
} }
Flexfec03HeaderWriter writer; Flexfec03HeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, kUlpfecPacketMask, const FecHeaderWriter::ProtectedStream protected_streams[] = {
sizeof(kUlpfecPacketMask), &written_packet); {.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = kUlpfecPacketMask}};
writer.FinalizeFecHeader(protected_streams, written_packet);
VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize, VerifyFinalizedHeaders(kFlexfecPacketMask, kExpectedPacketMaskSize,
written_packet); 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, // TODO(brandtr): Update this function when we support offset-based masks,
// retransmissions, and protecting multiple SSRCs. // retransmissions, and protecting multiple SSRCs.
void FlexfecHeaderWriter::FinalizeFecHeader( void FlexfecHeaderWriter::FinalizeFecHeader(
uint32_t media_ssrc, rtc::ArrayView<const ProtectedStream> protected_streams,
uint16_t seq_num_base, ForwardErrorCorrection::Packet& fec_packet) const {
const uint8_t* packet_mask, // TODO(bugs.webrtc.org/15002): Iterate over all streams and update FlexFEC
size_t packet_mask_size, // header accordingly.
ForwardErrorCorrection::Packet* fec_packet) const { RTC_CHECK_EQ(protected_streams.size(), 1);
uint8_t* data = fec_packet->data.MutableData(); 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] &= 0x7f; // Clear R bit.
data[0] &= 0xbf; // Clear F bit. data[0] &= 0xbf; // Clear F bit.
ByteWriter<uint8_t>::WriteBigEndian(&data[8], kSsrcCount); 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; size_t FecHeaderSize(size_t packet_mask_row_size) const override;
void FinalizeFecHeader( void FinalizeFecHeader(
uint32_t media_ssrc, rtc::ArrayView<const ProtectedStream> protected_streams,
uint16_t seq_num_base, ForwardErrorCorrection::Packet& fec_packet) const override;
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const override;
}; };
} // namespace webrtc } // namespace webrtc

View File

@ -328,9 +328,13 @@ void ForwardErrorCorrection::FinalizeFecHeaders(size_t num_fec_packets,
uint32_t media_ssrc, uint32_t media_ssrc,
uint16_t seq_num_base) { uint16_t seq_num_base) {
for (size_t i = 0; i < num_fec_packets; ++i) { for (size_t i = 0; i < num_fec_packets; ++i) {
fec_header_writer_->FinalizeFecHeader( const FecHeaderWriter::ProtectedStream protected_streams[] = {
media_ssrc, seq_num_base, &packet_masks_[i * packet_mask_size_], {.ssrc = media_ssrc,
packet_mask_size_, &generated_fec_packets_[i]); .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 { class FecHeaderWriter {
public: public:
struct ProtectedStream {
uint32_t ssrc = 0;
uint16_t seq_num_base = 0;
rtc::ArrayView<const uint8_t> packet_mask;
};
virtual ~FecHeaderWriter(); virtual ~FecHeaderWriter();
// The maximum number of media packets that can be covered by one FEC packet. // The maximum number of media packets that can be covered by one FEC packet.
@ -414,11 +420,8 @@ class FecHeaderWriter {
// Writes FEC header. // Writes FEC header.
virtual void FinalizeFecHeader( virtual void FinalizeFecHeader(
uint32_t media_ssrc, rtc::ArrayView<const ProtectedStream> protected_streams,
uint16_t seq_num_base, ForwardErrorCorrection::Packet& fec_packet) const = 0;
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const = 0;
protected: protected:
FecHeaderWriter(size_t max_media_packets, 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( void UlpfecHeaderWriter::FinalizeFecHeader(
uint32_t /* media_ssrc */, rtc::ArrayView<const ProtectedStream> protected_streams,
uint16_t seq_num_base, ForwardErrorCorrection::Packet& fec_packet) const {
const uint8_t* packet_mask, RTC_CHECK_EQ(protected_streams.size(), 1);
size_t packet_mask_size, uint16_t seq_num_base = protected_streams[0].seq_num_base;
ForwardErrorCorrection::Packet* fec_packet) const { const uint8_t* packet_mask = protected_streams[0].packet_mask.data();
uint8_t* data = fec_packet->data.MutableData(); size_t packet_mask_size = protected_streams[0].packet_mask.size();
uint8_t* data = fec_packet.data.MutableData();
// Set E bit to zero. // Set E bit to zero.
data[0] &= 0x7f; data[0] &= 0x7f;
// Set L bit based on packet mask size. (Note that the packet mask // Set L bit based on packet mask size. (Note that the packet mask
@ -133,7 +135,7 @@ void UlpfecHeaderWriter::FinalizeFecHeader(
// required in general.) // required in general.)
const size_t fec_header_size = FecHeaderSize(packet_mask_size); const size_t fec_header_size = FecHeaderSize(packet_mask_size);
ByteWriter<uint16_t>::WriteBigEndian( 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. // Copy the packet mask.
memcpy(&data[12], packet_mask, packet_mask_size); 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; size_t FecHeaderSize(size_t packet_mask_row_size) const override;
void FinalizeFecHeader( void FinalizeFecHeader(
uint32_t media_ssrc, // Unused by ULPFEC. rtc::ArrayView<const ProtectedStream> protected_streams,
uint16_t seq_num_base, ForwardErrorCorrection::Packet& fec_packet) const override;
const uint8_t* packet_mask,
size_t packet_mask_size,
ForwardErrorCorrection::Packet* fec_packet) const override;
}; };
} // namespace webrtc } // 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) { for (size_t i = 0; i < written_packet->data.size(); ++i) {
data[i] = i; // Actual content doesn't matter. data[i] = i; // Actual content doesn't matter.
} }
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask, const FecHeaderWriter::ProtectedStream protected_streams[] = {
packet_mask_size, written_packet.get()); {.ssrc = kMediaSsrc,
.seq_num_base = kMediaStartSeqNum,
.packet_mask = {packet_mask, packet_mask_size}}};
writer.FinalizeFecHeader(protected_streams, *written_packet);
return written_packet; return written_packet;
} }
@ -160,8 +163,11 @@ TEST(UlpfecHeaderWriterTest, FinalizesSmallHeader) {
} }
UlpfecHeaderWriter writer; UlpfecHeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(), const FecHeaderWriter::ProtectedStream protected_streams[] = {
packet_mask_size, &written_packet); {.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(); const uint8_t* packet = written_packet.data.cdata();
EXPECT_EQ(0x00, packet[0] & 0x80); // E bit. EXPECT_EQ(0x00, packet[0] & 0x80); // E bit.
@ -185,8 +191,11 @@ TEST(UlpfecHeaderWriterTest, FinalizesLargeHeader) {
} }
UlpfecHeaderWriter writer; UlpfecHeaderWriter writer;
writer.FinalizeFecHeader(kMediaSsrc, kMediaStartSeqNum, packet_mask.get(), const FecHeaderWriter::ProtectedStream protected_streams[] = {
packet_mask_size, &written_packet); {.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(); const uint8_t* packet = written_packet.data.cdata();
EXPECT_EQ(0x00, packet[0] & 0x80); // E bit. EXPECT_EQ(0x00, packet[0] & 0x80); // E bit.