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