[vdpu34x]: Support fbc fmt set for dec_out

1.hevc all resolution support fbc out
2.h264 only support frame mb only for fbc out
3.vp9 all resolution support fbc out

Change-Id: I1d68b75aebea30560a1c6c25bd552121f86097f0
Signed-off-by: sayon.chen <sayon.chen@rock-chips.com>
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2020-12-02 18:20:37 +08:00
parent 40261ab528
commit fdb769274c
14 changed files with 192 additions and 40 deletions

View File

@@ -242,8 +242,8 @@ static void generate_info_set(MppBufSlotsImpl *impl, MppFrame frame, RK_U32 forc
RK_U32 width = mpp_frame_get_width(frame);
RK_U32 height = mpp_frame_get_height(frame);
MppFrameFormat fmt = mpp_frame_get_fmt(frame);
RK_U32 depth = (fmt == MPP_FMT_YUV420SP_10BIT
|| fmt == MPP_FMT_YUV422SP_10BIT) ? 10 : 8;
RK_U32 depth = ((fmt & MPP_FRAME_FMT_MASK) == MPP_FMT_YUV420SP_10BIT ||
(fmt & MPP_FRAME_FMT_MASK) == MPP_FMT_YUV422SP_10BIT) ? 10 : 8;
RK_U32 codec_hor_stride = mpp_frame_get_hor_stride(frame);
RK_U32 codec_ver_stride = mpp_frame_get_ver_stride(frame);
RK_U32 hal_hor_stride = (codec_hor_stride) ?

View File

@@ -1007,6 +1007,7 @@ typedef struct h264d_video_ctx_t {
RK_S32 active_sps_id[MAX_NUM_DPB_LAYERS];
RK_U32 PicWidthInMbs;
RK_U32 FrameHeightInMbs;
RK_S32 frame_mbs_only_flag;
RK_S32 yuv_format;
RK_U32 bit_depth_chroma;
RK_U32 bit_depth_luma;

View File

@@ -381,6 +381,11 @@ static inline RK_U32 rkv_len_align_422(RK_U32 val)
return ((5 * MPP_ALIGN(val, 16)) / 2);
}
static RK_U32 hor_align_64(RK_U32 val)
{
return MPP_ALIGN(val, 64);
}
static MPP_RET dpb_mark_malloc(H264dVideoCtx_t *p_Vid, H264_StorePic_t *dec_pic)
{
MPP_RET ret = MPP_ERR_UNKNOW;
@@ -410,19 +415,34 @@ static MPP_RET dpb_mark_malloc(H264dVideoCtx_t *p_Vid, H264_StorePic_t *dec_pic)
{
MppFrame mframe = NULL;
RK_U32 hor_stride, ver_stride;
MppFrameFormat fmt = MPP_FMT_YUV_BUTT;
MppFrameFormat out_fmt = p_Dec->cfg->base.out_fmt;
mpp_frame_init(&mframe);
if ((H264_CHROMA_420 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) {
mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP);
fmt = MPP_FMT_YUV420SP;
} else if ((H264_CHROMA_420 == p_Vid->yuv_format) && (10 == p_Vid->bit_depth_luma)) {
mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP_10BIT);
fmt = MPP_FMT_YUV420SP_10BIT;
} else if ((H264_CHROMA_422 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) {
mpp_frame_set_fmt(mframe, MPP_FMT_YUV422SP);
fmt = MPP_FMT_YUV422SP;
mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422);
} else if ((H264_CHROMA_422 == p_Vid->yuv_format) && (10 == p_Vid->bit_depth_luma)) {
mpp_frame_set_fmt(mframe, MPP_FMT_YUV422SP_10BIT);
fmt = MPP_FMT_YUV422SP_10BIT;
mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422);
}
if (MPP_FRAME_FMT_IS_FBC(out_fmt)) {
/* field mode can not use FBC */
if (p_Vid->frame_mbs_only_flag) {
mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_HOR_ALIGN, hor_align_64);
mpp_frame_set_offset_x(mframe, 0);
mpp_frame_set_offset_y(mframe, 4);
fmt |= (out_fmt & MPP_FRAME_FBC_MASK);
}
p_Dec->cfg->base.out_fmt = fmt;
}
mpp_frame_set_fmt(mframe, fmt);
hor_stride = MPP_ALIGN(p_Vid->width * p_Vid->bit_depth_luma, 8) / 8;
ver_stride = p_Vid->height;
/* Before cropping */

