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