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