| /* |
| * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #ifndef MODULES_VIDEO_CODING_UTILITY_QUALITY_SCALER_H_ |
| #define MODULES_VIDEO_CODING_UTILITY_QUALITY_SCALER_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include "absl/types/optional.h" |
| #include "api/video_codecs/video_encoder.h" |
| #include "rtc_base/experiments/quality_scaling_experiment.h" |
| #include "rtc_base/numerics/moving_average.h" |
| #include "rtc_base/synchronization/sequence_checker.h" |
| #include "rtc_base/task_queue.h" |
| #include "rtc_base/task_utils/repeating_task.h" |
| |
| namespace webrtc { |
| |
| // An interface for signaling requests to limit or increase the resolution or |
| // framerate of the captured video stream. |
| class AdaptationObserverInterface { |
| public: |
| // Indicates if the adaptation is due to overuse of the CPU resources, or if |
| // the quality of the encoded frames have dropped too low. |
| enum AdaptReason : size_t { kQuality = 0, kCpu = 1 }; |
| static const size_t kScaleReasonSize = 2; |
| // Called to signal that we can handle larger or more frequent frames. |
| virtual void AdaptUp(AdaptReason reason) = 0; |
| // Called to signal that the source should reduce the resolution or framerate. |
| // Returns false if a downgrade was requested but the request did not result |
| // in a new limiting resolution or fps. |
| virtual bool AdaptDown(AdaptReason reason) = 0; |
| |
| protected: |
| virtual ~AdaptationObserverInterface() {} |
| }; |
| |
| // QualityScaler runs asynchronously and monitors QP values of encoded frames. |
| // It holds a reference to an AdaptationObserverInterface implementation to |
| // signal an intent to scale up or down. |
| class QualityScaler { |
| public: |
| // Construct a QualityScaler with given |thresholds| and |observer|. |
| // This starts the quality scaler periodically checking what the average QP |
| // has been recently. |
| QualityScaler(rtc::TaskQueue* task_queue, |
| AdaptationObserverInterface* observer, |
| VideoEncoder::QpThresholds thresholds); |
| virtual ~QualityScaler(); |
| // Should be called each time a frame is dropped at encoding. |
| void ReportDroppedFrameByMediaOpt(); |
| void ReportDroppedFrameByEncoder(); |
| // Inform the QualityScaler of the last seen QP. |
| void ReportQp(int qp, int64_t time_sent_us); |
| |
| void SetQpThresholds(VideoEncoder::QpThresholds thresholds); |
| bool QpFastFilterLow() const; |
| |
| // The following members declared protected for testing purposes. |
| protected: |
| QualityScaler(rtc::TaskQueue* task_queue, |
| AdaptationObserverInterface* observer, |
| VideoEncoder::QpThresholds thresholds, |
| int64_t sampling_period_ms); |
| |
| private: |
| class QpSmoother; |
| |
| void CheckQp(); |
| void ClearSamples(); |
| void ReportQpLow(); |
| void ReportQpHigh(); |
| int64_t GetSamplingPeriodMs() const; |
| |
| RepeatingTaskHandle check_qp_task_ RTC_GUARDED_BY(&task_checker_); |
| AdaptationObserverInterface* const observer_ RTC_GUARDED_BY(&task_checker_); |
| SequenceChecker task_checker_; |
| |
| VideoEncoder::QpThresholds thresholds_ RTC_GUARDED_BY(&task_checker_); |
| const int64_t sampling_period_ms_; |
| bool fast_rampup_ RTC_GUARDED_BY(&task_checker_); |
| rtc::MovingAverage average_qp_ RTC_GUARDED_BY(&task_checker_); |
| rtc::MovingAverage framedrop_percent_media_opt_ |
| RTC_GUARDED_BY(&task_checker_); |
| rtc::MovingAverage framedrop_percent_all_ RTC_GUARDED_BY(&task_checker_); |
| |
| // Used by QualityScalingExperiment. |
| const bool experiment_enabled_; |
| QualityScalingExperiment::Config config_ RTC_GUARDED_BY(&task_checker_); |
| std::unique_ptr<QpSmoother> qp_smoother_high_ RTC_GUARDED_BY(&task_checker_); |
| std::unique_ptr<QpSmoother> qp_smoother_low_ RTC_GUARDED_BY(&task_checker_); |
| bool observed_enough_frames_ RTC_GUARDED_BY(&task_checker_); |
| |
| const size_t min_frames_needed_; |
| const double initial_scale_factor_; |
| const absl::optional<double> scale_factor_; |
| bool adapt_called_ RTC_GUARDED_BY(&task_checker_); |
| bool adapt_failed_ RTC_GUARDED_BY(&task_checker_); |
| }; |
| } // namespace webrtc |
| |
| #endif // MODULES_VIDEO_CODING_UTILITY_QUALITY_SCALER_H_ |