1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "hwpq_test"
7
8 #include <getopt.h>
9 #include <stdlib.h>
10 #include <stdint.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <pthread.h>
14 #include <errno.h>
15
16 #include "mpp_mem.h"
17 #include "mpp_buffer.h"
18 #include "mpp_log.h"
19
20 #include "hwpq_vdpp_proc_api.h"
21
22 typedef struct {
23 char src_file_name[128];
24 char dst_file_name_y[128];
25 char dst_file_name_uv[128];
26 char dst_file_name_hist[128];
27 unsigned int img_w_i;
28 unsigned int img_h_i;
29 unsigned int img_w_i_vir;
30 unsigned int img_h_i_vir;
31 unsigned int img_w_o;
32 unsigned int img_h_o;
33 unsigned int img_w_o_vir;
34 unsigned int img_h_o_vir;
35 unsigned int uv_diff_flag;
36 unsigned int img_w_o_c;
37 unsigned int img_h_o_c;
38 unsigned int img_w_o_c_vir;
39 unsigned int img_h_o_c_vir;
40
41 unsigned int work_mode;
42
43 int32_t nthreads;
44 int32_t frame_num;
45 } VdppCmdCfg;
46
47 typedef struct {
48 int chn;
49
50 FILE *fp_i;
51 FILE *fp_o_y;
52 FILE *fp_o_uv;
53 FILE *fp_o_h;
54
55 unsigned int frm_eos;
56 unsigned int loop_times;
57 } VdppTestMultiCtx;
58
59 typedef struct {
60 VdppCmdCfg *cmd;
61 int chn;
62
63 pthread_t thd; // thread for for each instance
64 VdppTestMultiCtx ctx; // context of vdpp
65 } VdppTestMultiCtxInfo;
66
67 static void parse_cmd(char** argv, int argc, VdppCmdCfg* p_cmd_cfg);
68
69 extern char *optarg;
70 extern int opterr;
71
multi_vdpp(void * cmd_ctx)72 static void *multi_vdpp(void *cmd_ctx)
73 {
74 VdppTestMultiCtxInfo *info = (VdppTestMultiCtxInfo *)cmd_ctx;
75 VdppTestMultiCtx *ctx = &info->ctx;
76 VdppCmdCfg *p_cmd_cfg = info->cmd;
77
78 rk_vdpp_context vdpp_ctx;
79 rk_vdpp_proc_params vdpp_proc_cfg;
80
81 // cmd config params
82 if (p_cmd_cfg->uv_diff_flag == 0) {
83 p_cmd_cfg->img_w_o_c = p_cmd_cfg->img_w_o;
84 p_cmd_cfg->img_h_o_c = p_cmd_cfg->img_h_o;
85 p_cmd_cfg->img_w_o_c_vir = p_cmd_cfg->img_w_o_vir;
86 p_cmd_cfg->img_h_o_c_vir = p_cmd_cfg->img_h_o_vir;
87 }
88
89 size_t srcfrmsize = p_cmd_cfg->img_w_i_vir * p_cmd_cfg->img_h_i_vir * 3 / 2;
90 size_t dstfrmsize = p_cmd_cfg->img_w_o_vir * p_cmd_cfg->img_h_o_vir * 3;
91 size_t dstfrmsize_c = p_cmd_cfg->img_w_o_c_vir * p_cmd_cfg->img_h_o_c_vir * 2;
92
93 // malloc buffers
94 MppBuffer srcbuf;
95 MppBuffer dstbuf;
96 MppBuffer dstbuf_c;
97 MppBuffer histbuf;
98 void *psrc = NULL;
99 void *pdst = NULL;
100 void *phist = NULL;
101 RK_S32 fdsrc = -1;
102 RK_S32 fddst = -1;
103 RK_S32 fdhist = -1;
104 int frame_idx = 0;
105 MppBufferGroup memGroup;
106 MPP_RET ret = mpp_buffer_group_get_internal(&memGroup, MPP_BUFFER_TYPE_DRM);
107 if (MPP_OK != ret) {
108 mpp_err("memGroup mpp_buffer_group_get failed\n");
109 return NULL;
110 }
111
112 mpp_buffer_get(memGroup, &srcbuf, srcfrmsize);
113 mpp_buffer_get(memGroup, &dstbuf, dstfrmsize);
114 mpp_buffer_get(memGroup, &dstbuf_c, dstfrmsize_c);
115 mpp_buffer_get(memGroup, &histbuf, VDPP_HIST_LENGTH);
116 psrc = mpp_buffer_get_ptr(srcbuf);
117 pdst = mpp_buffer_get_ptr(dstbuf);
118 phist = mpp_buffer_get_ptr(histbuf);
119
120 fdsrc = mpp_buffer_get_fd(srcbuf);
121 fddst = mpp_buffer_get_fd(dstbuf);
122 fdhist = mpp_buffer_get_fd(histbuf);
123
124 hwpq_vdpp_init(&vdpp_ctx);
125
126 ctx->chn = info->chn;
127
128 ctx->fp_i = fopen(p_cmd_cfg->src_file_name, "rb");
129 if (!ctx->fp_i) {
130 mpp_err("failed to open file %s", p_cmd_cfg->src_file_name);
131 goto __RET;
132 }
133
134 ctx->fp_o_y = fopen(p_cmd_cfg->dst_file_name_y, "wb");
135 ctx->fp_o_uv = fopen(p_cmd_cfg->dst_file_name_uv, "wb");
136 ctx->fp_o_h = fopen(p_cmd_cfg->dst_file_name_hist, "wb");
137
138 while (1) {
139 vdpp_proc_cfg.frame_idx = frame_idx;
140
141 if ((srcfrmsize > fread(psrc, 1, srcfrmsize, ctx->fp_i)) || feof(ctx->fp_i)) {
142 ctx->frm_eos = 1;
143
144 if (p_cmd_cfg->frame_num < 0 || frame_idx < p_cmd_cfg->frame_num) {
145 clearerr(ctx->fp_i);
146 rewind(ctx->fp_i);
147 ctx->frm_eos = 0;
148 mpp_log("chn %d loop times %d\n", ctx->chn, ++ctx->loop_times);
149 continue;
150 }
151 mpp_log("chn %d found last frame. feof %d\n", ctx->chn, feof(ctx->fp_i));
152 } else if (ret == MPP_ERR_VALUE)
153 break;
154
155 vdpp_proc_cfg.src_img_info.img_fmt = VDPP_FMT_NV12;
156 vdpp_proc_cfg.src_img_info.img_yrgb.fd = fdsrc;
157 vdpp_proc_cfg.src_img_info.img_yrgb.addr = psrc;
158 vdpp_proc_cfg.src_img_info.img_yrgb.offset = 0;
159 vdpp_proc_cfg.src_img_info.img_yrgb.w_vld = p_cmd_cfg->img_w_i;
160 vdpp_proc_cfg.src_img_info.img_yrgb.h_vld = p_cmd_cfg->img_h_i;
161 vdpp_proc_cfg.src_img_info.img_yrgb.w_vir = p_cmd_cfg->img_w_i_vir;
162 vdpp_proc_cfg.src_img_info.img_yrgb.h_vir = p_cmd_cfg->img_h_i_vir;
163
164 vdpp_proc_cfg.src_img_info.img_cbcr.fd = fdsrc;
165 vdpp_proc_cfg.src_img_info.img_cbcr.addr = psrc;
166 vdpp_proc_cfg.src_img_info.img_cbcr.offset = p_cmd_cfg->img_w_i_vir * p_cmd_cfg->img_h_i_vir;
167 vdpp_proc_cfg.src_img_info.img_cbcr.w_vld = p_cmd_cfg->img_w_i / 2;
168 vdpp_proc_cfg.src_img_info.img_cbcr.h_vld = p_cmd_cfg->img_h_i / 2;
169 vdpp_proc_cfg.src_img_info.img_cbcr.w_vir = p_cmd_cfg->img_w_i_vir;
170 vdpp_proc_cfg.src_img_info.img_cbcr.h_vir = p_cmd_cfg->img_h_i_vir / 2;
171
172 vdpp_proc_cfg.dst_img_info.img_fmt = VDPP_FMT_NV24;
173 vdpp_proc_cfg.dst_img_info.img_yrgb.fd = fddst;
174 vdpp_proc_cfg.dst_img_info.img_yrgb.addr = pdst;
175 vdpp_proc_cfg.dst_img_info.img_yrgb.offset = 0;
176 vdpp_proc_cfg.dst_img_info.img_yrgb.w_vld = p_cmd_cfg->img_w_o;
177 vdpp_proc_cfg.dst_img_info.img_yrgb.h_vld = p_cmd_cfg->img_h_o;
178 vdpp_proc_cfg.dst_img_info.img_yrgb.w_vir = p_cmd_cfg->img_w_o_vir;
179 vdpp_proc_cfg.dst_img_info.img_yrgb.h_vir = p_cmd_cfg->img_h_o_vir;
180
181 vdpp_proc_cfg.dst_img_info.img_cbcr.fd = fddst;
182 vdpp_proc_cfg.dst_img_info.img_cbcr.addr = pdst;
183 vdpp_proc_cfg.dst_img_info.img_cbcr.offset = p_cmd_cfg->img_w_o_vir * p_cmd_cfg->img_h_o_vir;
184 vdpp_proc_cfg.dst_img_info.img_cbcr.w_vld = p_cmd_cfg->img_w_o_c;
185 vdpp_proc_cfg.dst_img_info.img_cbcr.h_vld = p_cmd_cfg->img_h_o_c;
186 vdpp_proc_cfg.dst_img_info.img_cbcr.w_vir = p_cmd_cfg->img_w_o_c_vir;
187 vdpp_proc_cfg.dst_img_info.img_cbcr.h_vir = p_cmd_cfg->img_h_o_c_vir;
188
189 {
190 int work_mode_ref = hwpq_vdpp_check_work_mode(vdpp_ctx, &vdpp_proc_cfg);
191
192 vdpp_proc_cfg.hist_mode_en = (VDPP_RUN_MODE_HIST == p_cmd_cfg->work_mode) ||
193 (VDPP_RUN_MODE_HIST == work_mode_ref);
194 }
195
196 vdpp_proc_cfg.hist_buf_fd = fdhist;
197 vdpp_proc_cfg.p_hist_buf = phist;
198
199 vdpp_proc_cfg.yuv_diff_flag = 0;
200 vdpp_proc_cfg.vdpp_config_update_flag = 0;
201
202 hwpq_vdpp_proc(vdpp_ctx, &vdpp_proc_cfg);
203
204 if (ctx->fp_o_y)
205 fwrite(vdpp_proc_cfg.dst_img_info.img_yrgb.addr, 1, p_cmd_cfg->img_w_o_vir * p_cmd_cfg->img_h_o_vir * 1, ctx->fp_o_y);
206 if (ctx->fp_o_uv)
207 fwrite((unsigned char*)vdpp_proc_cfg.dst_img_info.img_cbcr.addr + p_cmd_cfg->img_w_o_vir * p_cmd_cfg->img_h_o_vir, 1, p_cmd_cfg->img_w_o_c_vir * p_cmd_cfg->img_h_o_c_vir * 2, ctx->fp_o_uv);
208 if (ctx->fp_o_h)
209 fwrite(vdpp_proc_cfg.p_hist_buf, 1, VDPP_HIST_LENGTH, ctx->fp_o_h);
210
211 frame_idx++;
212
213 if (p_cmd_cfg->frame_num > 0 && frame_idx >= p_cmd_cfg->frame_num) {
214 ctx->frm_eos = 1;
215 break;
216 }
217
218 if (ctx->frm_eos)
219 break;
220 }
221
222 __RET:
223 if (ctx->fp_i) {
224 fclose(ctx->fp_i);
225 ctx->fp_i = NULL;
226 }
227 if (ctx->fp_o_y) {
228 fclose(ctx->fp_o_y);
229 ctx->fp_o_y = NULL;
230 }
231 if (ctx->fp_o_uv) {
232 fclose(ctx->fp_o_uv);
233 ctx->fp_o_uv = NULL;
234 }
235 if (ctx->fp_o_h) {
236 fclose(ctx->fp_o_h);
237 ctx->fp_o_h = NULL;
238 }
239
240 mpp_buffer_put(srcbuf);
241 mpp_buffer_put(dstbuf);
242 mpp_buffer_put(histbuf);
243 mpp_buffer_put(dstbuf_c);
244
245 if (memGroup) {
246 mpp_buffer_group_put(memGroup);
247 memGroup = NULL;
248 }
249
250 hwpq_vdpp_deinit(vdpp_ctx);
251
252 return NULL;
253 }
254
main(int argc,char ** argv)255 int32_t main(int argc, char **argv)
256 {
257 VdppCmdCfg vdpp_cmd_cfg;
258 VdppCmdCfg *p_cmd_cfg = &vdpp_cmd_cfg;
259 VdppTestMultiCtxInfo *ctxs = NULL;
260 int i = 0;
261 int ret = 0;
262
263 parse_cmd(argv, argc, p_cmd_cfg);
264
265 ctxs = mpp_calloc(VdppTestMultiCtxInfo, p_cmd_cfg->nthreads);
266 if (NULL == ctxs) {
267 mpp_err("failed to alloc context for instances\n");
268 ret = MPP_ERR_MALLOC;
269 goto __RET;
270 }
271
272 for (i = 0; i < p_cmd_cfg->nthreads; i++) {
273 ctxs[i].cmd = p_cmd_cfg;
274 ctxs[i].chn = i;
275
276 ret = pthread_create(&ctxs[i].thd, NULL, multi_vdpp, &ctxs[i]);
277 if (ret) {
278 mpp_err("failed to create thread %d\n", i);
279 ret = MPP_NOK;
280 goto __RET;
281 }
282 }
283
284 for (i = 0; i < p_cmd_cfg->nthreads; i++)
285 pthread_join(ctxs[i].thd, NULL);
286
287 __RET:
288 MPP_FREE(ctxs);
289 ctxs = NULL;
290
291 return ret;
292 }
293
parse_cmd(char ** argv,int argc,VdppCmdCfg * p_cmd_cfg)294 static void parse_cmd(char** argv, int argc, VdppCmdCfg* p_cmd_cfg)
295 {
296 mpp_log("in parse 3\n");
297 int32_t ch;
298 int32_t option_index = 0;
299
300 opterr = 0;
301 static struct option long_options[] = {
302 {"ip", required_argument, 0, 0 },
303 {"oy", required_argument, 0, 0 },
304 {"oc", required_argument, 0, 0 },
305 {"oh", required_argument, 0, 0 },
306 {"wi_vld", required_argument, 0, 0 },
307 {"hi_vld", required_argument, 0, 0 },
308 {"wi_vir", required_argument, 0, 0 },
309 {"hi_vir", required_argument, 0, 0 },
310 {"wo_vld", required_argument, 0, 0 },
311 {"ho_vld", required_argument, 0, 0 },
312 {"wo_vir", required_argument, 0, 0 },
313 {"ho_vir", required_argument, 0, 0 },
314 {"uv_diff", required_argument, 0, 0 },
315 {"wo_uv", required_argument, 0, 0 },
316 {"ho_uv", required_argument, 0, 0 },
317 {"wo_uv_vir", required_argument, 0, 0 },
318 {"ho_uv_vir", required_argument, 0, 0 },
319 {"work_mode", required_argument, 0, 0 },
320 {"nthread", required_argument, 0, 0 },
321 {"frame_num", required_argument, 0, 0 },
322 { 0, 0, 0, 0 },
323 };
324
325 p_cmd_cfg->nthreads = 1;
326
327 while ((ch = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) {
328 switch (ch) {
329 case 0: {
330 switch (option_index) {
331 case 0 : {
332 strncpy(p_cmd_cfg->src_file_name, optarg, sizeof(p_cmd_cfg->src_file_name) - 1);
333 mpp_log("ssrc file name: %s\n", p_cmd_cfg->src_file_name);
334 } break;
335 case 1 : {
336 strncpy(p_cmd_cfg->dst_file_name_y, optarg, sizeof(p_cmd_cfg->dst_file_name_y) - 1);
337 mpp_log("ddst-Y file name: %s\n", p_cmd_cfg->dst_file_name_y);
338 } break;
339 case 2 : {
340 strncpy(p_cmd_cfg->dst_file_name_uv, optarg, sizeof(p_cmd_cfg->dst_file_name_uv) - 1);
341 mpp_log("ddst-UV file name: %s\n", p_cmd_cfg->dst_file_name_uv);
342 } break;
343 case 3 : {
344 strncpy(p_cmd_cfg->dst_file_name_hist, optarg, sizeof(p_cmd_cfg->dst_file_name_hist) - 1);
345 mpp_log("ddst-Hist file name: %s\n", p_cmd_cfg->dst_file_name_hist);
346 } break;
347 case 4 : {
348 p_cmd_cfg->img_w_i = atoi(optarg);
349 } break;
350 case 5 : {
351 p_cmd_cfg->img_h_i = atoi(optarg);
352 } break;
353 case 6 : {
354 p_cmd_cfg->img_w_i_vir = atoi(optarg);
355 } break;
356 case 7 : {
357 p_cmd_cfg->img_h_i_vir = atoi(optarg);
358 } break;
359 case 8 : {
360 p_cmd_cfg->img_w_o = atoi(optarg);
361 } break;
362 case 9 : {
363 p_cmd_cfg->img_h_o = atoi(optarg);
364 } break;
365 case 10 : {
366 p_cmd_cfg->img_w_o_vir = atoi(optarg);
367 } break;
368 case 11 : {
369 p_cmd_cfg->img_h_o_vir = atoi(optarg);
370 } break;
371 case 12 : {
372 p_cmd_cfg->uv_diff_flag = atoi(optarg);
373 } break;
374 case 13 : {
375 p_cmd_cfg->img_w_o_c = atoi(optarg);
376 } break;
377 case 14 : {
378 p_cmd_cfg->img_h_o_c = atoi(optarg);
379 } break;
380 case 15 : {
381 p_cmd_cfg->img_w_o_c_vir = atoi(optarg);
382 } break;
383 case 16 : {
384 p_cmd_cfg->img_h_o_c_vir = atoi(optarg);
385 } break;
386 case 17 : {
387 p_cmd_cfg->work_mode = atoi(optarg);
388 } break;
389 case 18 : {
390 p_cmd_cfg->nthreads = atoi(optarg);
391 if (p_cmd_cfg->nthreads < 1)
392 p_cmd_cfg->nthreads = 1;
393 } break;
394 case 19: {
395 p_cmd_cfg->frame_num = atoi(optarg);
396 } break;
397 default : {
398 } break;
399 }
400 mpp_log("%s: %s", long_options[option_index].name, optarg);
401
402 } break;
403 default: {
404 } break;
405 }
406 }
407 }
408