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 |