From 83e2724158771bcfff6c3552b1e7b76c6539d6ad Mon Sep 17 00:00:00 2001 From: Herman Chen Date: Wed, 13 May 2020 16:23:35 +0800 Subject: [PATCH] [mpp_enc_cfg]: Add MppEncCfg control 1. Add h264e process function. 1. Add h265e process function. 2. Add jpege process function. 2. Add vpu_api_legacy support. 3. Clear input MppEncCfgSet when MPP_ENC_SET_CFG is finished. Change-Id: Ida1234c351483bd9f96a75bc77e90ca2d75ec38b Signed-off-by: Herman Chen --- inc/rk_mpi_cmd.h | 16 +- mpp/base/mpp_enc_cfg.cpp | 4 +- mpp/codec/enc/h264/h264e_api_v2.c | 429 ++++++++++++++++-------------- mpp/codec/enc/h265/h265e_api_v2.c | 312 +++++++++++++--------- mpp/codec/enc/jpeg/jpege_api_v2.c | 345 +++++++++++++----------- mpp/codec/mpp_enc.cpp | 8 +- mpp/codec/mpp_enc_v2.cpp | 5 +- mpp/legacy/vpu_api_legacy.cpp | 94 +++++-- mpp/legacy/vpu_api_legacy.h | 4 +- 9 files changed, 705 insertions(+), 512 deletions(-) diff --git a/inc/rk_mpi_cmd.h b/inc/rk_mpi_cmd.h index 9530fb6f..6ae2ad92 100644 --- a/inc/rk_mpi_cmd.h +++ b/inc/rk_mpi_cmd.h @@ -96,14 +96,14 @@ typedef enum { MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, /* basic encoder setup control */ - MPP_ENC_SET_CFG, /* set MppEncCfgSet structure */ - MPP_ENC_GET_CFG, /* get MppEncCfgSet structure */ - MPP_ENC_SET_PREP_CFG, /* set MppEncPrepCfg structure */ - MPP_ENC_GET_PREP_CFG, /* get MppEncPrepCfg structure */ - MPP_ENC_SET_RC_CFG, /* set MppEncRcCfg structure */ - MPP_ENC_GET_RC_CFG, /* get MppEncRcCfg structure */ - MPP_ENC_SET_CODEC_CFG, /* set MppEncCodecCfg structure */ - MPP_ENC_GET_CODEC_CFG, /* get MppEncCodecCfg structure */ + MPP_ENC_SET_CFG, /* set MppEncCfg structure */ + MPP_ENC_GET_CFG, /* get MppEncCfg structure */ + MPP_ENC_SET_PREP_CFG, /* deprecated set MppEncPrepCfg structure, use MPP_ENC_SET_CFG instead */ + MPP_ENC_GET_PREP_CFG, /* deprecated get MppEncPrepCfg structure, use MPP_ENC_GET_CFG instead */ + MPP_ENC_SET_RC_CFG, /* deprecated set MppEncRcCfg structure, use MPP_ENC_SET_CFG instead */ + MPP_ENC_GET_RC_CFG, /* deprecated get MppEncRcCfg structure, use MPP_ENC_GET_CFG instead */ + MPP_ENC_SET_CODEC_CFG, /* deprecated set MppEncCodecCfg structure, use MPP_ENC_SET_CFG instead */ + MPP_ENC_GET_CODEC_CFG, /* deprecated get MppEncCodecCfg structure, use MPP_ENC_GET_CFG instead */ /* runtime encoder setup control */ MPP_ENC_SET_IDR_FRAME, /* next frame will be encoded as intra frame */ MPP_ENC_SET_OSD_LEGACY_0, /* deprecated */ diff --git a/mpp/base/mpp_enc_cfg.cpp b/mpp/base/mpp_enc_cfg.cpp index 7f6c0311..93fd2463 100644 --- a/mpp/base/mpp_enc_cfg.cpp +++ b/mpp/base/mpp_enc_cfg.cpp @@ -116,7 +116,7 @@ static const char *cfg_func_names[] = { MPP_RET set_##base##_##name(MppEncCfgSet *cfg, in_type name) \ { \ mpp_enc_cfg_dbg_func("enter\n"); \ - if (cfg->field0.field1 != (in_type)name) { \ + if (cfg->field0.field1 != (in_type)name || SET_##func_type == SET_PTR) { \ cfg->field0.field1 = (in_type)name; \ cfg->field0.change |= flag; \ } \ @@ -171,6 +171,8 @@ static const char *cfg_func_names[] = { ENTRY(prep, color, S32, MppFrameColorSpace,MPP_ENC_PREP_CFG_CHANGE_FORMAT, prep, color) \ ENTRY(prep, rotation, S32, MppEncRotationCfg, MPP_ENC_PREP_CFG_CHANGE_ROTATION, prep, rotation) \ ENTRY(prep, mirroring, S32, RK_S32, MPP_ENC_PREP_CFG_CHANGE_MIRRORING, prep, mirroring) \ + /* codec coding config */ \ + ENTRY(codec, type, S32, MppCodingType, 0, codec, coding) \ /* h264 config */ \ ENTRY(h264, stream_type, S32, RK_S32, MPP_ENC_H264_CFG_STREAM_TYPE, codec.h264, stream_type) \ ENTRY(h264, profile, S32, RK_S32, MPP_ENC_H264_CFG_CHANGE_PROFILE, codec.h264, profile) \ diff --git a/mpp/codec/enc/h264/h264e_api_v2.c b/mpp/codec/enc/h264/h264e_api_v2.c index 92943fd9..6cd96eb2 100644 --- a/mpp/codec/enc/h264/h264e_api_v2.c +++ b/mpp/codec/enc/h264/h264e_api_v2.c @@ -36,6 +36,7 @@ #include "rc.h" #include "enc_impl_api.h" +#include "mpp_enc_cfg_impl.h" RK_U32 h264e_debug = 0; @@ -192,221 +193,263 @@ static MPP_RET h264e_deinit(void *ctx) return MPP_OK; } +static MPP_RET h264e_proc_prep_cfg(MppEncPrepCfg *dst, MppEncPrepCfg *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + mpp_assert(change); + if (change) { + MppEncPrepCfg bak = *dst; + + if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT) + dst->format = src->format; + + if (change & MPP_ENC_PREP_CFG_CHANGE_ROTATION) + dst->rotation = src->rotation; + + if (change & MPP_ENC_PREP_CFG_CHANGE_MIRRORING) + dst->mirroring = src->mirroring; + + if (change & MPP_ENC_PREP_CFG_CHANGE_DENOISE) + dst->denoise = src->denoise; + + if (change & MPP_ENC_PREP_CFG_CHANGE_SHARPEN) + dst->sharpen = src->sharpen; + + if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) { + if (dst->rotation == MPP_ENC_ROT_90 || dst->rotation == MPP_ENC_ROT_270) { + dst->width = src->height; + dst->height = src->width; + } else { + dst->width = src->width; + dst->height = src->height; + } + dst->hor_stride = src->hor_stride; + dst->ver_stride = src->ver_stride; + } + + dst->change |= change; + + // parameter checking + if (dst->width > dst->hor_stride || dst->height > dst->ver_stride) { + mpp_err("invalid size w:h [%d:%d] stride [%d:%d]\n", + dst->width, dst->height, dst->hor_stride, dst->ver_stride); + ret = MPP_ERR_VALUE; + } + + if (ret) { + mpp_err_f("failed to accept new prep config\n"); + *dst = bak; + } else { + mpp_log_f("MPP_ENC_SET_PREP_CFG w:h [%d:%d] stride [%d:%d]\n", + dst->width, dst->height, + dst->hor_stride, dst->ver_stride); + } + } + + return ret; +} + +static MPP_RET h264e_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + if (change) { + MppEncRcCfg bak = *dst; + + if (change & MPP_ENC_RC_CFG_CHANGE_RC_MODE) + dst->rc_mode = src->rc_mode; + + if (change & MPP_ENC_RC_CFG_CHANGE_QUALITY) + dst->quality = src->quality; + + if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { + dst->bps_target = src->bps_target; + dst->bps_max = src->bps_max; + dst->bps_min = src->bps_min; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_IN) { + dst->fps_in_flex = src->fps_in_flex; + dst->fps_in_num = src->fps_in_num; + dst->fps_in_denorm = src->fps_in_denorm; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { + dst->fps_out_flex = src->fps_out_flex; + dst->fps_out_num = src->fps_out_num; + dst->fps_out_denorm = src->fps_out_denorm; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_GOP) + dst->gop = src->gop; + + if (change & MPP_ENC_RC_CFG_CHANGE_SKIP_CNT) + dst->skip_cnt = src->skip_cnt; + + // parameter checking + if (dst->rc_mode >= MPP_ENC_RC_MODE_BUTT) { + mpp_err("invalid rc mode %d should be RC_MODE_VBR or RC_MODE_CBR\n", + src->rc_mode); + ret = MPP_ERR_VALUE; + } + if (dst->quality >= MPP_ENC_RC_QUALITY_BUTT) { + mpp_err("invalid quality %d should be from QUALITY_WORST to QUALITY_BEST\n", + dst->quality); + ret = MPP_ERR_VALUE; + } + if (dst->rc_mode != MPP_ENC_RC_MODE_FIXQP) { + if ((dst->bps_target >= 100 * SZ_1M || dst->bps_target <= 1 * SZ_1K) || + (dst->bps_max >= 100 * SZ_1M || dst->bps_max <= 1 * SZ_1K) || + (dst->bps_min >= 100 * SZ_1M || dst->bps_min <= 1 * SZ_1K)) { + mpp_err("invalid bit per second %d [%d:%d] out of range 1K~100M\n", + dst->bps_target, dst->bps_min, dst->bps_max); + ret = MPP_ERR_VALUE; + } + } + + dst->change |= change; + + if (ret) { + mpp_err_f("failed to accept new rc config\n"); + *dst = bak; + } else { + mpp_log_f("MPP_ENC_SET_RC_CFG bps %d [%d : %d] fps [%d:%d] gop %d\n", + dst->bps_target, dst->bps_min, dst->bps_max, + dst->fps_in_num, dst->fps_out_num, dst->gop); + } + } + + return ret; +} + +static MPP_RET h264e_proc_h264_cfg(MppEncH264Cfg *dst, MppEncH264Cfg *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + // TODO: do codec check first + if (change & MPP_ENC_H264_CFG_STREAM_TYPE) + dst->stream_type = src->stream_type; + if (change & MPP_ENC_H264_CFG_CHANGE_PROFILE) { + dst->profile = src->profile; + dst->level = src->level; + } + if (change & MPP_ENC_H264_CFG_CHANGE_ENTROPY) { + dst->entropy_coding_mode = src->entropy_coding_mode; + dst->cabac_init_idc = src->cabac_init_idc; + } + if (change & MPP_ENC_H264_CFG_CHANGE_TRANS_8x8) + dst->transform8x8_mode = src->transform8x8_mode; + if (change & MPP_ENC_H264_CFG_CHANGE_CONST_INTRA) + dst->constrained_intra_pred_mode = src->constrained_intra_pred_mode; + if (change & MPP_ENC_H264_CFG_CHANGE_CHROMA_QP) { + dst->chroma_cb_qp_offset = src->chroma_cb_qp_offset; + dst->chroma_cr_qp_offset = src->chroma_cr_qp_offset; + } + if (change & MPP_ENC_H264_CFG_CHANGE_DEBLOCKING) { + dst->deblock_disable = src->deblock_disable; + dst->deblock_offset_alpha = src->deblock_offset_alpha; + dst->deblock_offset_beta = src->deblock_offset_beta; + } + if (change & MPP_ENC_H264_CFG_CHANGE_LONG_TERM) + dst->use_longterm = src->use_longterm; + + if (change & MPP_ENC_H264_CFG_CHANGE_SCALING_LIST) + dst->scaling_list_mode = src->scaling_list_mode; + + if (change & MPP_ENC_H264_CFG_CHANGE_QP_LIMIT) { + dst->qp_init = src->qp_init; + dst->qp_max = src->qp_max; + dst->qp_min = src->qp_min; + dst->qp_max_step = src->qp_max_step; + } + if (change & MPP_ENC_H264_CFG_CHANGE_INTRA_REFRESH) { + dst->intra_refresh_mode = src->intra_refresh_mode; + dst->intra_refresh_arg = src->intra_refresh_arg; + } + if (change & MPP_ENC_H264_CFG_CHANGE_SLICE_MODE) { + dst->slice_mode = src->slice_mode; + dst->slice_arg = src->slice_arg; + } + if (change & MPP_ENC_H264_CFG_CHANGE_VUI) { + dst->vui = src->vui; + } + if (change & MPP_ENC_H264_CFG_CHANGE_SEI) { + dst->sei = src->sei; + } + + dst->change |= change; + return ret; +} + +static MPP_RET h264e_proc_split_cfg(MppEncSliceSplit *dst, MppEncSliceSplit *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + if (change & MPP_ENC_SPLIT_CFG_CHANGE_MODE) { + dst->split_mode = src->split_mode; + dst->split_arg = src->split_arg; + } + + if (change & MPP_ENC_SPLIT_CFG_CHANGE_ARG) + dst->split_arg = src->split_arg; + + dst->change |= change; + + return ret; +} + static MPP_RET h264e_proc_cfg(void *ctx, MpiCmd cmd, void *param) { MPP_RET ret = MPP_OK; H264eCtx *p = (H264eCtx *)ctx; + MppEncCfgSet *cfg = p->cfg; h264e_dbg_func("enter ctx %p cmd %x param %p\n", ctx, cmd, param); switch (cmd) { case MPP_ENC_SET_CFG : { + MppEncCfgImpl *impl = (MppEncCfgImpl *)param; + MppEncCfgSet *src = &impl->cfg; + + if (src->prep.change) { + ret |= h264e_proc_prep_cfg(&cfg->prep, &src->prep); + src->prep.change = 0; + } + if (src->rc.change) { + ret |= h264e_proc_rc_cfg(&cfg->rc, &src->rc); + src->rc.change = 0; + } + if (src->codec.h264.change) { + ret |= h264e_proc_h264_cfg(&cfg->codec.h264, &src->codec.h264); + src->codec.h264.change = 0; + } + if (src->split.change) { + ret |= h264e_proc_split_cfg(&cfg->split, &src->split); + src->split.change = 0; + } } break; case MPP_ENC_SET_PREP_CFG : { - MppEncPrepCfg *src = (MppEncPrepCfg *)param; - RK_U32 change = src->change; - - mpp_assert(change); - if (change) { - MppEncPrepCfg *dst = &p->cfg->prep; - MppEncPrepCfg bak = p->cfg->prep; - - if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT) - dst->format = src->format; - - if (change & MPP_ENC_PREP_CFG_CHANGE_ROTATION) - dst->rotation = src->rotation; - - if (change & MPP_ENC_PREP_CFG_CHANGE_MIRRORING) - dst->mirroring = src->mirroring; - - if (change & MPP_ENC_PREP_CFG_CHANGE_DENOISE) - dst->denoise = src->denoise; - - if (change & MPP_ENC_PREP_CFG_CHANGE_SHARPEN) - dst->sharpen = src->sharpen; - - if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) { - if (dst->rotation == MPP_ENC_ROT_90 || dst->rotation == MPP_ENC_ROT_270) { - dst->width = src->height; - dst->height = src->width; - } else { - dst->width = src->width; - dst->height = src->height; - } - dst->hor_stride = src->hor_stride; - dst->ver_stride = src->ver_stride; - } - - dst->change |= change; - - // parameter checking - if (dst->width > dst->hor_stride || dst->height > dst->ver_stride) { - mpp_err("invalid size w:h [%d:%d] stride [%d:%d]\n", - dst->width, dst->height, dst->hor_stride, dst->ver_stride); - ret = MPP_ERR_VALUE; - } - - if (ret) { - mpp_err_f("failed to accept new prep config\n"); - *dst = bak; - break; - } - mpp_log_f("MPP_ENC_SET_PREP_CFG w:h [%d:%d] stride [%d:%d]\n", - dst->width, dst->height, dst->hor_stride, dst->ver_stride); - } + ret = h264e_proc_prep_cfg(&cfg->prep, param); } break; case MPP_ENC_SET_RC_CFG : { - MppEncRcCfg *src = (MppEncRcCfg *)param; - RK_U32 change = src->change; - - if (change) { - MppEncRcCfg *dst = &p->cfg->rc; - MppEncRcCfg bak = p->cfg->rc; - - if (change & MPP_ENC_RC_CFG_CHANGE_RC_MODE) - dst->rc_mode = src->rc_mode; - - if (change & MPP_ENC_RC_CFG_CHANGE_QUALITY) - dst->quality = src->quality; - - if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { - dst->bps_target = src->bps_target; - dst->bps_max = src->bps_max; - dst->bps_min = src->bps_min; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_FPS_IN) { - dst->fps_in_flex = src->fps_in_flex; - dst->fps_in_num = src->fps_in_num; - dst->fps_in_denorm = src->fps_in_denorm; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { - dst->fps_out_flex = src->fps_out_flex; - dst->fps_out_num = src->fps_out_num; - dst->fps_out_denorm = src->fps_out_denorm; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_GOP) - dst->gop = src->gop; - - if (change & MPP_ENC_RC_CFG_CHANGE_SKIP_CNT) - dst->skip_cnt = src->skip_cnt; - - // parameter checking - if (dst->rc_mode >= MPP_ENC_RC_MODE_BUTT) { - mpp_err("invalid rc mode %d should be RC_MODE_VBR or RC_MODE_CBR\n", - src->rc_mode); - ret = MPP_ERR_VALUE; - } - if (dst->quality >= MPP_ENC_RC_QUALITY_BUTT) { - mpp_err("invalid quality %d should be from QUALITY_WORST to QUALITY_BEST\n", - dst->quality); - ret = MPP_ERR_VALUE; - } - if (dst->rc_mode != MPP_ENC_RC_MODE_FIXQP) { - if ((dst->bps_target >= 100 * SZ_1M || dst->bps_target <= 1 * SZ_1K) || - (dst->bps_max >= 100 * SZ_1M || dst->bps_max <= 1 * SZ_1K) || - (dst->bps_min >= 100 * SZ_1M || dst->bps_min <= 1 * SZ_1K)) { - mpp_err("invalid bit per second %d [%d:%d] out of range 1K~100M\n", - dst->bps_target, dst->bps_min, dst->bps_max); - ret = MPP_ERR_VALUE; - } - } - - dst->change |= change; - - if (ret) { - mpp_err_f("failed to accept new rc config\n"); - *dst = bak; - break; - } - - mpp_log_f("MPP_ENC_SET_RC_CFG bps %d [%d : %d] fps [%d:%d] gop %d\n", - dst->bps_target, dst->bps_min, dst->bps_max, - dst->fps_in_num, dst->fps_out_num, dst->gop); - } + ret = h264e_proc_rc_cfg(&cfg->rc, param); } break; case MPP_ENC_SET_CODEC_CFG : { - MppEncH264Cfg *src = &((MppEncCodecCfg *)param)->h264; - MppEncH264Cfg *dst = &p->cfg->codec.h264; - RK_U32 change = src->change; - - // TODO: do codec check first - if (change & MPP_ENC_H264_CFG_STREAM_TYPE) - dst->stream_type = src->stream_type; - if (change & MPP_ENC_H264_CFG_CHANGE_PROFILE) { - dst->profile = src->profile; - dst->level = src->level; - } - if (change & MPP_ENC_H264_CFG_CHANGE_ENTROPY) { - dst->entropy_coding_mode = src->entropy_coding_mode; - dst->cabac_init_idc = src->cabac_init_idc; - } - if (change & MPP_ENC_H264_CFG_CHANGE_TRANS_8x8) - dst->transform8x8_mode = src->transform8x8_mode; - if (change & MPP_ENC_H264_CFG_CHANGE_CONST_INTRA) - dst->constrained_intra_pred_mode = src->constrained_intra_pred_mode; - if (change & MPP_ENC_H264_CFG_CHANGE_CHROMA_QP) { - dst->chroma_cb_qp_offset = src->chroma_cb_qp_offset; - dst->chroma_cr_qp_offset = src->chroma_cr_qp_offset; - } - if (change & MPP_ENC_H264_CFG_CHANGE_DEBLOCKING) { - dst->deblock_disable = src->deblock_disable; - dst->deblock_offset_alpha = src->deblock_offset_alpha; - dst->deblock_offset_beta = src->deblock_offset_beta; - } - if (change & MPP_ENC_H264_CFG_CHANGE_LONG_TERM) - dst->use_longterm = src->use_longterm; - - if (change & MPP_ENC_H264_CFG_CHANGE_SCALING_LIST) - dst->scaling_list_mode = src->scaling_list_mode; - - if (change & MPP_ENC_H264_CFG_CHANGE_QP_LIMIT) { - dst->qp_init = src->qp_init; - dst->qp_max = src->qp_max; - dst->qp_min = src->qp_min; - dst->qp_max_step = src->qp_max_step; - } - if (change & MPP_ENC_H264_CFG_CHANGE_INTRA_REFRESH) { - dst->intra_refresh_mode = src->intra_refresh_mode; - dst->intra_refresh_arg = src->intra_refresh_arg; - } - if (change & MPP_ENC_H264_CFG_CHANGE_SLICE_MODE) { - dst->slice_mode = src->slice_mode; - dst->slice_arg = src->slice_arg; - } - if (change & MPP_ENC_H264_CFG_CHANGE_VUI) { - dst->vui = src->vui; - } - if (change & MPP_ENC_H264_CFG_CHANGE_SEI) { - dst->sei = src->sei; - } - - dst->change |= change; + MppEncCodecCfg *codec = (MppEncCodecCfg *)param; + ret = h264e_proc_h264_cfg(&cfg->codec.h264, &codec->h264); } break; case MPP_ENC_SET_SEI_CFG : { } break; case MPP_ENC_SET_IDR_FRAME : { p->idr_request++; } break; - case MPP_ENC_SET_OSD_DATA_CFG : { - } break; case MPP_ENC_SET_SPLIT : { - MppEncSliceSplit *src = (MppEncSliceSplit *)param; - MppEncSliceSplit *dst = &p->cfg->split; - RK_U32 change = src->change; - - if (change & MPP_ENC_SPLIT_CFG_CHANGE_MODE) { - dst->split_mode = src->split_mode; - dst->split_arg = src->split_arg; - } - - if (change & MPP_ENC_SPLIT_CFG_CHANGE_ARG) - dst->split_arg = src->split_arg; - - dst->change |= change; + ret = h264e_proc_split_cfg(&cfg->split, param); } break; default: mpp_err("No correspond cmd found, and can not config!"); diff --git a/mpp/codec/enc/h265/h265e_api_v2.c b/mpp/codec/enc/h265/h265e_api_v2.c index 7071288f..88029426 100644 --- a/mpp/codec/enc/h265/h265e_api_v2.c +++ b/mpp/codec/enc/h265/h265e_api_v2.c @@ -19,6 +19,10 @@ #include #include "mpp_env.h" +#include "mpp_mem.h" + +#include "rc.h" +#include "mpp_enc_cfg_impl.h" #include "h265e_api.h" #include "h265e_slice.h" @@ -26,8 +30,6 @@ #include "h265e_syntax_new.h" #include "h265e_ps.h" #include "h265e_header_gen.h" -#include "mpp_mem.h" -#include "rc.h" extern RK_U32 h265e_debug; @@ -342,14 +344,183 @@ static MPP_RET h265e_flush(void *ctx) return MPP_OK; } +static MPP_RET h265e_proc_prep_cfg(MppEncPrepCfg *dst, MppEncPrepCfg *src) +{ + memcpy(dst, src, sizeof(MppEncPrepCfg)); + return MPP_OK; +} + +static MPP_RET h265e_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + if (change) { + MppEncRcCfg bak = *dst; + + if (change & MPP_ENC_RC_CFG_CHANGE_RC_MODE) + dst->rc_mode = src->rc_mode; + + if (change & MPP_ENC_RC_CFG_CHANGE_QUALITY) + dst->quality = src->quality; + + if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { + dst->bps_target = src->bps_target; + dst->bps_max = src->bps_max; + dst->bps_min = src->bps_min; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_IN) { + dst->fps_in_flex = src->fps_in_flex; + dst->fps_in_num = src->fps_in_num; + dst->fps_in_denorm = src->fps_in_denorm; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { + dst->fps_out_flex = src->fps_out_flex; + dst->fps_out_num = src->fps_out_num; + dst->fps_out_denorm = src->fps_out_denorm; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_GOP) + dst->gop = src->gop; + + // parameter checking + if (dst->rc_mode >= MPP_ENC_RC_MODE_BUTT) { + mpp_err("invalid rc mode %d should be RC_MODE_VBR or RC_MODE_CBR\n", + src->rc_mode); + ret = MPP_ERR_VALUE; + } + if (dst->quality >= MPP_ENC_RC_QUALITY_BUTT) { + mpp_err("invalid quality %d should be from QUALITY_WORST to QUALITY_BEST\n", + dst->quality); + ret = MPP_ERR_VALUE; + } + if (dst->rc_mode != MPP_ENC_RC_MODE_FIXQP) { + if ((dst->bps_target >= 100 * SZ_1M || dst->bps_target <= 1 * SZ_1K) || + (dst->bps_max >= 100 * SZ_1M || dst->bps_max <= 1 * SZ_1K) || + (dst->bps_min >= 100 * SZ_1M || dst->bps_min <= 1 * SZ_1K)) { + mpp_err("invalid bit per second %d [%d:%d] out of range 1K~100M\n", + dst->bps_target, dst->bps_min, dst->bps_max); + ret = MPP_ERR_VALUE; + } + } + + dst->change |= change; + + if (ret) { + mpp_err_f("failed to accept new rc config\n"); + *dst = bak; + } else { + mpp_log_f("MPP_ENC_SET_RC_CFG bps %d [%d : %d] fps [%d:%d] gop %d\n", + dst->bps_target, dst->bps_min, dst->bps_max, + dst->fps_in_num, dst->fps_out_num, dst->gop); + } + } + + return ret; +} + +static MPP_RET h265e_proc_h265_cfg(MppEncH265Cfg *dst, MppEncH265Cfg *src) +{ + RK_U32 change = src->change; + + // TODO: do codec check first + if (change & MPP_ENC_H265_CFG_PROFILE_LEVEL_TILER_CHANGE) { + dst->profile = src->profile; + dst->level = src->level; + } + + if (change & MPP_ENC_H265_CFG_CU_CHANGE) { + memcpy(&dst->cu_cfg, &src->cu_cfg, sizeof(src->cu_cfg)); + } + if (change & MPP_ENC_H265_CFG_DBLK_CHANGE) { + memcpy(&dst->dblk_cfg, &src->dblk_cfg, sizeof(src->dblk_cfg)); + } + if (change & MPP_ENC_H265_CFG_SAO_CHANGE) { + memcpy(&dst->sao_cfg, &src->sao_cfg, sizeof(src->sao_cfg)); + } + if (change & MPP_ENC_H265_CFG_TRANS_CHANGE) { + memcpy(&dst->trans_cfg, &src->trans_cfg, sizeof(src->trans_cfg)); + } + + if (change & MPP_ENC_H265_CFG_SLICE_CHANGE) { + memcpy(&dst->slice_cfg, &src->slice_cfg, sizeof(src->slice_cfg)); + } + + if (change & MPP_ENC_H265_CFG_ENTROPY_CHANGE) { + memcpy(&dst->entropy_cfg, &src->entropy_cfg, sizeof(src->entropy_cfg)); + } + + if (change & MPP_ENC_H265_CFG_MERGE_CHANGE) { + memcpy(&dst->merge_cfg, &src->merge_cfg, sizeof(src->merge_cfg)); + } + + if (change & MPP_ENC_H265_CFG_CHANGE_VUI) { + memcpy(&dst->vui, &src->vui, sizeof(src->vui)); + } + + if (change & MPP_ENC_H265_CFG_RC_QP_CHANGE) { + dst->qp_init = src->qp_init; + dst->max_qp = src->max_qp; + dst->min_qp = src->min_qp; + dst->max_i_qp = src->max_i_qp; + dst->min_i_qp = src->min_i_qp; + } + /* + * NOTE: use OR here for avoiding overwrite on multiple config + * When next encoding is trigger the change flag will be clear + */ + dst->change |= change; + + return MPP_OK; +} + +static MPP_RET h265e_proc_split_cfg(MppEncH265SliceCfg *dst, MppEncSliceSplit *src) +{ + if (src->split_mode > MPP_ENC_SPLIT_NONE) { + dst->split_enable = 1; + dst->split_mode = 0; + if (src->split_mode == MPP_ENC_SPLIT_BY_CTU) + dst->split_mode = 1; + dst->slice_size = src->split_arg; + } else { + dst->split_enable = 0; + } + + return MPP_OK; +} + static MPP_RET h265e_proc_cfg(void *ctx, MpiCmd cmd, void *param) { H265eCtx *p = (H265eCtx *)ctx; + MppEncCfgSet *cfg = p->cfg; MPP_RET ret = MPP_OK; h265e_dbg_func("enter ctx %p cmd %08x\n", ctx, cmd); switch (cmd) { + case MPP_ENC_SET_CFG : { + MppEncCfgImpl *impl = (MppEncCfgImpl *)param; + MppEncCfgSet *src = &impl->cfg; + + if (src->prep.change) { + ret |= h265e_proc_prep_cfg(&cfg->prep, &src->prep); + src->prep.change = 0; + } + if (src->rc.change) { + ret |= h265e_proc_rc_cfg(&cfg->rc, &src->rc); + src->rc.change = 0; + } + if (src->codec.h265.change) { + ret |= h265e_proc_h265_cfg(&cfg->codec.h265, &src->codec.h265); + src->codec.h265.change = 0; + } + if (src->split.change) { + ret |= h265e_proc_split_cfg(&cfg->codec.h265.slice_cfg, &src->split); + src->split.change = 0; + } + } break; case MPP_ENC_SET_IDR_FRAME : { p->syntax.idr_request = 1; p->idr_request = 1; @@ -360,144 +531,22 @@ static MPP_RET h265e_proc_cfg(void *ctx, MpiCmd cmd, void *param) h265e_get_extra_info(p, pkt_out); } break; case MPP_ENC_SET_PREP_CFG : { - MppEncPrepCfg *src = (MppEncPrepCfg *)param; - MppEncPrepCfg *dst = &p->cfg->prep; - - memcpy(dst, src, sizeof(MppEncPrepCfg)); + ret = h265e_proc_prep_cfg(&cfg->prep, param); } break; case MPP_ENC_SET_CODEC_CFG: { - MppEncCodecCfg *cfg = (MppEncCodecCfg *)param; - MppEncH265Cfg *src = &cfg->h265; - MppEncH265Cfg *dst = &p->cfg->codec.h265; - RK_U32 change = cfg->h265.change; + MppEncCodecCfg *codec = (MppEncCodecCfg *)param; - // TODO: do codec check first - if (change & MPP_ENC_H265_CFG_PROFILE_LEVEL_TILER_CHANGE) { - dst->profile = src->profile; - dst->level = src->level; - } - - if (change & MPP_ENC_H265_CFG_CU_CHANGE) { - memcpy(&dst->cu_cfg, &src->cu_cfg, sizeof(src->cu_cfg)); - } - if (change & MPP_ENC_H265_CFG_DBLK_CHANGE) { - memcpy(&dst->dblk_cfg, &src->dblk_cfg, sizeof(src->dblk_cfg)); - } - if (change & MPP_ENC_H265_CFG_SAO_CHANGE) { - memcpy(&dst->sao_cfg, &src->sao_cfg, sizeof(src->sao_cfg)); - } - if (change & MPP_ENC_H265_CFG_TRANS_CHANGE) { - memcpy(&dst->trans_cfg, &src->trans_cfg, sizeof(src->trans_cfg)); - } - - if (change & MPP_ENC_H265_CFG_SLICE_CHANGE) { - memcpy(&dst->slice_cfg, &src->slice_cfg, sizeof(src->slice_cfg)); - } - - if (change & MPP_ENC_H265_CFG_ENTROPY_CHANGE) { - memcpy(&dst->entropy_cfg, &src->entropy_cfg, sizeof(src->entropy_cfg)); - } - - if (change & MPP_ENC_H265_CFG_MERGE_CHANGE) { - memcpy(&dst->merge_cfg, &src->merge_cfg, sizeof(src->merge_cfg)); - } - - if (change & MPP_ENC_H265_CFG_CHANGE_VUI) { - memcpy(&dst->vui, &src->vui, sizeof(src->vui)); - } - - if (change & MPP_ENC_H265_CFG_RC_QP_CHANGE) { - dst->qp_init = src->qp_init; - dst->max_qp = src->max_qp; - dst->min_qp = src->min_qp; - dst->max_i_qp = src->max_i_qp; - dst->min_i_qp = src->min_i_qp; - } - /* - * NOTE: use OR here for avoiding overwrite on multiple config - * When next encoding is trigger the change flag will be clear - */ - dst->change |= change; + ret = h265e_proc_h265_cfg(&cfg->codec.h265, &codec->h265); } break; case MPP_ENC_SET_RC_CFG : { - MppEncRcCfg *src = (MppEncRcCfg *)param; - RK_U32 change = src->change; - - if (change) { - MppEncRcCfg *dst = &p->cfg->rc; - MppEncRcCfg bak = p->cfg->rc; - - if (change & MPP_ENC_RC_CFG_CHANGE_RC_MODE) - dst->rc_mode = src->rc_mode; - - if (change & MPP_ENC_RC_CFG_CHANGE_QUALITY) - dst->quality = src->quality; - - if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { - dst->bps_target = src->bps_target; - dst->bps_max = src->bps_max; - dst->bps_min = src->bps_min; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_FPS_IN) { - dst->fps_in_flex = src->fps_in_flex; - dst->fps_in_num = src->fps_in_num; - dst->fps_in_denorm = src->fps_in_denorm; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { - dst->fps_out_flex = src->fps_out_flex; - dst->fps_out_num = src->fps_out_num; - dst->fps_out_denorm = src->fps_out_denorm; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_GOP) - dst->gop = src->gop; - - if (change & MPP_ENC_RC_CFG_CHANGE_SKIP_CNT) - dst->skip_cnt = src->skip_cnt; - - // parameter checking - if (dst->rc_mode >= MPP_ENC_RC_MODE_BUTT) { - mpp_err("invalid rc mode %d should be RC_MODE_VBR or RC_MODE_CBR\n", - src->rc_mode); - ret = MPP_ERR_VALUE; - } - if (dst->quality >= MPP_ENC_RC_QUALITY_BUTT) { - mpp_err("invalid quality %d should be from QUALITY_WORST to QUALITY_BEST\n", - dst->quality); - ret = MPP_ERR_VALUE; - } - if (dst->rc_mode != MPP_ENC_RC_MODE_FIXQP) { - if ((dst->bps_target >= 100 * SZ_1M || dst->bps_target <= 1 * SZ_1K) || - (dst->bps_max >= 100 * SZ_1M || dst->bps_max <= 1 * SZ_1K) || - (dst->bps_min >= 100 * SZ_1M || dst->bps_min <= 1 * SZ_1K)) { - mpp_err("invalid bit per second %d [%d:%d] out of range 1K~100M\n", - dst->bps_target, dst->bps_min, dst->bps_max); - ret = MPP_ERR_VALUE; - } - } - - dst->change |= change; - - if (ret) { - mpp_err_f("failed to accept new rc config\n"); - *dst = bak; - break; - } - - mpp_log_f("MPP_ENC_SET_RC_CFG bps %d [%d : %d] fps [%d:%d] gop %d\n", - dst->bps_target, dst->bps_min, dst->bps_max, - dst->fps_in_num, dst->fps_out_num, dst->gop); - } + ret = h265e_proc_rc_cfg(&cfg->rc, param); } break; case MPP_ENC_SET_SEI_CFG: { - } break; - case MPP_ENC_SET_SPLIT : { MppEncSliceSplit *src = (MppEncSliceSplit *)param; - MppEncH265SliceCfg *slice_cfg = &p->cfg->codec.h265.slice_cfg; + MppEncH265SliceCfg *slice_cfg = &cfg->codec.h265.slice_cfg; + if (src->split_mode > MPP_ENC_SPLIT_NONE) { slice_cfg->split_enable = 1; slice_cfg->split_mode = 0; @@ -508,13 +557,10 @@ static MPP_RET h265e_proc_cfg(void *ctx, MpiCmd cmd, void *param) slice_cfg->split_enable = 0; } } break; - case MPP_ENC_SET_GOPREF: { MppEncGopRef *ref = (MppEncGopRef *)param; - MppEncCfgSet *cfg = p->cfg; memcpy(&cfg->gop_ref, ref , sizeof(*ref)); } break; - default: mpp_err("No correspond %08x found, and can not config!\n", cmd); ret = MPP_NOK; diff --git a/mpp/codec/enc/jpeg/jpege_api_v2.c b/mpp/codec/enc/jpeg/jpege_api_v2.c index 7d9ecb4c..293cb267 100644 --- a/mpp/codec/enc/jpeg/jpege_api_v2.c +++ b/mpp/codec/enc/jpeg/jpege_api_v2.c @@ -26,6 +26,7 @@ #include "jpege_debug.h" #include "jpege_api.h" #include "jpege_syntax.h" +#include "mpp_enc_cfg_impl.h" typedef struct { MppEncCfgSet *cfg; @@ -66,6 +67,177 @@ static MPP_RET jpege_deinit_v2(void *ctx) return MPP_OK; } +static MPP_RET jpege_proc_prep_cfg(MppEncPrepCfg *dst, MppEncPrepCfg *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + mpp_assert(change); + if (change) { + MppEncPrepCfg bak = *dst; + + if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT) + dst->format = src->format; + + if (change & MPP_ENC_PREP_CFG_CHANGE_ROTATION) + dst->rotation = src->rotation; + + /* jpeg encoder do not have mirring / denoise feature */ + + if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) { + if (dst->rotation == MPP_ENC_ROT_90 || dst->rotation == MPP_ENC_ROT_270) { + dst->width = src->height; + dst->height = src->width; + } else { + dst->width = src->width; + dst->height = src->height; + } + dst->hor_stride = src->hor_stride; + dst->ver_stride = src->ver_stride; + } + + if (dst->width < 16 && dst->width > 8192) { + mpp_err_f("invalid width %d is not in range [16..8192]\n", dst->width); + ret = MPP_NOK; + } + + if (dst->height < 16 && dst->height > 8192) { + mpp_err_f("invalid height %d is not in range [16..8192]\n", dst->height); + ret = MPP_NOK; + } + + if (dst->format != MPP_FMT_YUV420SP && + dst->format != MPP_FMT_YUV420P && + dst->format != MPP_FMT_YUV422SP_VU && + dst->format != MPP_FMT_YUV422_YUYV && + dst->format != MPP_FMT_YUV422_UYVY && + dst->format != MPP_FMT_RGB888 && + dst->format != MPP_FMT_BGR888) { + mpp_err_f("invalid format %d is not supportted\n", dst->format); + ret = MPP_NOK; + } + + dst->change |= change; + + // parameter checking + if (dst->width > dst->hor_stride || dst->height > dst->ver_stride) { + mpp_err("invalid size w:h [%d:%d] stride [%d:%d]\n", + dst->width, dst->height, dst->hor_stride, dst->ver_stride); + ret = MPP_ERR_VALUE; + } + + if (ret) { + mpp_err_f("failed to accept new prep config\n"); + *dst = bak; + } else { + mpp_log_f("MPP_ENC_SET_PREP_CFG w:h [%d:%d] stride [%d:%d]\n", + dst->width, dst->height, + dst->hor_stride, dst->ver_stride); + } + } + + return ret; +} + +static MPP_RET jpege_proc_rc_cfg(MppEncRcCfg *dst, MppEncRcCfg *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + if (change) { + MppEncRcCfg bak = *dst; + + if (change & MPP_ENC_RC_CFG_CHANGE_RC_MODE) + dst->rc_mode = src->rc_mode; + + if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { + dst->bps_target = src->bps_target; + dst->bps_max = src->bps_max; + dst->bps_min = src->bps_min; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_IN) { + dst->fps_in_flex = src->fps_in_flex; + dst->fps_in_num = src->fps_in_num; + dst->fps_in_denorm = src->fps_in_denorm; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { + dst->fps_out_flex = src->fps_out_flex; + dst->fps_out_num = src->fps_out_num; + dst->fps_out_denorm = src->fps_out_denorm; + } + + if (change & MPP_ENC_RC_CFG_CHANGE_GOP) + dst->gop = src->gop; + + // parameter checking + if (dst->rc_mode >= MPP_ENC_RC_MODE_BUTT) { + mpp_err("invalid rc mode %d should be RC_MODE_VBR or RC_MODE_CBR\n", + src->rc_mode); + ret = MPP_ERR_VALUE; + } + if (dst->quality >= MPP_ENC_RC_QUALITY_BUTT) { + mpp_err("invalid quality %d should be from QUALITY_WORST to QUALITY_BEST\n", + dst->quality); + ret = MPP_ERR_VALUE; + } + if (dst->rc_mode != MPP_ENC_RC_MODE_FIXQP) { + if ((dst->bps_target >= 100 * SZ_1M || dst->bps_target <= 1 * SZ_1K) || + (dst->bps_max >= 100 * SZ_1M || dst->bps_max <= 1 * SZ_1K) || + (dst->bps_min >= 100 * SZ_1M || dst->bps_min <= 1 * SZ_1K)) { + mpp_err("invalid bit per second %d [%d:%d] out of range 1K~100M\n", + dst->bps_target, dst->bps_min, dst->bps_max); + ret = MPP_ERR_VALUE; + } + } + + dst->change |= change; + + if (ret) { + mpp_err_f("failed to accept new rc config\n"); + *dst = bak; + } else { + mpp_log_f("MPP_ENC_SET_RC_CFG bps %d [%d : %d] fps [%d:%d] gop %d\n", + dst->bps_target, dst->bps_min, dst->bps_max, + dst->fps_in_num, dst->fps_out_num, dst->gop); + } + } + + return ret; +} + +static MPP_RET jpege_proc_jpeg_cfg(MppEncJpegCfg *dst, MppEncJpegCfg *src) +{ + MPP_RET ret = MPP_OK; + RK_U32 change = src->change; + + if (change) { + MppEncJpegCfg bak = *dst; + + if (change & MPP_ENC_JPEG_CFG_CHANGE_QP) { + dst->quant = src->quant; + } + + if (dst->quant < 0 || dst->quant > 10) { + mpp_err_f("invalid quality level %d is not in range [0..10] set to default 8\n"); + dst->quant = 8; + } + + if (ret) { + mpp_err_f("failed to accept new rc config\n"); + *dst = bak; + } else { + mpp_log_f("MPP_ENC_SET_CODEC_CFG jpeg quant set to %d\n", dst->quant); + dst->change = src->change; + } + + dst->change = src->change; + } + + return ret; +} + static MPP_RET jpege_proc_cfg(void *ctx, MpiCmd cmd, void *param) { JpegeCtx *p = (JpegeCtx *)ctx; @@ -76,168 +248,31 @@ static MPP_RET jpege_proc_cfg(void *ctx, MpiCmd cmd, void *param) switch (cmd) { case MPP_ENC_SET_CFG : { + MppEncCfgImpl *impl = (MppEncCfgImpl *)param; + MppEncCfgSet *src = &impl->cfg; + + if (src->prep.change) { + ret |= jpege_proc_prep_cfg(&cfg->prep, &src->prep); + src->prep.change = 0; + } + if (src->rc.change) { + ret |= jpege_proc_rc_cfg(&cfg->rc, &src->rc); + src->rc.change = 0; + } + if (src->codec.jpeg.change) { + ret |= jpege_proc_jpeg_cfg(&cfg->codec.jpeg, &src->codec.jpeg); + src->codec.jpeg.change = 0; + } } break; case MPP_ENC_SET_PREP_CFG : { - MppEncPrepCfg *src = (MppEncPrepCfg *)param; - RK_U32 change = src->change; - - if (change) { - MppEncPrepCfg *dst = &cfg->prep; - MppEncPrepCfg bak = *dst; - - if (change & MPP_ENC_PREP_CFG_CHANGE_FORMAT) - dst->format = src->format; - - if (change & MPP_ENC_PREP_CFG_CHANGE_INPUT) { - if (dst->rotation == MPP_ENC_ROT_90 || dst->rotation == MPP_ENC_ROT_270) { - dst->width = src->height; - dst->height = src->width; - } else { - dst->width = src->width; - dst->height = src->height; - } - dst->hor_stride = src->hor_stride; - dst->ver_stride = src->ver_stride; - } - - if (dst->width < 16 && dst->width > 8192) { - mpp_err_f("invalid width %d is not in range [16..8192]\n", dst->width); - ret = MPP_NOK; - } - - if (dst->height < 16 && dst->height > 8192) { - mpp_err_f("invalid height %d is not in range [16..8192]\n", dst->height); - ret = MPP_NOK; - } - - if (dst->format != MPP_FMT_YUV420SP && - dst->format != MPP_FMT_YUV420P && - dst->format != MPP_FMT_YUV422SP_VU && - dst->format != MPP_FMT_YUV422_YUYV && - dst->format != MPP_FMT_YUV422_UYVY && - dst->format != MPP_FMT_RGB888 && - dst->format != MPP_FMT_BGR888) { - mpp_err_f("invalid format %d is not supportted\n", dst->format); - ret = MPP_NOK; - } - - if (dst->width > dst->hor_stride || dst->height > dst->ver_stride) { - mpp_err_f("invalid size w:h [%d:%d] stride [%d:%d]\n", - dst->width, dst->height, dst->hor_stride, dst->ver_stride); - ret = MPP_ERR_VALUE; - } - - if (ret) { - mpp_err_f("failed to accept new prep config\n"); - *dst = bak; - } else { - mpp_log_f("MPP_ENC_SET_PREP_CFG w:h [%d:%d] stride [%d:%d]\n", - dst->width, dst->height, - dst->hor_stride, dst->ver_stride); - - dst->change = src->change; - } - } + ret = jpege_proc_prep_cfg(&cfg->prep, param); } break; case MPP_ENC_SET_RC_CFG : { - MppEncRcCfg *src = (MppEncRcCfg *)param; - RK_U32 change = src->change; - - if (change) { - MppEncRcCfg *dst = &cfg->rc; - MppEncRcCfg bak = *dst; - - if (change & MPP_ENC_RC_CFG_CHANGE_RC_MODE) - dst->rc_mode = src->rc_mode; - - if (change & MPP_ENC_RC_CFG_CHANGE_QUALITY) - dst->quality = src->quality; - - if (change & MPP_ENC_RC_CFG_CHANGE_BPS) { - dst->bps_target = src->bps_target; - dst->bps_max = src->bps_max; - dst->bps_min = src->bps_min; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_FPS_IN) { - dst->fps_in_flex = src->fps_in_flex; - dst->fps_in_num = src->fps_in_num; - dst->fps_in_denorm = src->fps_in_denorm; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_FPS_OUT) { - dst->fps_out_flex = src->fps_out_flex; - dst->fps_out_num = src->fps_out_num; - dst->fps_out_denorm = src->fps_out_denorm; - } - - if (change & MPP_ENC_RC_CFG_CHANGE_GOP) - dst->gop = src->gop; - - if (change & MPP_ENC_RC_CFG_CHANGE_SKIP_CNT) - dst->skip_cnt = src->skip_cnt; - - // parameter checking - if (dst->rc_mode >= MPP_ENC_RC_MODE_BUTT) { - mpp_err("invalid rc mode %d should be RC_MODE_VBR or RC_MODE_CBR\n", - src->rc_mode); - ret = MPP_ERR_VALUE; - } - if (dst->quality >= MPP_ENC_RC_QUALITY_BUTT) { - mpp_err("invalid quality %d should be from QUALITY_WORST to QUALITY_BEST\n", - dst->quality); - ret = MPP_ERR_VALUE; - } - if (dst->rc_mode != MPP_ENC_RC_MODE_FIXQP) { - if ((dst->bps_target >= 100 * SZ_1M || dst->bps_target <= 1 * SZ_1K) || - (dst->bps_max >= 100 * SZ_1M || dst->bps_max <= 1 * SZ_1K) || - (dst->bps_min >= 100 * SZ_1M || dst->bps_min <= 1 * SZ_1K)) { - mpp_err("invalid bit per second %d [%d:%d] out of range 1K~100M\n", - dst->bps_target, dst->bps_min, dst->bps_max); - ret = MPP_ERR_VALUE; - } - } - - dst->change |= change; - - if (ret) { - mpp_err_f("failed to accept new rc config\n"); - *dst = bak; - } else { - mpp_log_f("MPP_ENC_SET_RC_CFG bps %d [%d : %d] fps [%d:%d] gop %d\n", - dst->bps_target, dst->bps_min, dst->bps_max, - dst->fps_in_num, dst->fps_out_num, dst->gop); - } - } + ret = jpege_proc_rc_cfg(&cfg->rc, param); } break; case MPP_ENC_SET_CODEC_CFG : { MppEncCodecCfg *codec = (MppEncCodecCfg *)param; - MppEncJpegCfg *src = &codec->jpeg; - RK_U32 change = src->change; - - if (change) { - MppEncJpegCfg *dst = &cfg->codec.jpeg; - MppEncJpegCfg bak = *dst; - - if (change & MPP_ENC_JPEG_CFG_CHANGE_QP) { - dst->quant = src->quant; - } - - if (dst->quant < 0 || dst->quant > 10) { - mpp_err_f("invalid quality level %d is not in range [0..10] set to default 8\n"); - dst->quant = 8; - } - - if (ret) { - mpp_err_f("failed to accept new rc config\n"); - *dst = bak; - } else { - mpp_log_f("MPP_ENC_SET_CODEC_CFG jpeg quant set to %d\n", dst->quant); - dst->change = src->change; - } - - dst->change = src->change; - } + ret = jpege_proc_jpeg_cfg(&cfg->codec.jpeg, &codec->jpeg); } break; case MPP_ENC_SET_IDR_FRAME : case MPP_ENC_SET_OSD_PLT_CFG : diff --git a/mpp/codec/mpp_enc.cpp b/mpp/codec/mpp_enc.cpp index 7332a349..5e56f13a 100644 --- a/mpp/codec/mpp_enc.cpp +++ b/mpp/codec/mpp_enc.cpp @@ -27,6 +27,7 @@ #include "mpp.h" #include "mpp_enc_debug.h" +#include "mpp_enc_cfg_impl.h" #include "mpp_enc_impl.h" #include "mpp_hal.h" #include "hal_h264e_api.h" @@ -601,9 +602,10 @@ MPP_RET mpp_enc_control(MppEnc ctx, MpiCmd cmd, void *param) switch (cmd) { case MPP_ENC_SET_CFG : { MppEncRcCfg *rc = &enc->set.rc; + MppEncCfgImpl *cfg = (MppEncCfgImpl *)param; enc_dbg_ctrl("set all config\n"); - memcpy(&enc->set, param, sizeof(enc->set)); + memcpy(&enc->set, &cfg->cfg, sizeof(enc->set)); if (rc->rc_mode == MPP_ENC_RC_MODE_VBR && rc->quality == MPP_ENC_RC_QUALITY_CQP) rc->rc_mode = MPP_ENC_RC_MODE_FIXQP; @@ -622,10 +624,10 @@ MPP_RET mpp_enc_control(MppEnc ctx, MpiCmd cmd, void *param) ret = mpp_hal_control(enc->hal, MPP_ENC_SET_CODEC_CFG, &enc->set.codec); } break; case MPP_ENC_GET_CFG : { - MppEncCfgSet *p = (MppEncCfgSet *)param; + MppEncCfgImpl *p = (MppEncCfgImpl *)param; enc_dbg_ctrl("get all config\n"); - memcpy(p, &enc->cfg, sizeof(*p)); + memcpy(&p->cfg, &enc->cfg, sizeof(enc->cfg)); } break; case MPP_ENC_SET_PREP_CFG : { enc_dbg_ctrl("set prep config\n"); diff --git a/mpp/codec/mpp_enc_v2.cpp b/mpp/codec/mpp_enc_v2.cpp index 892bb2e1..01defd4f 100644 --- a/mpp/codec/mpp_enc_v2.cpp +++ b/mpp/codec/mpp_enc_v2.cpp @@ -27,6 +27,7 @@ #include "mpp.h" #include "mpp_enc_debug.h" +#include "mpp_enc_cfg_impl.h" #include "mpp_enc_impl.h" #include "mpp_enc_hal.h" #include "hal_h264e_api_v2.h" @@ -1076,8 +1077,10 @@ MPP_RET mpp_enc_control_v2(MppEnc ctx, MpiCmd cmd, void *param) switch (cmd) { case MPP_ENC_GET_CFG : { + MppEncCfgImpl *p = (MppEncCfgImpl *)param; + enc_dbg_ctrl("get all config\n"); - memcpy(param, &enc->cfg, sizeof(enc->cfg)); + memcpy(&p->cfg, &enc->cfg, sizeof(enc->cfg)); } break; case MPP_ENC_GET_PREP_CFG : { enc_dbg_ctrl("get prep config\n"); diff --git a/mpp/legacy/vpu_api_legacy.cpp b/mpp/legacy/vpu_api_legacy.cpp index f3b1612b..f5a18e52 100644 --- a/mpp/legacy/vpu_api_legacy.cpp +++ b/mpp/legacy/vpu_api_legacy.cpp @@ -87,17 +87,11 @@ 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, +static MPP_RET vpu_api_set_enc_cfg(MppCtx mpp_ctx, MppApi *mpi, MppEncCfg enc_cfg, MppCodingType coding, MppFrameFormat fmt, EncParameter_t *cfg) { MPP_RET ret = MPP_OK; - MppEncCodecCfg codec; - MppEncPrepCfg prep; - MppEncRcCfg rc; - MppEncCodecCfg *codec_cfg = &codec; - MppEncPrepCfg *prep_cfg = &prep; - MppEncRcCfg *rc_cfg = &rc; RK_S32 width = cfg->width; RK_S32 height = cfg->height; RK_S32 bps = cfg->bitRate; @@ -125,6 +119,57 @@ static MPP_RET vpu_api_set_enc_cfg(MppCtx mpp_ctx, MppApi *mpi, mpp_assert(height); mpp_assert(qp); + mpp_enc_cfg_set_s32(enc_cfg, "prep:width", width); + mpp_enc_cfg_set_s32(enc_cfg, "prep:height", height); + mpp_enc_cfg_set_s32(enc_cfg, "prep:hor_stride", MPP_ALIGN(width, 16)); + mpp_enc_cfg_set_s32(enc_cfg, "prep:ver_stride", MPP_ALIGN(height, 16)); + mpp_enc_cfg_set_s32(enc_cfg, "prep:format", fmt); + + mpp_enc_cfg_set_s32(enc_cfg, "rc:rc_mode", rc_mode ? MPP_ENC_RC_MODE_CBR : MPP_ENC_RC_MODE_FIXQP); + mpp_enc_cfg_set_s32(enc_cfg, "rc:bps_target", bps); + mpp_enc_cfg_set_s32(enc_cfg, "rc:bps_max", bps * 17 / 16); + mpp_enc_cfg_set_s32(enc_cfg, "rc:bps_min", bps * 17 / 16); + mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_in_flex", 0); + mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_in_num", fps_in); + mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_in_denorm", 1); + mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_out_flex", 0); + mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_out_num", fps_out); + mpp_enc_cfg_set_s32(enc_cfg, "rc:fps_out_denorm", 1); + mpp_enc_cfg_set_s32(enc_cfg, "rc:gop", gop); + + mpp_enc_cfg_set_s32(enc_cfg, "codec:type", coding); + switch (coding) { + case MPP_VIDEO_CodingAVC : { + mpp_enc_cfg_set_s32(enc_cfg, "h264:profile", profile); + mpp_enc_cfg_set_s32(enc_cfg, "h264:level", level); + mpp_enc_cfg_set_s32(enc_cfg, "h264:cabac_en", cabac_en); + mpp_enc_cfg_set_s32(enc_cfg, "h264:cabac_idc", 0); + mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_init", rc_mode ? 0 : qp); + mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_min", rc_mode ? 10 : qp); + mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_max", rc_mode ? 51 : qp); + mpp_enc_cfg_set_s32(enc_cfg, "h264:qp_step", rc_mode ? 4 : 0); + } break; + case MPP_VIDEO_CodingMJPEG : { + mpp_enc_cfg_set_s32(enc_cfg, "jpeg:quant", qp); + } break; + default : { + mpp_err_f("support encoder coding type %d\n", coding); + } break; + } + + ret = mpi->control(mpp_ctx, MPP_ENC_SET_CFG, enc_cfg); + if (ret) { + mpp_err("setup enc config failed ret %d\n", ret); + goto RET; + } +#if 0 + MppEncCodecCfg codec; + MppEncPrepCfg prep; + MppEncRcCfg rc; + MppEncCodecCfg *codec_cfg = &codec; + MppEncPrepCfg *prep_cfg = &prep; + MppEncRcCfg *rc_cfg = &rc; + prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT | MPP_ENC_PREP_CFG_CHANGE_FORMAT; prep_cfg->width = width; @@ -215,6 +260,7 @@ static MPP_RET vpu_api_set_enc_cfg(MppCtx mpp_ctx, MppApi *mpi, ret = mpi->control(mpp_ctx, MPP_ENC_SET_CODEC_CFG, codec_cfg); if (ret) mpp_err("setup codec config failed ret %d\n", ret); +#endif RET: return ret; } @@ -294,13 +340,14 @@ VpuApiLegacy::VpuApiLegacy() : format(MPP_FMT_YUV420P), fd_input(-1), fd_output(-1), - mEosSet(0) + mEosSet(0), + enc_cfg(NULL) { vpu_api_dbg_func("enter\n"); mpp_create(&mpp_ctx, &mpi); - memset(&enc_cfg, 0, sizeof(enc_cfg)); + memset(&enc_param, 0, sizeof(enc_param)); vpu_api_dbg_func("leave\n"); } @@ -308,12 +355,17 @@ VpuApiLegacy::~VpuApiLegacy() { vpu_api_dbg_func("enter\n"); + mpp_destroy(mpp_ctx); + if (memGroup) { mpp_buffer_group_put(memGroup); memGroup = NULL; } - mpp_destroy(mpp_ctx); + if (enc_cfg) { + mpp_enc_cfg_deinit(enc_cfg); + enc_cfg = NULL; + } vpu_api_dbg_func("leave\n"); } @@ -404,16 +456,24 @@ RK_S32 VpuApiLegacy::init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_s if (memGroup == NULL) { ret = mpp_buffer_group_get_internal(&memGroup, MPP_BUFFER_TYPE_ION); - if (MPP_OK != ret) { - mpp_err("memGroup mpp_buffer_group_get failed\n"); + if (ret) { + mpp_err("memGroup mpp_buffer_group_get failed %d\n", ret); return ret; } } + ret = mpp_enc_cfg_init(&enc_cfg); + if (ret) { + mpp_err("mpp_enc_cfg_init failed %d\n", ret); + mpp_buffer_group_put(memGroup); + memGroup = NULL; + return ret; + } + format = vpu_pic_type_remap_to_mpp((EncInputPictureType)param->format); - memcpy(&enc_cfg, param, sizeof(enc_cfg)); - vpu_api_set_enc_cfg(mpp_ctx, mpi, coding, format, param); + memcpy(&enc_param, param, sizeof(enc_param)); + vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, param); mpi->control(mpp_ctx, MPP_ENC_GET_EXTRA_INFO, &pkt); @@ -1368,11 +1428,11 @@ RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param) case VPU_API_ENC_SETCFG : { 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); + memcpy(&enc_param, param, sizeof(enc_param)); + return vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, &enc_param); } break; case VPU_API_ENC_GETCFG : { - memcpy(param, &enc_cfg, sizeof(enc_cfg)); + memcpy(param, &enc_param, sizeof(enc_param)); return 0; } break; case VPU_API_ENC_SETFORMAT : { diff --git a/mpp/legacy/vpu_api_legacy.h b/mpp/legacy/vpu_api_legacy.h index 05b143ac..fb65e54f 100644 --- a/mpp/legacy/vpu_api_legacy.h +++ b/mpp/legacy/vpu_api_legacy.h @@ -21,6 +21,7 @@ #include "vpu_api.h" #include "rk_mpi.h" +#include "rk_venc_cfg.h" #define OMX_BUFFERFLAG_EOS 0x00000001 @@ -79,7 +80,8 @@ private: RK_U32 mEosSet; - EncParameter_t enc_cfg; + EncParameter_t enc_param; + MppEncCfg enc_cfg; }; #endif /*_VPU_API_H_*/