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 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 if (num_media_packets > kMaxMediaPackets) { | 112 if (num_media_packets > kMaxMediaPackets) { |
113 LOG(LS_WARNING) << "Can't protect " << num_media_packets | 113 LOG(LS_WARNING) << "Can't protect " << num_media_packets |
114 << " media packets per frame. Max is " << kMaxMediaPackets | 114 << " media packets per frame. Max is " << kMaxMediaPackets |
115 << "."; | 115 << "."; |
116 return -1; | 116 return -1; |
117 } | 117 } |
118 | 118 |
119 bool l_bit = (num_media_packets > 8 * kMaskSizeLBitClear); | 119 bool l_bit = (num_media_packets > 8 * kMaskSizeLBitClear); |
120 int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; | 120 int num_mask_bytes = l_bit ? kMaskSizeLBitSet : kMaskSizeLBitClear; |
121 | 121 |
122 // Do some error checking on the media packets. | 122 // Error check the media packets. |
123 for (const auto& media_packet : media_packets) { | 123 for (const auto& media_packet : media_packets) { |
124 RTC_DCHECK(media_packet); | 124 RTC_DCHECK(media_packet); |
125 | |
126 if (media_packet->length < kRtpHeaderSize) { | 125 if (media_packet->length < kRtpHeaderSize) { |
127 LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes " | 126 LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes " |
128 << "is smaller than RTP header."; | 127 << "is smaller than RTP header."; |
129 return -1; | 128 return -1; |
130 } | 129 } |
131 | 130 // Ensure the FEC packets will fit in a typical MTU. |
132 // Ensure our FEC packets will fit in a typical MTU. | 131 if (media_packet->length + MaxPacketOverhead() + kTransportOverhead > |
133 if (media_packet->length + PacketOverhead() + kTransportOverhead > | |
134 IP_PACKET_SIZE) { | 132 IP_PACKET_SIZE) { |
135 LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes " | 133 LOG(LS_WARNING) << "Media packet " << media_packet->length << " bytes " |
136 << "with overhead is larger than " << IP_PACKET_SIZE | 134 << "with overhead is larger than " << IP_PACKET_SIZE |
137 << " bytes."; | 135 << " bytes."; |
138 } | 136 } |
139 } | 137 } |
140 | 138 |
141 int num_fec_packets = GetNumberOfFecPackets(num_media_packets, | 139 int num_fec_packets = NumFecPackets(num_media_packets, protection_factor); |
142 protection_factor); | |
143 if (num_fec_packets == 0) { | 140 if (num_fec_packets == 0) { |
144 return 0; | 141 return 0; |
145 } | 142 } |
146 | 143 |
147 // Prepare generated FEC packets by setting them to 0. | 144 // Prepare generated FEC packets by setting them to 0. |
148 for (int i = 0; i < num_fec_packets; ++i) { | 145 for (int i = 0; i < num_fec_packets; ++i) { |
149 memset(generated_fec_packets_[i].data, 0, IP_PACKET_SIZE); | 146 memset(generated_fec_packets_[i].data, 0, IP_PACKET_SIZE); |
150 // Use this as a marker for untouched packets. | 147 // Use this as a marker for untouched packets. |
151 generated_fec_packets_[i].length = 0; | 148 generated_fec_packets_[i].length = 0; |
152 fec_packets->push_back(&generated_fec_packets_[i]); | 149 fec_packets->push_back(&generated_fec_packets_[i]); |
(...skipping 17 matching lines...) Expand all Loading... |
170 if (l_bit) { | 167 if (l_bit) { |
171 num_mask_bytes = kMaskSizeLBitSet; | 168 num_mask_bytes = kMaskSizeLBitSet; |
172 } | 169 } |
173 | 170 |
174 GenerateFecBitStrings(media_packets, packet_mask_, num_fec_packets, l_bit); | 171 GenerateFecBitStrings(media_packets, packet_mask_, num_fec_packets, l_bit); |
175 GenerateFecUlpHeaders(media_packets, packet_mask_, num_fec_packets, l_bit); | 172 GenerateFecUlpHeaders(media_packets, packet_mask_, num_fec_packets, l_bit); |
176 | 173 |
177 return 0; | 174 return 0; |
178 } | 175 } |
179 | 176 |
180 int ForwardErrorCorrection::GetNumberOfFecPackets(int num_media_packets, | 177 int ForwardErrorCorrection::NumFecPackets(int num_media_packets, |
181 int protection_factor) { | 178 int protection_factor) { |
182 // Result in Q0 with an unsigned round. | 179 // Result in Q0 with an unsigned round. |
183 int num_fec_packets = (num_media_packets * protection_factor + (1 << 7)) >> 8; | 180 int num_fec_packets = (num_media_packets * protection_factor + (1 << 7)) >> 8; |
184 // Generate at least one FEC packet if we need protection. | 181 // Generate at least one FEC packet if we need protection. |
185 if (protection_factor > 0 && num_fec_packets == 0) { | 182 if (protection_factor > 0 && num_fec_packets == 0) { |
186 num_fec_packets = 1; | 183 num_fec_packets = 1; |
187 } | 184 } |
188 RTC_DCHECK_LE(num_fec_packets, num_media_packets); | 185 RTC_DCHECK_LE(num_fec_packets, num_media_packets); |
189 return num_fec_packets; | 186 return num_fec_packets; |
190 } | 187 } |
191 | 188 |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 // A big gap in sequence numbers. The old recovered packets | 766 // A big gap in sequence numbers. The old recovered packets |
770 // are now useless, so it's safe to do a reset. | 767 // are now useless, so it's safe to do a reset. |
771 ResetState(recovered_packets); | 768 ResetState(recovered_packets); |
772 } | 769 } |
773 } | 770 } |
774 InsertPackets(received_packets, recovered_packets); | 771 InsertPackets(received_packets, recovered_packets); |
775 AttemptRecover(recovered_packets); | 772 AttemptRecover(recovered_packets); |
776 return 0; | 773 return 0; |
777 } | 774 } |
778 | 775 |
779 size_t ForwardErrorCorrection::PacketOverhead() { | 776 size_t ForwardErrorCorrection::MaxPacketOverhead() const { |
780 return kFecHeaderSize + kUlpHeaderSizeLBitSet; | 777 return kFecHeaderSize + kUlpHeaderSizeLBitSet; |
781 } | 778 } |
782 } // namespace webrtc | 779 } // namespace webrtc |
OLD | NEW |