libxcoder 5.9.0
Loading...
Searching...
No Matches
ni_xcoder_transcode_filter.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Copyright (C) 2022 NETINT Technologies
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 * SOFTWARE.
19 *
20 ******************************************************************************/
21
22/*!*****************************************************************************
23 * \file ni_xcoder_transcode_filter.c
24 *
25 * \brief Video transcoding and filtering demo application directly using
26 * Netint Libxcoder API
27 ******************************************************************************/
28
29#include "ni_generic_utils.h"
30#include "ni_decode_utils.h"
31#include "ni_encode_utils.h"
32#include "ni_filter_utils.h"
33#include "ni_log.h"
34#include "ni_util.h"
35
36#ifdef _WIN32
37#include "ni_getopt.h"
38#elif __linux__ || __APPLE__
39#include <getopt.h>
40#include <unistd.h>
41#endif
42
44 int32_t width;
45 int32_t height;
46 int32_t channel;
47 int32_t classes;
48 int32_t component;
50 float *output;
52
61
62static void ni_destroy_network(ni_ai_pre_network_t *network)
63{
64 if (network) {
65 int i;
66
67 if (network->layers) {
68 for (i = 0; i < (int)network->raw.output_num; i++) {
69 free(network->layers[i].output);
70 network->layers[i].output = NULL;
71 }
72
73 free(network->layers);
74 network->layers = NULL;
75 }
76 }
77}
78
79static int ni_create_network(ni_ai_pre_network_t *network)
80{
81 int ret;
82 int i;
83 ni_network_data_t *ni_network = &network->raw;
84
86 "network input number %d, output number %d\n",
87 ni_network->input_num, ni_network->output_num);
88
89 if (ni_network->input_num == 0 || ni_network->output_num == 0) {
90 ni_log(NI_LOG_ERROR, "invalid network layer\n");
92 }
93
94 network->layers =
95 malloc(sizeof(ni_ai_pre_network_layer_t) * ni_network->output_num);
96 if (!network->layers) {
97 ni_log(NI_LOG_ERROR, "cannot allocate network layer memory\n");
99 }
100 memset(network->layers, 0,
101 sizeof(ni_ai_pre_network_layer_t) * ni_network->output_num);
102
103 for (i = 0; i < (int)ni_network->output_num; i++) {
104 network->layers[i].width = ni_network->linfo.out_param[i].sizes[0];
105 network->layers[i].height =
106 ni_network->linfo.out_param[i].sizes[1];
107 network->layers[i].channel =
108 ni_network->linfo.out_param[i].sizes[2];
109 network->layers[i].component = 3;
110 network->layers[i].classes =
111 (network->layers[i].channel / network->layers[i].component) -
112 (4 + 1);
113 network->layers[i].output_number =
115 if (network->layers[i].output_number !=
116 network->layers[i].width * network->layers[i].height *
117 network->layers[i].channel) {
119 "network layer %d output dims mismatch\n", i);
121 goto out;
122 }
123
124 network->layers[i].output =
125 malloc(network->layers[i].output_number * sizeof(float));
126 if (!network->layers[i].output) {
128 "failed to allocate network layer %d output buffer\n",
129 i);
131 goto out;
132 }
133
135 "network layer %d: w %d, h %d, ch %d, co %d, cl %d\n", i,
136 network->layers[i].width, network->layers[i].height,
137 network->layers[i].channel, network->layers[i].component,
138 network->layers[i].classes);
139 }
140
141 network->netw = ni_network->linfo.in_param[0].sizes[1];
142 network->neth = ni_network->linfo.in_param[0].sizes[2];
143 network->net_out_w = ni_network->linfo.out_param[0].sizes[1];
144 network->net_out_h = ni_network->linfo.out_param[0].sizes[2];
145
146 return 0;
147out:
148 ni_destroy_network(network);
149 return ret;
150}
151
152static void print_usage(void)
153{
155 "Video transcoding demo application directly using Netint Libxcoder version %s\n"
156 "Usage: ni_xcoder_transcode_filter [options]\n"
157 "\n"
158 "options:\n"
159 "-h | --help Show this message.\n"
160 "-v | --version Print version info.\n"
161 "-i | --input (Required) Input file path.\n"
162 "-o | --output (Required) Output file path.\n"
163 " Can be specified multiple (max %d) times\n"
164 " to run multiple encoding instances simultaneously.\n"
165 "-m | --dec-codec (Required) Decoder codec format. Must match the codec of input file.\n"
166 " [a|avc, h|hevc, v|vp9]\n"
167 "-n | --enc-codec (Required) Encoder codec format.\n"
168 " [a|avc, h|hevc, x|av1] (x is in ivf container format)\n"
169 "-l | --loglevel Set loglevel of this application and libxcoder API.\n"
170 " [none, fatal, error, info, debug, trace]\n"
171 " (Default: info)\n"
172 "-c | --card Set card index to use.\n"
173 " See `ni_rsrc_mon` for info of cards on system.\n"
174 " (Default: 0)\n"
175 "-r | --repeat To loop input X times. Must be a positive integer\n"
176 " (Default: 1)\n"
177 "-d | --decoder-params Decoding params. See \"Decoding Parameters\" chapter in\n"
178 " QuadraIntegration&ProgrammingGuide*.pdf for help.\n"
179 " (Default: \"\")\n"
180 "-e | --encoder-params Encoding params. See \"Encoding Parameters\" chapter in\n"
181 " QuadraIntegration&ProgrammingGuide*.pdf for help.\n"
182 " Can be specified multiple (max %d) times,\n"
183 " must match the number of -o specified.\n"
184 " (Default: \"\")\n"
185 "-g | --encoder-gop Custom GOP for encoding. See \"Custom Gop Structure\" chapter in\n"
186 " QuadraIntegration&ProgrammingGuide*.pdf for help.\n"
187 " gopPresetIdx must be set to 0 to be in effect.\n"
188 " (Default: \"\")\n"
189 "-u | --user-data-sei-passthru (No argument) Enable user data unregistered SEI passthrough when specified\n"
190 "-f | --vf Video filter params. The only supported filters in this demo are:\n"
191 " ni_quadra_scale - supported params [width, height, format]\n"
192 " e.g. ni_quadra_scale=width=1280:height=720:format=yuv420p\n"
193 " ni_quadra_drawbox - supported params [x, y, width, height]\n"
194 " e.g. ni_quadra_drawbox=x=300:y=150:width=600:height=400\n"
195 " ni_quadra_ai_pre - supported params [nb, width, height]\n"
196 " ai preprocessing driven by a network binary (.nb) file.\n"
197 " e.g. ni_quadra_ai_pre=nb=/path/model.nb\n"
198 " (Default: \"\")\n"
200}
201
202int main(int argc, char *argv[])
203{
204 int i, ret = 0;
205 ni_demo_context_t ctx = {0};
206 char in_filename[FILE_NAME_LEN] = {0};
207 char out_filename[MAX_OUTPUT_FILES][FILE_NAME_LEN] = {0};
208 FILE *output_fp[MAX_OUTPUT_FILES] = {0};
209 int o_index = 0, e_index = 0, g_index = 0, f_index = 0;
210 int output_total = 0;
211 int input_width = 0, input_height = 0, bit_depth = 8;
212 int output_width[MAX_OUTPUT_FILES] = {0};
213 int output_height[MAX_OUTPUT_FILES] = {0};
214 int dec_codec_format = -1, enc_codec_format = -1;
215 ni_log_level_t log_level;
216 int xcoderGUID = 0;
217 char *n;
218 char dec_conf_params[2048] = {0};
219 char filter_conf_params[MAX_OUTPUT_FILES][2048] = {0};
220 char enc_conf_params[MAX_OUTPUT_FILES][2048] = {0};
221 char enc_gop_params[MAX_OUTPUT_FILES][2048] = {0};
222 int user_data_sei_passthru = 0;
223 ni_h264_sps_t avc_sps = {0};
224 ni_h265_sps_t hevc_sps = {0};
225 ni_vp9_header_info_t vp9_info = {0};
226 ni_xcoder_params_t *p_dec_api_param = NULL;
227 ni_xcoder_params_t *p_enc_api_param = NULL;
228 ni_session_context_t dec_ctx = {0};
231 ni_session_context_t crop_ctx = {0};
232 ni_session_context_t pad_ctx = {0};
233 ni_session_context_t ovly_ctx = {0};
234 ni_session_context_t fmt_ctx = {0};
235 int send_rc = NI_TEST_RETCODE_SUCCESS, receive_rc = NI_TEST_RETCODE_SUCCESS, rx_size = 0;
236 void *p_stream_info = NULL;
237 int fps_num = 30, fps_den = 1, bitrate = 200000;
238 uint64_t current_time, previous_time;
239 ni_session_data_io_t in_pkt = {0};
240 ni_session_data_io_t out_frame = {0};
241 ni_session_data_io_t filter_out_frame[MAX_OUTPUT_FILES] = {0};
243 ni_session_data_io_t enc_in_frame = {0};
244 ni_session_data_io_t out_packet[MAX_OUTPUT_FILES] = {0};
245 niFrameSurface1_t *p_hwframe = NULL;
247 int encoder_opened = 0, end_of_all_streams = 0;
248 ni_scale_params_t scale_params[MAX_OUTPUT_FILES] = {0};
249 ni_drawbox_params_t drawbox_params = {0};
250 ni_ai_pre_params_t ai_pre_params[MAX_OUTPUT_FILES] = {0};
252 ni_ai_pre_network_t ai_network[MAX_OUTPUT_FILES] = {0};
253 ni_pix_fmt_t enc_pix_fmt[MAX_OUTPUT_FILES];
254 int hw_frame_ref_flag = 0;
255 int recycle_hw_frame_for_scaler = 0;
256
257 int opt;
258 int opt_index;
259 const char *opt_string = "hvi:o:m:n:l:c:r:d:e:g:uf:";
260 static struct option long_options[] = {
261 {"help", no_argument, NULL, 'h'},
262 {"version", no_argument, NULL, 'v'},
263 {"input", required_argument, NULL, 'i'},
264 {"output", required_argument, NULL, 'o'},
265 {"dec-codec", required_argument, NULL, 'n'},
266 {"enc-codec", required_argument, NULL, 'm'},
267 {"loglevel", required_argument, NULL, 'l'},
268 {"card", required_argument, NULL, 'c'},
269 {"repeat", required_argument, NULL, 'r'},
270 {"decoder-params", required_argument, NULL, 'd'},
271 {"encoder-params", required_argument, NULL, 'e'},
272 {"encoder-gop", required_argument, NULL, 'g'},
273 {"user-data-sei-passthru", no_argument, NULL, 'u'},
274 {"vf", required_argument, NULL, 'f'},
275 {NULL, 0, NULL, 0},
276 };
277
278 while ((opt = getopt_long(argc, argv, opt_string, long_options, &opt_index)) != -1)
279 {
280 switch (opt)
281 {
282 case 'h':
283 print_usage();
284 ret = 0;
285 goto end;
286 case 'v':
288 ret = 0;
289 goto end;
290 case 'i':
291 ni_strcpy(in_filename, FILE_NAME_LEN, optarg);
292 break;
293 case 'o':
294 if (o_index == MAX_OUTPUT_FILES)
295 {
296 ni_log(NI_LOG_ERROR, "Error: number of output files cannot exceed %d\n", MAX_OUTPUT_FILES);
297 ret = -1;
298 goto end;
299 }
300
301 for (i = 0; i < o_index; i++)
302 {
303 if (0 == strcmp(out_filename[i], optarg))
304 {
305 ni_log(NI_LOG_ERROR, "Error: output file names must be unique: %s\n", optarg);
306 ret = -1;
307 goto end;
308 }
309 }
310
311 ni_strcpy(out_filename[o_index], FILE_NAME_LEN, optarg);
312 o_index++;
313 break;
314 case 'm':
315 // Accept both upper and lower case
316 for (i = 0; i < strlen(optarg); i++)
317 {
318 optarg[i] = (char)tolower((unsigned char)optarg[i]);
319 }
320 if (strcmp(optarg, "a") == 0 || strcmp(optarg, "avc") == 0)
321 {
322 dec_codec_format = NI_CODEC_FORMAT_H264;
323 }
324 else if (strcmp(optarg, "h") == 0 || strcmp(optarg, "hevc") == 0)
325 {
326 dec_codec_format = NI_CODEC_FORMAT_H265;
327 }
328 else if (strcmp(optarg, "v") == 0 || strcmp(optarg, "vp9") == 0)
329 {
330 dec_codec_format = NI_CODEC_FORMAT_VP9;
331 }
332 else
333 {
334 ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -m | --dec-codec option\n"
335 "Must be one of [a|avc, h|hevc, v|vp9]\n", optarg);
336 ret = -1;
337 goto end;
338 }
339 break;
340 case 'n':
341 // Accept both upper and lower case
342 for (i = 0; i < strlen(optarg); i++)
343 {
344 optarg[i] = (char)tolower((unsigned char)optarg[i]);
345 }
346 if (strcmp(optarg, "a") == 0 || strcmp(optarg, "avc") == 0)
347 {
348 enc_codec_format = NI_CODEC_FORMAT_H264;
349 }
350 else if (strcmp(optarg, "h") == 0 || strcmp(optarg, "hevc") == 0)
351 {
352 enc_codec_format = NI_CODEC_FORMAT_H265;
353 }
354 else if (strcmp(optarg, "x") == 0 || strcmp(optarg, "av1") == 0)
355 {
356 enc_codec_format = NI_CODEC_FORMAT_AV1;
357 }
358 else
359 {
360 ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -n | --enc-codec option\n"
361 "Must be one of [a|avc, h|hevc, x|av1]\n", optarg);
362 ret = -1;
363 goto end;
364 }
365 break;
366 case 'l':
367 log_level = arg_to_ni_log_level(optarg);
368 if (log_level != NI_LOG_INVALID)
369 {
370 ni_log_set_level(log_level);
371 }
372 else
373 {
374 ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -l | --loglevel option\n"
375 "Must be one of [none, fatal, error, info, debug, trace]\n", optarg);
376 ret = -1;
377 goto end;
378 }
379 break;
380 case 'c':
381 xcoderGUID = (int)strtol(optarg, &n, 10);
382 if (n == optarg || *n != '\0' || xcoderGUID < 0)
383 {
384 ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -c | --card option\n"
385 "Must be a non-negative integer\n", optarg);
386 ret = -1;
387 goto end;
388 }
389 break;
390 case 'r':
391 ctx.loops_left = strtol(optarg, &n, 10);
392 if (n == optarg || *n != '\0' || !(ctx.loops_left >= 1))
393 {
394 ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -r | --repeat option\n"
395 "Must be a positive integer\n", optarg);
396 ret = -1;
397 goto end;
398 }
399 break;
400 case 'd':
401 ni_strcpy(dec_conf_params, sizeof(dec_conf_params), optarg);
402 break;
403 case 'e':
404 if (e_index == MAX_OUTPUT_FILES)
405 {
406 ni_log(NI_LOG_ERROR, "Error: number of encoder config cannot exceed %d\n", MAX_OUTPUT_FILES);
407 ret = -1;
408 goto end;
409 }
410 ni_strcpy(enc_conf_params[e_index], sizeof(enc_conf_params[e_index]), optarg);
411 e_index++;
412 break;
413 case 'g':
414 if (g_index == MAX_OUTPUT_FILES)
415 {
416 ni_log(NI_LOG_ERROR, "Error: number of encoder gop settings cannot exceed %d\n", MAX_OUTPUT_FILES);
417 ret = -1;
418 goto end;
419 }
420 ni_strcpy(enc_gop_params[g_index], sizeof(enc_gop_params[g_index]), optarg);
421 g_index++;
422 break;
423 case 'u':
424 user_data_sei_passthru = 1;
425 break;
426 case 'f':
427 if (f_index == MAX_OUTPUT_FILES)
428 {
429 ni_log(NI_LOG_ERROR, "Error: number of filter config cannot exceed %d\n", MAX_OUTPUT_FILES);
430 ret = -1;
431 goto end;
432 }
433 ni_strcpy(filter_conf_params[f_index], sizeof(filter_conf_params[f_index]), optarg);
434 f_index++;
435 break;
436 default:
437 print_usage();
438 ret = -1;
439 goto end;
440 }
441 }
442
443 if (!in_filename[0]) {
444 ni_log(NI_LOG_ERROR, "Error: Missing input file argument (-i | --input)\n");
445 ret = -1;
446 goto end;
447 }
448
449 if (o_index == 0) {
450 ni_log(NI_LOG_ERROR, "Error: Missing output file argument (-o | --output)\n");
451 ret = -1;
452 goto end;
453 }
454
455 if (dec_codec_format == -1) {
456 ni_log(NI_LOG_ERROR, "Error: Missing decoder codec argument (-m | --dec-codec)\n");
457 ret = -1;
458 goto end;
459 }
460
461 if (enc_codec_format == -1) {
462 ni_log(NI_LOG_ERROR, "Error: Missing encoder codec argument (-n | --enc-codec)\n");
463 ret = -1;
464 goto end;
465 }
466
467 ret = read_and_cache_file(&ctx, in_filename);
468 if (ret)
469 {
470 ni_log(NI_LOG_ERROR, "Error: Read input file failure\n");
471 goto end;
472 }
473
474 output_total = o_index;
475 for (i = 0; i < output_total; i++)
476 {
477 if (strcmp(out_filename[i], "null") != 0 &&
478 strcmp(out_filename[i], "/dev/null") != 0)
479 {
480 output_fp[i] = NULL;
481 ni_fopen(&(output_fp[i]), out_filename[i], "wb");
482 if (!output_fp[i])
483 {
484 ni_log(NI_LOG_ERROR, "Error: Failed to open %s\n", out_filename[i]);
485 ret = -1;
486 goto end;
487 }
488 ni_log(NI_LOG_INFO, "Opened output file: %s\n", out_filename[i]);
489 } else
490 {
491 output_fp[i] = NULL;
492 ni_log(NI_LOG_INFO, "Note: Requested NULL output for index %d, no output file will be generated\n", i);
493 }
494
495 frame_to_enc[i] = NULL;
496 enc_pix_fmt[i] = NI_PIX_FMT_YUV420P;
497 p_hwframe2[i] = NULL;
498 }
499
500 p_dec_api_param = malloc(sizeof(ni_xcoder_params_t));
501 if (!p_dec_api_param)
502 {
503 ni_log(NI_LOG_ERROR, "Error: failed to allocate p_dec_api_param\n");
504 ret = -1;
505 goto end;
506 }
507
508 p_enc_api_param = calloc(output_total, sizeof(ni_xcoder_params_t));
509 if (!p_enc_api_param)
510 {
511 ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for p_enc_api_param\n");
512 ret = -1;
513 goto end;
514 }
515
516 if (dec_codec_format == NI_CODEC_FORMAT_H264)
517 {
518 ret = probe_h264_stream_info(&ctx, &avc_sps);
519 if (ret)
520 {
522 "ERROR: Failed to probe input file as H.264, file format not supported!\n");
523 goto end;
524 }
525
526 bit_depth = avc_sps.bit_depth_luma;
527 input_width = avc_sps.width;
528 input_height = avc_sps.height;
529 ni_log(NI_LOG_DEBUG, "Using probed H.264 source info: %d bits, resolution %dx%d\n",
530 bit_depth, input_width, input_height);
531 } else if (dec_codec_format == NI_CODEC_FORMAT_H265)
532 {
533 ret = probe_h265_stream_info(&ctx, &hevc_sps);
534 if (ret)
535 {
537 "ERROR: Failed to probe input file as H.265, file format not supported!\n");
538 goto end;
539 }
540 bit_depth = hevc_sps.bit_depth_chroma;
541 input_width = (int)(hevc_sps.width -
542 (hevc_sps.pic_conf_win.left_offset +
543 hevc_sps.pic_conf_win.right_offset));
544 input_height = (int)(hevc_sps.height -
545 (hevc_sps.pic_conf_win.top_offset +
546 hevc_sps.pic_conf_win.bottom_offset));
547 ni_log(NI_LOG_INFO, "Using probed H.265 source info: %d bits, resolution %dx%d\n",
548 bit_depth, input_width, input_height);
549 } else if (dec_codec_format == NI_CODEC_FORMAT_VP9)
550 {
551 ret = probe_vp9_stream_info(&ctx, &vp9_info);
552 if (ret)
553 {
555 "ERROR: Failed to probe input file as VP9, file format not supported!\n");
556 goto end;
557 }
558 bit_depth = vp9_info.profile ? 10 : 8;
559 input_width = vp9_info.width;
560 input_height = vp9_info.height;
562 "Using probed VP9 source info: %d bits, resolution %dx%d, timebase %u/%u\n",
563 bit_depth, input_width, input_height,
564 vp9_info.timebase.den, vp9_info.timebase.num);
565 }
566
567 // set up decoder config params with some hard-coded values
568 ret = ni_decoder_init_default_params(p_dec_api_param, 25, 1, 200000, input_width, input_height);
569 if (ret)
570 {
571 ni_log(NI_LOG_ERROR, "Error: Failed to init default decoder config\n");
572 goto end;
573 }
574
575 ret = ni_device_session_context_init(&dec_ctx);
576 if (ret)
577 {
578 ni_log(NI_LOG_ERROR, "Error: Failed to init decoder context\n");
579 goto end;
580 }
581
582 dec_ctx.codec_format = dec_codec_format;
583 dec_ctx.src_bit_depth = bit_depth;
584 dec_ctx.bit_depth_factor = 1;
585 if (10 == dec_ctx.src_bit_depth)
586 {
587 dec_ctx.bit_depth_factor = 2;
588 }
589 if ((NI_CODEC_FORMAT_H264 == dec_codec_format) || (NI_CODEC_FORMAT_H265 == dec_codec_format))
590 dec_ctx.enable_user_data_sei_passthru = user_data_sei_passthru;
591
592 // check and set ni_decoder_params from --xcoder-params
593 ret = ni_retrieve_decoder_params(dec_conf_params, p_dec_api_param, &dec_ctx);
594 if (ret)
595 {
596 ni_log(NI_LOG_ERROR, "Error: decoder config params parsing error\n");
597 goto end;
598 }
599
600 // Decode, use all the parameters specified by user
601 ret = decoder_open_session(&dec_ctx, xcoderGUID, p_dec_api_param);
602 if (ret)
603 {
604 ni_log(NI_LOG_ERROR, "Error: Failed to open decoder session\n");
605 goto end;
606 }
607
608 for (i = 0; i < output_total; i++)
609 {
610 if (ni_device_session_context_init(&enc_ctx[i]) < 0)
611 {
612 ni_log(NI_LOG_ERROR, "Error: init encoder %d context error\n", i);
613 ret = -1;
614 goto end;
615 }
616 }
617
618 for (i = 0; i < output_total; i++)
619 {
620 enc_ctx[i].codec_format = enc_codec_format;
621 output_width[i] = input_width;
622 output_height[i] = input_height;
623 }
624
625 if (dec_codec_format == NI_CODEC_FORMAT_H264)
626 p_stream_info = &avc_sps;
627 else if (dec_codec_format == NI_CODEC_FORMAT_H265)
628 p_stream_info = &hevc_sps;
629 else if (dec_codec_format == NI_CODEC_FORMAT_VP9)
630 {
631 p_stream_info = &vp9_info;
632 fps_num = vp9_info.timebase.den;
633 fps_den = vp9_info.timebase.num;
634 }
635
636 for (i = 0; i < output_total; i++)
637 {
638 if (filter_conf_params[i][0])
639 {
640 if (!dec_ctx.hw_action) {
641 ni_log(NI_LOG_ERROR, "Error: filters are only supported when hwframe is enabled (out=hw)\n");
642 ret = -1;
643 goto end;
644 }
645
646 ret = retrieve_filter_params(filter_conf_params[i], &scale_params[i], &drawbox_params, &ai_pre_params[i]);
647 if (ret)
648 {
649 ni_log(NI_LOG_ERROR, "Error: failed to parse filter parameters: %s\n", filter_conf_params[i]);
650 goto end;
651 }
652 }
653
654 if (scale_params[i].enabled)
655 {
656 ret = ni_device_session_context_init(&sca_ctx[i]);
657 if (ret)
658 {
659 ni_log(NI_LOG_ERROR, "Error: Failed to init scale context\n");
660 goto end;
661 }
662 output_width[i] = scale_params[i].width;
663 output_height[i] = scale_params[i].height;
664 }
665 else if (ai_pre_params[i].enabled)
666 {
667 if (!ai_pre_params[i].nb_file[0])
668 {
669 ni_log(NI_LOG_ERROR, "Error: ni_quadra_ai_pre requires an 'nb' (network binary) param\n");
670 ret = -1;
671 goto end;
672 }
673
674 ret = ni_device_session_context_init(&ai_ctx[i]);
675 if (ret)
676 {
677 ni_log(NI_LOG_ERROR, "Error: Failed to init ai_pre context\n");
678 goto end;
679 }
680
681 // ai_pre preserves the resolution unless the user overrides width/height.
682 if (ai_pre_params[i].out_width > 0)
683 output_width[i] = ai_pre_params[i].out_width;
684 if (ai_pre_params[i].out_height > 0)
685 output_height[i] = ai_pre_params[i].out_height;
686 }
687 else if ((drawbox_params.enabled)) // drawbox is only supported for a single instance in this example.
688 {
689 ret = ni_device_session_context_init(&crop_ctx);
690 if (ret)
691 {
692 ni_log(NI_LOG_ERROR, "Error: Failed to init crop context\n");
693 goto end;
694 }
695 ret = ni_device_session_context_init(&pad_ctx);
696 if (ret)
697 {
698 ni_log(NI_LOG_ERROR, "Error: Failed to init pad context\n");
699 goto end;
700 }
701 ret = ni_device_session_context_init(&ovly_ctx);
702 if (ret)
703 {
704 ni_log(NI_LOG_ERROR, "Error: Failed to init overlay context\n");
705 goto end;
706 }
707 ret = ni_device_session_context_init(&fmt_ctx);
708 if (ret)
709 {
710 ni_log(NI_LOG_ERROR, "Error: Failed to init format context\n");
711 goto end;
712 }
713 break;
714 }
715 }
716
717 for (i = 0; i < output_total; i++)
718 {
719 if (drawbox_params.enabled && scale_params[i].enabled){
720 ni_log(NI_LOG_ERROR, "Error: Mixing scale and drawbox filter is not supported in this demo\n");
721 goto end;
722 }
723 if (drawbox_params.enabled && ai_pre_params[i].enabled){
724 ni_log(NI_LOG_ERROR, "Error: Mixing ai_pre and drawbox filter is not supported in this demo\n");
725 goto end;
726 }
727 ni_log(NI_LOG_INFO, "(Task %d) Starting to transcode: HWFrames %d, video resolution %dx%d -> %dx%d\n",
728 i, dec_ctx.hw_action, input_width, input_height, output_width[i], output_height[i]);
729 }
730
733
734 while (!end_of_all_streams &&
735 (send_rc == NI_TEST_RETCODE_SUCCESS || receive_rc == NI_TEST_RETCODE_SUCCESS ||
736 (send_rc == NI_TEST_RETCODE_EAGAIN && receive_rc == NI_TEST_RETCODE_EAGAIN)))
737 {
738 // bitstream Sending
739decode_send:
740 send_rc = decoder_send_data(&ctx, &dec_ctx, &in_pkt, input_width, input_height, p_stream_info);
741 if (send_rc < 0)
742 {
743 ni_log(NI_LOG_ERROR, "Error: decoder send packet failed\n");
744 ret = send_rc;
745 break;
746 }
747
748 // YUV Receiving: not writing to file
749 receive_rc = decoder_receive_data(&ctx, &dec_ctx, &out_frame, input_width,
750 input_height, NULL, 0, &rx_size);
751
752 for (i = 0; i < output_total; i++)
753 {
754 frame_to_enc[i] = &out_frame;
755 }
756
757 if (receive_rc < 0)
758 {
759 ni_log(NI_LOG_ERROR, "Error: decoder receive frame failed\n");
760 ret = receive_rc;
761 break;
762 }
763 else if (receive_rc == NI_TEST_RETCODE_EAGAIN)
764 {
765 if (!dec_ctx.hw_action)
766 {
768 } else
769 {
770 ni_frame_buffer_free(&(out_frame.data.frame));
771 }
772
773 // use first encode config low delay flag for call flow
774 if (p_enc_api_param[0].low_delay_mode <= 0 && encoder_opened)
775 {
776 ni_log(NI_LOG_DEBUG, "no decoder output, jump to encoder receive!\n");
777 goto encode_recv;
778 } else
779 {
780 ni_log(NI_LOG_DEBUG, "no decoder output, encode low_delay, jump to decoder send!\n");
781 goto decode_send;
782 }
783 }
784 else if (receive_rc != NI_TEST_RETCODE_END_OF_STREAM)
785 {
786
787 p_hwframe = (niFrameSurface1_t *)out_frame.data.frame.p_data[3];
788 recycle_hw_frame_for_scaler = 1;
789 for (i = 0; i < output_total; i++)
790 {
791 if (scale_params[i].enabled)
792 {
793 if(!hw_frame_ref_flag)
794 {
795 hw_frame_ref_flag = 1;
796 ni_hw_frame_ref(p_hwframe);
797 }
798
799 scale_filter(&sca_ctx[i], &out_frame.data.frame, &filter_out_frame[i], xcoderGUID, scale_params[i].width,
800 scale_params[i].height, ni_to_gc620_pix_fmt(dec_ctx.pixel_format), scale_params[i].format);
801 frame_to_enc[i] = &filter_out_frame[i];
802 }
803 else if (ai_pre_params[i].enabled)
804 {
805 int ai_out_gc620 = ni_to_gc620_pix_fmt(dec_ctx.pixel_format);
806
807 if(!hw_frame_ref_flag)
808 {
809 hw_frame_ref_flag = 1;
810 ni_hw_frame_ref(p_hwframe);
811 }
812
813 // Open the AI session lazily now that the decoder pixel
814 // format and resolution are known.
815 if (!ai_pre_params[i].initialized)
816 {
817 ret = ai_pre_filter_init(&ai_ctx[i], &ai_network[i].raw, xcoderGUID,
818 &ai_pre_params[i], p_hwframe->ui16width,
819 p_hwframe->ui16height, ai_out_gc620);
820 if (ret != 0)
821 {
822 ni_log(NI_LOG_ERROR, "Error: ai_pre init failed\n");
823 goto end;
824 }
825
826 // Parse the network layers to obtain the model
827 // input/output resolutions.
828 ret = ni_create_network(&ai_network[i]);
829 if (ret != 0)
830 {
831 ni_log(NI_LOG_ERROR, "Error: ai_pre create network failed\n");
832 goto end;
833 }
834
835 // channel_mode == 0: the model consumes/produces full
836 // frames, so make sure the model resolution matches the
837 // actual input/output resolution.
838 if ((ai_network[i].netw != p_hwframe->ui16width
839 && ai_network[i].neth != p_hwframe->ui16height)
840 && ai_network[i].netw != NI_VPU_ALIGN128(p_hwframe->ui16width))
841 {
843 "Model not match input, model resolution=%dx%d, input resolution=%dx%d\n",
844 ai_network[i].netw, ai_network[i].neth,
845 p_hwframe->ui16width, p_hwframe->ui16height);
846 ret = -1;
847 goto end;
848 }
849
850 if ((ai_network[i].net_out_w != ai_pre_params[i].out_width
851 && ai_network[i].net_out_h != ai_pre_params[i].out_height)
852 && ai_network[i].net_out_w != NI_VPU_ALIGN128(ai_pre_params[i].out_width))
853 {
855 "Model not match output, model resolution=%dx%d, output resolution=%dx%d\n",
856 ai_network[i].net_out_w, ai_network[i].net_out_h,
857 ai_pre_params[i].out_width, ai_pre_params[i].out_height);
858 ret = -1;
859 goto end;
860 }
861 }
862
863 // ai_pre preserves the decoder pixel format on its output.
864 ret = ai_pre_filter(&ai_ctx[i], &ai_network[i].raw, &out_frame.data.frame,
865 &filter_out_frame[i], &ai_pre_params[i], ai_out_gc620);
866 if (ret != 0)
867 {
868 ni_log(NI_LOG_ERROR, "Error: ai_pre filter failed\n");
869 goto end;
870 }
871
872 frame_to_enc[i] = &filter_out_frame[i];
873 }
874 else if (drawbox_params.enabled)
875 {
876 if(!hw_frame_ref_flag)
877 {
878 hw_frame_ref_flag = 1;
879 ni_hw_frame_ref(p_hwframe);
880 }
881
882 drawbox_filter(&crop_ctx, &pad_ctx, &ovly_ctx, &fmt_ctx, &out_frame.data.frame, &filter_out_frame[0],
883 &drawbox_params, xcoderGUID, ni_to_gc620_pix_fmt(dec_ctx.pixel_format), GC620_I420);
884 for (i = 0; i < output_total; i++)
885 {
886 frame_to_enc[i] = &filter_out_frame[0];
887 }
888 break;
889 }
890
891 if (!scale_params[i].enabled && !ai_pre_params[i].enabled)
892 recycle_hw_frame_for_scaler = 0;
893 }
894
895 // If the decoder generates a hardware frame, that frame is passed to the filter or the encoder directly.
896 // Once the (scaler) filter has used it, the frame should be recycled/unreferenced. (It is done here.)
897 // The filter then creates a new hardware frame, which is sent to the encoder and later recycled.
898 // When one transcoder uses a filter and another transcoder does not, the hardware frame produced
899 // by the decoder must NOT be recycled after the filter, because it will still be used by
900 // the encoder and will be recycled later. recycle_hw_frame_for_scaler is a flag for this purpose.
901 if((hw_frame_ref_flag) && (recycle_hw_frame_for_scaler))
902 {
903 hw_frame_ref_flag = 0;
905 }
906
907 if (!encoder_opened)
908 {
909 for (i = 0; i < output_total; i++)
910 {
911 p_hwframe2[i] = dec_ctx.hw_action == NI_CODEC_HW_ENABLE ?
912 (niFrameSurface1_t *)frame_to_enc[i]->data.frame.p_data[3] : NULL;
913
914 if (scale_params[i].enabled)
915 enc_pix_fmt[i] = gc620_to_ni_pix_fmt(scale_params[i].format);
916 else if (ai_pre_params[i].enabled)
917 enc_pix_fmt[i] = dec_ctx.pixel_format;
918 else if (drawbox_params.enabled)
919 enc_pix_fmt[i] = NI_PIX_FMT_YUV420P;
920 else
921 enc_pix_fmt[i] = dec_ctx.pixel_format;
922 }
923
924 ret = encoder_open2(&ctx, enc_ctx, p_enc_api_param, output_total, enc_conf_params,
925 enc_gop_params, &out_frame.data.frame, output_width, output_height,
926 fps_num, fps_den, bitrate, enc_codec_format, enc_pix_fmt,
927 out_frame.data.frame.aspect_ratio_idc, xcoderGUID, p_hwframe2, 0, false);
928 if (ret != 0)
929 {
930 break;
931 }
932 encoder_opened = 1;
933
934 do
935 {
936 receive_rc = encoder_receive2(&ctx, enc_ctx, &enc_in_frame, out_packet,
937 output_width, output_height, output_total, output_fp);
938 }
939 while (receive_rc == NI_TEST_RETCODE_EAGAIN);
940
941 if (receive_rc == NI_TEST_RETCODE_SUCCESS)
942 {
943 ni_log(NI_LOG_INFO, "Got encoded sequence header packet\n");
944 }
945 else
946 {
947 ni_log(NI_LOG_ERROR, "Failed to get encoded sequence header packet, retcode %d\n", receive_rc);
948 ret = receive_rc;
949 break;
950 }
951 }
952 }
953
954 //encode_send
955 for (i = 0; i < output_total; i++)
956 {
957 ctx.curr_enc_index = i;
958 // YUV Sending
959 send_rc = encoder_send_data2(&ctx, &enc_ctx[i], frame_to_enc[i], &enc_in_frame, output_width[i], output_height[i]);
960
961 if (send_rc < 0) //Error
962 {
963 if (dec_ctx.hw_action)
964 {
965 p_hwframe = (niFrameSurface1_t *)frame_to_enc[i]->data.frame.p_data[3];
966 ni_hw_frame_ref(p_hwframe);
967 } else
968 {
969 ni_decoder_frame_buffer_free(&frame_to_enc[i]->data.frame);
970 }
971 break;
972 } else if (send_rc == NI_TEST_RETCODE_EAGAIN)
973 {
974 // need to resend
975 i--;
976 continue;
977 } else if (dec_ctx.hw_action && !ctx.enc_eos_sent[i])
978 {
979 p_hwframe = (niFrameSurface1_t *)frame_to_enc[i]->data.frame.p_data[3];
980 ni_hw_frame_ref(p_hwframe);
981 }
982
983 // encoder send handling
984 if (dec_ctx.hw_action)
985 {
986 ni_frame_wipe_aux_data(&frame_to_enc[i]->data.frame);
987 } else
988 {
989 ni_decoder_frame_buffer_free(&frame_to_enc[i]->data.frame);
990 }
991 }
992
993 if (send_rc < 0)
994 {
995 break;
996 }
997
998encode_recv:
999 receive_rc = encoder_receive2(&ctx, enc_ctx, &enc_in_frame, out_packet,
1000 output_width, output_height, output_total, output_fp);
1001
1002 for (i = 0; receive_rc >= 0 && i < output_total; i++)
1003 {
1004 if (!ctx.enc_eos_received[i])
1005 {
1006 ni_log(NI_LOG_DEBUG, "enc %d continues to read!\n", i);
1007 end_of_all_streams = 0;
1008 break;
1009 } else
1010 {
1011 ni_log(NI_LOG_DEBUG, "enc %d eos !\n", i);
1012 end_of_all_streams = 1;
1013 }
1014 }
1015
1017 if (current_time - previous_time >= (uint64_t)1000000000) {
1018 ni_log(NI_LOG_INFO, "Decoder stats: received %u frames, fps %.2f, total bytes %u\n",
1020 (float)ctx.num_frames_received / (float)(current_time - ctx.start_time) * (float)1000000000,
1022 for (i = 0; i < output_total; i++)
1023 {
1024 ni_log(NI_LOG_INFO, "Encoder %d stats: received %u packets, fps %.2f, total bytes %u\n",
1025 i, ctx.num_packets_received[i],
1026 (float)enc_ctx[i].frame_num / (float)(current_time - ctx.start_time) * (float)1000000000,
1028 }
1030 }
1031 }
1032
1033end:
1034 decoder_stat_report_and_close(&ctx, &dec_ctx);
1035 encoder_stat_report_and_close(&ctx, enc_ctx, output_total);
1036
1037 for (i = 0; i < output_total; i++)
1038 {
1039 if (ai_pre_params[i].enabled)
1040 {
1042 ni_destroy_network(&ai_network[i]);
1043 }
1044 }
1045
1046#ifdef _WIN32
1048 for (i = 0; i < output_total; i++)
1049 {
1050 ni_device_close(enc_ctx[i].device_handle);
1051 if (scale_params[i].enabled)
1052 {
1053 ni_device_close(sca_ctx[i].device_handle);
1054 }
1055 if (ai_pre_params[i].enabled)
1056 {
1057 ni_device_close(ai_ctx[i].device_handle);
1058 }
1059 }
1060 if (drawbox_params.enabled)
1061 {
1066 }
1067#elif __linux__
1070 for (i = 0; i < output_total; i++)
1071 {
1072 ni_device_close(enc_ctx[i].device_handle);
1073 ni_device_close(enc_ctx[i].blk_io_handle);
1074 if (scale_params[i].enabled)
1075 {
1076 ni_device_close(sca_ctx[i].device_handle);
1077 ni_device_close(sca_ctx[i].blk_io_handle);
1078 }
1079 if (ai_pre_params[i].enabled)
1080 {
1081 ni_device_close(ai_ctx[i].device_handle);
1082 ni_device_close(ai_ctx[i].blk_io_handle);
1083 }
1084 }
1085 if (drawbox_params.enabled)
1086 {
1095 }
1096#endif
1097
1099 if (dec_ctx.hw_action == NI_CODEC_HW_ENABLE)
1100 {
1101 ni_frame_buffer_free(&out_frame.data.frame);
1102 } else
1103 {
1105 }
1106 for (i = 0; i < output_total; i++)
1107 {
1108 ni_frame_buffer_free(&filter_out_frame[i].data.frame);
1109 }
1110
1111 ni_frame_buffer_free(&enc_in_frame.data.frame);
1112 for (i = 0; i < output_total; i++)
1113 {
1114 ni_packet_buffer_free(&out_packet[i].data.packet);
1115 }
1116
1118 for (i = 0; i < output_total; i++)
1119 {
1121 if (output_fp[i] != NULL)
1122 {
1123 fclose(output_fp[i]);
1124 }
1125 if (scale_params[i].enabled)
1126 {
1128 }
1129 if (ai_pre_params[i].enabled)
1130 {
1132 }
1133 }
1134 if (drawbox_params.enabled)
1135 {
1140 }
1141
1142 free(ctx.file_cache);
1143
1144 for(i = 0; i < MAX_OUTPUT_FILES; ++i)
1145 {
1146 free(ctx.enc_pts_queue[i]);
1147 ctx.enc_pts_queue[i] = NULL;
1148 }
1149
1150 free(p_dec_api_param);
1151 free(p_enc_api_param);
1152
1153 return ret;
1154}
int main()
Definition client.cpp:51
void decoder_stat_report_and_close(ni_demo_context_t *p_ctx, ni_session_context_t *p_dec_ctx)
int probe_h264_stream_info(ni_demo_context_t *p_ctx, ni_h264_sps_t *sps)
int decoder_receive_data(ni_demo_context_t *p_ctx, ni_session_context_t *p_dec_ctx, ni_session_data_io_t *p_out_data, int output_video_width, int output_video_height, FILE *p_file, int write_to_file, int *p_rx_size)
Receive decoded output data from decoder.
int decoder_open_session(ni_session_context_t *p_dec_ctx, int iXcoderGUID, ni_xcoder_params_t *p_dec_params)
decoder session open
int probe_h265_stream_info(ni_demo_context_t *p_ctx, ni_h265_sps_t *sps)
int probe_vp9_stream_info(ni_demo_context_t *p_ctx, ni_vp9_header_info_t *vp9_info)
int decoder_send_data(ni_demo_context_t *p_ctx, ni_session_context_t *p_dec_ctx, ni_session_data_io_t *p_in_data, int input_video_width, int input_video_height, void *stream_info)
Send decoder input data.
#define NI_XCODER_REVISION
Definition ni_defs.h:98
@ NI_DEVICE_TYPE_AI
Definition ni_defs.h:363
@ NI_RETCODE_ERROR_MEM_ALOC
Definition ni_defs.h:452
@ NI_RETCODE_INVALID_PARAM
Definition ni_defs.h:450
void ni_frame_wipe_aux_data(ni_frame_t *frame)
Free and remove all auxiliary data from the frame.
ni_retcode_t ni_frame_buffer_free(ni_frame_t *p_frame)
Free frame buffer that was previously allocated with either ni_frame_buffer_alloc or ni_encoder_frame...
ni_retcode_t ni_device_session_close(ni_session_context_t *p_ctx, int eos_recieved, ni_device_type_t device_type)
Close device session that was previously opened by calling ni_device_session_open() If device_type is...
ni_retcode_t ni_packet_buffer_free(ni_packet_t *p_packet)
Free packet buffer that was previously allocated with ni_packet_buffer_alloc.
ni_retcode_t ni_device_session_context_init(ni_session_context_t *p_ctx)
Initialize already allocated session context to a known state.
ni_retcode_t ni_decoder_init_default_params(ni_xcoder_params_t *p_param, int fps_num, int fps_denom, long bit_rate, int width, int height)
Initialize default decoder parameters.
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
void ni_device_session_context_clear(ni_session_context_t *p_ctx)
Clear already allocated session context.
ni_retcode_t ni_decoder_frame_buffer_free(ni_frame_t *p_frame)
Free decoder frame buffer that was previously allocated with ni_decoder_frame_buffer_alloc,...
#define GC620_I420
#define NI_VPU_ALIGN128(_x)
@ NI_CODEC_HW_ENABLE
@ NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_AV1
@ NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_VP9
ni_pix_fmt_t
@ NI_PIX_FMT_YUV420P
int encoder_open2(ni_demo_context_t *p_ctx, ni_session_context_t *enc_ctx_list, ni_xcoder_params_t *p_api_param_list, int output_total, char p_enc_conf_params[][2048], char p_enc_conf_gop[][2048], ni_frame_t *p_ni_frame, int width[], int height[], int fps_num, int fps_den, int bitrate, int codec_format, ni_pix_fmt_t pix_fmt[], int aspect_ratio_idc, int xcoder_guid, niFrameSurface1_t *p_surface[], int multi_thread, bool check_zerocopy)
int encoder_receive2(ni_demo_context_t *p_ctx, ni_session_context_t *enc_ctx_list, ni_session_data_io_t *in_frame, ni_session_data_io_t *pkt, int width[], int height[], int output_total, FILE **pfs_list)
int encoder_send_data2(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_dec_out_data, ni_session_data_io_t *p_enc_in_data, int input_video_width, int input_video_height)
void encoder_stat_report_and_close(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx_list, int output_total)
int scale_filter(ni_session_context_t *p_ctx, ni_frame_t *p_frame_in, ni_session_data_io_t *p_data_out, int iXcoderGUID, int scale_width, int scale_height, int in_format, int out_format)
Do a scale and/or format-change operation.
int drawbox_filter(ni_session_context_t *p_crop_ctx, ni_session_context_t *p_pad_ctx, ni_session_context_t *p_overlay_ctx, ni_session_context_t *p_fmt_ctx, ni_frame_t *p_frame_in, ni_session_data_io_t *p_data_out, ni_drawbox_params_t *p_box_params, int iXcoderGUID, int input_format, int output_format)
Use crop->pad->overlay to simulate a drawbox filter.
int ai_pre_filter(ni_session_context_t *p_ai_ctx, ni_network_data_t *p_network, ni_frame_t *p_frame_in, ni_session_data_io_t *p_data_out, ni_ai_pre_params_t *params, int in_gc620_format)
Run one AI preprocess operation on a hardware frame. The output is a new hardware frame preserving th...
int retrieve_filter_params(char filter_params[], ni_scale_params_t *scale_params, ni_drawbox_params_t *drawbox_params, ni_ai_pre_params_t *ai_pre_params)
int ai_pre_filter_init(ni_session_context_t *p_ai_ctx, ni_network_data_t *p_network, int iXcoderGUID, ni_ai_pre_params_t *params, int in_width, int in_height, int in_gc620_format)
Open an AI session, configure the network binary and create the hardware output frame pool used by th...
ni_pix_fmt_t gc620_to_ni_pix_fmt(int pix_fmt)
void ni_hw_frame_unref(uint16_t hwframe_index)
int ni_to_gc620_pix_fmt(ni_pix_fmt_t pix_fmt)
int read_and_cache_file(ni_demo_context_t *ctx, char *filename)
void print_version(void)
void ni_hw_frame_ref(const niFrameSurface1_t *p_surface)
#define MAX_OUTPUT_FILES
#define NI_TEST_RETCODE_SUCCESS
#define NI_TEST_RETCODE_EAGAIN
#define NI_TEST_RETCODE_END_OF_STREAM
#define FILE_NAME_LEN
char * optarg
Definition ni_getopt.c:33
int getopt_long(int argc, char *argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition ni_getopt.c:99
Implementation of getopt() and getopt_long() for Windows environment.
#define no_argument
Definition ni_getopt.h:85
#define required_argument
Definition ni_getopt.h:86
ni_log_level_t arg_to_ni_log_level(const char *arg_str)
Convert terminal arg string to ni_log_level_t.
Definition ni_log.c:262
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
Definition ni_log.c:202
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition ni_log.c:183
Logging definitions.
ni_log_level_t
Definition ni_log.h:58
@ NI_LOG_DEBUG
Definition ni_log.h:64
@ NI_LOG_ERROR
Definition ni_log.h:62
@ NI_LOG_INFO
Definition ni_log.h:63
@ NI_LOG_INVALID
Definition ni_log.h:59
struct timeval current_time
struct timeval previous_time
uint32_t ni_ai_network_layer_dims(ni_network_layer_params_t *p_param)
Definition ni_util.c:4080
ni_retcode_t ni_fopen(FILE **fp, const char *filename, const char *mode)
Definition ni_util.c:998
ni_retcode_t ni_strcpy(char *dest, size_t dmax, const char *src)
Definition ni_util.c:460
int ni_retrieve_decoder_params(char xcoderParams[], ni_xcoder_params_t *params, ni_session_context_t *ctx)
retrieve decoder config parameter values from –decoder-params
Definition ni_util.c:4646
uint64_t ni_gettime_ns(void)
Definition ni_util.c:2701
Utility definitions.
struct _ni_ai_pre_network_layer ni_ai_pre_network_layer_t
struct _ni_ai_pre_network ni_ai_pre_network_t
ni_ai_pre_network_layer_t * layers
uint64_t dec_total_bytes_received
uint64_t num_packets_received[MAX_OUTPUT_FILES]
ni_pts_queue * enc_pts_queue[MAX_OUTPUT_FILES]
int enc_eos_received[MAX_OUTPUT_FILES]
int enc_eos_sent[MAX_OUTPUT_FILES]
uint64_t enc_total_bytes_received[MAX_OUTPUT_FILES]
uint8_t aspect_ratio_idc
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
int bit_depth_luma
bit_depth_luma_minus8 + 8
ni_h265_window_t pic_conf_win
unsigned int left_offset
unsigned int bottom_offset
unsigned int right_offset
unsigned int top_offset
ni_network_layer_info_t linfo
ni_network_layer_params_t * in_param
ni_network_layer_params_t * out_param
ni_device_handle_t device_handle
ni_device_handle_t blk_io_handle
union _ni_session_data_io::@19 data
struct _ni_vp9_header_info::@3 timebase