mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-15 21:50:37 +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;
|
} 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 {
|
||||||
|
@@ -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;
|
||||||
|
@@ -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_mode = cfg->split_mode ? 1 : 0;
|
|
||||||
regs->reg087.sli_splt_cpst = 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;
|
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,
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user