mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-04 16:52:40 +08:00
[h264e]: add configuration of ROI
Change-Id: Ieba60baedc8fabd248112636f5ea59a107775403 Signed-off-by: timkingh.huang <timkingh.huang@rock-chips.com>
This commit is contained in:

committed by
Herman Chen

parent
bb5552b7d9
commit
1acefd6207
@@ -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;
|
||||
|
||||
/*
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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__ */
|
||||
|
@@ -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");
|
||||
|
Reference in New Issue
Block a user