libxcoder  5.2.0
ni_p2p_test.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_p2p_test.c
24  *
25  * \brief Application for performing video processing using libxcoder API and
26  * P2P DMA. Its code provides examples on how to programatically use
27  * libxcoder API in conjunction with P2P DMA.
28  ******************************************************************************/
29 
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stdint.h>
34 
35 #define _POSIX_C_SOURCE 200809L
36 #include <getopt.h>
37 #include <unistd.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <sys/time.h>
42 #include <time.h>
43 
44 #include "ni_device_api.h"
45 #include "ni_util.h"
46 
47 // max YUV frame size
48 #define MAX_YUV_FRAME_SIZE (7680 * 4320 * 3 / 2)
49 #define MAX_ABGR_FRAME_SIZE (7680 * 4320 * 4)
50 #define POOL_SIZE 2
51 #define FILE_NAME_LEN 256
52 
53 int send_fin_flag = 0;
55 int enc_eos_sent = 0;
56 
57 uint32_t number_of_frames = 0;
58 uint32_t number_of_packets = 0;
59 uint64_t data_left_size = 0;
60 int g_repeat = 1;
61 
62 struct timeval start_time;
63 struct timeval previous_time;
64 struct timeval current_time;
65 
66 time_t start_timestamp = 0;
67 time_t previous_timestamp = 0;
68 time_t current_timestamp = 0;
69 
70 unsigned long total_file_size = 0;
71 
72 uint8_t *g_curr_cache_pos = NULL;
73 uint8_t *g_yuv_frame[POOL_SIZE] = {NULL, NULL};
74 uint8_t *g_rgba_frame[POOL_SIZE] = {NULL, NULL};
75 
76 uint8_t g_rgb2yuv_csc = 0;
77 
78 /*!****************************************************************************
79  * \brief Exit on argument error
80  *
81  * \param[in] arg_name pointer to argument name
82  * [in] param pointer to provided parameter
83  *
84  * \return None program exit
85  ******************************************************************************/
86 void arg_error_exit(char *arg_name, char *param)
87 {
88  fprintf(stderr, "Error: unrecognized argument for %s, \"%s\"\n", arg_name,
89  param);
90  exit(-1);
91 }
92 
93 /*!****************************************************************************
94  * \brief Read the next frame
95  *
96  * \param[in] fd file descriptor of input file
97  * \param[out] p_dst pointer to place the frame
98  * \param[in] to_read number of bytes to copy to the pointer
99  *
100  * \return bytes copied
101  ******************************************************************************/
102 int read_next_chunk_from_file(int fd, uint8_t *p_dst, uint32_t to_read)
103 {
104  uint8_t *tmp_dst = p_dst;
106  "read_next_chunk_from_file:p_dst %p len %u totalSize %llu left %llu\n",
107  tmp_dst, to_read, (unsigned long long)total_file_size, (unsigned long long)data_left_size);
108  int to_copy = to_read;
109  unsigned long tmpFileSize = to_read;
110  if (data_left_size == 0)
111  {
112  if (g_repeat > 1)
113  {
115  g_repeat--;
116  ni_log(NI_LOG_DEBUG, "input processed %d left\n", g_repeat);
117  lseek(fd, 0, SEEK_SET); //back to beginning
118  } else
119  {
120  return 0;
121  }
122  } else if (data_left_size < to_read)
123  {
124  tmpFileSize = data_left_size;
125  to_copy = data_left_size;
126  }
127 
128  int one_read_size = read(fd, tmp_dst, to_copy);
129  if (one_read_size == -1)
130  {
131  fprintf(stderr, "Error: reading file, quit! left-to-read %lu\n",
132  tmpFileSize);
133  fprintf(stderr, "Error: input file read error\n");
134  return -1;
135  }
136  data_left_size -= one_read_size;
137 
138  return to_copy;
139 }
140 
141 /*!****************************************************************************
142  * \brief Load the input file into memory
143  *
144  * \param [in] filename name of input file
145  * [out] bytes_read number of bytes read from file
146  *
147  * \return 0 on success
148  * < 0 on error
149  ******************************************************************************/
150 int load_input_file(const char *filename, unsigned long *bytes_read)
151 {
152  struct stat info;
153 
154  /* Get information on the file */
155  if (stat(filename, &info) < 0)
156  {
157  fprintf(stderr, "Can't stat %s\n", filename);
158  return -1;
159  }
160 
161  /* Check the file size */
162  if (info.st_size <= 0)
163  {
164  fprintf(stderr, "File %s is empty\n", filename);
165  return -1;
166  }
167 
168  *bytes_read = info.st_size;
169 
170  return 0;
171 }
172 
173 /*!****************************************************************************
174 * \brief Recycle hw frames back to Quadra
175 *
176 * \param [in] p2p_frame - array of hw frames to recycle
177 *
178 * \return Returns the number of hw frames that have been recycled
179 *******************************************************************************/
180 int recycle_frames(ni_frame_t p2p_frame[])
181 {
182  int i;
183  int cnt = 0;
184  ni_retcode_t rc;
185 
186  for (i = 0; i < POOL_SIZE; i++)
187  {
188  rc = ni_hwframe_p2p_buffer_recycle(&p2p_frame[i]);
189 
190  if (rc != NI_RETCODE_SUCCESS)
191  {
192  fprintf(stderr, "Recycle failed\n");
193  }
194 
195  cnt += (rc == NI_RETCODE_SUCCESS) ? 1 : 0;
196  }
197 
198  return cnt;
199 }
200 
201 /*!****************************************************************************
202  * \brief Reads YUV data from input file then calls a special libxcoder API
203  * function to transfer the YUV data into the hardware frame on
204  * the Quadra device.
205  *
206  * \param [in] p_upl_ctx pointer to upload session context
207  * [in] fd file descriptor of input file
208  * [in] p_yuv420p_frame address of pointer to YUV data
209  * [in] p_in_frame pointer to hardware frame
210  * [in] input_video_width video width
211  * [in] input_video_height video height
212  * [out] bytes_sent updated byte count of total data read
213  * [out] input_exhausted set to 1 when we reach end-of-file
214  *
215  * \return 0 on success
216  * -1 on error
217  ******************************************************************************/
219  uint8_t **p_yuv420p_frame, ni_frame_t *p_in_frame,
220  int input_video_width, int input_video_height,
221  unsigned long *bytes_sent, int *input_exhausted)
222 {
223  static uint8_t tmp_buf[MAX_YUV_FRAME_SIZE];
224  void *p_buffer;
225  uint8_t *p_src[NI_MAX_NUM_DATA_POINTERS];
226  uint8_t *p_dst[NI_MAX_NUM_DATA_POINTERS];
227  int src_stride[NI_MAX_NUM_DATA_POINTERS];
228  int src_height[NI_MAX_NUM_DATA_POINTERS];
229  int dst_stride[NI_MAX_NUM_DATA_POINTERS] = {0, 0, 0, 0};
230  int dst_height[NI_MAX_NUM_DATA_POINTERS] = {0, 0, 0, 0};
231  int frame_size;
232  int chunk_size;
233  int alignedh;
234  int Ysize;
235  int Usize;
236  int Vsize;
237  int total_size;
238 
239  ni_log2(p_upl_ctx, NI_LOG_DEBUG, "===> p2p upload_send_data <===\n");
240 
241  /* An 8-bit YUV420 planar frame occupies [(width x height x 3)/2] bytes */
242  frame_size = input_video_height * input_video_width * 3 / 2;
243 
244  chunk_size = read_next_chunk_from_file(fd, tmp_buf, frame_size);
245 
246  if (chunk_size == 0)
247  {
248  ni_log2(p_upl_ctx, NI_LOG_DEBUG, "p2p_upload_send_data: read chunk size 0, eos!\n");
249  *input_exhausted = 1;
250  }
251 
252  p_in_frame->video_width = input_video_width;
253  p_in_frame->video_height = input_video_height;
254  p_in_frame->extra_data_len = 0;
255 
256  ni_get_hw_yuv420p_dim(input_video_width, input_video_height,
257  p_upl_ctx->bit_depth_factor, 0, dst_stride,
258  dst_height);
259 
260  ni_log2(p_upl_ctx, NI_LOG_DEBUG, "p_dst alloc linesize = %d/%d/%d src height=%d "
261  "dst height aligned = %d/%d/%d \n",
262  dst_stride[0], dst_stride[1], dst_stride[2],
263  input_video_height, dst_height[0], dst_height[1],
264  dst_height[2]);
265 
266  src_stride[0] = input_video_width * p_upl_ctx->bit_depth_factor;
267  src_stride[1] = src_stride[2] = src_stride[0] / 2;
268 
269  src_height[0] = input_video_height;
270  src_height[1] = src_height[0] / 2;
271  src_height[2] = src_height[1];
272 
273  p_src[0] = tmp_buf;
274  p_src[1] = tmp_buf + src_stride[0] * src_height[0];
275  p_src[2] = p_src[1] + src_stride[1] * src_height[1];
276 
277  alignedh = (input_video_height + 1) & ~1;
278 
279  Ysize = dst_stride[0] * alignedh;
280  Usize = dst_stride[1] * alignedh / 2;
281  Vsize = dst_stride[2] * alignedh / 2;
282 
283  total_size = Ysize + Usize + Vsize;
284  total_size = ((total_size + 4095) & ~4095) + 4096;
285 
286  if (*p_yuv420p_frame == NULL)
287  {
288  if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), total_size))
289  {
290  fprintf(stderr, "Can't alloc memory\n");
291  return -1;
292  }
293 
294  *p_yuv420p_frame = p_buffer;
295  }
296 
297  p_dst[0] = *p_yuv420p_frame;
298  p_dst[1] = *p_yuv420p_frame + Ysize;
299  p_dst[2] = *p_yuv420p_frame + Ysize + Usize;
300  p_dst[3] = NULL;
301 
302  ni_copy_hw_yuv420p(p_dst, p_src, input_video_width, input_video_height, 1,
303  0, 0, dst_stride, dst_height, src_stride, src_height);
304 #ifndef _WIN32
305  if (ni_uploader_p2p_test_send(p_upl_ctx, *p_yuv420p_frame, total_size,
306  p_in_frame))
307  {
308  fprintf(stderr, "Error: failed ni_uploader_p2p_test_send()\n");
309  return -1;
310  } else
311 #endif
312  {
313  *bytes_sent = total_size;
314  }
315 
316  return 0;
317 }
318 
319 /*!****************************************************************************
320  * \brief Reads RGBA data from input file then calls a special libxcoder API
321  * function to transfer the RGBA data into the hardware frame on
322  * the Quadra device.
323  *
324  * \param [in] p_upl_ctx pointer to upload session context
325  * [in] fd file descriptor of input file
326  * [in] p_rgba_frame address of pointer to RGBA data
327  * [in] p_in_frame pointer to hardware frame
328  * [in] input_video_width video width
329  * [in] input_video_height video height
330  * [out] bytes_sent updated byte count of total data read
331  * [out] input_exhausted set to 1 when we reach end-of-file
332  *
333  * \return 0 on success
334  * -1 on error
335  ******************************************************************************/
337  uint8_t **p_rgba_frame, ni_frame_t *p_in_frame,
338  int input_video_width, int input_video_height,
339  unsigned long *bytes_sent, int *input_exhausted)
340 {
341  static uint8_t tmp_buf[MAX_ABGR_FRAME_SIZE];
342  void *p_buffer;
343  uint8_t *p_src,*p_dst;
344  int linewidth;
345  int frame_size;
346  int chunk_size;
347  int total_size;
348  int row;
349 
350  ni_log2(p_upl_ctx, NI_LOG_DEBUG, "===> p2p upload_rgba_send_data <===\n");
351 
352  /* An 8-bit RGBA frame is in a packed raster (or linear) format */
353  /* and occupies width * height * 4 bytes. */
354  frame_size = input_video_width * input_video_height * 4;
355 
356  chunk_size = read_next_chunk_from_file(fd, tmp_buf, frame_size);
357 
358  if (chunk_size == 0)
359  {
360  ni_log2(p_upl_ctx, NI_LOG_DEBUG, "p2p_upload_rgba_send_data: eos!\n");
361  *input_exhausted = 1;
362  }
363 
364  p_in_frame->video_width = input_video_width;
365  p_in_frame->video_height = input_video_height;
366  p_in_frame->extra_data_len = 0;
367 
368  linewidth = input_video_width * 4;
369 
370  // Round up to 4K
371  total_size = NI_VPU_ALIGN4096(frame_size);
372 
373  if (*p_rgba_frame == NULL)
374  {
375  if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), total_size))
376  {
377  fprintf(stderr, "Can't alloc memory\n");
378  return -1;
379  }
380 
381  *p_rgba_frame = p_buffer;
382  }
383 
384  p_src = tmp_buf;
385  p_dst = *p_rgba_frame;
386 
387  for (row = 0; row < input_video_height; row++)
388  {
389  memcpy(p_dst, p_src, linewidth);
390  p_src += linewidth;
391  p_dst += linewidth;
392  }
393 
394  if (ni_uploader_p2p_test_send(p_upl_ctx, *p_rgba_frame, total_size,
395  p_in_frame))
396  {
397  fprintf(stderr, "Error: failed ni_uploader_p2p_test_send()\n");
398  return -1;
399  } else
400  {
401  *bytes_sent = total_size;
402  }
403 
404  return 0;
405 }
406 
407 /*!****************************************************************************
408  * \brief Prepare frames to simulate P2P transfers
409  *
410  * \param [in] p_upl_ctx pointer to caller allocated uploader
411  * session context
412  * [in] input_video_width video width
413  * [in] input_video_height video height
414  * [out] p2p_frame array of hw frames
415  *
416  * \return 0 on success
417  * -1 on error
418  ******************************************************************************/
419 int p2p_prepare_frames(ni_session_context_t *p_upl_ctx, int input_video_width,
420  int input_video_height, ni_frame_t p2p_frame[])
421 {
422  int i;
423  int ret = 0;
424  ni_frame_t *p_in_frame;
425 
426  // Allocate memory for two hardware frames
427  for (i = 0; i < POOL_SIZE; i++)
428  {
429  p_in_frame = &p2p_frame[i];
430 
431  p_in_frame->start_of_stream = 0;
432  p_in_frame->end_of_stream = 0;
433  p_in_frame->force_key_frame = 0;
434  p_in_frame->extra_data_len = 0;
435 
436  // Allocate a hardware ni_frame structure for the encoder
438  p_in_frame, input_video_width, input_video_height,
439  (int)p_in_frame->extra_data_len) != NI_RETCODE_SUCCESS)
440  {
441  fprintf(stderr, "Error: could not allocate hw frame buffer!");
442  ret = -1;
443  goto fail_out;
444  }
445 
446 #ifndef _WIN32
447  // Acquire a hw frame from the upload session. This obtains a handle
448  // to Quadra memory from the previously created frame pool.
449  if (ni_device_session_acquire(p_upl_ctx, p_in_frame))
450  {
451  fprintf(stderr, "Error: failed ni_device_session_acquire()\n");
452  ret = -1;
453  goto fail_out;
454  }
455 #endif
456  }
457 
458  return ret;
459 
460 fail_out:
461  for (i = 0; i < POOL_SIZE; i++)
462  {
463  ni_frame_buffer_free(&(p2p_frame[i]));
464  }
465 
466  return ret;
467 }
468 
469 /*!****************************************************************************
470  * \brief Send the Quadra encoder a hardware frame which triggers
471  * Quadra to encode the frame
472  *
473  * \param [in] p_enc_ctx pointer to encoder context
474  * [in] p_in_frame pointer to hw frame
475  * [in] input_exhausted flag indicating this is the last frame
476  * [in/out] need_to_resend flag indicating need to re-send
477  *
478  * \return 0 on success
479  * -1 on failure
480  ******************************************************************************/
482  ni_frame_t *p_in_frame, int input_exhausted,
483  int *need_to_resend)
484 {
485  static int started = 0;
486  int oneSent;
487  ni_session_data_io_t in_data;
488 
489  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "===> encoder_encode_frame <===\n");
490 
491  if (enc_eos_sent == 1)
492  {
493  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "encoder_encode_frame: ALL data (incl. eos) sent "
494  "already!\n");
495  return 0;
496  }
497 
498  if (*need_to_resend)
499  {
500  goto send_frame;
501  }
502 
503  p_in_frame->start_of_stream = 0;
504 
505  // If this is the first frame, mark the frame as start-of-stream
506  if (!started)
507  {
508  started = 1;
509  p_in_frame->start_of_stream = 1;
510  }
511 
512  // If this is the last frame, mark the frame as end-of-stream
513  p_in_frame->end_of_stream = input_exhausted ? 1 : 0;
514  p_in_frame->force_key_frame = 0;
515 
516 send_frame:
517 
518  in_data.data.frame = *p_in_frame;
519  oneSent =
520  ni_device_session_write(p_enc_ctx, &in_data, NI_DEVICE_TYPE_ENCODER);
521 
522  if (oneSent < 0)
523  {
524  fprintf(stderr,
525  "Error: failed ni_device_session_write() for encoder\n");
526  *need_to_resend = 1;
527  return -1;
528  } else if (oneSent == 0 && !p_enc_ctx->ready_to_close)
529  {
530  *need_to_resend = 1;
531  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "NEEDED TO RESEND");
532  } else
533  {
534  *need_to_resend = 0;
535 
536  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "encoder_encode_frame: total sent data size=%u\n",
537  p_in_frame->data_len[3]);
538 
539  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "encoder_encode_frame: success\n");
540 
541  if (p_enc_ctx->ready_to_close)
542  {
543  enc_eos_sent = 1;
544  }
545  }
546 
547  return 0;
548 }
549 
550 /*!****************************************************************************
551  * \brief Receive output packet data from the Quadra encoder
552  *
553  * \param [in] p_enc_ctx pointer to encoder session context
554  * [in] p_out_data pointer to output data session
555  * [in] p_file pointer to file to write the packet
556  * [out] total_bytes_received running counter of bytes read
557  * [in] print_time 1 = print the time
558  *
559  * \return 0 - success got packet
560  * 1 - received eos
561  * 2 - got nothing, need retry
562  * -1 - failure
563  ******************************************************************************/
565  ni_session_data_io_t *p_out_data, FILE *p_file,
566  unsigned long long *total_bytes_received,
567  int print_time)
568 {
569  int packet_size = NI_MAX_TX_SZ;
570  int rc = 0;
571  int end_flag = 0;
572  int rx_size = 0;
573  int meta_size = p_enc_ctx->meta_size;
574  ni_packet_t *p_out_pkt = &(p_out_data->data.packet);
575  static int received_stream_header = 0;
576 
577  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "===> encoder_receive_data <===\n");
578 
579  if (NI_INVALID_SESSION_ID == p_enc_ctx->session_id ||
580  NI_INVALID_DEVICE_HANDLE == p_enc_ctx->blk_io_handle)
581  {
582  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "encode session not opened yet, return\n");
583  return 0;
584  }
585 
586  if (p_file == NULL)
587  {
588  ni_log2(p_enc_ctx, NI_LOG_ERROR, "Bad file pointer, return\n");
589  return -1;
590  }
591 
592  rc = ni_packet_buffer_alloc(p_out_pkt, packet_size);
593  if (rc != NI_RETCODE_SUCCESS)
594  {
595  fprintf(stderr, "Error: malloc packet failed, ret = %d!\n", rc);
596  return -1;
597  }
598 
599  /*
600  * The first data read from the encoder session context
601  * is a stream header read.
602  */
603  if (!received_stream_header)
604  {
605  /* Read the encoded stream header */
606  rc = ni_encoder_session_read_stream_header(p_enc_ctx, p_out_data);
607 
608  if (rc > 0)
609  {
610  /* Write out the stream header */
611  if (fwrite((uint8_t *)p_out_pkt->p_data + meta_size,
612  p_out_pkt->data_len - meta_size, 1, p_file) != 1)
613  {
614  fprintf(stderr, "Error: writing data %u bytes error!\n",
615  p_out_pkt->data_len - meta_size);
616  fprintf(stderr, "Error: ferror rc = %d\n", ferror(p_file));
617  }
618 
619  rx_size = rc;
620  *total_bytes_received += rx_size;
622  received_stream_header = 1;
623  } else if (rc != 0)
624  {
625  fprintf(stderr, "Error: reading header %d\n", rc);
626  return -1;
627  }
628 
629  if (print_time)
630  {
631  int timeDiff = (int)(current_time.tv_sec - start_time.tv_sec);
632  if (timeDiff == 0)
633  {
634  timeDiff = 1;
635  }
636  printf("[R] Got:%d Packets= %u fps=%u Total bytes %llu\n",
637  rx_size, number_of_packets, number_of_packets / timeDiff,
638  *total_bytes_received);
639  }
640 
641  /* This shouldn't happen */
642  if (p_out_pkt->end_of_stream)
643  {
644  return 1;
645  } else if (rc == 0)
646  {
647  return 2;
648  }
649  }
650 
651 receive_data:
652  rc = ni_device_session_read(p_enc_ctx, p_out_data, NI_DEVICE_TYPE_ENCODER);
653 
654  end_flag = p_out_pkt->end_of_stream;
655  rx_size = rc;
656 
657  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "encoder_receive_data: received data size=%d\n", rx_size);
658 
659  if (rx_size > meta_size)
660  {
661  if (fwrite((uint8_t *)p_out_pkt->p_data + meta_size,
662  p_out_pkt->data_len - meta_size, 1, p_file) != 1)
663  {
664  fprintf(stderr, "Error: writing data %u bytes error!\n",
665  p_out_pkt->data_len - meta_size);
666  fprintf(stderr, "Error: ferror rc = %d\n", ferror(p_file));
667  }
668 
669  *total_bytes_received += rx_size - meta_size;
671 
672  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "Got: Packets= %u\n", number_of_packets);
673  } else if (rx_size != 0)
674  {
675  fprintf(stderr, "Error: received %d bytes, <= metadata size %d!\n",
676  rx_size, meta_size);
677  return -1;
678  } else if (!end_flag &&
679  (((ni_xcoder_params_t *)(p_enc_ctx->p_session_config))
680  ->low_delay_mode))
681  {
682  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "low delay mode and NO pkt, keep reading...\n");
683  goto receive_data;
684  }
685 
686  if (print_time)
687  {
688  int timeDiff = (int)(current_time.tv_sec - start_time.tv_sec);
689  if (timeDiff == 0)
690  {
691  timeDiff = 1;
692  }
693  printf("[R] Got:%d Packets= %u fps=%u Total bytes %llu\n", rx_size,
695  *total_bytes_received);
696  }
697 
698  if (end_flag)
699  {
700  printf("Encoder Receiving done\n");
701  return 1;
702  } else if (0 == rx_size)
703  {
704  return 2;
705  }
706 
707  ni_log2(p_enc_ctx, NI_LOG_DEBUG, "encoder_receive_data: success\n");
708 
709  return 0;
710 }
711 
712 /*!****************************************************************************
713  * \brief Open an encoder session to Quadra
714  *
715  * \param [out] p_enc_ctx pointer to an encoder session context
716  * [in] dst_codec_format AVC or HEVC
717  * [in] iXcoderGUID id to identify the Quadra device
718  * [in] p_enc_params sets the encoder parameters
719  * [in] width width of frames to encode
720  * [in] height height of frames to encode
721  *
722  * \return 0 if successful, < 0 otherwise
723  ******************************************************************************/
724 int encoder_open_session(ni_session_context_t *p_enc_ctx, int dst_codec_format,
725  int iXcoderGUID, ni_xcoder_params_t *p_enc_params,
726  int width, int height, ni_frame_t *p_frame)
727 {
728  int ret = 0;
729 
730  // Enable hardware frame encoding
731  p_enc_ctx->hw_action = NI_CODEC_HW_ENABLE;
732  p_enc_params->hwframes = 1;
733 
734  // Provide the first frame to the Quadra encoder
735  p_enc_params->p_first_frame = p_frame;
736 
737  // Specify codec, AVC vs HEVC
738  p_enc_ctx->codec_format = dst_codec_format;
739 
740  p_enc_ctx->p_session_config = p_enc_params;
741  p_enc_ctx->session_id = NI_INVALID_SESSION_ID;
742 
743  // Assign the card GUID in the encoder context to open a session
744  // to that specific Quadra device
745  p_enc_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
746  p_enc_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
747  p_enc_ctx->hw_id = iXcoderGUID;
748 
749  if (g_rgb2yuv_csc)
750  p_enc_ctx->pixel_format = NI_PIX_FMT_ABGR;
751 
752  ni_encoder_set_input_frame_format(p_enc_ctx, p_enc_params, width, height, 8,
754 
755  // Encoder will operate in P2P mode
757  if (ret != NI_RETCODE_SUCCESS)
758  {
759  fprintf(stderr, "Error: encoder open session failure\n");
760  } else
761  {
762  printf("Encoder device %d session open successful\n", iXcoderGUID);
763  }
764 
765  return ret;
766 }
767 
768 /*!****************************************************************************
769  * \brief Open an upload session to Quadra
770  *
771  * \param [out] p_upl_ctx pointer to an upload context of the open session
772  * [in] iXcoderGUID pointer to Quadra card hw id
773  * [in] width width of the frames
774  * [in] height height of the frames
775  *
776  * \return 0 if successful, < 0 otherwise
777  ******************************************************************************/
778 int uploader_open_session(ni_session_context_t *p_upl_ctx, int *iXcoderGUID,
779  int width, int height)
780 {
781  int ret = 0;
782  ni_pix_fmt_t frame_format;
783 
784  p_upl_ctx->session_id = NI_INVALID_SESSION_ID;
785 
786  // Assign the card GUID in the encoder context
787  p_upl_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
788  p_upl_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
789 
790  // Assign the card id to specify the specific Quadra device
791  p_upl_ctx->hw_id = *iXcoderGUID;
792 
793  // Assign the pixel format we want to use
795 
796  // Set the input frame format of the upload session
797  ni_uploader_set_frame_format(p_upl_ctx, width, height, frame_format,
798  1);
799 
801  if (ret != NI_RETCODE_SUCCESS)
802  {
803  fprintf(stderr, "Error: uploader_open_session failure!\n");
804  return ret;
805  } else
806  {
807  printf("Uploader device %d session opened successfully\n",
808  *iXcoderGUID);
809  *iXcoderGUID = p_upl_ctx->hw_id;
810  }
811 
812  // Create a P2P frame pool for the uploader sesson of pool size 2
813  ret = ni_device_session_init_framepool(p_upl_ctx, POOL_SIZE, 1);
814  if (ret < 0)
815  {
816  fprintf(stderr, "Error: Can't create frame pool\n");
818  } else
819  {
820  printf("Uploader device %d configured successfully\n", *iXcoderGUID);
821  }
822 
823  return ret;
824 }
825 
826 /*!****************************************************************************
827  * \brief Print usage information
828  *
829  * \param none
830  *
831  * \return none
832  ******************************************************************************/
833 void print_usage(void)
834 {
835  printf("Video encoder/P2P application directly using Netint "
836  "Libxcoder release v%s\n"
837  "Usage: xcoderp2p [options]\n"
838  "\n"
839  "options:\n"
840  "--------------------------------------------------------------------------------\n"
841  " -h | --help Show help.\n"
842  " -v | --version Print version info.\n"
843  " -l | --loglevel Set loglevel of libxcoder API.\n"
844  " [none, fatal, error, info, debug, trace]\n"
845  " Default: info\n"
846  " -c | --card Set card index to use.\n"
847  " See `ni_rsrc_mon` for cards on system.\n"
848  " (Default: 0)\n"
849  " -i | --input Input file path.\n"
850  " -r | --repeat (Positive integer) to Repeat input X times "
851  "for performance \n"
852  " test. (Default: 1)\n"
853  " -s | --size Resolution of input file in format "
854  "WIDTHxHEIGHT.\n"
855  " (eg. '1920x1080')\n"
856  " -m | --mode Input to output codec processing mode in "
857  "format:\n"
858  " INTYPE2OUTTYPE. [p2a, p2h, r2a, r2h]\n"
859  " Type notation: p=P2P, a=AVC, h=HEVC, r=ABGR\n"
860  " -o | --output Output file path.\n",
862 }
863 
864 /*!****************************************************************************
865  * \brief Parse user command line arguments
866  *
867  * \param [in] argc argument count
868  * [in] argv argument vector
869  * [out] input_filename input filename
870  * [out] output_filename output filename
871  * [out] iXcoderGUID Quadra device
872  * [out] arg_width resolution width
873  * [out] arg_height resolution height
874  * [out] dst_codec_format codec (AVC vs HEVC)
875  *
876  * \return nothing program exit on error
877  ******************************************************************************/
878 void parse_arguments(int argc, char *argv[], char *input_filename,
879  char *output_filename, int *iXcoderGUID, int *arg_width,
880  int *arg_height, int *dst_codec_format)
881 {
882  char xcoderGUID[32];
883  char mode_description[128];
884  char *n; // used for parsing width and height from --size
885  size_t i;
886  int opt;
887  int opt_index;
888  ni_log_level_t log_level;
889 
890  static const char *opt_string = "hvl:c:i:s:m:o:r:";
891  static const struct option long_options[] = {
892  {"help", no_argument, NULL, 'h'},
893  {"version", no_argument, NULL, 'v'},
894  {"loglevel", no_argument, NULL, 'l'},
895  {"card", required_argument, NULL, 'c'},
896  {"input", required_argument, NULL, 'i'},
897  {"size", required_argument, NULL, 's'},
898  {"mode", required_argument, NULL, 'm'},
899  {"output", required_argument, NULL, 'o'},
900  {"repeat", required_argument, NULL, 'r'},
901  {NULL, 0, NULL, 0},
902  };
903 
904  while ((opt = getopt_long(argc, argv, opt_string, long_options,
905  &opt_index)) != -1)
906  {
907  switch (opt)
908  {
909  case 'h':
910  print_usage();
911  exit(0);
912  case 'v':
913  printf("Release ver: %s\n"
914  "API ver: %s\n"
915  "Date: %s\n"
916  "ID: %s\n",
919  exit(0);
920  case 'l':
921  log_level = arg_to_ni_log_level(optarg);
922  if (log_level != NI_LOG_INVALID)
923  {
924  ni_log_set_level(log_level);
925  } else {
926  arg_error_exit("-l | --loglevel", optarg);
927  }
928  break;
929  case 'c':
930  strcpy(xcoderGUID, optarg);
931  *iXcoderGUID = (int)strtol(optarg, &n, 10);
932  // No numeric characters found in left side of optarg
933  if (n == xcoderGUID)
934  arg_error_exit("-c | --card", optarg);
935  break;
936  case 'i':
937  strcpy(input_filename, optarg);
938  break;
939  case 's':
940  *arg_width = (int)strtol(optarg, &n, 10);
941  *arg_height = atoi(n + 1);
942  if ((*n != 'x') || (!*arg_width || !*arg_height))
943  arg_error_exit("-s | --size", optarg);
944  break;
945  case 'm':
946  if (!(strlen(optarg) == 3))
947  arg_error_exit("-m | --mode", optarg);
948 
949  // convert to lower case for processing
950  for (i = 0; i < strlen(optarg); i++)
951  optarg[i] = (char)tolower((unsigned char)optarg[i]);
952 
953  if (strcmp(optarg, "p2a") != 0 && strcmp(optarg, "p2h") != 0 &&
954  strcmp(optarg, "r2a") != 0 && strcmp(optarg, "r2h") != 0)
955  arg_error_exit("-, | --mode", optarg);
956 
957  // determine codec
958  sprintf(mode_description, "P2P + Encoding");
959 
960  g_rgb2yuv_csc = (optarg[0] == 'r') ? 1 : 0;
961 
962  if (optarg[2] == 'a')
963  {
964  *dst_codec_format = NI_CODEC_FORMAT_H264;
965  strcat(mode_description, " to AVC");
966  }
967 
968  if (optarg[2] == 'h')
969  {
970  *dst_codec_format = NI_CODEC_FORMAT_H265;
971  strcat(mode_description, " to HEVC");
972  }
973  printf("%s...\n", mode_description);
974 
975  break;
976  case 'o':
977  strcpy(output_filename, optarg);
978  break;
979  case 'r':
980  if (!(atoi(optarg) >= 1))
981  arg_error_exit("-r | --repeat", optarg);
982  g_repeat = atoi(optarg);
983  break;
984  default:
985  print_usage();
986  exit(1);
987  }
988  }
989 
990  // Check required args are present
991  if (!input_filename[0])
992  {
993  printf("Error: missing argument for -i | --input\n");
994  exit(-1);
995  }
996 
997  if (!output_filename[0])
998  {
999  printf("Error: missing argument for -o | --output\n");
1000  exit(-1);
1001  }
1002 }
1003 
1004 int main(int argc, char *argv[])
1005 {
1006  static char input_filename[FILE_NAME_LEN];
1007  static char output_filename[FILE_NAME_LEN];
1008  unsigned long total_bytes_sent;
1009  unsigned long long total_bytes_received;
1010  int input_video_width;
1011  int input_video_height;
1012  int iXcoderGUID = 0;
1013  int arg_width = 0;
1014  int arg_height = 0;
1015  int input_exhausted = 0;
1016  int num_post_recycled = 0;
1017  int dst_codec_format = 0;
1018  int ret;
1019  int timeDiff;
1020  int print_time;
1021  int need_to_resend = 0;
1022  int render_index = 0;
1023  int encode_index = -1;
1024  FILE *p_file = NULL;
1025  ni_xcoder_params_t api_param;
1026  ni_session_context_t enc_ctx = {0};
1027  ni_session_context_t upl_ctx = {0};
1028  ni_frame_t p2p_frame[POOL_SIZE];
1029  ni_session_data_io_t out_packet = {0};
1030  int input_file_fd = -1;
1031 
1032  parse_arguments(argc, argv, input_filename, output_filename, &iXcoderGUID,
1033  &arg_width, &arg_height, &dst_codec_format);
1034 
1035  // Load input file into memory
1036  if (load_input_file(input_filename, &total_file_size) < 0)
1037  {
1038  exit(-1);
1039  }
1040 
1042 
1043  // Create output file
1044  if (strcmp(output_filename, "null") != 0)
1045  {
1046  p_file = fopen(output_filename, "wb");
1047  if (p_file == NULL)
1048  {
1049  fprintf(stderr, "Error: cannot open %s\n", output_filename);
1050  goto end;
1051  }
1052  }
1053 
1054  printf("SUCCESS: Opened output file: %s\n", output_filename);
1055 
1056  if (ni_device_session_context_init(&enc_ctx) < 0)
1057  {
1058  fprintf(stderr, "Error: init encoder context error\n");
1059  return -1;
1060  }
1061 
1062  if (ni_device_session_context_init(&upl_ctx) < 0)
1063  {
1064  fprintf(stderr, "Error: init uploader context error\n");
1065  return -1;
1066  }
1067 
1068  total_bytes_received = 0;
1069  total_bytes_sent = 0;
1070 
1071  send_fin_flag = 0;
1072  receive_fin_flag = 0;
1073 
1074  printf("User video resolution: %dx%d\n", arg_width, arg_height);
1075 
1076  if (arg_width == 0 || arg_height == 0)
1077  {
1078  input_video_width = 1280;
1079  input_video_height = 720;
1080  } else
1081  {
1082  input_video_width = arg_width;
1083  input_video_height = arg_height;
1084  }
1085 
1086  ni_gettimeofday(&start_time, NULL);
1088  ni_gettimeofday(&current_time, NULL);
1090 
1091  printf("P2P Encoding resolution: %dx%d\n", input_video_width,
1092  input_video_height);
1093 
1094  // Open an uploader session to Quadra
1095  if (uploader_open_session(&upl_ctx, &iXcoderGUID, arg_width, arg_height))
1096  {
1097  goto end;
1098  }
1099 
1100  // Configure the encoder parameter structure. We'll use some basic
1101  // defaults: 30 fps, 200000 bps CBR encoding, AVC or HEVC encoding
1102  if (ni_encoder_init_default_params(&api_param, 30, 1, 200000, arg_width,
1103  arg_height, enc_ctx.codec_format) < 0)
1104  {
1105  fprintf(stderr, "Error: encoder init default set up error\n");
1107  return -1;
1108  }
1109 
1110  // For P2P demo, change some of the encoding parameters from
1111  // the default. Enable low delay encoding.
1112  if ((ret = ni_encoder_params_set_value(&api_param, "lowDelay", "1")) !=
1114  {
1115  fprintf(stderr, "Error: can't set low delay mode %d\n", ret);
1117  return -1;
1118  }
1119 
1120  // Use a GOP preset of 9 which represents a GOP pattern of
1121  // IPPPPPPP....This will be low latency.
1122  if ((ret = ni_encoder_params_set_value(&api_param, "gopPresetIdx", "9")) !=
1124  {
1125  fprintf(stderr, "Error: can't set gop preset %d\n", ret);
1127  return -1;
1128  }
1129 
1130  // Prepare two frames for double buffering
1131  ret = p2p_prepare_frames(&upl_ctx, input_video_width, input_video_height,
1132  p2p_frame);
1133 
1134  if (ret < 0)
1135  {
1137  goto end;
1138  }
1139 
1140  // Open the encoder session with given parameters
1141  ret = encoder_open_session(&enc_ctx, dst_codec_format, iXcoderGUID,
1142  &api_param, arg_width, arg_height,
1143  &p2p_frame[render_index]);
1144  if (ret < 0)
1145  {
1147  goto end;
1148  }
1149 
1150 #ifdef _WIN32
1151  input_file_fd = open(input_filename, O_RDONLY | O_BINARY);
1152 #else
1153  input_file_fd = open(input_filename, O_RDONLY);
1154 #endif
1155 
1156  if (input_file_fd < 0)
1157  {
1158  fprintf(stderr, "Error: can not open input file %s\n", input_filename);
1159  goto end;
1160  }
1161 
1162  if (g_rgb2yuv_csc)
1163  {
1164  // upload an rgba frame to quadra
1166  &upl_ctx, input_file_fd, &g_rgba_frame[render_index],
1167  &p2p_frame[render_index], input_video_width, input_video_height,
1168  &total_bytes_sent, &input_exhausted))
1169  {
1170  fprintf(stderr, "Error: upload frame error\n");
1172  goto end;
1173  }
1174  } else
1175  {
1176  /* send out a frame to do rendering */
1178  &upl_ctx, input_file_fd, &g_yuv_frame[render_index],
1179  &p2p_frame[render_index], input_video_width, input_video_height,
1180  &total_bytes_sent, &input_exhausted))
1181  {
1182  fprintf(stderr, "Error: upload frame error\n");
1183  close(input_file_fd);
1184  return -1;
1185  }
1186  }
1187 
1188  while (send_fin_flag == 0 || receive_fin_flag == 0)
1189  {
1190  ni_gettimeofday(&current_time, NULL);
1191 
1192  // Print the time if >= 1 second has passed
1193  print_time = ((current_time.tv_sec - previous_time.tv_sec) > 1);
1194  encode_index = render_index;
1195 
1196  // Encode the frame
1197  send_fin_flag = encoder_encode_frame(&enc_ctx, &p2p_frame[encode_index],
1198  input_exhausted, &need_to_resend);
1199 
1200  // Error, exit
1201  if (send_fin_flag == 2)
1202  {
1203  break;
1204  }
1205 
1206  // Switch to the other hw frame buffer
1207  render_index = !render_index;
1208 
1209  // Fill the frame buffer with YUV data while the previous frame is being encoded
1210  if (!input_exhausted && need_to_resend == 0)
1211  {
1212  if (g_rgb2yuv_csc)
1213  {
1215  &upl_ctx, input_file_fd, &g_rgba_frame[render_index],
1216  &p2p_frame[render_index], input_video_width,
1217  input_video_height, &total_bytes_sent, &input_exhausted))
1218  {
1219  fprintf(stderr, "Error: upload frame error\n");
1220  close(input_file_fd);
1221  return -1;
1222  }
1223  }
1224  else
1225  {
1227  &upl_ctx, input_file_fd, &g_yuv_frame[render_index],
1228  &p2p_frame[render_index], input_video_width,
1229  input_video_height, &total_bytes_sent, &input_exhausted))
1230  {
1231  fprintf(stderr, "Error: upload frame error\n");
1232  close(input_file_fd);
1233  return -1;
1234  }
1235  }
1236  }
1237 
1238  // Receive encoded packet data from the encoder
1240  &enc_ctx, &out_packet, p_file, &total_bytes_received, print_time);
1241 
1242  if (print_time)
1243  {
1245  }
1246 
1247  // Error or eos
1248  if (receive_fin_flag < 0 || out_packet.data.packet.end_of_stream)
1249  {
1250  break;
1251  }
1252  }
1253 
1254  timeDiff = (int)(current_time.tv_sec - start_time.tv_sec);
1255  timeDiff = (timeDiff > 0) ? timeDiff : 1; // avoid division by zero
1256 
1257  printf("[R] Got: Packets= %u fps=%u Total bytes %llu\n",
1259  total_bytes_received);
1260 
1261  // Recycle the hardware frames back to the pool prior
1262  // to closing the uploader session.
1263  num_post_recycled = recycle_frames(p2p_frame);
1264 
1265  ni_log(NI_LOG_DEBUG, "Cleanup recycled %d internal buffers\n", num_post_recycled);
1266 
1269 
1272 
1273  for (int i = 0; i < POOL_SIZE; i++)
1274  {
1275  ni_frame_buffer_free(&(p2p_frame[i]));
1276  }
1277 
1278  ni_packet_buffer_free(&(out_packet.data.packet));
1279 
1280 end:
1281  close(input_file_fd);
1282 
1283  if (p_file)
1284  {
1285  fclose(p_file);
1286  }
1287 
1288  printf("All done\n");
1289 
1290  return 0;
1291 }
ni_encoder_session_read_stream_header
int ni_encoder_session_read_stream_header(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data)
Read encoder stream header from the device.
Definition: ni_device_api.c:11232
NI_MAX_TX_SZ
#define NI_MAX_TX_SZ
Definition: ni_defs.h:249
ni_log_level_t
ni_log_level_t
Definition: ni_log.h:55
ni_encoder_params_set_value
ni_retcode_t ni_encoder_params_set_value(ni_xcoder_params_t *p_params, const char *name, const char *value)
Set value referenced by name in encoder parameters structure.
Definition: ni_device_api.c:5635
NI_DEVICE_TYPE_ENCODER
@ NI_DEVICE_TYPE_ENCODER
Definition: ni_defs.h:347
ni_pix_fmt_t
ni_pix_fmt_t
Definition: ni_device_api.h:260
number_of_frames
uint32_t number_of_frames
Definition: ni_p2p_test.c:57
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:3561
encoder_receive_data
int encoder_receive_data(ni_session_context_t *p_enc_ctx, ni_session_data_io_t *p_out_data, FILE *p_file, unsigned long long *total_bytes_received, int print_time)
Receive output packet data from the Quadra encoder.
Definition: ni_p2p_test.c:564
read_next_chunk_from_file
int read_next_chunk_from_file(int fd, uint8_t *p_dst, uint32_t to_read)
Read the next frame.
Definition: ni_p2p_test.c:102
_ni_session_context::session_id
uint32_t session_id
Definition: ni_device_api.h:1480
NI_SW_RELEASE_ID
#define NI_SW_RELEASE_ID
Definition: ni_release_info.h:29
NI_PIX_FMT_YUV420P
@ NI_PIX_FMT_YUV420P
Definition: ni_device_api.h:262
_ni_packet::end_of_stream
uint32_t end_of_stream
Definition: ni_device_api.h:2831
_ni_session_data_io::packet
ni_packet_t packet
Definition: ni_device_api.h:2871
NI_RETCODE_SUCCESS
@ NI_RETCODE_SUCCESS
Definition: ni_defs.h:427
g_yuv_frame
uint8_t * g_yuv_frame[POOL_SIZE]
Definition: ni_p2p_test.c:73
total_file_size
unsigned long total_file_size
Definition: ni_p2p_test.c:70
NI_DEVICE_TYPE_UPLOAD
@ NI_DEVICE_TYPE_UPLOAD
Definition: ni_defs.h:353
NI_INVALID_SESSION_ID
#define NI_INVALID_SESSION_ID
Definition: ni_device_api.h:111
previous_timestamp
time_t previous_timestamp
Definition: ni_p2p_test.c:67
ni_log_set_level
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
Definition: ni_log.c:202
send_fin_flag
int send_fin_flag
Definition: ni_p2p_test.c:53
required_argument
#define required_argument
Definition: ni_getopt.h:86
NI_XCODER_REVISION
#define NI_XCODER_REVISION
Definition: ni_defs.h:95
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:3843
_ni_session_context::blk_io_handle
ni_device_handle_t blk_io_handle
Definition: ni_device_api.h:1465
current_timestamp
time_t current_timestamp
Definition: ni_p2p_test.c:68
no_argument
#define no_argument
Definition: ni_getopt.h:85
MAX_YUV_FRAME_SIZE
#define MAX_YUV_FRAME_SIZE
Definition: ni_p2p_test.c:48
_ni_session_context::bit_depth_factor
int bit_depth_factor
Definition: ni_device_api.h:1494
p2p_upload_rgba_send_data
int p2p_upload_rgba_send_data(ni_session_context_t *p_upl_ctx, int fd, uint8_t **p_rgba_frame, ni_frame_t *p_in_frame, int input_video_width, int input_video_height, unsigned long *bytes_sent, int *input_exhausted)
Reads RGBA data from input file then calls a special libxcoder API function to transfer the RGBA data...
Definition: ni_p2p_test.c:336
_ni_session_context::hw_id
int hw_id
Definition: ni_device_api.h:1478
ni_copy_hw_yuv420p
void ni_copy_hw_yuv420p(uint8_t *p_dst[NI_MAX_NUM_DATA_POINTERS], uint8_t *p_src[NI_MAX_NUM_DATA_POINTERS], int frame_width, int frame_height, int factor, int is_semiplanar, int conf_win_right, int dst_stride[NI_MAX_NUM_DATA_POINTERS], int dst_height[NI_MAX_NUM_DATA_POINTERS], int src_stride[NI_MAX_NUM_DATA_POINTERS], int src_height[NI_MAX_NUM_DATA_POINTERS])
Copy YUV data to Netint HW YUV420p frame layout to be sent to encoder for encoding....
Definition: ni_util.c:2352
ni_retcode_t
ni_retcode_t
Definition: ni_defs.h:425
ni_packet_buffer_alloc
ni_retcode_t ni_packet_buffer_alloc(ni_packet_t *p_packet, int packet_size)
Allocate memory for the packet buffer based on provided packet size.
Definition: ni_device_api.c:3713
number_of_packets
uint32_t number_of_packets
Definition: ni_p2p_test.c:58
ni_device_session_acquire
int ni_device_session_acquire(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
Acquire a P2P frame buffer from the hwupload session.
Definition: ni_device_api.c:10602
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
NI_LOG_ERROR
@ NI_LOG_ERROR
Definition: ni_log.h:60
p2p_upload_send_data
int p2p_upload_send_data(ni_session_context_t *p_upl_ctx, int fd, uint8_t **p_yuv420p_frame, ni_frame_t *p_in_frame, int input_video_width, int input_video_height, unsigned long *bytes_sent, int *input_exhausted)
Reads YUV data from input file then calls a special libxcoder API function to transfer the YUV data i...
Definition: ni_p2p_test.c:218
print_usage
void print_usage(void)
Print usage information.
Definition: ni_p2p_test.c:833
_ni_frame::data_len
uint32_t data_len[NI_MAX_NUM_DATA_POINTERS]
Definition: ni_device_api.h:2664
_ni_frame::extra_data_len
unsigned int extra_data_len
Definition: ni_device_api.h:2657
p2p_prepare_frames
int p2p_prepare_frames(ni_session_context_t *p_upl_ctx, int input_video_width, int input_video_height, ni_frame_t p2p_frame[])
Prepare frames to simulate P2P transfers.
Definition: ni_p2p_test.c:419
ni_encoder_init_default_params
ni_retcode_t ni_encoder_init_default_params(ni_xcoder_params_t *p_param, int fps_num, int fps_denom, long bit_rate, int width, int height, ni_codec_format_t codec_format)
Initialize default encoder parameters.
Definition: ni_device_api.c:4147
uploader_open_session
int uploader_open_session(ni_session_context_t *p_upl_ctx, int *iXcoderGUID, int width, int height)
Open an upload session to Quadra.
Definition: ni_p2p_test.c:778
previous_time
struct timeval previous_time
Definition: ni_p2p_test.c:63
_ni_frame::end_of_stream
uint32_t end_of_stream
Definition: ni_device_api.h:2608
current_time
struct timeval current_time
Definition: ni_p2p_test.c:64
_ni_xcoder_params::hwframes
int hwframes
Definition: ni_device_api.h:2774
_ni_session_context::device_handle
ni_device_handle_t device_handle
Definition: ni_device_api.h:1462
_ni_session_context::p_session_config
void * p_session_config
Definition: ni_device_api.h:1473
NI_SW_RELEASE_TIME
#define NI_SW_RELEASE_TIME
Definition: ni_release_info.h:28
_ni_packet::p_data
void * p_data
Definition: ni_device_api.h:2837
_ni_session_data_io
Definition: ni_device_api.h:2866
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:57
ni_hwframe_p2p_buffer_recycle
ni_retcode_t ni_hwframe_p2p_buffer_recycle(ni_frame_t *p_frame)
Recycle hw P2P frames.
Definition: ni_device_api.c:10996
getopt_long
int getopt_long(int argc, char *argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: ni_getopt.c:99
ni_uploader_set_frame_format
ni_retcode_t ni_uploader_set_frame_format(ni_session_context_t *p_upl_ctx, int width, int height, ni_pix_fmt_t pixel_format, int isP2P)
Set the outgoing frame format for the uploader.
Definition: ni_device_api.c:11171
g_repeat
int g_repeat
Definition: ni_p2p_test.c:60
_ni_frame::force_key_frame
int force_key_frame
Definition: ni_device_api.h:2624
_ni_packet
Definition: ni_device_api.h:2825
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:249
ni_encoder_set_input_frame_format
ni_retcode_t ni_encoder_set_input_frame_format(ni_session_context_t *p_enc_ctx, ni_xcoder_params_t *p_enc_params, int width, int height, int bit_depth, int src_endian, int planar)
Set the incoming frame format for the encoder.
Definition: ni_device_api.c:11083
optarg
char * optarg
Definition: ni_getopt.c:33
start_timestamp
time_t start_timestamp
Definition: ni_p2p_test.c:66
data_left_size
uint64_t data_left_size
Definition: ni_p2p_test.c:59
_ni_session_context::hw_action
int hw_action
Definition: ni_device_api.h:1609
MAX_ABGR_FRAME_SIZE
#define MAX_ABGR_FRAME_SIZE
Definition: ni_p2p_test.c:49
_ni_session_context
Definition: ni_device_api.h:1408
POOL_SIZE
#define POOL_SIZE
Definition: ni_p2p_test.c:50
ni_device_session_read
int ni_device_session_read(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data, ni_device_type_t device_type)
Read data from the device If device_type is NI_DEVICE_TYPE_DECODER reads data packet from decoder If ...
Definition: ni_device_api.c:1769
NI_CODEC_HW_ENABLE
@ NI_CODEC_HW_ENABLE
Definition: ni_device_api.h:940
ni_frame_buffer_alloc_hwenc
ni_retcode_t ni_frame_buffer_alloc_hwenc(ni_frame_t *p_frame, int video_width, int video_height, int extra_len)
Allocate memory for the hwDescriptor buffer based on provided parameters taking into account pic size...
Definition: ni_device_api.c:8399
NI_MAX_NUM_DATA_POINTERS
#define NI_MAX_NUM_DATA_POINTERS
Definition: ni_defs.h:232
_ni_session_data_io::data
union _ni_session_data_io::@19 data
_ni_frame
Definition: ni_device_api.h:2601
ni_device_session_open
ni_retcode_t ni_device_session_open(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Open a new device session depending on the device_type parameter If device_type is NI_DEVICE_TYPE_DEC...
Definition: ni_device_api.c:710
g_rgb2yuv_csc
uint8_t g_rgb2yuv_csc
Definition: ni_p2p_test.c:76
encoder_encode_frame
int encoder_encode_frame(ni_session_context_t *p_enc_ctx, ni_frame_t *p_in_frame, int input_exhausted, int *need_to_resend)
Send the Quadra encoder a hardware frame which triggers Quadra to encode the frame.
Definition: ni_p2p_test.c:481
NI_VPU_ALIGN4096
#define NI_VPU_ALIGN4096(_x)
Definition: ni_device_api.h:338
NI_PIX_FMT_ABGR
@ NI_PIX_FMT_ABGR
Definition: ni_device_api.h:269
_ni_xcoder_params
Definition: ni_device_api.h:2713
option
Definition: ni_getopt.h:73
g_curr_cache_pos
uint8_t * g_curr_cache_pos
Definition: ni_p2p_test.c:72
_ni_session_context::ready_to_close
uint32_t ready_to_close
Definition: ni_device_api.h:1544
g_rgba_frame
uint8_t * g_rgba_frame[POOL_SIZE]
Definition: ni_p2p_test.c:74
_ni_session_context::codec_format
uint32_t codec_format
Definition: ni_device_api.h:1486
ni_posix_memalign
int ni_posix_memalign(void **memptr, size_t alignment, size_t size)
Allocate aligned memory.
Definition: ni_util.c:198
parse_arguments
void parse_arguments(int argc, char *argv[], char *input_filename, char *output_filename, int *iXcoderGUID, int *arg_width, int *arg_height, int *dst_codec_format)
Parse user command line arguments.
Definition: ni_p2p_test.c:878
ni_log2
void ni_log2(const void *p_context, ni_log_level_t level, const char *fmt,...)
print log message and additional information using ni_log_callback,
Definition: ni_log.c:337
load_input_file
int load_input_file(const char *filename, unsigned long *bytes_read)
Load the input file into memory.
Definition: ni_p2p_test.c:150
_ni_session_data_io::frame
ni_frame_t frame
Definition: ni_device_api.h:2870
recycle_frames
int recycle_frames(ni_frame_t p2p_frame[])
Recycle hw frames back to Quadra.
Definition: ni_p2p_test.c:180
main
int main(int argc, char *argv[])
Definition: ni_p2p_test.c:1004
atoi
#define atoi(p_str)
Definition: ni_device_api.c:7178
ni_get_hw_yuv420p_dim
void ni_get_hw_yuv420p_dim(int width, int height, int factor, int is_semiplanar, int plane_stride[NI_MAX_NUM_DATA_POINTERS], int plane_height[NI_MAX_NUM_DATA_POINTERS])
Get dimension information of Netint HW YUV420p frame to be sent to encoder for encoding....
Definition: ni_util.c:2040
_ni_frame::video_height
uint32_t video_height
Definition: ni_device_api.h:2611
LIBXCODER_API_VERSION
#define LIBXCODER_API_VERSION
Definition: ni_defs.h:112
start_time
struct timeval start_time
Definition: ni_p2p_test.c:62
ni_device_session_write
int ni_device_session_write(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data, ni_device_type_t device_type)
Sends data to the device If device_type is NI_DEVICE_TYPE_DECODER sends data packet to decoder If dev...
Definition: ni_device_api.c:1668
ni_gettimeofday
int32_t ni_gettimeofday(struct timeval *p_tp, void *p_tzp)
Get time for logs with microsecond timestamps.
Definition: ni_util.c:139
ni_device_api.h
Public definitions for operating NETINT video processing devices for video processing.
_ni_session_context::meta_size
uint32_t meta_size
Params used in VFR mode Done///.
Definition: ni_device_api.h:1638
_ni_frame::start_of_stream
uint32_t start_of_stream
Definition: ni_device_api.h:2609
ni_util.h
Utility definitions.
NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_H264
Definition: ni_device_api.h:911
FILE_NAME_LEN
#define FILE_NAME_LEN
Definition: ni_p2p_test.c:51
_ni_frame::video_width
uint32_t video_width
Definition: ni_device_api.h:2610
NI_FRAME_LITTLE_ENDIAN
#define NI_FRAME_LITTLE_ENDIAN
Definition: ni_device_api.h:108
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_device_session_init_framepool
int ni_device_session_init_framepool(ni_session_context_t *p_ctx, uint32_t pool_size, uint32_t pool)
Sends frame pool setup info to device.
Definition: ni_device_api.c:8564
_ni_session_context::pixel_format
int pixel_format
Definition: ni_device_api.h:1616
encoder_open_session
int encoder_open_session(ni_session_context_t *p_enc_ctx, int dst_codec_format, int iXcoderGUID, ni_xcoder_params_t *p_enc_params, int width, int height, ni_frame_t *p_frame)
Open an encoder session to Quadra.
Definition: ni_p2p_test.c:724
NI_LOG_DEBUG
@ NI_LOG_DEBUG
Definition: ni_log.h:62
ni_uploader_p2p_test_send
ni_retcode_t ni_uploader_p2p_test_send(ni_session_context_t *p_upl_ctx, uint8_t *p_data, uint32_t len, ni_frame_t *p_hwframe)
Special P2P test API function. Copies YUV data from the software frame to the hardware P2P frame on t...
Definition: ni_device_api.c:10869
ni_device_session_close
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...
Definition: ni_device_api.c:1379
arg_error_exit
void arg_error_exit(char *arg_name, char *param)
Exit on argument error.
Definition: ni_p2p_test.c:86
enc_eos_sent
int enc_eos_sent
Definition: ni_p2p_test.c:55
_ni_xcoder_params::p_first_frame
ni_frame_t * p_first_frame
Definition: ni_device_api.h:2776
receive_fin_flag
int receive_fin_flag
Definition: ni_p2p_test.c:54
NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_H265
Definition: ni_device_api.h:912
_ni_packet::data_len
uint32_t data_len
Definition: ni_device_api.h:2838