From f0079f49d247288631aa42e83e20f7b2d456f2f6 Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Thu, 24 Feb 2022 17:18:38 +0800 Subject: [PATCH] [h264e_vepu580]: Add dpb hal func and more buffer Change-Id: I1e458732b821571d25079aebe19831948bd591ee Signed-off-by: Herman Chen --- inc/rk_venc_cmd.h | 3 + mpp/codec/enc/h264/h264e_api_v2.c | 1 + mpp/codec/enc/h264/h264e_dpb.c | 77 ++++++++++++++++++++----- mpp/codec/enc/h264/h264e_dpb.h | 16 ++++- mpp/hal/inc/hal_enc_task.h | 3 + mpp/hal/rkenc/h264e/hal_h264e_vepu580.c | 23 +++++++- 6 files changed, 107 insertions(+), 16 deletions(-) diff --git a/inc/rk_venc_cmd.h b/inc/rk_venc_cmd.h index bd44fcaf..c389cd2c 100644 --- a/inc/rk_venc_cmd.h +++ b/inc/rk_venc_cmd.h @@ -397,6 +397,9 @@ typedef struct MppEncHwCfg_t { /* vepu1/2 */ RK_S32 mb_rc_disable; + + /* vepu580 */ + RK_S32 extra_buf; } MppEncHwCfg; /* diff --git a/mpp/codec/enc/h264/h264e_api_v2.c b/mpp/codec/enc/h264/h264e_api_v2.c index df47d319..a16fb240 100644 --- a/mpp/codec/enc/h264/h264e_api_v2.c +++ b/mpp/codec/enc/h264/h264e_api_v2.c @@ -644,6 +644,7 @@ static MPP_RET h264e_proc_hal(void *ctx, HalEncTask *task) h264e_add_syntax(p, H264E_SYN_CFG, p->cfg); h264e_add_syntax(p, H264E_SYN_SPS, &p->sps); h264e_add_syntax(p, H264E_SYN_PPS, &p->pps); + h264e_add_syntax(p, H264E_SYN_DPB, &p->dpb); h264e_add_syntax(p, H264E_SYN_SLICE, &p->slice); h264e_add_syntax(p, H264E_SYN_FRAME, &p->frms); diff --git a/mpp/codec/enc/h264/h264e_dpb.c b/mpp/codec/enc/h264/h264e_dpb.c index 98692b78..d33dd928 100644 --- a/mpp/codec/enc/h264/h264e_dpb.c +++ b/mpp/codec/enc/h264/h264e_dpb.c @@ -25,6 +25,22 @@ #include "h264e_dpb.h" #include "h264e_slice.h" +void h264e_dpb_dump_usage(H264eDpb *dpb, const char *fmt) +{ + RK_S32 i = 0; + char buf[256]; + RK_S32 pos = 0; + + pos += snprintf(buf, sizeof(buf) - 1, "total %2d ", dpb->total_cnt); + + for (i = 0; i < dpb->total_cnt; i++) { + H264eDpbFrm *frm = &dpb->frames[i]; + + pos += snprintf(buf + pos, sizeof(buf) - 1 - pos, "%04x ", frm->on_used); + } + mpp_log("%s %s", fmt, buf); +} + void h264e_dpb_dump_frm(H264eDpb *dpb, const char *caller, RK_S32 line) { RK_S32 i = 0; @@ -123,6 +139,9 @@ MPP_RET h264e_dpb_setup(H264eDpb *dpb, MppEncCfgSet* cfg, H264eSps *sps) dpb->max_poc_lsb = (1 << log2_max_poc_lsb); dpb->poc_type = sps->pic_order_cnt_type; + if (cfg->hw.extra_buf) + dpb->total_cnt++; + h264e_dbg_dpb("max ref frm num %d total slot %d\n", ref_frm_num, dpb->total_cnt); h264e_dbg_dpb("log2 max frm num %d -> %d\n", @@ -135,9 +154,11 @@ MPP_RET h264e_dpb_setup(H264eDpb *dpb, MppEncCfgSet* cfg, H264eSps *sps) return ret; } -H264eDpbFrm *find_cpb_frame(H264eDpbFrm *frms, RK_S32 cnt, EncFrmStatus *frm) +H264eDpbFrm *find_cpb_frame(H264eDpb *dpb, EncFrmStatus *frm) { + H264eDpbFrm *frms = dpb->frames; RK_S32 seq_idx = frm->seq_idx; + RK_S32 cnt = dpb->total_cnt; RK_S32 i; if (!frm->valid) @@ -161,6 +182,8 @@ H264eDpbFrm *find_cpb_frame(H264eDpbFrm *frms, RK_S32 cnt, EncFrmStatus *frm) } mpp_err_f("can not find match frm %d\n", seq_idx); + h264e_dpb_dump_frms(dpb); + abort(); return NULL; } @@ -230,7 +253,7 @@ void h264e_dpb_build_list(H264eDpb *dpb, EncCpbStatus *cpb) h264e_dbg_list("idx %d frm %d valid %d is_non_ref %d lt_ref %d\n", i, frm->seq_idx, frm->valid, frm->is_non_ref, frm->is_lt_ref); - H264eDpbFrm *p = find_cpb_frame(dpb->frames, dpb->total_cnt, frm); + H264eDpbFrm *p = find_cpb_frame(dpb, frm); if (!frm->is_lt_ref) { dpb->stref[st_size++] = p; p->status.val = frm->val; @@ -413,7 +436,7 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) if (curr->is_idr) { for (i = 0; i < H264E_MAX_REFS_CNT + 1; i++) { - frames[i].on_used = 0; + frames[i].dpb_used = 0; frames[i].status.valid = 0; } dpb->used_size = 0; @@ -434,13 +457,13 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) * user defined cpb to hal slot index */ for (i = 0; i < MAX_CPB_REFS; i++) { - H264eDpbFrm *frm = find_cpb_frame(frames, dpb->total_cnt, &init[i]); + H264eDpbFrm *frm = find_cpb_frame(dpb, &init[i]); dpb->map[i] = frm; if (frm) { if (!frm->on_used) mpp_err_f("warning frm %d is used by cpb but on not used status\n", frm->seq_idx); - frm->on_used = 1; + frm->dpb_used = 1; used_size++; } } @@ -475,7 +498,8 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) } } - h264e_dbg_dpb("slot %2d check in cpb init valid %d\n", i, valid); + h264e_dbg_dpb("slot %2d check in cpb init valid %d used %04x\n", + i, valid, p->on_used); if (valid) { if (!p->on_used || !p->status.valid) { @@ -486,12 +510,19 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) continue; } + h264e_dbg_dpb("slot %2d used %04x checking\n", i, p->on_used); + + if (p->hal_used) + continue; + if (found_curr) { - p->on_used = 0; + p->dpb_used = 0; p->status.valid = 0; continue; } + h264e_dbg_dpb("slot %2d used %04x mark as current\n", i, p->on_used); + dpb->curr = p; p->status.val = curr->val; p->seq_idx = curr->seq_idx; @@ -523,7 +554,7 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) } p->lt_idx = curr->lt_idx; - p->on_used = 1; + p->dpb_used = 1; rt->last_seq_idx = curr->seq_idx; rt->last_is_ref = !curr->is_non_ref; @@ -542,7 +573,7 @@ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb) mpp_err_f("frm %d failed to find a slot for curr %d\n", seq_idx); h264e_dbg_dpb("frm %d start finding slot for refr %d\n", seq_idx, refr->seq_idx); - dpb->refr = find_cpb_frame(frames, dpb->total_cnt, refr); + dpb->refr = find_cpb_frame(dpb, refr); if (NULL == dpb->refr) dpb->refr = dpb->curr; @@ -576,7 +607,7 @@ void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb) curr->seq_idx, refr->seq_idx); if (curr->status.is_non_ref) { - curr->on_used = 0; + curr->dpb_used = 0; curr->status.valid = 0; } else { /* sliding window process */ @@ -601,7 +632,7 @@ void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb) if (tmp == curr) continue; - if (!tmp->on_used) + if (!tmp->dpb_used) continue; if (!tmp->status.valid) @@ -613,7 +644,7 @@ void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb) continue; if (tmp->lt_idx == lt_idx) { - tmp->on_used = 0; + tmp->dpb_used = 0; tmp->status.valid = 0; h264e_dbg_dpb("frm %d lt_idx %d replace %d\n", curr->seq_idx, curr->lt_idx, tmp->slot_idx); @@ -665,7 +696,7 @@ void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb) h264e_dbg_dpb("removing frm %d poc %d\n", unref->seq_idx, unref->poc); - unref->on_used = 0; + unref->dpb_used = 0; dpb->st_size--; mpp_assert(dpb->st_size >= 0); used_size--; @@ -685,7 +716,7 @@ void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb) RK_S32 used_size = 0; for (i = 0; i < MAX_CPB_REFS; i++) { - dpb->map[i] = find_cpb_frame(dpb->frames, dpb->total_cnt, &cpb->final[i]); + dpb->map[i] = find_cpb_frame(dpb, &cpb->final[i]); if (dpb->map[i]) used_size++; } @@ -696,3 +727,21 @@ void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb) h264e_dbg_dpb("leave %p\n", dpb); } + +MPP_RET h264e_dpb_hal_start(H264eDpb *dpb, RK_S32 slot_idx) +{ + H264eDpbFrm *frm = &dpb->frames[slot_idx]; + + frm->hal_used++; + //h264e_dpb_dump_usage(dpb, __FUNCTION__); + return MPP_OK; +} + +MPP_RET h264e_dpb_hal_end(H264eDpb *dpb, RK_S32 slot_idx) +{ + H264eDpbFrm *frm = &dpb->frames[slot_idx]; + + frm->hal_used--; + //h264e_dpb_dump_usage(dpb, __FUNCTION__); + return MPP_OK; +} diff --git a/mpp/codec/enc/h264/h264e_dpb.h b/mpp/codec/enc/h264/h264e_dpb.h index 6e69c6a8..dd0eb414 100644 --- a/mpp/codec/enc/h264/h264e_dpb.h +++ b/mpp/codec/enc/h264/h264e_dpb.h @@ -54,7 +54,14 @@ typedef struct H264eDpbFrm_t { RK_S32 slot_idx; // frame index in frames RK_S32 seq_idx; - RK_U32 on_used; + + union { + RK_U32 on_used; + struct { + RK_U32 dpb_used : 8; + RK_U32 hal_used : 8; + }; + }; /* frame status */ EncFrmStatus status; @@ -141,6 +148,13 @@ MPP_RET h264e_dpb_setup(H264eDpb *dpb, MppEncCfgSet* cfg, H264eSps *sps); * lt_ref - current frame is marked as longterm reference */ MPP_RET h264e_dpb_proc(H264eDpb *dpb, EncCpbStatus *cpb); + +/* + * hal usage flag mark / unmark function + */ +MPP_RET h264e_dpb_hal_start(H264eDpb *dpb, RK_S32 slot_idx); +MPP_RET h264e_dpb_hal_end(H264eDpb *dpb, RK_S32 slot_idx); + void h264e_dpb_check(H264eDpb *dpb, EncCpbStatus *cpb); #define h264e_dpb_dump_frms(dpb) h264e_dpb_dump_frm(dpb, __FUNCTION__, __LINE__) diff --git a/mpp/hal/inc/hal_enc_task.h b/mpp/hal/inc/hal_enc_task.h index 57fefce2..8f4f2c57 100644 --- a/mpp/hal/inc/hal_enc_task.h +++ b/mpp/hal/inc/hal_enc_task.h @@ -35,6 +35,9 @@ typedef struct HalEncTaskFlag_t { RK_U32 err; RK_S32 drop_by_fps; RK_S32 reg_idx; + /* hal buf index */ + RK_S32 curr_idx; + RK_S32 refr_idx; } HalEncTaskFlag; typedef struct MppSyntax_t { diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c index b92e9bf6..125f3351 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c @@ -26,6 +26,7 @@ #include "h264e_sps.h" #include "h264e_pps.h" +#include "h264e_dpb.h" #include "h264e_slice.h" #include "hal_h264e_debug.h" @@ -62,6 +63,7 @@ typedef struct HalH264eVepu580Ctx_t { RK_U32 updated; H264eSps *sps; H264ePps *pps; + H264eDpb *dpb; H264eSlice *slice; H264eFrmInfo *frms; H264eReorderInfo *reorder; @@ -248,6 +250,7 @@ static MPP_RET hal_h264e_vepu580_init(void *hal, MppEncHalCfg *cfg) hw->qp_delta_row_i = 2; hw->qp_delta_row = 2; + hw->extra_buf = 1; memcpy(hw->aq_thrd_i, h264_aq_tthd_default, sizeof(hw->aq_thrd_i)); memcpy(hw->aq_thrd_p, h264_aq_tthd_default, sizeof(hw->aq_thrd_p)); @@ -286,7 +289,7 @@ static void setup_hal_bufs(HalH264eVepu580Ctx *ctx) RK_S32 pixel_buf_size = pixel_buf_fbc_hdr_size + pixel_buf_fbc_bdy_size; RK_S32 thumb_buf_size = MPP_ALIGN(aligned_w / 64 * aligned_h / 64 * 256, SZ_8K); RK_S32 old_max_cnt = ctx->max_buf_cnt; - RK_S32 new_max_cnt = 2; + RK_S32 new_max_cnt = 4; MppEncRefCfg ref_cfg = cfg->ref_cfg; if (ref_cfg) { @@ -391,6 +394,10 @@ static RK_U32 update_vepu580_syntax(HalH264eVepu580Ctx *ctx, MppSyntax *syntax) hal_h264e_dbg_detail("update pps"); ctx->pps = desc->p; } break; + case H264E_SYN_DPB : { + hal_h264e_dbg_detail("update dpb"); + ctx->dpb = desc->p; + } break; case H264E_SYN_SLICE : { hal_h264e_dbg_detail("update slice"); ctx->slice = desc->p; @@ -419,6 +426,7 @@ static MPP_RET hal_h264e_vepu580_get_task(void *hal, HalEncTask *task) HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal; RK_U32 updated = update_vepu580_syntax(ctx, &task->syntax); EncFrmStatus *frm_status = &task->rc_task->frm; + H264eFrmInfo *frms = ctx->frms; hal_h264e_dbg_func("enter %p\n", hal); @@ -433,7 +441,15 @@ static MPP_RET hal_h264e_vepu580_get_task(void *hal, HalEncTask *task) mpp_meta_get_ptr_d(meta, KEY_OSD_DATA2, (void **)&ctx->osd_cfg.osd_data2, NULL); } + if (ctx->dpb) { + h264e_dpb_hal_start(ctx->dpb, frms->curr_idx); + h264e_dpb_hal_start(ctx->dpb, frms->refr_idx); + } + task->flags.reg_idx = ctx->task_idx; + task->flags.curr_idx = frms->curr_idx; + task->flags.refr_idx = frms->refr_idx; + ctx->ext_line_buf = ctx->ext_line_bufs[ctx->task_idx]; ctx->regs_set = &ctx->regs_sets[ctx->task_idx]; ctx->osd_cfg.reg_base = &ctx->regs_set->reg_osd; @@ -2072,6 +2088,11 @@ static MPP_RET hal_h264e_vepu580_ret_task(void *hal, HalEncTask *task) mpp_dev_multi_offset_reset(ctx->offsets); + if (ctx->dpb) { + h264e_dpb_hal_end(ctx->dpb, task->flags.curr_idx); + h264e_dpb_hal_end(ctx->dpb, task->flags.refr_idx); + } + hal_h264e_dbg_func("leave %p\n", hal); return MPP_OK;