• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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