diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ecccf1c2..bd7b5b93 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -32,15 +32,9 @@ add_mpp_test(mpi_dec_mt) # mpi encoder unit test add_mpp_test(mpi_enc) -# mpi rc unit test -add_mpp_test(mpi_rc) - # new mpi rc unit test add_mpp_test(mpi_rc2) -# new enc multi unit test -add_mpp_test(mpi_enc_multi) - # new dec multi unit test add_mpp_test(mpi_dec_multi) diff --git a/test/mpi_dec_mt_test.c b/test/mpi_dec_mt_test.c index c4c25944..1c03cd8e 100644 --- a/test/mpi_dec_mt_test.c +++ b/test/mpi_dec_mt_test.c @@ -427,14 +427,8 @@ int main(int argc, char **argv) // parse the cmd option ret = mpi_dec_test_cmd_init(cmd, argc, argv); - if (ret) { - if (ret < 0) { - mpp_err("mpi_dec_test_cmd_init: input parameter invalid\n"); - } - - mpi_dec_test_cmd_help(); + if (ret) goto RET; - } mpi_dec_test_cmd_options(cmd); diff --git a/test/mpi_dec_multi_test.c b/test/mpi_dec_multi_test.c index fa593e63..9253156d 100644 --- a/test/mpi_dec_multi_test.c +++ b/test/mpi_dec_multi_test.c @@ -595,14 +595,8 @@ int main(int argc, char **argv) // parse the cmd option ret = mpi_dec_test_cmd_init(cmd, argc, argv); - if (ret) { - if (ret < 0) { - mpp_err("mpi_dec_multi_test_parse_options: input parameter invalid\n"); - } - - mpi_dec_test_cmd_help(); + if (ret) goto RET; - } mpi_dec_test_cmd_options(cmd); diff --git a/test/mpi_dec_test.c b/test/mpi_dec_test.c index 571e2f8a..1770e22c 100644 --- a/test/mpi_dec_test.c +++ b/test/mpi_dec_test.c @@ -716,14 +716,8 @@ int main(int argc, char **argv) // parse the cmd option ret = mpi_dec_test_cmd_init(cmd, argc, argv); - if (ret) { - if (ret < 0) { - mpp_err("mpi_dec_test_cmd_init: input parameter invalid\n"); - } - - mpi_dec_test_cmd_help(); + if (ret) goto RET; - } mpi_dec_test_cmd_options(cmd); diff --git a/test/mpi_enc_multi_test.c b/test/mpi_enc_multi_test.c deleted file mode 100644 index c3492107..00000000 --- a/test/mpi_enc_multi_test.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * 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_multi_test" - -#include -#include -#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 "vpu_api.h" - - -#define MPI_ENC_IO_COUNT (4) -#define MAX_FILE_NAME_LENGTH 256 - -#define MPI_ENC_TEST_SET_IDR_FRAME 0 - -typedef struct { - char file_input[MAX_FILE_NAME_LENGTH]; - char file_output[MAX_FILE_NAME_LENGTH]; - MppCodingType type; - RK_U32 width; - RK_U32 height; - - RK_U32 hor_stride; - RK_U32 ver_stride; - - MppFrameFormat format; - RK_U32 debug; - RK_U32 num_frames; - RK_U32 target_bps; - - RK_U32 have_input; - RK_U32 have_output; - - RK_U32 payload_cnts; -} MpiEncTestCmd; - -typedef struct { - // global flow control flag - RK_U32 frm_eos; - RK_U32 pkt_eos; - RK_U32 frame_count; - RK_U64 stream_size; - - // src and dst - FILE *fp_input; - FILE *fp_output; - - // base flow context - MppCtx ctx; - MppApi *mpi; - MppEncPrepCfg prep_cfg; - MppEncRcCfg rc_cfg; - MppEncCodecCfg codec_cfg; - - // input / output - MppBufferGroup frm_grp; - MppBufferGroup pkt_grp; - MppBufferGroup buf_grp; - MppFrame frame; - MppPacket packet; - MppBuffer frm_buf[MPI_ENC_IO_COUNT]; - MppBuffer pkt_buf[MPI_ENC_IO_COUNT]; - MppBuffer md_buf[MPI_ENC_IO_COUNT]; - MppEncSeiMode sei_mode; - - // paramter for resource malloc - RK_U32 width; - RK_U32 height; - RK_U32 hor_stride; - RK_U32 ver_stride; - MppFrameFormat fmt; - MppCodingType type; - RK_U32 num_frames; - - // resources - size_t frame_size; - /* NOTE: packet buffer may overflow */ - size_t packet_size; - /* 32bits for each 16x16 block */ - size_t mdinfo_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]; - - // rate control runtime parameter - RK_S32 gop; - RK_S32 fps; - RK_S32 bps; - RK_S32 qp_min; - RK_S32 qp_max; - RK_S32 qp_step; - RK_S32 qp_init; -} MpiEncTestData; - -MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestCmd *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->num_frames = cmd->num_frames; - p->bps = cmd->target_bps; - - if (cmd->have_input) { - 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->have_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 - if (p->fmt <= MPP_FMT_YUV_BUTT) - p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 3 / 2; - else - p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4; - p->packet_size = p->width * p->height; - //NOTE: hor_stride should be 16-MB aligned - p->mdinfo_size = (((p->hor_stride + 255) & (~255)) / 16) * (p->ver_stride / 16) * 4; - /* - * 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->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_res_init(MpiEncTestData *p) -{ - RK_U32 i; - MPP_RET ret; - - mpp_assert(p); - - ret = mpp_buffer_group_get_internal(&p->frm_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("failed to get buffer group for input frame ret %d\n", ret); - goto RET; - } - - ret = mpp_buffer_group_get_internal(&p->pkt_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("failed to get buffer group for output packet ret %d\n", ret); - goto RET; - } - - ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("failed to get buffer group for output packet ret %d\n", ret); - goto RET; - } - - for (i = 0; i < MPI_ENC_IO_COUNT; i++) { - ret = mpp_buffer_get(p->frm_grp, &p->frm_buf[i], p->frame_size); - if (ret) { - mpp_err("failed to get buffer for input frame ret %d\n", ret); - goto RET; - } - - ret = mpp_buffer_get(p->pkt_grp, &p->pkt_buf[i], p->packet_size); - if (ret) { - mpp_err("failed to get buffer for input frame ret %d\n", ret); - goto RET; - } - - ret = mpp_buffer_get(p->pkt_grp, &p->md_buf[i], p->mdinfo_size); - if (ret) { - mpp_err("failed to get buffer for motion detection info ret %d\n", ret); - goto RET; - } - } -RET: - return ret; -} - -MPP_RET test_res_deinit(MpiEncTestData *p) -{ - RK_U32 i; - - mpp_assert(p); - - for (i = 0; i < MPI_ENC_IO_COUNT; i++) { - if (p->frm_buf[i]) { - mpp_buffer_put(p->frm_buf[i]); - p->frm_buf[i] = NULL; - } - - if (p->pkt_buf[i]) { - mpp_buffer_put(p->pkt_buf[i]); - p->pkt_buf[i] = NULL; - } - - if (p->md_buf[i]) { - mpp_buffer_put(p->md_buf[i]); - p->md_buf[i] = NULL; - } - } - - if (p->frm_grp) { - mpp_buffer_group_put(p->frm_grp); - p->frm_grp = NULL; - } - - if (p->pkt_grp) { - mpp_buffer_group_put(p->pkt_grp); - p->pkt_grp = NULL; - } - - if (p->buf_grp) { - mpp_buffer_group_put(p->pkt_grp); - p->buf_grp = NULL; - } - - return MPP_OK; -} - -MPP_RET test_mpp_init(MpiEncTestData *p) -{ - MPP_RET ret; - - if (NULL == p) - return MPP_ERR_NULL_PTR; - - ret = mpp_create(&p->ctx, &p->mpi); - if (ret) { - mpp_err("mpp_create failed ret %d\n", ret); - goto RET; - } - - ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type); - if (ret) - mpp_err("mpp_init failed ret %d\n", ret); - -RET: - return ret; -} - -MPP_RET test_mpp_setup(MpiEncTestData *p) -{ - MPP_RET ret; - MppApi *mpi; - MppCtx ctx; - MppEncCodecCfg *codec_cfg; - MppEncPrepCfg *prep_cfg; - MppEncRcCfg *rc_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; - - /* setup default parameter */ - p->fps = 30; - p->gop = 60; - - if (!p->bps) { - p->bps = p->width * p->height / 8 * p->fps; - } - - p->qp_init = (p->type == MPP_VIDEO_CodingMJPEG) ? (10) : (26); - - 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 = MPP_ENC_RC_MODE_CBR; - 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 * 17 / 16; - rc_cfg->bps_min = p->bps * 15 / 16; - } else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_VBR) { - /* variable bitrate has large bps range */ - rc_cfg->bps_target = p->bps; - rc_cfg->bps_max = p->bps * 17 / 16; - rc_cfg->bps_min = p->bps * 1 / 16; - } - - /* fix input / output frame rate */ - rc_cfg->fps_in_flex = 0; - rc_cfg->fps_in_num = p->fps; - rc_cfg->fps_in_denorm = 1; - rc_cfg->fps_out_flex = 0; - rc_cfg->fps_out_num = p->fps; - rc_cfg->fps_out_denorm = 1; - - rc_cfg->gop = p->gop; - rc_cfg->max_reenc_times = 1; - - if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_FIXQP) { - /* constant QP mode qp is fixed */ - p->qp_max = p->qp_init; - p->qp_min = p->qp_init; - p->qp_step = 0; - } else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_CBR) { - /* constant bitrate do not limit qp range */ - p->qp_max = 48; - p->qp_min = 4; - p->qp_step = 16; - p->qp_init = 0; - } else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_VBR) { - /* variable bitrate has qp min limit */ - p->qp_max = 40; - p->qp_min = 12; - p->qp_step = 8; - p->qp_init = 0; - } - - rc_cfg->qp_max = p->qp_max; - rc_cfg->qp_min = p->qp_min; - rc_cfg->qp_max_i = p->qp_max; - rc_cfg->qp_min_i = p->qp_min; - rc_cfg->qp_init = p->qp_init; - rc_cfg->qp_max_step = p->qp_step; - rc_cfg->qp_delta_ip = 4; - rc_cfg->qp_delta_vi = 2; - - mpp_log("mpi_enc_test bps %d fps %d gop %d\n", - 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_QFACTOR; - codec_cfg->jpeg.q_factor = 90; - codec_cfg->jpeg.qf_min = 1; - codec_cfg->jpeg.qf_max = 99; - } break; - case MPP_VIDEO_CodingHEVC : - case MPP_VIDEO_CodingVP8 : - 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; - } - - /* 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; - } - -RET: - return ret; -} - -/* - * write header here - */ -MPP_RET test_mpp_preprare(MpiEncTestData *p) -{ - MPP_RET ret; - MppApi *mpi; - MppCtx ctx; - MppPacket packet = NULL; - - if (NULL == p) - return MPP_ERR_NULL_PTR; - - mpi = p->mpi; - ctx = p->ctx; - ret = mpi->control(ctx, MPP_ENC_GET_EXTRA_INFO, &packet); - if (ret) { - mpp_err("mpi control enc get extra info failed\n"); - goto RET; - } - - /* get and write sps/pps for H.264 */ - if (packet) { - 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); - - packet = NULL; - } -RET: - return ret; -} - -MPP_RET test_mpp_run(MpiEncTestData *p) -{ - MPP_RET ret; - MppApi *mpi; - MppCtx ctx; - MppPacket packet = NULL; - RK_S32 i; - RK_S64 p_s, p_e, diff; - - if (NULL == p) - return MPP_ERR_NULL_PTR; - - mpi = p->mpi; - ctx = p->ctx; - - p_s = mpp_time(); - ret = mpp_frame_init(&p->frame); - if (ret) { - mpp_err_f("mpp_frame_init failed\n"); - goto RET; - } - - mpp_frame_set_width(p->frame, p->width); - mpp_frame_set_height(p->frame, p->height); - mpp_frame_set_hor_stride(p->frame, p->hor_stride); - mpp_frame_set_ver_stride(p->frame, p->ver_stride); - mpp_frame_set_fmt(p->frame, p->fmt); - - i = 0; - while (!p->pkt_eos) { - MppTask task = NULL; - RK_S32 index = i++; - MppBuffer frm_buf_in = p->frm_buf[index]; - MppBuffer pkt_buf_out = p->pkt_buf[index]; - MppBuffer md_info_buf = p->md_buf[index]; - - void *buf = mpp_buffer_get_ptr(frm_buf_in); - - if (i == MPI_ENC_IO_COUNT) - i = 0; - - 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)) { - mpp_log("found last frame. feof %d\n", feof(p->fp_input)); - p->frm_eos = 1; - } else if (ret == MPP_ERR_VALUE) - goto RET; - } else { - ret = fill_image(buf, p->width, p->height, p->hor_stride, - p->ver_stride, p->fmt, p->frame_count); - if (ret) - goto RET; - } - - mpp_frame_set_buffer(p->frame, frm_buf_in); - mpp_frame_set_eos(p->frame, p->frm_eos); - - mpp_packet_init_with_buffer(&packet, pkt_buf_out); - mpp_packet_set_length(packet, 0); - - ret = mpi->poll(ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK); - if (ret) { - mpp_err("mpp task input poll failed ret %d\n", ret); - goto RET; - } - - ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task); - if (ret || NULL == task) { - mpp_err("mpp task input dequeue failed ret %d task %p\n", ret, task); - goto RET; - } - - mpp_task_meta_set_frame (task, KEY_INPUT_FRAME, p->frame); - mpp_task_meta_set_packet(task, KEY_OUTPUT_PACKET, packet); - mpp_task_meta_set_buffer(task, KEY_MOTION_INFO, md_info_buf); - - /* set idr frame */ -#if MPI_ENC_TEST_SET_IDR_FRAME - if (p->frame_count && p->frame_count % (p->gop / 4) == 0) { - ret = mpi->control(ctx, MPP_ENC_SET_IDR_FRAME, NULL); - if (MPP_OK != ret) { - mpp_err("mpi control enc set idr frame failed\n"); - goto RET; - } - } -#endif - - ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task); - if (ret) { - mpp_err("mpp task input enqueue failed\n"); - goto RET; - } - - ret = mpi->poll(ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK); - if (ret) { - mpp_err("mpp task output poll failed ret %d\n", ret); - goto RET; - } - - ret = mpi->dequeue(ctx, MPP_PORT_OUTPUT, &task); - if (ret || NULL == task) { - mpp_err("mpp task output dequeue failed ret %d task %p\n", ret, task); - goto RET; - } - - if (task) { - MppFrame packet_out = NULL; - - mpp_task_meta_get_packet(task, KEY_OUTPUT_PACKET, &packet_out); - - mpp_assert(packet_out == packet); - if (packet) { - // write packet to file here - void *ptr = mpp_packet_get_pos(packet); - size_t len = mpp_packet_get_length(packet); - - p->pkt_eos = mpp_packet_get_eos(packet); - - if (p->fp_output) - fwrite(ptr, 1, len, p->fp_output); - mpp_packet_deinit(&packet); - - mpp_log_f("encoded frame %d size %d\n", p->frame_count, len); - p->stream_size += len; - - if (p->pkt_eos) { - mpp_log("found last packet\n"); - mpp_assert(p->frm_eos); - } - } - p->frame_count++; - } - - ret = mpi->enqueue(ctx, MPP_PORT_OUTPUT, task); - if (ret) { - mpp_err("mpp task output enqueue failed\n"); - goto RET; - } - - if (p->num_frames && p->frame_count >= p->num_frames) { - mpp_log_f("encode max %d frames", p->frame_count); - break; - } - if (p->frm_eos && p->pkt_eos) - break; - } - - p_e = mpp_time(); - diff = (p_e - p_s) / 1000; - mpp_log("chn encode %d frames use time %lld frm_rate:%d.\n", - p->frame_count, diff, p->frame_count * 1000 / diff); - -RET: - if (p->frame) { - mpp_frame_deinit(&p->frame); - p->frame = NULL; - } - - return ret; -} - -MPP_RET test_mpp_deinit(MpiEncTestData *p) -{ - if (p->ctx) { - mpp_destroy(p->ctx); - p->ctx = NULL; - } - - return MPP_OK; -} - -void* mpi_enc_test(void *cmd_ctx) -{ - MPP_RET ret = MPP_OK; - MpiEncTestData *p = NULL; - MpiEncTestCmd *cmd = (MpiEncTestCmd *)cmd_ctx; - RK_S64 t_s, t_e; - RK_S64 t_diff = 1; - - 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 = test_res_init(p); - if (ret) { - mpp_err_f("test resource init failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - mpp_log("mpi_enc_test encoder test start w %d h %d type %d\n", - p->width, p->height, p->type); - - // encoder demo - ret = test_mpp_init(p); - if (ret) { - mpp_err_f("test mpp init failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - ret = test_mpp_setup(p); - if (ret) { - mpp_err_f("test mpp setup failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - ret = test_mpp_preprare(p); - if (ret) { - mpp_err_f("test mpp prepare failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - t_s = mpp_time(); - 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; - } - t_e = mpp_time(); - t_diff = (t_e - t_s) / 1000; - -MPP_TEST_OUT: - test_mpp_deinit(p); - - test_res_deinit(p); - - if (MPP_OK == ret) - mpp_log("mpi_enc_test success total frame %d bps %lld\n", - p->frame_count, (RK_U64)((p->stream_size * 8 * p->fps) / p->frame_count)); - else - mpp_err("mpi_enc_test failed ret %d\n", ret); - - RK_U32 *rate = malloc(sizeof(RK_U32)); - mpp_assert(rate != NULL); - *rate = (p->frame_count * 1000) / t_diff; - - test_ctx_deinit(&p); - - return rate; -} - -static RK_S32 mpi_enc_test_parse_options(int argc, char **argv, MpiEncTestCmd* cmd) -{ - const char *opt; - const char *next; - RK_S32 optindex = 1; - RK_S32 handleoptions = 1; - RK_S32 err = MPP_NOK; - - if ((argc < 2) || (cmd == NULL)) { - err = 1; - return err; - } - - /* parse options */ - while (optindex < argc) { - opt = (const char*)argv[optindex++]; - next = (const char*)argv[optindex]; - - if (handleoptions && opt[0] == '-' && opt[1] != '\0') { - if (opt[1] == '-') { - if (opt[2] != '\0') { - opt++; - } else { - handleoptions = 0; - continue; - } - } - - opt++; - - switch (*opt) { - case 'i': - if (next) { - strncpy(cmd->file_input, next, MAX_FILE_NAME_LENGTH - 1); - cmd->have_input = 1; - } else { - mpp_err("input file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'o': - if (next) { - strncpy(cmd->file_output, next, MAX_FILE_NAME_LENGTH - 1); - cmd->have_output = 1; - } else { - mpp_log("output file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'd': - if (next) { - cmd->debug = atoi(next);; - } else { - mpp_err("invalid debug flag\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'w': - if (next) { - cmd->width = atoi(next); - } else { - mpp_err("invalid input width\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'h': - if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) { - mpi_enc_test_help(); - err = 1; - goto PARSE_OPINIONS_OUT; - } else if (next) { - cmd->height = atoi(next); - } else { - mpp_log("input height is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'u': - if (next) { - cmd->hor_stride = atoi(next); - } else { - mpp_err("invalid input width\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'v': - if (next) { - cmd->ver_stride = atoi(next); - } else { - mpp_log("input height is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'f': - if (next) { - cmd->format = (MppFrameFormat)atoi(next); - err = (!MPP_FRAME_FMT_IS_LE(cmd->format)) && ((cmd->format >= MPP_FMT_YUV_BUTT && cmd->format < MPP_FRAME_FMT_RGB) || - cmd->format >= MPP_FMT_RGB_BUTT); - } - - if (!next || err) { - mpp_err("invalid input format %d\n", cmd->format); - goto PARSE_OPINIONS_OUT; - } - break; - case 't': - if (next) { - cmd->type = (MppCodingType)atoi(next); - err = mpp_check_support_format(MPP_CTX_ENC, cmd->type); - } - - if (!next || err) { - mpp_err("invalid input coding type\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'n': - if (next) { - cmd->num_frames = atoi(next); - } else { - mpp_err("invalid input max number of frames\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'p': - if (next) { - cmd->payload_cnts = atoi(next); - } else { - mpp_err("invalid input max number of payloads\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'b': - if (next) { - cmd->target_bps = atoi(next); - } else { - mpp_err("invalid bit rate\n"); - goto PARSE_OPINIONS_OUT; - } - break; - default: - mpp_err("skip invalid opt %c\n", *opt); - break; - } - - optindex++; - } - } - - err = 0; - -PARSE_OPINIONS_OUT: - return err; -} - -static void mpi_enc_test_show_options(MpiEncTestCmd* cmd) -{ - mpp_log("cmd parse result:\n"); - mpp_log("input file name: %s\n", cmd->file_input); - mpp_log("output file name: %s\n", cmd->file_output); - mpp_log("width : %d\n", cmd->width); - mpp_log("height : %d\n", cmd->height); - mpp_log("type : %d\n", cmd->type); - mpp_log("debug flag : %x\n", cmd->debug); -} - -int main(int argc, char **argv) -{ - RK_S32 ret = 0; - RK_U32 i = 0; - RK_U32 **rates = NULL; - RK_U32 total_rate = 0; - pthread_t *handles; - MpiEncTestCmd cmd_ctx; - MpiEncTestCmd* cmd = &cmd_ctx; - - memset((void*)cmd, 0, sizeof(*cmd)); - - // parse the cmd option - ret = mpi_enc_test_parse_options(argc, argv, cmd); - if (ret) { - if (ret < 0) { - mpp_err("mpi_enc_test_parse_options: input parameter invalid\n"); - } - - mpi_enc_test_help(); - return ret; - } - - mpi_enc_test_show_options(cmd); - - mpp_env_set_u32("mpi_debug", cmd->debug); - - handles = malloc(sizeof(pthread_t) * cmd->payload_cnts); - mpp_assert(handles != NULL); - rates = malloc(sizeof(RK_U32 *) * cmd->payload_cnts); - mpp_assert(rates != NULL); - - for (i = 0; i < cmd->payload_cnts; i++) { - ret = pthread_create(&handles[i], NULL, mpi_enc_test, cmd); - if (ret != 0) { - mpp_log("failed to create thread %d\n", i); - return -1; - } - } - - for (i = 0; i < cmd->payload_cnts; i++) { - pthread_join(handles[i], (void *)&rates[i]); - } - - for (i = 0; i < cmd->payload_cnts; i++) { - total_rate += *rates[i]; - mpp_log("payload %d farme rate:%d\n", i, *rates[i]); - } - total_rate /= cmd->payload_cnts; - mpp_log("average frame rate %d\n", total_rate); - - mpp_env_set_u32("mpi_debug", 0x0); - return total_rate; -} diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index 9f00ca7c..b4aa3749 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -35,24 +35,30 @@ #include "mpp_enc_roi_utils.h" typedef struct { + // base flow context + MppCtx ctx; + MppApi *mpi; + RK_S32 chn; + // global flow control flag RK_U32 frm_eos; RK_U32 pkt_eos; RK_U32 frm_pkt_cnt; + RK_S32 frame_num; RK_S32 frame_count; RK_U64 stream_size; + /* end of encoding flag when set quit the loop */ + volatile RK_U32 loop_end; // src and dst FILE *fp_input; FILE *fp_output; - // base flow context - MppCtx ctx; - MppApi *mpi; - MppEncCfg cfg; - MppEncPrepCfg prep_cfg; - MppEncRcCfg rc_cfg; - MppEncCodecCfg codec_cfg; + /* encoder config set */ + MppEncCfg cfg; + MppEncPrepCfg prep_cfg; + MppEncRcCfg rc_cfg; + MppEncCodecCfg codec_cfg; MppEncSliceSplit split_cfg; MppEncOSDPltCfg osd_plt_cfg; MppEncOSDPlt osd_plt; @@ -74,7 +80,6 @@ typedef struct { RK_U32 ver_stride; MppFrameFormat fmt; MppCodingType type; - RK_S32 num_frames; RK_S32 loop_times; CamSource *cam_ctx; MppEncRoiCtx roi_ctx; @@ -94,7 +99,6 @@ typedef struct { RK_U32 roi_enable; // rate control runtime parameter - RK_S32 fps_in_flex; RK_S32 fps_in_den; RK_S32 fps_in_num; @@ -108,25 +112,37 @@ typedef struct { RK_S32 gop_mode; RK_S32 gop_len; RK_S32 vi_len; + + RK_S64 first_frm; + RK_S64 first_pkt; } MpiEncTestData; -MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd) +/* For each instance thread return value */ +typedef struct { + float frame_rate; + RK_U64 bit_rate; + RK_S64 elapsed_time; + RK_S32 frame_count; + RK_S64 stream_size; + RK_S64 delay; +} MpiEncMultiCtxRet; + +typedef struct { + MpiEncTestArgs *cmd; // pointer to global command line info + const char *name; + RK_S32 chn; + + pthread_t thd; // thread for for each instance + MpiEncTestData ctx; // context of encoder + MpiEncMultiCtxRet ret; // return of encoder +} MpiEncMultiCtxInfo; + +MPP_RET test_ctx_init(MpiEncMultiCtxInfo *info) { - MpiEncTestData *p = NULL; + MpiEncTestArgs *cmd = info->cmd; + MpiEncTestData *p = &info->ctx; 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; @@ -140,10 +156,10 @@ MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd) 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) { + p->frame_num = cmd->frame_num; + if (cmd->type == MPP_VIDEO_CodingMJPEG && p->frame_num == 0) { mpp_log("jpege default encode only one frame. Use -n [num] for rc case\n"); - p->num_frames = 1; + p->frame_num = 1; } p->gop_mode = cmd->gop_mode; p->gop_len = cmd->gop_len; @@ -212,20 +228,11 @@ MPP_RET test_ctx_init(MpiEncTestData **data, MpiEncTestArgs *cmd) else p->header_size = 0; -RET: - *data = p; return ret; } -MPP_RET test_ctx_deinit(MpiEncTestData **data) +MPP_RET test_ctx_deinit(MpiEncTestData *p) { - 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); @@ -239,25 +246,19 @@ MPP_RET test_ctx_deinit(MpiEncTestData **data) fclose(p->fp_output); p->fp_output = NULL; } - MPP_FREE(p); - *data = NULL; } return MPP_OK; } -MPP_RET test_mpp_enc_cfg_setup(MpiEncTestData *p) +MPP_RET test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo *info) { + MpiEncTestArgs *cmd = info->cmd; + MpiEncTestData *p = &info->ctx; + MppApi *mpi = p->mpi; + MppCtx ctx = p->ctx; + MppEncCfg cfg = p->cfg; + RK_U32 quiet = cmd->quiet; 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) @@ -405,7 +406,7 @@ MPP_RET test_mpp_enc_cfg_setup(MpiEncTestData *p) 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_log_q(quiet, "%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); } @@ -469,18 +470,16 @@ RET: return ret; } -MPP_RET test_mpp_run(MpiEncTestData *p) +MPP_RET test_mpp_run(MpiEncMultiCtxInfo *info) { - MPP_RET ret = MPP_OK; - MppApi *mpi; - MppCtx ctx; + MpiEncTestArgs *cmd = info->cmd; + MpiEncTestData *p = &info->ctx; + MppApi *mpi = p->mpi; + MppCtx ctx = p->ctx; + RK_U32 quiet = cmd->quiet; + RK_S32 chn = info->chn; RK_U32 cap_num = 0; - - if (NULL == p) - return MPP_ERR_NULL_PTR; - - mpi = p->mpi; - ctx = p->ctx; + MPP_RET ret = MPP_OK; if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) { MppPacket packet = NULL; @@ -525,14 +524,14 @@ MPP_RET test_mpp_run(MpiEncTestData *p) if (ret == MPP_NOK || feof(p->fp_input)) { p->frm_eos = 1; - if (p->num_frames < 0 || p->frame_count < p->num_frames) { + if (p->frame_num < 0 || p->frame_count < p->frame_num) { clearerr(p->fp_input); rewind(p->fp_input); p->frm_eos = 0; - mpp_log("%p loop times %d\n", ctx, ++p->loop_times); + mpp_log_q(quiet, "chn %d loop times %d\n", chn, ++p->loop_times); continue; } - mpp_log("%p found last frame. feof %d\n", ctx, feof(p->fp_input)); + mpp_log_q(quiet, "chn %d found last frame. feof %d\n", chn, feof(p->fp_input)); } else if (ret == MPP_ERR_VALUE) goto RET; } else { @@ -664,6 +663,8 @@ MPP_RET test_mpp_run(MpiEncTestData *p) } } + if (!p->first_frm) + p->first_frm = mpp_time(); /* * NOTE: in non-block mode the frame can be resent. * The default input timeout mode is block. @@ -673,16 +674,17 @@ MPP_RET test_mpp_run(MpiEncTestData *p) */ ret = mpi->encode_put_frame(ctx, frame); if (ret) { - mpp_err("mpp encode put frame failed\n"); + mpp_err("chn %d encode put frame failed\n", chn); mpp_frame_deinit(&frame); goto RET; } + mpp_frame_deinit(&frame); do { ret = mpi->encode_get_packet(ctx, &packet); if (ret) { - mpp_err("mpp encode get packet failed\n"); + mpp_err("chn %d encode get packet failed\n", chn); goto RET; } @@ -696,6 +698,9 @@ MPP_RET test_mpp_run(MpiEncTestData *p) RK_S32 log_size = sizeof(log_buf) - 1; RK_S32 log_len = 0; + if (!p->first_pkt) + p->first_pkt = mpp_time(); + p->pkt_eos = mpp_packet_get_eos(packet); if (p->fp_output) @@ -735,15 +740,16 @@ MPP_RET test_mpp_run(MpiEncTestData *p) " qp %d", avg_qp); } - mpp_log("%p %s\n", ctx, log_buf); + mpp_log_q(quiet, "chn %d %s\n", chn, log_buf); mpp_packet_deinit(&packet); + fps_calc_inc(cmd->fps); p->stream_size += len; p->frame_count += eoi; if (p->pkt_eos) { - mpp_log("%p found last packet\n", ctx); + mpp_log_q(quiet, "chn %d found last packet\n", chn); mpp_assert(p->frm_eos); } } @@ -752,10 +758,11 @@ MPP_RET test_mpp_run(MpiEncTestData *p) 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); + if (p->frame_num > 0 && p->frame_count >= p->frame_num) + break; + + if (p->loop_end) break; - } if (p->frm_eos && p->pkt_eos) break; @@ -764,15 +771,21 @@ RET: return ret; } -int mpi_enc_test(MpiEncTestArgs *cmd) +void *enc_test(void *arg) { - MPP_RET ret = MPP_OK; - MpiEncTestData *p = NULL; + MpiEncMultiCtxInfo *info = (MpiEncMultiCtxInfo *)arg; + MpiEncTestArgs *cmd = info->cmd; + MpiEncTestData *p = &info->ctx; + MpiEncMultiCtxRet *enc_ret = &info->ret; MppPollType timeout = MPP_POLL_BLOCK; + RK_U32 quiet = cmd->quiet; + MPP_RET ret = MPP_OK; + RK_S64 t_s = 0; + RK_S64 t_e = 0; - mpp_log("mpi_enc_test start\n"); + mpp_log_q(quiet, "%s start\n", info->name); - ret = test_ctx_init(&p, cmd); + ret = test_ctx_init(info); if (ret) { mpp_err_f("test data init failed ret %d\n", ret); goto MPP_TEST_OUT; @@ -803,8 +816,8 @@ int mpi_enc_test(MpiEncTestArgs *cmd) 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); + mpp_log_q(quiet, "%p 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) { @@ -824,13 +837,15 @@ int mpi_enc_test(MpiEncTestArgs *cmd) goto MPP_TEST_OUT; } - ret = test_mpp_enc_cfg_setup(p); + ret = test_mpp_enc_cfg_setup(info); if (ret) { mpp_err_f("test mpp setup failed ret %d\n", ret); goto MPP_TEST_OUT; } - ret = test_mpp_run(p); + t_s = mpp_time(); + ret = test_mpp_run(info); + t_e = mpp_time(); if (ret) { mpp_err_f("test mpp run failed ret %d\n", ret); goto MPP_TEST_OUT; @@ -842,14 +857,14 @@ int mpi_enc_test(MpiEncTestArgs *cmd) 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); + enc_ret->elapsed_time = t_e - t_s; + enc_ret->frame_count = p->frame_count; + enc_ret->stream_size = p->stream_size; + enc_ret->frame_rate = (float)p->frame_count * 1000000 / enc_ret->elapsed_time; + enc_ret->bit_rate = (p->stream_size * 8 * (p->fps_out_num / p->fps_out_den)) / p->frame_count; + enc_ret->delay = p->first_pkt - p->first_frm; +MPP_TEST_OUT: if (p->ctx) { mpp_destroy(p->ctx); p->ctx = NULL; @@ -885,7 +900,64 @@ MPP_TEST_OUT: p->roi_ctx = NULL; } - test_ctx_deinit(&p); + test_ctx_deinit(p); + + return NULL; +} + +int enc_test_multi(MpiEncTestArgs* cmd, const char *name) +{ + MpiEncMultiCtxInfo *ctxs = NULL; + float total_rate = 0.0; + RK_S32 ret = MPP_NOK; + RK_S32 i = 0; + + ctxs = mpp_calloc(MpiEncMultiCtxInfo, cmd->nthreads); + if (NULL == ctxs) { + mpp_err("failed to alloc context for instances\n"); + return -1; + } + + for (i = 0; i < cmd->nthreads; i++) { + ctxs[i].cmd = cmd; + ctxs[i].name = name; + ctxs[i].chn = i; + + ret = pthread_create(&ctxs[i].thd, NULL, enc_test, &ctxs[i]); + if (ret) { + mpp_err("failed to create thread %d\n", i); + return ret; + } + } + + if (cmd->frame_num < 0) { + // wait for input then quit encoding + mpp_log("*******************************************\n"); + mpp_log("**** Press Enter to stop loop encoding ****\n"); + mpp_log("*******************************************\n"); + + getc(stdin); + for (i = 0; i < cmd->nthreads; i++) + ctxs[i].ctx.loop_end = 1; + } + + for (i = 0; i < cmd->nthreads; i++) + pthread_join(ctxs[i].thd, NULL); + + for (i = 0; i < cmd->nthreads; i++) { + MpiEncMultiCtxRet *enc_ret = &ctxs[i].ret; + + mpp_log("chn %d encode %d frames time %lld ms delay %3d ms fps %3.2f bps %lld\n", + i, enc_ret->frame_count, (RK_S64)(enc_ret->elapsed_time / 1000), + (RK_S32)(enc_ret->delay / 1000), enc_ret->frame_rate, enc_ret->bit_rate); + + total_rate += enc_ret->frame_rate; + } + + MPP_FREE(ctxs); + + total_rate /= cmd->nthreads; + mpp_log("%s average frame rate %.2f\n", name, total_rate); return ret; } @@ -895,20 +967,14 @@ 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(); + ret = mpi_enc_test_cmd_update_by_args(cmd, argc, argv); + if (ret) goto DONE; - } mpi_enc_test_cmd_show_opt(cmd); - ret = mpi_enc_test(cmd); + ret = enc_test_multi(cmd, argv[0]); DONE: mpi_enc_test_cmd_put(cmd); diff --git a/test/mpi_rc_test.c b/test/mpi_rc_test.c deleted file mode 100644 index 5ff3b2bf..00000000 --- a/test/mpi_rc_test.c +++ /dev/null @@ -1,1180 +0,0 @@ -/* - * 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_rc_test" - -#include -#include -#include "rk_mpi.h" - -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_time.h" -#include "mpp_common.h" -#include "mpp_mem.h" - -#include "utils.h" - -#include "vpu_api.h" - -#define MPI_RC_IO_COUNT 1 -#define MPI_RC_FILE_NAME_LEN 256 - -#define MPI_BIT_DEPTH 8 -#define MPI_PIXEL_MAX ((1 << MPI_BIT_DEPTH) - 1) - -#define MPI_RC_ITEM_BPS 0x00000001 -#define MPI_RC_ITEM_FPS 0x00000002 -#define MPI_RC_ITEM_GOP 0x00000004 -#define MPI_RC_ITEM_FORCE_I 0x00000008 -#define MPI_RC_ITEM_ROI 0x00000010 - -typedef RK_U8 pixel; - -typedef struct { - RK_U32 bitrate; -} MpiRcCfg; - -typedef struct { - double psnr_y; - double ssim_y; - RK_U32 avg_bitrate; // Every sequence, byte per second - RK_U32 ins_bitrate; // Every second, byte per second - RK_U32 frame_size; // Every frame, byte -} MpiRcStat; - -typedef struct { - FILE *fp_input; - FILE *fp_enc_out; - FILE *fp_dec_out; - FILE *fp_stat; -} MpiRcFile; - -typedef struct { - char file_input[MPI_RC_FILE_NAME_LEN]; - char file_enc_out[MPI_RC_FILE_NAME_LEN]; - char file_dec_out[MPI_RC_FILE_NAME_LEN]; - char file_stat[MPI_RC_FILE_NAME_LEN]; - MppCodingType type; - RK_U32 width; - RK_U32 height; - MppFrameFormat format; - RK_U32 debug; - RK_U32 num_frames; - RK_U32 item_flag; - - RK_U32 have_input; - RK_U32 have_enc_out; - RK_U32 have_dec_out; - RK_U32 have_stat_out; -} MpiRcTestCmd; - -typedef struct { - MpiRcTestCmd cmd; - MpiRcCfg cfg; - MpiRcStat stat; - MpiRcFile file; - RK_U8 *com_buf; -} MpiRcTestCtx; - -static OptionInfo mpi_rc_cmd[] = { - {"i", "input_file", "input bitstream file"}, - {"o", "output_file", "output bitstream file, "}, - {"w", "width", "the width of input picture"}, - {"h", "height", "the height of input picture"}, - {"f", "format", "the format of input picture"}, - {"t", "type", "output stream coding type"}, - {"n", "max frame number", "max encoding frame number"}, - {"d", "debug", "debug flag"}, - {"s", "stat_file", "stat output file name"}, - {"c", "rc test item", "rc test item flags, one bit each item: roi|force_intra|gop|fps|bps"}, -}; - -static void mpi_rc_deinit(MpiRcTestCtx *ctx) -{ - MpiRcFile *file = &ctx->file; - - if (file->fp_enc_out) { - fclose(file->fp_enc_out); - file->fp_enc_out = NULL; - } - if (file->fp_dec_out) { - fclose(file->fp_dec_out); - file->fp_dec_out = NULL; - } - - if (file->fp_stat) { - fclose(file->fp_stat); - file->fp_stat = NULL; - } - - if (file->fp_input) { - fclose(file->fp_input); - file->fp_input = NULL; - } - - MPP_FREE(ctx->com_buf); -} - -static MPP_RET mpi_rc_init(MpiRcTestCtx *ctx) -{ - MPP_RET ret = MPP_OK; - MpiRcTestCmd *cmd = &ctx->cmd; - MpiRcFile *file = &ctx->file; - - if (cmd->have_input) { - file->fp_input = fopen(cmd->file_input, "rb"); - if (NULL == file->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->have_enc_out) { - file->fp_enc_out = fopen(cmd->file_enc_out, "w+b"); - if (NULL == file->fp_enc_out) { - mpp_err("failed to open enc output file %s\n", cmd->file_enc_out); - ret = MPP_ERR_OPEN_FILE; - goto err; - } - } - - if (cmd->have_dec_out) { - file->fp_dec_out = fopen(cmd->file_dec_out, "w+b"); - if (NULL == file->fp_dec_out) { - mpp_err("failed to open dec output file %s\n", cmd->file_dec_out); - ret = MPP_ERR_OPEN_FILE; - goto err; - } - } - - if (cmd->have_stat_out) { - file->fp_stat = fopen(cmd->file_stat, "w+b"); - if (NULL == file->fp_stat) { - mpp_err("failed to open stat file %s\n", cmd->file_stat); - ret = MPP_ERR_OPEN_FILE; - goto err; - } - fprintf(file->fp_stat, "frame,size(bit),psnr,ssim,ins_bitrate(bit/s),avg_bitrate(bit/s)\n"); - } - - ctx->com_buf = mpp_malloc(RK_U8, cmd->width * cmd->height * 2); - if (ctx->com_buf == NULL) { - mpp_err_f("ctx->com_buf malloc failed"); - ret = MPP_NOK; - goto err; - } - -err: - - return ret; -} - -static MPP_RET mpi_rc_cmp_frame(MppFrame frame_in, MppFrame frame_out) -{ - RK_U8 *enc_buf = (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_in)); - RK_U8 *dec_buf = (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_out)); - RK_U32 enc_width = mpp_frame_get_width(frame_in); - RK_U32 enc_height = mpp_frame_get_height(frame_in); - RK_U32 dec_width = mpp_frame_get_width(frame_out); - RK_U32 dec_height = mpp_frame_get_height(frame_out); - - if (!enc_buf) { - mpp_err_f("enc buf is NULL"); - return MPP_NOK; - } - if (!dec_buf) { - mpp_err_f("dec buf is NULL"); - return MPP_NOK; - } - - if (enc_width != dec_width) { - mpp_err_f("enc_width %d != dec_width %d", enc_width, dec_width); - return MPP_NOK; - } - - if (enc_height != dec_height) { - mpp_err_f("enc_height %d != dec_height %d", enc_height, dec_height); - return MPP_NOK; - } - - return MPP_OK; -} - -static void mpi_rc_calc_psnr(MpiRcStat *stat, MppFrame frame_in, MppFrame frame_out) -{ - RK_U32 x, y; - RK_S32 tmp; - double ssd_y = 0.0; - double mse_y = 0.0; - double psnr_y = 0.0; - - RK_U32 width = mpp_frame_get_width(frame_in); - RK_U32 height = mpp_frame_get_height(frame_in); - RK_U32 luma_size = width * height; - RK_U32 enc_hor_stride = mpp_frame_get_hor_stride(frame_in); - RK_U32 dec_hor_stride = mpp_frame_get_hor_stride(frame_out); - RK_U8 *enc_buf = (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_in)); - RK_U8 *dec_buf = (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_out)); - RK_U8 *enc_buf_y = enc_buf; - RK_U8 *dec_buf_y = dec_buf; - - for (y = 0 ; y < height; y++) { - for (x = 0; x < width; x++) { - tmp = enc_buf_y[x + y * enc_hor_stride] - dec_buf_y[x + y * dec_hor_stride]; - tmp *= tmp; - ssd_y += tmp; - } - } - // NOTE: should be 65025.0 rather than 65025, because 65025*luma_size may exceed - // 1 << 32. - mse_y = ssd_y / (65025.0 * luma_size); // 65025=255*255 - if (mse_y <= 0.0000000001) - psnr_y = 100; - else - psnr_y = -10.0 * log10f(mse_y); - - stat->psnr_y = psnr_y; -} - -static float ssim_end1( int s1, int s2, int ss, int s12 ) -{ - /* Maximum value for 10-bit is: ss*64 = (2^10-1)^2*16*4*64 = 4286582784, which will overflow in some cases. - * s1*s1, s2*s2, and s1*s2 also obtain this value for edge cases: ((2^10-1)*16*4)^2 = 4286582784. - * Maximum value for 9-bit is: ss*64 = (2^9-1)^2*16*4*64 = 1069551616, which will not overflow. */ - static const int ssim_c1 = (int)(.01 * .01 * MPI_PIXEL_MAX * MPI_PIXEL_MAX * 64 + .5); - static const int ssim_c2 = (int)(.03 * .03 * MPI_PIXEL_MAX * MPI_PIXEL_MAX * 64 * 63 + .5); - int fs1 = s1; - int fs2 = s2; - int fss = ss; - int fs12 = s12; - int vars = fss * 64 - fs1 * fs1 - fs2 * fs2; - int covar = fs12 * 64 - fs1 * fs2; - - return (float)(2 * fs1 * fs2 + ssim_c1) * (float)(2 * covar + ssim_c2) - / ((float)(fs1 * fs1 + fs2 * fs2 + ssim_c1) * (float)(vars + ssim_c2)); -} - -static float ssim_end4( int sum0[5][4], int sum1[5][4], int width ) -{ - double ssim = 0.0; - int i = 0; - for (i = 0; i < width; i++ ) - ssim += ssim_end1( sum0[i][0] + sum0[i + 1][0] + sum1[i][0] + sum1[i + 1][0], - sum0[i][1] + sum0[i + 1][1] + sum1[i][1] + sum1[i + 1][1], - sum0[i][2] + sum0[i + 1][2] + sum1[i][2] + sum1[i + 1][2], - sum0[i][3] + sum0[i + 1][3] + sum1[i][3] + sum1[i + 1][3] ); - return ssim; -} - -static void ssim_4x4x2_core( const pixel *pix1, intptr_t stride1, - const pixel *pix2, intptr_t stride2, - int sums[2][4] ) -{ - int a = 0; - int b = 0; - int x = 0; - int y = 0; - int z = 0; - for (z = 0; z < 2; z++ ) { - uint32_t s1 = 0, s2 = 0, ss = 0, s12 = 0; - for (y = 0; y < 4; y++ ) - for ( x = 0; x < 4; x++ ) { - a = pix1[x + y * stride1]; - b = pix2[x + y * stride2]; - s1 += a; - s2 += b; - ss += a * a; - ss += b * b; - s12 += a * b; - - } - sums[z][0] = s1; - sums[z][1] = s2; - sums[z][2] = ss; - sums[z][3] = s12; - pix1 += 4; - pix2 += 4; - } -} - - -static float calc_ssim(pixel *pix1, RK_U32 stride1, - pixel *pix2, RK_U32 stride2, - int width, int height, void *buf, int *cnt) -{ - int x = 0; - int y = 0; - int z = 0; - float ssim = 0.0; - int (*sum0)[4] = buf; - int (*sum1)[4] = sum0 + (width >> 2) + 3; - width >>= 2; - height >>= 2; - for ( y = 1; y < height; y++ ) { - for ( ; z <= y; z++ ) { - MPP_SWAP( void*, sum0, sum1 ); - for ( x = 0; x < width; x += 2 ) - ssim_4x4x2_core( &pix1[4 * (x + z * stride1)], stride1, &pix2[4 * (x + z * stride2)], stride2, &sum0[x] ); - - } - for ( x = 0; x < width - 1; x += 4 ) - ssim += ssim_end4( sum0 + x, sum1 + x, MPP_MIN(4, width - x - 1) ); - - } - *cnt = (height - 1) * (width - 1); - return ssim; -} - -static void mpi_rc_calc_ssim(MpiRcTestCtx *ctx, MppFrame frame_in, MppFrame frame_out) -{ - int cnt = 0; - float ssim = 0; - MpiRcStat *stat = &ctx->stat; - RK_U32 width = mpp_frame_get_width(frame_in); - RK_U32 height = mpp_frame_get_height(frame_in); - RK_U32 enc_hor_stride = mpp_frame_get_hor_stride(frame_in); - RK_U32 dec_hor_stride = mpp_frame_get_hor_stride(frame_out); - pixel *enc_buf = (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_in)); - pixel *dec_buf = (RK_U8 *)mpp_buffer_get_ptr(mpp_frame_get_buffer(frame_out)); - pixel *enc_buf_y = enc_buf; - pixel *dec_buf_y = dec_buf; - - ssim = calc_ssim(enc_buf_y, enc_hor_stride, dec_buf_y, dec_hor_stride, width - 2, height - 2, ctx->com_buf, &cnt); - ssim /= (float)cnt; - - stat->ssim_y = (double)ssim; - -} - -static MPP_RET mpi_rc_calc_stat(MpiRcTestCtx *ctx, MppFrame frame_in, MppFrame frame_out) -{ - MPP_RET ret = MPP_OK; - MpiRcStat *stat = &ctx->stat; - - ret = mpi_rc_cmp_frame(frame_in, frame_out); - if (MPP_OK != ret) { - mpp_err_f("mpi_rc_cmp_frame failed ret %d", ret); - return MPP_NOK; - } - - mpi_rc_calc_psnr(stat, frame_in, frame_out); - mpi_rc_calc_ssim(ctx, frame_in, frame_out); - - return ret; -} - -static void mpi_rc_log_stat(MpiRcTestCtx *ctx, RK_U32 frame_count, RK_U32 one_second, RK_U32 seq_end) -{ - //static char rc_log_str[1024] = {0}; - MpiRcStat *stat = &ctx->stat; - MpiRcFile *file = &ctx->file; - FILE *fp = file->fp_stat; - - mpp_log("frame %3d | frame_size %6d bits | psnr %5.2f | ssim %5.5f", - frame_count, stat->frame_size, stat->psnr_y, stat->ssim_y); - if (one_second) - mpp_log("ins_bitrate %d bit/s", stat->ins_bitrate); - - if (fp) { - fprintf(fp, "%3d,%6d,%5.2f,%5.5f,", - frame_count, stat->frame_size, stat->psnr_y, stat->ssim_y); - if (one_second) - fprintf(fp, "%d,", stat->ins_bitrate); - if (!seq_end) - fprintf(fp, "\n"); - } -} - -static MPP_RET mpi_rc_codec(MpiRcTestCtx *ctx) -{ - MPP_RET ret = MPP_OK; - MpiRcTestCmd *cmd = &ctx->cmd; - RK_U32 frm_eos = 0; - RK_U32 pkt_eos = 0; - MpiRcFile *file = &ctx->file; - MpiRcStat *stat = &ctx->stat; - FILE *fp_input = file->fp_input; - FILE *fp_enc_out = file->fp_enc_out; - FILE *fp_dec_out = file->fp_dec_out; - FILE *fp_stat = file->fp_stat; - RK_U8 *dec_in_buf = NULL; - RK_U32 need_split = 0; - MppPollType block = MPP_POLL_NON_BLOCK; - - // base flow context - MppCtx enc_ctx = NULL; - MppApi *enc_mpi = NULL; - MppCtx dec_ctx = NULL; - MppApi *dec_mpi = NULL; - - // input / output - RK_S32 i; - MppBufferGroup frm_grp = NULL; - MppBufferGroup pkt_grp = NULL; - MppFrame frame_in = NULL; - MppFrame frame_out = NULL; - MppFrame frame_tmp = NULL; - MppPacket packet = NULL; - MppPacket dec_packet = NULL; - MppBuffer frm_buf[MPI_RC_IO_COUNT] = { NULL }; - MppBuffer pkt_buf[MPI_RC_IO_COUNT] = { NULL }; - MppEncSeiMode sei_mode = MPP_ENC_SEI_MODE_ONE_SEQ; - - // paramter for resource malloc - RK_U32 width = cmd->width; - RK_U32 height = cmd->height; - RK_U32 hor_stride = MPP_ALIGN(width, 16); - RK_U32 ver_stride = MPP_ALIGN(height, 16); - MppFrameFormat fmt = cmd->format; - MppCodingType type = cmd->type; - RK_U32 num_frames = cmd->num_frames; - - // resources - size_t frame_size = hor_stride * ver_stride * 3 / 2; - /* NOTE: packet buffer may overflow */ - size_t packet_size = width * height; - RK_U32 frame_count = 0; - RK_U64 stream_size = 0; - RK_U64 stream_size_1s = 0; - - // runtime config - MppEncRcCfg rc; - MppEncPrepCfg prep; - MppEncCodecCfg codec; - MppEncRcCfg *rc_cfg = &rc; - MppEncPrepCfg *prep_cfg = &prep; - MppEncCodecCfg *codec_cfg = &codec; - RK_S32 fps = 20; - - mpp_log_f("test start width %d height %d codingtype %d\n", width, height, type); - ret = mpp_buffer_group_get_internal(&frm_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("failed to get buffer group for input frame ret %d\n", ret); - goto MPP_TEST_OUT; - } - - ret = mpp_buffer_group_get_internal(&pkt_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("failed to get buffer group for output packet ret %d\n", ret); - goto MPP_TEST_OUT; - } - - for (i = 0; i < MPI_RC_IO_COUNT; i++) { - ret = mpp_buffer_get(frm_grp, &frm_buf[i], frame_size); - if (ret) { - mpp_err("failed to get buffer for input frame ret %d\n", ret); - goto MPP_TEST_OUT; - } - - ret = mpp_buffer_get(pkt_grp, &pkt_buf[i], packet_size); - if (ret) { - mpp_err("failed to get buffer for input frame ret %d\n", ret); - goto MPP_TEST_OUT; - } - } - - dec_in_buf = mpp_calloc(RK_U8, packet_size); - if (NULL == dec_in_buf) { - mpp_err("mpi_dec_test malloc input stream buffer failed\n"); - goto MPP_TEST_OUT; - } - - // decoder init - ret = mpp_create(&dec_ctx, &dec_mpi); - if (MPP_OK != ret) { - mpp_err("mpp_create decoder failed\n"); - goto MPP_TEST_OUT; - } - - ret = mpp_packet_init(&dec_packet, dec_in_buf, packet_size); - if (ret) { - mpp_err("mpp_packet_init failed\n"); - goto MPP_TEST_OUT; - } - - ret = dec_mpi->control(dec_ctx, MPP_DEC_SET_PARSER_SPLIT_MODE, &need_split); - if (MPP_OK != ret) { - mpp_err("dec_mpi->control failed\n"); - goto MPP_TEST_OUT; - } - - block = MPP_POLL_NON_BLOCK; - ret = dec_mpi->control(dec_ctx, MPP_SET_INPUT_TIMEOUT, (MppParam)&block); - if (MPP_OK != ret) { - mpp_err("dec_mpi->control dec MPP_SET_INPUT_TIMEOUT failed\n"); - goto MPP_TEST_OUT; - } - - block = MPP_POLL_BLOCK; - ret = dec_mpi->control(dec_ctx, MPP_SET_OUTPUT_TIMEOUT, (MppParam)&block); - if (MPP_OK != ret) { - mpp_err("dec_mpi->control MPP_SET_OUTPUT_TIMEOUT failed\n"); - goto MPP_TEST_OUT; - } - - ret = mpp_init(dec_ctx, MPP_CTX_DEC, type); - if (MPP_OK != ret) { - mpp_err("mpp_init dec failed\n"); - goto MPP_TEST_OUT; - } - - mpp_frame_init(&frame_tmp); - mpp_frame_set_width(frame_tmp, width); - mpp_frame_set_height(frame_tmp, height); - // NOTE: only for current version, otherwise there will be info change - mpp_frame_set_hor_stride(frame_tmp, /*(MPP_ALIGN(hor_stride, 256) | 256)*/hor_stride); - mpp_frame_set_ver_stride(frame_tmp, ver_stride); - mpp_frame_set_fmt(frame_tmp, MPP_FMT_YUV420SP); // dec out frame only support 420sp - ret = dec_mpi->control(dec_ctx, MPP_DEC_SET_FRAME_INFO, (MppParam)frame_tmp); - if (MPP_OK != ret) { - mpp_err("dec_mpi->control set frame info failed"); - goto MPP_TEST_OUT; - } - - // encoder init - ret = mpp_create(&enc_ctx, &enc_mpi); - if (MPP_OK != ret) { - mpp_err("mpp_create encoder failed\n"); - goto MPP_TEST_OUT; - } - - block = MPP_POLL_NON_BLOCK; - ret = enc_mpi->control(enc_ctx, MPP_SET_INPUT_TIMEOUT, (MppParam)&block); - if (MPP_OK != ret) { - mpp_err("enc_mpi->control MPP_SET_INPUT_TIMEOUT failed\n"); - goto MPP_TEST_OUT; - } - - ret = enc_mpi->control(enc_ctx, MPP_SET_OUTPUT_TIMEOUT, (MppParam)&block); - if (MPP_OK != ret) { - mpp_err("enc_mpi->control MPP_SET_OUTPUT_TIMEOUT failed\n"); - goto MPP_TEST_OUT; - } - - ret = mpp_init(enc_ctx, MPP_CTX_ENC, type); - if (MPP_OK != ret) { - mpp_err("mpp_init enc failed\n"); - goto MPP_TEST_OUT; - } - - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_SEI_CFG, &sei_mode); - if (MPP_OK != ret) { - mpp_err("mpi control enc set sei cfg failed\n"); - goto MPP_TEST_OUT; - } - - rc_cfg->change = MPP_ENC_RC_CFG_CHANGE_ALL; - rc_cfg->rc_mode = MPP_ENC_RC_MODE_CBR; - rc_cfg->quality = MPP_ENC_RC_QUALITY_MEDIUM; - rc_cfg->bps_target = 800000; - rc_cfg->bps_max = 800000; - rc_cfg->bps_min = 800000; - rc_cfg->fps_in_denorm = 1; - rc_cfg->fps_out_denorm = 1; - rc_cfg->fps_in_num = fps; - rc_cfg->fps_out_num = fps; - rc_cfg->fps_in_flex = 0; - rc_cfg->fps_out_flex = 0; - rc_cfg->gop = fps; - rc_cfg->max_reenc_times = 1; - rc_cfg->qp_init = -1; - if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_FIXQP) { - /* constant QP mode qp is fixed */ - rc_cfg->qp_init = 26; - rc_cfg->qp_max = 26; - rc_cfg->qp_min = 26; - } else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_CBR) { - /* constant bitrate do not limit qp range */ - rc_cfg->qp_max = 48; - rc_cfg->qp_min = 4; - } else if (rc_cfg->rc_mode == MPP_ENC_RC_MODE_VBR) { - /* variable bitrate has qp min limit */ - rc_cfg->qp_max = 40; - rc_cfg->qp_min = 12; - } - - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_RC_CFG, rc_cfg); - if (ret) { - mpp_err("mpi control enc set rc cfg failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - prep_cfg->change = MPP_ENC_PREP_CFG_CHANGE_INPUT | - MPP_ENC_PREP_CFG_CHANGE_FORMAT; - prep_cfg->width = width; - prep_cfg->height = height; - prep_cfg->hor_stride = hor_stride; - prep_cfg->ver_stride = ver_stride; - prep_cfg->format = fmt; - - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_PREP_CFG, prep_cfg); - if (ret) { - mpp_err("mpi control enc set prep cfg failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - codec_cfg->coding = type; - codec_cfg->h264.change = MPP_ENC_H264_CFG_CHANGE_PROFILE | - MPP_ENC_H264_CFG_CHANGE_ENTROPY; - /* - * 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; - - ret = enc_mpi->control(enc_ctx, MPP_ENC_SET_CODEC_CFG, codec_cfg); - if (ret) { - mpp_err("mpi control enc set codec cfg failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - ret = enc_mpi->control(enc_ctx, MPP_ENC_GET_EXTRA_INFO, &packet); - if (MPP_OK != ret) { - mpp_err("mpi control enc get extra info failed\n"); - goto MPP_TEST_OUT; - } - - /* get and write sps/pps for H.264 */ - if (packet) { - void *ptr = mpp_packet_get_pos(packet); - size_t len = mpp_packet_get_length(packet); - MppPacket tmp_pkt = NULL; - - // write extra data to dec packet and send - mpp_packet_init(&tmp_pkt, ptr, len); - mpp_packet_set_extra_data(tmp_pkt); - dec_mpi->decode_put_packet(dec_ctx, tmp_pkt); - mpp_packet_deinit(&tmp_pkt); - - if (fp_enc_out) - fwrite(ptr, 1, len, fp_enc_out); - - packet = NULL; - } - - ret = mpp_frame_init(&frame_in); - if (MPP_OK != ret) { - mpp_err("mpp_frame_init failed\n"); - goto MPP_TEST_OUT; - } - - mpp_frame_set_width(frame_in, width); - mpp_frame_set_height(frame_in, height); - mpp_frame_set_hor_stride(frame_in, hor_stride); - mpp_frame_set_ver_stride(frame_in, ver_stride); - mpp_frame_set_fmt(frame_in, fmt); - - i = 0; - while (!pkt_eos) { - MppTask enc_task = NULL; - RK_S32 index = i++; - MppBuffer frm_buf_in = frm_buf[index]; - MppBuffer pkt_buf_out = pkt_buf[index]; - void *buf = mpp_buffer_get_ptr(frm_buf_in); - - if (i == MPI_RC_IO_COUNT) - i = 0; - - if (fp_input) { - ret = read_image(buf, fp_input, - prep_cfg->width, prep_cfg->height, - prep_cfg->hor_stride, prep_cfg->ver_stride, - prep_cfg->format); - if (MPP_OK != ret || feof(fp_input)) { - mpp_log("found last frame\n"); - frm_eos = 1; - } - } else { - ret = fill_image(buf, prep_cfg->width, prep_cfg->height, - prep_cfg->hor_stride, prep_cfg->ver_stride, - prep_cfg->format, frame_count); - if (ret) - goto MPP_TEST_OUT; - } - - mpp_frame_set_buffer(frame_in, frm_buf_in); - mpp_frame_set_eos(frame_in, frm_eos); - - mpp_packet_init_with_buffer(&packet, pkt_buf_out); - mpp_packet_set_length(packet, 0); - - ret = enc_mpi->poll(enc_ctx, MPP_PORT_INPUT, MPP_POLL_BLOCK); - if (ret) { - mpp_err("mpp input poll failed\n"); - goto MPP_TEST_OUT; - } - - ret = enc_mpi->dequeue(enc_ctx, MPP_PORT_INPUT, &enc_task); - if (ret) { - mpp_err("mpp task input dequeue failed\n"); - goto MPP_TEST_OUT; - } - - mpp_assert(enc_task); - { - MppFrame tmp_frm = NULL; - mpp_task_meta_get_frame(enc_task, KEY_INPUT_FRAME, &tmp_frm); - if (tmp_frm) - mpp_assert(tmp_frm == frame_in); - } - - mpp_task_meta_set_frame (enc_task, KEY_INPUT_FRAME, frame_in); - mpp_task_meta_set_packet(enc_task, KEY_OUTPUT_PACKET, packet); - - ret = enc_mpi->enqueue(enc_ctx, MPP_PORT_INPUT, enc_task); - if (ret) { - mpp_err("mpp task input enqueue failed\n"); - goto MPP_TEST_OUT; - } - - ret = enc_mpi->poll(enc_ctx, MPP_PORT_OUTPUT, MPP_POLL_BLOCK); - if (ret) { - mpp_err("mpp task output poll failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - ret = enc_mpi->dequeue(enc_ctx, MPP_PORT_OUTPUT, &enc_task); - if (ret || NULL == enc_task) { - mpp_err("mpp task output dequeue failed ret %d task %p\n", ret, enc_task); - goto MPP_TEST_OUT; - } - - if (enc_task) { - MppFrame packet_out = NULL; - - mpp_task_meta_get_packet(enc_task, KEY_OUTPUT_PACKET, &packet_out); - - mpp_assert(packet_out == packet); - if (packet) { - // write packet to file here - void *ptr = mpp_packet_get_pos(packet); - size_t len = mpp_packet_get_length(packet); - RK_U32 dec_pkt_done = 0; - - pkt_eos = mpp_packet_get_eos(packet); - - if (fp_enc_out) - fwrite(ptr, 1, len, fp_enc_out); - - //mpp_log_f("encoded frame %d size %d bits\n", frame_count, len * 8); - stream_size += len * 8; - stream_size_1s += len * 8; - stat->frame_size = len * 8; - if ((frame_count + 1) % fps == 0) { - stat->ins_bitrate = stream_size_1s; - stream_size_1s = 0; - } - - if (pkt_eos) { - mpp_log("found last packet\n"); - mpp_assert(frm_eos); - } - - /* decode one frame */ - // write packet to dec input - memset(dec_in_buf, 0, packet_size); - mpp_packet_write(dec_packet, 0, ptr, len); - // reset pos - mpp_packet_set_pos(dec_packet, dec_in_buf); - mpp_packet_set_length(dec_packet, len); - mpp_packet_set_size(dec_packet, len); - frame_out = NULL; - - do { - // send the packet first if packet is not done - if (!dec_pkt_done) { - ret = dec_mpi->decode_put_packet(dec_ctx, dec_packet); - if (MPP_OK == ret) - dec_pkt_done = 1; - } - - // then get all available frame and release - do { - RK_S32 dec_get_frm = 0; - RK_U32 dec_frm_eos = 0; - - ret = dec_mpi->decode_get_frame(dec_ctx, &frame_out); - if (MPP_OK != ret) { - mpp_err("decode_get_frame failed ret %d\n", ret); - break; - } - - if (frame_out) { - if (mpp_frame_get_info_change(frame_out)) { - mpp_log("decode_get_frame get info changed found\n"); - dec_mpi->control(dec_ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); - } else { - if (fp_dec_out) - dump_mpp_frame_to_file(frame_out, fp_dec_out); - mpi_rc_calc_stat(ctx, frame_in, frame_out); - mpi_rc_log_stat(ctx, frame_count, (frame_count + 1) % fps == 0, - frame_count + 1 == num_frames); - dec_get_frm = 1; - } - dec_frm_eos = mpp_frame_get_eos(frame_out); - mpp_frame_deinit(&frame_out); - frame_out = NULL; - } - - // if last packet is send but last frame is not found continue - if (pkt_eos && dec_pkt_done && !dec_frm_eos) - continue; - - if (dec_get_frm) - break; - } while (1); - - if (dec_pkt_done) - break; - - msleep(5); - } while (1); - - mpp_packet_deinit(&packet); // encoder packet deinit - } - frame_count++; - - ret = enc_mpi->enqueue(enc_ctx, MPP_PORT_OUTPUT, enc_task); - if (ret) { - mpp_err("mpp task output enqueue failed\n"); - goto MPP_TEST_OUT; - } - } - - if (num_frames && frame_count >= num_frames) { - mpp_log_f("codec max %d frames", frame_count); - break; - } - if (frm_eos && pkt_eos) - break; - } - - ret = enc_mpi->reset(enc_ctx); - if (MPP_OK != ret) { - mpp_err("mpi->reset enc failed\n"); - goto MPP_TEST_OUT; - } - - ret = dec_mpi->reset(dec_ctx); - if (MPP_OK != ret) { - mpp_err("mpi->reset dec failed\n"); - goto MPP_TEST_OUT; - } - - stat->avg_bitrate = (RK_U64)stream_size * fps / frame_count; - mpp_log_f("avg_bitrate %d bit/s", stat->avg_bitrate); - if (fp_stat) - fprintf(fp_stat, "%d\n", stat->avg_bitrate); - -MPP_TEST_OUT: - - if (frame_tmp) - mpp_frame_deinit(&frame_tmp); - // encoder deinit - if (enc_ctx) { - mpp_destroy(enc_ctx); - enc_ctx = NULL; - } - - if (frame_in) { - mpp_frame_deinit(&frame_in); - frame_in = NULL; - } - - for (i = 0; i < MPI_RC_IO_COUNT; i++) { - if (frm_buf[i]) { - mpp_buffer_put(frm_buf[i]); - frm_buf[i] = NULL; - } - - if (pkt_buf[i]) { - mpp_buffer_put(pkt_buf[i]); - pkt_buf[i] = NULL; - } - } - - if (frm_grp) { - mpp_buffer_group_put(frm_grp); - frm_grp = NULL; - } - - if (pkt_grp) { - mpp_buffer_group_put(pkt_grp); - pkt_grp = NULL; - } - - // decoder deinit - if (dec_packet) { - mpp_packet_deinit(&dec_packet); - dec_packet = NULL; - } - - if (frame_out) { - mpp_frame_deinit(&frame_out); - frame_out = NULL; - } - - if (dec_ctx) { - mpp_destroy(dec_ctx); - dec_ctx = NULL; - } - - MPP_FREE(dec_in_buf); - - if (MPP_OK == ret) - mpp_log("test success total frame %d bps %d\n", - frame_count, stat->avg_bitrate); - else - mpp_err_f("failed ret %d\n", ret); - - return ret; -} - -static void mpi_rc_test_help() -{ - mpp_log("usage: mpi_rc_test [options]\n"); - show_options(mpi_rc_cmd); - mpp_show_support_format(); -} - -static RK_S32 mpi_enc_test_parse_options(int argc, char **argv, MpiRcTestCmd* cmd) -{ - const char *opt; - const char *next; - RK_S32 optindex = 1; - RK_S32 handleoptions = 1; - RK_S32 err = MPP_NOK; - - if ((argc < 2) || (cmd == NULL)) { - err = 1; - return err; - } - - /* parse options */ - while (optindex < argc) { - opt = (const char*)argv[optindex++]; - next = (const char*)argv[optindex]; - - if (handleoptions && opt[0] == '-' && opt[1] != '\0') { - if (opt[1] == '-') { - if (opt[2] != '\0') { - opt++; - } else { - handleoptions = 0; - continue; - } - } - - opt++; - - switch (*opt) { - case 'i': - if (next) { - strncpy(cmd->file_input, next, MPI_RC_FILE_NAME_LEN - 1); - cmd->have_input = 1; - } else { - mpp_err("input file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'o': - if (next) { - strncpy(cmd->file_enc_out, next, MPI_RC_FILE_NAME_LEN - 1); - cmd->have_enc_out = 1; - } else { - mpp_log("output file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'd': - if (next) { - cmd->debug = atoi(next);; - } else { - mpp_err("invalid debug flag\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'w': - if (next) { - cmd->width = atoi(next); - } else { - mpp_err("invalid input width\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'h': - if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) { - mpi_rc_test_help(); - err = 1; - goto PARSE_OPINIONS_OUT; - } else if (next) { - cmd->height = atoi(next); - } else { - mpp_log("input height is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'f': - if (next) { - cmd->format = (MppFrameFormat)atoi(next); - err = ((cmd->format >= MPP_FMT_YUV_BUTT && cmd->format < MPP_FRAME_FMT_RGB) || - cmd->format >= MPP_FMT_RGB_BUTT); - } - - if (!next || err) { - mpp_err("invalid input format %d\n", cmd->format); - goto PARSE_OPINIONS_OUT; - } - break; - case 't': - if (next) { - cmd->type = (MppCodingType)atoi(next); - err = mpp_check_support_format(MPP_CTX_ENC, cmd->type); - } - - if (!next || err) { - mpp_err("invalid input coding type\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'n': - if (next) { - cmd->num_frames = atoi(next); - } else { - mpp_err("invalid input max number of frames\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'y': - if (next) { - strncpy(cmd->file_dec_out, next, MPI_RC_FILE_NAME_LEN - 1); - cmd->have_dec_out = 1; - } else { - mpp_log("dec output file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 's': - if (next) { - strncpy(cmd->file_stat, next, MPI_RC_FILE_NAME_LEN - 1); - cmd->have_stat_out = 1; - } else { - mpp_log("stat file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'c': - if (next) { - cmd->item_flag = strtol(next, NULL, 0); - } else { - mpp_err("invalid input item_flag\n"); - goto PARSE_OPINIONS_OUT; - } - break; - default: - goto PARSE_OPINIONS_OUT; - break; - } - - optindex++; - } - } - - err = 0; - -PARSE_OPINIONS_OUT: - return err; -} - -static void mpi_rc_test_show_options(MpiRcTestCmd* cmd) -{ - mpp_log("cmd parse result:\n"); - mpp_log("input file name: %s\n", cmd->file_input); - mpp_log("enc out file name: %s\n", cmd->file_enc_out); - mpp_log("dec out file name: %s\n", cmd->file_dec_out); - mpp_log("stat file name: %s\n", cmd->file_stat); - mpp_log("width : %d\n", cmd->width); - mpp_log("height : %d\n", cmd->height); - mpp_log("type : %d\n", cmd->type); - mpp_log("debug flag : %x\n", cmd->debug); - mpp_log("format : %d\n", cmd->format); - mpp_log("num frames : %d\n", cmd->num_frames); - mpp_log("item flag : 0x%x\n", cmd->item_flag); -} - -int main(int argc, char **argv) -{ - MPP_RET ret = MPP_OK; - MpiRcTestCtx ctx; - MpiRcTestCmd* cmd = &ctx.cmd; - - mpp_log("=========== mpi rc test start ===========\n"); - - memset(&ctx, 0, sizeof(ctx)); - - // parse the cmd option - ret = mpi_enc_test_parse_options(argc, argv, cmd); - if (ret) { - if (ret < 0) { - mpp_err("mpi_rc_test_parse_options: input parameter invalid\n"); - } - - mpi_rc_test_help(); - return ret; - } - - mpi_rc_test_show_options(cmd); - - mpp_env_set_u32("mpi_rc_debug", cmd->debug); - - ret = mpi_rc_init(&ctx); - if (ret != MPP_OK) { - mpp_err("mpi_rc_init failded ret %d", ret); - goto err; - } - - ret = mpi_rc_codec(&ctx); - if (ret != MPP_OK) { - mpp_err("mpi_rc_codec failded ret %d", ret); - goto err; - } - -err: - mpi_rc_deinit(&ctx); - - mpp_log("=========== mpi rc test end ===========\n"); - - return (int)ret; -} - diff --git a/utils/mpi_dec_utils.c b/utils/mpi_dec_utils.c index c56dcc70..f0369ffd 100644 --- a/utils/mpi_dec_utils.c +++ b/utils/mpi_dec_utils.c @@ -30,6 +30,7 @@ #include "mpp_common.h" #include "mpp_buffer.h" +#include "mpp_opt.h" #include "mpi_dec_utils.h" #define IVF_HEADER_LENGTH 32 @@ -434,158 +435,233 @@ void show_dec_fps(RK_S64 total_time, RK_S64 total_count, RK_S64 last_time, RK_S6 total_count, avg_fps, ins_fps); } -void mpi_dec_test_cmd_help() +RK_S32 mpi_dec_opt_i(void *ctx, const char *next) { - mpp_log("usage: mpi_dec_test [options]\n"); - show_options(mpi_dec_cmd); + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + if (next) { + strncpy(cmd->file_input, next, MAX_FILE_NAME_LENGTH - 1); + cmd->have_input = 1; + name_to_coding_type(cmd->file_input, &cmd->type); + return 1; + } + + mpp_err("input file is invalid\n"); + return 0; +} + +RK_S32 mpi_dec_opt_o(void *ctx, const char *next) +{ + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + if (next) { + strncpy(cmd->file_output, next, MAX_FILE_NAME_LENGTH - 1); + cmd->have_output = 1; + return 1; + } + + mpp_log("output file is invalid\n"); + return 0; +} + +RK_S32 mpi_dec_opt_w(void *ctx, const char *next) +{ + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + if (next) { + cmd->width = atoi(next); + return 1; + } + + mpp_err("invalid input width\n"); + return 0; +} + +RK_S32 mpi_dec_opt_h(void *ctx, const char *next) +{ + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + if (next) { + cmd->height = atoi(next); + return 1; + } + + mpp_err("invalid input height\n"); + return 0; +} + +RK_S32 mpi_dec_opt_t(void *ctx, const char *next) +{ + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + if (next) { + MPP_RET ret; + + cmd->type = (MppCodingType)atoi(next); + ret = mpp_check_support_format(MPP_CTX_DEC, cmd->type); + if (!ret) + return 1; + } + + mpp_err("invalid input coding type\n"); + return 0; +} + +RK_S32 mpi_dec_opt_f(void *ctx, const char *next) +{ + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + if (next) { + cmd->format = (MppFrameFormat)atoi(next); + + if (MPP_FRAME_FMT_IS_YUV(cmd->format) || + MPP_FRAME_FMT_IS_RGB(cmd->format)) + return 1; + } + + mpp_err("invalid output format\n"); + cmd->format = MPP_FMT_BUTT; + return 0; +} + +RK_S32 mpi_dec_opt_n(void *ctx, const char *next) +{ + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + if (next) { + cmd->frame_num = atoi(next); + + if (cmd->frame_num < 0) + mpp_log("infinite loop decoding mode\n"); + + return 1; + } + + mpp_err("invalid frame number\n"); + return 0; +} + +RK_S32 mpi_dec_opt_s(void *ctx, const char *next) +{ + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + cmd->nthreads = -1; + if (next) { + cmd->nthreads = atoi(next); + if (cmd->nthreads >= 1) + return 1; + } + + mpp_err("invalid nthreads %d\n", cmd->nthreads); + cmd->nthreads = 1; + return 0; +} + +RK_S32 mpi_dec_opt_v(void *ctx, const char *next) +{ + MpiDecTestCmd *cmd = (MpiDecTestCmd *)ctx; + + if (next) { + if (strstr(next, "q")) + cmd->quiet = 1; + if (strstr(next, "f")) + cmd->trace_fps = 1; + + return 1; + } + + return 0; +} + +RK_S32 mpi_dec_opt_help(void *ctx, const char *next) +{ + (void)ctx; + (void)next; + /* return invalid option to print help */ + return -1; +} + +static MppOptInfo dec_opts[] = { + {"i", "input_file", "input bitstream file", mpi_dec_opt_i}, + {"o", "output_file", "output decoded frame file", mpi_dec_opt_o}, + {"w", "width", "the width of input bitstream", mpi_dec_opt_w}, + {"h", "height", "the height of input bitstream", mpi_dec_opt_h}, + {"t", "type", "input stream coding type", mpi_dec_opt_t}, + {"f", "format", "output frame format type", mpi_dec_opt_f}, + {"n", "frame_number", "max output frame number", mpi_dec_opt_n}, + {"s", "instance_nb", "number of instances", mpi_dec_opt_s}, + {"v", "trace option", "q - quiet f - show fps", mpi_dec_opt_v}, + {"help", "help", "show help", mpi_dec_opt_help}, +}; + +static RK_U32 dec_opt_cnt = MPP_ARRAY_ELEMS(dec_opts); + +RK_S32 mpi_dec_show_help(const char *name) +{ + RK_U32 max_name = 1; + RK_U32 max_full_name = 1; + RK_U32 max_help = 1; + char logs[256]; + RK_U32 len; + RK_U32 i; + + mpp_log("usage: %s [options]\n", name); + + for (i = 0; i < dec_opt_cnt; i++) { + MppOptInfo *opt = &dec_opts[i]; + + if (opt->name) { + len = strlen(opt->name); + if (len > max_name) + max_name = len; + } + + if (opt->full_name) { + len = strlen(opt->full_name); + if (len > max_full_name) + max_full_name = len; + } + + if (opt->help) { + len = strlen(opt->help); + if (len > max_help) + max_help = len; + } + } + + snprintf(logs, sizeof(logs) - 1, "-%%-%ds %%-%ds %%-%ds\n", max_name, max_full_name, max_help); + + for (i = 0; i < dec_opt_cnt; i++) { + MppOptInfo *opt = &dec_opts[i]; + + mpp_log(logs, opt->name, opt->full_name, opt->help); + } mpp_show_support_format(); + + return -1; } RK_S32 mpi_dec_test_cmd_init(MpiDecTestCmd* cmd, int argc, char **argv) { - const char *opt; - const char *next; - RK_S32 optindex = 1; - RK_S32 handleoptions = 1; - RK_S32 err = MPP_OK; + MppOpt opts = NULL; + RK_S32 ret = -1; + RK_U32 i; - if ((argc < 2) || (cmd == NULL)) { - err = 1; - return err; - } + if ((argc < 2) || (cmd == NULL)) + goto done; - /* parse options */ - while (optindex < argc) { - opt = (const char*)argv[optindex++]; - next = (const char*)argv[optindex]; + mpp_opt_init(&opts); + /* should change node count when option increases */ + mpp_opt_setup(opts, cmd, 18, dec_opt_cnt); - if (handleoptions && opt[0] == '-' && opt[1] != '\0') { - if (opt[1] == '-') { - if (opt[2] != '\0') { - opt++; - } else { - handleoptions = 0; - continue; - } - } + for (i = 0; i < dec_opt_cnt; i++) + mpp_opt_add(opts, &dec_opts[i]); - opt++; + /* mark option end */ + mpp_opt_add(opts, NULL); - switch (*opt) { - case 'i' : { - if (next) { - strncpy(cmd->file_input, next, MAX_FILE_NAME_LENGTH - 1); - cmd->have_input = 1; - name_to_coding_type(cmd->file_input, &cmd->type); - } else { - mpp_err("input file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'o' : { - if (next) { - strncpy(cmd->file_output, next, MAX_FILE_NAME_LENGTH - 1); - cmd->have_output = 1; - } else { - mpp_log("output file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'w' : { - if (next) { - cmd->width = atoi(next); - } else { - mpp_err("invalid input width\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'h' : { - if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) { - mpi_dec_test_cmd_help(); - err = 1; - goto PARSE_OPINIONS_OUT; - } else if (next) { - cmd->height = atoi(next); - } else { - mpp_log("input height is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 't' : { - if (next) { - cmd->type = (MppCodingType)atoi(next); - err = mpp_check_support_format(MPP_CTX_DEC, cmd->type); - } + ret = mpp_opt_parse(opts, argc, argv); - if (!next || err) { - mpp_err("invalid input coding type\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'f' : { - if (next) { - cmd->format = (MppFrameFormat)atoi(next); - - if (!MPP_FRAME_FMT_IS_YUV(cmd->format) && - !MPP_FRAME_FMT_IS_RGB(cmd->format)) - err = 1; - } - - if (!next || err) { - mpp_err("invalid output format\n"); - cmd->format = MPP_FMT_BUTT; - goto PARSE_OPINIONS_OUT; - } - } break; - case 'x' : { - if (next) { - cmd->timeout = atoi(next); - } - - if (!next || cmd->timeout < 0) { - mpp_err("invalid output timeout interval\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'n' : { - if (next) { - cmd->frame_num = atoi(next); - if (cmd->frame_num < 0) - mpp_log("infinite loop decoding mode\n"); - } else { - mpp_err("invalid frame number\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 's' : { - if (next) { - cmd->nthreads = atoi(next); - } - if (!next || cmd->nthreads < 0) { - mpp_err("invalid nthreads\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'v' : { - if (next) { - if (strstr(next, "q")) - cmd->quiet = 1; - if (strstr(next, "f")) - cmd->trace_fps = 1; - } - } break; - default : { - mpp_err("skip invalid opt %c\n", *opt); - } break; - } - - optindex++; - } - } - - err = 0; - -PARSE_OPINIONS_OUT: if (cmd->have_input) { reader_init(&cmd->reader, cmd->file_input); if (cmd->reader) @@ -597,7 +673,16 @@ PARSE_OPINIONS_OUT: fps_calc_set_cb(cmd->fps, show_dec_fps); } - return err; +done: + if (opts) { + mpp_opt_deinit(opts); + opts = NULL; + } + + if (ret) + mpi_dec_show_help(argv[0]); + + return ret; } RK_S32 mpi_dec_test_cmd_deinit(MpiDecTestCmd* cmd) diff --git a/utils/mpi_dec_utils.h b/utils/mpi_dec_utils.h index 9fe6de5f..702a24de 100644 --- a/utils/mpi_dec_utils.h +++ b/utils/mpi_dec_utils.h @@ -61,7 +61,6 @@ typedef struct MpiDecTestCmd_t { FpsCalc fps; /* runtime log flag */ - RK_U32 debug; RK_U32 quiet; RK_U32 trace_fps; } MpiDecTestCmd; @@ -71,7 +70,6 @@ extern OptionInfo mpi_dec_cmd[]; RK_S32 mpi_dec_test_cmd_init(MpiDecTestCmd* cmd, int argc, char **argv); RK_S32 mpi_dec_test_cmd_deinit(MpiDecTestCmd* cmd); void mpi_dec_test_cmd_options(MpiDecTestCmd* cmd); -void mpi_dec_test_cmd_help(); void reader_init(FileReader* reader, char* file_in); void reader_deinit(FileReader reader); diff --git a/utils/mpi_enc_utils.c b/utils/mpi_enc_utils.c index 37944530..61bb037e 100644 --- a/utils/mpi_enc_utils.c +++ b/utils/mpi_enc_utils.c @@ -25,6 +25,8 @@ #include "rk_mpi.h" #include "utils.h" #include "mpp_common.h" + +#include "mpp_opt.h" #include "mpi_enc_utils.h" #define MAX_FILE_NAME_LENGTH 256 @@ -91,244 +93,414 @@ MpiEncTestArgs *mpi_enc_test_cmd_get(void) { MpiEncTestArgs *args = mpp_calloc(MpiEncTestArgs, 1); + if (args) + args->nthreads = 1; + return args; } +RK_S32 mpi_enc_opt_i(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + size_t len = strnlen(next, MAX_FILE_NAME_LENGTH); + if (len) { + cmd->file_input = mpp_calloc(char, len + 1); + strcpy(cmd->file_input, next); + name_to_frame_format(cmd->file_input, &cmd->format); + } + + return 1; + } + + mpp_err("input file is invalid\n"); + return 0; +} + +RK_S32 mpi_enc_opt_o(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + size_t len = strnlen(next, MAX_FILE_NAME_LENGTH); + if (len) { + cmd->file_output = mpp_calloc(char, len + 1); + strcpy(cmd->file_output, next); + name_to_coding_type(cmd->file_output, &cmd->type); + } + + return 1; + } + + mpp_log("output file is invalid\n"); + return 0; +} + +RK_S32 mpi_enc_opt_w(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + cmd->width = atoi(next); + return 1; + } + + mpp_err("invalid input width\n"); + return 0; +} + +RK_S32 mpi_enc_opt_h(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + cmd->height = atoi(next); + return 1; + } + + mpp_err("invalid input height\n"); + return 0; +} + +RK_S32 mpi_enc_opt_hstride(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + cmd->hor_stride = atoi(next); + return 1; + } + + mpp_err("invalid input horizontal stride\n"); + return 0; +} + +RK_S32 mpi_enc_opt_vstride(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + cmd->ver_stride = atoi(next); + return 1; + } + + mpp_err("invalid input vertical stride\n"); + return 0; +} + +RK_S32 mpi_enc_opt_f(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + MppFrameFormat format = MPP_FMT_BUTT; + + if (next) { + if (strstr(next, "x") || strstr(next, "X")) { + /* hex value with 0x prefix, use sscanf */ + sscanf(next, "0x%x", &format); + } else if (strstr(next, "a") || strstr(next, "A") || + strstr(next, "b") || strstr(next, "B") || + strstr(next, "c") || strstr(next, "C") || + strstr(next, "d") || strstr(next, "D") || + strstr(next, "e") || strstr(next, "E") || + strstr(next, "f") || strstr(next, "F")) { + /* hex value without 0x prefix, use sscanf */ + sscanf(next, "%x", &format); + } else { + /* decimal value, use atoi */ + format = (MppFrameFormat)atoi(next); + } + if (MPP_FRAME_FMT_IS_LE(format) && + (MPP_FRAME_FMT_IS_YUV(format) || MPP_FRAME_FMT_IS_RGB(format))) { + cmd->format = format; + return 1; + } + } + + mpp_err("invalid input format %x\n", format); + cmd->format = MPP_FMT_YUV420SP; + return 0; +} + +RK_S32 mpi_enc_opt_t(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + MppCodingType type = MPP_VIDEO_CodingUnused; + + if (next) { + type = (MppCodingType)atoi(next); + if (!mpp_check_support_format(MPP_CTX_ENC, type)) + cmd->type = type; + return 1; + } + + mpp_err("invalid input coding type %d\n", type); + return 0; +} + +RK_S32 mpi_enc_opt_n(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + cmd->frame_num = atoi(next); + return 1; + } + + mpp_err("invalid input max number of frames\n"); + return 0; +} + +RK_S32 mpi_enc_opt_g(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + RK_S32 cnt = 0; + + if (next) { + cnt = sscanf(next, "%d:%d:%d", + &cmd->gop_mode, &cmd->gop_len, &cmd->vi_len); + if (cnt) + return 1; + } + + mpp_err("invalid gop mode use -g gop_mode:gop_len:vi_len\n"); + return 0; +} + +RK_S32 mpi_enc_opt_bps(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + RK_S32 cnt = 0; + + if (next) { + cnt = sscanf(next, "%d:%d:%d:%d", + &cmd->bps_target, &cmd->bps_min, &cmd->bps_max, + &cmd->rc_mode); + if (cnt) + return 1; + } + + mpp_err("invalid bit rate usage -b bps_target:bps_min:bps_max:rc_mode\n"); + mpp_err("rc_mode 0:vbr 1:cbr 2:avbr 3:cvbr 4:fixqp\n"); + return 0; +} + +RK_S32 mpi_enc_opt_fps(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + RK_U32 num = sscanf(next, "%d:%d:%d/%d:%d:%d", + &cmd->fps_in_num, &cmd->fps_in_den, &cmd->fps_in_flex, + &cmd->fps_out_num, &cmd->fps_out_den, &cmd->fps_out_flex); + switch (num) { + case 1 : { + cmd->fps_out_num = cmd->fps_in_num; + cmd->fps_out_den = cmd->fps_in_den = 1; + cmd->fps_out_flex = cmd->fps_in_flex = 0; + } break; + case 2 : { + cmd->fps_out_num = cmd->fps_in_num; + cmd->fps_out_den = cmd->fps_in_den; + cmd->fps_out_flex = cmd->fps_in_flex = 0; + } break; + case 3 : { + cmd->fps_out_num = cmd->fps_in_num; + cmd->fps_out_den = cmd->fps_in_den; + cmd->fps_out_flex = cmd->fps_in_flex; + } break; + case 4 : { + cmd->fps_out_den = 1; + cmd->fps_out_flex = 0; + } break; + case 5 : { + cmd->fps_out_flex = 0; + } break; + case 6 : { + } break; + default : { + mpp_err("invalid in/out frame rate," + " use \"-r numerator:denominator:flex\"" + " for set the input to the same fps as the output, such as 50:1:1\n" + " or \"-r numerator:denominator/flex-numerator:denominator:flex\"" + " for set input and output separately, such as 40:1:1/30:1:0\n"); + } break; + } + + return (num && num <= 6); + } + + mpp_err("invalid output frame rate\n"); + return 0; +} + +RK_S32 mpi_enc_opt_s(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + cmd->nthreads = -1; + if (next) { + cmd->nthreads = atoi(next); + if (cmd->nthreads >= 1) + return 1; + } + + mpp_err("invalid nthreads %d\n", cmd->nthreads); + cmd->nthreads = 1; + return 0; +} + +RK_S32 mpi_enc_opt_l(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + cmd->loop_cnt = atoi(next); + return 1; + } + + mpp_err("invalid loop count\n"); + return 0; +} + +RK_S32 mpi_enc_opt_v(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + if (strstr(next, "q")) + cmd->quiet = 1; + if (strstr(next, "f")) + cmd->trace_fps = 1; + + return 1; + } + + return 0; +} + +RK_S32 mpi_enc_opt_ini(void *ctx, const char *next) +{ + MpiEncTestArgs *cmd = (MpiEncTestArgs *)ctx; + + if (next) { + size_t len = strnlen(next, MAX_FILE_NAME_LENGTH); + if (len) { + cmd->file_cfg = mpp_calloc(char, len + 1); + strncpy(cmd->file_cfg, next, len); + cmd->cfg_ini = iniparser_load(cmd->file_cfg); + + return 1; + } + } + + mpp_err("input ini file is invalid\n"); + return 0; +} + +RK_S32 mpi_enc_opt_help(void *ctx, const char *next) +{ + (void)ctx; + (void)next; + return -1; +} + +static MppOptInfo enc_opts[] = { + {"i", "input_file", "input frame file", mpi_enc_opt_i}, + {"o", "output_file", "output encoded bitstream file", mpi_enc_opt_o}, + {"w", "width", "the width of input picture", mpi_enc_opt_w}, + {"h", "height", "the height of input picture", mpi_enc_opt_h}, + {"hstride", "hor_stride", "the horizontal stride of input picture", mpi_enc_opt_hstride}, + {"vstride", "ver_stride", "the vertical stride of input picture", mpi_enc_opt_vstride}, + {"f", "format", "the format of input picture", mpi_enc_opt_f}, + {"t", "type", "output stream coding type", mpi_enc_opt_t}, + {"n", "max frame number", "max encoding frame number", mpi_enc_opt_n}, + {"g", "gop reference mode", "gop_mode:gop_len:vi_len", mpi_enc_opt_g}, + {"bps", "bps target:min:max", "set tareget/min/max bps and rc_mode", mpi_enc_opt_bps}, + {"fps", "in/output fps", "set input and output frame rate", mpi_enc_opt_fps}, + {"s", "instance_nb", "number of instances", mpi_enc_opt_s}, + {"v", "trace option", "q - quiet f - show fps", mpi_enc_opt_v}, + {"l", "loop count", "loop encoding times for each frame", mpi_enc_opt_l}, + {"ini", "ini file", "encoder extra ini config file", mpi_enc_opt_ini}, +}; + +static RK_U32 enc_opt_cnt = MPP_ARRAY_ELEMS(enc_opts); + +RK_S32 mpi_enc_show_help(const char *name) +{ + RK_U32 max_name = 1; + RK_U32 max_full_name = 1; + RK_U32 max_help = 1; + char logs[256]; + RK_U32 len; + RK_U32 i; + + mpp_log("usage: %s [options]\n", name); + + for (i = 0; i < enc_opt_cnt; i++) { + MppOptInfo *opt = &enc_opts[i]; + + if (opt->name) { + len = strlen(opt->name); + if (len > max_name) + max_name = len; + } + + if (opt->full_name) { + len = strlen(opt->full_name); + if (len > max_full_name) + max_full_name = len; + } + + if (opt->help) { + len = strlen(opt->help); + if (len > max_help) + max_help = len; + } + } + + snprintf(logs, sizeof(logs) - 1, "-%%-%ds %%-%ds %%-%ds\n", max_name, max_full_name, max_help); + + for (i = 0; i < enc_opt_cnt; i++) { + MppOptInfo *opt = &enc_opts[i]; + + mpp_log(logs, opt->name, opt->full_name, opt->help); + } + mpp_show_support_format(); + mpp_show_color_format(); + + return -1; +} + +void show_enc_fps(RK_S64 total_time, RK_S64 total_count, RK_S64 last_time, RK_S64 last_count) +{ + float avg_fps = (float)total_count * 1000000 / total_time; + float ins_fps = (float)last_count * 1000000 / last_time; + + mpp_log("encoded %10lld frame fps avg %7.2f ins %7.2f\n", + total_count, avg_fps, ins_fps); +} + MPP_RET mpi_enc_test_cmd_update_by_args(MpiEncTestArgs* cmd, int argc, char **argv) { - const char *opt; - const char *next; - RK_S32 optindex = 1; - RK_S32 handleoptions = 1; - MPP_RET ret = MPP_NOK; + MppOpt opts = NULL; + RK_S32 ret = -1; + RK_U32 i; - if ((argc < 2) || (cmd == NULL)) - return ret; + if ((argc < 2) || NULL == cmd || NULL == argv) + goto done; - /* parse options */ - while (optindex < argc) { - opt = (const char*)argv[optindex++]; - next = (const char*)argv[optindex]; + mpp_opt_init(&opts); + /* should change node count when option increases */ + mpp_opt_setup(opts, cmd, 50, enc_opt_cnt); - if (handleoptions && opt[0] == '-' && opt[1] != '\0') { - if (opt[1] == '-') { - if (opt[2] != '\0') { - opt++; - } else { - handleoptions = 0; - continue; - } - } + for (i = 0; i < enc_opt_cnt; i++) + mpp_opt_add(opts, &enc_opts[i]); - opt++; + /* mark option end */ + mpp_opt_add(opts, NULL); - switch (*opt) { - case 'i' : { - if (next) { - size_t len = strnlen(next, MAX_FILE_NAME_LENGTH); - if (len) { - cmd->file_input = mpp_calloc(char, len + 1); - strcpy(cmd->file_input, next); - name_to_frame_format(cmd->file_input, &cmd->format); - } - } else { - mpp_err("input file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'o' : { - if (next) { - size_t len = strnlen(next, MAX_FILE_NAME_LENGTH); - if (len) { - cmd->file_output = mpp_calloc(char, len + 1); - strcpy(cmd->file_output, next); - name_to_coding_type(cmd->file_output, &cmd->type); - } - } else { - mpp_log("output file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'w' : { - if (next) { - cmd->width = atoi(next); - } else { - mpp_err("invalid input width\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'h' : { - if (!next) - goto PARSE_OPINIONS_OUT; - - if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) { - goto PARSE_OPINIONS_OUT; - } else if (next) { - cmd->height = atoi(next); - } - } break; - case 'u' : { - if (next) { - cmd->hor_stride = atoi(next); - } else { - mpp_err("invalid input width\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'v' : { - if (next) { - cmd->ver_stride = atoi(next); - } else { - mpp_log("input height is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'f' : { - if (next) { - if (strstr(next, "x") || strstr(next, "X")) { - /* hex value with 0x prefix, use sscanf */ - sscanf(next, "0x%x", &cmd->format); - } else if (strstr(next, "a") || strstr(next, "A") || - strstr(next, "b") || strstr(next, "B") || - strstr(next, "c") || strstr(next, "C") || - strstr(next, "d") || strstr(next, "D") || - strstr(next, "e") || strstr(next, "E") || - strstr(next, "f") || strstr(next, "F")) { - /* hex value without 0x prefix, use sscanf */ - sscanf(next, "%x", &cmd->format); - } else { - /* decimal value, use atoi */ - cmd->format = (MppFrameFormat)atoi(next); - } - ret = (!MPP_FRAME_FMT_IS_LE(cmd->format)) && ((cmd->format >= MPP_FMT_YUV_BUTT && cmd->format < MPP_FRAME_FMT_RGB) || - cmd->format >= MPP_FMT_RGB_BUTT); - } - - if (!next || ret) { - mpp_err("invalid input format %d\n", cmd->format); - goto PARSE_OPINIONS_OUT; - } - } break; - case 't' : { - if (next) { - cmd->type = (MppCodingType)atoi(next); - ret = mpp_check_support_format(MPP_CTX_ENC, cmd->type); - } - - if (!next || ret) { - mpp_err("invalid input coding type\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'n' : { - if (next) { - cmd->num_frames = atoi(next); - } else { - mpp_err("invalid input max number of frames\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'g' : { - RK_S32 cnt = 0; - - if (next) - cnt = sscanf(next, "%d:%d:%d", - &cmd->gop_mode, &cmd->gop_len, &cmd->vi_len); - - if (!cnt) { - mpp_err("invalid gop mode use -g gop_mode:gop_len:vi_len\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'b' : { - RK_S32 cnt = 0; - - if (next) - cnt = sscanf(next, "%d:%d:%d:%d", - &cmd->bps_target, &cmd->bps_min, &cmd->bps_max, - &cmd->rc_mode); - - if (!cnt) { - mpp_err("invalid bit rate usage -b bps_target:bps_min:bps_max:rc_mode\n"); - mpp_err("rc_mode 0:vbr 1:cbr 2:avbr 3:cvbr 4:fixqp\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'r' : { - if (next) { - RK_S32 num = sscanf(next, "%d:%d:%d/%d:%d:%d", - &cmd->fps_in_num, &cmd->fps_in_den, &cmd->fps_in_flex, - &cmd->fps_out_num, &cmd->fps_out_den, &cmd->fps_out_flex); - switch (num) { - case 1 : { - cmd->fps_out_num = cmd->fps_in_num; - cmd->fps_out_den = cmd->fps_in_den = 1; - cmd->fps_out_flex = cmd->fps_in_flex = 0; - } break; - case 2 : { - cmd->fps_out_num = cmd->fps_in_num; - cmd->fps_out_den = cmd->fps_in_den; - cmd->fps_out_flex = cmd->fps_in_flex = 0; - } break; - case 3 : { - cmd->fps_out_num = cmd->fps_in_num; - cmd->fps_out_den = cmd->fps_in_den; - cmd->fps_out_flex = cmd->fps_in_flex; - } break; - case 4 : { - cmd->fps_out_den = 1; - cmd->fps_out_flex = 0; - } break; - case 5 : { - cmd->fps_out_flex = 0; - } break; - case 6 : { - } break; - default : { - mpp_err("invalid in/out frame rate," - " use \"-r numerator:denominator:flex\"" - " for set the input to the same fps as the output, such as 50:1:1\n" - " or \"-r numerator:denominator/flex-numerator:denominator:flex\"" - " for set input and output separately, such as 40:1:1/30:1:0\n"); - goto PARSE_OPINIONS_OUT; - } break; - } - } else { - mpp_err("invalid output frame rate\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'l' : { - if (next) { - cmd->loop_cnt = atoi(next); - } else { - mpp_err("invalid loop count\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - case 'x': { - if (next) { - size_t len = strnlen(next, MAX_FILE_NAME_LENGTH); - if (len) { - cmd->file_cfg = mpp_calloc(char, len + 1); - strncpy(cmd->file_cfg, next, len); - cmd->cfg_ini = iniparser_load(cmd->file_cfg); - } - } else { - mpp_err("input file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - } break; - default : { - mpp_err("skip invalid opt %c\n", *opt); - } break; - } - - optindex++; - } - } - - ret = MPP_OK; + ret = mpp_opt_parse(opts, argc, argv); /* check essential parameter */ if (cmd->type <= MPP_VIDEO_CodingAutoDetect) { @@ -347,8 +519,20 @@ MPP_RET mpi_enc_test_cmd_update_by_args(MpiEncTestArgs* cmd, int argc, char **ar cmd->width, cmd->height, cmd->hor_stride, cmd->ver_stride); ret = MPP_NOK; } + if (cmd->trace_fps) { + fps_calc_init(&cmd->fps); + mpp_assert(cmd->fps); + fps_calc_set_cb(cmd->fps, show_enc_fps); + } + +done: + if (opts) { + mpp_opt_deinit(opts); + opts = NULL; + } + if (ret) + mpi_enc_show_help(argv[0]); -PARSE_OPINIONS_OUT: return ret; } @@ -362,6 +546,11 @@ MPP_RET mpi_enc_test_cmd_put(MpiEncTestArgs* cmd) cmd->cfg_ini = NULL; } + if (cmd->fps) { + fps_calc_deinit(cmd->fps); + cmd->fps = NULL; + } + MPP_FREE(cmd->file_input); MPP_FREE(cmd->file_output); MPP_FREE(cmd->file_cfg); diff --git a/utils/mpi_enc_utils.h b/utils/mpi_enc_utils.h index 84108b3b..363a3f69 100644 --- a/utils/mpi_enc_utils.h +++ b/utils/mpi_enc_utils.h @@ -30,19 +30,22 @@ typedef struct MpiEncTestArgs_t { MppCodingType type; MppFrameFormat format; - RK_S32 num_frames; + RK_S32 frame_num; RK_S32 loop_cnt; + RK_S32 nthreads; RK_S32 width; RK_S32 height; RK_S32 hor_stride; RK_S32 ver_stride; + /* -bps */ RK_S32 bps_target; RK_S32 bps_max; RK_S32 bps_min; RK_S32 rc_mode; + /* -fps */ RK_S32 fps_in_flex; RK_S32 fps_in_num; RK_S32 fps_in_den; @@ -50,13 +53,16 @@ typedef struct MpiEncTestArgs_t { RK_S32 fps_out_num; RK_S32 fps_out_den; + /* -g gop mode */ RK_S32 gop_mode; RK_S32 gop_len; RK_S32 vi_len; - MppEncHeaderMode header_mode; - - MppEncSliceSplit split; + /* -v q runtime log disable flag */ + RK_U32 quiet; + /* -v f runtime fps log flag */ + RK_U32 trace_fps; + FpsCalc fps; } MpiEncTestArgs; #ifdef __cplusplus