1 /*
2 * Copyright 2021 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
17 #define MODULE_TAG "hal_h264e_vepu580"
18
19 #include <string.h>
20
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_common.h"
24 #include "mpp_frame_impl.h"
25 #include "mpp_packet_impl.h"
26 #include "mpp_rc.h"
27
28 #include "h264e_sps.h"
29 #include "h264e_pps.h"
30 #include "h264e_dpb.h"
31 #include "h264e_slice.h"
32
33 #include "hal_h264e_debug.h"
34 #include "hal_bufs.h"
35 #include "mpp_enc_hal.h"
36 #include "rkv_enc_def.h"
37 #include "vepu5xx_common.h"
38 #include "vepu580_common.h"
39 #include "vepu5xx.h"
40 #include "hal_h264e_vepu580_reg.h"
41 #include "mpp_enc_cb_param.h"
42 #include "hal_h264e_stream_amend.h"
43
44 #define DUMP_REG 0
45 #define MAX_TASK_CNT 2
46
47 typedef struct Vepu580RoiH264BsCfg_t {
48 RK_U64 force_inter : 42;
49 RK_U64 mode_mask : 9;
50 RK_U64 reserved : 10;
51 RK_U64 force_intra : 1;
52 RK_U64 qp_adj_en : 1;
53 RK_U64 amv_en : 1;
54 } Vepu580RoiH264BsCfg;
55
56 typedef struct HalH264eVepu580Ctx_t {
57 MppEncCfgSet *cfg;
58
59 MppDev dev;
60 RK_S32 frame_cnt;
61 RK_U32 task_cnt;
62
63 /* buffers management */
64 HalBufs hw_recn;
65 RK_S32 pixel_buf_fbc_hdr_size;
66 RK_S32 pixel_buf_fbc_bdy_size;
67 RK_S32 pixel_buf_size;
68 RK_S32 thumb_buf_size;
69 RK_S32 max_buf_cnt;
70 MppDevRegOffCfgs *offsets;
71
72 /* external line buffer over 4K */
73 MppBufferGroup ext_line_buf_grp;
74 MppBuffer ext_line_bufs[MAX_TASK_CNT];
75 RK_S32 ext_line_buf_size;
76
77 /* syntax for input from enc_impl */
78 RK_U32 updated;
79 H264eSps *sps;
80 H264ePps *pps;
81 H264eDpb *dpb;
82 H264eFrmInfo *frms;
83
84 /* async encode TSVC info */
85 H264eReorderInfo *reorder;
86 H264eMarkingInfo *marking;
87
88 /* syntax for output to enc_impl */
89 EncRcTaskInfo hal_rc_cfg;
90
91 /* roi */
92 void *roi_data;
93 MppBufferGroup roi_grp;
94 MppBuffer roi_base_cfg_buf;
95 RK_S32 roi_base_buf_size;
96
97 /* osd */
98 Vepu5xxOsdCfg osd_cfg;
99
100 /* finetune */
101 void *tune;
102 MppBuffer qpmap_base_cfg_buf;
103 MppBuffer qpmap_qp_cfg_buf;
104 RK_U8* md_flag_buf;
105 RK_S32 qpmap_base_cfg_size;
106 RK_S32 qpmap_qp_cfg_size;
107 RK_S32 md_flag_size;
108
109 /* two-pass deflicker */
110 MppBuffer buf_pass1;
111
112 /* register */
113 HalVepu580RegSet *regs_sets;
114 HalH264eVepuStreamAmend *amend_sets;
115
116 H264ePrefixNal *prefix_sets;
117 H264eSlice *slice_sets;
118
119 /* frame parallel info */
120 RK_S32 task_idx;
121 RK_S32 curr_idx;
122 RK_S32 prev_idx;
123 HalVepu580RegSet *regs_set;
124 HalH264eVepuStreamAmend *amend;
125 H264ePrefixNal *prefix;
126 H264eSlice *slice;
127
128 MppBuffer ext_line_buf;
129
130 /* slice low delay output callback */
131 MppCbCtx *output_cb;
132 RK_S32 poll_slice_max;
133 RK_S32 poll_cfg_size;
134 MppDevPollCfg *poll_cfgs;
135 } HalH264eVepu580Ctx;
136
137 #define CHROMA_KLUT_TAB_SIZE (24 * sizeof(RK_U32))
138
139 static RK_U32 h264e_klut_weight[30] = {
140 0x0a000010, 0x00064000, 0x14000020, 0x000c8000,
141 0x28000040, 0x00194000, 0x50800080, 0x0032c000,
142 0xa1000100, 0x00658000, 0x42800200, 0x00cb0001,
143 0x85000400, 0x01964002, 0x0a000800, 0x032c8005,
144 0x14001000, 0x0659400a, 0x28802000, 0x0cb2c014,
145 0x51004000, 0x1965c028, 0xa2808000, 0x32cbc050,
146 0x4500ffff, 0x659780a1, 0x8a81fffe, 0xCC000142,
147 0xFF83FFFF, 0x000001FF,
148 };
149
150 static RK_U32 disable_rcb_buf = 0;
151
152 static RK_U32 h264_mode_bias[16] = {
153 0, 2, 4, 6,
154 8, 10, 12, 14,
155 16, 18, 20, 24,
156 28, 32, 64, 128
157 };
158
159 static RK_S32 h264_aq_tthd_default[16] = {
160 0, 0, 0, 0,
161 3, 3, 5, 5,
162 8, 8, 8, 15,
163 15, 20, 25, 35,
164 };
165
166 static RK_S32 h264_P_aq_step_default[16] = {
167 -8, -7, -6, -5,
168 -4, -3, -2, -1,
169 0, 1, 2, 3,
170 4, 5, 7, 8,
171 };
172
173 static RK_S32 h264_I_aq_step_default[16] = {
174 -8, -7, -6, -5,
175 -4, -3, -2, -1,
176 0, 1, 2, 3,
177 4, 5, 6, 8,
178 };
179
180 #include "hal_h264e_vepu580_tune.c"
181
setup_ext_line_bufs(HalH264eVepu580Ctx * ctx)182 static void setup_ext_line_bufs(HalH264eVepu580Ctx *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(HalH264eVepu580Ctx * ctx)195 static void clear_ext_line_bufs(HalH264eVepu580Ctx *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_vepu580_deinit(void * hal)207 static MPP_RET hal_h264e_vepu580_deinit(void *hal)
208 {
209 HalH264eVepu580Ctx *p = (HalH264eVepu580Ctx *)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 vepu580_h264e_tune_deinit(p->tune);
267 p->tune = NULL;
268 }
269
270 if (p->qpmap_base_cfg_buf) {
271 mpp_buffer_put(p->qpmap_base_cfg_buf);
272 p->qpmap_base_cfg_buf = NULL;
273 }
274
275 if (p->qpmap_qp_cfg_buf) {
276 mpp_buffer_put(p->qpmap_qp_cfg_buf);
277 p->qpmap_qp_cfg_buf = NULL;
278 }
279
280 if (p->md_flag_buf) {
281 MPP_FREE(p->md_flag_buf);
282 }
283
284 hal_h264e_dbg_func("leave %p\n", p);
285
286 return MPP_OK;
287 }
288
hal_h264e_vepu580_init(void * hal,MppEncHalCfg * cfg)289 static MPP_RET hal_h264e_vepu580_init(void *hal, MppEncHalCfg *cfg)
290 {
291 HalH264eVepu580Ctx *p = (HalH264eVepu580Ctx *)hal;
292 MPP_RET ret = MPP_OK;
293 RK_U32 i;
294
295 hal_h264e_dbg_func("enter %p\n", p);
296
297 p->cfg = cfg->cfg;
298
299 mpp_env_get_u32("disable_rcb_buf", &disable_rcb_buf, 0);
300
301 /* update output to MppEnc */
302 cfg->type = VPU_CLIENT_RKVENC;
303 ret = mpp_dev_init(&cfg->dev, cfg->type);
304 if (ret) {
305 mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
306 goto DONE;
307 }
308 p->dev = cfg->dev;
309 p->task_cnt = cfg->task_cnt;
310 mpp_assert(p->task_cnt && p->task_cnt <= MAX_TASK_CNT);
311
312 ret = hal_bufs_init(&p->hw_recn);
313 if (ret) {
314 mpp_err_f("init vepu buffer failed ret: %d\n", ret);
315 goto DONE;
316 }
317
318 p->regs_sets = mpp_malloc(HalVepu580RegSet, p->task_cnt);
319 if (NULL == p->regs_sets) {
320 ret = MPP_ERR_MALLOC;
321 mpp_err_f("init register buffer failed\n");
322 goto DONE;
323 }
324 p->amend_sets = mpp_malloc(HalH264eVepuStreamAmend, p->task_cnt);
325 if (NULL == p->amend_sets) {
326 ret = MPP_ERR_MALLOC;
327 mpp_err_f("init amend data failed\n");
328 goto DONE;
329 }
330
331 if (p->task_cnt > 1) {
332 p->prefix_sets = mpp_malloc(H264ePrefixNal, p->task_cnt);
333 if (NULL == p->prefix_sets) {
334 ret = MPP_ERR_MALLOC;
335 mpp_err_f("init amend data failed\n");
336 goto DONE;
337 }
338
339 p->slice_sets = mpp_malloc(H264eSlice, p->task_cnt);
340 if (NULL == p->slice_sets) {
341 ret = MPP_ERR_MALLOC;
342 mpp_err_f("init amend data failed\n");
343 goto DONE;
344 }
345
346 p->reorder = mpp_malloc(H264eReorderInfo, 1);
347 if (NULL == p->reorder) {
348 ret = MPP_ERR_MALLOC;
349 mpp_err_f("init amend data failed\n");
350 goto DONE;
351 }
352
353 p->marking = mpp_malloc(H264eMarkingInfo, 1);
354 if (NULL == p->marking) {
355 ret = MPP_ERR_MALLOC;
356 mpp_err_f("init amend data failed\n");
357 goto DONE;
358 }
359 }
360
361 p->poll_slice_max = 8;
362 p->poll_cfg_size = (sizeof(p->poll_cfgs) + sizeof(RK_S32) * p->poll_slice_max);
363 p->poll_cfgs = mpp_malloc_size(MppDevPollCfg, p->poll_cfg_size * p->task_cnt);
364 if (NULL == p->poll_cfgs) {
365 ret = MPP_ERR_MALLOC;
366 mpp_err_f("init poll cfg buffer failed\n");
367 goto DONE;
368 }
369
370 p->osd_cfg.reg_base = &p->regs_sets->reg_osd;
371 p->osd_cfg.dev = p->dev;
372 p->osd_cfg.reg_cfg = NULL;
373 p->osd_cfg.plt_cfg = &p->cfg->plt_cfg;
374 p->osd_cfg.osd_data = NULL;
375 p->osd_cfg.osd_data2 = NULL;
376
377 { /* setup default hardware config */
378 MppEncHwCfg *hw = &cfg->cfg->hw;
379
380 hw->qp_delta_row_i = 2;
381 hw->qp_delta_row = 2;
382 hw->extra_buf = 1;
383 hw->qbias_i = 683;
384 hw->qbias_p = 341;
385 hw->qbias_en = 0;
386
387 memcpy(hw->aq_thrd_i, h264_aq_tthd_default, sizeof(hw->aq_thrd_i));
388 memcpy(hw->aq_thrd_p, h264_aq_tthd_default, sizeof(hw->aq_thrd_p));
389 memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i));
390 memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p));
391
392 for (i = 0; i < MPP_ARRAY_ELEMS(hw->mode_bias); i++)
393 hw->mode_bias[i] = 8;
394
395 hw->skip_sad = 8;
396 hw->skip_bias = 8;
397 }
398 mpp_dev_multi_offset_init(&p->offsets, 24);
399 p->osd_cfg.reg_cfg = p->offsets;
400
401 p->tune = vepu580_h264e_tune_init(p);
402 p->output_cb = cfg->output_cb;
403
404 cfg->cap_recn_out = 1;
405
406 for (i = 0; i < p->task_cnt; i++)
407 h264e_vepu_stream_amend_init(&p->amend_sets[i]);
408
409 DONE:
410 if (ret)
411 hal_h264e_vepu580_deinit(hal);
412
413 hal_h264e_dbg_func("leave %p\n", p);
414 return ret;
415 }
416
417 /*
418 * NOTE: recon / refer buffer is FBC data buffer.
419 * And FBC data require extra 16 lines space for hardware io.
420 */
setup_hal_bufs(HalH264eVepu580Ctx * ctx)421 static void setup_hal_bufs(HalH264eVepu580Ctx *ctx)
422 {
423 MppEncCfgSet *cfg = ctx->cfg;
424 MppEncPrepCfg *prep = &cfg->prep;
425 RK_S32 alignment_w = 64;
426 RK_S32 alignment_h = 16;
427 RK_S32 aligned_w = MPP_ALIGN(prep->width, alignment_w);
428 RK_S32 aligned_h = MPP_ALIGN(prep->height, alignment_h) + 16;
429 RK_S32 pixel_buf_fbc_hdr_size = MPP_ALIGN(aligned_w * aligned_h / 64, SZ_8K);
430 RK_S32 pixel_buf_fbc_bdy_size = aligned_w * aligned_h * 3 / 2;
431 RK_S32 pixel_buf_size = pixel_buf_fbc_hdr_size + pixel_buf_fbc_bdy_size;
432 RK_S32 thumb_buf_size = MPP_ALIGN(aligned_w / 64 * aligned_h / 64 * 256, SZ_8K);
433 RK_S32 old_max_cnt = ctx->max_buf_cnt;
434 RK_S32 new_max_cnt = 4;
435 MppEncRefCfg ref_cfg = cfg->ref_cfg;
436
437 if (ref_cfg) {
438 MppEncCpbInfo *info = mpp_enc_ref_cfg_get_cpb_info(ref_cfg);
439 if (new_max_cnt < MPP_MAX(new_max_cnt, info->dpb_size + 1))
440 new_max_cnt = MPP_MAX(new_max_cnt, info->dpb_size + 1);
441 }
442
443 if (aligned_w > SZ_4K) {
444 /* 480 bytes for each ctu above 3072 */
445 RK_S32 ext_line_buf_size = (aligned_w - 3 * SZ_1K) / 64 * 480;
446
447 if (NULL == ctx->ext_line_buf_grp)
448 mpp_buffer_group_get_internal(&ctx->ext_line_buf_grp, MPP_BUFFER_TYPE_ION);
449 else if (ext_line_buf_size != ctx->ext_line_buf_size) {
450 clear_ext_line_bufs(ctx);
451 mpp_buffer_group_clear(ctx->ext_line_buf_grp);
452 }
453
454 mpp_assert(ctx->ext_line_buf_grp);
455
456 ctx->ext_line_buf_size = ext_line_buf_size;
457 setup_ext_line_bufs(ctx);
458 } else {
459 clear_ext_line_bufs(ctx);
460 if (ctx->ext_line_buf_grp) {
461 mpp_buffer_group_clear(ctx->ext_line_buf_grp);
462 mpp_buffer_group_put(ctx->ext_line_buf_grp);
463 ctx->ext_line_buf_grp = NULL;
464 }
465 ctx->ext_line_buf_size = 0;
466 }
467
468 if ((ctx->pixel_buf_fbc_hdr_size != pixel_buf_fbc_hdr_size) ||
469 (ctx->pixel_buf_fbc_bdy_size != pixel_buf_fbc_bdy_size) ||
470 (ctx->pixel_buf_size != pixel_buf_size) ||
471 (ctx->thumb_buf_size != thumb_buf_size) ||
472 (new_max_cnt > old_max_cnt)) {
473 size_t sizes[2];
474
475 hal_h264e_dbg_detail("frame size %d -> %d max count %d -> %d\n",
476 ctx->pixel_buf_size, pixel_buf_size,
477 old_max_cnt, new_max_cnt);
478
479 /* pixel buffer */
480 sizes[0] = pixel_buf_size;
481 /* thumb buffer */
482 sizes[1] = thumb_buf_size;
483 new_max_cnt = MPP_MAX(new_max_cnt, old_max_cnt);
484
485 hal_bufs_setup(ctx->hw_recn, new_max_cnt, 2, sizes);
486
487 ctx->pixel_buf_fbc_hdr_size = pixel_buf_fbc_hdr_size;
488 ctx->pixel_buf_fbc_bdy_size = pixel_buf_fbc_bdy_size;
489 ctx->pixel_buf_size = pixel_buf_size;
490 ctx->thumb_buf_size = thumb_buf_size;
491 ctx->max_buf_cnt = new_max_cnt;
492 }
493 }
494
hal_h264e_vepu580_prepare(void * hal)495 static MPP_RET hal_h264e_vepu580_prepare(void *hal)
496 {
497 HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
498 MppEncPrepCfg *prep = &ctx->cfg->prep;
499
500 hal_h264e_dbg_func("enter %p\n", hal);
501
502 if (prep->change_res) {
503 RK_S32 i;
504
505 // pre-alloc required buffers to reduce first frame delay
506 setup_hal_bufs(ctx);
507 for (i = 0; i < ctx->max_buf_cnt; i++)
508 hal_bufs_get_buf(ctx->hw_recn, i);
509
510 prep->change_res = 0;
511 }
512
513 hal_h264e_dbg_func("leave %p\n", hal);
514
515 return MPP_OK;
516 }
517
update_vepu580_syntax(HalH264eVepu580Ctx * ctx,MppSyntax * syntax)518 static RK_U32 update_vepu580_syntax(HalH264eVepu580Ctx *ctx, MppSyntax *syntax)
519 {
520 H264eSyntaxDesc *desc = syntax->data;
521 RK_S32 syn_num = syntax->number;
522 RK_U32 updated = 0;
523 RK_S32 i;
524
525 for (i = 0; i < syn_num; i++, desc++) {
526 switch (desc->type) {
527 case H264E_SYN_CFG : {
528 hal_h264e_dbg_detail("update cfg");
529 ctx->cfg = desc->p;
530 } break;
531 case H264E_SYN_SPS : {
532 hal_h264e_dbg_detail("update sps");
533 ctx->sps = desc->p;
534 } break;
535 case H264E_SYN_PPS : {
536 hal_h264e_dbg_detail("update pps");
537 ctx->pps = desc->p;
538 } break;
539 case H264E_SYN_DPB : {
540 hal_h264e_dbg_detail("update dpb");
541 ctx->dpb = desc->p;
542 } break;
543 case H264E_SYN_SLICE : {
544 hal_h264e_dbg_detail("update slice");
545 ctx->slice = desc->p;
546 } break;
547 case H264E_SYN_FRAME : {
548 hal_h264e_dbg_detail("update frames");
549 ctx->frms = desc->p;
550 } break;
551 case H264E_SYN_PREFIX : {
552 hal_h264e_dbg_detail("update prefix nal");
553 ctx->prefix = desc->p;
554 } break;
555 default : {
556 mpp_log_f("invalid syntax type %d\n", desc->type);
557 } break;
558 }
559
560 updated |= SYN_TYPE_FLAG(desc->type);
561 }
562
563 return updated;
564 }
565
hal_h264e_vepu580_get_task(void * hal,HalEncTask * task)566 static MPP_RET hal_h264e_vepu580_get_task(void *hal, HalEncTask *task)
567 {
568 HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
569 MppEncCfgSet *cfg_set = ctx->cfg;
570 MppEncRefCfgImpl *ref = (MppEncRefCfgImpl *)cfg_set->ref_cfg;
571 MppEncH264HwCfg *hw_cfg = &cfg_set->h264.hw_cfg;
572 RK_U32 updated = update_vepu580_syntax(ctx, &task->syntax);
573 EncFrmStatus *frm_status = &task->rc_task->frm;
574 H264eFrmInfo *frms = ctx->frms;
575
576 hal_h264e_dbg_func("enter %p\n", hal);
577
578 if (updated & SYN_TYPE_FLAG(H264E_SYN_CFG))
579 setup_hal_bufs(ctx);
580
581 if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
582 MppMeta meta = mpp_frame_get_meta(task->frame);
583
584 mpp_meta_get_ptr_d(meta, KEY_ROI_DATA2, (void **)&ctx->roi_data, NULL);
585 mpp_meta_get_ptr_d(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data, NULL);
586 mpp_meta_get_ptr_d(meta, KEY_OSD_DATA2, (void **)&ctx->osd_cfg.osd_data2, NULL);
587 }
588
589 if (ctx->dpb) {
590 h264e_dpb_hal_start(ctx->dpb, frms->curr_idx);
591 h264e_dpb_hal_start(ctx->dpb, frms->refr_idx);
592 }
593
594 task->flags.reg_idx = ctx->task_idx;
595 task->flags.curr_idx = frms->curr_idx;
596 task->flags.refr_idx = frms->refr_idx;
597 task->part_first = 1;
598 task->part_last = 0;
599
600 ctx->ext_line_buf = ctx->ext_line_bufs[ctx->task_idx];
601 ctx->regs_set = &ctx->regs_sets[ctx->task_idx];
602 ctx->amend = &ctx->amend_sets[ctx->task_idx];
603 ctx->osd_cfg.reg_base = &ctx->regs_set->reg_osd;
604
605 /* if not VEPU1/2, update log2_max_frame_num_minus4 in hw_cfg */
606 hw_cfg->hw_log2_max_frame_num_minus4 = ctx->sps->log2_max_frame_num_minus4;
607
608 if (ctx->task_cnt > 1 && (ref->lt_cfg_cnt || ref->st_cfg_cnt > 1)) {
609 H264ePrefixNal *prefix = &ctx->prefix_sets[ctx->task_idx];
610 H264eSlice *slice = &ctx->slice_sets[ctx->task_idx];
611
612 //store async encode TSVC info
613 if (ctx->prefix)
614 memcpy(prefix, ctx->prefix, sizeof(H264ePrefixNal));
615 else
616 prefix = NULL;
617
618 if (ctx->slice) {
619 memcpy(slice, ctx->slice, sizeof(H264eSlice));
620
621 /*
622 * Generally, reorder and marking are shared by dpb and slice.
623 * However, async encoding TSVC will change reorder and marking in each task.
624 * Therefore, malloc a special space for async encoding TSVC.
625 */
626 ctx->amend->reorder = ctx->reorder;
627 ctx->amend->marking = ctx->marking;
628 }
629
630 h264e_vepu_stream_amend_config(ctx->amend, task->packet, ctx->cfg,
631 slice, prefix);
632 } else {
633 h264e_vepu_stream_amend_config(ctx->amend, task->packet, ctx->cfg,
634 ctx->slice, ctx->prefix);
635 }
636
637 if (ctx->task_cnt > 1)
638 ctx->task_idx = !ctx->task_idx;
639
640 hal_h264e_dbg_func("leave %p\n", hal);
641
642 return MPP_OK;
643 }
644
setup_vepu580_normal(HalVepu580RegSet * regs)645 static void setup_vepu580_normal(HalVepu580RegSet *regs)
646 {
647 hal_h264e_dbg_func("enter\n");
648
649 /* reg001 ENC_STRT */
650 regs->reg_ctl.enc_strt.lkt_num = 0;
651 regs->reg_ctl.enc_strt.vepu_cmd = 1;
652 regs->reg_ctl.func_en.cke = 1;
653 regs->reg_ctl.func_en.resetn_hw_en = 1;
654 regs->reg_ctl.func_en.enc_done_tmvp_en = 1;
655
656 /* reg002 ENC_CLR */
657 regs->reg_ctl.enc_clr.safe_clr = 0;
658 regs->reg_ctl.enc_clr.force_clr = 0;
659
660 /* reg004 INT_EN */
661 regs->reg_ctl.int_en.enc_done_en = 1;
662 regs->reg_ctl.int_en.lkt_node_done_en = 1;
663 regs->reg_ctl.int_en.sclr_done_en = 1;
664 regs->reg_ctl.int_en.slc_done_en = 0;
665 regs->reg_ctl.int_en.bsf_oflw_en = 1;
666 regs->reg_ctl.int_en.brsp_otsd_en = 1;
667 regs->reg_ctl.int_en.wbus_err_en = 1;
668 regs->reg_ctl.int_en.rbus_err_en = 1;
669 regs->reg_ctl.int_en.wdg_en = 1;
670
671 /* reg005 INT_MSK */
672 regs->reg_ctl.int_msk.enc_done_msk = 0;
673 regs->reg_ctl.int_msk.lkt_node_done_msk = 0;
674 regs->reg_ctl.int_msk.sclr_done_msk = 0;
675 regs->reg_ctl.int_msk.slc_done_msk = 0;
676 regs->reg_ctl.int_msk.bsf_oflw_msk = 0;
677 regs->reg_ctl.int_msk.brsp_otsd_msk = 0;
678 regs->reg_ctl.int_msk.wbus_err_msk = 0;
679 regs->reg_ctl.int_msk.rbus_err_msk = 0;
680 regs->reg_ctl.int_msk.wdg_msk = 0;
681
682 regs->reg_ctl.enc_wdg.vs_load_thd = 0x1fffff;
683 regs->reg_ctl.enc_wdg.rfp_load_thd = 0;
684
685 /* reg015 DTRNS_MAP */
686 regs->reg_ctl.dtrns_map.cmvw_bus_ordr = 0;
687 regs->reg_ctl.dtrns_map.dspw_bus_ordr = 0;
688 regs->reg_ctl.dtrns_map.rfpw_bus_ordr = 0;
689 regs->reg_ctl.dtrns_map.src_bus_edin = 0;
690 regs->reg_ctl.dtrns_map.meiw_bus_edin = 0;
691 regs->reg_ctl.dtrns_map.bsw_bus_edin = 7;
692 regs->reg_ctl.dtrns_map.lktr_bus_edin = 0;
693 regs->reg_ctl.dtrns_map.roir_bus_edin = 0;
694 regs->reg_ctl.dtrns_map.lktw_bus_edin = 0;
695 regs->reg_ctl.dtrns_map.afbc_bsize = 1;
696
697 regs->reg_ctl.dtrns_cfg.axi_brsp_cke = 0;
698 regs->reg_ctl.dtrns_cfg.dspr_otsd = 1;
699 hal_h264e_dbg_func("leave\n");
700 }
701
setup_vepu580_prep(HalVepu580RegSet * regs,MppEncPrepCfg * prep,HalEncTask * task)702 static MPP_RET setup_vepu580_prep(HalVepu580RegSet *regs, MppEncPrepCfg *prep,
703 HalEncTask *task)
704 {
705 VepuFmtCfg cfg;
706 MppFrameFormat fmt = prep->format;
707 MPP_RET ret = vepu5xx_set_fmt(&cfg, fmt);
708 RK_U32 hw_fmt = cfg.format;
709 RK_S32 y_stride;
710 RK_S32 c_stride;
711
712 hal_h264e_dbg_func("enter\n");
713
714 /* do nothing when color format is not supported */
715 if (ret)
716 return ret;
717
718 regs->reg_base.enc_rsl.pic_wd8_m1 = MPP_ALIGN(prep->width, 16) / 8 - 1;
719 regs->reg_base.src_fill.pic_wfill = MPP_ALIGN(prep->width, 16) - prep->width;
720 regs->reg_base.enc_rsl.pic_hd8_m1 = MPP_ALIGN(prep->height, 16) / 8 - 1;
721 regs->reg_base.src_fill.pic_hfill = MPP_ALIGN(prep->height, 16) - prep->height;
722
723 regs->reg_ctl.dtrns_map.src_bus_edin = cfg.src_endian;
724
725 regs->reg_base.src_fmt.src_cfmt = hw_fmt;
726 regs->reg_base.src_fmt.alpha_swap = cfg.alpha_swap;
727 regs->reg_base.src_fmt.rbuv_swap = cfg.rbuv_swap;
728 regs->reg_base.src_fmt.out_fmt = (fmt == MPP_FMT_YUV400) ? 0 : 1;
729
730 if (MPP_FRAME_FMT_IS_YUV(fmt))
731 regs->reg_base.src_fmt.src_range = 1;
732 else
733 regs->reg_base.src_fmt.src_range = (prep->range == MPP_FRAME_RANGE_JPEG) ? 1 : 0;
734
735 if (MPP_FRAME_FMT_IS_FBC(fmt)) {
736 y_stride = mpp_frame_get_fbc_hdr_stride(task->frame);
737 if (!y_stride)
738 y_stride = MPP_ALIGN(prep->width, 16);
739 } else if (prep->hor_stride) {
740 y_stride = prep->hor_stride;
741 } else {
742 if (hw_fmt == VEPU5xx_FMT_BGRA8888 )
743 y_stride = prep->width * 4;
744 else if (hw_fmt == VEPU5xx_FMT_BGR888 )
745 y_stride = prep->width * 3;
746 else if (hw_fmt == VEPU5xx_FMT_BGR565 ||
747 hw_fmt == VEPU5xx_FMT_YUYV422 ||
748 hw_fmt == VEPU5xx_FMT_UYVY422)
749 y_stride = prep->width * 2;
750 else
751 y_stride = prep->width;
752 }
753
754 switch (hw_fmt) {
755 case VEPU5xx_FMT_YUV444SP : {
756 c_stride = y_stride * 2;
757 } break;
758 case VEPU5xx_FMT_YUV422SP :
759 case VEPU5xx_FMT_YUV420SP :
760 case VEPU5xx_FMT_YUV444P : {
761 c_stride = y_stride;
762 } break;
763 default : {
764 c_stride = y_stride / 2;
765 } break;
766 }
767
768 if (hw_fmt < VEPU5xx_FMT_ARGB1555) {
769 const VepuRgb2YuvCfg *cfg_coeffs = get_rgb2yuv_cfg(prep->range, prep->color);
770
771 hal_h264e_dbg_flow("input color range %d colorspace %d", prep->range, prep->color);
772
773 regs->reg_base.src_udfy.csc_wgt_b2y = cfg_coeffs->_2y.b_coeff;
774 regs->reg_base.src_udfy.csc_wgt_g2y = cfg_coeffs->_2y.g_coeff;
775 regs->reg_base.src_udfy.csc_wgt_r2y = cfg_coeffs->_2y.r_coeff;
776
777 regs->reg_base.src_udfu.csc_wgt_b2u = cfg_coeffs->_2u.b_coeff;
778 regs->reg_base.src_udfu.csc_wgt_g2u = cfg_coeffs->_2u.g_coeff;
779 regs->reg_base.src_udfu.csc_wgt_r2u = cfg_coeffs->_2u.r_coeff;
780
781 regs->reg_base.src_udfv.csc_wgt_b2v = cfg_coeffs->_2v.b_coeff;
782 regs->reg_base.src_udfv.csc_wgt_g2v = cfg_coeffs->_2v.g_coeff;
783 regs->reg_base.src_udfv.csc_wgt_r2v = cfg_coeffs->_2v.r_coeff;
784
785 regs->reg_base.src_udfo.csc_ofst_y = cfg_coeffs->_2y.offset;
786 regs->reg_base.src_udfo.csc_ofst_u = cfg_coeffs->_2u.offset;
787 regs->reg_base.src_udfo.csc_ofst_v = cfg_coeffs->_2v.offset;
788
789 hal_h264e_dbg_flow("use color range %d colorspace %d", cfg_coeffs->dst_range, cfg_coeffs->color);
790 } else {
791 regs->reg_base.src_udfy.csc_wgt_b2y = cfg.weight[0];
792 regs->reg_base.src_udfy.csc_wgt_g2y = cfg.weight[1];
793 regs->reg_base.src_udfy.csc_wgt_r2y = cfg.weight[2];
794
795 regs->reg_base.src_udfu.csc_wgt_b2u = cfg.weight[3];
796 regs->reg_base.src_udfu.csc_wgt_g2u = cfg.weight[4];
797 regs->reg_base.src_udfu.csc_wgt_r2u = cfg.weight[5];
798
799 regs->reg_base.src_udfv.csc_wgt_b2v = cfg.weight[6];
800 regs->reg_base.src_udfv.csc_wgt_g2v = cfg.weight[7];
801 regs->reg_base.src_udfv.csc_wgt_r2v = cfg.weight[8];
802
803 regs->reg_base.src_udfo.csc_ofst_y = cfg.offset[0];
804 regs->reg_base.src_udfo.csc_ofst_u = cfg.offset[1];
805 regs->reg_base.src_udfo.csc_ofst_v = cfg.offset[2];
806 }
807
808 regs->reg_base.src_proc.afbcd_en = MPP_FRAME_FMT_IS_FBC(fmt) ? 1 : 0;
809 regs->reg_base.src_strd0.src_strd0 = y_stride;
810 regs->reg_base.src_strd1.src_strd1 = c_stride;
811
812 regs->reg_base.src_proc.src_mirr = prep->mirroring > 0;
813 regs->reg_base.src_proc.src_rot = prep->rotation;
814 regs->reg_base.src_proc.txa_en = 0;
815
816 regs->reg_base.sli_cfg.sli_crs_en = 1;
817
818 regs->reg_base.pic_ofst.pic_ofst_y = 0;
819 regs->reg_base.pic_ofst.pic_ofst_x = 0;
820
821 hal_h264e_dbg_func("leave\n");
822
823 return ret;
824 }
825
vepu580_h264e_save_pass1_patch(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx)826 static MPP_RET vepu580_h264e_save_pass1_patch(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
827 {
828 RK_S32 width_align = MPP_ALIGN(ctx->cfg->prep.width, 64);
829 RK_S32 height_align = MPP_ALIGN(ctx->cfg->prep.height, 16);
830
831 if (NULL == ctx->buf_pass1) {
832 mpp_buffer_get(NULL, &ctx->buf_pass1, width_align * height_align * 3 / 2);
833 if (!ctx->buf_pass1) {
834 mpp_err("buf_pass1 malloc fail, debreath invaild");
835 return MPP_NOK;
836 }
837 }
838
839 regs->reg_base.enc_pic.cur_frm_ref = 1;
840 regs->reg_base.rfpw_h_addr = mpp_buffer_get_fd(ctx->buf_pass1);
841 regs->reg_base.rfpw_b_addr = regs->reg_base.rfpw_h_addr;
842 regs->reg_base.enc_pic.rec_fbc_dis = 1;
843
844 mpp_dev_multi_offset_update(ctx->offsets, 164, width_align * height_align);
845
846 /* NOTE: disable split to avoid lowdelay slice output */
847 regs->reg_base.sli_splt.sli_splt = 0;
848 regs->reg_base.enc_pic.slen_fifo = 0;
849
850 return MPP_OK;
851 }
852
vepu580_h264e_use_pass1_patch(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx)853 static MPP_RET vepu580_h264e_use_pass1_patch(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
854 {
855 MppEncPrepCfg *prep = &ctx->cfg->prep;
856 RK_S32 hor_stride = MPP_ALIGN(prep->width, 64);
857 RK_S32 ver_stride = MPP_ALIGN(prep->height, 16);
858 RK_S32 frame_size = hor_stride * ver_stride;
859 RK_S32 fd_in = mpp_buffer_get_fd(ctx->buf_pass1);
860
861 hal_h264e_dbg_func("enter\n");
862
863 regs->reg_base.src_fmt.src_cfmt = VEPU5xx_FMT_YUV420SP;
864 regs->reg_base.src_fmt.alpha_swap = 0;
865 regs->reg_base.src_fmt.rbuv_swap = 0;
866 regs->reg_base.src_fmt.out_fmt = 1;
867
868 regs->reg_base.src_proc.afbcd_en = 0;
869 regs->reg_base.src_strd0.src_strd0 = hor_stride;
870 regs->reg_base.src_strd1.src_strd1 = hor_stride;
871
872 regs->reg_base.src_proc.src_mirr = 0;
873 regs->reg_base.src_proc.src_rot = 0;
874 regs->reg_base.src_proc.txa_en = 0;
875
876 regs->reg_base.pic_ofst.pic_ofst_y = 0;
877 regs->reg_base.pic_ofst.pic_ofst_x = 0;
878
879
880 regs->reg_base.adr_src0 = fd_in;
881 regs->reg_base.adr_src1 = fd_in;
882 regs->reg_base.adr_src2 = fd_in;
883
884 mpp_dev_multi_offset_update(ctx->offsets, 161, frame_size);
885 mpp_dev_multi_offset_update(ctx->offsets, 162, frame_size);
886
887 hal_h264e_dbg_func("leave\n");
888 return MPP_OK;
889 }
890
setup_vepu580_codec(HalVepu580RegSet * regs,H264eSps * sps,H264ePps * pps,H264eSlice * slice)891 static void setup_vepu580_codec(HalVepu580RegSet *regs, H264eSps *sps,
892 H264ePps *pps, H264eSlice *slice)
893 {
894 hal_h264e_dbg_func("enter\n");
895
896 regs->reg_base.enc_pic.enc_stnd = 0;
897 regs->reg_base.enc_pic.cur_frm_ref = slice->nal_reference_idc > 0;
898 regs->reg_base.enc_pic.bs_scp = 1;
899
900 regs->reg_base.synt_nal.nal_ref_idc = slice->nal_reference_idc;
901 regs->reg_base.synt_nal.nal_unit_type = slice->nalu_type;
902
903 regs->reg_base.synt_sps.max_fnum = sps->log2_max_frame_num_minus4;
904 regs->reg_base.synt_sps.drct_8x8 = sps->direct8x8_inference;
905 regs->reg_base.synt_sps.mpoc_lm4 = sps->log2_max_poc_lsb_minus4;
906
907 regs->reg_base.synt_pps.etpy_mode = pps->entropy_coding_mode;
908 regs->reg_base.synt_pps.trns_8x8 = pps->transform_8x8_mode;
909 regs->reg_base.synt_pps.csip_flag = pps->constrained_intra_pred;
910 regs->reg_base.synt_pps.num_ref0_idx = pps->num_ref_idx_l0_default_active - 1;
911 regs->reg_base.synt_pps.num_ref1_idx = pps->num_ref_idx_l1_default_active - 1;
912 regs->reg_base.synt_pps.pic_init_qp = pps->pic_init_qp;
913 regs->reg_base.synt_pps.cb_ofst = pps->chroma_qp_index_offset;
914 regs->reg_base.synt_pps.cr_ofst = pps->second_chroma_qp_index_offset;
915 regs->reg_base.synt_pps.wght_pred = pps->weighted_pred;
916 regs->reg_base.synt_pps.dbf_cp_flg = pps->deblocking_filter_control;
917
918 regs->reg_base.synt_sli0.sli_type = (slice->slice_type == H264_I_SLICE) ? (2) : (0);
919 regs->reg_base.synt_sli0.pps_id = slice->pic_parameter_set_id;
920 regs->reg_base.synt_sli0.drct_smvp = 0;
921 regs->reg_base.synt_sli0.num_ref_ovrd = slice->num_ref_idx_override;
922 regs->reg_base.synt_sli0.cbc_init_idc = slice->cabac_init_idc;
923 regs->reg_base.synt_sli0.frm_num = slice->frame_num;
924
925 regs->reg_base.synt_sli1.idr_pid = (slice->slice_type == H264_I_SLICE) ? slice->idr_pic_id : (RK_U32)(-1);
926 regs->reg_base.synt_sli1.poc_lsb = slice->pic_order_cnt_lsb;
927
928
929 regs->reg_base.synt_sli2.dis_dblk_idc = slice->disable_deblocking_filter_idc;
930 regs->reg_base.synt_sli2.sli_alph_ofst = slice->slice_alpha_c0_offset_div2;
931
932 h264e_reorder_rd_rewind(slice->reorder);
933 { /* reorder process */
934 H264eRplmo rplmo;
935 MPP_RET ret = h264e_reorder_rd_op(slice->reorder, &rplmo);
936
937 if (MPP_OK == ret) {
938 regs->reg_base.synt_sli2.ref_list0_rodr = 1;
939 regs->reg_base.synt_sli2.rodr_pic_idx = rplmo.modification_of_pic_nums_idc;
940
941 switch (rplmo.modification_of_pic_nums_idc) {
942 case 0 :
943 case 1 : {
944 regs->reg_base.synt_sli2.rodr_pic_num = rplmo.abs_diff_pic_num_minus1;
945 } break;
946 case 2 : {
947 regs->reg_base.synt_sli2.rodr_pic_num = rplmo.long_term_pic_idx;
948 } break;
949 default : {
950 mpp_err_f("invalid modification_of_pic_nums_idc %d\n",
951 rplmo.modification_of_pic_nums_idc);
952 } break;
953 }
954 } else {
955 // slice->ref_pic_list_modification_flag;
956 regs->reg_base.synt_sli2.ref_list0_rodr = 0;
957 regs->reg_base.synt_sli2.rodr_pic_idx = 0;
958 regs->reg_base.synt_sli2.rodr_pic_num = 0;
959 }
960 }
961
962 /* clear all mmco arg first */
963 regs->reg_base.synt_refm0.nopp_flg = 0;
964 regs->reg_base.synt_refm0.ltrf_flg = 0;
965 regs->reg_base.synt_refm0.arpm_flg = 0;
966 regs->reg_base.synt_refm0.mmco4_pre = 0;
967 regs->reg_base.synt_refm0.mmco_type0 = 0;
968 regs->reg_base.synt_refm0.mmco_parm0 = 0;
969 regs->reg_base.synt_refm0.mmco_type1 = 0;
970 regs->reg_base.synt_refm1.mmco_parm1 = 0;
971 regs->reg_base.synt_refm0.mmco_type2 = 0;
972 regs->reg_base.synt_refm1.mmco_parm2 = 0;
973 regs->reg_base.synt_refm2.long_term_frame_idx0 = 0;
974 regs->reg_base.synt_refm2.long_term_frame_idx1 = 0;
975 regs->reg_base.synt_refm2.long_term_frame_idx2 = 0;
976
977 h264e_marking_rd_rewind(slice->marking);
978
979 /* only update used parameter */
980 if (slice->slice_type == H264_I_SLICE) {
981 regs->reg_base.synt_refm0.nopp_flg = slice->no_output_of_prior_pics;
982 regs->reg_base.synt_refm0.ltrf_flg = slice->long_term_reference_flag;
983 } else {
984 if (!h264e_marking_is_empty(slice->marking)) {
985 H264eMmco mmco;
986
987 regs->reg_base.synt_refm0.arpm_flg = 1;
988
989 /* max 3 mmco */
990 do {
991 RK_S32 type = 0;
992 RK_S32 param_0 = 0;
993 RK_S32 param_1 = 0;
994
995 h264e_marking_rd_op(slice->marking, &mmco);
996 type = mmco.mmco;
997 switch (type) {
998 case 1 : {
999 param_0 = mmco.difference_of_pic_nums_minus1;
1000 } break;
1001 case 2 : {
1002 param_0 = mmco.long_term_pic_num;
1003 } break;
1004 case 3 : {
1005 param_0 = mmco.difference_of_pic_nums_minus1;
1006 param_1 = mmco.long_term_frame_idx;
1007 } break;
1008 case 4 : {
1009 param_0 = mmco.max_long_term_frame_idx_plus1;
1010 } break;
1011 case 5 : {
1012 } break;
1013 case 6 : {
1014 param_0 = mmco.long_term_frame_idx;
1015 } break;
1016 default : {
1017 mpp_err_f("unsupported mmco 0 %d\n", type);
1018 type = 0;
1019 } break;
1020 }
1021
1022 regs->reg_base.synt_refm0.mmco_type0 = type;
1023 regs->reg_base.synt_refm0.mmco_parm0 = param_0;
1024 regs->reg_base.synt_refm2.long_term_frame_idx0 = param_1;
1025
1026 if (h264e_marking_is_empty(slice->marking))
1027 break;
1028
1029 h264e_marking_rd_op(slice->marking, &mmco);
1030 type = mmco.mmco;
1031 param_0 = 0;
1032 param_1 = 0;
1033 switch (type) {
1034 case 1 : {
1035 param_0 = mmco.difference_of_pic_nums_minus1;
1036 } break;
1037 case 2 : {
1038 param_0 = mmco.long_term_pic_num;
1039 } break;
1040 case 3 : {
1041 param_0 = mmco.difference_of_pic_nums_minus1;
1042 param_1 = mmco.long_term_frame_idx;
1043 } break;
1044 case 4 : {
1045 param_0 = mmco.max_long_term_frame_idx_plus1;
1046 } break;
1047 case 5 : {
1048 } break;
1049 case 6 : {
1050 param_0 = mmco.long_term_frame_idx;
1051 } break;
1052 default : {
1053 mpp_err_f("unsupported mmco 0 %d\n", type);
1054 type = 0;
1055 } break;
1056 }
1057
1058 regs->reg_base.synt_refm0.mmco_type1 = type;
1059 regs->reg_base.synt_refm1.mmco_parm1 = param_0;
1060 regs->reg_base.synt_refm2.long_term_frame_idx1 = param_1;
1061
1062 if (h264e_marking_is_empty(slice->marking))
1063 break;
1064
1065 h264e_marking_rd_op(slice->marking, &mmco);
1066 type = mmco.mmco;
1067 param_0 = 0;
1068 param_1 = 0;
1069 switch (type) {
1070 case 1 : {
1071 param_0 = mmco.difference_of_pic_nums_minus1;
1072 } break;
1073 case 2 : {
1074 param_0 = mmco.long_term_pic_num;
1075 } break;
1076 case 3 : {
1077 param_0 = mmco.difference_of_pic_nums_minus1;
1078 param_1 = mmco.long_term_frame_idx;
1079 } break;
1080 case 4 : {
1081 param_0 = mmco.max_long_term_frame_idx_plus1;
1082 } break;
1083 case 5 : {
1084 } break;
1085 case 6 : {
1086 param_0 = mmco.long_term_frame_idx;
1087 } break;
1088 default : {
1089 mpp_err_f("unsupported mmco 0 %d\n", type);
1090 type = 0;
1091 } break;
1092 }
1093
1094 regs->reg_base.synt_refm0.mmco_type2 = type;
1095 regs->reg_base.synt_refm1.mmco_parm2 = param_0;
1096 regs->reg_base.synt_refm2.long_term_frame_idx2 = param_1;
1097 } while (0);
1098 }
1099 }
1100
1101 hal_h264e_dbg_func("leave\n");
1102 }
1103
setup_vepu580_rdo_pred(HalVepu580RegSet * regs,H264eSps * sps,H264ePps * pps,H264eSlice * slice)1104 static void setup_vepu580_rdo_pred(HalVepu580RegSet *regs, H264eSps *sps,
1105 H264ePps *pps, H264eSlice *slice)
1106 {
1107 hal_h264e_dbg_func("enter\n");
1108
1109 if (slice->slice_type == H264_I_SLICE) {
1110 regs->reg_rc_klut.klut_ofst.chrm_klut_ofst = 0;
1111 memcpy(®s->reg_rc_klut.klut_wgt0, &h264e_klut_weight[0], CHROMA_KLUT_TAB_SIZE);
1112 } else {
1113 regs->reg_rc_klut.klut_ofst.chrm_klut_ofst = 3;
1114 memcpy(®s->reg_rc_klut.klut_wgt0, &h264e_klut_weight[4], CHROMA_KLUT_TAB_SIZE);
1115 }
1116
1117 regs->reg_base.iprd_csts.vthd_y = 9;
1118 regs->reg_base.iprd_csts.vthd_c = 63;
1119
1120 regs->reg_base.rdo_cfg.rect_size = (sps->profile_idc == H264_PROFILE_BASELINE &&
1121 sps->level_idc <= H264_LEVEL_3_0) ? 1 : 0;
1122 regs->reg_base.rdo_cfg.inter_4x4 = 1;
1123 regs->reg_base.rdo_cfg.vlc_lmt = (sps->profile_idc < H264_PROFILE_MAIN) &&
1124 !pps->entropy_coding_mode;
1125 regs->reg_base.rdo_cfg.chrm_spcl = 1;
1126 regs->reg_base.rdo_cfg.rdo_mask = 0;
1127 regs->reg_base.rdo_cfg.ccwa_e = 1;
1128 regs->reg_base.rdo_cfg.scl_lst_sel = pps->pic_scaling_matrix_present;
1129 regs->reg_base.rdo_cfg.atr_e = 1;
1130 regs->reg_base.rdo_cfg.atf_intra_e = 1;
1131
1132 hal_h264e_dbg_func("leave\n");
1133 }
1134
setup_vepu580_rdo_bias_cfg(Vepu580RdoCfg * regs,MppEncHwCfg * hw)1135 static void setup_vepu580_rdo_bias_cfg(Vepu580RdoCfg *regs, MppEncHwCfg *hw)
1136 {
1137 RK_U8 bias = h264_mode_bias[hw->mode_bias[1]];
1138
1139 regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt00 = bias > 24 ? bias : 24;
1140 regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt01 = bias > 22 ? bias : 22;
1141 regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt02 = bias > 21 ? bias : 21;
1142 regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt10 = bias > 22 ? bias : 22;
1143 regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt11 = bias > 21 ? bias : 21;
1144 regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt12 = bias > 20 ? bias : 20;
1145 regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt20 = bias > 20 ? bias : 20;
1146 regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt21 = bias > 19 ? bias : 19;
1147 regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt22 = bias > 18 ? bias : 18;
1148 regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt30 = bias;
1149 regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt31 = bias;
1150 regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt32 = bias;
1151
1152 if (hw->skip_bias_en) {
1153 bias = hw->skip_bias;
1154
1155 regs->rdo_skip_cime_thd0.atf_rdo_skip_cime_thd0 = hw->skip_sad < 10 ? hw->skip_sad : 10;
1156 regs->rdo_skip_cime_thd0.atf_rdo_skip_cime_thd1 = hw->skip_sad < 8 ? hw->skip_sad : 8;
1157 regs->rdo_skip_cime_thd1.atf_rdo_skip_cime_thd2 = hw->skip_sad < 15 ? hw->skip_sad : 15;
1158 regs->rdo_skip_cime_thd1.atf_rdo_skip_cime_thd3 = hw->skip_sad;
1159 regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt00 = bias > 20 ? bias : 20;
1160 regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt10 = bias;
1161 regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt11 = bias;
1162 regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt12 = bias;
1163 regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt20 = bias;
1164 regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt21 = bias;
1165 regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt22 = bias;
1166 regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt30 = bias;
1167 regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt31 = bias;
1168 regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt32 = bias;
1169 regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt40 = bias;
1170 regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt41 = bias;
1171 regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt42 = bias;
1172 }
1173 }
1174
setup_vepu580_rdo_cfg(Vepu580RdoCfg * regs)1175 static void setup_vepu580_rdo_cfg(Vepu580RdoCfg *regs)
1176 {
1177 hal_h264e_dbg_func("enter\n");
1178
1179 /* 0x2000 */
1180 regs->rdo_sqi_cfg.atf_pskip_en = 1;
1181
1182 /* 0x20CC ~ 0x20D0 */
1183 regs->rdo_intra_cime_thd0.atf_rdo_intra_cime_thd0 = 28;
1184 regs->rdo_intra_cime_thd0.atf_rdo_intra_cime_thd1 = 44;
1185 regs->rdo_intra_cime_thd1.atf_rdo_intra_cime_thd2 = 72;
1186
1187 /* 0x20D4 ~ 0x20E0 */
1188 regs->rdo_intra_var_thd0.atf_rdo_intra_var_thd00 = 25;
1189 regs->rdo_intra_var_thd0.atf_rdo_intra_var_thd01 = 64;
1190 regs->rdo_intra_var_thd1.atf_rdo_intra_var_thd10 = 25;
1191 regs->rdo_intra_var_thd1.atf_rdo_intra_var_thd11 = 64;
1192 regs->rdo_intra_var_thd2.atf_rdo_intra_var_thd20 = 70;
1193 regs->rdo_intra_var_thd2.atf_rdo_intra_var_thd21 = 100;
1194 regs->rdo_intra_var_thd3.atf_rdo_intra_var_thd30 = 70;
1195 regs->rdo_intra_var_thd3.atf_rdo_intra_var_thd31 = 100;
1196
1197 /* 0x20E4 ~ 0x20F0 */
1198 regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt00 = 24;
1199 regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt01 = 22;
1200 regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt02 = 21;
1201 regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt10 = 22;
1202 regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt11 = 21;
1203 regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt12 = 20;
1204 regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt20 = 20;
1205 regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt21 = 19;
1206 regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt22 = 18;
1207 regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt30 = 16;
1208 regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt31 = 16;
1209 regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt32 = 16;
1210
1211 /* 0x211C ~ 0x2130 */
1212 regs->rdo_skip_cime_thd0.atf_rdo_skip_cime_thd0 = 10;
1213 regs->rdo_skip_cime_thd0.atf_rdo_skip_cime_thd1 = 8;
1214 regs->rdo_skip_cime_thd1.atf_rdo_skip_cime_thd2 = 15;
1215 regs->rdo_skip_cime_thd1.atf_rdo_skip_cime_thd3 = 25;
1216 regs->rdo_skip_var_thd0.atf_rdo_skip_var_thd10 = 25;
1217 regs->rdo_skip_var_thd0.atf_rdo_skip_var_thd11 = 40;
1218 regs->rdo_skip_var_thd1.atf_rdo_skip_var_thd20 = 25;
1219 regs->rdo_skip_var_thd1.atf_rdo_skip_var_thd21 = 40;
1220 regs->rdo_skip_var_thd2.atf_rdo_skip_var_thd30 = 70;
1221 regs->rdo_skip_var_thd2.atf_rdo_skip_var_thd31 = 100;
1222 regs->rdo_skip_var_thd3.atf_rdo_skip_var_thd40 = 70;
1223 regs->rdo_skip_var_thd3.atf_rdo_skip_var_thd41 = 100;
1224
1225 /* 0x2134 ~ 0x2140 */
1226 regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt00 = 20;
1227 regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt10 = 16;
1228 regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt11 = 16;
1229 regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt12 = 16;
1230 regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt20 = 16;
1231 regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt21 = 16;
1232 regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt22 = 16;
1233 regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt30 = 16;
1234 regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt31 = 16;
1235 regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt32 = 16;
1236 regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt40 = 16;
1237 regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt41 = 16;
1238 regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt42 = 16;
1239
1240 hal_h264e_dbg_func("leave\n");
1241 }
1242
setup_vepu580_rc_base(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx,EncRcTask * rc_task)1243 static void setup_vepu580_rc_base(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx, EncRcTask *rc_task)
1244 {
1245 EncRcTaskInfo *rc_info = &rc_task->info;
1246 H264eSlice *slice = ctx->slice;
1247 MppEncCfgSet *cfg = ctx->cfg;
1248 MppEncHwCfg *hw = &cfg->hw;
1249 H264eSps *sps = ctx->sps;
1250 MppEncRcCfg *rc = &cfg->rc;
1251 RK_S32 mb_w = sps->pic_width_in_mbs;
1252 RK_S32 mb_h = sps->pic_height_in_mbs;
1253 RK_U32 qp_target = rc_info->quality_target;
1254 RK_U32 qp_min = rc_info->quality_min;
1255 RK_U32 qp_max = rc_info->quality_max;
1256 RK_U32 qpmap_mode = 1;
1257 RK_S32 mb_target_bits_mul_16 = (rc_info->bit_target << 4) / (mb_w * mb_h);
1258 RK_S32 mb_target_bits;
1259 RK_S32 negative_bits_thd;
1260 RK_S32 positive_bits_thd;
1261
1262 hal_h264e_dbg_rc("bittarget %d qp [%d %d %d]\n", rc_info->bit_target,
1263 qp_min, qp_target, qp_max);
1264
1265 hal_h264e_dbg_func("enter\n");
1266
1267 regs->reg_rc_klut.roi_qthd0.qpmin_area0 = qp_min;
1268 regs->reg_rc_klut.roi_qthd0.qpmax_area0 = qp_max;
1269 regs->reg_rc_klut.roi_qthd0.qpmin_area1 = qp_min;
1270 regs->reg_rc_klut.roi_qthd0.qpmax_area1 = qp_max;
1271 regs->reg_rc_klut.roi_qthd0.qpmin_area2 = qp_min;
1272
1273 regs->reg_rc_klut.roi_qthd1.qpmax_area2 = qp_max;
1274 regs->reg_rc_klut.roi_qthd1.qpmin_area3 = qp_min;
1275 regs->reg_rc_klut.roi_qthd1.qpmax_area3 = qp_max;
1276 regs->reg_rc_klut.roi_qthd1.qpmin_area4 = qp_min;
1277 regs->reg_rc_klut.roi_qthd1.qpmax_area4 = qp_max;
1278
1279 regs->reg_rc_klut.roi_qthd2.qpmin_area5 = qp_min;
1280 regs->reg_rc_klut.roi_qthd2.qpmax_area5 = qp_max;
1281 regs->reg_rc_klut.roi_qthd2.qpmin_area6 = qp_min;
1282 regs->reg_rc_klut.roi_qthd2.qpmax_area6 = qp_max;
1283 regs->reg_rc_klut.roi_qthd2.qpmin_area7 = qp_min;
1284
1285 regs->reg_rc_klut.roi_qthd3.qpmax_area7 = qp_max;
1286 regs->reg_rc_klut.roi_qthd3.qpmap_mode = qpmap_mode;
1287
1288 if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
1289 regs->reg_base.enc_pic.pic_qp = qp_target;
1290 regs->reg_base.rc_qp.rc_max_qp = qp_target;
1291 regs->reg_base.rc_qp.rc_min_qp = qp_target;
1292
1293 return;
1294 }
1295
1296 if (mb_target_bits_mul_16 >= 0x100000)
1297 mb_target_bits_mul_16 = 0x50000;
1298
1299 mb_target_bits = (mb_target_bits_mul_16 * mb_w) >> 4;
1300 negative_bits_thd = 0 - 5 * mb_target_bits / 16;
1301 positive_bits_thd = 5 * mb_target_bits / 16;
1302
1303 regs->reg_base.enc_pic.pic_qp = qp_target;
1304 regs->reg_base.rc_cfg.rc_en = 1;
1305 regs->reg_base.rc_cfg.aq_en = 1;
1306 regs->reg_base.rc_cfg.aq_mode = 0;
1307 regs->reg_base.rc_cfg.rc_ctu_num = mb_w;
1308 regs->reg_base.rc_qp.rc_qp_range = (slice->slice_type == H264_I_SLICE) ?
1309 hw->qp_delta_row_i : hw->qp_delta_row;
1310 regs->reg_base.rc_qp.rc_max_qp = qp_max;
1311 regs->reg_base.rc_qp.rc_min_qp = qp_min;
1312 regs->reg_base.rc_tgt.ctu_ebit = mb_target_bits_mul_16;
1313
1314 regs->reg_rc_klut.rc_adj0.qp_adj0 = -2;
1315 regs->reg_rc_klut.rc_adj0.qp_adj1 = -1;
1316 regs->reg_rc_klut.rc_adj0.qp_adj2 = 0;
1317 regs->reg_rc_klut.rc_adj0.qp_adj3 = 1;
1318 regs->reg_rc_klut.rc_adj0.qp_adj4 = 2;
1319 regs->reg_rc_klut.rc_adj1.qp_adj5 = 0;
1320 regs->reg_rc_klut.rc_adj1.qp_adj6 = 0;
1321 regs->reg_rc_klut.rc_adj1.qp_adj7 = 0;
1322 regs->reg_rc_klut.rc_adj1.qp_adj8 = 1;
1323
1324 regs->reg_rc_klut.rc_dthd_0_8[0] = 4 * negative_bits_thd;
1325 regs->reg_rc_klut.rc_dthd_0_8[1] = negative_bits_thd;
1326 regs->reg_rc_klut.rc_dthd_0_8[2] = positive_bits_thd;
1327 regs->reg_rc_klut.rc_dthd_0_8[3] = 4 * positive_bits_thd;
1328 regs->reg_rc_klut.rc_dthd_0_8[4] = 0x7FFFFFFF;
1329 regs->reg_rc_klut.rc_dthd_0_8[5] = 0x7FFFFFFF;
1330 regs->reg_rc_klut.rc_dthd_0_8[6] = 0x7FFFFFFF;
1331 regs->reg_rc_klut.rc_dthd_0_8[7] = 0x7FFFFFFF;
1332 regs->reg_rc_klut.rc_dthd_0_8[8] = 0x7FFFFFFF;
1333
1334 {
1335 /* 0x1070 ~ 0x1074 */
1336 regs->reg_rc_klut.md_sad_thd.md_sad_thd0 = 4;
1337 regs->reg_rc_klut.md_sad_thd.md_sad_thd1 = 9;
1338 regs->reg_rc_klut.md_sad_thd.md_sad_thd2 = 15;
1339
1340 regs->reg_rc_klut.madi_thd.madi_thd0 = 4;
1341 regs->reg_rc_klut.madi_thd.madi_thd1 = 9;
1342 regs->reg_rc_klut.madi_thd.madi_thd2 = 15;
1343 }
1344
1345 if (cfg->rc.rc_mode == MPP_ENC_RC_MODE_SMTRC) {
1346 regs->reg_base.rc_qp.rc_qp_range = 0;
1347 }
1348
1349 hal_h264e_dbg_func("leave\n");
1350 }
1351
setup_vepu580_io_buf(HalVepu580RegSet * regs,MppDevRegOffCfgs * offsets,HalEncTask * task)1352 static void setup_vepu580_io_buf(HalVepu580RegSet *regs, MppDevRegOffCfgs *offsets,
1353 HalEncTask *task)
1354 {
1355 MppFrame frm = task->frame;
1356 MppPacket pkt = task->packet;
1357 MppBuffer buf_in = mpp_frame_get_buffer(frm);
1358 MppBuffer buf_out = task->output;
1359 MppFrameFormat fmt = mpp_frame_get_fmt(frm);
1360 RK_S32 hor_stride = mpp_frame_get_hor_stride(frm);
1361 RK_S32 ver_stride = mpp_frame_get_ver_stride(frm);
1362 RK_S32 fd_in = mpp_buffer_get_fd(buf_in);
1363 RK_U32 off_in[2] = {0};
1364 RK_U32 off_out = mpp_packet_get_length(pkt);
1365 size_t siz_out = mpp_buffer_get_size(buf_out);
1366 RK_S32 fd_out = mpp_buffer_get_fd(buf_out);
1367
1368 hal_h264e_dbg_func("enter\n");
1369
1370 regs->reg_base.adr_src0 = fd_in;
1371 regs->reg_base.adr_src1 = fd_in;
1372 regs->reg_base.adr_src2 = fd_in;
1373
1374 regs->reg_base.bsbb_addr = fd_out;
1375 regs->reg_base.bsbr_addr = fd_out;
1376 regs->reg_base.adr_bsbs = fd_out;
1377 regs->reg_base.bsbt_addr = fd_out;
1378
1379 if (MPP_FRAME_FMT_IS_FBC(fmt)) {
1380 off_in[0] = mpp_frame_get_fbc_offset(frm);;
1381 off_in[1] = 0;
1382 } else if (MPP_FRAME_FMT_IS_YUV(fmt)) {
1383 VepuFmtCfg cfg;
1384
1385 vepu5xx_set_fmt(&cfg, fmt);
1386 switch (cfg.format) {
1387 case VEPU5xx_FMT_BGRA8888 :
1388 case VEPU5xx_FMT_BGR888 :
1389 case VEPU5xx_FMT_BGR565 : {
1390 off_in[0] = 0;
1391 off_in[1] = 0;
1392 } break;
1393 case VEPU5xx_FMT_YUV420SP :
1394 case VEPU5xx_FMT_YUV422SP : {
1395 off_in[0] = hor_stride * ver_stride;
1396 off_in[1] = hor_stride * ver_stride;
1397 } break;
1398 case VEPU5xx_FMT_YUV422P : {
1399 off_in[0] = hor_stride * ver_stride;
1400 off_in[1] = hor_stride * ver_stride * 3 / 2;
1401 } break;
1402 case VEPU5xx_FMT_YUV420P : {
1403 off_in[0] = hor_stride * ver_stride;
1404 off_in[1] = hor_stride * ver_stride * 5 / 4;
1405 } break;
1406 case VEPU5xx_FMT_YUV400 :
1407 case VEPU5xx_FMT_YUYV422 :
1408 case VEPU5xx_FMT_UYVY422 : {
1409 off_in[0] = 0;
1410 off_in[1] = 0;
1411 } break;
1412 case VEPU5xx_FMT_YUV444SP : {
1413 off_in[0] = hor_stride * ver_stride;
1414 off_in[1] = hor_stride * ver_stride;
1415 } break;
1416 case VEPU5xx_FMT_YUV444P : {
1417 off_in[0] = hor_stride * ver_stride;
1418 off_in[1] = hor_stride * ver_stride * 2;
1419 } break;
1420 default : {
1421 off_in[0] = 0;
1422 off_in[1] = 0;
1423 } break;
1424 }
1425 }
1426
1427 mpp_dev_multi_offset_update(offsets, 161, off_in[0]);
1428 mpp_dev_multi_offset_update(offsets, 162, off_in[1]);
1429 mpp_dev_multi_offset_update(offsets, 172, siz_out);
1430 mpp_dev_multi_offset_update(offsets, 175, off_out);
1431
1432 hal_h264e_dbg_func("leave\n");
1433 }
1434
vepu580_h264_set_one_roi(void * buf,MppEncROIRegion * region,RK_S32 w,RK_S32 h)1435 static MPP_RET vepu580_h264_set_one_roi(void *buf, MppEncROIRegion *region, RK_S32 w, RK_S32 h)
1436 {
1437 Vepu580RoiH264BsCfg *ptr = (Vepu580RoiH264BsCfg *)buf;
1438 RK_S32 mb_w = MPP_ALIGN(w, 16) / 16;
1439 RK_S32 mb_h = MPP_ALIGN(h, 16) / 16;
1440 RK_S32 stride_h = MPP_ALIGN(mb_w, 4);
1441 Vepu580RoiH264BsCfg cfg;
1442 MPP_RET ret = MPP_NOK;
1443
1444 if (NULL == buf || NULL == region) {
1445 mpp_err_f("invalid buf %p roi %p\n", buf, region);
1446 goto DONE;
1447 }
1448
1449 RK_S32 roi_width = (region->w + 15) / 16;
1450 RK_S32 roi_height = (region->h + 15) / 16;
1451 RK_S32 pos_x_init = region->x / 16;
1452 RK_S32 pos_y_init = region->y / 16;
1453 RK_S32 pos_x_end = pos_x_init + roi_width;
1454 RK_S32 pos_y_end = pos_y_init + roi_height;
1455 RK_S32 x, y;
1456
1457 pos_x_end = MPP_MIN(pos_x_end, mb_w);
1458 pos_y_end = MPP_MIN(pos_y_end, mb_h);
1459 pos_x_init = MPP_MAX(pos_x_init, 0);
1460 pos_y_init = MPP_MAX(pos_y_init, 0);
1461
1462 mpp_assert(pos_x_end > pos_x_init);
1463 mpp_assert(pos_y_end > pos_y_init);
1464
1465 cfg.force_intra = 1;
1466
1467 ptr += pos_y_init * stride_h + pos_x_init;
1468 roi_width = pos_x_end - pos_x_init;
1469 roi_height = pos_y_end - pos_y_init;
1470
1471 for (y = 0; y < roi_height; y++) {
1472 Vepu580RoiH264BsCfg *dst = ptr;
1473
1474 for (x = 0; x < roi_width; x++, dst++)
1475 memcpy(dst, &cfg, sizeof(cfg));
1476
1477 ptr += stride_h;
1478 }
1479 DONE:
1480 return ret;
1481 }
1482
setup_vepu580_intra_refresh(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx,RK_U32 refresh_idx)1483 static MPP_RET setup_vepu580_intra_refresh(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx, RK_U32 refresh_idx)
1484 {
1485 MPP_RET ret = MPP_OK;
1486 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
1487 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
1488 RK_U32 w = mb_w * 16;
1489 RK_U32 h = mb_h * 16;
1490 MppEncROIRegion *region = NULL;
1491 RK_U32 refresh_num = ctx->cfg->rc.refresh_num;
1492 RK_U32 stride_h = MPP_ALIGN(mb_w, 4);
1493 RK_U32 stride_v = MPP_ALIGN(mb_h, 4);
1494 RK_S32 roi_base_buf_size = stride_h * stride_v * 8;
1495 RK_U32 i = 0;
1496
1497 hal_h264e_dbg_func("enter\n");
1498
1499 if (!ctx->cfg->rc.refresh_en) {
1500 ret = MPP_ERR_VALUE;
1501 goto RET;
1502 }
1503
1504 if (ctx->roi_base_buf_size < roi_base_buf_size) {
1505 if (NULL == ctx->roi_grp)
1506 mpp_buffer_group_get_internal(&ctx->roi_grp, MPP_BUFFER_TYPE_ION);
1507 if (ctx->roi_base_cfg_buf)
1508 mpp_buffer_put(ctx->roi_base_cfg_buf);
1509 mpp_buffer_get(ctx->roi_grp, &ctx->roi_base_cfg_buf, roi_base_buf_size);
1510 ctx->roi_base_buf_size = roi_base_buf_size;
1511 }
1512
1513 mpp_assert(ctx->roi_base_cfg_buf);
1514 RK_S32 base_cfg_fd = mpp_buffer_get_fd(ctx->roi_base_cfg_buf);
1515 void *base_cfg_buf = mpp_buffer_get_ptr(ctx->roi_base_cfg_buf);
1516 Vepu580RoiH264BsCfg base_cfg;
1517 Vepu580RoiH264BsCfg *base_cfg_ptr = (Vepu580RoiH264BsCfg *)base_cfg_buf;
1518
1519 base_cfg.force_intra = 0;
1520 base_cfg.qp_adj_en = 1;
1521
1522 for (i = 0; i < stride_h * stride_v; i++, base_cfg_ptr++)
1523 memcpy(base_cfg_ptr, &base_cfg, sizeof(base_cfg));
1524
1525 region = mpp_calloc(MppEncROIRegion, 1);
1526
1527 if (NULL == region) {
1528 mpp_err_f("Failed to calloc for MppEncROIRegion !\n");
1529 ret = MPP_ERR_MALLOC;
1530 }
1531
1532 if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_ROW) {
1533 region->x = 0;
1534 region->w = w;
1535 if (refresh_idx > 0) {
1536 region->y = refresh_idx * 16 * refresh_num - 32;
1537 region->h = 16 * refresh_num + 32;
1538 } else {
1539 region->y = refresh_idx * 16 * refresh_num;
1540 region->h = 16 * refresh_num;
1541 }
1542 regs->reg_base.me_rnge.cme_srch_v = 1;
1543 } else if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_COL) {
1544 region->y = 0;
1545 region->h = h;
1546 if (refresh_idx > 0) {
1547 region->x = refresh_idx * 16 * refresh_num - 32;
1548 region->w = 16 * refresh_num + 32;
1549 } else {
1550 region->x = refresh_idx * 16 * refresh_num;
1551 region->w = 16 * refresh_num;
1552 }
1553 regs->reg_base.me_rnge.cme_srch_h = 1;
1554 }
1555
1556 region->intra = 1;
1557 region->quality = -ctx->cfg->rc.qp_delta_ip;
1558
1559 region->area_map_en = 1;
1560 region->qp_area_idx = 1;
1561 region->abs_qp_en = 0;
1562
1563 regs->reg_base.enc_pic.roi_en = 1;
1564 regs->reg_base.roi_addr = base_cfg_fd;
1565 vepu580_h264_set_one_roi(base_cfg_buf, region, w, h);
1566 mpp_free(region);
1567 mpp_buffer_sync_end(ctx->roi_base_cfg_buf);
1568
1569 RET:
1570 hal_h264e_dbg_func("leave, ret %d\n", ret);
1571 return ret;
1572 }
1573
setup_vepu580_roi(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx)1574 static void setup_vepu580_roi(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
1575 {
1576 hal_h264e_dbg_func("enter\n");
1577
1578 /* memset register on start so do not clear registers again here */
1579 if (ctx->roi_data) {
1580 /* roi setup */
1581 RK_U32 mb_w = MPP_ALIGN(ctx->cfg->prep.width, 64) / 16;
1582 RK_U32 mb_h = MPP_ALIGN(ctx->cfg->prep.height, 64) / 16;
1583 RK_U32 base_cfg_size = mb_w * mb_h * 8;
1584 RK_U32 qp_cfg_size = mb_w * mb_h * 2;
1585 RK_U32 amv_cfg_size = mb_w * mb_h / 4;
1586 RK_U32 mv_cfg_size = mb_w * mb_h * 96 / 4;
1587 MppEncROICfg2 *cfg = (MppEncROICfg2 *)ctx->roi_data;
1588
1589 if (mpp_buffer_get_size(cfg->base_cfg_buf) >= base_cfg_size) {
1590 regs->reg_base.enc_pic.roi_en = 1;
1591 regs->reg_base.roi_addr = mpp_buffer_get_fd(cfg->base_cfg_buf);
1592 } else {
1593 mpp_err("roi base cfg buf not enough, roi is invalid");
1594 }
1595
1596 if (cfg->roi_qp_en) {
1597 if (mpp_buffer_get_size(cfg->qp_cfg_buf) >= qp_cfg_size) {
1598 regs->reg_base.roi_qp_addr = mpp_buffer_get_fd(cfg->qp_cfg_buf);
1599 regs->reg_base.roi_en.roi_qp_en = 1;
1600 } else {
1601 mpp_err("roi qp cfg buf not enough, roi is invalid");
1602 }
1603 }
1604
1605 if (cfg->roi_amv_en) {
1606 if (mpp_buffer_get_size(cfg->amv_cfg_buf) >= amv_cfg_size) {
1607 regs->reg_base.qoi_amv_addr = mpp_buffer_get_fd(cfg->amv_cfg_buf);
1608 regs->reg_base.roi_en.roi_amv_en = 1;
1609 } else {
1610 mpp_err("roi amv cfg buf not enough, roi is invalid");
1611 }
1612 }
1613
1614 if (cfg->roi_mv_en) {
1615 if (mpp_buffer_get_size(cfg->mv_cfg_buf) >= mv_cfg_size) {
1616 regs->reg_base.qoi_mv_addr = mpp_buffer_get_fd(cfg->mv_cfg_buf);
1617 regs->reg_base.roi_en.roi_mv_en = 1;
1618 } else {
1619 mpp_err("roi mv cfg buf not enough, roi is invalid");
1620 }
1621 }
1622 }
1623
1624 hal_h264e_dbg_func("leave\n");
1625 }
1626
setup_vepu580_recn_refr(HalH264eVepu580Ctx * ctx,HalVepu580RegSet * regs)1627 static void setup_vepu580_recn_refr(HalH264eVepu580Ctx *ctx, HalVepu580RegSet *regs)
1628 {
1629 H264eFrmInfo *frms = ctx->frms;
1630 HalBufs bufs = ctx->hw_recn;
1631 RK_S32 fbc_hdr_size = ctx->pixel_buf_fbc_hdr_size;
1632
1633 HalBuf *curr = hal_bufs_get_buf(bufs, frms->curr_idx);
1634 HalBuf *refr = hal_bufs_get_buf(bufs, frms->refr_idx);
1635
1636 hal_h264e_dbg_func("enter\n");
1637
1638 if (curr && curr->cnt) {
1639 MppBuffer buf_pixel = curr->buf[0];
1640 MppBuffer buf_thumb = curr->buf[1];
1641 RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1642
1643 mpp_assert(buf_pixel);
1644 mpp_assert(buf_thumb);
1645
1646 regs->reg_base.rfpw_h_addr = fd;
1647 regs->reg_base.rfpw_b_addr = fd;
1648 regs->reg_base.dspw_addr = mpp_buffer_get_fd(buf_thumb);
1649 }
1650
1651 if (refr && refr->cnt) {
1652 MppBuffer buf_pixel = refr->buf[0];
1653 MppBuffer buf_thumb = refr->buf[1];
1654 RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1655
1656 mpp_assert(buf_pixel);
1657 mpp_assert(buf_thumb);
1658
1659 regs->reg_base.rfpr_h_addr = fd;
1660 regs->reg_base.rfpr_b_addr = fd;
1661 regs->reg_base.dspr_addr = mpp_buffer_get_fd(buf_thumb);
1662 }
1663
1664 mpp_dev_multi_offset_update(ctx->offsets, 164, fbc_hdr_size);
1665 mpp_dev_multi_offset_update(ctx->offsets, 166, fbc_hdr_size);
1666
1667 hal_h264e_dbg_func("leave\n");
1668 }
1669
setup_vepu580_split(HalVepu580RegSet * regs,MppEncCfgSet * enc_cfg)1670 static void setup_vepu580_split(HalVepu580RegSet *regs, MppEncCfgSet *enc_cfg)
1671 {
1672 MppEncSliceSplit *cfg = &enc_cfg->split;
1673
1674 hal_h264e_dbg_func("enter\n");
1675
1676 switch (cfg->split_mode) {
1677 case MPP_ENC_SPLIT_NONE : {
1678 regs->reg_base.sli_splt.sli_splt = 0;
1679 regs->reg_base.sli_splt.sli_splt_mode = 0;
1680 regs->reg_base.sli_splt.sli_splt_cpst = 0;
1681 regs->reg_base.sli_splt.sli_max_num_m1 = 0;
1682 regs->reg_base.sli_splt.sli_flsh = 0;
1683 regs->reg_base.sli_cnum.sli_splt_cnum_m1 = 0;
1684
1685 regs->reg_base.sli_byte.sli_splt_byte = 0;
1686 regs->reg_base.enc_pic.slen_fifo = 0;
1687 } break;
1688 case MPP_ENC_SPLIT_BY_BYTE : {
1689 regs->reg_base.sli_splt.sli_splt = 1;
1690 regs->reg_base.sli_splt.sli_splt_mode = 0;
1691 regs->reg_base.sli_splt.sli_splt_cpst = 0;
1692 regs->reg_base.sli_splt.sli_max_num_m1 = 500;
1693 regs->reg_base.sli_splt.sli_flsh = 1;
1694 regs->reg_base.sli_cnum.sli_splt_cnum_m1 = 0;
1695
1696 regs->reg_base.sli_byte.sli_splt_byte = cfg->split_arg;
1697 regs->reg_base.enc_pic.slen_fifo = cfg->split_out ? 1 : 0;
1698 regs->reg_ctl.int_en.slc_done_en = regs->reg_base.enc_pic.slen_fifo;
1699 } break;
1700 case MPP_ENC_SPLIT_BY_CTU : {
1701 RK_U32 mb_w = MPP_ALIGN(enc_cfg->prep.width, 16) / 16;
1702 RK_U32 mb_h = MPP_ALIGN(enc_cfg->prep.height, 16) / 16;
1703 RK_U32 slice_num = (mb_w * mb_h + cfg->split_arg - 1) / cfg->split_arg;
1704
1705 regs->reg_base.sli_splt.sli_splt = 1;
1706 regs->reg_base.sli_splt.sli_splt_mode = 1;
1707 regs->reg_base.sli_splt.sli_splt_cpst = 0;
1708 regs->reg_base.sli_splt.sli_max_num_m1 = 500;
1709 regs->reg_base.sli_splt.sli_flsh = 1;
1710 regs->reg_base.sli_cnum.sli_splt_cnum_m1 = cfg->split_arg - 1;
1711
1712 regs->reg_base.sli_byte.sli_splt_byte = 0;
1713 regs->reg_base.enc_pic.slen_fifo = cfg->split_out ? 1 : 0;
1714
1715 if ((cfg->split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) ||
1716 (regs->reg_base.enc_pic.slen_fifo && (slice_num > VEPU580_SLICE_FIFO_LEN)))
1717 regs->reg_ctl.int_en.slc_done_en = 1;
1718
1719 } break;
1720 default : {
1721 mpp_log_f("invalide slice split mode %d\n", cfg->split_mode);
1722 } break;
1723 }
1724
1725 hal_h264e_dbg_func("leave\n");
1726 }
1727
calc_cime_parameter(HalVepu580RegSet * regs,H264eSps * sps)1728 static void calc_cime_parameter(HalVepu580RegSet *regs, H264eSps *sps)
1729 {
1730 Vepu580BaseCfg *base_regs = ®s->reg_base;
1731 RK_S32 x_gmv = base_regs->gmv.gmv_x;
1732 RK_S32 y_gmv = base_regs->gmv.gmv_y;
1733 RK_S32 srch_w = base_regs->me_rnge.cme_srch_h * 4;
1734 RK_S32 srch_h = base_regs->me_rnge.cme_srch_v * 4;
1735 RK_S32 frm_sta = 0, frm_end = 0, pic_w = 0;
1736 RK_S32 pic_wd64 = MPP_ALIGN(sps->pic_width_in_mbs * 16, 64) / 64;
1737
1738 // calc cime_linebuf_w
1739 {
1740 if (x_gmv - srch_w < 0) {
1741 frm_sta = (x_gmv - srch_w - 15) / 16;
1742 } else {
1743 frm_sta = (x_gmv - srch_w) / 16;
1744 }
1745 frm_sta = mpp_clip(frm_sta, 0, pic_wd64 - 1);
1746
1747 if (x_gmv + srch_w < 0) {
1748 frm_end = pic_wd64 - 1 + (x_gmv + srch_w) / 16;
1749 } else {
1750 frm_end = pic_wd64 - 1 + (x_gmv + srch_w + 15) / 16;
1751 }
1752 frm_end = mpp_clip(frm_end, 0, pic_wd64 - 1);
1753
1754 pic_w = (frm_end - frm_sta + 1) * 64;
1755 base_regs->me_cach.cme_linebuf_w = (pic_w ? pic_w : 64) / 64;
1756 }
1757
1758 // calc cime_cacha_h and cime_cacha_max
1759 {
1760 RK_U32 cime_cacha_max = 2464;
1761 RK_U32 ctu_4_h = 1, ramb_h;
1762 RK_U32 cur_srch_16_w, cur_srch_4_h, cur_srch_max;
1763 RK_U32 cime_cacha_h = ctu_4_h;
1764
1765 if ((x_gmv % 16 - srch_w % 16) < 0) {
1766 cur_srch_16_w = (16 + (x_gmv % 16 - srch_w % 16) % 16 + srch_w * 2 + 15) / 16 + 1;
1767 } else {
1768 cur_srch_16_w = ((x_gmv % 16 - srch_w % 16) % 16 + srch_w * 2 + 15) / 16 + 1;
1769 }
1770
1771 if ((y_gmv % 4 - srch_h % 4) < 0) {
1772 cur_srch_4_h = (4 + (y_gmv % 4 - srch_h % 4) % 4 + srch_h * 2 + 3) / 4 + ctu_4_h;
1773 } else {
1774 cur_srch_4_h = ((y_gmv % 4 - srch_h % 4) % 4 + srch_h * 2 + 3) / 4 + ctu_4_h;
1775 }
1776
1777 cur_srch_max = cur_srch_4_h;
1778
1779 if (base_regs->me_cach.cme_linebuf_w < cur_srch_16_w) {
1780 cur_srch_16_w = base_regs->me_cach.cme_linebuf_w;
1781 }
1782
1783 ramb_h = cur_srch_4_h;
1784 while ((cime_cacha_h < cur_srch_max) && (cime_cacha_max >
1785 ((cime_cacha_h - ctu_4_h) * base_regs->me_cach.cme_linebuf_w * 4 + (ramb_h * 4 * cur_srch_16_w)))) {
1786 cime_cacha_h = cime_cacha_h + ctu_4_h;
1787
1788 if (ramb_h > 2 * ctu_4_h) {
1789 ramb_h = ramb_h - ctu_4_h;
1790 } else {
1791 ramb_h = ctu_4_h;
1792 }
1793 }
1794
1795 if (cur_srch_4_h == ctu_4_h) {
1796 cime_cacha_h = cime_cacha_h + ctu_4_h;
1797 ramb_h = 0;
1798 }
1799
1800 if (cime_cacha_max < ((cime_cacha_h - ctu_4_h) * base_regs->me_cach.cme_linebuf_w * 4 + (ramb_h * 4 * cur_srch_16_w))) {
1801 cime_cacha_h = cime_cacha_h - ctu_4_h;
1802 }
1803 base_regs->me_cach.cme_rama_h = cime_cacha_h;
1804
1805 /* cime_cacha_max */
1806 {
1807 RK_U32 ram_col_h = (cime_cacha_h - ctu_4_h) / ctu_4_h;
1808 base_regs->me_cach.cme_rama_max = ram_col_h * base_regs->me_cach.cme_linebuf_w + cur_srch_16_w;
1809 }
1810 }
1811 }
1812
setup_vepu580_me(HalVepu580RegSet * regs,H264eSps * sps,H264eSlice * slice)1813 static void setup_vepu580_me(HalVepu580RegSet *regs, H264eSps *sps,
1814 H264eSlice *slice)
1815 {
1816 RK_S32 level_idc = sps->level_idc;
1817 RK_S32 cime_w = 176;
1818 RK_S32 cime_h = 112;
1819 RK_S32 cime_blk_w_max = 44;
1820 RK_S32 cime_blk_h_max = 28;
1821
1822 hal_h264e_dbg_func("enter\n");
1823 /*
1824 * Step 1. limit the mv range by level_idc
1825 * For level 1 and level 1b the vertical MV range is [-64,+63.75]
1826 * For level 1.1, 1.2, 1.3 and 2 the vertical MV range is [-128,+127.75]
1827 */
1828 switch (level_idc) {
1829 case H264_LEVEL_1_0 :
1830 case H264_LEVEL_1_b : {
1831 cime_blk_h_max = 12;
1832 } break;
1833 case H264_LEVEL_1_1 :
1834 case H264_LEVEL_1_2 :
1835 case H264_LEVEL_1_3 :
1836 case H264_LEVEL_2_0 : {
1837 cime_blk_h_max = 28;
1838 } break;
1839 default : {
1840 cime_blk_h_max = 28;
1841 } break;
1842 }
1843
1844 if (cime_w < cime_blk_w_max * 4)
1845 cime_blk_w_max = cime_w / 4;
1846
1847 if (cime_h < cime_blk_h_max * 4)
1848 cime_blk_h_max = cime_h / 4;
1849
1850 /*
1851 * Step 2. limit the mv range by image size
1852 */
1853 if (cime_blk_w_max / 4 * 2 > (sps->pic_width_in_mbs * 2 + 1) / 2)
1854 cime_blk_w_max = (sps->pic_width_in_mbs * 2 + 1) / 2 / 2 * 4;
1855
1856 if (cime_blk_h_max / 4 > MPP_ALIGN(sps->pic_height_in_mbs * 16, 64) / 128 * 4)
1857 cime_blk_h_max = MPP_ALIGN(sps->pic_height_in_mbs * 16, 64) / 128 * 16;
1858
1859 regs->reg_base.me_rnge.cme_srch_h = cime_blk_w_max / 4;
1860 regs->reg_base.me_rnge.cme_srch_v = cime_blk_h_max / 4;
1861 regs->reg_base.me_rnge.rme_srch_h = 7;
1862 regs->reg_base.me_rnge.rme_srch_v = 5;
1863 regs->reg_base.me_rnge.dlt_frm_num = 0;
1864
1865 if (slice->slice_type == H264_I_SLICE) {
1866 regs->reg_base.me_cfg.pmv_mdst_h = 0;
1867 regs->reg_base.me_cfg.pmv_mdst_v = 0;
1868 } else {
1869 regs->reg_base.me_cfg.pmv_mdst_h = 5;
1870 regs->reg_base.me_cfg.pmv_mdst_v = 5;
1871 }
1872 regs->reg_base.me_cfg.mv_limit = (sps->level_idc > 20) ? 2 : ((sps->level_idc >= 11) ? 1 : 0);//2;
1873 regs->reg_base.me_cfg.pmv_num = 2;
1874 regs->reg_base.me_cfg.rme_dis = 0;
1875 regs->reg_base.me_cfg.fme_dis = 0;
1876 regs->reg_base.me_cfg.lvl4_ovrd_en = 0;
1877
1878 calc_cime_parameter(regs, sps);
1879
1880 hal_h264e_dbg_func("leave\n");
1881 }
1882
1883 #define H264E_LAMBDA_TAB_SIZE (52 * sizeof(RK_U32))
1884
1885 static RK_U32 h264e_lambda_default[58] = {
1886 0x00000003, 0x00000005, 0x00000006, 0x00000007,
1887 0x00000009, 0x0000000b, 0x0000000e, 0x00000012,
1888 0x00000016, 0x0000001c, 0x00000024, 0x0000002d,
1889 0x00000039, 0x00000048, 0x0000005b, 0x00000073,
1890 0x00000091, 0x000000b6, 0x000000e6, 0x00000122,
1891 0x0000016d, 0x000001cc, 0x00000244, 0x000002db,
1892 0x00000399, 0x00000489, 0x000005b6, 0x00000733,
1893 0x00000912, 0x00000b6d, 0x00000e66, 0x00001224,
1894 0x000016db, 0x00001ccc, 0x00002449, 0x00002db7,
1895 0x00003999, 0x00004892, 0x00005b6f, 0x00007333,
1896 0x00009124, 0x0000b6de, 0x0000e666, 0x00012249,
1897 0x00016dbc, 0x0001cccc, 0x00024492, 0x0002db79,
1898 0x00039999, 0x00048924, 0x0005b6f2, 0x00073333,
1899 0x00091249, 0x000b6de5, 0x000e6666, 0x00122492,
1900 0x0016dbcb, 0x001ccccc,
1901 };
1902
setup_vepu580_l2(HalVepu580RegSet * regs,H264eSlice * slice,MppEncHwCfg * hw)1903 static void setup_vepu580_l2(HalVepu580RegSet *regs, H264eSlice *slice, MppEncHwCfg *hw)
1904 {
1905 RK_U32 i;
1906
1907 hal_h264e_dbg_func("enter\n");
1908
1909 regs->reg_s3.iprd_wgt_qp_hevc_0_51[0] = 0;
1910 /* ~ */
1911 regs->reg_s3.iprd_wgt_qp_hevc_0_51[51] = 0;
1912
1913 if (slice->slice_type == H264_I_SLICE) {
1914 memcpy(regs->reg_s3.rdo_wgta_qp_grpa_0_51, &h264e_lambda_default[6], H264E_LAMBDA_TAB_SIZE);
1915 } else {
1916 memcpy(regs->reg_s3.rdo_wgta_qp_grpa_0_51, &h264e_lambda_default[6], H264E_LAMBDA_TAB_SIZE);
1917 }
1918 memset(regs->reg_s3.iprd_wgt_qp_hevc_0_51, 0, H264E_LAMBDA_TAB_SIZE);
1919
1920 regs->reg_rc_klut.madi_cfg.madi_mode = 0;
1921 regs->reg_rc_klut.madi_cfg.madi_thd = 25;
1922
1923 regs->reg_s3.lvl32_intra_CST_THD0.lvl4_intra_cst_thd0 = 1;
1924 regs->reg_s3.lvl32_intra_CST_THD0.lvl4_intra_cst_thd1 = 4;
1925 regs->reg_s3.lvl32_intra_CST_THD1.lvl4_intra_cst_thd2 = 9;
1926 regs->reg_s3.lvl32_intra_CST_THD1.lvl4_intra_cst_thd3 = 36;
1927
1928 regs->reg_s3.lvl16_intra_CST_THD0.lvl8_intra_chrm_cst_thd0 = 1;
1929 regs->reg_s3.lvl16_intra_CST_THD0.lvl8_intra_chrm_cst_thd1 = 4;
1930 regs->reg_s3.lvl16_intra_CST_THD1.lvl8_intra_chrm_cst_thd2 = 9;
1931 regs->reg_s3.lvl16_intra_CST_THD1.lvl8_intra_chrm_cst_thd3 = 36;
1932
1933 regs->reg_s3.lvl8_intra_CST_THD0.lvl8_intra_cst_thd0 = 1;
1934 regs->reg_s3.lvl8_intra_CST_THD0.lvl8_intra_cst_thd1 = 4;
1935 regs->reg_s3.lvl8_intra_CST_THD1.lvl8_intra_cst_thd2 = 9;
1936 regs->reg_s3.lvl8_intra_CST_THD1.lvl8_intra_cst_thd3 = 36;
1937
1938 regs->reg_s3.lvl16_intra_UL_CST_THD.lvl16_intra_ul_cst_thld = 0;
1939 regs->reg_s3.lvl32_intra_CST_WGT0.lvl8_intra_cst_wgt0 = 48;
1940 regs->reg_s3.lvl32_intra_CST_WGT0.lvl8_intra_cst_wgt1 = 60;
1941 regs->reg_s3.lvl32_intra_CST_WGT0.lvl8_intra_cst_wgt2 = 40;
1942 regs->reg_s3.lvl32_intra_CST_WGT0.lvl8_intra_cst_wgt3 = 48;
1943
1944 regs->reg_s3.lvl32_intra_CST_WGT1.lvl4_intra_cst_wgt0 = 48;
1945 regs->reg_s3.lvl32_intra_CST_WGT1.lvl4_intra_cst_wgt1 = 60;
1946 regs->reg_s3.lvl32_intra_CST_WGT1.lvl4_intra_cst_wgt2 = 40;
1947 regs->reg_s3.lvl32_intra_CST_WGT1.lvl4_intra_cst_wgt3 = 48;
1948
1949 regs->reg_s3.lvl16_intra_CST_WGT0.lvl16_intra_cst_wgt0 = 48;
1950 regs->reg_s3.lvl16_intra_CST_WGT0.lvl16_intra_cst_wgt1 = 60;
1951 regs->reg_s3.lvl16_intra_CST_WGT0.lvl16_intra_cst_wgt2 = 40;
1952 regs->reg_s3.lvl16_intra_CST_WGT0.lvl16_intra_cst_wgt3 = 48;
1953 /* 0x1728 */
1954 regs->reg_s3.lvl16_intra_CST_WGT1.lvl8_intra_chrm_cst_wgt0 = 36;
1955 regs->reg_s3.lvl16_intra_CST_WGT1.lvl8_intra_chrm_cst_wgt1 = 42;
1956 regs->reg_s3.lvl16_intra_CST_WGT1.lvl8_intra_chrm_cst_wgt2 = 28;
1957 regs->reg_s3.lvl16_intra_CST_WGT1.lvl8_intra_chrm_cst_wgt3 = 32;
1958
1959 regs->reg_s3.RDO_QUANT.quant_f_bias_P = 171;
1960
1961 if (slice->slice_type == H264_I_SLICE) {
1962 regs->reg_s3.RDO_QUANT.quant_f_bias_I = 683;
1963 regs->reg_s3.ATR_THD0.atr_thd0 = 1;
1964 regs->reg_s3.ATR_THD0.atr_thd1 = 4;
1965 regs->reg_s3.ATR_THD1.atr_thd2 = 36;
1966 } else {
1967 regs->reg_s3.RDO_QUANT.quant_f_bias_I = 583;
1968 regs->reg_s3.ATR_THD0.atr_thd0 = 4;
1969 regs->reg_s3.ATR_THD0.atr_thd1 = 16;
1970 regs->reg_s3.ATR_THD1.atr_thd2 = 81;
1971 }
1972 regs->reg_s3.ATR_THD1.atr_thdqp = 45;
1973
1974 if (slice->slice_type == H264_I_SLICE) {
1975 regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt0 = 16;
1976 regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt1 = 16;
1977 regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt2 = 16;
1978
1979 regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt0 = 22;
1980 regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt1 = 21;
1981 regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt2 = 20;
1982
1983 regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt0 = 20;
1984 regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt1 = 18;
1985 regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt2 = 16;
1986 } else {
1987 regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt0 = 25;
1988 regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt1 = 20;
1989 regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt2 = 16;
1990
1991 regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt0 = 25;
1992 regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt1 = 20;
1993 regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt2 = 18;
1994
1995 regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt0 = 25;
1996 regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt1 = 20;
1997 regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt2 = 16;
1998 }
1999 /* CIME */
2000 {
2001 /* 0x1760 */
2002 regs->reg_s3.cime_sqi_cfg.cime_sad_mod_sel = 0;
2003 regs->reg_s3.cime_sqi_cfg.cime_sad_use_big_block = 1;
2004 regs->reg_s3.cime_sqi_cfg.cime_pmv_set_zero = 1;
2005 regs->reg_s3.cime_sqi_cfg.cime_pmv_num = 3;
2006
2007 /* 0x1764 */
2008 regs->reg_s3.cime_sqi_thd.cime_mvd_th0 = 32;
2009 regs->reg_s3.cime_sqi_thd.cime_mvd_th1 = 80;
2010 regs->reg_s3.cime_sqi_thd.cime_mvd_th2 = 128;
2011
2012 /* 0x1768 */
2013 regs->reg_s3.cime_sqi_multi0.cime_multi0 = 4;
2014 regs->reg_s3.cime_sqi_multi0.cime_multi1 = 8;
2015 regs->reg_s3.cime_sqi_multi1.cime_multi2 = 24;
2016 regs->reg_s3.cime_sqi_multi1.cime_multi3 = 24;
2017 }
2018
2019 /* RIME && FME */
2020 {
2021 /* 0x1770 */
2022 regs->reg_s3.rime_sqi_thd.cime_sad_th0 = 50;
2023 regs->reg_s3.rime_sqi_thd.rime_mvd_th0 = 3;
2024 regs->reg_s3.rime_sqi_thd.rime_mvd_th1 = 8;
2025 regs->reg_s3.rime_sqi_multi.rime_multi0 = 4;
2026 regs->reg_s3.rime_sqi_multi.rime_multi1 = 32;
2027 regs->reg_s3.rime_sqi_multi.rime_multi2 = 128;
2028
2029 /* 0x1778 */
2030 regs->reg_s3.fme_sqi_thd0.cime_sad_pu16_th = 2;
2031
2032 /* 0x177C */
2033 regs->reg_s3.fme_sqi_thd1.move_lambda = 1;
2034 }
2035
2036 if (slice->slice_type == H264_I_SLICE) {
2037 for (i = 0; i < MPP_ARRAY_ELEMS(h264_aq_tthd_default); i++) {
2038 regs->reg_rc_klut.aq_tthd[i] = hw->aq_thrd_i[i];
2039 regs->reg_rc_klut.aq_step[i] = hw->aq_step_i[i] & 0x3f;
2040 }
2041 } else {
2042 for (i = 0; i < MPP_ARRAY_ELEMS(h264_P_aq_step_default); i++) {
2043 regs->reg_rc_klut.aq_tthd[i] = hw->aq_thrd_p[i];
2044 regs->reg_rc_klut.aq_step[i] = hw->aq_step_p[i] & 0x3f;
2045 }
2046 }
2047
2048 hal_h264e_dbg_func("leave\n");
2049 }
2050
setup_vepu580_ext_line_buf(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx)2051 static void setup_vepu580_ext_line_buf(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
2052 {
2053 RK_S32 offset = 0;
2054 RK_S32 fd;
2055
2056 if (!ctx->ext_line_buf) {
2057 regs->reg_base.ebufb_addr = 0;
2058 regs->reg_base.ebufb_addr = 0;
2059 return;
2060 }
2061
2062 fd = mpp_buffer_get_fd(ctx->ext_line_buf);
2063 offset = ctx->ext_line_buf_size;
2064
2065 regs->reg_base.ebuft_addr = fd;
2066 regs->reg_base.ebufb_addr = fd;
2067
2068 mpp_dev_multi_offset_update(ctx->offsets, 182, offset);
2069
2070 /* rcb info for sram */
2071 if (!disable_rcb_buf) {
2072 MppDevRcbInfoCfg rcb_cfg;
2073
2074 rcb_cfg.reg_idx = 183;
2075 rcb_cfg.size = offset;
2076
2077 mpp_dev_ioctl(ctx->dev, MPP_DEV_RCB_INFO, &rcb_cfg);
2078
2079 rcb_cfg.reg_idx = 182;
2080 rcb_cfg.size = 0;
2081
2082 mpp_dev_ioctl(ctx->dev, MPP_DEV_RCB_INFO, &rcb_cfg);
2083 }
2084 }
2085
setup_vepu580_dual_core(HalH264eVepu580Ctx * ctx,H264SliceType slice_type)2086 static MPP_RET setup_vepu580_dual_core(HalH264eVepu580Ctx *ctx, H264SliceType slice_type)
2087 {
2088 Vepu580BaseCfg *reg_base = &ctx->regs_set->reg_base;
2089 RK_U32 dchs_ofst = 9;
2090 RK_U32 dchs_rxe = 1;
2091
2092 if (ctx->task_cnt == 1)
2093 return MPP_OK;
2094
2095 if (slice_type == H264_I_SLICE) {
2096 ctx->curr_idx = 0;
2097 ctx->prev_idx = 0;
2098 dchs_rxe = 0;
2099 }
2100
2101 reg_base->dual_core.dchs_txid = ctx->curr_idx;
2102 reg_base->dual_core.dchs_rxid = ctx->prev_idx;
2103 reg_base->dual_core.dchs_txe = 1;
2104 reg_base->dual_core.dchs_rxe = dchs_rxe;
2105 reg_base->dual_core.dchs_ofst = dchs_ofst;
2106
2107 ctx->prev_idx = ctx->curr_idx++;
2108 if (ctx->curr_idx > 3)
2109 ctx->curr_idx = 0;
2110
2111 return MPP_OK;
2112 }
2113
hal_h264e_vepu580_gen_regs(void * hal,HalEncTask * task)2114 static MPP_RET hal_h264e_vepu580_gen_regs(void *hal, HalEncTask *task)
2115 {
2116 HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
2117 HalVepu580RegSet *regs = ctx->regs_set;
2118 MppEncCfgSet *cfg = ctx->cfg;
2119 H264eSps *sps = ctx->sps;
2120 H264ePps *pps = ctx->pps;
2121 H264eSlice *slice = ctx->slice;
2122 EncRcTask *rc_task = task->rc_task;
2123 EncFrmStatus *frm = &rc_task->frm;
2124 MPP_RET ret = MPP_OK;
2125 EncFrmStatus *frm_status = &task->rc_task->frm;
2126
2127 hal_h264e_dbg_func("enter %p\n", hal);
2128 hal_h264e_dbg_detail("frame %d generate regs now", ctx->frms->seq_idx);
2129
2130 /* register setup */
2131 memset(regs, 0, sizeof(*regs));
2132
2133 setup_vepu580_normal(regs);
2134 ret = setup_vepu580_prep(regs, &ctx->cfg->prep, task);
2135 if (ret)
2136 return ret;
2137
2138 setup_vepu580_dual_core(ctx, slice->slice_type);
2139 setup_vepu580_codec(regs, sps, pps, slice);
2140 setup_vepu580_rdo_pred(regs, sps, pps, slice);
2141 setup_vepu580_rdo_cfg(®s->reg_rdo);
2142 setup_vepu580_rdo_bias_cfg(®s->reg_rdo, &cfg->hw);
2143
2144 // scl cfg
2145 memcpy(®s->reg_scl, vepu580_540_h264_flat_scl_tab, sizeof(vepu580_540_h264_flat_scl_tab));
2146
2147 setup_vepu580_rc_base(regs, ctx, rc_task);
2148 setup_vepu580_io_buf(regs, ctx->offsets, task);
2149 setup_vepu580_roi(regs, ctx);
2150 setup_vepu580_recn_refr(ctx, regs);
2151
2152 regs->reg_base.meiw_addr = task->md_info ? mpp_buffer_get_fd(task->md_info) : 0;
2153 regs->reg_base.enc_pic.mei_stor = task->md_info ? 1 : 0;
2154 regs->reg_base.pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
2155 regs->reg_base.pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
2156
2157 setup_vepu580_split(regs, cfg);
2158 setup_vepu580_me(regs, sps, slice);
2159
2160 if (frm_status->is_i_refresh)
2161 setup_vepu580_intra_refresh(regs, ctx, frm_status->seq_idx % cfg->rc.gop);
2162
2163 if (cfg->tune.deblur_en && (!rc_task->info.complex_scene) &&
2164 cfg->rc.rc_mode == MPP_ENC_RC_MODE_SMTRC &&
2165 cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC) {
2166 if (MPP_OK != setup_vepu580_qpmap_buf(ctx))
2167 mpp_err("qpmap malloc buffer failed!\n");
2168 }
2169
2170 vepu580_set_osd(&ctx->osd_cfg);
2171 setup_vepu580_l2(regs, slice, &cfg->hw);
2172 setup_vepu580_ext_line_buf(regs, ctx);
2173 vepu580_h264e_tune_reg_patch(ctx->tune);
2174
2175 /* two pass register patch */
2176 if (frm->save_pass1)
2177 vepu580_h264e_save_pass1_patch(regs, ctx);
2178
2179 if (frm->use_pass1)
2180 vepu580_h264e_use_pass1_patch(regs, ctx);
2181
2182 ctx->frame_cnt++;
2183
2184 hal_h264e_dbg_func("leave %p\n", hal);
2185 return MPP_OK;
2186 }
2187
hal_h264e_vepu580_start(void * hal,HalEncTask * task)2188 static MPP_RET hal_h264e_vepu580_start(void *hal, HalEncTask *task)
2189 {
2190 MPP_RET ret = MPP_OK;
2191 HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
2192 HalVepu580RegSet *regs = ctx->regs_set;
2193
2194 (void) task;
2195
2196 hal_h264e_dbg_func("enter %p\n", hal);
2197
2198 do {
2199 MppDevRegWrCfg wr_cfg;
2200 MppDevRegRdCfg rd_cfg;
2201
2202 wr_cfg.reg = ®s->reg_ctl;
2203 wr_cfg.size = sizeof(regs->reg_ctl);
2204 wr_cfg.offset = VEPU580_CONTROL_CFG_OFFSET;
2205 #if DUMP_REG
2206 {
2207 RK_U32 i;
2208 RK_U32 *reg = (RK_U32)wr_cfg.reg;
2209 for ( i = 0; i < sizeof(regs->reg_ctl) / sizeof(RK_U32); i++) {
2210 /* code */
2211 mpp_log("reg[%d] = 0x%08x\n", i, reg[i]);
2212 }
2213
2214 }
2215 #endif
2216 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2217 if (ret) {
2218 mpp_err_f("set register write failed %d\n", ret);
2219 break;
2220 }
2221 wr_cfg.reg = ®s->reg_base;
2222 wr_cfg.size = sizeof(regs->reg_base);
2223 wr_cfg.offset = VEPU580_BASE_CFG_OFFSET;
2224
2225 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2226 if (ret) {
2227 mpp_err_f("set register write failed %d\n", ret);
2228 break;
2229 }
2230 wr_cfg.reg = ®s->reg_rc_klut;
2231 wr_cfg.size = sizeof(regs->reg_rc_klut);
2232 wr_cfg.offset = VEPU580_RC_KLUT_CFG_OFFSET;
2233
2234 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2235 if (ret) {
2236 mpp_err_f("set register write failed %d\n", ret);
2237 break;
2238 }
2239 wr_cfg.reg = ®s->reg_s3;
2240 wr_cfg.size = sizeof(regs->reg_s3);
2241 wr_cfg.offset = VEPU580_SECTION_3_OFFSET;
2242
2243 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2244 if (ret) {
2245 mpp_err_f("set register write failed %d\n", ret);
2246 break;
2247 }
2248 wr_cfg.reg = ®s->reg_rdo;
2249 wr_cfg.size = sizeof(regs->reg_rdo);
2250 wr_cfg.offset = VEPU580_RDO_CFG_OFFSET;
2251
2252 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2253 if (ret) {
2254 mpp_err_f("set register write failed %d\n", ret);
2255 break;
2256 }
2257
2258 wr_cfg.reg = ®s->reg_scl;
2259 wr_cfg.size = sizeof(regs->reg_scl);
2260 wr_cfg.offset = VEPU580_SCL_CFG_OFFSET;
2261
2262 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2263 if (ret) {
2264 mpp_err_f("set register write failed %d\n", ret);
2265 break;
2266 }
2267
2268 wr_cfg.reg = ®s->reg_osd;
2269 wr_cfg.size = sizeof(regs->reg_osd);
2270 wr_cfg.offset = VEPU580_OSD_OFFSET;
2271
2272 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2273 if (ret) {
2274 mpp_err_f("set register write failed %d\n", ret);
2275 break;
2276 }
2277
2278 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFS, ctx->offsets);
2279 if (ret) {
2280 mpp_err_f("set register offsets failed %d\n", ret);
2281 break;
2282 }
2283
2284 rd_cfg.reg = ®s->reg_ctl.int_sta;
2285 rd_cfg.size = sizeof(RK_U32);
2286 rd_cfg.offset = VEPU580_REG_BASE_HW_STATUS;
2287
2288 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
2289 if (ret) {
2290 mpp_err_f("set register read failed %d\n", ret);
2291 break;
2292 }
2293
2294 rd_cfg.reg = ®s->reg_st;
2295 rd_cfg.size = sizeof(regs->reg_st);
2296 rd_cfg.offset = VEPU580_STATUS_OFFSET;
2297
2298 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
2299 if (ret) {
2300 mpp_err_f("set register read failed %d\n", ret);
2301 break;
2302 }
2303
2304 /* send request to hardware */
2305 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
2306 if (ret) {
2307 mpp_err_f("send cmd failed %d\n", ret);
2308 break;
2309 }
2310 } while (0);
2311
2312 hal_h264e_dbg_func("leave %p\n", hal);
2313
2314 return ret;
2315 }
2316
hal_h264e_vepu580_status_check(HalVepu580RegSet * regs)2317 static MPP_RET hal_h264e_vepu580_status_check(HalVepu580RegSet *regs)
2318 {
2319 MPP_RET ret = MPP_OK;
2320
2321 if (regs->reg_ctl.int_sta.lkt_node_done_sta)
2322 hal_h264e_dbg_detail("lkt_done finish");
2323
2324 if (regs->reg_ctl.int_sta.enc_done_sta)
2325 hal_h264e_dbg_detail("enc_done finish");
2326
2327 if (regs->reg_ctl.int_sta.slc_done_sta)
2328 hal_h264e_dbg_detail("enc_slice finsh");
2329
2330 if (regs->reg_ctl.int_sta.sclr_done_sta)
2331 hal_h264e_dbg_detail("safe clear finsh");
2332
2333 if (regs->reg_ctl.int_sta.bsf_oflw_sta) {
2334 mpp_err_f("bit stream overflow");
2335 ret = MPP_NOK;
2336 }
2337
2338 if (regs->reg_ctl.int_sta.brsp_otsd_sta) {
2339 mpp_err_f("bus write full");
2340 ret = MPP_NOK;
2341 }
2342
2343 if (regs->reg_ctl.int_sta.wbus_err_sta) {
2344 mpp_err_f("bus write error");
2345 ret = MPP_NOK;
2346 }
2347
2348 if (regs->reg_ctl.int_sta.rbus_err_sta) {
2349 mpp_err_f("bus read error");
2350 ret = MPP_NOK;
2351 }
2352
2353 if (regs->reg_ctl.int_sta.wdg_sta) {
2354 ret = MPP_NOK;
2355 mpp_err_f("wdg timeout");
2356 }
2357
2358 return ret;
2359 }
2360
hal_h264e_vepu580_wait(void * hal,HalEncTask * task)2361 static MPP_RET hal_h264e_vepu580_wait(void *hal, HalEncTask *task)
2362 {
2363 MPP_RET ret = MPP_OK;
2364 HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
2365 HalVepu580RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
2366 RK_U32 split_out = ctx->cfg->split.split_out;
2367 MppPacket pkt = task->packet;
2368 RK_S32 offset = mpp_packet_get_length(pkt);
2369 H264NaluType type = task->rc_task->frm.is_idr ? H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE;
2370 MppEncH264HwCfg *hw_cfg = &ctx->cfg->h264.hw_cfg;
2371 RK_S32 i;
2372
2373 hal_h264e_dbg_func("enter %p\n", hal);
2374
2375 /* if pass1 mode, it will disable split mode and the split out need to be disable */
2376 if (task->rc_task->frm.save_pass1)
2377 split_out = 0;
2378
2379 /* update split_out in hw_cfg */
2380 hw_cfg->hw_split_out = split_out;
2381
2382 if (split_out) {
2383 EncOutParam param;
2384 RK_U32 slice_len;
2385 RK_U32 slice_last;
2386 MppDevPollCfg *poll_cfg = (MppDevPollCfg *)((char *)ctx->poll_cfgs +
2387 task->flags.reg_idx * ctx->poll_cfg_size);
2388 param.task = task;
2389 param.base = mpp_packet_get_data(task->packet);
2390
2391 do {
2392 poll_cfg->poll_type = 0;
2393 poll_cfg->poll_ret = 0;
2394 poll_cfg->count_max = split_out & MPP_ENC_SPLIT_OUT_LOWDELAY ? 1 : ctx->poll_slice_max;
2395 poll_cfg->count_ret = 0;
2396
2397 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, poll_cfg);
2398
2399 for (i = 0; i < poll_cfg->count_ret; i++) {
2400 slice_last = poll_cfg->slice_info[i].last;
2401 slice_len = poll_cfg->slice_info[i].length;
2402
2403 mpp_packet_add_segment_info(pkt, type, offset, slice_len);
2404 offset += slice_len;
2405
2406 if (split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) {
2407 param.length = slice_len;
2408
2409 if (slice_last)
2410 ctx->output_cb->cmd = ENC_OUTPUT_FINISH;
2411 else
2412 ctx->output_cb->cmd = ENC_OUTPUT_SLICE;
2413
2414 mpp_callback(ctx->output_cb, ¶m);
2415 }
2416 }
2417 } while (!slice_last);
2418
2419 ret = hal_h264e_vepu580_status_check(regs);
2420 if (!ret)
2421 task->hw_length += regs->reg_st.bs_lgth_l32;
2422 } else {
2423 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
2424 if (ret) {
2425 mpp_err_f("poll cmd failed %d\n", ret);
2426 ret = MPP_ERR_VPUHW;
2427 } else {
2428 ret = hal_h264e_vepu580_status_check(regs);
2429 if (!ret)
2430 task->hw_length += regs->reg_st.bs_lgth_l32;
2431 }
2432
2433 mpp_packet_add_segment_info(pkt, type, offset, regs->reg_st.bs_lgth_l32);
2434 }
2435
2436 if (!(split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) && !ret) {
2437 HalH264eVepuStreamAmend *amend = &ctx->amend_sets[task->flags.reg_idx];
2438
2439 if (amend->enable) {
2440 amend->old_length = task->hw_length;
2441 amend->slice->is_multi_slice = (ctx->cfg->split.split_mode > 0);
2442 h264e_vepu_stream_amend_proc(amend, &ctx->cfg->h264.hw_cfg);
2443 task->hw_length = amend->new_length;
2444 } else if (amend->prefix) {
2445 /* check prefix value */
2446 amend->old_length = task->hw_length;
2447 h264e_vepu_stream_amend_sync_ref_idc(amend);
2448 }
2449 }
2450
2451 hal_h264e_dbg_func("leave %p ret %d\n", hal, ret);
2452
2453 return ret;
2454 }
2455
hal_h264e_vepu580_ret_task(void * hal,HalEncTask * task)2456 static MPP_RET hal_h264e_vepu580_ret_task(void * hal, HalEncTask * task)
2457 {
2458 HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
2459 HalVepu580RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
2460 EncRcTaskInfo *rc_info = &task->rc_task->info;
2461 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
2462 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
2463 RK_U32 mbs = mb_w * mb_h;
2464
2465 hal_h264e_dbg_func("enter %p\n", hal);
2466
2467 // update total hardware length
2468 task->length += task->hw_length;
2469
2470 // setup bit length for rate control
2471 rc_info->bit_real = task->hw_length * 8;
2472 rc_info->quality_real = regs->reg_st.qp_sum / mbs;
2473 rc_info->madi = (!regs->reg_st.st_bnum_b16.num_b16) ? 0 :
2474 regs->reg_st.madi / regs->reg_st.st_bnum_b16.num_b16;
2475 rc_info->madp = (!regs->reg_st.st_bnum_cme.num_ctu) ? 0 :
2476 regs->reg_st.madp / regs->reg_st.st_bnum_cme.num_ctu;
2477 rc_info->iblk4_prop = (regs->reg_st.st_pnum_i4.pnum_i4 +
2478 regs->reg_st.st_pnum_i8.pnum_i8 +
2479 regs->reg_st.st_pnum_i16.pnum_i16) * 256 / mbs;
2480
2481 rc_info->sse = ((RK_S64)regs->reg_st.sse_h32 << 16) + (regs->reg_st.st_sse_bsl.sse_l16 & 0xffff);
2482 rc_info->lvl16_inter_num = regs->reg_st.st_pnum_p16.pnum_p16;
2483 rc_info->lvl8_inter_num = regs->reg_st.st_pnum_p8.pnum_p8;
2484 rc_info->lvl16_intra_num = regs->reg_st.st_pnum_i16.pnum_i16;
2485 rc_info->lvl8_intra_num = regs->reg_st.st_pnum_i8.pnum_i8;
2486 rc_info->lvl4_intra_num = regs->reg_st.st_pnum_i4.pnum_i4;
2487
2488 ctx->hal_rc_cfg.bit_real = rc_info->bit_real;
2489 ctx->hal_rc_cfg.quality_real = rc_info->quality_real;
2490 ctx->hal_rc_cfg.iblk4_prop = rc_info->iblk4_prop;
2491
2492 task->hal_ret.data = &ctx->hal_rc_cfg;
2493 task->hal_ret.number = 1;
2494
2495 //RK_U32 madi_th_cnt0 = ctx->regs_set->reg_st.madi_b16num0;
2496 RK_U32 madi_th_cnt1 = ctx->regs_set->reg_st.madi_b16num1;
2497 RK_U32 madi_th_cnt2 = ctx->regs_set->reg_st.madi_b16num2;
2498 RK_U32 madi_th_cnt3 = ctx->regs_set->reg_st.madi_b16num3;
2499 //RK_U32 madp_th_cnt0 = ctx->regs_set->reg_st.md_sad_b16num0;
2500 RK_U32 madp_th_cnt1 = ctx->regs_set->reg_st.md_sad_b16num1;
2501 RK_U32 madp_th_cnt2 = ctx->regs_set->reg_st.md_sad_b16num2;
2502 RK_U32 madp_th_cnt3 = ctx->regs_set->reg_st.md_sad_b16num3;
2503
2504 RK_U32 md_cnt = (24 * madp_th_cnt3 + 22 * madp_th_cnt2 + 17 * madp_th_cnt1) >> 2;
2505 RK_U32 madi_cnt = (6 * madi_th_cnt3 + 5 * madi_th_cnt2 + 4 * madi_th_cnt1) >> 2;
2506
2507 rc_info->motion_level = 0;
2508 if (md_cnt * 100 > 15 * mbs)
2509 rc_info->motion_level = 200;
2510 else if (md_cnt * 100 > 5 * mbs)
2511 rc_info->motion_level = 100;
2512 else
2513 rc_info->motion_level = 0;
2514
2515 rc_info->complex_level = 0;
2516 if (madi_cnt * 100 > 30 * mbs)
2517 rc_info->complex_level = 2;
2518 else if (madi_cnt * 100 > 13 * mbs)
2519 rc_info->complex_level = 1;
2520 else
2521 rc_info->complex_level = 0;
2522
2523 hal_h264e_dbg_rc("motion_level %u, complex_level %u\n", rc_info->motion_level, rc_info->complex_level);
2524
2525 vepu580_h264e_tune_stat_update(ctx->tune, task);
2526
2527 mpp_dev_multi_offset_reset(ctx->offsets);
2528
2529 if (ctx->dpb) {
2530 h264e_dpb_hal_end(ctx->dpb, task->flags.curr_idx);
2531 h264e_dpb_hal_end(ctx->dpb, task->flags.refr_idx);
2532 }
2533
2534 hal_h264e_dbg_func("leave %p\n", hal);
2535
2536 return MPP_OK;
2537 }
2538
2539 const MppEncHalApi hal_h264e_vepu580 = {
2540 .name = "hal_h264e_vepu580",
2541 .coding = MPP_VIDEO_CodingAVC,
2542 .ctx_size = sizeof(HalH264eVepu580Ctx),
2543 .flag = 0,
2544 .init = hal_h264e_vepu580_init,
2545 .deinit = hal_h264e_vepu580_deinit,
2546 .prepare = hal_h264e_vepu580_prepare,
2547 .get_task = hal_h264e_vepu580_get_task,
2548 .gen_regs = hal_h264e_vepu580_gen_regs,
2549 .start = hal_h264e_vepu580_start,
2550 .wait = hal_h264e_vepu580_wait,
2551 .part_start = NULL,
2552 .part_wait = NULL,
2553 .ret_task = hal_h264e_vepu580_ret_task,
2554 };
2555