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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 if (protect) { | 123 if (protect) { |
124 producer_fec_.AddRtpPacketAndGenerateFec(media_packet->data(), | 124 producer_fec_.AddRtpPacketAndGenerateFec(media_packet->data(), |
125 media_packet->payload_size(), | 125 media_packet->payload_size(), |
126 media_packet->headers_size()); | 126 media_packet->headers_size()); |
127 } | 127 } |
128 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); | 128 uint16_t num_fec_packets = producer_fec_.NumAvailableFecPackets(); |
129 if (num_fec_packets > 0) { | 129 if (num_fec_packets > 0) { |
130 uint16_t first_fec_sequence_number = | 130 uint16_t first_fec_sequence_number = |
131 rtp_sender_->AllocateSequenceNumber(num_fec_packets); | 131 rtp_sender_->AllocateSequenceNumber(num_fec_packets); |
132 fec_packets = producer_fec_.GetUlpfecPacketsAsRed( | 132 fec_packets = producer_fec_.GetUlpfecPacketsAsRed( |
133 red_payload_type_, fec_payload_type_, first_fec_sequence_number, | 133 red_payload_type_, ulpfec_payload_type_, first_fec_sequence_number, |
134 media_packet->headers_size()); | 134 media_packet->headers_size()); |
135 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); | 135 RTC_DCHECK_EQ(num_fec_packets, fec_packets.size()); |
136 if (retransmission_settings_ & kRetransmitFECPackets) | 136 if (retransmission_settings_ & kRetransmitFECPackets) |
137 fec_storage = kAllowRetransmission; | 137 fec_storage = kAllowRetransmission; |
138 } | 138 } |
139 } | 139 } |
140 // Send |red_packet| instead of |packet| for allocated sequence number. | 140 // Send |red_packet| instead of |packet| for allocated sequence number. |
141 size_t red_packet_size = red_packet->size(); | 141 size_t red_packet_size = red_packet->size(); |
142 if (rtp_sender_->SendToNetwork(std::move(red_packet), media_packet_storage, | 142 if (rtp_sender_->SendToNetwork(std::move(red_packet), media_packet_storage, |
143 RtpPacketSender::kLowPriority)) { | 143 RtpPacketSender::kLowPriority)) { |
(...skipping 19 matching lines...) Expand all Loading... | |
163 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); | 163 fec_bitrate_.Update(fec_packet->length(), clock_->TimeInMilliseconds()); |
164 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), | 164 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), |
165 "Video::PacketFec", "timestamp", rtp_timestamp, | 165 "Video::PacketFec", "timestamp", rtp_timestamp, |
166 "seqnum", fec_sequence_number); | 166 "seqnum", fec_sequence_number); |
167 } else { | 167 } else { |
168 LOG(LS_WARNING) << "Failed to send FEC packet " << fec_sequence_number; | 168 LOG(LS_WARNING) << "Failed to send FEC packet " << fec_sequence_number; |
169 } | 169 } |
170 } | 170 } |
171 } | 171 } |
172 | 172 |
173 void RTPSenderVideo::SetUlpfecConfig(bool enabled, | 173 bool RTPSenderVideo::RedEnabled() const { |
174 int red_payload_type, | 174 rtc::CritScope cs(&crit_); |
danilchap
2016/10/28 09:29:43
do not (re)take lock, instead annotate these funct
brandtr
2016/10/28 11:05:06
Got it! Done. Also changed name to cheap_accessor_
| |
175 return red_payload_type_ >= 0; | |
176 } | |
177 | |
178 bool RTPSenderVideo::UlpfecEnabled() const { | |
179 rtc::CritScope cs(&crit_); | |
180 return ulpfec_payload_type_ >= 0; | |
181 } | |
182 | |
183 void RTPSenderVideo::SetUlpfecConfig(int red_payload_type, | |
175 int ulpfec_payload_type) { | 184 int ulpfec_payload_type) { |
176 RTC_DCHECK(!enabled || red_payload_type > 0); | 185 // Sanity check. Per the definition of UlpfecConfig (see config.h), |
186 // a payload type of -1 means that the corresponding feature is | |
187 // turned off. | |
188 RTC_DCHECK_GE(red_payload_type, -1); | |
177 RTC_DCHECK_LE(red_payload_type, 127); | 189 RTC_DCHECK_LE(red_payload_type, 127); |
190 RTC_DCHECK_GE(ulpfec_payload_type, -1); | |
178 RTC_DCHECK_LE(ulpfec_payload_type, 127); | 191 RTC_DCHECK_LE(ulpfec_payload_type, 127); |
179 | 192 |
180 rtc::CritScope cs(&crit_); | 193 rtc::CritScope cs(&crit_); |
181 fec_enabled_ = enabled; | |
182 red_payload_type_ = red_payload_type; | 194 red_payload_type_ = red_payload_type; |
183 fec_payload_type_ = ulpfec_payload_type; | 195 ulpfec_payload_type_ = ulpfec_payload_type; |
196 | |
197 // Must not enable ULPFEC without RED. | |
198 // TODO(brandtr): We currently support enabling RED without ULPFEC. Change | |
199 // this when we have removed the RED/RTX send-side workaround, so that we | |
200 // ensure that RED and ULPFEC are only enabled together. | |
201 RTC_DCHECK(RedEnabled() || !UlpfecEnabled()); | |
184 | 202 |
185 // Reset FEC rates. | 203 // Reset FEC rates. |
186 delta_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; | 204 delta_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; |
187 key_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; | 205 key_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom}; |
188 } | 206 } |
189 | 207 |
190 void RTPSenderVideo::UlpfecConfig(bool* enabled, | 208 void RTPSenderVideo::UlpfecConfig(int* red_payload_type, |
191 int* red_payload_type, | |
192 int* ulpfec_payload_type) const { | 209 int* ulpfec_payload_type) const { |
193 rtc::CritScope cs(&crit_); | 210 rtc::CritScope cs(&crit_); |
194 *enabled = fec_enabled_; | |
195 *red_payload_type = red_payload_type_; | 211 *red_payload_type = red_payload_type_; |
196 *ulpfec_payload_type = fec_payload_type_; | 212 *ulpfec_payload_type = ulpfec_payload_type_; |
197 } | 213 } |
198 | 214 |
199 size_t RTPSenderVideo::FecPacketOverhead() const { | 215 size_t RTPSenderVideo::FecPacketOverhead() const { |
200 rtc::CritScope cs(&crit_); | 216 rtc::CritScope cs(&crit_); |
201 size_t overhead = 0; | 217 size_t overhead = 0; |
202 if (red_payload_type_ != -1) { | 218 if (RedEnabled()) { |
203 // Overhead is FEC headers plus RED for FEC header plus anything in RTP | 219 // Overhead is FEC headers plus RED for FEC header plus anything in RTP |
204 // header beyond the 12 bytes base header (CSRC list, extensions...) | 220 // header beyond the 12 bytes base header (CSRC list, extensions...) |
205 // This reason for the header extensions to be included here is that | 221 // This reason for the header extensions to be included here is that |
206 // from an FEC viewpoint, they are part of the payload to be protected. | 222 // from an FEC viewpoint, they are part of the payload to be protected. |
207 // (The base RTP header is already protected by the FEC header.) | 223 // (The base RTP header is already protected by the FEC header.) |
208 return producer_fec_.MaxPacketOverhead() + kRedForFecHeaderLength + | 224 return producer_fec_.MaxPacketOverhead() + kRedForFecHeaderLength + |
209 (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); | 225 (rtp_sender_->RtpHeaderLength() - kRtpHeaderSize); |
210 } | 226 } |
211 if (fec_enabled_) | 227 if (UlpfecEnabled()) |
212 overhead += producer_fec_.MaxPacketOverhead(); | 228 overhead += producer_fec_.MaxPacketOverhead(); |
213 return overhead; | 229 return overhead; |
214 } | 230 } |
215 | 231 |
216 void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, | 232 void RTPSenderVideo::SetFecParameters(const FecProtectionParams* delta_params, |
217 const FecProtectionParams* key_params) { | 233 const FecProtectionParams* key_params) { |
218 rtc::CritScope cs(&crit_); | 234 rtc::CritScope cs(&crit_); |
219 RTC_DCHECK(delta_params); | 235 RTC_DCHECK(delta_params); |
220 RTC_DCHECK(key_params); | 236 RTC_DCHECK(key_params); |
221 if (fec_enabled_) { | 237 if (UlpfecEnabled()) { |
222 delta_fec_params_ = *delta_params; | 238 delta_fec_params_ = *delta_params; |
223 key_fec_params_ = *key_params; | 239 key_fec_params_ = *key_params; |
224 } | 240 } |
225 } | 241 } |
226 | 242 |
227 bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, | 243 bool RTPSenderVideo::SendVideo(RtpVideoCodecTypes video_type, |
228 FrameType frame_type, | 244 FrameType frame_type, |
229 int8_t payload_type, | 245 int8_t payload_type, |
230 uint32_t rtp_timestamp, | 246 uint32_t rtp_timestamp, |
231 int64_t capture_time_ms, | 247 int64_t capture_time_ms, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 (rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0); | 281 (rtp_sender_->RtxStatus() ? kRtxHeaderSize : 0); |
266 RTC_DCHECK_LE(packet_capacity, rtp_header->capacity()); | 282 RTC_DCHECK_LE(packet_capacity, rtp_header->capacity()); |
267 RTC_DCHECK_GT(packet_capacity, rtp_header->headers_size()); | 283 RTC_DCHECK_GT(packet_capacity, rtp_header->headers_size()); |
268 size_t max_data_payload_length = packet_capacity - rtp_header->headers_size(); | 284 size_t max_data_payload_length = packet_capacity - rtp_header->headers_size(); |
269 | 285 |
270 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 286 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( |
271 video_type, max_data_payload_length, | 287 video_type, max_data_payload_length, |
272 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); | 288 video_header ? &(video_header->codecHeader) : nullptr, frame_type)); |
273 | 289 |
274 StorageType storage; | 290 StorageType storage; |
275 int red_payload_type; | 291 bool red_enabled; |
276 bool first_frame = first_frame_sent_(); | 292 bool first_frame = first_frame_sent_(); |
277 { | 293 { |
278 rtc::CritScope cs(&crit_); | 294 rtc::CritScope cs(&crit_); |
279 FecProtectionParams* fec_params = | 295 FecProtectionParams* fec_params = |
280 frame_type == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; | 296 frame_type == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_; |
281 producer_fec_.SetFecParameters(fec_params); | 297 producer_fec_.SetFecParameters(fec_params); |
282 storage = packetizer->GetStorageType(retransmission_settings_); | 298 storage = packetizer->GetStorageType(retransmission_settings_); |
283 red_payload_type = red_payload_type_; | 299 red_enabled = RedEnabled(); |
284 } | 300 } |
285 | 301 |
286 // TODO(changbin): we currently don't support to configure the codec to | 302 // TODO(changbin): we currently don't support to configure the codec to |
287 // output multiple partitions for VP8. Should remove below check after the | 303 // output multiple partitions for VP8. Should remove below check after the |
288 // issue is fixed. | 304 // issue is fixed. |
289 const RTPFragmentationHeader* frag = | 305 const RTPFragmentationHeader* frag = |
290 (video_type == kRtpVideoVp8) ? NULL : fragmentation; | 306 (video_type == kRtpVideoVp8) ? NULL : fragmentation; |
291 | 307 |
292 packetizer->SetPayloadData(payload_data, payload_size, frag); | 308 packetizer->SetPayloadData(payload_data, payload_size, frag); |
293 | 309 |
294 bool first = true; | 310 bool first = true; |
295 bool last = false; | 311 bool last = false; |
296 while (!last) { | 312 while (!last) { |
297 std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(*rtp_header)); | 313 std::unique_ptr<RtpPacketToSend> packet(new RtpPacketToSend(*rtp_header)); |
298 uint8_t* payload = packet->AllocatePayload(max_data_payload_length); | 314 uint8_t* payload = packet->AllocatePayload(max_data_payload_length); |
299 RTC_DCHECK(payload); | 315 RTC_DCHECK(payload); |
300 | 316 |
301 size_t payload_bytes_in_packet = 0; | 317 size_t payload_bytes_in_packet = 0; |
302 if (!packetizer->NextPacket(payload, &payload_bytes_in_packet, &last)) | 318 if (!packetizer->NextPacket(payload, &payload_bytes_in_packet, &last)) |
303 return false; | 319 return false; |
304 | 320 |
305 packet->SetPayloadSize(payload_bytes_in_packet); | 321 packet->SetPayloadSize(payload_bytes_in_packet); |
306 packet->SetMarker(last); | 322 packet->SetMarker(last); |
307 if (!rtp_sender_->AssignSequenceNumber(packet.get())) | 323 if (!rtp_sender_->AssignSequenceNumber(packet.get())) |
308 return false; | 324 return false; |
309 | 325 |
310 if (red_payload_type != -1) { | 326 if (red_enabled) { |
311 SendVideoPacketAsRed(std::move(packet), storage, | 327 SendVideoPacketAsRed(std::move(packet), storage, |
312 packetizer->GetProtectionType() == kProtectedPacket); | 328 packetizer->GetProtectionType() == kProtectedPacket); |
313 } else { | 329 } else { |
314 SendVideoPacket(std::move(packet), storage); | 330 SendVideoPacket(std::move(packet), storage); |
315 } | 331 } |
316 | 332 |
317 if (first_frame) { | 333 if (first_frame) { |
318 if (first) { | 334 if (first) { |
319 LOG(LS_INFO) | 335 LOG(LS_INFO) |
320 << "Sent first RTP packet of the first video frame (pre-pacer)"; | 336 << "Sent first RTP packet of the first video frame (pre-pacer)"; |
(...skipping 25 matching lines...) Expand all Loading... | |
346 rtc::CritScope cs(&crit_); | 362 rtc::CritScope cs(&crit_); |
347 return retransmission_settings_; | 363 return retransmission_settings_; |
348 } | 364 } |
349 | 365 |
350 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { | 366 void RTPSenderVideo::SetSelectiveRetransmissions(uint8_t settings) { |
351 rtc::CritScope cs(&crit_); | 367 rtc::CritScope cs(&crit_); |
352 retransmission_settings_ = settings; | 368 retransmission_settings_ = settings; |
353 } | 369 } |
354 | 370 |
355 } // namespace webrtc | 371 } // namespace webrtc |
OLD | NEW |