xref: /rockchip-linux_mpp/mpp/hal/rkenc/h264e/hal_h264e_vepu510_tune.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2  * Copyright 2024 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 #include "hal_enc_task.h"
18 #include "hal_h264e_vepu510_reg.h"
19 
20 #define HAL_H264E_DBG_CONTENT           (0x00000200)
21 #define hal_h264e_dbg_content(fmt, ...) hal_h264e_dbg_f(HAL_H264E_DBG_CONTENT, fmt, ## __VA_ARGS__)
22 
23 typedef struct HalH264eVepu510Tune_t {
24     HalH264eVepu510Ctx  *ctx;
25 
26     RK_U8 *qm_mv_buf; /* qpmap mv buffer */
27     RK_U32 qm_mv_buf_size;
28     Vepu510NpuOut *obj_out; /* object map from npu */
29 
30     RK_S32  pre_madp[2];
31     RK_S32  pre_madi[2];
32 } HalH264eVepu510Tune;
33 
vepu510_h264e_tune_init(HalH264eVepu510Ctx * ctx)34 static HalH264eVepu510Tune *vepu510_h264e_tune_init(HalH264eVepu510Ctx *ctx)
35 {
36     HalH264eVepu510Tune *tune = mpp_calloc(HalH264eVepu510Tune, 1);
37 
38     if (NULL == tune)
39         return tune;
40 
41     tune->ctx = ctx;
42     tune->pre_madi[0] = tune->pre_madi[1] = -1;
43     tune->pre_madp[0] = tune->pre_madp[1] = -1;
44 
45     return tune;
46 }
47 
vepu510_h264e_tune_deinit(void * tune)48 static void vepu510_h264e_tune_deinit(void *tune)
49 {
50     HalH264eVepu510Tune * t = (HalH264eVepu510Tune *)tune;
51     MPP_FREE(t->qm_mv_buf);
52     MPP_FREE(tune);
53 }
54 
vepu510_h264e_tune_qpmap_init(HalH264eVepu510Tune * tune)55 static MPP_RET vepu510_h264e_tune_qpmap_init(HalH264eVepu510Tune *tune)
56 {
57     HalH264eVepu510Ctx *ctx = tune->ctx;
58     HalVepu510RegSet *regs = ctx->regs_set;
59     H264eVepu510Frame *reg_frm = &regs->reg_frm;
60     RK_S32 w64 = MPP_ALIGN(ctx->cfg->prep.width, 64);
61     RK_S32 h16 = MPP_ALIGN(ctx->cfg->prep.height, 16);
62     RK_S32 roir_buf_fd = -1;
63 
64     if (ctx->roi_data) {
65         //TODO: external qpmap buffer
66     } else {
67         if (NULL == ctx->roir_buf) {
68             if (NULL == ctx->roi_grp)
69                 mpp_buffer_group_get_internal(&ctx->roi_grp, MPP_BUFFER_TYPE_ION);
70 
71             //TODO: bmap_mdc_dpth = 1 ???
72             ctx->roir_buf_size = w64 * h16 / 256 * 4;
73             mpp_buffer_get(ctx->roi_grp, &ctx->roir_buf, ctx->roir_buf_size);
74         }
75 
76         roir_buf_fd = mpp_buffer_get_fd(ctx->roir_buf);
77     }
78 
79     if (ctx->roir_buf == NULL) {
80         mpp_err("failed to get roir_buf\n");
81         return MPP_ERR_MALLOC;
82     }
83     reg_frm->common.adr_roir = roir_buf_fd;
84 
85     if (tune->qm_mv_buf == NULL) {
86         tune->qm_mv_buf_size = w64 * h16 / 256;
87         tune->qm_mv_buf = mpp_calloc(RK_U8, tune->qm_mv_buf_size);
88         if (NULL == tune->qm_mv_buf) {
89             mpp_err("failed to get qm_mv_buf\n");
90             return MPP_ERR_MALLOC;
91         }
92     }
93 
94     hal_h264e_dbg_detail("roir_buf_fd %d, size %d qm_mv_buf %p size %d\n",
95                          roir_buf_fd, ctx->roir_buf_size, tune->qm_mv_buf,
96                          tune->qm_mv_buf_size);
97     return MPP_OK;
98 }
99 
vepu510_h264e_tune_qpmap(void * p,HalEncTask * task)100 static void vepu510_h264e_tune_qpmap(void *p, HalEncTask *task)
101 {
102     HalH264eVepu510Tune *tune = (HalH264eVepu510Tune *)p;
103     MPP_RET ret = MPP_OK;
104 
105     (void)task;
106     hal_h264e_dbg_func("enter\n");
107 
108     ret = vepu510_h264e_tune_qpmap_init(tune);
109     if (ret != MPP_OK) {
110         mpp_err("failed to init qpmap\n");
111         return;
112     }
113 
114     hal_h264e_dbg_func("leave\n");
115 }
116 
vepu510_h264e_tune_reg_patch(void * p,HalEncTask * task)117 static void vepu510_h264e_tune_reg_patch(void *p, HalEncTask *task)
118 {
119     HalH264eVepu510Tune *tune = (HalH264eVepu510Tune *)p;
120 
121     if (NULL == tune)
122         return;
123 
124     HalH264eVepu510Ctx *ctx = tune->ctx;
125 
126     if (ctx->qpmap_en && (task->md_info != NULL))
127         vepu510_h264e_tune_qpmap(tune, task);
128 }
129 
vepu510_h264e_tune_stat_update(void * p,HalEncTask * task)130 static void vepu510_h264e_tune_stat_update(void *p, HalEncTask *task)
131 {
132     HalH264eVepu510Tune *tune = (HalH264eVepu510Tune *)p;
133 
134     if (NULL == tune)
135         return;
136 
137     EncRcTaskInfo *rc_info = &task->rc_task->info;
138     HalH264eVepu510Ctx *ctx = tune->ctx;
139     HalVepu510RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
140     Vepu510Status *st = &regs->reg_st;
141     RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
142     RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
143     RK_U32 b16_num = mb_w * mb_h;
144     RK_U32 madi_cnt = 0;
145 
146     RK_U32 madi_th_cnt0 = st->st_madi_lt_num0.madi_th_lt_cnt0 +
147                           st->st_madi_rt_num0.madi_th_rt_cnt0 +
148                           st->st_madi_lb_num0.madi_th_lb_cnt0 +
149                           st->st_madi_rb_num0.madi_th_rb_cnt0;
150     RK_U32 madi_th_cnt1 = st->st_madi_lt_num0.madi_th_lt_cnt1 +
151                           st->st_madi_rt_num0.madi_th_rt_cnt1 +
152                           st->st_madi_lb_num0.madi_th_lb_cnt1 +
153                           st->st_madi_rb_num0.madi_th_rb_cnt1;
154     RK_U32 madi_th_cnt2 = st->st_madi_lt_num1.madi_th_lt_cnt2 +
155                           st->st_madi_rt_num1.madi_th_rt_cnt2 +
156                           st->st_madi_lb_num1.madi_th_lb_cnt2 +
157                           st->st_madi_rb_num1.madi_th_rb_cnt2;
158     RK_U32 madi_th_cnt3 = st->st_madi_lt_num1.madi_th_lt_cnt3 +
159                           st->st_madi_rt_num1.madi_th_rt_cnt3 +
160                           st->st_madi_lb_num1.madi_th_lb_cnt3 +
161                           st->st_madi_rb_num1.madi_th_rb_cnt3;
162     RK_U32 madp_th_cnt0 = st->st_madp_lt_num0.madp_th_lt_cnt0 +
163                           st->st_madp_rt_num0.madp_th_rt_cnt0 +
164                           st->st_madp_lb_num0.madp_th_lb_cnt0 +
165                           st->st_madp_rb_num0.madp_th_rb_cnt0;
166     RK_U32 madp_th_cnt1 = st->st_madp_lt_num0.madp_th_lt_cnt1 +
167                           st->st_madp_rt_num0.madp_th_rt_cnt1 +
168                           st->st_madp_lb_num0.madp_th_lb_cnt1 +
169                           st->st_madp_rb_num0.madp_th_rb_cnt1;
170     RK_U32 madp_th_cnt2 = st->st_madp_lt_num1.madp_th_lt_cnt2 +
171                           st->st_madp_rt_num1.madp_th_rt_cnt2 +
172                           st->st_madp_lb_num1.madp_th_lb_cnt2 +
173                           st->st_madp_rb_num1.madp_th_rb_cnt2;
174     RK_U32 madp_th_cnt3 = st->st_madp_lt_num1.madp_th_lt_cnt3 +
175                           st->st_madp_rt_num1.madp_th_rt_cnt3 +
176                           st->st_madp_lb_num1.madp_th_lb_cnt3 +
177                           st->st_madp_rb_num1.madp_th_rb_cnt3;
178 
179     madi_cnt = (6 * madi_th_cnt3 + 5 * madi_th_cnt2 + 4 * madi_th_cnt1) >> 2;
180     rc_info->complex_level = (madi_cnt * 100 > 30 * b16_num) ? 2 :
181                              (madi_cnt * 100 > 13 * b16_num) ? 1 : 0;
182 
183     {
184         RK_U32 md_cnt = 0, motion_level = 0;
185 
186         if (ctx->smart_en)
187             md_cnt = (12 * madp_th_cnt3 + 11 * madp_th_cnt2 + 8 * madp_th_cnt1) >> 2;
188         else
189             md_cnt = (24 * madp_th_cnt3 + 22 * madp_th_cnt2 + 17 * madp_th_cnt1) >> 2;
190 
191         if (md_cnt * 100 > 15 * b16_num)
192             motion_level = 200;
193         else if (md_cnt * 100 > 5 * b16_num)
194             motion_level = 100;
195         else if (md_cnt * 100 > (b16_num >> 2))
196             motion_level = 1;
197         else
198             motion_level = 0;
199         rc_info->motion_level = motion_level;
200     }
201     hal_h264e_dbg_rc("complex_level %d motion_level %d\n",
202                      rc_info->complex_level, rc_info->motion_level);
203 
204     (void)madi_th_cnt0;
205     (void)madp_th_cnt0;
206 }
207