diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 9d92000c..1187d368 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -45,6 +45,12 @@ #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 MppEncSeiMode_t { + MPP_ENC_SEI_MODE_DISABLE, /* default mode, SEI writing is disabled */ + MPP_ENC_SEI_MODE_ONE_SEQ, /* one sequence has only one SEI */ + MPP_ENC_SEI_MODE_ONE_FRAME /* one frame may have one SEI, if SEI info has changed */ +} MppEncSeiMode; + typedef enum { MPP_OSAL_CMD_BASE = CMD_MODULE_OSAL, MPP_OSAL_CMD_END, @@ -86,6 +92,8 @@ typedef enum { MPP_ENC_GET_EXTRA_INFO, MPP_ENC_SET_FORMAT, MPP_ENC_SET_IDR_FRAME, + MPP_ENC_SET_SEI_CFG, /*SEI: Supplement Enhancemant Information, parameter is MppSeiMode */ + MPP_ENC_GET_SEI_DATA, /*SEI: Supplement Enhancemant Information, parameter is MppPacket */ MPP_ENC_CMD_END, MPP_ISP_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ISP, diff --git a/mpp/codec/mpp_enc.cpp b/mpp/codec/mpp_enc.cpp index e957921c..621035b6 100644 --- a/mpp/codec/mpp_enc.cpp +++ b/mpp/codec/mpp_enc.cpp @@ -420,19 +420,13 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param) *mpp_cfg = enc->mpp_cfg; ret = MPP_OK; } break; - case MPP_ENC_GET_EXTRA_INFO : { - ret = mpp_hal_control(enc->hal, cmd, param); - } break; - case MPP_ENC_SET_RC_CFG : { - ret = mpp_hal_control(enc->hal, cmd, param); - } break; - case MPP_ENC_GET_RC_CFG : { - ret = mpp_hal_control(enc->hal, cmd, param); - } break; - case MPP_ENC_SET_OSD_PLT_CFG : { - ret = mpp_hal_control(enc->hal, cmd, param); - } break; - case MPP_ENC_SET_OSD_DATA_CFG : { + case MPP_ENC_GET_EXTRA_INFO : + case MPP_ENC_SET_RC_CFG : + case MPP_ENC_GET_RC_CFG : + case MPP_ENC_SET_OSD_PLT_CFG : + case MPP_ENC_SET_OSD_DATA_CFG : + case MPP_ENC_SET_SEI_CFG : + case MPP_ENC_GET_SEI_DATA : { ret = mpp_hal_control(enc->hal, cmd, param); } break; default : { diff --git a/mpp/hal/rkenc/h264e/hal_h264e.h b/mpp/hal/rkenc/h264e/hal_h264e.h index 27804f2d..44f3987c 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e.h +++ b/mpp/hal/rkenc/h264e/hal_h264e.h @@ -34,6 +34,7 @@ extern RK_U32 h264e_hal_log_mode; #define H264E_HAL_LOG_DPB 0x00001000 #define H264E_HAL_LOG_HEADER 0x00002000 +#define H264E_HAL_LOG_SEI 0x00004000 #define H264E_HAL_LOG_DETAIL 0x00010000 @@ -87,6 +88,12 @@ extern RK_U32 h264e_hal_log_mode; { mpp_log(fmt, ## __VA_ARGS__); }\ } while (0) +#define h264e_hal_log_sei(fmt, ...) \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_SEI)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ + } while (0) + #define h264e_hal_log_simple(fmt, ...) \ do {\ if (h264e_hal_log_mode & H264E_HAL_LOG_SIMPLE)\ @@ -133,9 +140,18 @@ extern RK_U32 h264e_hal_log_mode; } \ } while (0) +#define H264E_HAL_SPRINT(s, ...) \ + do { \ + s += sprintf(s, ## __VA_ARGS__); \ + } while (0) -#define H264E_REF_MAX 16 -#define H264E_MAX_PACKETED_PARAM_SIZE 256 //sps + pps +#define H264E_UUID_LENGTH 16 + +#define H264E_REF_MAX 16 + +#define H264E_SPSPPS_BUF_SIZE 512 //sps + pps +#define H264E_SEI_BUF_SIZE 1024 //unit in byte, may not be large enough in the future +#define H264E_EXTRA_INFO_BUF_SIZE (H264E_SPSPPS_BUF_SIZE + H264E_SEI_BUF_SIZE) typedef enum h264e_hal_slice_type_t { H264E_HAL_SLICE_TYPE_P = 0, @@ -272,9 +288,22 @@ typedef struct h264e_hal_pps_t { const RK_U8 *scaling_list[8]; /* could be 12, but we don't allow separate Cb/Cr lists */ } h264e_hal_pps; +typedef enum h264e_sei_payload_type_t { + H264E_SEI_BUFFERING_PERIOD = 0, + H264E_SEI_PIC_TIMING = 1, + H264E_SEI_PAN_SCAN_RECT = 2, + H264E_SEI_FILLER = 3, + H264E_SEI_USER_DATA_REGISTERED = 4, + H264E_SEI_USER_DATA_UNREGISTERED = 5, + H264E_SEI_RECOVERY_POINT = 6, + H264E_SEI_DEC_REF_PIC_MARKING = 7, + H264E_SEI_FRAME_PACKING = 45, +} h264e_sei_payload_type; + typedef enum h264e_rkv_nal_idx_t { RKV_H264E_RKV_NAL_IDX_SPS, RKV_H264E_RKV_NAL_IDX_PPS, + RKV_H264E_RKV_NAL_IDX_SEI, RKV_H264E_RKV_NAL_IDX_BUTT, } h264e_rkv_nal_idx; @@ -316,6 +345,12 @@ typedef struct h264e_hal_vui_param_t { RK_S32 i_chroma_loc; /* both top & bottom */ } h264e_hal_vui_param; +typedef struct h264e_hal_sei_t { + RK_U32 frame_cnt; + h264e_control_extra_info_cfg extra_info_cfg; + MppEncRcCfg rc_cfg; +} h264e_hal_sei; + typedef struct h264e_hal_ref_param_t { RK_S32 i_frame_reference; /* Maximum number of reference frames */ RK_S32 i_ref_pos; @@ -357,13 +392,12 @@ typedef struct h264e_hal_context_t { void *dump_files; void *param_buf; - size_t param_size; MppPacket packeted_param; void *test_cfg; - h264e_control_extra_info_cfg extra_info_cfg; RK_U32 osd_plt_type; //0:user define, 1:default MppEncOSDData osd_data; + MppEncSeiMode sei_mode; } h264e_hal_context; #endif diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c index ffc7326d..bcd98bce 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c @@ -1805,12 +1805,11 @@ RK_S32 hal_h264e_rkv_stream_get_pos(h264e_hal_rkv_stream *s) MPP_RET hal_h264e_rkv_stream_init(h264e_hal_rkv_stream *s) { RK_S32 offset = 0; - RK_U8 *p_buf = NULL; - s->buf = mpp_calloc(RK_U8, 512); //SPS+PPS - p_buf = s->buf + 8; //NOTE + s->buf = mpp_calloc(RK_U8, H264E_EXTRA_INFO_BUF_SIZE); + s->buf_plus8 = s->buf + 8; //NOTE: prepare for align - offset = (size_t)(p_buf) & 3; - s->p = s->p_start = p_buf - offset; + offset = (size_t)(s->buf_plus8) & 3; + s->p = s->p_start = s->buf_plus8 - offset; //s->p_end = (RK_U8*)s->buf + i_data; s->i_left = (4 - offset) * 8; //s->cur_bits = endian_fix32(M32(s->p)); @@ -1825,18 +1824,15 @@ MPP_RET hal_h264e_rkv_stream_init(h264e_hal_rkv_stream *s) MPP_RET hal_h264e_rkv_stream_reset(h264e_hal_rkv_stream *s) { RK_S32 offset = 0; - RK_U8 *p_buf = NULL; - p_buf = s->buf + 8; //NOTE h264e_hal_debug_enter(); - offset = (size_t)(p_buf) & 3; - s->p = s->p_start = p_buf - offset; - //s->p_end = (RK_U8*)s->buf + i_data; + offset = (size_t)(s->buf_plus8) & 3; + s->p = s->p_start; s->i_left = (4 - offset) * 8; - //s->cur_bits = endian_fix32(M32(s->p)); s->cur_bits = (*(s->p) << 24) + (*(s->p + 1) << 16) + (*(s->p + 2) << 8) + (*(s->p + 3) << 0); s->cur_bits >>= (4 - offset) * 8; s->count_bit = 0; + h264e_hal_debug_leave(); return MPP_OK; } @@ -2003,7 +1999,7 @@ MPP_RET hal_h264e_rkv_stream_flush(h264e_hal_rkv_stream *s) void hal_h264e_rkv_nals_init(h264e_hal_rkv_extra_info *out) { - out->nal_buf = mpp_calloc(RK_U8, 512); + out->nal_buf = mpp_calloc(RK_U8, H264E_EXTRA_INFO_BUF_SIZE); out->nal_num = 0; } @@ -2017,30 +2013,27 @@ void hal_h264e_rkv_nals_deinit(h264e_hal_rkv_extra_info *out) void hal_h264e_rkv_nal_start(h264e_hal_rkv_extra_info *out, RK_S32 i_type, RK_S32 i_ref_idc) { h264e_hal_rkv_stream *s = &out->stream; - RK_U8 *stream_buf = s->p_start; - out->nal[out->nal_num].i_ref_idc = i_ref_idc; - out->nal[out->nal_num].i_type = i_type; - out->nal[out->nal_num].b_long_startcode = 1; + h264e_hal_rkv_nal *nal = &out->nal[out->nal_num]; - out->nal[out->nal_num].i_payload = 0; - out->nal[out->nal_num].p_payload = &stream_buf[hal_h264e_rkv_stream_get_pos(s) / 8]; - out->nal[out->nal_num].i_padding = 0; + nal->i_ref_idc = i_ref_idc; + nal->i_type = i_type; + nal->b_long_startcode = 1; + + nal->i_payload = 0; + nal->p_payload = &s->buf_plus8[hal_h264e_rkv_stream_get_pos(s) / 8]; ////NOTE: consistent with stream_init + nal->i_padding = 0; } void hal_h264e_rkv_nal_end(h264e_hal_rkv_extra_info *out) { h264e_hal_rkv_nal *nal = &(out->nal[out->nal_num]); h264e_hal_rkv_stream *s = &out->stream; - RK_U8 *stream_buf = s->p_start; - RK_U8 *end = &stream_buf[hal_h264e_rkv_stream_get_pos(s) / 8]; + RK_U8 *end = &s->buf_plus8[hal_h264e_rkv_stream_get_pos(s) / 8]; //NOTE: consistent with stream_init nal->i_payload = (RK_S32)(end - nal->p_payload); /* Assembly implementation of nal_escape reads past the end of the input. * While undefined padding wouldn't actually affect the output, it makes valgrind unhappy. */ memset(end, 0xff, 64); - //if (h->param.nalu_process) - // h->param.nalu_process(h, nal, h->fenc->opaque); out->nal_num++; - //return x264_nal_check_buffer(h); } RK_U8 *hal_h264e_rkv_nal_escape_c(RK_U8 *dst, RK_U8 *src, RK_U8 *end) @@ -2129,7 +2122,100 @@ MPP_RET hal_h264e_rkv_encapsulate_nals(h264e_hal_rkv_extra_info *out) return MPP_OK; } +static MPP_RET hal_h264e_rkv_sei_pack2str(char *str, h264e_hal_rkv_extra_info *extra_info) +{ + h264e_hal_sei *sei = &extra_info->sei; + h264e_control_extra_info_cfg *extra_info_cfg = &sei->extra_info_cfg; + MppEncRcCfg *rc_cfg = &sei->rc_cfg; + h264e_hal_debug_enter(); + H264E_HAL_SPRINT(str, "frame %d rkvenc_cfg: ", sei->frame_cnt); + + if (extra_info->sei_change_flg & H264E_SEI_CHG_SPSPPS) { + h264e_hal_log_sei("write sei extra_info_cfg"); + H264E_HAL_SPRINT(str, "extra_info: "); + H264E_HAL_SPRINT(str, "pic_w %d ", extra_info_cfg->pic_luma_width); + H264E_HAL_SPRINT(str, "pic_h %d ", extra_info_cfg->pic_luma_height); + H264E_HAL_SPRINT(str, "en_cabac %d ", extra_info_cfg->enable_cabac); + H264E_HAL_SPRINT(str, "t8x8 %d ", extra_info_cfg->transform8x8_mode); + H264E_HAL_SPRINT(str, "cb_qp_ofst %d ", extra_info_cfg->chroma_qp_index_offset); + H264E_HAL_SPRINT(str, "pic_init_qp %d ", extra_info_cfg->pic_init_qp); + H264E_HAL_SPRINT(str, "fps %d ", extra_info_cfg->frame_rate); + H264E_HAL_SPRINT(str, "src_fmt %d ", extra_info_cfg->input_image_format); + H264E_HAL_SPRINT(str, "profile %d ", extra_info_cfg->profile_idc); + H264E_HAL_SPRINT(str, "level %d ", extra_info_cfg->level_idc); + H264E_HAL_SPRINT(str, "key_interval %d ", extra_info_cfg->keyframe_max_interval); + H264E_HAL_SPRINT(str, "cr_qp_ofst %d ", extra_info_cfg->second_chroma_qp_index_offset); + H264E_HAL_SPRINT(str, "pps_id %d ", extra_info_cfg->pps_id); + extra_info->sei_change_flg &= ~H264E_SEI_CHG_SPSPPS; + } + + if (extra_info->sei_change_flg & H264E_SEI_CHG_RC) { + h264e_hal_log_sei("write sei rc_cfg"); + H264E_HAL_SPRINT(str, "rc: "); + H264E_HAL_SPRINT(str, "mode %d ", rc_cfg->rc_mode); + H264E_HAL_SPRINT(str, "qlt %d ", rc_cfg->quality); + H264E_HAL_SPRINT(str, "bps_tgt %d ", rc_cfg->bps_target); + H264E_HAL_SPRINT(str, "bps_max %d ", rc_cfg->bps_max); + H264E_HAL_SPRINT(str, "bps_min %d ", rc_cfg->bps_min); + H264E_HAL_SPRINT(str, "fps_in %d ", rc_cfg->fps_in); + H264E_HAL_SPRINT(str, "fps_out %d ", rc_cfg->fps_out); + H264E_HAL_SPRINT(str, "gop %d ", rc_cfg->gop); + H264E_HAL_SPRINT(str, "skip_cnt %d ", rc_cfg->skip_cnt); + extra_info->sei_change_flg &= ~H264E_SEI_CHG_RC; + } + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static MPP_RET hal_h264e_rkv_sei_write(h264e_hal_rkv_stream *s, RK_U8 *payload, RK_S32 payload_size, RK_S32 payload_type) +{ + RK_S32 i = 0; + + h264e_hal_debug_enter(); + + s->count_bit = 0; + hal_h264e_rkv_stream_realign(s); + + for (i = 0; i <= payload_type - 255; i += 255) + hal_h264e_rkv_stream_write_with_log(s, 8, 0xff, "sei_payload_type_ff_byte"); + hal_h264e_rkv_stream_write_with_log(s, 8, payload_type - i, "sei_last_payload_type_byte"); + + for (i = 0; i <= payload_size - 255; i += 255) + hal_h264e_rkv_stream_write_with_log(s, 8, 0xff, "sei_payload_size_ff_byte"); + hal_h264e_rkv_stream_write_with_log( s, 8, payload_size - i , "sei_last_payload_size_byte"); + + for (i = 0; i < payload_size; i++) + hal_h264e_rkv_stream_write_with_log(s, 8, (RK_U32)payload[i], "sei_payload_data"); + + hal_h264e_rkv_stream_rbsp_trailing(s); + hal_h264e_rkv_stream_flush(s); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_sei_encode(h264e_hal_rkv_extra_info *info) +{ + char *str = (char *)info->sei_buf; + RK_S32 str_len = 0; + + hal_h264e_rkv_sei_pack2str(str + H264E_UUID_LENGTH, info); + + str_len = strlen(str) + 1; + if (str_len > H264E_SEI_BUF_SIZE) { + h264e_hal_log_err("SEI actual string length %d exceed malloced size %d", str_len, H264E_SEI_BUF_SIZE); + return MPP_NOK; + } else { + hal_h264e_rkv_sei_write(&info->stream, (RK_U8 *)str, str_len, H264E_SEI_USER_DATA_UNREGISTERED); + } + + + return MPP_OK; +} MPP_RET hal_h264e_rkv_sps_write(h264e_hal_sps *sps, h264e_hal_rkv_stream *s) { @@ -2456,9 +2542,21 @@ MPP_RET hal_h264e_rkv_pps_write(h264e_hal_pps *pps, h264e_hal_sps *sps, h264e_ha static MPP_RET hal_h264e_rkv_init_extra_info(h264e_hal_rkv_extra_info *extra_info) { + // random ID number generated according to ISO-11578 + // NOTE: any element of h264e_sei_uuid should NOT be 0x00, + // otherwise the string length of sei_buf will always be the distance between the + // element 0x00 address and the sei_buf start address. + static const RK_U8 h264e_sei_uuid[H264E_UUID_LENGTH] = { + 0x63, 0xfc, 0x6a, 0x3c, 0xd8, 0x5c, 0x44, 0x1e, + 0x87, 0xfb, 0x3f, 0xab, 0xec, 0xb3, 0xb6, 0x77 + }; + hal_h264e_rkv_nals_init(extra_info); hal_h264e_rkv_stream_init(&extra_info->stream); + extra_info->sei_buf = mpp_calloc_size(RK_U8, H264E_SEI_BUF_SIZE); + memcpy(extra_info->sei_buf, h264e_sei_uuid, H264E_UUID_LENGTH); + return MPP_OK; } @@ -2468,6 +2566,8 @@ static MPP_RET hal_h264e_rkv_deinit_extra_info(void *extra_info) hal_h264e_rkv_stream_deinit(&info->stream); hal_h264e_rkv_nals_deinit(info); + MPP_FREE(info->sei_buf); + return MPP_OK; } @@ -2476,13 +2576,15 @@ static MPP_RET hal_h264e_rkv_set_extra_info(h264e_hal_context *ctx, void *param) h264e_control_extra_info_cfg *cfg = (h264e_control_extra_info_cfg *)param; h264e_hal_param *par = &ctx->param; h264e_hal_rkv_extra_info *info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_hal_sei *sei = &info->sei; h264e_hal_sps *sps_info = &info->sps; h264e_hal_pps *pps_info = &info->pps; h264e_hal_debug_enter(); hal_h264e_rkv_dump_mpp_extra_info_cfg(ctx, cfg); - ctx->extra_info_cfg = *cfg; + sei->extra_info_cfg = *cfg; + info->nal_num = 0; hal_h264e_rkv_stream_reset(&info->stream); @@ -2496,6 +2598,13 @@ static MPP_RET hal_h264e_rkv_set_extra_info(h264e_hal_context *ctx, void *param) hal_h264e_rkv_pps_write(pps_info, sps_info, &info->stream); hal_h264e_rkv_nal_end(info); + if (ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_SEQ || ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_FRAME) { + info->sei_change_flg |= H264E_SEI_CHG_SPSPPS; + hal_h264e_rkv_nal_start(info, RKVENC_NAL_SEI, RKVENC_NAL_PRIORITY_DISPOSABLE); + hal_h264e_rkv_sei_encode(info); + hal_h264e_rkv_nal_end(info); + } + hal_h264e_rkv_encapsulate_nals(info); h264e_hal_debug_leave(); @@ -2503,6 +2612,24 @@ static MPP_RET hal_h264e_rkv_set_extra_info(h264e_hal_context *ctx, void *param) return MPP_OK; } +static MPP_RET hal_h264e_rkv_get_extra_info(h264e_hal_context *ctx, MppPacket *pkt_out) +{ + RK_S32 k = 0; + size_t offset = 0; + MppPacket pkt = ctx->packeted_param; + h264e_hal_rkv_extra_info *src = (h264e_hal_rkv_extra_info *)ctx->extra_info; + + for (k = 0; k < src->nal_num; k++) { + h264e_hal_log_header("get extra info nal type %d, size %d bytes", src->nal[k].i_type, src->nal[k].i_payload); + mpp_packet_write(pkt, offset, src->nal[k].p_payload, src->nal[k].i_payload); + offset += src->nal[k].i_payload; + } + mpp_packet_set_length(pkt, offset); + *pkt_out = pkt; + + return MPP_OK; +} + static MPP_RET hal_h264e_rkv_set_osd_plt(h264e_hal_context *ctx, void *param) { MppEncOSDPlt *plt = (MppEncOSDPlt *)param; @@ -2593,9 +2720,8 @@ MPP_RET hal_h264e_rkv_init(void *hal, MppHalCfg *cfg) ctx->extra_info = mpp_calloc(h264e_hal_rkv_extra_info, 1); ctx->dpb_ctx = mpp_calloc(h264e_hal_rkv_dpb_ctx, 1); ctx->dump_files = mpp_calloc(h264e_hal_rkv_dump_files, 1); - ctx->param_size = H264E_MAX_PACKETED_PARAM_SIZE; - ctx->param_buf = mpp_calloc_size(void, ctx->param_size); - mpp_packet_init(&ctx->packeted_param, ctx->param_buf, ctx->param_size); + ctx->param_buf = mpp_calloc_size(void, H264E_EXTRA_INFO_BUF_SIZE); + mpp_packet_init(&ctx->packeted_param, ctx->param_buf, H264E_EXTRA_INFO_BUF_SIZE); hal_h264e_rkv_open_dump_files(ctx->dump_files); hal_h264e_rkv_init_extra_info(ctx->extra_info); hal_h264e_rkv_reference_init(ctx->dpb_ctx, &ctx->param); @@ -2645,6 +2771,7 @@ MPP_RET hal_h264e_rkv_deinit(void *hal) MPP_FREE(ctx->regs); MPP_FREE(ctx->ioctl_input); MPP_FREE(ctx->ioctl_output); + MPP_FREE(ctx->param_buf); if (ctx->buffers) { hal_h264e_rkv_free_buffers(ctx); @@ -2661,10 +2788,6 @@ MPP_RET hal_h264e_rkv_deinit(void *hal) ctx->packeted_param = NULL; } - MPP_FREE(ctx->param_buf); - - ctx->param_size = 0; - if (ctx->dpb_ctx) { hal_h264e_rkv_reference_deinit(ctx->dpb_ctx); MPP_FREE(ctx->dpb_ctx); @@ -2791,7 +2914,8 @@ MPP_RET hal_h264e_rkv_set_rc_regs(h264e_hal_context *ctx, h264e_rkv_reg_set *reg regs->swreg55.ctu_ebits = mb_target_size; //sw_ctu_target_bits; } else { - h264e_control_extra_info_cfg *extra_info_cfg = &ctx->extra_info_cfg; + h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_control_extra_info_cfg *extra_info_cfg = &extra_info->sei.extra_info_cfg; RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); RK_U32 frame_target_bitrate = (syn->pic_luma_width * syn->pic_luma_height / 1920 / 1080) * 8000000 / 8; //Bytes RK_U32 frame_target_size = frame_target_bitrate / extra_info_cfg->keyframe_max_interval; @@ -3089,6 +3213,14 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) h264e_hal_log_simple("frame %d | type %d | start gen regs", ctx->frame_cnt, syn->slice_type); + if (ctx->sei_mode == MPP_ENC_SEI_MODE_ONE_FRAME && extra_info->sei_change_flg) { + extra_info->nal_num = 0; + hal_h264e_rkv_stream_reset(&extra_info->stream); + hal_h264e_rkv_nal_start(extra_info, RKVENC_NAL_SEI, RKVENC_NAL_PRIORITY_DISPOSABLE); + hal_h264e_rkv_sei_encode(extra_info); + hal_h264e_rkv_nal_end(extra_info); + } + if (ctx->frame_cnt == 0) { if (MPP_OK != hal_h264e_rkv_allocate_buffers(ctx, syn, sps, test_cfg)) { h264e_hal_log_err("hal_h264e_rkv_allocate_buffers failed, free buffers and return"); @@ -3483,6 +3615,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) ctx->frame_cnt_gen_ready++; ctx->frame_cnt++; + extra_info->sei.frame_cnt++; h264e_hal_debug_leave(); @@ -3702,21 +3835,9 @@ MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param) break; } case MPP_ENC_GET_EXTRA_INFO: { - RK_S32 k = 0; - size_t offset = 0; - MppPacket pkt = ctx->packeted_param; - MppPacket *pkt_out = (MppPacket *)param; - h264e_hal_rkv_extra_info *src = (h264e_hal_rkv_extra_info *)ctx->extra_info; - - for (k = 0; k < src->nal_num; k++) { - h264e_hal_log_header("get extra info nal type %d, size %d bytes", src->nal[k].i_type, src->nal[k].i_payload); - mpp_packet_write(pkt, offset, src->nal[k].p_payload, src->nal[k].i_payload); - offset += src->nal[k].i_payload; - } - mpp_packet_set_length(pkt, offset); - *pkt_out = pkt; - - hal_h264e_rkv_dump_mpp_strm_out_header(ctx, pkt); + MppPacket *pkt_out = (MppPacket *)param; + hal_h264e_rkv_get_extra_info(ctx, pkt_out); + hal_h264e_rkv_dump_mpp_strm_out_header(ctx, *pkt_out); break; } case MPP_ENC_SET_OSD_PLT_CFG: { @@ -3727,6 +3848,14 @@ MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param) hal_h264e_rkv_set_osd_data(ctx, param); break; } + case MPP_ENC_SET_SEI_CFG: { + ctx->sei_mode = *((MppEncSeiMode *)param); + break; + } + case MPP_ENC_GET_SEI_DATA: { + hal_h264e_rkv_get_extra_info(ctx, (MppPacket *)param); + break; + } default : { h264e_hal_log_err("unrecognizable cmd type %d", cmd_type); } break; diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h index 3a9284d9..b8a52e6f 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h @@ -84,6 +84,9 @@ enc_mode #define RKV_H264E_INT_BUS_READ_ERROR 0x00000080 #define RKV_H264E_INT_TIMEOUT_ERROR 0x00000100 +#define H264E_SEI_CHG_SPSPPS 0x00000001 +#define H264E_SEI_CHG_RC 0x00000010 + #if RKV_H264E_SDK_TEST typedef struct h264e_hal_rkv_coveragetest_cfg_t { RK_U32 qp; @@ -201,7 +204,8 @@ typedef struct h264e_hal_rkv_stream_t { //add buf pointer RK_U8 *buf; - RK_U32 count_bit; + RK_U8 *buf_plus8; + RK_U32 count_bit; // only for debug } h264e_hal_rkv_stream; @@ -209,10 +213,14 @@ typedef struct h264e_hal_rkv_extra_info_t { RK_S32 nal_num; h264e_hal_rkv_nal nal[RKV_H264E_RKV_NAL_IDX_BUTT]; RK_U8 *nal_buf; + RK_U8 *sei_buf; + RK_U32 sei_change_flg; h264e_hal_rkv_stream stream; h264e_hal_sps sps; h264e_hal_pps pps; + h264e_hal_sei sei; } h264e_hal_rkv_extra_info; + #define RKV_H264E_REF_MAX 16 typedef RK_U8 pixel; struct h264e_hal_rkv_weight_t; diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vpu.c b/mpp/hal/rkenc/h264e/hal_h264e_vpu.c index 1be30904..b910c844 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vpu.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vpu.c @@ -1645,7 +1645,7 @@ static MPP_RET hal_h264e_vpu_set_extra_info(h264e_hal_context *ctx, void *param) h264e_hal_pps *pps = &info->pps; h264e_hal_debug_enter(); - ctx->extra_info_cfg = *cfg; + info->sei.extra_info_cfg = *cfg; hal_h264e_vpu_stream_buffer_reset(sps_stream); hal_h264e_vpu_stream_buffer_reset(pps_stream); @@ -1686,9 +1686,8 @@ MPP_RET hal_h264e_vpu_init(void *hal, MppHalCfg *cfg) ctx->buffers = mpp_calloc(h264e_hal_vpu_buffers, 1); ctx->extra_info = mpp_calloc(h264e_hal_vpu_extra_info, 1); ctx->dump_files = mpp_calloc(h264e_hal_vpu_dump_files, 1); - ctx->param_size = H264E_MAX_PACKETED_PARAM_SIZE; - ctx->param_buf = mpp_calloc_size(void, ctx->param_size); - mpp_packet_init(&ctx->packeted_param, ctx->param_buf, ctx->param_size); + ctx->param_buf = mpp_calloc_size(void, H264E_EXTRA_INFO_BUF_SIZE); + mpp_packet_init(&ctx->packeted_param, ctx->param_buf, H264E_EXTRA_INFO_BUF_SIZE); hal_h264e_vpu_init_extra_info(ctx->extra_info); #ifdef H264E_DUMP_DATA_TO_FILE @@ -1727,6 +1726,7 @@ MPP_RET hal_h264e_vpu_deinit(void *hal) h264e_hal_debug_enter(); MPP_FREE(ctx->regs); + MPP_FREE(ctx->param_buf); if (ctx->extra_info) { hal_h264e_vpu_deinit_extra_info(ctx->extra_info); @@ -1738,13 +1738,6 @@ MPP_RET hal_h264e_vpu_deinit(void *hal) ctx->packeted_param = NULL; } - if (ctx->param_buf) { - mpp_free(ctx->param_buf); - ctx->param_buf = NULL; - } - - ctx->param_size = 0; - if (ctx->buffers) { hal_h264e_vpu_free_buffers(ctx); MPP_FREE(ctx->buffers); @@ -2246,6 +2239,10 @@ MPP_RET hal_h264e_vpu_control(void *hal, RK_S32 cmd_type, void *param) #endif break; } + case MPP_ENC_SET_SEI_CFG: { + ctx->sei_mode = *((MppEncSeiMode *)param); + break; + } default : { mpp_err("unrecognizable cmd type %d", cmd_type); } break; diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vpu.h b/mpp/hal/rkenc/h264e/hal_h264e_vpu.h index eba514d4..7d34d34f 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vpu.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_vpu.h @@ -663,6 +663,7 @@ typedef struct h264e_hal_vpu_extra_info_t { h264e_hal_vpu_stream pps_stream; h264e_hal_sps sps; h264e_hal_pps pps; + h264e_hal_sei sei; } h264e_hal_vpu_extra_info; typedef enum h264e_hal_vpu_buf_grp_t { diff --git a/mpp/hal/rkenc/h264e/test/h264e_hal_test.c b/mpp/hal/rkenc/h264e/test/h264e_hal_test.c index e98abbe6..5f6e4573 100644 --- a/mpp/hal/rkenc/h264e/test/h264e_hal_test.c +++ b/mpp/hal/rkenc/h264e/test/h264e_hal_test.c @@ -1363,7 +1363,7 @@ MPP_RET h264e_hal_vpu_test() h264e_syntax syntax_data; h264e_control_extra_info_cfg extra_info_cfg; MppPacket extra_info_pkt; - RK_U8 extra_info_buf[H264E_MAX_PACKETED_PARAM_SIZE] = {0}; + RK_U8 extra_info_buf[H264E_EXTRA_INFO_BUF_SIZE] = {0}; MppBufferGroup hw_input_buf_grp = NULL; MppBufferGroup hw_output_buf_grp = NULL; MppBuffer hw_input_buf = NULL; //Y, U, V @@ -1373,7 +1373,7 @@ MPP_RET h264e_hal_vpu_test() RK_U8 *input_sw_buf = mpp_malloc(RK_U8, MAX_FRAME_TOTAL_SIZE); - mpp_packet_init(&extra_info_pkt, (void *)extra_info_buf, H264E_MAX_PACKETED_PARAM_SIZE); + mpp_packet_init(&extra_info_pkt, (void *)extra_info_buf, H264E_EXTRA_INFO_BUF_SIZE); get_vpu_syntax_in(&syntax_data, hw_input_buf, hw_output_strm_buf, frame_luma_size); if (fp_golden_syntax_in) @@ -1476,8 +1476,7 @@ MPP_RET h264e_hal_rkv_test(h264e_hal_test_cfg *test_cfg) HalTaskInfo task_info; h264e_control_extra_info_cfg extra_info_cfg; MppPacket extra_info_pkt; - RK_U8 extra_info_buf[H264E_MAX_PACKETED_PARAM_SIZE] = {0}; - //h264e_hal_rkv_dbg_info dbg_info; + RK_U8 extra_info_buf[H264E_EXTRA_INFO_BUF_SIZE] = {0}; h264e_syntax syntax_data[RKV_H264E_LINKTABLE_FRAME_NUM]; MppBufferGroup hw_input_buf_grp = NULL; MppBufferGroup hw_output_buf_grp = NULL; @@ -1499,7 +1498,7 @@ MPP_RET h264e_hal_rkv_test(h264e_hal_test_cfg *test_cfg) MPP_ENC_OSD_PLT_BLACK }; - mpp_packet_init(&extra_info_pkt, (void *)extra_info_buf, H264E_MAX_PACKETED_PARAM_SIZE); + mpp_packet_init(&extra_info_pkt, (void *)extra_info_buf, H264E_EXTRA_INFO_BUF_SIZE); get_rkv_syntax_in(&syntax_data[0], hw_input_buf_mul, hw_output_strm_buf_mul, test_cfg); diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index 1a9e2d3c..635f7386 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -178,6 +178,7 @@ int mpi_enc_test(MpiEncTestCmd *cmd) MppBuffer md_buf[MPI_ENC_IO_COUNT] = { NULL }; MppBuffer osd_idx_buf[MPI_ENC_IO_COUNT] = { NULL }; MppEncOSDPlt osd_plt; + MppEncSeiMode sei_mode = MPP_ENC_SEI_MODE_ONE_SEQ; // paramter for resource malloc RK_U32 width = cmd->width; @@ -301,6 +302,12 @@ int mpi_enc_test(MpiEncTestCmd *cmd) mpp_cfg.level = 41; mpp_cfg.cabac_en = 1; + ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &sei_mode); + if (MPP_OK != ret) { + mpp_err("mpi control enc set sei cfg failed\n"); + goto MPP_TEST_OUT; + } + ret = mpi->control(ctx, MPP_ENC_SET_CFG, &mpp_cfg); if (MPP_OK != ret) { mpp_err("mpi control enc set cfg failed\n");