linuxOS_AP06/external/rockit/mpi/example/mod/test_mpi_dis.cpp
2025-06-03 12:28:32 +08:00

1217 lines
45 KiB
C++
Executable File

/*
* 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 <string>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include "rk_defines.h"
#include "rk_debug.h"
#include "rk_mpi_cal.h"
#include "rk_mpi_mb.h"
#include "rk_mpi_mmz.h"
#include "rk_mpi_sys.h"
#include "rk_mpi_vi.h"
#include "rk_mpi_venc.h"
#include "rk_mpi_vo.h"
#include "rk_common.h"
#include "rk_comm_venc.h"
#include "rk_comm_vi.h"
#include "rk_comm_vo.h"
#include "test_common.h"
#include "test_comm_utils.h"
#include "test_comm_sys.h"
#include "test_comm_argparse.h"
#define TEST_VI_SENSOR_NUM 4
/* for RK3588 */
#define RK3588_VO_DEV_HDMI 0
#define RK3588_VO_DEV_MIPI 3
static RK_BOOL bExit = RK_FALSE;
typedef enum _rkTEST_DIS_MODE_E {
TEST_DIS_MODE_VI_ONLY = 0,
TEST_DIS_MODE_BIND_VO = 1,
TEST_DIS_MODE_BIND_VENC = 2
} TEST_DIS_MODE_E;
typedef enum _rkTEST_DIS_CHANGE_MODE_E {
TEST_DIS_X_NONE = 0,
TEST_DIS_X_FUNC_SWITCH = 1,
TEST_DIS_X_CROP_RATIO = 2,
TEST_DIS_X_STILL_CROP = 3
} TEST_DIS_CHANGE_MODE_E;
typedef struct _rkTEST_DIS_CTX_S {
RK_S32 s32LoopCount;
TEST_DIS_MODE_E enTestMode;
RK_U32 u32Width;
RK_U32 u32Height;
PIXEL_FORMAT_E enPixelFormat;
COMPRESS_MODE_E enCompressMode;
RK_U32 u32ViCnt;
RK_U32 u32ViBufCnt;
RK_U32 u32DisBufCnt;
RK_BOOL bUserPicEnabled;
const RK_CHAR *pUserPicFile;
RK_U32 u32CropRatio;
const RK_CHAR *pDstFilePath;
TEST_DIS_CHANGE_MODE_E enChangeMode;
} TEST_DIS_CTX_S;
typedef struct rkVI_CFG_S {
VI_DEV s32DevId;
VI_CHN s32ChnId;
VI_PIPE s32PipeId;
VI_DEV_ATTR_S stViDevAttr;
VI_CHN_STATUS_S stViChnStatus;
VI_CHN_ATTR_S stViChnAttr;
VI_DEV_BIND_PIPE_S stBindPipe;
RK_BOOL bUserPicEnabled;
const RK_CHAR *pUserPicFile;
VI_USERPIC_ATTR_S stUsrPic;
RK_S32 s32LoopCount;
RK_BOOL bThreadExit;
const RK_CHAR *pDstFilePath;
TEST_DIS_CHANGE_MODE_E enChangeMode;
} VI_CFG_S;
typedef struct _rkVO_CFG_S {
VO_DEV s32DevId;
VO_CHN s32ChnId;
VO_LAYER s32LayerId;
VO_VIDEO_LAYER_ATTR_S stVoLayerAttr;
VO_CHN_ATTR_S stVoChnAttr;
VO_CSC_S stVoCscAttr;
} VO_CFG_S;
typedef struct rkVENC_CFG_S {
VENC_CHN VencChn;
VENC_CHN_ATTR_S stAttr;
} VENC_CFG_S;
static RK_S32 readFromPic(VI_CFG_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;
if (!ctx->pUserPicFile) {
return RK_ERR_NULL_PTR;
}
stPicBufAttr.u32Width = ctx->stViChnAttr.stSize.u32Width;
stPicBufAttr.u32Height = ctx->stViChnAttr.stSize.u32Height;
stPicBufAttr.enCompMode = COMPRESS_MODE_NONE;
stPicBufAttr.enPixelFormat = RK_FMT_YUV420SP;
s32Ret = RK_MPI_CAL_VGS_GetPicBufferSize(&stPicBufAttr, &stMbPicCalResult);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("get user picture buffer size failed %#x!", s32Ret);
return RK_NULL;
}
s32Ret = RK_MPI_MMZ_Alloc(&srcBlk, stMbPicCalResult.u32MBSize, RK_MMZ_ALLOC_CACHEABLE);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("all user picture buffer failed %#x!", s32Ret);
return RK_NULL;
}
fp = fopen(ctx->pUserPicFile, "rb");
if (NULL == fp) {
RK_LOGE("open %s fail", ctx->pUserPicFile);
goto __FREE_USER_PIC;
} 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", ctx->pUserPicFile);
}
buffer->u32Width = ctx->stViChnAttr.stSize.u32Width;
buffer->u32Height = ctx->stViChnAttr.stSize.u32Height;
buffer->u32VirWidth = ctx->stViChnAttr.stSize.u32Width;
buffer->u32VirHeight = ctx->stViChnAttr.stSize.u32Height;
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->stViChnAttr.stSize.u32Width, ctx->stViChnAttr.stSize.u32Height,
stMbPicCalResult.u32MBSize, RK_FMT_YUV420SP);
return RK_SUCCESS;
__FREE_USER_PIC:
RK_MPI_SYS_MmzFree(srcBlk);
return RK_NULL;
}
static RK_S32 create_vi(VI_CFG_S *ctx) {
RK_S32 s32Ret = RK_FAILURE;
/* 0. get dev config status */
s32Ret = RK_MPI_VI_GetDevAttr(ctx->s32DevId, &ctx->stViDevAttr);
if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
/* 0-1.config dev */
s32Ret = RK_MPI_VI_SetDevAttr(ctx->s32DevId, &ctx->stViDevAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d] RK_MPI_VI_SetDevAttr failed: %#x!",
ctx->s32DevId, ctx->s32ChnId, s32Ret);
goto __FAILED;
}
}
RK_LOGV("vi [%d, %d] RK_MPI_VI_SetDevAttr already.",
ctx->s32DevId, ctx->s32ChnId);
/* 1.get dev enable status */
s32Ret = RK_MPI_VI_GetDevIsEnable(ctx->s32DevId);
if (s32Ret != RK_SUCCESS) {
/* 1-2.enable dev */
s32Ret = RK_MPI_VI_EnableDev(ctx->s32DevId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d] RK_MPI_VI_EnableDev failed: %#x!",
ctx->s32DevId, ctx->s32ChnId, s32Ret);
goto __FAILED;
}
RK_LOGV("vi [%d, %d] RK_MPI_VI_EnableDev already.",
ctx->s32DevId, ctx->s32ChnId);
/* 1-3.bind dev/pipe */
ctx->stBindPipe.u32Num = ctx->s32PipeId;
ctx->stBindPipe.PipeId[0] = ctx->s32PipeId;
s32Ret = RK_MPI_VI_SetDevBindPipe(ctx->s32DevId, &ctx->stBindPipe);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d] RK_MPI_VI_SetDevBindPipe failed: %#x!",
ctx->s32DevId, ctx->s32ChnId, s32Ret);
goto __FAILED;
}
RK_LOGV("vi [%d, %d] RK_MPI_VI_SetDevBindPipe already.",
ctx->s32DevId, ctx->s32ChnId);
}
RK_LOGV("vi [%d, %d] RK_MPI_VI_GetDevIsEnable already.",
ctx->s32DevId, ctx->s32ChnId);
/* 2.config channel */
s32Ret = RK_MPI_VI_SetChnAttr(ctx->s32PipeId, ctx->s32ChnId, &ctx->stViChnAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] RK_MPI_VI_SetChnAttr failed: %#x!",
ctx->s32DevId, ctx->s32PipeId, ctx->s32ChnId, s32Ret);
goto __FAILED;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetChnAttr already.",
ctx->s32DevId, ctx->s32PipeId, ctx->s32ChnId);
if (ctx->bUserPicEnabled) {
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("vi [%d, %d] readFromPic fail:%x",
ctx->s32DevId, ctx->s32ChnId, 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->s32PipeId, ctx->s32ChnId, &ctx->stUsrPic);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] RK_MPI_VI_SetUserPic failed: %#x!",
ctx->s32DevId, ctx->s32PipeId, ctx->s32ChnId, s32Ret);
goto __FREE_USER_PIC;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetUserPic already.",
ctx->s32DevId, ctx->s32PipeId, ctx->s32ChnId);
s32Ret = RK_MPI_VI_EnableUserPic(ctx->s32PipeId, ctx->s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] RK_MPI_VI_EnableUserPic failed: %#x!",
ctx->s32DevId, ctx->s32PipeId, ctx->s32ChnId, s32Ret);
goto __FREE_USER_PIC;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_EnableUserPic already.",
ctx->s32DevId, ctx->s32PipeId, ctx->s32ChnId);
}
/* 3.enable channel */
s32Ret = RK_MPI_VI_EnableChn(ctx->s32PipeId, ctx->s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] RK_MPI_VI_EnableChn failed: %#x!",
ctx->s32DevId, ctx->s32PipeId, ctx->s32ChnId, s32Ret);
goto __FAILED;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_EnableChn already.",
ctx->s32DevId, ctx->s32PipeId, ctx->s32ChnId);
__FREE_USER_PIC:
if (ctx->bUserPicEnabled &&
VI_USERPIC_MODE_PIC == ctx->stUsrPic.enUsrPicMode &&
ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk) {
RK_MPI_MMZ_Free(ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk);
ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk = RK_NULL;
}
__FAILED:
return s32Ret;
}
static RK_S32 destroy_vi(VI_CFG_S *ctx) {
RK_S32 s32Ret = RK_SUCCESS;
s32Ret = RK_MPI_VI_DisableChn(ctx->s32PipeId, ctx->s32ChnId);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("RK_MPI_VI_DisableChn failed: %#x!",
ctx->s32DevId, ctx->s32ChnId, s32Ret);
goto __FAILED;
} else {
RK_LOGV("vi [%d, %d] RK_MPI_VI_DisableChn already.",
ctx->s32DevId, ctx->s32ChnId);
}
s32Ret = RK_MPI_VI_DisableDev(ctx->s32DevId);
if (RK_SUCCESS != s32Ret) {
RK_LOGE("RK_MPI_VI_DisableDev failed: %#x!",
ctx->s32DevId, ctx->s32ChnId, s32Ret);
goto __FAILED;
} else {
RK_LOGV("vi [%d, %d] RK_MPI_VI_DisableDev already.",
ctx->s32DevId, ctx->s32ChnId);
}
__FAILED:
if (ctx->bUserPicEnabled &&
VI_USERPIC_MODE_PIC == ctx->stUsrPic.enUsrPicMode &&
ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk) {
RK_MPI_MMZ_Free(ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk);
ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk = RK_NULL;
}
return s32Ret;
}
static RK_S32 create_venc(VENC_CFG_S *ctx) {
RK_S32 s32Ret = RK_SUCCESS;
VENC_RECV_PIC_PARAM_S stRecvParam;
memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
stRecvParam.s32RecvPicNum = -1;
s32Ret = RK_MPI_VENC_CreateChn(ctx->VencChn, &ctx->stAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("venc [%d] RK_MPI_VENC_CreateChn failed: %#x!",
ctx->VencChn, s32Ret);
return s32Ret;
}
RK_LOGV("venc [%d] RK_MPI_VENC_CreateChn already.", ctx->VencChn);
s32Ret = RK_MPI_VENC_StartRecvFrame(ctx->VencChn, &stRecvParam);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("venc [%d] RK_MPI_VENC_StartRecvFrame failed: %#x!",
ctx->VencChn, s32Ret);
return s32Ret;
}
RK_LOGV("venc [%d] RK_MPI_VENC_StartRecvFrame already.", ctx->VencChn);
return RK_SUCCESS;
}
static RK_S32 destroy_venc(VENC_CFG_S *ctx) {
RK_S32 s32Ret = RK_SUCCESS;
s32Ret = RK_MPI_VENC_StopRecvFrame(ctx->VencChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("venc [%d] RK_MPI_VENC_StopRecvFrame failed: %#x!",
ctx->VencChn, s32Ret);
return s32Ret;
}
RK_LOGV("venc [%d] RK_MPI_VENC_StopRecvFrame already.", ctx->VencChn);
s32Ret = RK_MPI_VENC_DestroyChn(ctx->VencChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("venc [%d] RK_MPI_VENC_DestroyChn failed: %#x!",
ctx->VencChn, s32Ret);
return s32Ret;
}
RK_LOGV("venc [%d] RK_MPI_VENC_DestroyChn already.", ctx->VencChn);
return RK_SUCCESS;
}
static RK_S32 create_vo(VO_CFG_S *ctx) {
RK_S32 s32Ret = RK_SUCCESS;
RK_U32 u32DispBufLen;
VO_PUB_ATTR_S VoPubAttr;
VO_LAYER VoLayer = ctx->s32LayerId;
VO_DEV VoDev = ctx->s32DevId;
VO_CHN VoChn = ctx->s32ChnId;
memset(&VoPubAttr, 0, sizeof(VO_PUB_ATTR_S));
s32Ret = RK_MPI_VO_GetPubAttr(VoDev, &VoPubAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_GetPubAttr failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_GetPubAttr already.",
VoDev, VoLayer, VoChn);
if (RK3588_VO_DEV_HDMI == VoDev) {
VoPubAttr.enIntfType = VO_INTF_HDMI;
VoPubAttr.enIntfSync = VO_OUTPUT_1080P60;
} else if (RK3588_VO_DEV_MIPI == VoDev) {
VoPubAttr.enIntfType = VO_INTF_MIPI;
VoPubAttr.enIntfSync = VO_OUTPUT_DEFAULT;
}
s32Ret = RK_MPI_VO_SetPubAttr(VoDev, &VoPubAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_GetPubAttr failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetPubAttr already.",
VoDev, VoLayer, VoChn);
s32Ret = RK_MPI_VO_Enable(VoDev);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_Enable failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_Enable already.",
VoDev, VoLayer, VoChn);
s32Ret = RK_MPI_VO_GetLayerDispBufLen(VoLayer, &u32DispBufLen);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_GetLayerDispBufLen failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_GetLayerDispBufLen already.",
VoDev, VoLayer, VoChn);
u32DispBufLen = 3;
s32Ret = RK_MPI_VO_SetLayerDispBufLen(VoLayer, u32DispBufLen);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_GetLayerDispBufLen %d failed: %#x!",
VoDev, VoLayer, VoChn, u32DispBufLen, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_GetLayerDispBufLen %d already.",
VoDev, VoLayer, VoChn, u32DispBufLen);
s32Ret = RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_GRAPHIC);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_BindLayer failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_BindLayer already.",
VoDev, VoLayer, VoChn);
s32Ret = RK_MPI_VO_SetLayerAttr(VoLayer, &ctx->stVoLayerAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_SetLayerAttr failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetLayerAttr already.",
VoDev, VoLayer, VoChn);
#if VO_RGA
s32Ret = RK_MPI_VO_SetLayerSpliceMode(VoLayer, VO_SPLICE_MODE_RGA);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("RK_MPI_VO_SetLayerSpliceMode failed: %#x", s32Ret);
return RK_FAILURE;
}
#endif
s32Ret = RK_MPI_VO_EnableLayer(VoLayer);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_EnableLayer failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_EnableLayer already.",
VoDev, VoLayer, VoChn);
s32Ret = RK_MPI_VO_SetChnAttr(VoLayer, VoChn, &ctx->stVoChnAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr already.",
VoDev, VoLayer, VoChn);
s32Ret = RK_MPI_VO_SetLayerCSC(VoLayer, &ctx->stVoCscAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr already.",
VoDev, VoLayer, VoChn);
s32Ret = RK_MPI_VO_EnableChn(VoLayer, VoChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_EnableChn failed: %#x!",
VoDev, VoLayer, VoChn, s32Ret);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_EnableChn already.",
VoDev, VoLayer, VoChn);
return s32Ret;
}
static RK_S32 destroy_vo(VO_CFG_S *ctx) {
RK_S32 s32Ret = RK_SUCCESS;
VO_LAYER VoLayer = ctx->s32LayerId;
VO_DEV VoDev = ctx->s32DevId;
VO_CHN VoChn = ctx->s32ChnId;
s32Ret = RK_MPI_VO_DisableChn(VoDev, VoChn);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_DisableChn failed: %#x!",
VoDev, VoLayer, VoChn);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_DisableChn already.",
VoDev, VoLayer, VoChn);
s32Ret = RK_MPI_VO_DisableLayer(VoLayer);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_DisableLayer failed: %#x!",
VoDev, VoLayer, VoChn);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_DisableLayer already.",
VoDev, VoLayer, VoChn);
s32Ret = RK_MPI_VO_Disable(VoDev);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_Disable failed: %#x!",
VoDev, VoLayer, VoChn);
return s32Ret;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_Disable already.",
VoDev, VoLayer, VoChn);
return s32Ret;
}
static RK_VOID *vi_get_frame(void *pArgs) {
VI_CFG_S *pstCtx = reinterpret_cast<VI_CFG_S *>(pArgs);
RK_S32 s32Ret = RK_SUCCESS;
char cWritePath[256] = {0};
VIDEO_FRAME_INFO_S stViFrame;
memset(&stViFrame, 0, sizeof(VIDEO_FRAME_INFO_S));
for (RK_S32 loopCount = 0; loopCount < pstCtx->s32LoopCount; loopCount++) {
s32Ret = RK_MPI_VI_GetChnFrame(pstCtx->s32PipeId, pstCtx->s32ChnId, &stViFrame, -1);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] RK_MPI_VI_GetChnFrame loopCount %d failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId, pstCtx->s32ChnId, loopCount, s32Ret);
}
if (pstCtx->pDstFilePath) {
snprintf(cWritePath, sizeof(cWritePath), "%sres_vi_%dx%d_%d_%d_%d.bin",
pstCtx->pDstFilePath, stViFrame.stVFrame.u32VirWidth,
stViFrame.stVFrame.u32VirHeight, pstCtx->s32DevId,
pstCtx->s32PipeId, pstCtx->s32ChnId, loopCount);
s32Ret = TEST_COMM_FileWriteOneFrame(cWritePath, &stViFrame);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] TEST_COMM_FileWriteOneFrame loopCount %d failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId, pstCtx->s32ChnId, loopCount, s32Ret);
break;
}
}
s32Ret = RK_MPI_VI_ReleaseChnFrame(pstCtx->s32PipeId, pstCtx->s32ChnId, &stViFrame);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] RK_MPI_VI_ReleaseChnFrame loopCount %d failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId, pstCtx->s32ChnId, loopCount, s32Ret);
break;
}
}
return RK_NULL;
}
static RK_S32 test_vi_get_release_frame_loop(TEST_DIS_CTX_S *ctx) {
RK_S32 s32Ret = RK_SUCCESS;
VI_CFG_S *pstViCtx = reinterpret_cast<VI_CFG_S *>(malloc(
sizeof(VI_CFG_S) * ctx->u32ViCnt));
DIS_CONFIG_S pstDisConfig;
DIS_ATTR_S pstDisAttr;
pthread_t viThread[VI_MAX_CHN_NUM] = {0};
memset(pstViCtx, 0, sizeof(VI_CFG_S) * ctx->u32ViCnt);
memset(&pstDisConfig, 0, sizeof(DIS_CONFIG_S));
memset(&pstDisAttr, 0, sizeof(DIS_ATTR_S));
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
/* vi config init */
pstViCtx[i].s32DevId = i;
pstViCtx[i].s32PipeId = pstViCtx[i].s32DevId;
/* only support RK3588 */
if (ctx->enCompressMode == COMPRESS_MODE_NONE) {
pstViCtx[i].s32ChnId = 0; // main path
} else if (ctx->enCompressMode == COMPRESS_AFBC_16x16) {
pstViCtx[i].s32ChnId = 2; // fbc path
}
pstViCtx[i].stViChnAttr.stSize.u32Width = ctx->u32Width;
pstViCtx[i].stViChnAttr.stSize.u32Height = ctx->u32Height;
pstViCtx[i].stViChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
pstViCtx[i].stViChnAttr.stIspOpt.u32BufCount = ctx->u32ViBufCnt;
pstViCtx[i].stViChnAttr.u32Depth = 2;
pstViCtx[i].stViChnAttr.enPixelFormat = ctx->enPixelFormat;
pstViCtx[i].stViChnAttr.enCompressMode = ctx->enCompressMode;
pstViCtx[i].stViChnAttr.stFrameRate.s32SrcFrameRate = -1;
pstViCtx[i].stViChnAttr.stFrameRate.s32DstFrameRate = -1;
if (ctx->bUserPicEnabled) {
pstViCtx[i].bUserPicEnabled = ctx->bUserPicEnabled;
pstViCtx[i].pUserPicFile = ctx->pUserPicFile;
}
pstViCtx[i].s32LoopCount = ctx->s32LoopCount;
pstViCtx[i].pDstFilePath = ctx->pDstFilePath;
/* vi create */
s32Ret = create_vi(&pstViCtx[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] create failed: %#x!",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VI;
}
RK_LOGV("vi [%d, %d, %d] create already.",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId);
/* dis config init */
pstDisConfig.enMode = DIS_MODE_4_DOF_GME;
pstDisConfig.enMotionLevel = DIS_MOTION_LEVEL_NORMAL;
pstDisConfig.u32CropRatio = ctx->u32CropRatio;
pstDisConfig.u32BufNum = ctx->u32DisBufCnt;
pstDisConfig.u32FrameRate = 30;
pstDisConfig.enPdtType = DIS_PDT_TYPE_IPC;
pstDisConfig.u32GyroOutputRange = 0;
pstDisConfig.bCameraSteady = RK_FALSE;
pstDisConfig.u32GyroDataBitWidth = 0;
pstDisAttr.bEnable = RK_TRUE;
pstDisAttr.u32MovingSubjectLevel = 0;
pstDisAttr.s32RollingShutterCoef = 0;
pstDisAttr.u32Timelag = 33333;
pstDisAttr.u32ViewAngle = 1000;
pstDisAttr.bStillCrop = RK_FALSE;
pstDisAttr.u32HorizontalLimit = 512;
pstDisAttr.u32VerticalLimit = 512;
s32Ret = RK_MPI_VI_SetChnDISConfig(pstViCtx[i].s32DevId, pstViCtx[i].s32ChnId, &pstDisConfig);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_SetChnDISConfig failed: %#x!",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VI;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetChnDISConfig already.",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId);
s32Ret = RK_MPI_VI_SetChnDISAttr(pstViCtx[i].s32DevId, pstViCtx[i].s32ChnId, &pstDisAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_SetChnDISAttr failed: %#x!",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VI;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetChnDISAttr already.",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId);
}
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
pthread_create(&viThread[i], 0, vi_get_frame, reinterpret_cast<void *>(&pstViCtx[i]));
}
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
if (viThread[i])
pthread_join(viThread[i], RK_NULL);
}
__DESTROY_VI:
/* destroy vi */
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
s32Ret = destroy_vi(&pstViCtx[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] destroy_vi failed: %#x!",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId, s32Ret);
}
RK_LOGV("vi [%d, %d, %d] destroy already.",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId);
}
RK_SAFE_FREE(pstViCtx);
return s32Ret;
}
static RK_S32 TEST_DIS_FuncSwitch(VI_CFG_S *pstCtx) {
RK_S32 s32Ret = RK_SUCCESS;
DIS_ATTR_S pstDisAttr;
memset(&pstDisAttr, 0, sizeof(DIS_ATTR_S));
s32Ret = RK_MPI_VI_GetChnDISAttr(pstCtx->s32DevId, pstCtx->s32ChnId, &pstDisAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_GetChnDISAttr failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, s32Ret);
return s32Ret;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_GetChnDISAttr already.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId);
RK_LOGD("vi [%d, %d, %d] dis attr bEnable %d -> %d.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, pstDisAttr.bEnable, !pstDisAttr.bEnable);
pstDisAttr.bEnable = (RK_BOOL)!pstDisAttr.bEnable;
s32Ret = RK_MPI_VI_SetChnDISAttr(pstCtx->s32DevId, pstCtx->s32ChnId, &pstDisAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_SetChnDISAttr failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, s32Ret);
return s32Ret;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetChnDISAttr already.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId);
return s32Ret;
}
static RK_S32 TEST_DIS_CropRatio(VI_CFG_S *pstCtx) {
RK_S32 s32Ret = RK_SUCCESS;
DIS_CONFIG_S pstDisConfig;
RK_U32 tCropRatio = 50;
memset(&pstDisConfig, 0, sizeof(DIS_CONFIG_S));
s32Ret = RK_MPI_VI_GetChnDISConfig(pstCtx->s32DevId, pstCtx->s32ChnId, &pstDisConfig);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_GetChnDISConfig failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, s32Ret);
return s32Ret;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_GetChnDISConfig already.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId);
tCropRatio = pstDisConfig.u32CropRatio;
pstDisConfig.u32CropRatio++;
if (pstDisConfig.u32CropRatio > 98) {
pstDisConfig.u32CropRatio = 50;
}
RK_LOGD("vi [%d, %d, %d] dis config u32CropRatio %d -> %d.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, tCropRatio, pstDisConfig.u32CropRatio);
s32Ret = RK_MPI_VI_SetChnDISConfig(pstCtx->s32DevId, pstCtx->s32ChnId, &pstDisConfig);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_SetChnDISConfig failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, s32Ret);
return s32Ret;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetChnDISConfig already.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId);
return s32Ret;
}
static RK_S32 TEST_DIS_StillCrop(VI_CFG_S *pstCtx) {
RK_S32 s32Ret = RK_SUCCESS;
DIS_ATTR_S pstDisAttr;
memset(&pstDisAttr, 0, sizeof(DIS_ATTR_S));
s32Ret = RK_MPI_VI_GetChnDISAttr(pstCtx->s32DevId, pstCtx->s32ChnId, &pstDisAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_GetChnDISAttr failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, s32Ret);
return s32Ret;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_GetChnDISAttr already.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId);
RK_LOGD("vi [%d, %d, %d] dis attr bStillCrop %d -> %d.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, pstDisAttr.bStillCrop, !pstDisAttr.bStillCrop);
pstDisAttr.bStillCrop = (RK_BOOL)!pstDisAttr.bStillCrop;
s32Ret = RK_MPI_VI_SetChnDISAttr(pstCtx->s32DevId, pstCtx->s32ChnId, &pstDisAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_SetChnDISAttr failed: %#x!",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId, s32Ret);
return s32Ret;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetChnDISAttr already.",
pstCtx->s32DevId, pstCtx->s32PipeId,
pstCtx->s32ChnId);
return s32Ret;
}
static RK_VOID *vi_dis_change_loop(void *pArgs) {
VI_CFG_S *pstCtx = reinterpret_cast<VI_CFG_S *>(pArgs);
RK_S32 s32Ret = RK_SUCCESS;
RK_S32 s32LoopCount = 0;
while (!bExit) {
switch (pstCtx->enChangeMode) {
case TEST_DIS_X_FUNC_SWITCH:
s32Ret = TEST_DIS_FuncSwitch(pstCtx);
break;
case TEST_DIS_X_CROP_RATIO:
s32Ret = TEST_DIS_CropRatio(pstCtx);
break;
case TEST_DIS_X_STILL_CROP:
s32Ret = TEST_DIS_StillCrop(pstCtx);
break;
default:
break;
}
RK_LOGD("dis change loop cnt %d", s32LoopCount++);
usleep(100 * 1000);
}
return RK_NULL;
}
static RK_VOID sigterm_handler(int sig) {
RK_PRINT("signal %d\n", sig);
bExit = RK_TRUE;
}
static RK_S32 test_vi_bind_vo_loop(TEST_DIS_CTX_S *ctx) {
RK_S32 s32Ret = RK_SUCCESS;
RK_S32 s32LoopCount = 0;
VI_CFG_S *pstViCtx = RK_NULL;
VO_CFG_S *pstVoCtx = RK_NULL;
pstViCtx = reinterpret_cast<VI_CFG_S *>(malloc(sizeof(VI_CFG_S) * ctx->u32ViCnt));
pstVoCtx = reinterpret_cast<VO_CFG_S *>(malloc(sizeof(VO_CFG_S) * ctx->u32ViCnt));
pthread_t viThread[VI_MAX_CHN_NUM] = {0};
RK_S32 spiltDispWidth = 0;
RK_S32 spiltDispHeight = 0;
RK_S32 spiltDispColumn = 1;
DIS_CONFIG_S pstDisConfig;
DIS_ATTR_S pstDisAttr;
memset(pstViCtx, 0, sizeof(VI_CFG_S) * ctx->u32ViCnt);
memset(pstVoCtx, 0, sizeof(VO_CFG_S) * ctx->u32ViCnt);
memset(&pstDisConfig, 0, sizeof(DIS_CONFIG_S));
memset(&pstDisAttr, 0, sizeof(DIS_ATTR_S));
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
/* vi config init */
pstViCtx[i].s32DevId = i;
pstViCtx[i].s32PipeId = pstViCtx[i].s32DevId;
pstViCtx[i].enChangeMode = ctx->enChangeMode;
if (ctx->enCompressMode == COMPRESS_MODE_NONE) {
pstViCtx[i].s32ChnId = 0; // main path
} else if (ctx->enCompressMode == COMPRESS_AFBC_16x16) {
pstViCtx[i].s32ChnId = 2; // fbc path
}
pstViCtx[i].stViChnAttr.stSize.u32Width = ctx->u32Width;
pstViCtx[i].stViChnAttr.stSize.u32Height = ctx->u32Height;
pstViCtx[i].stViChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
pstViCtx[i].stViChnAttr.stIspOpt.u32BufCount = 5;
pstViCtx[i].stViChnAttr.u32Depth = 2;
pstViCtx[i].stViChnAttr.enPixelFormat = ctx->enPixelFormat;
pstViCtx[i].stViChnAttr.enCompressMode = ctx->enCompressMode;
pstViCtx[i].stViChnAttr.stFrameRate.s32SrcFrameRate = -1;
pstViCtx[i].stViChnAttr.stFrameRate.s32DstFrameRate = -1;
/* vi create */
s32Ret = create_vi(&pstViCtx[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] create failed: %x",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VI;
}
RK_LOGV("vi [%d, %d, %d] create already.",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId);
/* dis config init */
pstDisConfig.enMode = DIS_MODE_4_DOF_GME;
pstDisConfig.enMotionLevel = DIS_MOTION_LEVEL_NORMAL;
pstDisConfig.u32CropRatio = ctx->u32CropRatio;
pstDisConfig.u32BufNum = ctx->u32DisBufCnt;
pstDisConfig.u32FrameRate = 30;
pstDisConfig.enPdtType = DIS_PDT_TYPE_IPC;
pstDisConfig.u32GyroOutputRange = 0;
pstDisConfig.bCameraSteady = RK_FALSE;
pstDisConfig.u32GyroDataBitWidth = 0;
pstDisAttr.bEnable = RK_TRUE;
pstDisAttr.u32MovingSubjectLevel = 0;
pstDisAttr.s32RollingShutterCoef = 0;
pstDisAttr.u32Timelag = 33333;
pstDisAttr.u32ViewAngle = 1000;
pstDisAttr.bStillCrop = RK_FALSE;
pstDisAttr.u32HorizontalLimit = 512;
pstDisAttr.u32VerticalLimit = 512;
s32Ret = RK_MPI_VI_SetChnDISConfig(pstViCtx[i].s32DevId, pstViCtx[i].s32ChnId, &pstDisConfig);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_SetChnDISConfig failed: %#x!",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VI;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetChnDISConfig already.",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId);
s32Ret = RK_MPI_VI_SetChnDISAttr(pstViCtx[i].s32DevId, pstViCtx[i].s32ChnId, &pstDisAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d,%d] RK_MPI_VI_SetChnDISAttr failed: %#x!",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VI;
}
RK_LOGV("vi [%d, %d, %d] RK_MPI_VI_SetChnDISAttr already.",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId);
}
if (ctx->u32ViCnt <= 4) {
spiltDispColumn = 2;
} else if (ctx->u32ViCnt <= VI_MAX_DEV_NUM) {
spiltDispColumn = 3;
}
spiltDispWidth = 1920 / spiltDispColumn;
spiltDispHeight = 1080 / spiltDispColumn;
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
/* vo config init */
pstVoCtx[i].s32LayerId = 0;
pstVoCtx[i].s32DevId = RK3588_VO_DEV_HDMI;
pstVoCtx[i].s32ChnId = i;
if (RK3588_VO_DEV_HDMI == pstVoCtx[i].s32DevId) {
pstVoCtx[i].stVoLayerAttr.stDispRect.u32Width = 1920;
pstVoCtx[i].stVoLayerAttr.stDispRect.u32Height = 1080;
} else if (RK3588_VO_DEV_MIPI == pstVoCtx[i].s32DevId) {
pstVoCtx[i].stVoLayerAttr.stDispRect.u32Width = 1080;
pstVoCtx[i].stVoLayerAttr.stDispRect.u32Height = 1920;
}
pstVoCtx[i].stVoLayerAttr.enPixFormat = RK_FMT_RGB888;
pstVoCtx[i].stVoCscAttr.enCscMatrix = VO_CSC_MATRIX_IDENTITY;
pstVoCtx[i].stVoCscAttr.u32Contrast = 50;
pstVoCtx[i].stVoCscAttr.u32Hue = 50;
pstVoCtx[i].stVoCscAttr.u32Luma = 50;
pstVoCtx[i].stVoCscAttr.u32Satuature = 50;
pstVoCtx[i].stVoLayerAttr.stDispRect.s32X = 0;
pstVoCtx[i].stVoLayerAttr.stDispRect.s32Y = 0;
pstVoCtx[i].stVoLayerAttr.stImageSize.u32Width =
pstVoCtx[i].stVoLayerAttr.stDispRect.u32Width;
pstVoCtx[i].stVoLayerAttr.stImageSize.u32Height =
pstVoCtx[i].stVoLayerAttr.stDispRect.u32Height;
pstVoCtx[i].stVoLayerAttr.u32DispFrmRt = 30;
pstVoCtx[i].stVoChnAttr.stRect.s32X = spiltDispWidth * (i % spiltDispColumn);
pstVoCtx[i].stVoChnAttr.stRect.s32Y = spiltDispHeight * (i / spiltDispColumn);
pstVoCtx[i].stVoChnAttr.stRect.u32Width = spiltDispWidth;
pstVoCtx[i].stVoChnAttr.stRect.u32Height = spiltDispHeight;
pstVoCtx[i].stVoChnAttr.bDeflicker = RK_FALSE;
pstVoCtx[i].stVoChnAttr.u32Priority = 1;
pstVoCtx[i].stVoChnAttr.u32FgAlpha = 128;
pstVoCtx[i].stVoChnAttr.u32BgAlpha = 0;
/* vo create */
if (0 == i) {
s32Ret = create_vo(&pstVoCtx[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] create failed: %x",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId,
pstVoCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VO;
}
RK_LOGV("vo [%d, %d, %d] create already.",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId,
pstVoCtx[i].s32ChnId);
} else {
s32Ret = RK_MPI_VO_SetChnAttr(pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId, &pstVoCtx[i].stVoChnAttr);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr failed with %#x!",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId,
pstVoCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VO;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr already.",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId,
pstVoCtx[i].s32ChnId);
s32Ret = RK_MPI_VO_EnableChn(pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_EnableChn failedd: %#x!",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId,
pstVoCtx[i].s32ChnId, s32Ret);
goto __DESTROY_VO;
}
RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_EnableChn already.",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId,
pstVoCtx[i].s32ChnId);
}
}
// bind vi to vo
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
s32Ret = TEST_SYS_ViBindVo(pstViCtx[i].s32DevId, pstViCtx[i].s32ChnId,
pstVoCtx[i].s32DevId, pstVoCtx[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("bind failed: %x, vi [%d, %d, %d] -> vo [%d, %d, %d]",
s32Ret, pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId,
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId);
goto __UNBIND_VI_VO;
}
RK_LOGV("bind success, vi [%d, %d, %d] -> vo [%d, %d, %d]",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId,
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId);
}
signal(SIGINT, sigterm_handler);
if (ctx->enChangeMode != TEST_DIS_X_NONE) {
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
pthread_create(&viThread[i], 0, vi_dis_change_loop, reinterpret_cast<void *>(&pstViCtx[i]));
}
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
if (viThread[i])
pthread_join(viThread[i], RK_NULL);
}
} else {
if (ctx->s32LoopCount > 0) {
while (!bExit && s32LoopCount < ctx->s32LoopCount) {
s32LoopCount++;
usleep(33 * 1000);
}
}
}
__UNBIND_VI_VO:
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
s32Ret = TEST_SYS_ViUnbindVo(pstViCtx[i].s32DevId, pstViCtx[i].s32ChnId,
pstVoCtx[i].s32DevId, pstVoCtx[i].s32ChnId);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("unbind failed: %x, vi [%d, %d, %d] -> vo [%d, %d, %d]",
s32Ret, pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId,
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId);
goto __UNBIND_VI_VO;
}
RK_LOGV("unbind success, vi [%d, %d, %d] -> vo [%d, %d, %d]",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId,
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId, pstVoCtx[i].s32ChnId);
}
__DESTROY_VO:
/* destroy vo */
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
s32Ret = destroy_vo(&pstVoCtx[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vo [%d, %d, %d] destroy_vo failed: %#x!",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId,
pstVoCtx[i].s32ChnId, s32Ret);
}
RK_LOGV("vo [%d, %d, %d] destroy_vo already.",
pstVoCtx[i].s32DevId, pstVoCtx[i].s32LayerId,
pstVoCtx[i].s32ChnId);
}
__DESTROY_VI:
/* destroy vi */
for (RK_S32 i = 0; i < ctx->u32ViCnt; i++) {
s32Ret = destroy_vi(&pstViCtx[i]);
if (s32Ret != RK_SUCCESS) {
RK_LOGE("vi [%d, %d, %d] destroy_vi failed: %#x!",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId, s32Ret);
}
RK_LOGV("vi [%d, %d, %d] destroy_vi already.",
pstViCtx[i].s32DevId, pstViCtx[i].s32PipeId,
pstViCtx[i].s32ChnId);
}
RK_SAFE_FREE(pstViCtx);
RK_SAFE_FREE(pstVoCtx);
return s32Ret;
}
static void mpi_dis_test_show_options(const TEST_DIS_CTX_S *ctx) {
RK_PRINT("cmd parse result:\n");
RK_PRINT("loop count : %d\n", ctx->s32LoopCount);
RK_PRINT("test mode : %d\n", ctx->enTestMode);
RK_PRINT("vi dev cnt : %d\n", ctx->u32ViCnt);
RK_PRINT("vi pixel format : %d\n", ctx->enPixelFormat);
RK_PRINT("vi compress mode : %d\n", ctx->enCompressMode);
RK_PRINT("vi output width : %d\n", ctx->u32Width);
RK_PRINT("vi output hight : %d\n", ctx->u32Height);
RK_PRINT("vi enable pic : %d\n", ctx->bUserPicEnabled);
RK_PRINT("user pic file : %s\n", ctx->pUserPicFile);
RK_PRINT("vi out buf cnt : %d\n", ctx->u32ViBufCnt);
RK_PRINT("dis out buf cnt : %d\n", ctx->u32DisBufCnt);
RK_PRINT("dis crop ratio : %d\n", ctx->u32CropRatio);
}
static const char *const usages[] = {
"./rk_mpi_dis_test -w 1920 -h 1080",
RK_NULL,
};
int main(int argc, const char **argv) {
RK_S32 s32Ret = RK_FAILURE;
TEST_DIS_CTX_S ctx;
memset(&ctx, 0, sizeof(TEST_DIS_CTX_S));
ctx.enTestMode = TEST_DIS_MODE_BIND_VO;
ctx.s32LoopCount = 100;
ctx.u32ViCnt = 1;
ctx.u32ViBufCnt = 3;
ctx.u32DisBufCnt = 5;
ctx.u32CropRatio = 80;
ctx.enChangeMode = TEST_DIS_X_STILL_CROP;
RK_LOGE("test running enter!");
struct argparse_option options[] = {
OPT_HELP(),
OPT_GROUP("basic options:"),
OPT_INTEGER('\0', "test_mode", &(ctx.enTestMode),
"test mode (default 1, 0:vi get&release frame; 1:vi bind vo (HDMI).", NULL, 0, 0),
OPT_INTEGER('\0', "vi_cnt", &(ctx.u32ViCnt),
"vi dev cnt (default 1).", NULL, 0, 0),
OPT_INTEGER('n', "loop_count", &(ctx.s32LoopCount),
"set capture frame count (default 100).", NULL, 0, 0),
OPT_STRING('o', "output", &(ctx.pDstFilePath),
"output file path. e.g.(/userdata/dis/). default(NULL).", NULL, 0, 0),
OPT_GROUP("vi options:"),
OPT_INTEGER('m', "src_compress", &(ctx.enCompressMode),
"set capture compress mode (default 0, 0: NONE; 1: AFBC).", NULL, 0, 0),
OPT_INTEGER('w', "width", &(ctx.u32Width),
"set capture channel width (default 0) <required>.", NULL, 0, 0),
OPT_INTEGER('h', "height", &(ctx.u32Height),
"set capture channel height (default 0) <required>.", NULL, 0, 0),
OPT_INTEGER('f', "format", &(ctx.enPixelFormat),
"set the format (default 0, 0:RK_FMT_YUV420SP).", NULL, 0, 0),
OPT_INTEGER('U', "user_pic", &(ctx.bUserPicEnabled),
"enable using user specify picture as vi input.", NULL, 0, 0),
OPT_STRING('\0', "usr_pic_file", &(ctx.pUserPicFile),
"user specify picture file.", NULL, 0, 0),
OPT_INTEGER('\0', "vi_buf_count", &(ctx.u32ViBufCnt),
"vi out buf count, range[1, 8] (default 3).", NULL, 0, 0),
OPT_GROUP("dis options:"),
OPT_INTEGER('\0', "dis_buf_count", &(ctx.u32DisBufCnt),
"dis out buf count, range[1, 8] (default 5).", NULL, 0, 0),
OPT_INTEGER('\0', "crop_ratio", &(ctx.u32CropRatio),
"dis out buf count, range[50, 98] (default 80).", NULL, 0, 0),
OPT_GROUP("dis change test options:"),
OPT_INTEGER('\0', "change_test", &(ctx.enChangeMode),
"dis params dynamic change test, "
"(default 0. 0: NONE, 1: function switch, "
"2: crop ratio change, 3: still crop switch).", 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.u32Width || !ctx.u32Height) {
argparse_usage(&argparse);
goto __FAILED;
}
mpi_dis_test_show_options(&ctx);
s32Ret = RK_MPI_SYS_Init();
if (RK_SUCCESS != s32Ret) {
RK_LOGE("rk mpi sys init fail!");
goto __FAILED;
}
switch (ctx.enTestMode) {
case TEST_DIS_MODE_VI_ONLY:
s32Ret = test_vi_get_release_frame_loop(&ctx);
break;
case TEST_DIS_MODE_BIND_VO:
s32Ret = test_vi_bind_vo_loop(&ctx);
break;
default:
RK_LOGE("unsupport such test mode:%d", ctx.enTestMode);
break;
}
__FAILED:
RK_LOGE("test running exit:%d", s32Ret);
RK_MPI_SYS_Exit();
return 0;
}