[mpp_enc]: Add new roi buffer config mode

The roi structure on vepu580 is too complex.

So we provide provide a buffer tunnel for externl user to config encoder
hardware directly.

External user should generate roi data structure according to datasheet.
Then config the base_addr, qp_addr, amv_addr, pmv_addr by metadata.

Change-Id: Iae50bf3ca36c1ff789140055d4d36a79afeb2e58
Signed-off-by: sayon.chen <sayon.chen@rock-chips.com>
This commit is contained in:
sayon.chen
2021-11-09 17:08:52 +08:00
committed by Herman Chen
parent cde64171f7
commit 1fb20bb450
5 changed files with 83 additions and 164 deletions

View File

@@ -82,6 +82,17 @@ typedef enum MppMetaKey_e {
KEY_OSD_DATA2 = FOURCC_META('o', 's', 'd', '2'), KEY_OSD_DATA2 = FOURCC_META('o', 's', 'd', '2'),
KEY_USER_DATA = FOURCC_META('u', 's', 'r', 'd'), KEY_USER_DATA = FOURCC_META('u', 's', 'r', 'd'),
KEY_USER_DATAS = FOURCC_META('u', 'r', 'd', 's'), KEY_USER_DATAS = FOURCC_META('u', 'r', 'd', 's'),
/*
* For vepu580 roi buffer config mode
* The encoder roi structure is so complex that we should provide a buffer
* tunnel for externl user to config encoder hardware by direct sending
* roi data buffer.
* This way can reduce the config parsing and roi buffer data generating
* overhead in mpp.
*/
KEY_ROI_DATA2 = FOURCC_META('r', 'o', 'i', '2'),
/* /*
* qpmap for rv1109/1126 encoder qpmap config * qpmap for rv1109/1126 encoder qpmap config
* Input data is a MppBuffer which contains an array of 16bit Vepu541RoiCfg. * Input data is a MppBuffer which contains an array of 16bit Vepu541RoiCfg.

View File

@@ -1108,6 +1108,19 @@ typedef struct MppEncROICfg_t {
MppEncROIRegion *regions; /**< ROI parameters */ MppEncROIRegion *regions; /**< ROI parameters */
} MppEncROICfg; } MppEncROICfg;
typedef struct MppEncROICfg2_t {
MppBuffer base_cfg_buf;
MppBuffer qp_cfg_buf;
MppBuffer amv_cfg_buf;
MppBuffer mv_cfg_buf;
RK_U32 roi_qp_en : 1;
RK_U32 roi_amv_en : 1;
RK_U32 roi_mv_en : 1;
RK_U32 reserve_bits : 29;
RK_U32 reserve[3];
} MppEncROICfg2;
/* /*
* Mpp OSD parameter * Mpp OSD parameter
* *

View File

@@ -53,6 +53,7 @@ static MppMetaDef meta_defs[] = {
{ KEY_ENC_AVERAGE_QP, TYPE_S32, }, { KEY_ENC_AVERAGE_QP, TYPE_S32, },
{ KEY_ROI_DATA, TYPE_PTR, }, { KEY_ROI_DATA, TYPE_PTR, },
{ KEY_ROI_DATA2, TYPE_PTR, },
{ KEY_OSD_DATA, TYPE_PTR, }, { KEY_OSD_DATA, TYPE_PTR, },
{ KEY_OSD_DATA2, TYPE_PTR, }, { KEY_OSD_DATA2, TYPE_PTR, },
{ KEY_USER_DATA, TYPE_PTR, }, { KEY_USER_DATA, TYPE_PTR, },

View File

@@ -69,10 +69,7 @@ typedef struct HalH264eVepu580Ctx_t {
EncRcTaskInfo hal_rc_cfg; EncRcTaskInfo hal_rc_cfg;
/* roi */ /* roi */
MppEncROICfg *roi_data; void *roi_data;
MppBufferGroup roi_grp;
MppBuffer roi_buf;
RK_S32 roi_buf_size;
/* osd */ /* osd */
Vepu541OsdCfg osd_cfg; Vepu541OsdCfg osd_cfg;
@@ -129,16 +126,6 @@ static MPP_RET hal_h264e_vepu580_deinit(void *hal)
p->dev = NULL; p->dev = NULL;
} }
if (p->roi_buf) {
mpp_buffer_put(p->roi_buf);
p->roi_buf = NULL;
}
if (p->roi_grp) {
mpp_buffer_group_put(p->roi_grp);
p->roi_grp = NULL;
}
if (p->ext_line_buf) { if (p->ext_line_buf) {
mpp_buffer_put(p->ext_line_buf); mpp_buffer_put(p->ext_line_buf);
p->ext_line_buf = NULL; p->ext_line_buf = NULL;
@@ -371,7 +358,7 @@ static MPP_RET hal_h264e_vepu580_get_task(void *hal, HalEncTask *task)
if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) { if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
MppMeta meta = mpp_frame_get_meta(task->frame); MppMeta meta = mpp_frame_get_meta(task->frame);
mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void **)&ctx->roi_data); mpp_meta_get_ptr(meta, KEY_ROI_DATA2, (void **)&ctx->roi_data);
mpp_meta_get_ptr(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data); mpp_meta_get_ptr(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data);
mpp_meta_get_ptr(meta, KEY_OSD_DATA2, (void **)&ctx->osd_cfg.osd_data2); mpp_meta_get_ptr(meta, KEY_OSD_DATA2, (void **)&ctx->osd_cfg.osd_data2);
} }
@@ -1034,46 +1021,30 @@ static void setup_vepu580_io_buf(HalVepu580RegSet *regs, MppDev dev,
static void setup_vepu580_roi(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx) static void setup_vepu580_roi(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
{ {
MppEncROICfg *roi = ctx->roi_data;
RK_U32 w = ctx->sps->pic_width_in_mbs * 16;
RK_U32 h = ctx->sps->pic_height_in_mbs * 16;
hal_h264e_dbg_func("enter\n"); hal_h264e_dbg_func("enter\n");
/* memset register on start so do not clear registers again here */
if (ctx->roi_data) {
/* roi setup */ /* roi setup */
if (roi && roi->number && roi->regions) { MppEncROICfg2 *cfg = ( MppEncROICfg2 *)ctx->roi_data;
RK_S32 roi_buf_size = vepu541_get_roi_buf_size(w, h);
if (!ctx->roi_buf || roi_buf_size != ctx->roi_buf_size) {
if (NULL == ctx->roi_grp)
mpp_buffer_group_get_internal(&ctx->roi_grp, MPP_BUFFER_TYPE_ION);
else if (roi_buf_size != ctx->roi_buf_size) {
if (ctx->roi_buf) {
mpp_buffer_put(ctx->roi_buf);
ctx->roi_buf = NULL;
}
mpp_buffer_group_clear(ctx->roi_grp);
}
mpp_assert(ctx->roi_grp);
if (NULL == ctx->roi_buf)
mpp_buffer_get(ctx->roi_grp, &ctx->roi_buf, roi_buf_size);
ctx->roi_buf_size = roi_buf_size;
}
mpp_assert(ctx->roi_buf);
RK_S32 fd = mpp_buffer_get_fd(ctx->roi_buf);
void *buf = mpp_buffer_get_ptr(ctx->roi_buf);
regs->reg_base.enc_pic.roi_en = 1; regs->reg_base.enc_pic.roi_en = 1;
regs->reg_base.roi_addr = fd; regs->reg_base.roi_addr = mpp_buffer_get_fd(cfg->base_cfg_buf);
vepu541_set_roi(buf, roi, w, h); if (cfg->roi_qp_en) {
} else { regs->reg_base.roi_qp_addr = mpp_buffer_get_fd(cfg->qp_cfg_buf);
regs->reg_base.enc_pic.roi_en = 0; regs->reg_base.roi_en.roi_qp_en = 1;
regs->reg_base.roi_addr = 0; }
if (cfg->roi_amv_en) {
regs->reg_base.qoi_amv_addr = mpp_buffer_get_fd(cfg->amv_cfg_buf);
regs->reg_base.roi_en.roi_amv_en = 1;
}
if (cfg->roi_mv_en) {
regs->reg_base.qoi_mv_addr = mpp_buffer_get_fd(cfg->mv_cfg_buf);
regs->reg_base.roi_en.roi_mv_en = 1;
}
} }
hal_h264e_dbg_func("leave\n"); hal_h264e_dbg_func("leave\n");

View File

@@ -78,11 +78,7 @@ typedef struct H265eV580HalContext_t {
/* @frame_cnt starts from ZERO */ /* @frame_cnt starts from ZERO */
RK_U32 frame_cnt; RK_U32 frame_cnt;
Vepu541OsdCfg osd_cfg; Vepu541OsdCfg osd_cfg;
MppEncROICfg *roi_data; void *roi_data;
void *roi_buf;
MppBufferGroup roi_grp;
MppBuffer roi_hw_buf;
RK_U32 roi_buf_size;
MppEncCfgSet *cfg; MppEncCfgSet *cfg;
MppBufferGroup tile_grp; MppBufferGroup tile_grp;
@@ -1096,18 +1092,8 @@ MPP_RET hal_h265e_v580_deinit(void *hal)
} }
MPP_FREE(ctx->input_fmt); MPP_FREE(ctx->input_fmt);
MPP_FREE(ctx->roi_buf);
hal_bufs_deinit(ctx->dpb_bufs); hal_bufs_deinit(ctx->dpb_bufs);
if (ctx->roi_hw_buf) {
mpp_buffer_put(ctx->roi_hw_buf);
ctx->roi_hw_buf = NULL;
}
if (ctx->roi_grp) {
mpp_buffer_group_put(ctx->roi_grp);
ctx->roi_grp = NULL;
}
if (ctx->hw_tile_buf[0]) { if (ctx->hw_tile_buf[0]) {
mpp_buffer_put(ctx->hw_tile_buf[0]); mpp_buffer_put(ctx->hw_tile_buf[0]);
ctx->hw_tile_buf[0] = NULL; ctx->hw_tile_buf[0] = NULL;
@@ -1228,82 +1214,31 @@ vepu580_h265_set_patch_info(MppDev dev, H265eSyntax_new *syn, Vepu541Fmt input_f
return ret; return ret;
} }
MPP_RET vepu580_h265_set_roi(void *dst_buf, void *src_buf, RK_S32 w, RK_S32 h) static MPP_RET vepu580_h265_set_roi_regs(H265eV580HalContext *ctx, hevc_vepu580_base *regs)
{ {
Vepu541RoiCfg *src = (Vepu541RoiCfg *)src_buf; /* memset register on start so do not clear registers again here */
Vepu541RoiCfg *dst = (Vepu541RoiCfg *)dst_buf; if (ctx->roi_data) {
RK_S32 mb_w = MPP_ALIGN(w, 64) / 64; /* roi setup */
RK_S32 mb_h = MPP_ALIGN(h, 64) / 64; MppEncROICfg2 *cfg = ( MppEncROICfg2 *)ctx->roi_data;
RK_S32 ctu_line = mb_w;
RK_S32 i, j, cu16cnt;
for (j = 0; j < mb_h; j++) {
for ( i = 0; i < mb_w; i++) {
RK_S32 ctu_addr = j * ctu_line + i;
RK_S32 cu16_num_line = ctu_line * 4;
for ( cu16cnt = 0; cu16cnt < 16; cu16cnt++) {
RK_S32 cu16_x;
RK_S32 cu16_y;
RK_S32 cu16_addr_in_frame;
cu16_x = cu16cnt & 3;
cu16_y = cu16cnt / 4;
cu16_x += i * 4;
cu16_y += j * 4;
cu16_addr_in_frame = cu16_x + cu16_y * cu16_num_line;
dst[ctu_addr * 16 + cu16cnt] = src[cu16_addr_in_frame];
}
}
}
return MPP_OK;
}
static MPP_RET
vepu580_h265_set_roi_regs(H265eV580HalContext *ctx, hevc_vepu580_base *regs)
{
MppEncROICfg *cfg = (MppEncROICfg*)ctx->roi_data;
RK_U32 h = ctx->cfg->prep.height;
RK_U32 w = ctx->cfg->prep.width;
// RK_U8 *roi_base;
if (!cfg)
return MPP_OK;
if (cfg->number && cfg->regions) {
RK_U32 roi_buf_size = vepu541_get_roi_buf_size(w, h);
if (!ctx->roi_hw_buf || roi_buf_size != ctx->roi_buf_size) {
if (NULL == ctx->roi_grp)
mpp_buffer_group_get_internal(&ctx->roi_grp, MPP_BUFFER_TYPE_ION);
else if (roi_buf_size != ctx->roi_buf_size) {
if (ctx->roi_hw_buf) {
mpp_buffer_put(ctx->roi_hw_buf);
ctx->roi_hw_buf = NULL;
}
MPP_FREE(ctx->roi_buf);
mpp_buffer_group_clear(ctx->roi_grp);
}
mpp_assert(ctx->roi_grp);
if (NULL == ctx->roi_hw_buf)
mpp_buffer_get(ctx->roi_grp, &ctx->roi_hw_buf, roi_buf_size);
if (ctx->roi_buf == NULL)
ctx->roi_buf = mpp_malloc(RK_U8, roi_buf_size);
ctx->roi_buf_size = roi_buf_size;
}
regs->reg0192_enc_pic.roi_en = 1; regs->reg0192_enc_pic.roi_en = 1;
regs->reg0178_roi_addr = mpp_buffer_get_fd(ctx->roi_hw_buf); regs->reg0178_roi_addr = mpp_buffer_get_fd(cfg->base_cfg_buf);
//to be Done if (cfg->roi_qp_en) {
regs->reg0179_roi_qp_addr = mpp_buffer_get_fd(cfg->qp_cfg_buf);
// regs->reg0179_roi_qp_addr = mpp_buffer_get_fd(ctx->roi_hw_buf); regs->reg0228_roi_en.roi_qp_en = 1;
// regs->reg0180_qoi_amv_addr = mpp_buffer_get_fd(ctx->roi_hw_buf);
// regs->reg0181_qoi_mv_addr = mpp_buffer_get_fd(ctx->roi_hw_buf);
// roi_base = (RK_U8 *)mpp_buffer_get_ptr(ctx->roi_hw_buf);
// vepu541_set_roi(ctx->roi_buf, cfg, w, h);
// vepu541_h265_set_roi(roi_base, ctx->roi_buf, w, h);
} }
if (cfg->roi_amv_en) {
regs->reg0180_roi_amv_addr = mpp_buffer_get_fd(cfg->amv_cfg_buf);
regs->reg0228_roi_en.roi_amv_en = 1;
}
if (cfg->roi_mv_en) {
regs->reg0181_roi_mv_addr = mpp_buffer_get_fd(cfg->mv_cfg_buf);
regs->reg0228_roi_en.roi_mv_en = 1;
}
}
return MPP_OK; return MPP_OK;
} }
@@ -1710,15 +1645,6 @@ void vepu580_h265_set_hw_address(H265eV580HalContext *ctx, hevc_vepu580_base *re
regs->reg0174_bsbr_addr = regs->reg0172_bsbt_addr; regs->reg0174_bsbr_addr = regs->reg0172_bsbt_addr;
regs->reg0175_adr_bsbs = regs->reg0172_bsbt_addr; regs->reg0175_adr_bsbs = regs->reg0172_bsbt_addr;
regs->reg0176_lpfw_addr = regs->reg0160_adr_src0;
regs->reg0177_lpfr_addr = regs->reg0160_adr_src0;
regs->reg0178_roi_addr = regs->reg0160_adr_src0;
regs->reg0179_roi_qp_addr = regs->reg0160_adr_src0;
regs->reg0180_roi_amv_addr = regs->reg0160_adr_src0;
regs->reg0181_roi_mv_addr = regs->reg0160_adr_src0;
regs->reg0182_ebuft_addr = regs->reg0160_adr_src0;
regs->reg183_ebufb_addr = regs->reg0160_adr_src0;
mpp_dev_set_reg_offset(ctx->dev, 175, mpp_packet_get_length(task->packet)); mpp_dev_set_reg_offset(ctx->dev, 175, mpp_packet_get_length(task->packet));
} }
MPP_RET hal_h265e_v580_gen_regs(void *hal, HalEncTask *task) MPP_RET hal_h265e_v580_gen_regs(void *hal, HalEncTask *task)
@@ -1743,7 +1669,6 @@ MPP_RET hal_h265e_v580_gen_regs(void *hal, HalEncTask *task)
hal_h265e_dbg_simple("frame %d | type %d | start gen regs", hal_h265e_dbg_simple("frame %d | type %d | start gen regs",
ctx->frame_cnt, ctx->frame_type); ctx->frame_cnt, ctx->frame_type);
memset(regs, 0, sizeof(H265eV580RegSet)); memset(regs, 0, sizeof(H265eV580RegSet));
reg_ctl->reg0004_enc_strt.lkt_num = 0; reg_ctl->reg0004_enc_strt.lkt_num = 0;
@@ -1780,9 +1705,6 @@ MPP_RET hal_h265e_v580_gen_regs(void *hal, HalEncTask *task)
reg_ctl->reg0014_enc_wdg.vs_load_thd = 0; reg_ctl->reg0014_enc_wdg.vs_load_thd = 0;
reg_ctl->reg0014_enc_wdg.rfp_load_thd = 0; reg_ctl->reg0014_enc_wdg.rfp_load_thd = 0;
reg_base->reg0196_enc_rsl.pic_wd8_m1 = pic_width_align8 / 8 - 1; reg_base->reg0196_enc_rsl.pic_wd8_m1 = pic_width_align8 / 8 - 1;
reg_base->reg0197_src_fill.pic_wfill = (syn->pp.pic_width & 0x7) reg_base->reg0197_src_fill.pic_wfill = (syn->pp.pic_width & 0x7)
? (8 - (syn->pp.pic_width & 0x7)) : 0; ? (8 - (syn->pp.pic_width & 0x7)) : 0;
@@ -2304,7 +2226,8 @@ MPP_RET hal_h265e_v580_get_task(void *hal, HalEncTask *task)
} }
if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) { if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
MppMeta meta = mpp_frame_get_meta(frame); MppMeta meta = mpp_frame_get_meta(frame);
mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void **)&ctx->roi_data);
mpp_meta_get_ptr(meta, KEY_ROI_DATA2, (void **)&ctx->roi_data);
mpp_meta_get_ptr(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data); mpp_meta_get_ptr(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data);
mpp_meta_get_ptr(meta, KEY_OSD_DATA2, (void **)&ctx->osd_cfg.osd_data2); mpp_meta_get_ptr(meta, KEY_OSD_DATA2, (void **)&ctx->osd_cfg.osd_data2);
} }