diff --git a/mpp/hal/rkenc/common/vepu541_common.c b/mpp/hal/rkenc/common/vepu541_common.c index 073e4cd8..716d68eb 100644 --- a/mpp/hal/rkenc/common/vepu541_common.c +++ b/mpp/hal/rkenc/common/vepu541_common.c @@ -413,8 +413,14 @@ DONE: return ret; } -//TODO: open interface later +/* + * Invert color threshold is for the absolute difference between background + * and foregroud color. + * If background color and foregroud color are close enough then trigger the + * invert color process. + */ #define ENC_DEFAULT_OSD_INV_THR 15 + #define VEPU541_OSD_ADDR_IDX_BASE 124 #define VEPU541_OSD_CFG_OFFSET 0x01C0 #define VEPU541_OSD_PLT_OFFSET 0x0400 @@ -568,7 +574,7 @@ MPP_RET vepu541_set_osd(Vepu541OsdCfg *cfg) /* There should be enough buffer and offset should be 16B aligned */ if (buf_size < tmp->buf_offset + blk_len || (tmp->buf_offset & 0xf)) { - mpp_err_f("invalid osd cfg: %d x:y:w:h:off %d:%d:%d:%x\n", + mpp_err_f("invalid osd cfg: %d x:y:w:h:off %d:%d:%d:%d:%x\n", k, tmp->start_mb_x, tmp->start_mb_y, tmp->num_mb_x, tmp->num_mb_y, tmp->buf_offset); } @@ -726,6 +732,8 @@ MPP_RET vepu540_set_osd(Vepu541OsdCfg *cfg) regs->reg112.osd_e = 0; regs->reg112.osd_lu_inv_en = 0; + regs->reg094.osd_ch_inv_en = 0; + regs->reg094.osd_lu_inv_msk = 0; if (NULL == osd || osd->num_region == 0 || NULL == osd->buf) return MPP_OK; @@ -751,7 +759,8 @@ MPP_RET vepu540_set_osd(Vepu541OsdCfg *cfg) for (k = 0; k < num; k++, tmp++) { regs->reg112.osd_e |= tmp->enable << k; - regs->reg112.osd_lu_inv_en |= tmp->inverse << k; + regs->reg112.osd_lu_inv_en |= (tmp->inverse) ? (1 << k) : 0; + regs->reg094.osd_ch_inv_en |= (tmp->inverse) ? (1 << k) : 0; if (tmp->enable && tmp->num_mb_x && tmp->num_mb_y) { Vepu541OsdPos *pos = ®s->osd_pos[k]; @@ -775,9 +784,9 @@ MPP_RET vepu540_set_osd(Vepu541OsdCfg *cfg) /* There should be enough buffer and offset should be 16B aligned */ if (buf_size < tmp->buf_offset + blk_len || (tmp->buf_offset & 0xf)) { - mpp_err_f("invalid osd cfg: %d x:y:w:h:off %d:%d:%d:%x\n", + mpp_err_f("invalid osd cfg: %d x:y:w:h:off %d:%d:%d:%d:%x size %x\n", k, tmp->start_mb_x, tmp->start_mb_y, - tmp->num_mb_x, tmp->num_mb_y, tmp->buf_offset); + tmp->num_mb_x, tmp->num_mb_y, tmp->buf_offset, buf_size); } } } diff --git a/test/mpi_enc_multi_test.c b/test/mpi_enc_multi_test.c index b8d40684..5c2f4648 100644 --- a/test/mpi_enc_multi_test.c +++ b/test/mpi_enc_multi_test.c @@ -40,8 +40,6 @@ #define MAX_FILE_NAME_LENGTH 256 #define MPI_ENC_TEST_SET_IDR_FRAME 0 -#define MPI_ENC_TEST_SET_OSD 1 -#define MPI_ENC_TEST_SET_ROI 1 typedef struct { char file_input[MAX_FILE_NAME_LENGTH]; @@ -85,17 +83,12 @@ typedef struct { // input / output MppBufferGroup frm_grp; MppBufferGroup pkt_grp; + MppBufferGroup buf_grp; MppFrame frame; MppPacket packet; MppBuffer frm_buf[MPI_ENC_IO_COUNT]; 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 */ - MppEncROICfg roi_cfg; MppEncSeiMode sei_mode; // paramter for resource malloc @@ -244,6 +237,12 @@ MPP_RET test_res_init(MpiEncTestData *p) goto RET; } + ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_ION); + if (ret) { + mpp_err("failed to get buffer group for output packet ret %d\n", ret); + goto RET; + } + for (i = 0; i < MPI_ENC_IO_COUNT; i++) { ret = mpp_buffer_get(p->frm_grp, &p->frm_buf[i], p->frame_size); if (ret) { @@ -251,12 +250,6 @@ MPP_RET test_res_init(MpiEncTestData *p) goto RET; } - ret = mpp_buffer_get(p->frm_grp, &p->osd_idx_buf[i], p->osd_idx_size); - if (ret) { - mpp_err("failed to get buffer for osd idx buf ret %d\n", ret); - goto RET; - } - ret = mpp_buffer_get(p->pkt_grp, &p->pkt_buf[i], p->packet_size); if (ret) { mpp_err("failed to get buffer for input frame ret %d\n", ret); @@ -294,11 +287,6 @@ MPP_RET test_res_deinit(MpiEncTestData *p) mpp_buffer_put(p->md_buf[i]); p->md_buf[i] = NULL; } - - if (p->osd_idx_buf[i]) { - mpp_buffer_put(p->osd_idx_buf[i]); - p->osd_idx_buf[i] = NULL; - } } if (p->frm_grp) { @@ -311,6 +299,11 @@ MPP_RET test_res_deinit(MpiEncTestData *p) p->pkt_grp = NULL; } + if (p->buf_grp) { + mpp_buffer_group_put(p->pkt_grp); + p->buf_grp = NULL; + } + return MPP_OK; } @@ -500,19 +493,6 @@ MPP_RET test_mpp_setup(MpiEncTestData *p) goto RET; } - /* 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_cfg); - if (ret) { - mpp_err("mpi control enc set osd plt failed ret %d\n", ret); - goto RET; - } -#endif - RET: return ret; } @@ -587,8 +567,6 @@ MPP_RET test_mpp_run(MpiEncTestData *p) MppBuffer frm_buf_in = p->frm_buf[index]; MppBuffer pkt_buf_out = p->pkt_buf[index]; MppBuffer md_info_buf = p->md_buf[index]; - MppBuffer osd_data_buf = p->osd_idx_buf[index]; - MppMeta meta = mpp_frame_get_meta(p->frame); void *buf = mpp_buffer_get_ptr(frm_buf_in); @@ -643,43 +621,6 @@ MPP_RET test_mpp_run(MpiEncTestData *p) } #endif -#if MPI_ENC_TEST_SET_OSD - /* gen and cfg osd plt */ - mpi_enc_gen_osd_data(&p->osd_data, osd_data_buf, p->frame_count); - mpp_log("meta %p osd %p", meta, &p->osd_data); - mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)&p->osd_data); -#endif - -#if MPI_ENC_TEST_SET_ROI - if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) { - MppEncROIRegion *region = p->roi_region; - - /* 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->abs_qp_en = 1; - region->area_map_en = 0; - region->qp_area_idx = 0; - - 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 = 10; /* qp of macroblock */ - region->abs_qp_en = 0; - region->area_map_en = 1; - region->qp_area_idx = 1; - - p->roi_cfg.number = 2; - p->roi_cfg.regions = p->roi_region; - - mpp_log("meta %p roi %p", meta, p->roi_region); - mpp_meta_set_ptr(meta, KEY_ROI_DATA, (void*)&p->roi_cfg); // new way for roi - } -#endif - ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task); if (ret) { mpp_err("mpp task input enqueue failed\n"); diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index e72078c4..4e7b45b8 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -64,7 +64,6 @@ typedef struct { MppBuffer pkt_buf; MppEncSeiMode sei_mode; MppEncHeaderMode header_mode; - MppBuffer osd_idx_buf; // paramter for resource malloc RK_U32 width; @@ -82,12 +81,6 @@ 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; @@ -216,20 +209,6 @@ MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd) else p->header_size = 0; - /* - * 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; @@ -455,21 +434,6 @@ MPP_RET test_mpp_enc_cfg_setup(MpiEncTestData *p) /* setup test mode by env */ 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; - } - } - mpp_env_get_u32("roi_enable", &p->roi_enable, 0); mpp_env_get_u32("user_data_enable", &p->user_data_enable, 0); @@ -624,7 +588,21 @@ MPP_RET test_mpp_run(MpiEncTestData *p) if (p->osd_enable) { /* gen and cfg osd plt */ - mpi_enc_gen_osd_data(&p->osd_data, p->osd_idx_buf, p->frame_count); + mpi_enc_gen_osd_plt(&p->osd_plt, p->frame_count); + + 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; + } + + /* gen and cfg osd plt */ + mpi_enc_gen_osd_data(&p->osd_data, p->buf_grp, p->width, + p->height, p->frame_count); mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)&p->osd_data); } @@ -772,12 +750,6 @@ int mpi_enc_test(MpiEncTestArgs *cmd) goto MPP_TEST_OUT; } - ret = mpp_buffer_get(p->buf_grp, &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; - } - // encoder demo ret = mpp_create(&p->ctx, &p->mpi); if (ret) { @@ -852,9 +824,9 @@ MPP_TEST_OUT: p->pkt_buf = NULL; } - if (p->osd_idx_buf) { - mpp_buffer_put(p->osd_idx_buf); - p->osd_idx_buf = NULL; + if (p->osd_data.buf) { + mpp_buffer_put(p->osd_data.buf); + p->osd_data.buf = NULL; } if (p->buf_grp) { diff --git a/utils/mpi_enc_utils.c b/utils/mpi_enc_utils.c index 4a411fc3..31f358d4 100644 --- a/utils/mpi_enc_utils.c +++ b/utils/mpi_enc_utils.c @@ -20,6 +20,7 @@ #include "mpp_mem.h" #include "mpp_log.h" +#include "mpp_buffer.h" #include "rk_mpi.h" #include "utils.h" @@ -597,45 +598,109 @@ MPP_RET mpi_enc_gen_smart_gop_ref_cfg(MppEncRefCfg ref, RK_S32 gop_len, RK_S32 v return ret; } -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 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 idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes). + * for general use, 1/8 Y buffer is enough. + */ + static RK_U32 plt_table[8] = { + MPP_ENC_OSD_PLT_RED, + MPP_ENC_OSD_PLT_YELLOW, + MPP_ENC_OSD_PLT_BLUE, + MPP_ENC_OSD_PLT_GREEN, + MPP_ENC_OSD_PLT_CYAN, + MPP_ENC_OSD_PLT_TRANS, + MPP_ENC_OSD_PLT_BLACK, + MPP_ENC_OSD_PLT_WHITE, + }; - osd_data->num_region = 8; - osd_data->buf = osd_buf; + if (osd_plt) { + RK_U32 k = 0; + RK_U32 base = frame_cnt & 7; - 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); + for (k = 0; k < 256; k++) + osd_plt->data[k].val = plt_table[(base + k) % 8]; } - return MPP_OK; } -MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 *table) -{ - RK_U32 k = 0; +#define STEP_X 3 +#define STEP_Y 2 +#define STEP_W 2 +#define STEP_H 2 - if (osd_plt->data && table) { - for (k = 0; k < 256; k++) - osd_plt->data[k].val = table[k % 8]; +MPP_RET mpi_enc_gen_osd_data(MppEncOSDData *osd_data, MppBufferGroup group, + RK_U32 width, RK_U32 height, RK_U32 frame_cnt) +{ + MppEncOSDRegion *region = NULL; + RK_U32 k = 0; + RK_U32 num_region = 8; + RK_U32 buf_offset = 0; + RK_U32 buf_size = 0; + RK_U32 mb_w_max = MPP_ALIGN(width, 16) / 16; + RK_U32 mb_h_max = MPP_ALIGN(height, 16) / 16; + RK_U32 mb_x = (frame_cnt * STEP_X) % mb_w_max; + RK_U32 mb_y = (frame_cnt * STEP_Y) % mb_h_max; + RK_U32 mb_w = STEP_W; + RK_U32 mb_h = STEP_H; + MppBuffer buf = osd_data->buf; + + if (buf) + buf_size = mpp_buffer_get_size(buf); + + /* generate osd region info */ + osd_data->num_region = num_region; + + region = osd_data->region; + + for (k = 0; k < num_region; k++, region++) { + // NOTE: offset must be 16 byte aligned + RK_U32 region_size = MPP_ALIGN(mb_w * mb_h * 256, 16); + + region->inverse = 1; + region->start_mb_x = mb_x; + region->start_mb_y = mb_y; + region->num_mb_x = mb_w; + region->num_mb_y = mb_h; + region->buf_offset = buf_offset; + region->enable = (mb_w && mb_h); + + buf_offset += region_size; + + mb_x += STEP_X; + mb_y += STEP_Y; + if (mb_x >= mb_w_max) + mb_x -= mb_w_max; + if (mb_y >= mb_h_max) + mb_y -= mb_h_max; } + + /* create buffer and write osd index data */ + if (buf_size < buf_offset) { + if (buf) + mpp_buffer_put(buf); + + mpp_buffer_get(group, &buf, buf_offset); + if (NULL == buf) + mpp_err_f("failed to create osd buffer size %d\n", buf_offset); + } + + if (buf) { + void *ptr = mpp_buffer_get_ptr(buf); + region = osd_data->region; + + for (k = 0; k < num_region; k++, region++) { + mb_w = region->num_mb_x; + mb_h = region->num_mb_y; + buf_offset = region->buf_offset; + + memset(ptr + buf_offset, k, mb_w * mb_h * 256); + } + } + + osd_data->buf = buf; + return MPP_OK; } diff --git a/utils/mpi_enc_utils.h b/utils/mpi_enc_utils.h index 3336392f..84108b3b 100644 --- a/utils/mpi_enc_utils.h +++ b/utils/mpi_enc_utils.h @@ -73,8 +73,9 @@ RK_S32 mpi_enc_width_default_stride(RK_S32 width, MppFrameFormat fmt); */ MPP_RET mpi_enc_gen_ref_cfg(MppEncRefCfg ref, RK_S32 gop_mode); MPP_RET mpi_enc_gen_smart_gop_ref_cfg(MppEncRefCfg ref, RK_S32 gop_len, RK_S32 vi_len); -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); +MPP_RET mpi_enc_gen_osd_data(MppEncOSDData *osd_data, MppBufferGroup group, + RK_U32 width, RK_U32 height, RK_U32 frame_cnt); +MPP_RET mpi_enc_gen_osd_plt(MppEncOSDPlt *osd_plt, RK_U32 frame_cnt); MpiEncTestArgs *mpi_enc_test_cmd_get(void); MPP_RET mpi_enc_test_cmd_update_by_args(MpiEncTestArgs* cmd, int argc, char **argv);