1 /* SPDX-License-Identifier: Apache-2.0 */
2 /*
3 * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "hal_h264e_vepu511"
7
8 #include <string.h>
9
10 #include "mpp_env.h"
11 #include "mpp_mem.h"
12 #include "mpp_common.h"
13 #include "mpp_frame_impl.h"
14 #include "mpp_packet_impl.h"
15 #include "mpp_enc_cb_param.h"
16
17 #include "rkv_enc_def.h"
18 #include "hal_h264e_debug.h"
19 #include "hal_bufs.h"
20 #include "hal_h264e_vepu511_reg.h"
21 #include "hal_h264e_vepu511.h"
22 #include "hal_h264e_stream_amend.h"
23 #include "h264e_dpb.h"
24
25 #include "vepu5xx.h"
26 #include "vepu5xx_common.h"
27 #include "vepu511_common.h"
28
29 #define DUMP_REG 0
30 #define MAX_TASK_CNT 2
31 #define VEPU540C_MAX_ROI_NUM 8
32
33 /* Custom Quant Matrices: Joint Video Team */
34 static RK_U8 vepu511_h264_cqm_jvt8i[64] = {
35 6, 10, 13, 16, 18, 23, 25, 27,
36 10, 11, 16, 18, 23, 25, 27, 29,
37 13, 16, 18, 23, 25, 27, 29, 31,
38 16, 18, 23, 25, 27, 29, 31, 33,
39 18, 23, 25, 27, 29, 31, 33, 36,
40 23, 25, 27, 29, 31, 33, 36, 38,
41 25, 27, 29, 31, 33, 36, 38, 40,
42 27, 29, 31, 33, 36, 38, 40, 42
43 };
44
45 static RK_U8 vepu511_h264_cqm_jvt8p[64] = {
46 9, 13, 15, 17, 19, 21, 22, 24,
47 13, 13, 17, 19, 21, 22, 24, 25,
48 15, 17, 19, 21, 22, 24, 25, 27,
49 17, 19, 21, 22, 24, 25, 27, 28,
50 19, 21, 22, 24, 25, 27, 28, 30,
51 21, 22, 24, 25, 27, 28, 30, 32,
52 22, 24, 25, 27, 28, 30, 32, 33,
53 24, 25, 27, 28, 30, 32, 33, 35
54 };
55
56 typedef struct Vepu511RoiH264BsCfg_t {
57 RK_U64 force_inter : 42;
58 RK_U64 mode_mask : 9;
59 RK_U64 reserved : 10;
60 RK_U64 force_intra : 1;
61 RK_U64 qp_adj_en : 1;
62 RK_U64 amv_en : 1;
63 } Vepu511RoiH264BsCfg;
64
65 typedef struct Vepu511H264Fbk_t {
66 RK_U32 hw_status; /* 0:corret, 1:error */
67 RK_U32 frame_type;
68 RK_U32 qp_sum;
69 RK_U32 out_strm_size;
70 RK_U32 out_hw_strm_size;
71 RK_S64 sse_sum;
72 RK_U32 st_lvl64_inter_num;
73 RK_U32 st_lvl32_inter_num;
74 RK_U32 st_lvl16_inter_num;
75 RK_U32 st_lvl8_inter_num;
76 RK_U32 st_lvl32_intra_num;
77 RK_U32 st_lvl16_intra_num;
78 RK_U32 st_lvl8_intra_num;
79 RK_U32 st_lvl4_intra_num;
80 RK_U32 st_cu_num_qp[52];
81 RK_U32 st_madp;
82 RK_U32 st_madi;
83 RK_U32 st_mb_num;
84 RK_U32 st_ctu_num;
85 RK_U32 st_smear_cnt[5];
86 } Vepu511H264Fbk;
87
88 typedef struct HalH264eVepu511Ctx_t {
89 MppEncCfgSet *cfg;
90
91 MppDev dev;
92 RK_S32 frame_cnt;
93 RK_U32 task_cnt;
94
95 /* buffers management */
96 HalBufs hw_recn;
97 RK_S32 pixel_buf_fbc_hdr_size;
98 RK_S32 pixel_buf_fbc_bdy_size;
99 RK_S32 pixel_buf_size;
100 RK_S32 thumb_buf_size;
101 RK_S32 max_buf_cnt;
102 MppDevRegOffCfgs *offsets;
103
104 /* external line buffer over 4K */
105 MppBufferGroup ext_line_buf_grp;
106 MppBuffer ext_line_bufs[MAX_TASK_CNT];
107 RK_S32 ext_line_buf_size;
108
109 /* syntax for input from enc_impl */
110 RK_U32 updated;
111 H264eSps *sps;
112 H264ePps *pps;
113 H264eDpb *dpb;
114 H264eFrmInfo *frms;
115
116 /* async encode TSVC info */
117 H264eReorderInfo *reorder;
118 H264eMarkingInfo *marking;
119
120 /* syntax for output to enc_impl */
121 EncRcTaskInfo hal_rc_cfg;
122
123 /* osd */
124 Vepu511OsdCfg osd_cfg;
125
126 /* roi */
127 void *roi_data;
128 MppBufferGroup roi_grp;
129 MppBuffer roi_base_cfg_buf;
130 RK_S32 roi_base_buf_size;
131
132 /* two-pass deflicker */
133 MppBuffer buf_pass1;
134
135 /* register */
136 HalVepu511RegSet *regs_sets;
137 HalH264eVepuStreamAmend *amend_sets;
138
139 H264ePrefixNal *prefix_sets;
140 H264eSlice *slice_sets;
141
142 /* frame parallel info */
143 RK_S32 task_idx;
144 RK_S32 curr_idx;
145 RK_S32 prev_idx;
146 HalVepu511RegSet *regs_set;
147 HalH264eVepuStreamAmend *amend;
148 H264ePrefixNal *prefix;
149 H264eSlice *slice;
150
151 MppBuffer ext_line_buf;
152
153 /* slice low delay output callback */
154 MppCbCtx *output_cb;
155 RK_S32 poll_slice_max;
156 RK_S32 poll_cfg_size;
157 MppDevPollCfg *poll_cfgs;
158
159 Vepu511H264Fbk feedback;
160 Vepu511H264Fbk last_frame_fb;
161
162 void *tune;
163 RK_S32 smart_en;
164 RK_S32 qpmap_en;
165 } HalH264eVepu511Ctx;
166
167 static RK_S32 h264_aq_tthd_default[16] = {
168 0, 0, 0, 0, 3, 3, 5, 5,
169 8, 8, 8, 15, 15, 20, 25, 25
170 };
171
172 static RK_S32 h264_P_aq_step_default[16] = {
173 -8, -7, -6, -5, -4, -3, -2, -1,
174 0, 1, 2, 3, 4, 5, 7, 8
175 };
176
177 static RK_S32 h264_I_aq_step_default[16] = {
178 -8, -7, -6, -5, -4, -3, -2, -1,
179 0, 1, 2, 3, 4, 5, 7, 8
180 };
181
setup_ext_line_bufs(HalH264eVepu511Ctx * ctx)182 static void setup_ext_line_bufs(HalH264eVepu511Ctx *ctx)
183 {
184 RK_U32 i;
185
186 for (i = 0; i < ctx->task_cnt; i++) {
187 if (ctx->ext_line_bufs[i])
188 continue;
189
190 mpp_buffer_get(ctx->ext_line_buf_grp, &ctx->ext_line_bufs[i],
191 ctx->ext_line_buf_size);
192 }
193 }
194
clear_ext_line_bufs(HalH264eVepu511Ctx * ctx)195 static void clear_ext_line_bufs(HalH264eVepu511Ctx *ctx)
196 {
197 RK_U32 i;
198
199 for (i = 0; i < ctx->task_cnt; i++) {
200 if (ctx->ext_line_bufs[i]) {
201 mpp_buffer_put(ctx->ext_line_bufs[i]);
202 ctx->ext_line_bufs[i] = NULL;
203 }
204 }
205 }
206
hal_h264e_vepu511_deinit(void * hal)207 static MPP_RET hal_h264e_vepu511_deinit(void *hal)
208 {
209 HalH264eVepu511Ctx *p = (HalH264eVepu511Ctx *)hal;
210 RK_U32 i;
211
212 hal_h264e_dbg_func("enter %p\n", p);
213
214 if (p->dev) {
215 mpp_dev_deinit(p->dev);
216 p->dev = NULL;
217 }
218
219 clear_ext_line_bufs(p);
220
221 if (p->amend_sets) {
222 for (i = 0; i < p->task_cnt; i++)
223 h264e_vepu_stream_amend_deinit(&p->amend_sets[i]);
224 }
225
226 MPP_FREE(p->regs_sets);
227 MPP_FREE(p->amend_sets);
228 MPP_FREE(p->prefix_sets);
229 MPP_FREE(p->slice_sets);
230 MPP_FREE(p->reorder);
231 MPP_FREE(p->marking);
232 MPP_FREE(p->poll_cfgs);
233
234 if (p->ext_line_buf_grp) {
235 mpp_buffer_group_put(p->ext_line_buf_grp);
236 p->ext_line_buf_grp = NULL;
237 }
238
239 if (p->hw_recn) {
240 hal_bufs_deinit(p->hw_recn);
241 p->hw_recn = NULL;
242 }
243
244 if (p->roi_base_cfg_buf) {
245 mpp_buffer_put(p->roi_base_cfg_buf);
246 p->roi_base_cfg_buf = NULL;
247 p->roi_base_buf_size = 0;
248 }
249
250 if (p->roi_grp) {
251 mpp_buffer_group_put(p->roi_grp);
252 p->roi_grp = NULL;
253 }
254
255 if (p->offsets) {
256 mpp_dev_multi_offset_deinit(p->offsets);
257 p->offsets = NULL;
258 }
259
260 if (p->buf_pass1) {
261 mpp_buffer_put(p->buf_pass1);
262 p->buf_pass1 = NULL;
263 }
264
265 if (p->tune) {
266 // vepu511_h264e_tune_deinit(p->tune);
267 p->tune = NULL;
268 }
269
270 hal_h264e_dbg_func("leave %p\n", p);
271
272 return MPP_OK;
273 }
274
hal_h264e_vepu511_init(void * hal,MppEncHalCfg * cfg)275 static MPP_RET hal_h264e_vepu511_init(void *hal, MppEncHalCfg *cfg)
276 {
277 HalH264eVepu511Ctx *p = (HalH264eVepu511Ctx *)hal;
278 MPP_RET ret = MPP_OK;
279 RK_U32 i;
280
281 hal_h264e_dbg_func("enter %p\n", p);
282
283 p->cfg = cfg->cfg;
284 /* update output to MppEnc */
285 cfg->type = VPU_CLIENT_RKVENC;
286 ret = mpp_dev_init(&cfg->dev, cfg->type);
287 if (ret) {
288 mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
289 goto DONE;
290 }
291 p->dev = cfg->dev;
292 p->task_cnt = cfg->task_cnt;
293 mpp_assert(p->task_cnt && p->task_cnt <= MAX_TASK_CNT);
294
295 ret = hal_bufs_init(&p->hw_recn);
296 if (ret) {
297 mpp_err_f("init vepu buffer failed ret: %d\n", ret);
298 goto DONE;
299 }
300
301 p->regs_sets = mpp_malloc(HalVepu511RegSet, p->task_cnt);
302 if (NULL == p->regs_sets) {
303 ret = MPP_ERR_MALLOC;
304 mpp_err_f("init register buffer failed\n");
305 goto DONE;
306 }
307
308 p->amend_sets = mpp_malloc(HalH264eVepuStreamAmend, p->task_cnt);
309 if (NULL == p->amend_sets) {
310 ret = MPP_ERR_MALLOC;
311 mpp_err_f("init amend data failed\n");
312 goto DONE;
313 }
314
315 if (p->task_cnt > 1) {
316 p->prefix_sets = mpp_malloc(H264ePrefixNal, p->task_cnt);
317 if (NULL == p->prefix_sets) {
318 ret = MPP_ERR_MALLOC;
319 mpp_err_f("init amend data failed\n");
320 goto DONE;
321 }
322
323 p->slice_sets = mpp_malloc(H264eSlice, p->task_cnt);
324 if (NULL == p->slice_sets) {
325 ret = MPP_ERR_MALLOC;
326 mpp_err_f("init amend data failed\n");
327 goto DONE;
328 }
329
330 p->reorder = mpp_malloc(H264eReorderInfo, 1);
331 if (NULL == p->reorder) {
332 ret = MPP_ERR_MALLOC;
333 mpp_err_f("init amend data failed\n");
334 goto DONE;
335 }
336
337 p->marking = mpp_malloc(H264eMarkingInfo, 1);
338 if (NULL == p->marking) {
339 ret = MPP_ERR_MALLOC;
340 mpp_err_f("init amend data failed\n");
341 goto DONE;
342 }
343 }
344
345 p->poll_slice_max = 8;
346 p->poll_cfg_size = (sizeof(p->poll_cfgs) + sizeof(RK_S32) * p->poll_slice_max);
347 p->poll_cfgs = mpp_malloc_size(MppDevPollCfg, p->poll_cfg_size * p->task_cnt);
348 if (NULL == p->poll_cfgs) {
349 ret = MPP_ERR_MALLOC;
350 mpp_err_f("init poll cfg buffer failed\n");
351 goto DONE;
352 }
353
354 { /* setup default hardware config */
355 MppEncHwCfg *hw = &cfg->cfg->hw;
356
357 hw->qp_delta_row_i = 1;
358 hw->qp_delta_row = 2;
359 hw->extra_buf = 1;
360 hw->qbias_i = 683;
361 hw->qbias_p = 341;
362 hw->qbias_en = 0;
363
364 memcpy(hw->aq_thrd_i, h264_aq_tthd_default, sizeof(hw->aq_thrd_i));
365 memcpy(hw->aq_thrd_p, h264_aq_tthd_default, sizeof(hw->aq_thrd_p));
366 memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i));
367 memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p));
368
369 for (i = 0; i < MPP_ARRAY_ELEMS(hw->mode_bias); i++)
370 hw->mode_bias[i] = 8;
371
372 hw->skip_sad = 8;
373 hw->skip_bias = 8;
374 }
375
376 mpp_dev_multi_offset_init(&p->offsets, 24);
377 p->output_cb = cfg->output_cb;
378 cfg->cap_recn_out = 1;
379 for (i = 0; i < p->task_cnt; i++)
380 h264e_vepu_stream_amend_init(&p->amend_sets[i]);
381
382 // p->tune = vepu511_h264e_tune_init(p);
383
384 DONE:
385 if (ret)
386 hal_h264e_vepu511_deinit(hal);
387
388 hal_h264e_dbg_func("leave %p\n", p);
389 return ret;
390 }
391
392 /*
393 * NOTE: recon / refer buffer is FBC data buffer.
394 * And FBC data require extra 16 lines space for hardware io.
395 */
setup_hal_bufs(HalH264eVepu511Ctx * ctx)396 static void setup_hal_bufs(HalH264eVepu511Ctx *ctx)
397 {
398 MppEncCfgSet *cfg = ctx->cfg;
399 MppEncPrepCfg *prep = &cfg->prep;
400 RK_S32 alignment_w = 64;
401 RK_S32 alignment_h = 16;
402 RK_S32 aligned_w = MPP_ALIGN(prep->width, alignment_w);
403 RK_S32 aligned_h = MPP_ALIGN(prep->height, alignment_h) + 16;
404 RK_S32 pixel_buf_fbc_hdr_size = MPP_ALIGN(aligned_w * aligned_h / 64, SZ_8K);
405 RK_S32 pixel_buf_fbc_bdy_size = aligned_w * aligned_h * 3 / 2;
406 RK_S32 pixel_buf_size = pixel_buf_fbc_hdr_size + pixel_buf_fbc_bdy_size;
407 RK_S32 thumb_buf_size = MPP_ALIGN(aligned_w / 64 * aligned_h / 64 * 256, SZ_8K);
408 RK_S32 old_max_cnt = ctx->max_buf_cnt;
409 RK_S32 new_max_cnt = 4;
410 MppEncRefCfg ref_cfg = cfg->ref_cfg;
411
412 if (ref_cfg) {
413 MppEncCpbInfo *info = mpp_enc_ref_cfg_get_cpb_info(ref_cfg);
414 if (new_max_cnt < MPP_MAX(new_max_cnt, info->dpb_size + 1))
415 new_max_cnt = MPP_MAX(new_max_cnt, info->dpb_size + 1);
416 }
417
418 if (aligned_w > SZ_4K) {
419 RK_S32 ctu_w = (aligned_w + 63) / 64;
420 RK_S32 ext_line_buf_size = ((ctu_w - 53) * 53 + 15) / 16 * 16 * 16;
421
422 if (NULL == ctx->ext_line_buf_grp)
423 mpp_buffer_group_get_internal(&ctx->ext_line_buf_grp, MPP_BUFFER_TYPE_ION);
424 else if (ext_line_buf_size != ctx->ext_line_buf_size) {
425 clear_ext_line_bufs(ctx);
426 mpp_buffer_group_clear(ctx->ext_line_buf_grp);
427 }
428
429 mpp_assert(ctx->ext_line_buf_grp);
430
431 ctx->ext_line_buf_size = ext_line_buf_size;
432 setup_ext_line_bufs(ctx);
433 } else {
434 clear_ext_line_bufs(ctx);
435 if (ctx->ext_line_buf_grp) {
436 mpp_buffer_group_clear(ctx->ext_line_buf_grp);
437 mpp_buffer_group_put(ctx->ext_line_buf_grp);
438 ctx->ext_line_buf_grp = NULL;
439 }
440 ctx->ext_line_buf_size = 0;
441 }
442
443 if ((ctx->pixel_buf_fbc_hdr_size != pixel_buf_fbc_hdr_size) ||
444 (ctx->pixel_buf_fbc_bdy_size != pixel_buf_fbc_bdy_size) ||
445 (ctx->pixel_buf_size != pixel_buf_size) ||
446 (ctx->thumb_buf_size != thumb_buf_size) ||
447 (new_max_cnt > old_max_cnt)) {
448 size_t sizes[3];
449
450 hal_h264e_dbg_detail("frame size %d -> %d max count %d -> %d\n",
451 ctx->pixel_buf_size, pixel_buf_size,
452 old_max_cnt, new_max_cnt);
453
454 /* pixel buffer */
455 sizes[0] = pixel_buf_size;
456 /* thumb buffer */
457 sizes[1] = thumb_buf_size;
458 /* smear buffer */
459 sizes[2] = MPP_ALIGN(aligned_w / 64, 16) * MPP_ALIGN(aligned_h / 16, 16);
460 new_max_cnt = MPP_MAX(new_max_cnt, old_max_cnt);
461
462 hal_bufs_setup(ctx->hw_recn, new_max_cnt, MPP_ARRAY_ELEMS(sizes), sizes);
463
464 ctx->pixel_buf_fbc_hdr_size = pixel_buf_fbc_hdr_size;
465 ctx->pixel_buf_fbc_bdy_size = pixel_buf_fbc_bdy_size;
466 ctx->pixel_buf_size = pixel_buf_size;
467 ctx->thumb_buf_size = thumb_buf_size;
468 ctx->max_buf_cnt = new_max_cnt;
469 }
470 }
471
hal_h264e_vepu511_prepare(void * hal)472 static MPP_RET hal_h264e_vepu511_prepare(void *hal)
473 {
474 HalH264eVepu511Ctx *ctx = (HalH264eVepu511Ctx *)hal;
475 MppEncPrepCfg *prep = &ctx->cfg->prep;
476
477 hal_h264e_dbg_func("enter %p\n", hal);
478
479 if (prep->change_res) {
480 RK_S32 i;
481
482 // pre-alloc required buffers to reduce first frame delay
483 setup_hal_bufs(ctx);
484 for (i = 0; i < ctx->max_buf_cnt; i++)
485 hal_bufs_get_buf(ctx->hw_recn, i);
486
487 prep->change_res = 0;
488 }
489
490 hal_h264e_dbg_func("leave %p\n", hal);
491
492 return MPP_OK;
493 }
494
update_vepu511_syntax(HalH264eVepu511Ctx * ctx,MppSyntax * syntax)495 static RK_U32 update_vepu511_syntax(HalH264eVepu511Ctx *ctx, MppSyntax *syntax)
496 {
497 H264eSyntaxDesc *desc = syntax->data;
498 RK_S32 syn_num = syntax->number;
499 RK_U32 updated = 0;
500 RK_S32 i;
501
502 for (i = 0; i < syn_num; i++, desc++) {
503 switch (desc->type) {
504 case H264E_SYN_CFG : {
505 hal_h264e_dbg_detail("update cfg");
506 ctx->cfg = desc->p;
507 } break;
508 case H264E_SYN_SPS : {
509 hal_h264e_dbg_detail("update sps");
510 ctx->sps = desc->p;
511 } break;
512 case H264E_SYN_PPS : {
513 hal_h264e_dbg_detail("update pps");
514 ctx->pps = desc->p;
515 } break;
516 case H264E_SYN_DPB : {
517 hal_h264e_dbg_detail("update dpb");
518 ctx->dpb = desc->p;
519 } break;
520 case H264E_SYN_SLICE : {
521 hal_h264e_dbg_detail("update slice");
522 ctx->slice = desc->p;
523 } break;
524 case H264E_SYN_FRAME : {
525 hal_h264e_dbg_detail("update frames");
526 ctx->frms = desc->p;
527 } break;
528 case H264E_SYN_PREFIX : {
529 hal_h264e_dbg_detail("update prefix nal");
530 ctx->prefix = desc->p;
531 } break;
532 default : {
533 mpp_log_f("invalid syntax type %d\n", desc->type);
534 } break;
535 }
536
537 updated |= SYN_TYPE_FLAG(desc->type);
538 }
539
540 return updated;
541 }
542
hal_h264e_vepu511_get_task(void * hal,HalEncTask * task)543 static MPP_RET hal_h264e_vepu511_get_task(void *hal, HalEncTask *task)
544 {
545 HalH264eVepu511Ctx *ctx = (HalH264eVepu511Ctx *)hal;
546 MppEncCfgSet *cfg_set = ctx->cfg;
547 MppEncRefCfgImpl *ref = (MppEncRefCfgImpl *)cfg_set->ref_cfg;
548 MppEncH264HwCfg *hw_cfg = &cfg_set->h264.hw_cfg;
549 RK_U32 updated = update_vepu511_syntax(ctx, &task->syntax);
550 EncFrmStatus *frm_status = &task->rc_task->frm;
551 H264eFrmInfo *frms = ctx->frms;
552
553 hal_h264e_dbg_func("enter %p\n", hal);
554
555 ctx->smart_en = (ctx->cfg->rc.rc_mode == MPP_ENC_RC_MODE_SMTRC);
556 ctx->qpmap_en = ctx->cfg->tune.deblur_en;
557
558 if (updated & SYN_TYPE_FLAG(H264E_SYN_CFG))
559 setup_hal_bufs(ctx);
560
561 if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
562 MppMeta meta = mpp_frame_get_meta(task->frame);
563 mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void **)&ctx->roi_data);
564 mpp_meta_get_ptr_d(meta, KEY_OSD_DATA3, (void **)&ctx->osd_cfg.osd_data3, NULL);
565 }
566
567 if (!frm_status->reencode)
568 ctx->last_frame_fb = ctx->feedback;
569
570 if (ctx->dpb) {
571 h264e_dpb_hal_start(ctx->dpb, frms->curr_idx);
572 h264e_dpb_hal_start(ctx->dpb, frms->refr_idx);
573 }
574
575 task->flags.reg_idx = ctx->task_idx;
576 task->flags.curr_idx = frms->curr_idx;
577 task->flags.refr_idx = frms->refr_idx;
578 task->part_first = 1;
579 task->part_last = 0;
580
581 ctx->ext_line_buf = ctx->ext_line_bufs[ctx->task_idx];
582 ctx->regs_set = &ctx->regs_sets[ctx->task_idx];
583 ctx->amend = &ctx->amend_sets[ctx->task_idx];
584
585 /* if not VEPU1/2, update log2_max_frame_num_minus4 in hw_cfg */
586 hw_cfg->hw_log2_max_frame_num_minus4 = ctx->sps->log2_max_frame_num_minus4;
587 hw_cfg->hw_poc_type = ctx->sps->pic_order_cnt_type;
588
589 if (ctx->task_cnt > 1 && (ref->lt_cfg_cnt || ref->st_cfg_cnt > 1)) {
590 H264ePrefixNal *prefix = &ctx->prefix_sets[ctx->task_idx];
591 H264eSlice *slice = &ctx->slice_sets[ctx->task_idx];
592
593 //store async encode TSVC info
594 if (ctx->prefix)
595 memcpy(prefix, ctx->prefix, sizeof(H264ePrefixNal));
596 else
597 prefix = NULL;
598
599 if (ctx->slice) {
600 memcpy(slice, ctx->slice, sizeof(H264eSlice));
601
602 /*
603 * Generally, reorder and marking are shared by dpb and slice.
604 * However, async encoding TSVC will change reorder and marking in each task.
605 * Therefore, malloc a special space for async encoding TSVC.
606 */
607 ctx->amend->reorder = ctx->reorder;
608 ctx->amend->marking = ctx->marking;
609 }
610
611 h264e_vepu_stream_amend_config(ctx->amend, task->packet, ctx->cfg,
612 slice, prefix);
613 } else {
614 h264e_vepu_stream_amend_config(ctx->amend, task->packet, ctx->cfg,
615 ctx->slice, ctx->prefix);
616 }
617
618 if (ctx->task_cnt > 1)
619 ctx->task_idx = !ctx->task_idx;
620
621 hal_h264e_dbg_func("leave %p\n", hal);
622
623 return MPP_OK;
624 }
625
setup_vepu511_normal(HalVepu511RegSet * regs)626 static void setup_vepu511_normal(HalVepu511RegSet *regs)
627 {
628 hal_h264e_dbg_func("enter\n");
629 /* reg000 VERSION is read only */
630
631 /* reg001 ENC_STRT */
632 regs->reg_ctl.enc_strt.lkt_num = 0;
633 regs->reg_ctl.enc_strt.vepu_cmd = 1;
634
635 regs->reg_ctl.opt_strg.cke = 1;
636 regs->reg_ctl.opt_strg.resetn_hw_en = 1;
637
638 /* reg002 ENC_CLR */
639 regs->reg_ctl.enc_clr.safe_clr = 0;
640 regs->reg_ctl.enc_clr.force_clr = 0;
641
642 /* reg004 INT_EN */
643 regs->reg_ctl.int_en.enc_done_en = 1;
644 regs->reg_ctl.int_en.lkt_node_done_en = 1;
645 regs->reg_ctl.int_en.sclr_done_en = 1;
646 regs->reg_ctl.int_en.vslc_done_en = 0;
647 regs->reg_ctl.int_en.vbsf_oflw_en = 1;
648 regs->reg_ctl.int_en.vbuf_lens_en = 1;
649 regs->reg_ctl.int_en.enc_err_en = 1;
650
651 regs->reg_ctl.int_en.wdg_en = 1;
652 regs->reg_ctl.int_en.vsrc_err_en = 1;
653 regs->reg_ctl.int_en.wdg_en = 1;
654 regs->reg_ctl.int_en.lkt_err_int_en = 1;
655 regs->reg_ctl.int_en.lkt_err_stop_en = 1;
656 regs->reg_ctl.int_en.lkt_force_stop_en = 1;
657 regs->reg_ctl.int_en.jslc_done_en = 1;
658 regs->reg_ctl.int_en.jbsf_oflw_en = 1;
659 regs->reg_ctl.int_en.jbuf_lens_en = 1;
660 regs->reg_ctl.int_en.dvbm_err_en = 0;
661
662 /* reg005 INT_MSK */
663 regs->reg_ctl.int_msk.enc_done_msk = 0;
664 regs->reg_ctl.int_msk.lkt_node_done_msk = 0;
665 regs->reg_ctl.int_msk.sclr_done_msk = 0;
666 regs->reg_ctl.int_msk.vslc_done_msk = 0;
667 regs->reg_ctl.int_msk.vbsf_oflw_msk = 0;
668 regs->reg_ctl.int_msk.vbuf_lens_msk = 0;
669 regs->reg_ctl.int_msk.enc_err_msk = 0;
670 regs->reg_ctl.int_msk.vsrc_err_msk = 0;
671 regs->reg_ctl.int_msk.wdg_msk = 0;
672 regs->reg_ctl.int_msk.lkt_err_int_msk = 0;
673 regs->reg_ctl.int_msk.lkt_err_stop_msk = 0;
674 regs->reg_ctl.int_msk.lkt_force_stop_msk = 0;
675 regs->reg_ctl.int_msk.jslc_done_msk = 0;
676 regs->reg_ctl.int_msk.jbsf_oflw_msk = 0;
677 regs->reg_ctl.int_msk.jbuf_lens_msk = 0;
678 regs->reg_ctl.int_msk.dvbm_err_msk = 0;
679
680 /* reg006 INT_CLR is not set */
681 /* reg007 INT_STA is read only */
682 /* reg008 ~ reg0011 gap */
683 regs->reg_ctl.enc_wdg.vs_load_thd = 0;
684
685 /* reg015 DTRNS_MAP */
686 regs->reg_ctl.dtrns_map.jpeg_bus_edin = 0;
687 regs->reg_ctl.dtrns_map.src_bus_edin = 0;
688 regs->reg_ctl.dtrns_map.meiw_bus_edin = 0;
689 regs->reg_ctl.dtrns_map.bsw_bus_edin = 7;
690 regs->reg_ctl.dtrns_map.lktw_bus_edin = 0;
691 regs->reg_ctl.dtrns_map.rec_nfbc_bus_edin = 0;
692
693 regs->reg_ctl.dtrns_cfg.axi_brsp_cke = 0;
694
695 hal_h264e_dbg_func("leave\n");
696 }
697
setup_vepu511_prep(HalVepu511RegSet * regs,MppEncPrepCfg * prep,HalEncTask * task)698 static MPP_RET setup_vepu511_prep(HalVepu511RegSet *regs, MppEncPrepCfg *prep, HalEncTask *task)
699 {
700 H264eVepu511Frame *reg_frm = ®s->reg_frm;
701 VepuFmtCfg cfg;
702 MppFrameFormat fmt = prep->format;
703 MPP_RET ret = vepu5xx_set_fmt(&cfg, fmt);
704 RK_U32 hw_fmt = cfg.format;
705 RK_S32 y_stride;
706 RK_S32 c_stride;
707
708 hal_h264e_dbg_func("enter\n");
709
710 /* do nothing when color format is not supported */
711 if (ret)
712 return ret;
713
714 reg_frm->common.enc_rsl.pic_wd8_m1 = MPP_ALIGN(prep->width, 16) / 8 - 1;
715 reg_frm->common.src_fill.pic_wfill = MPP_ALIGN(prep->width, 16) - prep->width;
716 reg_frm->common.enc_rsl.pic_hd8_m1 = MPP_ALIGN(prep->height, 16) / 8 - 1;
717 reg_frm->common.src_fill.pic_hfill = MPP_ALIGN(prep->height, 16) - prep->height;
718
719 regs->reg_ctl.dtrns_map.src_bus_edin = cfg.src_endian;
720
721 reg_frm->common.src_fmt.src_cfmt = hw_fmt;
722 reg_frm->common.src_fmt.alpha_swap = cfg.alpha_swap;
723 reg_frm->common.src_fmt.rbuv_swap = cfg.rbuv_swap;
724 reg_frm->common.src_fmt.out_fmt = ((fmt & MPP_FRAME_FMT_MASK) == MPP_FMT_YUV400 ? 0 : 1);
725
726 if (MPP_FRAME_FMT_IS_FBC(fmt)) {
727 reg_frm->common.src_proc.rkfbcd_en = 1;
728
729 y_stride = mpp_frame_get_fbc_hdr_stride(task->frame);
730 if (!y_stride)
731 y_stride = MPP_ALIGN(prep->hor_stride, 64) >> 2;
732 } else if (prep->hor_stride) {
733 y_stride = prep->hor_stride;
734 } else {
735 if (hw_fmt == VEPU5xx_FMT_BGRA8888 )
736 y_stride = prep->width * 4;
737 else if (hw_fmt == VEPU5xx_FMT_BGR888 )
738 y_stride = prep->width * 3;
739 else if (hw_fmt == VEPU5xx_FMT_BGR565 ||
740 hw_fmt == VEPU5xx_FMT_YUYV422 ||
741 hw_fmt == VEPU5xx_FMT_UYVY422)
742 y_stride = prep->width * 2;
743 else
744 y_stride = prep->width;
745 }
746
747 switch (hw_fmt) {
748 case VEPU5xx_FMT_YUV444SP : {
749 c_stride = y_stride * 2;
750 } break;
751 case VEPU5xx_FMT_YUV422SP :
752 case VEPU5xx_FMT_YUV420SP :
753 case VEPU5xx_FMT_YUV444P : {
754 c_stride = y_stride;
755 } break;
756 default : {
757 c_stride = y_stride / 2;
758 } break;
759 }
760
761 if (hw_fmt < VEPU5xx_FMT_ARGB1555) {
762 const VepuRgb2YuvCfg *cfg_coeffs = get_rgb2yuv_cfg(prep->range, prep->color);
763
764 hal_h264e_dbg_flow("input color range %d colorspace %d", prep->range, prep->color);
765
766 reg_frm->common.src_udfy.csc_wgt_b2y = cfg_coeffs->_2y.b_coeff;
767 reg_frm->common.src_udfy.csc_wgt_g2y = cfg_coeffs->_2y.g_coeff;
768 reg_frm->common.src_udfy.csc_wgt_r2y = cfg_coeffs->_2y.r_coeff;
769
770 reg_frm->common.src_udfu.csc_wgt_b2u = cfg_coeffs->_2u.b_coeff;
771 reg_frm->common.src_udfu.csc_wgt_g2u = cfg_coeffs->_2u.g_coeff;
772 reg_frm->common.src_udfu.csc_wgt_r2u = cfg_coeffs->_2u.r_coeff;
773
774 reg_frm->common.src_udfv.csc_wgt_b2v = cfg_coeffs->_2v.b_coeff;
775 reg_frm->common.src_udfv.csc_wgt_g2v = cfg_coeffs->_2v.g_coeff;
776 reg_frm->common.src_udfv.csc_wgt_r2v = cfg_coeffs->_2v.r_coeff;
777
778 reg_frm->common.src_udfo.csc_ofst_y = cfg_coeffs->_2y.offset;
779 reg_frm->common.src_udfo.csc_ofst_u = cfg_coeffs->_2u.offset;
780 reg_frm->common.src_udfo.csc_ofst_v = cfg_coeffs->_2v.offset;
781
782 hal_h264e_dbg_flow("use color range %d colorspace %d", cfg_coeffs->dst_range, cfg_coeffs->color);
783 } else {
784 reg_frm->common.src_udfy.csc_wgt_b2y = cfg.weight[0];
785 reg_frm->common.src_udfy.csc_wgt_g2y = cfg.weight[1];
786 reg_frm->common.src_udfy.csc_wgt_r2y = cfg.weight[2];
787
788 reg_frm->common.src_udfu.csc_wgt_b2u = cfg.weight[3];
789 reg_frm->common.src_udfu.csc_wgt_g2u = cfg.weight[4];
790 reg_frm->common.src_udfu.csc_wgt_r2u = cfg.weight[5];
791
792 reg_frm->common.src_udfv.csc_wgt_b2v = cfg.weight[6];
793 reg_frm->common.src_udfv.csc_wgt_g2v = cfg.weight[7];
794 reg_frm->common.src_udfv.csc_wgt_r2v = cfg.weight[8];
795
796 reg_frm->common.src_udfo.csc_ofst_y = cfg.offset[0];
797 reg_frm->common.src_udfo.csc_ofst_u = cfg.offset[1];
798 reg_frm->common.src_udfo.csc_ofst_v = cfg.offset[2];
799 }
800
801 reg_frm->common.src_strd0.src_strd0 = y_stride;
802 reg_frm->common.src_strd1.src_strd1 = c_stride;
803
804 reg_frm->common.src_proc.src_mirr = prep->mirroring > 0;
805 reg_frm->common.src_proc.src_rot = prep->rotation;
806
807 reg_frm->sli_cfg.mv_v_lmt_thd = 0;
808 reg_frm->sli_cfg.mv_v_lmt_en = 0;
809
810 reg_frm->common.pic_ofst.pic_ofst_y = 0;
811 reg_frm->common.pic_ofst.pic_ofst_x = 0;
812
813 hal_h264e_dbg_func("leave\n");
814
815 return ret;
816 }
817
vepu511_h264e_save_pass1_patch(HalVepu511RegSet * regs,HalH264eVepu511Ctx * ctx)818 static MPP_RET vepu511_h264e_save_pass1_patch(HalVepu511RegSet *regs, HalH264eVepu511Ctx *ctx)
819 {
820 H264eVepu511Frame *reg_frm = ®s->reg_frm;
821 RK_S32 width_align = MPP_ALIGN(ctx->cfg->prep.width, 16);
822 RK_S32 height_align = MPP_ALIGN(ctx->cfg->prep.height, 16);
823
824 if (NULL == ctx->buf_pass1) {
825 mpp_buffer_get(NULL, &ctx->buf_pass1, width_align * height_align * 3 / 2);
826 if (!ctx->buf_pass1) {
827 mpp_err("buf_pass1 malloc fail, debreath invaild");
828 return MPP_NOK;
829 }
830 }
831
832 reg_frm->common.enc_pic.cur_frm_ref = 1;
833 reg_frm->common.rfpw_h_addr = mpp_buffer_get_fd(ctx->buf_pass1);
834 reg_frm->common.rfpw_b_addr = reg_frm->common.rfpw_h_addr;
835 reg_frm->common.enc_pic.rec_fbc_dis = 1;
836
837 mpp_dev_multi_offset_update(ctx->offsets, 164, width_align * height_align);
838
839 /* NOTE: disable split to avoid lowdelay slice output */
840 reg_frm->common.sli_splt.sli_splt = 0;
841 reg_frm->common.enc_pic.slen_fifo = 0;
842
843 return MPP_OK;
844 }
845
vepu511_h264e_use_pass1_patch(HalVepu511RegSet * regs,HalH264eVepu511Ctx * ctx)846 static MPP_RET vepu511_h264e_use_pass1_patch(HalVepu511RegSet *regs, HalH264eVepu511Ctx *ctx)
847 {
848 H264eVepu511Frame *reg_frm = ®s->reg_frm;
849 RK_S32 fd_in = mpp_buffer_get_fd(ctx->buf_pass1);
850 RK_S32 width_align = MPP_ALIGN(ctx->cfg->prep.width, 16);
851 RK_S32 height_align = MPP_ALIGN(ctx->cfg->prep.height, 16);
852 RK_S32 y_stride = width_align;
853
854 hal_h264e_dbg_func("enter\n");
855
856 reg_frm->common.enc_pic.rfpr_compress_mode = 1;
857 reg_frm->common.src_fmt.src_cfmt = VEPU5xx_FMT_YUV420SP;
858 reg_frm->common.src_fmt.alpha_swap = 0;
859 reg_frm->common.src_fmt.rbuv_swap = 0;
860 reg_frm->common.src_fmt.out_fmt = 1;
861
862 reg_frm->common.src_strd0.src_strd0 = y_stride;
863 reg_frm->common.src_strd1.src_strd1 = y_stride;
864
865 reg_frm->common.src_proc.src_mirr = 0;
866 reg_frm->common.src_proc.src_rot = 0;
867
868 reg_frm->common.pic_ofst.pic_ofst_y = 0;
869 reg_frm->common.pic_ofst.pic_ofst_x = 0;
870
871 reg_frm->common.adr_src0 = fd_in;
872 reg_frm->common.adr_src1 = fd_in;
873
874 mpp_dev_multi_offset_update(ctx->offsets, 161, width_align * height_align);
875
876 hal_h264e_dbg_func("leave\n");
877 return MPP_OK;
878 }
879
setup_vepu511_codec(HalVepu511RegSet * regs,HalH264eVepu511Ctx * ctx)880 static void setup_vepu511_codec(HalVepu511RegSet *regs, HalH264eVepu511Ctx *ctx)
881 {
882 H264eVepu511Frame *reg_frm = ®s->reg_frm;
883 H264eSps *sps = ctx->sps;
884 H264ePps *pps = ctx->pps;
885 H264eSlice *slice = ctx->slice;
886
887 hal_h264e_dbg_func("enter\n");
888
889 reg_frm->common.enc_pic.enc_stnd = 0;
890 reg_frm->common.enc_pic.cur_frm_ref = slice->nal_reference_idc > 0;
891 reg_frm->common.enc_pic.bs_scp = 1;
892
893 reg_frm->synt_nal.nal_ref_idc = slice->nal_reference_idc;
894 reg_frm->synt_nal.nal_unit_type = slice->nalu_type;
895
896 reg_frm->synt_sps.max_fnum = sps->log2_max_frame_num_minus4;
897 reg_frm->synt_sps.drct_8x8 = sps->direct8x8_inference;
898 reg_frm->synt_sps.mpoc_lm4 = sps->log2_max_poc_lsb_minus4;
899 reg_frm->synt_sps.poc_type = sps->pic_order_cnt_type;
900
901 reg_frm->synt_pps.etpy_mode = pps->entropy_coding_mode;
902 reg_frm->synt_pps.trns_8x8 = pps->transform_8x8_mode;
903 reg_frm->synt_pps.csip_flag = pps->constrained_intra_pred;
904 reg_frm->synt_pps.num_ref0_idx = pps->num_ref_idx_l0_default_active - 1;
905 reg_frm->synt_pps.num_ref1_idx = pps->num_ref_idx_l1_default_active - 1;
906 reg_frm->synt_pps.pic_init_qp = pps->pic_init_qp;
907 reg_frm->synt_pps.cb_ofst = pps->chroma_qp_index_offset;
908 reg_frm->synt_pps.cr_ofst = pps->second_chroma_qp_index_offset;
909 reg_frm->synt_pps.dbf_cp_flg = pps->deblocking_filter_control;
910
911 reg_frm->synt_sli0.sli_type = (slice->slice_type == H264_I_SLICE) ? (2) : (0);
912 reg_frm->synt_sli0.pps_id = slice->pic_parameter_set_id;
913 reg_frm->synt_sli0.drct_smvp = 0;
914 reg_frm->synt_sli0.num_ref_ovrd = slice->num_ref_idx_override;
915 reg_frm->synt_sli0.cbc_init_idc = slice->cabac_init_idc;
916 reg_frm->synt_sli0.frm_num = slice->frame_num;
917
918 reg_frm->synt_sli1.idr_pid = (slice->slice_type == H264_I_SLICE) ? slice->idr_pic_id : (RK_U32)(-1);
919 reg_frm->synt_sli1.poc_lsb = slice->pic_order_cnt_lsb;
920
921 reg_frm->synt_sli2.dis_dblk_idc = slice->disable_deblocking_filter_idc;
922 reg_frm->synt_sli2.sli_alph_ofst = slice->slice_alpha_c0_offset_div2;
923
924 h264e_reorder_rd_rewind(slice->reorder);
925 { /* reorder process */
926 H264eRplmo rplmo;
927 MPP_RET ret = h264e_reorder_rd_op(slice->reorder, &rplmo);
928
929 if (MPP_OK == ret) {
930 reg_frm->synt_sli2.ref_list0_rodr = 1;
931 reg_frm->synt_sli2.rodr_pic_idx = rplmo.modification_of_pic_nums_idc;
932
933 switch (rplmo.modification_of_pic_nums_idc) {
934 case 0 :
935 case 1 : {
936 reg_frm->synt_sli2.rodr_pic_num = rplmo.abs_diff_pic_num_minus1;
937 } break;
938 case 2 : {
939 reg_frm->synt_sli2.rodr_pic_num = rplmo.long_term_pic_idx;
940 } break;
941 default : {
942 mpp_err_f("invalid modification_of_pic_nums_idc %d\n",
943 rplmo.modification_of_pic_nums_idc);
944 } break;
945 }
946 } else {
947 // slice->ref_pic_list_modification_flag;
948 reg_frm->synt_sli2.ref_list0_rodr = 0;
949 reg_frm->synt_sli2.rodr_pic_idx = 0;
950 reg_frm->synt_sli2.rodr_pic_num = 0;
951 }
952 }
953
954 /* clear all mmco arg first */
955 reg_frm->synt_refm0.nopp_flg = 0;
956 reg_frm->synt_refm0.ltrf_flg = 0;
957 reg_frm->synt_refm0.arpm_flg = 0;
958 reg_frm->synt_refm0.mmco4_pre = 0;
959 reg_frm->synt_refm0.mmco_type0 = 0;
960 reg_frm->synt_refm0.mmco_parm0 = 0;
961 reg_frm->synt_refm0.mmco_type1 = 0;
962 reg_frm->synt_refm1.mmco_parm1 = 0;
963 reg_frm->synt_refm0.mmco_type2 = 0;
964 reg_frm->synt_refm1.mmco_parm2 = 0;
965 reg_frm->synt_refm2.long_term_frame_idx0 = 0;
966 reg_frm->synt_refm2.long_term_frame_idx1 = 0;
967 reg_frm->synt_refm2.long_term_frame_idx2 = 0;
968
969 h264e_marking_rd_rewind(slice->marking);
970
971 /* only update used parameter */
972 if (slice->slice_type == H264_I_SLICE) {
973 reg_frm->synt_refm0.nopp_flg = slice->no_output_of_prior_pics;
974 reg_frm->synt_refm0.ltrf_flg = slice->long_term_reference_flag;
975 } else {
976 if (!h264e_marking_is_empty(slice->marking)) {
977 H264eMmco mmco;
978
979 reg_frm->synt_refm0.arpm_flg = 1;
980
981 /* max 3 mmco */
982 do {
983 RK_S32 type = 0;
984 RK_S32 param_0 = 0;
985 RK_S32 param_1 = 0;
986
987 h264e_marking_rd_op(slice->marking, &mmco);
988 type = mmco.mmco;
989 switch (type) {
990 case 1 : {
991 param_0 = mmco.difference_of_pic_nums_minus1;
992 } break;
993 case 2 : {
994 param_0 = mmco.long_term_pic_num;
995 } break;
996 case 3 : {
997 param_0 = mmco.difference_of_pic_nums_minus1;
998 param_1 = mmco.long_term_frame_idx;
999 } break;
1000 case 4 : {
1001 param_0 = mmco.max_long_term_frame_idx_plus1;
1002 } break;
1003 case 5 : {
1004 } break;
1005 case 6 : {
1006 param_0 = mmco.long_term_frame_idx;
1007 } break;
1008 default : {
1009 mpp_err_f("unsupported mmco 0 %d\n", type);
1010 type = 0;
1011 } break;
1012 }
1013
1014 reg_frm->synt_refm0.mmco_type0 = type;
1015 reg_frm->synt_refm0.mmco_parm0 = param_0;
1016 reg_frm->synt_refm2.long_term_frame_idx0 = param_1;
1017
1018 if (h264e_marking_is_empty(slice->marking))
1019 break;
1020
1021 h264e_marking_rd_op(slice->marking, &mmco);
1022 type = mmco.mmco;
1023 param_0 = 0;
1024 param_1 = 0;
1025 switch (type) {
1026 case 1 : {
1027 param_0 = mmco.difference_of_pic_nums_minus1;
1028 } break;
1029 case 2 : {
1030 param_0 = mmco.long_term_pic_num;
1031 } break;
1032 case 3 : {
1033 param_0 = mmco.difference_of_pic_nums_minus1;
1034 param_1 = mmco.long_term_frame_idx;
1035 } break;
1036 case 4 : {
1037 param_0 = mmco.max_long_term_frame_idx_plus1;
1038 } break;
1039 case 5 : {
1040 } break;
1041 case 6 : {
1042 param_0 = mmco.long_term_frame_idx;
1043 } break;
1044 default : {
1045 mpp_err_f("unsupported mmco 0 %d\n", type);
1046 type = 0;
1047 } break;
1048 }
1049
1050 reg_frm->synt_refm0.mmco_type1 = type;
1051 reg_frm->synt_refm1.mmco_parm1 = param_0;
1052 reg_frm->synt_refm2.long_term_frame_idx1 = param_1;
1053
1054 if (h264e_marking_is_empty(slice->marking))
1055 break;
1056
1057 h264e_marking_rd_op(slice->marking, &mmco);
1058 type = mmco.mmco;
1059 param_0 = 0;
1060 param_1 = 0;
1061 switch (type) {
1062 case 1 : {
1063 param_0 = mmco.difference_of_pic_nums_minus1;
1064 } break;
1065 case 2 : {
1066 param_0 = mmco.long_term_pic_num;
1067 } break;
1068 case 3 : {
1069 param_0 = mmco.difference_of_pic_nums_minus1;
1070 param_1 = mmco.long_term_frame_idx;
1071 } break;
1072 case 4 : {
1073 param_0 = mmco.max_long_term_frame_idx_plus1;
1074 } break;
1075 case 5 : {
1076 } break;
1077 case 6 : {
1078 param_0 = mmco.long_term_frame_idx;
1079 } break;
1080 default : {
1081 mpp_err_f("unsupported mmco 0 %d\n", type);
1082 type = 0;
1083 } break;
1084 }
1085
1086 reg_frm->synt_refm0.mmco_type2 = type;
1087 reg_frm->synt_refm1.mmco_parm2 = param_0;
1088 reg_frm->synt_refm2.long_term_frame_idx2 = param_1;
1089 } while (0);
1090 }
1091 }
1092
1093 hal_h264e_dbg_func("leave\n");
1094 }
1095
setup_vepu511_rdo_pred(HalH264eVepu511Ctx * ctx)1096 static void setup_vepu511_rdo_pred(HalH264eVepu511Ctx *ctx)
1097 {
1098 HalVepu511RegSet *regs = ctx->regs_set;
1099 H264eVepu511Frame *reg_frm = ®s->reg_frm;
1100 H264eSps *sps = ctx->sps;
1101 H264ePps *pps = ctx->pps;
1102 H264eSlice *slice = ctx->slice;
1103 RK_U32 is_ipc_scene = (ctx->cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC);
1104
1105 hal_h264e_dbg_func("enter\n");
1106
1107 /*
1108 * H264 Mode Mask of Mode Decision.
1109 * More prediction modes lead to better compression performance but increase computational cycles.
1110 *
1111 * Default speed preset configuration to 0.67 PPC, ~40 FPS for 4K resolution at 500MHz:
1112 * - Set i4/i16 partition RDO numbers to 1 for P-frames and all other CU RDO numbers to 2.
1113 * - Set cime_fuse = 0, enable dual-window search for higher compression performance.
1114 * - Set fme_lvl_mrg = 1, enable FME's depth1 and depth2 joint search,
1115 * improves real-time performance but will reduce the compression ratio.
1116 * - Set cime_srch_lftw/rgtw/uph/dwnh = 12/12/15/15, expand CIME search range degraded real-time performance.
1117 * - Set rime_prelvl_en = 0, disable RIME pre-level to improve real-time performance.
1118 */
1119 if (slice->slice_type == H264_I_SLICE) {
1120 regs->reg_rc_roi.klut_ofst.chrm_klut_ofst = 6;
1121 reg_frm->rdo_mark_mode.iframe_i4_rdo_num = 2;
1122 reg_frm->rdo_mark_mode.i8_rdo_num = 2;
1123 reg_frm->rdo_mark_mode.iframe_i16_rdo_num = 2;
1124 reg_frm->rdo_mark_mode.rdo_mark_mode = 0;
1125 } else {
1126 regs->reg_rc_roi.klut_ofst.chrm_klut_ofst = is_ipc_scene ? 9 : 6;
1127 reg_frm->rdo_mark_mode.p16_interp_num = 2;
1128 reg_frm->rdo_mark_mode.p16t8_rdo_num = 2;
1129 reg_frm->rdo_mark_mode.p16t4_rmd_num = 2;
1130 reg_frm->rdo_mark_mode.rdo_mark_mode = 0;
1131 reg_frm->rdo_mark_mode.p8_interp_num = 2;
1132 reg_frm->rdo_mark_mode.p8t8_rdo_num = 2;
1133 reg_frm->rdo_mark_mode.p8t4_rmd_num = 2;
1134 regs->reg_frm.rdo_mark_mode.i8_rdo_num = 2;
1135 regs->reg_frm.rdo_mark_mode.iframe_i4_rdo_num = 1;
1136 regs->reg_frm.rdo_mark_mode.iframe_i16_rdo_num = 1;
1137 }
1138
1139 reg_frm->rdo_cfg.rect_size = (sps->profile_idc == H264_PROFILE_BASELINE &&
1140 sps->level_idc <= H264_LEVEL_3_0) ? 1 : 0;
1141 reg_frm->rdo_cfg.vlc_lmt = (sps->profile_idc < H264_PROFILE_MAIN) &&
1142 !pps->entropy_coding_mode;
1143 reg_frm->rdo_cfg.ccwa_e = 1;
1144 reg_frm->rdo_cfg.scl_lst_sel = pps->pic_scaling_matrix_present;
1145 reg_frm->rdo_cfg.atf_e = ctx->cfg->tune.anti_flicker_str > 0;
1146 reg_frm->rdo_cfg.atr_e = ctx->cfg->tune.atr_str_i > 0;
1147 reg_frm->rdo_cfg.atr_mult_sel_e = 1;
1148
1149 hal_h264e_dbg_func("leave\n");
1150 }
1151
setup_vepu511_rc_base(HalVepu511RegSet * regs,HalH264eVepu511Ctx * ctx,EncRcTask * rc_task)1152 static void setup_vepu511_rc_base(HalVepu511RegSet *regs, HalH264eVepu511Ctx *ctx, EncRcTask *rc_task)
1153 {
1154 H264eSps *sps = ctx->sps;
1155 H264eSlice *slice = ctx->slice;
1156 MppEncCfgSet *cfg = ctx->cfg;
1157 MppEncRcCfg *rc = &cfg->rc;
1158 MppEncHwCfg *hw = &cfg->hw;
1159 EncRcTaskInfo *rc_info = &rc_task->info;
1160 H264eVepu511Frame *reg_frm = ®s->reg_frm;
1161 RK_S32 mb_w = sps->pic_width_in_mbs;
1162 RK_S32 mb_h = sps->pic_height_in_mbs;
1163 RK_U32 qp_target = rc_info->quality_target;
1164 RK_U32 qp_min = rc_info->quality_min;
1165 RK_U32 qp_max = rc_info->quality_max;
1166 RK_S32 mb_target_bits_mul_16 = (rc_info->bit_target << 4) / (mb_w * mb_h);
1167 RK_S32 mb_target_bits;
1168 RK_S32 negative_bits_thd;
1169 RK_S32 positive_bits_thd;
1170
1171 hal_h264e_dbg_rc("bittarget %d qp [%d %d %d]\n", rc_info->bit_target,
1172 qp_min, qp_target, qp_max);
1173
1174 hal_h264e_dbg_func("enter\n");
1175
1176 regs->reg_rc_roi.roi_qthd0.qpmin_area0 = qp_min;
1177 regs->reg_rc_roi.roi_qthd0.qpmax_area0 = qp_max;
1178 regs->reg_rc_roi.roi_qthd0.qpmin_area1 = qp_min;
1179 regs->reg_rc_roi.roi_qthd0.qpmax_area1 = qp_max;
1180 regs->reg_rc_roi.roi_qthd0.qpmin_area2 = qp_min;
1181
1182 regs->reg_rc_roi.roi_qthd1.qpmax_area2 = qp_max;
1183 regs->reg_rc_roi.roi_qthd1.qpmin_area3 = qp_min;
1184 regs->reg_rc_roi.roi_qthd1.qpmax_area3 = qp_max;
1185 regs->reg_rc_roi.roi_qthd1.qpmin_area4 = qp_min;
1186 regs->reg_rc_roi.roi_qthd1.qpmax_area4 = qp_max;
1187
1188 regs->reg_rc_roi.roi_qthd2.qpmin_area5 = qp_min;
1189 regs->reg_rc_roi.roi_qthd2.qpmax_area5 = qp_max;
1190 regs->reg_rc_roi.roi_qthd2.qpmin_area6 = qp_min;
1191 regs->reg_rc_roi.roi_qthd2.qpmax_area6 = qp_max;
1192 regs->reg_rc_roi.roi_qthd2.qpmin_area7 = qp_min;
1193 regs->reg_rc_roi.roi_qthd3.qpmax_area7 = qp_max;
1194
1195 if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
1196 reg_frm->common.enc_pic.pic_qp = rc_info->quality_target;
1197 reg_frm->common.rc_qp.rc_max_qp = rc_info->quality_target;
1198 reg_frm->common.rc_qp.rc_min_qp = rc_info->quality_target;
1199
1200 return;
1201 }
1202
1203 if (mb_target_bits_mul_16 >= 0x100000)
1204 mb_target_bits_mul_16 = 0x50000;
1205
1206 mb_target_bits = (mb_target_bits_mul_16 * mb_w) >> 4;
1207 negative_bits_thd = 0 - 5 * mb_target_bits / 16;
1208 positive_bits_thd = 5 * mb_target_bits / 16;
1209
1210 reg_frm->common.enc_pic.pic_qp = qp_target;
1211
1212 reg_frm->common.rc_cfg.rc_en = 1;
1213 reg_frm->common.rc_cfg.aq_en = 1;
1214 reg_frm->common.rc_cfg.rc_ctu_num = mb_w;
1215
1216 reg_frm->common.rc_qp.rc_max_qp = qp_max;
1217 reg_frm->common.rc_qp.rc_min_qp = qp_min;
1218 reg_frm->common.rc_tgt.ctu_ebit = mb_target_bits_mul_16;
1219
1220 if (rc->rc_mode == MPP_ENC_RC_MODE_SMTRC) {
1221 reg_frm->common.rc_qp.rc_qp_range = 0;
1222 } else {
1223 reg_frm->common.rc_qp.rc_qp_range = (slice->slice_type == H264_I_SLICE) ?
1224 hw->qp_delta_row_i : hw->qp_delta_row;
1225 }
1226
1227 {
1228 /* fixed frame level QP */
1229 RK_S32 fqp_min, fqp_max;
1230
1231 if (slice->slice_type == H264_I_SLICE) {
1232 fqp_min = rc->fqp_min_i;
1233 fqp_max = rc->fqp_max_i;
1234 } else {
1235 fqp_min = rc->fqp_min_p;
1236 fqp_max = rc->fqp_max_p;
1237 }
1238
1239 if ((fqp_min == fqp_max) && (fqp_min >= 1) && (fqp_max <= 51)) {
1240 reg_frm->common.enc_pic.pic_qp = fqp_min;
1241 reg_frm->common.rc_qp.rc_qp_range = 0;
1242 }
1243 }
1244
1245 regs->reg_rc_roi.rc_adj0.qp_adj0 = -2;
1246 regs->reg_rc_roi.rc_adj0.qp_adj1 = -1;
1247 regs->reg_rc_roi.rc_adj0.qp_adj2 = 0;
1248 regs->reg_rc_roi.rc_adj0.qp_adj3 = 1;
1249 regs->reg_rc_roi.rc_adj0.qp_adj4 = 2;
1250 regs->reg_rc_roi.rc_adj1.qp_adj5 = 0;
1251 regs->reg_rc_roi.rc_adj1.qp_adj6 = 0;
1252 regs->reg_rc_roi.rc_adj1.qp_adj7 = 0;
1253 regs->reg_rc_roi.rc_adj1.qp_adj8 = 0;
1254
1255 regs->reg_rc_roi.rc_dthd_0_8[0] = 4 * negative_bits_thd;
1256 regs->reg_rc_roi.rc_dthd_0_8[1] = negative_bits_thd;
1257 regs->reg_rc_roi.rc_dthd_0_8[2] = positive_bits_thd;
1258 regs->reg_rc_roi.rc_dthd_0_8[3] = 4 * positive_bits_thd;
1259 regs->reg_rc_roi.rc_dthd_0_8[4] = 0x7FFFFFFF;
1260 regs->reg_rc_roi.rc_dthd_0_8[5] = 0x7FFFFFFF;
1261 regs->reg_rc_roi.rc_dthd_0_8[6] = 0x7FFFFFFF;
1262 regs->reg_rc_roi.rc_dthd_0_8[7] = 0x7FFFFFFF;
1263 regs->reg_rc_roi.rc_dthd_0_8[8] = 0x7FFFFFFF;
1264
1265 hal_h264e_dbg_func("leave\n");
1266 }
1267
setup_vepu511_io_buf(HalVepu511RegSet * regs,MppDevRegOffCfgs * offsets,HalEncTask * task)1268 static void setup_vepu511_io_buf(HalVepu511RegSet *regs, MppDevRegOffCfgs *offsets,
1269 HalEncTask *task)
1270 {
1271 MppFrame frm = task->frame;
1272 MppPacket pkt = task->packet;
1273 MppBuffer buf_in = mpp_frame_get_buffer(frm);
1274 MppBuffer buf_out = task->output;
1275 MppFrameFormat fmt = mpp_frame_get_fmt(frm);
1276 H264eVepu511Frame *reg_frm = ®s->reg_frm;
1277 RK_S32 hor_stride = mpp_frame_get_hor_stride(frm);
1278 RK_S32 ver_stride = mpp_frame_get_ver_stride(frm);
1279 RK_S32 fd_in = mpp_buffer_get_fd(buf_in);
1280 RK_U32 off_in[2] = {0};
1281 RK_U32 off_out = mpp_packet_get_length(pkt);
1282 size_t siz_out = mpp_buffer_get_size(buf_out);
1283 RK_S32 fd_out = mpp_buffer_get_fd(buf_out);
1284
1285 hal_h264e_dbg_func("enter\n");
1286
1287 reg_frm->common.adr_src0 = fd_in;
1288 reg_frm->common.adr_src1 = fd_in;
1289 reg_frm->common.adr_src2 = fd_in;
1290
1291 reg_frm->common.bsbt_addr = fd_out;
1292 reg_frm->common.bsbb_addr = fd_out;
1293 reg_frm->common.adr_bsbs = fd_out;
1294 reg_frm->common.bsbr_addr = fd_out;
1295
1296 reg_frm->common.rfpt_h_addr = 0xffffffff;
1297 reg_frm->common.rfpb_h_addr = 0;
1298 reg_frm->common.rfpt_b_addr = 0xffffffff;
1299 reg_frm->common.adr_rfpb_b = 0;
1300
1301 if (MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(task->frame))) {
1302 off_in[0] = mpp_frame_get_fbc_offset(task->frame);;
1303 off_in[1] = off_in[0];
1304 } else if (MPP_FRAME_FMT_IS_YUV(fmt)) {
1305 VepuFmtCfg cfg;
1306
1307 vepu5xx_set_fmt(&cfg, fmt);
1308 switch (cfg.format) {
1309 case VEPU5xx_FMT_BGRA8888 :
1310 case VEPU5xx_FMT_BGR888 :
1311 case VEPU5xx_FMT_BGR565 : {
1312 off_in[0] = 0;
1313 off_in[1] = 0;
1314 } break;
1315 case VEPU5xx_FMT_YUV420SP :
1316 case VEPU5xx_FMT_YUV422SP : {
1317 off_in[0] = hor_stride * ver_stride;
1318 off_in[1] = hor_stride * ver_stride;
1319 } break;
1320 case VEPU5xx_FMT_YUV422P : {
1321 off_in[0] = hor_stride * ver_stride;
1322 off_in[1] = hor_stride * ver_stride * 3 / 2;
1323 } break;
1324 case VEPU5xx_FMT_YUV420P : {
1325 off_in[0] = hor_stride * ver_stride;
1326 off_in[1] = hor_stride * ver_stride * 5 / 4;
1327 } break;
1328 case VEPU5xx_FMT_YUV400 :
1329 case VEPU5xx_FMT_YUYV422 :
1330 case VEPU5xx_FMT_UYVY422 : {
1331 off_in[0] = 0;
1332 off_in[1] = 0;
1333 } break;
1334 case VEPU5xx_FMT_YUV444SP : {
1335 off_in[0] = hor_stride * ver_stride;
1336 off_in[1] = hor_stride * ver_stride;
1337 } break;
1338 case VEPU5xx_FMT_YUV444P : {
1339 off_in[0] = hor_stride * ver_stride;
1340 off_in[1] = hor_stride * ver_stride * 2;
1341 } break;
1342 default : {
1343 off_in[0] = 0;
1344 off_in[1] = 0;
1345 } break;
1346 }
1347 }
1348
1349 mpp_dev_multi_offset_update(offsets, 161, off_in[0]);
1350 mpp_dev_multi_offset_update(offsets, 162, off_in[1]);
1351 mpp_dev_multi_offset_update(offsets, 172, siz_out);
1352 mpp_dev_multi_offset_update(offsets, 174, off_out);
1353
1354 reg_frm->common.meiw_addr = task->md_info ? mpp_buffer_get_fd(task->md_info) : 0;
1355 reg_frm->common.enc_pic.mei_stor = 0;
1356 reg_frm->common.pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
1357 reg_frm->common.pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
1358
1359 hal_h264e_dbg_func("leave\n");
1360 }
1361
vepu511_h264_set_one_roi(void * buf,MppEncROIRegion * region,RK_S32 w,RK_S32 h)1362 static MPP_RET vepu511_h264_set_one_roi(void *buf, MppEncROIRegion *region, RK_S32 w, RK_S32 h)
1363 {
1364 Vepu511RoiH264BsCfg *ptr = (Vepu511RoiH264BsCfg *)buf;
1365 RK_S32 mb_w = MPP_ALIGN(w, 16) / 16;
1366 RK_S32 mb_h = MPP_ALIGN(h, 16) / 16;
1367 RK_S32 stride_h = MPP_ALIGN(mb_w, 4);
1368 Vepu511RoiH264BsCfg cfg;
1369 MPP_RET ret = MPP_NOK;
1370
1371 if (NULL == buf || NULL == region) {
1372 mpp_err_f("invalid buf %p roi %p\n", buf, region);
1373 goto DONE;
1374 }
1375
1376 RK_S32 roi_width = (region->w + 15) / 16;
1377 RK_S32 roi_height = (region->h + 15) / 16;
1378 RK_S32 pos_x_init = region->x / 16;
1379 RK_S32 pos_y_init = region->y / 16;
1380 RK_S32 pos_x_end = pos_x_init + roi_width;
1381 RK_S32 pos_y_end = pos_y_init + roi_height;
1382 RK_S32 x, y;
1383
1384 pos_x_end = MPP_MIN(pos_x_end, mb_w);
1385 pos_y_end = MPP_MIN(pos_y_end, mb_h);
1386 pos_x_init = MPP_MAX(pos_x_init, 0);
1387 pos_y_init = MPP_MAX(pos_y_init, 0);
1388
1389 mpp_assert(pos_x_end > pos_x_init);
1390 mpp_assert(pos_y_end > pos_y_init);
1391
1392 cfg.force_intra = 1;
1393
1394 ptr += pos_y_init * stride_h + pos_x_init;
1395 roi_width = pos_x_end - pos_x_init;
1396 roi_height = pos_y_end - pos_y_init;
1397
1398 for (y = 0; y < roi_height; y++) {
1399 Vepu511RoiH264BsCfg *dst = ptr;
1400
1401 for (x = 0; x < roi_width; x++, dst++)
1402 memcpy(dst, &cfg, sizeof(cfg));
1403
1404 ptr += stride_h;
1405 }
1406 DONE:
1407 return ret;
1408 }
1409
setup_vepu511_intra_refresh(HalVepu511RegSet * regs,HalH264eVepu511Ctx * ctx,RK_U32 refresh_idx)1410 static MPP_RET setup_vepu511_intra_refresh(HalVepu511RegSet *regs, HalH264eVepu511Ctx *ctx, RK_U32 refresh_idx)
1411 {
1412 MPP_RET ret = MPP_OK;
1413 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
1414 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
1415 RK_U32 w = mb_w * 16;
1416 RK_U32 h = mb_h * 16;
1417 MppEncROIRegion *region = NULL;
1418 H264eVepu511Frame *reg_frm = ®s->reg_frm;
1419 RK_U32 refresh_num = ctx->cfg->rc.refresh_num;
1420 RK_U32 stride_h = MPP_ALIGN(mb_w, 4);
1421 RK_U32 stride_v = MPP_ALIGN(mb_h, 4);
1422 RK_U32 roi_base_buf_size = stride_h * stride_v * 8;
1423 RK_U32 i = 0;
1424
1425 hal_h264e_dbg_func("enter\n");
1426
1427 if (!ctx->cfg->rc.refresh_en) {
1428 ret = MPP_ERR_VALUE;
1429 goto RET;
1430 }
1431
1432 if (NULL == ctx->roi_base_cfg_buf) {
1433 if (NULL == ctx->roi_grp)
1434 mpp_buffer_group_get_internal(&ctx->roi_grp, MPP_BUFFER_TYPE_ION);
1435 mpp_buffer_get(ctx->roi_grp, &ctx->roi_base_cfg_buf, roi_base_buf_size);
1436 ctx->roi_base_buf_size = roi_base_buf_size;
1437 }
1438
1439 mpp_assert(ctx->roi_base_cfg_buf);
1440 void *base_cfg_buf = mpp_buffer_get_ptr(ctx->roi_base_cfg_buf);
1441 Vepu511RoiH264BsCfg base_cfg;
1442 Vepu511RoiH264BsCfg *base_cfg_ptr = (Vepu511RoiH264BsCfg *)base_cfg_buf;
1443
1444 base_cfg.force_intra = 0;
1445 base_cfg.qp_adj_en = 1;
1446
1447 for (i = 0; i < stride_h * stride_v; i++, base_cfg_ptr++)
1448 memcpy(base_cfg_ptr, &base_cfg, sizeof(base_cfg));
1449
1450 region = mpp_calloc(MppEncROIRegion, 1);
1451
1452 if (NULL == region) {
1453 mpp_err_f("Failed to calloc for MppEncROIRegion !\n");
1454 ret = MPP_ERR_MALLOC;
1455 }
1456
1457 if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_ROW) {
1458 region->x = 0;
1459 region->w = w;
1460 if (refresh_idx > 0) {
1461 region->y = refresh_idx * 16 * refresh_num - 32;
1462 region->h = 16 * refresh_num + 32;
1463 } else {
1464 region->y = refresh_idx * 16 * refresh_num;
1465 region->h = 16 * refresh_num;
1466 }
1467 reg_frm->common.me_rnge.cime_srch_uph = 1;
1468 } else if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_COL) {
1469 region->y = 0;
1470 region->h = h;
1471 if (refresh_idx > 0) {
1472 region->x = refresh_idx * 16 * refresh_num - 32;
1473 region->w = 16 * refresh_num + 32;
1474 } else {
1475 region->x = refresh_idx * 16 * refresh_num;
1476 region->w = 16 * refresh_num;
1477 }
1478 reg_frm->common.me_rnge.cime_srch_dwnh = 1;
1479 }
1480
1481 region->intra = 1;
1482 region->quality = -ctx->cfg->rc.qp_delta_ip;
1483
1484 region->area_map_en = 1;
1485 region->qp_area_idx = 1;
1486 region->abs_qp_en = 0;
1487
1488 vepu511_h264_set_one_roi(base_cfg_buf, region, w, h);
1489 mpp_free(region);
1490 RET:
1491 hal_h264e_dbg_func("leave, ret %d\n", ret);
1492 return ret;
1493 }
1494
setup_vepu511_recn_refr(HalH264eVepu511Ctx * ctx,HalVepu511RegSet * regs)1495 static void setup_vepu511_recn_refr(HalH264eVepu511Ctx *ctx, HalVepu511RegSet *regs)
1496 {
1497
1498 H264eVepu511Frame *reg_frm = ®s->reg_frm;
1499 H264eFrmInfo *frms = ctx->frms;
1500 HalBufs bufs = ctx->hw_recn;
1501 RK_S32 fbc_hdr_size = ctx->pixel_buf_fbc_hdr_size;
1502
1503 HalBuf *curr = hal_bufs_get_buf(bufs, frms->curr_idx);
1504 HalBuf *refr = hal_bufs_get_buf(bufs, frms->refr_idx);
1505
1506 hal_h264e_dbg_func("enter\n");
1507
1508 if (curr && curr->cnt) {
1509 MppBuffer buf_pixel = curr->buf[0];
1510 MppBuffer buf_thumb = curr->buf[1];
1511 MppBuffer buf_smear = curr->buf[2];
1512 RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1513
1514 mpp_assert(buf_pixel);
1515 mpp_assert(buf_thumb);
1516
1517 reg_frm->common.rfpw_h_addr = fd;
1518 reg_frm->common.rfpw_b_addr = fd;
1519 reg_frm->common.dspw_addr = mpp_buffer_get_fd(buf_thumb);
1520 reg_frm->common.adr_smear_wr = mpp_buffer_get_fd(buf_smear);
1521 }
1522
1523 if (refr && refr->cnt) {
1524 MppBuffer buf_pixel = refr->buf[0];
1525 MppBuffer buf_thumb = refr->buf[1];
1526 MppBuffer buf_smear = curr->buf[2];
1527 RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1528
1529 mpp_assert(buf_pixel);
1530 mpp_assert(buf_thumb);
1531
1532 reg_frm->common.rfpr_h_addr = fd;
1533 reg_frm->common.rfpr_b_addr = fd;
1534 reg_frm->common.dspr_addr = mpp_buffer_get_fd(buf_thumb);
1535 reg_frm->common.adr_smear_rd = mpp_buffer_get_fd(buf_smear);
1536 }
1537 mpp_dev_multi_offset_update(ctx->offsets, 164, fbc_hdr_size);
1538 mpp_dev_multi_offset_update(ctx->offsets, 166, fbc_hdr_size);
1539
1540 hal_h264e_dbg_func("leave\n");
1541 }
1542
setup_vepu511_split(HalVepu511RegSet * regs,MppEncCfgSet * enc_cfg)1543 static void setup_vepu511_split(HalVepu511RegSet *regs, MppEncCfgSet *enc_cfg)
1544 {
1545 H264eVepu511Frame *reg_frm = ®s->reg_frm;
1546 MppEncSliceSplit *cfg = &enc_cfg->split;
1547
1548 hal_h264e_dbg_func("enter\n");
1549
1550 switch (cfg->split_mode) {
1551 case MPP_ENC_SPLIT_NONE : {
1552 reg_frm->common.sli_splt.sli_splt = 0;
1553 reg_frm->common.sli_splt.sli_splt_mode = 0;
1554 reg_frm->common.sli_splt.sli_splt_cpst = 0;
1555 reg_frm->common.sli_splt.sli_max_num_m1 = 0;
1556 reg_frm->common.sli_splt.sli_flsh = 0;
1557 reg_frm->common.sli_cnum.sli_splt_cnum_m1 = 0;
1558
1559 reg_frm->common.sli_byte.sli_splt_byte = 0;
1560 reg_frm->common.enc_pic.slen_fifo = 0;
1561 } break;
1562 case MPP_ENC_SPLIT_BY_BYTE : {
1563 reg_frm->common.sli_splt.sli_splt = 1;
1564 reg_frm->common.sli_splt.sli_splt_mode = 0;
1565 reg_frm->common.sli_splt.sli_splt_cpst = 0;
1566 reg_frm->common.sli_splt.sli_max_num_m1 = 500;
1567 reg_frm->common.sli_splt.sli_flsh = 1;
1568 reg_frm->common.sli_cnum.sli_splt_cnum_m1 = 0;
1569
1570 reg_frm->common.sli_byte.sli_splt_byte = cfg->split_arg;
1571 reg_frm->common.enc_pic.slen_fifo = cfg->split_out ? 1 : 0;
1572 regs->reg_ctl.int_en.vslc_done_en = reg_frm->common.enc_pic.slen_fifo;
1573 } break;
1574 case MPP_ENC_SPLIT_BY_CTU : {
1575 RK_U32 mb_w = MPP_ALIGN(enc_cfg->prep.width, 16) / 16;
1576 RK_U32 mb_h = MPP_ALIGN(enc_cfg->prep.height, 16) / 16;
1577 RK_U32 slice_num = (mb_w * mb_h + cfg->split_arg - 1) / cfg->split_arg;
1578
1579 reg_frm->common.sli_splt.sli_splt = 1;
1580 reg_frm->common.sli_splt.sli_splt_mode = 1;
1581 reg_frm->common.sli_splt.sli_splt_cpst = 0;
1582 reg_frm->common.sli_splt.sli_max_num_m1 = 500;
1583 reg_frm->common.sli_splt.sli_flsh = 1;
1584 reg_frm->common.sli_cnum.sli_splt_cnum_m1 = cfg->split_arg - 1;
1585
1586 reg_frm->common.sli_byte.sli_splt_byte = 0;
1587 reg_frm->common.enc_pic.slen_fifo = cfg->split_out ? 1 : 0;
1588 if ((cfg->split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) ||
1589 (regs->reg_frm.common.enc_pic.slen_fifo && (slice_num > VEPU511_SLICE_FIFO_LEN)))
1590 regs->reg_ctl.int_en.vslc_done_en = 1;
1591 } break;
1592 default : {
1593 mpp_log_f("invalide slice split mode %d\n", cfg->split_mode);
1594 } break;
1595 }
1596
1597 hal_h264e_dbg_func("leave\n");
1598 }
1599
setup_vepu511_me(HalH264eVepu511Ctx * ctx)1600 static void setup_vepu511_me(HalH264eVepu511Ctx *ctx)
1601 {
1602 HalVepu511RegSet *regs = ctx->regs_set;
1603 H264eVepu511Frame *reg_frm = ®s->reg_frm;
1604 H264eVepu511Param *reg_param = ®s->reg_param;
1605 MppEncSceneMode sm = ctx->cfg->tune.scene_mode;
1606
1607 hal_h264e_dbg_func("enter\n");
1608
1609 reg_frm->common.me_rnge.cime_srch_dwnh = 15;
1610 reg_frm->common.me_rnge.cime_srch_uph = 15;
1611 reg_frm->common.me_rnge.cime_srch_rgtw = 12;
1612 reg_frm->common.me_rnge.cime_srch_lftw = 12;
1613 reg_frm->common.me_cfg.rme_srch_h = 3;
1614 reg_frm->common.me_cfg.rme_srch_v = 3;
1615
1616 reg_frm->common.me_cfg.srgn_max_num = 72;
1617 reg_frm->common.me_cfg.cime_dist_thre = 1024;
1618 reg_frm->common.me_cfg.rme_dis = 0;
1619 reg_frm->common.me_cfg.fme_dis = 0;
1620 reg_frm->common.me_rnge.dlt_frm_num = 0x0;
1621 reg_frm->common.me_cach.cime_zero_thre = 64;
1622
1623 /* CIME: 0x1760 - 0x176C */
1624 reg_param->me_sqi_comb.cime_pmv_num = 1;
1625 reg_param->me_sqi_comb.cime_fuse = 0;
1626 reg_param->me_sqi_comb.move_lambda = 0;
1627 reg_param->me_sqi_comb.rime_lvl_mrg = 1;
1628 reg_param->me_sqi_comb.rime_prelvl_en = 0;
1629 reg_param->me_sqi_comb.rime_prersu_en = 0;
1630 reg_param->me_sqi_comb.fme_lvl_mrg = 1;
1631 reg_param->cime_mvd_th_comb.cime_mvd_th0 = 16;
1632 reg_param->cime_mvd_th_comb.cime_mvd_th1 = 48;
1633 reg_param->cime_mvd_th_comb.cime_mvd_th2 = 80;
1634 reg_param->cime_madp_th_comb.cime_madp_th = 16;
1635 reg_param->cime_multi_comb.cime_multi0 = 8;
1636 reg_param->cime_multi_comb.cime_multi1 = 12;
1637 reg_param->cime_multi_comb.cime_multi2 = 16;
1638 reg_param->cime_multi_comb.cime_multi3 = 20;
1639
1640 /* RFME: 0x1770 - 0x1778 */
1641 reg_param->rime_mvd_th_comb.rime_mvd_th0 = 1;
1642 reg_param->rime_mvd_th_comb.rime_mvd_th1 = 2;
1643 reg_param->rime_mvd_th_comb.fme_madp_th = 0;
1644 reg_param->rime_madp_th_comb.rime_madp_th0 = 8;
1645 reg_param->rime_madp_th_comb.rime_madp_th1 = 16;
1646 reg_param->rime_multi_comb.rime_multi0 = 4;
1647 reg_param->rime_multi_comb.rime_multi1 = 8;
1648 reg_param->rime_multi_comb.rime_multi2 = 12;
1649 reg_param->cmv_st_th_comb.cmv_th0 = 64;
1650 reg_param->cmv_st_th_comb.cmv_th1 = 96;
1651 reg_param->cmv_st_th_comb.cmv_th2 = 128;
1652
1653 if (sm != MPP_ENC_SCENE_MODE_IPC) {
1654 /* disable subjective optimization */
1655 reg_param->cime_madp_th_comb.cime_madp_th = 0;
1656 reg_param->rime_madp_th_comb.rime_madp_th0 = 0;
1657 reg_param->rime_madp_th_comb.rime_madp_th1 = 0;
1658 reg_param->cime_multi_comb.cime_multi0 = 4;
1659 reg_param->cime_multi_comb.cime_multi1 = 4;
1660 reg_param->cime_multi_comb.cime_multi2 = 4;
1661 reg_param->cime_multi_comb.cime_multi3 = 4;
1662 reg_param->rime_multi_comb.rime_multi0 = 4;
1663 reg_param->rime_multi_comb.rime_multi1 = 4;
1664 reg_param->rime_multi_comb.rime_multi2 = 4;
1665 }
1666
1667 /* 0x1064 */
1668 regs->reg_rc_roi.madi_st_thd.madi_th0 = 5;
1669 regs->reg_rc_roi.madi_st_thd.madi_th1 = 12;
1670 regs->reg_rc_roi.madi_st_thd.madi_th2 = 20;
1671 /* 0x1068 */
1672 regs->reg_rc_roi.madp_st_thd0.madp_th0 = 4 << 4;
1673 regs->reg_rc_roi.madp_st_thd0.madp_th1 = 9 << 4;
1674 /* 0x106C */
1675 regs->reg_rc_roi.madp_st_thd1.madp_th2 = 15 << 4;
1676
1677 hal_h264e_dbg_func("leave\n");
1678 }
1679
1680 #define H264E_LAMBDA_TAB_SIZE (52 * sizeof(RK_U32))
1681
1682 static RK_U32 h264e_lambda_default[60] = {
1683 0x00000005, 0x00000006, 0x00000007, 0x00000009,
1684 0x0000000b, 0x0000000e, 0x00000012, 0x00000016,
1685 0x0000001c, 0x00000024, 0x0000002d, 0x00000039,
1686 0x00000048, 0x0000005b, 0x00000073, 0x00000091,
1687 0x000000b6, 0x000000e6, 0x00000122, 0x0000016d,
1688 0x000001cc, 0x00000244, 0x000002db, 0x00000399,
1689 0x00000489, 0x000005b6, 0x00000733, 0x00000912,
1690 0x00000b6d, 0x00000e66, 0x00001224, 0x000016db,
1691 0x00001ccc, 0x00002449, 0x00002db7, 0x00003999,
1692 0x00004892, 0x00005b6f, 0x00007333, 0x00009124,
1693 0x0000b6de, 0x0000e666, 0x00012249, 0x00016dbc,
1694 0x0001cccc, 0x00024492, 0x0002db79, 0x00039999,
1695 0x00048924, 0x0005b6f2, 0x00073333, 0x00091249,
1696 0x000b6de5, 0x000e6666, 0x00122492, 0x0016dbcb,
1697 0x001ccccc, 0x00244924, 0x002db796, 0x00399998,
1698 };
1699
1700 static RK_U32 h264e_lambda_cvr[60] = {
1701 0x00000009, 0x0000000b, 0x0000000e, 0x00000011,
1702 0x00000016, 0x0000001b, 0x00000022, 0x0000002b,
1703 0x00000036, 0x00000045, 0x00000056, 0x0000006d,
1704 0x00000089, 0x000000ad, 0x000000da, 0x00000112,
1705 0x00000159, 0x000001b3, 0x00000224, 0x000002b3,
1706 0x00000366, 0x00000449, 0x00000566, 0x000006cd,
1707 0x00000891, 0x00000acb, 0x00000d9a, 0x000013c1,
1708 0x000018e4, 0x00001f5c, 0x00002783, 0x000031c8,
1709 0x00003eb8, 0x00004f06, 0x00006390, 0x00008e14,
1710 0x0000b302, 0x0000e18a, 0x00011c29, 0x00016605,
1711 0x0001c313, 0x00027ae1, 0x00031fe6, 0x0003efcf,
1712 0x0004f5c3, 0x0006e785, 0x0008b2ef, 0x000af5c3,
1713 0x000f1e7a, 0x00130c7f, 0x00180000, 0x001e3cf4,
1714 0x002618fe, 0x00300000, 0x003c79e8, 0x004c31fc,
1715 0x00600000, 0x0078f3d0, 0x009863f8, 0x0c000000,
1716 };
1717
1718 static void
setup_vepu511_l2(HalH264eVepu511Ctx * ctx)1719 setup_vepu511_l2(HalH264eVepu511Ctx *ctx)
1720 {
1721 HalVepu511RegSet *regs = ctx->regs_set;
1722 MppEncSceneMode sm = ctx->cfg->tune.scene_mode;
1723 RK_S32 lambda_idx = ctx->cfg->tune.lambda_idx_i; //TODO: lambda_idx_p
1724
1725 hal_h264e_dbg_func("enter\n");
1726
1727 if (sm == MPP_ENC_SCENE_MODE_IPC) {
1728 memcpy(regs->reg_param.rdo_wgta_qp_grpa_0_51,
1729 &h264e_lambda_default[lambda_idx], H264E_LAMBDA_TAB_SIZE);
1730 } else {
1731 memcpy(regs->reg_param.rdo_wgta_qp_grpa_0_51,
1732 &h264e_lambda_cvr[lambda_idx], H264E_LAMBDA_TAB_SIZE);
1733 }
1734
1735 hal_h264e_dbg_func("leave\n");
1736 }
1737
setup_vepu511_ext_line_buf(HalVepu511RegSet * regs,HalH264eVepu511Ctx * ctx)1738 static void setup_vepu511_ext_line_buf(HalVepu511RegSet *regs, HalH264eVepu511Ctx *ctx)
1739 {
1740 H264eVepu511Frame *reg_frm = ®s->reg_frm;
1741 MppDevRcbInfoCfg rcb_cfg;
1742 RK_S32 offset = 0;
1743 RK_S32 fd;
1744
1745 if (!ctx->ext_line_buf) {
1746 reg_frm->common.ebufb_addr = 0;
1747 reg_frm->common.ebufb_addr = 0;
1748 return;
1749 }
1750
1751 fd = mpp_buffer_get_fd(ctx->ext_line_buf);
1752 offset = ctx->ext_line_buf_size;
1753
1754 reg_frm->common.ebuft_addr = fd;
1755 reg_frm->common.ebufb_addr = fd;
1756
1757 mpp_dev_multi_offset_update(ctx->offsets, 178, offset);
1758
1759 /* rcb info for sram */
1760 rcb_cfg.reg_idx = 179;
1761 rcb_cfg.size = offset;
1762
1763 mpp_dev_ioctl(ctx->dev, MPP_DEV_RCB_INFO, &rcb_cfg);
1764
1765 rcb_cfg.reg_idx = 178;
1766 rcb_cfg.size = 0;
1767
1768 mpp_dev_ioctl(ctx->dev, MPP_DEV_RCB_INFO, &rcb_cfg);
1769 }
1770
setup_vepu511_aq(HalH264eVepu511Ctx * ctx)1771 static void setup_vepu511_aq(HalH264eVepu511Ctx *ctx)
1772 {
1773 MppEncCfgSet *cfg = ctx->cfg;
1774 MppEncHwCfg *hw = &cfg->hw;
1775 Vepu511RcRoi *s = &ctx->regs_set->reg_rc_roi;
1776 RK_S32 *aq_step, *aq_thd;
1777 RK_U8 i;
1778
1779 if (ctx->slice->slice_type == H264_I_SLICE) {
1780 aq_thd = (RK_S32 *)&hw->aq_thrd_i[0];
1781 aq_step = &hw->aq_step_i[0];
1782 } else {
1783 aq_thd = (RK_S32 *)&hw->aq_thrd_p[0];
1784 aq_step = &hw->aq_step_p[0];
1785 }
1786
1787 for (i = 0; i < 16; i++)
1788 s->aq_tthd[i] = aq_thd[i] & 0xff;
1789
1790 s->aq_stp0.aq_stp_s0 = aq_step[0] & 0x1f;
1791 s->aq_stp0.aq_stp_0t1 = aq_step[1] & 0x1f;
1792 s->aq_stp0.aq_stp_1t2 = aq_step[2] & 0x1f;
1793 s->aq_stp0.aq_stp_2t3 = aq_step[3] & 0x1f;
1794 s->aq_stp0.aq_stp_3t4 = aq_step[4] & 0x1f;
1795 s->aq_stp0.aq_stp_4t5 = aq_step[5] & 0x1f;
1796 s->aq_stp1.aq_stp_5t6 = aq_step[6] & 0x1f;
1797 s->aq_stp1.aq_stp_6t7 = aq_step[7] & 0x1f;
1798 s->aq_stp1.aq_stp_7t8 = 0;
1799 s->aq_stp1.aq_stp_8t9 = aq_step[8] & 0x1f;
1800 s->aq_stp1.aq_stp_9t10 = aq_step[9] & 0x1f;
1801 s->aq_stp1.aq_stp_10t11 = aq_step[10] & 0x1f;
1802 s->aq_stp2.aq_stp_11t12 = aq_step[11] & 0x1f;
1803 s->aq_stp2.aq_stp_12t13 = aq_step[12] & 0x1f;
1804 s->aq_stp2.aq_stp_13t14 = aq_step[13] & 0x1f;
1805 s->aq_stp2.aq_stp_14t15 = aq_step[14] & 0x1f;
1806 s->aq_stp2.aq_stp_b15 = aq_step[15] & 0x1f;
1807 }
1808
setup_vepu511_anti_stripe(HalH264eVepu511Ctx * ctx)1809 static void setup_vepu511_anti_stripe(HalH264eVepu511Ctx *ctx)
1810 {
1811 HalVepu511RegSet *regs = ctx->regs_set;
1812 H264eVepu511Param *s = ®s->reg_param;
1813 RK_S32 str = ctx->cfg->tune.atl_str;
1814
1815 s->iprd_tthdy4_0.iprd_tthdy4_0 = 1;
1816 s->iprd_tthdy4_0.iprd_tthdy4_1 = 3;
1817 s->iprd_tthdy4_1.iprd_tthdy4_2 = 6;
1818 s->iprd_tthdy4_1.iprd_tthdy4_3 = 8;
1819 s->iprd_tthdc8_0.iprd_tthdc8_0 = 1;
1820 s->iprd_tthdc8_0.iprd_tthdc8_1 = 3;
1821 s->iprd_tthdc8_1.iprd_tthdc8_2 = 6;
1822 s->iprd_tthdc8_1.iprd_tthdc8_3 = 8;
1823 s->iprd_tthdy8_0.iprd_tthdy8_0 = 1;
1824 s->iprd_tthdy8_0.iprd_tthdy8_1 = 3;
1825 s->iprd_tthdy8_1.iprd_tthdy8_2 = 6;
1826 s->iprd_tthdy8_1.iprd_tthdy8_3 = 8;
1827
1828 if (ctx->cfg->tune.scene_mode != MPP_ENC_SCENE_MODE_IPC)
1829 s->iprd_tthd_ul.iprd_tthd_ul = 4095; /* disable anti-stripe */
1830 else
1831 s->iprd_tthd_ul.iprd_tthd_ul = str ? 4 : 255;
1832
1833 s->iprd_wgty8.iprd_wgty8_0 = str ? 22 : 16;
1834 s->iprd_wgty8.iprd_wgty8_1 = str ? 23 : 16;
1835 s->iprd_wgty8.iprd_wgty8_2 = str ? 20 : 16;
1836 s->iprd_wgty8.iprd_wgty8_3 = str ? 22 : 16;
1837 s->iprd_wgty4.iprd_wgty4_0 = str ? 22 : 16;
1838 s->iprd_wgty4.iprd_wgty4_1 = str ? 26 : 16;
1839 s->iprd_wgty4.iprd_wgty4_2 = str ? 20 : 16;
1840 s->iprd_wgty4.iprd_wgty4_3 = str ? 22 : 16;
1841 s->iprd_wgty16.iprd_wgty16_0 = 22;
1842 s->iprd_wgty16.iprd_wgty16_1 = 26;
1843 s->iprd_wgty16.iprd_wgty16_2 = 20;
1844 s->iprd_wgty16.iprd_wgty16_3 = 22;
1845 s->iprd_wgtc8.iprd_wgtc8_0 = 18;
1846 s->iprd_wgtc8.iprd_wgtc8_1 = 21;
1847 s->iprd_wgtc8.iprd_wgtc8_2 = 20;
1848 s->iprd_wgtc8.iprd_wgtc8_3 = 19;
1849 }
1850
setup_vepu511_anti_ringing(HalH264eVepu511Ctx * ctx)1851 static void setup_vepu511_anti_ringing(HalH264eVepu511Ctx *ctx)
1852 {
1853 HalVepu511RegSet *regs = ctx->regs_set;
1854 H264eVepu511Sqi *s = ®s->reg_sqi;
1855 MppEncSceneMode sm = ctx->cfg->tune.scene_mode;
1856
1857 s->atr_thd.atr_qp = (sm == MPP_ENC_SCENE_MODE_IPC) ? 32 : 45;
1858 if (ctx->slice->slice_type == H264_I_SLICE) {
1859 s->atr_thd.atr_thd0 = 1;
1860 s->atr_thd.atr_thd1 = 2;
1861 s->atr_thd.atr_thd2 = 6;
1862 s->atr_wgt16.atr_lv16_wgt0 = 16;
1863 s->atr_wgt16.atr_lv16_wgt1 = 16;
1864 s->atr_wgt16.atr_lv16_wgt2 = 16;
1865
1866 if (sm == MPP_ENC_SCENE_MODE_IPC) {
1867 s->atr_wgt8.atr_lv8_wgt0 = 22;
1868 s->atr_wgt8.atr_lv8_wgt1 = 21;
1869 s->atr_wgt8.atr_lv8_wgt2 = 20;
1870 s->atr_wgt4.atr_lv4_wgt0 = 20;
1871 s->atr_wgt4.atr_lv4_wgt1 = 18;
1872 s->atr_wgt4.atr_lv4_wgt2 = 16;
1873 } else {
1874 s->atr_wgt8.atr_lv8_wgt0 = 18;
1875 s->atr_wgt8.atr_lv8_wgt1 = 17;
1876 s->atr_wgt8.atr_lv8_wgt2 = 18;
1877 s->atr_wgt4.atr_lv4_wgt0 = 16;
1878 s->atr_wgt4.atr_lv4_wgt1 = 16;
1879 s->atr_wgt4.atr_lv4_wgt2 = 16;
1880 }
1881 } else {
1882 if (sm == MPP_ENC_SCENE_MODE_IPC) {
1883 s->atr_thd.atr_thd0 = 2;
1884 s->atr_thd.atr_thd1 = 4;
1885 s->atr_thd.atr_thd2 = 9;
1886 s->atr_wgt16.atr_lv16_wgt0 = 25;
1887 s->atr_wgt16.atr_lv16_wgt1 = 20;
1888 s->atr_wgt16.atr_lv16_wgt2 = 16;
1889 s->atr_wgt8.atr_lv8_wgt0 = 25;
1890 s->atr_wgt8.atr_lv8_wgt1 = 20;
1891 s->atr_wgt8.atr_lv8_wgt2 = 18;
1892 s->atr_wgt4.atr_lv4_wgt0 = 25;
1893 s->atr_wgt4.atr_lv4_wgt1 = 20;
1894 s->atr_wgt4.atr_lv4_wgt2 = 16;
1895 } else {
1896 s->atr_thd.atr_thd0 = 1;
1897 s->atr_thd.atr_thd1 = 2;
1898 s->atr_thd.atr_thd2 = 7;
1899 s->atr_wgt16.atr_lv16_wgt0 = 23;
1900 s->atr_wgt16.atr_lv16_wgt1 = 22;
1901 s->atr_wgt16.atr_lv16_wgt2 = 20;
1902 s->atr_wgt8.atr_lv8_wgt0 = 24;
1903 s->atr_wgt8.atr_lv8_wgt1 = 24;
1904 s->atr_wgt8.atr_lv8_wgt2 = 24;
1905 s->atr_wgt4.atr_lv4_wgt0 = 23;
1906 s->atr_wgt4.atr_lv4_wgt1 = 22;
1907 s->atr_wgt4.atr_lv4_wgt2 = 20;
1908 }
1909 }
1910 }
1911
setup_vepu511_anti_flicker(HalH264eVepu511Ctx * ctx)1912 static void setup_vepu511_anti_flicker(HalH264eVepu511Ctx *ctx)
1913 {
1914 HalVepu511RegSet *regs = ctx->regs_set;
1915 H264eVepu511Sqi *reg = ®s->reg_sqi;
1916 RK_U32 str = ctx->cfg->tune.anti_flicker_str;
1917 rdo_skip_par *p_skip = NULL;
1918 rdo_noskip_par *p_no_skip = NULL;
1919
1920 static RK_U8 pskip_atf_th0[4] = { 0, 0, 0, 1 };
1921 static RK_U8 pskip_atf_th1[4] = { 7, 7, 7, 10 };
1922 static RK_U8 pskip_atf_wgt0[4] = { 16, 16, 16, 20 };
1923 static RK_U8 pskip_atf_wgt1[4] = { 16, 16, 14, 16 };
1924 static RK_U8 intra_atf_th0[4] = { 8, 16, 20, 20 };
1925 static RK_U8 intra_atf_th1[4] = { 16, 32, 40, 40 };
1926 static RK_U8 intra_atf_th2[4] = { 32, 56, 72, 72 };
1927 static RK_U8 intra_atf_wgt0[4] = { 16, 24, 27, 27 };
1928 static RK_U8 intra_atf_wgt1[4] = { 16, 22, 25, 25 };
1929 static RK_U8 intra_atf_wgt2[4] = { 16, 19, 20, 20 };
1930
1931 p_skip = ®->rdo_b16_skip;
1932 p_skip->atf_thd0.madp_thd0 = pskip_atf_th0[str];
1933 p_skip->atf_thd0.madp_thd1 = pskip_atf_th1[str];
1934 p_skip->atf_thd1.madp_thd2 = 15;
1935 p_skip->atf_thd1.madp_thd3 = 25;
1936 p_skip->atf_wgt0.wgt0 = pskip_atf_wgt0[str];
1937 p_skip->atf_wgt0.wgt1 = pskip_atf_wgt1[str];
1938 p_skip->atf_wgt0.wgt2 = 16;
1939 p_skip->atf_wgt0.wgt3 = 16;
1940 p_skip->atf_wgt1.wgt4 = 16;
1941
1942 p_no_skip = ®->rdo_b16_inter;
1943 p_no_skip->ratf_thd0.madp_thd0 = 20;
1944 p_no_skip->ratf_thd0.madp_thd1 = 40;
1945 p_no_skip->ratf_thd1.madp_thd2 = 72;
1946 p_no_skip->atf_wgt.wgt0 = 16;
1947 p_no_skip->atf_wgt.wgt1 = 16;
1948 p_no_skip->atf_wgt.wgt2 = 16;
1949 p_no_skip->atf_wgt.wgt3 = 16;
1950
1951 p_no_skip = ®->rdo_b16_intra;
1952 p_no_skip->ratf_thd0.madp_thd0 = intra_atf_th0[str];
1953 p_no_skip->ratf_thd0.madp_thd1 = intra_atf_th1[str];
1954 p_no_skip->ratf_thd1.madp_thd2 = intra_atf_th2[str];
1955 p_no_skip->atf_wgt.wgt0 = intra_atf_wgt0[str];
1956 p_no_skip->atf_wgt.wgt1 = intra_atf_wgt1[str];
1957 p_no_skip->atf_wgt.wgt2 = intra_atf_wgt2[str];
1958 p_no_skip->atf_wgt.wgt3 = 16;
1959
1960 reg->rdo_b16_intra_atf_cnt_thd.thd0 = 1;
1961 reg->rdo_b16_intra_atf_cnt_thd.thd1 = 4;
1962 reg->rdo_b16_intra_atf_cnt_thd.thd2 = 1;
1963 reg->rdo_b16_intra_atf_cnt_thd.thd3 = 4;
1964
1965 reg->rdo_atf_resi_thd.big_th0 = 16;
1966 reg->rdo_atf_resi_thd.big_th1 = 16;
1967 reg->rdo_atf_resi_thd.small_th0 = 8;
1968 reg->rdo_atf_resi_thd.small_th1 = 8;
1969 }
1970
setup_vepu511_anti_smear(HalH264eVepu511Ctx * ctx)1971 static void setup_vepu511_anti_smear(HalH264eVepu511Ctx *ctx)
1972 {
1973 HalVepu511RegSet *regs = ctx->regs_set;
1974 H264eVepu511Sqi *reg = ®s->reg_sqi;
1975 H264eSlice *slice = ctx->slice;
1976 Vepu511H264Fbk *last_fb = &ctx->last_frame_fb;
1977 RK_U32 mb_cnt = last_fb->st_mb_num;
1978 RK_U32 *smear_cnt = last_fb->st_smear_cnt;
1979 RK_S32 deblur_str = ctx->cfg->tune.deblur_str;
1980 RK_S32 delta_qp = 0;
1981 RK_S32 flg0 = smear_cnt[4] < (mb_cnt >> 6);
1982 RK_S32 flg1 = 1, flg2 = 0, flg3 = 0;
1983 RK_S32 smear_multi[4] = { 9, 12, 16, 16 };
1984
1985 hal_h264e_dbg_func("enter\n");
1986
1987 if ((smear_cnt[3] < ((5 * mb_cnt) >> 10)) ||
1988 (smear_cnt[3] < ((1126 * MPP_MAX3(smear_cnt[0], smear_cnt[1], smear_cnt[2])) >> 10)) ||
1989 (deblur_str == 6) || (deblur_str == 7))
1990 flg1 = 0;
1991
1992 flg3 = flg1 ? 3 : (smear_cnt[4] > ((102 * mb_cnt) >> 10)) ? 2 :
1993 (smear_cnt[4] > ((66 * mb_cnt) >> 10)) ? 1 : 0;
1994
1995 if (ctx->cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC) {
1996 reg->smear_opt_cfg.rdo_smear_en = ctx->qpmap_en;
1997 if (ctx->qpmap_en && deblur_str > 3)
1998 reg->smear_opt_cfg.rdo_smear_lvl16_multi = smear_multi[flg3];
1999 else
2000 reg->smear_opt_cfg.rdo_smear_lvl16_multi = flg0 ? 9 : 12;
2001 } else {
2002 reg->smear_opt_cfg.rdo_smear_en = 0;
2003 reg->smear_opt_cfg.rdo_smear_lvl16_multi = 16;
2004 }
2005
2006 if (ctx->qpmap_en && deblur_str > 3) {
2007 flg2 = 1;
2008 if (smear_cnt[2] + smear_cnt[3] > (3 * smear_cnt[4] / 4))
2009 delta_qp = 1;
2010 if (smear_cnt[4] < (mb_cnt >> 4))
2011 delta_qp -= 8;
2012 else if (smear_cnt[4] < ((3 * mb_cnt) >> 5))
2013 delta_qp -= 7;
2014 else
2015 delta_qp -= 6;
2016
2017 if (flg3 == 2)
2018 delta_qp = 0;
2019 else if (flg3 == 1)
2020 delta_qp = -2;
2021 } else {
2022 if (smear_cnt[2] + smear_cnt[3] > smear_cnt[4] / 2)
2023 delta_qp = 1;
2024 if (smear_cnt[4] < (mb_cnt >> 8))
2025 delta_qp -= (deblur_str < 2) ? 6 : 8;
2026 else if (smear_cnt[4] < (mb_cnt >> 7))
2027 delta_qp -= (deblur_str < 2) ? 5 : 6;
2028 else if (smear_cnt[4] < (mb_cnt >> 6))
2029 delta_qp -= (deblur_str < 2) ? 3 : 4;
2030 else
2031 delta_qp -= 1;
2032 }
2033 reg->smear_opt_cfg.rdo_smear_dlt_qp = delta_qp;
2034
2035 if ((H264_I_SLICE == slice->slice_type) ||
2036 (H264_I_SLICE == last_fb->frame_type))
2037 reg->smear_opt_cfg.stated_mode = 1;
2038 else
2039 reg->smear_opt_cfg.stated_mode = 2;
2040
2041 reg->smear_madp_thd0.madp_cur_thd0 = 0;
2042 reg->smear_madp_thd0.madp_cur_thd1 = flg2 ? 48 : 24;
2043 reg->smear_madp_thd1.madp_cur_thd2 = flg2 ? 64 : 48;
2044 reg->smear_madp_thd1.madp_cur_thd3 = flg2 ? 72 : 64;
2045 reg->smear_madp_thd2.madp_around_thd0 = flg2 ? 4095 : 16;
2046 reg->smear_madp_thd2.madp_around_thd1 = 32;
2047 reg->smear_madp_thd3.madp_around_thd2 = 48;
2048 reg->smear_madp_thd3.madp_around_thd3 = flg2 ? 0 : 96;
2049 reg->smear_madp_thd4.madp_around_thd4 = 48;
2050 reg->smear_madp_thd4.madp_around_thd5 = 24;
2051 reg->smear_madp_thd5.madp_ref_thd0 = flg2 ? 64 : 96;
2052 reg->smear_madp_thd5.madp_ref_thd1 = 48;
2053
2054 reg->smear_cnt_thd0.cnt_cur_thd0 = flg2 ? 2 : 1;
2055 reg->smear_cnt_thd0.cnt_cur_thd1 = flg2 ? 5 : 3;
2056 reg->smear_cnt_thd0.cnt_cur_thd2 = 1;
2057 reg->smear_cnt_thd0.cnt_cur_thd3 = 3;
2058 reg->smear_cnt_thd1.cnt_around_thd0 = 1;
2059 reg->smear_cnt_thd1.cnt_around_thd1 = 4;
2060 reg->smear_cnt_thd1.cnt_around_thd2 = 1;
2061 reg->smear_cnt_thd1.cnt_around_thd3 = 4;
2062 reg->smear_cnt_thd2.cnt_around_thd4 = 0;
2063 reg->smear_cnt_thd2.cnt_around_thd5 = 3;
2064 reg->smear_cnt_thd2.cnt_around_thd6 = 0;
2065 reg->smear_cnt_thd2.cnt_around_thd7 = 3;
2066 reg->smear_cnt_thd3.cnt_ref_thd0 = 1;
2067 reg->smear_cnt_thd3.cnt_ref_thd1 = 3;
2068
2069 reg->smear_resi_thd0.resi_small_cur_th0 = 6;
2070 reg->smear_resi_thd0.resi_big_cur_th0 = 9;
2071 reg->smear_resi_thd0.resi_small_cur_th1 = 6;
2072 reg->smear_resi_thd0.resi_big_cur_th1 = 9;
2073 reg->smear_resi_thd1.resi_small_around_th0 = 6;
2074 reg->smear_resi_thd1.resi_big_around_th0 = 11;
2075 reg->smear_resi_thd1.resi_small_around_th1 = 6;
2076 reg->smear_resi_thd1.resi_big_around_th1 = 8;
2077 reg->smear_resi_thd2.resi_small_around_th2 = 9;
2078 reg->smear_resi_thd2.resi_big_around_th2 = 20;
2079 reg->smear_resi_thd2.resi_small_around_th3 = 6;
2080 reg->smear_resi_thd2.resi_big_around_th3 = 20;
2081 reg->smear_resi_thd3.resi_small_ref_th0 = 7;
2082 reg->smear_resi_thd3.resi_big_ref_th0 = 16;
2083 reg->smear_resi_thd4.resi_th0 = flg2 ? 0 : 10;
2084 reg->smear_resi_thd4.resi_th1 = flg2 ? 0 : 6;
2085
2086 reg->smear_st_thd.madp_cnt_th0 = flg2 ? 0 : 1;
2087 reg->smear_st_thd.madp_cnt_th1 = flg2 ? 0 : 5;
2088 reg->smear_st_thd.madp_cnt_th2 = flg2 ? 0 : 1;
2089 reg->smear_st_thd.madp_cnt_th3 = flg2 ? 0 : 3;
2090
2091 hal_h264e_dbg_func("leave\n");
2092 }
2093
setup_vepu511_scaling_list(HalH264eVepu511Ctx * ctx)2094 static void setup_vepu511_scaling_list(HalH264eVepu511Ctx *ctx)
2095 {
2096 HalVepu511RegSet *regs = ctx->regs_set;
2097 H264eVepu511SclCfg *s = ®s->reg_scl;
2098 RK_U8 *p = (RK_U8 *)&s->tu8_intra_y[0];
2099 RK_U8 idx;
2100
2101 hal_h264e_dbg_func("enter\n");
2102
2103 /* intra4x4 and inter4x4 is not supported on VEPU500.
2104 * valid range: 0x2200 ~ 0x221F
2105 */
2106 if (ctx->pps->pic_scaling_matrix_present == 1) {
2107 for (idx = 0; idx < 64; idx++) {
2108 p[idx] = vepu511_h264_cqm_jvt8i[63 - idx]; /* intra8x8 */
2109 p[idx + 64] = vepu511_h264_cqm_jvt8p[63 - idx]; /* inter8x8 */
2110 }
2111 } else if (ctx->pps->pic_scaling_matrix_present == 2) {
2112 //TODO: Update scaling list for (scaling_list_mode == 2)
2113 mpp_log_f("scaling_list_mode 2 is not supported yet\n");
2114 }
2115
2116 hal_h264e_dbg_func("leave\n");
2117 }
2118
hal_h264e_vepu511_gen_regs(void * hal,HalEncTask * task)2119 static MPP_RET hal_h264e_vepu511_gen_regs(void *hal, HalEncTask *task)
2120 {
2121 HalH264eVepu511Ctx *ctx = (HalH264eVepu511Ctx *)hal;
2122 HalVepu511RegSet *regs = ctx->regs_set;
2123 MppEncCfgSet *cfg = ctx->cfg;
2124 EncRcTask *rc_task = task->rc_task;
2125 EncFrmStatus *frm = &rc_task->frm;
2126 MPP_RET ret = MPP_OK;
2127
2128 hal_h264e_dbg_func("enter %p\n", hal);
2129 hal_h264e_dbg_detail("frame %d generate regs now", ctx->frms->seq_idx);
2130
2131 /* register setup */
2132 memset(regs, 0, sizeof(*regs));
2133
2134 setup_vepu511_normal(regs);
2135 ret = setup_vepu511_prep(regs, &ctx->cfg->prep, task);
2136 if (ret)
2137 return ret;
2138
2139 setup_vepu511_codec(regs, ctx);
2140 setup_vepu511_rdo_pred(ctx);
2141 setup_vepu511_aq(ctx);
2142 setup_vepu511_anti_stripe(ctx);
2143 setup_vepu511_anti_ringing(ctx);
2144 setup_vepu511_anti_flicker(ctx);
2145 setup_vepu511_anti_smear(ctx);
2146 setup_vepu511_scaling_list(ctx);
2147
2148 setup_vepu511_rc_base(regs, ctx, rc_task);
2149 setup_vepu511_io_buf(regs, ctx->offsets, task);
2150 setup_vepu511_recn_refr(ctx, regs);
2151 setup_vepu511_split(regs, cfg);
2152 setup_vepu511_me(ctx);
2153
2154 if (frm->is_i_refresh)
2155 setup_vepu511_intra_refresh(regs, ctx, frm->seq_idx % cfg->rc.gop);
2156
2157 setup_vepu511_l2(ctx);
2158 setup_vepu511_ext_line_buf(regs, ctx);
2159
2160 if (ctx->osd_cfg.osd_data3)
2161 vepu511_set_osd(&ctx->osd_cfg, ®s->reg_osd.osd_comb_cfg);
2162
2163 if (ctx->roi_data)
2164 vepu511_set_roi(&ctx->regs_set->reg_rc_roi.roi_cfg, ctx->roi_data,
2165 ctx->cfg->prep.width, ctx->cfg->prep.height);
2166
2167 /* two pass register patch */
2168 if (frm->save_pass1)
2169 vepu511_h264e_save_pass1_patch(regs, ctx);
2170
2171 if (frm->use_pass1)
2172 vepu511_h264e_use_pass1_patch(regs, ctx);
2173
2174 ctx->frame_cnt++;
2175
2176 hal_h264e_dbg_func("leave %p\n", hal);
2177 return MPP_OK;
2178 }
2179
hal_h264e_vepu511_start(void * hal,HalEncTask * task)2180 static MPP_RET hal_h264e_vepu511_start(void *hal, HalEncTask *task)
2181 {
2182 MPP_RET ret = MPP_OK;
2183 HalH264eVepu511Ctx *ctx = (HalH264eVepu511Ctx *)hal;
2184 HalVepu511RegSet *regs = ctx->regs_set;
2185
2186 (void) task;
2187
2188 hal_h264e_dbg_func("enter %p\n", hal);
2189
2190 do {
2191 MppDevRegWrCfg wr_cfg;
2192 MppDevRegRdCfg rd_cfg;
2193
2194 wr_cfg.reg = ®s->reg_ctl;
2195 wr_cfg.size = sizeof(regs->reg_ctl);
2196 wr_cfg.offset = VEPU511_CTL_OFFSET;
2197 #if DUMP_REG
2198 {
2199 RK_U32 i;
2200 RK_U32 *reg = (RK_U32)wr_cfg.reg;
2201 for ( i = 0; i < sizeof(regs->reg_ctl) / sizeof(RK_U32); i++) {
2202 mpp_log("reg[%d] = 0x%08x\n", i, reg[i]);
2203 }
2204
2205 }
2206 #endif
2207 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2208 if (ret) {
2209 mpp_err_f("set register write failed %d\n", ret);
2210 break;
2211 }
2212
2213 wr_cfg.reg = ®s->reg_frm;
2214 wr_cfg.size = sizeof(regs->reg_frm);
2215 wr_cfg.offset = VEPU511_FRAME_OFFSET;
2216
2217 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2218 if (ret) {
2219 mpp_err_f("set register write failed %d\n", ret);
2220 break;
2221 }
2222
2223 wr_cfg.reg = ®s->reg_rc_roi;
2224 wr_cfg.size = sizeof(regs->reg_rc_roi);
2225 wr_cfg.offset = VEPU511_RC_ROI_OFFSET;
2226
2227 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2228 if (ret) {
2229 mpp_err_f("set register write failed %d\n", ret);
2230 break;
2231 }
2232
2233 wr_cfg.reg = ®s->reg_param;
2234 wr_cfg.size = sizeof(regs->reg_param);
2235 wr_cfg.offset = VEPU511_PARAM_OFFSET;
2236
2237 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2238 if (ret) {
2239 mpp_err_f("set register write failed %d\n", ret);
2240 break;
2241 }
2242
2243 wr_cfg.reg = ®s->reg_sqi;
2244 wr_cfg.size = sizeof(regs->reg_sqi);
2245 wr_cfg.offset = VEPU511_SQI_OFFSET;
2246
2247 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2248 if (ret) {
2249 mpp_err_f("set register write failed %d\n", ret);
2250 break;
2251 }
2252
2253 wr_cfg.reg = ®s->reg_scl;
2254 wr_cfg.size = sizeof(regs->reg_scl);
2255 wr_cfg.offset = VEPU511_SCL_OFFSET ;
2256
2257 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2258 if (ret) {
2259 mpp_err_f("set register write failed %d\n", ret);
2260 break;
2261 }
2262
2263 wr_cfg.reg = ®s->reg_osd;
2264 wr_cfg.size = sizeof(regs->reg_osd);
2265 wr_cfg.offset = VEPU511_OSD_OFFSET ;
2266
2267 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2268 if (ret) {
2269 mpp_err_f("set register write failed %d\n", ret);
2270 return ret;
2271 }
2272
2273 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFS, ctx->offsets);
2274 if (ret) {
2275 mpp_err_f("set register offsets failed %d\n", ret);
2276 break;
2277 }
2278
2279 rd_cfg.reg = ®s->reg_ctl.int_sta;
2280 rd_cfg.size = sizeof(RK_U32);
2281 rd_cfg.offset = VEPU511_REG_BASE_HW_STATUS;
2282 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
2283 if (ret) {
2284 mpp_err_f("set register read failed %d\n", ret);
2285 break;
2286 }
2287
2288 rd_cfg.reg = ®s->reg_st;
2289 rd_cfg.size = sizeof(regs->reg_st);
2290 rd_cfg.offset = VEPU511_STATUS_OFFSET;
2291
2292 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
2293 if (ret) {
2294 mpp_err_f("set register read failed %d\n", ret);
2295 break;
2296 }
2297
2298 /* send request to hardware */
2299 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
2300 if (ret) {
2301 mpp_err_f("send cmd failed %d\n", ret);
2302 break;
2303 }
2304 } while (0);
2305
2306 hal_h264e_dbg_func("leave %p\n", hal);
2307
2308 return ret;
2309 }
2310
hal_h264e_vepu511_status_check(HalVepu511RegSet * regs)2311 static MPP_RET hal_h264e_vepu511_status_check(HalVepu511RegSet *regs)
2312 {
2313 MPP_RET ret = MPP_OK;
2314
2315 if (regs->reg_ctl.int_sta.lkt_node_done_sta)
2316 hal_h264e_dbg_detail("lkt_done finish");
2317
2318 if (regs->reg_ctl.int_sta.enc_done_sta)
2319 hal_h264e_dbg_detail("enc_done finish");
2320
2321 if (regs->reg_ctl.int_sta.vslc_done_sta)
2322 hal_h264e_dbg_detail("enc_slice finsh");
2323
2324 if (regs->reg_ctl.int_sta.sclr_done_sta)
2325 hal_h264e_dbg_detail("safe clear finsh");
2326
2327 if (regs->reg_ctl.int_sta.vbsf_oflw_sta) {
2328 mpp_err_f("bit stream overflow");
2329 ret = MPP_NOK;
2330 }
2331
2332 if (regs->reg_ctl.int_sta.vbuf_lens_sta) {
2333 mpp_err_f("bus write full");
2334 ret = MPP_NOK;
2335 }
2336
2337 if (regs->reg_ctl.int_sta.enc_err_sta) {
2338 mpp_err_f("bus error");
2339 ret = MPP_NOK;
2340 }
2341
2342 if (regs->reg_ctl.int_sta.wdg_sta) {
2343 mpp_err_f("wdg timeout");
2344 ret = MPP_NOK;
2345 }
2346
2347 return ret;
2348 }
2349
hal_h264e_vepu511_wait(void * hal,HalEncTask * task)2350 static MPP_RET hal_h264e_vepu511_wait(void *hal, HalEncTask *task)
2351 {
2352 MPP_RET ret = MPP_OK;
2353 HalH264eVepu511Ctx *ctx = (HalH264eVepu511Ctx *)hal;
2354 HalVepu511RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
2355 RK_U32 split_out = ctx->cfg->split.split_out;
2356 MppPacket pkt = task->packet;
2357 RK_S32 offset = mpp_packet_get_length(pkt);
2358 H264NaluType type = task->rc_task->frm.is_idr ? H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE;
2359 MppEncH264HwCfg *hw_cfg = &ctx->cfg->h264.hw_cfg;
2360 RK_S32 i;
2361
2362 hal_h264e_dbg_func("enter %p\n", hal);
2363
2364 /* if pass1 mode, it will disable split mode and the split out need to be disable */
2365 if (task->rc_task->frm.save_pass1)
2366 split_out = 0;
2367
2368 /* update split_out in hw_cfg */
2369 hw_cfg->hw_split_out = split_out;
2370
2371 if (split_out) {
2372 EncOutParam param;
2373 RK_U32 slice_len;
2374 RK_U32 slice_last;
2375 MppDevPollCfg *poll_cfg = (MppDevPollCfg *)((char *)ctx->poll_cfgs +
2376 task->flags.reg_idx * ctx->poll_cfg_size);
2377 param.task = task;
2378 param.base = mpp_packet_get_data(task->packet);
2379
2380 do {
2381 poll_cfg->poll_type = 0;
2382 poll_cfg->poll_ret = 0;
2383 poll_cfg->count_max = ctx->poll_slice_max;
2384 poll_cfg->count_ret = 0;
2385
2386 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, poll_cfg);
2387
2388 for (i = 0; i < poll_cfg->count_ret; i++) {
2389 slice_last = poll_cfg->slice_info[i].last;
2390 slice_len = poll_cfg->slice_info[i].length;
2391
2392 mpp_packet_add_segment_info(pkt, type, offset, slice_len);
2393 offset += slice_len;
2394
2395 if (split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) {
2396 param.length = slice_len;
2397
2398 if (slice_last)
2399 ctx->output_cb->cmd = ENC_OUTPUT_FINISH;
2400 else
2401 ctx->output_cb->cmd = ENC_OUTPUT_SLICE;
2402
2403 mpp_callback(ctx->output_cb, ¶m);
2404 }
2405 }
2406 } while (!slice_last);
2407
2408 ret = hal_h264e_vepu511_status_check(regs);
2409 if (!ret)
2410 task->hw_length += regs->reg_st.bs_lgth_l32;
2411 } else {
2412 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
2413 if (ret) {
2414 mpp_err_f("poll cmd failed %d\n", ret);
2415 ret = MPP_ERR_VPUHW;
2416 } else {
2417 ret = hal_h264e_vepu511_status_check(regs);
2418 if (!ret)
2419 task->hw_length += regs->reg_st.bs_lgth_l32;
2420 }
2421
2422 mpp_packet_add_segment_info(pkt, type, offset, regs->reg_st.bs_lgth_l32);
2423 }
2424
2425 if (!(split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) && !ret) {
2426 HalH264eVepuStreamAmend *amend = &ctx->amend_sets[task->flags.reg_idx];
2427
2428 if (amend->enable) {
2429 amend->old_length = task->hw_length;
2430 amend->slice->is_multi_slice = (ctx->cfg->split.split_mode > 0);
2431 h264e_vepu_stream_amend_proc(amend, &ctx->cfg->h264.hw_cfg);
2432 task->hw_length = amend->new_length;
2433 } else if (amend->prefix) {
2434 /* check prefix value */
2435 amend->old_length = task->hw_length;
2436 h264e_vepu_stream_amend_sync_ref_idc(amend);
2437 }
2438 }
2439
2440 hal_h264e_dbg_func("leave %p ret %d\n", hal, ret);
2441
2442 return ret;
2443 }
2444
vepu511_h264e_update_tune_stat(HalH264eVepu511Ctx * ctx,HalEncTask * task)2445 static void vepu511_h264e_update_tune_stat(HalH264eVepu511Ctx *ctx, HalEncTask *task)
2446 {
2447 HalVepu511RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
2448 Vepu511Status *reg_st = ®s->reg_st;
2449 EncRcTaskInfo *rc_info = &task->rc_task->info;
2450 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
2451 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
2452 RK_U32 mbs = mb_w * mb_h;
2453 RK_U32 madi_th_cnt[4], madp_th_cnt[4];
2454 RK_U32 madi_cnt = 0, madp_cnt = 0;
2455 RK_U32 md_cnt;
2456
2457 madi_th_cnt[0] = reg_st->st_madi_lt_num0.madi_th_lt_cnt0 +
2458 reg_st->st_madi_rt_num0.madi_th_rt_cnt0 +
2459 reg_st->st_madi_lb_num0.madi_th_lb_cnt0 +
2460 reg_st->st_madi_rb_num0.madi_th_rb_cnt0;
2461 madi_th_cnt[1] = reg_st->st_madi_lt_num0.madi_th_lt_cnt1 +
2462 reg_st->st_madi_rt_num0.madi_th_rt_cnt1 +
2463 reg_st->st_madi_lb_num0.madi_th_lb_cnt1 +
2464 reg_st->st_madi_rb_num0.madi_th_rb_cnt1;
2465 madi_th_cnt[2] = reg_st->st_madi_lt_num1.madi_th_lt_cnt2 +
2466 reg_st->st_madi_rt_num1.madi_th_rt_cnt2 +
2467 reg_st->st_madi_lb_num1.madi_th_lb_cnt2 +
2468 reg_st->st_madi_rb_num1.madi_th_rb_cnt2;
2469 madi_th_cnt[3] = reg_st->st_madi_lt_num1.madi_th_lt_cnt3 +
2470 reg_st->st_madi_rt_num1.madi_th_rt_cnt3 +
2471 reg_st->st_madi_lb_num1.madi_th_lb_cnt3 +
2472 reg_st->st_madi_rb_num1.madi_th_rb_cnt3;
2473 madp_th_cnt[0] = reg_st->st_madp_lt_num0.madp_th_lt_cnt0 +
2474 reg_st->st_madp_rt_num0.madp_th_rt_cnt0 +
2475 reg_st->st_madp_lb_num0.madp_th_lb_cnt0 +
2476 reg_st->st_madp_rb_num0.madp_th_rb_cnt0;
2477 madp_th_cnt[1] = reg_st->st_madp_lt_num0.madp_th_lt_cnt1 +
2478 reg_st->st_madp_rt_num0.madp_th_rt_cnt1 +
2479 reg_st->st_madp_lb_num0.madp_th_lb_cnt1 +
2480 reg_st->st_madp_rb_num0.madp_th_rb_cnt1;
2481 madp_th_cnt[2] = reg_st->st_madp_lt_num1.madp_th_lt_cnt2 +
2482 reg_st->st_madp_rt_num1.madp_th_rt_cnt2 +
2483 reg_st->st_madp_lb_num1.madp_th_lb_cnt2 +
2484 reg_st->st_madp_rb_num1.madp_th_rb_cnt2;
2485 madp_th_cnt[3] = reg_st->st_madp_lt_num1.madp_th_lt_cnt3 +
2486 reg_st->st_madp_rt_num1.madp_th_rt_cnt3 +
2487 reg_st->st_madp_lb_num1.madp_th_lb_cnt3 +
2488 reg_st->st_madp_rb_num1.madp_th_rb_cnt3;
2489
2490 if (ctx->smart_en)
2491 md_cnt = (12 * madp_th_cnt[3] + 11 * madp_th_cnt[2] + 8 * madp_th_cnt[1]) >> 2;
2492 else
2493 md_cnt = (24 * madp_th_cnt[3] + 22 * madp_th_cnt[2] + 17 * madp_th_cnt[1]) >> 2;
2494 madi_cnt = (6 * madi_th_cnt[3] + 5 * madi_th_cnt[2] + 4 * madi_th_cnt[1]) >> 2;
2495
2496 /* fill rc info */
2497 if (md_cnt * 100 > 15 * mbs)
2498 rc_info->motion_level = 200;
2499 else if (md_cnt * 100 > 5 * mbs)
2500 rc_info->motion_level = 100;
2501 else if (md_cnt * 100 > (mbs >> 2))
2502 rc_info->motion_level = 1;
2503 else
2504 rc_info->motion_level = 0;
2505
2506 if (madi_cnt * 100 > 30 * mbs)
2507 rc_info->complex_level = 2;
2508 else if (madi_cnt * 100 > 13 * mbs)
2509 rc_info->complex_level = 1;
2510 else
2511 rc_info->complex_level = 0;
2512
2513 rc_info->madi = madi_th_cnt[0] * regs->reg_rc_roi.madi_st_thd.madi_th0 +
2514 madi_th_cnt[1] * (regs->reg_rc_roi.madi_st_thd.madi_th0 +
2515 regs->reg_rc_roi.madi_st_thd.madi_th1) / 2 +
2516 madi_th_cnt[2] * (regs->reg_rc_roi.madi_st_thd.madi_th1 +
2517 regs->reg_rc_roi.madi_st_thd.madi_th2) / 2 +
2518 madi_th_cnt[3] * regs->reg_rc_roi.madi_st_thd.madi_th2;
2519
2520 madi_cnt = madi_th_cnt[0] + madi_th_cnt[1] + madi_th_cnt[2] + madi_th_cnt[3];
2521 if (madi_cnt)
2522 rc_info->madi = rc_info->madi / madi_cnt;
2523
2524 rc_info->madp = madp_th_cnt[0] * regs->reg_rc_roi.madp_st_thd0.madp_th0 +
2525 madp_th_cnt[1] * (regs->reg_rc_roi.madp_st_thd0.madp_th0 +
2526 regs->reg_rc_roi.madp_st_thd0.madp_th1) / 2 +
2527 madp_th_cnt[2] * (regs->reg_rc_roi.madp_st_thd0.madp_th1 +
2528 regs->reg_rc_roi.madp_st_thd1.madp_th2) / 2 +
2529 madp_th_cnt[3] * regs->reg_rc_roi.madp_st_thd1.madp_th2;
2530
2531 madp_cnt = madp_th_cnt[0] + madp_th_cnt[1] + madp_th_cnt[2] + madp_th_cnt[3];
2532
2533 if (madp_cnt)
2534 rc_info->madp = rc_info->madp / madp_cnt;
2535
2536 hal_h264e_dbg_rc("complex_level %d motion_level %d\n",
2537 rc_info->complex_level, rc_info->motion_level);
2538 }
2539
hal_h264e_vepu511_ret_task(void * hal,HalEncTask * task)2540 static MPP_RET hal_h264e_vepu511_ret_task(void * hal, HalEncTask * task)
2541 {
2542 HalH264eVepu511Ctx *ctx = (HalH264eVepu511Ctx *)hal;
2543 HalVepu511RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
2544 EncRcTaskInfo *rc_info = &task->rc_task->info;
2545 Vepu511H264Fbk *fb = &ctx->feedback;
2546 Vepu511Status *reg_st = ®s->reg_st;
2547 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
2548 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
2549 RK_U32 mbs = mb_w * mb_h;
2550
2551 hal_h264e_dbg_func("enter %p\n", hal);
2552
2553 fb->st_mb_num = mbs;
2554 fb->st_smear_cnt[0] = reg_st->st_smear_cnt0.rdo_smear_cnt0 * 4;
2555 fb->st_smear_cnt[1] = reg_st->st_smear_cnt0.rdo_smear_cnt1 * 4;
2556 fb->st_smear_cnt[2] = reg_st->st_smear_cnt1.rdo_smear_cnt2 * 4;
2557 fb->st_smear_cnt[3] = reg_st->st_smear_cnt1.rdo_smear_cnt3 * 4;
2558 fb->st_smear_cnt[4] = fb->st_smear_cnt[0] + fb->st_smear_cnt[1] +
2559 fb->st_smear_cnt[2] + fb->st_smear_cnt[3];
2560 fb->frame_type = ctx->slice->slice_type;
2561
2562 // update total hardware length
2563 task->length += task->hw_length;
2564
2565 // setup bit length for rate control
2566 rc_info->bit_real = task->hw_length * 8;
2567 rc_info->quality_real = regs->reg_st.qp_sum / mbs;
2568 rc_info->iblk4_prop = (regs->reg_st.st_pnum_i4.pnum_i4 +
2569 regs->reg_st.st_pnum_i8.pnum_i8 +
2570 regs->reg_st.st_pnum_i16.pnum_i16) * 256 / mbs;
2571
2572 rc_info->sse = ((RK_S64)regs->reg_st.sse_h32 << 16) +
2573 (regs->reg_st.st_sse_bsl.sse_l16 & 0xffff);
2574 rc_info->lvl16_inter_num = regs->reg_st.st_pnum_p16.pnum_p16;
2575 rc_info->lvl8_inter_num = regs->reg_st.st_pnum_p8.pnum_p8;
2576 rc_info->lvl16_intra_num = regs->reg_st.st_pnum_i16.pnum_i16;
2577 rc_info->lvl8_intra_num = regs->reg_st.st_pnum_i8.pnum_i8;
2578 rc_info->lvl4_intra_num = regs->reg_st.st_pnum_i4.pnum_i4;
2579
2580 ctx->hal_rc_cfg.bit_real = rc_info->bit_real;
2581 ctx->hal_rc_cfg.quality_real = rc_info->quality_real;
2582 ctx->hal_rc_cfg.iblk4_prop = rc_info->iblk4_prop;
2583
2584 task->hal_ret.data = &ctx->hal_rc_cfg;
2585 task->hal_ret.number = 1;
2586
2587 mpp_dev_multi_offset_reset(ctx->offsets);
2588
2589 if (ctx->dpb) {
2590 h264e_dpb_hal_end(ctx->dpb, task->flags.curr_idx);
2591 h264e_dpb_hal_end(ctx->dpb, task->flags.refr_idx);
2592 }
2593
2594 vepu511_h264e_update_tune_stat(ctx, task);
2595
2596 hal_h264e_dbg_func("leave %p\n", hal);
2597
2598 return MPP_OK;
2599 }
2600
2601 const MppEncHalApi hal_h264e_vepu511 = {
2602 .name = "hal_h264e_vepu511",
2603 .coding = MPP_VIDEO_CodingAVC,
2604 .ctx_size = sizeof(HalH264eVepu511Ctx),
2605 .flag = 0,
2606 .init = hal_h264e_vepu511_init,
2607 .deinit = hal_h264e_vepu511_deinit,
2608 .prepare = hal_h264e_vepu511_prepare,
2609 .get_task = hal_h264e_vepu511_get_task,
2610 .gen_regs = hal_h264e_vepu511_gen_regs,
2611 .start = hal_h264e_vepu511_start,
2612 .wait = hal_h264e_vepu511_wait,
2613 .part_start = NULL,
2614 .part_wait = NULL,
2615 .ret_task = hal_h264e_vepu511_ret_task,
2616 };
2617