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