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 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 total_missing_seq_nums > 8 * kMaskSizeLBitClear) { | 299 total_missing_seq_nums > 8 * kMaskSizeLBitClear) { |
300 new_mask_bytes = kMaskSizeLBitSet; | 300 new_mask_bytes = kMaskSizeLBitSet; |
301 } | 301 } |
302 memset(tmp_packet_mask_, 0, num_fec_packets * kMaskSizeLBitSet); | 302 memset(tmp_packet_mask_, 0, num_fec_packets * kMaskSizeLBitSet); |
303 | 303 |
304 auto media_packets_it = media_packets.cbegin(); | 304 auto media_packets_it = media_packets.cbegin(); |
305 uint16_t prev_seq_num = first_seq_num; | 305 uint16_t prev_seq_num = first_seq_num; |
306 ++media_packets_it; | 306 ++media_packets_it; |
307 | 307 |
308 // Insert the first column. | 308 // Insert the first column. |
309 CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask, num_mask_bytes, | 309 internal::CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask_, |
310 num_fec_packets, 0, 0); | 310 num_mask_bytes, num_fec_packets, 0, 0); |
311 int new_bit_index = 1; | 311 size_t new_bit_index = 1; |
312 int old_bit_index = 1; | 312 size_t old_bit_index = 1; |
313 // 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. |
314 while (media_packets_it != media_packets.end()) { | 314 while (media_packets_it != media_packets.end()) { |
315 if (new_bit_index == 8 * kMaskSizeLBitSet) { | 315 if (new_bit_index == 8 * kMaskSizeLBitSet) { |
316 // We can only cover up to 48 packets. | 316 // We can only cover up to 48 packets. |
317 break; | 317 break; |
318 } | 318 } |
319 uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data); | 319 uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data); |
320 const int zeros_to_insert = | 320 const int num_zeros_to_insert = |
321 static_cast<uint16_t>(seq_num - prev_seq_num - 1); | 321 static_cast<uint16_t>(seq_num - prev_seq_num - 1); |
322 if (zeros_to_insert > 0) { | 322 if (num_zeros_to_insert > 0) { |
323 InsertZeroColumns(zeros_to_insert, tmp_packet_mask_, new_mask_bytes, | 323 internal::InsertZeroColumns(num_zeros_to_insert, tmp_packet_mask_, |
324 num_fec_packets, new_bit_index); | 324 new_mask_bytes, num_fec_packets, |
| 325 new_bit_index); |
325 } | 326 } |
326 new_bit_index += zeros_to_insert; | 327 new_bit_index += num_zeros_to_insert; |
327 CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask, num_mask_bytes, | 328 internal::CopyColumn(tmp_packet_mask_, new_mask_bytes, packet_mask_, |
328 num_fec_packets, new_bit_index, old_bit_index); | 329 num_mask_bytes, num_fec_packets, new_bit_index, |
| 330 old_bit_index); |
329 ++new_bit_index; | 331 ++new_bit_index; |
330 ++old_bit_index; | 332 ++old_bit_index; |
331 prev_seq_num = seq_num; | 333 prev_seq_num = seq_num; |
332 ++media_packets_it; | 334 ++media_packets_it; |
333 } | 335 } |
334 if (new_bit_index % 8 != 0) { | 336 if (new_bit_index % 8 != 0) { |
335 // We didn't fill the last byte. Shift bits to correct position. | 337 // We didn't fill the last byte. Shift bits to correct position. |
336 for (uint16_t row = 0; row < num_fec_packets; ++row) { | 338 for (uint16_t row = 0; row < num_fec_packets; ++row) { |
337 int new_byte_index = row * new_mask_bytes + new_bit_index / 8; | 339 int new_byte_index = row * new_mask_bytes + new_bit_index / 8; |
338 tmp_packet_mask_[new_byte_index] <<= (7 - (new_bit_index % 8)); | 340 tmp_packet_mask_[new_byte_index] <<= (7 - (new_bit_index % 8)); |
339 } | 341 } |
340 } | 342 } |
341 // Replace the old mask with the new. | 343 // Replace the old mask with the new. |
342 memcpy(packet_mask, tmp_packet_mask_, kMaskSizeLBitSet * num_fec_packets); | 344 memcpy(packet_mask, tmp_packet_mask_, kMaskSizeLBitSet * num_fec_packets); |
343 return new_bit_index; | 345 return new_bit_index; |
344 } | 346 } |
345 | 347 |
346 void ForwardErrorCorrection::InsertZeroColumns(int num_zeros, | |
347 uint8_t* new_mask, | |
348 int new_mask_bytes, | |
349 int num_fec_packets, | |
350 int new_bit_index) { | |
351 for (uint16_t row = 0; row < num_fec_packets; ++row) { | |
352 const int new_byte_index = row * new_mask_bytes + new_bit_index / 8; | |
353 const int max_shifts = (7 - (new_bit_index % 8)); | |
354 new_mask[new_byte_index] <<= std::min(num_zeros, max_shifts); | |
355 } | |
356 } | |
357 | |
358 void ForwardErrorCorrection::CopyColumn(uint8_t* new_mask, | |
359 int new_mask_bytes, | |
360 uint8_t* old_mask, | |
361 int old_mask_bytes, | |
362 int num_fec_packets, | |
363 int new_bit_index, | |
364 int old_bit_index) { | |
365 // Copy column from the old mask to the beginning of the new mask and shift it | |
366 // out from the old mask. | |
367 for (uint16_t row = 0; row < num_fec_packets; ++row) { | |
368 int new_byte_index = row * new_mask_bytes + new_bit_index / 8; | |
369 int old_byte_index = row * old_mask_bytes + old_bit_index / 8; | |
370 new_mask[new_byte_index] |= ((old_mask[old_byte_index] & 0x80) >> 7); | |
371 if (new_bit_index % 8 != 7) { | |
372 new_mask[new_byte_index] <<= 1; | |
373 } | |
374 old_mask[old_byte_index] <<= 1; | |
375 } | |
376 } | |
377 | |
378 void ForwardErrorCorrection::GenerateFecUlpHeaders( | 348 void ForwardErrorCorrection::GenerateFecUlpHeaders( |
379 const PacketList& media_packets, | 349 const PacketList& media_packets, |
380 uint8_t* packet_mask, | 350 uint8_t* packet_mask, |
381 int num_fec_packets, | 351 int num_fec_packets, |
382 bool l_bit) { | 352 bool l_bit) { |
383 // -- Generate FEC and ULP headers -- | 353 // -- Generate FEC and ULP headers -- |
384 // | 354 // |
385 // FEC Header, 10 bytes | 355 // FEC Header, 10 bytes |
386 // 0 1 2 3 | 356 // 0 1 2 3 |
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 | 357 // 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 |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 } | 773 } |
804 InsertPackets(received_packets, recovered_packets); | 774 InsertPackets(received_packets, recovered_packets); |
805 AttemptRecover(recovered_packets); | 775 AttemptRecover(recovered_packets); |
806 return 0; | 776 return 0; |
807 } | 777 } |
808 | 778 |
809 size_t ForwardErrorCorrection::PacketOverhead() { | 779 size_t ForwardErrorCorrection::PacketOverhead() { |
810 return kFecHeaderSize + kUlpHeaderSizeLBitSet; | 780 return kFecHeaderSize + kUlpHeaderSizeLBitSet; |
811 } | 781 } |
812 } // namespace webrtc | 782 } // namespace webrtc |
OLD | NEW |