1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "call/rtp_video_sender.h"
12
13 #include <algorithm>
14 #include <memory>
15 #include <string>
16 #include <utility>
17
18 #include "absl/algorithm/container.h"
19 #include "absl/strings/match.h"
20 #include "api/array_view.h"
21 #include "api/transport/field_trial_based_config.h"
22 #include "api/video_codecs/video_codec.h"
23 #include "call/rtp_transport_controller_send_interface.h"
24 #include "modules/pacing/packet_router.h"
25 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
26 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
27 #include "modules/rtp_rtcp/source/rtp_sender.h"
28 #include "modules/utility/include/process_thread.h"
29 #include "modules/video_coding/include/video_codec_interface.h"
30 #include "rtc_base/checks.h"
31 #include "rtc_base/location.h"
32 #include "rtc_base/logging.h"
33 #include "rtc_base/task_queue.h"
34
35 namespace webrtc {
36
37 namespace webrtc_internal_rtp_video_sender {
38
RtpStreamSender(std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp,std::unique_ptr<RTPSenderVideo> sender_video,std::unique_ptr<VideoFecGenerator> fec_generator)39 RtpStreamSender::RtpStreamSender(
40 std::unique_ptr<ModuleRtpRtcpImpl2> 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)) {}
46
47 RtpStreamSender::~RtpStreamSender() = default;
48
49 } // namespace webrtc_internal_rtp_video_sender
50
51 namespace {
52 static const int kMinSendSidePacketHistorySize = 600;
53 // We don't do MTU discovery, so assume that we have the standard ethernet MTU.
54 static const size_t kPathMTU = 1500;
55
56 using webrtc_internal_rtp_video_sender::RtpStreamSender;
57
PayloadTypeSupportsSkippingFecPackets(const std::string & payload_name,const WebRtcKeyValueConfig & trials)58 bool PayloadTypeSupportsSkippingFecPackets(const std::string& payload_name,
59 const WebRtcKeyValueConfig& trials) {
60 const VideoCodecType codecType = PayloadStringToCodecType(payload_name);
61 if (codecType == kVideoCodecVP8 || codecType == kVideoCodecVP9) {
62 return true;
63 }
64 if (codecType == kVideoCodecGeneric &&
65 absl::StartsWith(trials.Lookup("WebRTC-GenericPictureId"), "Enabled")) {
66 return true;
67 }
68 return false;
69 }
70
ShouldDisableRedAndUlpfec(bool flexfec_enabled,const RtpConfig & rtp_config,const WebRtcKeyValueConfig & trials)71 bool ShouldDisableRedAndUlpfec(bool flexfec_enabled,
72 const RtpConfig& rtp_config,
73 const WebRtcKeyValueConfig& trials) {
74 // Consistency of NACK and RED+ULPFEC parameters is checked in this function.
75 const bool nack_enabled = rtp_config.nack.rtp_history_ms > 0;
76
77 // Shorthands.
78 auto IsRedEnabled = [&]() { return rtp_config.ulpfec.red_payload_type >= 0; };
79 auto IsUlpfecEnabled = [&]() {
80 return rtp_config.ulpfec.ulpfec_payload_type >= 0;
81 };
82
83 bool should_disable_red_and_ulpfec = false;
84
85 if (absl::StartsWith(trials.Lookup("WebRTC-DisableUlpFecExperiment"),
86 "Enabled")) {
87 RTC_LOG(LS_INFO) << "Experiment to disable sending ULPFEC is enabled.";
88 should_disable_red_and_ulpfec = true;
89 }
90
91 // If enabled, FlexFEC takes priority over RED+ULPFEC.
92 if (flexfec_enabled) {
93 if (IsUlpfecEnabled()) {
94 RTC_LOG(LS_INFO)
95 << "Both FlexFEC and ULPFEC are configured. Disabling ULPFEC.";
96 }
97 should_disable_red_and_ulpfec = true;
98 }
99
100 // Payload types without picture ID cannot determine that a stream is complete
101 // without retransmitting FEC, so using ULPFEC + NACK for H.264 (for instance)
102 // is a waste of bandwidth since FEC packets still have to be transmitted.
103 // Note that this is not the case with FlexFEC.
104 if (nack_enabled && IsUlpfecEnabled() &&
105 !PayloadTypeSupportsSkippingFecPackets(rtp_config.payload_name, trials)) {
106 RTC_LOG(LS_WARNING)
107 << "Transmitting payload type without picture ID using "
108 "NACK+ULPFEC is a waste of bandwidth since ULPFEC packets "
109 "also have to be retransmitted. Disabling ULPFEC.";
110 should_disable_red_and_ulpfec = true;
111 }
112
113 // Verify payload types.
114 if (IsUlpfecEnabled() ^ IsRedEnabled()) {
115 RTC_LOG(LS_WARNING)
116 << "Only RED or only ULPFEC enabled, but not both. Disabling both.";
117 should_disable_red_and_ulpfec = true;
118 }
119
120 return should_disable_red_and_ulpfec;
121 }
122
123 // TODO(brandtr): Update this function when we support multistream protection.
MaybeCreateFecGenerator(Clock * clock,const RtpConfig & rtp,const std::map<uint32_t,RtpState> & suspended_ssrcs,int simulcast_index,const WebRtcKeyValueConfig & trials)124 std::unique_ptr<VideoFecGenerator> MaybeCreateFecGenerator(
125 Clock* clock,
126 const RtpConfig& rtp,
127 const std::map<uint32_t, RtpState>& suspended_ssrcs,
128 int simulcast_index,
129 const WebRtcKeyValueConfig& trials) {
130 // If flexfec is configured that takes priority.
131 if (rtp.flexfec.payload_type >= 0) {
132 RTC_DCHECK_GE(rtp.flexfec.payload_type, 0);
133 RTC_DCHECK_LE(rtp.flexfec.payload_type, 127);
134 if (rtp.flexfec.ssrc == 0) {
135 RTC_LOG(LS_WARNING) << "FlexFEC is enabled, but no FlexFEC SSRC given. "
136 "Therefore disabling FlexFEC.";
137 return nullptr;
138 }
139 if (rtp.flexfec.protected_media_ssrcs.empty()) {
140 RTC_LOG(LS_WARNING)
141 << "FlexFEC is enabled, but no protected media SSRC given. "
142 "Therefore disabling FlexFEC.";
143 return nullptr;
144 }
145
146 if (rtp.flexfec.protected_media_ssrcs.size() > 1) {
147 RTC_LOG(LS_WARNING)
148 << "The supplied FlexfecConfig contained multiple protected "
149 "media streams, but our implementation currently only "
150 "supports protecting a single media stream. "
151 "To avoid confusion, disabling FlexFEC completely.";
152 return nullptr;
153 }
154
155 if (absl::c_find(rtp.flexfec.protected_media_ssrcs,
156 rtp.ssrcs[simulcast_index]) ==
157 rtp.flexfec.protected_media_ssrcs.end()) {
158 // Media SSRC not among flexfec protected SSRCs.
159 return nullptr;
160 }
161
162 const RtpState* rtp_state = nullptr;
163 auto it = suspended_ssrcs.find(rtp.flexfec.ssrc);
164 if (it != suspended_ssrcs.end()) {
165 rtp_state = &it->second;
166 }
167
168 RTC_DCHECK_EQ(1U, rtp.flexfec.protected_media_ssrcs.size());
169 return std::make_unique<FlexfecSender>(
170 rtp.flexfec.payload_type, rtp.flexfec.ssrc,
171 rtp.flexfec.protected_media_ssrcs[0], rtp.mid, rtp.extensions,
172 RTPSender::FecExtensionSizes(), rtp_state, clock);
173 } else if (rtp.ulpfec.red_payload_type >= 0 &&
174 rtp.ulpfec.ulpfec_payload_type >= 0 &&
175 !ShouldDisableRedAndUlpfec(/*flexfec_enabled=*/false, rtp,
176 trials)) {
177 // Flexfec not configured, but ulpfec is and is not disabled.
178 return std::make_unique<UlpfecGenerator>(
179 rtp.ulpfec.red_payload_type, rtp.ulpfec.ulpfec_payload_type, clock);
180 }
181
182 // Not a single FEC is given.
183 return nullptr;
184 }
185
CreateRtpStreamSenders(Clock * clock,const RtpConfig & rtp_config,const RtpSenderObservers & observers,int rtcp_report_interval_ms,Transport * send_transport,RtcpBandwidthObserver * bandwidth_callback,RtpTransportControllerSendInterface * transport,const std::map<uint32_t,RtpState> & suspended_ssrcs,RtcEventLog * event_log,RateLimiter * retransmission_rate_limiter,FrameEncryptorInterface * frame_encryptor,const CryptoOptions & crypto_options,rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,bool use_deferred_fec,const WebRtcKeyValueConfig & trials)186 std::vector<RtpStreamSender> CreateRtpStreamSenders(
187 Clock* clock,
188 const RtpConfig& rtp_config,
189 const RtpSenderObservers& observers,
190 int rtcp_report_interval_ms,
191 Transport* send_transport,
192 RtcpBandwidthObserver* bandwidth_callback,
193 RtpTransportControllerSendInterface* transport,
194 const std::map<uint32_t, RtpState>& suspended_ssrcs,
195 RtcEventLog* event_log,
196 RateLimiter* retransmission_rate_limiter,
197 FrameEncryptorInterface* frame_encryptor,
198 const CryptoOptions& crypto_options,
199 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
200 bool use_deferred_fec,
201 const WebRtcKeyValueConfig& trials) {
202 RTC_DCHECK_GT(rtp_config.ssrcs.size(), 0);
203
204 RtpRtcpInterface::Configuration configuration;
205 configuration.clock = clock;
206 configuration.audio = false;
207 configuration.receiver_only = false;
208 configuration.outgoing_transport = send_transport;
209 configuration.intra_frame_callback = observers.intra_frame_callback;
210 configuration.rtcp_loss_notification_observer =
211 observers.rtcp_loss_notification_observer;
212 configuration.bandwidth_callback = bandwidth_callback;
213 configuration.network_state_estimate_observer =
214 transport->network_state_estimate_observer();
215 configuration.transport_feedback_callback =
216 transport->transport_feedback_observer();
217 configuration.rtt_stats = observers.rtcp_rtt_stats;
218 configuration.rtcp_packet_type_counter_observer =
219 observers.rtcp_type_observer;
220 configuration.rtcp_statistics_callback = observers.rtcp_stats;
221 configuration.report_block_data_observer =
222 observers.report_block_data_observer;
223 configuration.paced_sender = transport->packet_sender();
224 configuration.send_bitrate_observer = observers.bitrate_observer;
225 configuration.send_side_delay_observer = observers.send_delay_observer;
226 configuration.send_packet_observer = observers.send_packet_observer;
227 configuration.event_log = event_log;
228 configuration.retransmission_rate_limiter = retransmission_rate_limiter;
229 configuration.rtp_stats_callback = observers.rtp_stats;
230 configuration.frame_encryptor = frame_encryptor;
231 configuration.require_frame_encryption =
232 crypto_options.sframe.require_frame_encryption;
233 configuration.extmap_allow_mixed = rtp_config.extmap_allow_mixed;
234 configuration.rtcp_report_interval_ms = rtcp_report_interval_ms;
235 configuration.field_trials = &trials;
236
237 std::vector<RtpStreamSender> rtp_streams;
238
239 RTC_DCHECK(rtp_config.rtx.ssrcs.empty() ||
240 rtp_config.rtx.ssrcs.size() == rtp_config.ssrcs.size());
241 for (size_t i = 0; i < rtp_config.ssrcs.size(); ++i) {
242 RTPSenderVideo::Config video_config;
243 configuration.local_media_ssrc = rtp_config.ssrcs[i];
244
245 std::unique_ptr<VideoFecGenerator> fec_generator =
246 MaybeCreateFecGenerator(clock, rtp_config, suspended_ssrcs, i, trials);
247 configuration.fec_generator = fec_generator.get();
248 if (!use_deferred_fec) {
249 video_config.fec_generator = fec_generator.get();
250 }
251
252 configuration.rtx_send_ssrc =
253 rtp_config.GetRtxSsrcAssociatedWithMediaSsrc(rtp_config.ssrcs[i]);
254 RTC_DCHECK_EQ(configuration.rtx_send_ssrc.has_value(),
255 !rtp_config.rtx.ssrcs.empty());
256
257 configuration.need_rtp_packet_infos = rtp_config.lntf.enabled;
258
259 std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp(
260 ModuleRtpRtcpImpl2::Create(configuration));
261 rtp_rtcp->SetSendingStatus(false);
262 rtp_rtcp->SetSendingMediaStatus(false);
263 rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
264 // Set NACK.
265 rtp_rtcp->SetStorePacketsStatus(true, kMinSendSidePacketHistorySize);
266
267 video_config.clock = configuration.clock;
268 video_config.rtp_sender = rtp_rtcp->RtpSender();
269 video_config.frame_encryptor = frame_encryptor;
270 video_config.require_frame_encryption =
271 crypto_options.sframe.require_frame_encryption;
272 video_config.enable_retransmit_all_layers = false;
273 video_config.field_trials = &trials;
274
275 const bool using_flexfec =
276 fec_generator &&
277 fec_generator->GetFecType() == VideoFecGenerator::FecType::kFlexFec;
278 const bool should_disable_red_and_ulpfec =
279 ShouldDisableRedAndUlpfec(using_flexfec, rtp_config, trials);
280 if (!should_disable_red_and_ulpfec &&
281 rtp_config.ulpfec.red_payload_type != -1) {
282 video_config.red_payload_type = rtp_config.ulpfec.red_payload_type;
283 }
284 if (fec_generator) {
285 video_config.fec_type = fec_generator->GetFecType();
286 video_config.fec_overhead_bytes = fec_generator->MaxPacketOverhead();
287 }
288 video_config.frame_transformer = frame_transformer;
289 video_config.send_transport_queue = transport->GetWorkerQueue()->Get();
290 auto sender_video = std::make_unique<RTPSenderVideo>(video_config);
291 rtp_streams.emplace_back(std::move(rtp_rtcp), std::move(sender_video),
292 std::move(fec_generator));
293 }
294 return rtp_streams;
295 }
296
CalculateOverheadRate(DataRate data_rate,DataSize packet_size,DataSize overhead_per_packet)297 DataRate CalculateOverheadRate(DataRate data_rate,
298 DataSize packet_size,
299 DataSize overhead_per_packet) {
300 Frequency packet_rate = data_rate / packet_size;
301 // TOSO(srte): We should not need to round to nearest whole packet per second
302 // rate here.
303 return packet_rate.RoundUpTo(Frequency::Hertz(1)) * overhead_per_packet;
304 }
305
GetVideoCodecType(const RtpConfig & config)306 absl::optional<VideoCodecType> GetVideoCodecType(const RtpConfig& config) {
307 if (config.raw_payload) {
308 return absl::nullopt;
309 }
310 return PayloadStringToCodecType(config.payload_name);
311 }
TransportSeqNumExtensionConfigured(const RtpConfig & config)312 bool TransportSeqNumExtensionConfigured(const RtpConfig& config) {
313 return absl::c_any_of(config.extensions, [](const RtpExtension& ext) {
314 return ext.uri == RtpExtension::kTransportSequenceNumberUri;
315 });
316 }
317 } // namespace
318
RtpVideoSender(Clock * clock,std::map<uint32_t,RtpState> suspended_ssrcs,const std::map<uint32_t,RtpPayloadState> & states,const RtpConfig & rtp_config,int rtcp_report_interval_ms,Transport * send_transport,const RtpSenderObservers & observers,RtpTransportControllerSendInterface * transport,RtcEventLog * event_log,RateLimiter * retransmission_limiter,std::unique_ptr<FecController> fec_controller,FrameEncryptorInterface * frame_encryptor,const CryptoOptions & crypto_options,rtc::scoped_refptr<FrameTransformerInterface> frame_transformer)319 RtpVideoSender::RtpVideoSender(
320 Clock* clock,
321 std::map<uint32_t, RtpState> suspended_ssrcs,
322 const std::map<uint32_t, RtpPayloadState>& states,
323 const RtpConfig& rtp_config,
324 int rtcp_report_interval_ms,
325 Transport* send_transport,
326 const RtpSenderObservers& observers,
327 RtpTransportControllerSendInterface* transport,
328 RtcEventLog* event_log,
329 RateLimiter* retransmission_limiter,
330 std::unique_ptr<FecController> fec_controller,
331 FrameEncryptorInterface* frame_encryptor,
332 const CryptoOptions& crypto_options,
333 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer)
334 : send_side_bwe_with_overhead_(absl::StartsWith(
335 field_trials_.Lookup("WebRTC-SendSideBwe-WithOverhead"),
336 "Enabled")),
337 account_for_packetization_overhead_(!absl::StartsWith(
338 field_trials_.Lookup("WebRTC-SubtractPacketizationOverhead"),
339 "Disabled")),
340 use_early_loss_detection_(!absl::StartsWith(
341 field_trials_.Lookup("WebRTC-UseEarlyLossDetection"),
342 "Disabled")),
343 has_packet_feedback_(TransportSeqNumExtensionConfigured(rtp_config)),
344 use_deferred_fec_(
345 absl::StartsWith(field_trials_.Lookup("WebRTC-DeferredFecGeneration"),
346 "Enabled")),
347 active_(false),
348 module_process_thread_(nullptr),
349 suspended_ssrcs_(std::move(suspended_ssrcs)),
350 fec_controller_(std::move(fec_controller)),
351 fec_allowed_(true),
352 rtp_streams_(CreateRtpStreamSenders(clock,
353 rtp_config,
354 observers,
355 rtcp_report_interval_ms,
356 send_transport,
357 transport->GetBandwidthObserver(),
358 transport,
359 suspended_ssrcs_,
360 event_log,
361 retransmission_limiter,
362 frame_encryptor,
363 crypto_options,
364 std::move(frame_transformer),
365 use_deferred_fec_,
366 field_trials_)),
367 rtp_config_(rtp_config),
368 codec_type_(GetVideoCodecType(rtp_config)),
369 transport_(transport),
370 transport_overhead_bytes_per_packet_(0),
371 encoder_target_rate_bps_(0),
372 frame_counts_(rtp_config.ssrcs.size()),
373 frame_count_observer_(observers.frame_count_observer) {
374 RTC_DCHECK_EQ(rtp_config_.ssrcs.size(), rtp_streams_.size());
375 if (send_side_bwe_with_overhead_ && has_packet_feedback_)
376 transport_->IncludeOverheadInPacedSender();
377 module_process_thread_checker_.Detach();
378 // SSRCs are assumed to be sorted in the same order as |rtp_modules|.
379 for (uint32_t ssrc : rtp_config_.ssrcs) {
380 // Restore state if it previously existed.
381 const RtpPayloadState* state = nullptr;
382 auto it = states.find(ssrc);
383 if (it != states.end()) {
384 state = &it->second;
385 shared_frame_id_ = std::max(shared_frame_id_, state->shared_frame_id);
386 }
387 params_.push_back(RtpPayloadParams(ssrc, state, field_trials_));
388 }
389
390 // RTP/RTCP initialization.
391
392 // We add the highest spatial layer first to ensure it'll be prioritized
393 // when sending padding, with the hope that the packet rate will be smaller,
394 // and that it's more important to protect than the lower layers.
395
396 // TODO(nisse): Consider moving registration with PacketRouter last, after the
397 // modules are fully configured.
398 for (const RtpStreamSender& stream : rtp_streams_) {
399 constexpr bool remb_candidate = true;
400 transport->packet_router()->AddSendRtpModule(stream.rtp_rtcp.get(),
401 remb_candidate);
402 }
403
404 for (size_t i = 0; i < rtp_config_.extensions.size(); ++i) {
405 const std::string& extension = rtp_config_.extensions[i].uri;
406 int id = rtp_config_.extensions[i].id;
407 RTC_DCHECK(RtpExtension::IsSupportedForVideo(extension));
408 for (const RtpStreamSender& stream : rtp_streams_) {
409 stream.rtp_rtcp->RegisterRtpHeaderExtension(extension, id);
410 }
411 }
412
413 ConfigureSsrcs();
414 ConfigureRids();
415
416 if (!rtp_config_.mid.empty()) {
417 for (const RtpStreamSender& stream : rtp_streams_) {
418 stream.rtp_rtcp->SetMid(rtp_config_.mid);
419 }
420 }
421
422 bool fec_enabled = false;
423 for (const RtpStreamSender& stream : rtp_streams_) {
424 // Simulcast has one module for each layer. Set the CNAME on all modules.
425 stream.rtp_rtcp->SetCNAME(rtp_config_.c_name.c_str());
426 stream.rtp_rtcp->SetMaxRtpPacketSize(rtp_config_.max_packet_size);
427 stream.rtp_rtcp->RegisterSendPayloadFrequency(rtp_config_.payload_type,
428 kVideoPayloadTypeFrequency);
429 if (stream.fec_generator != nullptr) {
430 fec_enabled = true;
431 }
432 }
433 // Currently, both ULPFEC and FlexFEC use the same FEC rate calculation logic,
434 // so enable that logic if either of those FEC schemes are enabled.
435 fec_controller_->SetProtectionMethod(fec_enabled, NackEnabled());
436
437 fec_controller_->SetProtectionCallback(this);
438 // Signal congestion controller this object is ready for OnPacket* callbacks.
439 transport_->GetStreamFeedbackProvider()->RegisterStreamFeedbackObserver(
440 rtp_config_.ssrcs, this);
441 }
442
~RtpVideoSender()443 RtpVideoSender::~RtpVideoSender() {
444 for (const RtpStreamSender& stream : rtp_streams_) {
445 transport_->packet_router()->RemoveSendRtpModule(stream.rtp_rtcp.get());
446 }
447 transport_->GetStreamFeedbackProvider()->DeRegisterStreamFeedbackObserver(
448 this);
449 }
450
RegisterProcessThread(ProcessThread * module_process_thread)451 void RtpVideoSender::RegisterProcessThread(
452 ProcessThread* module_process_thread) {
453 RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
454 RTC_DCHECK(!module_process_thread_);
455 module_process_thread_ = module_process_thread;
456
457 for (const RtpStreamSender& stream : rtp_streams_) {
458 module_process_thread_->RegisterModule(stream.rtp_rtcp.get(),
459 RTC_FROM_HERE);
460 }
461 }
462
DeRegisterProcessThread()463 void RtpVideoSender::DeRegisterProcessThread() {
464 RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
465 for (const RtpStreamSender& stream : rtp_streams_)
466 module_process_thread_->DeRegisterModule(stream.rtp_rtcp.get());
467 }
468
SetActive(bool active)469 void RtpVideoSender::SetActive(bool active) {
470 MutexLock lock(&mutex_);
471 if (active_ == active)
472 return;
473 const std::vector<bool> active_modules(rtp_streams_.size(), active);
474 SetActiveModulesLocked(active_modules);
475 }
476
SetActiveModules(const std::vector<bool> active_modules)477 void RtpVideoSender::SetActiveModules(const std::vector<bool> active_modules) {
478 MutexLock lock(&mutex_);
479 return SetActiveModulesLocked(active_modules);
480 }
481
SetActiveModulesLocked(const std::vector<bool> active_modules)482 void RtpVideoSender::SetActiveModulesLocked(
483 const std::vector<bool> active_modules) {
484 RTC_DCHECK_EQ(rtp_streams_.size(), active_modules.size());
485 active_ = false;
486 for (size_t i = 0; i < active_modules.size(); ++i) {
487 if (active_modules[i]) {
488 active_ = true;
489 }
490 // Sends a kRtcpByeCode when going from true to false.
491 rtp_streams_[i].rtp_rtcp->SetSendingStatus(active_modules[i]);
492 // If set to false this module won't send media.
493 rtp_streams_[i].rtp_rtcp->SetSendingMediaStatus(active_modules[i]);
494 }
495 }
496
IsActive()497 bool RtpVideoSender::IsActive() {
498 MutexLock lock(&mutex_);
499 return IsActiveLocked();
500 }
501
IsActiveLocked()502 bool RtpVideoSender::IsActiveLocked() {
503 return active_ && !rtp_streams_.empty();
504 }
505
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info,const RTPFragmentationHeader *)506 EncodedImageCallback::Result RtpVideoSender::OnEncodedImage(
507 const EncodedImage& encoded_image,
508 const CodecSpecificInfo* codec_specific_info,
509 const RTPFragmentationHeader* /*fragmentation*/) {
510 fec_controller_->UpdateWithEncodedData(encoded_image.size(),
511 encoded_image._frameType);
512 MutexLock lock(&mutex_);
513 RTC_DCHECK(!rtp_streams_.empty());
514 if (!active_)
515 return Result(Result::ERROR_SEND_FAILED);
516
517 shared_frame_id_++;
518 size_t stream_index = 0;
519 if (codec_specific_info &&
520 (codec_specific_info->codecType == kVideoCodecVP8 ||
521 codec_specific_info->codecType == kVideoCodecH264 ||
522 codec_specific_info->codecType == kVideoCodecGeneric)) {
523 // Map spatial index to simulcast.
524 stream_index = encoded_image.SpatialIndex().value_or(0);
525 }
526 RTC_DCHECK_LT(stream_index, rtp_streams_.size());
527
528 uint32_t rtp_timestamp =
529 encoded_image.Timestamp() +
530 rtp_streams_[stream_index].rtp_rtcp->StartTimestamp();
531
532 // RTCPSender has it's own copy of the timestamp offset, added in
533 // RTCPSender::BuildSR, hence we must not add the in the offset for this call.
534 // TODO(nisse): Delete RTCPSender:timestamp_offset_, and see if we can confine
535 // knowledge of the offset to a single place.
536 if (!rtp_streams_[stream_index].rtp_rtcp->OnSendingRtpFrame(
537 encoded_image.Timestamp(), encoded_image.capture_time_ms_,
538 rtp_config_.payload_type,
539 encoded_image._frameType == VideoFrameType::kVideoFrameKey)) {
540 // The payload router could be active but this module isn't sending.
541 return Result(Result::ERROR_SEND_FAILED);
542 }
543
544 absl::optional<int64_t> expected_retransmission_time_ms;
545 if (encoded_image.RetransmissionAllowed()) {
546 expected_retransmission_time_ms =
547 rtp_streams_[stream_index].rtp_rtcp->ExpectedRetransmissionTimeMs();
548 }
549
550 if (encoded_image._frameType == VideoFrameType::kVideoFrameKey) {
551 // If encoder adapter produce FrameDependencyStructure, pass it so that
552 // dependency descriptor rtp header extension can be used.
553 // If not supported, disable using dependency descriptor by passing nullptr.
554 rtp_streams_[stream_index].sender_video->SetVideoStructure(
555 (codec_specific_info && codec_specific_info->template_structure)
556 ? &*codec_specific_info->template_structure
557 : nullptr);
558 }
559
560 bool send_result = rtp_streams_[stream_index].sender_video->SendEncodedImage(
561 rtp_config_.payload_type, codec_type_, rtp_timestamp, encoded_image,
562 params_[stream_index].GetRtpVideoHeader(
563 encoded_image, codec_specific_info, shared_frame_id_),
564 expected_retransmission_time_ms);
565 if (frame_count_observer_) {
566 FrameCounts& counts = frame_counts_[stream_index];
567 if (encoded_image._frameType == VideoFrameType::kVideoFrameKey) {
568 ++counts.key_frames;
569 } else if (encoded_image._frameType == VideoFrameType::kVideoFrameDelta) {
570 ++counts.delta_frames;
571 } else {
572 RTC_DCHECK(encoded_image._frameType == VideoFrameType::kEmptyFrame);
573 }
574 frame_count_observer_->FrameCountUpdated(counts,
575 rtp_config_.ssrcs[stream_index]);
576 }
577 if (!send_result)
578 return Result(Result::ERROR_SEND_FAILED);
579
580 return Result(Result::OK, rtp_timestamp);
581 }
582
OnBitrateAllocationUpdated(const VideoBitrateAllocation & bitrate)583 void RtpVideoSender::OnBitrateAllocationUpdated(
584 const VideoBitrateAllocation& bitrate) {
585 MutexLock lock(&mutex_);
586 if (IsActiveLocked()) {
587 if (rtp_streams_.size() == 1) {
588 // If spatial scalability is enabled, it is covered by a single stream.
589 rtp_streams_[0].rtp_rtcp->SetVideoBitrateAllocation(bitrate);
590 } else {
591 std::vector<absl::optional<VideoBitrateAllocation>> layer_bitrates =
592 bitrate.GetSimulcastAllocations();
593 // Simulcast is in use, split the VideoBitrateAllocation into one struct
594 // per rtp stream, moving over the temporal layer allocation.
595 for (size_t i = 0; i < rtp_streams_.size(); ++i) {
596 // The next spatial layer could be used if the current one is
597 // inactive.
598 if (layer_bitrates[i]) {
599 rtp_streams_[i].rtp_rtcp->SetVideoBitrateAllocation(
600 *layer_bitrates[i]);
601 } else {
602 // Signal a 0 bitrate on a simulcast stream.
603 rtp_streams_[i].rtp_rtcp->SetVideoBitrateAllocation(
604 VideoBitrateAllocation());
605 }
606 }
607 }
608 }
609 }
610
NackEnabled() const611 bool RtpVideoSender::NackEnabled() const {
612 const bool nack_enabled = rtp_config_.nack.rtp_history_ms > 0;
613 return nack_enabled;
614 }
615
GetPacketizationOverheadRate() const616 uint32_t RtpVideoSender::GetPacketizationOverheadRate() const {
617 uint32_t packetization_overhead_bps = 0;
618 for (size_t i = 0; i < rtp_streams_.size(); ++i) {
619 if (rtp_streams_[i].rtp_rtcp->SendingMedia()) {
620 packetization_overhead_bps +=
621 rtp_streams_[i].sender_video->PacketizationOverheadBps();
622 }
623 }
624 return packetization_overhead_bps;
625 }
626
DeliverRtcp(const uint8_t * packet,size_t length)627 void RtpVideoSender::DeliverRtcp(const uint8_t* packet, size_t length) {
628 // Runs on a network thread.
629 for (const RtpStreamSender& stream : rtp_streams_)
630 stream.rtp_rtcp->IncomingRtcpPacket(packet, length);
631 }
632
ConfigureSsrcs()633 void RtpVideoSender::ConfigureSsrcs() {
634 // Configure regular SSRCs.
635 RTC_CHECK(ssrc_to_rtp_module_.empty());
636 for (size_t i = 0; i < rtp_config_.ssrcs.size(); ++i) {
637 uint32_t ssrc = rtp_config_.ssrcs[i];
638 RtpRtcpInterface* const rtp_rtcp = rtp_streams_[i].rtp_rtcp.get();
639
640 // Restore RTP state if previous existed.
641 auto it = suspended_ssrcs_.find(ssrc);
642 if (it != suspended_ssrcs_.end())
643 rtp_rtcp->SetRtpState(it->second);
644
645 ssrc_to_rtp_module_[ssrc] = rtp_rtcp;
646 }
647
648 // Set up RTX if available.
649 if (rtp_config_.rtx.ssrcs.empty())
650 return;
651
652 RTC_DCHECK_EQ(rtp_config_.rtx.ssrcs.size(), rtp_config_.ssrcs.size());
653 for (size_t i = 0; i < rtp_config_.rtx.ssrcs.size(); ++i) {
654 uint32_t ssrc = rtp_config_.rtx.ssrcs[i];
655 RtpRtcpInterface* const rtp_rtcp = rtp_streams_[i].rtp_rtcp.get();
656 auto it = suspended_ssrcs_.find(ssrc);
657 if (it != suspended_ssrcs_.end())
658 rtp_rtcp->SetRtxState(it->second);
659 }
660
661 // Configure RTX payload types.
662 RTC_DCHECK_GE(rtp_config_.rtx.payload_type, 0);
663 for (const RtpStreamSender& stream : rtp_streams_) {
664 stream.rtp_rtcp->SetRtxSendPayloadType(rtp_config_.rtx.payload_type,
665 rtp_config_.payload_type);
666 stream.rtp_rtcp->SetRtxSendStatus(kRtxRetransmitted |
667 kRtxRedundantPayloads);
668 }
669 if (rtp_config_.ulpfec.red_payload_type != -1 &&
670 rtp_config_.ulpfec.red_rtx_payload_type != -1) {
671 for (const RtpStreamSender& stream : rtp_streams_) {
672 stream.rtp_rtcp->SetRtxSendPayloadType(
673 rtp_config_.ulpfec.red_rtx_payload_type,
674 rtp_config_.ulpfec.red_payload_type);
675 }
676 }
677 }
678
ConfigureRids()679 void RtpVideoSender::ConfigureRids() {
680 if (rtp_config_.rids.empty())
681 return;
682
683 // Some streams could have been disabled, but the rids are still there.
684 // This will occur when simulcast has been disabled for a codec (e.g. VP9)
685 RTC_DCHECK(rtp_config_.rids.size() >= rtp_streams_.size());
686 for (size_t i = 0; i < rtp_streams_.size(); ++i) {
687 rtp_streams_[i].rtp_rtcp->SetRid(rtp_config_.rids[i]);
688 }
689 }
690
OnNetworkAvailability(bool network_available)691 void RtpVideoSender::OnNetworkAvailability(bool network_available) {
692 for (const RtpStreamSender& stream : rtp_streams_) {
693 stream.rtp_rtcp->SetRTCPStatus(network_available ? rtp_config_.rtcp_mode
694 : RtcpMode::kOff);
695 }
696 }
697
GetRtpStates() const698 std::map<uint32_t, RtpState> RtpVideoSender::GetRtpStates() const {
699 std::map<uint32_t, RtpState> rtp_states;
700
701 for (size_t i = 0; i < rtp_config_.ssrcs.size(); ++i) {
702 uint32_t ssrc = rtp_config_.ssrcs[i];
703 RTC_DCHECK_EQ(ssrc, rtp_streams_[i].rtp_rtcp->SSRC());
704 rtp_states[ssrc] = rtp_streams_[i].rtp_rtcp->GetRtpState();
705
706 // Only happens during shutdown, when RTP module is already inactive,
707 // so OK to call fec generator here.
708 if (rtp_streams_[i].fec_generator) {
709 absl::optional<RtpState> fec_state =
710 rtp_streams_[i].fec_generator->GetRtpState();
711 if (fec_state) {
712 uint32_t ssrc = rtp_config_.flexfec.ssrc;
713 rtp_states[ssrc] = *fec_state;
714 }
715 }
716 }
717
718 for (size_t i = 0; i < rtp_config_.rtx.ssrcs.size(); ++i) {
719 uint32_t ssrc = rtp_config_.rtx.ssrcs[i];
720 rtp_states[ssrc] = rtp_streams_[i].rtp_rtcp->GetRtxState();
721 }
722
723 return rtp_states;
724 }
725
GetRtpPayloadStates() const726 std::map<uint32_t, RtpPayloadState> RtpVideoSender::GetRtpPayloadStates()
727 const {
728 MutexLock lock(&mutex_);
729 std::map<uint32_t, RtpPayloadState> payload_states;
730 for (const auto& param : params_) {
731 payload_states[param.ssrc()] = param.state();
732 payload_states[param.ssrc()].shared_frame_id = shared_frame_id_;
733 }
734 return payload_states;
735 }
736
OnTransportOverheadChanged(size_t transport_overhead_bytes_per_packet)737 void RtpVideoSender::OnTransportOverheadChanged(
738 size_t transport_overhead_bytes_per_packet) {
739 MutexLock lock(&mutex_);
740 transport_overhead_bytes_per_packet_ = transport_overhead_bytes_per_packet;
741
742 size_t max_rtp_packet_size =
743 std::min(rtp_config_.max_packet_size,
744 kPathMTU - transport_overhead_bytes_per_packet_);
745 for (const RtpStreamSender& stream : rtp_streams_) {
746 stream.rtp_rtcp->SetMaxRtpPacketSize(max_rtp_packet_size);
747 }
748 }
749
OnBitrateUpdated(BitrateAllocationUpdate update,int framerate)750 void RtpVideoSender::OnBitrateUpdated(BitrateAllocationUpdate update,
751 int framerate) {
752 // Substract overhead from bitrate.
753 MutexLock lock(&mutex_);
754 size_t num_active_streams = 0;
755 size_t overhead_bytes_per_packet = 0;
756 for (const auto& stream : rtp_streams_) {
757 if (stream.rtp_rtcp->SendingMedia()) {
758 overhead_bytes_per_packet += stream.rtp_rtcp->ExpectedPerPacketOverhead();
759 ++num_active_streams;
760 }
761 }
762 if (num_active_streams > 1) {
763 overhead_bytes_per_packet /= num_active_streams;
764 }
765
766 DataSize packet_overhead = DataSize::Bytes(
767 overhead_bytes_per_packet + transport_overhead_bytes_per_packet_);
768 DataSize max_total_packet_size = DataSize::Bytes(
769 rtp_config_.max_packet_size + transport_overhead_bytes_per_packet_);
770 uint32_t payload_bitrate_bps = update.target_bitrate.bps();
771 if (send_side_bwe_with_overhead_ && has_packet_feedback_) {
772 DataRate overhead_rate = CalculateOverheadRate(
773 update.target_bitrate, max_total_packet_size, packet_overhead);
774 // TODO(srte): We probably should not accept 0 payload bitrate here.
775 payload_bitrate_bps = rtc::saturated_cast<uint32_t>(payload_bitrate_bps -
776 overhead_rate.bps());
777 }
778
779 // Get the encoder target rate. It is the estimated network rate -
780 // protection overhead.
781 // TODO(srte): We should multiply with 255 here.
782 encoder_target_rate_bps_ = fec_controller_->UpdateFecRates(
783 payload_bitrate_bps, framerate,
784 rtc::saturated_cast<uint8_t>(update.packet_loss_ratio * 256),
785 loss_mask_vector_, update.round_trip_time.ms());
786 if (!fec_allowed_) {
787 encoder_target_rate_bps_ = payload_bitrate_bps;
788 // fec_controller_->UpdateFecRates() was still called so as to allow
789 // |fec_controller_| to update whatever internal state it might have,
790 // since |fec_allowed_| may be toggled back on at any moment.
791 }
792
793 uint32_t packetization_rate_bps = 0;
794 if (account_for_packetization_overhead_) {
795 // Subtract packetization overhead from the encoder target. If target rate
796 // is really low, cap the overhead at 50%. This also avoids the case where
797 // |encoder_target_rate_bps_| is 0 due to encoder pause event while the
798 // packetization rate is positive since packets are still flowing.
799 packetization_rate_bps =
800 std::min(GetPacketizationOverheadRate(), encoder_target_rate_bps_ / 2);
801 encoder_target_rate_bps_ -= packetization_rate_bps;
802 }
803
804 loss_mask_vector_.clear();
805
806 uint32_t encoder_overhead_rate_bps = 0;
807 if (send_side_bwe_with_overhead_ && has_packet_feedback_) {
808 // TODO(srte): The packet size should probably be the same as in the
809 // CalculateOverheadRate call above (just max_total_packet_size), it doesn't
810 // make sense to use different packet rates for different overhead
811 // calculations.
812 DataRate encoder_overhead_rate = CalculateOverheadRate(
813 DataRate::BitsPerSec(encoder_target_rate_bps_),
814 max_total_packet_size - DataSize::Bytes(overhead_bytes_per_packet),
815 packet_overhead);
816 encoder_overhead_rate_bps = std::min(
817 encoder_overhead_rate.bps<uint32_t>(),
818 update.target_bitrate.bps<uint32_t>() - encoder_target_rate_bps_);
819 }
820 // When the field trial "WebRTC-SendSideBwe-WithOverhead" is enabled
821 // protection_bitrate includes overhead.
822 const uint32_t media_rate = encoder_target_rate_bps_ +
823 encoder_overhead_rate_bps +
824 packetization_rate_bps;
825 RTC_DCHECK_GE(update.target_bitrate, DataRate::BitsPerSec(media_rate));
826 protection_bitrate_bps_ = update.target_bitrate.bps() - media_rate;
827 }
828
GetPayloadBitrateBps() const829 uint32_t RtpVideoSender::GetPayloadBitrateBps() const {
830 return encoder_target_rate_bps_;
831 }
832
GetProtectionBitrateBps() const833 uint32_t RtpVideoSender::GetProtectionBitrateBps() const {
834 return protection_bitrate_bps_;
835 }
836
GetSentRtpPacketInfos(uint32_t ssrc,rtc::ArrayView<const uint16_t> sequence_numbers) const837 std::vector<RtpSequenceNumberMap::Info> RtpVideoSender::GetSentRtpPacketInfos(
838 uint32_t ssrc,
839 rtc::ArrayView<const uint16_t> sequence_numbers) const {
840 for (const auto& rtp_stream : rtp_streams_) {
841 if (ssrc == rtp_stream.rtp_rtcp->SSRC()) {
842 return rtp_stream.rtp_rtcp->GetSentRtpPacketInfos(sequence_numbers);
843 }
844 }
845 return std::vector<RtpSequenceNumberMap::Info>();
846 }
847
ProtectionRequest(const FecProtectionParams * delta_params,const FecProtectionParams * key_params,uint32_t * sent_video_rate_bps,uint32_t * sent_nack_rate_bps,uint32_t * sent_fec_rate_bps)848 int RtpVideoSender::ProtectionRequest(const FecProtectionParams* delta_params,
849 const FecProtectionParams* key_params,
850 uint32_t* sent_video_rate_bps,
851 uint32_t* sent_nack_rate_bps,
852 uint32_t* sent_fec_rate_bps) {
853 *sent_video_rate_bps = 0;
854 *sent_nack_rate_bps = 0;
855 *sent_fec_rate_bps = 0;
856 for (const RtpStreamSender& stream : rtp_streams_) {
857 if (use_deferred_fec_) {
858 stream.rtp_rtcp->SetFecProtectionParams(*delta_params, *key_params);
859
860 auto send_bitrate = stream.rtp_rtcp->GetSendRates();
861 *sent_video_rate_bps += send_bitrate[RtpPacketMediaType::kVideo].bps();
862 *sent_fec_rate_bps +=
863 send_bitrate[RtpPacketMediaType::kForwardErrorCorrection].bps();
864 *sent_nack_rate_bps +=
865 send_bitrate[RtpPacketMediaType::kRetransmission].bps();
866 } else {
867 if (stream.fec_generator) {
868 stream.fec_generator->SetProtectionParameters(*delta_params,
869 *key_params);
870 *sent_fec_rate_bps += stream.fec_generator->CurrentFecRate().bps();
871 }
872 *sent_video_rate_bps += stream.sender_video->VideoBitrateSent();
873 *sent_nack_rate_bps +=
874 stream.rtp_rtcp->GetSendRates()[RtpPacketMediaType::kRetransmission]
875 .bps<uint32_t>();
876 }
877 }
878 return 0;
879 }
880
SetFecAllowed(bool fec_allowed)881 void RtpVideoSender::SetFecAllowed(bool fec_allowed) {
882 MutexLock lock(&mutex_);
883 fec_allowed_ = fec_allowed;
884 }
885
OnPacketFeedbackVector(std::vector<StreamPacketInfo> packet_feedback_vector)886 void RtpVideoSender::OnPacketFeedbackVector(
887 std::vector<StreamPacketInfo> packet_feedback_vector) {
888 if (fec_controller_->UseLossVectorMask()) {
889 MutexLock lock(&mutex_);
890 for (const StreamPacketInfo& packet : packet_feedback_vector) {
891 loss_mask_vector_.push_back(!packet.received);
892 }
893 }
894
895 // Map from SSRC to all acked packets for that RTP module.
896 std::map<uint32_t, std::vector<uint16_t>> acked_packets_per_ssrc;
897 for (const StreamPacketInfo& packet : packet_feedback_vector) {
898 if (packet.received) {
899 acked_packets_per_ssrc[packet.ssrc].push_back(packet.rtp_sequence_number);
900 }
901 }
902
903 if (use_early_loss_detection_) {
904 // Map from SSRC to vector of RTP sequence numbers that are indicated as
905 // lost by feedback, without being trailed by any received packets.
906 std::map<uint32_t, std::vector<uint16_t>> early_loss_detected_per_ssrc;
907
908 for (const StreamPacketInfo& packet : packet_feedback_vector) {
909 if (!packet.received) {
910 // Last known lost packet, might not be detectable as lost by remote
911 // jitter buffer.
912 early_loss_detected_per_ssrc[packet.ssrc].push_back(
913 packet.rtp_sequence_number);
914 } else {
915 // Packet received, so any loss prior to this is already detectable.
916 early_loss_detected_per_ssrc.erase(packet.ssrc);
917 }
918 }
919
920 for (const auto& kv : early_loss_detected_per_ssrc) {
921 const uint32_t ssrc = kv.first;
922 auto it = ssrc_to_rtp_module_.find(ssrc);
923 RTC_DCHECK(it != ssrc_to_rtp_module_.end());
924 RTPSender* rtp_sender = it->second->RtpSender();
925 for (uint16_t sequence_number : kv.second) {
926 rtp_sender->ReSendPacket(sequence_number);
927 }
928 }
929 }
930
931 for (const auto& kv : acked_packets_per_ssrc) {
932 const uint32_t ssrc = kv.first;
933 auto it = ssrc_to_rtp_module_.find(ssrc);
934 if (it == ssrc_to_rtp_module_.end()) {
935 // Packets not for a media SSRC, so likely RTX or FEC. If so, ignore
936 // since there's no RTP history to clean up anyway.
937 continue;
938 }
939 rtc::ArrayView<const uint16_t> rtp_sequence_numbers(kv.second);
940 it->second->OnPacketsAcknowledged(rtp_sequence_numbers);
941 }
942 }
943
SetEncodingData(size_t width,size_t height,size_t num_temporal_layers)944 void RtpVideoSender::SetEncodingData(size_t width,
945 size_t height,
946 size_t num_temporal_layers) {
947 fec_controller_->SetEncodingData(width, height, num_temporal_layers,
948 rtp_config_.max_packet_size);
949 }
950 } // namespace webrtc
951