From 3ea5eb5a510bae606b1a38b3aa85a075f4744a8f Mon Sep 17 00:00:00 2001 From: Yanjun Liao Date: Tue, 21 Jan 2025 16:03:29 +0800 Subject: [PATCH] fix[mpp_enc]: Fix some exceptions when force pskip 1. Add rc model in when force skip frm 2. Fix ref frm error when force pskip 3. Disable pskip when cfg force idr 4. Support pskip frm as ref frm 5. Support force skip frm as is_ref or non_ref Change-Id: Ib138ab75a9df2c4521cb376e3a3d7fd30565ecd9 Signed-off-by: Yanjun Liao --- inc/mpp_meta.h | 7 +- inc/mpp_rc_defs.h | 4 +- mpp/base/inc/mpp_enc_refs.h | 11 ++-- mpp/base/mpp_enc_refs.cpp | 12 +++- mpp/base/mpp_meta.cpp | 1 + mpp/codec/enc/h264/h264e_api_v2.c | 45 ++++++++++++- mpp/codec/enc/h264/h264e_dpb.c | 10 ++- mpp/codec/enc/h264/h264e_dpb.h | 2 + mpp/codec/enc/h265/h265e_api.c | 4 +- mpp/codec/enc/h265/h265e_dpb.c | 54 +++++++++------- mpp/codec/enc/h265/h265e_dpb.h | 1 + mpp/codec/enc/h265/h265e_syntax.c | 9 ++- mpp/codec/inc/mpp_enc_impl.h | 5 ++ mpp/codec/mpp_enc_impl.cpp | 103 +++++++++++++++++++----------- mpp/common/h265e_syntax_new.h | 1 - mpp/hal/common/hal_bufs.c | 2 +- 16 files changed, 187 insertions(+), 84 deletions(-) diff --git a/inc/mpp_meta.h b/inc/mpp_meta.h index 6a9daccf..66f90405 100644 --- a/inc/mpp_meta.h +++ b/inc/mpp_meta.h @@ -84,8 +84,13 @@ typedef enum MppMetaKey_e { KEY_LVL4_INTRA_NUM = FOURCC_META('l', '4', 'i', ' '), /* output P skip frame indicator */ KEY_OUTPUT_PSKIP = FOURCC_META('o', 'p', 's', 'p'), - /* input P skip frame request */ + /* + * Input P-skip frame request + * KEY_INPUT_PSKIP: The skip frame will be referenced in the next frame. + * KEY_INPUT_PSKIP_NON_REF: The skip frame will not be referenced as a frame. + */ KEY_INPUT_PSKIP = FOURCC_META('i', 'p', 's', 'p'), + KEY_INPUT_PSKIP_NON_REF = FOURCC_META('i', 'p', 'n', 'r'), KEY_ENC_SSE = FOURCC_META('e', 's', 's', 'e'), /* diff --git a/inc/mpp_rc_defs.h b/inc/mpp_rc_defs.h index c5643f2d..78722b4e 100644 --- a/inc/mpp_rc_defs.h +++ b/inc/mpp_rc_defs.h @@ -131,7 +131,8 @@ typedef union EncFrmStatus_u { /* * When true currnet frame is force to encoded as software skip frame */ - RK_U32 force_pskip : 1; + RK_U32 force_pskip : 1; + RK_U32 force_pskip_is_ref : 1; /* * Current frame is intra refresh frame @@ -141,7 +142,6 @@ typedef union EncFrmStatus_u { * Current frame needs add recovery point prefix */ RK_U32 is_i_recovery : 1; - RK_U32 reserved1 : 1; /* reencode times */ RK_U32 reencode_times : 8; diff --git a/mpp/base/inc/mpp_enc_refs.h b/mpp/base/inc/mpp_enc_refs.h index ca9de1b4..b7b6ec44 100644 --- a/mpp/base/inc/mpp_enc_refs.h +++ b/mpp/base/inc/mpp_enc_refs.h @@ -32,11 +32,12 @@ * When encoder is running user can change the frame property by MppEncRefFrmUsrCfg. */ #define ENC_FORCE_IDR (0x00000001) -#define ENC_FORCE_PSKIP (0x00000002) -#define ENC_FORCE_NONREF (0x00000004) -#define ENC_FORCE_LT_REF_IDX (0x00000008) -#define ENC_FORCE_TEMPORAL_ID (0x00000010) -#define ENC_FORCE_REF_MODE (0x00000020) +#define ENC_FORCE_NONREF (0x00000002) +#define ENC_FORCE_LT_REF_IDX (0x00000004) +#define ENC_FORCE_TEMPORAL_ID (0x00000008) +#define ENC_FORCE_REF_MODE (0x00000010) +#define ENC_FORCE_PSKIP_IS_REF (0x00000020) +#define ENC_FORCE_PSKIP_NON_REF (0x00000040) typedef struct MppEncRefFrmForceCfg_t { RK_U32 force_flag; diff --git a/mpp/base/mpp_enc_refs.cpp b/mpp/base/mpp_enc_refs.cpp index 6e5a7053..1ff0ec15 100644 --- a/mpp/base/mpp_enc_refs.cpp +++ b/mpp/base/mpp_enc_refs.cpp @@ -906,10 +906,16 @@ MPP_RET mpp_enc_refs_get_cpb(MppEncRefs refs, EncCpbStatus *status) usr_cfg->force_flag &= ~ENC_FORCE_REF_MODE; } - if (usr_cfg->force_flag & ENC_FORCE_PSKIP) { - frm->force_pskip = 1; + if (usr_cfg->force_flag & ENC_FORCE_PSKIP_NON_REF) { + frm->is_non_ref = 1; - usr_cfg->force_flag &= ~ENC_FORCE_PSKIP; + usr_cfg->force_flag &= ~ENC_FORCE_PSKIP_NON_REF; + } + + if (usr_cfg->force_flag & ENC_FORCE_PSKIP_IS_REF) { + frm->force_pskip_is_ref = 1; + + usr_cfg->force_flag &= ~ENC_FORCE_PSKIP_IS_REF; } frm->non_recn = frm->is_non_ref || (p->igop == 1); diff --git a/mpp/base/mpp_meta.cpp b/mpp/base/mpp_meta.cpp index 2d1f969c..b9b2c2f8 100644 --- a/mpp/base/mpp_meta.cpp +++ b/mpp/base/mpp_meta.cpp @@ -90,6 +90,7 @@ static RK_U64 meta_defs[] = { META_KEY_TO_U64(KEY_LVL4_INTRA_NUM, TYPE_VAL_32), META_KEY_TO_U64(KEY_INPUT_PSKIP, TYPE_VAL_32), META_KEY_TO_U64(KEY_OUTPUT_PSKIP, TYPE_VAL_32), + META_KEY_TO_U64(KEY_INPUT_PSKIP_NON_REF, TYPE_VAL_32), META_KEY_TO_U64(KEY_ENC_SSE, TYPE_VAL_64), META_KEY_TO_U64(KEY_ENC_MARK_LTR, TYPE_VAL_32), diff --git a/mpp/codec/enc/h264/h264e_api_v2.c b/mpp/codec/enc/h264/h264e_api_v2.c index 8f225eab..692bee79 100644 --- a/mpp/codec/enc/h264/h264e_api_v2.c +++ b/mpp/codec/enc/h264/h264e_api_v2.c @@ -757,6 +757,41 @@ static MPP_RET h264e_start(void *ctx, HalEncTask *task) return MPP_OK; } +MPP_RET h264e_pskip_ref_check(H264eDpb *dpb, H264eFrmInfo *frms) +{ + H264eDpbFrm *curr = NULL; + H264eDpbFrm *refr = NULL; + RK_U32 i; + MPP_RET ret = MPP_OK; + + curr = dpb->curr; + refr = dpb->refr; + + if (curr->status.force_pskip_is_ref) { + H264eDpbFrm *temp_frm; + for (i = 0; i < H264E_MAX_REFS_CNT; i++) { + temp_frm = &dpb->frames[i]; + if (temp_frm->slot_idx != frms->refr_idx) { + temp_frm->as_pskip_ref = 0; + } else { + temp_frm->as_pskip_ref = 1; + } + } + } + + if (!refr->status.force_pskip_is_ref && !curr->status.force_pskip_is_ref) { + H264eDpbFrm *temp_frm; + for (i = 0; i < H264E_MAX_REFS_CNT; i++) { + temp_frm = &dpb->frames[i]; + if (temp_frm) { + temp_frm->as_pskip_ref = 0; + } + } + } + + return ret; +} + static MPP_RET h264e_proc_dpb(void *ctx, HalEncTask *task) { H264eCtx *p = (H264eCtx *)ctx; @@ -784,14 +819,17 @@ static MPP_RET h264e_proc_dpb(void *ctx, HalEncTask *task) frms->curr_idx = curr->slot_idx; if (refr) { - if (refr->status.force_pskip) - frms->refr_idx = p->pre_ref_idx; + if (refr->status.force_pskip_is_ref) + frms->refr_idx = refr->prev_ref_idx; else frms->refr_idx = refr->slot_idx; } else { frms->refr_idx = curr->slot_idx; } + // mark actual refs buf when force pskip is ref + h264e_pskip_ref_check(dpb, frms); + for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(frms->usage); i++) frms->usage[i] = dpb->frames[i].on_used; @@ -904,8 +942,9 @@ static MPP_RET h264e_sw_enc(void *ctx, HalEncTask *task) rc_info->bit_real = task->length; rc_info->quality_real = rc_info->quality_target; - p->pre_ref_idx = p->frms.refr_idx; + p->dpb.curr->prev_ref_idx = p->frms.refr_idx; mpp_packet_add_segment_info(packet, H264_NALU_TYPE_SLICE, length, final_len); + mpp_buffer_sync_partial_end(mpp_packet_get_buffer(packet), length, final_len); return MPP_OK; } diff --git a/mpp/codec/enc/h264/h264e_dpb.c b/mpp/codec/enc/h264/h264e_dpb.c index f93a202c..8c8f0d53 100644 --- a/mpp/codec/enc/h264/h264e_dpb.c +++ b/mpp/codec/enc/h264/h264e_dpb.c @@ -460,7 +460,7 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) H264eDpbFrm *frm = find_cpb_frame(dpb, &init[i]); dpb->map[i] = frm; if (frm) { - if (!frm->on_used) + if (!frm->on_used && !frm->status.force_pskip_is_ref) mpp_err_f("warning frm %d is used by cpb but on not used status\n", frm->seq_idx); frm->dpb_used = 1; @@ -492,7 +492,7 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) RK_S32 j; for (j = 0; j < MAX_CPB_REFS; j++) { - if (p == dpb->map[j]) { + if (p == dpb->map[j] || p->as_pskip_ref) { valid = 1; break; } @@ -502,7 +502,8 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) i, valid, p->on_used); if (valid) { - if (!p->on_used || !p->status.valid) { + if ((!p->as_pskip_ref) && + (!p->on_used || !p->status.valid)) { mpp_assert(p->on_used); mpp_assert(p->status.valid); h264e_dpb_dump_frms(dpb); @@ -672,6 +673,9 @@ void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb) h264e_dbg_dpb("frm %d num %d poc %d\n", tmp->seq_idx, tmp->frame_num, tmp->poc); + if (tmp->as_pskip_ref) + continue; + if (!tmp->on_used) continue; diff --git a/mpp/codec/enc/h264/h264e_dpb.h b/mpp/codec/enc/h264/h264e_dpb.h index dd0eb414..30021a11 100644 --- a/mpp/codec/enc/h264/h264e_dpb.h +++ b/mpp/codec/enc/h264/h264e_dpb.h @@ -65,6 +65,8 @@ typedef struct H264eDpbFrm_t { /* frame status */ EncFrmStatus status; + RK_S32 prev_ref_idx; + RK_S32 as_pskip_ref; /* frame number from H264eSlice */ RK_S32 frame_num; diff --git a/mpp/codec/enc/h265/h265e_api.c b/mpp/codec/enc/h265/h265e_api.c index 91d51cdf..4e9a5ea1 100644 --- a/mpp/codec/enc/h265/h265e_api.c +++ b/mpp/codec/enc/h265/h265e_api.c @@ -310,6 +310,7 @@ static MPP_RET h265e_proc_dpb(void *ctx, HalEncTask *task) H265eCtx *p = (H265eCtx *)ctx; EncRcTask *rc_task = task->rc_task; EncCpbStatus *cpb = &task->rc_task->cpb; + h265e_dbg_func("enter\n"); h265e_dpb_proc_cpb(p->dpb, cpb); h265e_dpb_get_curr(p->dpb); @@ -383,8 +384,9 @@ static MPP_RET h265e_proc_enc_skip(void *ctx, HalEncTask *task) new_length = h265e_code_slice_skip_frame(ctx, p->slice, ptr, len); task->length = new_length; task->rc_task->info.bit_real = 8 * new_length; - syntax->pre_ref_idx = syntax->sp.recon_pic.slot_idx; + p->dpb->curr->prev_ref_idx = syntax->sp.recon_pic.slot_idx; mpp_packet_add_segment_info(pkt, NAL_TRAIL_R, offset, new_length); + mpp_buffer_sync_partial_end(mpp_packet_get_buffer(pkt), offset, new_length); h265e_dbg_func("leave\n"); return MPP_OK; diff --git a/mpp/codec/enc/h265/h265e_dpb.c b/mpp/codec/enc/h265/h265e_dpb.c index 5ab3abd6..365d9292 100644 --- a/mpp/codec/enc/h265/h265e_dpb.c +++ b/mpp/codec/enc/h265/h265e_dpb.c @@ -300,28 +300,27 @@ void sort_delta_poc(H265eReferencePictureSet *rps) } } - void h265e_dpb_apply_rps(H265eDpb *dpb, H265eReferencePictureSet *rps, int curPoc) { H265eDpbFrm *outPic = NULL; - RK_S32 i, isReference; + RK_S32 i; // loop through all pictures in the reference picture buffer RK_U32 index = 0; H265eDpbFrm *frame_list = &dpb->frame_list[0]; + h265e_dbg_func("enter\n"); + for (index = 0; index < MPP_ARRAY_ELEMS(dpb->frame_list); index++) { outPic = &frame_list[index]; if (!outPic->inited || !outPic->slice->is_referenced) { continue; } - isReference = 0; // loop through all pictures in the Reference Picture Set // to see if the picture should be kept as reference picture for (i = 0; i < rps->num_positive_pic + rps->num_negative_pic; i++) { h265e_dbg_dpb("outPic->slice->poc %d,curPoc %d dealt %d", outPic->slice->poc, curPoc, rps->delta_poc[i]); if (!outPic->is_long_term && outPic->slice->poc == curPoc + rps->delta_poc[i]) { - isReference = 1; outPic->used_by_cur = (rps->m_used[i] == 1); outPic->is_long_term = 0; } @@ -330,27 +329,16 @@ void h265e_dpb_apply_rps(H265eDpb *dpb, H265eReferencePictureSet *rps, int curPo for (; i < rps->m_numberOfPictures; i++) { if (rps->check_lt_msb[i] == 0) { if (outPic->is_long_term && (outPic->slice->poc == rps->m_RealPoc[i])) { - isReference = 1; outPic->used_by_cur = (rps->m_used[i] == 1); } } else { if (outPic->is_long_term && (outPic->slice->poc == rps->m_RealPoc[i])) { - isReference = 1; outPic->used_by_cur = (rps->m_used[i] == 1); } } } - - // mark the picture as "unused for reference" if it is not in - // the Reference Picture Set - if (outPic->slice->poc != curPoc && isReference == 0) { - h265e_dbg_dpb("free unreference buf poc %d", outPic->slice->poc); - outPic->slice->is_referenced = 0; - outPic->used_by_cur = 0; - outPic->dpb_used = 0; - outPic->is_long_term = 0; - } } + h265e_dbg_func("leave\n"); } @@ -703,6 +691,26 @@ void h265e_dpb_cpb2rps(H265eDpb *dpb, RK_S32 curPoc, H265eSlice *slice, EncCpbSt h265e_dbg_func("leave\n"); } +MPP_RET h265e_pskip_ref_check(H265eDpb *dpb, EncCpbStatus *cpb, H265eDpbFrm *frm) +{ + MPP_RET ret = MPP_OK; + + h265e_dbg_func("enter\n"); + + if ((cpb->curr.force_pskip_is_ref) && (frm->slot_idx == dpb->curr->slice->m_refPicList[0][0]->slot_idx)) { + h265e_dbg_dpb("hold refr buf as skip frm recon buf, poc %d slot idx %d.", frm->slice->poc, frm->slot_idx); + ret = MPP_NOK; + } + + if ((cpb->refr.force_pskip_is_ref) && (frm->slot_idx == dpb->curr->slice->m_refPicList[0][0]->prev_ref_idx)) { + h265e_dbg_dpb("hold refr buf as skip frm recon buf, poc %d slot idx %d.", frm->slice->poc, frm->slot_idx); + ret = MPP_NOK; + } + + h265e_dbg_func("leave\n"); + return ret; +} + void h265e_dpb_free_unsed(H265eDpb *dpb, EncCpbStatus *cpb) { RK_S32 i = 0; @@ -722,16 +730,16 @@ void h265e_dpb_free_unsed(H265eDpb *dpb, EncCpbStatus *cpb) for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(dpb->frame_list); i++) { H265eDpbFrm *frm = &dpb->frame_list[i]; - if (!frm->dpb_used) continue; - if (h265e_check_frame_cpb(frm, MAX_REFS, &cpb->final[0])) { - h265e_dbg_dpb("cpb final unreference buf poc %d", frm->slice->poc); - frm->is_long_term = 0; - frm->used_by_cur = 0; - frm->dpb_used = 0; - frm->slice->is_referenced = 0; + if (!h265e_pskip_ref_check(dpb, cpb, frm)) { + h265e_dbg_dpb("cpb final unreference buf poc %d", frm->slice->poc); + frm->is_long_term = 0; + frm->used_by_cur = 0; + frm->dpb_used = 0; + frm->slice->is_referenced = 0; + } } } diff --git a/mpp/codec/enc/h265/h265e_dpb.h b/mpp/codec/enc/h265/h265e_dpb.h index 6429755f..6308cbbf 100644 --- a/mpp/codec/enc/h265/h265e_dpb.h +++ b/mpp/codec/enc/h265/h265e_dpb.h @@ -67,6 +67,7 @@ typedef struct H265eDpbFrm_t { RK_S32 seq_idx; RK_S32 gop_idx; RK_S32 gop_cnt; + RK_S32 prev_ref_idx; EncFrmStatus status; union { diff --git a/mpp/codec/enc/h265/h265e_syntax.c b/mpp/codec/enc/h265/h265e_syntax.c index a27136e4..c4e1fd7b 100644 --- a/mpp/codec/enc/h265/h265e_syntax.c +++ b/mpp/codec/enc/h265/h265e_syntax.c @@ -192,7 +192,6 @@ RK_S32 fill_ref_parameters(const H265eCtx *h, H265eSlicParams *sp) { H265eSlice *slice = h->slice; H265eReferencePictureSet* rps = slice->m_rps; - H265eSyntax_new *syn = (H265eSyntax_new*)&h->syntax; RK_U32 numRpsCurrTempList = 0; RK_S32 ref_num = 0; H265eDpbFrm *ref_frame; @@ -342,13 +341,13 @@ RK_S32 fill_ref_parameters(const H265eCtx *h, H265eSlicParams *sp) ref_frame = slice->m_refPicList[0][0]; if (ref_frame) { - if (ref_frame->status.force_pskip) - ref_frame->slot_idx = syn->pre_ref_idx; - sp->ref_pic.slot_idx = ref_frame->slot_idx; + if (ref_frame->status.force_pskip_is_ref) + sp->ref_pic.slot_idx = slice->m_refPicList[0][0]->prev_ref_idx; + else + sp->ref_pic.slot_idx = ref_frame->slot_idx; } else { sp->ref_pic.slot_idx = h->dpb->curr->slot_idx; } - return 0; } diff --git a/mpp/codec/inc/mpp_enc_impl.h b/mpp/codec/inc/mpp_enc_impl.h index 1da12e3b..cbbcab20 100644 --- a/mpp/codec/inc/mpp_enc_impl.h +++ b/mpp/codec/inc/mpp_enc_impl.h @@ -28,6 +28,11 @@ #define HDR_ADDED_MASK 0xe +typedef struct MppPskipMode_t { + RK_S32 pskip_is_ref; + RK_S32 pskip_is_non_ref; +} MppPskipMode; + typedef union MppEncHeaderStatus_u { RK_U32 val; struct { diff --git a/mpp/codec/mpp_enc_impl.cpp b/mpp/codec/mpp_enc_impl.cpp index f9543cd3..d2937015 100644 --- a/mpp/codec/mpp_enc_impl.cpp +++ b/mpp/codec/mpp_enc_impl.cpp @@ -1655,11 +1655,15 @@ static MPP_RET mpp_enc_force_pskip_check(Mpp *mpp, EncAsyncTaskInfo *task) mpp_enc_refs_get_cpb_info(enc->refs, &cpb_info); max_tid = cpb_info.max_st_tid; - if (frm->is_idr) { + if (task->usr.force_flag & ENC_FORCE_IDR) { + enc_dbg_detail("task %d, FORCE IDR should not be set as pskip frames", frm->seq_idx); + ret = MPP_NOK; + } + if (cpb->curr.is_idr) { enc_dbg_detail("task %d, IDR frames should not be set as pskip frames", frm->seq_idx); ret = MPP_NOK; } - if (frm->is_lt_ref) { + if (cpb->curr.is_lt_ref) { enc_dbg_detail("task %d, LTR frames should not be set as pskip frames", frm->seq_idx); ret = MPP_NOK; } @@ -1689,7 +1693,10 @@ static MPP_RET mpp_enc_force_pskip(Mpp *mpp, EncAsyncTaskInfo *task) enc_dbg_func("enter\n"); frm_cfg->force_pskip++; - frm_cfg->force_flag |= ENC_FORCE_PSKIP; + if (frm->force_pskip) + frm_cfg->force_flag |= ENC_FORCE_PSKIP_NON_REF; + else if (frm->force_pskip_is_ref) + frm_cfg->force_flag |= ENC_FORCE_PSKIP_IS_REF; /* NOTE: in some condition the pskip should not happen */ mpp_enc_refs_set_usr_cfg(enc->refs, frm_cfg); @@ -1697,23 +1704,33 @@ static MPP_RET mpp_enc_force_pskip(Mpp *mpp, EncAsyncTaskInfo *task) enc_dbg_detail("task %d enc proc dpb\n", frm->seq_idx); mpp_enc_refs_get_cpb(enc->refs, cpb); - enc_dbg_frm_status("frm %d start ***********************************\n", cpb->curr.seq_idx); - ENC_RUN_FUNC2(enc_impl_proc_dpb, impl, hal_task, mpp, ret); - ret = mpp_enc_force_pskip_check(mpp, task); + if (ret) { mpp_enc_refs_rollback(enc->refs); frm_cfg->force_pskip--; - frm_cfg->force_flag &= ~ENC_FORCE_PSKIP; + if (frm->force_pskip) + frm_cfg->force_flag &= ~ENC_FORCE_PSKIP_NON_REF; + else if (frm->force_pskip_is_ref) + frm_cfg->force_flag &= ~ENC_FORCE_PSKIP_IS_REF; return MPP_NOK; } + enc_dbg_frm_status("frm %d start ***********************************\n", cpb->curr.seq_idx); + ENC_RUN_FUNC2(enc_impl_proc_dpb, impl, hal_task, mpp, ret); + enc_dbg_detail("task %d rc frame start\n", frm->seq_idx); ENC_RUN_FUNC2(rc_frm_start, enc->rc_ctx, rc_task, mpp, ret); + enc_dbg_detail("task %d rc hal start\n", frm->seq_idx); + ENC_RUN_FUNC2(rc_hal_start, enc->rc_ctx, rc_task, mpp, ret); + enc_dbg_detail("task %d enc sw enc start\n", frm->seq_idx); ENC_RUN_FUNC2(enc_impl_sw_enc, impl, hal_task, mpp, ret); + enc_dbg_detail("task %d rc hal end\n", frm->seq_idx); + ENC_RUN_FUNC2(rc_hal_end, enc->rc_ctx, rc_task, mpp, ret); + enc_dbg_detail("task %d rc frame end\n", frm->seq_idx); ENC_RUN_FUNC2(rc_frm_end, enc->rc_ctx, rc_task, mpp, ret); @@ -1722,6 +1739,39 @@ TASK_DONE: return ret; } +static MPP_RET mpp_enc_get_pskip_mode(Mpp *mpp, EncAsyncTaskInfo *task, MppPskipMode *skip_mode) +{ + MppEncImpl *enc = (MppEncImpl *)mpp->mEnc; + EncRcTask *rc_task = &task->rc; + EncFrmStatus *frm = &rc_task->frm; + HalEncTask *hal_task = &task->task; + MPP_RET ret = MPP_OK; + + skip_mode->pskip_is_ref = 0; + skip_mode->pskip_is_non_ref = 0; + enc->frame = hal_task->frame; + + if (mpp_frame_has_meta(enc->frame)) { + MppMeta frm_meta = mpp_frame_get_meta(enc->frame); + if (frm_meta) { + mpp_meta_get_s32(frm_meta, KEY_INPUT_PSKIP, &skip_mode->pskip_is_ref); + mpp_meta_get_s32(frm_meta, KEY_INPUT_PSKIP_NON_REF, &skip_mode->pskip_is_non_ref); + } + } + + if (skip_mode->pskip_is_ref == 1 && skip_mode->pskip_is_non_ref == 1) { + mpp_err("task %d, Don't cfg pskip frame to be both a ref and non-ref at the same time"); + ret = MPP_NOK; + } else { + frm->force_pskip = skip_mode->pskip_is_non_ref; + frm->force_pskip_is_ref = skip_mode->pskip_is_ref; + ret = MPP_OK; + } + + return ret; +} + + static void mpp_enc_add_sw_header(MppEncImpl *enc, HalEncTask *hal_task) { EncImpl impl = enc->impl; @@ -1816,17 +1866,11 @@ static MPP_RET mpp_enc_normal(Mpp *mpp, EncAsyncTaskInfo *task) enc_dbg_detail("task %d check force pskip start\n", frm->seq_idx); if (!status->check_frm_pskip) { - RK_S32 force_pskip = 0; + MppPskipMode skip_mode; status->check_frm_pskip = 1; - if (mpp_frame_has_meta(enc->frame)) { - MppMeta frm_meta = mpp_frame_get_meta(enc->frame); - if (frm_meta) - mpp_meta_get_s32(frm_meta, KEY_INPUT_PSKIP, &force_pskip); - } - - if (force_pskip == 1) { - frm->force_pskip = 1; + mpp_enc_get_pskip_mode((Mpp*)enc->mpp, task, &skip_mode); + if (skip_mode.pskip_is_ref || skip_mode.pskip_is_non_ref) { ret = mpp_enc_force_pskip((Mpp*)enc->mpp, task); if (ret) enc_dbg_detail("task %d set force pskip failed.", frm->seq_idx); @@ -1992,7 +2036,7 @@ static MPP_RET mpp_enc_reenc_force_pskip(Mpp *mpp, EncAsyncTaskInfo *task) enc_dbg_func("enter\n"); frm_cfg->force_pskip++; - frm_cfg->force_flag |= ENC_FORCE_PSKIP; + frm_cfg->force_flag |= ENC_FORCE_PSKIP_NON_REF; /* NOTE: in some condition the pskip should not happen */ @@ -2251,17 +2295,11 @@ static MPP_RET try_proc_low_deley_task(Mpp *mpp, EncAsyncTaskInfo *task, EncAsyn enc_dbg_detail("task %d check force pskip start\n", frm->seq_idx); if (!status->check_frm_pskip) { - RK_S32 force_pskip = 0; + MppPskipMode skip_mode; status->check_frm_pskip = 1; - if (mpp_frame_has_meta(enc->frame)) { - MppMeta frm_meta = mpp_frame_get_meta(enc->frame); - if (frm_meta) - mpp_meta_get_s32(frm_meta, KEY_INPUT_PSKIP, &force_pskip); - } - - if (force_pskip == 1) { - frm->force_pskip = 1; + mpp_enc_get_pskip_mode((Mpp*)enc->mpp, task, &skip_mode); + if (skip_mode.pskip_is_ref || skip_mode.pskip_is_non_ref) { ret = mpp_enc_force_pskip((Mpp*)enc->mpp, task); if (ret) enc_dbg_detail("task %d set force pskip failed.", frm->seq_idx); @@ -3121,19 +3159,12 @@ static MPP_RET proc_async_task(MppEncImpl *enc, EncAsyncWait *wait) goto SEND_TASK_INFO; if (!status->check_frm_pskip) { - RK_S32 force_pskip = 0; + MppPskipMode skip_mode; status->check_frm_pskip = 1; - if (mpp_frame_has_meta(hal_task->frame)) { - MppMeta frm_meta = mpp_frame_get_meta(hal_task->frame); - if (frm_meta) - mpp_meta_get_s32(frm_meta, KEY_INPUT_PSKIP, &force_pskip); - } - - if (force_pskip == 1) { - frm->force_pskip = 1; + mpp_enc_get_pskip_mode((Mpp*)enc->mpp, async, &skip_mode); + if (skip_mode.pskip_is_ref || skip_mode.pskip_is_non_ref) { ret = mpp_enc_force_pskip((Mpp*)enc->mpp, async); - if (ret) enc_dbg_detail("task %d set force pskip failed.", frm->seq_idx); else diff --git a/mpp/common/h265e_syntax_new.h b/mpp/common/h265e_syntax_new.h index cd77ac0c..dadec201 100644 --- a/mpp/common/h265e_syntax_new.h +++ b/mpp/common/h265e_syntax_new.h @@ -210,7 +210,6 @@ typedef struct UserDatas_t { typedef struct H265eSyntax_new_t { RK_S32 idr_request; - RK_S32 pre_ref_idx; H265ePicParams pp; H265eSlicParams sp; void *dpb; diff --git a/mpp/hal/common/hal_bufs.c b/mpp/hal/common/hal_bufs.c index 41648e50..51ba9ca6 100644 --- a/mpp/hal/common/hal_bufs.c +++ b/mpp/hal/common/hal_bufs.c @@ -225,7 +225,7 @@ HalBuf *hal_bufs_get_buf(HalBufs bufs, RK_S32 buf_idx) RK_S32 i; if (NULL == impl || buf_idx < 0 || buf_idx >= impl->max_cnt) { - mpp_err_f("invalid input impl %p buf_idx %d\n", impl, buf_idx); + mpp_err_f("invalid input impl %p buf_idx %d max_cnt %d\n", impl, buf_idx, impl->max_cnt); return NULL; }