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

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

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 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" 11 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
12 12
13 #include <string.h> 13 #include <string.h>
14 14
15 #include <algorithm> 15 #include <algorithm>
16 #include <iterator> 16 #include <iterator>
17 #include <memory> 17 #include <utility>
18 18
19 #include "webrtc/base/checks.h" 19 #include "webrtc/base/checks.h"
20 #include "webrtc/base/logging.h" 20 #include "webrtc/base/logging.h"
21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" 21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" 22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
23 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h" 23 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h"
24 24
25 namespace webrtc { 25 namespace webrtc {
26 26
27 // FEC header size in bytes. 27 // FEC header size in bytes.
28 constexpr size_t kFecHeaderSize = 10; 28 constexpr size_t kFecHeaderSize = 10;
29 29
30 // ULP header size in bytes (L bit is set). 30 // ULP header size in bytes (L bit is set).
31 constexpr size_t kUlpHeaderSizeLBitSet = (2 + kMaskSizeLBitSet); 31 constexpr size_t kUlpHeaderSizeLBitSet = (2 + kMaskSizeLBitSet);
32 32
33 // ULP header size in bytes (L bit is cleared). 33 // ULP header size in bytes (L bit is cleared).
34 constexpr size_t kUlpHeaderSizeLBitClear = (2 + kMaskSizeLBitClear); 34 constexpr size_t kUlpHeaderSizeLBitClear = (2 + kMaskSizeLBitClear);
35 35
36 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. 36 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum.
37 constexpr size_t kTransportOverhead = 28; 37 constexpr size_t kTransportOverhead = 28;
38 38
39 // Maximum number of media packets that can be protected.
40 constexpr size_t ForwardErrorCorrection::kMaxMediaPackets;
41
39 // Maximum number of FEC packets stored internally. 42 // Maximum number of FEC packets stored internally.
40 constexpr size_t kMaxFecPackets = ForwardErrorCorrection::kMaxMediaPackets; 43 constexpr size_t kMaxFecPackets = ForwardErrorCorrection::kMaxMediaPackets;
41 44
42 int32_t ForwardErrorCorrection::Packet::AddRef() { 45 int32_t ForwardErrorCorrection::Packet::AddRef() {
43 return ++ref_count_; 46 return ++ref_count_;
44 } 47 }
45 48
46 int32_t ForwardErrorCorrection::Packet::Release() { 49 int32_t ForwardErrorCorrection::Packet::Release() {
47 int32_t ref_count; 50 int32_t ref_count;
48 ref_count = --ref_count_; 51 ref_count = --ref_count_;
49 if (ref_count == 0) 52 if (ref_count == 0)
50 delete this; 53 delete this;
51 return ref_count; 54 return ref_count;
52 } 55 }
53 56
54 // Used to link media packets to their protecting FEC packets. 57 // This comparator is used to compare std::unique_ptr's pointing to
55 // 58 // subclasses of SortablePackets. It needs to be parametric since
56 // TODO(holmer): Refactor into a proper class. 59 // the std::unique_ptr's are not covariant w.r.t. the types that
57 class ProtectedPacket : public ForwardErrorCorrection::SortablePacket { 60 // they are pointing to.
58 public: 61 template <typename S, typename T>
59 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt; 62 bool ForwardErrorCorrection::SortablePacket::LessThan::operator() (
60 }; 63 const S& first,
61 64 const T& second) {
62 typedef std::list<ProtectedPacket*> ProtectedPacketList;
63
64 //
65 // Used for internal storage of FEC packets in a list.
66 //
67 // TODO(holmer): Refactor into a proper class.
68 class FecPacket : public ForwardErrorCorrection::SortablePacket {
69 public:
70 ProtectedPacketList protected_pkt_list;
71 uint32_t ssrc; // SSRC of the current frame.
72 rtc::scoped_refptr<ForwardErrorCorrection::Packet> pkt;
73 };
74
75 bool ForwardErrorCorrection::SortablePacket::LessThan(
76 const SortablePacket* first,
77 const SortablePacket* second) {
78 return IsNewerSequenceNumber(second->seq_num, first->seq_num); 65 return IsNewerSequenceNumber(second->seq_num, first->seq_num);
79 } 66 }
80 67
81 ForwardErrorCorrection::ReceivedPacket::ReceivedPacket() {} 68 ForwardErrorCorrection::ReceivedPacket::ReceivedPacket() {}
82 ForwardErrorCorrection::ReceivedPacket::~ReceivedPacket() {} 69 ForwardErrorCorrection::ReceivedPacket::~ReceivedPacket() {}
83 70
84 ForwardErrorCorrection::RecoveredPacket::RecoveredPacket() {} 71 ForwardErrorCorrection::RecoveredPacket::RecoveredPacket() {}
85 ForwardErrorCorrection::RecoveredPacket::~RecoveredPacket() {} 72 ForwardErrorCorrection::RecoveredPacket::~RecoveredPacket() {}
86 73
87 ForwardErrorCorrection::ForwardErrorCorrection() 74 ForwardErrorCorrection::ForwardErrorCorrection()
88 : generated_fec_packets_(kMaxMediaPackets), fec_packet_list_(), 75 : generated_fec_packets_(kMaxMediaPackets), received_fec_packets_(),
89 packet_mask_(), tmp_packet_mask_() {} 76 packet_mask_(), tmp_packet_mask_() {}
90 ForwardErrorCorrection::~ForwardErrorCorrection() {} 77 ForwardErrorCorrection::~ForwardErrorCorrection() {}
91 78
92 // Input packet 79 // Input packet
93 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 80 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
94 // | RTP Header (12 octets) | 81 // | RTP Header (12 octets) |
95 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 82 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
96 // | RTP Payload | 83 // | RTP Payload |
97 // | | 84 // | |
98 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 85 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99 86
100 // Output packet 87 // Output packet
101 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 88 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102 // | FEC Header (10 octets) | 89 // | FEC Header (10 octets) |
103 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 90 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
104 // | FEC Level 0 Header | 91 // | FEC Level 0 Header |
105 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 92 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106 // | FEC Level 0 Payload | 93 // | FEC Level 0 Payload |
107 // | | 94 // | |
108 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 95 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109 // 96 //
110 // Note that any potential RED headers are added/removed before calling 97 // Note that any potential RED headers are added/removed before calling
111 // GenerateFec() or DecodeFec(). 98 // GenerateFec() or DecodeFec().
112 int ForwardErrorCorrection::GenerateFec(const PacketList& media_packet_list, 99 int ForwardErrorCorrection::GenerateFec(const PacketList& media_packets,
113 uint8_t protection_factor, 100 uint8_t protection_factor,
114 int num_important_packets, 101 int num_important_packets,
115 bool use_unequal_protection, 102 bool use_unequal_protection,
116 FecMaskType fec_mask_type, 103 FecMaskType fec_mask_type,
117 PacketList* fec_packet_list) { 104 std::list<Packet*>* fec_packets) {
118 const uint16_t num_media_packets = media_packet_list.size(); 105 const uint16_t num_media_packets = media_packets.size();
119 // Sanity check arguments. 106 // Sanity check arguments.
120 RTC_DCHECK_GT(num_media_packets, 0); 107 RTC_DCHECK_GT(num_media_packets, 0);
121 RTC_DCHECK_GE(num_important_packets, 0); 108 RTC_DCHECK_GE(num_important_packets, 0);
122 RTC_DCHECK_LE(num_important_packets, num_media_packets); 109 RTC_DCHECK_LE(num_important_packets, num_media_packets);
123 RTC_DCHECK(fec_packet_list->empty()); 110 RTC_DCHECK(fec_packets->empty());
124 111
125 if (num_media_packets > kMaxMediaPackets) { 112 if (num_media_packets > kMaxMediaPackets) {
126 LOG(LS_WARNING) << "Can't protect " << num_media_packets 113 LOG(LS_WARNING) << "Can't protect " << num_media_packets
127 << " media packets per frame. Max is " << kMaxMediaPackets; 114 << " media packets per frame. Max is " << kMaxMediaPackets
115 << ".";
128 return -1; 116 return -1;
129 } 117 }
130 118
131 bool l_bit = (num_media_packets > 8 * kMaskSizeLBitClear); 119 bool l_bit = (num_media_packets > 8 * kMaskSizeLBitClear);
132 int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; 120 int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
133 121
134 // Do some error checking on the media packets. 122 // Do some error checking on the media packets.
135 for (Packet* media_packet : media_packet_list) { 123 for (const auto& media_packet : media_packets) {
136 RTC_DCHECK(media_packet); 124 RTC_DCHECK(media_packet);
137 125
138 if (media_packet->length < kRtpHeaderSize) { 126 if (media_packet->length < kRtpHeaderSize) {
139 LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes " 127 LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes "
140 << "is smaller than RTP header."; 128 << "is smaller than RTP header.";
141 return -1; 129 return -1;
142 } 130 }
143 131
144 // Ensure our FEC packets will fit in a typical MTU. 132 // Ensure our FEC packets will fit in a typical MTU.
145 if (media_packet->length + PacketOverhead() + kTransportOverhead > 133 if (media_packet->length + PacketOverhead() + kTransportOverhead >
146 IP_PACKET_SIZE) { 134 IP_PACKET_SIZE) {
147 LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes " 135 LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes "
148 << "with overhead is larger than " << IP_PACKET_SIZE; 136 << "with overhead is larger than " << IP_PACKET_SIZE
137 << " bytes.";
149 } 138 }
150 } 139 }
151 140
152 int num_fec_packets = 141 int num_fec_packets =
153 GetNumberOfFecPackets(num_media_packets, protection_factor); 142 GetNumberOfFecPackets(num_media_packets, protection_factor);
154 if (num_fec_packets == 0) { 143 if (num_fec_packets == 0) {
155 return 0; 144 return 0;
156 } 145 }
157 146
158 // Prepare FEC packets by setting them to 0. 147 // Prepare generated FEC packets by setting them to 0.
159 for (int i = 0; i < num_fec_packets; ++i) { 148 for (int i = 0; i < num_fec_packets; ++i) {
160 memset(generated_fec_packets_[i].data, 0, IP_PACKET_SIZE); 149 memset(generated_fec_packets_[i].data, 0, IP_PACKET_SIZE);
161 generated_fec_packets_[i].length = 0; // Use this as a marker for untouched 150 // Use this as a marker for untouched packets.
162 // packets. 151 generated_fec_packets_[i].length = 0;
163 fec_packet_list->push_back(&generated_fec_packets_[i]); 152 fec_packets->push_back(&generated_fec_packets_[i]);
164 } 153 }
165 154
166 const internal::PacketMaskTable mask_table(fec_mask_type, num_media_packets); 155 const internal::PacketMaskTable mask_table(fec_mask_type, num_media_packets);
167 156
168 // -- Generate packet masks -- 157 // -- Generate packet masks --
169 memset(packet_mask_, 0, num_fec_packets * num_mask_bytes); 158 memset(packet_mask_, 0, num_fec_packets * num_mask_bytes);
170 internal::GeneratePacketMasks(num_media_packets, num_fec_packets, 159 internal::GeneratePacketMasks(num_media_packets, num_fec_packets,
171 num_important_packets, use_unequal_protection, 160 num_important_packets, use_unequal_protection,
172 mask_table, packet_mask_); 161 mask_table, packet_mask_);
173 162
174 int num_mask_bits = InsertZerosInBitMasks( 163 int num_mask_bits = InsertZerosInBitMasks(
175 media_packet_list, packet_mask_, num_mask_bytes, num_fec_packets); 164 media_packets, packet_mask_, num_mask_bytes, num_fec_packets);
176 165
177 if (num_mask_bits < 0) { 166 if (num_mask_bits < 0) {
178 return -1; 167 return -1;
179 } 168 }
180 l_bit = (static_cast<size_t>(num_mask_bits) > 8 * kMaskSizeLBitClear); 169 l_bit = (static_cast<size_t>(num_mask_bits) > 8 * kMaskSizeLBitClear);
181 if (l_bit) { 170 if (l_bit) {
182 num_mask_bytes = kMaskSizeLBitSet; 171 num_mask_bytes = kMaskSizeLBitSet;
183 } 172 }
184 173
185 GenerateFecBitStrings(media_packet_list, packet_mask_, 174 GenerateFecBitStrings(media_packets, packet_mask_, num_fec_packets, l_bit);
186 num_fec_packets, l_bit); 175 GenerateFecUlpHeaders(media_packets, packet_mask_, num_fec_packets, l_bit);
187 GenerateFecUlpHeaders(media_packet_list, packet_mask_,
188 num_fec_packets, l_bit);
189 176
190 return 0; 177 return 0;
191 } 178 }
192 179
193 int ForwardErrorCorrection::GetNumberOfFecPackets(int num_media_packets, 180 int ForwardErrorCorrection::GetNumberOfFecPackets(int num_media_packets,
194 int protection_factor) { 181 int protection_factor) {
195 // Result in Q0 with an unsigned round. 182 // Result in Q0 with an unsigned round.
196 int num_fec_packets = (num_media_packets * protection_factor + (1 << 7)) >> 8; 183 int num_fec_packets = (num_media_packets * protection_factor + (1 << 7)) >> 8;
197 // Generate at least one FEC packet if we need protection. 184 // Generate at least one FEC packet if we need protection.
198 if (protection_factor > 0 && num_fec_packets == 0) { 185 if (protection_factor > 0 && num_fec_packets == 0) {
199 num_fec_packets = 1; 186 num_fec_packets = 1;
200 } 187 }
201 RTC_DCHECK_LE(num_fec_packets, num_media_packets); 188 RTC_DCHECK_LE(num_fec_packets, num_media_packets);
202 return num_fec_packets; 189 return num_fec_packets;
203 } 190 }
204 191
205 void ForwardErrorCorrection::GenerateFecBitStrings( 192 void ForwardErrorCorrection::GenerateFecBitStrings(
206 const PacketList& media_packet_list, 193 const PacketList& media_packets,
207 uint8_t* packet_mask, 194 uint8_t* packet_mask,
208 int num_fec_packets, 195 int num_fec_packets,
209 bool l_bit) { 196 bool l_bit) {
210 RTC_DCHECK(!media_packet_list.empty()); 197 RTC_DCHECK(!media_packets.empty());
211 uint8_t media_payload_length[2]; 198 uint8_t media_payload_length[2];
212 const int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; 199 const int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
213 const uint16_t ulp_header_size = 200 const uint16_t ulp_header_size =
214 l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear; 201 l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear;
215 const uint16_t fec_rtp_offset = 202 const uint16_t fec_rtp_offset =
216 kFecHeaderSize + ulp_header_size - kRtpHeaderSize; 203 kFecHeaderSize + ulp_header_size - kRtpHeaderSize;
217 204
218 for (int i = 0; i < num_fec_packets; ++i) { 205 for (int i = 0; i < num_fec_packets; ++i) {
219 Packet* const fec_packet = &generated_fec_packets_[i]; 206 Packet* const fec_packet = &generated_fec_packets_[i];
220 auto media_list_it = media_packet_list.cbegin(); 207 auto media_packets_it = media_packets.cbegin();
221 uint32_t pkt_mask_idx = i * num_mask_bytes; 208 uint32_t pkt_mask_idx = i * num_mask_bytes;
222 uint32_t media_pkt_idx = 0; 209 uint32_t media_pkt_idx = 0;
223 uint16_t fec_packet_length = 0; 210 uint16_t fec_packet_length = 0;
224 uint16_t prev_seq_num = ParseSequenceNumber((*media_list_it)->data); 211 uint16_t prev_seq_num = ParseSequenceNumber((*media_packets_it)->data);
225 while (media_list_it != media_packet_list.end()) { 212 while (media_packets_it != media_packets.end()) {
226 // Each FEC packet has a multiple byte mask. Determine if this media 213 // Each FEC packet has a multiple byte mask. Determine if this media
227 // packet should be included in FEC packet i. 214 // packet should be included in FEC packet i.
228 if (packet_mask[pkt_mask_idx] & (1 << (7 - media_pkt_idx))) { 215 if (packet_mask[pkt_mask_idx] & (1 << (7 - media_pkt_idx))) {
229 Packet* media_packet = *media_list_it; 216 Packet* media_packet = media_packets_it->get();
230 217
231 // Assign network-ordered media payload length. 218 // Assign network-ordered media payload length.
232 ByteWriter<uint16_t>::WriteBigEndian( 219 ByteWriter<uint16_t>::WriteBigEndian(
233 media_payload_length, media_packet->length - kRtpHeaderSize); 220 media_payload_length, media_packet->length - kRtpHeaderSize);
234 221
235 fec_packet_length = media_packet->length + fec_rtp_offset; 222 fec_packet_length = media_packet->length + fec_rtp_offset;
236 // On the first protected packet, we don't need to XOR. 223 // On the first protected packet, we don't need to XOR.
237 if (fec_packet->length == 0) { 224 if (fec_packet->length == 0) {
238 // Copy the first 2 bytes of the RTP header. Note that the E and L 225 // Copy the first 2 bytes of the RTP header. Note that the E and L
239 // bits are overwritten in GenerateFecUlpHeaders. 226 // bits are overwritten in GenerateFecUlpHeaders.
(...skipping 24 matching lines...) Expand all
264 // XOR with RTP payload, leaving room for the ULP header. 251 // XOR with RTP payload, leaving room for the ULP header.
265 for (int32_t j = kFecHeaderSize + ulp_header_size; 252 for (int32_t j = kFecHeaderSize + ulp_header_size;
266 j < fec_packet_length; j++) { 253 j < fec_packet_length; j++) {
267 fec_packet->data[j] ^= media_packet->data[j - fec_rtp_offset]; 254 fec_packet->data[j] ^= media_packet->data[j - fec_rtp_offset];
268 } 255 }
269 } 256 }
270 if (fec_packet_length > fec_packet->length) { 257 if (fec_packet_length > fec_packet->length) {
271 fec_packet->length = fec_packet_length; 258 fec_packet->length = fec_packet_length;
272 } 259 }
273 } 260 }
274 media_list_it++; 261 media_packets_it++;
275 if (media_list_it != media_packet_list.end()) { 262 if (media_packets_it != media_packets.end()) {
276 uint16_t seq_num = ParseSequenceNumber((*media_list_it)->data); 263 uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data);
277 media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num); 264 media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num);
278 prev_seq_num = seq_num; 265 prev_seq_num = seq_num;
279 } 266 }
280 pkt_mask_idx += media_pkt_idx / 8; 267 pkt_mask_idx += media_pkt_idx / 8;
281 media_pkt_idx %= 8; 268 media_pkt_idx %= 8;
282 } 269 }
283 RTC_DCHECK_GT(fec_packet->length, 0u) 270 RTC_DCHECK_GT(fec_packet->length, 0u)
284 << "Packet mask is wrong or poorly designed."; 271 << "Packet mask is wrong or poorly designed.";
285 } 272 }
286 } 273 }
(...skipping 14 matching lines...) Expand all
301 if (total_missing_seq_nums == 0) { 288 if (total_missing_seq_nums == 0) {
302 // All sequence numbers are covered by the packet mask. No zero insertion 289 // All sequence numbers are covered by the packet mask. No zero insertion
303 // required. 290 // required.
304 return media_packets.size(); 291 return media_packets.size();
305 } 292 }
306 // We can only protect 8 * kMaskSizeLBitSet packets. 293 // We can only protect 8 * kMaskSizeLBitSet packets.
307 if (total_missing_seq_nums + media_packets.size() > 8 * kMaskSizeLBitSet) 294 if (total_missing_seq_nums + media_packets.size() > 8 * kMaskSizeLBitSet)
308 return -1; 295 return -1;
309 // Allocate the new mask. 296 // Allocate the new mask.
310 int new_mask_bytes = kMaskSizeLBitClear; 297 int new_mask_bytes = kMaskSizeLBitClear;
311 if (media_packets.size() + total_missing_seq_nums > 8 * kMaskSizeLBitClear) { 298 if (media_packets.size() +
299 total_missing_seq_nums > 8 * kMaskSizeLBitClear) {
312 new_mask_bytes = kMaskSizeLBitSet; 300 new_mask_bytes = kMaskSizeLBitSet;
313 } 301 }
314 memset(tmp_packet_mask_, 0, num_fec_packets * kMaskSizeLBitSet); 302 memset(tmp_packet_mask_, 0, num_fec_packets * kMaskSizeLBitSet);
315 303
316 auto it = media_packets.cbegin(); 304 auto media_packets_it = media_packets.cbegin();
317 uint16_t prev_seq_num = first_seq_num; 305 uint16_t prev_seq_num = first_seq_num;
318 ++it; 306 ++media_packets_it;
319 307
320 // Insert the first column. 308 // Insert the first column.
321 CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask, num_mask_bytes, 309 CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask, num_mask_bytes,
322 num_fec_packets, 0, 0); 310 num_fec_packets, 0, 0);
323 int new_bit_index = 1; 311 int new_bit_index = 1;
324 int old_bit_index = 1; 312 int old_bit_index = 1;
325 // Insert zeros in the bit mask for every hole in the sequence. 313 // Insert zeros in the bit mask for every hole in the sequence.
326 for (; it != media_packets.end(); ++it) { 314 while (media_packets_it != media_packets.end()) {
327 if (new_bit_index == 8 * kMaskSizeLBitSet) { 315 if (new_bit_index == 8 * kMaskSizeLBitSet) {
328 // We can only cover up to 48 packets. 316 // We can only cover up to 48 packets.
329 break; 317 break;
330 } 318 }
331 uint16_t seq_num = ParseSequenceNumber((*it)->data); 319 uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data);
332 const int zeros_to_insert = 320 const int zeros_to_insert =
333 static_cast<uint16_t>(seq_num - prev_seq_num - 1); 321 static_cast<uint16_t>(seq_num - prev_seq_num - 1);
334 if (zeros_to_insert > 0) { 322 if (zeros_to_insert > 0) {
335 InsertZeroColumns(zeros_to_insert, tmp_packet_mask_, new_mask_bytes, 323 InsertZeroColumns(zeros_to_insert, tmp_packet_mask_, new_mask_bytes,
336 num_fec_packets, new_bit_index); 324 num_fec_packets, new_bit_index);
337 } 325 }
338 new_bit_index += zeros_to_insert; 326 new_bit_index += zeros_to_insert;
339 CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask, num_mask_bytes, 327 CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask, num_mask_bytes,
340 num_fec_packets, new_bit_index, old_bit_index); 328 num_fec_packets, new_bit_index, old_bit_index);
341 ++new_bit_index; 329 ++new_bit_index;
342 ++old_bit_index; 330 ++old_bit_index;
343 prev_seq_num = seq_num; 331 prev_seq_num = seq_num;
332 ++media_packets_it;
344 } 333 }
345 if (new_bit_index % 8 != 0) { 334 if (new_bit_index % 8 != 0) {
346 // We didn't fill the last byte. Shift bits to correct position. 335 // We didn't fill the last byte. Shift bits to correct position.
347 for (uint16_t row = 0; row < num_fec_packets; ++row) { 336 for (uint16_t row = 0; row < num_fec_packets; ++row) {
348 int new_byte_index = row * new_mask_bytes + new_bit_index / 8; 337 int new_byte_index = row * new_mask_bytes + new_bit_index / 8;
349 tmp_packet_mask_[new_byte_index] <<= (7 - (new_bit_index % 8)); 338 tmp_packet_mask_[new_byte_index] <<= (7 - (new_bit_index % 8));
350 } 339 }
351 } 340 }
352 // Replace the old mask with the new. 341 // Replace the old mask with the new.
353 memcpy(packet_mask, tmp_packet_mask_, kMaskSizeLBitSet * num_fec_packets); 342 memcpy(packet_mask, tmp_packet_mask_, kMaskSizeLBitSet * num_fec_packets);
(...skipping 26 matching lines...) Expand all
380 int old_byte_index = row * old_mask_bytes + old_bit_index / 8; 369 int old_byte_index = row * old_mask_bytes + old_bit_index / 8;
381 new_mask[new_byte_index] |= ((old_mask[old_byte_index] & 0x80) >> 7); 370 new_mask[new_byte_index] |= ((old_mask[old_byte_index] & 0x80) >> 7);
382 if (new_bit_index % 8 != 7) { 371 if (new_bit_index % 8 != 7) {
383 new_mask[new_byte_index] <<= 1; 372 new_mask[new_byte_index] <<= 1;
384 } 373 }
385 old_mask[old_byte_index] <<= 1; 374 old_mask[old_byte_index] <<= 1;
386 } 375 }
387 } 376 }
388 377
389 void ForwardErrorCorrection::GenerateFecUlpHeaders( 378 void ForwardErrorCorrection::GenerateFecUlpHeaders(
390 const PacketList& media_packet_list, 379 const PacketList& media_packets,
391 uint8_t* packet_mask, 380 uint8_t* packet_mask,
392 int num_fec_packets, 381 int num_fec_packets,
393 bool l_bit) { 382 bool l_bit) {
394 // -- Generate FEC and ULP headers -- 383 // -- Generate FEC and ULP headers --
395 // 384 //
396 // FEC Header, 10 bytes 385 // FEC Header, 10 bytes
397 // 0 1 2 3 386 // 0 1 2 3
398 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 387 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
399 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 388 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
400 // |E|L|P|X| CC |M| PT recovery | SN base | 389 // |E|L|P|X| CC |M| PT recovery | SN base |
401 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 390 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
402 // | TS recovery | 391 // | TS recovery |
403 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 392 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
404 // | length recovery | 393 // | length recovery |
405 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 394 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
406 // 395 //
407 // ULP Header, 4 bytes (for L = 0) 396 // ULP Header, 4 bytes (for L = 0)
408 // 0 1 2 3 397 // 0 1 2 3
409 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 398 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
410 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 399 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
411 // | Protection Length | mask | 400 // | Protection Length | mask |
412 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 401 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
413 // | mask cont. (present only when L = 1) | 402 // | mask cont. (present only when L = 1) |
414 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 403 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
415 int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; 404 int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear;
416 const uint16_t ulp_header_size = 405 const uint16_t ulp_header_size =
417 l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear; 406 l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear;
418 407
419 RTC_DCHECK(!media_packet_list.empty()); 408 RTC_DCHECK(!media_packets.empty());
420 Packet* first_media_packet = media_packet_list.front(); 409 Packet* first_media_packet = media_packets.front().get();
421 RTC_DCHECK(first_media_packet); 410 RTC_DCHECK(first_media_packet);
422 uint16_t seq_num = ParseSequenceNumber(first_media_packet->data); 411 uint16_t seq_num = ParseSequenceNumber(first_media_packet->data);
423 for (int i = 0; i < num_fec_packets; ++i) { 412 for (int i = 0; i < num_fec_packets; ++i) {
424 Packet* const fec_packet = &generated_fec_packets_[i]; 413 Packet* const fec_packet = &generated_fec_packets_[i];
425 // -- FEC header -- 414 // -- FEC header --
426 fec_packet->data[0] &= 0x7f; // Set E to zero. 415 fec_packet->data[0] &= 0x7f; // Set E to zero.
427 if (l_bit == 0) { 416 if (l_bit == 0) {
428 fec_packet->data[0] &= 0xbf; // Clear the L bit. 417 fec_packet->data[0] &= 0xbf; // Clear the L bit.
429 } else { 418 } else {
430 fec_packet->data[0] |= 0x40; // Set the L bit. 419 fec_packet->data[0] |= 0x40; // Set the L bit.
(...skipping 10 matching lines...) Expand all
441 &fec_packet->data[10], 430 &fec_packet->data[10],
442 fec_packet->length - kFecHeaderSize - ulp_header_size); 431 fec_packet->length - kFecHeaderSize - ulp_header_size);
443 432
444 // Copy the packet mask. 433 // Copy the packet mask.
445 memcpy(&fec_packet->data[12], &packet_mask[i * num_mask_bytes], 434 memcpy(&fec_packet->data[12], &packet_mask[i * num_mask_bytes],
446 num_mask_bytes); 435 num_mask_bytes);
447 } 436 }
448 } 437 }
449 438
450 void ForwardErrorCorrection::ResetState( 439 void ForwardErrorCorrection::ResetState(
451 RecoveredPacketList* recovered_packet_list) { 440 RecoveredPacketList* recovered_packets) {
452 // Free the memory for any existing recovered packets, if the user hasn't. 441 // Free the memory for any existing recovered packets, if the user hasn't.
453 while (!recovered_packet_list->empty()) { 442 recovered_packets->clear();
454 delete recovered_packet_list->front(); 443 received_fec_packets_.clear();
455 recovered_packet_list->pop_front();
456 }
457 RTC_DCHECK(recovered_packet_list->empty());
458
459 // Free the FEC packet list.
460 while (!fec_packet_list_.empty()) {
461 FecPacket* fec_packet = fec_packet_list_.front();
462 auto protected_packet_list_it = fec_packet->protected_pkt_list.begin();
463 while (protected_packet_list_it != fec_packet->protected_pkt_list.end()) {
464 delete *protected_packet_list_it;
465 protected_packet_list_it =
466 fec_packet->protected_pkt_list.erase(protected_packet_list_it);
467 }
468 RTC_DCHECK(fec_packet->protected_pkt_list.empty());
469 delete fec_packet;
470 fec_packet_list_.pop_front();
471 }
472 RTC_DCHECK(fec_packet_list_.empty());
473 } 444 }
474 445
475 void ForwardErrorCorrection::InsertMediaPacket( 446 void ForwardErrorCorrection::InsertMediaPacket(
476 ReceivedPacket* rx_packet, 447 ReceivedPacket* rx_packet,
477 RecoveredPacketList* recovered_packet_list) { 448 RecoveredPacketList* recovered_packets) {
478 auto recovered_packet_list_it = recovered_packet_list->cbegin();
479 449
480 // Search for duplicate packets. 450 // Search for duplicate packets.
481 while (recovered_packet_list_it != recovered_packet_list->end()) { 451 for (const auto& recovered_packet : *recovered_packets) {
482 if (rx_packet->seq_num == (*recovered_packet_list_it)->seq_num) { 452 if (rx_packet->seq_num == recovered_packet->seq_num) {
483 // Duplicate packet, no need to add to list. 453 // Duplicate packet, no need to add to list.
484 // Delete duplicate media packet data. 454 // Delete duplicate media packet data.
485 rx_packet->pkt = nullptr; 455 rx_packet->pkt = nullptr;
486 return; 456 return;
487 } 457 }
488 ++recovered_packet_list_it;
489 } 458 }
490 RecoveredPacket* recovered_packet_to_insert = new RecoveredPacket(); 459 std::unique_ptr<RecoveredPacket> recovered_packet_to_insert(
460 new RecoveredPacket());
461 // This "recovered packet" was not recovered using parity packets.
491 recovered_packet_to_insert->was_recovered = false; 462 recovered_packet_to_insert->was_recovered = false;
492 // Inserted Media packet is already sent to VCM. 463 // This media packet has already been passed on.
493 recovered_packet_to_insert->returned = true; 464 recovered_packet_to_insert->returned = true;
494 recovered_packet_to_insert->seq_num = rx_packet->seq_num; 465 recovered_packet_to_insert->seq_num = rx_packet->seq_num;
495 recovered_packet_to_insert->pkt = rx_packet->pkt; 466 recovered_packet_to_insert->pkt = rx_packet->pkt;
496 recovered_packet_to_insert->pkt->length = rx_packet->pkt->length; 467 recovered_packet_to_insert->pkt->length = rx_packet->pkt->length;
497 468
469 RecoveredPacket* recovered_packet_to_insert_ptr =
470 recovered_packet_to_insert.get();
498 // TODO(holmer): Consider replacing this with a binary search for the right 471 // TODO(holmer): Consider replacing this with a binary search for the right
499 // position, and then just insert the new packet. Would get rid of the sort. 472 // position, and then just insert the new packet. Would get rid of the sort.
500 recovered_packet_list->push_back(recovered_packet_to_insert); 473 recovered_packets->push_back(std::move(recovered_packet_to_insert));
501 recovered_packet_list->sort(SortablePacket::LessThan); 474 recovered_packets->sort(SortablePacket::LessThan());
danilchap 2016/08/01 14:39:24 here SortablePacket::LessThan has to be a functor.
502 UpdateCoveringFecPackets(recovered_packet_to_insert); 475 UpdateCoveringFecPackets(recovered_packet_to_insert_ptr);
503 } 476 }
504 477
505 void ForwardErrorCorrection::UpdateCoveringFecPackets(RecoveredPacket* packet) { 478 void ForwardErrorCorrection::UpdateCoveringFecPackets(RecoveredPacket* packet) {
506 for (auto* fec_packet : fec_packet_list_) { 479 for (auto& fec_packet : received_fec_packets_) {
507 // Is this FEC packet protecting the media packet |packet|? 480 // Is this FEC packet protecting the media packet |packet|?
508 auto protected_it = std::lower_bound(fec_packet->protected_pkt_list.begin(), 481 auto protected_it = std::lower_bound(fec_packet->protected_pkt_list.begin(),
509 fec_packet->protected_pkt_list.end(), 482 fec_packet->protected_pkt_list.end(),
510 packet, 483 packet,
511 SortablePacket::LessThan); 484 SortablePacket::LessThan());
512 if (protected_it != fec_packet->protected_pkt_list.end() && 485 if (protected_it != fec_packet->protected_pkt_list.end() &&
513 (*protected_it)->seq_num == packet->seq_num) { 486 (*protected_it)->seq_num == packet->seq_num) {
514 // Found an FEC packet which is protecting |packet|. 487 // Found an FEC packet which is protecting |packet|.
515 (*protected_it)->pkt = packet->pkt; 488 (*protected_it)->pkt = packet->pkt;
516 } 489 }
517 } 490 }
518 } 491 }
519 492
520 void ForwardErrorCorrection::InsertFecPacket( 493 void ForwardErrorCorrection::InsertFecPacket(
521 ReceivedPacket* rx_packet, 494 ReceivedPacket* rx_packet,
522 const RecoveredPacketList* recovered_packet_list) { 495 const RecoveredPacketList* recovered_packets) {
523 // Check for duplicate. 496 // Check for duplicate.
524 for (auto* fec_packet : fec_packet_list_) { 497 for (const auto& existing_fec_packet : received_fec_packets_) {
525 if (rx_packet->seq_num == fec_packet->seq_num) { 498 if (rx_packet->seq_num == existing_fec_packet->seq_num) {
526 // Delete duplicate FEC packet data. 499 // Delete duplicate FEC packet data.
527 rx_packet->pkt = nullptr; 500 rx_packet->pkt = nullptr;
528 return; 501 return;
529 } 502 }
530 } 503 }
531 FecPacket* fec_packet = new FecPacket(); 504 std::unique_ptr<ReceivedFecPacket> fec_packet(new ReceivedFecPacket());
532 fec_packet->pkt = rx_packet->pkt; 505 fec_packet->pkt = rx_packet->pkt;
533 fec_packet->seq_num = rx_packet->seq_num; 506 fec_packet->seq_num = rx_packet->seq_num;
534 fec_packet->ssrc = rx_packet->ssrc; 507 fec_packet->ssrc = rx_packet->ssrc;
535 508
536 const uint16_t seq_num_base = 509 const uint16_t seq_num_base =
537 ByteReader<uint16_t>::ReadBigEndian(&fec_packet->pkt->data[2]); 510 ByteReader<uint16_t>::ReadBigEndian(&fec_packet->pkt->data[2]);
538 const uint16_t maskSizeBytes = (fec_packet->pkt->data[0] & 0x40) 511 const uint16_t maskSizeBytes = (fec_packet->pkt->data[0] & 0x40)
539 ? kMaskSizeLBitSet 512 ? kMaskSizeLBitSet
540 : kMaskSizeLBitClear; // L bit set? 513 : kMaskSizeLBitClear; // L bit set?
541 514
542 for (uint16_t byte_idx = 0; byte_idx < maskSizeBytes; ++byte_idx) { 515 for (uint16_t byte_idx = 0; byte_idx < maskSizeBytes; ++byte_idx) {
543 uint8_t packet_mask = fec_packet->pkt->data[12 + byte_idx]; 516 uint8_t packet_mask = fec_packet->pkt->data[12 + byte_idx];
544 for (uint16_t bit_idx = 0; bit_idx < 8; ++bit_idx) { 517 for (uint16_t bit_idx = 0; bit_idx < 8; ++bit_idx) {
545 if (packet_mask & (1 << (7 - bit_idx))) { 518 if (packet_mask & (1 << (7 - bit_idx))) {
546 ProtectedPacket* protected_packet = new ProtectedPacket(); 519 std::unique_ptr<ProtectedPacket> protected_packet(
547 fec_packet->protected_pkt_list.push_back(protected_packet); 520 new ProtectedPacket());
548 // This wraps naturally with the sequence number. 521 // This wraps naturally with the sequence number.
549 protected_packet->seq_num = 522 protected_packet->seq_num =
550 static_cast<uint16_t>(seq_num_base + (byte_idx << 3) + bit_idx); 523 static_cast<uint16_t>(seq_num_base + (byte_idx << 3) + bit_idx);
551 protected_packet->pkt = nullptr; 524 protected_packet->pkt = nullptr;
525 fec_packet->protected_pkt_list.push_back(std::move(protected_packet));
552 } 526 }
553 } 527 }
554 } 528 }
555 if (fec_packet->protected_pkt_list.empty()) { 529 if (fec_packet->protected_pkt_list.empty()) {
556 // All-zero packet mask; we can discard this FEC packet. 530 // All-zero packet mask; we can discard this FEC packet.
557 LOG(LS_WARNING) << "FEC packet has an all-zero packet mask."; 531 LOG(LS_WARNING) << "FEC packet has an all-zero packet mask.";
558 delete fec_packet;
559 } else { 532 } else {
560 AssignRecoveredPackets(fec_packet, recovered_packet_list); 533 AssignRecoveredPackets(fec_packet.get(), recovered_packets);
561 // TODO(holmer): Consider replacing this with a binary search for the right 534 // TODO(holmer): Consider replacing this with a binary search for the right
562 // position, and then just insert the new packet. Would get rid of the sort. 535 // position, and then just insert the new packet. Would get rid of the sort.
563 fec_packet_list_.push_back(fec_packet); 536 received_fec_packets_.push_back(std::move(fec_packet));
564 fec_packet_list_.sort(SortablePacket::LessThan); 537 received_fec_packets_.sort(SortablePacket::LessThan());
565 if (fec_packet_list_.size() > kMaxFecPackets) { 538 if (received_fec_packets_.size() > kMaxFecPackets) {
566 DiscardFecPacket(fec_packet_list_.front()); 539 received_fec_packets_.pop_front();
567 fec_packet_list_.pop_front();
568 } 540 }
569 RTC_DCHECK_LE(fec_packet_list_.size(), kMaxFecPackets); 541 RTC_DCHECK_LE(received_fec_packets_.size(), kMaxFecPackets);
570 } 542 }
571 } 543 }
572 544
573 void ForwardErrorCorrection::AssignRecoveredPackets( 545 void ForwardErrorCorrection::AssignRecoveredPackets(
574 FecPacket* fec_packet, 546 ReceivedFecPacket* fec_packet,
575 const RecoveredPacketList* recovered_packets) { 547 const RecoveredPacketList* recovered_packets) {
576 // Search for missing packets which have arrived or have been recovered by 548 ProtectedPacketList* protected_packets = &fec_packet->protected_pkt_list;
577 // another FEC packet. 549 std::vector<RecoveredPacket*> recovered_protected_packets;
578 ProtectedPacketList* not_recovered = &fec_packet->protected_pkt_list; 550
579 RecoveredPacketList already_recovered; 551 // Find intersection between the (sorted) containers |protected_packets|
580 std::set_intersection( 552 // and |recovered_packets|, i.e. all protected packets that have already
581 recovered_packets->cbegin(), recovered_packets->cend(), 553 // been recovered. Update the corresponding protected packets to point to
582 not_recovered->cbegin(), not_recovered->cend(), 554 // the recovered packets.
583 std::inserter(already_recovered, already_recovered.end()), 555 auto it_p = protected_packets->cbegin();
584 SortablePacket::LessThan); 556 auto it_r = recovered_packets->cbegin();
585 // Set the FEC pointers to all recovered packets so that we don't have to 557 SortablePacket::LessThan less_than;
stefan-webrtc 2016/08/01 11:29:51 I might be mistaking myself, but if the function w
586 // search for them when we are doing recovery. 558 while (it_p != protected_packets->end() && it_r != recovered_packets->end()) {
587 auto not_recovered_it = not_recovered->cbegin(); 559 if (less_than(*it_p, *it_r)) {
588 for (auto it = already_recovered.cbegin(); 560 ++it_p;
589 it != already_recovered.end(); ++it) { 561 } else if (less_than(*it_r, *it_p)) {
590 // Search for the next recovered packet in |not_recovered|. 562 ++it_r;
591 while ((*not_recovered_it)->seq_num != (*it)->seq_num) 563 } else { // *it_p == *it_r.
592 ++not_recovered_it; 564 // This protected packet has already been recovered.
593 (*not_recovered_it)->pkt = (*it)->pkt; 565 (*it_p)->pkt = (*it_r)->pkt;
566 ++it_p;
567 ++it_r;
568 }
594 } 569 }
595 } 570 }
596 571
597 void ForwardErrorCorrection::InsertPackets( 572 void ForwardErrorCorrection::InsertPackets(
598 ReceivedPacketList* received_packet_list, 573 ReceivedPacketList* received_packets,
599 RecoveredPacketList* recovered_packet_list) { 574 RecoveredPacketList* recovered_packets) {
600 while (!received_packet_list->empty()) { 575 while (!received_packets->empty()) {
601 ReceivedPacket* rx_packet = received_packet_list->front(); 576 ReceivedPacket* rx_packet = received_packets->front().get();
602 577
603 // Check for discarding oldest FEC packet, to avoid wrong FEC decoding from 578 // Check for discarding oldest FEC packet, to avoid wrong FEC decoding from
604 // sequence number wrap-around. Detection of old FEC packet is based on 579 // sequence number wrap-around. Detection of old FEC packet is based on
605 // sequence number difference of received packet and oldest packet in FEC 580 // sequence number difference of received packet and oldest packet in FEC
606 // packet list. 581 // packet list.
607 // TODO(marpan/holmer): We should be able to improve detection/discarding of 582 // TODO(marpan/holmer): We should be able to improve detection/discarding of
608 // old FEC packets based on timestamp information or better sequence number 583 // old FEC packets based on timestamp information or better sequence number
609 // thresholding (e.g., to distinguish between wrap-around and reordering). 584 // thresholding (e.g., to distinguish between wrap-around and reordering).
610 if (!fec_packet_list_.empty()) { 585 if (!received_fec_packets_.empty()) {
611 uint16_t seq_num_diff = 586 uint16_t seq_num_diff =
612 abs(static_cast<int>(rx_packet->seq_num) - 587 abs(static_cast<int>(rx_packet->seq_num) -
613 static_cast<int>(fec_packet_list_.front()->seq_num)); 588 static_cast<int>(received_fec_packets_.front()->seq_num));
614 if (seq_num_diff > 0x3fff) { 589 if (seq_num_diff > 0x3fff) {
615 DiscardFecPacket(fec_packet_list_.front()); 590 received_fec_packets_.pop_front();
616 fec_packet_list_.pop_front();
617 } 591 }
618 } 592 }
619 593
620 if (rx_packet->is_fec) { 594 if (rx_packet->is_fec) {
621 InsertFecPacket(rx_packet, recovered_packet_list); 595 InsertFecPacket(rx_packet, recovered_packets);
622 } else { 596 } else {
623 // Insert packet at the end of |recoveredPacketList|. 597 // Insert packet at the end of |recoveredPacketList|.
624 InsertMediaPacket(rx_packet, recovered_packet_list); 598 InsertMediaPacket(rx_packet, recovered_packets);
625 } 599 }
626 // Delete the received packet "wrapper", but not the packet data. 600 // Delete the received packet "wrapper".
627 delete rx_packet; 601 received_packets->pop_front();
628 received_packet_list->pop_front();
629 } 602 }
630 RTC_DCHECK(received_packet_list->empty()); 603 RTC_DCHECK(received_packets->empty());
631 DiscardOldPackets(recovered_packet_list); 604 DiscardOldRecoveredPackets(recovered_packets);
632 } 605 }
633 606
634 bool ForwardErrorCorrection::StartPacketRecovery(const FecPacket* fec_packet, 607 bool ForwardErrorCorrection::StartPacketRecovery(
635 RecoveredPacket* recovered) { 608 const ReceivedFecPacket* fec_packet,
609 RecoveredPacket* recovered) {
636 // This is the first packet which we try to recover with. 610 // This is the first packet which we try to recover with.
637 const uint16_t ulp_header_size = fec_packet->pkt->data[0] & 0x40 611 const uint16_t ulp_header_size = fec_packet->pkt->data[0] & 0x40
638 ? kUlpHeaderSizeLBitSet 612 ? kUlpHeaderSizeLBitSet
639 : kUlpHeaderSizeLBitClear; // L bit set? 613 : kUlpHeaderSizeLBitClear; // L bit set?
640 if (fec_packet->pkt->length < 614 if (fec_packet->pkt->length <
641 static_cast<size_t>(kFecHeaderSize + ulp_header_size)) { 615 static_cast<size_t>(kFecHeaderSize + ulp_header_size)) {
642 LOG(LS_WARNING) 616 LOG(LS_WARNING)
643 << "Truncated FEC packet doesn't contain room for ULP header."; 617 << "Truncated FEC packet doesn't contain room for ULP header.";
644 return false; 618 return false;
645 } 619 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 dst_packet->length_recovery[1] ^= media_payload_length[1]; 682 dst_packet->length_recovery[1] ^= media_payload_length[1];
709 683
710 // XOR with RTP payload. 684 // XOR with RTP payload.
711 // TODO(marpan/ajm): Are we doing more XORs than required here? 685 // TODO(marpan/ajm): Are we doing more XORs than required here?
712 for (size_t i = kRtpHeaderSize; i < src_packet->length; ++i) { 686 for (size_t i = kRtpHeaderSize; i < src_packet->length; ++i) {
713 dst_packet->pkt->data[i] ^= src_packet->data[i]; 687 dst_packet->pkt->data[i] ^= src_packet->data[i];
714 } 688 }
715 } 689 }
716 690
717 bool ForwardErrorCorrection::RecoverPacket( 691 bool ForwardErrorCorrection::RecoverPacket(
718 const FecPacket* fec_packet, 692 const ReceivedFecPacket* fec_packet,
719 RecoveredPacket* rec_packet_to_insert) { 693 RecoveredPacket* rec_packet_to_insert) {
720 if (!StartPacketRecovery(fec_packet, rec_packet_to_insert)) 694 if (!StartPacketRecovery(fec_packet, rec_packet_to_insert))
721 return false; 695 return false;
722 for (const auto* protected_packet : fec_packet->protected_pkt_list) { 696 for (const auto& protected_packet : fec_packet->protected_pkt_list) {
723 if (protected_packet->pkt == nullptr) { 697 if (protected_packet->pkt == nullptr) {
724 // This is the packet we're recovering. 698 // This is the packet we're recovering.
725 rec_packet_to_insert->seq_num = protected_packet->seq_num; 699 rec_packet_to_insert->seq_num = protected_packet->seq_num;
726 } else { 700 } else {
727 XorPackets(protected_packet->pkt, rec_packet_to_insert); 701 XorPackets(protected_packet->pkt, rec_packet_to_insert);
728 } 702 }
729 } 703 }
730 if (!FinishPacketRecovery(rec_packet_to_insert)) 704 if (!FinishPacketRecovery(rec_packet_to_insert))
731 return false; 705 return false;
732 return true; 706 return true;
733 } 707 }
734 708
735 void ForwardErrorCorrection::AttemptRecover( 709 void ForwardErrorCorrection::AttemptRecover(
736 RecoveredPacketList* recovered_packet_list) { 710 RecoveredPacketList* recovered_packets) {
737 auto fec_packet_list_it = fec_packet_list_.begin(); 711 auto fec_packet_it = received_fec_packets_.begin();
738 while (fec_packet_list_it != fec_packet_list_.end()) { 712 while (fec_packet_it != received_fec_packets_.end()) {
739 // Search for each FEC packet's protected media packets. 713 // Search for each FEC packet's protected media packets.
740 int packets_missing = NumCoveredPacketsMissing(*fec_packet_list_it); 714 int packets_missing = NumCoveredPacketsMissing(fec_packet_it->get());
741 715
742 // We can only recover one packet with an FEC packet. 716 // We can only recover one packet with an FEC packet.
743 if (packets_missing == 1) { 717 if (packets_missing == 1) {
744 // Recovery possible. 718 // Recovery possible.
745 RecoveredPacket* packet_to_insert = new RecoveredPacket(); 719 std::unique_ptr<RecoveredPacket> packet_to_insert(new RecoveredPacket());
746 packet_to_insert->pkt = nullptr; 720 packet_to_insert->pkt = nullptr;
747 if (!RecoverPacket(*fec_packet_list_it, packet_to_insert)) { 721 if (!RecoverPacket(fec_packet_it->get(), packet_to_insert.get())) {
748 // Can't recover using this packet, drop it. 722 // Can't recover using this packet, drop it.
749 DiscardFecPacket(*fec_packet_list_it); 723 fec_packet_it = received_fec_packets_.erase(fec_packet_it);
750 fec_packet_list_it = fec_packet_list_.erase(fec_packet_list_it);
751 delete packet_to_insert;
752 continue; 724 continue;
753 } 725 }
754 726
727 auto packet_to_insert_ptr = packet_to_insert.get();
755 // Add recovered packet to the list of recovered packets and update any 728 // Add recovered packet to the list of recovered packets and update any
756 // FEC packets covering this packet with a pointer to the data. 729 // FEC packets covering this packet with a pointer to the data.
757 // TODO(holmer): Consider replacing this with a binary search for the 730 // TODO(holmer): Consider replacing this with a binary search for the
758 // right position, and then just insert the new packet. Would get rid of 731 // right position, and then just insert the new packet. Would get rid of
759 // the sort. 732 // the sort.
760 recovered_packet_list->push_back(packet_to_insert); 733 recovered_packets->push_back(std::move(packet_to_insert));
761 recovered_packet_list->sort(SortablePacket::LessThan); 734 recovered_packets->sort(SortablePacket::LessThan());
762 UpdateCoveringFecPackets(packet_to_insert); 735 UpdateCoveringFecPackets(packet_to_insert_ptr);
763 DiscardOldPackets(recovered_packet_list); 736 DiscardOldRecoveredPackets(recovered_packets);
764 DiscardFecPacket(*fec_packet_list_it); 737 fec_packet_it = received_fec_packets_.erase(fec_packet_it);
765 fec_packet_list_it = fec_packet_list_.erase(fec_packet_list_it);
766 738
767 // A packet has been recovered. We need to check the FEC list again, as 739 // A packet has been recovered. We need to check the FEC list again, as
768 // this may allow additional packets to be recovered. 740 // this may allow additional packets to be recovered.
769 // Restart for first FEC packet. 741 // Restart for first FEC packet.
770 fec_packet_list_it = fec_packet_list_.begin(); 742 fec_packet_it = received_fec_packets_.begin();
771 } else if (packets_missing == 0) { 743 } else if (packets_missing == 0) {
772 // Either all protected packets arrived or have been recovered. We can 744 // Either all protected packets arrived or have been recovered. We can
773 // discard this FEC packet. 745 // discard this FEC packet.
774 DiscardFecPacket(*fec_packet_list_it); 746 fec_packet_it = received_fec_packets_.erase(fec_packet_it);
775 fec_packet_list_it = fec_packet_list_.erase(fec_packet_list_it);
776 } else { 747 } else {
777 fec_packet_list_it++; 748 fec_packet_it++;
778 } 749 }
779 } 750 }
780 } 751 }
781 752
782 int ForwardErrorCorrection::NumCoveredPacketsMissing( 753 int ForwardErrorCorrection::NumCoveredPacketsMissing(
783 const FecPacket* fec_packet) { 754 const ReceivedFecPacket* fec_packet) {
784 int packets_missing = 0; 755 int packets_missing = 0;
785 for (const auto* protected_packet : fec_packet->protected_pkt_list) { 756 for (const auto& protected_packet : fec_packet->protected_pkt_list) {
786 if (protected_packet->pkt == nullptr) { 757 if (protected_packet->pkt == nullptr) {
787 ++packets_missing; 758 ++packets_missing;
788 if (packets_missing > 1) { 759 if (packets_missing > 1) {
789 break; // We can't recover more than one packet. 760 break; // We can't recover more than one packet.
790 } 761 }
791 } 762 }
792 } 763 }
793 return packets_missing; 764 return packets_missing;
794 } 765 }
795 766
796 void ForwardErrorCorrection::DiscardFecPacket(FecPacket* fec_packet) { 767 void ForwardErrorCorrection::DiscardOldRecoveredPackets(
797 while (!fec_packet->protected_pkt_list.empty()) { 768 RecoveredPacketList* recovered_packets) {
798 delete fec_packet->protected_pkt_list.front(); 769 while (recovered_packets->size() > kMaxMediaPackets) {
799 fec_packet->protected_pkt_list.pop_front(); 770 recovered_packets->pop_front();
800 } 771 }
801 RTC_DCHECK(fec_packet->protected_pkt_list.empty()); 772 RTC_DCHECK_LE(recovered_packets->size(), kMaxMediaPackets);
802 delete fec_packet;
803 }
804
805 void ForwardErrorCorrection::DiscardOldPackets(
806 RecoveredPacketList* recovered_packet_list) {
807 while (recovered_packet_list->size() > kMaxMediaPackets) {
808 ForwardErrorCorrection::RecoveredPacket* packet =
809 recovered_packet_list->front();
810 delete packet;
811 recovered_packet_list->pop_front();
812 }
813 RTC_DCHECK(recovered_packet_list->size() <= kMaxMediaPackets);
814 } 773 }
815 774
816 uint16_t ForwardErrorCorrection::ParseSequenceNumber(uint8_t* packet) { 775 uint16_t ForwardErrorCorrection::ParseSequenceNumber(uint8_t* packet) {
817 return (packet[2] << 8) + packet[3]; 776 return (packet[2] << 8) + packet[3];
818 } 777 }
819 778
820 int ForwardErrorCorrection::DecodeFec( 779 int ForwardErrorCorrection::DecodeFec(
821 ReceivedPacketList* received_packet_list, 780 ReceivedPacketList* received_packets,
822 RecoveredPacketList* recovered_packet_list) { 781 RecoveredPacketList* recovered_packets) {
823 // TODO(marpan/ajm): can we check for multiple ULP headers, and return an 782 // TODO(marpan/ajm): can we check for multiple ULP headers, and return an
824 // error? 783 // error?
825 if (recovered_packet_list->size() == kMaxMediaPackets) { 784 if (recovered_packets->size() == kMaxMediaPackets) {
826 const unsigned int seq_num_diff = 785 const unsigned int seq_num_diff =
827 abs(static_cast<int>(received_packet_list->front()->seq_num) - 786 abs(static_cast<int>(received_packets->front()->seq_num) -
828 static_cast<int>(recovered_packet_list->back()->seq_num)); 787 static_cast<int>(recovered_packets->back()->seq_num));
829 if (seq_num_diff > kMaxMediaPackets) { 788 if (seq_num_diff > kMaxMediaPackets) {
830 // A big gap in sequence numbers. The old recovered packets 789 // A big gap in sequence numbers. The old recovered packets
831 // are now useless, so it's safe to do a reset. 790 // are now useless, so it's safe to do a reset.
832 ResetState(recovered_packet_list); 791 ResetState(recovered_packets);
833 } 792 }
834 } 793 }
835 InsertPackets(received_packet_list, recovered_packet_list); 794 InsertPackets(received_packets, recovered_packets);
836 AttemptRecover(recovered_packet_list); 795 AttemptRecover(recovered_packets);
837 return 0; 796 return 0;
838 } 797 }
839 798
840 size_t ForwardErrorCorrection::PacketOverhead() { 799 size_t ForwardErrorCorrection::PacketOverhead() {
841 return kFecHeaderSize + kUlpHeaderSizeLBitSet; 800 return kFecHeaderSize + kUlpHeaderSizeLBitSet;
842 } 801 }
843 } // namespace webrtc 802 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698