xref: /OK3568_Linux_fs/external/mpp/test/mpi_enc_mt_test.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2022 Rockchip Electronics Co. LTD
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Licensed under the Apache License, Version 2.0 (the "License");
5*4882a593Smuzhiyun  * you may not use this file except in compliance with the License.
6*4882a593Smuzhiyun  * You may obtain a copy of the License at
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *      http://www.apache.org/licenses/LICENSE-2.0
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * Unless required by applicable law or agreed to in writing, software
11*4882a593Smuzhiyun  * distributed under the License is distributed on an "AS IS" BASIS,
12*4882a593Smuzhiyun  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4882a593Smuzhiyun  * See the License for the specific language governing permissions and
14*4882a593Smuzhiyun  * limitations under the License.
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define MODULE_TAG "mpi_enc_mt_test"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <string.h>
20*4882a593Smuzhiyun #include "rk_mpi.h"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #include "mpp_env.h"
23*4882a593Smuzhiyun #include "mpp_mem.h"
24*4882a593Smuzhiyun #include "mpp_time.h"
25*4882a593Smuzhiyun #include "mpp_list.h"
26*4882a593Smuzhiyun #include "mpp_lock.h"
27*4882a593Smuzhiyun #include "mpp_debug.h"
28*4882a593Smuzhiyun #include "mpp_common.h"
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #include "utils.h"
31*4882a593Smuzhiyun #include "mpi_enc_utils.h"
32*4882a593Smuzhiyun #include "camera_source.h"
33*4882a593Smuzhiyun #include "mpp_enc_roi_utils.h"
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define BUF_COUNT   4
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun typedef struct {
38*4882a593Smuzhiyun     // base flow context
39*4882a593Smuzhiyun     MppCtx ctx;
40*4882a593Smuzhiyun     MppApi *mpi;
41*4882a593Smuzhiyun     RK_S32 chn;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun     // global flow control flag
44*4882a593Smuzhiyun     RK_U32 frm_eos;
45*4882a593Smuzhiyun     RK_U32 pkt_eos;
46*4882a593Smuzhiyun     RK_U32 frm_pkt_cnt;
47*4882a593Smuzhiyun     RK_S32 frame_num;
48*4882a593Smuzhiyun     RK_S32 frm_cnt_in;
49*4882a593Smuzhiyun     RK_S32 frm_cnt_out;
50*4882a593Smuzhiyun     RK_U64 stream_size;
51*4882a593Smuzhiyun     /* end of encoding flag when set quit the loop */
52*4882a593Smuzhiyun     volatile RK_U32 loop_end;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun     // src and dst
55*4882a593Smuzhiyun     FILE *fp_input;
56*4882a593Smuzhiyun     FILE *fp_output;
57*4882a593Smuzhiyun     FILE *fp_verify;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun     /* encoder config set */
60*4882a593Smuzhiyun     MppEncCfg       cfg;
61*4882a593Smuzhiyun     MppEncPrepCfg   prep_cfg;
62*4882a593Smuzhiyun     MppEncRcCfg     rc_cfg;
63*4882a593Smuzhiyun     MppEncCodecCfg  codec_cfg;
64*4882a593Smuzhiyun     MppEncOSDPltCfg osd_plt_cfg;
65*4882a593Smuzhiyun     MppEncOSDPlt    osd_plt;
66*4882a593Smuzhiyun     MppEncOSDData   osd_data;
67*4882a593Smuzhiyun     RoiRegionCfg    roi_region;
68*4882a593Smuzhiyun     MppEncROICfg    roi_cfg;
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun     // input / output
71*4882a593Smuzhiyun     mpp_list        *list_buf;
72*4882a593Smuzhiyun     MppBufferGroup buf_grp;
73*4882a593Smuzhiyun     MppBuffer frm_buf[BUF_COUNT];
74*4882a593Smuzhiyun     MppBuffer pkt_buf[BUF_COUNT];
75*4882a593Smuzhiyun     RK_S32 buf_idx;
76*4882a593Smuzhiyun     MppEncSeiMode sei_mode;
77*4882a593Smuzhiyun     MppEncHeaderMode header_mode;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun     // paramter for resource malloc
80*4882a593Smuzhiyun     RK_U32 width;
81*4882a593Smuzhiyun     RK_U32 height;
82*4882a593Smuzhiyun     RK_U32 hor_stride;
83*4882a593Smuzhiyun     RK_U32 ver_stride;
84*4882a593Smuzhiyun     MppFrameFormat fmt;
85*4882a593Smuzhiyun     MppCodingType type;
86*4882a593Smuzhiyun     RK_S32 loop_times;
87*4882a593Smuzhiyun     CamSource *cam_ctx;
88*4882a593Smuzhiyun     MppEncRoiCtx roi_ctx;
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun     // resources
91*4882a593Smuzhiyun     size_t header_size;
92*4882a593Smuzhiyun     size_t frame_size;
93*4882a593Smuzhiyun     /* NOTE: packet buffer may overflow */
94*4882a593Smuzhiyun     size_t packet_size;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun     RK_U32 osd_enable;
97*4882a593Smuzhiyun     RK_U32 osd_mode;
98*4882a593Smuzhiyun     RK_U32 split_mode;
99*4882a593Smuzhiyun     RK_U32 split_arg;
100*4882a593Smuzhiyun     RK_U32 split_out;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun     RK_U32 user_data_enable;
103*4882a593Smuzhiyun     RK_U32 roi_enable;
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun     // rate control runtime parameter
106*4882a593Smuzhiyun     RK_S32 fps_in_flex;
107*4882a593Smuzhiyun     RK_S32 fps_in_den;
108*4882a593Smuzhiyun     RK_S32 fps_in_num;
109*4882a593Smuzhiyun     RK_S32 fps_out_flex;
110*4882a593Smuzhiyun     RK_S32 fps_out_den;
111*4882a593Smuzhiyun     RK_S32 fps_out_num;
112*4882a593Smuzhiyun     RK_S32 bps;
113*4882a593Smuzhiyun     RK_S32 bps_max;
114*4882a593Smuzhiyun     RK_S32 bps_min;
115*4882a593Smuzhiyun     RK_S32 rc_mode;
116*4882a593Smuzhiyun     RK_S32 gop_mode;
117*4882a593Smuzhiyun     RK_S32 gop_len;
118*4882a593Smuzhiyun     RK_S32 vi_len;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun     RK_S64 first_frm;
121*4882a593Smuzhiyun     RK_S64 first_pkt;
122*4882a593Smuzhiyun     RK_S64 last_pkt;
123*4882a593Smuzhiyun } MpiEncMtTestData;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun /* For each instance thread return value */
126*4882a593Smuzhiyun typedef struct {
127*4882a593Smuzhiyun     float           frame_rate;
128*4882a593Smuzhiyun     RK_U64          bit_rate;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun     RK_S64          time_start;
131*4882a593Smuzhiyun     RK_S64          time_delay;
132*4882a593Smuzhiyun     RK_S64          time_total;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun     RK_S64          elapsed_time;
135*4882a593Smuzhiyun     RK_S32          frame_count;
136*4882a593Smuzhiyun     RK_S64          stream_size;
137*4882a593Smuzhiyun     RK_S64          delay;
138*4882a593Smuzhiyun } MpiEncMtCtxRet;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun typedef struct {
141*4882a593Smuzhiyun     MpiEncTestArgs      *cmd;       // pointer to global command line info
142*4882a593Smuzhiyun     const char          *name;
143*4882a593Smuzhiyun     RK_S32              chn;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun     pthread_t           thd_in;     // thread for for frame input
146*4882a593Smuzhiyun     pthread_t           thd_out;    // thread for for packet output
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun     struct list_head    frm_list;
149*4882a593Smuzhiyun     spinlock_t          frm_lock;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun     MpiEncMtTestData    ctx;        // context of encoder
152*4882a593Smuzhiyun     MpiEncMtCtxRet      ret;        // return of encoder
153*4882a593Smuzhiyun } MpiEncMtCtxInfo;
154*4882a593Smuzhiyun 
mt_test_ctx_init(MpiEncMtCtxInfo * info)155*4882a593Smuzhiyun MPP_RET mt_test_ctx_init(MpiEncMtCtxInfo *info)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun     MpiEncTestArgs *cmd = info->cmd;
158*4882a593Smuzhiyun     MpiEncMtTestData *p = &info->ctx;
159*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun     // get paramter from cmd
162*4882a593Smuzhiyun     p->width        = cmd->width;
163*4882a593Smuzhiyun     p->height       = cmd->height;
164*4882a593Smuzhiyun     p->hor_stride   = (cmd->hor_stride) ? (cmd->hor_stride) :
165*4882a593Smuzhiyun                       (MPP_ALIGN(cmd->width, 16));
166*4882a593Smuzhiyun     p->ver_stride   = (cmd->ver_stride) ? (cmd->ver_stride) :
167*4882a593Smuzhiyun                       (MPP_ALIGN(cmd->height, 16));
168*4882a593Smuzhiyun     p->fmt          = cmd->format;
169*4882a593Smuzhiyun     p->type         = cmd->type;
170*4882a593Smuzhiyun     p->bps          = cmd->bps_target;
171*4882a593Smuzhiyun     p->bps_min      = cmd->bps_min;
172*4882a593Smuzhiyun     p->bps_max      = cmd->bps_max;
173*4882a593Smuzhiyun     p->rc_mode      = cmd->rc_mode;
174*4882a593Smuzhiyun     p->frame_num    = cmd->frame_num;
175*4882a593Smuzhiyun     if (cmd->type == MPP_VIDEO_CodingMJPEG && p->frame_num == 0) {
176*4882a593Smuzhiyun         mpp_log("jpege default encode only one frame. Use -n [num] for rc case\n");
177*4882a593Smuzhiyun         p->frame_num = 1;
178*4882a593Smuzhiyun     }
179*4882a593Smuzhiyun     p->gop_mode     = cmd->gop_mode;
180*4882a593Smuzhiyun     p->gop_len      = cmd->gop_len;
181*4882a593Smuzhiyun     p->vi_len       = cmd->vi_len;
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun     p->fps_in_flex  = cmd->fps_in_flex;
184*4882a593Smuzhiyun     p->fps_in_den   = cmd->fps_in_den;
185*4882a593Smuzhiyun     p->fps_in_num   = cmd->fps_in_num;
186*4882a593Smuzhiyun     p->fps_out_flex = cmd->fps_out_flex;
187*4882a593Smuzhiyun     p->fps_out_den  = cmd->fps_out_den;
188*4882a593Smuzhiyun     p->fps_out_num  = cmd->fps_out_num;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun     if (cmd->file_input) {
191*4882a593Smuzhiyun         if (!strncmp(cmd->file_input, "/dev/video", 10)) {
192*4882a593Smuzhiyun             mpp_log("open camera device");
193*4882a593Smuzhiyun             p->cam_ctx = camera_source_init(cmd->file_input, 4, p->width, p->height, p->fmt);
194*4882a593Smuzhiyun             mpp_log("new framecap ok");
195*4882a593Smuzhiyun             if (p->cam_ctx == NULL)
196*4882a593Smuzhiyun                 mpp_err("open %s fail", cmd->file_input);
197*4882a593Smuzhiyun         } else {
198*4882a593Smuzhiyun             p->fp_input = fopen(cmd->file_input, "rb");
199*4882a593Smuzhiyun             if (NULL == p->fp_input) {
200*4882a593Smuzhiyun                 mpp_err("failed to open input file %s\n", cmd->file_input);
201*4882a593Smuzhiyun                 mpp_err("create default yuv image for test\n");
202*4882a593Smuzhiyun             }
203*4882a593Smuzhiyun         }
204*4882a593Smuzhiyun     }
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun     if (cmd->file_output) {
207*4882a593Smuzhiyun         p->fp_output = fopen(cmd->file_output, "w+b");
208*4882a593Smuzhiyun         if (NULL == p->fp_output) {
209*4882a593Smuzhiyun             mpp_err("failed to open output file %s\n", cmd->file_output);
210*4882a593Smuzhiyun             ret = MPP_ERR_OPEN_FILE;
211*4882a593Smuzhiyun         }
212*4882a593Smuzhiyun     }
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun     if (cmd->file_slt) {
215*4882a593Smuzhiyun         p->fp_verify = fopen(cmd->file_slt, "wt");
216*4882a593Smuzhiyun         if (!p->fp_verify)
217*4882a593Smuzhiyun             mpp_err("failed to open verify file %s\n", cmd->file_slt);
218*4882a593Smuzhiyun     }
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun     // update resource parameter
221*4882a593Smuzhiyun     switch (p->fmt & MPP_FRAME_FMT_MASK) {
222*4882a593Smuzhiyun     case MPP_FMT_YUV420SP:
223*4882a593Smuzhiyun     case MPP_FMT_YUV420P: {
224*4882a593Smuzhiyun         p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 3 / 2;
225*4882a593Smuzhiyun     } break;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun     case MPP_FMT_YUV422_YUYV :
228*4882a593Smuzhiyun     case MPP_FMT_YUV422_YVYU :
229*4882a593Smuzhiyun     case MPP_FMT_YUV422_UYVY :
230*4882a593Smuzhiyun     case MPP_FMT_YUV422_VYUY :
231*4882a593Smuzhiyun     case MPP_FMT_YUV422P :
232*4882a593Smuzhiyun     case MPP_FMT_YUV422SP : {
233*4882a593Smuzhiyun         p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 2;
234*4882a593Smuzhiyun     } break;
235*4882a593Smuzhiyun     case MPP_FMT_RGB444 :
236*4882a593Smuzhiyun     case MPP_FMT_BGR444 :
237*4882a593Smuzhiyun     case MPP_FMT_RGB555 :
238*4882a593Smuzhiyun     case MPP_FMT_BGR555 :
239*4882a593Smuzhiyun     case MPP_FMT_RGB565 :
240*4882a593Smuzhiyun     case MPP_FMT_BGR565 :
241*4882a593Smuzhiyun     case MPP_FMT_RGB888 :
242*4882a593Smuzhiyun     case MPP_FMT_BGR888 :
243*4882a593Smuzhiyun     case MPP_FMT_RGB101010 :
244*4882a593Smuzhiyun     case MPP_FMT_BGR101010 :
245*4882a593Smuzhiyun     case MPP_FMT_ARGB8888 :
246*4882a593Smuzhiyun     case MPP_FMT_ABGR8888 :
247*4882a593Smuzhiyun     case MPP_FMT_BGRA8888 :
248*4882a593Smuzhiyun     case MPP_FMT_RGBA8888 : {
249*4882a593Smuzhiyun         p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64);
250*4882a593Smuzhiyun     } break;
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun     default: {
253*4882a593Smuzhiyun         p->frame_size = MPP_ALIGN(p->hor_stride, 64) * MPP_ALIGN(p->ver_stride, 64) * 4;
254*4882a593Smuzhiyun     } break;
255*4882a593Smuzhiyun     }
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun     if (MPP_FRAME_FMT_IS_FBC(p->fmt))
258*4882a593Smuzhiyun         p->header_size = MPP_ALIGN(MPP_ALIGN(p->width, 16) * MPP_ALIGN(p->height, 16) / 16, SZ_4K);
259*4882a593Smuzhiyun     else
260*4882a593Smuzhiyun         p->header_size = 0;
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun     return ret;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun 
mt_test_ctx_deinit(MpiEncMtCtxInfo * info)265*4882a593Smuzhiyun MPP_RET mt_test_ctx_deinit(MpiEncMtCtxInfo *info)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun     MpiEncMtTestData *p = NULL;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun     if (NULL == info)
270*4882a593Smuzhiyun         return MPP_OK;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun     p = &info->ctx;
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun     if (p->cam_ctx) {
275*4882a593Smuzhiyun         camera_source_deinit(p->cam_ctx);
276*4882a593Smuzhiyun         p->cam_ctx = NULL;
277*4882a593Smuzhiyun     }
278*4882a593Smuzhiyun     if (p->fp_input) {
279*4882a593Smuzhiyun         fclose(p->fp_input);
280*4882a593Smuzhiyun         p->fp_input = NULL;
281*4882a593Smuzhiyun     }
282*4882a593Smuzhiyun     if (p->fp_output) {
283*4882a593Smuzhiyun         fclose(p->fp_output);
284*4882a593Smuzhiyun         p->fp_output = NULL;
285*4882a593Smuzhiyun     }
286*4882a593Smuzhiyun     if (p->fp_verify) {
287*4882a593Smuzhiyun         fclose(p->fp_verify);
288*4882a593Smuzhiyun         p->fp_verify = NULL;
289*4882a593Smuzhiyun     }
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun     return MPP_OK;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
test_mt_cfg_setup(MpiEncMtCtxInfo * info)294*4882a593Smuzhiyun MPP_RET test_mt_cfg_setup(MpiEncMtCtxInfo *info)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun     MpiEncTestArgs *cmd = info->cmd;
297*4882a593Smuzhiyun     MpiEncMtTestData *p = &info->ctx;
298*4882a593Smuzhiyun     MppApi *mpi = p->mpi;
299*4882a593Smuzhiyun     MppCtx ctx = p->ctx;
300*4882a593Smuzhiyun     MppEncCfg cfg = p->cfg;
301*4882a593Smuzhiyun     RK_U32 gop_mode = p->gop_mode;
302*4882a593Smuzhiyun     RK_U32 quiet = cmd->quiet;
303*4882a593Smuzhiyun     MPP_RET ret;
304*4882a593Smuzhiyun     MppEncRefCfg ref = NULL;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun     /* setup default parameter */
307*4882a593Smuzhiyun     if (p->fps_in_den == 0)
308*4882a593Smuzhiyun         p->fps_in_den = 1;
309*4882a593Smuzhiyun     if (p->fps_in_num == 0)
310*4882a593Smuzhiyun         p->fps_in_num = 30;
311*4882a593Smuzhiyun     if (p->fps_out_den == 0)
312*4882a593Smuzhiyun         p->fps_out_den = 1;
313*4882a593Smuzhiyun     if (p->fps_out_num == 0)
314*4882a593Smuzhiyun         p->fps_out_num = 30;
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun     if (!p->bps)
317*4882a593Smuzhiyun         p->bps = p->width * p->height / 8 * (p->fps_out_num / p->fps_out_den);
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "prep:width", p->width);
320*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "prep:height", p->height);
321*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "prep:hor_stride", p->hor_stride);
322*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "prep:ver_stride", p->ver_stride);
323*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "prep:format", p->fmt);
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:mode", p->rc_mode);
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun     /* fix input / output frame rate */
328*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:fps_in_flex", p->fps_in_flex);
329*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:fps_in_num", p->fps_in_num);
330*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:fps_in_denorm", p->fps_in_den);
331*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:fps_out_flex", p->fps_out_flex);
332*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:fps_out_num", p->fps_out_num);
333*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:fps_out_denorm", p->fps_out_den);
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun     /* drop frame or not when bitrate overflow */
336*4882a593Smuzhiyun     mpp_enc_cfg_set_u32(cfg, "rc:drop_mode", MPP_ENC_RC_DROP_FRM_DISABLED);
337*4882a593Smuzhiyun     mpp_enc_cfg_set_u32(cfg, "rc:drop_thd", 20);        /* 20% of max bps */
338*4882a593Smuzhiyun     mpp_enc_cfg_set_u32(cfg, "rc:drop_gap", 1);         /* Do not continuous drop frame */
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun     /* setup bitrate for different rc_mode */
341*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:bps_target", p->bps);
342*4882a593Smuzhiyun     switch (p->rc_mode) {
343*4882a593Smuzhiyun     case MPP_ENC_RC_MODE_FIXQP : {
344*4882a593Smuzhiyun         /* do not setup bitrate on FIXQP mode */
345*4882a593Smuzhiyun     } break;
346*4882a593Smuzhiyun     case MPP_ENC_RC_MODE_CBR : {
347*4882a593Smuzhiyun         /* CBR mode has narrow bound */
348*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
349*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
350*4882a593Smuzhiyun     } break;
351*4882a593Smuzhiyun     case MPP_ENC_RC_MODE_VBR :
352*4882a593Smuzhiyun     case MPP_ENC_RC_MODE_AVBR : {
353*4882a593Smuzhiyun         /* VBR mode has wide bound */
354*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
355*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 1 / 16);
356*4882a593Smuzhiyun     } break;
357*4882a593Smuzhiyun     default : {
358*4882a593Smuzhiyun         /* default use CBR mode */
359*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:bps_max", p->bps_max ? p->bps_max : p->bps * 17 / 16);
360*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:bps_min", p->bps_min ? p->bps_min : p->bps * 15 / 16);
361*4882a593Smuzhiyun     } break;
362*4882a593Smuzhiyun     }
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun     /* setup qp for different codec and rc_mode */
365*4882a593Smuzhiyun     switch (p->type) {
366*4882a593Smuzhiyun     case MPP_VIDEO_CodingAVC :
367*4882a593Smuzhiyun     case MPP_VIDEO_CodingHEVC : {
368*4882a593Smuzhiyun         switch (p->rc_mode) {
369*4882a593Smuzhiyun         case MPP_ENC_RC_MODE_FIXQP : {
370*4882a593Smuzhiyun             RK_S32 fix_qp = cmd->qp_init;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_init", fix_qp);
373*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_max", fix_qp);
374*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_min", fix_qp);
375*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", fix_qp);
376*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", fix_qp);
377*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 0);
378*4882a593Smuzhiyun         } break;
379*4882a593Smuzhiyun         case MPP_ENC_RC_MODE_CBR :
380*4882a593Smuzhiyun         case MPP_ENC_RC_MODE_VBR :
381*4882a593Smuzhiyun         case MPP_ENC_RC_MODE_AVBR : {
382*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_init", cmd->qp_init ? cmd->qp_init : -1);
383*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_max", cmd->qp_max ? cmd->qp_max : 51);
384*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_min", cmd->qp_min ? cmd->qp_min : 10);
385*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", cmd->qp_max_i ? cmd->qp_max_i : 51);
386*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", cmd->qp_min_i ? cmd->qp_min_i : 10);
387*4882a593Smuzhiyun             mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 2);
388*4882a593Smuzhiyun         } break;
389*4882a593Smuzhiyun         default : {
390*4882a593Smuzhiyun             mpp_err_f("unsupport encoder rc mode %d\n", p->rc_mode);
391*4882a593Smuzhiyun         } break;
392*4882a593Smuzhiyun         }
393*4882a593Smuzhiyun     } break;
394*4882a593Smuzhiyun     case MPP_VIDEO_CodingVP8 : {
395*4882a593Smuzhiyun         /* vp8 only setup base qp range */
396*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:qp_init", cmd->qp_init ? cmd->qp_init : 40);
397*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:qp_max",  cmd->qp_max ? cmd->qp_max : 127);
398*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:qp_min",  cmd->qp_min ? cmd->qp_min : 0);
399*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:qp_max_i", cmd->qp_max_i ? cmd->qp_max_i : 127);
400*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:qp_min_i", cmd->qp_min_i ? cmd->qp_min_i : 0);
401*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "rc:qp_ip", 6);
402*4882a593Smuzhiyun     } break;
403*4882a593Smuzhiyun     case MPP_VIDEO_CodingMJPEG : {
404*4882a593Smuzhiyun         /* jpeg use special codec config to control qtable */
405*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "jpeg:q_factor", cmd->qp_init ? cmd->qp_init : 80);
406*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "jpeg:qf_max", cmd->qp_max ? cmd->qp_max : 99);
407*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "jpeg:qf_min", cmd->qp_min ? cmd->qp_min : 1);
408*4882a593Smuzhiyun     } break;
409*4882a593Smuzhiyun     default : {
410*4882a593Smuzhiyun     } break;
411*4882a593Smuzhiyun     }
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun     /* setup codec  */
414*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "codec:type", p->type);
415*4882a593Smuzhiyun     switch (p->type) {
416*4882a593Smuzhiyun     case MPP_VIDEO_CodingAVC : {
417*4882a593Smuzhiyun         /*
418*4882a593Smuzhiyun          * H.264 profile_idc parameter
419*4882a593Smuzhiyun          * 66  - Baseline profile
420*4882a593Smuzhiyun          * 77  - Main profile
421*4882a593Smuzhiyun          * 100 - High profile
422*4882a593Smuzhiyun          */
423*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "h264:profile", 100);
424*4882a593Smuzhiyun         /*
425*4882a593Smuzhiyun          * H.264 level_idc parameter
426*4882a593Smuzhiyun          * 10 / 11 / 12 / 13    - qcif@15fps / cif@7.5fps / cif@15fps / cif@30fps
427*4882a593Smuzhiyun          * 20 / 21 / 22         - cif@30fps / half-D1@@25fps / D1@12.5fps
428*4882a593Smuzhiyun          * 30 / 31 / 32         - D1@25fps / 720p@30fps / 720p@60fps
429*4882a593Smuzhiyun          * 40 / 41 / 42         - 1080p@30fps / 1080p@30fps / 1080p@60fps
430*4882a593Smuzhiyun          * 50 / 51 / 52         - 4K@30fps
431*4882a593Smuzhiyun          */
432*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "h264:level", 40);
433*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "h264:cabac_en", 1);
434*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "h264:cabac_idc", 0);
435*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "h264:trans8x8", 1);
436*4882a593Smuzhiyun     } break;
437*4882a593Smuzhiyun     case MPP_VIDEO_CodingHEVC :
438*4882a593Smuzhiyun     case MPP_VIDEO_CodingMJPEG :
439*4882a593Smuzhiyun     case MPP_VIDEO_CodingVP8 : {
440*4882a593Smuzhiyun     } break;
441*4882a593Smuzhiyun     default : {
442*4882a593Smuzhiyun         mpp_err_f("unsupport encoder coding type %d\n", p->type);
443*4882a593Smuzhiyun     } break;
444*4882a593Smuzhiyun     }
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun     p->split_mode = 0;
447*4882a593Smuzhiyun     p->split_arg = 0;
448*4882a593Smuzhiyun     p->split_out = 0;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun     mpp_env_get_u32("split_mode", &p->split_mode, MPP_ENC_SPLIT_NONE);
451*4882a593Smuzhiyun     mpp_env_get_u32("split_arg", &p->split_arg, 0);
452*4882a593Smuzhiyun     mpp_env_get_u32("split_out", &p->split_out, 0);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun     if (p->split_mode) {
455*4882a593Smuzhiyun         mpp_log_q(quiet, "%p split mode %d arg %d out %d\n", ctx,
456*4882a593Smuzhiyun                   p->split_mode, p->split_arg, p->split_out);
457*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "split:mode", p->split_mode);
458*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "split:arg", p->split_arg);
459*4882a593Smuzhiyun         mpp_enc_cfg_set_s32(cfg, "split:out", p->split_out);
460*4882a593Smuzhiyun     }
461*4882a593Smuzhiyun 
462*4882a593Smuzhiyun     // config gop_len and ref cfg
463*4882a593Smuzhiyun     mpp_enc_cfg_set_s32(cfg, "rc:gop", p->gop_len ? p->gop_len : p->fps_out_num * 2);
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun     mpp_env_get_u32("gop_mode", &gop_mode, gop_mode);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun     if (gop_mode) {
468*4882a593Smuzhiyun         mpp_enc_ref_cfg_init(&ref);
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun         if (p->gop_mode < 4)
471*4882a593Smuzhiyun             mpi_enc_gen_ref_cfg(ref, gop_mode);
472*4882a593Smuzhiyun         else
473*4882a593Smuzhiyun             mpi_enc_gen_smart_gop_ref_cfg(ref, p->gop_len, p->vi_len);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun         mpp_enc_cfg_set_ptr(cfg, "rc:ref_cfg", ref);
476*4882a593Smuzhiyun     }
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun     ret = mpi->control(ctx, MPP_ENC_SET_CFG, cfg);
479*4882a593Smuzhiyun     if (ret) {
480*4882a593Smuzhiyun         mpp_err("mpi control enc set cfg failed ret %d\n", ret);
481*4882a593Smuzhiyun         goto RET;
482*4882a593Smuzhiyun     }
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun     if (ref)
485*4882a593Smuzhiyun         mpp_enc_ref_cfg_deinit(&ref);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun     /* optional */
488*4882a593Smuzhiyun     p->sei_mode = MPP_ENC_SEI_MODE_ONE_FRAME;
489*4882a593Smuzhiyun     ret = mpi->control(ctx, MPP_ENC_SET_SEI_CFG, &p->sei_mode);
490*4882a593Smuzhiyun     if (ret) {
491*4882a593Smuzhiyun         mpp_err("mpi control enc set sei cfg failed ret %d\n", ret);
492*4882a593Smuzhiyun         goto RET;
493*4882a593Smuzhiyun     }
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun     if (p->type == MPP_VIDEO_CodingAVC || p->type == MPP_VIDEO_CodingHEVC) {
496*4882a593Smuzhiyun         p->header_mode = MPP_ENC_HEADER_MODE_EACH_IDR;
497*4882a593Smuzhiyun         ret = mpi->control(ctx, MPP_ENC_SET_HEADER_MODE, &p->header_mode);
498*4882a593Smuzhiyun         if (ret) {
499*4882a593Smuzhiyun             mpp_err("mpi control enc set header mode failed ret %d\n", ret);
500*4882a593Smuzhiyun             goto RET;
501*4882a593Smuzhiyun         }
502*4882a593Smuzhiyun     }
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun     /* setup test mode by env */
505*4882a593Smuzhiyun     mpp_env_get_u32("osd_enable", &p->osd_enable, 0);
506*4882a593Smuzhiyun     mpp_env_get_u32("osd_mode", &p->osd_mode, MPP_ENC_OSD_PLT_TYPE_DEFAULT);
507*4882a593Smuzhiyun     mpp_env_get_u32("roi_enable", &p->roi_enable, 0);
508*4882a593Smuzhiyun     mpp_env_get_u32("user_data_enable", &p->user_data_enable, 0);
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun     if (p->roi_enable) {
511*4882a593Smuzhiyun         mpp_enc_roi_init(&p->roi_ctx, p->width, p->height, p->type, 4);
512*4882a593Smuzhiyun         mpp_assert(p->roi_ctx);
513*4882a593Smuzhiyun     }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun RET:
516*4882a593Smuzhiyun     return ret;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun 
mt_test_res_init(MpiEncMtCtxInfo * info)519*4882a593Smuzhiyun MPP_RET mt_test_res_init(MpiEncMtCtxInfo *info)
520*4882a593Smuzhiyun {
521*4882a593Smuzhiyun     MpiEncTestArgs *cmd = info->cmd;
522*4882a593Smuzhiyun     MpiEncMtTestData *p = &info->ctx;
523*4882a593Smuzhiyun     MppPollType timeout = MPP_POLL_NON_BLOCK;
524*4882a593Smuzhiyun     RK_U32 quiet = cmd->quiet;
525*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
526*4882a593Smuzhiyun     RK_S32 i;
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun     mpp_log_q(quiet, "%s start\n", info->name);
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun     p->list_buf = new mpp_list(NULL);
531*4882a593Smuzhiyun     if (NULL == p->list_buf) {
532*4882a593Smuzhiyun         mpp_err_f("failed to get mpp buffer list\n");
533*4882a593Smuzhiyun         return MPP_ERR_MALLOC;
534*4882a593Smuzhiyun     }
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun     ret = mpp_buffer_group_get_internal(&p->buf_grp, MPP_BUFFER_TYPE_DRM);
537*4882a593Smuzhiyun     if (ret) {
538*4882a593Smuzhiyun         mpp_err_f("failed to get mpp buffer group ret %d\n", ret);
539*4882a593Smuzhiyun         return ret;
540*4882a593Smuzhiyun     }
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun     for (i = 0; i < BUF_COUNT; i++) {
543*4882a593Smuzhiyun         ret = mpp_buffer_get(p->buf_grp, &p->frm_buf[i], p->frame_size + p->header_size);
544*4882a593Smuzhiyun         if (ret) {
545*4882a593Smuzhiyun             mpp_err_f("failed to get buffer for input frame ret %d\n", ret);
546*4882a593Smuzhiyun             return ret;
547*4882a593Smuzhiyun         }
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun         ret = mpp_buffer_get(p->buf_grp, &p->pkt_buf[i], p->frame_size);
550*4882a593Smuzhiyun         if (ret) {
551*4882a593Smuzhiyun             mpp_err_f("failed to get buffer for output packet ret %d\n", ret);
552*4882a593Smuzhiyun             return ret;
553*4882a593Smuzhiyun         }
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun         p->list_buf->add_at_tail(&p->frm_buf[i], sizeof(p->frm_buf[i]));
556*4882a593Smuzhiyun     }
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun     // encoder demo
559*4882a593Smuzhiyun     ret = mpp_create(&p->ctx, &p->mpi);
560*4882a593Smuzhiyun     if (ret) {
561*4882a593Smuzhiyun         mpp_err("mpp_create failed ret %d\n", ret);
562*4882a593Smuzhiyun         return ret;
563*4882a593Smuzhiyun     }
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun     mpp_log_q(quiet, "%p encoder test start w %d h %d type %d\n",
566*4882a593Smuzhiyun               p->ctx, p->width, p->height, p->type);
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun     ret = p->mpi->control(p->ctx, MPP_SET_INPUT_TIMEOUT, &timeout);
569*4882a593Smuzhiyun     if (ret) {
570*4882a593Smuzhiyun         mpp_err("mpi control set input timeout %d ret %d\n", timeout, ret);
571*4882a593Smuzhiyun         return ret;
572*4882a593Smuzhiyun     }
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun     timeout = MPP_POLL_BLOCK;
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun     ret = p->mpi->control(p->ctx, MPP_SET_OUTPUT_TIMEOUT, &timeout);
577*4882a593Smuzhiyun     if (ret) {
578*4882a593Smuzhiyun         mpp_err("mpi control set output timeout %d ret %d\n", timeout, ret);
579*4882a593Smuzhiyun         return ret;
580*4882a593Smuzhiyun     }
581*4882a593Smuzhiyun 
582*4882a593Smuzhiyun     ret = mpp_init(p->ctx, MPP_CTX_ENC, p->type);
583*4882a593Smuzhiyun     if (ret) {
584*4882a593Smuzhiyun         mpp_err("mpp_init failed ret %d\n", ret);
585*4882a593Smuzhiyun         return ret;
586*4882a593Smuzhiyun     }
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun     ret = mpp_enc_cfg_init(&p->cfg);
589*4882a593Smuzhiyun     if (ret) {
590*4882a593Smuzhiyun         mpp_err_f("mpp_enc_cfg_init failed ret %d\n", ret);
591*4882a593Smuzhiyun         return ret;
592*4882a593Smuzhiyun     }
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun     ret = p->mpi->control(p->ctx, MPP_ENC_GET_CFG, p->cfg);
595*4882a593Smuzhiyun     if (ret) {
596*4882a593Smuzhiyun         mpp_err_f("get enc cfg failed ret %d\n", ret);
597*4882a593Smuzhiyun         return ret;
598*4882a593Smuzhiyun     }
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun     ret = test_mt_cfg_setup(info);
601*4882a593Smuzhiyun     if (ret) {
602*4882a593Smuzhiyun         mpp_err_f("test mpp setup failed ret %d\n", ret);
603*4882a593Smuzhiyun     }
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun     return ret;
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun 
mt_test_res_deinit(MpiEncMtCtxInfo * info)608*4882a593Smuzhiyun MPP_RET mt_test_res_deinit(MpiEncMtCtxInfo *info)
609*4882a593Smuzhiyun {
610*4882a593Smuzhiyun     MpiEncMtTestData *p = &info->ctx;
611*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
612*4882a593Smuzhiyun     RK_S32 i;
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun     p->mpi->reset(p->ctx);
615*4882a593Smuzhiyun     if (ret) {
616*4882a593Smuzhiyun         mpp_err("mpi->reset failed\n");
617*4882a593Smuzhiyun         return ret;
618*4882a593Smuzhiyun     }
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun     if (p->ctx) {
621*4882a593Smuzhiyun         mpp_destroy(p->ctx);
622*4882a593Smuzhiyun         p->ctx = NULL;
623*4882a593Smuzhiyun     }
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun     if (p->cfg) {
626*4882a593Smuzhiyun         mpp_enc_cfg_deinit(p->cfg);
627*4882a593Smuzhiyun         p->cfg = NULL;
628*4882a593Smuzhiyun     }
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun     for (i = 0; i < BUF_COUNT; i++) {
631*4882a593Smuzhiyun         if (p->frm_buf[i]) {
632*4882a593Smuzhiyun             mpp_buffer_put(p->frm_buf[i]);
633*4882a593Smuzhiyun             p->frm_buf[i] = NULL;
634*4882a593Smuzhiyun         }
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun         if (p->pkt_buf[i]) {
637*4882a593Smuzhiyun             mpp_buffer_put(p->pkt_buf[i]);
638*4882a593Smuzhiyun             p->pkt_buf[i] = NULL;
639*4882a593Smuzhiyun         }
640*4882a593Smuzhiyun     }
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun     if (p->osd_data.buf) {
643*4882a593Smuzhiyun         mpp_buffer_put(p->osd_data.buf);
644*4882a593Smuzhiyun         p->osd_data.buf = NULL;
645*4882a593Smuzhiyun     }
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun     if (p->buf_grp) {
648*4882a593Smuzhiyun         mpp_buffer_group_put(p->buf_grp);
649*4882a593Smuzhiyun         p->buf_grp = NULL;
650*4882a593Smuzhiyun     }
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun     if (p->list_buf) {
653*4882a593Smuzhiyun         delete p->list_buf;
654*4882a593Smuzhiyun         p->list_buf = NULL;
655*4882a593Smuzhiyun     }
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun     if (p->roi_ctx) {
658*4882a593Smuzhiyun         mpp_enc_roi_deinit(p->roi_ctx);
659*4882a593Smuzhiyun         p->roi_ctx = NULL;
660*4882a593Smuzhiyun     }
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun     return MPP_OK;
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun 
enc_test_input(void * arg)665*4882a593Smuzhiyun void *enc_test_input(void *arg)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun     MpiEncMtCtxInfo *info = (MpiEncMtCtxInfo *)arg;
668*4882a593Smuzhiyun     MpiEncTestArgs *cmd = info->cmd;
669*4882a593Smuzhiyun     MpiEncMtTestData *p = &info->ctx;
670*4882a593Smuzhiyun     RK_S32 chn = info->chn;
671*4882a593Smuzhiyun     MppApi *mpi = p->mpi;
672*4882a593Smuzhiyun     MppCtx ctx = p->ctx;
673*4882a593Smuzhiyun     mpp_list *list_buf = p->list_buf;
674*4882a593Smuzhiyun     RK_U32 cap_num = 0;
675*4882a593Smuzhiyun     RK_U32 quiet = cmd->quiet;
676*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun     mpp_log_q(quiet, "%s start\n", info->name);
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun     while (1) {
681*4882a593Smuzhiyun         MppMeta meta = NULL;
682*4882a593Smuzhiyun         MppFrame frame = NULL;
683*4882a593Smuzhiyun         MppBuffer buffer = NULL;
684*4882a593Smuzhiyun         void *buf = NULL;
685*4882a593Smuzhiyun         RK_S32 cam_frm_idx = -1;
686*4882a593Smuzhiyun         MppBuffer cam_buf = NULL;
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun         {
689*4882a593Smuzhiyun             AutoMutex autolock(list_buf->mutex());
690*4882a593Smuzhiyun             if (!list_buf->list_size())
691*4882a593Smuzhiyun                 list_buf->wait();
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun             buffer = NULL;
694*4882a593Smuzhiyun             list_buf->del_at_head(&buffer, sizeof(buffer));
695*4882a593Smuzhiyun             if (NULL == buffer)
696*4882a593Smuzhiyun                 continue;
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun             buf = mpp_buffer_get_ptr(buffer);
699*4882a593Smuzhiyun         }
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun         if (p->fp_input) {
702*4882a593Smuzhiyun             ret = read_image((RK_U8 *)buf, p->fp_input, p->width, p->height,
703*4882a593Smuzhiyun                              p->hor_stride, p->ver_stride, p->fmt);
704*4882a593Smuzhiyun             if (ret == MPP_NOK || feof(p->fp_input)) {
705*4882a593Smuzhiyun                 p->frm_eos = 1;
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun                 if (p->frame_num < 0 || p->frm_cnt_in < p->frame_num) {
708*4882a593Smuzhiyun                     clearerr(p->fp_input);
709*4882a593Smuzhiyun                     rewind(p->fp_input);
710*4882a593Smuzhiyun                     p->frm_eos = 0;
711*4882a593Smuzhiyun                     mpp_log_q(quiet, "chn %d loop times %d\n", chn, ++p->loop_times);
712*4882a593Smuzhiyun                     continue;
713*4882a593Smuzhiyun                 }
714*4882a593Smuzhiyun                 mpp_log_q(quiet, "chn %d found last frame. feof %d\n", chn, feof(p->fp_input));
715*4882a593Smuzhiyun             } else if (ret == MPP_ERR_VALUE)
716*4882a593Smuzhiyun                 break;
717*4882a593Smuzhiyun         } else {
718*4882a593Smuzhiyun             if (p->cam_ctx == NULL) {
719*4882a593Smuzhiyun                 ret = fill_image((RK_U8 *)buf, p->width, p->height, p->hor_stride,
720*4882a593Smuzhiyun                                  p->ver_stride, p->fmt, p->frm_cnt_in);
721*4882a593Smuzhiyun                 if (ret)
722*4882a593Smuzhiyun                     break;
723*4882a593Smuzhiyun             } else {
724*4882a593Smuzhiyun                 cam_frm_idx = camera_source_get_frame(p->cam_ctx);
725*4882a593Smuzhiyun                 mpp_assert(cam_frm_idx >= 0);
726*4882a593Smuzhiyun 
727*4882a593Smuzhiyun                 /* skip unstable frames */
728*4882a593Smuzhiyun                 if (cap_num++ < 50) {
729*4882a593Smuzhiyun                     camera_source_put_frame(p->cam_ctx, cam_frm_idx);
730*4882a593Smuzhiyun                     continue;
731*4882a593Smuzhiyun                 }
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun                 cam_buf = camera_frame_to_buf(p->cam_ctx, cam_frm_idx);
734*4882a593Smuzhiyun                 mpp_assert(cam_buf);
735*4882a593Smuzhiyun             }
736*4882a593Smuzhiyun         }
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun         ret = mpp_frame_init(&frame);
739*4882a593Smuzhiyun         if (ret) {
740*4882a593Smuzhiyun             mpp_err_f("mpp_frame_init failed\n");
741*4882a593Smuzhiyun             break;
742*4882a593Smuzhiyun         }
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun         mpp_frame_set_width(frame, p->width);
745*4882a593Smuzhiyun         mpp_frame_set_height(frame, p->height);
746*4882a593Smuzhiyun         mpp_frame_set_hor_stride(frame, p->hor_stride);
747*4882a593Smuzhiyun         mpp_frame_set_ver_stride(frame, p->ver_stride);
748*4882a593Smuzhiyun         mpp_frame_set_fmt(frame, p->fmt);
749*4882a593Smuzhiyun         mpp_frame_set_eos(frame, p->frm_eos);
750*4882a593Smuzhiyun 
751*4882a593Smuzhiyun         if (p->fp_input && feof(p->fp_input))
752*4882a593Smuzhiyun             mpp_frame_set_buffer(frame, NULL);
753*4882a593Smuzhiyun         else if (cam_buf)
754*4882a593Smuzhiyun             mpp_frame_set_buffer(frame, cam_buf);
755*4882a593Smuzhiyun         else
756*4882a593Smuzhiyun             mpp_frame_set_buffer(frame, buffer);
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun         meta = mpp_frame_get_meta(frame);
759*4882a593Smuzhiyun 
760*4882a593Smuzhiyun         if (p->osd_enable || p->user_data_enable || p->roi_enable) {
761*4882a593Smuzhiyun             if (p->user_data_enable) {
762*4882a593Smuzhiyun                 MppEncUserData user_data;
763*4882a593Smuzhiyun                 const char *str = "this is user data\n";
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun                 if ((p->frm_cnt_in & 10) == 0) {
766*4882a593Smuzhiyun                     user_data.pdata = (void *)str;
767*4882a593Smuzhiyun                     user_data.len = strlen(str) + 1;
768*4882a593Smuzhiyun                     mpp_meta_set_ptr(meta, KEY_USER_DATA, &user_data);
769*4882a593Smuzhiyun                 }
770*4882a593Smuzhiyun                 static RK_U8 uuid_debug_info[16] = {
771*4882a593Smuzhiyun                     0x57, 0x68, 0x97, 0x80, 0xe7, 0x0c, 0x4b, 0x65,
772*4882a593Smuzhiyun                     0xa9, 0x06, 0xae, 0x29, 0x94, 0x11, 0xcd, 0x9a
773*4882a593Smuzhiyun                 };
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun                 MppEncUserDataSet data_group;
776*4882a593Smuzhiyun                 MppEncUserDataFull datas[2];
777*4882a593Smuzhiyun                 const char *str1 = "this is user data 1\n";
778*4882a593Smuzhiyun                 const char *str2 = "this is user data 2\n";
779*4882a593Smuzhiyun                 data_group.count = 2;
780*4882a593Smuzhiyun                 datas[0].len = strlen(str1) + 1;
781*4882a593Smuzhiyun                 datas[0].pdata = (void *)str1;
782*4882a593Smuzhiyun                 datas[0].uuid = uuid_debug_info;
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun                 datas[1].len = strlen(str2) + 1;
785*4882a593Smuzhiyun                 datas[1].pdata = (void *)str2;
786*4882a593Smuzhiyun                 datas[1].uuid = uuid_debug_info;
787*4882a593Smuzhiyun 
788*4882a593Smuzhiyun                 data_group.datas = datas;
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun                 mpp_meta_set_ptr(meta, KEY_USER_DATAS, &data_group);
791*4882a593Smuzhiyun             }
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun             if (p->osd_enable) {
794*4882a593Smuzhiyun                 /* gen and cfg osd plt */
795*4882a593Smuzhiyun                 mpi_enc_gen_osd_plt(&p->osd_plt, p->frm_cnt_in);
796*4882a593Smuzhiyun 
797*4882a593Smuzhiyun                 p->osd_plt_cfg.change = MPP_ENC_OSD_PLT_CFG_CHANGE_ALL;
798*4882a593Smuzhiyun                 p->osd_plt_cfg.type = MPP_ENC_OSD_PLT_TYPE_USERDEF;
799*4882a593Smuzhiyun                 p->osd_plt_cfg.plt = &p->osd_plt;
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun                 ret = mpi->control(ctx, MPP_ENC_SET_OSD_PLT_CFG, &p->osd_plt_cfg);
802*4882a593Smuzhiyun                 if (ret) {
803*4882a593Smuzhiyun                     mpp_err("mpi control enc set osd plt failed ret %d\n", ret);
804*4882a593Smuzhiyun                     break;
805*4882a593Smuzhiyun                 }
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun                 /* gen and cfg osd plt */
808*4882a593Smuzhiyun                 mpi_enc_gen_osd_data(&p->osd_data, p->buf_grp, p->width,
809*4882a593Smuzhiyun                                      p->height, p->frm_cnt_in);
810*4882a593Smuzhiyun                 mpp_meta_set_ptr(meta, KEY_OSD_DATA, (void*)&p->osd_data);
811*4882a593Smuzhiyun             }
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun             if (p->roi_enable) {
814*4882a593Smuzhiyun                 RoiRegionCfg *region = &p->roi_region;
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun                 /* calculated in pixels */
817*4882a593Smuzhiyun                 region->x = MPP_ALIGN(p->width / 8, 16);
818*4882a593Smuzhiyun                 region->y = MPP_ALIGN(p->height / 8, 16);
819*4882a593Smuzhiyun                 region->w = 128;
820*4882a593Smuzhiyun                 region->h = 256;
821*4882a593Smuzhiyun                 region->force_intra = 0;
822*4882a593Smuzhiyun                 region->qp_mode = 1;
823*4882a593Smuzhiyun                 region->qp_val = 24;
824*4882a593Smuzhiyun 
825*4882a593Smuzhiyun                 mpp_enc_roi_add_region(p->roi_ctx, region);
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun                 region->x = MPP_ALIGN(p->width / 2, 16);
828*4882a593Smuzhiyun                 region->y = MPP_ALIGN(p->height / 4, 16);
829*4882a593Smuzhiyun                 region->w = 256;
830*4882a593Smuzhiyun                 region->h = 128;
831*4882a593Smuzhiyun                 region->force_intra = 1;
832*4882a593Smuzhiyun                 region->qp_mode = 1;
833*4882a593Smuzhiyun                 region->qp_val = 10;
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun                 mpp_enc_roi_add_region(p->roi_ctx, region);
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun                 /* send roi info by metadata */
838*4882a593Smuzhiyun                 mpp_enc_roi_setup_meta(p->roi_ctx, meta);
839*4882a593Smuzhiyun             }
840*4882a593Smuzhiyun         }
841*4882a593Smuzhiyun 
842*4882a593Smuzhiyun         if (!p->first_frm)
843*4882a593Smuzhiyun             p->first_frm = mpp_time();
844*4882a593Smuzhiyun         /*
845*4882a593Smuzhiyun          * NOTE: in non-block mode the frame can be resent.
846*4882a593Smuzhiyun          * The default input timeout mode is block.
847*4882a593Smuzhiyun          *
848*4882a593Smuzhiyun          * User should release the input frame to meet the requirements of
849*4882a593Smuzhiyun          * resource creator must be the resource destroyer.
850*4882a593Smuzhiyun          */
851*4882a593Smuzhiyun         p->frm_cnt_in++;
852*4882a593Smuzhiyun         do {
853*4882a593Smuzhiyun             ret = mpi->encode_put_frame(ctx, frame);
854*4882a593Smuzhiyun             if (ret)
855*4882a593Smuzhiyun                 msleep(1);
856*4882a593Smuzhiyun         } while (ret);
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun         if (cam_frm_idx >= 0)
859*4882a593Smuzhiyun             camera_source_put_frame(p->cam_ctx, cam_frm_idx);
860*4882a593Smuzhiyun 
861*4882a593Smuzhiyun         if (p->frame_num > 0 && p->frm_cnt_in >= p->frame_num) {
862*4882a593Smuzhiyun             p->frm_eos = 1;
863*4882a593Smuzhiyun             break;
864*4882a593Smuzhiyun         }
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun         if (p->loop_end) {
867*4882a593Smuzhiyun             p->frm_eos = 1;
868*4882a593Smuzhiyun             break;
869*4882a593Smuzhiyun         }
870*4882a593Smuzhiyun 
871*4882a593Smuzhiyun         if (p->frm_eos)
872*4882a593Smuzhiyun             break;
873*4882a593Smuzhiyun     }
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun     return NULL;
876*4882a593Smuzhiyun }
877*4882a593Smuzhiyun 
enc_test_output(void * arg)878*4882a593Smuzhiyun void *enc_test_output(void *arg)
879*4882a593Smuzhiyun {
880*4882a593Smuzhiyun     MpiEncMtCtxInfo *info = (MpiEncMtCtxInfo *)arg;
881*4882a593Smuzhiyun     MpiEncTestArgs *cmd = info->cmd;
882*4882a593Smuzhiyun     MpiEncMtTestData *p = &info->ctx;
883*4882a593Smuzhiyun     MpiEncMtCtxRet *enc_ret = &info->ret;
884*4882a593Smuzhiyun     mpp_list *list_buf = p->list_buf;
885*4882a593Smuzhiyun     RK_S32 chn = info->chn;
886*4882a593Smuzhiyun     MppApi *mpi = p->mpi;
887*4882a593Smuzhiyun     MppCtx ctx = p->ctx;
888*4882a593Smuzhiyun     RK_U32 quiet = cmd->quiet;
889*4882a593Smuzhiyun     MPP_RET ret = MPP_OK;
890*4882a593Smuzhiyun     MppPacket packet = NULL;
891*4882a593Smuzhiyun     RK_U32 eoi = 1;
892*4882a593Smuzhiyun 
893*4882a593Smuzhiyun     void *ptr;
894*4882a593Smuzhiyun     size_t len;
895*4882a593Smuzhiyun     char log_buf[256];
896*4882a593Smuzhiyun     RK_S32 log_size = sizeof(log_buf) - 1;
897*4882a593Smuzhiyun     RK_S32 log_len = 0;
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun     while (1) {
900*4882a593Smuzhiyun         ret = mpi->encode_get_packet(ctx, &packet);
901*4882a593Smuzhiyun         if (ret || NULL == packet) {
902*4882a593Smuzhiyun             msleep(1);
903*4882a593Smuzhiyun             continue;
904*4882a593Smuzhiyun         }
905*4882a593Smuzhiyun 
906*4882a593Smuzhiyun         p->last_pkt = mpp_time();
907*4882a593Smuzhiyun 
908*4882a593Smuzhiyun         // write packet to file here
909*4882a593Smuzhiyun         ptr = mpp_packet_get_pos(packet);
910*4882a593Smuzhiyun         len = mpp_packet_get_length(packet);
911*4882a593Smuzhiyun         log_size = sizeof(log_buf) - 1;
912*4882a593Smuzhiyun         log_len = 0;
913*4882a593Smuzhiyun 
914*4882a593Smuzhiyun         if (!p->first_pkt)
915*4882a593Smuzhiyun             p->first_pkt = mpp_time();
916*4882a593Smuzhiyun 
917*4882a593Smuzhiyun         p->pkt_eos = mpp_packet_get_eos(packet);
918*4882a593Smuzhiyun 
919*4882a593Smuzhiyun         if (p->fp_output)
920*4882a593Smuzhiyun             fwrite(ptr, 1, len, p->fp_output);
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun         log_len += snprintf(log_buf + log_len, log_size - log_len,
923*4882a593Smuzhiyun                             "encoded frame %-4d", p->frm_cnt_out);
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun         /* for low delay partition encoding */
926*4882a593Smuzhiyun         if (mpp_packet_is_partition(packet)) {
927*4882a593Smuzhiyun             eoi = mpp_packet_is_eoi(packet);
928*4882a593Smuzhiyun 
929*4882a593Smuzhiyun             log_len += snprintf(log_buf + log_len, log_size - log_len,
930*4882a593Smuzhiyun                                 " pkt %d", p->frm_pkt_cnt);
931*4882a593Smuzhiyun             p->frm_pkt_cnt = (eoi) ? (0) : (p->frm_pkt_cnt + 1);
932*4882a593Smuzhiyun         }
933*4882a593Smuzhiyun 
934*4882a593Smuzhiyun         log_len += snprintf(log_buf + log_len, log_size - log_len,
935*4882a593Smuzhiyun                             " size %-7zu", len);
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun         if (mpp_packet_has_meta(packet)) {
938*4882a593Smuzhiyun             MppMeta meta = mpp_packet_get_meta(packet);
939*4882a593Smuzhiyun             MppFrame frm = NULL;
940*4882a593Smuzhiyun             RK_S32 temporal_id = 0;
941*4882a593Smuzhiyun             RK_S32 lt_idx = -1;
942*4882a593Smuzhiyun             RK_S32 avg_qp = -1;
943*4882a593Smuzhiyun 
944*4882a593Smuzhiyun             if (MPP_OK == mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &temporal_id))
945*4882a593Smuzhiyun                 log_len += snprintf(log_buf + log_len, log_size - log_len,
946*4882a593Smuzhiyun                                     " tid %d", temporal_id);
947*4882a593Smuzhiyun 
948*4882a593Smuzhiyun             if (MPP_OK == mpp_meta_get_s32(meta, KEY_LONG_REF_IDX, &lt_idx))
949*4882a593Smuzhiyun                 log_len += snprintf(log_buf + log_len, log_size - log_len,
950*4882a593Smuzhiyun                                     " lt %d", lt_idx);
951*4882a593Smuzhiyun 
952*4882a593Smuzhiyun             if (MPP_OK == mpp_meta_get_s32(meta, KEY_ENC_AVERAGE_QP, &avg_qp))
953*4882a593Smuzhiyun                 log_len += snprintf(log_buf + log_len, log_size - log_len,
954*4882a593Smuzhiyun                                     " qp %d", avg_qp);
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun             if (MPP_OK == mpp_meta_get_frame(meta, KEY_INPUT_FRAME, &frm)) {
957*4882a593Smuzhiyun                 MppBuffer frm_buf = NULL;
958*4882a593Smuzhiyun 
959*4882a593Smuzhiyun                 mpp_assert(frm);
960*4882a593Smuzhiyun                 frm_buf = mpp_frame_get_buffer(frm);
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun                 if (frm_buf) {
963*4882a593Smuzhiyun                     AutoMutex autolock(list_buf->mutex());
964*4882a593Smuzhiyun                     list_buf->add_at_tail(&frm_buf, sizeof(frm_buf));
965*4882a593Smuzhiyun                     list_buf->signal();
966*4882a593Smuzhiyun                 }
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun                 mpp_frame_deinit(&frm);
969*4882a593Smuzhiyun             }
970*4882a593Smuzhiyun         }
971*4882a593Smuzhiyun 
972*4882a593Smuzhiyun         mpp_log_q(quiet, "chn %d %s\n", chn, log_buf);
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun         mpp_packet_deinit(&packet);
975*4882a593Smuzhiyun         fps_calc_inc(cmd->fps);
976*4882a593Smuzhiyun 
977*4882a593Smuzhiyun         p->stream_size += len;
978*4882a593Smuzhiyun         p->frm_cnt_out += eoi;
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun         if (p->frm_cnt_out != p->frm_cnt_in)
981*4882a593Smuzhiyun             continue;
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun         if (p->frame_num > 0 && p->frm_cnt_out >= p->frame_num) {
984*4882a593Smuzhiyun             p->pkt_eos = 1;
985*4882a593Smuzhiyun             break;
986*4882a593Smuzhiyun         }
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun         if (p->frm_eos) {
989*4882a593Smuzhiyun             p->pkt_eos = 1;
990*4882a593Smuzhiyun             break;
991*4882a593Smuzhiyun         }
992*4882a593Smuzhiyun 
993*4882a593Smuzhiyun         if (p->pkt_eos) {
994*4882a593Smuzhiyun             mpp_log_q(quiet, "chn %d found last packet\n", chn);
995*4882a593Smuzhiyun             mpp_assert(p->frm_eos);
996*4882a593Smuzhiyun             break;
997*4882a593Smuzhiyun         }
998*4882a593Smuzhiyun     } while (!eoi);
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun     enc_ret->elapsed_time = p->last_pkt - p->first_frm;
1001*4882a593Smuzhiyun     enc_ret->frame_count = p->frm_cnt_out;
1002*4882a593Smuzhiyun     enc_ret->stream_size = p->stream_size;
1003*4882a593Smuzhiyun     enc_ret->frame_rate = (float)p->frm_cnt_out * 1000000 / enc_ret->elapsed_time;
1004*4882a593Smuzhiyun     enc_ret->bit_rate = (p->stream_size * 8 * (p->fps_out_num / p->fps_out_den)) / p->frm_cnt_out;
1005*4882a593Smuzhiyun     enc_ret->delay = p->first_pkt - p->first_frm;
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun     return NULL;
1008*4882a593Smuzhiyun }
1009*4882a593Smuzhiyun 
enc_test_mt(MpiEncTestArgs * cmd,const char * name)1010*4882a593Smuzhiyun int enc_test_mt(MpiEncTestArgs* cmd, const char *name)
1011*4882a593Smuzhiyun {
1012*4882a593Smuzhiyun     MpiEncMtCtxInfo *ctxs = NULL;
1013*4882a593Smuzhiyun     float total_rate = 0.0;
1014*4882a593Smuzhiyun     RK_S32 ret = MPP_NOK;
1015*4882a593Smuzhiyun     RK_S32 i = 0;
1016*4882a593Smuzhiyun 
1017*4882a593Smuzhiyun     ctxs = mpp_calloc(MpiEncMtCtxInfo, cmd->nthreads);
1018*4882a593Smuzhiyun     if (NULL == ctxs) {
1019*4882a593Smuzhiyun         mpp_err("failed to alloc context for instances\n");
1020*4882a593Smuzhiyun         return -1;
1021*4882a593Smuzhiyun     }
1022*4882a593Smuzhiyun 
1023*4882a593Smuzhiyun     for (i = 0; i < cmd->nthreads; i++) {
1024*4882a593Smuzhiyun         ctxs[i].cmd = cmd;
1025*4882a593Smuzhiyun         ctxs[i].name = name;
1026*4882a593Smuzhiyun         ctxs[i].chn = i;
1027*4882a593Smuzhiyun 
1028*4882a593Smuzhiyun         ret = mt_test_ctx_init(&ctxs[i]);
1029*4882a593Smuzhiyun         if (ret) {
1030*4882a593Smuzhiyun             mpp_err_f("test ctx init failed ret %d\n", ret);
1031*4882a593Smuzhiyun             return ret;
1032*4882a593Smuzhiyun         }
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun         ret = mt_test_res_init(&ctxs[i]);
1035*4882a593Smuzhiyun         if (ret) {
1036*4882a593Smuzhiyun             mpp_err_f("test resource deinit failed ret %d\n", ret);
1037*4882a593Smuzhiyun             return ret;
1038*4882a593Smuzhiyun         }
1039*4882a593Smuzhiyun 
1040*4882a593Smuzhiyun         ret = pthread_create(&ctxs[i].thd_out, NULL, enc_test_output, &ctxs[i]);
1041*4882a593Smuzhiyun         if (ret) {
1042*4882a593Smuzhiyun             mpp_err("failed to create thread %d\n", i);
1043*4882a593Smuzhiyun             return ret;
1044*4882a593Smuzhiyun         }
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun         ret = pthread_create(&ctxs[i].thd_in, NULL, enc_test_input, &ctxs[i]);
1047*4882a593Smuzhiyun         if (ret) {
1048*4882a593Smuzhiyun             mpp_err("failed to create thread %d\n", i);
1049*4882a593Smuzhiyun             return ret;
1050*4882a593Smuzhiyun         }
1051*4882a593Smuzhiyun     }
1052*4882a593Smuzhiyun 
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun     if (cmd->frame_num < 0) {
1055*4882a593Smuzhiyun         // wait for input then quit encoding
1056*4882a593Smuzhiyun         mpp_log("*******************************************\n");
1057*4882a593Smuzhiyun         mpp_log("**** Press Enter to stop loop encoding ****\n");
1058*4882a593Smuzhiyun         mpp_log("*******************************************\n");
1059*4882a593Smuzhiyun 
1060*4882a593Smuzhiyun         getc(stdin);
1061*4882a593Smuzhiyun         for (i = 0; i < cmd->nthreads; i++)
1062*4882a593Smuzhiyun             ctxs[i].ctx.loop_end = 1;
1063*4882a593Smuzhiyun     }
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun     for (i = 0; i < cmd->nthreads; i++) {
1066*4882a593Smuzhiyun         pthread_join(ctxs[i].thd_in, NULL);
1067*4882a593Smuzhiyun         pthread_join(ctxs[i].thd_out, NULL);
1068*4882a593Smuzhiyun 
1069*4882a593Smuzhiyun         ret = mt_test_res_deinit(&ctxs[i]);
1070*4882a593Smuzhiyun         if (ret) {
1071*4882a593Smuzhiyun             mpp_err_f("test resource deinit failed ret %d\n", ret);
1072*4882a593Smuzhiyun             return ret;
1073*4882a593Smuzhiyun         }
1074*4882a593Smuzhiyun 
1075*4882a593Smuzhiyun         ret = mt_test_ctx_deinit(&ctxs[i]);
1076*4882a593Smuzhiyun         if (ret) {
1077*4882a593Smuzhiyun             mpp_err_f("test ctx deinit failed ret %d\n", ret);
1078*4882a593Smuzhiyun             return ret;
1079*4882a593Smuzhiyun         }
1080*4882a593Smuzhiyun     }
1081*4882a593Smuzhiyun 
1082*4882a593Smuzhiyun     for (i = 0; i < cmd->nthreads; i++) {
1083*4882a593Smuzhiyun         MpiEncMtCtxRet *enc_ret = &ctxs[i].ret;
1084*4882a593Smuzhiyun 
1085*4882a593Smuzhiyun         mpp_log("chn %d encode %d frames time %lld ms delay %3d ms fps %3.2f bps %lld\n",
1086*4882a593Smuzhiyun                 i, enc_ret->frame_count, (RK_S64)(enc_ret->elapsed_time / 1000),
1087*4882a593Smuzhiyun                 (RK_S32)(enc_ret->delay / 1000), enc_ret->frame_rate, enc_ret->bit_rate);
1088*4882a593Smuzhiyun 
1089*4882a593Smuzhiyun         total_rate += enc_ret->frame_rate;
1090*4882a593Smuzhiyun     }
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun     MPP_FREE(ctxs);
1093*4882a593Smuzhiyun 
1094*4882a593Smuzhiyun     total_rate /= cmd->nthreads;
1095*4882a593Smuzhiyun     mpp_log("%s average frame rate %.2f\n", name, total_rate);
1096*4882a593Smuzhiyun 
1097*4882a593Smuzhiyun     return ret;
1098*4882a593Smuzhiyun }
1099*4882a593Smuzhiyun 
main(int argc,char ** argv)1100*4882a593Smuzhiyun int main(int argc, char **argv)
1101*4882a593Smuzhiyun {
1102*4882a593Smuzhiyun     RK_S32 ret = MPP_NOK;
1103*4882a593Smuzhiyun     MpiEncTestArgs* cmd = mpi_enc_test_cmd_get();
1104*4882a593Smuzhiyun 
1105*4882a593Smuzhiyun     // parse the cmd option
1106*4882a593Smuzhiyun     ret = mpi_enc_test_cmd_update_by_args(cmd, argc, argv);
1107*4882a593Smuzhiyun     if (ret)
1108*4882a593Smuzhiyun         goto DONE;
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun     mpi_enc_test_cmd_show_opt(cmd);
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun     ret = enc_test_mt(cmd, argv[0]);
1113*4882a593Smuzhiyun 
1114*4882a593Smuzhiyun DONE:
1115*4882a593Smuzhiyun     mpi_enc_test_cmd_put(cmd);
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun     return ret;
1118*4882a593Smuzhiyun }
1119