[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 <herman.chen@rock-chips.com>
This commit is contained in:
Herman Chen
2020-05-13 16:23:35 +08:00
parent 8e00c203d7
commit 83e2724158
9 changed files with 705 additions and 512 deletions

View File

@@ -96,14 +96,14 @@ typedef enum {
MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC,
/* basic encoder setup control */ /* basic encoder setup control */
MPP_ENC_SET_CFG, /* set MppEncCfgSet structure */ MPP_ENC_SET_CFG, /* set MppEncCfg structure */
MPP_ENC_GET_CFG, /* get MppEncCfgSet structure */ MPP_ENC_GET_CFG, /* get MppEncCfg structure */
MPP_ENC_SET_PREP_CFG, /* set MppEncPrepCfg structure */ MPP_ENC_SET_PREP_CFG, /* deprecated set MppEncPrepCfg structure, use MPP_ENC_SET_CFG instead */
MPP_ENC_GET_PREP_CFG, /* get MppEncPrepCfg structure */ MPP_ENC_GET_PREP_CFG, /* deprecated get MppEncPrepCfg structure, use MPP_ENC_GET_CFG instead */
MPP_ENC_SET_RC_CFG, /* set MppEncRcCfg structure */ MPP_ENC_SET_RC_CFG, /* deprecated set MppEncRcCfg structure, use MPP_ENC_SET_CFG instead */
MPP_ENC_GET_RC_CFG, /* get MppEncRcCfg structure */ MPP_ENC_GET_RC_CFG, /* deprecated get MppEncRcCfg structure, use MPP_ENC_GET_CFG instead */
MPP_ENC_SET_CODEC_CFG, /* set MppEncCodecCfg structure */ MPP_ENC_SET_CODEC_CFG, /* deprecated set MppEncCodecCfg structure, use MPP_ENC_SET_CFG instead */
MPP_ENC_GET_CODEC_CFG, /* get MppEncCodecCfg structure */ MPP_ENC_GET_CODEC_CFG, /* deprecated get MppEncCodecCfg structure, use MPP_ENC_GET_CFG instead */
/* runtime encoder setup control */ /* runtime encoder setup control */
MPP_ENC_SET_IDR_FRAME, /* next frame will be encoded as intra frame */ MPP_ENC_SET_IDR_FRAME, /* next frame will be encoded as intra frame */
MPP_ENC_SET_OSD_LEGACY_0, /* deprecated */ MPP_ENC_SET_OSD_LEGACY_0, /* deprecated */

View File

@@ -116,7 +116,7 @@ static const char *cfg_func_names[] = {
MPP_RET set_##base##_##name(MppEncCfgSet *cfg, in_type name) \ MPP_RET set_##base##_##name(MppEncCfgSet *cfg, in_type name) \
{ \ { \
mpp_enc_cfg_dbg_func("enter\n"); \ 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.field1 = (in_type)name; \
cfg->field0.change |= flag; \ 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, 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, 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) \ 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 */ \ /* h264 config */ \
ENTRY(h264, stream_type, S32, RK_S32, MPP_ENC_H264_CFG_STREAM_TYPE, codec.h264, stream_type) \ 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) \ ENTRY(h264, profile, S32, RK_S32, MPP_ENC_H264_CFG_CHANGE_PROFILE, codec.h264, profile) \

View File

@@ -36,6 +36,7 @@
#include "rc.h" #include "rc.h"
#include "enc_impl_api.h" #include "enc_impl_api.h"
#include "mpp_enc_cfg_impl.h"
RK_U32 h264e_debug = 0; RK_U32 h264e_debug = 0;
@@ -192,221 +193,263 @@ static MPP_RET h264e_deinit(void *ctx)
return MPP_OK; 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) static MPP_RET h264e_proc_cfg(void *ctx, MpiCmd cmd, void *param)
{ {
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
H264eCtx *p = (H264eCtx *)ctx; H264eCtx *p = (H264eCtx *)ctx;
MppEncCfgSet *cfg = p->cfg;
h264e_dbg_func("enter ctx %p cmd %x param %p\n", ctx, cmd, param); h264e_dbg_func("enter ctx %p cmd %x param %p\n", ctx, cmd, param);
switch (cmd) { switch (cmd) {
case MPP_ENC_SET_CFG : { 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; } break;
case MPP_ENC_SET_PREP_CFG : { case MPP_ENC_SET_PREP_CFG : {
MppEncPrepCfg *src = (MppEncPrepCfg *)param; ret = h264e_proc_prep_cfg(&cfg->prep, 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);
}
} break; } break;
case MPP_ENC_SET_RC_CFG : { case MPP_ENC_SET_RC_CFG : {
MppEncRcCfg *src = (MppEncRcCfg *)param; ret = h264e_proc_rc_cfg(&cfg->rc, 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);
}
} break; } break;
case MPP_ENC_SET_CODEC_CFG : { case MPP_ENC_SET_CODEC_CFG : {
MppEncH264Cfg *src = &((MppEncCodecCfg *)param)->h264; MppEncCodecCfg *codec = (MppEncCodecCfg *)param;
MppEncH264Cfg *dst = &p->cfg->codec.h264; ret = h264e_proc_h264_cfg(&cfg->codec.h264, &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;
} break; } break;
case MPP_ENC_SET_SEI_CFG : { case MPP_ENC_SET_SEI_CFG : {
} break; } break;
case MPP_ENC_SET_IDR_FRAME : { case MPP_ENC_SET_IDR_FRAME : {
p->idr_request++; p->idr_request++;
} break; } break;
case MPP_ENC_SET_OSD_DATA_CFG : {
} break;
case MPP_ENC_SET_SPLIT : { case MPP_ENC_SET_SPLIT : {
MppEncSliceSplit *src = (MppEncSliceSplit *)param; ret = h264e_proc_split_cfg(&cfg->split, 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;
} break; } break;
default: default:
mpp_err("No correspond cmd found, and can not config!"); mpp_err("No correspond cmd found, and can not config!");

View File

@@ -19,6 +19,10 @@
#include <string.h> #include <string.h>
#include "mpp_env.h" #include "mpp_env.h"
#include "mpp_mem.h"
#include "rc.h"
#include "mpp_enc_cfg_impl.h"
#include "h265e_api.h" #include "h265e_api.h"
#include "h265e_slice.h" #include "h265e_slice.h"
@@ -26,8 +30,6 @@
#include "h265e_syntax_new.h" #include "h265e_syntax_new.h"
#include "h265e_ps.h" #include "h265e_ps.h"
#include "h265e_header_gen.h" #include "h265e_header_gen.h"
#include "mpp_mem.h"
#include "rc.h"
extern RK_U32 h265e_debug; extern RK_U32 h265e_debug;
@@ -342,14 +344,183 @@ static MPP_RET h265e_flush(void *ctx)
return MPP_OK; 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) static MPP_RET h265e_proc_cfg(void *ctx, MpiCmd cmd, void *param)
{ {
H265eCtx *p = (H265eCtx *)ctx; H265eCtx *p = (H265eCtx *)ctx;
MppEncCfgSet *cfg = p->cfg;
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
h265e_dbg_func("enter ctx %p cmd %08x\n", ctx, cmd); h265e_dbg_func("enter ctx %p cmd %08x\n", ctx, cmd);
switch (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 : { case MPP_ENC_SET_IDR_FRAME : {
p->syntax.idr_request = 1; p->syntax.idr_request = 1;
p->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); h265e_get_extra_info(p, pkt_out);
} break; } break;
case MPP_ENC_SET_PREP_CFG : { case MPP_ENC_SET_PREP_CFG : {
MppEncPrepCfg *src = (MppEncPrepCfg *)param; ret = h265e_proc_prep_cfg(&cfg->prep, param);
MppEncPrepCfg *dst = &p->cfg->prep;
memcpy(dst, src, sizeof(MppEncPrepCfg));
} break; } break;
case MPP_ENC_SET_CODEC_CFG: { case MPP_ENC_SET_CODEC_CFG: {
MppEncCodecCfg *cfg = (MppEncCodecCfg *)param; MppEncCodecCfg *codec = (MppEncCodecCfg *)param;
MppEncH265Cfg *src = &cfg->h265;
MppEncH265Cfg *dst = &p->cfg->codec.h265;
RK_U32 change = cfg->h265.change;
// TODO: do codec check first ret = h265e_proc_h265_cfg(&cfg->codec.h265, &codec->h265);
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;
} break; } break;
case MPP_ENC_SET_RC_CFG : { case MPP_ENC_SET_RC_CFG : {
MppEncRcCfg *src = (MppEncRcCfg *)param; ret = h265e_proc_rc_cfg(&cfg->rc, 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);
}
} break; } break;
case MPP_ENC_SET_SEI_CFG: { case MPP_ENC_SET_SEI_CFG: {
} break; } break;
case MPP_ENC_SET_SPLIT : { case MPP_ENC_SET_SPLIT : {
MppEncSliceSplit *src = (MppEncSliceSplit *)param; 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) { if (src->split_mode > MPP_ENC_SPLIT_NONE) {
slice_cfg->split_enable = 1; slice_cfg->split_enable = 1;
slice_cfg->split_mode = 0; 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; slice_cfg->split_enable = 0;
} }
} break; } break;
case MPP_ENC_SET_GOPREF: { case MPP_ENC_SET_GOPREF: {
MppEncGopRef *ref = (MppEncGopRef *)param; MppEncGopRef *ref = (MppEncGopRef *)param;
MppEncCfgSet *cfg = p->cfg;
memcpy(&cfg->gop_ref, ref , sizeof(*ref)); memcpy(&cfg->gop_ref, ref , sizeof(*ref));
} break; } break;
default: default:
mpp_err("No correspond %08x found, and can not config!\n", cmd); mpp_err("No correspond %08x found, and can not config!\n", cmd);
ret = MPP_NOK; ret = MPP_NOK;

View File

@@ -26,6 +26,7 @@
#include "jpege_debug.h" #include "jpege_debug.h"
#include "jpege_api.h" #include "jpege_api.h"
#include "jpege_syntax.h" #include "jpege_syntax.h"
#include "mpp_enc_cfg_impl.h"
typedef struct { typedef struct {
MppEncCfgSet *cfg; MppEncCfgSet *cfg;
@@ -66,6 +67,177 @@ static MPP_RET jpege_deinit_v2(void *ctx)
return MPP_OK; 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) static MPP_RET jpege_proc_cfg(void *ctx, MpiCmd cmd, void *param)
{ {
JpegeCtx *p = (JpegeCtx *)ctx; JpegeCtx *p = (JpegeCtx *)ctx;
@@ -76,168 +248,31 @@ static MPP_RET jpege_proc_cfg(void *ctx, MpiCmd cmd, void *param)
switch (cmd) { switch (cmd) {
case MPP_ENC_SET_CFG : { 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; } break;
case MPP_ENC_SET_PREP_CFG : { case MPP_ENC_SET_PREP_CFG : {
MppEncPrepCfg *src = (MppEncPrepCfg *)param; ret = jpege_proc_prep_cfg(&cfg->prep, 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;
}
}
} break; } break;
case MPP_ENC_SET_RC_CFG : { case MPP_ENC_SET_RC_CFG : {
MppEncRcCfg *src = (MppEncRcCfg *)param; ret = jpege_proc_rc_cfg(&cfg->rc, 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);
}
}
} break; } break;
case MPP_ENC_SET_CODEC_CFG : { case MPP_ENC_SET_CODEC_CFG : {
MppEncCodecCfg *codec = (MppEncCodecCfg *)param; MppEncCodecCfg *codec = (MppEncCodecCfg *)param;
MppEncJpegCfg *src = &codec->jpeg; ret = jpege_proc_jpeg_cfg(&cfg->codec.jpeg, &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;
}
} break; } break;
case MPP_ENC_SET_IDR_FRAME : case MPP_ENC_SET_IDR_FRAME :
case MPP_ENC_SET_OSD_PLT_CFG : case MPP_ENC_SET_OSD_PLT_CFG :

View File

@@ -27,6 +27,7 @@
#include "mpp.h" #include "mpp.h"
#include "mpp_enc_debug.h" #include "mpp_enc_debug.h"
#include "mpp_enc_cfg_impl.h"
#include "mpp_enc_impl.h" #include "mpp_enc_impl.h"
#include "mpp_hal.h" #include "mpp_hal.h"
#include "hal_h264e_api.h" #include "hal_h264e_api.h"
@@ -601,9 +602,10 @@ MPP_RET mpp_enc_control(MppEnc ctx, MpiCmd cmd, void *param)
switch (cmd) { switch (cmd) {
case MPP_ENC_SET_CFG : { case MPP_ENC_SET_CFG : {
MppEncRcCfg *rc = &enc->set.rc; MppEncRcCfg *rc = &enc->set.rc;
MppEncCfgImpl *cfg = (MppEncCfgImpl *)param;
enc_dbg_ctrl("set all config\n"); 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) if (rc->rc_mode == MPP_ENC_RC_MODE_VBR && rc->quality == MPP_ENC_RC_QUALITY_CQP)
rc->rc_mode = MPP_ENC_RC_MODE_FIXQP; 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); ret = mpp_hal_control(enc->hal, MPP_ENC_SET_CODEC_CFG, &enc->set.codec);
} break; } break;
case MPP_ENC_GET_CFG : { case MPP_ENC_GET_CFG : {
MppEncCfgSet *p = (MppEncCfgSet *)param; MppEncCfgImpl *p = (MppEncCfgImpl *)param;
enc_dbg_ctrl("get all config\n"); enc_dbg_ctrl("get all config\n");
memcpy(p, &enc->cfg, sizeof(*p)); memcpy(&p->cfg, &enc->cfg, sizeof(enc->cfg));
} break; } break;
case MPP_ENC_SET_PREP_CFG : { case MPP_ENC_SET_PREP_CFG : {
enc_dbg_ctrl("set prep config\n"); enc_dbg_ctrl("set prep config\n");

View File

@@ -27,6 +27,7 @@
#include "mpp.h" #include "mpp.h"
#include "mpp_enc_debug.h" #include "mpp_enc_debug.h"
#include "mpp_enc_cfg_impl.h"
#include "mpp_enc_impl.h" #include "mpp_enc_impl.h"
#include "mpp_enc_hal.h" #include "mpp_enc_hal.h"
#include "hal_h264e_api_v2.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) { switch (cmd) {
case MPP_ENC_GET_CFG : { case MPP_ENC_GET_CFG : {
MppEncCfgImpl *p = (MppEncCfgImpl *)param;
enc_dbg_ctrl("get all config\n"); enc_dbg_ctrl("get all config\n");
memcpy(param, &enc->cfg, sizeof(enc->cfg)); memcpy(&p->cfg, &enc->cfg, sizeof(enc->cfg));
} break; } break;
case MPP_ENC_GET_PREP_CFG : { case MPP_ENC_GET_PREP_CFG : {
enc_dbg_ctrl("get prep config\n"); enc_dbg_ctrl("get prep config\n");

View File

@@ -87,17 +87,11 @@ static MppFrameFormat vpu_pic_type_remap_to_mpp(EncInputPictureType type)
return ret; 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, MppCodingType coding, MppFrameFormat fmt,
EncParameter_t *cfg) EncParameter_t *cfg)
{ {
MPP_RET ret = MPP_OK; 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 width = cfg->width;
RK_S32 height = cfg->height; RK_S32 height = cfg->height;
RK_S32 bps = cfg->bitRate; 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(height);
mpp_assert(qp); 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 | prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT |
MPP_ENC_PREP_CFG_CHANGE_FORMAT; MPP_ENC_PREP_CFG_CHANGE_FORMAT;
prep_cfg->width = width; 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); ret = mpi->control(mpp_ctx, MPP_ENC_SET_CODEC_CFG, codec_cfg);
if (ret) if (ret)
mpp_err("setup codec config failed ret %d\n", ret); mpp_err("setup codec config failed ret %d\n", ret);
#endif
RET: RET:
return ret; return ret;
} }
@@ -294,13 +340,14 @@ VpuApiLegacy::VpuApiLegacy() :
format(MPP_FMT_YUV420P), format(MPP_FMT_YUV420P),
fd_input(-1), fd_input(-1),
fd_output(-1), fd_output(-1),
mEosSet(0) mEosSet(0),
enc_cfg(NULL)
{ {
vpu_api_dbg_func("enter\n"); vpu_api_dbg_func("enter\n");
mpp_create(&mpp_ctx, &mpi); 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"); vpu_api_dbg_func("leave\n");
} }
@@ -308,12 +355,17 @@ VpuApiLegacy::~VpuApiLegacy()
{ {
vpu_api_dbg_func("enter\n"); vpu_api_dbg_func("enter\n");
mpp_destroy(mpp_ctx);
if (memGroup) { if (memGroup) {
mpp_buffer_group_put(memGroup); mpp_buffer_group_put(memGroup);
memGroup = NULL; memGroup = NULL;
} }
mpp_destroy(mpp_ctx); if (enc_cfg) {
mpp_enc_cfg_deinit(enc_cfg);
enc_cfg = NULL;
}
vpu_api_dbg_func("leave\n"); 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) { if (memGroup == NULL) {
ret = mpp_buffer_group_get_internal(&memGroup, MPP_BUFFER_TYPE_ION); ret = mpp_buffer_group_get_internal(&memGroup, MPP_BUFFER_TYPE_ION);
if (MPP_OK != ret) { if (ret) {
mpp_err("memGroup mpp_buffer_group_get failed\n"); mpp_err("memGroup mpp_buffer_group_get failed %d\n", ret);
return 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); format = vpu_pic_type_remap_to_mpp((EncInputPictureType)param->format);
memcpy(&enc_cfg, param, sizeof(enc_cfg)); memcpy(&enc_param, param, sizeof(enc_param));
vpu_api_set_enc_cfg(mpp_ctx, mpi, coding, format, param); vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, param);
mpi->control(mpp_ctx, MPP_ENC_GET_EXTRA_INFO, &pkt); 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 : { case VPU_API_ENC_SETCFG : {
MppCodingType coding = (MppCodingType)ctx->videoCoding; MppCodingType coding = (MppCodingType)ctx->videoCoding;
memcpy(&enc_cfg, param, sizeof(enc_cfg)); memcpy(&enc_param, param, sizeof(enc_param));
return vpu_api_set_enc_cfg(mpp_ctx, mpi, coding, format, &enc_cfg); return vpu_api_set_enc_cfg(mpp_ctx, mpi, enc_cfg, coding, format, &enc_param);
} break; } break;
case VPU_API_ENC_GETCFG : { case VPU_API_ENC_GETCFG : {
memcpy(param, &enc_cfg, sizeof(enc_cfg)); memcpy(param, &enc_param, sizeof(enc_param));
return 0; return 0;
} break; } break;
case VPU_API_ENC_SETFORMAT : { case VPU_API_ENC_SETFORMAT : {

View File

@@ -21,6 +21,7 @@
#include "vpu_api.h" #include "vpu_api.h"
#include "rk_mpi.h" #include "rk_mpi.h"
#include "rk_venc_cfg.h"
#define OMX_BUFFERFLAG_EOS 0x00000001 #define OMX_BUFFERFLAG_EOS 0x00000001
@@ -79,7 +80,8 @@ private:
RK_U32 mEosSet; RK_U32 mEosSet;
EncParameter_t enc_cfg; EncParameter_t enc_param;
MppEncCfg enc_cfg;
}; };
#endif /*_VPU_API_H_*/ #endif /*_VPU_API_H_*/