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 <utility>
15 
16 #include "api/optional.h"
17 #include "api/video_codecs/video_encoder.h"
18 #include "common_types.h"  // NOLINT(build/include)
19 #include "modules/video_coding/utility/moving_average.h"
20 #include "rtc_base/sequenced_task_checker.h"
21 
22 namespace webrtc {
23 
24 // An interface for signaling requests to limit or increase the resolution or
25 // framerate of the captured video stream.
26 class AdaptationObserverInterface {
27  public:
28   // Indicates if the adaptation is due to overuse of the CPU resources, or if
29   // the quality of the encoded frames have dropped too low.
30   enum AdaptReason : size_t { kQuality = 0, kCpu = 1 };
31   static const size_t kScaleReasonSize = 2;
32   // Called to signal that we can handle larger or more frequent frames.
33   virtual void AdaptUp(AdaptReason reason) = 0;
34   // Called to signal that the source should reduce the resolution or framerate.
35   virtual void AdaptDown(AdaptReason reason) = 0;
36 
37  protected:
~AdaptationObserverInterface()38   virtual ~AdaptationObserverInterface() {}
39 };
40 
41 // QualityScaler runs asynchronously and monitors QP values of encoded frames.
42 // It holds a reference to an AdaptationObserverInterface implementation to
43 // signal an intent to scale up or down.
44 class QualityScaler {
45  public:
46   // Construct a QualityScaler with a given |observer|.
47   // This starts the quality scaler periodically checking what the average QP
48   // has been recently.
49   QualityScaler(AdaptationObserverInterface* observer,
50                 VideoCodecType codec_type);
51   // If specific thresholds are desired these can be supplied as |thresholds|.
52   QualityScaler(AdaptationObserverInterface* observer,
53                 VideoEncoder::QpThresholds thresholds);
54   virtual ~QualityScaler();
55   // Should be called each time the encoder drops a frame
56   void ReportDroppedFrame();
57   // Inform the QualityScaler of the last seen QP.
58   void ReportQP(int qp);
59 
60   // The following members declared protected for testing purposes
61  protected:
62   QualityScaler(AdaptationObserverInterface* observer,
63                 VideoEncoder::QpThresholds thresholds,
64                 int64_t sampling_period);
65 
66  private:
67   class CheckQPTask;
68   void CheckQP();
69   void ClearSamples();
70   void ReportQPLow();
71   void ReportQPHigh();
72   int64_t GetSamplingPeriodMs() const;
73 
74   CheckQPTask* check_qp_task_ RTC_GUARDED_BY(&task_checker_);
75   AdaptationObserverInterface* const observer_ RTC_GUARDED_BY(&task_checker_);
76   rtc::SequencedTaskChecker task_checker_;
77 
78   const int64_t sampling_period_ms_;
79   bool fast_rampup_ RTC_GUARDED_BY(&task_checker_);
80   MovingAverage average_qp_ RTC_GUARDED_BY(&task_checker_);
81   MovingAverage framedrop_percent_ RTC_GUARDED_BY(&task_checker_);
82 
83   VideoEncoder::QpThresholds thresholds_ RTC_GUARDED_BY(&task_checker_);
84 };
85 }  // namespace webrtc
86 
87 #endif  // MODULES_VIDEO_CODING_UTILITY_QUALITY_SCALER_H_
88