1 /*
2  *  Copyright 2018 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 #include "video/video_send_stream_impl.h"
11 
12 #include <stdio.h>
13 
14 #include <algorithm>
15 #include <cstdint>
16 #include <string>
17 #include <utility>
18 
19 #include "absl/algorithm/container.h"
20 #include "api/crypto/crypto_options.h"
21 #include "api/rtp_parameters.h"
22 #include "api/scoped_refptr.h"
23 #include "api/video_codecs/video_codec.h"
24 #include "call/rtp_transport_controller_send_interface.h"
25 #include "call/video_send_stream.h"
26 #include "modules/pacing/paced_sender.h"
27 #include "rtc_base/atomic_ops.h"
28 #include "rtc_base/checks.h"
29 #include "rtc_base/experiments/alr_experiment.h"
30 #include "rtc_base/experiments/field_trial_parser.h"
31 #include "rtc_base/experiments/min_video_bitrate_experiment.h"
32 #include "rtc_base/experiments/rate_control_settings.h"
33 #include "rtc_base/logging.h"
34 #include "rtc_base/numerics/safe_conversions.h"
35 #include "rtc_base/synchronization/sequence_checker.h"
36 #include "rtc_base/thread_checker.h"
37 #include "rtc_base/trace_event.h"
38 #include "system_wrappers/include/clock.h"
39 #include "system_wrappers/include/field_trial.h"
40 
41 namespace webrtc {
42 namespace internal {
43 namespace {
44 
45 // Max positive size difference to treat allocations as "similar".
46 static constexpr int kMaxVbaSizeDifferencePercent = 10;
47 // Max time we will throttle similar video bitrate allocations.
48 static constexpr int64_t kMaxVbaThrottleTimeMs = 500;
49 
50 constexpr TimeDelta kEncoderTimeOut = TimeDelta::Seconds(2);
51 
TransportSeqNumExtensionConfigured(const VideoSendStream::Config & config)52 bool TransportSeqNumExtensionConfigured(const VideoSendStream::Config& config) {
53   const std::vector<RtpExtension>& extensions = config.rtp.extensions;
54   return absl::c_any_of(extensions, [](const RtpExtension& ext) {
55     return ext.uri == RtpExtension::kTransportSequenceNumberUri;
56   });
57 }
58 
59 // Calculate max padding bitrate for a multi layer codec.
CalculateMaxPadBitrateBps(const std::vector<VideoStream> & streams,bool is_svc,VideoEncoderConfig::ContentType content_type,int min_transmit_bitrate_bps,bool pad_to_min_bitrate,bool alr_probing)60 int CalculateMaxPadBitrateBps(const std::vector<VideoStream>& streams,
61                               bool is_svc,
62                               VideoEncoderConfig::ContentType content_type,
63                               int min_transmit_bitrate_bps,
64                               bool pad_to_min_bitrate,
65                               bool alr_probing) {
66   int pad_up_to_bitrate_bps = 0;
67 
68   RTC_DCHECK(!is_svc || streams.size() <= 1) << "Only one stream is allowed in "
69                                                 "SVC mode.";
70 
71   // Filter out only the active streams;
72   std::vector<VideoStream> active_streams;
73   for (const VideoStream& stream : streams) {
74     if (stream.active)
75       active_streams.emplace_back(stream);
76   }
77 
78   if (active_streams.size() > 1 || (!active_streams.empty() && is_svc)) {
79     // Simulcast or SVC is used.
80     // if SVC is used, stream bitrates should already encode svc bitrates:
81     // min_bitrate = min bitrate of a lowest svc layer.
82     // target_bitrate = sum of target bitrates of lower layers + min bitrate
83     // of the last one (as used in the calculations below).
84     // max_bitrate = sum of all active layers' max_bitrate.
85     if (alr_probing) {
86       // With alr probing, just pad to the min bitrate of the lowest stream,
87       // probing will handle the rest of the rampup.
88       pad_up_to_bitrate_bps = active_streams[0].min_bitrate_bps;
89     } else {
90       // Without alr probing, pad up to start bitrate of the
91       // highest active stream.
92       const double hysteresis_factor =
93           RateControlSettings::ParseFromFieldTrials()
94               .GetSimulcastHysteresisFactor(content_type);
95       if (is_svc) {
96         // For SVC, since there is only one "stream", the padding bitrate
97         // needed to enable the top spatial layer is stored in the
98         // |target_bitrate_bps| field.
99         // TODO(sprang): This behavior needs to die.
100         pad_up_to_bitrate_bps = static_cast<int>(
101             hysteresis_factor * active_streams[0].target_bitrate_bps + 0.5);
102       } else {
103         const size_t top_active_stream_idx = active_streams.size() - 1;
104         pad_up_to_bitrate_bps = std::min(
105             static_cast<int>(
106                 hysteresis_factor *
107                     active_streams[top_active_stream_idx].min_bitrate_bps +
108                 0.5),
109             active_streams[top_active_stream_idx].target_bitrate_bps);
110 
111         // Add target_bitrate_bps of the lower active streams.
112         for (size_t i = 0; i < top_active_stream_idx; ++i) {
113           pad_up_to_bitrate_bps += active_streams[i].target_bitrate_bps;
114         }
115       }
116     }
117   } else if (!active_streams.empty() && pad_to_min_bitrate) {
118     pad_up_to_bitrate_bps = active_streams[0].min_bitrate_bps;
119   }
120 
121   pad_up_to_bitrate_bps =
122       std::max(pad_up_to_bitrate_bps, min_transmit_bitrate_bps);
123 
124   return pad_up_to_bitrate_bps;
125 }
126 
CreateFrameEncryptionConfig(const VideoSendStream::Config * config)127 RtpSenderFrameEncryptionConfig CreateFrameEncryptionConfig(
128     const VideoSendStream::Config* config) {
129   RtpSenderFrameEncryptionConfig frame_encryption_config;
130   frame_encryption_config.frame_encryptor = config->frame_encryptor;
131   frame_encryption_config.crypto_options = config->crypto_options;
132   return frame_encryption_config;
133 }
134 
CreateObservers(RtcpRttStats * call_stats,EncoderRtcpFeedback * encoder_feedback,SendStatisticsProxy * stats_proxy,SendDelayStats * send_delay_stats)135 RtpSenderObservers CreateObservers(RtcpRttStats* call_stats,
136                                    EncoderRtcpFeedback* encoder_feedback,
137                                    SendStatisticsProxy* stats_proxy,
138                                    SendDelayStats* send_delay_stats) {
139   RtpSenderObservers observers;
140   observers.rtcp_rtt_stats = call_stats;
141   observers.intra_frame_callback = encoder_feedback;
142   observers.rtcp_loss_notification_observer = encoder_feedback;
143   observers.rtcp_stats = stats_proxy;
144   observers.report_block_data_observer = stats_proxy;
145   observers.rtp_stats = stats_proxy;
146   observers.bitrate_observer = stats_proxy;
147   observers.frame_count_observer = stats_proxy;
148   observers.rtcp_type_observer = stats_proxy;
149   observers.send_delay_observer = stats_proxy;
150   observers.send_packet_observer = send_delay_stats;
151   return observers;
152 }
153 
GetAlrSettings(VideoEncoderConfig::ContentType content_type)154 absl::optional<AlrExperimentSettings> GetAlrSettings(
155     VideoEncoderConfig::ContentType content_type) {
156   if (content_type == VideoEncoderConfig::ContentType::kScreen) {
157     return AlrExperimentSettings::CreateFromFieldTrial(
158         AlrExperimentSettings::kScreenshareProbingBweExperimentName);
159   }
160   return AlrExperimentSettings::CreateFromFieldTrial(
161       AlrExperimentSettings::kStrictPacingAndProbingExperimentName);
162 }
163 
SameStreamsEnabled(const VideoBitrateAllocation & lhs,const VideoBitrateAllocation & rhs)164 bool SameStreamsEnabled(const VideoBitrateAllocation& lhs,
165                         const VideoBitrateAllocation& rhs) {
166   for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
167     for (size_t ti = 0; ti < kMaxTemporalStreams; ++ti) {
168       if (lhs.HasBitrate(si, ti) != rhs.HasBitrate(si, ti)) {
169         return false;
170       }
171     }
172   }
173   return true;
174 }
175 }  // namespace
176 
PacingConfig()177 PacingConfig::PacingConfig()
178     : pacing_factor("factor", PacedSender::kDefaultPaceMultiplier),
179       max_pacing_delay("max_delay",
180                        TimeDelta::Millis(PacedSender::kMaxQueueLengthMs)) {
181   ParseFieldTrial({&pacing_factor, &max_pacing_delay},
182                   field_trial::FindFullName("WebRTC-Video-Pacing"));
183 }
184 PacingConfig::PacingConfig(const PacingConfig&) = default;
185 PacingConfig::~PacingConfig() = default;
186 
VideoSendStreamImpl(Clock * clock,SendStatisticsProxy * stats_proxy,rtc::TaskQueue * worker_queue,RtcpRttStats * call_stats,RtpTransportControllerSendInterface * transport,BitrateAllocatorInterface * bitrate_allocator,SendDelayStats * send_delay_stats,VideoStreamEncoderInterface * video_stream_encoder,RtcEventLog * event_log,const VideoSendStream::Config * config,int initial_encoder_max_bitrate,double initial_encoder_bitrate_priority,std::map<uint32_t,RtpState> suspended_ssrcs,std::map<uint32_t,RtpPayloadState> suspended_payload_states,VideoEncoderConfig::ContentType content_type,std::unique_ptr<FecController> fec_controller)187 VideoSendStreamImpl::VideoSendStreamImpl(
188     Clock* clock,
189     SendStatisticsProxy* stats_proxy,
190     rtc::TaskQueue* worker_queue,
191     RtcpRttStats* call_stats,
192     RtpTransportControllerSendInterface* transport,
193     BitrateAllocatorInterface* bitrate_allocator,
194     SendDelayStats* send_delay_stats,
195     VideoStreamEncoderInterface* video_stream_encoder,
196     RtcEventLog* event_log,
197     const VideoSendStream::Config* config,
198     int initial_encoder_max_bitrate,
199     double initial_encoder_bitrate_priority,
200     std::map<uint32_t, RtpState> suspended_ssrcs,
201     std::map<uint32_t, RtpPayloadState> suspended_payload_states,
202     VideoEncoderConfig::ContentType content_type,
203     std::unique_ptr<FecController> fec_controller)
204     : clock_(clock),
205       has_alr_probing_(config->periodic_alr_bandwidth_probing ||
206                        GetAlrSettings(content_type)),
207       pacing_config_(PacingConfig()),
208       stats_proxy_(stats_proxy),
209       config_(config),
210       worker_queue_(worker_queue),
211       timed_out_(false),
212       transport_(transport),
213       bitrate_allocator_(bitrate_allocator),
214       disable_padding_(true),
215       max_padding_bitrate_(0),
216       encoder_min_bitrate_bps_(0),
217       encoder_target_rate_bps_(0),
218       encoder_bitrate_priority_(initial_encoder_bitrate_priority),
219       has_packet_feedback_(false),
220       video_stream_encoder_(video_stream_encoder),
221       encoder_feedback_(clock, config_->rtp.ssrcs, video_stream_encoder),
222       bandwidth_observer_(transport->GetBandwidthObserver()),
223       rtp_video_sender_(
224           transport_->CreateRtpVideoSender(suspended_ssrcs,
225                                            suspended_payload_states,
226                                            config_->rtp,
227                                            config_->rtcp_report_interval_ms,
228                                            config_->send_transport,
229                                            CreateObservers(call_stats,
230                                                            &encoder_feedback_,
231                                                            stats_proxy_,
232                                                            send_delay_stats),
233                                            event_log,
234                                            std::move(fec_controller),
235                                            CreateFrameEncryptionConfig(config_),
236                                            config->frame_transformer)),
237       weak_ptr_factory_(this) {
238   video_stream_encoder->SetFecControllerOverride(rtp_video_sender_);
239   RTC_DCHECK_RUN_ON(worker_queue_);
240   RTC_LOG(LS_INFO) << "VideoSendStreamInternal: " << config_->ToString();
241   weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
242 
243   encoder_feedback_.SetRtpVideoSender(rtp_video_sender_);
244 
245   RTC_DCHECK(!config_->rtp.ssrcs.empty());
246   RTC_DCHECK(transport_);
247   RTC_DCHECK_NE(initial_encoder_max_bitrate, 0);
248 
249   if (initial_encoder_max_bitrate > 0) {
250     encoder_max_bitrate_bps_ =
251         rtc::dchecked_cast<uint32_t>(initial_encoder_max_bitrate);
252   } else {
253     // TODO(srte): Make sure max bitrate is not set to negative values. We don't
254     // have any way to handle unset values in downstream code, such as the
255     // bitrate allocator. Previously -1 was implicitly casted to UINT32_MAX, a
256     // behaviour that is not safe. Converting to 10 Mbps should be safe for
257     // reasonable use cases as it allows adding the max of multiple streams
258     // without wrappping around.
259     const int kFallbackMaxBitrateBps = 10000000;
260     RTC_DLOG(LS_ERROR) << "ERROR: Initial encoder max bitrate = "
261                        << initial_encoder_max_bitrate << " which is <= 0!";
262     RTC_DLOG(LS_INFO) << "Using default encoder max bitrate = 10 Mbps";
263     encoder_max_bitrate_bps_ = kFallbackMaxBitrateBps;
264   }
265 
266   RTC_CHECK(AlrExperimentSettings::MaxOneFieldTrialEnabled());
267   // If send-side BWE is enabled, check if we should apply updated probing and
268   // pacing settings.
269   if (TransportSeqNumExtensionConfigured(*config_)) {
270     has_packet_feedback_ = true;
271 
272     absl::optional<AlrExperimentSettings> alr_settings =
273         GetAlrSettings(content_type);
274     if (alr_settings) {
275       transport->EnablePeriodicAlrProbing(true);
276       transport->SetPacingFactor(alr_settings->pacing_factor);
277       configured_pacing_factor_ = alr_settings->pacing_factor;
278       transport->SetQueueTimeLimit(alr_settings->max_paced_queue_time);
279     } else {
280       RateControlSettings rate_control_settings =
281           RateControlSettings::ParseFromFieldTrials();
282 
283       transport->EnablePeriodicAlrProbing(
284           rate_control_settings.UseAlrProbing());
285       const double pacing_factor =
286           rate_control_settings.GetPacingFactor().value_or(
287               static_cast<double>(pacing_config_.pacing_factor));
288       transport->SetPacingFactor(pacing_factor);
289       configured_pacing_factor_ = pacing_factor;
290       transport->SetQueueTimeLimit(pacing_config_.max_pacing_delay.Get().ms());
291     }
292   }
293 
294   if (config_->periodic_alr_bandwidth_probing) {
295     transport->EnablePeriodicAlrProbing(true);
296   }
297 
298   RTC_DCHECK_GE(config_->rtp.payload_type, 0);
299   RTC_DCHECK_LE(config_->rtp.payload_type, 127);
300 
301   video_stream_encoder_->SetStartBitrate(
302       bitrate_allocator_->GetStartBitrate(this));
303 }
304 
~VideoSendStreamImpl()305 VideoSendStreamImpl::~VideoSendStreamImpl() {
306   RTC_DCHECK_RUN_ON(worker_queue_);
307   RTC_DCHECK(!rtp_video_sender_->IsActive())
308       << "VideoSendStreamImpl::Stop not called";
309   RTC_LOG(LS_INFO) << "~VideoSendStreamInternal: " << config_->ToString();
310   transport_->DestroyRtpVideoSender(rtp_video_sender_);
311 }
312 
RegisterProcessThread(ProcessThread * module_process_thread)313 void VideoSendStreamImpl::RegisterProcessThread(
314     ProcessThread* module_process_thread) {
315   // Called on libjingle's worker thread (not worker_queue_), as part of the
316   // initialization steps. That's also the correct thread/queue for setting the
317   // state for |video_stream_encoder_|.
318 
319   // Only request rotation at the source when we positively know that the remote
320   // side doesn't support the rotation extension. This allows us to prepare the
321   // encoder in the expectation that rotation is supported - which is the common
322   // case.
323   bool rotation_applied = absl::c_none_of(
324       config_->rtp.extensions, [](const RtpExtension& extension) {
325         return extension.uri == RtpExtension::kVideoRotationUri;
326       });
327 
328   video_stream_encoder_->SetSink(this, rotation_applied);
329 
330   rtp_video_sender_->RegisterProcessThread(module_process_thread);
331 }
332 
DeRegisterProcessThread()333 void VideoSendStreamImpl::DeRegisterProcessThread() {
334   rtp_video_sender_->DeRegisterProcessThread();
335 }
336 
DeliverRtcp(const uint8_t * packet,size_t length)337 void VideoSendStreamImpl::DeliverRtcp(const uint8_t* packet, size_t length) {
338   // Runs on a network thread.
339   RTC_DCHECK(!worker_queue_->IsCurrent());
340   rtp_video_sender_->DeliverRtcp(packet, length);
341 }
342 
UpdateActiveSimulcastLayers(const std::vector<bool> active_layers)343 void VideoSendStreamImpl::UpdateActiveSimulcastLayers(
344     const std::vector<bool> active_layers) {
345   RTC_DCHECK_RUN_ON(worker_queue_);
346   bool previously_active = rtp_video_sender_->IsActive();
347   rtp_video_sender_->SetActiveModules(active_layers);
348   if (!rtp_video_sender_->IsActive() && previously_active) {
349     // Payload router switched from active to inactive.
350     StopVideoSendStream();
351   } else if (rtp_video_sender_->IsActive() && !previously_active) {
352     // Payload router switched from inactive to active.
353     StartupVideoSendStream();
354   }
355 }
356 
Start()357 void VideoSendStreamImpl::Start() {
358   RTC_DCHECK_RUN_ON(worker_queue_);
359   RTC_LOG(LS_INFO) << "VideoSendStream::Start";
360   if (rtp_video_sender_->IsActive())
361     return;
362   TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start");
363   rtp_video_sender_->SetActive(true);
364   StartupVideoSendStream();
365 }
366 
StartupVideoSendStream()367 void VideoSendStreamImpl::StartupVideoSendStream() {
368   RTC_DCHECK_RUN_ON(worker_queue_);
369   bitrate_allocator_->AddObserver(this, GetAllocationConfig());
370   // Start monitoring encoder activity.
371   {
372     RTC_DCHECK(!check_encoder_activity_task_.Running());
373 
374     activity_ = false;
375     timed_out_ = false;
376     check_encoder_activity_task_ = RepeatingTaskHandle::DelayedStart(
377         worker_queue_->Get(), kEncoderTimeOut, [this] {
378           RTC_DCHECK_RUN_ON(worker_queue_);
379           if (!activity_) {
380             if (!timed_out_) {
381               SignalEncoderTimedOut();
382             }
383             timed_out_ = true;
384             disable_padding_ = true;
385           } else if (timed_out_) {
386             SignalEncoderActive();
387             timed_out_ = false;
388           }
389           activity_ = false;
390           return kEncoderTimeOut;
391         });
392   }
393 
394   video_stream_encoder_->SendKeyFrame();
395 }
396 
Stop()397 void VideoSendStreamImpl::Stop() {
398   RTC_DCHECK_RUN_ON(worker_queue_);
399   RTC_LOG(LS_INFO) << "VideoSendStream::Stop";
400   if (!rtp_video_sender_->IsActive())
401     return;
402   TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
403   rtp_video_sender_->SetActive(false);
404   StopVideoSendStream();
405 }
406 
StopVideoSendStream()407 void VideoSendStreamImpl::StopVideoSendStream() {
408   bitrate_allocator_->RemoveObserver(this);
409   check_encoder_activity_task_.Stop();
410   video_stream_encoder_->OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(),
411                                           DataRate::Zero(), 0, 0, 0);
412   stats_proxy_->OnSetEncoderTargetRate(0);
413 }
414 
SignalEncoderTimedOut()415 void VideoSendStreamImpl::SignalEncoderTimedOut() {
416   RTC_DCHECK_RUN_ON(worker_queue_);
417   // If the encoder has not produced anything the last kEncoderTimeOut and it
418   // is supposed to, deregister as BitrateAllocatorObserver. This can happen
419   // if a camera stops producing frames.
420   if (encoder_target_rate_bps_ > 0) {
421     RTC_LOG(LS_INFO) << "SignalEncoderTimedOut, Encoder timed out.";
422     bitrate_allocator_->RemoveObserver(this);
423   }
424 }
425 
OnBitrateAllocationUpdated(const VideoBitrateAllocation & allocation)426 void VideoSendStreamImpl::OnBitrateAllocationUpdated(
427     const VideoBitrateAllocation& allocation) {
428   if (!worker_queue_->IsCurrent()) {
429     auto ptr = weak_ptr_;
430     worker_queue_->PostTask([=] {
431       if (!ptr.get())
432         return;
433       ptr->OnBitrateAllocationUpdated(allocation);
434     });
435     return;
436   }
437 
438   RTC_DCHECK_RUN_ON(worker_queue_);
439 
440   int64_t now_ms = clock_->TimeInMilliseconds();
441   if (encoder_target_rate_bps_ != 0) {
442     if (video_bitrate_allocation_context_) {
443       // If new allocation is within kMaxVbaSizeDifferencePercent larger than
444       // the previously sent allocation and the same streams are still enabled,
445       // it is considered "similar". We do not want send similar allocations
446       // more once per kMaxVbaThrottleTimeMs.
447       const VideoBitrateAllocation& last =
448           video_bitrate_allocation_context_->last_sent_allocation;
449       const bool is_similar =
450           allocation.get_sum_bps() >= last.get_sum_bps() &&
451           allocation.get_sum_bps() <
452               (last.get_sum_bps() * (100 + kMaxVbaSizeDifferencePercent)) /
453                   100 &&
454           SameStreamsEnabled(allocation, last);
455       if (is_similar &&
456           (now_ms - video_bitrate_allocation_context_->last_send_time_ms) <
457               kMaxVbaThrottleTimeMs) {
458         // This allocation is too similar, cache it and return.
459         video_bitrate_allocation_context_->throttled_allocation = allocation;
460         return;
461       }
462     } else {
463       video_bitrate_allocation_context_.emplace();
464     }
465 
466     video_bitrate_allocation_context_->last_sent_allocation = allocation;
467     video_bitrate_allocation_context_->throttled_allocation.reset();
468     video_bitrate_allocation_context_->last_send_time_ms = now_ms;
469 
470     // Send bitrate allocation metadata only if encoder is not paused.
471     rtp_video_sender_->OnBitrateAllocationUpdated(allocation);
472   }
473 }
474 
SignalEncoderActive()475 void VideoSendStreamImpl::SignalEncoderActive() {
476   RTC_DCHECK_RUN_ON(worker_queue_);
477   if (rtp_video_sender_->IsActive()) {
478     RTC_LOG(LS_INFO) << "SignalEncoderActive, Encoder is active.";
479     bitrate_allocator_->AddObserver(this, GetAllocationConfig());
480   }
481 }
482 
GetAllocationConfig() const483 MediaStreamAllocationConfig VideoSendStreamImpl::GetAllocationConfig() const {
484   return MediaStreamAllocationConfig{
485       static_cast<uint32_t>(encoder_min_bitrate_bps_),
486       encoder_max_bitrate_bps_,
487       static_cast<uint32_t>(disable_padding_ ? 0 : max_padding_bitrate_),
488       /* priority_bitrate */ 0,
489       !config_->suspend_below_min_bitrate,
490       encoder_bitrate_priority_};
491 }
492 
OnEncoderConfigurationChanged(std::vector<VideoStream> streams,bool is_svc,VideoEncoderConfig::ContentType content_type,int min_transmit_bitrate_bps)493 void VideoSendStreamImpl::OnEncoderConfigurationChanged(
494     std::vector<VideoStream> streams,
495     bool is_svc,
496     VideoEncoderConfig::ContentType content_type,
497     int min_transmit_bitrate_bps) {
498   if (!worker_queue_->IsCurrent()) {
499     rtc::WeakPtr<VideoSendStreamImpl> send_stream = weak_ptr_;
500     worker_queue_->PostTask([send_stream, streams, is_svc, content_type,
501                              min_transmit_bitrate_bps]() mutable {
502       if (send_stream) {
503         send_stream->OnEncoderConfigurationChanged(
504             std::move(streams), is_svc, content_type, min_transmit_bitrate_bps);
505       }
506     });
507     return;
508   }
509 
510   RTC_DCHECK_GE(config_->rtp.ssrcs.size(), streams.size());
511   TRACE_EVENT0("webrtc", "VideoSendStream::OnEncoderConfigurationChanged");
512   RTC_DCHECK_RUN_ON(worker_queue_);
513 
514   const VideoCodecType codec_type =
515       PayloadStringToCodecType(config_->rtp.payload_name);
516 
517   const absl::optional<DataRate> experimental_min_bitrate =
518       GetExperimentalMinVideoBitrate(codec_type);
519   encoder_min_bitrate_bps_ =
520       experimental_min_bitrate
521           ? experimental_min_bitrate->bps()
522           : std::max(streams[0].min_bitrate_bps, kDefaultMinVideoBitrateBps);
523 
524   encoder_max_bitrate_bps_ = 0;
525   double stream_bitrate_priority_sum = 0;
526   for (const auto& stream : streams) {
527     // We don't want to allocate more bitrate than needed to inactive streams.
528     encoder_max_bitrate_bps_ += stream.active ? stream.max_bitrate_bps : 0;
529     if (stream.bitrate_priority) {
530       RTC_DCHECK_GT(*stream.bitrate_priority, 0);
531       stream_bitrate_priority_sum += *stream.bitrate_priority;
532     }
533   }
534   RTC_DCHECK_GT(stream_bitrate_priority_sum, 0);
535   encoder_bitrate_priority_ = stream_bitrate_priority_sum;
536   encoder_max_bitrate_bps_ =
537       std::max(static_cast<uint32_t>(encoder_min_bitrate_bps_),
538                encoder_max_bitrate_bps_);
539 
540   // TODO(bugs.webrtc.org/10266): Query the VideoBitrateAllocator instead.
541   max_padding_bitrate_ = CalculateMaxPadBitrateBps(
542       streams, is_svc, content_type, min_transmit_bitrate_bps,
543       config_->suspend_below_min_bitrate, has_alr_probing_);
544 
545   // Clear stats for disabled layers.
546   for (size_t i = streams.size(); i < config_->rtp.ssrcs.size(); ++i) {
547     stats_proxy_->OnInactiveSsrc(config_->rtp.ssrcs[i]);
548   }
549 
550   const size_t num_temporal_layers =
551       streams.back().num_temporal_layers.value_or(1);
552 
553   rtp_video_sender_->SetEncodingData(streams[0].width, streams[0].height,
554                                      num_temporal_layers);
555 
556   if (rtp_video_sender_->IsActive()) {
557     // The send stream is started already. Update the allocator with new bitrate
558     // limits.
559     bitrate_allocator_->AddObserver(this, GetAllocationConfig());
560   }
561 }
562 
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info)563 EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
564     const EncodedImage& encoded_image,
565     const CodecSpecificInfo* codec_specific_info) {
566   // Encoded is called on whatever thread the real encoder implementation run
567   // on. In the case of hardware encoders, there might be several encoders
568   // running in parallel on different threads.
569 
570   // Indicate that there still is activity going on.
571   activity_ = true;
572 
573   auto enable_padding_task = [this]() {
574     if (disable_padding_) {
575       RTC_DCHECK_RUN_ON(worker_queue_);
576       disable_padding_ = false;
577       // To ensure that padding bitrate is propagated to the bitrate allocator.
578       SignalEncoderActive();
579     }
580   };
581   if (!worker_queue_->IsCurrent()) {
582     worker_queue_->PostTask(enable_padding_task);
583   } else {
584     enable_padding_task();
585   }
586 
587   EncodedImageCallback::Result result(EncodedImageCallback::Result::OK);
588   result =
589       rtp_video_sender_->OnEncodedImage(encoded_image, codec_specific_info);
590   // Check if there's a throttled VideoBitrateAllocation that we should try
591   // sending.
592   rtc::WeakPtr<VideoSendStreamImpl> send_stream = weak_ptr_;
593   auto update_task = [send_stream]() {
594     if (send_stream) {
595       RTC_DCHECK_RUN_ON(send_stream->worker_queue_);
596       auto& context = send_stream->video_bitrate_allocation_context_;
597       if (context && context->throttled_allocation) {
598         send_stream->OnBitrateAllocationUpdated(*context->throttled_allocation);
599       }
600     }
601   };
602   if (!worker_queue_->IsCurrent()) {
603     worker_queue_->PostTask(update_task);
604   } else {
605     update_task();
606   }
607 
608   return result;
609 }
610 
OnDroppedFrame(EncodedImageCallback::DropReason reason)611 void VideoSendStreamImpl::OnDroppedFrame(
612     EncodedImageCallback::DropReason reason) {
613   activity_ = true;
614 }
615 
GetRtpStates() const616 std::map<uint32_t, RtpState> VideoSendStreamImpl::GetRtpStates() const {
617   return rtp_video_sender_->GetRtpStates();
618 }
619 
GetRtpPayloadStates() const620 std::map<uint32_t, RtpPayloadState> VideoSendStreamImpl::GetRtpPayloadStates()
621     const {
622   return rtp_video_sender_->GetRtpPayloadStates();
623 }
624 
OnBitrateUpdated(BitrateAllocationUpdate update)625 uint32_t VideoSendStreamImpl::OnBitrateUpdated(BitrateAllocationUpdate update) {
626   RTC_DCHECK_RUN_ON(worker_queue_);
627   RTC_DCHECK(rtp_video_sender_->IsActive())
628       << "VideoSendStream::Start has not been called.";
629 
630   // When the BWE algorithm doesn't pass a stable estimate, we'll use the
631   // unstable one instead.
632   if (update.stable_target_bitrate.IsZero()) {
633     update.stable_target_bitrate = update.target_bitrate;
634   }
635 
636   rtp_video_sender_->OnBitrateUpdated(update, stats_proxy_->GetSendFrameRate());
637   encoder_target_rate_bps_ = rtp_video_sender_->GetPayloadBitrateBps();
638   const uint32_t protection_bitrate_bps =
639       rtp_video_sender_->GetProtectionBitrateBps();
640   DataRate link_allocation = DataRate::Zero();
641   if (encoder_target_rate_bps_ > protection_bitrate_bps) {
642     link_allocation =
643         DataRate::BitsPerSec(encoder_target_rate_bps_ - protection_bitrate_bps);
644   }
645   DataRate overhead =
646       update.target_bitrate - DataRate::BitsPerSec(encoder_target_rate_bps_);
647   DataRate encoder_stable_target_rate = update.stable_target_bitrate;
648   if (encoder_stable_target_rate > overhead) {
649     encoder_stable_target_rate = encoder_stable_target_rate - overhead;
650   } else {
651     encoder_stable_target_rate = DataRate::BitsPerSec(encoder_target_rate_bps_);
652   }
653 
654   encoder_target_rate_bps_ =
655       std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
656 
657   encoder_stable_target_rate =
658       std::min(DataRate::BitsPerSec(encoder_max_bitrate_bps_),
659                encoder_stable_target_rate);
660 
661   DataRate encoder_target_rate = DataRate::BitsPerSec(encoder_target_rate_bps_);
662   link_allocation = std::max(encoder_target_rate, link_allocation);
663   video_stream_encoder_->OnBitrateUpdated(
664       encoder_target_rate, encoder_stable_target_rate, link_allocation,
665       rtc::dchecked_cast<uint8_t>(update.packet_loss_ratio * 256),
666       update.round_trip_time.ms(), update.cwnd_reduce_ratio);
667   stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_);
668   return protection_bitrate_bps;
669 }
670 
671 }  // namespace internal
672 }  // namespace webrtc
673