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, <_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