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