xref: /rockchip-linux_mpp/test/mpi_enc_test.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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, &lt_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