 |
libxcoder
5.2.0
|
Go to the documentation of this file.
40 #define _POSIX_C_SOURCE 200809L
43 #include <sys/types.h>
54 #include <sys/ioctl.h>
57 #define MAX_YUV_FRAME_SIZE (7680 * 4320 * 3 / 2)
58 #define MAX_ABGR_FRAME_SIZE (7680 * 4320 * 4)
60 #if MAX_ABGR_FRAME_SIZE > MAX_YUV_FRAME_SIZE
61 #define MAX_FRAME_SIZE MAX_ABGR_FRAME_SIZE
63 #define MAX_FRAME_SIZE MAX_YUV_FRAME_SIZE
66 #define FILE_NAME_LEN 256
67 #define MAX_SWAP_SIZE 3
109 fprintf(stderr,
"Error: unrecognized argument for %s, \"%s\"\n", arg_name,
125 uint8_t *tmp_dst = p_dst;
127 "read_next_chunk_from_file:p_dst %p len %u totalSize %llu left %llu\n",
129 int to_copy = to_read;
130 unsigned long tmpFileSize = to_read;
138 lseek(fd, 0, SEEK_SET);
149 int one_read_size = read(fd, tmp_dst, to_copy);
150 if (one_read_size == -1)
152 fprintf(stderr,
"Error: reading file, quit! left-to-read %lu\n",
154 fprintf(stderr,
"Error: input file read error\n");
176 if (stat(filename, &info) < 0)
178 fprintf(stderr,
"Can't stat %s\n", filename);
183 if (info.st_size <= 0)
185 fprintf(stderr,
"File %s is empty\n", filename);
189 *bytes_read = info.st_size;
209 fprintf(stderr,
"Recycle failed\n");
225 static int import_dma_buf(
228 unsigned long frame_size,
239 uimp.domain = p_session->
domain;
240 uimp.bus = p_session->
bus;
241 uimp.dev = p_session->
dev;
242 uimp.fn = p_session->
fn;
245 uimp.dma_len[0] = frame_size;
251 for (i = 0; i < uimp.nents; i++)
253 dma_addr->ui32DMALen[i] = uimp.dma_len[i];
254 dma_addr->ui64DMAAddr[i] = uimp.dma_addr[i];
256 dma_addr->ui32NumEntries = uimp.nents;
270 static int unimport_dma_buf(
282 uimp.domain = p_session->
domain;
283 uimp.bus = p_session->
bus;
284 uimp.dev = p_session->
dev,
285 uimp.fn = p_session->
fn;
314 int input_video_width,
315 int input_video_height,
316 unsigned long *bytes_sent,
317 int *input_exhausted)
344 frame_size = input_video_width * input_video_height * 4;
350 frame_size = input_video_height * input_video_width * 3 / 2;
358 *input_exhausted = 1;
367 dst_stride, dst_height);
370 "dst height aligned = %d/%d/%d \n",
371 dst_stride[0], dst_stride[1], dst_stride[2],
372 input_video_height, dst_height[0], dst_height[1],
378 total_size = linewidth * input_video_height;
383 if (*pp_data == NULL)
387 fprintf(stderr,
"Can't alloc memory\n");
397 for (row = 0; row < input_video_height; row++)
399 memcpy(pDst, pSrc, linewidth);
407 src_stride[1] = src_stride[2] = src_stride[0] / 2;
409 src_height[0] = input_video_height;
410 src_height[1] = src_height[0] / 2;
411 src_height[2] = src_height[1];
414 p_src[1] = tmp_buf + src_stride[0] * src_height[0];
415 p_src[2] = p_src[1] + src_stride[1] * src_height[1];
417 alignedh = (input_video_height + 1) & ~1;
419 Ysize = dst_stride[0] * alignedh;
420 Usize = dst_stride[1] * alignedh / 2;
421 Vsize = dst_stride[2] * alignedh / 2;
423 total_size = Ysize + Usize + Vsize;
426 if (*pp_data == NULL)
430 fprintf(stderr,
"Can't alloc memory\n");
438 p_dst[1] = *pp_data + Ysize;
439 p_dst[2] = *pp_data + Ysize + Usize;
443 0, 0, dst_stride, dst_height, src_stride, src_height);
446 *bytes_sent = total_size;
468 int input_video_height,
ni_frame_t *gpu_frame)
480 gpu_frame, input_video_width, input_video_height,
483 fprintf(stderr,
"Error: could not allocate hw frame buffer!");
493 fprintf(stderr,
"Error: failed ni_device_session_acquire()\n");
519 int input_video_height,
ni_frame_t *p2p_frame)
530 p2p_frame, input_video_width, input_video_height,
533 fprintf(stderr,
"Error: could not allocate hw frame buffer!\n");
541 fprintf(stderr,
"Error: failed ni_device_session_acquire()\n");
571 static int started = 0;
611 "Error: failed ni_device_session_write() for encoder\n");
652 unsigned long long *total_bytes_received,
661 static int received_stream_header = 0;
681 fprintf(stderr,
"Error: malloc packet failed, ret = %d!\n", rc);
689 if (!received_stream_header)
697 if (fwrite((uint8_t *)p_out_pkt->
p_data + meta_size,
698 p_out_pkt->
data_len - meta_size, 1, p_file) != 1)
700 fprintf(stderr,
"Error: writing data %u bytes error!\n",
702 fprintf(stderr,
"Error: ferror rc = %d\n", ferror(p_file));
705 *total_bytes_received += (rx_size - meta_size);
707 received_stream_header = 1;
710 fprintf(stderr,
"Error: reading header %d\n", rc);
721 printf(
"[R] Got:%d Packets= %u fps=%u Total bytes %llu\n",
723 *total_bytes_received);
742 ni_log2(p_enc_ctx,
NI_LOG_DEBUG,
"encoder_receive_data: received data size=%d\n", rx_size);
744 if (rx_size > meta_size)
746 if (fwrite((uint8_t *)p_out_pkt->
p_data + meta_size,
747 p_out_pkt->
data_len - meta_size, 1, p_file) != 1)
749 fprintf(stderr,
"Error: writing data %u bytes error!\n",
751 fprintf(stderr,
"Error: ferror rc = %d\n", ferror(p_file));
754 *total_bytes_received += rx_size - meta_size;
758 }
else if (rx_size != 0)
760 fprintf(stderr,
"Error: received %d bytes, <= metadata size %d!\n",
763 }
else if (!end_flag &&
778 printf(
"[R] Got:%d Packets= %u fps=%u Total bytes %llu\n", rx_size,
780 *total_bytes_received);
785 printf(
"Encoder Receiving done\n");
787 }
else if (0 == rx_size)
832 p_enc_ctx->
hw_id = iXcoderGUID;
844 fprintf(stderr,
"Error: encoder open session failure\n");
847 printf(
"Encoder device %d session open successful\n", iXcoderGUID);
866 int width,
int height,
int poolsize,
int p2p)
878 p_upl_ctx->
hw_id = *iXcoderGUID;
889 fprintf(stderr,
"Error: uploader_open_session failure!\n");
894 printf(
"Uploader device %d session opened successfully\n",
896 *iXcoderGUID = p_upl_ctx->
hw_id;
903 fprintf(stderr,
"Error: Can't create frame pool\n");
907 printf(
"Uploader device %d configured successfully\n", *iXcoderGUID);
922 printf(
"Video encoder/P2P application directly using Netint "
923 "Libxcoder release v%s\n"
924 "Usage: xcoderp2p_read [options]\n"
927 "--------------------------------------------------------------------------------\n"
928 " -h | --help Show help.\n"
929 " -v | --version Print version info.\n"
930 " -l | --loglevel Set loglevel of libxcoder API.\n"
931 " [none, fatal, error, info, debug, trace]\n"
933 " -c | --card Set card index to use.\n"
934 " See `ni_rsrc_mon` for cards on system.\n"
936 " -g | --gpucard Set gpu card index to use.\n"
937 " See `ni_rsrc_mon` for cards on system.\n"
938 " -i | --input Input file path.\n"
939 " -r | --repeat (Positive integer) to Repeat input X times "
941 " test. (Default: 1)\n"
942 " -s | --size Resolution of input file in format "
944 " (eg. '1920x1080')\n"
945 " -m | --mode Input to output codec processing mode in "
947 " INTYPE2OUTTYPE. [p2a, p2h, r2a, r2h]\n"
948 " Type notation: p=P2P, a=AVC, h=HEVC, r=ABGR\n"
949 " -o | --output Output file path.\n"
950 " -w | --swapchain Set size of swapchain.\n"
951 " (Default: 1) Valid values are 1, 2, or 3.\n",
971 char *output_filename,
int *iXcoderGUID,
int *iGpuGUID,
972 int *arg_width,
int *arg_height,
int *dst_codec_format)
976 char mode_description[128];
983 static const char *opt_string =
"hvl:c:g:i:s:m:o:r:w:";
984 static const struct option long_options[] = {
999 while ((opt =
getopt_long(argc, argv, opt_string, long_options,
1008 printf(
"Release ver: %s\n"
1025 strcpy(xcoderGUID,
optarg);
1026 *iXcoderGUID = (int)strtol(
optarg, &n, 10);
1028 if (n == xcoderGUID)
1033 *iGpuGUID = (int)strtol(
optarg, &n, 10);
1038 strcpy(input_filename,
optarg);
1041 *arg_width = (int)strtol(
optarg, &n, 10);
1042 *arg_height =
atoi(n + 1);
1043 if ((*n !=
'x') || (!*arg_width || !*arg_height))
1047 if (!(strlen(
optarg) == 3))
1051 for (i = 0; i < strlen(
optarg); i++)
1054 if (strcmp(
optarg,
"p2a") != 0 && strcmp(
optarg,
"p2h") != 0 &&
1055 strcmp(
optarg,
"r2a") != 0 && strcmp(
optarg,
"r2h") != 0)
1059 sprintf(mode_description,
"P2P + Encoding");
1066 strcat(mode_description,
" to AVC");
1072 strcat(mode_description,
" to HEVC");
1074 printf(
"%s...\n", mode_description);
1078 strcpy(output_filename,
optarg);
1097 if (!input_filename[0])
1099 printf(
"Error: missing argument for -i | --input\n");
1103 if (!output_filename[0])
1105 printf(
"Error: missing argument for -o | --output\n");
1111 if (*iXcoderGUID == *iGpuGUID)
1113 printf(
"Error: card and gpucard arguments cannot be the same\n");
1119 printf(
"Error: swapchain cannot be more than %d\n",
MAX_SWAP_SIZE);
1128 unsigned long frame_size;
1129 unsigned long long total_bytes_received;
1130 int input_video_width;
1131 int input_video_height;
1132 int iXcoderGUID = 0;
1136 int input_exhausted = 0;
1137 int dst_codec_format = 0;
1141 int need_to_resend = 0;
1142 FILE *p_file = NULL;
1150 int input_file_fd = -1;
1154 parse_arguments(argc, argv, input_filename, output_filename, &iXcoderGUID,
1155 &iGpuGUID, &arg_width, &arg_height, &dst_codec_format);
1166 if (strcmp(output_filename,
"null") != 0)
1168 p_file = fopen(output_filename,
"wb");
1171 fprintf(stderr,
"Error: cannot open %s\n", output_filename);
1176 printf(
"SUCCESS: Opened output file: %s\n", output_filename);
1180 fprintf(stderr,
"Error: init encoder context error\n");
1186 fprintf(stderr,
"Error: init uploader context error\n");
1192 fprintf(stderr,
"Error: init gpu uploader context error\n");
1196 total_bytes_received = 0;
1202 printf(
"User video resolution: %dx%d\n", arg_width, arg_height);
1204 if (arg_width == 0 || arg_height == 0)
1206 input_video_width = 1280;
1207 input_video_height = 720;
1211 input_video_width = arg_width;
1212 input_video_height = arg_height;
1220 printf(
"P2P Encoding resolution: %dx%d\n", input_video_width,
1221 input_video_height);
1250 input_file_fd = open(input_filename, O_RDONLY | O_BINARY);
1252 input_file_fd = open(input_filename, O_RDONLY);
1255 if (input_file_fd < 0)
1257 fprintf(stderr,
"Error: cannot open input file %s\n", input_filename);
1263 &swapchain.
gpu_frame[0], input_video_width,
1264 input_video_height, &frame_size, &input_exhausted))
1266 fprintf(stderr,
"Cannot render frame on source Quadra device\n");
1272 ret = import_dma_buf(&upl_ctx, &swapchain.
gpu_frame[i], frame_size,
1277 fprintf(stderr,
"Cannot import dma buffer %d\n",ret);
1295 fprintf(stderr,
"Error: encoder init default set up error\n");
1304 fprintf(stderr,
"Error: can't set low delay mode %d\n", ret);
1313 fprintf(stderr,
"Error: can't set gop preset %d\n", ret);
1323 fprintf(stderr,
"Error: can't set video full range\n");
1331 fprintf(stderr,
"Error: can't set color primaries\n");
1339 fprintf(stderr,
"Error: can't set color space\n");
1347 fprintf(stderr,
"Error: can't set color transfer characteristics\n");
1354 &api_param, arg_width, arg_height, &p2p_frame);
1358 fprintf(stderr,
"Could not open encoder session\n");
1372 fprintf(stderr,
"Error: can't read frame\n");
1378 input_exhausted, &need_to_resend);
1387 if (!input_exhausted && need_to_resend == 0)
1393 input_video_width, input_video_height,
1394 &frame_size, &input_exhausted);
1399 &enc_ctx, &out_packet, p_file, &total_bytes_received, print_time);
1414 timeDiff = (timeDiff > 0) ? timeDiff : 1;
1416 printf(
"[R] Got: Packets= %u fps=%u Total bytes %llu\n",
1418 total_bytes_received);
1426 unimport_dma_buf(&upl_ctx, &swapchain.
gpu_frame[swap_index]);
1464 close(input_file_fd);
1471 printf(
"All done\n");
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.
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.
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.
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...
int recycle_frame(ni_frame_t *p2p_frame)
Recycle hw frame back to Quadra.
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
unsigned long dma_addr[NI_DMABUF_MAX_SGL_ENTRY]
int gpu_prepare_frame(ni_session_context_t *p_gpu_ctx, int input_video_width, int input_video_height, ni_frame_t *gpu_frame)
Prepare frame on the proxy GPU Quadra device.
#define NI_INVALID_SESSION_ID
void print_usage(void)
Print usage information.
struct timeval current_time
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
ni_frame_t gpu_frame[MAX_SWAP_SIZE]
#define required_argument
#define NI_XCODER_REVISION
int gpu_render_frame(ni_session_context_t *p_ctx, int fd, uint8_t **pp_data, ni_frame_t *p_in_frame, int input_video_width, int input_video_height, unsigned long *bytes_sent, int *input_exhausted)
Reads video data from input file then calls a special libxcoder API function to transfer the video da...
ni_retcode_t ni_packet_buffer_free(ni_packet_t *p_packet)
Free packet buffer that was previously allocated with ni_packet_buffer_alloc.
ni_device_handle_t blk_io_handle
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....
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.
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.
struct timeval previous_time
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.
ni_log_level_t arg_to_ni_log_level(const char *arg_str)
Convert terminal arg string to ni_log_level_t.
#define NETINT_IOCTL_IMPORT_DMABUF
time_t previous_timestamp
#define NI_VPU_ALIGN16(_x)
int uploader_open_session(ni_session_context_t *p_upl_ctx, int *iXcoderGUID, int width, int height, int poolsize, int p2p)
Open an upload session to Quadra.
uint32_t data_len[NI_MAX_NUM_DATA_POINTERS]
unsigned int extra_data_len
Definitions related to NETINT P2P kernel driver interface.
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.
ni_device_handle_t device_handle
#define NI_SW_RELEASE_TIME
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
ni_retcode_t ni_hwframe_p2p_buffer_recycle(ni_frame_t *p_frame)
Recycle hw P2P frames.
int getopt_long(int argc, char *argv[], const char *optstring, const struct option *longopts, int *longindex)
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.
unsigned long total_file_size
void ni_device_session_context_clear(ni_session_context_t *p_ctx)
Clear already allocated session context.
void ni_get_frame_dim(int width, int height, ni_pix_fmt_t pix_fmt, int plane_stride[NI_MAX_NUM_DATA_POINTERS], int plane_height[NI_MAX_NUM_DATA_POINTERS])
Get dimension information of frame to be sent to encoder for encoding. Caller usually retrieves this ...
void arg_error_exit(char *arg_name, char *param)
Exit on argument error.
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.
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
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 ...
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...
#define NI_MAX_NUM_DATA_POINTERS
union _ni_session_data_io::@19 data
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...
#define NI_VPU_ALIGN4096(_x)
uint32_t number_of_frames
int ni_posix_memalign(void **memptr, size_t alignment, size_t size)
Allocate aligned memory.
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,
int main(int argc, char *argv[])
void parse_arguments(int argc, char *argv[], char *input_filename, char *output_filename, int *iXcoderGUID, int *iGpuGUID, int *arg_width, int *arg_height, int *dst_codec_format)
Parse user command line arguments.
uint8_t * g_curr_cache_pos
int ni_device_session_acquire_for_read(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
Acquire a P2P frame buffer from the hwupload session for P2P read.
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.
#define LIBXCODER_API_VERSION
ni_retcode_t ni_p2p_recv(ni_session_context_t *pSession, const ni_p2p_sgl_t *dmaAddrs, ni_frame_t *pDstFrame)
Initiate a P2P transfer (P2P read)
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...
int32_t ni_gettimeofday(struct timeval *p_tp, void *p_tzp)
Get time for logs with microsecond timestamps.
Public definitions for operating NETINT video processing devices for video processing.
uint32_t meta_size
Params used in VFR mode Done///.
int read_next_chunk_from_file(int fd, uint8_t *p_dst, uint32_t to_read)
Read the next frame.
int get_file_size(const char *filename, unsigned long *bytes_read)
Get file size.
uint32_t number_of_packets
ni_retcode_t ni_uploader_p2p_test_load(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 video data from the software frame to the hardware P2P frame on...
#define NI_FRAME_LITTLE_ENDIAN
ni_retcode_t ni_device_session_context_init(ni_session_context_t *p_ctx)
Initialize already allocated session context to a known state.
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.
int enc_prepare_frame(ni_session_context_t *p_upl_ctx, int input_video_width, int input_video_height, ni_frame_t *p2p_frame)
Prepare frame on the encoding Quadra device.
ni_retcode_t ni_device_session_close(ni_session_context_t *p_ctx, int eos_recieved, ni_device_type_t device_type)
Close device session that was previously opened by calling ni_device_session_open() If device_type is...
ni_frame_t * p_first_frame
struct timeval start_time