| Index: webrtc/video/video_send_stream.cc
|
| diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
|
| index 26082abf364389cdeb884945dd9ec2f333f947fa..aac73aba98ea8ac5902e09b48a06ac2c3b3c6a11 100644
|
| --- a/webrtc/video/video_send_stream.cc
|
| +++ b/webrtc/video/video_send_stream.cc
|
| @@ -942,59 +942,65 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
|
|
|
| void VideoSendStreamImpl::ConfigureProtection() {
|
| RTC_DCHECK_RUN_ON(worker_queue_);
|
| - // Enable NACK, FEC or both.
|
| - const bool enable_protection_nack = config_->rtp.nack.rtp_history_ms > 0;
|
| - const int red_payload_type = config_->rtp.ulpfec.red_payload_type;
|
| +
|
| + const bool nack_enabled = config_->rtp.nack.rtp_history_ms > 0;
|
| + int red_payload_type = config_->rtp.ulpfec.red_payload_type;
|
| int ulpfec_payload_type = config_->rtp.ulpfec.ulpfec_payload_type;
|
| +
|
| + // Shorthands.
|
| + auto IsRedEnabled = [&]() { return red_payload_type >= 0; };
|
| + auto IsUlpfecEnabled = [&]() { return ulpfec_payload_type >= 0; };
|
| + auto DisableUlpfec = [&]() { ulpfec_payload_type = -1; };
|
| +
|
| // Payload types without picture ID cannot determine that a stream is complete
|
| - // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
|
| - // a waste of bandwidth since FEC packets still have to be transmitted. Note
|
| - // that this is not the case with FLEXFEC.
|
| - if (enable_protection_nack &&
|
| + // without retransmitting FEC, so using ULPFEC + NACK for H.264 (for instance)
|
| + // is a waste of bandwidth since FEC packets still have to be transmitted.
|
| + // Note that this is not the case with FlexFEC.
|
| + if (nack_enabled && IsUlpfecEnabled() &&
|
| !PayloadTypeSupportsSkippingFecPackets(
|
| config_->encoder_settings.payload_name)) {
|
| - LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
|
| - "NACK+FEC is a waste of bandwidth since FEC packets "
|
| - "also have to be retransmitted. Disabling FEC.";
|
| - ulpfec_payload_type = -1;
|
| + LOG(LS_WARNING)
|
| + << "Transmitting payload type without picture ID using "
|
| + "NACK+ULPFEC is a waste of bandwidth since ULPFEC packets "
|
| + "also have to be retransmitted. Disabling ULPFEC.";
|
| + DisableUlpfec();
|
| }
|
|
|
| - // TODO(brandtr): Remove the workaround described below.
|
| + // Verify payload types.
|
| //
|
| - // In theory, we should enable RED if and only if ULPFEC is also enabled,
|
| - // and vice versa. (We only support ULPFEC over RED, not multiplexed in any
|
| - // other way.) However, due to the RED/RTX workaround introduced here:
|
| - // https://codereview.webrtc.org/1649493004, we need to send media over RED
|
| - // (even if ULPFEC is disabled), whenever RED has been negotiated in the SDP.
|
| - // This is due to the associated payload type is hardcoded to be RED in the
|
| - // receiver, whenever RED appears in the SDP. If we would not send media over
|
| - // RED in this case, the RTX receiver would recover retransmitted packets
|
| - // using the wrong payload type.
|
| -
|
| - // Verify validity of provided payload types.
|
| - if (red_payload_type != -1) {
|
| + // Due to how old receivers work, we need to always send RED if it has been
|
| + // negotiated. This is a remnant of an old RED/RTX workaround, see
|
| + // https://codereview.webrtc.org/2469093003.
|
| + // TODO(brandtr): This change went into M56, so we can remove it in ~M59.
|
| + // At that time, we can disable RED whenever ULPFEC is disabled, as there is
|
| + // no point in using RED without ULPFEC.
|
| + if (IsRedEnabled()) {
|
| RTC_DCHECK_GE(red_payload_type, 0);
|
| RTC_DCHECK_LE(red_payload_type, 127);
|
| }
|
| - if (ulpfec_payload_type != -1) {
|
| + if (IsUlpfecEnabled()) {
|
| RTC_DCHECK_GE(ulpfec_payload_type, 0);
|
| RTC_DCHECK_LE(ulpfec_payload_type, 127);
|
| + if (!IsRedEnabled()) {
|
| + LOG(LS_WARNING)
|
| + << "ULPFEC is enabled but RED is disabled. Disabling ULPFEC.";
|
| + DisableUlpfec();
|
| + }
|
| }
|
|
|
| for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
|
| // Set NACK.
|
| rtp_rtcp->SetStorePacketsStatus(
|
| - enable_protection_nack || congestion_controller_->pacer(),
|
| + nack_enabled || congestion_controller_->pacer(),
|
| kMinSendSidePacketHistorySize);
|
| - // Set FEC.
|
| + // Set RED/ULPFEC information.
|
| for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
|
| rtp_rtcp->SetUlpfecConfig(red_payload_type, ulpfec_payload_type);
|
| }
|
| }
|
|
|
| - const bool enable_protection_fec = (ulpfec_payload_type != -1);
|
| - protection_bitrate_calculator_.SetProtectionMethod(enable_protection_fec,
|
| - enable_protection_nack);
|
| + protection_bitrate_calculator_.SetProtectionMethod(IsUlpfecEnabled(),
|
| + nack_enabled);
|
| }
|
|
|
| void VideoSendStreamImpl::ConfigureSsrcs() {
|
|
|