diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 4ad19e14..a1416ab5 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -106,9 +106,9 @@ typedef enum { MPP_ENC_GET_CODEC_CFG, /* get MppEncCodecCfg structure */ /* runtime encoder setup control */ MPP_ENC_SET_IDR_FRAME, /* next frame will be encoded as intra frame */ - MPP_ENC_SET_OSD_PLT_CFG, /* set OSD palette, parameter should be pointer to MppEncOSDPlt */ - MPP_ENC_SET_OSD_DATA_CFG, /* set OSD data with at most 8 regions, parameter should be pointer to MppEncOSDData */ - MPP_ENC_GET_OSD_CFG, + MPP_ENC_SET_OSD_LEGACY_0, /* deprecated */ + MPP_ENC_SET_OSD_LEGACY_1, /* deprecated */ + MPP_ENC_SET_OSD_LEGACY_2, /* deprecated */ MPP_ENC_GET_HDR_SYNC, /* get vps / sps / pps which has better sync behavior parameter is MppPacket */ MPP_ENC_GET_EXTRA_INFO, /* deprecated */ MPP_ENC_SET_SEI_CFG, /* SEI: Supplement Enhancemant Information, parameter is MppSeiMode */ @@ -174,6 +174,12 @@ typedef enum { MPP_ENC_CFG_GOPREF = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_GOPREF, MPP_ENC_SET_GOPREF, /* set MppEncGopRef structure */ + MPP_ENC_CFG_OSD = CMD_MODULE_CODEC | CMD_CTX_ID_ENC | CMD_ENC_CFG_OSD, + MPP_ENC_SET_OSD_PLT_CFG, /* set OSD palette, parameter should be pointer to MppEncOSDPltCfg */ + MPP_ENC_GET_OSD_PLT_CFG, /* get OSD palette, parameter should be pointer to MppEncOSDPltCfg */ + MPP_ENC_SET_OSD_DATA_CFG, /* set OSD data with at most 8 regions, parameter should be pointer to MppEncOSDData */ + MPP_ENC_GET_OSD_DATA_CFG, /* get OSD data with at most 8 regions, parameter should be pointer to MppEncOSDData */ + MPP_ENC_CMD_END, MPP_ISP_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ISP, diff --git a/inc/rk_venc_cmd.h b/inc/rk_venc_cmd.h index b0dc695c..d2b4a24f 100644 --- a/inc/rk_venc_cmd.h +++ b/inc/rk_venc_cmd.h @@ -1111,39 +1111,68 @@ typedef struct MppEncROICfg_t { * alpha : 8 bits */ #define MPP_ENC_OSD_PLT_WHITE ((255<<24)|(128<<16)|(128<<8)|235) -#define MPP_ENC_OSD_PLT_YELLOW ((255<<24)|(146<<16)|( 16<<8 )|210) -#define MPP_ENC_OSD_PLT_CYAN ((255<<24)|( 16<<16 )|(166<<8)|170) -#define MPP_ENC_OSD_PLT_GREEN ((255<<24)|( 34<<16 )|( 54<<8 )|145) +#define MPP_ENC_OSD_PLT_YELLOW ((255<<24)|(146<<16)|( 16<<8)|210) +#define MPP_ENC_OSD_PLT_CYAN ((255<<24)|( 16<<16)|(166<<8)|170) +#define MPP_ENC_OSD_PLT_GREEN ((255<<24)|( 34<<16)|( 54<<8)|145) #define MPP_ENC_OSD_PLT_TRANS (( 0<<24)|(222<<16)|(202<<8)|106) -#define MPP_ENC_OSD_PLT_RED ((255<<24)|(240<<16)|( 90<<8 )|81) -#define MPP_ENC_OSD_PLT_BLUE ((255<<24)|(110<<16)|(240<<8)|41) -#define MPP_ENC_OSD_PLT_BLACK ((255<<24)|(128<<16)|(128<<8)|16) +#define MPP_ENC_OSD_PLT_RED ((255<<24)|(240<<16)|( 90<<8)| 81) +#define MPP_ENC_OSD_PLT_BLUE ((255<<24)|(110<<16)|(240<<8)| 41) +#define MPP_ENC_OSD_PLT_BLACK ((255<<24)|(128<<16)|(128<<8)| 16) + +typedef enum MppEncOSDPltType_e { + MPP_ENC_OSD_PLT_TYPE_DEFAULT, + MPP_ENC_OSD_PLT_TYPE_USERDEF, + MPP_ENC_OSD_PLT_TYPE_BUTT, +} MppEncOSDPltType; + +/* OSD palette value define */ +typedef union MppEncOSDPltVal_u { + struct { + RK_U32 y : 8; + RK_U32 u : 8; + RK_U32 v : 8; + RK_U32 alpha : 8; + }; + RK_U32 val; +} MppEncOSDPltVal; typedef struct MppEncOSDPlt_t { - RK_U32 buf[256]; + MppEncOSDPltVal data[256]; } MppEncOSDPlt; +typedef enum MppEncOSDPltCfgChange_e { + MPP_ENC_OSD_PLT_CFG_CHANGE_MODE = (1 << 0), /* change osd plt type */ + MPP_ENC_OSD_PLT_CFG_CHANGE_PLT_VAL = (1 << 1), /* change osd plt table value */ + MPP_ENC_OSD_PLT_CFG_CHANGE_ALL = (0xFFFFFFFF), +} MppEncOSDPltCfgChange; + +typedef struct MppEncOSDPltCfg_t { + RK_U32 change; + MppEncOSDPltType type; + MppEncOSDPlt *plt; +} MppEncOSDPltCfg; + /* position info is unit in 16 pixels(one MB), and * x-directon range in pixels = (rd_pos_x - lt_pos_x + 1) * 16; * y-directon range in pixels = (rd_pos_y - lt_pos_y + 1) * 16; */ typedef struct MppEncOSDRegion_t { - RK_U32 enable; - RK_U32 inverse; - RK_U32 start_mb_x; - RK_U32 start_mb_y; - RK_U32 num_mb_x; - RK_U32 num_mb_y; - RK_U32 buf_offset; + RK_U32 enable; + RK_U32 inverse; + RK_U32 start_mb_x; + RK_U32 start_mb_y; + RK_U32 num_mb_x; + RK_U32 num_mb_y; + RK_U32 buf_offset; } MppEncOSDRegion; /* if num_region > 0 && region==NULL * use old osd data */ typedef struct MppEncOSDData_t { - MppBuffer buf; - RK_U32 num_region; - MppEncOSDRegion region[8]; + MppBuffer buf; + RK_U32 num_region; + MppEncOSDRegion region[8]; } MppEncOSDData; typedef struct MppEncUserData_t { @@ -1151,5 +1180,4 @@ typedef struct MppEncUserData_t { void *pdata; } MppEncUserData; - #endif /*__RK_VENC_CMD_H__*/ diff --git a/mpp/codec/enc/h264/h264e_api_v2.c b/mpp/codec/enc/h264/h264e_api_v2.c index 7b5d83c6..a4c19c70 100644 --- a/mpp/codec/enc/h264/h264e_api_v2.c +++ b/mpp/codec/enc/h264/h264e_api_v2.c @@ -391,8 +391,6 @@ static MPP_RET h264e_proc_cfg(void *ctx, MpiCmd cmd, void *param) case MPP_ENC_SET_IDR_FRAME : { p->idr_request++; } break; - case MPP_ENC_SET_OSD_PLT_CFG : { - } break; case MPP_ENC_SET_OSD_DATA_CFG : { } break; case MPP_ENC_SET_SPLIT : { diff --git a/mpp/codec/enc/h265/h265e_api_v2.c b/mpp/codec/enc/h265/h265e_api_v2.c index 36f3ccf0..ebddbe9d 100644 --- a/mpp/codec/enc/h265/h265e_api_v2.c +++ b/mpp/codec/enc/h265/h265e_api_v2.c @@ -500,11 +500,6 @@ static MPP_RET h265e_proc_cfg(void *ctx, MpiCmd cmd, void *param) } break; - case MPP_ENC_SET_OSD_PLT_CFG: { - memcpy((void*)&p->cfg->osd_plt, param, sizeof(MppEncOSDPlt)); - p->plt_flag = 1; - break; - } case MPP_ENC_SET_SPLIT : { MppEncSliceSplit *src = (MppEncSliceSplit *)param; MppEncH265SliceCfg *slice_cfg = &p->cfg->codec.h265.slice_cfg; diff --git a/mpp/codec/enc/h265/h265e_syntax.c b/mpp/codec/enc/h265/h265e_syntax.c index 118c3932..d67ac332 100644 --- a/mpp/codec/enc/h265/h265e_syntax.c +++ b/mpp/codec/enc/h265/h265e_syntax.c @@ -349,10 +349,5 @@ RK_S32 h265e_syntax_fill(void *ctx) fill_slice_parameters(h, &syn->sp); fill_ref_parameters(h, &syn->sp); fill_frm_info(h, &syn->frms); - syn->ud.plt_data = NULL; - if (h->plt_flag) { - syn->ud.plt_data = (void*)&h->cfg->osd_plt; - h->plt_flag = 0; - } return 0; } diff --git a/mpp/codec/mpp_enc_v2.cpp b/mpp/codec/mpp_enc_v2.cpp index 906544dc..09d4680c 100644 --- a/mpp/codec/mpp_enc_v2.cpp +++ b/mpp/codec/mpp_enc_v2.cpp @@ -304,6 +304,35 @@ static void mpp_enc_proc_cfg(MppEncImpl *enc) *enc->cmd_ret = MPP_NOK; } } break; + case MPP_ENC_SET_OSD_PLT_CFG : { + MppEncOSDPltCfg *src = (MppEncOSDPltCfg *)enc->param; + MppEncOSDPltCfg *dst = &enc->cfg.plt_cfg; + RK_U32 change = src->change; + + if (change) { + RK_S32 cfg_err = 0; + + if (change & MPP_ENC_OSD_PLT_CFG_CHANGE_MODE) { + if (src->type >= MPP_ENC_OSD_PLT_TYPE_BUTT) { + mpp_err_f("invalid osd plt type %d\n", src->type); + cfg_err |= MPP_ENC_OSD_PLT_CFG_CHANGE_MODE; + } else + dst->type = src->type; + } + + if (change & MPP_ENC_OSD_PLT_CFG_CHANGE_PLT_VAL) { + if (src->plt == NULL) { + mpp_err_f("invalid osd plt NULL pointer\n"); + cfg_err |= MPP_ENC_OSD_PLT_CFG_CHANGE_PLT_VAL; + } else { + memcpy(dst->plt, src->plt, sizeof(MppEncOSDPlt)); + } + } + + dst->change = cfg_err ? 0 : change; + enc_dbg_ctrl("plt type %d data %p\n", dst->type, src->plt); + } + } break; default : { enc_impl_proc_cfg(enc->impl, enc->cmd, enc->param); if (MPP_ENC_SET_CODEC_CFG == enc->cmd || @@ -861,6 +890,7 @@ MPP_RET mpp_enc_init_v2(MppEnc *enc, MppEncCfg *cfg) /* NOTE: setup configure coding for check */ p->cfg.codec.coding = coding; p->set.codec.coding = coding; + p->cfg.plt_cfg.plt = &p->cfg.plt_data; sem_init(&p->enc_reset, 0, 0); sem_init(&p->enc_ctrl, 0, 0); @@ -1022,6 +1052,10 @@ MPP_RET mpp_enc_control_v2(MppEnc ctx, MpiCmd cmd, void *param) enc_dbg_ctrl("get header mode\n"); memcpy(param, &enc->hdr_mode, sizeof(enc->hdr_mode)); } break; + case MPP_ENC_GET_OSD_PLT_CFG : { + enc_dbg_ctrl("get osd plt cfg\n"); + memcpy(param, &enc->cfg.plt_cfg, sizeof(enc->cfg.plt_cfg)); + } break; default : { // Cmd which is not get configure will handle by enc_impl enc->cmd = cmd; diff --git a/mpp/common/h264e_syntax_new.h b/mpp/common/h264e_syntax_new.h index 677a5ddc..440122f4 100644 --- a/mpp/common/h264e_syntax_new.h +++ b/mpp/common/h264e_syntax_new.h @@ -29,8 +29,6 @@ typedef enum H264eSyntaxType_e { H264E_SYN_FRAME, H264E_SYN_RC, H264E_SYN_ROI, - H264E_SYN_OSD_PLT, - H264E_SYN_OSD, H264E_SYN_RC_RET, H264E_SYN_BUTT, } H264eSyntaxType; diff --git a/mpp/common/h265e_syntax_new.h b/mpp/common/h265e_syntax_new.h index fe5806fb..a1cd5e7c 100644 --- a/mpp/common/h265e_syntax_new.h +++ b/mpp/common/h265e_syntax_new.h @@ -222,7 +222,6 @@ typedef struct H265eSyntax_new_t { RK_S32 idr_request; H265ePicParams pp; H265eSlicParams sp; - UserDatas ud; H265eFrmInfo frms; } H265eSyntax_new; diff --git a/mpp/hal/rkenc/common/vepu541_common.c b/mpp/hal/rkenc/common/vepu541_common.c index fbc37d87..574bf6d5 100644 --- a/mpp/hal/rkenc/common/vepu541_common.c +++ b/mpp/hal/rkenc/common/vepu541_common.c @@ -24,6 +24,7 @@ #include "vepu541_common.h" #include "mpp_device_msg.h" +#include "mpp_buffer_impl.h" static const RK_S32 zeros[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -378,6 +379,11 @@ MPP_RET vepu541_set_roi(void *buf, MppEncROICfg *roi, RK_S32 w, RK_S32 h) #define VEPU541_OSD_CFG_OFFSET 0x01C0 #define VEPU541_OSD_PLT_OFFSET 0x0400 +typedef enum Vepu541OsdPltType_e { + VEPU541_OSD_PLT_TYPE_USERDEF = 0, + VEPU541_OSD_PLT_TYPE_DEFAULT = 1, +} Vepu541OsdPltType; + typedef struct Vepu541OsdReg_t { /* * OSD_CFG @@ -446,40 +452,36 @@ typedef struct Vepu541OsdReg_t { RK_U32 osd_addr[8]; } Vepu541OsdReg; -typedef enum Vepu541OsdPltType_e { - VEPU541_OSD_PLT_TYPE_USERDEF = 0, - VEPU541_OSD_PLT_TYPE_DEFAULT = 1, -} Vepu541OsdPltType; - -MPP_RET vepu541_set_osd_region(void *reg_base, MppDevCtx dev, - MppEncOSDData *osd, MppEncOSDPlt *plt) +MPP_RET vepu541_set_osd(Vepu541OsdCfg *cfg) { - RK_U8 *base = (RK_U8 *)reg_base + VEPU541_OSD_CFG_OFFSET; - Vepu541OsdPltType type = VEPU541_OSD_PLT_TYPE_DEFAULT; - Vepu541OsdReg *regs = (Vepu541OsdReg *)base; + Vepu541OsdReg *regs = (Vepu541OsdReg *)(cfg->reg_base + (size_t)VEPU541_OSD_CFG_OFFSET); + MppDevCtx dev = cfg->dev; + MppEncOSDPltCfg *plt_cfg = cfg->plt_cfg; + MppEncOSDData *osd = cfg->osd_data; - if (plt) { + if (plt_cfg->type == MPP_ENC_OSD_PLT_TYPE_USERDEF) { MppDevReqV1 req; req.cmd = MPP_CMD_SET_REG_WRITE; req.flag = 0; req.offset = VEPU541_REG_BASE_OSD_PLT; req.size = sizeof(MppEncOSDPlt); - req.data = plt; + req.data = plt_cfg->plt; mpp_device_add_request(dev, &req); - type = VEPU541_OSD_PLT_TYPE_USERDEF; - } - - if (NULL == osd || osd->num_region == 0 || NULL == osd->buf) { - regs->reg112.osd_e = 0; - regs->reg112.osd_inv_e = 0; + regs->reg112.osd_plt_cks = 1; + regs->reg112.osd_plt_typ = VEPU541_OSD_PLT_TYPE_USERDEF; + } else { regs->reg112.osd_plt_cks = 0; - regs->reg112.osd_plt_typ = type; - - return MPP_OK; + regs->reg112.osd_plt_typ = VEPU541_OSD_PLT_TYPE_DEFAULT; } + regs->reg112.osd_e = 0; + regs->reg112.osd_inv_e = 0; + + if (NULL == osd || osd->num_region == 0 || NULL == osd->buf) + return MPP_OK; + RK_S32 fd = mpp_buffer_get_fd(osd->buf); if (fd < 0) { mpp_err_f("invalid osd buffer fd %d\n", fd); @@ -491,11 +493,6 @@ MPP_RET vepu541_set_osd_region(void *reg_base, MppDevCtx dev, MppEncOSDRegion *region = osd->region; MppEncOSDRegion *tmp = region; - regs->reg112.osd_e = 0; - regs->reg112.osd_inv_e = 0; - regs->reg112.osd_plt_cks = 1; - regs->reg112.osd_plt_typ = type; - for (k = 0; k < num; k++, tmp++) { regs->reg112.osd_e |= tmp->enable << k; regs->reg112.osd_inv_e |= tmp->inverse << k; @@ -508,7 +505,7 @@ MPP_RET vepu541_set_osd_region(void *reg_base, MppDevCtx dev, pos->osd_rb_x = tmp->start_mb_x + tmp->num_mb_x - 1; pos->osd_rb_y = tmp->start_mb_y + tmp->num_mb_y - 1; - regs->osd_addr[k] = fd | (tmp->buf_offset << 10); + regs->osd_addr[k] = mpp_buffer_to_addr(osd->buf, tmp->buf_offset); } } diff --git a/mpp/hal/rkenc/common/vepu541_common.h b/mpp/hal/rkenc/common/vepu541_common.h index 6ae0885f..983efc4a 100644 --- a/mpp/hal/rkenc/common/vepu541_common.h +++ b/mpp/hal/rkenc/common/vepu541_common.h @@ -120,6 +120,13 @@ typedef struct Vepu541OsdPltColor_t { RK_U32 alpha : 8; } Vepu541OsdPltColor; +typedef struct Vepu541OsdCfg_t { + void *reg_base; + MppDevCtx dev; + MppEncOSDPltCfg *plt_cfg; + MppEncOSDData *osd_data; +} Vepu541OsdCfg; + #ifdef __cplusplus extern "C" { #endif @@ -138,8 +145,7 @@ MPP_RET vepu541_set_fmt(VepuFmtCfg *cfg, MppEncPrepCfg *prep); RK_S32 vepu541_get_roi_buf_size(RK_S32 w, RK_S32 h); MPP_RET vepu541_set_roi(void *buf, MppEncROICfg *roi, RK_S32 w, RK_S32 h); -MPP_RET vepu541_set_osd_region(void *reg_base, MppDevCtx dev, - MppEncOSDData *osd, MppEncOSDPlt *plt); +MPP_RET vepu541_set_osd(Vepu541OsdCfg *cfg); #ifdef __cplusplus } diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv_utils.c b/mpp/hal/rkenc/h264e/hal_h264e_rkv_utils.c index 97472487..75c4c2c9 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv_utils.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv_utils.c @@ -26,10 +26,11 @@ MPP_RET h264e_rkv_set_osd_plt(H264eHalContext *ctx, void *param) MppEncOSDPlt *plt = (MppEncOSDPlt *)param; hal_h264e_enter(); - if (plt->buf) { + if (plt->data) { MPP_RET ret = mpp_device_send_reg_with_id(ctx->dev_ctx, RKVE_IOC_SET_OSD_PLT, - param, sizeof(MppEncOSDPlt)); + plt->data, + sizeof(MppEncOSDPlt)); ctx->osd_plt_type = RKVE_OSD_PLT_TYPE_USERDEF; if (ret) { mpp_err_f("set osd plt error"); diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c index b6bf136d..937e4354 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c @@ -72,8 +72,7 @@ typedef struct HalH264eVepu541Ctx_t { RK_S32 roi_buf_size; /* osd */ - MppEncOSDPlt *osd_plt; - MppEncOSDData *osd_data; + Vepu541OsdCfg osd_cfg; /* register */ Vepu541H264eRegSet regs_set; @@ -150,6 +149,11 @@ static MPP_RET hal_h264e_vepu541_init(void *hal, MppEncHalCfg *cfg) goto DONE; } + p->osd_cfg.reg_base = &p->regs_set; + p->osd_cfg.dev = p->dev_ctx; + p->osd_cfg.plt_cfg = &p->cfg->plt_cfg; + p->osd_cfg.osd_data = NULL; + DONE: if (ret) hal_h264e_vepu541_deinit(hal); @@ -191,14 +195,6 @@ static RK_U32 update_vepu541_syntax(HalH264eVepu541Ctx *ctx, MppSyntax *syntax) hal_h264e_dbg_detail("update rc"); ctx->rc_syn = desc->p; } break; - case H264E_SYN_OSD_PLT : { - hal_h264e_dbg_detail("update osd plt"); - ctx->osd_plt = desc->p; - } break; - case H264E_SYN_OSD : { - hal_h264e_dbg_detail("update osd data"); - ctx->osd_data = desc->p; - } break; case H264E_SYN_ROI : { hal_h264e_dbg_detail("update roi"); ctx->roi_data = desc->p; @@ -253,11 +249,10 @@ static MPP_RET hal_h264e_vepu541_get_task(void *hal, HalEncTask *task) } ctx->roi_data = NULL; - ctx->osd_data = NULL; 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_OSD_DATA, (void **)&ctx->osd_data); + mpp_meta_get_ptr(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data); hal_h264e_dbg_func("leave %p\n", hal); @@ -1132,7 +1127,7 @@ static MPP_RET hal_h264e_vepu541_gen_regs(void *hal, HalEncTask *task) setup_vepu541_output(regs, task->packet, task->output); setup_vepu541_split(regs, &cfg->split); setup_vepu541_me(regs, sps, slice); - vepu541_set_osd_region(regs, ctx->dev_ctx, ctx->osd_data, ctx->osd_plt); + vepu541_set_osd(&ctx->osd_cfg); setup_vepu541_l2(&ctx->regs_l2_set, slice); mpp_env_get_u32("dump_l1_reg", &dump_l1_reg, 0); diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu541_reg.h b/mpp/hal/rkenc/h264e/hal_h264e_vepu541_reg.h index a57fcd83..702d48e7 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu541_reg.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu541_reg.h @@ -2082,73 +2082,6 @@ typedef struct Vepu541H264eRegSet_t { /* Number of valid 16x16 blocks for one frame. */ RK_U32 num_b16; } reg208; - - /* reg gap 209~251 */ - RK_U32 reg_209_251[43]; - - /* - * L2CFG_ADDR - * Address offset: 0x3F0 Access type: read and write - * Level2 configuration address - */ - struct { - /* Level2 configuration address. */ - RK_U32 l2cfg_addr; - } reg252; - - /* - * L2CFG_WDATA - * Address offset: 0x3F4 Access type: read and write - * L2 configuration write data - */ - struct { - /* - * L2 configuration write data. - * - * Single access: - * write address to VEPU_L2CFG_ADDR then write data to VEPU_L2CFG_WDATA. - * - * Burst access: - * write the start address to VEPU_L2CFG_ADDR then write datas - * (to VEPU_L2CFG_WDATA) consecutively. - * Address will be auto increased after write VEPU_L2CFG_WDATA, - * no need to configure VEPU_L2CFG_ADDR. - */ - RK_U32 l2cfg_wdata; - } reg253; - - /* - * L2CFG_RDATA - * Address offset: 0x3F8 Access type: read and write - * L2 configuration read data - */ - struct { - /* - * L2 configuration read data. - * - * Single access: - * write address to VEPU_L2CFG_ADDR then read data from VEPU_L2CFG_RDATA. - * - * Burst access: - * write the start address to VEPU_L2CFG_ADDR then read datas - * (from VEPU_L2CFG_RDATA) consecutively. - * Address will be auto increased after read VEPU_L2CFG_RDATA, - * no need to configure VEPU_L2CFG_ADDR. - */ - RK_U32 l2cfg_rdata; - } reg254; - - /* reg gap 255 */ - RK_U32 reg_255; - - /* - * OSD_PLT1 - * Address offset: 0x400~0x7FC Access type: read and write - * User defined OSD palette color from 0 ~ 255 - */ - struct { - Vepu541OsdPltColor plt_color[256]; - } reg256_511; } Vepu541H264eRegSet; /* return register is a subset of the whole register. */ diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu541_reg_l2.h b/mpp/hal/rkenc/h264e/hal_h264e_vepu541_reg_l2.h index 3ddcb187..5eee5bea 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu541_reg_l2.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu541_reg_l2.h @@ -19,6 +19,54 @@ #include "rk_type.h" +/* + * L2CFG_ADDR + * Address offset: 0x3F0 Access type: read and write + * Level2 configuration address + */ +/* + * L2CFG_WDATA + * Address offset: 0x3F4 Access type: read and write + * L2 configuration write data + */ +/* + * L2 configuration write data. + * + * Single access: + * write address to VEPU_L2CFG_ADDR then write data to VEPU_L2CFG_WDATA. + * + * Burst access: + * write the start address to VEPU_L2CFG_ADDR then write datas + * (to VEPU_L2CFG_WDATA) consecutively. + * Address will be auto increased after write VEPU_L2CFG_WDATA, + * no need to configure VEPU_L2CFG_ADDR. + */ + +/* + * L2CFG_RDATA + * Address offset: 0x3F8 Access type: read and write + * L2 configuration read data + */ +struct { + /* + * L2 configuration read data. + * + * Single access: + * write address to VEPU_L2CFG_ADDR then read data from VEPU_L2CFG_RDATA. + * + * Burst access: + * write the start address to VEPU_L2CFG_ADDR then read datas + * (from VEPU_L2CFG_RDATA) consecutively. + * Address will be auto increased after read VEPU_L2CFG_RDATA, + * no need to configure VEPU_L2CFG_ADDR. + */ + RK_U32 l2cfg_rdata; +} reg254; + +/* reg gap 255 */ +RK_U32 reg_255; + + typedef struct Vepu541H264eRegL2Set_t { /* * IPRD_TTHDY4_0_H264 ~ IPRD_TTHDY4_1_H264 diff --git a/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c b/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c index 2c0acbdc..8ef846fe 100644 --- a/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c +++ b/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c @@ -81,8 +81,7 @@ typedef struct H265eV541HalContext_t { /* @frame_cnt starts from ZERO */ RK_U32 frame_cnt; - RK_S32 osd_plt_type; - MppEncOSDData *osd_data; + Vepu541OsdCfg osd_cfg; MppEncROICfg *roi_data; void *roi_buf; MppEncCfgSet *set; @@ -349,7 +348,6 @@ MPP_RET hal_h265e_v541_init(void *hal, MppEncHalCfg *cfg) ctx->frame_cnt_gen_ready = 0; ctx->frame_cnt_send_ready = 0; ctx->num_frames_to_send = 1; - ctx->osd_plt_type = RKVE_OSD_PLT_TYPE_NONE; ctx->enc_mode = RKV_ENC_MODE; MppDevCfg dev_cfg = { @@ -375,6 +373,12 @@ MPP_RET hal_h265e_v541_init(void *hal, MppEncHalCfg *cfg) return MPP_ERR_MALLOC; } } + + ctx->osd_cfg.reg_base = ctx->regs; + ctx->osd_cfg.dev = ctx->dev_ctx; + ctx->osd_cfg.plt_cfg = &ctx->cfg->plt_cfg; + ctx->osd_cfg.osd_data = NULL; + ctx->frame_type = INTRA_FRAME; vepu541_h265_set_l2_regs(ctx, (H265eV541L2RegSet*)ctx->l2_regs); h265e_hal_leave(); @@ -1042,7 +1046,7 @@ MPP_RET hal_h265e_v541_gen_regs(void *hal, HalEncTask *task) vepu541_h265_set_ref_regs(syn, regs); - vepu541_set_osd_region(regs, ctx->dev_ctx, ctx->osd_data, syn->ud.plt_data); + vepu541_set_osd(&ctx->osd_cfg); /* ROI configure */ vepu541_h265_set_roi_regs(ctx, regs); @@ -1336,10 +1340,8 @@ MPP_RET hal_h265e_v541_get_task(void *hal, HalEncTask *task) ctx->frame_type = INTER_P_FRAME; } - ctx->roi_data = NULL; - ctx->osd_data = NULL; - mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void**)&ctx->roi_data); - mpp_meta_get_ptr(meta, KEY_OSD_DATA, (void**)&ctx->osd_data); + mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void **)&ctx->roi_data); + mpp_meta_get_ptr(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data); h265e_hal_leave(); return MPP_OK; diff --git a/mpp/hal/vpu/h264e/hal_h264e_vepu1_v2.c b/mpp/hal/vpu/h264e/hal_h264e_vepu1_v2.c index 70002153..2b52e36d 100644 --- a/mpp/hal/vpu/h264e/hal_h264e_vepu1_v2.c +++ b/mpp/hal/vpu/h264e/hal_h264e_vepu1_v2.c @@ -181,7 +181,6 @@ static RK_U32 update_vepu1_syntax(HalH264eVepu1Ctx *ctx, MppSyntax *syntax) hal_h264e_dbg_detail("update rc"); } break; case H264E_SYN_ROI : - case H264E_SYN_OSD : default : { mpp_log_f("invalid syntax type %d\n", desc->type); } break; diff --git a/mpp/hal/vpu/h264e/hal_h264e_vepu2_v2.c b/mpp/hal/vpu/h264e/hal_h264e_vepu2_v2.c index 76149986..38442e47 100644 --- a/mpp/hal/vpu/h264e/hal_h264e_vepu2_v2.c +++ b/mpp/hal/vpu/h264e/hal_h264e_vepu2_v2.c @@ -181,7 +181,6 @@ static RK_U32 update_vepu2_syntax(HalH264eVepu2Ctx *ctx, MppSyntax *syntax) hal_h264e_dbg_detail("update rc"); } break; case H264E_SYN_ROI : - case H264E_SYN_OSD : default : { mpp_log_f("invalid syntax type %d\n", desc->type); } break; diff --git a/mpp/hal/vpu/jpege/hal_jpege_vepu1.c b/mpp/hal/vpu/jpege/hal_jpege_vepu1.c index 63fbf53c..3b60ed98 100644 --- a/mpp/hal/vpu/jpege/hal_jpege_vepu1.c +++ b/mpp/hal/vpu/jpege/hal_jpege_vepu1.c @@ -561,7 +561,6 @@ MPP_RET hal_jpege_vepu1_control(void *hal, MpiCmd cmd, void *param) case MPP_ENC_SET_IDR_FRAME: case MPP_ENC_SET_OSD_PLT_CFG: case MPP_ENC_SET_OSD_DATA_CFG: - case MPP_ENC_GET_OSD_CFG: case MPP_ENC_GET_HDR_SYNC: case MPP_ENC_GET_EXTRA_INFO: case MPP_ENC_GET_SEI_DATA: diff --git a/mpp/hal/vpu/jpege/hal_jpege_vepu2.c b/mpp/hal/vpu/jpege/hal_jpege_vepu2.c index 746f9250..3d2f8b2a 100644 --- a/mpp/hal/vpu/jpege/hal_jpege_vepu2.c +++ b/mpp/hal/vpu/jpege/hal_jpege_vepu2.c @@ -538,7 +538,6 @@ MPP_RET hal_jpege_vepu2_control(void *hal, MpiCmd cmd, void *param) case MPP_ENC_SET_IDR_FRAME: case MPP_ENC_SET_OSD_PLT_CFG: case MPP_ENC_SET_OSD_DATA_CFG: - case MPP_ENC_GET_OSD_CFG: case MPP_ENC_GET_HDR_SYNC: case MPP_ENC_GET_EXTRA_INFO: case MPP_ENC_GET_SEI_DATA: diff --git a/mpp/inc/mpp_enc_cfg.h b/mpp/inc/mpp_enc_cfg.h index ae9be40e..e7e75d87 100644 --- a/mpp/inc/mpp_enc_cfg.h +++ b/mpp/inc/mpp_enc_cfg.h @@ -38,8 +38,8 @@ typedef struct MppEncCfgSet_t { MppEncSliceSplit split; MppEncGopRef gop_ref; MppEncROICfg roi; - MppEncOSDData osd_data; - MppEncOSDPlt osd_plt; + MppEncOSDPltCfg plt_cfg; + MppEncOSDPlt plt_data; } MppEncCfgSet; #endif /*__MPP_ENC_H__*/ diff --git a/test/mpi_enc_multi_test.c b/test/mpi_enc_multi_test.c index 059d17bb..bade9359 100644 --- a/test/mpi_enc_multi_test.c +++ b/test/mpi_enc_multi_test.c @@ -31,6 +31,7 @@ #include "mpp_common.h" #include "utils.h" +#include "mpi_enc_utils.h" #include "vpu_api.h" @@ -90,6 +91,7 @@ typedef struct { MppBuffer pkt_buf[MPI_ENC_IO_COUNT]; MppBuffer md_buf[MPI_ENC_IO_COUNT]; MppBuffer osd_idx_buf[MPI_ENC_IO_COUNT]; + MppEncOSDPltCfg osd_plt_cfg; MppEncOSDPlt osd_plt; MppEncOSDData osd_data; MppEncROIRegion roi_region[3]; /* can be more regions */ @@ -136,41 +138,6 @@ static OptionInfo mpi_enc_cmd[] = { {"d", "debug", "debug flag"}, }; -static MPP_RET mpi_enc_gen_osd_data(MppEncOSDData *osd_data, MppBuffer osd_buf, RK_U32 frame_cnt) -{ - RK_U32 k = 0, buf_size = 0; - RK_U8 data = 0; - - osd_data->num_region = 8; - osd_data->buf = osd_buf; - for (k = 0; k < osd_data->num_region; k++) { - osd_data->region[k].enable = 1; - osd_data->region[k].inverse = frame_cnt & 1; - osd_data->region[k].start_mb_x = k * 3; - osd_data->region[k].start_mb_y = k * 2; - osd_data->region[k].num_mb_x = 2; - osd_data->region[k].num_mb_y = 2; - - buf_size = osd_data->region[k].num_mb_x * osd_data->region[k].num_mb_y * 256; - osd_data->region[k].buf_offset = k * buf_size; - - data = k; - memset((RK_U8 *)mpp_buffer_get_ptr(osd_data->buf) + osd_data->region[k].buf_offset, data, buf_size); - } - - return MPP_OK; -} - -static MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 *table) -{ - RK_U32 k = 0; - if (osd_plt->buf) { - for (k = 0; k < 256; k++) - osd_plt->buf[k] = table[k % 8]; - } - return MPP_OK; -} - MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestCmd *cmd) { MpiEncTestData *p = NULL; @@ -546,8 +513,11 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) /* gen and cfg osd plt */ mpi_enc_gen_osd_plt(&p->osd_plt, p->plt_table); + p->osd_plt_cfg.change = MPP_ENC_OSD_PLT_CFG_CHANGE_ALL; + p->osd_plt_cfg.type = MPP_ENC_OSD_PLT_TYPE_USERDEF; + p->osd_plt_cfg.plt = &p->osd_plt; #if MPI_ENC_TEST_SET_OSD - ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt); + ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt_cfg); if (ret) { mpp_err("mpi control enc set osd plt failed ret %d\n", ret); goto RET; diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index 52c61f79..c45167a7 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -30,6 +30,7 @@ #include "mpp_common.h" #include "utils.h" +#include "mpi_enc_utils.h" #define MAX_FILE_NAME_LENGTH 256 @@ -69,10 +70,15 @@ typedef struct { MppEncRcCfg rc_cfg; MppEncCodecCfg codec_cfg; MppEncSliceSplit split_cfg; + MppEncOSDPltCfg osd_plt_cfg; + MppEncOSDPlt osd_plt; + MppEncOSDData osd_data; // input / output MppBuffer frm_buf; MppEncSeiMode sei_mode; + MppEncHeaderMode header_mode; + MppBuffer osd_idx_buf; // paramter for resource malloc RK_U32 width; @@ -87,6 +93,17 @@ typedef struct { size_t frame_size; /* NOTE: packet buffer may overflow */ size_t packet_size; + /* + * osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes). + * for general use, 1/8 Y buffer is enough. + */ + size_t osd_idx_size; + RK_U32 plt_table[8]; + + RK_U32 osd_enable; + RK_U32 osd_mode; + RK_U32 split_mode; + RK_U32 split_arg; // rate control runtime parameter RK_S32 gop; @@ -180,6 +197,21 @@ MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestCmd *cmd) p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4; } break; } + + /* + * osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes). + * for general use, 1/8 Y buffer is enough. + */ + p->osd_idx_size = p->hor_stride * p->ver_stride / 8; + p->plt_table[0] = MPP_ENC_OSD_PLT_RED; + p->plt_table[1] = MPP_ENC_OSD_PLT_YELLOW; + p->plt_table[2] = MPP_ENC_OSD_PLT_BLUE; + p->plt_table[3] = MPP_ENC_OSD_PLT_GREEN; + p->plt_table[4] = MPP_ENC_OSD_PLT_CYAN; + p->plt_table[5] = MPP_ENC_OSD_PLT_TRANS; + p->plt_table[6] = MPP_ENC_OSD_PLT_BLACK; + p->plt_table[7] = MPP_ENC_OSD_PLT_WHITE; + RET: *data = p; return ret; @@ -514,18 +546,18 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) goto RET; } - RK_U32 split_mode = 0; - RK_U32 split_arg = 0; + p->split_mode = 0; + p->split_arg = 0; - mpp_env_get_u32("split_mode", &split_mode, MPP_ENC_SPLIT_NONE); - mpp_env_get_u32("split_arg", &split_arg, 0); + mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE); + mpp_env_get_u32("split_arg", &p->split_arg, 0); - if (split_mode) { + if (p->split_mode) { split_cfg->change = MPP_ENC_SPLIT_CFG_CHANGE_ALL; - split_cfg->split_mode = split_mode; - split_cfg->split_arg = split_arg; + split_cfg->split_mode = p->split_mode; + split_cfg->split_arg = p->split_arg; - mpp_log("split_mode %d split_arg %d\n", split_mode, split_arg); + mpp_log("split_mode %d split_arg %d\n", p->split_mode, p->split_arg); ret = mpi->control(ctx, MPP_ENC_SET_SPLIT, split_cfg); if (ret) { @@ -555,13 +587,42 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) } } + if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) { + p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR; + ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode); + if (ret) { + mpp_err("mpi control enc set header mode failed ret %d\n", ret); + goto RET; + } + } + + p->osd_enable = 0; + p->osd_mode = 0; + + mpp_env_get_u32("osd_enable", &p->osd_enable, 0); + mpp_env_get_u32("osd_mode", &p->osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT); + + if (p->osd_enable) { + /* gen and cfg osd plt */ + mpi_enc_gen_osd_plt(&p->osd_plt, p->plt_table); + p->osd_plt_cfg.change = MPP_ENC_OSD_PLT_CFG_CHANGE_ALL; + p->osd_plt_cfg.type = MPP_ENC_OSD_PLT_TYPE_USERDEF; + p->osd_plt_cfg.plt = &p->osd_plt; + + ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt_cfg); + if (ret) { + mpp_err("mpi control enc set osd plt failed ret %d\n", ret); + goto RET; + } + } + RET: return ret; } MPP_RET test_mpp_run(MpiEncTestData *p) { - MPP_RET ret; + MPP_RET ret = MPP_OK; MppApi *mpi; MppCtx ctx; @@ -646,6 +707,25 @@ MPP_RET test_mpp_run(MpiEncTestData *p) else mpp_frame_set_buffer(frame, p->frm_buf); + MppEncUserData user_data; + char *str = "Hello world hahahaha lalalala\n"; + + { + MppMeta meta = mpp_frame_get_meta(frame); + + if ((p->frame_count & 2) == 0) { + user_data.pdata = str; + user_data.len = strlen(str) + 1; + mpp_meta_set_ptr(meta, KEY_USER_DATA, &user_data); + } + + if (p->osd_enable) { + /* gen and cfg osd plt */ + mpi_enc_gen_osd_data(&p->osd_data, p->osd_idx_buf, p->frame_count); + mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)&p->osd_data); + } + } + /* * NOTE: in non-block mode the frame can be resent. * The default input timeout mode is block. @@ -729,6 +809,12 @@ int mpi_enc_test(MpiEncTestCmd *cmd) goto MPP_TEST_OUT; } + ret = mpp_buffer_get(NULL, &p->osd_idx_buf, p->osd_idx_size); + if (ret) { + mpp_err_f("failed to get buffer for input osd index ret %d\n", ret); + goto MPP_TEST_OUT; + } + mpp_log("mpi_enc_test encoder test start w %d h %d type %d\n", p->width, p->height, p->type); @@ -780,6 +866,11 @@ MPP_TEST_OUT: p->frm_buf = NULL; } + if (p->osd_idx_buf) { + mpp_buffer_put(p->osd_idx_buf); + p->osd_idx_buf = NULL; + } + if (MPP_OK == ret) mpp_log("mpi_enc_test success total frame %d bps %lld\n", p->frame_count, (RK_U64)((p->stream_size * 8 * p->fps) / p->frame_count)); diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index e6d912ae..148eb2e1 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -3,6 +3,7 @@ # add libvpu implement # ---------------------------------------------------------------------------- add_library(utils STATIC + mpi_enc_utils.c utils.c iniparser.c dictionary.c diff --git a/utils/mpi_enc_utils.c b/utils/mpi_enc_utils.c new file mode 100644 index 00000000..6ff113eb --- /dev/null +++ b/utils/mpi_enc_utils.c @@ -0,0 +1,66 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpi_enc_utils" + +#include + +#include "mpp_mem.h" +#include "mpp_log.h" +#include "mpi_enc_utils.h" + +MPP_RET mpi_enc_gen_osd_data(MppEncOSDData *osd_data, MppBuffer osd_buf, RK_U32 frame_cnt) +{ + RK_U32 k = 0; + RK_U32 buf_size = 0; + RK_U32 buf_offset = 0; + RK_U8 *buf = mpp_buffer_get_ptr(osd_buf); + + osd_data->num_region = 8; + osd_data->buf = osd_buf; + + for (k = 0; k < osd_data->num_region; k++) { + MppEncOSDRegion *region = &osd_data->region[k]; + RK_U8 idx = k; + + region->enable = 1; + region->inverse = frame_cnt & 1; + region->start_mb_x = k * 3; + region->start_mb_y = k * 2; + region->num_mb_x = 2; + region->num_mb_y = 2; + + buf_size = region->num_mb_x * region->num_mb_y * 256; + buf_offset = k * buf_size; + osd_data->region[k].buf_offset = buf_offset; + + memset(buf + buf_offset, idx, buf_size); + } + + return MPP_OK; +} + +MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 *table) +{ + RK_U32 k = 0; + + if (osd_plt->data && table) { + for (k = 0; k < 256; k++) + osd_plt->data[k].val = table[k % 8]; + } + return MPP_OK; +} + diff --git a/utils/mpi_enc_utils.h b/utils/mpi_enc_utils.h new file mode 100644 index 00000000..8e7f7e85 --- /dev/null +++ b/utils/mpi_enc_utils.h @@ -0,0 +1,35 @@ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPI_ENC_UTILS_H__ +#define __MPI_ENC_UTILS_H__ + +#include + +#include "rk_venc_cmd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpi_enc_gen_osd_data(MppEncOSDData *osd_data, MppBuffer osd_buf, RK_U32 frame_cnt); +MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 *table); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPI_ENC_UTILS_H__*/