diff --git a/inc/rk_venc_cmd.h b/inc/rk_venc_cmd.h index 11f3f418..ca34086a 100644 --- a/inc/rk_venc_cmd.h +++ b/inc/rk_venc_cmd.h @@ -506,6 +506,12 @@ typedef enum MppEncH264CfgChange_e { MPP_ENC_H264_CFG_CHANGE_LONG_TERM = (1 << 8), /* change on scaling_list_mode */ MPP_ENC_H264_CFG_CHANGE_SCALING_LIST = (1 << 9), + /* change on poc type */ + MPP_ENC_H264_CFG_CHANGE_POC_TYPE = (1 << 10), + /* change on log2 max poc lsb minus 4 */ + MPP_ENC_H264_CFG_CHANGE_MAX_POC_LSB = (1 << 11), + /* change on log2 max frame number minus 4 */ + MPP_ENC_H264_CFG_CHANGE_MAX_FRM_NUM = (1 << 12), /* change on max_qp / min_qp / max_qp_step */ MPP_ENC_H264_CFG_CHANGE_QP_LIMIT = (1 << 16), @@ -535,8 +541,19 @@ typedef struct MppEncH264Cfg_t { */ RK_S32 stream_type; - /* H.264 codec syntax config */ - RK_S32 svc; /* 0 - avc 1 - svc */ + /* + * H.264 codec syntax config + * svc - deprecated, reserved for compile compatibility + * + * do NOT setup the three option below unless you are familiar with encoder detail + * poc_type - picture order count type 0 ~ 2 + * log2_max_poc_lsb - used in sps with poc_type 0, + * log2_max_frame_num - used in sps + */ + RK_U8 svc; + RK_U8 poc_type; + RK_U8 log2_max_poc_lsb; + RK_U8 log2_max_frame_num; /* * H.264 profile_idc parameter diff --git a/mpp/base/mpp_enc_cfg.cpp b/mpp/base/mpp_enc_cfg.cpp index 75edb968..982db658 100644 --- a/mpp/base/mpp_enc_cfg.cpp +++ b/mpp/base/mpp_enc_cfg.cpp @@ -178,6 +178,9 @@ static const char *cfg_func_names[] = { ENTRY(h264, stream_type, S32, RK_S32, MPP_ENC_H264_CFG_STREAM_TYPE, codec.h264, stream_type) \ ENTRY(h264, profile, S32, RK_S32, MPP_ENC_H264_CFG_CHANGE_PROFILE, codec.h264, profile) \ ENTRY(h264, level, S32, RK_S32, MPP_ENC_H264_CFG_CHANGE_PROFILE, codec.h264, level) \ + ENTRY(h264, poc_type, U32, RK_U32, MPP_ENC_H264_CFG_CHANGE_POC_TYPE, codec.h264, poc_type) \ + ENTRY(h264, log2_max_poc_lsb, U32, RK_U32, MPP_ENC_H264_CFG_CHANGE_MAX_POC_LSB, codec.h264, log2_max_poc_lsb) \ + ENTRY(h264, log2_max_frm_num, U32, RK_U32, MPP_ENC_H264_CFG_CHANGE_MAX_FRM_NUM, codec.h264, log2_max_frame_num) \ ENTRY(h264, cabac_en, S32, RK_S32, MPP_ENC_H264_CFG_CHANGE_ENTROPY, codec.h264, entropy_coding_mode) \ ENTRY(h264, cabac_idc, S32, RK_S32, MPP_ENC_H264_CFG_CHANGE_ENTROPY, codec.h264, cabac_init_idc) \ ENTRY(h264, trans8x8, S32, RK_S32, MPP_ENC_H264_CFG_CHANGE_TRANS_8x8, codec.h264, transform8x8_mode) \ @@ -236,7 +239,7 @@ RK_S32 const_strlen(const char* str) return *str ? 1 + const_strlen(str + 1) : 0; } -static RK_S32 node_len = ENTRY_TABLE(EXPAND_AS_STRLEN) - 23; +static RK_S32 node_len = ENTRY_TABLE(EXPAND_AS_STRLEN) - 21; class MppEncCfgService { diff --git a/mpp/codec/enc/h264/h264e_api_v2.c b/mpp/codec/enc/h264/h264e_api_v2.c index d6335b37..3bcf59ee 100644 --- a/mpp/codec/enc/h264/h264e_api_v2.c +++ b/mpp/codec/enc/h264/h264e_api_v2.c @@ -83,7 +83,7 @@ typedef struct { H264eSyntaxDesc syntax[H264E_SYN_BUTT]; } H264eCtx; -static void init_h264e_cfg_set(MppEncCfgSet *cfg) +static void init_h264e_cfg_set(MppEncCfgSet *cfg, MppDeviceId dev_id) { MppEncRcCfg *rc_cfg = &cfg->rc; MppEncPrepCfg *prep = &cfg->prep; @@ -103,6 +103,24 @@ static void init_h264e_cfg_set(MppEncCfgSet *cfg) h264->qp_min = 8; h264->qp_max_step = 8; + switch (dev_id) { + case DEV_VEPU : { + h264->poc_type = 2; + h264->log2_max_poc_lsb = 12; + h264->log2_max_frame_num = 12; + } break; + case DEV_RKVENC : { + h264->poc_type = 0; + h264->log2_max_poc_lsb = 12; + h264->log2_max_frame_num = 12; + } break; + default : { + h264->poc_type = 0; + h264->log2_max_poc_lsb = 12; + h264->log2_max_frame_num = 12; + } break; + } + /* * default prep: * 720p @@ -174,7 +192,7 @@ static MPP_RET h264e_init(void *ctx, EncImplCfg *ctrl_cfg) h264e_dpb_init(&p->dpb, &p->reorder, &p->marking); h264e_slice_init(&p->slice, &p->reorder, &p->marking); - init_h264e_cfg_set(p->cfg); + init_h264e_cfg_set(p->cfg, p->dev_id); mpp_env_get_u32("h264e_debug", &h264e_debug, 0); @@ -354,6 +372,21 @@ static MPP_RET h264e_proc_h264_cfg(MppEncH264Cfg *dst, MppEncH264Cfg *src) dst->level = src->level; dst->change |= MPP_ENC_H264_CFG_CHANGE_PROFILE; } + if ((change & MPP_ENC_H264_CFG_CHANGE_POC_TYPE) && + (dst->poc_type != src->poc_type)) { + dst->poc_type = src->poc_type; + dst->change |= MPP_ENC_H264_CFG_CHANGE_POC_TYPE; + } + if ((change & MPP_ENC_H264_CFG_CHANGE_MAX_POC_LSB) && + (dst->log2_max_poc_lsb != src->log2_max_poc_lsb)) { + dst->log2_max_poc_lsb = src->log2_max_poc_lsb; + dst->change |= MPP_ENC_H264_CFG_CHANGE_MAX_POC_LSB; + } + if ((change & MPP_ENC_H264_CFG_CHANGE_MAX_FRM_NUM) && + (dst->log2_max_frame_num != src->log2_max_frame_num)) { + dst->log2_max_frame_num = src->log2_max_frame_num; + dst->change |= MPP_ENC_H264_CFG_CHANGE_MAX_FRM_NUM; + } if ((change & MPP_ENC_H264_CFG_CHANGE_ENTROPY) && ((dst->entropy_coding_mode != src->entropy_coding_mode) || (dst->cabac_init_idc != src->cabac_init_idc))) { @@ -525,7 +558,7 @@ static MPP_RET h264e_gen_hdr(void *ctx, MppPacket pkt) h264e_dbg_func("enter\n"); - h264e_sps_update(&p->sps, p->cfg, p->dev_id); + h264e_sps_update(&p->sps, p->cfg); h264e_pps_update(&p->pps, p->cfg); /* diff --git a/mpp/codec/enc/h264/h264e_sps.c b/mpp/codec/enc/h264/h264e_sps.c index f429e128..189f80a6 100644 --- a/mpp/codec/enc/h264/h264e_sps.c +++ b/mpp/codec/enc/h264/h264e_sps.c @@ -58,7 +58,7 @@ H264eLevelInfo level_infos[] = { { H264_LEVEL_6_2, 16711680, 139264, 696320, 800000, "6.2" }, }; -MPP_RET h264e_sps_update(SynH264eSps *sps, MppEncCfgSet *cfg, MppDeviceId dev) +MPP_RET h264e_sps_update(SynH264eSps *sps, MppEncCfgSet *cfg) { SynH264eVui *vui = &sps->vui; MppEncPrepCfg *prep = &cfg->prep; @@ -112,6 +112,10 @@ MPP_RET h264e_sps_update(SynH264eSps *sps, MppEncCfgSet *cfg, MppDeviceId dev) sps->chroma_format_idc = H264_CHROMA_420; // set max frame number and poc lsb according to gop size + sps->pic_order_cnt_type = h264->poc_type; + sps->log2_max_poc_lsb_minus4 = h264->log2_max_poc_lsb; + sps->log2_max_frame_num_minus4 = h264->log2_max_frame_num; + mpp_assert(gop >= 0); if (gop == 0) { // only one I then all P frame @@ -124,22 +128,14 @@ MPP_RET h264e_sps_update(SynH264eSps *sps, MppEncCfgSet *cfg, MppDeviceId dev) } else { // normal case RK_S32 log2_gop = mpp_log2(gop); + RK_S32 log2_frm_num = (log2_gop <= 4) ? (0) : (log2_gop - 4); + RK_S32 log2_poc_lsb = (log2_gop <= 3) ? (0) : (log2_gop - 3); - sps->log2_max_frame_num_minus4 = (log2_gop <= 4) ? (0) : (log2_gop - 4); - sps->log2_max_poc_lsb_minus4 = (log2_gop <= 3) ? (0) : (log2_gop - 3); - } + if (sps->log2_max_frame_num_minus4 < log2_frm_num) + sps->log2_max_frame_num_minus4 = log2_frm_num; - // default poc_type 0 - sps->pic_order_cnt_type = 0; - if (dev == DEV_VEPU) { - // VEPU hardware default poc_type is 2 - sps->pic_order_cnt_type = 2; - sps->log2_max_frame_num_minus4 = 12; - } - // NOTE: when tsvc mode enabled poc type should be zero. - if (info->dpb_size > 1) { - sps->pic_order_cnt_type = 0; - sps->log2_max_frame_num_minus4 = 12; + if (sps->log2_max_poc_lsb_minus4 < log2_poc_lsb) + sps->log2_max_poc_lsb_minus4 = log2_poc_lsb; } // max one reference frame diff --git a/mpp/codec/enc/h264/h264e_sps.h b/mpp/codec/enc/h264/h264e_sps.h index a7e5a31c..64539960 100644 --- a/mpp/codec/enc/h264/h264e_sps.h +++ b/mpp/codec/enc/h264/h264e_sps.h @@ -17,8 +17,6 @@ #ifndef __H264E_SPS_H__ #define __H264E_SPS_H__ -#include "mpp_platform.h" - #include "mpp_packet.h" #include "mpp_enc_cfg.h" @@ -28,7 +26,7 @@ extern "C" { #endif -MPP_RET h264e_sps_update(SynH264eSps *sps, MppEncCfgSet *cfg, MppDeviceId dev); +MPP_RET h264e_sps_update(SynH264eSps *sps, MppEncCfgSet *cfg); MPP_RET h264e_sps_to_packet(SynH264eSps *sps, MppPacket packet, RK_S32 *len); MPP_RET h264e_sps_dump(SynH264eSps *sps);