feat[h265e]: Support force mark & use ltr

Change-Id: Ied10ca664f149a75ebc02733f884ffeb41449c4f
Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
This commit is contained in:
Yanjun Liao
2024-06-27 15:31:14 +08:00
committed by Herman Chen
parent ddafef8e65
commit fa97ca3dba
6 changed files with 145 additions and 20 deletions

View File

@@ -991,6 +991,9 @@ typedef enum MppEncH265CfgChange_e {
MPP_ENC_H265_CFG_TILE_LPFACS_CHANGE = (1 << 24),
MPP_ENC_H265_CFG_CHANGE_CONST_INTRA = (1 << 25),
MPP_ENC_H265_CFG_CHANGE_LCU_SIZE = (1 << 26),
MPP_ENC_H265_CFG_CHANGE_MAX_TID = (1 << 27),
MPP_ENC_H265_CFG_CHANGE_MAX_LTR = (1 << 28),
MPP_ENC_H265_CFG_CHANGE_BASE_LAYER_PID = (1 << 29),
MPP_ENC_H265_CFG_CHANGE_ALL = (0xFFFFFFFF),
} MppEncH265CfgChange;
@@ -1096,6 +1099,11 @@ typedef struct MppEncH265Cfg_t {
RK_S32 intra_refresh_mode;
RK_S32 intra_refresh_arg;
/* extra mode config */
RK_S32 max_ltr_frames;
RK_S32 max_tid;
RK_S32 base_layer_pid;
/* slice mode config */
RK_S32 independ_slice_mode;
RK_S32 independ_slice_arg;

View File

@@ -246,6 +246,9 @@ public:
ENTRY(h265, lpf_acs_sli_en, U32, RK_U32, MPP_ENC_H265_CFG_SLICE_LPFACS_CHANGE, codec.h265, lpf_acs_sli_en) \
ENTRY(h265, lpf_acs_tile_disable, U32, RK_U32, MPP_ENC_H265_CFG_TILE_LPFACS_CHANGE, codec.h265, lpf_acs_tile_disable) \
ENTRY(h265, auto_tile, S32, RK_S32, MPP_ENC_H265_CFG_TILE_CHANGE, codec.h265, auto_tile) \
ENTRY(h265, max_tid, S32, RK_S32, MPP_ENC_H265_CFG_CHANGE_MAX_TID, codec.h265, max_tid) \
ENTRY(h265, max_ltr, S32, RK_S32, MPP_ENC_H265_CFG_CHANGE_MAX_LTR, codec.h265, max_ltr_frames) \
ENTRY(h265, base_layer_pid, S32, RK_S32, MPP_ENC_H265_CFG_CHANGE_BASE_LAYER_PID, codec.h265, base_layer_pid) \
ENTRY(h265, const_intra, S32, RK_S32, MPP_ENC_H265_CFG_CHANGE_CONST_INTRA, codec.h265, const_intra_pred) \
ENTRY(h265, lcu_size, S32, RK_S32, MPP_ENC_H265_CFG_CHANGE_LCU_SIZE, codec.h265, max_cu_size) \
/* vp8 config */ \

View File

@@ -224,10 +224,49 @@ static MPP_RET h265e_gen_hdr(void *ctx, MppPacket pkt)
static MPP_RET h265e_start(void *ctx, HalEncTask *task)
{
H265eCtx *p = (H265eCtx *)ctx;
(void) p;
h265e_dbg_func("enter\n");
if (mpp_frame_has_meta(task->frame)) {
MppEncRefFrmUsrCfg *frm_cfg = task->frm_cfg;
EncRcForceCfg *rc_force = &task->rc_task->force;
MppMeta meta = mpp_frame_get_meta(task->frame);
RK_S32 force_lt_idx = -1;
RK_S32 force_use_lt_idx = -1;
RK_S32 force_frame_qp = -1;
RK_S32 base_layer_pid = -1;
mpp_meta_get_s32(meta, KEY_ENC_MARK_LTR, &force_lt_idx);
mpp_meta_get_s32(meta, KEY_ENC_USE_LTR, &force_use_lt_idx);
mpp_meta_get_s32(meta, KEY_ENC_FRAME_QP, &force_frame_qp);
mpp_meta_get_s32(meta, KEY_ENC_BASE_LAYER_PID, &base_layer_pid);
if (force_lt_idx >= 0) {
frm_cfg->force_flag |= ENC_FORCE_LT_REF_IDX;
frm_cfg->force_lt_idx = force_lt_idx;
}
if (force_use_lt_idx >= 0) {
frm_cfg->force_flag |= ENC_FORCE_REF_MODE;
frm_cfg->force_ref_mode = REF_TO_LT_REF_IDX;
frm_cfg->force_ref_arg = force_use_lt_idx;
}
if (force_frame_qp >= 0) {
rc_force->force_flag = ENC_RC_FORCE_QP;
rc_force->force_qp = force_frame_qp;
} else {
rc_force->force_flag &= (~ENC_RC_FORCE_QP);
rc_force->force_qp = -1;
}
if (base_layer_pid >= 0) {
H265eCtx *p = (H265eCtx *)ctx;
MppEncH265Cfg *h265 = &p->cfg->codec.h265;
h265->base_layer_pid = base_layer_pid;
}
}
/*
* Step 2: Fps conversion
*
@@ -267,16 +306,36 @@ static MPP_RET h265e_proc_dpb(void *ctx, HalEncTask *task)
static MPP_RET h265e_proc_hal(void *ctx, HalEncTask *task)
{
H265eCtx *p = (H265eCtx *)ctx;
EncFrmStatus *frm = &task->rc_task->frm;
MppPacket packet = task->packet;
MppMeta meta = mpp_packet_get_meta(packet);
MppEncH265Cfg *h265 = &p->cfg->codec.h265;
if (ctx == NULL) {
mpp_err_f("invalid NULL ctx\n");
return MPP_ERR_NULL_PTR;
}
mpp_meta_set_s32(meta, KEY_TEMPORAL_ID, frm->temporal_id);
/* check max temporal layer id */
{
MppEncCpbInfo *cpb_info = mpp_enc_ref_cfg_get_cpb_info(p->cfg->ref_cfg);
RK_S32 cpb_max_tid = cpb_info->max_st_tid;
RK_S32 cfg_max_tid = h265->max_tid;
if (cpb_max_tid != cfg_max_tid) {
mpp_log("max tid is update to match cpb %d -> %d\n",
cfg_max_tid, cpb_max_tid);
h265->max_tid = cpb_max_tid;
}
}
if (h265->max_tid) {
EncFrmStatus *frm = &task->rc_task->frm;
MppPacket packet = task->packet;
MppMeta meta = mpp_packet_get_meta(packet);
mpp_meta_set_s32(meta, KEY_TEMPORAL_ID, frm->temporal_id);
if (!frm->is_non_ref && frm->is_lt_ref)
mpp_meta_set_s32(meta, KEY_LONG_REF_IDX, frm->lt_idx);
}
h265e_dbg_func("enter ctx %p \n", ctx);
h265e_syntax_fill(ctx);
@@ -539,6 +598,25 @@ static MPP_RET h265e_proc_h265_cfg(MppEncH265Cfg *dst, MppEncH265Cfg *src)
dst->change |= MPP_ENC_H265_CFG_CHANGE_CONST_INTRA;
}
if ((change & MPP_ENC_H265_CFG_CHANGE_MAX_LTR) &&
(dst->max_ltr_frames != src->max_ltr_frames)) {
dst->max_ltr_frames = src->max_ltr_frames;
dst->change |= MPP_ENC_H265_CFG_CHANGE_MAX_LTR;
}
if ((change & MPP_ENC_H265_CFG_CHANGE_MAX_TID) &&
(dst->max_tid != src->max_tid)) {
dst->max_tid = src->max_tid;
dst->change |= MPP_ENC_H265_CFG_CHANGE_MAX_TID;
}
if ((change & MPP_ENC_H265_CFG_CHANGE_BASE_LAYER_PID) &&
(dst->base_layer_pid != src->base_layer_pid)) {
dst->base_layer_pid = src->base_layer_pid;
dst->change |= MPP_ENC_H265_CFG_CHANGE_BASE_LAYER_PID;
}
/*
* NOTE: use OR here for avoiding overwrite on multiple config
* When next encoding is trigger the change flag will be clear

View File

@@ -24,6 +24,7 @@
#include "h265e_codec.h"
#include "h265e_dpb.h"
#include "h265e_slice.h"
void h265e_dpb_dump_frm(H265eDpb *dpb, const char *fmt)
{
@@ -42,10 +43,42 @@ void h265e_dpb_dump_frm(H265eDpb *dpb, const char *fmt)
mpp_log("%20s %s", fmt, buf);
}
void h265e_dpb_set_ref_list(H265eRpsList *RpsList, H265eReferencePictureSet *m_pRps, RK_S32 delta_poc)
MPP_RET calc_ref_pic_set_idxl0(H265eDpb *dpb, H265eSlice *slice, RK_S32 ref_idx)
{
H265eReferencePictureSet * rps = (H265eReferencePictureSet*)&slice->m_localRPS;
H265eDpbFrm *frame_list = dpb->frame_list;
H265eRpsList *RpsList = &dpb->RpsList;
RK_S32 poc_idx = rps->m_RealPoc[ref_idx];
H265eDpbFrm* refPicSetLtCurr[MAX_REFS];
H265eDpbFrm* refPic = NULL;
RK_S32 numPocLtCurr = 0;
RK_S32 i = 0;
for (i = rps->num_negative_pic + rps->num_positive_pic + rps->num_long_term_pic - 1;
i > rps->num_negative_pic + rps->num_positive_pic - 1; i--) {
if (rps->m_used[i]) {
refPic = get_lt_ref_pic(frame_list, slice, rps->m_RealPoc[i], rps->check_lt_msb[i]);
refPicSetLtCurr[numPocLtCurr] = refPic;
numPocLtCurr++;
}
}
RpsList->m_RefPicListModification->m_RefPicSetIdxL0[0] = 0;
for (i = 0; i < numPocLtCurr; i++) {
if (poc_idx == refPicSetLtCurr[i]->poc)
RpsList->m_RefPicListModification->m_RefPicSetIdxL0[0] = i;
}
return MPP_OK;
}
void h265e_dpb_set_ref_list(H265eDpb *dpb, H265eSlice *slice, RK_S32 delta_poc)
{
RK_S32 i;
RK_S32 ref_idx = -1;
RK_S32 lt_cnt = 0, st_cnt = 0;
H265eRpsList *RpsList = &dpb->RpsList;
H265eReferencePictureSet * m_pRps = (H265eReferencePictureSet*)&slice->m_localRPS;
H265eRefPicListModification* refPicListModification = RpsList->m_RefPicListModification;
h265e_dbg_func("enter\n");
@@ -64,21 +97,19 @@ void h265e_dpb_set_ref_list(H265eRpsList *RpsList, H265eReferencePictureSet *m_p
h265e_dbg_dpb("m_pRps->delta_poc[%d] = %d", i, m_pRps->delta_poc[i]);
if (m_pRps->delta_poc[i] == delta_poc) {
ref_idx = i;
h265e_dbg_dpb("get ref ref_idx %d", ref_idx);
break;
if (i > m_pRps->m_numberOfPictures - m_pRps->num_long_term_pic - 1)
lt_cnt++;
else
st_cnt++;
h265e_dbg_dpb("get %s ref ref_idx %d delta_poc %d", st_cnt ? "st" : "lt", ref_idx, delta_poc);
}
}
if (-1 == ref_idx) {
mpp_err("Did not find the right reference picture");
if (lt_cnt != 1 && st_cnt == 0) {
mpp_err("Warning: Did not find the right long term reference picture or more than one.");
return;
} else if (ref_idx != 0) {
refPicListModification->m_refPicListModificationFlagL0 = 1;
refPicListModification->m_RefPicSetIdxL0[0] = ref_idx;
for ( i = 1; i < m_pRps->m_numberOfPictures - 1; i++) {
if (i != ref_idx)
refPicListModification->m_RefPicSetIdxL0[i] = i;
}
refPicListModification->m_RefPicSetIdxL0[ref_idx] = 0;
calc_ref_pic_set_idxl0(dpb, slice, ref_idx);
}
}
refPicListModification->m_refPicListModificationFlagL1 = 0;
@@ -650,9 +681,12 @@ void h265e_dpb_cpb2rps(H265eDpb *dpb, RK_S32 curPoc, H265eSlice *slice, EncCpbSt
rps->poc[i + st_size] = nLongTermRefPicPoc[i];
rps->m_RealPoc[i + st_size] = nLongTermRefPicRealPoc[i];
rps->m_used[i + st_size] = 1;
rps->m_ref[i + st_size] = p->is_long_term;
rps->delta_poc[i + st_size] = nLongTermDealtPoc[i];
rps->check_lt_msb[i + st_size] = isMsbValid[i];
if (cpb->refr.seq_idx == rps->poc[i + st_size])
rps->m_ref[i + st_size] = 1;
else
rps->m_ref[i + st_size] = 0;
}
}
@@ -663,7 +697,7 @@ void h265e_dpb_cpb2rps(H265eDpb *dpb, RK_S32 curPoc, H265eSlice *slice, EncCpbSt
slice->m_rps = rps;
h265e_dpb_apply_rps(dpb, slice->m_rps, curPoc);
h265e_dpb_arrange_lt_rps(dpb, slice);
h265e_dpb_set_ref_list(RpsList, rps, ref_dealt_poc);
h265e_dpb_set_ref_list(dpb, slice, ref_dealt_poc);
memcpy(&slice->m_RefPicListModification, RpsList->m_RefPicListModification,
sizeof(H265eRefPicListModification));
h265e_dbg_func("leave\n");

View File

@@ -169,7 +169,8 @@ void h265e_slice_set_ref_list(H265eDpbFrm *frame_list, H265eSlice *slice)
for ( rIdx = 0; rIdx < slice->m_numRefIdx[0]; rIdx++) {
cIdx = slice->m_RefPicListModification.m_refPicListModificationFlagL0 ? slice->m_RefPicListModification.m_RefPicSetIdxL0[rIdx] : (RK_U32)rIdx % numPocTotalCurr;
mpp_assert(cIdx >= 0 && cIdx < numPocTotalCurr);
slice->m_refPicList[0][rIdx] = rpsCurrList0[cIdx];
slice->m_refPicList[0][rIdx] = slice->m_RefPicListModification.m_refPicListModificationFlagL0 ?
rpsCurrList0[cIdx + numPocStCurr0] : rpsCurrList0[0];
slice->m_bIsUsedAsLongTerm[0][rIdx] = (cIdx >= numPocStCurr0 + numPocStCurr1);
}

View File

@@ -437,6 +437,7 @@ void h265e_slice_set_ref_list(H265eDpbFrm *frame_list, H265eSlice *slice);
void h265e_slice_set_ref_poc_list(H265eSlice *slice);
void h265e_slice_init(void *ctx, EncFrmStatus curr);
RK_S32 h265e_code_slice_skip_frame(void *ctx, H265eSlice *slice, RK_U8 *buf, RK_S32 len);
H265eDpbFrm* get_lt_ref_pic(H265eDpbFrm *frame_list, H265eSlice *slice, RK_S32 poc, RK_U32 pocHasMsb);
#ifdef __cplusplus
}