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:
parent
cfa0f817b7
commit
bde7c6ad11
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user