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 |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 namespace webrtc { | 27 namespace webrtc { |
28 | 28 |
29 class FecHeaderReader; | 29 class FecHeaderReader; |
30 class FecHeaderWriter; | 30 class FecHeaderWriter; |
31 | 31 |
32 // Performs codec-independent forward error correction (FEC), based on RFC 5109. | 32 // Performs codec-independent forward error correction (FEC), based on RFC 5109. |
33 // Option exists to enable unequal protection (UEP) across packets. | 33 // Option exists to enable unequal protection (UEP) across packets. |
34 // This is not to be confused with protection within packets | 34 // This is not to be confused with protection within packets |
35 // (referred to as uneven level protection (ULP) in RFC 5109). | 35 // (referred to as uneven level protection (ULP) in RFC 5109). |
| 36 // TODO(brandtr): Split this class into a separate encoder |
| 37 // and a separate decoder. |
36 class ForwardErrorCorrection { | 38 class ForwardErrorCorrection { |
37 public: | 39 public: |
38 // 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 |
39 // refactored into proper classes, and their members should be made private. | 41 // refactored into proper classes, and their members should be made private. |
40 // 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 |
41 // and receiver_fec.cc to be refactored into the packet classes. | 43 // and receiver_fec.cc to be refactored into the packet classes. |
42 class Packet { | 44 class Packet { |
43 public: | 45 public: |
44 Packet(); | 46 Packet(); |
45 virtual ~Packet(); | 47 virtual ~Packet(); |
46 | 48 |
47 // Add a reference. | 49 // Add a reference. |
48 virtual int32_t AddRef(); | 50 virtual int32_t AddRef(); |
49 | 51 |
50 // Release a reference. Will delete the object if the reference count | 52 // Release a reference. Will delete the object if the reference count |
51 // reaches zero. | 53 // reaches zero. |
52 virtual int32_t Release(); | 54 virtual int32_t Release(); |
53 | 55 |
54 size_t length; // Length of packet in bytes. | 56 size_t length; // Length of packet in bytes. |
55 uint8_t data[IP_PACKET_SIZE]; // Packet data. | 57 uint8_t data[IP_PACKET_SIZE]; // Packet data. |
56 | 58 |
57 private: | 59 private: |
58 int32_t ref_count_; // Counts the number of references to a packet. | 60 int32_t ref_count_; // Counts the number of references to a packet. |
59 }; | 61 }; |
60 | 62 |
61 // TODO(holmer): Refactor into a proper class. | 63 // TODO(holmer): Refactor into a proper class. |
62 class SortablePacket { | 64 class SortablePacket { |
63 public: | 65 public: |
64 // Functor which returns true if the sequence number of |first| | 66 // Functor which returns true if the sequence number of |first| |
65 // is < the sequence number of |second|. | 67 // is < the sequence number of |second|. Should only ever be called for |
| 68 // packets belonging to the same SSRC. |
66 struct LessThan { | 69 struct LessThan { |
67 template <typename S, typename T> | 70 template <typename S, typename T> |
68 bool operator() (const S& first, const T& second); | 71 bool operator() (const S& first, const T& second); |
69 }; | 72 }; |
70 | 73 |
| 74 uint32_t ssrc; |
71 uint16_t seq_num; | 75 uint16_t seq_num; |
72 }; | 76 }; |
73 | 77 |
74 // The received list parameter of DecodeFec() references structs of this type. | 78 // The received list parameter of DecodeFec() references structs of this type. |
75 // | 79 // |
76 // The ssrc member is needed to ensure that we can restore the SSRC field of | |
77 // recovered packets. In most situations this could be retrieved from other | |
78 // media packets, but in the case of an FEC packet protecting a single | |
79 // missing media packet, we have no other means of obtaining it. | |
80 // TODO(holmer): Refactor into a proper class. | 80 // TODO(holmer): Refactor into a proper class. |
81 class ReceivedPacket : public SortablePacket { | 81 class ReceivedPacket : public SortablePacket { |
82 public: | 82 public: |
83 ReceivedPacket(); | 83 ReceivedPacket(); |
84 ~ReceivedPacket(); | 84 ~ReceivedPacket(); |
85 | 85 |
86 uint32_t ssrc; // SSRC of the current frame. Must be set for FEC | |
87 // packets, but not required for media packets. | |
88 bool is_fec; // Set to true if this is an FEC packet and false | 86 bool is_fec; // Set to true if this is an FEC packet and false |
89 // otherwise. | 87 // otherwise. |
90 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage. | 88 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage. |
91 }; | 89 }; |
92 | 90 |
93 // The recovered list parameter of DecodeFec() references structs of | 91 // The recovered list parameter of DecodeFec() references structs of |
94 // this type. | 92 // this type. |
95 // TODO(holmer): Refactor into a proper class. | 93 // TODO(holmer): Refactor into a proper class. |
96 class RecoveredPacket : public SortablePacket { | 94 class RecoveredPacket : public SortablePacket { |
97 public: | 95 public: |
98 RecoveredPacket(); | 96 RecoveredPacket(); |
99 ~RecoveredPacket(); | 97 ~RecoveredPacket(); |
100 | 98 |
101 bool was_recovered; // Will be true if this packet was recovered by | 99 bool was_recovered; // Will be true if this packet was recovered by |
102 // the FEC. Otherwise it was a media packet passed in | 100 // the FEC. Otherwise it was a media packet passed in |
103 // through the received packet list. | 101 // through the received packet list. |
104 bool returned; // True when the packet already has been returned to the | 102 bool returned; // True when the packet already has been returned to the |
105 // caller through the callback. | 103 // caller through the callback. |
106 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage. | 104 rtc::scoped_refptr<Packet> pkt; // Pointer to the packet storage. |
107 }; | 105 }; |
108 | 106 |
109 // Used to link media packets to their protecting FEC packets. | 107 // Used to link media packets to their protecting FEC packets. |
110 // | 108 // |
111 // TODO(holmer): Refactor into a proper class. | 109 // TODO(holmer): Refactor into a proper class. |
112 class ProtectedPacket : public ForwardErrorCorrection::SortablePacket { | 110 class ProtectedPacket : public SortablePacket { |
113 public: | 111 public: |
114 ProtectedPacket(); | 112 ProtectedPacket(); |
115 ~ProtectedPacket(); | 113 ~ProtectedPacket(); |
116 | 114 |
117 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt; | 115 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt; |
118 }; | 116 }; |
119 | 117 |
120 using ProtectedPacketList = std::list<std::unique_ptr<ProtectedPacket>>; | 118 using ProtectedPacketList = std::list<std::unique_ptr<ProtectedPacket>>; |
121 | 119 |
122 // Used for internal storage of received FEC packets in a list. | 120 // Used for internal storage of received FEC packets in a list. |
123 // | 121 // |
124 // TODO(holmer): Refactor into a proper class. | 122 // TODO(holmer): Refactor into a proper class. |
125 class ReceivedFecPacket : public ForwardErrorCorrection::SortablePacket { | 123 class ReceivedFecPacket : public SortablePacket { |
126 public: | 124 public: |
127 ReceivedFecPacket(); | 125 ReceivedFecPacket(); |
128 ~ReceivedFecPacket(); | 126 ~ReceivedFecPacket(); |
129 | 127 |
130 // List of media packets that this FEC packet protects. | 128 // List of media packets that this FEC packet protects. |
131 ProtectedPacketList protected_packets; | 129 ProtectedPacketList protected_packets; |
132 // RTP header fields. | 130 // RTP header fields. |
133 uint32_t ssrc; | 131 uint32_t ssrc; |
134 // FEC header fields. | 132 // FEC header fields. |
135 size_t fec_header_size; | 133 size_t fec_header_size; |
136 uint32_t protected_ssrc; | 134 uint32_t protected_ssrc; |
137 uint16_t seq_num_base; | 135 uint16_t seq_num_base; |
138 size_t packet_mask_offset; // Relative start of FEC header. | 136 size_t packet_mask_offset; // Relative start of FEC header. |
139 size_t packet_mask_size; | 137 size_t packet_mask_size; |
140 size_t protection_length; | 138 size_t protection_length; |
141 // Raw data. | 139 // Raw data. |
142 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt; | 140 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt; |
143 }; | 141 }; |
144 | 142 |
145 using PacketList = std::list<std::unique_ptr<Packet>>; | 143 using PacketList = std::list<std::unique_ptr<Packet>>; |
146 using ReceivedPacketList = std::list<std::unique_ptr<ReceivedPacket>>; | 144 using ReceivedPacketList = std::list<std::unique_ptr<ReceivedPacket>>; |
147 using RecoveredPacketList = std::list<std::unique_ptr<RecoveredPacket>>; | 145 using RecoveredPacketList = std::list<std::unique_ptr<RecoveredPacket>>; |
148 using ReceivedFecPacketList = std::list<std::unique_ptr<ReceivedFecPacket>>; | 146 using ReceivedFecPacketList = std::list<std::unique_ptr<ReceivedFecPacket>>; |
149 | 147 |
150 ~ForwardErrorCorrection(); | 148 ~ForwardErrorCorrection(); |
151 | 149 |
152 // Creates a ForwardErrorCorrection tailored for a specific FEC scheme. | 150 // Creates a ForwardErrorCorrection tailored for a specific FEC scheme. |
153 static std::unique_ptr<ForwardErrorCorrection> CreateUlpfec(); | 151 static std::unique_ptr<ForwardErrorCorrection> CreateUlpfec(uint32_t ssrc); |
154 static std::unique_ptr<ForwardErrorCorrection> CreateFlexfec(); | 152 static std::unique_ptr<ForwardErrorCorrection> CreateFlexfec( |
| 153 uint32_t ssrc, |
| 154 uint32_t protected_media_ssrc); |
155 | 155 |
156 // Generates a list of FEC packets from supplied media packets. | 156 // Generates a list of FEC packets from supplied media packets. |
157 // | 157 // |
158 // Input: media_packets List of media packets to protect, of type | 158 // Input: media_packets List of media packets to protect, of type |
159 // Packet. All packets must belong to the | 159 // Packet. All packets must belong to the |
160 // same frame and the list must not be empty. | 160 // same frame and the list must not be empty. |
161 // Input: protection_factor FEC protection overhead in the [0, 255] | 161 // Input: protection_factor FEC protection overhead in the [0, 255] |
162 // domain. To obtain 100% overhead, or an | 162 // domain. To obtain 100% overhead, or an |
163 // equal number of FEC packets as | 163 // equal number of FEC packets as |
164 // media packets, use 255. | 164 // media packets, use 255. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 // Frees all memory allocated by this class. | 235 // Frees all memory allocated by this class. |
236 void ResetState(RecoveredPacketList* recovered_packets); | 236 void ResetState(RecoveredPacketList* recovered_packets); |
237 | 237 |
238 // TODO(brandtr): Remove these functions when the Packet classes | 238 // TODO(brandtr): Remove these functions when the Packet classes |
239 // have been refactored. | 239 // have been refactored. |
240 static uint16_t ParseSequenceNumber(uint8_t* packet); | 240 static uint16_t ParseSequenceNumber(uint8_t* packet); |
241 static uint32_t ParseSsrc(uint8_t* packet); | 241 static uint32_t ParseSsrc(uint8_t* packet); |
242 | 242 |
243 protected: | 243 protected: |
244 ForwardErrorCorrection(std::unique_ptr<FecHeaderReader> fec_header_reader, | 244 ForwardErrorCorrection(std::unique_ptr<FecHeaderReader> fec_header_reader, |
245 std::unique_ptr<FecHeaderWriter> fec_header_writer); | 245 std::unique_ptr<FecHeaderWriter> fec_header_writer, |
| 246 uint32_t ssrc, |
| 247 uint32_t protected_media_ssrc); |
246 | 248 |
247 private: | 249 private: |
248 // Analyzes |media_packets| for holes in the sequence and inserts zero columns | 250 // Analyzes |media_packets| for holes in the sequence and inserts zero columns |
249 // into the |packet_mask| where those holes are found. Zero columns means that | 251 // into the |packet_mask| where those holes are found. Zero columns means that |
250 // those packets will have no protection. | 252 // those packets will have no protection. |
251 // Returns the number of bits used for one row of the new packet mask. | 253 // Returns the number of bits used for one row of the new packet mask. |
252 // Requires that |packet_mask| has at least 6 * |num_fec_packets| bytes | 254 // Requires that |packet_mask| has at least 6 * |num_fec_packets| bytes |
253 // allocated. | 255 // allocated. |
254 int InsertZerosInPacketMasks(const PacketList& media_packets, | 256 int InsertZerosInPacketMasks(const PacketList& media_packets, |
255 size_t num_fec_packets); | 257 size_t num_fec_packets); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 // Get the number of missing media packets which are covered by |fec_packet|. | 325 // Get the number of missing media packets which are covered by |fec_packet|. |
324 // An FEC packet can recover at most one packet, and if zero packets are | 326 // An FEC packet can recover at most one packet, and if zero packets are |
325 // missing the FEC packet can be discarded. This function returns 2 when two | 327 // missing the FEC packet can be discarded. This function returns 2 when two |
326 // or more packets are missing. | 328 // or more packets are missing. |
327 static int NumCoveredPacketsMissing(const ReceivedFecPacket& fec_packet); | 329 static int NumCoveredPacketsMissing(const ReceivedFecPacket& fec_packet); |
328 | 330 |
329 // Discards old packets in |recovered_packets|, which are no longer relevant | 331 // Discards old packets in |recovered_packets|, which are no longer relevant |
330 // for recovering lost packets. | 332 // for recovering lost packets. |
331 void DiscardOldRecoveredPackets(RecoveredPacketList* recovered_packets); | 333 void DiscardOldRecoveredPackets(RecoveredPacketList* recovered_packets); |
332 | 334 |
| 335 // These SSRCs are only used by the decoder. |
| 336 const uint32_t ssrc_; |
| 337 const uint32_t protected_media_ssrc_; |
| 338 |
333 std::unique_ptr<FecHeaderReader> fec_header_reader_; | 339 std::unique_ptr<FecHeaderReader> fec_header_reader_; |
334 std::unique_ptr<FecHeaderWriter> fec_header_writer_; | 340 std::unique_ptr<FecHeaderWriter> fec_header_writer_; |
335 | 341 |
336 std::vector<Packet> generated_fec_packets_; | 342 std::vector<Packet> generated_fec_packets_; |
337 ReceivedFecPacketList received_fec_packets_; | 343 ReceivedFecPacketList received_fec_packets_; |
338 | 344 |
339 // Arrays used to avoid dynamically allocating memory when generating | 345 // Arrays used to avoid dynamically allocating memory when generating |
340 // the packet masks. | 346 // the packet masks. |
341 // (There are never more than |kUlpfecMaxMediaPackets| FEC packets generated.) | 347 // (There are never more than |kUlpfecMaxMediaPackets| FEC packets generated.) |
342 uint8_t packet_masks_[kUlpfecMaxMediaPackets * kUlpfecMaxPacketMaskSize]; | 348 uint8_t packet_masks_[kUlpfecMaxMediaPackets * kUlpfecMaxPacketMaskSize]; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 size_t max_packet_overhead); | 412 size_t max_packet_overhead); |
407 | 413 |
408 const size_t max_media_packets_; | 414 const size_t max_media_packets_; |
409 const size_t max_fec_packets_; | 415 const size_t max_fec_packets_; |
410 const size_t max_packet_overhead_; | 416 const size_t max_packet_overhead_; |
411 }; | 417 }; |
412 | 418 |
413 } // namespace webrtc | 419 } // namespace webrtc |
414 | 420 |
415 #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ | 421 #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_FORWARD_ERROR_CORRECTION_H_ |
OLD | NEW |