[mpi_enc_test]: fix mpi_enc_test read src frame bug

1. read src frame with real width and height of picture,
   rather than virtual ones.
2. configure correct hor_stride & ver_stride for hardware
3. support yuv420/420sp for mpi_enc_test demo and video
   app, and is compatible for old interface

Change-Id: I1fc23dc2954577b28e25b80a4dcdd1536d45d622
Signed-off-by: Lin Kesheng <lks@rock-chips.com>
This commit is contained in:
Lin Kesheng
2016-11-23 09:57:24 +08:00
parent edaf21bab8
commit 723ffae18e
12 changed files with 158 additions and 36 deletions

View File

@@ -303,8 +303,7 @@ MPP_RET avsd_callback(void *decoder, void *info)
if (ctx->hard_err || task_dec->flags.had_error) {
if (task_dec->flags.used_for_ref) {
mpp_frame_set_errinfo(mframe, MPP_FRAME_FLAG_PAIRED_FIELD);
}
else {
} else {
mpp_frame_set_discard(mframe, MPP_FRAME_FLAG_PAIRED_FIELD);
}
}

View File

@@ -42,6 +42,8 @@ typedef struct {
RK_U32 lumHeightSrc; /* Source input image height */
RK_U32 lumWidth; /* Encoded image width */
RK_U32 lumHeight; /* Encoded image height */
RK_U32 hor_stride; /* Encoded image horizontal stride */
RK_U32 ver_stride; /* Encoded image vertical stride */
RK_U32 horOffsetSrc; /* Encoded frame offset, reference is ... */
RK_U32 verOffsetSrc; /* ...top left corner of source image */
RK_U32 inputFormat;

View File

@@ -210,6 +210,8 @@ typedef struct {
H264Level level;
RK_U32 width; /* Encoded picture width in pixels, multiple of 4 */
RK_U32 height; /* Encoded picture height in pixels, multiple of 2 */
RK_U32 hor_stride; /* Encoded picture horizontal stride in pixels */
RK_U32 ver_stride; /* Encoded picture vertical stride in pixels */
RK_U32 frameRateNum; /* The stream time scale, [1..65535] */
RK_U32 frameRateDenom; /* Maximum frame rate is frameRateNum/frameRateDenom
* in frames/second. The actual frame rate will be

View File

@@ -221,6 +221,9 @@ bool_e SetParameter(H264ECtx * inst, const H264EncConfig * pEncCfg)
inst->preProcess.lumHeight = pEncCfg->height;
inst->preProcess.lumHeightSrc = pEncCfg->height;
inst->preProcess.hor_stride = pEncCfg->hor_stride;
inst->preProcess.ver_stride = pEncCfg->ver_stride;
inst->preProcess.horOffsetSrc = 0;
inst->preProcess.verOffsetSrc = 0;

View File

@@ -109,6 +109,8 @@ void EncAsicFrameStart(void * inst, regValues_s * val, h264e_syntax *syntax_data
syntax_data->output_strm_addr = val->outputStrmBase;
syntax_data->pic_luma_width = ctx->preProcess.lumWidth;
syntax_data->pic_luma_height = ctx->preProcess.lumHeight;
syntax_data->pic_hor_stride = ctx->preProcess.hor_stride;
syntax_data->pic_ver_stride = ctx->preProcess.ver_stride;
syntax_data->input_luma_addr = val->inputLumBase;
syntax_data->input_cb_addr = val->inputCbBase;
syntax_data->input_cr_addr = val->inputCrBase;

View File

@@ -82,8 +82,8 @@ MPP_RET h264e_encode(void *ctx, HalEncTask *task)
H264ECtx *p = (H264ECtx *)ctx;
H264EncIn *encIn = &(p->encIn);
H264EncOut *encOut = &(p->encOut);
RK_U32 srcLumaWidth = p->lumWidthSrc;
RK_U32 srcLumaHeight = p->lumHeightSrc;
RK_U32 srcHorStride = p->preProcess.hor_stride;
RK_U32 srcVerStride = p->preProcess.ver_stride;
encIn->pOutBuf = (RK_U32*)mpp_buffer_get_ptr(task->output);
encIn->busOutBuf = mpp_buffer_get_fd(task->output);
@@ -104,14 +104,10 @@ MPP_RET h264e_encode(void *ctx, HalEncTask *task)
}
/* Setup encoder input */
{
RK_U32 w = srcLumaWidth;
// TODO: support more format in the future
encIn->busLuma = mpp_buffer_get_fd(task->input);
encIn->busChromaU = encIn->busLuma | ((w * srcLumaHeight) << 10);
encIn->busChromaV = encIn->busChromaU +
((((w + 1) >> 1) * ((srcLumaHeight + 1) >> 1)) << 10);
}
encIn->busChromaU = encIn->busLuma | ((srcHorStride * srcVerStride) << 10);
encIn->busChromaV = encIn->busLuma | ((srcHorStride * srcVerStride * 5 / 4) << 10);
/* Select frame type */
if (p->intraPicRate != 0 && (p->intraPeriodCnt >= p->intraPicRate)) {
@@ -287,6 +283,16 @@ MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param)
} else
mpp_err("width %d height %d is not available\n", mpp_cfg->width, mpp_cfg->height);
if (mpp_cfg->hor_stride && mpp_cfg->ver_stride) {
enc_cfg->hor_stride = mpp_cfg->hor_stride;
enc_cfg->ver_stride = mpp_cfg->ver_stride;
} else {
mpp_err("hor_stride %d ver_stride %d is invalid, use width and height",
mpp_cfg->hor_stride, mpp_cfg->ver_stride);
enc_cfg->hor_stride = enc_cfg->width;
enc_cfg->ver_stride = enc_cfg->height;
}
enc_cfg->input_image_format = mpp_cfg->format;
enc_cfg->frameRateNum = mpp_cfg->fps_in;
enc_cfg->frameRateDenom = 1;

View File

@@ -51,6 +51,8 @@ typedef struct h264e_syntax_t {
RK_U32 output_strm_addr; // outputStrmBase
RK_U32 pic_luma_width; // preProcess->lumWidth
RK_U32 pic_luma_height; // preProcess->lumHeight
RK_U32 pic_hor_stride; // preProcess->hor_stride
RK_U32 pic_ver_stride; // preProcess->ver_stride
RK_U32 input_luma_addr; // inputLumBase
RK_U32 input_cb_addr; // inputCbBase
RK_U32 input_cr_addr; // inputCrBase

View File

@@ -2796,10 +2796,12 @@ MPP_RET hal_h264e_rkv_deinit(void *hal)
}
MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_info, h264e_syntax *syn)
MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_info, h264e_syntax *syn, h264e_rkv_reg_set *regs)
{
h264e_rkv_ioctl_extra_info_elem *info = NULL;
RK_U32 frame_size = syn->pic_luma_width * syn->pic_luma_height; // TODO: according to yuv format
RK_U32 hor_stride = regs->swreg23.src_ystrid + 1;
RK_U32 ver_stride = syn->pic_ver_stride ? syn->pic_ver_stride : syn->pic_luma_height;
RK_U32 frame_size = hor_stride * ver_stride; // TODO: according to yuv format
extra_info->magic = 0;
extra_info->cnt = 2;
@@ -3131,6 +3133,9 @@ MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, Mp
for (k = 0; k < 40; k++)
regs->swreg22_h3d_tbl[k] = h264e_h3d_tbl[k];
if (syn->pic_hor_stride) {
stridey = syn->pic_hor_stride - 1;
} else {
stridey = (regs->swreg19.src_rot == 1 || regs->swreg19.src_rot == 3) ? (syn->pic_luma_height - 1) : (syn->pic_luma_width - 1);
if (regs->swreg14.src_cfmt == 0 )
stridey = (stridey + 1) * 4 - 1;
@@ -3138,6 +3143,7 @@ MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, Mp
stridey = (stridey + 1) * 3 - 1;
else if ( regs->swreg14.src_cfmt == 2 || regs->swreg14.src_cfmt == 8 || regs->swreg14.src_cfmt == 9 )
stridey = (stridey + 1) * 2 - 1;
}
stridec = (regs->swreg14.src_cfmt == 4 || regs->swreg14.src_cfmt == 6) ? stridey : ((stridey + 1) / 2 - 1);
regs->swreg23.src_ystrid = stridey; //syn->swreg23.src_ystrid;
regs->swreg23.src_cstrid = stridec; //syn->swreg23.src_cstrid; ////YUV420 planar;
@@ -3153,6 +3159,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
h264e_hal_context *ctx = (h264e_hal_context *)hal;
h264e_hal_param *par = &ctx->param;
h264e_rkv_reg_set *regs = NULL;
h264e_rkv_ioctl_reg_info *ioctl_reg_info = NULL;
h264e_hal_rkv_csp_info src_fmt;
h264e_syntax *syn = (h264e_syntax *)task->enc.syntax.data;
h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input;
@@ -3216,14 +3223,14 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
}
regs = &reg_list[idx];
ioctl_info->reg_info[idx].reg_num = sizeof(h264e_rkv_reg_set) / 4;
hal_h264e_rkv_set_ioctl_extra_info(&ioctl_info->reg_info[idx].extra_info, syn);
ioctl_reg_info = &ioctl_info->reg_info[idx];
} else {
ctx->num_frames_to_send = 1;
ioctl_info->frame_num = ctx->num_frames_to_send;
ioctl_info->enc_mode = ctx->enc_mode;
regs = &reg_list[0];
ioctl_info->reg_info[0].reg_num = sizeof(h264e_rkv_reg_set) / 4;
hal_h264e_rkv_set_ioctl_extra_info(&ioctl_info->reg_info[0].extra_info, syn);
ioctl_reg_info = &ioctl_info->reg_info[0];
}
if (MPP_OK != hal_h264e_rkv_reference_frame_set(ctx, syn)) {
@@ -3287,6 +3294,7 @@ MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task)
regs->swreg13.cime_dspw_orsd = 0x0;
hal_h264e_rkv_set_pp_regs(regs, syn, bufs->hw_pp_buf[buf2_idx], bufs->hw_pp_buf[1 - buf2_idx], ctx->frame_cnt, test_cfg);
hal_h264e_rkv_set_ioctl_extra_info(&ioctl_reg_info->extra_info, syn, regs);
regs->swreg24_adr_srcy = syn->input_luma_addr; //syn->addr_cfg.adr_srcy;
regs->swreg25_adr_srcu = syn->input_cb_addr; //syn->addr_cfg.adr_srcu;

