1 /*
2 * Copyright 2015 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_vepu2_v2"
18
19 #include <string.h>
20
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_frame.h"
24 #include "mpp_common.h"
25 #include "mpp_device.h"
26 #include "mpp_rc.h"
27 #include "mpp_packet_impl.h"
28
29 #include "mpp_enc_hal.h"
30 #include "h264e_debug.h"
31 #include "h264e_sps.h"
32 #include "h264e_pps.h"
33 #include "h264e_slice.h"
34
35 #include "hal_h264e_debug.h"
36 #include "hal_h264e_vpu_tbl.h"
37 #include "hal_h264e_vepu_v2.h"
38 #include "hal_h264e_stream_amend.h"
39
40 #include "hal_h264e_vepu2_reg_tbl.h"
41
42 typedef struct HalH264eVepu2Ctx_t {
43 MppEncCfgSet *cfg;
44
45 MppDev dev;
46 RK_S32 frame_cnt;
47
48 /* buffers management */
49 HalH264eVepuBufs hw_bufs;
50
51 /* preprocess config */
52 HalH264eVepuPrep hw_prep;
53
54 /* input / recon / refer address config */
55 HalH264eVepuAddr hw_addr;
56 VepuOffsetCfg hw_offset;
57
58 /* macroblock ratecontrol config */
59 HalH264eVepuMbRc hw_mbrc;
60
61 /* syntax for input from enc_impl */
62 RK_U32 updated;
63 H264eSps *sps;
64 H264ePps *pps;
65 H264eSlice *slice;
66 H264eFrmInfo *frms;
67 H264eReorderInfo *reorder;
68 H264eMarkingInfo *marking;
69 H264ePrefixNal *prefix;
70
71 /* special TSVC stream header fixup */
72 HalH264eVepuStreamAmend amend;
73
74 /* vepu2 macroblock ratecontrol context */
75 HalH264eVepuMbRcCtx rc_ctx;
76
77 H264eVpu2RegSet regs_set;
78 H264eVpu2RegSet regs_get;
79 } HalH264eVepu2Ctx;
80
hal_h264e_vepu2_deinit_v2(void * hal)81 static MPP_RET hal_h264e_vepu2_deinit_v2(void *hal)
82 {
83 HalH264eVepu2Ctx *p = (HalH264eVepu2Ctx *)hal;
84
85 hal_h264e_dbg_func("enter %p\n", p);
86
87 if (p->dev) {
88 mpp_dev_deinit(p->dev);
89 p->dev = NULL;
90 }
91
92 h264e_vepu_buf_deinit(&p->hw_bufs);
93
94 if (p->rc_ctx) {
95 h264e_vepu_mbrc_deinit(p->rc_ctx);
96 p->rc_ctx = NULL;
97 }
98
99 h264e_vepu_stream_amend_deinit(&p->amend);
100
101 hal_h264e_dbg_func("leave %p\n", p);
102
103 return MPP_OK;
104 }
105
hal_h264e_vepu2_init_v2(void * hal,MppEncHalCfg * cfg)106 static MPP_RET hal_h264e_vepu2_init_v2(void *hal, MppEncHalCfg *cfg)
107 {
108 HalH264eVepu2Ctx *p = (HalH264eVepu2Ctx *)hal;
109 MPP_RET ret = MPP_OK;
110
111 hal_h264e_dbg_func("enter %p\n", p);
112
113 p->cfg = cfg->cfg;
114
115 /* update output to MppEnc */
116 cfg->type = VPU_CLIENT_VEPU2;
117
118 ret = mpp_dev_init(&cfg->dev, cfg->type);
119 if (ret) {
120 mpp_err_f("mpp_dev_init failed ret: %d\n", ret);
121 goto DONE;
122 }
123 p->dev = cfg->dev;
124
125 ret = h264e_vepu_buf_init(&p->hw_bufs);
126 if (ret) {
127 mpp_err_f("init vepu buffer failed ret: %d\n", ret);
128 goto DONE;
129 }
130
131 ret = h264e_vepu_mbrc_init(&p->rc_ctx, &p->hw_mbrc);
132 if (ret) {
133 mpp_err_f("init mb rate control failed ret: %d\n", ret);
134 goto DONE;
135 }
136
137 /* create buffer to TSVC stream */
138 h264e_vepu_stream_amend_init(&p->amend);
139
140 DONE:
141 if (ret)
142 hal_h264e_vepu2_deinit_v2(hal);
143
144 hal_h264e_dbg_func("leave %p\n", p);
145 return ret;
146 }
147
update_vepu2_syntax(HalH264eVepu2Ctx * ctx,MppSyntax * syntax)148 static RK_U32 update_vepu2_syntax(HalH264eVepu2Ctx *ctx, MppSyntax *syntax)
149 {
150 H264eSyntaxDesc *desc = syntax->data;
151 RK_S32 syn_num = syntax->number;
152 RK_U32 updated = 0;
153 RK_S32 i;
154
155 for (i = 0; i < syn_num; i++, desc++) {
156 switch (desc->type) {
157 case H264E_SYN_CFG : {
158 hal_h264e_dbg_detail("update cfg");
159 ctx->cfg = desc->p;
160 } break;
161 case H264E_SYN_SPS : {
162 hal_h264e_dbg_detail("update sps");
163 ctx->sps = desc->p;
164 } break;
165 case H264E_SYN_PPS : {
166 hal_h264e_dbg_detail("update pps");
167 ctx->pps = desc->p;
168 } break;
169 case H264E_SYN_DPB : {
170 hal_h264e_dbg_detail("update dpb");
171 } break;
172 case H264E_SYN_SLICE : {
173 hal_h264e_dbg_detail("update slice");
174 ctx->slice = desc->p;
175 } break;
176 case H264E_SYN_FRAME : {
177 hal_h264e_dbg_detail("update frames");
178 ctx->frms = desc->p;
179 } break;
180 case H264E_SYN_PREFIX : {
181 hal_h264e_dbg_detail("update prefix nal");
182 ctx->prefix = desc->p;
183 } break;
184 default : {
185 mpp_log_f("invalid syntax type %d\n", desc->type);
186 } break;
187 }
188
189 updated |= SYN_TYPE_FLAG(desc->type);
190 }
191
192 return updated;
193 }
194
hal_h264e_vepu2_get_task_v2(void * hal,HalEncTask * task)195 static MPP_RET hal_h264e_vepu2_get_task_v2(void *hal, HalEncTask *task)
196 {
197 HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
198 RK_U32 updated = update_vepu2_syntax(ctx, &task->syntax);
199 MppEncPrepCfg *prep = &ctx->cfg->prep;
200 HalH264eVepuPrep *hw_prep = &ctx->hw_prep;
201 HalH264eVepuAddr *hw_addr = &ctx->hw_addr;
202 HalH264eVepuBufs *hw_bufs = &ctx->hw_bufs;
203 VepuOffsetCfg *hw_offset = &ctx->hw_offset;
204 H264eFrmInfo *frms = ctx->frms;
205
206 hal_h264e_dbg_func("enter %p\n", hal);
207
208 if (updated & SYN_TYPE_FLAG(H264E_SYN_CFG)) {
209 h264e_vepu_buf_set_frame_size(hw_bufs, prep->width, prep->height);
210
211 /* preprocess setup */
212 if (h264e_vepu_prep_setup(hw_prep, prep))
213 return MPP_NOK;
214
215 h264e_vepu_mbrc_setup(ctx->rc_ctx, ctx->cfg);
216 }
217
218 if (updated & SYN_TYPE_FLAG(H264E_SYN_SLICE)) {
219 H264eSlice *slice = ctx->slice;
220
221 h264e_vepu_buf_set_cabac_idc(hw_bufs, slice->cabac_init_idc);
222 }
223
224 h264e_vepu_prep_get_addr(hw_prep, task->input, &hw_addr->orig);
225
226 MppBuffer recn = h264e_vepu_buf_get_frame_buffer(hw_bufs, frms->curr_idx);
227 MppBuffer refr = h264e_vepu_buf_get_frame_buffer(hw_bufs, frms->refr_idx);
228
229 hw_addr->recn[0] = mpp_buffer_get_fd(recn);
230 hw_addr->refr[0] = mpp_buffer_get_fd(refr);
231 hw_addr->recn[1] = hw_addr->recn[0];
232 hw_addr->refr[1] = hw_addr->refr[0];
233
234 hw_offset->fmt = prep->format;
235 hw_offset->width = prep->width;
236 hw_offset->height = prep->height;
237 hw_offset->hor_stride = prep->hor_stride;
238 hw_offset->ver_stride = prep->ver_stride;
239 hw_offset->offset_x = mpp_frame_get_offset_x(task->frame);
240 hw_offset->offset_y = mpp_frame_get_offset_y(task->frame);
241
242 get_vepu_offset_cfg(hw_offset);
243
244 h264e_vepu_stream_amend_config(&ctx->amend, task->packet, ctx->cfg,
245 ctx->slice, ctx->prefix);
246
247 hal_h264e_dbg_func("leave %p\n", hal);
248
249 return MPP_OK;
250 }
251
setup_output_packet(HalH264eVepu2Ctx * ctx,RK_U32 * reg,MppBuffer buf,RK_U32 offset)252 static RK_S32 setup_output_packet(HalH264eVepu2Ctx *ctx, RK_U32 *reg, MppBuffer buf, RK_U32 offset)
253 {
254 RK_U32 offset8 = offset & (~0x7);
255 RK_S32 fd = mpp_buffer_get_fd(buf);
256 RK_U32 hdr_rem_msb = 0;
257 RK_U32 hdr_rem_lsb = 0;
258 RK_U32 limit = 0;
259
260 if (offset) {
261 RK_U8 *buf32 = (RK_U8 *)mpp_buffer_get_ptr(buf) + offset8;
262
263 hdr_rem_msb = MPP_RB32(buf32);
264 hdr_rem_lsb = MPP_RB32(buf32 + 4);
265 }
266
267 hal_h264e_dbg_detail("offset %d offset8 %d\n", offset, offset8);
268 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_STREAM, fd);
269 mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_OUTPUT_STREAM >> 2, offset8);
270
271 /* output buffer size is 64 bit address then 8 multiple size */
272 limit = mpp_buffer_get_size(buf);
273 limit -= offset8;
274 limit >>= 3;
275 limit &= ~7;
276 H264E_HAL_SET_REG(reg, VEPU_REG_STR_BUF_LIMIT, limit);
277
278 hal_h264e_dbg_detail("msb %08x lsb %08x", hdr_rem_msb, hdr_rem_lsb);
279
280 H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_MSB, hdr_rem_msb);
281 H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_LSB, hdr_rem_lsb);
282
283 return (offset - offset8) * 8;
284 }
285
setup_intra_refresh(HalH264eVepu2Ctx * ctx,EncFrmStatus * frm)286 static MPP_RET setup_intra_refresh(HalH264eVepu2Ctx *ctx, EncFrmStatus *frm)
287 {
288 MPP_RET ret = MPP_OK;
289 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
290 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
291 RK_U32 refresh_num = ctx->cfg->rc.refresh_num;
292 MppEncCfgSet *cfg = ctx->cfg;
293 RK_U32 *reg = ctx->regs_set.val;
294 RK_U32 val = 0;
295 RK_S32 top = 0;
296 RK_S32 left = 0;
297 RK_S32 right = 0;
298 RK_S32 bottom = 0;
299 RK_U32 refresh_idx = frm->seq_idx % cfg->rc.gop;
300
301 hal_h264e_dbg_func("enter\n");
302
303 if (!ctx->cfg->rc.refresh_en || !frm->is_i_refresh) {
304 goto RET;
305 }
306
307 if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_ROW) {
308 left = 0;
309 right = mb_w;
310 top = refresh_idx * refresh_num - 2;
311 bottom = (refresh_idx + 1) * refresh_num - 1;
312 top = mpp_clip(top, 0, mb_h);
313 bottom = mpp_clip(bottom, 0, mb_h);
314 } else if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_COL) {
315 top = 0;
316 bottom = mb_h;
317 left = refresh_idx * refresh_num - 2;
318 right = (refresh_idx + 1) * refresh_num - 1;
319 left = mpp_clip(left, 0, mb_w);
320 right = mpp_clip(right, 0, mb_w);
321 }
322
323 RET:
324 val = VEPU_REG_INTRA_AREA_TOP(top)
325 | VEPU_REG_INTRA_AREA_BOTTOM(bottom)
326 | VEPU_REG_INTRA_AREA_LEFT(left)
327 | VEPU_REG_INTRA_AREA_RIGHT(right);
328 H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_AREA_CTRL, val);
329
330 hal_h264e_dbg_func("leave, ret %d\n", ret);
331
332 return ret;
333 }
334
hal_h264e_vepu2_gen_regs_v2(void * hal,HalEncTask * task)335 static MPP_RET hal_h264e_vepu2_gen_regs_v2(void *hal, HalEncTask *task)
336 {
337 //MPP_RET ret = MPP_OK;
338 HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
339 HalH264eVepuBufs *hw_bufs = &ctx->hw_bufs;
340 HalH264eVepuPrep *hw_prep = &ctx->hw_prep;
341 HalH264eVepuAddr *hw_addr = &ctx->hw_addr;
342 HalH264eVepuMbRc *hw_mbrc = &ctx->hw_mbrc;
343 VepuOffsetCfg *hw_offset = &ctx->hw_offset;
344 EncRcTaskInfo *rc_info = &task->rc_task->info;
345 EncFrmStatus *frm = &task->rc_task->frm;
346 H264eSps *sps = ctx->sps;
347 H264ePps *pps = ctx->pps;
348 H264eSlice *slice = ctx->slice;
349 RK_U32 *reg = ctx->regs_set.val;
350 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
351 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
352 RK_U32 offset = mpp_packet_get_length(task->packet);
353 RK_U32 first_free_bit = 0;
354 RK_U32 val = 0;
355 RK_S32 i = 0;
356
357 if (hw_prep->rotation) {
358 mb_w = ctx->sps->pic_height_in_mbs;
359 mb_h = ctx->sps->pic_width_in_mbs;
360 }
361
362 hw_mbrc->qp_init = rc_info->quality_target;
363 hw_mbrc->qp_max = rc_info->quality_max;
364 hw_mbrc->qp_min = rc_info->quality_min;
365
366 hal_h264e_dbg_func("enter %p\n", hal);
367
368 hal_h264e_dbg_detail("frame %d generate regs now", frm->seq_idx);
369
370 // prepare mb rc config
371 h264e_vepu_mbrc_prepare(ctx->rc_ctx, &ctx->hw_mbrc, task->rc_task);
372 h264e_vepu_slice_split_cfg(ctx->slice, &ctx->hw_mbrc, task->rc_task, ctx->cfg);
373
374 /* setup output address with offset */
375 first_free_bit = setup_output_packet(ctx, reg, task->output, offset);
376
377 /* set extra byte for header */
378 hw_mbrc->hdr_strm_size = offset;
379 hw_mbrc->hdr_free_size = first_free_bit / 8;
380 hw_mbrc->out_strm_size = 0;
381
382 /*
383 * The hardware needs only the value for luma plane, because
384 * values of other planes are calculated internally based on
385 * format setting.
386 */
387 setup_intra_refresh(ctx, frm);
388
389 val = VEPU_REG_AXI_CTRL_READ_ID(0);
390 val |= VEPU_REG_AXI_CTRL_WRITE_ID(0);
391 val |= VEPU_REG_AXI_CTRL_BURST_LEN(16);
392 val |= VEPU_REG_AXI_CTRL_INCREMENT_MODE(0);
393 val |= VEPU_REG_AXI_CTRL_BIRST_DISCARD(0);
394 H264E_HAL_SET_REG(reg, VEPU_REG_AXI_CTRL, val);
395
396 H264E_HAL_SET_REG(reg, VEPU_QP_ADJUST_MAD_DELTA_ROI,
397 hw_mbrc->mad_qp_change);
398
399 val = 0;
400 if (mb_w * mb_h > 3600)
401 val = VEPU_REG_DISABLE_QUARTER_PIXEL_MV;
402 val |= VEPU_REG_CABAC_INIT_IDC(slice->cabac_init_idc);
403 if (pps->entropy_coding_mode)
404 val |= VEPU_REG_ENTROPY_CODING_MODE;
405 if (pps->transform_8x8_mode)
406 val |= VEPU_REG_H264_TRANS8X8_MODE;
407 if (sps->profile_idc > 31)
408 val |= VEPU_REG_H264_INTER4X4_MODE;
409 /*reg |= VEPU_REG_H264_STREAM_MODE;*/
410 val |= VEPU_REG_H264_SLICE_SIZE(hw_mbrc->slice_size_mb_rows);
411 H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL0, val);
412
413 RK_U32 scaler = MPP_MAX(1, 200 / (mb_w + mb_h));
414
415 RK_U32 skip_penalty = MPP_MIN(255, h264_skip_sad_penalty[hw_mbrc->qp_init] * scaler);
416
417 RK_U32 overfill_r = (hw_prep->src_w & 0x0f) ?
418 ((16 - (hw_prep->src_w & 0x0f)) / 4) : 0;
419
420 RK_U32 overfill_b = (hw_prep->src_h & 0x0f) ?
421 (16 - (hw_prep->src_h & 0x0f)) : 0;
422
423 val = VEPU_REG_STREAM_START_OFFSET(first_free_bit) |
424 VEPU_REG_SKIP_MACROBLOCK_PENALTY(skip_penalty) |
425 VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) |
426 VEPU_REG_IN_IMG_CTRL_OVRFLB(overfill_b);
427 H264E_HAL_SET_REG(reg, VEPU_REG_ENC_OVER_FILL_STRM_OFFSET, val);
428
429 // When offset is zero row length should be total 16 aligned width
430 val = VEPU_REG_IN_IMG_CHROMA_OFFSET(0)
431 | VEPU_REG_IN_IMG_LUMA_OFFSET(0)
432 | VEPU_REG_IN_IMG_CTRL_ROW_LEN(hw_prep->pixel_stride);
433
434 H264E_HAL_SET_REG(reg, VEPU_REG_INPUT_LUMA_INFO, val);
435
436 val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[0])
437 | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[1]);
438 H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(0), val);
439
440 val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[2])
441 | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[3]);
442 H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(1), val);
443
444 val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[4])
445 | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[5]);
446 H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(2), val);
447
448 val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[6])
449 | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[7]);
450 H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(3), val);
451
452 val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[8])
453 | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[9]);
454 H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(4), val);
455
456 val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[0])
457 | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[1]);
458 H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(0), val);
459
460 val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[2])
461 | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[3]);
462 H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(1), val);
463
464 val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[4])
465 | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[5]);
466 H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(2), val);
467
468 val = VEPU_REG_CHKPT_DELTA_QP_CHK6(hw_mbrc->cp_delta_qp[6])
469 | VEPU_REG_CHKPT_DELTA_QP_CHK5(hw_mbrc->cp_delta_qp[5])
470 | VEPU_REG_CHKPT_DELTA_QP_CHK4(hw_mbrc->cp_delta_qp[4])
471 | VEPU_REG_CHKPT_DELTA_QP_CHK3(hw_mbrc->cp_delta_qp[3])
472 | VEPU_REG_CHKPT_DELTA_QP_CHK2(hw_mbrc->cp_delta_qp[2])
473 | VEPU_REG_CHKPT_DELTA_QP_CHK1(hw_mbrc->cp_delta_qp[1])
474 | VEPU_REG_CHKPT_DELTA_QP_CHK0(hw_mbrc->cp_delta_qp[0]);
475 H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_DELTA_QP, val);
476
477 val = VEPU_REG_MAD_THRESHOLD(hw_mbrc->mad_threshold)
478 | VEPU_REG_IN_IMG_CTRL_FMT(hw_prep->src_fmt)
479 | VEPU_REG_IN_IMG_ROTATE_MODE(hw_prep->rotation)
480 | VEPU_REG_SIZE_TABLE_PRESENT; //FIXED
481 H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL1, val);
482
483 val = VEPU_REG_INTRA16X16_MODE(h264_intra16_favor[hw_mbrc->qp_init])
484 | VEPU_REG_INTER_MODE(h264_inter_favor[hw_mbrc->qp_init]);
485 H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_INTER_MODE, val);
486
487 val = VEPU_REG_PPS_INIT_QP(pps->pic_init_qp)
488 | VEPU_REG_SLICE_FILTER_ALPHA(slice->slice_alpha_c0_offset_div2)
489 | VEPU_REG_SLICE_FILTER_BETA(slice->slice_beta_offset_div2)
490 | VEPU_REG_CHROMA_QP_OFFSET(pps->chroma_qp_index_offset)
491 | VEPU_REG_IDR_PIC_ID(slice->idr_pic_id);
492
493 if (slice->disable_deblocking_filter_idc)
494 val |= VEPU_REG_FILTER_DISABLE;
495
496 if (pps->constrained_intra_pred)
497 val |= VEPU_REG_CONSTRAINED_INTRA_PREDICTION;
498 H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL2, val);
499
500 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_NEXT_PIC, 0);
501 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_MV_OUT, 0);
502
503 MppBuffer cabac_table = hw_bufs->cabac_table;
504 RK_S32 cabac_table_fd = cabac_table ? mpp_buffer_get_fd(cabac_table) : 0;
505
506 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_CABAC_TBL, cabac_table_fd);
507
508 val = VEPU_REG_ROI1_TOP_MB(mb_h)
509 | VEPU_REG_ROI1_BOTTOM_MB(mb_h)
510 | VEPU_REG_ROI1_LEFT_MB(mb_w)
511 | VEPU_REG_ROI1_RIGHT_MB(mb_w);
512 H264E_HAL_SET_REG(reg, VEPU_REG_ROI1, val);
513
514 val = VEPU_REG_ROI2_TOP_MB(mb_h)
515 | VEPU_REG_ROI2_BOTTOM_MB(mb_h)
516 | VEPU_REG_ROI2_LEFT_MB(mb_w)
517 | VEPU_REG_ROI2_RIGHT_MB(mb_w);
518 H264E_HAL_SET_REG(reg, VEPU_REG_ROI2, val);
519 H264E_HAL_SET_REG(reg, VEPU_REG_STABLILIZATION_OUTPUT, 0);
520
521 val = VEPU_REG_RGB2YUV_CONVERSION_COEFB(hw_prep->color_conversion_coeff_b)
522 | VEPU_REG_RGB2YUV_CONVERSION_COEFA(hw_prep->color_conversion_coeff_a);
523 H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF1, val);
524
525 val = VEPU_REG_RGB2YUV_CONVERSION_COEFE(hw_prep->color_conversion_coeff_e)
526 | VEPU_REG_RGB2YUV_CONVERSION_COEFC(hw_prep->color_conversion_coeff_c);
527 H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF2, val);
528
529 val = VEPU_REG_RGB2YUV_CONVERSION_COEFF(hw_prep->color_conversion_coeff_f);
530 H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF3, val);
531
532 val = VEPU_REG_RGB_MASK_B_MSB(hw_prep->b_mask_msb)
533 | VEPU_REG_RGB_MASK_G_MSB(hw_prep->g_mask_msb)
534 | VEPU_REG_RGB_MASK_R_MSB(hw_prep->r_mask_msb);
535 H264E_HAL_SET_REG(reg, VEPU_REG_RGB_MASK_MSB, val); //FIXED
536
537 {
538 RK_U32 diff_mv_penalty[3] = {0};
539 diff_mv_penalty[0] = h264_diff_mv_penalty4p[hw_mbrc->qp_init];
540 diff_mv_penalty[1] = h264_diff_mv_penalty[hw_mbrc->qp_init];
541 diff_mv_penalty[2] = h264_diff_mv_penalty[hw_mbrc->qp_init];
542
543 val = VEPU_REG_1MV_PENALTY(diff_mv_penalty[1])
544 | VEPU_REG_QMV_PENALTY(diff_mv_penalty[2])
545 | VEPU_REG_4MV_PENALTY(diff_mv_penalty[0]);
546 }
547
548 val |= VEPU_REG_SPLIT_MV_MODE_EN;
549 H264E_HAL_SET_REG(reg, VEPU_REG_MV_PENALTY, val);
550
551 val = VEPU_REG_H264_LUMA_INIT_QP(hw_mbrc->qp_init)
552 | VEPU_REG_H264_QP_MAX(hw_mbrc->qp_max)
553 | VEPU_REG_H264_QP_MIN(hw_mbrc->qp_min)
554 | VEPU_REG_H264_CHKPT_DISTANCE(hw_mbrc->cp_distance_mbs);
555 H264E_HAL_SET_REG(reg, VEPU_REG_QP_VAL, val);
556
557 val = VEPU_REG_ZERO_MV_FAVOR_D2(10);
558 H264E_HAL_SET_REG(reg, VEPU_REG_MVC_RELATE, val);
559
560 val = VEPU_REG_OUTPUT_SWAP32
561 | VEPU_REG_OUTPUT_SWAP16
562 | VEPU_REG_OUTPUT_SWAP8
563 | VEPU_REG_INPUT_SWAP8_(hw_prep->swap_8_in)
564 | VEPU_REG_INPUT_SWAP16_(hw_prep->swap_16_in)
565 | VEPU_REG_INPUT_SWAP32_(hw_prep->swap_32_in);
566 H264E_HAL_SET_REG(reg, VEPU_REG_DATA_ENDIAN, val);
567
568 val = VEPU_REG_PPS_ID(pps->pps_id)
569 | VEPU_REG_INTRA_PRED_MODE(h264_prev_mode_favor[hw_mbrc->qp_init])
570 | VEPU_REG_FRAME_NUM(slice->frame_num);
571 H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL3, val);
572
573 val = VEPU_REG_INTERRUPT_TIMEOUT_EN;
574 H264E_HAL_SET_REG(reg, VEPU_REG_INTERRUPT, val);
575
576 {
577 RK_U8 dmv_penalty[128] = {0};
578 RK_U8 dmv_qpel_penalty[128] = {0};
579
580 for (i = 0; i < 128; i++) {
581 dmv_penalty[i] = i;
582 dmv_qpel_penalty[i] = MPP_MIN(255, exp_golomb_signed(i));
583 }
584
585 for (i = 0; i < 128; i += 4) {
586 val = VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i], 3);
587 val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 1], 2);
588 val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 2], 1);
589 val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 3], 0);
590 H264E_HAL_SET_REG(reg, VEPU_REG_DMV_PENALTY_TBL(i / 4), val);
591
592 val = VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
593 dmv_qpel_penalty[i], 3);
594 val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
595 dmv_qpel_penalty[i + 1], 2);
596 val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
597 dmv_qpel_penalty[i + 2], 1);
598 val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
599 dmv_qpel_penalty[i + 3], 0);
600 H264E_HAL_SET_REG(reg, VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i / 4), val);
601 }
602 }
603
604 /* set buffers addr */
605 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_LUMA, hw_addr->orig[0]);
606 if (hw_offset->offset_byte[0])
607 mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_IN_LUMA >> 2,
608 hw_offset->offset_byte[0]);
609 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CB, hw_addr->orig[1]);
610 if (hw_offset->offset_byte[1])
611 mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_IN_CB >> 2,
612 hw_offset->offset_byte[1]);
613 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CR, hw_addr->orig[2]);
614 if (hw_offset->offset_byte[2])
615 mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_IN_CR >> 2,
616 hw_offset->offset_byte[2]);
617
618 MppBuffer nal_size_table = h264e_vepu_buf_get_nal_size_table(hw_bufs);
619 RK_S32 nal_size_table_fd = nal_size_table ? mpp_buffer_get_fd(nal_size_table) : 0;
620
621 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_CTRL, nal_size_table_fd);
622
623 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_LUMA, hw_addr->recn[0]);
624 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_CHROMA, hw_addr->recn[1]);
625 mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_REC_CHROMA >> 2, hw_bufs->yuv_size);
626 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_LUMA, hw_addr->refr[0]);
627 H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_CHROMA, hw_addr->refr[1]);
628 mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_REF_CHROMA >> 2, hw_bufs->yuv_size);
629
630 /* set important encode mode info */
631 val = VEPU_REG_MB_HEIGHT(mb_h)
632 | VEPU_REG_MB_WIDTH(mb_w)
633 | VEPU_REG_PIC_TYPE(slice->idr_flag)
634 | VEPU_REG_ENCODE_FORMAT(3)
635 | VEPU_REG_ENCODE_ENABLE;
636 H264E_HAL_SET_REG(reg, VEPU_REG_ENCODE_START, val);
637
638 ctx->frame_cnt++;
639
640 hal_h264e_dbg_func("leave %p\n", hal);
641 return MPP_OK;
642 }
643
hal_h264e_vepu2_start_v2(void * hal,HalEncTask * task)644 static MPP_RET hal_h264e_vepu2_start_v2(void *hal, HalEncTask *task)
645 {
646 MPP_RET ret = MPP_OK;
647 HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
648 (void)task;
649
650 hal_h264e_dbg_func("enter %p\n", hal);
651
652 if (ctx->dev) {
653 MppDevRegWrCfg wr_cfg;
654 MppDevRegRdCfg rd_cfg;
655 RK_U32 reg_size = sizeof(ctx->regs_set);
656
657 do {
658 wr_cfg.reg = &ctx->regs_set;
659 wr_cfg.size = reg_size;
660 wr_cfg.offset = 0;
661
662 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
663 if (ret) {
664 mpp_err_f("set register write failed %d\n", ret);
665 break;
666 }
667
668 rd_cfg.reg = &ctx->regs_get;
669 rd_cfg.size = reg_size;
670 rd_cfg.offset = 0;
671
672 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
673 if (ret) {
674 mpp_err_f("set register read failed %d\n", ret);
675 break;
676 }
677
678 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
679 if (ret) {
680 mpp_err_f("send cmd failed %d\n", ret);
681 break;
682 }
683 } while (0);
684 } else
685 mpp_err("invalid NULL device ctx\n");
686
687 hal_h264e_dbg_func("leave %p\n", hal);
688
689 return ret;
690 }
691
h264e_vepu2_get_mbrc(HalH264eVepuMbRc * mb_rc,H264eVpu2RegSet * reg)692 static void h264e_vepu2_get_mbrc(HalH264eVepuMbRc *mb_rc, H264eVpu2RegSet *reg)
693 {
694 RK_S32 i = 0;
695 RK_U32 cpt_prev = 0;
696 RK_U32 overflow = 0;
697 RK_U32 cpt_idx = VEPU_REG_CHECKPOINT(0) / 4;
698 RK_U32 *reg_val = reg->val;
699
700 mb_rc->hw_status = reg_val[VEPU_REG_INTERRUPT / 4];
701 mb_rc->out_strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8 - mb_rc->hdr_free_size;
702 mb_rc->qp_sum = ((reg_val[VEPU_REG_QP_SUM_DIV2 / 4] >> 11) & 0x001fffff) * 2;
703 mb_rc->less_mad_count = (reg_val[VEPU_REG_MB_CTRL / 4] >> 16) & 0xffff;
704 mb_rc->rlc_count = reg_val[VEPU_REG_RLC_SUM / 4] & 0x3fffff;
705
706 for (i = 0; i < VEPU_CHECK_POINTS_MAX; i++) {
707 RK_U32 cpt = VEPU_REG_CHECKPOINT_RESULT(reg_val[cpt_idx]);
708
709 if (cpt < cpt_prev)
710 overflow += (1 << 21);
711
712 cpt_prev = cpt;
713 mb_rc->cp_usage[i] = cpt + overflow;
714 cpt_idx += (i & 1);
715 }
716 }
717
hal_h264e_vepu2_wait_v2(void * hal,HalEncTask * task)718 static MPP_RET hal_h264e_vepu2_wait_v2(void *hal, HalEncTask *task)
719 {
720 HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
721 HalH264eVepuMbRc *hw_mbrc = &ctx->hw_mbrc;
722 H264NaluType type = task->rc_task->frm.is_idr ? H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE;
723 MppPacket pkt = task->packet;
724 RK_S32 offset = mpp_packet_get_length(pkt);
725 MPP_RET ret = MPP_NOK;
726
727 hal_h264e_dbg_func("enter %p\n", hal);
728
729 if (ctx->dev) {
730 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
731 if (ret)
732 mpp_err_f("poll cmd failed %d\n", ret);
733 } else {
734 mpp_err("invalid NULL device ctx\n");
735 return ret;
736 }
737
738 h264e_vepu2_get_mbrc(hw_mbrc, &ctx->regs_get);
739 h264e_vepu_mbrc_update(ctx->rc_ctx, hw_mbrc);
740
741 mpp_packet_add_segment_info(pkt, type, offset, hw_mbrc->out_strm_size);
742
743 {
744 HalH264eVepuStreamAmend *amend = &ctx->amend;
745
746 if (amend->enable) {
747 amend->old_length = hw_mbrc->out_strm_size;
748 h264e_vepu_stream_amend_proc(amend, &ctx->cfg->h264.hw_cfg);
749 ctx->hw_mbrc.out_strm_size = amend->new_length;
750 } else if (amend->prefix) {
751 /* check prefix value */
752 amend->old_length = hw_mbrc->out_strm_size;
753 h264e_vepu_stream_amend_sync_ref_idc(amend);
754 }
755 }
756
757 task->hw_length += ctx->hw_mbrc.out_strm_size;
758
759 hal_h264e_dbg_func("leave %p\n", hal);
760
761 return MPP_OK;
762 }
763
hal_h264e_vepu2_ret_task_v2(void * hal,HalEncTask * task)764 static MPP_RET hal_h264e_vepu2_ret_task_v2(void *hal, HalEncTask *task)
765 {
766 HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
767 EncRcTaskInfo *rc_info = &task->rc_task->info;
768 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
769 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
770 RK_U32 mbs = mb_w * mb_h;
771
772 hal_h264e_dbg_func("enter %p\n", hal);
773
774 task->length += task->hw_length;
775
776 rc_info->bit_real = task->hw_length * 8;
777 rc_info->quality_real = ctx->hw_mbrc.qp_sum / mbs;
778
779 hal_h264e_dbg_rc("real bit %d quality %d\n", rc_info->bit_real, rc_info->quality_real);
780
781 task->hal_ret.data = rc_info;
782 task->hal_ret.number = 1;
783
784 hal_h264e_dbg_func("leave %p\n", hal);
785
786 return MPP_OK;
787 }
788
789 const MppEncHalApi hal_h264e_vepu2 = {
790 .name = "hal_h264e_vepu2",
791 .coding = MPP_VIDEO_CodingAVC,
792 .ctx_size = sizeof(HalH264eVepu2Ctx),
793 .flag = 0,
794 .init = hal_h264e_vepu2_init_v2,
795 .deinit = hal_h264e_vepu2_deinit_v2,
796 .prepare = NULL,
797 .get_task = hal_h264e_vepu2_get_task_v2,
798 .gen_regs = hal_h264e_vepu2_gen_regs_v2,
799 .start = hal_h264e_vepu2_start_v2,
800 .wait = hal_h264e_vepu2_wait_v2,
801 .part_start = NULL,
802 .part_wait = NULL,
803 .ret_task = hal_h264e_vepu2_ret_task_v2,
804 };
805