new/external/rockit/mpi/example/mod/test_mpi_vi.cpp

1535 lines
58 KiB
C++
Raw Permalink Normal View History

2025-05-10 21:58:58 +08:00
/*
* Copyright 2020 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.
*
*/
#include <stdio.h>
#include <sys/poll.h>
#include <errno.h>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <pthread.h>
#include "rk_defines.h"
#include "rk_debug.h"
#include "rk_mpi_vi.h"
#include "rk_mpi_mb.h"
#include "rk_mpi_sys.h"
#include "rk_mpi_venc.h"
#include "rk_mpi_vpss.h"
#include "rk_mpi_vo.h"
#include "rk_mpi_rgn.h"
#include "rk_common.h"
#include "rk_comm_rgn.h"
#include "rk_comm_vi.h"
#include "rk_comm_vo.h"
#include "test_common.h"
#include "test_comm_utils.h"
#include "test_comm_argparse.h"
#include "rk_mpi_cal.h"
#include "rk_mpi_mmz.h"
#define TEST_VENC_MAX 2
#define TEST_WITH_FD 0
#define TEST_WITH_FD_SWITCH 0
#undef DBG_MOD_ID
#define DBG_MOD_ID RK_ID_VI
// for 356x vo
#define RK356X_VO_DEV_HD0 0
#define RK356X_VO_DEV_HD1 1
#define RK356X_VOP_LAYER_CLUSTER_0 0
#define RK356X_VOP_LAYER_CLUSTER_1 2
#define RK356X_VOP_LAYER_ESMART_0 4
#define RK356X_VOP_LAYER_ESMART_1 5
#define RK356X_VOP_LAYER_SMART_0 6
#define RK356X_VOP_LAYER_SMART_1 7
#define TEST_VI_SENSOR_NUM 6
typedef struct _rkTestVencCfg {
RK_BOOL bOutDebugCfg;
VENC_CHN_ATTR_S stAttr;
RK_CHAR dstFilePath[128];
RK_CHAR dstFileName[128];
RK_S32 s32ChnId;
FILE *fp;
RK_S32 selectFd;
} TEST_VENC_CFG;
typedef struct rkVPSS_CFG_S {
const char *dstFilePath;
RK_S32 s32DevId;
RK_S32 s32ChnId;
RK_U32 u32VpssChnCnt;
VPSS_GRP_ATTR_S stGrpVpssAttr;
VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_CHN_NUM];
} VPSS_CFG_S;
typedef struct rkRGN_CFG_S {
RGN_ATTR_S stRgnAttr;
RGN_CHN_ATTR_S stRgnChnAttr;
} RGN_CFG_S;
typedef enum rkTestVIMODE_E {
TEST_VI_MODE_VI_ONLY = 0,
TEST_VI_MODE_BIND_VENC = 1,
TEST_VI_MODE_BIND_VENC_MULTI = 2,
TEST_VI_MODE_BIND_VPSS_BIND_VENC = 3,
TEST_VI_MODE_BIND_VO = 4,
TEST_VI_MODE_MUTI_VI = 5,
} TEST_VI_MODE_E;
typedef struct _rkMpiVICtx {
RK_S32 width;
RK_S32 height;
RK_S32 devId;
RK_S32 pipeId;
RK_S32 channelId;
RK_S32 loopCountSet;
RK_S32 selectFd;
RK_BOOL bFreeze;
RK_BOOL bEnRgn;
RK_S32 s32RgnCnt;
RK_S32 rgnType;
RK_BOOL bUserPicEnabled;
RK_BOOL bGetConnecInfo;
RK_BOOL bGetEdid;
RK_BOOL bSetEdid;
COMPRESS_MODE_E enCompressMode;
VI_DEV_ATTR_S stDevAttr;
VI_DEV_BIND_PIPE_S stBindPipe;
VI_CHN_ATTR_S stChnAttr;
VI_SAVE_FILE_INFO_S stDebugFile;
VIDEO_FRAME_INFO_S stViFrame;
VI_CHN_STATUS_S stChnStatus;
VI_USERPIC_ATTR_S stUsrPic;
TEST_VI_MODE_E enMode;
const char *aEntityName;
// for vi
RGN_CFG_S stViRgn;
// for venc
TEST_VENC_CFG stVencCfg[TEST_VENC_MAX];
VENC_STREAM_S stFrame[TEST_VENC_MAX];
VPSS_CFG_S stVpssCfg;
// for vo
VO_LAYER s32VoLayer;
VO_DEV s32VoDev;
} TEST_VI_CTX_S;
RK_U8 test_edid[2][128] = {
{
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x49, 0x70, 0x88, 0x35, 0x01, 0x00, 0x00, 0x00,
0x2d, 0x1f, 0x01, 0x03, 0x80, 0x78, 0x44, 0x78, 0x0a, 0xcf, 0x74, 0xa3, 0x57, 0x4c, 0xb0, 0x23,
0x09, 0x48, 0x4c, 0x21, 0x08, 0x00, 0x61, 0x40, 0x01, 0x01, 0x81, 0x00, 0x95, 0x00, 0xa9, 0xc0,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0xe8, 0x00, 0x30, 0xf2, 0x70, 0x5a, 0x80, 0xb0, 0x58,
0x8a, 0x00, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40,
0x58, 0x2c, 0x45, 0x00, 0xb9, 0xa8, 0x42, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x52,
0x4b, 0x2d, 0x55, 0x48, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd,
0x00, 0x3b, 0x46, 0x1f, 0x8c, 0x3c, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xa3
},
{
0x02, 0x03, 0x39, 0xd2, 0x51, 0x07, 0x16, 0x14, 0x05, 0x01, 0x03, 0x12, 0x13, 0x84, 0x22, 0x1f,
0x90, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x66, 0x03,
0x0c, 0x00, 0x30, 0x00, 0x10, 0x67, 0xd8, 0x5d, 0xc4, 0x01, 0x78, 0xc8, 0x07, 0xe3, 0x05, 0x03,
0x01, 0xe4, 0x0f, 0x00, 0xf0, 0x01, 0xe2, 0x00, 0xff, 0x08, 0xe8, 0x00, 0x30, 0xf2, 0x70, 0x5a,
0x80, 0xb0, 0x58, 0x8a, 0x00, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, 0x02, 0x3a, 0x80, 0x18, 0x71,
0x38, 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0xb9, 0xa8, 0x42, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1
}
};
static RK_S32 create_vpss(VPSS_CFG_S *pstVpssCfg, RK_S32 s32Grp, RK_S32 s32OutChnNum) {
RK_S32 s32Ret = RK_SUCCESS;
VPSS_CHN VpssChn[VPSS_MAX_CHN_NUM] = { VPSS_CHN0, VPSS_CHN1, VPSS_CHN2, VPSS_CHN3 };
VPSS_CROP_INFO_S stCropInfo;
s32Ret = RK_MPI_VPSS_CreateGrp(s32Grp, &pstVpssCfg->stGrpVpssAttr);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
for (RK_S32 i = 0; i < s32OutChnNum; i++) {
s32Ret = RK_MPI_VPSS_SetChnAttr(s32Grp, VpssChn[i], &pstVpssCfg->stVpssChnAttr[i]);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
s32Ret = RK_MPI_VPSS_EnableChn(s32Grp, VpssChn[i]);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
}
s32Ret = RK_MPI_VPSS_EnableBackupFrame(s32Grp);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
s32Ret = RK_MPI_VPSS_StartGrp(s32Grp);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
return RK_SUCCESS;
}
static RK_S32 destory_vpss(RK_S32 s32Grp, RK_S32 s32OutChnNum) {
RK_S32 s32Ret = RK_SUCCESS;
VPSS_CHN VpssChn[VPSS_MAX_CHN_NUM] = { VPSS_CHN0, VPSS_CHN1, VPSS_CHN2, VPSS_CHN3 };
s32Ret = RK_MPI_VPSS_StopGrp(s32Grp);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
for (RK_S32 i = 0; i < s32OutChnNum; i++) {
s32Ret = RK_MPI_VPSS_DisableChn(s32Grp, VpssChn[i]);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
}
s32Ret = RK_MPI_VPSS_DisableBackupFrame(s32Grp);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
s32Ret = RK_MPI_VPSS_DestroyGrp(s32Grp);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
return RK_SUCCESS;
}
static RK_S32 create_venc(TEST_VI_CTX_S *ctx, RK_U32 u32Ch) {
VENC_RECV_PIC_PARAM_S stRecvParam;
stRecvParam.s32RecvPicNum = ctx->loopCountSet;
RK_MPI_VENC_CreateChn(u32Ch, &ctx->stVencCfg[u32Ch].stAttr);
RK_MPI_VENC_StartRecvFrame(u32Ch, &stRecvParam);
return RK_SUCCESS;
}
void init_venc_cfg(TEST_VI_CTX_S *ctx, RK_U32 u32Ch, RK_CODEC_ID_E enType) {
ctx->stVencCfg[u32Ch].stAttr.stVencAttr.enType = enType;
ctx->stVencCfg[u32Ch].s32ChnId = u32Ch;
ctx->stVencCfg[u32Ch].stAttr.stVencAttr.enPixelFormat = ctx->stChnAttr.enPixelFormat;
ctx->stVencCfg[u32Ch].stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
ctx->stVencCfg[u32Ch].stAttr.stRcAttr.stH264Cbr.u32Gop = 60;
ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32PicWidth = ctx->width;
ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32PicHeight = ctx->height;
ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32VirWidth = ctx->width;
ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32VirHeight = ctx->height;
ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32StreamBufCnt = 5;
ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32BufSize = ctx->width * ctx->height * 3 / 2;
}
static RK_S32 create_vo(TEST_VI_CTX_S *ctx, RK_U32 u32Ch) {
/* Enable VO */
VO_PUB_ATTR_S VoPubAttr;
VO_VIDEO_LAYER_ATTR_S stLayerAttr;
RK_S32 s32Ret = RK_SUCCESS;
VO_CHN_ATTR_S stChnAttr;
VO_LAYER VoLayer = ctx->s32VoLayer;
VO_DEV VoDev = ctx->s32VoDev;
RK_MPI_VO_DisableLayer(VoLayer);
RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_ESMART_0);
RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_ESMART_1);
RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_SMART_0);
RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_SMART_1);
RK_MPI_VO_Disable(VoDev);
memset(&VoPubAttr, 0, sizeof(VO_PUB_ATTR_S));
memset(&stLayerAttr, 0, sizeof(VO_VIDEO_LAYER_ATTR_S));
stLayerAttr.enPixFormat = RK_FMT_RGB888;
stLayerAttr.stDispRect.s32X = 0;
stLayerAttr.stDispRect.s32Y = 0;
stLayerAttr.u32DispFrmRt = 30;
stLayerAttr.stDispRect.u32Width = 1920;
stLayerAttr.stDispRect.u32Height = 1080;
stLayerAttr.stImageSize.u32Width = 1920;
stLayerAttr.stImageSize.u32Height = 1080;
s32Ret = RK_MPI_VO_GetPubAttr(VoDev, &VoPubAttr);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
VoPubAttr.enIntfType = VO_INTF_HDMI;
VoPubAttr.enIntfSync = VO_OUTPUT_DEFAULT;
s32Ret = RK_MPI_VO_SetPubAttr(VoDev, &VoPubAttr);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
s32Ret = RK_MPI_VO_Enable(VoDev);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
s32Ret = RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_GRAPHIC);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VO_BindLayer failed,s32Ret:%d\n", s32Ret);
return RK_FAILURE;
}
s32Ret = RK_MPI_VO_SetLayerAttr(VoLayer, &stLayerAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VO_SetLayerAttr failed,s32Ret:%d\n", s32Ret);
return RK_FAILURE;
}
s32Ret = RK_MPI_VO_EnableLayer(VoLayer);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VO_EnableLayer failed,s32Ret:%d\n", s32Ret);
return RK_FAILURE;
}
stChnAttr.stRect.s32X = 0;
stChnAttr.stRect.s32Y = 0;
stChnAttr.stRect.u32Width = stLayerAttr.stImageSize.u32Width;
stChnAttr.stRect.u32Height = stLayerAttr.stImageSize.u32Height;
stChnAttr.u32Priority = 0;
stChnAttr.u32FgAlpha = 128;
stChnAttr.u32BgAlpha = 0;
s32Ret = RK_MPI_VO_SetChnAttr(VoLayer, u32Ch, &stChnAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("set chn Attr failed,s32Ret:%d\n", s32Ret);
return RK_FAILURE;
}
return s32Ret;
}
RK_S32 test_vi_poll_event(RK_S32 timeoutMsec, RK_S32 fd) {
RK_S32 num_fds = 1;
struct pollfd pollFds[num_fds];
RK_S32 ret = 0;
RK_ASSERT(fd > 0);
memset(pollFds, 0, sizeof(pollFds));
pollFds[0].fd = fd;
pollFds[0].events = (POLLPRI | POLLIN | POLLERR | POLLNVAL | POLLHUP);
ret = poll(pollFds, num_fds, timeoutMsec);
if (ret > 0 && (pollFds[0].revents & (POLLERR | POLLNVAL | POLLHUP))) {
RK_LOGE("fd:%d polled error", fd);
return -1;
}
return ret;
}
static RK_S32 readFromPic(TEST_VI_CTX_S *ctx, VIDEO_FRAME_S *buffer) {
FILE *fp = NULL;
RK_S32 s32Ret = RK_SUCCESS;
MB_BLK srcBlk = MB_INVALID_HANDLE;
PIC_BUF_ATTR_S stPicBufAttr;
MB_PIC_CAL_S stMbPicCalResult;
const char *user_picture_path = "/data/test_vi_user.yuv";
stPicBufAttr.u32Width = ctx->width;
stPicBufAttr.u32Height = ctx->height;
stPicBufAttr.enCompMode = COMPRESS_MODE_NONE;
stPicBufAttr.enPixelFormat = RK_FMT_YUV420SP;
s32Ret = RK_MPI_CAL_VGS_GetPicBufferSize(&stPicBufAttr, &stMbPicCalResult);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("get picture buffer size failed. err 0x%x", s32Ret);
return RK_NULL;
}
RK_MPI_MMZ_Alloc(&srcBlk, stMbPicCalResult.u32MBSize, RK_MMZ_ALLOC_CACHEABLE);
fp = fopen(user_picture_path, "rb");
if (NULL == fp) {
RK_LOGE("open %s fail", user_picture_path);
return RK_FAILURE;
} else {
fread(RK_MPI_MB_Handle2VirAddr(srcBlk), 1 , stMbPicCalResult.u32MBSize, fp);
fclose(fp);
RK_MPI_SYS_MmzFlushCache(srcBlk, RK_FALSE);
RK_LOGD("open %s success", user_picture_path);
}
buffer->u32Width = ctx->width;
buffer->u32Height = ctx->height;
buffer->u32VirWidth = ctx->width;
buffer->u32VirHeight = ctx->height;
buffer->enPixelFormat = RK_FMT_YUV420SP;
buffer->u32TimeRef = 0;
buffer->u64PTS = 0;
buffer->enCompressMode = COMPRESS_MODE_NONE;
buffer->pMbBlk = srcBlk;
RK_LOGD("readFromPic width = %d, height = %d size = %d pixFormat = %d",
ctx->width, ctx->height, stMbPicCalResult.u32MBSize, RK_FMT_YUV420SP);
return RK_SUCCESS;
}
static RK_S32 create_rgn(TEST_VI_CTX_S *ctx) {
RK_S32 i;
RK_S32 s32Ret = RK_SUCCESS;
RGN_ATTR_S stRgnAttr;
RGN_CHN_ATTR_S stRgnChnAttr;
RGN_HANDLE RgnHandle = 0;
MPP_CHN_S stMppChn;
RGN_TYPE_E rgnType = (RGN_TYPE_E)ctx->rgnType;
/****************************************
step 1: create overlay regions
****************************************/
for (i = 0; i < ctx->s32RgnCnt; i++) {
ctx->stViRgn.stRgnAttr.unAttr.stOverlay.u32ClutNum = 0;
ctx->stViRgn.stRgnAttr.unAttr.stOverlay.stSize.u32Width = 128;
ctx->stViRgn.stRgnAttr.unAttr.stOverlay.stSize.u32Height = 128;
RgnHandle = i;
s32Ret = RK_MPI_RGN_Create(RgnHandle, &ctx->stViRgn.stRgnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("RK_MPI_RGN_Create (%d) failed with %#x!", RgnHandle, s32Ret);
RK_MPI_RGN_Destroy(RgnHandle);
return RK_FAILURE;
}
RK_LOGI("The handle: %d, create success!", RgnHandle);
}
/*********************************************
step 2: display overlay regions to vi
*********************************************/
for (i = 0; i < ctx->s32RgnCnt; i++) {
stMppChn.enModId = RK_ID_VI;
stMppChn.s32DevId = ctx->devId;
stMppChn.s32ChnId = ctx->channelId;
RgnHandle = i;
memset(&stRgnChnAttr, 0, sizeof(stRgnChnAttr));
stRgnChnAttr.bShow = RK_TRUE;
stRgnChnAttr.enType = rgnType;
BITMAP_S stBitmap;
switch (rgnType) {
case COVER_RGN: {
RGN_CHN_ATTR_S stCoverChnAttr;
stCoverChnAttr.bShow = RK_TRUE;
stCoverChnAttr.enType = COVER_RGN;
stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32X = 128 * i;
stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32Y = 128 * i;
stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Width = 128;
stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Height = 128;
stCoverChnAttr.unChnAttr.stCoverChn.u32Color = 0xffffff; // white
stCoverChnAttr.unChnAttr.stCoverChn.enCoordinate = RGN_ABS_COOR;
stCoverChnAttr.unChnAttr.stCoverChn.u32Layer = i;
s32Ret = RK_MPI_RGN_AttachToChn(RgnHandle, &stMppChn, &stCoverChnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("failed with %#x!", s32Ret);
goto __EXIT;
}
s32Ret = RK_MPI_RGN_GetDisplayAttr(RgnHandle, &stMppChn, &stCoverChnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("failed with %#x!", s32Ret);
goto __EXIT;
}
stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32X = 128 * i;
stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32Y = 128 * i;
stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Width = 128;
stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Height = 128;
stCoverChnAttr.unChnAttr.stCoverChn.u32Color = 0x0000ff; // blue
stCoverChnAttr.unChnAttr.stCoverChn.enCoordinate = RGN_ABS_COOR;
stCoverChnAttr.unChnAttr.stCoverChn.u32Layer = i;
// change cover channel attribute below.
s32Ret = RK_MPI_RGN_SetDisplayAttr(RgnHandle, &stMppChn, &stCoverChnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("failed with %#x!", s32Ret);
goto __EXIT;
}
RK_LOGI("the cover region:%d to <%d, %d, %d, %d>",
RgnHandle,
stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32X,
stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32Y,
stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Width,
stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Height);
} break;
case MOSAIC_RGN: {
RGN_CHN_ATTR_S stMoscaiChnAttr;
stMoscaiChnAttr.bShow = RK_TRUE;
stMoscaiChnAttr.enType = MOSAIC_RGN;
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32X = 128 * i;
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32Y = 128 * i;
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Width = 128;
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Height = 128;
stMoscaiChnAttr.unChnAttr.stMosaicChn.enBlkSize = MOSAIC_BLK_SIZE_8;
stMoscaiChnAttr.unChnAttr.stMosaicChn.u32Layer = i;
s32Ret = RK_MPI_RGN_AttachToChn(RgnHandle, &stMppChn, &stMoscaiChnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("failed with %#x!", s32Ret);
goto __EXIT;
}
s32Ret = RK_MPI_RGN_GetDisplayAttr(RgnHandle, &stMppChn, &stMoscaiChnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("failed with %#x!", s32Ret);
goto __EXIT;
}
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32X = 128 * i;
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32Y = 128 * i;
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Width = 128;
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Height = 128;
stMoscaiChnAttr.unChnAttr.stMosaicChn.enBlkSize = MOSAIC_BLK_SIZE_8;
stMoscaiChnAttr.unChnAttr.stMosaicChn.u32Layer = i;
// change mosaic channel attribute below.
s32Ret = RK_MPI_RGN_SetDisplayAttr(RgnHandle, &stMppChn, &stMoscaiChnAttr);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("failed with %#x!", s32Ret);
goto __EXIT;
}
RK_LOGI("the mosaic region:%d to <%d, %d, %d, %d>",
RgnHandle,
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32X,
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32Y,
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Width,
stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Height);
} break;
default:
break;
}
}
return RK_SUCCESS;
__EXIT:
for (i = 0; i < ctx->s32RgnCnt; i++) {
stMppChn.enModId = RK_ID_VI;
stMppChn.s32DevId = ctx->devId;
stMppChn.s32ChnId = ctx->channelId;
RgnHandle = i;
s32Ret = RK_MPI_RGN_DetachFromChn(RgnHandle, &stMppChn);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("RK_MPI_RGN_DetachFrmChn (%d) failed with %#x!", RgnHandle, s32Ret);
return RK_FAILURE;
}
}
return RK_FAILURE;
}
static RK_S32 destory_rgn(TEST_VI_CTX_S *ctx) {
RK_S32 i;
RK_S32 s32Ret = RK_SUCCESS;
RGN_HANDLE RgnHandle = 0;
for (RK_S32 i = 0; i < ctx->s32RgnCnt; i++) {
RgnHandle = i;
s32Ret = RK_MPI_RGN_Destroy(RgnHandle);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("RK_MPI_RGN_Destroy (%d) failed with %#x!", RgnHandle, s32Ret);
}
RK_LOGI("Destory handle:%d success", RgnHandle);
}
RK_LOGD("vi RK_MPI_RGN_Destroy OK");
return RK_SUCCESS;
}
static RK_S32 test_vi_hdmi_rx_infomation(TEST_VI_CTX_S *ctx) {
RK_S32 s32Ret = RK_FAILURE;
/* test get connect info before enable chn(need after RK_MPI_VI_SetChnAttr)*/
if (ctx->bGetConnecInfo) {
VI_CONNECT_INFO_S stConnectInfo;
s32Ret = RK_MPI_VI_GetChnConnectInfo(ctx->pipeId, ctx->channelId, &stConnectInfo);
RK_LOGE("RK_MPI_VI_GetChnConnectInfo %x, w:%d,h:%d,fmt:0x%x,connect:%d", s32Ret,
stConnectInfo.u32Width, stConnectInfo.u32Height,
stConnectInfo.enPixFmt, stConnectInfo.enConnect);
}
if (ctx->bGetEdid) {
VI_EDID_S stEdid;
memset(&stEdid, 0, sizeof(VI_EDID_S));
stEdid.u32Blocks = 3;
stEdid.pu8Edid = (RK_U8 *)calloc(128 * stEdid.u32Blocks, 1);
s32Ret = RK_MPI_VI_GetChnEdid(ctx->pipeId, ctx->channelId, &stEdid);
RK_LOGE("RK_MPI_VI_GetChnEdid %x, stEdid.u32Blocks=%d "
"edid[0]:0x%x,edid[1]:0x%x,edid[2]:0x%x,edid[3]:0x%x,edid[126]:0x%x edid[127]:0x%x",
s32Ret, stEdid.u32Blocks,
stEdid.pu8Edid[0], stEdid.pu8Edid[1],
stEdid.pu8Edid[2], stEdid.pu8Edid[3],
stEdid.pu8Edid[126], stEdid.pu8Edid[127]);
free(stEdid.pu8Edid);
}
if (ctx->bSetEdid) {
VI_EDID_S stEdid;
memset(&stEdid, 0, sizeof(VI_EDID_S));
stEdid.u32Blocks = 2;
stEdid.pu8Edid = (RK_U8 *)test_edid;
s32Ret = RK_MPI_VI_SetChnEdid(ctx->pipeId, ctx->channelId, &stEdid);
RK_LOGE("RK_MPI_VI_SetChnEdid %x, edid[0]:0x%x,edid[1]:0x%x,edid[2]:0x%x,edid[3]:0x%x,"
"edid[126]:0x%x edid[127]:0x%x",
s32Ret,
stEdid.pu8Edid[0], stEdid.pu8Edid[1],
stEdid.pu8Edid[2], stEdid.pu8Edid[3],
stEdid.pu8Edid[126], stEdid.pu8Edid[127]);
}
return s32Ret;
}
static RK_S32 test_vi_init(TEST_VI_CTX_S *ctx) {
RK_S32 s32Ret = RK_FAILURE;
// 0. get dev config status
s32Ret = RK_MPI_VI_GetDevAttr(ctx->devId, &ctx->stDevAttr);
if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
// 0-1.config dev
s32Ret = RK_MPI_VI_SetDevAttr(ctx->devId, &ctx->stDevAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_SetDevAttr %x", s32Ret);
goto __FAILED;
}
} else {
RK_LOGE("RK_MPI_VI_SetDevAttr already");
}
// 1.get dev enable status
s32Ret = RK_MPI_VI_GetDevIsEnable(ctx->devId);
if (s32Ret != RK_SUCCESS) {
// 1-2.enable dev
s32Ret = RK_MPI_VI_EnableDev(ctx->devId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_EnableDev %x", s32Ret);
goto __FAILED;
}
// 1-3.bind dev/pipe
ctx->stBindPipe.u32Num = ctx->pipeId;
ctx->stBindPipe.PipeId[0] = ctx->pipeId;
s32Ret = RK_MPI_VI_SetDevBindPipe(ctx->devId, &ctx->stBindPipe);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_SetDevBindPipe %x", s32Ret);
goto __FAILED;
}
} else {
RK_LOGE("RK_MPI_VI_EnableDev already");
}
// 2.config channel
ctx->stChnAttr.stSize.u32Width = ctx->width;
ctx->stChnAttr.stSize.u32Height = ctx->height;
ctx->stChnAttr.enCompressMode = ctx->enCompressMode;
s32Ret = RK_MPI_VI_SetChnAttr(ctx->pipeId, ctx->channelId, &ctx->stChnAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_SetChnAttr %x", s32Ret);
goto __FAILED;
}
/* test user picture */
if (ctx->bUserPicEnabled) {
ctx->stUsrPic.enUsrPicMode = VI_USERPIC_MODE_BGC;
// ctx->stUsrPic.enUsrPicMode = VI_USERPIC_MODE_PIC;
if (ctx->stUsrPic.enUsrPicMode == VI_USERPIC_MODE_PIC) {
s32Ret = readFromPic(ctx, &ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_SetUserPic fail:%x", s32Ret);
goto __FAILED;
}
} else if (ctx->stUsrPic.enUsrPicMode == VI_USERPIC_MODE_BGC) {
/* set background color */
ctx->stUsrPic.unUsrPic.stUsrPicBg.u32BgColor = RGB(0, 0, 128);
}
s32Ret = RK_MPI_VI_SetUserPic(ctx->pipeId, ctx->channelId, &ctx->stUsrPic);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_SetUserPic fail:%x", s32Ret);
goto __FAILED;
}
s32Ret = RK_MPI_VI_EnableUserPic(ctx->pipeId, ctx->channelId);
}
test_vi_hdmi_rx_infomation(ctx);
ctx->stViRgn.stRgnAttr.enType = (RGN_TYPE_E)ctx->rgnType;
ctx->stViRgn.stRgnChnAttr.bShow = RK_TRUE;
// open fd before enable chn will be better
#if TEST_WITH_FD
ctx->selectFd = RK_MPI_VI_GetChnFd(ctx->pipeId, ctx->channelId);
RK_LOGE("ctx->pipeId=%d, ctx->channelId=%d, ctx->selectFd:%d ", ctx->pipeId, ctx->channelId, ctx->selectFd);
#endif
// 3.enable channel
s32Ret = RK_MPI_VI_EnableChn(ctx->pipeId, ctx->channelId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_EnableChn %x", s32Ret);
goto __FAILED;
}
if (ctx->bEnRgn) {
s32Ret = create_rgn(ctx);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("Error:create rgn failed!");
goto __FAILED;
}
}
// 4.save debug file
if (ctx->stDebugFile.bCfg) {
s32Ret = RK_MPI_VI_ChnSaveFile(ctx->pipeId, ctx->channelId, &ctx->stDebugFile);
RK_LOGD("RK_MPI_VI_ChnSaveFile %x", s32Ret);
}
__FAILED:
return s32Ret;
}
static RK_S32 test_vi_bind_vo_loop(TEST_VI_CTX_S *ctx) {
MPP_CHN_S stSrcChn, stDestChn;
RK_S32 loopCount = 0;
void *pData = RK_NULL;
RK_S32 s32Ret = RK_FAILURE;
RK_U32 i;
s32Ret = test_vi_init(ctx);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi %d:%d init failed:%x", ctx->devId, ctx->channelId, s32Ret);
goto __FAILED;
}
// vo init and create
ctx->s32VoLayer = RK356X_VOP_LAYER_CLUSTER_0;
ctx->s32VoDev = RK356X_VO_DEV_HD0;
s32Ret = create_vo(ctx, 0);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("create vo ch:%d failed", ctx->channelId);
goto __FAILED;
}
// bind vi to vo
stSrcChn.enModId = RK_ID_VI;
stSrcChn.s32DevId = ctx->devId;
stSrcChn.s32ChnId = ctx->channelId;
stDestChn.enModId = RK_ID_VO;
stDestChn.s32DevId = ctx->s32VoLayer;
stDestChn.s32ChnId = 0;
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi band vo fail:%x", s32Ret);
goto __FAILED;
}
// enable vo
s32Ret = RK_MPI_VO_EnableChn(ctx->s32VoLayer, 0);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("Enalbe vo chn failed, s32Ret = %d\n", s32Ret);
goto __FAILED;
}
while (loopCount < ctx->loopCountSet) {
loopCount++;
//RK_LOGE("loopCount:%d", loopCount);
// can not get the vo frameout count . so here regard as 33ms one frame.
usleep(33*1000);
}
__FAILED:
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
}
// disable vo
RK_MPI_VO_DisableLayer(ctx->s32VoLayer);
RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_ESMART_0);
RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_ESMART_1);
RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_SMART_0);
RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_SMART_1);
RK_MPI_VO_DisableChn(ctx->s32VoLayer, 0);
RK_MPI_VO_Disable(ctx->s32VoDev);
// 5. disable one chn
s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
RK_MPI_VO_DisableChn(ctx->s32VoLayer, 0);
// 6.disable dev(will diabled all chn)
s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
return s32Ret;
}
static RK_S32 test_vi_bind_vpss_venc_loop(TEST_VI_CTX_S *ctx) {
MPP_CHN_S stViChn, stVencChn[TEST_VENC_MAX], stVpssChn;
RK_S32 loopCount = 0;
void *pData = RK_NULL;
RK_S32 s32Ret = RK_FAILURE;
RK_U32 i;
RK_U32 u32DstCount = 1;
s32Ret = test_vi_init(ctx);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi %d:%d init failed:%x", ctx->devId, ctx->channelId, s32Ret);
goto __FAILED;
}
/* vpss */
ctx->stVpssCfg.u32VpssChnCnt = 1;
ctx->stVpssCfg.stGrpVpssAttr.u32MaxW = 4096;
ctx->stVpssCfg.stGrpVpssAttr.u32MaxH = 4096;
ctx->stVpssCfg.stGrpVpssAttr.enPixelFormat = RK_FMT_YUV420SP;
ctx->stVpssCfg.stGrpVpssAttr.stFrameRate.s32SrcFrameRate = -1;
ctx->stVpssCfg.stGrpVpssAttr.stFrameRate.s32DstFrameRate = -1;
ctx->stVpssCfg.stGrpVpssAttr.enCompressMode = COMPRESS_MODE_NONE;
for (i = 0; i < VPSS_MAX_CHN_NUM; i ++) {
ctx->stVpssCfg.stVpssChnAttr[i].enChnMode = VPSS_CHN_MODE_PASSTHROUGH;
ctx->stVpssCfg.stVpssChnAttr[i].enDynamicRange = DYNAMIC_RANGE_SDR8;
ctx->stVpssCfg.stVpssChnAttr[i].enPixelFormat = RK_FMT_YUV420SP;
ctx->stVpssCfg.stVpssChnAttr[i].stFrameRate.s32SrcFrameRate = -1;
ctx->stVpssCfg.stVpssChnAttr[i].stFrameRate.s32DstFrameRate = -1;
ctx->stVpssCfg.stVpssChnAttr[i].u32Width = ctx->width;
ctx->stVpssCfg.stVpssChnAttr[i].u32Height = ctx->height;
ctx->stVpssCfg.stVpssChnAttr[i].enCompressMode = COMPRESS_MODE_NONE;
}
// init vpss
s32Ret = create_vpss(&ctx->stVpssCfg, 0, ctx->stVpssCfg.u32VpssChnCnt);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("creat 0 grp vpss failed!");
goto __FAILED;
}
// bind vi to vpss
stViChn.enModId = RK_ID_VI;
stViChn.s32DevId = ctx->devId;
stViChn.s32ChnId = ctx->channelId;
stVpssChn.enModId = RK_ID_VPSS;
stVpssChn.s32DevId = 0;
stVpssChn.s32ChnId = 0;
RK_LOGD("vi to vpss ch %d vpss group %d", stVpssChn.s32ChnId , stVpssChn.s32DevId);
s32Ret = RK_MPI_SYS_Bind(&stViChn, &stVpssChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi and vpss bind error ");
goto __FAILED;
}
/* venc */
for (i = 0; i < u32DstCount; i++) {
// venc init and create
init_venc_cfg(ctx, i, RK_VIDEO_ID_AVC);
s32Ret = create_venc(ctx, ctx->stVencCfg[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
return s32Ret;
}
// bind vpss to venc
stVencChn[i].enModId = RK_ID_VENC;
stVencChn[i].s32DevId = i;
stVencChn[i].s32ChnId = ctx->stVencCfg[i].s32ChnId;
s32Ret = RK_MPI_SYS_Bind(&stVpssChn, &stVencChn[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
goto __FAILED;
}
ctx->stFrame[i].pstPack = reinterpret_cast<VENC_PACK_S *>(malloc(sizeof(VENC_PACK_S)));
#if TEST_WITH_FD
ctx->stVencCfg[i].selectFd = RK_MPI_VENC_GetFd(ctx->stVencCfg[i].s32ChnId);
RK_LOGE("venc chn:%d, ctx->selectFd:%d ", ctx->stVencCfg[i].s32ChnId, ctx->stVencCfg[i].selectFd);
#endif
}
while (loopCount < ctx->loopCountSet) {
for (i = 0; i < u32DstCount; i++) {
#if TEST_WITH_FD
test_vi_poll_event(-1, ctx->stVencCfg[i].selectFd);
#endif
// freeze test
RK_MPI_VI_SetChnFreeze(ctx->pipeId, ctx->channelId, ctx->bFreeze);
s32Ret = RK_MPI_VENC_GetStream(ctx->stVencCfg[i].s32ChnId, &ctx->stFrame[i], -1);
if (s32Ret == RK_SUCCESS) {
if (ctx->stVencCfg[i].bOutDebugCfg) {
pData = RK_MPI_MB_Handle2VirAddr(ctx->stFrame[i].pstPack->pMbBlk);
fwrite(pData, 1, ctx->stFrame[i].pstPack->u32Len, ctx->stVencCfg[i].fp);
fflush(ctx->stVencCfg[i].fp);
}
RK_LOGD("chn:%d, loopCount:%d enc->seq:%d wd:%d\n", i, loopCount,
ctx->stFrame[i].u32Seq, ctx->stFrame[i].pstPack->u32Len);
s32Ret = RK_MPI_VENC_ReleaseStream(ctx->stVencCfg[i].s32ChnId, &ctx->stFrame[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_ReleaseStream fail %x", s32Ret);
}
loopCount++;
} else {
RK_LOGE("RK_MPI_VI_GetChnFrame fail %x", s32Ret);
}
}
usleep(10*1000);
}
__FAILED:
// unbind vi->vpss
s32Ret = RK_MPI_SYS_UnBind(&stViChn, &stVpssChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
}
// unbind vpss->venc
for (i = 0; i < u32DstCount; i++) {
s32Ret = RK_MPI_SYS_UnBind(&stVpssChn, &stVencChn[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
}
}
// destory vpss
s32Ret = destory_vpss(0, ctx->stVpssCfg.u32VpssChnCnt);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("destory vpss error");
return s32Ret;
}
// 5. disable one chn
s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
for (i = 0; i < u32DstCount; i++) {
s32Ret = RK_MPI_VENC_StopRecvFrame(ctx->stVencCfg[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
RK_LOGE("destroy enc chn:%d", ctx->stVencCfg[i].s32ChnId);
s32Ret = RK_MPI_VENC_DestroyChn(ctx->stVencCfg[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VDEC_DestroyChn fail %x", s32Ret);
}
}
// 6.disable dev(will diabled all chn)
s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
for (i = 0; i < u32DstCount; i++) {
if (ctx->stFrame[i].pstPack)
free(ctx->stFrame[i].pstPack);
if (ctx->stVencCfg[i].fp)
fclose(ctx->stVencCfg[i].fp);
}
return s32Ret;
}
static RK_S32 test_vi_bind_venc_loop(TEST_VI_CTX_S *ctx) {
MPP_CHN_S stSrcChn, stDestChn[TEST_VENC_MAX];
RK_S32 loopCount = 0;
void *pData = RK_NULL;
RK_S32 s32Ret = RK_FAILURE;
RK_U32 i;
RK_U32 u32DstCount = ((ctx->enMode == TEST_VI_MODE_BIND_VENC_MULTI) ? 2 : 1);
s32Ret = test_vi_init(ctx);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi %d:%d init failed:%x", ctx->devId, ctx->channelId, s32Ret);
goto __FAILED;
}
/* venc */
for (i = 0; i < u32DstCount; i++) {
// venc init and create
init_venc_cfg(ctx, i, RK_VIDEO_ID_AVC);
s32Ret = create_venc(ctx, ctx->stVencCfg[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
return s32Ret;
}
// bind vi to venc
stSrcChn.enModId = RK_ID_VI;
stSrcChn.s32DevId = ctx->devId;
stSrcChn.s32ChnId = ctx->channelId;
stDestChn[i].enModId = RK_ID_VENC;
stDestChn[i].s32DevId = i;
stDestChn[i].s32ChnId = ctx->stVencCfg[i].s32ChnId;
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
goto __FAILED;
}
ctx->stFrame[i].pstPack = reinterpret_cast<VENC_PACK_S *>(malloc(sizeof(VENC_PACK_S)));
#if TEST_WITH_FD
ctx->stVencCfg[i].selectFd = RK_MPI_VENC_GetFd(ctx->stVencCfg[i].s32ChnId);
RK_LOGE("venc chn:%d, ctx->selectFd:%d ", ctx->stVencCfg[i].s32ChnId, ctx->stVencCfg[i].selectFd);
#endif
}
while (loopCount < ctx->loopCountSet) {
for (i = 0; i < u32DstCount; i++) {
#if TEST_WITH_FD
test_vi_poll_event(-1, ctx->stVencCfg[i].selectFd);
#endif
// freeze test
RK_MPI_VI_SetChnFreeze(ctx->pipeId, ctx->channelId, ctx->bFreeze);
s32Ret = RK_MPI_VENC_GetStream(ctx->stVencCfg[i].s32ChnId, &ctx->stFrame[i], -1);
if (s32Ret == RK_SUCCESS) {
if (ctx->stVencCfg[i].bOutDebugCfg) {
pData = RK_MPI_MB_Handle2VirAddr(ctx->stFrame[i].pstPack->pMbBlk);
fwrite(pData, 1, ctx->stFrame[i].pstPack->u32Len, ctx->stVencCfg[i].fp);
fflush(ctx->stVencCfg[i].fp);
}
RK_U64 nowUs = TEST_COMM_GetNowUs();
RK_LOGD("chn:%d, loopCount:%d enc->seq:%d wd:%d pts=%lld delay=%lldus\n", i, loopCount,
ctx->stFrame[i].u32Seq, ctx->stFrame[i].pstPack->u32Len,
ctx->stFrame[i].pstPack->u64PTS,
nowUs - ctx->stFrame[i].pstPack->u64PTS);
s32Ret = RK_MPI_VENC_ReleaseStream(ctx->stVencCfg[i].s32ChnId, &ctx->stFrame[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VENC_ReleaseStream fail %x", s32Ret);
}
loopCount++;
} else {
RK_LOGE("RK_MPI_VI_GetChnFrame fail %x", s32Ret);
}
}
usleep(10*1000);
}
__FAILED:
for (i = 0; i < u32DstCount; i++) {
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
}
}
// 5. disable one chn
s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
for (i = 0; i < u32DstCount; i++) {
s32Ret = RK_MPI_VENC_StopRecvFrame(ctx->stVencCfg[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
return s32Ret;
}
RK_LOGE("destroy enc chn:%d", ctx->stVencCfg[i].s32ChnId);
s32Ret = RK_MPI_VENC_DestroyChn(ctx->stVencCfg[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VDEC_DestroyChn fail %x", s32Ret);
}
}
// 6.disable dev(will diabled all chn)
s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
for (i = 0; i < u32DstCount; i++) {
if (ctx->stFrame[i].pstPack)
free(ctx->stFrame[i].pstPack);
if (ctx->stVencCfg[i].fp)
fclose(ctx->stVencCfg[i].fp);
}
return s32Ret;
}
static RK_S32 test_vi_get_release_frame_loop(TEST_VI_CTX_S *ctx) {
RK_S32 s32Ret;
RK_S32 loopCount = 0;
RK_S32 waitTime = 33;
/* test use getframe&release_frame */
s32Ret = test_vi_init(ctx);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi %d:%d init failed:%x", ctx->devId, ctx->channelId, s32Ret);
goto __FAILED;
}
while (loopCount < ctx->loopCountSet) {
#if TEST_WITH_FD_SWITCH
if (loopCount % 10 == 0 && ctx->selectFd != -1) { // test close/reopen the fd
RK_MPI_VI_CloseChnFd(ctx->pipeId, ctx->channelId);
RK_LOGE("close ctx->pipeId=%d, ctx->channelId=%d, ctx->selectFd:%d",
ctx->pipeId, ctx->channelId, ctx->selectFd);
ctx->selectFd = -1;
} else {
if (ctx->selectFd < 0) {
ctx->selectFd = RK_MPI_VI_GetChnFd(ctx->pipeId, ctx->channelId);
RK_LOGE("regetfd ctx->pipeId=%d, ctx->channelId=%d, ctx->selectFd:%d",
ctx->pipeId, ctx->channelId, ctx->selectFd);
// do not use non-block polling for the first time after switching fd
test_vi_poll_event(33, ctx->selectFd);
} else {
test_vi_poll_event(-1, ctx->selectFd);
}
}
#elif TEST_WITH_FD
test_vi_poll_event(-1, ctx->selectFd);
#endif
/* test user picture */
if (loopCount > 5 && ctx->bUserPicEnabled) {
ctx->bUserPicEnabled = RK_FALSE;
RK_MPI_VI_DisableUserPic(ctx->pipeId, ctx->channelId);
if (ctx->stUsrPic.enUsrPicMode == VI_USERPIC_MODE_PIC &&
ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk) {
RK_MPI_MMZ_Free(ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk);
ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk = RK_NULL;
}
}
// freeze test
RK_MPI_VI_SetChnFreeze(ctx->pipeId, ctx->channelId, ctx->bFreeze);
// 5.get the frame
s32Ret = RK_MPI_VI_GetChnFrame(ctx->pipeId, ctx->channelId, &ctx->stViFrame, waitTime);
if (s32Ret == RK_SUCCESS) {
RK_U64 nowUs = TEST_COMM_GetNowUs();
void *data = RK_MPI_MB_Handle2VirAddr(ctx->stViFrame.stVFrame.pMbBlk);
RK_LOGD("RK_MPI_VI_GetChnFrame ok:data %p loop:%d seq:%d pts:%lld ms len=%d", data, loopCount,
ctx->stViFrame.stVFrame.u32TimeRef, ctx->stViFrame.stVFrame.u64PTS/1000,
RK_MPI_MB_GetLength(ctx->stViFrame.stVFrame.pMbBlk));
// 6.get the channel status
s32Ret = RK_MPI_VI_QueryChnStatus(ctx->pipeId, ctx->channelId, &ctx->stChnStatus);
RK_LOGD("RK_MPI_VI_QueryChnStatus ret %x, w:%d,h:%d,enable:%d," \
"current frame id:%d,input lost:%d,output lost:%d," \
"framerate:%d,vbfail:%d delay=%lldus",
s32Ret,
ctx->stChnStatus.stSize.u32Width,
ctx->stChnStatus.stSize.u32Height,
ctx->stChnStatus.bEnable,
ctx->stChnStatus.u32CurFrameID,
ctx->stChnStatus.u32InputLostFrame,
ctx->stChnStatus.u32OutputLostFrame,
ctx->stChnStatus.u32FrameRate,
ctx->stChnStatus.u32VbFail,
nowUs - ctx->stViFrame.stVFrame.u64PTS);
// 7.release the frame
s32Ret = RK_MPI_VI_ReleaseChnFrame(ctx->pipeId, ctx->channelId, &ctx->stViFrame);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_ReleaseChnFrame fail %x", s32Ret);
}
loopCount++;
} else {
RK_LOGE("RK_MPI_VI_GetChnFrame timeout %x", s32Ret);
}
usleep(10*1000);
}
__FAILED:
// if enable rgn,deinit it and destory it.
if (ctx->bEnRgn) {
destory_rgn(ctx);
}
// 9. disable one chn
s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
// 10.disable dev(will diabled all chn)
s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
return s32Ret;
}
static RK_S32 create_vi(TEST_VI_CTX_S *ctx) {
RK_S32 s32Ret = RK_FAILURE;
// 0. get dev config status
s32Ret = RK_MPI_VI_GetDevAttr(ctx->devId, &ctx->stDevAttr);
if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
// 0-1.config dev
s32Ret = RK_MPI_VI_SetDevAttr(ctx->devId, &ctx->stDevAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_SetDevAttr %x", s32Ret);
goto __FAILED;
}
} else {
RK_LOGE("RK_MPI_VI_SetDevAttr already");
}
// 1.get dev enable status
s32Ret = RK_MPI_VI_GetDevIsEnable(ctx->devId);
if (s32Ret != RK_SUCCESS) {
// 1-2.enable dev
s32Ret = RK_MPI_VI_EnableDev(ctx->devId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_EnableDev %x", s32Ret);
goto __FAILED;
}
// 1-3.bind dev/pipe
ctx->stBindPipe.u32Num = ctx->pipeId;
ctx->stBindPipe.PipeId[0] = ctx->pipeId;
s32Ret = RK_MPI_VI_SetDevBindPipe(ctx->devId, &ctx->stBindPipe);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_SetDevBindPipe %x", s32Ret);
goto __FAILED;
}
} else {
RK_LOGE("RK_MPI_VI_EnableDev already");
}
// 2.config channel
s32Ret = RK_MPI_VI_SetChnAttr(ctx->pipeId, ctx->channelId, &ctx->stChnAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_SetChnAttr %x", s32Ret);
goto __FAILED;
}
// 3.enable channel
RK_LOGD("RK_MPI_VI_EnableChn %x %d %d", ctx->devId, ctx->pipeId, ctx->channelId);
s32Ret = RK_MPI_VI_EnableChn(ctx->pipeId, ctx->channelId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_EnableChn %x", s32Ret);
goto __FAILED;
}
// 4.save debug file
if (ctx->stDebugFile.bCfg) {
s32Ret = RK_MPI_VI_ChnSaveFile(ctx->pipeId, ctx->channelId, &ctx->stDebugFile);
RK_LOGD("RK_MPI_VI_ChnSaveFile %x", s32Ret);
}
__FAILED:
return s32Ret;
}
static RK_S32 destroy_vi(TEST_VI_CTX_S *ctx) {
RK_S32 s32Ret = RK_FAILURE;
s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
RK_LOGE("RK_MPI_VI_DisableChn pipe=%d ret:%x", ctx->pipeId, s32Ret);
s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
RK_LOGE("RK_MPI_VI_DisableDev pipe=%d ret:%x", ctx->pipeId, s32Ret);
RK_SAFE_FREE(ctx);
return s32Ret;
}
static RK_S32 test_vi_muti_vi_loop(TEST_VI_CTX_S *ctx_out) {
RK_S32 s32Ret = RK_FAILURE;
TEST_VI_CTX_S *pstViCtx[TEST_VI_SENSOR_NUM];
RK_S32 loopCount = 0;
RK_S32 waitTime = 33;
RK_S32 i = 0;
for (i = 0; i < TEST_VI_SENSOR_NUM; i++) {
pstViCtx[i] = reinterpret_cast<TEST_VI_CTX_S *>(malloc(sizeof(TEST_VI_CTX_S)));
memset(pstViCtx[i], 0, sizeof(TEST_VI_CTX_S));
/* vi config init */
pstViCtx[i]->devId = i;
pstViCtx[i]->pipeId = pstViCtx[i]->devId;
pstViCtx[i]->channelId = 2;
if (TEST_VI_SENSOR_NUM == 2) {
pstViCtx[i]->stChnAttr.stSize.u32Width = 2688;
pstViCtx[i]->stChnAttr.stSize.u32Height = 1520;
} else if (TEST_VI_SENSOR_NUM == 4 || TEST_VI_SENSOR_NUM == 6) {
pstViCtx[i]->stChnAttr.stSize.u32Width = 2560;
pstViCtx[i]->stChnAttr.stSize.u32Height = 1520;
}
pstViCtx[i]->stChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
pstViCtx[i]->stChnAttr.stIspOpt.u32BufCount = 10;
pstViCtx[i]->stChnAttr.u32Depth = 2;
pstViCtx[i]->stChnAttr.enPixelFormat = RK_FMT_YUV420SP;
pstViCtx[i]->stChnAttr.enCompressMode = COMPRESS_AFBC_16x16;
pstViCtx[i]->stChnAttr.stFrameRate.s32SrcFrameRate = -1;
pstViCtx[i]->stChnAttr.stFrameRate.s32DstFrameRate = -1;
/* vi create */
s32Ret = create_vi(pstViCtx[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d] init failed: %x",
pstViCtx[i]->devId, pstViCtx[i]->channelId,
s32Ret);
goto __FAILED_VI;
}
}
while (loopCount < ctx_out->loopCountSet) {
for (i = 0; i < TEST_VI_SENSOR_NUM; i++) {
// get the frame
s32Ret = RK_MPI_VI_GetChnFrame(pstViCtx[i]->pipeId, pstViCtx[i]->channelId,
&pstViCtx[i]->stViFrame, waitTime);
if (s32Ret == RK_SUCCESS) {
RK_U64 nowUs = TEST_COMM_GetNowUs();
void *data = RK_MPI_MB_Handle2VirAddr(pstViCtx[i]->stViFrame.stVFrame.pMbBlk);
RK_LOGD("dev %d GetChnFrame Success!", i);
RK_LOGD("RK_MPI_VI_GetChnFrame ok:data %p loop:%d seq:%d pts:%lld ms len=%d",
data, loopCount, pstViCtx[i]->stViFrame.stVFrame.u32TimeRef,
pstViCtx[i]->stViFrame.stVFrame.u64PTS/1000,
RK_MPI_MB_GetLength(pstViCtx[i]->stViFrame.stVFrame.pMbBlk));
// get the channel status
s32Ret = RK_MPI_VI_QueryChnStatus(pstViCtx[i]->pipeId, pstViCtx[i]->channelId,
&pstViCtx[i]->stChnStatus);
RK_LOGD("RK_MPI_VI_QueryChnStatus ret %x, w:%d,h:%d,enable:%d," \
"input lost:%d, output lost:%d, framerate:%d,vbfail:%d delay=%lldus",
s32Ret,
pstViCtx[i]->stChnStatus.stSize.u32Width,
pstViCtx[i]->stChnStatus.stSize.u32Height,
pstViCtx[i]->stChnStatus.bEnable,
pstViCtx[i]->stChnStatus.u32InputLostFrame,
pstViCtx[i]->stChnStatus.u32OutputLostFrame,
pstViCtx[i]->stChnStatus.u32FrameRate,
pstViCtx[i]->stChnStatus.u32VbFail,
nowUs - pstViCtx[i]->stViFrame.stVFrame.u64PTS);
// release the frame
s32Ret = RK_MPI_VI_ReleaseChnFrame(pstViCtx[i]->pipeId, pstViCtx[i]->channelId,
&pstViCtx[i]->stViFrame);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VI_ReleaseChnFrame fail %x", s32Ret);
}
} else {
RK_LOGE("dev %d RK_MPI_VI_GetChnFrame timeout %x", i, s32Ret);
}
usleep(3*1000);
}
loopCount++;
usleep(10*1000);
}
__FAILED_VI:
/* destroy vi*/
for (RK_S32 i = 0; i < TEST_VI_SENSOR_NUM; i++) {
s32Ret = destroy_vi(pstViCtx[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("destroy vi [%d, %d] error %x",
pstViCtx[i]->devId, pstViCtx[i]->channelId,
s32Ret);
goto __FAILED;
}
}
__FAILED:
return s32Ret;
}
static void mpi_vi_test_show_options(const TEST_VI_CTX_S *ctx) {
RK_PRINT("cmd parse result:\n");
RK_PRINT("output file open : %d\n", ctx->stDebugFile.bCfg);
RK_PRINT("yuv output file name : %s/%s\n", ctx->stDebugFile.aFilePath, ctx->stDebugFile.aFileName);
RK_PRINT("enc0 output file path : /%s/%s\n", ctx->stVencCfg[0].dstFilePath, ctx->stVencCfg[0].dstFileName);
RK_PRINT("enc1 output file path : /%s/%s\n", ctx->stVencCfg[1].dstFilePath, ctx->stVencCfg[1].dstFileName);
RK_PRINT("loop count : %d\n", ctx->loopCountSet);
RK_PRINT("enMode : %d\n", ctx->enMode);
RK_PRINT("dev : %d\n", ctx->devId);
RK_PRINT("pipe : %d\n", ctx->pipeId);
RK_PRINT("channel : %d\n", ctx->channelId);
RK_PRINT("width : %d\n", ctx->width);
RK_PRINT("height : %d\n", ctx->height);
RK_PRINT("enCompressMode : %d\n", ctx->enCompressMode);
RK_PRINT("enMemoryType : %d\n", ctx->stChnAttr.stIspOpt.enMemoryType);
RK_PRINT("aEntityName : %s\n", ctx->stChnAttr.stIspOpt.aEntityName);
RK_PRINT("depth : %d\n", ctx->stChnAttr.u32Depth);
RK_PRINT("enPixelFormat : %d\n", ctx->stChnAttr.enPixelFormat);
RK_PRINT("bFreeze : %d\n", ctx->bFreeze);
RK_PRINT("src_frame rate : %d\n", ctx->stChnAttr.stFrameRate.s32SrcFrameRate);
RK_PRINT("dst frame rate : %d\n", ctx->stChnAttr.stFrameRate.s32DstFrameRate);
RK_PRINT("out buf count : %d\n", ctx->stChnAttr.stIspOpt.u32BufCount);
RK_PRINT("bUserPicEnabled : %d\n", ctx->bUserPicEnabled);
RK_PRINT("bEnRgn : %d\n", ctx->bEnRgn);
RK_PRINT("rgn count : %d\n", ctx->s32RgnCnt);
RK_PRINT("rgn type : %d\n", ctx->rgnType);
RK_PRINT("bGetConnecInfo : %d\n", ctx->bGetConnecInfo);
RK_PRINT("bGetEdid : %d\n", ctx->bGetEdid);
RK_PRINT("bSetEdid : %d\n", ctx->bSetEdid);
}
static const char *const usages[] = {
"./rk_mpi_vi_test -w 1920 -h 1080 -t 4 -n rkispp_scale0",
RK_NULL,
};
int main(int argc, const char **argv) {
RK_S32 i;
RK_S32 s32Ret = RK_FAILURE;
TEST_VI_CTX_S *ctx;
ctx = reinterpret_cast<TEST_VI_CTX_S *>(malloc(sizeof(TEST_VI_CTX_S)));
memset(ctx, 0, sizeof(TEST_VI_CTX_S));
ctx->width = 0;
ctx->height = 0;
ctx->devId = 0;
ctx->pipeId = ctx->devId;
ctx->channelId = 1;
ctx->loopCountSet = 100;
ctx->enMode = TEST_VI_MODE_BIND_VENC;
ctx->stChnAttr.stIspOpt.u32BufCount = 3;
ctx->stChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
ctx->stChnAttr.stIspOpt.enCaptureType = VI_V4L2_CAPTURE_TYPE_VIDEO_CAPTURE;
ctx->stChnAttr.u32Depth = 0;
ctx->aEntityName = RK_NULL;
ctx->stChnAttr.enPixelFormat = RK_FMT_YUV420SP;
ctx->stChnAttr.stFrameRate.s32SrcFrameRate = -1;
ctx->stChnAttr.stFrameRate.s32DstFrameRate = -1;
ctx->bEnRgn = RK_FALSE;
ctx->s32RgnCnt = 1;
ctx->rgnType = RGN_BUTT;
RK_LOGE("test running enter!");
struct argparse_option options[] = {
OPT_HELP(),
OPT_GROUP("basic options:"),
OPT_INTEGER('w', "width", &(ctx->width),
"set capture channel width(required, default 0)", NULL, 0, 0),
OPT_INTEGER('h', "height", &(ctx->height),
"set capture channel height(required, default 0)", NULL, 0, 0),
OPT_INTEGER('d', "dev", &(ctx->devId),
"set dev id(default 0)", NULL, 0, 0),
OPT_INTEGER('p', "pipe", &(ctx->pipeId),
"set pipe id(default 0)", NULL, 0, 0),
OPT_INTEGER('c', "channel", &(ctx->channelId),
"set channel id(default 1)", NULL, 0, 0),
OPT_INTEGER('l', "loopcount", &(ctx->loopCountSet),
"set capture frame count(default 100)", NULL, 0, 0),
OPT_INTEGER('C', "compressmode", &(ctx->enCompressMode),
"set capture compressmode(default 0; 0:MODE_NONE 1:AFBC_16x16)", NULL, 0, 0),
OPT_INTEGER('o', "output", &(ctx->stDebugFile.bCfg),
"save output file, file at /data/test_<devid>_<pipeid>_<channelid>.bin"
" (default 0; 0:no save 1:save)", NULL, 0, 0),
OPT_INTEGER('m', "mode", &(ctx->enMode),
"test mode(default 1; 0:vi get&release frame 1:vi bind one venc(h264) \n\t"
"2:vi bind two venc(h264)) 3:vi bind vpss bind venc \n\t"
"4:vi bind vo(only support 356x now)", NULL, 0, 0),
OPT_INTEGER('t', "memorytype", &(ctx->stChnAttr.stIspOpt.enMemoryType),
"set the buf memorytype(required, default 4; 1:mmap(hdmiin/bt1120/sensor input) "
"2:userptr(invalid) 3:overlay(invalid) 4:dma(sensor))", NULL, 0, 0),
OPT_STRING('n', "name", &(ctx->aEntityName),
"set the entityName (required, default null;\n\t"
"rv1126 sensor:rkispp_m_bypass rkispp_scale0 rkispp_scale1 rkispp_scale2;\n\t"
"rv1126 hdmiin/bt1120/sensor:/dev/videox such as /dev/video19 /dev/video20;\n\t"
"rk356x hdmiin/bt1120/sensor:/dev/videox such as /dev/video0 /dev/video1", NULL, 0, 0),
OPT_INTEGER('D', "depth", &(ctx->stChnAttr.u32Depth),
"channel output depth, default{u32BufCount(not bind) or 0(bind venc/vpss/...)}", NULL, 0, 0),
OPT_INTEGER('f', "format", &(ctx->stChnAttr.enPixelFormat),
"set the format(default 0; 0:RK_FMT_YUV420SP 10:RK_FMT_YUV422_UYVY"
"131080:RK_FMT_RGB_BAYER_SBGGR_12BPP)", NULL, 0, 0),
OPT_INTEGER('\0', "freeze", &(ctx->bFreeze),
"freeze output(default 0; 0:disable freeze 1:enable freeze)", NULL, 0, 0),
OPT_INTEGER('\0', "src_rate", &(ctx->stChnAttr.stFrameRate.s32SrcFrameRate),
"src frame rate(default -1; -1:not control; other:1-max_fps<isp_out_fps>)", NULL, 0, 0),
OPT_INTEGER('\0', "dst_rate", &(ctx->stChnAttr.stFrameRate.s32DstFrameRate),
"dst frame rate(default -1; -1:not control; other:1-src_fps<src_rate>)", NULL, 0, 0),
OPT_INTEGER('\0', "buf_count", &(ctx->stChnAttr.stIspOpt.u32BufCount),
"out buf count, range[1-8] default(3)", NULL, 0, 0),
OPT_INTEGER('U', "user_pic", &(ctx->bUserPicEnabled),
"enable using user specify picture as vi input.", NULL, 0, 0),
OPT_INTEGER('\0', "rgn_type", &(ctx->rgnType),
"rgn type. 0:overlay, 1:overlayEx,2:cover,3:coverEx,4:mosaic,5:moscaiEx", NULL, 0, 0),
OPT_INTEGER('\0', "rgn_cnt", &(ctx->s32RgnCnt),
"rgn count. default(1),max:8", NULL, 0, 0),
OPT_INTEGER('\0', "en_rgn", &(ctx->bEnRgn),
"enable rgn. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "get_connect_info", &(ctx->bGetConnecInfo),
"get connect info. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "get_edid", &(ctx->bGetEdid),
"get edid. default(0)", NULL, 0, 0),
OPT_INTEGER('\0', "set_edid", &(ctx->bSetEdid),
"set edid. default(0)", NULL, 0, 0),
OPT_END(),
};
struct argparse argparse;
argparse_init(&argparse, options, usages, 0);
argparse_describe(&argparse, "\nselect a test case to run.",
"\nuse --help for details.");
argc = argparse_parse(&argparse, argc, argv);
if (!ctx->width || !ctx->height) {
argparse_usage(&argparse);
goto __FAILED2;
}
if (ctx->pipeId != ctx->devId)
ctx->pipeId = ctx->devId;
if (ctx->stDebugFile.bCfg) {
if (ctx->enMode == TEST_VI_MODE_BIND_VENC || ctx->enMode == TEST_VI_MODE_BIND_VPSS_BIND_VENC) {
ctx->stVencCfg[0].bOutDebugCfg = ctx->stDebugFile.bCfg;
} else if (ctx->enMode == TEST_VI_MODE_BIND_VENC_MULTI) {
ctx->stVencCfg[0].bOutDebugCfg = ctx->stDebugFile.bCfg;
ctx->stVencCfg[1].bOutDebugCfg = ctx->stDebugFile.bCfg;
}
memcpy(&ctx->stDebugFile.aFilePath, "/data", strlen("/data"));
snprintf(ctx->stDebugFile.aFileName, MAX_VI_FILE_PATH_LEN,
"test_%d_%d_%d.bin", ctx->devId, ctx->pipeId, ctx->channelId);
}
for (i = 0; i < ctx->enMode; i++) {
if (ctx->stVencCfg[i].bOutDebugCfg) {
char name[256] = {0};
memcpy(&ctx->stVencCfg[i].dstFilePath, "data", strlen("data"));
snprintf(ctx->stVencCfg[i].dstFileName, sizeof(ctx->stVencCfg[i].dstFileName),
"venc_%d.bin", i);
snprintf(name, sizeof(name), "/%s/%s",
ctx->stVencCfg[i].dstFilePath, ctx->stVencCfg[i].dstFileName);
ctx->stVencCfg[i].fp = fopen(name, "wb");
if (ctx->stVencCfg[i].fp == RK_NULL) {
RK_LOGE("chn %d can't open file %s in get picture thread!\n", i, name);
goto __FAILED;
}
}
}
RK_LOGE("test running enter ctx->aEntityName=%s!", ctx->aEntityName);
if (ctx->aEntityName != RK_NULL)
memcpy(ctx->stChnAttr.stIspOpt.aEntityName, ctx->aEntityName, strlen(ctx->aEntityName));
if (ctx->pipeId != ctx->devId)
ctx->pipeId = ctx->devId;
mpi_vi_test_show_options(ctx);
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
RK_LOGE("rk mpi sys init fail!");
goto __FAILED;
}
switch (ctx->enMode) {
case TEST_VI_MODE_VI_ONLY:
if (!ctx->stChnAttr.u32Depth) {
RK_LOGE("depth need > 0 when vi not bind any other module!");
ctx->stChnAttr.u32Depth = ctx->stChnAttr.stIspOpt.u32BufCount;
}
s32Ret = test_vi_get_release_frame_loop(ctx);
break;
case TEST_VI_MODE_BIND_VENC:
case TEST_VI_MODE_BIND_VENC_MULTI:
s32Ret = test_vi_bind_venc_loop(ctx);
break;
case TEST_VI_MODE_BIND_VPSS_BIND_VENC:
s32Ret = test_vi_bind_vpss_venc_loop(ctx);
break;
case TEST_VI_MODE_BIND_VO:
s32Ret = test_vi_bind_vo_loop(ctx);
break;
case TEST_VI_MODE_MUTI_VI:
s32Ret = test_vi_muti_vi_loop(ctx);
break;
default:
RK_LOGE("no support such test mode:%d", ctx->enMode);
break;
}
__FAILED:
RK_LOGE("test running exit:%d", s32Ret);
RK_MPI_SYS_Exit();
__FAILED2:
if (ctx) {
free(ctx);
ctx = RK_NULL;
}
return 0;
}