xref: /OK3568_Linux_fs/external/rockit/mpi/example/mod/test_mpi_vi.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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