diff --git a/mpp/codec/enc/h264/include/h264encapi.h b/mpp/codec/enc/h264/include/h264encapi.h index 732b85f0..a04e256e 100644 --- a/mpp/codec/enc/h264/include/h264encapi.h +++ b/mpp/codec/enc/h264/include/h264encapi.h @@ -231,8 +231,7 @@ typedef struct { RK_U32 pictureRc; /* Adjust QP between pictures, [0,1] */ RK_U32 mbRc; /* Adjust QP inside picture, [0,1] */ RK_U32 pictureSkip; /* Allow rate control to skip pictures, [0,1] */ - RK_U32 intraPicRate; /* intra period */ - RK_U32 keyframe_max_interval; + RK_U32 intraPicRate; /* intra period, namely keyframe_max_interval */ RK_S32 qpHdr; /* QP for next encoded picture, [-1..51] * -1 = Let rate control calculate initial QP * This QP is used for all pictures if diff --git a/mpp/codec/enc/h264/src/h264e_api.c b/mpp/codec/enc/h264/src/h264e_api.c index c2c5bad5..915534e0 100644 --- a/mpp/codec/enc/h264/src/h264e_api.c +++ b/mpp/codec/enc/h264/src/h264e_api.c @@ -339,7 +339,6 @@ MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param) else enc_rc_cfg->intraPicRate = 30; - enc_rc_cfg->keyframe_max_interval = mpp_cfg->gop; enc_rc_cfg->bitPerSecond = mpp_cfg->bps; enc_rc_cfg->gopLen = mpp_cfg->gop; enc_rc_cfg->fixedIntraQp = 0; @@ -377,7 +376,8 @@ MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param) info->input_image_format = enc_cfg->input_image_format; info->profile_idc = enc_cfg->profile; info->level_idc = enc_cfg->level; - info->keyframe_max_interval = enc_rc_cfg->keyframe_max_interval; + info->keyframe_max_interval = enc_rc_cfg->intraPicRate; + info->frame_rate = enc_cfg->frameRateNum; info->second_chroma_qp_index_offset = enc_cfg->second_chroma_qp_index_offset; info->pps_id = enc_cfg->pps_id; diff --git a/mpp/common/h264e_syntax.h b/mpp/common/h264e_syntax.h index 23360657..4a125b2c 100644 --- a/mpp/common/h264e_syntax.h +++ b/mpp/common/h264e_syntax.h @@ -95,6 +95,7 @@ typedef struct h264e_control_extra_info_cfg_t { RK_S32 transform8x8_mode; RK_S32 chroma_qp_index_offset; RK_S32 pic_init_qp; + RK_S32 frame_rate; //RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation /* additional cfg only for rkv */ diff --git a/mpp/hal/inc/hal_task.h b/mpp/hal/inc/hal_task.h index 6f349696..66845f93 100644 --- a/mpp/hal/inc/hal_task.h +++ b/mpp/hal/inc/hal_task.h @@ -86,6 +86,14 @@ typedef struct MppSyntax_t { * +----------------------+ +----v----+ */ +#define HAL_ENC_TASK_ERR_INIT 0x00000001 +#define HAL_ENC_TASK_ERR_ALLOC 0x00000010 +#define HAL_ENC_TASK_ERR_EXTRAINFO 0x00000100 +#define HAL_ENC_TASK_ERR_GENREG 0x00001000 +#define HAL_ENC_TASK_ERR_START 0x00010000 +#define HAL_ENC_TASK_ERR_WAIT 0x00100000 + + typedef union HalDecTaskFlag_t { RK_U32 val; struct { @@ -96,6 +104,10 @@ typedef union HalDecTaskFlag_t { }; } HalDecTaskFlag; +typedef struct HalEncTaskFlag_t { + RK_U32 err; +} HalEncTaskFlag; + typedef struct HalDecTask_t { // set by parser to signal that it is valid RK_U32 valid; @@ -135,6 +147,9 @@ typedef struct HalEncTask_t { MppBuffer input; RK_U32 is_intra; + + HalEncTaskFlag flags; + } HalEncTask; diff --git a/mpp/hal/rkenc/h264e/hal_h264e.h b/mpp/hal/rkenc/h264e/hal_h264e.h index d6eb4136..ae55d789 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e.h +++ b/mpp/hal/rkenc/h264e/hal_h264e.h @@ -66,7 +66,7 @@ extern RK_U32 h264e_hal_log_mode; #define h264e_hal_log_err(fmt, ...) \ do {\ if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\ - { mpp_err(fmt, ## __VA_ARGS__); }\ + { mpp_err_f(fmt, ## __VA_ARGS__); }\ } while (0) #define h264e_hal_log_detail(fmt, ...) \ diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c index 8af87dc5..c4964c91 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c @@ -1469,12 +1469,40 @@ static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, h264e_synt RK_S32 k = 0; h264e_hal_rkv_buffers *buffers = (h264e_hal_rkv_buffers *)ctx->buffers; RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); - RK_U32 frame_size = ((syn->pic_luma_width + 15) & (~15)) * ((syn->pic_luma_height + 15) & (~15)) * 3 / 2; + RK_U32 frame_size = ((syn->pic_luma_width + 15) & (~15)) * ((syn->pic_luma_height + 15) & (~15)); //only Y component h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; h264e_hal_rkv_frame *frame_buf = dpb_ctx->frame_buf; RK_U32 all_intra_mode = sps->keyframe_max_interval == 1; h264e_hal_debug_enter(); - //TODO: reduce buf size + + switch ((h264e_hal_rkv_csp)syn->input_image_format) { + case H264E_RKV_CSP_YUV420P: + case H264E_RKV_CSP_YUV420SP: { + frame_size = frame_size * 3 / 2; + break; + } + case H264E_RKV_CSP_YUV422P: + case H264E_RKV_CSP_YUV422SP: + case H264E_RKV_CSP_YUYV422: + case H264E_RKV_CSP_UYVY422: + case H264E_RKV_CSP_BGR565: { + frame_size *= 2; + break; + } + case H264E_RKV_CSP_BGR888: { + frame_size *= 3; + break; + } + case H264E_RKV_CSP_BGRA8888: { + frame_size *= 4; + break; + } + default: { + h264e_hal_log_err("unvalid src color space: %d, return early", syn->input_image_format); + return MPP_NOK; + } + } + for (k = 0; k < H264E_HAL_RKV_BUF_GRP_BUTT; k++) { if (MPP_OK != mpp_buffer_group_get_internal(&buffers->hw_buf_grp[k], MPP_BUFFER_TYPE_ION)) { h264e_hal_log_err("buf group[%d] get failed", k); @@ -1606,7 +1634,7 @@ MPP_RET hal_h264e_rkv_set_sps(h264e_hal_sps *sps, h264e_hal_param *par, h264e_co RK_S32 crop_rect_top = 0; RK_S32 crop_rect_bottom = 0; RK_S32 i_timebase_num = 1; - RK_S32 i_timebase_den = 25; + RK_S32 i_timebase_den = cfg->frame_rate; RK_S32 b_vfr_input = 0; RK_S32 i_nal_hrd = 0; RK_S32 b_pic_struct = 0; @@ -3038,6 +3066,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) h264e_hal_rkv_coveragetest_cfg *test_cfg = (h264e_hal_rkv_coveragetest_cfg *)ctx->test_cfg; h264e_hal_sps *sps = &extra_info->sps; h264e_hal_pps *pps = &extra_info->pps; + HalEncTask *enc_task = &task->enc; RK_S32 pic_width_align16 = (syn->pic_luma_width + 15) & (~15); RK_S32 pic_height_align16 = (syn->pic_luma_height + 15) & (~15); @@ -3051,11 +3080,13 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) h264e_hal_debug_enter(); hal_h264e_rkv_dump_mpp_syntax_in(syn, ctx); - if (MPP_OK != hal_h264e_rkv_validate_syntax(syn, &src_fmt, ctx->frame_cnt % sps->keyframe_max_interval == 0)) { - h264e_hal_log_err("hal_h264e_rkv_validate_syntax failed"); - } + enc_task->flags.err = 0; - ctx->enc_task = task->enc; + if (MPP_OK != hal_h264e_rkv_validate_syntax(syn, &src_fmt, ctx->frame_cnt % sps->keyframe_max_interval == 0)) { + h264e_hal_log_err("hal_h264e_rkv_validate_syntax failed, return early"); + enc_task->flags.err |= HAL_ENC_TASK_ERR_GENREG; + return MPP_NOK; + } hal_h264e_rkv_adjust_param(ctx); //TODO: future expansion @@ -3063,8 +3094,10 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) 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 now"); + h264e_hal_log_err("hal_h264e_rkv_allocate_buffers failed, free buffers and return"); + enc_task->flags.err |= HAL_ENC_TASK_ERR_ALLOC; hal_h264e_rkv_free_buffers(ctx); + return MPP_ERR_MALLOC; } } @@ -3464,8 +3497,14 @@ MPP_RET hal_h264e_rkv_start(void *hal, HalTaskInfo *task) h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs; RK_U32 length = 0, k = 0; h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input; + HalEncTask *enc_task = &task->enc; h264e_hal_debug_enter(); + if (enc_task->flags.err) { + h264e_hal_log_err("enc_task->flags.err %08x, return early", enc_task->flags.err); + return MPP_NOK; + } + if (ctx->frame_cnt_gen_ready != ctx->num_frames_to_send) { h264e_hal_log_detail("frame_cnt_gen_ready(%d) != num_frames_to_send(%d), start hardware later", ctx->frame_cnt_gen_ready, ctx->num_frames_to_send); @@ -3568,9 +3607,14 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) RK_S32 length = (sizeof(reg_out->frame_num) + sizeof(reg_out->elem[0]) * ctx->num_frames_to_send) >> 2; IOInterruptCB int_cb = ctx->int_cb; h264e_feedback *fb = &ctx->feedback; - (void)task; + HalEncTask *enc_task = &task->enc; h264e_hal_debug_enter(); + if (enc_task->flags.err) { + h264e_hal_log_err("enc_task->flags.err %08x, return early", enc_task->flags.err); + return MPP_NOK; + } + if (ctx->frame_cnt_gen_ready != ctx->num_frames_to_send) { h264e_hal_log_detail("frame_cnt_gen_ready(%d) != num_frames_to_send(%d), wait hardware later", ctx->frame_cnt_gen_ready, ctx->num_frames_to_send); @@ -3623,7 +3667,7 @@ MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) hal_h264e_rkv_dump_mpp_reg_out(ctx); hal_h264e_rkv_dump_mpp_feedback(ctx); - hal_h264e_rkv_dump_mpp_strm_out(ctx, ctx->enc_task.output); + hal_h264e_rkv_dump_mpp_strm_out(ctx, enc_task->output); h264e_hal_debug_leave(); return MPP_OK; diff --git a/mpp/hal/rkenc/h264e/test/h264e_hal_test.c b/mpp/hal/rkenc/h264e/test/h264e_hal_test.c index 349f5502..691330b5 100644 --- a/mpp/hal/rkenc/h264e/test/h264e_hal_test.c +++ b/mpp/hal/rkenc/h264e/test/h264e_hal_test.c @@ -1331,6 +1331,8 @@ static void h264e_hal_set_extra_info_cfg(h264e_control_extra_info_cfg *info, h26 info->keyframe_max_interval = syn->keyframe_max_interval; info->second_chroma_qp_index_offset = syn->second_chroma_qp_index_offset; info->pps_id = syn->pps_id; + + info->frame_rate = 30; } MPP_RET h264e_hal_vpu_test() diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index 7375b5f2..27da441b 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -83,8 +83,8 @@ static MPP_RET fill_yuv_image(RK_U8 *buf, MppEncConfig *mpp_cfg, RK_U32 frame_co p = buf_c; for (y = 0; y < height / 2; y++, p += hor_stride) { for (x = 0; x < width / 2; x++) { - p[x*2+0] = 128 + y + frame_count * 2; - p[x*2+1] = 64 + x + frame_count * 5; + p[x * 2 + 0] = 128 + y + frame_count * 2; + p[x * 2 + 1] = 64 + x + frame_count * 5; } } } break;