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