[h264e]: Add slice split function

Slice split has two modes: split by byte and split by CTU number.

Change-Id: Id5a07f8a8cae612b6b913e9cb747dacec5b8e5a2
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2020-03-06 09:32:31 +08:00
parent 73ec7df421
commit 6cee8bb11a
4 changed files with 99 additions and 24 deletions

View File

@@ -954,10 +954,40 @@ typedef struct MppEncCodecCfg_t {
}; };
} MppEncCodecCfg; } 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 { typedef struct MppEncSliceSplit_t {
RK_S32 split_en; RK_U32 change;
RK_S32 split_mode;
RK_S32 slice_size; /*
* 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; } MppEncSliceSplit;
typedef enum MppEncRefMode_e { typedef enum MppEncRefMode_e {

View File

@@ -395,6 +395,21 @@ static MPP_RET h264e_proc_cfg(void *ctx, MpiCmd cmd, void *param)
} break; } break;
case MPP_ENC_SET_OSD_DATA_CFG : { case MPP_ENC_SET_OSD_DATA_CFG : {
} break; } 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: default:
mpp_err("No correspond cmd found, and can not config!"); mpp_err("No correspond cmd found, and can not config!");
ret = MPP_NOK; ret = MPP_NOK;

View File

@@ -704,7 +704,8 @@ static void setup_vepu541_output(Vepu541H264eRegSet *regs, MppBuffer out)
static void setup_vepu541_split(Vepu541H264eRegSet *regs, MppEncSliceSplit *cfg) 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 = 0;
regs->reg087.sli_splt_mode = 0; regs->reg087.sli_splt_mode = 0;
regs->reg087.sli_splt_cpst = 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->reg087.sli_splt_cnum_m1 = 0;
regs->reg088.sli_splt_byte = 0; regs->reg088.sli_splt_byte = 0;
/* */
regs->reg013.slen_fifo = 0; regs->reg013.slen_fifo = 0;
} break;
return ; case MPP_ENC_SPLIT_BY_BYTE : {
} regs->reg087.sli_splt = 1;
regs->reg087.sli_splt_mode = 0;
regs->reg087.sli_splt = 0; regs->reg087.sli_splt_cpst = 0;
regs->reg087.sli_splt_mode = cfg->split_mode ? 1 : 0; regs->reg087.sli_max_num_m1 = 500;
regs->reg087.sli_splt_cpst = 0; regs->reg087.sli_flsh = 1;
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;
regs->reg087.sli_splt_cnum_m1 = 0; 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 */ cfg->change = 0;
regs->reg013.slen_fifo = 1;
} }
static void setup_vepu541_me(Vepu541H264eRegSet *regs, SynH264eSps *sps, static void setup_vepu541_me(Vepu541H264eRegSet *regs, SynH264eSps *sps,

View File

@@ -64,6 +64,7 @@ typedef struct {
MppEncPrepCfg prep_cfg; MppEncPrepCfg prep_cfg;
MppEncRcCfg rc_cfg; MppEncRcCfg rc_cfg;
MppEncCodecCfg codec_cfg; MppEncCodecCfg codec_cfg;
MppEncSliceSplit split_cfg;
// input / output // input / output
MppBuffer frm_buf; MppBuffer frm_buf;
@@ -194,6 +195,7 @@ MPP_RET test_mpp_setup(MpiEncTestData *p)
MppEncCodecCfg *codec_cfg; MppEncCodecCfg *codec_cfg;
MppEncPrepCfg *prep_cfg; MppEncPrepCfg *prep_cfg;
MppEncRcCfg *rc_cfg; MppEncRcCfg *rc_cfg;
MppEncSliceSplit *split_cfg;
if (NULL == p) if (NULL == p)
return MPP_ERR_NULL_PTR; return MPP_ERR_NULL_PTR;
@@ -203,6 +205,7 @@ MPP_RET test_mpp_setup(MpiEncTestData *p)
codec_cfg = &p->codec_cfg; codec_cfg = &p->codec_cfg;
prep_cfg = &p->prep_cfg; prep_cfg = &p->prep_cfg;
rc_cfg = &p->rc_cfg; rc_cfg = &p->rc_cfg;
split_cfg = &p->split_cfg;
/* setup default parameter */ /* setup default parameter */
p->fps = 30; p->fps = 30;
@@ -310,6 +313,26 @@ MPP_RET test_mpp_setup(MpiEncTestData *p)
goto RET; 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 */ /* optional */
p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME; p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode); ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);