View File

@@ -384,6 +384,7 @@ static void update_video_pars(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps)
p_Vid->PicWidthInMbs = (sps->pic_width_in_mbs_minus1 + 1);
p_Vid->FrameHeightInMbs = (2 - sps->frame_mbs_only_flag) * (sps->pic_height_in_map_units_minus1 + 1);
p_Vid->yuv_format = sps->chroma_format_idc;
p_Vid->frame_mbs_only_flag = sps->frame_mbs_only_flag;
p_Vid->width = p_Vid->PicWidthInMbs * 16;
p_Vid->height = p_Vid->FrameHeightInMbs * 16;

View File

@@ -480,12 +480,13 @@ __BITREAD_ERR:
static RK_S32 set_sps(HEVCContext *s, const HEVCSPS *sps)
{
RK_U32 num = 0, den = 0;
MppFrameFormat fmt = s->h265dctx->cfg->base.out_fmt & (~MPP_FRAME_FMT_MASK);
s->h265dctx->coded_width = sps->width;
s->h265dctx->coded_height = sps->height;
s->h265dctx->width = sps->output_width;
s->h265dctx->height = sps->output_height;
s->h265dctx->pix_fmt = sps->pix_fmt;
s->h265dctx->pix_fmt = fmt | sps->pix_fmt;
s->h265dctx->nBitDepth = sps->bit_depth;
s->h265dctx->sample_aspect_ratio = sps->vui.sar;

View File

@@ -71,9 +71,13 @@ void mpp_hevc_flush_dpb(HEVCContext *s)
}
}
static RK_U32 hor_align_64(RK_U32 val)
{
return MPP_ALIGN(val, 64);
}
static HEVCFrame *alloc_frame(HEVCContext *s)
{
RK_U32 i;
MPP_RET ret = MPP_OK;
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
@@ -89,6 +93,13 @@ static HEVCFrame *alloc_frame(HEVCContext *s)
(MPP_ALIGN(s->h265dctx->coded_width, 64) * s->h265dctx->nBitDepth) >> 3);
mpp_frame_set_ver_stride(frame->frame, s->h265dctx->coded_height);
mpp_frame_set_fmt(frame->frame, s->h265dctx->pix_fmt);
if (MPP_FRAME_FMT_IS_FBC(s->h265dctx->pix_fmt)) {
mpp_slots_set_prop(s->slots, SLOTS_HOR_ALIGN, hor_align_64);
mpp_frame_set_offset_x(frame->frame, 0);
mpp_frame_set_offset_y(frame->frame, 4);
}
mpp_frame_set_errinfo(frame->frame, 0);
mpp_frame_set_pts(frame->frame, s->pts);
mpp_frame_set_poc(frame->frame, s->poc);

View File

