xref: /rockchip-linux_mpp/mpp/hal/vpu/h264e/hal_h264e_vepu_v2.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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