[h264e]: add configuration of ROI

Change-Id: Ieba60baedc8fabd248112636f5ea59a107775403
Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
This commit is contained in:
timkingh.huang
2017-12-21 11:47:27 +08:00
committed by Herman Chen
parent bb5552b7d9
commit 1acefd6207
7 changed files with 148 additions and 15 deletions

View File

@@ -120,6 +120,7 @@ typedef enum {
MPP_ENC_GET_SEI_DATA, /* SEI: Supplement Enhancemant Information, parameter is MppPacket */
MPP_ENC_PRE_ALLOC_BUFF, /* allocate buffers before encoding */
MPP_ENC_SET_QP_RANGE, /* used for adjusting qp range, the parameter can be 1 or 2 */
MPP_ENC_SET_ROI_CFG, /* set MppEncROICfg structure */
MPP_ENC_CMD_END,
MPP_ISP_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ISP,
@@ -455,22 +456,30 @@ typedef struct MppEncPrepCfg_t {
MppEncPrepSharpenCfg sharpen;
} MppEncPrepCfg;
/*
* Mpp ROI parameter
* Region configture define a rectangle as ROI
/**
* @brief Mpp ROI parameter
* Region configure define a rectangle as ROI
* @note x, y, w, h are calculated in pixels, which had better be 16-pixel aligned.
* These parameters MUST retain in memory when encoder is running.
* TODO: Only absolute qp is supported so far, relative qp should be supported
* in the future. Also, the ROI regions can be overlaid with each other,
* so overlay priority should be considered.
*/
typedef struct MppEncROIRegion_t {
RK_U16 x;
RK_U16 y;
RK_U16 w;
RK_U16 h;
RK_U16 intra;
RK_U16 quality;
RK_U16 x; /**< horizontal position of top left corner */
RK_U16 y; /**< vertical position of top left corner */
RK_U16 w; /**< width of ROI rectangle */
RK_U16 h; /**< height of ROI rectangle */
RK_U16 intra; /**< flag of forced intra macroblock */
RK_U16 quality; /**< absolute qp of macroblock */
} MppEncROIRegion;
/**
* @brief MPP encoder's ROI configuration
*/
typedef struct MppEncROICfg_t {
RK_U32 number;
MppEncROIRegion *regions;
RK_U32 number; /**< ROI rectangle number */
MppEncROIRegion *regions;/**< ROI parameters */
} MppEncROICfg;
/*

View File

@@ -521,6 +521,10 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param)
mpp_enc_dbg_ctrl("set osd data\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_SET_ROI_CFG : {
mpp_enc_dbg_ctrl("set roi data\n");
ret = mpp_hal_control(enc->hal, cmd, param);
} break;
case MPP_ENC_SET_SEI_CFG : {
mpp_enc_dbg_ctrl("set sei\n");
ret = mpp_hal_control(enc->hal, cmd, param);

View File

@@ -434,6 +434,7 @@ typedef struct H264eHalContext_t {
H264eOsdPltType osd_plt_type; //-1:invalid, 0:user define, 1:default
MppEncOSDData osd_data;
MppEncROICfg roi_data;
MppEncSeiMode sei_mode;
MppEncCfgSet *cfg;

View File

@@ -328,6 +328,7 @@ MPP_RET hal_h264e_rkv_init(void *hal, MppHalCfg *cfg)
ctx->frame_cnt_send_ready = 0;
ctx->num_frames_to_send = 1;
ctx->osd_plt_type = H264E_OSD_PLT_TYPE_NONE;
ctx->hw_cfg.roi_en = 1;
/* support multi-refs */
dpb_ctx = (H264eRkvDpbCtx *)ctx->dpb_ctx;
@@ -704,6 +705,24 @@ h264e_rkv_set_osd_regs(H264eHalContext *ctx, H264eRkvRegSet *regs)
return MPP_OK;
}
static MPP_RET
h264e_rkv_set_roi_regs(H264eHalContext *ctx, H264eRkvRegSet *regs)
{
MppEncROICfg *cfg = &ctx->roi_data;
h264e_hal_rkv_buffers *bufs = (h264e_hal_rkv_buffers *)ctx->buffers;
RK_U8 *roi_base;
if(cfg->number && cfg->regions){
regs->swreg10.roi_enc = 1;
regs->swreg29_ctuc_addr = mpp_buffer_get_fd(bufs->hw_roi_buf[0]);
roi_base = (RK_U8 *)mpp_buffer_get_ptr(bufs->hw_roi_buf[0]);
rkv_config_roi_area(ctx, roi_base);
}
return MPP_OK;
}
static MPP_RET h264e_rkv_set_pp_regs(H264eRkvRegSet *regs, H264eHwCfg *syn,
MppEncPrepCfg *prep_cfg, MppBuffer hw_buf_w,
MppBuffer hw_buf_r)
@@ -1394,6 +1413,9 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
h264e_rkv_set_osd_regs(ctx, regs);
/* ROI configure */
h264e_rkv_set_roi_regs(ctx, regs);
regs->swreg69.bs_lgth = 0x0;
regs->swreg70.sse_l32 = 0x0;
@@ -1848,6 +1870,10 @@ MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param)
h264e_rkv_set_osd_data(ctx, param);
break;
}
case MPP_ENC_SET_ROI_CFG : {
h264e_rkv_set_roi_data(ctx, param);
break;
}
case MPP_ENC_SET_SEI_CFG: {
ctx->sei_mode = *((MppEncSeiMode *)param);
break;

View File

@@ -73,3 +73,68 @@ MPP_RET h264e_rkv_set_osd_data(H264eHalContext *ctx, void *param)
h264e_hal_leave();
return MPP_OK;
}
MPP_RET h264e_rkv_set_roi_data(H264eHalContext *ctx, void *param)
{
MppEncROICfg *src = (MppEncROICfg *)param;
MppEncROICfg *dst = &ctx->roi_data;
h264e_hal_enter();
if (src->number && src->regions) {
dst->number = src->number;
dst->regions = src->regions;
} else {
memset(dst, 0, sizeof(*dst));
}
h264e_hal_leave();
return MPP_OK;
}
MPP_RET rkv_config_roi_area(H264eHalContext *ctx, RK_U8 *roi_base)
{
h264e_hal_enter();
RK_U32 ret = MPP_OK, idx = 0, num = 0;
RK_U32 init_pos_x, init_pos_y, roi_width, roi_height, mb_width, pos_y;
RkvRoiCfg cfg;
MppEncROIRegion *region;
RK_U8 *ptr = roi_base;
if(ctx == NULL || roi_base == NULL){
mpp_err("NULL pointer ctx %p roi_base %p\n", ctx, roi_base);
return MPP_NOK;
}
region = ctx->roi_data.regions;
for(num = 0; num < ctx->roi_data.number; num++){
init_pos_x = (region->x + 15) / 16;
init_pos_y = (region->y + 15) / 16;
roi_width = (region->w + 15) / 16;
roi_height = (region->h + 15) / 16;
mb_width = (ctx->hw_cfg.width + 15) / 16;
pos_y = init_pos_y;
for (idx = 0; idx < roi_width * roi_height; idx++) {
if(idx % roi_width == 0)
pos_y = init_pos_y + idx / roi_width;
ptr = roi_base + (pos_y * mb_width + init_pos_x) + (idx % roi_width);
if (region->quality) {
cfg.qp_y = region->quality;
cfg.set_qp_y_en = 1;
cfg.forbid_inter = region->intra;
} else {
cfg.set_qp_y_en = 0;
cfg.forbid_inter = 0;
}
memcpy(ptr, &cfg, sizeof(RkvRoiCfg));
}
region++;
}
h264e_hal_leave();
return ret;
}

