1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2016 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef COMMON_VIDEO_INCLUDE_BITRATE_ADJUSTER_H_ 12*d9f75844SAndroid Build Coastguard Worker #define COMMON_VIDEO_INCLUDE_BITRATE_ADJUSTER_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h> 15*d9f75844SAndroid Build Coastguard Worker #include <stdint.h> 16*d9f75844SAndroid Build Coastguard Worker 17*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h" 18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/rate_statistics.h" 19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h" 20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h" 21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h" 22*d9f75844SAndroid Build Coastguard Worker 23*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 24*d9f75844SAndroid Build Coastguard Worker 25*d9f75844SAndroid Build Coastguard Worker // Certain hardware encoders tend to consistently overshoot the bitrate that 26*d9f75844SAndroid Build Coastguard Worker // they are configured to encode at. This class estimates an adjusted bitrate 27*d9f75844SAndroid Build Coastguard Worker // that when set on the encoder will produce the desired bitrate. 28*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT BitrateAdjuster { 29*d9f75844SAndroid Build Coastguard Worker public: 30*d9f75844SAndroid Build Coastguard Worker // min_adjusted_bitrate_pct and max_adjusted_bitrate_pct are the lower and 31*d9f75844SAndroid Build Coastguard Worker // upper bound outputted adjusted bitrates as a percentage of the target 32*d9f75844SAndroid Build Coastguard Worker // bitrate. 33*d9f75844SAndroid Build Coastguard Worker BitrateAdjuster(float min_adjusted_bitrate_pct, 34*d9f75844SAndroid Build Coastguard Worker float max_adjusted_bitrate_pct); ~BitrateAdjuster()35*d9f75844SAndroid Build Coastguard Worker virtual ~BitrateAdjuster() {} 36*d9f75844SAndroid Build Coastguard Worker 37*d9f75844SAndroid Build Coastguard Worker static const uint32_t kBitrateUpdateIntervalMs; 38*d9f75844SAndroid Build Coastguard Worker static const uint32_t kBitrateUpdateFrameInterval; 39*d9f75844SAndroid Build Coastguard Worker static const float kBitrateTolerancePct; 40*d9f75844SAndroid Build Coastguard Worker static const float kBytesPerMsToBitsPerSecond; 41*d9f75844SAndroid Build Coastguard Worker 42*d9f75844SAndroid Build Coastguard Worker // Sets the desired bitrate in bps (bits per second). 43*d9f75844SAndroid Build Coastguard Worker // Should be called at least once before Update. 44*d9f75844SAndroid Build Coastguard Worker void SetTargetBitrateBps(uint32_t bitrate_bps); 45*d9f75844SAndroid Build Coastguard Worker uint32_t GetTargetBitrateBps() const; 46*d9f75844SAndroid Build Coastguard Worker 47*d9f75844SAndroid Build Coastguard Worker // Returns the adjusted bitrate in bps. 48*d9f75844SAndroid Build Coastguard Worker uint32_t GetAdjustedBitrateBps() const; 49*d9f75844SAndroid Build Coastguard Worker 50*d9f75844SAndroid Build Coastguard Worker // Returns what we think the current bitrate is. 51*d9f75844SAndroid Build Coastguard Worker absl::optional<uint32_t> GetEstimatedBitrateBps(); 52*d9f75844SAndroid Build Coastguard Worker 53*d9f75844SAndroid Build Coastguard Worker // This should be called after each frame is encoded. The timestamp at which 54*d9f75844SAndroid Build Coastguard Worker // it is called is used to estimate the output bitrate of the encoder. 55*d9f75844SAndroid Build Coastguard Worker // Should be called from only one thread. 56*d9f75844SAndroid Build Coastguard Worker void Update(size_t frame_size); 57*d9f75844SAndroid Build Coastguard Worker 58*d9f75844SAndroid Build Coastguard Worker private: 59*d9f75844SAndroid Build Coastguard Worker // Returns true if the bitrate is within kBitrateTolerancePct of bitrate_bps. 60*d9f75844SAndroid Build Coastguard Worker bool IsWithinTolerance(uint32_t bitrate_bps, uint32_t target_bitrate_bps); 61*d9f75844SAndroid Build Coastguard Worker 62*d9f75844SAndroid Build Coastguard Worker // Returns smallest possible adjusted value. 63*d9f75844SAndroid Build Coastguard Worker uint32_t GetMinAdjustedBitrateBps() const 64*d9f75844SAndroid Build Coastguard Worker RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 65*d9f75844SAndroid Build Coastguard Worker // Returns largest possible adjusted value. 66*d9f75844SAndroid Build Coastguard Worker uint32_t GetMaxAdjustedBitrateBps() const 67*d9f75844SAndroid Build Coastguard Worker RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 68*d9f75844SAndroid Build Coastguard Worker 69*d9f75844SAndroid Build Coastguard Worker void Reset(); 70*d9f75844SAndroid Build Coastguard Worker void UpdateBitrate(uint32_t current_time_ms) 71*d9f75844SAndroid Build Coastguard Worker RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); 72*d9f75844SAndroid Build Coastguard Worker 73*d9f75844SAndroid Build Coastguard Worker mutable Mutex mutex_; 74*d9f75844SAndroid Build Coastguard Worker const float min_adjusted_bitrate_pct_; 75*d9f75844SAndroid Build Coastguard Worker const float max_adjusted_bitrate_pct_; 76*d9f75844SAndroid Build Coastguard Worker // The bitrate we want. 77*d9f75844SAndroid Build Coastguard Worker volatile uint32_t target_bitrate_bps_ RTC_GUARDED_BY(mutex_); 78*d9f75844SAndroid Build Coastguard Worker // The bitrate we use to get what we want. 79*d9f75844SAndroid Build Coastguard Worker volatile uint32_t adjusted_bitrate_bps_ RTC_GUARDED_BY(mutex_); 80*d9f75844SAndroid Build Coastguard Worker // The target bitrate that the adjusted bitrate was computed from. 81*d9f75844SAndroid Build Coastguard Worker volatile uint32_t last_adjusted_target_bitrate_bps_ RTC_GUARDED_BY(mutex_); 82*d9f75844SAndroid Build Coastguard Worker // Used to estimate bitrate. 83*d9f75844SAndroid Build Coastguard Worker RateStatistics bitrate_tracker_ RTC_GUARDED_BY(mutex_); 84*d9f75844SAndroid Build Coastguard Worker // The last time we tried to adjust the bitrate. 85*d9f75844SAndroid Build Coastguard Worker uint32_t last_bitrate_update_time_ms_ RTC_GUARDED_BY(mutex_); 86*d9f75844SAndroid Build Coastguard Worker // The number of frames since the last time we tried to adjust the bitrate. 87*d9f75844SAndroid Build Coastguard Worker uint32_t frames_since_last_update_ RTC_GUARDED_BY(mutex_); 88*d9f75844SAndroid Build Coastguard Worker }; 89*d9f75844SAndroid Build Coastguard Worker 90*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 91*d9f75844SAndroid Build Coastguard Worker 92*d9f75844SAndroid Build Coastguard Worker #endif // COMMON_VIDEO_INCLUDE_BITRATE_ADJUSTER_H_ 93