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