1 /*
2 * Copyright 2020 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #include <stdio.h>
19 #include <sys/poll.h>
20 #include <errno.h>
21 #include <cstring>
22 #include <cstdlib>
23 #include <unistd.h>
24 #include <pthread.h>
25
26 #include "rk_defines.h"
27 #include "rk_debug.h"
28 #include "rk_mpi_vi.h"
29 #include "rk_mpi_mb.h"
30 #include "rk_mpi_sys.h"
31 #include "rk_mpi_venc.h"
32 #include "rk_mpi_vpss.h"
33 #include "rk_mpi_vo.h"
34 #include "rk_mpi_rgn.h"
35 #include "rk_common.h"
36 #include "rk_comm_rgn.h"
37 #include "rk_comm_vi.h"
38 #include "rk_comm_vo.h"
39 #include "test_common.h"
40 #include "test_comm_utils.h"
41 #include "test_comm_argparse.h"
42 #include "rk_mpi_cal.h"
43 #include "rk_mpi_mmz.h"
44
45 #define TEST_VENC_MAX 2
46 #define TEST_WITH_FD 0
47 #define TEST_WITH_FD_SWITCH 0
48
49 #undef DBG_MOD_ID
50 #define DBG_MOD_ID RK_ID_VI
51
52 // for 356x vo
53 #define RK356X_VO_DEV_HD0 0
54 #define RK356X_VO_DEV_HD1 1
55 #define RK356X_VOP_LAYER_CLUSTER_0 0
56 #define RK356X_VOP_LAYER_CLUSTER_1 2
57 #define RK356X_VOP_LAYER_ESMART_0 4
58 #define RK356X_VOP_LAYER_ESMART_1 5
59 #define RK356X_VOP_LAYER_SMART_0 6
60 #define RK356X_VOP_LAYER_SMART_1 7
61
62 #define TEST_VI_SENSOR_NUM 6
63
64 typedef struct _rkTestVencCfg {
65 RK_BOOL bOutDebugCfg;
66 VENC_CHN_ATTR_S stAttr;
67 RK_CHAR dstFilePath[128];
68 RK_CHAR dstFileName[128];
69 RK_S32 s32ChnId;
70 FILE *fp;
71 RK_S32 selectFd;
72 } TEST_VENC_CFG;
73
74 typedef struct rkVPSS_CFG_S {
75 const char *dstFilePath;
76 RK_S32 s32DevId;
77 RK_S32 s32ChnId;
78 RK_U32 u32VpssChnCnt;
79 VPSS_GRP_ATTR_S stGrpVpssAttr;
80 VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_CHN_NUM];
81 } VPSS_CFG_S;
82
83 typedef struct rkRGN_CFG_S {
84 RGN_ATTR_S stRgnAttr;
85 RGN_CHN_ATTR_S stRgnChnAttr;
86 } RGN_CFG_S;
87
88 typedef enum rkTestVIMODE_E {
89 TEST_VI_MODE_VI_ONLY = 0,
90 TEST_VI_MODE_BIND_VENC = 1,
91 TEST_VI_MODE_BIND_VENC_MULTI = 2,
92 TEST_VI_MODE_BIND_VPSS_BIND_VENC = 3,
93 TEST_VI_MODE_BIND_VO = 4,
94 TEST_VI_MODE_MUTI_VI = 5,
95 } TEST_VI_MODE_E;
96
97 typedef struct _rkMpiVICtx {
98 RK_S32 width;
99 RK_S32 height;
100 RK_S32 devId;
101 RK_S32 pipeId;
102 RK_S32 channelId;
103 RK_S32 loopCountSet;
104 RK_S32 selectFd;
105 RK_BOOL bFreeze;
106 RK_BOOL bEnRgn;
107 RK_S32 s32RgnCnt;
108 RK_S32 rgnType;
109 RK_BOOL bUserPicEnabled;
110 RK_BOOL bGetConnecInfo;
111 RK_BOOL bGetEdid;
112 RK_BOOL bSetEdid;
113 COMPRESS_MODE_E enCompressMode;
114 VI_DEV_ATTR_S stDevAttr;
115 VI_DEV_BIND_PIPE_S stBindPipe;
116 VI_CHN_ATTR_S stChnAttr;
117 VI_SAVE_FILE_INFO_S stDebugFile;
118 VIDEO_FRAME_INFO_S stViFrame;
119 VI_CHN_STATUS_S stChnStatus;
120 VI_USERPIC_ATTR_S stUsrPic;
121 TEST_VI_MODE_E enMode;
122 const char *aEntityName;
123 // for vi
124 RGN_CFG_S stViRgn;
125 // for venc
126 TEST_VENC_CFG stVencCfg[TEST_VENC_MAX];
127 VENC_STREAM_S stFrame[TEST_VENC_MAX];
128 VPSS_CFG_S stVpssCfg;
129 // for vo
130 VO_LAYER s32VoLayer;
131 VO_DEV s32VoDev;
132 } TEST_VI_CTX_S;
133
134 RK_U8 test_edid[2][128] = {
135 {
136 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x49, 0x70, 0x88, 0x35, 0x01, 0x00, 0x00, 0x00,
137 0x2d, 0x1f, 0x01, 0x03, 0x80, 0x78, 0x44, 0x78, 0x0a, 0xcf, 0x74, 0xa3, 0x57, 0x4c, 0xb0, 0x23,
138 0x09, 0x48, 0x4c, 0x21, 0x08, 0x00, 0x61, 0x40, 0x01, 0x01, 0x81, 0x00, 0x95, 0x00, 0xa9, 0xc0,
139 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0xe8, 0x00, 0x30, 0xf2, 0x70, 0x5a, 0x80, 0xb0, 0x58,
140 0x8a, 0x00, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40,
141 0x58, 0x2c, 0x45, 0x00, 0xb9, 0xa8, 0x42, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x52,
142 0x4b, 0x2d, 0x55, 0x48, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd,
143 0x00, 0x3b, 0x46, 0x1f, 0x8c, 0x3c, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xa3
144 },
145 {
146 0x02, 0x03, 0x39, 0xd2, 0x51, 0x07, 0x16, 0x14, 0x05, 0x01, 0x03, 0x12, 0x13, 0x84, 0x22, 0x1f,
147 0x90, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x66, 0x03,
148 0x0c, 0x00, 0x30, 0x00, 0x10, 0x67, 0xd8, 0x5d, 0xc4, 0x01, 0x78, 0xc8, 0x07, 0xe3, 0x05, 0x03,
149 0x01, 0xe4, 0x0f, 0x00, 0xf0, 0x01, 0xe2, 0x00, 0xff, 0x08, 0xe8, 0x00, 0x30, 0xf2, 0x70, 0x5a,
150 0x80, 0xb0, 0x58, 0x8a, 0x00, 0xc4, 0x8e, 0x21, 0x00, 0x00, 0x1e, 0x02, 0x3a, 0x80, 0x18, 0x71,
151 0x38, 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0xb9, 0xa8, 0x42, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1
154 }
155 };
156
create_vpss(VPSS_CFG_S * pstVpssCfg,RK_S32 s32Grp,RK_S32 s32OutChnNum)157 static RK_S32 create_vpss(VPSS_CFG_S *pstVpssCfg, RK_S32 s32Grp, RK_S32 s32OutChnNum) {
158 RK_S32 s32Ret = RK_SUCCESS;
159 VPSS_CHN VpssChn[VPSS_MAX_CHN_NUM] = { VPSS_CHN0, VPSS_CHN1, VPSS_CHN2, VPSS_CHN3 };
160 VPSS_CROP_INFO_S stCropInfo;
161
162 s32Ret = RK_MPI_VPSS_CreateGrp(s32Grp, &pstVpssCfg->stGrpVpssAttr);
163 if (s32Ret != RK_SUCCESS) {
164 return s32Ret;
165 }
166
167 for (RK_S32 i = 0; i < s32OutChnNum; i++) {
168 s32Ret = RK_MPI_VPSS_SetChnAttr(s32Grp, VpssChn[i], &pstVpssCfg->stVpssChnAttr[i]);
169 if (s32Ret != RK_SUCCESS) {
170 return s32Ret;
171 }
172 s32Ret = RK_MPI_VPSS_EnableChn(s32Grp, VpssChn[i]);
173 if (s32Ret != RK_SUCCESS) {
174 return s32Ret;
175 }
176 }
177
178 s32Ret = RK_MPI_VPSS_EnableBackupFrame(s32Grp);
179 if (s32Ret != RK_SUCCESS) {
180 return s32Ret;
181 }
182
183 s32Ret = RK_MPI_VPSS_StartGrp(s32Grp);
184 if (s32Ret != RK_SUCCESS) {
185 return s32Ret;
186 }
187
188 return RK_SUCCESS;
189 }
190
destory_vpss(RK_S32 s32Grp,RK_S32 s32OutChnNum)191 static RK_S32 destory_vpss(RK_S32 s32Grp, RK_S32 s32OutChnNum) {
192 RK_S32 s32Ret = RK_SUCCESS;
193 VPSS_CHN VpssChn[VPSS_MAX_CHN_NUM] = { VPSS_CHN0, VPSS_CHN1, VPSS_CHN2, VPSS_CHN3 };
194
195 s32Ret = RK_MPI_VPSS_StopGrp(s32Grp);
196 if (s32Ret != RK_SUCCESS) {
197 return s32Ret;
198 }
199
200 for (RK_S32 i = 0; i < s32OutChnNum; i++) {
201 s32Ret = RK_MPI_VPSS_DisableChn(s32Grp, VpssChn[i]);
202 if (s32Ret != RK_SUCCESS) {
203 return s32Ret;
204 }
205 }
206
207 s32Ret = RK_MPI_VPSS_DisableBackupFrame(s32Grp);
208 if (s32Ret != RK_SUCCESS) {
209 return s32Ret;
210 }
211
212 s32Ret = RK_MPI_VPSS_DestroyGrp(s32Grp);
213 if (s32Ret != RK_SUCCESS) {
214 return s32Ret;
215 }
216
217 return RK_SUCCESS;
218 }
219
create_venc(TEST_VI_CTX_S * ctx,RK_U32 u32Ch)220 static RK_S32 create_venc(TEST_VI_CTX_S *ctx, RK_U32 u32Ch) {
221 VENC_RECV_PIC_PARAM_S stRecvParam;
222
223 stRecvParam.s32RecvPicNum = ctx->loopCountSet;
224 RK_MPI_VENC_CreateChn(u32Ch, &ctx->stVencCfg[u32Ch].stAttr);
225 RK_MPI_VENC_StartRecvFrame(u32Ch, &stRecvParam);
226
227 return RK_SUCCESS;
228 }
229
init_venc_cfg(TEST_VI_CTX_S * ctx,RK_U32 u32Ch,RK_CODEC_ID_E enType)230 void init_venc_cfg(TEST_VI_CTX_S *ctx, RK_U32 u32Ch, RK_CODEC_ID_E enType) {
231 ctx->stVencCfg[u32Ch].stAttr.stVencAttr.enType = enType;
232 ctx->stVencCfg[u32Ch].s32ChnId = u32Ch;
233 ctx->stVencCfg[u32Ch].stAttr.stVencAttr.enPixelFormat = ctx->stChnAttr.enPixelFormat;
234 ctx->stVencCfg[u32Ch].stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
235 ctx->stVencCfg[u32Ch].stAttr.stRcAttr.stH264Cbr.u32Gop = 60;
236 ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32PicWidth = ctx->width;
237 ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32PicHeight = ctx->height;
238 ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32VirWidth = ctx->width;
239 ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32VirHeight = ctx->height;
240 ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32StreamBufCnt = 5;
241 ctx->stVencCfg[u32Ch].stAttr.stVencAttr.u32BufSize = ctx->width * ctx->height * 3 / 2;
242 }
243
create_vo(TEST_VI_CTX_S * ctx,RK_U32 u32Ch)244 static RK_S32 create_vo(TEST_VI_CTX_S *ctx, RK_U32 u32Ch) {
245 /* Enable VO */
246 VO_PUB_ATTR_S VoPubAttr;
247 VO_VIDEO_LAYER_ATTR_S stLayerAttr;
248 RK_S32 s32Ret = RK_SUCCESS;
249 VO_CHN_ATTR_S stChnAttr;
250 VO_LAYER VoLayer = ctx->s32VoLayer;
251 VO_DEV VoDev = ctx->s32VoDev;
252
253 RK_MPI_VO_DisableLayer(VoLayer);
254 RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_ESMART_0);
255 RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_ESMART_1);
256 RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_SMART_0);
257 RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_SMART_1);
258 RK_MPI_VO_Disable(VoDev);
259
260 memset(&VoPubAttr, 0, sizeof(VO_PUB_ATTR_S));
261 memset(&stLayerAttr, 0, sizeof(VO_VIDEO_LAYER_ATTR_S));
262
263 stLayerAttr.enPixFormat = RK_FMT_RGB888;
264 stLayerAttr.stDispRect.s32X = 0;
265 stLayerAttr.stDispRect.s32Y = 0;
266 stLayerAttr.u32DispFrmRt = 30;
267 stLayerAttr.stDispRect.u32Width = 1920;
268 stLayerAttr.stDispRect.u32Height = 1080;
269 stLayerAttr.stImageSize.u32Width = 1920;
270 stLayerAttr.stImageSize.u32Height = 1080;
271
272 s32Ret = RK_MPI_VO_GetPubAttr(VoDev, &VoPubAttr);
273 if (s32Ret != RK_SUCCESS) {
274 return s32Ret;
275 }
276
277 VoPubAttr.enIntfType = VO_INTF_HDMI;
278 VoPubAttr.enIntfSync = VO_OUTPUT_DEFAULT;
279
280 s32Ret = RK_MPI_VO_SetPubAttr(VoDev, &VoPubAttr);
281 if (s32Ret != RK_SUCCESS) {
282 return s32Ret;
283 }
284 s32Ret = RK_MPI_VO_Enable(VoDev);
285 if (s32Ret != RK_SUCCESS) {
286 return s32Ret;
287 }
288
289 s32Ret = RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_GRAPHIC);
290 if (s32Ret != RK_SUCCESS) {
291 RK_LOGE("RK_MPI_VO_BindLayer failed,s32Ret:%d\n", s32Ret);
292 return RK_FAILURE;
293 }
294
295 s32Ret = RK_MPI_VO_SetLayerAttr(VoLayer, &stLayerAttr);
296 if (s32Ret != RK_SUCCESS) {
297 RK_LOGE("RK_MPI_VO_SetLayerAttr failed,s32Ret:%d\n", s32Ret);
298 return RK_FAILURE;
299 }
300
301 s32Ret = RK_MPI_VO_EnableLayer(VoLayer);
302 if (s32Ret != RK_SUCCESS) {
303 RK_LOGE("RK_MPI_VO_EnableLayer failed,s32Ret:%d\n", s32Ret);
304 return RK_FAILURE;
305 }
306
307 stChnAttr.stRect.s32X = 0;
308 stChnAttr.stRect.s32Y = 0;
309 stChnAttr.stRect.u32Width = stLayerAttr.stImageSize.u32Width;
310 stChnAttr.stRect.u32Height = stLayerAttr.stImageSize.u32Height;
311 stChnAttr.u32Priority = 0;
312 stChnAttr.u32FgAlpha = 128;
313 stChnAttr.u32BgAlpha = 0;
314
315 s32Ret = RK_MPI_VO_SetChnAttr(VoLayer, u32Ch, &stChnAttr);
316 if (s32Ret != RK_SUCCESS) {
317 RK_LOGE("set chn Attr failed,s32Ret:%d\n", s32Ret);
318 return RK_FAILURE;
319 }
320
321 return s32Ret;
322 }
323
test_vi_poll_event(RK_S32 timeoutMsec,RK_S32 fd)324 RK_S32 test_vi_poll_event(RK_S32 timeoutMsec, RK_S32 fd) {
325 RK_S32 num_fds = 1;
326 struct pollfd pollFds[num_fds];
327 RK_S32 ret = 0;
328
329 RK_ASSERT(fd > 0);
330 memset(pollFds, 0, sizeof(pollFds));
331 pollFds[0].fd = fd;
332 pollFds[0].events = (POLLPRI | POLLIN | POLLERR | POLLNVAL | POLLHUP);
333
334 ret = poll(pollFds, num_fds, timeoutMsec);
335
336 if (ret > 0 && (pollFds[0].revents & (POLLERR | POLLNVAL | POLLHUP))) {
337 RK_LOGE("fd:%d polled error", fd);
338 return -1;
339 }
340
341 return ret;
342 }
343
readFromPic(TEST_VI_CTX_S * ctx,VIDEO_FRAME_S * buffer)344 static RK_S32 readFromPic(TEST_VI_CTX_S *ctx, VIDEO_FRAME_S *buffer) {
345 FILE *fp = NULL;
346 RK_S32 s32Ret = RK_SUCCESS;
347 MB_BLK srcBlk = MB_INVALID_HANDLE;
348 PIC_BUF_ATTR_S stPicBufAttr;
349 MB_PIC_CAL_S stMbPicCalResult;
350 const char *user_picture_path = "/data/test_vi_user.yuv";
351
352 stPicBufAttr.u32Width = ctx->width;
353 stPicBufAttr.u32Height = ctx->height;
354 stPicBufAttr.enCompMode = COMPRESS_MODE_NONE;
355 stPicBufAttr.enPixelFormat = RK_FMT_YUV420SP;
356 s32Ret = RK_MPI_CAL_VGS_GetPicBufferSize(&stPicBufAttr, &stMbPicCalResult);
357 if (s32Ret != RK_SUCCESS) {
358 RK_LOGE("get picture buffer size failed. err 0x%x", s32Ret);
359 return RK_NULL;
360 }
361
362 RK_MPI_MMZ_Alloc(&srcBlk, stMbPicCalResult.u32MBSize, RK_MMZ_ALLOC_CACHEABLE);
363
364 fp = fopen(user_picture_path, "rb");
365 if (NULL == fp) {
366 RK_LOGE("open %s fail", user_picture_path);
367 return RK_FAILURE;
368 } else {
369 fread(RK_MPI_MB_Handle2VirAddr(srcBlk), 1 , stMbPicCalResult.u32MBSize, fp);
370 fclose(fp);
371 RK_MPI_SYS_MmzFlushCache(srcBlk, RK_FALSE);
372 RK_LOGD("open %s success", user_picture_path);
373 }
374
375 buffer->u32Width = ctx->width;
376 buffer->u32Height = ctx->height;
377 buffer->u32VirWidth = ctx->width;
378 buffer->u32VirHeight = ctx->height;
379 buffer->enPixelFormat = RK_FMT_YUV420SP;
380 buffer->u32TimeRef = 0;
381 buffer->u64PTS = 0;
382 buffer->enCompressMode = COMPRESS_MODE_NONE;
383 buffer->pMbBlk = srcBlk;
384
385 RK_LOGD("readFromPic width = %d, height = %d size = %d pixFormat = %d",
386 ctx->width, ctx->height, stMbPicCalResult.u32MBSize, RK_FMT_YUV420SP);
387 return RK_SUCCESS;
388 }
389
create_rgn(TEST_VI_CTX_S * ctx)390 static RK_S32 create_rgn(TEST_VI_CTX_S *ctx) {
391 RK_S32 i;
392 RK_S32 s32Ret = RK_SUCCESS;
393 RGN_ATTR_S stRgnAttr;
394 RGN_CHN_ATTR_S stRgnChnAttr;
395 RGN_HANDLE RgnHandle = 0;
396 MPP_CHN_S stMppChn;
397 RGN_TYPE_E rgnType = (RGN_TYPE_E)ctx->rgnType;
398
399 /****************************************
400 step 1: create overlay regions
401 ****************************************/
402 for (i = 0; i < ctx->s32RgnCnt; i++) {
403 ctx->stViRgn.stRgnAttr.unAttr.stOverlay.u32ClutNum = 0;
404 ctx->stViRgn.stRgnAttr.unAttr.stOverlay.stSize.u32Width = 128;
405 ctx->stViRgn.stRgnAttr.unAttr.stOverlay.stSize.u32Height = 128;
406 RgnHandle = i;
407 s32Ret = RK_MPI_RGN_Create(RgnHandle, &ctx->stViRgn.stRgnAttr);
408 if (RK_SUCCESS != s32Ret) {
409 RK_LOGE("RK_MPI_RGN_Create (%d) failed with %#x!", RgnHandle, s32Ret);
410 RK_MPI_RGN_Destroy(RgnHandle);
411 return RK_FAILURE;
412 }
413 RK_LOGI("The handle: %d, create success!", RgnHandle);
414 }
415
416 /*********************************************
417 step 2: display overlay regions to vi
418 *********************************************/
419 for (i = 0; i < ctx->s32RgnCnt; i++) {
420 stMppChn.enModId = RK_ID_VI;
421 stMppChn.s32DevId = ctx->devId;
422 stMppChn.s32ChnId = ctx->channelId;
423 RgnHandle = i;
424
425 memset(&stRgnChnAttr, 0, sizeof(stRgnChnAttr));
426 stRgnChnAttr.bShow = RK_TRUE;
427 stRgnChnAttr.enType = rgnType;
428
429 BITMAP_S stBitmap;
430 switch (rgnType) {
431 case COVER_RGN: {
432 RGN_CHN_ATTR_S stCoverChnAttr;
433 stCoverChnAttr.bShow = RK_TRUE;
434 stCoverChnAttr.enType = COVER_RGN;
435 stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32X = 128 * i;
436 stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32Y = 128 * i;
437 stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Width = 128;
438 stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Height = 128;
439 stCoverChnAttr.unChnAttr.stCoverChn.u32Color = 0xffffff; // white
440 stCoverChnAttr.unChnAttr.stCoverChn.enCoordinate = RGN_ABS_COOR;
441 stCoverChnAttr.unChnAttr.stCoverChn.u32Layer = i;
442
443 s32Ret = RK_MPI_RGN_AttachToChn(RgnHandle, &stMppChn, &stCoverChnAttr);
444 if (RK_SUCCESS != s32Ret) {
445 RK_LOGE("failed with %#x!", s32Ret);
446 goto __EXIT;
447 }
448 s32Ret = RK_MPI_RGN_GetDisplayAttr(RgnHandle, &stMppChn, &stCoverChnAttr);
449 if (RK_SUCCESS != s32Ret) {
450 RK_LOGE("failed with %#x!", s32Ret);
451 goto __EXIT;
452 }
453 stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32X = 128 * i;
454 stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32Y = 128 * i;
455 stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Width = 128;
456 stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Height = 128;
457 stCoverChnAttr.unChnAttr.stCoverChn.u32Color = 0x0000ff; // blue
458 stCoverChnAttr.unChnAttr.stCoverChn.enCoordinate = RGN_ABS_COOR;
459 stCoverChnAttr.unChnAttr.stCoverChn.u32Layer = i;
460 // change cover channel attribute below.
461 s32Ret = RK_MPI_RGN_SetDisplayAttr(RgnHandle, &stMppChn, &stCoverChnAttr);
462 if (RK_SUCCESS != s32Ret) {
463 RK_LOGE("failed with %#x!", s32Ret);
464 goto __EXIT;
465 }
466
467 RK_LOGI("the cover region:%d to <%d, %d, %d, %d>",
468 RgnHandle,
469 stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32X,
470 stCoverChnAttr.unChnAttr.stCoverChn.stRect.s32Y,
471 stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Width,
472 stCoverChnAttr.unChnAttr.stCoverChn.stRect.u32Height);
473 } break;
474 case MOSAIC_RGN: {
475 RGN_CHN_ATTR_S stMoscaiChnAttr;
476 stMoscaiChnAttr.bShow = RK_TRUE;
477 stMoscaiChnAttr.enType = MOSAIC_RGN;
478 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32X = 128 * i;
479 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32Y = 128 * i;
480 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Width = 128;
481 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Height = 128;
482 stMoscaiChnAttr.unChnAttr.stMosaicChn.enBlkSize = MOSAIC_BLK_SIZE_8;
483 stMoscaiChnAttr.unChnAttr.stMosaicChn.u32Layer = i;
484
485 s32Ret = RK_MPI_RGN_AttachToChn(RgnHandle, &stMppChn, &stMoscaiChnAttr);
486 if (RK_SUCCESS != s32Ret) {
487 RK_LOGE("failed with %#x!", s32Ret);
488 goto __EXIT;
489 }
490 s32Ret = RK_MPI_RGN_GetDisplayAttr(RgnHandle, &stMppChn, &stMoscaiChnAttr);
491 if (RK_SUCCESS != s32Ret) {
492 RK_LOGE("failed with %#x!", s32Ret);
493 goto __EXIT;
494 }
495
496 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32X = 128 * i;
497 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32Y = 128 * i;
498 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Width = 128;
499 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Height = 128;
500 stMoscaiChnAttr.unChnAttr.stMosaicChn.enBlkSize = MOSAIC_BLK_SIZE_8;
501 stMoscaiChnAttr.unChnAttr.stMosaicChn.u32Layer = i;
502
503 // change mosaic channel attribute below.
504 s32Ret = RK_MPI_RGN_SetDisplayAttr(RgnHandle, &stMppChn, &stMoscaiChnAttr);
505 if (RK_SUCCESS != s32Ret) {
506 RK_LOGE("failed with %#x!", s32Ret);
507 goto __EXIT;
508 }
509 RK_LOGI("the mosaic region:%d to <%d, %d, %d, %d>",
510 RgnHandle,
511 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32X,
512 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.s32Y,
513 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Width,
514 stMoscaiChnAttr.unChnAttr.stMosaicChn.stRect.u32Height);
515 } break;
516 default:
517 break;
518 }
519 }
520
521 return RK_SUCCESS;
522 __EXIT:
523 for (i = 0; i < ctx->s32RgnCnt; i++) {
524 stMppChn.enModId = RK_ID_VI;
525 stMppChn.s32DevId = ctx->devId;
526 stMppChn.s32ChnId = ctx->channelId;
527 RgnHandle = i;
528 s32Ret = RK_MPI_RGN_DetachFromChn(RgnHandle, &stMppChn);
529 if (RK_SUCCESS != s32Ret) {
530 RK_LOGE("RK_MPI_RGN_DetachFrmChn (%d) failed with %#x!", RgnHandle, s32Ret);
531 return RK_FAILURE;
532 }
533 }
534 return RK_FAILURE;
535 }
536
destory_rgn(TEST_VI_CTX_S * ctx)537 static RK_S32 destory_rgn(TEST_VI_CTX_S *ctx) {
538 RK_S32 i;
539 RK_S32 s32Ret = RK_SUCCESS;
540 RGN_HANDLE RgnHandle = 0;
541
542 for (RK_S32 i = 0; i < ctx->s32RgnCnt; i++) {
543 RgnHandle = i;
544 s32Ret = RK_MPI_RGN_Destroy(RgnHandle);
545 if (RK_SUCCESS != s32Ret) {
546 RK_LOGE("RK_MPI_RGN_Destroy (%d) failed with %#x!", RgnHandle, s32Ret);
547 }
548 RK_LOGI("Destory handle:%d success", RgnHandle);
549 }
550
551 RK_LOGD("vi RK_MPI_RGN_Destroy OK");
552 return RK_SUCCESS;
553 }
554
test_vi_hdmi_rx_infomation(TEST_VI_CTX_S * ctx)555 static RK_S32 test_vi_hdmi_rx_infomation(TEST_VI_CTX_S *ctx) {
556 RK_S32 s32Ret = RK_FAILURE;
557
558 /* test get connect info before enable chn(need after RK_MPI_VI_SetChnAttr)*/
559 if (ctx->bGetConnecInfo) {
560 VI_CONNECT_INFO_S stConnectInfo;
561 s32Ret = RK_MPI_VI_GetChnConnectInfo(ctx->pipeId, ctx->channelId, &stConnectInfo);
562 RK_LOGE("RK_MPI_VI_GetChnConnectInfo %x, w:%d,h:%d,fmt:0x%x,connect:%d", s32Ret,
563 stConnectInfo.u32Width, stConnectInfo.u32Height,
564 stConnectInfo.enPixFmt, stConnectInfo.enConnect);
565 }
566 if (ctx->bGetEdid) {
567 VI_EDID_S stEdid;
568 memset(&stEdid, 0, sizeof(VI_EDID_S));
569 stEdid.u32Blocks = 3;
570 stEdid.pu8Edid = (RK_U8 *)calloc(128 * stEdid.u32Blocks, 1);
571 s32Ret = RK_MPI_VI_GetChnEdid(ctx->pipeId, ctx->channelId, &stEdid);
572 RK_LOGE("RK_MPI_VI_GetChnEdid %x, stEdid.u32Blocks=%d "
573 "edid[0]:0x%x,edid[1]:0x%x,edid[2]:0x%x,edid[3]:0x%x,edid[126]:0x%x edid[127]:0x%x",
574 s32Ret, stEdid.u32Blocks,
575 stEdid.pu8Edid[0], stEdid.pu8Edid[1],
576 stEdid.pu8Edid[2], stEdid.pu8Edid[3],
577 stEdid.pu8Edid[126], stEdid.pu8Edid[127]);
578 free(stEdid.pu8Edid);
579 }
580 if (ctx->bSetEdid) {
581 VI_EDID_S stEdid;
582 memset(&stEdid, 0, sizeof(VI_EDID_S));
583 stEdid.u32Blocks = 2;
584 stEdid.pu8Edid = (RK_U8 *)test_edid;
585 s32Ret = RK_MPI_VI_SetChnEdid(ctx->pipeId, ctx->channelId, &stEdid);
586 RK_LOGE("RK_MPI_VI_SetChnEdid %x, edid[0]:0x%x,edid[1]:0x%x,edid[2]:0x%x,edid[3]:0x%x,"
587 "edid[126]:0x%x edid[127]:0x%x",
588 s32Ret,
589 stEdid.pu8Edid[0], stEdid.pu8Edid[1],
590 stEdid.pu8Edid[2], stEdid.pu8Edid[3],
591 stEdid.pu8Edid[126], stEdid.pu8Edid[127]);
592 }
593
594 return s32Ret;
595 }
596
597
test_vi_init(TEST_VI_CTX_S * ctx)598 static RK_S32 test_vi_init(TEST_VI_CTX_S *ctx) {
599 RK_S32 s32Ret = RK_FAILURE;
600
601 // 0. get dev config status
602 s32Ret = RK_MPI_VI_GetDevAttr(ctx->devId, &ctx->stDevAttr);
603 if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
604 // 0-1.config dev
605 s32Ret = RK_MPI_VI_SetDevAttr(ctx->devId, &ctx->stDevAttr);
606 if (s32Ret != RK_SUCCESS) {
607 RK_LOGE("RK_MPI_VI_SetDevAttr %x", s32Ret);
608 goto __FAILED;
609 }
610 } else {
611 RK_LOGE("RK_MPI_VI_SetDevAttr already");
612 }
613 // 1.get dev enable status
614 s32Ret = RK_MPI_VI_GetDevIsEnable(ctx->devId);
615 if (s32Ret != RK_SUCCESS) {
616 // 1-2.enable dev
617 s32Ret = RK_MPI_VI_EnableDev(ctx->devId);
618 if (s32Ret != RK_SUCCESS) {
619 RK_LOGE("RK_MPI_VI_EnableDev %x", s32Ret);
620 goto __FAILED;
621 }
622 // 1-3.bind dev/pipe
623 ctx->stBindPipe.u32Num = ctx->pipeId;
624 ctx->stBindPipe.PipeId[0] = ctx->pipeId;
625 s32Ret = RK_MPI_VI_SetDevBindPipe(ctx->devId, &ctx->stBindPipe);
626 if (s32Ret != RK_SUCCESS) {
627 RK_LOGE("RK_MPI_VI_SetDevBindPipe %x", s32Ret);
628 goto __FAILED;
629 }
630 } else {
631 RK_LOGE("RK_MPI_VI_EnableDev already");
632 }
633 // 2.config channel
634 ctx->stChnAttr.stSize.u32Width = ctx->width;
635 ctx->stChnAttr.stSize.u32Height = ctx->height;
636 ctx->stChnAttr.enCompressMode = ctx->enCompressMode;
637 s32Ret = RK_MPI_VI_SetChnAttr(ctx->pipeId, ctx->channelId, &ctx->stChnAttr);
638 if (s32Ret != RK_SUCCESS) {
639 RK_LOGE("RK_MPI_VI_SetChnAttr %x", s32Ret);
640 goto __FAILED;
641 }
642
643 /* test user picture */
644 if (ctx->bUserPicEnabled) {
645 ctx->stUsrPic.enUsrPicMode = VI_USERPIC_MODE_BGC;
646 // ctx->stUsrPic.enUsrPicMode = VI_USERPIC_MODE_PIC;
647
648 if (ctx->stUsrPic.enUsrPicMode == VI_USERPIC_MODE_PIC) {
649 s32Ret = readFromPic(ctx, &ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame);
650 if (s32Ret != RK_SUCCESS) {
651 RK_LOGE("RK_MPI_VI_SetUserPic fail:%x", s32Ret);
652 goto __FAILED;
653 }
654 } else if (ctx->stUsrPic.enUsrPicMode == VI_USERPIC_MODE_BGC) {
655 /* set background color */
656 ctx->stUsrPic.unUsrPic.stUsrPicBg.u32BgColor = RGB(0, 0, 128);
657 }
658
659 s32Ret = RK_MPI_VI_SetUserPic(ctx->pipeId, ctx->channelId, &ctx->stUsrPic);
660 if (s32Ret != RK_SUCCESS) {
661 RK_LOGE("RK_MPI_VI_SetUserPic fail:%x", s32Ret);
662 goto __FAILED;
663 }
664
665 s32Ret = RK_MPI_VI_EnableUserPic(ctx->pipeId, ctx->channelId);
666 }
667
668 test_vi_hdmi_rx_infomation(ctx);
669
670 ctx->stViRgn.stRgnAttr.enType = (RGN_TYPE_E)ctx->rgnType;
671 ctx->stViRgn.stRgnChnAttr.bShow = RK_TRUE;
672
673 // open fd before enable chn will be better
674 #if TEST_WITH_FD
675 ctx->selectFd = RK_MPI_VI_GetChnFd(ctx->pipeId, ctx->channelId);
676 RK_LOGE("ctx->pipeId=%d, ctx->channelId=%d, ctx->selectFd:%d ", ctx->pipeId, ctx->channelId, ctx->selectFd);
677 #endif
678 // 3.enable channel
679 s32Ret = RK_MPI_VI_EnableChn(ctx->pipeId, ctx->channelId);
680 if (s32Ret != RK_SUCCESS) {
681 RK_LOGE("RK_MPI_VI_EnableChn %x", s32Ret);
682 goto __FAILED;
683 }
684
685 if (ctx->bEnRgn) {
686 s32Ret = create_rgn(ctx);
687 if (s32Ret != RK_SUCCESS) {
688 RK_LOGE("Error:create rgn failed!");
689 goto __FAILED;
690 }
691 }
692
693 // 4.save debug file
694 if (ctx->stDebugFile.bCfg) {
695 s32Ret = RK_MPI_VI_ChnSaveFile(ctx->pipeId, ctx->channelId, &ctx->stDebugFile);
696 RK_LOGD("RK_MPI_VI_ChnSaveFile %x", s32Ret);
697 }
698
699 __FAILED:
700 return s32Ret;
701 }
702
test_vi_bind_vo_loop(TEST_VI_CTX_S * ctx)703 static RK_S32 test_vi_bind_vo_loop(TEST_VI_CTX_S *ctx) {
704 MPP_CHN_S stSrcChn, stDestChn;
705 RK_S32 loopCount = 0;
706 void *pData = RK_NULL;
707 RK_S32 s32Ret = RK_FAILURE;
708 RK_U32 i;
709
710 s32Ret = test_vi_init(ctx);
711 if (s32Ret != RK_SUCCESS) {
712 RK_LOGE("vi %d:%d init failed:%x", ctx->devId, ctx->channelId, s32Ret);
713 goto __FAILED;
714 }
715
716 // vo init and create
717 ctx->s32VoLayer = RK356X_VOP_LAYER_CLUSTER_0;
718 ctx->s32VoDev = RK356X_VO_DEV_HD0;
719 s32Ret = create_vo(ctx, 0);
720 if (s32Ret != RK_SUCCESS) {
721 RK_LOGE("create vo ch:%d failed", ctx->channelId);
722 goto __FAILED;
723 }
724 // bind vi to vo
725 stSrcChn.enModId = RK_ID_VI;
726 stSrcChn.s32DevId = ctx->devId;
727 stSrcChn.s32ChnId = ctx->channelId;
728
729 stDestChn.enModId = RK_ID_VO;
730 stDestChn.s32DevId = ctx->s32VoLayer;
731 stDestChn.s32ChnId = 0;
732
733 s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
734 if (s32Ret != RK_SUCCESS) {
735 RK_LOGE("vi band vo fail:%x", s32Ret);
736 goto __FAILED;
737 }
738
739 // enable vo
740 s32Ret = RK_MPI_VO_EnableChn(ctx->s32VoLayer, 0);
741 if (s32Ret != RK_SUCCESS) {
742 RK_LOGE("Enalbe vo chn failed, s32Ret = %d\n", s32Ret);
743 goto __FAILED;
744 }
745
746 while (loopCount < ctx->loopCountSet) {
747 loopCount++;
748 //RK_LOGE("loopCount:%d", loopCount);
749 // can not get the vo frameout count . so here regard as 33ms one frame.
750 usleep(33*1000);
751 }
752
753 __FAILED:
754 s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn);
755 if (s32Ret != RK_SUCCESS) {
756 RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
757 }
758 // disable vo
759 RK_MPI_VO_DisableLayer(ctx->s32VoLayer);
760 RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_ESMART_0);
761 RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_ESMART_1);
762 RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_SMART_0);
763 RK_MPI_VO_DisableLayer(RK356X_VOP_LAYER_SMART_1);
764 RK_MPI_VO_DisableChn(ctx->s32VoLayer, 0);
765 RK_MPI_VO_Disable(ctx->s32VoDev);
766
767 // 5. disable one chn
768 s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
769 RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
770
771 RK_MPI_VO_DisableChn(ctx->s32VoLayer, 0);
772
773 // 6.disable dev(will diabled all chn)
774 s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
775 RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
776
777 return s32Ret;
778 }
779
test_vi_bind_vpss_venc_loop(TEST_VI_CTX_S * ctx)780 static RK_S32 test_vi_bind_vpss_venc_loop(TEST_VI_CTX_S *ctx) {
781 MPP_CHN_S stViChn, stVencChn[TEST_VENC_MAX], stVpssChn;
782 RK_S32 loopCount = 0;
783 void *pData = RK_NULL;
784 RK_S32 s32Ret = RK_FAILURE;
785 RK_U32 i;
786 RK_U32 u32DstCount = 1;
787
788 s32Ret = test_vi_init(ctx);
789 if (s32Ret != RK_SUCCESS) {
790 RK_LOGE("vi %d:%d init failed:%x", ctx->devId, ctx->channelId, s32Ret);
791 goto __FAILED;
792 }
793
794 /* vpss */
795 ctx->stVpssCfg.u32VpssChnCnt = 1;
796 ctx->stVpssCfg.stGrpVpssAttr.u32MaxW = 4096;
797 ctx->stVpssCfg.stGrpVpssAttr.u32MaxH = 4096;
798 ctx->stVpssCfg.stGrpVpssAttr.enPixelFormat = RK_FMT_YUV420SP;
799 ctx->stVpssCfg.stGrpVpssAttr.stFrameRate.s32SrcFrameRate = -1;
800 ctx->stVpssCfg.stGrpVpssAttr.stFrameRate.s32DstFrameRate = -1;
801 ctx->stVpssCfg.stGrpVpssAttr.enCompressMode = COMPRESS_MODE_NONE;
802 for (i = 0; i < VPSS_MAX_CHN_NUM; i ++) {
803 ctx->stVpssCfg.stVpssChnAttr[i].enChnMode = VPSS_CHN_MODE_PASSTHROUGH;
804 ctx->stVpssCfg.stVpssChnAttr[i].enDynamicRange = DYNAMIC_RANGE_SDR8;
805 ctx->stVpssCfg.stVpssChnAttr[i].enPixelFormat = RK_FMT_YUV420SP;
806 ctx->stVpssCfg.stVpssChnAttr[i].stFrameRate.s32SrcFrameRate = -1;
807 ctx->stVpssCfg.stVpssChnAttr[i].stFrameRate.s32DstFrameRate = -1;
808 ctx->stVpssCfg.stVpssChnAttr[i].u32Width = ctx->width;
809 ctx->stVpssCfg.stVpssChnAttr[i].u32Height = ctx->height;
810 ctx->stVpssCfg.stVpssChnAttr[i].enCompressMode = COMPRESS_MODE_NONE;
811 }
812
813 // init vpss
814 s32Ret = create_vpss(&ctx->stVpssCfg, 0, ctx->stVpssCfg.u32VpssChnCnt);
815 if (s32Ret != RK_SUCCESS) {
816 RK_LOGE("creat 0 grp vpss failed!");
817 goto __FAILED;
818 }
819 // bind vi to vpss
820 stViChn.enModId = RK_ID_VI;
821 stViChn.s32DevId = ctx->devId;
822 stViChn.s32ChnId = ctx->channelId;
823 stVpssChn.enModId = RK_ID_VPSS;
824 stVpssChn.s32DevId = 0;
825 stVpssChn.s32ChnId = 0;
826
827 RK_LOGD("vi to vpss ch %d vpss group %d", stVpssChn.s32ChnId , stVpssChn.s32DevId);
828 s32Ret = RK_MPI_SYS_Bind(&stViChn, &stVpssChn);
829 if (s32Ret != RK_SUCCESS) {
830 RK_LOGE("vi and vpss bind error ");
831 goto __FAILED;
832 }
833
834 /* venc */
835 for (i = 0; i < u32DstCount; i++) {
836 // venc init and create
837 init_venc_cfg(ctx, i, RK_VIDEO_ID_AVC);
838 s32Ret = create_venc(ctx, ctx->stVencCfg[i].s32ChnId);
839 if (s32Ret != RK_SUCCESS) {
840 RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
841 return s32Ret;
842 }
843 // bind vpss to venc
844 stVencChn[i].enModId = RK_ID_VENC;
845 stVencChn[i].s32DevId = i;
846 stVencChn[i].s32ChnId = ctx->stVencCfg[i].s32ChnId;
847
848 s32Ret = RK_MPI_SYS_Bind(&stVpssChn, &stVencChn[i]);
849 if (s32Ret != RK_SUCCESS) {
850 RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
851 goto __FAILED;
852 }
853 ctx->stFrame[i].pstPack = reinterpret_cast<VENC_PACK_S *>(malloc(sizeof(VENC_PACK_S)));
854 #if TEST_WITH_FD
855 ctx->stVencCfg[i].selectFd = RK_MPI_VENC_GetFd(ctx->stVencCfg[i].s32ChnId);
856 RK_LOGE("venc chn:%d, ctx->selectFd:%d ", ctx->stVencCfg[i].s32ChnId, ctx->stVencCfg[i].selectFd);
857 #endif
858 }
859
860 while (loopCount < ctx->loopCountSet) {
861 for (i = 0; i < u32DstCount; i++) {
862 #if TEST_WITH_FD
863 test_vi_poll_event(-1, ctx->stVencCfg[i].selectFd);
864 #endif
865
866 // freeze test
867 RK_MPI_VI_SetChnFreeze(ctx->pipeId, ctx->channelId, ctx->bFreeze);
868
869 s32Ret = RK_MPI_VENC_GetStream(ctx->stVencCfg[i].s32ChnId, &ctx->stFrame[i], -1);
870 if (s32Ret == RK_SUCCESS) {
871 if (ctx->stVencCfg[i].bOutDebugCfg) {
872 pData = RK_MPI_MB_Handle2VirAddr(ctx->stFrame[i].pstPack->pMbBlk);
873 fwrite(pData, 1, ctx->stFrame[i].pstPack->u32Len, ctx->stVencCfg[i].fp);
874 fflush(ctx->stVencCfg[i].fp);
875 }
876 RK_LOGD("chn:%d, loopCount:%d enc->seq:%d wd:%d\n", i, loopCount,
877 ctx->stFrame[i].u32Seq, ctx->stFrame[i].pstPack->u32Len);
878 s32Ret = RK_MPI_VENC_ReleaseStream(ctx->stVencCfg[i].s32ChnId, &ctx->stFrame[i]);
879 if (s32Ret != RK_SUCCESS) {
880 RK_LOGE("RK_MPI_VENC_ReleaseStream fail %x", s32Ret);
881 }
882 loopCount++;
883 } else {
884 RK_LOGE("RK_MPI_VI_GetChnFrame fail %x", s32Ret);
885 }
886 }
887 usleep(10*1000);
888 }
889
890 __FAILED:
891 // unbind vi->vpss
892 s32Ret = RK_MPI_SYS_UnBind(&stViChn, &stVpssChn);
893 if (s32Ret != RK_SUCCESS) {
894 RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
895 }
896 // unbind vpss->venc
897 for (i = 0; i < u32DstCount; i++) {
898 s32Ret = RK_MPI_SYS_UnBind(&stVpssChn, &stVencChn[i]);
899 if (s32Ret != RK_SUCCESS) {
900 RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
901 }
902 }
903 // destory vpss
904 s32Ret = destory_vpss(0, ctx->stVpssCfg.u32VpssChnCnt);
905 if (s32Ret != RK_SUCCESS) {
906 RK_LOGE("destory vpss error");
907 return s32Ret;
908 }
909 // 5. disable one chn
910 s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
911 RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
912
913 for (i = 0; i < u32DstCount; i++) {
914 s32Ret = RK_MPI_VENC_StopRecvFrame(ctx->stVencCfg[i].s32ChnId);
915 if (s32Ret != RK_SUCCESS) {
916 return s32Ret;
917 }
918 RK_LOGE("destroy enc chn:%d", ctx->stVencCfg[i].s32ChnId);
919 s32Ret = RK_MPI_VENC_DestroyChn(ctx->stVencCfg[i].s32ChnId);
920 if (s32Ret != RK_SUCCESS) {
921 RK_LOGE("RK_MPI_VDEC_DestroyChn fail %x", s32Ret);
922 }
923 }
924
925 // 6.disable dev(will diabled all chn)
926 s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
927 RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
928 for (i = 0; i < u32DstCount; i++) {
929 if (ctx->stFrame[i].pstPack)
930 free(ctx->stFrame[i].pstPack);
931 if (ctx->stVencCfg[i].fp)
932 fclose(ctx->stVencCfg[i].fp);
933 }
934 return s32Ret;
935 }
936
test_vi_bind_venc_loop(TEST_VI_CTX_S * ctx)937 static RK_S32 test_vi_bind_venc_loop(TEST_VI_CTX_S *ctx) {
938 MPP_CHN_S stSrcChn, stDestChn[TEST_VENC_MAX];
939 RK_S32 loopCount = 0;
940 void *pData = RK_NULL;
941 RK_S32 s32Ret = RK_FAILURE;
942 RK_U32 i;
943 RK_U32 u32DstCount = ((ctx->enMode == TEST_VI_MODE_BIND_VENC_MULTI) ? 2 : 1);
944
945 s32Ret = test_vi_init(ctx);
946 if (s32Ret != RK_SUCCESS) {
947 RK_LOGE("vi %d:%d init failed:%x", ctx->devId, ctx->channelId, s32Ret);
948 goto __FAILED;
949 }
950
951 /* venc */
952 for (i = 0; i < u32DstCount; i++) {
953 // venc init and create
954 init_venc_cfg(ctx, i, RK_VIDEO_ID_AVC);
955 s32Ret = create_venc(ctx, ctx->stVencCfg[i].s32ChnId);
956 if (s32Ret != RK_SUCCESS) {
957 RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
958 return s32Ret;
959 }
960 // bind vi to venc
961 stSrcChn.enModId = RK_ID_VI;
962 stSrcChn.s32DevId = ctx->devId;
963 stSrcChn.s32ChnId = ctx->channelId;
964
965 stDestChn[i].enModId = RK_ID_VENC;
966 stDestChn[i].s32DevId = i;
967 stDestChn[i].s32ChnId = ctx->stVencCfg[i].s32ChnId;
968
969 s32Ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn[i]);
970 if (s32Ret != RK_SUCCESS) {
971 RK_LOGE("create %d ch venc failed", ctx->stVencCfg[i].s32ChnId);
972 goto __FAILED;
973 }
974 ctx->stFrame[i].pstPack = reinterpret_cast<VENC_PACK_S *>(malloc(sizeof(VENC_PACK_S)));
975 #if TEST_WITH_FD
976 ctx->stVencCfg[i].selectFd = RK_MPI_VENC_GetFd(ctx->stVencCfg[i].s32ChnId);
977 RK_LOGE("venc chn:%d, ctx->selectFd:%d ", ctx->stVencCfg[i].s32ChnId, ctx->stVencCfg[i].selectFd);
978 #endif
979 }
980
981 while (loopCount < ctx->loopCountSet) {
982 for (i = 0; i < u32DstCount; i++) {
983 #if TEST_WITH_FD
984 test_vi_poll_event(-1, ctx->stVencCfg[i].selectFd);
985 #endif
986 // freeze test
987 RK_MPI_VI_SetChnFreeze(ctx->pipeId, ctx->channelId, ctx->bFreeze);
988
989 s32Ret = RK_MPI_VENC_GetStream(ctx->stVencCfg[i].s32ChnId, &ctx->stFrame[i], -1);
990 if (s32Ret == RK_SUCCESS) {
991 if (ctx->stVencCfg[i].bOutDebugCfg) {
992 pData = RK_MPI_MB_Handle2VirAddr(ctx->stFrame[i].pstPack->pMbBlk);
993 fwrite(pData, 1, ctx->stFrame[i].pstPack->u32Len, ctx->stVencCfg[i].fp);
994 fflush(ctx->stVencCfg[i].fp);
995 }
996 RK_U64 nowUs = TEST_COMM_GetNowUs();
997
998 RK_LOGD("chn:%d, loopCount:%d enc->seq:%d wd:%d pts=%lld delay=%lldus\n", i, loopCount,
999 ctx->stFrame[i].u32Seq, ctx->stFrame[i].pstPack->u32Len,
1000 ctx->stFrame[i].pstPack->u64PTS,
1001 nowUs - ctx->stFrame[i].pstPack->u64PTS);
1002 s32Ret = RK_MPI_VENC_ReleaseStream(ctx->stVencCfg[i].s32ChnId, &ctx->stFrame[i]);
1003 if (s32Ret != RK_SUCCESS) {
1004 RK_LOGE("RK_MPI_VENC_ReleaseStream fail %x", s32Ret);
1005 }
1006 loopCount++;
1007 } else {
1008 RK_LOGE("RK_MPI_VI_GetChnFrame fail %x", s32Ret);
1009 }
1010 }
1011 usleep(10*1000);
1012 }
1013
1014 __FAILED:
1015 for (i = 0; i < u32DstCount; i++) {
1016 s32Ret = RK_MPI_SYS_UnBind(&stSrcChn, &stDestChn[i]);
1017 if (s32Ret != RK_SUCCESS) {
1018 RK_LOGE("RK_MPI_SYS_UnBind fail %x", s32Ret);
1019 }
1020 }
1021 // 5. disable one chn
1022 s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
1023 RK_LOGE("RK_MPI_VI_DisableChn %x", s32Ret);
1024
1025 for (i = 0; i < u32DstCount; i++) {
1026 s32Ret = RK_MPI_VENC_StopRecvFrame(ctx->stVencCfg[i].s32ChnId);
1027 if (s32Ret != RK_SUCCESS) {
1028 return s32Ret;
1029 }
1030 RK_LOGE("destroy enc chn:%d", ctx->stVencCfg[i].s32ChnId);
1031 s32Ret = RK_MPI_VENC_DestroyChn(ctx->stVencCfg[i].s32ChnId);
1032 if (s32Ret != RK_SUCCESS) {
1033 RK_LOGE("RK_MPI_VDEC_DestroyChn fail %x", s32Ret);
1034 }
1035 }
1036
1037 // 6.disable dev(will diabled all chn)
1038 s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
1039 RK_LOGE("RK_MPI_VI_DisableDev %x", s32Ret);
1040 for (i = 0; i < u32DstCount; i++) {
1041 if (ctx->stFrame[i].pstPack)
1042 free(ctx->stFrame[i].pstPack);
1043 if (ctx->stVencCfg[i].fp)
1044 fclose(ctx->stVencCfg[i].fp);
1045 }
1046 return s32Ret;
1047 }
1048
test_vi_get_release_frame_loop(TEST_VI_CTX_S * ctx)1049 static RK_S32 test_vi_get_release_frame_loop(TEST_VI_CTX_S *ctx) {
1050 RK_S32 s32Ret;
1051 RK_S32 loopCount = 0;
1052 RK_S32 waitTime = 33;
1053
1054 /* test use getframe&release_frame */
1055 s32Ret = test_vi_init(ctx);
1056 if (s32Ret != RK_SUCCESS) {
1057 RK_LOGE("vi %d:%d init failed:%x", ctx->devId, ctx->channelId, s32Ret);
1058 goto __FAILED;
1059 }
1060
1061 while (loopCount < ctx->loopCountSet) {
1062 #if TEST_WITH_FD_SWITCH
1063 if (loopCount % 10 == 0 && ctx->selectFd != -1) { // test close/reopen the fd
1064 RK_MPI_VI_CloseChnFd(ctx->pipeId, ctx->channelId);
1065 RK_LOGE("close ctx->pipeId=%d, ctx->channelId=%d, ctx->selectFd:%d",
1066 ctx->pipeId, ctx->channelId, ctx->selectFd);
1067 ctx->selectFd = -1;
1068 } else {
1069 if (ctx->selectFd < 0) {
1070 ctx->selectFd = RK_MPI_VI_GetChnFd(ctx->pipeId, ctx->channelId);
1071 RK_LOGE("regetfd ctx->pipeId=%d, ctx->channelId=%d, ctx->selectFd:%d",
1072 ctx->pipeId, ctx->channelId, ctx->selectFd);
1073 // do not use non-block polling for the first time after switching fd
1074 test_vi_poll_event(33, ctx->selectFd);
1075 } else {
1076 test_vi_poll_event(-1, ctx->selectFd);
1077 }
1078 }
1079 #elif TEST_WITH_FD
1080 test_vi_poll_event(-1, ctx->selectFd);
1081 #endif
1082
1083 /* test user picture */
1084 if (loopCount > 5 && ctx->bUserPicEnabled) {
1085 ctx->bUserPicEnabled = RK_FALSE;
1086 RK_MPI_VI_DisableUserPic(ctx->pipeId, ctx->channelId);
1087 if (ctx->stUsrPic.enUsrPicMode == VI_USERPIC_MODE_PIC &&
1088 ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk) {
1089 RK_MPI_MMZ_Free(ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk);
1090 ctx->stUsrPic.unUsrPic.stUsrPicFrm.stVFrame.pMbBlk = RK_NULL;
1091 }
1092 }
1093
1094 // freeze test
1095 RK_MPI_VI_SetChnFreeze(ctx->pipeId, ctx->channelId, ctx->bFreeze);
1096
1097 // 5.get the frame
1098 s32Ret = RK_MPI_VI_GetChnFrame(ctx->pipeId, ctx->channelId, &ctx->stViFrame, waitTime);
1099 if (s32Ret == RK_SUCCESS) {
1100 RK_U64 nowUs = TEST_COMM_GetNowUs();
1101 void *data = RK_MPI_MB_Handle2VirAddr(ctx->stViFrame.stVFrame.pMbBlk);
1102
1103 RK_LOGD("RK_MPI_VI_GetChnFrame ok:data %p loop:%d seq:%d pts:%lld ms len=%d", data, loopCount,
1104 ctx->stViFrame.stVFrame.u32TimeRef, ctx->stViFrame.stVFrame.u64PTS/1000,
1105 RK_MPI_MB_GetLength(ctx->stViFrame.stVFrame.pMbBlk));
1106 // 6.get the channel status
1107 s32Ret = RK_MPI_VI_QueryChnStatus(ctx->pipeId, ctx->channelId, &ctx->stChnStatus);
1108 RK_LOGD("RK_MPI_VI_QueryChnStatus ret %x, w:%d,h:%d,enable:%d," \
1109 "current frame id:%d,input lost:%d,output lost:%d," \
1110 "framerate:%d,vbfail:%d delay=%lldus",
1111 s32Ret,
1112 ctx->stChnStatus.stSize.u32Width,
1113 ctx->stChnStatus.stSize.u32Height,
1114 ctx->stChnStatus.bEnable,
1115 ctx->stChnStatus.u32CurFrameID,
1116 ctx->stChnStatus.u32InputLostFrame,
1117 ctx->stChnStatus.u32OutputLostFrame,
1118 ctx->stChnStatus.u32FrameRate,
1119 ctx->stChnStatus.u32VbFail,
1120 nowUs - ctx->stViFrame.stVFrame.u64PTS);
1121
1122 // 7.release the frame
1123 s32Ret = RK_MPI_VI_ReleaseChnFrame(ctx->pipeId, ctx->channelId, &ctx->stViFrame);
1124 if (s32Ret != RK_SUCCESS) {
1125 RK_LOGE("RK_MPI_VI_ReleaseChnFrame fail %x", s32Ret);
1126 }
1127 loopCount++;
1128 } else {
1129 RK_LOGE("RK_MPI_VI_GetChnFrame timeout %x", s32Ret);
1130 }
1131
1132 usleep(10*1000);
1133 }
1134
1135 __FAILED:
1136 // if enable rgn,deinit it and destory it.
1137 if (ctx->bEnRgn) {
1138 destory_rgn(ctx);
1139 }
1140
1141 // 9. disable one chn
1142 s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
1143 // 10.disable dev(will diabled all chn)
1144 s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
1145
1146 return s32Ret;
1147 }
1148
create_vi(TEST_VI_CTX_S * ctx)1149 static RK_S32 create_vi(TEST_VI_CTX_S *ctx) {
1150 RK_S32 s32Ret = RK_FAILURE;
1151
1152 // 0. get dev config status
1153 s32Ret = RK_MPI_VI_GetDevAttr(ctx->devId, &ctx->stDevAttr);
1154 if (s32Ret == RK_ERR_VI_NOT_CONFIG) {
1155 // 0-1.config dev
1156 s32Ret = RK_MPI_VI_SetDevAttr(ctx->devId, &ctx->stDevAttr);
1157 if (s32Ret != RK_SUCCESS) {
1158 RK_LOGE("RK_MPI_VI_SetDevAttr %x", s32Ret);
1159 goto __FAILED;
1160 }
1161 } else {
1162 RK_LOGE("RK_MPI_VI_SetDevAttr already");
1163 }
1164 // 1.get dev enable status
1165 s32Ret = RK_MPI_VI_GetDevIsEnable(ctx->devId);
1166 if (s32Ret != RK_SUCCESS) {
1167 // 1-2.enable dev
1168 s32Ret = RK_MPI_VI_EnableDev(ctx->devId);
1169 if (s32Ret != RK_SUCCESS) {
1170 RK_LOGE("RK_MPI_VI_EnableDev %x", s32Ret);
1171 goto __FAILED;
1172 }
1173 // 1-3.bind dev/pipe
1174 ctx->stBindPipe.u32Num = ctx->pipeId;
1175 ctx->stBindPipe.PipeId[0] = ctx->pipeId;
1176 s32Ret = RK_MPI_VI_SetDevBindPipe(ctx->devId, &ctx->stBindPipe);
1177 if (s32Ret != RK_SUCCESS) {
1178 RK_LOGE("RK_MPI_VI_SetDevBindPipe %x", s32Ret);
1179 goto __FAILED;
1180 }
1181 } else {
1182 RK_LOGE("RK_MPI_VI_EnableDev already");
1183 }
1184 // 2.config channel
1185 s32Ret = RK_MPI_VI_SetChnAttr(ctx->pipeId, ctx->channelId, &ctx->stChnAttr);
1186 if (s32Ret != RK_SUCCESS) {
1187 RK_LOGE("RK_MPI_VI_SetChnAttr %x", s32Ret);
1188 goto __FAILED;
1189 }
1190 // 3.enable channel
1191 RK_LOGD("RK_MPI_VI_EnableChn %x %d %d", ctx->devId, ctx->pipeId, ctx->channelId);
1192 s32Ret = RK_MPI_VI_EnableChn(ctx->pipeId, ctx->channelId);
1193 if (s32Ret != RK_SUCCESS) {
1194 RK_LOGE("RK_MPI_VI_EnableChn %x", s32Ret);
1195 goto __FAILED;
1196 }
1197 // 4.save debug file
1198 if (ctx->stDebugFile.bCfg) {
1199 s32Ret = RK_MPI_VI_ChnSaveFile(ctx->pipeId, ctx->channelId, &ctx->stDebugFile);
1200 RK_LOGD("RK_MPI_VI_ChnSaveFile %x", s32Ret);
1201 }
1202
1203 __FAILED:
1204 return s32Ret;
1205 }
1206
destroy_vi(TEST_VI_CTX_S * ctx)1207 static RK_S32 destroy_vi(TEST_VI_CTX_S *ctx) {
1208 RK_S32 s32Ret = RK_FAILURE;
1209 s32Ret = RK_MPI_VI_DisableChn(ctx->pipeId, ctx->channelId);
1210 RK_LOGE("RK_MPI_VI_DisableChn pipe=%d ret:%x", ctx->pipeId, s32Ret);
1211
1212 s32Ret = RK_MPI_VI_DisableDev(ctx->devId);
1213 RK_LOGE("RK_MPI_VI_DisableDev pipe=%d ret:%x", ctx->pipeId, s32Ret);
1214
1215 RK_SAFE_FREE(ctx);
1216 return s32Ret;
1217 }
1218
test_vi_muti_vi_loop(TEST_VI_CTX_S * ctx_out)1219 static RK_S32 test_vi_muti_vi_loop(TEST_VI_CTX_S *ctx_out) {
1220 RK_S32 s32Ret = RK_FAILURE;
1221 TEST_VI_CTX_S *pstViCtx[TEST_VI_SENSOR_NUM];
1222 RK_S32 loopCount = 0;
1223 RK_S32 waitTime = 33;
1224 RK_S32 i = 0;
1225
1226 for (i = 0; i < TEST_VI_SENSOR_NUM; i++) {
1227 pstViCtx[i] = reinterpret_cast<TEST_VI_CTX_S *>(malloc(sizeof(TEST_VI_CTX_S)));
1228 memset(pstViCtx[i], 0, sizeof(TEST_VI_CTX_S));
1229
1230 /* vi config init */
1231 pstViCtx[i]->devId = i;
1232 pstViCtx[i]->pipeId = pstViCtx[i]->devId;
1233 pstViCtx[i]->channelId = 2;
1234
1235 if (TEST_VI_SENSOR_NUM == 2) {
1236 pstViCtx[i]->stChnAttr.stSize.u32Width = 2688;
1237 pstViCtx[i]->stChnAttr.stSize.u32Height = 1520;
1238 } else if (TEST_VI_SENSOR_NUM == 4 || TEST_VI_SENSOR_NUM == 6) {
1239 pstViCtx[i]->stChnAttr.stSize.u32Width = 2560;
1240 pstViCtx[i]->stChnAttr.stSize.u32Height = 1520;
1241 }
1242 pstViCtx[i]->stChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
1243
1244 pstViCtx[i]->stChnAttr.stIspOpt.u32BufCount = 10;
1245 pstViCtx[i]->stChnAttr.u32Depth = 2;
1246 pstViCtx[i]->stChnAttr.enPixelFormat = RK_FMT_YUV420SP;
1247 pstViCtx[i]->stChnAttr.enCompressMode = COMPRESS_AFBC_16x16;
1248 pstViCtx[i]->stChnAttr.stFrameRate.s32SrcFrameRate = -1;
1249 pstViCtx[i]->stChnAttr.stFrameRate.s32DstFrameRate = -1;
1250
1251 /* vi create */
1252 s32Ret = create_vi(pstViCtx[i]);
1253 if (s32Ret != RK_SUCCESS) {
1254 RK_LOGE("vi [%d, %d] init failed: %x",
1255 pstViCtx[i]->devId, pstViCtx[i]->channelId,
1256 s32Ret);
1257 goto __FAILED_VI;
1258 }
1259 }
1260
1261 while (loopCount < ctx_out->loopCountSet) {
1262 for (i = 0; i < TEST_VI_SENSOR_NUM; i++) {
1263 // get the frame
1264 s32Ret = RK_MPI_VI_GetChnFrame(pstViCtx[i]->pipeId, pstViCtx[i]->channelId,
1265 &pstViCtx[i]->stViFrame, waitTime);
1266 if (s32Ret == RK_SUCCESS) {
1267 RK_U64 nowUs = TEST_COMM_GetNowUs();
1268 void *data = RK_MPI_MB_Handle2VirAddr(pstViCtx[i]->stViFrame.stVFrame.pMbBlk);
1269 RK_LOGD("dev %d GetChnFrame Success!", i);
1270 RK_LOGD("RK_MPI_VI_GetChnFrame ok:data %p loop:%d seq:%d pts:%lld ms len=%d",
1271 data, loopCount, pstViCtx[i]->stViFrame.stVFrame.u32TimeRef,
1272 pstViCtx[i]->stViFrame.stVFrame.u64PTS/1000,
1273 RK_MPI_MB_GetLength(pstViCtx[i]->stViFrame.stVFrame.pMbBlk));
1274 // get the channel status
1275 s32Ret = RK_MPI_VI_QueryChnStatus(pstViCtx[i]->pipeId, pstViCtx[i]->channelId,
1276 &pstViCtx[i]->stChnStatus);
1277 RK_LOGD("RK_MPI_VI_QueryChnStatus ret %x, w:%d,h:%d,enable:%d," \
1278 "input lost:%d, output lost:%d, framerate:%d,vbfail:%d delay=%lldus",
1279 s32Ret,
1280 pstViCtx[i]->stChnStatus.stSize.u32Width,
1281 pstViCtx[i]->stChnStatus.stSize.u32Height,
1282 pstViCtx[i]->stChnStatus.bEnable,
1283 pstViCtx[i]->stChnStatus.u32InputLostFrame,
1284 pstViCtx[i]->stChnStatus.u32OutputLostFrame,
1285 pstViCtx[i]->stChnStatus.u32FrameRate,
1286 pstViCtx[i]->stChnStatus.u32VbFail,
1287 nowUs - pstViCtx[i]->stViFrame.stVFrame.u64PTS);
1288 // release the frame
1289 s32Ret = RK_MPI_VI_ReleaseChnFrame(pstViCtx[i]->pipeId, pstViCtx[i]->channelId,
1290 &pstViCtx[i]->stViFrame);
1291 if (s32Ret != RK_SUCCESS) {
1292 RK_LOGE("RK_MPI_VI_ReleaseChnFrame fail %x", s32Ret);
1293 }
1294 } else {
1295 RK_LOGE("dev %d RK_MPI_VI_GetChnFrame timeout %x", i, s32Ret);
1296 }
1297 usleep(3*1000);
1298 }
1299 loopCount++;
1300 usleep(10*1000);
1301 }
1302
1303 __FAILED_VI:
1304 /* destroy vi*/
1305 for (RK_S32 i = 0; i < TEST_VI_SENSOR_NUM; i++) {
1306 s32Ret = destroy_vi(pstViCtx[i]);
1307 if (s32Ret != RK_SUCCESS) {
1308 RK_LOGE("destroy vi [%d, %d] error %x",
1309 pstViCtx[i]->devId, pstViCtx[i]->channelId,
1310 s32Ret);
1311 goto __FAILED;
1312 }
1313 }
1314 __FAILED:
1315 return s32Ret;
1316 }
1317
mpi_vi_test_show_options(const TEST_VI_CTX_S * ctx)1318 static void mpi_vi_test_show_options(const TEST_VI_CTX_S *ctx) {
1319 RK_PRINT("cmd parse result:\n");
1320
1321 RK_PRINT("output file open : %d\n", ctx->stDebugFile.bCfg);
1322 RK_PRINT("yuv output file name : %s/%s\n", ctx->stDebugFile.aFilePath, ctx->stDebugFile.aFileName);
1323 RK_PRINT("enc0 output file path : /%s/%s\n", ctx->stVencCfg[0].dstFilePath, ctx->stVencCfg[0].dstFileName);
1324 RK_PRINT("enc1 output file path : /%s/%s\n", ctx->stVencCfg[1].dstFilePath, ctx->stVencCfg[1].dstFileName);
1325 RK_PRINT("loop count : %d\n", ctx->loopCountSet);
1326 RK_PRINT("enMode : %d\n", ctx->enMode);
1327 RK_PRINT("dev : %d\n", ctx->devId);
1328 RK_PRINT("pipe : %d\n", ctx->pipeId);
1329 RK_PRINT("channel : %d\n", ctx->channelId);
1330 RK_PRINT("width : %d\n", ctx->width);
1331 RK_PRINT("height : %d\n", ctx->height);
1332 RK_PRINT("enCompressMode : %d\n", ctx->enCompressMode);
1333 RK_PRINT("enMemoryType : %d\n", ctx->stChnAttr.stIspOpt.enMemoryType);
1334 RK_PRINT("aEntityName : %s\n", ctx->stChnAttr.stIspOpt.aEntityName);
1335 RK_PRINT("depth : %d\n", ctx->stChnAttr.u32Depth);
1336 RK_PRINT("enPixelFormat : %d\n", ctx->stChnAttr.enPixelFormat);
1337 RK_PRINT("bFreeze : %d\n", ctx->bFreeze);
1338 RK_PRINT("src_frame rate : %d\n", ctx->stChnAttr.stFrameRate.s32SrcFrameRate);
1339 RK_PRINT("dst frame rate : %d\n", ctx->stChnAttr.stFrameRate.s32DstFrameRate);
1340 RK_PRINT("out buf count : %d\n", ctx->stChnAttr.stIspOpt.u32BufCount);
1341 RK_PRINT("bUserPicEnabled : %d\n", ctx->bUserPicEnabled);
1342 RK_PRINT("bEnRgn : %d\n", ctx->bEnRgn);
1343 RK_PRINT("rgn count : %d\n", ctx->s32RgnCnt);
1344 RK_PRINT("rgn type : %d\n", ctx->rgnType);
1345 RK_PRINT("bGetConnecInfo : %d\n", ctx->bGetConnecInfo);
1346 RK_PRINT("bGetEdid : %d\n", ctx->bGetEdid);
1347 RK_PRINT("bSetEdid : %d\n", ctx->bSetEdid);
1348 }
1349
1350 static const char *const usages[] = {
1351 "./rk_mpi_vi_test -w 1920 -h 1080 -t 4 -n rkispp_scale0",
1352 RK_NULL,
1353 };
1354
main(int argc,const char ** argv)1355 int main(int argc, const char **argv) {
1356 RK_S32 i;
1357 RK_S32 s32Ret = RK_FAILURE;
1358 TEST_VI_CTX_S *ctx;
1359 ctx = reinterpret_cast<TEST_VI_CTX_S *>(malloc(sizeof(TEST_VI_CTX_S)));
1360 memset(ctx, 0, sizeof(TEST_VI_CTX_S));
1361
1362 ctx->width = 0;
1363 ctx->height = 0;
1364 ctx->devId = 0;
1365 ctx->pipeId = ctx->devId;
1366 ctx->channelId = 1;
1367 ctx->loopCountSet = 100;
1368 ctx->enMode = TEST_VI_MODE_BIND_VENC;
1369 ctx->stChnAttr.stIspOpt.u32BufCount = 3;
1370 ctx->stChnAttr.stIspOpt.enMemoryType = VI_V4L2_MEMORY_TYPE_DMABUF;
1371 ctx->stChnAttr.stIspOpt.enCaptureType = VI_V4L2_CAPTURE_TYPE_VIDEO_CAPTURE;
1372 ctx->stChnAttr.u32Depth = 0;
1373 ctx->aEntityName = RK_NULL;
1374 ctx->stChnAttr.enPixelFormat = RK_FMT_YUV420SP;
1375 ctx->stChnAttr.stFrameRate.s32SrcFrameRate = -1;
1376 ctx->stChnAttr.stFrameRate.s32DstFrameRate = -1;
1377 ctx->bEnRgn = RK_FALSE;
1378 ctx->s32RgnCnt = 1;
1379 ctx->rgnType = RGN_BUTT;
1380 RK_LOGE("test running enter!");
1381
1382 struct argparse_option options[] = {
1383 OPT_HELP(),
1384 OPT_GROUP("basic options:"),
1385 OPT_INTEGER('w', "width", &(ctx->width),
1386 "set capture channel width(required, default 0)", NULL, 0, 0),
1387 OPT_INTEGER('h', "height", &(ctx->height),
1388 "set capture channel height(required, default 0)", NULL, 0, 0),
1389 OPT_INTEGER('d', "dev", &(ctx->devId),
1390 "set dev id(default 0)", NULL, 0, 0),
1391 OPT_INTEGER('p', "pipe", &(ctx->pipeId),
1392 "set pipe id(default 0)", NULL, 0, 0),
1393 OPT_INTEGER('c', "channel", &(ctx->channelId),
1394 "set channel id(default 1)", NULL, 0, 0),
1395 OPT_INTEGER('l', "loopcount", &(ctx->loopCountSet),
1396 "set capture frame count(default 100)", NULL, 0, 0),
1397 OPT_INTEGER('C', "compressmode", &(ctx->enCompressMode),
1398 "set capture compressmode(default 0; 0:MODE_NONE 1:AFBC_16x16)", NULL, 0, 0),
1399 OPT_INTEGER('o', "output", &(ctx->stDebugFile.bCfg),
1400 "save output file, file at /data/test_<devid>_<pipeid>_<channelid>.bin"
1401 " (default 0; 0:no save 1:save)", NULL, 0, 0),
1402 OPT_INTEGER('m', "mode", &(ctx->enMode),
1403 "test mode(default 1; 0:vi get&release frame 1:vi bind one venc(h264) \n\t"
1404 "2:vi bind two venc(h264)) 3:vi bind vpss bind venc \n\t"
1405 "4:vi bind vo(only support 356x now)", NULL, 0, 0),
1406 OPT_INTEGER('t', "memorytype", &(ctx->stChnAttr.stIspOpt.enMemoryType),
1407 "set the buf memorytype(required, default 4; 1:mmap(hdmiin/bt1120/sensor input) "
1408 "2:userptr(invalid) 3:overlay(invalid) 4:dma(sensor))", NULL, 0, 0),
1409 OPT_STRING('n', "name", &(ctx->aEntityName),
1410 "set the entityName (required, default null;\n\t"
1411 "rv1126 sensor:rkispp_m_bypass rkispp_scale0 rkispp_scale1 rkispp_scale2;\n\t"
1412 "rv1126 hdmiin/bt1120/sensor:/dev/videox such as /dev/video19 /dev/video20;\n\t"
1413 "rk356x hdmiin/bt1120/sensor:/dev/videox such as /dev/video0 /dev/video1", NULL, 0, 0),
1414 OPT_INTEGER('D', "depth", &(ctx->stChnAttr.u32Depth),
1415 "channel output depth, default{u32BufCount(not bind) or 0(bind venc/vpss/...)}", NULL, 0, 0),
1416 OPT_INTEGER('f', "format", &(ctx->stChnAttr.enPixelFormat),
1417 "set the format(default 0; 0:RK_FMT_YUV420SP 10:RK_FMT_YUV422_UYVY"
1418 "131080:RK_FMT_RGB_BAYER_SBGGR_12BPP)", NULL, 0, 0),
1419 OPT_INTEGER('\0', "freeze", &(ctx->bFreeze),
1420 "freeze output(default 0; 0:disable freeze 1:enable freeze)", NULL, 0, 0),
1421 OPT_INTEGER('\0', "src_rate", &(ctx->stChnAttr.stFrameRate.s32SrcFrameRate),
1422 "src frame rate(default -1; -1:not control; other:1-max_fps<isp_out_fps>)", NULL, 0, 0),
1423 OPT_INTEGER('\0', "dst_rate", &(ctx->stChnAttr.stFrameRate.s32DstFrameRate),
1424 "dst frame rate(default -1; -1:not control; other:1-src_fps<src_rate>)", NULL, 0, 0),
1425 OPT_INTEGER('\0', "buf_count", &(ctx->stChnAttr.stIspOpt.u32BufCount),
1426 "out buf count, range[1-8] default(3)", NULL, 0, 0),
1427 OPT_INTEGER('U', "user_pic", &(ctx->bUserPicEnabled),
1428 "enable using user specify picture as vi input.", NULL, 0, 0),
1429 OPT_INTEGER('\0', "rgn_type", &(ctx->rgnType),
1430 "rgn type. 0:overlay, 1:overlayEx,2:cover,3:coverEx,4:mosaic,5:moscaiEx", NULL, 0, 0),
1431 OPT_INTEGER('\0', "rgn_cnt", &(ctx->s32RgnCnt),
1432 "rgn count. default(1),max:8", NULL, 0, 0),
1433 OPT_INTEGER('\0', "en_rgn", &(ctx->bEnRgn),
1434 "enable rgn. default(0)", NULL, 0, 0),
1435 OPT_INTEGER('\0', "get_connect_info", &(ctx->bGetConnecInfo),
1436 "get connect info. default(0)", NULL, 0, 0),
1437 OPT_INTEGER('\0', "get_edid", &(ctx->bGetEdid),
1438 "get edid. default(0)", NULL, 0, 0),
1439 OPT_INTEGER('\0', "set_edid", &(ctx->bSetEdid),
1440 "set edid. default(0)", NULL, 0, 0),
1441
1442 OPT_END(),
1443 };
1444
1445 struct argparse argparse;
1446 argparse_init(&argparse, options, usages, 0);
1447 argparse_describe(&argparse, "\nselect a test case to run.",
1448 "\nuse --help for details.");
1449 argc = argparse_parse(&argparse, argc, argv);
1450
1451 if (!ctx->width || !ctx->height) {
1452 argparse_usage(&argparse);
1453 goto __FAILED2;
1454 }
1455
1456 if (ctx->pipeId != ctx->devId)
1457 ctx->pipeId = ctx->devId;
1458
1459 if (ctx->stDebugFile.bCfg) {
1460 if (ctx->enMode == TEST_VI_MODE_BIND_VENC || ctx->enMode == TEST_VI_MODE_BIND_VPSS_BIND_VENC) {
1461 ctx->stVencCfg[0].bOutDebugCfg = ctx->stDebugFile.bCfg;
1462 } else if (ctx->enMode == TEST_VI_MODE_BIND_VENC_MULTI) {
1463 ctx->stVencCfg[0].bOutDebugCfg = ctx->stDebugFile.bCfg;
1464 ctx->stVencCfg[1].bOutDebugCfg = ctx->stDebugFile.bCfg;
1465 }
1466 memcpy(&ctx->stDebugFile.aFilePath, "/data", strlen("/data"));
1467 snprintf(ctx->stDebugFile.aFileName, MAX_VI_FILE_PATH_LEN,
1468 "test_%d_%d_%d.bin", ctx->devId, ctx->pipeId, ctx->channelId);
1469 }
1470 for (i = 0; i < ctx->enMode; i++) {
1471 if (ctx->stVencCfg[i].bOutDebugCfg) {
1472 char name[256] = {0};
1473 memcpy(&ctx->stVencCfg[i].dstFilePath, "data", strlen("data"));
1474 snprintf(ctx->stVencCfg[i].dstFileName, sizeof(ctx->stVencCfg[i].dstFileName),
1475 "venc_%d.bin", i);
1476 snprintf(name, sizeof(name), "/%s/%s",
1477 ctx->stVencCfg[i].dstFilePath, ctx->stVencCfg[i].dstFileName);
1478 ctx->stVencCfg[i].fp = fopen(name, "wb");
1479 if (ctx->stVencCfg[i].fp == RK_NULL) {
1480 RK_LOGE("chn %d can't open file %s in get picture thread!\n", i, name);
1481 goto __FAILED;
1482 }
1483 }
1484 }
1485
1486 RK_LOGE("test running enter ctx->aEntityName=%s!", ctx->aEntityName);
1487 if (ctx->aEntityName != RK_NULL)
1488 memcpy(ctx->stChnAttr.stIspOpt.aEntityName, ctx->aEntityName, strlen(ctx->aEntityName));
1489
1490 if (ctx->pipeId != ctx->devId)
1491 ctx->pipeId = ctx->devId;
1492
1493 mpi_vi_test_show_options(ctx);
1494
1495 if (RK_MPI_SYS_Init() != RK_SUCCESS) {
1496 RK_LOGE("rk mpi sys init fail!");
1497 goto __FAILED;
1498 }
1499 switch (ctx->enMode) {
1500 case TEST_VI_MODE_VI_ONLY:
1501 if (!ctx->stChnAttr.u32Depth) {
1502 RK_LOGE("depth need > 0 when vi not bind any other module!");
1503 ctx->stChnAttr.u32Depth = ctx->stChnAttr.stIspOpt.u32BufCount;
1504 }
1505 s32Ret = test_vi_get_release_frame_loop(ctx);
1506 break;
1507 case TEST_VI_MODE_BIND_VENC:
1508 case TEST_VI_MODE_BIND_VENC_MULTI:
1509 s32Ret = test_vi_bind_venc_loop(ctx);
1510 break;
1511 case TEST_VI_MODE_BIND_VPSS_BIND_VENC:
1512 s32Ret = test_vi_bind_vpss_venc_loop(ctx);
1513 break;
1514 case TEST_VI_MODE_BIND_VO:
1515 s32Ret = test_vi_bind_vo_loop(ctx);
1516 break;
1517 case TEST_VI_MODE_MUTI_VI:
1518 s32Ret = test_vi_muti_vi_loop(ctx);
1519 break;
1520 default:
1521 RK_LOGE("no support such test mode:%d", ctx->enMode);
1522 break;
1523 }
1524 __FAILED:
1525 RK_LOGE("test running exit:%d", s32Ret);
1526 RK_MPI_SYS_Exit();
1527 __FAILED2:
1528 if (ctx) {
1529 free(ctx);
1530 ctx = RK_NULL;
1531 }
1532
1533 return 0;
1534 }
1535