Simplify {,Set}UlpfecConfig interface.
Prior to this change, we signalled that ULPFEC was disabled
through a bool, but that RED was disabled by setting its
payload type to -1. The latter is consistent with how we
disable RED/ULPFEC in the config, so this CL removes the
ULPFEC bool from the {,Set}UlpfecConfig chain of member
functions.
BUG=webrtc:5654
Review-Url: https://codereview.webrtc.org/2460533002
Cr-Original-Commit-Position: refs/heads/master@{#14944}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: f1bb47605098f3e7c6583ff935f8570b3bb55a28
diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h
index be3d0f4..68429c6 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -434,9 +434,16 @@
// Video
// **************************************************************************
- // Turn on/off ULPFEC.
- virtual void SetUlpfecConfig(bool enabled,
- int red_payload_type,
+ // Set RED and ULPFEC payload types. A payload type of -1 means that the
+ // corresponding feature is turned off. Note that we DO NOT support enabling
+ // ULPFEC without enabling RED. However, we DO support enabling RED without
+ // enabling ULPFEC. This is due to an RED/RTX workaround, where the receiver
+ // assumes that RTX packets carry RED if RED has been configured in the SDP,
+ // regardless of what RTX payload type mapping was negotiated in the SDP.
+ // TODO(brandtr): Update this comment when we have removed the RED/RTX
+ // send-side workaround, i.e., when we do not support enabling RED without
+ // enabling ULPFEC.
+ virtual void SetUlpfecConfig(int red_payload_type,
int ulpfec_payload_type) = 0;
virtual int32_t SetFecParameters(const FecProtectionParams* delta_params,
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 4f396e7..ff8d90f 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -186,10 +186,8 @@
int32_t(bool enable, uint8_t id));
MOCK_METHOD1(SetAudioLevel, int32_t(uint8_t level_dbov));
MOCK_METHOD1(SetTargetSendBitrate, void(uint32_t bitrate_bps));
- MOCK_METHOD3(SetUlpfecConfig,
- void(bool ulpfec_enabled,
- int red_payload_type,
- int fec_payload_type));
+ MOCK_METHOD2(SetUlpfecConfig,
+ void(int red_payload_type, int fec_payload_type));
MOCK_METHOD2(SetFecParameters,
int32_t(const FecProtectionParams* delta_params,
const FecProtectionParams* key_params));
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 9f4e165..2a2bf0d 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -789,10 +789,9 @@
GetFeedbackState(), kRtcpSli, 0, 0, false, picture_id);
}
-void ModuleRtpRtcpImpl::SetUlpfecConfig(bool enabled,
- int red_payload_type,
+void ModuleRtpRtcpImpl::SetUlpfecConfig(int red_payload_type,
int ulpfec_payload_type) {
- rtp_sender_.SetUlpfecConfig(enabled, red_payload_type, ulpfec_payload_type);
+ rtp_sender_.SetUlpfecConfig(red_payload_type, ulpfec_payload_type);
}
int32_t ModuleRtpRtcpImpl::SetFecParameters(
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index c89de9b..f055bbe 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -277,9 +277,7 @@
// Send a request for a keyframe.
int32_t RequestKeyFrame() override;
- void SetUlpfecConfig(bool enabled,
- int red_payload_type,
- int ulpfec_payload_type) override;
+ void SetUlpfecConfig(int red_payload_type, int ulpfec_payload_type) override;
int32_t SetFecParameters(const FecProtectionParams* delta_params,
const FecProtectionParams* key_params) override;
diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc
index f0e323a..a3593c6 100644
--- a/modules/rtp_rtcp/source/rtp_sender.cc
+++ b/modules/rtp_rtcp/source/rtp_sender.cc
@@ -789,10 +789,10 @@
if (!video_) {
return false;
}
- bool fec_enabled;
int pt_red;
int pt_fec;
- video_->GetUlpfecConfig(&fec_enabled, &pt_red, &pt_fec);
+ video_->GetUlpfecConfig(&pt_red, &pt_fec);
+ const bool fec_enabled = (pt_fec != -1);
return fec_enabled && static_cast<int>(packet.PayloadType()) == pt_red &&
static_cast<int>(packet.payload()[0]) == pt_fec;
}
@@ -1131,11 +1131,9 @@
return video_->VideoCodecType();
}
-void RTPSender::SetUlpfecConfig(bool enabled,
- int red_payload_type,
- int ulpfec_payload_type) {
+void RTPSender::SetUlpfecConfig(int red_payload_type, int ulpfec_payload_type) {
RTC_DCHECK(!audio_configured_);
- video_->SetUlpfecConfig(enabled, red_payload_type, ulpfec_payload_type);
+ video_->SetUlpfecConfig(red_payload_type, ulpfec_payload_type);
}
int32_t RTPSender::SetFecParameters(
diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h
index 75132b2..dafddc5 100644
--- a/modules/rtp_rtcp/source/rtp_sender.h
+++ b/modules/rtp_rtcp/source/rtp_sender.h
@@ -183,10 +183,8 @@
uint32_t MaxConfiguredBitrateVideo() const;
- // FEC.
- void SetUlpfecConfig(bool enabled,
- int red_payload_type,
- int ulpfec_payload_type);
+ // ULPFEC.
+ void SetUlpfecConfig(int red_payload_type, int ulpfec_payload_type);
int32_t SetFecParameters(const FecProtectionParams *delta_params,
const FecProtectionParams *key_params);
diff --git a/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
index 16bc271..fa8db8a 100644
--- a/modules/rtp_rtcp/source/rtp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_unittest.cc
@@ -1123,8 +1123,8 @@
expected.transmitted.packets = 3;
callback.Matches(ssrc, expected);
- // Send FEC.
- rtp_sender_->SetUlpfecConfig(true, kRedPayloadType, kUlpfecPayloadType);
+ // Send ULPFEC.
+ rtp_sender_->SetUlpfecConfig(kRedPayloadType, kUlpfecPayloadType);
FecProtectionParams fec_params;
fec_params.fec_mask_type = kFecMaskRandom;
fec_params.fec_rate = 1;
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index dd19bb2..2450a43 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -50,9 +50,8 @@
video_type_(kRtpVideoGeneric),
retransmission_settings_(kRetransmitBaseLayer),
last_rotation_(kVideoRotation_0),
- fec_enabled_(false),
red_payload_type_(-1),
- fec_payload_type_(-1),
+ ulpfec_payload_type_(-1),
delta_fec_params_{0, 1, kFecMaskRandom},
key_fec_params_{0, 1, kFecMaskRandom},
fec_bitrate_(1000, RateStatistics::kBpsScale),
@@ -139,7 +138,7 @@
uint16_t first_fec_sequence_number =
rtp_sender_->AllocateSequenceNumber(num_fec_packets);
fec_packets = ulpfec_generator_.GetUlpfecPacketsAsRed(
- red_payload_type_, fec_payload_type_, first_fec_sequence_number,
+ red_payload_type_, ulpfec_payload_type_, first_fec_sequence_number,
media_packet->headers_size());
RTC_DCHECK_EQ(num_fec_packets, fec_packets.size());
if (retransmission_settings_ & kRetransmitFECPackets)
@@ -179,36 +178,42 @@
}
}
-void RTPSenderVideo::SetUlpfecConfig(bool enabled,
- int red_payload_type,
+void RTPSenderVideo::SetUlpfecConfig(int red_payload_type,
int ulpfec_payload_type) {
- RTC_DCHECK(!enabled || red_payload_type > 0);
+ // Sanity check. Per the definition of UlpfecConfig (see config.h),
+ // a payload type of -1 means that the corresponding feature is
+ // turned off.
+ RTC_DCHECK_GE(red_payload_type, -1);
RTC_DCHECK_LE(red_payload_type, 127);
+ RTC_DCHECK_GE(ulpfec_payload_type, -1);
RTC_DCHECK_LE(ulpfec_payload_type, 127);
rtc::CritScope cs(&crit_);
- fec_enabled_ = enabled;
red_payload_type_ = red_payload_type;
- fec_payload_type_ = ulpfec_payload_type;
+ ulpfec_payload_type_ = ulpfec_payload_type;
+
+ // Must not enable ULPFEC without RED.
+ // TODO(brandtr): We currently support enabling RED without ULPFEC. Change
+ // this when we have removed the RED/RTX send-side workaround, so that we
+ // ensure that RED and ULPFEC are only enabled together.
+ RTC_DCHECK(red_enabled() || !ulpfec_enabled());
// Reset FEC rates.
delta_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom};
key_fec_params_ = FecProtectionParams{0, 1, kFecMaskRandom};
}
-void RTPSenderVideo::GetUlpfecConfig(bool* enabled,
- int* red_payload_type,
+void RTPSenderVideo::GetUlpfecConfig(int* red_payload_type,
int* ulpfec_payload_type) const {
rtc::CritScope cs(&crit_);
- *enabled = fec_enabled_;
*red_payload_type = red_payload_type_;
- *ulpfec_payload_type = fec_payload_type_;
+ *ulpfec_payload_type = ulpfec_payload_type_;
}
size_t RTPSenderVideo::FecPacketOverhead() const {
rtc::CritScope cs(&crit_);
size_t overhead = 0;
- if (red_payload_type_ != -1) {
+ if (red_enabled()) {
// Overhead is FEC headers plus RED for FEC header plus anything in RTP
// header beyond the 12 bytes base header (CSRC list, extensions...)
// This reason for the header extensions to be included here is that
@@ -217,7 +222,7 @@
return ulpfec_generator_.MaxPacketOverhead() + kRedForFecHeaderLength +
(rtp_sender_->RtpHeaderLength() - kRtpHeaderSize);
}
- if (fec_enabled_)
+ if (ulpfec_enabled())
overhead += ulpfec_generator_.MaxPacketOverhead();
return overhead;
}
@@ -227,7 +232,7 @@
rtc::CritScope cs(&crit_);
RTC_DCHECK(delta_params);
RTC_DCHECK(key_params);
- if (fec_enabled_) {
+ if (ulpfec_enabled()) {
delta_fec_params_ = *delta_params;
key_fec_params_ = *key_params;
}
@@ -283,7 +288,7 @@
video_header ? &(video_header->codecHeader) : nullptr, frame_type));
StorageType storage;
- int red_payload_type;
+ bool red_enabled;
bool first_frame = first_frame_sent_();
{
rtc::CritScope cs(&crit_);
@@ -291,7 +296,7 @@
frame_type == kVideoFrameKey ? &key_fec_params_ : &delta_fec_params_;
ulpfec_generator_.SetFecParameters(fec_params);
storage = packetizer->GetStorageType(retransmission_settings_);
- red_payload_type = red_payload_type_;
+ red_enabled = this->red_enabled();
}
// TODO(changbin): we currently don't support to configure the codec to
@@ -318,7 +323,7 @@
if (!rtp_sender_->AssignSequenceNumber(packet.get()))
return false;
- if (red_payload_type != -1) {
+ if (red_enabled) {
SendVideoPacketAsRed(std::move(packet), storage,
packetizer->GetProtectionType() == kProtectedPacket);
} else {
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.h b/modules/rtp_rtcp/source/rtp_sender_video.h
index 56be39d..2cb40e3 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.h
+++ b/modules/rtp_rtcp/source/rtp_sender_video.h
@@ -59,14 +59,9 @@
void SetVideoCodecType(RtpVideoCodecTypes type);
- // FEC
- void SetUlpfecConfig(bool enabled,
- int red_payload_type,
- int ulpfec_payload_type);
-
- void GetUlpfecConfig(bool* enabled,
- int* red_payload_type,
- int* ulpfec_payload_type) const;
+ // ULPFEC.
+ void SetUlpfecConfig(int red_payload_type, int ulpfec_payload_type);
+ void GetUlpfecConfig(int* red_payload_type, int* ulpfec_payload_type) const;
void SetFecParameters(const FecProtectionParams* delta_params,
const FecProtectionParams* key_params);
@@ -85,6 +80,14 @@
StorageType media_packet_storage,
bool protect);
+ bool red_enabled() const EXCLUSIVE_LOCKS_REQUIRED(crit_) {
+ return red_payload_type_ >= 0;
+ }
+
+ bool ulpfec_enabled() const EXCLUSIVE_LOCKS_REQUIRED(crit_) {
+ return ulpfec_payload_type_ >= 0;
+ }
+
RTPSender* const rtp_sender_;
Clock* const clock_;
@@ -96,10 +99,9 @@
int32_t retransmission_settings_ GUARDED_BY(crit_);
VideoRotation last_rotation_ GUARDED_BY(encoder_checker_);
- // FEC
- bool fec_enabled_ GUARDED_BY(crit_);
+ // RED/ULPFEC.
int red_payload_type_ GUARDED_BY(crit_);
- int fec_payload_type_ GUARDED_BY(crit_);
+ int ulpfec_payload_type_ GUARDED_BY(crit_);
FecProtectionParams delta_fec_params_ GUARDED_BY(crit_);
FecProtectionParams key_fec_params_ GUARDED_BY(crit_);
UlpfecGenerator ulpfec_generator_ GUARDED_BY(crit_);
diff --git a/video/rtp_stream_receiver.cc b/video/rtp_stream_receiver.cc
index cf108e1..576543b 100644
--- a/video/rtp_stream_receiver.cc
+++ b/video/rtp_stream_receiver.cc
@@ -178,8 +178,10 @@
config_.rtp.ulpfec.red_rtx_payload_type,
config_.rtp.ulpfec.red_payload_type);
}
-
- rtp_rtcp_->SetUlpfecConfig(true, config_.rtp.ulpfec.red_payload_type,
+ // TODO(brandtr): It doesn't seem that |rtp_rtcp_| is used for sending any
+ // RTP packets. Investigate if this is the case, and if so, remove this
+ // call, since there are no RTP packets to protect with RED+ULPFEC.
+ rtp_rtcp_->SetUlpfecConfig(config_.rtp.ulpfec.red_payload_type,
config_.rtp.ulpfec.ulpfec_payload_type);
}
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index 14fd72f..98baf05 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -934,7 +934,8 @@
RTC_DCHECK_RUN_ON(worker_queue_);
// Enable NACK, FEC or both.
const bool enable_protection_nack = config_->rtp.nack.rtp_history_ms > 0;
- bool enable_protection_fec = config_->rtp.ulpfec.ulpfec_payload_type != -1;
+ const int red_payload_type = config_->rtp.ulpfec.red_payload_type;
+ int ulpfec_payload_type = config_->rtp.ulpfec.ulpfec_payload_type;
// 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
@@ -945,7 +946,7 @@
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.";
- enable_protection_fec = false;
+ ulpfec_payload_type = -1;
}
// TODO(brandtr): Remove the workaround described below.
@@ -961,13 +962,13 @@
// using the wrong payload type.
// Verify validity of provided payload types.
- if (config_->rtp.ulpfec.red_payload_type != -1) {
- RTC_DCHECK_GE(config_->rtp.ulpfec.red_payload_type, 0);
- RTC_DCHECK_LE(config_->rtp.ulpfec.red_payload_type, 127);
+ if (red_payload_type != -1) {
+ RTC_DCHECK_GE(red_payload_type, 0);
+ RTC_DCHECK_LE(red_payload_type, 127);
}
- if (config_->rtp.ulpfec.ulpfec_payload_type != -1) {
- RTC_DCHECK_GE(config_->rtp.ulpfec.ulpfec_payload_type, 0);
- RTC_DCHECK_LE(config_->rtp.ulpfec.ulpfec_payload_type, 127);
+ if (ulpfec_payload_type != -1) {
+ RTC_DCHECK_GE(ulpfec_payload_type, 0);
+ RTC_DCHECK_LE(ulpfec_payload_type, 127);
}
for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
@@ -977,12 +978,11 @@
kMinSendSidePacketHistorySize);
// Set FEC.
for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
- rtp_rtcp->SetUlpfecConfig(enable_protection_fec,
- config_->rtp.ulpfec.red_payload_type,
- config_->rtp.ulpfec.ulpfec_payload_type);
+ 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);
}