diff --git a/mpp/codec/enc/h264/h264e_sps.c b/mpp/codec/enc/h264/h264e_sps.c index 0d282f8d..ca68f85b 100644 --- a/mpp/codec/enc/h264/h264e_sps.c +++ b/mpp/codec/enc/h264/h264e_sps.c @@ -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 */ diff --git a/mpp/codec/enc/h265/h265e_header_gen.c b/mpp/codec/enc/h265/h265e_header_gen.c index 19c1a163..41b71b40 100644 --- a/mpp/codec/enc/h265/h265e_header_gen.c +++ b/mpp/codec/enc/h265/h265e_header_gen.c @@ -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) diff --git a/mpp/codec/enc/h265/h265e_ps.c b/mpp/codec/enc/h265/h265e_ps.c index 6fdc2202..0e76e8d1 100644 --- a/mpp/codec/enc/h265/h265e_ps.c +++ b/mpp/codec/enc/h265/h265e_ps.c @@ -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]; diff --git a/mpp/codec/enc/h265/h265e_slice.c b/mpp/codec/enc/h265/h265e_slice.c index 44dc8643..acd3f120 100644 --- a/mpp/codec/enc/h265/h265e_slice.c +++ b/mpp/codec/enc/h265/h265e_slice.c @@ -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; diff --git a/mpp/codec/enc/h265/h265e_slice.h b/mpp/codec/enc/h265/h265e_slice.h index eb68001b..47b4d954 100644 --- a/mpp/codec/enc/h265/h265e_slice.h +++ b/mpp/codec/enc/h265/h265e_slice.h @@ -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 { diff --git a/mpp/common/h265_syntax.h b/mpp/common/h265_syntax.h index 5482050f..48f23afc 100644 --- a/mpp/common/h265_syntax.h +++ b/mpp/common/h265_syntax.h @@ -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 diff --git a/mpp/hal/rkenc/common/vepu541_common.c b/mpp/hal/rkenc/common/vepu541_common.c index 303586d6..eacc9935 100644 --- a/mpp/hal/rkenc/common/vepu541_common.c +++ b/mpp/hal/rkenc/common/vepu541_common.c @@ -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, diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu540c.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu540c.c index ad70e5f7..fb19d83b 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu540c.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu540c.c @@ -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; diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c index 0d102f25..f3eb8a44 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c @@ -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; diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c index 772b7c7b..e560e6af 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c @@ -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; diff --git a/mpp/hal/rkenc/h265e/hal_h265e_vepu540c.c b/mpp/hal/rkenc/h265e/hal_h265e_vepu540c.c index 90690db2..4c8f5843 100644 --- a/mpp/hal/rkenc/h265e/hal_h265e_vepu540c.c +++ b/mpp/hal/rkenc/h265e/hal_h265e_vepu540c.c @@ -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; diff --git a/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c b/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c index 76d7393d..43922016 100644 --- a/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c +++ b/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c @@ -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; diff --git a/mpp/hal/rkenc/h265e/hal_h265e_vepu580.c b/mpp/hal/rkenc/h265e/hal_h265e_vepu580.c index ca4104c5..7e3d7318 100644 --- a/mpp/hal/rkenc/h265e/hal_h265e_vepu580.c +++ b/mpp/hal/rkenc/h265e/hal_h265e_vepu580.c @@ -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;