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

Side by Side Diff: webrtc/modules/rtp_rtcp/source/forward_error_correction.h

Issue 2099243003: Use std::unique_ptr in ForwardErrorCorrection. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@flexfec-pt1a_mini-fixes-in-ULPFEC
Patch Set: Final nit from danilchap. Created 4 years, 5 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 <memory>
17 #include <vector> 18 #include <vector>
18 19
19 #include "webrtc/base/refcount.h" 20 #include "webrtc/base/refcount.h"
20 #include "webrtc/base/scoped_ref_ptr.h" 21 #include "webrtc/base/scoped_ref_ptr.h"
21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 22 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
22 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h" 23 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h"
23 #include "webrtc/typedefs.h" 24 #include "webrtc/typedefs.h"
24 25
25 namespace webrtc { 26 namespace webrtc {
26 27
27 // Forward declaration.
28 class FecPacket;
29
30 // Performs codec-independent forward error correction (FEC), based on RFC 5109. 28 // Performs codec-independent forward error correction (FEC), based on RFC 5109.
31 // Option exists to enable unequal protection (UEP) across packets. 29 // Option exists to enable unequal protection (UEP) across packets.
32 // This is not to be confused with protection within packets 30 // This is not to be confused with protection within packets
33 // (referred to as uneven level protection (ULP) in RFC 5109). 31 // (referred to as uneven level protection (ULP) in RFC 5109).
34 class ForwardErrorCorrection { 32 class ForwardErrorCorrection {
35 public: 33 public:
36 // Maximum number of media packets we can protect 34 // Maximum number of media packets we can protect
37 static constexpr size_t kMaxMediaPackets = 48u; 35 static constexpr size_t kMaxMediaPackets = 48u;
38 36
39 // TODO(holmer): As a next step all these struct-like packet classes should be 37 // TODO(holmer): As a next step all these struct-like packet classes should be
(...skipping 15 matching lines...) Expand all
55 size_t length; // Length of packet in bytes. 53 size_t length; // Length of packet in bytes.
56 uint8_t data[IP_PACKET_SIZE]; // Packet data. 54 uint8_t data[IP_PACKET_SIZE]; // Packet data.
57 55
58 private: 56 private:
59 int32_t ref_count_; // Counts the number of references to a packet. 57 int32_t ref_count_; // Counts the number of references to a packet.
60 }; 58 };
61 59
62 // TODO(holmer): Refactor into a proper class. 60 // TODO(holmer): Refactor into a proper class.
63 class SortablePacket { 61 class SortablePacket {
64 public: 62 public:
65 // True if first is <= than second. 63 // Functor which returns true if the sequence number of |first|
66 static bool LessThan(const SortablePacket* first, 64 // is < the sequence number of |second|.
67 const SortablePacket* second); 65 struct LessThan {
66 template <typename S, typename T>
67 bool operator() (const S& first, const T& second);
stefan-webrtc 2016/08/01 11:29:51 This should be static, right?
danilchap 2016/08/01 13:29:07 it wouldn't compile: error: overloaded 'operator()
stefan-webrtc 2016/08/01 14:33:23 Good point. But maybe we can make it a static func
68 };
68 69
69 uint16_t seq_num; 70 uint16_t seq_num;
70 }; 71 };
71 72
72 // The received list parameter of #DecodeFec() must reference structs of this 73 // The received list parameter of #DecodeFec() must reference structs of this
73 // type. The last_media_pkt_in_frame is not required to be used for correct 74 // type. The last_media_pkt_in_frame is not required to be used for correct
74 // recovery, but will reduce delay by allowing #DecodeFec() to pre-emptively 75 // recovery, but will reduce delay by allowing #DecodeFec() to pre-emptively
75 // determine frame completion. If set, we assume a FEC stream, and the 76 // determine frame completion. If set, we assume a FEC stream, and the
76 // following assumptions must hold: 77 // following assumptions must hold:
77 // 78 //
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 bool was_recovered; // Will be true if this packet was recovered by 110 bool was_recovered; // Will be true if this packet was recovered by
110 // the FEC. Otherwise it was a media packet passed in 111 // the FEC. Otherwise it was a media packet passed in
111 // through the received packet list. 112 // through the received packet list.
112 bool returned; // True when the packet already has been returned to the 113 bool returned; // True when the packet already has been returned to the
113 // caller through the callback. 114 // caller through the callback.
114 uint8_t length_recovery[2]; // Two bytes used for recovering the packet 115 uint8_t length_recovery[2]; // Two bytes used for recovering the packet
115 // length with XOR operations. 116 // length with XOR operations.
116 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage. 117 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage.
117 }; 118 };
118 119
119 typedef std::list<Packet*> PacketList; 120 using PacketList = std::list<std::unique_ptr<Packet>>;
120 typedef std::list<ReceivedPacket*> ReceivedPacketList; 121 using ReceivedPacketList = std::list<std::unique_ptr<ReceivedPacket>>;
121 typedef std::list<RecoveredPacket*> RecoveredPacketList; 122 using RecoveredPacketList = std::list<std::unique_ptr<RecoveredPacket>>;
122 123
123 ForwardErrorCorrection(); 124 ForwardErrorCorrection();
124 virtual ~ForwardErrorCorrection(); 125 virtual ~ForwardErrorCorrection();
125 126
126 /** 127 /**
127 * Generates a list of FEC packets from supplied media packets. 128 * Generates a list of FEC packets from supplied media packets.
128 * 129 *
129 * \param[in] mediaPacketList List of media packets to protect, of type 130 * \param[in] mediaPacketList List of media packets to protect, of type
130 * #Packet. All packets must belong to the 131 * #Packet. All packets must belong to the
131 * same frame and the list must not be empty. 132 * same frame and the list must not be empty.
(...skipping 20 matching lines...) Expand all
152 * packets. If the number of media packets is 153 * packets. If the number of media packets is
153 * above 12, the packets masks from the 154 * above 12, the packets masks from the
154 * random table will be selected. 155 * random table will be selected.
155 * \param[out] fecPacketList List of FEC packets, of type #Packet. Must 156 * \param[out] fecPacketList List of FEC packets, of type #Packet. Must
156 * be empty on entry. The memory available 157 * be empty on entry. The memory available
157 * through the list will be valid until the 158 * through the list will be valid until the
158 * next call to GenerateFec(). 159 * next call to GenerateFec().
159 * 160 *
160 * \return 0 on success, -1 on failure. 161 * \return 0 on success, -1 on failure.
161 */ 162 */
162 int GenerateFec(const PacketList& media_packet_list, 163 int GenerateFec(const PacketList& media_packets,
163 uint8_t protection_factor, int num_important_packets, 164 uint8_t protection_factor, int num_important_packets,
164 bool use_unequal_protection, FecMaskType fec_mask_type, 165 bool use_unequal_protection, FecMaskType fec_mask_type,
165 PacketList* fec_packet_list); 166 std::list<Packet*>* fec_packets);
166 167
167 /** 168 /**
168 * Decodes a list of media and FEC packets. It will parse the input received 169 * Decodes a list of media and FEC packets. It will parse the input received
169 * packet list, storing FEC packets internally and inserting media packets to 170 * packet list, storing FEC packets internally and inserting media packets to
170 * the output recovered packet list. The recovered list will be sorted by 171 * the output recovered packet list. The recovered list will be sorted by
171 * ascending sequence number and have duplicates removed. The function 172 * ascending sequence number and have duplicates removed. The function
172 * should be called as new packets arrive, with the recovered list being 173 * should be called as new packets arrive, with the recovered list being
173 * progressively assembled with each call. The received packet list will be 174 * progressively assembled with each call. The received packet list will be
174 * empty at output. 175 * empty at output.
175 * 176 *
176 * The user will allocate packets submitted through the received list. The 177 * The user will allocate packets submitted through the received list. The
177 * function will handle allocation of recovered packets and optionally 178 * function will handle allocation of recovered packets and optionally
178 * deleting of all packet memory. The user may delete the recovered list 179 * deleting of all packet memory. The user may delete the recovered list
179 * packets, in which case they must remove deleted packets from the 180 * packets, in which case they must remove deleted packets from the
180 * recovered list. 181 * recovered list.
181 * 182 *
182 * \param[in] receivedPacketList List of new received packets, of type 183 * \param[in] receivedPacketList List of new received packets, of type
183 * #ReceivedPacket, belonging to a single 184 * #ReceivedPacket, belonging to a single
184 * frame. At output the list will be empty, 185 * frame. At output the list will be empty,
185 * with packets either stored internally, 186 * with packets either stored internally,
186 * or accessible through the recovered list. 187 * or accessible through the recovered list.
187 * \param[out] recoveredPacketList List of recovered media packets, of type 188 * \param[out] recoveredPacketList List of recovered media packets, of type
188 * #RecoveredPacket, belonging to a single 189 * #RecoveredPacket, belonging to a single
189 * frame. The memory available through the 190 * frame. The memory available through the
190 * list will be valid until the next call to 191 * list will be valid until the next call to
191 * DecodeFec(). 192 * DecodeFec().
192 * 193 *
193 * \return 0 on success, -1 on failure. 194 * \return 0 on success, -1 on failure.
194 */ 195 */
195 int DecodeFec(ReceivedPacketList* received_packet_list, 196 int DecodeFec(ReceivedPacketList* received_packets,
196 RecoveredPacketList* recovered_packet_list); 197 RecoveredPacketList* recovered_packets);
197 198
198 // Get the number of FEC packets, given the number of media packets and the 199 // Get the number of FEC packets, given the number of media packets and the
199 // protection factor. 200 // protection factor.
200 int GetNumberOfFecPackets(int num_media_packets, int protection_factor); 201 int GetNumberOfFecPackets(int num_media_packets, int protection_factor);
201 202
202 // Gets the size in bytes of the FEC/ULP headers, which must be accounted for 203 // Gets the size in bytes of the FEC/ULP headers, which must be accounted for
203 // as packet overhead. 204 // as packet overhead.
204 // \return Packet overhead in bytes. 205 // \return Packet overhead in bytes.
205 static size_t PacketOverhead(); 206 static size_t PacketOverhead();
206 207
207 // Reset internal states from last frame and clear the recovered_packet_list. 208 // Reset internal states from last frame and clears |recovered_packets|.
208 // Frees all memory allocated by this class. 209 // Frees all memory allocated by this class.
209 void ResetState(RecoveredPacketList* recovered_packet_list); 210 void ResetState(RecoveredPacketList* recovered_packets);
210 211
211 private: 212 private:
212 typedef std::list<FecPacket*> FecPacketList; 213 // Used to link media packets to their protecting FEC packets.
214 //
215 // TODO(holmer): Refactor into a proper class.
216 class ProtectedPacket : public ForwardErrorCorrection::SortablePacket {
217 public:
218 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
219 };
220
221 using ProtectedPacketList = std::list<std::unique_ptr<ProtectedPacket>>;
222
223 // Used for internal storage of received FEC packets in a list.
224 //
225 // TODO(holmer): Refactor into a proper class.
226 class ReceivedFecPacket : public ForwardErrorCorrection::SortablePacket {
227 public:
228 ProtectedPacketList protected_pkt_list;
229 uint32_t ssrc; // SSRC of the current frame.
230 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
231 };
232
233 using ReceivedFecPacketList = std::list<std::unique_ptr<ReceivedFecPacket>>;
213 234
214 // Analyzes |media_packets| for holes in the sequence and inserts zero columns 235 // Analyzes |media_packets| for holes in the sequence and inserts zero columns
215 // into the |packet_mask| where those holes are found. Zero columns means that 236 // into the |packet_mask| where those holes are found. Zero columns means that
216 // those packets will have no protection. 237 // those packets will have no protection.
217 // Returns the number of bits used for one row of the new packet mask. 238 // Returns the number of bits used for one row of the new packet mask.
218 // Requires that |packet_mask| has at least 6 * |num_fec_packets| bytes 239 // Requires that |packet_mask| has at least 6 * |num_fec_packets| bytes
219 // allocated. 240 // allocated.
220 int InsertZerosInBitMasks(const PacketList& media_packets, 241 int InsertZerosInBitMasks(const PacketList& media_packets,
221 uint8_t* packet_mask, int num_mask_bytes, 242 uint8_t* packet_mask, int num_mask_bytes,
222 int num_fec_packets); 243 int num_fec_packets);
(...skipping 12 matching lines...) Expand all
235 // represent the number of bytes used per row for each mask. |num_fec_packets| 256 // represent the number of bytes used per row for each mask. |num_fec_packets|
236 // represent the number of rows of the masks. 257 // represent the number of rows of the masks.
237 // The copied bit is shifted out from |old_mask| and is shifted one step to 258 // The copied bit is shifted out from |old_mask| and is shifted one step to
238 // the left in |new_mask|. |new_mask| will contain "xxxx xxn0" after this 259 // the left in |new_mask|. |new_mask| will contain "xxxx xxn0" after this
239 // operation, where x are previously inserted bits and n is the new bit. 260 // operation, where x are previously inserted bits and n is the new bit.
240 static void CopyColumn(uint8_t* new_mask, int new_mask_bytes, 261 static void CopyColumn(uint8_t* new_mask, int new_mask_bytes,
241 uint8_t* old_mask, int old_mask_bytes, 262 uint8_t* old_mask, int old_mask_bytes,
242 int num_fec_packets, int new_bit_index, 263 int num_fec_packets, int new_bit_index,
243 int old_bit_index); 264 int old_bit_index);
244 265
245 void GenerateFecUlpHeaders(const PacketList& media_packet_list, 266 void GenerateFecUlpHeaders(const PacketList& media_packets,
246 uint8_t* packet_mask, int num_fec_packets, 267 uint8_t* packet_mask, int num_fec_packets,
247 bool l_bit); 268 bool l_bit);
248 269
249 void GenerateFecBitStrings(const PacketList& media_packet_list, 270 void GenerateFecBitStrings(const PacketList& media_packets,
250 uint8_t* packet_mask, int num_fec_packets, 271 uint8_t* packet_mask, int num_fec_packets,
251 bool l_bit); 272 bool l_bit);
252 273
253 // Insert received packets into FEC or recovered list. 274 // Insert received packets into FEC or recovered list.
254 void InsertPackets(ReceivedPacketList* received_packet_list, 275 void InsertPackets(ReceivedPacketList* received_packets,
255 RecoveredPacketList* recovered_packet_list); 276 RecoveredPacketList* recovered_packets);
256 277
257 // Insert media packet into recovered packet list. We delete duplicates. 278 // Insert media packet into recovered packet list. We delete duplicates.
258 void InsertMediaPacket(ReceivedPacket* rx_packet, 279 void InsertMediaPacket(ReceivedPacket* rx_packet,
259 RecoveredPacketList* recovered_packet_list); 280 RecoveredPacketList* recovered_packets);
260 281
261 // Assigns pointers to the recovered packet from all FEC packets which cover 282 // Assigns pointers to the recovered packet from all FEC packets which cover
262 // it. 283 // it.
263 // Note: This reduces the complexity when we want to try to recover a packet 284 // Note: This reduces the complexity when we want to try to recover a packet
264 // since we don't have to find the intersection between recovered packets and 285 // since we don't have to find the intersection between recovered packets and
265 // packets covered by the FEC packet. 286 // packets covered by the FEC packet.
266 void UpdateCoveringFecPackets(RecoveredPacket* packet); 287 void UpdateCoveringFecPackets(RecoveredPacket* packet);
267 288
268 // Insert packet into FEC list. We delete duplicates. 289 // Insert packet into FEC list. We delete duplicates.
269 void InsertFecPacket(ReceivedPacket* rx_packet, 290 void InsertFecPacket(ReceivedPacket* rx_packet,
270 const RecoveredPacketList* recovered_packet_list); 291 const RecoveredPacketList* recovered_packets);
271 292
272 // Assigns pointers to already recovered packets covered by this FEC packet. 293 // Assigns pointers to already recovered packets covered by this FEC packet.
273 static void AssignRecoveredPackets( 294 static void AssignRecoveredPackets(
274 FecPacket* fec_packet, const RecoveredPacketList* recovered_packets); 295 ReceivedFecPacket* fec_packet,
296 const RecoveredPacketList* recovered_packets);
275 297
276 // Insert into recovered list in correct position. 298 // Insert into recovered list in correct position.
277 void InsertRecoveredPacket(RecoveredPacket* rec_packet_to_insert, 299 void InsertRecoveredPacket(RecoveredPacket* rec_packet_to_insert,
278 RecoveredPacketList* recovered_packet_list); 300 RecoveredPacketList* recovered_packets);
279 301
280 // Attempt to recover missing packets. 302 // Attempt to recover missing packets.
281 void AttemptRecover(RecoveredPacketList* recovered_packet_list); 303 void AttemptRecover(RecoveredPacketList* recovered_packets);
282 304
283 // Initializes the packet recovery using the FEC packet. 305 // Initializes the packet recovery using the FEC packet.
284 static bool StartPacketRecovery(const FecPacket* fec_packet, 306 static bool StartPacketRecovery(const ReceivedFecPacket* fec_packet,
285 RecoveredPacket* recovered); 307 RecoveredPacket* recovered);
286 308
287 // Performs XOR between |src_packet| and |dst_packet| and stores the result 309 // Performs XOR between |src_packet| and |dst_packet| and stores the result
288 // in |dst_packet|. 310 // in |dst_packet|.
289 static void XorPackets(const Packet* src_packet, RecoveredPacket* dst_packet); 311 static void XorPackets(const Packet* src_packet, RecoveredPacket* dst_packet);
290 312
291 // Finish up the recovery of a packet. 313 // Finish up the recovery of a packet.
292 static bool FinishPacketRecovery(RecoveredPacket* recovered); 314 static bool FinishPacketRecovery(RecoveredPacket* recovered);
293 315
294 // Recover a missing packet. 316 // Recover a missing packet.
295 bool RecoverPacket(const FecPacket* fec_packet, 317 bool RecoverPacket(const ReceivedFecPacket* fec_packet,
296 RecoveredPacket* rec_packet_to_insert); 318 RecoveredPacket* rec_packet_to_insert);
297 319
298 // Get the number of missing media packets which are covered by this 320 // Get the number of missing media packets which are covered by this
299 // FEC packet. An FEC packet can recover at most one packet, and if zero 321 // FEC packet. An FEC packet can recover at most one packet, and if zero
300 // packets are missing the FEC packet can be discarded. 322 // packets are missing the FEC packet can be discarded.
301 // This function returns 2 when two or more packets are missing. 323 // This function returns 2 when two or more packets are missing.
302 static int NumCoveredPacketsMissing(const FecPacket* fec_packet); 324 static int NumCoveredPacketsMissing(const ReceivedFecPacket* fec_packet);
303 325
304 static void DiscardFecPacket(FecPacket* fec_packet); 326 static void DiscardOldRecoveredPackets(
305 static void DiscardOldPackets(RecoveredPacketList* recovered_packet_list); 327 RecoveredPacketList* recovered_packets);
306 static uint16_t ParseSequenceNumber(uint8_t* packet); 328 static uint16_t ParseSequenceNumber(uint8_t* packet);
307 329
308 std::vector<Packet> generated_fec_packets_; 330 std::vector<Packet> generated_fec_packets_;
309 FecPacketList fec_packet_list_; 331 ReceivedFecPacketList received_fec_packets_;
310 332
311 // Arrays used to avoid dynamically allocating memory when generating 333 // Arrays used to avoid dynamically allocating memory when generating
312 // the packet masks in the ULPFEC headers. 334 // the packet masks in the ULPFEC headers.
313 // (There are never more than |kMaxMediaPackets| FEC packets generated.) 335 // (There are never more than |kMaxMediaPackets| FEC packets generated.)
314 uint8_t packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet]; 336 uint8_t packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet];
315 uint8_t tmp_packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet]; 337 uint8_t tmp_packet_mask_[kMaxMediaPackets * kMaskSizeLBitSet];
316 }; 338 };
317 } // namespace webrtc 339 } // namespace webrtc
318 #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ 340 #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698