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