Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Unified Diff: webrtc/modules/rtp_rtcp/source/forward_error_correction.h

Issue 2260803002: Generalize FEC header formatting. (pt. 4) (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Lint fix. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/rtp_rtcp/source/forward_error_correction.h
diff --git a/webrtc/modules/rtp_rtcp/source/forward_error_correction.h b/webrtc/modules/rtp_rtcp/source/forward_error_correction.h
index 21f2afb2c00ec35e6129ee216737939a40630889..a0600f05bf5863f6c272596d20a3548dbbb216f3 100644
--- a/webrtc/modules/rtp_rtcp/source/forward_error_correction.h
+++ b/webrtc/modules/rtp_rtcp/source/forward_error_correction.h
@@ -17,31 +17,32 @@
#include <memory>
#include <vector>
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/constructormagic.h"
#include "webrtc/base/refcount.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h"
-#include "webrtc/typedefs.h"
namespace webrtc {
+class FecHeaderReader;
+class FecHeaderWriter;
+
// Performs codec-independent forward error correction (FEC), based on RFC 5109.
// Option exists to enable unequal protection (UEP) across packets.
// This is not to be confused with protection within packets
// (referred to as uneven level protection (ULP) in RFC 5109).
class ForwardErrorCorrection {
public:
- // Maximum number of media packets we can protect
- static constexpr size_t kMaxMediaPackets = 48u;
-
// TODO(holmer): As a next step all these struct-like packet classes should be
// refactored into proper classes, and their members should be made private.
// This will require parts of the functionality in forward_error_correction.cc
// and receiver_fec.cc to be refactored into the packet classes.
class Packet {
public:
- Packet() : length(0), data(), ref_count_(0) {}
- virtual ~Packet() {}
+ Packet();
+ virtual ~Packet();
// Add a reference.
virtual int32_t AddRef();
@@ -89,7 +90,7 @@ class ForwardErrorCorrection {
rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage.
};
- // The recovered list parameter of #DecodeFec() references structs of
+ // The recovered list parameter of DecodeFec() references structs of
// this type.
// TODO(holmer): Refactor into a proper class.
class RecoveredPacket : public SortablePacket {
@@ -102,19 +103,55 @@ class ForwardErrorCorrection {
// through the received packet list.
bool returned; // True when the packet already has been returned to the
// caller through the callback.
- uint8_t length_recovery[2]; // Two bytes used for recovering the packet
- // length with XOR operations.
rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage.
};
+ // Used to link media packets to their protecting FEC packets.
+ //
+ // TODO(holmer): Refactor into a proper class.
+ class ProtectedPacket : public ForwardErrorCorrection::SortablePacket {
+ public:
+ ProtectedPacket();
+ ~ProtectedPacket();
+
+ rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
+ };
+
+ using ProtectedPacketList = std::list<std::unique_ptr<ProtectedPacket>>;
+
+ // Used for internal storage of received FEC packets in a list.
+ //
+ // TODO(holmer): Refactor into a proper class.
+ class ReceivedFecPacket : public ForwardErrorCorrection::SortablePacket {
+ public:
+ ReceivedFecPacket();
+ ~ReceivedFecPacket();
+
+ // List of media packets that this FEC packet protects.
+ ProtectedPacketList protected_packets;
+ // RTP header fields.
+ uint32_t ssrc;
+ // FEC header fields.
+ size_t fec_header_size;
+ uint32_t protected_ssrc;
+ uint16_t seq_num_base;
+ size_t packet_mask_offset; // Relative start of FEC header.
+ size_t packet_mask_size;
+ size_t protection_length;
+ // Raw data.
+ rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
+ };
+
using PacketList = std::list<std::unique_ptr<Packet>>;
using ReceivedPacketList = std::list<std::unique_ptr<ReceivedPacket>>;
using RecoveredPacketList = std::list<std::unique_ptr<RecoveredPacket>>;
+ using ReceivedFecPacketList = std::list<std::unique_ptr<ReceivedFecPacket>>;
- ForwardErrorCorrection();
- virtual ~ForwardErrorCorrection();
+ ~ForwardErrorCorrection();
+
+ // Creates a ForwardErrorCorrection tailored for a specific FEC scheme.
+ static std::unique_ptr<ForwardErrorCorrection> CreateUlpfec();
- //
// Generates a list of FEC packets from supplied media packets.
//
// Input: media_packets List of media packets to protect, of type
@@ -158,7 +195,6 @@ class ForwardErrorCorrection {
FecMaskType fec_mask_type,
std::list<Packet*>* fec_packets);
- //
// Decodes a list of received media and FEC packets. It will parse the
// |received_packets|, storing FEC packets internally, and move
// media packets to |recovered_packets|. The recovered list will be
@@ -198,47 +234,32 @@ class ForwardErrorCorrection {
// Frees all memory allocated by this class.
void ResetState(RecoveredPacketList* recovered_packets);
- private:
- // Used to link media packets to their protecting FEC packets.
- //
- // TODO(holmer): Refactor into a proper class.
- class ProtectedPacket : public ForwardErrorCorrection::SortablePacket {
- public:
- rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
- };
-
- using ProtectedPacketList = std::list<std::unique_ptr<ProtectedPacket>>;
-
- // Used for internal storage of received FEC packets in a list.
- //
- // TODO(holmer): Refactor into a proper class.
- class ReceivedFecPacket : public ForwardErrorCorrection::SortablePacket {
- public:
- ProtectedPacketList protected_packets;
- uint32_t ssrc; // SSRC of the current frame.
- rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
- };
+ // TODO(brandtr): Remove these functions when the Packet classes
+ // have been refactored.
+ static uint16_t ParseSequenceNumber(uint8_t* packet);
+ static uint32_t ParseSsrc(uint8_t* packet);
- using ReceivedFecPacketList = std::list<std::unique_ptr<ReceivedFecPacket>>;
+ protected:
+ ForwardErrorCorrection(std::unique_ptr<FecHeaderReader> fec_header_reader,
+ std::unique_ptr<FecHeaderWriter> fec_header_writer);
+ private:
// Analyzes |media_packets| for holes in the sequence and inserts zero columns
// into the |packet_mask| where those holes are found. Zero columns means that
// those packets will have no protection.
// Returns the number of bits used for one row of the new packet mask.
// Requires that |packet_mask| has at least 6 * |num_fec_packets| bytes
// allocated.
- int InsertZerosInBitMasks(const PacketList& media_packets,
- uint8_t* packet_mask, int num_mask_bytes,
- int num_fec_packets);
-
+ int InsertZerosInPacketMasks(const PacketList& media_packets,
+ size_t num_fec_packets);
- void GenerateFecUlpHeaders(const PacketList& media_packets,
- uint8_t* packet_mask, int num_fec_packets,
- bool l_bit);
+ // Writes FEC payloads and some recovery fields in the FEC headers.
+ void GenerateFecPayloads(const PacketList& media_packets,
+ size_t num_fec_packets);
- void GenerateFecBitStrings(const PacketList& media_packets,
- uint8_t* packet_mask, int num_fec_packets,
- bool l_bit);
+ // Writes the FEC header fields that are not written by GenerateFecPayloads.
+ // This includes writing the packet masks.
+ void FinalizeFecHeaders(size_t num_fec_packets, uint16_t seq_num_base);
// Inserts the |received_packets| into the internal received FEC packet list
// or into |recovered_packets|.
@@ -246,67 +267,145 @@ class ForwardErrorCorrection {
RecoveredPacketList* recovered_packets);
// Inserts the |received_packet| into |recovered_packets|. Deletes duplicates.
- void InsertMediaPacket(ReceivedPacket* received_packet,
- RecoveredPacketList* recovered_packets);
+ void InsertMediaPacket(RecoveredPacketList* recovered_packets,
+ ReceivedPacket* received_packet);
// Assigns pointers to the recovered packet from all FEC packets which cover
// it.
// Note: This reduces the complexity when we want to try to recover a packet
// since we don't have to find the intersection between recovered packets and
// packets covered by the FEC packet.
- void UpdateCoveringFecPackets(RecoveredPacket* packet);
+ void UpdateCoveringFecPackets(const RecoveredPacket& packet);
// Insert |received_packet| into internal FEC list. Deletes duplicates.
- void InsertFecPacket(ReceivedPacket* received_packet,
- const RecoveredPacketList* recovered_packets);
+ void InsertFecPacket(const RecoveredPacketList& recovered_packets,
+ ReceivedPacket* received_packet);
// Assigns pointers to already recovered packets covered by |fec_packet|.
static void AssignRecoveredPackets(
- ReceivedFecPacket* fec_packet,
- const RecoveredPacketList* recovered_packets);
-
- // Insert |rec_packet_to_insert| into |recovered_packets| in correct position.
- void InsertRecoveredPacket(RecoveredPacket* rec_packet_to_insert,
- RecoveredPacketList* recovered_packets);
+ const RecoveredPacketList& recovered_packets,
+ ReceivedFecPacket* fec_packet);
// Attempt to recover missing packets, using the internally stored
// received FEC packets.
- void AttemptRecover(RecoveredPacketList* recovered_packets);
+ void AttemptRecovery(RecoveredPacketList* recovered_packets);
- // Initializes packet recovery using the received |fec_packet|.
- static bool StartPacketRecovery(const ReceivedFecPacket* fec_packet,
+ // Initializes headers and payload before the XOR operation
+ // that recovers a packet.
+ static bool StartPacketRecovery(const ReceivedFecPacket& fec_packet,
RecoveredPacket* recovered_packet);
- // Performs XOR between |src| and |dst| and stores the result in |dst|.
- static void XorPackets(const Packet* src, RecoveredPacket* dst);
+ // Performs XOR between the first 8 bytes of |src| and |dst| and stores
+ // the result in |dst|. The 3rd and 4th bytes are used for storing
+ // the length recovery field.
+ static void XorHeaders(const Packet& src, Packet* dst);
+
+ // Performs XOR between the payloads of |src| and |dst| and stores the result
+ // in |dst|. The parameter |dst_offset| determines at what byte the
+ // XOR operation starts in |dst|. In total, |payload_length| bytes are XORed.
+ static void XorPayloads(const Packet& src,
+ size_t payload_length,
+ size_t dst_offset,
+ Packet* dst);
- // Finish up the recovery of a packet.
- static bool FinishPacketRecovery(RecoveredPacket* recovered_packet);
+ // Finalizes recovery of packet by setting RTP header fields.
+ // This is not specific to the FEC scheme used.
+ static bool FinishPacketRecovery(const ReceivedFecPacket& fec_packet,
+ RecoveredPacket* recovered_packet);
// Recover a missing packet.
- bool RecoverPacket(const ReceivedFecPacket* fec_packet,
- RecoveredPacket* rec_packet_to_insert);
+ static bool RecoverPacket(const ReceivedFecPacket& fec_packet,
+ RecoveredPacket* recovered_packet);
// Get the number of missing media packets which are covered by |fec_packet|.
// An FEC packet can recover at most one packet, and if zero packets are
// missing the FEC packet can be discarded. This function returns 2 when two
// or more packets are missing.
- static int NumCoveredPacketsMissing(const ReceivedFecPacket* fec_packet);
+ static int NumCoveredPacketsMissing(const ReceivedFecPacket& fec_packet);
// Discards old packets in |recovered_packets|, which are no longer relevant
// for recovering lost packets.
- static void DiscardOldRecoveredPackets(
- RecoveredPacketList* recovered_packets);
- static uint16_t ParseSequenceNumber(uint8_t* packet);
+ void DiscardOldRecoveredPackets(RecoveredPacketList* recovered_packets);
+
+ std::unique_ptr<FecHeaderReader> fec_header_reader_;
+ std::unique_ptr<FecHeaderWriter> fec_header_writer_;
std::vector<Packet> generated_fec_packets_;
ReceivedFecPacketList received_fec_packets_;
// Arrays used to avoid dynamically allocating memory when generating
- // the packet masks in the ULPFEC headers.
- // (There are never more than |kMaxMediaPackets| FEC packets generated.)
- uint8_t packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet];
- uint8_t tmp_packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet];
+ // the packet masks.
+ // (There are never more than |kUlpfecMaxMediaPackets| FEC packets generated.)
+ uint8_t packet_masks_[kUlpfecMaxMediaPackets * kUlpfecMaxPacketMaskSize];
+ uint8_t tmp_packet_masks_[kUlpfecMaxMediaPackets * kUlpfecMaxPacketMaskSize];
+ size_t packet_mask_size_;
};
+
+// Classes derived from FecHeader{Reader,Writer} encapsulate the
+// specifics of reading and writing FEC header for, e.g., ULPFEC
+// and FlexFEC.
+class FecHeaderReader {
+ public:
+ virtual ~FecHeaderReader();
+
+ // The maximum number of media packets that can be covered by one FEC packet.
+ size_t MaxMediaPackets() const;
+
+ // The maximum number of FEC packets that is supported, per call
+ // to ForwardErrorCorrection::EncodeFec().
+ size_t MaxFecPackets() const;
+
+ // Parses FEC header and stores information in ReceivedFecPacket members.
+ virtual bool ReadFecHeader(
+ ForwardErrorCorrection::ReceivedFecPacket* fec_packet) const = 0;
+
+ protected:
+ FecHeaderReader(size_t max_media_packets, size_t max_fec_packets);
+
+ const size_t max_media_packets_;
+ const size_t max_fec_packets_;
+};
+
+class FecHeaderWriter {
+ public:
+ virtual ~FecHeaderWriter();
+
+ // The maximum number of media packets that can be covered by one FEC packet.
+ size_t MaxMediaPackets() const;
+
+ // The maximum number of FEC packets that is supported, per call
+ // to ForwardErrorCorrection::EncodeFec().
+ size_t MaxFecPackets() const;
+
+ // The maximum overhead (in bytes) per packet, due to FEC headers.
+ size_t MaxPacketOverhead() const;
+
+ // Calculates the minimum packet mask size needed (in bytes),
+ // given the discrete options of the ULPFEC masks and the bits
+ // set in the current packet mask.
+ virtual size_t MinPacketMaskSize(const uint8_t* packet_mask,
+ size_t packet_mask_size) const = 0;
+
+ // The header size (in bytes), given the packet mask size.
+ virtual size_t FecHeaderSize(size_t packet_mask_size) const = 0;
+
+ // Writes FEC header.
+ virtual void FinalizeFecHeader(
+ uint16_t seq_num_base,
+ const uint8_t* packet_mask,
+ size_t packet_mask_size,
+ ForwardErrorCorrection::Packet* fec_packet) const = 0;
+
+ protected:
+ FecHeaderWriter(size_t max_media_packets,
+ size_t max_fec_packets,
+ size_t max_packet_overhead);
+
+ const size_t max_media_packets_;
+ const size_t max_fec_packets_;
+ const size_t max_packet_overhead_;
+};
+
} // namespace webrtc
+
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_
« no previous file with comments | « webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc ('k') | webrtc/modules/rtp_rtcp/source/forward_error_correction.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698