diff options
Diffstat (limited to 'drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c')
-rw-r--r-- | drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c index 7a00f050ec36..d0123dfc5f93 100644 --- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c +++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c @@ -25,6 +25,16 @@ static const char h264_filler_marker[] = {0x0, 0x0, 0x0, 0x1, 0xc}; #define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098 /* + * enum venc_h264_frame_type - h264 encoder output bitstream frame type + */ +enum venc_h264_frame_type { + VENC_H264_IDR_FRM, + VENC_H264_I_FRM, + VENC_H264_P_FRM, + VENC_H264_B_FRM, +}; + +/* * enum venc_h264_vpu_work_buf - h264 encoder buffer index */ enum venc_h264_vpu_work_buf { @@ -138,6 +148,7 @@ struct venc_h264_inst { struct mtk_vcodec_mem pps_buf; bool work_buf_allocated; unsigned int frm_cnt; + unsigned int skip_frm_cnt; unsigned int prepend_hdr; struct venc_vpu_inst vpu_inst; struct venc_h264_vsi *vsi; @@ -327,6 +338,22 @@ static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst) return irq_status; } +static int h264_frame_type(struct venc_h264_inst *inst) +{ + if ((inst->vsi->config.gop_size != 0 && + (inst->frm_cnt % inst->vsi->config.gop_size) == 0) || + (inst->frm_cnt == 0 && inst->vsi->config.gop_size == 0)) { + /* IDR frame */ + return VENC_H264_IDR_FRM; + } else if ((inst->vsi->config.intra_period != 0 && + (inst->frm_cnt % inst->vsi->config.intra_period) == 0) || + (inst->frm_cnt == 0 && inst->vsi->config.intra_period == 0)) { + /* I frame */ + return VENC_H264_I_FRM; + } else { + return VENC_H264_P_FRM; /* Note: B frames are not supported */ + } +} static int h264_encode_sps(struct venc_h264_inst *inst, struct mtk_vcodec_mem *bs_buf, unsigned int *bs_size) @@ -337,7 +364,7 @@ static int h264_encode_sps(struct venc_h264_inst *inst, mtk_vcodec_debug_enter(inst); ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL, - bs_buf, bs_size); + bs_buf, bs_size, NULL); if (ret) return ret; @@ -364,7 +391,7 @@ static int h264_encode_pps(struct venc_h264_inst *inst, mtk_vcodec_debug_enter(inst); ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL, - bs_buf, bs_size); + bs_buf, bs_size, NULL); if (ret) return ret; @@ -410,11 +437,18 @@ static int h264_encode_frame(struct venc_h264_inst *inst, { int ret = 0; unsigned int irq_status; + struct venc_frame_info frame_info; mtk_vcodec_debug_enter(inst); - + mtk_vcodec_debug(inst, "frm_cnt = %d\n ", inst->frm_cnt); + frame_info.frm_count = inst->frm_cnt; + frame_info.skip_frm_count = inst->skip_frm_cnt; + frame_info.frm_type = h264_frame_type(inst); + mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n", + frame_info.frm_count, frame_info.skip_frm_count, + frame_info.frm_type); ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf, - bs_buf, bs_size); + bs_buf, bs_size, &frame_info); if (ret) return ret; @@ -428,6 +462,7 @@ static int h264_encode_frame(struct venc_h264_inst *inst, inst->work_bufs[VENC_H264_VPU_WORK_BUF_SKIP_FRAME].va, *bs_size); ++inst->frm_cnt; + ++inst->skip_frm_cnt; return ret; } @@ -464,6 +499,7 @@ static void h264_encode_filler(struct venc_h264_inst *inst, void *buf, static int h264_enc_init(struct mtk_vcodec_ctx *ctx) { + const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx); int ret = 0; struct venc_h264_inst *inst; @@ -473,7 +509,7 @@ static int h264_enc_init(struct mtk_vcodec_ctx *ctx) inst->ctx = ctx; inst->vpu_inst.ctx = ctx; - inst->vpu_inst.id = IPI_VENC_H264; + inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264; inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS); mtk_vcodec_debug_enter(inst); @@ -629,7 +665,12 @@ static int h264_enc_set_param(void *handle, inst->prepend_hdr = 1; mtk_vcodec_debug(inst, "set prepend header mode"); break; - + case VENC_SET_PARAM_FORCE_INTRA: + case VENC_SET_PARAM_GOP_SIZE: + case VENC_SET_PARAM_INTRA_PERIOD: + inst->frm_cnt = 0; + inst->skip_frm_cnt = 0; + fallthrough; default: ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm); break; |