1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4 */
5
6 #if defined(_WIN32)
7 #include "vld.h"
8 #endif
9
10 #define MODULE_TAG "mpi_enc_test"
11
12 #include <string.h>
13 #include <math.h>
14 #include "rk_mpi.h"
15 #include "rk_venc_kcfg.h"
16
17 #include "mpp_env.h"
18 #include "mpp_mem.h"
19 #include "mpp_time.h"
20 #include "mpp_debug.h"
21 #include "mpp_common.h"
22 #include "mpp_soc.h"
23
24 #include "utils.h"
25 #include "mpi_enc_utils.h"
26 #include "camera_source.h"
27 #include "mpp_enc_roi_utils.h"
28 #include "mpp_rc_api.h"
29 #include "osd3_test.h"
30 #include "kmpp_obj.h"
31
32 static RK_S32 qbias_arr_hevc[18] = {
33 3, 6, 13, 171, 171, 171, 171,
34 3, 6, 13, 171, 171, 220, 171, 85, 85, 85, 85
35 };
36
37 static RK_S32 qbias_arr_avc[18] = {
38 3, 6, 13, 683, 683, 683, 683,
39 3, 6, 13, 683, 683, 683, 683, 341, 341, 341, 341
40 };
41
42 static RK_S32 aq_rnge_arr[10] = {
43 5, 5, 10, 12, 12,
44 5, 5, 10, 12, 12
45 };
46
47 static RK_S32 aq_thd_smart[16] = {
48 1, 3, 3, 3, 3, 3, 5, 5,
49 8, 8, 8, 15, 15, 20, 25, 28
50 };
51
52 static RK_S32 aq_step_smart[16] = {
53 -8, -7, -6, -5, -4, -3, -2, -1,
54 0, 1, 2, 3, 4, 6, 8, 10
55 };
56
57 typedef struct {
58 // base flow context
59 MppCtx ctx;
60 MppApi *mpi;
61 RK_S32 chn;
62
63 // global flow control flag
64 RK_U32 frm_eos;
65 RK_U32 pkt_eos;
66 RK_U32 frm_pkt_cnt;
67 RK_S32 frame_num;
68 RK_S32 frame_count;
69 RK_S32 frm_step;
70
71 RK_U64 stream_size;
72 /* end of encoding flag when set quit the loop */
73 volatile RK_U32 loop_end;
74
75 // src and dst
76 FILE *fp_input;
77 FILE *fp_output;
78 FILE *fp_verify;
79
80 /* encoder config set */
81 MppEncCfg cfg;
82 MppEncPrepCfg prep_cfg;
83 MppEncRcCfg rc_cfg;
84 MppEncSliceSplit split_cfg;
85 MppEncOSDPltCfg osd_plt_cfg;
86 MppEncOSDPlt osd_plt;
87 MppEncOSDData osd_data;
88 RoiRegionCfg roi_region;
89 MppEncROICfg roi_cfg;
90 MppJpegROICfg roi_jpeg_cfg;
91
92 // input / output
93 MppBufferGroup buf_grp;
94 MppBuffer frm_buf;
95 MppBuffer pkt_buf;
96 MppBuffer md_info;
97 MppEncSeiMode sei_mode;
98 MppEncHeaderMode header_mode;
99
100 // paramter for resource malloc
101 RK_U32 width;
102 RK_U32 height;
103 RK_U32 hor_stride;
104 RK_U32 ver_stride;
105 MppFrameFormat fmt;
106 MppCodingType type;
107 RK_S32 loop_times;
108 CamSource *cam_ctx;
109 MppEncRoiCtx roi_ctx;
110
111 MppVencKcfg init_kcfg;
112
113 // resources
114 size_t header_size;
115 size_t frame_size;
116 size_t mdinfo_size;
117 /* NOTE: packet buffer may overflow */
118 size_t packet_size;
119
120 RK_U32 osd_enable;
121 RK_U32 osd_mode;
122 RK_U32 split_mode;
123 RK_U32 split_arg;
124 RK_U32 split_out;
125
126 RK_U32 user_data_enable;
127 RK_U32 roi_enable;
128 RK_U32 roi_jpeg_enable;
129
130 // rate control runtime parameter
131 RK_S32 fps_in_flex;
132 RK_S32 fps_in_den;
133 RK_S32 fps_in_num;
134 RK_S32 fps_out_flex;
135 RK_S32 fps_out_den;
136 RK_S32 fps_out_num;
137 RK_S32 bps;
138 RK_S32 bps_max;
139 RK_S32 bps_min;
140 RK_S32 rc_mode;
141 RK_S32 gop_mode;
142 RK_S32 gop_len;
143 RK_S32 vi_len;
144 RK_S32 scene_mode;
145 RK_S32 deblur_en;
146
147 RK_S32 cu_qp_delta_depth;
148 RK_S32 anti_flicker_str;
149 RK_S32 atr_str_i;
150 RK_S32 atr_str_p;
151 RK_S32 atl_str;
152 RK_S32 sao_str_i;
153 RK_S32 sao_str_p;
154 RK_S64 first_frm;
155 RK_S64 first_pkt;
156
157 MppEncOSDData3 osd_data3;
158 KmppBuffer osd_buffer;
159 RK_U8 *osd_pattern;
160 RK_U32 jpeg_osd_case;
161 } MpiEncTestData;
162
163 /* For each instance thread return value */
164 typedef struct {
165 float frame_rate;
166 RK_U64 bit_rate;
167 RK_S64 elapsed_time;
168 RK_S32 frame_count;
169 RK_S64 stream_size;
170 RK_S64 delay;
171 } MpiEncMultiCtxRet;
172
173 typedef struct {
174 MpiEncTestArgs *cmd; // pointer to global command line info
175 const char *name;
176 RK_S32 chn;
177
178 pthread_t thd; // thread for for each instance
179 MpiEncTestData ctx; // context of encoder
180 MpiEncMultiCtxRet ret; // return of encoder
181 } MpiEncMultiCtxInfo;
182
183 static RK_S32 aq_thd[16] = {
184 0, 0, 0, 0,
185 3, 3, 5, 5,
186 8, 8, 8, 15,
187 15, 20, 25, 25
188 };
189
190 static RK_S32 aq_step_i_ipc[16] = {
191 -8, -7, -6, -5,
192 -4, -3, -2, -1,
193 0, 1, 2, 3,
194 5, 7, 7, 8,
195 };
196
197 static RK_S32 aq_step_p_ipc[16] = {
198 -8, -7, -6, -5,
199 -4, -2, -1, -1,
200 0, 2, 3, 4,
201 6, 8, 9, 10,
202 };
203
get_mdinfo_size(MpiEncTestData * p,MppCodingType type)204 static RK_S32 get_mdinfo_size(MpiEncTestData *p, MppCodingType type)
205 {
206 RockchipSocType soc_type = mpp_get_soc_type();
207 RK_S32 md_size;
208 RK_U32 w = p->hor_stride, h = p->ver_stride;
209
210 if (soc_type == ROCKCHIP_SOC_RV1126B) {
211 md_size = (MPP_VIDEO_CodingHEVC == type) ?
212 (MPP_ALIGN(w, 32) >> 5) * (MPP_ALIGN(h, 32) >> 5) * 20 :
213 (MPP_ALIGN(w, 64) >> 6) * (MPP_ALIGN(h, 16) >> 4) * 16;
214 } else if (soc_type == ROCKCHIP_SOC_RK3588) {
215 md_size = (MPP_ALIGN(w, 64) >> 6) * (MPP_ALIGN(h, 64) >> 6) * 32;
216 } else {
217 md_size = (MPP_VIDEO_CodingHEVC == type) ?
218 (MPP_ALIGN(w, 32) >> 5) * (MPP_ALIGN(h, 32) >> 5) * 16 :
219 (MPP_ALIGN(w, 64) >> 6) * (MPP_ALIGN(h, 16) >> 4) * 16;
220 }
221
222 return md_size;
223 }
224
kmpp_cfg_init(MpiEncMultiCtxInfo * info)225 static MPP_RET kmpp_cfg_init(MpiEncMultiCtxInfo *info)
226 {
227 MppVencKcfg init_kcfg = NULL;
228 MpiEncTestData *p = &info->ctx;
229 MPP_RET ret = MPP_NOK;
230
231 mpp_venc_kcfg_init(&init_kcfg, MPP_VENC_KCFG_TYPE_INIT);
232 if (!init_kcfg) {
233 mpp_err_f("kmpp_venc_init_cfg_init failed\n");
234 return ret;
235 }
236
237 p->init_kcfg = init_kcfg;
238
239 mpp_venc_kcfg_set_u32(init_kcfg, "type", MPP_CTX_ENC);
240 mpp_venc_kcfg_set_u32(init_kcfg, "coding", p->type);
241 mpp_venc_kcfg_set_s32(init_kcfg, "chan_id", 0);
242 mpp_venc_kcfg_set_s32(init_kcfg, "online", 0);
243 mpp_venc_kcfg_set_u32(init_kcfg, "buf_size", 0);
244 mpp_venc_kcfg_set_u32(init_kcfg, "max_strm_cnt", 0);
245 mpp_venc_kcfg_set_u32(init_kcfg, "shared_buf_en", 0);
246 mpp_venc_kcfg_set_u32(init_kcfg, "smart_en", p->rc_mode == MPP_ENC_RC_MODE_SMTRC);
247 mpp_venc_kcfg_set_u32(init_kcfg, "max_width", p->width);
248 mpp_venc_kcfg_set_u32(init_kcfg, "max_height", p->height);
249 mpp_venc_kcfg_set_u32(init_kcfg, "max_lt_cnt", 0);
250 mpp_venc_kcfg_set_u32(init_kcfg, "qpmap_en", p->deblur_en);
251 mpp_venc_kcfg_set_u32(init_kcfg, "chan_dup", 0);
252 mpp_venc_kcfg_set_u32(init_kcfg, "tmvp_enable", 0);
253 mpp_venc_kcfg_set_u32(init_kcfg, "only_smartp", 0);
254 /* set notify mode to zero to disable rockit ko call back */
255 mpp_venc_kcfg_set_u32(init_kcfg, "ntfy_mode", 0);
256 /* set input timeout to block mode to insure put_frame ioctl return while encoding finished */
257 mpp_venc_kcfg_set_s32(init_kcfg, "input_timeout", MPP_POLL_BLOCK);
258
259 ret = p->mpi->control(p->ctx, MPP_SET_VENC_INIT_KCFG, init_kcfg);
260 if (ret)
261 mpp_err_f("mpi control set kmpp enc cfg failed ret %d\n", ret);
262
263 return ret;
264 }
265
test_ctx_init(MpiEncMultiCtxInfo * info)266 MPP_RET test_ctx_init(MpiEncMultiCtxInfo *info)
267 {
268 MpiEncTestArgs *cmd = info->cmd;
269 MpiEncTestData *p = &info->ctx;
270 MPP_RET ret = MPP_OK;
271
272 // get paramter from cmd
273 p->width = cmd->width;
274 p->height = cmd->height;
275 p->hor_stride = (cmd->hor_stride) ? (cmd->hor_stride) :
276 (MPP_ALIGN(cmd->width, 16));
277 p->ver_stride = (cmd->ver_stride) ? (cmd->ver_stride) :
278 (MPP_ALIGN(cmd->height, 16));
279 p->fmt = cmd->format;
280 p->type = cmd->type;
281 p->bps = cmd->bps_target;
282 p->bps_min = cmd->bps_min;
283 p->bps_max = cmd->bps_max;
284 p->rc_mode = cmd->rc_mode;
285 p->frame_num = cmd->frame_num;
286 if (cmd->type == MPP_VIDEO_CodingMJPEG && p->frame_num == 0) {
287 mpp_log("jpege default encode only one frame. Use -n [num] for rc case\n");
288 p->frame_num = 1;
289 }
290
291 p->frm_step = cmd->frm_step;
292 p->gop_mode = cmd->gop_mode;
293 p->gop_len = cmd->gop_len;
294 p->vi_len = cmd->vi_len;
295 p->fps_in_flex = cmd->fps_in_flex;
296 p->fps_in_den = cmd->fps_in_den;
297 p->fps_in_num = cmd->fps_in_num;
298 p->fps_out_flex = cmd->fps_out_flex;
299 p->fps_out_den = cmd->fps_out_den;
300 p->fps_out_num = cmd->fps_out_num;
301 p->scene_mode = cmd->scene_mode;
302 p->deblur_en = cmd->deblur_en;
303 p->cu_qp_delta_depth = cmd->cu_qp_delta_depth;
304 p->anti_flicker_str = cmd->anti_flicker_str;
305 p->atr_str_i = cmd->atr_str_i;
306 p->atr_str_p = cmd->atr_str_p;
307 p->atl_str = cmd->atl_str;
308 p->sao_str_i = cmd->sao_str_i;
309 p->sao_str_p = cmd->sao_str_p;
310 p->mdinfo_size = get_mdinfo_size(p, cmd->type);
311
312 if (cmd->file_input) {
313 if (!strncmp(cmd->file_input, "/dev/video", 10)) {
314 mpp_log("open camera device");
315 p->cam_ctx = camera_source_init(cmd->file_input, 4, p->width, p->height, p->fmt);
316 mpp_log("new framecap ok");
317 if (p->cam_ctx == NULL)
318 mpp_err("open %s fail", cmd->file_input);
319 } else {
320 p->fp_input = fopen(cmd->file_input, "rb");
321 if (NULL == p->fp_input) {
322 mpp_err("failed to open input file %s\n", cmd->file_input);
323 mpp_err("create default yuv image for test\n");
324 }
325 }
326 }
327
328 if (cmd->file_output) {
329 p->fp_output = fopen(cmd->file_output, "w+b");
330 if (NULL == p->fp_output) {
331 mpp_err("failed to open output file %s\n", cmd->file_output);
332 ret = MPP_ERR_OPEN_FILE;
333 }
334 }
335
336 if (cmd->file_slt) {
337 p->fp_verify = fopen(cmd->file_slt, "wt");
338 if (!p->fp_verify)
339 mpp_err("failed to open verify file %s\n", cmd->file_slt);
340 }
341
342 // update resource parameter
343 switch (p->fmt & MPP_FRAME_FMT_MASK) {
344 case MPP_FMT_YUV420SP:
345 case MPP_FMT_YUV420P: {
346 p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 3 / 2;
347 } break;
348
349 case MPP_FMT_YUV422_YUYV :
350 case MPP_FMT_YUV422_YVYU :
351 case MPP_FMT_YUV422_UYVY :
352 case MPP_FMT_YUV422_VYUY :
353 case MPP_FMT_YUV422P :
354 case MPP_FMT_YUV422SP : {
355 p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 2;
356 } break;
357 case MPP_FMT_YUV400:
358 case MPP_FMT_RGB444 :
359 case MPP_FMT_BGR444 :
360 case MPP_FMT_RGB555 :
361 case MPP_FMT_BGR555 :
362 case MPP_FMT_RGB565 :
363 case MPP_FMT_BGR565 :
364 case MPP_FMT_RGB888 :
365 case MPP_FMT_BGR888 :
366 case MPP_FMT_RGB101010 :
367 case MPP_FMT_BGR101010 :
368 case MPP_FMT_ARGB8888 :
369 case MPP_FMT_ABGR8888 :
370 case MPP_FMT_BGRA8888 :
371 case MPP_FMT_RGBA8888 : {
372 p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64);
373 } break;
374
375 default: {
376 p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4;
377 } break;
378 }
379
380 if (MPP_FRAME_FMT_IS_FBC(p->fmt)) {
381 if ((p->fmt & MPP_FRAME_FBC_MASK) == MPP_FRAME_FBC_AFBC_V1)
382 p->header_size = MPP_ALIGN(MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16, SZ_4K);
383 else
384 p->header_size = MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16;
385 } else {
386 p->header_size = 0;
387 }
388
389 return ret;
390 }
391
test_ctx_deinit(MpiEncTestData * p)392 MPP_RET test_ctx_deinit(MpiEncTestData *p)
393 {
394 if (p) {
395 if (p->cam_ctx) {
396 camera_source_deinit(p->cam_ctx);
397 p->cam_ctx = NULL;
398 }
399 if (p->fp_input) {
400 fclose(p->fp_input);
401 p->fp_input = NULL;
402 }
403 if (p->fp_output) {
404 fclose(p->fp_output);
405 p->fp_output = NULL;
406 }
407 if (p->fp_verify) {
408 fclose(p->fp_verify);
409 p->fp_verify = NULL;
410 }
411 }
412 return MPP_OK;
413 }
414
test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo * info)415 MPP_RET test_mpp_enc_cfg_setup(MpiEncMultiCtxInfo *info)
416 {
417 MpiEncTestArgs *cmd = info->cmd;
418 MpiEncTestData *p = &info->ctx;
419 MppApi *mpi = p->mpi;
420 MppCtx ctx = p->ctx;
421 MppEncCfg cfg = p->cfg;
422 RK_U32 quiet = cmd->quiet;
423 MPP_RET ret;
424 RK_U32 rotation;
425 RK_U32 mirroring;
426 RK_U32 flip;
427 RK_U32 gop_mode = p->gop_mode;
428 MppEncRefCfg ref = NULL;
429
430 /* setup default parameter */
431 if (p->fps_in_den == 0)
432 p->fps_in_den = 1;
433 if (p->fps_in_num == 0)
434 p->fps_in_num = 30;
435 if (p->fps_out_den == 0)
436 p->fps_out_den = 1;
437 if (p->fps_out_num == 0)
438 p->fps_out_num = 30;
439
440 if (!p->bps)
441 p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
442
443 mpp_enc_cfg_set_s32(cfg, "codec:type", p->type);
444
445 /* setup preprocess parameters */
446 mpp_enc_cfg_set_s32(cfg, "prep:width", p->width);
447 mpp_enc_cfg_set_s32(cfg, "prep:height", p->height);
448 mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", p->hor_stride);
449 mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", p->ver_stride);
450 mpp_enc_cfg_set_s32(cfg, "prep:format", p->fmt);
451 mpp_enc_cfg_set_s32(cfg, "prep:range", MPP_FRAME_RANGE_JPEG);
452
453 mpp_env_get_u32("mirroring", &mirroring, 0);
454 mpp_env_get_u32("rotation", &rotation, 0);
455 mpp_env_get_u32("flip", &flip, 0);
456
457 mpp_enc_cfg_set_s32(cfg, "prep:mirroring", mirroring);
458 mpp_enc_cfg_set_s32(cfg, "prep:rotation", rotation);
459 mpp_enc_cfg_set_s32(cfg, "prep:flip", flip);
460
461 /* setup rate control parameters */
462 mpp_enc_cfg_set_s32(cfg, "rc:mode", p->rc_mode);
463 mpp_enc_cfg_set_u32(cfg, "rc:max_reenc_times", 0);
464 mpp_enc_cfg_set_u32(cfg, "rc:super_mode", 0);
465
466 /* fix input / output frame rate */
467 mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", p->fps_in_flex);
468 mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", p->fps_in_num);
469 mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denom", p->fps_in_den);
470 mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", p->fps_out_flex);
471 mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num", p->fps_out_num);
472 mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denom", p->fps_out_den);
473
474 /* drop frame or not when bitrate overflow */
475 mpp_enc_cfg_set_u32(cfg, "rc:drop_mode", MPP_ENC_RC_DROP_FRM_DISABLED);
476 mpp_enc_cfg_set_u32(cfg, "rc:drop_thd", 20); /* 20% of max bps */
477 mpp_enc_cfg_set_u32(cfg, "rc:drop_gap", 1); /* Do not continuous drop frame */
478
479 /* setup bitrate for different rc_mode */
480 mpp_enc_cfg_set_s32(cfg, "rc:bps_target", p->bps);
481 switch (p->rc_mode) {
482 case MPP_ENC_RC_MODE_FIXQP : {
483 /* do not setup bitrate on FIXQP mode */
484 } break;
485 case MPP_ENC_RC_MODE_CBR : {
486 /* CBR mode has narrow bound */
487 mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
488 mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
489 } break;
490 case MPP_ENC_RC_MODE_VBR :
491 case MPP_ENC_RC_MODE_AVBR : {
492 /* VBR mode has wide bound */
493 mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
494 mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 1 / 16);
495 } break;
496 default : {
497 /* default use CBR mode */
498 mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
499 mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
500 } break;
501 }
502
503 /* setup qp for different codec and rc_mode */
504 switch (p->type) {
505 case MPP_VIDEO_CodingAVC :
506 case MPP_VIDEO_CodingHEVC : {
507 switch (p->rc_mode) {
508 case MPP_ENC_RC_MODE_FIXQP : {
509 RK_S32 fix_qp = cmd->qp_init;
510
511 mpp_enc_cfg_set_s32(cfg, "rc:qp_init", fix_qp);
512 mpp_enc_cfg_set_s32(cfg, "rc:qp_max", fix_qp);
513 mpp_enc_cfg_set_s32(cfg, "rc:qp_min", fix_qp);
514 mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", fix_qp);
515 mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", fix_qp);
516 mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 0);
517 mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_i", fix_qp);
518 mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_i", fix_qp);
519 mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_p", fix_qp);
520 mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_p", fix_qp);
521 } break;
522 case MPP_ENC_RC_MODE_CBR :
523 case MPP_ENC_RC_MODE_VBR :
524 case MPP_ENC_RC_MODE_AVBR :
525 case MPP_ENC_RC_MODE_SMTRC : {
526 mpp_enc_cfg_set_s32(cfg, "rc:qp_init", cmd->qp_init ? cmd->qp_init : -1);
527 mpp_enc_cfg_set_s32(cfg, "rc:qp_max", cmd->qp_max ? cmd->qp_max : 51);
528 mpp_enc_cfg_set_s32(cfg, "rc:qp_min", cmd->qp_min ? cmd->qp_min : 10);
529 mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", cmd->qp_max_i ? cmd->qp_max_i : 51);
530 mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", cmd->qp_min_i ? cmd->qp_min_i : 10);
531 mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 2);
532 mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_i", cmd->fqp_min_i ? cmd->fqp_min_i : 10);
533 mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_i", cmd->fqp_max_i ? cmd->fqp_max_i : 45);
534 mpp_enc_cfg_set_s32(cfg, "rc:fqp_min_p", cmd->fqp_min_p ? cmd->fqp_min_p : 10);
535 mpp_enc_cfg_set_s32(cfg, "rc:fqp_max_p", cmd->fqp_max_p ? cmd->fqp_max_p : 45);
536 } break;
537 default : {
538 mpp_err_f("unsupport encoder rc mode %d\n", p->rc_mode);
539 } break;
540 }
541 } break;
542 case MPP_VIDEO_CodingVP8 : {
543 /* vp8 only setup base qp range */
544 mpp_enc_cfg_set_s32(cfg, "rc:qp_init", cmd->qp_init ? cmd->qp_init : 40);
545 mpp_enc_cfg_set_s32(cfg, "rc:qp_max", cmd->qp_max ? cmd->qp_max : 127);
546 mpp_enc_cfg_set_s32(cfg, "rc:qp_min", cmd->qp_min ? cmd->qp_min : 0);
547 mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", cmd->qp_max_i ? cmd->qp_max_i : 127);
548 mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", cmd->qp_min_i ? cmd->qp_min_i : 0);
549 mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 6);
550 } break;
551 case MPP_VIDEO_CodingMJPEG : {
552 /* jpeg use special codec config to control qtable */
553 mpp_enc_cfg_set_s32(cfg, "jpeg:q_factor", cmd->qp_init ? cmd->qp_init : 80);
554 mpp_enc_cfg_set_s32(cfg, "jpeg:qf_max", cmd->qp_max ? cmd->qp_max : 99);
555 mpp_enc_cfg_set_s32(cfg, "jpeg:qf_min", cmd->qp_min ? cmd->qp_min : 1);
556 } break;
557 default : {
558 } break;
559 }
560
561 /* setup codec */
562 mpp_enc_cfg_set_s32(cfg, "codec:type", p->type);
563 switch (p->type) {
564 case MPP_VIDEO_CodingAVC : {
565 RK_U32 constraint_set;
566
567 /*
568 * H.264 profile_idc parameter
569 * 66 - Baseline profile
570 * 77 - Main profile
571 * 100 - High profile
572 */
573 mpp_enc_cfg_set_s32(cfg, "h264:profile", 100);
574 /*
575 * H.264 level_idc parameter
576 * 10 / 11 / 12 / 13 - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
577 * 20 / 21 / 22 - cif@30fps / half-D1@@25fps / D1@12.5fps
578 * 30 / 31 / 32 - D1@25fps / 720p@30fps / 720p@60fps
579 * 40 / 41 / 42 - 1080p@30fps / 1080p@30fps / 1080p@60fps
580 * 50 / 51 / 52 - 4K@30fps
581 */
582 mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
583 mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
584 mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
585 mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
586
587 mpp_env_get_u32("constraint_set", &constraint_set, 0);
588 if (constraint_set & 0x3f0000)
589 mpp_enc_cfg_set_s32(cfg, "h264:constraint_set", constraint_set);
590 } break;
591 case MPP_VIDEO_CodingHEVC : {
592 mpp_enc_cfg_set_s32(cfg, "h265:diff_cu_qp_delta_depth", p->cu_qp_delta_depth);
593 } break;
594 case MPP_VIDEO_CodingMJPEG :
595 case MPP_VIDEO_CodingVP8 : {
596 } break;
597 default : {
598 mpp_err_f("unsupport encoder coding type %d\n", p->type);
599 } break;
600 }
601
602 p->split_mode = 0;
603 p->split_arg = 0;
604 p->split_out = 0;
605
606 mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE);
607 mpp_env_get_u32("split_arg", &p->split_arg, 0);
608 mpp_env_get_u32("split_out", &p->split_out, 0);
609
610 if (p->split_mode) {
611 mpp_log_q(quiet, "%p split mode %d arg %d out %d\n", ctx,
612 p->split_mode, p->split_arg, p->split_out);
613 mpp_enc_cfg_set_s32(cfg, "split:mode", p->split_mode);
614 mpp_enc_cfg_set_s32(cfg, "split:arg", p->split_arg);
615 mpp_enc_cfg_set_s32(cfg, "split:out", p->split_out);
616 }
617
618 // config gop_len and ref cfg
619 mpp_enc_cfg_set_s32(cfg, "rc:gop", p->gop_len ? p->gop_len : p->fps_out_num * 2);
620
621 mpp_env_get_u32("gop_mode", &gop_mode, gop_mode);
622 if (gop_mode) {
623 mpp_enc_ref_cfg_init(&ref);
624
625 if (p->gop_mode < 4)
626 mpi_enc_gen_ref_cfg(ref, gop_mode);
627 else
628 mpi_enc_gen_smart_gop_ref_cfg(ref, p->gop_len, p->vi_len);
629
630 mpp_enc_cfg_set_ptr(cfg, "rc:ref_cfg", ref);
631 }
632
633 /* setup fine tuning paramters */
634 mpp_enc_cfg_set_s32(cfg, "tune:anti_flicker_str", p->anti_flicker_str);
635 mpp_enc_cfg_set_s32(cfg, "tune:atf_str", cmd->atf_str);
636 mpp_enc_cfg_set_s32(cfg, "tune:atr_str_i", p->atr_str_i);
637 mpp_enc_cfg_set_s32(cfg, "tune:atr_str_p", p->atr_str_p);
638 mpp_enc_cfg_set_s32(cfg, "tune:atl_str", p->atl_str);
639 mpp_enc_cfg_set_s32(cfg, "tune:deblur_en", cmd->deblur_en);
640 mpp_enc_cfg_set_s32(cfg, "tune:deblur_str", cmd->deblur_str);
641 mpp_enc_cfg_set_s32(cfg, "tune:sao_str_i", p->sao_str_i);
642 mpp_enc_cfg_set_s32(cfg, "tune:sao_str_p", p->sao_str_p);
643 mpp_enc_cfg_set_s32(cfg, "tune:lambda_idx_p", cmd->lambda_idx_p);
644 mpp_enc_cfg_set_s32(cfg, "tune:lambda_idx_i", cmd->lambda_idx_i);
645 mpp_enc_cfg_set_s32(cfg, "tune:rc_container", cmd->rc_container);
646 mpp_enc_cfg_set_s32(cfg, "tune:scene_mode", p->scene_mode);
647 mpp_enc_cfg_set_s32(cfg, "tune:speed", cmd->speed);
648 mpp_enc_cfg_set_s32(cfg, "tune:vmaf_opt", 0);
649
650 /* setup hardware specified parameters */
651 if (cmd->rc_mode == MPP_ENC_RC_MODE_SMTRC) {
652 mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_i", aq_thd_smart);
653 mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_p", aq_thd_smart);
654 mpp_enc_cfg_set_st(cfg, "hw:aq_step_i", aq_step_smart);
655 mpp_enc_cfg_set_st(cfg, "hw:aq_step_p", aq_step_smart);
656 } else {
657 mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_i", aq_thd);
658 mpp_enc_cfg_set_st(cfg, "hw:aq_thrd_p", aq_thd);
659 mpp_enc_cfg_set_st(cfg, "hw:aq_step_i", aq_step_i_ipc);
660 mpp_enc_cfg_set_st(cfg, "hw:aq_step_p", aq_step_p_ipc);
661 }
662 mpp_enc_cfg_set_st(cfg, "hw:aq_rnge_arr", aq_rnge_arr);
663
664 mpp_enc_cfg_set_s32(cfg, "hw:qbias_en", 1);
665 mpp_enc_cfg_set_s32(cfg, "hw:qbias_i", cmd->bias_i);
666 mpp_enc_cfg_set_s32(cfg, "hw:qbias_p", cmd->bias_p);
667
668 if (p->type == MPP_VIDEO_CodingAVC) {
669 mpp_enc_cfg_set_st(cfg, "hw:qbias_arr", qbias_arr_avc);
670 } else if (p->type == MPP_VIDEO_CodingHEVC) {
671 mpp_enc_cfg_set_st(cfg, "hw:qbias_arr", qbias_arr_hevc);
672 }
673
674 mpp_enc_cfg_set_s32(cfg, "hw:skip_bias_en", 0);
675 mpp_enc_cfg_set_s32(cfg, "hw:skip_bias", 4);
676 mpp_enc_cfg_set_s32(cfg, "hw:skip_sad", 8);
677
678 ret = mpi->control(ctx, MPP_ENC_SET_CFG, cfg);
679 if (ret) {
680 mpp_err("mpi control enc set cfg failed ret %d\n", ret);
681 goto RET;
682 }
683
684 if (cmd->type == MPP_VIDEO_CodingAVC || cmd->type == MPP_VIDEO_CodingHEVC) {
685 RcApiBrief rc_api_brief;
686 rc_api_brief.type = cmd->type;
687 rc_api_brief.name = (cmd->rc_mode == MPP_ENC_RC_MODE_SMTRC) ?
688 "smart" : "default";
689
690 ret = mpi->control(ctx, MPP_ENC_SET_RC_API_CURRENT, &rc_api_brief);
691 if (ret) {
692 mpp_err("mpi control enc set rc api failed ret %d\n", ret);
693 goto RET;
694 }
695 }
696
697 if (ref)
698 mpp_enc_ref_cfg_deinit(&ref);
699
700 /* optional */
701 {
702 RK_U32 sei_mode;
703
704 mpp_env_get_u32("sei_mode", &sei_mode, MPP_ENC_SEI_MODE_DISABLE);
705 p->sei_mode = sei_mode;
706 ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
707 if (ret) {
708 mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
709 goto RET;
710 }
711 }
712
713 if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
714 p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
715 ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode);
716 if (ret) {
717 mpp_err("mpi control enc set header mode failed ret %d\n", ret);
718 goto RET;
719 }
720 }
721
722 /* setup test mode by env */
723 mpp_env_get_u32("osd_enable", &p->osd_enable, 0);
724 mpp_env_get_u32("roi_jpeg_enable", &p->roi_jpeg_enable, 0);
725 mpp_env_get_u32("jpeg_osd_case", &p->jpeg_osd_case, 0);
726 mpp_env_get_u32("osd_mode", &p->osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT);
727 mpp_env_get_u32("roi_enable", &p->roi_enable, 0);
728 mpp_env_get_u32("user_data_enable", &p->user_data_enable, 0);
729
730 if (p->roi_enable) {
731 mpp_enc_roi_init(&p->roi_ctx, p->width, p->height, p->type, 4);
732 mpp_assert(p->roi_ctx);
733 }
734
735 RET:
736 return ret;
737 }
738
test_mpp_run(MpiEncMultiCtxInfo * info)739 MPP_RET test_mpp_run(MpiEncMultiCtxInfo *info)
740 {
741 MpiEncTestArgs *cmd = info->cmd;
742 MpiEncTestData *p = &info->ctx;
743 MppApi *mpi = p->mpi;
744 MppCtx ctx = p->ctx;
745 RK_U32 quiet = cmd->quiet;
746 RK_S32 chn = info->chn;
747 RK_U32 cap_num = 0;
748 DataCrc checkcrc;
749 MPP_RET ret = MPP_OK;
750 RK_FLOAT psnr_const = 0;
751 RK_U32 sse_unit_in_pixel = 0;
752 RK_U32 soc_type;
753
754 memset(&checkcrc, 0, sizeof(checkcrc));
755 checkcrc.sum = mpp_malloc(RK_ULONG, 512);
756 soc_type = mpp_get_soc_type();
757
758 if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
759 MppPacket packet = NULL;
760
761 /*
762 * Can use packet with normal malloc buffer as input not pkt_buf.
763 * Please refer to vpu_api_legacy.cpp for normal buffer case.
764 * Using pkt_buf buffer here is just for simplifing demo.
765 */
766 mpp_packet_init_with_buffer(&packet, p->pkt_buf);
767 /* NOTE: It is important to clear output packet length!! */
768 mpp_packet_set_length(packet, 0);
769
770 ret = mpi->control(ctx, MPP_ENC_GET_HDR_SYNC, packet);
771 if (ret) {
772 mpp_err("mpi control enc get extra info failed\n");
773 goto RET;
774 } else {
775 /* get and write sps/pps for H.264 */
776
777 void *ptr = mpp_packet_get_pos(packet);
778 size_t len = mpp_packet_get_length(packet);
779
780 if (p->fp_output)
781 fwrite(ptr, 1, len, p->fp_output);
782 }
783
784 mpp_packet_deinit(&packet);
785
786 sse_unit_in_pixel = p->type == MPP_VIDEO_CodingAVC ? 16 : 8;
787 psnr_const = (16 + log2(MPP_ALIGN(p->width, sse_unit_in_pixel) *
788 MPP_ALIGN(p->height, sse_unit_in_pixel)));
789 }
790 while (!p->pkt_eos) {
791 MppMeta meta = NULL;
792 MppFrame frame = NULL;
793 MppPacket packet = NULL;
794 void *buf = mpp_buffer_get_ptr(p->frm_buf);
795 RK_S32 cam_frm_idx = -1;
796 MppBuffer cam_buf = NULL;
797 RK_U32 eoi = 1;
798
799 if (p->fp_input) {
800 mpp_buffer_sync_begin(p->frm_buf);
801 ret = read_image(buf, p->fp_input, p->width, p->height,
802 p->hor_stride, p->ver_stride, p->fmt);
803 if (ret == MPP_NOK || feof(p->fp_input)) {
804 p->frm_eos = 1;
805
806 if (p->frame_num < 0) {
807 clearerr(p->fp_input);
808 rewind(p->fp_input);
809 p->frm_eos = 0;
810 mpp_log_q(quiet, "chn %d loop times %d\n", chn, ++p->loop_times);
811 continue;
812 }
813 mpp_log_q(quiet, "chn %d found last frame. feof %d\n", chn, feof(p->fp_input));
814 } else if (ret == MPP_ERR_VALUE)
815 goto RET;
816 mpp_buffer_sync_end(p->frm_buf);
817 } else {
818 if (p->cam_ctx == NULL) {
819 mpp_buffer_sync_begin(p->frm_buf);
820 ret = fill_image(buf, p->width, p->height, p->hor_stride,
821 p->ver_stride, p->fmt, p->frame_count * p->frm_step);
822 if (ret)
823 goto RET;
824 mpp_buffer_sync_end(p->frm_buf);
825 } else {
826 cam_frm_idx = camera_source_get_frame(p->cam_ctx);
827 mpp_assert(cam_frm_idx >= 0);
828
829 /* skip unstable frames */
830 if (cap_num++ < 50) {
831 camera_source_put_frame(p->cam_ctx, cam_frm_idx);
832 continue;
833 }
834
835 cam_buf = camera_frame_to_buf(p->cam_ctx, cam_frm_idx);
836 mpp_assert(cam_buf);
837 }
838 }
839
840 ret = mpp_frame_init(&frame);
841 if (ret) {
842 mpp_err_f("mpp_frame_init failed\n");
843 goto RET;
844 }
845
846 mpp_frame_set_width(frame, p->width);
847 mpp_frame_set_height(frame, p->height);
848 mpp_frame_set_hor_stride(frame, p->hor_stride);
849 mpp_frame_set_ver_stride(frame, p->ver_stride);
850 mpp_frame_set_fmt(frame, p->fmt);
851 mpp_frame_set_eos(frame, p->frm_eos);
852
853 if (p->fp_input && feof(p->fp_input))
854 mpp_frame_set_buffer(frame, NULL);
855 else if (cam_buf)
856 mpp_frame_set_buffer(frame, cam_buf);
857 else
858 mpp_frame_set_buffer(frame, p->frm_buf);
859
860 meta = mpp_frame_get_meta(frame);
861 mpp_packet_init_with_buffer(&packet, p->pkt_buf);
862 /* NOTE: It is important to clear output packet length!! */
863 mpp_packet_set_length(packet, 0);
864 mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, packet);
865 mpp_meta_set_buffer(meta, KEY_MOTION_INFO, p->md_info);
866
867 if (p->osd_enable || p->user_data_enable || p->roi_enable || p->roi_jpeg_enable) {
868 if (p->user_data_enable) {
869 MppEncUserData user_data;
870 char *str = "this is user data\n";
871
872 if ((p->frame_count & 10) == 0) {
873 user_data.pdata = str;
874 user_data.len = strlen(str) + 1;
875 mpp_meta_set_ptr(meta, KEY_USER_DATA, &user_data);
876 }
877 static RK_U8 uuid_debug_info[16] = {
878 0x57, 0x68, 0x97, 0x80, 0xe7, 0x0c, 0x4b, 0x65,
879 0xa9, 0x06, 0xae, 0x29, 0x94, 0x11, 0xcd, 0x9a
880 };
881
882 MppEncUserDataSet data_group;
883 MppEncUserDataFull datas[2];
884 char *str1 = "this is user data 1\n";
885 char *str2 = "this is user data 2\n";
886 data_group.count = 2;
887 datas[0].len = strlen(str1) + 1;
888 datas[0].pdata = str1;
889 datas[0].uuid = uuid_debug_info;
890
891 datas[1].len = strlen(str2) + 1;
892 datas[1].pdata = str2;
893 datas[1].uuid = uuid_debug_info;
894
895 data_group.datas = datas;
896
897 mpp_meta_set_ptr(meta, KEY_USER_DATAS, &data_group);
898 }
899
900 if (p->osd_enable) {
901 if (soc_type == ROCKCHIP_SOC_RV1126B) {
902 /* osd for RV1126B use struct MppEncOSDData3 */
903 RK_S32 osd_case;
904 if (!p->osd_pattern) {
905 osd3_gen_smpte_bar_argb(&p->osd_pattern);
906 }
907
908 if (p->type == MPP_VIDEO_CodingMJPEG) {
909 osd_case = p->jpeg_osd_case;
910 } else {
911 osd_case = p->frame_count;
912 }
913
914 osd3_get_test_case(&p->osd_data3, p->osd_pattern,
915 (RK_U32)osd_case % OSD_CASE_BUTT, &p->osd_buffer);
916
917 mpp_meta_set_ptr(meta, KEY_OSD_DATA3, (void*)&p->osd_data3);
918 } else {
919 /* gen and cfg osd plt */
920 mpi_enc_gen_osd_plt(&p->osd_plt, p->frame_count);
921
922 p->osd_plt_cfg.change = MPP_ENC_OSD_PLT_CFG_CHANGE_ALL;
923 p->osd_plt_cfg.type = MPP_ENC_OSD_PLT_TYPE_USERDEF;
924 p->osd_plt_cfg.plt = &p->osd_plt;
925
926 ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt_cfg);
927 if (ret) {
928 mpp_err("mpi control enc set osd plt failed ret %d\n", ret);
929 goto RET;
930 }
931
932 /* gen and cfg osd plt */
933 mpi_enc_gen_osd_data(&p->osd_data, p->buf_grp, p->width,
934 p->height, p->frame_count);
935 mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)&p->osd_data);
936 }
937 }
938
939 if (p->roi_enable) {
940 RoiRegionCfg *region = &p->roi_region;
941
942 /* calculated in pixels */
943 region->x = MPP_ALIGN(p->width / 8, 16);
944 region->y = MPP_ALIGN(p->height / 8, 16);
945 region->w = 128;
946 region->h = 256;
947 region->force_intra = 0;
948 region->qp_mode = 1;
949 region->qp_val = 24;
950
951 mpp_enc_roi_add_region(p->roi_ctx, region);
952
953 region->x = MPP_ALIGN(p->width / 2, 16);
954 region->y = MPP_ALIGN(p->height / 4, 16);
955 region->w = 256;
956 region->h = 128;
957 region->force_intra = 1;
958 region->qp_mode = 1;
959 region->qp_val = 10;
960
961 mpp_enc_roi_add_region(p->roi_ctx, region);
962
963 /* send roi info by metadata */
964 mpp_enc_roi_setup_meta(p->roi_ctx, meta);
965 }
966
967 if (p->roi_jpeg_enable) {
968 RK_U32 index;
969 RK_U32 width = 128;
970 RK_U32 height = 128;
971 RK_U32 start_x = 0;
972 RK_U32 start_y = 0;
973
974 p->roi_jpeg_cfg.change = 1;
975 p->roi_jpeg_cfg.non_roi_en = 1;
976 p->roi_jpeg_cfg.non_roi_level = 0;
977
978 for (index = 0; index < 16; index++) {
979 if ((start_x + width) > p->width || (start_y + height) > p->height)
980 break;
981 p->roi_jpeg_cfg.regions[index].roi_en = 1;
982 p->roi_jpeg_cfg.regions[index].x = start_x;
983 p->roi_jpeg_cfg.regions[index].y = start_y;
984 p->roi_jpeg_cfg.regions[index].w = width;
985 p->roi_jpeg_cfg.regions[index].h = height;
986 p->roi_jpeg_cfg.regions[index].level = 63;
987
988 start_x += width;
989 start_y += height;
990 }
991
992 if (cmd->kmpp_en)
993 ret = mpi->control(ctx, MPP_ENC_SET_JPEG_ROI_CFG, &p->roi_jpeg_cfg);
994 else
995 mpp_meta_set_ptr(meta, KEY_JPEG_ROI_DATA, (void*)&p->roi_jpeg_cfg);
996 }
997 }
998
999 if (!p->first_frm)
1000 p->first_frm = mpp_time();
1001 /*
1002 * NOTE: in non-block mode the frame can be resent.
1003 * The default input timeout mode is block.
1004 *
1005 * User should release the input frame to meet the requirements of
1006 * resource creator must be the resource destroyer.
1007 */
1008 ret = mpi->encode_put_frame(ctx, frame);
1009 if (ret) {
1010 mpp_err("chn %d encode put frame failed\n", chn);
1011 mpp_frame_deinit(&frame);
1012 goto RET;
1013 }
1014
1015 mpp_frame_deinit(&frame);
1016
1017 do {
1018 ret = mpi->encode_get_packet(ctx, &packet);
1019 if (ret) {
1020 mpp_err("chn %d encode get packet failed\n", chn);
1021 goto RET;
1022 }
1023
1024 mpp_assert(packet);
1025
1026 if (packet) {
1027 // write packet to file here
1028 void *ptr = mpp_packet_get_pos(packet);
1029 size_t len = mpp_packet_get_length(packet);
1030 char log_buf[256];
1031 RK_S32 log_size = sizeof(log_buf) - 1;
1032 RK_S32 log_len = 0;
1033
1034 if (!p->first_pkt)
1035 p->first_pkt = mpp_time();
1036
1037 p->pkt_eos = mpp_packet_get_eos(packet);
1038
1039 if (p->fp_output)
1040 fwrite(ptr, 1, len, p->fp_output);
1041
1042 if (p->fp_verify && !p->pkt_eos) {
1043 calc_data_crc((RK_U8 *)ptr, (RK_U32)len, &checkcrc);
1044 mpp_log("p->frame_count=%d, len=%d\n", p->frame_count, len);
1045 write_data_crc(p->fp_verify, &checkcrc);
1046 }
1047
1048 log_len += snprintf(log_buf + log_len, log_size - log_len,
1049 "encoded frame %-4d", p->frame_count);
1050
1051 /* for low delay partition encoding */
1052 if (mpp_packet_is_partition(packet)) {
1053 eoi = mpp_packet_is_eoi(packet);
1054
1055 log_len += snprintf(log_buf + log_len, log_size - log_len,
1056 " pkt %d", p->frm_pkt_cnt);
1057 p->frm_pkt_cnt = (eoi) ? (0) : (p->frm_pkt_cnt + 1);
1058 }
1059
1060 log_len += snprintf(log_buf + log_len, log_size - log_len,
1061 " size %-7zu", len);
1062
1063 if (mpp_packet_has_meta(packet)) {
1064 meta = mpp_packet_get_meta(packet);
1065 RK_S32 temporal_id = 0;
1066 RK_S32 lt_idx = -1;
1067 RK_S32 avg_qp = -1, bps_rt = -1;
1068 RK_S32 use_lt_idx = -1;
1069 RK_S64 sse = 0;
1070 RK_FLOAT psnr = 0;
1071
1072 if (MPP_OK == mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &temporal_id))
1073 log_len += snprintf(log_buf + log_len, log_size - log_len,
1074 " tid %d", temporal_id);
1075
1076 if (MPP_OK == mpp_meta_get_s32(meta, KEY_LONG_REF_IDX, <_idx))
1077 log_len += snprintf(log_buf + log_len, log_size - log_len,
1078 " lt %d", lt_idx);
1079
1080 if (MPP_OK == mpp_meta_get_s32(meta, KEY_ENC_AVERAGE_QP, &avg_qp))
1081 log_len += snprintf(log_buf + log_len, log_size - log_len,
1082 " qp %2d", avg_qp);
1083
1084 if (MPP_OK == mpp_meta_get_s32(meta, KEY_ENC_BPS_RT, &bps_rt))
1085 log_len += snprintf(log_buf + log_len, log_size - log_len,
1086 " bps_rt %d", bps_rt);
1087
1088 if (MPP_OK == mpp_meta_get_s32(meta, KEY_ENC_USE_LTR, &use_lt_idx))
1089 log_len += snprintf(log_buf + log_len, log_size - log_len, " vi");
1090
1091 if (MPP_OK == mpp_meta_get_s64(meta, KEY_ENC_SSE, &sse)) {
1092 psnr = 3.01029996 * (psnr_const - log2(sse));
1093 log_len += snprintf(log_buf + log_len, log_size - log_len,
1094 " psnr %.4f", psnr);
1095 }
1096 }
1097
1098 mpp_log_q(quiet, "chn %d %s\n", chn, log_buf);
1099
1100 mpp_packet_deinit(&packet);
1101 fps_calc_inc(cmd->fps);
1102
1103 p->stream_size += len;
1104 p->frame_count += eoi;
1105
1106 if (p->pkt_eos) {
1107 mpp_log_q(quiet, "chn %d found last packet\n", chn);
1108 mpp_assert(p->frm_eos);
1109 }
1110 }
1111 } while (!eoi);
1112
1113 if (cam_frm_idx >= 0)
1114 camera_source_put_frame(p->cam_ctx, cam_frm_idx);
1115
1116 if (p->frame_num > 0 && p->frame_count >= p->frame_num)
1117 break;
1118
1119 if (p->loop_end)
1120 break;
1121
1122 if (p->frm_eos && p->pkt_eos)
1123 break;
1124 }
1125 RET:
1126 MPP_FREE(checkcrc.sum);
1127
1128 return ret;
1129 }
1130
enc_test(void * arg)1131 void *enc_test(void *arg)
1132 {
1133 MpiEncMultiCtxInfo *info = (MpiEncMultiCtxInfo *)arg;
1134 MpiEncTestArgs *cmd = info->cmd;
1135 MpiEncTestData *p = &info->ctx;
1136 MpiEncMultiCtxRet *enc_ret = &info->ret;
1137 MppPollType timeout = MPP_POLL_BLOCK;
1138 RK_U32 quiet = cmd->quiet;
1139 MPP_RET ret = MPP_OK;
1140 RK_S64 t_s = 0;
1141 RK_S64 t_e = 0;
1142
1143 mpp_log_q(quiet, "%s start\n", info->name);
1144
1145 ret = test_ctx_init(info);
1146 if (ret) {
1147 mpp_err_f("test data init failed ret %d\n", ret);
1148 goto MPP_TEST_OUT;
1149 }
1150
1151 ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_DRM | MPP_BUFFER_FLAGS_CACHABLE);
1152 if (ret) {
1153 mpp_err_f("failed to get mpp buffer group ret %d\n", ret);
1154 goto MPP_TEST_OUT;
1155 }
1156
1157 ret = mpp_buffer_get(p->buf_grp, &p->frm_buf, p->frame_size + p->header_size);
1158 if (ret) {
1159 mpp_err_f("failed to get buffer for input frame ret %d\n", ret);
1160 goto MPP_TEST_OUT;
1161 }
1162
1163 ret = mpp_buffer_get(p->buf_grp, &p->pkt_buf, p->frame_size);
1164 if (ret) {
1165 mpp_err_f("failed to get buffer for output packet ret %d\n", ret);
1166 goto MPP_TEST_OUT;
1167 }
1168
1169 ret = mpp_buffer_get(p->buf_grp, &p->md_info, p->mdinfo_size);
1170 if (ret) {
1171 mpp_err_f("failed to get buffer for motion info output packet ret %d\n", ret);
1172 goto MPP_TEST_OUT;
1173 }
1174
1175 // encoder demo
1176 ret = mpp_create(&p->ctx, &p->mpi);
1177 if (ret) {
1178 mpp_err("mpp_create failed ret %d\n", ret);
1179 goto MPP_TEST_OUT;
1180 }
1181
1182 mpp_log_q(quiet, "%p encoder test start w %d h %d type %d\n",
1183 p->ctx, p->width, p->height, p->type);
1184
1185 ret = p->mpi->control(p->ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
1186 if (MPP_OK != ret) {
1187 mpp_err("mpi control set output timeout %d ret %d\n", timeout, ret);
1188 goto MPP_TEST_OUT;
1189 }
1190
1191 if (cmd->kmpp_en)
1192 kmpp_cfg_init(info);
1193
1194 ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type);
1195 if (ret) {
1196 mpp_err("mpp_init failed ret %d\n", ret);
1197 goto MPP_TEST_OUT;
1198 }
1199
1200 if (cmd->kmpp_en)
1201 ret = mpp_enc_cfg_init_k(&p->cfg);
1202 else
1203 ret = mpp_enc_cfg_init(&p->cfg);
1204 if (ret) {
1205 mpp_err_f("mpp_enc_cfg_init failed ret %d\n", ret);
1206 goto MPP_TEST_OUT;
1207 }
1208
1209 ret = p->mpi->control(p->ctx, MPP_ENC_GET_CFG, p->cfg);
1210 if (ret) {
1211 mpp_err_f("get enc cfg failed ret %d\n", ret);
1212 goto MPP_TEST_OUT;
1213 }
1214
1215 ret = test_mpp_enc_cfg_setup(info);
1216 if (ret) {
1217 mpp_err_f("test mpp setup failed ret %d\n", ret);
1218 goto MPP_TEST_OUT;
1219 }
1220
1221 t_s = mpp_time();
1222 ret = test_mpp_run(info);
1223 t_e = mpp_time();
1224 if (ret) {
1225 mpp_err_f("test mpp run failed ret %d\n", ret);
1226 goto MPP_TEST_OUT;
1227 }
1228
1229 ret = p->mpi->reset(p->ctx);
1230 if (ret) {
1231 mpp_err("mpi->reset failed\n");
1232 goto MPP_TEST_OUT;
1233 }
1234
1235 enc_ret->elapsed_time = t_e - t_s;
1236 enc_ret->frame_count = p->frame_count;
1237 enc_ret->stream_size = p->stream_size;
1238 enc_ret->frame_rate = (float)p->frame_count * 1000000 / enc_ret->elapsed_time;
1239 enc_ret->bit_rate = (p->stream_size * 8 * (p->fps_out_num / p->fps_out_den)) / p->frame_count;
1240 enc_ret->delay = p->first_pkt - p->first_frm;
1241
1242 MPP_TEST_OUT:
1243 if (p->ctx) {
1244 mpp_destroy(p->ctx);
1245 p->ctx = NULL;
1246 }
1247
1248 if (p->cfg) {
1249 mpp_enc_cfg_deinit(p->cfg);
1250 p->cfg = NULL;
1251 }
1252
1253 if (p->frm_buf) {
1254 mpp_buffer_put(p->frm_buf);
1255 p->frm_buf = NULL;
1256 }
1257
1258 if (p->pkt_buf) {
1259 mpp_buffer_put(p->pkt_buf);
1260 p->pkt_buf = NULL;
1261 }
1262
1263 if (p->md_info) {
1264 mpp_buffer_put(p->md_info);
1265 p->md_info = NULL;
1266 }
1267
1268 if (p->osd_data.buf) {
1269 mpp_buffer_put(p->osd_data.buf);
1270 p->osd_data.buf = NULL;
1271 }
1272
1273 if (p->osd_buffer) {
1274 kmpp_obj_put_f(p->osd_buffer);
1275 p->osd_buffer = NULL;
1276 }
1277
1278 if (p->buf_grp) {
1279 mpp_buffer_group_put(p->buf_grp);
1280 p->buf_grp = NULL;
1281 }
1282
1283 if (p->roi_ctx) {
1284 mpp_enc_roi_deinit(p->roi_ctx);
1285 p->roi_ctx = NULL;
1286 }
1287 if (p->init_kcfg)
1288 mpp_venc_kcfg_deinit(p->init_kcfg);
1289
1290 if (p->osd_pattern) {
1291 free(p->osd_pattern);
1292 p->osd_pattern = NULL;
1293 }
1294
1295 test_ctx_deinit(p);
1296
1297 return NULL;
1298 }
1299
enc_test_multi(MpiEncTestArgs * cmd,const char * name)1300 int enc_test_multi(MpiEncTestArgs* cmd, const char *name)
1301 {
1302 MpiEncMultiCtxInfo *ctxs = NULL;
1303 float total_rate = 0.0;
1304 RK_S32 ret = MPP_NOK;
1305 RK_S32 i = 0;
1306
1307 ctxs = mpp_calloc(MpiEncMultiCtxInfo, cmd->nthreads);
1308 if (NULL == ctxs) {
1309 mpp_err("failed to alloc context for instances\n");
1310 return -1;
1311 }
1312
1313 for (i = 0; i < cmd->nthreads; i++) {
1314 ctxs[i].cmd = cmd;
1315 ctxs[i].name = name;
1316 ctxs[i].chn = i;
1317
1318 ret = pthread_create(&ctxs[i].thd, NULL, enc_test, &ctxs[i]);
1319 if (ret) {
1320 mpp_err("failed to create thread %d\n", i);
1321 return ret;
1322 }
1323 }
1324
1325 if (cmd->frame_num < 0) {
1326 // wait for input then quit encoding
1327 mpp_log("*******************************************\n");
1328 mpp_log("**** Press Enter to stop loop encoding ****\n");
1329 mpp_log("*******************************************\n");
1330
1331 getc(stdin);
1332 for (i = 0; i < cmd->nthreads; i++)
1333 ctxs[i].ctx.loop_end = 1;
1334 }
1335
1336 for (i = 0; i < cmd->nthreads; i++)
1337 pthread_join(ctxs[i].thd, NULL);
1338
1339 for (i = 0; i < cmd->nthreads; i++) {
1340 MpiEncMultiCtxRet *enc_ret = &ctxs[i].ret;
1341
1342 mpp_log("chn %d encode %d frames time %lld ms delay %3d ms fps %3.2f bps %lld\n",
1343 i, enc_ret->frame_count, (RK_S64)(enc_ret->elapsed_time / 1000),
1344 (RK_S32)(enc_ret->delay / 1000), enc_ret->frame_rate, enc_ret->bit_rate);
1345
1346 total_rate += enc_ret->frame_rate;
1347 }
1348
1349 MPP_FREE(ctxs);
1350
1351 total_rate /= cmd->nthreads;
1352 mpp_log("%s average frame rate %.2f\n", name, total_rate);
1353
1354 return ret;
1355 }
1356
main(int argc,char ** argv)1357 int main(int argc, char **argv)
1358 {
1359 RK_S32 ret = MPP_NOK;
1360 MpiEncTestArgs* cmd = mpi_enc_test_cmd_get();
1361
1362 // parse the cmd option
1363 ret = mpi_enc_test_cmd_update_by_args(cmd, argc, argv);
1364 if (ret)
1365 goto DONE;
1366
1367 mpi_enc_test_cmd_show_opt(cmd);
1368
1369 ret = enc_test_multi(cmd, argv[0]);
1370
1371 DONE:
1372 mpi_enc_test_cmd_put(cmd);
1373
1374 return ret;
1375 }
1376