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