aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
diff options
context:
space:
mode:
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.c53
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;