diff --git a/modules/rtp_rtcp/source/flexfec_03_header_reader_writer.cc b/modules/rtp_rtcp/source/flexfec_03_header_reader_writer.cc index ddf8e32f85..cf4dc3e58e 100644 --- a/modules/rtp_rtcp/source/flexfec_03_header_reader_writer.cc +++ b/modules/rtp_rtcp/source/flexfec_03_header_reader_writer.cc @@ -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 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::WriteBigEndian(&data[8], kSsrcCount); diff --git a/modules/rtp_rtcp/source/flexfec_03_header_reader_writer.h b/modules/rtp_rtcp/source/flexfec_03_header_reader_writer.h index c5e965eb26..189561ed17 100644 --- a/modules/rtp_rtcp/source/flexfec_03_header_reader_writer.h +++ b/modules/rtp_rtcp/source/flexfec_03_header_reader_writer.h @@ -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 protected_streams, + ForwardErrorCorrection::Packet& fec_packet) const override; }; } // namespace webrtc diff --git a/modules/rtp_rtcp/source/flexfec_03_header_reader_writer_unittest.cc b/modules/rtp_rtcp/source/flexfec_03_header_reader_writer_unittest.cc index e58e1b4590..ad68de4525 100644 --- a/modules/rtp_rtcp/source/flexfec_03_header_reader_writer_unittest.cc +++ b/modules/rtp_rtcp/source/flexfec_03_header_reader_writer_unittest.cc @@ -85,8 +85,11 @@ rtc::scoped_refptr 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); diff --git a/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc b/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc index b6596824fc..0cdaa88cf3 100644 --- a/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc +++ b/modules/rtp_rtcp/source/flexfec_header_reader_writer.cc @@ -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 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::WriteBigEndian(&data[8], kSsrcCount); diff --git a/modules/rtp_rtcp/source/flexfec_header_reader_writer.h b/modules/rtp_rtcp/source/flexfec_header_reader_writer.h index a49702b210..81103821e7 100644 --- a/modules/rtp_rtcp/source/flexfec_header_reader_writer.h +++ b/modules/rtp_rtcp/source/flexfec_header_reader_writer.h @@ -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 protected_streams, + ForwardErrorCorrection::Packet& fec_packet) const override; }; } // namespace webrtc diff --git a/modules/rtp_rtcp/source/forward_error_correction.cc b/modules/rtp_rtcp/source/forward_error_correction.cc index 750c800757..ee99bb956a 100644 --- a/modules/rtp_rtcp/source/forward_error_correction.cc +++ b/modules/rtp_rtcp/source/forward_error_correction.cc @@ -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]); } } diff --git a/modules/rtp_rtcp/source/forward_error_correction.h b/modules/rtp_rtcp/source/forward_error_correction.h index 3da3e6b71a..ff6c4593f9 100644 --- a/modules/rtp_rtcp/source/forward_error_correction.h +++ b/modules/rtp_rtcp/source/forward_error_correction.h @@ -391,6 +391,12 @@ class FecHeaderReader { class FecHeaderWriter { public: + struct ProtectedStream { + uint32_t ssrc = 0; + uint16_t seq_num_base = 0; + rtc::ArrayView 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 protected_streams, + ForwardErrorCorrection::Packet& fec_packet) const = 0; protected: FecHeaderWriter(size_t max_media_packets, diff --git a/modules/rtp_rtcp/source/ulpfec_header_reader_writer.cc b/modules/rtp_rtcp/source/ulpfec_header_reader_writer.cc index e93d7f0e31..f57f31115c 100644 --- a/modules/rtp_rtcp/source/ulpfec_header_reader_writer.cc +++ b/modules/rtp_rtcp/source/ulpfec_header_reader_writer.cc @@ -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 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::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); } diff --git a/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h b/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h index a8bb737dbb..1d823b937a 100644 --- a/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h +++ b/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h @@ -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 protected_streams, + ForwardErrorCorrection::Packet& fec_packet) const override; }; } // namespace webrtc diff --git a/modules/rtp_rtcp/source/ulpfec_header_reader_writer_unittest.cc b/modules/rtp_rtcp/source/ulpfec_header_reader_writer_unittest.cc index 89581ee960..f0b78e8d87 100644 --- a/modules/rtp_rtcp/source/ulpfec_header_reader_writer_unittest.cc +++ b/modules/rtp_rtcp/source/ulpfec_header_reader_writer_unittest.cc @@ -59,8 +59,11 @@ std::unique_ptr 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.