View File

@@ -18,6 +18,7 @@
#include <string.h>
#include "vpu.h"
#include "rk_mpi.h"
#include "mpp_common.h"
#include "mpp_mem.h"
#include "mpp_frame.h"
#include "hal_h264e.h"
@@ -1768,6 +1769,10 @@ MPP_RET hal_h264e_vpu_deinit(void *hal)
static MPP_RET hal_h264e_vpu_validate_syntax(h264e_syntax *syn, h264e_hal_vpu_csp_info *src_fmt)
{
MPP_RET ret = MPP_OK;
RK_U32 width_align16 = MPP_ALIGN(syn->pic_luma_width, 16);
RK_U32 height_align16 = MPP_ALIGN(syn->pic_luma_height, 16);
h264e_hal_debug_enter();
/* validate */
@@ -1781,8 +1786,24 @@ static MPP_RET hal_h264e_vpu_validate_syntax(h264e_syntax *syn, h264e_hal_vpu_cs
H264E_HAL_VALIDATE_NEQ(syn->input_image_format, "input_image_format", H264E_VPU_CSP_NONE);
if (syn->pic_hor_stride != syn->pic_luma_width &&
syn->pic_hor_stride != width_align16) {
mpp_err_f("syn->pic_hor_stride %d is not supported for vpu", syn->pic_hor_stride);
ret = MPP_NOK;
goto err;
}
if (syn->pic_ver_stride != syn->pic_luma_height &&
syn->pic_ver_stride != height_align16) {
mpp_err_f("syn->pic_ver_stride %d is not supported for vpu", syn->pic_ver_stride);
ret = MPP_NOK;
goto err;
}
err:
h264e_hal_debug_leave();
return MPP_OK;
return ret;
}

View File

@@ -1313,8 +1313,8 @@ RK_S32 VpuApiLegacy::control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param)
} else if (ctx->videoCoding == OMX_RK_VIDEO_CodingVP9) {
p->ImgHorStride = MPP_ALIGN(ImgWidth, 128);
p->ImgVerStride = MPP_ALIGN(p->ImgHeight, 64);
} else if (ctx->videoCoding == OMX_RK_VIDEO_CodingAVC
&& (p->ImgWidth > 1920 || p->ImgHeight > 1088)) {
} else if (ctx->videoCoding == OMX_RK_VIDEO_CodingAVC &&
(p->ImgWidth > 1920 || p->ImgHeight > 1088)) {
p->ImgHorStride = hevc_hor_align_256_odd(ImgWidth);
p->ImgVerStride = default_align_16(p->ImgHeight);
} else {

View File

@@ -36,6 +36,7 @@
#define MAX_FILE_NAME_LENGTH 256
#define MPI_ENC_TEST_SET_IDR_FRAME 0
#define MPI_ENC_TEST_SET_OSD 0
typedef struct {
char file_input[MAX_FILE_NAME_LENGTH];
@@ -62,6 +63,79 @@ static OptionInfo mpi_enc_cmd[] = {
{"d", "debug", "debug flag"},
};
static MPP_RET read_yuv_image(RK_U8 *buf, MppEncConfig *mpp_cfg, FILE *fp)
{
MPP_RET ret = MPP_OK;
RK_U32 read_size;
RK_U32 row = 0;
RK_U32 width = mpp_cfg->width;
RK_U32 height = mpp_cfg->height;
RK_U32 hor_stride = mpp_cfg->hor_stride;
RK_U32 ver_stride = mpp_cfg->ver_stride;
MppFrameFormat fmt = mpp_cfg->format;
RK_U8 *buf_y = buf;
RK_U8 *buf_u = buf_y + hor_stride * ver_stride; // NOTE: diff from gen_yuv_image
RK_U8 *buf_v = buf_u + hor_stride * ver_stride / 4; // NOTE: diff from gen_yuv_image
switch (fmt) {
case MPP_FMT_YUV420SP : {
for (row = 0; row < height; row++) {
read_size = fread(buf_y + row * hor_stride, 1, width, fp);
if (read_size != width) {
mpp_err_f("read ori yuv file luma failed");
ret = MPP_NOK;
goto err;
}
}
for (row = 0; row < height / 2; row++) {
read_size = fread(buf_u + row * hor_stride, 1, width, fp);
if (read_size != width) {
mpp_err_f("read ori yuv file cb failed");
ret = MPP_NOK;
goto err;
}
}
} break;
case MPP_FMT_YUV420P : {
for (row = 0; row < height; row++) {
read_size = fread(buf_y + row * hor_stride, 1, width, fp);
if (read_size != width) {
mpp_err_f("read ori yuv file luma failed");
ret = MPP_NOK;
goto err;
}
}
for (row = 0; row < height / 2; row++) {
read_size = fread(buf_u + row * hor_stride / 2, 1, width / 2, fp);
if (read_size != width / 2) {
mpp_err_f("read ori yuv file cb failed");
ret = MPP_NOK;
goto err;
}
}
for (row = 0; row < height / 2; row++) {
read_size = fread(buf_v + row * hor_stride / 2, 1, width / 2, fp);
if (read_size != width / 2) {
mpp_err_f("read ori yuv file cr failed");
ret = MPP_NOK;
goto err;
}
}
} break;
default : {
mpp_err_f("read image do not support fmt %d\n", fmt);
ret = MPP_NOK;
} break;
}
err:
return ret;
}
static MPP_RET fill_yuv_image(RK_U8 *buf, MppEncConfig *mpp_cfg, RK_U32 frame_count)
{
MPP_RET ret = MPP_OK;
@@ -201,7 +275,6 @@ int mpi_enc_test(MpiEncTestCmd *cmd)
size_t mdinfo_size = (((hor_stride + 255) & (~255)) / 16) * (ver_stride / 16) * 4; //NOTE: hor_stride should be 16-MB aligned
/* 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 = hor_stride * ver_stride / 8;
size_t read_size = 0;
RK_U32 frame_count = 0;
RK_U64 stream_size = 0;
RK_U32 plt_table[8] = {
@@ -349,11 +422,13 @@ int mpi_enc_test(MpiEncTestCmd *cmd)
/* gen and cfg osd plt */
mpi_enc_gen_osd_plt(&osd_plt, plt_table);
#if MPI_ENC_TEST_SET_OSD
ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &osd_plt);
if (MPP_OK != ret) {
mpp_err("mpi control enc set osd plt failed\n");
goto MPP_TEST_OUT;
}
#endif
i = 0;
while (!pkt_eos) {
@@ -370,9 +445,9 @@ int mpi_enc_test(MpiEncTestCmd *cmd)
i = 0;
if (fp_input) {
read_size = fread(buf, 1, frame_size, fp_input);
if (read_size != frame_size || feof(fp_input)) {
mpp_log("found last frame\n");
ret = read_yuv_image(buf, &mpp_cfg, fp_input);
if (ret != MPP_OK || feof(fp_input)) {
mpp_log("found last frame. feof %d\n", feof(fp_input));
frm_eos = 1;
}
} else {
@@ -424,11 +499,13 @@ int mpi_enc_test(MpiEncTestCmd *cmd)
/* gen and cfg osd plt */
mpi_enc_gen_osd_data(&osd_data, osd_data_buf, frame_count);
#if MPI_ENC_TEST_SET_OSD
ret = mpi->control(ctx, MPP_ENC_SET_OSD_DATA_CFG, &osd_data);
if (MPP_OK != ret) {
mpp_err("mpi control enc set osd data failed\n");
goto MPP_TEST_OUT;
}
#endif
ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task);
if (ret) {