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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 const int l_bit = |
206 (num_media_packets - num_fec_for_imp_packets) > 16 ? 1 : 0; | 207 (num_media_packets - num_fec_for_imp_packets) > 16 ? 1 : 0; |
207 | 208 |
208 const int res_mask_bytes = | 209 const int res_mask_bytes = (l_bit == 1) ? kUlpfecPacketMaskSizeLBitSet |
danilchap
2016/09/01 16:28:48
May be PacketMaskSize(num_media_packets - num_fec_
brandtr
2016/09/02 08:29:13
Might as well do it here, while we're at it..!
| |
209 (l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear; | 210 : kUlpfecPacketMaskSizeLBitClear; |
210 | 211 |
211 const uint8_t* packet_mask_sub_21 = | 212 const uint8_t* packet_mask_sub_21 = |
212 mask_table.fec_packet_mask_table()[num_media_packets - | 213 mask_table.fec_packet_mask_table()[num_media_packets - |
213 num_fec_for_imp_packets - | 214 num_fec_for_imp_packets - |
214 1][num_fec_remaining - 1]; | 215 1][num_fec_remaining - 1]; |
215 | 216 |
216 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, |
217 (num_fec_for_imp_packets + num_fec_remaining), | 218 (num_fec_for_imp_packets + num_fec_remaining), |
218 packet_mask_sub_21, packet_mask); | 219 packet_mask_sub_21, packet_mask); |
219 | 220 |
(...skipping 19 matching lines...) Expand all Loading... | |
239 } | 240 } |
240 } | 241 } |
241 | 242 |
242 // Protection for important (first partition) packets | 243 // Protection for important (first partition) packets |
243 void ImportantPacketProtection(int num_fec_for_imp_packets, | 244 void ImportantPacketProtection(int num_fec_for_imp_packets, |
244 int num_imp_packets, | 245 int num_imp_packets, |
245 int num_mask_bytes, | 246 int num_mask_bytes, |
246 uint8_t* packet_mask, | 247 uint8_t* packet_mask, |
247 const PacketMaskTable& mask_table) { | 248 const PacketMaskTable& mask_table) { |
248 const int l_bit = num_imp_packets > 16 ? 1 : 0; | 249 const int l_bit = num_imp_packets > 16 ? 1 : 0; |
249 const int num_imp_mask_bytes = | 250 const int num_imp_mask_bytes = (l_bit == 1) ? kUlpfecPacketMaskSizeLBitSet |
danilchap
2016/09/01 16:28:48
probably can use PacketMaskSize(num_imp_packets) h
| |
250 (l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear; | 251 : kUlpfecPacketMaskSizeLBitClear; |
251 | 252 |
252 // Get sub_mask1 from table | 253 // Get sub_mask1 from table |
253 const uint8_t* packet_mask_sub_1 = | 254 const uint8_t* packet_mask_sub_1 = |
254 mask_table.fec_packet_mask_table()[num_imp_packets - | 255 mask_table.fec_packet_mask_table()[num_imp_packets - |
255 1][num_fec_for_imp_packets - 1]; | 256 1][num_fec_for_imp_packets - 1]; |
256 | 257 |
257 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, |
258 packet_mask_sub_1, packet_mask); | 259 packet_mask_sub_1, packet_mask); |
259 } | 260 } |
260 | 261 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 int num_fec_packets, | 370 int num_fec_packets, |
370 int num_imp_packets, | 371 int num_imp_packets, |
371 bool use_unequal_protection, | 372 bool use_unequal_protection, |
372 const PacketMaskTable& mask_table, | 373 const PacketMaskTable& mask_table, |
373 uint8_t* packet_mask) { | 374 uint8_t* packet_mask) { |
374 assert(num_media_packets > 0); | 375 assert(num_media_packets > 0); |
375 assert(num_fec_packets <= num_media_packets && num_fec_packets > 0); | 376 assert(num_fec_packets <= num_media_packets && num_fec_packets > 0); |
376 assert(num_imp_packets <= num_media_packets && num_imp_packets >= 0); | 377 assert(num_imp_packets <= num_media_packets && num_imp_packets >= 0); |
377 | 378 |
378 int l_bit = num_media_packets > 16 ? 1 : 0; | 379 int l_bit = num_media_packets > 16 ? 1 : 0; |
379 const int num_mask_bytes = | 380 const int num_mask_bytes = (l_bit == 1) ? kUlpfecPacketMaskSizeLBitSet |
danilchap
2016/09/01 16:28:48
probably can use PacketMaskSize(num_media_packets)
| |
380 (l_bit == 1) ? kMaskSizeLBitSet : kMaskSizeLBitClear; | 381 : kUlpfecPacketMaskSizeLBitClear; |
381 | 382 |
382 // Equal-protection for these cases. | 383 // Equal-protection for these cases. |
383 if (!use_unequal_protection || num_imp_packets == 0) { | 384 if (!use_unequal_protection || num_imp_packets == 0) { |
384 // Retrieve corresponding mask table directly:for equal-protection case. | 385 // Retrieve corresponding mask table directly:for equal-protection case. |
385 // Mask = (k,n-k), with protection factor = (n-k)/k, | 386 // Mask = (k,n-k), with protection factor = (n-k)/k, |
386 // 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. |
387 memcpy(packet_mask, | 388 memcpy(packet_mask, |
388 mask_table.fec_packet_mask_table()[num_media_packets - | 389 mask_table.fec_packet_mask_table()[num_media_packets - |
389 1][num_fec_packets - 1], | 390 1][num_fec_packets - 1], |
390 num_fec_packets * num_mask_bytes); | 391 num_fec_packets * num_mask_bytes); |
391 } else { // UEP case | 392 } else { // UEP case |
392 UnequalProtectionMask(num_media_packets, num_fec_packets, num_imp_packets, | 393 UnequalProtectionMask(num_media_packets, num_fec_packets, num_imp_packets, |
393 num_mask_bytes, packet_mask, mask_table); | 394 num_mask_bytes, packet_mask, mask_table); |
394 } // End of UEP modification | 395 } // End of UEP modification |
395 } // End of GetPacketMasks | 396 } // End of GetPacketMasks |
396 | 397 |
398 size_t PacketMaskSize(size_t num_sequence_numbers) { | |
399 RTC_DCHECK_LE(num_sequence_numbers, 8 * kUlpfecPacketMaskSizeLBitSet); | |
400 if (num_sequence_numbers > 8 * kUlpfecPacketMaskSizeLBitClear) { | |
401 return kUlpfecPacketMaskSizeLBitSet; | |
402 } | |
403 return kUlpfecPacketMaskSizeLBitClear; | |
404 } | |
405 | |
397 void InsertZeroColumns(int num_zeros, | 406 void InsertZeroColumns(int num_zeros, |
398 uint8_t* new_mask, | 407 uint8_t* new_mask, |
399 int new_mask_bytes, | 408 int new_mask_bytes, |
400 int num_fec_packets, | 409 int num_fec_packets, |
401 int new_bit_index) { | 410 int new_bit_index) { |
402 for (uint16_t row = 0; row < num_fec_packets; ++row) { | 411 for (uint16_t row = 0; row < num_fec_packets; ++row) { |
403 const int new_byte_index = row * new_mask_bytes + new_bit_index / 8; | 412 const int new_byte_index = row * new_mask_bytes + new_bit_index / 8; |
404 const int max_shifts = (7 - (new_bit_index % 8)); | 413 const int max_shifts = (7 - (new_bit_index % 8)); |
405 new_mask[new_byte_index] <<= std::min(num_zeros, max_shifts); | 414 new_mask[new_byte_index] <<= std::min(num_zeros, max_shifts); |
406 } | 415 } |
(...skipping 14 matching lines...) Expand all Loading... | |
421 new_mask[new_byte_index] |= ((old_mask[old_byte_index] & 0x80) >> 7); | 430 new_mask[new_byte_index] |= ((old_mask[old_byte_index] & 0x80) >> 7); |
422 if (new_bit_index % 8 != 7) { | 431 if (new_bit_index % 8 != 7) { |
423 new_mask[new_byte_index] <<= 1; | 432 new_mask[new_byte_index] <<= 1; |
424 } | 433 } |
425 old_mask[old_byte_index] <<= 1; | 434 old_mask[old_byte_index] <<= 1; |
426 } | 435 } |
427 } | 436 } |
428 | 437 |
429 } // namespace internal | 438 } // namespace internal |
430 } // namespace webrtc | 439 } // namespace webrtc |
OLD | NEW |