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