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