xref: /aosp_15_r20/external/webrtc/modules/video_coding/utility/quality_scaler.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2014 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 #ifndef MODULES_VIDEO_CODING_UTILITY_QUALITY_SCALER_H_
12 #define MODULES_VIDEO_CODING_UTILITY_QUALITY_SCALER_H_
13 
14 #include <stddef.h>
15 #include <stdint.h>
16 
17 #include <memory>
18 
19 #include "absl/types/optional.h"
20 #include "api/scoped_refptr.h"
21 #include "api/sequence_checker.h"
22 #include "api/video_codecs/video_encoder.h"
23 #include "rtc_base/experiments/quality_scaling_experiment.h"
24 #include "rtc_base/numerics/moving_average.h"
25 #include "rtc_base/ref_count.h"
26 #include "rtc_base/system/no_unique_address.h"
27 
28 namespace webrtc {
29 
30 class QualityScalerQpUsageHandlerCallbackInterface;
31 class QualityScalerQpUsageHandlerInterface;
32 
33 // QualityScaler runs asynchronously and monitors QP values of encoded frames.
34 // It holds a reference to a QualityScalerQpUsageHandlerInterface implementation
35 // to signal an overuse or underuse of QP (which indicate a desire to scale the
36 // video stream down or up).
37 class QualityScaler {
38  public:
39   // Construct a QualityScaler with given `thresholds` and `handler`.
40   // This starts the quality scaler periodically checking what the average QP
41   // has been recently.
42   QualityScaler(QualityScalerQpUsageHandlerInterface* handler,
43                 VideoEncoder::QpThresholds thresholds);
44   virtual ~QualityScaler();
45   // Should be called each time a frame is dropped at encoding.
46   void ReportDroppedFrameByMediaOpt();
47   void ReportDroppedFrameByEncoder();
48   // Inform the QualityScaler of the last seen QP.
49   void ReportQp(int qp, int64_t time_sent_us);
50 
51   void SetQpThresholds(VideoEncoder::QpThresholds thresholds);
52   bool QpFastFilterLow() const;
53 
54   // The following members declared protected for testing purposes.
55  protected:
56   QualityScaler(QualityScalerQpUsageHandlerInterface* handler,
57                 VideoEncoder::QpThresholds thresholds,
58                 int64_t sampling_period_ms);
59 
60  private:
61   class QpSmoother;
62   class CheckQpTask;
63   class CheckQpTaskHandlerCallback;
64 
65   enum class CheckQpResult {
66     kInsufficientSamples,
67     kNormalQp,
68     kHighQp,
69     kLowQp,
70   };
71 
72   // Starts checking for QP in a delayed task. When the resulting CheckQpTask
73   // completes, it will invoke this method again, ensuring that we always
74   // periodically check for QP. See CheckQpTask for more details. We never run
75   // more than one CheckQpTask at a time.
76   void StartNextCheckQpTask();
77 
78   CheckQpResult CheckQp() const;
79   void ClearSamples();
80 
81   std::unique_ptr<CheckQpTask> pending_qp_task_ RTC_GUARDED_BY(&task_checker_);
82   QualityScalerQpUsageHandlerInterface* const handler_
83       RTC_GUARDED_BY(&task_checker_);
84   RTC_NO_UNIQUE_ADDRESS SequenceChecker task_checker_;
85 
86   VideoEncoder::QpThresholds thresholds_ RTC_GUARDED_BY(&task_checker_);
87   const int64_t sampling_period_ms_;
88   bool fast_rampup_ RTC_GUARDED_BY(&task_checker_);
89   rtc::MovingAverage average_qp_ RTC_GUARDED_BY(&task_checker_);
90   rtc::MovingAverage framedrop_percent_media_opt_
91       RTC_GUARDED_BY(&task_checker_);
92   rtc::MovingAverage framedrop_percent_all_ RTC_GUARDED_BY(&task_checker_);
93 
94   // Used by QualityScalingExperiment.
95   const bool experiment_enabled_;
96   QualityScalingExperiment::Config config_ RTC_GUARDED_BY(&task_checker_);
97   std::unique_ptr<QpSmoother> qp_smoother_high_ RTC_GUARDED_BY(&task_checker_);
98   std::unique_ptr<QpSmoother> qp_smoother_low_ RTC_GUARDED_BY(&task_checker_);
99 
100   const size_t min_frames_needed_;
101   const double initial_scale_factor_;
102   const absl::optional<double> scale_factor_;
103 };
104 
105 // Reacts to QP being too high or too low. For best quality, when QP is high it
106 // is desired to decrease the resolution or frame rate of the stream and when QP
107 // is low it is desired to increase the resolution or frame rate of the stream.
108 // Whether to reconfigure the stream is ultimately up to the handler, which is
109 // able to respond asynchronously.
110 class QualityScalerQpUsageHandlerInterface {
111  public:
112   virtual ~QualityScalerQpUsageHandlerInterface();
113 
114   virtual void OnReportQpUsageHigh() = 0;
115   virtual void OnReportQpUsageLow() = 0;
116 };
117 
118 }  // namespace webrtc
119 
120 #endif  // MODULES_VIDEO_CODING_UTILITY_QUALITY_SCALER_H_
121