]> granicus.if.org Git - libvpx/blob - vp9/ratectrl_rtc.cc
Initialize VP9EncoderConfig profile and bit depth
[libvpx] / vp9 / ratectrl_rtc.cc
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/encoder/vp9_encoder.h"
15 #include "vp9/encoder/vp9_picklpf.h"
16 #include "vpx/vp8cx.h"
17 #include "vpx/vpx_codec.h"
18
19 namespace libvpx {
20
21 std::unique_ptr<VP9RateControlRTC> VP9RateControlRTC::Create(
22     const VP9RateControlRtcConfig &cfg) {
23   std::unique_ptr<VP9RateControlRTC> rc_api(new (std::nothrow)
24                                                 VP9RateControlRTC());
25   if (!rc_api) return nullptr;
26   rc_api->cpi_ = static_cast<VP9_COMP *>(vpx_memalign(32, sizeof(*cpi_)));
27   if (rc_api->cpi_ == nullptr) {
28     return nullptr;
29   }
30   rc_api->InitRateControl(cfg);
31   return rc_api;
32 }
33
34 void VP9RateControlRTC::InitRateControl(const VP9RateControlRtcConfig &rc_cfg) {
35   VP9_COMMON *cm = &cpi_->common;
36   VP9EncoderConfig *oxcf = &cpi_->oxcf;
37   RATE_CONTROL *const rc = &cpi_->rc;
38   cm->profile = PROFILE_0;
39   cm->bit_depth = VPX_BITS_8;
40   cm->show_frame = 1;
41   oxcf->rc_mode = VPX_CBR;
42   oxcf->profile = cm->profile;
43   oxcf->bit_depth = cm->bit_depth;
44   oxcf->pass = 0;
45   oxcf->aq_mode = NO_AQ;
46   oxcf->content = VP9E_CONTENT_DEFAULT;
47   oxcf->drop_frames_water_mark = 0;
48
49   UpdateRateControl(rc_cfg);
50
51   cpi_->use_svc = (cpi_->svc.number_spatial_layers > 1 ||
52                    cpi_->svc.number_temporal_layers > 1)
53                       ? 1
54                       : 0;
55
56   rc->rc_1_frame = 0;
57   rc->rc_2_frame = 0;
58   vp9_rc_init_minq_luts();
59   vp9_rc_init(oxcf, 0, rc);
60   cpi_->sf.use_nonrd_pick_mode = 1;
61   cm->current_video_frame = 0;
62 }
63
64 void VP9RateControlRTC::UpdateRateControl(
65     const VP9RateControlRtcConfig &rc_cfg) {
66   VP9_COMMON *cm = &cpi_->common;
67   VP9EncoderConfig *oxcf = &cpi_->oxcf;
68   RATE_CONTROL *const rc = &cpi_->rc;
69
70   cm->width = rc_cfg.width;
71   cm->height = rc_cfg.height;
72   oxcf->width = rc_cfg.width;
73   oxcf->height = rc_cfg.height;
74   oxcf->worst_allowed_q = vp9_quantizer_to_qindex(rc_cfg.max_quantizer);
75   oxcf->best_allowed_q = vp9_quantizer_to_qindex(rc_cfg.min_quantizer);
76   rc->worst_quality = oxcf->worst_allowed_q;
77   rc->best_quality = oxcf->best_allowed_q;
78   oxcf->target_bandwidth = 1000 * rc_cfg.target_bandwidth;
79   oxcf->starting_buffer_level_ms = rc_cfg.buf_initial_sz;
80   oxcf->optimal_buffer_level_ms = rc_cfg.buf_optimal_sz;
81   oxcf->maximum_buffer_size_ms = rc_cfg.buf_sz;
82   oxcf->under_shoot_pct = rc_cfg.undershoot_pct;
83   oxcf->over_shoot_pct = rc_cfg.overshoot_pct;
84   oxcf->ss_number_layers = rc_cfg.ss_number_layers;
85   oxcf->ts_number_layers = rc_cfg.ts_number_layers;
86   oxcf->temporal_layering_mode = (VP9E_TEMPORAL_LAYERING_MODE)(
87       (rc_cfg.ts_number_layers > 1) ? rc_cfg.ts_number_layers : 0);
88
89   cpi_->oxcf.rc_max_intra_bitrate_pct = rc_cfg.max_intra_bitrate_pct;
90   cpi_->framerate = rc_cfg.framerate;
91   cpi_->svc.number_spatial_layers = rc_cfg.ss_number_layers;
92   cpi_->svc.number_temporal_layers = rc_cfg.ts_number_layers;
93
94   for (int sl = 0; sl < cpi_->svc.number_spatial_layers; ++sl) {
95     for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) {
96       const int layer =
97           LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers);
98       LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
99       RATE_CONTROL *const lrc = &lc->rc;
100       oxcf->layer_target_bitrate[layer] =
101           1000 * rc_cfg.layer_target_bitrate[layer];
102       lrc->worst_quality =
103           vp9_quantizer_to_qindex(rc_cfg.max_quantizers[layer]);
104       lrc->best_quality = vp9_quantizer_to_qindex(rc_cfg.min_quantizers[layer]);
105       lc->scaling_factor_num = rc_cfg.scaling_factor_num[sl];
106       lc->scaling_factor_den = rc_cfg.scaling_factor_den[sl];
107       oxcf->ts_rate_decimator[tl] = rc_cfg.ts_rate_decimator[tl];
108     }
109   }
110   vp9_set_rc_buffer_sizes(cpi_);
111   vp9_new_framerate(cpi_, cpi_->framerate);
112   if (cpi_->svc.number_temporal_layers > 1 ||
113       cpi_->svc.number_spatial_layers > 1) {
114     if (cm->current_video_frame == 0) vp9_init_layer_context(cpi_);
115     vp9_update_layer_context_change_config(cpi_,
116                                            (int)cpi_->oxcf.target_bandwidth);
117   }
118   vp9_check_reset_rc_flag(cpi_);
119 }
120
121 void VP9RateControlRTC::ComputeQP(const VP9FrameParamsQpRTC &frame_params) {
122   VP9_COMMON *const cm = &cpi_->common;
123   int width, height;
124   cpi_->svc.spatial_layer_id = frame_params.spatial_layer_id;
125   cpi_->svc.temporal_layer_id = frame_params.temporal_layer_id;
126   if (cpi_->svc.number_spatial_layers > 1) {
127     const int layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id,
128                                        cpi_->svc.temporal_layer_id,
129                                        cpi_->svc.number_temporal_layers);
130     LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
131     get_layer_resolution(cpi_->oxcf.width, cpi_->oxcf.height,
132                          lc->scaling_factor_num, lc->scaling_factor_den, &width,
133                          &height);
134     cm->width = width;
135     cm->height = height;
136   }
137   vp9_set_mb_mi(cm, cm->width, cm->height);
138   cm->frame_type = frame_params.frame_type;
139   cpi_->refresh_golden_frame = (cm->frame_type == KEY_FRAME) ? 1 : 0;
140   cpi_->sf.use_nonrd_pick_mode = 1;
141   if (cpi_->svc.number_spatial_layers == 1 &&
142       cpi_->svc.number_temporal_layers == 1) {
143     int target;
144     if (frame_is_intra_only(cm))
145       target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_);
146     else
147       target = vp9_calc_pframe_target_size_one_pass_cbr(cpi_);
148     vp9_rc_set_frame_target(cpi_, target);
149     vp9_update_buffer_level_preencode(cpi_);
150   } else {
151     vp9_update_temporal_layer_framerate(cpi_);
152     vp9_restore_layer_context(cpi_);
153     vp9_rc_get_svc_params(cpi_);
154   }
155   int bottom_index, top_index;
156   cpi_->common.base_qindex =
157       vp9_rc_pick_q_and_bounds(cpi_, &bottom_index, &top_index);
158 }
159
160 int VP9RateControlRTC::GetQP() const { return cpi_->common.base_qindex; }
161
162 int VP9RateControlRTC::GetLoopfilterLevel() const {
163   struct loopfilter *const lf = &cpi_->common.lf;
164   vp9_pick_filter_level(nullptr, cpi_, LPF_PICK_FROM_Q);
165   return lf->filter_level;
166 }
167
168 void VP9RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {
169   vp9_rc_postencode_update(cpi_, encoded_frame_size);
170   if (cpi_->svc.number_spatial_layers > 1 ||
171       cpi_->svc.number_temporal_layers > 1)
172     vp9_save_layer_context(cpi_);
173   cpi_->common.current_video_frame++;
174 }
175
176 }  // namespace libvpx