• 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/cleanup/cleanup.h"
22 #include "absl/types/optional.h"
23 #include "api/field_trials_view.h"
24 #include "api/sequence_checker.h"
25 #include "api/task_queue/task_queue_base.h"
26 #include "api/video/encoded_image.h"
27 #include "api/video/i420_buffer.h"
28 #include "api/video/render_resolution.h"
29 #include "api/video/video_adaptation_reason.h"
30 #include "api/video/video_bitrate_allocator_factory.h"
31 #include "api/video/video_codec_constants.h"
32 #include "api/video/video_layers_allocation.h"
33 #include "api/video_codecs/sdp_video_format.h"
34 #include "api/video_codecs/video_encoder.h"
35 #include "call/adaptation/resource_adaptation_processor.h"
36 #include "call/adaptation/video_source_restrictions.h"
37 #include "call/adaptation/video_stream_adapter.h"
38 #include "media/base/media_channel.h"
39 #include "modules/video_coding/include/video_codec_initializer.h"
40 #include "modules/video_coding/svc/svc_rate_allocator.h"
41 #include "modules/video_coding/utility/vp8_constants.h"
42 #include "rtc_base/arraysize.h"
43 #include "rtc_base/checks.h"
44 #include "rtc_base/event.h"
45 #include "rtc_base/experiments/alr_experiment.h"
46 #include "rtc_base/experiments/encoder_info_settings.h"
47 #include "rtc_base/experiments/rate_control_settings.h"
48 #include "rtc_base/logging.h"
49 #include "rtc_base/strings/string_builder.h"
50 #include "rtc_base/system/no_unique_address.h"
51 #include "rtc_base/thread_annotations.h"
52 #include "rtc_base/trace_event.h"
53 #include "system_wrappers/include/metrics.h"
54 #include "video/adaptation/video_stream_encoder_resource_manager.h"
55 #include "video/alignment_adjuster.h"
56 #include "video/config/encoder_stream_factory.h"
57 #include "video/frame_cadence_adapter.h"
58 
59 namespace webrtc {
60 
61 namespace {
62 
63 // Time interval for logging frame counts.
64 const int64_t kFrameLogIntervalMs = 60000;
65 
66 // Time to keep a single cached pending frame in paused state.
67 const int64_t kPendingFrameTimeoutMs = 1000;
68 
69 constexpr char kFrameDropperFieldTrial[] = "WebRTC-FrameDropper";
70 
71 // TODO(bugs.webrtc.org/13572): Remove this kill switch after deploying the
72 // feature.
73 constexpr char kSwitchEncoderOnInitializationFailuresFieldTrial[] =
74     "WebRTC-SwitchEncoderOnInitializationFailures";
75 
76 const size_t kDefaultPayloadSize = 1440;
77 
78 const int64_t kParameterUpdateIntervalMs = 1000;
79 
80 // Animation is capped to 720p.
81 constexpr int kMaxAnimationPixels = 1280 * 720;
82 
83 constexpr int kDefaultMinScreenSharebps = 1200000;
84 
RequiresEncoderReset(const VideoCodec & prev_send_codec,const VideoCodec & new_send_codec,bool was_encode_called_since_last_initialization)85 bool RequiresEncoderReset(const VideoCodec& prev_send_codec,
86                           const VideoCodec& new_send_codec,
87                           bool was_encode_called_since_last_initialization) {
88   // Does not check max/minBitrate or maxFramerate.
89   if (new_send_codec.codecType != prev_send_codec.codecType ||
90       new_send_codec.width != prev_send_codec.width ||
91       new_send_codec.height != prev_send_codec.height ||
92       new_send_codec.qpMax != prev_send_codec.qpMax ||
93       new_send_codec.numberOfSimulcastStreams !=
94           prev_send_codec.numberOfSimulcastStreams ||
95       new_send_codec.mode != prev_send_codec.mode ||
96       new_send_codec.GetFrameDropEnabled() !=
97           prev_send_codec.GetFrameDropEnabled()) {
98     return true;
99   }
100 
101   if (!was_encode_called_since_last_initialization &&
102       (new_send_codec.startBitrate != prev_send_codec.startBitrate)) {
103     // If start bitrate has changed reconfigure encoder only if encoding had not
104     // yet started.
105     return true;
106   }
107 
108   switch (new_send_codec.codecType) {
109     case kVideoCodecVP8:
110       if (new_send_codec.VP8() != prev_send_codec.VP8()) {
111         return true;
112       }
113       break;
114 
115     case kVideoCodecVP9:
116       if (new_send_codec.VP9() != prev_send_codec.VP9()) {
117         return true;
118       }
119       break;
120 
121     case kVideoCodecH264:
122       if (new_send_codec.H264() != prev_send_codec.H264()) {
123         return true;
124       }
125       break;
126 
127     default:
128       break;
129   }
130 
131   for (unsigned char i = 0; i < new_send_codec.numberOfSimulcastStreams; ++i) {
132     if (!new_send_codec.simulcastStream[i].active) {
133       // No need to reset when stream is inactive.
134       continue;
135     }
136 
137     if (!prev_send_codec.simulcastStream[i].active ||
138         new_send_codec.simulcastStream[i].width !=
139             prev_send_codec.simulcastStream[i].width ||
140         new_send_codec.simulcastStream[i].height !=
141             prev_send_codec.simulcastStream[i].height ||
142         new_send_codec.simulcastStream[i].numberOfTemporalLayers !=
143             prev_send_codec.simulcastStream[i].numberOfTemporalLayers ||
144         new_send_codec.simulcastStream[i].qpMax !=
145             prev_send_codec.simulcastStream[i].qpMax) {
146       return true;
147     }
148   }
149 
150   if (new_send_codec.codecType == kVideoCodecVP9) {
151     size_t num_spatial_layers = new_send_codec.VP9().numberOfSpatialLayers;
152     for (unsigned char i = 0; i < num_spatial_layers; ++i) {
153       if (new_send_codec.spatialLayers[i].width !=
154               prev_send_codec.spatialLayers[i].width ||
155           new_send_codec.spatialLayers[i].height !=
156               prev_send_codec.spatialLayers[i].height ||
157           new_send_codec.spatialLayers[i].numberOfTemporalLayers !=
158               prev_send_codec.spatialLayers[i].numberOfTemporalLayers ||
159           new_send_codec.spatialLayers[i].qpMax !=
160               prev_send_codec.spatialLayers[i].qpMax) {
161         return true;
162       }
163     }
164   }
165 
166   if (new_send_codec.GetScalabilityMode() !=
167       prev_send_codec.GetScalabilityMode()) {
168     return true;
169   }
170 
171   return false;
172 }
173 
GetExperimentGroups()174 std::array<uint8_t, 2> GetExperimentGroups() {
175   std::array<uint8_t, 2> experiment_groups;
176   absl::optional<AlrExperimentSettings> experiment_settings =
177       AlrExperimentSettings::CreateFromFieldTrial(
178           AlrExperimentSettings::kStrictPacingAndProbingExperimentName);
179   if (experiment_settings) {
180     experiment_groups[0] = experiment_settings->group_id + 1;
181   } else {
182     experiment_groups[0] = 0;
183   }
184   experiment_settings = AlrExperimentSettings::CreateFromFieldTrial(
185       AlrExperimentSettings::kScreenshareProbingBweExperimentName);
186   if (experiment_settings) {
187     experiment_groups[1] = experiment_settings->group_id + 1;
188   } else {
189     experiment_groups[1] = 0;
190   }
191   return experiment_groups;
192 }
193 
194 // Limit allocation across TLs in bitrate allocation according to number of TLs
195 // in EncoderInfo.
UpdateAllocationFromEncoderInfo(const VideoBitrateAllocation & allocation,const VideoEncoder::EncoderInfo & encoder_info)196 VideoBitrateAllocation UpdateAllocationFromEncoderInfo(
197     const VideoBitrateAllocation& allocation,
198     const VideoEncoder::EncoderInfo& encoder_info) {
199   if (allocation.get_sum_bps() == 0) {
200     return allocation;
201   }
202   VideoBitrateAllocation new_allocation;
203   for (int si = 0; si < kMaxSpatialLayers; ++si) {
204     if (encoder_info.fps_allocation[si].size() == 1 &&
205         allocation.IsSpatialLayerUsed(si)) {
206       // One TL is signalled to be used by the encoder. Do not distribute
207       // bitrate allocation across TLs (use sum at ti:0).
208       new_allocation.SetBitrate(si, 0, allocation.GetSpatialLayerSum(si));
209     } else {
210       for (int ti = 0; ti < kMaxTemporalStreams; ++ti) {
211         if (allocation.HasBitrate(si, ti))
212           new_allocation.SetBitrate(si, ti, allocation.GetBitrate(si, ti));
213       }
214     }
215   }
216   new_allocation.set_bw_limited(allocation.is_bw_limited());
217   return new_allocation;
218 }
219 
220 // Converts a VideoBitrateAllocation that contains allocated bitrate per layer,
221 // and an EncoderInfo that contains information about the actual encoder
222 // structure used by a codec. Stream structures can be Ksvc, Full SVC, Simulcast
223 // etc.
CreateVideoLayersAllocation(const VideoCodec & encoder_config,const VideoEncoder::RateControlParameters & current_rate,const VideoEncoder::EncoderInfo & encoder_info)224 VideoLayersAllocation CreateVideoLayersAllocation(
225     const VideoCodec& encoder_config,
226     const VideoEncoder::RateControlParameters& current_rate,
227     const VideoEncoder::EncoderInfo& encoder_info) {
228   const VideoBitrateAllocation& target_bitrate = current_rate.target_bitrate;
229   VideoLayersAllocation layers_allocation;
230   if (target_bitrate.get_sum_bps() == 0) {
231     return layers_allocation;
232   }
233 
234   if (encoder_config.numberOfSimulcastStreams > 1) {
235     layers_allocation.resolution_and_frame_rate_is_valid = true;
236     for (int si = 0; si < encoder_config.numberOfSimulcastStreams; ++si) {
237       if (!target_bitrate.IsSpatialLayerUsed(si) ||
238           target_bitrate.GetSpatialLayerSum(si) == 0) {
239         continue;
240       }
241       layers_allocation.active_spatial_layers.emplace_back();
242       VideoLayersAllocation::SpatialLayer& spatial_layer =
243           layers_allocation.active_spatial_layers.back();
244       spatial_layer.width = encoder_config.simulcastStream[si].width;
245       spatial_layer.height = encoder_config.simulcastStream[si].height;
246       spatial_layer.rtp_stream_index = si;
247       spatial_layer.spatial_id = 0;
248       auto frame_rate_fraction =
249           VideoEncoder::EncoderInfo::kMaxFramerateFraction;
250       if (encoder_info.fps_allocation[si].size() == 1) {
251         // One TL is signalled to be used by the encoder. Do not distribute
252         // bitrate allocation across TLs (use sum at tl:0).
253         spatial_layer.target_bitrate_per_temporal_layer.push_back(
254             DataRate::BitsPerSec(target_bitrate.GetSpatialLayerSum(si)));
255         frame_rate_fraction = encoder_info.fps_allocation[si][0];
256       } else {  // Temporal layers are supported.
257         uint32_t temporal_layer_bitrate_bps = 0;
258         for (size_t ti = 0;
259              ti < encoder_config.simulcastStream[si].numberOfTemporalLayers;
260              ++ti) {
261           if (!target_bitrate.HasBitrate(si, ti)) {
262             break;
263           }
264           if (ti < encoder_info.fps_allocation[si].size()) {
265             // Use frame rate of the top used temporal layer.
266             frame_rate_fraction = encoder_info.fps_allocation[si][ti];
267           }
268           temporal_layer_bitrate_bps += target_bitrate.GetBitrate(si, ti);
269           spatial_layer.target_bitrate_per_temporal_layer.push_back(
270               DataRate::BitsPerSec(temporal_layer_bitrate_bps));
271         }
272       }
273       // Encoder may drop frames internally if `maxFramerate` is set.
274       spatial_layer.frame_rate_fps = std::min<uint8_t>(
275           encoder_config.simulcastStream[si].maxFramerate,
276           rtc::saturated_cast<uint8_t>(
277               (current_rate.framerate_fps * frame_rate_fraction) /
278               VideoEncoder::EncoderInfo::kMaxFramerateFraction));
279     }
280   } else if (encoder_config.numberOfSimulcastStreams == 1) {
281     // TODO(bugs.webrtc.org/12000): Implement support for AV1 with
282     // scalability.
283     const bool higher_spatial_depend_on_lower =
284         encoder_config.codecType == kVideoCodecVP9 &&
285         encoder_config.VP9().interLayerPred == InterLayerPredMode::kOn;
286     layers_allocation.resolution_and_frame_rate_is_valid = true;
287 
288     std::vector<DataRate> aggregated_spatial_bitrate(
289         webrtc::kMaxTemporalStreams, DataRate::Zero());
290     for (int si = 0; si < webrtc::kMaxSpatialLayers; ++si) {
291       layers_allocation.resolution_and_frame_rate_is_valid = true;
292       if (!target_bitrate.IsSpatialLayerUsed(si) ||
293           target_bitrate.GetSpatialLayerSum(si) == 0) {
294         break;
295       }
296       layers_allocation.active_spatial_layers.emplace_back();
297       VideoLayersAllocation::SpatialLayer& spatial_layer =
298           layers_allocation.active_spatial_layers.back();
299       spatial_layer.width = encoder_config.spatialLayers[si].width;
300       spatial_layer.height = encoder_config.spatialLayers[si].height;
301       spatial_layer.rtp_stream_index = 0;
302       spatial_layer.spatial_id = si;
303       auto frame_rate_fraction =
304           VideoEncoder::EncoderInfo::kMaxFramerateFraction;
305       if (encoder_info.fps_allocation[si].size() == 1) {
306         // One TL is signalled to be used by the encoder. Do not distribute
307         // bitrate allocation across TLs (use sum at tl:0).
308         DataRate aggregated_temporal_bitrate =
309             DataRate::BitsPerSec(target_bitrate.GetSpatialLayerSum(si));
310         aggregated_spatial_bitrate[0] += aggregated_temporal_bitrate;
311         if (higher_spatial_depend_on_lower) {
312           spatial_layer.target_bitrate_per_temporal_layer.push_back(
313               aggregated_spatial_bitrate[0]);
314         } else {
315           spatial_layer.target_bitrate_per_temporal_layer.push_back(
316               aggregated_temporal_bitrate);
317         }
318         frame_rate_fraction = encoder_info.fps_allocation[si][0];
319       } else {  // Temporal layers are supported.
320         DataRate aggregated_temporal_bitrate = DataRate::Zero();
321         for (size_t ti = 0;
322              ti < encoder_config.spatialLayers[si].numberOfTemporalLayers;
323              ++ti) {
324           if (!target_bitrate.HasBitrate(si, ti)) {
325             break;
326           }
327           if (ti < encoder_info.fps_allocation[si].size()) {
328             // Use frame rate of the top used temporal layer.
329             frame_rate_fraction = encoder_info.fps_allocation[si][ti];
330           }
331           aggregated_temporal_bitrate +=
332               DataRate::BitsPerSec(target_bitrate.GetBitrate(si, ti));
333           if (higher_spatial_depend_on_lower) {
334             spatial_layer.target_bitrate_per_temporal_layer.push_back(
335                 aggregated_temporal_bitrate + aggregated_spatial_bitrate[ti]);
336             aggregated_spatial_bitrate[ti] += aggregated_temporal_bitrate;
337           } else {
338             spatial_layer.target_bitrate_per_temporal_layer.push_back(
339                 aggregated_temporal_bitrate);
340           }
341         }
342       }
343       // Encoder may drop frames internally if `maxFramerate` is set.
344       spatial_layer.frame_rate_fps = std::min<uint8_t>(
345           encoder_config.spatialLayers[si].maxFramerate,
346           rtc::saturated_cast<uint8_t>(
347               (current_rate.framerate_fps * frame_rate_fraction) /
348               VideoEncoder::EncoderInfo::kMaxFramerateFraction));
349     }
350   }
351 
352   return layers_allocation;
353 }
354 
GetEncoderInfoWithBitrateLimitUpdate(const VideoEncoder::EncoderInfo & info,const VideoEncoderConfig & encoder_config,bool default_limits_allowed)355 VideoEncoder::EncoderInfo GetEncoderInfoWithBitrateLimitUpdate(
356     const VideoEncoder::EncoderInfo& info,
357     const VideoEncoderConfig& encoder_config,
358     bool default_limits_allowed) {
359   if (!default_limits_allowed || !info.resolution_bitrate_limits.empty() ||
360       encoder_config.simulcast_layers.size() <= 1) {
361     return info;
362   }
363   // Bitrate limits are not configured and more than one layer is used, use
364   // the default limits (bitrate limits are not used for simulcast).
365   VideoEncoder::EncoderInfo new_info = info;
366   new_info.resolution_bitrate_limits =
367       EncoderInfoSettings::GetDefaultSinglecastBitrateLimits(
368           encoder_config.codec_type);
369   return new_info;
370 }
371 
NumActiveStreams(const std::vector<VideoStream> & streams)372 int NumActiveStreams(const std::vector<VideoStream>& streams) {
373   int num_active = 0;
374   for (const auto& stream : streams) {
375     if (stream.active)
376       ++num_active;
377   }
378   return num_active;
379 }
380 
ApplyVp9BitrateLimits(const VideoEncoder::EncoderInfo & encoder_info,const VideoEncoderConfig & encoder_config,VideoCodec * codec)381 void ApplyVp9BitrateLimits(const VideoEncoder::EncoderInfo& encoder_info,
382                            const VideoEncoderConfig& encoder_config,
383                            VideoCodec* codec) {
384   if (codec->codecType != VideoCodecType::kVideoCodecVP9 ||
385       encoder_config.simulcast_layers.size() <= 1 ||
386       VideoStreamEncoderResourceManager::IsSimulcastOrMultipleSpatialLayers(
387           encoder_config)) {
388     // Resolution bitrate limits usage is restricted to singlecast.
389     return;
390   }
391 
392   // Get bitrate limits for active stream.
393   absl::optional<uint32_t> pixels =
394       VideoStreamAdapter::GetSingleActiveLayerPixels(*codec);
395   if (!pixels.has_value()) {
396     return;
397   }
398   absl::optional<VideoEncoder::ResolutionBitrateLimits> bitrate_limits =
399       encoder_info.GetEncoderBitrateLimitsForResolution(*pixels);
400   if (!bitrate_limits.has_value()) {
401     return;
402   }
403 
404   // Index for the active stream.
405   absl::optional<size_t> index;
406   for (size_t i = 0; i < encoder_config.simulcast_layers.size(); ++i) {
407     if (encoder_config.simulcast_layers[i].active)
408       index = i;
409   }
410   if (!index.has_value()) {
411     return;
412   }
413 
414   int min_bitrate_bps;
415   if (encoder_config.simulcast_layers[*index].min_bitrate_bps <= 0) {
416     min_bitrate_bps = bitrate_limits->min_bitrate_bps;
417   } else {
418     min_bitrate_bps =
419         std::max(bitrate_limits->min_bitrate_bps,
420                  encoder_config.simulcast_layers[*index].min_bitrate_bps);
421   }
422   int max_bitrate_bps;
423   if (encoder_config.simulcast_layers[*index].max_bitrate_bps <= 0) {
424     max_bitrate_bps = bitrate_limits->max_bitrate_bps;
425   } else {
426     max_bitrate_bps =
427         std::min(bitrate_limits->max_bitrate_bps,
428                  encoder_config.simulcast_layers[*index].max_bitrate_bps);
429   }
430   if (min_bitrate_bps >= max_bitrate_bps) {
431     RTC_LOG(LS_WARNING) << "Bitrate limits not used, min_bitrate_bps "
432                         << min_bitrate_bps << " >= max_bitrate_bps "
433                         << max_bitrate_bps;
434     return;
435   }
436 
437   for (int i = 0; i < codec->VP9()->numberOfSpatialLayers; ++i) {
438     if (codec->spatialLayers[i].active) {
439       codec->spatialLayers[i].minBitrate = min_bitrate_bps / 1000;
440       codec->spatialLayers[i].maxBitrate = max_bitrate_bps / 1000;
441       codec->spatialLayers[i].targetBitrate =
442           std::min(codec->spatialLayers[i].targetBitrate,
443                    codec->spatialLayers[i].maxBitrate);
444       break;
445     }
446   }
447 }
448 
ApplyEncoderBitrateLimitsIfSingleActiveStream(const VideoEncoder::EncoderInfo & encoder_info,const std::vector<VideoStream> & encoder_config_layers,std::vector<VideoStream> * streams)449 void ApplyEncoderBitrateLimitsIfSingleActiveStream(
450     const VideoEncoder::EncoderInfo& encoder_info,
451     const std::vector<VideoStream>& encoder_config_layers,
452     std::vector<VideoStream>* streams) {
453   // Apply limits if simulcast with one active stream (expect lowest).
454   bool single_active_stream =
455       streams->size() > 1 && NumActiveStreams(*streams) == 1 &&
456       !streams->front().active && NumActiveStreams(encoder_config_layers) == 1;
457   if (!single_active_stream) {
458     return;
459   }
460 
461   // Index for the active stream.
462   size_t index = 0;
463   for (size_t i = 0; i < encoder_config_layers.size(); ++i) {
464     if (encoder_config_layers[i].active)
465       index = i;
466   }
467   if (streams->size() < (index + 1) || !(*streams)[index].active) {
468     return;
469   }
470 
471   // Get bitrate limits for active stream.
472   absl::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
473       encoder_info.GetEncoderBitrateLimitsForResolution(
474           (*streams)[index].width * (*streams)[index].height);
475   if (!encoder_bitrate_limits) {
476     return;
477   }
478 
479   // If bitrate limits are set by RtpEncodingParameters, use intersection.
480   int min_bitrate_bps;
481   if (encoder_config_layers[index].min_bitrate_bps <= 0) {
482     min_bitrate_bps = encoder_bitrate_limits->min_bitrate_bps;
483   } else {
484     min_bitrate_bps = std::max(encoder_bitrate_limits->min_bitrate_bps,
485                                (*streams)[index].min_bitrate_bps);
486   }
487   int max_bitrate_bps;
488   if (encoder_config_layers[index].max_bitrate_bps <= 0) {
489     max_bitrate_bps = encoder_bitrate_limits->max_bitrate_bps;
490   } else {
491     max_bitrate_bps = std::min(encoder_bitrate_limits->max_bitrate_bps,
492                                (*streams)[index].max_bitrate_bps);
493   }
494   if (min_bitrate_bps >= max_bitrate_bps) {
495     RTC_LOG(LS_WARNING) << "Encoder bitrate limits"
496                         << " (min=" << encoder_bitrate_limits->min_bitrate_bps
497                         << ", max=" << encoder_bitrate_limits->max_bitrate_bps
498                         << ") do not intersect with stream limits"
499                         << " (min=" << (*streams)[index].min_bitrate_bps
500                         << ", max=" << (*streams)[index].max_bitrate_bps
501                         << "). Encoder bitrate limits not used.";
502     return;
503   }
504 
505   (*streams)[index].min_bitrate_bps = min_bitrate_bps;
506   (*streams)[index].max_bitrate_bps = max_bitrate_bps;
507   (*streams)[index].target_bitrate_bps =
508       std::min((*streams)[index].target_bitrate_bps,
509                encoder_bitrate_limits->max_bitrate_bps);
510 }
511 
ParseVp9LowTierCoreCountThreshold(const FieldTrialsView & trials)512 absl::optional<int> ParseVp9LowTierCoreCountThreshold(
513     const FieldTrialsView& trials) {
514   FieldTrialFlag disable_low_tier("Disabled");
515   FieldTrialParameter<int> max_core_count("max_core_count", 2);
516   ParseFieldTrial({&disable_low_tier, &max_core_count},
517                   trials.Lookup("WebRTC-VP9-LowTierOptimizations"));
518   if (disable_low_tier.Get()) {
519     return absl::nullopt;
520   }
521   return max_core_count.Get();
522 }
523 
MergeRestrictions(const std::vector<absl::optional<VideoSourceRestrictions>> & list)524 absl::optional<VideoSourceRestrictions> MergeRestrictions(
525     const std::vector<absl::optional<VideoSourceRestrictions>>& list) {
526   absl::optional<VideoSourceRestrictions> return_value;
527   for (const auto& res : list) {
528     if (!res) {
529       continue;
530     }
531     if (!return_value) {
532       return_value = *res;
533       continue;
534     }
535     return_value->UpdateMin(*res);
536   }
537   return return_value;
538 }
539 
540 }  //  namespace
541 
EncoderRateSettings()542 VideoStreamEncoder::EncoderRateSettings::EncoderRateSettings()
543     : rate_control(),
544       encoder_target(DataRate::Zero()),
545       stable_encoder_target(DataRate::Zero()) {}
546 
EncoderRateSettings(const VideoBitrateAllocation & bitrate,double framerate_fps,DataRate bandwidth_allocation,DataRate encoder_target,DataRate stable_encoder_target)547 VideoStreamEncoder::EncoderRateSettings::EncoderRateSettings(
548     const VideoBitrateAllocation& bitrate,
549     double framerate_fps,
550     DataRate bandwidth_allocation,
551     DataRate encoder_target,
552     DataRate stable_encoder_target)
553     : rate_control(bitrate, framerate_fps, bandwidth_allocation),
554       encoder_target(encoder_target),
555       stable_encoder_target(stable_encoder_target) {}
556 
operator ==(const EncoderRateSettings & rhs) const557 bool VideoStreamEncoder::EncoderRateSettings::operator==(
558     const EncoderRateSettings& rhs) const {
559   return rate_control == rhs.rate_control &&
560          encoder_target == rhs.encoder_target &&
561          stable_encoder_target == rhs.stable_encoder_target;
562 }
563 
operator !=(const EncoderRateSettings & rhs) const564 bool VideoStreamEncoder::EncoderRateSettings::operator!=(
565     const EncoderRateSettings& rhs) const {
566   return !(*this == rhs);
567 }
568 
569 class VideoStreamEncoder::DegradationPreferenceManager
570     : public DegradationPreferenceProvider {
571  public:
DegradationPreferenceManager(VideoStreamAdapter * video_stream_adapter)572   explicit DegradationPreferenceManager(
573       VideoStreamAdapter* video_stream_adapter)
574       : degradation_preference_(DegradationPreference::DISABLED),
575         is_screenshare_(false),
576         effective_degradation_preference_(DegradationPreference::DISABLED),
577         video_stream_adapter_(video_stream_adapter) {
578     RTC_DCHECK(video_stream_adapter_);
579     sequence_checker_.Detach();
580   }
581 
582   ~DegradationPreferenceManager() override = default;
583 
degradation_preference() const584   DegradationPreference degradation_preference() const override {
585     RTC_DCHECK_RUN_ON(&sequence_checker_);
586     return effective_degradation_preference_;
587   }
588 
SetDegradationPreference(DegradationPreference degradation_preference)589   void SetDegradationPreference(DegradationPreference degradation_preference) {
590     RTC_DCHECK_RUN_ON(&sequence_checker_);
591     degradation_preference_ = degradation_preference;
592     MaybeUpdateEffectiveDegradationPreference();
593   }
594 
SetIsScreenshare(bool is_screenshare)595   void SetIsScreenshare(bool is_screenshare) {
596     RTC_DCHECK_RUN_ON(&sequence_checker_);
597     is_screenshare_ = is_screenshare;
598     MaybeUpdateEffectiveDegradationPreference();
599   }
600 
601  private:
MaybeUpdateEffectiveDegradationPreference()602   void MaybeUpdateEffectiveDegradationPreference()
603       RTC_RUN_ON(&sequence_checker_) {
604     DegradationPreference effective_degradation_preference =
605         (is_screenshare_ &&
606          degradation_preference_ == DegradationPreference::BALANCED)
607             ? DegradationPreference::MAINTAIN_RESOLUTION
608             : degradation_preference_;
609 
610     if (effective_degradation_preference != effective_degradation_preference_) {
611       effective_degradation_preference_ = effective_degradation_preference;
612       video_stream_adapter_->SetDegradationPreference(
613           effective_degradation_preference);
614     }
615   }
616 
617   RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
618   DegradationPreference degradation_preference_
619       RTC_GUARDED_BY(&sequence_checker_);
620   bool is_screenshare_ RTC_GUARDED_BY(&sequence_checker_);
621   DegradationPreference effective_degradation_preference_
622       RTC_GUARDED_BY(&sequence_checker_);
623   VideoStreamAdapter* video_stream_adapter_ RTC_GUARDED_BY(&sequence_checker_);
624 };
625 
VideoStreamEncoder(Clock * clock,uint32_t number_of_cores,VideoStreamEncoderObserver * encoder_stats_observer,const VideoStreamEncoderSettings & settings,std::unique_ptr<OveruseFrameDetector> overuse_detector,std::unique_ptr<FrameCadenceAdapterInterface> frame_cadence_adapter,std::unique_ptr<webrtc::TaskQueueBase,webrtc::TaskQueueDeleter> encoder_queue,BitrateAllocationCallbackType allocation_cb_type,const FieldTrialsView & field_trials,webrtc::VideoEncoderFactory::EncoderSelectorInterface * encoder_selector)626 VideoStreamEncoder::VideoStreamEncoder(
627     Clock* clock,
628     uint32_t number_of_cores,
629     VideoStreamEncoderObserver* encoder_stats_observer,
630     const VideoStreamEncoderSettings& settings,
631     std::unique_ptr<OveruseFrameDetector> overuse_detector,
632     std::unique_ptr<FrameCadenceAdapterInterface> frame_cadence_adapter,
633     std::unique_ptr<webrtc::TaskQueueBase, webrtc::TaskQueueDeleter>
634         encoder_queue,
635     BitrateAllocationCallbackType allocation_cb_type,
636     const FieldTrialsView& field_trials,
637     webrtc::VideoEncoderFactory::EncoderSelectorInterface* encoder_selector)
638     : field_trials_(field_trials),
639       worker_queue_(TaskQueueBase::Current()),
640       number_of_cores_(number_of_cores),
641       sink_(nullptr),
642       settings_(settings),
643       allocation_cb_type_(allocation_cb_type),
644       rate_control_settings_(RateControlSettings::ParseFromFieldTrials()),
645       encoder_selector_from_constructor_(encoder_selector),
646       encoder_selector_from_factory_(
647           encoder_selector_from_constructor_
648               ? nullptr
649               : settings.encoder_factory->GetEncoderSelector()),
650       encoder_selector_(encoder_selector_from_constructor_
651                             ? encoder_selector_from_constructor_
652                             : encoder_selector_from_factory_.get()),
653       encoder_stats_observer_(encoder_stats_observer),
654       cadence_callback_(*this),
655       frame_cadence_adapter_(std::move(frame_cadence_adapter)),
656       encoder_initialized_(false),
657       max_framerate_(-1),
658       pending_encoder_reconfiguration_(false),
659       pending_encoder_creation_(false),
660       crop_width_(0),
661       crop_height_(0),
662       encoder_target_bitrate_bps_(absl::nullopt),
663       max_data_payload_length_(0),
664       encoder_paused_and_dropped_frame_(false),
665       was_encode_called_since_last_initialization_(false),
666       encoder_failed_(false),
667       clock_(clock),
668       last_captured_timestamp_(0),
669       delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() -
670                              clock_->TimeInMilliseconds()),
671       last_frame_log_ms_(clock_->TimeInMilliseconds()),
672       captured_frame_count_(0),
673       dropped_frame_cwnd_pushback_count_(0),
674       dropped_frame_encoder_block_count_(0),
675       pending_frame_post_time_us_(0),
676       accumulated_update_rect_{0, 0, 0, 0},
677       accumulated_update_rect_is_valid_(true),
678       animation_start_time_(Timestamp::PlusInfinity()),
679       cap_resolution_due_to_video_content_(false),
680       expect_resize_state_(ExpectResizeState::kNoResize),
681       fec_controller_override_(nullptr),
682       force_disable_frame_dropper_(false),
683       pending_frame_drops_(0),
684       cwnd_frame_counter_(0),
685       next_frame_types_(1, VideoFrameType::kVideoFrameDelta),
686       frame_encode_metadata_writer_(this),
687       experiment_groups_(GetExperimentGroups()),
688       automatic_animation_detection_experiment_(
689           ParseAutomatincAnimationDetectionFieldTrial()),
690       input_state_provider_(encoder_stats_observer),
691       video_stream_adapter_(
692           std::make_unique<VideoStreamAdapter>(&input_state_provider_,
693                                                encoder_stats_observer,
694                                                field_trials)),
695       degradation_preference_manager_(
696           std::make_unique<DegradationPreferenceManager>(
697               video_stream_adapter_.get())),
698       adaptation_constraints_(),
699       stream_resource_manager_(&input_state_provider_,
700                                encoder_stats_observer,
701                                clock_,
702                                settings_.experiment_cpu_load_estimator,
703                                std::move(overuse_detector),
704                                degradation_preference_manager_.get(),
705                                field_trials),
706       video_source_sink_controller_(/*sink=*/frame_cadence_adapter_.get(),
707                                     /*source=*/nullptr),
708       default_limits_allowed_(
709           !field_trials.IsEnabled("WebRTC-DefaultBitrateLimitsKillSwitch")),
710       qp_parsing_allowed_(
711           !field_trials.IsEnabled("WebRTC-QpParsingKillSwitch")),
712       switch_encoder_on_init_failures_(!field_trials.IsDisabled(
713           kSwitchEncoderOnInitializationFailuresFieldTrial)),
714       vp9_low_tier_core_threshold_(
715           ParseVp9LowTierCoreCountThreshold(field_trials)),
716       encoder_queue_(std::move(encoder_queue)) {
717   TRACE_EVENT0("webrtc", "VideoStreamEncoder::VideoStreamEncoder");
718   RTC_DCHECK_RUN_ON(worker_queue_);
719   RTC_DCHECK(encoder_stats_observer);
720   RTC_DCHECK_GE(number_of_cores, 1);
721 
722   frame_cadence_adapter_->Initialize(&cadence_callback_);
723   stream_resource_manager_.Initialize(encoder_queue_.Get());
724 
__anon1bb4af870202null725   encoder_queue_.PostTask([this] {
726     RTC_DCHECK_RUN_ON(&encoder_queue_);
727 
728     resource_adaptation_processor_ =
729         std::make_unique<ResourceAdaptationProcessor>(
730             video_stream_adapter_.get());
731 
732     stream_resource_manager_.SetAdaptationProcessor(
733         resource_adaptation_processor_.get(), video_stream_adapter_.get());
734     resource_adaptation_processor_->AddResourceLimitationsListener(
735         &stream_resource_manager_);
736     video_stream_adapter_->AddRestrictionsListener(&stream_resource_manager_);
737     video_stream_adapter_->AddRestrictionsListener(this);
738     stream_resource_manager_.MaybeInitializePixelLimitResource();
739 
740     // Add the stream resource manager's resources to the processor.
741     adaptation_constraints_ = stream_resource_manager_.AdaptationConstraints();
742     for (auto* constraint : adaptation_constraints_) {
743       video_stream_adapter_->AddAdaptationConstraint(constraint);
744     }
745   });
746 }
747 
~VideoStreamEncoder()748 VideoStreamEncoder::~VideoStreamEncoder() {
749   RTC_DCHECK_RUN_ON(worker_queue_);
750   RTC_DCHECK(!video_source_sink_controller_.HasSource())
751       << "Must call ::Stop() before destruction.";
752 }
753 
Stop()754 void VideoStreamEncoder::Stop() {
755   RTC_DCHECK_RUN_ON(worker_queue_);
756   video_source_sink_controller_.SetSource(nullptr);
757 
758   rtc::Event shutdown_event;
759   absl::Cleanup shutdown = [&shutdown_event] { shutdown_event.Set(); };
760   encoder_queue_.PostTask(
761       [this, shutdown = std::move(shutdown)] {
762         RTC_DCHECK_RUN_ON(&encoder_queue_);
763         if (resource_adaptation_processor_) {
764           stream_resource_manager_.StopManagedResources();
765           for (auto* constraint : adaptation_constraints_) {
766             video_stream_adapter_->RemoveAdaptationConstraint(constraint);
767           }
768           for (auto& resource : additional_resources_) {
769             stream_resource_manager_.RemoveResource(resource);
770           }
771           additional_resources_.clear();
772           video_stream_adapter_->RemoveRestrictionsListener(this);
773           video_stream_adapter_->RemoveRestrictionsListener(
774               &stream_resource_manager_);
775           resource_adaptation_processor_->RemoveResourceLimitationsListener(
776               &stream_resource_manager_);
777           stream_resource_manager_.SetAdaptationProcessor(nullptr, nullptr);
778           resource_adaptation_processor_.reset();
779         }
780         rate_allocator_ = nullptr;
781         ReleaseEncoder();
782         encoder_ = nullptr;
783         frame_cadence_adapter_ = nullptr;
784       });
785   shutdown_event.Wait(rtc::Event::kForever);
786 }
787 
SetFecControllerOverride(FecControllerOverride * fec_controller_override)788 void VideoStreamEncoder::SetFecControllerOverride(
789     FecControllerOverride* fec_controller_override) {
790   encoder_queue_.PostTask([this, fec_controller_override] {
791     RTC_DCHECK_RUN_ON(&encoder_queue_);
792     RTC_DCHECK(!fec_controller_override_);
793     fec_controller_override_ = fec_controller_override;
794     if (encoder_) {
795       encoder_->SetFecControllerOverride(fec_controller_override_);
796     }
797   });
798 }
799 
AddAdaptationResource(rtc::scoped_refptr<Resource> resource)800 void VideoStreamEncoder::AddAdaptationResource(
801     rtc::scoped_refptr<Resource> resource) {
802   RTC_DCHECK_RUN_ON(worker_queue_);
803   TRACE_EVENT0("webrtc", "VideoStreamEncoder::AddAdaptationResource");
804   // Map any externally added resources as kCpu for the sake of stats reporting.
805   // TODO(hbos): Make the manager map any unknown resources to kCpu and get rid
806   // of this MapResourceToReason() call.
807   TRACE_EVENT_ASYNC_BEGIN0(
808       "webrtc", "VideoStreamEncoder::AddAdaptationResource(latency)", this);
809   encoder_queue_.PostTask([this, resource = std::move(resource)] {
810     TRACE_EVENT_ASYNC_END0(
811         "webrtc", "VideoStreamEncoder::AddAdaptationResource(latency)", this);
812     RTC_DCHECK_RUN_ON(&encoder_queue_);
813     additional_resources_.push_back(resource);
814     stream_resource_manager_.AddResource(resource, VideoAdaptationReason::kCpu);
815   });
816 }
817 
818 std::vector<rtc::scoped_refptr<Resource>>
GetAdaptationResources()819 VideoStreamEncoder::GetAdaptationResources() {
820   RTC_DCHECK_RUN_ON(worker_queue_);
821   // In practice, this method is only called by tests to verify operations that
822   // run on the encoder queue. So rather than force PostTask() operations to
823   // be accompanied by an event and a `Wait()`, we'll use PostTask + Wait()
824   // here.
825   rtc::Event event;
826   std::vector<rtc::scoped_refptr<Resource>> resources;
827   encoder_queue_.PostTask([&] {
828     RTC_DCHECK_RUN_ON(&encoder_queue_);
829     resources = resource_adaptation_processor_->GetResources();
830     event.Set();
831   });
832   event.Wait(rtc::Event::kForever);
833   return resources;
834 }
835 
SetSource(rtc::VideoSourceInterface<VideoFrame> * source,const DegradationPreference & degradation_preference)836 void VideoStreamEncoder::SetSource(
837     rtc::VideoSourceInterface<VideoFrame>* source,
838     const DegradationPreference& degradation_preference) {
839   RTC_DCHECK_RUN_ON(worker_queue_);
840   video_source_sink_controller_.SetSource(source);
841   input_state_provider_.OnHasInputChanged(source);
842 
843   // This may trigger reconfiguring the QualityScaler on the encoder queue.
844   encoder_queue_.PostTask([this, degradation_preference] {
845     RTC_DCHECK_RUN_ON(&encoder_queue_);
846     degradation_preference_manager_->SetDegradationPreference(
847         degradation_preference);
848     stream_resource_manager_.SetDegradationPreferences(degradation_preference);
849     if (encoder_) {
850       stream_resource_manager_.ConfigureQualityScaler(
851           encoder_->GetEncoderInfo());
852       stream_resource_manager_.ConfigureBandwidthQualityScaler(
853           encoder_->GetEncoderInfo());
854     }
855   });
856 }
857 
SetSink(EncoderSink * sink,bool rotation_applied)858 void VideoStreamEncoder::SetSink(EncoderSink* sink, bool rotation_applied) {
859   RTC_DCHECK_RUN_ON(worker_queue_);
860   video_source_sink_controller_.SetRotationApplied(rotation_applied);
861   video_source_sink_controller_.PushSourceSinkSettings();
862 
863   encoder_queue_.PostTask([this, sink] {
864     RTC_DCHECK_RUN_ON(&encoder_queue_);
865     sink_ = sink;
866   });
867 }
868 
SetStartBitrate(int start_bitrate_bps)869 void VideoStreamEncoder::SetStartBitrate(int start_bitrate_bps) {
870   encoder_queue_.PostTask([this, start_bitrate_bps] {
871     RTC_DCHECK_RUN_ON(&encoder_queue_);
872     RTC_LOG(LS_INFO) << "SetStartBitrate " << start_bitrate_bps;
873     encoder_target_bitrate_bps_ =
874         start_bitrate_bps != 0 ? absl::optional<uint32_t>(start_bitrate_bps)
875                                : absl::nullopt;
876     stream_resource_manager_.SetStartBitrate(
877         DataRate::BitsPerSec(start_bitrate_bps));
878   });
879 }
880 
ConfigureEncoder(VideoEncoderConfig config,size_t max_data_payload_length)881 void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config,
882                                           size_t max_data_payload_length) {
883   ConfigureEncoder(std::move(config), max_data_payload_length, nullptr);
884 }
885 
ConfigureEncoder(VideoEncoderConfig config,size_t max_data_payload_length,SetParametersCallback callback)886 void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config,
887                                           size_t max_data_payload_length,
888                                           SetParametersCallback callback) {
889   RTC_DCHECK_RUN_ON(worker_queue_);
890   encoder_queue_.PostTask(
891       [this, config = std::move(config), max_data_payload_length,
892        callback = std::move(callback)]() mutable {
893         RTC_DCHECK_RUN_ON(&encoder_queue_);
894         RTC_DCHECK(sink_);
895         RTC_LOG(LS_INFO) << "ConfigureEncoder requested.";
896 
897         // Set up the frame cadence adapter according to if we're going to do
898         // screencast. The final number of spatial layers is based on info
899         // in `send_codec_`, which is computed based on incoming frame
900         // dimensions which can only be determined later.
901         //
902         // Note: zero-hertz mode isn't enabled by this alone. Constraints also
903         // have to be set up with min_fps = 0 and max_fps > 0.
904         if (config.content_type == VideoEncoderConfig::ContentType::kScreen) {
905           frame_cadence_adapter_->SetZeroHertzModeEnabled(
906               FrameCadenceAdapterInterface::ZeroHertzModeParams{});
907         } else {
908           frame_cadence_adapter_->SetZeroHertzModeEnabled(absl::nullopt);
909         }
910 
911         pending_encoder_creation_ =
912             (!encoder_ || encoder_config_.video_format != config.video_format ||
913              max_data_payload_length_ != max_data_payload_length);
914         encoder_config_ = std::move(config);
915         max_data_payload_length_ = max_data_payload_length;
916         pending_encoder_reconfiguration_ = true;
917 
918         // Reconfigure the encoder now if the frame resolution is known.
919         // Otherwise, the reconfiguration is deferred until the next frame to
920         // minimize the number of reconfigurations. The codec configuration
921         // depends on incoming video frame size.
922         if (last_frame_info_) {
923           if (callback) {
924             encoder_configuration_callbacks_.push_back(std::move(callback));
925           }
926 
927           ReconfigureEncoder();
928         } else {
929           webrtc::InvokeSetParametersCallback(callback, webrtc::RTCError::OK());
930         }
931       });
932 }
933 
934 // We should reduce the number of 'full' ReconfigureEncoder(). If only need
935 // subset of it at runtime, consider handle it in
936 // VideoStreamEncoder::EncodeVideoFrame() when encoder_info_ != info.
ReconfigureEncoder()937 void VideoStreamEncoder::ReconfigureEncoder() {
938   // Running on the encoder queue.
939   RTC_DCHECK(pending_encoder_reconfiguration_);
940 
941   bool encoder_reset_required = false;
942   if (pending_encoder_creation_) {
943     // Destroy existing encoder instance before creating a new one. Otherwise
944     // attempt to create another instance will fail if encoder factory
945     // supports only single instance of encoder of given type.
946     encoder_.reset();
947 
948     encoder_ = settings_.encoder_factory->CreateVideoEncoder(
949         encoder_config_.video_format);
950     if (!encoder_) {
951       RTC_LOG(LS_ERROR) << "CreateVideoEncoder failed, failing encoder format: "
952                         << encoder_config_.video_format.ToString();
953       RequestEncoderSwitch();
954       return;
955     }
956 
957     if (encoder_selector_) {
958       encoder_selector_->OnCurrentEncoder(encoder_config_.video_format);
959     }
960 
961     encoder_->SetFecControllerOverride(fec_controller_override_);
962 
963     encoder_reset_required = true;
964   }
965 
966   // TODO(webrtc:14451) : Move AlignmentAdjuster into EncoderStreamFactory
967   // Possibly adjusts scale_resolution_down_by in `encoder_config_` to limit the
968   // alignment value.
969   AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
970       encoder_->GetEncoderInfo(), &encoder_config_, absl::nullopt);
971 
972   std::vector<VideoStream> streams;
973   if (encoder_config_.video_stream_factory) {
974     // Note: only tests set their own EncoderStreamFactory...
975     streams = encoder_config_.video_stream_factory->CreateEncoderStreams(
976         last_frame_info_->width, last_frame_info_->height, encoder_config_);
977   } else {
978     rtc::scoped_refptr<VideoEncoderConfig::VideoStreamFactoryInterface>
979         factory = rtc::make_ref_counted<cricket::EncoderStreamFactory>(
980             encoder_config_.video_format.name, encoder_config_.max_qp,
981             encoder_config_.content_type ==
982                 webrtc::VideoEncoderConfig::ContentType::kScreen,
983             encoder_config_.legacy_conference_mode, encoder_->GetEncoderInfo(),
984             MergeRestrictions({latest_restrictions_, animate_restrictions_}),
985             &field_trials_);
986 
987     streams = factory->CreateEncoderStreams(
988         last_frame_info_->width, last_frame_info_->height, encoder_config_);
989   }
990 
991   // TODO(webrtc:14451) : Move AlignmentAdjuster into EncoderStreamFactory
992   // Get alignment when actual number of layers are known.
993   int alignment = AlignmentAdjuster::GetAlignmentAndMaybeAdjustScaleFactors(
994       encoder_->GetEncoderInfo(), &encoder_config_, streams.size());
995 
996   // Check that the higher layers do not try to set number of temporal layers
997   // to less than 1.
998   // TODO(brandtr): Get rid of the wrapping optional as it serves no purpose
999   // at this layer.
1000 #if RTC_DCHECK_IS_ON
1001   for (const auto& stream : streams) {
1002     RTC_DCHECK_GE(stream.num_temporal_layers.value_or(1), 1);
1003   }
1004 #endif
1005 
1006   // TODO(ilnik): If configured resolution is significantly less than provided,
1007   // e.g. because there are not enough SSRCs for all simulcast streams,
1008   // signal new resolutions via SinkWants to video source.
1009 
1010   // Stream dimensions may be not equal to given because of a simulcast
1011   // restrictions.
1012   auto highest_stream = absl::c_max_element(
1013       streams, [](const webrtc::VideoStream& a, const webrtc::VideoStream& b) {
1014         return std::tie(a.width, a.height) < std::tie(b.width, b.height);
1015       });
1016   int highest_stream_width = static_cast<int>(highest_stream->width);
1017   int highest_stream_height = static_cast<int>(highest_stream->height);
1018   // Dimension may be reduced to be, e.g. divisible by 4.
1019   RTC_CHECK_GE(last_frame_info_->width, highest_stream_width);
1020   RTC_CHECK_GE(last_frame_info_->height, highest_stream_height);
1021   crop_width_ = last_frame_info_->width - highest_stream_width;
1022   crop_height_ = last_frame_info_->height - highest_stream_height;
1023 
1024   if (!encoder_->GetEncoderInfo().is_qp_trusted.value_or(true)) {
1025     // when qp is not trusted, we priorities to using the
1026     // |resolution_bitrate_limits| provided by the decoder.
1027     const std::vector<VideoEncoder::ResolutionBitrateLimits>& bitrate_limits =
1028         encoder_->GetEncoderInfo().resolution_bitrate_limits.empty()
1029             ? EncoderInfoSettings::
1030                   GetDefaultSinglecastBitrateLimitsWhenQpIsUntrusted()
1031             : encoder_->GetEncoderInfo().resolution_bitrate_limits;
1032 
1033     // For BandwidthQualityScaler, its implement based on a certain pixel_count
1034     // correspond a certain bps interval. In fact, WebRTC default max_bps is
1035     // 2500Kbps when width * height > 960 * 540. For example, we assume:
1036     // 1.the camera support 1080p.
1037     // 2.ResolutionBitrateLimits set 720p bps interval is [1500Kbps,2000Kbps].
1038     // 3.ResolutionBitrateLimits set 1080p bps interval is [2000Kbps,2500Kbps].
1039     // We will never be stable at 720p due to actual encoding bps of 720p and
1040     // 1080p are both 2500Kbps. So it is necessary to do a linear interpolation
1041     // to get a certain bitrate for certain pixel_count. It also doesn't work
1042     // for 960*540 and 640*520, we will nerver be stable at 640*520 due to their
1043     // |target_bitrate_bps| are both 2000Kbps.
1044     absl::optional<VideoEncoder::ResolutionBitrateLimits>
1045         qp_untrusted_bitrate_limit = EncoderInfoSettings::
1046             GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
1047                 last_frame_info_->width * last_frame_info_->height,
1048                 bitrate_limits);
1049 
1050     if (qp_untrusted_bitrate_limit) {
1051       // bandwidth_quality_scaler is only used for singlecast.
1052       if (streams.size() == 1 && encoder_config_.simulcast_layers.size() == 1) {
1053         streams.back().min_bitrate_bps =
1054             qp_untrusted_bitrate_limit->min_bitrate_bps;
1055         streams.back().max_bitrate_bps =
1056             qp_untrusted_bitrate_limit->max_bitrate_bps;
1057         // If it is screen share mode, the minimum value of max_bitrate should
1058         // be greater than/equal to 1200kbps.
1059         if (encoder_config_.content_type ==
1060             VideoEncoderConfig::ContentType::kScreen) {
1061           streams.back().max_bitrate_bps = std::max(
1062               streams.back().max_bitrate_bps, kDefaultMinScreenSharebps);
1063         }
1064         streams.back().target_bitrate_bps =
1065             qp_untrusted_bitrate_limit->max_bitrate_bps;
1066       }
1067     }
1068   } else {
1069     absl::optional<VideoEncoder::ResolutionBitrateLimits>
1070         encoder_bitrate_limits =
1071             encoder_->GetEncoderInfo().GetEncoderBitrateLimitsForResolution(
1072                 last_frame_info_->width * last_frame_info_->height);
1073 
1074     if (encoder_bitrate_limits) {
1075       if (streams.size() == 1 && encoder_config_.simulcast_layers.size() == 1) {
1076         // Bitrate limits can be set by app (in SDP or RtpEncodingParameters)
1077         // or/and can be provided by encoder. In presence of both set of
1078         // limits, the final set is derived as their intersection.
1079         int min_bitrate_bps;
1080         if (encoder_config_.simulcast_layers.empty() ||
1081             encoder_config_.simulcast_layers[0].min_bitrate_bps <= 0) {
1082           min_bitrate_bps = encoder_bitrate_limits->min_bitrate_bps;
1083         } else {
1084           min_bitrate_bps = std::max(encoder_bitrate_limits->min_bitrate_bps,
1085                                      streams.back().min_bitrate_bps);
1086         }
1087 
1088         int max_bitrate_bps;
1089         // We don't check encoder_config_.simulcast_layers[0].max_bitrate_bps
1090         // here since encoder_config_.max_bitrate_bps is derived from it (as
1091         // well as from other inputs).
1092         if (encoder_config_.max_bitrate_bps <= 0) {
1093           max_bitrate_bps = encoder_bitrate_limits->max_bitrate_bps;
1094         } else {
1095           max_bitrate_bps = std::min(encoder_bitrate_limits->max_bitrate_bps,
1096                                      streams.back().max_bitrate_bps);
1097         }
1098 
1099         if (min_bitrate_bps < max_bitrate_bps) {
1100           streams.back().min_bitrate_bps = min_bitrate_bps;
1101           streams.back().max_bitrate_bps = max_bitrate_bps;
1102           streams.back().target_bitrate_bps =
1103               std::min(streams.back().target_bitrate_bps,
1104                        encoder_bitrate_limits->max_bitrate_bps);
1105         } else {
1106           RTC_LOG(LS_WARNING)
1107               << "Bitrate limits provided by encoder"
1108               << " (min=" << encoder_bitrate_limits->min_bitrate_bps
1109               << ", max=" << encoder_bitrate_limits->max_bitrate_bps
1110               << ") do not intersect with limits set by app"
1111               << " (min=" << streams.back().min_bitrate_bps
1112               << ", max=" << encoder_config_.max_bitrate_bps
1113               << "). The app bitrate limits will be used.";
1114         }
1115       }
1116     }
1117   }
1118 
1119   ApplyEncoderBitrateLimitsIfSingleActiveStream(
1120       GetEncoderInfoWithBitrateLimitUpdate(
1121           encoder_->GetEncoderInfo(), encoder_config_, default_limits_allowed_),
1122       encoder_config_.simulcast_layers, &streams);
1123 
1124   VideoCodec codec;
1125   if (!VideoCodecInitializer::SetupCodec(encoder_config_, streams, &codec)) {
1126     RTC_LOG(LS_ERROR) << "Failed to create encoder configuration.";
1127   }
1128 
1129   if (encoder_config_.codec_type == kVideoCodecVP9) {
1130     // Spatial layers configuration might impose some parity restrictions,
1131     // thus some cropping might be needed.
1132     crop_width_ = last_frame_info_->width - codec.width;
1133     crop_height_ = last_frame_info_->height - codec.height;
1134     ApplyVp9BitrateLimits(GetEncoderInfoWithBitrateLimitUpdate(
1135                               encoder_->GetEncoderInfo(), encoder_config_,
1136                               default_limits_allowed_),
1137                           encoder_config_, &codec);
1138   }
1139 
1140   char log_stream_buf[4 * 1024];
1141   rtc::SimpleStringBuilder log_stream(log_stream_buf);
1142   log_stream << "ReconfigureEncoder:\n";
1143   log_stream << "Simulcast streams:\n";
1144   for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) {
1145     log_stream << i << ": " << codec.simulcastStream[i].width << "x"
1146                << codec.simulcastStream[i].height
1147                << " min_kbps: " << codec.simulcastStream[i].minBitrate
1148                << " target_kbps: " << codec.simulcastStream[i].targetBitrate
1149                << " max_kbps: " << codec.simulcastStream[i].maxBitrate
1150                << " max_fps: " << codec.simulcastStream[i].maxFramerate
1151                << " max_qp: " << codec.simulcastStream[i].qpMax
1152                << " num_tl: " << codec.simulcastStream[i].numberOfTemporalLayers
1153                << " active: "
1154                << (codec.simulcastStream[i].active ? "true" : "false") << "\n";
1155   }
1156   if (encoder_config_.codec_type == kVideoCodecVP9) {
1157     size_t num_spatial_layers = codec.VP9()->numberOfSpatialLayers;
1158     log_stream << "Spatial layers:\n";
1159     for (size_t i = 0; i < num_spatial_layers; ++i) {
1160       log_stream << i << ": " << codec.spatialLayers[i].width << "x"
1161                  << codec.spatialLayers[i].height
1162                  << " min_kbps: " << codec.spatialLayers[i].minBitrate
1163                  << " target_kbps: " << codec.spatialLayers[i].targetBitrate
1164                  << " max_kbps: " << codec.spatialLayers[i].maxBitrate
1165                  << " max_fps: " << codec.spatialLayers[i].maxFramerate
1166                  << " max_qp: " << codec.spatialLayers[i].qpMax
1167                  << " num_tl: " << codec.spatialLayers[i].numberOfTemporalLayers
1168                  << " active: "
1169                  << (codec.spatialLayers[i].active ? "true" : "false") << "\n";
1170     }
1171   }
1172   RTC_LOG(LS_INFO) << log_stream.str();
1173 
1174   codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000,
1175                                 codec.minBitrate);
1176   codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate);
1177   codec.expect_encode_from_texture = last_frame_info_->is_texture;
1178   // Make sure the start bit rate is sane...
1179   RTC_DCHECK_LE(codec.startBitrate, 1000000);
1180   max_framerate_ = codec.maxFramerate;
1181 
1182   // Inform source about max configured framerate,
1183   // requested_resolution and which layers are active.
1184   int max_framerate = 0;
1185   // Is any layer active.
1186   bool active = false;
1187   // The max requested_resolution.
1188   absl::optional<rtc::VideoSinkWants::FrameSize> requested_resolution;
1189   for (const auto& stream : streams) {
1190     max_framerate = std::max(stream.max_framerate, max_framerate);
1191     active |= stream.active;
1192     // Note: we propagate the highest requested_resolution regardless
1193     // if layer is active or not.
1194     if (stream.requested_resolution) {
1195       if (!requested_resolution) {
1196         requested_resolution.emplace(stream.requested_resolution->width,
1197                                      stream.requested_resolution->height);
1198       } else {
1199         requested_resolution.emplace(
1200             std::max(stream.requested_resolution->width,
1201                      requested_resolution->width),
1202             std::max(stream.requested_resolution->height,
1203                      requested_resolution->height));
1204       }
1205     }
1206   }
1207 
1208   // The resolutions that we're actually encoding with.
1209   std::vector<rtc::VideoSinkWants::FrameSize> encoder_resolutions;
1210   // TODO(hbos): For the case of SVC, also make use of `codec.spatialLayers`.
1211   // For now, SVC layers are handled by the VP9 encoder.
1212   for (const auto& simulcastStream : codec.simulcastStream) {
1213     if (!simulcastStream.active)
1214       continue;
1215     encoder_resolutions.emplace_back(simulcastStream.width,
1216                                      simulcastStream.height);
1217   }
1218 
1219   worker_queue_->PostTask(SafeTask(
1220       task_safety_.flag(),
1221       [this, max_framerate, alignment,
1222        encoder_resolutions = std::move(encoder_resolutions),
1223        requested_resolution = std::move(requested_resolution), active]() {
1224         RTC_DCHECK_RUN_ON(worker_queue_);
1225         if (max_framerate !=
1226                 video_source_sink_controller_.frame_rate_upper_limit() ||
1227             alignment != video_source_sink_controller_.resolution_alignment() ||
1228             encoder_resolutions !=
1229                 video_source_sink_controller_.resolutions() ||
1230             (video_source_sink_controller_.requested_resolution() !=
1231              requested_resolution) ||
1232             (video_source_sink_controller_.active() != active)) {
1233           video_source_sink_controller_.SetFrameRateUpperLimit(max_framerate);
1234           video_source_sink_controller_.SetResolutionAlignment(alignment);
1235           video_source_sink_controller_.SetResolutions(
1236               std::move(encoder_resolutions));
1237           video_source_sink_controller_.SetRequestedResolution(
1238               requested_resolution);
1239           video_source_sink_controller_.SetActive(active);
1240           video_source_sink_controller_.PushSourceSinkSettings();
1241         }
1242       }));
1243 
1244   rate_allocator_ =
1245       settings_.bitrate_allocator_factory->CreateVideoBitrateAllocator(codec);
1246   rate_allocator_->SetLegacyConferenceMode(
1247       encoder_config_.legacy_conference_mode);
1248 
1249   // Reset (release existing encoder) if one exists and anything except
1250   // start bitrate or max framerate has changed.
1251   if (!encoder_reset_required) {
1252     encoder_reset_required = RequiresEncoderReset(
1253         send_codec_, codec, was_encode_called_since_last_initialization_);
1254   }
1255 
1256   if (codec.codecType == VideoCodecType::kVideoCodecVP9 &&
1257       number_of_cores_ <= vp9_low_tier_core_threshold_.value_or(0)) {
1258     codec.SetVideoEncoderComplexity(VideoCodecComplexity::kComplexityLow);
1259   }
1260 
1261   send_codec_ = codec;
1262 
1263   // Keep the same encoder, as long as the video_format is unchanged.
1264   // Encoder creation block is split in two since EncoderInfo needed to start
1265   // CPU adaptation with the correct settings should be polled after
1266   // encoder_->InitEncode().
1267   if (encoder_reset_required) {
1268     ReleaseEncoder();
1269     const size_t max_data_payload_length = max_data_payload_length_ > 0
1270                                                ? max_data_payload_length_
1271                                                : kDefaultPayloadSize;
1272     if (encoder_->InitEncode(
1273             &send_codec_,
1274             VideoEncoder::Settings(settings_.capabilities, number_of_cores_,
1275                                    max_data_payload_length)) != 0) {
1276       RTC_LOG(LS_ERROR) << "Failed to initialize the encoder associated with "
1277                            "codec type: "
1278                         << CodecTypeToPayloadString(send_codec_.codecType)
1279                         << " (" << send_codec_.codecType << ")";
1280       ReleaseEncoder();
1281     } else {
1282       encoder_initialized_ = true;
1283       encoder_->RegisterEncodeCompleteCallback(this);
1284       frame_encode_metadata_writer_.OnEncoderInit(send_codec_);
1285       next_frame_types_.clear();
1286       next_frame_types_.resize(
1287           std::max(static_cast<int>(codec.numberOfSimulcastStreams), 1),
1288           VideoFrameType::kVideoFrameKey);
1289     }
1290 
1291     frame_encode_metadata_writer_.Reset();
1292     last_encode_info_ms_ = absl::nullopt;
1293     was_encode_called_since_last_initialization_ = false;
1294   }
1295 
1296   // Inform dependents of updated encoder settings.
1297   OnEncoderSettingsChanged();
1298 
1299   if (encoder_initialized_) {
1300     RTC_LOG(LS_VERBOSE) << " max bitrate " << codec.maxBitrate
1301                         << " start bitrate " << codec.startBitrate
1302                         << " max frame rate " << codec.maxFramerate
1303                         << " max payload size " << max_data_payload_length_;
1304   } else {
1305     RTC_LOG(LS_ERROR) << "Failed to configure encoder.";
1306     rate_allocator_ = nullptr;
1307   }
1308 
1309   if (pending_encoder_creation_) {
1310     stream_resource_manager_.ConfigureEncodeUsageResource();
1311     pending_encoder_creation_ = false;
1312   }
1313 
1314   int num_layers;
1315   if (codec.codecType == kVideoCodecVP8) {
1316     num_layers = codec.VP8()->numberOfTemporalLayers;
1317   } else if (codec.codecType == kVideoCodecVP9) {
1318     num_layers = codec.VP9()->numberOfTemporalLayers;
1319   } else if (codec.codecType == kVideoCodecH264) {
1320     num_layers = codec.H264()->numberOfTemporalLayers;
1321   } else if (codec.codecType == kVideoCodecGeneric &&
1322              codec.numberOfSimulcastStreams > 0) {
1323     // This is mainly for unit testing, disabling frame dropping.
1324     // TODO(sprang): Add a better way to disable frame dropping.
1325     num_layers = codec.simulcastStream[0].numberOfTemporalLayers;
1326   } else {
1327     num_layers = 1;
1328   }
1329 
1330   frame_dropper_.Reset();
1331   frame_dropper_.SetRates(codec.startBitrate, max_framerate_);
1332   // Force-disable frame dropper if either:
1333   //  * We have screensharing with layers.
1334   //  * "WebRTC-FrameDropper" field trial is "Disabled".
1335   force_disable_frame_dropper_ =
1336       field_trials_.IsDisabled(kFrameDropperFieldTrial) ||
1337       (num_layers > 1 && codec.mode == VideoCodecMode::kScreensharing);
1338 
1339   VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
1340   if (rate_control_settings_.UseEncoderBitrateAdjuster()) {
1341     bitrate_adjuster_ = std::make_unique<EncoderBitrateAdjuster>(codec);
1342     bitrate_adjuster_->OnEncoderInfo(info);
1343   }
1344 
1345   if (rate_allocator_ && last_encoder_rate_settings_) {
1346     // We have a new rate allocator instance and already configured target
1347     // bitrate. Update the rate allocation and notify observers.
1348     // We must invalidate the last_encoder_rate_settings_ to ensure
1349     // the changes get propagated to all listeners.
1350     EncoderRateSettings rate_settings = *last_encoder_rate_settings_;
1351     last_encoder_rate_settings_.reset();
1352     rate_settings.rate_control.framerate_fps = GetInputFramerateFps();
1353 
1354     SetEncoderRates(UpdateBitrateAllocation(rate_settings));
1355   }
1356 
1357   encoder_stats_observer_->OnEncoderReconfigured(encoder_config_, streams);
1358 
1359   pending_encoder_reconfiguration_ = false;
1360 
1361   bool is_svc = false;
1362   // Set min_bitrate_bps, max_bitrate_bps, and max padding bit rate for VP9
1363   // and leave only one stream containing all necessary information.
1364   if (encoder_config_.codec_type == kVideoCodecVP9) {
1365     // Lower max bitrate to the level codec actually can produce.
1366     streams[0].max_bitrate_bps =
1367         std::min(streams[0].max_bitrate_bps,
1368                  SvcRateAllocator::GetMaxBitrate(codec).bps<int>());
1369     streams[0].min_bitrate_bps = codec.spatialLayers[0].minBitrate * 1000;
1370     // target_bitrate_bps specifies the maximum padding bitrate.
1371     streams[0].target_bitrate_bps =
1372         SvcRateAllocator::GetPaddingBitrate(codec).bps<int>();
1373     streams[0].width = streams.back().width;
1374     streams[0].height = streams.back().height;
1375     is_svc = codec.VP9()->numberOfSpatialLayers > 1;
1376     streams.resize(1);
1377   }
1378 
1379   sink_->OnEncoderConfigurationChanged(
1380       std::move(streams), is_svc, encoder_config_.content_type,
1381       encoder_config_.min_transmit_bitrate_bps);
1382 
1383   stream_resource_manager_.ConfigureQualityScaler(info);
1384   stream_resource_manager_.ConfigureBandwidthQualityScaler(info);
1385 
1386   webrtc::RTCError encoder_configuration_result = webrtc::RTCError::OK();
1387 
1388   if (!encoder_initialized_) {
1389     RTC_LOG(LS_WARNING) << "Failed to initialize "
1390                         << CodecTypeToPayloadString(codec.codecType)
1391                         << " encoder."
1392                         << "switch_encoder_on_init_failures: "
1393                         << switch_encoder_on_init_failures_;
1394 
1395     if (switch_encoder_on_init_failures_) {
1396       RequestEncoderSwitch();
1397     } else {
1398       encoder_configuration_result =
1399           webrtc::RTCError(RTCErrorType::UNSUPPORTED_OPERATION);
1400     }
1401   }
1402 
1403   if (!encoder_configuration_callbacks_.empty()) {
1404     for (auto& callback : encoder_configuration_callbacks_) {
1405       webrtc::InvokeSetParametersCallback(callback,
1406                                           encoder_configuration_result);
1407     }
1408     encoder_configuration_callbacks_.clear();
1409   }
1410 }
1411 
RequestEncoderSwitch()1412 void VideoStreamEncoder::RequestEncoderSwitch() {
1413   bool is_encoder_switching_supported =
1414       settings_.encoder_switch_request_callback != nullptr;
1415   bool is_encoder_selector_available = encoder_selector_ != nullptr;
1416 
1417   RTC_LOG(LS_INFO) << "RequestEncoderSwitch."
1418                    << " is_encoder_selector_available: "
1419                    << is_encoder_selector_available
1420                    << " is_encoder_switching_supported: "
1421                    << is_encoder_switching_supported;
1422 
1423   if (!is_encoder_switching_supported) {
1424     return;
1425   }
1426 
1427   // If encoder selector is available, switch to the encoder it prefers.
1428   // Otherwise try switching to VP8 (default WebRTC codec).
1429   absl::optional<SdpVideoFormat> preferred_fallback_encoder;
1430   if (is_encoder_selector_available) {
1431     preferred_fallback_encoder = encoder_selector_->OnEncoderBroken();
1432   }
1433 
1434   if (!preferred_fallback_encoder) {
1435     preferred_fallback_encoder =
1436         SdpVideoFormat(CodecTypeToPayloadString(kVideoCodecVP8));
1437   }
1438 
1439   settings_.encoder_switch_request_callback->RequestEncoderSwitch(
1440       *preferred_fallback_encoder, /*allow_default_fallback=*/true);
1441 }
1442 
OnEncoderSettingsChanged()1443 void VideoStreamEncoder::OnEncoderSettingsChanged() {
1444   EncoderSettings encoder_settings(
1445       GetEncoderInfoWithBitrateLimitUpdate(
1446           encoder_->GetEncoderInfo(), encoder_config_, default_limits_allowed_),
1447       encoder_config_.Copy(), send_codec_);
1448   stream_resource_manager_.SetEncoderSettings(encoder_settings);
1449   input_state_provider_.OnEncoderSettingsChanged(encoder_settings);
1450   bool is_screenshare = encoder_settings.encoder_config().content_type ==
1451                         VideoEncoderConfig::ContentType::kScreen;
1452   degradation_preference_manager_->SetIsScreenshare(is_screenshare);
1453   if (is_screenshare) {
1454     frame_cadence_adapter_->SetZeroHertzModeEnabled(
1455         FrameCadenceAdapterInterface::ZeroHertzModeParams{
1456             send_codec_.numberOfSimulcastStreams});
1457   }
1458 }
1459 
OnFrame(Timestamp post_time,int frames_scheduled_for_processing,const VideoFrame & video_frame)1460 void VideoStreamEncoder::OnFrame(Timestamp post_time,
1461                                  int frames_scheduled_for_processing,
1462                                  const VideoFrame& video_frame) {
1463   RTC_DCHECK_RUN_ON(&encoder_queue_);
1464   VideoFrame incoming_frame = video_frame;
1465 
1466   // In some cases, e.g., when the frame from decoder is fed to encoder,
1467   // the timestamp may be set to the future. As the encoding pipeline assumes
1468   // capture time to be less than present time, we should reset the capture
1469   // timestamps here. Otherwise there may be issues with RTP send stream.
1470   if (incoming_frame.timestamp_us() > post_time.us())
1471     incoming_frame.set_timestamp_us(post_time.us());
1472 
1473   // Capture time may come from clock with an offset and drift from clock_.
1474   int64_t capture_ntp_time_ms;
1475   if (video_frame.ntp_time_ms() > 0) {
1476     capture_ntp_time_ms = video_frame.ntp_time_ms();
1477   } else if (video_frame.render_time_ms() != 0) {
1478     capture_ntp_time_ms = video_frame.render_time_ms() + delta_ntp_internal_ms_;
1479   } else {
1480     capture_ntp_time_ms = post_time.ms() + delta_ntp_internal_ms_;
1481   }
1482   incoming_frame.set_ntp_time_ms(capture_ntp_time_ms);
1483 
1484   // Convert NTP time, in ms, to RTP timestamp.
1485   const int kMsToRtpTimestamp = 90;
1486   incoming_frame.set_timestamp(
1487       kMsToRtpTimestamp * static_cast<uint32_t>(incoming_frame.ntp_time_ms()));
1488 
1489   if (incoming_frame.ntp_time_ms() <= last_captured_timestamp_) {
1490     // We don't allow the same capture time for two frames, drop this one.
1491     RTC_LOG(LS_WARNING) << "Same/old NTP timestamp ("
1492                         << incoming_frame.ntp_time_ms()
1493                         << " <= " << last_captured_timestamp_
1494                         << ") for incoming frame. Dropping.";
1495     encoder_queue_.PostTask([this, incoming_frame]() {
1496       RTC_DCHECK_RUN_ON(&encoder_queue_);
1497       accumulated_update_rect_.Union(incoming_frame.update_rect());
1498       accumulated_update_rect_is_valid_ &= incoming_frame.has_update_rect();
1499     });
1500     return;
1501   }
1502 
1503   bool log_stats = false;
1504   if (post_time.ms() - last_frame_log_ms_ > kFrameLogIntervalMs) {
1505     last_frame_log_ms_ = post_time.ms();
1506     log_stats = true;
1507   }
1508 
1509   last_captured_timestamp_ = incoming_frame.ntp_time_ms();
1510 
1511   encoder_stats_observer_->OnIncomingFrame(incoming_frame.width(),
1512                                            incoming_frame.height());
1513   ++captured_frame_count_;
1514   CheckForAnimatedContent(incoming_frame, post_time.us());
1515   bool cwnd_frame_drop =
1516       cwnd_frame_drop_interval_ &&
1517       (cwnd_frame_counter_++ % cwnd_frame_drop_interval_.value() == 0);
1518   if (frames_scheduled_for_processing == 1 && !cwnd_frame_drop) {
1519     MaybeEncodeVideoFrame(incoming_frame, post_time.us());
1520   } else {
1521     if (cwnd_frame_drop) {
1522       // Frame drop by congestion window pushback. Do not encode this
1523       // frame.
1524       ++dropped_frame_cwnd_pushback_count_;
1525       encoder_stats_observer_->OnFrameDropped(
1526           VideoStreamEncoderObserver::DropReason::kCongestionWindow);
1527     } else {
1528       // There is a newer frame in flight. Do not encode this frame.
1529       RTC_LOG(LS_VERBOSE)
1530           << "Incoming frame dropped due to that the encoder is blocked.";
1531       ++dropped_frame_encoder_block_count_;
1532       encoder_stats_observer_->OnFrameDropped(
1533           VideoStreamEncoderObserver::DropReason::kEncoderQueue);
1534     }
1535     accumulated_update_rect_.Union(incoming_frame.update_rect());
1536     accumulated_update_rect_is_valid_ &= incoming_frame.has_update_rect();
1537   }
1538   if (log_stats) {
1539     RTC_LOG(LS_INFO) << "Number of frames: captured " << captured_frame_count_
1540                      << ", dropped (due to congestion window pushback) "
1541                      << dropped_frame_cwnd_pushback_count_
1542                      << ", dropped (due to encoder blocked) "
1543                      << dropped_frame_encoder_block_count_ << ", interval_ms "
1544                      << kFrameLogIntervalMs;
1545     captured_frame_count_ = 0;
1546     dropped_frame_cwnd_pushback_count_ = 0;
1547     dropped_frame_encoder_block_count_ = 0;
1548   }
1549 }
1550 
OnDiscardedFrame()1551 void VideoStreamEncoder::OnDiscardedFrame() {
1552   encoder_stats_observer_->OnFrameDropped(
1553       VideoStreamEncoderObserver::DropReason::kSource);
1554 }
1555 
EncoderPaused() const1556 bool VideoStreamEncoder::EncoderPaused() const {
1557   RTC_DCHECK_RUN_ON(&encoder_queue_);
1558   // Pause video if paused by caller or as long as the network is down or the
1559   // pacer queue has grown too large in buffered mode.
1560   // If the pacer queue has grown too large or the network is down,
1561   // `last_encoder_rate_settings_->encoder_target` will be 0.
1562   return !last_encoder_rate_settings_ ||
1563          last_encoder_rate_settings_->encoder_target == DataRate::Zero();
1564 }
1565 
TraceFrameDropStart()1566 void VideoStreamEncoder::TraceFrameDropStart() {
1567   RTC_DCHECK_RUN_ON(&encoder_queue_);
1568   // Start trace event only on the first frame after encoder is paused.
1569   if (!encoder_paused_and_dropped_frame_) {
1570     TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
1571   }
1572   encoder_paused_and_dropped_frame_ = true;
1573 }
1574 
TraceFrameDropEnd()1575 void VideoStreamEncoder::TraceFrameDropEnd() {
1576   RTC_DCHECK_RUN_ON(&encoder_queue_);
1577   // End trace event on first frame after encoder resumes, if frame was dropped.
1578   if (encoder_paused_and_dropped_frame_) {
1579     TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
1580   }
1581   encoder_paused_and_dropped_frame_ = false;
1582 }
1583 
1584 VideoStreamEncoder::EncoderRateSettings
UpdateBitrateAllocation(const EncoderRateSettings & rate_settings)1585 VideoStreamEncoder::UpdateBitrateAllocation(
1586     const EncoderRateSettings& rate_settings) {
1587   VideoBitrateAllocation new_allocation;
1588   // Only call allocators if bitrate > 0 (ie, not suspended), otherwise they
1589   // might cap the bitrate to the min bitrate configured.
1590   if (rate_allocator_ && rate_settings.encoder_target > DataRate::Zero()) {
1591     new_allocation = rate_allocator_->Allocate(VideoBitrateAllocationParameters(
1592         rate_settings.encoder_target, rate_settings.stable_encoder_target,
1593         rate_settings.rate_control.framerate_fps));
1594   }
1595 
1596   EncoderRateSettings new_rate_settings = rate_settings;
1597   new_rate_settings.rate_control.target_bitrate = new_allocation;
1598   new_rate_settings.rate_control.bitrate = new_allocation;
1599   // VideoBitrateAllocator subclasses may allocate a bitrate higher than the
1600   // target in order to sustain the min bitrate of the video codec. In this
1601   // case, make sure the bandwidth allocation is at least equal the allocation
1602   // as that is part of the document contract for that field.
1603   new_rate_settings.rate_control.bandwidth_allocation =
1604       std::max(new_rate_settings.rate_control.bandwidth_allocation,
1605                DataRate::BitsPerSec(
1606                    new_rate_settings.rate_control.bitrate.get_sum_bps()));
1607 
1608   if (bitrate_adjuster_) {
1609     VideoBitrateAllocation adjusted_allocation =
1610         bitrate_adjuster_->AdjustRateAllocation(new_rate_settings.rate_control);
1611     RTC_LOG(LS_VERBOSE) << "Adjusting allocation, fps = "
1612                         << rate_settings.rate_control.framerate_fps << ", from "
1613                         << new_allocation.ToString() << ", to "
1614                         << adjusted_allocation.ToString();
1615     new_rate_settings.rate_control.bitrate = adjusted_allocation;
1616   }
1617 
1618   return new_rate_settings;
1619 }
1620 
GetInputFramerateFps()1621 uint32_t VideoStreamEncoder::GetInputFramerateFps() {
1622   const uint32_t default_fps = max_framerate_ != -1 ? max_framerate_ : 30;
1623 
1624   // This method may be called after we cleared out the frame_cadence_adapter_
1625   // reference in Stop(). In such a situation it's probably not important with a
1626   // decent estimate.
1627   absl::optional<uint32_t> input_fps =
1628       frame_cadence_adapter_ ? frame_cadence_adapter_->GetInputFrameRateFps()
1629                              : absl::nullopt;
1630   if (!input_fps || *input_fps == 0) {
1631     return default_fps;
1632   }
1633   return *input_fps;
1634 }
1635 
SetEncoderRates(const EncoderRateSettings & rate_settings)1636 void VideoStreamEncoder::SetEncoderRates(
1637     const EncoderRateSettings& rate_settings) {
1638   RTC_DCHECK_GT(rate_settings.rate_control.framerate_fps, 0.0);
1639   bool rate_control_changed =
1640       (!last_encoder_rate_settings_.has_value() ||
1641        last_encoder_rate_settings_->rate_control != rate_settings.rate_control);
1642   // For layer allocation signal we care only about the target bitrate (not the
1643   // adjusted one) and the target fps.
1644   bool layer_allocation_changed =
1645       !last_encoder_rate_settings_.has_value() ||
1646       last_encoder_rate_settings_->rate_control.target_bitrate !=
1647           rate_settings.rate_control.target_bitrate ||
1648       last_encoder_rate_settings_->rate_control.framerate_fps !=
1649           rate_settings.rate_control.framerate_fps;
1650 
1651   if (last_encoder_rate_settings_ != rate_settings) {
1652     last_encoder_rate_settings_ = rate_settings;
1653   }
1654 
1655   if (!encoder_)
1656     return;
1657 
1658   // Make the cadence adapter know if streams were disabled.
1659   for (int spatial_index = 0;
1660        spatial_index != send_codec_.numberOfSimulcastStreams; ++spatial_index) {
1661     frame_cadence_adapter_->UpdateLayerStatus(
1662         spatial_index,
1663         /*enabled=*/rate_settings.rate_control.target_bitrate
1664                 .GetSpatialLayerSum(spatial_index) > 0);
1665   }
1666 
1667   // `bitrate_allocation` is 0 it means that the network is down or the send
1668   // pacer is full. We currently don't pass this on to the encoder since it is
1669   // unclear how current encoder implementations behave when given a zero target
1670   // bitrate.
1671   // TODO(perkj): Make sure all known encoder implementations handle zero
1672   // target bitrate and remove this check.
1673   if (rate_settings.rate_control.bitrate.get_sum_bps() == 0)
1674     return;
1675 
1676   if (rate_control_changed) {
1677     encoder_->SetRates(rate_settings.rate_control);
1678 
1679     encoder_stats_observer_->OnBitrateAllocationUpdated(
1680         send_codec_, rate_settings.rate_control.bitrate);
1681     frame_encode_metadata_writer_.OnSetRates(
1682         rate_settings.rate_control.bitrate,
1683         static_cast<uint32_t>(rate_settings.rate_control.framerate_fps + 0.5));
1684     stream_resource_manager_.SetEncoderRates(rate_settings.rate_control);
1685     if (layer_allocation_changed &&
1686         allocation_cb_type_ ==
1687             BitrateAllocationCallbackType::kVideoLayersAllocation) {
1688       sink_->OnVideoLayersAllocationUpdated(CreateVideoLayersAllocation(
1689           send_codec_, rate_settings.rate_control, encoder_->GetEncoderInfo()));
1690     }
1691   }
1692   if ((allocation_cb_type_ ==
1693        BitrateAllocationCallbackType::kVideoBitrateAllocation) ||
1694       (encoder_config_.content_type ==
1695            VideoEncoderConfig::ContentType::kScreen &&
1696        allocation_cb_type_ == BitrateAllocationCallbackType::
1697                                   kVideoBitrateAllocationWhenScreenSharing)) {
1698     sink_->OnBitrateAllocationUpdated(
1699         // Update allocation according to info from encoder. An encoder may
1700         // choose to not use all layers due to for example HW.
1701         UpdateAllocationFromEncoderInfo(
1702             rate_settings.rate_control.target_bitrate,
1703             encoder_->GetEncoderInfo()));
1704   }
1705 }
1706 
MaybeEncodeVideoFrame(const VideoFrame & video_frame,int64_t time_when_posted_us)1707 void VideoStreamEncoder::MaybeEncodeVideoFrame(const VideoFrame& video_frame,
1708                                                int64_t time_when_posted_us) {
1709   RTC_DCHECK_RUN_ON(&encoder_queue_);
1710   input_state_provider_.OnFrameSizeObserved(video_frame.size());
1711 
1712   if (!last_frame_info_ || video_frame.width() != last_frame_info_->width ||
1713       video_frame.height() != last_frame_info_->height ||
1714       video_frame.is_texture() != last_frame_info_->is_texture) {
1715     if ((!last_frame_info_ || video_frame.width() != last_frame_info_->width ||
1716          video_frame.height() != last_frame_info_->height) &&
1717         settings_.encoder_switch_request_callback && encoder_selector_) {
1718       if (auto encoder = encoder_selector_->OnResolutionChange(
1719               {video_frame.width(), video_frame.height()})) {
1720         settings_.encoder_switch_request_callback->RequestEncoderSwitch(
1721             *encoder, /*allow_default_fallback=*/false);
1722       }
1723     }
1724 
1725     pending_encoder_reconfiguration_ = true;
1726     last_frame_info_ = VideoFrameInfo(video_frame.width(), video_frame.height(),
1727                                       video_frame.is_texture());
1728     RTC_LOG(LS_INFO) << "Video frame parameters changed: dimensions="
1729                      << last_frame_info_->width << "x"
1730                      << last_frame_info_->height
1731                      << ", texture=" << last_frame_info_->is_texture << ".";
1732     // Force full frame update, since resolution has changed.
1733     accumulated_update_rect_ =
1734         VideoFrame::UpdateRect{0, 0, video_frame.width(), video_frame.height()};
1735   }
1736 
1737   // We have to create the encoder before the frame drop logic,
1738   // because the latter depends on encoder_->GetScalingSettings.
1739   // According to the testcase
1740   // InitialFrameDropOffWhenEncoderDisabledScaling, the return value
1741   // from GetScalingSettings should enable or disable the frame drop.
1742 
1743   // Update input frame rate before we start using it. If we update it after
1744   // any potential frame drop we are going to artificially increase frame sizes.
1745   // Poll the rate before updating, otherwise we risk the rate being estimated
1746   // a little too high at the start of the call when then window is small.
1747   uint32_t framerate_fps = GetInputFramerateFps();
1748   frame_cadence_adapter_->UpdateFrameRate();
1749 
1750   int64_t now_ms = clock_->TimeInMilliseconds();
1751   if (pending_encoder_reconfiguration_) {
1752     ReconfigureEncoder();
1753     last_parameters_update_ms_.emplace(now_ms);
1754   } else if (!last_parameters_update_ms_ ||
1755              now_ms - *last_parameters_update_ms_ >=
1756                  kParameterUpdateIntervalMs) {
1757     if (last_encoder_rate_settings_) {
1758       // Clone rate settings before update, so that SetEncoderRates() will
1759       // actually detect the change between the input and
1760       // `last_encoder_rate_setings_`, triggering the call to SetRate() on the
1761       // encoder.
1762       EncoderRateSettings new_rate_settings = *last_encoder_rate_settings_;
1763       new_rate_settings.rate_control.framerate_fps =
1764           static_cast<double>(framerate_fps);
1765       SetEncoderRates(UpdateBitrateAllocation(new_rate_settings));
1766     }
1767     last_parameters_update_ms_.emplace(now_ms);
1768   }
1769 
1770   // Because pending frame will be dropped in any case, we need to
1771   // remember its updated region.
1772   if (pending_frame_) {
1773     encoder_stats_observer_->OnFrameDropped(
1774         VideoStreamEncoderObserver::DropReason::kEncoderQueue);
1775     accumulated_update_rect_.Union(pending_frame_->update_rect());
1776     accumulated_update_rect_is_valid_ &= pending_frame_->has_update_rect();
1777   }
1778 
1779   if (DropDueToSize(video_frame.size())) {
1780     RTC_LOG(LS_INFO) << "Dropping frame. Too large for target bitrate.";
1781     stream_resource_manager_.OnFrameDroppedDueToSize();
1782     // Storing references to a native buffer risks blocking frame capture.
1783     if (video_frame.video_frame_buffer()->type() !=
1784         VideoFrameBuffer::Type::kNative) {
1785       pending_frame_ = video_frame;
1786       pending_frame_post_time_us_ = time_when_posted_us;
1787     } else {
1788       // Ensure that any previously stored frame is dropped.
1789       pending_frame_.reset();
1790       accumulated_update_rect_.Union(video_frame.update_rect());
1791       accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
1792       encoder_stats_observer_->OnFrameDropped(
1793           VideoStreamEncoderObserver::DropReason::kEncoderQueue);
1794     }
1795     return;
1796   }
1797   stream_resource_manager_.OnMaybeEncodeFrame();
1798 
1799   if (EncoderPaused()) {
1800     // Storing references to a native buffer risks blocking frame capture.
1801     if (video_frame.video_frame_buffer()->type() !=
1802         VideoFrameBuffer::Type::kNative) {
1803       if (pending_frame_)
1804         TraceFrameDropStart();
1805       pending_frame_ = video_frame;
1806       pending_frame_post_time_us_ = time_when_posted_us;
1807     } else {
1808       // Ensure that any previously stored frame is dropped.
1809       pending_frame_.reset();
1810       TraceFrameDropStart();
1811       accumulated_update_rect_.Union(video_frame.update_rect());
1812       accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
1813       encoder_stats_observer_->OnFrameDropped(
1814           VideoStreamEncoderObserver::DropReason::kEncoderQueue);
1815     }
1816     return;
1817   }
1818 
1819   pending_frame_.reset();
1820 
1821   frame_dropper_.Leak(framerate_fps);
1822   // Frame dropping is enabled iff frame dropping is not force-disabled, and
1823   // rate controller is not trusted.
1824   const bool frame_dropping_enabled =
1825       !force_disable_frame_dropper_ &&
1826       !encoder_info_.has_trusted_rate_controller;
1827   frame_dropper_.Enable(frame_dropping_enabled);
1828   if (frame_dropping_enabled && frame_dropper_.DropFrame()) {
1829     RTC_LOG(LS_VERBOSE)
1830         << "Drop Frame: "
1831            "target bitrate "
1832         << (last_encoder_rate_settings_
1833                 ? last_encoder_rate_settings_->encoder_target.bps()
1834                 : 0)
1835         << ", input frame rate " << framerate_fps;
1836     OnDroppedFrame(
1837         EncodedImageCallback::DropReason::kDroppedByMediaOptimizations);
1838     accumulated_update_rect_.Union(video_frame.update_rect());
1839     accumulated_update_rect_is_valid_ &= video_frame.has_update_rect();
1840     return;
1841   }
1842 
1843   EncodeVideoFrame(video_frame, time_when_posted_us);
1844 }
1845 
EncodeVideoFrame(const VideoFrame & video_frame,int64_t time_when_posted_us)1846 void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
1847                                           int64_t time_when_posted_us) {
1848   RTC_DCHECK_RUN_ON(&encoder_queue_);
1849   RTC_LOG(LS_VERBOSE) << __func__ << " posted " << time_when_posted_us
1850                       << " ntp time " << video_frame.ntp_time_ms();
1851 
1852   // If the encoder fail we can't continue to encode frames. When this happens
1853   // the WebrtcVideoSender is notified and the whole VideoSendStream is
1854   // recreated.
1855   if (encoder_failed_ || !encoder_initialized_)
1856     return;
1857 
1858   // It's possible that EncodeVideoFrame can be called after we've completed
1859   // a Stop() operation. Check if the encoder_ is set before continuing.
1860   // See: bugs.webrtc.org/12857
1861   if (!encoder_)
1862     return;
1863 
1864   TraceFrameDropEnd();
1865 
1866   // Encoder metadata needs to be updated before encode complete callback.
1867   VideoEncoder::EncoderInfo info = encoder_->GetEncoderInfo();
1868   if (info.implementation_name != encoder_info_.implementation_name ||
1869       info.is_hardware_accelerated != encoder_info_.is_hardware_accelerated) {
1870     encoder_stats_observer_->OnEncoderImplementationChanged({
1871         .name = info.implementation_name,
1872         .is_hardware_accelerated = info.is_hardware_accelerated,
1873     });
1874     if (bitrate_adjuster_) {
1875       // Encoder implementation changed, reset overshoot detector states.
1876       bitrate_adjuster_->Reset();
1877     }
1878   }
1879 
1880   if (encoder_info_ != info) {
1881     OnEncoderSettingsChanged();
1882     stream_resource_manager_.ConfigureEncodeUsageResource();
1883     // Re-configure scalers when encoder info changed. Consider two cases:
1884     // 1. When the status of the scaler changes from enabled to disabled, if we
1885     // don't do this CL, scaler will adapt up/down to trigger an unnecessary
1886     // full ReconfigureEncoder() when the scaler should be banned.
1887     // 2. When the status of the scaler changes from disabled to enabled, if we
1888     // don't do this CL, scaler will not work until some code trigger
1889     // ReconfigureEncoder(). In extreme cases, the scaler doesn't even work for
1890     // a long time when we expect that the scaler should work.
1891     stream_resource_manager_.ConfigureQualityScaler(info);
1892     stream_resource_manager_.ConfigureBandwidthQualityScaler(info);
1893 
1894     RTC_LOG(LS_INFO) << "Encoder info changed to " << info.ToString();
1895   }
1896 
1897   if (bitrate_adjuster_) {
1898     for (size_t si = 0; si < kMaxSpatialLayers; ++si) {
1899       if (info.fps_allocation[si] != encoder_info_.fps_allocation[si]) {
1900         bitrate_adjuster_->OnEncoderInfo(info);
1901         break;
1902       }
1903     }
1904   }
1905   encoder_info_ = info;
1906   last_encode_info_ms_ = clock_->TimeInMilliseconds();
1907 
1908   VideoFrame out_frame(video_frame);
1909   // Crop or scale the frame if needed. Dimension may be reduced to fit encoder
1910   // requirements, e.g. some encoders may require them to be divisible by 4.
1911   if ((crop_width_ > 0 || crop_height_ > 0) &&
1912       (out_frame.video_frame_buffer()->type() !=
1913            VideoFrameBuffer::Type::kNative ||
1914        !info.supports_native_handle)) {
1915     int cropped_width = video_frame.width() - crop_width_;
1916     int cropped_height = video_frame.height() - crop_height_;
1917     rtc::scoped_refptr<VideoFrameBuffer> cropped_buffer;
1918     // TODO(ilnik): Remove scaling if cropping is too big, as it should never
1919     // happen after SinkWants signaled correctly from ReconfigureEncoder.
1920     VideoFrame::UpdateRect update_rect = video_frame.update_rect();
1921     if (crop_width_ < 4 && crop_height_ < 4) {
1922       // The difference is small, crop without scaling.
1923       cropped_buffer = video_frame.video_frame_buffer()->CropAndScale(
1924           crop_width_ / 2, crop_height_ / 2, cropped_width, cropped_height,
1925           cropped_width, cropped_height);
1926       update_rect.offset_x -= crop_width_ / 2;
1927       update_rect.offset_y -= crop_height_ / 2;
1928       update_rect.Intersect(
1929           VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height});
1930 
1931     } else {
1932       // The difference is large, scale it.
1933       cropped_buffer = video_frame.video_frame_buffer()->Scale(cropped_width,
1934                                                                cropped_height);
1935       if (!update_rect.IsEmpty()) {
1936         // Since we can't reason about pixels after scaling, we invalidate whole
1937         // picture, if anything changed.
1938         update_rect =
1939             VideoFrame::UpdateRect{0, 0, cropped_width, cropped_height};
1940       }
1941     }
1942     if (!cropped_buffer) {
1943       RTC_LOG(LS_ERROR) << "Cropping and scaling frame failed, dropping frame.";
1944       return;
1945     }
1946 
1947     out_frame.set_video_frame_buffer(cropped_buffer);
1948     out_frame.set_update_rect(update_rect);
1949     out_frame.set_ntp_time_ms(video_frame.ntp_time_ms());
1950     // Since accumulated_update_rect_ is constructed before cropping,
1951     // we can't trust it. If any changes were pending, we invalidate whole
1952     // frame here.
1953     if (!accumulated_update_rect_.IsEmpty()) {
1954       accumulated_update_rect_ =
1955           VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()};
1956       accumulated_update_rect_is_valid_ = false;
1957     }
1958   }
1959 
1960   if (!accumulated_update_rect_is_valid_) {
1961     out_frame.clear_update_rect();
1962   } else if (!accumulated_update_rect_.IsEmpty() &&
1963              out_frame.has_update_rect()) {
1964     accumulated_update_rect_.Union(out_frame.update_rect());
1965     accumulated_update_rect_.Intersect(
1966         VideoFrame::UpdateRect{0, 0, out_frame.width(), out_frame.height()});
1967     out_frame.set_update_rect(accumulated_update_rect_);
1968     accumulated_update_rect_.MakeEmptyUpdate();
1969   }
1970   accumulated_update_rect_is_valid_ = true;
1971 
1972   TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(),
1973                           "Encode");
1974 
1975   stream_resource_manager_.OnEncodeStarted(out_frame, time_when_posted_us);
1976 
1977   // The encoder should get the size that it expects.
1978   RTC_DCHECK(send_codec_.width <= out_frame.width() &&
1979              send_codec_.height <= out_frame.height())
1980       << "Encoder configured to " << send_codec_.width << "x"
1981       << send_codec_.height << " received a too small frame "
1982       << out_frame.width() << "x" << out_frame.height();
1983 
1984   TRACE_EVENT1("webrtc", "VCMGenericEncoder::Encode", "timestamp",
1985                out_frame.timestamp());
1986 
1987   frame_encode_metadata_writer_.OnEncodeStarted(out_frame);
1988 
1989   const int32_t encode_status = encoder_->Encode(out_frame, &next_frame_types_);
1990   was_encode_called_since_last_initialization_ = true;
1991 
1992   if (encode_status < 0) {
1993     RTC_LOG(LS_ERROR) << "Encoder failed, failing encoder format: "
1994                       << encoder_config_.video_format.ToString();
1995     RequestEncoderSwitch();
1996     return;
1997   }
1998 
1999   for (auto& it : next_frame_types_) {
2000     it = VideoFrameType::kVideoFrameDelta;
2001   }
2002 }
2003 
RequestRefreshFrame()2004 void VideoStreamEncoder::RequestRefreshFrame() {
2005   worker_queue_->PostTask(SafeTask(task_safety_.flag(), [this] {
2006     RTC_DCHECK_RUN_ON(worker_queue_);
2007     video_source_sink_controller_.RequestRefreshFrame();
2008   }));
2009 }
2010 
SendKeyFrame(const std::vector<VideoFrameType> & layers)2011 void VideoStreamEncoder::SendKeyFrame(
2012     const std::vector<VideoFrameType>& layers) {
2013   if (!encoder_queue_.IsCurrent()) {
2014     encoder_queue_.PostTask([this, layers] { SendKeyFrame(layers); });
2015     return;
2016   }
2017   RTC_DCHECK_RUN_ON(&encoder_queue_);
2018   TRACE_EVENT0("webrtc", "OnKeyFrameRequest");
2019   RTC_DCHECK(!next_frame_types_.empty());
2020 
2021   if (frame_cadence_adapter_)
2022     frame_cadence_adapter_->ProcessKeyFrameRequest();
2023 
2024   if (!encoder_) {
2025     RTC_DLOG(LS_INFO) << __func__ << " no encoder.";
2026     return;  // Shutting down, or not configured yet.
2027   }
2028 
2029   if (!layers.empty()) {
2030     RTC_DCHECK_EQ(layers.size(), next_frame_types_.size());
2031     for (size_t i = 0; i < layers.size() && i < next_frame_types_.size(); i++) {
2032       next_frame_types_[i] = layers[i];
2033     }
2034   } else {
2035     std::fill(next_frame_types_.begin(), next_frame_types_.end(),
2036               VideoFrameType::kVideoFrameKey);
2037   }
2038 }
2039 
OnLossNotification(const VideoEncoder::LossNotification & loss_notification)2040 void VideoStreamEncoder::OnLossNotification(
2041     const VideoEncoder::LossNotification& loss_notification) {
2042   if (!encoder_queue_.IsCurrent()) {
2043     encoder_queue_.PostTask(
2044         [this, loss_notification] { OnLossNotification(loss_notification); });
2045     return;
2046   }
2047 
2048   RTC_DCHECK_RUN_ON(&encoder_queue_);
2049   if (encoder_) {
2050     encoder_->OnLossNotification(loss_notification);
2051   }
2052 }
2053 
AugmentEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info)2054 EncodedImage VideoStreamEncoder::AugmentEncodedImage(
2055     const EncodedImage& encoded_image,
2056     const CodecSpecificInfo* codec_specific_info) {
2057   EncodedImage image_copy(encoded_image);
2058   const size_t spatial_idx = encoded_image.SpatialIndex().value_or(0);
2059   frame_encode_metadata_writer_.FillTimingInfo(spatial_idx, &image_copy);
2060   frame_encode_metadata_writer_.UpdateBitstream(codec_specific_info,
2061                                                 &image_copy);
2062   VideoCodecType codec_type = codec_specific_info
2063                                   ? codec_specific_info->codecType
2064                                   : VideoCodecType::kVideoCodecGeneric;
2065   if (image_copy.qp_ < 0 && qp_parsing_allowed_) {
2066     // Parse encoded frame QP if that was not provided by encoder.
2067     image_copy.qp_ = qp_parser_
2068                          .Parse(codec_type, spatial_idx, image_copy.data(),
2069                                 image_copy.size())
2070                          .value_or(-1);
2071   }
2072   RTC_LOG(LS_VERBOSE) << __func__ << " spatial_idx " << spatial_idx << " qp "
2073                       << image_copy.qp_;
2074   image_copy.SetAtTargetQuality(codec_type == kVideoCodecVP8 &&
2075                                 image_copy.qp_ <= kVp8SteadyStateQpThreshold);
2076 
2077   // Piggyback ALR experiment group id and simulcast id into the content type.
2078   const uint8_t experiment_id =
2079       experiment_groups_[videocontenttypehelpers::IsScreenshare(
2080           image_copy.content_type_)];
2081 
2082   // TODO(ilnik): This will force content type extension to be present even
2083   // for realtime video. At the expense of miniscule overhead we will get
2084   // sliced receive statistics.
2085   RTC_CHECK(videocontenttypehelpers::SetExperimentId(&image_copy.content_type_,
2086                                                      experiment_id));
2087   // We count simulcast streams from 1 on the wire. That's why we set simulcast
2088   // id in content type to +1 of that is actual simulcast index. This is because
2089   // value 0 on the wire is reserved for 'no simulcast stream specified'.
2090   RTC_CHECK(videocontenttypehelpers::SetSimulcastId(
2091       &image_copy.content_type_, static_cast<uint8_t>(spatial_idx + 1)));
2092 
2093   return image_copy;
2094 }
2095 
OnEncodedImage(const EncodedImage & encoded_image,const CodecSpecificInfo * codec_specific_info)2096 EncodedImageCallback::Result VideoStreamEncoder::OnEncodedImage(
2097     const EncodedImage& encoded_image,
2098     const CodecSpecificInfo* codec_specific_info) {
2099   TRACE_EVENT_INSTANT1("webrtc", "VCMEncodedFrameCallback::Encoded",
2100                        "timestamp", encoded_image.Timestamp());
2101 
2102   // TODO(bugs.webrtc.org/10520): Signal the simulcast id explicitly.
2103 
2104   const size_t spatial_idx = encoded_image.SpatialIndex().value_or(0);
2105   const VideoCodecType codec_type = codec_specific_info
2106                                         ? codec_specific_info->codecType
2107                                         : VideoCodecType::kVideoCodecGeneric;
2108   EncodedImage image_copy =
2109       AugmentEncodedImage(encoded_image, codec_specific_info);
2110 
2111   // Post a task because `send_codec_` requires `encoder_queue_` lock and we
2112   // need to update on quality convergence.
2113   unsigned int image_width = image_copy._encodedWidth;
2114   unsigned int image_height = image_copy._encodedHeight;
2115   encoder_queue_.PostTask([this, codec_type, image_width, image_height,
2116                            spatial_idx,
2117                            at_target_quality = image_copy.IsAtTargetQuality()] {
2118     RTC_DCHECK_RUN_ON(&encoder_queue_);
2119 
2120     // Let the frame cadence adapter know about quality convergence.
2121     if (frame_cadence_adapter_)
2122       frame_cadence_adapter_->UpdateLayerQualityConvergence(spatial_idx,
2123                                                             at_target_quality);
2124 
2125     // Currently, the internal quality scaler is used for VP9 instead of the
2126     // webrtc qp scaler (in the no-svc case or if only a single spatial layer is
2127     // encoded). It has to be explicitly detected and reported to adaptation
2128     // metrics.
2129     if (codec_type == VideoCodecType::kVideoCodecVP9 &&
2130         send_codec_.VP9()->automaticResizeOn) {
2131       unsigned int expected_width = send_codec_.width;
2132       unsigned int expected_height = send_codec_.height;
2133       int num_active_layers = 0;
2134       for (int i = 0; i < send_codec_.VP9()->numberOfSpatialLayers; ++i) {
2135         if (send_codec_.spatialLayers[i].active) {
2136           ++num_active_layers;
2137           expected_width = send_codec_.spatialLayers[i].width;
2138           expected_height = send_codec_.spatialLayers[i].height;
2139         }
2140       }
2141       RTC_DCHECK_LE(num_active_layers, 1)
2142           << "VP9 quality scaling is enabled for "
2143              "SVC with several active layers.";
2144       encoder_stats_observer_->OnEncoderInternalScalerUpdate(
2145           image_width < expected_width || image_height < expected_height);
2146     }
2147   });
2148 
2149   // Encoded is called on whatever thread the real encoder implementation run
2150   // on. In the case of hardware encoders, there might be several encoders
2151   // running in parallel on different threads.
2152   encoder_stats_observer_->OnSendEncodedImage(image_copy, codec_specific_info);
2153 
2154   EncodedImageCallback::Result result =
2155       sink_->OnEncodedImage(image_copy, codec_specific_info);
2156 
2157   // We are only interested in propagating the meta-data about the image, not
2158   // encoded data itself, to the post encode function. Since we cannot be sure
2159   // the pointer will still be valid when run on the task queue, set it to null.
2160   DataSize frame_size = DataSize::Bytes(image_copy.size());
2161   image_copy.ClearEncodedData();
2162 
2163   int temporal_index = 0;
2164   if (codec_specific_info) {
2165     if (codec_specific_info->codecType == kVideoCodecVP9) {
2166       temporal_index = codec_specific_info->codecSpecific.VP9.temporal_idx;
2167     } else if (codec_specific_info->codecType == kVideoCodecVP8) {
2168       temporal_index = codec_specific_info->codecSpecific.VP8.temporalIdx;
2169     }
2170   }
2171   if (temporal_index == kNoTemporalIdx) {
2172     temporal_index = 0;
2173   }
2174 
2175   RunPostEncode(image_copy, clock_->CurrentTime().us(), temporal_index,
2176                 frame_size);
2177 
2178   if (result.error == Result::OK) {
2179     // In case of an internal encoder running on a separate thread, the
2180     // decision to drop a frame might be a frame late and signaled via
2181     // atomic flag. This is because we can't easily wait for the worker thread
2182     // without risking deadlocks, eg during shutdown when the worker thread
2183     // might be waiting for the internal encoder threads to stop.
2184     if (pending_frame_drops_.load() > 0) {
2185       int pending_drops = pending_frame_drops_.fetch_sub(1);
2186       RTC_DCHECK_GT(pending_drops, 0);
2187       result.drop_next_frame = true;
2188     }
2189   }
2190 
2191   return result;
2192 }
2193 
OnDroppedFrame(DropReason reason)2194 void VideoStreamEncoder::OnDroppedFrame(DropReason reason) {
2195   switch (reason) {
2196     case DropReason::kDroppedByMediaOptimizations:
2197       encoder_stats_observer_->OnFrameDropped(
2198           VideoStreamEncoderObserver::DropReason::kMediaOptimization);
2199       break;
2200     case DropReason::kDroppedByEncoder:
2201       encoder_stats_observer_->OnFrameDropped(
2202           VideoStreamEncoderObserver::DropReason::kEncoder);
2203       break;
2204   }
2205   sink_->OnDroppedFrame(reason);
2206   encoder_queue_.PostTask([this, reason] {
2207     RTC_DCHECK_RUN_ON(&encoder_queue_);
2208     stream_resource_manager_.OnFrameDropped(reason);
2209   });
2210 }
2211 
UpdateTargetBitrate(DataRate target_bitrate,double cwnd_reduce_ratio)2212 DataRate VideoStreamEncoder::UpdateTargetBitrate(DataRate target_bitrate,
2213                                                  double cwnd_reduce_ratio) {
2214   RTC_DCHECK_RUN_ON(&encoder_queue_);
2215   DataRate updated_target_bitrate = target_bitrate;
2216 
2217   // Drop frames when congestion window pushback ratio is larger than 1
2218   // percent and target bitrate is larger than codec min bitrate.
2219   // When target_bitrate is 0 means codec is paused, skip frame dropping.
2220   if (cwnd_reduce_ratio > 0.01 && target_bitrate.bps() > 0 &&
2221       target_bitrate.bps() > send_codec_.minBitrate * 1000) {
2222     int reduce_bitrate_bps = std::min(
2223         static_cast<int>(target_bitrate.bps() * cwnd_reduce_ratio),
2224         static_cast<int>(target_bitrate.bps() - send_codec_.minBitrate * 1000));
2225     if (reduce_bitrate_bps > 0) {
2226       // At maximum the congestion window can drop 1/2 frames.
2227       cwnd_frame_drop_interval_ = std::max(
2228           2, static_cast<int>(target_bitrate.bps() / reduce_bitrate_bps));
2229       // Reduce target bitrate accordingly.
2230       updated_target_bitrate =
2231           target_bitrate - (target_bitrate / cwnd_frame_drop_interval_.value());
2232       return updated_target_bitrate;
2233     }
2234   }
2235   cwnd_frame_drop_interval_.reset();
2236   return updated_target_bitrate;
2237 }
2238 
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)2239 void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
2240                                           DataRate stable_target_bitrate,
2241                                           DataRate link_allocation,
2242                                           uint8_t fraction_lost,
2243                                           int64_t round_trip_time_ms,
2244                                           double cwnd_reduce_ratio) {
2245   RTC_DCHECK_GE(link_allocation, target_bitrate);
2246   if (!encoder_queue_.IsCurrent()) {
2247     encoder_queue_.PostTask([this, target_bitrate, stable_target_bitrate,
2248                              link_allocation, fraction_lost, round_trip_time_ms,
2249                              cwnd_reduce_ratio] {
2250       DataRate updated_target_bitrate =
2251           UpdateTargetBitrate(target_bitrate, cwnd_reduce_ratio);
2252       OnBitrateUpdated(updated_target_bitrate, stable_target_bitrate,
2253                        link_allocation, fraction_lost, round_trip_time_ms,
2254                        cwnd_reduce_ratio);
2255     });
2256     return;
2257   }
2258   RTC_DCHECK_RUN_ON(&encoder_queue_);
2259 
2260   const bool video_is_suspended = target_bitrate == DataRate::Zero();
2261   const bool video_suspension_changed = video_is_suspended != EncoderPaused();
2262 
2263   if (!video_is_suspended && settings_.encoder_switch_request_callback &&
2264       encoder_selector_) {
2265     if (auto encoder = encoder_selector_->OnAvailableBitrate(link_allocation)) {
2266       settings_.encoder_switch_request_callback->RequestEncoderSwitch(
2267           *encoder, /*allow_default_fallback=*/false);
2268     }
2269   }
2270 
2271   RTC_DCHECK(sink_) << "sink_ must be set before the encoder is active.";
2272 
2273   RTC_LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate " << target_bitrate.bps()
2274                       << " stable bitrate = " << stable_target_bitrate.bps()
2275                       << " link allocation bitrate = " << link_allocation.bps()
2276                       << " packet loss " << static_cast<int>(fraction_lost)
2277                       << " rtt " << round_trip_time_ms;
2278 
2279   if (encoder_) {
2280     encoder_->OnPacketLossRateUpdate(static_cast<float>(fraction_lost) / 256.f);
2281     encoder_->OnRttUpdate(round_trip_time_ms);
2282   }
2283 
2284   uint32_t framerate_fps = GetInputFramerateFps();
2285   frame_dropper_.SetRates((target_bitrate.bps() + 500) / 1000, framerate_fps);
2286 
2287   EncoderRateSettings new_rate_settings{
2288       VideoBitrateAllocation(), static_cast<double>(framerate_fps),
2289       link_allocation, target_bitrate, stable_target_bitrate};
2290   SetEncoderRates(UpdateBitrateAllocation(new_rate_settings));
2291 
2292   if (target_bitrate.bps() != 0)
2293     encoder_target_bitrate_bps_ = target_bitrate.bps();
2294 
2295   stream_resource_manager_.SetTargetBitrate(target_bitrate);
2296 
2297   if (video_suspension_changed) {
2298     RTC_LOG(LS_INFO) << "Video suspend state changed to: "
2299                      << (video_is_suspended ? "suspended" : "not suspended");
2300     encoder_stats_observer_->OnSuspendChange(video_is_suspended);
2301 
2302     if (!video_is_suspended && pending_frame_ &&
2303         !DropDueToSize(pending_frame_->size())) {
2304       // A pending stored frame can be processed.
2305       int64_t pending_time_us =
2306           clock_->CurrentTime().us() - pending_frame_post_time_us_;
2307       if (pending_time_us < kPendingFrameTimeoutMs * 1000)
2308         EncodeVideoFrame(*pending_frame_, pending_frame_post_time_us_);
2309       pending_frame_.reset();
2310     } else if (!video_is_suspended && !pending_frame_ &&
2311                encoder_paused_and_dropped_frame_) {
2312       // A frame was enqueued during pause-state, but since it was a native
2313       // frame we could not store it in `pending_frame_` so request a
2314       // refresh-frame instead.
2315       RequestRefreshFrame();
2316     }
2317   }
2318 }
2319 
DropDueToSize(uint32_t pixel_count) const2320 bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const {
2321   if (!encoder_ || !stream_resource_manager_.DropInitialFrames() ||
2322       !encoder_target_bitrate_bps_.has_value()) {
2323     return false;
2324   }
2325 
2326   bool simulcast_or_svc =
2327       (send_codec_.codecType == VideoCodecType::kVideoCodecVP9 &&
2328        send_codec_.VP9().numberOfSpatialLayers > 1) ||
2329       (send_codec_.numberOfSimulcastStreams > 1 ||
2330        encoder_config_.simulcast_layers.size() > 1);
2331 
2332   if (simulcast_or_svc) {
2333     if (stream_resource_manager_.SingleActiveStreamPixels()) {
2334       pixel_count = stream_resource_manager_.SingleActiveStreamPixels().value();
2335     } else {
2336       return false;
2337     }
2338   }
2339 
2340   uint32_t bitrate_bps =
2341       stream_resource_manager_.UseBandwidthAllocationBps().value_or(
2342           encoder_target_bitrate_bps_.value());
2343 
2344   absl::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
2345       GetEncoderInfoWithBitrateLimitUpdate(
2346           encoder_->GetEncoderInfo(), encoder_config_, default_limits_allowed_)
2347           .GetEncoderBitrateLimitsForResolution(pixel_count);
2348 
2349   if (encoder_bitrate_limits.has_value()) {
2350     // Use bitrate limits provided by encoder.
2351     return bitrate_bps <
2352            static_cast<uint32_t>(encoder_bitrate_limits->min_start_bitrate_bps);
2353   }
2354 
2355   if (bitrate_bps < 300000 /* qvga */) {
2356     return pixel_count > 320 * 240;
2357   } else if (bitrate_bps < 500000 /* vga */) {
2358     return pixel_count > 640 * 480;
2359   }
2360   return false;
2361 }
2362 
OnVideoSourceRestrictionsUpdated(VideoSourceRestrictions restrictions,const VideoAdaptationCounters & adaptation_counters,rtc::scoped_refptr<Resource> reason,const VideoSourceRestrictions & unfiltered_restrictions)2363 void VideoStreamEncoder::OnVideoSourceRestrictionsUpdated(
2364     VideoSourceRestrictions restrictions,
2365     const VideoAdaptationCounters& adaptation_counters,
2366     rtc::scoped_refptr<Resource> reason,
2367     const VideoSourceRestrictions& unfiltered_restrictions) {
2368   RTC_DCHECK_RUN_ON(&encoder_queue_);
2369   RTC_LOG(LS_INFO) << "Updating sink restrictions from "
2370                    << (reason ? reason->Name() : std::string("<null>"))
2371                    << " to " << restrictions.ToString();
2372 
2373   // TODO(webrtc:14451) Split video_source_sink_controller_
2374   // so that ownership on restrictions/wants is kept on &encoder_queue_
2375   latest_restrictions_ = restrictions;
2376 
2377   worker_queue_->PostTask(SafeTask(
2378       task_safety_.flag(), [this, restrictions = std::move(restrictions)]() {
2379         RTC_DCHECK_RUN_ON(worker_queue_);
2380         video_source_sink_controller_.SetRestrictions(std::move(restrictions));
2381         video_source_sink_controller_.PushSourceSinkSettings();
2382       }));
2383 }
2384 
RunPostEncode(const EncodedImage & encoded_image,int64_t time_sent_us,int temporal_index,DataSize frame_size)2385 void VideoStreamEncoder::RunPostEncode(const EncodedImage& encoded_image,
2386                                        int64_t time_sent_us,
2387                                        int temporal_index,
2388                                        DataSize frame_size) {
2389   if (!encoder_queue_.IsCurrent()) {
2390     encoder_queue_.PostTask([this, encoded_image, time_sent_us, temporal_index,
2391                              frame_size] {
2392       RunPostEncode(encoded_image, time_sent_us, temporal_index, frame_size);
2393     });
2394     return;
2395   }
2396 
2397   RTC_DCHECK_RUN_ON(&encoder_queue_);
2398 
2399   absl::optional<int> encode_duration_us;
2400   if (encoded_image.timing_.flags != VideoSendTiming::kInvalid) {
2401     encode_duration_us =
2402         TimeDelta::Millis(encoded_image.timing_.encode_finish_ms -
2403                           encoded_image.timing_.encode_start_ms)
2404             .us();
2405   }
2406 
2407   // Run post encode tasks, such as overuse detection and frame rate/drop
2408   // stats for internal encoders.
2409   const bool keyframe =
2410       encoded_image._frameType == VideoFrameType::kVideoFrameKey;
2411 
2412   if (!frame_size.IsZero()) {
2413     frame_dropper_.Fill(frame_size.bytes(), !keyframe);
2414   }
2415 
2416   stream_resource_manager_.OnEncodeCompleted(encoded_image, time_sent_us,
2417                                              encode_duration_us, frame_size);
2418   if (bitrate_adjuster_) {
2419     bitrate_adjuster_->OnEncodedFrame(
2420         frame_size, encoded_image.SpatialIndex().value_or(0), temporal_index);
2421   }
2422 }
2423 
ReleaseEncoder()2424 void VideoStreamEncoder::ReleaseEncoder() {
2425   if (!encoder_ || !encoder_initialized_) {
2426     return;
2427   }
2428   encoder_->Release();
2429   encoder_initialized_ = false;
2430   TRACE_EVENT0("webrtc", "VCMGenericEncoder::Release");
2431 }
2432 
2433 VideoStreamEncoder::AutomaticAnimationDetectionExperiment
ParseAutomatincAnimationDetectionFieldTrial() const2434 VideoStreamEncoder::ParseAutomatincAnimationDetectionFieldTrial() const {
2435   AutomaticAnimationDetectionExperiment result;
2436 
2437   result.Parser()->Parse(
2438       field_trials_.Lookup("WebRTC-AutomaticAnimationDetectionScreenshare"));
2439 
2440   if (!result.enabled) {
2441     RTC_LOG(LS_INFO) << "Automatic animation detection experiment is disabled.";
2442     return result;
2443   }
2444 
2445   RTC_LOG(LS_INFO) << "Automatic animation detection experiment settings:"
2446                       " min_duration_ms="
2447                    << result.min_duration_ms
2448                    << " min_area_ration=" << result.min_area_ratio
2449                    << " min_fps=" << result.min_fps;
2450 
2451   return result;
2452 }
2453 
CheckForAnimatedContent(const VideoFrame & frame,int64_t time_when_posted_in_us)2454 void VideoStreamEncoder::CheckForAnimatedContent(
2455     const VideoFrame& frame,
2456     int64_t time_when_posted_in_us) {
2457   if (!automatic_animation_detection_experiment_.enabled ||
2458       encoder_config_.content_type !=
2459           VideoEncoderConfig::ContentType::kScreen ||
2460       stream_resource_manager_.degradation_preference() !=
2461           DegradationPreference::BALANCED) {
2462     return;
2463   }
2464 
2465   if (expect_resize_state_ == ExpectResizeState::kResize && last_frame_info_ &&
2466       last_frame_info_->width != frame.width() &&
2467       last_frame_info_->height != frame.height()) {
2468     // On applying resolution cap there will be one frame with no/different
2469     // update, which should be skipped.
2470     // It can be delayed by several frames.
2471     expect_resize_state_ = ExpectResizeState::kFirstFrameAfterResize;
2472     return;
2473   }
2474 
2475   if (expect_resize_state_ == ExpectResizeState::kFirstFrameAfterResize) {
2476     // The first frame after resize should have new, scaled update_rect.
2477     if (frame.has_update_rect()) {
2478       last_update_rect_ = frame.update_rect();
2479     } else {
2480       last_update_rect_ = absl::nullopt;
2481     }
2482     expect_resize_state_ = ExpectResizeState::kNoResize;
2483   }
2484 
2485   bool should_cap_resolution = false;
2486   if (!frame.has_update_rect()) {
2487     last_update_rect_ = absl::nullopt;
2488     animation_start_time_ = Timestamp::PlusInfinity();
2489   } else if ((!last_update_rect_ ||
2490               frame.update_rect() != *last_update_rect_)) {
2491     last_update_rect_ = frame.update_rect();
2492     animation_start_time_ = Timestamp::Micros(time_when_posted_in_us);
2493   } else {
2494     TimeDelta animation_duration =
2495         Timestamp::Micros(time_when_posted_in_us) - animation_start_time_;
2496     float area_ratio = static_cast<float>(last_update_rect_->width *
2497                                           last_update_rect_->height) /
2498                        (frame.width() * frame.height());
2499     if (animation_duration.ms() >=
2500             automatic_animation_detection_experiment_.min_duration_ms &&
2501         area_ratio >=
2502             automatic_animation_detection_experiment_.min_area_ratio &&
2503         encoder_stats_observer_->GetInputFrameRate() >=
2504             automatic_animation_detection_experiment_.min_fps) {
2505       should_cap_resolution = true;
2506     }
2507   }
2508   if (cap_resolution_due_to_video_content_ != should_cap_resolution) {
2509     expect_resize_state_ = should_cap_resolution ? ExpectResizeState::kResize
2510                                                  : ExpectResizeState::kNoResize;
2511     cap_resolution_due_to_video_content_ = should_cap_resolution;
2512     if (should_cap_resolution) {
2513       RTC_LOG(LS_INFO) << "Applying resolution cap due to animation detection.";
2514     } else {
2515       RTC_LOG(LS_INFO) << "Removing resolution cap due to no consistent "
2516                           "animation detection.";
2517     }
2518     // TODO(webrtc:14451) Split video_source_sink_controller_
2519     // so that ownership on restrictions/wants is kept on &encoder_queue_
2520     if (should_cap_resolution) {
2521       animate_restrictions_ =
2522           VideoSourceRestrictions(kMaxAnimationPixels,
2523                                   /* target_pixels_per_frame= */ absl::nullopt,
2524                                   /* max_frame_rate= */ absl::nullopt);
2525     } else {
2526       animate_restrictions_.reset();
2527     }
2528 
2529     worker_queue_->PostTask(
2530         SafeTask(task_safety_.flag(), [this, should_cap_resolution]() {
2531           RTC_DCHECK_RUN_ON(worker_queue_);
2532           video_source_sink_controller_.SetPixelsPerFrameUpperLimit(
2533               should_cap_resolution
2534                   ? absl::optional<size_t>(kMaxAnimationPixels)
2535                   : absl::nullopt);
2536           video_source_sink_controller_.PushSourceSinkSettings();
2537         }));
2538   }
2539 }
2540 
InjectAdaptationResource(rtc::scoped_refptr<Resource> resource,VideoAdaptationReason reason)2541 void VideoStreamEncoder::InjectAdaptationResource(
2542     rtc::scoped_refptr<Resource> resource,
2543     VideoAdaptationReason reason) {
2544   encoder_queue_.PostTask([this, resource = std::move(resource), reason] {
2545     RTC_DCHECK_RUN_ON(&encoder_queue_);
2546     additional_resources_.push_back(resource);
2547     stream_resource_manager_.AddResource(resource, reason);
2548   });
2549 }
2550 
InjectAdaptationConstraint(AdaptationConstraint * adaptation_constraint)2551 void VideoStreamEncoder::InjectAdaptationConstraint(
2552     AdaptationConstraint* adaptation_constraint) {
2553   rtc::Event event;
2554   encoder_queue_.PostTask([this, adaptation_constraint, &event] {
2555     RTC_DCHECK_RUN_ON(&encoder_queue_);
2556     if (!resource_adaptation_processor_) {
2557       // The VideoStreamEncoder was stopped and the processor destroyed before
2558       // this task had a chance to execute. No action needed.
2559       return;
2560     }
2561     adaptation_constraints_.push_back(adaptation_constraint);
2562     video_stream_adapter_->AddAdaptationConstraint(adaptation_constraint);
2563     event.Set();
2564   });
2565   event.Wait(rtc::Event::kForever);
2566 }
2567 
AddRestrictionsListenerForTesting(VideoSourceRestrictionsListener * restrictions_listener)2568 void VideoStreamEncoder::AddRestrictionsListenerForTesting(
2569     VideoSourceRestrictionsListener* restrictions_listener) {
2570   rtc::Event event;
2571   encoder_queue_.PostTask([this, restrictions_listener, &event] {
2572     RTC_DCHECK_RUN_ON(&encoder_queue_);
2573     RTC_DCHECK(resource_adaptation_processor_);
2574     video_stream_adapter_->AddRestrictionsListener(restrictions_listener);
2575     event.Set();
2576   });
2577   event.Wait(rtc::Event::kForever);
2578 }
2579 
RemoveRestrictionsListenerForTesting(VideoSourceRestrictionsListener * restrictions_listener)2580 void VideoStreamEncoder::RemoveRestrictionsListenerForTesting(
2581     VideoSourceRestrictionsListener* restrictions_listener) {
2582   rtc::Event event;
2583   encoder_queue_.PostTask([this, restrictions_listener, &event] {
2584     RTC_DCHECK_RUN_ON(&encoder_queue_);
2585     RTC_DCHECK(resource_adaptation_processor_);
2586     video_stream_adapter_->RemoveRestrictionsListener(restrictions_listener);
2587     event.Set();
2588   });
2589   event.Wait(rtc::Event::kForever);
2590 }
2591 
2592 }  // namespace webrtc
2593