| 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 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h" | 11 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h" |
| 12 | 12 |
| 13 #include <assert.h> | 13 #include <assert.h> |
| 14 #include <string.h> | 14 #include <string.h> |
| 15 | 15 |
| 16 #include <algorithm> | 16 #include <algorithm> |
| 17 | 17 |
| 18 #include "webrtc/base/checks.h" |
| 18 #include "webrtc/modules/rtp_rtcp/source/fec_private_tables_bursty.h" | 19 #include "webrtc/modules/rtp_rtcp/source/fec_private_tables_bursty.h" |
| 19 #include "webrtc/modules/rtp_rtcp/source/fec_private_tables_random.h" | 20 #include "webrtc/modules/rtp_rtcp/source/fec_private_tables_random.h" |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 using webrtc::fec_private_tables::kPacketMaskBurstyTbl; | 23 using webrtc::fec_private_tables::kPacketMaskBurstyTbl; |
| 23 using webrtc::fec_private_tables::kPacketMaskRandomTbl; | 24 using webrtc::fec_private_tables::kPacketMaskRandomTbl; |
| 24 | 25 |
| 25 // Allow for different modes of protection for packets in UEP case. | 26 // Allow for different modes of protection for packets in UEP case. |
| 26 enum ProtectionMode { | 27 enum ProtectionMode { |
| 27 kModeNoOverlap, | 28 kModeNoOverlap, |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 void RemainingPacketProtection(int num_media_packets, | 196 void RemainingPacketProtection(int num_media_packets, |
| 196 int num_fec_remaining, | 197 int num_fec_remaining, |
| 197 int num_fec_for_imp_packets, | 198 int num_fec_for_imp_packets, |
| 198 int num_mask_bytes, | 199 int num_mask_bytes, |
| 199 ProtectionMode mode, | 200 ProtectionMode mode, |
| 200 uint8_t* packet_mask, | 201 uint8_t* packet_mask, |
| 201 const PacketMaskTable& mask_table) { | 202 const PacketMaskTable& mask_table) { |
| 202 if (mode == kModeNoOverlap) { | 203 if (mode == kModeNoOverlap) { |
| 203 // sub_mask21 | 204 // sub_mask21 |
| 204 | 205 |
| 205 const int l_bit = | |
| 206 (num_media_packets - num_fec_for_imp_packets) > 16 ? 1 : 0; | |
| 207 | |
| 208 const int res_mask_bytes = | 206 const int res_mask_bytes = |
| 209 (l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear; | 207 PacketMaskSize(num_media_packets - num_fec_for_imp_packets); |
| 210 | 208 |
| 211 const uint8_t* packet_mask_sub_21 = | 209 const uint8_t* packet_mask_sub_21 = |
| 212 mask_table.fec_packet_mask_table()[num_media_packets - | 210 mask_table.fec_packet_mask_table()[num_media_packets - |
| 213 num_fec_for_imp_packets - | 211 num_fec_for_imp_packets - |
| 214 1][num_fec_remaining - 1]; | 212 1][num_fec_remaining - 1]; |
| 215 | 213 |
| 216 ShiftFitSubMask(num_mask_bytes, res_mask_bytes, num_fec_for_imp_packets, | 214 ShiftFitSubMask(num_mask_bytes, res_mask_bytes, num_fec_for_imp_packets, |
| 217 (num_fec_for_imp_packets + num_fec_remaining), | 215 (num_fec_for_imp_packets + num_fec_remaining), |
| 218 packet_mask_sub_21, packet_mask); | 216 packet_mask_sub_21, packet_mask); |
| 219 | 217 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 238 assert(false); | 236 assert(false); |
| 239 } | 237 } |
| 240 } | 238 } |
| 241 | 239 |
| 242 // Protection for important (first partition) packets | 240 // Protection for important (first partition) packets |
| 243 void ImportantPacketProtection(int num_fec_for_imp_packets, | 241 void ImportantPacketProtection(int num_fec_for_imp_packets, |
| 244 int num_imp_packets, | 242 int num_imp_packets, |
| 245 int num_mask_bytes, | 243 int num_mask_bytes, |
| 246 uint8_t* packet_mask, | 244 uint8_t* packet_mask, |
| 247 const PacketMaskTable& mask_table) { | 245 const PacketMaskTable& mask_table) { |
| 248 const int l_bit = num_imp_packets > 16 ? 1 : 0; | 246 const int num_imp_mask_bytes = PacketMaskSize(num_imp_packets); |
| 249 const int num_imp_mask_bytes = | |
| 250 (l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear; | |
| 251 | 247 |
| 252 // Get sub_mask1 from table | 248 // Get sub_mask1 from table |
| 253 const uint8_t* packet_mask_sub_1 = | 249 const uint8_t* packet_mask_sub_1 = |
| 254 mask_table.fec_packet_mask_table()[num_imp_packets - | 250 mask_table.fec_packet_mask_table()[num_imp_packets - |
| 255 1][num_fec_for_imp_packets - 1]; | 251 1][num_fec_for_imp_packets - 1]; |
| 256 | 252 |
| 257 FitSubMask(num_mask_bytes, num_imp_mask_bytes, num_fec_for_imp_packets, | 253 FitSubMask(num_mask_bytes, num_imp_mask_bytes, num_fec_for_imp_packets, |
| 258 packet_mask_sub_1, packet_mask); | 254 packet_mask_sub_1, packet_mask); |
| 259 } | 255 } |
| 260 | 256 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 void GeneratePacketMasks(int num_media_packets, | 364 void GeneratePacketMasks(int num_media_packets, |
| 369 int num_fec_packets, | 365 int num_fec_packets, |
| 370 int num_imp_packets, | 366 int num_imp_packets, |
| 371 bool use_unequal_protection, | 367 bool use_unequal_protection, |
| 372 const PacketMaskTable& mask_table, | 368 const PacketMaskTable& mask_table, |
| 373 uint8_t* packet_mask) { | 369 uint8_t* packet_mask) { |
| 374 assert(num_media_packets > 0); | 370 assert(num_media_packets > 0); |
| 375 assert(num_fec_packets <= num_media_packets && num_fec_packets > 0); | 371 assert(num_fec_packets <= num_media_packets && num_fec_packets > 0); |
| 376 assert(num_imp_packets <= num_media_packets && num_imp_packets >= 0); | 372 assert(num_imp_packets <= num_media_packets && num_imp_packets >= 0); |
| 377 | 373 |
| 378 int l_bit = num_media_packets > 16 ? 1 : 0; | 374 const int num_mask_bytes = PacketMaskSize(num_media_packets); |
| 379 const int num_mask_bytes = | |
| 380 (l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear; | |
| 381 | 375 |
| 382 // Equal-protection for these cases. | 376 // Equal-protection for these cases. |
| 383 if (!use_unequal_protection || num_imp_packets == 0) { | 377 if (!use_unequal_protection || num_imp_packets == 0) { |
| 384 // Retrieve corresponding mask table directly:for equal-protection case. | 378 // Retrieve corresponding mask table directly:for equal-protection case. |
| 385 // Mask = (k,n-k), with protection factor = (n-k)/k, | 379 // Mask = (k,n-k), with protection factor = (n-k)/k, |
| 386 // where k = num_media_packets, n=total#packets, (n-k)=num_fec_packets. | 380 // where k = num_media_packets, n=total#packets, (n-k)=num_fec_packets. |
| 387 memcpy(packet_mask, | 381 memcpy(packet_mask, |
| 388 mask_table.fec_packet_mask_table()[num_media_packets - | 382 mask_table.fec_packet_mask_table()[num_media_packets - |
| 389 1][num_fec_packets - 1], | 383 1][num_fec_packets - 1], |
| 390 num_fec_packets * num_mask_bytes); | 384 num_fec_packets * num_mask_bytes); |
| 391 } else { // UEP case | 385 } else { // UEP case |
| 392 UnequalProtectionMask(num_media_packets, num_fec_packets, num_imp_packets, | 386 UnequalProtectionMask(num_media_packets, num_fec_packets, num_imp_packets, |
| 393 num_mask_bytes, packet_mask, mask_table); | 387 num_mask_bytes, packet_mask, mask_table); |
| 394 } // End of UEP modification | 388 } // End of UEP modification |
| 395 } // End of GetPacketMasks | 389 } // End of GetPacketMasks |
| 396 | 390 |
| 391 size_t PacketMaskSize(size_t num_sequence_numbers) { |
| 392 RTC_DCHECK_LE(num_sequence_numbers, 8 * kUlpfecPacketMaskSizeLBitSet); |
| 393 if (num_sequence_numbers > 8 * kUlpfecPacketMaskSizeLBitClear) { |
| 394 return kUlpfecPacketMaskSizeLBitSet; |
| 395 } |
| 396 return kUlpfecPacketMaskSizeLBitClear; |
| 397 } |
| 398 |
| 397 void InsertZeroColumns(int num_zeros, | 399 void InsertZeroColumns(int num_zeros, |
| 398 uint8_t* new_mask, | 400 uint8_t* new_mask, |
| 399 int new_mask_bytes, | 401 int new_mask_bytes, |
| 400 int num_fec_packets, | 402 int num_fec_packets, |
| 401 int new_bit_index) { | 403 int new_bit_index) { |
| 402 for (uint16_t row = 0; row < num_fec_packets; ++row) { | 404 for (uint16_t row = 0; row < num_fec_packets; ++row) { |
| 403 const int new_byte_index = row * new_mask_bytes + new_bit_index / 8; | 405 const int new_byte_index = row * new_mask_bytes + new_bit_index / 8; |
| 404 const int max_shifts = (7 - (new_bit_index % 8)); | 406 const int max_shifts = (7 - (new_bit_index % 8)); |
| 405 new_mask[new_byte_index] <<= std::min(num_zeros, max_shifts); | 407 new_mask[new_byte_index] <<= std::min(num_zeros, max_shifts); |
| 406 } | 408 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 421 new_mask[new_byte_index] |= ((old_mask[old_byte_index] & 0x80) >> 7); | 423 new_mask[new_byte_index] |= ((old_mask[old_byte_index] & 0x80) >> 7); |
| 422 if (new_bit_index % 8 != 7) { | 424 if (new_bit_index % 8 != 7) { |
| 423 new_mask[new_byte_index] <<= 1; | 425 new_mask[new_byte_index] <<= 1; |
| 424 } | 426 } |
| 425 old_mask[old_byte_index] <<= 1; | 427 old_mask[old_byte_index] <<= 1; |
| 426 } | 428 } |
| 427 } | 429 } |
| 428 | 430 |
| 429 } // namespace internal | 431 } // namespace internal |
| 430 } // namespace webrtc | 432 } // namespace webrtc |
| OLD | NEW |