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

Side by Side 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: Created 4 years, 4 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ 11 #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_
12 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ 12 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_
13 13
14 #include <stdint.h> 14 #include <stdint.h>
15 15
16 #include <list> 16 #include <list>
17 #include <map>
17 #include <memory> 18 #include <memory>
19 #include <tuple>
18 #include <vector> 20 #include <vector>
19 21
22 #include "webrtc/base/basictypes.h"
23 #include "webrtc/base/constructormagic.h"
20 #include "webrtc/base/refcount.h" 24 #include "webrtc/base/refcount.h"
21 #include "webrtc/base/scoped_ref_ptr.h" 25 #include "webrtc/base/scoped_ref_ptr.h"
22 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 26 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
23 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h" 27 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h"
24 #include "webrtc/typedefs.h"
25 28
26 namespace webrtc { 29 namespace webrtc {
27 30
31 class FecHeaderReader;
32 class FecHeaderWriter;
33
28 // Performs codec-independent forward error correction (FEC), based on RFC 5109. 34 // Performs codec-independent forward error correction (FEC), based on RFC 5109.
29 // Option exists to enable unequal protection (UEP) across packets. 35 // Option exists to enable unequal protection (UEP) across packets.
30 // This is not to be confused with protection within packets 36 // This is not to be confused with protection within packets
31 // (referred to as uneven level protection (ULP) in RFC 5109). 37 // (referred to as uneven level protection (ULP) in RFC 5109).
32 class ForwardErrorCorrection { 38 class ForwardErrorCorrection {
33 public: 39 public:
34 // Maximum number of media packets we can protect
35 static constexpr size_t kMaxMediaPackets = 48u;
36
37 // TODO(holmer): As a next step all these struct-like packet classes should be 40 // TODO(holmer): As a next step all these struct-like packet classes should be
38 // refactored into proper classes, and their members should be made private. 41 // refactored into proper classes, and their members should be made private.
39 // This will require parts of the functionality in forward_error_correction.cc 42 // This will require parts of the functionality in forward_error_correction.cc
40 // and receiver_fec.cc to be refactored into the packet classes. 43 // and receiver_fec.cc to be refactored into the packet classes.
41 class Packet { 44 class Packet {
42 public: 45 public:
43 Packet() : length(0), data(), ref_count_(0) {} 46 Packet() : length(0), data(), ref_count_(0) {}
44 virtual ~Packet() {} 47 virtual ~Packet() {}
45 48
46 // Add a reference. 49 // Add a reference.
(...skipping 25 matching lines...) Expand all
72 75
73 // The received list parameter of DecodeFec() references structs of this type. 76 // The received list parameter of DecodeFec() references structs of this type.
74 // 77 //
75 // The ssrc member is needed to ensure that we can restore the SSRC field of 78 // The ssrc member is needed to ensure that we can restore the SSRC field of
76 // recovered packets. In most situations this could be retrieved from other 79 // recovered packets. In most situations this could be retrieved from other
77 // media packets, but in the case of an FEC packet protecting a single 80 // media packets, but in the case of an FEC packet protecting a single
78 // missing media packet, we have no other means of obtaining it. 81 // missing media packet, we have no other means of obtaining it.
79 // TODO(holmer): Refactor into a proper class. 82 // TODO(holmer): Refactor into a proper class.
80 class ReceivedPacket : public SortablePacket { 83 class ReceivedPacket : public SortablePacket {
81 public: 84 public:
82 ReceivedPacket();
83 ~ReceivedPacket();
84
85 uint32_t ssrc; // SSRC of the current frame. Must be set for FEC 85 uint32_t ssrc; // SSRC of the current frame. Must be set for FEC
86 // packets, but not required for media packets. 86 // packets, but not required for media packets.
87 bool is_fec; // Set to true if this is an FEC packet and false 87 bool is_fec; // Set to true if this is an FEC packet and false
88 // otherwise. 88 // otherwise.
89 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage. 89 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage.
90 }; 90 };
91 91
92 // The recovered list parameter of #DecodeFec() references structs of 92 // The recovered list parameter of DecodeFec() references structs of
93 // this type. 93 // this type.
94 // TODO(holmer): Refactor into a proper class. 94 // TODO(holmer): Refactor into a proper class.
95 class RecoveredPacket : public SortablePacket { 95 class RecoveredPacket : public SortablePacket {
96 public: 96 public:
97 RecoveredPacket();
98 ~RecoveredPacket();
99
100 bool was_recovered; // Will be true if this packet was recovered by 97 bool was_recovered; // Will be true if this packet was recovered by
101 // the FEC. Otherwise it was a media packet passed in 98 // the FEC. Otherwise it was a media packet passed in
102 // through the received packet list. 99 // through the received packet list.
103 bool returned; // True when the packet already has been returned to the 100 bool returned; // True when the packet already has been returned to the
104 // caller through the callback. 101 // caller through the callback.
105 uint8_t length_recovery[2]; // Two bytes used for recovering the packet
106 // length with XOR operations.
107 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage. 102 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage.
108 }; 103 };
109 104
105 // Used to link media packets to their protecting FEC packets.
106 //
107 // TODO(holmer): Refactor into a proper class.
108 class ProtectedPacket : public ForwardErrorCorrection::SortablePacket {
danilchap 2016/08/22 13:00:41 any reason to have ProtectedPacket in the public s
brandtr 2016/08/23 08:19:11 I think so, since it is used in the public interfa
109 public:
110 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
111 };
112
113 using ProtectedPacketList = std::list<std::unique_ptr<ProtectedPacket>>;
114
115 // Used for internal storage of received FEC packets in a list.
116 //
117 // TODO(holmer): Refactor into a proper class.
118 class ReceivedFecPacket : public ForwardErrorCorrection::SortablePacket {
119 public:
120 ProtectedPacketList protected_packets;
121 // RTP header fields.
122 uint32_t rtp_ssrc;
123 // FEC header fields.
124 size_t fec_header_size;
125 size_t protection_length;
126 // Packet masks metadata.
127 // SSRC -> [SN base, packet mask offset, packet mask size (bytes)]
128 std::map<uint32_t, std::tuple<uint16_t, size_t, size_t>> packet_mask_info;
129 // Raw data.
130 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
131 };
132
110 using PacketList = std::list<std::unique_ptr<Packet>>; 133 using PacketList = std::list<std::unique_ptr<Packet>>;
111 using ReceivedPacketList = std::list<std::unique_ptr<ReceivedPacket>>; 134 using ReceivedPacketList = std::list<std::unique_ptr<ReceivedPacket>>;
112 using RecoveredPacketList = std::list<std::unique_ptr<RecoveredPacket>>; 135 using RecoveredPacketList = std::list<std::unique_ptr<RecoveredPacket>>;
136 using ReceivedFecPacketList = std::list<std::unique_ptr<ReceivedFecPacket>>;
113 137
114 ForwardErrorCorrection(); 138 // Moveable but not copyable.
115 virtual ~ForwardErrorCorrection(); 139 RTC_DISALLOW_COPY_AND_ASSIGN(ForwardErrorCorrection);
danilchap 2016/08/22 13:00:41 this line should always be the last in the class d
brandtr 2016/08/23 08:19:11 Done, see https://codereview.webrtc.org/2260803002
140 ForwardErrorCorrection(ForwardErrorCorrection&&) = default;
116 141
117 // 142 // Creates a ForwardErrorCorrection tailored for a specific FEC scheme.
143 static ForwardErrorCorrection CreateUlpfec();
danilchap 2016/08/22 13:00:41 ForwardErrorCorrection is not a small class to ret
brandtr 2016/08/23 08:19:11 Right, but since ForwardErrorCorrection is neither
brandtr 2016/08/23 11:17:47 Reimplemented to use std::unique_ptr's.
144 static ForwardErrorCorrection CreateFlexfec();
145
118 // Generates a list of FEC packets from supplied media packets. 146 // Generates a list of FEC packets from supplied media packets.
119 // 147 //
120 // Input: media_packets List of media packets to protect, of type 148 // Input: media_packets List of media packets to protect, of type
121 // Packet. All packets must belong to the 149 // Packet. All packets must belong to the
122 // same frame and the list must not be empty. 150 // same frame and the list must not be empty.
123 // Input: protection_factor FEC protection overhead in the [0, 255] 151 // Input: protection_factor FEC protection overhead in the [0, 255]
124 // domain. To obtain 100% overhead, or an 152 // domain. To obtain 100% overhead, or an
125 // equal number of FEC packets as 153 // equal number of FEC packets as
126 // media packets, use 255. 154 // media packets, use 255.
127 // Input: num_important_packets The number of "important" packets in the 155 // Input: num_important_packets The number of "important" packets in the
(...skipping 12 matching lines...) Expand all
140 // Input: fec_mask_type The type of packet mask used in the FEC. 168 // Input: fec_mask_type The type of packet mask used in the FEC.
141 // Random or bursty type may be selected. The 169 // Random or bursty type may be selected. The
142 // bursty type is only defined up to 12 media 170 // bursty type is only defined up to 12 media
143 // packets. If the number of media packets is 171 // packets. If the number of media packets is
144 // above 12, the packet masks from the random 172 // above 12, the packet masks from the random
145 // table will be selected. 173 // table will be selected.
146 // Output: fec_packets List of pointers to generated FEC packets, 174 // Output: fec_packets List of pointers to generated FEC packets,
147 // of type Packet. Must be empty on entry. 175 // of type Packet. Must be empty on entry.
148 // The memory available through the list will 176 // The memory available through the list will
149 // be valid until the next call to 177 // be valid until the next call to
150 // GenerateFec(). 178 // EncodeFec().
151 // 179 //
152 // Returns 0 on success, -1 on failure. 180 // Returns 0 on success, -1 on failure.
153 // 181 //
154 int GenerateFec(const PacketList& media_packets, 182 int EncodeFec(const PacketList& media_packets,
155 uint8_t protection_factor, int num_important_packets, 183 uint8_t protection_factor,
156 bool use_unequal_protection, FecMaskType fec_mask_type, 184 int num_important_packets,
157 std::list<Packet*>* fec_packets); 185 bool use_unequal_protection,
186 FecMaskType fec_mask_type,
187 std::list<Packet*>* fec_packets);
158 188
159 //
160 // Decodes a list of received media and FEC packets. It will parse the 189 // Decodes a list of received media and FEC packets. It will parse the
161 // |received_packets|, storing FEC packets internally, and move 190 // |received_packets|, storing FEC packets internally, and move
162 // media packets to |recovered_packets|. The recovered list will be 191 // media packets to |recovered_packets|. The recovered list will be
163 // sorted by ascending sequence number and have duplicates removed. 192 // sorted by ascending sequence number and have duplicates removed.
164 // The function should be called as new packets arrive, and 193 // The function should be called as new packets arrive, and
165 // |recovered_packets| will be progressively assembled with each call. 194 // |recovered_packets| will be progressively assembled with each call.
166 // When the function returns, |received_packets| will be empty. 195 // When the function returns, |received_packets| will be empty.
167 // 196 //
168 // The caller will allocate packets submitted through |received_packets|. 197 // The caller will allocate packets submitted through |received_packets|.
169 // The function will handle allocation of recovered packets. 198 // The function will handle allocation of recovered packets.
170 // 199 //
171 // Input: received_packets List of new received packets, of type 200 // Input: received_packets List of new received packets, of type
172 // ReceivedPacket, belonging to a single 201 // ReceivedPacket, belonging to a single
173 // frame. At output the list will be empty, 202 // frame. At output the list will be empty,
174 // with packets either stored internally, 203 // with packets either stored internally,
175 // or accessible through the recovered list. 204 // or accessible through the recovered list.
176 // Output: recovered_packets List of recovered media packets, of type 205 // Output: recovered_packets List of recovered media packets, of type
177 // RecoveredPacket, belonging to a single 206 // RecoveredPacket, belonging to a single
178 // frame. The memory available through the 207 // frame. The memory available through the
179 // list will be valid until the next call to 208 // list will be valid until the next call to
180 // DecodeFec(). 209 // DecodeFec().
181 // 210 //
182 // Returns 0 on success, -1 on failure. 211 // Returns 0 on success, -1 on failure.
183 // 212 //
184 int DecodeFec(ReceivedPacketList* received_packets, 213 int DecodeFec(ReceivedPacketList* received_packets,
185 RecoveredPacketList* recovered_packets); 214 RecoveredPacketList* recovered_packets);
186 215
187 // Get the number of generated FEC packets, given the number of media packets 216 // Get the number of generated FEC packets, given the number of media packets
188 // and the protection factor. 217 // and the protection factor.
189 int GetNumberOfFecPackets(int num_media_packets, int protection_factor); 218 static int NumFecPackets(int num_media_packets, int protection_factor);
190 219
191 // Gets the size in bytes of the FEC/ULP headers, which must be accounted for 220 // Gets the maximum size of the FEC headers in bytes, which must be
192 // as packet overhead. Returns the packet overhead in bytes. 221 // accounted for as packet overhead.
193 static size_t PacketOverhead(); 222 size_t MaxPacketOverhead() const;
194 223
195 // Reset internal states from last frame and clear |recovered_packets|. 224 // Reset internal states from last frame and clear |recovered_packets|.
196 // Frees all memory allocated by this class. 225 // Frees all memory allocated by this class.
197 void ResetState(RecoveredPacketList* recovered_packets); 226 void ResetState(RecoveredPacketList* recovered_packets);
198 227
228 // TODO(brandtr): Remove these functions when the Packet classes
229 // have been refactored.
230 static uint16_t ParseSequenceNumber(uint8_t* packet);
231 static uint32_t ParseSsrc(uint8_t* packet);
232
199 private: 233 private:
200 // Used to link media packets to their protecting FEC packets. 234 ForwardErrorCorrection(std::unique_ptr<FecHeaderReader> fec_header_reader,
201 // 235 std::unique_ptr<FecHeaderWriter> fec_header_writer);
202 // TODO(holmer): Refactor into a proper class.
203 class ProtectedPacket : public ForwardErrorCorrection::SortablePacket {
204 public:
205 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
206 };
207
208 using ProtectedPacketList = std::list<std::unique_ptr<ProtectedPacket>>;
209
210 // Used for internal storage of received FEC packets in a list.
211 //
212 // TODO(holmer): Refactor into a proper class.
213 class ReceivedFecPacket : public ForwardErrorCorrection::SortablePacket {
214 public:
215 ProtectedPacketList protected_packets;
216 uint32_t ssrc; // SSRC of the current frame.
217 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
218 };
219
220 using ReceivedFecPacketList = std::list<std::unique_ptr<ReceivedFecPacket>>;
221 236
222 // Analyzes |media_packets| for holes in the sequence and inserts zero columns 237 // Analyzes |media_packets| for holes in the sequence and inserts zero columns
223 // into the |packet_mask| where those holes are found. Zero columns means that 238 // into the |packet_mask| where those holes are found. Zero columns means that
224 // those packets will have no protection. 239 // those packets will have no protection.
225 // Returns the number of bits used for one row of the new packet mask. 240 // Returns the number of bits used for one row of the new packet mask.
226 // Requires that |packet_mask| has at least 6 * |num_fec_packets| bytes 241 // Requires that |packet_mask| has at least 6 * |num_fec_packets| bytes
227 // allocated. 242 // allocated.
228 int InsertZerosInBitMasks(const PacketList& media_packets, 243 int InsertZerosInPacketMasks(const PacketList& media_packets,
229 uint8_t* packet_mask, int num_mask_bytes, 244 size_t num_fec_packets);
230 int num_fec_packets);
231 245
232 // Inserts |num_zeros| zero columns into |new_mask| at position 246 // Writes FEC payload and some recovery fields in the FEC headers.
233 // |new_bit_index|. If the current byte of |new_mask| can't fit all zeros, the 247 void GenerateFecPayloads(const PacketList& media_packets,
234 // byte will be filled with zeros from |new_bit_index|, but the next byte will 248 size_t num_fec_packets);
235 // be untouched.
236 static void InsertZeroColumns(int num_zeros, uint8_t* new_mask,
237 int new_mask_bytes, int num_fec_packets,
238 int new_bit_index);
239 249
240 // Copies the left most bit column from the byte pointed to by 250 // Writes the FEC header fields that are not written by GenerateFecPayloads.
241 // |old_bit_index| in |old_mask| to the right most column of the byte pointed 251 // This includes writing the packet masks.
242 // to by |new_bit_index| in |new_mask|. |old_mask_bytes| and |new_mask_bytes| 252 void FinalizeFecHeaders(const PacketList& media_packets,
243 // represent the number of bytes used per row for each mask. |num_fec_packets| 253 size_t num_fec_packets);
244 // represent the number of rows of the masks.
245 // The copied bit is shifted out from |old_mask| and is shifted one step to
246 // the left in |new_mask|. |new_mask| will contain "xxxx xxn0" after this
247 // operation, where x are previously inserted bits and n is the new bit.
248 static void CopyColumn(uint8_t* new_mask, int new_mask_bytes,
249 uint8_t* old_mask, int old_mask_bytes,
250 int num_fec_packets, int new_bit_index,
251 int old_bit_index);
252
253 void GenerateFecUlpHeaders(const PacketList& media_packets,
254 uint8_t* packet_mask, int num_fec_packets,
255 bool l_bit);
256
257 void GenerateFecBitStrings(const PacketList& media_packets,
258 uint8_t* packet_mask, int num_fec_packets,
259 bool l_bit);
260 254
261 // Inserts the |received_packets| into the internal received FEC packet list 255 // Inserts the |received_packets| into the internal received FEC packet list
262 // or into |recovered_packets|. 256 // or into |recovered_packets|.
263 void InsertPackets(ReceivedPacketList* received_packets, 257 void InsertPackets(ReceivedPacketList* received_packets,
264 RecoveredPacketList* recovered_packets); 258 RecoveredPacketList* recovered_packets);
265 259
266 // Inserts the |received_packet| into |recovered_packets|. Deletes duplicates. 260 // Inserts the |received_packet| into |recovered_packets|. Deletes duplicates.
267 void InsertMediaPacket(ReceivedPacket* received_packet, 261 void InsertMediaPacket(ReceivedPacket* received_packet,
268 RecoveredPacketList* recovered_packets); 262 RecoveredPacketList* recovered_packets);
269 263
270 // Assigns pointers to the recovered packet from all FEC packets which cover 264 // Assigns pointers to the recovered packet from all FEC packets which cover
271 // it. 265 // it.
272 // Note: This reduces the complexity when we want to try to recover a packet 266 // Note: This reduces the complexity when we want to try to recover a packet
273 // since we don't have to find the intersection between recovered packets and 267 // since we don't have to find the intersection between recovered packets and
274 // packets covered by the FEC packet. 268 // packets covered by the FEC packet.
275 void UpdateCoveringFecPackets(RecoveredPacket* packet); 269 void UpdateCoveringFecPackets(RecoveredPacket* packet);
276 270
277 // Insert |received_packet| into internal FEC list. Deletes duplicates. 271 // Insert |received_packet| into internal FEC list. Deletes duplicates.
278 void InsertFecPacket(ReceivedPacket* received_packet, 272 void InsertFecPacket(ReceivedPacket* received_packet,
279 const RecoveredPacketList* recovered_packets); 273 const RecoveredPacketList* recovered_packets);
280 274
281 // Assigns pointers to already recovered packets covered by |fec_packet|. 275 // Assigns pointers to already recovered packets covered by |fec_packet|.
282 static void AssignRecoveredPackets( 276 static void AssignRecoveredPackets(
283 ReceivedFecPacket* fec_packet, 277 ReceivedFecPacket* fec_packet,
284 const RecoveredPacketList* recovered_packets); 278 const RecoveredPacketList* recovered_packets);
285 279
286 // Insert |rec_packet_to_insert| into |recovered_packets| in correct position.
287 void InsertRecoveredPacket(RecoveredPacket* rec_packet_to_insert,
288 RecoveredPacketList* recovered_packets);
289
290 // Attempt to recover missing packets, using the internally stored 280 // Attempt to recover missing packets, using the internally stored
291 // received FEC packets. 281 // received FEC packets.
292 void AttemptRecover(RecoveredPacketList* recovered_packets); 282 void AttemptRecovery(RecoveredPacketList* recovered_packets);
293
294 // Initializes packet recovery using the received |fec_packet|.
295 static bool StartPacketRecovery(const ReceivedFecPacket* fec_packet,
296 RecoveredPacket* recovered_packet);
297 283
298 // Performs XOR between |src| and |dst| and stores the result in |dst|. 284 // Performs XOR between |src| and |dst| and stores the result in |dst|.
299 static void XorPackets(const Packet* src, RecoveredPacket* dst); 285 // The parameters |src_offset| and |dst_offset| determines at what byte
286 // the XOR operation starts in |src| and |dst|, respectively. In total,
287 // |payload_length| bytes are XORed.
288 static void XorPackets(const Packet* src,
289 size_t src_offset,
290 size_t payload_length,
291 size_t dst_offset,
292 Packet* dst);
300 293
301 // Finish up the recovery of a packet. 294 // Initializes headers and payload before the XOR operation
302 static bool FinishPacketRecovery(RecoveredPacket* recovered_packet); 295 // that recovers a packet.
296 bool StartPacketRecovery(ReceivedFecPacket* fec_packet,
297 RecoveredPacket* recovered_packet) const;
298
299 // Finalizes recovery of packet by setting RTP header fields.
300 // This is not specific to the FEC scheme used.
301 static bool FinishPacketRecovery(const ReceivedFecPacket* fec_packet,
302 RecoveredPacket* recovered_packet);
303 303
304 // Recover a missing packet. 304 // Recover a missing packet.
305 bool RecoverPacket(const ReceivedFecPacket* fec_packet, 305 bool RecoverPacket(ReceivedFecPacket* fec_packet,
306 RecoveredPacket* rec_packet_to_insert); 306 RecoveredPacket* recovered_packet);
307 307
308 // Get the number of missing media packets which are covered by |fec_packet|. 308 // Get the number of missing media packets which are covered by |fec_packet|.
309 // An FEC packet can recover at most one packet, and if zero packets are 309 // An FEC packet can recover at most one packet, and if zero packets are
310 // missing the FEC packet can be discarded. This function returns 2 when two 310 // missing the FEC packet can be discarded. This function returns 2 when two
311 // or more packets are missing. 311 // or more packets are missing.
312 static int NumCoveredPacketsMissing(const ReceivedFecPacket* fec_packet); 312 static int NumCoveredPacketsMissing(const ReceivedFecPacket* fec_packet);
313 313
314 // Discards old packets in |recovered_packets|, which are no longer relevant 314 // Discards old packets in |recovered_packets|, which are no longer relevant
315 // for recovering lost packets. 315 // for recovering lost packets.
316 static void DiscardOldRecoveredPackets( 316 void DiscardOldRecoveredPackets(RecoveredPacketList* recovered_packets);
317 RecoveredPacketList* recovered_packets); 317
318 static uint16_t ParseSequenceNumber(uint8_t* packet); 318 std::unique_ptr<FecHeaderReader> fec_header_reader_;
319 std::unique_ptr<FecHeaderWriter> fec_header_writer_;
319 320
320 std::vector<Packet> generated_fec_packets_; 321 std::vector<Packet> generated_fec_packets_;
321 ReceivedFecPacketList received_fec_packets_; 322 ReceivedFecPacketList received_fec_packets_;
322 323
323 // Arrays used to avoid dynamically allocating memory when generating 324 // Arrays used to avoid dynamically allocating memory when generating
324 // the packet masks in the ULPFEC headers. 325 // the packet masks.
325 // (There are never more than |kMaxMediaPackets| FEC packets generated.) 326 // (There are never more than |kUlpfecMaxMediaPackets| FEC packets generated.)
326 uint8_t packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet]; 327 uint8_t packet_masks_[kUlpfecMaxMediaPackets * kUlpfecPacketMaskSizeLBitSet];
327 uint8_t tmp_packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet]; 328 uint8_t
329 tmp_packet_masks_[kUlpfecMaxMediaPackets * kUlpfecPacketMaskSizeLBitSet];
330 size_t packet_mask_size_; //
328 }; 331 };
332
333 // Classes derived from FecHeader{Reader,Writer} encapsulate the
334 // specifics of reading and writing FEC header for, e.g., ULPFEC
335 // and FlexFEC.
336 class FecHeaderReader {
337 public:
338 virtual ~FecHeaderReader();
339
340 // The maximum number of media packets that can be covered by one FEC packet.
341 size_t MaxMediaPackets() const;
342
343 // The maximum number of FEC packets that is supported, per call
344 // to ForwardErrorCorrection::EncodeFec().
345 size_t MaxFecPackets() const;
346
347 // Parses FEC header and stores information in ReceivedFecPacket members.
348 virtual bool ReadFecHeader(
349 ForwardErrorCorrection::ReceivedFecPacket* fec_packet) const = 0;
350
351 protected:
352 FecHeaderReader(size_t max_media_packets, size_t max_fec_packets);
353
354 const size_t max_media_packets_;
355 const size_t max_fec_packets_;
356 };
357
358 class FecHeaderWriter {
359 public:
360 FecHeaderWriter(size_t max_media_packets, size_t max_fec_packets);
361 virtual ~FecHeaderWriter();
362
363 // The maximum number of media packets that can be covered by one FEC packet.
364 size_t MaxMediaPackets() const;
365
366 // The maximum number of FEC packets that is supported, per call
367 // to ForwardErrorCorrection::EncodeFec().
368 size_t MaxFecPackets() const;
369
370 // The maximum overhead (in bytes) per packet, due to FEC headers.
371 size_t MaxPacketOverhead() const;
372
373 // Calculates the minimum packet mask size needed (in bytes),
374 // given the discrete options of the ULPFEC masks and the bits
375 // set in the current packet mask.
376 virtual size_t MinPacketMaskSize(const uint8_t* packet_mask,
377 size_t packet_mask_size) const = 0;
378
379 // The header size (in bytes), given the packet mask size.
380 virtual size_t FecHeaderSize(size_t packet_mask_size) const = 0;
381
382 // Writes FEC header.
383 virtual void FinalizeFecHeader(
384 const ForwardErrorCorrection::PacketList& media_packets,
385 const uint8_t* packet_mask,
386 size_t packet_mask_size,
387 ForwardErrorCorrection::Packet* fec_packet) const = 0;
388
389 protected:
390 FecHeaderWriter(size_t max_media_packets,
391 size_t max_fec_packets,
392 size_t max_packet_overhead_);
393
394 const size_t max_media_packets_;
395 const size_t max_fec_packets_;
396 const size_t max_packet_overhead_;
397 };
398
329 } // namespace webrtc 399 } // namespace webrtc
400
330 #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ 401 #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698