1 /*
2 * Copyright 2016 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "vp8e_rc"
18
19 #include <math.h>
20 #include <string.h>
21
22 #include "mpp_env.h"
23 #include "mpp_mem.h"
24 #include "mpp_common.h"
25
26 #include "rc_debug.h"
27 #include "rc_ctx.h"
28 #include "rc_model_v2.h"
29
30 #define UPSCALE 8000
31
vp8_initial_qp(RK_S32 bits,RK_S32 pels)32 static RK_S32 vp8_initial_qp(RK_S32 bits, RK_S32 pels)
33 {
34 RK_S32 i = -1;
35 static const RK_S32 qp_tbl[2][12] = {
36 {47, 57, 73, 93, 122, 155, 214, 294, 373, 506, 781, 0x7FFFFFFF},
37 {120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10}
38 };
39
40 if (bits > 1000000)
41 return 10;
42
43 pels >>= 8;
44 bits >>= 5;
45
46 bits *= pels + 250;
47 bits /= 350 + (3 * pels) / 4;
48 bits = axb_div_c(bits, UPSCALE, pels << 6);
49
50 while (qp_tbl[0][++i] < bits);
51
52 return qp_tbl[1][i];
53 }
54
rc_model_v2_vp8_hal_start(void * ctx,EncRcTask * task)55 MPP_RET rc_model_v2_vp8_hal_start(void *ctx, EncRcTask *task)
56 {
57 RcModelV2Ctx *p = (RcModelV2Ctx *)ctx;
58 EncFrmStatus *frm = &task->frm;
59 EncRcTaskInfo *info = &task->info;
60 EncRcForceCfg *force = &task->force;
61 RcCfg *usr_cfg = &p->usr_cfg;
62 RK_S32 mb_w = MPP_ALIGN(usr_cfg->width, 16) / 16;
63 RK_S32 mb_h = MPP_ALIGN(usr_cfg->height, 16) / 16;
64 RK_S32 bit_min = info->bit_min;
65 RK_S32 bit_max = info->bit_max;
66 RK_S32 bit_target = info->bit_target;
67 RK_S32 quality_min = info->quality_min;
68 RK_S32 quality_max = info->quality_max;
69 RK_S32 quality_target = info->quality_target;
70
71 rc_dbg_func("enter p %p task %p\n", p, task);
72
73 rc_dbg_rc("seq_idx %d intra %d\n", frm->seq_idx, frm->is_intra);
74
75 if (force->force_flag & ENC_RC_FORCE_QP) {
76 RK_S32 qp = force->force_qp;
77 info->quality_target = qp;
78 info->quality_max = qp;
79 info->quality_min = qp;
80 return MPP_OK;
81 }
82
83 if (usr_cfg->mode == RC_FIXQP)
84 return MPP_OK;
85
86 /* setup quality parameters */
87 if (p->first_frm_flg && frm->is_intra) {
88 if (info->quality_target < 0) {
89 if (info->bit_target) {
90 p->start_qp = vp8_initial_qp(info->bit_target, mb_w * mb_h * 16 * 16);
91 p->cur_scale_qp = (p->start_qp) << 6;
92 } else {
93 mpp_log("fix qp case but init qp no set");
94 info->quality_target = 40;
95 p->start_qp = 40;
96 p->cur_scale_qp = (p->start_qp) << 6;
97 }
98 } else {
99 p->start_qp = info->quality_target;
100 p->cur_scale_qp = (p->start_qp) << 6;
101 }
102
103 if (p->reenc_cnt > 0) {
104 p->cur_scale_qp += p->next_ratio;
105 p->start_qp = p->cur_scale_qp >> 6;
106 rc_dbg_rc("p->start_qp = %d, p->cur_scale_qp %d,p->next_ratio %d ", p->start_qp, p->cur_scale_qp, p->next_ratio);
107 } else {
108 p->start_qp -= usr_cfg->i_quality_delta;
109 }
110 p->cur_scale_qp = mpp_clip(p->cur_scale_qp, (info->quality_min << 6), (info->quality_max << 6));
111 p->pre_i_qp = p->cur_scale_qp >> 6;
112 p->pre_p_qp = p->cur_scale_qp >> 6;
113 } else {
114 RK_S32 qp_scale = p->cur_scale_qp + p->next_ratio;
115 RK_S32 start_qp = 0;
116 RK_S32 dealt_qp = 0;
117
118 if (frm->is_intra) {
119 qp_scale = mpp_clip(qp_scale, (info->quality_min << 6), (info->quality_max << 6));
120
121 start_qp = ((p->pre_i_qp + ((qp_scale + p->next_i_ratio) >> 6)) >> 1);
122
123 start_qp = mpp_clip(start_qp, info->quality_min, info->quality_max);
124 p->pre_i_qp = start_qp;
125 p->start_qp = start_qp;
126 p->cur_scale_qp = qp_scale;
127
128 if (usr_cfg->i_quality_delta && !p->reenc_cnt)
129 p->start_qp -= dealt_qp;
130 } else {
131 qp_scale = mpp_clip(qp_scale, (info->quality_min << 6), (info->quality_max << 6));
132 p->cur_scale_qp = qp_scale;
133 p->start_qp = qp_scale >> 6;
134 if (frm->ref_mode == REF_TO_PREV_INTRA && usr_cfg->vi_quality_delta) {
135 p->start_qp -= usr_cfg->vi_quality_delta;
136 }
137 }
138 rc_dbg_rc("i_quality_delta %d, vi_quality_delta %d", dealt_qp, usr_cfg->vi_quality_delta);
139 }
140
141 p->start_qp = mpp_clip(p->start_qp, info->quality_min, info->quality_max);
142 info->quality_target = p->start_qp;
143
144 rc_dbg_rc("bitrate [%d : %d : %d] -> [%d : %d : %d]\n",
145 bit_min, bit_target, bit_max,
146 info->bit_min, info->bit_target, info->bit_max);
147 rc_dbg_rc("quality [%d : %d : %d] -> [%d : %d : %d]\n",
148 quality_min, quality_target, quality_max,
149 info->quality_min, info->quality_target, info->quality_max);
150
151 rc_dbg_func("leave %p\n", p);
152 return MPP_OK;
153 }
154
155 const RcImplApi default_vp8e = {
156 "default",
157 MPP_VIDEO_CodingVP8,
158 sizeof(RcModelV2Ctx),
159 rc_model_v2_init,
160 rc_model_v2_deinit,
161 NULL,
162 rc_model_v2_check_reenc,
163 rc_model_v2_start,
164 rc_model_v2_end,
165 rc_model_v2_vp8_hal_start,
166 rc_model_v2_hal_end,
167 };
168