xref: /OK3568_Linux_fs/external/rockit/mpi/example/mod/test_mpi_avs.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: 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 <string>
19 #include <cstring>
20 #include <unistd.h>
21 #include <pthread.h>
22 #include <signal.h>
23 #include <fcntl.h>
24 #include <sys/poll.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/ioctl.h>
28 #include <sys/prctl.h>
29 
30 #include "rk_mpi_avs.h"
31 #include "rk_mpi_cal.h"
32 #include "rk_mpi_mb.h"
33 #include "rk_mpi_mmz.h"
34 #include "rk_mpi_venc.h"
35 #include "rk_mpi_vpss.h"
36 #include "rk_mpi_vo.h"
37 #include "rk_mpi_sys.h"
38 
39 #include "test_common.h"
40 #include "test_comm_argparse.h"
41 #include "test_comm_avs.h"
42 #include "test_comm_vpss.h"
43 #include "test_comm_sys.h"
44 #include "test_comm_utils.h"
45 
46 /* for RK3588 */
47 #define RK3588_VO_DEV_HDMI         0
48 #define RK3588_VO_DEV_MIPI         3
49 
50 static RK_BOOL bExit = RK_FALSE;
51 
52 typedef struct rkVPSS_CFG_S {
53     VPSS_GRP        VpssGrp;
54     RK_U32          u32VpssChnCnt;
55     VPSS_GRP_ATTR_S stGrpVpssAttr;
56     VPSS_CHN_ATTR_S stVpssChnAttr[VPSS_MAX_CHN_NUM];
57 } VPSS_CFG_S;
58 
59 typedef struct rkVENC_CFG_S {
60     VENC_CHN VencChn;
61     VENC_CHN_ATTR_S stAttr;
62 } VENC_CFG_S;
63 
64 typedef struct _rkVO_CFG_S {
65     VO_DEV                s32DevId;
66     VO_CHN                s32ChnId;
67     VO_LAYER              s32LayerId;
68     VO_VIDEO_LAYER_ATTR_S stVoLayerAttr;
69     VO_CHN_ATTR_S         stVoChnAttr;
70     VO_CSC_S              stVoCscAttr;
71 } VO_CFG_S;
72 
create_venc(VENC_CFG_S * ctx)73 static RK_S32 create_venc(VENC_CFG_S *ctx) {
74     RK_S32 s32Ret = RK_SUCCESS;
75     VENC_RECV_PIC_PARAM_S   stRecvParam;
76 
77     memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
78     stRecvParam.s32RecvPicNum = -1;
79 
80     s32Ret = RK_MPI_VENC_CreateChn(ctx->VencChn, &ctx->stAttr);
81     if (s32Ret != RK_SUCCESS) {
82         RK_LOGE("venc [%d] RK_MPI_VENC_CreateChn failed: %#x!",
83                 ctx->VencChn, s32Ret);
84         return s32Ret;
85     }
86     RK_LOGV("venc [%d] RK_MPI_VENC_CreateChn already.", ctx->VencChn);
87 
88     s32Ret = RK_MPI_VENC_StartRecvFrame(ctx->VencChn, &stRecvParam);
89     if (s32Ret != RK_SUCCESS) {
90         RK_LOGE("venc [%d] RK_MPI_VENC_StartRecvFrame failed: %#x!",
91                 ctx->VencChn, s32Ret);
92         return s32Ret;
93     }
94     RK_LOGV("venc [%d] RK_MPI_VENC_StartRecvFrame already.", ctx->VencChn);
95 
96     return RK_SUCCESS;
97 }
98 
destroy_venc(VENC_CFG_S * ctx)99 static RK_S32 destroy_venc(VENC_CFG_S *ctx) {
100     RK_S32 s32Ret = RK_SUCCESS;
101 
102     s32Ret = RK_MPI_VENC_StopRecvFrame(ctx->VencChn);
103     if (s32Ret != RK_SUCCESS) {
104         RK_LOGE("venc [%d] RK_MPI_VENC_StopRecvFrame failed: %#x!",
105                 ctx->VencChn, s32Ret);
106         return s32Ret;
107     }
108     RK_LOGV("venc [%d] RK_MPI_VENC_StopRecvFrame already.", ctx->VencChn);
109 
110     s32Ret = RK_MPI_VENC_DestroyChn(ctx->VencChn);
111     if (s32Ret != RK_SUCCESS) {
112         RK_LOGE("venc [%d] RK_MPI_VENC_DestroyChn failed: %#x!",
113                 ctx->VencChn, s32Ret);
114         return s32Ret;
115     }
116     RK_LOGV("venc [%d] RK_MPI_VENC_DestroyChn already.", ctx->VencChn);
117 
118     return RK_SUCCESS;
119 }
120 
create_vo(VO_CFG_S * ctx)121 static RK_S32 create_vo(VO_CFG_S *ctx) {
122     RK_S32 s32Ret = RK_SUCCESS;
123     RK_U32 u32DispBufLen;
124     VO_PUB_ATTR_S VoPubAttr;
125     VO_LAYER VoLayer = ctx->s32LayerId;
126     VO_DEV VoDev = ctx->s32DevId;
127     VO_CHN VoChn = ctx->s32ChnId;
128 
129     memset(&VoPubAttr, 0, sizeof(VO_PUB_ATTR_S));
130 
131     s32Ret = RK_MPI_VO_GetPubAttr(VoDev, &VoPubAttr);
132     if (s32Ret != RK_SUCCESS) {
133         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_GetPubAttr failed: %#x!",
134                 VoDev, VoLayer, VoChn, s32Ret);
135         return s32Ret;
136     }
137     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_GetPubAttr already.",
138             VoDev, VoLayer, VoChn);
139 
140     if (RK3588_VO_DEV_HDMI == VoDev) {
141         VoPubAttr.enIntfType = VO_INTF_HDMI;
142         VoPubAttr.enIntfSync = VO_OUTPUT_1080P60;
143     } else if (RK3588_VO_DEV_MIPI == VoDev) {
144         VoPubAttr.enIntfType = VO_INTF_MIPI;
145         VoPubAttr.enIntfSync = VO_OUTPUT_DEFAULT;
146     }
147 
148     s32Ret = RK_MPI_VO_SetPubAttr(VoDev, &VoPubAttr);
149     if (s32Ret != RK_SUCCESS) {
150         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_GetPubAttr failed: %#x!",
151                 VoDev, VoLayer, VoChn, s32Ret);
152         return s32Ret;
153     }
154     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetPubAttr already.",
155             VoDev, VoLayer, VoChn);
156 
157     s32Ret = RK_MPI_VO_Enable(VoDev);
158     if (s32Ret != RK_SUCCESS) {
159         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_Enable failed: %#x!",
160                 VoDev, VoLayer, VoChn, s32Ret);
161         return s32Ret;
162     }
163     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_Enable already.",
164             VoDev, VoLayer, VoChn);
165 
166     s32Ret = RK_MPI_VO_GetLayerDispBufLen(VoLayer, &u32DispBufLen);
167     if (s32Ret != RK_SUCCESS) {
168         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_GetLayerDispBufLen failed: %#x!",
169                 VoDev, VoLayer, VoChn, s32Ret);
170         return s32Ret;
171     }
172     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_GetLayerDispBufLen already.",
173             VoDev, VoLayer, VoChn);
174 
175     u32DispBufLen = 3;
176     s32Ret = RK_MPI_VO_SetLayerDispBufLen(VoLayer, u32DispBufLen);
177     if (s32Ret != RK_SUCCESS) {
178         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_GetLayerDispBufLen %d failed: %#x!",
179                 VoDev, VoLayer, VoChn, u32DispBufLen, s32Ret);
180         return s32Ret;
181     }
182     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_GetLayerDispBufLen %d already.",
183             VoDev, VoLayer, VoChn, u32DispBufLen);
184 
185     s32Ret = RK_MPI_VO_BindLayer(VoLayer, VoDev, VO_LAYER_MODE_GRAPHIC);
186     if (s32Ret != RK_SUCCESS) {
187         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_BindLayer failed: %#x!",
188                 VoDev, VoLayer, VoChn, s32Ret);
189         return s32Ret;
190     }
191     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_BindLayer already.",
192             VoDev, VoLayer, VoChn);
193 
194     s32Ret = RK_MPI_VO_SetLayerAttr(VoLayer, &ctx->stVoLayerAttr);
195     if (s32Ret != RK_SUCCESS) {
196         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_SetLayerAttr failed: %#x!",
197                 VoDev, VoLayer, VoChn, s32Ret);
198         return s32Ret;
199     }
200     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetLayerAttr already.",
201             VoDev, VoLayer, VoChn);
202 
203 #if VO_RGA
204     s32Ret = RK_MPI_VO_SetLayerSpliceMode(VoLayer, VO_SPLICE_MODE_RGA);
205     if (s32Ret != RK_SUCCESS) {
206         RK_LOGE("RK_MPI_VO_SetLayerSpliceMode failed: %#x", s32Ret);
207         return RK_FAILURE;
208     }
209 #endif
210 
211     s32Ret = RK_MPI_VO_EnableLayer(VoLayer);
212     if (s32Ret != RK_SUCCESS) {
213         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_EnableLayer failed: %#x!",
214                 VoDev, VoLayer, VoChn, s32Ret);
215         return s32Ret;
216     }
217     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_EnableLayer already.",
218             VoDev, VoLayer, VoChn);
219 
220     s32Ret = RK_MPI_VO_SetChnAttr(VoLayer, VoChn, &ctx->stVoChnAttr);
221     if (s32Ret != RK_SUCCESS) {
222         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr failed: %#x!",
223                 VoDev, VoLayer, VoChn, s32Ret);
224         return s32Ret;
225     }
226     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr already.",
227             VoDev, VoLayer, VoChn);
228 
229     s32Ret = RK_MPI_VO_SetLayerCSC(VoLayer, &ctx->stVoCscAttr);
230     if (s32Ret != RK_SUCCESS) {
231         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr failed: %#x!",
232                 VoDev, VoLayer, VoChn, s32Ret);
233         return s32Ret;
234     }
235     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_SetChnAttr already.",
236             VoDev, VoLayer, VoChn);
237 
238     s32Ret = RK_MPI_VO_EnableChn(VoLayer, VoChn);
239     if (s32Ret != RK_SUCCESS) {
240         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_EnableChn failed: %#x!",
241                 VoDev, VoLayer, VoChn, s32Ret);
242         return s32Ret;
243     }
244     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_EnableChn already.",
245             VoDev, VoLayer, VoChn);
246 
247     return s32Ret;
248 }
249 
destroy_vo(VO_CFG_S * ctx)250 static RK_S32 destroy_vo(VO_CFG_S *ctx) {
251     RK_S32 s32Ret = RK_SUCCESS;
252     VO_LAYER VoLayer = ctx->s32LayerId;
253     VO_DEV VoDev = ctx->s32DevId;
254     VO_CHN VoChn = ctx->s32ChnId;
255 
256     s32Ret = RK_MPI_VO_DisableChn(VoDev, VoChn);
257     if (s32Ret != RK_SUCCESS) {
258         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_DisableChn failed: %#x!",
259                 VoDev, VoLayer, VoChn);
260         return s32Ret;
261     }
262     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_DisableChn already.",
263             VoDev, VoLayer, VoChn);
264 
265     s32Ret = RK_MPI_VO_DisableLayer(VoLayer);
266     if (s32Ret != RK_SUCCESS) {
267         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_DisableLayer failed: %#x!",
268                 VoDev, VoLayer, VoChn);
269         return s32Ret;
270     }
271     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_DisableLayer already.",
272             VoDev, VoLayer, VoChn);
273 
274     s32Ret = RK_MPI_VO_Disable(VoDev);
275     if (s32Ret != RK_SUCCESS) {
276         RK_LOGE("vo [%d, %d, %d] RK_MPI_VO_Disable failed: %#x!",
277                 VoDev, VoLayer, VoChn);
278         return s32Ret;
279     }
280     RK_LOGV("vo [%d, %d, %d] RK_MPI_VO_Disable already.",
281             VoDev, VoLayer, VoChn);
282 
283     return s32Ret;
284 }
285 
test_single_avs_loop(TEST_AVS_CTX_S * ctx)286 static RK_S32 test_single_avs_loop(TEST_AVS_CTX_S *ctx) {
287     RK_S32 s32Ret = RK_SUCCESS;
288 
289     s32Ret = TEST_AVS_UnitTest(ctx);
290     if (s32Ret != RK_SUCCESS) {
291         RK_LOGE("TEST_AVS_UnitTest failed: %#x!", s32Ret);
292         goto __FAILED;
293     }
294 
295 __FAILED:
296 
297     return s32Ret;
298 }
299 
sigterm_handler(int sig)300 static RK_VOID sigterm_handler(int sig) {
301     RK_PRINT("signal %d\n", sig);
302     bExit = RK_TRUE;
303 }
304 
test_avs_vpss_venc_loop(TEST_AVS_CTX_S * pstAvsCtx)305 static RK_S32 test_avs_vpss_venc_loop(TEST_AVS_CTX_S *pstAvsCtx) {
306     RK_PRINT(" Media link: \n");
307     RK_PRINT(" %d pool -> avs -> vpss -> venc(H264) \n", pstAvsCtx->s32PipeNum);
308     RK_PRINT("                        -> venc(H265) \n");
309 
310     RK_S32 s32Ret     = RK_SUCCESS;
311     RK_S32 loopCount  = 0;
312     RK_S32 vpssChnCnt = 1;
313     RK_S32 vencChnCnt = vpssChnCnt;
314     RK_S32 vpssOutputWidth[vpssChnCnt] = {3840};
315     RK_S32 vpssOutputHeight[vpssChnCnt] = {2160};
316 
317     VPSS_CFG_S  pstVpssCtx;
318     VENC_CFG_S *pstVencCtx;
319     VIDEO_FRAME_INFO_S **pstPipeFrames;
320 
321     pstVencCtx = reinterpret_cast<VENC_CFG_S *>
322                                 (malloc(sizeof(VENC_CFG_S) * vencChnCnt));
323     memset(pstVencCtx, 0, sizeof(VENC_CFG_S) * vencChnCnt);
324     pstPipeFrames = reinterpret_cast<VIDEO_FRAME_INFO_S **>(
325                         malloc(sizeof(VIDEO_FRAME_INFO_S *) * AVS_PIPE_NUM));
326     for (RK_S32 i = 0; i < AVS_PIPE_NUM; i++) {
327         pstPipeFrames[i] = reinterpret_cast<VIDEO_FRAME_INFO_S *>(malloc(sizeof(VIDEO_FRAME_INFO_S)));
328         memset(pstPipeFrames[i], 0, sizeof(VIDEO_FRAME_INFO_S));
329     }
330 
331     s32Ret = TEST_AVS_ModCreateFramePool(pstAvsCtx);
332     if (s32Ret != RK_SUCCESS) {
333         goto __FREE_PIPE_FRAME;
334     }
335 
336     /* avs create */
337     s32Ret = TEST_AVS_ModInit(pstAvsCtx);
338     if (s32Ret != RK_SUCCESS) {
339         goto __DESTROY_FRAME_POOL;
340     }
341 
342     /* vpss config init */
343     pstVpssCtx.VpssGrp                                   = 0;
344     pstVpssCtx.u32VpssChnCnt                             = vpssChnCnt;
345     pstVpssCtx.stGrpVpssAttr.u32MaxW                     = 8192;
346     pstVpssCtx.stGrpVpssAttr.u32MaxH                     = 8192;
347     pstVpssCtx.stGrpVpssAttr.enPixelFormat               = RK_FMT_YUV420SP;
348     pstVpssCtx.stGrpVpssAttr.stFrameRate.s32SrcFrameRate = -1;
349     pstVpssCtx.stGrpVpssAttr.stFrameRate.s32DstFrameRate = -1;
350     pstVpssCtx.stGrpVpssAttr.enCompressMode              = COMPRESS_MODE_NONE;
351     for (RK_S32 i = 0; i < vpssChnCnt; i ++) {
352         pstVpssCtx.stVpssChnAttr[i].enChnMode                   = VPSS_CHN_MODE_USER;
353         pstVpssCtx.stVpssChnAttr[i].enDynamicRange              = DYNAMIC_RANGE_SDR8;
354         pstVpssCtx.stVpssChnAttr[i].enPixelFormat               = RK_FMT_YUV420SP;
355         pstVpssCtx.stVpssChnAttr[i].stFrameRate.s32SrcFrameRate = -1;
356         pstVpssCtx.stVpssChnAttr[i].stFrameRate.s32DstFrameRate = -1;
357         pstVpssCtx.stVpssChnAttr[i].u32Width                    = vpssOutputWidth[i];
358         pstVpssCtx.stVpssChnAttr[i].u32Height                   = vpssOutputHeight[i];
359         pstVpssCtx.stVpssChnAttr[i].enCompressMode              = COMPRESS_AFBC_16x16;
360         pstVpssCtx.stVpssChnAttr[i].u32FrameBufCnt              = 3;
361         pstVpssCtx.stVpssChnAttr[i].u32Depth                    = 1;
362     }
363 
364     /* vpss create */
365     s32Ret = TEST_VPSS_Start(pstVpssCtx.VpssGrp, pstVpssCtx.u32VpssChnCnt,
366                         &pstVpssCtx.stGrpVpssAttr, pstVpssCtx.stVpssChnAttr);
367     if (s32Ret != RK_SUCCESS) {
368         goto __DESTROY_AVS;
369     }
370 
371     for (RK_S32 i = 0; i < vencChnCnt; i++) {
372         /* venc config init */
373         PIC_BUF_ATTR_S   stPicBufAttr;
374         MB_PIC_CAL_S     stMbPicCalResult;
375 
376         stPicBufAttr.u32Width      = vpssOutputWidth[i];
377         stPicBufAttr.u32Height     = vpssOutputHeight[i];
378         stPicBufAttr.enCompMode    = COMPRESS_AFBC_16x16;
379         stPicBufAttr.enPixelFormat = RK_FMT_YUV420SP;
380 
381         s32Ret = RK_MPI_CAL_VGS_GetPicBufferSize(&stPicBufAttr, &stMbPicCalResult);
382         if (s32Ret != RK_SUCCESS) {
383             RK_LOGE("get picture buffer size failed: %#x!", s32Ret);
384             goto __DESTROY_VENC;
385         }
386 
387         pstVencCtx[i].VencChn = i;
388         pstVencCtx[i].stAttr.stVencAttr.enPixelFormat   = RK_FMT_YUV420SP;
389         pstVencCtx[i].stAttr.stVencAttr.u32PicWidth     = vpssOutputWidth[i];
390         pstVencCtx[i].stAttr.stVencAttr.u32PicHeight    = vpssOutputHeight[i];
391         pstVencCtx[i].stAttr.stVencAttr.u32VirWidth     = vpssOutputWidth[i];
392         pstVencCtx[i].stAttr.stVencAttr.u32VirHeight    = vpssOutputHeight[i];
393         pstVencCtx[i].stAttr.stVencAttr.u32StreamBufCnt = 3;
394         pstVencCtx[i].stAttr.stVencAttr.u32BufSize      = stMbPicCalResult.u32MBSize;
395         if (i % 2 == 0) {
396             pstVencCtx[i].stAttr.stVencAttr.enType             = RK_VIDEO_ID_AVC;
397             pstVencCtx[i].stAttr.stVencAttr.u32Profile         = H264E_PROFILE_HIGH;
398             pstVencCtx[i].stAttr.stRcAttr.enRcMode             = VENC_RC_MODE_H264CBR;
399             pstVencCtx[i].stAttr.stRcAttr.stH264Cbr.u32Gop     = 60;
400             pstVencCtx[i].stAttr.stRcAttr.stH264Cbr.u32BitRate = 65536;
401         } else {
402             pstVencCtx[i].stAttr.stVencAttr.enType             = RK_VIDEO_ID_HEVC;
403             pstVencCtx[i].stAttr.stVencAttr.u32Profile         = H265E_PROFILE_MAIN;
404             pstVencCtx[i].stAttr.stRcAttr.enRcMode             = VENC_RC_MODE_H265CBR;
405             pstVencCtx[i].stAttr.stRcAttr.stH265Cbr.u32Gop     = 60;
406             pstVencCtx[i].stAttr.stRcAttr.stH264Cbr.u32BitRate = 16384;
407         }
408         /* venc create */
409         s32Ret = create_venc(&pstVencCtx[i]);
410         if (s32Ret != RK_SUCCESS) {
411             goto __DESTROY_VENC;
412         }
413     }
414 
415     /* bind avs -> vpss */
416     s32Ret = TEST_SYS_AvsBindVpss(0, 0, pstVpssCtx.VpssGrp);
417     if (s32Ret != RK_SUCCESS) {
418         RK_LOGE("bind failed: %x, avs [%d, %d] -> vpss [%d]",
419                 s32Ret, 0, 0, pstVpssCtx.VpssGrp);
420         goto __DESTROY_VENC;
421     }
422     RK_LOGV("bind success, avs [%d, %d] -> vpss [%d]",
423             0, 0, pstVpssCtx.VpssGrp);
424 
425     /* bind vpss -> venc */
426     for (RK_S32 i = 0; i < vpssChnCnt; i++) {
427         s32Ret = TEST_SYS_VpssBindVenc(0, i, i);
428         if (s32Ret != RK_SUCCESS) {
429             RK_LOGE("bind failed: %x, vpss [%d, %d] -> venc [%d]",
430                     s32Ret, 0, i, i);
431             goto __UNBIND_AVS_VPSS;
432         }
433         RK_LOGV("bind success, vpss [%d, %d] -> venc [%d]",
434                 0, i, i);
435     }
436 
437     /* thread: do somethings */
438     signal(SIGINT, sigterm_handler);
439     if (pstAvsCtx->s32LoopCount > 0) {
440         VENC_STREAM_S stVencStream;
441         stVencStream.pstPack = reinterpret_cast<VENC_PACK_S *>(malloc(sizeof(VENC_PACK_S)));
442 
443         while (!bExit && loopCount < pstAvsCtx->s32LoopCount) {
444             s32Ret = TEST_AVS_ModGetFrameFromPool(pstAvsCtx, pstPipeFrames);
445 
446             s32Ret = TEST_AVS_ModSendFrame(pstAvsCtx->s32GrpIndex, pstAvsCtx->s32PipeNum, pstPipeFrames);
447             if (s32Ret != RK_SUCCESS) {
448                 TEST_AVS_ModReleaseFrameToPool(pstAvsCtx, pstPipeFrames);
449                 continue;
450             }
451 
452             TEST_AVS_ModReleaseFrameToPool(pstAvsCtx, pstPipeFrames);
453 
454             for (RK_S32 i = 0; i < vencChnCnt; i++) {
455                 s32Ret = RK_MPI_VENC_GetStream(i, &stVencStream, 100);
456                 if (s32Ret >= 0) {
457                     RK_MPI_VENC_ReleaseStream(i, &stVencStream);
458                 }
459             }
460 
461             usleep(33 * 1000);
462             loopCount++;
463         }
464 
465         if (stVencStream.pstPack) {
466             free(stVencStream.pstPack);
467         }
468     }
469 
470 __UNBIND_VPSS_VENC:
471     /* unbind avs -> vpss */
472     s32Ret = TEST_SYS_AvsUnbindVpss(0, 0, pstVpssCtx.VpssGrp);
473     if (s32Ret != RK_SUCCESS) {
474         RK_LOGE("unbind failed: %x, avs [%d, %d] -> vpss [%d]",
475                 s32Ret, 0, 0, pstVpssCtx.VpssGrp);
476     }
477     RK_LOGV("unbind success, avs [%d, %d] -> vpss [%d]",
478             0 , 0, pstVpssCtx.VpssGrp);
479 
480 __UNBIND_AVS_VPSS:
481     /* unbind vpss -> venc */
482     for (RK_S32 i = 0; i < vpssChnCnt; i++) {
483         s32Ret = TEST_SYS_VpssUnbindVenc(0, i, i);
484         if (s32Ret != RK_SUCCESS) {
485             RK_LOGE("unbind failed: %x, vpss [%d, %d] -> venc [%d]",
486                     s32Ret, pstVpssCtx.VpssGrp, i, i);
487         }
488         RK_LOGV("unbind success, vpss [%d, %d] -> venc [%d]",
489                 pstVpssCtx.VpssGrp, i, i);
490     }
491 
492 __DESTROY_VENC:
493     /* destroy venc */
494     for (RK_S32 i = 0; i < vencChnCnt; i++) {
495         s32Ret = destroy_venc(&pstVencCtx[i]);
496         if (s32Ret != RK_SUCCESS) {
497             RK_LOGE("venc [%d] destroy_venc failed: %#x", i, s32Ret);
498         }
499         RK_LOGV("venc [%d] destroy_venc already.", i);
500     }
501 
502 __DESTROY_VPSS:
503     /* destroy vpss */
504     s32Ret = TEST_VPSS_Stop(pstVpssCtx.VpssGrp, pstVpssCtx.u32VpssChnCnt);
505     if (s32Ret != RK_SUCCESS) {
506         RK_LOGE("vpss [%d] TEST_VPSS_Stop failed: %#x", pstVpssCtx.VpssGrp, s32Ret);
507     }
508     RK_LOGV("vpss [%d] TEST_VPSS_Stop already.", pstVpssCtx.VpssGrp);
509 
510 __DESTROY_AVS:
511     /* destroy avs */
512     s32Ret = TEST_AVS_ModDeInit(pstAvsCtx);
513     if (s32Ret != RK_SUCCESS) {
514         RK_LOGE("avs [%d] TEST_AVS_ModDeInit failed: %#x", pstAvsCtx->s32GrpIndex, s32Ret);
515     }
516     RK_LOGV("avs [%d] TEST_AVS_ModDeInit already.", pstAvsCtx->s32GrpIndex);
517 
518 __DESTROY_FRAME_POOL:
519 
520     s32Ret = TEST_AVS_ModDestroyFramePool(pstAvsCtx);
521     if (s32Ret != RK_SUCCESS) {
522         RK_LOGE("avs [%d] TEST_AVS_ModDestroyFramePool failed: %#x",
523                 pstAvsCtx->s32GrpIndex, s32Ret);
524     }
525     RK_LOGV("avs [%d] TEST_AVS_ModDestroyFramePool already.",
526             pstAvsCtx->s32GrpIndex);
527 
528 __FREE_PIPE_FRAME:
529 
530     for (RK_S32 i = 0; i < AVS_PIPE_NUM; i++) {
531         RK_SAFE_FREE(pstPipeFrames[i]);
532     }
533 
534     RK_SAFE_FREE(pstPipeFrames);
535 
536 __FREE_VENC_CFG:
537 
538     RK_SAFE_FREE(pstVencCtx);
539 
540     return s32Ret;
541 }
542 
test_avs_vo_loop(TEST_AVS_CTX_S * pstAvsCtx)543 static RK_S32 test_avs_vo_loop(TEST_AVS_CTX_S *pstAvsCtx) {
544     RK_PRINT(" Media link: \n");
545     RK_PRINT(" %d avs -> vo (HDMI) \n", pstAvsCtx->s32PipeNum);
546 
547     RK_S32 s32Ret    = RK_SUCCESS;
548     RK_S32 loopCount = 0;
549     VO_CFG_S pstVoCtx;
550     VIDEO_FRAME_INFO_S **pstPipeFrames;
551 
552     pstPipeFrames = reinterpret_cast<VIDEO_FRAME_INFO_S **>(
553                         malloc(sizeof(VIDEO_FRAME_INFO_S *) * AVS_PIPE_NUM));
554     for (RK_S32 i = 0; i < AVS_PIPE_NUM; i++) {
555         pstPipeFrames[i] = reinterpret_cast<VIDEO_FRAME_INFO_S *>(malloc(sizeof(VIDEO_FRAME_INFO_S)));
556         memset(pstPipeFrames[i], 0, sizeof(VIDEO_FRAME_INFO_S));
557     }
558 
559     s32Ret = TEST_AVS_ModCreateFramePool(pstAvsCtx);
560     if (s32Ret != RK_SUCCESS) {
561         goto __FREE_PIPE_FRAME;
562     }
563 
564     /* avs create */
565     s32Ret = TEST_AVS_ModInit(pstAvsCtx);
566     if (s32Ret != RK_SUCCESS) {
567         goto __DESTROY_FRAME_POOL;
568     }
569 
570     /* vo config init */
571     pstVoCtx.s32LayerId = 0;
572     pstVoCtx.s32DevId   = RK3588_VO_DEV_HDMI;
573 
574     if (RK3588_VO_DEV_HDMI == pstVoCtx.s32DevId) {
575         pstVoCtx.stVoLayerAttr.stDispRect.u32Width = 1920;
576         pstVoCtx.stVoLayerAttr.stDispRect.u32Height = 1080;
577     } else if (RK3588_VO_DEV_MIPI == pstVoCtx.s32DevId) {
578         pstVoCtx.stVoLayerAttr.stDispRect.u32Width = 1080;
579         pstVoCtx.stVoLayerAttr.stDispRect.u32Height = 1920;
580     }
581     pstVoCtx.stVoLayerAttr.enPixFormat = RK_FMT_RGB888;
582 
583     pstVoCtx.s32ChnId = 0;
584     pstVoCtx.stVoCscAttr.enCscMatrix = VO_CSC_MATRIX_IDENTITY;
585     pstVoCtx.stVoCscAttr.u32Contrast = 50;
586     pstVoCtx.stVoCscAttr.u32Hue = 50;
587     pstVoCtx.stVoCscAttr.u32Luma = 50;
588     pstVoCtx.stVoCscAttr.u32Satuature = 50;
589 
590     pstVoCtx.stVoLayerAttr.stDispRect.s32X = 0;
591     pstVoCtx.stVoLayerAttr.stDispRect.s32Y = 0;
592     pstVoCtx.stVoLayerAttr.stImageSize.u32Width =
593         pstVoCtx.stVoLayerAttr.stDispRect.u32Width;
594     pstVoCtx.stVoLayerAttr.stImageSize.u32Height =
595         pstVoCtx.stVoLayerAttr.stDispRect.u32Height;
596 
597     pstVoCtx.stVoLayerAttr.u32DispFrmRt = 30;
598     pstVoCtx.stVoChnAttr.stRect.s32X = 0;
599     pstVoCtx.stVoChnAttr.stRect.s32Y = 0;
600     pstVoCtx.stVoChnAttr.stRect.u32Width =
601         pstVoCtx.stVoLayerAttr.stImageSize.u32Width;
602     pstVoCtx.stVoChnAttr.stRect.u32Height =
603         pstVoCtx.stVoLayerAttr.stImageSize.u32Height;
604     pstVoCtx.stVoChnAttr.bDeflicker = RK_FALSE;
605     pstVoCtx.stVoChnAttr.u32Priority = 1;
606     pstVoCtx.stVoChnAttr.u32FgAlpha = 128;
607     pstVoCtx.stVoChnAttr.u32BgAlpha = 0;
608 
609     /* vo creat */
610     s32Ret = create_vo(&pstVoCtx);
611     if (s32Ret != RK_SUCCESS) {
612         RK_LOGE("vo [%d, %d, %d] create failed: %x",
613                 pstVoCtx.s32DevId,
614                 pstVoCtx.s32LayerId,
615                 pstVoCtx.s32ChnId,
616                 s32Ret);
617         goto __DESTROY_AVS;
618     }
619 
620     /* bind avs -> vo */
621     s32Ret = TEST_SYS_AvsBindVo(0, 0, 0, 0);
622     if (s32Ret != RK_SUCCESS) {
623         RK_LOGE("bind failed: %x, avs [%d, %d] -> vo [%d, %d]",
624                 s32Ret, 0, 0, 0, 0);
625         goto __DESTROY_VO;
626     }
627     RK_LOGV("bind success, avs [%d, %d] -> vo [%d, %d]",
628             0 , 0, 0, 0);
629 
630     /* thread: do somethings */
631     signal(SIGINT, sigterm_handler);
632     if (pstAvsCtx->s32LoopCount > 0) {
633         while (!bExit && loopCount < pstAvsCtx->s32LoopCount) {
634             s32Ret = TEST_AVS_ModGetFrameFromPool(pstAvsCtx, pstPipeFrames);
635 
636             s32Ret = TEST_AVS_ModSendFrame(pstAvsCtx->s32GrpIndex, pstAvsCtx->s32PipeNum, pstPipeFrames);
637             if (s32Ret != RK_SUCCESS) {
638                 TEST_AVS_ModReleaseFrameToPool(pstAvsCtx, pstPipeFrames);
639                 continue;
640             }
641 
642             TEST_AVS_ModReleaseFrameToPool(pstAvsCtx, pstPipeFrames);
643             usleep(1000);
644             loopCount++;
645         }
646     }
647 
648 __UNBIND_AVS_VO:
649     /* unbind avs -> vo */
650     s32Ret = TEST_SYS_AvsUnbindVo(0, 0, 0, 0);
651     if (s32Ret != RK_SUCCESS) {
652         RK_LOGE("bind failed: %x, avs [%d, %d] -> vo [%d, %d]",
653                 s32Ret, pstAvsCtx->s32GrpIndex, 0,
654                 pstVoCtx.s32DevId, pstVoCtx.s32ChnId);
655     }
656     RK_LOGV("unbind success, avs [%d, %d] -> vo [%d, %d]",
657             pstAvsCtx->s32GrpIndex, 0,
658             pstVoCtx.s32DevId, pstVoCtx.s32ChnId);
659 
660 __DESTROY_VO:
661     /* destroy vo */
662     s32Ret = destroy_vo(&pstVoCtx);
663     if (s32Ret != RK_SUCCESS) {
664         RK_LOGE("vo [%d, %d, %d] destroy_vo failed: %#x",
665                 pstVoCtx.s32DevId, pstVoCtx.s32LayerId,
666                 pstVoCtx.s32ChnId, s32Ret);
667     }
668     RK_LOGV("vo [%d, %d, %d] destroy_vo already.",
669             pstVoCtx.s32DevId, pstVoCtx.s32LayerId,
670             pstVoCtx.s32ChnId);
671 
672 __DESTROY_AVS:
673     /* destroy avs */
674     s32Ret = TEST_AVS_ModDeInit(pstAvsCtx);
675     if (s32Ret != RK_SUCCESS) {
676         RK_LOGE("avs [%d] TEST_AVS_ModDeInit failed: %#x", pstAvsCtx->s32GrpIndex, s32Ret);
677     }
678     RK_LOGV("avs [%d] TEST_AVS_ModDeInit already.", pstAvsCtx->s32GrpIndex);
679 
680 __DESTROY_FRAME_POOL:
681     s32Ret = TEST_AVS_ModDestroyFramePool(pstAvsCtx);
682     if (s32Ret != RK_SUCCESS) {
683         RK_LOGE("avs [%d] TEST_AVS_ModDestroyFramePool failed: %#x",
684                 pstAvsCtx->s32GrpIndex, s32Ret);
685     }
686     RK_LOGV("avs [%d] TEST_AVS_ModDestroyFramePool already.",
687             pstAvsCtx->s32GrpIndex);
688 
689 __FREE_PIPE_FRAME:
690     for (RK_S32 i = 0; i < AVS_PIPE_NUM; i++) {
691         RK_SAFE_FREE(pstPipeFrames[i]);
692     }
693 
694     RK_SAFE_FREE(pstPipeFrames);
695 
696     return s32Ret;
697 }
698 
699 static const char *const usages[] = {
700     "./rk_mpi_avs_test [--test_mode TEST_MODE] [-c COMPRESS_MODE] [-n LOOP_COUNT] [-p PIPE_NUM]",
701     RK_NULL,
702 };
703 
mpi_avs_test_show_options(const TEST_AVS_CTX_S * ctx)704 static void mpi_avs_test_show_options(const TEST_AVS_CTX_S *ctx) {
705     RK_PRINT("cmd parse result:\n");
706     RK_PRINT("input file path      : %s\n", ctx->srcFilePath);
707     RK_PRINT("output file path     : %s\n", ctx->dstFilePath);
708     RK_PRINT("test mode            : %d\n", ctx->enTestMode);
709     RK_PRINT("group number         : %d\n", ctx->s32GrpNum);
710     RK_PRINT("pipe number          : %d\n", ctx->s32PipeNum);
711     RK_PRINT("channel number       : %d\n", ctx->s32ChnNum);
712     RK_PRINT("loop count           : %d\n", ctx->s32LoopCount);
713     RK_PRINT("input width          : %d\n", ctx->u32SrcWidth);
714     RK_PRINT("input height         : %d\n", ctx->u32SrcHeight);
715     RK_PRINT("input virtual width  : %d\n", ctx->u32SrcVirWidth);
716     RK_PRINT("input virtual height : %d\n", ctx->u32SrcVirHeight);
717     RK_PRINT("input pixel format   : %d\n", ctx->enSrcPixFormat);
718     RK_PRINT("input compress mode  : %d\n", ctx->enSrcCompressMode);
719     RK_PRINT("output width         : %d\n", ctx->u32DstWidth);
720     RK_PRINT("output height        : %d\n", ctx->u32DstHeight);
721     RK_PRINT("output pixel format  : %d\n", ctx->enDstPixFormat);
722     RK_PRINT("output compress mode : %d\n", ctx->enDstCompressMode);
723     RK_PRINT("work mode            : %d\n", ctx->enAvsWorkMode);
724     RK_PRINT("projection mode      : %d\n", ctx->enAvsProjMode);
725     RK_PRINT("params sources       : %d\n", ctx->enParamSource);
726     RK_PRINT("lut file path        : %s\n", ctx->lutFilePath);
727     RK_PRINT("lut accuracy         : %d\n", ctx->enLutAccuracy);
728     RK_PRINT("lut fuse width       : %d\n", ctx->enLutFuseWidth);
729     RK_PRINT("lut step x           : %d\n", ctx->stLutStep.enStepX);
730     RK_PRINT("lut step y           : %d\n", ctx->stLutStep.enStepY);
731     RK_PRINT("calib file name      : %s\n", ctx->calibFileName);
732     RK_PRINT("mesh file path       : %s\n", ctx->meshFilePath);
733     RK_PRINT("avs frame sync       : %d\n", ctx->bFrameSync);
734     RK_PRINT("center x             : %d\n", ctx->stCenter.s32X);
735     RK_PRINT("center x             : %d\n", ctx->stCenter.s32Y);
736     RK_PRINT("fov x                : %d\n", ctx->stFov.u32FOVX);
737     RK_PRINT("fov y                : %d\n", ctx->stFov.u32FOVY);
738     RK_PRINT("rotation ori yaw     : %d\n", ctx->stOriRotation.s32Yaw);
739     RK_PRINT("rotation ori pitch   : %d\n", ctx->stOriRotation.s32Pitch);
740     RK_PRINT("rotation ori roll    : %d\n", ctx->stOriRotation.s32Roll);
741     RK_PRINT("rotation yaw         : %d\n", ctx->stRotation.s32Yaw);
742     RK_PRINT("rotation pitch       : %d\n", ctx->stRotation.s32Pitch);
743     RK_PRINT("rotation roll        : %d\n", ctx->stRotation.s32Roll);
744     RK_PRINT("distance             : %3.2f\n", ctx->fDistance);
745     RK_PRINT("enable comm mb pool  : %d\n", ctx->bCommPool);
746 }
747 
main(int argc,const char ** argv)748 RK_S32 main(int argc, const char **argv) {
749     RK_S32 s32Ret = RK_FAILURE;
750     TEST_AVS_CTX_S   ctx;
751 
752     memset(&ctx, 0, sizeof(TEST_AVS_CTX_S));
753 
754     ctx.dstFilePath        = RK_NULL;
755 
756     ctx.s32LoopCount       = 1;
757     ctx.enTestMode         = TEST_MODE_AVS_ONLY;
758     ctx.enParamSource      = AVS_PARAM_SOURCE_CALIB;
759     ctx.bFrameSync         = RK_FALSE;
760     ctx.enAvsWorkMode      = AVS_MODE_BLEND;
761     ctx.s32GrpNum          = 1;
762     ctx.s32ChnNum          = 1;
763     ctx.s32PipeNum         = 6;
764     ctx.s32GrpIndex        = 0;
765     ctx.u32ChnDepth        = 1;
766     ctx.u32FrameBufCnt     = 3;
767     ctx.s32SrcChnRate      = -1;
768     ctx.s32DstChnRate      = -1;
769     ctx.s32SrcGrpRate      = -1;
770     ctx.s32DstGrpRate      = -1;
771     ctx.fDistance          = 1.0;
772 
773     RK_LOGE("avs test running enter!");
774 
775     struct argparse_option options[] = {
776         OPT_HELP(),
777         OPT_GROUP("basic options:"),
778         OPT_STRING('i', "input",  &(ctx.srcFilePath),
779                    "input file name. e.g.(/userdata/6x_equirectangular/input_image/). default(NULL).", NULL, 0, 0),
780         OPT_STRING('o', "output", &(ctx.dstFilePath),
781                     "output file path. e.g.(/userdata/res/). default(NULL).", NULL, 0, 0),
782         OPT_INTEGER('\0', "test_mode", &(ctx.enTestMode),
783                     "test mode. default(0. 0: avs single mod test, 1: multi mods bind test).", NULL, 0, 0),
784         OPT_INTEGER('n', "loop count", &(ctx.s32LoopCount),
785                     "loop running count. default(1).", NULL, 0, 0),
786         OPT_INTEGER('g', "group_count", &(ctx.s32GrpNum),
787                     "the count of avs group. default(1).", NULL, 0, 0),
788         OPT_INTEGER('p', "pipe_count", &(ctx.s32PipeNum),
789                     "the count of avs pipe. default(6).", NULL, 0, 0),
790         OPT_INTEGER('c', "channel_count", &(ctx.s32ChnNum),
791                     "the count of avs channel. default(1).", NULL, 0, 0),
792         OPT_INTEGER('w', "src_width", &(ctx.u32SrcWidth),
793                     "src width. e.g.(2560). <required>.", NULL, 0, 0),
794         OPT_INTEGER('h', "src_height", &(ctx.u32SrcHeight),
795                     "src height. e.g.(1520). <required>.", NULL, 0, 0),
796         OPT_INTEGER('\0', "src_vir_width", &(ctx.u32SrcVirWidth),
797                     "src virtual width. e.g.(2560). default(0).", NULL, 0, 0),
798         OPT_INTEGER('\0', "src_vir_height", &(ctx.u32SrcVirHeight),
799                     "src virtual height. e.g.(1520). default(0).", NULL, 0, 0),
800         OPT_INTEGER('f', "src_format", &(ctx.enSrcPixFormat),
801                     "src pixel format. default(only 0. 0 is NV12).", NULL, 0, 0),
802         OPT_INTEGER('m', "src_compress", &(ctx.enSrcCompressMode),
803                     "src compress mode. default(0. 0: NONE, 1: AFBC).", NULL, 0, 0),
804         OPT_INTEGER('W', "dst_width", &(ctx.u32DstWidth),
805                     "dst width. e.g.(8192). <required>.", NULL, 0, 0),
806         OPT_INTEGER('H', "dst_height", &(ctx.u32DstHeight),
807                     "dst height. e.g.(3840). <required>.", NULL, 0, 0),
808         OPT_INTEGER('M', "dst_compress", &(ctx.enDstCompressMode),
809                     "dst compress mode. default(0. 0: NONE, 1: AFBC).", NULL, 0, 0),
810         OPT_INTEGER('F', "dst_format", &(ctx.enDstPixFormat),
811                     "dst pixel format. default(only 0. 0 is NV12).", NULL, 0, 0),
812         OPT_INTEGER('\0', "work_mode", &(ctx.enAvsWorkMode),
813                     "work mode. default(0. 0: BLEND, 1: NOBLEND_VER, 2: NOBLEND_HOR, 3: NOBLEND_QR).",
814                     NULL, 0, 0),
815         OPT_INTEGER('\0', "proj_mode", &(ctx.enAvsProjMode),
816                     "projection mode. default(0. 0: EQUIRECTANGULAR, 1: RECTILINEAR, 2: CYLINDRICAL,"
817                     "3: CUBE_MAP, 4: EQUIRECTANGULAR_TRANS).",
818                     NULL, 0, 0),
819         OPT_INTEGER('\0', "frame_sync", &(ctx.bFrameSync),
820                     "whether enable avs frame sync. default(0. 0: Disable, 1: Enable).", NULL, 0, 0),
821         OPT_INTEGER('\0', "param_source", &(ctx.enParamSource),
822                     "params required for stitch are obtained by lut or calib. default(1. 0: Lut, 1: Calib).",
823                     NULL, 0, 0),
824         OPT_STRING('\0', "lut_file_path",  &(ctx.lutFilePath),
825                     "lut file path. e.g.(/userdata/6x_equirectangular/middle_lut/). default(NULL).", NULL, 0, 0),
826         OPT_INTEGER('\0', "lut_accuracy", &(ctx.enLutAccuracy),
827                     "lut accuracy. default(0, 0: HIGH, 1: LOW).", NULL, 0, 0),
828         OPT_INTEGER('\0', "lut_use_width", &(ctx.enLutFuseWidth),
829                     "lut fuse width. default(0, 0: 128 pixel, 1: 256 pixel, 2: 512 pixel).", NULL, 0, 0),
830         OPT_INTEGER('\0', "lut_step_x", &(ctx.stLutStep.enStepX),
831                     "lut step in the x-axis direction. default(0, 0: 16 pixel, 1: 32 pixel, 2: 64 pixel).", NULL, 0, 0),
832         OPT_INTEGER('\0', "lut_step_y", &(ctx.stLutStep.enStepY),
833                     "lut step in the y-axis direction. default(0, 0: 16 pixel, 1: 32 pixel, 2: 64 pixel).", NULL, 0, 0),
834         OPT_STRING('\0', "calib_file_name",  &(ctx.calibFileName),
835                    "calib file name. e.g.(/userdata/avs/6x_equirectangular/avs_calib/calib_file.pto). default(NULL).",
836                    NULL, 0, 0),
837         OPT_STRING('\0', "mesh_file_path",  &(ctx.meshFilePath),
838                    "mesh file path. e.g.(/userdata/avs/6x_equirectangular/avs_mesh/). default(NULL).", NULL, 0, 0),
839         OPT_INTEGER('\0', "center_x", &(ctx.stCenter.s32X),
840                     "center point in the x-axis direction. default(0).", NULL, 0, 0),
841         OPT_INTEGER('\0', "center_y", &(ctx.stCenter.s32Y),
842                     "center point in the y-axis direction. default(0).", NULL, 0, 0),
843         OPT_INTEGER('\0', "fov_x", &(ctx.stFov.u32FOVX),
844                     "fov size in the x-axis direction. default(0).", NULL, 0, 0),
845         OPT_INTEGER('\0', "fov_y", &(ctx.stFov.u32FOVY),
846                     "fov size in the y-axis direction. default(0).", NULL, 0, 0),
847         OPT_INTEGER('\0', "ori_yaw", &(ctx.stOriRotation.s32Yaw),
848                     "ori rotation in the yaw direction. default(0).", NULL, 0, 0),
849         OPT_INTEGER('\0', "ori_pitch", &(ctx.stOriRotation.s32Pitch),
850                     "ori rotation in the pitch direction. default(0).", NULL, 0, 0),
851         OPT_INTEGER('\0', "ori_roll", &(ctx.stOriRotation.s32Roll),
852                     "ori rotation in the roll direction. default(0).", NULL, 0, 0),
853         OPT_INTEGER('\0', "yaw", &(ctx.stRotation.s32Yaw),
854                     "rotation in the yaw direction. default(0).", NULL, 0, 0),
855         OPT_INTEGER('\0', "pitch", &(ctx.stRotation.s32Pitch),
856                     "rotation in the pitch direction. default(0).", NULL, 0, 0),
857         OPT_INTEGER('\0', "distance", &(ctx.fDistance),
858                     "optimal stitch distance. default(1.0).", NULL, 0, 0),
859         OPT_INTEGER('\0', "src_grp_rate", &(ctx.s32SrcGrpRate),
860                     "src avs group frame rate, default(-1).", NULL, 0, 0),
861         OPT_INTEGER('\0', "dst_grp_rate", &(ctx.s32DstGrpRate),
862                     "dst avs group frame rate, default(-1).", NULL, 0, 0),
863         OPT_INTEGER('d', "chn_depth", &(ctx.u32ChnDepth),
864                     "channel output depth, default(3)", NULL, 0, 0),
865         OPT_INTEGER('b', "chn_buf_cnt", &(ctx.u32FrameBufCnt),
866                     "channel output buf cnt, default(3)", NULL, 0, 0),
867         OPT_INTEGER('\0', "roll", &(ctx.stRotation.s32Roll),
868                     "rotation in the roll direction. default(0).", NULL, 0, 0),
869         OPT_INTEGER('\0', "src_chn_rate", &(ctx.s32SrcChnRate),
870                     "src avs channel frame rate, default(-1).", NULL, 0, 0),
871         OPT_INTEGER('\0', "dst_chn_rate", &(ctx.s32DstChnRate),
872                     "dst avs channel frame rate, default(-1).", NULL, 0, 0),
873         OPT_BOOLEAN('\0', "comm_mb_pool", &(ctx.bCommPool),
874                     "whether enable common mb pool, default(0, 0: Disable, 1: Enable).", NULL, 0, 0),
875         OPT_GROUP("external options:"),
876         OPT_BOOLEAN('\0', "get_final_lut", &(ctx.bGetFinalLut),
877                     "whether get final lut, default(0, 0: Disable, 1: Enable).", NULL, 0, 0),
878         OPT_END(),
879     };
880 
881     struct argparse argparse;
882     argparse_init(&argparse, options, usages, 0);
883     argparse_describe(&argparse, "\nselect a test case to run.",
884                                  "\nuse --help for details.");
885 
886     argc = argparse_parse(&argparse, argc, argv);
887     mpi_avs_test_show_options(&ctx);
888 
889     if (ctx.u32SrcWidth <= 0
890         || ctx.u32SrcHeight <= 0
891         || ctx.u32DstWidth <= 0
892         || ctx.u32DstHeight <= 0) {
893         argparse_usage(&argparse);
894         return RK_FAILURE;
895     }
896 
897     s32Ret = RK_MPI_SYS_Init();
898     if (s32Ret != RK_SUCCESS) {
899         return s32Ret;
900     }
901 
902     switch (ctx.enTestMode) {
903         case TEST_MODE_AVS_ONLY: {
904             s32Ret = test_single_avs_loop(&ctx);
905             if (s32Ret != RK_SUCCESS) {
906                 goto __FAILED;
907             }
908         } break;
909         case TEST_MODE_AVS_VO: {
910             s32Ret = test_avs_vo_loop(&ctx);
911             if (s32Ret != RK_SUCCESS) {
912                 goto __FAILED;
913             }
914         } break;
915         case TEST_MODE_AVS_VPSS_VENC: {
916             s32Ret = test_avs_vpss_venc_loop(&ctx);
917             if (s32Ret != RK_SUCCESS) {
918                 goto __FAILED;
919             }
920         } break;
921         default:
922             RK_LOGE("unsupport test mode: %d", ctx.enTestMode);
923         break;
924     }
925 
926     s32Ret = RK_MPI_SYS_Exit();
927     if (s32Ret != RK_SUCCESS) {
928         return s32Ret;
929     }
930     RK_LOGV("test running ok.");
931 
932     return RK_SUCCESS;
933 
934 __FAILED:
935     RK_LOGE("test running exit: %x", s32Ret);
936     RK_MPI_SYS_Exit();
937 
938     return s32Ret;
939 }
940