libxcoder 5.6.0
Loading...
Searching...
No Matches
ni_device_api.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_device_api.c
24 *
25 * \brief Public definitions for operating NETINT video processing devices for
26 * video processing
27 ******************************************************************************/
28
29#if __linux__ || __APPLE__
30#define _GNU_SOURCE //O_DIRECT is Linux-specific. One must define _GNU_SOURCE to obtain its definitions
31#if __linux__
32#include <linux/types.h>
33#endif
34#include <unistd.h>
35#include <sys/ioctl.h>
36#include <sys/mman.h>
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <sys/time.h>
40#include <fcntl.h>
41#include <errno.h>
42#include <semaphore.h>
43#include <limits.h>
44#include <unistd.h>
45#include <signal.h>
46#include <poll.h>
47#endif
48
49#include <stdint.h>
50#include <string.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <stdint.h>
54#include <sys/stat.h>
55#include "inttypes.h"
56#include "ni_device_api.h"
57#include "ni_device_api_priv.h"
58#include "ni_nvme.h"
59#include "ni_util.h"
60#include "ni_rsrc_api.h"
61#include "ni_rsrc_priv.h"
62#include "ni_lat_meas.h"
63#ifdef _WIN32
64#include <shlobj.h>
65#else
66#include "ni_p2p_ioctl.h"
67#endif
68
85#if __linux__ || __APPLE__
86static struct stat g_nvme_stat = { 0 };
87
88static int close_fd_zero_atexit = 0;
89
90static void close_fd_zero(void)
91{
92 close(0);
93}
94
95#endif
96
97/*!*****************************************************************************
98 * \brief Allocate and initialize a new ni_session_context_t struct
99 *
100 *
101 * \return On success returns a valid pointer to newly allocated context
102 * On failure returns NULL
103 ******************************************************************************/
105{
106 ni_session_context_t *p_ctx = NULL;
107
108 p_ctx = malloc(sizeof(ni_session_context_t));
109 if (!p_ctx)
110 {
112 "ERROR: %s() Failed to allocate memory for session context\n",
113 __func__);
114 } else
115 {
116 memset(p_ctx, 0, sizeof(ni_session_context_t));
117
119 {
120 ni_log(NI_LOG_ERROR, "ERROR: %s() Failed to init session context\n",
121 __func__);
123 return NULL;
124 }
125 }
126 return p_ctx;
127}
128
129/*!*****************************************************************************
130 * \brief Free previously allocated session context
131 *
132 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
133 * struct
134 *
135 ******************************************************************************/
137{
138 if (p_ctx)
139 {
141#ifdef MEASURE_LATENCY
142 if (p_ctx->frame_time_q)
143 {
145 }
146#endif
147 free(p_ctx);
148 }
149}
150
151/*!*****************************************************************************
152 * \brief Initialize already allocated session context to a known state
153 *
154 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
155 * struct
156 * \return On success
157 * NI_RETCODE_SUCCESS
158 * On failure
159 * NI_RETCODE_INVALID_PARAM
160 * NI_RETCODE_FAILURE
161 ******************************************************************************/
163{
164 int bitrate = 0;
165 int framerate_num = 0;
166 int framerate_denom = 0;
167
168 if (!p_ctx)
169 {
171 }
172
174 {
175 // session context will reset so save the last values for sequence change
176 if (p_ctx->last_bitrate < NI_MIN_BITRATE)
177 bitrate = NI_MIN_BITRATE;
178 else if (p_ctx->last_bitrate > NI_MAX_BITRATE)
179 bitrate = NI_MAX_BITRATE;
180 else
181 bitrate = p_ctx->last_bitrate;
182 framerate_num = p_ctx->last_framerate.framerate_num;
183 framerate_denom = p_ctx->last_framerate.framerate_denom;
184 }
185
186 memset(p_ctx, 0, sizeof(ni_session_context_t));
187
188 p_ctx->last_bitrate = bitrate;
189 p_ctx->last_framerate.framerate_num = framerate_num;
190 p_ctx->last_framerate.framerate_denom = framerate_denom;
191
192 // Xcoder thread mutex init
193 if (ni_pthread_mutex_init(&p_ctx->mutex))
194 {
195 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): init xcoder_mutex fail, return\n",
196 __func__);
197 return NI_RETCODE_FAILURE;
198 }
199 p_ctx->pext_mutex = &p_ctx->mutex; //used exclusively for hwdl
200
201 // low delay send/recv sync init
203 {
204 ni_log2(p_ctx, NI_LOG_ERROR,
205 "ERROR %s(): init xcoder_low_delay_sync_mutex fail return\n",
206 __func__);
207 return NI_RETCODE_FAILURE;
208 }
209 if (ni_pthread_cond_init(&p_ctx->low_delay_sync_cond, NULL))
210 {
211 ni_log2(p_ctx, NI_LOG_ERROR,
212 "ERROR %s(): init xcoder_low_delay_sync_cond fail return\n",
213 __func__);
214 return NI_RETCODE_FAILURE;
215 }
216
217 p_ctx->mutex_initialized = true;
218
219 // Init the max IO size to be invalid
223 p_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
224 p_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
225 p_ctx->hw_id = NI_INVALID_HWID;
226 p_ctx->event_handle = NI_INVALID_EVENT_HANDLE;
227 p_ctx->thread_event_handle = NI_INVALID_EVENT_HANDLE;
229 p_ctx->keep_alive_thread = (ni_pthread_t){0};
231 p_ctx->decoder_low_delay = 0;
232 p_ctx->enable_low_delay_check = 0;
233 p_ctx->low_delay_sync_flag = 0;
234 p_ctx->async_mode = 0;
236 p_ctx->buffered_frame_index = 0;
237 p_ctx->ppu_reconfig_pkt_pos = 0;
238 p_ctx->headers_length = 0;
239 // by default, select the least model load card
242#ifdef MY_SAVE
243 p_ctx->debug_write_ptr = NULL;
244 p_ctx->debug_write_index_ptr = NULL;
245 p_ctx->debug_write_sent_size = 0;
246#endif
247
248#ifdef MEASURE_LATENCY
249 p_ctx->frame_time_q = (void *)ni_lat_meas_q_create(2000);
250#endif
251
252 return NI_RETCODE_SUCCESS;
253}
254
255/*!*****************************************************************************
256 * \brief Clear already allocated session context
257 *
258 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
259 *
260 *
261 ******************************************************************************/
272
273/*!*****************************************************************************
274 * \brief Create event and return event handle if successful (Windows only)
275 *
276 * \return On success returns a event handle
277 * On failure returns NI_INVALID_EVENT_HANDLE
278 ******************************************************************************/
279ni_event_handle_t ni_create_event(void)
280{
281#ifdef _WIN32
282 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
283
284 // Input-0 determines whether the returned handle can be inherited by the child process.If lpEventAttributes is NULL, this handle cannot be inherited.
285 // Input-1 specifies whether the event object is created to be restored manually or automatically.If set to FALSE, when a thread waits for an event signal, the system automatically restores the event state to a non-signaled state.
286 // Input-2 specifies the initial state of the event object.If TRUE, the initial state is signaled;Otherwise, no signal state.
287 // Input-3 If the lpName is NULL, a nameless event object is created.。
288 event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
289 if (event_handle == NULL)
290 {
291 ni_log(NI_LOG_ERROR, "ERROR %d: %s() create event failed\n",
292 NI_ERRNO, __func__);
293 return NI_INVALID_EVENT_HANDLE;
294 }
295 return event_handle;
296#else
297 return NI_INVALID_EVENT_HANDLE;
298#endif
299}
300
301/*!*****************************************************************************
302 * \brief Close event and release resources (Windows only)
303 *
304 * \return NONE
305 *
306 ******************************************************************************/
307void ni_close_event(ni_event_handle_t event_handle)
308{
309 if ( NI_INVALID_DEVICE_HANDLE == event_handle )
310 {
311 ni_log(NI_LOG_DEBUG, "Warning %s: null parameter passed %x\n", __func__,
312 event_handle);
313 return;
314 }
315
316 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
317
318#ifdef _WIN32
319 BOOL retval;
320 ni_log(NI_LOG_DEBUG, "%s(): closing %p\n", __func__, event_handle);
321
322 retval = CloseHandle(event_handle);
323 if (FALSE == retval)
324 {
325 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): closing event_handle %p failed\n",
326 NI_ERRNO, __func__, event_handle);
327 }
328 else
329 {
330 ni_log(NI_LOG_DEBUG, "%s(): device %p closed successfuly\n", __func__,
331 event_handle);
332 }
333#else
334 int err = 0;
335 ni_log(NI_LOG_DEBUG, "%s(): closing %d\n", __func__, event_handle);
336 err = close(event_handle);
337 if (err)
338 {
339 char error_message[100] = {'\0'};
340 char unknown_error_message[20] = {'\0'};
341 ni_sprintf(error_message, 100, "ERROR: %s(): ", __func__);
342 switch (err)
343 {
344 case EBADF:
345 ni_strcat(error_message, 100, "EBADF\n");
346 break;
347 case EINTR:
348 ni_strcat(error_message, 100, "EINTR\n");
349 break;
350 case EIO:
351 ni_strcat(error_message, 100, "EIO\n");
352 break;
353 default:
354 ni_sprintf(unknown_error_message, 20, "Unknown error %d\n", err);
355 ni_strcat(error_message, 100, unknown_error_message);
356 }
357 ni_log(NI_LOG_ERROR, "%s\n", error_message);
358 }
359#endif
360 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
361}
362
363#ifndef DEPRECATION_AS_ERROR
364/*!*****************************************************************************
365 * \brief Open device and return device device_handle if successful
366 *
367 * \param[in] p_dev Device name represented as c string. ex: "/dev/nvme0"
368 * \param[out] p_max_io_size_out Maximum IO Transfer size supported, could be
369 * NULL
370 *
371 * \return On success returns a device device_handle
372 * On failure returns NI_INVALID_DEVICE_HANDLE
373 ******************************************************************************/
374NI_DEPRECATED ni_device_handle_t ni_device_open(const char * p_dev, uint32_t * p_max_io_size_out)
375{
376#ifdef _WIN32
377 DWORD retval;
378 HANDLE device_handle;
379
380 if (!p_dev)
381 {
382 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
383 return NI_INVALID_DEVICE_HANDLE;
384 }
385
386 if (p_max_io_size_out != NULL && *p_max_io_size_out == NI_INVALID_IO_SIZE)
387 {
388 // For now, we just use it to allocate p_leftover buffer
389 // NI_MAX_PACKET_SZ is big enough
390 *p_max_io_size_out = NI_MAX_PACKET_SZ;
391 }
392
393 device_handle = CreateFile(p_dev, GENERIC_READ | GENERIC_WRITE,
394 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
395 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
396
397 ni_log(NI_LOG_DEBUG, "%s() device_name: %s", __func__, p_dev);
398 if (INVALID_HANDLE_VALUE == device_handle)
399 {
400 retval = GetLastError();
401 ni_log(NI_LOG_ERROR, "Failed to open %s, retval %d \n", p_dev, retval);
402 } else
403 {
404 ni_log(NI_LOG_DEBUG, "Found NVME Controller at %s \n", p_dev);
405 }
406
407 return device_handle;
408#else
409 int retval = -1;
410 ni_device_handle_t fd = NI_INVALID_DEVICE_HANDLE;
411
412 if (!p_dev)
413 {
414 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
416 }
417
418 if (p_max_io_size_out != NULL && *p_max_io_size_out == NI_INVALID_IO_SIZE)
419 {
420#if __linux__
421 *p_max_io_size_out = ni_get_kernel_max_io_size(p_dev);
422#elif __APPLE__
423 *p_max_io_size_out = MAX_IO_TRANSFER_SIZE;
424#endif
425 }
426
427 ni_log(NI_LOG_DEBUG, "%s: opening regular-io enabled %s\n", __func__,
428 p_dev);
429 //O_SYNC is added to ensure that data is written to the card when the pread/pwrite function returns
430 #if __linux__
431 //O_DIRECT is added to ensure that data can be sent directly to the card instead of to cache memory
432 fd = open(p_dev, O_RDWR | O_SYNC | O_DIRECT);
433 #elif __APPLE__
434 //O_DIRECT isn't available, so instead we use F_NOCACHE below
435 fd = open(p_dev, O_RDWR | O_SYNC);
436 #endif
437
438 if (fd < 0)
439 {
440 char errmsg[NI_ERRNO_LEN] = {0};
442 ni_log(NI_LOG_ERROR, "ERROR: %d %s open() failed on %s\n", NI_ERRNO,
443 errmsg, p_dev);
444 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
445 fd = NI_INVALID_DEVICE_HANDLE;
446 LRETURN;
447 }
448 else if(fd == 0)
449 {
450 //this code is just for the case that we do not initialize all fds to NI_INVALID_DEVICE_HANDLE
451
452 //if we make sure that all the fds in libxcoder is initialized to NI_INVALID_DEVICE_HANDLE
453 //we should remove this check
454
455 //we hold the fd = 0, so other threads could not visit these code
456 //thread safe unless other thread close fd=0 accidently
457 ni_log(NI_LOG_ERROR, "open fd = 0 is not as expeceted\n");
458 if(close_fd_zero_atexit == 0)
459 {
460 close_fd_zero_atexit = 1;
461 atexit(close_fd_zero);
462 }
463 else
464 {
465 ni_log(NI_LOG_ERROR, "libxcoder has held the fd=0, but open fd=0 again, maybe fd=0 was closed accidently.");
466 }
467 fd = NI_INVALID_DEVICE_HANDLE;
468 }
469
470 #if __APPLE__
471 //F_NOCACHE is set to ensure that data can be sent directly to the card instead of to cache memory
472 retval = fcntl(fd, F_NOCACHE, 1);
473 if (retval < 0)
474 {
475 ni_log(NI_LOG_ERROR, "ERROR: fnctl() failed on %s\n", p_dev);
476 ni_log(NI_LOG_ERROR, "ERROR: ni_device_open() failed!\n");
477 close(fd);
478 fd = NI_INVALID_DEVICE_HANDLE;
479 LRETURN;
480 }
481 #endif
482
483 retval = fstat(fd, &g_nvme_stat);
484 if (retval < 0)
485 {
486 ni_log(NI_LOG_ERROR, "ERROR: fstat() failed on %s\n", p_dev);
487 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
488 close(fd);
489 fd = NI_INVALID_DEVICE_HANDLE;
490 LRETURN;
491 }
492
493 if (!S_ISCHR(g_nvme_stat.st_mode) && !S_ISBLK(g_nvme_stat.st_mode))
494 {
495 ni_log(NI_LOG_ERROR, "ERROR: %s is not a block or character device\n",
496 p_dev);
497 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
498 close(fd);
499 fd = NI_INVALID_DEVICE_HANDLE;
500 LRETURN;
501 }
502
503 ni_log(NI_LOG_DEBUG, "%s: success, fd=%d\n", __func__, fd);
504
505END:
506
507 return fd;
508#endif
509}
510#endif
511
512/*!*****************************************************************************
513 * \brief Open device and return device device_handle if successful
514 *
515 * \param[in] p_dev Device name represented as c string. ex: "/dev/nvme0"
516 * \param[in] p_config Device configuration parameters
517 *
518 * \return On success returns a device device_handle
519 * On failure returns NI_INVALID_DEVICE_HANDLE
520 ******************************************************************************/
521ni_device_handle_t ni_device_open2(const char * p_dev, ni_device_mode_t mode)
522{
523#ifdef _WIN32
524 DWORD retval;
525 HANDLE device_handle;
526 DWORD dwDesiredAccess = 0;
527
528 if (!p_dev)
529 {
530 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
531 return NI_INVALID_DEVICE_HANDLE;
532 }
533
534 /* Convert access mode using bit operations */
535 switch(mode & NI_DEVICE_READ_WRITE)
536 {
538 /* Read-only mode */
539 dwDesiredAccess = GENERIC_READ;
540 break;
542 /* Write-only mode */
543 dwDesiredAccess = GENERIC_WRITE;
544 break;
546 default:
547 /* Read-write mode takes precedence */
548 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
549 break;
550 }
551
552 device_handle = CreateFile(p_dev, dwDesiredAccess,
553 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
554 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
555
556 ni_log(NI_LOG_DEBUG, "%s() device_name: %s", __func__, p_dev);
557 if (INVALID_HANDLE_VALUE == device_handle)
558 {
559 retval = GetLastError();
560 ni_log(NI_LOG_ERROR, "Failed to open %s, retval %d \n", p_dev, retval);
561 } else
562 {
563 ni_log(NI_LOG_DEBUG, "Found NVME Controller at %s \n", p_dev);
564 }
565
566 return device_handle;
567#else
568 int retval = -1;
569 ni_device_handle_t fd = NI_INVALID_DEVICE_HANDLE;
570 int open_flags = 0;
571
572 if (!p_dev)
573 {
574 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
576 }
577
578 ni_log(NI_LOG_DEBUG, "%s: opening regular-io enabled %s\n", __func__,
579 p_dev);
580
581 /* Set access mode using bit operations */
582 switch(mode & NI_DEVICE_READ_WRITE)
583 {
585 /* Read-only mode */
586 open_flags = O_RDONLY;
587 break;
589 /* Write-only mode */
590 open_flags = O_WRONLY;
591 break;
593 default:
594 /* Read-write mode takes precedence */
595 open_flags = O_RDWR;
596 break;
597 }
598
599 open_flags |= O_SYNC;
600#if __linux__
601 open_flags |= O_DIRECT;
602#elif __APPLE__
603 /* macOS doesn't support O_DIRECT, use F_NOCACHE instead */
604#endif
605
606 fd = open(p_dev, open_flags);
607 if (fd < 0)
608 {
609 ni_log(NI_LOG_ERROR, "ERROR: %d %s open() failed on %s\n", NI_ERRNO,
610 strerror(NI_ERRNO), p_dev);
611 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
612 fd = NI_INVALID_DEVICE_HANDLE;
613 LRETURN;
614 }
615
616#if __APPLE__
617 //F_NOCACHE is set to ensure that data can be sent directly to the card instead of to cache memory
618 retval = fcntl(fd, F_NOCACHE, 1);
619 if (retval < 0)
620 {
621 ni_log(NI_LOG_ERROR, "ERROR: fnctl() failed on %s\n", p_dev);
622 ni_log(NI_LOG_ERROR, "ERROR: ni_device_open2() failed!\n");
623 close(fd);
624 fd = NI_INVALID_DEVICE_HANDLE;
625 LRETURN;
626 }
627#endif
628
629 retval = fstat(fd, &g_nvme_stat);
630 if (retval < 0)
631 {
632 ni_log(NI_LOG_ERROR, "ERROR: fstat() failed on %s\n", p_dev);
633 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
634 close(fd);
635 fd = NI_INVALID_DEVICE_HANDLE;
636 LRETURN;
637 }
638
639 if (!S_ISCHR(g_nvme_stat.st_mode) && !S_ISBLK(g_nvme_stat.st_mode))
640 {
641 ni_log(NI_LOG_ERROR, "ERROR: %s is not a block or character device\n",
642 p_dev);
643 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
644 close(fd);
645 fd = NI_INVALID_DEVICE_HANDLE;
646 LRETURN;
647 }
648
649 ni_log(NI_LOG_DEBUG, "%s: success, fd=%d\n", __func__, fd);
650
651END:
652
653 return fd;
654#endif
655}
656
657/*!*****************************************************************************
658 * \brief Close device and release resources
659 *
660 * \param[in] device_handle Device handle obtained by calling ni_device_open()
661 *
662 * \return NONE
663 *
664 ******************************************************************************/
665void ni_device_close(ni_device_handle_t device_handle)
666{
667 if ( NI_INVALID_DEVICE_HANDLE == device_handle )
668 {
669 ni_log(NI_LOG_ERROR, "ERROR %s: null parameter passed %x\n", __func__,
670 device_handle);
671 return;
672 }
673
674 if(device_handle == 0)
675 {
676 //this code is just for the case that we do not initialize all fds to NI_INVALID_DEVICE_HANDLE
677
678 //if we make sure that all the fds in libxcoder is initialized to NI_INVALID_DEVICE_HANDLE
679 //we should remove this check
680 ni_log(NI_LOG_ERROR, "%s close fd=0 is not as expected", __func__);
681 return;
682 }
683
684 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
685
686#ifdef _WIN32
687 BOOL retval;
688
689 ni_log(NI_LOG_DEBUG, "%s(): closing %p\n", __func__, device_handle);
690
691 retval = CloseHandle(device_handle);
692 if (FALSE == retval)
693 {
695 "ERROR: %s(): closing device device_handle %p failed, error: %d\n",
696 __func__, device_handle, NI_ERRNO);
697 }
698 else
699 {
700 ni_log(NI_LOG_DEBUG, "%s(): device %p closed successfuly\n", __func__,
701 device_handle);
702 }
703#else
704 int err = 0;
705 ni_log(NI_LOG_DEBUG, "%s(): closing fd %d\n", __func__, device_handle);
706 err = close(device_handle);
707 if (err == -1)
708 {
709 char error_message[100] = {'\0'};
710 char unknown_error_message[20] = {'\0'};
711 ni_sprintf(error_message, 100, "ERROR: %s(): ", __func__);
712 switch (errno)
713 {
714 case EBADF:
715 ni_strcat(error_message, 100, "EBADF\n");
716 break;
717 case EINTR:
718 ni_strcat(error_message, 100, "EINTR\n");
719 break;
720 case EIO:
721 ni_strcat(error_message, 100, "EIO\n");
722 break;
723 default:
724 ni_sprintf(unknown_error_message, 20, "Unknown error %d\n", err);
725 ni_strcat(error_message, 100, unknown_error_message);
726 }
727 char errmsg[NI_ERRNO_LEN] = {0};
729 ni_log(NI_LOG_ERROR, "%s\n", errmsg);
730 ni_log(NI_LOG_ERROR, "%s\n", error_message);
731 }
732#endif
733 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
734}
735
736#ifndef DEPRECATION_AS_ERROR
737/*!*****************************************************************************
738 * \brief Query device and return device capability structure
739 * This function had been replaced by ni_device_capability_query2
740 * This function can't be callback in multi thread
741 *
742 * \param[in] device_handle Device handle obtained by calling ni_device_open
743 * \param[in] p_cap Pointer to a caller allocated ni_device_capability_t
744 * struct
745 * \return On success
746 * NI_RETCODE_SUCCESS
747 * On failure
748 * NI_RETCODE_INVALID_PARAM
749 * NI_RETCODE_ERROR_MEM_ALOC
750 * NI_RETCODE_ERROR_NVME_CMD_FAILED
751 ******************************************************************************/
753{
754 void * p_buffer = NULL;
756 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
757
758 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
759
760 if ( (NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_cap) )
761 {
762 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
763 __func__);
765 LRETURN;
766 }
767
768 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
770 {
771 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
772 NI_ERRNO, __func__);
774 LRETURN;
775 }
776
777 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
778
779 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
780 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer, NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
781 {
783 LRETURN;
784 }
785
787
788END:
789
790 ni_aligned_free(p_buffer);
791 ni_log(NI_LOG_DEBUG, "%s(): retval: %d\n", __func__, retval);
792
793 return retval;
794}
795#endif
796
797/*!*****************************************************************************
798 * \brief Query device and return device capability structure
799 * This function had replaced ni_device_capability_query
800 * This function can be callback with multi thread
801 *
802 * \param[in] device_handle Device handle obtained by calling ni_device_open
803 * \param[in] p_cap Pointer to a caller allocated ni_device_capability_t
804 * struct
805 * \param[in] device_in_ctxt If device is in ctx
806 * \return On success
807 * NI_RETCODE_SUCCESS
808 * On failure
809 * NI_RETCODE_INVALID_PARAM
810 * NI_RETCODE_ERROR_MEM_ALOC
811 * NI_RETCODE_ERROR_NVME_CMD_FAILED
812 ******************************************************************************/
813ni_retcode_t ni_device_capability_query2(ni_device_handle_t device_handle,
814 ni_device_capability_t *p_cap, bool device_in_ctxt)
815{
816 void * p_buffer = NULL;
818 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
819
820 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
821
822 if ( (NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_cap) )
823 {
824 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
825 __func__);
827 LRETURN;
828 }
829
830 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
832 {
833 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
834 NI_ERRNO, __func__);
836 LRETURN;
837 }
838
839 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
840
841 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
842 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer, NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
843 {
845 LRETURN;
846 }
847
848 ni_populate_device_capability_struct(p_cap, p_buffer, device_handle, device_in_ctxt);
849
850END:
851
852 ni_aligned_free(p_buffer);
853 ni_log(NI_LOG_DEBUG, "%s(): retval: %d\n", __func__, retval);
854
855 return retval;
856}
857
858/*!*****************************************************************************
859 * \brief Open a new device session depending on the device_type parameter
860 * If device_type is NI_DEVICE_TYPE_DECODER opens decoding session
861 * If device_type is NI_DEVICE_TYPE_ENCODER opens encoding session
862 * If device_type is NI_DEVICE_TYPE_SCALER opens scaling session
863 *
864 * \param[in] p_ctx Pointer to a caller allocated
865 * ni_session_context_t struct
866 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER,
867 * or NI_DEVICE_TYPE_SCALER
868 * \return On success
869 * NI_RETCODE_SUCCESS
870 * On failure
871 * NI_RETCODE_INVALID_PARAM
872 * NI_RETCODE_ERROR_MEM_ALOC
873 * NI_RETCODE_ERROR_NVME_CMD_FAILED
874 * NI_RETCODE_ERROR_INVALID_SESSION
875 ******************************************************************************/
877 ni_device_type_t device_type)
878{
880 ni_device_pool_t *p_device_pool = NULL;
881 ni_device_context_t *p_device_context = NULL;
882 ni_device_info_t *p_dev_info = NULL;
883 ni_device_info_t dev_info = { 0 };
885 ni_device_context_t *rsrc_ctx = NULL;
886 int i = 0;
887 int rc = 0;
888 int num_coders = 0;
889 bool use_model_load = true;
890 int least_load = 0;
891 int curr_load = 0;
892 int guid = -1;
893 uint32_t num_sw_instances = 0;
894 uint32_t pixel_load = 0xFFFFFFFFU;
895 int user_handles = false;
896 ni_lock_handle_t lock = NI_INVALID_LOCK_HANDLE;
897 ni_device_handle_t handle = NI_INVALID_DEVICE_HANDLE;
898 ni_device_handle_t handle1 = NI_INVALID_DEVICE_HANDLE;
899 // For none nvme block device we just need to pass in dummy
900 ni_session_context_t p_session_context = {0};
901 ni_device_type_t query_type = device_type;
902
903 if (!p_ctx)
904 {
905 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
906 __func__);
908 }
909
910#ifdef _WIN32
911 if (!IsUserAnAdmin())
912 {
913 ni_log(NI_LOG_ERROR, "ERROR: %s must be in admin priviledge\n", __func__);
915 }
916#endif
917
920
921 ni_device_session_context_init(&p_session_context);
922
923 if (NI_INVALID_SESSION_ID != p_ctx->session_id)
924 {
925 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: trying to overwrite existing session, "
926 "device_type %d, session id %d\n",
927 device_type, p_ctx->session_id);
929 LRETURN;
930 }
931
932 p_ctx->p_hdr_buf = NULL;
933 p_ctx->hdr_buf_size = 0;
934
935 p_ctx->roi_side_data_size = p_ctx->nb_rois = 0;
936 p_ctx->av_rois = NULL;
937 p_ctx->roi_map = NULL;
938 p_ctx->avc_roi_map = NULL;
939 p_ctx->hevc_roi_map = NULL;
940 p_ctx->hevc_sub_ctu_roi_buf = NULL;
941 p_ctx->p_master_display_meta_data = NULL;
942
943 p_ctx->enc_change_params = NULL;
944
945 p_ctx->target_bitrate = -1;
946 p_ctx->force_idr_frame = 0;
948 p_ctx->ltr_to_set.use_long_term_ref = 0;
949 p_ctx->ltr_interval = -1;
950 p_ctx->ltr_frame_ref_invalid = -1;
951 p_ctx->framerate.framerate_num = 0;
952 p_ctx->framerate.framerate_denom = 0;
953 p_ctx->vui.colorDescPresent = 0;
954 p_ctx->vui.colorPrimaries = 2; // 2 is unspecified
955 p_ctx->vui.colorTrc = 2; // 2 is unspecified
956 p_ctx->vui.colorSpace = 2; // 2 is unspecified
957 p_ctx->vui.aspectRatioWidth = 0;
958 p_ctx->vui.aspectRatioHeight = 0;
959 p_ctx->vui.videoFullRange = 0;
960 p_ctx->max_frame_size = 0;
961 p_ctx->reconfig_crf = -1;
962 p_ctx->reconfig_crf_decimal = 0;
963 p_ctx->reconfig_vbv_buffer_size = 0;
964 p_ctx->reconfig_vbv_max_rate = 0;
965 p_ctx->last_gop_size = 0;
966 p_ctx->initial_frame_delay = 0;
967 p_ctx->current_frame_delay = 0;
968 p_ctx->max_frame_delay = 0;
969 p_ctx->av1_pkt_num = 0;
971 p_ctx->force_low_delay = false;
972 p_ctx->force_low_delay_cnt = 0;
973 p_ctx->pkt_delay_cnt = 0;
974 p_ctx->reconfig_intra_period = -1;
975 p_ctx->reconfig_slice_arg = 0;
976
977 memset(p_ctx->input_frame_fifo, 0, sizeof(ni_input_frame) * 120);
978 for (i = 0; i < 120; i++)
979 {
980 p_ctx->input_frame_fifo[i].usable = -1;
981 }
982
983 handle = p_ctx->device_handle;
984 handle1 = p_ctx->blk_io_handle;
985
986 ni_log2(p_ctx, NI_LOG_DEBUG,
987 "%s: device type %d hw_id %d blk_dev_name: %s dev_xcoder_name: %s.\n",
988 __func__, device_type, p_ctx->hw_id, p_ctx->blk_dev_name,
989 p_ctx->dev_xcoder_name);
990
991 if (device_type == NI_DEVICE_TYPE_UPLOAD)
992 {
993 //uploader shares resources with encoder to query as encoder for load info
994 query_type = NI_DEVICE_TYPE_ENCODER;
995 }
996
997 // if caller requested device by block device name, try to find its GUID and
998 // use it to override the hw_id which is the passed in device GUID
999 if (0 != strcmp(p_ctx->blk_dev_name, ""))
1000 {
1001 int tmp_guid_id;
1002 tmp_guid_id =
1004 if (tmp_guid_id != NI_RETCODE_FAILURE)
1005 {
1006 ni_log2(p_ctx, NI_LOG_DEBUG,
1007 "%s: block device name %s type %d guid %d is to "
1008 "override passed in guid %d\n",
1009 __func__, p_ctx->blk_dev_name, device_type, tmp_guid_id,
1010 p_ctx->hw_id);
1011 p_ctx->hw_id = tmp_guid_id;
1012 } else
1013 {
1014 ni_log(NI_LOG_INFO, "%s: block device name %s type %d NOT found ..\n",
1015 __func__, p_ctx->blk_dev_name, device_type);
1017 LRETURN;
1018 }
1019 }
1020
1021 // User did not pass in any handle, so we create it for them
1022 if ((handle1 == NI_INVALID_DEVICE_HANDLE) && (handle == NI_INVALID_DEVICE_HANDLE))
1023 {
1024 if (p_ctx->hw_id >=0) // User selected the encder/ decoder number
1025 {
1026 if ((rsrc_ctx = ni_rsrc_allocate_simple_direct(device_type, p_ctx->hw_id)) == NULL)
1027 {
1028
1029 ni_log2(p_ctx, NI_LOG_ERROR, "Error XCoder resource allocation: inst %d\n",
1030 p_ctx->hw_id);
1032 LRETURN;
1033 }
1034 ni_log2(p_ctx, NI_LOG_DEBUG, "device %p\n", rsrc_ctx);
1035 // Now the device name is in the rsrc_ctx, we open this device to get the file handles
1036
1037#ifdef _WIN32
1038 if ((handle = ni_device_open2(rsrc_ctx->p_device_info->blk_name,
1039 NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE)
1040 {
1043 LRETURN;
1044 } else
1045 {
1046 user_handles = true;
1047 p_ctx->device_handle = handle;
1048 p_ctx->blk_io_handle = handle;
1049 handle1 = handle;
1053 }
1054#else
1055 //The original design (code below) is to open char and block device file separately. And the ffmpeg will close the device twice.
1056 //However, in I/O version, char device can't be opened. For compatibility, and to avoid errors, open the block device twice.
1057 if (((handle = ni_device_open2(rsrc_ctx->p_device_info->dev_name, NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE) ||
1058 ((handle1 = ni_device_open2(rsrc_ctx->p_device_info->dev_name, NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE))
1059 {
1062 LRETURN;
1063 } else
1064 {
1065 user_handles = true;
1066 p_ctx->device_handle = handle;
1067 p_ctx->blk_io_handle = handle1;
1068 // NOLINTNEXTLINE(clang-analyzer-core.NonNullParamChecker): Couldn't determine why it will be NULL.
1071
1073 }
1074#endif
1075 } else
1076 {
1077 int tmp_id = -1;
1078
1079 // Decide on model load or real load to be used, based on name passed
1080 // in from p_ctx->dev_xcoder_name; after checking it will be used to
1081 // store device file name.
1082 if (0 == strcmp(p_ctx->dev_xcoder_name, NI_BEST_REAL_LOAD_STR))
1083 {
1084 use_model_load = false;
1085 } else if (0 != strcmp(p_ctx->dev_xcoder_name, NI_BEST_MODEL_LOAD_STR))
1086 {
1087 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s unrecognized option: %s.\n",
1088 __func__, p_ctx->dev_xcoder_name);
1089 retval = NI_RETCODE_INVALID_PARAM;
1090 LRETURN;
1091 }
1092
1093 if (ni_rsrc_lock_and_open(query_type, &lock) != NI_RETCODE_SUCCESS)
1094 {
1096 LRETURN;
1097 }
1098
1099 // We need to query through all the boards to confirm the least load.
1100
1101 p_device_pool = ni_rsrc_get_device_pool();
1102
1103 if (!p_device_pool)
1104 {
1105 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Error calling ni_rsrc_get_device_pool()\n");
1107 LRETURN;
1108 }
1109 if (IS_XCODER_DEVICE_TYPE(query_type))
1110 {
1111 num_coders = p_device_pool->p_device_queue->xcoder_cnt[query_type];
1112 } else
1113 {
1114 retval = NI_RETCODE_INVALID_PARAM;
1115 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1116 {
1118 LRETURN;
1119 }
1120 LRETURN;
1121 }
1122
1123 for (i = 0; i < num_coders; i++)
1124 {
1125 tmp_id = p_device_pool->p_device_queue->xcoders[query_type][i];
1126 p_device_context = ni_rsrc_get_device_context(query_type, tmp_id);
1127
1128 if (p_device_context == NULL)
1129 {
1130 ni_log2(p_ctx, NI_LOG_ERROR,
1131 "ERROR: %s() ni_rsrc_get_device_context() failed\n",
1132 __func__);
1133 continue;
1134 }
1135
1136 // Code is included in the for loop. In the loop, the device is
1137 // just opened once, and it will be closed once too.
1138 p_session_context.blk_io_handle = ni_device_open2(
1139 p_device_context->p_device_info->dev_name, NI_DEVICE_READ_WRITE);
1140 p_session_context.device_handle = p_session_context.blk_io_handle;
1141
1142 if (NI_INVALID_DEVICE_HANDLE == p_session_context.device_handle)
1143 {
1144 ni_log2(p_ctx, NI_LOG_ERROR, "Error open device");
1145 ni_rsrc_free_device_context(p_device_context);
1146 continue;
1147 }
1148
1149 p_session_context.hw_id = p_device_context->p_device_info->hw_id;
1150 rc = ni_device_session_query(&p_session_context, query_type);
1151 if (NI_INVALID_DEVICE_HANDLE != p_session_context.device_handle)
1152 {
1153 ni_device_close(p_session_context.device_handle);
1154 }
1155
1156 if (NI_RETCODE_SUCCESS != rc)
1157 {
1158 ni_log2(p_ctx, NI_LOG_ERROR, "Error query %s %s.%d\n",
1159 g_device_type_str[query_type],
1160 p_device_context->p_device_info->dev_name,
1161 p_device_context->p_device_info->hw_id);
1162 ni_rsrc_free_device_context(p_device_context);
1163 continue;
1164 }
1165 ni_rsrc_update_record(p_device_context, &p_session_context);
1166 p_dev_info = p_device_context->p_device_info;
1167
1168 // here we select the best load
1169 // for decoder/encoder: check the model_load/real_load
1170 // for hwuploader: check directly hwupload pixel load in query result
1171 if (NI_DEVICE_TYPE_UPLOAD == device_type)
1172 {
1173 if (lower_pixel_rate(&p_session_context.load_query, pixel_load))
1174 {
1175 guid = tmp_id;
1176 pixel_load = p_session_context.load_query.total_pixel_load;
1177 memcpy(&dev_info, p_dev_info, sizeof(ni_device_info_t));
1178 }
1179 } else
1180 {
1181 if (use_model_load)
1182 {
1183 curr_load = p_dev_info->model_load;
1184 } else
1185 {
1186 curr_load = p_dev_info->load;
1187 }
1188
1189 if (i == 0 || curr_load < least_load ||
1190 (curr_load == least_load &&
1191 p_dev_info->active_num_inst < num_sw_instances))
1192 {
1193 guid = tmp_id;
1194 least_load = curr_load;
1195 num_sw_instances = p_dev_info->active_num_inst;
1196 memcpy(&dev_info, p_dev_info, sizeof(ni_device_info_t));
1197 }
1198 }
1199 ni_rsrc_free_device_context(p_device_context);
1200 }
1201
1202#ifdef _WIN32
1203 // Now we have the device info that has the least load of the FW
1204 // we open this device and assign the FD
1205 if ((handle = ni_device_open2(dev_info.blk_name, NI_DEVICE_READ_WRITE)) ==
1206 NI_INVALID_DEVICE_HANDLE)
1207 {
1209 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1210 {
1212 LRETURN;
1213 }
1214 LRETURN;
1215 } else
1216 {
1217 p_ctx->device_handle = handle;
1218 p_ctx->blk_io_handle = handle;
1219 handle1 = handle;
1220 p_ctx->hw_id = guid;
1223 }
1224#else
1225 //The original design (code below) is to open char and block device file separately. And the ffmpeg will close the device twice.
1226 //However, in I/O version, char device can't be opened. For compatibility, and to avoid errors, open the block device twice.
1227 if (((handle = ni_device_open2(dev_info.dev_name, NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE) ||
1228 ((handle1 = ni_device_open2(dev_info.dev_name, NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE))
1229 {
1231 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1232 {
1234 LRETURN;
1235 }
1236 LRETURN;
1237 }
1238 else
1239 {
1240 p_ctx->device_handle = handle;
1241 p_ctx->blk_io_handle = handle1;
1242 p_ctx->hw_id = guid;
1245 }
1246#endif
1247 }
1248 }
1249 // user passed in the handle, but one of them is invalid, this is error case so we return error
1250 else if((handle1 == NI_INVALID_DEVICE_HANDLE) || (handle == NI_INVALID_DEVICE_HANDLE))
1251 {
1253 LRETURN;
1254 }
1255 // User passed in both handles, so we do not need to allocate for it
1256 else
1257 {
1258 user_handles = true;
1259 }
1260
1261 ni_log2(p_ctx, NI_LOG_DEBUG,
1262 "Finish open the session dev:%s guid:%d handle:%p handle1:%p\n",
1263 p_ctx->dev_xcoder_name, p_ctx->hw_id,
1264 p_ctx->device_handle, p_ctx->blk_io_handle);
1267 // get FW API version
1268 p_device_context = ni_rsrc_get_device_context(device_type, p_ctx->hw_id);
1269 if (p_device_context == NULL)
1270 {
1271 ni_log2(p_ctx, NI_LOG_ERROR,
1272 "ERROR: %s() ni_rsrc_get_device_context() failed\n",
1273 __func__);
1274 if (user_handles != true)
1275 {
1276 if(ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1277 {
1279 LRETURN;
1280 }
1281 }
1283 LRETURN;
1284 }
1285
1286 if (!(strcmp(p_ctx->dev_xcoder_name, "")) || !(strcmp(p_ctx->dev_xcoder_name, NI_BEST_MODEL_LOAD_STR)) ||
1287 !(strcmp(p_ctx->dev_xcoder_name, NI_BEST_REAL_LOAD_STR)))
1288 {
1290 }
1291
1292 memcpy(p_ctx->fw_rev , p_device_context->p_device_info->fw_rev, 8);
1293
1294 ni_rsrc_free_device_context(p_device_context);
1295
1296 retval = ni_device_get_ddr_configuration(p_ctx);
1297 if (retval != NI_RETCODE_SUCCESS)
1298 {
1299 ni_log2(p_ctx, NI_LOG_ERROR,
1300 "ERROR: %s() cannot retrieve DDR configuration\n",
1301 __func__);
1302 if (user_handles != true)
1303 {
1304 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1305 {
1307 LRETURN;
1308 }
1309 }
1310 LRETURN;
1311 }
1312
1313 if (p_ctx->keep_alive_timeout == 0)
1314 {
1315 ni_log2(p_ctx, NI_LOG_ERROR,
1316 "ERROR: %s() keep_alive_timeout was 0, should be between 1-100. "
1317 "Setting to default of %u\n",
1320 }
1321 switch (device_type)
1322 {
1324 {
1325 retval = ni_decoder_session_open(p_ctx);
1326 if (user_handles != true)
1327 {
1328 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1329 {
1331 LRETURN;
1332 }
1333 }
1334 // send keep alive signal thread
1335 if (NI_RETCODE_SUCCESS != retval)
1336 {
1337 LRETURN;
1338 }
1339 break;
1340 }
1342 {
1343#ifndef _WIN32
1344 // p2p is not supported on Windows, so skip following assignments.
1345 ni_xcoder_params_t *p_enc_params;
1346
1347 p_enc_params = p_ctx->p_session_config;
1348
1349 if (p_enc_params && p_enc_params->hwframes &&
1350 p_enc_params->p_first_frame)
1351 {
1352 niFrameSurface1_t *pSurface;
1353 pSurface =
1354 (niFrameSurface1_t *)p_enc_params->p_first_frame->p_data[3];
1355 p_ctx->sender_handle =
1356 (ni_device_handle_t)(int64_t)pSurface->device_handle;
1357 p_enc_params->rootBufId = pSurface->ui16FrameIdx;
1358
1359 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: sender_handle and rootBufId %d set\n",
1360 __func__, p_enc_params->rootBufId);
1361 }
1362#endif
1363
1364 retval = ni_encoder_session_open(p_ctx);
1365 if (user_handles != true)
1366 {
1367 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1368 {
1370 LRETURN;
1371 }
1372 }
1373 // send keep alive signal thread
1374 if (NI_RETCODE_SUCCESS != retval)
1375 {
1376 LRETURN;
1377 }
1378 break;
1379 }
1381 {
1382 retval = ni_uploader_session_open(p_ctx);
1383 if (user_handles != true)
1384 {
1385 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1386 {
1388 LRETURN;
1389 }
1390 }
1391 // send keep alive signal thread
1392 if (NI_RETCODE_SUCCESS != retval)
1393 {
1394 LRETURN;
1395 }
1396 break;
1397 }
1399 {
1400 retval = ni_scaler_session_open(p_ctx);
1401 if (user_handles != true)
1402 {
1403 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1404 {
1406 LRETURN;
1407 }
1408 }
1409 // send keep alive signal thread
1410 if (NI_RETCODE_SUCCESS != retval)
1411 {
1412 LRETURN;
1413 }
1414 break;
1415 }
1416 case NI_DEVICE_TYPE_AI:
1417 {
1418 retval = ni_ai_session_open(p_ctx);
1419 if (user_handles != true)
1420 {
1421 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1422 {
1424 LRETURN;
1425 }
1426 }
1427 // send keep alive signal thread
1428 if (NI_RETCODE_SUCCESS != retval)
1429 {
1430 LRETURN;
1431 }
1432 break;
1433 }
1434 default:
1435 {
1436 if (user_handles != true)
1437 {
1438 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1439 {
1441 LRETURN;
1442 }
1443 }
1444 retval = NI_RETCODE_INVALID_PARAM;
1445 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1446 __func__, device_type);
1447 LRETURN;
1448 }
1449 }
1450
1452 if (!p_ctx->keep_alive_thread_args)
1453 {
1454 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: thread_args allocation failed!\n");
1455 ni_device_session_close(p_ctx, 0, device_type);
1457 LRETURN;
1458 }
1459
1462 p_ctx->keep_alive_thread_args->device_type = device_type;
1465 p_ctx->keep_alive_thread_args->close_thread = false;
1468 p_ctx->keep_alive_thread_args->p_mutex = &p_ctx->mutex;
1469 p_ctx->keep_alive_thread_args->hw_id = p_ctx->hw_id;
1471
1473 sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
1474 {
1475 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: keep alive p_buffer allocation failed!\n");
1476 ni_device_session_close(p_ctx, 0, device_type);
1478 LRETURN;
1479 }
1481
1482 if (0 !=
1485 (void *)p_ctx->keep_alive_thread_args))
1486 {
1487 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to create keep alive thread\n");
1488 p_ctx->keep_alive_thread = (ni_pthread_t){0};
1491 ni_device_session_close(p_ctx, 0, device_type);
1493 LRETURN;
1494 }
1495 ni_log2(p_ctx, NI_LOG_DEBUG, "Enabled keep alive thread\n");
1496
1497 // allocate memory for encoder change data to be reused
1498 p_ctx->enc_change_params = calloc(1, sizeof(ni_encoder_change_params_t));
1499 if (!p_ctx->enc_change_params)
1500 {
1501 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: enc_change_params allocation failed!\n");
1502 ni_device_session_close(p_ctx, 0, device_type);
1504 }
1505
1506END:
1507 ni_device_session_context_clear(&p_session_context);
1508
1509 if (p_device_pool)
1510 {
1511 ni_rsrc_free_device_pool(p_device_pool);
1512 p_device_pool = NULL;
1513 }
1514
1515 p_ctx->xcoder_state &= ~NI_XCODER_OPEN_STATE;
1516
1518
1519 return retval;
1520}
1521
1522/*!*****************************************************************************
1523 * \brief Close device session that was previously opened by calling
1524 * ni_device_session_open()
1525 * If device_type is NI_DEVICE_TYPE_DECODER closes decoding session
1526 * If device_type is NI_DEVICE_TYPE_ENCODER closes encoding session
1527 * If device_type is NI_DEVICE_TYPE_SCALER closes scaling session
1528 *
1529 * \param[in] p_ctx Pointer to a caller allocated
1530 * ni_session_context_t struct
1531 * \param[in] eos_received Flag indicating if End Of Stream indicator was
1532 * received
1533 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER,
1534 * or NI_DEVICE_TYPE_SCALER
1535 * \return On success
1536 * NI_RETCODE_SUCCESS
1537 * On failure
1538 * NI_RETCODE_INVALID_PARAM
1539 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1540 * NI_RETCODE_ERROR_INVALID_SESSION
1541 ******************************************************************************/
1543 int eos_recieved,
1544 ni_device_type_t device_type)
1545{
1546 int ret;
1548
1549 if (!p_ctx)
1550 {
1551 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1552 __func__);
1554 }
1555
1559
1560#ifdef _WIN32
1561 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args)
1562#else
1563 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args)
1564#endif
1565 {
1566 p_ctx->keep_alive_thread_args->close_thread = true;
1567 ret = ni_pthread_join(p_ctx->keep_alive_thread, NULL);
1568 if (ret)
1569 {
1570 ni_log2(p_ctx, NI_LOG_ERROR,
1571 "join keep alive thread fail! : sid %u ret %d\n",
1572 p_ctx->session_id, ret);
1573 }
1576 } else
1577 {
1578 ni_log2(p_ctx, NI_LOG_ERROR, "invalid keep alive thread: %u\n",
1579 p_ctx->session_id);
1580 }
1581
1582 switch (device_type)
1583 {
1585 {
1586 retval = ni_decoder_session_close(p_ctx, eos_recieved);
1587 break;
1588 }
1590 {
1592 // fall through
1593 }
1595 {
1596 retval = ni_encoder_session_close(p_ctx, eos_recieved);
1597 break;
1598 }
1600 {
1601 retval = ni_scaler_session_close(p_ctx, eos_recieved);
1602 break;
1603 }
1604 case NI_DEVICE_TYPE_AI:
1605 {
1606 retval = ni_ai_session_close(p_ctx, eos_recieved);
1607 break;
1608 }
1609 default:
1610 {
1611 retval = NI_RETCODE_INVALID_PARAM;
1612 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1613 __func__, device_type);
1614 break;
1615 }
1616 }
1617
1619 // need set invalid after closed. May cause open invalid parameters.
1621
1622 ni_memfree(p_ctx->p_hdr_buf);
1623 ni_memfree(p_ctx->av_rois);
1624 ni_memfree(p_ctx->roi_map);
1625 ni_memfree(p_ctx->avc_roi_map);
1626 ni_memfree(p_ctx->hevc_roi_map);
1630 p_ctx->hdr_buf_size = 0;
1631 p_ctx->roi_side_data_size = 0;
1632 p_ctx->nb_rois = 0;
1633 p_ctx->target_bitrate = -1;
1634 p_ctx->force_idr_frame = 0;
1636 p_ctx->ltr_to_set.use_long_term_ref = 0;
1637 p_ctx->ltr_interval = -1;
1638 p_ctx->ltr_frame_ref_invalid = -1;
1639 p_ctx->max_frame_size = 0;
1640 p_ctx->reconfig_crf = -1;
1641 p_ctx->reconfig_crf_decimal = 0;
1642 p_ctx->reconfig_vbv_buffer_size = 0;
1643 p_ctx->reconfig_vbv_max_rate = 0;
1644 p_ctx->last_gop_size = 0;
1645 p_ctx->initial_frame_delay = 0;
1646 p_ctx->current_frame_delay = 0;
1647 p_ctx->max_frame_delay = 0;
1648 p_ctx->av1_pkt_num = 0;
1649 p_ctx->reconfig_intra_period = -1;
1650 p_ctx->reconfig_slice_arg = 0;
1651
1652 p_ctx->xcoder_state &= ~NI_XCODER_CLOSE_STATE;
1654
1655 return retval;
1656}
1657
1658/*!*****************************************************************************
1659 * \brief Send a flush command to the device
1660 * If device_type is NI_DEVICE_TYPE_DECODER sends EOS command to
1661 * decoder
1662 * If device_type is NI_DEVICE_TYPE_ENCODER sends EOS command to
1663 * encoder
1664 *
1665 * \param[in] p_ctx Pointer to a caller allocated
1666 * ni_session_context_t struct
1667 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1668 * \return On success
1669 * NI_RETCODE_SUCCESS
1670 * On failure
1671 * NI_RETCODE_INVALID_PARAM
1672 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1673 * NI_RETCODE_ERROR_INVALID_SESSION
1674 ******************************************************************************/
1676{
1678 if (!p_ctx)
1679 {
1680 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1681 __func__);
1683 }
1684
1687
1688 switch (device_type)
1689 {
1691 {
1692 retval = ni_decoder_session_send_eos(p_ctx);
1693 break;
1694 }
1696 {
1697 retval = ni_encoder_session_send_eos(p_ctx);
1698 break;
1699 }
1700 default:
1701 {
1702 retval = NI_RETCODE_INVALID_PARAM;
1703 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1704 __func__, device_type);
1705 break;
1706 }
1707 }
1708 p_ctx->ready_to_close = (NI_RETCODE_SUCCESS == retval);
1709 p_ctx->xcoder_state &= ~NI_XCODER_FLUSH_STATE;
1711 return retval;
1712}
1713
1714/*!*****************************************************************************
1715 * \brief Save a stream's headers in a decoder session that can be used later
1716 * for continuous decoding from the same source.
1717 *
1718 * \param[in] p_ctx Pointer to a caller allocated
1719 * ni_session_context_t struct
1720 * \param[in] hdr_data Pointer to header data
1721 * \param[in] hdr_size Size of header data in bytes
1722 * \return On success
1723 * NI_RETCODE_SUCCESS
1724 * On failure
1725 * NI_RETCODE_INVALID_PARAM
1726 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1727 * NI_RETCODE_ERROR_INVALID_SESSION
1728 ******************************************************************************/
1730 uint8_t *hdr_data,
1731 uint8_t hdr_size)
1732{
1734
1735 if (!p_ctx)
1736 {
1737 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s p_ctx null, return\n", __func__);
1739 }
1740
1741 if (!hdr_data)
1742 {
1743 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s hdr_data null, return\n", __func__);
1745 } else if (p_ctx->p_hdr_buf && p_ctx->hdr_buf_size == hdr_size &&
1746 0 == memcmp(p_ctx->p_hdr_buf, hdr_data, hdr_size))
1747 {
1748 // no change from the saved headers, success !
1749 return retval;
1750 }
1751
1752 // update the saved header data
1753 free(p_ctx->p_hdr_buf);
1754 p_ctx->hdr_buf_size = 0;
1755 p_ctx->p_hdr_buf = malloc(hdr_size);
1756 if (p_ctx->p_hdr_buf)
1757 {
1758 memcpy(p_ctx->p_hdr_buf, hdr_data, hdr_size);
1759 p_ctx->hdr_buf_size = hdr_size;
1760 ni_log2(p_ctx, NI_LOG_DEBUG, "%s saved hdr size %u\n", __func__,
1761 p_ctx->hdr_buf_size);
1762 } else
1763 {
1765 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s no memory.\n", __func__);
1766 }
1767 return retval;
1768}
1769
1770/*!*****************************************************************************
1771 * \brief Flush a decoder session to get ready to continue decoding.
1772 * Note: this is different from ni_device_session_flush in that it closes the
1773 * current decode session and opens a new one for continuous decoding.
1774 *
1775 * \param[in] p_ctx Pointer to a caller allocated
1776 * ni_session_context_t struct
1777 * \return On success
1778 * NI_RETCODE_SUCCESS
1779 * On failure
1780 * NI_RETCODE_INVALID_PARAM
1781 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1782 * NI_RETCODE_ERROR_INVALID_SESSION
1783 ******************************************************************************/
1785{
1787
1788 if (!p_ctx)
1789 {
1790 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s ctx null, return\n", __func__);
1792 }
1794 retval = ni_decoder_session_flush(p_ctx);
1795 if (NI_RETCODE_SUCCESS == retval) {
1796 p_ctx->ready_to_close = 0;
1797 }
1799 return retval;
1800}
1801
1802/*!*****************************************************************************
1803 * \brief Sends data to the device
1804 * If device_type is NI_DEVICE_TYPE_DECODER sends data packet to
1805 * decoder
1806 * If device_type is NI_DEVICE_TYPE_ENCODER sends data frame to encoder
1807 * If device_type is NI_DEVICE_TYPE_AI sends data frame to ai engine
1808 *
1809 * \param[in] p_ctx Pointer to a caller allocated
1810 * ni_session_context_t struct
1811 * \param[in] p_data Pointer to a caller allocated
1812 * ni_session_data_io_t struct which contains either a
1813 * ni_frame_t data frame or ni_packet_t data packet to
1814 * send
1815 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER or
1816 * NI_DEVICE_TYPE_AI
1817 * If NI_DEVICE_TYPE_DECODER is specified, it is
1818 * expected that the ni_packet_t struct inside the
1819 * p_data pointer contains data to send.
1820 * If NI_DEVICE_TYPE_ENCODER or NI_DEVICE_TYPE_AI is
1821 * specified, it is expected that the ni_frame_t
1822 * struct inside the p_data pointer contains data to
1823 * send.
1824 * \return On success
1825 * Total number of bytes written
1826 * On failure
1827 * NI_RETCODE_INVALID_PARAM
1828 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1829 * NI_RETCODE_ERROR_INVALID_SESSION
1830 ******************************************************************************/
1832{
1834
1835 if (!p_ctx || !p_data)
1836 {
1837 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1838 __func__);
1840 }
1841 // Here check if keep alive thread is closed.
1842#ifdef _WIN32
1843 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
1845#else
1846 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
1848#endif
1849 {
1850 ni_log2(p_ctx, NI_LOG_ERROR,
1851 "ERROR: %s() keep alive thread has been closed, "
1852 "hw:%d, session:%d\n",
1853 __func__, p_ctx->hw_id, p_ctx->session_id);
1855 }
1856
1858 // In close state, let the close process execute first.
1860 {
1861 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
1863 ni_usleep(100);
1865 }
1868
1869 switch (device_type)
1870 {
1872 {
1873 retval = ni_decoder_session_write(p_ctx, &(p_data->data.packet));
1874 break;
1875 }
1877 {
1878 retval = ni_encoder_session_write(p_ctx, &(p_data->data.frame));
1879 break;
1880 }
1881 case NI_DEVICE_TYPE_AI:
1882 {
1883 retval = ni_ai_session_write(p_ctx, &(p_data->data.frame));
1884 break;
1885 }
1886 default:
1887 {
1888 retval = NI_RETCODE_INVALID_PARAM;
1889 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1890 __func__, device_type);
1891 break;
1892 }
1893 }
1894
1896 p_ctx->xcoder_state &= ~NI_XCODER_WRITE_STATE;
1898 return retval;
1899}
1900
1901/*!*****************************************************************************
1902 * \brief Read data from the device
1903 * If device_type is NI_DEVICE_TYPE_DECODER reads data packet from
1904 * decoder
1905 * If device_type is NI_DEVICE_TYPE_ENCODER reads data frame from
1906 * encoder
1907 * If device_type is NI_DEVICE_TYPE_AI reads data frame from AI engine
1908 *
1909 * \param[in] p_ctx Pointer to a caller allocated
1910 * ni_session_context_t struct
1911 * \param[in] p_data Pointer to a caller allocated ni_session_data_io_t
1912 * struct which contains either a ni_frame_t data frame
1913 * or ni_packet_t data packet to send
1914 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER, or
1915 * NI_DEVICE_TYPE_SCALER
1916 * If NI_DEVICE_TYPE_DECODER is specified, data that
1917 * was read will be placed into ni_frame_t struct
1918 * inside the p_data pointer
1919 * If NI_DEVICE_TYPE_ENCODER is specified, data that
1920 * was read will be placed into ni_packet_t struct
1921 * inside the p_data pointer
1922 * If NI_DEVICE_TYPE_AI is specified, data that was
1923 * read will be placed into ni_frame_t struct inside
1924 * the p_data pointer
1925 * \return On success
1926 * Total number of bytes read
1927 * On failure
1928 * NI_RETCODE_INVALID_PARAM
1929 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1930 * NI_RETCODE_ERROR_INVALID_SESSION
1931 ******************************************************************************/
1933{
1935 if ((!p_ctx) || (!p_data))
1936 {
1937 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1938 __func__);
1940 }
1941
1942 // Here check if keep alive thread is closed.
1943#ifdef _WIN32
1944 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
1946#else
1947 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
1949#endif
1950 {
1951 ni_log2(p_ctx, NI_LOG_ERROR,
1952 "ERROR: %s() keep alive thread has been closed, "
1953 "hw:%d, session:%d\n",
1954 __func__, p_ctx->hw_id, p_ctx->session_id);
1956 }
1957
1959 // In close state, let the close process execute first.
1961 {
1962 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
1964 ni_usleep(100);
1966 }
1969
1970 switch (device_type)
1971 {
1973 {
1974 int seq_change_read_count = 0;
1975 p_data->data.frame.src_codec = p_ctx->codec_format;
1976 for (;;)
1977 {
1978 retval = ni_decoder_session_read(p_ctx, &(p_data->data.frame));
1979 // check resolution change only after initial setting obtained
1980 // p_data->data.frame.video_width is picture width and will be 32-align
1981 // adjusted to frame size; p_data->data.frame.video_height is the same as
1982 // frame size, then compare them to saved one for resolution checking
1983 //
1984 uint32_t aligned_width;
1985 if(QUADRA)
1986 {
1987 aligned_width = ((((p_data->data.frame.video_width * p_ctx->bit_depth_factor) + 127) / 128) * 128);
1988 }
1989 else
1990 {
1991 aligned_width = ((p_data->data.frame.video_width + 31) / 32) * 32;
1992 }
1993
1994 if (0 == retval && seq_change_read_count)
1995 {
1996 ni_log2(p_ctx, NI_LOG_DEBUG,
1997 "%s (decoder): seq change NO data, next time.\n", __func__);
1998 p_ctx->active_video_width = 0;
1999 p_ctx->active_video_height = 0;
2000 p_ctx->actual_video_width = 0;
2001 break;
2002 }
2003 else if (retval < 0)
2004 {
2005 ni_log2(p_ctx, NI_LOG_ERROR, "%s (decoder): failure ret %d, return ..\n",
2006 __func__, retval);
2007 break;
2008 }
2009 // aligned_width may equal to active_video_width if bit depth and width
2010 // are changed at the same time. So, check video_width != actual_video_width.
2011 else if (p_ctx->frame_num && (p_ctx->pixel_format_changed ||
2012 (p_data->data.frame.video_width &&
2013 p_data->data.frame.video_height &&
2014 (aligned_width != p_ctx->active_video_width ||
2015 p_data->data.frame.video_height != p_ctx->active_video_height))))
2016 {
2017 ni_log2(
2018 p_ctx, NI_LOG_DEBUG,
2019 "%s (decoder): resolution change, frame size %ux%u -> %ux%u, "
2020 "width %u bit %d, pix_fromat_changed %d, actual_video_width %d, continue read ...\n",
2021 __func__, p_ctx->active_video_width, p_ctx->active_video_height,
2022 aligned_width, p_data->data.frame.video_height,
2023 p_data->data.frame.video_width, p_ctx->bit_depth_factor,
2025 // reset active video resolution to 0 so it can be queried in the re-read
2026 p_ctx->active_video_width = 0;
2027 p_ctx->active_video_height = 0;
2028 p_ctx->actual_video_width = 0;
2029 seq_change_read_count++;
2030 }
2031 else
2032 {
2033 break;
2034 }
2035 }
2036 break;
2037 }
2039 {
2040 retval = ni_encoder_session_read(p_ctx, &(p_data->data.packet));
2041 break;
2042 }
2043 case NI_DEVICE_TYPE_AI:
2044 {
2045 retval = ni_ai_session_read(p_ctx, &(p_data->data.packet));
2046 break;
2047 }
2048 default:
2049 {
2050 retval = NI_RETCODE_INVALID_PARAM;
2051 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2052 __func__, device_type);
2053 break;
2054 }
2055 }
2056
2058 p_ctx->xcoder_state &= ~NI_XCODER_READ_STATE;
2060 return retval;
2061}
2062
2063/*!*****************************************************************************
2064 * \brief Query session data from the device -
2065 * If device_type is valid, will query session data
2066 * from specified device type
2067 *
2068 * \param[in] p_ctx Pointer to a caller allocated
2069 * ni_session_context_t struct
2070 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2071 * NI_DEVICE_TYPE_ENCODER or
2072 * NI_DEVICE_TYPE_SCALER or
2073 * NI_DEVICE_TYPE_AI or
2074 * NI_DEVICE_TYPE_UPLOADER
2075 *
2076 * \return On success
2077 * NI_RETCODE_SUCCESS
2078 * On failure
2079 * NI_RETCODE_INVALID_PARAM
2080 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2081 * NI_RETCODE_ERROR_INVALID_SESSION
2082 ******************************************************************************/
2084{
2086 if (!p_ctx)
2087 {
2088 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2089 __func__);
2091 }
2092
2093 if (IS_XCODER_DEVICE_TYPE(device_type))
2094 {
2095 retval = ni_xcoder_session_query(p_ctx, device_type);
2096 } else
2097 {
2098 retval = NI_RETCODE_INVALID_PARAM;
2099 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2100 __func__, device_type);
2101 }
2102
2103 return retval;
2104}
2105
2106/*!*****************************************************************************
2107 * \brief Query detail session data from the device -
2108 * If device_type is valid, will query session data
2109 * from specified device type
2110 *
2111 * \param[in] p_ctx Pointer to a caller allocated
2112 * ni_session_context_t struct
2113 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2114 * NI_DEVICE_TYPE_ENCODER or
2115 *
2116 * \return On success
2117 * NI_RETCODE_SUCCESS
2118 * On failure
2119 * NI_RETCODE_INVALID_PARAM
2120 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2121 * NI_RETCODE_ERROR_INVALID_SESSION
2122 ******************************************************************************/
2124{
2126 if (!p_ctx)
2127 {
2128 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2129 __func__);
2131 }
2132
2133 if (IS_XCODER_DEVICE_TYPE(device_type))
2134 {
2135 retval = ni_xcoder_session_query_detail(p_ctx, device_type, detail_data, 0);
2136 } else
2137 {
2138 retval = NI_RETCODE_INVALID_PARAM;
2139 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2140 __func__, device_type);
2141 }
2142
2143 return retval;
2144}
2145
2146/*!*****************************************************************************
2147 * \brief Query detail session data from the device -
2148 * If device_type is valid, will query session data
2149 * from specified device type
2150 *
2151 * \param[in] p_ctx Pointer to a caller allocated
2152 * ni_session_context_t struct
2153 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2154 * NI_DEVICE_TYPE_ENCODER or
2155 *
2156 * \return On success
2157 * NI_RETCODE_SUCCESS
2158 * On failure
2159 * NI_RETCODE_INVALID_PARAM
2160 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2161 * NI_RETCODE_ERROR_INVALID_SESSION
2162 ******************************************************************************/
2164{
2166 if (!p_ctx)
2167 {
2168 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2169 __func__);
2171 }
2172
2173 if (IS_XCODER_DEVICE_TYPE(device_type))
2174 {
2175 retval = ni_xcoder_session_query_detail(p_ctx, device_type, detail_data, 1);
2176 } else
2177 {
2178 retval = NI_RETCODE_INVALID_PARAM;
2179 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2180 __func__, device_type);
2181 }
2182
2183 return retval;
2184}
2185
2186/*!*****************************************************************************
2187 * \brief Send namespace num and SRIOv index to the device with specified logic block
2188 * address.
2189 *
2190 * \param[in] device_handle Device handle obtained by calling ni_device_open
2191 * \param[in] namespace_num Set the namespace number with designated sriov
2192 * \param[in] sriov_index Identify which sriov need to be set
2193 *
2194 * \return On success
2195 * NI_RETCODE_SUCCESS
2196 * On failure
2197 * NI_RETCODE_ERROR_MEM_ALOC
2198 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2199 ******************************************************************************/
2200ni_retcode_t ni_device_config_namespace_num(ni_device_handle_t device_handle,
2201 uint32_t namespace_num, uint32_t sriov_index)
2202{
2203 ni_log(NI_LOG_DEBUG, "%s namespace_num %u sriov_index %u\n",
2204 __func__, namespace_num, sriov_index);
2205 return ni_device_config_ns_qos(device_handle, namespace_num, sriov_index);
2206}
2207
2208/*!*****************************************************************************
2209 * \brief Send qos mode to the device with specified logic block
2210 * address.
2211 *
2212 * \param[in] device_handle Device handle obtained by calling ni_device_open
2213 * \param[in] mode The requested qos mode
2214 *
2215 * \return On success
2216 * NI_RETCODE_SUCCESS
2217 * On failure
2218 * NI_RETCODE_ERROR_MEM_ALOC
2219 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2220 ******************************************************************************/
2221ni_retcode_t ni_device_config_qos(ni_device_handle_t device_handle,
2222 uint32_t mode)
2223{
2224 ni_log(NI_LOG_DEBUG, "%s device_handle %p mode %u\n",
2225 __func__, device_handle, mode);
2226 return ni_device_config_ns_qos(device_handle, QOS_NAMESPACE_CODE, mode);
2227}
2228
2229/*!*****************************************************************************
2230 * \brief Send qos over provisioning mode to target namespace with specified logic
2231 * block address.
2232 *
2233 * \param[in] device_handle Device handle obtained by calling ni_device_open
2234 * \param[in] device_handle_t Target device handle of namespace required for OP
2235 * \param[in] over_provision The request overprovision percent
2236 *
2237 * \return On success
2238 * NI_RETCODE_SUCCESS
2239 * On failure
2240 * NI_RETCODE_ERROR_MEM_ALOC
2241 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2242 ******************************************************************************/
2243ni_retcode_t ni_device_config_qos_op(ni_device_handle_t device_handle,
2244 ni_device_handle_t device_handle_t,
2245 uint32_t over_provision)
2246{
2247 ni_retcode_t retval;
2248 float f_over_provision = 0;
2249 memcpy(&f_over_provision, &over_provision, sizeof(int32_t));
2250 ni_log(NI_LOG_DEBUG, "%s device_handle %p target %p over_provision %f\n",
2251 __func__, device_handle, device_handle_t, f_over_provision);
2252 retval = ni_device_config_ns_qos(device_handle, QOS_OP_CONFIG_REC_OP_CODE,
2253 over_provision);
2254 if (NI_RETCODE_SUCCESS != retval)
2255 {
2256 return retval;
2257 }
2258 retval = ni_device_config_ns_qos(device_handle_t, QOS_OP_CONFIG_CODE,
2259 0);
2260 return retval;
2261}
2262
2263/*!*****************************************************************************
2264 * \brief Allocate preliminary memory for the frame buffer based on provided
2265 * parameters. Applicable to YUV420 Planar pixel (8 or 10 bit/pixel)
2266 * format or 32-bit RGBA.
2267 *
2268 * \param[in] p_frame Pointer to a caller allocated
2269 * ni_frame_t struct
2270 * \param[in] video_width Width of the video frame
2271 * \param[in] video_height Height of the video frame
2272 * \param[in] alignment Allignment requirement
2273 * \param[in] metadata_flag Flag indicating if space for additional metadata
2274 * should be allocated
2275 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel,
2276 * 4 for 32 bits/pixel (RGBA)
2277 * \param[in] hw_frame_count Number of hw descriptors stored
2278 * \param[in] is_planar 0 if semiplanar else planar
2279 *
2280 * \return On success
2281 * NI_RETCODE_SUCCESS
2282 * On failure
2283 * NI_RETCODE_INVALID_PARAM
2284 * NI_RETCODE_ERROR_MEM_ALOC
2285 ******************************************************************************/
2287 int video_height, int alignment,
2288 int metadata_flag, int factor,
2289 int hw_frame_count, int is_planar)
2290{
2291 void* p_buffer = NULL;
2292 int metadata_size = 0;
2293 int retval = NI_RETCODE_SUCCESS;
2294 int width_aligned = video_width;
2295 int height_aligned = video_height;
2296
2297 if ((!p_frame) || ((factor!=1) && (factor!=2) && (factor !=4))
2298 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
2299 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
2300 {
2301 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2302 "factor %d, video_width %d, video_height %d\n",
2303 __func__, factor, video_width, video_height);
2305 }
2306
2307 if (metadata_flag)
2308 {
2309 metadata_size = NI_FW_META_DATA_SZ + NI_MAX_SEI_DATA;
2310 }
2311
2312 if (QUADRA)
2313 {
2314 switch (factor)
2315 {
2316 case 1: /* 8-bit YUV420 */
2317 case 2: /* 10-bit YUV420 */
2318 width_aligned = ((((video_width * factor) + 127) / 128) * 128) / factor;
2319 height_aligned = ((video_height + 1) / 2) * 2;
2320 break;
2321 case 4: /* 32-bit RGBA */
2322 //64byte aligned => 16 rgba pixels
2323 width_aligned = NI_VPU_ALIGN16(video_width);
2324 height_aligned = ((video_height + 1) / 2) * 2;
2325 break;
2326 default:
2328 }
2329 }
2330 else
2331 {
2332 width_aligned = ((video_width + 31) / 32) * 32;
2333 height_aligned = ((video_height + 7) / 8) * 8;
2334 if (alignment)
2335 {
2336 height_aligned = ((video_height + 15) / 16) * 16;
2337 }
2338 }
2339
2340 int luma_size = width_aligned * height_aligned * factor;
2341 int chroma_b_size;
2342 int chroma_r_size;
2343 if (QUADRA)
2344 {
2345 int chroma_width_aligned = ((((video_width / 2 * factor) + 127) / 128) * 128) / factor;
2346 if (is_planar == NI_PIXEL_PLANAR_FORMAT_TILED4X4 ||
2348 {
2349 chroma_width_aligned =
2350 ((((video_width * factor) + 127) / 128) * 128) / factor;
2351 }
2352 int chroma_height_aligned = height_aligned / 2;
2353 chroma_b_size = chroma_r_size = chroma_width_aligned * chroma_height_aligned * factor;
2354 if (is_planar == NI_PIXEL_PLANAR_FORMAT_TILED4X4 ||
2356 {
2357 chroma_r_size = 0;
2358 }
2359 if (4 == factor)
2360 {
2361 chroma_b_size = chroma_r_size = 0;
2362 }
2363 //ni_log(NI_LOG_DEBUG, "%s: factor %d chroma_aligned=%dx%d org=%dx%d\n", __func__, factor, chroma_width_aligned, chroma_height_aligned, video_width, video_height);
2364 }
2365 else
2366 {
2367 chroma_b_size = luma_size / 4;
2368 chroma_r_size = chroma_b_size;
2369 }
2370 int buffer_size;
2371
2372 /* if hw_frame_count is zero, this is a software frame */
2373 if (hw_frame_count == 0)
2374 buffer_size = luma_size + chroma_b_size + chroma_r_size + metadata_size;
2375 else
2376 buffer_size =
2377 (int)sizeof(niFrameSurface1_t) * hw_frame_count + metadata_size;
2378
2379 // added 2 blocks of 512 bytes buffer space to handle any extra metadata
2380 // retrieval from fw
2381 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT + NI_MEM_PAGE_ALIGNMENT * 3;
2382 //ni_log(NI_LOG_DEBUG, "%s: luma_size %d chroma_b_size %d chroma_r_size %d metadata_size %d buffer_size %d\n", __func__, luma_size, chroma_b_size, chroma_r_size, metadata_size, buffer_size);
2383
2384 //Check if need to free
2385 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
2386 {
2388 "%s: free current p_frame, p_frame->buffer_size=%u\n", __func__,
2389 p_frame->buffer_size);
2390 ni_frame_buffer_free(p_frame);
2391 }
2392
2393 //Check if need to realocate
2394 if (p_frame->buffer_size != buffer_size)
2395 {
2396 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
2397 {
2398 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
2399 NI_ERRNO, __func__);
2401 LRETURN;
2402 }
2403
2404 // init once after allocation
2405 //memset(p_buffer, 0, buffer_size);
2406 p_frame->buffer_size = buffer_size;
2407 p_frame->p_buffer = p_buffer;
2408
2409 ni_log(NI_LOG_DEBUG, "%s: Allocate new p_frame buffer\n", __func__);
2410 }
2411 else
2412 {
2413 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
2414 }
2415
2416 if (hw_frame_count)
2417 {
2418 p_frame->data_len[0] = 0;
2419 p_frame->data_len[1] = 0;
2420 p_frame->data_len[2] = 0;
2421 p_frame->data_len[3] = sizeof(niFrameSurface1_t)*hw_frame_count;
2422 }
2423 else
2424 {
2425 p_frame->data_len[0] = luma_size;
2426 p_frame->data_len[1] = chroma_b_size;
2427 p_frame->data_len[2] = chroma_r_size;
2428 p_frame->data_len[3] = 0;//unused by hwdesc
2429 }
2430
2431 p_frame->p_data[0] = p_frame->p_buffer;
2432 p_frame->p_data[1] = p_frame->p_data[0] + p_frame->data_len[0];
2433 p_frame->p_data[2] = p_frame->p_data[1] + p_frame->data_len[1];
2434 p_frame->p_data[3] = p_frame->p_data[2] + p_frame->data_len[2]; //hwdescriptor
2435
2436 // init p_data[3] to 0 so that ni_frame_buffer_free frees only valid DMA buf
2437 // fd in hw frame read from fw
2438 if (hw_frame_count)
2439 {
2440 memset(p_frame->p_data[3], 0, sizeof(niFrameSurface1_t) * hw_frame_count);
2441 }
2442
2443 p_frame->video_width = width_aligned;
2444 p_frame->video_height = height_aligned;
2445
2446 ni_log(NI_LOG_DEBUG, "ni_frame_buffer_alloc: p_buffer %p p_data [%p %p %p %p] data_len [%d %d %d %d] video_width %d video_height %d\n", p_frame->p_buffer, p_frame->p_data[0], p_frame->p_data[1], p_frame->p_data[2], p_frame->p_data[3], p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2], p_frame->data_len[3], p_frame->video_width, p_frame->video_height);
2447 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2448 p_frame->buffer_size);
2449
2450END:
2451
2452 if (NI_RETCODE_SUCCESS != retval)
2453 {
2454 ni_aligned_free(p_buffer);
2455 }
2456
2457 return retval;
2458}
2459
2460/*!*****************************************************************************
2461 * \brief Wrapper function for ni_frame_buffer_alloc. Meant to handle RGBA min.
2462 * resoulution considerations for encoder.
2463 *
2464 * \param[in] p_frame Pointer to a caller allocated
2465 * ni_frame_t struct
2466 * \param[in] video_width Width of the video frame
2467 * \param[in] video_height Height of the video frame
2468 * \param[in] alignment Allignment requirement
2469 * \param[in] metadata_flag Flag indicating if space for additional metadata
2470 * should be allocated
2471 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel,
2472 * 4 for 32 bits/pixel (RGBA)
2473 * \param[in] hw_frame_count Number of hw descriptors stored
2474 * \param[in] is_planar 0 if semiplanar else planar
2475 * \param[in] pix_fmt pixel format to distinguish between planar types
2476 * and/or components
2477 *
2478 * \return On success
2479 * NI_RETCODE_SUCCESS
2480 * On failure
2481 * NI_RETCODE_INVALID_PARAM
2482 * NI_RETCODE_ERROR_MEM_ALOC
2483 ******************************************************************************/
2485 int video_height, int alignment,
2486 int metadata_flag, int factor,
2487 int hw_frame_count, int is_planar,
2488 ni_pix_fmt_t pix_fmt)
2489{
2490 int extra_len = 0;
2491 int dst_stride[NI_MAX_NUM_DATA_POINTERS] = {0};
2492 int height_aligned[NI_MAX_NUM_DATA_POINTERS] = {0};
2493
2494 if (((factor!=1) && (factor!=2) && (factor !=4))
2495 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
2496 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
2497 {
2498 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2499 "factor %d, video_width %d, video_height %d\n",
2500 __func__, factor, video_width, video_height);
2502 }
2503
2504 switch (pix_fmt)
2505 {
2506 case NI_PIX_FMT_YUV420P:
2508 case NI_PIX_FMT_NV12:
2509 case NI_PIX_FMT_P010LE:
2510 case NI_PIX_FMT_NV16:
2511 case NI_PIX_FMT_YUYV422:
2512 case NI_PIX_FMT_UYVY422:
2513 case NI_PIX_FMT_ARGB:
2514 case NI_PIX_FMT_ABGR:
2515 case NI_PIX_FMT_RGBA:
2516 case NI_PIX_FMT_BGRA:
2517 case NI_PIX_FMT_BGR0:
2518 break;
2519 default:
2520 ni_log(NI_LOG_ERROR, "ERROR: %s pix_fmt %d not supported \n",
2521 __func__, pix_fmt);
2523 }
2524 //Get stride info for original resolution
2525 ni_get_frame_dim(video_width, video_height,
2526 pix_fmt,
2527 dst_stride, height_aligned);
2528
2529 if (metadata_flag)
2530 {
2531 extra_len = NI_FW_META_DATA_SZ + NI_MAX_SEI_DATA;
2532 }
2533
2534 return ni_frame_buffer_alloc_pixfmt(p_frame, pix_fmt, video_width,
2535 video_height, dst_stride, alignment,
2536 extra_len);
2537}
2538
2539/*!*****************************************************************************
2540 * \brief Allocate preliminary memory for the frame buffer based on provided
2541 * parameters.
2542 *
2543 * \param[in] p_frame Pointer to a caller allocated
2544 * ni_frame_t struct
2545 * \param[in] video_width Width of the video frame
2546 * \param[in] video_height Height of the video frame
2547 * \param[in] alignment Allignment requirement
2548 * \param[in] pixel_format Format for input
2549 *
2550 * \return On success
2551 * NI_RETCODE_SUCCESS
2552 * On failure
2553 * NI_RETCODE_INVALID_PARAM
2554 * NI_RETCODE_ERROR_MEM_ALOC
2555 ******************************************************************************/
2557 int video_height, int pixel_format)
2558{
2559 void *p_buffer = NULL;
2560 int retval = NI_RETCODE_SUCCESS;
2561 int width_aligned = video_width;
2562 int height_aligned = video_height;
2563 int buffer_size;
2564 int luma_size;
2565 int chroma_b_size;
2566 int chroma_r_size;
2567
2568 if ((!p_frame) || (video_width > NI_MAX_RESOLUTION_WIDTH) ||
2569 (video_width <= 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT) ||
2570 (video_height <= 0))
2571 {
2573 "ERROR: %s passed parameters are null or not supported, "
2574 "video_width %d, video_height %d\n",
2575 __func__, video_width, video_height);
2577 }
2578
2579 switch (pixel_format)
2580 {
2581 case NI_PIX_FMT_YUV420P:
2582 width_aligned = NI_VPU_ALIGN128(video_width);
2583 height_aligned = NI_VPU_CEIL(video_height, 2);
2584
2585 luma_size = width_aligned * height_aligned;
2586 chroma_b_size =
2587 NI_VPU_ALIGN128(video_width / 2) * height_aligned / 2;
2588 chroma_r_size = chroma_b_size;
2589 break;
2591 width_aligned = NI_VPU_ALIGN128(video_width * 2) / 2;
2592 height_aligned = NI_VPU_CEIL(video_height, 2);
2593
2594 luma_size = width_aligned * height_aligned * 2;
2595 chroma_b_size = NI_VPU_ALIGN128(video_width) * height_aligned / 2;
2596 chroma_r_size = chroma_b_size;
2597 break;
2598 case NI_PIX_FMT_NV12:
2599 width_aligned = NI_VPU_ALIGN128(video_width);
2600 height_aligned = NI_VPU_CEIL(video_height, 2);
2601
2602 luma_size = width_aligned * height_aligned;
2603 chroma_b_size = width_aligned * height_aligned / 2;
2604 chroma_r_size = 0;
2605 break;
2606 case NI_PIX_FMT_P010LE:
2607 width_aligned = NI_VPU_ALIGN128(video_width * 2) / 2;
2608 height_aligned = NI_VPU_CEIL(video_height, 2);
2609
2610 luma_size = width_aligned * height_aligned * 2;
2611 chroma_b_size = NI_VPU_ALIGN128(video_width) * height_aligned;
2612 chroma_r_size = 0;
2613 break;
2614 case NI_PIX_FMT_NV16:
2615 width_aligned = NI_VPU_ALIGN64(video_width);
2616 height_aligned = video_height;
2617
2618 luma_size = width_aligned * height_aligned;
2619 chroma_b_size = luma_size;
2620 chroma_r_size = 0;
2621 break;
2622 case NI_PIX_FMT_YUYV422:
2623 case NI_PIX_FMT_UYVY422:
2624 width_aligned = NI_VPU_ALIGN16(video_width);
2625 height_aligned = video_height;
2626
2627 luma_size = width_aligned * height_aligned * 2;
2628 chroma_b_size = 0;
2629 chroma_r_size = 0;
2630 break;
2631 case NI_PIX_FMT_RGBA:
2632 case NI_PIX_FMT_BGRA:
2633 case NI_PIX_FMT_ARGB:
2634 case NI_PIX_FMT_ABGR:
2635 case NI_PIX_FMT_BGR0:
2636 width_aligned = NI_VPU_ALIGN16(video_width);
2637 height_aligned = video_height;
2638
2639 luma_size = width_aligned * height_aligned * 4;
2640 chroma_b_size = 0;
2641 chroma_r_size = 0;
2642 break;
2643 case NI_PIX_FMT_BGRP:
2644 width_aligned = NI_VPU_ALIGN32(video_width);
2645 height_aligned = video_height;
2646
2647 luma_size = width_aligned * height_aligned;
2648 chroma_b_size = luma_size;
2649 chroma_r_size = luma_size;
2650 break;
2651 default:
2652 ni_log(NI_LOG_ERROR, "Unknown pixel format %d\n", pixel_format);
2654 }
2655
2656 /* Allocate local memory to hold a software ni_frame */
2657 buffer_size = luma_size + chroma_b_size + chroma_r_size;
2658
2659 /* Round up to nearest 4K block */
2660 buffer_size = NI_VPU_ALIGN4096(buffer_size);
2661
2662 ni_log(NI_LOG_DEBUG, "%s: Rlen %d Glen %d Blen %d buffer_size %d\n",
2663 __func__, luma_size, chroma_b_size, chroma_r_size, buffer_size);
2664
2665 /* If the frame has changed, reallocate it */
2666 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
2667 {
2669 "%s: free current p_frame, p_frame->buffer_size=%u\n", __func__,
2670 p_frame->buffer_size);
2671 ni_frame_buffer_free(p_frame);
2672 }
2673
2674 /* Check if need to reallocate */
2675 if (p_frame->buffer_size != buffer_size)
2676 {
2677 ni_log(NI_LOG_DEBUG, "%s: Allocate new p_frame buffer\n", __func__);
2678 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
2679 {
2681 "ERROR %d: %s() Cannot allocate p_frame buffer.\n", NI_ERRNO,
2682 __func__);
2684 LRETURN;
2685 }
2686 } else
2687 {
2688 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
2689 p_buffer = p_frame->p_buffer;
2690 }
2691
2692 // init once after allocation
2693 // memset(p_buffer, 0, buffer_size);
2694
2695 p_frame->buffer_size = buffer_size;
2696 p_frame->p_buffer = p_buffer;
2697
2698 p_frame->data_len[0] = luma_size;
2699 p_frame->data_len[1] = chroma_b_size;
2700 p_frame->data_len[2] = chroma_r_size;
2701 p_frame->data_len[3] = 0;
2702
2703 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
2704 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + p_frame->data_len[0];
2705 p_frame->p_data[2] = (uint8_t *)p_frame->p_data[1] + p_frame->data_len[1];
2706 p_frame->p_data[3] = (uint8_t *)p_frame->p_data[2] + p_frame->data_len[2];
2707
2708 // init p_data[3] to 0 so that ni_frame_buffer_free frees only valid DMA buf
2709 // fd in hw frame read from fw
2710 p_frame->video_width = width_aligned;
2711 p_frame->video_height = height_aligned;
2712
2713 // ni_log(NI_LOG_DEBUG, "ni_frame_buffer_alloc: p_buffer %p p_data [%p %p %p %p] data_len [%d %d %d %d] video_width %d video_height %d\n", p_frame->p_buffer, p_frame->p_data[0], p_frame->p_data[1], p_frame->p_data[2], p_frame->p_data[3], p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2], p_frame->data_len[3], p_frame->video_width, p_frame->video_height);
2714 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2715 p_frame->buffer_size);
2716END:
2717
2718 if (NI_RETCODE_SUCCESS != retval)
2719 {
2720 ni_aligned_free(p_buffer);
2721 }
2722
2723 return retval;
2724}
2725
2726/*!*****************************************************************************
2727 * \brief Allocate memory for decoder frame buffer based on provided
2728 * parameters; the memory is retrieved from a buffer pool and will be
2729 * returned to the same buffer pool by ni_decoder_frame_buffer_free.
2730 * Note: all attributes of ni_frame_t will be set up except for memory and
2731 * buffer, which rely on the pool being allocated; the pool will be
2732 * allocated only after the frame resolution is known.
2733 *
2734 * \param[in] p_pool Buffer pool to get the memory from
2735 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
2736 * \param[in] alloc_mem Whether to get memory from buffer pool
2737 * \param[in] video_width Width of the video frame
2738 * \param[in] video_height Height of the video frame
2739 * \param[in] alignment Alignment requirement
2740 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel
2741 * \param[in] is_planar 0 if semiplanar else planar
2742 *
2743 * \return On success
2744 * NI_RETCODE_SUCCESS
2745 * On failure
2746 * NI_RETCODE_INVALID_PARAM
2747 * NI_RETCODE_ERROR_MEM_ALOC
2748 ******************************************************************************/
2750 ni_frame_t *p_frame, int alloc_mem,
2751 int video_width, int video_height,
2752 int alignment, int factor,
2753 int is_planar)
2754{
2755 int retval = NI_RETCODE_SUCCESS;
2756
2757 int width_aligned;
2758 int height_aligned;
2759
2760 if ((!p_frame) || ((factor!=1) && (factor!=2))
2761 || (video_width > NI_MAX_RESOLUTION_WIDTH) || (video_width <= 0)
2762 || (video_height > NI_MAX_RESOLUTION_HEIGHT) || (video_height <= 0))
2763 {
2764 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2765 "factor %d, video_width %d, video_height %d\n",
2766 __func__, factor, video_width, video_height);
2768 }
2769
2770 if (QUADRA)
2771 {
2772 width_aligned = ((((video_width * factor) + 127) / 128) * 128) / factor;
2773 height_aligned = video_height;
2774 }
2775 else
2776 {
2777 width_aligned = ((video_width + 31) / 32) * 32;
2778 height_aligned = ((video_height + 7) / 8) * 8;
2779 if (alignment)
2780 {
2781 height_aligned = ((video_height + 15) / 16) * 16;
2782 }
2783 }
2784
2785 ni_log(NI_LOG_DEBUG, "%s: aligned=%dx%d orig=%dx%d\n", __func__,
2786 width_aligned, height_aligned, video_width, video_height);
2787
2788 int luma_size = width_aligned * height_aligned * factor;
2789 int chroma_b_size;
2790 int chroma_r_size;
2791 if (QUADRA)
2792 {
2793 int chroma_width_aligned = ((((video_width / 2 * factor) + 127) / 128) * 128) / factor;
2794 if (!is_planar)
2795 {
2796 chroma_width_aligned =
2797 ((((video_width * factor) + 127) / 128) * 128) / factor;
2798 }
2799 int chroma_height_aligned = height_aligned / 2;
2800 chroma_b_size = chroma_r_size = chroma_width_aligned * chroma_height_aligned * factor;
2801 if (!is_planar)
2802 {
2803 chroma_r_size = 0;
2804 }
2805 }
2806 else
2807 {
2808 chroma_b_size = luma_size / 4;
2809 chroma_r_size = chroma_b_size;
2810 }
2811 int buffer_size = luma_size + chroma_b_size + chroma_r_size +
2813
2814 // added 2 blocks of 512 bytes buffer space to handle any extra metadata
2815 // retrieval from fw
2816 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT + NI_MEM_PAGE_ALIGNMENT * 3;
2817
2818 p_frame->buffer_size = buffer_size;
2819
2820 // if need to get a buffer from pool, pool must have been set up
2821 if (alloc_mem)
2822 {
2823 if (! p_pool)
2824 {
2825 ni_log(NI_LOG_ERROR, "ERROR %s: invalid pool!\n", __func__);
2827 LRETURN;
2828 }
2829
2830 p_frame->dec_buf = ni_buf_pool_get_buffer(p_pool);
2831 if (! p_frame->dec_buf)
2832 {
2834 LRETURN;
2835 }
2836
2837 p_frame->p_buffer = p_frame->dec_buf->buf;
2838
2839 ni_log(NI_LOG_DEBUG, "%s: got new frame ptr %p buffer %p\n", __func__,
2840 p_frame->p_buffer, p_frame->dec_buf);
2841 }
2842 else
2843 {
2844 p_frame->dec_buf = NULL;
2845 p_frame->p_buffer = NULL;
2846 ni_log(NI_LOG_DEBUG, "%s: NOT alloc mem buffer\n", __func__);
2847 }
2848
2849 if (p_frame->p_buffer)
2850 {
2851 p_frame->p_data[0] = p_frame->p_buffer;
2852 p_frame->p_data[1] = p_frame->p_data[0] + luma_size;
2853 p_frame->p_data[2] = p_frame->p_data[1] + chroma_b_size;
2854 p_frame->p_data[3] = p_frame->p_data[2] + chroma_r_size;
2855 }
2856 else
2857 {
2858 p_frame->p_data[0] = p_frame->p_data[1] = p_frame->p_data[2] = NULL;
2859 }
2860
2861 p_frame->data_len[0] = luma_size;
2862 p_frame->data_len[1] = chroma_b_size;
2863 p_frame->data_len[2] = chroma_r_size;
2864 p_frame->data_len[3] = 0; //for hwdesc
2865
2866 p_frame->video_width = width_aligned;
2867 p_frame->video_height = height_aligned;
2868
2869 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2870 p_frame->buffer_size);
2871
2872END:
2873
2874 return retval;
2875}
2876
2877/*!*****************************************************************************
2878 * \brief Check if incoming frame is encoder zero copy compatible or not
2879 *
2880 * \param[in] p_enc_ctx pointer to encoder context
2881 * [in] p_enc_params pointer to encoder parameters
2882 * [in] width input width
2883 * [in] height input height
2884 * [in] linesize input linesizes (pointer to array)
2885 * [in] set_linesize setup linesizes 0 means not setup linesizes, 1 means setup linesizes (before encoder open)
2886 *
2887 * \return on success and can do zero copy
2888 * NI_RETCODE_SUCCESS
2889 *
2890 * cannot do zero copy
2891 * NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
2892 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
2893 * NI_RETCODE_INVALID_PARAM
2894 *
2895*******************************************************************************/
2897 ni_xcoder_params_t *p_enc_params,
2898 int width, int height,
2899 const int linesize[],
2900 bool set_linesize)
2901{
2902 // check pixel format / width / height / linesize can be supported
2903 if ((!p_enc_ctx) || (!p_enc_params) || (!linesize)
2904 || (linesize[0]<=0)
2905 || (width>NI_MAX_RESOLUTION_WIDTH) || (width<=0)
2906 || (height>NI_MAX_RESOLUTION_HEIGHT) || (height<=0))
2907 {
2908 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s passed parameters are null or not supported, "
2909 "p_enc_ctx %p, p_enc_params %p, linesize %p, "
2910 "width %d, height %d linesize[0] %d\n",
2911 __func__, p_enc_ctx, p_enc_params, linesize,
2912 width, height, (linesize) ? linesize[0] : 0);
2914 }
2915
2916 // check fw revision (if fw_rev has been populated in open session)
2919 "6Q") < 0))
2920 {
2921 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: not supported on device with FW API version < 6.Q\n", __func__);
2923 }
2924
2925 bool isrgba = false;
2926 bool isplanar = false;
2927 bool issemiplanar = false;
2928
2929 switch (p_enc_ctx->pixel_format)
2930 {
2931 case NI_PIX_FMT_YUV420P:
2933 isplanar = true;
2934 break;
2935 case NI_PIX_FMT_NV12:
2936 case NI_PIX_FMT_P010LE:
2937 issemiplanar = true;
2938 break;
2939 case NI_PIX_FMT_ABGR:
2940 case NI_PIX_FMT_ARGB:
2941 case NI_PIX_FMT_RGBA:
2942 case NI_PIX_FMT_BGRA:
2943 isrgba = true;
2944 break;
2945 default:
2946 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: pixel_format %d not supported\n", __func__);
2948 }
2949
2950 // check fw revision (if fw_rev has been populated in open session)
2951 if (issemiplanar &&
2954 "6q") < 0))
2955 {
2956 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: semi-planar not supported on device with FW API version < 6.q\n", __func__);
2958 }
2959
2960 // check zero copy compatibilty and set linesize
2961 if (p_enc_params->zerocopy_mode) // always allow zero copy for RGBA, because RGBA pixel format data copy currently not supported
2962 {
2963 if (set_linesize)
2964 {
2965 bool ishwframe = (p_enc_params->hwframes) ? true : false;
2966 int max_linesize = isrgba ? (NI_MAX_RESOLUTION_RGBA_WIDTH*4) : NI_MAX_RESOLUTION_LINESIZE;
2967 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s isrgba %u issemiplanar %u, ishwframe %u, "
2968 "p_enc_ctx %p, p_enc_params %p, linesize %p, "
2969 "width %d, height %d, linesize[0] %d linesize[1] %d\n",
2970 __func__, isrgba, issemiplanar, ishwframe, p_enc_ctx, p_enc_params, linesize,
2971 width, height, linesize[0], linesize[1]);
2972
2973 if (linesize[0] <= max_linesize &&
2974 linesize[0] % 2 == 0 && //even stride
2975 linesize[1] % 2 == 0 && //even stride
2976 width % 2 == 0 && //even width
2977 height % 2 == 0 && //even height
2978 (!p_enc_params->enable_ai_enhance || width % 128 == 0) && // align for AI engine
2979 width >= NI_MIN_WIDTH &&
2980 height >= NI_MIN_HEIGHT &&
2981 !ishwframe &&
2982 (!isplanar || linesize[2] == linesize[1]) // for planar, make sure cb linesize equal to cr linesize
2983 )
2984 {
2985 // send luma / chorma linesize to device (device is also aware frame will not be padded for 2-pass workaround)
2986 p_enc_params->luma_linesize = linesize[0];
2987 p_enc_params->chroma_linesize = (isrgba) ? 0 : linesize[1]; // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format
2988 return NI_RETCODE_SUCCESS;
2989 }
2990 else
2991 {
2992 p_enc_params->luma_linesize = 0;
2993 p_enc_params->chroma_linesize = 0;
2994 }
2995 }
2996 else if (p_enc_params->luma_linesize ||
2997 p_enc_params->chroma_linesize)
2998 {
2999 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s "
3000 "luma_linesize %d, chroma_linesize %d, "
3001 "linesize[0] %d, linesize[1] %d\n",
3002 __func__, p_enc_params->luma_linesize, p_enc_params->chroma_linesize,
3003 linesize[0], linesize[1]);
3004 if (p_enc_params->luma_linesize != linesize[0] ||
3005 (p_enc_params->chroma_linesize && p_enc_params->chroma_linesize != linesize[1]) // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format
3006 )
3007 {
3008#ifndef XCODER_311
3009 // linesizes can change during SW frame seqeunce change transcoding when FFmpeg noautoscale option is not set
3010 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: linesize changed from %u %u to %u %u - resolution change?\n", __func__,
3011 p_enc_params->luma_linesize, p_enc_params->chroma_linesize,
3012 linesize[0], linesize[1]);
3013#endif
3014 }
3015 else
3016 return NI_RETCODE_SUCCESS;
3017 }
3018 }
3019
3021}
3022
3023/*!*****************************************************************************
3024 * \brief Check if the frame data transferred is within a frame boundary and
3025 * adjust with offset if it doesn't. EP will re-adjust the data pointer
3026 * to the correct start address.
3027 *
3028 * \param[in] video_height Height of the video frame after filtering
3029 * [in] linesize Picture line size after filtering (i.e. cropping)
3030 * [in] data Picture data pointers after filtering (for each of YUV planes)
3031 * [in] buf_size0 Y frame size before any filtering (original size)
3032 * [in] buf_size1 U frame size before any filtering (original)
3033 * [in] buf_size2 V frame size before any filtering (original)
3034 * [in] buf_data0 Y picture data pointer before any filtering (original)
3035 * [in] buf_data1 U picture data pointer before any filtering (original)
3036 * [in] buf_data2 V picture data pointer before any filtering (original)
3037 *
3038 * \return On success
3039 * NI_RETCODE_SUCCESS
3040 * On failure
3041 * NI_RETCODE_INVALID_PARAM
3042 *****************************************************************************/
3044 ni_session_context_t *p_enc_ctx,
3045 ni_frame_t *p_frame, int video_height,
3046 const int linesize[], const uint8_t *data[],
3047 int buf_size0, int buf_size1, int buf_size2,
3048 uint8_t *buf_data0, uint8_t *buf_data1, uint8_t *buf_data2)
3049{
3050 int retval = NI_RETCODE_SUCCESS;
3051
3052 if (!p_frame || !p_enc_ctx || !data || !linesize)
3053 {
3054 ni_log(NI_LOG_ERROR, "ERROR: %s: null parameters: p_frame=%p, p_enc_ctx=%p, linesize=%p, data=%p\n",
3055 __func__, p_frame, p_enc_ctx, linesize, data);
3057 }
3058
3059 // Only newer firmware versions (6sU and above) support zero-copy with SW cropping corner
3060 // case handling. See the brief of this function.
3061 if (ni_cmp_fw_api_ver((char*)&p_enc_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sU") < 0)
3062 {
3063 p_frame->hor_adjust_offset = 0;
3064 return NI_RETCODE_SUCCESS;
3065 }
3066
3067 const uint8_t *buf_data[3] = { buf_data0, buf_data1, buf_data2 };
3068 const int buf_size[3] = { buf_size0, buf_size1, buf_size2 };
3069 const uint8_t *end_used, *end_alloc;
3070 int offset = 0;
3071 int i;
3072
3073 // num_planes = 1 if frame is directly from quadra decoder (out=sw) or from raw YUV file
3074 // num_planes = actual number of planes if frame is from ffmpeg SW decoder or after ffmpeg
3075 // pixel format conversion or after hwdownload from quadra decoder (out=hw)
3076 const int num_planes = (buf_size[2] != 0) ? 3 : (buf_size[1] != 0) ? 2 : 1;
3077
3078 // In case of num_planes==1, only index 0 of buf_data[] and buf_size[] exist,
3079 // but all 3 indices of data[] and linesize[] are available for yuv420p and 2 for nv12.
3080 // The same applies to both 8 and 10 bit pixel formats
3081 for (i = 0; i < num_planes; i++)
3082 {
3083 if (!data[i] || !buf_data[i] || buf_size[i] <= 0)
3084 {
3085 ni_log(NI_LOG_ERROR, "ERROR: %s: invalid parameter %d: data=%p, buf_data=%p, size=%d\n",
3086 __func__, i, data[i], buf_data[i], buf_size[i]);
3088 }
3089
3090 int plane_height = video_height >> (i > 0 ? 1 : 0);
3091
3092 // End of used data after filtering (e.g., cropping)
3093 if(num_planes == 1)
3094 {
3095 // Find end address used by last plane since it can reach the end of the buffer and buf_data[0] contains all YUV
3096 if (data[2])
3097 {
3098 // Planar pixel format if 3 data pointers are present
3099 end_used = data[2] + linesize[2] * (video_height >> 1);
3100 }
3101 else if (data[1])
3102 {
3103 // Semiplanar pixel format if only 2 data pointers are present
3104 end_used = data[1] + linesize[1] * (video_height >> 1);
3105 }
3106 else
3107 {
3108 ni_log(NI_LOG_ERROR, "ERROR: %s: Single-plane pixel format not supported\n", __func__);
3110 }
3111 }
3112 else
3113 {
3114 // Find Y, U, and V end address used
3115 end_used = data[i] + linesize[i] * plane_height;
3116 }
3117
3118 // End address of original allocated buffer.
3119 end_alloc = buf_data[i] + buf_size[i];
3120
3121 // Positive offset means filtered data to be transferred by zerocopy exceeds original buffer
3122 int plane_offset = (int)(end_used - end_alloc);
3123 plane_offset = (plane_offset > 0) ? plane_offset : 0;
3124
3125 if(num_planes == 1)
3126 {
3127 if (data[2])
3128 {
3129 offset = plane_offset * 2;
3130 ((uint8_t **)data)[0] -= offset;
3131 ((uint8_t **)data)[1] -= plane_offset;
3132 ((uint8_t **)data)[2] -= plane_offset;
3133 }
3134 else
3135 {
3136 offset = plane_offset;
3137 ((uint8_t **)data)[0] -= plane_offset;
3138 ((uint8_t **)data)[1] -= plane_offset;
3139 }
3140 }
3141 else
3142 {
3143 ((uint8_t **)data)[i] -= plane_offset;
3144 if (i == 0)
3145 {
3146 offset = plane_offset;
3147 }
3148 }
3149
3150 ni_log(NI_LOG_DEBUG, "%s: plane %d offset %d\n", __func__, i, offset);
3151 }
3152
3153 p_frame->hor_adjust_offset = offset;
3154
3155 return retval;
3156}
3157
3158/*!*****************************************************************************
3159 * \brief Allocate memory for encoder zero copy (metadata, etc.)
3160 * for encoding based on given
3161 * parameters, taking into account pic linesize and extra data.
3162 * Applicable to YUV planr / semi-planar 8 or 10 bit and RGBA pixel formats.
3163 *
3164 *
3165 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3166 * \param[in] video_width Width of the video frame
3167 * \param[in] video_height Height of the video frame
3168 * \param[in] linesize Picture line size
3169 * \param[in] data Picture data pointers (for each of YUV planes)
3170 * \param[in] extra_len Extra data size (incl. meta data)
3171 *
3172 * \return On success
3173 * NI_RETCODE_SUCCESS
3174 * On failure
3175 * NI_RETCODE_INVALID_PARAM
3176 * NI_RETCODE_ERROR_MEM_ALOC
3177 *****************************************************************************/
3179 int video_width, int video_height,
3180 const int linesize[], const uint8_t *data[],
3181 int extra_len)
3182{
3183 int retval = NI_RETCODE_SUCCESS;
3184
3185 if ((!p_frame) || (!linesize) || (!data))
3186 {
3187 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3188 "p_frame %p, linesize %p, data %p\n",
3189 __func__, p_frame, linesize, data);
3191 }
3192
3194 "%s: resolution=%dx%d linesize=%d/%d/%d "
3195 "data=%p %p %p extra_len=%d\n",
3196 __func__, video_width, video_height,
3197 linesize[0], linesize[1], linesize[2],
3198 data[0], data[1], data[2], extra_len);
3199
3200 if (p_frame->buffer_size)
3201 {
3202 p_frame->buffer_size = 0; //notify p_frame->p_buffer is not allocated
3203 ni_aligned_free(p_frame->p_buffer); // also free the temp p_buffer allocated for niFrameSurface1_t in encoder init stage
3204 }
3205
3206 p_frame->p_buffer = (uint8_t *)data[0];
3207 p_frame->p_data[0] = (uint8_t *)data[0];
3208 p_frame->p_data[1] = (uint8_t *)data[1];
3209 p_frame->p_data[2] = (uint8_t *)data[2];
3210
3211 int luma_size = linesize[0] * video_height;
3212 int chroma_b_size = 0;
3213 int chroma_r_size = 0;
3214
3215 // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format, but only data[0] pointer is populated
3216 if (data[1]) // cb size is 0 for RGBA pixel format
3217 chroma_b_size = linesize[1] * (video_height / 2);
3218
3219 if (data[2]) // cr size is 0 for semi-planar or RGBA pixel format
3220 chroma_r_size = linesize[2] * (video_height / 2);
3221
3222 //ni_log(NI_LOG_DEBUG, "%s: luma_size=%d chroma_b_size=%d chroma_r_size=%d\n", __func__, luma_size, chroma_b_size, chroma_r_size);
3223
3224 uint32_t start_offset;
3225 uint32_t total_start_len = 0;
3226 int i;
3227
3228 p_frame->inconsecutive_transfer = 0;
3229
3230 // rgba has one data pointer, semi-planar has two data pointers
3231 if ((data[1] && (data[0] + luma_size != data[1]))
3232 || (data[2] && (data[1] + chroma_b_size != data[2])))
3233 {
3234 p_frame->inconsecutive_transfer = 1;
3235 }
3236
3237 if (p_frame->inconsecutive_transfer)
3238 {
3239 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
3240 {
3241 start_offset = (uintptr_t)p_frame->p_data[i] % NI_MEM_PAGE_ALIGNMENT;
3242 p_frame->start_len[i] = start_offset ? (NI_MEM_PAGE_ALIGNMENT - start_offset) : 0;
3243 total_start_len += p_frame->start_len[i];
3244 }
3245 }
3246 else
3247 {
3248 start_offset = (uintptr_t)p_frame->p_data[0] % NI_MEM_PAGE_ALIGNMENT;
3249 p_frame->start_len[0] = start_offset ? (NI_MEM_PAGE_ALIGNMENT - start_offset) : 0;
3250 p_frame->start_len[1] = p_frame->start_len[2] = 0;
3251 total_start_len = p_frame->start_len[0];
3252 }
3253 p_frame->total_start_len = total_start_len;
3254
3255 if (ni_encoder_metadata_buffer_alloc(p_frame, extra_len))
3256 {
3257 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_metadata_buffer buffer.\n",
3258 NI_ERRNO, __func__);
3260 LRETURN;
3261 }
3262 p_frame->separate_metadata = 1;
3263
3264 if (total_start_len)
3265 {
3266 if (ni_encoder_start_buffer_alloc(p_frame))
3267 {
3268 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_start_buffer buffer.\n",
3269 NI_ERRNO, __func__);
3271 LRETURN;
3272 }
3273 p_frame->separate_start = 1;
3274
3275 // copy non-4k-aligned part at the start of YUV data
3276 int start_buffer_offset = 0;
3277 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
3278 {
3279 if (p_frame->p_data[i])
3280 {
3281 memcpy(p_frame->p_start_buffer+start_buffer_offset, p_frame->p_data[i],
3282 p_frame->start_len[i]);
3283 start_buffer_offset += p_frame->start_len[i];
3284 }
3285 }
3286 }
3287
3288 p_frame->data_len[0] = luma_size;
3289 p_frame->data_len[1] = chroma_b_size;
3290 p_frame->data_len[2] = chroma_r_size;
3291 p_frame->data_len[3] = 0;//unused by hwdesc
3292
3293 p_frame->video_width = video_width;
3294 p_frame->video_height = video_height;
3295
3297 "%s: success: p_metadata_buffer %p metadata_buffer_size %u "
3298 "p_start_buffer %p start_buffer_size %u data_len %u %u %u\n",
3299 __func__, p_frame->p_metadata_buffer, p_frame->metadata_buffer_size,
3300 p_frame->p_start_buffer, p_frame->start_buffer_size,
3301 p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2]);
3302
3303END:
3304
3305 return retval;
3306}
3307
3308
3309/*!*****************************************************************************
3310 * \brief Check if incoming frame is hwupload zero copy compatible or not
3311 *
3312 * \param[in] p_upl_ctx pointer to uploader context
3313 * [in] width input width
3314 * [in] height input height
3315 * [in] linesize input linesizes (pointer to array)
3316 * [in] pixel_format input pixel format
3317 *
3318 * \return on success and can do zero copy
3319 * NI_RETCODE_SUCCESS
3320 *
3321 * cannot do zero copy
3322 * NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
3323 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
3324 * NI_RETCODE_INVALID_PARAM
3325 *
3326*******************************************************************************/
3328 int width, int height,
3329 const int linesize[], int pixel_format)
3330{
3331 // check pixel format / width / height / linesize can be supported
3332 if ((!p_upl_ctx) || (!linesize)
3333 || (linesize[0]<=0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3334 || (width>NI_MAX_RESOLUTION_WIDTH) || (width<=0)
3335 || (height>NI_MAX_RESOLUTION_HEIGHT) || (height<=0))
3336 {
3337 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s passed parameters are null or not supported, "
3338 "p_enc_ctx %p, linesize %p, "
3339 "width %d, height %d linesize[0] %d\n",
3340 __func__, p_upl_ctx, linesize,
3341 width, height, (linesize) ? linesize[0] : 0);
3343 }
3344
3345 // check fw revision (if fw_rev has been populated in open session)
3348 "6S") < 0))
3349 {
3350 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: not supported on device with FW API version < 6.S\n", __func__);
3352 }
3353
3354 // upload does not have zeroCopyMode parameter, currently only allows resolution >= 1080p
3355 if ((width * height) < NI_NUM_OF_PIXELS_1080P)
3357
3358 // check zero copy compatibilty
3359 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s pixel_format %d "
3360 "p_upl_ctx %p, linesize %p, "
3361 "width %d, height %d, linesize[0] %d\n",
3362 __func__, pixel_format, p_upl_ctx, linesize,
3363 width, height, linesize[0]);
3364
3365 int bit_depth_factor;
3366 bool isrgba = false;
3367 bool isplanar = false;
3368 bool issemiplanar = false;
3369
3370 switch (pixel_format)
3371 {
3372 case NI_PIX_FMT_YUV420P:
3373 isplanar = true;
3374 bit_depth_factor = 1;
3375 break;
3377 isplanar = true;
3378 bit_depth_factor = 2;
3379 break;
3380 case NI_PIX_FMT_NV12:
3381 issemiplanar = true;
3382 bit_depth_factor = 1;
3383 break;
3384 case NI_PIX_FMT_P010LE:
3385 issemiplanar = true;
3386 bit_depth_factor = 2;
3387 break;
3388 case NI_PIX_FMT_ABGR:
3389 case NI_PIX_FMT_ARGB:
3390 case NI_PIX_FMT_RGBA:
3391 case NI_PIX_FMT_BGRA:
3392 isrgba = true;
3393 bit_depth_factor = 4; // not accurate, only for linesize check
3394 break;
3395 default:
3396 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: pixel_format %d not supported\n", __func__);
3398 }
3399
3400 // check fw revision (if fw_rev has been populated in open session)
3401 if (issemiplanar &&
3404 "6q") < 0))
3405 {
3406 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: semi-planar not supported on device with FW API version < 6.q\n", __func__);
3408 }
3409
3410 int max_linesize = isrgba ? (NI_MAX_RESOLUTION_RGBA_WIDTH*4) : NI_MAX_RESOLUTION_LINESIZE;
3411 if (linesize[0] <= max_linesize &&
3412 width % 2 == 0 && //even width
3413 height % 2 == 0 && //even height
3414 width >= NI_MIN_WIDTH && height >= NI_MIN_HEIGHT)
3415 {
3416 // yuv only support default 128 bytes aligned linesize, because downstream filter or encoder expect HW frame 128 bytes aligned
3417 if (isplanar &&
3418 linesize[0] == NI_VPU_ALIGN128(width * bit_depth_factor) &&
3419 linesize[1] == NI_VPU_ALIGN128(width * bit_depth_factor / 2) &&
3420 linesize[2] == linesize[1])
3421 return NI_RETCODE_SUCCESS;
3422
3423 // yuv only support default 128 bytes aligned linesize, because downstream filter or encoder expect HW frame 128 bytes aligned
3424 if (issemiplanar &&
3425 linesize[0] == NI_VPU_ALIGN128(width * bit_depth_factor) &&
3426 linesize[1] == linesize[0])
3427 return NI_RETCODE_SUCCESS;
3428
3429 // rgba only support 64 bytes aligned for 2D
3430 if (isrgba &&
3431 linesize[0] == NI_VPU_ALIGN64(width * bit_depth_factor))
3432 return NI_RETCODE_SUCCESS;
3433 }
3434
3436}
3437
3438/*!*****************************************************************************
3439 * \brief Allocate memory for the frame buffer for encoding based on given
3440 * parameters, taking into account pic line size and extra data.
3441 * Applicable to YUV420p AVFrame only. 8 or 10 bit/pixel.
3442 * Cb/Cr size matches that of Y.
3443 *
3444 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3445 *
3446 * \param[in] video_width Width of the video frame
3447 * \param[in] video_height Height of the video frame
3448 * \param[in] linesize Picture line size
3449 * \param[in] alignment Allignment requirement
3450 * \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3451 * to allocate any buffer (zero-copy from existing)
3452 * \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3453 *
3454 * \return On success
3455 * NI_RETCODE_SUCCESS
3456 * On failure
3457 * NI_RETCODE_INVALID_PARAM
3458 * NI_RETCODE_ERROR_MEM_ALOC
3459 *****************************************************************************/
3461 int video_height, int linesize[],
3462 int alignment, int extra_len,
3463 bool alignment_2pass_wa)
3464{
3465 void* p_buffer = NULL;
3466 int height_aligned;
3467 int retval = NI_RETCODE_SUCCESS;
3468
3469 if ((!p_frame) || (!linesize) || (linesize[0]<=0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3470 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
3471 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
3472 {
3473 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3474 "p_frame %p, linesize %p, video_width %d, video_height %d\n",
3475 __func__, p_frame, linesize, video_width, video_height);
3477 }
3478
3479 if (QUADRA)
3480 {
3481 height_aligned = ((video_height + 1) / 2) * 2;
3482 } else
3483 {
3484 height_aligned = ((video_height + 7) / 8) * 8;
3485
3486 if (alignment)
3487 {
3488 height_aligned = ((video_height + 15) / 16) * 16;
3489 }
3490 }
3491 if (height_aligned < NI_MIN_HEIGHT)
3492 {
3493 height_aligned = NI_MIN_HEIGHT;
3494 }
3495
3497 "%s: aligned=%dx%d org=%dx%d linesize=%d/%d/%d "
3498 "extra_len=%d\n",
3499 __func__, video_width, height_aligned, video_width, video_height,
3500 linesize[0], linesize[1], linesize[2], extra_len);
3501
3502 int luma_size = linesize[0] * height_aligned;
3503 int chroma_b_size;
3504 int chroma_r_size;
3505 if (QUADRA)
3506 {
3507 chroma_b_size = chroma_r_size = linesize[1] * (height_aligned / 2);
3508 if (alignment_2pass_wa)
3509 {
3510 // for 2-pass encode output mismatch WA, need to extend (and pad) Cr plane height, because 1st pass assume input 32 align
3511 chroma_r_size = linesize[1] * (((height_aligned + 31) / 32) * 32) / 2;
3512 }
3513 //ni_log(NI_LOG_DEBUG, "%s: luma_size=%d chroma_b_size=%d chroma_r_size=%d\n", __func__, luma_size, chroma_b_size, chroma_r_size);
3514 }
3515 else
3516 {
3517 chroma_b_size = luma_size / 4;
3518 chroma_r_size = luma_size / 4;
3519 }
3520 if(extra_len >= 0)
3521 {
3522 int buffer_size = luma_size + chroma_b_size + chroma_r_size + extra_len;
3523
3525
3526 //Check if Need to free
3527 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
3528 {
3530 "%s: free current p_frame, "
3531 "p_frame->buffer_size=%u\n",
3532 __func__, p_frame->buffer_size);
3533 ni_frame_buffer_free(p_frame);
3534 }
3535
3536 //Check if need to realocate
3537 if (p_frame->buffer_size != buffer_size)
3538 {
3539 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3540 {
3541 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
3542 NI_ERRNO, __func__);
3544 LRETURN;
3545 }
3546
3547 // init once after allocation
3548 memset(p_buffer, 0, buffer_size);
3549 p_frame->buffer_size = buffer_size;
3550 p_frame->p_buffer = p_buffer;
3551
3552 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
3553 }
3554 else
3555 {
3556 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
3557 }
3558 p_frame->p_data[0] = (uint8_t*)p_frame->p_buffer;
3559 p_frame->p_data[1] = (uint8_t*)p_frame->p_data[0] + luma_size;
3560 p_frame->p_data[2] = (uint8_t*)p_frame->p_data[1] + chroma_b_size;
3561 }
3562 else
3563 {
3564 p_frame->buffer_size = 0; //no ownership
3565 }
3566
3567 p_frame->data_len[0] = luma_size;
3568 p_frame->data_len[1] = chroma_b_size;
3569 p_frame->data_len[2] = chroma_r_size;
3570 p_frame->data_len[3] = 0;//unused by hwdesc
3571
3572 p_frame->video_width = video_width;
3573 p_frame->video_height = height_aligned;
3574
3576 "%s: success: p_frame->p_buffer %p "
3577 "p_frame->buffer_size=%u\n",
3578 __func__, p_frame->p_buffer, p_frame->buffer_size);
3579
3580END:
3581
3582 if (NI_RETCODE_SUCCESS != retval)
3583 {
3584 ni_aligned_free(p_buffer);
3585 }
3586
3587 return retval;
3588}
3589
3590/*!*****************************************************************************
3591 * \brief allocate device destination frame from scaler hwframe pool
3592 *
3593 * \param
3594 *
3595 * \return 0 if successful, < 0 otherwise
3596 ******************************************************************************/
3598 ni_scaler_input_params_t scaler_params,
3599 niFrameSurface1_t *p_surface)
3600{
3601 int ret = 0;
3602 if (scaler_params.op != NI_SCALER_OPCODE_OVERLAY && scaler_params.op != NI_SCALER_OPCODE_WATERMARK)
3603 {
3605 p_ctx, scaler_params.output_width, scaler_params.output_height,
3606 scaler_params.output_format, NI_SCALER_FLAG_IO,
3607 scaler_params.out_rec_width, scaler_params.out_rec_height,
3608 scaler_params.out_rec_x, scaler_params.out_rec_y,
3609 scaler_params.rgba_color, -1, NI_DEVICE_TYPE_SCALER);
3610 } else
3611 {
3612 // in vf_overlay_ni.c: flags = (s->alpha_format ? NI_SCALER_FLAG_PA : 0) | NI_SCALER_FLAG_IO;
3614 p_ctx, scaler_params.output_width, scaler_params.output_height,
3615 scaler_params.output_format, NI_SCALER_FLAG_IO,
3616 scaler_params.out_rec_width, scaler_params.out_rec_height,
3617 scaler_params.out_rec_x, scaler_params.out_rec_y,
3618 p_surface->ui32nodeAddress, p_surface->ui16FrameIdx,
3620 }
3621 return ret;
3622}
3623
3624/*!*****************************************************************************
3625 * \brief allocate device input frame by hw descriptor. This call won't actually allocate
3626 a frame but sends the incoming hardware frame index to the scaler manager
3627 *
3628 * \param
3629 *
3630 * \return 0 if successful, < 0 otherwise
3631 ******************************************************************************/
3633 ni_scaler_input_params_t scaler_params,
3634 niFrameSurface1_t *p_src_surface)
3635{
3636 int ret = 0;
3637
3639 p_ctx, scaler_params.input_width, scaler_params.input_height,
3640 scaler_params.input_format, 0, scaler_params.in_rec_width,
3641 scaler_params.in_rec_height, scaler_params.in_rec_x,
3642 scaler_params.in_rec_y, p_src_surface->ui32nodeAddress,
3643 p_src_surface->ui16FrameIdx, NI_DEVICE_TYPE_SCALER);
3644 return ret;
3645}
3646
3647/*!*****************************************************************************
3648 * \brief init output pool of scaler frames
3649 *
3650 * \param
3651 *
3652 * \return 0 if successful, < 0 otherwise
3653 ******************************************************************************/
3655 ni_scaler_input_params_t scaler_params)
3656{
3657 int rc = 0;
3658 int options = NI_SCALER_FLAG_IO | NI_SCALER_FLAG_PC;
3659 if (p_ctx->isP2P)
3660 options |= NI_SCALER_FLAG_P2;
3661
3662 /* Allocate a pool of frames by the scaler */
3663 rc = ni_device_alloc_frame(p_ctx, scaler_params.output_width,
3664 scaler_params.output_height,
3665 scaler_params.output_format, options,
3666 0, // rec width
3667 0, // rec height
3668 0, // rec X pos
3669 0, // rec Y pos
3670 NI_MAX_FILTER_POOL_SIZE, // rgba color/pool size
3671 0, // frame index
3673 return rc;
3674}
3675
3676/*!*****************************************************************************
3677* \brief Allocate memory for the frame buffer based on provided parameters
3678* taking into account pic line size and extra data.
3679* Applicable to nv12 AVFrame only. Cb/Cr size matches that of Y.
3680*
3681* \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3682*
3683* \param[in] video_width Width of the video frame
3684* \param[in] video_height Height of the video frame
3685* \param[in] linesize Picture line size
3686* \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3687* to allocate any buffer (zero-copy from existing)
3688* \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3689*
3690* \return On success
3691* NI_RETCODE_SUCCESS
3692* On failure
3693* NI_RETCODE_INVALID_PARAM
3694* NI_RETCODE_ERROR_MEM_ALOC
3695*****************************************************************************/
3697 int video_height, int linesize[],
3698 int extra_len, bool alignment_2pass_wa)
3699{
3700 void* p_buffer = NULL;
3701 int height_aligned;
3702 int retval = NI_RETCODE_SUCCESS;
3703
3704 if ((!p_frame) || (!linesize) || (linesize[0] <= 0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3705 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width <= 0)
3706 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height <= 0))
3707 {
3708 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3709 "p_frame %p, linesize %p, video_width %d, video_height %d\n",
3710 __func__, p_frame, linesize, video_width, video_height);
3712 }
3713
3714 height_aligned = ((video_height + 1) / 2) * 2;
3715
3716 if (height_aligned < NI_MIN_HEIGHT)
3717 {
3718 height_aligned = NI_MIN_HEIGHT;
3719 }
3720
3722 "%s: aligned=%dx%d org=%dx%d linesize=%d/%d/%d extra_len=%d\n",
3723 __func__, video_width, height_aligned, video_width, video_height,
3724 linesize[0], linesize[1], linesize[2], extra_len);
3725
3726 int luma_size = linesize[0] * height_aligned;
3727 int chroma_br_size = luma_size / 2;
3728 //int chroma_r_size = luma_size / 4;
3729 if (alignment_2pass_wa)
3730 {
3731 // for 2-pass encode output mismatch WA, need to extend (and pad) CbCr plane height, because 1st pass assume input 32 align
3732 chroma_br_size = linesize[0] * ((((height_aligned + 31) / 32) * 32) / 2);
3733 }
3734 if (extra_len >= 0)
3735 {
3736 int buffer_size = luma_size + chroma_br_size + extra_len;
3737
3739
3740 //Check if Need to free
3741 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
3742 {
3743 ni_log(NI_LOG_DEBUG, "%s: free current p_frame->buffer_size=%u\n",
3744 __func__, p_frame->buffer_size);
3745 ni_frame_buffer_free(p_frame);
3746 }
3747
3748 //Check if need to realocate
3749 if (p_frame->buffer_size != buffer_size)
3750 {
3751 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3752 {
3753 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
3754 NI_ERRNO, __func__);
3756 LRETURN;
3757 }
3758
3759 // init once after allocation
3760 memset(p_buffer, 0, buffer_size);
3761 p_frame->buffer_size = buffer_size;
3762 p_frame->p_buffer = p_buffer;
3763
3764 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
3765 }
3766 else
3767 {
3768 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
3769 }
3770
3771 p_frame->p_data[0] = (uint8_t*)p_frame->p_buffer;
3772 p_frame->p_data[1] = (uint8_t*)p_frame->p_data[0] + luma_size;
3773 p_frame->p_data[2] = (uint8_t*)p_frame->p_data[1] + chroma_br_size;
3774 }
3775 else
3776 {
3777 p_frame->buffer_size = 0; //no ownership
3778 }
3779 p_frame->data_len[0] = luma_size;
3780 p_frame->data_len[1] = chroma_br_size;
3781 p_frame->data_len[2] = 0;
3782
3783 p_frame->video_width = video_width;
3784 p_frame->video_height = height_aligned;
3785
3786 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
3787 p_frame->buffer_size);
3788
3789END:
3790
3791 if (NI_RETCODE_SUCCESS != retval)
3792 {
3793 ni_aligned_free(p_buffer);
3794 }
3795
3796 return retval;
3797}
3798
3799/*!*****************************************************************************
3800 * \brief This API is a wrapper for ni_encoder_frame_buffer_alloc(), used
3801 * for planar pixel formats, and ni_frame_buffer_alloc_nv(), used for
3802 * semi-planar pixel formats. This API is meant to combine the
3803 * functionality for both individual format APIs.
3804 * Allocate memory for the frame buffer for encoding based on given
3805 * parameters, taking into account pic line size and extra data.
3806 * Applicable to YUV420p(8 or 10 bit/pixel) or nv12 AVFrame.
3807 * Cb/Cr size matches that of Y.
3808 *
3809 * \param[in] planar true: if planar:
3810 * pixel_format == (NI_PIX_FMT_YUV420P ||
3811 * NI_PIX_FMT_YUV420P10LE ||NI_PIX_FMT_RGBA).
3812 * false: semi-planar:
3813 * pixel_format == (NI_PIX_FMT_NV12 ||
3814 * NI_PIX_FMT_P010LE).
3815 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3816 * \param[in] video_width Width of the video frame
3817 * \param[in] video_height Height of the video frame
3818 * \param[in] linesize Picture line size
3819 * \param[in] alignment Allignment requirement. Only used for planar format.
3820 * \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3821 * to allocate any buffer (zero-copy from existing)
3822 * \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3823 *
3824 * \return On success
3825 * NI_RETCODE_SUCCESS
3826 * On failure
3827 * NI_RETCODE_INVALID_PARAM
3828 * NI_RETCODE_ERROR_MEM_ALOC
3829 *****************************************************************************/
3831 int video_width, int video_height,
3832 int linesize[], int alignment,
3833 int extra_len,
3834 bool alignment_2pass_wa)
3835{
3836 if (true == planar)
3837 {
3838 return ni_encoder_frame_buffer_alloc(p_frame, video_width, video_height,
3839 linesize, alignment, extra_len,
3840 alignment_2pass_wa);
3841 }
3842 else
3843 {
3844 return ni_frame_buffer_alloc_nv(p_frame, video_width, video_height,
3845 linesize, extra_len,
3846 alignment_2pass_wa);
3847 }
3848}
3849
3850/*!*****************************************************************************
3851 * \brief Free frame buffer that was previously allocated with either
3852 * ni_frame_buffer_alloc or ni_encoder_frame_buffer_alloc or
3853 * ni_frame_buffer_alloc_nv
3854 *
3855 * \param[in] p_frame Pointer to a previously allocated ni_frame_t struct
3856 *
3857 * \return On success NI_RETCODE_SUCCESS
3858 * On failure NI_RETCODE_INVALID_PARAM
3859 ******************************************************************************/
3861{
3862 int i;
3864
3865 ni_log(NI_LOG_TRACE, "%s: enter\n", __func__);
3866
3867 if (!p_frame)
3868 {
3869 ni_log(NI_LOG_DEBUG, "WARN: %s(): p_frame is NULL\n", __func__);
3870 LRETURN;
3871 }
3872
3873 if (!p_frame->p_buffer)
3874 {
3875 ni_log(NI_LOG_DEBUG, "WARN: %s(): already freed, nothing to free\n",
3876 __func__);
3877 }
3878
3879#ifndef _WIN32
3880 // If this is a hardware frame with a DMA buf fd attached, close the DMA buf fd
3881 if ((p_frame->data_len[3] > 0) && (p_frame->p_data[3] != NULL))
3882 {
3883 niFrameSurface1_t *p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
3884 if ((p_surface->dma_buf_fd > 0) && (p_surface->ui16FrameIdx > 0))
3885 {
3886 // Close the DMA buf fd
3888 "%s: close p_surface->dma_buf_fd %d "
3889 "ui16FrameIdx %u\n",
3890 __func__, p_surface->dma_buf_fd, p_surface->ui16FrameIdx);
3891 close(p_surface->dma_buf_fd);
3892 }
3893 }
3894#endif
3895
3896 if (p_frame->buffer_size)
3897 {
3898 p_frame->buffer_size = 0;
3899 ni_aligned_free(p_frame->p_buffer);
3900 }
3901
3902 for (i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
3903 {
3904 p_frame->data_len[i] = 0;
3905 p_frame->p_data[i] = NULL;
3906 }
3907
3908 ni_frame_wipe_aux_data(p_frame);
3909
3910 if (p_frame->metadata_buffer_size)
3911 {
3912 p_frame->metadata_buffer_size = 0;
3914 }
3915 p_frame->separate_metadata = 0;
3916
3917 if (p_frame->start_buffer_size)
3918 {
3919 p_frame->start_buffer_size = 0;
3921 }
3922 p_frame->separate_start = 0;
3923 memset(p_frame->start_len, 0, sizeof(p_frame->start_len));
3924 p_frame->total_start_len = 0;
3925 p_frame->inconsecutive_transfer = 0;
3926
3927END:
3928
3929 ni_log(NI_LOG_TRACE, "%s: exit\n", __func__);
3930
3931 return retval;
3932}
3933
3934/*!*****************************************************************************
3935 * \brief Free decoder frame buffer that was previously allocated with
3936 * ni_decoder_frame_buffer_alloc, returning memory to a buffer pool.
3937 *
3938 * \param[in] p_frame Pointer to a previously allocated ni_frame_t struct
3939 *
3940 * \return On success NI_RETCODE_SUCCESS
3941 * On failure NI_RETCODE_INVALID_PARAM
3942 ******************************************************************************/
3944{
3945 int i;
3947
3948 ni_log(NI_LOG_TRACE, "%s: enter\n", __func__);
3949
3950 if (!p_frame)
3951 {
3952 ni_log(NI_LOG_DEBUG, "WARN: %s(): p_frame is NULL\n", __func__);
3953 retval = NI_RETCODE_INVALID_PARAM;
3954 LRETURN;
3955 }
3956
3957 if (p_frame->dec_buf)
3958 {
3960 ni_log(NI_LOG_DEBUG, "%s(): Mem buf returned ptr %p buf %p !\n", __func__,
3961 p_frame->dec_buf->buf, p_frame->dec_buf);
3962 }
3963 else
3964 {
3965 ni_log(NI_LOG_DEBUG, "%s(): NO mem buf returned !\n", __func__);
3966 }
3967
3968 p_frame->dec_buf = NULL;
3969 p_frame->p_buffer = NULL;
3970 p_frame->buffer_size = 0;
3971 for (i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
3972 {
3973 p_frame->data_len[i] = 0;
3974 p_frame->p_data[i] = NULL;
3975 }
3976 ni_frame_wipe_aux_data(p_frame);
3977
3978END:
3979
3980 ni_log(NI_LOG_TRACE, "%s: exit\n", __func__);
3981
3982 return retval;
3983}
3984
3985/*!*****************************************************************************
3986 * \brief Return a memory buffer to memory buffer pool.
3987 *
3988 * \param[in] buf Buffer to be returned.
3989 * \param[in] p_buffer_pool Buffer pool to return buffer to.
3990 *
3991 * \return None
3992 ******************************************************************************/
3994 ni_buf_pool_t *p_buffer_pool)
3995{
3996 ni_buf_pool_return_buffer(buf, p_buffer_pool);
3997}
3998
3999/*!*****************************************************************************
4000 * \brief Allocate memory for the packet buffer based on provided packet size
4001 *
4002 * \param[in] p_packet Pointer to a caller allocated
4003 * ni_packet_t struct
4004 * \param[in] packet_size Required allocation size
4005 *
4006 * \return On success
4007 * NI_RETCODE_SUCCESS
4008 * On failure
4009 * NI_RETCODE_INVALID_PARAM
4010 * NI_RETCODE_ERROR_MEM_ALOC
4011 ******************************************************************************/
4013{
4014 void* p_buffer = NULL;
4015 int metadata_size = 0;
4016
4017 metadata_size = NI_FW_META_DATA_SZ;
4018
4019 int buffer_size = (((packet_size + metadata_size) / NI_MAX_PACKET_SZ) + 1) * NI_MAX_PACKET_SZ;
4020
4021 ni_log(NI_LOG_TRACE, "%s: packet_size=%d\n", __func__,
4022 packet_size + metadata_size);
4023
4024 if (!p_packet || !packet_size)
4025 {
4026 ni_log(NI_LOG_ERROR, "ERROR: %s: null pointer parameters passed\n",
4027 __func__);
4029 }
4030
4031 if (buffer_size % NI_MEM_PAGE_ALIGNMENT)
4032 {
4033 buffer_size = ( (buffer_size / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT ) + NI_MEM_PAGE_ALIGNMENT;
4034 }
4035
4036 if (p_packet->buffer_size == buffer_size)
4037 {
4038 // Already allocated the exact size.
4039 p_packet->p_data = p_packet->p_buffer;
4040 ni_log(NI_LOG_DEBUG, "%s: reuse current p_packet buffer\n", __func__);
4041 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4042 p_packet->buffer_size);
4043 return NI_RETCODE_SUCCESS;
4044 }
4045
4046 if (p_packet->buffer_size)
4047 {
4049 "%s: free current p_packet, p_packet->buffer_size=%u\n", __func__,
4050 p_packet->buffer_size);
4051 ni_packet_buffer_free(p_packet);
4052 }
4053
4054 ni_log(NI_LOG_DEBUG, "%s: Allocating p_frame buffer, buffer_size=%d\n",
4055 __func__, buffer_size);
4056
4057 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
4058 {
4059 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_packet buffer.\n",
4060 NI_ERRNO, __func__);
4061 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4062 p_packet->buffer_size);
4064 }
4065
4066 p_packet->buffer_size = buffer_size;
4067 p_packet->p_buffer = p_buffer;
4068 p_packet->p_data = p_packet->p_buffer;
4069
4070 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4071 p_packet->buffer_size);
4072
4073 return NI_RETCODE_SUCCESS;
4074}
4075
4076/*!*****************************************************************************
4077 * \brief Allocate packet buffer using a user provided pointer, the memory
4078 * is expected to have already been allocated.
4079 *
4080 * For ideal performance memory should be 4k aligned. If it is not 4K aligned
4081 * then a temporary 4k aligned memory will be used to copy data to and from
4082 * when writing and reading. This will negatively impact performance.
4083 *
4084 * This API will overwrite p_packet->buffer_size, p_packet->p_buffer and
4085 * p_packet->p_data fields in p_packet.
4086 *
4087 * This API will not free any memory associated with p_packet->p_buffer and
4088 * p_packet->p_data fields in p_packet.
4089 * Common use case could be,
4090 * 1. Allocate memory to pointer
4091 * 2. Call ni_custom_packet_buffer_alloc() with allocated pointer.
4092 * 3. Use p_packet as required.
4093 * 4. Call ni_packet_buffer_free() to free up the memory.
4094 *
4095 * \param[in] p_buffer User provided pointer to be used for buffer
4096 * \param[in] p_packet Pointer to a caller allocated
4097 * ni_packet_t struct
4098 * \param[in] buffer_size Buffer size
4099 *
4100 * \return On success
4101 * NI_RETCODE_SUCCESS
4102 * On failure
4103 * NI_RETCODE_INVALID_PARAM
4104 * NI_RETCODE_ERROR_MEM_ALOC
4105 ******************************************************************************/
4107 ni_packet_t *p_packet,
4108 int buffer_size)
4109{
4110 ni_log(NI_LOG_TRACE, "%s(): enter buffer_size=%d\n", __func__, buffer_size);
4111
4112 if (!p_buffer || !p_packet || !buffer_size)
4113 {
4114 ni_log(NI_LOG_ERROR, "ERROR: %s: null pointer parameters passed\n",
4115 __func__);
4117 }
4118 if (((uintptr_t)p_buffer) % NI_MEM_PAGE_ALIGNMENT)
4119 {
4120 ni_log(NI_LOG_INFO, "Info: %s: Warning buffer not 4k aligned = %p!. Will do an extra copy\n",
4121 __func__, p_buffer);
4122 }
4123
4124 p_packet->buffer_size = buffer_size;
4125 p_packet->p_buffer = p_buffer;
4126 p_packet->p_data = p_packet->p_buffer;
4127
4128 ni_log(NI_LOG_TRACE, "%s: exit: \n", __func__);
4129
4130 return NI_RETCODE_SUCCESS;
4131}
4132
4133/*!*****************************************************************************
4134 * \brief Free packet buffer that was previously allocated with
4135 * ni_packet_buffer_alloc
4136 *
4137 * \param[in] p_packet Pointer to a previously allocated ni_packet_t struct
4138 *
4139 * \return On success NI_RETCODE_SUCCESS
4140 * On failure NI_RETCODE_INVALID_PARAM
4141 ******************************************************************************/
4143{
4145
4146 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
4147
4148 if (!p_packet)
4149 {
4150 ni_log(NI_LOG_ERROR, "ERROR: %s(): p_packet is NULL\n", __func__);
4151 retval = NI_RETCODE_FAILURE;
4152 LRETURN;
4153 }
4154
4155 if (!p_packet->p_buffer)
4156 {
4157 ni_log(NI_LOG_DEBUG, "%s(): already freed, nothing to free\n", __func__);
4158 LRETURN;
4159 }
4160
4161 ni_aligned_free(p_packet->p_buffer);
4162 p_packet->p_buffer = NULL;
4163 p_packet->buffer_size = 0;
4164 p_packet->data_len = 0;
4165 p_packet->p_data = NULL;
4166
4167 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
4168
4169END:
4170
4171 return retval;
4172}
4173
4174/*!*****************************************************************************
4175 * \brief Free packet buffer that was previously allocated with
4176 * ni_packet_buffer_alloc for AV1 packets merge
4177 *
4178 * \param[in] p_packet Pointer to a previously allocated ni_packet_t struct
4179 *
4180 * \return On success NI_RETCODE_SUCCESS
4181 * On failure NI_RETCODE_INVALID_PARAM
4182 ******************************************************************************/
4184{
4185 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
4187 int i;
4188
4189 if (!p_packet)
4190 {
4191 ni_log(NI_LOG_ERROR, "ERROR: %s(): p_packet is NULL\n", __func__);
4192 retval = NI_RETCODE_FAILURE;
4193 LRETURN;
4194 }
4195
4196 if (!p_packet->av1_buffer_index)
4197 {
4199 "%s(): no need to free previous av1 packet buffers\n", __func__);
4200 LRETURN;
4201 }
4202
4203 for (i = 0; i < p_packet->av1_buffer_index; i++)
4204 {
4205 ni_log(NI_LOG_DEBUG, "%s(): free previous av1 packet buffer %d\n",
4206 __func__, i);
4207 ni_aligned_free(p_packet->av1_p_buffer[i]);
4208 p_packet->av1_p_buffer[i] = NULL;
4209 p_packet->av1_p_data[i] = NULL;
4210 p_packet->av1_buffer_size[i] = 0;
4211 p_packet->av1_data_len[i] = 0;
4212 }
4213
4214 p_packet->av1_buffer_index = 0;
4215
4216END:
4217
4218 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
4219
4220 return retval;
4221}
4222
4223/*!*****************************************************************************
4224 * \brief Copy video packet accounting for alignment
4225 *
4226 * \param[in] p_destination Destination to where to copy to
4227 * \param[in] p_source Source from where to copy from
4228 * \param[in] cur_size current size
4229 * \param[out] p_leftover Pointer to the data that was left over
4230 * \param[out] p_prev_size Size of the data leftover ??
4231 *
4232 * \return On success Total number of bytes that were copied
4233 * On failure NI_RETCODE_FAILURE
4234 ******************************************************************************/
4235int ni_packet_copy(void* p_destination, const void* const p_source, int cur_size, void* p_leftover, int* p_prev_size)
4236{
4237 int copy_size = 0;
4238 int padding_size = 0;
4239 int prev_size = p_prev_size == NULL? 0 : *p_prev_size;
4240
4241 int total_size = cur_size + prev_size;
4242 uint8_t* p_src = (uint8_t*)p_source;
4243 uint8_t* p_dst = (uint8_t*)p_destination;
4244 uint8_t* p_lftover = (uint8_t*)p_leftover;
4245
4246 if (!p_prev_size)
4247 {
4249 }
4250
4251 ni_log(NI_LOG_TRACE, "%s(): enter, *prev_size=%d\n", __func__, *p_prev_size);
4252
4253 if ((0 == cur_size) && (0 == prev_size))
4254 {
4255 return copy_size;
4256 }
4257
4258 if (((0 != cur_size) && (!p_source)) || (!p_destination) || (!p_leftover))
4259 {
4260 return NI_RETCODE_FAILURE;
4261 }
4262
4263 copy_size = ((total_size + NI_MEM_PAGE_ALIGNMENT - 1) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
4264
4265 if (copy_size > total_size)
4266 {
4267 padding_size = copy_size - total_size;
4268 }
4269
4270 if (prev_size > 0)
4271 {
4272 memcpy(p_dst, p_lftover, prev_size);
4273 }
4274
4275 p_dst += prev_size;
4276
4277 memcpy(p_dst, p_src, cur_size);
4278
4279 if (padding_size)
4280 {
4281 p_dst += cur_size;
4282 memset(p_dst, 0, padding_size);
4283 }
4284
4286 "%s(): exit, cur_size=%d, copy_size=%d, "
4287 "prev_size=%d, padding_size=%d\n", __func__, cur_size,
4288 copy_size, *p_prev_size, padding_size);
4289
4290 *p_prev_size = 0;
4291
4292 return copy_size;
4293}
4294
4295/*!*****************************************************************************
4296 * \brief Add a new auxiliary data to a frame
4297 *
4298 * \param[in/out] frame a frame to which the auxiliary data should be added
4299 * \param[in] type type of the added auxiliary data
4300 * \param[in] data_size size of the added auxiliary data
4301 *
4302 * \return a pointer to the newly added aux data on success, NULL otherwise
4303 ******************************************************************************/
4305 int data_size)
4306{
4307 ni_aux_data_t *ret;
4308
4310 !(ret = malloc(sizeof(ni_aux_data_t))))
4311 {
4313 "ERROR: %s No memory or exceeding max aux_data number !\n",
4314 __func__);
4315 return NULL;
4316 }
4317
4318 ret->type = type;
4319 ret->size = data_size;
4320 ret->data = calloc(1, data_size);
4321 if (!ret->data)
4322 {
4323 ni_log(NI_LOG_ERROR, "ERROR: %s No memory for aux data !\n", __func__);
4324 free(ret);
4325 ret = NULL;
4326 } else
4327 {
4328 frame->aux_data[frame->nb_aux_data++] = ret;
4329 }
4330
4331 return ret;
4332}
4333
4334/*!*****************************************************************************
4335 * \brief Add a new auxiliary data to a frame and copy in the raw data
4336 *
4337 * \param[in/out] frame a frame to which the auxiliary data should be added
4338 * \param[in] type type of the added auxiliary data
4339 * \param[in] raw_data the raw data of the aux data
4340 * \param[in] data_size size of the added auxiliary data
4341 *
4342 * \return a pointer to the newly added aux data on success, NULL otherwise
4343 ******************************************************************************/
4345 ni_aux_data_type_t type,
4346 const uint8_t *raw_data,
4347 int data_size)
4348{
4349 ni_aux_data_t *ret = ni_frame_new_aux_data(frame, type, data_size);
4350 if (ret)
4351 {
4352 memcpy(ret->data, raw_data, data_size);
4353 }
4354 return ret;
4355}
4356
4357/*!*****************************************************************************
4358 * \brief Retrieve from the frame auxiliary data of a given type if exists
4359 *
4360 * \param[in] frame a frame from which the auxiliary data should be retrieved
4361 * \param[in] type type of the auxiliary data to be retrieved
4362 *
4363 * \return a pointer to the aux data of a given type on success, NULL otherwise
4364 ******************************************************************************/
4366 ni_aux_data_type_t type)
4367{
4368 int i;
4369 for (i = 0; i < frame->nb_aux_data; i++)
4370 {
4371 if (frame->aux_data[i]->type == type)
4372 {
4373 return frame->aux_data[i];
4374 }
4375 }
4376 return NULL;
4377}
4378
4379/*!*****************************************************************************
4380 * \brief If auxiliary data of the given type exists in the frame, free it
4381 * and remove it from the frame.
4382 *
4383 * \param[in/out] frame a frame from which the auxiliary data should be removed
4384 * \param[in] type type of the auxiliary data to be removed
4385 *
4386 * \return None
4387 ******************************************************************************/
4389{
4390 int i;
4391 ni_aux_data_t *aux;
4392
4393 for (i = 0; i < frame->nb_aux_data; i++)
4394 {
4395 aux = frame->aux_data[i];
4396 if (aux->type == type)
4397 {
4398 frame->aux_data[i] = frame->aux_data[frame->nb_aux_data - 1];
4399 frame->aux_data[frame->nb_aux_data - 1] = NULL;
4400 frame->nb_aux_data--;
4401 free(aux->data);
4402 free(aux);
4403 }
4404 }
4405}
4406
4407/*!*****************************************************************************
4408 * \brief Free and remove all auxiliary data from the frame.
4409 *
4410 * \param[in/out] frame a frame from which the auxiliary data should be removed
4411 *
4412 * \return None
4413 ******************************************************************************/
4415{
4416 int i;
4417 ni_aux_data_t *aux;
4418
4419 for (i = 0; i < frame->nb_aux_data; i++)
4420 {
4421 aux = frame->aux_data[i];
4422 free(aux->data);
4423 free(aux);
4424 }
4425 frame->nb_aux_data = 0;
4426}
4427
4428/*!*****************************************************************************
4429 * \brief Initialize default encoder parameters
4430 *
4431 * \param[out] param Pointer to a user allocated ni_xcoder_params_t
4432 * to initialize to default parameters
4433 * \param[in] fps_num Frames per second
4434 * \param[in] fps_denom FPS denomination
4435 * \param[in] bit_rate bit rate
4436 * \param[in] width frame width
4437 * \param[in] height frame height
4438 * \param[in] codec_format codec from ni_codec_format_t
4439 *
4440 * \return On success
4441 * NI_RETCODE_SUCCESS
4442 * On failure
4443 * NI_RETCODE_FAILURE
4444 * NI_RETCODE_INVALID_PARAM
4445 ******************************************************************************/
4447 int fps_num, int fps_denom,
4448 long bit_rate, int width,
4449 int height,
4450 ni_codec_format_t codec_format)
4451{
4452 ni_encoder_cfg_params_t *p_enc = NULL;
4453 int i = 0, j = 0;
4455
4456 //Initialize p_param structure
4457 if (!p_param)
4458 {
4459 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameters passed\n",
4460 __func__);
4461 retval = NI_RETCODE_INVALID_PARAM;
4462 LRETURN;
4463 }
4464
4465 ni_log(NI_LOG_DEBUG, "%s()\n", __func__);
4466
4467 //Initialize p_param structure
4468 memset(p_param, 0, sizeof(ni_xcoder_params_t));
4469
4470 p_enc = &p_param->cfg_enc_params;
4471
4472 // Rev. B: unified for HEVC/H.264
4473 p_enc->profile = 0;
4474 p_enc->level_idc = 0;
4475 p_enc->high_tier = 0;
4476
4477 if (QUADRA)
4479 else
4481
4482 p_enc->use_recommend_enc_params = 0;
4483 p_enc->cu_size_mode = 7;
4484 p_enc->max_num_merge = 2;
4485 p_enc->enable_dynamic_8x8_merge = 1;
4486 p_enc->enable_dynamic_16x16_merge = 1;
4487 p_enc->enable_dynamic_32x32_merge = 1;
4488
4489 p_enc->rc.trans_rate = 0;
4490
4491 p_enc->rc.enable_rate_control = 0;
4492 if (QUADRA)
4494 else
4496 p_enc->rc.enable_hvs_qp = 0;
4497 p_enc->rc.enable_hvs_qp_scale = 1;
4498 p_enc->rc.hvs_qp_scale = 2;
4499 p_enc->rc.min_qp = 8;
4500 p_enc->rc.max_qp = 51;
4501 p_enc->rc.max_delta_qp = 10;
4502
4503 // hrd is disabled if vbv_buffer_size=0, hrd is enabled if vbv_buffer_size is [10, 3000]
4504 p_enc->rc.vbv_buffer_size = -1;
4505 p_enc->rc.enable_filler = 0;
4506 p_enc->rc.enable_pic_skip = 0;
4507 p_enc->rc.vbv_max_rate = 0;
4508
4509 p_enc->roi_enable = 0;
4510
4512 // feature not supported on JPEG/AV1 - disable by default
4513 if (codec_format == NI_CODEC_FORMAT_JPEG ||
4514 codec_format == NI_CODEC_FORMAT_AV1)
4515 {
4517 }
4518
4519 p_enc->long_term_ref_enable = 0;
4520 p_enc->long_term_ref_interval = 0;
4521 p_enc->long_term_ref_count = 2;
4522
4523 p_enc->conf_win_top = 0;
4524 p_enc->conf_win_bottom = 0;
4525 p_enc->conf_win_left = 0;
4526 p_enc->conf_win_right = 0;
4527
4528 p_enc->intra_period = 120;
4529 p_enc->rc.intra_qp = 22;
4530 p_enc->rc.intra_qp_delta = -2;
4531 if (QUADRA)
4532 p_enc->rc.enable_mb_level_rc = 0;
4533 else
4534 p_enc->rc.enable_mb_level_rc = 1;
4535
4536 p_enc->decoding_refresh_type = 1;
4537
4538 p_enc->slice_mode = 0;
4539 p_enc->slice_arg = 0;
4540
4541 // Rev. B: H.264 only parameters.
4542 p_enc->enable_transform_8x8 = 1;
4543 p_enc->entropy_coding_mode = 1;
4544
4545 p_enc->intra_mb_refresh_mode = 0;
4546 p_enc->intra_mb_refresh_arg = 0;
4547 p_enc->intra_reset_refresh = 0;
4548
4550#ifndef QUADRA
4551 if (!QUADRA)
4552 {
4553 for (i = 0; i < NI_MAX_GOP_NUM; i++)
4554 {
4557 p_enc->custom_gop_params.pic_param[i].pic_qp = 0;
4558 p_enc->custom_gop_params.pic_param[i].num_ref_pic_L0 = 0;
4559 p_enc->custom_gop_params.pic_param[i].ref_poc_L0 = 0;
4560 p_enc->custom_gop_params.pic_param[i].ref_poc_L1 = 0;
4562 }
4563 }
4564 else // QUADRA
4565#endif
4566 {
4567 for (i = 0; i < NI_MAX_GOP_NUM; i++)
4568 {
4572 (float)0.3; // QP Factor range is between 0.3 and 1, higher values mean lower quality and less bits
4576 for (j = 0; j < NI_MAX_REF_PIC; j++)
4577 {
4578 p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic = 0;
4579 p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic_used = -1;
4580 }
4581 }
4582 }
4583
4584 p_param->source_width = width;
4585 p_param->source_height = height;
4586
4587 p_param->fps_number = fps_num;
4588 p_param->fps_denominator = fps_denom;
4589
4590 if (p_param->fps_number && p_param->fps_denominator)
4591 {
4592 p_enc->frame_rate = (int)(p_param->fps_number / p_param->fps_denominator);
4593 }
4594 else
4595 {
4596 p_enc->frame_rate = 30;
4597 }
4598
4599 p_param->bitrate = (int)bit_rate;
4600 p_param->roi_demo_mode = 0;
4601 p_param->reconf_demo_mode = 0; // for encoder reconfiguration testing
4602 p_param->force_pic_qp_demo_mode = 0;
4603 p_param->force_frame_type = 0;
4604 p_param->hdrEnableVUI = 0;
4605 p_param->cacheRoi = 0;
4606 p_param->low_delay_mode = 0;
4607 p_param->padding = 1;
4608 p_param->generate_enc_hdrs = 0;
4609 p_param->use_low_delay_poc_type = 0;
4610 p_param->rootBufId = 0;
4611 p_param->staticMmapThreshold = 0;
4612 p_param->zerocopy_mode = 1;
4613 p_param->luma_linesize = 0;
4614 p_param->chroma_linesize = 0;
4615 p_param ->enableCpuAffinity = 0;
4616
4618
4619 p_param->dolby_vision_profile = 0;
4620
4621 // encoder stream header VUI setting
4622 p_param->color_primaries = 2; // default COL_PRI_UNSPECIFIED
4623 p_param->color_transfer_characteristic = 2; // default COL_TRC_UNSPECIFIED
4624 p_param->color_space = 2; // default COL_SPC_UNSPECIFIED
4625 p_param->sar_num = 0; // default SAR numerator 0
4626 p_param->sar_denom = 1; // default SAR denominator 1
4627 p_param->video_full_range_flag = -1;
4628
4629 p_param->enable2PassGop = 0;
4631 p_param->minFramesDelay = 0;
4632 p_param->interval_of_psnr = 1;
4633 for (i = 0; i < NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL; i++) {
4634 for (j = 0; j < NI_CUSTOMIZE_ROI_QP_NUM; j++) {
4635 // 127 is invalid for delta qp and absolute qp
4636 p_param->customize_roi_qp_map[i][j] = 127;
4637 }
4638 }
4639
4640 //QUADRA
4641 p_enc->EnableAUD = 0;
4642 p_enc->lookAheadDepth = 0;
4643 p_enc->rdoLevel = (codec_format == NI_CODEC_FORMAT_JPEG) ? 0 : 1;
4644 p_enc->crf = -1;
4645 p_enc->HDR10MaxLight = 0;
4646 p_enc->HDR10AveLight = 0;
4647 p_enc->HDR10CLLEnable = 0;
4648 p_enc->EnableRdoQuant = -1;
4649 p_enc->ctbRcMode = 0;
4650 p_enc->gopSize = 0;
4651 p_enc->gopLowdelay = 0;
4652 p_enc->gdrDuration = 0;
4653 p_enc->hrdEnable = 0;
4654 p_enc->ltrRefInterval = 0;
4655 p_enc->ltrRefQpOffset = 0;
4656 p_enc->ltrFirstGap = 0;
4657 p_enc->ltrNextInterval = 1;
4658 p_enc->multicoreJointMode = 0;
4659 p_enc->qlevel = -1;
4660 p_enc->maxFrameSize = 0;
4661 p_enc->maxFrameSizeRatio = 0;
4662 p_enc->chromaQpOffset = 0;
4663 p_enc->tolCtbRcInter = (float)0.1;
4664 p_enc->tolCtbRcIntra = (float)0.1;
4665 p_enc->bitrateWindow = -255;
4666 p_enc->inLoopDSRatio = 1;
4667 p_enc->blockRCSize = 0;
4668 p_enc->rcQpDeltaRange = 10;
4669 p_enc->ctbRowQpStep = 0;
4670 p_enc->newRcEnable = -1;
4671 p_enc->colorDescPresent = 0;
4672 p_enc->colorPrimaries = 2;
4673 p_enc->colorTrc = 2;
4674 p_enc->colorSpace = 2;
4675 p_enc->aspectRatioWidth = 0;
4676 p_enc->aspectRatioHeight = 1;
4677 p_enc->videoFullRange = 0;
4679 p_enc->enable_ssim = 0;
4680 p_enc->HDR10Enable = 0;
4681 p_enc->HDR10dx0 = 0;
4682 p_enc->HDR10dy0 = 0;
4683 p_enc->HDR10dx1 = 0;
4684 p_enc->HDR10dy1 = 0;
4685 p_enc->HDR10dx2 = 0;
4686 p_enc->HDR10dy2 = 0;
4687 p_enc->HDR10wx = 0;
4688 p_enc->HDR10wy = 0;
4689 p_enc->HDR10maxluma = 0;
4690 p_enc->HDR10minluma = 0;
4691 p_enc->avcc_hvcc = 0;
4692 p_enc->av1_error_resilient_mode = 0;
4693 p_enc->temporal_layers_enable = 0;
4694 p_enc->crop_width = 0;
4695 p_enc->crop_height = 0;
4696 p_enc->hor_offset = 0;
4697 p_enc->ver_offset = 0;
4698 p_enc->crfMax = -1;
4699 p_enc->qcomp = (float)0.6;
4700 p_enc->noMbtree = 0;
4701 p_enc->noHWMultiPassSupport = 0;
4702 p_enc->cuTreeFactor = 5;
4703 p_enc->ipRatio = (float)1.4;
4704 p_enc->pbRatio = (float)1.3;
4705 p_enc->cplxDecay = (float)0.5;
4706 p_enc->pps_init_qp = -1;
4707 p_enc->bitrateMode = -1; // -1 = not set, bitrateMode 0 = max bitrate (actual bitrate can be lower than bitrate), bitrateMode 1 = average bitrate (actual bitrate approximately equal to bitrate)
4708 p_enc->pass1_qp = -1;
4709 p_enc->crfFloat = -1.0f;
4710 p_enc->hvsBaseMbComplexity = 15;
4711 p_enc->statistic_output_level = 0;
4712 p_enc->skip_frame_enable = 0;
4713 p_enc->max_consecutive_skip_num = 1;
4714 p_enc->skip_frame_interval = 0;
4715 p_enc->enableipRatio = 0;
4716 p_enc->enable_all_sei_passthru = 0;
4717 p_enc->iframe_size_ratio = 100;
4718 p_enc->crf_max_iframe_enable = 0;
4719 p_enc->vbv_min_rate = 0;
4720 p_enc->totalCuTreeDepth = 0;
4721 p_enc->adaptiveCuTree = 0;
4722 p_enc->preIntraHandling = 1;
4723 p_enc->baseLayerOnly = 0;
4724 p_enc->pastFrameMaxIntraRatio = 20;
4725 p_enc->linkFrameMaxIntraRatio = 40;
4726 p_enc->adaptiveLamdaMode = 0;
4727 p_enc->adaptiveCrfMode = 0;
4728#ifdef XCODER_311
4729 p_enc->disable_adaptive_buffers = 1;
4730#else
4731 p_enc->disable_adaptive_buffers = 0;
4732#endif
4733 p_enc->disableBframeRdoq = 0;
4734 p_enc->forceBframeQpfactor = (float)-1.0;
4735 p_enc->tune_bframe_visual = 0;
4736 p_enc->enable_acq_limit = 0;
4737 p_enc->get_psnr_mode = 3;
4739 p_enc->motionConstrainedMode = 0;
4740 p_enc->still_image_detect_level = 0;
4741 p_enc->scene_change_detect_level = 0;
4742 p_enc->encMallocStrategy = 0;
4743 p_enc->enable_smooth_crf = 0;
4744 p_enc->enable_compensate_qp = 0;
4745 p_enc->spatial_layers = 1;
4746 p_enc->enable_timecode = 0;
4748 p_enc->vbvBufferReencode = 0;
4749 p_enc->disableAv1TimingInfo = 0;
4751 p_enc->preset_enabled = 0;
4752 p_enc->reset_dts_offset = 1;
4753 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
4754 {
4755 p_enc->spatialLayerBitrate[i] = 0;
4756 p_enc->av1OpLevel[i] = 0;
4757 }
4758 p_enc->intraCompensateMode = 0;
4759 p_enc->customMinCoeffDiv = 0;
4760
4761 if (codec_format == NI_CODEC_FORMAT_AV1)
4762 {
4763 if (p_param->source_width < NI_PARAM_AV1_MIN_WIDTH)
4764 {
4766 LRETURN;
4767 }
4769 {
4771 LRETURN;
4772 }
4773 if (p_param->source_width > NI_PARAM_AV1_MAX_WIDTH)
4774 {
4776 LRETURN;
4777 }
4779 {
4781 LRETURN;
4782 }
4783 if (p_param->source_height * p_param->source_width >
4785 {
4787 LRETURN;
4788 }
4789 // AV1 8x8 alignment HW limitation is now worked around by FW cropping input resolution
4791 {
4792 ni_log(NI_LOG_ERROR, "AV1 Picture Width not aligned to %d - picture will be cropped\n",
4794 }
4796 {
4797 ni_log(NI_LOG_ERROR, "AV1 Picture Height not aligned to %d - picture will be cropped\n",
4799 }
4800 }
4801
4802 if (codec_format == NI_CODEC_FORMAT_JPEG)
4803 {
4804 if (p_param->source_width < NI_MIN_WIDTH)
4805 {
4807 LRETURN;
4808 }
4809 if (p_param->source_height < NI_MIN_HEIGHT)
4810 {
4812 LRETURN;
4813 }
4814 }
4815
4816 if (p_param->source_width > NI_PARAM_MAX_WIDTH)
4817 {
4819 LRETURN;
4820 }
4821 if (p_param->source_width < NI_PARAM_MIN_WIDTH)
4822 {
4824 LRETURN;
4825 }
4826
4827 if (p_param->source_height > NI_PARAM_MAX_HEIGHT)
4828 {
4830 LRETURN;
4831 }
4832 if (p_param->source_height < NI_PARAM_MIN_HEIGHT)
4833 {
4835 LRETURN;
4836 }
4837 if (p_param->source_height*p_param->source_width > NI_MAX_RESOLUTION_AREA)
4838 {
4840 LRETURN;
4841 }
4842
4843END:
4844
4845 return retval;
4846}
4847
4848/*!*****************************************************************************
4849 * \brief Initialize default decoder parameters
4850 *
4851 * \param[out] param Pointer to a user allocated ni_xcoder_params_t
4852 * to initialize to default parameters
4853 * \param[in] fps_num Frames per second
4854 * \param[in] fps_denom FPS denomination
4855 * \param[in] bit_rate bit rate
4856 * \param[in] width frame width
4857 * \param[in] height frame height
4858 *
4859 * \return On success
4860 * NI_RETCODE_SUCCESS
4861 * On failure
4862 * NI_RETCODE_FAILURE
4863 * NI_RETCODE_INVALID_PARAM
4864 ******************************************************************************/
4866 int fps_num, int fps_denom,
4867 long bit_rate, int width,
4868 int height)
4869{
4870 ni_decoder_input_params_t* p_dec = NULL;
4871 int i;
4873
4874 //Initialize p_param structure
4875 if (!p_param)
4876 {
4877 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameter passed\n",
4878 __func__);
4879 retval = NI_RETCODE_INVALID_PARAM;
4880 LRETURN;
4881 }
4882
4883 ni_log(NI_LOG_DEBUG, "%s\n", __func__);
4884
4885 //Initialize p_param structure
4886 memset(p_param, 0, sizeof(ni_xcoder_params_t));
4887
4888 p_dec = &p_param->dec_input_params;
4889
4890 p_param->source_width = width;
4891 p_param->source_height = height;
4892
4893 if(fps_num <= 0 || fps_denom <= 0)
4894 {
4895 fps_num = 30;
4896 fps_denom = 1;
4897 ni_log(NI_LOG_INFO, "%s(): FPS is not set, setting the default FPS to 30\n", __func__);
4898 }
4899
4900 p_param->fps_number = fps_num;
4901 p_param->fps_denominator = fps_denom;
4902
4903 p_dec->hwframes = 0;
4904 p_dec->mcmode = 0;
4905 p_dec->nb_save_pkt = 0;
4906 p_dec->enable_out1 = 0;
4907 p_dec->enable_out2 = 0;
4908 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
4909 {
4910 p_dec->force_8_bit[i] = 0;
4911 p_dec->semi_planar[i] = 0;
4912 p_dec->crop_mode[i] = NI_DEC_CROP_MODE_AUTO;
4913 p_dec->crop_whxy[i][0] = width;
4914 p_dec->crop_whxy[i][1] = height;
4915 p_dec->crop_whxy[i][2] = 0;
4916 p_dec->crop_whxy[i][3] = 0;
4917 p_dec->scale_wh[i][0] = 0;
4918 p_dec->scale_wh[i][1] = 0;
4919 p_dec->scale_long_short_edge[i] = 0;
4920 p_dec->scale_resolution_ceil[i] = 2;
4921 p_dec->scale_round[i] = -1;
4922 }
4924 p_dec->decoder_low_delay = 0;
4925 p_dec->force_low_delay = false;
4926 p_dec->enable_low_delay_check = 0;
4927 p_dec->decoder_disable_reorder = 0;
4929 p_dec->custom_sei_passthru = -1;
4932 p_dec->enable_advanced_ec = 1;
4934 p_dec->enable_ppu_scale_adapt = 0;
4935 p_dec->enable_ppu_scale_limit = 0;
4936 p_dec->max_extra_hwframe_cnt = 255; //uint8_max
4937 p_dec->pkt_pts_unchange = 0;
4938 p_dec->enable_all_sei_passthru = 0;
4939 p_dec->enable_follow_iframe = 0;
4941#ifdef XCODER_311
4942 p_dec->disable_adaptive_buffers = 1;
4943 p_dec->min_packets_delay = true;
4944 p_dec->reduce_dpb_delay = 1;
4945#else
4946 p_dec->disable_adaptive_buffers = 0;
4947 p_dec->min_packets_delay = false;
4948 p_dec->reduce_dpb_delay = 0;
4949#endif
4950 p_dec->survive_stream_err = 0;
4951 p_dec->skip_extra_headers = 0;
4952
4953 //-------init unused param start----------
4954
4955 p_param->bitrate = (int)bit_rate;
4956 p_param->reconf_demo_mode = 0; // for encoder reconfiguration testing
4957 p_param->force_pic_qp_demo_mode = 0;
4958 p_param->force_frame_type = 0;
4959 p_param->hdrEnableVUI = 0;
4960 p_param->cacheRoi = 0;
4961 p_param->low_delay_mode = 0;
4962 p_param->padding = 1;
4963 p_param->generate_enc_hdrs = 0;
4964 p_param->use_low_delay_poc_type = 0;
4965 p_param->dolby_vision_profile = 0;
4966
4967 // encoder stream header VUI setting
4968 p_param->color_primaries = 2; // default COL_PRI_UNSPECIFIED
4969 p_param->color_transfer_characteristic = 2; // default COL_TRC_UNSPECIFIED
4970 p_param->color_space = 2; // default COL_SPC_UNSPECIFIED
4971 p_param->sar_num = 0; // default SAR numerator 0
4972 p_param->sar_denom = 1; // default SAR denominator 1
4973 p_param->video_full_range_flag = -1;
4974
4975 //-------init unused param done----------
4976
4977END:
4978
4979 return retval;
4980}
4981
4982// read demo reconfig data file and parse out reconfig key/values in the format:
4983// key:val1,val2,val3,...val9 (max 9 values); only digit/:/,/newline is allowed
4984ni_retcode_t ni_parse_reconf_file(const char *reconf_file,
4986{
4987 char keyChar[10] = "";
4988 int key;
4989 char valChar[10] = "";
4990 int val;
4991 int valIdx = 1;
4992 int parseKey = 1;
4993 int idx = 0;
4994 int readc = EOF;
4995 FILE *reconf = NULL;
4996
4997 if (!reconf_file)
4998 {
4999 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5000 __func__);
5002 }
5003
5004 ni_fopen(&reconf, reconf_file, "r");
5005 if (!reconf)
5006 {
5007 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): Cannot open reconfig_file: %s\n",
5008 NI_ERRNO, __func__, reconf_file);
5010 }
5012
5013 while ((readc = fgetc(reconf)) != EOF)
5014 {
5015 //parse lines
5016 if (isdigit(readc))
5017 {
5018 if (parseKey)
5019 {
5020 ni_strncat(keyChar, 10, (const char *)(&readc), 1);
5021 }
5022 else
5023 {
5024 ni_strncat(valChar, 10, (const char *)(&readc), 1);
5025 }
5026 }
5027 else if (readc == ':')
5028 {
5029 parseKey = 0;
5030 key = atoi(keyChar);
5031 hash_map[idx][0] = key;
5032 }
5033 else if (readc == ',')
5034 {
5036 {
5038 "ERROR: Number of entries per line in reconfig file is greater then the "
5039 "limit of %d\n",
5041 retval = NI_RETCODE_INVALID_PARAM;
5042 break;
5043 }
5044 val = atoi(valChar);
5045 hash_map[idx][valIdx] = val;
5046 valIdx++;
5047 memset(valChar, 0, 10);
5048 }
5049 else if (readc == '\n')
5050 {
5052 {
5054 "ERROR: Number of lines in reconfig file is greater then the "
5055 "limit of %d\n",
5057 retval = NI_RETCODE_INVALID_PARAM;
5058 break;
5059 }
5060 parseKey = 1;
5061 val = atoi (valChar);
5062 hash_map[idx][valIdx] = val;
5063 valIdx = 1;
5064 memset(keyChar,0,10);
5065 memset(valChar,0,10);
5066 idx ++;
5067 }
5068 else
5069 {
5070 ni_log(NI_LOG_ERROR, "ERROR: character %c in reconfig file. this may lead to mistaken reconfiguration values\n", readc);
5071 }
5072 }
5073
5074 fclose(reconf);
5075
5076 if (NI_RETCODE_SUCCESS == retval && parseKey != 1)
5077 {
5079 "ERROR %d: %s(): Incorrect format / "
5080 "incomplete Key/Value pair in reconfig_file: %s\n",
5081 NI_ERRNO, __func__, reconf_file);
5083 }
5084
5085 return retval;
5086}
5087
5089 int8_t qp_map[][NI_CUSTOMIZE_ROI_QP_NUM])
5090{
5091 char valChar[5] = "";
5092 int val;
5093 int negative = 0;
5094 int qpIdx = 0;
5095 int levelIdx = 0;
5096 int readc = EOF;
5097 FILE *reconf = NULL;
5098
5099 if (!customize_file)
5100 {
5101 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5102 __func__);
5104 }
5105
5106 ni_fopen(&reconf, customize_file, "r");
5107 if (!reconf)
5108 {
5109 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): Cannot open reconfig_file: %s\n",
5110 NI_ERRNO, __func__, customize_file);
5112 }
5114
5115 while ((readc = fgetc(reconf)) != EOF)
5116 {
5117 //parse lines
5118 if (isdigit(readc))
5119 {
5120 ni_strncat(valChar, 5, (const char *)(&readc), 1);
5121 }
5122 else if (readc == '-') {
5123 negative = 1;
5124 }
5125 else if (readc == ',')
5126 {
5127 if (qpIdx >= NI_CUSTOMIZE_ROI_QP_NUM || levelIdx >= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL)
5128 {
5130 "ERROR: Number of qpIdx %d greater then the limit of %d or"
5131 "Number of levelIdx %d greater then the limit of %d\n",
5133 retval = NI_RETCODE_INVALID_PARAM;
5134 break;
5135 }
5136 if (!negative) {
5137 val = clip3(0, NI_MAX_QP_INFO, atoi(valChar));
5138 qp_map[levelIdx][qpIdx] = val;
5139 } else {
5140 val = clip3(0, 32, atoi(valChar));
5141 qp_map[levelIdx][qpIdx] = val * -1;
5142 }
5143 negative = 0;
5144 memset(valChar, 0, 5);
5145 qpIdx++;
5146 }
5147 else if (readc == '\n')
5148 {
5149 if (qpIdx >= NI_CUSTOMIZE_ROI_QP_NUM || levelIdx >= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL)
5150 {
5152 "ERROR: Number of qpIdx %d greater then the limit of %d or"
5153 "Number of levelIdx %d greater then the limit of %d\n",
5155 retval = NI_RETCODE_INVALID_PARAM;
5156 break;
5157 }
5158 if (!negative) {
5159 val = clip3(0, NI_MAX_QP_INFO, atoi(valChar));
5160 qp_map[levelIdx][qpIdx] = val;
5161 } else {
5162 val = clip3(0, 32, atoi(valChar));
5163 qp_map[levelIdx][qpIdx] = val * -1;
5164 }
5165 negative = 0;
5166 memset(valChar, 0, 5);
5167 qpIdx = 0;
5168 levelIdx++;
5169 }
5170 else
5171 {
5172 ni_log(NI_LOG_ERROR, "ERROR: character %c in reconfig file. this may lead to mistaken reconfiguration values\n", readc);
5173 }
5174 }
5175 fclose(reconf);
5176
5177 return retval;
5178}
5179
5180
5181#undef atoi
5182#undef atof
5183#define atoi(p_str) ni_atoi(p_str, &b_error)
5184#define atof(p_str) ni_atof(p_str, &b_error)
5185#define atobool(p_str) (ni_atobool(p_str, &b_error))
5186/*!*****************************************************************************
5187* \brief Set value referenced by name in decoder parameters structure
5188*
5189* \param[in] p_params Pointer to a user allocated ni_xcoder_params_t (used
5190* for decoder too for now ) to find and set a particular
5191* parameter
5192* \param[in] name String represented parameter name to search
5193* \param[in] value Parameter value to set
5194*
5195* \return On success
5196* NI_RETCODE_SUCCESS
5197* On failure
5198* NI_RETCODE_FAILURE
5199* NI_RETCODE_INVALID_PARAM
5200*******************************************************************************/
5202 const char *name, char *value)
5203{
5204 bool b_error = false;
5205 bool bNameWasBool = false;
5206 bool bValueWasNull = !value;
5207 ni_decoder_input_params_t* p_dec = NULL;
5208 char nameBuf[64] = { 0 };
5209 const char delim[2] = ",";
5210 const char xdelim[2] = "x";
5211 char *chunk;//for parsing out multi param input
5212 int i, j, k;
5213
5214 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
5215
5216 if (!p_params)
5217 {
5218 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5219 __func__);
5221 }
5222
5223 if (!name)
5224 {
5225 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
5226 __func__);
5228 }
5229 p_dec = &p_params->dec_input_params;
5230
5231 // skip -- prefix if provided
5232 if (name[0] == '-' && name[1] == '-')
5233 {
5234 name += 2;
5235 }
5236
5237 // s/_/-/g
5238 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
5239 {
5240 char* c;
5241 ni_strcpy(nameBuf, sizeof(nameBuf), name);
5242 while ((c = strchr(nameBuf, '_')) != 0)
5243 {
5244 *c = '-';
5245 }
5246 name = nameBuf;
5247 }
5248
5249 if (!value)
5250 {
5251 value = "true";
5252 }
5253 else if (value[0] == '=')
5254 {
5255 value++;
5256 }
5257
5258#if defined(_MSC_VER)
5259#define OPT(STR) else if (!_stricmp(name, STR))
5260#define OPT2(STR1, STR2) \
5261 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2))
5262#else
5263#define OPT(STR) else if (!strcasecmp(name, STR))
5264#define OPT2(STR1, STR2) else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2))
5265#endif
5266 if (0); // suppress cppcheck
5268 {
5269 if (!strncmp(value, "hw", sizeof("hw"))){
5270 p_dec->hwframes = 1;
5271 }
5272 else if (!strncmp(value, "sw", sizeof("sw"))) {
5273 p_dec->hwframes = 0;
5274 }
5275 else{
5276 ni_log(NI_LOG_ERROR, "ERROR: %s(): out can only be <hw,sw> got %s\n",
5277 __func__, value);
5279 }
5280 }
5282 {
5283 if (atoi(value) == 1)
5284 p_dec->enable_out1 = 1;
5285 }
5287 {
5288 if (atoi(value) == 1)
5289 p_dec->enable_out2 = 1;
5290 }
5292 {
5293 if (atoi(value) == 1)
5294 p_dec->force_8_bit[0] = 1;
5295 }
5297 {
5298 if (atoi(value) == 1)
5299 p_dec->force_8_bit[1] = 1;
5300 }
5302 {
5303 if (atoi(value) == 1)
5304 p_dec->force_8_bit[2] = 1;
5305 }
5307 {
5308 if (atoi(value) == 1 || atoi(value) == 2)
5309 p_dec->semi_planar[0] = atoi(value);
5310 }
5312 {
5313 if (atoi(value) == 1 || atoi(value) == 2)
5314 p_dec->semi_planar[1] = atoi(value);
5315 }
5317 {
5318 if (atoi(value) == 1 || atoi(value) == 2)
5319 p_dec->semi_planar[2] = atoi(value);
5320 }
5322 {
5323 if (!strncmp(value, "manual", sizeof("manual"))) {
5325 }
5326 else if (!strncmp(value, "auto", sizeof("auto"))) {
5327 p_dec->crop_mode[0] = NI_DEC_CROP_MODE_AUTO;
5328 }
5329 else{
5331 "ERROR: %s():cropMode0 input can only be <manual,auto> got %s\n",
5332 __func__, value);
5334 }
5335 }
5337 {
5338 if (!strncmp(value, "manual", sizeof("manual"))) {
5340 }
5341 else if (!strncmp(value, "auto", sizeof("auto"))) {
5342 p_dec->crop_mode[1] = NI_DEC_CROP_MODE_AUTO;
5343 }
5344 else {
5346 "ERROR: %s():cropMode1 input can only be <manual,auto> got %s\n",
5347 __func__, value);
5349 }
5350 }
5352 {
5353 if (!strncmp(value, "manual", sizeof("manual"))) {
5355 }
5356 else if (!strncmp(value, "auto", sizeof("auto"))) {
5357 p_dec->crop_mode[2] = NI_DEC_CROP_MODE_AUTO;
5358 }
5359 else {
5361 "ERROR: %s():cropMode2 input can only be <manual,auto> got %s\n",
5362 __func__, value);
5364 }
5365 }
5367 {
5368 char *saveptr = NULL;
5369 chunk = ni_strtok(value, delim, &saveptr);
5370 for (i = 0; i < 4; i++)
5371 {
5372 if (chunk != NULL)
5373 {
5374 j = k = 0;
5375 while (chunk[j])
5376 {
5377 if (chunk[j] != '\"' && chunk[j] != '\'')
5378 {
5379 p_dec->cr_expr[0][i][k] = chunk[j];
5380 k++;
5381 }
5383 {
5385 }
5386 }
5387 chunk = ni_strtok(NULL, delim, &saveptr);
5388 }
5389 else if (i == 2 ) //default offsets to centered image if not specified, may need recalc
5390 {
5391 ni_strcpy(p_dec->cr_expr[0][i], sizeof(p_dec->cr_expr[0][i]), "in_w/2-out_w/2");
5392 }
5393 else if (i == 3)
5394 {
5395 ni_strcpy(p_dec->cr_expr[0][i], sizeof(p_dec->cr_expr[0][i]), "in_h/2-out_h/2");
5396 } else
5397 {
5399 }
5400 }
5401 }
5403 {
5404 char *saveptr = NULL;
5405 chunk = ni_strtok(value, delim, &saveptr);
5406 for (i = 0; i < 4; i++)
5407 {
5408 if (chunk != NULL)
5409 {
5410 j = k = 0;
5411 while (chunk[j])
5412 {
5413 if (chunk[j] != '\"' && chunk[j] != '\'')
5414 {
5415 p_dec->cr_expr[1][i][k] = chunk[j];
5416 k++;
5417 }
5419 {
5421 }
5422 }
5423 chunk = ni_strtok(NULL, delim, &saveptr);
5424 }
5425 else if (i == 2) //default offsets to centered image if not specified, may need recalc
5426 {
5427 ni_strcpy(p_dec->cr_expr[1][i], sizeof(p_dec->cr_expr[1][i]), "in_w/2-out_w/2");
5428 }
5429 else if (i == 3)
5430 {
5431 ni_strcpy(p_dec->cr_expr[1][i], sizeof(p_dec->cr_expr[1][i]), "in_h/2-out_h/2");
5432 }
5433 else
5434 {
5436 }
5437 }
5438 }
5440 {
5441 char *saveptr = NULL;
5442 chunk = ni_strtok(value, delim, &saveptr);
5443 for (i = 0; i < 4; i++)
5444 {
5445 if (chunk != NULL)
5446 {
5447 j = k = 0;
5448 while (chunk[j])
5449 {
5450 if (chunk[j] != '\"' && chunk[j] != '\'')
5451 {
5452 p_dec->cr_expr[2][i][k] = chunk[j];
5453 k++;
5454 }
5456 {
5458 }
5459 }
5460 chunk = ni_strtok(NULL, delim, &saveptr);
5461 }
5462 else if (i == 2) //default offsets to centered image if not specified, may need recalc
5463 {
5464 ni_strcpy(p_dec->cr_expr[2][i], sizeof(p_dec->cr_expr[2][i]), "in_w/2-out_w/2");
5465 }
5466 else if (i == 3)
5467 {
5468 ni_strcpy(p_dec->cr_expr[2][i], sizeof(p_dec->cr_expr[2][i]), "in_h/2-out_h/2");
5469 }
5470 else
5471 {
5473 }
5474 }
5475 }
5477 {
5478 chunk = value;
5479 i = 0; // 'x' character counter
5480 while (*chunk++) {
5481 if (*chunk == xdelim[0]) {
5482 i++;
5483 }
5484 }
5485 if (i != 1) {
5487 }
5488 chunk = NULL;
5489
5490 char *saveptr = NULL;
5491 chunk = ni_strtok(value, xdelim, &saveptr);
5492 for (i = 0; i < 2; i++)
5493 {
5494 if (chunk != NULL)
5495 {
5496 j = k = 0;
5497 while (chunk[j])
5498 {
5499 if (chunk[j] != '\"' && chunk[j] != '\'')
5500 {
5501 p_dec->sc_expr[0][i][k] = chunk[j];
5502 k++;
5503 }
5505 {
5507 }
5508 }
5509 chunk = ni_strtok(NULL, xdelim, &saveptr);
5510 }
5511 else
5512 {
5514 }
5515 }
5516 }
5518 {
5519 chunk = value;
5520 i = 0; // 'x' character counter
5521 while (*chunk++) {
5522 if (*chunk == xdelim[0]) {
5523 i++;
5524 }
5525 }
5526 if (i != 1) {
5528 }
5529 chunk = NULL;
5530
5531 char *saveptr = NULL;
5532 chunk = ni_strtok(value, xdelim, &saveptr);
5533 for (i = 0; i < 2; i++)
5534 {
5535 if (chunk != NULL)
5536 {
5537 j = k = 0;
5538 while (chunk[j])
5539 {
5540 if (chunk[j] != '\"' && chunk[j] != '\'')
5541 {
5542 p_dec->sc_expr[1][i][k] = chunk[j];
5543 k++;
5544 }
5546 {
5548 }
5549 }
5550 chunk = ni_strtok(NULL, xdelim, &saveptr);
5551 }
5552 else
5553 {
5555 }
5556 }
5557 }
5559 {
5560 chunk = value;
5561 i = 0; // 'x' character counter
5562 while (*chunk++) {
5563 if (*chunk == xdelim[0]) {
5564 i++;
5565 }
5566 }
5567 if (i != 1) {
5569 }
5570 chunk = NULL;
5571
5572 char *saveptr = NULL;
5573 chunk = ni_strtok(value, xdelim, &saveptr);
5574 for (i = 0; i < 2; i++)
5575 {
5576 if (chunk != NULL)
5577 {
5578 j = k = 0;
5579 while (chunk[j])
5580 {
5581 if (chunk[j] != '\"' && chunk[j] != '\'')
5582 {
5583 p_dec->sc_expr[2][i][k] = chunk[j];
5584 k++;
5585 }
5587 {
5589 }
5590 }
5591 chunk = ni_strtok(NULL, xdelim, &saveptr);
5592 }
5593 else
5594 {
5596 }
5597 }
5598 }
5600 {
5601 if ((atoi(value) < 0) || (atoi(value) > 2))
5602 {
5604 }
5605 p_dec->scale_long_short_edge[0] = atoi(value);
5606 }
5608 {
5609 if ((atoi(value) < 0) || (atoi(value) > 2))
5610 {
5612 }
5613 p_dec->scale_long_short_edge[1] = atoi(value);
5614 }
5616 {
5617 if ((atoi(value) < 0) || (atoi(value) > 2))
5618 {
5620 }
5621 p_dec->scale_long_short_edge[2] = atoi(value);
5622 }
5624 {
5625 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5626 {
5627 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5628 "and must be even number and less than or equal to 128. Got: %s\n",
5629 __func__, NI_DEC_PARAM_SCALE_0_RES_CEIL, value);
5630
5632 }
5633 p_dec->scale_resolution_ceil[0] = atoi(value);
5634 }
5636 {
5637 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5638 {
5639 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5640 "and must be even number and less than or equal to 128. Got: %s\n",
5641 __func__, NI_DEC_PARAM_SCALE_1_RES_CEIL, value);
5643 }
5644 p_dec->scale_resolution_ceil[1] = atoi(value);
5645 }
5647 {
5648 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5649 {
5650 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5651 "and must be even number and less than or equal to 128. Got: %s\n",
5652 __func__, NI_DEC_PARAM_SCALE_2_RES_CEIL, value);
5654 }
5655 p_dec->scale_resolution_ceil[2] = atoi(value);
5656 }
5658 {
5659 if (!strncmp(value, "up", sizeof("up"))){
5660 p_dec->scale_round[0] = 0;
5661 }
5662 else if (!strncmp(value, "down", sizeof("down"))) {
5663 p_dec->scale_round[0] = 1;
5664 }
5665 else{
5666 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5667 __func__, NI_DEC_PARAM_SCALE_0_ROUND, value);
5669 }
5670 }
5672 {
5673 if (!strncmp(value, "up", sizeof("up"))){
5674 p_dec->scale_round[1] = 0;
5675 }
5676 else if (!strncmp(value, "down", sizeof("down"))) {
5677 p_dec->scale_round[1] = 1;
5678 }
5679 else{
5680 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5681 __func__, NI_DEC_PARAM_SCALE_1_ROUND, value);
5683 }
5684 }
5686 {
5687 if (!strncmp(value, "up", sizeof("up"))){
5688 p_dec->scale_round[2] = 0;
5689 }
5690 else if (!strncmp(value, "down", sizeof("down"))) {
5691 p_dec->scale_round[2] = 1;
5692 }
5693 else{
5694 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5695 __func__, NI_DEC_PARAM_SCALE_2_ROUND, value);
5697 }
5698 }
5700 {
5701 if ((atoi(value) != 0) && (atoi(value) != 1))
5702 {
5704 }
5705 p_dec->mcmode = atoi(value);
5706 }
5708 {
5709 if (atoi(value) < 0)
5710 {
5712 }
5713 p_dec->nb_save_pkt = atoi(value);
5714 }
5716 {
5717 if ((atoi(value) < NI_MIN_KEEP_ALIVE_TIMEOUT) ||
5719 {
5721 }
5722 p_dec->keep_alive_timeout = atoi(value);
5723 }
5725 {
5726 if (atoi(value) < 0)
5727 {
5729 }
5730 p_dec->decoder_low_delay = atoi(value);
5731 }
5733 {
5734 if ((atoi(value) != 0) && (atoi(value) != 1))
5735 {
5737 }
5738 p_dec->force_low_delay = atoi(value);
5739 }
5741 {
5742 if (atoi(value) < 0)
5743 {
5745 }
5746 p_dec->enable_low_delay_check = atoi(value);
5747 }
5749 {
5750 if (atoi(value) < 0)
5751 {
5753 }
5754 p_dec->decoder_disable_reorder = atoi(value);
5755 }
5757 {
5758 if ((atoi(value) != 0) && (atoi(value) != 1))
5759 {
5761 }
5762 p_dec->min_packets_delay = atoi(value);
5763 }
5765 {
5766 if (atoi(value) != NI_ENABLE_USR_DATA_SEI_PASSTHRU &&
5768 {
5770 }
5771 p_dec->enable_user_data_sei_passthru = atoi(value);
5772 }
5774 {
5775 if (atoi(value) < NI_MIN_CUSTOM_SEI_PASSTHRU ||
5777 {
5779 }
5780 p_dec->custom_sei_passthru = atoi(value);
5781 }
5783 {
5785 {
5787 }
5788 p_dec->svct_decoding_layer = atoi(value);
5789 }
5791 {
5792 if (atoi(value) >= NI_DDR_PRIORITY_MAX ||
5793 atoi(value) <= NI_DDR_PRIORITY_NONE)
5794 {
5796 }
5797 p_params->ddr_priority_mode = atoi(value);
5798 }
5800 {
5801 if (strncmp(value, "tolerant", sizeof("tolerant")) == 0) {
5803 } else if (strncmp(value, "ignore", sizeof("ignore")) == 0) {
5805 } else if (strncmp(value, "skip", sizeof("skip")) == 0) {
5807 } else if (strncmp(value, "best_effort", sizeof("best_effort")) == 0) {
5809 } else if (strncmp(value, "limited_error", sizeof("limited_error")) == 0) {
5811 } else if (strncmp(value, "best_effort_out_dc", sizeof("best_effort_out_dc")) == 0) {
5813 } else {
5815 }
5816 }
5818 {
5819 if (atoi(value) != 0 &&
5820 atoi(value) != 1 &&
5821 atoi(value) != 2)
5822 {
5824 }
5825 p_dec->enable_advanced_ec = atoi(value);
5826 }
5828 {
5829 if (atoi(value) < 0 || (atoi(value) > 100))
5830 {
5832 }
5833 p_dec->error_ratio_threshold = atoi(value);
5834 }
5836 {
5837 if (atoi(value) < 0 || (atoi(value) > 2))
5838 {
5840 }
5841 p_dec->enable_ppu_scale_adapt = atoi(value);
5842 }
5844 {
5845 if (atoi(value) < 0 || (atoi(value) > 1))
5846 {
5848 }
5849 p_dec->enable_ppu_scale_limit = atoi(value);
5850 }
5852 {
5853 if (atoi(value) < 0 || atoi(value) > 255)
5854 {
5856 }
5857 p_dec->max_extra_hwframe_cnt = atoi(value);
5858 }
5860 {
5861 if (atoi(value) < 0 || atoi(value) > 1)
5862 {
5864 }
5865 p_dec->skip_pts_guess = atoi(value);
5866 }
5868 {
5869 if (atoi(value) != 0 && atoi(value) != 1)
5870 {
5872 }
5873 p_dec->pkt_pts_unchange = atoi(value);
5874 }
5876 {
5877 if (atoi(value) < 0 ||
5878 atoi(value) > 1)
5879 {
5881 }
5882 p_dec->enable_all_sei_passthru = atoi(value);
5883 }
5885 {
5886 if (atoi(value) != 0 && atoi(value) != 1)
5887 {
5889 }
5890 p_dec->enable_follow_iframe = atoi(value);
5891 }
5893 {
5894 if (atoi(value) < 0 ||
5895 atoi(value) > 1)
5896 {
5898 }
5899 p_dec->disable_adaptive_buffers = atoi(value);
5900 }
5902 {
5903 if (atoi(value) < 0 || atoi(value) > 1)
5904 {
5906 }
5907 p_dec->survive_stream_err = atoi(value);
5908 }
5910 {
5911 if ((atoi(value) != 0) && (atoi(value) != 1))
5912 {
5914 }
5915 p_dec->reduce_dpb_delay = atoi(value);
5916 }
5918 {
5919 if ((atoi(value) != 0) && (atoi(value) != 1))
5920 {
5922 }
5923 p_dec->skip_extra_headers = atoi(value);
5924 }
5926 {
5927 if ((atoi(value) != 0) && (atoi(value) != 1))
5928 {
5930 }
5931 p_params->enableCpuAffinity = atoi(value);
5932 }
5933 else
5934 {
5936 }
5937
5938#undef OPT
5939#undef atobool
5940#undef atoi
5941#undef atof
5942 b_error |= bValueWasNull && !bNameWasBool;
5943
5944 ni_log(NI_LOG_TRACE, "%s: exit, b_error=%d\n", __func__, b_error);
5945
5947}
5948
5949#undef atoi
5950#undef atof
5951#define atoi(p_str) ni_atoi(p_str, &b_error)
5952#define atof(p_str) ni_atof(p_str, &b_error)
5953#define atobool(p_str) (ni_atobool(p_str, &b_error))
5954
5955/*!*****************************************************************************
5956 * \brief Set value referenced by name in encoder parameters structure
5957 *
5958 * \param[in] p_params Pointer to a user allocated ni_xcoder_params_t
5959 * to find and set a particular parameter
5960 * \param[in] name String represented parameter name to search
5961 * \param[in] value Parameter value to set
5962*
5963 * \return On success
5964 * NI_RETCODE_SUCCESS
5965 * On failure
5966 * NI_RETCODE_FAILURE
5967 * NI_RETCODE_INVALID_PARAM
5968 ******************************************************************************/
5970 const char *name, const char *value)
5971{
5972 bool b_error = false;
5973 bool bNameWasBool = false;
5974 bool bValueWasNull = !value;
5975 ni_encoder_cfg_params_t *p_enc = NULL;
5976 char nameBuf[64] = { 0 };
5977 int i,j,k;
5978
5979 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
5980
5981 if (!p_params)
5982 {
5983 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5984 __func__);
5986 }
5987
5988 if ( !name )
5989 {
5990 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
5991 __func__);
5993 }
5994 p_enc = &p_params->cfg_enc_params;
5995 // skip -- prefix if provided
5996 if (name[0] == '-' && name[1] == '-')
5997 {
5998 name += 2;
5999 }
6000
6001 // s/_/-/g
6002 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
6003 {
6004 char* c;
6005 ni_strcpy(nameBuf, sizeof(nameBuf), name);
6006 while ((c = strchr(nameBuf, '_')) != 0)
6007 {
6008 *c = '-';
6009 }
6010 name = nameBuf;
6011 }
6012
6013 if (!value)
6014 {
6015 value = "true";
6016 }
6017 else if (value[0] == '=')
6018 {
6019 value++;
6020 }
6021
6022#if defined(_MSC_VER)
6023#define OPT(STR) else if (!_stricmp(name, STR))
6024#define OPT2(STR1, STR2) \
6025 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2))
6026#else
6027#define OPT(STR) else if (!strcasecmp(name, STR))
6028#define OPT2(STR1, STR2) else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2))
6029#endif
6030#define COMPARE(STR1, STR2, STR3) \
6031 if ((atoi(STR1) > (STR2)) || (atoi(STR1) < (STR3))) \
6032 { \
6033 return NI_RETCODE_PARAM_ERROR_OOR; \
6034 }
6035 if (0); // suppress cppcheck
6037 {
6038 if (AV_CODEC_DEFAULT_BITRATE == p_params->bitrate)
6039 {
6040 if (atoi(value) > NI_MAX_BITRATE)
6041 {
6043 }
6044 if (atoi(value) < NI_MIN_BITRATE)
6045 {
6047 }
6048 p_params->bitrate = atoi(value);
6049 }
6050 }
6052 {
6053 p_params->reconf_demo_mode = atoi(value); // for encoder reconfiguration testing
6054 }
6056 {
6057 ni_retcode_t retval = ni_parse_reconf_file(value, p_params->reconf_hash);
6058 if (retval != NI_RETCODE_SUCCESS) // for encoder reconfiguration testing
6059 {
6060 return retval;
6061 }
6062 }
6064 {
6065 // for encoder reconfiguration testing
6066 p_params->roi_demo_mode = atoi(value);
6067 if ((p_params->roi_demo_mode < 0) || (p_params->roi_demo_mode > 2))
6068 {
6070 }
6071 }
6073 {
6074 if (0 > atoi(value))
6075 {
6077 }
6078 p_params->low_delay_mode = atoi(value);
6079 }
6081 {
6082 if (atoi(value) < 0 || atoi(value) > 2)
6083 {
6085 }
6086 p_params->minFramesDelay = atoi(value);
6087 }
6089 {
6090 p_params->padding = atoi(value);
6091 }
6092#ifndef DEPRECATION_AS_ERROR
6094 {
6095 if (0 != atoi(value) && 1 != atoi(value))
6096 {
6098 }
6099 p_params->generate_enc_hdrs = atoi(value);
6100 // genHdrs is deprecated in favour of libavcodec parameter -gen_global_headers
6102 }
6103#endif
6105 {
6106 if (0 != atoi(value) && 1 != atoi(value))
6107 {
6109 }
6110 p_params->use_low_delay_poc_type = atoi(value);
6111 }
6113 {
6114 if (QUADRA)
6115 {
6117 }
6118 p_params->force_frame_type = atoi(value);
6119 }
6121 {
6122 p_enc->profile = atoi(value);
6123 }
6125 {
6129 if (atof(value) <= 10)
6130 {
6131 p_enc->level_idc = (int)(10 * atof(value) + .5);
6132 }
6133 else
6134 {
6135 p_enc->level_idc = atoi(value);
6136 }
6137 }
6139 {
6140 p_enc->high_tier = atobool(value);
6141 }
6143 {
6144 p_params->log = atoi(value);
6145 if (b_error)
6146 {
6147 b_error = false;
6148 p_params->log = ni_parse_name(value, g_xcoder_log_names, &b_error) - 1;
6149 }
6150 }
6152 {
6153 if ((atoi(value) > NI_MAX_GOP_PRESET_IDX) || (atoi(value) < NI_MIN_GOP_PRESET_IDX))
6154 {
6156 }
6157 p_enc->gop_preset_index = atoi(value);
6158 }
6160 {
6162 {
6164 }
6165
6166 p_enc->use_recommend_enc_params = atoi(value);
6167 }
6169 {
6170 if (QUADRA)
6171 {
6173 }
6174 if (((atoi(value) > NI_MAX_CU_SIZE_MODE) || (atoi(value) < NI_MIN_CU_SIZE_MODE)) && (atoi(value) != NI_DEFAULT_CU_SIZE_MODE))
6175 {
6177 }
6178
6179 p_enc->cu_size_mode = atoi(value);
6180 }
6182 {
6183 if (QUADRA)
6184 {
6186 }
6187 if ((atoi(value) > NI_MAX_MAX_NUM_MERGE) || (atoi(value) < NI_MIN_MAX_NUM_MERGE))
6188 {
6190 }
6191
6192 p_enc->max_num_merge = atoi(value);
6193 }
6195 {
6196 if (QUADRA)
6197 {
6199 }
6200 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6201 {
6203 }
6204
6205 p_enc->enable_dynamic_8x8_merge = atoi(value);
6206 }
6208 {
6209 if (QUADRA)
6210 {
6212 }
6213 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6214 {
6216 }
6217
6218 p_enc->enable_dynamic_16x16_merge = atoi(value);
6219 }
6221 {
6222 if (QUADRA)
6223 {
6225 }
6226 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6227 {
6229 }
6230
6231 p_enc->enable_dynamic_32x32_merge = atoi(value);
6232 }
6234 {
6235 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6236 {
6238 }
6239
6240 p_enc->rc.enable_rate_control = atoi(value);
6241 }
6243 {
6244 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6245 {
6247 }
6248
6249 p_enc->rc.enable_cu_level_rate_control = atoi(value);
6250 }
6252 {
6253 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6254 {
6256 }
6257 p_enc->rc.enable_hvs_qp = atoi(value);
6258 }
6260 {
6261 if (QUADRA)
6262 {
6264 }
6265 p_enc->rc.enable_hvs_qp_scale = atoi(value);
6266 }
6268 {
6269 p_enc->rc.hvs_qp_scale = atoi(value);
6270 }
6272 {
6273 p_enc->rc.min_qp = atoi(value);
6274 }
6276 {
6277 p_enc->rc.max_qp = atoi(value);
6278 }
6280 {
6281 if (QUADRA)
6282 {
6284 }
6285 p_enc->rc.max_delta_qp = atoi(value);
6286 }
6287#ifndef DEPRECATION_AS_ERROR
6289 {
6290 if ((atoi(value) > 51) || (atoi(value) < -1))
6291 {
6293 }
6294 p_enc->crf = atoi(value);
6295 }
6296#endif
6298 {
6299 p_enc->rc.vbv_buffer_size = atoi(value);
6300 if (QUADRA)
6301 {
6302 // RcInitDelay is deprecated and replaced with vbvBufferSize. But still accept the value.
6304 }
6305 }
6307 {
6308 p_enc->rc.vbv_buffer_size = atoi(value);
6309 }
6311 {
6312 p_enc->rc.vbv_max_rate = atoi(value);
6313 }
6315 {
6316 p_enc->rc.enable_filler = atoi(value);
6317 if (QUADRA)
6318 {
6319 // cbr is deprecated and replaced with fillerEnable. But still accept the value.
6321 }
6322 }
6324 {
6325 p_enc->rc.enable_filler = atoi(value);
6326 }
6328 {
6329 if (0 != atoi(value) && 1 != atoi(value))
6330 {
6332 }
6333 // Currenly pic skip is supported for low delay gops only - pic skip issues tracked by QDFW-1785/1958
6334 p_enc->rc.enable_pic_skip = atoi(value);
6335 }
6336#ifndef DEPRECATION_AS_ERROR
6338#else
6340#endif
6341 {
6342#ifdef _MSC_VER
6343 if (!_strnicmp(value, "ratio", 5))
6344#else
6345 if (!strncasecmp(value, "ratio", 5))
6346#endif
6347 {
6348 char value_buf[32] = {0};
6349 for (i = 0; i < sizeof(value_buf); i++)
6350 {
6351 if (value[i+6] == ']')
6352 {
6353 break;
6354 }
6355 value_buf[i] = value[i+6];
6356 }
6357 if (i == sizeof(value_buf) || atoi(value_buf) < 0)
6358 {
6360 }
6361
6362 p_enc->maxFrameSizeRatio = atoi(value_buf);
6363 }
6364 else
6365 {
6366 int size = atoi(value);
6367 if (size < NI_MIN_FRAME_SIZE)
6368 {
6370 }
6371 p_enc->maxFrameSize = (size > NI_MAX_FRAME_SIZE) ? NI_MAX_FRAME_SIZE : size;
6372 }
6373 }
6375 {
6376#ifdef _MSC_VER
6377 if (!_strnicmp(value, "ratio", 5))
6378#else
6379 if (!strncasecmp(value, "ratio", 5))
6380#endif
6381 {
6382 char value_buf[32] = {0};
6383 for (i = 0; i < sizeof(value_buf); i++)
6384 {
6385 if (value[i+6] == ']')
6386 {
6387 break;
6388 }
6389 value_buf[i] = value[i+6];
6390 }
6391 if (i == sizeof(value_buf) || atoi(value_buf) < 0)
6392 {
6394 }
6395
6396 p_enc->maxFrameSizeRatio = atoi(value_buf);
6397 }
6398 else
6399 {
6400 int size = atoi(value) / 8;
6401 if (size < NI_MIN_FRAME_SIZE)
6402 {
6404 }
6405 p_enc->maxFrameSize = (size > NI_MAX_FRAME_SIZE) ? NI_MAX_FRAME_SIZE : size;
6406 }
6407 }
6409 {
6410 if (0 != atoi(value) && 1 != atoi(value))
6411 {
6413 }
6414 p_enc->forced_header_enable = atoi(value);
6415 }
6417 {
6418 p_enc->roi_enable = atoi(value);
6419 }
6421 {
6422 p_enc->conf_win_top = atoi(value);
6423 }
6425 {
6426 p_enc->conf_win_bottom = atoi(value);
6427 }
6429 {
6430 p_enc->conf_win_left = atoi(value);
6431 }
6433 {
6434 p_enc->conf_win_right = atoi(value);
6435 }
6437 {
6438 p_enc->intra_period = atoi(value);
6439 //p_enc->bitrateWindow = p_enc->intra_period;
6440 }
6442 {
6443 if (atoi(value) > NI_MAX_BITRATE)
6444 {
6446 }
6447 if (atoi(value) < NI_MIN_BITRATE)
6448 {
6450 }
6451 p_enc->rc.trans_rate = atoi(value);
6452 }
6454 {
6455 if (atoi(value) <= 0 )
6456 {
6458 }
6459 p_params->fps_number = atoi(value);
6460 p_params->fps_denominator = 1;
6461 p_enc->frame_rate = p_params->fps_number;
6462 }
6464 {
6465 if (atoi(value) <= 0)
6466 {
6468 }
6469 p_params->fps_denominator = atoi(value);
6470 p_enc->frame_rate = (int)(p_params->fps_number / p_params->fps_denominator);
6471 }
6473 {
6474 if ((atoi(value) > NI_MAX_INTRA_QP) || (atoi(value) < NI_MIN_INTRA_QP))
6475 {
6477 }
6478
6479 p_enc->rc.intra_qp = atoi(value);
6480 }
6482 {
6483 if ((atoi(value) > NI_MAX_INTRA_QP_DELTA) ||
6484 (atoi(value) < NI_MIN_INTRA_QP_DELTA))
6485 {
6487 }
6488
6489 p_enc->rc.intra_qp_delta = atoi(value);
6490 }
6492 {
6493 if ((atoi(value) > NI_MAX_INTRA_QP) || (atoi(value) < NI_MIN_INTRA_QP))
6494 {
6496 }
6497 p_params->force_pic_qp_demo_mode = atoi(value);
6498 }
6500 {
6501 if (QUADRA)
6502 {
6504 }
6506 {
6508 }
6509 p_enc->decoding_refresh_type = atoi(value);
6510 }
6512 {
6513 if (0 != atoi(value) && 1 != atoi(value))
6514 {
6516 }
6517 p_enc->intra_reset_refresh = atoi(value);
6518 }
6519 // Rev. B: H.264 only parameters.
6521 {
6522 if (QUADRA)
6523 {
6525 }
6526 p_enc->enable_transform_8x8 = atoi(value);
6527 }
6529 {
6530 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6531 {
6533 }
6534 p_enc->slice_mode = atoi(value);
6535 }
6537 {
6538 p_enc->slice_arg = atoi(value);
6539 }
6541 {
6542 if (0 != atoi(value) && 1 != atoi(value))
6543 {
6545 }
6546 p_enc->entropy_coding_mode = atoi(value);
6547 }
6548// Rev. B: shared between HEVC and H.264
6550 {
6551 p_enc->intra_mb_refresh_mode = atoi(value);
6552 }
6554 {
6555 p_enc->intra_mb_refresh_arg = atoi(value);
6556 }
6558 {
6559 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6560 {
6562 }
6563 p_enc->rc.enable_mb_level_rc = atoi(value);
6564 if (QUADRA)
6565 {
6566 // mbLevelRcEnable will be deprecated and cuLevelRCEnable should be used instead. But still accept the value.
6568 }
6569 }
6571 {
6572 if ((atoi(value) > 255) || (atoi(value) < 0))
6573 {
6575 }
6577 }
6579 {
6580 if (atoi(value) != 0 && atoi(value) != 5)
6581 {
6583 }
6584 p_params->dolby_vision_profile = atoi(value);
6585 }
6587 {
6588 if ((atoi(value) > 3) || (atoi(value) < 1))
6589 {
6591 }
6592 p_enc->rdoLevel = atoi(value);
6593 }
6595 {
6596 const char delim[2] = ",";
6597 char *chunk;
6598#ifdef _MSC_VER
6599 char *v = _strdup(value);
6600#else
6601 char *v = strdup(value);
6602#endif
6603 char *saveptr = NULL;
6604 chunk = ni_strtok(v, delim, &saveptr);
6605 if (chunk != NULL)
6606 {
6607 if ((atoi(chunk) > 65535) || (atoi(chunk) < 0))
6608 {
6609 free(v);
6611 }
6612 p_enc->HDR10MaxLight = atoi(chunk);
6613 chunk = ni_strtok(NULL, delim, &saveptr);
6614 if (chunk != NULL)
6615 {
6616 if ((atoi(chunk) > 65535) || (atoi(chunk) < 0))
6617 {
6618 free(v);
6620 }
6621 p_enc->HDR10AveLight = atoi(chunk);
6622 p_enc->HDR10CLLEnable = 1; //Both param populated so enable
6623 free(v);
6624 }
6625 else
6626 {
6627 free(v);
6629 }
6630 }
6631 else
6632 {
6633 free(v);
6635 }
6636 }
6637
6639 {
6640#ifdef _MSC_VER
6641#define STRDUP(value) _strdup(value);
6642#else
6643#define STRDUP(value) strdup(value);
6644#endif
6645 const char G[2] = "G";
6646 const char B[2] = "B";
6647 const char R[2] = "R";
6648 const char W[2] = "W";
6649 const char L[2] = "L";
6650 const char P[2] = "P";
6651 const char parL[2] = "(";
6652 const char comma[2] = ",";
6653 const char parR[2] = ")";
6654 int synCheck_GBRWLPCP[8];
6655 int posCheck_GBRWL[5] = {0};
6656 char *chunk;//for parsing out more complex inputs
6657 char *subchunk;
6658 char *v = STRDUP(value);
6659 //basic check syntax correct
6660 for (i = 0; i<8; i++)
6661 {
6662 synCheck_GBRWLPCP[i] = 0;
6663 }
6664 chunk = v;
6665 i = 0; // character index
6666
6667 //count keys and punctuation, save indicies to be parsed
6668 while (*chunk) {
6669 if (*chunk == G[0])
6670 {
6671 synCheck_GBRWLPCP[0]++;
6672 posCheck_GBRWL[0] = i;
6673 }
6674 else if (*chunk == B[0])
6675 {
6676 synCheck_GBRWLPCP[1]++;
6677 posCheck_GBRWL[1] = i;
6678 }
6679 else if (*chunk == R[0])
6680 {
6681 synCheck_GBRWLPCP[2]++;
6682 posCheck_GBRWL[2] = i;
6683 }
6684 else if (*chunk == W[0])
6685 {
6686 synCheck_GBRWLPCP[3]++;
6687 posCheck_GBRWL[3] = i;
6688 }
6689 else if (*chunk == L[0])
6690 {
6691 synCheck_GBRWLPCP[4]++;
6692 posCheck_GBRWL[4] = i;
6693 }
6694 else if (*chunk == parL[0])
6695 {
6696 synCheck_GBRWLPCP[5]++;
6697 }
6698 else if (*chunk == comma[0])
6699 {
6700 synCheck_GBRWLPCP[6]++;
6701 }
6702 else if (*chunk == parR[0])
6703 {
6704 synCheck_GBRWLPCP[7]++;
6705 }
6706 chunk++;
6707 i++;
6708 }
6709 free(v);
6710 if (synCheck_GBRWLPCP[0] != 1 || synCheck_GBRWLPCP[1] != 1 || synCheck_GBRWLPCP[2] != 1 ||
6711 synCheck_GBRWLPCP[3] != 1 || synCheck_GBRWLPCP[4] != 1 || synCheck_GBRWLPCP[5] != 5 ||
6712 synCheck_GBRWLPCP[6] != 5 || synCheck_GBRWLPCP[7] != 5)
6713 {
6715 }
6716
6717 //Parse a key-value set like G(%hu, %hu)
6718#define GBRWLPARSE(OUT1,OUT2,OFF,IDX) \
6719{ \
6720 char *v = STRDUP(value); \
6721 chunk = v + posCheck_GBRWL[IDX]; \
6722 i = j = k = 0; \
6723 while (chunk != NULL) \
6724 { \
6725 if (*chunk == parL[0] && i == 1+(OFF)) \
6726 { \
6727 j = 1; \
6728 } \
6729 if((OFF) == 1 && *chunk != P[0] && i == 1) \
6730 { \
6731 break; \
6732 } \
6733 if (*chunk == parR[0]) \
6734 { \
6735 k = 1; \
6736 break; \
6737 } \
6738 i++; \
6739 chunk++; \
6740 } \
6741 if (!j || !k) \
6742 { \
6743 free(v); \
6744 return NI_RETCODE_PARAM_INVALID_VALUE; \
6745 } \
6746 subchunk = malloc(i - 1 - (OFF)); \
6747 if (subchunk == NULL) \
6748 { \
6749 free(v); \
6750 return NI_RETCODE_ERROR_MEM_ALOC; \
6751 } \
6752 memcpy(subchunk, v + posCheck_GBRWL[IDX] + 2 + (OFF), i - 2 - (OFF)); \
6753 subchunk[i - 2 - (OFF)] = '\0'; \
6754 char *saveptr = NULL; \
6755 chunk = ni_strtok(subchunk, comma, &saveptr); \
6756 if (chunk != NULL) \
6757 { \
6758 if(atoi(chunk) < 0) \
6759 { \
6760 free(v); \
6761 if(subchunk != NULL){ \
6762 free(subchunk); \
6763 } \
6764 return NI_RETCODE_PARAM_INVALID_VALUE; \
6765 } \
6766 *(OUT1) = atoi(chunk); \
6767 } \
6768 chunk = ni_strtok(NULL, comma, &saveptr); \
6769 if (chunk != NULL) \
6770 { \
6771 if(atoi(chunk) < 0) \
6772 { \
6773 free(v); \
6774 if(subchunk != NULL){ \
6775 free(subchunk); \
6776 } \
6777 return NI_RETCODE_PARAM_INVALID_VALUE; \
6778 } \
6779 *(OUT2) = atoi(chunk); \
6780 } \
6781 free(subchunk); \
6782 free(v); \
6783}
6784 GBRWLPARSE(&p_enc->HDR10dx0, &p_enc->HDR10dy0, 0, 0);
6785 GBRWLPARSE(&p_enc->HDR10dx1, &p_enc->HDR10dy1, 0, 1);
6786 GBRWLPARSE(&p_enc->HDR10dx2, &p_enc->HDR10dy2, 0, 2);
6787 GBRWLPARSE(&p_enc->HDR10wx, &p_enc->HDR10wy, 1, 3);
6788 GBRWLPARSE(&p_enc->HDR10maxluma, &p_enc->HDR10minluma, 0, 4);
6789 p_enc->HDR10Enable = 1;
6790 }
6792 {
6793 if (atoi(value)!= 0 && ((atoi(value) > 40 ) || (atoi(value) < 4)))
6794 {
6796 }
6797 p_enc->lookAheadDepth = atoi(value);
6798 }
6800 {
6801 if (atoi(value) != 0 && atoi(value) != 1)
6802 {
6804 }
6805 p_enc->hrdEnable = atoi(value);
6806 }
6808 {
6809 if ((atoi(value) != 0) && (atoi(value) != 1))
6810 {
6812 }
6813 p_enc->EnableAUD = atoi(value);
6814 }
6816 {
6817 if (atoi(value) != 0 && atoi(value) != 1)
6818 {
6820 }
6821 p_params->cacheRoi = atoi(value);
6822 }
6824 {
6825 if (atoi(value) != 0 && atoi(value) != 1)
6826 {
6828 }
6829 p_enc->long_term_ref_enable = atoi(value);
6830 }
6832 {
6833 p_enc->long_term_ref_interval = atoi(value);
6834 }
6836 {
6837 if (atoi(value) < 1 || atoi(value) > 2)
6838 {
6840 }
6841 p_enc->long_term_ref_count = atoi(value);
6842 }
6844 {
6845 if ((atoi(value) != 0) && (atoi(value) != 1))
6846 {
6848 }
6849 p_enc->EnableRdoQuant = atoi(value);
6850 }
6852 {
6853 if (QUADRA)
6854 {
6856 }
6857
6858 if ((atoi(value) < 0) || (atoi(value) > 3))
6859 {
6861 }
6862 p_enc->ctbRcMode = atoi(value);
6863 }
6865 {
6866 if (QUADRA)
6867 {
6869 }
6870
6871 p_enc->gopSize = atoi(value);
6872 }
6874 {
6875 if (QUADRA)
6876 {
6878 }
6879
6880 if ((atoi(value) != 0) && (atoi(value) != 1))
6881 {
6883 }
6884 p_enc->gopLowdelay = atoi(value);
6885 }
6887 {
6888 if (QUADRA)
6889 {
6891 }
6892 p_enc->gdrDuration = atoi(value);
6893 }
6895 {
6896 p_enc->ltrRefInterval = atoi(value);
6897 }
6899 {
6900 p_enc->ltrRefQpOffset = atoi(value);
6901 }
6903 {
6904 p_enc->ltrFirstGap = atoi(value);
6905 }
6908 {
6909 if ((atoi(value) != 0) && (atoi(value) != 1))
6910 {
6912 }
6913 p_enc->multicoreJointMode = atoi(value);
6914 }
6916 {
6917 if ((atoi(value) < 0) || (atoi(value) > 9))
6918 {
6920 }
6921 p_enc->qlevel = atoi(value);
6922 }
6924 {
6925 if ((atoi(value) > 12) || (atoi(value) < -12))
6926 {
6928 }
6929 p_enc->chromaQpOffset = atoi(value);
6930 }
6931 OPT(NI_ENC_PARAM_TOL_RC_INTER) { p_enc->tolCtbRcInter = (float)atof(value); }
6932 OPT(NI_ENC_PARAM_TOL_RC_INTRA) { p_enc->tolCtbRcIntra = (float)atof(value); }
6934 {
6935 if ((atoi(value) > 300) || (atoi(value) < 1))
6936 {
6938 }
6939 p_enc->bitrateWindow = atoi(value);
6940 }
6942 {
6943 if ((atoi(value) > 2) || (atoi(value) < 0))
6944 {
6946 }
6947 p_enc->blockRCSize = atoi(value);
6948 }
6950 {
6951 if ((atoi(value) > 15) || (atoi(value) < 0))
6952 {
6954 }
6955 p_enc->rcQpDeltaRange = atoi(value);
6956 }
6958 {
6959 if ((atoi(value) > 500) || (atoi(value) < 0))
6960 {
6962 }
6963 p_enc->ctbRowQpStep = atoi(value);
6964 }
6966 {
6967 if ((atoi(value) > 1) || (atoi(value) < 0))
6968 {
6970 }
6971 p_enc->newRcEnable = atoi(value);
6972 }
6974 {
6975 if ((atoi(value) > 1) || (atoi(value) < 0))
6976 {
6978 }
6979 p_enc->inLoopDSRatio = atoi(value);
6980 }
6982 {
6983 COMPARE(value, 22, 0)
6984 p_params->color_primaries = p_enc->colorPrimaries = atoi(value);
6985 p_enc->colorDescPresent = 1;
6986 }
6988 {
6989 COMPARE(value, 18, 0)
6990 p_params->color_transfer_characteristic = p_enc->colorTrc = atoi(value);
6991 p_enc->colorDescPresent = 1;
6992 }
6994 {
6995 COMPARE(value, 14, 0)
6996 p_params->color_space = p_enc->colorSpace = atoi(value);
6997 p_enc->colorDescPresent = 1;
6998 }
7000 {
7001 p_params->sar_num = p_enc->aspectRatioWidth = atoi(value);
7002 }
7004 {
7005 p_params->sar_denom = p_enc->aspectRatioHeight = atoi(value);
7006 }
7008 {
7009 p_params->video_full_range_flag = p_enc->videoFullRange = atoi(value);
7010 }
7012 {
7013 if ((atoi(value) < NI_MIN_KEEP_ALIVE_TIMEOUT) ||
7015 {
7017 }
7018 p_enc->keep_alive_timeout = atoi(value);
7019 }
7021 {
7022 if (atoi(value) != 0 && atoi(value) != 1)
7023 {
7025 }
7026 p_params->enable_vfr = atoi(value);
7027 }
7029 {
7030 if (atoi(value) < 0 || atoi(value) > 3)
7031 {
7033 }
7034 p_enc->get_psnr_mode = atoi(value);
7035 }
7037 {
7038 if (atoi(value) < 1)
7039 {
7041 }
7042 p_params->interval_of_psnr = atoi(value);
7043 }
7045 {
7046 if (atoi(value) < 0 || atoi(value) > 1)
7047 {
7049 }
7050 p_enc->get_psnr_mode = atoi(value) + 3;
7051 }
7053 {
7054 if ((atoi(value) != 0) && (atoi(value) != 1))
7055 {
7057 }
7058 p_enc->enable_ssim = atoi(value);
7059 }
7061 {
7062 if ((atoi(value) != 0) && (atoi(value) != 1))
7063 {
7065 }
7066 p_enc->av1_error_resilient_mode = atoi(value);
7067 }
7069 {
7070 if ((atoi(value) != 0) && (atoi(value) != 1))
7071 {
7073 }
7074 p_params->staticMmapThreshold = atoi(value);
7075 }
7077 {
7078 p_enc->temporal_layers_enable = atoi(value);
7079 }
7081 {
7082 if ((atoi(value) != 0) && (atoi(value) != 1))
7083 {
7085 }
7086 p_params->enable_ai_enhance = atoi(value);
7087 }
7089 {
7090 if ((atoi(value) != 0) && (atoi(value) != 1))
7091 {
7093 }
7094 if(p_params->enable_ai_enhance)
7095 {
7096 ni_log(NI_LOG_ERROR, "Cannot set enableAIEnhance and enableHVSPlus at same time, just enableHVSPlus\n");
7097 }
7098 p_params->enable_ai_enhance = (atoi(value) == 1) ? 2 : 0;
7099 }
7101 {
7102 if ((atoi(value) != 0) && (atoi(value) != 1))
7103 {
7105 }
7106 p_params->enable2PassGop = atoi(value);
7107 }
7109 {
7110 if ((atoi(value) != 0) && (atoi(value) != 1) && (atoi(value) != -1))
7111 {
7113 }
7114 p_params->zerocopy_mode = atoi(value);
7115 }
7117 {
7118 if ((atoi(value) == 0) || (atoi(value) > 3))
7119 {
7121 }
7122 p_params->ai_enhance_level = atoi(value);
7123 }
7125 {
7126 if ((atoi(value) == 0) || (atoi(value) > 2))
7127 {
7129 }
7130 p_params->ai_enhance_level = atoi(value);
7131 }
7133 {
7134 if ((atoi(value) < NI_MIN_WIDTH) ||
7135 (atoi(value) > NI_PARAM_MAX_WIDTH))
7136 {
7138 }
7139 p_enc->crop_width = atoi(value);
7140 }
7142 {
7143 if ((atoi(value) < NI_MIN_HEIGHT) ||
7144 (atoi(value) > NI_PARAM_MAX_HEIGHT))
7145 {
7147 }
7148 p_enc->crop_height = atoi(value);
7149 }
7151 {
7152 if ((atoi(value) < 0) ||
7153 (atoi(value) > NI_PARAM_MAX_WIDTH))
7154 {
7156 }
7157 p_enc->hor_offset = atoi(value);
7158 }
7160 {
7161 if ((atoi(value) < 0) ||
7162 (atoi(value) > NI_PARAM_MAX_HEIGHT))
7163 {
7165 }
7166 p_enc->ver_offset = atoi(value);
7167 }
7169 {
7170 if ((atoi(value) > 51) || (atoi(value) < -1))
7171 {
7173 }
7174 p_enc->crfMax = atoi(value);
7175 }
7177 {
7178 if ((atof(value) > 1.0) || (atof(value) < 0.0))
7179 {
7181 }
7182 p_enc->qcomp = (float)atof(value);
7183 }
7185 {
7186 if ((atoi(value) != 0) && (atoi(value) != 1))
7187 {
7189 }
7190 p_enc->noMbtree = atoi(value);
7191 }
7193 {
7194 if ((atoi(value) != 0) && (atoi(value) != 1))
7195 {
7197 }
7198 p_enc->avcc_hvcc = atoi(value);
7199 }
7201 {
7202 if ((atoi(value) != 0) && (atoi(value) != 1))
7203 {
7205 }
7206 p_enc->noHWMultiPassSupport = atoi(value);
7207 }
7209 {
7210 if ((atoi(value) > 10) || (atoi(value) < 1))
7211 {
7213 }
7214 p_enc->cuTreeFactor = atoi(value);
7215 }
7217 {
7218 if ((atof(value) > 10.0) || (atof(value) < 0.01))
7219 {
7221 }
7222 p_enc->ipRatio = (float)atof(value);
7223 }
7225 {
7226 if ((atoi(value) != 0) && (atoi(value) != 1))
7227 {
7229 }
7230 p_enc->enableipRatio = atoi(value);
7231 }
7233 {
7234 if ((atof(value) > 10.0) || (atof(value) < 0.01))
7235 {
7237 }
7238 p_enc->pbRatio = (float)atof(value);
7239 }
7241 {
7242 if ((atof(value) > 1.0) || (atof(value) < 0.1))
7243 {
7245 }
7246 p_enc->cplxDecay = (float)atof(value);
7247 }
7249 {
7250 if ((atoi(value) > 51) || (atoi(value) < -1))
7251 {
7253 }
7254 p_enc->pps_init_qp = atoi(value);
7255 }
7257 {
7258 if (atoi(value) >= NI_DDR_PRIORITY_MAX ||
7259 atoi(value) <= NI_DDR_PRIORITY_NONE)
7260 {
7262 }
7263 p_params->ddr_priority_mode = atoi(value);
7264 }
7266 {
7267 if ((atoi(value) != 0) && (atoi(value) != 1))
7268 {
7270 }
7271 p_enc->bitrateMode = atoi(value);
7272 }
7274 {
7275 if ((atoi(value) > 51) || (atoi(value) < -1))
7276 {
7278 }
7279 p_enc->pass1_qp = atoi(value);
7280 }
7282 {
7283 if (((atof(value) < 0.0) && (atof(value) != -1.0)) ||
7284 (atof(value) > 51.00))
7285 {
7287 }
7288 p_enc->crfFloat = (float)atof(value);
7289 }
7291 {
7292 if ((atoi(value) < 0) || (atoi(value) > 31))
7293 {
7295 }
7296 p_enc->hvsBaseMbComplexity = atoi(value);
7297 }
7299 {
7300 if (atoi(value) != 0 && atoi(value) != 1 && atoi(value) != 6)
7301 {
7303 }
7304 p_enc->statistic_output_level = atoi(value);
7305 }
7307 {
7308 //Currently only support 6 stillImage detect level
7309 //0-3: no performance drop
7310 //4-6: performance drop
7311 if ((atoi(value) < 0 || atoi(value) > 6))
7312 {
7314 }
7315 p_enc->still_image_detect_level = atoi(value);
7316 }
7318 {
7319 //Currently only support 10 sceneChange detect level
7320 //1-5 : no performance drop
7321 //6-10: performance drop
7322 if ((atoi(value) < 0 || atoi(value) > 10))
7323 {
7325 }
7326 p_enc->scene_change_detect_level = atoi(value);
7327 }
7329 {
7330 if ((atoi(value) != 0) && (atoi(value) != 1))
7331 {
7333 }
7334 p_enc->enable_smooth_crf = atoi(value);
7335 }
7337 {
7338 if ((atoi(value) != 0) && (atoi(value) != 1))
7339 {
7341 }
7342 p_enc->enable_compensate_qp = atoi(value);
7343 }
7345 {
7346 if (atoi(value) < 0 || atoi(value) > 1)
7347 {
7349 }
7350 p_enc->skip_frame_enable = atoi(value);
7351 }
7353 {
7354 if (atoi(value) < 0)
7355 {
7357 }
7358 p_enc->max_consecutive_skip_num = atoi(value);
7359 }
7361 {
7362 if (atoi(value) < 0 || atoi(value) > 255)
7363 {
7365 }
7366 p_enc->skip_frame_interval = atoi(value);
7367 }
7369 {
7370 if (atoi(value) != 0 && atoi(value) != 1)
7371 {
7373 }
7374 p_enc->enable_all_sei_passthru = atoi(value);
7375 }
7377 {
7378 if (atoi(value) <= 0)
7379 {
7381 }
7382 p_enc->iframe_size_ratio = atoi(value);
7383 }
7385 {
7386 if ((atoi(value) < 0 || atoi(value) > 2) &&
7387 atoi(value) != 5 && atoi(value) != 6)
7388 {
7390 }
7391 p_enc->crf_max_iframe_enable = atoi(value);
7392 }
7394 {
7395 p_enc->vbv_min_rate = atoi(value);
7396 }
7398 {
7399 if (atoi(value) != 0 && atoi(value) != 1)
7400 {
7402 }
7403 p_enc->disable_adaptive_buffers = atoi(value);
7404 }
7406 {
7407 if ((atoi(value) != 0) && (atoi(value) != 1))
7408 {
7410 }
7411 p_enc->disableBframeRdoq = atoi(value);
7412 }
7414 {
7415 if ((atof(value) > 1.0) || (atof(value) < 0.0))
7416 {
7418 }
7419 p_enc->forceBframeQpfactor = (float)atof(value);
7420 }
7422 {
7423 if (atoi(value) < 0 || atoi(value) > 2)
7424 {
7426 }
7427 p_enc->tune_bframe_visual = atoi(value);
7428 }
7430 {
7431 if ((atoi(value) != 0) && (atoi(value) != 1))
7432 {
7434 }
7435 p_enc->enable_acq_limit = atoi(value);
7436 }
7438 {
7439 if (atoi(value) < NI_CUS_ROI_DISABLE || atoi(value) > NI_CUS_ROI_MERGE)
7440 {
7442 }
7443 p_enc->customize_roi_qp_level += atoi(value);
7444 }
7446 {
7448 if (retval != NI_RETCODE_SUCCESS)
7449 {
7450 return retval;
7451 }
7452 // indicate it need to upload roi qp map
7453 p_enc->customize_roi_qp_level += 64;
7454 }
7456 {
7457 if (atoi(value) < 0 || atoi(value) > 2)
7458 {
7460 }
7461 p_enc->motionConstrainedMode = atoi(value);
7462 }
7464 {
7467 {
7469 }
7470 p_enc->encMallocStrategy = atoi(value);
7471 }
7473 {
7474 if (atoi(value) < 1 || atoi(value) > 4)
7475 {
7477 }
7478 p_enc->spatial_layers = atoi(value);
7479 }
7481 {
7482 if (atoi(value) < 0 || atoi(value) > 1)
7483 {
7485 }
7486 p_enc->enable_timecode = atoi(value);
7487 }
7489 {
7490 if ((atoi(value) != 0) && (atoi(value) != 1))
7491 {
7493 }
7494 p_enc->spatial_layers_ref_base_layer = atoi(value);
7495 }
7497 {
7498 if ((atoi(value) != 0) && (atoi(value) != 1))
7499 {
7501 }
7502 p_enc->vbvBufferReencode = atoi(value);
7503 }
7505 {
7506 if (atoi(value)!= 0 && ((atoi(value) > 40 ) || (atoi(value) < 4)))
7507 {
7509 }
7510 p_enc->totalCuTreeDepth = atoi(value);
7511 }
7513 {
7514 if (atoi(value) != 0 && atoi(value) != 1)
7515 {
7517 }
7518 p_enc->adaptiveCuTree = atoi(value);
7519 }
7521 {
7522 if (atoi(value) != 0 && atoi(value) != 1)
7523 {
7525 }
7526 p_enc->preIntraHandling = atoi(value);
7527 }
7529 {
7530 if (atoi(value) != 0 && atoi(value) != 1)
7531 {
7533 }
7534 p_enc->baseLayerOnly = atoi(value);
7535 }
7537 {
7538 if (atoi(value) < 0 || atoi(value) > 100)
7539 {
7541 }
7542 p_enc->pastFrameMaxIntraRatio = atoi(value);
7543 }
7545 {
7546 if (atoi(value) < 0 || atoi(value) > 100)
7547 {
7549 }
7550 p_enc->linkFrameMaxIntraRatio = atoi(value);
7551 }
7553 {
7554 const char delim[2] = ",";
7555 char *chunk;
7556#ifdef _MSC_VER
7557 char *v = _strdup(value);
7558#else
7559 char *v = strdup(value);
7560#endif
7561 char *saveptr = NULL;
7562 i = 0;
7563 chunk = ni_strtok(v, delim, &saveptr);
7564 while (chunk != NULL && i < NI_MAX_SPATIAL_LAYERS)
7565 {
7566 if ((atoi(chunk) > NI_MAX_BITRATE) || (atoi(chunk) < NI_MIN_BITRATE))
7567 {
7568 free(v);
7570 }
7571 p_enc->spatialLayerBitrate[i] = atoi(chunk);
7572 chunk = ni_strtok(NULL, delim, &saveptr);
7573 i++;
7574 }
7575 free(v);
7576 }
7578 {
7579 const char delim[2] = ",";
7580 char *chunk;
7581#ifdef _MSC_VER
7582 char *v = _strdup(value);
7583#else
7584 char *v = strdup(value);
7585#endif
7586 char *saveptr = NULL;
7587 i = 0;
7588 chunk = ni_strtok(v, delim, &saveptr);
7589 while (chunk != NULL && i < NI_MAX_SPATIAL_LAYERS)
7590 {
7594 if (atof(chunk) <= 10)
7595 {
7596 p_enc->av1OpLevel[i] = (int)(10 * atof(chunk) + .5);
7597 }
7598 else
7599 {
7600 p_enc->av1OpLevel[i] = atoi(chunk);
7601 }
7602 chunk = ni_strtok(NULL, delim, &saveptr);
7603 i++;
7604 }
7605 free(v);
7606 }
7608 {
7609 if ((atoi(value) != 0) && (atoi(value) != 1))
7610 {
7612 }
7613 p_enc->disableAv1TimingInfo = atoi(value);
7614 }
7616 {
7617 if ((atoi(value) != 0) && (atoi(value) != 1))
7618 {
7620 }
7621 p_params->enableCpuAffinity = atoi(value);
7622 }
7624 {
7625 for (i = 0; i < NI_NUM_PRESETS_MAX; i++) {
7626 if (0 == strcmp(value, g_xcoder_preset_names[i])) {
7627 p_enc->preset_index = i;
7628 break;
7629 }
7630 else if(i == NI_NUM_PRESETS_MAX - 1) {
7632 }
7633 }
7634 }
7636 {
7637 if (atoi(value) < 0 || atoi(value) > 3)
7638 {
7640 }
7641 p_enc->adaptiveLamdaMode = atoi(value);
7642 }
7644 {
7645 if (atoi(value) < 0 || atoi(value) > 2)
7646 {
7648 }
7649 p_enc->adaptiveCrfMode = atoi(value);
7650 }
7652 {
7653 if (atoi(value) < 0 || atoi(value) > 3)
7654 {
7656 }
7657 p_enc->intraCompensateMode = atoi(value);
7658 }
7660 {
7661 if (atoi(value) < 0 || atoi(value) > 255)
7662 {
7664 }
7665 p_enc->customMinCoeffDiv = atoi(value);
7666 }
7667 else { return NI_RETCODE_PARAM_INVALID_NAME; }
7668
7669#undef OPT
7670#undef OPT2
7671#undef atobool
7672#undef atoi
7673#undef atof
7674
7675 b_error |= bValueWasNull && !bNameWasBool;
7676
7677 ni_log(NI_LOG_TRACE, "%s: exit, b_error=%d\n", __func__, b_error);
7678
7680}
7681
7682#undef atoi
7683#undef atof
7684#define atoi(p_str) ni_atoi(p_str, &b_error)
7685#define atof(p_str) ni_atof(p_str, &b_error)
7686#define atobool(p_str) (ni_atobool(p_str, &b_error))
7687
7688/*!*****************************************************************************
7689 * \brief Set GOP parameter value referenced by name in encoder parameters
7690 * structure
7691 *
7692 * \param[in] p_params Pointer to a user allocated ni_xcoder_params_t
7693 * to find and set a particular parameter
7694 * \param[in] name String represented parameter name to search
7695 * \param[in] value Parameter value to set
7696*
7697 * \return On success
7698 * NI_RETCODE_SUCCESS
7699 * On failure
7700 * NI_RETCODE_FAILURE
7701 * NI_RETCODE_INVALID_PARAM
7702 ******************************************************************************/
7704 const char *name,
7705 const char *value)
7706{
7707 bool b_error = false;
7708 bool bNameWasBool = false;
7709 bool bValueWasNull = !value;
7710 ni_encoder_cfg_params_t *p_enc = NULL;
7711 ni_custom_gop_params_t* p_gop = NULL;
7712 char nameBuf[64] = { 0 };
7713
7714 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
7715
7716 if (!p_params)
7717 {
7718 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
7719 __func__);
7721 }
7722
7723 if ( !name )
7724 {
7725 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
7726 __func__);
7728 }
7729 p_enc = &p_params->cfg_enc_params;
7730 p_gop = &p_enc->custom_gop_params;
7731
7732 // skip -- prefix if provided
7733 if (name[0] == '-' && name[1] == '-')
7734 {
7735 name += 2;
7736 }
7737
7738 // s/_/-/g
7739 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
7740 {
7741 char* c;
7742 ni_strcpy(nameBuf, sizeof(nameBuf), name);
7743 while ((c = strchr(nameBuf, '_')) != 0)
7744 {
7745 *c = '-';
7746 }
7747 name = nameBuf;
7748 }
7749
7750 if (!value)
7751 {
7752 value = "true";
7753 }
7754 else if (value[0] == '=')
7755 {
7756 value++;
7757 }
7758
7759#if defined(_MSC_VER)
7760#define OPT(STR) else if (!_stricmp(name, STR))
7761#else
7762#define OPT(STR) else if (!strcasecmp(name, STR))
7763#endif
7764 if (0); // suppress cppcheck
7766 {
7767 if (atoi(value) > NI_MAX_GOP_SIZE)
7768 {
7770 }
7771 if (atoi(value) < NI_MIN_GOP_SIZE)
7772 {
7774 }
7775 p_gop->custom_gop_size = atoi(value);
7776 }
7777
7778#ifndef QUADRA
7780 {
7781 p_gop->pic_param[0].pic_type = atoi(value);
7782 }
7784 {
7785 p_gop->pic_param[0].poc_offset = atoi(value);
7786 }
7787 OPT(NI_ENC_GOP_PARAMS_G0_PIC_QP)
7788 {
7789 p_gop->pic_param[0].pic_qp = atoi(value);
7790 }
7791 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC_L0)
7792 {
7793 p_gop->pic_param[0].num_ref_pic_L0 = atoi(value);
7794 }
7795 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_POC_L0)
7796 {
7797 p_gop->pic_param[0].ref_poc_L0 = atoi(value);
7798 }
7799 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_POC_L1)
7800 {
7801 p_gop->pic_param[0].ref_poc_L1 = atoi(value);
7802 }
7804 {
7805 p_gop->pic_param[0].temporal_id = atoi(value);
7806 }
7807
7809 {
7810 p_gop->pic_param[1].pic_type = atoi(value);
7811 }
7813 {
7814 p_gop->pic_param[1].poc_offset = atoi(value);
7815 }
7816 OPT(NI_ENC_GOP_PARAMS_G1_PIC_QP)
7817 {
7818 p_gop->pic_param[1].pic_qp = atoi(value);
7819 }
7820 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC_L0)
7821 {
7822 p_gop->pic_param[1].num_ref_pic_L0 = atoi(value);
7823 }
7824 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_POC_L0)
7825 {
7826 p_gop->pic_param[1].ref_poc_L0 = atoi(value);
7827 }
7828 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_POC_L1)
7829 {
7830 p_gop->pic_param[1].ref_poc_L1 = atoi(value);
7831 }
7833 {
7834 p_gop->pic_param[1].temporal_id = atoi(value);
7835 }
7836
7838 {
7839 p_gop->pic_param[2].pic_type = atoi(value);
7840 }
7842 {
7843 p_gop->pic_param[2].poc_offset = atoi(value);
7844 }
7845 OPT(NI_ENC_GOP_PARAMS_G2_PIC_QP)
7846 {
7847 p_gop->pic_param[2].pic_qp = atoi(value);
7848 }
7849 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC_L0)
7850 {
7851 p_gop->pic_param[2].num_ref_pic_L0 = atoi(value);
7852 }
7853 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_POC_L0)
7854 {
7855 p_gop->pic_param[2].ref_poc_L0 = atoi(value);
7856 }
7857 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_POC_L1)
7858 {
7859 p_gop->pic_param[2].ref_poc_L1 = atoi(value);
7860 }
7862 {
7863 p_gop->pic_param[2].temporal_id = atoi(value);
7864 }
7865
7867 {
7868 p_gop->pic_param[3].pic_type = atoi(value);
7869 }
7871 {
7872 p_gop->pic_param[3].poc_offset = atoi(value);
7873 }
7874 OPT(NI_ENC_GOP_PARAMS_G3_PIC_QP)
7875 {
7876 p_gop->pic_param[3].pic_qp = atoi(value);
7877 }
7878 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC_L0)
7879 {
7880 p_gop->pic_param[3].num_ref_pic_L0 = atoi(value);
7881 }
7882 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_POC_L0)
7883 {
7884 p_gop->pic_param[3].ref_poc_L0 = atoi(value);
7885 }
7886 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_POC_L1)
7887 {
7888 p_gop->pic_param[3].ref_poc_L1 = atoi(value);
7889 }
7891 {
7892 p_gop->pic_param[3].temporal_id = atoi(value);
7893 }
7894
7896 {
7897 p_gop->pic_param[4].pic_type = atoi(value);
7898 }
7900 {
7901 p_gop->pic_param[4].poc_offset = atoi(value);
7902 }
7903 OPT(NI_ENC_GOP_PARAMS_G4_PIC_QP)
7904 {
7905 p_gop->pic_param[4].pic_qp = atoi(value);
7906 }
7907 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC_L0)
7908 {
7909 p_gop->pic_param[4].num_ref_pic_L0 = atoi(value);
7910 }
7911 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_POC_L0)
7912 {
7913 p_gop->pic_param[4].ref_poc_L0 = atoi(value);
7914 }
7915 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_POC_L1)
7916 {
7917 p_gop->pic_param[4].ref_poc_L1 = atoi(value);
7918 }
7920 {
7921 p_gop->pic_param[4].temporal_id = atoi(value);
7922 }
7923
7925 {
7926 p_gop->pic_param[5].pic_type = atoi(value);
7927 }
7929 {
7930 p_gop->pic_param[5].poc_offset = atoi(value);
7931 }
7932 OPT(NI_ENC_GOP_PARAMS_G5_PIC_QP)
7933 {
7934 p_gop->pic_param[5].pic_qp = atoi(value);
7935 }
7936 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC_L0)
7937 {
7938 p_gop->pic_param[5].num_ref_pic_L0 = atoi(value);
7939 }
7940 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_POC_L0)
7941 {
7942 p_gop->pic_param[5].ref_poc_L0 = atoi(value);
7943 }
7944 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_POC_L1)
7945 {
7946 p_gop->pic_param[5].ref_poc_L1 = atoi(value);
7947 }
7949 {
7950 p_gop->pic_param[5].temporal_id = atoi(value);
7951 }
7952
7954 {
7955 p_gop->pic_param[6].pic_type = atoi(value);
7956 }
7958 {
7959 p_gop->pic_param[6].poc_offset = atoi(value);
7960 }
7961 OPT(NI_ENC_GOP_PARAMS_G6_PIC_QP)
7962 {
7963 p_gop->pic_param[6].pic_qp = atoi(value);
7964 }
7965 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC_L0)
7966 {
7967 p_gop->pic_param[6].num_ref_pic_L0 = atoi(value);
7968 }
7969 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_POC_L0)
7970 {
7971 p_gop->pic_param[6].ref_poc_L0 = atoi(value);
7972 }
7973 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_POC_L1)
7974 {
7975 p_gop->pic_param[6].ref_poc_L1 = atoi(value);
7976 }
7978 {
7979 p_gop->pic_param[6].temporal_id = atoi(value);
7980 }
7981
7983 {
7984 p_gop->pic_param[7].pic_type = atoi(value);
7985 }
7987 {
7988 p_gop->pic_param[7].poc_offset = atoi(value);
7989 }
7990 OPT(NI_ENC_GOP_PARAMS_G7_PIC_QP)
7991 {
7992 p_gop->pic_param[7].pic_qp = atoi(value);
7993 }
7994 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC_L0)
7995 {
7996 p_gop->pic_param[7].num_ref_pic_L0 = atoi(value);
7997 }
7998 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_POC_L0)
7999 {
8000 p_gop->pic_param[7].ref_poc_L0 = atoi(value);
8001 }
8002 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_POC_L1)
8003 {
8004 p_gop->pic_param[7].ref_poc_L1 = atoi(value);
8005 }
8007 {
8008 p_gop->pic_param[7].temporal_id = atoi(value);
8009 }
8010 else
8011 {
8012 ni_log(NI_LOG_ERROR, "%s(): Invalid parameter name passed\n", __func__);
8014 }
8015#else
8017 {
8018 p_gop->pic_param[0].poc_offset = atoi(value);
8019 }
8021 {
8022 p_gop->pic_param[0].qp_offset = atoi(value);
8023 }
8024 /*
8025 OPT(NI_ENC_GOP_PARAMS_G0_QP_FACTOR)
8026 {
8027 p_gop->pic_param[0].qp_factor = atof(value);
8028 }
8029 */
8031 {
8032 p_gop->pic_param[0].temporal_id = atoi(value);
8033 }
8035 {
8036 p_gop->pic_param[0].pic_type = atoi(value);
8037 }
8039 {
8040 p_gop->pic_param[0].num_ref_pics = atoi(value);
8041 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 num_ref_pics %d\n", __func__, p_gop->pic_param[0].num_ref_pics);
8042 }
8044 {
8045 p_gop->pic_param[0].rps[0].ref_pic = atoi(value);
8046 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 %d rps[0].ref_pic %d\n", __func__, p_gop->pic_param[0].rps[0].ref_pic);
8047 }
8049 {
8050 p_gop->pic_param[0].rps[0].ref_pic_used = atoi(value);
8051 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 %d rps[0].ref_pic_used %d\n", __func__, p_gop->pic_param[0].rps[0].ref_pic_used);
8052 }
8054 {
8055 p_gop->pic_param[0].rps[1].ref_pic = atoi(value);
8056 }
8058 {
8059 p_gop->pic_param[0].rps[1].ref_pic_used = atoi(value);
8060 }
8062 {
8063 p_gop->pic_param[0].rps[2].ref_pic = atoi(value);
8064 }
8066 {
8067 p_gop->pic_param[0].rps[2].ref_pic_used = atoi(value);
8068 }
8070 {
8071 p_gop->pic_param[0].rps[3].ref_pic = atoi(value);
8072 }
8074 {
8075 p_gop->pic_param[0].rps[3].ref_pic_used = atoi(value);
8076 }
8077
8079 {
8080 p_gop->pic_param[1].poc_offset = atoi(value);
8081 }
8083 {
8084 p_gop->pic_param[1].qp_offset = atoi(value);
8085 }
8086 /*
8087 OPT(NI_ENC_GOP_PARAMS_G1_QP_FACTOR)
8088 {
8089 p_gop->pic_param[1].qp_factor = atof(value);
8090 }
8091 */
8093 {
8094 p_gop->pic_param[1].temporal_id = atoi(value);
8095 }
8097 {
8098 p_gop->pic_param[1].pic_type = atoi(value);
8099 }
8101 {
8102 p_gop->pic_param[1].num_ref_pics = atoi(value);
8103 }
8105 {
8106 p_gop->pic_param[1].rps[0].ref_pic = atoi(value);
8107 }
8109 {
8110 p_gop->pic_param[1].rps[0].ref_pic_used = atoi(value);
8111 }
8113 {
8114 p_gop->pic_param[1].rps[1].ref_pic = atoi(value);
8115 }
8117 {
8118 p_gop->pic_param[1].rps[1].ref_pic_used = atoi(value);
8119 }
8121 {
8122 p_gop->pic_param[1].rps[2].ref_pic = atoi(value);
8123 }
8125 {
8126 p_gop->pic_param[1].rps[2].ref_pic_used = atoi(value);
8127 }
8129 {
8130 p_gop->pic_param[1].rps[3].ref_pic = atoi(value);
8131 }
8133 {
8134 p_gop->pic_param[1].rps[3].ref_pic_used = atoi(value);
8135 }
8136
8138 {
8139 p_gop->pic_param[2].poc_offset = atoi(value);
8140 }
8142 {
8143 p_gop->pic_param[2].qp_offset = atoi(value);
8144 }
8145 /*
8146 OPT(NI_ENC_GOP_PARAMS_G2_QP_FACTOR)
8147 {
8148 p_gop->pic_param[2].qp_factor = atof(value);
8149 }
8150 */
8152 {
8153 p_gop->pic_param[2].temporal_id = atoi(value);
8154 }
8156 {
8157 p_gop->pic_param[2].pic_type = atoi(value);
8158 }
8160 {
8161 p_gop->pic_param[2].num_ref_pics = atoi(value);
8162 }
8164 {
8165 p_gop->pic_param[2].rps[0].ref_pic = atoi(value);
8166 }
8168 {
8169 p_gop->pic_param[2].rps[0].ref_pic_used = atoi(value);
8170 }
8172 {
8173 p_gop->pic_param[2].rps[1].ref_pic = atoi(value);
8174 }
8176 {
8177 p_gop->pic_param[2].rps[1].ref_pic_used = atoi(value);
8178 }
8180 {
8181 p_gop->pic_param[2].rps[2].ref_pic = atoi(value);
8182 }
8184 {
8185 p_gop->pic_param[2].rps[2].ref_pic_used = atoi(value);
8186 }
8188 {
8189 p_gop->pic_param[2].rps[3].ref_pic = atoi(value);
8190 }
8192 {
8193 p_gop->pic_param[2].rps[3].ref_pic_used = atoi(value);
8194 }
8195
8197 {
8198 p_gop->pic_param[3].poc_offset = atoi(value);
8199 }
8201 {
8202 p_gop->pic_param[3].qp_offset = atoi(value);
8203 }
8204 /*
8205 OPT(NI_ENC_GOP_PARAMS_G3_QP_FACTOR)
8206 {
8207 p_gop->pic_param[3].qp_factor = atof(value);
8208 }
8209 */
8211 {
8212 p_gop->pic_param[3].temporal_id = atoi(value);
8213 }
8215 {
8216 p_gop->pic_param[3].pic_type = atoi(value);
8217 }
8219 {
8220 p_gop->pic_param[3].num_ref_pics = atoi(value);
8221 }
8223 {
8224 p_gop->pic_param[3].rps[0].ref_pic = atoi(value);
8225 }
8227 {
8228 p_gop->pic_param[3].rps[0].ref_pic_used = atoi(value);
8229 }
8231 {
8232 p_gop->pic_param[3].rps[1].ref_pic = atoi(value);
8233 }
8235 {
8236 p_gop->pic_param[3].rps[1].ref_pic_used = atoi(value);
8237 }
8239 {
8240 p_gop->pic_param[3].rps[2].ref_pic = atoi(value);
8241 }
8243 {
8244 p_gop->pic_param[3].rps[2].ref_pic_used = atoi(value);
8245 }
8247 {
8248 p_gop->pic_param[3].rps[3].ref_pic = atoi(value);
8249 }
8251 {
8252 p_gop->pic_param[3].rps[3].ref_pic_used = atoi(value);
8253 }
8254
8256 {
8257 p_gop->pic_param[4].poc_offset = atoi(value);
8258 }
8260 {
8261 p_gop->pic_param[4].qp_offset = atoi(value);
8262 }
8263 /*
8264 OPT(NI_ENC_GOP_PARAMS_G4_QP_FACTOR)
8265 {
8266 p_gop->pic_param[4].qp_factor = atof(value);
8267 }
8268 */
8270 {
8271 p_gop->pic_param[4].temporal_id = atoi(value);
8272 }
8274 {
8275 p_gop->pic_param[4].pic_type = atoi(value);
8276 }
8278 {
8279 p_gop->pic_param[4].num_ref_pics = atoi(value);
8280 }
8282 {
8283 p_gop->pic_param[4].rps[0].ref_pic = atoi(value);
8284 }
8286 {
8287 p_gop->pic_param[4].rps[0].ref_pic_used = atoi(value);
8288 }
8290 {
8291 p_gop->pic_param[4].rps[1].ref_pic = atoi(value);
8292 }
8294 {
8295 p_gop->pic_param[4].rps[1].ref_pic_used = atoi(value);
8296 }
8298 {
8299 p_gop->pic_param[4].rps[2].ref_pic = atoi(value);
8300 }
8302 {
8303 p_gop->pic_param[4].rps[2].ref_pic_used = atoi(value);
8304 }
8306 {
8307 p_gop->pic_param[4].rps[3].ref_pic = atoi(value);
8308 }
8310 {
8311 p_gop->pic_param[4].rps[3].ref_pic_used = atoi(value);
8312 }
8313
8315 {
8316 p_gop->pic_param[5].poc_offset = atoi(value);
8317 }
8319 {
8320 p_gop->pic_param[5].qp_offset = atoi(value);
8321 }
8322 /*
8323 OPT(NI_ENC_GOP_PARAMS_G5_QP_FACTOR)
8324 {
8325 p_gop->pic_param[5].qp_factor = atof(value);
8326 }
8327 */
8329 {
8330 p_gop->pic_param[5].temporal_id = atoi(value);
8331 }
8333 {
8334 p_gop->pic_param[5].pic_type = atoi(value);
8335 }
8337 {
8338 p_gop->pic_param[5].num_ref_pics = atoi(value);
8339 }
8341 {
8342 p_gop->pic_param[5].rps[0].ref_pic = atoi(value);
8343 }
8345 {
8346 p_gop->pic_param[5].rps[0].ref_pic_used = atoi(value);
8347 }
8349 {
8350 p_gop->pic_param[5].rps[1].ref_pic = atoi(value);
8351 }
8353 {
8354 p_gop->pic_param[5].rps[1].ref_pic_used = atoi(value);
8355 }
8357 {
8358 p_gop->pic_param[5].rps[2].ref_pic = atoi(value);
8359 }
8361 {
8362 p_gop->pic_param[5].rps[2].ref_pic_used = atoi(value);
8363 }
8365 {
8366 p_gop->pic_param[5].rps[3].ref_pic = atoi(value);
8367 }
8369 {
8370 p_gop->pic_param[5].rps[3].ref_pic_used = atoi(value);
8371 }
8372
8374 {
8375 p_gop->pic_param[6].poc_offset = atoi(value);
8376 }
8378 {
8379 p_gop->pic_param[6].qp_offset = atoi(value);
8380 }
8381 /*
8382 OPT(NI_ENC_GOP_PARAMS_G6_QP_FACTOR)
8383 {
8384 p_gop->pic_param[6].qp_factor = atof(value);
8385 }
8386 */
8388 {
8389 p_gop->pic_param[6].temporal_id = atoi(value);
8390 }
8392 {
8393 p_gop->pic_param[6].pic_type = atoi(value);
8394 }
8396 {
8397 p_gop->pic_param[6].num_ref_pics = atoi(value);
8398 }
8400 {
8401 p_gop->pic_param[6].rps[0].ref_pic = atoi(value);
8402 }
8404 {
8405 p_gop->pic_param[6].rps[0].ref_pic_used = atoi(value);
8406 }
8408 {
8409 p_gop->pic_param[6].rps[1].ref_pic = atoi(value);
8410 }
8412 {
8413 p_gop->pic_param[6].rps[1].ref_pic_used = atoi(value);
8414 }
8416 {
8417 p_gop->pic_param[6].rps[2].ref_pic = atoi(value);
8418 }
8420 {
8421 p_gop->pic_param[6].rps[2].ref_pic_used = atoi(value);
8422 }
8424 {
8425 p_gop->pic_param[6].rps[3].ref_pic = atoi(value);
8426 }
8428 {
8429 p_gop->pic_param[6].rps[3].ref_pic_used = atoi(value);
8430 }
8431
8433 {
8434 p_gop->pic_param[7].poc_offset = atoi(value);
8435 }
8437 {
8438 p_gop->pic_param[7].qp_offset = atoi(value);
8439 }
8440 /*
8441 OPT(NI_ENC_GOP_PARAMS_G7_QP_FACTOR)
8442 {
8443 p_gop->pic_param[7].qp_factor = atof(value);
8444 }
8445 */
8447 {
8448 p_gop->pic_param[7].temporal_id = atoi(value);
8449 }
8451 {
8452 p_gop->pic_param[7].pic_type = atoi(value);
8453 }
8455 {
8456 p_gop->pic_param[7].num_ref_pics = atoi(value);
8457 }
8459 {
8460 p_gop->pic_param[7].rps[0].ref_pic = atoi(value);
8461 }
8463 {
8464 p_gop->pic_param[7].rps[0].ref_pic_used = atoi(value);
8465 }
8467 {
8468 p_gop->pic_param[7].rps[1].ref_pic = atoi(value);
8469 }
8471 {
8472 p_gop->pic_param[7].rps[1].ref_pic_used = atoi(value);
8473 }
8475 {
8476 p_gop->pic_param[7].rps[2].ref_pic = atoi(value);
8477 }
8479 {
8480 p_gop->pic_param[7].rps[2].ref_pic_used = atoi(value);
8481 }
8483 {
8484 p_gop->pic_param[7].rps[3].ref_pic = atoi(value);
8485 }
8487 {
8488 p_gop->pic_param[7].rps[3].ref_pic_used = atoi(value);
8489 }
8490 else
8491 {
8492 ni_log(NI_LOG_ERROR, "%s(): Invalid parameter name passed\n", __func__);
8494 }
8495#endif
8496
8497#undef OPT
8498#undef OPT2
8499#undef atobool
8500#undef atoi
8501#undef atof
8502
8503 b_error |= bValueWasNull && !bNameWasBool;
8504
8505 ni_log(NI_LOG_TRACE, "%s(): exit, b_error=%d\n", __func__, b_error);
8506
8508}
8509
8510/*!*****************************************************************************
8511* \brief Copy existing decoding session params for hw frame usage
8512*
8513* \param[in] src_p_ctx Pointer to a caller allocated source session context
8514* \param[in] dst_p_ctx Pointer to a caller allocated destination session
8515* context
8516* \return On success
8517* NI_RETCODE_SUCCESS
8518* On failure
8519* NI_RETCODE_INVALID_PARAM
8520******************************************************************************/
8522{
8523 return ni_decoder_session_copy_internal(src_p_ctx, dst_p_ctx);
8524}
8525
8526/*!*****************************************************************************
8527* \brief Read data from the device
8528* If device_type is NI_DEVICE_TYPE_DECODER reads data hwdesc from
8529* decoder
8530* If device_type is NI_DEVICE_TYPE_SCALER reads data hwdesc from
8531* scaler
8532*
8533* \param[in] p_ctx Pointer to a caller allocated
8534* ni_session_context_t struct
8535* \param[in] p_data Pointer to a caller allocated
8536* ni_session_data_io_t struct which contains either a
8537* ni_frame_t data frame or ni_packet_t data packet to
8538* send
8539* \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_SCALER
8540* If NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_SCALER is specified,
8541* hw descriptor info will be stored in p_data ni_frame
8542* \return On success
8543* Total number of bytes read
8544* On failure
8545* NI_RETCODE_INVALID_PARAM
8546* NI_RETCODE_ERROR_NVME_CMD_FAILED
8547* NI_RETCODE_ERROR_INVALID_SESSION
8548******************************************************************************/
8550{
8551 ni_log2(p_ctx, NI_LOG_DEBUG, "%s start\n", __func__);
8553 if ((!p_ctx) || (!p_data))
8554 {
8555 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
8556 __func__);
8558 }
8559
8560 // Here check if keep alive thread is closed.
8561#ifdef _WIN32
8562 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
8564#else
8565 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
8567#endif
8568 {
8569 ni_log2(p_ctx, NI_LOG_ERROR,
8570 "ERROR: %s() keep alive thread has been closed, "
8571 "hw:%d, session:%d\n",
8572 __func__, p_ctx->hw_id, p_ctx->session_id);
8574 }
8575
8577 // In close state, let the close process execute first.
8579 {
8580 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
8582 ni_usleep(100);
8584 }
8587
8588 switch (device_type)
8589 {
8591 {
8592 int seq_change_read_count = 0;
8593 p_data->data.frame.src_codec = p_ctx->codec_format;
8594 for (;;)
8595 {
8596 //retval = ni_decoder_session_read(p_ctx, &(p_data->data.frame));
8597 retval = ni_decoder_session_read_desc(p_ctx, &(p_data->data.frame));
8598 // check resolution change only after initial setting obtained
8599 // p_data->data.frame.video_width is picture width and will be 32-align
8600 // adjusted to frame size; p_data->data.frame.video_height is the same as
8601 // frame size, then compare them to saved one for resolution checking
8602 //
8603 uint32_t aligned_width;
8604 if(QUADRA)
8605 {
8606 aligned_width = ((((p_data->data.frame.video_width * p_ctx->bit_depth_factor) + 127) / 128) * 128);
8607 }
8608 else
8609 {
8610 aligned_width = ((p_data->data.frame.video_width + 31) / 32) * 32;
8611 }
8612
8613 ni_log2(p_ctx, NI_LOG_DEBUG,
8614 "FNum %" PRIu64
8615 ", DFVWxDFVH %u x %u, AlWid %u, AVW x AVH %u x %u\n",
8616 p_ctx->frame_num, p_data->data.frame.video_width,
8617 p_data->data.frame.video_height, aligned_width,
8619
8620 if (0 == retval && seq_change_read_count)
8621 {
8622 ni_log2(p_ctx, NI_LOG_DEBUG, "%s (decoder): seq change NO data, next time.\n",
8623 __func__);
8624 p_ctx->active_video_width = 0;
8625 p_ctx->active_video_height = 0;
8626 p_ctx->actual_video_width = 0;
8627 break;
8628 }
8629 else if (retval < 0)
8630 {
8631 ni_log2(p_ctx, NI_LOG_ERROR, "%s (decoder): failure ret %d, return ..\n",
8632 __func__, retval);
8633 break;
8634 }
8635 // aligned_width may equal to active_video_width if bit depth and width
8636 // are changed at the same time. So, check video_width != actual_video_width.
8637 else if (p_ctx->frame_num && (p_ctx->pixel_format_changed ||
8638 (p_data->data.frame.video_width &&
8639 p_data->data.frame.video_height &&
8640 (aligned_width != p_ctx->active_video_width ||
8641 p_data->data.frame.video_height != p_ctx->active_video_height))))
8642 {
8643 ni_log2(
8644 p_ctx, NI_LOG_DEBUG,
8645 "%s (decoder): resolution change, frame size %ux%u -> %ux%u, "
8646 "width %u bit %d, pix_fromat_changed %d, actual_video_width %d, continue read ...\n",
8647 __func__, p_ctx->active_video_width, p_ctx->active_video_height,
8648 aligned_width, p_data->data.frame.video_height,
8649 p_data->data.frame.video_width, p_ctx->bit_depth_factor,
8651 // reset active video resolution to 0 so it can be queried in the re-read
8652 p_ctx->active_video_width = 0;
8653 p_ctx->active_video_height = 0;
8654 p_ctx->actual_video_width = 0;
8655 seq_change_read_count++;
8656 //break;
8657 }
8658 else
8659 {
8660 break;
8661 }
8662 }
8663 break;
8664 }
8666 {
8667 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Encoder has no hwdesc to read\n");
8669 }
8670
8672 {
8673 retval = ni_scaler_session_read_hwdesc(p_ctx, &(p_data->data.frame));
8674 break;
8675 }
8676
8677 case NI_DEVICE_TYPE_AI:
8678 {
8679 retval = ni_ai_session_read_hwdesc(p_ctx, &(p_data->data.frame));
8680 break;
8681 }
8682
8683 default:
8684 {
8685 retval = NI_RETCODE_INVALID_PARAM;
8686 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
8687 __func__, device_type);
8688 break;
8689 }
8690 }
8691
8693 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
8695
8696 return retval;
8697}
8698
8699/*!*****************************************************************************
8700* \brief Reads YUV data from hw descriptor stored location on device
8701*
8702* \param[in] p_ctx Pointer to a caller allocated
8703* ni_session_context_t struct
8704* \param[in] p_data Pointer to a caller allocated
8705* ni_session_data_io_t struct which contains either a
8706* ni_frame_t data frame or ni_packet_t data packet to
8707* send
8708* \param[in] hwdesc HW descriptor to find frame in XCODER
8709* \return On success
8710* Total number of bytes read
8711* On failure
8712* NI_RETCODE_INVALID_PARAM
8713* NI_RETCODE_ERROR_NVME_CMD_FAILED
8714* NI_RETCODE_ERROR_INVALID_SESSION
8715*******************************************************************************/
8717{
8719 if ((!hwdesc) || (!p_data))
8720 {
8721 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8722 __func__);
8724 }
8725
8726 /* download by frameidx */
8727 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rd") >= 0))
8728 {
8729 if(hwdesc->ui16FrameIdx == 0)
8730 {
8731 ni_log(NI_LOG_ERROR, "%s(): Invaild frame index\n", __func__);
8733 }
8734 retval = ni_hwdownload_by_frame_idx(hwdesc, &(p_data->data.frame), p_ctx->is_auto_dl);
8735 } else {
8736 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
8737 {
8738 if (p_ctx->pext_mutex == &(p_ctx->mutex))
8739 {
8740 ni_log(NI_LOG_ERROR, "ERROR %s(): Invalid session\n",
8741 __func__);
8743 }
8744 }
8745
8747 bool use_external_mutex = false;
8748 uint32_t orig_session_id = p_ctx->session_id;
8749 ni_device_handle_t orig_blk_io_handle = p_ctx->blk_io_handle;
8750 uint32_t orig_codec_format = p_ctx->codec_format;
8751 int orig_bit_depth_factor = p_ctx->bit_depth_factor;
8752 int orig_hw_action = p_ctx->hw_action;
8753
8754 ni_pthread_mutex_t *p_ctx_mutex = &(p_ctx->mutex);
8755 if ((p_ctx_mutex != p_ctx->pext_mutex) ||
8758 "6r8") < 0)
8759 {
8760 use_external_mutex = true;
8761 p_ctx->session_id = hwdesc->ui16session_ID;
8762 p_ctx->blk_io_handle = (ni_device_handle_t)(int64_t)hwdesc->device_handle;
8763 p_ctx->codec_format = NI_CODEC_FORMAT_H264; //unused
8764 p_ctx->bit_depth_factor = (int)hwdesc->bit_depth;
8766 }
8767
8769
8770 retval = ni_hwdownload_session_read(p_ctx, &(p_data->data.frame), hwdesc); //cut me down as needed
8771
8772 p_ctx->xcoder_state &= ~NI_XCODER_HWDL_STATE;
8773 if (use_external_mutex)
8774 {
8775 p_ctx->session_id = orig_session_id;
8776 p_ctx->blk_io_handle = orig_blk_io_handle;
8777 p_ctx->codec_format = orig_codec_format;
8778 p_ctx->bit_depth_factor = orig_bit_depth_factor;
8779 p_ctx->hw_action = orig_hw_action;
8780 }
8782 }
8783
8784 return retval;
8785}
8786
8787/*!*****************************************************************************
8788* \brief Query the session if a buffer is available
8789*
8790* \param[in] p_ctx Pointer to a caller allocated
8791* ni_session_context_t struct
8792* [in] device_type Quadra device type
8793*
8794* \return On success
8795* NI_RETCODE_SUCCESS
8796* On failure
8797* NI_RETCODE_INVALID_PARAM
8798* NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
8799* NI_RETCODE_ERROR_NVME_CMD_FAILED
8800* NI_RETCODE_ERROR_INVALID_SESSION
8801*******************************************************************************/
8803 ni_device_type_t device_type)
8804{
8806
8807 if (!p_ctx)
8808 {
8809 ni_log(NI_LOG_ERROR, "ERROR: No session\n");
8811 }
8812
8815 "6rt") < 0)
8816 {
8817 ni_log2(p_ctx, NI_LOG_DEBUG,
8818 "%s function not supported in FW API version < 6rt\n",
8819 __func__);
8821 }
8822
8823 switch (device_type)
8824 {
8828
8830
8831 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
8833 break;
8834
8838
8840
8841 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
8843 break;
8844
8845 default:
8846 break;
8847 }
8848
8849 return retval;
8850}
8851
8852/*!*****************************************************************************
8853* \brief Sends raw YUV input to uploader instance and retrieves a HW descriptor
8854* to represent it
8855*
8856* \param[in] p_ctx Pointer to a caller allocated
8857* ni_session_context_t struct
8858* \param[in] p_src_data Pointer to a caller allocated
8859* ni_session_data_io_t struct which contains a
8860* ni_frame_t data frame to send to uploader
8861* \param[out] hwdesc HW descriptor to find frame in XCODER
8862* \return On success
8863* Total number of bytes read
8864* On failure
8865* NI_RETCODE_INVALID_PARAM
8866* NI_RETCODE_ERROR_NVME_CMD_FAILED
8867* NI_RETCODE_ERROR_INVALID_SESSION
8868*******************************************************************************/
8870{
8872 if ((!hwdesc) || (!p_src_data))
8873 {
8874 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8875 __func__);
8877 }
8880
8881 retval = ni_hwupload_session_write(p_ctx, &p_src_data->data.frame, hwdesc);
8882
8883 p_ctx->xcoder_state &= ~NI_XCODER_HWUP_STATE;
8885
8886 return retval;
8887}
8888
8889/*!*****************************************************************************
8890* \brief Allocate memory for the hwDescriptor buffer based on provided
8891* parameters taking into account pic size and extra data.
8892*
8893* \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
8894*
8895* \param[in] video_width Width of the video frame
8896* \param[in] video_height Height of the video frame
8897* \param[in] extra_len Extra data size (incl. meta data)
8898*
8899* \return On success
8900* NI_RETCODE_SUCCESS
8901* On failure
8902* NI_RETCODE_INVALID_PARAM
8903* NI_RETCODE_ERROR_MEM_ALOC
8904*****************************************************************************/
8906 int video_height, int extra_len)
8907{
8908 void* p_buffer = NULL;
8909 int height_aligned = video_height;
8910 int retval = NI_RETCODE_SUCCESS;
8911
8912 if (!p_frame)
8913 {
8914 ni_log(NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8915 __func__);
8917 }
8918
8919 ni_log(NI_LOG_DEBUG, "%s: extra_len=%d\n", __func__, extra_len);
8920
8921 int buffer_size = (int)sizeof(niFrameSurface1_t) + extra_len;
8922
8924
8925 //Check if Need to free
8926 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
8927 {
8928 ni_log(NI_LOG_DEBUG, "%s: free current p_frame->buffer_size=%u\n",
8929 __func__, p_frame->buffer_size);
8930 ni_frame_buffer_free(p_frame);
8931 }
8932
8933 //Check if need to realocate
8934 if (p_frame->buffer_size != buffer_size)
8935 {
8936 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
8937 {
8938 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
8939 NI_ERRNO, __func__);
8941 LRETURN;
8942 }
8943
8944 // init once after allocation
8945 memset(p_buffer, 0, buffer_size);
8946 p_frame->buffer_size = buffer_size;
8947 p_frame->p_buffer = p_buffer;
8948
8949 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
8950 }
8951 else
8952 {
8953 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
8954 }
8955
8956 p_frame->p_data[3] = p_frame->p_buffer;
8957 p_frame->p_data[0] = NULL;
8958 p_frame->p_data[1] = NULL;
8959 p_frame->p_data[2] = NULL;
8960
8961 p_frame->data_len[0] = 0;//luma_size;
8962 p_frame->data_len[1] = 0;//chroma_b_size;
8963 p_frame->data_len[2] = 0;//chroma_r_size;
8964 p_frame->data_len[3] = sizeof(niFrameSurface1_t);
8965
8966 p_frame->video_width = video_width;
8967 p_frame->video_height = height_aligned;
8968
8969 ((niFrameSurface1_t*)p_frame->p_data[3])->device_handle = (int32_t)NI_INVALID_DEVICE_HANDLE;
8970
8971 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
8972 p_frame->buffer_size);
8973
8974END:
8975
8976 if (NI_RETCODE_SUCCESS != retval)
8977 {
8978 ni_aligned_free(p_buffer);
8979 }
8980
8981 return retval;
8982}
8983
8984/*!*****************************************************************************
8985* \brief Recycle a frame buffer on card
8986*
8987* \param[in] surface Struct containing device and frame location to clear out
8988* \param[in] device_handle handle to access device memory buffer is stored in
8989*
8990* \return On success NI_RETCODE_SUCCESS
8991* On failure NI_RETCODE_INVALID_PARAM
8992*******************************************************************************/
8994 int32_t device_handle)
8995{
8997
8998 if (surface)
8999 {
9000 ni_log(NI_LOG_DEBUG, "%s(): Start cleaning out buffer\n", __func__);
9002 "%s(): ui16FrameIdx=%d sessionId=%d device_handle=0x%x\n",
9003 __func__, surface->ui16FrameIdx, surface->ui16session_ID,
9004 device_handle);
9005 retval = ni_clear_instance_buf(surface);
9006 }
9007 else
9008 {
9009 ni_log(NI_LOG_DEBUG, "%s(): Surface is empty\n", __func__);
9010 }
9011
9012 return retval;
9013}
9014
9015/*!*****************************************************************************
9016* \brief Recycle a frame buffer on card, only hwframe descriptor is needed
9017*
9018* \param[in] surface Struct containing device and frame location to clear out
9019*
9020* \return On success NI_RETCODE_SUCCESS
9021* On failure NI_RETCODE_INVALID_PARAM
9022*******************************************************************************/
9024{
9026 int32_t saved_dma_buf_fd;
9027 if (surface)
9028 {
9029 if(surface->ui16FrameIdx == 0)
9030 {
9031 ni_log(NI_LOG_DEBUG, "%s(): Invaild frame index\n", __func__);
9032 return retval;
9033 }
9034 ni_log(NI_LOG_DEBUG, "%s(): Start cleaning out buffer\n", __func__);
9036 "%s(): ui16FrameIdx=%d sessionId=%d device_handle=0x%x\n",
9037 __func__, surface->ui16FrameIdx, surface->ui16session_ID,
9038 surface->device_handle);
9039 retval = ni_clear_instance_buf(surface);
9040 saved_dma_buf_fd = surface->dma_buf_fd;
9041 memset(surface, 0, sizeof(niFrameSurface1_t));
9042 surface->dma_buf_fd = saved_dma_buf_fd;
9043 }
9044 else
9045 {
9046 ni_log(NI_LOG_DEBUG, "%s(): Surface is empty\n", __func__);
9047 retval = NI_RETCODE_INVALID_PARAM;
9048 }
9049
9050 return retval;
9051}
9052
9053/*!*****************************************************************************
9054* \brief Sends frame pool setup info to device
9055*
9056* \param[in] p_ctx Pointer to a caller allocated
9057* ni_session_context_t struct
9058* \param[in] pool_size Upload session initial allocated frames count
9059* must be > 0,
9060* \param[in] pool 0 use the normal pool
9061* 1 use a dedicated P2P pool
9062*
9063* \return On success Return code
9064* On failure
9065* NI_RETCODE_INVALID_PARAM
9066* NI_RETCODE_ERROR_NVME_CMD_FAILED
9067* NI_RETCODE_ERROR_INVALID_SESSION
9068* NI_RETCODE_ERROR_MEM_ALOC
9069*******************************************************************************/
9071 uint32_t pool_size, uint32_t pool)
9072{
9074 if (!p_ctx)
9075 {
9076 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9077 __func__);
9079 }
9080 if (pool_size == 0 || pool_size > NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL)
9081 {
9082 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Invalid poolsize == 0 or > 100\n");
9084 }
9085 if (pool & NI_UPLOADER_FLAG_LM)
9086 {
9087 ni_log2(p_ctx, NI_LOG_DEBUG, "uploader buffer acquisition is limited!\n");
9088 }
9091
9092 retval = ni_config_instance_set_uploader_params(p_ctx, pool_size, pool);
9093
9094 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9096
9097 return retval;
9098}
9099
9100/*!*****************************************************************************
9101* \brief Sends frame pool change info to device
9102*
9103* \param[in] p_ctx Pointer to a caller allocated
9104* ni_session_context_t struct
9105* \param[in] pool_size if pool_size = 0, free allocated device memory buffers
9106* if pool_size > 0, expand device frame buffer pool of
9107* current instance with pool_size more frame buffers
9108*
9109* \return On success Return code
9110* On failure
9111* NI_RETCODE_FAILURE
9112* NI_RETCODE_INVALID_PARAM
9113* NI_RETCODE_ERROR_NVME_CMD_FAILED
9114* NI_RETCODE_ERROR_INVALID_SESSION
9115* NI_RETCODE_ERROR_MEM_ALOC
9116* NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9117*******************************************************************************/
9119 uint32_t pool_size)
9120{
9122 if (!p_ctx)
9123 {
9124 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9125 __func__);
9127 }
9130 "6r3") < 0)
9131 {
9132 ni_log2(p_ctx, NI_LOG_ERROR,
9133 "ERROR: %s function not supported in FW API version < 6r3\n",
9134 __func__);
9136 }
9137 if (p_ctx->pool_type == NI_POOL_TYPE_NONE)
9138 {
9139 ni_log2(p_ctx, NI_LOG_ERROR,
9140 "ERROR: can't free or expand framepool of session 0x%x "
9141 "before init framepool\n", p_ctx->session_id);
9142 return NI_RETCODE_FAILURE;
9143 }
9144 if (pool_size > NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL)
9145 {
9146 ni_log2(p_ctx, NI_LOG_ERROR,
9147 "ERROR: Invalid poolsize > %u\n", NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL);
9149 }
9150 if (pool_size == 0)
9151 {
9152 ni_log2(p_ctx, NI_LOG_INFO, "Free frame pool of session 0x%x\n", p_ctx->session_id);
9153 }
9154
9157
9158 retval = ni_config_instance_set_uploader_params(p_ctx, pool_size, p_ctx->pool_type);
9159
9160 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9162
9163 return retval;
9164}
9165
9166/*!*****************************************************************************
9167 * \brief Set parameters on the device for the 2D engine
9168 *
9169 * \param[in] p_ctx pointer to session context
9170 * \param[in] p_params pointer to scaler parameters
9171 *
9172 * \return NI_RETCODE_INVALID_PARAM
9173 * NI_RETCODE_ERROR_INVALID_SESSION
9174 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9175 * NI_RETCODE_ERROR_MEM_ALOC
9176 ******************************************************************************/
9178 ni_scaler_params_t *p_params)
9179{
9181
9182 if (!p_ctx || !p_params)
9183 {
9184 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9185 __func__);
9187 }
9190
9191 retval = ni_config_instance_set_scaler_params(p_ctx, p_params);
9192
9193 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9195
9196 return retval;
9197}
9198
9199/*!******************************************************************************
9200 * \brief Send a p_config command to configure scaling drawbox parameters.
9201 *
9202 * \param ni_session_context_t p_ctx - xcoder Context
9203 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_drawbox params_t struct
9204 *
9205 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
9206*******************************************************************************/
9209{
9210 void *p_scaler_config = NULL;
9211 uint32_t buffer_size = sizeof(ni_scaler_multi_drawbox_params_t);
9213 uint32_t ui32LBA = 0;
9214
9215 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
9216
9217 if (!p_ctx || !p_params)
9218 {
9219 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n", __func__);
9220 retval = NI_RETCODE_INVALID_PARAM;
9221 LRETURN;
9222 }
9223
9224 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
9225 {
9226 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n", __func__);
9228 LRETURN;
9229 }
9230
9231 buffer_size =
9232 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
9234 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
9235 {
9236 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
9237 NI_ERRNO, __func__);
9239 LRETURN;
9240 }
9241 memset(p_scaler_config, 0, buffer_size);
9242
9243 //configure the session here
9246
9247 memcpy(p_scaler_config, p_params, buffer_size);
9248
9250 p_scaler_config, buffer_size, ui32LBA) < 0)
9251 {
9252 ni_log2(p_ctx, NI_LOG_ERROR,
9253 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
9254 ", hw_id, %d, xcoder_inst_id: %d\n",
9255 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
9256 // Close the session since we can't configure it as per fw
9257 retval = ni_scaler_session_close(p_ctx, 0);
9258 if (NI_RETCODE_SUCCESS != retval)
9259 {
9260 ni_log2(p_ctx, NI_LOG_ERROR,
9261 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
9262 "hw_id, %d, xcoder_inst_id: %d\n",
9263 __func__,
9264 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
9265 p_ctx->session_id);
9266 }
9267
9269 }
9270
9271END:
9272
9273 ni_aligned_free(p_scaler_config);
9274 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
9275
9276 return retval;
9277}
9278
9279/*!******************************************************************************
9280 * \brief Send a p_config command to configure scaling watermark parameters.
9281 *
9282 * \param ni_session_context_t p_ctx - xcoder Context
9283 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_watermark_params_t struct
9284 *
9285 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
9286*******************************************************************************/
9289{
9290 void *p_scaler_config = NULL;
9291 uint32_t buffer_size = sizeof(ni_scaler_multi_watermark_params_t);
9293 uint32_t ui32LBA = 0;
9294
9295 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
9296
9297 if (!p_ctx || !p_params)
9298 {
9299 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n", __func__);
9300 retval = NI_RETCODE_INVALID_PARAM;
9301 LRETURN;
9302 }
9303
9304 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
9305 {
9306 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n", __func__);
9308 LRETURN;
9309 }
9310
9311 buffer_size =
9312 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
9314 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
9315 {
9316 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
9317 NI_ERRNO, __func__);
9319 LRETURN;
9320 }
9321 memset(p_scaler_config, 0, buffer_size);
9322
9323 //configure the session here
9326
9327 memcpy(p_scaler_config, p_params, buffer_size);
9328
9330 p_scaler_config, buffer_size, ui32LBA) < 0)
9331 {
9332 ni_log2(p_ctx, NI_LOG_ERROR,
9333 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
9334 ", hw_id, %d, xcoder_inst_id: %d\n",
9335 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
9336 // Close the session since we can't configure it as per fw
9337 retval = ni_scaler_session_close(p_ctx, 0);
9338 if (NI_RETCODE_SUCCESS != retval)
9339 {
9340 ni_log2(p_ctx, NI_LOG_ERROR,
9341 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
9342 "hw_id, %d, xcoder_inst_id: %d\n",
9343 __func__,
9344 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
9345 p_ctx->session_id);
9346 }
9347
9349 }
9350
9351END:
9352
9353 ni_aligned_free(p_scaler_config);
9354 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
9355
9356 return retval;
9357}
9358
9359
9360/*!*****************************************************************************
9361 * \brief Allocate a frame on the device for 2D engine or AI engine
9362 * to work on based on provided parameters
9363 *
9364 * \param[in] p_ctx pointer to session context
9365 * \param[in] width width, in pixels
9366 * \param[in] height height, in pixels
9367 * \param[in] format pixel format
9368 * \param[in] options options bitmap flags, bit 0 (NI_SCALER_FLAG_IO) is
9369 * 0=input frame or 1=output frame. Bit 1 (NI_SCALER_FLAG_PC) is
9370 * 0=single allocation, 1=create pool. Bit 2 (NI_SCALER_FLAG_PA) is
9371 * 0=straight alpha, 1=premultiplied alpha
9372 * \param[in] rectangle_width clipping rectangle width
9373 * \param[in] rectangle_height clipping rectangle height
9374 * \param[in] rectangle_x horizontal position of clipping rectangle
9375 * \param[in] rectangle_y vertical position of clipping rectangle
9376 * \param[in] rgba_color RGBA fill colour (for padding only)
9377 * \param[in] frame_index input hwdesc index
9378 * \param[in] device_type only NI_DEVICE_TYPE_SCALER
9379 * and NI_DEVICE_TYPE_AI (only needs p_ctx and frame_index)
9380 *
9381 * \return NI_RETCODE_INVALID_PARAM
9382 * NI_RETCODE_ERROR_INVALID_SESSION
9383 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9384 * NI_RETCODE_ERROR_MEM_ALOC
9385 ******************************************************************************/
9387 int width,
9388 int height,
9389 int format,
9390 int options,
9391 int rectangle_width,
9392 int rectangle_height,
9393 int rectangle_x,
9394 int rectangle_y,
9395 int rgba_color,
9396 int frame_index,
9397 ni_device_type_t device_type)
9398{
9400
9401 if (!p_ctx)
9402 {
9403 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9404 __func__);
9406 }
9409
9410 switch (device_type)
9411 {
9413 retval = ni_scaler_alloc_frame(p_ctx,width, height, format, options,
9414 rectangle_width, rectangle_height,
9415 rectangle_x, rectangle_y,
9416 rgba_color, frame_index);
9417 break;
9418
9419 case NI_DEVICE_TYPE_AI:
9420 retval = ni_ai_alloc_hwframe(p_ctx, width, height, options, rgba_color,
9421 frame_index);
9422 break;
9423
9426 /* fall through */
9427
9428 default:
9429 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", device_type);
9430 retval = NI_RETCODE_INVALID_PARAM;
9431 break;
9432 }
9433
9434 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9436
9437 return retval;
9438}
9439
9440/*!*****************************************************************************
9441 * \brief Allocate a frame on the device and return the frame index
9442 *
9443 * \param[in] p_ctx pointer to session context
9444 * \param[in] p_out_surface pointer to output frame surface
9445 * \param[in] device_type currently only NI_DEVICE_TYPE_AI
9446 *
9447 * \return NI_RETCODE_INVALID_PARAM
9448 * NI_RETCODE_ERROR_INVALID_SESSION
9449 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9450 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9451 * NI_RETCODE_ERROR_MEM_ALOC
9452 ******************************************************************************/
9454 niFrameSurface1_t *p_out_surface,
9455 ni_device_type_t device_type)
9456{
9458
9459 if (!p_ctx)
9460 {
9461 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, %p, return\n",
9462 __func__, p_ctx);
9464 }
9467
9468 switch (device_type)
9469 {
9470 case NI_DEVICE_TYPE_AI:
9471 retval = ni_ai_alloc_dst_frame(p_ctx, p_out_surface);
9472 break;
9473
9477 /* fall through */
9478
9479 default:
9480 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", device_type);
9481 retval = NI_RETCODE_INVALID_PARAM;
9482 break;
9483 }
9484
9485 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9487
9488 return retval;
9489}
9490
9491/*!*****************************************************************************
9492 * \brief Copy the data of src hwframe to dst hwframe
9493 *
9494 * \param[in] p_ctx pointer to session context
9495 * \param[in] p_frameclone_desc pointer to the frameclone descriptor
9496 *
9497 * \return NI_RETCODE_INVALID_PARAM
9498 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9499 * NI_RETCODE_ERROR_INVALID_SESSION
9500 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9501 * NI_RETCODE_ERROR_MEM_ALOC
9502 ******************************************************************************/
9504 ni_frameclone_desc_t *p_frameclone_desc)
9505{
9507
9508 if (!p_ctx)
9509 {
9510 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9511 __func__);
9513 }
9514
9517 "6rL") < 0)
9518 {
9519 ni_log2(p_ctx, NI_LOG_ERROR,
9520 "Error: %s function not supported on device with FW API version < 6rL\n",
9521 __func__);
9523 }
9524
9527 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
9528 {
9529 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
9530 __func__);
9532 LRETURN;
9533 }
9534
9535 retval = ni_hwframe_clone(p_ctx, p_frameclone_desc);
9536
9537END:
9538 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9540
9541 return retval;
9542}
9543
9544/*!*****************************************************************************
9545 * \brief Configure the 2D engine to work based on provided parameters
9546 *
9547 * \param[in] p_ctx pointer to session context
9548 * \param[in] p_cfg pointer to frame configuration
9549 *
9550 * \return NI_RETCODE_INVALID_PARAM
9551 * NI_RETCODE_ERROR_INVALID_SESSION
9552 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9553 * NI_RETCODE_ERROR_MEM_ALOC
9554 ******************************************************************************/
9556 ni_frame_config_t *p_cfg)
9557{
9559
9560 if (!p_ctx || !p_cfg)
9561 {
9562 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9563 __func__);
9565 }
9566
9569
9570 switch (p_ctx->device_type)
9571 {
9573 retval = ni_scaler_config_frame(p_ctx, p_cfg);
9574 break;
9575
9576 default:
9577 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", p_ctx->device_type);
9578 retval = NI_RETCODE_INVALID_PARAM;
9579 break;
9580 }
9581
9582 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9584
9585 return retval;
9586}
9587
9588/*!*****************************************************************************
9589 * \brief Configure the 2D engine to work based on provided parameters
9590 *
9591 * \param[in] p_ctx pointer to session context
9592 * \param[in] p_cfg_in pointer to input frame configuration
9593 * \param[in] numInCfgs number of input frame configurations
9594 * \param[in] p_cfg_out pointer to output frame configuration
9595 *
9596 * \return NI_RETCODE_INVALID_PARAM
9597 * NI_RETCODE_ERROR_INVALID_SESSION
9598 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9599 * NI_RETCODE_ERROR_MEM_ALOC
9600 ******************************************************************************/
9602 ni_frame_config_t p_cfg_in[],
9603 int numInCfgs,
9604 ni_frame_config_t *p_cfg_out)
9605{
9607
9608 if (!p_ctx || !p_cfg_in)
9609 {
9610 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9611 __func__);
9613 }
9614
9617
9618 switch (p_ctx->device_type)
9619 {
9621 retval = ni_scaler_multi_config_frame(p_ctx, p_cfg_in, numInCfgs, p_cfg_out);
9622 break;
9623
9624 case NI_DEVICE_TYPE_AI:
9625 retval = ni_ai_multi_config_frame(p_ctx, p_cfg_in, numInCfgs, p_cfg_out);
9626 break;
9627
9628 default:
9629 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", p_ctx->device_type);
9630 retval = NI_RETCODE_INVALID_PARAM;
9631 break;
9632 }
9633
9634 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9636
9637 return retval;
9638}
9639
9640/*!*****************************************************************************
9641 * \brief Calculate the total size of a frame based on the upload
9642 * context attributes and includes rounding up to the page size
9643 *
9644 * \param[in] p_upl_ctx pointer to an uploader session context
9645 * \param[in] linesize array of line stride
9646 *
9647 * \return size
9648 * NI_RETCODE_INVALID_PARAM
9649 *
9650 ******************************************************************************/
9652 const int linesize[])
9653{
9654 int pixel_format;
9655 int width, height;
9656 int alignedh;
9657 int luma, chroma_b, chroma_r;
9658 int total;
9659
9660 pixel_format = p_upl_ctx->pixel_format;
9661 width = p_upl_ctx->active_video_width;
9662 height = p_upl_ctx->active_video_height;
9663
9664 switch (pixel_format)
9665 {
9666 case NI_PIX_FMT_YUV420P:
9668 case NI_PIX_FMT_NV12:
9669 case NI_PIX_FMT_P010LE:
9670 if (width < 0 || width > NI_MAX_RESOLUTION_WIDTH)
9671 {
9673 }
9674
9675 if ((height < 0) || (height > NI_MAX_RESOLUTION_HEIGHT))
9676 {
9678 }
9679 break;
9680
9681 case NI_PIX_FMT_RGBA:
9682 case NI_PIX_FMT_ABGR:
9683 case NI_PIX_FMT_ARGB:
9684 case NI_PIX_FMT_BGRA:
9685 case NI_PIX_FMT_BGR0:
9686 if ((width < 0) || (width > NI_MAX_RESOLUTION_WIDTH))
9687 {
9689 }
9690
9691 if ((height < 0) || (height > NI_MAX_RESOLUTION_HEIGHT))
9692 {
9694 }
9695 break;
9696
9697 default:
9699 }
9700
9701 alignedh = NI_VPU_CEIL(height, 2);
9702
9703 switch (pixel_format)
9704 {
9705 case NI_PIX_FMT_YUV420P:
9707 luma = linesize[0] * alignedh;
9708 chroma_b = linesize[1] * alignedh / 2;
9709 chroma_r = linesize[2] * alignedh / 2;
9710 total =
9711 luma + chroma_b + chroma_r + NI_APP_ENC_FRAME_META_DATA_SIZE;
9712 break;
9713
9714 case NI_PIX_FMT_NV12:
9715 case NI_PIX_FMT_P010LE:
9716 luma = linesize[0] * alignedh;
9717 chroma_b = linesize[1] * alignedh / 2;
9718 chroma_r = 0;
9719 total =
9720 luma + chroma_b + chroma_r + NI_APP_ENC_FRAME_META_DATA_SIZE;
9721 break;
9722
9723 case NI_PIX_FMT_RGBA:
9724 case NI_PIX_FMT_ABGR:
9725 case NI_PIX_FMT_ARGB:
9726 case NI_PIX_FMT_BGRA:
9727 case NI_PIX_FMT_BGR0:
9728 total = width * height * 4 + NI_APP_ENC_FRAME_META_DATA_SIZE;
9729 break;
9730
9731 default:
9733 break;
9734 }
9735
9737
9738 return total;
9739}
9740
9741/*!*****************************************************************************
9742 * \brief Allocate memory for the frame buffer based on provided parameters
9743 * taking into account the pixel format, width, height, stride,
9744 * alignment, and extra data
9745 * \param[in] p_frame Pointer to caller allocated ni_frame_t
9746 * \param[in] pixel_format a pixel format in ni_pix_fmt_t enum
9747 * \param[in] video_width width, in pixels
9748 * \param[in] video_height height, in pixels
9749 * \param[in] linesize horizontal stride
9750 * \param[in] alignment apply a 16 pixel height alignment (T408 only)
9751 * \param[in] extra_len meta data size
9752 *
9753 * \return NI_RETCODE_SUCCESS
9754 * NI_RETCODE_INVALID_PARAM
9755 * NI_RETCODE_ERROR_MEM_ALOC
9756 *
9757 ******************************************************************************/
9759 int video_width, int video_height,
9760 int linesize[], int alignment,
9761 int extra_len)
9762{
9763 int buffer_size;
9764 void *p_buffer = NULL;
9765 int retval = NI_RETCODE_SUCCESS;
9766 int height_aligned;
9767 int luma_size = 0;
9768 int chroma_b_size = 0;
9769 int chroma_r_size = 0;
9770
9771 if (!p_frame)
9772 {
9773 ni_log(NI_LOG_ERROR, "Invalid frame pointer\n");
9775 }
9776
9777 switch (pixel_format)
9778 {
9779 case NI_PIX_FMT_YUV420P:
9781 case NI_PIX_FMT_NV12:
9782 case NI_PIX_FMT_P010LE:
9783 case NI_PIX_FMT_NV16:
9784 case NI_PIX_FMT_YUYV422:
9785 case NI_PIX_FMT_UYVY422:
9786 if ((video_width < 0) || (video_width > NI_MAX_RESOLUTION_WIDTH))
9787 {
9788 ni_log(NI_LOG_ERROR, "Video resolution width %d out of range\n",
9789 video_width);
9791 }
9792
9793 if ((video_height < 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT))
9794 {
9795 ni_log(NI_LOG_ERROR, "Video resolution height %d out of range\n",
9796 video_width);
9798 }
9799 break;
9800
9801 case NI_PIX_FMT_RGBA:
9802 case NI_PIX_FMT_BGRA:
9803 case NI_PIX_FMT_ARGB:
9804 case NI_PIX_FMT_ABGR:
9805 case NI_PIX_FMT_BGR0:
9806 case NI_PIX_FMT_BGRP:
9807 /*
9808 * For 2D engine using RGBA, the minimum width is 32. There is no
9809 * height restriction. The 2D engine supports a height/width of up to
9810 * 32K but but we will limit the max height and width to 8K.
9811 */
9812 if ((video_width < 0) || (video_width > NI_MAX_RESOLUTION_WIDTH))
9813 {
9814 ni_log(NI_LOG_ERROR, "Video resolution width %d out of range\n",
9815 video_width);
9817 }
9818
9819 if ((video_height <= 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT))
9820 {
9821 ni_log(NI_LOG_ERROR, "Video resolution height %d out of range\n",
9822 video_height);
9824 }
9825 break;
9826
9827 default:
9828 ni_log(NI_LOG_ERROR, "Unknown pixel format %d\n",pixel_format);
9830 }
9831
9832 if (QUADRA)
9833 {
9834 /* Quadra requires an even-numbered height/width */
9835 height_aligned = NI_VPU_CEIL(video_height, 2);
9836 }
9837 else
9838 {
9839 height_aligned = NI_VPU_ALIGN8(video_height);
9840
9841 if (alignment)
9842 {
9843 /* 16-pixel aligned pixel height for Quadra */
9844 height_aligned = NI_VPU_ALIGN16(video_height);
9845 }
9846 }
9847
9848 switch (pixel_format)
9849 {
9850 case NI_PIX_FMT_YUV420P:
9852 luma_size = linesize[0] * height_aligned;
9853
9854 if (QUADRA)
9855 {
9856 chroma_b_size = linesize[1] * height_aligned / 2;
9857 chroma_r_size = linesize[2] * height_aligned / 2;
9858 }
9859 else
9860 {
9861 chroma_b_size = luma_size / 4;
9862 chroma_r_size = luma_size / 4;
9863 }
9864 break;
9865
9866 case NI_PIX_FMT_RGBA:
9867 case NI_PIX_FMT_BGRA:
9868 case NI_PIX_FMT_ARGB:
9869 case NI_PIX_FMT_ABGR:
9870 case NI_PIX_FMT_BGR0:
9871 luma_size = linesize[0] * video_height;
9872 chroma_b_size = 0;
9873 chroma_r_size = 0;
9874 break;
9875
9876 case NI_PIX_FMT_NV12:
9877 case NI_PIX_FMT_P010LE:
9878 if (QUADRA)
9879 {
9880 luma_size = linesize[0] * height_aligned;
9881 chroma_b_size = linesize[1] * height_aligned / 2;
9882 chroma_r_size = 0;
9883 break;
9884 }
9885 case NI_PIX_FMT_NV16:
9886 if (QUADRA)
9887 {
9888 luma_size = linesize[0] * video_height;
9889 chroma_b_size = linesize[1] * video_height;
9890 chroma_r_size = 0;
9891 break;
9892 }
9893 case NI_PIX_FMT_YUYV422:
9894 case NI_PIX_FMT_UYVY422:
9895 if (QUADRA)
9896 {
9897 luma_size = linesize[0] * video_height;
9898 chroma_b_size = 0;
9899 chroma_r_size = 0;
9900 break;
9901 }
9902 case NI_PIX_FMT_BGRP:
9903 if (QUADRA)
9904 {
9905 luma_size = NI_VPU_ALIGN32(linesize[0] * video_height);
9906 chroma_b_size = NI_VPU_ALIGN32(linesize[1] * video_height);
9907 chroma_r_size = NI_VPU_ALIGN32(linesize[2] * video_height);
9908 break;
9909 }
9910 /*fall through*/
9911 default:
9912 ni_log(NI_LOG_ERROR, "Error: unsupported pixel format %d\n",pixel_format);
9914 }
9915
9916 buffer_size = luma_size + chroma_b_size + chroma_r_size + extra_len;
9917
9918 /* Allocate a buffer size that is page aligned for the host */
9919 buffer_size = NI_VPU_CEIL(buffer_size,NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
9920
9921 /* If this buffer has a different size, realloc a new buffer */
9922 if ((p_frame->buffer_size > 0) && (p_frame->buffer_size != buffer_size))
9923 {
9924 ni_log(NI_LOG_DEBUG, "Free current p_frame, p_frame->buffer_size %u\n",
9925 p_frame->buffer_size);
9926 ni_frame_buffer_free(p_frame);
9927 }
9928
9929 if (p_frame->buffer_size != buffer_size)
9930 {
9931 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
9932 {
9933 ni_log(NI_LOG_ERROR, "Error: Cannot allocate p_frame\n");
9935 LRETURN;
9936 }
9937
9938 memset(p_buffer, 0, buffer_size);
9939 p_frame->buffer_size = buffer_size;
9940 p_frame->p_buffer = p_buffer;
9941 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
9942 }
9943 else
9944 {
9945 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
9946 }
9947
9948 switch (pixel_format)
9949 {
9950 case NI_PIX_FMT_YUV420P:
9952 p_frame->p_data[0] = p_frame->p_buffer;
9953 p_frame->p_data[1] = p_frame->p_data[0] + luma_size;
9954 p_frame->p_data[2] = p_frame->p_data[1] + chroma_b_size;
9955 p_frame->p_data[3] = NULL;
9956
9957 p_frame->data_len[0] = luma_size;
9958 p_frame->data_len[1] = chroma_b_size;
9959 p_frame->data_len[2] = chroma_r_size;
9960 p_frame->data_len[3] = 0;
9961 video_width = NI_VPU_ALIGN128(video_width);
9962 break;
9963
9964 case NI_PIX_FMT_RGBA:
9965 case NI_PIX_FMT_BGRA:
9966 case NI_PIX_FMT_ARGB:
9967 case NI_PIX_FMT_ABGR:
9968 case NI_PIX_FMT_BGR0:
9969 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
9970 p_frame->p_data[1] = NULL;
9971 p_frame->p_data[2] = NULL;
9972 p_frame->p_data[3] = NULL;
9973
9974 p_frame->data_len[0] = luma_size;
9975 p_frame->data_len[1] = 0;
9976 p_frame->data_len[2] = 0;
9977 p_frame->data_len[3] = 0;
9978 video_width = NI_VPU_ALIGN16(video_width);
9979 break;
9980
9981 case NI_PIX_FMT_NV12:
9982 case NI_PIX_FMT_P010LE:
9983 if (QUADRA)
9984 {
9985 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
9986 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
9987 p_frame->p_data[2] = NULL;
9988 p_frame->p_data[3] = NULL;
9989
9990 p_frame->data_len[0] = luma_size;
9991 p_frame->data_len[1] = chroma_b_size;
9992 p_frame->data_len[2] = 0;
9993 p_frame->data_len[3] = 0;
9994
9995 video_width = NI_VPU_ALIGN128(video_width);
9996 break;
9997 }
9998 case NI_PIX_FMT_NV16:
9999 if (QUADRA)
10000 {
10001 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10002 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10003 p_frame->p_data[2] = NULL;
10004 p_frame->p_data[3] = NULL;
10005
10006 p_frame->data_len[0] = luma_size;
10007 p_frame->data_len[1] = chroma_b_size;
10008 p_frame->data_len[2] = 0;
10009 p_frame->data_len[3] = 0;
10010
10011 video_width = NI_VPU_ALIGN64(video_width);
10012 break;
10013 }
10014
10015 case NI_PIX_FMT_YUYV422:
10016 case NI_PIX_FMT_UYVY422:
10017 if (QUADRA)
10018 {
10019 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10020 p_frame->p_data[1] = NULL;
10021 p_frame->p_data[2] = NULL;
10022 p_frame->p_data[3] = NULL;
10023
10024 p_frame->data_len[0] = luma_size;
10025 p_frame->data_len[1] = 0;
10026 p_frame->data_len[2] = 0;
10027 p_frame->data_len[3] = 0;
10028 video_width = NI_VPU_ALIGN16(video_width);
10029 break;
10030 }
10031 case NI_PIX_FMT_BGRP:
10032 if (QUADRA)
10033 {
10034 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10035 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10036 p_frame->p_data[2] = (uint8_t *)p_frame->p_data[1] + chroma_b_size;
10037 p_frame->p_data[3] = NULL;
10038
10039 p_frame->data_len[0] = luma_size;
10040 p_frame->data_len[1] = chroma_b_size;
10041 p_frame->data_len[2] = chroma_r_size;
10042 p_frame->data_len[3] = 0;
10043 break;
10044 }
10045 /* fall through */
10046 default:
10047 ni_log(NI_LOG_ERROR, "Error: unsupported pixel format %d\n",pixel_format);
10048 retval = NI_RETCODE_INVALID_PARAM;
10049 LRETURN;
10050 }
10051
10052 p_frame->video_width = video_width;
10053 p_frame->video_height = height_aligned;
10054
10055 ni_log(NI_LOG_DEBUG, "%s success: w=%d; h=%d; aligned buffer size=%d\n",
10056 __func__, video_width, video_height, buffer_size);
10057
10058END:
10059
10060 if (retval != NI_RETCODE_SUCCESS)
10061 {
10062 ni_aligned_free(p_buffer);
10063 }
10064
10065 return retval;
10066}
10067
10069 ni_network_data_t *p_network,
10070 const char *file)
10071{
10072 FILE *fp = NULL;
10073 struct stat file_stat;
10075 unsigned char *buffer = NULL;
10076
10077 if (!p_ctx)
10078 {
10079 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10080 __func__);
10082 }
10086
10087 char errmsg[NI_ERRNO_LEN] = {0};
10088 if (stat(file, &file_stat) != 0)
10089 {
10091 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to get network binary file stat, %s\n",
10092 __func__, errmsg);
10093 retval = NI_RETCODE_FAILURE;
10094 LRETURN;
10095 }
10096
10097 if (file_stat.st_size == 0)
10098 {
10099 ni_log2(p_ctx, NI_LOG_ERROR, "%s: network binary size is null\n", __func__);
10100 retval = NI_RETCODE_FAILURE;
10101 LRETURN;
10102 }
10103
10104 ni_fopen(&fp, file, "rb");
10105 if (!fp)
10106 {
10108 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to open network binary, %s\n", __func__,
10109 errmsg);
10110 retval = NI_RETCODE_FAILURE;
10111 LRETURN;
10112 }
10113
10114 buffer = malloc(file_stat.st_size);
10115 if (!buffer)
10116 {
10117 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to alloate memory\n", __func__);
10119 LRETURN;
10120 }
10121
10122 if (fread(buffer, file_stat.st_size, 1, fp) != 1)
10123 {
10124 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to read network binary\n", __func__);
10125 retval = NI_RETCODE_FAILURE;
10126 LRETURN;
10127 }
10128
10129 retval =
10130 ni_config_instance_network_binary(p_ctx, buffer, file_stat.st_size);
10131 if (retval != NI_RETCODE_SUCCESS)
10132 {
10133 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to configure instance, retval %d\n",
10134 __func__, retval);
10135 LRETURN;
10136 }
10137
10138 retval = ni_config_read_inout_layers(p_ctx, p_network);
10139 if (retval != NI_RETCODE_SUCCESS)
10140 {
10141 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to read network layers, retval %d\n",
10142 retval);
10143 }
10144
10145END:
10146
10147 if (fp)
10148 {
10149 fclose(fp);
10150 }
10151 free(buffer);
10152
10154 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10156
10157 return retval;
10158}
10159
10161 ni_network_data_t *p_network)
10162{
10164
10165 if (!p_ctx)
10166 {
10167 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10168 __func__);
10170 }
10171
10172 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6ro") < 0))
10173 {
10174 ni_log2(p_ctx, NI_LOG_ERROR, "Error: hvsplus filter not supported on device with FW API version < 6ro\n");
10176 }
10177
10181
10182 retval =
10183 ni_config_instance_hvsplus(p_ctx); //, buffer, file_stat.st_size);
10184 if (retval != NI_RETCODE_SUCCESS)
10185 {
10186 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to configure instance, retval %d\n",
10187 __func__, retval);
10188 LRETURN;
10189 }
10190
10191 retval = ni_config_read_inout_layers(p_ctx, p_network);
10192 if (retval != NI_RETCODE_SUCCESS)
10193 {
10194 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to read network layers, retval %d\n",
10195 retval);
10196 }
10197
10198END:
10199
10201 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10203
10204 return retval;
10205}
10206
10208 ni_network_data_t *p_network)
10209{
10210 uint32_t buffer_size = 0;
10211 void *p_buffer = NULL;
10212 int retval = NI_RETCODE_SUCCESS;
10213 uint32_t i, this_size;
10214 ni_network_layer_info_t *p_linfo;
10215
10216 if (!p_frame || !p_network)
10217 {
10218 ni_log(NI_LOG_ERROR, "Invalid frame or network layer pointer\n");
10220 }
10221
10222 p_linfo = &p_network->linfo;
10223 for (i = 0; i < p_network->input_num; i++)
10224 {
10225 this_size = ni_ai_network_layer_size(&p_linfo->in_param[i]);
10226 this_size =
10227 (this_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
10228 if (p_network->inset[i].offset != buffer_size)
10229 {
10231 "ERROR: %s(): invalid buffer_size of network\n", __func__);
10233 }
10234 buffer_size += this_size;
10235 }
10236
10237 /* fixed size */
10238 p_frame->data_len[0] = buffer_size;
10239
10240 /* Allocate a buffer size that is page aligned for the host */
10241 buffer_size = (buffer_size + NI_MEM_PAGE_ALIGNMENT - 1) &
10242 ~(NI_MEM_PAGE_ALIGNMENT - 1);
10243
10244 /* If this buffer has a different size, realloc a new buffer */
10245 if ((p_frame->buffer_size > 0) && (p_frame->buffer_size != buffer_size))
10246 {
10247 ni_log(NI_LOG_DEBUG, "Free current p_frame, p_frame->buffer_size %u\n",
10248 p_frame->buffer_size);
10249 ni_frame_buffer_free(p_frame);
10250 }
10251
10252 if (p_frame->buffer_size != buffer_size)
10253 {
10254 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10255 {
10256 ni_log(NI_LOG_ERROR, "Error: Cannot allocate p_frame\n");
10258 LRETURN;
10259 }
10260
10261 // memset(p_buffer, 0, buffer_size);
10262 p_frame->buffer_size = buffer_size;
10263 p_frame->p_buffer = p_buffer;
10264 ni_log(NI_LOG_DEBUG, "%s(): allocated new p_frame buffer\n", __func__);
10265 } else
10266 {
10267 ni_log(NI_LOG_DEBUG, "%s(): reuse p_frame buffer\n", __func__);
10268 }
10269
10270 p_frame->p_data[0] = p_frame->p_buffer;
10271 p_frame->p_data[1] = NULL;
10272 p_frame->p_data[2] = NULL;
10273 p_frame->p_data[3] = NULL;
10274
10275 p_frame->iovec = NULL;
10276 p_frame->iovec_num = 0;
10277
10278 ni_log(NI_LOG_DEBUG, "%s() success: aligned buffer size=%u\n", __func__,
10279 buffer_size);
10280
10281END:
10282
10283 if (retval != NI_RETCODE_SUCCESS)
10284 {
10285 ni_aligned_free(p_buffer);
10286 }
10287
10288 return retval;
10289}
10290
10292 ni_network_data_t *p_network)
10293{
10294 void *p_buffer = NULL;
10295 int retval = NI_RETCODE_SUCCESS;
10296 uint32_t buffer_size = 0;
10297 uint32_t i, data_size;
10298 ni_network_layer_info_t *p_linfo;
10299
10300 if (!p_packet || !p_network)
10301 {
10302 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameters passed\n",
10303 __func__);
10305 }
10306
10307 p_linfo = &p_network->linfo;
10308 for (i = 0; i < p_network->output_num; i++)
10309 {
10310 data_size = ni_ai_network_layer_size(&p_linfo->out_param[i]);
10311 data_size =
10312 (data_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
10313 if (p_network->outset[i].offset != buffer_size)
10314 {
10316 "ERROR: %s(): invalid buffer_size of network\n", __func__);
10318 }
10319 buffer_size += data_size;
10320 }
10321 data_size = buffer_size;
10322
10323 ni_log(NI_LOG_DEBUG, "%s(): packet_size=%u\n", __func__, buffer_size);
10324
10325 if (buffer_size & (NI_MEM_PAGE_ALIGNMENT - 1))
10326 {
10327 buffer_size = (buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
10328 ~(NI_MEM_PAGE_ALIGNMENT - 1);
10329 }
10330
10331 if (p_packet->buffer_size == buffer_size)
10332 {
10333 p_packet->p_data = p_packet->p_buffer;
10334 ni_log(NI_LOG_DEBUG, "%s(): reuse current p_packet buffer\n", __func__);
10335 LRETURN; //Already allocated the exact size
10336 } else if (p_packet->buffer_size > 0)
10337 {
10339 "%s(): free current p_packet, p_packet->buffer_size=%u\n",
10340 __func__, p_packet->buffer_size);
10341 ni_packet_buffer_free(p_packet);
10342 }
10343 ni_log(NI_LOG_DEBUG, "%s(): Allocating p_packet buffer, buffer_size=%u\n",
10344 __func__, buffer_size);
10345
10346 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10347 {
10348 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_packet buffer.\n",
10349 NI_ERRNO, __func__);
10351 LRETURN;
10352 }
10353
10354 p_packet->buffer_size = buffer_size;
10355 p_packet->p_buffer = p_buffer;
10356 p_packet->p_data = p_packet->p_buffer;
10357 p_packet->data_len = data_size;
10358
10359END:
10360
10361 if (NI_RETCODE_SUCCESS != retval)
10362 {
10363 ni_aligned_free(p_buffer);
10364 }
10365
10366 ni_log(NI_LOG_TRACE, "%s(): exit: p_packet->buffer_size=%u\n", __func__,
10367 p_packet->buffer_size);
10368
10369 return retval;
10370}
10371
10372/*!*****************************************************************************
10373 * \brief Reconfigure bitrate dynamically during encoding.
10374 *
10375 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10376 * \param[in] bitrate Target bitrate to set
10377 *
10378 * \return On success NI_RETCODE_SUCCESS
10379 * On failure NI_RETCODE_INVALID_PARAM
10380 ******************************************************************************/
10382{
10383 if (!p_ctx || bitrate < NI_MIN_BITRATE || bitrate > NI_MAX_BITRATE)
10384 {
10385 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid bitrate passed in %d\n",
10386 __func__, bitrate);
10388 }
10391
10392 if (p_ctx->target_bitrate > 0)
10393 {
10394 ni_log2(p_ctx, NI_LOG_DEBUG,
10395 "Warning: %s(): bitrate %d overwriting current one %d\n",
10396 __func__, bitrate, p_ctx->target_bitrate);
10397 }
10398
10399 p_ctx->target_bitrate = bitrate;
10400
10401 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10403
10404 return NI_RETCODE_SUCCESS;
10405}
10406
10407/*!*****************************************************************************
10408 * \brief Reconfigure intraPeriod dynamically during encoding.
10409 *
10410 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10411 * \param[in] intra_period Target intra period to set
10412 *
10413 *
10414 * \return On success NI_RETCODE_SUCCESS
10415 * On failure NI_RETCODE_INVALID_PARAM
10416 *
10417 * NOTE - the frame upon which intra period is reconfigured is encoded as IDR frame
10418 * NOTE - reconfigure intra period is not allowed if intraRefreshMode is enabled or if gopPresetIdx is 1
10419 *
10420 ******************************************************************************/
10422 int32_t intra_period)
10423{
10424 if (!p_ctx || intra_period < 0 || intra_period > 1024)
10425 {
10426 ni_log(NI_LOG_ERROR, "ERROR: %s(): invalid intraPeriod passed in %d\n",
10427 __func__, intra_period);
10429 }
10432
10433 if (p_ctx->reconfig_intra_period >= 0)
10434 {
10436 "Warning: %s(): intraPeriod %d overwriting current one %d\n",
10437 __func__, intra_period, p_ctx->reconfig_intra_period);
10438 }
10439
10440 p_ctx->reconfig_intra_period = intra_period;
10441
10442 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10444
10445 return NI_RETCODE_SUCCESS;
10446}
10447
10448/*!*****************************************************************************
10449 * \brief Reconfigure VUI HRD dynamically during encoding.
10450 *
10451 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10452 * \param[in] bitrate Target bitrate to set
10453 *
10454 * \return On success NI_RETCODE_SUCCESS
10455 * On failure NI_RETCODE_INVALID_PARAM
10456 ******************************************************************************/
10458{
10459 if (!p_ctx || vui->colorDescPresent < 0 || vui->colorDescPresent > 1)
10460 {
10461 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid colorDescPresent passed in %d\n",
10462 __func__, vui->colorDescPresent);
10464 }
10465
10467 {
10468 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid aspect ratio passed in (%dx%d)\n",
10469 __func__, vui->aspectRatioWidth, vui->aspectRatioHeight);
10471 }
10472
10473 if (vui->videoFullRange < 0 || vui->videoFullRange > 1)
10474 {
10475 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid videoFullRange passed in %d\n",
10476 __func__, vui->videoFullRange);
10478 }
10479
10482
10484 p_ctx->vui.colorPrimaries = vui->colorPrimaries;
10485 p_ctx->vui.colorTrc = vui->colorTrc;
10486 p_ctx->vui.colorSpace = vui->colorSpace;
10489 p_ctx->vui.videoFullRange = vui->videoFullRange;
10490
10491 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10493
10494 return NI_RETCODE_SUCCESS;
10495}
10496
10497/*!*****************************************************************************
10498 * \brief Force next frame to be IDR frame during encoding.
10499 *
10500 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10501 *
10502 * \return On success NI_RETCODE_SUCCESS
10503 ******************************************************************************/
10505{
10506 if (!p_ctx)
10507 {
10508 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10509 __func__);
10511 }
10514
10515 if (p_ctx->force_idr_frame)
10516 {
10517 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: %s(): already forcing IDR frame\n",
10518 __func__);
10519 }
10520
10521 p_ctx->force_idr_frame = 1;
10522
10523 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10525
10526 return NI_RETCODE_SUCCESS;
10527}
10528
10529/*!*****************************************************************************
10530 * \brief Set a frame's support of Long Term Reference frame during encoding.
10531 *
10532 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10533 * \param[in] ltr Pointer to struct specifying LTR support
10534 *
10535 * \return On success NI_RETCODE_SUCCESS
10536 * On failure NI_RETCODE_INVALID_PARAM
10537 ******************************************************************************/
10539{
10540 if (!p_ctx)
10541 {
10542 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10543 __func__);
10545 }
10547
10551
10553
10554 return NI_RETCODE_SUCCESS;
10555}
10556
10557/*!*****************************************************************************
10558 * \brief Set Long Term Reference interval
10559 *
10560 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10561 * \param[in] ltr_interval the new long term reference inteval value
10562 *
10563 * \return On success NI_RETCODE_SUCCESS
10564 * On failure NI_RETCODE_INVALID_PARAM
10565 ******************************************************************************/
10567 int32_t ltr_interval)
10568{
10569 if (!p_ctx)
10570 {
10571 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10572 __func__);
10574 }
10576
10577 p_ctx->ltr_interval = ltr_interval;
10578
10580
10581 return NI_RETCODE_SUCCESS;
10582}
10583
10584/*!*****************************************************************************
10585 * \brief Set frame reference invalidation
10586 *
10587 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10588 * \param[in] frame_num frame number after which all references shall be
10589 * invalidated
10590 *
10591 * \return On success NI_RETCODE_SUCCESS
10592 * On failure NI_RETCODE_INVALID_PARAM
10593 ******************************************************************************/
10595 int32_t frame_num)
10596{
10597 if (!p_ctx)
10598 {
10599 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10600 __func__);
10602 }
10604 p_ctx->ltr_frame_ref_invalid = frame_num;
10606
10607 return NI_RETCODE_SUCCESS;
10608}
10609
10610/*!*****************************************************************************
10611 * \brief Reconfigure framerate dynamically during encoding.
10612 *
10613 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10614 * \param[in] framerate Target framerate to set
10615 *
10616 * \return On success NI_RETCODE_SUCCESS
10617 * On failure NI_RETCODE_INVALID_PARAM
10618 ******************************************************************************/
10620 ni_framerate_t *framerate)
10621{
10622 int32_t framerate_num = framerate->framerate_num;
10623 int32_t framerate_denom = framerate->framerate_denom;
10624 if (!p_ctx || framerate_num <= 0 || framerate_denom <= 0)
10625 {
10626 ni_log2(p_ctx, NI_LOG_ERROR,
10627 "ERROR: %s(): invalid framerate passed in (%d/%d)\n", __func__,
10628 framerate_num, framerate_denom);
10630 }
10631
10632 if ((framerate_num % framerate_denom) != 0)
10633 {
10634 uint32_t numUnitsInTick = 1000;
10635 framerate_num = framerate_num / framerate_denom;
10636 framerate_denom = numUnitsInTick + 1;
10637 framerate_num += 1;
10638 framerate_num *= numUnitsInTick;
10639 } else
10640 {
10641 framerate_num = framerate_num / framerate_denom;
10642 framerate_denom = 1;
10643 }
10644
10645 if (((framerate_num + framerate_denom - 1) / framerate_denom) >
10647 {
10648 ni_log2(p_ctx, NI_LOG_ERROR,
10649 "ERROR: %s(): invalid framerate passed in (%d/%d)\n", __func__,
10650 framerate->framerate_num, framerate->framerate_denom);
10652 }
10653
10656
10657 if (p_ctx->framerate.framerate_num > 0)
10658 {
10659 ni_log2(p_ctx, NI_LOG_DEBUG,
10660 "Warning: %s(): framerate (%d/%d) overwriting current "
10661 "one (%d/%d)\n",
10662 __func__, framerate_num, framerate_denom,
10663 p_ctx->framerate.framerate_num,
10664 p_ctx->framerate.framerate_denom);
10665 }
10666
10667 p_ctx->framerate.framerate_num = framerate_num;
10668 p_ctx->framerate.framerate_denom = framerate_denom;
10669
10670 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10672
10673 return NI_RETCODE_SUCCESS;
10674}
10675
10676/*!*****************************************************************************
10677 * \brief Reconfigure maxFrameSize dynamically during encoding.
10678 *
10679 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10680 * \param[in] max_frame_size maxFrameSize to set
10681 *
10682 * \return On success NI_RETCODE_SUCCESS
10683 * On failure NI_RETCODE_INVALID_PARAM
10684 *
10685 * NOTE - maxFrameSize_Bytes value less than ((bitrate / 8) / framerate) will be rejected
10686 *
10687 ******************************************************************************/
10689{
10690 ni_xcoder_params_t *api_param;
10691 int32_t bitrate, framerate_num, framerate_denom;
10692 uint32_t maxFrameSize = (uint32_t)max_frame_size / 2000;
10693 uint32_t min_maxFrameSize;
10694
10695 if (!p_ctx || !p_ctx->p_session_config)
10696 {
10697 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10698 __func__);
10700 }
10701
10702 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10703
10704 if (!api_param->low_delay_mode)
10705 {
10706 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size is valid only when lowDelay mode is enabled\n",
10707 __func__, max_frame_size);
10709 }
10710
10711 bitrate = (p_ctx->target_bitrate > 0) ? p_ctx->target_bitrate : api_param->bitrate;
10712
10713 if ((p_ctx->framerate.framerate_num > 0) && (p_ctx->framerate.framerate_denom > 0))
10714 {
10715 framerate_num = p_ctx->framerate.framerate_num;
10716 framerate_denom = p_ctx->framerate.framerate_denom;
10717 }
10718 else
10719 {
10720 framerate_num = (int32_t) api_param->fps_number;
10721 framerate_denom = (int32_t) api_param->fps_denominator;
10722 }
10723
10724 min_maxFrameSize = (((uint32_t)bitrate / framerate_num * framerate_denom) / 8) / 2000;
10725
10726 if (maxFrameSize < min_maxFrameSize)
10727 {
10728 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size %d is too small (invalid)\n",
10729 __func__, max_frame_size);
10731 }
10732 if (max_frame_size > NI_MAX_FRAME_SIZE) {
10733 max_frame_size = NI_MAX_FRAME_SIZE;
10734 }
10735
10738
10739 if (p_ctx->max_frame_size > 0)
10740 {
10741 ni_log2(p_ctx, NI_LOG_DEBUG,
10742 "Warning: %s(): max_frame_size %d overwriting current one %d\n",
10743 __func__, max_frame_size, p_ctx->max_frame_size);
10744 }
10745
10746 p_ctx->max_frame_size = max_frame_size;
10747
10748 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10750
10751 return NI_RETCODE_SUCCESS;
10752}
10753
10754/*!*****************************************************************************
10755 * \brief Reconfigure min&max qp dynamically during encoding.
10756 *
10757 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10758 * \param[in] ni_rc_min_max_qp Target min&max qp to set
10759 *
10760 * \return On success NI_RETCODE_SUCCESS
10761 * On failure NI_RETCODE_INVALID_PARAM
10762 ******************************************************************************/
10764 ni_rc_min_max_qp *p_min_max_qp)
10765{
10766 int32_t minQpI, maxQpI, maxDeltaQp, minQpPB, maxQpPB;
10767
10768 if (!p_ctx || !p_min_max_qp)
10769 {
10770 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_min_max_qp pointer\n",
10771 __func__);
10773 }
10774
10775 minQpI = p_min_max_qp->minQpI;
10776 maxQpI = p_min_max_qp->maxQpI;
10777 maxDeltaQp = p_min_max_qp->maxDeltaQp;
10778 minQpPB = p_min_max_qp->minQpPB;
10779 maxQpPB = p_min_max_qp->maxQpPB;
10780
10781 if (minQpI > maxQpI || minQpPB > maxQpPB ||
10782 maxQpI > 51 || minQpI < 0 || maxQpPB > 51 || minQpPB < 0)
10783 {
10784 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid qp setting <%d %d %d %d %d>\n",
10785 __func__, minQpI, maxQpI, maxDeltaQp, minQpPB, maxQpPB);
10787 }
10788
10791
10792 p_ctx->enc_change_params->minQpI = minQpI;
10793 p_ctx->enc_change_params->maxQpI = maxQpI;
10794 p_ctx->enc_change_params->maxDeltaQp = maxDeltaQp;
10795 p_ctx->enc_change_params->minQpPB = minQpPB;
10796 p_ctx->enc_change_params->maxQpPB = maxQpPB;
10797
10798 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10800
10801 return NI_RETCODE_SUCCESS;
10802}
10803
10804/*!*****************************************************************************
10805 * \brief Reconfigure crf value dynamically during encoding.
10806 *
10807 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10808 * \param[in] crf crf value to reconfigure
10809 *
10810 * \return On success NI_RETCODE_SUCCESS
10811 * On failure NI_RETCODE_INVALID_PARAM
10812 ******************************************************************************/
10814 int32_t crf)
10815{
10816 ni_xcoder_params_t *api_param;
10817
10818 if (!p_ctx || !p_ctx->p_session_config)
10819 {
10820 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10821 __func__);
10823 }
10824
10825 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10826
10827 if (api_param->cfg_enc_params.crf < 0)
10828 {
10829 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %d is valid only in CRF mode\n",
10830 __func__, crf);
10832 }
10833
10834 if (crf < 0 || crf > 51)
10835 {
10836 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %d is invalid (valid range in [0..51])\n",
10837 __func__, crf);
10839 }
10840
10842
10844
10845 if (p_ctx->reconfig_crf >= 0)
10846 {
10847 ni_log2(p_ctx, NI_LOG_DEBUG,
10848 "Warning: %s(): crf reconfig value %d overwriting current reconfig_crf %d\n",
10849 __func__, crf, p_ctx->reconfig_crf);
10850 }
10851
10852 p_ctx->reconfig_crf = crf;
10853
10854 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10855
10857
10858 return NI_RETCODE_SUCCESS;
10859}
10860
10861/*!*****************************************************************************
10862 * \brief Reconfigure crf float point value dynamically during encoding.
10863 *
10864 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10865 * \param[in] crf crf float point value to reconfigure
10866 *
10867 * \return On success NI_RETCODE_SUCCESS
10868 * On failure NI_RETCODE_INVALID_PARAM
10869 ******************************************************************************/
10871 float crf)
10872{
10873 ni_xcoder_params_t *api_param;
10874
10875 if (!p_ctx || !p_ctx->p_session_config)
10876 {
10877 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10878 __func__);
10880 }
10881
10882 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10883
10884 if (api_param->cfg_enc_params.crfFloat < 0)
10885 {
10886 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %f is valid only in CRF mode\n",
10887 __func__, crf);
10889 }
10890
10891 if (crf < 0.0 || crf > 51.0)
10892 {
10893 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %f is invalid (valid range in [0..51])\n",
10894 __func__, crf);
10896 }
10897
10899
10901
10902 if (p_ctx->reconfig_crf >= 0 || p_ctx->reconfig_crf_decimal > 0)
10903 {
10904 ni_log2(p_ctx, NI_LOG_DEBUG,
10905 "Warning: %s(): crf reconfig value %d overwriting current "
10906 "reconfig_crf %d, reconfig_crf_decimal %d\n", __func__,
10907 crf, p_ctx->reconfig_crf, p_ctx->reconfig_crf_decimal);
10908 }
10909
10910 p_ctx->reconfig_crf = (int)crf;
10911 p_ctx->reconfig_crf_decimal = (int)((crf - (float)p_ctx->reconfig_crf) * 100);
10912
10913 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10914
10916
10917 return NI_RETCODE_SUCCESS;
10918}
10919
10920/*!*****************************************************************************
10921 * \brief Reconfigure vbv buffer size and vbv max rate dynamically during encoding.
10922 *
10923 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10924 * \param[in] vbvBufferSize Target vbvBufferSize to set
10925 * \param[in] vbvMaxRate Target vbvMaxRate to set
10926 *
10927 * \return On success NI_RETCODE_SUCCESS
10928 * On failure NI_RETCODE_INVALID_PARAM
10929 ******************************************************************************/
10931 int32_t vbvMaxRate, int32_t vbvBufferSize)
10932{
10933 ni_xcoder_params_t *api_param;
10934 if (!p_ctx || !p_ctx->p_session_config)
10935 {
10936 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10937 __func__);
10939 }
10940 if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
10941 {
10942 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): vbvBufferSize value %d\n",
10943 __func__, vbvBufferSize);
10945 }
10946 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10947 if (api_param->bitrate > 0 && vbvMaxRate > 0 && vbvMaxRate < api_param->bitrate) {
10948 ni_log2(p_ctx, NI_LOG_ERROR, "vbvMaxRate %u cannot be smaller than bitrate %d\n",
10949 vbvMaxRate, api_param->bitrate);
10951 }
10952 if (vbvBufferSize == 0 && vbvMaxRate > 0) {
10953 ni_log2(p_ctx, NI_LOG_INFO, "vbvMaxRate %d does not take effect when "
10954 "vbvBufferSize is 0, force vbvMaxRate to 0\n",
10955 vbvMaxRate);
10956 vbvMaxRate = 0;
10957 }
10958
10961
10962 p_ctx->reconfig_vbv_buffer_size = vbvBufferSize;
10963 p_ctx->reconfig_vbv_max_rate = vbvMaxRate;
10964
10965 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10967
10968 return NI_RETCODE_SUCCESS;
10969}
10970
10971/*!*****************************************************************************
10972 * \brief Reconfigure maxFrameSizeRatio dynamically during encoding.
10973 *
10974 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10975 * \param[in] max_frame_size_ratio maxFrameSizeRatio to set
10976 *
10977 * \return On success NI_RETCODE_SUCCESS
10978 * On failure NI_RETCODE_INVALID_PARAM
10979 ******************************************************************************/
10981{
10982 ni_xcoder_params_t *api_param;
10983 int32_t bitrate, framerate_num, framerate_denom;
10984 uint32_t min_maxFrameSize, maxFrameSize;
10985
10986 if (!p_ctx || !p_ctx->p_session_config)
10987 {
10988 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10989 __func__);
10991 }
10992
10993 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10994
10995 if (!api_param->low_delay_mode)
10996 {
10997 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size_ratio is valid only when lowDelay mode is enabled\n",
10998 __func__, max_frame_size_ratio);
11000 }
11001
11002 if (max_frame_size_ratio < 1) {
11003 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size_ratio %d cannot < 1\n",
11004 max_frame_size_ratio);
11006 }
11007
11008 bitrate = (p_ctx->target_bitrate > 0) ? p_ctx->target_bitrate : api_param->bitrate;
11009
11010 if ((p_ctx->framerate.framerate_num > 0) && (p_ctx->framerate.framerate_denom > 0))
11011 {
11012 framerate_num = p_ctx->framerate.framerate_num;
11013 framerate_denom = p_ctx->framerate.framerate_denom;
11014 }
11015 else
11016 {
11017 framerate_num = (int32_t) api_param->fps_number;
11018 framerate_denom = (int32_t) api_param->fps_denominator;
11019 }
11020
11021 min_maxFrameSize = (((uint32_t)bitrate / framerate_num * framerate_denom) / 8) / 2000;
11022
11023 maxFrameSize = min_maxFrameSize * max_frame_size_ratio > NI_MAX_FRAME_SIZE ?
11024 NI_MAX_FRAME_SIZE : min_maxFrameSize * max_frame_size_ratio;
11025
11028
11029 if (p_ctx->max_frame_size > 0)
11030 {
11031 ni_log2(p_ctx, NI_LOG_DEBUG,
11032 "Warning: %s(): max_frame_size %d overwriting current one %d\n",
11033 __func__, maxFrameSize, p_ctx->max_frame_size);
11034 }
11035
11036 p_ctx->max_frame_size = maxFrameSize;
11037
11038 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11040
11041 return NI_RETCODE_SUCCESS;
11042}
11043
11044/*!*****************************************************************************
11045 * \brief Reconfigure sliceArg dynamically during encoding.
11046 *
11047 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11048 * \param[in] sliceArg the new sliceArg value
11049 *
11050 * \return On success NI_RETCODE_SUCCESS
11051 * On failure NI_RETCODE_INVALID_PARAM
11052 ******************************************************************************/
11054{
11055 ni_xcoder_params_t *api_param;
11057
11058 if (!p_ctx || !p_ctx->p_session_config)
11059 {
11060 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11061 __func__);
11063 }
11064
11065 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11066 p_enc = &api_param->cfg_enc_params;
11067 if (p_enc->slice_mode == 0)
11068 {
11069 ni_log2(p_ctx, NI_LOG_ERROR, "%s():not support to reconfig slice_arg when slice_mode disable.\n",
11070 __func__);
11071 sliceArg = 0;
11072 }
11074 {
11075 ni_log2(p_ctx, NI_LOG_ERROR, "%s():sliceArg is only supported for H.264 or H.265.\n",
11076 __func__);
11077 sliceArg = 0;
11078 }
11079 int ctu_mb_size = (NI_CODEC_FORMAT_H264 == p_ctx->codec_format) ? 16 : 64;
11080 int max_num_ctu_mb_row = (api_param->source_height + ctu_mb_size - 1) / ctu_mb_size;
11081 if (sliceArg < 1 || sliceArg > max_num_ctu_mb_row)
11082 {
11083 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid data sliceArg %d\n", __func__,
11084 sliceArg);
11085 sliceArg = 0;
11086 }
11087
11090
11091 p_ctx->reconfig_slice_arg = sliceArg;
11092
11093 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11095
11096 return NI_RETCODE_SUCCESS;
11097}
11098
11099#ifndef _WIN32
11100/*!*****************************************************************************
11101* \brief Acquire a P2P frame buffer from the hwupload session
11102*
11103* \param[in] p_ctx Pointer to a caller allocated
11104* ni_session_context_t struct
11105* \param[out] p_frame Pointer to a caller allocated hw frame
11106*
11107* \return On success
11108* NI_RETCODE_SUCCESS
11109* On failure
11110* NI_RETCODE_INVALID_PARAM
11111* NI_RETCODE_ERROR_NVME_CMD_FAILED
11112* NI_RETCODE_ERROR_INVALID_SESSION
11113*******************************************************************************/
11115{
11117 struct netint_iocmd_export_dmabuf uexp;
11118 unsigned int offset;
11119 int ret, is_semi_planar;
11120 int linestride[NI_MAX_NUM_DATA_POINTERS];
11121 int alignedheight[NI_MAX_NUM_DATA_POINTERS];
11122 niFrameSurface1_t hwdesc = {0};
11123 niFrameSurface1_t *p_surface;
11124
11125 if (p_ctx == NULL || p_frame == NULL || p_frame->p_data[3] == NULL)
11126 {
11127 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
11128 __func__);
11130 }
11131
11132 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11133
11136
11137 retval = ni_hwupload_session_read_hwdesc(p_ctx, &hwdesc);
11138
11141
11142 if (retval != NI_RETCODE_SUCCESS)
11143 {
11144 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: hwdesc read failure %d\n", retval);
11145 return retval;
11146 }
11147
11148 retval = ni_get_memory_offset(p_ctx, &hwdesc, &offset);
11149 if (retval != NI_RETCODE_SUCCESS)
11150 {
11151 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: bad buffer id\n");
11153 }
11154
11155 is_semi_planar = ((p_ctx->pixel_format == NI_PIX_FMT_NV12) ||
11156 p_ctx->pixel_format == NI_PIX_FMT_P010LE) ?
11157 1 :
11158 0;
11159
11161 p_ctx->bit_depth_factor, is_semi_planar, linestride,
11162 alignedheight);
11163
11164 uexp.fd = -1;
11165 uexp.flags = 0;
11166 uexp.offset = offset;
11167
11168 uexp.length = ni_calculate_total_frame_size(p_ctx, linestride);
11169 uexp.domain = p_ctx->domain;
11170 uexp.bus = p_ctx->bus;
11171 uexp.dev = p_ctx->dev;
11172 uexp.fn = p_ctx->fn;
11173 uexp.bar = 4; // PCI BAR4 configuration space
11174
11175 ret = ioctl(p_ctx->netint_fd, NETINT_IOCTL_EXPORT_DMABUF, &uexp);
11176 if (ret < 0)
11177 {
11178 ni_log2(p_ctx, NI_LOG_ERROR, "%s: Failed to export dmabuf %d errno %d\n",
11179 __func__, ret, NI_ERRNO);
11180 return NI_RETCODE_FAILURE;
11181 }
11182
11183 *p_surface = hwdesc;
11184 p_surface->ui16width = p_ctx->active_video_width;
11185 p_surface->ui16height = p_ctx->active_video_height;
11186 p_surface->ui32nodeAddress = offset;
11187 p_surface->encoding_type = is_semi_planar ?
11190 p_surface->dma_buf_fd = uexp.fd;
11191
11192 return retval;
11193}
11194
11195/*!*****************************************************************************
11196* \brief Acquire a P2P frame buffer from the hwupload session for P2P read
11197*
11198* \param[in] p_ctx Pointer to a caller allocated
11199* ni_session_context_t struct
11200* \param[out] p_frame Pointer to a caller allocated hw frame
11201*
11202* \return On success
11203* NI_RETCODE_SUCCESS
11204* On failure
11205* NI_RETCODE_INVALID_PARAM
11206* NI_RETCODE_ERROR_NVME_CMD_FAILED
11207* NI_RETCODE_ERROR_INVALID_SESSION
11208*******************************************************************************/
11210{
11212
11213 int is_semi_planar;
11214 int linestride[NI_MAX_NUM_DATA_POINTERS];
11215 int alignedheight[NI_MAX_NUM_DATA_POINTERS];
11216 niFrameSurface1_t hwdesc = {0};
11217 niFrameSurface1_t *p_surface;
11218
11219 if (p_ctx == NULL || p_frame == NULL || p_frame->p_data[3] == NULL)
11220 {
11221 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
11222 __func__);
11224 }
11225
11226 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11227
11230
11231 retval = ni_hwupload_session_read_hwdesc(p_ctx, &hwdesc);
11232
11235
11236 if (retval != NI_RETCODE_SUCCESS)
11237 {
11238 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: hwdesc read failure %d\n", retval);
11239 return retval;
11240 }
11241
11242 is_semi_planar = ((p_ctx->pixel_format == NI_PIX_FMT_NV12) ||
11243 p_ctx->pixel_format == NI_PIX_FMT_P010LE) ?
11244 1 :
11245 0;
11246
11248 p_ctx->bit_depth_factor, is_semi_planar, linestride,
11249 alignedheight);
11250
11251 *p_surface = hwdesc;
11252 p_surface->ui16width = p_ctx->active_video_width;
11253 p_surface->ui16height = p_ctx->active_video_height;
11254 p_surface->ui32nodeAddress = 0;
11255 p_surface->encoding_type = is_semi_planar ?
11258 p_surface->dma_buf_fd = 0;
11259
11260 return retval;
11261}
11262
11263
11264/*!*****************************************************************************
11265 * \brief Lock a hardware P2P frame prior to encoding
11266 *
11267 * \param[in] p_upl_ctx pointer to caller allocated upload context
11268 * [in] p_frame pointer to caller allocated hardware P2P frame
11269 *
11270 * \return On success
11271 * NI_RETCODE_SUCCESS
11272 * On failure NI_RETCODE_FAILURE
11273 * NI_RETCODE_INVALID_PARAM
11274*******************************************************************************/
11276 ni_frame_t *p_frame)
11277{
11278 int ret;
11279 struct netint_iocmd_attach_rfence uatch = {0};
11280 struct pollfd pfds[1] = {0};
11281 niFrameSurface1_t *p_surface;
11282
11283 if (p_upl_ctx == NULL || p_frame == NULL)
11284 {
11285 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: bad parameters\n", __func__);
11287 }
11288
11289 if (p_frame->p_data[3] == NULL)
11290 {
11291 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: not a hardware frame\n", __func__);
11293 }
11294
11295 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11296
11297 pfds[0].fd = p_surface->dma_buf_fd;
11298 pfds[0].events = POLLIN;
11299 pfds[0].revents = 0;
11300
11301 ret = poll(pfds, 1, -1);
11302 char errmsg[NI_ERRNO_LEN] = {0};
11303 if (ret < 0)
11304 {
11306 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s:failed to poll dmabuf fd errno %s\n", __func__,
11307 errmsg);
11308 return ret;
11309 }
11310
11311 uatch.fd = p_surface->dma_buf_fd;
11312 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_ATTACH_RFENCE, &uatch);
11313 if (ret < 0)
11314 {
11316 ni_log2(p_upl_ctx, NI_LOG_ERROR,
11317 "%s: failed to attach dmabuf read fence errno %s\n", __func__,
11318 errmsg);
11319 return ret;
11320 }
11321
11322 return NI_RETCODE_SUCCESS;
11323}
11324
11325/*!*****************************************************************************
11326 * \brief Unlock a hardware P2P frame after encoding
11327 *
11328 * \param[in] p_upl_ctx pointer to caller allocated upload context
11329 * [in] p_frame pointer to caller allocated hardware P2P frame
11330 *
11331 * \return On success
11332 * NI_RETCODE_SUCCESS
11333 * On failure NI_RETCODE_FAILURE
11334 * NI_RETCODE_INVALID_PARAM
11335*******************************************************************************/
11337 ni_frame_t *p_frame)
11338{
11339 int ret;
11340 struct netint_iocmd_signal_rfence usigl = {0};
11341 niFrameSurface1_t *p_surface;
11342
11343 if ((p_upl_ctx == NULL) || (p_frame == NULL))
11344 {
11345 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid parameters %p %p\n", __func__,
11346 p_upl_ctx, p_frame);
11348 }
11349
11350 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11351
11352 if (p_surface == NULL)
11353 {
11354 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid hw frame\n", __func__);
11356 }
11357
11358 usigl.fd = p_surface->dma_buf_fd;
11359 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_SIGNAL_RFENCE, &usigl);
11360 if (ret < 0)
11361 {
11362 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Failed to signal dmabuf read fence\n");
11363 return NI_RETCODE_FAILURE;
11364 }
11365
11366 return NI_RETCODE_SUCCESS;
11367}
11368
11369/*!*****************************************************************************
11370 * \brief Special P2P test API function. Copies YUV data from the software
11371 * frame to the hardware P2P frame on the Quadra device
11372 *
11373 * \param[in] p_upl_ctx pointer to caller allocated uploader session
11374 * context
11375 * [in] p_swframe pointer to a caller allocated software frame
11376 * [in] p_hwframe pointer to a caller allocated hardware frame
11377 *
11378 * \return On success
11379 * NI_RETCODE_SUCCESS
11380 * On failure
11381 * NI_RETCODE_FAILURE
11382 * NI_RETCODE_INVALID_PARAM
11383*******************************************************************************/
11385 uint8_t *p_data, uint32_t len,
11386 ni_frame_t *p_hwframe)
11387{
11388 int ret;
11389 struct netint_iocmd_issue_request uis = {0};
11390 niFrameSurface1_t *p_surface;
11391
11392 if (p_upl_ctx == NULL || p_data == NULL || p_hwframe == NULL)
11393 {
11394 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: invalid null parameters\n", __func__);
11396 }
11397
11398 if (p_hwframe->p_data[3] == NULL)
11399 {
11400 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: empty frame\n", __func__);
11402 }
11403
11404 p_surface = (niFrameSurface1_t *)p_hwframe->p_data[3];
11405
11406 uis.fd = p_surface->dma_buf_fd;
11407 uis.data = p_data;
11408 uis.len = len;
11410
11411 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_ISSUE_REQ, &uis);
11412 if (ret < 0)
11413 {
11414 ni_log2(p_upl_ctx, NI_LOG_ERROR,
11415 "%s: Failed to request dmabuf rendering errno %d\n", __func__,
11416 NI_ERRNO);
11417 return NI_RETCODE_FAILURE;
11418 }
11419
11420 return NI_RETCODE_SUCCESS;
11421}
11422
11423/*!*****************************************************************************
11424 * \brief Special P2P test API function. Copies video data from the software
11425 * frame to the hardware P2P frame on the Quadra device. Does not
11426 * need the Netint kernel driver but requires root privilege.
11427 *
11428 * \param[in] p_upl_ctx pointer to caller allocated uploader session
11429 * context
11430 * [in] p_swframe pointer to a caller allocated software frame
11431 * [in] p_hwframe pointer to a caller allocated hardware frame
11432 *
11433 * \return On success
11434 * NI_RETCODE_SUCCESS
11435 * On failure
11436 * NI_RETCODE_FAILURE
11437 * NI_RETCODE_INVALID_PARAM
11438*******************************************************************************/
11440 uint8_t *p_data, uint32_t len,
11441 ni_frame_t *p_hwframe)
11442{
11443 int bar4_fd, ret;
11444 char bar4_name[128];
11445 char *bar4_mm;
11446 struct stat stat;
11447 niFrameSurface1_t *pSurf;
11448 uint32_t offset;
11449
11450 pSurf = (niFrameSurface1_t *) p_hwframe->p_data[3];
11451
11452 ret = ni_get_memory_offset(p_upl_ctx, pSurf, &offset);
11453 if (ret != 0)
11454 {
11455 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Error bad buffer id\n");
11456 return NI_RETCODE_FAILURE;
11457 }
11458
11459 snprintf(bar4_name, 128,
11460 "/sys/bus/pci/devices/%04x:%02x:%02x.%1x/resource4",
11461 p_upl_ctx->domain,p_upl_ctx->bus,p_upl_ctx->dev,p_upl_ctx->fn);
11462
11463 bar4_fd = open(bar4_name, O_RDWR | O_SYNC);
11464
11465 char errmsg[NI_ERRNO_LEN] = {0};
11466 if (bar4_fd < 0)
11467 {
11469 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't open bar4 %s (%s)\n",
11470 bar4_name, errmsg);
11471 return NI_RETCODE_FAILURE;
11472 }
11473
11474 if (fstat(bar4_fd, &stat) != 0)
11475 {
11477 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't stat bar4 (%s)\n",
11478 errmsg);
11479 close(bar4_fd);
11480 return NI_RETCODE_FAILURE;
11481 }
11482
11483 bar4_mm = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, bar4_fd, 0);
11484
11485 if (bar4_mm == MAP_FAILED)
11486 {
11488 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't mmap to bar4 (%s)\n",
11489 errmsg);
11490 close(bar4_fd);
11491 return NI_RETCODE_FAILURE;
11492 }
11493
11494 /* Copy the data directly into Quadra video memory */
11495 memcpy(bar4_mm + offset, p_data, len);
11496
11497 munmap(bar4_mm, 0);
11498 close(bar4_fd);
11499
11500 return NI_RETCODE_SUCCESS;
11501}
11502
11503
11504/*!*****************************************************************************
11505 * \brief Recycle hw P2P frames
11506 *
11507 * \param [in] p_frame pointer to an acquired P2P hw frame
11508 *
11509 * \return on success
11510 * NI_RETCODE_SUCCESS
11511 *
11512 * on failure
11513 * NI_RETCODE_INVALID_PARAM
11514*******************************************************************************/
11516{
11517 niFrameSurface1_t *p_surface;
11518
11519 if (p_frame == NULL)
11520 {
11521 ni_log(NI_LOG_ERROR, "%s: Invalid frame\n", __func__);
11523 }
11524
11525 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11526 if (p_surface == NULL)
11527 {
11528 ni_log(NI_LOG_ERROR, "%s: Invalid surface data\n", __func__);
11530 }
11531
11532 return ni_hwframe_buffer_recycle2(p_surface);
11533}
11534
11535/*!*****************************************************************************
11536 * \brief Acquire the scaler P2P DMA buffer for read/write
11537 *
11538 * \param [in] p_ctx pointer to caller allocated upload context
11539 * [in] p_surface pointer to a caller allocated hardware frame
11540 * [in] data_len scaler frame buffer data length
11541 *
11542 * \return on success
11543 * NI_RETCODE_SUCCESS
11544 *
11545 * on failure
11546 * NI_RETCODE_FAILURE
11547*******************************************************************************/
11549 niFrameSurface1_t *p_surface,
11550 int data_len)
11551{
11552 unsigned int offset;
11553 int ret;
11554
11555 ret = ni_get_memory_offset(p_ctx, p_surface, &offset);
11556 if (ret != 0)
11557 {
11558 ni_log2(p_ctx, NI_LOG_ERROR, "Error: bad buffer id\n");
11559 return NI_RETCODE_FAILURE;
11560 }
11561 p_surface->ui32nodeAddress = 0;
11562
11563 struct netint_iocmd_export_dmabuf uexp;
11564 uexp.fd = -1;
11565 uexp.flags = 0;
11566 uexp.offset = offset;
11567 uexp.length = data_len;
11568 uexp.domain = p_ctx->domain;
11569 uexp.bus = p_ctx->bus;
11570 uexp.dev = p_ctx->dev;
11571 uexp.fn = p_ctx->fn;
11572 uexp.bar = 4;
11573 ret = ioctl(p_ctx->netint_fd, NETINT_IOCTL_EXPORT_DMABUF, &uexp);
11574 if (ret < 0)
11575 {
11576 char errmsg[NI_ERRNO_LEN] = {0};
11578 ni_log2(p_ctx, NI_LOG_ERROR, "failed to export dmabuf: %s\n", errmsg);
11579 return NI_RETCODE_FAILURE;
11580 }
11581 p_surface->dma_buf_fd = uexp.fd;
11582 return ret;
11583}
11584#endif
11585
11586/*!*****************************************************************************
11587 * \brief Set the incoming frame format for the encoder
11588 *
11589 * \param[in] p_enc_ctx pointer to encoder context
11590 * [in] p_enc_params pointer to encoder parameters
11591 * [in] width input width
11592 * [in] height input height
11593 * [in] bit_depth 8 for 8-bit YUV, 10 for 10-bit YUV
11594 * [in] src_endian NI_FRAME_LITTLE_ENDIAN or NI_FRAME_BIG_ENDIAN
11595 * [in] planar 0 for semi-planar YUV, 1 for planar YUV
11596 *
11597 * \return on success
11598 * NI_RETCODE_SUCCESS
11599 *
11600 * on failure
11601 * NI_RETCODE_INVALID_PARAM
11602 *
11603*******************************************************************************/
11605 ni_xcoder_params_t *p_enc_params,
11606 int width, int height,
11607 int bit_depth, int src_endian,
11608 int planar)
11609{
11610 int alignedw;
11611 int alignedh;
11612
11613 if (p_enc_ctx == NULL || p_enc_params == NULL)
11614 {
11615 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: null ptr\n", __func__);
11617 }
11618
11619 if (!(bit_depth == 8) && !(bit_depth == 10))
11620 {
11621 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad bit depth %d\n", __func__, bit_depth);
11623 }
11624
11625 if (!(src_endian == NI_FRAME_LITTLE_ENDIAN) &&
11626 !(src_endian == NI_FRAME_BIG_ENDIAN))
11627 {
11628 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad endian %d\n", __func__, src_endian);
11630 }
11631
11632 if ((planar < 0) || (planar >= NI_PIXEL_PLANAR_MAX))
11633 {
11634 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad planar value %d\n", __func__, planar);
11636 }
11637
11638 p_enc_ctx->src_bit_depth = bit_depth;
11639 p_enc_ctx->bit_depth_factor = (bit_depth == 8) ? 1 : 2;
11640 p_enc_ctx->src_endian = src_endian;
11641
11642 alignedw = width;
11643
11644 if (alignedw < NI_MIN_WIDTH)
11645 {
11646 p_enc_params->cfg_enc_params.conf_win_right +=
11647 (NI_MIN_WIDTH - width) / 2 * 2;
11648 alignedw = NI_MIN_WIDTH;
11649 } else
11650 {
11651 alignedw = ((width + 1) / 2) * 2;
11652 p_enc_params->cfg_enc_params.conf_win_right +=
11653 (alignedw - width) / 2 * 2;
11654 }
11655
11656 p_enc_params->source_width = alignedw;
11657 alignedh = height;
11658
11659 if (alignedh < NI_MIN_HEIGHT)
11660 {
11661 p_enc_params->cfg_enc_params.conf_win_bottom +=
11662 (NI_MIN_HEIGHT - height) / 2 * 2;
11663 alignedh = NI_MIN_HEIGHT;
11664 } else
11665 {
11666 alignedh = ((height + 1) / 2) * 2;
11667 p_enc_params->cfg_enc_params.conf_win_bottom +=
11668 (alignedh - height) / 2 * 2;
11669 }
11670
11671 p_enc_params->source_height = alignedh;
11672 p_enc_params->cfg_enc_params.planar = planar;
11673
11674 return NI_RETCODE_SUCCESS;
11675}
11676
11677/*!*****************************************************************************
11678 * \brief Set the outgoing frame format for the uploader
11679 *
11680 * \param[in] p_upl_ctx pointer to uploader context
11681 * [in] width width
11682 * [in] height height
11683 * [in] pixel_format pixel format
11684 * [in] isP2P 0 = normal, 1 = P2P
11685 *
11686 * \return on success
11687 * NI_RETCODE_SUCCESS
11688 *
11689 * on failure
11690 * NI_RETCODE_INVALID_PARAM
11691*******************************************************************************/
11693 int width, int height,
11694 ni_pix_fmt_t pixel_format, int isP2P)
11695{
11696 if (p_upl_ctx == NULL)
11697 {
11698 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: null ptr\n", __func__);
11700 }
11701
11702 switch (pixel_format)
11703 {
11704 case NI_PIX_FMT_YUV420P:
11705 case NI_PIX_FMT_NV12:
11706 p_upl_ctx->src_bit_depth = 8;
11707 p_upl_ctx->bit_depth_factor = 1;
11708 break;
11710 case NI_PIX_FMT_P010LE:
11711 p_upl_ctx->src_bit_depth = 10;
11712 p_upl_ctx->bit_depth_factor = 2;
11713 break;
11714 case NI_PIX_FMT_RGBA:
11715 case NI_PIX_FMT_BGRA:
11716 case NI_PIX_FMT_ARGB:
11717 case NI_PIX_FMT_ABGR:
11718 case NI_PIX_FMT_BGR0:
11719 case NI_PIX_FMT_BGRP:
11720 p_upl_ctx->src_bit_depth = 8;
11721 p_upl_ctx->bit_depth_factor = 4;
11722 break;
11723 default:
11724 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid pixfmt %d\n", __func__,
11725 pixel_format);
11727 }
11728
11730 p_upl_ctx->pixel_format = pixel_format;
11731 p_upl_ctx->active_video_width = width;
11732 p_upl_ctx->active_video_height = height;
11733 p_upl_ctx->isP2P = isP2P;
11734
11735 return NI_RETCODE_SUCCESS;
11736}
11737
11738/*!*****************************************************************************
11739 * \brief Read encoder stream header from the device
11740 *
11741 * \param[in] p_ctx Pointer to a caller allocated
11742 * ni_session_context_t struct from encoder
11743 * \param[in] p_data Pointer to a caller allocated ni_session_data_io_t
11744 * struct which contains a ni_packet_t data packet to
11745 * receive
11746 * \return On success
11747 * Total number of bytes read
11748 * On failure
11749 * NI_RETCODE_INVALID_PARAM
11750 * NI_RETCODE_ERROR_NVME_CMD_FAILED
11751 * NI_RETCODE_ERROR_INVALID_SESSION
11752*******************************************************************************/
11754 ni_session_data_io_t *p_data)
11755{
11756 int rx_size;
11757 int done = 0;
11758 int bytes_read = 0;
11759
11760 /* This function should be called once at the start of encoder read */
11761 if (p_ctx->pkt_num != 0)
11762 {
11763 ni_log2(p_ctx, NI_LOG_ERROR, "Error: stream header has already been read\n");
11765 }
11766
11767 while (!done)
11768 {
11769 rx_size = ni_device_session_read(p_ctx, p_data, NI_DEVICE_TYPE_ENCODER);
11770
11771 if (rx_size > (int)p_ctx->meta_size)
11772 {
11773 /* stream header has been read, return size */
11774 bytes_read += (rx_size - (int)p_ctx->meta_size);
11775
11776 p_ctx->pkt_num = 1;
11777 ni_log2(p_ctx, NI_LOG_DEBUG, "Got encoded stream header\n");
11778 done = 1;
11779 } else if (rx_size != 0)
11780 {
11781 ni_log2(p_ctx, NI_LOG_ERROR, "Error: received rx_size = %d\n", rx_size);
11782 bytes_read = -1;
11783 done = 1;
11784 } else
11785 {
11786 ni_log2(p_ctx, NI_LOG_DEBUG, "No data, keep reading..\n");
11787 continue;
11788 }
11789 }
11790
11791 return bytes_read;
11792}
11793
11794/*!*****************************************************************************
11795 * \brief Get the DMA buffer file descriptor from the P2P frame
11796 *
11797 * \param[in] p_frame pointer to a P2P frame
11798 *
11799 * \return On success
11800 * DMA buffer file descriptor
11801 * On failure
11802 * NI_RETCODE_INVALID_PARAM
11803*******************************************************************************/
11805{
11806 const niFrameSurface1_t *p_surface;
11807
11808 if (p_frame == NULL)
11809 {
11810 ni_log(NI_LOG_ERROR, "%s: NULL frame\n", __func__);
11812 }
11813
11814 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11815
11816 if (p_surface == NULL)
11817 {
11818 ni_log(NI_LOG_ERROR, "%s: Invalid hw frame\n", __func__);
11820 }
11821
11822 return p_surface->dma_buf_fd;
11823}
11824
11825/*!*****************************************************************************
11826 * \brief Send sequence change information to device
11827 *
11828 * \param[in] p_ctx Pointer to a caller allocated
11829 * ni_session_context_t struct
11830 * \param[in] width input width
11831 * \param[in] height input height
11832 * \param[in] bit_depth_factor 1 for 8-bit YUV, 2 for 10-bit YUV
11833 * \param[in] device_type device type (must be encoder)
11834 * \return On success
11835 * NI_RETCODE_SUCCESS
11836 * On failure
11837 * NI_RETCODE_INVALID_PARAM
11838 * NI_RETCODE_ERROR_MEM_ALOC
11839 * NI_RETCODE_ERROR_NVME_CMD_FAILED
11840 * NI_RETCODE_ERROR_INVALID_SESSION
11841 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
11842 ******************************************************************************/
11844 int width, int height, int bit_depth_factor, ni_device_type_t device_type)
11845{
11846 ni_resolution_t resolution;
11848 ni_xcoder_params_t *p_param = NULL;
11849
11850 // requires API version >= 54
11852 "54") < 0)
11853 {
11854 ni_log2(p_ctx, NI_LOG_ERROR, "Error: %s function not supported on device with FW API version < 5.4\n", __func__);
11856 }
11857
11858 /* This function should be called only if sequence change is detected */
11860 {
11861 ni_log2(p_ctx, NI_LOG_ERROR, "Error: stream header has already been read\n");
11863 }
11864
11865 resolution.width = width;
11866 resolution.height = height;
11867 resolution.bit_depth_factor = bit_depth_factor;
11868 resolution.luma_linesize = 0;
11869 resolution.chroma_linesize = 0;
11870 if (p_ctx->p_session_config)
11871 {
11873 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11874 p_enc = &p_param->cfg_enc_params;
11875 if (p_enc->spatial_layers > 1)
11876 {
11877 retval = NI_RETCODE_INVALID_PARAM;
11878 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Config sequence change not supported when spatialLayers > 1\n");
11879 return retval;
11880 }
11881 resolution.luma_linesize = p_param->luma_linesize;
11882 resolution.chroma_linesize = p_param->chroma_linesize;
11883 }
11884 else
11885 {
11887 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: invalid p_session_config\n");
11888 return retval;
11889 }
11890
11891 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: resolution change config - width %d height %d bit_depth_factor %d "
11892 "luma_linesize %d chroma_linesize %d\n", __func__,
11893 resolution.width, resolution.height, resolution.bit_depth_factor,
11894 resolution.luma_linesize, resolution.chroma_linesize);
11895
11896 switch (device_type)
11897 {
11899 {
11900 // config sequence change
11901 retval = ni_encoder_session_sequence_change(p_ctx, &resolution);
11902 break;
11903 }
11904 default:
11905 {
11906 retval = NI_RETCODE_INVALID_PARAM;
11907 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Config sequence change not supported for device type: %d", device_type);
11908 return retval;
11909 }
11910 }
11911 return retval;
11912}
11913
11915 ni_network_perf_metrics_t *p_metrics)
11916{
11917 return ni_ai_session_query_metrics(p_ctx, p_metrics);
11918}
11919
11920ni_retcode_t ni_query_fl_fw_versions(ni_device_handle_t device_handle,
11921 ni_device_info_t *p_dev_info)
11922{
11923 void *buffer;
11924 uint32_t size;
11925 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
11926 ni_log_fl_fw_versions_t fl_fw_versions;
11927
11928 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_info))
11929 {
11930 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
11931 __func__);
11933 }
11934
11936 "6h") < 0)
11937 {
11939 "ERROR: %s function not supported on device with FW API version < 6.h\n",
11940 __func__);
11942 }
11943
11944 buffer = NULL;
11946
11947 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
11948 {
11949 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
11951 }
11952
11953 memset(buffer, 0, size);
11954
11955 if (ni_nvme_send_read_cmd(device_handle,
11956 event_handle,
11957 buffer,
11958 size,
11960 {
11961 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
11962 ni_aligned_free(buffer);
11964 }
11965
11966 memcpy(&fl_fw_versions, buffer, sizeof(ni_log_fl_fw_versions_t));
11967
11968 memcpy(p_dev_info->fl_ver_last_ran,
11969 &fl_fw_versions.last_ran_fl_version,
11971 memcpy(p_dev_info->fl_ver_nor_flash,
11972 &fl_fw_versions.nor_flash_fl_version,
11974 memcpy(p_dev_info->fw_rev_nor_flash,
11975 &fl_fw_versions.nor_flash_fw_revision,
11977
11978 ni_aligned_free(buffer);
11979 return NI_RETCODE_SUCCESS;
11980}
11981
11983 ni_load_query_t *p_load_query)
11984{
11985 void *buffer;
11986 uint32_t size;
11987
11988 ni_instance_mgr_general_status_t general_status;
11989
11990 if (!p_ctx)
11991 {
11992 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: p_ctx cannot be null\n");
11994 }
11995 if (!p_load_query)
11996 {
11997 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: p_load_query cannot be null\n");
11999 }
12000
12002 "6O") < 0)
12003 {
12004 ni_log2(p_ctx, NI_LOG_ERROR,
12005 "ERROR: %s function not supported on device with FW API version < 6.O\n",
12006 __func__);
12008 }
12009
12010 buffer = NULL;
12012
12013 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12014 {
12015 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12017 }
12018
12019 memset(buffer, 0, size);
12020
12022 p_ctx->event_handle,
12023 buffer,
12024 size,
12026 {
12027 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12028 ni_aligned_free(buffer);
12030 }
12031
12032 memcpy(&general_status, buffer, sizeof(ni_instance_mgr_general_status_t));
12033
12034 p_load_query->tp_fw_load = general_status.tp_fw_load;
12035 p_load_query->pcie_load = general_status.pcie_load;
12036 p_load_query->pcie_throughput = general_status.pcie_throughput;
12037 p_load_query->fw_load = general_status.fw_load;
12038 p_load_query->fw_share_mem_usage = general_status.fw_share_mem_usage;
12039
12040 ni_aligned_free(buffer);
12041 return NI_RETCODE_SUCCESS;
12042}
12043
12044ni_retcode_t ni_query_vf_ns_id(ni_device_handle_t device_handle,
12045 ni_device_vf_ns_id_t *p_dev_ns_vf,
12046 uint8_t fw_rev[])
12047{
12048 void *p_buffer = NULL;
12049 uint32_t size;
12050 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12051
12052 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_ns_vf))
12053 {
12054 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12055 __func__);
12057 }
12058
12060 "6m") < 0)
12061 {
12063 "ERROR: %s function not supported on device with FW API version < 6.m\n",
12064 __func__);
12066 }
12067
12069
12070 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12071 {
12072 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12074 }
12075
12076 memset(p_buffer, 0, size);
12077
12078 if (ni_nvme_send_read_cmd(device_handle,
12079 event_handle,
12080 p_buffer,
12081 size,
12082 QUERY_GET_NS_VF_R) < 0)
12083 {
12084 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12085 ni_aligned_free(p_buffer);
12087 }
12088
12089 ni_device_vf_ns_id_t *p_dev_ns_vf_data = (ni_device_vf_ns_id_t *)p_buffer;
12090 p_dev_ns_vf->vf_id = p_dev_ns_vf_data->vf_id;
12091 p_dev_ns_vf->ns_id = p_dev_ns_vf_data->ns_id;
12092 ni_log(NI_LOG_DEBUG, "%s(): NS/VF %u/%u\n", __func__, p_dev_ns_vf->ns_id, p_dev_ns_vf->vf_id);
12093 ni_aligned_free(p_buffer);
12094 return NI_RETCODE_SUCCESS;
12095}
12096
12097ni_retcode_t ni_query_temperature(ni_device_handle_t device_handle,
12098 ni_device_temp_t *p_dev_temp,
12099 uint8_t fw_rev[])
12100{
12101 void *p_buffer = NULL;
12102 uint32_t size;
12103 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12104
12105 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_temp))
12106 {
12107 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12108 __func__);
12110 }
12111
12113 "6rC") < 0)
12114 {
12116 "ERROR: %s function not supported on device with FW API version < 6rC\n",
12117 __func__);
12119 }
12120
12122
12123 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12124 {
12125 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12127 }
12128
12129 memset(p_buffer, 0, size);
12130
12131 if (ni_nvme_send_read_cmd(device_handle,
12132 event_handle,
12133 p_buffer,
12134 size,
12136 {
12137 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12138 ni_aligned_free(p_buffer);
12140 }
12141
12142 ni_device_temp_t *p_dev_temp_data = (ni_device_temp_t *)p_buffer;
12143 p_dev_temp->composite_temp = p_dev_temp_data->composite_temp;
12144 p_dev_temp->on_board_temp = p_dev_temp_data->on_board_temp;
12145 p_dev_temp->on_die_temp = p_dev_temp_data->on_die_temp;
12146 ni_log(NI_LOG_DEBUG, "%s(): current composite temperature %d on board temperature %d on die temperature %d\n",
12147 __func__, p_dev_temp->composite_temp, p_dev_temp->on_board_temp, p_dev_temp->on_die_temp);
12148 ni_aligned_free(p_buffer);
12149 return NI_RETCODE_SUCCESS;
12150}
12151
12152ni_retcode_t ni_query_extra_info(ni_device_handle_t device_handle,
12153 ni_device_extra_info_t *p_dev_extra_info,
12154 uint8_t fw_rev[])
12155{
12156 void *p_buffer = NULL;
12157 uint32_t size;
12158 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12159
12160 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_extra_info))
12161 {
12162 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12163 __func__);
12165 }
12166
12168 "6rC") < 0)
12169 {
12171 "ERROR: %s function not supported on device with FW API version < 6rC\n",
12172 __func__);
12174 }
12175
12177
12178 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12179 {
12180 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12182 }
12183
12184 memset(p_buffer, 0, size);
12185
12186 if (ni_nvme_send_read_cmd(device_handle,
12187 event_handle,
12188 p_buffer,
12189 size,
12191 {
12192 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12193 ni_aligned_free(p_buffer);
12195 }
12196
12197 ni_device_extra_info_t *p_dev_extra_info_data = (ni_device_extra_info_t *)p_buffer;
12198 p_dev_extra_info->composite_temp = p_dev_extra_info_data->composite_temp;
12199 p_dev_extra_info->on_board_temp = p_dev_extra_info_data->on_board_temp;
12200 p_dev_extra_info->on_die_temp = p_dev_extra_info_data->on_die_temp;
12201 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sN") >= 0)
12202 {
12203 p_dev_extra_info->fw_flavour = p_dev_extra_info_data->fw_flavour;
12204 }
12205 else
12206 {
12207 p_dev_extra_info->fw_flavour = (uint8_t)'-';
12208 }
12209 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rC") >= 0 &&
12210 ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rR") < 0)
12211 {
12212 p_dev_extra_info->power_consumption = NI_INVALID_POWER;
12213 }
12214 else
12215 {
12216 p_dev_extra_info->power_consumption = p_dev_extra_info_data->power_consumption;
12217 }
12218 //QUADPV-1210-Remove ADC current measurement decoding from FW
12219 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6s4") >= 0 &&
12220 ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sR") <= 0)
12221 {
12222 p_dev_extra_info->current_consumption = p_dev_extra_info_data->current_consumption;
12223 ni_device_capability_t device_capability = {0};
12224 if (ni_device_capability_query2(device_handle, &device_capability, false) != NI_RETCODE_SUCCESS)
12225 {
12226 ni_log(NI_LOG_ERROR, "ERROR: unable to query capability\n");
12228 }
12229 p_dev_extra_info->power_consumption = ni_decode_power_measurement(p_dev_extra_info->current_consumption, device_capability.serial_number);
12230 }
12231 ni_log(NI_LOG_DEBUG, "%s(): current composite temperature %d on board temperature %d "
12232 "on die temperature %d power consumption %d current consumption %d\n",
12233 __func__, p_dev_extra_info->composite_temp, p_dev_extra_info->on_board_temp,
12234 p_dev_extra_info->on_die_temp, p_dev_extra_info->power_consumption, p_dev_extra_info->current_consumption);
12235 ni_aligned_free(p_buffer);
12236 return NI_RETCODE_SUCCESS;
12237}
12238
12239/*!*****************************************************************************
12240 * \brief Allocate log buffer if needed and retrieve firmware logs from device
12241 *
12242 * \param[in] p_ctx Pointer to a caller allocated
12243 * ni_session_context_t struct
12244 * \param[in] p_log_buffer Reference to pointer to a log buffer
12245 * If log buffer pointer is NULL, this function will allocate log buffer
12246 * NOTE caller is responsible for freeing log buffer after calling this function
12247 * \param[in] gen_log_file Indicating whether it is required to generate log files
12248 *
12249 *
12250 * \return on success
12251 * NI_RETCODE_SUCCESS
12252 *
12253 * on failure
12254 * NI_RETCODE_ERROR_MEM_ALOC
12255 * NI_RETCODE_INVALID_PARAM
12256*******************************************************************************/
12257ni_retcode_t ni_device_alloc_and_get_firmware_logs(ni_session_context_t *p_ctx, void** p_log_buffer, bool gen_log_file)
12258{
12260 bool is_ext_buf = true;
12261 if (*p_log_buffer == NULL)
12262 {
12263 if (ni_posix_memalign(p_log_buffer, sysconf(_SC_PAGESIZE), TOTAL_CPU_LOG_BUFFER_SIZE))
12264 {
12265 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate log buffer\n",
12266 NI_ERRNO, __func__);
12268 }
12269 is_ext_buf = false;
12270 }
12271
12272 if(*p_log_buffer != NULL){
12273 memset(*p_log_buffer, 0, TOTAL_CPU_LOG_BUFFER_SIZE);
12274 retval = ni_dump_log_all_cores(p_ctx, *p_log_buffer, gen_log_file); // dump FW logs
12275 if(!is_ext_buf)
12276 ni_aligned_free(*p_log_buffer);
12277 }else{
12279 }
12280
12281 return retval;
12282}
12283
12284/*!*****************************************************************************
12285 * \brief Set up hard coded demo ROI map
12286 *
12287 * \param[in] p_enc_ctx Pointer to a caller allocated
12288 *
12289 * \return on success
12290 * NI_RETCODE_SUCCESS
12291 *
12292 * on failure
12293 * NI_RETCODE_ERROR_MEM_ALOC
12294*******************************************************************************/
12296{
12297 ni_xcoder_params_t *p_param =
12298 (ni_xcoder_params_t *)(p_enc_ctx->p_session_config);
12299 int sumQp = 0;
12300 uint32_t ctu, i, j;
12301 // mode 1: Set QP for center 1/3 of picture to highest - lowest quality
12302 // the rest to lowest - highest quality;
12303 // mode non-1: reverse of mode 1
12304 int importanceLevelCentre = p_param->roi_demo_mode == 1 ? 40 : 10;
12305 int importanceLevelRest = p_param->roi_demo_mode == 1 ? 10 : 40;
12306 int linesize_aligned = p_param->source_width;
12307 int height_aligned = p_param->source_height;
12308 if (QUADRA)
12309 {
12310 uint32_t block_size, max_cu_size, customMapSize;
12311 uint32_t mbWidth;
12312 uint32_t mbHeight;
12313 uint32_t numMbs;
12314 uint32_t roiMapBlockUnitSize;
12315 uint32_t entryPerMb;
12316
12317 max_cu_size = p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264 ? 16: 64;
12318 // AV1 non-8x8-aligned resolution is implicitly cropped due to Quadra HW limitation
12319 if (NI_CODEC_FORMAT_AV1 == p_enc_ctx->codec_format)
12320 {
12321 linesize_aligned = (linesize_aligned / 8) * 8;
12322 height_aligned = (height_aligned / 8) * 8;
12323 }
12324
12325 // (ROI map version >= 1) each QP info takes 8-bit, represent 8 x 8
12326 // pixel block
12327 block_size =
12328 ((linesize_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) *
12329 ((height_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12330 (8 * 8);
12331
12332 // need to align to 64 bytes
12333 customMapSize = ((block_size + 63) & (~63));
12334 if (!p_enc_ctx->roi_map)
12335 {
12336 p_enc_ctx->roi_map =
12337 (ni_enc_quad_roi_custom_map *)calloc(1, customMapSize);
12338 }
12339 if (!p_enc_ctx->roi_map)
12340 {
12342 }
12343
12344 // for H.264, select ROI Map Block Unit Size: 16x16
12345 // for H.265, select ROI Map Block Unit Size: 64x64
12346 roiMapBlockUnitSize = p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264 ? 16 : 64;
12347
12348 mbWidth =
12349 ((linesize_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12350 roiMapBlockUnitSize;
12351 mbHeight =
12352 ((height_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12353 roiMapBlockUnitSize;
12354 numMbs = mbWidth * mbHeight;
12355
12356 // copy roi MBs QPs into custom map
12357 // number of qp info (8x8) per mb or ctb
12358 entryPerMb = (roiMapBlockUnitSize / 8) * (roiMapBlockUnitSize / 8);
12359
12360 for (i = 0; i < numMbs; i++)
12361 {
12362 bool bIsCenter = (i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3);
12363 for (j = 0; j < entryPerMb; j++)
12364 {
12365 /*
12366 g_quad_roi_map[i*4+j].field.skip_flag = 0; // don't force
12367 skip mode g_quad_roi_map[i*4+j].field.roiAbsQp_flag = 1; //
12368 absolute QP g_quad_roi_map[i*4+j].field.qp_info = bIsCenter
12369 ? importanceLevelCentre : importanceLevelRest;
12370 */
12371 p_enc_ctx->roi_map[i * entryPerMb + j].field.ipcm_flag =
12372 0; // don't force skip mode
12373 p_enc_ctx->roi_map[i * entryPerMb + j]
12374 .field.roiAbsQp_flag = 1; // absolute QP
12375 p_enc_ctx->roi_map[i * entryPerMb + j].field.qp_info =
12376 bIsCenter ? importanceLevelCentre : importanceLevelRest;
12377 }
12378 sumQp += p_enc_ctx->roi_map[i * entryPerMb].field.qp_info;
12379 }
12380 p_enc_ctx->roi_len = customMapSize;
12381 p_enc_ctx->roi_avg_qp =
12382 // NOLINTNEXTLINE(clang-analyzer-core.DivideZero)
12383 (sumQp + (numMbs >> 1)) / numMbs; // round off
12384 }
12385 else if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264)
12386 {
12387 // roi for H.264 is specified for 16x16 pixel macroblocks - 1 MB
12388 // is stored in each custom map entry
12389
12390 // number of MBs in each row
12391 uint32_t mbWidth = (linesize_aligned + 16 - 1) >> 4;
12392 // number of MBs in each column
12393 uint32_t mbHeight = (height_aligned + 16 - 1) >> 4;
12394 uint32_t numMbs = mbWidth * mbHeight;
12395 uint32_t customMapSize =
12396 sizeof(ni_enc_avc_roi_custom_map_t) * numMbs;
12397 p_enc_ctx->avc_roi_map =
12398 (ni_enc_avc_roi_custom_map_t *)calloc(1, customMapSize);
12399 if (!p_enc_ctx->avc_roi_map)
12400 {
12402 }
12403
12404 // copy roi MBs QPs into custom map
12405 for (i = 0; i < numMbs; i++)
12406 {
12407 if ((i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3))
12408 {
12409 p_enc_ctx->avc_roi_map[i].field.mb_qp = importanceLevelCentre;
12410 }
12411 else
12412 {
12413 p_enc_ctx->avc_roi_map[i].field.mb_qp = importanceLevelRest;
12414 }
12415 sumQp += p_enc_ctx->avc_roi_map[i].field.mb_qp;
12416 }
12417 p_enc_ctx->roi_len = customMapSize;
12418 p_enc_ctx->roi_avg_qp =
12419 (sumQp + (numMbs >> 1)) / numMbs; // round off
12420 }
12421 else if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265)
12422 {
12423 // roi for H.265 is specified for 32x32 pixel subCTU blocks - 4
12424 // subCTU QPs are stored in each custom CTU map entry
12425
12426 // number of CTUs in each row
12427 uint32_t ctuWidth = (linesize_aligned + 64 - 1) >> 6;
12428 // number of CTUs in each column
12429 uint32_t ctuHeight = (height_aligned + 64 - 1) >> 6;
12430 // number of sub CTUs in each row
12431 uint32_t subCtuWidth = ctuWidth * 2;
12432 // number of CTUs in each column
12433 uint32_t subCtuHeight = ctuHeight * 2;
12434 uint32_t numSubCtus = subCtuWidth * subCtuHeight;
12435
12436 p_enc_ctx->hevc_sub_ctu_roi_buf = (uint8_t *)malloc(numSubCtus);
12437 if (!p_enc_ctx->hevc_sub_ctu_roi_buf)
12438 {
12440 }
12441 for (i = 0; i < numSubCtus; i++)
12442 {
12443 if ((i % subCtuWidth > subCtuWidth / 3) &&
12444 (i % subCtuWidth < subCtuWidth * 2 / 3))
12445 {
12446 p_enc_ctx->hevc_sub_ctu_roi_buf[i] = importanceLevelCentre;
12447 }
12448 else
12449 {
12450 p_enc_ctx->hevc_sub_ctu_roi_buf[i] = importanceLevelRest;
12451 }
12452 }
12453 p_enc_ctx->hevc_roi_map = (ni_enc_hevc_roi_custom_map_t *)calloc(
12454 1, sizeof(ni_enc_hevc_roi_custom_map_t) * ctuWidth * ctuHeight);
12455 if (!p_enc_ctx->hevc_roi_map)
12456 {
12458 }
12459
12460 for (i = 0; i < ctuHeight; i++)
12461 {
12462 uint8_t *ptr = &p_enc_ctx->hevc_sub_ctu_roi_buf[subCtuWidth * i * 2];
12463 for (j = 0; j < ctuWidth; j++, ptr += 2)
12464 {
12465 ctu = (i * ctuWidth + j);
12466 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_0 = *ptr;
12467 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_1 = *(ptr + 1);
12468 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_2 =
12469 *(ptr + subCtuWidth);
12470 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_3 =
12471 *(ptr + subCtuWidth + 1);
12472 sumQp += (p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_0 +
12473 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_1 +
12474 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_2 +
12475 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_3);
12476 }
12477 }
12478 p_enc_ctx->roi_len =
12479 ctuWidth * ctuHeight * sizeof(ni_enc_hevc_roi_custom_map_t);
12480 p_enc_ctx->roi_avg_qp =
12481 (sumQp + (numSubCtus >> 1)) / numSubCtus; // round off.
12482 }
12483 return NI_RETCODE_SUCCESS;
12484}
12485
12487{
12488 // for encoder reconfiguration testing
12489 // reset encoder change data buffer for reconf parameters
12490 ni_retcode_t retval = 0;
12491 ni_xcoder_params_t *p_param =
12493 ni_aux_data_t *aux_data = NULL;
12496 {
12497 memset(p_enc_ctx->enc_change_params, 0, sizeof(ni_encoder_change_params_t));
12498 }
12499
12500 switch (p_param->reconf_demo_mode) {
12502 if (p_enc_ctx->frame_num ==
12503 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12504 {
12505 aux_data = ni_frame_new_aux_data(
12506 p_frame, NI_FRAME_AUX_DATA_BITRATE, sizeof(int32_t));
12507 if (!aux_data)
12508 {
12510 }
12511 *((int32_t *)aux_data->data) =
12512 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12513
12514 p_enc_ctx->reconfigCount++;
12515 if (p_param->cfg_enc_params.hrdEnable)
12516 {
12517 p_frame->force_key_frame = 1;
12518 p_frame->ni_pict_type = PIC_TYPE_IDR;
12519 }
12520 }
12521 break;
12522 // reconfig intraperiod param
12524 if (p_enc_ctx->frame_num ==
12525 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12526 {
12527 aux_data = ni_frame_new_aux_data(
12528 p_frame, NI_FRAME_AUX_DATA_INTRAPRD, sizeof(int32_t));
12529 if (!aux_data)
12530 {
12532 }
12533 int32_t intraprd = *((int32_t *)aux_data->data) =
12534 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12535 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12536 "xcoder_send_frame: frame #%lu reconf "
12537 "intraPeriod %d\n",
12538 p_enc_ctx->frame_num,
12539 intraprd);
12540 p_enc_ctx->reconfigCount++;
12541 }
12542 break;
12543 // reconfig VUI parameters
12545 if (p_enc_ctx->frame_num ==
12546 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12547 {
12548 aux_data = ni_frame_new_aux_data(p_frame,
12550 sizeof(ni_vui_hrd_t));
12551 if (!aux_data)
12552 {
12554 }
12555 ni_vui_hrd_t *vui = (ni_vui_hrd_t *)aux_data->data;
12556 vui->colorDescPresent =
12557 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12558 vui->colorPrimaries =
12559 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12560 vui->colorTrc =
12561 p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
12562 vui->colorSpace =
12563 p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
12564 vui->aspectRatioWidth =
12565 p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
12566 vui->aspectRatioHeight =
12567 p_param->reconf_hash[p_enc_ctx->reconfigCount][6];
12568 vui->videoFullRange =
12569 p_param->reconf_hash[p_enc_ctx->reconfigCount][7];
12570 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12571 "xcoder_send_frame: frame #%lu reconf "
12572 "vui colorDescPresent %d colorPrimaries %d "
12573 "colorTrc %d colorSpace %d aspectRatioWidth %d "
12574 "aspectRatioHeight %d videoFullRange %d\n",
12575 p_enc_ctx->frame_num, vui->colorDescPresent,
12576 vui->colorPrimaries, vui->colorTrc,
12577 vui->colorSpace, vui->aspectRatioWidth,
12579
12580 p_enc_ctx->reconfigCount++;
12581 }
12582 break;
12583 // long term ref
12585 // the reconf file data line format for this is:
12586 // <frame-number>:useCurSrcAsLongtermPic,useLongtermRef where
12587 // values will stay the same on every frame until changed.
12588 if (p_enc_ctx->frame_num ==
12589 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12590 {
12591 ni_long_term_ref_t *p_ltr;
12592 aux_data = ni_frame_new_aux_data(
12594 sizeof(ni_long_term_ref_t));
12595 if (!aux_data)
12596 {
12598 }
12599 p_ltr = (ni_long_term_ref_t *)aux_data->data;
12601 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12602 p_ltr->use_long_term_ref =
12603 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12604 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12605 "xcoder_send_frame: frame #%lu metadata "
12606 "use_cur_src_as_long_term_pic %d use_long_term_ref "
12607 "%d\n",
12608 p_enc_ctx->frame_num,
12610 p_ltr->use_long_term_ref);
12611 p_enc_ctx->reconfigCount++;
12612 }
12613 break;
12614 // reconfig min / max QP
12617 if (p_enc_ctx->frame_num ==
12618 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12619 aux_data = ni_frame_new_aux_data(
12621 if (!aux_data) {
12623 }
12624
12625 ni_rc_min_max_qp *qp_info = (ni_rc_min_max_qp *)aux_data->data;
12626 qp_info->minQpI = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12627 qp_info->maxQpI = p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12628 qp_info->maxDeltaQp = p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
12629 qp_info->minQpPB = p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
12630 qp_info->maxQpPB = p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
12631
12632 p_enc_ctx->reconfigCount++;
12633 }
12634 break;
12635#ifdef QUADRA
12636 // reconfig LTR interval
12638 if (p_enc_ctx->frame_num ==
12639 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12640 aux_data = ni_frame_new_aux_data(p_frame,
12642 sizeof(int32_t));
12643 if (!aux_data) {
12645 }
12646 *((int32_t *)aux_data->data) =
12647 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12648 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12649 "xcoder_send_frame: frame #%lu reconf "
12650 "ltrInterval %d\n",
12651 p_enc_ctx->frame_num,
12652 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12653
12654 p_enc_ctx->reconfigCount++;
12655 }
12656 break;
12657 // invalidate reference frames
12659 if (p_enc_ctx->frame_num ==
12660 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12661 aux_data = ni_frame_new_aux_data(
12663 sizeof(int32_t));
12664 if (!aux_data) {
12666 }
12667 *((int32_t *)aux_data->data) =
12668 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12669 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12670 "xcoder_send_frame: frame #%lu reconf "
12671 "invalidFrameNum %d\n",
12672 p_enc_ctx->frame_num,
12673 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12674
12675 p_enc_ctx->reconfigCount++;
12676 }
12677 break;
12678 // reconfig framerate
12680 if (p_enc_ctx->frame_num ==
12681 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12682 ni_framerate_t *framerate;
12683
12684 aux_data = ni_frame_new_aux_data(p_frame,
12686 sizeof(ni_framerate_t));
12687 if (!aux_data) {
12689 }
12690
12691 framerate = (ni_framerate_t *)aux_data->data;
12692 framerate->framerate_num =
12693 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12694 framerate->framerate_denom =
12695 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12696 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12697 "xcoder_send_frame: frame #%lu reconf "
12698 "framerate (%d/%d)\n",
12699 p_enc_ctx->frame_num, framerate->framerate_num,
12700 framerate->framerate_denom);
12701 p_enc_ctx->reconfigCount++;
12702 }
12703 break;
12705 if (p_enc_ctx->frame_num ==
12706 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12707 aux_data = ni_frame_new_aux_data(
12708 p_frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
12709 if (!aux_data) {
12711 }
12712 *((int32_t *)aux_data->data) =
12713 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12714 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12715 "xcoder_send_frame: frame #%lu reconf "
12716 "maxFrameSize %d\n",
12717 p_enc_ctx->frame_num,
12718 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12719
12720 p_enc_ctx->reconfigCount++;
12721 }
12722 break;
12724 if (p_enc_ctx->frame_num ==
12725 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12726 aux_data = ni_frame_new_aux_data(
12727 p_frame, NI_FRAME_AUX_DATA_CRF, sizeof(int32_t));
12728 if (!aux_data) {
12730 }
12731 *((int32_t *)aux_data->data) =
12732 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12733 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12734 "xcoder_send_frame: frame #%lu reconf "
12735 "crf %d\n",
12736 p_enc_ctx->frame_num,
12737 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12738
12739 p_enc_ctx->reconfigCount++;
12740 }
12741 break;
12743 if (p_enc_ctx->frame_num ==
12744 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12745 aux_data = ni_frame_new_aux_data(
12746 p_frame, NI_FRAME_AUX_DATA_CRF_FLOAT, sizeof(float));
12747 if (!aux_data) {
12749 }
12750 float crf = (float)(p_param->reconf_hash[p_enc_ctx->reconfigCount][1] +
12751 (float)p_param->reconf_hash[p_enc_ctx->reconfigCount][2] / 100.0);
12752 *((float *)aux_data->data) = crf;
12753 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12754 "xcoder_send_frame: frame #%lu reconf "
12755 "crf %f\n",
12756 p_enc_ctx->frame_num, crf);
12757
12758 p_enc_ctx->reconfigCount++;
12759 }
12760 break;
12762 if (p_enc_ctx->frame_num ==
12763 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12764 int32_t vbvBufferSize = p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12765 int32_t vbvMaxRate = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12766 if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
12767 {
12768 ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid vbvBufferSize value %d\n",
12769 __func__, vbvBufferSize);
12771 }
12772 if (p_param->bitrate > 0 && vbvMaxRate > 0 && vbvMaxRate < p_param->bitrate) {
12773 ni_log2(p_enc_ctx, NI_LOG_ERROR, "vbvMaxRate %u cannot be smaller than bitrate %d\n",
12774 vbvMaxRate, p_param->bitrate);
12776 }
12777 if (vbvBufferSize == 0 && vbvMaxRate > 0) {
12778 ni_log2(p_enc_ctx, NI_LOG_INFO, "vbvMaxRate %d does not take effect when "
12779 "vbvBufferSize is 0, force vbvMaxRate to 0\n",
12780 vbvMaxRate);
12781 vbvMaxRate = 0;
12782 }
12783
12784 aux_data = ni_frame_new_aux_data(
12785 p_frame, NI_FRAME_AUX_DATA_VBV_MAX_RATE, sizeof(int32_t));
12786 if (!aux_data) {
12788 }
12789 *((int32_t *)aux_data->data) = vbvMaxRate;
12790 aux_data = ni_frame_new_aux_data(
12791 p_frame, NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE, sizeof(int32_t));
12792 if (!aux_data) {
12794 }
12795 *((int32_t *)aux_data->data) = vbvBufferSize;
12796 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12797 "xcoder_send_frame: frame #%lu reconfig vbvMaxRate %d vbvBufferSize "
12798 "%d by frame aux data\n",
12799 p_enc_ctx->frame_num, vbvMaxRate, vbvBufferSize);
12800
12801 p_enc_ctx->reconfigCount++;
12802 }
12803 break;
12805 if (p_enc_ctx->frame_num ==
12806 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12807 int maxFrameSizeRatio = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12808 if (maxFrameSizeRatio < 1) {
12809 ni_log2(p_enc_ctx, NI_LOG_ERROR, "maxFrameSizeRatio %d cannot < 1\n",
12810 maxFrameSizeRatio);
12812 }
12813 aux_data = ni_frame_new_aux_data(
12814 p_frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
12815 if (!aux_data) {
12817 }
12818
12819 int32_t bitrate, framerate_num, framerate_denom;
12820 uint32_t min_maxFrameSize, maxFrameSize;
12821 bitrate = (p_enc_ctx->target_bitrate > 0) ? p_enc_ctx->target_bitrate : p_param->bitrate;
12822
12823 if ((p_enc_ctx->framerate.framerate_num > 0) && (p_enc_ctx->framerate.framerate_denom > 0))
12824 {
12825 framerate_num = p_enc_ctx->framerate.framerate_num;
12826 framerate_denom = p_enc_ctx->framerate.framerate_denom;
12827 }
12828 else
12829 {
12830 framerate_num = (int32_t) p_param->fps_number;
12831 framerate_denom = (int32_t) p_param->fps_denominator;
12832 }
12833
12834 min_maxFrameSize = ((uint32_t)bitrate / framerate_num * framerate_denom) / 8;
12835 maxFrameSize = min_maxFrameSize * maxFrameSizeRatio > NI_MAX_FRAME_SIZE ?
12836 NI_MAX_FRAME_SIZE : min_maxFrameSize * maxFrameSizeRatio;
12837 *((int32_t *)aux_data->data) = maxFrameSize;
12838 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12839 "xcoder_send_frame: frame #%lu reconf "
12840 "maxFrameSizeRatio %d maxFrameSize %d\n",
12841 p_enc_ctx->frame_num, maxFrameSizeRatio, maxFrameSize);
12842
12843 p_enc_ctx->reconfigCount++;
12844 }
12845 break;
12847 if (p_enc_ctx->frame_num ==
12848 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12849 aux_data = ni_frame_new_aux_data(
12850 p_frame, NI_FRAME_AUX_DATA_SLICE_ARG, sizeof(int16_t));
12851 if (!aux_data) {
12853 }
12854 *((int16_t *)aux_data->data) =
12855 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12856 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12857 "xcoder_send_frame: frame #%lu reconf "
12858 "sliceArg %d\n",
12859 p_enc_ctx->frame_num,
12860 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12861
12862 p_enc_ctx->reconfigCount++;
12863 }
12864 break;
12865 // force IDR frame through API test code
12867 if (p_enc_ctx->frame_num ==
12868 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12869 ni_force_idr_frame_type(p_enc_ctx);
12870 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12871 "xcoder_send_frame: frame #%lu force IDR frame\n",
12872 p_enc_ctx->frame_num);
12873
12874 p_enc_ctx->reconfigCount++;
12875 }
12876 break;
12877 // reconfig bit rate through API test code
12879 if (p_enc_ctx->frame_num ==
12880 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12881 if ((retval = ni_reconfig_bitrate(
12882 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))){
12883 return retval;
12884 }
12885 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12886 "xcoder_send_frame: frame #%lu API reconfig BR %d\n",
12887 p_enc_ctx->frame_num,
12888 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12889
12890 p_enc_ctx->reconfigCount++;
12891 }
12892 break;
12894 if (p_enc_ctx->frame_num ==
12895 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12896 int32_t intraprd =
12897 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12898 if ((retval = ni_reconfig_intraprd(p_enc_ctx, intraprd))){
12899 return retval;
12900 }
12902 "xcoder_send_frame: frame #%lu API reconfig intraPeriod %d\n",
12903 p_enc_ctx->frame_num,
12904 intraprd);
12905
12906 p_enc_ctx->reconfigCount++;
12907 }
12908 break;
12910 if (p_enc_ctx->frame_num ==
12911 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12912 ni_vui_hrd_t vui;
12913 vui.colorDescPresent =
12914 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12915 vui.colorPrimaries =
12916 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12917 vui.colorTrc =
12918 p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
12919 vui.colorSpace =
12920 p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
12921 vui.aspectRatioWidth =
12922 p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
12923 vui.aspectRatioHeight =
12924 p_param->reconf_hash[p_enc_ctx->reconfigCount][6];
12925 vui.videoFullRange =
12926 p_param->reconf_hash[p_enc_ctx->reconfigCount][7];
12927 if ((retval = ni_reconfig_vui(p_enc_ctx, &vui))){
12928 return retval;
12929 }
12930 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12931 "xcoder_send_frame: frame #%lu reconf "
12932 "vui colorDescPresent %d colorPrimaries %d "
12933 "colorTrc %d colorSpace %d aspectRatioWidth %d "
12934 "aspectRatioHeight %d videoFullRange %d\n",
12935 p_enc_ctx->frame_num, vui.colorDescPresent,
12936 vui.colorPrimaries, vui.colorTrc,
12939 p_enc_ctx->reconfigCount++;
12940 }
12941 break;
12943 if (p_enc_ctx->frame_num ==
12944 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12947 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12948 ltr.use_long_term_ref =
12949 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12950
12951 if ((retval = ni_set_ltr(p_enc_ctx, &ltr))) {
12952 return retval;
12953 }
12954 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12955 "xcoder_send_frame(): frame #%lu API set LTR\n",
12956 p_enc_ctx->frame_num);
12957 p_enc_ctx->reconfigCount++;
12958 }
12959 break;
12962 if (p_enc_ctx->frame_num ==
12963 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12964 ni_rc_min_max_qp qp_info;
12965 qp_info.minQpI = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12966 qp_info.maxQpI = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12967 qp_info.maxDeltaQp = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
12968 qp_info.minQpPB = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
12969 qp_info.maxQpPB = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
12970 if ((retval = ni_reconfig_min_max_qp(p_enc_ctx, &qp_info))) {
12971 return retval;
12972 }
12973 ni_log2(p_enc_ctx, NI_LOG_DEBUG,
12974 "%s(): frame %d minQpI %d maxQpI %d maxDeltaQp %d minQpPB %d maxQpPB %d\n",
12975 __func__, p_enc_ctx->frame_num,
12976 qp_info.minQpI, qp_info.maxQpI, qp_info.maxDeltaQp, qp_info.minQpPB, qp_info.maxQpPB);
12977 p_enc_ctx->reconfigCount++;
12978 }
12979 break;
12981 if (p_enc_ctx->frame_num ==
12982 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12983 if ((retval = ni_set_ltr_interval(
12984 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
12985 return retval;
12986 }
12987 ni_log2(p_enc_ctx,
12989 "xcoder_send_frame(): frame #%lu API set LTR interval %d\n",
12990 p_enc_ctx->frame_num,
12991 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12992 p_enc_ctx->reconfigCount++;
12993 }
12994 break;
12996 if (p_enc_ctx->frame_num ==
12997 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12998 if ((retval = ni_set_frame_ref_invalid(
12999 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13000 return retval;
13001 }
13002 ni_log2(p_enc_ctx,
13004 "xcoder_send_frame(): frame #%lu API set frame ref invalid "
13005 "%d\n",
13006 p_enc_ctx->frame_num,
13007 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13008 p_enc_ctx->reconfigCount++;
13009 }
13010 break;
13012 if (p_enc_ctx->frame_num ==
13013 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13014 ni_framerate_t framerate;
13015 framerate.framerate_num =
13016 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13017 framerate.framerate_denom =
13018 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13019 if ((retval = ni_reconfig_framerate(p_enc_ctx, &framerate))) {
13020 return retval;
13021 }
13022 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13023 "xcoder_send_frame: frame #%lu API reconfig framerate "
13024 "(%d/%d)\n",
13025 p_enc_ctx->frame_num,
13026 p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13027 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13028
13029 p_enc_ctx->reconfigCount++;
13030 }
13031 break;
13033 if (p_enc_ctx->frame_num ==
13034 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13035 if ((retval = ni_reconfig_max_frame_size(
13036 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13037 return retval;
13038 }
13039 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13040 "xcoder_send_frame: frame #%lu API reconfig maxFrameSize %d\n",
13041 p_enc_ctx->frame_num,
13042 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13043
13044 p_enc_ctx->reconfigCount++;
13045 }
13046 break;
13048 if (p_enc_ctx->frame_num ==
13049 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13050 if ((retval = ni_reconfig_crf(
13051 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13052 return retval;
13053 }
13054 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13055 "xcoder_send_frame: frame #%lu API reconfig crf %d\n",
13056 p_enc_ctx->frame_num,
13057 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13058
13059 p_enc_ctx->reconfigCount++;
13060 }
13061 break;
13063 if (p_enc_ctx->frame_num ==
13064 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13065 float crf = (float)(p_param->reconf_hash[p_enc_ctx->reconfigCount][1] +
13066 (float)p_param->reconf_hash[p_enc_ctx->reconfigCount][2] / 100.0);
13067 if ((retval = ni_reconfig_crf2(p_enc_ctx, crf))) {
13068 return retval;
13069 }
13070 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13071 "xcoder_send_frame: frame #%lu API reconfig crf %f\n",
13072 p_enc_ctx->frame_num, crf);
13073
13074 p_enc_ctx->reconfigCount++;
13075 }
13076 break;
13078 if (p_enc_ctx->frame_num ==
13079 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13080 if ((retval = ni_reconfig_vbv_value(
13081 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13082 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]))) {
13083 return retval;
13084 }
13085 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13086 "xcoder_send_frame: frame #%lu API reconfig vbvMaxRate %d vbvBufferSize %d\n",
13087 p_enc_ctx->frame_num,
13088 p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13089 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13090
13091 p_enc_ctx->reconfigCount++;
13092 }
13093 break;
13095 if (p_enc_ctx->frame_num ==
13096 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13097
13099 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13100 return retval;
13101 }
13102 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13103 "xcoder_send_frame: frame #%lu reconf maxFrameSizeRatio %d\n",
13104 p_enc_ctx->frame_num, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13105
13106 p_enc_ctx->reconfigCount++;
13107 }
13108 break;
13110 if (p_enc_ctx->frame_num ==
13111 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13112 if ((retval = ni_reconfig_slice_arg(
13113 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13114 return retval;
13115 }
13116 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13117 "xcoder_send_frame: frame #%lu API reconfig sliceArg %d\n",
13118 p_enc_ctx->frame_num,
13119 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13120
13121 p_enc_ctx->reconfigCount++;
13122 }
13123 break;
13124#endif
13126 default:
13127 ;
13128 }
13129 return NI_RETCODE_SUCCESS;
13130}
13131
13135static int ni_tolower(int c)
13136{
13137 if (c >= 'A' && c <= 'Z')
13138 c ^= 0x20;
13139 return c;
13140}
13141
13142int ni_strcasecmp(const char *a, const char *b)
13143{
13144 uint8_t c1, c2;
13145 do
13146 {
13147 c1 = ni_tolower(*a++);
13148 c2 = ni_tolower(*b++);
13149 } while (c1 && c1 == c2);
13150 return c1 - c2;
13151}
13152
13154{
13155 ni_encoder_cfg_params_t *p_enc = &p_param->cfg_enc_params;
13158 p_gop->pic_param[0].rps[0].ref_pic = 1;
13160 p_gop->pic_param[0].rps[0].ref_pic_used = 1;
13162 p_gop->pic_param[0].rps[1].ref_pic = 1;
13164 p_gop->pic_param[0].rps[1].ref_pic_used = 1;
13166 p_gop->pic_param[0].rps[2].ref_pic = 1;
13168 p_gop->pic_param[0].rps[2].ref_pic_used = 1;
13170 p_gop->pic_param[0].rps[3].ref_pic = 1;
13172 p_gop->pic_param[0].rps[3].ref_pic_used = 1;
13174 p_gop->pic_param[1].rps[0].ref_pic = 1;
13176 p_gop->pic_param[1].rps[0].ref_pic_used = 1;
13178 p_gop->pic_param[1].rps[1].ref_pic = 1;
13180 p_gop->pic_param[1].rps[1].ref_pic_used = 1;
13182 p_gop->pic_param[1].rps[2].ref_pic = 1;
13184 p_gop->pic_param[1].rps[2].ref_pic_used = 1;
13186 p_gop->pic_param[1].rps[3].ref_pic = 1;
13188 p_gop->pic_param[1].rps[3].ref_pic_used = 1;
13190 p_gop->pic_param[2].rps[0].ref_pic = 1;
13192 p_gop->pic_param[2].rps[0].ref_pic_used = 1;
13194 p_gop->pic_param[2].rps[1].ref_pic = 1;
13196 p_gop->pic_param[2].rps[1].ref_pic_used = 1;
13198 p_gop->pic_param[2].rps[2].ref_pic = 1;
13200 p_gop->pic_param[2].rps[2].ref_pic_used = 1;
13202 p_gop->pic_param[2].rps[3].ref_pic = 1;
13204 p_gop->pic_param[2].rps[3].ref_pic_used = 1;
13206 p_gop->pic_param[3].rps[0].ref_pic = 1;
13208 p_gop->pic_param[3].rps[0].ref_pic_used = 1;
13210 p_gop->pic_param[3].rps[1].ref_pic = 1;
13212 p_gop->pic_param[3].rps[1].ref_pic_used = 1;
13214 p_gop->pic_param[3].rps[2].ref_pic = 1;
13216 p_gop->pic_param[3].rps[2].ref_pic_used = 1;
13218 p_gop->pic_param[3].rps[3].ref_pic = 1;
13220 p_gop->pic_param[3].rps[3].ref_pic_used = 1;
13222 p_gop->pic_param[4].rps[0].ref_pic = 1;
13224 p_gop->pic_param[4].rps[0].ref_pic_used = 1;
13226 p_gop->pic_param[4].rps[1].ref_pic = 1;
13228 p_gop->pic_param[4].rps[1].ref_pic_used = 1;
13230 p_gop->pic_param[4].rps[2].ref_pic = 1;
13232 p_gop->pic_param[4].rps[2].ref_pic_used = 1;
13234 p_gop->pic_param[4].rps[3].ref_pic = 1;
13236 p_gop->pic_param[4].rps[3].ref_pic_used = 1;
13238 p_gop->pic_param[5].rps[0].ref_pic = 1;
13240 p_gop->pic_param[5].rps[0].ref_pic_used = 1;
13242 p_gop->pic_param[5].rps[1].ref_pic = 1;
13244 p_gop->pic_param[5].rps[1].ref_pic_used = 1;
13246 p_gop->pic_param[5].rps[2].ref_pic = 1;
13248 p_gop->pic_param[5].rps[2].ref_pic_used = 1;
13250 p_gop->pic_param[5].rps[3].ref_pic = 1;
13252 p_gop->pic_param[5].rps[3].ref_pic_used = 1;
13254 p_gop->pic_param[6].rps[0].ref_pic = 1;
13256 p_gop->pic_param[6].rps[0].ref_pic_used = 1;
13258 p_gop->pic_param[6].rps[1].ref_pic = 1;
13260 p_gop->pic_param[6].rps[1].ref_pic_used = 1;
13262 p_gop->pic_param[6].rps[2].ref_pic = 1;
13264 p_gop->pic_param[6].rps[2].ref_pic_used = 1;
13266 p_gop->pic_param[6].rps[3].ref_pic = 1;
13268 p_gop->pic_param[6].rps[3].ref_pic_used = 1;
13270 p_gop->pic_param[7].rps[0].ref_pic = 1;
13272 p_gop->pic_param[7].rps[0].ref_pic_used = 1;
13274 p_gop->pic_param[7].rps[1].ref_pic = 1;
13276 p_gop->pic_param[7].rps[1].ref_pic_used = 1;
13278 p_gop->pic_param[7].rps[2].ref_pic = 1;
13280 p_gop->pic_param[7].rps[2].ref_pic_used = 1;
13282 p_gop->pic_param[7].rps[3].ref_pic = 1;
13284 p_gop->pic_param[7].rps[3].ref_pic_used = 1;
13285
13286}
13287
13289{
13290 ni_encoder_cfg_params_t *p_enc = &p_param->cfg_enc_params;
13292 int i, j;
13293 for (i=0; i<NI_MAX_GOP_NUM; i++)
13294 {
13295 for (j=0; j<NI_MAX_REF_PIC; j++)
13296 {
13297 if (p_gop->pic_param[i].rps[j].ref_pic == 1 &&
13298 p_gop->pic_param[i].rps[j].ref_pic_used != 1)
13299 {
13301 "g%drefPic%d specified without g%drefPic%dUsed specified!\n",
13302 i, j, i, j);
13303 return false;
13304 }
13305 }
13306 }
13307 // set custom_gop_params default.
13308 for (i=0; i<NI_MAX_GOP_NUM; i++)
13309 {
13310 for (j=0; j<NI_MAX_REF_PIC; j++)
13311 {
13312 p_gop->pic_param[i].rps[j].ref_pic = 0;
13313 p_gop->pic_param[i].rps[j].ref_pic_used = 0;
13314 }
13315 }
13316 return true;
13317}
13318
13319#ifndef DEPRECATION_AS_ERROR
13320/*!*****************************************************************************
13321 * \brief Initiate P2P transfer (P2P write) (deprecated)
13322 *
13323 * \param[in] pSession Pointer to source card destination
13324 * \param[in] source Pointer to source frame to transmit
13325 * \param[in] ui64DestAddr Destination address on target device
13326 * \param[in] ui32FrameSize Size of frame to transfer
13327 *
13328 * \return always returns
13329 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13330*******************************************************************************/
13332 niFrameSurface1_t *source,
13333 uint64_t ui64DestAddr,
13334 uint32_t ui32FrameSize)
13335{
13336 // avoid compiler warnings
13337 (void) pSession;
13338 (void) source;
13339 (void) ui64DestAddr;
13340 (void) ui32FrameSize;
13341
13343}
13344#endif
13345
13346/*!*****************************************************************************
13347 * \brief Initiate P2P transfer (P2P write)
13348 *
13349 * \param[in] pSession Pointer to source card destination
13350 * \param[in] source Pointer to source frame to transmit
13351 * \param[in] ui64DestAddr Destination address on target device
13352 * \param[in] ui32FrameSize Size of frame to transfer
13353 *
13354 * \return on success
13355 * NI_RETCODE_SUCCESS
13356 * on failure
13357 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13358 * NI_RETCODE_INVALID_PARAM
13359 * NI_RETCODE_ERROR_INVALID_SESSION
13360 * NI_RETCODE_ERROR_MEM_ALOC
13361 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13362*******************************************************************************/
13364 niFrameSurface1_t *source,
13365 uint64_t ui64DestAddr, uint32_t ui32FrameSize)
13366{
13368
13369 if ((pSession == NULL) || (source == NULL))
13370 {
13372 }
13373
13374 /* Firmware compatibility check */
13375 if (ni_cmp_fw_api_ver((char *) &pSession->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6re") < 0)
13376 {
13377 ni_log2(pSession, NI_LOG_ERROR, "%s: FW doesn't support this operation\n", __func__);
13379 }
13380
13381 retval = ni_send_to_target(pSession, source, ui64DestAddr, ui32FrameSize);
13382
13383 if (retval < 0)
13384 {
13385 ni_log2(pSession, NI_LOG_ERROR, "%s(): Can't DMA to destination (%d)\n", __func__, retval);
13386 }
13387
13388 return retval;
13389}
13390
13391/*!*****************************************************************************
13392 * \brief Initiate a P2P transfer (P2P read)
13393 *
13394 * \param[in] pSession Pointer to destination upload session
13395 * \param[in] dmaAddrs Pointer to source DMA addresses
13396 * \param[in] pDstFrame Pointer to destination P2P frame
13397 *
13398 * \return on success
13399 * NI_RETCODE_SUCCESS
13400 * on failure
13401 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13402 * NI_RETCODE_INVALID_PARAM
13403 * NI_RETCODE_ERROR_INVALID_SESSION
13404 * NI_RETCODE_ERROR_MEM_ALOC
13405 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13406*******************************************************************************/
13408 const ni_p2p_sgl_t *dmaAddrs,
13409 ni_frame_t *pDstFrame)
13410{
13412
13413 if ((pSession == NULL) || (dmaAddrs == NULL) || (pDstFrame == NULL))
13414 {
13416 }
13417
13418 /* Firmware compatibility check */
13419 if (ni_cmp_fw_api_ver((char *) &pSession->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6re") < 0)
13420 {
13421 ni_log2(pSession, NI_LOG_ERROR,
13422 "%s: FW doesn't support this operation\n", __func__);
13424 }
13425
13426 retval = ni_recv_from_target(pSession, dmaAddrs, pDstFrame);
13427
13428 if (retval < 0)
13429 {
13430 ni_log2(pSession, NI_LOG_ERROR,
13431 "%s(): Can't DMA from source (%d)\n", __func__, retval);
13432 retval = NI_RETCODE_INVALID_PARAM;
13433 }
13434
13435 return retval;
13436}
13437
13438/*!*****************************************************************************
13439 * \brief Send a restart command after flush command
13440 * Only support Encoder now
13441 *
13442 * \param[in] p_ctx Pointer to a caller allocated
13443 * ni_session_context_t struct
13444 * \param[in] width width, in pixels
13445 * \param[in] height height, in pixels
13446 * \param[in] device_type NI_DEVICE_TYPE_ENCODER
13447 * \return On success
13448 * NI_RETCODE_SUCCESS
13449 * On failure
13450 * NI_RETCODE_INVALID_PARAM
13451 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13452 * NI_RETCODE_ERROR_INVALID_SESSION
13453 ******************************************************************************/
13455 int video_width,
13456 int video_height,
13457 ni_device_type_t device_type)
13458{
13459 ni_retcode_t retval = 0;
13460 ni_resolution_t resolution;
13461 ni_xcoder_params_t *p_param = NULL;
13462
13463 if (!p_ctx)
13464 {
13465 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
13466 __func__);
13468 }
13469
13470 switch (device_type)
13471 {
13473 {
13474 // requires API version >= 54
13476 "54") < 0)
13477 {
13478 ni_log2(p_ctx, NI_LOG_ERROR, "Error: %s function not supported on device with FW API version < 5.4\n", __func__);
13480 }
13481
13482 /* This function should be called only if flushing is detected */
13484 {
13485 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() wrong state %d\n",
13486 __func__, p_ctx->session_run_state);
13488 }
13489
13490 if (video_width < NI_MIN_WIDTH || video_width > NI_MAX_WIDTH ||
13491 video_height < NI_MIN_HEIGHT || video_height > NI_MAX_HEIGHT)
13492 {
13493 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() invalid width %d or height %d\n",
13494 __func__, video_width, video_height);
13496 }
13497 resolution.width = video_width;
13498 resolution.height = video_height;
13499 resolution.bit_depth_factor = p_ctx->bit_depth_factor;
13500 resolution.luma_linesize = 0;
13501 resolution.chroma_linesize = 0;
13502 if (p_ctx->p_session_config)
13503 {
13504 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
13505 resolution.luma_linesize = p_param->luma_linesize;
13506 resolution.chroma_linesize = p_param->chroma_linesize;
13507 }
13509
13510 // reconfig the encoder session
13511 retval = ni_encoder_session_sequence_change(p_ctx, &resolution);
13512 if (NI_RETCODE_SUCCESS != retval)
13513 {
13514 ni_log(NI_LOG_ERROR, "Failed to reconfig config the encoder session (status = %d)\n", retval);
13516 return retval;
13517 }
13518
13519 // update session context
13520 p_ctx->ready_to_close = 0;
13521 p_ctx->frame_num = 0;
13522 p_ctx->pkt_num = 0;
13524 break;
13525 }
13526 default:
13527 {
13528 retval = NI_RETCODE_INVALID_PARAM;
13529 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unsupported device type: %d",
13530 __func__, device_type);
13531 break;
13532 }
13533 }
13534 return retval;
13535}
13536
13537/*!******************************************************************************
13538* \brief Send a p_config command to reconfigure decoding ppu params.
13539*
13540* \param ni_session_context_t p_session_ctx - xcoder Context
13541* \param ni_xcoder_params_t p_param - xcoder Params
13542* \param ni_ppu_config_t p_ppu_config - Struct ni_ppu_config
13543*
13544* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
13545*******************************************************************************/
13547 ni_xcoder_params_t *p_param, ni_ppu_config_t *p_ppu_config)
13548{
13549 int ret = 0, i = 0;
13550 if (!p_session_ctx || !p_param || !p_ppu_config)
13551 {
13553 return ret;
13554 }
13555 if (p_session_ctx->ppu_reconfig_pkt_pos != 0)
13556 {
13557 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: Warning ignore ppu reconfig before last config done!\n", __func__);
13558 return 0;
13559 }
13560
13561 // check fw revision
13563 (char*) &p_session_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
13564 "6sF") < 0)
13565 {
13566 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: not supported on device with FW API version < 6sF\n", __func__);
13568 }
13569
13570 if (NI_CODEC_FORMAT_H264 != p_session_ctx->codec_format &&
13571 NI_CODEC_FORMAT_H265 != p_session_ctx->codec_format)
13572 {
13573 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): only supported for h264 and h265 decoder\n", __func__);
13575 }
13576
13577 ni_decoder_input_params_t *p_dec_input_param = &(p_param->dec_input_params);
13578 if (p_dec_input_param->hwframes != 1)
13579 {
13580 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): only supported for hw mode\n", __func__);
13582 }
13583 if (!p_dec_input_param->disable_adaptive_buffers)
13584 {
13585 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): not supported when disable_adaptive_buffers is disabled\n", __func__);
13587 }
13588 if (p_dec_input_param->mcmode)
13589 {
13590 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): not supported when MulticoreJointMode is enabled\n", __func__);
13592 }
13593 if (p_dec_input_param->enable_out1 == 0 &&
13594 p_ppu_config->ppu_set_enable & (0x01 << 1))
13595 {
13596 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Error reconfig ppu1 while ppu1 is not enabled\n", __func__);
13598 }
13599 if (p_dec_input_param->enable_out2 == 0 &&
13600 p_ppu_config->ppu_set_enable & (0x01 << 2))
13601 {
13602 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Error reconfig ppu2 while ppu2 is not enabled\n", __func__);
13604 }
13605 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
13606 {
13607 if (p_ppu_config->ppu_set_enable & (0x01 << i))
13608 {
13609 if (p_ppu_config->ppu_w[i] > NI_MAX_RESOLUTION_WIDTH ||
13610 p_ppu_config->ppu_h[i] > NI_MAX_RESOLUTION_HEIGHT ||
13611 p_ppu_config->ppu_w[i] < NI_MIN_RESOLUTION_WIDTH_SCALER ||
13612 p_ppu_config->ppu_h[i] < NI_MIN_RESOLUTION_WIDTH_SCALER)
13613 {
13614 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu[%d] width x height %ux%u "
13615 "out of range\n", __func__, i, p_ppu_config->ppu_w[i], p_ppu_config->ppu_h[i]);
13617 return ret;
13618 }
13619 if ((p_ppu_config->ppu_w[i] & 1) || (p_ppu_config->ppu_h[i] & 1))
13620 {
13621 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu[%d] wxh %dx%d not align to 2!\n",
13622 __func__, i, p_ppu_config->ppu_w[i], p_ppu_config->ppu_h[i]);
13624 return ret;
13625 }
13626 }
13627 }
13629 p_session_ctx, p_ppu_config, sizeof(ni_ppu_config_t));
13630 if (ret == NI_RETCODE_SUCCESS)
13631 {
13632 p_session_ctx->ppu_reconfig_pkt_pos = p_session_ctx->pkt_num;
13633 }
13634 return ret;
13635}
#define NI_DEPRECATED
Definition ni_defs.h:80
#define NI_MAX_FILTER_POOL_SIZE
Definition ni_defs.h:329
#define NI_XCODER_REVISION_API_MAJOR_VER_IDX
Definition ni_defs.h:99
#define NI_MAX_NUM_SW_FRAME_DATA_POINTERS
Definition ni_defs.h:246
#define END
Definition ni_defs.h:338
#define NI_MAX_NUM_DATA_POINTERS
Definition ni_defs.h:244
#define NI_INVALID_IO_SIZE
Definition ni_defs.h:233
#define NI_APP_ENC_FRAME_META_DATA_SIZE
Definition ni_defs.h:322
#define NI_MAX_NUM_OF_DECODER_OUTPUTS
Definition ni_defs.h:255
ni_device_type_t
Definition ni_defs.h:356
@ NI_DEVICE_TYPE_SCALER
Definition ni_defs.h:362
@ NI_DEVICE_TYPE_AI
Definition ni_defs.h:363
@ NI_DEVICE_TYPE_DECODER
Definition ni_defs.h:360
@ NI_DEVICE_TYPE_UPLOAD
Definition ni_defs.h:367
@ NI_DEVICE_TYPE_ENCODER
Definition ni_defs.h:361
#define NI_ERRNO
Definition ni_defs.h:229
#define NI_MAX_PACKET_SZ
Definition ni_defs.h:239
#define NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL
Definition ni_defs.h:300
@ NI_SCALER_OPCODE_OVERLAY
Definition ni_defs.h:593
@ NI_SCALER_OPCODE_WATERMARK
Definition ni_defs.h:598
#define NI_MEM_PAGE_ALIGNMENT
Definition ni_defs.h:263
#define TOTAL_CPU_LOG_BUFFER_SIZE
Definition ni_defs.h:374
#define NI_FW_META_DATA_SZ
Definition ni_defs.h:320
#define QUADRA
Definition ni_defs.h:123
#define LRETURN
Definition ni_defs.h:337
ni_retcode_t
Definition ni_defs.h:442
@ NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
Definition ni_defs.h:523
@ NI_RETCODE_PARAM_WARNING_DEPRECATED
Definition ni_defs.h:532
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_BIG
Definition ni_defs.h:514
@ NI_RETCODE_PARAM_ERROR_ZERO
Definition ni_defs.h:508
@ NI_RETCODE_FAILURE
Definition ni_defs.h:444
@ NI_RETCODE_ERROR_PERMISSION_DENIED
Definition ni_defs.h:539
@ NI_RETCODE_ERROR_INVALID_SESSION
Definition ni_defs.h:449
@ NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
Definition ni_defs.h:537
@ NI_RETCODE_ERROR_GET_DEVICE_POOL
Definition ni_defs.h:522
@ NI_RETCODE_ERROR_UNLOCK_DEVICE
Definition ni_defs.h:525
@ NI_RETCODE_PARAM_INVALID_NAME
Definition ni_defs.h:452
@ NI_RETCODE_PARAM_ERROR_AREA_TOO_BIG
Definition ni_defs.h:518
@ NI_RETCODE_SUCCESS
Definition ni_defs.h:443
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_SMALL
Definition ni_defs.h:516
@ NI_RETCODE_ERROR_INVALID_HANDLE
Definition ni_defs.h:527
@ NI_RETCODE_PARAM_ERROR_TOO_BIG
Definition ni_defs.h:505
@ NI_RETCODE_PARAM_INVALID_VALUE
Definition ni_defs.h:453
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_BIG
Definition ni_defs.h:510
@ NI_RETCODE_ERROR_NVME_CMD_FAILED
Definition ni_defs.h:448
@ NI_RETCODE_ERROR_MEM_ALOC
Definition ni_defs.h:447
@ NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
Definition ni_defs.h:538
@ NI_RETCODE_PARAM_ERROR_OOR
Definition ni_defs.h:509
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_SMALL
Definition ni_defs.h:512
@ NI_RETCODE_INVALID_PARAM
Definition ni_defs.h:445
@ NI_RETCODE_PARAM_ERROR_TOO_SMALL
Definition ni_defs.h:506
@ NI_RETCODE_ERROR_OPEN_DEVICE
Definition ni_defs.h:526
#define NI_MAX_PPU_PARAM_EXPR_CHAR
Definition ni_defs.h:259
#define IS_XCODER_DEVICE_TYPE(t)
Definition ni_defs.h:426
#define NI_INVALID_HWID
Definition ni_defs.h:232
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)
ni_retcode_t ni_ai_config_network_binary(ni_session_context_t *p_ctx, ni_network_data_t *p_network, const char *file)
configure a network context based with the network binary
ni_retcode_t ni_frame_buffer_alloc_dl(ni_frame_t *p_frame, int video_width, int video_height, int pixel_format)
Allocate preliminary memory for the frame buffer based on provided parameters.
ni_retcode_t ni_device_session_flush(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Send a flush command to the device If device_type is NI_DEVICE_TYPE_DECODER sends EOS command to deco...
#define atof(p_str)
ni_aux_data_t * ni_frame_new_aux_data(ni_frame_t *frame, ni_aux_data_type_t type, int data_size)
Add a new auxiliary data to a frame.
const char *const g_xcoder_log_names[NI_XCODER_LOG_NAMES_ARRAY_LEN]
void ni_gop_params_check_set(ni_xcoder_params_t *p_param, char *value)
Set custom gop and prepare to check if success.
ni_retcode_t ni_reconfig_max_frame_size_ratio(ni_session_context_t *p_ctx, int32_t max_frame_size_ratio)
Reconfigure maxFrameSizeRatio dynamically during encoding.
#define COMPARE(STR1, STR2, STR3)
ni_retcode_t ni_ai_config_hvsplus(ni_session_context_t *p_ctx, ni_network_data_t *p_network)
configure a hvsplus filter
NI_DEPRECATED ni_device_handle_t ni_device_open(const char *p_dev, uint32_t *p_max_io_size_out)
Open device and return device device_handle if successful.
void ni_frame_free_aux_data(ni_frame_t *frame, ni_aux_data_type_t type)
If auxiliary data of the given type exists in the frame, free it and remove it from the frame.
#define OPT(STR)
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...
ni_retcode_t ni_encoder_frame_zerocopy_buffer_alloc(ni_frame_t *p_frame, int video_width, int video_height, const int linesize[], const uint8_t *data[], int extra_len)
Allocate memory for encoder zero copy (metadata, etc.) for encoding based on given parameters,...
void ni_frame_wipe_aux_data(ni_frame_t *frame)
Free and remove all auxiliary data from the frame.
int ni_calculate_total_frame_size(const ni_session_context_t *p_upl_ctx, const int linesize[])
Calculate the total size of a frame based on the upload context attributes and includes rounding up t...
ni_retcode_t ni_decoder_params_set_value(ni_xcoder_params_t *p_params, const char *name, char *value)
Set value referenced by name in decoder parameters structure.
ni_retcode_t ni_reconfig_intraprd(ni_session_context_t *p_ctx, int32_t intra_period)
Reconfigure intraPeriod dynamically during encoding.
ni_retcode_t ni_scaler_set_watermark_params(ni_session_context_t *p_ctx, ni_scaler_watermark_params_t *p_params)
Send a p_config command to configure scaling watermark parameters.
ni_retcode_t ni_dec_reconfig_ppu_params(ni_session_context_t *p_session_ctx, ni_xcoder_params_t *p_param, ni_ppu_config_t *p_ppu_config)
Send a p_config command to reconfigure decoding ppu params.
ni_retcode_t ni_frame_buffer_alloc_pixfmt(ni_frame_t *p_frame, int pixel_format, int video_width, int video_height, int linesize[], int alignment, int extra_len)
Allocate memory for the frame buffer based on provided parameters taking into account the pixel forma...
ni_retcode_t ni_query_nvme_status(ni_session_context_t *p_ctx, ni_load_query_t *p_load_query)
Query NVMe load from the device.
ni_retcode_t ni_frame_buffer_alloc_nv(ni_frame_t *p_frame, int video_width, int video_height, int linesize[], int extra_len, bool alignment_2pass_wa)
Allocate memory for the frame buffer based on provided parameters taking into account pic line size a...
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 ni_packet_copy(void *p_destination, const void *const p_source, int cur_size, void *p_leftover, int *p_prev_size)
Copy video packet accounting for alignment.
ni_retcode_t ni_scaler_p2p_frame_acquire(ni_session_context_t *p_ctx, niFrameSurface1_t *p_surface, int data_len)
Acquire the scaler P2P DMA buffer for read/write.
ni_retcode_t ni_ai_frame_buffer_alloc(ni_frame_t *p_frame, ni_network_data_t *p_network)
Allocate input layers memory for AI frame buffer based on provided parameters taking into account wid...
void ni_device_session_context_free(ni_session_context_t *p_ctx)
Free previously allocated session context.
int ni_device_session_hwdl(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data, niFrameSurface1_t *hwdesc)
Reads YUV data from hw descriptor stored location on device.
ni_retcode_t ni_device_config_qos_op(ni_device_handle_t device_handle, ni_device_handle_t device_handle_t, uint32_t over_provision)
Send qos over provisioning mode to target namespace with specified logic block address.
int ni_strcasecmp(const char *a, const char *b)
ni_retcode_t ni_frame_buffer_alloc(ni_frame_t *p_frame, int video_width, int video_height, int alignment, int metadata_flag, int factor, int hw_frame_count, int is_planar)
Allocate preliminary memory for the frame buffer based on provided parameters. Applicable to YUV420 P...
ni_retcode_t ni_scaler_frame_pool_alloc(ni_session_context_t *p_ctx, ni_scaler_input_params_t scaler_params)
init output pool of scaler frames
ni_retcode_t ni_scaler_set_drawbox_params(ni_session_context_t *p_ctx, ni_scaler_drawbox_params_t *p_params)
Send a p_config command to configure scaling drawbox parameters.
ni_retcode_t ni_device_clone_hwframe(ni_session_context_t *p_ctx, ni_frameclone_desc_t *p_frameclone_desc)
Copy the data of src hwframe to dst hwframe.
ni_retcode_t ni_ai_session_read_metrics(ni_session_context_t *p_ctx, ni_network_perf_metrics_t *p_metrics)
Fetch perf metrics of inferences from 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_DEPRECATED ni_retcode_t ni_device_capability_query(ni_device_handle_t device_handle, ni_device_capability_t *p_cap)
Query device and return device capability structure This function had been replaced by ni_device_capa...
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...
ni_event_handle_t ni_create_event(void)
Create event and return event handle if successful (Windows only)
ni_retcode_t ni_parse_customize_qpoffset_file(const char *customize_file, int8_t qp_map[][NI_CUSTOMIZE_ROI_QP_NUM])
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.
#define OPT2(STR1, STR2)
void ni_decoder_frame_buffer_pool_return_buf(ni_buf_t *buf, ni_buf_pool_t *p_buffer_pool)
Return a memory buffer to memory buffer pool.
ni_retcode_t ni_packet_buffer_free(ni_packet_t *p_packet)
Free packet buffer that was previously allocated with ni_packet_buffer_alloc.
int ni_device_session_hwup(ni_session_context_t *p_ctx, ni_session_data_io_t *p_src_data, niFrameSurface1_t *hwdesc)
Sends raw YUV input to uploader instance and retrieves a HW descriptor to represent it.
ni_retcode_t ni_encoder_frame_zerocopy_check(ni_session_context_t *p_enc_ctx, ni_xcoder_params_t *p_enc_params, int width, int height, const int linesize[], bool set_linesize)
Check if incoming frame is encoder zero copy compatible or not.
ni_retcode_t ni_hwframe_p2p_buffer_recycle(ni_frame_t *p_frame)
Recycle hw P2P frames.
ni_retcode_t ni_query_fl_fw_versions(ni_device_handle_t device_handle, ni_device_info_t *p_dev_info)
Query firmware loader and firmware versions from the device.
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_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...
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_device_capability_query2(ni_device_handle_t device_handle, ni_device_capability_t *p_cap, bool device_in_ctxt)
Query device and return device capability structure This function had replaced ni_device_capability_q...
ni_retcode_t ni_uploader_frame_buffer_unlock(ni_session_context_t *p_upl_ctx, ni_frame_t *p_frame)
Unlock a hardware P2P frame after encoding.
ni_retcode_t ni_scaler_dest_frame_alloc(ni_session_context_t *p_ctx, ni_scaler_input_params_t scaler_params, niFrameSurface1_t *p_surface)
allocate device destination frame from scaler hwframe pool
ni_retcode_t ni_set_ltr(ni_session_context_t *p_ctx, ni_long_term_ref_t *ltr)
Set a frame's support of Long Term Reference frame during encoding.
ni_retcode_t ni_hwframe_buffer_recycle2(niFrameSurface1_t *surface)
Recycle a frame buffer on card, only hwframe descriptor is needed.
ni_retcode_t ni_device_session_query(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Query session data from the device - If device_type is valid, will query session data from specified ...
ni_retcode_t ni_hwframe_buffer_recycle(niFrameSurface1_t *surface, int32_t device_handle)
Recycle a frame buffer on card.
ni_retcode_t ni_device_session_copy(ni_session_context_t *src_p_ctx, ni_session_context_t *dst_p_ctx)
Copy existing decoding session params for hw frame usage.
ni_session_context_t * ni_device_session_context_alloc_init(void)
Allocate and initialize a new ni_session_context_t struct.
ni_retcode_t ni_reconfig_max_frame_size(ni_session_context_t *p_ctx, int32_t max_frame_size)
Reconfigure maxFrameSize dynamically during encoding.
ni_retcode_t ni_device_session_sequence_change(ni_session_context_t *p_ctx, int width, int height, int bit_depth_factor, ni_device_type_t device_type)
Send sequence change information to device.
ni_retcode_t ni_device_session_query_detail_v1(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_instance_mgr_detail_status_v1_t *detail_data)
Query detail session data from the device - If device_type is valid, will query session data from spe...
bool ni_gop_params_check(ni_xcoder_params_t *p_param)
Check custom gop params set.
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_retcode_t ni_query_vf_ns_id(ni_device_handle_t device_handle, ni_device_vf_ns_id_t *p_dev_ns_vf, uint8_t fw_rev[])
Query VF and NS id from device.
ni_retcode_t ni_set_ltr_interval(ni_session_context_t *p_ctx, int32_t ltr_interval)
Set Long Term Reference interval.
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_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.
ni_retcode_t ni_ai_packet_buffer_alloc(ni_packet_t *p_packet, ni_network_data_t *p_network)
Allocate output layers memory for the packet buffer based on provided network.
ni_retcode_t ni_reconfig_min_max_qp(ni_session_context_t *p_ctx, ni_rc_min_max_qp *p_min_max_qp)
Reconfigure min&max qp dynamically during encoding.
ni_aux_data_t * ni_frame_get_aux_data(const ni_frame_t *frame, ni_aux_data_type_t type)
Retrieve from the frame auxiliary data of a given type if exists.
ni_retcode_t ni_device_session_context_init(ni_session_context_t *p_ctx)
Initialize already allocated session context to a known state.
ni_retcode_t ni_force_idr_frame_type(ni_session_context_t *p_ctx)
Force next frame to be IDR frame during encoding.
ni_retcode_t ni_reconfig_framerate(ni_session_context_t *p_ctx, ni_framerate_t *framerate)
Reconfigure framerate dynamically during encoding.
ni_retcode_t ni_device_dec_session_flush(ni_session_context_t *p_ctx)
Flush a decoder session to get ready to continue decoding. Note: this is different from ni_device_ses...
ni_retcode_t ni_device_session_query_detail(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_instance_mgr_detail_status_t *detail_data)
Query detail session data from the device - If device_type is valid, will query session data from spe...
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.
#define atoi(p_str)
ni_retcode_t ni_reconfig_crf(ni_session_context_t *p_ctx, int32_t crf)
Reconfigure crf value dynamically during encoding.
ni_retcode_t ni_scaler_input_frame_alloc(ni_session_context_t *p_ctx, ni_scaler_input_params_t scaler_params, niFrameSurface1_t *p_src_surface)
allocate device input frame by hw descriptor. This call won't actually allocate a frame but sends the...
ni_retcode_t ni_enc_prep_reconf_demo_data(ni_session_context_t *p_enc_ctx, ni_frame_t *p_frame)
Convert various reconfig and demo modes (stored in encoder configuration) to aux data and store them ...
ni_aux_data_t * ni_frame_new_aux_data_from_raw_data(ni_frame_t *frame, ni_aux_data_type_t type, const uint8_t *raw_data, int data_size)
Add a new auxiliary data to a frame and copy in the raw data.
ni_retcode_t ni_uploader_frame_zerocopy_check(ni_session_context_t *p_upl_ctx, int width, int height, const int linesize[], int pixel_format)
Check if incoming frame is hwupload zero copy compatible or not.
ni_retcode_t ni_device_session_restart(ni_session_context_t *p_ctx, int video_width, int video_height, ni_device_type_t device_type)
Send a restart command after flush command Only support Encoder now.
const char *const g_xcoder_preset_names[NI_XCODER_PRESET_NAMES_ARRAY_LEN]
void ni_close_event(ni_event_handle_t event_handle)
Close event and release resources (Windows only)
ni_retcode_t ni_device_alloc_frame(ni_session_context_t *p_ctx, int width, int height, int format, int options, int rectangle_width, int rectangle_height, int rectangle_x, int rectangle_y, int rgba_color, int frame_index, ni_device_type_t device_type)
Allocate a frame on the device for 2D engine or AI engine to work on based on provided parameters.
ni_retcode_t ni_reconfig_vbv_value(ni_session_context_t *p_ctx, int32_t vbvMaxRate, int32_t vbvBufferSize)
Reconfigure vbv buffer size and vbv max rate dynamically during encoding.
ni_retcode_t ni_device_alloc_dst_frame(ni_session_context_t *p_ctx, niFrameSurface1_t *p_out_surface, ni_device_type_t device_type)
Allocate a frame on the device and return the frame index.
ni_retcode_t ni_device_config_frame(ni_session_context_t *p_ctx, ni_frame_config_t *p_cfg)
Configure the 2D engine to work based on provided parameters.
NI_DEPRECATED ni_retcode_t ni_p2p_xfer(ni_session_context_t *pSession, niFrameSurface1_t *source, uint64_t ui64DestAddr, uint32_t ui32FrameSize)
Initiate P2P transfer (P2P write) (deprecated)
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.
ni_retcode_t ni_reconfig_crf2(ni_session_context_t *p_ctx, float crf)
Reconfigure crf float point value dynamically during encoding.
ni_retcode_t ni_device_session_update_framepool(ni_session_context_t *p_ctx, uint32_t pool_size)
Sends frame pool change info to device.
int32_t ni_get_dma_buf_file_descriptor(const ni_frame_t *p_frame)
Get the DMA buffer file descriptor from the P2P frame.
ni_retcode_t ni_set_demo_roi_map(ni_session_context_t *p_enc_ctx)
Set up hard coded demo ROI map.
ni_retcode_t ni_set_frame_ref_invalid(ni_session_context_t *p_ctx, int32_t frame_num)
Set frame reference invalidation.
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
ni_retcode_t ni_device_alloc_and_get_firmware_logs(ni_session_context_t *p_ctx, void **p_log_buffer, bool gen_log_file)
Allocate log buffer if needed and retrieve firmware logs from 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.
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.
#define STRDUP(value)
ni_retcode_t ni_encoder_gop_params_set_value(ni_xcoder_params_t *p_params, const char *name, const char *value)
Set GOP parameter value referenced by name in encoder parameters structure.
ni_retcode_t ni_device_config_namespace_num(ni_device_handle_t device_handle, uint32_t namespace_num, uint32_t sriov_index)
Send namespace num and SRIOv index to the device with specified logic block address.
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...
ni_retcode_t ni_decoder_frame_buffer_alloc(ni_buf_pool_t *p_pool, ni_frame_t *p_frame, int alloc_mem, int video_width, int video_height, int alignment, int factor, int is_planar)
Allocate memory for decoder frame buffer based on provided parameters; the memory is retrieved from a...
ni_retcode_t ni_enc_frame_buffer_alloc(ni_frame_t *p_frame, int video_width, int video_height, int alignment, int metadata_flag, int factor, int hw_frame_count, int is_planar, ni_pix_fmt_t pix_fmt)
Wrapper function for ni_frame_buffer_alloc. Meant to handle RGBA min. resoulution considerations for ...
ni_retcode_t ni_reconfig_slice_arg(ni_session_context_t *p_ctx, int16_t sliceArg)
Reconfigure sliceArg dynamically during encoding.
int ni_device_session_read_hwdesc(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 hwdesc from decoder If ...
ni_retcode_t ni_query_extra_info(ni_device_handle_t device_handle, ni_device_extra_info_t *p_dev_extra_info, uint8_t fw_rev[])
Query CompositeTemp from device.
ni_retcode_t ni_parse_reconf_file(const char *reconf_file, int hash_map[][NI_BITRATE_RECONFIG_FILE_MAX_ENTRIES_PER_LINE])
ni_retcode_t ni_device_session_query_buffer_avail(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Query the session if a buffer is available.
ni_retcode_t ni_encoder_sw_frame_buffer_alloc(bool planar, ni_frame_t *p_frame, int video_width, int video_height, int linesize[], int alignment, int extra_len, bool alignment_2pass_wa)
This API is a wrapper for ni_encoder_frame_buffer_alloc(), used for planar pixel formats,...
ni_device_handle_t ni_device_open2(const char *p_dev, ni_device_mode_t mode)
Open device and return device device_handle if successful.
ni_retcode_t ni_encoder_frame_zerocopy_adjust(ni_session_context_t *p_enc_ctx, ni_frame_t *p_frame, int video_height, const int linesize[], const uint8_t *data[], int buf_size0, int buf_size1, int buf_size2, uint8_t *buf_data0, uint8_t *buf_data1, uint8_t *buf_data2)
Check if the frame data transferred is within a frame boundary and adjust with offset if it doesn't....
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.
ni_retcode_t ni_custom_packet_buffer_alloc(void *p_buffer, ni_packet_t *p_packet, int buffer_size)
Allocate packet buffer using a user provided pointer, the memory is expected to have already been all...
ni_retcode_t ni_scaler_set_params(ni_session_context_t *p_ctx, ni_scaler_params_t *p_params)
Set parameters on the device for the 2D engine.
ni_retcode_t ni_device_dec_session_save_hdrs(ni_session_context_t *p_ctx, uint8_t *hdr_data, uint8_t hdr_size)
Save a stream's headers in a decoder session that can be used later for continuous decoding from the ...
void ni_device_session_context_clear(ni_session_context_t *p_ctx)
Clear already allocated session context.
ni_retcode_t ni_device_multi_config_frame(ni_session_context_t *p_ctx, ni_frame_config_t p_cfg_in[], int numInCfgs, ni_frame_config_t *p_cfg_out)
Configure the 2D engine to work based on provided parameters.
ni_retcode_t ni_packet_buffer_free_av1(ni_packet_t *p_packet)
Free packet buffer that was previously allocated with ni_packet_buffer_alloc for AV1 packets merge.
ni_retcode_t ni_reconfig_vui(ni_session_context_t *p_ctx, ni_vui_hrd_t *vui)
Reconfigure VUI HRD dynamically during encoding.
ni_retcode_t ni_query_temperature(ni_device_handle_t device_handle, ni_device_temp_t *p_dev_temp, uint8_t fw_rev[])
Query CompositeTemp from device.
ni_retcode_t ni_reconfig_bitrate(ni_session_context_t *p_ctx, int32_t bitrate)
Reconfigure bitrate dynamically during encoding.
ni_retcode_t ni_encoder_frame_buffer_alloc(ni_frame_t *p_frame, int video_width, int video_height, int linesize[], int alignment, int extra_len, bool alignment_2pass_wa)
Allocate memory for the frame buffer for encoding based on given parameters, taking into account pic ...
#define GBRWLPARSE(OUT1, OUT2, OFF, IDX)
ni_retcode_t ni_p2p_send(ni_session_context_t *pSession, niFrameSurface1_t *source, uint64_t ui64DestAddr, uint32_t ui32FrameSize)
Initiate P2P transfer (P2P 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...
#define atobool(p_str)
ni_retcode_t ni_uploader_frame_buffer_lock(ni_session_context_t *p_upl_ctx, ni_frame_t *p_frame)
Lock a hardware P2P frame prior to encoding.
ni_retcode_t ni_device_config_qos(ni_device_handle_t device_handle, uint32_t mode)
Send qos mode to the device with specified logic block address.
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,...
Public definitions for operating NETINT video processing devices for video processing.
#define NI_PARAM_AV1_MIN_WIDTH
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC1_USED
#define NI_MIN_HEIGHT
#define NI_ENC_PARAM_PASS1_QP
#define NI_ENC_PARAM_PSNR_INTERVAL
#define NI_ENC_PARAM_RDO_QUANT
#define NI_DEC_PARAM_CROP_PARAM_1
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC2
@ SESSION_RUN_STATE_NORMAL
@ SESSION_RUN_STATE_SEQ_CHANGE_DRAINING
@ SESSION_RUN_STATE_FLUSHING
struct _ni_scaler_multi_drawbox_params_t ni_scaler_multi_drawbox_params_t
#define NI_PARAM_MIN_WIDTH
#define NI_DEC_PARAM_DISABLE_REORDER
#define NI_ENC_PARAM_GOP_SIZE
#define NI_ENC_PARAM_DECODING_REFRESH_TYPE
#define NI_ENC_PARAM_INTRA_REFRESH_MODE
#define NI_MIN_CU_SIZE_MODE
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC0
#define NI_ENC_PARAM_DISABLE_AV1_TIMING_INFO
#define NI_DEC_PARAM_SCALE_0
#define NI_PARAM_MAX_HEIGHT
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC2_USED
#define AV_CODEC_DEFAULT_BITRATE
#define NI_ENC_PARAM_GOP_PRESET_IDX
#define NI_ENC_PARAM_MAX_FRAME_SIZE_BITS_LOW_DELAY
#define NI_FRAME_BIG_ENDIAN
#define NI_ENC_PARAM_ENABLE_2PASS_GOP
#define NI_DEC_PARAM_ENABLE_CPU_AFFINITY
#define NI_DEC_PARAM_SCALE_0_LONG_SHORT_ADAPT
#define NI_ENC_PARAM_FORCED_HEADER_ENABLE
#define NI_DEFAULT_CU_SIZE_MODE
#define NI_ENC_PARAM_STATIC_MMAP_THRESHOLD
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC0
#define NI_MIN_INTRA_QP
@ XCODER_TEST_RECONF_MAX_FRAME_SIZE_RATIO
@ XCODER_TEST_RECONF_VBV_API
@ XCODER_TEST_RECONF_FRAMERATE_API
@ XCODER_TEST_RECONF_RC_MIN_MAX_QP_API
@ XCODER_TEST_RECONF_FRAMERATE
@ XCODER_TEST_RECONF_MAX_FRAME_SIZE
@ XCODER_TEST_RECONF_CRF_FLOAT
@ XCODER_TEST_RECONF_LTR_INTERVAL_API
@ XCODER_TEST_RECONF_SLICE_ARG
@ XCODER_TEST_RECONF_VUI_HRD
@ XCODER_TEST_CRF_API
@ XCODER_TEST_RECONF_LTR_INTERVAL
@ XCODER_TEST_RECONF_LTR_API
@ XCODER_TEST_RECONF_INTRAPRD
@ XCODER_TEST_RECONF_SLICE_ARG_API
@ XCODER_TEST_RECONF_RC_MIN_MAX_QP
@ XCODER_TEST_CRF_FLOAT_API
@ XCODER_TEST_RECONF_VUI_HRD_API
@ XCODER_TEST_FORCE_IDR_FRAME
@ XCODER_TEST_RECONF_BR_API
@ XCODER_TEST_RECONF_MAX_FRAME_SIZE_API
@ XCODER_TEST_RECONF_LONG_TERM_REF
@ XCODER_TEST_RECONF_MAX_FRAME_SIZE_RATIO_API
@ XCODER_TEST_RECONF_END
@ XCODER_TEST_RECONF_BR
@ XCODER_TEST_RECONF_RC_MIN_MAX_QP_REDUNDANT
@ XCODER_TEST_RECONF_CRF
@ XCODER_TEST_INVALID_REF_FRAME_API
@ XCODER_TEST_INVALID_REF_FRAME
@ XCODER_TEST_RECONF_VBV
@ XCODER_TEST_RECONF_INTRAPRD_API
@ XCODER_TEST_RECONF_RC_MIN_MAX_QP_API_REDUNDANT
@ XCODER_TEST_RECONF_OFF
#define NI_ENC_PARAM_TUNE_BFRAME_VISUAL
@ NI_POOL_TYPE_NONE
#define NI_ENC_PARAM_USE_RECOMMENDED_ENC_PARAMS
#define NI_ENC_PARAM_TEMPORAL_LAYERS_ENABLE
#define NI_MAX_USE_RECOMMENDED_ENC_PARAMS
#define NI_XCODER_LOG_NAME_WARN
#define NI_ENC_PARAM_LOG
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC1_USED
#define NI_BEST_MODEL_LOAD_STR
#define NI_ENC_PARAM_CUSTOMIZE_ROI_QP_MAP
#define NI_ENC_PARAM_CONF_WIN_RIGHT
union _ni_enc_avc_roi_custom_map ni_enc_avc_roi_custom_map_t
encoder AVC ROI custom map (1 MB = 8bits)
#define NI_BITRATE_RECONFIG_FILE_MAX_LINES
Max number of lines supported for the bitrate reconfig file.
#define NI_DEC_PARAM_ENABLE_FOLLOW_IFRAME
#define NI_MAX_WIDTH
#define NI_ENC_PARAM_CONF_WIN_LEFT
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC1_USED
#define NI_ENC_PARAM_LTR_REF_INTERVAL
#define NI_MIN_MAX_NUM_MERGE
#define NI_ENC_PARAM_CONSTANT_RATE_FACTOR_MAX
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC1
#define NI_ENC_PARAM_ROI_DEMO_MODE
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PICS
#define NI_ENC_PARAM_PREFERRED_TRANSFER_CHARACTERISTICS
#define NI_ENC_PARAM_CPLX_DECAY
#define NI_DEC_PARAM_OUT
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC2
#define NI_MIN_DYNAMIC_MERGE
#define NI_ENC_PARAM_MAX_DELTA_QP
#define NI_ENC_PARAM_QCOMP
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC3_USED
#define NI_DEC_PARAM_ENABLE_PPU_SCALE_ADAPT
#define NI_XCODER_LOG_NAMES_ARRAY_LEN
#define NI_MAX_RESOLUTION_LINESIZE
#define NI_ENC_GOP_PARAMS_G5_PIC_TYPE
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC0
#define NI_ENC_PARAM_ENABLE_CU_LEVEL_RATE_CONTROL
#define NI_ENC_PARAM_DOLBY_VISION_PROFILE
#define NI_ENC_PARAM_LTR_NEXT_INTERVAL
#define NI_MIN_WIDTH
#define NI_DEC_PARAM_SCALE_1_ROUND
#define NI_XCODER_PRESET_NAME_MEDIUM
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PICS
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC0_USED
#define NI_ENC_PARAM_MIN_FRAMES_DELAY
#define NI_ENC_GOP_PARAMS_G3_TEMPORAL_ID
#define NI_DEC_PARAM_SCALE_0_RES_CEIL
#define NI_ENC_PARAM_MULTICORE_JOINT_MODE
#define NI_ENC_PARAM_VERTICAL_OFFSET
#define NI_ENC_PARAM_ENABLE_RATE_CONTROL
#define NI_ENC_PARAM_VIDEO_FULL_RANGE_FLAG
#define NI_ENC_PARAM_HORIZONTAL_OFFSET
#define NI_DEC_PARAM_ENABLE_ALL_SEI_PASSTHRU
#define NI_MAX_INTRA_QP_DELTA
struct _niFrameSurface1 niFrameSurface1_t
#define NI_DEC_PARAM_SCALE_1_LONG_SHORT_ADAPT
#define NI_ENC_PARAM_MAX_CONSUTIVE_SKIP_FRAME_NUMBER
#define NI_ENC_GOP_PARAMS_G7_POC_OFFSET
#define NI_MIN_FRAME_SIZE
#define NI_ENC_PARAM_ADAPTIVE_CUTREE
#define NI_DEC_PARAM_DISABLE_ADAPTIVE_BUFFERS
#define NI_MIN_BIN
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC1
#define NI_ENC_PARAM_COLOR_PRIMARY
#define NI_DEC_PARAM_SEMI_PLANAR_1
#define NI_ENC_GOP_PARAMS_G6_PIC_TYPE
@ NI_PIXEL_PLANAR_FORMAT_SEMIPLANAR
@ NI_PIXEL_PLANAR_MAX
@ NI_PIXEL_PLANAR_FORMAT_TILED4X4
@ NI_PIXEL_PLANAR_FORMAT_PLANAR
#define NI_ENC_PARAM_DISABLE_ADAPTIVE_BUFFERS
#define NI_ENC_PARAM_SAR_DENOM
#define NI_ENC_PARAM_ADAPTIVE_LAMDA_MODE
#define NI_VPU_ALIGN16(_x)
#define NI_ENC_PARAM_MOTION_CONSTRAINED_MODE
#define NI_ENC_REPEAT_HEADERS_ALL_I_FRAMES
#define NI_ENC_GOP_PARAMS_G4_QP_OFFSET
#define NI_ENC_GOP_PARAMS_G7_QP_OFFSET
#define NI_DEC_PARAM_ENABLE_OUT_1
#define NI_ENC_PARAM_HVSPLUS_LEVEL
#define NI_MIN_KEEP_ALIVE_TIMEOUT
#define NI_XCODER_LOG_NAME_FULL
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC2_USED
#define NI_ENC_GOP_PARAMS_G2_QP_OFFSET
#define NI_PARAM_AV1_MAX_HEIGHT
#define NI_ENC_PARAM_ALLOCATE_STRAEGY
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC1_USED
#define NI_DEC_PARAM_ENABLE_LOW_DELAY_CHECK
#define NI_XCODER_LOG_NAME_INFO
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC0_USED
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC3
#define NI_SCALER_FLAG_PC
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC2
#define NI_DEC_PARAM_SCALE_2_RES_CEIL
#define NI_PARAM_AV1_MIN_HEIGHT
#define NI_ENC_PARAM_ADAPTIVE_CRF_MODE
#define NI_ENC_PARAM_INTRA_REFRESH_MIN_PERIOD
#define NI_ENC_PARAM_SKIP_FRAME_ENABLE
#define NI_MAX_SEI_DATA
#define NI_VPU_ALIGN128(_x)
#define NI_ENC_PARAM_VBV_MAXRAE
#define NI_ENC_PARAM_ENABLE_MB_LEVEL_RC
#define NI_ENC_PARAM_MIN_QP
#define NI_MAX_RESOLUTION_RGBA_WIDTH
#define NI_DEC_PARAM_FORCE_8BIT_1
#define NI_ENC_PARAM_CBR
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC3
#define NI_VPU_ALIGN32(_x)
#define NI_ENC_PARAM_RECONF_FILE
@ NI_DEVICE_READ_ONLY
@ NI_DEVICE_WRITE_ONLY
@ NI_DEVICE_READ_WRITE
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC2
#define NI_MAX_GOP_NUM
#define NI_ENC_PARAM_LOG_LEVEL
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC3_USED
#define NI_ENC_GOP_PARAMS_G6_TEMPORAL_ID
#define NI_ENC_GOP_PARAMS_G5_TEMPORAL_ID
#define NI_ENC_PARAM_FORCE_BFRAME_QPFACTOR
#define NI_ENC_PARAM_MAX_NUM_MERGE
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC0
#define NI_XCODER_PRESET_NAME_FAST
#define NI_ENC_ENABLE_SSIM
#define NI_CUSTOMIZE_ROI_QP_NUM
Max number of entries per line supported for the qp number.
#define NI_ENC_GOP_PARAMS_G1_QP_OFFSET
#define NI_ENC_PARAM_AV1_OP_LEVEL
#define NI_PARAM_MIN_HEIGHT
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC3
#define NI_DEC_PARAM_SCALE_1
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC1
#define NI_ENC_GOP_PARAMS_G5_POC_OFFSET
#define NI_ENC_PARAM_VBV_BUFFER_SIZE
#define NI_ENC_GOP_PARAMS_G3_POC_OFFSET
#define NI_MIN_GOP_SIZE
#define NI_ENC_GOP_PARAMS_G2_POC_OFFSET
#define NI_ENC_PARAM_BITRATE_WINDOW
#define NI_XCODER_PRESET_NAME_SLOWER
#define NI_ENC_PARAM_ENABLE_CPU_AFFINITY
#define NI_ENC_PARAM_CHROMA_QP_OFFSET
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC0_USED
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC0_USED
#define NI_ENC_GOP_PARAMS_G4_TEMPORAL_ID
#define NI_ENC_GOP_PARAMS_CUSTOM_GOP_SIZE
#define NI_MAX_FRAME_SIZE
#define NI_ENC_GOP_PARAMS_G3_PIC_TYPE
#define NI_DEC_PARAM_MAX_EXTRA_HW_FRAME_CNT
#define NI_ENC_PARAM_PADDING
@ NI_DEC_CROP_MODE_AUTO
@ NI_DEC_CROP_MODE_MANUAL
#define NI_ENC_PARAM_ENABLE_ACQUIRE_LIMIT
#define NI_ENC_RC_QP_DELTA_RANGE
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC1_USED
#define NI_DEC_PARAM_SEMI_PLANAR_2
#define NI_PARAM_AV1_MAX_WIDTH
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC3
#define NI_ENC_PARAM_PRESET
#define NI_EC_POLICY_LIMITED_ERROR
#define NI_ENC_PARAM_ROI_ENABLE
@ NI_XCODER_HWDL_STATE
@ NI_XCODER_IDLE_STATE
@ NI_XCODER_READ_DESC_STATE
@ NI_XCODER_FLUSH_STATE
@ NI_XCODER_GENERAL_STATE
@ NI_XCODER_READ_STATE
@ NI_XCODER_CLOSE_STATE
@ NI_XCODER_HWUP_STATE
@ NI_XCODER_OPEN_STATE
@ NI_XCODER_WRITE_STATE
@ NI_FRAME_AUX_DATA_BITRATE
@ NI_FRAME_AUX_DATA_SLICE_ARG
@ NI_FRAME_AUX_DATA_CRF_FLOAT
@ NI_FRAME_AUX_DATA_MAX_MIN_QP
@ NI_FRAME_AUX_DATA_FRAMERATE
@ NI_FRAME_AUX_DATA_LTR_INTERVAL
@ NI_FRAME_AUX_DATA_VBV_MAX_RATE
@ NI_FRAME_AUX_DATA_INTRAPRD
@ NI_FRAME_AUX_DATA_CRF
@ NI_FRAME_AUX_DATA_MAX_FRAME_SIZE
@ NI_FRAME_AUX_DATA_VUI
@ NI_FRAME_AUX_DATA_INVALID_REF_FRAME
@ NI_FRAME_AUX_DATA_LONG_TERM_REF
@ NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE
#define NI_MAX_RESOLUTION_WIDTH
#define NI_DEC_PARAM_ENABLE_CUSTOM_SEI_PASSTHRU
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC2_USED
#define NI_ENC_PARAM_IP_RATIO
#define NI_DEC_PARAM_CROP_PARAM_2
#define NI_EC_POLICY_TOLERANT
#define NI_MAX_BIN
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC3_USED
#define NI_FRAME_LITTLE_ENDIAN
#define NI_ENC_PARAM_ENABLE_AUD
#define NI_ENC_PARAM_INTRA_REFRESH_ARG
#define NI_ENC_PARAM_DISABLE_BFRAME_RDOQ
#define NI_ENC_PARAM_HVS_QP_SCALE
#define NI_ENC_PARAM_GDR_DURATION
#define NI_EC_ERR_THRESHOLD_DEFAULT
#define NI_ENC_PARAM_CONSTANT_RATE_FACTOR
#define NI_ENC_PARAM_NO_HW_MULTIPASS_SUPPORT
#define NI_MAX_DECODING_REFRESH_TYPE
#define NI_ENC_PARAM_FORCE_FRAME_TYPE
#define NI_ENC_PARAM_JPEG_QLEVEL
#define NI_MIN_CUSTOM_SEI_PASSTHRU
@ QOS_OP_CONFIG_CODE
@ QOS_OP_CONFIG_REC_OP_CODE
@ QOS_NAMESPACE_CODE
#define NI_ENC_GOP_PARAMS_G6_POC_OFFSET
union _ni_enc_hevc_roi_custom_map ni_enc_hevc_roi_custom_map_t
encoder HEVC ROI custom map (1 CTU = 64bits)
#define NI_ENC_PARAM_HVS_BASE_MB_COMPLEXITY
#define NI_ENC_PARAM_TRANS_RATE
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PICS
#define NI_ENC_PARAM_ENABLE_DYNAMIC_32X32_MERGE
#define NI_ENC_GOP_PARAMS_G0_PIC_TYPE
#define NI_ENC_PARAM_ENABLE_HVS_QP
#define NI_DEC_PARAM_SCALE_1_RES_CEIL
#define NI_MIN_BITRATE
#define NI_ENC_PARAM_ENABLE_TIMECODE
#define NI_ENC_PARAM_ENTROPY_CODING_MODE
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC3
#define NI_MAX_MAX_NUM_MERGE
#define NI_ENC_GOP_PARAMS_G7_TEMPORAL_ID
#define NI_ENC_PARAM_INTRA_QP
#define NI_ENC_PARAM_SLICE_MODE
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC0_USED
#define NI_MAX_BITRATE
#define NI_DEC_PARAM_FORCE_8BIT_2
#define NI_MAX_HEIGHT
#define NI_DISABLE_USR_DATA_SEI_PASSTHRU
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC0
#define NI_ENC_PARAM_ENABLE_DYNAMIC_8X8_MERGE
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC2_USED
#define NI_ENC_REPEAT_HEADERS_FIRST_IDR
#define NI_ENC_PARAM_RECONF_DEMO_MODE
#define NI_ENC_GOP_PARAMS_G0_QP_OFFSET
#define NI_ENC_PARAM_STILL_IMAGE_DETECT_LEVEL
#define NI_PARAM_AV1_ALIGN_WIDTH_HEIGHT
#define NI_XCODER_PRESET_NAME_SLOW
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC1
#define NI_ENC_NEW_RC_ENABLE
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC2
#define NI_EC_POLICY_IGNORE
#define NI_DEC_PARAM_ENABLE_ADVANCED_EC
#define NI_ENC_PARAM_BASE_LAYER_ONLY
#define NI_DEC_PARAM_ENABLE_OUT_2
#define NI_ENC_PARAM_CRF_MAX_IFRAME_ENABLE
#define NI_UPLOADER_FLAG_LM
#define NI_PARAM_AV1_MAX_AREA
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC1
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC1_USED
#define NI_ENC_PARAM_MAX_FRAME_SIZE_BYTES_LOW_DELAY
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC3_USED
#define NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL
Max number of lines supported for qpoffset level.
#define NI_INVALID_SESSION_ID
enum _ni_frame_aux_data_type ni_aux_data_type_t
#define NI_DEC_PARAM_EC_POLICY
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC1_USED
#define NI_ENC_PARAM_FRAME_RATE_DENOM
#define NI_ENC_PARAM_MAX_QP
#define NI_ENC_PARAM_ENABLE_VFR
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC3_USED
struct _ni_scaler_multi_watermark_params_t ni_scaler_multi_watermark_params_t
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC3_USED
#define NI_DEC_PARAM_ERROR_THRESHOLD
#define NI_ENC_PARAM_ENABLE_HVS_QP_SCALE
#define NI_ENC_GOP_PARAMS_G6_QP_OFFSET
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC0_USED
#define NI_MAX_RESOLUTION_AREA
#define NI_VPU_ALIGN4096(_x)
#define NI_ENC_PARAM_AI_ENHANCE_LEVEL
#define NI_ENC_PARAM_CACHE_ROI
#define NI_ENC_PARAM_AV1_ERROR_RESILIENT_MODE
#define NI_SCALER_FLAG_P2
#define NI_ENC_PARAM_ENABLE_AI_ENHANCE
#define NI_MAX_CUSTOM_SEI_PASSTHRU
enum _ni_codec_format ni_codec_format_t
This is an enumeration for supported codec formats.
#define NI_ENC_PARAM_GOP_LOW_DELAY
#define NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC2_USED
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC0
#define NI_ENC_PARAM_LOW_DELAY
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC2
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PICS
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC0
#define NI_ENC_PARAM_PAST_FRAME_MAX_INTRA_RATIO
#define NI_ENC_PARAM_BITRATE_MODE
#define NI_ENC_PARAM_ENABLE_8X8_TRANSFORM
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PICS
#define NI_XCODER_LOG_NAME_NONE
#define NI_ENC_PARAM_CONF_WIN_TOP
#define NI_ENC_PARAM_TOL_RC_INTER
#define NI_ENC_PARAM_MAX_FRAME_SIZE_LOW_DELAY
#define NI_ENC_PARAM_ENABLE_IP_RATIO
#define NI_MAX_DYNAMIC_MERGE
#define NI_ENC_BLOCK_RC_SIZE
#define NI_DEC_PARAM_CROP_PARAM_0
#define NI_NUM_OF_PIXELS_1080P
#define NI_DEC_PARAM_SCALE_2
#define NI_ENC_PARAM_ENABLE_ALL_SEI_PASSTHRU
#define NI_ENC_PARAM_ENABLE_AI_HVSPLUS
#define NI_ENC_PARAM_VBV_BUFFER_REENCODE
#define NI_DEC_PARAM_SVC_T_DECODING_LAYER
#define NI_MIN_GOP_PRESET_IDX
#define NI_DEC_PARAM_LOW_DELAY
#define NI_DEC_PARAM_FORCE_LOW_DELAY
#define NI_DEC_PARAM_DDR_PRIORITY_MODE
#define NI_ENC_PARAM_NO_MBTREE
#define NI_ENC_PARAM_LEVEL
@ NI_DDR_PRIORITY_NONE
@ NI_DDR_PRIORITY_MAX
#define NI_DEC_PARAM_MULTICORE_JOINT_MODE
#define NI_ENC_GOP_PARAMS_G7_PIC_TYPE
#define NI_ENC_GOP_PARAMS_G1_POC_OFFSET
#define NI_ENC_PARAM_COLOR_SPACE
#define NI_MIN_INTRA_QP_DELTA
#define NI_ENC_CTB_ROW_QP_STEP
#define MAX_CHAR_IN_DEVICE_NAME
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC3_USED
#define NI_ENC_GOP_PARAMS_G3_QP_OFFSET
#define NI_ENC_PARAM_VBV_MINRATE
#define NI_ENC_PARAM_CU_SIZE_MODE
#define NI_ENC_PARAM_TOL_RC_INTRA
#define NI_ENC_GOP_PARAMS_G1_PIC_TYPE
#define NI_ENC_PARAM_STATISTIC_OUTPUT_LEVEL
#define NI_ENC_PARAM_USE_LOW_DELAY_POC_TYPE
#define NI_MIN_DECODING_REFRESH_TYPE
#define NI_DEC_PARAM_PKT_PTS_UNCHANGE
#define NI_ENC_PARAM_INTRA_REFRESH_RESET
#define NI_ENC_PARAM_LONG_TERM_REFERENCE_INTERVAL
#define NI_ENC_PARAM_SPATIAL_LAYERS
#define NI_EC_POLICY_BEST_EFFORT_OUT_DC
#define NI_MAX_QP_INFO
#define NI_ENC_PARAM_PB_RATIO
#define NI_DEC_PARAM_CROP_MODE_2
#define NI_ENC_GOP_PARAMS_G0_TEMPORAL_ID
#define NI_ENC_PARAM_SPATIAL_LAYER_BITRATE
#define NI_ENC_PARAM_ENABLE_DYNAMIC_16X16_MERGE
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC1_USED
#define NI_ENC_PARAM_CROP_WIDTH
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC1
#define NI_ENC_GOP_PARAMS_G1_NUM_REF_PICS
#define NI_ENC_PARAM_CROP_HEIGHT
#define NI_MIN_RESOLUTION_WIDTH_SCALER
#define NI_MAX_FRAMERATE
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC0
#define NI_ENC_PARAM_GET_PSNR_MODE
#define NI_XCODER_PRESET_NAME_FASTER
#define NI_ENC_PARAM_RDO_LEVEL
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PICS
#define NI_EC_POLICY_SKIP
#define NI_ENC_PARAM_CTB_RC_MODE
#define NI_MAX_SPATIAL_LAYERS
#define NI_ENC_PARAM_TOTAL_CUTREE_DEPTH
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC0_USED
#define NI_ENC_PARAM_LOOK_AHEAD_DEPTH
#define NI_ENC_PARAM_SLICE_ARG
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC2_USED
#define NI_ENC_PARAM_BITRATE
@ NI_CODEC_HW_DOWNLOAD
#define NI_ENC_GOP_PARAMS_G0_POC_OFFSET
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC3
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC0_USED
@ NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_AV1
@ NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_JPEG
#define NI_ENC_PARAM_CONF_WIN_BOTTOM
ni_pix_fmt_t
@ NI_PIX_FMT_ARGB
@ NI_PIX_FMT_P010LE
@ NI_PIX_FMT_YUV420P
@ NI_PIX_FMT_ABGR
@ NI_PIX_FMT_BGRP
@ NI_PIX_FMT_BGR0
@ NI_PIX_FMT_YUYV422
@ NI_PIX_FMT_RGBA
@ NI_PIX_FMT_NV12
@ NI_PIX_FMT_BGRA
@ NI_PIX_FMT_NV16
@ NI_PIX_FMT_UYVY422
@ NI_PIX_FMT_YUV420P10LE
#define NI_ENC_GOP_PARAMS_G2_PIC_TYPE
#define NI_ENC_PARAM_LINK_FRAME_MAX_INTRA_RATIO
#define NI_ENC_PARAM_INTRA_QP_DELTA
#define NI_DEC_PARAM_CROP_MODE_1
#define NI_ENC_GOP_PARAMS_G4_POC_OFFSET
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC3_USED
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC2_USED
#define NI_ENC_PARAM_SAR_NUM
#define NI_XCODER_PRESET_NAME_VERYFAST
#define NI_ENC_PARAM_GEN_HDRS
#define NI_ENC_PARAM_INTRA_MB_REFRESH_ARG
#define NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC1
#define NI_DEC_PARAM_REDUCE_DPB_DELAY
#define NI_ENC_PARAM_IFRAME_SIZE_RATIO
#define NI_ENC_PARAM_MASTER_DISPLAY
#define NI_ENC_PARAM_PRE_INTRA_HANDLING
#define NI_ENC_PARAM_LONG_TERM_REFERENCE_COUNT
#define NI_MAX_ASPECTRATIO
#define NI_ENC_PARAM_SPATIAL_LAYERS_REF_BASE_LAYER
#define NI_ENC_PARAM_ENABLE_PIC_SKIP
#define NI_MAX_KEEP_ALIVE_TIMEOUT
#define NI_DEC_PARAM_FORCE_8BIT_0
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PICS
#define NI_ENC_PARAM_SCENE_CHANG_DETECT_LEVEL
#define NI_PARAM_MAX_WIDTH
#define NI_BITRATE_RECONFIG_FILE_MAX_ENTRIES_PER_LINE
@ PIC_TYPE_IDR
@ PIC_TYPE_I
#define NI_DEFAULT_KEEP_ALIVE_TIMEOUT
#define NI_ENC_PARAM_ZEROCOPY_MODE
#define NI_ENC_PARAM_COLOR_TRANSFER_CHARACTERISTIC
#define NI_ENC_PARAM_LTR_REF_QPOFFSET
#define NI_KEEP_ALIVE_TIMEOUT
#define NI_MAX_CU_SIZE_MODE
#define NI_ENABLE_USR_DATA_SEI_PASSTHRU
#define NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC1
#define NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC2
#define NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC2
#define NI_DEC_PARAM_SAVE_PKT
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC3
#define NI_DEC_PARAM_SCALE_2_ROUND
#define NI_SCALER_FLAG_IO
@ NI_ENC_MEM_ALLOCATE_STRATEGY_INVALID_MAX
@ NI_ENC_MEM_ALLOCATE_STRATEGY_INVALID_MIN
#define NI_DEC_PARAM_SEMI_PLANAR_0
#define NI_DEC_PARAM_SCALE_2_LONG_SHORT_ADAPT
#define NI_XCODER_PRESET_NAMES_ARRAY_LEN
@ NI_PRESETS_NONE
@ NI_NUM_PRESETS_MAX
#define NI_MAX_NUM_AUX_DATA_PER_FRAME
#define NI_ENC_GOP_PARAMS_G1_TEMPORAL_ID
#define NI_EC_POLICY_DEFAULT
#define NI_XCODER_PRESET_NAME_VERYSLOW
#define NI_ENC_PARAM_LONG_TERM_REFERENCE_ENABLE
@ NI_CUS_ROI_MERGE
@ NI_CUS_ROI_DISABLE
#define NI_MAX_RESOLUTION_HEIGHT
#define NI_EC_POLICY_BEST_EFFORT
enum _ni_device_mode ni_device_mode_t
Device access mode enumeration.
#define NI_ENC_PARAM_INTRA_COMPENSATE_MODE
#define NI_ENC_PARAM_PROFILE
#define NI_ENC_PARAM_CU_TREE_FACTOR
#define NI_DEC_PARAM_ENABLE_USR_DATA_SEI_PASSTHRU
#define NI_ENC_PARAM_ENABLE_FILLER
#define NI_VPU_ALIGN64(_x)
#define NI_BEST_REAL_LOAD_STR
#define NI_ENC_PARAM_LTR_FIRST_GAP
#define NI_ENC_PARAM_INTRA_MB_REFRESH_MODE
#define NI_MAX_INTRA_QP
#define NI_DEC_PARAM_MIN_PACKETS_DELAY
#define NI_MAX_REF_PIC
#define NI_ENC_GOP_PARAMS_G4_PIC_TYPE
#define NI_ENC_PARAM_FRAME_RATE
#define NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC3
#define NI_ENC_GOP_PARAMS_G5_QP_OFFSET
#define NI_DEC_PARAM_SKIP_PTS_GUESS
#define NI_XCODER_LOG_NAME_DEBUG
#define NI_ENC_PARAM_GET_RECONSTRUCTED_MODE
#define NI_ENC_PARAM_ENABLE_COMPENSATE_QP
#define NI_ENC_GOP_PARAMS_G2_TEMPORAL_ID
#define NI_ENC_PARAM_DDR_PRIORITY_MODE
#define NI_MAX_GOP_SIZE
#define NI_MIN_USE_RECOMMENDED_ENC_PARAMS
#define NI_DEC_PARAM_CROP_MODE_0
#define NI_DEC_PARAM_ENABLE_PPU_SCALE_LIMIT
#define NI_ENC_PARAM_FORCE_PIC_QP_DEMO_MODE
#define NI_ENC_PARAM_CUSTOM_MIN_COEFF_DIV
#define NI_DEC_PARAM_SCALE_0_ROUND
#define NI_ENC_INLOOP_DS_RATIO
#define NI_ENC_PARAM_HIGH_TIER
#define NI_VPU_ALIGN8(_x)
#define NI_XCODER_LOG_NAME_ERROR
#define NI_ENC_PARAM_INTRA_PERIOD
#define NI_ENC_PARAM_HRD_ENABLE
#define NI_INVALID_SVCT_DECODING_LAYER
#define NI_DEC_PARAM_SURVIVE_STREAM_ERR
#define NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC2_USED
#define NI_DEC_PARAM_SKIP_EXTRA_HEADERS
#define NI_ENC_PARAM_CONSTANT_RATE_FACTOR_FLOAT
#define NI_MAX_GOP_PRESET_IDX
#define NI_ENC_PARAM_MAX_CLL
#define NI_ENC_PARAM_AVCC_HVCC
#define NI_ENC_PARAM_RC_INIT_DELAY
#define NI_VPU_CEIL(_data, _align)
#define NI_ENC_PARAM_ENABLE_SMOOTH_CRF
#define NI_ENC_PARAM_CUSTOMIZE_ROI_QP_LEVEL
#define NI_ENC_PARAM_PPS_INIT_QP
#define NI_ENC_PARAM_SKIP_FRAME_INTERVAL
ni_retcode_t ni_encoder_session_open(ni_session_context_t *p_ctx)
Open a xcoder encoder instance.
ni_retcode_t ni_ai_alloc_hwframe(ni_session_context_t *p_ctx, int width, int height, int options, int pool_size, int frame_index)
ni_retcode_t ni_config_instance_set_decoder_ppu_params(ni_session_context_t *p_ctx, void *p_dec_ppu_config, int buffer_size)
Send a p_config command to configure decoding parameters.
ni_retcode_t ni_get_memory_offset(ni_session_context_t *p_ctx, const niFrameSurface1_t *hwdesc, uint32_t *p_offset)
Get an address offset from a hw descriptor.
ni_retcode_t ni_scaler_config_frame(ni_session_context_t *p_ctx, ni_frame_config_t *p_cfg)
config a frame in the scaler
ni_retcode_t ni_scaler_multi_config_frame(ni_session_context_t *p_ctx, ni_frame_config_t p_cfg_in[], int numInCfgs, ni_frame_config_t *p_cfg_out)
config multiple frames in the scaler
ni_retcode_t ni_decoder_session_copy_internal(ni_session_context_t *src_p_ctx, ni_session_context_t *dst_p_ctx)
Copy a xcoder decoder worker thread info.
int ni_hwupload_session_write(ni_session_context_t *p_ctx, ni_frame_t *p_frame, niFrameSurface1_t *hwdesc)
Send a YUV p_frame to upload session.
ni_retcode_t ni_encoder_session_sequence_change(ni_session_context_t *p_ctx, ni_resolution_t *p_resolution)
Send sequnce change to a xcoder encoder instance.
int ni_decoder_session_write(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
Send a video p_packet to decoder.
ni_retcode_t ni_decoder_session_close(ni_session_context_t *p_ctx, int eos_recieved)
Close a xcoder decoder instance.
void ni_populate_device_capability_struct(ni_device_capability_t *p_cap, void *p_data, ni_device_handle_t device_handle, bool device_in_ctxt)
Get info from received xcoder capability.
ni_retcode_t ni_hwupload_session_query_buffer_avail(ni_session_context_t *p_ctx)
Query and acquire buffer from xcoder upload instance.
ni_retcode_t ni_scaler_session_close(ni_session_context_t *p_ctx, int eos_received)
close a scaler session
ni_retcode_t ni_ai_session_write(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
ni_retcode_t ni_config_instance_hvsplus(ni_session_context_t *p_ctx)
ni_retcode_t ni_scaler_session_query_buffer_avail(ni_session_context_t *p_ctx)
Query and acquire buffer from xcoder scaler instance.
ni_retcode_t ni_encoder_session_close(ni_session_context_t *p_ctx, int eos_recieved)
Close a xcoder encoder instance.
ni_retcode_t ni_ai_session_query_metrics(ni_session_context_t *p_ctx, ni_network_perf_metrics_t *p_metrics)
ni_retcode_t ni_encoder_session_send_eos(ni_session_context_t *p_ctx)
Flush encoder output.
ni_retcode_t ni_config_read_inout_layers(ni_session_context_t *p_ctx, ni_network_data_t *p_network)
int ni_decoder_session_read(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
Retrieve a YUV p_frame from decoder.
ni_retcode_t ni_encoder_metadata_buffer_alloc(ni_frame_t *p_frame, int extra_len)
Allocate memory for the metadata header and auxillary data for encoder input data.
ni_retcode_t ni_ai_session_read(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
ni_retcode_t ni_hwframe_clone(ni_session_context_t *p_ctx, ni_frameclone_desc_t *p_frameclone_desc)
Copy a src hw frame to a dst hw frame.
int ni_xcoder_session_query_detail(ni_session_context_t *p_ctx, ni_device_type_t device_type, void *detail_data, int ver)
Query current xcoder status.
ni_retcode_t ni_ai_alloc_dst_frame(ni_session_context_t *p_ctx, niFrameSurface1_t *p_out_surface)
ni_retcode_t ni_config_instance_set_uploader_params(ni_session_context_t *p_ctx, uint32_t pool_size, uint32_t pool)
Send a p_config command to configure uploading parameters.
ni_retcode_t ni_decoder_session_open(ni_session_context_t *p_ctx)
Open a xcoder decoder instance.
ni_retcode_t ni_encoder_start_buffer_alloc(ni_frame_t *p_frame)
Allocate memory for the non-4k-aligned part at the start of YUV data for encoder input data.
ni_retcode_t ni_scaler_session_read_hwdesc(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
read a hardware descriptor from a scaler session
ni_retcode_t ni_uploader_session_close(ni_session_context_t *p_ctx)
Close an xcoder upload instance.
ni_retcode_t ni_scaler_alloc_frame(ni_session_context_t *p_ctx, int width, int height, int format, int options, int rectangle_width, int rectangle_height, int rectangle_x, int rectangle_y, int rgba_color, int frame_index)
allocate a frame in the scaler
ni_retcode_t ni_decoder_session_read_desc(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
Retrieve a hw desc p_frame from decoder.
void * ni_session_keep_alive_thread(void *arguments)
decoder keep alive thread function triggers every 1 second
ni_retcode_t ni_recv_from_target(ni_session_context_t *p_ctx, const ni_p2p_sgl_t *dmaAddrs, ni_frame_t *pDstFrame)
ni_retcode_t ni_device_config_ns_qos(ni_device_handle_t device_handle, uint32_t key, uint32_t value)
Send namespace num / Opmode and SRIOv index/value to the device with specified logic block address.
ni_retcode_t ni_config_instance_network_binary(ni_session_context_t *p_ctx, void *nb_data, uint32_t nb_size)
int ni_hwupload_session_read_hwdesc(ni_session_context_t *p_ctx, niFrameSurface1_t *hwdesc)
Retrieve a HW descriptor of uploaded frame.
int ni_xcoder_session_query(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Query current xcoder status.
ni_retcode_t ni_config_instance_set_scaler_params(ni_session_context_t *p_ctx, ni_scaler_params_t *p_params)
Send a p_config command to configure scaling parameters.
ni_retcode_t ni_device_get_ddr_configuration(ni_session_context_t *p_ctx)
Get DDR configuration of Quadra device.
ni_retcode_t ni_ai_session_read_hwdesc(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
read a hardware descriptor from a scaler session
ni_retcode_t ni_send_to_target(ni_session_context_t *p_ctx, niFrameSurface1_t *source, uint64_t ui64DestAddr, uint32_t ui32FrameSize)
ni_retcode_t ni_decoder_session_send_eos(ni_session_context_t *p_ctx)
Send end of stream signal to the decoder.
int ni_encoder_session_read(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
ni_retcode_t ni_uploader_session_open(ni_session_context_t *p_ctx)
Open a xcoder upload instance.
ni_retcode_t ni_ai_session_open(ni_session_context_t *p_ctx)
ni_retcode_t ni_clear_instance_buf(niFrameSurface1_t *surface)
clear a particular xcoder instance buffer/data
ni_retcode_t ni_ai_multi_config_frame(ni_session_context_t *p_ctx, ni_frame_config_t p_cfg_in[], int numInCfgs, ni_frame_config_t *p_cfg_out)
ni_retcode_t ni_ai_session_close(ni_session_context_t *p_ctx, int eos_recieved)
int lower_pixel_rate(const ni_load_query_t *pQuery, uint32_t ui32CurrentLowest)
int ni_hwdownload_session_read(ni_session_context_t *p_ctx, ni_frame_t *p_frame, niFrameSurface1_t *hwdesc)
Retrieve a YUV p_frame from decoder.
ni_retcode_t ni_decoder_session_flush(ni_session_context_t *p_ctx)
Flush decoder output.
ni_retcode_t ni_dump_log_all_cores(ni_session_context_t *p_ctx, void *p_data, bool gen_log_file)
int ni_scaler_session_open(ni_session_context_t *p_ctx)
Open a xcoder scaler instance.
int ni_encoder_session_write(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
Send a YUV p_frame to encoder.
int ni_hwdownload_by_frame_idx(niFrameSurface1_t *hwdesc, ni_frame_t *p_frame, int is_auto_dl)
Retrieve a YUV p_frame by frame index.
Private definitions used by ni_device_api.c for video processing tasks.
struct _ni_log_fl_fw_versions ni_log_fl_fw_versions_t
@ GOP_PRESET_IDX_NONE
@ GOP_PRESET_IDX_IBBBP
struct _ni_instance_mgr_general_status ni_instance_mgr_general_status_t
#define NI_AI_HW_ALIGN_SIZE
#define NI_VERSION_CHARACTER_COUNT
ni_lat_meas_q_t * ni_lat_meas_q_create(int capacity)
Create a latency measurement queue object of a given capacity.
Definition ni_lat_meas.c:52
void ni_lat_meas_q_destroy(ni_lat_meas_q_t *frame_time_q)
Destroy a latency measurement queue object.
Definition ni_lat_meas.c:97
Utility definitions for measuring frame/packet processing time in NETINT video processing devices.
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
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition ni_log.c:183
#define NI_ERRNO_LEN
Definition ni_log.h:51
@ NI_LOG_DEBUG
Definition ni_log.h:64
@ NI_LOG_TRACE
Definition ni_log.h:65
@ NI_LOG_ERROR
Definition ni_log.h:62
@ NI_LOG_INFO
Definition ni_log.h:63
int32_t ni_nvme_send_read_cmd(ni_device_handle_t handle, ni_event_handle_t event_handle, void *p_data, uint32_t data_len, uint32_t lba)
Compose an io read command.
Definition ni_nvme.c:554
int32_t ni_nvme_send_write_cmd(ni_device_handle_t handle, ni_event_handle_t event_handle, void *p_data, uint32_t data_len, uint32_t lba)
Compose a io write command.
Definition ni_nvme.c:660
Private definitions for interfacing with NETINT video processing devices over NVMe.
#define QUERY_GET_NVME_STATUS_R
Definition ni_nvme.h:790
#define QUERY_GET_EXTTRA_INFO_R
Definition ni_nvme.h:799
#define CONFIG_INSTANCE_SetScalerDrawBoxPara_W(sid, instance)
Definition ni_nvme.h:825
#define QUERY_GET_NS_VF_R
Definition ni_nvme.h:795
#define QUERY_GET_TEMPERATURE_R
Definition ni_nvme.h:797
#define IDENTIFY_DEVICE_R
Definition ni_nvme.h:687
#define QUERY_GET_VERSIONS_R
Definition ni_nvme.h:792
#define NI_DATA_BUFFER_LEN
Definition ni_nvme.h:624
#define NI_NVME_IDENTITY_CMD_DATA_SZ
Definition ni_nvme.h:38
#define CONFIG_INSTANCE_SetScalerWatermarkPara_W(sid, instance)
Definition ni_nvme.h:831
Definitions related to NETINT P2P kernel driver interface.
#define NETINT_IOCTL_ATTACH_RFENCE
#define NETINT_IOCTL_EXPORT_DMABUF
@ NI_DMABUF_WRITE_TO_DEVICE
#define NETINT_IOCTL_SIGNAL_RFENCE
#define NETINT_IOCTL_ISSUE_REQ
int ni_rsrc_unlock(int device_type, ni_lock_handle_t lock)
unlock a file lock
NI_DEPRECATED bool g_device_in_ctxt
ni_device_context_t * ni_rsrc_allocate_simple_direct(ni_device_type_t device_type, int guid)
Allocate resources for decoding/encoding, by designating explicitly the device to use....
int ni_rsrc_lock_and_open(int device_type, ni_lock_handle_t *lock)
lock a file lock and open a session on a device
void ni_rsrc_free_device_context(ni_device_context_t *p_device_context)
Free previously allocated device context.
int ni_rsrc_get_device_by_block_name(const char *blk_name, ni_device_type_t device_type)
Get GUID of the device by block device name and type.
void ni_rsrc_free_device_pool(ni_device_pool_t *p_device_pool)
Free all resources taken by the device pool.
NI_DEPRECATED ni_device_handle_t g_dev_handle
Public definitions for managing NETINT video processing devices.
struct _ni_device_extra_info ni_device_extra_info_t
struct _ni_device_vf_ns_id ni_device_vf_ns_id_t
LIB_API ni_device_context_t * ni_rsrc_get_device_context(ni_device_type_t type, int guid)
Allocates and returns a pointer to ni_device_context_t struct based on provided device_type and guid....
struct _ni_device_temp ni_device_temp_t
LIB_API ni_device_pool_t * ni_rsrc_get_device_pool(void)
Create and return the allocated ni_device_pool_t struct.
Private definitions used by ni_rsrc_api.cpp for management of NETINT video processing devices.
void ni_rsrc_update_record(ni_device_context_t *p_device_context, ni_session_context_t *p_session_ctx)
int ni_pthread_cond_init(ni_pthread_cond_t *cond, const ni_pthread_condattr_t *attr)
initialize condition variables
Definition ni_util.c:4806
int ni_pthread_mutex_lock(ni_pthread_mutex_t *mutex)
thread mutex lock
Definition ni_util.c:4686
int ni_pthread_cond_destroy(ni_pthread_cond_t *cond)
destroy condition variables
Definition ni_util.c:4825
int32_t ni_parse_name(const char *arg, const char *const *names, bool *b_error)
Parse name.
Definition ni_util.c:2594
ni_retcode_t ni_strncpy(char *dest, size_t dmax, const char *src, size_t slen)
Definition ni_util.c:518
int ni_posix_memalign(void **memptr, size_t alignment, size_t size)
Allocate aligned memory.
Definition ni_util.c:202
int ni_pthread_create(ni_pthread_t *thread, const ni_pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
create a new thread
Definition ni_util.c:4750
ni_retcode_t ni_strncat(char *dest, size_t dmax, const char *src, size_t slen)
Definition ni_util.c:807
ni_buf_t * ni_buf_pool_get_buffer(ni_buf_pool_t *p_buffer_pool)
Definition ni_util.c:1091
ni_retcode_t ni_strerror(char *dest, size_t dmax, int errnum)
Definition ni_util.c:656
int ni_pthread_mutex_destroy(ni_pthread_mutex_t *mutex)
destory a mutex
Definition ni_util.c:4668
ni_retcode_t ni_strcat(char *dest, size_t dmax, const char *src)
Definition ni_util.c:689
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:2664
char * ni_strtok(char *s, const char *delim, char **saveptr)
Definition ni_util.c:424
ni_retcode_t ni_fopen(FILE **fp, const char *filename, const char *mode)
Definition ni_util.c:983
ni_retcode_t ni_strcpy(char *dest, size_t dmax, const char *src)
Definition ni_util.c:453
uint32_t ni_ai_network_layer_size(ni_network_layer_params_t *p_param)
Definition ni_util.c:3989
void ni_usleep(int64_t usec)
Definition ni_util.c:362
void ni_buf_pool_return_buffer(ni_buf_t *buf, ni_buf_pool_t *p_buffer_pool)
Definition ni_util.c:1152
uint64_t ni_gettime_ns(void)
Definition ni_util.c:2622
int ni_pthread_join(ni_pthread_t thread, void **value_ptr)
join with a terminated thread
Definition ni_util.c:4777
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 ...
Definition ni_util.c:2716
int ni_pthread_mutex_unlock(ni_pthread_mutex_t *mutex)
thread mutex unlock
Definition ni_util.c:4712
int ni_sprintf(char *dest, size_t dmax, const char *fmt,...)
Definition ni_util.c:1063
int ni_pthread_mutex_init(ni_pthread_mutex_t *mutex)
initialize a mutex
Definition ni_util.c:4630
uint32_t ni_decode_power_measurement(uint32_t current_data, const uint8_t *serial_number)
decode the raw current obtained and determine power
Definition ni_util.c:5013
int ni_cmp_fw_api_ver(const char ver1[], const char ver2[])
Compare two 3 character strings containing a FW API version. Handle comparision when FW API version f...
Definition ni_util.c:4302
Utility definitions.
#define NI_INVALID_POWER
Definition ni_util.h:44
#define ni_aligned_free(p_memptr)
Definition ni_util.h:400
#define ni_memfree(p_memptr)
Definition ni_util.h:410
ni_aux_data_type_t type
struct _ni_buf_pool_t * pool
ni_gop_params_t pic_param[NI_MAX_GOP_NUM]
char cr_expr[NI_MAX_NUM_OF_DECODER_OUTPUTS][4][NI_MAX_PPU_PARAM_EXPR_CHAR+1]
int scale_wh[NI_MAX_NUM_OF_DECODER_OUTPUTS][2]
int scale_resolution_ceil[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int semi_planar[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int scale_round[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int scale_long_short_edge[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int force_8_bit[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int crop_mode[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int crop_whxy[NI_MAX_NUM_OF_DECODER_OUTPUTS][4]
char sc_expr[NI_MAX_NUM_OF_DECODER_OUTPUTS][2][NI_MAX_PPU_PARAM_EXPR_CHAR+1]
device capability type
ni_device_info_t * p_device_info
char dev_name[NI_MAX_DEVICE_NAME_LEN]
uint8_t fw_rev[8]
char blk_name[NI_MAX_DEVICE_NAME_LEN]
uint8_t fl_ver_last_ran[8]
uint8_t fw_rev_nor_flash[8]
uint32_t active_num_inst
uint8_t fl_ver_nor_flash[8]
ni_device_queue_t * p_device_queue
Definition ni_rsrc_api.h:99
int32_t xcoders[NI_DEVICE_TYPE_XCODER_MAX][NI_MAX_DEVICE_CNT]
Definition ni_rsrc_api.h:70
uint32_t xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
Definition ni_rsrc_api.h:69
int32_t composite_temp
int32_t on_board_temp
int32_t on_die_temp
ni_custom_gop_params_t custom_gop_params
struct _ni_encoder_cfg_params::@16 rc
int spatialLayerBitrate[NI_MAX_SPATIAL_LAYERS]
int av1OpLevel[NI_MAX_SPATIAL_LAYERS]
This is a data structure for encoding parameters that have changed.
uint8_t inconsecutive_transfer
uint32_t data_len[NI_MAX_NUM_DATA_POINTERS]
uint8_t * p_buffer
ni_codec_format_t src_codec
ni_iovec_t * iovec
uint32_t start_len[NI_MAX_NUM_DATA_POINTERS]
uint32_t start_buffer_size
uint8_t separate_metadata
ni_buf_t * dec_buf
uint32_t metadata_buffer_size
uint32_t video_width
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
uint32_t total_start_len
uint8_t * p_start_buffer
uint32_t buffer_size
uint8_t separate_start
ni_pic_type_t ni_pict_type
uint16_t hor_adjust_offset
uint32_t iovec_num
ni_aux_data_t * aux_data[NI_MAX_NUM_AUX_DATA_PER_FRAME]
uint8_t * p_metadata_buffer
uint32_t video_height
int32_t framerate_denom
int32_t framerate_num
ni_gop_rps_t rps[NI_MAX_REF_PIC]
uint32_t fw_share_mem_usage
uint32_t total_pixel_load
uint32_t pcie_throughput
uint8_t nor_flash_fw_revision[NI_VERSION_CHARACTER_COUNT]
uint8_t last_ran_fl_version[NI_VERSION_CHARACTER_COUNT]
uint8_t nor_flash_fl_version[NI_VERSION_CHARACTER_COUNT]
uint8_t use_cur_src_as_long_term_pic
ni_network_layer_offset_t * inset
ni_network_layer_info_t linfo
ni_network_layer_offset_t * outset
ni_network_layer_params_t * in_param
ni_network_layer_params_t * out_param
uint32_t data_len
uint32_t av1_data_len[MAX_AV1_ENCODER_GOP_NUM]
uint8_t * av1_p_buffer[MAX_AV1_ENCODER_GOP_NUM]
uint32_t buffer_size
uint8_t * av1_p_data[MAX_AV1_ENCODER_GOP_NUM]
uint32_t av1_buffer_size[MAX_AV1_ENCODER_GOP_NUM]
uint16_t ppu_h[NI_MAX_NUM_OF_DECODER_OUTPUTS]
uint16_t ppu_w[NI_MAX_NUM_OF_DECODER_OUTPUTS]
char blk_xcoder_name[MAX_CHAR_IN_DEVICE_NAME]
ni_pthread_mutex_t mutex
ni_pthread_cond_t low_delay_sync_cond
ni_event_handle_t thread_event_handle
ni_thread_arg_struct_t * keep_alive_thread_args
char blk_dev_name[NI_MAX_DEVICE_NAME_LEN]
ni_device_handle_t sender_handle
ni_device_handle_t device_handle
ni_load_query_t load_query
ni_pthread_mutex_t * pext_mutex
ni_framerate_t framerate
volatile uint64_t last_access_time
ni_enc_avc_roi_custom_map_t * avc_roi_map
char dev_xcoder_name[MAX_CHAR_IN_DEVICE_NAME]
ni_pthread_t keep_alive_thread
unsigned short domain
ni_event_handle_t event_handle
ni_input_frame input_frame_fifo[120]
encoder:calculate PSNR start
ni_framerate_t last_framerate
uint32_t meta_size
Params used in VFR mode Done///.
ni_device_handle_t blk_io_handle
ni_enc_hevc_roi_custom_map_t * hevc_roi_map
ni_long_term_ref_t ltr_to_set
ni_session_run_state_t session_run_state
ni_encoder_change_params_t * enc_change_params
ni_pthread_mutex_t low_delay_sync_mutex
ni_enc_quad_roi_custom_map * roi_map
ni_region_of_interest_t * av_rois
uint8_t * hevc_sub_ctu_roi_buf
ni_frame_pool_type_t pool_type
union _ni_session_data_io::@19 data
ni_event_handle_t thread_event_handle
ni_pthread_mutex_t * p_mutex
ni_device_handle_t device_handle
volatile uint64_t * plast_access_time
int32_t videoFullRange
int32_t colorDescPresent
int32_t colorPrimaries
int32_t aspectRatioHeight
int32_t colorSpace
int32_t colorTrc
int32_t aspectRatioWidth
ni_encoder_cfg_params_t cfg_enc_params
int8_t customize_roi_qp_map[NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL][NI_CUSTOMIZE_ROI_QP_NUM]
ni_ddr_priority_mode_t ddr_priority_mode
ni_frame_t * p_first_frame
ni_decoder_input_params_t dec_input_params
int reconf_hash[NI_BITRATE_RECONFIG_FILE_MAX_LINES][NI_BITRATE_RECONFIG_FILE_MAX_ENTRIES_PER_LINE]
encoder AVC ROI custom map (1 MB = 8bits)
struct _ni_enc_avc_roi_custom_map::@5 field
encoder HEVC ROI custom map (1 CTU = 64bits)
struct _ni_enc_hevc_roi_custom_map::@4 field
encoder AVC ROI custom map (1 MB = 8bits)
struct _ni_enc_quad_roi_custom_map::@6 field