xref: /aosp_15_r20/external/webrtc/modules/video_coding/utility/bandwidth_quality_scaler.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2021 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 "modules/video_coding/utility/bandwidth_quality_scaler.h"
12 
13 #include <algorithm>
14 #include <memory>
15 #include <utility>
16 #include <vector>
17 
18 #include "api/video/video_adaptation_reason.h"
19 #include "api/video_codecs/video_encoder.h"
20 #include "rtc_base/checks.h"
21 #include "rtc_base/experiments/bandwidth_quality_scaler_settings.h"
22 #include "rtc_base/logging.h"
23 #include "rtc_base/numerics/exp_filter.h"
24 #include "rtc_base/time_utils.h"
25 #include "rtc_base/weak_ptr.h"
26 
27 namespace webrtc {
28 
29 namespace {
30 
31 constexpr int kDefaultMaxWindowSizeMs = 5000;
32 constexpr float kHigherMaxBitrateTolerationFactor = 0.95;
33 constexpr float kLowerMinBitrateTolerationFactor = 0.8;
34 constexpr int kDefaultBitrateStateUpdateIntervalSeconds = 5;
35 }  // namespace
36 
BandwidthQualityScaler(BandwidthQualityScalerUsageHandlerInterface * handler)37 BandwidthQualityScaler::BandwidthQualityScaler(
38     BandwidthQualityScalerUsageHandlerInterface* handler)
39     : kBitrateStateUpdateInterval(TimeDelta::Seconds(
40           BandwidthQualityScalerSettings::ParseFromFieldTrials()
41               .BitrateStateUpdateInterval()
42               .value_or(kDefaultBitrateStateUpdateIntervalSeconds))),
43       handler_(handler),
44       encoded_bitrate_(kDefaultMaxWindowSizeMs, RateStatistics::kBpsScale),
45       weak_ptr_factory_(this) {
46   RTC_DCHECK_RUN_ON(&task_checker_);
47   RTC_DCHECK(handler_ != nullptr);
48 
49   StartCheckForBitrate();
50 }
51 
~BandwidthQualityScaler()52 BandwidthQualityScaler::~BandwidthQualityScaler() {
53   RTC_DCHECK_RUN_ON(&task_checker_);
54 }
55 
StartCheckForBitrate()56 void BandwidthQualityScaler::StartCheckForBitrate() {
57   RTC_DCHECK_RUN_ON(&task_checker_);
58   TaskQueueBase::Current()->PostDelayedTask(
59       [this_weak_ptr = weak_ptr_factory_.GetWeakPtr(), this] {
60         if (!this_weak_ptr) {
61           // The caller BandwidthQualityScaler has been deleted.
62           return;
63         }
64         RTC_DCHECK_RUN_ON(&task_checker_);
65         switch (CheckBitrate()) {
66           case BandwidthQualityScaler::CheckBitrateResult::kHighBitRate: {
67             handler_->OnReportUsageBandwidthHigh();
68             last_frame_size_pixels_.reset();
69             break;
70           }
71           case BandwidthQualityScaler::CheckBitrateResult::kLowBitRate: {
72             handler_->OnReportUsageBandwidthLow();
73             last_frame_size_pixels_.reset();
74             break;
75           }
76           case BandwidthQualityScaler::CheckBitrateResult::kNormalBitrate: {
77             break;
78           }
79           case BandwidthQualityScaler::CheckBitrateResult::
80               kInsufficientSamples: {
81             break;
82           }
83         }
84         StartCheckForBitrate();
85       },
86       kBitrateStateUpdateInterval);
87 }
88 
ReportEncodeInfo(int frame_size_bytes,int64_t time_sent_in_ms,uint32_t encoded_width,uint32_t encoded_height)89 void BandwidthQualityScaler::ReportEncodeInfo(int frame_size_bytes,
90                                               int64_t time_sent_in_ms,
91                                               uint32_t encoded_width,
92                                               uint32_t encoded_height) {
93   RTC_DCHECK_RUN_ON(&task_checker_);
94   last_time_sent_in_ms_ = time_sent_in_ms;
95   last_frame_size_pixels_ = encoded_width * encoded_height;
96   encoded_bitrate_.Update(frame_size_bytes, time_sent_in_ms);
97 }
98 
SetResolutionBitrateLimits(const std::vector<VideoEncoder::ResolutionBitrateLimits> & resolution_bitrate_limits)99 void BandwidthQualityScaler::SetResolutionBitrateLimits(
100     const std::vector<VideoEncoder::ResolutionBitrateLimits>&
101         resolution_bitrate_limits) {
102   if (resolution_bitrate_limits.empty()) {
103     resolution_bitrate_limits_ = EncoderInfoSettings::
104         GetDefaultSinglecastBitrateLimitsWhenQpIsUntrusted();
105   } else {
106     resolution_bitrate_limits_ = resolution_bitrate_limits;
107   }
108 }
109 
110 BandwidthQualityScaler::CheckBitrateResult
CheckBitrate()111 BandwidthQualityScaler::CheckBitrate() {
112   RTC_DCHECK_RUN_ON(&task_checker_);
113   if (!last_frame_size_pixels_.has_value() ||
114       !last_time_sent_in_ms_.has_value()) {
115     return BandwidthQualityScaler::CheckBitrateResult::kInsufficientSamples;
116   }
117 
118   absl::optional<int64_t> current_bitrate_bps =
119       encoded_bitrate_.Rate(last_time_sent_in_ms_.value());
120   if (!current_bitrate_bps.has_value()) {
121     // We can't get a valid bitrate due to not enough data points.
122     return BandwidthQualityScaler::CheckBitrateResult::kInsufficientSamples;
123   }
124   absl::optional<VideoEncoder::ResolutionBitrateLimits> suitable_bitrate_limit =
125       EncoderInfoSettings::
126           GetSinglecastBitrateLimitForResolutionWhenQpIsUntrusted(
127               last_frame_size_pixels_, resolution_bitrate_limits_);
128 
129   if (!suitable_bitrate_limit.has_value()) {
130     return BandwidthQualityScaler::CheckBitrateResult::kInsufficientSamples;
131   }
132 
133   // Multiply by toleration factor to solve the frequent adaptation due to
134   // critical value.
135   if (current_bitrate_bps > suitable_bitrate_limit->max_bitrate_bps *
136                                 kHigherMaxBitrateTolerationFactor) {
137     return BandwidthQualityScaler::CheckBitrateResult::kLowBitRate;
138   } else if (current_bitrate_bps <
139              suitable_bitrate_limit->min_start_bitrate_bps *
140                  kLowerMinBitrateTolerationFactor) {
141     return BandwidthQualityScaler::CheckBitrateResult::kHighBitRate;
142   }
143   return BandwidthQualityScaler::CheckBitrateResult::kNormalBitrate;
144 }
145 
146 BandwidthQualityScalerUsageHandlerInterface::
~BandwidthQualityScalerUsageHandlerInterface()147     ~BandwidthQualityScalerUsageHandlerInterface() {}
148 }  // namespace webrtc
149