@@ -359,6 +359,7 @@ MPP_RET vp9d_parser_init(Vp9CodecContext *vp9_ctx, ParserCfg *init)
s->packet_slots = init->packet_slots;
s->slots = init->frame_slots;
s->cfg = init->cfg;
mpp_buf_slot_setup(s->slots, 25);
mpp_env_get_u32("vp9d_debug", &vp9d_debug, 0);
@@ -389,11 +390,11 @@ 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);
#if 0
mpp_frame_set_fmt(frame->frame, s->h265dctx->pix_fmt);
mpp_frame_set_errinfo(frame->f, 0);
#endif
if (MPP_FRAME_FMT_IS_FBC(s->cfg->base.out_fmt))
ctx->pix_fmt |= (s->cfg->base.out_fmt & (~MPP_FRAME_FBC_MASK));
mpp_frame_set_fmt(frame->f, ctx->pix_fmt);
mpp_buf_slot_get_unused(s->slots, &frame->slot_index);
mpp_buf_slot_set_prop(s->slots, frame->slot_index, SLOT_FRAME, frame->f);
mpp_buf_slot_set_flag(s->slots, frame->slot_index, SLOT_CODEC_USE);
@@ -788,7 +789,7 @@ static RK_S32 decode_parser_header(Vp9CodecContext *ctx,
for (i = 0; i < 3; i++) {
RK_U32 refw = mpp_frame_get_width(s->refs[s->refidx[i]].f);
RK_U32 refh = mpp_frame_get_height(s->refs[s->refidx[i]].f);
RK_S32 reffmt = mpp_frame_get_fmt(s->refs[s->refidx[i]].f);
RK_S32 reffmt = mpp_frame_get_fmt(s->refs[s->refidx[i]].f) & MPP_FRAME_FMT_MASK;
vp9d_dbg(VP9D_DBG_REF, "ref get width frame slot %p", s->refs[s->refidx[i]].f);
if (reffmt != fmt) {

View File

@@ -246,6 +246,7 @@ typedef struct VP9Context {
RK_S32 first_partition_size;
MppBufSlots slots;
MppBufSlots packet_slots;
MppDecCfgSet *cfg;
HalDecTask *task;
RK_S32 eos; ///< current packet contains an EOS/EOB NAL
RK_S64 pts;

View File

@@ -57,6 +57,7 @@ typedef struct MppDecImpl_t {
MppBufSlots frame_slots;
MppBufSlots packet_slots;
MppCbCtx dec_cb;
const MppDecHwCap *hw_info;
HalTaskGroup tasks;
HalTaskGroup vproc_tasks;

View File

@@ -275,6 +275,23 @@ MPP_RET mpp_dec_update_cfg(MppDecImpl *p)
return MPP_OK;
}
MPP_RET mpp_dec_check_fbc_cap(MppDecImpl *p)
{
MppDecBaseCfg *base = &p->cfg.base;
if (MPP_FRAME_FMT_IS_FBC(base->out_fmt)) {
RK_U32 fbc = (RK_U32)base->out_fmt & MPP_FRAME_FBC_MASK;
RK_U32 fmt = base->out_fmt - fbc;
if (p->hw_info && p->hw_info->cap_fbc)
fmt |= fbc;
base->out_fmt = (MppFrameFormat)fmt;
}
return MPP_OK;
}
MPP_RET mpp_dec_proc_cfg(MppDecImpl *dec, MpiCmd cmd, void *param)
{
MPP_RET ret = MPP_OK;
@@ -307,6 +324,7 @@ MPP_RET mpp_dec_proc_cfg(MppDecImpl *dec, MpiCmd cmd, void *param)
case MPP_DEC_SET_PARSER_SPLIT_MODE :
case MPP_DEC_SET_PARSER_FAST_MODE :
case MPP_DEC_SET_IMMEDIATE_OUT :
case MPP_DEC_SET_OUTPUT_FORMAT :
case MPP_DEC_SET_DISABLE_ERROR :
case MPP_DEC_SET_ENABLE_DEINTERLACE : {
ret = mpp_dec_set_cfg_by_cmd(&dec->cfg, cmd, param);
@@ -345,6 +363,7 @@ MPP_RET mpp_dec_proc_cfg(MppDecImpl *dec, MpiCmd cmd, void *param)
if (dec_cfg) {
mpp_dec_set_cfg(&dec->cfg, &dec_cfg->cfg);
mpp_dec_update_cfg(dec);
mpp_dec_check_fbc_cap(dec);
}
dec_dbg_func("set dec cfg\n");
@@ -1509,6 +1528,10 @@ MPP_RET mpp_dec_init(MppDec *dec, MppDecInitCfg *cfg)
break;
}
p->hw_info = hal_cfg.hw_info;
/* check fbc cap after hardware info is valid */
mpp_dec_check_fbc_cap(p);
ParserCfg parser_cfg = {
coding,
frame_slots,
@@ -1797,6 +1820,10 @@ MPP_RET mpp_dec_set_cfg_by_cmd(MppDecCfgSet *set, MpiCmd cmd, void *param)
cfg->change |= MPP_DEC_CFG_CHANGE_FAST_PARSE;
dec_dbg_func("fast parse mode %d\n", cfg->fast_parse);
} break;
case MPP_DEC_SET_OUTPUT_FORMAT : {
cfg->out_fmt = (param) ? (*((MppFrameFormat *)param)) : (MPP_FMT_YUV420SP);
cfg->change |= MPP_DEC_CFG_CHANGE_OUTPUT_FORMAT;
} break;
case MPP_DEC_SET_DISABLE_ERROR: {
cfg->disable_error = (param) ? (*((RK_U32 *)param)) : (1);
cfg->change |= MPP_DEC_CFG_CHANGE_DISABLE_ERROR;

View File

@@ -37,17 +37,17 @@ typedef enum VpuHwMode_e {
typedef struct MppHalCfg_t {
// input
MppCtxType type;
MppCodingType coding;
MppBufSlots frame_slots;
MppBufSlots packet_slots;
MppDecCfgSet *cfg;
MppCbCtx *dec_cb;
MppCtxType type;
MppCodingType coding;
MppBufSlots frame_slots;
MppBufSlots packet_slots;
MppDecCfgSet *cfg;
MppCbCtx *dec_cb;
// output from mpp_hal
HalTaskGroup tasks;
HalTaskGroup tasks;
// output from hardware module
const void *hw_info;
const MppDecHwCap *hw_info;
} MppHalCfg;
typedef struct MppHalApi_t {

View File

@@ -495,9 +495,21 @@ static MPP_RET set_registers(H264dHalCtx_t *p_hal, Vdpu34xH264dRegSet *regs, Hal
ver_virstride = mpp_frame_get_ver_stride(mframe);
y_virstride = hor_virstride * ver_virstride;
common->reg018.y_hor_virstride = hor_virstride / 16;
common->reg019.uv_hor_virstride = hor_virstride / 16;
common->reg020_y_virstride.y_virstride = y_virstride / 16;
if (MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(mframe))) {
RK_U32 fbd_offset = MPP_ALIGN(hor_virstride * (ver_virstride + 16) / 16, SZ_4K);
if (pp->bit_depth_luma_minus8 > 0) {
RK_U32 pixel_width = MPP_ALIGN(mpp_frame_get_width(mframe), 64);
common->reg018.y_hor_virstride = pixel_width / 16;
common->reg019.uv_hor_virstride = pixel_width / 16;
}
common->reg012.fbc_e = 1;
common->reg012.colmv_compress_en = 1;
common->reg020_fbc_payload_off.payload_st_offset = fbd_offset >> 4;
} else {
common->reg018.y_hor_virstride = hor_virstride / 16;
common->reg019.uv_hor_virstride = hor_virstride / 16;
common->reg020_y_virstride.y_virstride = y_virstride / 16;
}
}
//!< set current
{
@@ -630,7 +642,22 @@ MPP_RET vdpu34x_h264d_init(void *hal, MppHalCfg *cfg)
mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, rkv_ver_align);
mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align);
(void)cfg;
{
// report hw_info to parser
const MppSocInfo *info = mpp_get_soc_info();
const void *hw_info = NULL;
for (i = 0; i < MPP_ARRAY_ELEMS(info->dec_caps); i++) {
if (info->dec_caps[i] && info->dec_caps[i]->type == VPU_CLIENT_RKVDEC) {
hw_info = info->dec_caps[i];
break;
}
}
mpp_assert(hw_info);
cfg->hw_info = hw_info;
}
__RETURN:
return MPP_OK;
__FAILED:

View File

@@ -232,6 +232,23 @@ static MPP_RET hal_h265d_vdpu34x_init(void *hal, MppHalCfg *cfg)
return ret;
}
{
// report hw_info to parser
const MppSocInfo *info = mpp_get_soc_info();
const void *hw_info = NULL;
RK_U32 i;
for (i = 0; i < MPP_ARRAY_ELEMS(info->dec_caps); i++) {
if (info->dec_caps[i] && info->dec_caps[i]->type == VPU_CLIENT_RKVDEC) {
hw_info = info->dec_caps[i];
break;
}
}
mpp_assert(hw_info);
cfg->hw_info = hw_info;
}
#ifdef dump
fp = fopen("/data/hal.bin", "wb");
#endif
@@ -820,23 +837,39 @@ static MPP_RET hal_h265d_vdpu34x_gen_regs(void *hal, HalTaskInfo *syn)
hal_bufs_setup(reg_cxt->cmv_bufs, reg_cxt->mv_count, 1, &size);
}
stride_y = ((MPP_ALIGN(width, 64)
* (dxva_cxt->pp.bit_depth_luma_minus8 + 8)) >> 3);
stride_uv = ((MPP_ALIGN(width, 64)
* (dxva_cxt->pp.bit_depth_chroma_minus8 + 8)) >> 3);
{
MppFrame mframe = NULL;
RK_U32 ver_virstride;
stride_y = hevc_hor_align(stride_y);
stride_uv = hevc_hor_align(stride_uv);
virstrid_y = hevc_ver_align(height) * stride_y;
mpp_buf_slot_get_prop(reg_cxt->slots, dxva_cxt->pp.CurrPic.Index7Bits,
SLOT_FRAME_PTR, &mframe);
stride_y = mpp_frame_get_hor_stride(mframe);
ver_virstride = mpp_frame_get_ver_stride(mframe);
stride_uv = stride_y;
virstrid_y = ver_virstride * stride_y;
hw_regs->common.reg017.slice_num = dxva_cxt->slice_count;
hw_regs->common.reg018.y_hor_virstride = stride_y >> 4;
hw_regs->common.reg019.uv_hor_virstride = stride_uv >> 4;
hw_regs->common.reg020_y_virstride.y_virstride = virstrid_y >> 4;
hw_regs->h265d_param.reg64.h26x_rps_mode = 0;
hw_regs->h265d_param.reg64.h26x_frame_orslice = 0;
hw_regs->h265d_param.reg64.h26x_stream_mode = 0;
hw_regs->common.reg017.slice_num = dxva_cxt->slice_count;
hw_regs->common.reg018.y_hor_virstride = stride_y >> 4;
hw_regs->common.reg019.uv_hor_virstride = stride_uv >> 4;
hw_regs->common.reg020_y_virstride.y_virstride = virstrid_y >> 4;
hw_regs->h265d_param.reg64.h26x_rps_mode = 0;
hw_regs->h265d_param.reg64.h26x_frame_orslice = 0;
hw_regs->h265d_param.reg64.h26x_stream_mode = 0;
if (MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(mframe))) {
RK_U32 fbd_offset = MPP_ALIGN(stride_y * (MPP_ALIGN(ver_virstride, 64) + 16) / 16,
SZ_4K);
if (dxva_cxt->pp.bit_depth_luma_minus8) {
RK_U32 pixel_width = MPP_ALIGN(mpp_frame_get_width(mframe), 64);
hw_regs->common.reg018.y_hor_virstride = pixel_width >> 4;
hw_regs->common.reg019.uv_hor_virstride = pixel_width >> 4;
}
hw_regs->common.reg012.fbc_e = 1;
hw_regs->common.reg012.colmv_compress_en = 1;
hw_regs->common.reg020_fbc_payload_off.payload_st_offset = fbd_offset >> 4;
}
}
mpp_buf_slot_get_prop(reg_cxt->slots, dxva_cxt->pp.CurrPic.Index7Bits,
SLOT_BUFFER, &framebuf);
hw_regs->common_addr.reg130_decout_base = mpp_buffer_get_fd(framebuf); //just index need map

View File

@@ -245,7 +245,22 @@ static MPP_RET hal_vp9d_vdpu34x_init(void *hal, MppHalCfg *cfg)
}
hw_ctx->last_segid_flag = 1;
(void) cfg;
{
// report hw_info to parser
const MppSocInfo *info = mpp_get_soc_info();
const void *hw_info = NULL;
RK_U32 i;
for (i = 0; i < MPP_ARRAY_ELEMS(info->dec_caps); i++) {
if (info->dec_caps[i] && info->dec_caps[i]->type == VPU_CLIENT_RKVDEC) {
hw_info = info->dec_caps[i];
break;
}
}
mpp_assert(hw_info);
cfg->hw_info = hw_info;
}
return ret = MPP_OK;
__FAILED:
@@ -362,6 +377,19 @@ static MPP_RET hal_vp9d_vdpu34x_gen_regs(void *hal, HalTaskInfo *task)
vp9_hw_regs->common.reg019.uv_hor_virstride = sw_uv_hor_virstride;
vp9_hw_regs->common.reg020_y_virstride.y_virstride = sw_y_virstride;
{
MppFrame mframe = NULL;
mpp_buf_slot_get_prop(p_hal->slots, task->dec.output, SLOT_FRAME_PTR, &mframe);
if (MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(mframe))) {
RK_U32 h = mpp_frame_get_ver_stride(mframe);
RK_U32 w = mpp_frame_get_hor_stride(mframe);
RK_U32 fbd_offset = MPP_ALIGN(w * (h + 16) / 16, SZ_4K);
vp9_hw_regs->common.reg012.fbc_e = 1;
vp9_hw_regs->common.reg012.colmv_compress_en = 1;
vp9_hw_regs->common.reg020_fbc_payload_off.payload_st_offset = fbd_offset >> 4;
}
}
if (!pic_param->intra_only && pic_param->frame_type &&
!pic_param->error_resilient_mode && hw_ctx->ls_info.last_show_frame) {
hw_ctx->pre_mv_base_addr = hw_ctx->mv_base_addr;