mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-16 14:11:10 +08:00
[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:
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
} 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 = 100;
|
||||
regs->reg087.sli_max_num_m1 = 500;
|
||||
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->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,
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user