libxcoder  5.4.0
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 
43 static void print_usage(void)
44 {
46  "Video transcoding demo application directly using Netint Libxcoder version %s\n"
47  "Usage: ni_xcoder_transcode_filter [options]\n"
48  "\n"
49  "options:\n"
50  "-h | --help Show this message.\n"
51  "-v | --version Print version info.\n"
52  "-i | --input (Required) Input file path.\n"
53  "-o | --output (Required) Output file path.\n"
54  " Can be specified multiple (max %d) times\n"
55  " to run multiple encoding instances simultaneously.\n"
56  "-m | --dec-codec (Required) Decoder codec format. Must match the codec of input file.\n"
57  " [a|avc, h|hevc, v|vp9]\n"
58  "-n | --enc-codec (Required) Encoder codec format.\n"
59  " [a|avc, h|hevc, x|av1] (x is in ivf container format)\n"
60  "-l | --loglevel Set loglevel of this application and libxcoder API.\n"
61  " [none, fatal, error, info, debug, trace]\n"
62  " (Default: info)\n"
63  "-c | --card Set card index to use.\n"
64  " See `ni_rsrc_mon` for info of cards on system.\n"
65  " (Default: 0)\n"
66  "-r | --repeat To loop input X times. Must be a positive integer\n"
67  " (Default: 1)\n"
68  "-d | --decoder-params Decoding params. See \"Decoding Parameters\" chapter in\n"
69  " QuadraIntegration&ProgrammingGuide*.pdf for help.\n"
70  " (Default: \"\")\n"
71  "-e | --encoder-params Encoding params. See \"Encoding Parameters\" chapter in\n"
72  " QuadraIntegration&ProgrammingGuide*.pdf for help.\n"
73  " Can be specified multiple (max %d) times,\n"
74  " must match the number of -o specified.\n"
75  " (Default: \"\")\n"
76  "-g | --encoder-gop Custom GOP for encoding. See \"Custom Gop Structure\" chapter in\n"
77  " QuadraIntegration&ProgrammingGuide*.pdf for help.\n"
78  " gopPresetIdx must be set to 0 to be in effect.\n"
79  " (Default: \"\")\n"
80  "-u | --user-data-sei-passthru (No argument) Enable user data unregistered SEI passthrough when specified\n"
81  "-f | --vf Video filter params. The only supported filters in this demo are:\n"
82  " ni_quadra_scale - supported params [width, height, format]\n"
83  " e.g. ni_quadra_scale=width=1280:height=720:format=yuv420p\n"
84  " ni_quadra_drawbox - supported params [x, y, width, height]\n"
85  " e.g. ni_quadra_drawbox=x=300:y=150:width=600:height=400\n"
86  " (Default: \"\")\n"
88 }
89 
90 int main(int argc, char *argv[])
91 {
92  int i, ret = 0;
93  ni_demo_context_t ctx = {0};
94  char in_filename[FILE_NAME_LEN] = {0};
95  char out_filename[MAX_OUTPUT_FILES][FILE_NAME_LEN] = {0};
96  FILE *output_fp[MAX_OUTPUT_FILES] = {0};
97  int o_index = 0, e_index = 0, g_index = 0, f_index = 0;
98  int output_total = 0;
99  int input_width = 0, input_height = 0, bit_depth = 8;
100  int output_width[MAX_OUTPUT_FILES] = {0};
101  int output_height[MAX_OUTPUT_FILES] = {0};
102  int dec_codec_format = -1, enc_codec_format = -1;
103  ni_log_level_t log_level;
104  int xcoderGUID = 0;
105  char *n;
106  char dec_conf_params[2048] = {0};
107  char filter_conf_params[MAX_OUTPUT_FILES][2048] = {0};
108  char enc_conf_params[MAX_OUTPUT_FILES][2048] = {0};
109  char enc_gop_params[MAX_OUTPUT_FILES][2048] = {0};
110  int user_data_sei_passthru = 0;
111  ni_h264_sps_t avc_sps = {0};
112  ni_h265_sps_t hevc_sps = {0};
113  ni_vp9_header_info_t vp9_info = {0};
114  ni_xcoder_params_t *p_dec_api_param = NULL;
115  ni_xcoder_params_t *p_enc_api_param = NULL;
116  ni_session_context_t dec_ctx = {0};
117  ni_session_context_t enc_ctx[MAX_OUTPUT_FILES] = {0};
118  ni_session_context_t sca_ctx[MAX_OUTPUT_FILES] = {0};
119  ni_session_context_t crop_ctx = {0};
120  ni_session_context_t pad_ctx = {0};
121  ni_session_context_t ovly_ctx = {0};
122  ni_session_context_t fmt_ctx = {0};
123  int send_rc = NI_TEST_RETCODE_SUCCESS, receive_rc = NI_TEST_RETCODE_SUCCESS, rx_size = 0;
124  void *p_stream_info = NULL;
125  int fps_num = 30, fps_den = 1, bitrate = 200000;
126  uint64_t current_time, previous_time;
127  ni_session_data_io_t in_pkt = {0};
128  ni_session_data_io_t out_frame = {0};
129  ni_session_data_io_t filter_out_frame[MAX_OUTPUT_FILES] = {0};
130  ni_session_data_io_t *frame_to_enc[MAX_OUTPUT_FILES];
131  ni_session_data_io_t enc_in_frame = {0};
132  ni_session_data_io_t out_packet[MAX_OUTPUT_FILES] = {0};
133  niFrameSurface1_t *p_hwframe = NULL;
134  niFrameSurface1_t *p_hwframe2[MAX_OUTPUT_FILES];
135  int encoder_opened = 0, end_of_all_streams = 0;
136  ni_scale_params_t scale_params[MAX_OUTPUT_FILES] = {0};
137  ni_drawbox_params_t drawbox_params = {0};
138  ni_pix_fmt_t enc_pix_fmt[MAX_OUTPUT_FILES];
139  int hw_frame_ref_flag = 0;
140  int recycle_hw_frame_for_scaler = 0;
141 
142  int opt;
143  int opt_index;
144  const char *opt_string = "hvi:o:m:n:l:c:r:d:e:g:uf:";
145  static struct option long_options[] = {
146  {"help", no_argument, NULL, 'h'},
147  {"version", no_argument, NULL, 'v'},
148  {"input", required_argument, NULL, 'i'},
149  {"output", required_argument, NULL, 'o'},
150  {"dec-codec", required_argument, NULL, 'n'},
151  {"enc-codec", required_argument, NULL, 'm'},
152  {"loglevel", required_argument, NULL, 'l'},
153  {"card", required_argument, NULL, 'c'},
154  {"repeat", required_argument, NULL, 'r'},
155  {"decoder-params", required_argument, NULL, 'd'},
156  {"encoder-params", required_argument, NULL, 'e'},
157  {"encoder-gop", required_argument, NULL, 'g'},
158  {"user-data-sei-passthru", no_argument, NULL, 'u'},
159  {"vf", required_argument, NULL, 'f'},
160  {NULL, 0, NULL, 0},
161  };
162 
163  while ((opt = getopt_long(argc, argv, opt_string, long_options, &opt_index)) != -1)
164  {
165  switch (opt)
166  {
167  case 'h':
168  print_usage();
169  ret = 0;
170  goto end;
171  case 'v':
172  print_version();
173  ret = 0;
174  goto end;
175  case 'i':
176  ni_strcpy(in_filename, FILE_NAME_LEN, optarg);
177  break;
178  case 'o':
179  if (o_index == MAX_OUTPUT_FILES)
180  {
181  ni_log(NI_LOG_ERROR, "Error: number of output files cannot exceed %d\n", MAX_OUTPUT_FILES);
182  ret = -1;
183  goto end;
184  }
185 
186  for (i = 0; i < o_index; i++)
187  {
188  if (0 == strcmp(out_filename[i], optarg))
189  {
190  ni_log(NI_LOG_ERROR, "Error: output file names must be unique: %s\n", optarg);
191  ret = -1;
192  goto end;
193  }
194  }
195 
196  ni_strcpy(out_filename[o_index], FILE_NAME_LEN, optarg);
197  o_index++;
198  break;
199  case 'm':
200  // Accept both upper and lower case
201  for (i = 0; i < strlen(optarg); i++)
202  {
203  optarg[i] = (char)tolower((unsigned char)optarg[i]);
204  }
205  if (strcmp(optarg, "a") == 0 || strcmp(optarg, "avc") == 0)
206  {
207  dec_codec_format = NI_CODEC_FORMAT_H264;
208  }
209  else if (strcmp(optarg, "h") == 0 || strcmp(optarg, "hevc") == 0)
210  {
211  dec_codec_format = NI_CODEC_FORMAT_H265;
212  }
213  else if (strcmp(optarg, "v") == 0 || strcmp(optarg, "vp9") == 0)
214  {
215  dec_codec_format = NI_CODEC_FORMAT_VP9;
216  }
217  else
218  {
219  ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -m | --dec-codec option\n"
220  "Must be one of [a|avc, h|hevc, v|vp9]\n", optarg);
221  ret = -1;
222  goto end;
223  }
224  break;
225  case 'n':
226  // Accept both upper and lower case
227  for (i = 0; i < strlen(optarg); i++)
228  {
229  optarg[i] = (char)tolower((unsigned char)optarg[i]);
230  }
231  if (strcmp(optarg, "a") == 0 || strcmp(optarg, "avc") == 0)
232  {
233  enc_codec_format = NI_CODEC_FORMAT_H264;
234  }
235  else if (strcmp(optarg, "h") == 0 || strcmp(optarg, "hevc") == 0)
236  {
237  enc_codec_format = NI_CODEC_FORMAT_H265;
238  }
239  else if (strcmp(optarg, "x") == 0 || strcmp(optarg, "av1") == 0)
240  {
241  enc_codec_format = NI_CODEC_FORMAT_AV1;
242  }
243  else
244  {
245  ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -n | --enc-codec option\n"
246  "Must be one of [a|avc, h|hevc, x|av1]\n", optarg);
247  ret = -1;
248  goto end;
249  }
250  break;
251  case 'l':
252  log_level = arg_to_ni_log_level(optarg);
253  if (log_level != NI_LOG_INVALID)
254  {
255  ni_log_set_level(log_level);
256  }
257  else
258  {
259  ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -l | --loglevel option\n"
260  "Must be one of [none, fatal, error, info, debug, trace]\n", optarg);
261  ret = -1;
262  goto end;
263  }
264  break;
265  case 'c':
266  xcoderGUID = (int)strtol(optarg, &n, 10);
267  if (n == optarg || *n != '\0' || xcoderGUID < 0)
268  {
269  ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -c | --card option\n"
270  "Must be a non-negative integer\n", optarg);
271  ret = -1;
272  goto end;
273  }
274  break;
275  case 'r':
276  ctx.loops_left = strtol(optarg, &n, 10);
277  if (n == optarg || *n != '\0' || !(ctx.loops_left >= 1))
278  {
279  ni_log(NI_LOG_ERROR, "Error: Invalid value \"%s\" for -r | --repeat option\n"
280  "Must be a positive integer\n", optarg);
281  ret = -1;
282  goto end;
283  }
284  break;
285  case 'd':
286  ni_strcpy(dec_conf_params, sizeof(dec_conf_params), optarg);
287  break;
288  case 'e':
289  if (e_index == MAX_OUTPUT_FILES)
290  {
291  ni_log(NI_LOG_ERROR, "Error: number of encoder config cannot exceed %d\n", MAX_OUTPUT_FILES);
292  ret = -1;
293  goto end;
294  }
295  ni_strcpy(enc_conf_params[e_index], sizeof(enc_conf_params[e_index]), optarg);
296  e_index++;
297  break;
298  case 'g':
299  if (g_index == MAX_OUTPUT_FILES)
300  {
301  ni_log(NI_LOG_ERROR, "Error: number of encoder gop settings cannot exceed %d\n", MAX_OUTPUT_FILES);
302  ret = -1;
303  goto end;
304  }
305  ni_strcpy(enc_gop_params[g_index], sizeof(enc_gop_params[g_index]), optarg);
306  g_index++;
307  break;
308  case 'u':
309  user_data_sei_passthru = 1;
310  break;
311  case 'f':
312  if (f_index == MAX_OUTPUT_FILES)
313  {
314  ni_log(NI_LOG_ERROR, "Error: number of filter config cannot exceed %d\n", MAX_OUTPUT_FILES);
315  ret = -1;
316  goto end;
317  }
318  ni_strcpy(filter_conf_params[f_index], sizeof(filter_conf_params[f_index]), optarg);
319  f_index++;
320  break;
321  default:
322  print_usage();
323  ret = -1;
324  goto end;
325  }
326  }
327 
328  if (!in_filename[0]) {
329  ni_log(NI_LOG_ERROR, "Error: Missing input file argument (-i | --input)\n");
330  ret = -1;
331  goto end;
332  }
333 
334  if (o_index == 0) {
335  ni_log(NI_LOG_ERROR, "Error: Missing output file argument (-o | --output)\n");
336  ret = -1;
337  goto end;
338  }
339 
340  if (dec_codec_format == -1) {
341  ni_log(NI_LOG_ERROR, "Error: Missing decoder codec argument (-m | --dec-codec)\n");
342  ret = -1;
343  goto end;
344  }
345 
346  if (enc_codec_format == -1) {
347  ni_log(NI_LOG_ERROR, "Error: Missing encoder codec argument (-n | --enc-codec)\n");
348  ret = -1;
349  goto end;
350  }
351 
352  ret = read_and_cache_file(&ctx, in_filename);
353  if (ret)
354  {
355  ni_log(NI_LOG_ERROR, "Error: Read input file failure\n");
356  goto end;
357  }
358 
359  output_total = o_index;
360  for (i = 0; i < output_total; i++)
361  {
362  if (strcmp(out_filename[i], "null") != 0 &&
363  strcmp(out_filename[i], "/dev/null") != 0)
364  {
365  output_fp[i] = NULL;
366  ni_fopen(&(output_fp[i]), out_filename[i], "wb");
367  if (!output_fp[i])
368  {
369  ni_log(NI_LOG_ERROR, "Error: Failed to open %s\n", out_filename[i]);
370  ret = -1;
371  goto end;
372  }
373  ni_log(NI_LOG_INFO, "Opened output file: %s\n", out_filename[i]);
374  } else
375  {
376  output_fp[i] = NULL;
377  ni_log(NI_LOG_INFO, "Note: Requested NULL output for index %d, no output file will be generated\n", i);
378  }
379 
380  frame_to_enc[i] = NULL;
381  enc_pix_fmt[i] = NI_PIX_FMT_YUV420P;
382  p_hwframe2[i] = NULL;
383  }
384 
385  p_dec_api_param = malloc(sizeof(ni_xcoder_params_t));
386  if (!p_dec_api_param)
387  {
388  ni_log(NI_LOG_ERROR, "Error: failed to allocate p_dec_api_param\n");
389  ret = -1;
390  goto end;
391  }
392 
393  p_enc_api_param = calloc(output_total, sizeof(ni_xcoder_params_t));
394  if (!p_enc_api_param)
395  {
396  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for p_enc_api_param\n");
397  ret = -1;
398  goto end;
399  }
400 
401  if (dec_codec_format == NI_CODEC_FORMAT_H264)
402  {
403  ret = probe_h264_stream_info(&ctx, &avc_sps);
404  if (ret)
405  {
407  "ERROR: Failed to probe input file as H.264, file format not supported!\n");
408  goto end;
409  }
410 
411  bit_depth = avc_sps.bit_depth_luma;
412  input_width = avc_sps.width;
413  input_height = avc_sps.height;
414  ni_log(NI_LOG_DEBUG, "Using probed H.264 source info: %d bits, resolution %dx%d\n",
415  bit_depth, input_width, input_height);
416  } else if (dec_codec_format == NI_CODEC_FORMAT_H265)
417  {
418  ret = probe_h265_stream_info(&ctx, &hevc_sps);
419  if (ret)
420  {
422  "ERROR: Failed to probe input file as H.265, file format not supported!\n");
423  goto end;
424  }
425  bit_depth = hevc_sps.bit_depth_chroma;
426  input_width = (int)(hevc_sps.width -
427  (hevc_sps.pic_conf_win.left_offset +
428  hevc_sps.pic_conf_win.right_offset));
429  input_height = (int)(hevc_sps.height -
430  (hevc_sps.pic_conf_win.top_offset +
431  hevc_sps.pic_conf_win.bottom_offset));
432  ni_log(NI_LOG_INFO, "Using probed H.265 source info: %d bits, resolution %dx%d\n",
433  bit_depth, input_width, input_height);
434  } else if (dec_codec_format == NI_CODEC_FORMAT_VP9)
435  {
436  ret = probe_vp9_stream_info(&ctx, &vp9_info);
437  if (ret)
438  {
440  "ERROR: Failed to probe input file as VP9, file format not supported!\n");
441  goto end;
442  }
443  bit_depth = vp9_info.profile ? 10 : 8;
444  input_width = vp9_info.width;
445  input_height = vp9_info.height;
447  "Using probed VP9 source info: %d bits, resolution %dx%d, timebase %u/%u\n",
448  bit_depth, input_width, input_height,
449  vp9_info.timebase.den, vp9_info.timebase.num);
450  }
451 
452  // set up decoder config params with some hard-coded values
453  ret = ni_decoder_init_default_params(p_dec_api_param, 25, 1, 200000, input_width, input_height);
454  if (ret)
455  {
456  ni_log(NI_LOG_ERROR, "Error: Failed to init default decoder config\n");
457  goto end;
458  }
459 
460  ret = ni_device_session_context_init(&dec_ctx);
461  if (ret)
462  {
463  ni_log(NI_LOG_ERROR, "Error: Failed to init decoder context\n");
464  goto end;
465  }
466 
467  dec_ctx.codec_format = dec_codec_format;
468  dec_ctx.src_bit_depth = bit_depth;
469  dec_ctx.bit_depth_factor = 1;
470  if (10 == dec_ctx.src_bit_depth)
471  {
472  dec_ctx.bit_depth_factor = 2;
473  }
474  if ((NI_CODEC_FORMAT_H264 == dec_codec_format) || (NI_CODEC_FORMAT_H265 == dec_codec_format))
475  dec_ctx.enable_user_data_sei_passthru = user_data_sei_passthru;
476 
477  // check and set ni_decoder_params from --xcoder-params
478  ret = ni_retrieve_decoder_params(dec_conf_params, p_dec_api_param, &dec_ctx);
479  if (ret)
480  {
481  ni_log(NI_LOG_ERROR, "Error: decoder config params parsing error\n");
482  goto end;
483  }
484 
485  // Decode, use all the parameters specified by user
486  ret = decoder_open_session(&dec_ctx, xcoderGUID, p_dec_api_param);
487  if (ret)
488  {
489  ni_log(NI_LOG_ERROR, "Error: Failed to open decoder session\n");
490  goto end;
491  }
492 
493  for (i = 0; i < output_total; i++)
494  {
495  if (ni_device_session_context_init(&enc_ctx[i]) < 0)
496  {
497  ni_log(NI_LOG_ERROR, "Error: init encoder %d context error\n", i);
498  ret = -1;
499  goto end;
500  }
501  }
502 
503  for (i = 0; i < output_total; i++)
504  {
505  enc_ctx[i].codec_format = enc_codec_format;
506  output_width[i] = input_width;
507  output_height[i] = input_height;
508  }
509 
510  if (dec_codec_format == NI_CODEC_FORMAT_H264)
511  p_stream_info = &avc_sps;
512  else if (dec_codec_format == NI_CODEC_FORMAT_H265)
513  p_stream_info = &hevc_sps;
514  else if (dec_codec_format == NI_CODEC_FORMAT_VP9)
515  {
516  p_stream_info = &vp9_info;
517  fps_num = vp9_info.timebase.den;
518  fps_den = vp9_info.timebase.num;
519  }
520 
521  for (i = 0; i < output_total; i++)
522  {
523  if (filter_conf_params[i][0])
524  {
525  if (!dec_ctx.hw_action) {
526  ni_log(NI_LOG_ERROR, "Error: filters are only supported when hwframe is enabled (out=hw)\n");
527  ret = -1;
528  goto end;
529  }
530 
531  ret = retrieve_filter_params(filter_conf_params[i], &scale_params[i], &drawbox_params);
532  if (ret)
533  {
534  ni_log(NI_LOG_ERROR, "Error: failed to parse filter parameters: %s\n", filter_conf_params[i]);
535  goto end;
536  }
537  }
538 
539  if (scale_params[i].enabled)
540  {
541  ret = ni_device_session_context_init(&sca_ctx[i]);
542  if (ret)
543  {
544  ni_log(NI_LOG_ERROR, "Error: Failed to init scale context\n");
545  goto end;
546  }
547  output_width[i] = scale_params[i].width;
548  output_height[i] = scale_params[i].height;
549  }
550  else if ((drawbox_params.enabled)) // drawbox is only supported for a single instance in this example.
551  {
552  ret = ni_device_session_context_init(&crop_ctx);
553  if (ret)
554  {
555  ni_log(NI_LOG_ERROR, "Error: Failed to init crop context\n");
556  goto end;
557  }
558  ret = ni_device_session_context_init(&pad_ctx);
559  if (ret)
560  {
561  ni_log(NI_LOG_ERROR, "Error: Failed to init pad context\n");
562  goto end;
563  }
564  ret = ni_device_session_context_init(&ovly_ctx);
565  if (ret)
566  {
567  ni_log(NI_LOG_ERROR, "Error: Failed to init overlay context\n");
568  goto end;
569  }
570  ret = ni_device_session_context_init(&fmt_ctx);
571  if (ret)
572  {
573  ni_log(NI_LOG_ERROR, "Error: Failed to init format context\n");
574  goto end;
575  }
576  break;
577  }
578  }
579 
580  for (i = 0; i < output_total; i++)
581  {
582  if (drawbox_params.enabled && scale_params[i].enabled){
583  ni_log(NI_LOG_ERROR, "Error: Mixing scale and drawbox filter is not supported in this demo\n");
584  goto end;
585  }
586  ni_log(NI_LOG_INFO, "(Task %d) Starting to transcode: HWFrames %d, video resolution %dx%d -> %dx%d\n",
587  i, dec_ctx.hw_action, input_width, input_height, output_width[i], output_height[i]);
588  }
589 
590  ctx.start_time = ni_gettime_ns();
592 
593  while (!end_of_all_streams &&
594  (send_rc == NI_TEST_RETCODE_SUCCESS || receive_rc == NI_TEST_RETCODE_SUCCESS ||
595  (send_rc == NI_TEST_RETCODE_EAGAIN && receive_rc == NI_TEST_RETCODE_EAGAIN)))
596  {
597  // bitstream Sending
598 decode_send:
599  send_rc = decoder_send_data(&ctx, &dec_ctx, &in_pkt, input_width, input_height, p_stream_info);
600  if (send_rc < 0)
601  {
602  ni_log(NI_LOG_ERROR, "Error: decoder send packet failed\n");
603  ret = send_rc;
604  break;
605  }
606 
607  // YUV Receiving: not writing to file
608  receive_rc = decoder_receive_data(&ctx, &dec_ctx, &out_frame, input_width,
609  input_height, NULL, 0, &rx_size);
610 
611  for (i = 0; i < output_total; i++)
612  {
613  frame_to_enc[i] = &out_frame;
614  }
615 
616  if (receive_rc < 0)
617  {
618  ni_log(NI_LOG_ERROR, "Error: decoder receive frame failed\n");
619  ret = receive_rc;
620  break;
621  }
622  else if (receive_rc == NI_TEST_RETCODE_EAGAIN)
623  {
624  if (!dec_ctx.hw_action)
625  {
627  } else
628  {
629  ni_frame_buffer_free(&(out_frame.data.frame));
630  }
631 
632  // use first encode config low delay flag for call flow
633  if (p_enc_api_param[0].low_delay_mode <= 0 && encoder_opened)
634  {
635  ni_log(NI_LOG_DEBUG, "no decoder output, jump to encoder receive!\n");
636  goto encode_recv;
637  } else
638  {
639  ni_log(NI_LOG_DEBUG, "no decoder output, encode low_delay, jump to decoder send!\n");
640  goto decode_send;
641  }
642  }
643  else if (receive_rc != NI_TEST_RETCODE_END_OF_STREAM)
644  {
645 
646  p_hwframe = (niFrameSurface1_t *)out_frame.data.frame.p_data[3];
647  recycle_hw_frame_for_scaler = 1;
648  for (i = 0; i < output_total; i++)
649  {
650  if (scale_params[i].enabled)
651  {
652  if(!hw_frame_ref_flag)
653  {
654  hw_frame_ref_flag = 1;
655  ni_hw_frame_ref(p_hwframe);
656  }
657 
658  scale_filter(&sca_ctx[i], &out_frame.data.frame, &filter_out_frame[i], xcoderGUID, scale_params[i].width,
659  scale_params[i].height, ni_to_gc620_pix_fmt(dec_ctx.pixel_format), scale_params[i].format);
660  frame_to_enc[i] = &filter_out_frame[i];
661  }
662  else if (drawbox_params.enabled)
663  {
664  if(!hw_frame_ref_flag)
665  {
666  hw_frame_ref_flag = 1;
667  ni_hw_frame_ref(p_hwframe);
668  }
669 
670  drawbox_filter(&crop_ctx, &pad_ctx, &ovly_ctx, &fmt_ctx, &out_frame.data.frame, &filter_out_frame[0],
671  &drawbox_params, xcoderGUID, ni_to_gc620_pix_fmt(dec_ctx.pixel_format), GC620_I420);
672  for (i = 0; i < output_total; i++)
673  {
674  frame_to_enc[i] = &filter_out_frame[0];
675  }
676  break;
677  }
678 
679  if (!scale_params[i].enabled)
680  recycle_hw_frame_for_scaler = 0;
681  }
682 
683  // If the decoder generates a hardware frame, that frame is passed to the filter or the encoder directly.
684  // Once the (scaler) filter has used it, the frame should be recycled/unreferenced. (It is done here.)
685  // The filter then creates a new hardware frame, which is sent to the encoder and later recycled.
686  // When one transcoder uses a filter and another transcoder does not, the hardware frame produced
687  // by the decoder must NOT be recycled after the filter, because it will still be used by
688  // the encoder and will be recycled later. recycle_hw_frame_for_scaler is a flag for this purpose.
689  if((hw_frame_ref_flag) && (recycle_hw_frame_for_scaler))
690  {
691  hw_frame_ref_flag = 0;
692  ni_hw_frame_unref(p_hwframe->ui16FrameIdx);
693  }
694 
695  if (!encoder_opened)
696  {
697  for (i = 0; i < output_total; i++)
698  {
699  p_hwframe2[i] = dec_ctx.hw_action == NI_CODEC_HW_ENABLE ?
700  (niFrameSurface1_t *)frame_to_enc[i]->data.frame.p_data[3] : NULL;
701 
702  if (scale_params[i].enabled)
703  enc_pix_fmt[i] = gc620_to_ni_pix_fmt(scale_params[i].format);
704  else if (drawbox_params.enabled)
705  enc_pix_fmt[i] = NI_PIX_FMT_YUV420P;
706  else
707  enc_pix_fmt[i] = dec_ctx.pixel_format;
708  }
709 
710  ret = encoder_open2(&ctx, enc_ctx, p_enc_api_param, output_total, enc_conf_params,
711  enc_gop_params, &out_frame.data.frame, output_width, output_height,
712  fps_num, fps_den, bitrate, enc_codec_format, enc_pix_fmt,
713  out_frame.data.frame.aspect_ratio_idc, xcoderGUID, p_hwframe2, 0, false);
714  if (ret != 0)
715  {
716  break;
717  }
718  encoder_opened = 1;
719 
720  do
721  {
722  receive_rc = encoder_receive2(&ctx, enc_ctx, &enc_in_frame, out_packet,
723  output_width, output_height, output_total, output_fp);
724  }
725  while (receive_rc == NI_TEST_RETCODE_EAGAIN);
726 
727  if (receive_rc == NI_TEST_RETCODE_SUCCESS)
728  {
729  ni_log(NI_LOG_INFO, "Got encoded sequence header packet\n");
730  }
731  else
732  {
733  ni_log(NI_LOG_ERROR, "Failed to get encoded sequence header packet, retcode %d\n", receive_rc);
734  ret = receive_rc;
735  break;
736  }
737  }
738  }
739 
740  //encode_send
741  for (i = 0; i < output_total; i++)
742  {
743  ctx.curr_enc_index = i;
744  // YUV Sending
745  send_rc = encoder_send_data2(&ctx, &enc_ctx[i], frame_to_enc[i], &enc_in_frame, output_width[i], output_height[i]);
746 
747  if (send_rc < 0) //Error
748  {
749  if (dec_ctx.hw_action)
750  {
751  p_hwframe = (niFrameSurface1_t *)frame_to_enc[i]->data.frame.p_data[3];
752  ni_hw_frame_ref(p_hwframe);
753  } else
754  {
755  ni_decoder_frame_buffer_free(&frame_to_enc[i]->data.frame);
756  }
757  break;
758  } else if (send_rc == NI_TEST_RETCODE_EAGAIN)
759  {
760  // need to resend
761  i--;
762  continue;
763  } else if (dec_ctx.hw_action && !ctx.enc_eos_sent[i])
764  {
765  p_hwframe = (niFrameSurface1_t *)frame_to_enc[i]->data.frame.p_data[3];
766  ni_hw_frame_ref(p_hwframe);
767  }
768 
769  // encoder send handling
770  if (dec_ctx.hw_action)
771  {
772  ni_frame_wipe_aux_data(&frame_to_enc[i]->data.frame);
773  } else
774  {
775  ni_decoder_frame_buffer_free(&frame_to_enc[i]->data.frame);
776  }
777  }
778 
779  if (send_rc < 0)
780  {
781  break;
782  }
783 
784 encode_recv:
785  receive_rc = encoder_receive2(&ctx, enc_ctx, &enc_in_frame, out_packet,
786  output_width, output_height, output_total, output_fp);
787 
788  for (i = 0; receive_rc >= 0 && i < output_total; i++)
789  {
790  if (!ctx.enc_eos_received[i])
791  {
792  ni_log(NI_LOG_DEBUG, "enc %d continues to read!\n", i);
793  end_of_all_streams = 0;
794  break;
795  } else
796  {
797  ni_log(NI_LOG_DEBUG, "enc %d eos !\n", i);
798  end_of_all_streams = 1;
799  }
800  }
801 
803  if (current_time - previous_time >= (uint64_t)1000000000) {
804  ni_log(NI_LOG_INFO, "Decoder stats: received %u frames, fps %.2f, total bytes %u\n",
806  (float)ctx.num_frames_received / (float)(current_time - ctx.start_time) * (float)1000000000,
808  for (i = 0; i < output_total; i++)
809  {
810  ni_log(NI_LOG_INFO, "Encoder %d stats: received %u packets, fps %.2f, total bytes %u\n",
811  i, ctx.num_packets_received[i],
812  (float)enc_ctx[i].frame_num / (float)(current_time - ctx.start_time) * (float)1000000000,
813  ctx.enc_total_bytes_received[i]);
814  }
816  }
817  }
818 
819  decoder_stat_report_and_close(&ctx, &dec_ctx);
820  encoder_stat_report_and_close(&ctx, enc_ctx, output_total);
821 
822 end:
824  if (dec_ctx.hw_action == NI_CODEC_HW_ENABLE)
825  {
826  ni_frame_buffer_free(&out_frame.data.frame);
827  } else
828  {
830  }
831  for (i = 0; i < output_total; i++)
832  {
833  ni_frame_buffer_free(&filter_out_frame[i].data.frame);
834  }
835 
836  ni_frame_buffer_free(&enc_in_frame.data.frame);
837  for (i = 0; i < output_total; i++)
838  {
839  ni_packet_buffer_free(&out_packet[i].data.packet);
840  }
841 
843  for (i = 0; i < output_total; i++)
844  {
845  ni_device_session_context_clear(&enc_ctx[i]);
846  if (output_fp[i] != NULL)
847  {
848  fclose(output_fp[i]);
849  }
850  if (scale_params[i].enabled)
851  {
852  ni_device_session_context_clear(&sca_ctx[i]);
853  }
854  }
855  if (drawbox_params.enabled)
856  {
861  }
862 
863  free(ctx.file_cache);
864 
865  for(i = 0; i < MAX_OUTPUT_FILES; ++i)
866  {
867  free(ctx.enc_pts_queue[i]);
868  ctx.enc_pts_queue[i] = NULL;
869  }
870 
871  free(p_dec_api_param);
872  free(p_enc_api_param);
873 
874  return ret;
875 }
_ni_scale_params::height
int height
Definition: ni_filter_utils.h:37
ni_decode_utils.h
ni_log_level_t
ni_log_level_t
Definition: ni_log.h:57
gc620_to_ni_pix_fmt
ni_pix_fmt_t gc620_to_ni_pix_fmt(int pix_fmt)
Definition: ni_generic_utils.c:130
_ni_demo_context::loops_left
uint64_t loops_left
Definition: ni_generic_utils.h:128
ni_pix_fmt_t
ni_pix_fmt_t
Definition: ni_device_api.h:263
_ni_h265_sps_t::bit_depth_chroma
int bit_depth_chroma
Definition: ni_decode_utils.h:251
ni_frame_buffer_free
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...
Definition: ni_device_api.c:3574
ni_hw_frame_ref
void ni_hw_frame_ref(const niFrameSurface1_t *p_surface)
Definition: ni_generic_utils.c:657
_ni_vp9_header_info::den
uint32_t den
Definition: ni_decode_utils.h:347
encoder_stat_report_and_close
void encoder_stat_report_and_close(ni_demo_context_t *p_ctx, ni_session_context_t *p_enc_ctx_list, int output_total)
Definition: ni_encode_utils.c:2563
_ni_frame::aspect_ratio_idc
uint8_t aspect_ratio_idc
Definition: ni_device_api.h:2756
probe_h264_stream_info
int probe_h264_stream_info(ni_demo_context_t *p_ctx, ni_h264_sps_t *sps)
Definition: ni_decode_utils.c:715
ni_strcpy
ni_retcode_t ni_strcpy(char *dest, size_t dmax, const char *src)
Definition: ni_util.c:449
ni_hw_frame_unref
void ni_hw_frame_unref(uint16_t hwframe_index)
Definition: ni_generic_utils.c:678
ni_generic_utils.h
print_version
void print_version(void)
Definition: ni_generic_utils.c:66
retrieve_filter_params
int retrieve_filter_params(char filter_params[], ni_scale_params_t *scale_params, ni_drawbox_params_t *drawbox_params)
Definition: ni_filter_utils.c:104
NI_PIX_FMT_YUV420P
@ NI_PIX_FMT_YUV420P
Definition: ni_device_api.h:265
_ni_demo_context::enc_pts_queue
ni_pts_queue * enc_pts_queue[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:162
_ni_session_data_io::packet
ni_packet_t packet
Definition: ni_device_api.h:2948
ni_encode_utils.h
current_time
struct timeval current_time
Definition: ni_p2p_read_test.c:80
ni_log_set_level
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
Definition: ni_log.c:202
ni_gettime_ns
uint64_t ni_gettime_ns(void)
Definition: ni_util.c:2618
MAX_OUTPUT_FILES
#define MAX_OUTPUT_FILES
Definition: ni_generic_utils.h:48
_ni_h265_window_t::bottom_offset
unsigned int bottom_offset
Definition: ni_decode_utils.h:141
required_argument
#define required_argument
Definition: ni_getopt.h:86
encoder_open2
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)
Definition: ni_encode_utils.c:2220
NI_XCODER_REVISION
#define NI_XCODER_REVISION
Definition: ni_defs.h:98
probe_h265_stream_info
int probe_h265_stream_info(ni_demo_context_t *p_ctx, ni_h265_sps_t *sps)
Definition: ni_decode_utils.c:1994
ni_packet_buffer_free
ni_retcode_t ni_packet_buffer_free(ni_packet_t *p_packet)
Free packet buffer that was previously allocated with ni_packet_buffer_alloc.
Definition: ni_device_api.c:3856
_ni_h265_window_t::left_offset
unsigned int left_offset
Definition: ni_decode_utils.h:138
no_argument
#define no_argument
Definition: ni_getopt.h:85
drawbox_filter
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.
Definition: ni_filter_utils.c:375
_ni_session_context::bit_depth_factor
int bit_depth_factor
Definition: ni_device_api.h:1524
_ni_h265_sps_t::width
int width
Definition: ni_decode_utils.h:317
decoder_receive_data
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.
Definition: ni_decode_utils.c:2416
previous_time
struct timeval previous_time
Definition: ni_p2p_read_test.c:79
FILE_NAME_LEN
#define FILE_NAME_LEN
Definition: ni_generic_utils.h:46
probe_vp9_stream_info
int probe_vp9_stream_info(ni_demo_context_t *p_ctx, ni_vp9_header_info_t *vp9_info)
Definition: ni_decode_utils.c:2180
ni_log.h
Logging definitions.
_ni_scale_params::format
int format
Definition: ni_filter_utils.h:38
_niFrameSurface1::ui16FrameIdx
uint16_t ui16FrameIdx
Definition: ni_device_api.h:2872
_ni_demo_context
Definition: ni_generic_utils.h:120
_ni_vp9_header_info
Definition: ni_decode_utils.h:339
NI_LOG_INFO
@ NI_LOG_INFO
Definition: ni_log.h:63
arg_to_ni_log_level
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
decoder_stat_report_and_close
void decoder_stat_report_and_close(ni_demo_context_t *p_ctx, ni_session_context_t *p_dec_ctx)
Definition: ni_decode_utils.c:2612
NI_LOG_ERROR
@ NI_LOG_ERROR
Definition: ni_log.h:62
ni_to_gc620_pix_fmt
int ni_to_gc620_pix_fmt(ni_pix_fmt_t pix_fmt)
Definition: ni_generic_utils.c:115
_ni_session_context::src_bit_depth
int src_bit_depth
Definition: ni_device_api.h:1522
NI_TEST_RETCODE_END_OF_STREAM
#define NI_TEST_RETCODE_END_OF_STREAM
Definition: ni_generic_utils.h:52
read_and_cache_file
int read_and_cache_file(ni_demo_context_t *ctx, char *filename)
Definition: ni_generic_utils.c:258
_ni_vp9_header_info::timebase
struct _ni_vp9_header_info::@3 timebase
ni_filter_utils.h
_ni_demo_context::num_frames_received
uint64_t num_frames_received
Definition: ni_generic_utils.h:139
_ni_h264_sps_t
Definition: ni_decode_utils.h:70
_ni_demo_context::enc_eos_sent
int enc_eos_sent[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:158
_ni_vp9_header_info::num
uint32_t num
Definition: ni_decode_utils.h:348
NI_TEST_RETCODE_EAGAIN
#define NI_TEST_RETCODE_EAGAIN
Definition: ni_generic_utils.h:53
decoder_open_session
int decoder_open_session(ni_session_context_t *p_dec_ctx, int iXcoderGUID, ni_xcoder_params_t *p_dec_params)
decoder session open
Definition: ni_decode_utils.c:2575
_ni_h265_sps_t::height
int height
Definition: ni_decode_utils.h:318
_ni_scale_params::width
int width
Definition: ni_filter_utils.h:36
_ni_h265_sps_t::pic_conf_win
ni_h265_window_t pic_conf_win
Definition: ni_decode_utils.h:248
NI_CODEC_FORMAT_AV1
@ NI_CODEC_FORMAT_AV1
Definition: ni_device_api.h:928
_ni_h265_window_t::right_offset
unsigned int right_offset
Definition: ni_decode_utils.h:139
_ni_session_data_io
Definition: ni_device_api.h:2943
_ni_h265_sps_t
Definition: ni_decode_utils.h:241
ni_log
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition: ni_log.c:183
NI_LOG_INVALID
@ NI_LOG_INVALID
Definition: ni_log.h:59
NI_TEST_RETCODE_SUCCESS
#define NI_TEST_RETCODE_SUCCESS
Definition: ni_generic_utils.h:51
_ni_h264_sps_t::width
int width
Definition: ni_decode_utils.h:72
main
int main(int argc, char *argv[])
Definition: ni_xcoder_transcode_filter.c:90
getopt_long
int getopt_long(int argc, char *argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: ni_getopt.c:99
_ni_h264_sps_t::bit_depth_luma
int bit_depth_luma
bit_depth_luma_minus8 + 8
Definition: ni_decode_utils.h:128
GC620_I420
#define GC620_I420
Definition: ni_device_api.h:196
_ni_vp9_header_info::profile
int profile
Definition: ni_decode_utils.h:341
decoder_send_data
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.
Definition: ni_decode_utils.c:2228
_ni_h265_window_t::top_offset
unsigned int top_offset
Definition: ni_decode_utils.h:140
_ni_session_context::frame_num
uint64_t frame_num
Definition: ni_device_api.h:1561
ni_device_session_context_clear
void ni_device_session_context_clear(ni_session_context_t *p_ctx)
Clear already allocated session context.
Definition: ni_device_api.c:255
_ni_frame::p_data
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
Definition: ni_device_api.h:2733
optarg
char * optarg
Definition: ni_getopt.c:33
NI_CODEC_FORMAT_VP9
@ NI_CODEC_FORMAT_VP9
Definition: ni_device_api.h:926
_ni_vp9_header_info::height
uint16_t height
Definition: ni_decode_utils.h:344
ni_decoder_init_default_params
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.
Definition: ni_device_api.c:4572
_ni_vp9_header_info::width
uint16_t width
Definition: ni_decode_utils.h:343
_ni_session_context::hw_action
int hw_action
Definition: ni_device_api.h:1639
_ni_scale_params
Definition: ni_filter_utils.h:33
_ni_session_context
Definition: ni_device_api.h:1434
_niFrameSurface1
Definition: ni_device_api.h:2870
NI_CODEC_HW_ENABLE
@ NI_CODEC_HW_ENABLE
Definition: ni_device_api.h:953
_ni_session_data_io::data
union _ni_session_data_io::@19 data
_ni_demo_context::start_time
uint64_t start_time
Definition: ni_generic_utils.h:143
_ni_xcoder_params
Definition: ni_device_api.h:2787
option
Definition: ni_getopt.h:73
_ni_demo_context::file_cache
uint8_t * file_cache
Definition: ni_generic_utils.h:125
_ni_session_context::codec_format
uint32_t codec_format
Definition: ni_device_api.h:1516
scale_filter
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.
Definition: ni_filter_utils.c:513
_ni_demo_context::dec_total_bytes_received
uint64_t dec_total_bytes_received
Definition: ni_generic_utils.h:136
_ni_session_data_io::frame
ni_frame_t frame
Definition: ni_device_api.h:2947
_ni_demo_context::num_packets_received
uint64_t num_packets_received[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:141
_ni_scale_params::enabled
int enabled
Definition: ni_filter_utils.h:35
_ni_drawbox_params::enabled
int enabled
Definition: ni_filter_utils.h:43
_ni_demo_context::enc_eos_received
int enc_eos_received[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:159
_ni_session_context::enable_user_data_sei_passthru
int enable_user_data_sei_passthru
Definition: ni_device_api.h:1644
encoder_receive2
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)
Definition: ni_encode_utils.c:2491
ni_util.h
Utility definitions.
encoder_send_data2
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)
Definition: ni_encode_utils.c:880
NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_H264
Definition: ni_device_api.h:924
_ni_h264_sps_t::height
int height
Definition: ni_decode_utils.h:73
ni_device_session_context_init
ni_retcode_t ni_device_session_context_init(ni_session_context_t *p_ctx)
Initialize already allocated session context to a known state.
Definition: ni_device_api.c:156
_ni_session_context::pixel_format
int pixel_format
Definition: ni_device_api.h:1646
_ni_demo_context::enc_total_bytes_received
uint64_t enc_total_bytes_received[MAX_OUTPUT_FILES]
Definition: ni_generic_utils.h:138
ni_retrieve_decoder_params
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:4556
NI_LOG_DEBUG
@ NI_LOG_DEBUG
Definition: ni_log.h:64
_ni_demo_context::curr_enc_index
uint8_t curr_enc_index
Definition: ni_generic_utils.h:134
ni_getopt.h
Implementation of getopt() and getopt_long() for Windows environment.
ni_fopen
ni_retcode_t ni_fopen(FILE **fp, const char *filename, const char *mode)
Definition: ni_util.c:979
_ni_drawbox_params
Definition: ni_filter_utils.h:41
ni_decoder_frame_buffer_free
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,...
Definition: ni_device_api.c:3657
NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_H265
Definition: ni_device_api.h:925
ni_frame_wipe_aux_data
void ni_frame_wipe_aux_data(ni_frame_t *frame)
Free and remove all auxiliary data from the frame.
Definition: ni_device_api.c:4128