35 #define _POSIX_C_SOURCE 200809L
38 #include <sys/types.h>
49 #define MAX_YUV_FRAME_SIZE (7680 * 4320 * 3 / 2)
51 #define FILE_NAME_LEN 256
76 static int32_t log_str_to_level(
char *log_str)
80 for (i = 0; i < strlen(log_str); i++)
81 log_str[i] = tolower((
unsigned char) log_str[i]);
83 if (strcmp(log_str,
"none") == 0)
85 else if (strcmp(log_str,
"fatal") == 0)
87 else if (strcmp(log_str,
"error") == 0)
89 else if (strcmp(log_str,
"info") == 0)
91 else if (strcmp(log_str,
"debug") == 0)
93 else if (strcmp(log_str,
"trace") == 0)
96 converted_log_level = -16;
97 return converted_log_level;
111 fprintf(stderr,
"Error: unrecognized argument for %s, \"%s\"\n", arg_name,
127 uint8_t *tmp_dst = p_dst;
129 "read_next_chunk_from_file:p_dst %p len %u totalSize %llu left %llu\n",
131 int to_copy = to_read;
132 unsigned long tmpFileSize = to_read;
140 lseek(fd, 0, SEEK_SET);
151 int one_read_size = read(fd, tmp_dst, to_copy);
152 if (one_read_size == -1)
154 fprintf(stderr,
"Error: reading file, quit! left-to-read %lu\n",
156 fprintf(stderr,
"Error: input file read error\n");
178 if (stat(filename, &info) < 0)
180 fprintf(stderr,
"Can't stat %s\n", filename);
185 if (info.st_size <= 0)
187 fprintf(stderr,
"File %s is empty\n", filename);
191 *bytes_read = info.st_size;
212 rc = ni_hwframe_p2p_buffer_recycle(&p2p_frame[i]);
214 if (rc != NI_RETCODE_SUCCESS)
216 fprintf(stderr,
"Recycle failed\n");
219 cnt += (rc == NI_RETCODE_SUCCESS) ? 1 : 0;
244 int input_video_width,
int input_video_height,
245 unsigned long *bytes_sent,
int *input_exhausted)
265 frame_size = input_video_height * input_video_width * 3 / 2;
272 *input_exhausted = 1;
284 "dst height aligned = %d/%d/%d \n",
285 dst_stride[0], dst_stride[1], dst_stride[2],
286 input_video_height, dst_height[0], dst_height[1],
290 src_stride[1] = src_stride[2] = src_stride[0] / 2;
292 src_height[0] = input_video_height;
293 src_height[1] = src_height[0] / 2;
294 src_height[2] = src_height[1];
297 p_src[1] = tmp_buf + src_stride[0] * src_height[0];
298 p_src[2] = p_src[1] + src_stride[1] * src_height[1];
300 Ysize = dst_stride[0] * dst_height[0];
301 Usize = dst_stride[1] * dst_height[1];
302 Vsize = dst_stride[2] * dst_height[2];
304 total_size = Ysize + Usize + Vsize;
305 total_size = ((total_size + 4095) & ~4095);
307 if (*p_yuv420p_frame == NULL)
311 fprintf(stderr,
"Can't alloc memory\n");
315 *p_yuv420p_frame = p_buffer;
318 p_dst[0] = *p_yuv420p_frame;
319 p_dst[1] = *p_yuv420p_frame + Ysize;
320 p_dst[2] = *p_yuv420p_frame + Ysize + Usize;
324 dst_stride, dst_height, src_stride, src_height);
329 fprintf(stderr,
"Error: failed ni_uploader_p2p_test_send()\n");
334 *bytes_sent = total_size;
364 p_in_frame = &p2p_frame[i];
377 p_in_frame, input_video_width, input_video_height,
380 fprintf(stderr,
"Error: could not allocate hw frame buffer!");
389 fprintf(stderr,
"Error: failed ni_device_session_acquire()\n");
423 static int started = 0;
463 "Error: failed ni_device_session_write() for encoder\n");
504 unsigned long long *total_bytes_received,
513 static int received_stream_header = 0;
533 fprintf(stderr,
"Error: malloc packet failed, ret = %d!\n", rc);
541 if (!received_stream_header)
549 if (fwrite((uint8_t *)p_out_pkt->
p_data + meta_size,
550 p_out_pkt->
data_len - meta_size, 1, p_file) != 1)
552 fprintf(stderr,
"Error: writing data %u bytes error!\n",
554 fprintf(stderr,
"Error: ferror rc = %d\n", ferror(p_file));
557 *total_bytes_received += (rx_size - meta_size);
559 received_stream_header = 1;
562 fprintf(stderr,
"Error: reading header %d\n", rc);
573 printf(
"[R] Got:%d Packets= %u fps=%u Total bytes %llu\n",
575 *total_bytes_received);
596 if (rx_size > meta_size)
598 if (fwrite((uint8_t *)p_out_pkt->
p_data + meta_size,
599 p_out_pkt->
data_len - meta_size, 1, p_file) != 1)
601 fprintf(stderr,
"Error: writing data %u bytes error!\n",
603 fprintf(stderr,
"Error: ferror rc = %d\n", ferror(p_file));
606 *total_bytes_received += rx_size - meta_size;
610 }
else if (rx_size != 0)
612 fprintf(stderr,
"Error: received %d bytes, <= metadata size %d!\n",
615 }
else if (!end_flag &&
630 printf(
"[R] Got:%d Packets= %u fps=%u Total bytes %llu\n", rx_size,
632 *total_bytes_received);
637 printf(
"Encoder Receiving done\n");
639 }
else if (0 == rx_size)
657 int dst_codec_format,
int xcoder_id,
658 const char *xcoder_name,
660 int src_bit_depth,
int width,
int height,
664 int video_full_range_flag,
665 int sar_num,
int sar_den,
683 p_enc_ctx->
hw_id = xcoder_id;
684 p_enc_ctx->
hw_name = xcoder_name;
695 int linesize_aligned = ((width + 7) / 8) * 8;
698 linesize_aligned = ((width + 15) / 16) * 16;
705 else if (linesize_aligned > width)
711 int height_aligned = ((height + 7) / 8) * 8;
714 height_aligned = ((height + 15) / 16) * 16;
721 else if (height_aligned > height)
728 ni_logan_set_vui(p_enc_params, p_enc_ctx, color_primaries, color_trc, color_space,
729 video_full_range_flag, sar_num, sar_den, dst_codec_format);
734 fprintf(stderr,
"Error: %s failure!\n", __FUNCTION__);
738 if (xcoder_name != NULL)
740 printf(
"Encoder device %s session open successful.\n", xcoder_name);
744 printf(
"Encoder device %d session open successful.\n", xcoder_id);
763 int width,
int height)
774 p_upl_ctx->
hw_id = *iXcoderGUID;
782 p_upl_ctx->
isP2P = 1;
787 fprintf(stderr,
"Error: uploader_open_session failure!\n");
791 printf(
"Uploader device %d session opened successfully\n",
793 *iXcoderGUID = p_upl_ctx->
hw_id;
800 fprintf(stderr,
"Error: Can't create frame pool\n");
804 printf(
"Uploader device %d configured successfully\n", *iXcoderGUID);
819 printf(
"Video encoder/P2P application directly using Netint "
820 "Libxcoder release v%s\n"
821 "Usage: xcoderp2p [options]\n"
824 "--------------------------------------------------------------------------------"
825 " -h | --help Show help.\n"
826 " -v | --version Print version info.\n"
827 " -l | --loglevel Set loglevel of libxcoder API.\n"
828 " [none, fatal, error, info, debug, trace]\n"
830 " -c | --card Set card index to use.\n"
831 " See `ni_rsrc_mon_logan` for cards on system.\n"
833 " -i | --input Input file path.\n"
834 " -r | --repeat (Positive integer) to Repeat input X times "
836 " test. (Default: 1)\n"
837 " -s | --size Resolution of input file in format "
839 " (eg. '1920x1080')\n"
840 " -m | --mode Input to output codec processing mode in "
842 " INTYPE2OUTTYPE. [p2a, p2h]\n"
843 " Type notation: p=P2P, a=AVC, h=HEVC\n"
844 " -o | --output Output file path.\n",
863 char *output_filename,
int *iXcoderGUID,
int *arg_width,
864 int *arg_height,
int *dst_codec_format)
867 char mode_description[128];
874 static const char *opt_string =
"hvl:c:i:s:m:o:r:";
875 static const struct option long_options[] = {
888 while ((opt =
getopt_long(argc, argv, opt_string, long_options,
900 log_level = log_str_to_level(
optarg);
901 if (log_level < NI_LOG_NONE || log_level >
NI_LOG_TRACE)
906 strcpy(xcoderGUID,
optarg);
907 *iXcoderGUID = (int)strtol(
optarg, &n, 10);
913 strcpy(input_filename,
optarg);
916 *arg_width = (int)strtol(
optarg, &n, 10);
917 *arg_height =
atoi(n + 1);
918 if ((*n !=
'x') || (!*arg_width || !*arg_height))
922 if (!(strlen(
optarg) == 3))
926 for (i = 0; i < strlen(
optarg); i++)
929 if (strcmp(
optarg,
"p2a") != 0 && strcmp(
optarg,
"p2h") != 0)
933 sprintf(mode_description,
"P2P + Encoding");
938 strcat(mode_description,
" to AVC");
944 strcat(mode_description,
" to HEVC");
946 printf(
"%s...\n", mode_description);
950 strcpy(output_filename,
optarg);
964 if (!input_filename[0])
966 printf(
"Error: missing argument for -i | --input\n");
970 if (!output_filename[0])
972 printf(
"Error: missing argument for -o | --output\n");
977 int main(
int argc,
char *argv[])
981 unsigned long total_bytes_sent;
982 unsigned long long total_bytes_received;
983 int input_video_width;
984 int input_video_height;
988 int input_exhausted = 0;
989 int num_post_recycled = 0;
990 int dst_codec_format = 0;
994 int need_to_resend = 0;
995 int render_index = 0;
996 int encode_index = -1;
1003 int input_file_fd = -1;
1004 char encConfXcoderParams[2048] = { 0 };
1006 parse_arguments(argc, argv, input_filename, output_filename, &iXcoderGUID,
1007 &arg_width, &arg_height, &dst_codec_format);
1018 if (strcmp(output_filename,
"null") != 0)
1020 p_file = fopen(output_filename,
"wb");
1023 fprintf(stderr,
"Error: cannot open %s\n", output_filename);
1028 printf(
"SUCCESS: Opened output file: %s\n", output_filename);
1040 total_bytes_received = 0;
1041 total_bytes_sent = 0;
1046 printf(
"User video resolution: %dx%d\n", arg_width, arg_height);
1048 if (arg_width == 0 || arg_height == 0)
1050 input_video_width = 1280;
1051 input_video_height = 720;
1054 input_video_width = arg_width;
1055 input_video_height = arg_height;
1063 printf(
"P2P Encoding resolution: %dx%d\n", input_video_width,
1064 input_video_height);
1077 fprintf(stderr,
"Error: encoder init default set up error\n");
1087 fprintf(stderr,
"Error: can't set low delay mode %d\n", ret);
1097 fprintf(stderr,
"Error: can't set gop preset %d\n", ret);
1112 int video_full_range_flag = 0;
1122 &api_param, 8, arg_width, arg_height,
1126 video_full_range_flag,
1135 input_file_fd = open(input_filename, O_RDONLY | O_BINARY);
1137 input_file_fd = open(input_filename, O_RDONLY);
1140 if (input_file_fd < 0)
1142 fprintf(stderr,
"Error: can not open input file %s\n", input_filename);
1148 &upl_ctx, input_file_fd, &
g_yuv_frame[render_index],
1149 &p2p_frame[render_index], input_video_width, input_video_height,
1150 &total_bytes_sent, &input_exhausted))
1152 fprintf(stderr,
"Error: upload frame error\n");
1153 close(input_file_fd);
1163 encode_index = render_index;
1173 input_exhausted, &need_to_resend);
1182 render_index = !render_index;
1185 if (!input_exhausted && need_to_resend == 0)
1188 &upl_ctx, input_file_fd, &
g_yuv_frame[render_index],
1189 &p2p_frame[render_index], input_video_width,
1190 input_video_height, &total_bytes_sent, &input_exhausted))
1192 fprintf(stderr,
"Error: upload frame error\n");
1193 close(input_file_fd);
1200 &enc_ctx, &out_packet, p_file, &total_bytes_received, print_time);
1209 fprintf(stderr,
"Failed to unlock frame\n");
1227 timeDiff = (timeDiff > 0) ? timeDiff : 1;
1229 printf(
"[R] Got: Packets= %u fps=%u Total bytes %llu\n",
1231 total_bytes_received);
1254 close(input_file_fd);
1261 printf(
"All done\n");
void ni_logan_set_vui(ni_logan_encoder_params_t *p_param, ni_logan_session_context_t *p_ctx, ni_color_primaries_t color_primaries, ni_color_transfer_characteristic_t color_trc, ni_color_space_t color_space, int video_full_range_flag, int sar_num, int sar_den, ni_logan_codec_format_t codec_format)
Set SPS VUI part of encoded stream header.
NETINT audio/video related utility functions.
enum _ni_color_primaries ni_color_primaries_t
enum _ni_color_transfer_characteristic ni_color_transfer_characteristic_t
enum _ni_color_space ni_color_space_t
@ NI_LOGAN_RETCODE_SUCCESS
#define NI_LOGAN_FW_ENC_BITSTREAM_META_DATA_SIZE
#define NI_LOGAN_MAX_NUM_DATA_POINTERS
#define NI_LOGAN_XCODER_REVISION
@ NI_LOGAN_DEVICE_TYPE_UPLOAD
@ NI_LOGAN_DEVICE_TYPE_ENCODER
#define NI_LOGAN_MAX_TX_SZ
ni_logan_retcode_t ni_logan_uploader_frame_buffer_unlock(ni_logan_session_context_t *p_upl_ctx, ni_logan_frame_t *p_frame)
Unlock a hardware P2P frame after encoding.
ni_logan_retcode_t ni_logan_packet_buffer_alloc(ni_logan_packet_t *p_packet, int packet_size)
Allocate memory for the packet buffer based on provided packet size.
ni_logan_retcode_t ni_logan_device_session_close(ni_logan_session_context_t *p_ctx, int eos_recieved, ni_logan_device_type_t device_type)
Closes device session that was previously opened by calling ni_logan_device_session_open() If device_...
ni_logan_retcode_t ni_logan_frame_buffer_alloc_hwenc(ni_logan_frame_t *p_frame, int video_width, int video_height, int extra_len)
Allocate memory for the frame buffer based on provided parameters taking into account pic line size a...
ni_logan_retcode_t ni_logan_uploader_frame_buffer_lock(ni_logan_session_context_t *p_upl_ctx, ni_logan_frame_t *p_frame)
Lock a hardware P2P frame prior to encoding.
int ni_logan_device_session_acquire(ni_logan_session_context_t *p_ctx, ni_logan_frame_t *p_frame)
Acquire a P2P frame buffer from the hwupload session.
ni_logan_retcode_t ni_logan_packet_buffer_free(ni_logan_packet_t *p_packet)
Free packet buffer that was previously allocated with either ni_logan_packet_buffer_alloc.
void ni_logan_device_session_context_init(ni_logan_session_context_t *p_ctx)
Initialize already allocated session context to a known state.
ni_logan_retcode_t ni_logan_frame_buffer_free(ni_logan_frame_t *p_frame)
Free frame buffer that was previously allocated with either ni_logan_frame_buffer_alloc or ni_logan_e...
int ni_logan_device_session_init_framepool(ni_logan_session_context_t *p_ctx, uint32_t pool_size, uint32_t p2p_pool)
Sends frame pool setup info to device.
ni_logan_retcode_t ni_logan_uploader_p2p_test_send(ni_logan_session_context_t *p_upl_ctx, uint8_t *p_data, uint32_t len, ni_logan_frame_t *p_hwframe)
Special P2P test API function. Copies YUV data from the software frame to the hardware P2P frame on t...
int ni_logan_device_session_read(ni_logan_session_context_t *p_ctx, ni_logan_session_data_io_t *p_data, ni_logan_device_type_t device_type)
Reads data the device If device_type is NI_LOGAN_DEVICE_TYPE_DECODER reads data packet from decoder I...
ni_logan_retcode_t ni_logan_encoder_params_set_value(ni_logan_encoder_params_t *p_params, const char *name, const char *value, ni_logan_session_context_t *ctx)
Set value referenced by name in encoder parameters structure.
void ni_logan_device_session_context_clear(ni_logan_session_context_t *p_ctx)
Clear already allocated session context to all zeros.
ni_logan_retcode_t ni_logan_encoder_init_default_params(ni_logan_encoder_params_t *p_param, int fps_num, int fps_denom, long bit_rate, int width, int height)
Initialize default encoder parameters.
ni_logan_retcode_t ni_logan_device_session_open(ni_logan_session_context_t *p_ctx, ni_logan_device_type_t device_type)
Opens a new device session depending on the device_type parameter If device_type is NI_LOGAN_DEVICE_T...
int ni_logan_device_session_write(ni_logan_session_context_t *p_ctx, ni_logan_session_data_io_t *p_data, ni_logan_device_type_t device_type)
Sends data the device If device_type is NI_LOGAN_DEVICE_TYPE_DECODER sends data packet to decoder If ...
Main NETINT device API header file provides the ability to communicate with NI T-408 type hardware tr...
@ NI_LOGAN_CODEC_HW_ENABLE
#define NI_LOGAN_MIN_WIDTH
#define NI_LOGAN_MIN_HEIGHT
#define NI_LOGAN_FRAME_LITTLE_ENDIAN
@ NI_LOGAN_CODEC_FORMAT_H265
@ NI_LOGAN_CODEC_FORMAT_H264
@ NI_LOGAN_PIX_FMT_YUV420P
#define NI_LOGAN_INVALID_SESSION_ID
int getopt_long(int argc, char *argv[], const char *optstring, const struct option *longopts, int *longindex)
#define required_argument
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
int load_input_file(const char *filename, unsigned long *bytes_read)
Load the input file into memory.
#define MAX_YUV_FRAME_SIZE
int main(int argc, char *argv[])
uint8_t * g_curr_cache_pos
time_t previous_timestamp
struct timeval current_time
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.
int uploader_open_session(ni_logan_session_context_t *p_upl_ctx, int *iXcoderGUID, int width, int height)
Open an upload session to T408.
int encoder_receive_data(ni_logan_session_context_t *p_enc_ctx, ni_logan_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.
int read_next_chunk_from_file(int fd, uint8_t *p_dst, uint32_t to_read)
Read the next frame.
void print_usage(void)
Print usage information.
int p2p_prepare_frames(ni_logan_session_context_t *p_upl_ctx, int input_video_width, int input_video_height, ni_logan_frame_t p2p_frame[])
Prepare frames to simulate P2P transfers.
uint8_t * g_yuv_frame[POOL_SIZE]
uint32_t number_of_packets
unsigned long total_file_size
struct timeval start_time
int encoder_encode_frame(ni_logan_session_context_t *p_enc_ctx, ni_logan_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.
int p2p_upload_send_data(ni_logan_session_context_t *p_upl_ctx, int fd, uint8_t **p_yuv420p_frame, ni_logan_frame_t *p_in_frame, int input_video_width, int input_video_height, unsigned long *bytes_sent, int *input_exhausted)
Recycle hw frames back to T408.
void arg_error_exit(char *arg_name, char *param)
Exit on argument error.
struct timeval previous_time
uint32_t number_of_frames
int encoder_open_session(ni_logan_session_context_t *p_enc_ctx, int dst_codec_format, int xcoder_id, const char *xcoder_name, ni_logan_encoder_params_t *p_enc_params, int src_bit_depth, int width, int height, ni_color_primaries_t color_primaries, ni_color_transfer_characteristic_t color_trc, ni_color_space_t color_space, int video_full_range_flag, int sar_num, int sar_den, ni_logan_frame_t *p_frame)
Encoder session open.
int32_t ni_logan_posix_memalign(void **pp_memptr, size_t alignment, size_t size)
void ni_logan_copy_hw_yuv420p(uint8_t *p_dst[NI_LOGAN_MAX_NUM_DATA_POINTERS], uint8_t *p_src[NI_LOGAN_MAX_NUM_DATA_POINTERS], int frame_width, int frame_height, int bit_depth_factor, int dst_stride[NI_LOGAN_MAX_NUM_DATA_POINTERS], int dst_height[NI_LOGAN_MAX_NUM_DATA_POINTERS], int src_stride[NI_LOGAN_MAX_NUM_DATA_POINTERS], int src_height[NI_LOGAN_MAX_NUM_DATA_POINTERS])
Copy YUV data to Netint HW YUV420p frame layout to be sent to encoder for encoding....
void ni_logan_get_hw_yuv420p_dim(int width, int height, int bit_depth_factor, int is_h264, int plane_stride[NI_LOGAN_MAX_NUM_DATA_POINTERS], int plane_height[NI_LOGAN_MAX_NUM_DATA_POINTERS])
Get dimension information of Netint HW YUV420p frame to be sent to encoder for encoding....
int32_t ni_logan_gettimeofday(struct timeval *p_tp, void *p_tzp)
Exported utility routines definition.
ni_logan_encoder_input_params_t enc_input_params
int color_transfer_characteristic
ni_logan_frame_t * p_first_frame
int video_full_range_flag
uint32_t data_len[NI_LOGAN_MAX_NUM_DATA_POINTERS]
unsigned int extra_data_len
ni_device_handle_t device_handle
ni_device_handle_t blk_io_handle
ni_region_of_interest_t * av_rois
uint32_t active_video_width
uint32_t active_video_height
union _ni_logan_session_data_io::@4 data