[HAL_H264E_RKV]: complete buffers allocation

1. add HalEncTask.flags.err to decribe errors
2. support alloc error treatment
3. support frame rate configuration
4. user tool to format file mpi_enc_test.c
5. allocate buffer according to color space

Change-Id: I17a89039504390bf1f2ff664a0aa4075b04d33ee
Signed-off-by: Lin Kesheng <lks@rock-chips.com>
This commit is contained in:
Lin Kesheng
2016-09-20 11:07:43 +08:00
parent 1752473f33
commit 3300d13c3c
8 changed files with 78 additions and 17 deletions

View File

@@ -231,8 +231,7 @@ typedef struct {
RK_U32 pictureRc; /* Adjust QP between pictures, [0,1] */ RK_U32 pictureRc; /* Adjust QP between pictures, [0,1] */
RK_U32 mbRc; /* Adjust QP inside picture, [0,1] */ RK_U32 mbRc; /* Adjust QP inside picture, [0,1] */
RK_U32 pictureSkip; /* Allow rate control to skip pictures, [0,1] */ RK_U32 pictureSkip; /* Allow rate control to skip pictures, [0,1] */
RK_U32 intraPicRate; /* intra period */ RK_U32 intraPicRate; /* intra period, namely keyframe_max_interval */
RK_U32 keyframe_max_interval;
RK_S32 qpHdr; /* QP for next encoded picture, [-1..51] RK_S32 qpHdr; /* QP for next encoded picture, [-1..51]
* -1 = Let rate control calculate initial QP * -1 = Let rate control calculate initial QP
* This QP is used for all pictures if * This QP is used for all pictures if

View File

@@ -339,7 +339,6 @@ MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param)
else else
enc_rc_cfg->intraPicRate = 30; enc_rc_cfg->intraPicRate = 30;
enc_rc_cfg->keyframe_max_interval = mpp_cfg->gop;
enc_rc_cfg->bitPerSecond = mpp_cfg->bps; enc_rc_cfg->bitPerSecond = mpp_cfg->bps;
enc_rc_cfg->gopLen = mpp_cfg->gop; enc_rc_cfg->gopLen = mpp_cfg->gop;
enc_rc_cfg->fixedIntraQp = 0; 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->input_image_format = enc_cfg->input_image_format;
info->profile_idc = enc_cfg->profile; info->profile_idc = enc_cfg->profile;
info->level_idc = enc_cfg->level; 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->second_chroma_qp_index_offset = enc_cfg->second_chroma_qp_index_offset;
info->pps_id = enc_cfg->pps_id; info->pps_id = enc_cfg->pps_id;

View File

@@ -95,6 +95,7 @@ typedef struct h264e_control_extra_info_cfg_t {
RK_S32 transform8x8_mode; RK_S32 transform8x8_mode;
RK_S32 chroma_qp_index_offset; RK_S32 chroma_qp_index_offset;
RK_S32 pic_init_qp; RK_S32 pic_init_qp;
RK_S32 frame_rate;
//RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation //RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation
/* additional cfg only for rkv */ /* additional cfg only for rkv */

View File

@@ -86,6 +86,14 @@ typedef struct MppSyntax_t {
* +----------------------+ +----v----+ * +----------------------+ +----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 { typedef union HalDecTaskFlag_t {
RK_U32 val; RK_U32 val;
struct { struct {
@@ -96,6 +104,10 @@ typedef union HalDecTaskFlag_t {
}; };
} HalDecTaskFlag; } HalDecTaskFlag;
typedef struct HalEncTaskFlag_t {
RK_U32 err;
} HalEncTaskFlag;
typedef struct HalDecTask_t { typedef struct HalDecTask_t {
// set by parser to signal that it is valid // set by parser to signal that it is valid
RK_U32 valid; RK_U32 valid;
@@ -135,6 +147,9 @@ typedef struct HalEncTask_t {
MppBuffer input; MppBuffer input;
RK_U32 is_intra; RK_U32 is_intra;
HalEncTaskFlag flags;
} HalEncTask; } HalEncTask;

View File

@@ -66,7 +66,7 @@ extern RK_U32 h264e_hal_log_mode;
#define h264e_hal_log_err(fmt, ...) \ #define h264e_hal_log_err(fmt, ...) \
do {\ do {\
if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\ if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\
{ mpp_err(fmt, ## __VA_ARGS__); }\ { mpp_err_f(fmt, ## __VA_ARGS__); }\
} while (0) } while (0)
#define h264e_hal_log_detail(fmt, ...) \ #define h264e_hal_log_detail(fmt, ...) \

View File

@@ -1469,12 +1469,40 @@ static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, h264e_synt
RK_S32 k = 0; RK_S32 k = 0;
h264e_hal_rkv_buffers *buffers = (h264e_hal_rkv_buffers *)ctx->buffers; 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 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_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx;
h264e_hal_rkv_frame *frame_buf = dpb_ctx->frame_buf; h264e_hal_rkv_frame *frame_buf = dpb_ctx->frame_buf;
RK_U32 all_intra_mode = sps->keyframe_max_interval == 1; RK_U32 all_intra_mode = sps->keyframe_max_interval == 1;
h264e_hal_debug_enter(); 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++) { 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)) { 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); 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_top = 0;
RK_S32 crop_rect_bottom = 0; RK_S32 crop_rect_bottom = 0;
RK_S32 i_timebase_num = 1; 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 b_vfr_input = 0;
RK_S32 i_nal_hrd = 0; RK_S32 i_nal_hrd = 0;
RK_S32 b_pic_struct = 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_rkv_coveragetest_cfg *test_cfg = (h264e_hal_rkv_coveragetest_cfg *)ctx->test_cfg;
h264e_hal_sps *sps = &extra_info->sps; h264e_hal_sps *sps = &extra_info->sps;
h264e_hal_pps *pps = &extra_info->pps; 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_width_align16 = (syn->pic_luma_width + 15) & (~15);
RK_S32 pic_height_align16 = (syn->pic_luma_height + 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(); h264e_hal_debug_enter();
hal_h264e_rkv_dump_mpp_syntax_in(syn, ctx); 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)) { enc_task->flags.err = 0;
h264e_hal_log_err("hal_h264e_rkv_validate_syntax failed");
}
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 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 (ctx->frame_cnt == 0) {
if (MPP_OK != hal_h264e_rkv_allocate_buffers(ctx, syn, sps, test_cfg)) { 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); 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; h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs;
RK_U32 length = 0, k = 0; RK_U32 length = 0, k = 0;
h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input; h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input;
HalEncTask *enc_task = &task->enc;
h264e_hal_debug_enter(); 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) { 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", 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); 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; 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; IOInterruptCB int_cb = ctx->int_cb;
h264e_feedback *fb = &ctx->feedback; h264e_feedback *fb = &ctx->feedback;
(void)task; HalEncTask *enc_task = &task->enc;
h264e_hal_debug_enter(); 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) { 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", 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); 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_reg_out(ctx);
hal_h264e_rkv_dump_mpp_feedback(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(); h264e_hal_debug_leave();
return MPP_OK; return MPP_OK;

View File

@@ -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->keyframe_max_interval = syn->keyframe_max_interval;
info->second_chroma_qp_index_offset = syn->second_chroma_qp_index_offset; info->second_chroma_qp_index_offset = syn->second_chroma_qp_index_offset;
info->pps_id = syn->pps_id; info->pps_id = syn->pps_id;
info->frame_rate = 30;
} }
MPP_RET h264e_hal_vpu_test() MPP_RET h264e_hal_vpu_test()

View File

@@ -83,8 +83,8 @@ static MPP_RET fill_yuv_image(RK_U8 *buf, MppEncConfig *mpp_cfg, RK_U32 frame_co
p = buf_c; p = buf_c;
for (y = 0; y < height / 2; y++, p += hor_stride) { for (y = 0; y < height / 2; y++, p += hor_stride) {
for (x = 0; x < width / 2; x++) { for (x = 0; x < width / 2; x++) {
p[x*2+0] = 128 + y + frame_count * 2; p[x * 2 + 0] = 128 + y + frame_count * 2;
p[x*2+1] = 64 + x + frame_count * 5; p[x * 2 + 1] = 64 + x + frame_count * 5;
} }
} }
} break; } break;