diff --git a/inc/mpp_frame.h b/inc/mpp_frame.h index 96a874d0..965a8e18 100644 --- a/inc/mpp_frame.h +++ b/inc/mpp_frame.h @@ -330,6 +330,12 @@ typedef enum MppFrameError { MPP_FRAME_ERR_DEC_MISS_REF = 0x0200, } MppFrameError; +typedef enum { + MPP_FRAME_THUMBNAIL_NONE, + MPP_FRAME_THUMBNAIL_MIXED, + MPP_FRAME_THUMBNAIL_ONLY, +} MppFrameThumbnailMode; + #ifdef __cplusplus extern "C" { #endif diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 391df8e5..27de4800 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -106,6 +106,7 @@ typedef enum { MPP_DEC_SET_DISABLE_THREAD, /* MPP no thread mode and use external thread to decode */ MPP_DEC_SET_MAX_USE_BUFFER_SIZE, MPP_DEC_SET_ENABLE_MVC, /* enable MVC decoding*/ + MPP_DEC_GET_THUMBNAIL_FRAME_INFO, /* update thumbnail frame info to user, for MPP_FRAME_THUMBNAIL_ONLY mode */ MPP_DEC_CMD_QUERY = CMD_MODULE_CODEC | CMD_CTX_ID_DEC | CMD_DEC_QUERY, /* query decoder runtime information for decode stage */ diff --git a/mpp/base/mpp_buf_slot.cpp b/mpp/base/mpp_buf_slot.cpp index c7b4aace..4a48b880 100644 --- a/mpp/base/mpp_buf_slot.cpp +++ b/mpp/base/mpp_buf_slot.cpp @@ -363,7 +363,7 @@ static void generate_info_set(MppBufSlotsImpl *impl, MppFrame frame, RK_U32 forc mpp_frame_set_ver_stride(frame, hal_ver_stride); mpp_frame_set_hor_stride_pixel(frame, hor_stride_pixel); impl->buf_size = size; - if (mpp_frame_get_thumbnail_en(frame)) { + if (mpp_frame_get_thumbnail_en(frame) == MPP_FRAME_THUMBNAIL_MIXED) { /* * The decode hw only support 1/2 scaling in width and height, * downscale output image only support raster mode with 8bit depth. diff --git a/mpp/codec/dec/av1/av1d_parser.c b/mpp/codec/dec/av1/av1d_parser.c index de7417d1..274dd4b7 100644 --- a/mpp/codec/dec/av1/av1d_parser.c +++ b/mpp/codec/dec/av1/av1d_parser.c @@ -794,7 +794,8 @@ static MPP_RET get_current_frame(Av1CodecContext *ctx) ctx->pix_fmt |= s->cfg->base.out_fmt & (MPP_FRAME_FBC_MASK); mpp_frame_set_offset_x(frame->f, 0); mpp_frame_set_offset_y(frame->f, 0); - mpp_frame_set_ver_stride(frame->f, MPP_ALIGN(ctx->height, 8) + 28); + if (mpp_get_soc_type() == ROCKCHIP_SOC_RK3588) + mpp_frame_set_ver_stride(frame->f, MPP_ALIGN(ctx->height, 8) + 28); } else if (MPP_FRAME_FMT_IS_TILE(s->cfg->base.out_fmt)) { ctx->pix_fmt |= s->cfg->base.out_fmt & (MPP_FRAME_TILE_FLAG); } @@ -805,7 +806,7 @@ static MPP_RET get_current_frame(Av1CodecContext *ctx) mpp_frame_set_fmt(frame->f, ctx->pix_fmt); if (s->cfg->base.enable_thumbnail && s->hw_info && s->hw_info->cap_down_scale) - mpp_frame_set_thumbnail_en(frame->f, 1); + mpp_frame_set_thumbnail_en(frame->f, s->cfg->base.enable_thumbnail); else mpp_frame_set_thumbnail_en(frame->f, 0); diff --git a/mpp/codec/dec/avs2/avs2d_dpb.c b/mpp/codec/dec/avs2/avs2d_dpb.c index d07abc3c..31e61e6b 100644 --- a/mpp/codec/dec/avs2/avs2d_dpb.c +++ b/mpp/codec/dec/avs2/avs2d_dpb.c @@ -520,7 +520,7 @@ static Avs2dFrame_t *dpb_alloc_frame(Avs2dCtx_t *p_dec, HalDecTask *task) mpp_frame_set_fmt(mframe, mpp_frame_get_fmt(mframe) | MPP_FRAME_HDR); if (p_dec->init.cfg->base.enable_thumbnail && p_dec->init.hw_info->cap_down_scale) - mpp_frame_set_thumbnail_en(mframe, 1); + mpp_frame_set_thumbnail_en(mframe, p_dec->init.cfg->base.enable_thumbnail); else mpp_frame_set_thumbnail_en(mframe, 0); diff --git a/mpp/codec/dec/h264/h264d_init.c b/mpp/codec/dec/h264/h264d_init.c index a841ae61..e45ce8f2 100644 --- a/mpp/codec/dec/h264/h264d_init.c +++ b/mpp/codec/dec/h264/h264d_init.c @@ -529,7 +529,7 @@ static MPP_RET dpb_mark_malloc(H264dVideoCtx_t *p_Vid, H264_StorePic_t *dec_pic) } if (p_Dec->cfg->base.enable_thumbnail && p_Dec->hw_info->cap_down_scale) - mpp_frame_set_thumbnail_en(p_Dec->curframe, 1); + mpp_frame_set_thumbnail_en(p_Dec->curframe, p_Dec->cfg->base.enable_thumbnail); else mpp_frame_set_thumbnail_en(p_Dec->curframe, 0); diff --git a/mpp/codec/dec/h265/h265d_refs.c b/mpp/codec/dec/h265/h265d_refs.c index 65b88cb8..1c31ad0c 100644 --- a/mpp/codec/dec/h265/h265d_refs.c +++ b/mpp/codec/dec/h265/h265d_refs.c @@ -126,7 +126,7 @@ static HEVCFrame *alloc_frame(HEVCContext *s) } if (s->h265dctx->cfg->base.enable_thumbnail && s->h265dctx->hw_info->cap_down_scale) - mpp_frame_set_thumbnail_en(frame->frame, 1); + mpp_frame_set_thumbnail_en(frame->frame, s->h265dctx->cfg->base.enable_thumbnail); else mpp_frame_set_thumbnail_en(frame->frame, 0); diff --git a/mpp/codec/dec/vp9/vp9d_parser.c b/mpp/codec/dec/vp9/vp9d_parser.c index 04835848..baa8a895 100644 --- a/mpp/codec/dec/vp9/vp9d_parser.c +++ b/mpp/codec/dec/vp9/vp9d_parser.c @@ -419,7 +419,7 @@ static RK_S32 vp9_alloc_frame(Vp9CodecContext *ctx, VP9Frame *frame) } if (s->cfg->base.enable_thumbnail && s->hw_info->cap_down_scale) - mpp_frame_set_thumbnail_en(frame->f, 1); + mpp_frame_set_thumbnail_en(frame->f, s->cfg->base.enable_thumbnail); else mpp_frame_set_thumbnail_en(frame->f, 0); diff --git a/mpp/codec/mpp_dec_normal.cpp b/mpp/codec/mpp_dec_normal.cpp index f629588a..986056d4 100644 --- a/mpp/codec/mpp_dec_normal.cpp +++ b/mpp/codec/mpp_dec_normal.cpp @@ -602,7 +602,18 @@ static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task) output = task_dec->output; mpp_buf_slot_get_prop(frame_slots, output, SLOT_BUFFER, &hal_buf_out); if (NULL == hal_buf_out) { + MppFrame mframe = NULL; + mpp_buf_slot_get_prop(frame_slots, output, + SLOT_FRAME_PTR, &mframe); size_t size = mpp_buf_slot_get_size(frame_slots); + + if (mframe && mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY) { + // only for 8K thumbnail downscale to 4K 8bit mode + RK_U32 downscale_width = mpp_frame_get_width(mframe) / 2; + RK_U32 downscale_height = mpp_frame_get_height(mframe) / 2; + + size = downscale_width * downscale_height * 3 / 2; + } mpp_buffer_get(mpp->mFrameGroup, &hal_buf_out, size); if (hal_buf_out) mpp_buf_slot_set_prop(frame_slots, output, SLOT_BUFFER, diff --git a/mpp/hal/rkdec/h264d/hal_h264d_vdpu383.c b/mpp/hal/rkdec/h264d/hal_h264d_vdpu383.c index 16136af8..ed25850a 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_vdpu383.c +++ b/mpp/hal/rkdec/h264d/hal_h264d_vdpu383.c @@ -108,6 +108,7 @@ typedef struct Vdpu383H264dRegCtx_t { MppBuffer rcb_buf[VDPU383_FAST_REG_SET_CNT]; Vdpu383H264dRegSet *regs; + HalBufs origin_bufs; } Vdpu383H264dRegCtx; MPP_RET vdpu383_h264d_deinit(void *hal); @@ -126,6 +127,32 @@ static RK_U32 rkv_len_align_422(RK_U32 val) return ((5 * MPP_ALIGN(val, 16)) / 2); } +static MPP_RET vdpu383_setup_scale_origin_bufs(H264dHalCtx_t *p_hal, MppFrame mframe) +{ + Vdpu383H264dRegCtx *ctx = (Vdpu383H264dRegCtx *)p_hal->reg_ctx; + /* for 8K FrameBuf scale mode */ + size_t origin_buf_size = 0; + + origin_buf_size = mpp_frame_get_buf_size(mframe); + + if (!origin_buf_size) { + mpp_err_f("origin_bufs get buf size failed\n"); + return MPP_NOK; + } + if (ctx->origin_bufs) { + hal_bufs_deinit(ctx->origin_bufs); + ctx->origin_bufs = NULL; + } + hal_bufs_init(&ctx->origin_bufs); + if (!ctx->origin_bufs) { + mpp_err_f("origin_bufs init fail\n"); + return MPP_ERR_NOMEM; + } + hal_bufs_setup(ctx->origin_bufs, 16, 1, &origin_buf_size); + + return MPP_OK; +} + static MPP_RET prepare_spspps(H264dHalCtx_t *p_hal, RK_U64 *data, RK_U32 len) { RK_S32 i = 0; @@ -389,6 +416,8 @@ static MPP_RET set_registers(H264dHalCtx_t *p_hal, Vdpu383H264dRegSet *regs, Hal { DXVA_PicParams_H264_MVC *pp = p_hal->pp; HalBuf *mv_buf = NULL; + HalBuf *origin_buf = NULL; + Vdpu383H264dRegCtx *ctx = (Vdpu383H264dRegCtx *)p_hal->reg_ctx; // memset(regs, 0, sizeof(Vdpu383H264dRegSet)); regs->h264d_paras.reg66_stream_len = p_hal->strm_len; @@ -462,6 +491,10 @@ static MPP_RET set_registers(H264dHalCtx_t *p_hal, Vdpu383H264dRegSet *regs, Hal /* mark 3 to differ from current frame */ mpp_buf_slot_get_prop(p_hal->frame_slots, ref_index, SLOT_BUFFER, &mbuffer); mpp_buf_slot_get_prop(p_hal->frame_slots, ref_index, SLOT_FRAME_PTR, &mframe); + if (ctx->origin_bufs && mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY) { + origin_buf = hal_bufs_get_buf(ctx->origin_bufs, ref_index); + mbuffer = origin_buf->buf[0]; + } if (pp->FrameNumList[i] < pp->frame_num && pp->FrameNumList[i] > min_frame_num && @@ -485,6 +518,10 @@ static MPP_RET set_registers(H264dHalCtx_t *p_hal, Vdpu383H264dRegSet *regs, Hal mpp_buf_slot_get_prop(p_hal->frame_slots, ref_index, SLOT_BUFFER, &mbuffer); fd = mpp_buffer_get_fd(mbuffer); + if (mpp_frame_get_thumbnail_en(mframe) == 2) { + origin_buf = hal_bufs_get_buf(ctx->origin_bufs, ref_index); + fd = mpp_buffer_get_fd(origin_buf->buf[0]); + } regs->h264d_addrs.reg170_185_ref_base[15] = fd; regs->h264d_addrs.reg195_210_payload_st_ref_base[15] = fd; mv_buf = hal_bufs_get_buf(p_hal->cmv_bufs, ref_index); @@ -514,14 +551,33 @@ static MPP_RET set_registers(H264dHalCtx_t *p_hal, Vdpu383H264dRegSet *regs, Hal { //scale down config MppFrame mframe = NULL; + MppBuffer mbuffer = NULL; + RK_S32 fd = -1; + MppFrameThumbnailMode thumbnail_mode; + mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_BUFFER, &mbuffer); mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_FRAME_PTR, &mframe); - if (mpp_frame_get_thumbnail_en(mframe)) { - regs->common_addr.reg133_scale_down_base = regs->h264d_addrs.reg168_decout_base; + fd = mpp_buffer_get_fd(mbuffer); + thumbnail_mode = mpp_frame_get_thumbnail_en(mframe); + switch (thumbnail_mode) { + case MPP_FRAME_THUMBNAIL_ONLY: + regs->common_addr.reg133_scale_down_base = fd; + origin_buf = hal_bufs_get_buf(ctx->origin_bufs, pp->CurrPic.Index7Bits); + fd = mpp_buffer_get_fd(origin_buf->buf[0]); + regs->h264d_addrs.reg168_decout_base = fd; + regs->h264d_addrs.reg192_payload_st_cur_base = fd; + regs->h264d_addrs.reg169_error_ref_base = fd; vdpu383_setup_down_scale(mframe, p_hal->dev, ®s->ctrl_regs, (void*)®s->h264d_paras); - } else { + break; + case MPP_FRAME_THUMBNAIL_MIXED: + regs->common_addr.reg133_scale_down_base = fd; + vdpu383_setup_down_scale(mframe, p_hal->dev, ®s->ctrl_regs, (void*)®s->h264d_paras); + break; + case MPP_FRAME_THUMBNAIL_NONE: + default: regs->ctrl_regs.reg9.scale_down_en = 0; + break; } } @@ -667,6 +723,11 @@ MPP_RET vdpu383_h264d_deinit(void *hal) p_hal->cmv_bufs = NULL; } + if (reg_ctx->origin_bufs) { + hal_bufs_deinit(reg_ctx->origin_bufs); + reg_ctx->origin_bufs = NULL; + } + MPP_FREE(p_hal->reg_ctx); return MPP_OK; @@ -772,6 +833,7 @@ MPP_RET vdpu383_h264d_gen_regs(void *hal, HalTaskInfo *task) RK_S32 height = MPP_ALIGN((p_hal->pp->wFrameHeightInMbsMinus1 + 1) << 4, 64); Vdpu383H264dRegCtx *ctx = (Vdpu383H264dRegCtx *)p_hal->reg_ctx; Vdpu383H264dRegSet *regs = ctx->regs; + MppFrame mframe; RK_S32 mv_size = MPP_ALIGN(width, 64) * MPP_ALIGN(height, 16); // 16 byte unit INP_CHECK(ret, NULL == p_hal); @@ -803,6 +865,12 @@ MPP_RET vdpu383_h264d_gen_regs(void *hal, HalTaskInfo *task) hal_bufs_setup(p_hal->cmv_bufs, p_hal->mv_count, 1, &size); } + mpp_buf_slot_get_prop(p_hal->frame_slots, p_hal->pp->CurrPic.Index7Bits, SLOT_FRAME_PTR, &mframe); + if (mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY && + ctx->origin_bufs == NULL) { + vdpu383_setup_scale_origin_bufs(p_hal, mframe); + } + if (p_hal->fast_mode) { RK_U32 i = 0; for (i = 0; i < MPP_ARRAY_ELEMS(ctx->reg_buf); i++) { @@ -1046,6 +1114,9 @@ MPP_RET vdpu383_h264d_control(void *hal, MpiCmd cmd_type, void *param) mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, mpp_align_128_odd_plus_64); } } break; + case MPP_DEC_GET_THUMBNAIL_FRAME_INFO: { + vdpu383_update_thumbnail_frame_info((MppFrame)param); + } break; case MPP_DEC_SET_OUTPUT_FORMAT: { } break; default : { diff --git a/mpp/hal/rkdec/h265d/hal_h265d_ctx.h b/mpp/hal/rkdec/h265d/hal_h265d_ctx.h index e0409927..c01dc72f 100644 --- a/mpp/hal/rkdec/h265d/hal_h265d_ctx.h +++ b/mpp/hal/rkdec/h265d/hal_h265d_ctx.h @@ -86,6 +86,7 @@ typedef struct HalH265dCtx_t { RK_U32 sclst_offset; void *pps_buf; void *sw_rps_buf; + HalBufs origin_bufs; const MppDecHwCap *hw_info; } HalH265dCtx; diff --git a/mpp/hal/rkdec/h265d/hal_h265d_vdpu383.c b/mpp/hal/rkdec/h265d/hal_h265d_vdpu383.c index ce2ca863..e764393a 100644 --- a/mpp/hal/rkdec/h265d/hal_h265d_vdpu383.c +++ b/mpp/hal/rkdec/h265d/hal_h265d_vdpu383.c @@ -77,6 +77,33 @@ static RK_U32 rkv_len_align_444(RK_U32 val) return (3 * MPP_ALIGN(val, 16)); } +static MPP_RET vdpu383_setup_scale_origin_bufs(HalH265dCtx *ctx, MppFrame mframe) +{ + /* for 8K FrameBuf scale mode */ + size_t origin_buf_size = 0; + + origin_buf_size = mpp_frame_get_buf_size(mframe); + + if (!origin_buf_size) { + mpp_err_f("origin_bufs get buf size failed\n"); + return MPP_NOK; + } + + if (ctx->origin_bufs) { + hal_bufs_deinit(ctx->origin_bufs); + ctx->origin_bufs = NULL; + } + hal_bufs_init(&ctx->origin_bufs); + if (!ctx->origin_bufs) { + mpp_err_f("origin_bufs init fail\n"); + return MPP_ERR_NOMEM; + } + + hal_bufs_setup(ctx->origin_bufs, 16, 1, &origin_buf_size); + + return MPP_OK; +} + static MPP_RET hal_h265d_vdpu383_init(void *hal, MppHalCfg *cfg) { RK_S32 ret = 0; @@ -202,6 +229,11 @@ static MPP_RET hal_h265d_vdpu383_deinit(void *hal) reg_ctx->cmv_bufs = NULL; } + if (reg_ctx->origin_bufs) { + hal_bufs_deinit(reg_ctx->origin_bufs); + reg_ctx->origin_bufs = NULL; + } + return MPP_OK; } @@ -879,6 +911,7 @@ static MPP_RET hal_h265d_vdpu383_gen_regs(void *hal, HalTaskInfo *syn) HalH265dCtx *reg_ctx = (HalH265dCtx *)hal; RK_S32 max_poc = dxva_ctx->pp.current_poc; RK_S32 min_poc = 0; + HalBuf *origin_buf = NULL; void *rps_ptr = NULL; if (reg_ctx ->fast_mode) { @@ -969,6 +1002,12 @@ static MPP_RET hal_h265d_vdpu383_gen_regs(void *hal, HalTaskInfo *syn) mpp_buf_slot_get_prop(reg_ctx->slots, dxva_ctx->pp.CurrPic.Index7Bits, SLOT_FRAME_PTR, &mframe); + /* for 8K downscale mode*/ + if (mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY && + reg_ctx->origin_bufs == NULL) { + vdpu383_setup_scale_origin_bufs(reg_ctx, mframe); + } + fmt = mpp_frame_get_fmt(mframe); stride_y = mpp_frame_get_hor_stride(mframe); @@ -1016,6 +1055,12 @@ static MPP_RET hal_h265d_vdpu383_gen_regs(void *hal, HalTaskInfo *syn) mpp_buf_slot_get_prop(reg_ctx->slots, dxva_ctx->pp.CurrPic.Index7Bits, SLOT_BUFFER, &framebuf); + if (reg_ctx->origin_bufs) { + origin_buf = hal_bufs_get_buf(reg_ctx->origin_bufs, + dxva_ctx->pp.CurrPic.Index7Bits); + framebuf = origin_buf->buf[0]; + } + hw_regs->h265d_addrs.reg168_decout_base = mpp_buffer_get_fd(framebuf); //just index need map hw_regs->h265d_addrs.reg169_error_ref_base = mpp_buffer_get_fd(framebuf); /*if out_base is equal to zero it means this frame may error @@ -1122,6 +1167,11 @@ static MPP_RET hal_h265d_vdpu383_gen_regs(void *hal, HalTaskInfo *syn) SLOT_BUFFER, &framebuf); mpp_buf_slot_get_prop(reg_ctx->slots, dxva_ctx->pp.RefPicList[i].Index7Bits, SLOT_FRAME_PTR, &mframe); + if (mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY) { + origin_buf = hal_bufs_get_buf(reg_ctx->origin_bufs, + dxva_ctx->pp.RefPicList[i].Index7Bits); + framebuf = origin_buf->buf[0]; + } if (framebuf != NULL) { hw_regs->h265d_addrs.reg170_185_ref_base[i] = mpp_buffer_get_fd(framebuf); hw_regs->h265d_addrs.reg195_210_payload_st_ref_base[i] = mpp_buffer_get_fd(framebuf); @@ -1188,14 +1238,32 @@ static MPP_RET hal_h265d_vdpu383_gen_regs(void *hal, HalTaskInfo *syn) { //scale down config MppFrame mframe = NULL; + MppBuffer mbuffer = NULL; + MppFrameThumbnailMode thumbnail_mode; + mpp_buf_slot_get_prop(reg_ctx->slots, dxva_ctx->pp.CurrPic.Index7Bits, + SLOT_BUFFER, &mbuffer); mpp_buf_slot_get_prop(reg_ctx->slots, dxva_ctx->pp.CurrPic.Index7Bits, SLOT_FRAME_PTR, &mframe); - if (mpp_frame_get_thumbnail_en(mframe)) { - hw_regs->common_addr.reg133_scale_down_base = hw_regs->h265d_addrs.reg168_decout_base; + thumbnail_mode = mpp_frame_get_thumbnail_en(mframe); + switch (thumbnail_mode) { + case MPP_FRAME_THUMBNAIL_ONLY: + hw_regs->common_addr.reg133_scale_down_base = mpp_buffer_get_fd(mbuffer); + origin_buf = hal_bufs_get_buf(reg_ctx->origin_bufs, dxva_ctx->pp.CurrPic.Index7Bits); + fd = mpp_buffer_get_fd(origin_buf->buf[0]); + hw_regs->h265d_addrs.reg168_decout_base = fd; + hw_regs->h265d_addrs.reg192_payload_st_cur_base = fd; + hw_regs->h265d_addrs.reg169_error_ref_base = fd; vdpu383_setup_down_scale(mframe, reg_ctx->dev, &hw_regs->ctrl_regs, (void*)&hw_regs->h265d_paras); - } else { + break; + case MPP_FRAME_THUMBNAIL_MIXED: + hw_regs->common_addr.reg133_scale_down_base = mpp_buffer_get_fd(mbuffer); + vdpu383_setup_down_scale(mframe, reg_ctx->dev, &hw_regs->ctrl_regs, (void*)&hw_regs->h265d_paras); + break; + case MPP_FRAME_THUMBNAIL_NONE: + default: hw_regs->ctrl_regs.reg9.scale_down_en = 0; + break; } } @@ -1426,6 +1494,9 @@ static MPP_RET hal_h265d_vdpu383_control(void *hal, MpiCmd cmd_type, void *param } break; } + case MPP_DEC_GET_THUMBNAIL_FRAME_INFO: { + vdpu383_update_thumbnail_frame_info((MppFrame)param); + } break; case MPP_DEC_SET_OUTPUT_FORMAT: { } break; default: { diff --git a/mpp/hal/rkdec/inc/vdpu383_com.h b/mpp/hal/rkdec/inc/vdpu383_com.h index 4d5c733d..fb56e1e5 100644 --- a/mpp/hal/rkdec/inc/vdpu383_com.h +++ b/mpp/hal/rkdec/inc/vdpu383_com.h @@ -644,6 +644,7 @@ void vdpu383_setup_statistic(Vdpu383CtrlReg *com); void vdpu383_afbc_align_calc(MppBufSlots slots, MppFrame frame, RK_U32 expand); RK_S32 vdpu383_set_rcbinfo(MppDev dev, Vdpu383RcbInfo *rcb_info); void vdpu383_setup_down_scale(MppFrame frame, MppDev dev, Vdpu383CtrlReg *com, void* comParas); +void vdpu383_update_thumbnail_frame_info(MppFrame frame); #ifdef DUMP_VDPU383_DATAS extern RK_U32 dump_cur_frame; diff --git a/mpp/hal/rkdec/vdpu383_com.c b/mpp/hal/rkdec/vdpu383_com.c index 1b22cae8..887900ac 100644 --- a/mpp/hal/rkdec/vdpu383_com.c +++ b/mpp/hal/rkdec/vdpu383_com.c @@ -170,12 +170,38 @@ RK_S32 vdpu383_set_rcbinfo(MppDev dev, Vdpu383RcbInfo *rcb_info) return 0; } +void vdpu383_update_thumbnail_frame_info(MppFrame frame) +{ + RK_U32 down_scale_height = mpp_frame_get_height(frame) >> 1; + RK_U32 down_scale_width = mpp_frame_get_width(frame) >> 1; + RK_U32 down_scale_ver = MPP_ALIGN(down_scale_height, 16); + RK_U32 down_scale_hor = MPP_ALIGN(down_scale_width, 16); + RK_U32 down_scale_buf_size = 0; + + if (!MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(frame))) { + down_scale_hor = mpp_align_128_odd_plus_64(down_scale_hor); + down_scale_ver = mpp_frame_get_ver_stride(frame) >> 1; + } + + down_scale_buf_size = down_scale_hor * down_scale_ver * 3 / 2; + /* + * no matter what format, scale down image will output as 8bit raster format; + */ + mpp_frame_set_fmt(frame, MPP_FMT_YUV420SP); + mpp_frame_set_width(frame, down_scale_width); + mpp_frame_set_height(frame, down_scale_height); + mpp_frame_set_hor_stride(frame, down_scale_hor); + mpp_frame_set_ver_stride(frame, down_scale_ver); + mpp_frame_set_buf_size(frame, down_scale_buf_size); +} + void vdpu383_setup_down_scale(MppFrame frame, MppDev dev, Vdpu383CtrlReg *com, void* comParas) { RK_U32 down_scale_height = mpp_frame_get_height(frame) >> 1; RK_U32 down_scale_width = mpp_frame_get_width(frame) >> 1; RK_U32 down_scale_ver = MPP_ALIGN(down_scale_height, 16); RK_U32 down_scale_hor = MPP_ALIGN(down_scale_width, 16); + Vdpu383RegCommParas* paras = (Vdpu383RegCommParas*)comParas; MppFrameFormat fmt = mpp_frame_get_fmt(frame); MppMeta meta = mpp_frame_get_meta(frame); @@ -184,6 +210,11 @@ void vdpu383_setup_down_scale(MppFrame frame, MppDev dev, Vdpu383CtrlReg *com, v RK_U32 down_scale_y_virstride = down_scale_ver * down_scale_hor; RK_U32 downscale_buf_size; + if (!MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(frame))) { + down_scale_hor = mpp_align_128_odd_plus_64(down_scale_hor); + down_scale_ver = mpp_frame_get_ver_stride(frame) >> 1; + down_scale_y_virstride = down_scale_ver * down_scale_hor; + } /* * no matter what format, scale down image will output as 8bit raster format; * down_scale image buffer size was already added to the buf_size of mpp_frame, @@ -220,9 +251,11 @@ void vdpu383_setup_down_scale(MppFrame frame, MppDev dev, Vdpu383CtrlReg *com, v if ((fmt & MPP_FRAME_FMT_MASK) == MPP_FMT_YUV444SP) paras->reg72_scl_ref_raster_uv_hor_virstride = down_scale_hor >> 3; paras->reg73_scl_ref_virstride = down_scale_y_virstride >> 4; - mpp_dev_set_reg_offset(dev, 133, down_scale_y_offset); - mpp_meta_set_s32(meta, KEY_DEC_TBN_Y_OFFSET, down_scale_y_offset); - mpp_meta_set_s32(meta, KEY_DEC_TBN_UV_OFFSET, down_scale_uv_offset); + if (mpp_frame_get_thumbnail_en(frame) == MPP_FRAME_THUMBNAIL_MIXED) { + mpp_dev_set_reg_offset(dev, 133, down_scale_y_offset); + mpp_meta_set_s32(meta, KEY_DEC_TBN_Y_OFFSET, down_scale_y_offset); + mpp_meta_set_s32(meta, KEY_DEC_TBN_UV_OFFSET, down_scale_uv_offset); + } } #ifdef DUMP_VDPU383_DATAS diff --git a/mpp/hal/rkdec/vp9d/hal_vp9d_vdpu383.c b/mpp/hal/rkdec/vp9d/hal_vp9d_vdpu383.c index be5ffea0..393109ad 100644 --- a/mpp/hal/rkdec/vp9d/hal_vp9d_vdpu383.c +++ b/mpp/hal/rkdec/vp9d/hal_vp9d_vdpu383.c @@ -66,6 +66,7 @@ typedef struct Vdpu383Vp9dCtx_t { HalBufs cmv_bufs; RK_S32 mv_size; RK_S32 mv_count; + HalBufs origin_bufs; RK_U32 prob_ctx_valid[VP9_CONTEXT]; MppBuffer prob_loop_base[VP9_CONTEXT]; /* uncompress header data */ @@ -77,6 +78,30 @@ static RK_U32 cur_last_segid_flag; static MppBuffer cur_last_prob_base; #endif +static MPP_RET vdpu383_setup_scale_origin_bufs(Vdpu383Vp9dCtx *ctx, MppFrame mframe) +{ + /* for 8K FrameBuf scale mode */ + size_t origin_buf_size = 0; + + origin_buf_size = mpp_frame_get_buf_size(mframe); + + if (!origin_buf_size) { + mpp_err_f("origin_bufs get buf size failed\n"); + return MPP_NOK; + } + if (ctx->origin_bufs) { + hal_bufs_deinit(ctx->origin_bufs); + ctx->origin_bufs = NULL; + } + hal_bufs_init(&ctx->origin_bufs); + if (!ctx->origin_bufs) { + mpp_err_f("origin_bufs thumb init fail\n"); + return MPP_ERR_NOMEM; + } + hal_bufs_setup(ctx->origin_bufs, 16, 1, &origin_buf_size); + + return MPP_OK; +} static MPP_RET hal_vp9d_alloc_res(HalVp9dCtx *hal) { HalVp9dCtx *p_hal = (HalVp9dCtx*)hal; @@ -279,6 +304,15 @@ static MPP_RET hal_vp9d_release_res(HalVp9dCtx *hal) return ret; } } + if (hw_ctx->origin_bufs) { + ret = hal_bufs_deinit(hw_ctx->origin_bufs); + if (ret) { + mpp_err("thumb vp9 origin_bufs deinit buffer failed\n"); + return ret; + } + hw_ctx->origin_bufs = NULL; + } + return MPP_OK; } @@ -673,6 +707,7 @@ static MPP_RET hal_vp9d_vdpu383_gen_regs(void *hal, HalTaskInfo *task) MppBuffer framebuf = NULL; HalBuf *mv_buf = NULL; RK_U32 fbc_en = 0; + HalBuf *origin_buf = NULL; HalVp9dCtx *p_hal = (HalVp9dCtx*)hal; Vdpu383Vp9dCtx *hw_ctx = (Vdpu383Vp9dCtx*)p_hal->hw_ctx; @@ -680,6 +715,7 @@ static MPP_RET hal_vp9d_vdpu383_gen_regs(void *hal, HalTaskInfo *task) Vdpu383Vp9dRegSet *vp9_hw_regs = NULL; RK_S32 mv_size = pic_param->width * pic_param->height / 2; RK_U32 frame_ctx_id = pic_param->frame_context_idx; + MppFrame mframe; if (p_hal->fast_mode) { for (i = 0; i < MAX_GEN_REG; i++) { @@ -738,6 +774,12 @@ static MPP_RET hal_vp9d_vdpu383_gen_regs(void *hal, HalTaskInfo *task) hal_bufs_setup(hw_ctx->cmv_bufs, hw_ctx->mv_count, 1, &size); } + mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, SLOT_FRAME_PTR, &mframe); + if (mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY && + hw_ctx->origin_bufs == NULL) { + vdpu383_setup_scale_origin_bufs(hw_ctx, mframe); + } + stream_len = (RK_S32)mpp_packet_get_length(task->dec.input_packet); intraFlag = (!pic_param->frame_type || pic_param->intra_only); @@ -815,8 +857,6 @@ static MPP_RET hal_vp9d_vdpu383_gen_regs(void *hal, HalTaskInfo *task) pic_h[2] = pic_h[1]; { - MppFrame mframe = NULL; - mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, SLOT_FRAME_PTR, &mframe); fbc_en = MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(mframe)); @@ -859,7 +899,12 @@ static MPP_RET hal_vp9d_vdpu383_gen_regs(void *hal, HalTaskInfo *task) hw_ctx->pre_mv_base_addr = hw_ctx->mv_base_addr; } + mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, SLOT_FRAME_PTR, &mframe); mpp_buf_slot_get_prop(p_hal ->slots, task->dec.output, SLOT_BUFFER, &framebuf); + if (mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY) { + origin_buf = hal_bufs_get_buf(hw_ctx->origin_bufs, task->dec.output); + framebuf = origin_buf->buf[0]; + } vp9_hw_regs->vp9d_addrs.reg168_decout_base = mpp_buffer_get_fd(framebuf); vp9_hw_regs->vp9d_addrs.reg169_error_ref_base = mpp_buffer_get_fd(framebuf); vp9_hw_regs->vp9d_addrs.reg192_payload_st_cur_base = mpp_buffer_get_fd(framebuf); @@ -926,6 +971,10 @@ static MPP_RET hal_vp9d_vdpu383_gen_regs(void *hal, HalTaskInfo *task) if (pic_param->ref_frame_map[ref_idx].Index7Bits < 0x7f) { mpp_buf_slot_get_prop(p_hal ->slots, pic_param->ref_frame_map[ref_idx].Index7Bits, SLOT_BUFFER, &framebuf); + if (hw_ctx->origin_bufs && mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY) { + origin_buf = hal_bufs_get_buf(hw_ctx->origin_bufs, pic_param->ref_frame_map[ref_idx].Index7Bits); + framebuf = origin_buf->buf[0]; + } switch (i) { case 0: { @@ -1038,16 +1087,36 @@ static MPP_RET hal_vp9d_vdpu383_gen_regs(void *hal, HalTaskInfo *task) { //scale down config - MppFrame mframe = NULL; + MppBuffer mbuffer = NULL; + RK_S32 fd = -1; + MppFrameThumbnailMode thumbnail_mode; + mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, + SLOT_BUFFER, &mbuffer); mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, SLOT_FRAME_PTR, &mframe); - if (mpp_frame_get_thumbnail_en(mframe)) { - vp9_hw_regs->common_addr.reg133_scale_down_base = vp9_hw_regs->vp9d_addrs.reg168_decout_base; + thumbnail_mode = mpp_frame_get_thumbnail_en(mframe); + switch (thumbnail_mode) { + case MPP_FRAME_THUMBNAIL_ONLY: + vp9_hw_regs->common_addr.reg133_scale_down_base = mpp_buffer_get_fd(mbuffer); + origin_buf = hal_bufs_get_buf(hw_ctx->origin_bufs, task->dec.output); + fd = mpp_buffer_get_fd(origin_buf->buf[0]); + vp9_hw_regs->vp9d_addrs.reg168_decout_base = fd; + vp9_hw_regs->vp9d_addrs.reg169_error_ref_base = fd; + vp9_hw_regs->vp9d_addrs.reg192_payload_st_cur_base = fd; + vp9_hw_regs->vp9d_addrs.reg194_payload_st_error_ref_base = fd; vdpu383_setup_down_scale(mframe, p_hal->dev, &vp9_hw_regs->ctrl_regs, (void *)&vp9_hw_regs->vp9d_paras); - } else { + break; + case MPP_FRAME_THUMBNAIL_MIXED: + vp9_hw_regs->common_addr.reg133_scale_down_base = mpp_buffer_get_fd(mbuffer); + vdpu383_setup_down_scale(mframe, p_hal->dev, &vp9_hw_regs->ctrl_regs, + (void *)&vp9_hw_regs->vp9d_paras); + break; + case MPP_FRAME_THUMBNAIL_NONE: + default: vp9_hw_regs->ctrl_regs.reg9.scale_down_en = 0; + break; } } @@ -1264,6 +1333,9 @@ static MPP_RET hal_vp9d_vdpu383_control(void *hal, MpiCmd cmd_type, void *param) mpp_slots_set_prop(p_hal->slots, SLOTS_HOR_ALIGN, mpp_align_128_odd_plus_64); } } break; + case MPP_DEC_GET_THUMBNAIL_FRAME_INFO: { + vdpu383_update_thumbnail_frame_info((MppFrame)param); + } break; default : { } break; } diff --git a/mpp/hal/vpu/av1d/hal_av1d_vdpu383.c b/mpp/hal/vpu/av1d/hal_av1d_vdpu383.c index 9f34463b..e4631d81 100644 --- a/mpp/hal/vpu/av1d/hal_av1d_vdpu383.c +++ b/mpp/hal/vpu/av1d/hal_av1d_vdpu383.c @@ -206,6 +206,7 @@ typedef struct VdpuAv1dRegCtx_t { RK_U32 num_tile_cols; /* uncompress header data */ RK_U8 header_data[VDPU383_UNCMPS_HEADER_SIZE]; + HalBufs origin_bufs; } Vdpu383Av1dRegCtx; // #define DUMP_AV1D_VDPU383_DATAS @@ -1262,6 +1263,32 @@ static RK_U32 rkv_len_align_422(RK_U32 val) return ((5 * MPP_ALIGN(val, 64)) / 2); } +static MPP_RET vdpu383_setup_scale_origin_bufs(Av1dHalCtx *p_hal, MppFrame mframe) +{ + Vdpu383Av1dRegCtx *ctx = (Vdpu383Av1dRegCtx *)p_hal->reg_ctx; + /* for 8K FrameBuf scale mode */ + size_t origin_buf_size = 0; + + origin_buf_size = mpp_frame_get_buf_size(mframe); + + if (!origin_buf_size) { + mpp_err_f("origin_bufs get buf size failed\n"); + return MPP_NOK; + } + if (ctx->origin_bufs) { + hal_bufs_deinit(ctx->origin_bufs); + ctx->origin_bufs = NULL; + } + hal_bufs_init(&ctx->origin_bufs); + if (!ctx->origin_bufs) { + mpp_err_f("origin_bufs init fail\n"); + return MPP_ERR_NOMEM; + } + hal_bufs_setup(ctx->origin_bufs, 16, 1, &origin_buf_size); + + return MPP_OK; +} + static MPP_RET hal_av1d_alloc_res(void *hal) { @@ -1334,6 +1361,10 @@ static void hal_av1d_release_res(void *hal) hal_bufs_deinit(reg_ctx->colmv_bufs); reg_ctx->colmv_bufs = NULL; } + if (reg_ctx->origin_bufs) { + hal_bufs_deinit(reg_ctx->origin_bufs); + reg_ctx->origin_bufs = NULL; + } MPP_FREE(p_hal->reg_ctx); } @@ -2068,6 +2099,8 @@ MPP_RET vdpu383_av1d_gen_regs(void *hal, HalTaskInfo *task) Vdpu383Av1dRegSet *regs; DXVA_PicParams_AV1 *dxva = (DXVA_PicParams_AV1*)task->dec.syntax.data; RK_U32 i = 0; + HalBuf *origin_buf = NULL; + MppFrame mframe; INP_CHECK(ret, NULL == p_hal); @@ -2080,6 +2113,12 @@ MPP_RET vdpu383_av1d_gen_regs(void *hal, HalTaskInfo *task) goto __RETURN; } + mpp_buf_slot_get_prop(p_hal->slots, dxva->CurrPic.Index7Bits, SLOT_FRAME_PTR, &mframe); + if (mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY && + MPP_MAX(dxva->width, dxva->height) > 4096 && ctx->origin_bufs == NULL) { + vdpu383_setup_scale_origin_bufs(p_hal, mframe); + } + if (p_hal->fast_mode) { for (i = 0; i < MPP_ARRAY_ELEMS(ctx->reg_buf); i++) { if (!ctx->reg_buf[i].valid) { @@ -2203,7 +2242,6 @@ MPP_RET vdpu383_av1d_gen_regs(void *hal, HalTaskInfo *task) /* set reg -> para (stride, len) */ { - MppFrame mframe; RK_U32 hor_virstride = 0; RK_U32 ver_virstride = 0; RK_U32 y_virstride = 0; @@ -2268,6 +2306,7 @@ MPP_RET vdpu383_av1d_gen_regs(void *hal, HalTaskInfo *task) { MppBuffer mbuffer = NULL; RK_U32 mapped_idx; + mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, SLOT_FRAME_PTR, &mframe); mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, SLOT_BUFFER, &mbuffer); regs->av1d_addrs.reg168_decout_base = mpp_buffer_get_fd(mbuffer); regs->av1d_addrs.reg192_payload_st_cur_base = mpp_buffer_get_fd(mbuffer); @@ -2277,6 +2316,10 @@ MPP_RET vdpu383_av1d_gen_regs(void *hal, HalTaskInfo *task) mapped_idx = dxva->ref_frame_idx[i]; if (dxva->frame_refs[mapped_idx].Index != (CHAR)0xff && dxva->frame_refs[mapped_idx].Index != 0x7f) { mpp_buf_slot_get_prop(p_hal->slots, dxva->frame_refs[mapped_idx].Index, SLOT_BUFFER, &mbuffer); + if (ctx->origin_bufs && mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_ONLY) { + origin_buf = hal_bufs_get_buf(ctx->origin_bufs, dxva->frame_refs[mapped_idx].Index); + mbuffer = origin_buf->buf[0]; + } if (mbuffer) { SET_REF_BASE(regs->av1d_addrs, mapped_idx, mpp_buffer_get_fd(mbuffer)); SET_FBC_PAYLOAD_REF_BASE(regs->av1d_addrs, mapped_idx, mpp_buffer_get_fd(mbuffer)); @@ -2336,16 +2379,36 @@ MPP_RET vdpu383_av1d_gen_regs(void *hal, HalTaskInfo *task) { //scale down config - MppFrame mframe = NULL; + MppBuffer mbuffer = NULL; + RK_S32 fd = -1; + MppFrameThumbnailMode thumbnail_mode; + mpp_buf_slot_get_prop(p_hal->slots, dxva->CurrPic.Index7Bits, SLOT_BUFFER, &mbuffer); mpp_buf_slot_get_prop(p_hal->slots, dxva->CurrPic.Index7Bits, SLOT_FRAME_PTR, &mframe); - if (mpp_frame_get_thumbnail_en(mframe)) { - regs->com_pkt_addr.reg133_scale_down_tile_base = regs->av1d_addrs.reg168_decout_base; + thumbnail_mode = mpp_frame_get_thumbnail_en(mframe); + fd = mpp_buffer_get_fd(mbuffer); + + switch (thumbnail_mode) { + case MPP_FRAME_THUMBNAIL_ONLY: + regs->com_pkt_addr.reg133_scale_down_tile_base = fd; + origin_buf = hal_bufs_get_buf(ctx->origin_bufs, dxva->CurrPic.Index7Bits); + fd = mpp_buffer_get_fd(origin_buf->buf[0]); + regs->av1d_addrs.reg168_decout_base = fd; + regs->av1d_addrs.reg192_payload_st_cur_base = fd; + regs->av1d_addrs.reg169_error_ref_base = fd; vdpu383_setup_down_scale(mframe, p_hal->dev, ®s->ctrl_regs, (void *)®s->av1d_paras); - } else { + break; + case MPP_FRAME_THUMBNAIL_MIXED: + regs->com_pkt_addr.reg133_scale_down_tile_base = fd; + vdpu383_setup_down_scale(mframe, p_hal->dev, ®s->ctrl_regs, + (void *)®s->av1d_paras); + break; + case MPP_FRAME_THUMBNAIL_NONE: + default: regs->ctrl_regs.reg9.scale_down_en = 0; + break; } } @@ -2555,6 +2618,9 @@ MPP_RET vdpu383_av1d_control(void *hal, MpiCmd cmd_type, void *param) } break; } + case MPP_DEC_GET_THUMBNAIL_FRAME_INFO: { + vdpu383_update_thumbnail_frame_info((MppFrame)param); + } break; case MPP_DEC_SET_OUTPUT_FORMAT : { } break; default : { diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index 12537c06..554e48b7 100644 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -629,7 +629,7 @@ static void setup_VPU_FRAME_from_mpp_frame(VpuCodecContext *ctx, VPU_FRAME *vfra static void setup_video_frame_meta(VideoFrame_t *videoFrame, MppFrame mframe) { - if (mpp_frame_get_thumbnail_en(mframe)) { + if (mpp_frame_get_thumbnail_en(mframe) == MPP_FRAME_THUMBNAIL_MIXED) { MppMeta meta = NULL; RK_S32 yOffset = 0; RK_S32 uvOffset = 0; diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index d7b8d016..2cb96d88 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -1184,6 +1184,7 @@ MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param) MPP_RET ret = MPP_NOK; switch (cmd) { + case MPP_DEC_GET_THUMBNAIL_FRAME_INFO: case MPP_DEC_SET_FRAME_INFO: { ret = mpp_dec_control(mDec, cmd, param); } break;