mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-09-26 21:15:53 +08:00
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:
@@ -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;
|
||||
|
@@ -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 */ \
|
||||
|
@@ -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
|
||||
|
@@ -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");
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user