View File

@@ -19,15 +19,15 @@
#include "hal_h264e_com.h"
// TODO: add ROI function
typedef struct h264e_hal_rkv_roi_cfg_t {
typedef struct{
RK_U8 qp_y : 6;
RK_U8 set_qp_y_en : 1;
RK_U8 forbid_inter : 1;
} h264e_hal_rkv_roi_cfg;
} RkvRoiCfg;
MPP_RET h264e_rkv_set_osd_plt(H264eHalContext *ctx, void *param);
MPP_RET h264e_rkv_set_osd_data(H264eHalContext *ctx, void *param);
MPP_RET h264e_rkv_set_roi_data(H264eHalContext *ctx, void *param);
MPP_RET rkv_config_roi_area(H264eHalContext *ctx, RK_U8 *roi_base);
#endif /* __HAL_H264E_RKV_UTILS_H__ */

View File

@@ -38,6 +38,7 @@
#define MPI_ENC_TEST_SET_IDR_FRAME 0
#define MPI_ENC_TEST_SET_OSD 0
#define MPI_ENC_TEST_SET_ROI 1
typedef struct {
char file_input[MAX_FILE_NAME_LENGTH];
@@ -81,6 +82,7 @@ typedef struct {
MppBuffer md_buf[MPI_ENC_IO_COUNT];
MppBuffer osd_idx_buf[MPI_ENC_IO_COUNT];
MppEncOSDPlt osd_plt;
MppEncROIRegion roi_region[3]; /* can be more regions */
MppEncSeiMode sei_mode;
// paramter for resource malloc
@@ -799,6 +801,32 @@ MPP_RET test_mpp_run(MpiEncTestData *p)
}
#endif
#if MPI_ENC_TEST_SET_ROI
MppEncROIRegion *region = p->roi_region;
MppEncROICfg roi_cfg;
/* calculated in pixels */
region->x = region->y = 64;
region->w = region->h = 128; /* 16-pixel aligned is better */
region->intra = 0; /* flag of forced intra macroblock */
region->quality = 20; /* qp of macroblock */
region++;
region->x = region->y = 256;
region->w = region->h = 128; /* 16-pixel aligned is better */
region->intra = 1; /* flag of forced intra macroblock */
region->quality = 25; /* qp of macroblock */
roi_cfg.number = 2;
roi_cfg.regions = p->roi_region;
ret = mpi->control(ctx, MPP_ENC_SET_ROI_CFG, &roi_cfg);
if (MPP_OK != ret) {
mpp_err("mpi control enc set roi data failed\n");
goto RET;
}
#endif
ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task);
if (ret) {
mpp_err("mpp task input enqueue failed\n");