@@ -36,9 +36,13 @@ namespace webrtc {
36
36
37
37
namespace webrtc_internal_rtp_video_sender {
38
38
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)) {}
42
46
43
47
RtpStreamSender::~RtpStreamSender () = default ;
44
48
@@ -113,6 +117,67 @@ bool ShouldDisableRedAndUlpfec(bool flexfec_enabled,
113
117
return should_disable_red_and_ulpfec;
114
118
}
115
119
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
+
116
181
std::vector<RtpStreamSender> CreateRtpStreamSenders (
117
182
Clock* clock,
118
183
const RtpConfig& rtp_config,
@@ -121,7 +186,7 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
121
186
Transport* send_transport,
122
187
RtcpBandwidthObserver* bandwidth_callback,
123
188
RtpTransportControllerSendInterface* transport,
124
- FlexfecSender* flexfec_sender ,
189
+ const std::map< uint32_t , RtpState>& suspended_ssrcs ,
125
190
RtcEventLog* event_log,
126
191
RateLimiter* retransmission_rate_limiter,
127
192
OverheadObserver* overhead_observer,
@@ -161,18 +226,17 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
161
226
configuration.rtcp_report_interval_ms = rtcp_report_interval_ms;
162
227
163
228
std::vector<RtpStreamSender> rtp_streams;
164
- const std::vector<uint32_t >& flexfec_protected_ssrcs =
165
- rtp_config.flexfec .protected_media_ssrcs ;
229
+
166
230
RTC_DCHECK (rtp_config.rtx .ssrcs .empty () ||
167
231
rtp_config.rtx .ssrcs .size () == rtp_config.rtx .ssrcs .size ());
168
232
for (size_t i = 0 ; i < rtp_config.ssrcs .size (); ++i) {
233
+ RTPSenderVideo::Config video_config;
169
234
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 ();
176
240
177
241
if (rtp_config.rtx .ssrcs .size () > i) {
178
242
configuration.rtx_send_ssrc = rtp_config.rtx .ssrcs [i];
@@ -188,76 +252,31 @@ std::vector<RtpStreamSender> CreateRtpStreamSenders(
188
252
rtp_rtcp->SetStorePacketsStatus (true , kMinSendSidePacketHistorySize );
189
253
190
254
FieldTrialBasedConfig field_trial_config;
191
- RTPSenderVideo::Config video_config;
192
255
video_config.clock = configuration.clock ;
193
256
video_config.rtp_sender = rtp_rtcp->RtpSender ();
194
- video_config.flexfec_sender = configuration.flexfec_sender ;
195
257
video_config.frame_encryptor = frame_encryptor;
196
258
video_config.require_frame_encryption =
197
259
crypto_options.sframe .require_frame_encryption ;
198
260
video_config.enable_retransmit_all_layers = false ;
199
261
video_config.field_trials = &field_trial_config;
262
+
263
+ const bool using_flexfec =
264
+ fec_generator &&
265
+ fec_generator->GetFecType () == VideoFecGenerator::FecType::kFlexFec ;
200
266
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 ) {
204
270
video_config.red_payload_type = rtp_config.ulpfec .red_payload_type ;
205
271
}
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
- }
210
272
video_config.frame_transformer = std::move (frame_transformer);
211
273
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));
213
276
}
214
277
return rtp_streams;
215
278
}
216
279
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
-
261
280
DataRate CalculateOverheadRate (DataRate data_rate,
262
281
DataSize packet_size,
263
282
DataSize overhead_per_packet) {
@@ -305,8 +324,6 @@ RtpVideoSender::RtpVideoSender(
305
324
active_(false ),
306
325
module_process_thread_(nullptr ),
307
326
suspended_ssrcs_(std::move(suspended_ssrcs)),
308
- flexfec_sender_(
309
- MaybeCreateFlexfecSender (clock, rtp_config, suspended_ssrcs_)),
310
327
fec_controller_(std::move(fec_controller)),
311
328
fec_allowed_(true ),
312
329
rtp_streams_(CreateRtpStreamSenders(clock,
@@ -316,7 +333,7 @@ RtpVideoSender::RtpVideoSender(
316
333
send_transport,
317
334
transport->GetBandwidthObserver (),
318
335
transport,
319
- flexfec_sender_.get() ,
336
+ suspended_ssrcs_ ,
320
337
event_log,
321
338
retransmission_limiter,
322
339
this,
@@ -379,6 +396,7 @@ RtpVideoSender::RtpVideoSender(
379
396
}
380
397
}
381
398
399
+ bool fec_enabled = false ;
382
400
for (const RtpStreamSender& stream : rtp_streams_) {
383
401
// Simulcast has one module for each layer. Set the CNAME on all modules.
384
402
stream.rtp_rtcp ->SetCNAME (rtp_config_.c_name .c_str ());
@@ -388,10 +406,13 @@ RtpVideoSender::RtpVideoSender(
388
406
stream.rtp_rtcp ->SetMaxRtpPacketSize (rtp_config_.max_packet_size );
389
407
stream.rtp_rtcp ->RegisterSendPayloadFrequency (rtp_config_.payload_type ,
390
408
kVideoPayloadTypeFrequency );
409
+ if (stream.fec_generator != nullptr ) {
410
+ fec_enabled = true ;
411
+ }
391
412
}
392
413
// Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic,
393
414
// 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 ());
395
416
396
417
fec_controller_->SetProtectionCallback (this );
397
418
// Signal congestion controller this object is ready for OnPacket* callbacks.
@@ -559,14 +580,6 @@ void RtpVideoSender::OnBitrateAllocationUpdated(
559
580
}
560
581
}
561
582
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
-
570
583
bool RtpVideoSender::NackEnabled () const {
571
584
const bool nack_enabled = rtp_config_.nack .rtp_history_ms > 0 ;
572
585
return nack_enabled;
@@ -661,18 +674,21 @@ std::map<uint32_t, RtpState> RtpVideoSender::GetRtpStates() const {
661
674
uint32_t ssrc = rtp_config_.ssrcs [i];
662
675
RTC_DCHECK_EQ (ssrc, rtp_streams_[i].rtp_rtcp ->SSRC ());
663
676
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
+ }
664
685
}
665
686
666
687
for (size_t i = 0 ; i < rtp_config_.rtx .ssrcs .size (); ++i) {
667
688
uint32_t ssrc = rtp_config_.rtx .ssrcs [i];
668
689
rtp_states[ssrc] = rtp_streams_[i].rtp_rtcp ->GetRtxState ();
669
690
}
670
691
671
- if (flexfec_sender_) {
672
- uint32_t ssrc = rtp_config_.flexfec .ssrc ;
673
- rtp_states[ssrc] = flexfec_sender_->GetRtpState ();
674
- }
675
-
676
692
return rtp_states;
677
693
}
678
694
0 commit comments