1 /* 2 * Copyright (c) 2020 The WebM 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 VPX_VP9_RATECTRL_RTC_H_ 12 #define VPX_VP9_RATECTRL_RTC_H_ 13 14 #include <cstdint> 15 #include <memory> 16 17 #include "vp9/common/vp9_entropymode.h" 18 #include "vp9/common/vp9_enums.h" 19 #include "vp9/common/vp9_onyxc_int.h" 20 #include "vp9/vp9_iface_common.h" 21 #include "vp9/encoder/vp9_aq_cyclicrefresh.h" 22 #include "vp9/encoder/vp9_encoder.h" 23 #include "vp9/encoder/vp9_firstpass.h" 24 #include "vp9/vp9_cx_iface.h" 25 #include "vpx_mem/vpx_mem.h" 26 27 namespace libvpx { 28 29 struct VP9RateControlRtcConfig { 30 public: VP9RateControlRtcConfigVP9RateControlRtcConfig31 VP9RateControlRtcConfig() { 32 width = 1280; 33 height = 720; 34 max_quantizer = 63; 35 min_quantizer = 2; 36 target_bandwidth = 1000; 37 buf_initial_sz = 600; 38 buf_optimal_sz = 600; 39 buf_sz = 1000; 40 undershoot_pct = overshoot_pct = 50; 41 max_intra_bitrate_pct = 50; 42 max_inter_bitrate_pct = 0; 43 framerate = 30.0; 44 ss_number_layers = ts_number_layers = 1; 45 rc_mode = VPX_CBR; 46 aq_mode = 0; 47 vp9_zero(max_quantizers); 48 vp9_zero(min_quantizers); 49 vp9_zero(scaling_factor_den); 50 vp9_zero(scaling_factor_num); 51 vp9_zero(layer_target_bitrate); 52 vp9_zero(ts_rate_decimator); 53 scaling_factor_num[0] = 1; 54 scaling_factor_den[0] = 1; 55 layer_target_bitrate[0] = static_cast<int>(target_bandwidth); 56 max_quantizers[0] = max_quantizer; 57 min_quantizers[0] = min_quantizer; 58 ts_rate_decimator[0] = 1; 59 } 60 61 int width; 62 int height; 63 // 0-63 64 int max_quantizer; 65 int min_quantizer; 66 int64_t target_bandwidth; 67 int64_t buf_initial_sz; 68 int64_t buf_optimal_sz; 69 int64_t buf_sz; 70 int undershoot_pct; 71 int overshoot_pct; 72 int max_intra_bitrate_pct; 73 int max_inter_bitrate_pct; 74 double framerate; 75 // Number of spatial layers 76 int ss_number_layers; 77 // Number of temporal layers 78 int ts_number_layers; 79 int max_quantizers[VPX_MAX_LAYERS]; 80 int min_quantizers[VPX_MAX_LAYERS]; 81 int scaling_factor_num[VPX_SS_MAX_LAYERS]; 82 int scaling_factor_den[VPX_SS_MAX_LAYERS]; 83 int layer_target_bitrate[VPX_MAX_LAYERS]; 84 int ts_rate_decimator[VPX_TS_MAX_LAYERS]; 85 // vbr, cbr 86 enum vpx_rc_mode rc_mode; 87 int aq_mode; 88 }; 89 90 struct VP9FrameParamsQpRTC { 91 FRAME_TYPE frame_type; 92 int spatial_layer_id; 93 int temporal_layer_id; 94 }; 95 96 // This interface allows using VP9 real-time rate control without initializing 97 // the encoder. To use this interface, you need to link with libvp9rc.a. 98 // 99 // #include "vp9/ratectrl_rtc.h" 100 // VP9RateControlRTC rc_api; 101 // VP9RateControlRtcConfig cfg; 102 // VP9FrameParamsQpRTC frame_params; 103 // 104 // YourFunctionToInitializeConfig(cfg); 105 // rc_api.InitRateControl(cfg); 106 // // start encoding 107 // while (frame_to_encode) { 108 // if (config_changed) 109 // rc_api.UpdateRateControl(cfg); 110 // YourFunctionToFillFrameParams(frame_params); 111 // rc_api.ComputeQP(frame_params); 112 // YourFunctionToUseQP(rc_api.GetQP()); 113 // YourFunctionToUseLoopfilter(rc_api.GetLoopfilterLevel()); 114 // // After encoding 115 // rc_api.PostEncode(encoded_frame_size); 116 // } 117 class VP9RateControlRTC { 118 public: 119 static std::unique_ptr<VP9RateControlRTC> Create( 120 const VP9RateControlRtcConfig &cfg); ~VP9RateControlRTC()121 ~VP9RateControlRTC() { 122 if (cpi_) { 123 if (cpi_->svc.number_spatial_layers > 1 || 124 cpi_->svc.number_temporal_layers > 1) { 125 for (int sl = 0; sl < cpi_->svc.number_spatial_layers; sl++) { 126 for (int tl = 0; tl < cpi_->svc.number_temporal_layers; tl++) { 127 int layer = LAYER_IDS_TO_IDX(sl, tl, cpi_->oxcf.ts_number_layers); 128 LAYER_CONTEXT *const lc = &cpi_->svc.layer_context[layer]; 129 vpx_free(lc->map); 130 vpx_free(lc->last_coded_q_map); 131 vpx_free(lc->consec_zero_mv); 132 } 133 } 134 } 135 if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { 136 vpx_free(cpi_->segmentation_map); 137 cpi_->segmentation_map = NULL; 138 vp9_cyclic_refresh_free(cpi_->cyclic_refresh); 139 } 140 vpx_free(cpi_); 141 } 142 } 143 144 void UpdateRateControl(const VP9RateControlRtcConfig &rc_cfg); 145 // GetQP() needs to be called after ComputeQP() to get the latest QP 146 int GetQP() const; 147 int GetLoopfilterLevel() const; 148 signed char *GetCyclicRefreshMap() const; 149 int *GetDeltaQ() const; 150 void ComputeQP(const VP9FrameParamsQpRTC &frame_params); 151 // Feedback to rate control with the size of current encoded frame 152 void PostEncodeUpdate(uint64_t encoded_frame_size); 153 154 private: VP9RateControlRTC()155 VP9RateControlRTC() {} 156 void InitRateControl(const VP9RateControlRtcConfig &cfg); 157 VP9_COMP *cpi_; 158 }; 159 160 } // namespace libvpx 161 162 #endif // VPX_VP9_RATECTRL_RTC_H_ 163