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