2571 lines
90 KiB
C++
2571 lines
90 KiB
C++
/*
|
|
* 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 <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sys/prctl.h>
|
|
#include <pthread.h>
|
|
|
|
#include "rk_debug.h"
|
|
#include "rk_mpi_sys.h"
|
|
#include "rk_mpi_vo.h"
|
|
#include "rk_mpi_vdec.h"
|
|
#include "rk_mpi_mb.h"
|
|
#include "rk_common.h"
|
|
|
|
#include "test_comm_argparse.h"
|
|
#include "test_comm_utils.h"
|
|
|
|
#define MAX_FRAME_QUEUE 8
|
|
#define MAX_TIME_OUT_MS 20
|
|
|
|
#ifndef VDEC_INT64_MIN
|
|
#define VDEC_INT64_MIN (-0x7fffffffffffffffLL-1)
|
|
#endif
|
|
|
|
#ifndef VDEC_INT64_MAX
|
|
#define VDEC_INT64_MAX INT64_C(9223372036854775807)
|
|
#endif
|
|
|
|
#ifndef rk_safe_free
|
|
#define rk_safe_free(p) { if (p) {free(p); (p)=RK_NULL;} }
|
|
#endif
|
|
|
|
#ifndef rk_safe_delete
|
|
#define rk_safe_delete(p) { if (p) {delete(p); (p)=RK_NULL;} }
|
|
#endif
|
|
|
|
#define VDEC_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
|
|
|
|
typedef struct rkVO_Timing_S {
|
|
RK_S32 enIntfSync;
|
|
RK_U32 u32Width;
|
|
RK_U32 u32Height;
|
|
} VO_Timing_S;
|
|
|
|
typedef struct _rkWbcCfg {
|
|
VO_WBC_SOURCE_S stWbcSource;
|
|
VO_WBC_ATTR_S stWbcAttr;
|
|
RK_S32 s32ChnId;
|
|
RK_S32 s32VdecChnId;
|
|
} WBC_CFG;
|
|
|
|
typedef struct _rkVdecCfg {
|
|
RK_U32 u32FrameBufferCnt;
|
|
COMPRESS_MODE_E enCompressMode;
|
|
} VDEC_CFG;
|
|
|
|
typedef struct _rkVOCfg {
|
|
RK_U32 u32Screen0VoLayer;
|
|
RK_U32 u32Screen1VoLayer;
|
|
|
|
RK_U32 u32Screen0Rows;
|
|
RK_U32 u32Screen1Rows;
|
|
RK_BOOL bDoubleScreen;
|
|
} VO_CFG;
|
|
|
|
typedef struct _rkParserCfg {
|
|
char *srcFileUri[VDEC_MAX_CHN_NUM];
|
|
RK_CODEC_ID_E enCodecId;
|
|
RK_U32 u32SrcWidth;
|
|
RK_U32 u32SrcHeight;
|
|
RK_U32 u32StreamIndex;
|
|
void *pExtraData;
|
|
RK_U32 u32ExtraDataSize;
|
|
} PARSER_CFG;
|
|
|
|
typedef struct _rkBorderCfg {
|
|
RK_U32 u32LeftWidth;
|
|
RK_U32 u32RightWidth;
|
|
RK_U32 u32TopWidth;
|
|
RK_U32 u32BottomWidth;
|
|
} Border_CFG;
|
|
|
|
#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 RK356X_VO_DEV_HD0 0
|
|
#define RK356X_VO_DEV_HD1 1
|
|
|
|
#define DISPLAY_TYPE_HDMI 0
|
|
#define DISPLAY_TYPE_EDP 1
|
|
#define DISPLAY_TYPE_VGA 2
|
|
#define DISPLAY_TYPE_DP 3
|
|
#define DISPLAY_TYPE_HDMI_EDP 4
|
|
|
|
typedef struct _PixelFormatMap {
|
|
RK_U32 index;
|
|
PIXEL_FORMAT_E format;
|
|
} PixelFormatMap;
|
|
|
|
const static PixelFormatMap testPixelFormat[] = {
|
|
// usual yuv/rga formats
|
|
{1, RK_FMT_YUV420SP},
|
|
{2, RK_FMT_YUV420SP_VU},
|
|
{3, RK_FMT_RGB565},
|
|
{4, RK_FMT_BGR565},
|
|
{5, RK_FMT_RGB888},
|
|
{6, RK_FMT_BGR888},
|
|
{7, RK_FMT_BGRA8888},
|
|
{8, RK_FMT_RGBA8888},
|
|
{9, RK_FMT_RGBA5551},
|
|
{10, RK_FMT_BGRA5551}
|
|
};
|
|
|
|
#define MAX_VO_FORMAT_RGB_NUM 17
|
|
#define WBC_FORMAT_BGRA8888 0
|
|
#define WBC_FORMAT_RGBA8888 1
|
|
#define WBC_FORMAT_RGB888 2
|
|
#define WBC_FORMAT_BGR888 3
|
|
#define WBC_FORMAT_YUV420SP 4
|
|
#define WBC_FORMAT_YUV420SP_VU 5
|
|
|
|
#define VO_CHANNEL_PLAY_NORMAL 0
|
|
#define VO_CHANNEL_PLAY_PAUSE 1
|
|
#define VO_CHANNEL_PLAY_STEP 2
|
|
#define VO_CHANNEL_PLAY_SPEED 3
|
|
|
|
#define WBC_SOURCE_DEV 0
|
|
#define WBC_SOURCE_VIDEO 1
|
|
#define WBC_SOURCE_GRAPHIC 2
|
|
|
|
#define MAX_WINDOWS_NUM 64
|
|
#define MAX_STEP_FRAME_NUM 50
|
|
|
|
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
|
|
|
typedef struct _TEST_MODE {
|
|
RK_U32 mode;
|
|
VO_INTF_SYNC_E enIntfSync;
|
|
} TEST_MODE_S;
|
|
|
|
static VO_DEV VoLayer = RK356X_VOP_LAYER_CLUSTER_0;
|
|
static VO_DEV VoLayer_second = RK356X_VOP_LAYER_CLUSTER_1;
|
|
|
|
TEST_MODE_S test_mode_table[] = {
|
|
{0, VO_OUTPUT_640x480_60},
|
|
{1, VO_OUTPUT_PAL},
|
|
{2, VO_OUTPUT_576P50},
|
|
{3, VO_OUTPUT_NTSC},
|
|
{4, VO_OUTPUT_480P60},
|
|
{5, VO_OUTPUT_800x600_60},
|
|
{6, VO_OUTPUT_1024x768_60},
|
|
{7, VO_OUTPUT_720P50},
|
|
{8, VO_OUTPUT_720P60},
|
|
{9, VO_OUTPUT_1280x1024_60},
|
|
{10, VO_OUTPUT_1080P24},
|
|
{11, VO_OUTPUT_1080P25},
|
|
{12, VO_OUTPUT_1080P30},
|
|
{13, VO_OUTPUT_1080I50},
|
|
{14, VO_OUTPUT_1080I60},
|
|
{15, VO_OUTPUT_1080P50},
|
|
{16, VO_OUTPUT_1080P60},
|
|
{17, VO_OUTPUT_3840x2160_24},
|
|
{18, VO_OUTPUT_3840x2160_25},
|
|
{19, VO_OUTPUT_3840x2160_30},
|
|
{20, VO_OUTPUT_3840x2160_50},
|
|
{21, VO_OUTPUT_3840x2160_60},
|
|
{22, VO_OUTPUT_4096x2160_24},
|
|
{23, VO_OUTPUT_4096x2160_25},
|
|
{24, VO_OUTPUT_4096x2160_30},
|
|
{25, VO_OUTPUT_4096x2160_50},
|
|
{26, VO_OUTPUT_4096x2160_60},
|
|
};
|
|
|
|
static VO_Timing_S stVoTimings[] = {
|
|
{VO_OUTPUT_640x480_60, 640, 480},
|
|
{VO_OUTPUT_800x600_60, 800, 600},
|
|
{VO_OUTPUT_1024x768_60, 1024, 768},
|
|
{VO_OUTPUT_1280x1024_60, 1280, 1024},
|
|
{VO_OUTPUT_1366x768_60, 1366, 768},
|
|
{VO_OUTPUT_1440x900_60, 1440, 900},
|
|
{VO_OUTPUT_1280x800_60, 1280, 800},
|
|
{VO_OUTPUT_1600x1200_60, 1600, 1200},
|
|
{VO_OUTPUT_1680x1050_60, 1680, 1050},
|
|
{VO_OUTPUT_1920x1200_60, 1920, 1200},
|
|
};
|
|
static void Sample_VO_GetDisplaySize(RK_S32 enIntfSync, RK_U32 *s32W, RK_U32 *s32H) {
|
|
switch (enIntfSync) {
|
|
case VO_OUTPUT_640x480_60:
|
|
*s32W = 640;
|
|
*s32H = 480;
|
|
break;
|
|
case VO_OUTPUT_PAL:
|
|
case VO_OUTPUT_576P50:
|
|
*s32W = 720;
|
|
*s32H = 576;
|
|
break;
|
|
case VO_OUTPUT_NTSC:
|
|
case VO_OUTPUT_480P60:
|
|
*s32W = 720;
|
|
*s32H = 480;
|
|
break;
|
|
case VO_OUTPUT_800x600_60:
|
|
*s32W = 800;
|
|
*s32H = 600;
|
|
break;
|
|
case VO_OUTPUT_1024x768_60:
|
|
*s32W = 1024;
|
|
*s32H = 768;
|
|
break;
|
|
case VO_OUTPUT_720P50:
|
|
case VO_OUTPUT_720P60:
|
|
*s32W = 1280;
|
|
*s32H = 720;
|
|
break;
|
|
case VO_OUTPUT_1280x1024_60:
|
|
*s32W = 1280;
|
|
*s32H = 1024;
|
|
break;
|
|
case VO_OUTPUT_1080P24:
|
|
case VO_OUTPUT_1080P25:
|
|
case VO_OUTPUT_1080P30:
|
|
case VO_OUTPUT_1080I50:
|
|
case VO_OUTPUT_1080I60:
|
|
case VO_OUTPUT_1080P50:
|
|
case VO_OUTPUT_1080P60:
|
|
*s32W = 1920;
|
|
*s32H = 1080;
|
|
break;
|
|
case VO_OUTPUT_3840x2160_24:
|
|
case VO_OUTPUT_3840x2160_25:
|
|
case VO_OUTPUT_3840x2160_30:
|
|
case VO_OUTPUT_3840x2160_50:
|
|
case VO_OUTPUT_3840x2160_60:
|
|
*s32W = 3840;
|
|
*s32H = 2160;
|
|
break;
|
|
case VO_OUTPUT_4096x2160_24:
|
|
case VO_OUTPUT_4096x2160_25:
|
|
case VO_OUTPUT_4096x2160_30:
|
|
case VO_OUTPUT_4096x2160_50:
|
|
case VO_OUTPUT_4096x2160_60:
|
|
*s32W = 4096;
|
|
*s32H = 2160;
|
|
break;
|
|
default:
|
|
for (RK_S32 i = 0; i < ARRAY_LENGTH(stVoTimings); i++) {
|
|
if (stVoTimings[i].enIntfSync == enIntfSync) {
|
|
*s32W = stVoTimings[i].u32Width;
|
|
*s32H = stVoTimings[i].u32Height;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define Sample_Print(format, ...) RK_LOGI(format, ##__VA_ARGS__)
|
|
|
|
typedef struct _rkMpiVOCtx {
|
|
RK_S32 VoDev;
|
|
RK_S32 VoLayer;
|
|
RK_S32 VoLayerMode;
|
|
|
|
RK_S32 u32Windows;
|
|
RK_U32 enIntfType; /* 0 HDMI 1 edp */
|
|
RK_U32 enIntfSync; /* VO_OUTPUT_1080P50 */
|
|
RK_U32 enIntfSync_second;
|
|
RK_U32 s32X;
|
|
RK_U32 s32Y;
|
|
|
|
RK_U32 u32Screen0DisplayWidth;
|
|
RK_U32 u32Screen0DisplayHeight;
|
|
RK_U32 u32Screen1DisplayWidth;
|
|
RK_U32 u32Screen1DisplayHeight;
|
|
|
|
RK_U32 u32Screen0ImageWidth;
|
|
RK_U32 u32Screen0ImageHeight;
|
|
RK_U32 u32Screen1ImageWidth;
|
|
RK_U32 u32Screen1ImageHeight;
|
|
|
|
RK_U32 bDoubleScreen;
|
|
RK_U32 u32DispWidth;
|
|
RK_U32 u32DispHeight;
|
|
RK_U32 u32ImgeWidth;
|
|
RK_U32 u32ImageHeight;
|
|
RK_U32 s32PixFormat;
|
|
RK_U32 u32DispFrmRt;
|
|
RK_U32 u32DispFrmRtRatio;
|
|
RK_U32 uEnMode;
|
|
RK_BOOL bBorder;
|
|
RK_S32 loopCount;
|
|
|
|
RK_U32 wbc_enable;
|
|
RK_BOOL wbc_auto;
|
|
RK_U32 ui;
|
|
RK_U32 ui_alpha;
|
|
RK_U32 u32WbcWidth;
|
|
RK_S32 u32WbcHeight;
|
|
COMPRESS_MODE_E u32WbcCompressMode;
|
|
RK_S32 u32WbcPixFormat;
|
|
RK_U32 u32WbcSourceType;
|
|
RK_U32 u32WbcSourceId;
|
|
|
|
VO_LAYER VoVideoLayer;
|
|
RK_U32 u32VideoWindows;
|
|
RK_U32 u32GFXLayers;
|
|
VO_LAYER VOGfxLayer;
|
|
RK_BOOL threadExit;
|
|
|
|
RK_BOOL bVoPlay;
|
|
const char *cfgFileUri;
|
|
RK_S32 s32LoopCount;
|
|
RK_U32 u32ChnIndex;
|
|
RK_U32 u32Screen0Chn;
|
|
RK_U32 u32ChnDismode;
|
|
RK_U32 u32Screen1Chn;
|
|
RK_BOOL bThreadExit;
|
|
|
|
RK_BOOL bEnWbc;
|
|
RK_BOOL bEnWbcToVO;
|
|
RK_BOOL bChnPriority;
|
|
|
|
PARSER_CFG stParserCfg;
|
|
VDEC_CFG stVdecCfg;
|
|
VO_CFG stVoCfg;
|
|
WBC_CFG stWbcCfg;
|
|
RK_BOOL wbc_bind;
|
|
RK_U32 bHomologous;
|
|
Border_CFG stBorderCfg;
|
|
} TEST_VO_CTX_S;
|
|
|
|
typedef struct _VO_Send_Thread_Param {
|
|
RK_U32 u32VideoWindows;
|
|
VO_LAYER VoVideoLayer;
|
|
RK_U32 u32GFXLayers;
|
|
VO_LAYER VOGfxLayer;
|
|
RK_U32 u32Exit;
|
|
} VoThreadParam;
|
|
|
|
static RK_S32 SampleSetVoInterfacetiming(VO_PUB_ATTR_S *stVoPubAttr, RK_U32 enIntfSync) {
|
|
RK_U32 i;
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(test_mode_table); i++) {
|
|
if (enIntfSync == test_mode_table[i].mode)
|
|
break;
|
|
}
|
|
|
|
if (i == ARRAY_LENGTH(test_mode_table)) {
|
|
Sample_Print("%s not found supported mode in test mode_table\n", __func__);
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
stVoPubAttr->enIntfSync = test_mode_table[i].enIntfSync;
|
|
|
|
return s32Ret;
|
|
}
|
|
static PIXEL_FORMAT_E Sample_wbc_formt(RK_S32 format) {
|
|
switch (format) {
|
|
case WBC_FORMAT_BGRA8888:
|
|
return RK_FMT_BGRA8888;
|
|
case WBC_FORMAT_RGBA8888:
|
|
return RK_FMT_RGBA8888;
|
|
case WBC_FORMAT_RGB888:
|
|
return RK_FMT_RGB888;
|
|
case WBC_FORMAT_BGR888:
|
|
return RK_FMT_BGR888;
|
|
case WBC_FORMAT_YUV420SP:
|
|
return RK_FMT_YUV420SP;
|
|
case WBC_FORMAT_YUV420SP_VU:
|
|
return RK_FMT_YUV420SP_VU;
|
|
default:
|
|
return RK_FMT_BUTT;
|
|
}
|
|
}
|
|
|
|
static void* vochn_test_thread_func(void *pArgs) {
|
|
TEST_VO_CTX_S *ctx = reinterpret_cast<TEST_VO_CTX_S *>(pArgs);
|
|
RK_S32 i, j;
|
|
|
|
while (1) {
|
|
if (ctx->u32ChnDismode == VO_CHANNEL_PLAY_PAUSE) {
|
|
for (i = 0; i < ctx->u32Screen0Chn; i++) {
|
|
RK_MPI_VO_PauseChn(VoLayer, i);
|
|
}
|
|
|
|
usleep(1000llu * 2000);
|
|
|
|
for (i = 0; i < ctx->u32Screen0Chn; i++) {
|
|
RK_MPI_VO_ResumeChn(VoLayer, i);
|
|
}
|
|
} else if (ctx->u32ChnDismode == VO_CHANNEL_PLAY_STEP) {
|
|
for (i = 0; i < ctx->u32Screen0Chn; i++) {
|
|
for (RK_S32 j = 0; j < MAX_STEP_FRAME_NUM; j++) {
|
|
RK_MPI_VO_StepChn(VoLayer, i);
|
|
}
|
|
}
|
|
|
|
usleep(1000llu * 2000);
|
|
|
|
for (i = 0; i < ctx->u32Screen0Chn; i++) {
|
|
RK_MPI_VO_ResumeChn(VoLayer, i);
|
|
}
|
|
} else if (ctx->u32ChnDismode == VO_CHANNEL_PLAY_SPEED) {
|
|
for (i = 0; i < ctx->u32Screen0Chn; i++) {
|
|
RK_MPI_VO_SetChnFrameRate(VoLayer, i, ctx->u32DispFrmRt * ctx->u32DispFrmRtRatio);
|
|
}
|
|
|
|
usleep(1000llu * 2000);
|
|
|
|
for (i = 0; i < ctx->u32Screen0Chn; i++) {
|
|
RK_MPI_VO_ResumeChn(VoLayer, i);
|
|
}
|
|
}
|
|
|
|
if (ctx->stVoCfg.bDoubleScreen) {
|
|
if (ctx->u32ChnDismode == VO_CHANNEL_PLAY_PAUSE) {
|
|
for (i = 0; i < ctx->u32Screen1Chn; i++) {
|
|
RK_MPI_VO_PauseChn(VoLayer_second, i);
|
|
}
|
|
usleep(1000llu * 2000);
|
|
for (i = 0; i < ctx->u32Screen1Chn; i++) {
|
|
RK_MPI_VO_ResumeChn(VoLayer_second, i);
|
|
}
|
|
} else if (ctx->u32ChnDismode == VO_CHANNEL_PLAY_STEP) {
|
|
for (i = 0; i < ctx->u32Screen1Chn; i++) {
|
|
for (RK_S32 j = 0; j < MAX_STEP_FRAME_NUM; j++) {
|
|
RK_MPI_VO_StepChn(VoLayer_second, i);
|
|
}
|
|
}
|
|
|
|
usleep(1000llu * 2000);
|
|
|
|
for (i = 0; i < ctx->u32Screen1Chn; i++) {
|
|
RK_MPI_VO_ResumeChn(VoLayer_second, i);
|
|
}
|
|
} else if (ctx->u32ChnDismode == VO_CHANNEL_PLAY_SPEED) {
|
|
for (i = 0; i < ctx->u32Screen1Chn; i++) {
|
|
RK_MPI_VO_SetChnFrameRate(VoLayer_second, i, ctx->u32DispFrmRt * ctx->u32DispFrmRtRatio);
|
|
}
|
|
|
|
usleep(1000llu * 2000);
|
|
|
|
for (i = 0; i < ctx->u32Screen1Chn; i++) {
|
|
RK_MPI_VO_ResumeChn(VoLayer_second, i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return RK_NULL;
|
|
}
|
|
|
|
static RK_S32 mpi_vo_init_sample(const TEST_VO_CTX_S *ctx, RK_S32 primRows , RK_S32 secondRows) {
|
|
VO_PUB_ATTR_S VoPubAttr;
|
|
VO_VIDEO_LAYER_ATTR_S stLayerAttr;
|
|
VO_CSC_S VideoCSC;
|
|
VO_CHN_ATTR_S VoChnAttr[64];
|
|
VO_BORDER_S border;
|
|
RK_S32 i;
|
|
RK_U32 count = 0;
|
|
RK_U32 u32DispBufLen;
|
|
RK_U32 s32Ret;
|
|
RK_U32 u32DispWidth = ctx->u32DispWidth;
|
|
RK_U32 u32DispHeight = ctx->u32DispHeight;
|
|
RK_U32 u32ImageWidth = u32DispWidth;
|
|
RK_U32 u32ImageHeight = u32DispHeight;
|
|
|
|
memset(&VoPubAttr, 0, sizeof(VO_PUB_ATTR_S));
|
|
memset(&stLayerAttr, 0, sizeof(VO_VIDEO_LAYER_ATTR_S));
|
|
memset(&VideoCSC, 0, sizeof(VO_CSC_S));
|
|
memset(&VoChnAttr, 0, sizeof(VoChnAttr));
|
|
memset(&border, 0, sizeof(VO_BORDER_S));
|
|
|
|
VoPubAttr.enIntfType = VO_INTF_HDMI;
|
|
VoPubAttr.enIntfSync = VO_OUTPUT_1080P60;
|
|
|
|
s32Ret = RK_MPI_VO_SetPubAttr(RK356X_VO_DEV_HD0, &VoPubAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_Enable(RK356X_VO_DEV_HD0);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
if (ctx->stVoCfg.bDoubleScreen) {
|
|
VO_PUB_ATTR_S VoPubAttr1;
|
|
VoPubAttr1.enIntfType = VO_INTF_EDP;
|
|
VoPubAttr1.enIntfSync = VO_OUTPUT_1024x768_60;
|
|
VoPubAttr1.u32BgColor = 0x000000;
|
|
s32Ret = RK_MPI_VO_SetPubAttr(RK356X_VO_DEV_HD1, &VoPubAttr1);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_Enable(RK356X_VO_DEV_HD1);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VO_GetLayerDispBufLen(VoLayer_second, &u32DispBufLen);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("Get display buf len failed with error code %d!\n", s32Ret);
|
|
return s32Ret;
|
|
}
|
|
u32DispBufLen = 4;
|
|
s32Ret = RK_MPI_VO_SetLayerDispBufLen(VoLayer_second, u32DispBufLen);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
}
|
|
|
|
s32Ret = RK_MPI_VO_GetLayerDispBufLen(VoLayer, &u32DispBufLen);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("Get display buf len failed with error code %d!\n", s32Ret);
|
|
return s32Ret;
|
|
}
|
|
u32DispBufLen = 4;
|
|
s32Ret = RK_MPI_VO_SetLayerDispBufLen(VoLayer, u32DispBufLen);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
Sample_VO_GetDisplaySize(VoPubAttr.enIntfSync, &u32DispWidth, &u32DispHeight);
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
stLayerAttr.stDispRect.u32Width = u32DispWidth;
|
|
stLayerAttr.stDispRect.u32Height = u32DispHeight;
|
|
stLayerAttr.stImageSize.u32Width = u32ImageWidth;
|
|
stLayerAttr.stImageSize.u32Height = u32ImageHeight;
|
|
|
|
stLayerAttr.u32DispFrmRt = 30;
|
|
if (VoLayer == RK356X_VOP_LAYER_ESMART_0) {
|
|
stLayerAttr.enPixFormat = RK_FMT_YUV420SP;
|
|
} else {
|
|
stLayerAttr.enPixFormat = RK_FMT_RGBA8888;
|
|
}
|
|
VideoCSC.enCscMatrix = VO_CSC_MATRIX_IDENTITY;
|
|
VideoCSC.u32Contrast = 50;
|
|
VideoCSC.u32Hue = 50;
|
|
VideoCSC.u32Luma = 50;
|
|
VideoCSC.u32Satuature = 50;
|
|
|
|
s32Ret = RK_MPI_VO_SetLayerAttr(VoLayer, &stLayerAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_EnableLayer(VoLayer);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_SetLayerCSC(VoLayer, &VideoCSC);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
|
|
RK_S32 totalCH = primRows * primRows;
|
|
for (i = 0; i < totalCH; i++) {
|
|
VoChnAttr[i].bDeflicker = RK_FALSE;
|
|
VoChnAttr[i].u32Priority = 1;
|
|
VoChnAttr[i].stRect.s32X = (u32ImageWidth/primRows)*(i%primRows);
|
|
VoChnAttr[i].stRect.s32Y = (u32ImageHeight/primRows)*(i/primRows);
|
|
VoChnAttr[i].stRect.u32Width = u32ImageWidth/primRows;
|
|
VoChnAttr[i].stRect.u32Width = VoChnAttr[i].stRect.u32Width;
|
|
VoChnAttr[i].stRect.u32Height = u32ImageHeight/primRows;
|
|
VoChnAttr[i].stRect.u32Height = VoChnAttr[i].stRect.u32Height;
|
|
}
|
|
|
|
for (i = 0; i < totalCH; i++) {
|
|
RK_S32 s32ret = RK_MPI_VO_SetChnAttr(VoLayer, i, &VoChnAttr[i]);
|
|
if (RK_SUCCESS != s32ret) {
|
|
RK_LOGE("vo set dev %d chn %d attr failed! \n", VoLayer, i);
|
|
}
|
|
border.bBorderEn = RK_TRUE;
|
|
border.stBorder.u32Color = 0x191970;
|
|
border.stBorder.u32LeftWidth = 2;
|
|
border.stBorder.u32RightWidth = 2;
|
|
border.stBorder.u32TopWidth = 2;
|
|
border.stBorder.u32BottomWidth = 2;
|
|
s32Ret = RK_MPI_VO_SetChnBorder(VoLayer, i, &border);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
}
|
|
|
|
if (ctx->stVoCfg.bDoubleScreen) {
|
|
u32DispWidth = ctx->u32Screen1DisplayWidth;
|
|
u32DispHeight = ctx->u32Screen1DisplayHeight;
|
|
u32ImageWidth = u32DispWidth;
|
|
u32ImageHeight = u32DispHeight;
|
|
Sample_VO_GetDisplaySize(VO_OUTPUT_1024x768_60, &u32DispWidth, &u32DispHeight);
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
stLayerAttr.stDispRect.u32Width = u32DispWidth;
|
|
stLayerAttr.stDispRect.u32Height = u32DispHeight;
|
|
stLayerAttr.stImageSize.u32Width = u32ImageWidth;
|
|
stLayerAttr.stImageSize.u32Height = u32ImageHeight;
|
|
|
|
stLayerAttr.u32DispFrmRt = 30;
|
|
if (VoLayer_second == RK356X_VOP_LAYER_ESMART_1) {
|
|
stLayerAttr.enPixFormat = RK_FMT_YUV420SP;
|
|
} else {
|
|
stLayerAttr.enPixFormat = RK_FMT_BGR888;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VO_SetLayerAttr(VoLayer_second, &stLayerAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_EnableLayer(VoLayer_second);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_SetLayerCSC(VoLayer_second, &VideoCSC);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
|
|
totalCH = secondRows * secondRows;
|
|
for (i = 0; i < totalCH; i++) {
|
|
VoChnAttr[i].bDeflicker = RK_FALSE;
|
|
VoChnAttr[i].u32Priority = 1;
|
|
VoChnAttr[i].stRect.s32X = (u32ImageWidth/secondRows)*(i%secondRows);
|
|
VoChnAttr[i].stRect.s32Y = (u32ImageHeight/secondRows)*(i/secondRows);
|
|
VoChnAttr[i].stRect.u32Width = u32ImageWidth/secondRows;
|
|
VoChnAttr[i].stRect.u32Width = VoChnAttr[i].stRect.u32Width;
|
|
VoChnAttr[i].stRect.u32Height = u32ImageHeight/secondRows;
|
|
VoChnAttr[i].stRect.u32Height = VoChnAttr[i].stRect.u32Height;
|
|
}
|
|
/* demo Chn Priority test */
|
|
if (ctx->bChnPriority) {
|
|
VoChnAttr[0].u32Priority = 15;
|
|
|
|
VoChnAttr[1].u32Priority = 10;
|
|
VoChnAttr[1].stRect.s32X = (u32ImageWidth/secondRows)*(1%secondRows) - 100;
|
|
VoChnAttr[1].stRect.s32Y = (u32ImageHeight/secondRows)*(1/secondRows) + 100;
|
|
VoChnAttr[1].stRect.u32Width = u32ImageWidth/secondRows + 200;
|
|
VoChnAttr[1].stRect.u32Width = VoChnAttr[1].stRect.u32Width;
|
|
VoChnAttr[1].stRect.u32Height = u32ImageWidth/secondRows + 200;
|
|
VoChnAttr[1].stRect.u32Height = VoChnAttr[1].stRect.u32Height;
|
|
|
|
VoChnAttr[2].u32Priority = 5;
|
|
}
|
|
|
|
for (i = 0; i < totalCH; i++) {
|
|
RK_S32 s32ret = RK_MPI_VO_SetChnAttr(VoLayer_second, i, &VoChnAttr[i]);
|
|
if (RK_SUCCESS != s32ret) {
|
|
RK_LOGE("vo set dev %d chn %d attr failed! \n", VoLayer_second, i);
|
|
}
|
|
border.bBorderEn = RK_TRUE;
|
|
border.stBorder.u32Color = 0x191970;
|
|
border.stBorder.u32LeftWidth = 2;
|
|
border.stBorder.u32RightWidth = 2;
|
|
border.stBorder.u32TopWidth = 2;
|
|
border.stBorder.u32BottomWidth = 2;
|
|
s32Ret = RK_MPI_VO_SetChnBorder(VoLayer_second, i, &border);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
|
|
static RK_S32 mpi_vo_deinit_sample(const TEST_VO_CTX_S *ctx) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
s32Ret = RK_MPI_VO_DisableLayer(VoLayer);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
if (ctx->stVoCfg.bDoubleScreen) {
|
|
s32Ret = RK_MPI_VO_DisableLayer(VoLayer_second);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
}
|
|
|
|
s32Ret = RK_MPI_VO_Disable(RK356X_VO_DEV_HD0);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
if (ctx->stVoCfg.bDoubleScreen) {
|
|
s32Ret = RK_MPI_VO_Disable(RK356X_VO_DEV_HD1);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
}
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
|
|
static RK_S32 open_config(TEST_VO_CTX_S *ctx) {
|
|
FILE *fp = RK_NULL;
|
|
RK_U32 u32Count = 0;
|
|
RK_U32 u32FileLen = 0;
|
|
RK_U32 u32Len = 0;
|
|
RK_S32 s32Ret = 0;
|
|
char *line = RK_NULL;
|
|
char *pBuffer = RK_NULL;
|
|
|
|
if ((fp = fopen(ctx->cfgFileUri, "r")) == RK_NULL) {
|
|
RK_LOGE("Error! opening file");
|
|
return RK_FAILURE;
|
|
}
|
|
fseek(fp, 0L, SEEK_END);
|
|
u32FileLen = ftell(fp);
|
|
fseek(fp, 0, SEEK_SET);
|
|
|
|
size_t sLen = 0;
|
|
size_t read = 0;
|
|
while (read = getline(&line, &sLen, fp) != -1) {
|
|
pBuffer = reinterpret_cast<char *>(malloc(strlen(line)));
|
|
RK_S32 len = strlen(line);
|
|
snprintf(pBuffer, strlen(line), "%s", line);
|
|
while (len) {
|
|
if (pBuffer[len] == '\r') {
|
|
memcpy(&(pBuffer[len]), &(pBuffer[len + 1]), strlen(line) - len);
|
|
}
|
|
len--;
|
|
}
|
|
ctx->stParserCfg.srcFileUri[u32Count] = pBuffer;
|
|
|
|
RK_LOGI("url %s", ctx->stParserCfg.srcFileUri[u32Count]);
|
|
u32Count++;
|
|
|
|
if (u32Count >= VDEC_MAX_CHN_NUM)
|
|
break;
|
|
}
|
|
|
|
fclose(fp);
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 close_config(TEST_VO_CTX_S *ctx) {
|
|
RK_S32 i;
|
|
|
|
for (i = 0; i < VDEC_MAX_CHN_NUM; i++) {
|
|
if (ctx->stParserCfg.srcFileUri[i] != RK_NULL) {
|
|
rk_safe_free(ctx->stParserCfg.srcFileUri[i]);
|
|
}
|
|
}
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 creat_wbc(TEST_VO_CTX_S *ctx, RK_U32 u32Ch) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
VO_WBC VoWbc = u32Ch;
|
|
|
|
switch (ctx->u32WbcSourceType) {
|
|
case WBC_SOURCE_DEV:
|
|
ctx->stWbcCfg.stWbcSource.enSourceType = VO_WBC_SOURCE_DEV;
|
|
break;
|
|
default:
|
|
ctx->stWbcCfg.stWbcSource.enSourceType = VO_WBC_SOURCE_VIDEO;
|
|
}
|
|
s32Ret = RK_MPI_VO_SetWbcSource(VoWbc, &ctx->stWbcCfg.stWbcSource);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_SetWbcAttr(VoWbc, &ctx->stWbcCfg.stWbcAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_EnableWbc(VoWbc);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 destory_wbc(RK_U32 u32Ch) {
|
|
VO_WBC VoWbc = u32Ch;
|
|
RK_MPI_VO_DisableWbc(VoWbc);
|
|
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 creat_vdec(TEST_VO_CTX_S *ctx, RK_U32 u32Ch) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
VDEC_CHN_ATTR_S pstAttr;
|
|
VDEC_CHN_PARAM_S stVdecParam;
|
|
|
|
pstAttr.enMode = VIDEO_MODE_FRAME;
|
|
pstAttr.enType = ctx->stParserCfg.enCodecId;
|
|
pstAttr.u32PicWidth = ctx->stParserCfg.u32SrcWidth;
|
|
pstAttr.u32PicHeight = ctx->stParserCfg.u32SrcHeight;
|
|
pstAttr.u32FrameBufCnt = ctx->stVdecCfg.u32FrameBufferCnt;
|
|
|
|
s32Ret = RK_MPI_VDEC_CreateChn(u32Ch, &pstAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("create %d vdec failed! ", u32Ch);
|
|
RK_LOGE(R"(enMode %d enType %d u32PicWidth %d u32PicHeight %d \
|
|
u32PicVirWidth %d u32PicVirHeight %d u32FrameBufCnt %d)", \
|
|
pstAttr.enMode, pstAttr.enType, pstAttr.u32PicWidth, pstAttr.u32PicHeight, \
|
|
pstAttr.u32PicVirWidth, pstAttr.u32PicVirHeight, pstAttr.u32FrameBufCnt);
|
|
return s32Ret;
|
|
}
|
|
|
|
stVdecParam.stVdecVideoParam.enCompressMode = ctx->stVdecCfg.enCompressMode;
|
|
s32Ret = RK_MPI_VDEC_SetChnParam(u32Ch, &stVdecParam);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VDEC_StartRecvStream(u32Ch);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
|
|
if (TEST_COMM_GetUriSchemeType(ctx->stParserCfg.srcFileUri[u32Ch]) != RK_URI_SCHEME_LOCAL) {
|
|
s32Ret = RK_MPI_VDEC_SetDisplayMode(u32Ch, VIDEO_DISPLAY_MODE_PREVIEW);
|
|
} else {
|
|
s32Ret = RK_MPI_VDEC_SetDisplayMode(u32Ch, VIDEO_DISPLAY_MODE_PLAYBACK);
|
|
}
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
|
|
RK_LOGI("create %d vdec success", u32Ch);
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 screen1_process(TEST_VO_CTX_S *ctx, RK_U32 u32Index) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
MPP_CHN_S stSrcChn, stDstChn;
|
|
|
|
s32Ret = creat_vdec(ctx, u32Index);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("creat %d ch vdec failed!", u32Index);
|
|
return s32Ret;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VO_EnableChn(ctx->stVoCfg.u32Screen1VoLayer, u32Index - ctx->u32Screen0Chn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("creat %d layer %d ch vo failed!",
|
|
ctx->stVoCfg.u32Screen1VoLayer, u32Index - ctx->u32Screen0Chn);
|
|
return s32Ret;
|
|
}
|
|
RK_LOGD("create vo layer %d ch %d", ctx->stVoCfg.u32Screen1VoLayer, u32Index - ctx->u32Screen0Chn);
|
|
|
|
stSrcChn.enModId = RK_ID_VDEC;
|
|
stSrcChn.s32DevId = 0;
|
|
stSrcChn.s32ChnId = u32Index;
|
|
|
|
RK_LOGD("vdec Ch %d", stSrcChn.s32ChnId);
|
|
stDstChn.enModId = RK_ID_VO;
|
|
stDstChn.s32DevId = ctx->stVoCfg.u32Screen1VoLayer;
|
|
stDstChn.s32ChnId = u32Index - ctx->u32Screen0Chn;
|
|
|
|
RK_LOGD("VoLayer %d, voCh %d", ctx->stVoCfg.u32Screen1VoLayer, u32Index - ctx->u32Screen0Chn);
|
|
|
|
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDstChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("vdec and vo bind error");
|
|
return s32Ret;
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 screen0_process(TEST_VO_CTX_S *ctx, RK_U32 u32Index) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
MPP_CHN_S stSrcChn, stDstChn;
|
|
|
|
s32Ret = creat_vdec(ctx, u32Index);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("creat %d ch vdec failed!", u32Index);
|
|
return s32Ret;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VO_EnableChn(ctx->stVoCfg.u32Screen0VoLayer, u32Index);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("creat %d layer %d ch vo failed!", ctx->stVoCfg.u32Screen0VoLayer, u32Index);
|
|
return s32Ret;
|
|
}
|
|
|
|
RK_LOGD("create vo layer %d ch %d", ctx->stVoCfg.u32Screen0VoLayer, u32Index);
|
|
|
|
stSrcChn.enModId = RK_ID_VDEC;
|
|
stSrcChn.s32DevId = 0;
|
|
stSrcChn.s32ChnId = u32Index;
|
|
RK_LOGD("vdec Ch %d", stSrcChn.s32ChnId);
|
|
|
|
stDstChn.enModId = RK_ID_VO;
|
|
stDstChn.s32DevId = ctx->stVoCfg.u32Screen0VoLayer;
|
|
stDstChn.s32ChnId = u32Index;
|
|
RK_LOGD("voLayer %d, voCh %d", stDstChn.s32DevId, stDstChn.s32ChnId);
|
|
|
|
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDstChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("vdec and vo bind error ");
|
|
return s32Ret;
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_S32 wbc_process(TEST_VO_CTX_S *ctx) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
MPP_CHN_S stSrcChn, stDstChn;
|
|
|
|
s32Ret = creat_wbc(ctx, 0);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("create wbc failed");
|
|
return s32Ret;
|
|
}
|
|
|
|
stSrcChn.enModId = RK_ID_WBC;
|
|
stSrcChn.s32DevId = 0;
|
|
stSrcChn.s32ChnId = 0;
|
|
|
|
if (ctx->bEnWbcToVO) {
|
|
stDstChn.enModId = RK_ID_VO;
|
|
|
|
if (ctx->stWbcCfg.stWbcSource.u32SourceId == RK356X_VO_DEV_HD1) {
|
|
s32Ret = RK_MPI_VO_EnableChn(ctx->stVoCfg.u32Screen0VoLayer, ctx->u32Screen0Chn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("creat %d layer %d ch vo failed!",
|
|
ctx->stVoCfg.u32Screen0VoLayer, ctx->u32Screen0Chn);
|
|
return s32Ret;
|
|
}
|
|
stDstChn.s32DevId = ctx->stVoCfg.u32Screen0VoLayer;
|
|
} else {
|
|
s32Ret = RK_MPI_VO_EnableChn(ctx->stVoCfg.u32Screen1VoLayer, ctx->u32Screen1Chn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("creat %d layer %d ch vo failed!",
|
|
ctx->stVoCfg.u32Screen1VoLayer, ctx->u32Screen1Chn);
|
|
return s32Ret;
|
|
}
|
|
stDstChn.s32DevId = ctx->stVoCfg.u32Screen1VoLayer;
|
|
}
|
|
stDstChn.s32ChnId = ctx->u32Screen1Chn;
|
|
|
|
if (ctx->wbc_bind == RK_TRUE) {
|
|
s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDstChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("creat wbc bind vo failed!");
|
|
return RK_FAILURE;
|
|
}
|
|
} else {
|
|
RK_LOGD("WBC enabled,but not bind");
|
|
}
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
|
|
RK_S32 unit_mpi_voplay_test(TEST_VO_CTX_S *ctx) {
|
|
RK_U32 i, k;
|
|
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
RK_U32 u32MaxCh = 0;
|
|
RK_U32 u32step = 0;
|
|
RK_S32 u32VpssGrap = 0;
|
|
|
|
MPP_CHN_S stSrcChn, stDstChn;
|
|
|
|
TEST_VO_CTX_S mpiVdecCtx[VDEC_MAX_CHN_NUM];
|
|
TEST_VO_CTX_S mpiVencCtx[VENC_MAX_CHN_NUM];
|
|
|
|
pthread_t vdecSendThread[VDEC_MAX_CHN_NUM];
|
|
pthread_t vdecGetThread[VDEC_MAX_CHN_NUM];
|
|
|
|
pthread_t voThread;
|
|
RK_U32 u32VdecSendThreadNum = 0;
|
|
RK_U32 u32VdecGetThreadNum = 0;
|
|
RK_U32 u32Ch = 0;
|
|
|
|
if (open_config(ctx) < 0) {
|
|
RK_LOGE("parser cfg failed!");
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
mpi_vo_init_sample(ctx, ctx->stVoCfg.u32Screen0Rows, ctx->stVoCfg.u32Screen1Rows);
|
|
|
|
u32MaxCh = ctx->u32Screen1Chn + ctx->u32Screen0Chn;
|
|
|
|
RK_LOGD("screen0Ch %d screen1Ch %d maxCh %d", ctx->u32Screen0Chn, ctx->u32Screen1Chn, u32MaxCh);
|
|
|
|
for (i = 0; i < ctx->u32Screen0Chn; i++) {
|
|
s32Ret = screen0_process(ctx, i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("screen0_process failed!", i);
|
|
continue;
|
|
}
|
|
ctx->u32ChnIndex = i;
|
|
memcpy(&(mpiVdecCtx[i]), ctx, sizeof(TEST_VO_CTX_S));
|
|
u32VdecSendThreadNum++;
|
|
}
|
|
|
|
|
|
for (i = ctx->u32Screen0Chn; i < u32MaxCh; i++) {
|
|
s32Ret = screen1_process(ctx, i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
RK_LOGE("screen1_process failed!", i);
|
|
continue;
|
|
}
|
|
ctx->u32ChnIndex = i;
|
|
memcpy(&(mpiVdecCtx[i]), ctx, sizeof(TEST_VO_CTX_S));
|
|
u32VdecSendThreadNum++;
|
|
}
|
|
|
|
pthread_create(&voThread, 0, vochn_test_thread_func, reinterpret_cast<void *>(ctx));
|
|
|
|
if (ctx->bEnWbc) {
|
|
s32Ret = wbc_process(ctx);
|
|
if (s32Ret == RK_SUCCESS) {
|
|
RK_LOGE("wb process ok");
|
|
} else {
|
|
RK_LOGE("wb process failed");
|
|
}
|
|
}
|
|
|
|
u32VdecSendThreadNum = 0;
|
|
for (i = 0; i< ctx->u32Screen0Chn; i++) {
|
|
pthread_join(vdecSendThread[u32VdecSendThreadNum], RK_NULL);
|
|
u32VdecSendThreadNum++;
|
|
|
|
stSrcChn.enModId = RK_ID_VDEC;
|
|
stSrcChn.s32DevId = 0;
|
|
stSrcChn.s32ChnId = i;
|
|
|
|
stDstChn.enModId = RK_ID_VO;
|
|
stDstChn.s32DevId = ctx->stVoCfg.u32Screen0VoLayer;
|
|
stDstChn.s32ChnId = i;
|
|
|
|
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VDEC_StopRecvStream(i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VDEC_DestroyChn(i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_DisableChn(ctx->stVoCfg.u32Screen0VoLayer, i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
}
|
|
|
|
for (i = ctx->u32Screen0Chn; i < u32MaxCh; i++) {
|
|
pthread_join(vdecSendThread[u32VdecSendThreadNum], RK_NULL);
|
|
u32VdecSendThreadNum++;
|
|
|
|
stSrcChn.enModId = RK_ID_VDEC;
|
|
stSrcChn.s32DevId = 0;
|
|
stSrcChn.s32ChnId = i;
|
|
|
|
stDstChn.enModId = RK_ID_VO;
|
|
stDstChn.s32DevId = ctx->stVoCfg.u32Screen1VoLayer;
|
|
stDstChn.s32ChnId = i;
|
|
|
|
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VDEC_StopRecvStream(i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VDEC_DestroyChn(i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_DisableChn(ctx->stVoCfg.u32Screen1VoLayer, i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
}
|
|
|
|
if (ctx->bEnWbc) {
|
|
if (ctx->bEnWbcToVO) {
|
|
stSrcChn.enModId = RK_ID_WBC;
|
|
stSrcChn.s32DevId = 0;
|
|
stSrcChn.s32ChnId = 0;
|
|
|
|
stDstChn.enModId = RK_ID_VO;
|
|
stDstChn.s32DevId = ctx->stVoCfg.u32Screen0VoLayer;
|
|
stDstChn.s32ChnId = 0;
|
|
|
|
s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDstChn);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = destory_wbc(0);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
s32Ret = RK_MPI_VO_DisableChn(ctx->stVoCfg.u32Screen0VoLayer, 0);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
return s32Ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
mpi_vo_deinit_sample(ctx);
|
|
close_config(ctx);
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static void Sample_VO_GetPictureData(VO_FRAME_INFO_S *pstFrameInfo, const char *pFileName) {
|
|
RK_S32 u32Fd;
|
|
RK_U32 u32Size, u32Bpp, u32Stride;
|
|
|
|
switch (pstFrameInfo->enPixelFormat) {
|
|
case RK_FMT_RGBA8888:
|
|
u32Bpp = 4;
|
|
break;
|
|
case RK_FMT_RGB888:
|
|
case RK_FMT_BGR888:
|
|
u32Bpp = 3;
|
|
break;
|
|
case RK_FMT_YUV420SP:
|
|
case RK_FMT_YUV420SP_VU:
|
|
u32Bpp = 1;
|
|
break;
|
|
default:
|
|
Sample_Print("%s Unsupported Format %d\n", __func__, pstFrameInfo->enPixelFormat);
|
|
return;
|
|
}
|
|
|
|
u32Fd = open(pFileName, O_RDONLY);
|
|
if (u32Fd < 0) {
|
|
Sample_Print("cat not find file\n");
|
|
return;
|
|
}
|
|
u32Size = lseek(u32Fd, 0, SEEK_END);
|
|
lseek(u32Fd, 0, SEEK_SET);
|
|
|
|
Sample_Print("%dx%d %dx%d\n",
|
|
pstFrameInfo->u32Width, pstFrameInfo->u32Height,
|
|
pstFrameInfo->u32VirWidth, pstFrameInfo->u32VirHeight);
|
|
|
|
if (pstFrameInfo->u32Width != pstFrameInfo->u32VirWidth) {
|
|
u32Stride = pstFrameInfo->u32VirWidth * u32Bpp;
|
|
|
|
for (RK_S32 i = 0; i < pstFrameInfo->u32Height; i++)
|
|
read(u32Fd, reinterpret_cast<RK_S8 *>(pstFrameInfo->pData) + u32Stride * i,
|
|
pstFrameInfo->u32Width * u32Bpp);
|
|
|
|
if (pstFrameInfo->enPixelFormat == RK_FMT_YUV420SP ||
|
|
pstFrameInfo->enPixelFormat == RK_FMT_YUV420SP_VU) {
|
|
for (RK_S32 i = 0; i < pstFrameInfo->u32Height / 2; i++)
|
|
read(u32Fd, reinterpret_cast<RK_S8 *>(pstFrameInfo->pData)
|
|
+ u32Stride * pstFrameInfo->u32VirHeight + i * u32Stride,
|
|
pstFrameInfo->u32Width);
|
|
}
|
|
} else {
|
|
read(u32Fd, pstFrameInfo->pData, u32Size);
|
|
}
|
|
close(u32Fd);
|
|
}
|
|
|
|
static void filewrite(void *buf, uint32_t size, char *file) {
|
|
int fd = open(file, O_WRONLY | O_CREAT);
|
|
|
|
if (fd < 0) {
|
|
printf("cat not open file\n");
|
|
return;
|
|
}
|
|
|
|
write(fd, buf, size);
|
|
close(fd);
|
|
}
|
|
|
|
static void Sample_VO_DrawUI(VO_FRAME_INFO_S *pstFrameInfo, RK_S32 format, RK_S32 value) {
|
|
RK_S32 PixelVal0, PixelVal1;
|
|
RK_S8 *pData = reinterpret_cast<RK_S8 *>(pstFrameInfo->pData);
|
|
RK_U32 u32Offset;
|
|
|
|
for (RK_S32 i = 0; i < pstFrameInfo->u32Height; i++) {
|
|
for (RK_S32 j = 0; j < pstFrameInfo->u32Width; j++) {
|
|
u32Offset = i * pstFrameInfo->u32VirWidth + j;
|
|
if (format == RK_FMT_BGRA5551) {
|
|
u32Offset = u32Offset * 2;
|
|
PixelVal0 = value | 0x8000;
|
|
PixelVal1 = value & 0x7FFF;
|
|
} else if (format == RK_FMT_BGRA8888) {
|
|
u32Offset = u32Offset * 4;
|
|
PixelVal0 = 0x000000FF;
|
|
} else {
|
|
continue;
|
|
}
|
|
|
|
if (j < pstFrameInfo->u32Width / 2) {
|
|
if (format == RK_FMT_BGRA5551) {
|
|
pData[u32Offset] = PixelVal0 & 0xff;
|
|
pData[u32Offset + 1] = (PixelVal0 >> 8) & 0xff;
|
|
} else if (format == RK_FMT_BGRA8888) {
|
|
pData[u32Offset] = PixelVal0 & 0xff;
|
|
pData[u32Offset + 1] = (PixelVal0 >> 8) & 0xff;
|
|
pData[u32Offset + 1] = (PixelVal0 >> 16) & 0xff;
|
|
pData[u32Offset + 1] = (PixelVal0 >> 24) & 0xff;
|
|
}
|
|
} else {
|
|
if (format == RK_FMT_BGRA5551) {
|
|
pData[u32Offset] = PixelVal1 & 0xff;
|
|
pData[u32Offset + 1] = (PixelVal1 >> 8) & 0xff;
|
|
} else if (format == RK_FMT_BGRA8888) {
|
|
pData[u32Offset] = PixelVal0 & 0xff;
|
|
pData[u32Offset + 1] = (PixelVal0 >> 8) & 0xff;
|
|
pData[u32Offset + 1] = (PixelVal0 >> 16) & 0xff;
|
|
pData[u32Offset + 1] = (PixelVal0 >> 24) & 0xff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static RK_S32 Sample_VO_MultiGFXLayer_Start(VO_LAYER VoLayer, RK_U32 u32Layers) {
|
|
VO_VIDEO_LAYER_ATTR_S stLayerAttr;
|
|
VO_CHN_ATTR_S stChnAttr;
|
|
VO_CHN_PARAM_S stParam;
|
|
VO_BORDER_S stBorder;
|
|
RK_U32 u32Row, u32Column, i;
|
|
RK_U32 u32WinWidth, u32WinHeight;
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
s32Ret = RK_MPI_VO_GetLayerAttr(VoLayer, &stLayerAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
Sample_Print("[%s] Get Layer Attr failed\n", __func__);
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
for (i = 0; i < u32Layers; i++) {
|
|
stChnAttr.stRect.s32X = 0;
|
|
stChnAttr.stRect.s32Y = 0;
|
|
stChnAttr.stRect.u32Width = stLayerAttr.stDispRect.u32Width;
|
|
stChnAttr.stRect.u32Height = stLayerAttr.stDispRect.u32Height;
|
|
stChnAttr.u32Priority = i;
|
|
if (i == 0) {
|
|
stChnAttr.u32FgAlpha = 128;
|
|
stChnAttr.u32BgAlpha = 0;
|
|
} else {
|
|
stChnAttr.u32FgAlpha = 0;
|
|
stChnAttr.u32BgAlpha = 128;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VO_SetChnAttr(VoLayer, i, &stChnAttr);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
Sample_Print("[%s] set chn Attr failed\n", __func__);
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
s32Ret = RK_MPI_VO_EnableChn(VoLayer, i);
|
|
if (s32Ret != RK_SUCCESS) {
|
|
Sample_Print("[%s] Enalbe chn failed\n", __func__);
|
|
return RK_FAILURE;
|
|
}
|
|
}
|
|
|
|
Sample_Print("[%s] success\n", __func__);
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_MultiWindowns_Start(TEST_VO_CTX_S *ctx) {
|
|
VO_VIDEO_LAYER_ATTR_S stLayerAttr;
|
|
VO_CHN_ATTR_S stChnAttr;
|
|
VO_CHN_PARAM_S stChnParam;
|
|
VO_BORDER_S stBorder;
|
|
RK_U32 u32Row, u32Column, i;
|
|
RK_U32 u32WinWidth, u32WinHeight;
|
|
RK_U32 u32X, u32Y;
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
RK_U32 disp_width = 1920;
|
|
RK_U32 disp_height = 1080;
|
|
|
|
if (ctx->u32Windows <= 2)
|
|
u32Row = 1;
|
|
else if (ctx->u32Windows <= 4)
|
|
u32Row = 2;
|
|
else if (ctx->u32Windows <= 9)
|
|
u32Row = 3;
|
|
else if (ctx->u32Windows <= 16)
|
|
u32Row = 4;
|
|
else if (ctx->u32Windows <= 36)
|
|
u32Row = 6;
|
|
else if (ctx->u32Windows <= 64)
|
|
u32Row = 8;
|
|
else
|
|
return RK_FAILURE;
|
|
|
|
u32Column = ctx->u32Windows / u32Row + ((ctx->u32Windows % u32Row)? 1: 0);
|
|
|
|
s32Ret = RK_MPI_VO_GetLayerAttr(ctx->VoLayer, &stLayerAttr);
|
|
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
u32WinWidth = stLayerAttr.stDispRect.u32Width / u32Column;
|
|
u32WinHeight = stLayerAttr.stDispRect.u32Height / u32Row;
|
|
|
|
for (i = 0; i <ctx->u32Windows; i++) {
|
|
u32X = i % u32Column;
|
|
u32Y = i / u32Column;
|
|
stChnAttr.stRect.s32X = stLayerAttr.stDispRect.s32X + u32X * u32WinWidth;
|
|
stChnAttr.stRect.s32Y = stLayerAttr.stDispRect.s32Y + u32Y * u32WinHeight;
|
|
stChnAttr.stRect.u32Width = u32WinWidth;
|
|
stChnAttr.stRect.u32Height = u32WinHeight;
|
|
stChnAttr.u32FgAlpha = 255;
|
|
stChnAttr.u32BgAlpha = 0;
|
|
// set priority
|
|
stChnAttr.u32Priority = 1;
|
|
|
|
s32Ret = RK_MPI_VO_SetChnAttr(ctx->VoLayer, i, &stChnAttr);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
// set video aspect ratio
|
|
if (ctx->uEnMode == 2) {
|
|
stChnParam.stAspectRatio.enMode = ASPECT_RATIO_MANUAL;
|
|
stChnParam.stAspectRatio.stVideoRect.s32X = stLayerAttr.stDispRect.s32X + u32X * u32WinWidth;
|
|
stChnParam.stAspectRatio.stVideoRect.s32Y = stLayerAttr.stDispRect.s32Y + u32Y * u32WinHeight;
|
|
stChnParam.stAspectRatio.stVideoRect.u32Width = u32WinWidth/2;
|
|
stChnParam.stAspectRatio.stVideoRect.u32Height = u32WinHeight/2;
|
|
RK_MPI_VO_SetChnParam(ctx->VoLayer, i, &stChnParam);
|
|
} else if (ctx->uEnMode == 1) {
|
|
stChnParam.stAspectRatio.enMode = ASPECT_RATIO_AUTO;
|
|
stChnParam.stAspectRatio.stVideoRect.s32X = stLayerAttr.stDispRect.s32X + u32X * u32WinWidth;
|
|
stChnParam.stAspectRatio.stVideoRect.s32Y = stLayerAttr.stDispRect.s32Y + u32Y * u32WinHeight;
|
|
stChnParam.stAspectRatio.stVideoRect.u32Width = u32WinWidth;
|
|
stChnParam.stAspectRatio.stVideoRect.u32Height = u32WinHeight;
|
|
RK_MPI_VO_SetChnParam(ctx->VoLayer, i, &stChnParam);
|
|
}
|
|
|
|
stBorder.stBorder.u32Color = 0xFFFAFA;
|
|
stBorder.stBorder.u32TopWidth = ctx->stBorderCfg.u32TopWidth;
|
|
stBorder.stBorder.u32BottomWidth = ctx->stBorderCfg.u32BottomWidth;
|
|
stBorder.stBorder.u32LeftWidth = ctx->stBorderCfg.u32LeftWidth;
|
|
stBorder.stBorder.u32RightWidth = ctx->stBorderCfg.u32RightWidth;
|
|
stBorder.bBorderEn = ctx->bBorder;
|
|
s32Ret = RK_MPI_VO_SetChnBorder(ctx->VoLayer, i, &stBorder);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
s32Ret = RK_MPI_VO_EnableChn(ctx->VoLayer, i);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_MultiWindowns_Stop(VO_LAYER VoLayer, RK_U32 u32Windows) {
|
|
RK_U32 i;
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
for (i = 0; i < u32Windows; i++) {
|
|
s32Ret = RK_MPI_VO_DisableChn(VoLayer, i);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_StartDev(VO_DEV VoDev, VO_PUB_ATTR_S *pstPubAttr) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
s32Ret = RK_MPI_VO_SetPubAttr(VoDev, pstPubAttr);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
s32Ret = RK_MPI_VO_Enable(VoDev);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_StopDev(VO_DEV VoDev) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
s32Ret = RK_MPI_VO_Disable(VoDev);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_StartLayer(VO_LAYER VoLayer, const VO_VIDEO_LAYER_ATTR_S *pstLayerAttr) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
s32Ret = RK_MPI_VO_SetLayerAttr(VoLayer, pstLayerAttr);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
s32Ret = RK_MPI_VO_EnableLayer(VoLayer);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_StopLayer(VO_LAYER VoLayer) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
s32Ret = RK_MPI_VO_DisableLayer(VoLayer);
|
|
if (s32Ret != RK_SUCCESS)
|
|
return RK_FAILURE;
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_SetVFrame(VIDEO_FRAME_INFO_S *pVFrame,
|
|
RK_U32 u32Width,
|
|
RK_U32 u32Height,
|
|
RK_U32 u32VirWidth,
|
|
RK_U32 u32VirHeight,
|
|
PIXEL_FORMAT_E enPixelFormat,
|
|
RK_VOID *pMblk) {
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
|
|
if (pVFrame == NULL && pMblk == NULL)
|
|
return RK_FAILURE;
|
|
|
|
if (!u32Width || !u32Height ||
|
|
!u32VirWidth || !u32VirHeight ||
|
|
enPixelFormat >= RK_FMT_BUTT)
|
|
s32Ret = RK_FAILURE;
|
|
|
|
pVFrame->stVFrame.pMbBlk = pMblk;
|
|
pVFrame->stVFrame.u32Width = u32Width;
|
|
pVFrame->stVFrame.u32Height = u32Height;
|
|
pVFrame->stVFrame.u32VirWidth = u32VirWidth;
|
|
pVFrame->stVFrame.u32VirHeight = u32VirHeight;
|
|
pVFrame->stVFrame.enPixelFormat = enPixelFormat;
|
|
|
|
return s32Ret;
|
|
}
|
|
static RK_S32 Sample_VO_BindVoWbc(VO_DEV VoWbcDev, VO_LAYER VoLayer, VO_CHN VoChn) {
|
|
MPP_CHN_S stSrcChn, stDestChn;
|
|
|
|
stSrcChn.enModId = RK_ID_WBC;
|
|
stSrcChn.s32DevId = VoWbcDev;
|
|
stSrcChn.s32ChnId = 0;
|
|
|
|
stDestChn.enModId = RK_ID_VO;
|
|
stDestChn.s32ChnId = VoChn;
|
|
stDestChn.s32DevId = VoLayer;
|
|
|
|
return RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
|
|
}
|
|
|
|
static RK_S32 Sample_VO_UnBindVoWbc(VO_DEV VoWbcDev, VO_LAYER VoLayer, VO_CHN VoChn) {
|
|
MPP_CHN_S stSrcChn, stDestChn;
|
|
|
|
stSrcChn.enModId = RK_ID_WBC;
|
|
stSrcChn.s32DevId = VoWbcDev;
|
|
stSrcChn.s32ChnId = 0;
|
|
|
|
stDestChn.enModId = RK_ID_VO;
|
|
stDestChn.s32ChnId = VoChn;
|
|
stDestChn.s32DevId = VoLayer;
|
|
|
|
return RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
|
|
}
|
|
|
|
static RK_S32 Sample_VO_CreateGFXData(RK_U32 u32Width, RK_U32 u32Height, RK_U32 foramt, RK_U32 value, RK_VOID **pMblk) {
|
|
VO_FRAME_INFO_S stFrameInfo;
|
|
RK_U32 u32BuffSize;
|
|
|
|
u32BuffSize = RK_MPI_VO_CreateGraphicsFrameBuffer(u32Width, u32Height, foramt, pMblk);
|
|
if (u32BuffSize == 0) {
|
|
Sample_Print("can not create gfx buffer\n");
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
RK_MPI_VO_GetFrameInfo(*pMblk, &stFrameInfo);
|
|
if (foramt == RK_FMT_RGB888) {
|
|
if (u32Width == 1920 && u32Height == 1080 && value == 0)
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_1080P_RGB_0.yuv");
|
|
else if (u32Width == 1920 && u32Height == 1080 && value == 1 )
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_1080P_RGB_1.yuv");
|
|
else if (u32Width == 1024 && u32Height == 768 && value == 0 )
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_768P_RGB_0.yuv");
|
|
else if (u32Width == 1024 && u32Height == 768 && value == 1)
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_768P_RGB_1.yuv");
|
|
else
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_480P_RGB.yuv");
|
|
} else if (foramt == RK_FMT_RGBA8888) {
|
|
if (u32Width == 1920 && u32Height == 1080 && value == 0 )
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_1080P_RGBA.yuv");
|
|
else if (u32Width == 1920 && u32Height == 1080 && value == 1 )
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_1080P2_RGBA.yuv");
|
|
else if (u32Width == 1024 && u32Height == 768)
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_768P_RGBA.yuv");
|
|
else
|
|
Sample_VO_GetPictureData(&stFrameInfo, "/userdata/test/vo/res_480P_RGBA.yuv");
|
|
} else {
|
|
Sample_VO_DrawUI(&stFrameInfo, foramt, value);
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
}
|
|
|
|
static RK_VOID * Sample_VO_SendPicture_Mosaic(RK_VOID *pArg) {
|
|
VoThreadParam *pParam = reinterpret_cast<VoThreadParam *>(pArg);
|
|
VIDEO_FRAME_INFO_S *pstVFrame;
|
|
RK_VOID *pMblk, *pMblk_1080P, *pMblk_1080P2, *pMblk_768P, *pMblk_480P, *pMblk_G0, *pMblk_G1;
|
|
RK_U32 count;
|
|
|
|
Sample_VO_CreateGFXData(1920, 1080, RK_FMT_RGBA8888, 0, &pMblk_1080P);
|
|
Sample_VO_CreateGFXData(1920, 1080, RK_FMT_RGBA8888, 1, &pMblk_1080P2);
|
|
Sample_VO_CreateGFXData(720, 480, RK_FMT_RGBA8888, 0, &pMblk_480P);
|
|
Sample_VO_CreateGFXData(1024, 768, RK_FMT_RGBA8888, 0, &pMblk_768P);
|
|
Sample_VO_CreateGFXData(1920, 1080, RK_FMT_BGRA5551, 0x1F, &pMblk_G0);
|
|
Sample_VO_CreateGFXData(1920, 1080, RK_FMT_BGRA5551, 0x1F << 10, &pMblk_G1);
|
|
|
|
pstVFrame = reinterpret_cast<VIDEO_FRAME_INFO_S *>(malloc(sizeof(VIDEO_FRAME_INFO_S)));
|
|
|
|
while (!pParam->u32Exit) {
|
|
if (pParam->VoVideoLayer >= 0) {
|
|
for (RK_U32 i = 0; i < pParam->u32VideoWindows; i++) {
|
|
if (pParam->u32VideoWindows > 10) {
|
|
pstVFrame->stVFrame.u32Width = 720;
|
|
pstVFrame->stVFrame.u32Height = 480;
|
|
pstVFrame->stVFrame.u32VirWidth = 720;
|
|
pstVFrame->stVFrame.u32VirHeight = 480;
|
|
pstVFrame->stVFrame.enPixelFormat = RK_FMT_RGBA8888;
|
|
pMblk = pMblk_480P;
|
|
} else if (count % 2) {
|
|
pMblk = pMblk_1080P;
|
|
pstVFrame->stVFrame.u32Width = 1920;
|
|
pstVFrame->stVFrame.u32Height = 1080;
|
|
pstVFrame->stVFrame.u32VirWidth = 1920;
|
|
pstVFrame->stVFrame.u32VirHeight = 1080;
|
|
pstVFrame->stVFrame.enPixelFormat = RK_FMT_RGBA8888;
|
|
pstVFrame->stVFrame.pMbBlk = pMblk;
|
|
} else {
|
|
pMblk = pMblk_1080P2;
|
|
pstVFrame->stVFrame.u32Width = 1920;
|
|
pstVFrame->stVFrame.u32Height = 1080;
|
|
pstVFrame->stVFrame.u32VirWidth = 1920;
|
|
pstVFrame->stVFrame.u32VirHeight = 1080;
|
|
pstVFrame->stVFrame.enPixelFormat = RK_FMT_RGBA8888;
|
|
pstVFrame->stVFrame.pMbBlk = pMblk;
|
|
}
|
|
|
|
pstVFrame->stVFrame.pMbBlk = pMblk;
|
|
RK_MPI_VO_SendFrame(pParam->VoVideoLayer, i, pstVFrame, 0);
|
|
}
|
|
}
|
|
if (pParam->VOGfxLayer >= 0) {
|
|
for (RK_U32 i = 0; i < pParam->u32GFXLayers; i++) {
|
|
if (i == 0)
|
|
pMblk = pMblk_G0;
|
|
else if (i == 1)
|
|
pMblk = pMblk_G1;
|
|
else
|
|
continue;
|
|
|
|
pstVFrame->stVFrame.u32Width = 1920;
|
|
pstVFrame->stVFrame.u32Height = 1080;
|
|
pstVFrame->stVFrame.u32VirWidth = 1920;
|
|
pstVFrame->stVFrame.u32VirHeight = 1080;
|
|
pstVFrame->stVFrame.enPixelFormat = RK_FMT_BGRA5551;
|
|
pstVFrame->stVFrame.pMbBlk = pMblk;
|
|
RK_MPI_VO_SendFrame(pParam->VOGfxLayer, i, pstVFrame, 0);
|
|
}
|
|
}
|
|
usleep(1000000);
|
|
count++;
|
|
}
|
|
free(pstVFrame);
|
|
RK_MPI_VO_DestroyGraphicsFrameBuffer(pMblk);
|
|
Sample_Print("%s exit\n", __func__);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static RK_VOID Sample_VO_StartSendPicture_Mosaic(pthread_t *pThreadID, VoThreadParam *pstParam) {
|
|
pthread_create(pThreadID, NULL, Sample_VO_SendPicture_Mosaic, reinterpret_cast<RK_VOID *>(pstParam));
|
|
}
|
|
|
|
static RK_VOID Sample_VO_StopSendPicture_Mosaic(pthread_t tThreadID, VoThreadParam *pstParam) {
|
|
pstParam->u32Exit = 1;
|
|
pthread_join(tThreadID, RK_NULL);
|
|
}
|
|
|
|
static RK_S32 Sample_VO_Demo_Video_Mosaic(TEST_VO_CTX_S *ctx) {
|
|
VO_PUB_ATTR_S stVoPubAttr;
|
|
VO_VIDEO_LAYER_ATTR_S stLayerAttr;
|
|
RK_U32 u32DispWidth, u32DispHeight;
|
|
RK_U32 u32ImageWidth, u32ImageHeight;
|
|
VO_LAYER VoLayer;
|
|
VO_DEV VoDev;
|
|
RK_S32 u32Windows;
|
|
RK_U32 u32Fps, i;
|
|
pthread_t tThreadID;
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
VO_LAYER_MODE_E Vo_layer_mode;
|
|
VoThreadParam stThreadParam;
|
|
PIXEL_FORMAT_E video_format;
|
|
|
|
VoDev = ctx->VoDev;
|
|
u32Windows = ctx->u32Windows;
|
|
u32Fps = ctx->u32DispFrmRt;
|
|
VoLayer = ctx->VoLayer;
|
|
for (RK_U32 j = 0; j < VDEC_ARRAY_ELEMS(testPixelFormat); j++) {
|
|
if (ctx->s32PixFormat == testPixelFormat[j].index) {
|
|
video_format = testPixelFormat[j].format;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Sample_Print("%s VoDev %u Windows %u video_format %x\n", __func__, VoDev, u32Windows, video_format);
|
|
|
|
/* Bind Layer */
|
|
switch (ctx->VoLayerMode) {
|
|
case 0:
|
|
Vo_layer_mode = VO_LAYER_MODE_CURSOR;
|
|
break;
|
|
case 1:
|
|
Vo_layer_mode = VO_LAYER_MODE_GRAPHIC;
|
|
break;
|
|
case 2:
|
|
Vo_layer_mode = VO_LAYER_MODE_VIDEO;
|
|
break;
|
|
default:
|
|
Vo_layer_mode = VO_LAYER_MODE_VIDEO;
|
|
}
|
|
|
|
RK_MPI_VO_BindLayer(VoLayer, VoDev, Vo_layer_mode);
|
|
|
|
switch (ctx->enIntfType) {
|
|
case DISPLAY_TYPE_VGA:
|
|
stVoPubAttr.enIntfType = VO_INTF_VGA;
|
|
break;
|
|
case DISPLAY_TYPE_HDMI:
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI;
|
|
break;
|
|
case DISPLAY_TYPE_EDP:
|
|
stVoPubAttr.enIntfType = VO_INTF_EDP;
|
|
break;
|
|
case DISPLAY_TYPE_DP:
|
|
stVoPubAttr.enIntfType = VO_INTF_DP;
|
|
break;
|
|
case DISPLAY_TYPE_HDMI_EDP :
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI | VO_INTF_EDP;
|
|
break;
|
|
default:
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI;
|
|
Sample_Print("IntfType not set,use INTF_HDMI default\n");
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(test_mode_table); i++) {
|
|
if (ctx->enIntfSync == test_mode_table[i].mode)
|
|
break;
|
|
}
|
|
|
|
if (i == ARRAY_LENGTH(test_mode_table)) {
|
|
Sample_Print("%s not found supported mode in test mode_table\n", __func__);
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
stVoPubAttr.enIntfSync = test_mode_table[i].enIntfSync;
|
|
stVoPubAttr.u32BgColor = 0x000000;
|
|
Sample_VO_StartDev(VoDev, &stVoPubAttr);
|
|
|
|
/* Enable Layer */
|
|
stLayerAttr.enPixFormat = video_format;
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
Sample_VO_GetDisplaySize(stVoPubAttr.enIntfSync, &u32DispWidth, &u32DispHeight);
|
|
|
|
u32ImageWidth = u32DispWidth;
|
|
u32ImageHeight = u32DispHeight;
|
|
stLayerAttr.stDispRect.u32Width = u32DispWidth;
|
|
stLayerAttr.stDispRect.u32Height = u32DispHeight;
|
|
stLayerAttr.stImageSize.u32Width = u32ImageWidth;
|
|
stLayerAttr.stImageSize.u32Height = u32ImageHeight;
|
|
stLayerAttr.u32DispFrmRt = ctx->u32DispFrmRt;
|
|
|
|
Sample_VO_StartLayer(VoLayer, &stLayerAttr);
|
|
Sample_VO_MultiWindowns_Start(ctx);
|
|
stThreadParam.u32Exit = 0;
|
|
stThreadParam.u32VideoWindows = u32Windows;
|
|
stThreadParam.VoVideoLayer = VoLayer;
|
|
stThreadParam.VOGfxLayer = -1;
|
|
stThreadParam.u32GFXLayers = -1;
|
|
|
|
Sample_Print("Start Send Picture\n");
|
|
Sample_VO_StartSendPicture_Mosaic(&tThreadID, &stThreadParam);
|
|
|
|
while (1) {
|
|
Sample_Print("Press 'q' to quit\n");
|
|
if (getchar() == 'q')
|
|
break;
|
|
}
|
|
|
|
Sample_VO_StopSendPicture_Mosaic(tThreadID, &stThreadParam);
|
|
Sample_VO_MultiWindowns_Stop(VoLayer, u32Windows);
|
|
Sample_VO_StopLayer(VoLayer);
|
|
Sample_VO_StopDev(VoDev);
|
|
end:
|
|
RK_MPI_VO_UnBindLayer(VoLayer, VoDev);
|
|
RK_MPI_VO_CloseFd();
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_Demo_UI(TEST_VO_CTX_S *ctx) {
|
|
VO_PUB_ATTR_S stVoPubAttr;
|
|
VO_VIDEO_LAYER_ATTR_S stLayerAttr;
|
|
VIDEO_FRAME_INFO_S *pstVFrame;
|
|
RK_U32 u32DispWidth, u32DispHeight;
|
|
RK_U32 u32ImgWidth, u32ImgHeight;
|
|
VO_LAYER VoLayer;
|
|
RK_S32 VoDev;
|
|
RK_S32 VoDev_second;
|
|
VO_LAYER VoLayer_second;
|
|
RK_VOID *pMblk_1080P_1 = RK_NULL;
|
|
RK_VOID *pMblk_1080P_2 = RK_NULL;
|
|
RK_VOID *pMblk_768P_1 = RK_NULL;
|
|
RK_VOID *pMblk_768P_2 = RK_NULL;
|
|
RK_U32 s32Ret = RK_SUCCESS;
|
|
RK_S32 count = 0;
|
|
PIXEL_FORMAT_E plane_format;
|
|
|
|
for (RK_U32 j = 0; j < VDEC_ARRAY_ELEMS(testPixelFormat); j++) {
|
|
if (ctx->s32PixFormat == testPixelFormat[j].index) {
|
|
plane_format = testPixelFormat[j].format;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pstVFrame = reinterpret_cast<VIDEO_FRAME_INFO_S *>(malloc(sizeof(VIDEO_FRAME_INFO_S)));
|
|
/* GFX buffer dispaly on VoDev 0 */
|
|
Sample_VO_CreateGFXData(1920, 1080,
|
|
RK_FMT_RGB888, 0, &pMblk_1080P_1);
|
|
Sample_VO_CreateGFXData(1920, 1080,
|
|
RK_FMT_RGB888, 1, &pMblk_1080P_2);
|
|
|
|
/* GFX buffer dispaly on VoDev 1 */
|
|
if (ctx->bDoubleScreen) {
|
|
Sample_Print("DoubleScreen UI Demo test");
|
|
Sample_VO_CreateGFXData(1024, 768,
|
|
RK_FMT_RGB888, 0, &pMblk_768P_1);
|
|
Sample_VO_CreateGFXData(1024, 768,
|
|
RK_FMT_RGB888, 1, &pMblk_768P_2);
|
|
} else if (ctx->bHomologous) {
|
|
Sample_Print("Homologous UI Demo test");
|
|
} else {
|
|
Sample_Print("Single HDMI Screen UI Demo test");
|
|
}
|
|
/* Bind Layer */
|
|
VoLayer = RK356X_VOP_LAYER_ESMART_0;
|
|
VoDev = RK356X_VO_DEV_HD0;
|
|
if (ctx->bDoubleScreen) {
|
|
VoLayer_second = RK356X_VOP_LAYER_ESMART_1;
|
|
VoDev_second = RK356X_VO_DEV_HD1;
|
|
RK_MPI_VO_BindLayer(VoLayer_second, VoDev_second, VO_LAYER_MODE_GRAPHIC);
|
|
}
|
|
RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_GRAPHIC);
|
|
|
|
if (ctx->bHomologous) {
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI | VO_INTF_EDP;
|
|
stVoPubAttr.u32BgColor = 0x000000;
|
|
} else {
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI;
|
|
}
|
|
SampleSetVoInterfacetiming(&stVoPubAttr, ctx->enIntfSync);
|
|
Sample_VO_StartDev(VoDev, &stVoPubAttr);
|
|
|
|
stLayerAttr.enPixFormat = plane_format;
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
stLayerAttr.stDispRect.u32Width = ctx->u32Screen0DisplayWidth;
|
|
stLayerAttr.stDispRect.u32Height = ctx->u32Screen0DisplayHeight;
|
|
stLayerAttr.stImageSize.u32Width = ctx->u32Screen0ImageWidth;
|
|
stLayerAttr.stImageSize.u32Height = ctx->u32Screen0ImageHeight;
|
|
Sample_VO_StartLayer(VoLayer, &stLayerAttr);
|
|
|
|
if (ctx->bDoubleScreen) {
|
|
stVoPubAttr.enIntfType = VO_INTF_EDP;
|
|
stVoPubAttr.u32BgColor = 0x000000;
|
|
SampleSetVoInterfacetiming(&stVoPubAttr, ctx->enIntfSync_second);
|
|
Sample_VO_StartDev(VoDev_second, &stVoPubAttr);
|
|
stLayerAttr.enPixFormat = plane_format;
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
stLayerAttr.stDispRect.u32Width = ctx->u32Screen1DisplayWidth;
|
|
stLayerAttr.stDispRect.u32Height = ctx->u32Screen1DisplayHeight;
|
|
stLayerAttr.stImageSize.u32Width = ctx->u32Screen1ImageWidth;
|
|
stLayerAttr.stImageSize.u32Height = ctx->u32Screen1ImageHeight;
|
|
Sample_VO_StartLayer(VoLayer_second, &stLayerAttr);
|
|
}
|
|
|
|
while (1) {
|
|
sleep(1);
|
|
count++;
|
|
if (count % 2) {
|
|
Sample_VO_SetVFrame(pstVFrame,
|
|
1920,
|
|
1080,
|
|
1920,
|
|
1080,
|
|
RK_FMT_RGB888,
|
|
pMblk_1080P_1);
|
|
RK_MPI_VO_SendLayerFrame(VoLayer, pstVFrame);
|
|
if (ctx->bDoubleScreen) {
|
|
Sample_VO_SetVFrame(pstVFrame,
|
|
ctx->u32Screen1DisplayWidth,
|
|
ctx->u32Screen1DisplayHeight,
|
|
ctx->u32Screen1DisplayWidth,
|
|
ctx->u32Screen1DisplayHeight,
|
|
RK_FMT_RGB888,
|
|
pMblk_768P_1);
|
|
RK_MPI_VO_SendLayerFrame(VoLayer_second, pstVFrame);
|
|
}
|
|
} else {
|
|
Sample_VO_SetVFrame(pstVFrame,
|
|
1920,
|
|
1080,
|
|
1920,
|
|
1080,
|
|
RK_FMT_RGB888,
|
|
pMblk_1080P_2);
|
|
RK_MPI_VO_SendLayerFrame(VoLayer, pstVFrame);
|
|
if (ctx->bDoubleScreen) {
|
|
Sample_VO_SetVFrame(pstVFrame,
|
|
ctx->u32Screen1DisplayWidth,
|
|
ctx->u32Screen1DisplayHeight,
|
|
ctx->u32Screen1DisplayWidth,
|
|
ctx->u32Screen1DisplayHeight,
|
|
RK_FMT_RGB888,
|
|
pMblk_768P_2);
|
|
RK_MPI_VO_SendLayerFrame(VoLayer_second, pstVFrame);
|
|
}
|
|
}
|
|
|
|
if (count == ctx->loopCount )
|
|
break;
|
|
}
|
|
|
|
Sample_VO_StopLayer(VoLayer);
|
|
Sample_VO_StopDev(VoDev);
|
|
RK_MPI_VO_UnBindLayer(VoLayer, VoDev);
|
|
RK_MPI_VO_DestroyGraphicsFrameBuffer(pMblk_1080P_1);
|
|
RK_MPI_VO_DestroyGraphicsFrameBuffer(pMblk_1080P_2);
|
|
|
|
if (ctx->bDoubleScreen) {
|
|
Sample_VO_StopLayer(VoLayer_second);
|
|
Sample_VO_StopDev(VoDev_second);
|
|
RK_MPI_VO_UnBindLayer(VoLayer_second, VoDev_second);
|
|
RK_MPI_VO_DestroyGraphicsFrameBuffer(pMblk_768P_1);
|
|
RK_MPI_VO_DestroyGraphicsFrameBuffer(pMblk_768P_2);
|
|
}
|
|
end:
|
|
RK_MPI_VO_CloseFd();
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_Demo_Alpha(TEST_VO_CTX_S *ctx) {
|
|
VO_PUB_ATTR_S stVoPubAttr;
|
|
VO_VIDEO_LAYER_ATTR_S stLayerAttr;
|
|
VoThreadParam stThreadParam;
|
|
RK_U32 u32DispWidth, u32DispHeight, u32GfxLayers;
|
|
VO_LAYER VoGfxLayer, VoVideoLayer;
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
RK_U32 u32VideoWindows;
|
|
pthread_t tThreadDev0;
|
|
PIXEL_FORMAT_E video_format;
|
|
RK_U32 VoWbc;
|
|
PIXEL_FORMAT_E wbc_format;
|
|
VO_LAYER VoLayer;
|
|
VO_DEV VoDev;
|
|
|
|
u32VideoWindows = ctx->u32Windows;
|
|
for (RK_U32 j = 0; j < VDEC_ARRAY_ELEMS(testPixelFormat); j++) {
|
|
if (ctx->s32PixFormat == testPixelFormat[j].index) {
|
|
video_format = testPixelFormat[j].format;
|
|
break;
|
|
}
|
|
}
|
|
/* Bind Layer */
|
|
VoDev == RK356X_VO_DEV_HD0;
|
|
VoGfxLayer = RK356X_VOP_LAYER_ESMART_0;
|
|
VoVideoLayer = RK356X_VOP_LAYER_CLUSTER_0;
|
|
RK_MPI_VO_BindLayer(VoGfxLayer, VoDev, VO_LAYER_MODE_GRAPHIC);
|
|
RK_MPI_VO_BindLayer(VoVideoLayer, VoDev, VO_LAYER_MODE_VIDEO);
|
|
/* Enable VO Dev0 Device */
|
|
u32DispWidth = 1920;
|
|
u32DispHeight = 1080;
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI;
|
|
stVoPubAttr.enIntfSync = VO_OUTPUT_1080P60;
|
|
Sample_VO_StartDev(VoDev, &stVoPubAttr);
|
|
/* Enable Vodev 0 Video Layer */
|
|
if (VoVideoLayer != -1) {
|
|
stLayerAttr.enPixFormat = video_format;
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
stLayerAttr.stDispRect.u32Width = u32DispWidth;
|
|
stLayerAttr.stDispRect.u32Height = u32DispHeight;
|
|
stLayerAttr.stImageSize.u32Width = u32DispWidth;
|
|
stLayerAttr.stImageSize.u32Height = u32DispHeight;
|
|
stLayerAttr.u32DispFrmRt = 25;
|
|
Sample_VO_StartLayer(VoVideoLayer, &stLayerAttr);
|
|
ctx->VoLayer = VoVideoLayer;
|
|
Sample_VO_MultiWindowns_Start(ctx);
|
|
}
|
|
/* Enable Vodev 0 GFX Layer */
|
|
u32GfxLayers = 2;
|
|
if (VoGfxLayer != -1) {
|
|
stLayerAttr.enPixFormat = video_format;
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
stLayerAttr.stDispRect.u32Width = u32DispWidth;
|
|
stLayerAttr.stDispRect.u32Height = u32DispHeight;
|
|
stLayerAttr.stImageSize.u32Width = u32DispWidth;
|
|
stLayerAttr.stImageSize.u32Height = u32DispHeight;
|
|
stLayerAttr.u32DispFrmRt = 25;
|
|
Sample_VO_StartLayer(VoGfxLayer, &stLayerAttr);
|
|
Sample_VO_MultiGFXLayer_Start(VoGfxLayer, u32GfxLayers);
|
|
}
|
|
|
|
Sample_Print("HD0: Start Send Picture\n");
|
|
|
|
stThreadParam.u32Exit = 0;
|
|
stThreadParam.u32VideoWindows = u32VideoWindows;
|
|
stThreadParam.VoVideoLayer = VoVideoLayer;
|
|
stThreadParam.u32GFXLayers = u32GfxLayers;
|
|
stThreadParam.VOGfxLayer = VoGfxLayer;
|
|
Sample_VO_StartSendPicture_Mosaic(&tThreadDev0, &stThreadParam);
|
|
|
|
Sample_Print("Start HD1\n");
|
|
VoDev = RK356X_VO_DEV_HD1;
|
|
/* Bind Vodev1 Layer */
|
|
VoLayer = RK356X_VOP_LAYER_CLUSTER_1;
|
|
RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_VIDEO);
|
|
/* Enable VO Dev1 Device */
|
|
u32DispWidth = 1024;
|
|
u32DispHeight = 768;
|
|
stVoPubAttr.enIntfType = VO_INTF_EDP;
|
|
stVoPubAttr.enIntfSync = VO_OUTPUT_1024x768_60;
|
|
stVoPubAttr.u32BgColor = 0x000000;
|
|
Sample_VO_StartDev(VoDev, &stVoPubAttr);
|
|
/* Enable Layer */
|
|
stLayerAttr.enPixFormat = RK_FMT_BGR888;
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
stLayerAttr.stDispRect.u32Width = u32DispWidth;
|
|
stLayerAttr.stDispRect.u32Height = u32DispHeight;
|
|
stLayerAttr.stImageSize.u32Width = u32DispWidth;
|
|
stLayerAttr.stImageSize.u32Height = u32DispHeight;
|
|
stLayerAttr.u32DispFrmRt = 25;
|
|
Sample_VO_StartLayer(VoLayer, &stLayerAttr);
|
|
|
|
ctx->VoLayer = VoLayer;
|
|
ctx->u32Windows = 1;
|
|
Sample_VO_MultiWindowns_Start(ctx);
|
|
|
|
Sample_Print("Start DEV0 WBC\n");
|
|
/* Start WBC and bind to HD0 */
|
|
VoWbc = 0;
|
|
/* WBC bind source */
|
|
ctx->stWbcCfg.stWbcSource.enSourceType = VO_WBC_SOURCE_DEV;
|
|
ctx->stWbcCfg.stWbcSource.u32SourceId = RK356X_VO_DEV_HD0;
|
|
|
|
RK_MPI_VO_SetWbcSource(VoWbc, &ctx->stWbcCfg.stWbcSource);
|
|
/* Start WBC */
|
|
wbc_format = Sample_wbc_formt(ctx->u32WbcPixFormat);
|
|
|
|
ctx->stWbcCfg.stWbcAttr.enPixelFormat = wbc_format;
|
|
Sample_Print("wbc format is %x\n", ctx->stWbcCfg.stWbcAttr.enPixelFormat);
|
|
|
|
RK_MPI_VO_SetWbcAttr(VoWbc, &ctx->stWbcCfg.stWbcAttr);
|
|
RK_MPI_VO_EnableWbc(VoWbc);
|
|
|
|
if (ctx->wbc_bind == RK_TRUE)
|
|
Sample_VO_BindVoWbc(VoWbc, VoLayer, 0);
|
|
sleep(2);
|
|
while (1) {
|
|
Sample_Print("Press 'q' to quit\n");
|
|
if (getchar() == 'q')
|
|
break;
|
|
}
|
|
Sample_VO_StopSendPicture_Mosaic(tThreadDev0, &stThreadParam);
|
|
Sample_VO_UnBindVoWbc(VoWbc, VoLayer, 0);
|
|
Sample_Print("Stop dev0 WBC\n");
|
|
RK_MPI_VO_DisableWbc(VoWbc);
|
|
|
|
Sample_Print("Stop HD1\n");
|
|
Sample_VO_MultiWindowns_Stop(VoLayer, 1);
|
|
Sample_VO_StopLayer(VoLayer);
|
|
Sample_VO_StopDev(VoDev);
|
|
RK_MPI_VO_UnBindLayer(VoLayer, VoDev);
|
|
|
|
Sample_Print("Stop HD0");
|
|
VoGfxLayer = RK356X_VOP_LAYER_ESMART_0;
|
|
VoVideoLayer = RK356X_VOP_LAYER_CLUSTER_0;
|
|
VoDev = RK356X_VO_DEV_HD0;
|
|
Sample_VO_MultiWindowns_Stop(VoGfxLayer, u32GfxLayers);
|
|
Sample_VO_StopLayer(VoGfxLayer);
|
|
Sample_VO_MultiWindowns_Stop(VoVideoLayer, u32VideoWindows);
|
|
Sample_VO_StopLayer(VoVideoLayer);
|
|
RK_MPI_VO_UnBindLayer(VoGfxLayer, VoDev);
|
|
RK_MPI_VO_UnBindLayer(VoVideoLayer, VoDev);
|
|
Sample_VO_StopDev(VoDev);
|
|
|
|
RK_MPI_VO_CloseFd();
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 Sample_VO_Video_Homologous(TEST_VO_CTX_S *ctx) {
|
|
VO_WBC_SOURCE_S stWbcSource;
|
|
VO_WBC_ATTR_S stWbcAttr;
|
|
RK_U32 VoWbc;
|
|
VIDEO_FRAME_INFO_S *pFrame;
|
|
VO_PUB_ATTR_S stVoPubAttr;
|
|
VO_VIDEO_LAYER_ATTR_S stLayerAttr;
|
|
RK_U32 u32DispWidth, u32DispHeight;
|
|
VO_LAYER VoLayer;
|
|
VO_DEV VoDev;
|
|
RK_S32 u32Windows;
|
|
RK_U32 u32Fps, i;
|
|
pthread_t tThreadID;
|
|
RK_S32 s32Ret = RK_SUCCESS;
|
|
VO_LAYER_MODE_E Vo_layer_mode;
|
|
VoThreadParam stThreadParam;
|
|
PIXEL_FORMAT_E video_format;
|
|
TEST_VO_CTX_S stVoCtx;
|
|
PIXEL_FORMAT_E wbc_format;
|
|
VoDev = ctx->VoDev;
|
|
u32Windows = ctx->u32Windows;
|
|
u32Fps = ctx->u32DispFrmRt;
|
|
VoLayer = ctx->VoLayer;
|
|
for (RK_U32 j = 0; j < VDEC_ARRAY_ELEMS(testPixelFormat); j++) {
|
|
if (ctx->s32PixFormat == testPixelFormat[j].index) {
|
|
video_format = testPixelFormat[j].format;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Sample_Print("%s VoDev %u Windows %u video_format %x\n", __func__, VoDev, u32Windows, video_format);
|
|
|
|
/* Bind Layer */
|
|
switch (ctx->VoLayerMode) {
|
|
case 0:
|
|
Vo_layer_mode = VO_LAYER_MODE_CURSOR;
|
|
break;
|
|
case 1:
|
|
Vo_layer_mode = VO_LAYER_MODE_GRAPHIC;
|
|
break;
|
|
case 2:
|
|
Vo_layer_mode = VO_LAYER_MODE_VIDEO;
|
|
break;
|
|
default:
|
|
Vo_layer_mode = VO_LAYER_MODE_VIDEO;
|
|
}
|
|
|
|
RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_VIDEO);
|
|
|
|
switch (ctx->enIntfType) {
|
|
case DISPLAY_TYPE_VGA:
|
|
stVoPubAttr.enIntfType = VO_INTF_VGA;
|
|
break;
|
|
case DISPLAY_TYPE_HDMI:
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI;
|
|
break;
|
|
case DISPLAY_TYPE_EDP:
|
|
stVoPubAttr.enIntfType = VO_INTF_EDP;
|
|
break;
|
|
case DISPLAY_TYPE_DP:
|
|
stVoPubAttr.enIntfType = VO_INTF_DP;
|
|
break;
|
|
default:
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI;
|
|
Sample_Print("IntfType not set,use INTF_HDMI default\n");
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_LENGTH(test_mode_table); i++) {
|
|
if (ctx->enIntfSync == test_mode_table[i].mode)
|
|
break;
|
|
}
|
|
|
|
if (i == ARRAY_LENGTH(test_mode_table)) {
|
|
Sample_Print("%s not found supported mode in test mode_table\n", __func__);
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
stVoPubAttr.enIntfSync = test_mode_table[i].enIntfSync;
|
|
Sample_VO_StartDev(VoDev, &stVoPubAttr);
|
|
|
|
/* Enable Layer */
|
|
stLayerAttr.enPixFormat = video_format;
|
|
stLayerAttr.stDispRect.s32X = ctx->s32Y;
|
|
stLayerAttr.stDispRect.s32Y = ctx->s32Y;
|
|
if (ctx->VoDev== RK356X_VO_DEV_HD0) {
|
|
stLayerAttr.stDispRect.u32Width = ctx->u32DispWidth;
|
|
stLayerAttr.stDispRect.u32Height = ctx->u32DispHeight;
|
|
stLayerAttr.stImageSize.u32Width = ctx->u32ImgeWidth;
|
|
stLayerAttr.stImageSize.u32Height = ctx->u32ImageHeight;
|
|
} else if (ctx->VoDev== RK356X_VO_DEV_HD1) {
|
|
stLayerAttr.stDispRect.u32Width = 1024;
|
|
stLayerAttr.stDispRect.u32Height = 768;
|
|
stLayerAttr.stImageSize.u32Width = 1024;
|
|
stLayerAttr.stImageSize.u32Height = 768;
|
|
}
|
|
stLayerAttr.u32DispFrmRt = ctx->u32DispFrmRt;
|
|
Sample_VO_StartLayer(VoLayer, &stLayerAttr);
|
|
Sample_VO_MultiWindowns_Start(ctx);
|
|
stThreadParam.u32Exit = 0;
|
|
stThreadParam.u32VideoWindows = u32Windows;
|
|
stThreadParam.VoVideoLayer = VoLayer;
|
|
stThreadParam.VOGfxLayer = -1;
|
|
stThreadParam.u32GFXLayers = -1;
|
|
|
|
Sample_Print("Start Send Picture\n");
|
|
Sample_VO_StartSendPicture_Mosaic(&tThreadID, &stThreadParam);
|
|
|
|
Sample_Print("Start HD1\n");
|
|
/* Start HD1 Device */
|
|
VoDev = RK356X_VO_DEV_HD1;
|
|
/* Bind Layer */
|
|
VoLayer = RK356X_VOP_LAYER_CLUSTER_1;
|
|
RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_VIDEO);
|
|
|
|
/* Enable VO Device */
|
|
if (VoDev == RK356X_VO_DEV_HD0) {
|
|
u32DispWidth = 1920;
|
|
u32DispHeight = 1080;
|
|
stVoPubAttr.enIntfType = VO_INTF_HDMI;
|
|
stVoPubAttr.enIntfSync = VO_OUTPUT_1080P50;
|
|
} else if (VoDev == RK356X_VO_DEV_HD1) {
|
|
u32DispWidth = 1024;
|
|
u32DispHeight = 768;
|
|
stVoPubAttr.u32BgColor = 0x000000;
|
|
stVoPubAttr.enIntfType = VO_INTF_EDP;
|
|
stVoPubAttr.enIntfSync = VO_OUTPUT_1024x768_60;
|
|
} else {
|
|
s32Ret = RK_FAILURE;
|
|
// goto end;
|
|
}
|
|
Sample_VO_StartDev(VoDev, &stVoPubAttr);
|
|
|
|
/* Enable Layer */
|
|
stLayerAttr.enPixFormat = RK_FMT_BGR888;
|
|
stLayerAttr.stDispRect.s32X = 0;
|
|
stLayerAttr.stDispRect.s32Y = 0;
|
|
stLayerAttr.stDispRect.u32Width = u32DispWidth;
|
|
stLayerAttr.stDispRect.u32Height = u32DispHeight;
|
|
stLayerAttr.stImageSize.u32Width = u32DispWidth;
|
|
stLayerAttr.stImageSize.u32Height = u32DispHeight;
|
|
stLayerAttr.u32DispFrmRt = 25;
|
|
Sample_VO_StartLayer(VoLayer, &stLayerAttr);
|
|
|
|
ctx->VoLayer = RK356X_VOP_LAYER_CLUSTER_1;
|
|
ctx->u32Windows = 1;
|
|
Sample_VO_MultiWindowns_Start(ctx);
|
|
|
|
Sample_Print("Start Cluster0 WBC\n");
|
|
|
|
/* Start WBC and bind to HD0 */
|
|
VoWbc = 0;
|
|
/* WBC bind source */
|
|
ctx->stWbcCfg.stWbcSource.enSourceType = VO_WBC_SOURCE_VIDEO;
|
|
ctx->stWbcCfg.stWbcSource.u32SourceId = RK356X_VO_DEV_HD0;
|
|
|
|
RK_MPI_VO_SetWbcSource(VoWbc, &ctx->stWbcCfg.stWbcSource);
|
|
|
|
/* Start WBC */
|
|
wbc_format = Sample_wbc_formt(ctx->u32WbcPixFormat);
|
|
|
|
ctx->stWbcCfg.stWbcAttr.enPixelFormat = wbc_format;
|
|
if (ctx->u32WbcWidth > 1920 && ctx->u32WbcHeight > 1080) {
|
|
Sample_Print("WBC resolution exceeding 1080P\n");
|
|
ctx->u32WbcWidth = 1920;
|
|
ctx->u32WbcHeight = 1080;
|
|
}
|
|
|
|
ctx->stWbcCfg.stWbcAttr.stTargetSize.u32Width = ctx->u32WbcWidth;
|
|
ctx->stWbcCfg.stWbcAttr.stTargetSize.u32Height = ctx->u32WbcHeight;
|
|
|
|
Sample_Print("wbc format is %x\n", ctx->stWbcCfg.stWbcAttr.enPixelFormat);
|
|
|
|
RK_MPI_VO_SetWbcAttr(VoWbc, &ctx->stWbcCfg.stWbcAttr);
|
|
RK_MPI_VO_EnableWbc(VoWbc);
|
|
|
|
Sample_Print("--------------\nWBC Enabled\n---------------\n");
|
|
|
|
if (ctx->wbc_auto == RK_TRUE) {
|
|
/* Bind WBC to HD1 */
|
|
if (ctx->wbc_bind == RK_TRUE)
|
|
Sample_VO_BindVoWbc(VoWbc, VoLayer, 0);
|
|
|
|
while (1) {
|
|
Sample_Print("Press 'q' to quit\n");
|
|
if (getchar() == 'q')
|
|
break;
|
|
}
|
|
Sample_VO_StopSendPicture_Mosaic(tThreadID, &stThreadParam);
|
|
Sample_Print("Stop WBC\n");
|
|
Sample_VO_UnBindVoWbc(VoWbc, VoLayer, 0);
|
|
RK_MPI_VO_DisableWbc(VoWbc);
|
|
Sample_Print("Stop HD1\n");
|
|
Sample_VO_MultiWindowns_Stop(VoLayer, 1);
|
|
Sample_VO_StopLayer(VoLayer);
|
|
Sample_VO_StopDev(VoDev);
|
|
RK_MPI_VO_UnBindLayer(VoLayer, VoDev);
|
|
Sample_Print("Stop HD0\n");
|
|
VoDev = RK356X_VO_DEV_HD0;
|
|
VoLayer = RK356X_VOP_LAYER_CLUSTER_0;
|
|
|
|
Sample_VO_MultiWindowns_Stop(VoLayer, u32Windows);
|
|
Sample_VO_StopLayer(VoLayer);
|
|
Sample_VO_StopDev(VoDev);
|
|
RK_MPI_VO_CloseFd();
|
|
}
|
|
|
|
return s32Ret;
|
|
}
|
|
|
|
static RK_S32 check_options(const TEST_VO_CTX_S *ctx) {
|
|
if (ctx->VoDev > VO_MAX_DEV_NUM) {
|
|
RK_LOGE("illegal param, pls enter 0 or 1 max Vodev is %d!", VO_MAX_DEV_NUM);
|
|
goto __FAILED;
|
|
}
|
|
if ((ctx->VoLayerMode == 2) && (ctx->VoLayer > VO_MAX_LAYER_NUM)) {
|
|
RK_LOGE("illegal param, pls enter 0 or 2 max VoLyer is %d!", VO_MAX_LAYER_NUM);
|
|
goto __FAILED;
|
|
}
|
|
if ((ctx->VoLayerMode == 1) && (ctx->VoLayer > VO_MAX_LAYER_NUM)) {
|
|
RK_LOGE("illegal param, pls enter 4 or 5 max VoLyer is %d!", VO_MAX_LAYER_NUM);
|
|
goto __FAILED;
|
|
}
|
|
if (ctx->u32Windows <= 0 || ctx->u32Windows >= MAX_WINDOWS_NUM) {
|
|
RK_LOGE("illegal param, windos rang [1,63] max u32Windows is %d!", MAX_WINDOWS_NUM);
|
|
goto __FAILED;
|
|
}
|
|
if (ctx->u32WbcPixFormat >= MAX_VO_FORMAT_RGB_NUM) {
|
|
RK_LOGE("illegal param, WBC PixFormat rang [0,3]");
|
|
goto __FAILED;
|
|
}
|
|
if (ctx->s32PixFormat > MAX_VO_FORMAT_RGB_NUM) {
|
|
RK_LOGE("illegal param, Vidoe PixFormat rang [0,17]");
|
|
goto __FAILED;
|
|
}
|
|
|
|
return RK_SUCCESS;
|
|
|
|
__FAILED:
|
|
return RK_FAILURE;
|
|
}
|
|
|
|
static const char *const usages[] = {
|
|
"./rk_mpi_vo_test [-i SRC_PATH] [--imag_width IMG_WIDTH]"
|
|
"[--imag_height IMG_HEIGHT] [--dis_width DIS_WIDTH] [--dis_height DIS_HEIGHT]...",
|
|
NULL,
|
|
};
|
|
|
|
static void mpi_vo_test_show_options(const TEST_VO_CTX_S *ctx) {
|
|
RK_PRINT("cmd parse result:\n");
|
|
RK_PRINT("vop device id : %d\n", ctx->VoDev);
|
|
RK_PRINT("vop layer id : %d\n", ctx->VoLayer);
|
|
RK_PRINT("window size : %d\n", ctx->u32Windows);
|
|
RK_PRINT("connector type : %d\n", ctx->enIntfType);
|
|
RK_PRINT("display mode : %d\n", ctx->enIntfSync);
|
|
RK_PRINT("layer mode : %d\n", ctx->VoLayerMode);
|
|
RK_PRINT("display resolution rect X : %d\n", ctx->s32X);
|
|
RK_PRINT("display resolution rect Y : %d\n", ctx->s32Y);
|
|
RK_PRINT("display pixel format : %d\n", ctx->s32PixFormat);
|
|
RK_PRINT("display resolution width : %d\n", ctx->u32DispWidth);
|
|
RK_PRINT("display resolution height : %d\n", ctx->u32DispHeight);
|
|
RK_PRINT("display resolution0 width : %d\n", ctx->u32Screen0DisplayWidth);
|
|
RK_PRINT("display resolution0 height : %d\n", ctx->u32Screen0DisplayHeight);
|
|
RK_PRINT("display resolution1 width : %d\n", ctx->u32Screen1DisplayWidth);
|
|
RK_PRINT("display resolution1 height : %d\n", ctx->u32Screen1DisplayHeight);
|
|
RK_PRINT("double screen : %d\n", ctx->bDoubleScreen);
|
|
RK_PRINT("display rate : %d\n", ctx->u32DispFrmRt);
|
|
RK_PRINT("display rate ratio : %d\n", ctx->u32DispFrmRtRatio);
|
|
RK_PRINT("chn display mode : %d\n", ctx->u32ChnDismode);
|
|
RK_PRINT("chn Border lpx : %d\n", ctx->stBorderCfg.u32LeftWidth);
|
|
RK_PRINT("chn Border rpx : %d\n", ctx->stBorderCfg.u32RightWidth);
|
|
RK_PRINT("chn Border tpx : %d\n", ctx->stBorderCfg.u32TopWidth);
|
|
RK_PRINT("chn Border bpx : %d\n", ctx->stBorderCfg.u32BottomWidth);
|
|
RK_PRINT("video aspect ratio mode : %d\n", ctx->uEnMode);
|
|
RK_PRINT("input ImgWidth : %d\n", ctx->u32ImgeWidth);
|
|
RK_PRINT("input ImgHeight : %d\n", ctx->u32ImageHeight);
|
|
RK_PRINT("ui : %d\n", ctx->ui);
|
|
RK_PRINT("loopcount : %d\n", ctx->loopCount);
|
|
RK_PRINT("ui alpha : %d\n", ctx->ui_alpha);
|
|
RK_PRINT("wbc enable : %d\n", ctx->wbc_enable);
|
|
RK_PRINT("wbc bind enable : %d\n", ctx->wbc_bind);
|
|
RK_PRINT("wbc width : %d\n", ctx->u32WbcWidth);
|
|
RK_PRINT("wbc height : %d\n", ctx->u32WbcHeight);
|
|
RK_PRINT("wbc compress mode : %d\n", ctx->u32WbcCompressMode);
|
|
RK_PRINT("wbc pixel format : %d\n", ctx->u32WbcPixFormat);
|
|
RK_PRINT("wbc source type : %d\n", ctx->u32WbcSourceType);
|
|
RK_PRINT("wbc souce id : %d\n", ctx->u32WbcSourceId);
|
|
}
|
|
|
|
void init_cfg(TEST_VO_CTX_S *ctx) {
|
|
RK_S32 i = 0;
|
|
|
|
ctx->loopCount = 10;
|
|
ctx->u32Windows = 4;
|
|
ctx->enIntfType = 0; /* 0: HDMI 1: EDP 2: VGA 3: DP */
|
|
ctx->enIntfSync = 16; /* 1080P60 */
|
|
ctx->enIntfSync_second = 6; /* 768P */
|
|
|
|
ctx->VoDev = RK356X_VO_DEV_HD0;
|
|
ctx->VoLayer = RK356X_VOP_LAYER_CLUSTER_0;
|
|
ctx->VoLayerMode = 1; /* CURSOR = 0,GRAPHIC = 1,VIDEO = 2,*/
|
|
|
|
ctx->u32ImgeWidth = 1920;
|
|
ctx->u32ImageHeight = 1080;
|
|
|
|
ctx->bDoubleScreen = RK_TRUE;
|
|
ctx->stVoCfg.bDoubleScreen = RK_TRUE;
|
|
ctx->s32X = 0;
|
|
ctx->s32Y = 0;
|
|
ctx->u32Screen0DisplayWidth = 1920;
|
|
ctx->u32Screen0DisplayHeight = 1080;
|
|
ctx->u32Screen1DisplayWidth = 1024;
|
|
ctx->u32Screen1DisplayHeight = 768;
|
|
|
|
ctx->u32Screen0ImageWidth = 1920;
|
|
ctx->u32Screen0ImageHeight = 1080;
|
|
ctx->u32Screen1ImageWidth = 1024;
|
|
ctx->u32Screen1ImageHeight = 768;
|
|
|
|
ctx->u32DispWidth = 1920;
|
|
ctx->u32DispHeight = 1080;
|
|
ctx->s32PixFormat = 5;
|
|
ctx->u32DispFrmRt = 30;
|
|
ctx->u32DispFrmRtRatio = 1;
|
|
ctx->uEnMode = 1;
|
|
|
|
ctx->wbc_auto = RK_TRUE;
|
|
ctx->u32WbcWidth = 1024;
|
|
ctx->u32WbcHeight = 768;
|
|
ctx->u32WbcPixFormat = WBC_FORMAT_BGR888;
|
|
ctx->u32WbcCompressMode = COMPRESS_MODE_NONE;
|
|
ctx->u32WbcSourceType = WBC_SOURCE_VIDEO;
|
|
ctx->u32WbcSourceId = RK356X_VO_DEV_HD0;
|
|
|
|
ctx->bVoPlay = RK_FALSE;
|
|
ctx->bBorder = RK_FALSE;
|
|
ctx->bHomologous = RK_FALSE;
|
|
ctx->u32Screen0Chn = 16;
|
|
ctx->u32Screen1Chn = 4;
|
|
ctx->bEnWbc = RK_FALSE;
|
|
ctx->wbc_bind = RK_FALSE;
|
|
ctx->bChnPriority = RK_FALSE;
|
|
ctx->bEnWbcToVO = RK_TRUE;
|
|
ctx->s32LoopCount = -1;
|
|
ctx->u32ChnDismode = VO_CHANNEL_PLAY_NORMAL;
|
|
|
|
ctx->stVoCfg.u32Screen0VoLayer = RK356X_VOP_LAYER_CLUSTER_0;
|
|
ctx->stVoCfg.u32Screen1VoLayer = RK356X_VOP_LAYER_CLUSTER_1;
|
|
ctx->stVoCfg.u32Screen0Rows = 4;
|
|
ctx->stVoCfg.u32Screen1Rows = 3;
|
|
|
|
ctx->stVdecCfg.u32FrameBufferCnt = MAX_FRAME_QUEUE;
|
|
ctx->stVdecCfg.enCompressMode = COMPRESS_AFBC_16x16;
|
|
ctx->stWbcCfg.stWbcSource.enSourceType = VO_WBC_SOURCE_VIDEO;
|
|
ctx->stWbcCfg.stWbcSource.u32SourceId = RK356X_VO_DEV_HD0;
|
|
ctx->stWbcCfg.stWbcAttr.enPixelFormat = RK_FMT_YUV420SP;
|
|
ctx->stWbcCfg.stWbcAttr.stTargetSize.u32Width = 1024;
|
|
ctx->stWbcCfg.stWbcAttr.stTargetSize.u32Height = 768;
|
|
ctx->stWbcCfg.stWbcAttr.u32FrameRate = 25;
|
|
ctx->stWbcCfg.stWbcAttr.enCompressMode = COMPRESS_MODE_NONE;
|
|
ctx->stWbcCfg.s32ChnId = 0;
|
|
ctx->stWbcCfg.s32VdecChnId = -1;
|
|
|
|
ctx->stBorderCfg.u32BottomWidth = 2;
|
|
ctx->stBorderCfg.u32TopWidth = 2;
|
|
ctx->stBorderCfg.u32LeftWidth = 2;
|
|
ctx->stBorderCfg.u32RightWidth = 2;
|
|
}
|
|
|
|
int main(int argc, const char **argv) {
|
|
RK_S32 s32Ret;
|
|
TEST_VO_CTX_S ctx;
|
|
|
|
memset(&ctx, 0, sizeof(TEST_VO_CTX_S));
|
|
|
|
init_cfg(&ctx);
|
|
|
|
struct argparse_option options[] = {
|
|
OPT_HELP(),
|
|
OPT_GROUP("basic options:"),
|
|
OPT_STRING('i', "input", &(ctx.cfgFileUri),
|
|
"input config file. <required>", NULL, 0, 0),
|
|
OPT_INTEGER('d', "device_id", &(ctx.VoDev),
|
|
"Vop id. e.g.(0/1). default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('l', "layer_id", &(ctx.VoLayer),
|
|
"Layer id. e.g.(0/2/4/6) default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_enable", &(ctx.wbc_enable),
|
|
"wbc_enalbe. e.g.(0) default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_bind", &(ctx.wbc_bind),
|
|
"enable wbc bind, default(1): 0: disable, 1: enable", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "ui", &(ctx.ui),
|
|
"ui. e.g.(0) default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "loopCount", &(ctx.loopCount),
|
|
"loopCount. e.g.(0) default(10).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "ui_alpha", &(ctx.ui_alpha),
|
|
"ui_alpha. e.g.(0) default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('w', "Windows", &(ctx.u32Windows),
|
|
"windows num. e.g [1-64] default(4),max is 63.", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "ConnectorType", &(ctx.enIntfType),
|
|
"Connctor Type. e.g.(0: HDMI 1: EDP 2: VGA). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "layer_mode", &(ctx.VoLayerMode),
|
|
"Layer type. e.g.(0: CURSOR 1: UI 2: Video). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "display_mode", &(ctx.enIntfSync),
|
|
"dispaly. e.g.(12/14) default (12. 12 is 1080P60). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "display0_mode", &(ctx.enIntfSync_second),
|
|
"dispaly. e.g.(12/14) default (12. 12 is 1080P60). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp_frmrt", &(ctx.u32DispFrmRt),
|
|
"disp_frmrt. default(25).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp_frmrt_ratio", &(ctx.u32DispFrmRtRatio),
|
|
"disp_frmrt_ratio. e.g.(32, 16, 8, 4, 2 ,1). default(1).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "aspect_mode", &(ctx.uEnMode),
|
|
"video aspect ratio."
|
|
"e.g.(1: ratio no change 2: ratio manual set). default(1).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "border_lpx", &(ctx.stBorderCfg.u32LeftWidth),
|
|
"chn Border lpx. default(2).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "border_rpx", &(ctx.stBorderCfg.u32RightWidth),
|
|
"chn Border rpx. default(2).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "border_tpx", &(ctx.stBorderCfg.u32TopWidth),
|
|
"chn Border tpx. default(2).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "border_bpx", &(ctx.stBorderCfg.u32BottomWidth),
|
|
"chn Border bpx. default(2).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp_x", &(ctx.s32X),
|
|
"disp_x. default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp_y", &(ctx.s32Y),
|
|
"disp_y. default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "video_format", &(ctx.s32PixFormat),
|
|
"video pixel format."
|
|
"e.g.(0: ARGB8888 1: ABGR888 2: RGB888 3: BGR888 4: RK_FMT_YUV420SP)."
|
|
"default(4. 4 is RGB888).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp_width", &(ctx.u32DispWidth),
|
|
"dst width. e.g.(1920). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp_height", &(ctx.u32DispHeight),
|
|
"dst height. e.g.(1080). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "image0_width", &(ctx.u32Screen0ImageWidth),
|
|
"image0 width. e.g.(1920). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "image0_height", &(ctx.u32Screen0ImageHeight),
|
|
"image0 height. e.g.(1080). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "image1_width", &(ctx.u32Screen1ImageWidth),
|
|
"image1 width. e.g.(1024). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "image1_height", &(ctx.u32Screen1ImageHeight),
|
|
"image1 height. e.g.(768). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp0_width", &(ctx.u32Screen0DisplayWidth),
|
|
"dst width. e.g.(1920). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp0_height", &(ctx.u32Screen0DisplayHeight),
|
|
"dst height. e.g.(1080). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp1_width", &(ctx.u32Screen1DisplayWidth),
|
|
"dst width. e.g.(1024). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "disp1_height", &(ctx.u32Screen1DisplayHeight),
|
|
"dst height. e.g.(768). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "image_width", &(ctx.u32ImgeWidth),
|
|
"dst width. e.g.(1920). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "image_height", &(ctx.u32ImageHeight),
|
|
"dst height. e.g.(1080). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_width", &(ctx.u32WbcWidth),
|
|
"dst width. e.g.(1920). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_height", &(ctx.u32WbcHeight),
|
|
"dst height. e.g.(1080). <required>", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_compress", &(ctx.u32WbcCompressMode),
|
|
"wbc compress mode. default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_format", &(ctx.u32WbcPixFormat),
|
|
"wbc pixel format."
|
|
"e.g.(0: ARGB8888 1: ABGR888 2: RGB888 3: BGR888)."
|
|
"default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_type", &(ctx.u32WbcSourceType),
|
|
"wbc souce type. e.g.(0: dev 1: video default(1).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_id", &(ctx.u32WbcSourceId),
|
|
"wbc souce id. default(0).", NULL, 0, 0),
|
|
OPT_STRING('\0', "voplay", &(ctx.bVoPlay),
|
|
"play video test, default(0): 0: RK_FALSE, 1: RK_TRUE", NULL, 0, 0),
|
|
OPT_STRING('\0', "bBorder", &(ctx.bBorder),
|
|
"Border enable, default(0): 0: RK_FALSE, 1: RK_TRUE", NULL, 0, 0),
|
|
OPT_STRING('\0', "wbc_auto", &(ctx.wbc_auto),
|
|
"wbc auto bind, default(1): 0: RK_FALSE, 1: RK_TRUE", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "screen0_chn", &(ctx.u32Screen0Chn),
|
|
"the channel num of screen0. default(16)", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "chn_display", &(ctx.u32ChnDismode),
|
|
"the chn dispaly mode."
|
|
"e.g.(0: normol 1: pause 2: step 3: speed).default(0).", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "screen1_chn", &(ctx.u32Screen1Chn),
|
|
"the channel num of screen1 default(4)", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "screen0_rows", &(ctx.stVoCfg.u32Screen0Rows),
|
|
"the rows/cols of screen0 display. default(4: 4x4)", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "screen1_rows", &(ctx.stVoCfg.u32Screen1Rows),
|
|
"the rows/cols of screen1 display.default(3 : 3x3)", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "en_wbc", &(ctx.bEnWbc),
|
|
"enable wbc. default(0)", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "en_chnPriority", &(ctx.bChnPriority),
|
|
"enable Chn Priority. default(0)", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "wbc_src", &(ctx.stWbcCfg.stWbcSource.u32SourceId),
|
|
"the source of wbc, default(1)", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "double_screen", &(ctx.bDoubleScreen),
|
|
"double screen or not, default(1): 0: FALSE, 1: TRUE", NULL, 0, 0),
|
|
OPT_INTEGER('\0', "Homologous", &(ctx.bHomologous),
|
|
"Homologous Display, 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);
|
|
|
|
mpi_vo_test_show_options(&ctx);
|
|
|
|
if (check_options(&ctx)) {
|
|
RK_LOGE("illegal input parameters");
|
|
argparse_usage(&argparse);
|
|
goto __FAILED;
|
|
}
|
|
|
|
if (RK_MPI_SYS_Init() != RK_SUCCESS) {
|
|
goto __FAILED;
|
|
}
|
|
|
|
if (ctx.wbc_enable) {
|
|
Sample_VO_Video_Homologous(&ctx);
|
|
} else if (ctx.ui_alpha) {
|
|
Sample_VO_Demo_Alpha(&ctx);
|
|
} else if (ctx.ui) {
|
|
Sample_VO_Demo_UI(&ctx);
|
|
} else if (ctx.bVoPlay) {
|
|
unit_mpi_voplay_test(&ctx);
|
|
} else {
|
|
Sample_VO_Demo_Video_Mosaic(&ctx);
|
|
}
|
|
|
|
Sample_Print("test running ok.");
|
|
|
|
return RK_SUCCESS;
|
|
__FAILED:
|
|
RK_LOGE("test running failed!");
|
|
return RK_FAILURE;
|
|
}
|