feat[mpp_enc]: Add YUV400 support for vepu580/540

Add VEPU540/580 YUV400 format support in H.264 and H.265

Change-Id: Id62102dcdc42afea5c3485224d9b4e5bf25efbac
Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
This commit is contained in:
Yanjun Liao
2023-12-06 16:58:39 +08:00
committed by Herman Chen
parent ff6032ed80
commit ccf32c1da3
13 changed files with 96 additions and 39 deletions

View File

@@ -66,6 +66,7 @@ MPP_RET h264e_sps_update(H264eSps *sps, MppEncCfgSet *cfg)
MppEncH264Cfg *h264 = &cfg->codec.h264;
MppEncRefCfg ref = cfg->ref_cfg;
MppEncCpbInfo *info = mpp_enc_ref_cfg_get_cpb_info(ref);
MppFrameFormat fmt = prep->format;
RK_S32 gop = rc->gop;
RK_S32 width = prep->width;
RK_S32 height = prep->height;
@@ -158,7 +159,7 @@ MPP_RET h264e_sps_update(H264eSps *sps, MppEncCfgSet *cfg)
sps->level_idc = level_idc;
sps->sps_id = 0;
sps->chroma_format_idc = H264_CHROMA_420;
sps->chroma_format_idc = (fmt == MPP_FMT_YUV400) ? H264_CHROMA_400 : H264_CHROMA_420;
// set max frame number and poc lsb according to gop size
sps->pic_order_cnt_type = h264->hw_cfg.hw_poc_type;
@@ -260,6 +261,8 @@ MPP_RET h264e_sps_to_packet(H264eSps *sps, MppPacket packet, RK_S32 *offset,
MppWriteCtx bit_ctx;
MppWriteCtx *bit = &bit_ctx;
RK_S32 sps_size = 0;
static const RK_U32 SubWidthC[4] = { 1, 2, 2, 1};
static const RK_U32 SubHeightC[4] = { 1, 2, 1, 1};
mpp_writer_init(bit, p, buf_size);
@@ -338,13 +341,13 @@ MPP_RET h264e_sps_to_packet(H264eSps *sps, MppPacket packet, RK_S32 *offset,
mpp_writer_put_bits(bit, sps->cropping, 1);
if (sps->cropping) {
/* frame_crop_left_offset */
mpp_writer_put_ue(bit, sps->crop.left / 2);
mpp_writer_put_ue(bit, sps->crop.left / SubWidthC[sps->chroma_format_idc]);
/* frame_crop_right_offset */
mpp_writer_put_ue(bit, sps->crop.right / 2);
mpp_writer_put_ue(bit, sps->crop.right / SubWidthC[sps->chroma_format_idc]);
/* frame_crop_top_offset */
mpp_writer_put_ue(bit, sps->crop.top / 2);
mpp_writer_put_ue(bit, sps->crop.top / SubHeightC[sps->chroma_format_idc]);
/* frame_crop_bottom_offset */
mpp_writer_put_ue(bit, sps->crop.bottom / 2);
mpp_writer_put_ue(bit, sps->crop.bottom / SubHeightC[sps->chroma_format_idc]);
}
/* vui_parameters_present_flag */

View File

@@ -244,9 +244,24 @@ void codeProfileTier(H265eStream *s, ProfileTierLevel* ptl)
h265e_stream_write1_with_log(s, ptl->m_nonPackedConstraintFlag, "general_non_packed_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_frameOnlyConstraintFlag, "general_frame_only_constraint_flag");
h265e_stream_write_with_log(s, 0, 16, "reserved_zero_44bits[0..15]");
h265e_stream_write_with_log(s, 0, 16, "reserved_zero_44bits[16..31]");
h265e_stream_write_with_log(s, 0, 12, "eserved_zero_44bits[32..43]");
if (ptl->m_profileIdc == MPP_PROFILE_HEVC_FORMAT_RANGE_EXTENDIONS) {
h265e_stream_write1_with_log(s, ptl->m_max12bitConstraintFlag , "general_max_12_bit_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_max10bitConstraintFlag, "general_max_10_bit_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_max8bitConstraintFlag, "general_max_8_bit_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_max422chromaConstraintFlag, "general_max_422chroma_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_max420chromaConstraintFlag, "general_max_420chroma_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_maxMonochromaConstraintFlag, "general_max_monochroma_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_intraConstraintFlag, "general_intra_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_onePictureConstraintFlag, "general_one_picture_constraint_flag");
h265e_stream_write1_with_log(s, ptl->m_lowerBitRateConstraintFlag, "general_lower_bit_rate_constraint_flag");
h265e_stream_write_with_log(s, 0, 16, "reserved_zero_35bits[0..15]");
h265e_stream_write_with_log(s, 0, 16, "reserved_zero_35bits[16..31]");
h265e_stream_write_with_log(s, 0, 3, "eserved_zero_35bits[32..34]");
} else {
h265e_stream_write_with_log(s, 0, 16, "reserved_zero_44bits[0..15]");
h265e_stream_write_with_log(s, 0, 16, "reserved_zero_44bits[16..31]");
h265e_stream_write_with_log(s, 0, 12, "eserved_zero_44bits[32..43]");
}
}
void codePTL(H265eStream *s, H265ePTL* ptl, RK_U32 profilePresentFlag, int maxNumSubLayersMinus1)

View File

@@ -150,11 +150,24 @@ MPP_RET h265e_set_vps(H265eCtx *ctx, H265eVps *vps)
profileTierLevel->m_levelIdc = codec->level;
}
profileTierLevel->m_tierFlag = codec->tier ? 1 : 0;
if (prep->format == MPP_FMT_YUV400) {
/* general_profile_idc == 4 */
codec->profile = MPP_PROFILE_HEVC_FORMAT_RANGE_EXTENDIONS;
profileTierLevel->m_max12bitConstraintFlag = 1;
profileTierLevel->m_max10bitConstraintFlag = 1;
profileTierLevel->m_max8bitConstraintFlag = 1;
profileTierLevel->m_max422chromaConstraintFlag = 1;
profileTierLevel->m_max420chromaConstraintFlag = 1;
profileTierLevel->m_maxMonochromaConstraintFlag = 1;
profileTierLevel->m_lowerBitRateConstraintFlag = 1;
} else {
/* general_profile_idc == 2 */
profileTierLevel->m_profileCompatibilityFlag[2] = 1;
}
profileTierLevel->m_profileIdc = codec->profile;
profileTierLevel->m_profileCompatibilityFlag[codec->profile] = 1;
profileTierLevel->m_profileCompatibilityFlag[2] = 1;
profileTierLevel->m_progressiveSourceFlag = 1;
profileTierLevel->m_nonPackedConstraintFlag = 0;
profileTierLevel->m_frameOnlyConstraintFlag = 0;
@@ -169,6 +182,7 @@ MPP_RET h265e_set_sps(H265eCtx *ctx, H265eSps *sps, H265eVps *vps)
MppEncRcCfg *rc = &ctx->cfg->rc;
MppEncRefCfg ref_cfg = ctx->cfg->ref_cfg;
MppEncH265VuiCfg *vui = &codec->vui;
MppFrameFormat fmt = prep->format;
RK_S32 i_timebase_num = rc->fps_out_denorm;
RK_S32 i_timebase_den = rc->fps_out_num;
RK_U8 convertToBit[MAX_CU_SIZE + 1];
@@ -230,7 +244,7 @@ MPP_RET h265e_set_sps(H265eCtx *ctx, H265eSps *sps, H265eVps *vps)
sps->m_SPSId = 0;
sps->m_VPSId = 0;
sps->m_chromaFormatIdc = 0x1; //RKVE_CSP2_I420;
sps->m_chromaFormatIdc = (fmt == MPP_FMT_YUV400) ? H265_CHROMA_400 : H265_CHROMA_420;
sps->m_maxTLayers = 1;
sps->m_picWidthInLumaSamples = prep->width + pad[0];
sps->m_picHeightInLumaSamples = prep->height + pad[1];

View File

@@ -211,6 +211,7 @@ void h265e_slice_init(void *ctx, EncFrmStatus curr)
H265ePps *pps = &p->pps;
MppEncCfgSet *cfg = p->cfg;
MppEncH265Cfg *codec = &cfg->codec.h265;
MppEncPrepCfg *prep_cfg = &cfg->prep;
H265eSlice *slice = p->dpb->curr->slice;
p->slice = p->dpb->curr->slice;
h265e_dbg_func("enter\n");
@@ -256,7 +257,8 @@ void h265e_slice_init(void *ctx, EncFrmStatus curr)
slice->m_deblockingFilterTcOffsetDiv2 = pps->m_deblockingFilterTcOffsetDiv2;
}
slice->m_saoEnabledFlag = !codec->sao_cfg.slice_sao_luma_disable;
slice->m_saoEnabledFlagChroma = !codec->sao_cfg.slice_sao_chroma_disable;
slice->m_saoEnabledFlagChroma = (prep_cfg->format == MPP_FMT_YUV400) ? 0 :
!codec->sao_cfg.slice_sao_chroma_disable;
slice->m_maxNumMergeCand = codec->merge_cfg.max_mrg_cnd;
slice->m_cabacInitFlag = codec->entropy_cfg.cabac_init_flag;
slice->m_picOutputFlag = 1;

View File

@@ -93,6 +93,15 @@ typedef struct ProfileTierLevel_e {
RK_S32 m_interlacedSourceFlag;
RK_S32 m_nonPackedConstraintFlag;
RK_S32 m_frameOnlyConstraintFlag;
RK_S32 m_max12bitConstraintFlag;
RK_S32 m_max10bitConstraintFlag;
RK_S32 m_max8bitConstraintFlag;
RK_S32 m_max422chromaConstraintFlag;
RK_S32 m_max420chromaConstraintFlag;
RK_S32 m_maxMonochromaConstraintFlag;
RK_S32 m_intraConstraintFlag;
RK_S32 m_onePictureConstraintFlag;
RK_S32 m_lowerBitRateConstraintFlag;
} ProfileTierLevel;
typedef struct H265ePTL_e {

View File

@@ -109,6 +109,7 @@
#define MPP_PROFILE_HEVC_MAIN 1
#define MPP_PROFILE_HEVC_MAIN_10 2
#define MPP_PROFILE_HEVC_MAIN_STILL_PICTURE 3
#define MPP_PROFILE_HEVC_FORMAT_RANGE_EXTENDIONS 4
#define LOG2_MAX_CTB_SIZE 6
#define LOG2_MIN_CTB_SIZE 4
@@ -168,22 +169,6 @@ typedef enum H265NalPriority_t {
H265_NAL_PRIORITY_HIGHEST = 3,
} H265NalPriority;
enum RPSType {
ST_CURR_BEF = 0,
ST_CURR_AFT,
ST_FOLL,
LT_CURR,
LT_FOLL,
NB_RPS_TYPE,
};
typedef enum SliceType_t {
B_SLICE = 0,
P_SLICE = 1,
I_SLICE = 2,
} SliceType;
typedef enum {
H265_LEVEL_NONE = 0,
H265_LEVEL1 = 30,
@@ -202,4 +187,26 @@ typedef enum {
H265_LEVEL8_5 = 255,
} H265Level;
typedef enum H265ChromaFmt_e {
H265_CHROMA_400 = 0, //!< Monochrome
H265_CHROMA_420 = 1, //!< 4:2:0
H265_CHROMA_422 = 2, //!< 4:2:2
H265_CHROMA_444 = 3 //!< 4:4:4
} H265ChromaFmt;
typedef enum SliceType_t {
B_SLICE = 0,
P_SLICE = 1,
I_SLICE = 2,
} SliceType;
enum RPSType {
ST_CURR_BEF = 0,
ST_CURR_AFT,
ST_FOLL,
LT_CURR,
LT_FOLL,
NB_RPS_TYPE,
};
#endif

View File

@@ -136,7 +136,7 @@ static VepuFmtCfg vepu541_yuv_cfg[MPP_FMT_YUV_BUTT] = {
.offset = zeros,
},
{ /* MPP_FMT_YUV400 */
.format = VEPU541_FMT_NONE,
.format = VEPU540_FMT_YUV400,
.alpha_swap = 0,
.rbuv_swap = 0,
.src_range = 1,

View File

@@ -479,7 +479,7 @@ static MPP_RET setup_vepu540c_prep(HalVepu540cRegSet *regs, MppEncPrepCfg *prep)
regs->reg_base.src_fmt.src_cfmt = hw_fmt;
regs->reg_base.src_fmt.alpha_swap = cfg.alpha_swap;
regs->reg_base.src_fmt.rbuv_swap = cfg.rbuv_swap;
regs->reg_base.src_fmt.out_fmt = 1;
regs->reg_base.src_fmt.out_fmt = (fmt == MPP_FMT_YUV400) ? 0 : 1;
y_stride = (MPP_FRAME_FMT_IS_FBC(fmt)) ? (MPP_ALIGN(prep->width, 16)) :
(prep->hor_stride) ? (prep->hor_stride) : (prep->width);
@@ -1037,6 +1037,7 @@ static void setup_vepu540c_io_buf(HalVepu540cRegSet *regs, MppDev dev,
off_in[0] = hor_stride * ver_stride;
off_in[1] = hor_stride * ver_stride * 5 / 4;
} break;
case VEPU540_FMT_YUV400 :
case VEPU541_FMT_YUYV422 :
case VEPU541_FMT_UYVY422 : {
off_in[0] = 0;

View File

@@ -473,7 +473,7 @@ static MPP_RET setup_vepu541_prep(Vepu541H264eRegSet *regs, MppEncPrepCfg *prep,
regs->reg017.alpha_swap = cfg.alpha_swap;
regs->reg017.rbuv_swap = cfg.rbuv_swap;
regs->reg017.src_range = cfg.src_range;
regs->reg017.out_fmt_cfg = 0;
regs->reg017.out_fmt_cfg = (fmt == MPP_FMT_YUV400) ? 1 : 0;
if (MPP_FRAME_FMT_IS_FBC(fmt)) {
y_stride = mpp_frame_get_fbc_hdr_stride(task->frame);
@@ -948,6 +948,7 @@ static void setup_vepu541_io_buf(Vepu541H264eRegSet *regs, MppDev dev,
off_in[0] = hor_stride * ver_stride;
off_in[1] = hor_stride * ver_stride * 5 / 4;
} break;
case VEPU540_FMT_YUV400 :
case VEPU541_FMT_YUYV422 :
case VEPU541_FMT_UYVY422 : {
off_in[0] = 0;

View File

@@ -712,8 +712,8 @@ static MPP_RET setup_vepu580_prep(HalVepu580RegSet *regs, MppEncPrepCfg *prep,
regs->reg_base.src_fmt.src_cfmt = hw_fmt;
regs->reg_base.src_fmt.alpha_swap = cfg.alpha_swap;
regs->reg_base.src_fmt.rbuv_swap = cfg.rbuv_swap;
regs->reg_base.src_fmt.src_range = (prep->range == MPP_FRAME_RANGE_JPEG ? 1 : 0);
regs->reg_base.src_fmt.out_fmt = 1;
regs->reg_base.src_fmt.src_range = (prep->range == MPP_FRAME_RANGE_JPEG) ? 1 : 0;
regs->reg_base.src_fmt.out_fmt = (fmt == MPP_FMT_YUV400) ? 0 : 1;
if (MPP_FRAME_FMT_IS_FBC(fmt)) {
y_stride = mpp_frame_get_fbc_hdr_stride(task->frame);
@@ -1383,6 +1383,7 @@ static void setup_vepu580_io_buf(HalVepu580RegSet *regs, MppDevRegOffCfgs *offse
off_in[0] = hor_stride * ver_stride;
off_in[1] = hor_stride * ver_stride * 5 / 4;
} break;
case VEPU540_FMT_YUV400 :
case VEPU541_FMT_YUYV422 :
case VEPU541_FMT_UYVY422 : {
off_in[0] = 0;

View File

@@ -142,6 +142,8 @@ static MPP_RET vepu540c_h265_setup_hal_bufs(H265eV540cHalContext *ctx)
vepu541_set_fmt(fmt, ctx->cfg->prep.format);
input_fmt = (Vepu541Fmt)fmt->format;
switch (input_fmt) {
case VEPU540_FMT_YUV400:
break;
case VEPU541_FMT_YUV420P:
case VEPU541_FMT_YUV420SP: {
frame_size = frame_size * 3 / 2;
@@ -639,6 +641,7 @@ vepu540c_h265_set_patch_info(MppDev dev, H265eSyntax_new *syn, Vepu541Fmt input_
u_offset = frame_size;
v_offset = frame_size * 3 / 2;
} break;
case VEPU540_FMT_YUV400:
case VEPU541_FMT_YUYV422:
case VEPU541_FMT_UYVY422: {
u_offset = 0;
@@ -807,9 +810,7 @@ static MPP_RET vepu540c_h265_set_pp_regs(H265eV540cRegSet *regs, VepuFmtCfg *fmt
reg_base->reg0198_src_fmt.alpha_swap = fmt->alpha_swap;
reg_base->reg0198_src_fmt.rbuv_swap = fmt->rbuv_swap;
// reg_base->reg0198_src_fmt.src_range = fmt->src_range;
reg_base->reg0198_src_fmt.out_fmt = 1;
reg_base->reg0198_src_fmt.out_fmt = (prep_cfg->format == MPP_FMT_YUV400) ? 0 : 1;
reg_base->reg0203_src_proc.src_mirr = prep_cfg->mirroring > 0;
reg_base->reg0203_src_proc.src_rot = prep_cfg->rotation;

View File

@@ -163,6 +163,8 @@ static MPP_RET vepu54x_h265_setup_hal_bufs(H265eV541HalContext *ctx)
vepu541_set_fmt(fmt, ctx->cfg->prep.format);
input_fmt = (Vepu541Fmt)fmt->format;
switch (input_fmt) {
case VEPU540_FMT_YUV400:
break;
case VEPU541_FMT_YUV420P:
case VEPU541_FMT_YUV420SP: {
frame_size = frame_size * 3 / 2;

View File

@@ -1604,6 +1604,7 @@ vepu580_h265_set_patch_info(MppDevRegOffCfgs *cfgs, H265eSyntax_new *syn,
u_offset = frame_size;
v_offset = frame_size * 3 / 2;
} break;
case VEPU540_FMT_YUV400:
case VEPU541_FMT_YUYV422:
case VEPU541_FMT_UYVY422: {
u_offset = 0;
@@ -1932,8 +1933,8 @@ static MPP_RET vepu580_h265_set_pp_regs(H265eV580RegSet *regs, VepuFmtCfg *fmt,
reg_base->reg0198_src_fmt.src_cfmt = fmt->format;
reg_base->reg0198_src_fmt.alpha_swap = fmt->alpha_swap;
reg_base->reg0198_src_fmt.rbuv_swap = fmt->rbuv_swap;
reg_base->reg0198_src_fmt.src_range = (prep_cfg->range == MPP_FRAME_RANGE_JPEG ? 1 : 0);
reg_base->reg0198_src_fmt.out_fmt = 1;
reg_base->reg0198_src_fmt.src_range = (prep_cfg->range == MPP_FRAME_RANGE_JPEG) ? 1 : 0;
reg_base->reg0198_src_fmt.out_fmt = (prep_cfg->format == MPP_FMT_YUV400) ? 0 : 1;
reg_base->reg0203_src_proc.src_mirr = prep_cfg->mirroring > 0;
reg_base->reg0203_src_proc.src_rot = prep_cfg->rotation;