• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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               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   // Only request rotation at the source when we positively know that the remote
305   // side doesn't support the rotation extension. This allows us to prepare the
306   // encoder in the expectation that rotation is supported - which is the common
307   // case.
308   bool rotation_applied = absl::c_none_of(
309       config_->rtp.extensions, [](const RtpExtension& extension) {
310         return extension.uri == RtpExtension::kVideoRotationUri;
311       });
312 
313   video_stream_encoder_->SetSink(this, rotation_applied);
314 }
315 
~VideoSendStreamImpl()316 VideoSendStreamImpl::~VideoSendStreamImpl() {
317   RTC_DCHECK_RUN_ON(worker_queue_);
318   RTC_DCHECK(!rtp_video_sender_->IsActive())
319       << "VideoSendStreamImpl::Stop not called";
320   RTC_LOG(LS_INFO) << "~VideoSendStreamInternal: " << config_->ToString();
321   transport_->DestroyRtpVideoSender(rtp_video_sender_);
322 }
323 
RegisterProcessThread(ProcessThread * module_process_thread)324 void VideoSendStreamImpl::RegisterProcessThread(
325     ProcessThread* module_process_thread) {
326   rtp_video_sender_->RegisterProcessThread(module_process_thread);
327 }
328 
DeRegisterProcessThread()329 void VideoSendStreamImpl::DeRegisterProcessThread() {
330   rtp_video_sender_->DeRegisterProcessThread();
331 }
332 
DeliverRtcp(const uint8_t * packet,size_t length)333 void VideoSendStreamImpl::DeliverRtcp(const uint8_t* packet, size_t length) {
334   // Runs on a network thread.
335   RTC_DCHECK(!worker_queue_->IsCurrent());
336   rtp_video_sender_->DeliverRtcp(packet, length);
337 }
338 
UpdateActiveSimulcastLayers(const std::vector<bool> active_layers)339 void VideoSendStreamImpl::UpdateActiveSimulcastLayers(
340     const std::vector<bool> active_layers) {
341   RTC_DCHECK_RUN_ON(worker_queue_);
342   bool previously_active = rtp_video_sender_->IsActive();
343   rtp_video_sender_->SetActiveModules(active_layers);
344   if (!rtp_video_sender_->IsActive() && previously_active) {
345     // Payload router switched from active to inactive.
346     StopVideoSendStream();
347   } else if (rtp_video_sender_->IsActive() && !previously_active) {
348     // Payload router switched from inactive to active.
349     StartupVideoSendStream();
350   }
351 }
352 
Start()353 void VideoSendStreamImpl::Start() {
354   RTC_DCHECK_RUN_ON(worker_queue_);
355   RTC_LOG(LS_INFO) << "VideoSendStream::Start";
356   if (rtp_video_sender_->IsActive())
357     return;
358   TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start");
359   rtp_video_sender_->SetActive(true);
360   StartupVideoSendStream();
361 }
362 
StartupVideoSendStream()363 void VideoSendStreamImpl::StartupVideoSendStream() {
364   RTC_DCHECK_RUN_ON(worker_queue_);
365   bitrate_allocator_->AddObserver(this, GetAllocationConfig());
366   // Start monitoring encoder activity.
367   {
368     RTC_DCHECK(!check_encoder_activity_task_.Running());
369 
370     activity_ = false;
371     timed_out_ = false;
372     check_encoder_activity_task_ = RepeatingTaskHandle::DelayedStart(
373         worker_queue_->Get(), kEncoderTimeOut, [this] {
374           RTC_DCHECK_RUN_ON(worker_queue_);
375           if (!activity_) {
376             if (!timed_out_) {
377               SignalEncoderTimedOut();
378             }
379             timed_out_ = true;
380             disable_padding_ = true;
381           } else if (timed_out_) {
382             SignalEncoderActive();
383             timed_out_ = false;
384           }
385           activity_ = false;
386           return kEncoderTimeOut;
387         });
388   }
389 
390   video_stream_encoder_->SendKeyFrame();
391 }
392 
Stop()393 void VideoSendStreamImpl::Stop() {
394   RTC_DCHECK_RUN_ON(worker_queue_);
395   RTC_LOG(LS_INFO) << "VideoSendStream::Stop";
396   if (!rtp_video_sender_->IsActive())
397     return;
398   TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
399   rtp_video_sender_->SetActive(false);
400   StopVideoSendStream();
401 }
402 
StopVideoSendStream()403 void VideoSendStreamImpl::StopVideoSendStream() {
404   bitrate_allocator_->RemoveObserver(this);
405   check_encoder_activity_task_.Stop();
406   video_stream_encoder_->OnBitrateUpdated(DataRate::Zero(), DataRate::Zero(),
407                                           DataRate::Zero(), 0, 0, 0);
408   stats_proxy_->OnSetEncoderTargetRate(0);
409 }
410 
SignalEncoderTimedOut()411 void VideoSendStreamImpl::SignalEncoderTimedOut() {
412   RTC_DCHECK_RUN_ON(worker_queue_);
413   // If the encoder has not produced anything the last kEncoderTimeOut and it
414   // is supposed to, deregister as BitrateAllocatorObserver. This can happen
415   // if a camera stops producing frames.
416   if (encoder_target_rate_bps_ > 0) {
417     RTC_LOG(LS_INFO) << "SignalEncoderTimedOut, Encoder timed out.";
418     bitrate_allocator_->RemoveObserver(this);
419   }
420 }
421 
OnBitrateAllocationUpdated(const VideoBitrateAllocation & allocation)422 void VideoSendStreamImpl::OnBitrateAllocationUpdated(
423     const VideoBitrateAllocation& allocation) {
424   if (!worker_queue_->IsCurrent()) {
425     auto ptr = weak_ptr_;
426     worker_queue_->PostTask([=] {
427       if (!ptr.get())
428         return;
429       ptr->OnBitrateAllocationUpdated(allocation);
430     });
431     return;
432   }
433 
434   RTC_DCHECK_RUN_ON(worker_queue_);
435 
436   int64_t now_ms = clock_->TimeInMilliseconds();
437   if (encoder_target_rate_bps_ != 0) {
438     if (video_bitrate_allocation_context_) {
439       // If new allocation is within kMaxVbaSizeDifferencePercent larger than
440       // the previously sent allocation and the same streams are still enabled,
441       // it is considered "similar". We do not want send similar allocations
442       // more once per kMaxVbaThrottleTimeMs.
443       const VideoBitrateAllocation& last =
444           video_bitrate_allocation_context_->last_sent_allocation;
445       const bool is_similar =
446           allocation.get_sum_bps() >= last.get_sum_bps() &&
447           allocation.get_sum_bps() <
448               (last.get_sum_bps() * (100 + kMaxVbaSizeDifferencePercent)) /
449                   100 &&
450           SameStreamsEnabled(allocation, last);
451       if (is_similar &&
452           (now_ms - video_bitrate_allocation_context_->last_send_time_ms) <
453               kMaxVbaThrottleTimeMs) {
454         // This allocation is too similar, cache it and return.
455         video_bitrate_allocation_context_->throttled_allocation = allocation;
456         return;
457       }
458     } else {
459       video_bitrate_allocation_context_.emplace();
460     }
461 
462     video_bitrate_allocation_context_->last_sent_allocation = allocation;
463     video_bitrate_allocation_context_->throttled_allocation.reset();
464     video_bitrate_allocation_context_->last_send_time_ms = now_ms;
465 
466     // Send bitrate allocation metadata only if encoder is not paused.
467     rtp_video_sender_->OnBitrateAllocationUpdated(allocation);
468   }
469 }
470 
SignalEncoderActive()471 void VideoSendStreamImpl::SignalEncoderActive() {
472   RTC_DCHECK_RUN_ON(worker_queue_);
473   if (rtp_video_sender_->IsActive()) {
474     RTC_LOG(LS_INFO) << "SignalEncoderActive, Encoder is active.";
475     bitrate_allocator_->AddObserver(this, GetAllocationConfig());
476   }
477 }
478 
GetAllocationConfig() const479 MediaStreamAllocationConfig VideoSendStreamImpl::GetAllocationConfig() const {
480   return MediaStreamAllocationConfig{
481       static_cast<uint32_t>(encoder_min_bitrate_bps_),
482       encoder_max_bitrate_bps_,
483       static_cast<uint32_t>(disable_padding_ ? 0 : max_padding_bitrate_),
484       /* priority_bitrate */ 0,
485       !config_->suspend_below_min_bitrate,
486       encoder_bitrate_priority_};
487 }
488 
OnEncoderConfigurationChanged(std::vector<VideoStream> streams,bool is_svc,VideoEncoderConfig::ContentType content_type,int min_transmit_bitrate_bps)489 void VideoSendStreamImpl::OnEncoderConfigurationChanged(
490     std::vector<VideoStream> streams,
491     bool is_svc,
492     VideoEncoderConfig::ContentType content_type,
493     int min_transmit_bitrate_bps) {
494   if (!worker_queue_->IsCurrent()) {
495     rtc::WeakPtr<VideoSendStreamImpl> send_stream = weak_ptr_;
496     worker_queue_->PostTask([send_stream, streams, is_svc, content_type,
497                              min_transmit_bitrate_bps]() mutable {
498       if (send_stream) {
499         send_stream->OnEncoderConfigurationChanged(
500             std::move(streams), is_svc, content_type, min_transmit_bitrate_bps);
501       }
502     });
503     return;
504   }
505 
506   RTC_DCHECK_GE(config_->rtp.ssrcs.size(), streams.size());
507   TRACE_EVENT0("webrtc", "VideoSendStream::OnEncoderConfigurationChanged");
508   RTC_DCHECK_RUN_ON(worker_queue_);
509 
510   const VideoCodecType codec_type =
511       PayloadStringToCodecType(config_->rtp.payload_name);
512 
513   const absl::optional<DataRate> experimental_min_bitrate =
514       GetExperimentalMinVideoBitrate(codec_type);
515   encoder_min_bitrate_bps_ =
516       experimental_min_bitrate
517           ? experimental_min_bitrate->bps()
518           : std::max(streams[0].min_bitrate_bps, kDefaultMinVideoBitrateBps);
519 
520   encoder_max_bitrate_bps_ = 0;
521   double stream_bitrate_priority_sum = 0;
522   for (const auto& stream : streams) {
523     // We don't want to allocate more bitrate than needed to inactive streams.
524     encoder_max_bitrate_bps_ += stream.active ? stream.max_bitrate_bps : 0;
525     if (stream.bitrate_priority) {
526       RTC_DCHECK_GT(*stream.bitrate_priority, 0);
527       stream_bitrate_priority_sum += *stream.bitrate_priority;
528     }
529   }
530   RTC_DCHECK_GT(stream_bitrate_priority_sum, 0);
531   encoder_bitrate_priority_ = stream_bitrate_priority_sum;
532   encoder_max_bitrate_bps_ =
533       std::max(static_cast<uint32_t>(encoder_min_bitrate_bps_),
534                encoder_max_bitrate_bps_);
535 
536   // TODO(bugs.webrtc.org/10266): Query the VideoBitrateAllocator instead.
537   max_padding_bitrate_ = CalculateMaxPadBitrateBps(
538       streams, is_svc, content_type, min_transmit_bitrate_bps,
539       config_->suspend_below_min_bitrate, has_alr_probing_);
540 
541   // Clear stats for disabled layers.
542   for (size_t i = streams.size(); i < config_->rtp.ssrcs.size(); ++i) {
543     stats_proxy_->OnInactiveSsrc(config_->rtp.ssrcs[i]);
544   }
545 
546   const size_t num_temporal_layers =
547       streams.back().num_temporal_layers.value_or(1);
548 
549   rtp_video_sender_->SetEncodingData(streams[0].width, streams[0].height,
550                                      num_temporal_layers);
551 
552   if (rtp_video_sender_->IsActive()) {
553     // The send stream is started already. Update the allocator with new bitrate
554     // limits.
555     bitrate_allocator_->AddObserver(this, GetAllocationConfig());
556   }
557 }
558 
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info,const RTPFragmentationHeader * fragmentation)559 EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
560     const EncodedImage& encoded_image,
561     const CodecSpecificInfo* codec_specific_info,
562     const RTPFragmentationHeader* fragmentation) {
563   // Encoded is called on whatever thread the real encoder implementation run
564   // on. In the case of hardware encoders, there might be several encoders
565   // running in parallel on different threads.
566 
567   // Indicate that there still is activity going on.
568   activity_ = true;
569 
570   auto enable_padding_task = [this]() {
571     if (disable_padding_) {
572       RTC_DCHECK_RUN_ON(worker_queue_);
573       disable_padding_ = false;
574       // To ensure that padding bitrate is propagated to the bitrate allocator.
575       SignalEncoderActive();
576     }
577   };
578   if (!worker_queue_->IsCurrent()) {
579     worker_queue_->PostTask(enable_padding_task);
580   } else {
581     enable_padding_task();
582   }
583 
584   EncodedImageCallback::Result result(EncodedImageCallback::Result::OK);
585   result = rtp_video_sender_->OnEncodedImage(encoded_image, codec_specific_info,
586                                              fragmentation);
587   // Check if there's a throttled VideoBitrateAllocation that we should try
588   // sending.
589   rtc::WeakPtr<VideoSendStreamImpl> send_stream = weak_ptr_;
590   auto update_task = [send_stream]() {
591     if (send_stream) {
592       RTC_DCHECK_RUN_ON(send_stream->worker_queue_);
593       auto& context = send_stream->video_bitrate_allocation_context_;
594       if (context && context->throttled_allocation) {
595         send_stream->OnBitrateAllocationUpdated(*context->throttled_allocation);
596       }
597     }
598   };
599   if (!worker_queue_->IsCurrent()) {
600     worker_queue_->PostTask(update_task);
601   } else {
602     update_task();
603   }
604 
605   return result;
606 }
607 
OnDroppedFrame(EncodedImageCallback::DropReason reason)608 void VideoSendStreamImpl::OnDroppedFrame(
609     EncodedImageCallback::DropReason reason) {
610   activity_ = true;
611 }
612 
GetRtpStates() const613 std::map<uint32_t, RtpState> VideoSendStreamImpl::GetRtpStates() const {
614   return rtp_video_sender_->GetRtpStates();
615 }
616 
GetRtpPayloadStates() const617 std::map<uint32_t, RtpPayloadState> VideoSendStreamImpl::GetRtpPayloadStates()
618     const {
619   return rtp_video_sender_->GetRtpPayloadStates();
620 }
621 
OnBitrateUpdated(BitrateAllocationUpdate update)622 uint32_t VideoSendStreamImpl::OnBitrateUpdated(BitrateAllocationUpdate update) {
623   RTC_DCHECK_RUN_ON(worker_queue_);
624   RTC_DCHECK(rtp_video_sender_->IsActive())
625       << "VideoSendStream::Start has not been called.";
626 
627   // When the BWE algorithm doesn't pass a stable estimate, we'll use the
628   // unstable one instead.
629   if (update.stable_target_bitrate.IsZero()) {
630     update.stable_target_bitrate = update.target_bitrate;
631   }
632 
633   rtp_video_sender_->OnBitrateUpdated(update, stats_proxy_->GetSendFrameRate());
634   encoder_target_rate_bps_ = rtp_video_sender_->GetPayloadBitrateBps();
635   const uint32_t protection_bitrate_bps =
636       rtp_video_sender_->GetProtectionBitrateBps();
637   DataRate link_allocation = DataRate::Zero();
638   if (encoder_target_rate_bps_ > protection_bitrate_bps) {
639     link_allocation =
640         DataRate::BitsPerSec(encoder_target_rate_bps_ - protection_bitrate_bps);
641   }
642   DataRate overhead =
643       update.target_bitrate - DataRate::BitsPerSec(encoder_target_rate_bps_);
644   DataRate encoder_stable_target_rate = update.stable_target_bitrate;
645   if (encoder_stable_target_rate > overhead) {
646     encoder_stable_target_rate = encoder_stable_target_rate - overhead;
647   } else {
648     encoder_stable_target_rate = DataRate::BitsPerSec(encoder_target_rate_bps_);
649   }
650 
651   encoder_target_rate_bps_ =
652       std::min(encoder_max_bitrate_bps_, encoder_target_rate_bps_);
653 
654   encoder_stable_target_rate =
655       std::min(DataRate::BitsPerSec(encoder_max_bitrate_bps_),
656                encoder_stable_target_rate);
657 
658   DataRate encoder_target_rate = DataRate::BitsPerSec(encoder_target_rate_bps_);
659   link_allocation = std::max(encoder_target_rate, link_allocation);
660   video_stream_encoder_->OnBitrateUpdated(
661       encoder_target_rate, encoder_stable_target_rate, link_allocation,
662       rtc::dchecked_cast<uint8_t>(update.packet_loss_ratio * 256),
663       update.round_trip_time.ms(), update.cwnd_reduce_ratio);
664   stats_proxy_->OnSetEncoderTargetRate(encoder_target_rate_bps_);
665   return protection_bitrate_bps;
666 }
667 
668 }  // namespace internal
669 }  // namespace webrtc
670