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