diff --git a/inc/rk_venc_cmd.h b/inc/rk_venc_cmd.h index 18154ac0..2e4488a5 100644 --- a/inc/rk_venc_cmd.h +++ b/inc/rk_venc_cmd.h @@ -954,10 +954,40 @@ typedef struct MppEncCodecCfg_t { }; } MppEncCodecCfg; +typedef enum MppEncSliceSplit_e { + /* change on quant parameter */ + MPP_ENC_SPLIT_CFG_CHANGE_MODE = (1 << 0), + MPP_ENC_SPLIT_CFG_CHANGE_ARG = (1 << 1), + MPP_ENC_SPLIT_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncSliceSplitChange; + +typedef enum MppEncSplitMode_e { + MPP_ENC_SPLIT_NONE, + MPP_ENC_SPLIT_BY_BYTE, + MPP_ENC_SPLIT_BY_CTU, +} MppEncSplitMode; + typedef struct MppEncSliceSplit_t { - RK_S32 split_en; - RK_S32 split_mode; - RK_S32 slice_size; + RK_U32 change; + + /* + * slice split mode + * + * MPP_ENC_SPLIT_NONE - No slice is split + * MPP_ENC_SPLIT_BY_BYTE - Slice is split by byte number + * MPP_ENC_SPLIT_BY_CTU - Slice is split by macroblock / ctu number + */ + RK_U32 split_mode; + + /* + * slice split size parameter + * + * When split by byte number this value is the max byte number for each + * slice. + * When split by macroblock / ctu number this value is the MB/CTU number + * for each slice. + */ + RK_U32 split_arg; } MppEncSliceSplit; typedef enum MppEncRefMode_e { diff --git a/mpp/codec/enc/h264/h264e_api_v2.c b/mpp/codec/enc/h264/h264e_api_v2.c index 4c34c832..4e06b1c1 100644 --- a/mpp/codec/enc/h264/h264e_api_v2.c +++ b/mpp/codec/enc/h264/h264e_api_v2.c @@ -395,6 +395,21 @@ static MPP_RET h264e_proc_cfg(void *ctx, MpiCmd cmd, void *param) } break; case MPP_ENC_SET_OSD_DATA_CFG : { } break; + case MPP_ENC_SET_SPLIT : { + MppEncSliceSplit *src = (MppEncSliceSplit *)param; + MppEncSliceSplit *dst = &p->cfg->split; + RK_U32 change = src->change; + + if (change & MPP_ENC_SPLIT_CFG_CHANGE_MODE) { + dst->split_mode = src->split_mode; + dst->split_arg = src->split_arg; + } + + if (change & MPP_ENC_SPLIT_CFG_CHANGE_ARG) + dst->split_arg = src->split_arg; + + dst->change |= change; + } break; default: mpp_err("No correspond cmd found, and can not config!"); ret = MPP_NOK; diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c index 49a17989..359634e6 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c @@ -704,7 +704,8 @@ static void setup_vepu541_output(Vepu541H264eRegSet *regs, MppBuffer out) static void setup_vepu541_split(Vepu541H264eRegSet *regs, MppEncSliceSplit *cfg) { - if (!cfg->split_en) { + switch (cfg->split_mode) { + case MPP_ENC_SPLIT_NONE : { regs->reg087.sli_splt = 0; regs->reg087.sli_splt_mode = 0; regs->reg087.sli_splt_cpst = 0; @@ -713,30 +714,36 @@ static void setup_vepu541_split(Vepu541H264eRegSet *regs, MppEncSliceSplit *cfg) regs->reg087.sli_splt_cnum_m1 = 0; regs->reg088.sli_splt_byte = 0; - /* */ regs->reg013.slen_fifo = 0; - - return ; - } - - regs->reg087.sli_splt = 0; - regs->reg087.sli_splt_mode = cfg->split_mode ? 1 : 0; - regs->reg087.sli_splt_cpst = 0; - regs->reg087.sli_max_num_m1 = 100; - regs->reg087.sli_flsh = 1; - - if (cfg->split_mode) { - regs->reg087.sli_splt_mode = 1; - regs->reg087.sli_splt_cnum_m1 = cfg->slice_size; - regs->reg088.sli_splt_byte = 0; - } else { - regs->reg087.sli_splt_mode = 1; + } break; + case MPP_ENC_SPLIT_BY_BYTE : { + regs->reg087.sli_splt = 1; + regs->reg087.sli_splt_mode = 0; + regs->reg087.sli_splt_cpst = 0; + regs->reg087.sli_max_num_m1 = 500; + regs->reg087.sli_flsh = 1; regs->reg087.sli_splt_cnum_m1 = 0; - regs->reg088.sli_splt_byte = cfg->slice_size; + + regs->reg088.sli_splt_byte = cfg->split_arg; + regs->reg013.slen_fifo = 0; + } break; + case MPP_ENC_SPLIT_BY_CTU : { + regs->reg087.sli_splt = 1; + regs->reg087.sli_splt_mode = 1; + regs->reg087.sli_splt_cpst = 0; + regs->reg087.sli_max_num_m1 = 500; + regs->reg087.sli_flsh = 1; + regs->reg087.sli_splt_cnum_m1 = cfg->split_arg - 1; + + regs->reg088.sli_splt_byte = 0; + regs->reg013.slen_fifo = 0; + } break; + default : { + mpp_log_f("invalide slice split mode %d\n", cfg->split_mode); + } break; } - /* NOTE when use slice split mode slen fifo should be enabled */ - regs->reg013.slen_fifo = 1; + cfg->change = 0; } static void setup_vepu541_me(Vepu541H264eRegSet *regs, SynH264eSps *sps, diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index d2b89d03..5d6ebe55 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -64,6 +64,7 @@ typedef struct { MppEncPrepCfg prep_cfg; MppEncRcCfg rc_cfg; MppEncCodecCfg codec_cfg; + MppEncSliceSplit split_cfg; // input / output MppBuffer frm_buf; @@ -194,6 +195,7 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) MppEncCodecCfg *codec_cfg; MppEncPrepCfg *prep_cfg; MppEncRcCfg *rc_cfg; + MppEncSliceSplit *split_cfg; if (NULL == p) return MPP_ERR_NULL_PTR; @@ -203,6 +205,7 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) codec_cfg = &p->codec_cfg; prep_cfg = &p->prep_cfg; rc_cfg = &p->rc_cfg; + split_cfg = &p->split_cfg; /* setup default parameter */ p->fps = 30; @@ -310,6 +313,26 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) goto RET; } + RK_U32 split_mode = 0; + RK_U32 split_arg = 0; + + mpp_env_get_u32("split_mode", &split_mode, MPP_ENC_SPLIT_NONE); + mpp_env_get_u32("split_arg", &split_arg, 0); + + if (split_mode) { + split_cfg->change = MPP_ENC_SPLIT_CFG_CHANGE_ALL; + split_cfg->split_mode = split_mode; + split_cfg->split_arg = split_arg; + + mpp_log("split_mode %d split_arg %d\n", split_mode, split_arg); + + ret = mpi->control(ctx, MPP_ENC_SET_SPLIT, split_cfg); + if (ret) { + mpp_err("mpi control enc set codec cfg failed ret %d\n", ret); + goto RET; + } + } + /* optional */ p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME; ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);