1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka * Copyright 2015 - 2017 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 #define MODULE_TAG "hal_h264e_vepu_v2"
17*437bfbebSnyanmisaka
18*437bfbebSnyanmisaka #include <string.h>
19*437bfbebSnyanmisaka
20*437bfbebSnyanmisaka #include "mpp_mem.h"
21*437bfbebSnyanmisaka #include "mpp_common.h"
22*437bfbebSnyanmisaka #include "mpp_buffer.h"
23*437bfbebSnyanmisaka #include "mpp_enc_ref.h"
24*437bfbebSnyanmisaka
25*437bfbebSnyanmisaka #include "vepu_common.h"
26*437bfbebSnyanmisaka
27*437bfbebSnyanmisaka #include "h264e_slice.h"
28*437bfbebSnyanmisaka #include "hal_h264e_debug.h"
29*437bfbebSnyanmisaka #include "hal_h264e_vepu_v2.h"
30*437bfbebSnyanmisaka #include "hal_h264e_vpu_tbl_v2.h"
31*437bfbebSnyanmisaka
32*437bfbebSnyanmisaka typedef struct HalH264eVepuMbRcImpl_t {
33*437bfbebSnyanmisaka RK_S32 width;
34*437bfbebSnyanmisaka RK_S32 height;
35*437bfbebSnyanmisaka RK_S32 mb_w;
36*437bfbebSnyanmisaka RK_S32 mb_h;
37*437bfbebSnyanmisaka
38*437bfbebSnyanmisaka RK_S32 pels;
39*437bfbebSnyanmisaka RK_S32 mbs;
40*437bfbebSnyanmisaka
41*437bfbebSnyanmisaka RK_S32 bits_per_pic;
42*437bfbebSnyanmisaka
43*437bfbebSnyanmisaka RK_S32 mb_bit_rc_enable;
44*437bfbebSnyanmisaka
45*437bfbebSnyanmisaka /* frame rate control */
46*437bfbebSnyanmisaka RK_S32 fps_in_num;
47*437bfbebSnyanmisaka RK_S32 fps_in_denom;
48*437bfbebSnyanmisaka RK_S32 fps_out_num;
49*437bfbebSnyanmisaka RK_S32 fps_out_denom;
50*437bfbebSnyanmisaka
51*437bfbebSnyanmisaka RK_S32 fps_count;
52*437bfbebSnyanmisaka RK_S32 fps_step;
53*437bfbebSnyanmisaka RK_S32 fps_threshold;
54*437bfbebSnyanmisaka
55*437bfbebSnyanmisaka /*
56*437bfbebSnyanmisaka * MAD based QP adjustment
57*437bfbebSnyanmisaka * mad_qp_change [-8..7]
58*437bfbebSnyanmisaka * mad_threshold MAD threshold div256
59*437bfbebSnyanmisaka */
60*437bfbebSnyanmisaka RK_S32 mad_qp_change;
61*437bfbebSnyanmisaka RK_S32 mad_threshold;
62*437bfbebSnyanmisaka
63*437bfbebSnyanmisaka /*
64*437bfbebSnyanmisaka * check point parameter
65*437bfbebSnyanmisaka */
66*437bfbebSnyanmisaka RK_S32 check_point_count;
67*437bfbebSnyanmisaka RK_S32 check_point_distance;
68*437bfbebSnyanmisaka
69*437bfbebSnyanmisaka /* estimated first I frame qp */
70*437bfbebSnyanmisaka RK_S32 qp_init_est;
71*437bfbebSnyanmisaka
72*437bfbebSnyanmisaka RK_S32 frame_type;
73*437bfbebSnyanmisaka RK_S32 pre_frame_type;
74*437bfbebSnyanmisaka } HalH264eVepuMbRcImpl;
75*437bfbebSnyanmisaka
exp_golomb_signed(RK_S32 val)76*437bfbebSnyanmisaka RK_S32 exp_golomb_signed(RK_S32 val)
77*437bfbebSnyanmisaka {
78*437bfbebSnyanmisaka RK_S32 tmp = 0;
79*437bfbebSnyanmisaka
80*437bfbebSnyanmisaka if (val > 0)
81*437bfbebSnyanmisaka val = 2 * val;
82*437bfbebSnyanmisaka else
83*437bfbebSnyanmisaka val = -2 * val + 1;
84*437bfbebSnyanmisaka
85*437bfbebSnyanmisaka while (val >> ++tmp)
86*437bfbebSnyanmisaka ;
87*437bfbebSnyanmisaka
88*437bfbebSnyanmisaka return tmp * 2 - 1;
89*437bfbebSnyanmisaka }
90*437bfbebSnyanmisaka
vepu_swap_endian(RK_U32 * buf,RK_S32 size_bytes)91*437bfbebSnyanmisaka static void vepu_swap_endian(RK_U32 *buf, RK_S32 size_bytes)
92*437bfbebSnyanmisaka {
93*437bfbebSnyanmisaka RK_U32 i = 0;
94*437bfbebSnyanmisaka RK_S32 words = size_bytes / 4;
95*437bfbebSnyanmisaka RK_U32 val, val2, tmp, tmp2;
96*437bfbebSnyanmisaka
97*437bfbebSnyanmisaka mpp_assert((size_bytes % 8) == 0);
98*437bfbebSnyanmisaka
99*437bfbebSnyanmisaka while (words > 0) {
100*437bfbebSnyanmisaka val = buf[i];
101*437bfbebSnyanmisaka tmp = 0;
102*437bfbebSnyanmisaka
103*437bfbebSnyanmisaka tmp |= (val & 0xFF) << 24;
104*437bfbebSnyanmisaka tmp |= (val & 0xFF00) << 8;
105*437bfbebSnyanmisaka tmp |= (val & 0xFF0000) >> 8;
106*437bfbebSnyanmisaka tmp |= (val & 0xFF000000) >> 24;
107*437bfbebSnyanmisaka {
108*437bfbebSnyanmisaka val2 = buf[i + 1];
109*437bfbebSnyanmisaka tmp2 = 0;
110*437bfbebSnyanmisaka
111*437bfbebSnyanmisaka tmp2 |= (val2 & 0xFF) << 24;
112*437bfbebSnyanmisaka tmp2 |= (val2 & 0xFF00) << 8;
113*437bfbebSnyanmisaka tmp2 |= (val2 & 0xFF0000) >> 8;
114*437bfbebSnyanmisaka tmp2 |= (val2 & 0xFF000000) >> 24;
115*437bfbebSnyanmisaka
116*437bfbebSnyanmisaka buf[i] = tmp2;
117*437bfbebSnyanmisaka words--;
118*437bfbebSnyanmisaka i++;
119*437bfbebSnyanmisaka }
120*437bfbebSnyanmisaka buf[i] = tmp;
121*437bfbebSnyanmisaka words--;
122*437bfbebSnyanmisaka i++;
123*437bfbebSnyanmisaka }
124*437bfbebSnyanmisaka }
125*437bfbebSnyanmisaka
vepu_write_cabac_table(MppBuffer buf,RK_S32 cabac_init_idc)126*437bfbebSnyanmisaka static void vepu_write_cabac_table(MppBuffer buf, RK_S32 cabac_init_idc)
127*437bfbebSnyanmisaka {
128*437bfbebSnyanmisaka const RK_S32(*context)[460][2];
129*437bfbebSnyanmisaka RK_S32 i, j, qp;
130*437bfbebSnyanmisaka RK_U8 table[H264E_CABAC_TABLE_BUF_SIZE] = {0};
131*437bfbebSnyanmisaka
132*437bfbebSnyanmisaka for (qp = 0; qp < 52; qp++) { /* All QP values */
133*437bfbebSnyanmisaka for (j = 0; j < 2; j++) { /* Intra/Inter */
134*437bfbebSnyanmisaka if (j == 0)
135*437bfbebSnyanmisaka /*lint -e(545) */
136*437bfbebSnyanmisaka context = &h264_context_init_intra;
137*437bfbebSnyanmisaka else
138*437bfbebSnyanmisaka /*lint -e(545) */
139*437bfbebSnyanmisaka context = &h264_context_init[cabac_init_idc];
140*437bfbebSnyanmisaka
141*437bfbebSnyanmisaka for (i = 0; i < 460; i++) {
142*437bfbebSnyanmisaka RK_S32 m = (RK_S32)(*context)[i][0];
143*437bfbebSnyanmisaka RK_S32 n = (RK_S32)(*context)[i][1];
144*437bfbebSnyanmisaka
145*437bfbebSnyanmisaka RK_S32 pre_ctx_state = MPP_CLIP3(1, 126, ((m * (RK_S32)qp) >> 4) + n);
146*437bfbebSnyanmisaka
147*437bfbebSnyanmisaka if (pre_ctx_state <= 63)
148*437bfbebSnyanmisaka table[qp * 464 * 2 + j * 464 + i] =
149*437bfbebSnyanmisaka (RK_U8)((63 - pre_ctx_state) << 1);
150*437bfbebSnyanmisaka else
151*437bfbebSnyanmisaka table[qp * 464 * 2 + j * 464 + i] =
152*437bfbebSnyanmisaka (RK_U8)(((pre_ctx_state - 64) << 1) | 1);
153*437bfbebSnyanmisaka }
154*437bfbebSnyanmisaka }
155*437bfbebSnyanmisaka }
156*437bfbebSnyanmisaka
157*437bfbebSnyanmisaka vepu_swap_endian((RK_U32 *)table, H264E_CABAC_TABLE_BUF_SIZE);
158*437bfbebSnyanmisaka mpp_buffer_write(buf, 0, table, H264E_CABAC_TABLE_BUF_SIZE);
159*437bfbebSnyanmisaka }
160*437bfbebSnyanmisaka
h264e_vepu_buf_init(HalH264eVepuBufs * bufs)161*437bfbebSnyanmisaka MPP_RET h264e_vepu_buf_init(HalH264eVepuBufs *bufs)
162*437bfbebSnyanmisaka {
163*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
164*437bfbebSnyanmisaka
165*437bfbebSnyanmisaka hal_h264e_dbg_buffer("enter %p\n", bufs);
166*437bfbebSnyanmisaka
167*437bfbebSnyanmisaka memset(bufs, 0, sizeof(*bufs));
168*437bfbebSnyanmisaka
169*437bfbebSnyanmisaka // do not create buffer on cavlc case
170*437bfbebSnyanmisaka bufs->cabac_init_idc = -1;
171*437bfbebSnyanmisaka ret = mpp_buffer_group_get_internal(&bufs->group, MPP_BUFFER_TYPE_ION);
172*437bfbebSnyanmisaka if (ret)
173*437bfbebSnyanmisaka mpp_err_f("get buffer group failed ret %d\n", ret);
174*437bfbebSnyanmisaka
175*437bfbebSnyanmisaka hal_h264e_dbg_buffer("leave %p\n", bufs);
176*437bfbebSnyanmisaka
177*437bfbebSnyanmisaka return ret;
178*437bfbebSnyanmisaka }
179*437bfbebSnyanmisaka
h264e_vepu_buf_deinit(HalH264eVepuBufs * bufs)180*437bfbebSnyanmisaka MPP_RET h264e_vepu_buf_deinit(HalH264eVepuBufs *bufs)
181*437bfbebSnyanmisaka {
182*437bfbebSnyanmisaka RK_S32 i;
183*437bfbebSnyanmisaka
184*437bfbebSnyanmisaka hal_h264e_dbg_buffer("enter %p\n", bufs);
185*437bfbebSnyanmisaka
186*437bfbebSnyanmisaka if (bufs->cabac_table)
187*437bfbebSnyanmisaka mpp_buffer_put(bufs->cabac_table);
188*437bfbebSnyanmisaka
189*437bfbebSnyanmisaka if (bufs->nal_size_table)
190*437bfbebSnyanmisaka mpp_buffer_put(bufs->nal_size_table);
191*437bfbebSnyanmisaka
192*437bfbebSnyanmisaka for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(bufs->frm_buf); i++) {
193*437bfbebSnyanmisaka if (bufs->frm_buf[i])
194*437bfbebSnyanmisaka mpp_buffer_put(bufs->frm_buf[i]);
195*437bfbebSnyanmisaka }
196*437bfbebSnyanmisaka
197*437bfbebSnyanmisaka if (bufs->group)
198*437bfbebSnyanmisaka mpp_buffer_group_put(bufs->group);
199*437bfbebSnyanmisaka
200*437bfbebSnyanmisaka memset(bufs, 0, sizeof(*bufs));
201*437bfbebSnyanmisaka bufs->cabac_init_idc = -1;
202*437bfbebSnyanmisaka
203*437bfbebSnyanmisaka hal_h264e_dbg_buffer("leave %p\n", bufs);
204*437bfbebSnyanmisaka
205*437bfbebSnyanmisaka return MPP_OK;
206*437bfbebSnyanmisaka }
207*437bfbebSnyanmisaka
h264e_vepu_buf_set_cabac_idc(HalH264eVepuBufs * bufs,RK_S32 idc)208*437bfbebSnyanmisaka MPP_RET h264e_vepu_buf_set_cabac_idc(HalH264eVepuBufs *bufs, RK_S32 idc)
209*437bfbebSnyanmisaka {
210*437bfbebSnyanmisaka hal_h264e_dbg_buffer("enter %p\n", bufs);
211*437bfbebSnyanmisaka
212*437bfbebSnyanmisaka if (idc >= 0 && !bufs->cabac_table)
213*437bfbebSnyanmisaka mpp_buffer_get(bufs->group, &bufs->cabac_table, H264E_CABAC_TABLE_BUF_SIZE);
214*437bfbebSnyanmisaka
215*437bfbebSnyanmisaka if (bufs->cabac_table && idc != bufs->cabac_init_idc && idc >= 0)
216*437bfbebSnyanmisaka vepu_write_cabac_table(bufs->cabac_table, idc);
217*437bfbebSnyanmisaka
218*437bfbebSnyanmisaka bufs->cabac_init_idc = idc;
219*437bfbebSnyanmisaka
220*437bfbebSnyanmisaka hal_h264e_dbg_buffer("leave %p\n", bufs);
221*437bfbebSnyanmisaka
222*437bfbebSnyanmisaka return MPP_OK;
223*437bfbebSnyanmisaka }
224*437bfbebSnyanmisaka
h264e_vepu_buf_set_frame_size(HalH264eVepuBufs * bufs,RK_S32 w,RK_S32 h)225*437bfbebSnyanmisaka MPP_RET h264e_vepu_buf_set_frame_size(HalH264eVepuBufs *bufs, RK_S32 w, RK_S32 h)
226*437bfbebSnyanmisaka {
227*437bfbebSnyanmisaka RK_S32 aligned_w = MPP_ALIGN(w, 16);
228*437bfbebSnyanmisaka RK_S32 aligned_h = MPP_ALIGN(h, 16);
229*437bfbebSnyanmisaka size_t yuv_size = aligned_w * aligned_h;
230*437bfbebSnyanmisaka size_t frm_size = yuv_size * 3 / 2;
231*437bfbebSnyanmisaka RK_S32 i;
232*437bfbebSnyanmisaka RK_S32 cnt = (RK_S32)MPP_ARRAY_ELEMS(bufs->frm_buf);
233*437bfbebSnyanmisaka
234*437bfbebSnyanmisaka hal_h264e_dbg_buffer("enter %p\n", bufs);
235*437bfbebSnyanmisaka
236*437bfbebSnyanmisaka mpp_assert(frm_size);
237*437bfbebSnyanmisaka
238*437bfbebSnyanmisaka if (frm_size != bufs->frm_size) {
239*437bfbebSnyanmisaka if (bufs->frm_size) {
240*437bfbebSnyanmisaka /* reallocate only on larger frame size to save time */
241*437bfbebSnyanmisaka mpp_log("new frame size [%d:%d] require buffer %d not equal to %d\n",
242*437bfbebSnyanmisaka w, h, frm_size, bufs->frm_size);
243*437bfbebSnyanmisaka }
244*437bfbebSnyanmisaka
245*437bfbebSnyanmisaka for (i = 0; i < cnt; i++) {
246*437bfbebSnyanmisaka if (bufs->frm_buf[i]) {
247*437bfbebSnyanmisaka mpp_buffer_put(bufs->frm_buf[i]);
248*437bfbebSnyanmisaka bufs->frm_buf[i] = NULL;
249*437bfbebSnyanmisaka bufs->frm_cnt--;
250*437bfbebSnyanmisaka }
251*437bfbebSnyanmisaka }
252*437bfbebSnyanmisaka }
253*437bfbebSnyanmisaka
254*437bfbebSnyanmisaka bufs->mb_h = aligned_h >> 4;
255*437bfbebSnyanmisaka if (bufs->mb_h)
256*437bfbebSnyanmisaka bufs->nal_tab_size = MPP_ALIGN((bufs->mb_h + 1) * sizeof(RK_U32), 8);
257*437bfbebSnyanmisaka else
258*437bfbebSnyanmisaka bufs->nal_tab_size = 0;
259*437bfbebSnyanmisaka
260*437bfbebSnyanmisaka bufs->yuv_size = yuv_size;
261*437bfbebSnyanmisaka bufs->frm_size = frm_size;
262*437bfbebSnyanmisaka
263*437bfbebSnyanmisaka hal_h264e_dbg_buffer("leave %p\n", bufs);
264*437bfbebSnyanmisaka
265*437bfbebSnyanmisaka return MPP_OK;
266*437bfbebSnyanmisaka }
267*437bfbebSnyanmisaka
h264e_vepu_buf_get_nal_size_table(HalH264eVepuBufs * bufs)268*437bfbebSnyanmisaka MppBuffer h264e_vepu_buf_get_nal_size_table(HalH264eVepuBufs *bufs)
269*437bfbebSnyanmisaka {
270*437bfbebSnyanmisaka MppBuffer buf = bufs->nal_size_table;
271*437bfbebSnyanmisaka
272*437bfbebSnyanmisaka hal_h264e_dbg_buffer("enter %p\n", bufs);
273*437bfbebSnyanmisaka
274*437bfbebSnyanmisaka if (NULL == buf) {
275*437bfbebSnyanmisaka mpp_buffer_get(bufs->group, &buf, bufs->nal_tab_size);
276*437bfbebSnyanmisaka mpp_assert(buf);
277*437bfbebSnyanmisaka bufs->nal_size_table = buf;
278*437bfbebSnyanmisaka }
279*437bfbebSnyanmisaka
280*437bfbebSnyanmisaka hal_h264e_dbg_buffer("leave %p\n", bufs);
281*437bfbebSnyanmisaka
282*437bfbebSnyanmisaka return buf;
283*437bfbebSnyanmisaka }
284*437bfbebSnyanmisaka
h264e_vepu_buf_get_frame_buffer(HalH264eVepuBufs * bufs,RK_S32 index)285*437bfbebSnyanmisaka MppBuffer h264e_vepu_buf_get_frame_buffer(HalH264eVepuBufs *bufs, RK_S32 index)
286*437bfbebSnyanmisaka {
287*437bfbebSnyanmisaka MppBuffer buf = bufs->frm_buf[index];
288*437bfbebSnyanmisaka
289*437bfbebSnyanmisaka hal_h264e_dbg_buffer("enter\n", bufs);
290*437bfbebSnyanmisaka
291*437bfbebSnyanmisaka if (NULL == buf) {
292*437bfbebSnyanmisaka mpp_buffer_get(bufs->group, &buf, bufs->frm_size);
293*437bfbebSnyanmisaka mpp_assert(buf);
294*437bfbebSnyanmisaka bufs->frm_buf[index] = buf;
295*437bfbebSnyanmisaka bufs->frm_cnt++;
296*437bfbebSnyanmisaka }
297*437bfbebSnyanmisaka
298*437bfbebSnyanmisaka hal_h264e_dbg_buffer("leave %p\n", bufs);
299*437bfbebSnyanmisaka
300*437bfbebSnyanmisaka return buf;
301*437bfbebSnyanmisaka }
302*437bfbebSnyanmisaka
h264e_vepu_prep_setup(HalH264eVepuPrep * prep,MppEncPrepCfg * cfg)303*437bfbebSnyanmisaka MPP_RET h264e_vepu_prep_setup(HalH264eVepuPrep *prep, MppEncPrepCfg *cfg)
304*437bfbebSnyanmisaka {
305*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
306*437bfbebSnyanmisaka MppFrameFormat format = cfg->format;
307*437bfbebSnyanmisaka VepuFormatCfg fmt_cfg;
308*437bfbebSnyanmisaka RK_U32 width = cfg->width;
309*437bfbebSnyanmisaka RK_U32 height = cfg->height;
310*437bfbebSnyanmisaka RK_U32 rotation = 0;
311*437bfbebSnyanmisaka
312*437bfbebSnyanmisaka hal_h264e_dbg_buffer("enter\n");
313*437bfbebSnyanmisaka
314*437bfbebSnyanmisaka // do not support mirroring
315*437bfbebSnyanmisaka if (cfg->mirroring)
316*437bfbebSnyanmisaka mpp_err_f("Warning: do not support mirroring\n");
317*437bfbebSnyanmisaka
318*437bfbebSnyanmisaka if (cfg->rotation == MPP_ENC_ROT_90)
319*437bfbebSnyanmisaka rotation = 1;
320*437bfbebSnyanmisaka else if (cfg->rotation == MPP_ENC_ROT_270)
321*437bfbebSnyanmisaka rotation = 2;
322*437bfbebSnyanmisaka else if (cfg->rotation != MPP_ENC_ROT_0)
323*437bfbebSnyanmisaka mpp_err_f("Warning: only support 90 or 270 degree rotate, request rotate %d", rotation);
324*437bfbebSnyanmisaka
325*437bfbebSnyanmisaka if (rotation)
326*437bfbebSnyanmisaka MPP_SWAP(RK_U32, width, height);
327*437bfbebSnyanmisaka
328*437bfbebSnyanmisaka prep->src_fmt = format;
329*437bfbebSnyanmisaka prep->rotation = rotation;
330*437bfbebSnyanmisaka prep->src_w = width;
331*437bfbebSnyanmisaka prep->src_h = height;
332*437bfbebSnyanmisaka
333*437bfbebSnyanmisaka if (!get_vepu_fmt(&fmt_cfg, format)) {
334*437bfbebSnyanmisaka prep->r_mask_msb = fmt_cfg.r_mask;
335*437bfbebSnyanmisaka prep->g_mask_msb = fmt_cfg.g_mask;
336*437bfbebSnyanmisaka prep->b_mask_msb = fmt_cfg.b_mask;
337*437bfbebSnyanmisaka prep->swap_8_in = fmt_cfg.swap_8_in;
338*437bfbebSnyanmisaka prep->swap_16_in = fmt_cfg.swap_16_in;
339*437bfbebSnyanmisaka prep->swap_32_in = fmt_cfg.swap_32_in;
340*437bfbebSnyanmisaka prep->src_fmt = fmt_cfg.format;
341*437bfbebSnyanmisaka } else {
342*437bfbebSnyanmisaka prep->src_fmt = VEPU_FMT_BUTT;
343*437bfbebSnyanmisaka }
344*437bfbebSnyanmisaka
345*437bfbebSnyanmisaka if (format < MPP_FRAME_FMT_RGB) {
346*437bfbebSnyanmisaka // YUV case
347*437bfbebSnyanmisaka if (prep->src_fmt == VEPU_FMT_BUTT) {
348*437bfbebSnyanmisaka mpp_err("vepu do not support input frame format %d\n", format);
349*437bfbebSnyanmisaka ret = MPP_NOK;
350*437bfbebSnyanmisaka }
351*437bfbebSnyanmisaka
352*437bfbebSnyanmisaka prep->color_conversion_coeff_a = 0;
353*437bfbebSnyanmisaka prep->color_conversion_coeff_b = 0;
354*437bfbebSnyanmisaka prep->color_conversion_coeff_c = 0;
355*437bfbebSnyanmisaka prep->color_conversion_coeff_e = 0;
356*437bfbebSnyanmisaka prep->color_conversion_coeff_f = 0;
357*437bfbebSnyanmisaka } else {
358*437bfbebSnyanmisaka
359*437bfbebSnyanmisaka if (prep->src_fmt == VEPU_FMT_BUTT) {
360*437bfbebSnyanmisaka mpp_err("vepu do not support input frame format %d\n", format);
361*437bfbebSnyanmisaka ret = MPP_NOK;
362*437bfbebSnyanmisaka }
363*437bfbebSnyanmisaka
364*437bfbebSnyanmisaka switch (cfg->color) {
365*437bfbebSnyanmisaka case MPP_FRAME_SPC_RGB : {
366*437bfbebSnyanmisaka /* BT.601 */
367*437bfbebSnyanmisaka /* Y = 0.2989 R + 0.5866 G + 0.1145 B
368*437bfbebSnyanmisaka * Cb = 0.5647 (B - Y) + 128
369*437bfbebSnyanmisaka * Cr = 0.7132 (R - Y) + 128
370*437bfbebSnyanmisaka */
371*437bfbebSnyanmisaka prep->color_conversion_coeff_a = 19589;
372*437bfbebSnyanmisaka prep->color_conversion_coeff_b = 38443;
373*437bfbebSnyanmisaka prep->color_conversion_coeff_c = 7504;
374*437bfbebSnyanmisaka prep->color_conversion_coeff_e = 37008;
375*437bfbebSnyanmisaka prep->color_conversion_coeff_f = 46740;
376*437bfbebSnyanmisaka } break;
377*437bfbebSnyanmisaka case MPP_FRAME_SPC_BT709 : {
378*437bfbebSnyanmisaka /* BT.709 */
379*437bfbebSnyanmisaka /* Y = 0.2126 R + 0.7152 G + 0.0722 B
380*437bfbebSnyanmisaka * Cb = 0.5389 (B - Y) + 128
381*437bfbebSnyanmisaka * Cr = 0.6350 (R - Y) + 128
382*437bfbebSnyanmisaka */
383*437bfbebSnyanmisaka prep->color_conversion_coeff_a = 13933;
384*437bfbebSnyanmisaka prep->color_conversion_coeff_b = 46871;
385*437bfbebSnyanmisaka prep->color_conversion_coeff_c = 4732;
386*437bfbebSnyanmisaka prep->color_conversion_coeff_e = 35317;
387*437bfbebSnyanmisaka prep->color_conversion_coeff_f = 41615;
388*437bfbebSnyanmisaka } break;
389*437bfbebSnyanmisaka default : {
390*437bfbebSnyanmisaka prep->color_conversion_coeff_a = 19589;
391*437bfbebSnyanmisaka prep->color_conversion_coeff_b = 38443;
392*437bfbebSnyanmisaka prep->color_conversion_coeff_c = 7504;
393*437bfbebSnyanmisaka prep->color_conversion_coeff_e = 37008;
394*437bfbebSnyanmisaka prep->color_conversion_coeff_f = 46740;
395*437bfbebSnyanmisaka } break;
396*437bfbebSnyanmisaka }
397*437bfbebSnyanmisaka }
398*437bfbebSnyanmisaka
399*437bfbebSnyanmisaka /* NOTE: vepu only support 8bit encoding and stride must match with width align to 16 */
400*437bfbebSnyanmisaka RK_S32 hor_stride = cfg->hor_stride;
401*437bfbebSnyanmisaka RK_S32 ver_stride = cfg->ver_stride;
402*437bfbebSnyanmisaka VepuStrideCfg *stride_cfg = &prep->stride_cfg;
403*437bfbebSnyanmisaka
404*437bfbebSnyanmisaka prep->offset_cb = 0;
405*437bfbebSnyanmisaka prep->offset_cr = 0;
406*437bfbebSnyanmisaka get_vepu_pixel_stride(stride_cfg, prep->src_w, hor_stride, format);
407*437bfbebSnyanmisaka prep->pixel_stride = stride_cfg->pixel_stride;
408*437bfbebSnyanmisaka hor_stride = stride_cfg->pixel_stride * stride_cfg->pixel_size;
409*437bfbebSnyanmisaka
410*437bfbebSnyanmisaka switch (format & MPP_FRAME_FMT_MASK) {
411*437bfbebSnyanmisaka case MPP_FMT_YUV420SP : {
412*437bfbebSnyanmisaka prep->offset_cb = hor_stride * ver_stride;
413*437bfbebSnyanmisaka prep->size_y = hor_stride * MPP_ALIGN(prep->src_h, 16);
414*437bfbebSnyanmisaka prep->size_c = hor_stride / 2 * MPP_ALIGN(prep->src_h / 2, 8);
415*437bfbebSnyanmisaka } break;
416*437bfbebSnyanmisaka case MPP_FMT_YUV420P : {
417*437bfbebSnyanmisaka prep->offset_cb = hor_stride * ver_stride;
418*437bfbebSnyanmisaka prep->offset_cr = prep->offset_cb + ((hor_stride * ver_stride) / 4);
419*437bfbebSnyanmisaka prep->size_y = hor_stride * MPP_ALIGN(prep->src_h, 16);
420*437bfbebSnyanmisaka prep->size_c = hor_stride / 2 * MPP_ALIGN(prep->src_h / 2, 8);
421*437bfbebSnyanmisaka } break;
422*437bfbebSnyanmisaka case MPP_FMT_YUV422_YUYV :
423*437bfbebSnyanmisaka case MPP_FMT_YUV422_UYVY : {
424*437bfbebSnyanmisaka prep->size_y = hor_stride * MPP_ALIGN(prep->src_h, 16);
425*437bfbebSnyanmisaka prep->size_c = 0;
426*437bfbebSnyanmisaka } break;
427*437bfbebSnyanmisaka case MPP_FMT_RGB565 :
428*437bfbebSnyanmisaka case MPP_FMT_BGR565 :
429*437bfbebSnyanmisaka case MPP_FMT_RGB555 :
430*437bfbebSnyanmisaka case MPP_FMT_BGR555 :
431*437bfbebSnyanmisaka case MPP_FMT_RGB444 :
432*437bfbebSnyanmisaka case MPP_FMT_BGR444 : {
433*437bfbebSnyanmisaka prep->size_y = hor_stride * MPP_ALIGN(prep->src_h, 16);
434*437bfbebSnyanmisaka prep->size_c = 0;
435*437bfbebSnyanmisaka } break;
436*437bfbebSnyanmisaka case MPP_FMT_ARGB8888 :
437*437bfbebSnyanmisaka case MPP_FMT_ABGR8888 :
438*437bfbebSnyanmisaka case MPP_FMT_RGBA8888 :
439*437bfbebSnyanmisaka case MPP_FMT_BGRA8888 :
440*437bfbebSnyanmisaka case MPP_FMT_RGB101010 :
441*437bfbebSnyanmisaka case MPP_FMT_BGR101010 : {
442*437bfbebSnyanmisaka prep->size_y = hor_stride * MPP_ALIGN(prep->src_h, 16);
443*437bfbebSnyanmisaka prep->size_c = 0;
444*437bfbebSnyanmisaka } break;
445*437bfbebSnyanmisaka default: {
446*437bfbebSnyanmisaka mpp_err_f("invalid format %d", format);
447*437bfbebSnyanmisaka ret = MPP_NOK;
448*437bfbebSnyanmisaka }
449*437bfbebSnyanmisaka }
450*437bfbebSnyanmisaka
451*437bfbebSnyanmisaka hal_h264e_dbg_buffer("leave\n");
452*437bfbebSnyanmisaka
453*437bfbebSnyanmisaka return ret;
454*437bfbebSnyanmisaka }
455*437bfbebSnyanmisaka
h264e_vepu_prep_get_addr(HalH264eVepuPrep * prep,MppBuffer buffer,RK_U32 (* addr)[3])456*437bfbebSnyanmisaka MPP_RET h264e_vepu_prep_get_addr(HalH264eVepuPrep *prep, MppBuffer buffer,
457*437bfbebSnyanmisaka RK_U32 (*addr)[3])
458*437bfbebSnyanmisaka {
459*437bfbebSnyanmisaka RK_U32 fd = (RK_U32)mpp_buffer_get_fd(buffer);
460*437bfbebSnyanmisaka size_t size = mpp_buffer_get_size(buffer);
461*437bfbebSnyanmisaka
462*437bfbebSnyanmisaka hal_h264e_dbg_buffer("enter\n");
463*437bfbebSnyanmisaka
464*437bfbebSnyanmisaka (*addr)[0] = fd;
465*437bfbebSnyanmisaka (*addr)[1] = fd;
466*437bfbebSnyanmisaka (*addr)[2] = fd;
467*437bfbebSnyanmisaka
468*437bfbebSnyanmisaka if (size < prep->size_y)
469*437bfbebSnyanmisaka mpp_err("warnning: input buffer size 0x%x is smaller than required size 0x%x",
470*437bfbebSnyanmisaka size, prep->size_y);
471*437bfbebSnyanmisaka
472*437bfbebSnyanmisaka if (prep->size_c && (prep->offset_cb || prep->offset_cr)) {
473*437bfbebSnyanmisaka if (prep->offset_cb && (size < prep->offset_cb + prep->size_c))
474*437bfbebSnyanmisaka mpp_err("warnning: input buffer size 0x%x is smaller than cb requirement 0x%x + 0x%x",
475*437bfbebSnyanmisaka size, prep->offset_cb, prep->size_c);
476*437bfbebSnyanmisaka
477*437bfbebSnyanmisaka if (prep->offset_cr && (size < prep->offset_cr + prep->size_c))
478*437bfbebSnyanmisaka mpp_err("warnning: input buffer size 0x%x is smaller than cb requirement 0x%x + 0x%x",
479*437bfbebSnyanmisaka size, prep->offset_cr, prep->size_c);
480*437bfbebSnyanmisaka }
481*437bfbebSnyanmisaka
482*437bfbebSnyanmisaka hal_h264e_dbg_buffer("leave\n");
483*437bfbebSnyanmisaka
484*437bfbebSnyanmisaka return MPP_OK;
485*437bfbebSnyanmisaka }
486*437bfbebSnyanmisaka
h264e_vepu_mbrc_init(HalH264eVepuMbRcCtx * ctx,HalH264eVepuMbRc * mbrc)487*437bfbebSnyanmisaka MPP_RET h264e_vepu_mbrc_init(HalH264eVepuMbRcCtx *ctx, HalH264eVepuMbRc *mbrc)
488*437bfbebSnyanmisaka {
489*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
490*437bfbebSnyanmisaka HalH264eVepuMbRcImpl *p = mpp_calloc(HalH264eVepuMbRcImpl, 1);
491*437bfbebSnyanmisaka if (!p) {
492*437bfbebSnyanmisaka mpp_err_f("failed to alloc rate control context\n");
493*437bfbebSnyanmisaka ret = MPP_ERR_NOMEM;
494*437bfbebSnyanmisaka }
495*437bfbebSnyanmisaka
496*437bfbebSnyanmisaka memset(mbrc, 0, sizeof(*mbrc));
497*437bfbebSnyanmisaka mbrc->qp_init = -1;
498*437bfbebSnyanmisaka mbrc->qp_max = 48;
499*437bfbebSnyanmisaka mbrc->qp_min = 16;
500*437bfbebSnyanmisaka
501*437bfbebSnyanmisaka *ctx = p;
502*437bfbebSnyanmisaka return ret;
503*437bfbebSnyanmisaka }
504*437bfbebSnyanmisaka
h264e_vepu_mbrc_deinit(HalH264eVepuMbRcCtx ctx)505*437bfbebSnyanmisaka MPP_RET h264e_vepu_mbrc_deinit(HalH264eVepuMbRcCtx ctx)
506*437bfbebSnyanmisaka {
507*437bfbebSnyanmisaka MPP_FREE(ctx);
508*437bfbebSnyanmisaka return MPP_OK;
509*437bfbebSnyanmisaka }
510*437bfbebSnyanmisaka
h264e_vepu_mbrc_setup(HalH264eVepuMbRcCtx ctx,MppEncCfgSet * cfg)511*437bfbebSnyanmisaka MPP_RET h264e_vepu_mbrc_setup(HalH264eVepuMbRcCtx ctx, MppEncCfgSet*cfg)
512*437bfbebSnyanmisaka {
513*437bfbebSnyanmisaka HalH264eVepuMbRcImpl *p = (HalH264eVepuMbRcImpl *)ctx;
514*437bfbebSnyanmisaka MppEncPrepCfg *prep = &cfg->prep;
515*437bfbebSnyanmisaka MppEncRcCfg *rc = &cfg->rc;
516*437bfbebSnyanmisaka MppEncHwCfg* hw_cfg = &cfg->hw;
517*437bfbebSnyanmisaka
518*437bfbebSnyanmisaka hal_h264e_dbg_func("enter\n");
519*437bfbebSnyanmisaka
520*437bfbebSnyanmisaka // get necessary parameter from config
521*437bfbebSnyanmisaka p->width = prep->width;
522*437bfbebSnyanmisaka p->height = prep->height;
523*437bfbebSnyanmisaka p->mb_w = MPP_ALIGN(prep->width, 16) / 16;
524*437bfbebSnyanmisaka p->mb_h = MPP_ALIGN(prep->height, 16) / 16;
525*437bfbebSnyanmisaka p->pels = p->width * p->height;
526*437bfbebSnyanmisaka p->mbs = p->mb_w * p->mb_h;
527*437bfbebSnyanmisaka p->bits_per_pic = axb_div_c(rc->bps_target, rc->fps_out_denom,
528*437bfbebSnyanmisaka rc->fps_out_num);
529*437bfbebSnyanmisaka
530*437bfbebSnyanmisaka mpp_assert(p->pels);
531*437bfbebSnyanmisaka
532*437bfbebSnyanmisaka // frame rate control
533*437bfbebSnyanmisaka mpp_assert(rc->fps_out_num / rc->fps_out_denom <= rc->fps_in_num / rc->fps_in_denom);
534*437bfbebSnyanmisaka
535*437bfbebSnyanmisaka p->fps_in_num = rc->fps_in_num;
536*437bfbebSnyanmisaka p->fps_in_denom = rc->fps_in_denom;
537*437bfbebSnyanmisaka p->fps_out_num = rc->fps_out_num;
538*437bfbebSnyanmisaka p->fps_out_denom = rc->fps_out_denom;
539*437bfbebSnyanmisaka
540*437bfbebSnyanmisaka p->fps_step = rc->fps_in_denom * rc->fps_out_num;
541*437bfbebSnyanmisaka p->fps_threshold = rc->fps_in_num * rc->fps_out_denom;
542*437bfbebSnyanmisaka p->fps_count = p->fps_threshold;
543*437bfbebSnyanmisaka
544*437bfbebSnyanmisaka // if not constant
545*437bfbebSnyanmisaka p->mb_bit_rc_enable = !hw_cfg->mb_rc_disable && (rc->rc_mode != MPP_ENC_RC_MODE_FIXQP);
546*437bfbebSnyanmisaka
547*437bfbebSnyanmisaka hal_h264e_dbg_rc("estimated init qp %d\n", p->qp_init_est);
548*437bfbebSnyanmisaka
549*437bfbebSnyanmisaka // init first frame mad parameter
550*437bfbebSnyanmisaka p->mad_qp_change = 2;
551*437bfbebSnyanmisaka p->mad_threshold = 256 * 6;
552*437bfbebSnyanmisaka
553*437bfbebSnyanmisaka // init check point position
554*437bfbebSnyanmisaka if (p->mb_bit_rc_enable) {
555*437bfbebSnyanmisaka p->check_point_count = MPP_MIN(p->mb_h - 1, VEPU_CHECK_POINTS_MAX);
556*437bfbebSnyanmisaka p->check_point_distance = p->mbs / (p->check_point_count + 1);
557*437bfbebSnyanmisaka } else {
558*437bfbebSnyanmisaka p->check_point_count = 0;
559*437bfbebSnyanmisaka p->check_point_distance = 0;
560*437bfbebSnyanmisaka }
561*437bfbebSnyanmisaka
562*437bfbebSnyanmisaka p->frame_type = INTRA_FRAME;
563*437bfbebSnyanmisaka p->pre_frame_type = INTRA_FRAME;
564*437bfbebSnyanmisaka
565*437bfbebSnyanmisaka hal_h264e_dbg_func("leave\n");
566*437bfbebSnyanmisaka return MPP_OK;
567*437bfbebSnyanmisaka }
568*437bfbebSnyanmisaka
569*437bfbebSnyanmisaka #define WORD_CNT_MAX 65535
570*437bfbebSnyanmisaka
h264e_vepu_mbrc_prepare(HalH264eVepuMbRcCtx ctx,HalH264eVepuMbRc * mbrc,EncRcTask * rc_task)571*437bfbebSnyanmisaka MPP_RET h264e_vepu_mbrc_prepare(HalH264eVepuMbRcCtx ctx, HalH264eVepuMbRc *mbrc,
572*437bfbebSnyanmisaka EncRcTask *rc_task)
573*437bfbebSnyanmisaka {
574*437bfbebSnyanmisaka HalH264eVepuMbRcImpl *p = (HalH264eVepuMbRcImpl *)ctx;
575*437bfbebSnyanmisaka EncFrmStatus *frm = &rc_task->frm;
576*437bfbebSnyanmisaka EncRcTaskInfo *info = &rc_task->info;
577*437bfbebSnyanmisaka
578*437bfbebSnyanmisaka RK_S32 i;
579*437bfbebSnyanmisaka const RK_S32 sscale = 256;
580*437bfbebSnyanmisaka RK_S32 scaler, srcPrm;
581*437bfbebSnyanmisaka RK_S32 tmp, nonZeroTarget;
582*437bfbebSnyanmisaka RK_S32 coeffCntMax = p->mbs * 24 * 16;
583*437bfbebSnyanmisaka
584*437bfbebSnyanmisaka mbrc->qp_init = info->quality_target;
585*437bfbebSnyanmisaka mbrc->qp_min = info->quality_min;
586*437bfbebSnyanmisaka mbrc->qp_max = info->quality_max;
587*437bfbebSnyanmisaka mbrc->mad_qp_change = 0;
588*437bfbebSnyanmisaka mbrc->mad_threshold = 0;
589*437bfbebSnyanmisaka mbrc->cp_distance_mbs = 0;
590*437bfbebSnyanmisaka
591*437bfbebSnyanmisaka if (!p->mb_bit_rc_enable)
592*437bfbebSnyanmisaka return MPP_OK;
593*437bfbebSnyanmisaka
594*437bfbebSnyanmisaka p->pre_frame_type = p->frame_type;
595*437bfbebSnyanmisaka p->frame_type = (frm->is_intra) ? INTRA_FRAME : INTER_P_FRAME;
596*437bfbebSnyanmisaka
597*437bfbebSnyanmisaka if (mbrc->rlc_count == 0) {
598*437bfbebSnyanmisaka mbrc->rlc_count = 1;
599*437bfbebSnyanmisaka }
600*437bfbebSnyanmisaka
601*437bfbebSnyanmisaka srcPrm = axb_div_c(mbrc->out_strm_size * 8, 256, mbrc->rlc_count);
602*437bfbebSnyanmisaka /* Disable Mb Rc for Intra Slices, because coeffTarget will be wrong */
603*437bfbebSnyanmisaka if (frm->is_intra || srcPrm == 0)
604*437bfbebSnyanmisaka return 0;
605*437bfbebSnyanmisaka
606*437bfbebSnyanmisaka /* Required zero cnt */
607*437bfbebSnyanmisaka nonZeroTarget = axb_div_c(info->bit_target, 256, srcPrm);
608*437bfbebSnyanmisaka nonZeroTarget = MPP_MIN(coeffCntMax, MPP_MAX(0, nonZeroTarget));
609*437bfbebSnyanmisaka nonZeroTarget = MPP_MIN(0x7FFFFFFFU / 1024U, (RK_U32)nonZeroTarget);
610*437bfbebSnyanmisaka
611*437bfbebSnyanmisaka if (nonZeroTarget > 0) {
612*437bfbebSnyanmisaka scaler = axb_div_c(nonZeroTarget, sscale, (RK_S32) p->mbs);
613*437bfbebSnyanmisaka } else {
614*437bfbebSnyanmisaka return 0;
615*437bfbebSnyanmisaka }
616*437bfbebSnyanmisaka
617*437bfbebSnyanmisaka if ((p->frame_type != p->pre_frame_type) || (mbrc->rlc_count == 0)) {
618*437bfbebSnyanmisaka for (i = 0; i < VEPU_CHECK_POINTS_MAX; i++) {
619*437bfbebSnyanmisaka tmp = (scaler * (p->check_point_distance * (i + 1) + 1)) / sscale;
620*437bfbebSnyanmisaka tmp = MPP_MIN(WORD_CNT_MAX, tmp / 32 + 1);
621*437bfbebSnyanmisaka if (tmp < 0) tmp = WORD_CNT_MAX; /* Detect overflow */
622*437bfbebSnyanmisaka mbrc->cp_target[i] = tmp; /* div32 for regs */
623*437bfbebSnyanmisaka }
624*437bfbebSnyanmisaka
625*437bfbebSnyanmisaka tmp = axb_div_c(p->bits_per_pic, 256, srcPrm);
626*437bfbebSnyanmisaka } else {
627*437bfbebSnyanmisaka for (i = 0; i < VEPU_CHECK_POINTS_MAX; i++) {
628*437bfbebSnyanmisaka tmp = (RK_S32) (mbrc->cp_usage[i] * scaler) / sscale;
629*437bfbebSnyanmisaka tmp = MPP_MIN(WORD_CNT_MAX, tmp / 32 + 1);
630*437bfbebSnyanmisaka if (tmp < 0) tmp = WORD_CNT_MAX; /* Detect overflow */
631*437bfbebSnyanmisaka mbrc->cp_target[i] = tmp; /* div32 for regs */
632*437bfbebSnyanmisaka }
633*437bfbebSnyanmisaka tmp = axb_div_c(p->bits_per_pic, 256, srcPrm);
634*437bfbebSnyanmisaka }
635*437bfbebSnyanmisaka
636*437bfbebSnyanmisaka mbrc->cp_error[0] = -tmp * 3;
637*437bfbebSnyanmisaka mbrc->cp_delta_qp[0] = 3;
638*437bfbebSnyanmisaka mbrc->cp_error[1] = -tmp * 2;
639*437bfbebSnyanmisaka mbrc->cp_delta_qp[1] = 2;
640*437bfbebSnyanmisaka mbrc->cp_error[2] = -tmp * 1;
641*437bfbebSnyanmisaka mbrc->cp_delta_qp[2] = 1;
642*437bfbebSnyanmisaka mbrc->cp_error[3] = tmp * 1;
643*437bfbebSnyanmisaka mbrc->cp_delta_qp[3] = 0;
644*437bfbebSnyanmisaka mbrc->cp_error[4] = tmp * 2;
645*437bfbebSnyanmisaka mbrc->cp_delta_qp[4] = -1;
646*437bfbebSnyanmisaka mbrc->cp_error[5] = tmp * 3;
647*437bfbebSnyanmisaka mbrc->cp_delta_qp[5] = -2;
648*437bfbebSnyanmisaka mbrc->cp_error[6] = tmp * 4;
649*437bfbebSnyanmisaka mbrc->cp_delta_qp[6] = -3;
650*437bfbebSnyanmisaka
651*437bfbebSnyanmisaka for (i = 0; i < VEPU_CTRL_LEVELS; i++) {
652*437bfbebSnyanmisaka tmp = mbrc->cp_error[i];
653*437bfbebSnyanmisaka tmp = mpp_clip(tmp / 4, -32768, 32767);
654*437bfbebSnyanmisaka mbrc->cp_error[i] = tmp;
655*437bfbebSnyanmisaka }
656*437bfbebSnyanmisaka
657*437bfbebSnyanmisaka mbrc->cp_distance_mbs = p->check_point_distance;
658*437bfbebSnyanmisaka
659*437bfbebSnyanmisaka return MPP_OK;
660*437bfbebSnyanmisaka }
661*437bfbebSnyanmisaka
h264e_vepu_slice_split_cfg(H264eSlice * slice,HalH264eVepuMbRc * mbrc,EncRcTask * rc_task,MppEncCfgSet * cfg)662*437bfbebSnyanmisaka MPP_RET h264e_vepu_slice_split_cfg(H264eSlice *slice, HalH264eVepuMbRc *mbrc,
663*437bfbebSnyanmisaka EncRcTask *rc_task, MppEncCfgSet *cfg)
664*437bfbebSnyanmisaka {
665*437bfbebSnyanmisaka MppEncSliceSplit *split = &cfg->split;
666*437bfbebSnyanmisaka EncRcTaskInfo *info = &rc_task->info;
667*437bfbebSnyanmisaka RK_U32 slice_mb_rows = 0;
668*437bfbebSnyanmisaka
669*437bfbebSnyanmisaka hal_h264e_dbg_func("enter\n");
670*437bfbebSnyanmisaka
671*437bfbebSnyanmisaka switch (split->split_mode) {
672*437bfbebSnyanmisaka case MPP_ENC_SPLIT_NONE : {
673*437bfbebSnyanmisaka mbrc->slice_size_mb_rows = 0;
674*437bfbebSnyanmisaka } break;
675*437bfbebSnyanmisaka case MPP_ENC_SPLIT_BY_BYTE : {
676*437bfbebSnyanmisaka RK_U32 mb_per_col = (cfg->prep.height + 15) / 16;
677*437bfbebSnyanmisaka mpp_assert(split->split_arg > 0);
678*437bfbebSnyanmisaka RK_U32 slice_num = info->bit_target / (split->split_arg * 8);
679*437bfbebSnyanmisaka
680*437bfbebSnyanmisaka if (slice_num <= 0)
681*437bfbebSnyanmisaka slice_num = 4;
682*437bfbebSnyanmisaka
683*437bfbebSnyanmisaka slice_mb_rows = (mb_per_col + slice_num - 1) / slice_num;
684*437bfbebSnyanmisaka mbrc->slice_size_mb_rows = mpp_clip(slice_mb_rows, 2, 127);
685*437bfbebSnyanmisaka } break;
686*437bfbebSnyanmisaka case MPP_ENC_SPLIT_BY_CTU : {
687*437bfbebSnyanmisaka mpp_assert(split->split_arg > 0);
688*437bfbebSnyanmisaka RK_U32 mb_per_line = (cfg->prep.width + 15) / 16;
689*437bfbebSnyanmisaka
690*437bfbebSnyanmisaka slice_mb_rows = (split->split_arg + mb_per_line - 1) / mb_per_line;
691*437bfbebSnyanmisaka mbrc->slice_size_mb_rows = mpp_clip(slice_mb_rows, 2, 127);
692*437bfbebSnyanmisaka } break;
693*437bfbebSnyanmisaka default : {
694*437bfbebSnyanmisaka mpp_log_f("invalide slice split mode %d\n", split->split_mode);
695*437bfbebSnyanmisaka } break;
696*437bfbebSnyanmisaka }
697*437bfbebSnyanmisaka
698*437bfbebSnyanmisaka slice->is_multi_slice = (mbrc->slice_size_mb_rows > 0);
699*437bfbebSnyanmisaka
700*437bfbebSnyanmisaka hal_h264e_dbg_func("leave\n");
701*437bfbebSnyanmisaka return MPP_OK;
702*437bfbebSnyanmisaka }
703*437bfbebSnyanmisaka
h264e_vepu_mbrc_update(HalH264eVepuMbRcCtx ctx,HalH264eVepuMbRc * mbrc)704*437bfbebSnyanmisaka MPP_RET h264e_vepu_mbrc_update(HalH264eVepuMbRcCtx ctx, HalH264eVepuMbRc *mbrc)
705*437bfbebSnyanmisaka {
706*437bfbebSnyanmisaka HalH264eVepuMbRcImpl *p = (HalH264eVepuMbRcImpl *)ctx;
707*437bfbebSnyanmisaka (void) p;
708*437bfbebSnyanmisaka (void) mbrc;
709*437bfbebSnyanmisaka
710*437bfbebSnyanmisaka hal_h264e_dbg_func("enter\n");
711*437bfbebSnyanmisaka hal_h264e_dbg_func("leave\n");
712*437bfbebSnyanmisaka return MPP_OK;
713*437bfbebSnyanmisaka }
714*437bfbebSnyanmisaka
715