OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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_ |
OLD | NEW |