mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-09-29 22:42:06 +08:00

if input file name is start with "/dev/video", default open camera device as input. Change-Id: I85d639ddb6fa5d99413ea75a0b088c79798dd6c8 Signed-off-by: sayon.chen <sayon.chen@rock-chips.com>
1101 lines
34 KiB
C
1101 lines
34 KiB
C
/*
|
|
* Copyright 2015 Rockchip Electronics Co. LTD
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#if defined(_WIN32)
|
|
#include "vld.h"
|
|
#endif
|
|
|
|
#define MODULE_TAG "mpi_enc_test"
|
|
|
|
#include <string.h>
|
|
#include "rk_mpi.h"
|
|
|
|
#include "mpp_env.h"
|
|
#include "mpp_mem.h"
|
|
#include "mpp_log.h"
|
|
#include "mpp_time.h"
|
|
#include "mpp_common.h"
|
|
|
|
#include "utils.h"
|
|
#include "mpi_enc_utils.h"
|
|
#include "camera_source.h"
|
|
|
|
typedef struct {
|
|
// global flow control flag
|
|
RK_U32 frm_eos;
|
|
RK_U32 pkt_eos;
|
|
RK_S32 frame_count;
|
|
RK_U64 stream_size;
|
|
|
|
// src and dst
|
|
FILE *fp_input;
|
|
FILE *fp_output;
|
|
|
|
// base flow context
|
|
MppCtx ctx;
|
|
MppApi *mpi;
|
|
RK_U32 use_legacy_cfg;
|
|
MppEncCfg cfg;
|
|
MppEncPrepCfg prep_cfg;
|
|
MppEncRcCfg rc_cfg;
|
|
MppEncCodecCfg codec_cfg;
|
|
MppEncSliceSplit split_cfg;
|
|
MppEncOSDPltCfg osd_plt_cfg;
|
|
MppEncOSDPlt osd_plt;
|
|
MppEncOSDData osd_data;
|
|
MppEncROIRegion roi_region[3];
|
|
MppEncROICfg roi_cfg;
|
|
|
|
// input / output
|
|
MppBufferGroup buf_grp;
|
|
MppBuffer frm_buf;
|
|
MppBuffer pkt_buf;
|
|
MppEncSeiMode sei_mode;
|
|
MppEncHeaderMode header_mode;
|
|
MppBuffer osd_idx_buf;
|
|
|
|
// paramter for resource malloc
|
|
RK_U32 width;
|
|
RK_U32 height;
|
|
RK_U32 hor_stride;
|
|
RK_U32 ver_stride;
|
|
MppFrameFormat fmt;
|
|
MppCodingType type;
|
|
RK_S32 num_frames;
|
|
RK_S32 loop_times;
|
|
CamSource *cam_ctx;
|
|
|
|
// resources
|
|
size_t header_size;
|
|
size_t frame_size;
|
|
/* NOTE: packet buffer may overflow */
|
|
size_t packet_size;
|
|
/*
|
|
* osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes).
|
|
* for general use, 1/8 Y buffer is enough.
|
|
*/
|
|
size_t osd_idx_size;
|
|
RK_U32 plt_table[8];
|
|
|
|
RK_U32 osd_enable;
|
|
RK_U32 osd_mode;
|
|
RK_U32 split_mode;
|
|
RK_U32 split_arg;
|
|
|
|
RK_U32 user_data_enable;
|
|
RK_U32 roi_enable;
|
|
|
|
// rate control runtime parameter
|
|
|
|
RK_S32 fps_in_flex;
|
|
RK_S32 fps_in_den;
|
|
RK_S32 fps_in_num;
|
|
RK_S32 fps_out_flex;
|
|
RK_S32 fps_out_den;
|
|
RK_S32 fps_out_num;
|
|
RK_S32 bps;
|
|
RK_S32 bps_max;
|
|
RK_S32 bps_min;
|
|
RK_S32 rc_mode;
|
|
RK_S32 gop_mode;
|
|
RK_S32 gop_len;
|
|
RK_S32 vi_len;
|
|
} MpiEncTestData;
|
|
|
|
MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd)
|
|
{
|
|
MpiEncTestData *p = NULL;
|
|
MPP_RET ret = MPP_OK;
|
|
|
|
if (!data || !cmd) {
|
|
mpp_err_f("invalid input data %p cmd %p\n", data, cmd);
|
|
return MPP_ERR_NULL_PTR;
|
|
}
|
|
|
|
p = mpp_calloc(MpiEncTestData, 1);
|
|
if (!p) {
|
|
mpp_err_f("create MpiEncTestData failed\n");
|
|
ret = MPP_ERR_MALLOC;
|
|
goto RET;
|
|
}
|
|
|
|
// get paramter from cmd
|
|
p->width = cmd->width;
|
|
p->height = cmd->height;
|
|
p->hor_stride = (cmd->hor_stride) ? (cmd->hor_stride) :
|
|
(MPP_ALIGN(cmd->width, 16));
|
|
p->ver_stride = (cmd->ver_stride) ? (cmd->ver_stride) :
|
|
(MPP_ALIGN(cmd->height, 16));
|
|
p->fmt = cmd->format;
|
|
p->type = cmd->type;
|
|
p->bps = cmd->bps_target;
|
|
p->bps_min = cmd->bps_min;
|
|
p->bps_max = cmd->bps_max;
|
|
p->rc_mode = cmd->rc_mode;
|
|
p->num_frames = cmd->num_frames;
|
|
if (cmd->type == MPP_VIDEO_CodingMJPEG && p->num_frames == 0) {
|
|
mpp_log("jpege default encode only one frame. Use -n [num] for rc case\n");
|
|
p->num_frames = 1;
|
|
}
|
|
p->gop_mode = cmd->gop_mode;
|
|
p->gop_len = cmd->gop_len;
|
|
p->vi_len = cmd->vi_len;
|
|
|
|
p->fps_in_flex = cmd->fps_in_flex;
|
|
p->fps_in_den = cmd->fps_in_den;
|
|
p->fps_in_num = cmd->fps_in_num;
|
|
p->fps_out_flex = cmd->fps_out_flex;
|
|
p->fps_out_den = cmd->fps_out_den;
|
|
p->fps_out_num = cmd->fps_out_num;
|
|
|
|
if (cmd->file_input) {
|
|
if (!strncmp(cmd->file_input, "/dev/video", 10)) {
|
|
mpp_log("open camera device");
|
|
p->cam_ctx = camera_source_init(cmd->file_input, 4, p->width, p->height, p->fmt);
|
|
mpp_log("new framecap ok");
|
|
if (p->cam_ctx == NULL)
|
|
mpp_err("open %s fail", cmd->file_input);
|
|
} else {
|
|
p->fp_input = fopen(cmd->file_input, "rb");
|
|
if (NULL == p->fp_input) {
|
|
mpp_err("failed to open input file %s\n", cmd->file_input);
|
|
mpp_err("create default yuv image for test\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cmd->file_output) {
|
|
p->fp_output = fopen(cmd->file_output, "w+b");
|
|
if (NULL == p->fp_output) {
|
|
mpp_err("failed to open output file %s\n", cmd->file_output);
|
|
ret = MPP_ERR_OPEN_FILE;
|
|
}
|
|
}
|
|
|
|
// update resource parameter
|
|
switch (p->fmt & MPP_FRAME_FMT_MASK) {
|
|
case MPP_FMT_YUV420SP:
|
|
case MPP_FMT_YUV420P: {
|
|
p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 3 / 2;
|
|
} break;
|
|
|
|
case MPP_FMT_YUV422_YUYV :
|
|
case MPP_FMT_YUV422_YVYU :
|
|
case MPP_FMT_YUV422_UYVY :
|
|
case MPP_FMT_YUV422_VYUY :
|
|
case MPP_FMT_YUV422P :
|
|
case MPP_FMT_YUV422SP :
|
|
case MPP_FMT_RGB444 :
|
|
case MPP_FMT_BGR444 :
|
|
case MPP_FMT_RGB555 :
|
|
case MPP_FMT_BGR555 :
|
|
case MPP_FMT_RGB565 :
|
|
case MPP_FMT_BGR565 : {
|
|
p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 2;
|
|
} break;
|
|
|
|
default: {
|
|
p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4;
|
|
} break;
|
|
}
|
|
|
|
if (MPP_FRAME_FMT_IS_FBC(p->fmt))
|
|
p->header_size = MPP_ALIGN(MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16, SZ_4K);
|
|
else
|
|
p->header_size = 0;
|
|
|
|
/*
|
|
* osd idx size range from 16x16 bytes(pixels) to hor_stride*ver_stride(bytes).
|
|
* for general use, 1/8 Y buffer is enough.
|
|
*/
|
|
p->osd_idx_size = p->hor_stride * p->ver_stride / 8;
|
|
p->plt_table[0] = MPP_ENC_OSD_PLT_RED;
|
|
p->plt_table[1] = MPP_ENC_OSD_PLT_YELLOW;
|
|
p->plt_table[2] = MPP_ENC_OSD_PLT_BLUE;
|
|
p->plt_table[3] = MPP_ENC_OSD_PLT_GREEN;
|
|
p->plt_table[4] = MPP_ENC_OSD_PLT_CYAN;
|
|
p->plt_table[5] = MPP_ENC_OSD_PLT_TRANS;
|
|
p->plt_table[6] = MPP_ENC_OSD_PLT_BLACK;
|
|
p->plt_table[7] = MPP_ENC_OSD_PLT_WHITE;
|
|
|
|
RET:
|
|
*data = p;
|
|
return ret;
|
|
}
|
|
|
|
MPP_RET test_ctx_deinit(MpiEncTestData **data)
|
|
{
|
|
MpiEncTestData *p = NULL;
|
|
|
|
if (!data) {
|
|
mpp_err_f("invalid input data %p\n", data);
|
|
return MPP_ERR_NULL_PTR;
|
|
}
|
|
p = *data;
|
|
if (p) {
|
|
if (p->cam_ctx) {
|
|
camera_source_deinit(p->cam_ctx);
|
|
p->cam_ctx = NULL;
|
|
}
|
|
if (p->fp_input) {
|
|
fclose(p->fp_input);
|
|
p->fp_input = NULL;
|
|
}
|
|
if (p->fp_output) {
|
|
fclose(p->fp_output);
|
|
p->fp_output = NULL;
|
|
}
|
|
MPP_FREE(p);
|
|
*data = NULL;
|
|
}
|
|
return MPP_OK;
|
|
}
|
|
|
|
MPP_RET test_mpp_setup_legacy(MpiEncTestData *p)
|
|
{
|
|
MPP_RET ret;
|
|
MppApi *mpi;
|
|
MppCtx ctx;
|
|
MppEncCodecCfg *codec_cfg;
|
|
MppEncPrepCfg *prep_cfg;
|
|
MppEncRcCfg *rc_cfg;
|
|
MppEncSliceSplit *split_cfg;
|
|
|
|
if (NULL == p)
|
|
return MPP_ERR_NULL_PTR;
|
|
|
|
mpi = p->mpi;
|
|
ctx = p->ctx;
|
|
codec_cfg = &p->codec_cfg;
|
|
prep_cfg = &p->prep_cfg;
|
|
rc_cfg = &p->rc_cfg;
|
|
split_cfg = &p->split_cfg;
|
|
|
|
/* setup default parameter */
|
|
if (p->fps_in_den == 0)
|
|
p->fps_in_den = 1;
|
|
if (p->fps_in_num == 0)
|
|
p->fps_in_num = 30;
|
|
if (p->fps_out_den == 0)
|
|
p->fps_out_den = 1;
|
|
if (p->fps_out_num == 0)
|
|
p->fps_out_num = 30;
|
|
|
|
|
|
if (!p->bps)
|
|
p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
|
|
|
|
prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT |
|
|
MPP_ENC_PREP_CFG_CHANGE_ROTATION |
|
|
MPP_ENC_PREP_CFG_CHANGE_FORMAT;
|
|
prep_cfg->width = p->width;
|
|
prep_cfg->height = p->height;
|
|
prep_cfg->hor_stride = p->hor_stride;
|
|
prep_cfg->ver_stride = p->ver_stride;
|
|
prep_cfg->format = p->fmt;
|
|
prep_cfg->rotation = MPP_ENC_ROT_0;
|
|
ret = mpi->control(ctx, MPP_ENC_SET_PREP_CFG, prep_cfg);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set prep cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
|
|
rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL;
|
|
rc_cfg->rc_mode = p->rc_mode;
|
|
rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM;
|
|
|
|
if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
|
|
/* constant QP does not have bps */
|
|
rc_cfg->bps_target = -1;
|
|
rc_cfg->bps_max = -1;
|
|
rc_cfg->bps_min = -1;
|
|
} else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_CBR) {
|
|
/* constant bitrate has very small bps range of 1/16 bps */
|
|
rc_cfg->bps_target = p->bps;
|
|
rc_cfg->bps_max = p->bps_max ? p->bps_max : p->bps * 17 / 16;
|
|
rc_cfg->bps_min = p->bps_min ? p->bps_min : p->bps * 15 / 16;
|
|
} else {
|
|
/* variable bitrate has large bps range */
|
|
rc_cfg->bps_target = p->bps;
|
|
rc_cfg->bps_max = p->bps_max ? p->bps_max : p->bps * 17 / 16;
|
|
rc_cfg->bps_min = p->bps_min ? p->bps_min : p->bps * 1 / 16;
|
|
}
|
|
|
|
/* fix input / output frame rate */
|
|
rc_cfg->fps_in_flex = p->fps_in_flex;
|
|
rc_cfg->fps_in_num = p->fps_in_num;
|
|
rc_cfg->fps_in_denorm = p->fps_in_den;
|
|
rc_cfg->fps_out_flex = p->fps_out_flex;
|
|
rc_cfg->fps_out_num = p->fps_out_num;
|
|
rc_cfg->fps_out_denorm = p->fps_out_den;
|
|
|
|
rc_cfg->max_reenc_times = 1;
|
|
rc_cfg->gop = p->gop_len ? p->gop_len : p->fps_out_num * 2;
|
|
|
|
mpp_log("%p mpi_enc_test bps %d fps %d gop %d\n", ctx,
|
|
rc_cfg->bps_target, rc_cfg->fps_out_num, rc_cfg->gop);
|
|
ret = mpi->control(ctx, MPP_ENC_SET_RC_CFG, rc_cfg);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set rc cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
|
|
codec_cfg->coding = p->type;
|
|
switch (codec_cfg->coding) {
|
|
case MPP_VIDEO_CodingAVC : {
|
|
codec_cfg->h264.change = MPP_ENC_H264_CFG_CHANGE_PROFILE |
|
|
MPP_ENC_H264_CFG_CHANGE_ENTROPY |
|
|
MPP_ENC_H264_CFG_CHANGE_TRANS_8x8;
|
|
/*
|
|
* H.264 profile_idc parameter
|
|
* 66 - Baseline profile
|
|
* 77 - Main profile
|
|
* 100 - High profile
|
|
*/
|
|
codec_cfg->h264.profile = 100;
|
|
/*
|
|
* H.264 level_idc parameter
|
|
* 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
|
|
* 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps
|
|
* 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps
|
|
* 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps
|
|
* 50 / 51 / 52 - 4K@30fps
|
|
*/
|
|
codec_cfg->h264.level = 40;
|
|
codec_cfg->h264.entropy_coding_mode = 1;
|
|
codec_cfg->h264.cabac_init_idc = 0;
|
|
codec_cfg->h264.transform8x8_mode = 1;
|
|
} break;
|
|
case MPP_VIDEO_CodingMJPEG : {
|
|
codec_cfg->jpeg.change = MPP_ENC_JPEG_CFG_CHANGE_QP;
|
|
codec_cfg->jpeg.quant = 10;
|
|
} break;
|
|
case MPP_VIDEO_CodingVP8 : {
|
|
} break;
|
|
case MPP_VIDEO_CodingHEVC : {
|
|
codec_cfg->h265.change = MPP_ENC_H265_CFG_INTRA_QP_CHANGE | MPP_ENC_H265_CFG_RC_QP_CHANGE;
|
|
if (rc_cfg->rc_mode != MPP_ENC_RC_MODE_FIXQP)
|
|
codec_cfg->h265.qp_init = -1;
|
|
else
|
|
codec_cfg->h265.qp_init = 26;
|
|
codec_cfg->h265.max_i_qp = 46;
|
|
codec_cfg->h265.min_i_qp = 24;
|
|
codec_cfg->h265.max_qp = 51;
|
|
codec_cfg->h265.min_qp = 10;
|
|
if (0) {
|
|
codec_cfg->h265.change |= MPP_ENC_H265_CFG_SLICE_CHANGE;
|
|
codec_cfg->h265.slice_cfg.split_enable = 1;
|
|
codec_cfg->h265.slice_cfg.split_mode = 1;
|
|
codec_cfg->h265.slice_cfg.slice_size = 10;
|
|
}
|
|
} break;
|
|
default : {
|
|
mpp_err_f("support encoder coding type %d\n", codec_cfg->coding);
|
|
} break;
|
|
}
|
|
|
|
ret = mpi->control(ctx, MPP_ENC_SET_CODEC_CFG, codec_cfg);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set codec cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
|
|
p->split_mode = 0;
|
|
p->split_arg = 0;
|
|
|
|
mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE);
|
|
mpp_env_get_u32("split_arg", &p->split_arg, 0);
|
|
|
|
if (p->split_mode) {
|
|
split_cfg->change = MPP_ENC_SPLIT_CFG_CHANGE_ALL;
|
|
split_cfg->split_mode = p->split_mode;
|
|
split_cfg->split_arg = p->split_arg;
|
|
|
|
mpp_log("%p split_mode %d split_arg %d\n", ctx, p->split_mode, p->split_arg);
|
|
|
|
ret = mpi->control(ctx, MPP_ENC_SET_SPLIT, split_cfg);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set codec cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
}
|
|
|
|
/* optional */
|
|
p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
|
|
ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
|
|
if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
|
|
p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
|
|
ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set header mode failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
}
|
|
|
|
RK_U32 gop_mode = p->gop_mode;
|
|
|
|
mpp_env_get_u32("gop_mode", &gop_mode, gop_mode);
|
|
if (gop_mode) {
|
|
MppEncRefCfg ref;
|
|
|
|
mpp_enc_ref_cfg_init(&ref);
|
|
mpi_enc_gen_ref_cfg(ref, gop_mode);
|
|
ret = mpi->control(ctx, MPP_ENC_SET_REF_CFG, ref);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set ref cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
mpp_enc_ref_cfg_deinit(&ref);
|
|
}
|
|
|
|
/* setup test mode by env */
|
|
mpp_env_get_u32("osd_enable", &p->osd_enable, 0);
|
|
mpp_env_get_u32("osd_mode", &p->osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT);
|
|
|
|
if (p->osd_enable) {
|
|
/* gen and cfg osd plt */
|
|
mpi_enc_gen_osd_plt(&p->osd_plt, p->plt_table);
|
|
p->osd_plt_cfg.change = MPP_ENC_OSD_PLT_CFG_CHANGE_ALL;
|
|
p->osd_plt_cfg.type = MPP_ENC_OSD_PLT_TYPE_USERDEF;
|
|
p->osd_plt_cfg.plt = &p->osd_plt;
|
|
|
|
ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt_cfg);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set osd plt failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
}
|
|
|
|
mpp_env_get_u32("osd_enable", &p->user_data_enable, 0);
|
|
mpp_env_get_u32("roi_enable", &p->roi_enable, 0);
|
|
|
|
RET:
|
|
return ret;
|
|
}
|
|
|
|
MPP_RET test_mpp_enc_cfg_setup(MpiEncTestData *p)
|
|
{
|
|
MPP_RET ret;
|
|
MppApi *mpi;
|
|
MppCtx ctx;
|
|
MppEncCfg cfg;
|
|
|
|
if (NULL == p)
|
|
return MPP_ERR_NULL_PTR;
|
|
|
|
mpi = p->mpi;
|
|
ctx = p->ctx;
|
|
cfg = p->cfg;
|
|
|
|
/* setup default parameter */
|
|
if (p->fps_in_den == 0)
|
|
p->fps_in_den = 1;
|
|
if (p->fps_in_num == 0)
|
|
p->fps_in_num = 30;
|
|
if (p->fps_out_den == 0)
|
|
p->fps_out_den = 1;
|
|
if (p->fps_out_num == 0)
|
|
p->fps_out_num = 30;
|
|
|
|
if (!p->bps)
|
|
p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
|
|
|
|
|
|
mpp_enc_cfg_set_s32(cfg, "prep:width", p->width);
|
|
mpp_enc_cfg_set_s32(cfg, "prep:height", p->height);
|
|
mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", p->hor_stride);
|
|
mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", p->ver_stride);
|
|
mpp_enc_cfg_set_s32(cfg, "prep:format", p->fmt);
|
|
|
|
mpp_enc_cfg_set_s32(cfg, "rc:mode", p->rc_mode);
|
|
|
|
switch (p->rc_mode) {
|
|
case MPP_ENC_RC_MODE_FIXQP : {
|
|
/* do not set bps on fix qp mode */
|
|
} break;
|
|
case MPP_ENC_RC_MODE_CBR : {
|
|
/* CBR mode has narrow bound */
|
|
mpp_enc_cfg_set_s32(cfg, "rc:bps_target", p->bps);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
|
|
} break;
|
|
case MPP_ENC_RC_MODE_VBR : {
|
|
/* CBR mode has wide bound */
|
|
mpp_enc_cfg_set_s32(cfg, "rc:bps_target", p->bps);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 1 / 16);
|
|
} break;
|
|
default : {
|
|
mpp_err_f("unsupport encoder rc mode %d\n", p->rc_mode);
|
|
} break;
|
|
}
|
|
|
|
/* fix input / output frame rate */
|
|
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", p->fps_in_flex);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", p->fps_in_num);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denorm", p->fps_in_den);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", p->fps_out_flex);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num", p->fps_out_num);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denorm", p->fps_out_den);
|
|
mpp_enc_cfg_set_s32(cfg, "rc:gop", p->gop_len ? p->gop_len : p->fps_out_num * 2);
|
|
|
|
/* setup codec */
|
|
mpp_enc_cfg_set_s32(cfg, "codec:type", p->type);
|
|
switch (p->type) {
|
|
case MPP_VIDEO_CodingAVC : {
|
|
/*
|
|
* H.264 profile_idc parameter
|
|
* 66 - Baseline profile
|
|
* 77 - Main profile
|
|
* 100 - High profile
|
|
*/
|
|
mpp_enc_cfg_set_s32(cfg, "h264:profile", 100);
|
|
/*
|
|
* H.264 level_idc parameter
|
|
* 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
|
|
* 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps
|
|
* 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps
|
|
* 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps
|
|
* 50 / 51 / 52 - 4K@30fps
|
|
*/
|
|
mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
|
|
|
|
if (p->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_init", 20);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_max", 16);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_min", 16);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_max_i", 20);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_min_i", 20);
|
|
} else {
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_init", 26);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_max", 51);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_min", 10);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_max_i", 46);
|
|
mpp_enc_cfg_set_s32(cfg, "h264:qp_min_i", 24);
|
|
}
|
|
} break;
|
|
case MPP_VIDEO_CodingMJPEG : {
|
|
mpp_enc_cfg_set_s32(cfg, "jpeg:q_factor", 80);
|
|
mpp_enc_cfg_set_s32(cfg, "jpeg:qf_max", 99);
|
|
mpp_enc_cfg_set_s32(cfg, "jpeg:qf_min", 1);
|
|
} break;
|
|
case MPP_VIDEO_CodingVP8 : {
|
|
mpp_enc_cfg_set_s32(cfg, "vp8:qp_init", 40);
|
|
mpp_enc_cfg_set_s32(cfg, "vp8:qp_max", 127);
|
|
mpp_enc_cfg_set_s32(cfg, "vp8:qp_min", 0);
|
|
mpp_enc_cfg_set_s32(cfg, "vp8:qp_max_i", 127);
|
|
mpp_enc_cfg_set_s32(cfg, "vp8:qp_min_i", 0);
|
|
} break;
|
|
case MPP_VIDEO_CodingHEVC : {
|
|
mpp_enc_cfg_set_s32(cfg, "h265:qp_init", p->rc_mode == MPP_ENC_RC_MODE_FIXQP ? -1 : 26);
|
|
mpp_enc_cfg_set_s32(cfg, "h265:qp_max", 51);
|
|
mpp_enc_cfg_set_s32(cfg, "h265:qp_min", 10);
|
|
mpp_enc_cfg_set_s32(cfg, "h265:qp_max_i", 46);
|
|
mpp_enc_cfg_set_s32(cfg, "h265:qp_min_i", 24);
|
|
} break;
|
|
default : {
|
|
mpp_err_f("unsupport encoder coding type %d\n", p->type);
|
|
} break;
|
|
}
|
|
|
|
p->split_mode = 0;
|
|
p->split_arg = 0;
|
|
|
|
mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE);
|
|
mpp_env_get_u32("split_arg", &p->split_arg, 0);
|
|
|
|
if (p->split_mode) {
|
|
mpp_log("%p split_mode %d split_arg %d\n", ctx, p->split_mode, p->split_arg);
|
|
mpp_enc_cfg_set_s32(cfg, "split:mode", p->split_mode);
|
|
mpp_enc_cfg_set_s32(cfg, "split:arg", p->split_arg);
|
|
}
|
|
|
|
ret = mpi->control(ctx, MPP_ENC_SET_CFG, cfg);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
|
|
/* optional */
|
|
p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
|
|
ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
|
|
if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
|
|
p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
|
|
ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set header mode failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
}
|
|
|
|
RK_U32 gop_mode = p->gop_mode;
|
|
|
|
mpp_env_get_u32("gop_mode", &gop_mode, gop_mode);
|
|
if (gop_mode) {
|
|
MppEncRefCfg ref;
|
|
|
|
mpp_enc_ref_cfg_init(&ref);
|
|
|
|
if (p->gop_mode < 4)
|
|
mpi_enc_gen_ref_cfg(ref, gop_mode);
|
|
else
|
|
mpi_enc_gen_smart_gop_ref_cfg(ref, p->gop_len, p->vi_len);
|
|
|
|
ret = mpi->control(ctx, MPP_ENC_SET_REF_CFG, ref);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set ref cfg failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
mpp_enc_ref_cfg_deinit(&ref);
|
|
}
|
|
|
|
/* setup test mode by env */
|
|
mpp_env_get_u32("osd_enable", &p->osd_enable, 0);
|
|
mpp_env_get_u32("osd_mode", &p->osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT);
|
|
|
|
if (p->osd_enable) {
|
|
/* gen and cfg osd plt */
|
|
mpi_enc_gen_osd_plt(&p->osd_plt, p->plt_table);
|
|
p->osd_plt_cfg.change = MPP_ENC_OSD_PLT_CFG_CHANGE_ALL;
|
|
p->osd_plt_cfg.type = MPP_ENC_OSD_PLT_TYPE_USERDEF;
|
|
p->osd_plt_cfg.plt = &p->osd_plt;
|
|
|
|
ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt_cfg);
|
|
if (ret) {
|
|
mpp_err("mpi control enc set osd plt failed ret %d\n", ret);
|
|
goto RET;
|
|
}
|
|
}
|
|
|
|
mpp_env_get_u32("osd_enable", &p->user_data_enable, 0);
|
|
mpp_env_get_u32("roi_enable", &p->roi_enable, 0);
|
|
|
|
RET:
|
|
return ret;
|
|
}
|
|
|
|
MPP_RET test_mpp_run(MpiEncTestData *p)
|
|
{
|
|
MPP_RET ret = MPP_OK;
|
|
MppApi *mpi;
|
|
MppCtx ctx;
|
|
RK_U32 cap_num = 0;
|
|
|
|
if (NULL == p)
|
|
return MPP_ERR_NULL_PTR;
|
|
|
|
mpi = p->mpi;
|
|
ctx = p->ctx;
|
|
|
|
if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
|
|
MppPacket packet = NULL;
|
|
|
|
/*
|
|
* Can use packet with normal malloc buffer as input not pkt_buf.
|
|
* Please refer to vpu_api_legacy.cpp for normal buffer case.
|
|
* Using pkt_buf buffer here is just for simplifing demo.
|
|
*/
|
|
mpp_packet_init_with_buffer(&packet, p->pkt_buf);
|
|
/* NOTE: It is important to clear output packet length!! */
|
|
mpp_packet_set_length(packet, 0);
|
|
|
|
ret = mpi->control(ctx, MPP_ENC_GET_HDR_SYNC, packet);
|
|
if (ret) {
|
|
mpp_err("mpi control enc get extra info failed\n");
|
|
goto RET;
|
|
} else {
|
|
/* get and write sps/pps for H.264 */
|
|
|
|
void *ptr = mpp_packet_get_pos(packet);
|
|
size_t len = mpp_packet_get_length(packet);
|
|
|
|
if (p->fp_output)
|
|
fwrite(ptr, 1, len, p->fp_output);
|
|
}
|
|
|
|
mpp_packet_deinit(&packet);
|
|
}
|
|
while (!p->pkt_eos) {
|
|
MppMeta meta = NULL;
|
|
MppFrame frame = NULL;
|
|
MppPacket packet = NULL;
|
|
void *buf = mpp_buffer_get_ptr(p->frm_buf);
|
|
RK_S32 cam_frm_idx = -1;
|
|
MppBuffer cam_buf = NULL;
|
|
|
|
if (p->fp_input) {
|
|
ret = read_image(buf, p->fp_input, p->width, p->height,
|
|
p->hor_stride, p->ver_stride, p->fmt);
|
|
if (ret == MPP_NOK || feof(p->fp_input)) {
|
|
p->frm_eos = 1;
|
|
|
|
if (p->num_frames < 0 || p->frame_count < p->num_frames) {
|
|
clearerr(p->fp_input);
|
|
rewind(p->fp_input);
|
|
p->frm_eos = 0;
|
|
mpp_log("%p loop times %d\n", ctx, ++p->loop_times);
|
|
continue;
|
|
}
|
|
mpp_log("%p found last frame. feof %d\n", ctx, feof(p->fp_input));
|
|
} else if (ret == MPP_ERR_VALUE)
|
|
goto RET;
|
|
} else {
|
|
if (p->cam_ctx == NULL) {
|
|
ret = fill_image(buf, p->width, p->height, p->hor_stride,
|
|
p->ver_stride, p->fmt, p->frame_count);
|
|
if (ret)
|
|
goto RET;
|
|
} else {
|
|
cam_frm_idx = camera_source_get_frame(p->cam_ctx);
|
|
mpp_assert(cam_frm_idx >= 0);
|
|
|
|
/* skip unstable frames */
|
|
if (cap_num++ < 50) {
|
|
camera_source_put_frame(p->cam_ctx, cam_frm_idx);
|
|
continue;
|
|
}
|
|
|
|
cam_buf = camera_frame_to_buf(p->cam_ctx, cam_frm_idx);
|
|
mpp_assert(cam_buf);
|
|
}
|
|
}
|
|
|
|
ret = mpp_frame_init(&frame);
|
|
if (ret) {
|
|
mpp_err_f("mpp_frame_init failed\n");
|
|
goto RET;
|
|
}
|
|
|
|
mpp_frame_set_width(frame, p->width);
|
|
mpp_frame_set_height(frame, p->height);
|
|
mpp_frame_set_hor_stride(frame, p->hor_stride);
|
|
mpp_frame_set_ver_stride(frame, p->ver_stride);
|
|
mpp_frame_set_fmt(frame, p->fmt);
|
|
mpp_frame_set_eos(frame, p->frm_eos);
|
|
|
|
if (p->fp_input && feof(p->fp_input))
|
|
mpp_frame_set_buffer(frame, NULL);
|
|
else if (cam_buf)
|
|
mpp_frame_set_buffer(frame, cam_buf);
|
|
else
|
|
mpp_frame_set_buffer(frame, p->frm_buf);
|
|
|
|
meta = mpp_frame_get_meta(frame);
|
|
mpp_packet_init_with_buffer(&packet, p->pkt_buf);
|
|
/* NOTE: It is important to clear output packet length!! */
|
|
mpp_packet_set_length(packet, 0);
|
|
mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, packet);
|
|
|
|
if (p->osd_enable || p->user_data_enable || p->roi_enable) {
|
|
if (p->user_data_enable) {
|
|
MppEncUserData user_data;
|
|
char *str = "this is user data\n";
|
|
|
|
if ((p->frame_count & 10) == 0) {
|
|
user_data.pdata = str;
|
|
user_data.len = strlen(str) + 1;
|
|
mpp_meta_set_ptr(meta, KEY_USER_DATA, &user_data);
|
|
}
|
|
}
|
|
|
|
if (p->osd_enable) {
|
|
/* gen and cfg osd plt */
|
|
mpi_enc_gen_osd_data(&p->osd_data, p->osd_idx_buf, p->frame_count);
|
|
mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)&p->osd_data);
|
|
}
|
|
|
|
if (p->roi_enable) {
|
|
MppEncROIRegion *region = p->roi_region;
|
|
|
|
/* calculated in pixels */
|
|
region->x = 304;
|
|
region->y = 480;
|
|
region->w = 1344;
|
|
region->h = 600;
|
|
region->intra = 0; /* flag of forced intra macroblock */
|
|
region->quality = 24; /* qp of macroblock */
|
|
region->abs_qp_en = 1;
|
|
region->area_map_en = 1;
|
|
region->qp_area_idx = 0;
|
|
|
|
region++;
|
|
region->x = region->y = 16;
|
|
region->w = region->h = 64; /* 16-pixel aligned is better */
|
|
region->intra = 1; /* flag of forced intra macroblock */
|
|
region->quality = 10; /* qp of macroblock */
|
|
region->abs_qp_en = 1;
|
|
region->area_map_en = 1;
|
|
region->qp_area_idx = 1;
|
|
|
|
p->roi_cfg.number = 2;
|
|
p->roi_cfg.regions = p->roi_region;
|
|
|
|
mpp_meta_set_ptr(meta, KEY_ROI_DATA, (void*)&p->roi_cfg); // new way for roi
|
|
}
|
|
}
|
|
|
|
/*
|
|
* NOTE: in non-block mode the frame can be resent.
|
|
* The default input timeout mode is block.
|
|
*
|
|
* User should release the input frame to meet the requirements of
|
|
* resource creator must be the resource destroyer.
|
|
*/
|
|
ret = mpi->encode_put_frame(ctx, frame);
|
|
if (ret) {
|
|
mpp_err("mpp encode put frame failed\n");
|
|
mpp_frame_deinit(&frame);
|
|
goto RET;
|
|
}
|
|
mpp_frame_deinit(&frame);
|
|
|
|
ret = mpi->encode_get_packet(ctx, &packet);
|
|
if (ret) {
|
|
mpp_err("mpp encode get packet failed\n");
|
|
goto RET;
|
|
}
|
|
|
|
mpp_assert(packet);
|
|
|
|
if (packet) {
|
|
// write packet to file here
|
|
void *ptr = mpp_packet_get_pos(packet);
|
|
size_t len = mpp_packet_get_length(packet);
|
|
char log_buf[256];
|
|
RK_S32 log_size = sizeof(log_buf) - 1;
|
|
RK_S32 log_len = 0;
|
|
|
|
p->pkt_eos = mpp_packet_get_eos(packet);
|
|
|
|
if (p->fp_output)
|
|
fwrite(ptr, 1, len, p->fp_output);
|
|
|
|
log_len += snprintf(log_buf + log_len, log_size - log_len,
|
|
"encoded frame %-4d size %-7d",
|
|
p->frame_count, len);
|
|
|
|
if (mpp_packet_has_meta(packet)) {
|
|
meta = mpp_packet_get_meta(packet);
|
|
RK_S32 temporal_id = 0;
|
|
RK_S32 lt_idx = -1;
|
|
|
|
if (MPP_OK == mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &temporal_id))
|
|
log_len += snprintf(log_buf + log_len, log_size - log_len,
|
|
" tid %d", temporal_id);
|
|
|
|
if (MPP_OK == mpp_meta_get_s32(meta, KEY_LONG_REF_IDX, <_idx))
|
|
log_len += snprintf(log_buf + log_len, log_size - log_len,
|
|
" lt %d", lt_idx);
|
|
}
|
|
|
|
mpp_log("%p %s\n", ctx, log_buf);
|
|
|
|
mpp_packet_deinit(&packet);
|
|
|
|
p->stream_size += len;
|
|
p->frame_count++;
|
|
|
|
if (p->pkt_eos) {
|
|
mpp_log("%p found last packet\n", ctx);
|
|
mpp_assert(p->frm_eos);
|
|
}
|
|
}
|
|
|
|
if (cam_frm_idx >= 0)
|
|
camera_source_put_frame(p->cam_ctx, cam_frm_idx);
|
|
|
|
if (p->num_frames > 0 && p->frame_count >= p->num_frames) {
|
|
mpp_log("%p encode max %d frames", ctx, p->frame_count);
|
|
break;
|
|
}
|
|
|
|
if (p->frm_eos && p->pkt_eos)
|
|
break;
|
|
}
|
|
RET:
|
|
return ret;
|
|
}
|
|
|
|
int mpi_enc_test(MpiEncTestArgs *cmd)
|
|
{
|
|
MPP_RET ret = MPP_OK;
|
|
MpiEncTestData *p = NULL;
|
|
MppPollType timeout = MPP_POLL_BLOCK;
|
|
|
|
mpp_log("mpi_enc_test start\n");
|
|
|
|
ret = test_ctx_init(&p, cmd);
|
|
if (ret) {
|
|
mpp_err_f("test data init failed ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_DRM);
|
|
if (ret) {
|
|
mpp_err_f("failed to get mpp buffer group ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
ret = mpp_buffer_get(p->buf_grp, &p->frm_buf, p->frame_size + p->header_size);
|
|
if (ret) {
|
|
mpp_err_f("failed to get buffer for input frame ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
ret = mpp_buffer_get(p->buf_grp, &p->pkt_buf, p->frame_size);
|
|
if (ret) {
|
|
mpp_err_f("failed to get buffer for output packet ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
ret = mpp_buffer_get(p->buf_grp, &p->osd_idx_buf, p->osd_idx_size);
|
|
if (ret) {
|
|
mpp_err_f("failed to get buffer for input osd index ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
// encoder demo
|
|
ret = mpp_create(&p->ctx, &p->mpi);
|
|
if (ret) {
|
|
mpp_err("mpp_create failed ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
mpp_log("%p mpi_enc_test encoder test start w %d h %d type %d\n",
|
|
p->ctx, p->width, p->height, p->type);
|
|
|
|
ret = p->mpi->control(p->ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
|
|
if (MPP_OK != ret) {
|
|
mpp_err("mpi control set output timeout %d ret %d\n", timeout, ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type);
|
|
if (ret) {
|
|
mpp_err("mpp_init failed ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
ret = mpp_enc_cfg_init(&p->cfg);
|
|
if (ret) {
|
|
mpp_err_f("mpp_enc_cfg_init failed ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
if (p->use_legacy_cfg)
|
|
ret = test_mpp_setup_legacy(p);
|
|
else
|
|
ret = test_mpp_enc_cfg_setup(p);
|
|
if (ret) {
|
|
mpp_err_f("test mpp setup failed ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
ret = test_mpp_run(p);
|
|
if (ret) {
|
|
mpp_err_f("test mpp run failed ret %d\n", ret);
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
ret = p->mpi->reset(p->ctx);
|
|
if (ret) {
|
|
mpp_err("mpi->reset failed\n");
|
|
goto MPP_TEST_OUT;
|
|
}
|
|
|
|
MPP_TEST_OUT:
|
|
if (MPP_OK == ret)
|
|
mpp_log("%p mpi_enc_test success total frame %d bps %lld\n",
|
|
p->ctx, p->frame_count,
|
|
(RK_U64)((p->stream_size * 8 * (p->fps_out_num / p->fps_out_den)) / p->frame_count));
|
|
else
|
|
mpp_err("%p mpi_enc_test failed ret %d\n", p->ctx, ret);
|
|
|
|
if (p->ctx) {
|
|
mpp_destroy(p->ctx);
|
|
p->ctx = NULL;
|
|
}
|
|
|
|
if (p->cfg) {
|
|
mpp_enc_cfg_deinit(p->cfg);
|
|
p->cfg = NULL;
|
|
}
|
|
|
|
if (p->frm_buf) {
|
|
mpp_buffer_put(p->frm_buf);
|
|
p->frm_buf = NULL;
|
|
}
|
|
|
|
if (p->pkt_buf) {
|
|
mpp_buffer_put(p->pkt_buf);
|
|
p->pkt_buf = NULL;
|
|
}
|
|
|
|
if (p->osd_idx_buf) {
|
|
mpp_buffer_put(p->osd_idx_buf);
|
|
p->osd_idx_buf = NULL;
|
|
}
|
|
|
|
if (p->buf_grp) {
|
|
mpp_buffer_group_put(p->buf_grp);
|
|
p->buf_grp = NULL;
|
|
}
|
|
|
|
test_ctx_deinit(&p);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
RK_S32 ret = MPP_NOK;
|
|
MpiEncTestArgs* cmd = mpi_enc_test_cmd_get();
|
|
|
|
memset((void*)cmd, 0, sizeof(*cmd));
|
|
|
|
// parse the cmd option
|
|
if (argc > 1)
|
|
ret = mpi_enc_test_cmd_update_by_args(cmd, argc, argv);
|
|
|
|
if (ret) {
|
|
mpi_enc_test_help();
|
|
goto DONE;
|
|
}
|
|
|
|
mpi_enc_test_cmd_show_opt(cmd);
|
|
|
|
ret = mpi_enc_test(cmd);
|
|
|
|
DONE:
|
|
mpi_enc_test_cmd_put(cmd);
|
|
|
|
return ret;
|
|
}
|
|
|