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.h" | 11 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h" |
12 | 12 |
13 #include <string.h> | 13 #include <string.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 #include <iterator> | 16 #include <iterator> |
17 #include <utility> | 17 #include <utility> |
18 | 18 |
19 #include "webrtc/base/checks.h" | 19 #include "webrtc/base/checks.h" |
20 #include "webrtc/base/logging.h" | 20 #include "webrtc/base/logging.h" |
21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | 21 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" |
22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 22 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 23 #include "webrtc/modules/rtp_rtcp/source/flexfec_header_reader_writer.h" |
| 24 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction_internal.h" |
23 #include "webrtc/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h" | 25 #include "webrtc/modules/rtp_rtcp/source/ulpfec_header_reader_writer.h" |
24 | 26 |
25 namespace webrtc { | 27 namespace webrtc { |
26 | 28 |
27 namespace { | 29 namespace { |
28 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. | 30 // Transport header size in bytes. Assume UDP/IPv4 as a reasonable minimum. |
29 constexpr size_t kTransportOverhead = 28; | 31 constexpr size_t kTransportOverhead = 28; |
30 } // namespace | 32 } // namespace |
31 | 33 |
32 ForwardErrorCorrection::Packet::Packet() : length(0), data(), ref_count_(0) {} | 34 ForwardErrorCorrection::Packet::Packet() : length(0), data(), ref_count_(0) {} |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 | 79 |
78 ForwardErrorCorrection::~ForwardErrorCorrection() = default; | 80 ForwardErrorCorrection::~ForwardErrorCorrection() = default; |
79 | 81 |
80 std::unique_ptr<ForwardErrorCorrection> ForwardErrorCorrection::CreateUlpfec() { | 82 std::unique_ptr<ForwardErrorCorrection> ForwardErrorCorrection::CreateUlpfec() { |
81 std::unique_ptr<FecHeaderReader> fec_header_reader(new UlpfecHeaderReader()); | 83 std::unique_ptr<FecHeaderReader> fec_header_reader(new UlpfecHeaderReader()); |
82 std::unique_ptr<FecHeaderWriter> fec_header_writer(new UlpfecHeaderWriter()); | 84 std::unique_ptr<FecHeaderWriter> fec_header_writer(new UlpfecHeaderWriter()); |
83 return std::unique_ptr<ForwardErrorCorrection>(new ForwardErrorCorrection( | 85 return std::unique_ptr<ForwardErrorCorrection>(new ForwardErrorCorrection( |
84 std::move(fec_header_reader), std::move(fec_header_writer))); | 86 std::move(fec_header_reader), std::move(fec_header_writer))); |
85 } | 87 } |
86 | 88 |
| 89 std::unique_ptr<ForwardErrorCorrection> |
| 90 ForwardErrorCorrection::CreateFlexfec() { |
| 91 std::unique_ptr<FecHeaderReader> fec_header_reader(new FlexfecHeaderReader()); |
| 92 std::unique_ptr<FecHeaderWriter> fec_header_writer(new FlexfecHeaderWriter()); |
| 93 return std::unique_ptr<ForwardErrorCorrection>(new ForwardErrorCorrection( |
| 94 std::move(fec_header_reader), std::move(fec_header_writer))); |
| 95 } |
| 96 |
87 int ForwardErrorCorrection::EncodeFec(const PacketList& media_packets, | 97 int ForwardErrorCorrection::EncodeFec(const PacketList& media_packets, |
88 uint8_t protection_factor, | 98 uint8_t protection_factor, |
89 int num_important_packets, | 99 int num_important_packets, |
90 bool use_unequal_protection, | 100 bool use_unequal_protection, |
91 FecMaskType fec_mask_type, | 101 FecMaskType fec_mask_type, |
92 std::list<Packet*>* fec_packets) { | 102 std::list<Packet*>* fec_packets) { |
93 const size_t num_media_packets = media_packets.size(); | 103 const size_t num_media_packets = media_packets.size(); |
94 | 104 |
95 // Sanity check arguments. | 105 // Sanity check arguments. |
96 RTC_DCHECK_GT(num_media_packets, 0u); | 106 RTC_DCHECK_GT(num_media_packets, 0u); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 int num_mask_bits = InsertZerosInPacketMasks(media_packets, num_fec_packets); | 155 int num_mask_bits = InsertZerosInPacketMasks(media_packets, num_fec_packets); |
146 if (num_mask_bits < 0) { | 156 if (num_mask_bits < 0) { |
147 return -1; | 157 return -1; |
148 } | 158 } |
149 packet_mask_size_ = internal::PacketMaskSize(num_mask_bits); | 159 packet_mask_size_ = internal::PacketMaskSize(num_mask_bits); |
150 | 160 |
151 // Write FEC packets to |generated_fec_packets_|. | 161 // Write FEC packets to |generated_fec_packets_|. |
152 GenerateFecPayloads(media_packets, num_fec_packets); | 162 GenerateFecPayloads(media_packets, num_fec_packets); |
153 // TODO(brandtr): Generalize this when multistream protection support is | 163 // TODO(brandtr): Generalize this when multistream protection support is |
154 // added. | 164 // added. |
| 165 const uint32_t ssrc = ParseSsrc(media_packets.front().get()->data); |
155 const uint16_t seq_num_base = | 166 const uint16_t seq_num_base = |
156 ParseSequenceNumber(media_packets.front().get()->data); | 167 ParseSequenceNumber(media_packets.front().get()->data); |
157 FinalizeFecHeaders(num_fec_packets, seq_num_base); | 168 FinalizeFecHeaders(num_fec_packets, ssrc, seq_num_base); |
158 | 169 |
159 return 0; | 170 return 0; |
160 } | 171 } |
161 | 172 |
162 int ForwardErrorCorrection::NumFecPackets(int num_media_packets, | 173 int ForwardErrorCorrection::NumFecPackets(int num_media_packets, |
163 int protection_factor) { | 174 int protection_factor) { |
164 // Result in Q0 with an unsigned round. | 175 // Result in Q0 with an unsigned round. |
165 int num_fec_packets = (num_media_packets * protection_factor + (1 << 7)) >> 8; | 176 int num_fec_packets = (num_media_packets * protection_factor + (1 << 7)) >> 8; |
166 // Generate at least one FEC packet if we need protection. | 177 // Generate at least one FEC packet if we need protection. |
167 if (protection_factor > 0 && num_fec_packets == 0) { | 178 if (protection_factor > 0 && num_fec_packets == 0) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 tmp_packet_masks_[new_byte_index] <<= (7 - (new_bit_index % 8)); | 309 tmp_packet_masks_[new_byte_index] <<= (7 - (new_bit_index % 8)); |
299 } | 310 } |
300 } | 311 } |
301 // Replace the old mask with the new. | 312 // Replace the old mask with the new. |
302 memcpy(packet_masks_, tmp_packet_masks_, | 313 memcpy(packet_masks_, tmp_packet_masks_, |
303 num_fec_packets * tmp_packet_mask_size); | 314 num_fec_packets * tmp_packet_mask_size); |
304 return new_bit_index; | 315 return new_bit_index; |
305 } | 316 } |
306 | 317 |
307 void ForwardErrorCorrection::FinalizeFecHeaders(size_t num_fec_packets, | 318 void ForwardErrorCorrection::FinalizeFecHeaders(size_t num_fec_packets, |
| 319 uint32_t ssrc, |
308 uint16_t seq_num_base) { | 320 uint16_t seq_num_base) { |
309 for (size_t i = 0; i < num_fec_packets; ++i) { | 321 for (size_t i = 0; i < num_fec_packets; ++i) { |
310 fec_header_writer_->FinalizeFecHeader( | 322 fec_header_writer_->FinalizeFecHeader( |
311 seq_num_base, &packet_masks_[i * packet_mask_size_], packet_mask_size_, | 323 ssrc, seq_num_base, &packet_masks_[i * packet_mask_size_], |
312 &generated_fec_packets_[i]); | 324 packet_mask_size_, &generated_fec_packets_[i]); |
313 } | 325 } |
314 } | 326 } |
315 | 327 |
316 void ForwardErrorCorrection::ResetState( | 328 void ForwardErrorCorrection::ResetState( |
317 RecoveredPacketList* recovered_packets) { | 329 RecoveredPacketList* recovered_packets) { |
318 // Free the memory for any existing recovered packets, if the caller hasn't. | 330 // Free the memory for any existing recovered packets, if the caller hasn't. |
319 recovered_packets->clear(); | 331 recovered_packets->clear(); |
320 received_fec_packets_.clear(); | 332 received_fec_packets_.clear(); |
321 } | 333 } |
322 | 334 |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 | 737 |
726 size_t FecHeaderWriter::MaxFecPackets() const { | 738 size_t FecHeaderWriter::MaxFecPackets() const { |
727 return max_fec_packets_; | 739 return max_fec_packets_; |
728 } | 740 } |
729 | 741 |
730 size_t FecHeaderWriter::MaxPacketOverhead() const { | 742 size_t FecHeaderWriter::MaxPacketOverhead() const { |
731 return max_packet_overhead_; | 743 return max_packet_overhead_; |
732 } | 744 } |
733 | 745 |
734 } // namespace webrtc | 746 } // namespace webrtc |
OLD | NEW |