diff --git a/mpp/codec/dec/vp9/vp9d_parser.c b/mpp/codec/dec/vp9/vp9d_parser.c index d6009bd7..329731f2 100644 --- a/mpp/codec/dec/vp9/vp9d_parser.c +++ b/mpp/codec/dec/vp9/vp9d_parser.c @@ -393,6 +393,9 @@ static RK_S32 vp9_alloc_frame(Vp9CodecContext *ctx, VP9Frame *frame) mpp_frame_set_errinfo(frame->f, 0); mpp_frame_set_discard(frame->f, 0); mpp_frame_set_pts(frame->f, s->pts); + // set current poc + s->cur_poc++; + mpp_frame_set_poc(frame->f, s->cur_poc); if (MPP_FRAME_FMT_IS_FBC(s->cfg->base.out_fmt)) { mpp_slots_set_prop(s->slots, SLOTS_HOR_ALIGN, hor_align_64); @@ -635,8 +638,9 @@ static RK_S32 decode_parser_header(Vp9CodecContext *ctx, return MPP_ERR_STREAM; } vp9d_dbg(VP9D_DBG_HEADER, "profile %d", ctx->profile); - if (mpp_get_bit1(&s->gb)) { - vp9d_dbg(VP9D_DBG_HEADER, "show_existing_frame 1"); + s->show_existing_frame = mpp_get_bit1(&s->gb); + vp9d_dbg(VP9D_DBG_HEADER, "show_existing_frame %d", s->show_existing_frame); + if (s->show_existing_frame) { *refo = mpp_get_bits(&s->gb, 3); vp9d_dbg(VP9D_DBG_HEADER, "frame_to_show %d", *refo); return 0; @@ -1732,6 +1736,7 @@ MPP_RET vp9d_paser_reset(Vp9CodecContext *ctx) VP9ParseContext *pc = (VP9ParseContext *)ps->priv_data; s->got_keyframes = 0; + s->cur_poc = 0; for (i = 0; i < 3; i++) { if (s->frames[i].ref) { vp9_unref_frame(s, &s->frames[i]); diff --git a/mpp/codec/dec/vp9/vp9d_parser.h b/mpp/codec/dec/vp9/vp9d_parser.h index 004e12da..43ae6f2f 100644 --- a/mpp/codec/dec/vp9/vp9d_parser.h +++ b/mpp/codec/dec/vp9/vp9d_parser.h @@ -119,6 +119,7 @@ typedef struct VP9Context { RK_S32 y_stride, uv_stride; // bitstream header + RK_U8 show_existing_frame; RK_U8 keyframe, last_keyframe; RK_U8 last_bpp, bpp, bpp_index, bytesperpixel; RK_U8 invisible; @@ -259,6 +260,7 @@ typedef struct VP9Context { RK_S64 pts; RK_S32 upprobe_num; RK_S32 outframe_num; + RK_U32 cur_poc; } VP9Context; #ifdef __cplusplus diff --git a/mpp/codec/dec/vp9/vp9d_parser2_syntax.c b/mpp/codec/dec/vp9/vp9d_parser2_syntax.c index 1df60ee0..7028d0c8 100644 --- a/mpp/codec/dec/vp9/vp9d_parser2_syntax.c +++ b/mpp/codec/dec/vp9/vp9d_parser2_syntax.c @@ -79,6 +79,7 @@ static int vp9d_fill_picparams(Vp9CodecContext *ctx, DXVA_PicParams_VP9 *pic) int i; pic->profile = ctx->profile; + pic->show_existing_frame = s->show_existing_frame; pic->frame_type = !s->keyframe; pic->show_frame = !s->invisible; pic->error_resilient_mode = s->errorres; diff --git a/mpp/common/vp9d_syntax.h b/mpp/common/vp9d_syntax.h index 31bc130a..0549b7e0 100644 --- a/mpp/common/vp9d_syntax.h +++ b/mpp/common/vp9d_syntax.h @@ -104,7 +104,7 @@ typedef struct _DXVA_PicParams_VP9 { USHORT reset_frame_context : 2; USHORT allow_high_precision_mv : 1; USHORT parallelmode : 1; - USHORT ReservedFormatInfo2Bits : 1; + USHORT show_existing_frame : 1; }; USHORT wFormatAndPictureInfoFlags; }; diff --git a/mpp/hal/rkdec/inc/vdpu34x_com.h b/mpp/hal/rkdec/inc/vdpu34x_com.h index f9c1a72b..d8182c27 100644 --- a/mpp/hal/rkdec/inc/vdpu34x_com.h +++ b/mpp/hal/rkdec/inc/vdpu34x_com.h @@ -219,9 +219,27 @@ typedef struct Vdpu34xRegCommon_t { RK_U32 reserve : 11; RK_U32 reg_cfg_gating_en : 1; } reg026; + RK_U32 reg027; + struct SWREG28_MULTIPLY_CORE_CTRL { + RK_U32 swreg_vp9_wr_prob_idx : 3; + RK_U32 reserve0 : 1; + RK_U32 swreg_vp9_rd_prob_idx : 3; + RK_U32 reserve1 : 1; + RK_U32 swreg_ref_req_advance_flag : 1; + RK_U32 sw_colmv_req_advance_flag : 1; + RK_U32 sw_poc_only_highbit_flag : 1; + RK_U32 sw_poc_arb_flag : 1; + + RK_U32 reserve2 : 4; + RK_U32 sw_film_idx : 10; + RK_U32 reserve3 : 2; + RK_U32 sw_pu_req_mismatch_dis : 1; + RK_U32 sw_colmv_req_mismatch_dis : 1; + RK_U32 reserve4 : 2; + } reg028; /* NOTE: reg027 ~ reg032 are added in vdpu38x at rk3588 */ - RK_U32 reg027_031[5]; + RK_U32 reg029_031[3]; /* NOTE: timeout must be config in vdpu38x */ RK_U32 reg032_timeout_threshold; } Vdpu34xRegCommon; diff --git a/mpp/hal/rkdec/inc/vdpu34x_vp9d.h b/mpp/hal/rkdec/inc/vdpu34x_vp9d.h index b118c4c6..234bdb0e 100644 --- a/mpp/hal/rkdec/inc/vdpu34x_vp9d.h +++ b/mpp/hal/rkdec/inc/vdpu34x_vp9d.h @@ -28,12 +28,10 @@ typedef struct Vdpu34xRegVp9dParam_t { } reg64; struct SWREG65_CUR_POC { - RK_U32 cur_top_poc : 32; + RK_U32 cur_poc : 32; } reg65; - struct SWREG66_H264_CUR_POC1 { - RK_U32 cur_bot_poc : 32; - } reg66; + RK_U32 reg66; struct SWREG67_74_VP9_SEGID_GRP { RK_U32 segid_abs_delta : 1; @@ -49,7 +47,8 @@ typedef struct Vdpu34xRegVp9dParam_t { struct SWREG75_VP9_INFO_LASTFRAME { RK_U32 mode_deltas_lastframe : 14; - RK_U32 reserve0 : 2; + RK_U32 vp9_segment_id_clear : 1; + RK_U32 vp9_segment_id_update : 1; RK_U32 segmentation_enable_lstframe : 1; RK_U32 last_show_frame : 1; RK_U32 last_intra_only : 1; @@ -154,7 +153,31 @@ typedef struct Vdpu34xRegVp9dParam_t { RK_U32 reserve : 4; } reg94; - RK_U32 reg95_102_no_use[8]; + struct SWREG95_LAST_POC { + RK_U32 last_poc : 32; + } reg95; + + struct SWREG96_GOLDEN_POC { + RK_U32 golden_poc : 32; + } reg96; + + struct SWREG97_ALTREF_POC { + RK_U32 altref_poc : 32; + } reg97; + + struct SWREG98_COF_REF_POC { + RK_U32 col_ref_poc : 32; + } reg98; + + struct SWREG99_PROB_REF_POC { + RK_U32 prob_ref_poc : 32; + } reg99; + + struct SWREG100_SEGID_REF_POC { + RK_U32 segid_ref_poc : 32; + } reg100; + + RK_U32 reg101_102_no_use[2]; struct SWREG103_VP9_PROB_EN { RK_U32 reserve : 20; diff --git a/mpp/hal/rkdec/vp9d/hal_vp9d_vdpu34x.c b/mpp/hal/rkdec/vp9d/hal_vp9d_vdpu34x.c index 58ec19a0..f36c327a 100644 --- a/mpp/hal/rkdec/vp9d/hal_vp9d_vdpu34x.c +++ b/mpp/hal/rkdec/vp9d/hal_vp9d_vdpu34x.c @@ -69,6 +69,9 @@ typedef struct Vdpu34xVp9dCtx_t { RK_S32 mv_count; RK_U32 prob_ctx_valid[VP9_CONTEXT]; MppBuffer prob_loop_base[VP9_CONTEXT]; + RK_U32 prob_ref_poc[VP9_CONTEXT]; + RK_U32 col_ref_poc; + RK_U32 segid_ref_poc; } Vdpu34xVp9dCtx; static MPP_RET hal_vp9d_alloc_res(HalVp9dCtx *hal) @@ -529,6 +532,51 @@ static MPP_RET hal_vp9d_vdpu34x_gen_regs(void *hal, HalTaskInfo *task) vp9_hw_regs->vp9d_param.reg103.allow_high_precision_mv = pic_param->allow_high_precision_mv; vp9_hw_regs->vp9d_param.reg103.last_key_frame_flag = hw_ctx->ls_info.last_intra_only; + /* set info for multi core */ + { + MppFrame mframe = NULL; + RK_U8 ref_frame_idx = 0; + + vp9_hw_regs->common.reg028.sw_poc_arb_flag = 1; + mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, SLOT_FRAME, &mframe); + + vp9_hw_regs->vp9d_param.reg65.cur_poc = mpp_frame_get_poc(mframe); + // last poc + ref_idx = pic_param->frame_refs[0].Index7Bits; + ref_frame_idx = pic_param->ref_frame_map[ref_idx].Index7Bits; + if (ref_frame_idx < 0x7f) { + mpp_buf_slot_get_prop(p_hal ->slots, ref_frame_idx, SLOT_FRAME, &mframe); + vp9_hw_regs->vp9d_param.reg95.last_poc = mpp_frame_get_poc(mframe); + } + // golden poc + ref_idx = pic_param->frame_refs[1].Index7Bits; + ref_frame_idx = pic_param->ref_frame_map[ref_idx].Index7Bits; + if (ref_frame_idx < 0x7f) { + mpp_buf_slot_get_prop(p_hal ->slots, ref_frame_idx, SLOT_FRAME, &mframe); + vp9_hw_regs->vp9d_param.reg96.golden_poc = mpp_frame_get_poc(mframe); + } + // altref poc + ref_idx = pic_param->frame_refs[2].Index7Bits; + ref_frame_idx = pic_param->ref_frame_map[ref_idx].Index7Bits; + if (ref_frame_idx < 0x7f) { + mpp_buf_slot_get_prop(p_hal ->slots, ref_frame_idx, SLOT_FRAME, &mframe); + vp9_hw_regs->vp9d_param.reg97.altref_poc = mpp_frame_get_poc(mframe); + } + // colref poc + vp9_hw_regs->vp9d_param.reg98.col_ref_poc = + hw_ctx->col_ref_poc ? hw_ctx->col_ref_poc : vp9_hw_regs->vp9d_param.reg65.cur_poc; + if (pic_param->show_frame && !pic_param->show_existing_frame) + hw_ctx->col_ref_poc = vp9_hw_regs->vp9d_param.reg65.cur_poc; + // segment id ref poc + vp9_hw_regs->vp9d_param.reg100.segid_ref_poc = hw_ctx->segid_ref_poc; + + if ((pic_param->stVP9Segments.enabled && pic_param->stVP9Segments.update_map) || + (hw_ctx->ls_info.last_width != pic_param->width) || + (hw_ctx->ls_info.last_height != pic_param->height) || + intraFlag || pic_param->error_resilient_mode) { + hw_ctx->segid_ref_poc = vp9_hw_regs->vp9d_param.reg65.cur_poc; + } + } /* config last prob base and update write base */ { @@ -564,15 +612,24 @@ static MPP_RET hal_vp9d_vdpu34x_gen_regs(void *hal, HalTaskInfo *task) fclose(fp); } #endif + if (hw_ctx->prob_ctx_valid[frame_ctx_id]) { vp9_hw_regs->vp9d_addr.reg162_last_prob_base = mpp_buffer_get_fd(hw_ctx->prob_loop_base[frame_ctx_id]); + vp9_hw_regs->common.reg028.swreg_vp9_rd_prob_idx = frame_ctx_id + 1; + vp9_hw_regs->vp9d_param.reg99.prob_ref_poc = hw_ctx->prob_ref_poc[frame_ctx_id]; } else { vp9_hw_regs->vp9d_addr.reg162_last_prob_base = mpp_buffer_get_fd(hw_ctx->prob_default_base); hw_ctx->prob_ctx_valid[frame_ctx_id] |= pic_param->refresh_frame_context; + vp9_hw_regs->common.reg028.swreg_vp9_rd_prob_idx = 0; + vp9_hw_regs->vp9d_param.reg99.prob_ref_poc = 0; + if (pic_param->refresh_frame_context) + hw_ctx->prob_ref_poc[frame_ctx_id] = vp9_hw_regs->vp9d_param.reg65.cur_poc; } vp9_hw_regs->vp9d_addr.reg172_update_prob_wr_base = mpp_buffer_get_fd(hw_ctx->prob_loop_base[frame_ctx_id]); + vp9_hw_regs->common.reg028.swreg_vp9_wr_prob_idx = frame_ctx_id + 1; + } vp9_hw_regs->vp9d_addr.reg160_delta_prob_base = mpp_buffer_get_fd(hw_ctx->probe_base); #else