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