Skip to content

Commit f87536c

Browse files
Erik SprångCommit Bot
authored andcommitted
Reland "Reland "Refactors UlpFec and FlexFec to use a common interface.""
This is a reland of 49734dc Patchset 2 contains a fix for the fuzzer set up. Since we now parse an RtpPacket out of the fuzzer data, the header needs to be correct, otherwise we fail before even reaching the FEC code that we actually want to test. Bug: webrtc:11340, chromium:1052323, chromium:1055974 [email protected] Original change's description: > Reland "Refactors UlpFec and FlexFec to use a common interface." > > This is a reland of 11af1d7 > > Original change's description: > > Refactors UlpFec and FlexFec to use a common interface. > > > > The new VideoFecGenerator is now injected into RtpSenderVideo, > > and generalizes the usage. > > This also prepares for being able to genera FEC in the RTP egress > > module. > > > > Bug: webrtc:11340 > > Change-Id: I8aa873129b2fb4131eb3399ee88f6ea2747155a3 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168347 > > Reviewed-by: Stefan Holmer <[email protected]> > > Reviewed-by: Sebastian Jansson <[email protected]> > > Reviewed-by: Rasmus Brandt <[email protected]> > > Commit-Queue: Erik Språng <[email protected]> > > Cr-Commit-Position: refs/heads/master@{#30515} > > Bug: webrtc:11340, chromium:1052323 > Change-Id: Id646047365f1c46cca9e6f3e8eefa5151207b4a0 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168608 > Commit-Queue: Erik Språng <[email protected]> > Reviewed-by: Stefan Holmer <[email protected]> > Cr-Commit-Position: refs/heads/master@{#30593} Bug: webrtc:11340, chromium:1052323 Change-Id: Ib8925f44e2edfcfeadc95c845c3bfc23822604ed Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169222 Commit-Queue: Erik Språng <[email protected]> Reviewed-by: Ilya Nikolaevskiy <[email protected]> Cr-Commit-Position: refs/heads/master@{#30724}
1 parent 269d68f commit f87536c

23 files changed

+579
-564
lines changed

call/rtp_video_sender.cc

Lines changed: 99 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,13 @@ namespace webrtc {
3636

3737
namespace webrtc_internal_rtp_video_sender {
3838

39-
RtpStreamSender::RtpStreamSender(std::unique_ptr<RtpRtcp> rtp_rtcp,
40-
std::unique_ptr<RTPSenderVideo> sender_video)
41-
: rtp_rtcp(std::move(rtp_rtcp)), sender_video(std::move(sender_video)) {}
39+
RtpStreamSender::RtpStreamSender(
40+
std::unique_ptr<RtpRtcp> rtp_rtcp,
41+
std::unique_ptr<RTPSenderVideo> sender_video,
42+
std::unique_ptr<VideoFecGenerator> fec_generator)
43+
: rtp_rtcp(std::move(rtp_rtcp)),
44+
sender_video(std::move(sender_video)),
45+
fec_generator(std::move(fec_generator)) {}
4246

4347
RtpStreamSender::~RtpStreamSender() = default;
4448

@@ -113,6 +117,67 @@ bool ShouldDisableRedAndUlpfec(bool flexfec_enabled,
113117
return should_disable_red_and_ulpfec;
114118
}
115119

120+
// TODO(brandtr): Update this function when we support multistream protection.
121+
std::unique_ptr<VideoFecGenerator> MaybeCreateFecGenerator(
122+
Clock* clock,
123+
const RtpConfig& rtp,
124+
const std::map<uint32_t, RtpState>& suspended_ssrcs,
125+
int simulcast_index) {
126+
// If flexfec is configured that takes priority.
127+
if (rtp.flexfec.payload_type >= 0) {
128+
RTC_DCHECK_GE(rtp.flexfec.payload_type, 0);
129+
RTC_DCHECK_LE(rtp.flexfec.payload_type, 127);
130+
if (rtp.flexfec.ssrc == 0) {
131+
RTC_LOG(LS_WARNING) << "FlexFEC is enabled, but no FlexFEC SSRC given. "
132+
"Therefore disabling FlexFEC.";
133+
return nullptr;
134+
}
135+
if (rtp.flexfec.protected_media_ssrcs.empty()) {
136+
RTC_LOG(LS_WARNING)
137+
<< "FlexFEC is enabled, but no protected media SSRC given. "
138+
"Therefore disabling FlexFEC.";
139+
return nullptr;
140+
}
141+
142+
if (rtp.flexfec.protected_media_ssrcs.size() > 1) {
143+
RTC_LOG(LS_WARNING)
144+
<< "The supplied FlexfecConfig contained multiple protected "
145+
"media streams, but our implementation currently only "
146+
"supports protecting a single media stream. "
147+
"To avoid confusion, disabling FlexFEC completely.";
148+
return nullptr;
149+
}
150+
151+
if (absl::c_find(rtp.flexfec.protected_media_ssrcs,
152+
rtp.ssrcs[simulcast_index]) ==
153+
rtp.flexfec.protected_media_ssrcs.end()) {
154+
// Media SSRC not among flexfec protected SSRCs.
155+
return nullptr;
156+
}
157+
158+
const RtpState* rtp_state = nullptr;
159+
auto it = suspended_ssrcs.find(rtp.flexfec.ssrc);
160+
if (it != suspended_ssrcs.end()) {
161+
rtp_state = &it->second;
162+
}
163+
164+
RTC_DCHECK_EQ(1U, rtp.flexfec.protected_media_ssrcs.size());
165+
return std::make_unique<FlexfecSender>(
166+
rtp.flexfec.payload_type, rtp.flexfec.ssrc,
167+
rtp.flexfec.protected_media_ssrcs[0], rtp.mid, rtp.extensions,
168+
RTPSender::FecExtensionSizes(), rtp_state, clock);
169+
} else if (rtp.ulpfec.red_payload_type >= 0 &&
170+
rtp.ulpfec.ulpfec_payload_type >= 0 &&
171+
!ShouldDisableRedAndUlpfec(/*flexfec_enabled=*/false, rtp)) {
172+
// Flexfec not configured, but ulpfec is and is not disabled.
173+
return std::make_unique<UlpfecGenerator>(
174+
rtp.ulpfec.red_payload_type, rtp.ulpfec.ulpfec_payload_type, clock);
175+
}
176+
177+
// Not a single FEC is given.
178+
return nullptr;
179+
}
180+
116181
std::vector<RtpStreamSender> CreateRtpStreamSenders(
117182
Clock* clock,
118183
const RtpConfig& rtp_config,
@@ -121,7 +186,7 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
121186
Transport* send_transport,
122187
RtcpBandwidthObserver* bandwidth_callback,
123188
RtpTransportControllerSendInterface* transport,
124-
FlexfecSender* flexfec_sender,
189+
const std::map<uint32_t, RtpState>& suspended_ssrcs,
125190
RtcEventLog* event_log,
126191
RateLimiter* retransmission_rate_limiter,
127192
OverheadObserver* overhead_observer,
@@ -161,18 +226,17 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
161226
configuration.rtcp_report_interval_ms = rtcp_report_interval_ms;
162227

163228
std::vector<RtpStreamSender> rtp_streams;
164-
const std::vector<uint32_t>& flexfec_protected_ssrcs =
165-
rtp_config.flexfec.protected_media_ssrcs;
229+
166230
RTC_DCHECK(rtp_config.rtx.ssrcs.empty() ||
167231
rtp_config.rtx.ssrcs.size() == rtp_config.rtx.ssrcs.size());
168232
for (size_t i = 0; i < rtp_config.ssrcs.size(); ++i) {
233+
RTPSenderVideo::Config video_config;
169234
configuration.local_media_ssrc = rtp_config.ssrcs[i];
170-
bool enable_flexfec = flexfec_sender != nullptr &&
171-
std::find(flexfec_protected_ssrcs.begin(),
172-
flexfec_protected_ssrcs.end(),
173-
configuration.local_media_ssrc) !=
174-
flexfec_protected_ssrcs.end();
175-
configuration.flexfec_sender = enable_flexfec ? flexfec_sender : nullptr;
235+
236+
std::unique_ptr<VideoFecGenerator> fec_generator =
237+
MaybeCreateFecGenerator(clock, rtp_config, suspended_ssrcs, i);
238+
configuration.fec_generator = fec_generator.get();
239+
video_config.fec_generator = fec_generator.get();
176240

177241
if (rtp_config.rtx.ssrcs.size() > i) {
178242
configuration.rtx_send_ssrc = rtp_config.rtx.ssrcs[i];
@@ -188,76 +252,31 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
188252
rtp_rtcp->SetStorePacketsStatus(true, kMinSendSidePacketHistorySize);
189253

190254
FieldTrialBasedConfig field_trial_config;
191-
RTPSenderVideo::Config video_config;
192255
video_config.clock = configuration.clock;
193256
video_config.rtp_sender = rtp_rtcp->RtpSender();
194-
video_config.flexfec_sender = configuration.flexfec_sender;
195257
video_config.frame_encryptor = frame_encryptor;
196258
video_config.require_frame_encryption =
197259
crypto_options.sframe.require_frame_encryption;
198260
video_config.enable_retransmit_all_layers = false;
199261
video_config.field_trials = &field_trial_config;
262+
263+
const bool using_flexfec =
264+
fec_generator &&
265+
fec_generator->GetFecType() == VideoFecGenerator::FecType::kFlexFec;
200266
const bool should_disable_red_and_ulpfec =
201-
ShouldDisableRedAndUlpfec(enable_flexfec, rtp_config);
202-
if (rtp_config.ulpfec.red_payload_type != -1 &&
203-
!should_disable_red_and_ulpfec) {
267+
ShouldDisableRedAndUlpfec(using_flexfec, rtp_config);
268+
if (!should_disable_red_and_ulpfec &&
269+
rtp_config.ulpfec.red_payload_type != -1) {
204270
video_config.red_payload_type = rtp_config.ulpfec.red_payload_type;
205271
}
206-
if (rtp_config.ulpfec.ulpfec_payload_type != -1 &&
207-
!should_disable_red_and_ulpfec) {
208-
video_config.ulpfec_payload_type = rtp_config.ulpfec.ulpfec_payload_type;
209-
}
210272
video_config.frame_transformer = std::move(frame_transformer);
211273
auto sender_video = std::make_unique<RTPSenderVideo>(video_config);
212-
rtp_streams.emplace_back(std::move(rtp_rtcp), std::move(sender_video));
274+
rtp_streams.emplace_back(std::move(rtp_rtcp), std::move(sender_video),
275+
std::move(fec_generator));
213276
}
214277
return rtp_streams;
215278
}
216279

217-
// TODO(brandtr): Update this function when we support multistream protection.
218-
std::unique_ptr<FlexfecSender> MaybeCreateFlexfecSender(
219-
Clock* clock,
220-
const RtpConfig& rtp,
221-
const std::map<uint32_t, RtpState>& suspended_ssrcs) {
222-
if (rtp.flexfec.payload_type < 0) {
223-
return nullptr;
224-
}
225-
RTC_DCHECK_GE(rtp.flexfec.payload_type, 0);
226-
RTC_DCHECK_LE(rtp.flexfec.payload_type, 127);
227-
if (rtp.flexfec.ssrc == 0) {
228-
RTC_LOG(LS_WARNING) << "FlexFEC is enabled, but no FlexFEC SSRC given. "
229-
"Therefore disabling FlexFEC.";
230-
return nullptr;
231-
}
232-
if (rtp.flexfec.protected_media_ssrcs.empty()) {
233-
RTC_LOG(LS_WARNING)
234-
<< "FlexFEC is enabled, but no protected media SSRC given. "
235-
"Therefore disabling FlexFEC.";
236-
return nullptr;
237-
}
238-
239-
if (rtp.flexfec.protected_media_ssrcs.size() > 1) {
240-
RTC_LOG(LS_WARNING)
241-
<< "The supplied FlexfecConfig contained multiple protected "
242-
"media streams, but our implementation currently only "
243-
"supports protecting a single media stream. "
244-
"To avoid confusion, disabling FlexFEC completely.";
245-
return nullptr;
246-
}
247-
248-
const RtpState* rtp_state = nullptr;
249-
auto it = suspended_ssrcs.find(rtp.flexfec.ssrc);
250-
if (it != suspended_ssrcs.end()) {
251-
rtp_state = &it->second;
252-
}
253-
254-
RTC_DCHECK_EQ(1U, rtp.flexfec.protected_media_ssrcs.size());
255-
return std::make_unique<FlexfecSender>(
256-
rtp.flexfec.payload_type, rtp.flexfec.ssrc,
257-
rtp.flexfec.protected_media_ssrcs[0], rtp.mid, rtp.extensions,
258-
RTPSender::FecExtensionSizes(), rtp_state, clock);
259-
}
260-
261280
DataRate CalculateOverheadRate(DataRate data_rate,
262281
DataSize packet_size,
263282
DataSize overhead_per_packet) {
@@ -305,8 +324,6 @@ RtpVideoSender::RtpVideoSender(
305324
active_(false),
306325
module_process_thread_(nullptr),
307326
suspended_ssrcs_(std::move(suspended_ssrcs)),
308-
flexfec_sender_(
309-
MaybeCreateFlexfecSender(clock, rtp_config, suspended_ssrcs_)),
310327
fec_controller_(std::move(fec_controller)),
311328
fec_allowed_(true),
312329
rtp_streams_(CreateRtpStreamSenders(clock,
@@ -316,7 +333,7 @@ RtpVideoSender::RtpVideoSender(
316333
send_transport,
317334
transport->GetBandwidthObserver(),
318335
transport,
319-
flexfec_sender_.get(),
336+
suspended_ssrcs_,
320337
event_log,
321338
retransmission_limiter,
322339
this,
@@ -379,6 +396,7 @@ RtpVideoSender::RtpVideoSender(
379396
}
380397
}
381398

399+
bool fec_enabled = false;
382400
for (const RtpStreamSender& stream : rtp_streams_) {
383401
// Simulcast has one module for each layer. Set the CNAME on all modules.
384402
stream.rtp_rtcp->SetCNAME(rtp_config_.c_name.c_str());
@@ -388,10 +406,13 @@ RtpVideoSender::RtpVideoSender(
388406
stream.rtp_rtcp->SetMaxRtpPacketSize(rtp_config_.max_packet_size);
389407
stream.rtp_rtcp->RegisterSendPayloadFrequency(rtp_config_.payload_type,
390408
kVideoPayloadTypeFrequency);
409+
if (stream.fec_generator != nullptr) {
410+
fec_enabled = true;
411+
}
391412
}
392413
// Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic,
393414
// so enable that logic if either of those FEC schemes are enabled.
394-
fec_controller_->SetProtectionMethod(FecEnabled(), NackEnabled());
415+
fec_controller_->SetProtectionMethod(fec_enabled, NackEnabled());
395416

396417
fec_controller_->SetProtectionCallback(this);
397418
// Signal congestion controller this object is ready for OnPacket* callbacks.
@@ -559,14 +580,6 @@ void RtpVideoSender::OnBitrateAllocationUpdated(
559580
}
560581
}
561582

562-
bool RtpVideoSender::FecEnabled() const {
563-
const bool flexfec_enabled = (flexfec_sender_ != nullptr);
564-
const bool ulpfec_enabled =
565-
!webrtc::field_trial::IsEnabled("WebRTC-DisableUlpFecExperiment") &&
566-
(rtp_config_.ulpfec.ulpfec_payload_type >= 0);
567-
return flexfec_enabled || ulpfec_enabled;
568-
}
569-
570583
bool RtpVideoSender::NackEnabled() const {
571584
const bool nack_enabled = rtp_config_.nack.rtp_history_ms > 0;
572585
return nack_enabled;
@@ -661,18 +674,21 @@ std::map<uint32_t, RtpState> RtpVideoSender::GetRtpStates() const {
661674
uint32_t ssrc = rtp_config_.ssrcs[i];
662675
RTC_DCHECK_EQ(ssrc, rtp_streams_[i].rtp_rtcp->SSRC());
663676
rtp_states[ssrc] = rtp_streams_[i].rtp_rtcp->GetRtpState();
677+
678+
VideoFecGenerator* fec_generator = rtp_streams_[i].fec_generator.get();
679+
if (fec_generator &&
680+
fec_generator->GetFecType() == VideoFecGenerator::FecType::kFlexFec) {
681+
auto* flexfec_sender = static_cast<FlexfecSender*>(fec_generator);
682+
uint32_t ssrc = rtp_config_.flexfec.ssrc;
683+
rtp_states[ssrc] = flexfec_sender->GetRtpState();
684+
}
664685
}
665686

666687
for (size_t i = 0; i < rtp_config_.rtx.ssrcs.size(); ++i) {
667688
uint32_t ssrc = rtp_config_.rtx.ssrcs[i];
668689
rtp_states[ssrc] = rtp_streams_[i].rtp_rtcp->GetRtxState();
669690
}
670691

671-
if (flexfec_sender_) {
672-
uint32_t ssrc = rtp_config_.flexfec.ssrc;
673-
rtp_states[ssrc] = flexfec_sender_->GetRtpState();
674-
}
675-
676692
return rtp_states;
677693
}
678694

call/rtp_video_sender.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ namespace webrtc_internal_rtp_video_sender {
5151
// RtpVideoSender.
5252
struct RtpStreamSender {
5353
RtpStreamSender(std::unique_ptr<RtpRtcp> rtp_rtcp,
54-
std::unique_ptr<RTPSenderVideo> sender_video);
54+
std::unique_ptr<RTPSenderVideo> sender_video,
55+
std::unique_ptr<VideoFecGenerator> fec_generator);
5556
~RtpStreamSender();
5657

5758
RtpStreamSender(RtpStreamSender&&) = default;
@@ -60,6 +61,7 @@ struct RtpStreamSender {
6061
// Note: Needs pointer stability.
6162
std::unique_ptr<RtpRtcp> rtp_rtcp;
6263
std::unique_ptr<RTPSenderVideo> sender_video;
64+
std::unique_ptr<VideoFecGenerator> fec_generator;
6365
};
6466

6567
} // namespace webrtc_internal_rtp_video_sender
@@ -155,7 +157,6 @@ class RtpVideoSender : public RtpVideoSenderInterface,
155157
void ConfigureProtection();
156158
void ConfigureSsrcs();
157159
void ConfigureRids();
158-
bool FecEnabled() const;
159160
bool NackEnabled() const;
160161
uint32_t GetPacketizationOverheadRate() const;
161162

@@ -173,8 +174,6 @@ class RtpVideoSender : public RtpVideoSenderInterface,
173174
rtc::ThreadChecker module_process_thread_checker_;
174175
std::map<uint32_t, RtpState> suspended_ssrcs_;
175176

176-
std::unique_ptr<FlexfecSender> flexfec_sender_;
177-
178177
const std::unique_ptr<FecController> fec_controller_;
179178
bool fec_allowed_ RTC_GUARDED_BY(crit_);
180179

modules/include/module_fec_types.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ enum FecMaskType {
2424

2525
// Struct containing forward error correction settings.
2626
struct FecProtectionParams {
27-
int fec_rate;
28-
int max_fec_frames;
29-
FecMaskType fec_mask_type;
27+
int fec_rate = 0;
28+
int max_fec_frames = 0;
29+
FecMaskType fec_mask_type = FecMaskType::kFecMaskRandom;
3030
};
3131

3232
} // namespace webrtc

modules/rtp_rtcp/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ rtc_library("rtp_rtcp") {
214214
"source/ulpfec_header_reader_writer.h",
215215
"source/ulpfec_receiver_impl.cc",
216216
"source/ulpfec_receiver_impl.h",
217+
"source/video_fec_generator.h",
217218
"source/video_rtp_depacketizer.h",
218219
"source/video_rtp_depacketizer_av1.cc",
219220
"source/video_rtp_depacketizer_av1.h",

0 commit comments

Comments
 (0)