• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "vp9/ratectrl_rtc.h"
11 
12 #include <new>
13 
14 #include "vp9/common/vp9_common.h"
15 #include "vp9/encoder/vp9_encoder.h"
16 #include "vp9/encoder/vp9_picklpf.h"
17 #include "vpx/vp8cx.h"
18 #include "vpx/vpx_codec.h"
19 
20 namespace libvpx {
21 
Create(const VP9RateControlRtcConfig & cfg)22 std::unique_ptr<VP9RateControlRTC> VP9RateControlRTC::Create(
23     const VP9RateControlRtcConfig &cfg) {
24   std::unique_ptr<VP9RateControlRTC> rc_api(new (std::nothrow)
25                                                 VP9RateControlRTC());
26   if (!rc_api) return nullptr;
27   rc_api->cpi_ = static_cast<VP9_COMP *>(vpx_memalign(32, sizeof(*cpi_)));
28   if (!rc_api->cpi_) return nullptr;
29   vp9_zero(*rc_api->cpi_);
30 
31   rc_api->InitRateControl(cfg);
32   if (cfg.aq_mode) {
33     VP9_COMP *const cpi = rc_api->cpi_;
34     cpi->segmentation_map = static_cast<uint8_t *>(
35         vpx_calloc(cpi->common.mi_rows * cpi->common.mi_cols,
36                    sizeof(*cpi->segmentation_map)));
37     cpi->cyclic_refresh =
38         vp9_cyclic_refresh_alloc(cpi->common.mi_rows, cpi->common.mi_cols);
39     cpi->cyclic_refresh->content_mode = 0;
40   }
41   return rc_api;
42 }
43 
InitRateControl(const VP9RateControlRtcConfig & rc_cfg)44 void VP9RateControlRTC::InitRateControl(const VP9RateControlRtcConfig &rc_cfg) {
45   VP9_COMMON *cm = &cpi_->common;
46   VP9EncoderConfig *oxcf = &cpi_->oxcf;
47   RATE_CONTROL *const rc = &cpi_->rc;
48   cm->profile = PROFILE_0;
49   cm->bit_depth = VPX_BITS_8;
50   cm->show_frame = 1;
51   oxcf->profile = cm->profile;
52   oxcf->bit_depth = cm->bit_depth;
53   oxcf->rc_mode = rc_cfg.rc_mode;
54   oxcf->pass = 0;
55   oxcf->aq_mode = rc_cfg.aq_mode ? CYCLIC_REFRESH_AQ : NO_AQ;
56   oxcf->content = VP9E_CONTENT_DEFAULT;
57   oxcf->drop_frames_water_mark = 0;
58   cm->current_video_frame = 0;
59   rc->kf_boost = DEFAULT_KF_BOOST;
60 
61   UpdateRateControl(rc_cfg);
62   vp9_set_mb_mi(cm, cm->width, cm->height);
63 
64   cpi_->use_svc = (cpi_->svc.number_spatial_layers > 1 ||
65                    cpi_->svc.number_temporal_layers > 1)
66                       ? 1
67                       : 0;
68 
69   rc->rc_1_frame = 0;
70   rc->rc_2_frame = 0;
71   vp9_rc_init_minq_luts();
72   vp9_rc_init(oxcf, 0, rc);
73   rc->constrain_gf_key_freq_onepass_vbr = 0;
74   cpi_->sf.use_nonrd_pick_mode = 1;
75 }
76 
UpdateRateControl(const VP9RateControlRtcConfig & rc_cfg)77 void VP9RateControlRTC::UpdateRateControl(
78     const VP9RateControlRtcConfig &rc_cfg) {
79   VP9_COMMON *cm = &cpi_->common;
80   VP9EncoderConfig *oxcf = &cpi_->oxcf;
81   RATE_CONTROL *const rc = &cpi_->rc;
82 
83   cm->width = rc_cfg.width;
84   cm->height = rc_cfg.height;
85   oxcf->width = rc_cfg.width;
86   oxcf->height = rc_cfg.height;
87   oxcf->worst_allowed_q = vp9_quantizer_to_qindex(rc_cfg.max_quantizer);
88   oxcf->best_allowed_q = vp9_quantizer_to_qindex(rc_cfg.min_quantizer);
89   rc->worst_quality = oxcf->worst_allowed_q;
90   rc->best_quality = oxcf->best_allowed_q;
91   oxcf->init_framerate = rc_cfg.framerate;
92   oxcf->target_bandwidth = 1000 * rc_cfg.target_bandwidth;
93   oxcf->starting_buffer_level_ms = rc_cfg.buf_initial_sz;
94   oxcf->optimal_buffer_level_ms = rc_cfg.buf_optimal_sz;
95   oxcf->maximum_buffer_size_ms = rc_cfg.buf_sz;
96   oxcf->under_shoot_pct = rc_cfg.undershoot_pct;
97   oxcf->over_shoot_pct = rc_cfg.overshoot_pct;
98   oxcf->ss_number_layers = rc_cfg.ss_number_layers;
99   oxcf->ts_number_layers = rc_cfg.ts_number_layers;
100   oxcf->temporal_layering_mode = (VP9E_TEMPORAL_LAYERING_MODE)(
101       (rc_cfg.ts_number_layers > 1) ? rc_cfg.ts_number_layers : 0);
102 
103   cpi_->oxcf.rc_max_intra_bitrate_pct = rc_cfg.max_intra_bitrate_pct;
104   cpi_->oxcf.rc_max_inter_bitrate_pct = rc_cfg.max_inter_bitrate_pct;
105   cpi_->framerate = rc_cfg.framerate;
106   cpi_->svc.number_spatial_layers = rc_cfg.ss_number_layers;
107   cpi_->svc.number_temporal_layers = rc_cfg.ts_number_layers;
108 
109   for (int sl = 0; sl < cpi_->svc.number_spatial_layers; ++sl) {
110     for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) {
111       const int layer =
112           LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers);
113       LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
114       RATE_CONTROL *const lrc = &lc->rc;
115       oxcf->layer_target_bitrate[layer] =
116           1000 * rc_cfg.layer_target_bitrate[layer];
117       lrc->worst_quality =
118           vp9_quantizer_to_qindex(rc_cfg.max_quantizers[layer]);
119       lrc->best_quality = vp9_quantizer_to_qindex(rc_cfg.min_quantizers[layer]);
120       lc->scaling_factor_num = rc_cfg.scaling_factor_num[sl];
121       lc->scaling_factor_den = rc_cfg.scaling_factor_den[sl];
122       oxcf->ts_rate_decimator[tl] = rc_cfg.ts_rate_decimator[tl];
123     }
124   }
125   vp9_set_rc_buffer_sizes(cpi_);
126   vp9_new_framerate(cpi_, cpi_->framerate);
127   if (cpi_->svc.number_temporal_layers > 1 ||
128       cpi_->svc.number_spatial_layers > 1) {
129     if (cm->current_video_frame == 0) vp9_init_layer_context(cpi_);
130     vp9_update_layer_context_change_config(cpi_,
131                                            (int)cpi_->oxcf.target_bandwidth);
132   }
133   vp9_check_reset_rc_flag(cpi_);
134 }
135 
ComputeQP(const VP9FrameParamsQpRTC & frame_params)136 void VP9RateControlRTC::ComputeQP(const VP9FrameParamsQpRTC &frame_params) {
137   VP9_COMMON *const cm = &cpi_->common;
138   int width, height;
139   cpi_->svc.spatial_layer_id = frame_params.spatial_layer_id;
140   cpi_->svc.temporal_layer_id = frame_params.temporal_layer_id;
141   if (cpi_->svc.number_spatial_layers > 1) {
142     const int layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id,
143                                        cpi_->svc.temporal_layer_id,
144                                        cpi_->svc.number_temporal_layers);
145     LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
146     get_layer_resolution(cpi_->oxcf.width, cpi_->oxcf.height,
147                          lc->scaling_factor_num, lc->scaling_factor_den, &width,
148                          &height);
149     cm->width = width;
150     cm->height = height;
151   }
152   vp9_set_mb_mi(cm, cm->width, cm->height);
153   cm->frame_type = frame_params.frame_type;
154   cpi_->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;
155   cpi_->sf.use_nonrd_pick_mode = 1;
156   if (cpi_->svc.number_spatial_layers == 1 &&
157       cpi_->svc.number_temporal_layers == 1) {
158     int target = 0;
159     if (cpi_->oxcf.rc_mode == VPX_CBR) {
160       if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
161         vp9_cyclic_refresh_update_parameters(cpi_);
162       if (frame_is_intra_only(cm))
163         target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_);
164       else
165         target = vp9_calc_pframe_target_size_one_pass_cbr(cpi_);
166     } else if (cpi_->oxcf.rc_mode == VPX_VBR) {
167       if (cm->frame_type == KEY_FRAME) {
168         cpi_->rc.this_key_frame_forced = cm->current_video_frame != 0;
169         cpi_->rc.frames_to_key = cpi_->oxcf.key_freq;
170       }
171       vp9_set_gf_update_one_pass_vbr(cpi_);
172       if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
173         vp9_cyclic_refresh_update_parameters(cpi_);
174       if (frame_is_intra_only(cm))
175         target = vp9_calc_iframe_target_size_one_pass_vbr(cpi_);
176       else
177         target = vp9_calc_pframe_target_size_one_pass_vbr(cpi_);
178     }
179     vp9_rc_set_frame_target(cpi_, target);
180     vp9_update_buffer_level_preencode(cpi_);
181   } else {
182     vp9_update_temporal_layer_framerate(cpi_);
183     vp9_restore_layer_context(cpi_);
184     vp9_rc_get_svc_params(cpi_);
185   }
186   int bottom_index, top_index;
187   cpi_->common.base_qindex =
188       vp9_rc_pick_q_and_bounds(cpi_, &bottom_index, &top_index);
189 
190   if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) vp9_cyclic_refresh_setup(cpi_);
191 }
192 
GetQP() const193 int VP9RateControlRTC::GetQP() const { return cpi_->common.base_qindex; }
194 
GetLoopfilterLevel() const195 int VP9RateControlRTC::GetLoopfilterLevel() const {
196   struct loopfilter *const lf = &cpi_->common.lf;
197   vp9_pick_filter_level(nullptr, cpi_, LPF_PICK_FROM_Q);
198   return lf->filter_level;
199 }
200 
GetCyclicRefreshMap() const201 signed char *VP9RateControlRTC::GetCyclicRefreshMap() const {
202   return cpi_->cyclic_refresh->map;
203 }
204 
GetDeltaQ() const205 int *VP9RateControlRTC::GetDeltaQ() const {
206   return cpi_->cyclic_refresh->qindex_delta;
207 }
208 
PostEncodeUpdate(uint64_t encoded_frame_size)209 void VP9RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {
210   vp9_rc_postencode_update(cpi_, encoded_frame_size);
211   if (cpi_->svc.number_spatial_layers > 1 ||
212       cpi_->svc.number_temporal_layers > 1)
213     vp9_save_layer_context(cpi_);
214   cpi_->common.current_video_frame++;
215 }
216 
217 }  // namespace libvpx
218