xref: /rockchip-linux_mpp/mpp/codec/rc/vp8e_rc.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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