• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2012 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 "video/video_stream_encoder.h"
12 
13 #include <algorithm>
14 #include <array>
15 #include <limits>
16 #include <memory>
17 #include <numeric>
18 #include <utility>
19 
20 #include "absl/algorithm/container.h"
21 #include "absl/types/optional.h"
22 #include "api/task_queue/queued_task.h"
23 #include "api/task_queue/task_queue_base.h"
24 #include "api/video/encoded_image.h"
25 #include "api/video/i420_buffer.h"
26 #include "api/video/video_adaptation_reason.h"
27 #include "api/video/video_bitrate_allocator_factory.h"
28 #include "api/video/video_codec_constants.h"
29 #include "api/video_codecs/video_encoder.h"
30 #include "call/adaptation/resource_adaptation_processor.h"
31 #include "call/adaptation/video_stream_adapter.h"
32 #include "modules/video_coding/codecs/vp9/svc_rate_allocator.h"
33 #include "modules/video_coding/include/video_codec_initializer.h"
34 #include "rtc_base/arraysize.h"
35 #include "rtc_base/checks.h"
36 #include "rtc_base/constructor_magic.h"
37 #include "rtc_base/experiments/alr_experiment.h"
38 #include "rtc_base/experiments/rate_control_settings.h"
39 #include "rtc_base/location.h"
40 #include "rtc_base/logging.h"
41 #include "rtc_base/strings/string_builder.h"
42 #include "rtc_base/synchronization/mutex.h"
43 #include "rtc_base/synchronization/sequence_checker.h"
44 #include "rtc_base/thread_annotations.h"
45 #include "rtc_base/time_utils.h"
46 #include "rtc_base/trace_event.h"
47 #include "system_wrappers/include/field_trial.h"
48 #include "video/adaptation/video_stream_encoder_resource_manager.h"
49 
50 namespace webrtc {
51 
52 namespace {
53 
54 // Time interval for logging frame counts.
55 const int64_t kFrameLogIntervalMs = 60000;
56 
57 // Time to keep a single cached pending frame in paused state.
58 const int64_t kPendingFrameTimeoutMs = 1000;
59 
60 constexpr char kFrameDropperFieldTrial[] = "WebRTC-FrameDropper";
61 
62 // Averaging window spanning 90 frames at default 30fps, matching old media
63 // optimization module defaults.
64 const int64_t kFrameRateAvergingWindowSizeMs = (1000 / 30) * 90;
65 
66 const size_t kDefaultPayloadSize = 1440;
67 
68 const int64_t kParameterUpdateIntervalMs = 1000;
69 
70 // Animation is capped to 720p.
71 constexpr int kMaxAnimationPixels = 1280 * 720;
72 
RequiresEncoderReset(const VideoCodec & prev_send_codec,const VideoCodec & new_send_codec,bool was_encode_called_since_last_initialization)73 bool RequiresEncoderReset(const VideoCodec& prev_send_codec,
74                           const VideoCodec& new_send_codec,
75                           bool was_encode_called_since_last_initialization) {
76   // Does not check max/minBitrate or maxFramerate.
77   if (new_send_codec.codecType != prev_send_codec.codecType ||
78       new_send_codec.width != prev_send_codec.width ||
79       new_send_codec.height != prev_send_codec.height ||
80       new_send_codec.qpMax != prev_send_codec.qpMax ||
81       new_send_codec.numberOfSimulcastStreams !=
82           prev_send_codec.numberOfSimulcastStreams ||
83       new_send_codec.mode != prev_send_codec.mode) {
84     return true;
85   }
86 
87   if (!was_encode_called_since_last_initialization &&
88       (new_send_codec.startBitrate != prev_send_codec.startBitrate)) {
89     // If start bitrate has changed reconfigure encoder only if encoding had not
90     // yet started.
91     return true;
92   }
93 
94   switch (new_send_codec.codecType) {
95     case kVideoCodecVP8:
96       if (new_send_codec.VP8() != prev_send_codec.VP8()) {
97         return true;
98       }
99       break;
100 
101     case kVideoCodecVP9:
102       if (new_send_codec.VP9() != prev_send_codec.VP9()) {
103         return true;
104       }
105       break;
106 
107     case kVideoCodecH264:
108       if (new_send_codec.H264() != prev_send_codec.H264()) {
109         return true;
110       }
111       break;
112 
113     default:
114       break;
115   }
116 
117   for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams; ++i) {
118     if (new_send_codec.simulcastStream[i].width !=
119             prev_send_codec.simulcastStream[i].width ||
120         new_send_codec.simulcastStream[i].height !=
121             prev_send_codec.simulcastStream[i].height ||
122         new_send_codec.simulcastStream[i].maxFramerate !=
123             prev_send_codec.simulcastStream[i].maxFramerate ||
124         new_send_codec.simulcastStream[i].numberOfTemporalLayers !=
125             prev_send_codec.simulcastStream[i].numberOfTemporalLayers ||
126         new_send_codec.simulcastStream[i].qpMax !=
127             prev_send_codec.simulcastStream[i].qpMax ||
128         new_send_codec.simulcastStream[i].active !=
129             prev_send_codec.simulcastStream[i].active) {
130       return true;
131     }
132   }
133   return false;
134 }
135 
GetExperimentGroups()136 std::array<uint8_t, 2> GetExperimentGroups() {
137   std::array<uint8_t, 2> experiment_groups;
138   absl::optional<AlrExperimentSettings> experiment_settings =
139       AlrExperimentSettings::CreateFromFieldTrial(
140           AlrExperimentSettings::kStrictPacingAndProbingExperimentName);
141   if (experiment_settings) {
142     experiment_groups[0] = experiment_settings->group_id + 1;
143   } else {
144     experiment_groups[0] = 0;
145   }
146   experiment_settings = AlrExperimentSettings::CreateFromFieldTrial(
147       AlrExperimentSettings::kScreenshareProbingBweExperimentName);
148   if (experiment_settings) {
149     experiment_groups[1] = experiment_settings->group_id + 1;
150   } else {
151     experiment_groups[1] = 0;
152   }
153   return experiment_groups;
154 }
155 
156 // Limit allocation across TLs in bitrate allocation according to number of TLs
157 // in EncoderInfo.
UpdateAllocationFromEncoderInfo(const VideoBitrateAllocation & allocation,const VideoEncoder::EncoderInfo & encoder_info)158 VideoBitrateAllocation UpdateAllocationFromEncoderInfo(
159     const VideoBitrateAllocation& allocation,
160     const VideoEncoder::EncoderInfo& encoder_info) {
161   if (allocation.get_sum_bps() == 0) {
162     return allocation;
163   }
164   VideoBitrateAllocation new_allocation;
165   for (int si = 0; si < kMaxSpatialLayers; ++si) {
166     if (encoder_info.fps_allocation[si].size() == 1 &&
167         allocation.IsSpatialLayerUsed(si)) {
168       // One TL is signalled to be used by the encoder. Do not distribute
169       // bitrate allocation across TLs (use sum at ti:0).
170       new_allocation.SetBitrate(si, 0, allocation.GetSpatialLayerSum(si));
171     } else {
172       for (int ti = 0; ti < kMaxTemporalStreams; ++ti) {
173         if (allocation.HasBitrate(si, ti))
174           new_allocation.SetBitrate(si, ti, allocation.GetBitrate(si, ti));
175       }
176     }
177   }
178   new_allocation.set_bw_limited(allocation.is_bw_limited());
179   return new_allocation;
180 }
181 
182 }  //  namespace
183 
EncoderRateSettings()184 VideoStreamEncoder::EncoderRateSettings::EncoderRateSettings()
185     : rate_control(),
186       encoder_target(DataRate::Zero()),
187       stable_encoder_target(DataRate::Zero()) {}
188 
EncoderRateSettings(const VideoBitrateAllocation & bitrate,double framerate_fps,DataRate bandwidth_allocation,DataRate encoder_target,DataRate stable_encoder_target)189 VideoStreamEncoder::EncoderRateSettings::EncoderRateSettings(
190     const VideoBitrateAllocation& bitrate,
191     double framerate_fps,
192     DataRate bandwidth_allocation,
193     DataRate encoder_target,
194     DataRate stable_encoder_target)
195     : rate_control(bitrate, framerate_fps, bandwidth_allocation),
196       encoder_target(encoder_target),
197       stable_encoder_target(stable_encoder_target) {}
198 
operator ==(const EncoderRateSettings & rhs) const199 bool VideoStreamEncoder::EncoderRateSettings::operator==(
200     const EncoderRateSettings& rhs) const {
201   return rate_control == rhs.rate_control &&
202          encoder_target == rhs.encoder_target &&
203          stable_encoder_target == rhs.stable_encoder_target;
204 }
205 
operator !=(const EncoderRateSettings & rhs) const206 bool VideoStreamEncoder::EncoderRateSettings::operator!=(
207     const EncoderRateSettings& rhs) const {
208   return !(*this == rhs);
209 }
210 
211 class VideoStreamEncoder::DegradationPreferenceManager
212     : public DegradationPreferenceProvider {
213  public:
DegradationPreferenceManager()214   DegradationPreferenceManager()
215       : degradation_preference_(DegradationPreference::DISABLED),
216         is_screenshare_(false),
217         effective_degradation_preference_(DegradationPreference::DISABLED) {}
218 
~DegradationPreferenceManager()219   ~DegradationPreferenceManager() override {
220     RTC_DCHECK(!video_stream_adapter_);
221   }
222 
degradation_preference() const223   DegradationPreference degradation_preference() const override {
224     MutexLock lock(&lock_);
225     return effective_degradation_preference_;
226   }
227 
SetDegradationPreference(DegradationPreference degradation_preference)228   void SetDegradationPreference(DegradationPreference degradation_preference) {
229     MutexLock lock(&lock_);
230     degradation_preference_ = degradation_preference;
231     MaybeUpdateEffectiveDegradationPreference();
232   }
233 
SetIsScreenshare(bool is_screenshare)234   void SetIsScreenshare(bool is_screenshare) {
235     MutexLock lock(&lock_);
236     is_screenshare_ = is_screenshare;
237     MaybeUpdateEffectiveDegradationPreference();
238   }
239 
SetVideoStreamAdapterQueue(TaskQueueBase * video_stream_adapter_task_queue)240   void SetVideoStreamAdapterQueue(
241       TaskQueueBase* video_stream_adapter_task_queue) {
242     RTC_DCHECK(!video_stream_adapter_task_queue_);
243     RTC_DCHECK(video_stream_adapter_task_queue);
244     RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue);
245     video_stream_adapter_task_queue_ = video_stream_adapter_task_queue;
246   }
247 
SetVideoStreamAdapter(VideoStreamAdapter * video_stream_adapter)248   void SetVideoStreamAdapter(VideoStreamAdapter* video_stream_adapter) {
249     RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue_);
250     video_stream_adapter_ = video_stream_adapter;
251   }
252 
253  private:
MaybeUpdateEffectiveDegradationPreference()254   void MaybeUpdateEffectiveDegradationPreference()
255       RTC_EXCLUSIVE_LOCKS_REQUIRED(&lock_) {
256     DegradationPreference effective_degradation_preference =
257         (is_screenshare_ &&
258          degradation_preference_ == DegradationPreference::BALANCED)
259             ? DegradationPreference::MAINTAIN_RESOLUTION
260             : degradation_preference_;
261 
262     if (effective_degradation_preference != effective_degradation_preference_) {
263       effective_degradation_preference_ = effective_degradation_preference;
264       if (video_stream_adapter_task_queue_) {
265         video_stream_adapter_task_queue_->PostTask(
266             ToQueuedTask([this, effective_degradation_preference]() {
267               RTC_DCHECK_RUN_ON(video_stream_adapter_task_queue_);
268               if (video_stream_adapter_) {
269                 video_stream_adapter_->SetDegradationPreference(
270                     effective_degradation_preference);
271               }
272             }));
273       }
274     }
275   }
276 
277   mutable Mutex lock_;
278   DegradationPreference degradation_preference_ RTC_GUARDED_BY(&lock_);
279   bool is_screenshare_ RTC_GUARDED_BY(&lock_);
280   DegradationPreference effective_degradation_preference_
281       RTC_GUARDED_BY(&lock_);
282   TaskQueueBase* video_stream_adapter_task_queue_ = nullptr;
283   VideoStreamAdapter* video_stream_adapter_
284       RTC_GUARDED_BY(&video_stream_adapter_task_queue_);
285 };
286 
VideoStreamEncoder(Clock * clock,uint32_t number_of_cores,VideoStreamEncoderObserver * encoder_stats_observer,const VideoStreamEncoderSettings & settings,std::unique_ptr<OveruseFrameDetector> overuse_detector,TaskQueueFactory * task_queue_factory)287 VideoStreamEncoder::VideoStreamEncoder(
288     Clock* clock,
289     uint32_t number_of_cores,
290     VideoStreamEncoderObserver* encoder_stats_observer,
291     const VideoStreamEncoderSettings& settings,
292     std::unique_ptr<OveruseFrameDetector> overuse_detector,
293     TaskQueueFactory* task_queue_factory)
294     : shutdown_event_(true /* manual_reset */, false),
295       number_of_cores_(number_of_cores),
296       quality_scaling_experiment_enabled_(QualityScalingExperiment::Enabled()),
297       sink_(nullptr),
298       settings_(settings),
299       rate_control_settings_(RateControlSettings::ParseFromFieldTrials()),
300       encoder_selector_(settings.encoder_factory->GetEncoderSelector()),
301       encoder_stats_observer_(encoder_stats_observer),
302       encoder_initialized_(false),
303       max_framerate_(-1),
304       pending_encoder_reconfiguration_(false),
305       pending_encoder_creation_(false),
306       crop_width_(0),
307       crop_height_(0),
308       encoder_target_bitrate_bps_(absl::nullopt),
309       max_data_payload_length_(0),
310       encoder_paused_and_dropped_frame_(false),
311       was_encode_called_since_last_initialization_(false),
312       encoder_failed_(false),
313       clock_(clock),
314       posted_frames_waiting_for_encode_(0),
315       last_captured_timestamp_(0),
316       delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() -
317                              clock_->TimeInMilliseconds()),
318       last_frame_log_ms_(clock_->TimeInMilliseconds()),
319       captured_frame_count_(0),
320       dropped_frame_cwnd_pushback_count_(0),
321       dropped_frame_encoder_block_count_(0),
322       pending_frame_post_time_us_(0),
323       accumulated_update_rect_{0, 0, 0, 0},
324       accumulated_update_rect_is_valid_(true),
325       animation_start_time_(Timestamp::PlusInfinity()),
326       cap_resolution_due_to_video_content_(false),
327       expect_resize_state_(ExpectResizeState::kNoResize),
328       bitrate_observer_(nullptr),
329       fec_controller_override_(nullptr),
330       force_disable_frame_dropper_(false),
331       input_framerate_(kFrameRateAvergingWindowSizeMs, 1000),
332       pending_frame_drops_(0),
333       cwnd_frame_counter_(0),
334       next_frame_types_(1, VideoFrameType::kVideoFrameDelta),
335       frame_encode_metadata_writer_(this),
336       experiment_groups_(GetExperimentGroups()),
337       encoder_switch_experiment_(ParseEncoderSwitchFieldTrial()),
338       automatic_animation_detection_experiment_(
339           ParseAutomatincAnimationDetectionFieldTrial()),
340       encoder_switch_requested_(false),
341       input_state_provider_(encoder_stats_observer),
342       video_stream_adapter_(
343           std::make_unique<VideoStreamAdapter>(&input_state_provider_)),
344       resource_adaptation_processor_(
345           std::make_unique<ResourceAdaptationProcessor>(
346               encoder_stats_observer,
347               video_stream_adapter_.get())),
348       degradation_preference_manager_(
349           std::make_unique<DegradationPreferenceManager>()),
350       adaptation_constraints_(),
351       stream_resource_manager_(&input_state_provider_,
352                                encoder_stats_observer,
353                                clock_,
354                                settings_.experiment_cpu_load_estimator,
355                                std::move(overuse_detector),
356                                degradation_preference_manager_.get()),
357       video_source_sink_controller_(/*sink=*/this,
358                                     /*source=*/nullptr),
359       resource_adaptation_queue_(task_queue_factory->CreateTaskQueue(
360           "ResourceAdaptationQueue",
361           TaskQueueFactory::Priority::NORMAL)),
362       encoder_queue_(task_queue_factory->CreateTaskQueue(
363           "EncoderQueue",
364           TaskQueueFactory::Priority::NORMAL)) {
365   RTC_DCHECK(encoder_stats_observer);
366   RTC_DCHECK_GE(number_of_cores, 1);
367 
368   stream_resource_manager_.Initialize(&encoder_queue_,
369                                       &resource_adaptation_queue_);
370 
371   rtc::Event initialize_processor_event;
__anon9322e9290302null372   resource_adaptation_queue_.PostTask([this, &initialize_processor_event] {
373     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
374     resource_adaptation_processor_->SetResourceAdaptationQueue(
375         resource_adaptation_queue_.Get());
376     stream_resource_manager_.SetAdaptationProcessor(
377         resource_adaptation_processor_.get(), video_stream_adapter_.get());
378     resource_adaptation_processor_->AddResourceLimitationsListener(
379         &stream_resource_manager_);
380     video_stream_adapter_->AddRestrictionsListener(&stream_resource_manager_);
381     video_stream_adapter_->AddRestrictionsListener(this);
382     degradation_preference_manager_->SetVideoStreamAdapterQueue(
383         resource_adaptation_queue_.Get());
384     degradation_preference_manager_->SetVideoStreamAdapter(
385         video_stream_adapter_.get());
386 
387     // Add the stream resource manager's resources to the processor.
388     adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints();
389     for (auto& resource : stream_resource_manager_.MappedResources()) {
390       resource_adaptation_processor_->AddResource(resource);
391     }
392     for (auto* constraint : adaptation_constraints_) {
393       video_stream_adapter_->AddAdaptationConstraint(constraint);
394     }
395     for (auto* listener : stream_resource_manager_.AdaptationListeners()) {
396       video_stream_adapter_->AddAdaptationListener(listener);
397     }
398     initialize_processor_event.Set();
399   });
400   initialize_processor_event.Wait(rtc::Event::kForever);
401 }
402 
~VideoStreamEncoder()403 VideoStreamEncoder::~VideoStreamEncoder() {
404   RTC_DCHECK_RUN_ON(&thread_checker_);
405   RTC_DCHECK(shutdown_event_.Wait(0))
406       << "Must call ::Stop() before destruction.";
407 }
408 
Stop()409 void VideoStreamEncoder::Stop() {
410   RTC_DCHECK_RUN_ON(&thread_checker_);
411   video_source_sink_controller_.SetSource(nullptr);
412 
413   if (resource_adaptation_processor_) {
414     for (auto& resource : stream_resource_manager_.MappedResources()) {
415       resource_adaptation_processor_->RemoveResource(resource);
416     }
417   }
418   rtc::Event shutdown_adaptation_processor_event;
419   resource_adaptation_queue_.PostTask([this,
420                                        &shutdown_adaptation_processor_event] {
421     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
422     if (resource_adaptation_processor_) {
423       // Removed on the resource_adaptaiton_processor_ queue because the
424       // adaptation_constraints_ and adaptation_listeners_ fields are guarded by
425       // this queue.
426       for (auto* constraint : adaptation_constraints_) {
427         video_stream_adapter_->RemoveAdaptationConstraint(constraint);
428       }
429       for (auto* listener : stream_resource_manager_.AdaptationListeners()) {
430         video_stream_adapter_->RemoveAdaptationListener(listener);
431       }
432       video_stream_adapter_->RemoveRestrictionsListener(this);
433       video_stream_adapter_->RemoveRestrictionsListener(
434           &stream_resource_manager_);
435       resource_adaptation_processor_->RemoveResourceLimitationsListener(
436           &stream_resource_manager_);
437       stream_resource_manager_.SetAdaptationProcessor(nullptr, nullptr);
438       degradation_preference_manager_->SetVideoStreamAdapter(nullptr);
439       resource_adaptation_processor_.reset();
440     }
441     shutdown_adaptation_processor_event.Set();
442   });
443   shutdown_adaptation_processor_event.Wait(rtc::Event::kForever);
444   encoder_queue_.PostTask([this] {
445     RTC_DCHECK_RUN_ON(&encoder_queue_);
446     stream_resource_manager_.StopManagedResources();
447     rate_allocator_ = nullptr;
448     bitrate_observer_ = nullptr;
449     ReleaseEncoder();
450     shutdown_event_.Set();
451   });
452   shutdown_event_.Wait(rtc::Event::kForever);
453 }
454 
SetBitrateAllocationObserver(VideoBitrateAllocationObserver * bitrate_observer)455 void VideoStreamEncoder::SetBitrateAllocationObserver(
456     VideoBitrateAllocationObserver* bitrate_observer) {
457   RTC_DCHECK_RUN_ON(&thread_checker_);
458   encoder_queue_.PostTask([this, bitrate_observer] {
459     RTC_DCHECK_RUN_ON(&encoder_queue_);
460     RTC_DCHECK(!bitrate_observer_);
461     bitrate_observer_ = bitrate_observer;
462   });
463 }
464 
SetFecControllerOverride(FecControllerOverride * fec_controller_override)465 void VideoStreamEncoder::SetFecControllerOverride(
466     FecControllerOverride* fec_controller_override) {
467   encoder_queue_.PostTask([this, fec_controller_override] {
468     RTC_DCHECK_RUN_ON(&encoder_queue_);
469     RTC_DCHECK(!fec_controller_override_);
470     fec_controller_override_ = fec_controller_override;
471     if (encoder_) {
472       encoder_->SetFecControllerOverride(fec_controller_override_);
473     }
474   });
475 }
476 
AddAdaptationResource(rtc::scoped_refptr<Resource> resource)477 void VideoStreamEncoder::AddAdaptationResource(
478     rtc::scoped_refptr<Resource> resource) {
479   // Map any externally added resources as kCpu for the sake of stats reporting.
480   // TODO(hbos): Make the manager map any unknown resources to kCpu and get rid
481   // of this MapResourceToReason() call.
482   rtc::Event map_resource_event;
483   encoder_queue_.PostTask([this, resource, &map_resource_event] {
484     RTC_DCHECK_RUN_ON(&encoder_queue_);
485     stream_resource_manager_.MapResourceToReason(resource,
486                                                  VideoAdaptationReason::kCpu);
487     resource_adaptation_processor_->AddResource(resource);
488     map_resource_event.Set();
489   });
490   map_resource_event.Wait(rtc::Event::kForever);
491 }
492 
493 std::vector<rtc::scoped_refptr<Resource>>
GetAdaptationResources()494 VideoStreamEncoder::GetAdaptationResources() {
495   return resource_adaptation_processor_->GetResources();
496 }
497 
SetSource(rtc::VideoSourceInterface<VideoFrame> * source,const DegradationPreference & degradation_preference)498 void VideoStreamEncoder::SetSource(
499     rtc::VideoSourceInterface<VideoFrame>* source,
500     const DegradationPreference& degradation_preference) {
501   RTC_DCHECK_RUN_ON(&thread_checker_);
502   video_source_sink_controller_.SetSource(source);
503   input_state_provider_.OnHasInputChanged(source);
504 
505   degradation_preference_manager_->SetDegradationPreference(
506       degradation_preference);
507   // This may trigger reconfiguring the QualityScaler on the encoder queue.
508   encoder_queue_.PostTask([this, degradation_preference] {
509     RTC_DCHECK_RUN_ON(&encoder_queue_);
510     stream_resource_manager_.SetDegradationPreferences(degradation_preference);
511     if (encoder_) {
512       stream_resource_manager_.ConfigureQualityScaler(
513           encoder_->GetEncoderInfo());
514     }
515   });
516 }
517 
SetSink(EncoderSink * sink,bool rotation_applied)518 void VideoStreamEncoder::SetSink(EncoderSink* sink, bool rotation_applied) {
519   video_source_sink_controller_.SetRotationApplied(rotation_applied);
520   video_source_sink_controller_.PushSourceSinkSettings();
521   encoder_queue_.PostTask([this, sink] {
522     RTC_DCHECK_RUN_ON(&encoder_queue_);
523     sink_ = sink;
524   });
525 }
526 
SetStartBitrate(int start_bitrate_bps)527 void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) {
528   encoder_queue_.PostTask([this, start_bitrate_bps] {
529     RTC_DCHECK_RUN_ON(&encoder_queue_);
530     encoder_target_bitrate_bps_ =
531         start_bitrate_bps != 0 ? absl::optional<uint32_t>(start_bitrate_bps)
532                                : absl::nullopt;
533     stream_resource_manager_.SetStartBitrate(
534         DataRate::BitsPerSec(start_bitrate_bps));
535   });
536 }
537 
ConfigureEncoder(VideoEncoderConfig config,size_t max_data_payload_length)538 void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config,
539                                           size_t max_data_payload_length) {
540   encoder_queue_.PostTask(
541       [this, config = std::move(config), max_data_payload_length]() mutable {
542         RTC_DCHECK_RUN_ON(&encoder_queue_);
543         RTC_DCHECK(sink_);
544         RTC_LOG(LS_INFO) << "ConfigureEncoder requested.";
545 
546         pending_encoder_creation_ =
547             (!encoder_ || encoder_config_.video_format != config.video_format ||
548              max_data_payload_length_ != max_data_payload_length);
549         encoder_config_ = std::move(config);
550         max_data_payload_length_ = max_data_payload_length;
551         pending_encoder_reconfiguration_ = true;
552 
553         // Reconfigure the encoder now if the encoder has an internal source or
554         // if the frame resolution is known. Otherwise, the reconfiguration is
555         // deferred until the next frame to minimize the number of
556         // reconfigurations. The codec configuration depends on incoming video
557         // frame size.
558         if (last_frame_info_) {
559           ReconfigureEncoder();
560         } else {
561           codec_info_ = settings_.encoder_factory->QueryVideoEncoder(
562               encoder_config_.video_format);
563           if (HasInternalSource()) {
564             last_frame_info_ = VideoFrameInfo(kDefaultInputPixelsWidth,
565                                               kDefaultInputPixelsHeight, false);
566             ReconfigureEncoder();
567           }
568         }
569       });
570 }
571 
572 // TODO(bugs.webrtc.org/8807): Currently this always does a hard
573 // reconfiguration, but this isn't always necessary. Add in logic to only update
574 // the VideoBitrateAllocator and call OnEncoderConfigurationChanged with a
575 // "soft" reconfiguration.
ReconfigureEncoder()576 void VideoStreamEncoder::ReconfigureEncoder() {
577   RTC_DCHECK(pending_encoder_reconfiguration_);
578 
579   if (!encoder_selector_ &&
580       encoder_switch_experiment_.IsPixelCountBelowThreshold(
581           last_frame_info_->width * last_frame_info_->height) &&
582       !encoder_switch_requested_ && settings_.encoder_switch_request_callback) {
583     EncoderSwitchRequestCallback::Config conf;
584     conf.codec_name = encoder_switch_experiment_.to_codec;
585     conf.param = encoder_switch_experiment_.to_param;
586     conf.value = encoder_switch_experiment_.to_value;
587     settings_.encoder_switch_request_callback->RequestEncoderSwitch(conf);
588 
589     encoder_switch_requested_ = true;
590   }
591 
592   std::vector<VideoStream> streams =
593       encoder_config_.video_stream_factory->CreateEncoderStreams(
594           last_frame_info_->width, last_frame_info_->height, encoder_config_);
595 
596   // Check that the higher layers do not try to set number of temporal layers
597   // to less than 1.
598   // TODO(brandtr): Get rid of the wrapping optional as it serves no purpose
599   // at this layer.
600 #if RTC_DCHECK_IS_ON
601   for (const auto& stream : streams) {
602     RTC_DCHECK_GE(stream.num_temporal_layers.value_or(1), 1);
603   }
604 #endif
605 
606   // TODO(ilnik): If configured resolution is significantly less than provided,
607   // e.g. because there are not enough SSRCs for all simulcast streams,
608   // signal new resolutions via SinkWants to video source.
609 
610   // Stream dimensions may be not equal to given because of a simulcast
611   // restrictions.
612   auto highest_stream = absl::c_max_element(
613       streams, [](const webrtc::VideoStream& a, const webrtc::VideoStream& b) {
614         return std::tie(a.width, a.height) < std::tie(b.width, b.height);
615       });
616   int highest_stream_width = static_cast<int>(highest_stream->width);
617   int highest_stream_height = static_cast<int>(highest_stream->height);
618   // Dimension may be reduced to be, e.g. divisible by 4.
619   RTC_CHECK_GE(last_frame_info_->width, highest_stream_width);
620   RTC_CHECK_GE(last_frame_info_->height, highest_stream_height);
621   crop_width_ = last_frame_info_->width - highest_stream_width;
622   crop_height_ = last_frame_info_->height - highest_stream_height;
623 
624   bool encoder_reset_required = false;
625   if (pending_encoder_creation_) {
626     // Destroy existing encoder instance before creating a new one. Otherwise
627     // attempt to create another instance will fail if encoder factory
628     // supports only single instance of encoder of given type.
629     encoder_.reset();
630 
631     encoder_ = settings_.encoder_factory->CreateVideoEncoder(
632         encoder_config_.video_format);
633     // TODO(nisse): What to do if creating the encoder fails? Crash,
634     // or just discard incoming frames?
635     RTC_CHECK(encoder_);
636 
637     if (encoder_selector_) {
638       encoder_selector_->OnCurrentEncoder(encoder_config_.video_format);
639     }
640 
641     encoder_->SetFecControllerOverride(fec_controller_override_);
642 
643     codec_info_ = settings_.encoder_factory->QueryVideoEncoder(
644         encoder_config_.video_format);
645 
646     encoder_reset_required = true;
647   }
648 
649   encoder_bitrate_limits_ =
650       encoder_->GetEncoderInfo().GetEncoderBitrateLimitsForResolution(
651           last_frame_info_->width * last_frame_info_->height);
652 
653   if (streams.size() == 1 && encoder_bitrate_limits_) {
654     // Bitrate limits can be set by app (in SDP or RtpEncodingParameters) or/and
655     // can be provided by encoder. In presence of both set of limits, the final
656     // set is derived as their intersection.
657     int min_bitrate_bps;
658     if (encoder_config_.simulcast_layers.empty() ||
659         encoder_config_.simulcast_layers[0].min_bitrate_bps <= 0) {
660       min_bitrate_bps = encoder_bitrate_limits_->min_bitrate_bps;
661     } else {
662       min_bitrate_bps = std::max(encoder_bitrate_limits_->min_bitrate_bps,
663                                  streams.back().min_bitrate_bps);
664     }
665 
666     int max_bitrate_bps;
667     // We don't check encoder_config_.simulcast_layers[0].max_bitrate_bps
668     // here since encoder_config_.max_bitrate_bps is derived from it (as
669     // well as from other inputs).
670     if (encoder_config_.max_bitrate_bps <= 0) {
671       max_bitrate_bps = encoder_bitrate_limits_->max_bitrate_bps;
672     } else {
673       max_bitrate_bps = std::min(encoder_bitrate_limits_->max_bitrate_bps,
674                                  streams.back().max_bitrate_bps);
675     }
676 
677     if (min_bitrate_bps < max_bitrate_bps) {
678       streams.back().min_bitrate_bps = min_bitrate_bps;
679       streams.back().max_bitrate_bps = max_bitrate_bps;
680       streams.back().target_bitrate_bps =
681           std::min(streams.back().target_bitrate_bps,
682                    encoder_bitrate_limits_->max_bitrate_bps);
683     } else {
684       RTC_LOG(LS_WARNING) << "Bitrate limits provided by encoder"
685                           << " (min="
686                           << encoder_bitrate_limits_->min_bitrate_bps
687                           << ", max="
688                           << encoder_bitrate_limits_->min_bitrate_bps
689                           << ") do not intersect with limits set by app"
690                           << " (min=" << streams.back().min_bitrate_bps
691                           << ", max=" << encoder_config_.max_bitrate_bps
692                           << "). The app bitrate limits will be used.";
693     }
694   }
695 
696   VideoCodec codec;
697   if (!VideoCodecInitializer::SetupCodec(encoder_config_, streams, &codec)) {
698     RTC_LOG(LS_ERROR) << "Failed to create encoder configuration.";
699   }
700 
701   if (encoder_config_.codec_type == kVideoCodecVP9) {
702     // Spatial layers configuration might impose some parity restrictions,
703     // thus some cropping might be needed.
704     crop_width_ = last_frame_info_->width - codec.width;
705     crop_height_ = last_frame_info_->height - codec.height;
706   }
707 
708   char log_stream_buf[4 * 1024];
709   rtc::SimpleStringBuilder log_stream(log_stream_buf);
710   log_stream << "ReconfigureEncoder:\n";
711   log_stream << "Simulcast streams:\n";
712   for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) {
713     log_stream << i << ": " << codec.simulcastStream[i].width << "x"
714                << codec.simulcastStream[i].height
715                << " fps: " << codec.simulcastStream[i].maxFramerate
716                << " min_kbps: " << codec.simulcastStream[i].minBitrate
717                << " target_kbps: " << codec.simulcastStream[i].targetBitrate
718                << " max_kbps: " << codec.simulcastStream[i].maxBitrate
719                << " max_fps: " << codec.simulcastStream[i].maxFramerate
720                << " max_qp: " << codec.simulcastStream[i].qpMax
721                << " num_tl: " << codec.simulcastStream[i].numberOfTemporalLayers
722                << " active: "
723                << (codec.simulcastStream[i].active ? "true" : "false") << "\n";
724   }
725   if (encoder_config_.codec_type == kVideoCodecVP9) {
726     size_t num_spatial_layers = codec.VP9()->numberOfSpatialLayers;
727     log_stream << "Spatial layers:\n";
728     for (size_t i = 0; i < num_spatial_layers; ++i) {
729       log_stream << i << ": " << codec.spatialLayers[i].width << "x"
730                  << codec.spatialLayers[i].height
731                  << " fps: " << codec.spatialLayers[i].maxFramerate
732                  << " min_kbps: " << codec.spatialLayers[i].minBitrate
733                  << " target_kbps: " << codec.spatialLayers[i].targetBitrate
734                  << " max_kbps: " << codec.spatialLayers[i].maxBitrate
735                  << " max_qp: " << codec.spatialLayers[i].qpMax
736                  << " num_tl: " << codec.spatialLayers[i].numberOfTemporalLayers
737                  << " active: "
738                  << (codec.spatialLayers[i].active ? "true" : "false") << "\n";
739     }
740   }
741   RTC_LOG(LS_INFO) << log_stream.str();
742 
743   codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000,
744                                 codec.minBitrate);
745   codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate);
746   codec.expect_encode_from_texture = last_frame_info_->is_texture;
747   // Make sure the start bit rate is sane...
748   RTC_DCHECK_LE(codec.startBitrate, 1000000);
749   max_framerate_ = codec.maxFramerate;
750 
751   // Inform source about max configured framerate.
752   int max_framerate = 0;
753   for (const auto& stream : streams) {
754     max_framerate = std::max(stream.max_framerate, max_framerate);
755   }
756   int alignment = encoder_->GetEncoderInfo().requested_resolution_alignment;
757   if (max_framerate != video_source_sink_controller_.frame_rate_upper_limit() ||
758       alignment != video_source_sink_controller_.resolution_alignment()) {
759     video_source_sink_controller_.SetFrameRateUpperLimit(max_framerate);
760     video_source_sink_controller_.SetResolutionAlignment(alignment);
761     video_source_sink_controller_.PushSourceSinkSettings();
762   }
763 
764   if (codec.maxBitrate == 0) {
765     // max is one bit per pixel
766     codec.maxBitrate =
767         (static_cast<int>(codec.height) * static_cast<int>(codec.width) *
768          static_cast<int>(codec.maxFramerate)) /
769         1000;
770     if (codec.startBitrate > codec.maxBitrate) {
771       // But if the user tries to set a higher start bit rate we will
772       // increase the max accordingly.
773       codec.maxBitrate = codec.startBitrate;
774     }
775   }
776 
777   if (codec.startBitrate > codec.maxBitrate) {
778     codec.startBitrate = codec.maxBitrate;
779   }
780 
781   rate_allocator_ =
782       settings_.bitrate_allocator_factory->CreateVideoBitrateAllocator(codec);
783 
784   // Reset (release existing encoder) if one exists and anything except
785   // start bitrate or max framerate has changed.
786   if (!encoder_reset_required) {
787     encoder_reset_required = RequiresEncoderReset(
788         codec, send_codec_, was_encode_called_since_last_initialization_);
789   }
790   send_codec_ = codec;
791 
792   encoder_switch_experiment_.SetCodec(send_codec_.codecType);
793 
794   // Keep the same encoder, as long as the video_format is unchanged.
795   // Encoder creation block is split in two since EncoderInfo needed to start
796   // CPU adaptation with the correct settings should be polled after
797   // encoder_->InitEncode().
798   bool success = true;
799   if (encoder_reset_required) {
800     ReleaseEncoder();
801     const size_t max_data_payload_length = max_data_payload_length_ > 0
802                                                ? max_data_payload_length_
803                                                : kDefaultPayloadSize;
804     if (encoder_->InitEncode(
805             &send_codec_,
806             VideoEncoder::Settings(settings_.capabilities, number_of_cores_,
807                                    max_data_payload_length)) != 0) {
808       RTC_LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
809                            "codec type: "
810                         << CodecTypeToPayloadString(send_codec_.codecType)
811                         << " (" << send_codec_.codecType << ")";
812       ReleaseEncoder();
813       success = false;
814     } else {
815       encoder_initialized_ = true;
816       encoder_->RegisterEncodeCompleteCallback(this);
817       frame_encode_metadata_writer_.OnEncoderInit(send_codec_,
818                                                   HasInternalSource());
819     }
820 
821     frame_encode_metadata_writer_.Reset();
822     last_encode_info_ms_ = absl::nullopt;
823     was_encode_called_since_last_initialization_ = false;
824   }
825 
826   // Inform dependents of updated encoder settings.
827   OnEncoderSettingsChanged();
828 
829   if (success) {
830     next_frame_types_.clear();
831     next_frame_types_.resize(
832         std::max(static_cast<int>(codec.numberOfSimulcastStreams), 1),
833         VideoFrameType::kVideoFrameKey);
834     RTC_LOG(LS_VERBOSE) << " max bitrate " << codec.maxBitrate
835                         << " start bitrate " << codec.startBitrate
836                         << " max frame rate " << codec.maxFramerate
837                         << " max payload size " << max_data_payload_length_;
838   } else {
839     RTC_LOG(LS_ERROR) << "Failed to configure encoder.";
840     rate_allocator_ = nullptr;
841   }
842 
843   if (pending_encoder_creation_) {
844     // TODO(hbos): Stopping and restarting for backwards compatibility reasons.
845     // We may be able to change this to "EnsureStarted()" if it took care of
846     // reconfiguring the QualityScaler as well. (ConfigureQualityScaler() is
847     // invoked later in this method.)
848     stream_resource_manager_.StopManagedResources();
849     stream_resource_manager_.StartEncodeUsageResource();
850     pending_encoder_creation_ = false;
851   }
852 
853   int num_layers;
854   if (codec.codecType == kVideoCodecVP8) {
855     num_layers = codec.VP8()->numberOfTemporalLayers;
856   } else if (codec.codecType == kVideoCodecVP9) {
857     num_layers = codec.VP9()->numberOfTemporalLayers;
858   } else if (codec.codecType == kVideoCodecH264) {
859     num_layers = codec.H264()->numberOfTemporalLayers;
860   } else if (codec.codecType == kVideoCodecGeneric &&
861              codec.numberOfSimulcastStreams > 0) {
862     // This is mainly for unit testing, disabling frame dropping.
863     // TODO(sprang): Add a better way to disable frame dropping.
864     num_layers = codec.simulcastStream[0].numberOfTemporalLayers;
865   } else {
866     num_layers = 1;
867   }
868 
869   frame_dropper_.Reset();
870   frame_dropper_.SetRates(codec.startBitrate, max_framerate_);
871   // Force-disable frame dropper if either:
872   //  * We have screensharing with layers.
873   //  * "WebRTC-FrameDropper" field trial is "Disabled".
874   force_disable_frame_dropper_ =
875       field_trial::IsDisabled(kFrameDropperFieldTrial) ||
876       (num_layers > 1 && codec.mode == VideoCodecMode::kScreensharing);
877 
878   VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
879   if (rate_control_settings_.UseEncoderBitrateAdjuster()) {
880     bitrate_adjuster_ = std::make_unique<EncoderBitrateAdjuster>(codec);
881     bitrate_adjuster_->OnEncoderInfo(info);
882   }
883 
884   if (rate_allocator_ && last_encoder_rate_settings_) {
885     // We have a new rate allocator instance and already configured target
886     // bitrate. Update the rate allocation and notify observers.
887     // We must invalidate the last_encoder_rate_settings_ to ensure
888     // the changes get propagated to all listeners.
889     EncoderRateSettings rate_settings = *last_encoder_rate_settings_;
890     last_encoder_rate_settings_.reset();
891     rate_settings.rate_control.framerate_fps = GetInputFramerateFps();
892 
893     SetEncoderRates(UpdateBitrateAllocationAndNotifyObserver(rate_settings));
894   }
895 
896   encoder_stats_observer_->OnEncoderReconfigured(encoder_config_, streams);
897 
898   pending_encoder_reconfiguration_ = false;
899 
900   bool is_svc = false;
901   // Set min_bitrate_bps, max_bitrate_bps, and max padding bit rate for VP9
902   // and leave only one stream containing all necessary information.
903   if (encoder_config_.codec_type == kVideoCodecVP9) {
904     // Lower max bitrate to the level codec actually can produce.
905     streams[0].max_bitrate_bps =
906         std::min(streams[0].max_bitrate_bps,
907                  SvcRateAllocator::GetMaxBitrate(codec).bps<int>());
908     streams[0].min_bitrate_bps = codec.spatialLayers[0].minBitrate * 1000;
909     // target_bitrate_bps specifies the maximum padding bitrate.
910     streams[0].target_bitrate_bps =
911         SvcRateAllocator::GetPaddingBitrate(codec).bps<int>();
912     streams[0].width = streams.back().width;
913     streams[0].height = streams.back().height;
914     is_svc = codec.VP9()->numberOfSpatialLayers > 1;
915     streams.resize(1);
916   }
917 
918   sink_->OnEncoderConfigurationChanged(
919       std::move(streams), is_svc, encoder_config_.content_type,
920       encoder_config_.min_transmit_bitrate_bps);
921 
922   stream_resource_manager_.ConfigureQualityScaler(info);
923 }
924 
OnEncoderSettingsChanged()925 void VideoStreamEncoder::OnEncoderSettingsChanged() {
926   EncoderSettings encoder_settings(encoder_->GetEncoderInfo(),
927                                    encoder_config_.Copy(), send_codec_);
928   stream_resource_manager_.SetEncoderSettings(encoder_settings);
929   input_state_provider_.OnEncoderSettingsChanged(encoder_settings);
930   bool is_screenshare = encoder_settings.encoder_config().content_type ==
931                         VideoEncoderConfig::ContentType::kScreen;
932   degradation_preference_manager_->SetIsScreenshare(is_screenshare);
933 }
934 
OnFrame(const VideoFrame & video_frame)935 void VideoStreamEncoder::OnFrame(const VideoFrame& video_frame) {
936   RTC_DCHECK_RUNS_SERIALIZED(&incoming_frame_race_checker_);
937   VideoFrame incoming_frame = video_frame;
938 
939   // Local time in webrtc time base.
940   int64_t current_time_us = clock_->TimeInMicroseconds();
941   int64_t current_time_ms = current_time_us / rtc::kNumMicrosecsPerMillisec;
942   // In some cases, e.g., when the frame from decoder is fed to encoder,
943   // the timestamp may be set to the future. As the encoding pipeline assumes
944   // capture time to be less than present time, we should reset the capture
945   // timestamps here. Otherwise there may be issues with RTP send stream.
946   if (incoming_frame.timestamp_us() > current_time_us)
947     incoming_frame.set_timestamp_us(current_time_us);
948 
949   // Capture time may come from clock with an offset and drift from clock_.
950   int64_t capture_ntp_time_ms;
951   if (video_frame.ntp_time_ms() > 0) {
952     capture_ntp_time_ms = video_frame.ntp_time_ms();
953   } else if (video_frame.render_time_ms() != 0) {
954     capture_ntp_time_ms = video_frame.render_time_ms() + delta_ntp_internal_ms_;
955   } else {
956     capture_ntp_time_ms = current_time_ms + delta_ntp_internal_ms_;
957   }
958   incoming_frame.set_ntp_time_ms(capture_ntp_time_ms);
959 
960   // Convert NTP time, in ms, to RTP timestamp.
961   const int kMsToRtpTimestamp = 90;
962   incoming_frame.set_timestamp(
963       kMsToRtpTimestamp * static_cast<uint32_t>(incoming_frame.ntp_time_ms()));
964 
965   if (incoming_frame.ntp_time_ms() <= last_captured_timestamp_) {
966     // We don't allow the same capture time for two frames, drop this one.
967     RTC_LOG(LS_WARNING) << "Same/old NTP timestamp ("
968                         << incoming_frame.ntp_time_ms()
969                         << " <= " << last_captured_timestamp_
970                         << ") for incoming frame. Dropping.";
971     encoder_queue_.PostTask([this, incoming_frame]() {
972       RTC_DCHECK_RUN_ON(&encoder_queue_);
973       accumulated_update_rect_.Union(incoming_frame.update_rect());
974       accumulated_update_rect_is_valid_ &= incoming_frame.has_update_rect();
975     });
976     return;
977   }
978 
979   bool log_stats = false;
980   if (current_time_ms - last_frame_log_ms_ > kFrameLogIntervalMs) {
981     last_frame_log_ms_ = current_time_ms;
982     log_stats = true;
983   }
984 
985   last_captured_timestamp_ = incoming_frame.ntp_time_ms();
986 
987   int64_t post_time_us = rtc::TimeMicros();
988   ++posted_frames_waiting_for_encode_;
989 
990   encoder_queue_.PostTask(
991       [this, incoming_frame, post_time_us, log_stats]() {
992         RTC_DCHECK_RUN_ON(&encoder_queue_);
993         encoder_stats_observer_->OnIncomingFrame(incoming_frame.width(),
994                                                  incoming_frame.height());
995         ++captured_frame_count_;
996         const int posted_frames_waiting_for_encode =
997             posted_frames_waiting_for_encode_.fetch_sub(1);
998         RTC_DCHECK_GT(posted_frames_waiting_for_encode, 0);
999         CheckForAnimatedContent(incoming_frame, post_time_us);
1000         bool cwnd_frame_drop =
1001             cwnd_frame_drop_interval_ &&
1002             (cwnd_frame_counter_++ % cwnd_frame_drop_interval_.value() == 0);
1003         if (posted_frames_waiting_for_encode == 1 && !cwnd_frame_drop) {
1004           MaybeEncodeVideoFrame(incoming_frame, post_time_us);
1005         } else {
1006           if (cwnd_frame_drop) {
1007             // Frame drop by congestion window pusback. Do not encode this
1008             // frame.
1009             ++dropped_frame_cwnd_pushback_count_;
1010             encoder_stats_observer_->OnFrameDropped(
1011                 VideoStreamEncoderObserver::DropReason::kCongestionWindow);
1012           } else {
1013             // There is a newer frame in flight. Do not encode this frame.
1014             RTC_LOG(LS_VERBOSE)
1015                 << "Incoming frame dropped due to that the encoder is blocked.";
1016             ++dropped_frame_encoder_block_count_;
1017             encoder_stats_observer_->OnFrameDropped(
1018                 VideoStreamEncoderObserver::DropReason::kEncoderQueue);
1019           }
1020           accumulated_update_rect_.Union(incoming_frame.update_rect());
1021           accumulated_update_rect_is_valid_ &= incoming_frame.has_update_rect();
1022         }
1023         if (log_stats) {
1024           RTC_LOG(LS_INFO) << "Number of frames: captured "
1025                            << captured_frame_count_
1026                            << ", dropped (due to congestion window pushback) "
1027                            << dropped_frame_cwnd_pushback_count_
1028                            << ", dropped (due to encoder blocked) "
1029                            << dropped_frame_encoder_block_count_
1030                            << ", interval_ms " << kFrameLogIntervalMs;
1031           captured_frame_count_ = 0;
1032           dropped_frame_cwnd_pushback_count_ = 0;
1033           dropped_frame_encoder_block_count_ = 0;
1034         }
1035       });
1036 }
1037 
OnDiscardedFrame()1038 void VideoStreamEncoder::OnDiscardedFrame() {
1039   encoder_stats_observer_->OnFrameDropped(
1040       VideoStreamEncoderObserver::DropReason::kSource);
1041 }
1042 
EncoderPaused() const1043 bool VideoStreamEncoder::EncoderPaused() const {
1044   RTC_DCHECK_RUN_ON(&encoder_queue_);
1045   // Pause video if paused by caller or as long as the network is down or the
1046   // pacer queue has grown too large in buffered mode.
1047   // If the pacer queue has grown too large or the network is down,
1048   // |last_encoder_rate_settings_->encoder_target| will be 0.
1049   return !last_encoder_rate_settings_ ||
1050          last_encoder_rate_settings_->encoder_target == DataRate::Zero();
1051 }
1052 
TraceFrameDropStart()1053 void VideoStreamEncoder::TraceFrameDropStart() {
1054   RTC_DCHECK_RUN_ON(&encoder_queue_);
1055   // Start trace event only on the first frame after encoder is paused.
1056   if (!encoder_paused_and_dropped_frame_) {
1057     TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
1058   }
1059   encoder_paused_and_dropped_frame_ = true;
1060 }
1061 
TraceFrameDropEnd()1062 void VideoStreamEncoder::TraceFrameDropEnd() {
1063   RTC_DCHECK_RUN_ON(&encoder_queue_);
1064   // End trace event on first frame after encoder resumes, if frame was dropped.
1065   if (encoder_paused_and_dropped_frame_) {
1066     TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
1067   }
1068   encoder_paused_and_dropped_frame_ = false;
1069 }
1070 
1071 VideoStreamEncoder::EncoderRateSettings
UpdateBitrateAllocationAndNotifyObserver(const EncoderRateSettings & rate_settings)1072 VideoStreamEncoder::UpdateBitrateAllocationAndNotifyObserver(
1073     const EncoderRateSettings& rate_settings) {
1074   VideoBitrateAllocation new_allocation;
1075   // Only call allocators if bitrate > 0 (ie, not suspended), otherwise they
1076   // might cap the bitrate to the min bitrate configured.
1077   if (rate_allocator_ && rate_settings.encoder_target > DataRate::Zero()) {
1078     new_allocation = rate_allocator_->Allocate(VideoBitrateAllocationParameters(
1079         rate_settings.encoder_target, rate_settings.stable_encoder_target,
1080         rate_settings.rate_control.framerate_fps));
1081   }
1082 
1083   if (bitrate_observer_ && new_allocation.get_sum_bps() > 0) {
1084     if (encoder_ && encoder_initialized_) {
1085       // Avoid too old encoder_info_.
1086       const int64_t kMaxDiffMs = 100;
1087       const bool updated_recently =
1088           (last_encode_info_ms_ && ((clock_->TimeInMilliseconds() -
1089                                      *last_encode_info_ms_) < kMaxDiffMs));
1090       // Update allocation according to info from encoder.
1091       bitrate_observer_->OnBitrateAllocationUpdated(
1092           UpdateAllocationFromEncoderInfo(
1093               new_allocation,
1094               updated_recently ? encoder_info_ : encoder_->GetEncoderInfo()));
1095     } else {
1096       bitrate_observer_->OnBitrateAllocationUpdated(new_allocation);
1097     }
1098   }
1099 
1100   EncoderRateSettings new_rate_settings = rate_settings;
1101   new_rate_settings.rate_control.bitrate = new_allocation;
1102   // VideoBitrateAllocator subclasses may allocate a bitrate higher than the
1103   // target in order to sustain the min bitrate of the video codec. In this
1104   // case, make sure the bandwidth allocation is at least equal the allocation
1105   // as that is part of the document contract for that field.
1106   new_rate_settings.rate_control.bandwidth_allocation =
1107       std::max(new_rate_settings.rate_control.bandwidth_allocation,
1108                DataRate::BitsPerSec(
1109                    new_rate_settings.rate_control.bitrate.get_sum_bps()));
1110 
1111   if (bitrate_adjuster_) {
1112     VideoBitrateAllocation adjusted_allocation =
1113         bitrate_adjuster_->AdjustRateAllocation(new_rate_settings.rate_control);
1114     RTC_LOG(LS_VERBOSE) << "Adjusting allocation, fps = "
1115                         << rate_settings.rate_control.framerate_fps << ", from "
1116                         << new_allocation.ToString() << ", to "
1117                         << adjusted_allocation.ToString();
1118     new_rate_settings.rate_control.bitrate = adjusted_allocation;
1119   }
1120 
1121   encoder_stats_observer_->OnBitrateAllocationUpdated(
1122       send_codec_, new_rate_settings.rate_control.bitrate);
1123 
1124   return new_rate_settings;
1125 }
1126 
GetInputFramerateFps()1127 uint32_t VideoStreamEncoder::GetInputFramerateFps() {
1128   const uint32_t default_fps = max_framerate_ != -1 ? max_framerate_ : 30;
1129   absl::optional<uint32_t> input_fps =
1130       input_framerate_.Rate(clock_->TimeInMilliseconds());
1131   if (!input_fps || *input_fps == 0) {
1132     return default_fps;
1133   }
1134   return *input_fps;
1135 }
1136 
SetEncoderRates(const EncoderRateSettings & rate_settings)1137 void VideoStreamEncoder::SetEncoderRates(
1138     const EncoderRateSettings& rate_settings) {
1139   RTC_DCHECK_GT(rate_settings.rate_control.framerate_fps, 0.0);
1140   bool rate_control_changed =
1141       (!last_encoder_rate_settings_.has_value() ||
1142        last_encoder_rate_settings_->rate_control != rate_settings.rate_control);
1143   if (last_encoder_rate_settings_ != rate_settings) {
1144     last_encoder_rate_settings_ = rate_settings;
1145   }
1146 
1147   if (!encoder_) {
1148     return;
1149   }
1150 
1151   // |bitrate_allocation| is 0 it means that the network is down or the send
1152   // pacer is full. We currently only report this if the encoder has an internal
1153   // source. If the encoder does not have an internal source, higher levels
1154   // are expected to not call AddVideoFrame. We do this since its unclear
1155   // how current encoder implementations behave when given a zero target
1156   // bitrate.
1157   // TODO(perkj): Make sure all known encoder implementations handle zero
1158   // target bitrate and remove this check.
1159   if (!HasInternalSource() &&
1160       rate_settings.rate_control.bitrate.get_sum_bps() == 0) {
1161     return;
1162   }
1163 
1164   if (rate_control_changed) {
1165     encoder_->SetRates(rate_settings.rate_control);
1166     frame_encode_metadata_writer_.OnSetRates(
1167         rate_settings.rate_control.bitrate,
1168         static_cast<uint32_t>(rate_settings.rate_control.framerate_fps + 0.5));
1169     stream_resource_manager_.SetEncoderRates(rate_settings.rate_control);
1170   }
1171 }
1172 
MaybeEncodeVideoFrame(const VideoFrame & video_frame,int64_t time_when_posted_us)1173 void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame,
1174                                                int64_t time_when_posted_us) {
1175   RTC_DCHECK_RUN_ON(&encoder_queue_);
1176   input_state_provider_.OnFrameSizeObserved(video_frame.size());
1177 
1178   if (!last_frame_info_ || video_frame.width() != last_frame_info_->width ||
1179       video_frame.height() != last_frame_info_->height ||
1180       video_frame.is_texture() != last_frame_info_->is_texture) {
1181     pending_encoder_reconfiguration_ = true;
1182     last_frame_info_ = VideoFrameInfo(video_frame.width(), video_frame.height(),
1183                                       video_frame.is_texture());
1184     RTC_LOG(LS_INFO) << "Video frame parameters changed: dimensions="
1185                      << last_frame_info_->width << "x"
1186                      << last_frame_info_->height
1187                      << ", texture=" << last_frame_info_->is_texture << ".";
1188     // Force full frame update, since resolution has changed.
1189     accumulated_update_rect_ =
1190         VideoFrame::UpdateRect{0, 0, video_frame.width(), video_frame.height()};
1191   }
1192 
1193   // We have to create then encoder before the frame drop logic,
1194   // because the latter depends on encoder_->GetScalingSettings.
1195   // According to the testcase
1196   // InitialFrameDropOffWhenEncoderDisabledScaling, the return value
1197   // from GetScalingSettings should enable or disable the frame drop.
1198 
1199   // Update input frame rate before we start using it. If we update it after
1200   // any potential frame drop we are going to artificially increase frame sizes.
1201   // Poll the rate before updating, otherwise we risk the rate being estimated
1202   // a little too high at the start of the call when then window is small.
1203   uint32_t framerate_fps = GetInputFramerateFps();
1204   input_framerate_.Update(1u, clock_->TimeInMilliseconds());
1205 
1206   int64_t now_ms = clock_->TimeInMilliseconds();
1207   if (pending_encoder_reconfiguration_) {
1208     ReconfigureEncoder();
1209     last_parameters_update_ms_.emplace(now_ms);
1210   } else if (!last_parameters_update_ms_ ||
1211              now_ms - *last_parameters_update_ms_ >=
1212                  kParameterUpdateIntervalMs) {
1213     if (last_encoder_rate_settings_) {
1214       // Clone rate settings before update, so that SetEncoderRates() will
1215       // actually detect the change between the input and
1216       // |last_encoder_rate_setings_|, triggering the call to SetRate() on the
1217       // encoder.
1218       EncoderRateSettings new_rate_settings = *last_encoder_rate_settings_;
1219       new_rate_settings.rate_control.framerate_fps =
1220           static_cast<double>(framerate_fps);
1221       SetEncoderRates(
1222           UpdateBitrateAllocationAndNotifyObserver(new_rate_settings));
1223     }
1224     last_parameters_update_ms_.emplace(now_ms);
1225   }
1226 
1227   // Because pending frame will be dropped in any case, we need to
1228   // remember its updated region.
1229   if (pending_frame_) {
1230     encoder_stats_observer_->OnFrameDropped(
1231         VideoStreamEncoderObserver::DropReason::kEncoderQueue);
1232     accumulated_update_rect_.Union(pending_frame_->update_rect());
1233     accumulated_update_rect_is_valid_ &= pending_frame_->has_update_rect();
1234   }
1235 
1236   if (DropDueToSize(video_frame.size())) {
1237     RTC_LOG(LS_INFO) << "Dropping frame. Too large for target bitrate.";
1238     stream_resource_manager_.OnFrameDroppedDueToSize();
1239     // Storing references to a native buffer risks blocking frame capture.
1240     if (video_frame.video_frame_buffer()->type() !=
1241         VideoFrameBuffer::Type::kNative) {
1242       pending_frame_ = video_frame;
1243       pending_frame_post_time_us_ = time_when_posted_us;
1244     } else {
1245       // Ensure that any previously stored frame is dropped.
1246       pending_frame_.reset();
1247       accumulated_update_rect_.Union(video_frame.update_rect());
1248       accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
1249     }
1250     return;
1251   }
1252   stream_resource_manager_.OnMaybeEncodeFrame();
1253 
1254   if (EncoderPaused()) {
1255     // Storing references to a native buffer risks blocking frame capture.
1256     if (video_frame.video_frame_buffer()->type() !=
1257         VideoFrameBuffer::Type::kNative) {
1258       if (pending_frame_)
1259         TraceFrameDropStart();
1260       pending_frame_ = video_frame;
1261       pending_frame_post_time_us_ = time_when_posted_us;
1262     } else {
1263       // Ensure that any previously stored frame is dropped.
1264       pending_frame_.reset();
1265       TraceFrameDropStart();
1266       accumulated_update_rect_.Union(video_frame.update_rect());
1267       accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
1268     }
1269     return;
1270   }
1271 
1272   pending_frame_.reset();
1273 
1274   frame_dropper_.Leak(framerate_fps);
1275   // Frame dropping is enabled iff frame dropping is not force-disabled, and
1276   // rate controller is not trusted.
1277   const bool frame_dropping_enabled =
1278       !force_disable_frame_dropper_ &&
1279       !encoder_info_.has_trusted_rate_controller;
1280   frame_dropper_.Enable(frame_dropping_enabled);
1281   if (frame_dropping_enabled && frame_dropper_.DropFrame()) {
1282     RTC_LOG(LS_VERBOSE)
1283         << "Drop Frame: "
1284            "target bitrate "
1285         << (last_encoder_rate_settings_
1286                 ? last_encoder_rate_settings_->encoder_target.bps()
1287                 : 0)
1288         << ", input frame rate " << framerate_fps;
1289     OnDroppedFrame(
1290         EncodedImageCallback::DropReason::kDroppedByMediaOptimizations);
1291     accumulated_update_rect_.Union(video_frame.update_rect());
1292     accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
1293     return;
1294   }
1295 
1296   EncodeVideoFrame(video_frame, time_when_posted_us);
1297 }
1298 
EncodeVideoFrame(const VideoFrame & video_frame,int64_t time_when_posted_us)1299 void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
1300                                           int64_t time_when_posted_us) {
1301   RTC_DCHECK_RUN_ON(&encoder_queue_);
1302 
1303   // If the encoder fail we can't continue to encode frames. When this happens
1304   // the WebrtcVideoSender is notified and the whole VideoSendStream is
1305   // recreated.
1306   if (encoder_failed_)
1307     return;
1308 
1309   TraceFrameDropEnd();
1310 
1311   // Encoder metadata needs to be updated before encode complete callback.
1312   VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
1313   if (info.implementation_name != encoder_info_.implementation_name) {
1314     encoder_stats_observer_->OnEncoderImplementationChanged(
1315         info.implementation_name);
1316     if (bitrate_adjuster_) {
1317       // Encoder implementation changed, reset overshoot detector states.
1318       bitrate_adjuster_->Reset();
1319     }
1320   }
1321 
1322   if (encoder_info_ != info) {
1323     OnEncoderSettingsChanged();
1324     RTC_LOG(LS_INFO) << "Encoder settings changed from "
1325                      << encoder_info_.ToString() << " to " << info.ToString();
1326   }
1327 
1328   if (bitrate_adjuster_) {
1329     for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
1330       if (info.fps_allocation[si] != encoder_info_.fps_allocation[si]) {
1331         bitrate_adjuster_->OnEncoderInfo(info);
1332         break;
1333       }
1334     }
1335   }
1336   encoder_info_ = info;
1337   last_encode_info_ms_ = clock_->TimeInMilliseconds();
1338 
1339   VideoFrame out_frame(video_frame);
1340 
1341   const VideoFrameBuffer::Type buffer_type =
1342       out_frame.video_frame_buffer()->type();
1343   const bool is_buffer_type_supported =
1344       buffer_type == VideoFrameBuffer::Type::kI420 ||
1345       (buffer_type == VideoFrameBuffer::Type::kNative &&
1346        info.supports_native_handle);
1347 
1348   if (!is_buffer_type_supported) {
1349     // This module only supports software encoding.
1350     rtc::scoped_refptr<I420BufferInterface> converted_buffer(
1351         out_frame.video_frame_buffer()->ToI420());
1352 
1353     if (!converted_buffer) {
1354       RTC_LOG(LS_ERROR) << "Frame conversion failed, dropping frame.";
1355       return;
1356     }
1357 
1358     VideoFrame::UpdateRect update_rect = out_frame.update_rect();
1359     if (!update_rect.IsEmpty() &&
1360         out_frame.video_frame_buffer()->GetI420() == nullptr) {
1361       // UpdatedRect is reset to full update if it's not empty, and buffer was
1362       // converted, therefore we can't guarantee that pixels outside of
1363       // UpdateRect didn't change comparing to the previous frame.
1364       update_rect =
1365           VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()};
1366     }
1367 
1368     out_frame.set_video_frame_buffer(converted_buffer);
1369     out_frame.set_update_rect(update_rect);
1370   }
1371 
1372   // Crop frame if needed.
1373   if ((crop_width_ > 0 || crop_height_ > 0) &&
1374       out_frame.video_frame_buffer()->type() !=
1375           VideoFrameBuffer::Type::kNative) {
1376     // If the frame can't be converted to I420, drop it.
1377     auto i420_buffer = video_frame.video_frame_buffer()->ToI420();
1378     if (!i420_buffer) {
1379       RTC_LOG(LS_ERROR) << "Frame conversion for crop failed, dropping frame.";
1380       return;
1381     }
1382     int cropped_width = video_frame.width() - crop_width_;
1383     int cropped_height = video_frame.height() - crop_height_;
1384     rtc::scoped_refptr<I420Buffer> cropped_buffer =
1385         I420Buffer::Create(cropped_width, cropped_height);
1386     // TODO(ilnik): Remove scaling if cropping is too big, as it should never
1387     // happen after SinkWants signaled correctly from ReconfigureEncoder.
1388     VideoFrame::UpdateRect update_rect = video_frame.update_rect();
1389     if (crop_width_ < 4 && crop_height_ < 4) {
1390       cropped_buffer->CropAndScaleFrom(*i420_buffer, crop_width_ / 2,
1391                                        crop_height_ / 2, cropped_width,
1392                                        cropped_height);
1393       update_rect.offset_x -= crop_width_ / 2;
1394       update_rect.offset_y -= crop_height_ / 2;
1395       update_rect.Intersect(
1396           VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height});
1397 
1398     } else {
1399       cropped_buffer->ScaleFrom(*i420_buffer);
1400       if (!update_rect.IsEmpty()) {
1401         // Since we can't reason about pixels after scaling, we invalidate whole
1402         // picture, if anything changed.
1403         update_rect =
1404             VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height};
1405       }
1406     }
1407     out_frame.set_video_frame_buffer(cropped_buffer);
1408     out_frame.set_update_rect(update_rect);
1409     out_frame.set_ntp_time_ms(video_frame.ntp_time_ms());
1410     // Since accumulated_update_rect_ is constructed before cropping,
1411     // we can't trust it. If any changes were pending, we invalidate whole
1412     // frame here.
1413     if (!accumulated_update_rect_.IsEmpty()) {
1414       accumulated_update_rect_ =
1415           VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()};
1416       accumulated_update_rect_is_valid_ = false;
1417     }
1418   }
1419 
1420   if (!accumulated_update_rect_is_valid_) {
1421     out_frame.clear_update_rect();
1422   } else if (!accumulated_update_rect_.IsEmpty() &&
1423              out_frame.has_update_rect()) {
1424     accumulated_update_rect_.Union(out_frame.update_rect());
1425     accumulated_update_rect_.Intersect(
1426         VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()});
1427     out_frame.set_update_rect(accumulated_update_rect_);
1428     accumulated_update_rect_.MakeEmptyUpdate();
1429   }
1430   accumulated_update_rect_is_valid_ = true;
1431 
1432   TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(),
1433                           "Encode");
1434 
1435   stream_resource_manager_.OnEncodeStarted(out_frame, time_when_posted_us);
1436 
1437   RTC_DCHECK_LE(send_codec_.width, out_frame.width());
1438   RTC_DCHECK_LE(send_codec_.height, out_frame.height());
1439   // Native frames should be scaled by the client.
1440   // For internal encoders we scale everything in one place here.
1441   RTC_DCHECK((out_frame.video_frame_buffer()->type() ==
1442               VideoFrameBuffer::Type::kNative) ||
1443              (send_codec_.width == out_frame.width() &&
1444               send_codec_.height == out_frame.height()));
1445 
1446   TRACE_EVENT1("webrtc", "VCMGenericEncoder::Encode", "timestamp",
1447                out_frame.timestamp());
1448 
1449   frame_encode_metadata_writer_.OnEncodeStarted(out_frame);
1450 
1451   const int32_t encode_status = encoder_->Encode(out_frame, &next_frame_types_);
1452   was_encode_called_since_last_initialization_ = true;
1453 
1454   if (encode_status < 0) {
1455     if (encode_status == WEBRTC_VIDEO_CODEC_ENCODER_FAILURE) {
1456       RTC_LOG(LS_ERROR) << "Encoder failed, failing encoder format: "
1457                         << encoder_config_.video_format.ToString();
1458 
1459       if (settings_.encoder_switch_request_callback) {
1460         if (encoder_selector_) {
1461           if (auto encoder = encoder_selector_->OnEncoderBroken()) {
1462             settings_.encoder_switch_request_callback->RequestEncoderSwitch(
1463                 *encoder);
1464           }
1465         } else {
1466           encoder_failed_ = true;
1467           settings_.encoder_switch_request_callback->RequestEncoderFallback();
1468         }
1469       } else {
1470         RTC_LOG(LS_ERROR)
1471             << "Encoder failed but no encoder fallback callback is registered";
1472       }
1473     } else {
1474       RTC_LOG(LS_ERROR) << "Failed to encode frame. Error code: "
1475                         << encode_status;
1476     }
1477 
1478     return;
1479   }
1480 
1481   for (auto& it : next_frame_types_) {
1482     it = VideoFrameType::kVideoFrameDelta;
1483   }
1484 }
1485 
SendKeyFrame()1486 void VideoStreamEncoder::SendKeyFrame() {
1487   if (!encoder_queue_.IsCurrent()) {
1488     encoder_queue_.PostTask([this] { SendKeyFrame(); });
1489     return;
1490   }
1491   RTC_DCHECK_RUN_ON(&encoder_queue_);
1492   TRACE_EVENT0("webrtc", "OnKeyFrameRequest");
1493   RTC_DCHECK(!next_frame_types_.empty());
1494 
1495   // TODO(webrtc:10615): Map keyframe request to spatial layer.
1496   std::fill(next_frame_types_.begin(), next_frame_types_.end(),
1497             VideoFrameType::kVideoFrameKey);
1498 
1499   if (HasInternalSource()) {
1500     // Try to request the frame if we have an external encoder with
1501     // internal source since AddVideoFrame never will be called.
1502 
1503     // TODO(nisse): Used only with internal source. Delete as soon as
1504     // that feature is removed. The only implementation I've been able
1505     // to find ignores what's in the frame. With one exception: It seems
1506     // a few test cases, e.g.,
1507     // VideoSendStreamTest.VideoSendStreamStopSetEncoderRateToZero, set
1508     // internal_source to true and use FakeEncoder. And the latter will
1509     // happily encode this 1x1 frame and pass it on down the pipeline.
1510     if (encoder_->Encode(VideoFrame::Builder()
1511                              .set_video_frame_buffer(I420Buffer::Create(1, 1))
1512                              .set_rotation(kVideoRotation_0)
1513                              .set_timestamp_us(0)
1514                              .build(),
1515                          &next_frame_types_) == WEBRTC_VIDEO_CODEC_OK) {
1516       // Try to remove just-performed keyframe request, if stream still exists.
1517       std::fill(next_frame_types_.begin(), next_frame_types_.end(),
1518                 VideoFrameType::kVideoFrameDelta);
1519     }
1520   }
1521 }
1522 
OnLossNotification(const VideoEncoder::LossNotification & loss_notification)1523 void VideoStreamEncoder::OnLossNotification(
1524     const VideoEncoder::LossNotification& loss_notification) {
1525   if (!encoder_queue_.IsCurrent()) {
1526     encoder_queue_.PostTask(
1527         [this, loss_notification] { OnLossNotification(loss_notification); });
1528     return;
1529   }
1530 
1531   RTC_DCHECK_RUN_ON(&encoder_queue_);
1532   if (encoder_) {
1533     encoder_->OnLossNotification(loss_notification);
1534   }
1535 }
1536 
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info,const RTPFragmentationHeader * fragmentation)1537 EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage(
1538     const EncodedImage& encoded_image,
1539     const CodecSpecificInfo* codec_specific_info,
1540     const RTPFragmentationHeader* fragmentation) {
1541   TRACE_EVENT_INSTANT1("webrtc", "VCMEncodedFrameCallback::Encoded",
1542                        "timestamp", encoded_image.Timestamp());
1543   const size_t spatial_idx = encoded_image.SpatialIndex().value_or(0);
1544   EncodedImage image_copy(encoded_image);
1545 
1546   frame_encode_metadata_writer_.FillTimingInfo(spatial_idx, &image_copy);
1547 
1548   std::unique_ptr<RTPFragmentationHeader> fragmentation_copy =
1549       frame_encode_metadata_writer_.UpdateBitstream(codec_specific_info,
1550                                                     fragmentation, &image_copy);
1551 
1552   // Piggyback ALR experiment group id and simulcast id into the content type.
1553   const uint8_t experiment_id =
1554       experiment_groups_[videocontenttypehelpers::IsScreenshare(
1555           image_copy.content_type_)];
1556 
1557   // TODO(ilnik): This will force content type extension to be present even
1558   // for realtime video. At the expense of miniscule overhead we will get
1559   // sliced receive statistics.
1560   RTC_CHECK(videocontenttypehelpers::SetExperimentId(&image_copy.content_type_,
1561                                                      experiment_id));
1562   // We count simulcast streams from 1 on the wire. That's why we set simulcast
1563   // id in content type to +1 of that is actual simulcast index. This is because
1564   // value 0 on the wire is reserved for 'no simulcast stream specified'.
1565   RTC_CHECK(videocontenttypehelpers::SetSimulcastId(
1566       &image_copy.content_type_, static_cast<uint8_t>(spatial_idx + 1)));
1567 
1568   // Currently internal quality scaler is used for VP9 instead of webrtc qp
1569   // scaler (in no-svc case or if only a single spatial layer is encoded).
1570   // It has to be explicitly detected and reported to adaptation metrics.
1571   // Post a task because |send_codec_| requires |encoder_queue_| lock.
1572   unsigned int image_width = image_copy._encodedWidth;
1573   unsigned int image_height = image_copy._encodedHeight;
1574   VideoCodecType codec = codec_specific_info
1575                              ? codec_specific_info->codecType
1576                              : VideoCodecType::kVideoCodecGeneric;
1577   encoder_queue_.PostTask([this, codec, image_width, image_height] {
1578     RTC_DCHECK_RUN_ON(&encoder_queue_);
1579     if (codec == VideoCodecType::kVideoCodecVP9 &&
1580         send_codec_.VP9()->automaticResizeOn) {
1581       unsigned int expected_width = send_codec_.width;
1582       unsigned int expected_height = send_codec_.height;
1583       int num_active_layers = 0;
1584       for (int i = 0; i < send_codec_.VP9()->numberOfSpatialLayers; ++i) {
1585         if (send_codec_.spatialLayers[i].active) {
1586           ++num_active_layers;
1587           expected_width = send_codec_.spatialLayers[i].width;
1588           expected_height = send_codec_.spatialLayers[i].height;
1589         }
1590       }
1591       RTC_DCHECK_LE(num_active_layers, 1)
1592           << "VP9 quality scaling is enabled for "
1593              "SVC with several active layers.";
1594       encoder_stats_observer_->OnEncoderInternalScalerUpdate(
1595           image_width < expected_width || image_height < expected_height);
1596     }
1597   });
1598 
1599   // Encoded is called on whatever thread the real encoder implementation run
1600   // on. In the case of hardware encoders, there might be several encoders
1601   // running in parallel on different threads.
1602   encoder_stats_observer_->OnSendEncodedImage(image_copy, codec_specific_info);
1603 
1604   // The simulcast id is signaled in the SpatialIndex. This makes it impossible
1605   // to do simulcast for codecs that actually support spatial layers since we
1606   // can't distinguish between an actual spatial layer and a simulcast stream.
1607   // TODO(bugs.webrtc.org/10520): Signal the simulcast id explicitly.
1608   int simulcast_id = 0;
1609   if (codec_specific_info &&
1610       (codec_specific_info->codecType == kVideoCodecVP8 ||
1611        codec_specific_info->codecType == kVideoCodecH264 ||
1612        codec_specific_info->codecType == kVideoCodecGeneric)) {
1613     simulcast_id = encoded_image.SpatialIndex().value_or(0);
1614   }
1615 
1616   EncodedImageCallback::Result result = sink_->OnEncodedImage(
1617       image_copy, codec_specific_info,
1618       fragmentation_copy ? fragmentation_copy.get() : fragmentation);
1619 
1620   // We are only interested in propagating the meta-data about the image, not
1621   // encoded data itself, to the post encode function. Since we cannot be sure
1622   // the pointer will still be valid when run on the task queue, set it to null.
1623   DataSize frame_size = DataSize::Bytes(image_copy.size());
1624   image_copy.ClearEncodedData();
1625 
1626   int temporal_index = 0;
1627   if (codec_specific_info) {
1628     if (codec_specific_info->codecType == kVideoCodecVP9) {
1629       temporal_index = codec_specific_info->codecSpecific.VP9.temporal_idx;
1630     } else if (codec_specific_info->codecType == kVideoCodecVP8) {
1631       temporal_index = codec_specific_info->codecSpecific.VP8.temporalIdx;
1632     }
1633   }
1634   if (temporal_index == kNoTemporalIdx) {
1635     temporal_index = 0;
1636   }
1637 
1638   RunPostEncode(image_copy, rtc::TimeMicros(), temporal_index, frame_size);
1639 
1640   if (result.error == Result::OK) {
1641     // In case of an internal encoder running on a separate thread, the
1642     // decision to drop a frame might be a frame late and signaled via
1643     // atomic flag. This is because we can't easily wait for the worker thread
1644     // without risking deadlocks, eg during shutdown when the worker thread
1645     // might be waiting for the internal encoder threads to stop.
1646     if (pending_frame_drops_.load() > 0) {
1647       int pending_drops = pending_frame_drops_.fetch_sub(1);
1648       RTC_DCHECK_GT(pending_drops, 0);
1649       result.drop_next_frame = true;
1650     }
1651   }
1652 
1653   return result;
1654 }
1655 
OnDroppedFrame(DropReason reason)1656 void VideoStreamEncoder::OnDroppedFrame(DropReason reason) {
1657   switch (reason) {
1658     case DropReason::kDroppedByMediaOptimizations:
1659       encoder_stats_observer_->OnFrameDropped(
1660           VideoStreamEncoderObserver::DropReason::kMediaOptimization);
1661       break;
1662     case DropReason::kDroppedByEncoder:
1663       encoder_stats_observer_->OnFrameDropped(
1664           VideoStreamEncoderObserver::DropReason::kEncoder);
1665       break;
1666   }
1667   sink_->OnDroppedFrame(reason);
1668   encoder_queue_.PostTask([this, reason] {
1669     RTC_DCHECK_RUN_ON(&encoder_queue_);
1670     stream_resource_manager_.OnFrameDropped(reason);
1671   });
1672 }
1673 
UpdateTargetBitrate(DataRate target_bitrate,double cwnd_reduce_ratio)1674 DataRate VideoStreamEncoder::UpdateTargetBitrate(DataRate target_bitrate,
1675                                                  double cwnd_reduce_ratio) {
1676   RTC_DCHECK_RUN_ON(&encoder_queue_);
1677   DataRate updated_target_bitrate = target_bitrate;
1678 
1679   // Drop frames when congestion window pushback ratio is larger than 1
1680   // percent and target bitrate is larger than codec min bitrate.
1681   // When target_bitrate is 0 means codec is paused, skip frame dropping.
1682   if (cwnd_reduce_ratio > 0.01 && target_bitrate.bps() > 0 &&
1683       target_bitrate.bps() > send_codec_.minBitrate * 1000) {
1684     int reduce_bitrate_bps = std::min(
1685         static_cast<int>(target_bitrate.bps() * cwnd_reduce_ratio),
1686         static_cast<int>(target_bitrate.bps() - send_codec_.minBitrate * 1000));
1687     if (reduce_bitrate_bps > 0) {
1688       // At maximum the congestion window can drop 1/2 frames.
1689       cwnd_frame_drop_interval_ = std::max(
1690           2, static_cast<int>(target_bitrate.bps() / reduce_bitrate_bps));
1691       // Reduce target bitrate accordingly.
1692       updated_target_bitrate =
1693           target_bitrate - (target_bitrate / cwnd_frame_drop_interval_.value());
1694       return updated_target_bitrate;
1695     }
1696   }
1697   cwnd_frame_drop_interval_.reset();
1698   return updated_target_bitrate;
1699 }
1700 
OnBitrateUpdated(DataRate target_bitrate,DataRate stable_target_bitrate,DataRate link_allocation,uint8_t fraction_lost,int64_t round_trip_time_ms,double cwnd_reduce_ratio)1701 void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
1702                                           DataRate stable_target_bitrate,
1703                                           DataRate link_allocation,
1704                                           uint8_t fraction_lost,
1705                                           int64_t round_trip_time_ms,
1706                                           double cwnd_reduce_ratio) {
1707   RTC_DCHECK_GE(link_allocation, target_bitrate);
1708   if (!encoder_queue_.IsCurrent()) {
1709     encoder_queue_.PostTask([this, target_bitrate, stable_target_bitrate,
1710                              link_allocation, fraction_lost, round_trip_time_ms,
1711                              cwnd_reduce_ratio] {
1712       DataRate updated_target_bitrate =
1713           UpdateTargetBitrate(target_bitrate, cwnd_reduce_ratio);
1714       OnBitrateUpdated(updated_target_bitrate, stable_target_bitrate,
1715                        link_allocation, fraction_lost, round_trip_time_ms,
1716                        cwnd_reduce_ratio);
1717     });
1718     return;
1719   }
1720   RTC_DCHECK_RUN_ON(&encoder_queue_);
1721 
1722   const bool video_is_suspended = target_bitrate == DataRate::Zero();
1723   const bool video_suspension_changed = video_is_suspended != EncoderPaused();
1724 
1725   if (!video_is_suspended && settings_.encoder_switch_request_callback) {
1726     if (encoder_selector_) {
1727       if (auto encoder =
1728               encoder_selector_->OnAvailableBitrate(link_allocation)) {
1729         settings_.encoder_switch_request_callback->RequestEncoderSwitch(
1730             *encoder);
1731       }
1732     } else if (encoder_switch_experiment_.IsBitrateBelowThreshold(
1733                    target_bitrate) &&
1734                !encoder_switch_requested_) {
1735       EncoderSwitchRequestCallback::Config conf;
1736       conf.codec_name = encoder_switch_experiment_.to_codec;
1737       conf.param = encoder_switch_experiment_.to_param;
1738       conf.value = encoder_switch_experiment_.to_value;
1739       settings_.encoder_switch_request_callback->RequestEncoderSwitch(conf);
1740 
1741       encoder_switch_requested_ = true;
1742     }
1743   }
1744 
1745   RTC_DCHECK(sink_) << "sink_ must be set before the encoder is active.";
1746 
1747   RTC_LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate " << target_bitrate.bps()
1748                       << " stable bitrate = " << stable_target_bitrate.bps()
1749                       << " link allocation bitrate = " << link_allocation.bps()
1750                       << " packet loss " << static_cast<int>(fraction_lost)
1751                       << " rtt " << round_trip_time_ms;
1752 
1753   if (encoder_) {
1754     encoder_->OnPacketLossRateUpdate(static_cast<float>(fraction_lost) / 256.f);
1755     encoder_->OnRttUpdate(round_trip_time_ms);
1756   }
1757 
1758   uint32_t framerate_fps = GetInputFramerateFps();
1759   frame_dropper_.SetRates((target_bitrate.bps() + 500) / 1000, framerate_fps);
1760 
1761   EncoderRateSettings new_rate_settings{
1762       VideoBitrateAllocation(), static_cast<double>(framerate_fps),
1763       link_allocation, target_bitrate, stable_target_bitrate};
1764   SetEncoderRates(UpdateBitrateAllocationAndNotifyObserver(new_rate_settings));
1765 
1766   if (target_bitrate.bps() != 0)
1767     encoder_target_bitrate_bps_ = target_bitrate.bps();
1768 
1769   stream_resource_manager_.SetTargetBitrate(target_bitrate);
1770 
1771   if (video_suspension_changed) {
1772     RTC_LOG(LS_INFO) << "Video suspend state changed to: "
1773                      << (video_is_suspended ? "suspended" : "not suspended");
1774     encoder_stats_observer_->OnSuspendChange(video_is_suspended);
1775   }
1776   if (video_suspension_changed && !video_is_suspended && pending_frame_ &&
1777       !DropDueToSize(pending_frame_->size())) {
1778     int64_t pending_time_us = rtc::TimeMicros() - pending_frame_post_time_us_;
1779     if (pending_time_us < kPendingFrameTimeoutMs * 1000)
1780       EncodeVideoFrame(*pending_frame_, pending_frame_post_time_us_);
1781     pending_frame_.reset();
1782   }
1783 }
1784 
DropDueToSize(uint32_t pixel_count) const1785 bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const {
1786   bool simulcast_or_svc =
1787       (send_codec_.codecType == VideoCodecType::kVideoCodecVP9 &&
1788        send_codec_.VP9().numberOfSpatialLayers > 1) ||
1789       send_codec_.numberOfSimulcastStreams > 1 ||
1790       encoder_config_.simulcast_layers.size() > 1;
1791 
1792   if (simulcast_or_svc || !stream_resource_manager_.DropInitialFrames() ||
1793       !encoder_target_bitrate_bps_.has_value()) {
1794     return false;
1795   }
1796 
1797   absl::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
1798       encoder_->GetEncoderInfo().GetEncoderBitrateLimitsForResolution(
1799           pixel_count);
1800 
1801   if (encoder_bitrate_limits.has_value()) {
1802     // Use bitrate limits provided by encoder.
1803     return encoder_target_bitrate_bps_.value() <
1804            static_cast<uint32_t>(encoder_bitrate_limits->min_start_bitrate_bps);
1805   }
1806 
1807   if (encoder_target_bitrate_bps_.value() < 300000 /* qvga */) {
1808     return pixel_count > 320 * 240;
1809   } else if (encoder_target_bitrate_bps_.value() < 500000 /* vga */) {
1810     return pixel_count > 640 * 480;
1811   }
1812   return false;
1813 }
1814 
OnVideoSourceRestrictionsUpdated(VideoSourceRestrictions restrictions,const VideoAdaptationCounters & adaptation_counters,rtc::scoped_refptr<Resource> reason,const VideoSourceRestrictions & unfiltered_restrictions)1815 void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
1816     VideoSourceRestrictions restrictions,
1817     const VideoAdaptationCounters& adaptation_counters,
1818     rtc::scoped_refptr<Resource> reason,
1819     const VideoSourceRestrictions& unfiltered_restrictions) {
1820   RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
1821   std::string resource_name = reason ? reason->Name() : "<null>";
1822   RTC_LOG(INFO) << "Updating sink restrictions from " << resource_name << " to "
1823                 << restrictions.ToString();
1824   video_source_sink_controller_.SetRestrictions(std::move(restrictions));
1825   video_source_sink_controller_.PushSourceSinkSettings();
1826 }
1827 
RunPostEncode(const EncodedImage & encoded_image,int64_t time_sent_us,int temporal_index,DataSize frame_size)1828 void VideoStreamEncoder::RunPostEncode(const EncodedImage& encoded_image,
1829                                        int64_t time_sent_us,
1830                                        int temporal_index,
1831                                        DataSize frame_size) {
1832   if (!encoder_queue_.IsCurrent()) {
1833     encoder_queue_.PostTask([this, encoded_image, time_sent_us, temporal_index,
1834                              frame_size] {
1835       RunPostEncode(encoded_image, time_sent_us, temporal_index, frame_size);
1836     });
1837     return;
1838   }
1839 
1840   RTC_DCHECK_RUN_ON(&encoder_queue_);
1841 
1842   absl::optional<int> encode_duration_us;
1843   if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) {
1844     encode_duration_us =
1845         // TODO(nisse): Maybe use capture_time_ms_ rather than encode_start_ms_?
1846         rtc::kNumMicrosecsPerMillisec *
1847         (encoded_image.timing_.encode_finish_ms -
1848          encoded_image.timing_.encode_start_ms);
1849   }
1850 
1851   // Run post encode tasks, such as overuse detection and frame rate/drop
1852   // stats for internal encoders.
1853   const bool keyframe =
1854       encoded_image._frameType == VideoFrameType::kVideoFrameKey;
1855 
1856   if (!frame_size.IsZero()) {
1857     frame_dropper_.Fill(frame_size.bytes(), !keyframe);
1858   }
1859 
1860   if (HasInternalSource()) {
1861     // Update frame dropper after the fact for internal sources.
1862     input_framerate_.Update(1u, clock_->TimeInMilliseconds());
1863     frame_dropper_.Leak(GetInputFramerateFps());
1864     // Signal to encoder to drop next frame.
1865     if (frame_dropper_.DropFrame()) {
1866       pending_frame_drops_.fetch_add(1);
1867     }
1868   }
1869 
1870   stream_resource_manager_.OnEncodeCompleted(encoded_image, time_sent_us,
1871                                              encode_duration_us);
1872   if (bitrate_adjuster_) {
1873     bitrate_adjuster_->OnEncodedFrame(encoded_image, temporal_index);
1874   }
1875 }
1876 
HasInternalSource() const1877 bool VideoStreamEncoder::HasInternalSource() const {
1878   // TODO(sprang): Checking both info from encoder and from encoder factory
1879   // until we have deprecated and removed the encoder factory info.
1880   return codec_info_.has_internal_source || encoder_info_.has_internal_source;
1881 }
1882 
ReleaseEncoder()1883 void VideoStreamEncoder::ReleaseEncoder() {
1884   if (!encoder_ || !encoder_initialized_) {
1885     return;
1886   }
1887   encoder_->Release();
1888   encoder_initialized_ = false;
1889   TRACE_EVENT0("webrtc", "VCMGenericEncoder::Release");
1890 }
1891 
IsBitrateBelowThreshold(const DataRate & target_bitrate)1892 bool VideoStreamEncoder::EncoderSwitchExperiment::IsBitrateBelowThreshold(
1893     const DataRate& target_bitrate) {
1894   DataRate rate = DataRate::KilobitsPerSec(
1895       bitrate_filter.Apply(1.0, target_bitrate.kbps()));
1896   return current_thresholds.bitrate && rate < *current_thresholds.bitrate;
1897 }
1898 
IsPixelCountBelowThreshold(int pixel_count) const1899 bool VideoStreamEncoder::EncoderSwitchExperiment::IsPixelCountBelowThreshold(
1900     int pixel_count) const {
1901   return current_thresholds.pixel_count &&
1902          pixel_count < *current_thresholds.pixel_count;
1903 }
1904 
SetCodec(VideoCodecType codec)1905 void VideoStreamEncoder::EncoderSwitchExperiment::SetCodec(
1906     VideoCodecType codec) {
1907   auto it = codec_thresholds.find(codec);
1908   if (it == codec_thresholds.end()) {
1909     current_thresholds = {};
1910   } else {
1911     current_thresholds = it->second;
1912   }
1913 }
1914 
1915 VideoStreamEncoder::EncoderSwitchExperiment
ParseEncoderSwitchFieldTrial() const1916 VideoStreamEncoder::ParseEncoderSwitchFieldTrial() const {
1917   EncoderSwitchExperiment result;
1918 
1919   // Each "codec threshold" have the format
1920   // "<codec name>;<bitrate kbps>;<pixel count>", and are separated by the "|"
1921   // character.
1922   webrtc::FieldTrialOptional<std::string> codec_thresholds_string{
1923       "codec_thresholds"};
1924   webrtc::FieldTrialOptional<std::string> to_codec{"to_codec"};
1925   webrtc::FieldTrialOptional<std::string> to_param{"to_param"};
1926   webrtc::FieldTrialOptional<std::string> to_value{"to_value"};
1927   webrtc::FieldTrialOptional<double> window{"window"};
1928 
1929   webrtc::ParseFieldTrial(
1930       {&codec_thresholds_string, &to_codec, &to_param, &to_value, &window},
1931       webrtc::field_trial::FindFullName(
1932           "WebRTC-NetworkCondition-EncoderSwitch"));
1933 
1934   if (!codec_thresholds_string || !to_codec || !window) {
1935     return {};
1936   }
1937 
1938   result.bitrate_filter.Reset(1.0 - 1.0 / *window);
1939   result.to_codec = *to_codec;
1940   result.to_param = to_param.GetOptional();
1941   result.to_value = to_value.GetOptional();
1942 
1943   std::vector<std::string> codecs_thresholds;
1944   if (rtc::split(*codec_thresholds_string, '|', &codecs_thresholds) == 0) {
1945     return {};
1946   }
1947 
1948   for (const std::string& codec_threshold : codecs_thresholds) {
1949     std::vector<std::string> thresholds_split;
1950     if (rtc::split(codec_threshold, ';', &thresholds_split) != 3) {
1951       return {};
1952     }
1953 
1954     VideoCodecType codec = PayloadStringToCodecType(thresholds_split[0]);
1955     int bitrate_kbps;
1956     rtc::FromString(thresholds_split[1], &bitrate_kbps);
1957     int pixel_count;
1958     rtc::FromString(thresholds_split[2], &pixel_count);
1959 
1960     if (bitrate_kbps > 0) {
1961       result.codec_thresholds[codec].bitrate =
1962           DataRate::KilobitsPerSec(bitrate_kbps);
1963     }
1964 
1965     if (pixel_count > 0) {
1966       result.codec_thresholds[codec].pixel_count = pixel_count;
1967     }
1968 
1969     if (!result.codec_thresholds[codec].bitrate &&
1970         !result.codec_thresholds[codec].pixel_count) {
1971       return {};
1972     }
1973   }
1974 
1975   rtc::StringBuilder ss;
1976   ss << "Successfully parsed WebRTC-NetworkCondition-EncoderSwitch field "
1977         "trial."
1978         " to_codec:"
1979      << result.to_codec << " to_param:" << result.to_param.value_or("<none>")
1980      << " to_value:" << result.to_value.value_or("<none>")
1981      << " codec_thresholds:";
1982 
1983   for (auto kv : result.codec_thresholds) {
1984     std::string codec_name = CodecTypeToPayloadString(kv.first);
1985     std::string bitrate = kv.second.bitrate
1986                               ? std::to_string(kv.second.bitrate->kbps())
1987                               : "<none>";
1988     std::string pixels = kv.second.pixel_count
1989                              ? std::to_string(*kv.second.pixel_count)
1990                              : "<none>";
1991     ss << " (" << codec_name << ":" << bitrate << ":" << pixels << ")";
1992   }
1993 
1994   RTC_LOG(LS_INFO) << ss.str();
1995 
1996   return result;
1997 }
1998 
1999 VideoStreamEncoder::AutomaticAnimationDetectionExperiment
ParseAutomatincAnimationDetectionFieldTrial() const2000 VideoStreamEncoder::ParseAutomatincAnimationDetectionFieldTrial() const {
2001   AutomaticAnimationDetectionExperiment result;
2002 
2003   result.Parser()->Parse(webrtc::field_trial::FindFullName(
2004       "WebRTC-AutomaticAnimationDetectionScreenshare"));
2005 
2006   if (!result.enabled) {
2007     RTC_LOG(LS_INFO) << "Automatic animation detection experiment is disabled.";
2008     return result;
2009   }
2010 
2011   RTC_LOG(LS_INFO) << "Automatic animation detection experiment settings:"
2012                       " min_duration_ms="
2013                    << result.min_duration_ms
2014                    << " min_area_ration=" << result.min_area_ratio
2015                    << " min_fps=" << result.min_fps;
2016 
2017   return result;
2018 }
2019 
CheckForAnimatedContent(const VideoFrame & frame,int64_t time_when_posted_in_us)2020 void VideoStreamEncoder::CheckForAnimatedContent(
2021     const VideoFrame& frame,
2022     int64_t time_when_posted_in_us) {
2023   if (!automatic_animation_detection_experiment_.enabled ||
2024       encoder_config_.content_type !=
2025           VideoEncoderConfig::ContentType::kScreen ||
2026       stream_resource_manager_.degradation_preference() !=
2027           DegradationPreference::BALANCED) {
2028     return;
2029   }
2030 
2031   if (expect_resize_state_ == ExpectResizeState::kResize && last_frame_info_ &&
2032       last_frame_info_->width != frame.width() &&
2033       last_frame_info_->height != frame.height()) {
2034     // On applying resolution cap there will be one frame with no/different
2035     // update, which should be skipped.
2036     // It can be delayed by several frames.
2037     expect_resize_state_ = ExpectResizeState::kFirstFrameAfterResize;
2038     return;
2039   }
2040 
2041   if (expect_resize_state_ == ExpectResizeState::kFirstFrameAfterResize) {
2042     // The first frame after resize should have new, scaled update_rect.
2043     if (frame.has_update_rect()) {
2044       last_update_rect_ = frame.update_rect();
2045     } else {
2046       last_update_rect_ = absl::nullopt;
2047     }
2048     expect_resize_state_ = ExpectResizeState::kNoResize;
2049   }
2050 
2051   bool should_cap_resolution = false;
2052   if (!frame.has_update_rect()) {
2053     last_update_rect_ = absl::nullopt;
2054     animation_start_time_ = Timestamp::PlusInfinity();
2055   } else if ((!last_update_rect_ ||
2056               frame.update_rect() != *last_update_rect_)) {
2057     last_update_rect_ = frame.update_rect();
2058     animation_start_time_ = Timestamp::Micros(time_when_posted_in_us);
2059   } else {
2060     TimeDelta animation_duration =
2061         Timestamp::Micros(time_when_posted_in_us) - animation_start_time_;
2062     float area_ratio = static_cast<float>(last_update_rect_->width *
2063                                           last_update_rect_->height) /
2064                        (frame.width() * frame.height());
2065     if (animation_duration.ms() >=
2066             automatic_animation_detection_experiment_.min_duration_ms &&
2067         area_ratio >=
2068             automatic_animation_detection_experiment_.min_area_ratio &&
2069         encoder_stats_observer_->GetInputFrameRate() >=
2070             automatic_animation_detection_experiment_.min_fps) {
2071       should_cap_resolution = true;
2072     }
2073   }
2074   if (cap_resolution_due_to_video_content_ != should_cap_resolution) {
2075     expect_resize_state_ = should_cap_resolution ? ExpectResizeState::kResize
2076                                                  : ExpectResizeState::kNoResize;
2077     cap_resolution_due_to_video_content_ = should_cap_resolution;
2078     if (should_cap_resolution) {
2079       RTC_LOG(LS_INFO) << "Applying resolution cap due to animation detection.";
2080     } else {
2081       RTC_LOG(LS_INFO) << "Removing resolution cap due to no consistent "
2082                           "animation detection.";
2083     }
2084     video_source_sink_controller_.SetPixelsPerFrameUpperLimit(
2085         should_cap_resolution ? absl::optional<size_t>(kMaxAnimationPixels)
2086                               : absl::nullopt);
2087     video_source_sink_controller_.PushSourceSinkSettings();
2088   }
2089 }
InjectAdaptationResource(rtc::scoped_refptr<Resource> resource,VideoAdaptationReason reason)2090 void VideoStreamEncoder::InjectAdaptationResource(
2091     rtc::scoped_refptr<Resource> resource,
2092     VideoAdaptationReason reason) {
2093   rtc::Event map_resource_event;
2094   encoder_queue_.PostTask([this, resource, reason, &map_resource_event] {
2095     RTC_DCHECK_RUN_ON(&encoder_queue_);
2096     stream_resource_manager_.MapResourceToReason(resource, reason);
2097     resource_adaptation_processor_->AddResource(resource);
2098     map_resource_event.Set();
2099   });
2100   map_resource_event.Wait(rtc::Event::kForever);
2101 }
2102 
InjectAdaptationConstraint(AdaptationConstraint * adaptation_constraint)2103 void VideoStreamEncoder::InjectAdaptationConstraint(
2104     AdaptationConstraint* adaptation_constraint) {
2105   rtc::Event event;
2106   resource_adaptation_queue_.PostTask([this, adaptation_constraint, &event] {
2107     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
2108     if (!resource_adaptation_processor_) {
2109       // The VideoStreamEncoder was stopped and the processor destroyed before
2110       // this task had a chance to execute. No action needed.
2111       return;
2112     }
2113     adaptation_constraints_.push_back(adaptation_constraint);
2114     video_stream_adapter_->AddAdaptationConstraint(adaptation_constraint);
2115     event.Set();
2116   });
2117   event.Wait(rtc::Event::kForever);
2118 }
2119 
2120 rtc::scoped_refptr<QualityScalerResource>
quality_scaler_resource_for_testing()2121 VideoStreamEncoder::quality_scaler_resource_for_testing() {
2122   RTC_DCHECK_RUN_ON(&encoder_queue_);
2123   return stream_resource_manager_.quality_scaler_resource_for_testing();
2124 }
2125 
AddRestrictionsListenerForTesting(VideoSourceRestrictionsListener * restrictions_listener)2126 void VideoStreamEncoder::AddRestrictionsListenerForTesting(
2127     VideoSourceRestrictionsListener* restrictions_listener) {
2128   rtc::Event event;
2129   resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
2130     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
2131     RTC_DCHECK(resource_adaptation_processor_);
2132     video_stream_adapter_->AddRestrictionsListener(restrictions_listener);
2133     event.Set();
2134   });
2135   event.Wait(rtc::Event::kForever);
2136 }
2137 
RemoveRestrictionsListenerForTesting(VideoSourceRestrictionsListener * restrictions_listener)2138 void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
2139     VideoSourceRestrictionsListener* restrictions_listener) {
2140   rtc::Event event;
2141   resource_adaptation_queue_.PostTask([this, restrictions_listener, &event] {
2142     RTC_DCHECK_RUN_ON(&resource_adaptation_queue_);
2143     RTC_DCHECK(resource_adaptation_processor_);
2144     video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener);
2145     event.Set();
2146   });
2147   event.Wait(rtc::Event::kForever);
2148 }
2149 
2150 }  // namespace webrtc
2151