mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-07 01:52:46 +08:00
[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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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 = ®_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 = ®_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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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 {
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user