diff --git a/inc/rk_mpi.h b/inc/rk_mpi.h index 8906a373..8750ff36 100644 --- a/inc/rk_mpi.h +++ b/inc/rk_mpi.h @@ -81,63 +81,6 @@ typedef void* MppParam; * send a stream header to mpi ctx using parameter data / size * and decoder will try to decode the */ -typedef struct MppEncConfig_t { - /* encoder config also need to know size of itself */ - RK_U32 size; - RK_U32 version; - - /* - * input source data format - */ - RK_S32 width; - RK_S32 height; - RK_S32 hor_stride; - RK_S32 ver_stride; - RK_S32 format; - - /* - * Encoder does not support scaling and output data only support yuv420 so far - */ - - /* - * rate control parameter - * - * rc_mode - rate control mode - * 0 - fix qp mode - * 1 - constant bit rate mode (CBR) - * 2 - variable bit rate mode (VBR) - * skip_cnt - max continuous frame skip count - * 0 - frame skip is not allow - * bps - target bit rate, unit: bit per second - * fps_in - input frame rate, unit: frame per second - * if 0 then default set to 30 - * fps_out - output frame rate, unit: frame per second - * if 0 then default set to fps_in - * qp - constant qp for fix qp mode - * initial qp for CBR / VBR - * gop - gap between Intra frame - * 0 for only 1 I frame the rest are all P frames - * 1 for all I frame - * 2 for I P I P I P - * 3 for I P P I P P - * etc... - */ - RK_S32 rc_mode; - RK_S32 skip_cnt; - RK_S32 bps; - RK_S32 fps_in; - RK_S32 fps_out; - RK_S32 qp; - RK_S32 gop; - - /* - * stream feature parameter - */ - RK_S32 profile; - RK_S32 level; - RK_S32 cabac_en; -} MppEncConfig; - typedef struct MppEncCodecCfg_t { MppCodingType coding; diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 718a5df3..f702cfe0 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -80,9 +80,6 @@ typedef enum { MPP_DEC_CMD_END, MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, - /* legacy support for vpuapi */ - MPP_ENC_SET_CFG, - MPP_ENC_GET_CFG, /* basic encoder setup control */ MPP_ENC_SET_ALL_CFG, /* set MppEncCfgSet structure */ MPP_ENC_GET_ALL_CFG, /* get MppEncCfgSet structure */ diff --git a/mpp/codec/enc/h264/src/h264e_api.c b/mpp/codec/enc/h264/src/h264e_api.c index b41d6908..f1d519ba 100644 --- a/mpp/codec/enc/h264/src/h264e_api.c +++ b/mpp/codec/enc/h264/src/h264e_api.c @@ -138,6 +138,8 @@ MPP_RET h264e_encode(void *ctx, HalEncTask *task) MppEncCfgSet *cfg = p->cfg; MppEncRcCfg *rc = &cfg->rc; + h264e_dbg_func("enter\n"); + if (!p->rc_ready) { mpp_err_f("not initialize encoding\n"); task->valid = 0; @@ -152,6 +154,8 @@ MPP_RET h264e_encode(void *ctx, HalEncTask *task) task->syntax.number = 1; task->valid = 1; + h264e_dbg_func("leave\n"); + return MPP_OK; } @@ -193,82 +197,6 @@ static const H264Level h264e_supported_level[] = { H264_LEVEL_5_1, }; -static MPP_RET h264e_check_mpp_cfg(MppEncConfig *mpp_cfg) -{ - RK_U32 i, count; - - count = MPP_ARRAY_ELEMS(h264e_supported_profile); - for (i = 0; i < count; i++) { - if (h264e_supported_profile[i] == (H264Profile)mpp_cfg->profile) { - break; - } - } - - if (i >= count) { - mpp_log_f("invalid profile %d set to default baseline\n", mpp_cfg->profile); - mpp_cfg->profile = H264_PROFILE_BASELINE; - } - - count = MPP_ARRAY_ELEMS(h264e_supported_level); - for (i = 0; i < count; i++) { - if (h264e_supported_level[i] == (H264Level)mpp_cfg->level) { - break; - } - } - - if (i >= count) { - mpp_log_f("invalid level %d set to default 4.0\n", mpp_cfg->level); - mpp_cfg->level = H264_LEVEL_4_0; - } - - if (mpp_cfg->fps_in <= 0) { - mpp_log_f("invalid input fps %d will be set to default 30\n", mpp_cfg->fps_in); - mpp_cfg->fps_in = 30; - } - - if (mpp_cfg->fps_out <= 0) { - mpp_log_f("invalid output fps %d will be set to fps_in 30\n", mpp_cfg->fps_out, mpp_cfg->fps_in); - mpp_cfg->fps_out = mpp_cfg->fps_in; - } - - if (mpp_cfg->gop <= 0) { - mpp_log_f("invalid gop %d will be set to fps_out 30\n", mpp_cfg->gop, mpp_cfg->fps_out); - mpp_cfg->gop = mpp_cfg->fps_out; - } - - if (mpp_cfg->rc_mode < 0 || mpp_cfg->rc_mode > 2) { - mpp_err_f("invalid rc_mode %d\n", mpp_cfg->rc_mode); - return MPP_NOK; - } - - if (mpp_cfg->qp <= 0 || mpp_cfg->qp > 51) { - mpp_log_f("invalid qp %d set to default 26\n", mpp_cfg->qp); - mpp_cfg->qp = 26; - } - - if (mpp_cfg->bps <= 0) { - mpp_err_f("invalid bit rate %d\n", mpp_cfg->bps); - return MPP_NOK; - } - - if (mpp_cfg->width <= 0 || mpp_cfg->height <= 0) { - mpp_err_f("invalid width %d height %d\n", mpp_cfg->width, mpp_cfg->height); - return MPP_NOK; - } - - if (mpp_cfg->hor_stride <= 0) { - mpp_err_f("invalid hor_stride %d will be set to %d\n", mpp_cfg->hor_stride, mpp_cfg->width); - mpp_cfg->hor_stride = mpp_cfg->width; - } - - if (mpp_cfg->ver_stride <= 0) { - mpp_err_f("invalid ver_stride %d will be set to %d\n", mpp_cfg->ver_stride, mpp_cfg->height); - mpp_cfg->ver_stride = mpp_cfg->height; - } - - return MPP_OK; -} - MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param) { MPP_RET ret = MPP_OK; @@ -277,9 +205,6 @@ MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param) h264e_dbg_func("enter ctx %p cmd %x param %p\n", ctx, cmd, param); switch (cmd) { - case CHK_ENC_CFG : { - ret = h264e_check_mpp_cfg((MppEncConfig *)param); - } break; case SET_IDR_FRAME : { p->idr_request++; } break; diff --git a/mpp/codec/enc/jpeg/jpege_api.c b/mpp/codec/enc/jpeg/jpege_api.c index c1ff7049..92ad95fe 100644 --- a/mpp/codec/enc/jpeg/jpege_api.c +++ b/mpp/codec/enc/jpeg/jpege_api.c @@ -40,11 +40,10 @@ RK_U32 jpege_debug = 0; #define jpege_dbg_output(fmt, ...) jpege_dbg(JPEGE_DBG_OUTPUT, fmt, ## __VA_ARGS__) typedef struct { - /* output to hal */ - JpegeSyntax syntax; - /* input from hal */ JpegeFeedback feedback; + MppEncCfgSet *cfg; + MppEncCfgSet *set; } JpegeCtx; MPP_RET jpege_callback(void *ctx, void *feedback) @@ -64,17 +63,18 @@ MPP_RET jpege_callback(void *ctx, void *feedback) return MPP_OK; } -MPP_RET jpege_init(void *ctx, ControllerCfg *ctrlCfg) +MPP_RET jpege_init(void *ctx, ControllerCfg *cfg) { JpegeCtx *p = (JpegeCtx *)ctx; mpp_env_get_u32("jpege_debug", &jpege_debug, 0); jpege_dbg_func("enter ctx %p\n", ctx); - memset(&p->syntax, 0, sizeof(p->syntax)); + p->cfg = cfg->cfg; + p->set = cfg->set; - mpp_assert(ctrlCfg->coding = MPP_VIDEO_CodingMJPEG); - ctrlCfg->task_count = 1; + mpp_assert(cfg->coding = MPP_VIDEO_CodingMJPEG); + cfg->task_count = 1; jpege_dbg_func("leave ctx %p\n", ctx); return MPP_OK; @@ -89,14 +89,10 @@ MPP_RET jpege_deinit(void *ctx) MPP_RET jpege_encode(void *ctx, HalEncTask *task) { - JpegeCtx *p = (JpegeCtx *)ctx; - jpege_dbg_func("enter ctx %p\n", ctx); task->valid = 1; - task->syntax.data = &p->syntax; - task->syntax.number = 1; - task->is_intra = 1; + task->is_intra = 1; jpege_dbg_func("leave ctx %p\n", ctx); return MPP_OK; @@ -116,75 +112,12 @@ MPP_RET jpege_flush(void *ctx) return MPP_OK; } -static MPP_RET jpege_check_cfg(MppEncConfig *cfg) -{ - if (cfg->width < 16 && cfg->width > 8192) { - mpp_err("jpege: invalid width %d is not in range [16..8192]\n", cfg->width); - return MPP_NOK; - } - - if (cfg->height < 16 && cfg->height > 8192) { - mpp_err("jpege: invalid height %d is not in range [16..8192]\n", cfg->height); - return MPP_NOK; - } - - if (cfg->format != MPP_FMT_YUV420SP && - cfg->format != MPP_FMT_YUV420P && - cfg->format != MPP_FMT_RGB888) { - mpp_err("jpege: invalid format %d is not supportted\n", cfg->format); - return MPP_NOK; - } - - if (cfg->qp < 0 || cfg->qp > 10) { - mpp_err("jpege: invalid quality level %d is not in range [0..10] set to default 8\n"); - cfg->qp = 8; - } - - return MPP_OK; -} - MPP_RET jpege_config(void *ctx, RK_S32 cmd, void *param) { MPP_RET ret = MPP_OK; - JpegeCtx *p = (JpegeCtx *)ctx; jpege_dbg_func("enter ctx %p cmd %x param %p\n", ctx, cmd, param); - - switch (cmd) { - case CHK_ENC_CFG : { - /* NOTE */ - return jpege_check_cfg((MppEncConfig *)param); - } break; - case SET_ENC_CFG : { - MppEncConfig *mpp_cfg = (MppEncConfig *)param; - - if (jpege_check_cfg(mpp_cfg)) - break; - - JpegeSyntax *syntax = &p->syntax; - syntax->width = mpp_cfg->width; - syntax->height = mpp_cfg->height; - syntax->format = mpp_cfg->format; - syntax->quality = mpp_cfg->qp; - } break; - case SET_ENC_RC_CFG : { - mpp_assert(p); - MppEncConfig *mpp_cfg = (MppEncConfig *)param; - JpegeSyntax *syntax = &p->syntax; - - mpp_cfg->width = syntax->width; - mpp_cfg->height = syntax->height; - mpp_cfg->format = syntax->format; - mpp_cfg->qp = syntax->quality; - } break; - default: - mpp_err("No correspond cmd found, and can not config!"); - ret = MPP_NOK; - break; - } - jpege_dbg_func("leave ret %d\n", ret); - return ret; } diff --git a/mpp/codec/inc/mpp_enc.h b/mpp/codec/inc/mpp_enc.h index fae87e94..42e98f4e 100644 --- a/mpp/codec/inc/mpp_enc.h +++ b/mpp/codec/inc/mpp_enc.h @@ -170,11 +170,6 @@ struct MppEnc_t { /* Encoder configure set */ MppEncCfgSet cfg; MppEncCfgSet set; - - /* - * configuration parameter to controller and hal - */ - MppEncConfig mpp_cfg; }; #ifdef __cplusplus diff --git a/mpp/codec/mpp_enc.cpp b/mpp/codec/mpp_enc.cpp index 2eb8d0b9..906783e6 100644 --- a/mpp/codec/mpp_enc.cpp +++ b/mpp/codec/mpp_enc.cpp @@ -122,11 +122,12 @@ void *mpp_enc_control_thread(void *data) * if there is available buffer in the input frame do encoding */ if (NULL == packet) { - RK_U32 width = enc->mpp_cfg.width; - RK_U32 height = enc->mpp_cfg.height; + RK_U32 width = enc->cfg.prep.width; + RK_U32 height = enc->cfg.prep.height; RK_U32 size = width * height; MppBuffer buffer = NULL; + mpp_assert(size); mpp_buffer_get(mpp->mPacketGroup, &buffer, size); mpp_packet_init_with_buffer(&packet, buffer); mpp_buffer_put(buffer); @@ -362,7 +363,6 @@ MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding) p->tasks = hal_cfg.tasks; p->frame_slots = frame_slots; p->packet_slots = packet_slots; - p->mpp_cfg.size = sizeof(p->mpp_cfg); *enc = p; return MPP_OK; } while (0); @@ -429,36 +429,29 @@ MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param) AutoMutex auto_lock(&enc->lock); switch (cmd) { - case MPP_ENC_SET_CFG : { - mpp_enc_dbg_ctrl("set config\n"); -#if 0 - MppEncConfig *mpp_cfg = &enc->mpp_cfg; - void *extra_info_cfg = NULL; + case MPP_ENC_SET_ALL_CFG : { + mpp_enc_dbg_ctrl("set all config\n"); + memcpy(&enc->set, param, sizeof(enc->set)); - memcpy(mpp_cfg, param, sizeof(enc->mpp_cfg)); + ret = controller_config(enc->controller, MPP_ENC_SET_RC_CFG, param); + if (!ret) + ret = mpp_hal_control(enc->hal, MPP_ENC_SET_RC_CFG, &enc->set.rc); - /* before set config to controller check it first */ - ret = controller_config(enc->controller, CHK_ENC_CFG, (void *)mpp_cfg); - if (ret) { - mpp_err("config check failed ret %d\n", ret); - break; - } - controller_config(enc->controller, SET_ENC_CFG, (void *)mpp_cfg); - controller_config(enc->controller, SET_ENC_RC_CFG, (void *)mpp_cfg); - controller_config(enc->controller, GET_ENC_EXTRA_INFO, (void *)&extra_info_cfg); + if (!ret) + mpp_enc_update_rc_cfg(&enc->cfg.rc, &enc->set.rc); - ret = mpp_hal_control(enc->hal, MPP_ENC_SET_EXTRA_INFO, extra_info_cfg); -#endif + if (!ret) + ret = mpp_hal_control(enc->hal, MPP_ENC_SET_PREP_CFG, &enc->set.prep); + + if (!ret) + ret = mpp_hal_control(enc->hal, MPP_ENC_SET_CODEC_CFG, &enc->set.codec); } break; - case MPP_ENC_GET_CFG : { - MppEncConfig *mpp_cfg = (MppEncConfig *)param; + case MPP_ENC_GET_ALL_CFG : { + MppEncCfgSet *p = (MppEncCfgSet *)param; - mpp_enc_dbg_ctrl("get config\n"); - mpp_assert(mpp_cfg->size == sizeof(enc->mpp_cfg)); - - *mpp_cfg = enc->mpp_cfg; + mpp_enc_dbg_ctrl("get all config\n"); + memcpy(p, &enc->cfg, sizeof(*p)); } break; - case MPP_ENC_SET_PREP_CFG : { mpp_enc_dbg_ctrl("set prep config\n"); memcpy(&enc->set.prep, param, sizeof(enc->set.prep)); diff --git a/mpp/codec/mpp_rc.cpp b/mpp/codec/mpp_rc.cpp index 2f4aa9b9..b9460e91 100644 --- a/mpp/codec/mpp_rc.cpp +++ b/mpp/codec/mpp_rc.cpp @@ -23,12 +23,14 @@ #define MPP_RC_DBG_FUNCTION (0x00000001) #define MPP_RC_DBG_RC (0x00000010) +#define MPP_RC_DBG_CFG (0x00000100) #define mpp_rc_dbg(flag, fmt, ...) _mpp_dbg(mpp_rc_debug, flag, fmt, ## __VA_ARGS__) #define mpp_rc_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_rc_debug, flag, fmt, ## __VA_ARGS__) #define mpp_rc_dbg_func(fmt, ...) mpp_rc_dbg_f(MPP_RC_DBG_FUNCTION, fmt, ## __VA_ARGS__) #define mpp_rc_dbg_rc(fmt, ...) mpp_rc_dbg(MPP_RC_DBG_RC, fmt, ## __VA_ARGS__) +#define mpp_rc_dbg_cfg(fmt, ...) mpp_rc_dbg(MPP_RC_DBG_CFG, fmt, ## __VA_ARGS__) #define SIGN(a) ((a) < (0) ? (-1) : (1)) #define DIV(a, b) (((a) + (SIGN(a) * (b)) / 2) / (b)) @@ -283,12 +285,15 @@ MPP_RET mpp_rc_update_user_cfg(MppRateControl *ctx, MppEncRcCfg *cfg) * step 1: update parameters */ if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { + mpp_rc_dbg_cfg("bps: %d [%d %d]\n", cfg->bps_target, + cfg->bps_min, cfg->bps_max); ctx->bps_min = cfg->bps_min; ctx->bps_max = cfg->bps_max; ctx->bps_target = cfg->bps_target; } if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { + mpp_rc_dbg_cfg("fps: %d / %d\n", cfg->fps_out_num, cfg->fps_out_denorm); ctx->fps_num = cfg->fps_out_num; ctx->fps_denom = cfg->fps_out_denorm; ctx->fps_out = ctx->fps_num / ctx->fps_denom; @@ -299,6 +304,8 @@ MPP_RET mpp_rc_update_user_cfg(MppRateControl *ctx, MppEncRcCfg *cfg) (ctx->gop != cfg->gop)) { RK_S32 gop = cfg->gop; + mpp_rc_dbg_cfg("gop: %d\n", cfg->gop); + if (ctx->intra) mpp_data_deinit(ctx->intra); mpp_data_init(&ctx->intra, gop); diff --git a/mpp/hal/vpu/h264e/hal_h264e_vpu.c b/mpp/hal/vpu/h264e/hal_h264e_vpu.c index c9158a55..777d1aa8 100644 --- a/mpp/hal/vpu/h264e/hal_h264e_vpu.c +++ b/mpp/hal/vpu/h264e/hal_h264e_vpu.c @@ -512,11 +512,13 @@ void hal_h264e_vpu_stream_put_bits_with_detect(h264e_hal_vpu_stream * buffer, RK RK_U8 *stream = buffer->stream; RK_U32 byte_buffer = buffer->byte_buffer; - mpp_assert(value < (1 << number)); - mpp_assert(number < 25); - h264e_hal_log_header("assemble %s value %x, bits %d\n", name, value, number); + if (value) { + mpp_assert(value < (1 << number)); + mpp_assert(number < 25); + } + bits = number + buffer->buffered_bits; byte_buffer = byte_buffer | ((RK_U32) value << (32 - bits)); diff --git a/mpp/hal/vpu/jpege/hal_jpege_api.c b/mpp/hal/vpu/jpege/hal_jpege_api.c index 0969cb10..6e68a778 100644 --- a/mpp/hal/vpu/jpege/hal_jpege_api.c +++ b/mpp/hal/vpu/jpege/hal_jpege_api.c @@ -39,22 +39,26 @@ typedef struct JpegeIocExtInfoSlot_t { } JpegeIocExtInfoSlot; typedef struct JpegeIocExtInfo_t { - RK_U32 magic; /* tell kernel that it is extra info */ - RK_U32 cnt; - JpegeIocExtInfoSlot slots[5]; + RK_U32 magic; /* tell kernel that it is extra info */ + RK_U32 cnt; + JpegeIocExtInfoSlot slots[5]; } JpegeIocExtInfo; typedef struct JpegeIocRegInfo_t { - RK_U32 regs[VPU2_REG_NUM]; - JpegeIocExtInfo extra_info; + RK_U32 regs[VPU2_REG_NUM]; + JpegeIocExtInfo extra_info; } JpegeIocRegInfo; typedef struct hal_jpege_ctx_s { - RK_S32 vpu_fd; + RK_S32 vpu_fd; - IOInterruptCB int_cb; - JpegeBits bits; - JpegeIocRegInfo ioctl_info; + IOInterruptCB int_cb; + JpegeBits bits; + JpegeIocRegInfo ioctl_info; + + MppEncCfgSet *cfg; + MppEncCfgSet *set; + JpegeSyntax syntax; } HalJpegeCtx; #define HAL_JPEGE_DBG_FUNCTION (0x00000001) @@ -98,6 +102,8 @@ MPP_RET hal_jpege_init(void *hal, MppHalCfg *cfg) mpp_assert(ctx->bits); memset(&(ctx->ioctl_info), 0, sizeof(ctx->ioctl_info)); + ctx->cfg = cfg->cfg; + ctx->set = cfg->set; hal_jpege_dbg_func("leave hal %p\n", hal); return MPP_OK; @@ -171,10 +177,12 @@ MPP_RET hal_jpege_gen_regs(void *hal, HalTaskInfo *task) HalEncTask *info = &task->enc; MppBuffer input = info->input; MppBuffer output = info->output; - JpegeSyntax *syntax = (JpegeSyntax *)info->syntax.data; - RK_U32 width = syntax->width; - RK_U32 height = syntax->height; - MppFrameFormat fmt = syntax->format; + JpegeSyntax *syntax = &ctx->syntax; + MppEncPrepCfg *prep = &ctx->cfg->prep; + MppEncCodecCfg *codec = &ctx->cfg->codec; + RK_U32 width = prep->width; + RK_U32 height = prep->height; + MppFrameFormat fmt = prep->format; RK_U32 hor_stride = MPP_ALIGN(width, 16); RK_U32 ver_stride = MPP_ALIGN(height, 16); JpegeBits bits = ctx->bits; @@ -187,6 +195,11 @@ MPP_RET hal_jpege_gen_regs(void *hal, HalTaskInfo *task) RK_S32 bitpos; RK_S32 bytepos; + syntax->width = width; + syntax->height = height; + syntax->format = fmt; + syntax->quality = codec->jpeg.quant; + hal_jpege_dbg_func("enter hal %p\n", hal); /* write header to output buffer */ @@ -449,12 +462,70 @@ MPP_RET hal_jpege_flush(void *hal) return MPP_OK; } -MPP_RET hal_jpege_control(void *hal, RK_S32 cmd_type, void *param) +MPP_RET hal_jpege_control(void *hal, RK_S32 cmd, void *param) { - hal_jpege_dbg_func("enter hal %p cmd %x param %p\n", hal, cmd_type, param); + (void)hal; + MPP_RET ret = MPP_OK; + + hal_jpege_dbg_func("enter hal %p cmd %x param %p\n", hal, cmd, param); + + switch (cmd) { + case MPP_ENC_SET_PREP_CFG : { + MppEncPrepCfg *cfg = (MppEncPrepCfg *)param; + if (cfg->width < 16 && cfg->width > 8192) { + mpp_err("jpege: invalid width %d is not in range [16..8192]\n", cfg->width); + ret = MPP_NOK; + } + + if (cfg->height < 16 && cfg->height > 8192) { + mpp_err("jpege: invalid height %d is not in range [16..8192]\n", cfg->height); + ret = MPP_NOK; + } + + if (cfg->format != MPP_FMT_YUV420SP && + cfg->format != MPP_FMT_YUV420P && + cfg->format != MPP_FMT_RGB888) { + mpp_err("jpege: invalid format %d is not supportted\n", cfg->format); + ret = MPP_NOK; + } + } break; + case MPP_ENC_GET_PREP_CFG: + case MPP_ENC_GET_CODEC_CFG: + 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_SET_EXTRA_INFO: + case MPP_ENC_GET_EXTRA_INFO: + case MPP_ENC_GET_SEI_DATA: + case MPP_ENC_SET_SEI_CFG: + case MPP_ENC_SET_RC_CFG : { + } break; + case MPP_ENC_SET_CODEC_CFG : { + HalJpegeCtx *ctx = (HalJpegeCtx *)hal; + MppEncJpegCfg *src = &ctx->set->codec.jpeg; + MppEncJpegCfg *dst = &ctx->cfg->codec.jpeg; + RK_U32 change = src->change; + + if (change & MPP_ENC_JPEG_CFG_CHANGE_QP) { + if (src->quant < 0 || src->quant > 10) { + mpp_err("jpege: invalid quality level %d is not in range [0..10] set to default 8\n"); + src->quant = 8; + } + dst->quant = src->quant; + } + + dst->change = 0; + src->change = 0; + } break; + default: + mpp_err("No correspond cmd(%08x) found, and can not config!", cmd); + ret = MPP_NOK; + break; + } hal_jpege_dbg_func("leave hal %p\n", hal); - return MPP_OK; + return ret; } const MppHalApi hal_api_jpege = { diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index 0c776507..b110cf50 100755 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -112,6 +112,143 @@ static MppFrameFormat vpu_pic_type_remap_to_mpp(EncInputPictureType type) return ret; } +static MPP_RET vpu_api_set_enc_cfg(MppCtx mpp_ctx, MppApi *mpi, + MppCodingType coding, MppFrameFormat fmt, + EncParameter_t *cfg) +{ + MPP_RET ret = MPP_OK; + MppEncCfgSet set; + MppEncCodecCfg *codec_cfg = &set.codec; + MppEncPrepCfg *prep_cfg = &set.prep; + MppEncRcCfg *rc_cfg = &set.rc; + RK_S32 width = cfg->width; + RK_S32 height = cfg->height; + RK_S32 bps = cfg->bitRate; + RK_S32 fps_in = cfg->framerate; + RK_S32 fps_out = (cfg->framerateout) ? (cfg->framerateout) : (fps_in); + RK_S32 gop = (cfg->intraPicRate) ? (cfg->intraPicRate) : (fps_out); + RK_S32 qp_init = (coding == MPP_VIDEO_CodingAVC) ? (26) : + (coding == MPP_VIDEO_CodingMJPEG) ? (10) : + (coding == MPP_VIDEO_CodingVP8) ? (56) : (0); + RK_S32 qp = (cfg->qp) ? (cfg->qp) : (qp_init); + RK_S32 profile = cfg->profileIdc; + RK_S32 level = cfg->levelIdc; + RK_S32 cabac_en = cfg->enableCabac; + RK_S32 rc_mode = cfg->rc_mode; + + mpp_log("setup encoder rate control config:\n"); + mpp_log("width %4d height %4d format %d\n", width, height, fmt); + mpp_log("rc_mode %s qp %d bps %d\n", (rc_mode) ? ("VBR") : ("CQP"), qp, bps); + mpp_log("fps in %d fps out %d gop %d\n", fps_in, fps_out, gop); + mpp_log("setup encoder stream feature config:\n"); + mpp_log("profile %d level %d cabac %d\n", profile, level, cabac_en); + + mpp_assert(width); + mpp_assert(height); + mpp_assert(qp); + + prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT | + MPP_ENC_PREP_CFG_CHANGE_FORMAT; + prep_cfg->width = width; + prep_cfg->height = height; + prep_cfg->hor_stride = MPP_ALIGN(width, 16); + prep_cfg->ver_stride = MPP_ALIGN(height, 16); + prep_cfg->format = fmt; + ret = mpi->control(mpp_ctx, MPP_ENC_SET_PREP_CFG, prep_cfg); + if (ret) { + mpp_err("setup preprocess config failed ret %d\n", ret); + goto RET; + } + + rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL; + /* auto quality */ + rc_cfg->quality = 0; + if (rc_mode == 0) { + /* 0 - constant QP */ + /* constant QP does not have bps */ + rc_cfg->rc_mode = 1; + rc_cfg->bps_target = -1; + rc_cfg->bps_max = -1; + rc_cfg->bps_min = -1; + } else if (rc_mode == 1) { + /* 1 - constant bitrate */ + /* constant bitrate has very small bps range of 1/16 bps */ + rc_cfg->rc_mode = 5; + rc_cfg->bps_target = bps; + rc_cfg->bps_max = bps * 17 / 16; + rc_cfg->bps_min = bps * 15 / 16; + } else if (rc_mode == 2) { + /* 2 - variable bitrate */ + /* variable bitrate has large bps range */ + rc_cfg->rc_mode = 3; + rc_cfg->bps_target = bps; + rc_cfg->bps_max = bps * 17 / 16; + rc_cfg->bps_min = bps * 1 / 16; + } + + /* fix input / output frame rate */ + rc_cfg->fps_in_flex = 0; + rc_cfg->fps_in_num = fps_in; + rc_cfg->fps_in_denorm = 1; + rc_cfg->fps_out_flex = 0; + rc_cfg->fps_out_num = fps_out; + rc_cfg->fps_out_denorm = 1; + rc_cfg->gop = gop; + rc_cfg->skip_cnt = 0; + ret = mpi->control(mpp_ctx, MPP_ENC_SET_RC_CFG, rc_cfg); + if (ret) { + mpp_err("setup rate control config failed ret %d\n", ret); + goto RET; + } + + codec_cfg->coding = coding; + switch (coding) { + case MPP_VIDEO_CodingAVC : { + codec_cfg->h264.change = MPP_ENC_H264_CFG_STREAM_TYPE | + MPP_ENC_H264_CFG_CHANGE_PROFILE | + MPP_ENC_H264_CFG_CHANGE_ENTROPY | + MPP_ENC_H264_CFG_CHANGE_QP_LIMIT; + codec_cfg->h264.stream_type = 1; + codec_cfg->h264.profile = profile; + codec_cfg->h264.level = level; + codec_cfg->h264.entropy_coding_mode = cabac_en; + codec_cfg->h264.cabac_init_idc = 0; + + if (rc_mode == 0) { + /* constant QP mode qp is fixed */ + codec_cfg->h264.qp_max = qp; + codec_cfg->h264.qp_min = qp; + codec_cfg->h264.qp_max_step = 0; + } else if (rc_mode == 1) { + /* constant bitrate do not limit qp range */ + codec_cfg->h264.qp_max = 48; + codec_cfg->h264.qp_min = 4; + codec_cfg->h264.qp_max_step = 51; + } else if (rc_mode == 2) { + /* variable bitrate has qp min limit */ + codec_cfg->h264.qp_max = 48; + codec_cfg->h264.qp_min = qp; + codec_cfg->h264.qp_max_step = 8; + } + codec_cfg->h264.qp_init = 26; + } break; + case MPP_VIDEO_CodingMJPEG : { + codec_cfg->jpeg.change = MPP_ENC_JPEG_CFG_CHANGE_QP; + codec_cfg->jpeg.quant = qp; + } break; + case MPP_VIDEO_CodingVP8 : + case MPP_VIDEO_CodingHEVC : + default : { + mpp_err_f("support encoder coding type %d\n", coding); + } break; + } + ret = mpi->control(mpp_ctx, MPP_ENC_SET_CODEC_CFG, codec_cfg); + if (ret) + mpp_err("setup codec config failed ret %d\n", ret); +RET: + return ret; +} + static void vpu_api_dump_yuv(VPU_FRAME *vframe, FILE *fp, RK_U8 *fp_buf, RK_S64 pts) { //!< Dump yuv @@ -186,7 +323,7 @@ VpuApiLegacy::VpuApiLegacy() : fp(NULL), fp_buf(NULL), memGroup(NULL), - enc_in_fmt(ENC_INPUT_YUV420_PLANAR), + format(MPP_FMT_YUV420P), fd_input(-1), fd_output(-1), mEosSet(0) @@ -202,6 +339,7 @@ VpuApiLegacy::VpuApiLegacy() : fp_buf = mpp_malloc(RK_U8, (MAX_WRITE_HEIGHT * MAX_WRITE_WIDTH * 2)); } + memset(&enc_cfg, 0, sizeof(enc_cfg)); vpu_api_dbg_func("leave\n"); } @@ -270,132 +408,11 @@ RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_s if (MPP_CTX_ENC == type) { EncParameter_t *param = (EncParameter_t*)ctx->private_data; - MppEncConfig mpp_cfg; + MppCodingType coding = (MppCodingType)ctx->videoCoding; + format = vpu_pic_type_remap_to_mpp((EncInputPictureType)param->format); - memset(&mpp_cfg, 0, sizeof(mpp_cfg)); - - mpp_log("setup encoder rate control config:\n"); - mpp_log("width %4d height %4d format %d\n", param->width, param->height, param->format); - mpp_log("rc_mode %s qp %d bps %d\n", (param->rc_mode) ? ("VBR") : ("CQP"), param->qp, param->bitRate); - mpp_log("fps in %d fps out %d gop %d\n", param->framerate, param->framerateout, param->intraPicRate); - mpp_log("setup encoder stream feature config:\n"); - mpp_log("profile %d level %d cabac %d\n", param->profileIdc, param->levelIdc, param->enableCabac); - - mpp_assert(param->width); - mpp_assert(param->height); - - enc_in_fmt = (EncInputPictureType)param->format; - - mpp_cfg.width = param->width; - mpp_cfg.height = param->height; - mpp_cfg.format = vpu_pic_type_remap_to_mpp(enc_in_fmt); - mpp_cfg.rc_mode = param->rc_mode; - mpp_cfg.skip_cnt = 0; - mpp_cfg.bps = param->bitRate; - mpp_cfg.fps_in = param->framerate; - if (param->framerateout) - mpp_cfg.fps_out = param->framerateout; - else - mpp_cfg.fps_out = param->framerate; - mpp_cfg.qp = (param->qp) ? (param->qp) : (26); - mpp_cfg.gop = param->intraPicRate; - - mpp_cfg.profile = param->profileIdc; - mpp_cfg.level = param->levelIdc; - mpp_cfg.cabac_en = param->enableCabac; - - mpi->control(mpp_ctx, MPP_ENC_SET_CFG, &mpp_cfg); - - MppEncPrepCfg prep_cfg; - prep_cfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT | - MPP_ENC_PREP_CFG_CHANGE_FORMAT; - prep_cfg.width = param->width; - prep_cfg.height = param->height; - prep_cfg.hor_stride = MPP_ALIGN(param->width, 16); - prep_cfg.ver_stride = MPP_ALIGN(param->height, 16); - prep_cfg.format = (MppFrameFormat)mpp_cfg.format; - - mpi->control(mpp_ctx, MPP_ENC_SET_PREP_CFG, &prep_cfg); - - MppEncRcCfg rc_cfg; - rc_cfg.change = MPP_ENC_RC_CFG_CHANGE_ALL; - rc_cfg.rc_mode = (mpp_cfg.rc_mode == 0) ? (1) : /* 0 - constant QP */ - (mpp_cfg.rc_mode == 1) ? (5) : /* 1 - constant bitrate */ - (3); /* 2 - variable bitrate */ - rc_cfg.quality = 0; /* auto quality */ - - if (rc_cfg.rc_mode == 1) { - /* constant QP does not have bps */ - rc_cfg.bps_target = -1; - rc_cfg.bps_max = -1; - rc_cfg.bps_min = -1; - } else if (rc_cfg.rc_mode == 5) { - /* constant bitrate has very small bps range of 1/16 bps */ - rc_cfg.bps_target = mpp_cfg.bps; - rc_cfg.bps_max = mpp_cfg.bps * 17 / 16; - rc_cfg.bps_min = mpp_cfg.bps * 15 / 16; - } else if (rc_cfg.rc_mode == 3) { - /* variable bitrate has large bps range */ - rc_cfg.bps_target = mpp_cfg.bps; - rc_cfg.bps_max = mpp_cfg.bps * 17 / 16; - rc_cfg.bps_min = mpp_cfg.bps * 1 / 16; - } - - /* fix input / output frame rate */ - rc_cfg.fps_in_flex = 0; - rc_cfg.fps_in_num = mpp_cfg.fps_in; - rc_cfg.fps_in_denorm = 1; - rc_cfg.fps_out_flex = 0; - rc_cfg.fps_out_num = mpp_cfg.fps_out; - rc_cfg.fps_out_denorm = 1; - - rc_cfg.gop = mpp_cfg.gop; - rc_cfg.skip_cnt = mpp_cfg.skip_cnt; - - mpi->control(mpp_ctx, MPP_ENC_SET_RC_CFG, &rc_cfg); - - MppEncCodecCfg codec_cfg; - codec_cfg.coding = (MppCodingType)ctx->videoCoding; - switch (codec_cfg.coding) { - case MPP_VIDEO_CodingAVC : { - codec_cfg.h264.change = MPP_ENC_H264_CFG_STREAM_TYPE | - MPP_ENC_H264_CFG_CHANGE_PROFILE | - MPP_ENC_H264_CFG_CHANGE_ENTROPY | - MPP_ENC_H264_CFG_CHANGE_QP_LIMIT; - codec_cfg.h264.stream_type = 1; - codec_cfg.h264.profile = mpp_cfg.profile; - codec_cfg.h264.level = mpp_cfg.level; - codec_cfg.h264.entropy_coding_mode = mpp_cfg.cabac_en; - - if (rc_cfg.rc_mode == 1) { - /* constant QP mode qp is fixed */ - codec_cfg.h264.qp_max = mpp_cfg.qp; - codec_cfg.h264.qp_min = mpp_cfg.qp; - codec_cfg.h264.qp_max_step = 0; - } else if (rc_cfg.rc_mode == 5) { - /* constant bitrate do not limit qp range */ - codec_cfg.h264.qp_max = 48; - codec_cfg.h264.qp_min = 4; - codec_cfg.h264.qp_max_step = 51; - } else if (rc_cfg.rc_mode == 3) { - /* variable bitrate has qp min limit */ - codec_cfg.h264.qp_max = 48; - codec_cfg.h264.qp_min = mpp_cfg.qp; - codec_cfg.h264.qp_max_step = 8; - } - codec_cfg.h264.qp_init = 26; - } break; - case MPP_VIDEO_CodingMJPEG : { - codec_cfg.jpeg.change = MPP_ENC_JPEG_CFG_CHANGE_QP; - codec_cfg.jpeg.quant = mpp_cfg.qp; - } break; - case MPP_VIDEO_CodingVP8 : - case MPP_VIDEO_CodingHEVC : - default : { - mpp_err_f("support encoder coding type %d\n", codec_cfg.coding); - } break; - } - mpi->control(mpp_ctx, MPP_ENC_SET_CODEC_CFG, &codec_cfg); + memcpy(&enc_cfg, param, sizeof(enc_cfg)); + vpu_api_set_enc_cfg(mpp_ctx, mpi, coding, format, param); mpi->control(mpp_ctx, MPP_ENC_GET_EXTRA_INFO, &pkt); @@ -1306,54 +1323,18 @@ RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param) MpiCmd mpicmd = MPI_CMD_BUTT; switch (cmd) { case VPU_API_ENC_SETCFG : { - /* input EncParameter_t need to be transform to MppEncConfig */ - EncParameter_t *cfg = (EncParameter_t *)param; - MppEncConfig mpp_cfg; - - mpp_cfg.size = sizeof(mpp_cfg); - mpp_cfg.version = 0; - mpp_cfg.width = cfg->width; - mpp_cfg.height = cfg->height; - mpp_cfg.hor_stride = MPP_ALIGN(cfg->width, 16); - mpp_cfg.ver_stride = MPP_ALIGN(cfg->height, 16); - mpp_cfg.format = vpu_pic_type_remap_to_mpp(enc_in_fmt); - mpp_cfg.rc_mode = cfg->rc_mode; - mpp_cfg.skip_cnt = 0; - mpp_cfg.bps = cfg->bitRate; - mpp_cfg.fps_in = cfg->framerate; - mpp_cfg.fps_out = cfg->framerateout; - mpp_cfg.qp = cfg->qp; - mpp_cfg.gop = cfg->intraPicRate; - mpp_cfg.profile = cfg->profileIdc; - mpp_cfg.level = cfg->levelIdc; - mpp_cfg.cabac_en = cfg->enableCabac; - - return mpi->control(mpp_ctx, MPP_ENC_SET_CFG, (MppParam)&mpp_cfg); + MppCodingType coding = (MppCodingType)ctx->videoCoding; + + memcpy(&enc_cfg, param, sizeof(enc_cfg)); + return vpu_api_set_enc_cfg(mpp_ctx, mpi, coding, format, &enc_cfg); } break; case VPU_API_ENC_GETCFG : { - /* input EncParameter_t need to be transform to MppEncConfig */ - EncParameter_t *cfg = (EncParameter_t *)param; - MppEncConfig mpp_cfg; - - MPP_RET ret = mpi->control(mpp_ctx, MPP_ENC_GET_CFG, (MppParam)&mpp_cfg); - - cfg->width = mpp_cfg.width; - cfg->height = mpp_cfg.height; - cfg->rc_mode = mpp_cfg.rc_mode; - cfg->bitRate = mpp_cfg.bps; - cfg->framerate = mpp_cfg.fps_in; - cfg->framerateout = mpp_cfg.fps_out; - cfg->qp = mpp_cfg.qp; - cfg->intraPicRate = mpp_cfg.gop; - cfg->profileIdc = mpp_cfg.profile; - cfg->levelIdc = mpp_cfg.level; - cfg->enableCabac = mpp_cfg.cabac_en; - cfg->cabacInitIdc = 0; - - return ret; + memcpy(param, &enc_cfg, sizeof(enc_cfg)); + return 0; } break; case VPU_API_ENC_SETFORMAT : { - enc_in_fmt = *((EncInputPictureType *)param); + EncInputPictureType type = *((EncInputPictureType *)param); + format = vpu_pic_type_remap_to_mpp(type); return 0; } break; case VPU_API_ENC_SETIDRFRAME : { diff --git a/mpp/legacy/vpu_api_legacy.h b/mpp/legacy/vpu_api_legacy.h index 50cbc2ae..1ddb53ea 100644 --- a/mpp/legacy/vpu_api_legacy.h +++ b/mpp/legacy/vpu_api_legacy.h @@ -77,13 +77,15 @@ private: RK_U8 *fp_buf; /* encoder parameters */ - MppBufferGroup memGroup; - EncInputPictureType enc_in_fmt; + MppBufferGroup memGroup; + MppFrameFormat format; RK_S32 fd_input; RK_S32 fd_output; RK_U32 mEosSet; + + EncParameter_t enc_cfg; }; #endif /*_VPU_API_H_*/ diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index 2142a23f..bde574ea 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -304,12 +304,14 @@ MPP_RET Mpp::put_frame(MppFrame frame) MPP_RET ret = MPP_NOK; MppTask task = NULL; + /* poll input port for valid task */ ret = poll(MPP_PORT_INPUT, mInputBlock); if (ret) { mpp_log_f("poll on set timeout %d ret %d\n", mInputBlock, ret); goto RET; } + /* dequeue task for setup */ ret = dequeue(MPP_PORT_INPUT, &task); if (ret || NULL == task) { mpp_log_f("dequeue on set ret %d task %p\n", ret, task); @@ -318,24 +320,28 @@ MPP_RET Mpp::put_frame(MppFrame frame) mpp_assert(task); + /* setup task */ ret = mpp_task_meta_set_frame(task, KEY_INPUT_FRAME, frame); if (ret) { mpp_log_f("set input frame to task ret %d\n", ret); goto RET; } + /* enqueue valid task to encoder */ ret = enqueue(MPP_PORT_INPUT, task); if (ret) { mpp_log_f("enqueue ret %d\n", ret); goto RET; } - ret = poll(MPP_PORT_INPUT, mInputBlock); + /* wait enqueued task finished */ + ret = poll(MPP_PORT_INPUT, MPP_POLL_BLOCK); if (ret) { mpp_log_f("poll on get timeout %d ret %d\n", mInputBlock, ret); goto RET; } + /* get previous enqueued task back */ ret = dequeue(MPP_PORT_INPUT, &task); if (ret) { mpp_log_f("dequeue on get ret %d\n", ret); @@ -345,6 +351,7 @@ MPP_RET Mpp::put_frame(MppFrame frame) if (mInputBlock != MPP_POLL_NON_BLOCK) mpp_assert(task); + /* clear the enqueued task back */ if (task) { ret = mpp_task_meta_get_frame(task, KEY_INPUT_FRAME, &frame); if (frame) { @@ -353,6 +360,20 @@ MPP_RET Mpp::put_frame(MppFrame frame) } } + /* enqueue empty task back to encoder */ + ret = enqueue(MPP_PORT_INPUT, task); + if (ret) { + mpp_log_f("enqueue on get ret %d\n", ret); + goto RET; + } + + /* + * This process can be replaced by simple poll operation + * NOTE: But here is a risk that the frame pointer is still in task + * but it is a invalid pointer + * The safer way is to dequeue the task and destroy Mppframe + * with it then enqueue task back to the port + */ RET: return ret; } @@ -367,7 +388,9 @@ MPP_RET Mpp::get_packet(MppPacket *packet) ret = poll(MPP_PORT_OUTPUT, mOutputBlock); if (ret) { - mpp_log_f("poll on get timeout %d ret %d\n", mOutputBlock, ret); + // NOTE: Do not treat poll failure as error. Just clear output + ret = MPP_OK; + *packet = NULL; goto RET; } diff --git a/mpp/mpp.h b/mpp/mpp.h index 05c85120..e76be09f 100644 --- a/mpp/mpp.h +++ b/mpp/mpp.h @@ -143,10 +143,6 @@ private: RK_U32 mParserNeedSplit; RK_U32 mParserInternalPts; /* for MPEG2/MPEG4 */ - /* encoder paramter before init */ - MppEncConfig mControlCfg; - RK_U32 mControlCfgReady; - MPP_RET control_mpp(MpiCmd cmd, MppParam param); MPP_RET control_osal(MpiCmd cmd, MppParam param); MPP_RET control_codec(MpiCmd cmd, MppParam param); diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index 4aa93966..66fba579 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -67,7 +67,6 @@ typedef struct { // base flow context MppCtx ctx; MppApi *mpi; - MppEncConfig mpp_cfg; MppEncPrepCfg prep_cfg; MppEncRcCfg rc_cfg; MppEncCodecCfg codec_cfg; diff --git a/test/mpi_rc_test.c b/test/mpi_rc_test.c index fabbc367..9a691e8d 100644 --- a/test/mpi_rc_test.c +++ b/test/mpi_rc_test.c @@ -107,16 +107,16 @@ static OptionInfo mpi_rc_cmd[] = { {"c", "rc test item", "rc test item flags, one bit each item: roi|force_intra|gop|fps|bps"}, }; -static MPP_RET mpi_rc_read_yuv_image(RK_U8 *buf, MppEncConfig *mpp_cfg, FILE *fp) +static MPP_RET mpi_rc_read_yuv_image(RK_U8 *buf, MppEncPrepCfg *prep_cfg, FILE *fp) { MPP_RET ret = MPP_OK; RK_U32 read_size; RK_U32 row = 0; - RK_U32 width = mpp_cfg->width; - RK_U32 height = mpp_cfg->height; - RK_U32 hor_stride = mpp_cfg->hor_stride; - RK_U32 ver_stride = mpp_cfg->ver_stride; - MppFrameFormat fmt = mpp_cfg->format; + RK_U32 width = prep_cfg->width; + RK_U32 height = prep_cfg->height; + RK_U32 hor_stride = prep_cfg->hor_stride; + RK_U32 ver_stride = prep_cfg->ver_stride; + MppFrameFormat fmt = prep_cfg->format; RK_U8 *buf_y = buf; RK_U8 *buf_u = buf_y + hor_stride * ver_stride; // NOTE: diff from gen_yuv_image RK_U8 *buf_v = buf_u + hor_stride * ver_stride / 4; // NOTE: diff from gen_yuv_image @@ -180,14 +180,14 @@ err: return ret; } -static MPP_RET gen_yuv_image(RK_U8 *buf, MppEncConfig *mpp_cfg, RK_U32 frame_count) +static MPP_RET gen_yuv_image(RK_U8 *buf, MppEncPrepCfg *prep_cfg, RK_U32 frame_count) { MPP_RET ret = MPP_OK; - RK_U32 width = mpp_cfg->width; - RK_U32 height = mpp_cfg->height; - RK_U32 hor_stride = mpp_cfg->hor_stride; - RK_U32 ver_stride = mpp_cfg->ver_stride; - MppFrameFormat fmt = mpp_cfg->format; + RK_U32 width = prep_cfg->width; + RK_U32 height = prep_cfg->height; + RK_U32 hor_stride = prep_cfg->hor_stride; + RK_U32 ver_stride = prep_cfg->ver_stride; + MppFrameFormat fmt = prep_cfg->format; RK_U8 *buf_y = buf; RK_U8 *buf_c = buf + hor_stride * ver_stride; RK_U32 x, y; @@ -537,34 +537,6 @@ static void mpi_rc_log_stat(MpiRcTestCtx *ctx, RK_U32 frame_count, RK_U32 one_se } } -#if 0 -static void mpi_rc_change_cfg(MppEncConfig *mpp_cfg, MpiRcTestCmd *cmd, RK_U32 frame_count) -{ - RK_U32 item = cmd->item_flag; - if (item & MPI_RC_ITEM_BPS) { - mpp_log_f("change bps"); - } - - if (item & MPI_RC_ITEM_FPS) { - mpp_log_f("change fps"); - } - - if (item & MPI_RC_ITEM_GOP) { - mpp_log_f("change gop"); - } - - if (item & MPI_RC_ITEM_FORCE_I) { - mpp_log_f("change fps"); - } - - if (item & MPI_RC_ITEM_ROI) { - mpp_log_f("change roi"); - } - (void)mpp_cfg; - (void)frame_count; -} -#endif - static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) { MPP_RET ret = MPP_OK; @@ -587,7 +559,6 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) MppApi *enc_mpi = NULL; MppCtx dec_ctx = NULL; MppApi *dec_mpi = NULL; - MppEncConfig mpp_cfg; // input / output RK_S32 i; @@ -618,12 +589,15 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) RK_U32 frame_count = 0; RK_U64 stream_size = 0; RK_U64 stream_size_1s = 0; - MppEncRcCfg rc_cfg; - MppEncPrepCfg prep_cfg; - MppEncCodecCfg codec_cfg; + + // runtime config + MppEncCfgSet cfg; + MppEncRcCfg *rc_cfg = &cfg.rc; + MppEncPrepCfg *prep_cfg = &cfg.prep; + MppEncCodecCfg *codec_cfg = &cfg.codec; + RK_S32 fps = 30; mpp_log_f("test start width %d height %d codingtype %d\n", width, height, type); - ret = mpp_buffer_group_get_internal(&frm_grp, MPP_BUFFER_TYPE_ION); if (ret) { mpp_err("failed to get buffer group for input frame ret %d\n", ret); @@ -731,77 +705,54 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) goto MPP_TEST_OUT; } - memset(&mpp_cfg, 0, sizeof(mpp_cfg)); - mpp_cfg.size = sizeof(mpp_cfg); - mpp_cfg.width = width; - mpp_cfg.height = height; - mpp_cfg.hor_stride = hor_stride; - mpp_cfg.ver_stride = ver_stride; - mpp_cfg.format = fmt; - mpp_cfg.rc_mode = 0; - mpp_cfg.skip_cnt = 0; - mpp_cfg.fps_in = 30; - mpp_cfg.fps_out = 30; - mpp_cfg.bps = width * height * 2 * mpp_cfg.fps_in; - mpp_cfg.qp = (type == MPP_VIDEO_CodingMJPEG) ? (10) : (24); - mpp_cfg.gop = 60; - - mpp_cfg.profile = 100; - mpp_cfg.level = 41; - mpp_cfg.cabac_en = 1; - - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_CFG, &mpp_cfg); + ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_SEI_CFG, &sei_mode); if (MPP_OK != ret) { - mpp_err("mpi control enc set cfg failed\n"); + mpp_err("mpi control enc set sei cfg failed\n"); goto MPP_TEST_OUT; } - rc_cfg.change = MPP_ENC_RC_CFG_CHANGE_ALL; - rc_cfg.rc_mode = 3; - rc_cfg.quality = 0; - rc_cfg.bps_target = 2000000; - rc_cfg.bps_max = 3000000; - rc_cfg.bps_min = 1000000; - rc_cfg.fps_in_denorm = 1; - rc_cfg.fps_out_denorm = 1; - rc_cfg.fps_in_num = 30; - rc_cfg.fps_out_num = 30; - rc_cfg.fps_in_flex = 0; - rc_cfg.fps_out_flex = 0; - rc_cfg.gop = 30; - rc_cfg.skip_cnt = 0; + rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL; + rc_cfg->rc_mode = 3; + rc_cfg->quality = 0; + rc_cfg->bps_target = 2000000; + rc_cfg->bps_max = 3000000; + rc_cfg->bps_min = 1000000; + rc_cfg->fps_in_denorm = 1; + rc_cfg->fps_out_denorm = 1; + rc_cfg->fps_in_num = fps; + rc_cfg->fps_out_denorm = fps; + rc_cfg->fps_in_flex = 0; + rc_cfg->fps_out_flex = 0; + rc_cfg->gop = 30; + rc_cfg->skip_cnt = 0; - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_RC_CFG, &rc_cfg); - if (ret) { - mpp_err("mpi control enc set rc cfg failed ret %d\n", ret); - goto MPP_TEST_OUT; - } + ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_RC_CFG, rc_cfg); - prep_cfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT | - MPP_ENC_PREP_CFG_CHANGE_FORMAT; - prep_cfg.width = width; - prep_cfg.height = height; - prep_cfg.hor_stride = hor_stride; - prep_cfg.ver_stride = ver_stride; - prep_cfg.format = fmt; + prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT | + MPP_ENC_PREP_CFG_CHANGE_FORMAT; + prep_cfg->width = width; + prep_cfg->height = height; + prep_cfg->hor_stride = hor_stride; + prep_cfg->ver_stride = ver_stride; + prep_cfg->format = fmt; - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_PREP_CFG, &prep_cfg); + ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_PREP_CFG, prep_cfg); if (ret) { mpp_err("mpi control enc set prep cfg failed ret %d\n", ret); goto MPP_TEST_OUT; } - codec_cfg.coding = type; - codec_cfg.h264.change = MPP_ENC_H264_CFG_CHANGE_PROFILE | - MPP_ENC_H264_CFG_CHANGE_ENTROPY | - MPP_ENC_H264_CFG_CHANGE_QP_LIMIT; + codec_cfg->coding = type; + codec_cfg->h264.change = MPP_ENC_H264_CFG_CHANGE_PROFILE | + MPP_ENC_H264_CFG_CHANGE_ENTROPY | + MPP_ENC_H264_CFG_CHANGE_QP_LIMIT; /* * H.264 profile_idc parameter * 66 - Baseline profile * 77 - Main profile * 100 - High profile */ - codec_cfg.h264.profile = 100; + codec_cfg->h264.profile = 100; /* * H.264 level_idc parameter * 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps @@ -810,54 +761,33 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) * 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps * 50 / 51 / 52 - 4K@30fps */ - codec_cfg.h264.level = 40; - codec_cfg.h264.entropy_coding_mode = 1; - codec_cfg.h264.cabac_init_idc = 0; + codec_cfg->h264.level = 40; + codec_cfg->h264.entropy_coding_mode = 1; + codec_cfg->h264.cabac_init_idc = 0; - if (rc_cfg.rc_mode == 1) { + if (rc_cfg->rc_mode == 1) { /* constant QP mode qp is fixed */ - codec_cfg.h264.qp_max = 26; - codec_cfg.h264.qp_min = 26; - codec_cfg.h264.qp_max_step = 0; - } else if (rc_cfg.rc_mode == 5) { + codec_cfg->h264.qp_max = 26; + codec_cfg->h264.qp_min = 26; + codec_cfg->h264.qp_max_step = 0; + } else if (rc_cfg->rc_mode == 5) { /* constant bitrate do not limit qp range */ - codec_cfg.h264.qp_max = 48; - codec_cfg.h264.qp_min = 4; - codec_cfg.h264.qp_max_step = 16; - } else if (rc_cfg.rc_mode == 3) { + codec_cfg->h264.qp_max = 48; + codec_cfg->h264.qp_min = 4; + codec_cfg->h264.qp_max_step = 16; + } else if (rc_cfg->rc_mode == 3) { /* variable bitrate has qp min limit */ - codec_cfg.h264.qp_max = 40; - codec_cfg.h264.qp_min = 12; - codec_cfg.h264.qp_max_step = 8; + codec_cfg->h264.qp_max = 40; + codec_cfg->h264.qp_min = 12; + codec_cfg->h264.qp_max_step = 8; } - codec_cfg.h264.qp_init = 26; - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_CODEC_CFG, &codec_cfg); + codec_cfg->h264.qp_init = 26; + ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_CODEC_CFG, codec_cfg); if (ret) { mpp_err("mpi control enc set codec cfg failed ret %d\n", ret); goto MPP_TEST_OUT; } - /* optional */ - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_SEI_CFG, &sei_mode); - if (ret) { - mpp_err("mpi control enc set sei cfg failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - prep_cfg.change = MPP_ENC_PREP_CFG_CHANGE_INPUT | - MPP_ENC_PREP_CFG_CHANGE_FORMAT; - prep_cfg.width = width; - prep_cfg.height = height; - prep_cfg.hor_stride = hor_stride; - prep_cfg.ver_stride = ver_stride; - prep_cfg.format = fmt; - - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_PREP_CFG, &prep_cfg); - if (ret) { - mpp_err("mpi control enc set prep cfg failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - ret = enc_mpi->control(enc_ctx, MPP_ENC_GET_EXTRA_INFO, &packet); if (MPP_OK != ret) { mpp_err("mpi control enc get extra info failed\n"); @@ -906,13 +836,13 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) i = 0; if (fp_input) { - ret = mpi_rc_read_yuv_image(buf, &mpp_cfg, fp_input); + ret = mpi_rc_read_yuv_image(buf, prep_cfg, fp_input); if (MPP_OK != ret || feof(fp_input)) { mpp_log("found last frame\n"); frm_eos = 1; } } else { - ret = gen_yuv_image(buf, &mpp_cfg, frame_count); + ret = gen_yuv_image(buf, prep_cfg, frame_count); if (ret) goto MPP_TEST_OUT; } @@ -984,7 +914,7 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) stream_size += len; stream_size_1s += len; stat->frame_size = len; - if ((frame_count + 1) % mpp_cfg.fps_in == 0) { + if ((frame_count + 1) % fps == 0) { stat->ins_bitrate = stream_size_1s; stream_size_1s = 0; } @@ -1028,15 +958,10 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) mpp_log("decode_get_frame get info changed found\n"); dec_mpi->control(dec_ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); } else { - /* - mpp_log_f("decoded frame %d width %d height %d\n", - frame_count, mpp_frame_get_width(frame_out), - mpp_frame_get_height(frame_out)); - */ if (fp_dec_out) dump_mpp_frame_to_file(frame_out, fp_dec_out); mpi_rc_calc_stat(ctx, frame_in, frame_out); - mpi_rc_log_stat(ctx, frame_count, (frame_count + 1) % mpp_cfg.fps_in == 0, + mpi_rc_log_stat(ctx, frame_count, (frame_count + 1) % fps == 0, frame_count + 1 == num_frames); dec_get_frm = 1; } @@ -1090,7 +1015,7 @@ static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) goto MPP_TEST_OUT; } - stat->avg_bitrate = (RK_U64)stream_size * mpp_cfg.fps_out / frame_count; + stat->avg_bitrate = (RK_U64)stream_size * fps / frame_count; mpp_log_f("avg_bitrate %d byte/s", stat->avg_bitrate); if (fp_stat) fprintf(fp_stat, "%d\n", stat->avg_bitrate); @@ -1152,7 +1077,7 @@ MPP_TEST_OUT: if (MPP_OK == ret) mpp_log("test success total frame %d bps %lld\n", - frame_count, (RK_U64)((stream_size * 8 * mpp_cfg.fps_out) / frame_count)); + frame_count, (RK_U64)((stream_size * 8 * fps) / frame_count)); else mpp_err_f("failed ret %d\n", ret); diff --git a/test/mpi_test.c b/test/mpi_test.c index ba538ac5..dd82542e 100644 --- a/test/mpi_test.c +++ b/test/mpi_test.c @@ -36,7 +36,6 @@ int mpi_test() MPP_RET ret = MPP_NOK; MppCtx ctx = NULL; MppApi *mpi = NULL; - MppEncConfig cfg; MppPacket dec_in = NULL; MppFrame dec_out = NULL; @@ -190,17 +189,6 @@ int mpi_test() goto MPP_TEST_FAILED; } - memset(&cfg, 0, sizeof(cfg)); - - cmd = MPP_ENC_SET_CFG; - param = &cfg; - - ret = mpi->control(ctx, cmd, param); - if (MPP_OK != ret) { - mpp_err("mpi->control failed\n"); - goto MPP_TEST_FAILED; - } - // interface with both input and output for (i = 0; i < MPI_ENC_LOOP_COUNT; i++) { mpp_frame_init(&enc_in);