xref: /OK3568_Linux_fs/external/rockit/mpi/example/mod/test_mpi_venc.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2018 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 #include <cstdio>
18 #include <cerrno>
19 #include <cstring>
20 #include <cstdlib>
21 #include <unistd.h>
22 #include <pthread.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 
26 #include "rk_debug.h"
27 #include "rk_mpi_sys.h"
28 #include "rk_mpi_mb.h"
29 #include "rk_mpi_venc.h"
30 #include "rk_mpi_cal.h"
31 
32 #include "test_comm_argparse.h"
33 #include "test_comm_imgproc.h"
34 #include "test_comm_venc.h"
35 #include "test_comm_utils.h"
36 
37 #define MAX_TIME_OUT_MS          20
38 #define TEST_RC_MODE             0
39 #define TEST_CROP_PARAM_CHANGE   0
40 
41 typedef struct _rkMpiVENCCtx {
42     const char     *srcFileUri;
43     const char     *dstFilePath;
44     RK_U32          u32SrcWidth;
45     RK_U32          u32SrcHeight;
46     RK_U32          u32srcVirWidth;
47     RK_U32          u32srcVirHeight;
48     RK_S32          s32LoopCount;
49     RK_U32          u32ChnIndex;
50     RK_U32          u32ChNum;
51     RK_U32          u32SrcPixFormat;
52     RK_U32          u32DstCodec;
53     RK_U32          u32BufferSize;
54     RK_U32          u32StreamSize;
55     RK_U32          u32StreamBufCnt;
56     RK_U32          u32BitRateKb;
57     RK_U32          u32BitRateKbMax;
58     RK_U32          u32BitRateKbMin;
59     RK_U32          u32GopSize;
60     RK_U32          u32RoiTestCount;
61     RK_U32          u32FixQp;
62     RK_U32          u32DeBreath;
63     RK_U32          u32StatTime;
64     RK_S32          s32SnapPicCount;
65     RK_S32          s32FrameRateIn;
66     RK_S32          s32FrameRateOut;
67     RK_BOOL         threadExit;
68     RK_BOOL         bFrameRate;
69     RK_BOOL         bInsertUserData;
70     COMPRESS_MODE_E enCompressMode;
71     VENC_RC_MODE_E  enRcMode;
72     VENC_GOP_MODE_E enGopMode;
73     VENC_CROP_TYPE_E enCropType;
74     ROTATION_E enRotation;
75     MIRROR_E   enMirror;
76     RK_BOOL    bSuperFrm;
77     RK_BOOL    bFrmLost;
78     RK_BOOL    bIntraRefresh;
79     RK_BOOL    bHierarchicalQp;
80     RK_BOOL    bMjpegParam;
81     RK_BOOL    bMjpegRcParam;
82     RK_BOOL    bForceIdr;
83     RK_BOOL    bFullRange;
84     RK_BOOL    bSendFrameEx;
85     RK_BOOL    bQpmap;
86     RK_BOOL    bRefParam;
87     MB_POOL    vencPoolInput;
88     MB_POOL    vencPoolOutput[VENC_MAX_CHN_NUM];
89     RK_BOOL    bAttachPool;
90     RK_BOOL    bPerformance;
91     RK_BOOL    bSliceSplit;
92 } TEST_VENC_CTX_S;
93 
read_with_pixel_width(RK_U8 * pBuf,RK_U32 u32Width,RK_U32 u32VirHeight,RK_U32 u32VirWidth,RK_U32 u32PixWidth,FILE * fp)94 static RK_S32 read_with_pixel_width(RK_U8 *pBuf, RK_U32 u32Width, RK_U32 u32VirHeight,
95                                      RK_U32 u32VirWidth, RK_U32 u32PixWidth, FILE *fp) {
96     RK_U32 u32Row;
97     RK_S32 s32ReadSize;
98 
99     for (u32Row = 0; u32Row < u32VirHeight; u32Row++) {
100         s32ReadSize = fread(pBuf + u32Row * u32VirWidth * u32PixWidth, 1, u32Width * u32PixWidth, fp);
101         if (s32ReadSize != u32Width * u32PixWidth) {
102             RK_LOGE("read file failed expect %d vs %d\n",
103                       u32Width * u32PixWidth, s32ReadSize);
104             return RK_FAILURE;
105         }
106     }
107 
108     return RK_SUCCESS;
109 }
110 
read_image(RK_U8 * pVirAddr,RK_U32 u32Width,RK_U32 u32Height,RK_U32 u32VirWidth,RK_U32 u32VirHeight,RK_U32 u32PixFormat,FILE * fp)111 static RK_S32 read_image(RK_U8 *pVirAddr, RK_U32 u32Width, RK_U32 u32Height,
112                                   RK_U32 u32VirWidth, RK_U32 u32VirHeight, RK_U32 u32PixFormat, FILE *fp) {
113     RK_U32 u32Row = 0;
114     RK_U32 u32ReadSize = 0;
115     RK_S32 s32Ret = RK_SUCCESS;
116 
117     RK_U8 *pBufy = pVirAddr;
118     RK_U8 *pBufu = pBufy + u32VirWidth * u32VirHeight;
119     RK_U8 *pBufv = pBufu + u32VirWidth * u32VirHeight / 4;
120 
121     switch (u32PixFormat) {
122         case RK_FMT_YUV420SP: {
123             for (u32Row = 0; u32Row < u32VirHeight; u32Row++) {
124                 u32ReadSize = fread(pBufy + u32Row * u32VirWidth, 1, u32Width, fp);
125                 if (u32ReadSize != u32Width) {
126                      return RK_FAILURE;
127                 }
128             }
129 
130             for (u32Row = 0; u32Row < u32VirHeight / 2; u32Row++) {
131                 u32ReadSize = fread(pBufu + u32Row * u32VirWidth, 1, u32Width, fp);
132                 if (u32ReadSize != u32Width) {
133                     return RK_FAILURE;
134                 }
135             }
136         } break;
137         case RK_FMT_RGB888:
138         case RK_FMT_BGR888: {
139             s32Ret = read_with_pixel_width(pBufy, u32Width, u32VirHeight, u32VirWidth, 3, fp);
140         } break;
141         default : {
142             RK_LOGE("read image do not support fmt %d\n", u32PixFormat);
143             return RK_FAILURE;
144         } break;
145     }
146 
147     return s32Ret;
148 }
149 
check_options(const TEST_VENC_CTX_S * ctx)150 static RK_S32 check_options(const TEST_VENC_CTX_S *ctx) {
151     if (ctx->u32SrcPixFormat == RK_FMT_BUTT ||
152         ctx->u32DstCodec <= RK_VIDEO_ID_Unused ||
153         ctx->u32SrcWidth <= 0 ||
154         ctx->u32SrcHeight <= 0) {
155         goto __FAILED;
156     }
157 
158     return RK_SUCCESS;
159 
160 __FAILED:
161     return RK_ERR_VENC_ILLEGAL_PARAM;
162 }
163 
venc_force_idr(void * pArgs)164 void* venc_force_idr(void *pArgs) {
165     TEST_VENC_CTX_S *pstCtx     = reinterpret_cast<TEST_VENC_CTX_S *>(pArgs);
166     RK_U32           u32Ch      = pstCtx->u32ChnIndex;
167 
168     while (!pstCtx->threadExit) {
169         RK_MPI_VENC_RequestIDR(u32Ch, RK_FALSE);
170         usleep(30000);
171     }
172 
173     return RK_NULL;
174 }
175 
venc_get_stream(void * pArgs)176 void* venc_get_stream(void *pArgs) {
177     TEST_VENC_CTX_S *pstCtx     = reinterpret_cast<TEST_VENC_CTX_S *>(pArgs);
178     void            *pData      = RK_NULL;
179     RK_S32           s32Ret     = RK_SUCCESS;
180     FILE            *fp         = RK_NULL;
181     char             name[256]  = {0};
182     RK_U32           u32Ch      = pstCtx->u32ChnIndex;
183     RK_S32           s32StreamCnt = 0;
184     VENC_STREAM_S    stFrame;
185 
186     if (pstCtx->dstFilePath != RK_NULL) {
187         mkdir(pstCtx->dstFilePath, 0777);
188 
189         snprintf(name, sizeof(name), "%s/test_%d.bin",
190             pstCtx->dstFilePath, pstCtx->u32ChnIndex);
191 
192         fp = fopen(name, "wb");
193         if (fp == RK_NULL) {
194             RK_LOGE("chn %d can't open file %s in get picture thread!\n", u32Ch, name);
195             return RK_NULL;
196         }
197     }
198     stFrame.pstPack = reinterpret_cast<VENC_PACK_S *>(malloc(sizeof(VENC_PACK_S)));
199 
200     while (!pstCtx->threadExit) {
201         s32Ret = RK_MPI_VENC_GetStream(u32Ch, &stFrame, -1);
202         if (s32Ret >= 0) {
203             s32StreamCnt++;
204             RK_LOGD("get chn %d stream %d", u32Ch, s32StreamCnt);
205             if (pstCtx->dstFilePath != RK_NULL) {
206                 pData = RK_MPI_MB_Handle2VirAddr(stFrame.pstPack->pMbBlk);
207                 fwrite(pData, 1, stFrame.pstPack->u32Len, fp);
208                 fflush(fp);
209             }
210             RK_MPI_VENC_ReleaseStream(u32Ch, &stFrame);
211             if (stFrame.pstPack->bStreamEnd == RK_TRUE) {
212                 RK_LOGI("chn %d reach EOS stream", u32Ch);
213                 break;
214             }
215         } else {
216              if (pstCtx->threadExit) {
217                 break;
218              }
219 
220              usleep(1000llu);
221         }
222     }
223 
224     if (stFrame.pstPack)
225         free(stFrame.pstPack);
226 
227     if (fp)
228         fclose(fp);
229 
230     return RK_NULL;
231 }
232 
h265_set_qpmap_64x64(RK_S16 * dst,RK_S16 * src,RK_S32 w,RK_S32 h)233 void h265_set_qpmap_64x64(RK_S16 *dst, RK_S16 *src, RK_S32 w, RK_S32 h) {
234     RK_S32 mb_w = RK_ALIGN(w, 64) / 64;
235     RK_S32 mb_h = RK_ALIGN(h, 64) / 64;
236     RK_S32 ctu_line = mb_w;
237     RK_S32 i, j, cu16cnt;
238 
239     for (j = 0; j < mb_h; j++) {
240         for (i = 0; i < mb_w; i++) {
241             RK_S32 ctu_addr = j * ctu_line + i;
242             RK_S32 cu16_num_line = ctu_line * 4;
243             for (cu16cnt = 0; cu16cnt < 16; cu16cnt++) {
244                 RK_S32 cu16_x;
245                 RK_S32 cu16_y;
246                 RK_S32 cu16_addr_in_frame;
247                 cu16_x = cu16cnt & 3;
248                 cu16_y = cu16cnt / 4;
249                 cu16_x += i * 4;
250                 cu16_y += j * 4;
251                 cu16_addr_in_frame = cu16_x + cu16_y * cu16_num_line;
252                 dst[ctu_addr * 16 + cu16cnt] = src[cu16_addr_in_frame];
253             }
254         }
255     }
256 }
257 
venc_send_frame(void * pArgs)258 void* venc_send_frame(void *pArgs) {
259     TEST_VENC_CTX_S     *pstCtx        = reinterpret_cast<TEST_VENC_CTX_S *>(pArgs);
260     RK_S32               s32Ret         = RK_SUCCESS;
261     RK_U8               *pVirAddr       = RK_NULL;
262     FILE                *fp             = RK_NULL;
263     MB_BLK               blk            = RK_NULL;
264     RK_S32               s32LoopCount   = pstCtx->s32LoopCount;
265     MB_POOL              pool           = pstCtx->vencPoolInput;
266     RK_U32               u32Ch          = pstCtx->u32ChnIndex;
267     RK_S32               s32FrameCount  = 0;
268     RK_S32               s32ReachEOS    = 0;
269     VIDEO_FRAME_INFO_S   stFrame;
270     MB_BLK               qpmapBlk = RK_NULL;
271     RK_S16              *qpmapData = RK_NULL;
272     RK_S16              *qpmapTmp = RK_NULL;
273 
274     if (pstCtx->bSendFrameEx || pstCtx->bQpmap) {
275         if (pstCtx->u32DstCodec == RK_VIDEO_ID_AVC || pstCtx->u32DstCodec == RK_VIDEO_ID_HEVC) {
276             RK_U8 align = (pstCtx->u32DstCodec == RK_VIDEO_ID_AVC ? 16 : 64);
277             RK_U32 qpmapWidth = RK_ALIGN(pstCtx->u32SrcWidth, align) / 16;
278             RK_U32 qpmapHeight = RK_ALIGN(pstCtx->u32SrcHeight, align) / 16;
279             RK_U32 qpmapSize = qpmapWidth * qpmapHeight * 2;
280             RK_S16 *qpmap = RK_NULL;
281             if (!qpmapBlk) {
282                 s32Ret = RK_MPI_SYS_MmzAlloc(&qpmapBlk, RK_NULL, RK_NULL, qpmapSize);
283                 if (s32Ret != RK_SUCCESS)
284                     goto __EXIT;
285                 qpmapData = (RK_S16 *)RK_MPI_MB_Handle2VirAddr(qpmapBlk);
286             }
287             if (pstCtx->u32DstCodec == RK_VIDEO_ID_HEVC && !qpmapTmp) {
288                 qpmapTmp = (RK_S16 *)malloc(qpmapSize);
289                 if (!qpmapTmp)
290                     goto __EXIT;
291             }
292             qpmap = (pstCtx->u32DstCodec == RK_VIDEO_ID_AVC ? qpmapData : qpmapTmp);
293             for (RK_U32 j = 0; j < qpmapHeight; j++) {
294                 for (RK_U32 i = 0; i < qpmapWidth; i++) {
295                     qpmap[j * qpmapHeight + i] = 0x8F80;  // 0x8F: abs qp, qp 15, 0x80: must
296                 }
297             }
298             if (pstCtx->u32DstCodec == RK_VIDEO_ID_HEVC) {
299                 h265_set_qpmap_64x64(qpmapData, qpmapTmp, pstCtx->u32SrcWidth, pstCtx->u32SrcHeight);
300             }
301         }
302     }
303 
304     if (pstCtx->bQpmap) {
305         RK_MPI_VENC_SetQpmap(pstCtx->u32ChnIndex, qpmapBlk);
306     }
307 
308     memset(&stFrame, 0, sizeof(VIDEO_FRAME_INFO_S));
309 
310 
311 
312     while (!pstCtx->threadExit) {
313         blk = RK_MPI_MB_GetMB(pool, pstCtx->u32BufferSize, RK_TRUE);
314 
315         if (RK_NULL == blk) {
316             RK_LOGE("RK_MPI_MB_GetMB fail:%d", u32Ch);
317             usleep(2000llu);
318             continue;
319         }
320         pVirAddr = reinterpret_cast<RK_U8 *>(RK_MPI_MB_Handle2VirAddr(blk));
321 
322         if (pstCtx->srcFileUri) {
323             if (fp == RK_NULL) {
324                 fp = fopen(pstCtx->srcFileUri, "r");
325                 if (fp == RK_NULL) {
326                     RK_LOGE("chn %d can't open file %s!\n", u32Ch, pstCtx->srcFileUri);
327                     return RK_NULL;
328                 }
329             }
330             if (pstCtx->enCompressMode == COMPRESS_AFBC_16x16) {
331                 if (fread(pVirAddr, 1, pstCtx->u32BufferSize, fp) != pstCtx->u32BufferSize)
332                     s32Ret = RK_FAILURE;
333                 else
334                     s32Ret = RK_SUCCESS;
335             } else {
336                 s32Ret = read_image(pVirAddr, pstCtx->u32SrcWidth, pstCtx->u32SrcHeight,
337                          pstCtx->u32srcVirWidth, pstCtx->u32srcVirHeight, pstCtx->u32SrcPixFormat, fp);
338             }
339         } else {
340             s32Ret = TEST_COMM_FillImage(pVirAddr, pstCtx->u32SrcWidth,
341                             pstCtx->u32SrcHeight,
342                             pstCtx->u32srcVirWidth,
343                             pstCtx->u32srcVirHeight,
344                             (PIXEL_FORMAT_E)pstCtx->u32SrcPixFormat, s32FrameCount);
345             if (s32Ret != RK_SUCCESS) {
346                 RK_MPI_MB_ReleaseMB(blk);
347                 RK_LOGE("TEST_COMM_FillImage fail ch %d", u32Ch);
348                 return RK_NULL;
349             }
350         }
351 
352         if (s32Ret != RK_SUCCESS) {
353              s32ReachEOS = 1;
354              if (s32LoopCount > 0) {
355                 s32LoopCount--;
356                 RK_LOGD("finish venc count %d\n", pstCtx->s32LoopCount - s32LoopCount);
357                 if (s32LoopCount > 0) {
358                     s32ReachEOS = 0;
359                     RK_MPI_MB_ReleaseMB(blk);
360 
361                     fseek(fp, 0L, SEEK_SET);
362                     RK_LOGI("seek finish ch %d", u32Ch);
363                     continue;
364                 }
365              }
366         }
367 
368 #if TEST_CROP_PARAM_CHANGE
369         if (s32FrameCount == 50) {
370             VENC_CHN_PARAM_S stParam;
371             RK_MPI_VENC_GetChnParam(u32Ch, &stParam);
372             // for crop test
373             if (stParam.stCropCfg.enCropType == VENC_CROP_ONLY) {
374                 stParam.stCropCfg.stCropRect.s32X = 100;
375                 stParam.stCropCfg.stCropRect.s32Y = 100;
376                 stParam.stCropCfg.stCropRect.u32Height = 400;
377                 stParam.stCropCfg.stCropRect.u32Width = 300;
378             } else if (stParam.stCropCfg.enCropType == VENC_CROP_SCALE) {
379             // for crop/scale test
380                 stParam.stCropCfg.stScaleRect.stSrc.s32X = 100;
381                 stParam.stCropCfg.stScaleRect.stSrc.s32Y = 200;
382                 stParam.stCropCfg.stScaleRect.stSrc.u32Width = pstCtx->u32SrcWidth / 2;
383                 stParam.stCropCfg.stScaleRect.stSrc.u32Height = pstCtx->u32SrcHeight / 2;
384                 stParam.stCropCfg.stScaleRect.stDst.s32X = 0;
385                 stParam.stCropCfg.stScaleRect.stDst.s32Y = 0;
386                 stParam.stCropCfg.stScaleRect.stDst.u32Width = 1280;
387                 stParam.stCropCfg.stScaleRect.stDst.u32Height = 720;
388             }
389             RK_MPI_VENC_SetChnParam(u32Ch, &stParam);
390         }
391 #endif
392 
393         RK_MPI_SYS_MmzFlushCache(blk, RK_FALSE);
394 
395         stFrame.stVFrame.pMbBlk = blk;
396         stFrame.stVFrame.u32Width = pstCtx->u32SrcWidth;
397         stFrame.stVFrame.u32Height = pstCtx->u32SrcHeight;
398         stFrame.stVFrame.u32VirWidth = pstCtx->u32srcVirWidth;
399         stFrame.stVFrame.u32VirHeight = pstCtx->u32srcVirHeight;
400         stFrame.stVFrame.enPixelFormat = (PIXEL_FORMAT_E)pstCtx->u32SrcPixFormat;
401         stFrame.stVFrame.u32FrameFlag |= s32ReachEOS ? FRAME_FLAG_SNAP_END : 0;
402         stFrame.stVFrame.enCompressMode = pstCtx->enCompressMode;
403 
404         if (pstCtx->bInsertUserData) {
405             RK_U32 user_len;
406             RK_U8 user_data[] = "this is rockchip user data";
407             user_len = sizeof(user_data);
408             RK_MPI_VENC_InsertUserData(u32Ch, user_data, user_len);
409             RK_CHAR user_data2[1024];
410             snprintf(user_data2, sizeof(user_data2), "rockchip continuous user data:%d", s32FrameCount);
411             user_len = strlen(user_data2);
412             RK_MPI_VENC_InsertUserData(u32Ch, reinterpret_cast<RK_U8 *>(user_data2), user_len);
413         }
414 __RETRY:
415         if (pstCtx->bSendFrameEx) {
416             if (pstCtx->u32DstCodec == RK_VIDEO_ID_AVC || pstCtx->u32DstCodec == RK_VIDEO_ID_HEVC) {
417                 USER_FRAME_INFO_S stUser;
418                 memset(&stUser, 0, sizeof(stUser));
419                 memcpy(&stUser.stUserFrame, &stFrame, sizeof(stFrame));
420                 stUser.stUserRcInfo.bQpMapValid = RK_TRUE;
421                 stUser.stUserRcInfo.pMbBlkQpMap = qpmapBlk;
422                 s32Ret = RK_MPI_VENC_SendFrameEx(u32Ch, &stUser, -1);
423             } else {
424                 s32Ret = RK_MPI_VENC_SendFrame(u32Ch, &stFrame, -1);
425             }
426         } else {
427             s32Ret = RK_MPI_VENC_SendFrame(u32Ch, &stFrame, -1);
428         }
429         if (s32Ret < 0) {
430             if (pstCtx->threadExit) {
431                 RK_MPI_MB_ReleaseMB(blk);
432                 break;
433             }
434 
435             usleep(10000llu);
436             goto  __RETRY;
437         } else {
438             if (!pstCtx->bPerformance)
439                 RK_MPI_MB_ReleaseMB(blk);
440             s32FrameCount++;
441             RK_LOGD("chn %d frame %d", u32Ch, s32FrameCount);
442         }
443         if (s32ReachEOS ||
444            (pstCtx->s32SnapPicCount != -1 && s32FrameCount >= pstCtx->s32SnapPicCount)) {
445             RK_LOGI("chn %d reach EOS.", u32Ch);
446             if (pstCtx->bPerformance)
447                 RK_MPI_MB_ReleaseMB(blk);
448             break;
449         }
450         if (pstCtx->bPerformance) {
451             usleep(1000llu);
452             goto __RETRY;
453         }
454     }
455 
456 __EXIT:
457     if (fp)
458         fclose(fp);
459 
460     if (pstCtx->bSendFrameEx || pstCtx->bQpmap) {
461         if (qpmapBlk)
462             RK_MPI_SYS_MmzFree(qpmapBlk);
463         if (qpmapTmp)
464             free(qpmapTmp);
465     }
466 
467     return RK_NULL;
468 }
469 
unit_test_mpi_venc(TEST_VENC_CTX_S * ctx)470 RK_S32 unit_test_mpi_venc(TEST_VENC_CTX_S *ctx) {
471     RK_S32                  s32Ret = RK_SUCCESS;
472     RK_U32                  u32Ch = 0;
473     VENC_CHN_ATTR_S         stAttr;
474     VENC_CHN_PARAM_S        stParam;
475     VENC_RECV_PIC_PARAM_S   stRecvParam;
476     VENC_RC_PARAM_S         stRcParam;
477     MB_POOL_CONFIG_S        stMbPoolCfg;
478     TEST_VENC_CTX_S         stVencCtx[VENC_MAX_CHN_NUM];
479     pthread_t               vencThread[VENC_MAX_CHN_NUM] = {0};
480     pthread_t               getStreamThread[VENC_MAX_CHN_NUM] = {0};
481     pthread_t               forceIdrThread[VENC_MAX_CHN_NUM];
482 
483     memset(&stAttr, 0, sizeof(VENC_CHN_ATTR_S));
484     memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
485     memset(&stRcParam, 0, sizeof(VENC_RC_PARAM_S));
486     memset(&stParam, 0, sizeof(VENC_CHN_PARAM_S));
487 
488     if (ctx->u32BufferSize <= 0) {
489         PIC_BUF_ATTR_S stPicBufAttr;
490         MB_PIC_CAL_S stMbPicCalResult;
491 
492         stPicBufAttr.u32Width = ctx->u32SrcWidth;
493         stPicBufAttr.u32Height = ctx->u32SrcHeight;
494         stPicBufAttr.enPixelFormat = (PIXEL_FORMAT_E)ctx->u32SrcPixFormat;
495         stPicBufAttr.enCompMode = ctx->enCompressMode;
496         s32Ret = RK_MPI_CAL_COMM_GetPicBufferSize(&stPicBufAttr, &stMbPicCalResult);
497         if (s32Ret != RK_SUCCESS) {
498             RK_LOGE("get picture buffer size failed. err 0x%x", s32Ret);
499             return s32Ret;
500         }
501         ctx->u32BufferSize = stMbPicCalResult.u32MBSize;
502         RK_LOGD("calc picture size: %d", ctx->u32BufferSize);
503     }
504     if (ctx->u32BufferSize > 8192 * 8192 * 4) {
505         RK_LOGE("too large picture size: %d", ctx->u32BufferSize);
506         return RK_FAILURE;
507     }
508     if (ctx->u32StreamSize == 0) {
509         ctx->u32StreamSize = ctx->u32BufferSize;
510     }
511 
512     // for input image pool
513     memset(&stMbPoolCfg, 0, sizeof(MB_POOL_CONFIG_S));
514     stMbPoolCfg.u64MBSize = ctx->u32BufferSize;
515     stMbPoolCfg.u32MBCnt  = 3 * ctx->u32ChNum;
516     stMbPoolCfg.enAllocType = MB_ALLOC_TYPE_DMA;
517     stMbPoolCfg.bPreAlloc = RK_TRUE;
518     ctx->vencPoolInput = RK_MPI_MB_CreatePool(&stMbPoolCfg);
519     if (ctx->vencPoolInput == MB_INVALID_POOLID) {
520         RK_LOGE("create vencPoolInput failed!");
521         return RK_FAILURE;
522     }
523 
524     for (u32Ch = 0; u32Ch < ctx->u32ChNum; u32Ch++) {
525         memset(&stAttr, 0, sizeof(VENC_CHN_ATTR_S));
526         memset(&stRecvParam, 0, sizeof(VENC_RECV_PIC_PARAM_S));
527         memset(&stRcParam, 0, sizeof(VENC_RC_PARAM_S));
528         memset(&stParam, 0, sizeof(VENC_CHN_PARAM_S));
529         if (ctx->u32ChNum >= 1) {
530             ctx->u32ChnIndex = u32Ch;
531         }
532 
533         stAttr.stRcAttr.enRcMode = ctx->enRcMode;
534         stAttr.stRcAttr.stH264Cbr.u32Gop = ctx->u32GopSize;
535         stAttr.stRcAttr.stH264Cbr.u32BitRate = ctx->u32BitRateKb;
536         TEST_VENC_SET_BitRate(&stAttr.stRcAttr, ctx->u32BitRateKb, ctx->u32BitRateKbMax, ctx->u32BitRateKbMin);
537         TEST_VENC_SET_FixQp(&stAttr.stRcAttr, ctx->u32FixQp, ctx->u32FixQp + 2, ctx->u32FixQp);
538         TEST_VENC_SET_StatTime(&stAttr.stRcAttr, ctx->u32StatTime);
539 
540         stAttr.stVencAttr.enType = (RK_CODEC_ID_E)ctx->u32DstCodec;
541         stAttr.stVencAttr.u32Profile = H264E_PROFILE_HIGH;
542         stAttr.stVencAttr.enPixelFormat = (PIXEL_FORMAT_E)ctx->u32SrcPixFormat;
543         stAttr.stVencAttr.u32PicWidth = ctx->u32SrcWidth;
544         stAttr.stVencAttr.u32PicHeight = ctx->u32SrcHeight;
545         stAttr.stVencAttr.enMirror = ctx->enMirror;
546 
547         if (ctx->u32srcVirWidth <= 0) {
548             ctx->u32srcVirWidth = ctx->u32SrcWidth;
549         }
550         stAttr.stVencAttr.u32VirWidth = ctx->u32srcVirWidth;
551 
552         if (ctx->u32srcVirHeight <= 0) {
553             ctx->u32srcVirHeight = ctx->u32SrcHeight;
554         }
555         stAttr.stVencAttr.u32VirHeight = ctx->u32srcVirHeight;
556         stAttr.stVencAttr.u32StreamBufCnt = ctx->u32StreamBufCnt;
557         stAttr.stVencAttr.u32BufSize = ctx->u32StreamSize;
558 
559         if (stAttr.stVencAttr.enType == RK_VIDEO_ID_JPEG) {
560             stAttr.stVencAttr.stAttrJpege.bSupportDCF = RK_FALSE;
561             stAttr.stVencAttr.stAttrJpege.stMPFCfg.u8LargeThumbNailNum = 0;
562             stAttr.stVencAttr.stAttrJpege.enReceiveMode = VENC_PIC_RECEIVE_SINGLE;
563         }
564 
565         RK_MPI_VENC_CreateChn(u32Ch, &stAttr);
566 
567         stParam.stCropCfg.enCropType = ctx->enCropType;
568         // for crop test
569         if (stParam.stCropCfg.enCropType == VENC_CROP_ONLY) {
570             stParam.stCropCfg.stCropRect.s32X = 10;
571             stParam.stCropCfg.stCropRect.s32Y = 10;
572             stParam.stCropCfg.stCropRect.u32Height = 100;
573             stParam.stCropCfg.stCropRect.u32Width = 100;
574         } else if (stParam.stCropCfg.enCropType == VENC_CROP_SCALE) {
575         // for crop/scale test
576             stParam.stCropCfg.stScaleRect.stSrc.s32X = 0;
577             stParam.stCropCfg.stScaleRect.stSrc.s32Y = 0;
578             stParam.stCropCfg.stScaleRect.stSrc.u32Width = 0;
579             stParam.stCropCfg.stScaleRect.stSrc.u32Height = 0;
580             stParam.stCropCfg.stScaleRect.stDst.s32X = 0;
581             stParam.stCropCfg.stScaleRect.stDst.s32Y = 0;
582             stParam.stCropCfg.stScaleRect.stDst.u32Width = 640;
583             stParam.stCropCfg.stScaleRect.stDst.u32Height = 360;
584         }
585         // for framerate test
586         {
587             stParam.stFrameRate.bEnable = ctx->bFrameRate;
588             stParam.stFrameRate.s32SrcFrmRateNum = ctx->s32FrameRateIn;
589             stParam.stFrameRate.s32SrcFrmRateDen = 1;
590             stParam.stFrameRate.s32DstFrmRateNum = ctx->s32FrameRateOut;
591             stParam.stFrameRate.s32DstFrmRateDen = 1;
592         }
593         RK_MPI_VENC_SetChnParam(u32Ch, &stParam);
594 
595 #if TEST_RC_MODE
596         stAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264AVBR;
597         stAttr.stRcAttr.stH264Avbr.u32Gop = 99;
598         stAttr.stRcAttr.stH264Avbr.u32SrcFrameRateNum = 25;
599         stAttr.stRcAttr.stH264Avbr.u32SrcFrameRateDen = 1;
600         stAttr.stRcAttr.stH264Avbr.fr32DstFrameRateNum = 25;
601         stAttr.stRcAttr.stH264Avbr.fr32DstFrameRateDen = 1;
602         stAttr.stRcAttr.stH264Avbr.u32BitRate = 614400;
603         RK_MPI_VENC_SetChnAttr(u32Ch, &stAttr);
604 #endif
605         if (ctx->bAttachPool) {
606             // for output stream pool
607             memset(&stMbPoolCfg, 0, sizeof(MB_POOL_CONFIG_S));
608             stMbPoolCfg.u64MBSize = ctx->u32StreamSize;
609             stMbPoolCfg.u32MBCnt  = 3;
610             stMbPoolCfg.enAllocType = MB_ALLOC_TYPE_DMA;
611             stMbPoolCfg.bPreAlloc = RK_TRUE;  //  this must prealloc if attach enc output
612             ctx->vencPoolOutput[u32Ch] = RK_MPI_MB_CreatePool(&stMbPoolCfg);
613             if (ctx->vencPoolOutput[u32Ch] == MB_INVALID_POOLID) {
614                 RK_LOGE("create vencPoolOutput[%d] failed!", u32Ch);
615                 goto __FAILED;
616             }
617 
618             s32Ret = RK_MPI_VENC_AttachMbPool(u32Ch, ctx->vencPoolOutput[u32Ch]);
619             if (s32Ret != RK_SUCCESS) {
620                 RK_LOGE("RK_MPI_VENC_AttachMbPool fail:0x%x!", s32Ret);
621                 goto __FAILED;
622             }
623         }
624 
625         if (ctx->enGopMode) {
626             stAttr.stGopAttr.enGopMode = ctx->enGopMode;
627             if (!stAttr.stRcAttr.stH264Cbr.u32Gop)
628                 stAttr.stRcAttr.stH264Cbr.u32Gop = 60;
629             stAttr.stGopAttr.s32VirIdrLen = stAttr.stRcAttr.stH264Cbr.u32Gop / 2;
630             RK_MPI_VENC_SetChnAttr(u32Ch, &stAttr);
631         }
632 
633         if (ctx->enRotation) {
634             RK_MPI_VENC_SetChnRotation(u32Ch, ctx->enRotation);
635         }
636 
637         stRecvParam.s32RecvPicNum = ctx->s32SnapPicCount;
638         RK_MPI_VENC_StartRecvFrame(u32Ch, &stRecvParam);
639 
640         if (stAttr.stVencAttr.enType == RK_VIDEO_ID_JPEG) {
641             VENC_JPEG_PARAM_S stJpegParam;
642             memset(&stJpegParam, 0, sizeof(stJpegParam));
643             stJpegParam.u32Qfactor = 77;
644             RK_MPI_VENC_SetJpegParam(u32Ch, &stJpegParam);
645         }
646 
647         for (RK_U32 i = 0; i < ctx->u32RoiTestCount; i++) {
648             VENC_ROI_ATTR_S stRoiAttr;
649             stRoiAttr.u32Index = i;
650             stRoiAttr.bEnable = RK_TRUE;
651             stRoiAttr.bAbsQp = i % 2 ? RK_FALSE : RK_TRUE;
652             stRoiAttr.s32Qp = i + 42;
653             stRoiAttr.bIntra = i % 2 ? RK_TRUE : RK_FALSE;
654             stRoiAttr.stRect.s32X = RK_ALIGN_16((i + 1) * 16);
655             stRoiAttr.stRect.s32Y = RK_ALIGN_16((i + 1) * 16);
656             stRoiAttr.stRect.u32Width = RK_ALIGN_16(ctx->u32SrcWidth / (i + 2));
657             stRoiAttr.stRect.u32Height = RK_ALIGN_16(ctx->u32SrcHeight / (i + 2));
658             RK_MPI_VENC_SetRoiAttr(u32Ch, &stRoiAttr);
659         }
660 
661 #if TEST_RC_MODE
662         stRcParam.s32FirstFrameStartQp = 25;
663         stRcParam.stParamH264.u32StepQp = 4;
664         stRcParam.stParamH264.u32MinQp = 10;
665         stRcParam.stParamH264.u32MaxQp = 40;
666         stRcParam.stParamH264.u32MinIQp = 20;
667         stRcParam.stParamH264.u32MaxIQp = 30;
668         stRcParam.stParamH264.s32DeltIpQp = -2;
669         stRcParam.stParamH264.s32MaxReEncodeTimes = 2;
670         RK_MPI_VENC_SetRcParam(u32Ch, &stRcParam);
671 #endif
672 
673         if (!ctx->bFullRange) {
674             if (stAttr.stVencAttr.enType == RK_VIDEO_ID_AVC) {
675                 VENC_H264_VUI_S stH264Vui;
676                 RK_MPI_VENC_GetH264Vui(u32Ch, &stH264Vui);
677                 stH264Vui.stVuiVideoSignal.video_full_range_flag = 0;
678                 RK_MPI_VENC_SetH264Vui(u32Ch, &stH264Vui);
679             } else if (stAttr.stVencAttr.enType == RK_VIDEO_ID_HEVC) {
680                 VENC_H265_VUI_S stH265Vui;
681                 RK_MPI_VENC_GetH265Vui(u32Ch, &stH265Vui);
682                 stH265Vui.stVuiVideoSignal.video_full_range_flag = 0;
683                 RK_MPI_VENC_SetH265Vui(u32Ch, &stH265Vui);
684             }
685         }
686 
687         if (ctx->bSuperFrm) {
688             VENC_SUPERFRAME_CFG_S stSuperFrameCfg;
689             memset(&stSuperFrameCfg, 0, sizeof(stSuperFrameCfg));
690             stSuperFrameCfg.enSuperFrmMode = SUPERFRM_DISCARD;
691             stSuperFrameCfg.u32SuperIFrmBitsThr = 100 * 1024 * 8;  // 100KByte
692             stSuperFrameCfg.u32SuperPFrmBitsThr = 20 * 1024 * 8;  // 20KByte
693             stSuperFrameCfg.enRcPriority = VENC_RC_PRIORITY_FRAMEBITS_FIRST;
694             RK_MPI_VENC_SetSuperFrameStrategy(u32Ch, &stSuperFrameCfg);
695         }
696 
697         if (ctx->bIntraRefresh) {
698             VENC_INTRA_REFRESH_S stIntraRefresh;
699             memset(&stIntraRefresh, 0, sizeof(stIntraRefresh));
700             stIntraRefresh.bRefreshEnable = RK_TRUE;
701             stIntraRefresh.enIntraRefreshMode = INTRA_REFRESH_ROW;
702             stIntraRefresh.u32RefreshNum = 5;
703             RK_MPI_VENC_SetIntraRefresh(u32Ch, &stIntraRefresh);
704         }
705 
706         if (ctx->bHierarchicalQp) {
707             VENC_HIERARCHICAL_QP_S stHierarchicalQp;
708             memset(&stHierarchicalQp, 0, sizeof(stHierarchicalQp));
709             stHierarchicalQp.bHierarchicalQpEn = RK_TRUE;
710             stHierarchicalQp.s32HierarchicalQpDelta[0] = -10;
711             stHierarchicalQp.s32HierarchicalQpDelta[1] = -5;
712             stHierarchicalQp.s32HierarchicalFrameNum[0] = 2;
713             stHierarchicalQp.s32HierarchicalFrameNum[1] = 3;
714             RK_MPI_VENC_SetHierarchicalQp(u32Ch, &stHierarchicalQp);
715         }
716 
717         if (ctx->bMjpegParam && stAttr.stVencAttr.enType == RK_VIDEO_ID_MJPEG) {
718             VENC_MJPEG_PARAM_S stMjpegParam;
719             memset(&stMjpegParam, 0, sizeof(stMjpegParam));
720             /* set qtable for test only, users need set actual qtable */
721             memset(&stMjpegParam.u8YQt, 1, sizeof(stMjpegParam.u8YQt));
722             memset(&stMjpegParam.u8CbQt, 1, sizeof(stMjpegParam.u8CbQt));
723             memset(&stMjpegParam.u8CrQt, 1, sizeof(stMjpegParam.u8CrQt));
724             stMjpegParam.u32MCUPerECS = 100;
725             RK_MPI_VENC_SetMjpegParam(u32Ch, &stMjpegParam);
726         }
727 
728         if (ctx->bMjpegRcParam && stAttr.stVencAttr.enType == RK_VIDEO_ID_MJPEG) {
729             stRcParam.stParamMjpeg.u32Qfactor = 80;
730             stRcParam.stParamMjpeg.u32MaxQfactor = 90;
731             stRcParam.stParamMjpeg.u32MinQfactor = 50;
732             RK_MPI_VENC_SetRcParam(u32Ch, &stRcParam);
733         }
734 
735         if (ctx->bFrmLost) {
736             VENC_FRAMELOST_S stFrmLost;
737             memset(&stFrmLost, 0, sizeof(stFrmLost));
738             stFrmLost.bFrmLostOpen = RK_TRUE;
739             stFrmLost.u32FrmLostBpsThr = 1;
740             stFrmLost.enFrmLostMode = FRMLOST_NORMAL;
741             stFrmLost.u32EncFrmGaps = 0;
742             RK_MPI_VENC_SetFrameLostStrategy(u32Ch, &stFrmLost);
743         }
744 
745         if (ctx->u32DeBreath > 0) {
746             VENC_DEBREATHEFFECT_S stDeBreathEffect;
747             memset(&stDeBreathEffect, 0, sizeof(stDeBreathEffect));
748             stDeBreathEffect.bEnable = RK_TRUE;
749             stDeBreathEffect.s32Strength1 = ctx->u32DeBreath;
750             RK_MPI_VENC_SetDeBreathEffect(u32Ch, &stDeBreathEffect);
751         }
752         if (ctx->bRefParam) {
753             VENC_REF_PARAM_S stRefParam;
754             memset(&stRefParam, 0, sizeof(stRefParam));
755             stRefParam.u32Base = 3;
756             stRefParam.u32Enhance = 2;
757             stRefParam.bEnablePred = RK_TRUE;
758             RK_MPI_VENC_SetRefParam(u32Ch, &stRefParam);
759         }
760         if (ctx->bSliceSplit) {
761             VENC_SLICE_SPLIT_S stSliceSplit;
762             RK_MPI_VENC_GetSliceSplit(u32Ch, &stSliceSplit);
763             stSliceSplit.bSplitEnable = RK_TRUE;
764             stSliceSplit.u32SplitMode = 1;
765             stSliceSplit.u32SplitSize = 16;
766             RK_MPI_VENC_SetSliceSplit(u32Ch, &stSliceSplit);
767         }
768 
769         if (ctx->bForceIdr)
770             pthread_create(&forceIdrThread[u32Ch], 0, venc_force_idr, reinterpret_cast<void *>(&stVencCtx[u32Ch]));
771 
772         memcpy(&(stVencCtx[u32Ch]), ctx, sizeof(TEST_VENC_CTX_S));
773         pthread_create(&vencThread[u32Ch], 0, venc_send_frame, reinterpret_cast<void *>(&stVencCtx[u32Ch]));
774         pthread_create(&getStreamThread[u32Ch], 0, venc_get_stream, reinterpret_cast<void *>(&stVencCtx[u32Ch]));
775     }
776 
777 __FAILED:
778     for (u32Ch = 0; u32Ch < ctx->u32ChNum; u32Ch++) {
779         if (vencThread[u32Ch])
780             pthread_join(vencThread[u32Ch], RK_NULL);
781         if (getStreamThread[u32Ch])
782             pthread_join(getStreamThread[u32Ch], RK_NULL);
783 
784         stVencCtx[u32Ch].threadExit = RK_TRUE;
785         if (ctx->bForceIdr)
786             pthread_join(forceIdrThread[u32Ch], RK_NULL);
787         RK_MPI_VENC_StopRecvFrame(u32Ch);
788         if (ctx->bAttachPool) {
789             s32Ret = RK_MPI_VENC_DetachMbPool(u32Ch);
790             if (s32Ret != RK_SUCCESS) {
791                 RK_LOGE("ch:%d RK_MPI_VENC_DetachMbPool fail:0x%x!", u32Ch, s32Ret);
792             }
793         }
794 
795         RK_MPI_VENC_DestroyChn(u32Ch);
796         if (ctx->bAttachPool)
797             RK_MPI_MB_DestroyPool(ctx->vencPoolOutput[u32Ch]);
798     }
799     RK_MPI_MB_DestroyPool(ctx->vencPoolInput);
800 
801     return RK_SUCCESS;
802 }
803 
804 static const char *const usages[] = {
805     "./rk_mpi_venc_test [-i SRC_PATH] [-w SRC_WIDTH] [-h SRC_HEIGHT]",
806     NULL,
807 };
808 
mpi_venc_test_show_options(const TEST_VENC_CTX_S * ctx)809 static void mpi_venc_test_show_options(const TEST_VENC_CTX_S *ctx) {
810     RK_PRINT("cmd parse result:\n");
811     RK_PRINT("input  file name       : %s\n", ctx->srcFileUri);
812     RK_PRINT("output file name       : %s\n", ctx->dstFilePath);
813     RK_PRINT("src width              : %d\n", ctx->u32SrcWidth);
814     RK_PRINT("src height             : %d\n", ctx->u32SrcHeight);
815     RK_PRINT("src virWidth           : %d\n", ctx->u32srcVirWidth);
816     RK_PRINT("src virHeight          : %d\n", ctx->u32srcVirHeight);
817     RK_PRINT("src pixel format       : %d\n", ctx->u32SrcPixFormat);
818     RK_PRINT("encode codec type      : %d\n", ctx->u32DstCodec);
819     RK_PRINT("loop count             : %d\n", ctx->s32LoopCount);
820     RK_PRINT("channel index          : %d\n", ctx->u32ChnIndex);
821     RK_PRINT("channel num            : %d\n", ctx->u32ChNum);
822     RK_PRINT("output buffer count    : %d\n", ctx->u32StreamBufCnt);
823     RK_PRINT("one picture size       : %d\n", ctx->u32BufferSize);
824     RK_PRINT("out stream size        : %d\n", ctx->u32StreamSize);
825     RK_PRINT("gop mode               : %d\n", ctx->enGopMode);
826     RK_PRINT("snap picture count     : %d\n", ctx->s32SnapPicCount);
827     RK_PRINT("insert user data       : %d\n", ctx->bInsertUserData);
828     RK_PRINT("rotation               : %d\n", ctx->enRotation);
829     RK_PRINT("compress mode          : %d\n", ctx->enCompressMode);
830     RK_PRINT("rc mode                : %d\n", ctx->enRcMode);
831     RK_PRINT("bitrate                : %d\n", ctx->u32BitRateKb);
832     RK_PRINT("bitrate max            : %d\n", ctx->u32BitRateKbMax);
833     RK_PRINT("bitrate mix            : %d\n", ctx->u32BitRateKbMin);
834     RK_PRINT("gop size               : %d\n", ctx->u32GopSize);
835     RK_PRINT("roi count              : %d\n", ctx->u32RoiTestCount);
836     RK_PRINT("mirror                 : %d\n", ctx->enMirror);
837     RK_PRINT("fixqp                  : %d\n", ctx->u32FixQp);
838     RK_PRINT("full range             : %d\n", ctx->bFullRange);
839     RK_PRINT("enable attach mb pool  : %d\n", ctx->bAttachPool);
840     RK_PRINT("performance test       : %d\n", ctx->bPerformance);
841     RK_PRINT("rc stat time           : %d\n", ctx->u32StatTime);
842     RK_PRINT("slice split            : %d\n", ctx->bSliceSplit);
843 
844     return;
845 }
846 
main(int argc,const char ** argv)847 int main(int argc, const char **argv) {
848     RK_S32 s32Ret = RK_SUCCESS;
849     TEST_VENC_CTX_S ctx;
850     memset(&ctx, 0, sizeof(TEST_VENC_CTX_S));
851 
852     ctx.s32LoopCount    = 1;
853     ctx.u32StreamBufCnt = 8;
854     ctx.u32ChNum        = 1;
855     ctx.u32SrcPixFormat = RK_FMT_YUV420SP;
856     ctx.u32DstCodec     = RK_VIDEO_ID_AVC;
857     ctx.enCropType      = VENC_CROP_NONE;
858     ctx.bFrameRate      = RK_FALSE;
859     ctx.s32SnapPicCount = -1;
860     ctx.u32GopSize      = 60;
861     ctx.enRcMode        = VENC_RC_MODE_H264CBR;
862     ctx.u32BitRateKb    = 10 * 1024;
863     ctx.bFullRange      = RK_TRUE;
864     ctx.s32FrameRateIn  = 25;
865     ctx.s32FrameRateOut = 10;
866     ctx.u32StatTime = 3;
867 
868     struct argparse_option options[] = {
869         OPT_HELP(),
870         OPT_GROUP("basic options:"),
871         OPT_STRING('i', "input",  &(ctx.srcFileUri),
872                    "input file name.", NULL, 0, 0),
873         OPT_STRING('o', "output", &(ctx.dstFilePath),
874                    "the directory of encoder output", NULL, 0, 0),
875         OPT_INTEGER('n', "loop_count", &(ctx.s32LoopCount),
876                     "loop running count. default(1)", NULL, 0, 0),
877         OPT_INTEGER('w', "width", &(ctx.u32SrcWidth),
878                     "input source width. <required>", NULL, 0, 0),
879         OPT_INTEGER('h', "height", &(ctx.u32SrcHeight),
880                     "input source height. <required>", NULL, 0, 0),
881         OPT_INTEGER('\0', "vir_width", &(ctx.u32srcVirWidth),
882                     "input source virWidth.", NULL, 0, 0),
883         OPT_INTEGER('\0', "vir_height", &(ctx.u32srcVirHeight),
884                     "input source virHeight.", NULL, 0, 0),
885         OPT_INTEGER('f', "pixel_format", &(ctx.u32SrcPixFormat),
886                     "input source pixel format. default(0: NV12).", NULL, 0, 0),
887         OPT_INTEGER('C', "codec", &(ctx.u32DstCodec),
888                      "venc encode codec(8:h264, 9:mjpeg, 12:h265, 15:jpeg, ...). default(8)", NULL, 0, 0),
889         OPT_INTEGER('c', "channel_count", &(ctx.u32ChNum),
890                      "venc channel count. default(1).", NULL, 0, 0),
891         OPT_INTEGER('\0', "channel_index", &(ctx.u32ChnIndex),
892                      "venc channel index. default(0).", NULL, 0, 0),
893         OPT_INTEGER('\0', "enc_buf_cnt", &(ctx.u32StreamBufCnt),
894                      "venc encode output buffer count, default(8)", NULL, 0, 0),
895         OPT_INTEGER('\0', "src_pic_size", &(ctx.u32BufferSize),
896                      "the size of input single picture", NULL, 0, 0),
897         OPT_INTEGER('\0', "out_stream_size", &(ctx.u32StreamSize),
898                      "the size of out stream buff alloc, default(equal to u32BufferSize)", NULL, 0, 0),
899         OPT_INTEGER('\0', "crop", &(ctx.enCropType),
900                      "crop type(0:none 1:crop_only 2:crop_scale) default(0)", NULL, 0, 0),
901         OPT_INTEGER('\0', "framerate", &(ctx.bFrameRate),
902                      "framerate enable flag(0:disable 1:enable) default(0)", NULL, 0, 0),
903         OPT_INTEGER('\0', "framerate_in", &(ctx.s32FrameRateIn),
904                       "framerate in(when framerate=1 valid) default(25)", NULL, 0, 0),
905         OPT_INTEGER('\0', "framerate_out", &(ctx.s32FrameRateOut),
906                       "framerate out(when framerate=1 valid) default(10)", NULL, 0, 0),
907         OPT_INTEGER('g', "gop_mode", &(ctx.enGopMode),
908                     "gop mode(0/1:NORMALP 2:TSVC2 3:TSVC3 4:TSVC4 5:SMARTP) default(0)", NULL, 0, 0),
909         OPT_INTEGER('s', "snap_pic_cnt", &(ctx.s32SnapPicCount),
910                     "snap picture count(effective range[-1,0)(0, 2147483647)"
911                     "-1:not limit else:snap count) default(-1)", NULL, 0, 0),
912         OPT_INTEGER('\0', "insert_user_data", &(ctx.bInsertUserData),
913                     "insert user data flag(0:disable 1:enable) default(0)", NULL, 0, 0),
914         OPT_INTEGER('\0', "rotation", &(ctx.enRotation),
915                      "rotation output(0:0 1:90 2:180 3:270) default(0)", NULL, 0, 0),
916         OPT_INTEGER('\0', "compress_mode", &(ctx.enCompressMode),
917                     "set input compressmode(default 0; 0:MODE_NONE 1:AFBC_16x16)", NULL, 0, 0),
918         OPT_INTEGER('\0', "rc_mode", &(ctx.enRcMode),
919                     "rc mode(0:NULL 1:H264CBR 2:H264VBR 3:H264AVBR 4:H264FIXQP"
920                     "5:MJPEGCBR 6:MJPEGVBR 7:MJPEGFIXQP"
921                     "8:H265CBR 9:H265VBR 10:H265AVBR 11:H265FIXQP default(1)",
922                     NULL, 0, 0),
923         OPT_INTEGER('b', "bit_rate", &(ctx.u32BitRateKb),
924                     "bit rate kbps(h264/h265:range[3-200000],jpeg/mjpeg:range[5-800000] default(10*1024kb))",
925                     NULL, 0, 0),
926         OPT_INTEGER('\0', "bit_rate_max", &(ctx.u32BitRateKbMax),
927                     "bit rate kbps max(vbr/avbr valid)(h264/h265:range[3-200000];"
928                     "jpeg/mjpeg:range[5-800000] default(0:auto calcu))",
929                      NULL, 0, 0),
930         OPT_INTEGER('\0', "bit_rate_min", &(ctx.u32BitRateKbMin),
931                     "bit rate kbps min(vbr/avbr valid)(h264/h265:range[3-200000];"
932                     "jpeg/mjpeg:range[5-800000] default(0:auto calcu))",
933                      NULL, 0, 0),
934         OPT_INTEGER('\0', "gop_size", &(ctx.u32GopSize),
935                     "gop size(range >= 1 default(60))", NULL, 0, 0),
936         OPT_INTEGER('\0', "mirror", &(ctx.enMirror),
937                     "enMirror output(0:none 1:horizontal 2:vertical) default(0)", NULL, 0, 0),
938         OPT_INTEGER('\0', "super_frm", &(ctx.bSuperFrm),
939                     "super frm enable(0:disable 1:enable) default(0)", NULL, 0, 0),
940         OPT_INTEGER('\0', "frm_lost", &(ctx.bFrmLost),
941                     "frm lost enable(0:disable 1:enable) default(0)", NULL, 0, 0),
942         OPT_INTEGER('\0', "intra_refresh", &(ctx.bIntraRefresh),
943                     "intra refresh enable(0:disable 1:enable) default(0)", NULL, 0, 0),
944         OPT_INTEGER('\0', "hier_qp", &(ctx.bHierarchicalQp),
945                     "hierarchical qp enable(0:disable 1:enable) default(0)", NULL, 0, 0),
946         OPT_INTEGER('\0', "mjpeg_param", &(ctx.bMjpegParam),
947                     "mjpeg param enable(0:disable 1:enable) default(0)", NULL, 0, 0),
948         OPT_INTEGER('\0', "mjpeg_rc_param", &(ctx.bMjpegRcParam),
949                     "mjpeg rc param test enable(0:disable 1:enable) default(0)", NULL, 0, 0),
950         OPT_INTEGER('\0', "force_idr", &(ctx.bForceIdr),
951                     "force idr enable(0:disable 1:enable) default(0)", NULL, 0, 0),
952         OPT_INTEGER('\0', "roi_count", &(ctx.u32RoiTestCount),
953                     "roi test count(range[0-8] default(0))", NULL, 0, 0),
954         OPT_INTEGER('\0', "fix_qp", &(ctx.u32FixQp),
955                     "set fix qp(this value valid when rc_mode is fixqp;default(0))", NULL, 0, 0),
956         OPT_INTEGER('\0', "full_range", &(ctx.bFullRange),
957                     "set clolor range(0:limit color range 1:full color range) default(1)", NULL, 0, 0),
958         OPT_INTEGER('\0', "send_frame_ex", &(ctx.bSendFrameEx),
959                     "send frame ex enable(0:disable 1:enable) default(0)", NULL, 0, 0),
960         OPT_INTEGER('\0', "qpmap", &(ctx.bQpmap),
961                     "qpmap enable(0:disable 1:enable) default(0)", NULL, 0, 0),
962         OPT_INTEGER('\0', "attach_mb_pool", &(ctx.bAttachPool),
963                     "enable attach mb pool or not, default(0), 0: RK_FALSE, 1: RK_TRUE", NULL, 0, 0),
964         OPT_INTEGER('\0', "de_breath", &(ctx.u32DeBreath),
965                     "debreath[0, 35] default(0)", NULL, 0, 0),
966         OPT_INTEGER('\0', "ref_param", &(ctx.bRefParam),
967                     "ref param test(0:disable 1:enable) default(0)", NULL, 0, 0),
968         OPT_INTEGER('\0', "performance", &(ctx.bPerformance),
969                     "performance test(0:disable 1:enable) default(0)", NULL, 0, 0),
970         OPT_INTEGER('\0', "stat_time", &(ctx.u32StatTime),
971                     "rc statistic time(range[1,60]) default(3)", NULL, 0, 0),
972         OPT_INTEGER('\0', "slice_split", &(ctx.bSliceSplit),
973                     "slice split test(0:disable 1:enable) default(0)", NULL, 0, 0),
974 
975         OPT_END(),
976     };
977 
978     struct argparse argparse;
979     argparse_init(&argparse, options, usages, 0);
980     argparse_describe(&argparse, "\nselect a test case to run.",
981                                  "\nuse --help for details.");
982 
983     argc = argparse_parse(&argparse, argc, argv);
984     mpi_venc_test_show_options(&ctx);
985 
986     if (check_options(&ctx)) {
987         argparse_usage(&argparse);
988         return RK_FAILURE;
989     }
990 
991     s32Ret = RK_MPI_SYS_Init();
992     if (s32Ret != RK_SUCCESS) {
993         return s32Ret;
994     }
995 
996     if (unit_test_mpi_venc(&ctx) < 0) {
997         goto __FAILED;
998     }
999     s32Ret = RK_MPI_SYS_Exit();
1000     if (s32Ret != RK_SUCCESS) {
1001         return s32Ret;
1002     }
1003     RK_LOGE("test running success!");
1004     return RK_SUCCESS;
1005 __FAILED:
1006     RK_MPI_SYS_Exit();
1007     RK_LOGE("test running failed!");
1008     return s32Ret;
1009 }
1010