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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 return; | 210 return; |
211 } | 211 } |
212 uint8_t media_payload_length[2]; | 212 uint8_t media_payload_length[2]; |
213 const int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; | 213 const int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; |
214 const uint16_t ulp_header_size = | 214 const uint16_t ulp_header_size = |
215 l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear; | 215 l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear; |
216 const uint16_t fec_rtp_offset = | 216 const uint16_t fec_rtp_offset = |
217 kFecHeaderSize + ulp_header_size - kRtpHeaderSize; | 217 kFecHeaderSize + ulp_header_size - kRtpHeaderSize; |
218 | 218 |
219 for (int i = 0; i < num_fec_packets; ++i) { | 219 for (int i = 0; i < num_fec_packets; ++i) { |
| 220 Packet* const fec_packet = &generated_fec_packets_[i]; |
220 PacketList::const_iterator media_list_it = media_packet_list.begin(); | 221 PacketList::const_iterator media_list_it = media_packet_list.begin(); |
221 uint32_t pkt_mask_idx = i * num_mask_bytes; | 222 uint32_t pkt_mask_idx = i * num_mask_bytes; |
222 uint32_t media_pkt_idx = 0; | 223 uint32_t media_pkt_idx = 0; |
223 uint16_t fec_packet_length = 0; | 224 uint16_t fec_packet_length = 0; |
224 uint16_t prev_seq_num = ParseSequenceNumber((*media_list_it)->data); | 225 uint16_t prev_seq_num = ParseSequenceNumber((*media_list_it)->data); |
225 while (media_list_it != media_packet_list.end()) { | 226 while (media_list_it != media_packet_list.end()) { |
226 // Each FEC packet has a multiple byte mask. Determine if this media | 227 // Each FEC packet has a multiple byte mask. Determine if this media |
227 // packet should be included in FEC packet i. | 228 // packet should be included in FEC packet i. |
228 if (packet_mask[pkt_mask_idx] & (1 << (7 - media_pkt_idx))) { | 229 if (packet_mask[pkt_mask_idx] & (1 << (7 - media_pkt_idx))) { |
229 Packet* media_packet = *media_list_it; | 230 Packet* media_packet = *media_list_it; |
230 | 231 |
231 // Assign network-ordered media payload length. | 232 // Assign network-ordered media payload length. |
232 ByteWriter<uint16_t>::WriteBigEndian( | 233 ByteWriter<uint16_t>::WriteBigEndian( |
233 media_payload_length, media_packet->length - kRtpHeaderSize); | 234 media_payload_length, media_packet->length - kRtpHeaderSize); |
234 | 235 |
235 fec_packet_length = media_packet->length + fec_rtp_offset; | 236 fec_packet_length = media_packet->length + fec_rtp_offset; |
236 // On the first protected packet, we don't need to XOR. | 237 // On the first protected packet, we don't need to XOR. |
237 if (generated_fec_packets_[i].length == 0) { | 238 if (fec_packet->length == 0) { |
238 // Copy the first 2 bytes of the RTP header. | 239 // Copy the first 2 bytes of the RTP header. |
239 memcpy(generated_fec_packets_[i].data, media_packet->data, 2); | 240 memcpy(fec_packet->data, media_packet->data, 2); |
240 // Copy the 5th to 8th bytes of the RTP header. | 241 // Copy the 5th to 8th bytes of the RTP header. |
241 memcpy(&generated_fec_packets_[i].data[4], &media_packet->data[4], 4); | 242 memcpy(&fec_packet->data[4], &media_packet->data[4], 4); |
242 // Copy network-ordered payload size. | 243 // Copy network-ordered payload size. |
243 memcpy(&generated_fec_packets_[i].data[8], media_payload_length, 2); | 244 memcpy(&fec_packet->data[8], media_payload_length, 2); |
244 | 245 |
245 // Copy RTP payload, leaving room for the ULP header. | 246 // Copy RTP payload, leaving room for the ULP header. |
246 memcpy( | 247 memcpy(&fec_packet->data[kFecHeaderSize + ulp_header_size], |
247 &generated_fec_packets_[i].data[kFecHeaderSize + ulp_header_size], | 248 &media_packet->data[kRtpHeaderSize], |
248 &media_packet->data[kRtpHeaderSize], | 249 media_packet->length - kRtpHeaderSize); |
249 media_packet->length - kRtpHeaderSize); | |
250 } else { | 250 } else { |
251 // XOR with the first 2 bytes of the RTP header. | 251 // XOR with the first 2 bytes of the RTP header. |
252 generated_fec_packets_[i].data[0] ^= media_packet->data[0]; | 252 fec_packet->data[0] ^= media_packet->data[0]; |
253 generated_fec_packets_[i].data[1] ^= media_packet->data[1]; | 253 fec_packet->data[1] ^= media_packet->data[1]; |
254 | 254 |
255 // XOR with the 5th to 8th bytes of the RTP header. | 255 // XOR with the 5th to 8th bytes of the RTP header. |
256 for (uint32_t j = 4; j < 8; ++j) { | 256 for (uint32_t j = 4; j < 8; ++j) { |
257 generated_fec_packets_[i].data[j] ^= media_packet->data[j]; | 257 fec_packet->data[j] ^= media_packet->data[j]; |
258 } | 258 } |
259 | 259 |
260 // XOR with the network-ordered payload size. | 260 // XOR with the network-ordered payload size. |
261 generated_fec_packets_[i].data[8] ^= media_payload_length[0]; | 261 fec_packet->data[8] ^= media_payload_length[0]; |
262 generated_fec_packets_[i].data[9] ^= media_payload_length[1]; | 262 fec_packet->data[9] ^= media_payload_length[1]; |
263 | 263 |
264 // XOR with RTP payload, leaving room for the ULP header. | 264 // XOR with RTP payload, leaving room for the ULP header. |
265 for (int32_t j = kFecHeaderSize + ulp_header_size; | 265 for (int32_t j = kFecHeaderSize + ulp_header_size; |
266 j < fec_packet_length; j++) { | 266 j < fec_packet_length; j++) { |
267 generated_fec_packets_[i].data[j] ^= | 267 fec_packet->data[j] ^= media_packet->data[j - fec_rtp_offset]; |
268 media_packet->data[j - fec_rtp_offset]; | |
269 } | 268 } |
270 } | 269 } |
271 if (fec_packet_length > generated_fec_packets_[i].length) { | 270 if (fec_packet_length > fec_packet->length) { |
272 generated_fec_packets_[i].length = fec_packet_length; | 271 fec_packet->length = fec_packet_length; |
273 } | 272 } |
274 } | 273 } |
275 media_list_it++; | 274 media_list_it++; |
276 if (media_list_it != media_packet_list.end()) { | 275 if (media_list_it != media_packet_list.end()) { |
277 uint16_t seq_num = ParseSequenceNumber((*media_list_it)->data); | 276 uint16_t seq_num = ParseSequenceNumber((*media_list_it)->data); |
278 media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num); | 277 media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num); |
279 prev_seq_num = seq_num; | 278 prev_seq_num = seq_num; |
280 } | 279 } |
281 pkt_mask_idx += media_pkt_idx / 8; | 280 pkt_mask_idx += media_pkt_idx / 8; |
282 media_pkt_idx %= 8; | 281 media_pkt_idx %= 8; |
283 } | 282 } |
284 RTC_DCHECK_GT(generated_fec_packets_[i].length, 0u) | 283 RTC_DCHECK_GT(fec_packet->length, 0u) |
285 << "Packet mask is wrong or poorly designed."; | 284 << "Packet mask is wrong or poorly designed."; |
286 } | 285 } |
287 } | 286 } |
288 | 287 |
289 int ForwardErrorCorrection::InsertZerosInBitMasks( | 288 int ForwardErrorCorrection::InsertZerosInBitMasks( |
290 const PacketList& media_packets, | 289 const PacketList& media_packets, |
291 uint8_t* packet_mask, | 290 uint8_t* packet_mask, |
292 int num_mask_bytes, | 291 int num_mask_bytes, |
293 int num_fec_packets) { | 292 int num_fec_packets) { |
294 uint8_t* new_mask = NULL; | 293 uint8_t* new_mask = NULL; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 // | mask cont. (present only when L = 1) | | 416 // | mask cont. (present only when L = 1) | |
418 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 417 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
419 PacketList::const_iterator media_list_it = media_packet_list.begin(); | 418 PacketList::const_iterator media_list_it = media_packet_list.begin(); |
420 Packet* media_packet = *media_list_it; | 419 Packet* media_packet = *media_list_it; |
421 assert(media_packet != NULL); | 420 assert(media_packet != NULL); |
422 int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; | 421 int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; |
423 const uint16_t ulp_header_size = | 422 const uint16_t ulp_header_size = |
424 l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear; | 423 l_bit ? kUlpHeaderSizeLBitSet : kUlpHeaderSizeLBitClear; |
425 | 424 |
426 for (int i = 0; i < num_fec_packets; ++i) { | 425 for (int i = 0; i < num_fec_packets; ++i) { |
| 426 Packet* const fec_packet = &generated_fec_packets_[i]; |
427 // -- FEC header -- | 427 // -- FEC header -- |
428 generated_fec_packets_[i].data[0] &= 0x7f; // Set E to zero. | 428 fec_packet->data[0] &= 0x7f; // Set E to zero. |
429 if (l_bit == 0) { | 429 if (l_bit == 0) { |
430 generated_fec_packets_[i].data[0] &= 0xbf; // Clear the L bit. | 430 fec_packet->data[0] &= 0xbf; // Clear the L bit. |
431 } else { | 431 } else { |
432 generated_fec_packets_[i].data[0] |= 0x40; // Set the L bit. | 432 fec_packet->data[0] |= 0x40; // Set the L bit. |
433 } | 433 } |
434 // Two byte sequence number from first RTP packet to SN base. | 434 // Two byte sequence number from first RTP packet to SN base. |
435 // We use the same sequence number base for every FEC packet, | 435 // We use the same sequence number base for every FEC packet, |
436 // but that's not required in general. | 436 // but that's not required in general. |
437 memcpy(&generated_fec_packets_[i].data[2], &media_packet->data[2], 2); | 437 memcpy(&fec_packet->data[2], &media_packet->data[2], 2); |
438 | 438 |
439 // -- ULP header -- | 439 // -- ULP header -- |
440 // Copy the payload size to the protection length field. | 440 // Copy the payload size to the protection length field. |
441 // (We protect the entire packet.) | 441 // (We protect the entire packet.) |
442 ByteWriter<uint16_t>::WriteBigEndian( | 442 ByteWriter<uint16_t>::WriteBigEndian( |
443 &generated_fec_packets_[i].data[10], | 443 &fec_packet->data[10], |
444 generated_fec_packets_[i].length - kFecHeaderSize - ulp_header_size); | 444 fec_packet->length - kFecHeaderSize - ulp_header_size); |
445 | 445 |
446 // Copy the packet mask. | 446 // Copy the packet mask. |
447 memcpy(&generated_fec_packets_[i].data[12], | 447 memcpy(&fec_packet->data[12], &packet_mask[i * num_mask_bytes], |
448 &packet_mask[i * num_mask_bytes], num_mask_bytes); | 448 num_mask_bytes); |
449 } | 449 } |
450 } | 450 } |
451 | 451 |
452 void ForwardErrorCorrection::ResetState( | 452 void ForwardErrorCorrection::ResetState( |
453 RecoveredPacketList* recovered_packet_list) { | 453 RecoveredPacketList* recovered_packet_list) { |
454 fec_packet_received_ = false; | 454 fec_packet_received_ = false; |
455 | 455 |
456 // Free the memory for any existing recovered packets, if the user hasn't. | 456 // Free the memory for any existing recovered packets, if the user hasn't. |
457 while (!recovered_packet_list->empty()) { | 457 while (!recovered_packet_list->empty()) { |
458 delete recovered_packet_list->front(); | 458 delete recovered_packet_list->front(); |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 } | 850 } |
851 InsertPackets(received_packet_list, recovered_packet_list); | 851 InsertPackets(received_packet_list, recovered_packet_list); |
852 AttemptRecover(recovered_packet_list); | 852 AttemptRecover(recovered_packet_list); |
853 return 0; | 853 return 0; |
854 } | 854 } |
855 | 855 |
856 size_t ForwardErrorCorrection::PacketOverhead() { | 856 size_t ForwardErrorCorrection::PacketOverhead() { |
857 return kFecHeaderSize + kUlpHeaderSizeLBitSet; | 857 return kFecHeaderSize + kUlpHeaderSizeLBitSet; |
858 } | 858 } |
859 } // namespace webrtc | 859 } // namespace webrtc |
OLD | NEW |