libxcoder 5.7.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#include <syslog.h>
34#endif
35#include <unistd.h>
36#include <sys/ioctl.h>
37#include <sys/mman.h>
38#include <sys/types.h>
39#include <sys/stat.h>
40#include <sys/time.h>
41#include <fcntl.h>
42#include <errno.h>
43#include <semaphore.h>
44#include <limits.h>
45#include <unistd.h>
46#include <signal.h>
47#include <poll.h>
48#endif
49
50#include <stdint.h>
51#include <string.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <stdint.h>
55#include <sys/stat.h>
56#include "inttypes.h"
57#include "ni_device_api.h"
58#include "ni_device_api_priv.h"
59#include "ni_nvme.h"
60#include "ni_util.h"
61#include "ni_rsrc_api.h"
62#include "ni_rsrc_priv.h"
63#include "ni_lat_meas.h"
64#ifdef _WIN32
65#include <shlobj.h>
66#else
67#include "ni_p2p_ioctl.h"
68#endif
69
86#if __linux__ || __APPLE__
87static struct stat g_nvme_stat = { 0 };
88
89static int close_fd_zero_atexit = 0;
90
91static void close_fd_zero(void)
92{
93 close(0);
94}
95
96#endif
97
98/*!*****************************************************************************
99 * \brief Allocate and initialize a new ni_session_context_t struct
100 *
101 *
102 * \return On success returns a valid pointer to newly allocated context
103 * On failure returns NULL
104 ******************************************************************************/
106{
107 ni_session_context_t *p_ctx = NULL;
108
109 p_ctx = malloc(sizeof(ni_session_context_t));
110 if (!p_ctx)
111 {
113 "ERROR: %s() Failed to allocate memory for session context\n",
114 __func__);
115 } else
116 {
117 memset(p_ctx, 0, sizeof(ni_session_context_t));
118
120 {
121 ni_log(NI_LOG_ERROR, "ERROR: %s() Failed to init session context\n",
122 __func__);
124 return NULL;
125 }
126 }
127 return p_ctx;
128}
129
130/*!*****************************************************************************
131 * \brief Free previously allocated session context
132 *
133 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
134 * struct
135 *
136 ******************************************************************************/
138{
139 if (p_ctx)
140 {
142#ifdef MEASURE_LATENCY
143 if (p_ctx->frame_time_q)
144 {
146 }
147#endif
148 free(p_ctx);
149 }
150}
151
152/*!*****************************************************************************
153 * \brief Initialize already allocated session context to a known state
154 *
155 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
156 * struct
157 * \return On success
158 * NI_RETCODE_SUCCESS
159 * On failure
160 * NI_RETCODE_INVALID_PARAM
161 * NI_RETCODE_FAILURE
162 ******************************************************************************/
164{
165 int bitrate = 0;
166 int framerate_num = 0;
167 int framerate_denom = 0;
168
169 if (!p_ctx)
170 {
172 }
173
175 {
176 // session context will reset so save the last values for sequence change
177 if (p_ctx->last_bitrate < NI_MIN_BITRATE)
178 bitrate = NI_MIN_BITRATE;
179 else if (p_ctx->last_bitrate > NI_MAX_BITRATE)
180 bitrate = NI_MAX_BITRATE;
181 else
182 bitrate = p_ctx->last_bitrate;
183 framerate_num = p_ctx->last_framerate.framerate_num;
184 framerate_denom = p_ctx->last_framerate.framerate_denom;
185 }
186
187 memset(p_ctx, 0, sizeof(ni_session_context_t));
188
189 p_ctx->last_bitrate = bitrate;
190 p_ctx->last_framerate.framerate_num = framerate_num;
191 p_ctx->last_framerate.framerate_denom = framerate_denom;
192
193 // Xcoder thread mutex init
194 if (ni_pthread_mutex_init(&p_ctx->mutex))
195 {
196 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): init xcoder_mutex fail, return\n",
197 __func__);
198 return NI_RETCODE_FAILURE;
199 }
200 p_ctx->pext_mutex = &p_ctx->mutex; //used exclusively for hwdl
201
202 // low delay send/recv sync init
204 {
205 ni_log2(p_ctx, NI_LOG_ERROR,
206 "ERROR %s(): init xcoder_low_delay_sync_mutex fail return\n",
207 __func__);
208 return NI_RETCODE_FAILURE;
209 }
210 if (ni_pthread_cond_init(&p_ctx->low_delay_sync_cond, NULL))
211 {
212 ni_log2(p_ctx, NI_LOG_ERROR,
213 "ERROR %s(): init xcoder_low_delay_sync_cond fail return\n",
214 __func__);
215 return NI_RETCODE_FAILURE;
216 }
217
218 p_ctx->mutex_initialized = true;
219
220 // Init the max IO size to be invalid
224 p_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
225 p_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
226 p_ctx->hw_id = NI_INVALID_HWID;
227 p_ctx->event_handle = NI_INVALID_EVENT_HANDLE;
228 p_ctx->thread_event_handle = NI_INVALID_EVENT_HANDLE;
230 p_ctx->keep_alive_thread = (ni_pthread_t){0};
232 p_ctx->decoder_low_delay = 0;
233 p_ctx->enable_low_delay_check = 0;
234 p_ctx->low_delay_sync_flag = 0;
235 p_ctx->async_mode = 0;
237 p_ctx->buffered_frame_index = 0;
238 p_ctx->ppu_reconfig_pkt_pos = 0;
239 p_ctx->headers_length = 0;
240 // by default, select the least model load card
243#ifdef MY_SAVE
244 p_ctx->debug_write_ptr = NULL;
245 p_ctx->debug_write_index_ptr = NULL;
246 p_ctx->debug_write_sent_size = 0;
247#endif
248
249#ifdef MEASURE_LATENCY
250 p_ctx->frame_time_q = (void *)ni_lat_meas_q_create(2000);
251#endif
252
253 return NI_RETCODE_SUCCESS;
254}
255
256/*!*****************************************************************************
257 * \brief Clear already allocated session context
258 *
259 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
260 *
261 *
262 ******************************************************************************/
273
274/*!*****************************************************************************
275 * \brief Create event and return event handle if successful (Windows only)
276 *
277 * \return On success returns a event handle
278 * On failure returns NI_INVALID_EVENT_HANDLE
279 ******************************************************************************/
280ni_event_handle_t ni_create_event(void)
281{
282#ifdef _WIN32
283 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
284
285 // Input-0 determines whether the returned handle can be inherited by the child process.If lpEventAttributes is NULL, this handle cannot be inherited.
286 // 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.
287 // Input-2 specifies the initial state of the event object.If TRUE, the initial state is signaled;Otherwise, no signal state.
288 // Input-3 If the lpName is NULL, a nameless event object is created.。
289 event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
290 if (event_handle == NULL)
291 {
292 ni_log(NI_LOG_ERROR, "ERROR %d: %s() create event failed\n",
293 NI_ERRNO, __func__);
294 return NI_INVALID_EVENT_HANDLE;
295 }
296 return event_handle;
297#else
298 return NI_INVALID_EVENT_HANDLE;
299#endif
300}
301
302/*!*****************************************************************************
303 * \brief Close event and release resources (Windows only)
304 *
305 * \return NONE
306 *
307 ******************************************************************************/
308void ni_close_event(ni_event_handle_t event_handle)
309{
310 if ( NI_INVALID_DEVICE_HANDLE == event_handle )
311 {
312 ni_log(NI_LOG_DEBUG, "Warning %s: null parameter passed %x\n", __func__,
313 event_handle);
314 return;
315 }
316
317 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
318
319#ifdef _WIN32
320 BOOL retval;
321 ni_log(NI_LOG_DEBUG, "%s(): closing %p\n", __func__, event_handle);
322
323 retval = CloseHandle(event_handle);
324 if (FALSE == retval)
325 {
326 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): closing event_handle %p failed\n",
327 NI_ERRNO, __func__, event_handle);
328 }
329 else
330 {
331 ni_log(NI_LOG_DEBUG, "%s(): device %p closed successfuly\n", __func__,
332 event_handle);
333 }
334#else
335 int err = 0;
336 ni_log(NI_LOG_DEBUG, "%s(): closing %d\n", __func__, event_handle);
337 err = close(event_handle);
338 if (err)
339 {
340 char error_message[100] = {'\0'};
341 char unknown_error_message[20] = {'\0'};
342 ni_sprintf(error_message, 100, "ERROR: %s(): ", __func__);
343 switch (err)
344 {
345 case EBADF:
346 ni_strcat(error_message, 100, "EBADF\n");
347 break;
348 case EINTR:
349 ni_strcat(error_message, 100, "EINTR\n");
350 break;
351 case EIO:
352 ni_strcat(error_message, 100, "EIO\n");
353 break;
354 default:
355 ni_sprintf(unknown_error_message, 20, "Unknown error %d\n", err);
356 ni_strcat(error_message, 100, unknown_error_message);
357 }
358 ni_log(NI_LOG_ERROR, "%s\n", error_message);
359 }
360#endif
361 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
362}
363
364#ifndef DEPRECATION_AS_ERROR
365/*!*****************************************************************************
366 * \brief Open device and return device device_handle if successful
367 *
368 * \param[in] p_dev Device name represented as c string. ex: "/dev/nvme0"
369 * \param[out] p_max_io_size_out Maximum IO Transfer size supported, could be
370 * NULL
371 *
372 * \return On success returns a device device_handle
373 * On failure returns NI_INVALID_DEVICE_HANDLE
374 ******************************************************************************/
375NI_DEPRECATED ni_device_handle_t ni_device_open(const char * p_dev, uint32_t * p_max_io_size_out)
376{
377#ifdef _WIN32
378 DWORD retval;
379 HANDLE device_handle;
380
381 if (!p_dev)
382 {
383 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
384 return NI_INVALID_DEVICE_HANDLE;
385 }
386
387 if (p_max_io_size_out != NULL && *p_max_io_size_out == NI_INVALID_IO_SIZE)
388 {
389 // For now, we just use it to allocate p_leftover buffer
390 // NI_MAX_PACKET_SZ is big enough
391 *p_max_io_size_out = NI_MAX_PACKET_SZ;
392 }
393
394 device_handle = CreateFile(p_dev, GENERIC_READ | GENERIC_WRITE,
395 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
396 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
397
398 ni_log(NI_LOG_DEBUG, "%s() device_name: %s", __func__, p_dev);
399 if (INVALID_HANDLE_VALUE == device_handle)
400 {
401 retval = GetLastError();
402 ni_log(NI_LOG_ERROR, "Failed to open %s, retval %d \n", p_dev, retval);
403 } else
404 {
405 ni_log(NI_LOG_DEBUG, "Found NVME Controller at %s \n", p_dev);
406 }
407
408 return device_handle;
409#else
410 int retval = -1;
411 ni_device_handle_t fd = NI_INVALID_DEVICE_HANDLE;
412
413 if (!p_dev)
414 {
415 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
417 }
418
419 if (p_max_io_size_out != NULL && *p_max_io_size_out == NI_INVALID_IO_SIZE)
420 {
421#if __linux__
422 *p_max_io_size_out = ni_get_kernel_max_io_size(p_dev);
423#elif __APPLE__
424 *p_max_io_size_out = MAX_IO_TRANSFER_SIZE;
425#endif
426 }
427
428 ni_log(NI_LOG_DEBUG, "%s: opening regular-io enabled %s\n", __func__,
429 p_dev);
430 //O_SYNC is added to ensure that data is written to the card when the pread/pwrite function returns
431 #if __linux__
432 //O_DIRECT is added to ensure that data can be sent directly to the card instead of to cache memory
433 fd = open(p_dev, O_RDWR | O_SYNC | O_DIRECT);
434 #elif __APPLE__
435 //O_DIRECT isn't available, so instead we use F_NOCACHE below
436 fd = open(p_dev, O_RDWR | O_SYNC);
437 #endif
438
439 if (fd < 0)
440 {
441 char errmsg[NI_ERRNO_LEN] = {0};
443 ni_log(NI_LOG_ERROR, "ERROR: %d %s open() failed on %s\n", NI_ERRNO,
444 errmsg, p_dev);
445 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
446 fd = NI_INVALID_DEVICE_HANDLE;
447 LRETURN;
448 }
449 else if(fd == 0)
450 {
451 //this code is just for the case that we do not initialize all fds to NI_INVALID_DEVICE_HANDLE
452
453 //if we make sure that all the fds in libxcoder is initialized to NI_INVALID_DEVICE_HANDLE
454 //we should remove this check
455
456 //we hold the fd = 0, so other threads could not visit these code
457 //thread safe unless other thread close fd=0 accidently
458 ni_log(NI_LOG_ERROR, "open fd = 0 is not as expeceted\n");
459 if(close_fd_zero_atexit == 0)
460 {
461 close_fd_zero_atexit = 1;
462 atexit(close_fd_zero);
463 }
464 else
465 {
466 ni_log(NI_LOG_ERROR, "libxcoder has held the fd=0, but open fd=0 again, maybe fd=0 was closed accidently.");
467 }
468 fd = NI_INVALID_DEVICE_HANDLE;
469 }
470
471 #if __APPLE__
472 //F_NOCACHE is set to ensure that data can be sent directly to the card instead of to cache memory
473 retval = fcntl(fd, F_NOCACHE, 1);
474 if (retval < 0)
475 {
476 ni_log(NI_LOG_ERROR, "ERROR: fnctl() failed on %s\n", p_dev);
477 ni_log(NI_LOG_ERROR, "ERROR: ni_device_open() failed!\n");
478 close(fd);
479 fd = NI_INVALID_DEVICE_HANDLE;
480 LRETURN;
481 }
482 #endif
483
484 retval = fstat(fd, &g_nvme_stat);
485 if (retval < 0)
486 {
487 ni_log(NI_LOG_ERROR, "ERROR: fstat() failed on %s\n", p_dev);
488 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
489 close(fd);
490 fd = NI_INVALID_DEVICE_HANDLE;
491 LRETURN;
492 }
493
494 if (!S_ISCHR(g_nvme_stat.st_mode) && !S_ISBLK(g_nvme_stat.st_mode))
495 {
496 ni_log(NI_LOG_ERROR, "ERROR: %s is not a block or character device\n",
497 p_dev);
498 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
499 close(fd);
500 fd = NI_INVALID_DEVICE_HANDLE;
501 LRETURN;
502 }
503
504 ni_log(NI_LOG_DEBUG, "%s: success, fd=%d\n", __func__, fd);
505
506END:
507
508 return fd;
509#endif
510}
511#endif
512
513/*!*****************************************************************************
514 * \brief Open device and return device device_handle if successful
515 *
516 * \param[in] p_dev Device name represented as c string. ex: "/dev/nvme0"
517 * \param[in] p_config Device configuration parameters
518 *
519 * \return On success returns a device device_handle
520 * On failure returns NI_INVALID_DEVICE_HANDLE
521 ******************************************************************************/
522ni_device_handle_t ni_device_open2(const char * p_dev, ni_device_mode_t mode)
523{
524#ifdef _WIN32
525 DWORD retval;
526 HANDLE device_handle;
527 DWORD dwDesiredAccess = 0;
528
529 if (!p_dev)
530 {
531 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
532 return NI_INVALID_DEVICE_HANDLE;
533 }
534
535 /* Convert access mode using bit operations */
536 switch(mode & NI_DEVICE_READ_WRITE)
537 {
539 /* Read-only mode */
540 dwDesiredAccess = GENERIC_READ;
541 break;
543 /* Write-only mode */
544 dwDesiredAccess = GENERIC_WRITE;
545 break;
547 default:
548 /* Read-write mode takes precedence */
549 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
550 break;
551 }
552
553 device_handle = CreateFile(p_dev, dwDesiredAccess,
554 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
555 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
556
557 ni_log(NI_LOG_DEBUG, "%s() device_name: %s", __func__, p_dev);
558 if (INVALID_HANDLE_VALUE == device_handle)
559 {
560 retval = GetLastError();
561 ni_log(NI_LOG_ERROR, "Failed to open %s, retval %d \n", p_dev, retval);
562 } else
563 {
564 ni_log(NI_LOG_DEBUG, "Found NVME Controller at %s \n", p_dev);
565 }
566
567 return device_handle;
568#else
569 int retval = -1;
570 ni_device_handle_t fd = NI_INVALID_DEVICE_HANDLE;
571 int open_flags = 0;
572
573 if (!p_dev)
574 {
575 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
577 }
578
579 ni_log(NI_LOG_DEBUG, "%s: opening regular-io enabled %s\n", __func__,
580 p_dev);
581
582 /* Set access mode using bit operations */
583 switch(mode & NI_DEVICE_READ_WRITE)
584 {
586 /* Read-only mode */
587 open_flags = O_RDONLY;
588 break;
590 /* Write-only mode */
591 open_flags = O_WRONLY;
592 break;
594 default:
595 /* Read-write mode takes precedence */
596 open_flags = O_RDWR;
597 break;
598 }
599
600 open_flags |= O_SYNC;
601#if __linux__
602 open_flags |= O_DIRECT;
603#elif __APPLE__
604 /* macOS doesn't support O_DIRECT, use F_NOCACHE instead */
605#endif
606
607 fd = open(p_dev, open_flags);
608 if (fd < 0)
609 {
610 ni_log(NI_LOG_ERROR, "ERROR: %d %s open() failed on %s\n", NI_ERRNO,
611 strerror(NI_ERRNO), p_dev);
612 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
613 fd = NI_INVALID_DEVICE_HANDLE;
614 LRETURN;
615 }
616
617#if __APPLE__
618 //F_NOCACHE is set to ensure that data can be sent directly to the card instead of to cache memory
619 retval = fcntl(fd, F_NOCACHE, 1);
620 if (retval < 0)
621 {
622 ni_log(NI_LOG_ERROR, "ERROR: fnctl() failed on %s\n", p_dev);
623 ni_log(NI_LOG_ERROR, "ERROR: ni_device_open2() failed!\n");
624 close(fd);
625 fd = NI_INVALID_DEVICE_HANDLE;
626 LRETURN;
627 }
628#endif
629
630 retval = fstat(fd, &g_nvme_stat);
631 if (retval < 0)
632 {
633 ni_log(NI_LOG_ERROR, "ERROR: fstat() failed on %s\n", p_dev);
634 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
635 close(fd);
636 fd = NI_INVALID_DEVICE_HANDLE;
637 LRETURN;
638 }
639
640 if (!S_ISCHR(g_nvme_stat.st_mode) && !S_ISBLK(g_nvme_stat.st_mode))
641 {
642 ni_log(NI_LOG_ERROR, "ERROR: %s is not a block or character device\n",
643 p_dev);
644 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
645 close(fd);
646 fd = NI_INVALID_DEVICE_HANDLE;
647 LRETURN;
648 }
649
650 ni_log(NI_LOG_DEBUG, "%s: success, fd=%d\n", __func__, fd);
651
652END:
653
654 return fd;
655#endif
656}
657
658/*!*****************************************************************************
659 * \brief Close device and release resources
660 *
661 * \param[in] device_handle Device handle obtained by calling ni_device_open()
662 *
663 * \return NONE
664 *
665 ******************************************************************************/
666void ni_device_close(ni_device_handle_t device_handle)
667{
668 if ( NI_INVALID_DEVICE_HANDLE == device_handle )
669 {
670 ni_log(NI_LOG_ERROR, "ERROR %s: null parameter passed %x\n", __func__,
671 device_handle);
672 return;
673 }
674
675 if(device_handle == 0)
676 {
677 //this code is just for the case that we do not initialize all fds to NI_INVALID_DEVICE_HANDLE
678
679 //if we make sure that all the fds in libxcoder is initialized to NI_INVALID_DEVICE_HANDLE
680 //we should remove this check
681 ni_log(NI_LOG_ERROR, "%s close fd=0 is not as expected", __func__);
682 return;
683 }
684
685 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
686
687#ifdef _WIN32
688 BOOL retval;
689
690 ni_log(NI_LOG_DEBUG, "%s(): closing %p\n", __func__, device_handle);
691
692 retval = CloseHandle(device_handle);
693 if (FALSE == retval)
694 {
696 "ERROR: %s(): closing device device_handle %p failed, error: %d\n",
697 __func__, device_handle, NI_ERRNO);
698 }
699 else
700 {
701 ni_log(NI_LOG_DEBUG, "%s(): device %p closed successfuly\n", __func__,
702 device_handle);
703 }
704#else
705 int err = 0;
706 ni_log(NI_LOG_DEBUG, "%s(): closing fd %d\n", __func__, device_handle);
707 err = close(device_handle);
708 if (err == -1)
709 {
710 char error_message[100] = {'\0'};
711 char unknown_error_message[20] = {'\0'};
712 ni_sprintf(error_message, 100, "ERROR: %s(): ", __func__);
713 switch (errno)
714 {
715 case EBADF:
716 ni_strcat(error_message, 100, "EBADF\n");
717 break;
718 case EINTR:
719 ni_strcat(error_message, 100, "EINTR\n");
720 break;
721 case EIO:
722 ni_strcat(error_message, 100, "EIO\n");
723 break;
724 default:
725 ni_sprintf(unknown_error_message, 20, "Unknown error %d\n", err);
726 ni_strcat(error_message, 100, unknown_error_message);
727 }
728 char errmsg[NI_ERRNO_LEN] = {0};
730 ni_log(NI_LOG_ERROR, "%s\n", errmsg);
731 ni_log(NI_LOG_ERROR, "%s\n", error_message);
732 }
733#endif
734 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
735}
736
737#ifndef DEPRECATION_AS_ERROR
738/*!*****************************************************************************
739 * \brief Query device and return device capability structure
740 * This function had been replaced by ni_device_capability_query2
741 * This function can't be callback in multi thread
742 *
743 * \param[in] device_handle Device handle obtained by calling ni_device_open
744 * \param[in] p_cap Pointer to a caller allocated ni_device_capability_t
745 * struct
746 * \return On success
747 * NI_RETCODE_SUCCESS
748 * On failure
749 * NI_RETCODE_INVALID_PARAM
750 * NI_RETCODE_ERROR_MEM_ALOC
751 * NI_RETCODE_ERROR_NVME_CMD_FAILED
752 ******************************************************************************/
754{
755 void * p_buffer = NULL;
757 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
758
759 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
760
761 if ( (NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_cap) )
762 {
763 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
764 __func__);
766 LRETURN;
767 }
768
769 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
771 {
772 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
773 NI_ERRNO, __func__);
775 LRETURN;
776 }
777
778 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
779
780 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
781 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer, NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
782 {
784 LRETURN;
785 }
786
788
789END:
790
791 ni_aligned_free(p_buffer);
792 ni_log(NI_LOG_DEBUG, "%s(): retval: %d\n", __func__, retval);
793
794 return retval;
795}
796#endif
797
798/*!*****************************************************************************
799 * \brief Query device and return device capability structure
800 * This function had replaced ni_device_capability_query
801 * This function can be callback with multi thread
802 *
803 * \param[in] device_handle Device handle obtained by calling ni_device_open
804 * \param[in] p_cap Pointer to a caller allocated ni_device_capability_t
805 * struct
806 * \param[in] device_in_ctxt If device is in ctx
807 * \return On success
808 * NI_RETCODE_SUCCESS
809 * On failure
810 * NI_RETCODE_INVALID_PARAM
811 * NI_RETCODE_ERROR_MEM_ALOC
812 * NI_RETCODE_ERROR_NVME_CMD_FAILED
813 ******************************************************************************/
814ni_retcode_t ni_device_capability_query2(ni_device_handle_t device_handle,
815 ni_device_capability_t *p_cap, bool device_in_ctxt)
816{
817 void * p_buffer = NULL;
819 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
820
821 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
822
823 if ( (NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_cap) )
824 {
825 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
826 __func__);
828 LRETURN;
829 }
830
831 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
833 {
834 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
835 NI_ERRNO, __func__);
837 LRETURN;
838 }
839
840 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
841
842 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
843 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer, NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
844 {
846 LRETURN;
847 }
848
849 ni_populate_device_capability_struct(p_cap, p_buffer, device_handle, device_in_ctxt);
850
851END:
852
853 ni_aligned_free(p_buffer);
854 ni_log(NI_LOG_DEBUG, "%s(): retval: %d\n", __func__, retval);
855
856 return retval;
857}
858
859/*!*****************************************************************************
860 * \brief Open a new device session depending on the device_type parameter
861 * If device_type is NI_DEVICE_TYPE_DECODER opens decoding session
862 * If device_type is NI_DEVICE_TYPE_ENCODER opens encoding session
863 * If device_type is NI_DEVICE_TYPE_SCALER opens scaling session
864 *
865 * \param[in] p_ctx Pointer to a caller allocated
866 * ni_session_context_t struct
867 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER,
868 * or NI_DEVICE_TYPE_SCALER
869 * \return On success
870 * NI_RETCODE_SUCCESS
871 * On failure
872 * NI_RETCODE_INVALID_PARAM
873 * NI_RETCODE_ERROR_MEM_ALOC
874 * NI_RETCODE_ERROR_NVME_CMD_FAILED
875 * NI_RETCODE_ERROR_INVALID_SESSION
876 ******************************************************************************/
878 ni_device_type_t device_type)
879{
881 ni_device_pool_t *p_device_pool = NULL;
882 ni_device_context_t *p_device_context = NULL;
883 ni_device_info_t *p_dev_info = NULL;
884 ni_device_info_t dev_info = { 0 };
886 ni_device_context_t *rsrc_ctx = NULL;
887 int i = 0;
888 int rc = 0;
889 int num_coders = 0;
890 bool use_model_load = true;
891 int least_load = 0;
892 int curr_load = 0;
893 int guid = -1;
894 uint32_t num_sw_instances = 0;
895 uint32_t pixel_load = 0xFFFFFFFFU;
896 int user_handles = false;
897 ni_lock_handle_t lock = NI_INVALID_LOCK_HANDLE;
898 ni_device_handle_t handle = NI_INVALID_DEVICE_HANDLE;
899 ni_device_handle_t handle1 = NI_INVALID_DEVICE_HANDLE;
900 // For none nvme block device we just need to pass in dummy
901 ni_session_context_t *p_session_context = NULL;
902 ni_device_type_t query_type = device_type;
903
904 if (!p_ctx)
905 {
906 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
907 __func__);
909 }
910
911#ifdef _WIN32
912 if (!IsUserAnAdmin())
913 {
914 ni_log(NI_LOG_ERROR, "ERROR: %s must be in admin priviledge\n", __func__);
916 }
917#endif
918
921
922 p_session_context = ni_device_session_context_alloc_init();
923 if (!p_session_context)
924 {
926 LRETURN;
927 }
928
929 if (NI_INVALID_SESSION_ID != p_ctx->session_id)
930 {
931 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: trying to overwrite existing session, "
932 "device_type %d, session id %d\n",
933 device_type, p_ctx->session_id);
935 LRETURN;
936 }
937
938 p_ctx->p_hdr_buf = NULL;
939 p_ctx->hdr_buf_size = 0;
940
941 p_ctx->roi_side_data_size = p_ctx->nb_rois = 0;
942 p_ctx->av_rois = NULL;
943 p_ctx->roi_map = NULL;
944 p_ctx->avc_roi_map = NULL;
945 p_ctx->hevc_roi_map = NULL;
946 p_ctx->hevc_sub_ctu_roi_buf = NULL;
947 p_ctx->p_master_display_meta_data = NULL;
948
949 p_ctx->enc_change_params = NULL;
950
951 p_ctx->target_bitrate = -1;
952 p_ctx->force_idr_frame = 0;
954 p_ctx->ltr_to_set.use_long_term_ref = 0;
955 p_ctx->ltr_interval = -1;
956 p_ctx->ltr_frame_ref_invalid = -1;
957 p_ctx->framerate.framerate_num = 0;
958 p_ctx->framerate.framerate_denom = 0;
959 p_ctx->vui.colorDescPresent = 0;
960 p_ctx->vui.colorPrimaries = 2; // 2 is unspecified
961 p_ctx->vui.colorTrc = 2; // 2 is unspecified
962 p_ctx->vui.colorSpace = 2; // 2 is unspecified
963 p_ctx->vui.aspectRatioWidth = 0;
964 p_ctx->vui.aspectRatioHeight = 0;
965 p_ctx->vui.videoFullRange = 0;
966 p_ctx->max_frame_size = 0;
967 p_ctx->reconfig_crf = -1;
968 p_ctx->reconfig_crf_decimal = 0;
969 p_ctx->reconfig_vbv_buffer_size = 0;
970 p_ctx->reconfig_vbv_max_rate = 0;
971 p_ctx->last_gop_size = 0;
972 p_ctx->initial_frame_delay = 0;
973 p_ctx->current_frame_delay = 0;
974 p_ctx->max_frame_delay = 0;
975 p_ctx->av1_pkt_num = 0;
977 p_ctx->force_low_delay = false;
978 p_ctx->force_low_delay_cnt = 0;
979 p_ctx->pkt_delay_cnt = 0;
980 p_ctx->reconfig_intra_period = -1;
981 p_ctx->reconfig_slice_arg = 0;
982
983 memset(p_ctx->input_frame_fifo, 0, sizeof(ni_input_frame) * 120);
984 for (i = 0; i < 120; i++)
985 {
986 p_ctx->input_frame_fifo[i].usable = -1;
987 }
988
989 handle = p_ctx->device_handle;
990 handle1 = p_ctx->blk_io_handle;
991
992 ni_log2(p_ctx, NI_LOG_DEBUG,
993 "%s: device type %d hw_id %d blk_dev_name: %s dev_xcoder_name: %s.\n",
994 __func__, device_type, p_ctx->hw_id, p_ctx->blk_dev_name,
995 p_ctx->dev_xcoder_name);
996
997 if (device_type == NI_DEVICE_TYPE_UPLOAD)
998 {
999 //uploader shares resources with encoder to query as encoder for load info
1000 query_type = NI_DEVICE_TYPE_ENCODER;
1001 }
1002
1003 // if caller requested device by block device name, try to find its GUID and
1004 // use it to override the hw_id which is the passed in device GUID
1005 if (0 != strcmp(p_ctx->blk_dev_name, ""))
1006 {
1007 int tmp_guid_id;
1008 tmp_guid_id =
1010 if (tmp_guid_id != NI_RETCODE_FAILURE)
1011 {
1012 ni_log2(p_ctx, NI_LOG_DEBUG,
1013 "%s: block device name %s type %d guid %d is to "
1014 "override passed in guid %d\n",
1015 __func__, p_ctx->blk_dev_name, device_type, tmp_guid_id,
1016 p_ctx->hw_id);
1017 p_ctx->hw_id = tmp_guid_id;
1018 } else
1019 {
1020 ni_log(NI_LOG_INFO, "%s: block device name %s type %d NOT found ..\n",
1021 __func__, p_ctx->blk_dev_name, device_type);
1023 LRETURN;
1024 }
1025 }
1026
1027 // User did not pass in any handle, so we create it for them
1028 if ((handle1 == NI_INVALID_DEVICE_HANDLE) && (handle == NI_INVALID_DEVICE_HANDLE))
1029 {
1030 if (p_ctx->hw_id >=0) // User selected the encder/ decoder number
1031 {
1032 if ((rsrc_ctx = ni_rsrc_allocate_simple_direct(device_type, p_ctx->hw_id)) == NULL)
1033 {
1034
1035 ni_log2(p_ctx, NI_LOG_ERROR, "Error XCoder resource allocation: inst %d\n",
1036 p_ctx->hw_id);
1038 LRETURN;
1039 }
1040 ni_log2(p_ctx, NI_LOG_DEBUG, "device %p\n", rsrc_ctx);
1041 // Now the device name is in the rsrc_ctx, we open this device to get the file handles
1042
1043#ifdef _WIN32
1044 if ((handle = ni_device_open2(rsrc_ctx->p_device_info->blk_name,
1045 NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE)
1046 {
1049 LRETURN;
1050 } else
1051 {
1052 user_handles = true;
1053 p_ctx->device_handle = handle;
1054 p_ctx->blk_io_handle = handle;
1055 handle1 = handle;
1059 }
1060#else
1061 //The original design (code below) is to open char and block device file separately. And the ffmpeg will close the device twice.
1062 //However, in I/O version, char device can't be opened. For compatibility, and to avoid errors, open the block device twice.
1063 if (((handle = ni_device_open2(rsrc_ctx->p_device_info->dev_name, NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE) ||
1064 ((handle1 = ni_device_open2(rsrc_ctx->p_device_info->dev_name, NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE))
1065 {
1068 LRETURN;
1069 } else
1070 {
1071 user_handles = true;
1072 p_ctx->device_handle = handle;
1073 p_ctx->blk_io_handle = handle1;
1074 // NOLINTNEXTLINE(clang-analyzer-core.NonNullParamChecker): Couldn't determine why it will be NULL.
1077
1079 }
1080#endif
1081 } else
1082 {
1083 int tmp_id = -1;
1084
1085 // Decide on model load or real load to be used, based on name passed
1086 // in from p_ctx->dev_xcoder_name; after checking it will be used to
1087 // store device file name.
1088 if (0 == strcmp(p_ctx->dev_xcoder_name, NI_BEST_REAL_LOAD_STR))
1089 {
1090 use_model_load = false;
1091 } else if (0 != strcmp(p_ctx->dev_xcoder_name, NI_BEST_MODEL_LOAD_STR))
1092 {
1093 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s unrecognized option: %s.\n",
1094 __func__, p_ctx->dev_xcoder_name);
1095 retval = NI_RETCODE_INVALID_PARAM;
1096 LRETURN;
1097 }
1098
1099 if (ni_rsrc_lock_and_open(query_type, &lock) != NI_RETCODE_SUCCESS)
1100 {
1102 LRETURN;
1103 }
1104
1105 // We need to query through all the boards to confirm the least load.
1106
1107 p_device_pool = ni_rsrc_get_device_pool();
1108
1109 if (!p_device_pool)
1110 {
1111 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Error calling ni_rsrc_get_device_pool()\n");
1113 LRETURN;
1114 }
1115 if (IS_XCODER_DEVICE_TYPE(query_type))
1116 {
1117 num_coders = p_device_pool->p_device_queue->xcoder_cnt[query_type];
1118 } else
1119 {
1120 retval = NI_RETCODE_INVALID_PARAM;
1121 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1122 {
1124 LRETURN;
1125 }
1126 LRETURN;
1127 }
1128
1129 for (i = 0; i < num_coders; i++)
1130 {
1131 tmp_id = p_device_pool->p_device_queue->xcoders[query_type][i];
1132 p_device_context = ni_rsrc_get_device_context(query_type, tmp_id);
1133
1134 if (p_device_context == NULL)
1135 {
1136 ni_log2(p_ctx, NI_LOG_ERROR,
1137 "ERROR: %s() ni_rsrc_get_device_context() failed\n",
1138 __func__);
1139 continue;
1140 }
1141
1142 // Code is included in the for loop. In the loop, the device is
1143 // just opened once, and it will be closed once too.
1144 p_session_context->blk_io_handle = ni_device_open2(
1145 p_device_context->p_device_info->dev_name, NI_DEVICE_READ_WRITE);
1146 p_session_context->device_handle = p_session_context->blk_io_handle;
1147
1148 if (NI_INVALID_DEVICE_HANDLE == p_session_context->device_handle)
1149 {
1150 ni_log2(p_ctx, NI_LOG_ERROR, "Error open device");
1151 ni_rsrc_free_device_context(p_device_context);
1152 continue;
1153 }
1154
1155 p_session_context->hw_id = p_device_context->p_device_info->hw_id;
1156 rc = ni_device_session_query(p_session_context, query_type);
1157 if (NI_INVALID_DEVICE_HANDLE != p_session_context->device_handle)
1158 {
1159 ni_device_close(p_session_context->device_handle);
1160 }
1161
1162 if (NI_RETCODE_SUCCESS != rc)
1163 {
1164 ni_log2(p_ctx, NI_LOG_ERROR, "Error query %s %s.%d\n",
1165 g_device_type_str[query_type],
1166 p_device_context->p_device_info->dev_name,
1167 p_device_context->p_device_info->hw_id);
1168 ni_rsrc_free_device_context(p_device_context);
1169 continue;
1170 }
1171 ni_rsrc_update_record(p_device_context, p_session_context);
1172 p_dev_info = p_device_context->p_device_info;
1173
1174 // here we select the best load
1175 // for decoder/encoder: check the model_load/real_load
1176 // for hwuploader: check directly hwupload pixel load in query result
1177 if (NI_DEVICE_TYPE_UPLOAD == device_type)
1178 {
1179 if (lower_pixel_rate(&p_session_context->load_query, pixel_load))
1180 {
1181 guid = tmp_id;
1182 pixel_load = p_session_context->load_query.total_pixel_load;
1183 memcpy(&dev_info, p_dev_info, sizeof(ni_device_info_t));
1184 }
1185 } else
1186 {
1187 if (use_model_load)
1188 {
1189 curr_load = p_dev_info->model_load;
1190 } else
1191 {
1192 curr_load = p_dev_info->load;
1193 }
1194
1195 if (i == 0 || curr_load < least_load ||
1196 (curr_load == least_load &&
1197 p_dev_info->active_num_inst < num_sw_instances))
1198 {
1199 guid = tmp_id;
1200 least_load = curr_load;
1201 num_sw_instances = p_dev_info->active_num_inst;
1202 memcpy(&dev_info, p_dev_info, sizeof(ni_device_info_t));
1203 }
1204 }
1205 ni_rsrc_free_device_context(p_device_context);
1206 }
1207
1208#ifdef _WIN32
1209 // Now we have the device info that has the least load of the FW
1210 // we open this device and assign the FD
1211 if ((handle = ni_device_open2(dev_info.blk_name, NI_DEVICE_READ_WRITE)) ==
1212 NI_INVALID_DEVICE_HANDLE)
1213 {
1215 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1216 {
1218 LRETURN;
1219 }
1220 LRETURN;
1221 } else
1222 {
1223 p_ctx->device_handle = handle;
1224 p_ctx->blk_io_handle = handle;
1225 handle1 = handle;
1226 p_ctx->hw_id = guid;
1229 }
1230#else
1231 //The original design (code below) is to open char and block device file separately. And the ffmpeg will close the device twice.
1232 //However, in I/O version, char device can't be opened. For compatibility, and to avoid errors, open the block device twice.
1233 if (((handle = ni_device_open2(dev_info.dev_name, NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE) ||
1234 ((handle1 = ni_device_open2(dev_info.dev_name, NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE))
1235 {
1237 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1238 {
1240 LRETURN;
1241 }
1242 LRETURN;
1243 }
1244 else
1245 {
1246 p_ctx->device_handle = handle;
1247 p_ctx->blk_io_handle = handle1;
1248 p_ctx->hw_id = guid;
1251 }
1252#endif
1253 }
1254 }
1255 // user passed in the handle, but one of them is invalid, this is error case so we return error
1256 else if((handle1 == NI_INVALID_DEVICE_HANDLE) || (handle == NI_INVALID_DEVICE_HANDLE))
1257 {
1259 LRETURN;
1260 }
1261 // User passed in both handles, so we do not need to allocate for it
1262 else
1263 {
1264 user_handles = true;
1265 }
1266
1267 ni_log2(p_ctx, NI_LOG_DEBUG,
1268 "Finish open the session dev:%s guid:%d handle:%p handle1:%p\n",
1269 p_ctx->dev_xcoder_name, p_ctx->hw_id,
1270 p_ctx->device_handle, p_ctx->blk_io_handle);
1273 // get FW API version
1274 p_device_context = ni_rsrc_get_device_context(device_type, p_ctx->hw_id);
1275 if (p_device_context == NULL)
1276 {
1277 ni_log2(p_ctx, NI_LOG_ERROR,
1278 "ERROR: %s() ni_rsrc_get_device_context() failed\n",
1279 __func__);
1280 if (user_handles != true)
1281 {
1282 if(ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1283 {
1285 LRETURN;
1286 }
1287 }
1289 LRETURN;
1290 }
1291
1292 if (!(strcmp(p_ctx->dev_xcoder_name, "")) || !(strcmp(p_ctx->dev_xcoder_name, NI_BEST_MODEL_LOAD_STR)) ||
1293 !(strcmp(p_ctx->dev_xcoder_name, NI_BEST_REAL_LOAD_STR)))
1294 {
1296 }
1297
1298 memcpy(p_ctx->fw_rev , p_device_context->p_device_info->fw_rev, 8);
1299
1300 ni_rsrc_free_device_context(p_device_context);
1301
1302 retval = ni_device_get_ddr_configuration(p_ctx);
1303 if (retval != NI_RETCODE_SUCCESS)
1304 {
1305 ni_log2(p_ctx, NI_LOG_ERROR,
1306 "ERROR: %s() cannot retrieve DDR configuration\n",
1307 __func__);
1308 if (user_handles != true)
1309 {
1310 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1311 {
1313 LRETURN;
1314 }
1315 }
1316 LRETURN;
1317 }
1318
1319 if (p_ctx->keep_alive_timeout == 0)
1320 {
1321 ni_log2(p_ctx, NI_LOG_ERROR,
1322 "ERROR: %s() keep_alive_timeout was 0, should be between 1-100. "
1323 "Setting to default of %u\n",
1326 }
1327 switch (device_type)
1328 {
1330 {
1331 retval = ni_decoder_session_open(p_ctx);
1332 if (user_handles != true)
1333 {
1334 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1335 {
1337 LRETURN;
1338 }
1339 }
1340 // send keep alive signal thread
1341 if (NI_RETCODE_SUCCESS != retval)
1342 {
1343 LRETURN;
1344 }
1345 break;
1346 }
1348 {
1349#ifndef _WIN32
1350 // p2p is not supported on Windows, so skip following assignments.
1351 ni_xcoder_params_t *p_enc_params;
1352
1353 p_enc_params = p_ctx->p_session_config;
1354
1355 if (p_enc_params && p_enc_params->hwframes &&
1356 p_enc_params->p_first_frame)
1357 {
1358 niFrameSurface1_t *pSurface;
1359 pSurface =
1360 (niFrameSurface1_t *)p_enc_params->p_first_frame->p_data[3];
1361 p_ctx->sender_handle =
1362 (ni_device_handle_t)(int64_t)pSurface->device_handle;
1363 p_enc_params->rootBufId = pSurface->ui16FrameIdx;
1364
1365 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: sender_handle and rootBufId %d set\n",
1366 __func__, p_enc_params->rootBufId);
1367 }
1368#endif
1369
1370 retval = ni_encoder_session_open(p_ctx);
1371 if (user_handles != true)
1372 {
1373 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1374 {
1376 LRETURN;
1377 }
1378 }
1379 // send keep alive signal thread
1380 if (NI_RETCODE_SUCCESS != retval)
1381 {
1382 LRETURN;
1383 }
1384 break;
1385 }
1387 {
1388 retval = ni_uploader_session_open(p_ctx);
1389 if (user_handles != true)
1390 {
1391 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1392 {
1394 LRETURN;
1395 }
1396 }
1397 // send keep alive signal thread
1398 if (NI_RETCODE_SUCCESS != retval)
1399 {
1400 LRETURN;
1401 }
1402 break;
1403 }
1405 {
1406 retval = ni_scaler_session_open(p_ctx);
1407 if (user_handles != true)
1408 {
1409 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1410 {
1412 LRETURN;
1413 }
1414 }
1415 // send keep alive signal thread
1416 if (NI_RETCODE_SUCCESS != retval)
1417 {
1418 LRETURN;
1419 }
1420 break;
1421 }
1422 case NI_DEVICE_TYPE_AI:
1423 {
1424 retval = ni_ai_session_open(p_ctx);
1425 if (user_handles != true)
1426 {
1427 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1428 {
1430 LRETURN;
1431 }
1432 }
1433 // send keep alive signal thread
1434 if (NI_RETCODE_SUCCESS != retval)
1435 {
1436 LRETURN;
1437 }
1438 break;
1439 }
1440 default:
1441 {
1442 if (user_handles != true)
1443 {
1444 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1445 {
1447 LRETURN;
1448 }
1449 }
1450 retval = NI_RETCODE_INVALID_PARAM;
1451 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1452 __func__, device_type);
1453 LRETURN;
1454 }
1455 }
1456
1458 if (!p_ctx->keep_alive_thread_args)
1459 {
1460 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: thread_args allocation failed!\n");
1461 ni_device_session_close(p_ctx, 0, device_type);
1463 LRETURN;
1464 }
1465
1468 p_ctx->keep_alive_thread_args->device_type = device_type;
1471 p_ctx->keep_alive_thread_args->close_thread = false;
1474 p_ctx->keep_alive_thread_args->p_mutex = &p_ctx->mutex;
1475 p_ctx->keep_alive_thread_args->hw_id = p_ctx->hw_id;
1477
1479 sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
1480 {
1481 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: keep alive p_buffer allocation failed!\n");
1482 ni_device_session_close(p_ctx, 0, device_type);
1484 LRETURN;
1485 }
1487
1488 if (0 !=
1491 (void *)p_ctx->keep_alive_thread_args))
1492 {
1493 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to create keep alive thread\n");
1494 p_ctx->keep_alive_thread = (ni_pthread_t){0};
1497 ni_device_session_close(p_ctx, 0, device_type);
1499 LRETURN;
1500 }
1501 ni_log2(p_ctx, NI_LOG_DEBUG, "Enabled keep alive thread\n");
1502
1503 // allocate memory for encoder change data to be reused
1504 p_ctx->enc_change_params = calloc(1, sizeof(ni_encoder_change_params_t));
1505 if (!p_ctx->enc_change_params)
1506 {
1507 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: enc_change_params allocation failed!\n");
1508 ni_device_session_close(p_ctx, 0, device_type);
1510 }
1511
1512END:
1513 ni_device_session_context_free(p_session_context);
1514
1515 if (p_device_pool)
1516 {
1517 ni_rsrc_free_device_pool(p_device_pool);
1518 p_device_pool = NULL;
1519 }
1520
1521 p_ctx->xcoder_state &= ~NI_XCODER_OPEN_STATE;
1522
1524
1525 return retval;
1526}
1527
1528/*!*****************************************************************************
1529 * \brief Close device session that was previously opened by calling
1530 * ni_device_session_open()
1531 * If device_type is NI_DEVICE_TYPE_DECODER closes decoding session
1532 * If device_type is NI_DEVICE_TYPE_ENCODER closes encoding session
1533 * If device_type is NI_DEVICE_TYPE_SCALER closes scaling session
1534 *
1535 * \param[in] p_ctx Pointer to a caller allocated
1536 * ni_session_context_t struct
1537 * \param[in] eos_received Flag indicating if End Of Stream indicator was
1538 * received
1539 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER,
1540 * or NI_DEVICE_TYPE_SCALER
1541 * \return On success
1542 * NI_RETCODE_SUCCESS
1543 * On failure
1544 * NI_RETCODE_INVALID_PARAM
1545 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1546 * NI_RETCODE_ERROR_INVALID_SESSION
1547 ******************************************************************************/
1549 int eos_recieved,
1550 ni_device_type_t device_type)
1551{
1552 int ret;
1554
1555 if (!p_ctx)
1556 {
1557 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1558 __func__);
1560 }
1561
1565
1566#ifdef _WIN32
1567 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args)
1568#else
1569 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args)
1570#endif
1571 {
1572 p_ctx->keep_alive_thread_args->close_thread = true;
1573 ret = ni_pthread_join(p_ctx->keep_alive_thread, NULL);
1574 if (ret)
1575 {
1576 ni_log2(p_ctx, NI_LOG_ERROR,
1577 "join keep alive thread fail! : sid %u ret %d\n",
1578 p_ctx->session_id, ret);
1579 }
1582 } else
1583 {
1584 ni_log2(p_ctx, NI_LOG_ERROR, "invalid keep alive thread: %u\n",
1585 p_ctx->session_id);
1586 }
1587
1588 switch (device_type)
1589 {
1591 {
1592 retval = ni_decoder_session_close(p_ctx, eos_recieved);
1593 break;
1594 }
1596 {
1598 // fall through
1599 }
1601 {
1602 retval = ni_encoder_session_close(p_ctx, eos_recieved);
1603 break;
1604 }
1606 {
1607 retval = ni_scaler_session_close(p_ctx, eos_recieved);
1608 break;
1609 }
1610 case NI_DEVICE_TYPE_AI:
1611 {
1612 retval = ni_ai_session_close(p_ctx, eos_recieved);
1613 break;
1614 }
1615 default:
1616 {
1617 retval = NI_RETCODE_INVALID_PARAM;
1618 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1619 __func__, device_type);
1620 break;
1621 }
1622 }
1623
1625 // need set invalid after closed. May cause open invalid parameters.
1627
1628 ni_memfree(p_ctx->p_hdr_buf);
1629 ni_memfree(p_ctx->av_rois);
1630 ni_memfree(p_ctx->roi_map);
1631 ni_memfree(p_ctx->avc_roi_map);
1632 ni_memfree(p_ctx->hevc_roi_map);
1636 p_ctx->hdr_buf_size = 0;
1637 p_ctx->roi_side_data_size = 0;
1638 p_ctx->nb_rois = 0;
1639 p_ctx->target_bitrate = -1;
1640 p_ctx->force_idr_frame = 0;
1642 p_ctx->ltr_to_set.use_long_term_ref = 0;
1643 p_ctx->ltr_interval = -1;
1644 p_ctx->ltr_frame_ref_invalid = -1;
1645 p_ctx->max_frame_size = 0;
1646 p_ctx->reconfig_crf = -1;
1647 p_ctx->reconfig_crf_decimal = 0;
1648 p_ctx->reconfig_vbv_buffer_size = 0;
1649 p_ctx->reconfig_vbv_max_rate = 0;
1650 p_ctx->last_gop_size = 0;
1651 p_ctx->initial_frame_delay = 0;
1652 p_ctx->current_frame_delay = 0;
1653 p_ctx->max_frame_delay = 0;
1654 p_ctx->av1_pkt_num = 0;
1655 p_ctx->reconfig_intra_period = -1;
1656 p_ctx->reconfig_slice_arg = 0;
1657
1658 p_ctx->xcoder_state &= ~NI_XCODER_CLOSE_STATE;
1660
1661 return retval;
1662}
1663
1664/*!*****************************************************************************
1665 * \brief Send a flush command to the device
1666 * If device_type is NI_DEVICE_TYPE_DECODER sends EOS command to
1667 * decoder
1668 * If device_type is NI_DEVICE_TYPE_ENCODER sends EOS command to
1669 * encoder
1670 *
1671 * \param[in] p_ctx Pointer to a caller allocated
1672 * ni_session_context_t struct
1673 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1674 * \return On success
1675 * NI_RETCODE_SUCCESS
1676 * On failure
1677 * NI_RETCODE_INVALID_PARAM
1678 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1679 * NI_RETCODE_ERROR_INVALID_SESSION
1680 ******************************************************************************/
1682{
1684 if (!p_ctx)
1685 {
1686 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1687 __func__);
1689 }
1690
1693
1694 switch (device_type)
1695 {
1697 {
1698 retval = ni_decoder_session_send_eos(p_ctx);
1699 break;
1700 }
1702 {
1703 retval = ni_encoder_session_send_eos(p_ctx);
1704 break;
1705 }
1706 default:
1707 {
1708 retval = NI_RETCODE_INVALID_PARAM;
1709 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1710 __func__, device_type);
1711 break;
1712 }
1713 }
1714 p_ctx->ready_to_close = (NI_RETCODE_SUCCESS == retval);
1715 p_ctx->xcoder_state &= ~NI_XCODER_FLUSH_STATE;
1717 return retval;
1718}
1719
1720/*!*****************************************************************************
1721 * \brief Save a stream's headers in a decoder session that can be used later
1722 * for continuous decoding from the same source.
1723 *
1724 * \param[in] p_ctx Pointer to a caller allocated
1725 * ni_session_context_t struct
1726 * \param[in] hdr_data Pointer to header data
1727 * \param[in] hdr_size Size of header data in bytes
1728 * \return On success
1729 * NI_RETCODE_SUCCESS
1730 * On failure
1731 * NI_RETCODE_INVALID_PARAM
1732 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1733 * NI_RETCODE_ERROR_INVALID_SESSION
1734 ******************************************************************************/
1736 uint8_t *hdr_data,
1737 uint8_t hdr_size)
1738{
1740
1741 if (!p_ctx)
1742 {
1743 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s p_ctx null, return\n", __func__);
1745 }
1746
1747 if (!hdr_data)
1748 {
1749 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s hdr_data null, return\n", __func__);
1751 } else if (p_ctx->p_hdr_buf && p_ctx->hdr_buf_size == hdr_size &&
1752 0 == memcmp(p_ctx->p_hdr_buf, hdr_data, hdr_size))
1753 {
1754 // no change from the saved headers, success !
1755 return retval;
1756 }
1757
1758 // update the saved header data
1759 free(p_ctx->p_hdr_buf);
1760 p_ctx->hdr_buf_size = 0;
1761 p_ctx->p_hdr_buf = malloc(hdr_size);
1762 if (p_ctx->p_hdr_buf)
1763 {
1764 memcpy(p_ctx->p_hdr_buf, hdr_data, hdr_size);
1765 p_ctx->hdr_buf_size = hdr_size;
1766 ni_log2(p_ctx, NI_LOG_DEBUG, "%s saved hdr size %u\n", __func__,
1767 p_ctx->hdr_buf_size);
1768 } else
1769 {
1771 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s no memory.\n", __func__);
1772 }
1773 return retval;
1774}
1775
1776/*!*****************************************************************************
1777 * \brief Flush a decoder session to get ready to continue decoding.
1778 * Note: this is different from ni_device_session_flush in that it closes the
1779 * current decode session and opens a new one for continuous decoding.
1780 *
1781 * \param[in] p_ctx Pointer to a caller allocated
1782 * ni_session_context_t struct
1783 * \return On success
1784 * NI_RETCODE_SUCCESS
1785 * On failure
1786 * NI_RETCODE_INVALID_PARAM
1787 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1788 * NI_RETCODE_ERROR_INVALID_SESSION
1789 ******************************************************************************/
1791{
1793
1794 if (!p_ctx)
1795 {
1796 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s ctx null, return\n", __func__);
1798 }
1800 retval = ni_decoder_session_flush(p_ctx);
1801 if (NI_RETCODE_SUCCESS == retval) {
1802 p_ctx->ready_to_close = 0;
1803 }
1805 return retval;
1806}
1807
1808/*!*****************************************************************************
1809 * \brief Sends data to the device
1810 * If device_type is NI_DEVICE_TYPE_DECODER sends data packet to
1811 * decoder
1812 * If device_type is NI_DEVICE_TYPE_ENCODER sends data frame to encoder
1813 * If device_type is NI_DEVICE_TYPE_AI sends data frame to ai engine
1814 *
1815 * \param[in] p_ctx Pointer to a caller allocated
1816 * ni_session_context_t struct
1817 * \param[in] p_data Pointer to a caller allocated
1818 * ni_session_data_io_t struct which contains either a
1819 * ni_frame_t data frame or ni_packet_t data packet to
1820 * send
1821 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER or
1822 * NI_DEVICE_TYPE_AI
1823 * If NI_DEVICE_TYPE_DECODER is specified, it is
1824 * expected that the ni_packet_t struct inside the
1825 * p_data pointer contains data to send.
1826 * If NI_DEVICE_TYPE_ENCODER or NI_DEVICE_TYPE_AI is
1827 * specified, it is expected that the ni_frame_t
1828 * struct inside the p_data pointer contains data to
1829 * send.
1830 * \return On success
1831 * Total number of bytes written
1832 * On failure
1833 * NI_RETCODE_INVALID_PARAM
1834 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1835 * NI_RETCODE_ERROR_INVALID_SESSION
1836 ******************************************************************************/
1838{
1840
1841 if (!p_ctx || !p_data)
1842 {
1843 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1844 __func__);
1846 }
1847 // Here check if keep alive thread is closed.
1848#ifdef _WIN32
1849 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
1851#else
1852 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
1854#endif
1855 {
1856 ni_log2(p_ctx, NI_LOG_ERROR,
1857 "ERROR: %s() keep alive thread has been closed, "
1858 "hw:%d, session:%d\n",
1859 __func__, p_ctx->hw_id, p_ctx->session_id);
1861 }
1862
1864 // In close state, let the close process execute first.
1866 {
1867 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
1869 ni_usleep(100);
1871 }
1874
1875 switch (device_type)
1876 {
1878 {
1879 retval = ni_decoder_session_write(p_ctx, &(p_data->data.packet));
1880 break;
1881 }
1883 {
1884 retval = ni_encoder_session_write(p_ctx, &(p_data->data.frame));
1885 break;
1886 }
1887 case NI_DEVICE_TYPE_AI:
1888 {
1889 retval = ni_ai_session_write(p_ctx, &(p_data->data.frame));
1890 break;
1891 }
1892 default:
1893 {
1894 retval = NI_RETCODE_INVALID_PARAM;
1895 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1896 __func__, device_type);
1897 break;
1898 }
1899 }
1900
1902 p_ctx->xcoder_state &= ~NI_XCODER_WRITE_STATE;
1904 return retval;
1905}
1906
1907/*!*****************************************************************************
1908 * \brief Read data from the device
1909 * If device_type is NI_DEVICE_TYPE_DECODER reads data packet from
1910 * decoder
1911 * If device_type is NI_DEVICE_TYPE_ENCODER reads data frame from
1912 * encoder
1913 * If device_type is NI_DEVICE_TYPE_AI reads data frame from AI engine
1914 *
1915 * \param[in] p_ctx Pointer to a caller allocated
1916 * ni_session_context_t struct
1917 * \param[in] p_data Pointer to a caller allocated ni_session_data_io_t
1918 * struct which contains either a ni_frame_t data frame
1919 * or ni_packet_t data packet to send
1920 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER, or
1921 * NI_DEVICE_TYPE_SCALER
1922 * If NI_DEVICE_TYPE_DECODER is specified, data that
1923 * was read will be placed into ni_frame_t struct
1924 * inside the p_data pointer
1925 * If NI_DEVICE_TYPE_ENCODER is specified, data that
1926 * was read will be placed into ni_packet_t struct
1927 * inside the p_data pointer
1928 * If NI_DEVICE_TYPE_AI is specified, data that was
1929 * read will be placed into ni_frame_t struct inside
1930 * the p_data pointer
1931 * \return On success
1932 * Total number of bytes read
1933 * On failure
1934 * NI_RETCODE_INVALID_PARAM
1935 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1936 * NI_RETCODE_ERROR_INVALID_SESSION
1937 ******************************************************************************/
1939{
1941 if ((!p_ctx) || (!p_data))
1942 {
1943 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1944 __func__);
1946 }
1947
1948 // Here check if keep alive thread is closed.
1949#ifdef _WIN32
1950 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
1952#else
1953 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
1955#endif
1956 {
1957 ni_log2(p_ctx, NI_LOG_ERROR,
1958 "ERROR: %s() keep alive thread has been closed, "
1959 "hw:%d, session:%d\n",
1960 __func__, p_ctx->hw_id, p_ctx->session_id);
1962 }
1963
1965 // In close state, let the close process execute first.
1967 {
1968 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
1970 ni_usleep(100);
1972 }
1975
1976 switch (device_type)
1977 {
1979 {
1980 int seq_change_read_count = 0;
1981 p_data->data.frame.src_codec = p_ctx->codec_format;
1982 for (;;)
1983 {
1984 retval = ni_decoder_session_read(p_ctx, &(p_data->data.frame));
1985 // check resolution change only after initial setting obtained
1986 // p_data->data.frame.video_width is picture width and will be 32-align
1987 // adjusted to frame size; p_data->data.frame.video_height is the same as
1988 // frame size, then compare them to saved one for resolution checking
1989 //
1990 uint32_t aligned_width;
1991 if(QUADRA)
1992 {
1993 aligned_width = ((((p_data->data.frame.video_width * p_ctx->bit_depth_factor) + 127) / 128) * 128);
1994 }
1995 else
1996 {
1997 aligned_width = ((p_data->data.frame.video_width + 31) / 32) * 32;
1998 }
1999
2000 if (0 == retval && seq_change_read_count)
2001 {
2002 ni_log2(p_ctx, NI_LOG_DEBUG,
2003 "%s (decoder): seq change NO data, next time.\n", __func__);
2004 p_ctx->active_video_width = 0;
2005 p_ctx->active_video_height = 0;
2006 p_ctx->actual_video_width = 0;
2007 break;
2008 }
2009 else if (retval < 0)
2010 {
2011 ni_log2(p_ctx, NI_LOG_ERROR, "%s (decoder): failure ret %d, return ..\n",
2012 __func__, retval);
2013 break;
2014 }
2015 // aligned_width may equal to active_video_width if bit depth and width
2016 // are changed at the same time. So, check video_width != actual_video_width.
2017 else if (p_ctx->frame_num && (p_ctx->pixel_format_changed ||
2018 (p_data->data.frame.video_width &&
2019 p_data->data.frame.video_height &&
2020 (aligned_width != p_ctx->active_video_width ||
2021 p_data->data.frame.video_height != p_ctx->active_video_height))))
2022 {
2023 ni_log2(
2024 p_ctx, NI_LOG_DEBUG,
2025 "%s (decoder): resolution change, frame size %ux%u -> %ux%u, "
2026 "width %u bit %d, pix_fromat_changed %d, actual_video_width %d, continue read ...\n",
2027 __func__, p_ctx->active_video_width, p_ctx->active_video_height,
2028 aligned_width, p_data->data.frame.video_height,
2029 p_data->data.frame.video_width, p_ctx->bit_depth_factor,
2031 // reset active video resolution to 0 so it can be queried in the re-read
2032 p_ctx->active_video_width = 0;
2033 p_ctx->active_video_height = 0;
2034 p_ctx->actual_video_width = 0;
2035 seq_change_read_count++;
2036 }
2037 else
2038 {
2039 break;
2040 }
2041 }
2042 break;
2043 }
2045 {
2046 retval = ni_encoder_session_read(p_ctx, &(p_data->data.packet));
2047 break;
2048 }
2049 case NI_DEVICE_TYPE_AI:
2050 {
2051 retval = ni_ai_session_read(p_ctx, &(p_data->data.packet));
2052 break;
2053 }
2054 default:
2055 {
2056 retval = NI_RETCODE_INVALID_PARAM;
2057 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2058 __func__, device_type);
2059 break;
2060 }
2061 }
2062
2064 p_ctx->xcoder_state &= ~NI_XCODER_READ_STATE;
2066 return retval;
2067}
2068
2069/*!*****************************************************************************
2070 * \brief Query session data from the device -
2071 * If device_type is valid, will query session data
2072 * from specified device type
2073 *
2074 * \param[in] p_ctx Pointer to a caller allocated
2075 * ni_session_context_t struct
2076 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2077 * NI_DEVICE_TYPE_ENCODER or
2078 * NI_DEVICE_TYPE_SCALER or
2079 * NI_DEVICE_TYPE_AI or
2080 * NI_DEVICE_TYPE_UPLOADER
2081 *
2082 * \return On success
2083 * NI_RETCODE_SUCCESS
2084 * On failure
2085 * NI_RETCODE_INVALID_PARAM
2086 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2087 * NI_RETCODE_ERROR_INVALID_SESSION
2088 ******************************************************************************/
2090{
2092 if (!p_ctx)
2093 {
2094 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2095 __func__);
2097 }
2098
2099 if (IS_XCODER_DEVICE_TYPE(device_type))
2100 {
2101 retval = ni_xcoder_session_query(p_ctx, device_type);
2102 } else
2103 {
2104 retval = NI_RETCODE_INVALID_PARAM;
2105 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2106 __func__, device_type);
2107 }
2108
2109 return retval;
2110}
2111
2112/*!*****************************************************************************
2113 * \brief Query detail session data from the device -
2114 * If device_type is valid, will query session data
2115 * from specified device type
2116 *
2117 * \param[in] p_ctx Pointer to a caller allocated
2118 * ni_session_context_t struct
2119 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2120 * NI_DEVICE_TYPE_ENCODER or
2121 *
2122 * \return On success
2123 * NI_RETCODE_SUCCESS
2124 * On failure
2125 * NI_RETCODE_INVALID_PARAM
2126 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2127 * NI_RETCODE_ERROR_INVALID_SESSION
2128 ******************************************************************************/
2130{
2132 if (!p_ctx)
2133 {
2134 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2135 __func__);
2137 }
2138
2139 if (IS_XCODER_DEVICE_TYPE(device_type))
2140 {
2141 retval = ni_xcoder_session_query_detail(p_ctx, device_type, detail_data, 0);
2142 } else
2143 {
2144 retval = NI_RETCODE_INVALID_PARAM;
2145 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2146 __func__, device_type);
2147 }
2148
2149 return retval;
2150}
2151
2152/*!*****************************************************************************
2153 * \brief Query detail session data from the device -
2154 * If device_type is valid, will query session data
2155 * from specified device type
2156 *
2157 * \param[in] p_ctx Pointer to a caller allocated
2158 * ni_session_context_t struct
2159 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2160 * NI_DEVICE_TYPE_ENCODER or
2161 *
2162 * \return On success
2163 * NI_RETCODE_SUCCESS
2164 * On failure
2165 * NI_RETCODE_INVALID_PARAM
2166 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2167 * NI_RETCODE_ERROR_INVALID_SESSION
2168 ******************************************************************************/
2170{
2172 if (!p_ctx)
2173 {
2174 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2175 __func__);
2177 }
2178
2179 if (IS_XCODER_DEVICE_TYPE(device_type))
2180 {
2181 retval = ni_xcoder_session_query_detail(p_ctx, device_type, detail_data, 1);
2182 } else
2183 {
2184 retval = NI_RETCODE_INVALID_PARAM;
2185 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2186 __func__, device_type);
2187 }
2188
2189 return retval;
2190}
2191
2192/*!*****************************************************************************
2193 * \brief Send namespace num and SRIOv index to the device with specified logic block
2194 * address.
2195 *
2196 * \param[in] device_handle Device handle obtained by calling ni_device_open
2197 * \param[in] namespace_num Set the namespace number with designated sriov
2198 * \param[in] sriov_index Identify which sriov need to be set
2199 *
2200 * \return On success
2201 * NI_RETCODE_SUCCESS
2202 * On failure
2203 * NI_RETCODE_ERROR_MEM_ALOC
2204 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2205 ******************************************************************************/
2206ni_retcode_t ni_device_config_namespace_num(ni_device_handle_t device_handle,
2207 uint32_t namespace_num, uint32_t sriov_index)
2208{
2209 ni_log(NI_LOG_DEBUG, "%s namespace_num %u sriov_index %u\n",
2210 __func__, namespace_num, sriov_index);
2211 return ni_device_config_ns_qos(device_handle, namespace_num, sriov_index);
2212}
2213
2214/*!*****************************************************************************
2215 * \brief Send qos mode to the device with specified logic block
2216 * address.
2217 *
2218 * \param[in] device_handle Device handle obtained by calling ni_device_open
2219 * \param[in] mode The requested qos mode
2220 *
2221 * \return On success
2222 * NI_RETCODE_SUCCESS
2223 * On failure
2224 * NI_RETCODE_ERROR_MEM_ALOC
2225 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2226 ******************************************************************************/
2227ni_retcode_t ni_device_config_qos(ni_device_handle_t device_handle,
2228 uint32_t mode)
2229{
2230 ni_log(NI_LOG_DEBUG, "%s device_handle %p mode %u\n",
2231 __func__, device_handle, mode);
2232 return ni_device_config_ns_qos(device_handle, QOS_NAMESPACE_CODE, mode);
2233}
2234
2235/*!*****************************************************************************
2236 * \brief Send qos over provisioning mode to target namespace with specified logic
2237 * block address.
2238 *
2239 * \param[in] device_handle Device handle obtained by calling ni_device_open
2240 * \param[in] device_handle_t Target device handle of namespace required for OP
2241 * \param[in] over_provision The request overprovision percent
2242 *
2243 * \return On success
2244 * NI_RETCODE_SUCCESS
2245 * On failure
2246 * NI_RETCODE_ERROR_MEM_ALOC
2247 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2248 ******************************************************************************/
2249ni_retcode_t ni_device_config_qos_op(ni_device_handle_t device_handle,
2250 ni_device_handle_t device_handle_t,
2251 uint32_t over_provision)
2252{
2253 ni_retcode_t retval;
2254 float f_over_provision = 0;
2255 memcpy(&f_over_provision, &over_provision, sizeof(int32_t));
2256 ni_log(NI_LOG_DEBUG, "%s device_handle %p target %p over_provision %f\n",
2257 __func__, device_handle, device_handle_t, f_over_provision);
2258 retval = ni_device_config_ns_qos(device_handle, QOS_OP_CONFIG_REC_OP_CODE,
2259 over_provision);
2260 if (NI_RETCODE_SUCCESS != retval)
2261 {
2262 return retval;
2263 }
2264 retval = ni_device_config_ns_qos(device_handle_t, QOS_OP_CONFIG_CODE,
2265 0);
2266 return retval;
2267}
2268
2269/*!*****************************************************************************
2270 * \brief Set QoS allowance for a specific namespace
2271 *
2272 * \param[in] device_handle Device handle obtained by calling ni_device_open
2273 * \param[in] device_handle_t Target device handle of namespace required for allowance
2274 * \param[in] allowance Allowance percentage (0.0-100.0)
2275 *
2276 * \return On success
2277 * NI_RETCODE_SUCCESS
2278 * On failure
2279 * NI_RETCODE_ERROR_MEM_ALOC
2280 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2281 ******************************************************************************/
2282ni_retcode_t ni_device_config_qos_allowance(ni_device_handle_t device_handle,
2283 ni_device_handle_t device_handle_t,
2284 uint32_t allowance)
2285{
2286 ni_retcode_t retval;
2287 float f_allowance = 0;
2288 memcpy(&f_allowance, &allowance, sizeof(int32_t));
2289 ni_log(NI_LOG_DEBUG, "%s device_handle %p target %p allowance %f\n",
2290 __func__, device_handle, device_handle_t, f_allowance);
2292 allowance);
2293 if (NI_RETCODE_SUCCESS != retval)
2294 {
2295 return retval;
2296 }
2297 retval = ni_device_config_ns_qos(device_handle_t, QOS_ALLOW_CONFIG_CODE,
2298 0);
2299 return retval;
2300}
2301
2302
2303/*!*****************************************************************************
2304 * \brief Allocate preliminary memory for the frame buffer based on provided
2305 * parameters. Applicable to YUV420 Planar pixel (8 or 10 bit/pixel)
2306 * format or 32-bit RGBA.
2307 *
2308 * \param[in] p_frame Pointer to a caller allocated
2309 * ni_frame_t struct
2310 * \param[in] video_width Width of the video frame
2311 * \param[in] video_height Height of the video frame
2312 * \param[in] alignment Allignment requirement
2313 * \param[in] metadata_flag Flag indicating if space for additional metadata
2314 * should be allocated
2315 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel,
2316 * 4 for 32 bits/pixel (RGBA)
2317 * \param[in] hw_frame_count Number of hw descriptors stored
2318 * \param[in] is_planar 0 if semiplanar else planar
2319 *
2320 * \return On success
2321 * NI_RETCODE_SUCCESS
2322 * On failure
2323 * NI_RETCODE_INVALID_PARAM
2324 * NI_RETCODE_ERROR_MEM_ALOC
2325 ******************************************************************************/
2327 int video_height, int alignment,
2328 int metadata_flag, int factor,
2329 int hw_frame_count, int is_planar)
2330{
2331 void* p_buffer = NULL;
2332 int metadata_size = 0;
2333 int retval = NI_RETCODE_SUCCESS;
2334 int width_aligned = video_width;
2335 int height_aligned = video_height;
2336
2337 if ((!p_frame) || ((factor!=1) && (factor!=2) && (factor !=4))
2338 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
2339 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
2340 {
2341 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2342 "factor %d, video_width %d, video_height %d\n",
2343 __func__, factor, video_width, video_height);
2345 }
2346
2347 if (metadata_flag)
2348 {
2349 metadata_size = NI_FW_META_DATA_SZ + NI_MAX_SEI_DATA;
2350 }
2351
2352 if (QUADRA)
2353 {
2354 switch (factor)
2355 {
2356 case 1: /* 8-bit YUV420 */
2357 case 2: /* 10-bit YUV420 */
2358 width_aligned = ((((video_width * factor) + 127) / 128) * 128) / factor;
2359 height_aligned = ((video_height + 1) / 2) * 2;
2360 break;
2361 case 4: /* 32-bit RGBA */
2362 //64byte aligned => 16 rgba pixels
2363 width_aligned = NI_VPU_ALIGN16(video_width);
2364 height_aligned = ((video_height + 1) / 2) * 2;
2365 break;
2366 default:
2368 }
2369 }
2370 else
2371 {
2372 width_aligned = ((video_width + 31) / 32) * 32;
2373 height_aligned = ((video_height + 7) / 8) * 8;
2374 if (alignment)
2375 {
2376 height_aligned = ((video_height + 15) / 16) * 16;
2377 }
2378 }
2379
2380 int luma_size = width_aligned * height_aligned * factor;
2381 int chroma_b_size;
2382 int chroma_r_size;
2383 if (QUADRA)
2384 {
2385 int chroma_width_aligned = ((((video_width / 2 * factor) + 127) / 128) * 128) / factor;
2386 if (is_planar == NI_PIXEL_PLANAR_FORMAT_TILED4X4 ||
2388 {
2389 chroma_width_aligned =
2390 ((((video_width * factor) + 127) / 128) * 128) / factor;
2391 }
2392 int chroma_height_aligned = height_aligned / 2;
2393 chroma_b_size = chroma_r_size = chroma_width_aligned * chroma_height_aligned * factor;
2394 if (is_planar == NI_PIXEL_PLANAR_FORMAT_TILED4X4 ||
2396 {
2397 chroma_r_size = 0;
2398 }
2399 if (4 == factor)
2400 {
2401 chroma_b_size = chroma_r_size = 0;
2402 }
2403 //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);
2404 }
2405 else
2406 {
2407 chroma_b_size = luma_size / 4;
2408 chroma_r_size = chroma_b_size;
2409 }
2410 int buffer_size;
2411
2412 /* if hw_frame_count is zero, this is a software frame */
2413 if (hw_frame_count == 0)
2414 buffer_size = luma_size + chroma_b_size + chroma_r_size + metadata_size;
2415 else
2416 buffer_size =
2417 (int)sizeof(niFrameSurface1_t) * hw_frame_count + metadata_size;
2418
2419 // added 2 blocks of 512 bytes buffer space to handle any extra metadata
2420 // retrieval from fw
2421 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT + NI_MEM_PAGE_ALIGNMENT * 3;
2422 //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);
2423
2424 //Check if need to free
2425 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
2426 {
2428 "%s: free current p_frame, p_frame->buffer_size=%u\n", __func__,
2429 p_frame->buffer_size);
2430 ni_frame_buffer_free(p_frame);
2431 }
2432
2433 //Check if need to realocate
2434 if (p_frame->buffer_size != buffer_size)
2435 {
2436 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
2437 {
2438 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
2439 NI_ERRNO, __func__);
2441 LRETURN;
2442 }
2443
2444 // init once after allocation
2445 //memset(p_buffer, 0, buffer_size);
2446 p_frame->buffer_size = buffer_size;
2447 p_frame->p_buffer = p_buffer;
2448
2449 ni_log(NI_LOG_DEBUG, "%s: Allocate new p_frame buffer\n", __func__);
2450 }
2451 else
2452 {
2453 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
2454 }
2455
2456 if (hw_frame_count)
2457 {
2458 p_frame->data_len[0] = 0;
2459 p_frame->data_len[1] = 0;
2460 p_frame->data_len[2] = 0;
2461 p_frame->data_len[3] = sizeof(niFrameSurface1_t)*hw_frame_count;
2462 }
2463 else
2464 {
2465 p_frame->data_len[0] = luma_size;
2466 p_frame->data_len[1] = chroma_b_size;
2467 p_frame->data_len[2] = chroma_r_size;
2468 p_frame->data_len[3] = 0;//unused by hwdesc
2469 }
2470
2471 p_frame->p_data[0] = p_frame->p_buffer;
2472 p_frame->p_data[1] = p_frame->p_data[0] + p_frame->data_len[0];
2473 p_frame->p_data[2] = p_frame->p_data[1] + p_frame->data_len[1];
2474 p_frame->p_data[3] = p_frame->p_data[2] + p_frame->data_len[2]; //hwdescriptor
2475
2476 // init p_data[3] to 0 so that ni_frame_buffer_free frees only valid DMA buf
2477 // fd in hw frame read from fw
2478 if (hw_frame_count)
2479 {
2480 memset(p_frame->p_data[3], 0, sizeof(niFrameSurface1_t) * hw_frame_count);
2481 }
2482
2483 p_frame->video_width = width_aligned;
2484 p_frame->video_height = height_aligned;
2485
2486 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);
2487 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2488 p_frame->buffer_size);
2489
2490END:
2491
2492 if (NI_RETCODE_SUCCESS != retval)
2493 {
2494 ni_aligned_free(p_buffer);
2495 }
2496
2497 return retval;
2498}
2499
2500/*!*****************************************************************************
2501 * \brief Wrapper function for ni_frame_buffer_alloc. Meant to handle RGBA min.
2502 * resoulution considerations for encoder.
2503 *
2504 * \param[in] p_frame Pointer to a caller allocated
2505 * ni_frame_t struct
2506 * \param[in] video_width Width of the video frame
2507 * \param[in] video_height Height of the video frame
2508 * \param[in] alignment Allignment requirement
2509 * \param[in] metadata_flag Flag indicating if space for additional metadata
2510 * should be allocated
2511 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel,
2512 * 4 for 32 bits/pixel (RGBA)
2513 * \param[in] hw_frame_count Number of hw descriptors stored
2514 * \param[in] is_planar 0 if semiplanar else planar
2515 * \param[in] pix_fmt pixel format to distinguish between planar types
2516 * and/or components
2517 *
2518 * \return On success
2519 * NI_RETCODE_SUCCESS
2520 * On failure
2521 * NI_RETCODE_INVALID_PARAM
2522 * NI_RETCODE_ERROR_MEM_ALOC
2523 ******************************************************************************/
2525 int video_height, int alignment,
2526 int metadata_flag, int factor,
2527 int hw_frame_count, int is_planar,
2528 ni_pix_fmt_t pix_fmt)
2529{
2530 int extra_len = 0;
2531 int dst_stride[NI_MAX_NUM_DATA_POINTERS] = {0};
2532 int height_aligned[NI_MAX_NUM_DATA_POINTERS] = {0};
2533
2534 if (((factor!=1) && (factor!=2) && (factor !=4))
2535 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
2536 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
2537 {
2538 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2539 "factor %d, video_width %d, video_height %d\n",
2540 __func__, factor, video_width, video_height);
2542 }
2543
2544 switch (pix_fmt)
2545 {
2546 case NI_PIX_FMT_YUV420P:
2548 case NI_PIX_FMT_NV12:
2549 case NI_PIX_FMT_P010LE:
2550 case NI_PIX_FMT_NV16:
2551 case NI_PIX_FMT_YUYV422:
2552 case NI_PIX_FMT_UYVY422:
2553 case NI_PIX_FMT_ARGB:
2554 case NI_PIX_FMT_ABGR:
2555 case NI_PIX_FMT_RGBA:
2556 case NI_PIX_FMT_BGRA:
2557 case NI_PIX_FMT_BGR0:
2558 break;
2559 default:
2560 ni_log(NI_LOG_ERROR, "ERROR: %s pix_fmt %d not supported \n",
2561 __func__, pix_fmt);
2563 }
2564 //Get stride info for original resolution
2565 ni_get_frame_dim(video_width, video_height,
2566 pix_fmt,
2567 dst_stride, height_aligned);
2568
2569 if (metadata_flag)
2570 {
2571 extra_len = NI_FW_META_DATA_SZ + NI_MAX_SEI_DATA;
2572 }
2573
2574 return ni_frame_buffer_alloc_pixfmt(p_frame, pix_fmt, video_width,
2575 video_height, dst_stride, alignment,
2576 extra_len);
2577}
2578
2579/*!*****************************************************************************
2580 * \brief Allocate preliminary memory for the frame buffer based on provided
2581 * parameters.
2582 *
2583 * \param[in] p_frame Pointer to a caller allocated
2584 * ni_frame_t struct
2585 * \param[in] video_width Width of the video frame
2586 * \param[in] video_height Height of the video frame
2587 * \param[in] alignment Allignment requirement
2588 * \param[in] pixel_format Format for input
2589 *
2590 * \return On success
2591 * NI_RETCODE_SUCCESS
2592 * On failure
2593 * NI_RETCODE_INVALID_PARAM
2594 * NI_RETCODE_ERROR_MEM_ALOC
2595 ******************************************************************************/
2597 int video_height, int pixel_format)
2598{
2599 void *p_buffer = NULL;
2600 int retval = NI_RETCODE_SUCCESS;
2601 int width_aligned = video_width;
2602 int height_aligned = video_height;
2603 int buffer_size;
2604 int luma_size;
2605 int chroma_b_size;
2606 int chroma_r_size;
2607
2608 if ((!p_frame) || (video_width > NI_MAX_RESOLUTION_WIDTH) ||
2609 (video_width <= 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT) ||
2610 (video_height <= 0))
2611 {
2613 "ERROR: %s passed parameters are null or not supported, "
2614 "video_width %d, video_height %d\n",
2615 __func__, video_width, video_height);
2617 }
2618
2619 switch (pixel_format)
2620 {
2621 case NI_PIX_FMT_YUV420P:
2622 width_aligned = NI_VPU_ALIGN128(video_width);
2623 height_aligned = NI_VPU_CEIL(video_height, 2);
2624
2625 luma_size = width_aligned * height_aligned;
2626 chroma_b_size =
2627 NI_VPU_ALIGN128(video_width / 2) * height_aligned / 2;
2628 chroma_r_size = chroma_b_size;
2629 break;
2631 width_aligned = NI_VPU_ALIGN128(video_width * 2) / 2;
2632 height_aligned = NI_VPU_CEIL(video_height, 2);
2633
2634 luma_size = width_aligned * height_aligned * 2;
2635 chroma_b_size = NI_VPU_ALIGN128(video_width) * height_aligned / 2;
2636 chroma_r_size = chroma_b_size;
2637 break;
2638 case NI_PIX_FMT_NV12:
2639 width_aligned = NI_VPU_ALIGN128(video_width);
2640 height_aligned = NI_VPU_CEIL(video_height, 2);
2641
2642 luma_size = width_aligned * height_aligned;
2643 chroma_b_size = width_aligned * height_aligned / 2;
2644 chroma_r_size = 0;
2645 break;
2646 case NI_PIX_FMT_P010LE:
2647 width_aligned = NI_VPU_ALIGN128(video_width * 2) / 2;
2648 height_aligned = NI_VPU_CEIL(video_height, 2);
2649
2650 luma_size = width_aligned * height_aligned * 2;
2651 chroma_b_size = width_aligned * height_aligned;
2652 chroma_r_size = 0;
2653 break;
2654 case NI_PIX_FMT_NV16:
2655 width_aligned = NI_VPU_ALIGN64(video_width);
2656 height_aligned = video_height;
2657
2658 luma_size = width_aligned * height_aligned;
2659 chroma_b_size = luma_size;
2660 chroma_r_size = 0;
2661 break;
2662 case NI_PIX_FMT_YUYV422:
2663 case NI_PIX_FMT_UYVY422:
2664 width_aligned = NI_VPU_ALIGN16(video_width);
2665 height_aligned = video_height;
2666
2667 luma_size = width_aligned * height_aligned * 2;
2668 chroma_b_size = 0;
2669 chroma_r_size = 0;
2670 break;
2671 case NI_PIX_FMT_RGBA:
2672 case NI_PIX_FMT_BGRA:
2673 case NI_PIX_FMT_ARGB:
2674 case NI_PIX_FMT_ABGR:
2675 case NI_PIX_FMT_BGR0:
2676 width_aligned = NI_VPU_ALIGN16(video_width);
2677 height_aligned = video_height;
2678
2679 luma_size = width_aligned * height_aligned * 4;
2680 chroma_b_size = 0;
2681 chroma_r_size = 0;
2682 break;
2683 case NI_PIX_FMT_BGRP:
2684 width_aligned = NI_VPU_ALIGN32(video_width);
2685 height_aligned = video_height;
2686
2687 luma_size = width_aligned * height_aligned;
2688 chroma_b_size = luma_size;
2689 chroma_r_size = luma_size;
2690 break;
2691 default:
2692 ni_log(NI_LOG_ERROR, "Unknown pixel format %d\n", pixel_format);
2694 }
2695
2696 /* Allocate local memory to hold a software ni_frame */
2697 buffer_size = luma_size + chroma_b_size + chroma_r_size;
2698
2699 /* Round up to nearest 4K block */
2700 buffer_size = NI_VPU_ALIGN4096(buffer_size);
2701
2702 ni_log(NI_LOG_DEBUG, "%s: Rlen %d Glen %d Blen %d buffer_size %d\n",
2703 __func__, luma_size, chroma_b_size, chroma_r_size, buffer_size);
2704
2705 /* If the frame has changed, reallocate it */
2706 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
2707 {
2709 "%s: free current p_frame, p_frame->buffer_size=%u\n", __func__,
2710 p_frame->buffer_size);
2711 ni_frame_buffer_free(p_frame);
2712 }
2713
2714 /* Check if need to reallocate */
2715 if (p_frame->buffer_size != buffer_size)
2716 {
2717 ni_log(NI_LOG_DEBUG, "%s: Allocate new p_frame buffer\n", __func__);
2718 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
2719 {
2721 "ERROR %d: %s() Cannot allocate p_frame buffer.\n", NI_ERRNO,
2722 __func__);
2724 LRETURN;
2725 }
2726 } else
2727 {
2728 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
2729 p_buffer = p_frame->p_buffer;
2730 }
2731
2732 // init once after allocation
2733 // memset(p_buffer, 0, buffer_size);
2734
2735 p_frame->buffer_size = buffer_size;
2736 p_frame->p_buffer = p_buffer;
2737
2738 p_frame->data_len[0] = luma_size;
2739 p_frame->data_len[1] = chroma_b_size;
2740 p_frame->data_len[2] = chroma_r_size;
2741 p_frame->data_len[3] = 0;
2742
2743 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
2744 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + p_frame->data_len[0];
2745 p_frame->p_data[2] = (uint8_t *)p_frame->p_data[1] + p_frame->data_len[1];
2746 p_frame->p_data[3] = (uint8_t *)p_frame->p_data[2] + p_frame->data_len[2];
2747
2748 // init p_data[3] to 0 so that ni_frame_buffer_free frees only valid DMA buf
2749 // fd in hw frame read from fw
2750 p_frame->video_width = width_aligned;
2751 p_frame->video_height = height_aligned;
2752
2753 // 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);
2754 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2755 p_frame->buffer_size);
2756END:
2757
2758 if (NI_RETCODE_SUCCESS != retval)
2759 {
2760 ni_aligned_free(p_buffer);
2761 }
2762
2763 return retval;
2764}
2765
2766/*!*****************************************************************************
2767 * \brief Allocate memory for decoder frame buffer based on provided
2768 * parameters; the memory is retrieved from a buffer pool and will be
2769 * returned to the same buffer pool by ni_decoder_frame_buffer_free.
2770 * Note: all attributes of ni_frame_t will be set up except for memory and
2771 * buffer, which rely on the pool being allocated; the pool will be
2772 * allocated only after the frame resolution is known.
2773 *
2774 * \param[in] p_pool Buffer pool to get the memory from
2775 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
2776 * \param[in] alloc_mem Whether to get memory from buffer pool
2777 * \param[in] video_width Width of the video frame
2778 * \param[in] video_height Height of the video frame
2779 * \param[in] alignment Alignment requirement
2780 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel
2781 * \param[in] is_planar 0 if semiplanar else planar
2782 *
2783 * \return On success
2784 * NI_RETCODE_SUCCESS
2785 * On failure
2786 * NI_RETCODE_INVALID_PARAM
2787 * NI_RETCODE_ERROR_MEM_ALOC
2788 ******************************************************************************/
2790 ni_frame_t *p_frame, int alloc_mem,
2791 int video_width, int video_height,
2792 int alignment, int factor,
2793 int is_planar)
2794{
2795 int retval = NI_RETCODE_SUCCESS;
2796
2797 int width_aligned;
2798 int height_aligned;
2799
2800 if ((!p_frame) || ((factor!=1) && (factor!=2))
2801 || (video_width > NI_MAX_RESOLUTION_WIDTH) || (video_width <= 0)
2802 || (video_height > NI_MAX_RESOLUTION_HEIGHT) || (video_height <= 0))
2803 {
2804 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2805 "factor %d, video_width %d, video_height %d\n",
2806 __func__, factor, video_width, video_height);
2808 }
2809
2810 if (QUADRA)
2811 {
2812 width_aligned = ((((video_width * factor) + 127) / 128) * 128) / factor;
2813 height_aligned = video_height;
2814 }
2815 else
2816 {
2817 width_aligned = ((video_width + 31) / 32) * 32;
2818 height_aligned = ((video_height + 7) / 8) * 8;
2819 if (alignment)
2820 {
2821 height_aligned = ((video_height + 15) / 16) * 16;
2822 }
2823 }
2824
2825 ni_log(NI_LOG_DEBUG, "%s: aligned=%dx%d orig=%dx%d\n", __func__,
2826 width_aligned, height_aligned, video_width, video_height);
2827
2828 int luma_size = width_aligned * height_aligned * factor;
2829 int chroma_b_size;
2830 int chroma_r_size;
2831 if (QUADRA)
2832 {
2833 int chroma_width_aligned = ((((video_width / 2 * factor) + 127) / 128) * 128) / factor;
2834 if (!is_planar)
2835 {
2836 chroma_width_aligned =
2837 ((((video_width * factor) + 127) / 128) * 128) / factor;
2838 }
2839 int chroma_height_aligned = height_aligned / 2;
2840 chroma_b_size = chroma_r_size = chroma_width_aligned * chroma_height_aligned * factor;
2841 if (!is_planar)
2842 {
2843 chroma_r_size = 0;
2844 }
2845 }
2846 else
2847 {
2848 chroma_b_size = luma_size / 4;
2849 chroma_r_size = chroma_b_size;
2850 }
2851 int buffer_size = luma_size + chroma_b_size + chroma_r_size +
2853
2854 // added 2 blocks of 512 bytes buffer space to handle any extra metadata
2855 // retrieval from fw
2856 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT + NI_MEM_PAGE_ALIGNMENT * 3;
2857
2858 p_frame->buffer_size = buffer_size;
2859
2860 // if need to get a buffer from pool, pool must have been set up
2861 if (alloc_mem)
2862 {
2863 if (! p_pool)
2864 {
2865 ni_log(NI_LOG_ERROR, "ERROR %s: invalid pool!\n", __func__);
2867 LRETURN;
2868 }
2869
2870 p_frame->dec_buf = ni_buf_pool_get_buffer(p_pool);
2871 if (! p_frame->dec_buf)
2872 {
2874 LRETURN;
2875 }
2876
2877 p_frame->p_buffer = p_frame->dec_buf->buf;
2878
2879 ni_log(NI_LOG_DEBUG, "%s: got new frame ptr %p buffer %p\n", __func__,
2880 p_frame->p_buffer, p_frame->dec_buf);
2881 }
2882 else
2883 {
2884 p_frame->dec_buf = NULL;
2885 p_frame->p_buffer = NULL;
2886 ni_log(NI_LOG_DEBUG, "%s: NOT alloc mem buffer\n", __func__);
2887 }
2888
2889 if (p_frame->p_buffer)
2890 {
2891 p_frame->p_data[0] = p_frame->p_buffer;
2892 p_frame->p_data[1] = p_frame->p_data[0] + luma_size;
2893 p_frame->p_data[2] = p_frame->p_data[1] + chroma_b_size;
2894 p_frame->p_data[3] = p_frame->p_data[2] + chroma_r_size;
2895 }
2896 else
2897 {
2898 p_frame->p_data[0] = p_frame->p_data[1] = p_frame->p_data[2] = NULL;
2899 }
2900
2901 p_frame->data_len[0] = luma_size;
2902 p_frame->data_len[1] = chroma_b_size;
2903 p_frame->data_len[2] = chroma_r_size;
2904 p_frame->data_len[3] = 0; //for hwdesc
2905
2906 p_frame->video_width = width_aligned;
2907 p_frame->video_height = height_aligned;
2908
2909 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2910 p_frame->buffer_size);
2911
2912END:
2913
2914 return retval;
2915}
2916
2917/*!*****************************************************************************
2918 * \brief Check if incoming frame is encoder zero copy compatible or not
2919 *
2920 * \param[in] p_enc_ctx pointer to encoder context
2921 * [in] p_enc_params pointer to encoder parameters
2922 * [in] width input width
2923 * [in] height input height
2924 * [in] linesize input linesizes (pointer to array)
2925 * [in] set_linesize setup linesizes 0 means not setup linesizes, 1 means setup linesizes (before encoder open)
2926 *
2927 * \return on success and can do zero copy
2928 * NI_RETCODE_SUCCESS
2929 *
2930 * cannot do zero copy
2931 * NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
2932 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
2933 * NI_RETCODE_INVALID_PARAM
2934 *
2935*******************************************************************************/
2937 ni_xcoder_params_t *p_enc_params,
2938 int width, int height,
2939 const int linesize[],
2940 bool set_linesize)
2941{
2942 // check pixel format / width / height / linesize can be supported
2943 if ((!p_enc_ctx) || (!p_enc_params) || (!linesize)
2944 || (linesize[0]<=0)
2945 || (width>NI_MAX_RESOLUTION_WIDTH) || (width<=0)
2946 || (height>NI_MAX_RESOLUTION_HEIGHT) || (height<=0))
2947 {
2948 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s passed parameters are null or not supported, "
2949 "p_enc_ctx %p, p_enc_params %p, linesize %p, "
2950 "width %d, height %d linesize[0] %d\n",
2951 __func__, p_enc_ctx, p_enc_params, linesize,
2952 width, height, (linesize) ? linesize[0] : 0);
2954 }
2955
2956 // check fw revision (if fw_rev has been populated in open session)
2959 "6Q") < 0))
2960 {
2961 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: not supported on device with FW API version < 6.Q\n", __func__);
2963 }
2964
2965 bool isrgba = false;
2966 bool isplanar = false;
2967 bool issemiplanar = false;
2968
2969 switch (p_enc_ctx->pixel_format)
2970 {
2971 case NI_PIX_FMT_YUV420P:
2973 isplanar = true;
2974 break;
2975 case NI_PIX_FMT_NV12:
2976 case NI_PIX_FMT_P010LE:
2977 issemiplanar = true;
2978 break;
2979 case NI_PIX_FMT_ABGR:
2980 case NI_PIX_FMT_ARGB:
2981 case NI_PIX_FMT_RGBA:
2982 case NI_PIX_FMT_BGRA:
2983 isrgba = true;
2984 break;
2985 default:
2986 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: pixel_format %d not supported\n", __func__);
2988 }
2989
2990 // check fw revision (if fw_rev has been populated in open session)
2991 if (issemiplanar &&
2994 "6q") < 0))
2995 {
2996 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: semi-planar not supported on device with FW API version < 6.q\n", __func__);
2998 }
2999
3000 // check zero copy compatibilty and set linesize
3001 if (p_enc_params->zerocopy_mode) // always allow zero copy for RGBA, because RGBA pixel format data copy currently not supported
3002 {
3003 if (set_linesize)
3004 {
3005 bool ishwframe = (p_enc_params->hwframes) ? true : false;
3006 int max_linesize = isrgba ? (NI_MAX_RESOLUTION_RGBA_WIDTH*4) : NI_MAX_RESOLUTION_LINESIZE;
3007 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s isrgba %u issemiplanar %u, ishwframe %u, "
3008 "p_enc_ctx %p, p_enc_params %p, linesize %p, "
3009 "width %d, height %d, linesize[0] %d linesize[1] %d\n",
3010 __func__, isrgba, issemiplanar, ishwframe, p_enc_ctx, p_enc_params, linesize,
3011 width, height, linesize[0], linesize[1]);
3012
3013 if (linesize[0] <= max_linesize &&
3014 linesize[0] % 2 == 0 && //even stride
3015 linesize[1] % 2 == 0 && //even stride
3016 width % 2 == 0 && //even width
3017 height % 2 == 0 && //even height
3018 (!p_enc_params->enable_ai_enhance || width % 128 == 0) && // align for AI engine
3019 width >= NI_MIN_WIDTH &&
3020 height >= NI_MIN_HEIGHT &&
3021 !ishwframe &&
3022 (!isplanar || linesize[2] == linesize[1]) // for planar, make sure cb linesize equal to cr linesize
3023 )
3024 {
3025 // send luma / chorma linesize to device (device is also aware frame will not be padded for 2-pass workaround)
3026 p_enc_params->luma_linesize = linesize[0];
3027 p_enc_params->chroma_linesize = (isrgba) ? 0 : linesize[1]; // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format
3028 return NI_RETCODE_SUCCESS;
3029 }
3030 else
3031 {
3032 p_enc_params->luma_linesize = 0;
3033 p_enc_params->chroma_linesize = 0;
3034 }
3035 }
3036 else if (p_enc_params->luma_linesize ||
3037 p_enc_params->chroma_linesize)
3038 {
3039 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s "
3040 "luma_linesize %d, chroma_linesize %d, "
3041 "linesize[0] %d, linesize[1] %d\n",
3042 __func__, p_enc_params->luma_linesize, p_enc_params->chroma_linesize,
3043 linesize[0], linesize[1]);
3044 if (p_enc_params->luma_linesize != linesize[0] ||
3045 (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
3046 )
3047 {
3048#ifndef XCODER_311
3049 // linesizes can change during SW frame seqeunce change transcoding when FFmpeg noautoscale option is not set
3050 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: linesize changed from %u %u to %u %u - resolution change?\n", __func__,
3051 p_enc_params->luma_linesize, p_enc_params->chroma_linesize,
3052 linesize[0], linesize[1]);
3053#endif
3054 }
3055 else
3056 return NI_RETCODE_SUCCESS;
3057 }
3058 }
3059
3061}
3062
3063/*!*****************************************************************************
3064 * \brief Check if the frame data transferred is within a frame boundary and
3065 * adjust with offset if it doesn't. EP will re-adjust the data pointer
3066 * to the correct start address.
3067 *
3068 * \param[in] video_height Height of the video frame after filtering
3069 * [in] linesize Picture line size after filtering (i.e. cropping)
3070 * [in] data Picture data pointers after filtering (for each of YUV planes)
3071 * [in] buf_size0 Y frame size before any filtering (original size)
3072 * [in] buf_size1 U frame size before any filtering (original)
3073 * [in] buf_size2 V frame size before any filtering (original)
3074 * [in] buf_data0 Y picture data pointer before any filtering (original)
3075 * [in] buf_data1 U picture data pointer before any filtering (original)
3076 * [in] buf_data2 V picture data pointer before any filtering (original)
3077 *
3078 * \return On success
3079 * NI_RETCODE_SUCCESS
3080 * On failure
3081 * NI_RETCODE_INVALID_PARAM
3082 *****************************************************************************/
3084 ni_session_context_t *p_enc_ctx,
3085 ni_frame_t *p_frame, int video_height,
3086 const int linesize[], const uint8_t *data[],
3087 int buf_size0, int buf_size1, int buf_size2,
3088 uint8_t *buf_data0, uint8_t *buf_data1, uint8_t *buf_data2)
3089{
3090 int retval = NI_RETCODE_SUCCESS;
3091
3092 if (!p_frame || !p_enc_ctx || !data || !linesize)
3093 {
3094 ni_log(NI_LOG_ERROR, "ERROR: %s: null parameters: p_frame=%p, p_enc_ctx=%p, linesize=%p, data=%p\n",
3095 __func__, p_frame, p_enc_ctx, linesize, data);
3097 }
3098
3099 // Only newer firmware versions (6sU and above) support zero-copy with SW cropping corner
3100 // case handling. See the brief of this function.
3101 if (ni_cmp_fw_api_ver((char*)&p_enc_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sU") < 0)
3102 {
3103 p_frame->hor_adjust_offset = 0;
3104 return NI_RETCODE_SUCCESS;
3105 }
3106
3107 const uint8_t *buf_data[3] = { buf_data0, buf_data1, buf_data2 };
3108 const int buf_size[3] = { buf_size0, buf_size1, buf_size2 };
3109 const uint8_t *end_used, *end_alloc;
3110 int offset = 0;
3111 int i;
3112
3113 // num_planes = 1 if frame is directly from quadra decoder (out=sw) or from raw YUV file
3114 // num_planes = actual number of planes if frame is from ffmpeg SW decoder or after ffmpeg
3115 // pixel format conversion or after hwdownload from quadra decoder (out=hw)
3116 const int num_planes = (buf_size[2] != 0) ? 3 : (buf_size[1] != 0) ? 2 : 1;
3117
3118 // In case of num_planes==1, only index 0 of buf_data[] and buf_size[] exist,
3119 // but all 3 indices of data[] and linesize[] are available for yuv420p and 2 for nv12.
3120 // The same applies to both 8 and 10 bit pixel formats
3121 for (i = 0; i < num_planes; i++)
3122 {
3123 if (!data[i] || !buf_data[i] || buf_size[i] <= 0)
3124 {
3125 ni_log(NI_LOG_ERROR, "ERROR: %s: invalid parameter %d: data=%p, buf_data=%p, size=%d\n",
3126 __func__, i, data[i], buf_data[i], buf_size[i]);
3128 }
3129
3130 int plane_height = video_height >> (i > 0 ? 1 : 0);
3131
3132 // End of used data after filtering (e.g., cropping)
3133 if(num_planes == 1)
3134 {
3135 // Find end address used by last plane since it can reach the end of the buffer and buf_data[0] contains all YUV
3136 if (data[2])
3137 {
3138 // Planar pixel format if 3 data pointers are present
3139 end_used = data[2] + linesize[2] * (video_height >> 1);
3140 }
3141 else if (data[1])
3142 {
3143 // Semiplanar pixel format if only 2 data pointers are present
3144 end_used = data[1] + linesize[1] * (video_height >> 1);
3145 }
3146 else
3147 {
3148 ni_log(NI_LOG_ERROR, "ERROR: %s: Single-plane pixel format not supported\n", __func__);
3150 }
3151 }
3152 else
3153 {
3154 // Find Y, U, and V end address used
3155 end_used = data[i] + linesize[i] * plane_height;
3156 }
3157
3158 // End address of original allocated buffer.
3159 end_alloc = buf_data[i] + buf_size[i];
3160
3161 // Positive offset means filtered data to be transferred by zerocopy exceeds original buffer
3162 int plane_offset = (int)(end_used - end_alloc);
3163 plane_offset = (plane_offset > 0) ? plane_offset : 0;
3164
3165 if(num_planes == 1)
3166 {
3167 if (data[2])
3168 {
3169 offset = plane_offset * 2;
3170 ((uint8_t **)data)[0] -= offset;
3171 ((uint8_t **)data)[1] -= plane_offset;
3172 ((uint8_t **)data)[2] -= plane_offset;
3173 }
3174 else
3175 {
3176 offset = plane_offset;
3177 ((uint8_t **)data)[0] -= plane_offset;
3178 ((uint8_t **)data)[1] -= plane_offset;
3179 }
3180 }
3181 else
3182 {
3183 ((uint8_t **)data)[i] -= plane_offset;
3184 if (i == 0)
3185 {
3186 offset = plane_offset;
3187 }
3188 }
3189
3190 ni_log(NI_LOG_DEBUG, "%s: plane %d offset %d\n", __func__, i, offset);
3191 }
3192
3193 p_frame->hor_adjust_offset = offset;
3194
3195 return retval;
3196}
3197
3198/*!*****************************************************************************
3199 * \brief Allocate memory for encoder zero copy (metadata, etc.)
3200 * for encoding based on given
3201 * parameters, taking into account pic linesize and extra data.
3202 * Applicable to YUV planr / semi-planar 8 or 10 bit and RGBA pixel formats.
3203 *
3204 *
3205 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3206 * \param[in] video_width Width of the video frame
3207 * \param[in] video_height Height of the video frame
3208 * \param[in] linesize Picture line size
3209 * \param[in] data Picture data pointers (for each of YUV planes)
3210 * \param[in] extra_len Extra data size (incl. meta data)
3211 *
3212 * \return On success
3213 * NI_RETCODE_SUCCESS
3214 * On failure
3215 * NI_RETCODE_INVALID_PARAM
3216 * NI_RETCODE_ERROR_MEM_ALOC
3217 *****************************************************************************/
3219 int video_width, int video_height,
3220 const int linesize[], const uint8_t *data[],
3221 int extra_len)
3222{
3223 int retval = NI_RETCODE_SUCCESS;
3224
3225 if ((!p_frame) || (!linesize) || (!data))
3226 {
3227 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3228 "p_frame %p, linesize %p, data %p\n",
3229 __func__, p_frame, linesize, data);
3231 }
3232
3234 "%s: resolution=%dx%d linesize=%d/%d/%d "
3235 "data=%p %p %p extra_len=%d\n",
3236 __func__, video_width, video_height,
3237 linesize[0], linesize[1], linesize[2],
3238 data[0], data[1], data[2], extra_len);
3239
3240 if (p_frame->buffer_size)
3241 {
3242 p_frame->buffer_size = 0; //notify p_frame->p_buffer is not allocated
3243 ni_aligned_free(p_frame->p_buffer); // also free the temp p_buffer allocated for niFrameSurface1_t in encoder init stage
3244 }
3245
3246 p_frame->p_buffer = (uint8_t *)data[0];
3247 p_frame->p_data[0] = (uint8_t *)data[0];
3248 p_frame->p_data[1] = (uint8_t *)data[1];
3249 p_frame->p_data[2] = (uint8_t *)data[2];
3250
3251 int luma_size = linesize[0] * video_height;
3252 int chroma_b_size = 0;
3253 int chroma_r_size = 0;
3254
3255 // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format, but only data[0] pointer is populated
3256 if (data[1]) // cb size is 0 for RGBA pixel format
3257 chroma_b_size = linesize[1] * (video_height / 2);
3258
3259 if (data[2]) // cr size is 0 for semi-planar or RGBA pixel format
3260 chroma_r_size = linesize[2] * (video_height / 2);
3261
3262 //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);
3263
3264 uint32_t start_offset;
3265 uint32_t total_start_len = 0;
3266 int i;
3267
3268 p_frame->inconsecutive_transfer = 0;
3269
3270 // rgba has one data pointer, semi-planar has two data pointers
3271 if ((data[1] && (data[0] + luma_size != data[1]))
3272 || (data[2] && (data[1] + chroma_b_size != data[2])))
3273 {
3274 p_frame->inconsecutive_transfer = 1;
3275 }
3276
3277 if (p_frame->inconsecutive_transfer)
3278 {
3279 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
3280 {
3281 start_offset = (uintptr_t)p_frame->p_data[i] % NI_MEM_PAGE_ALIGNMENT;
3282 p_frame->start_len[i] = start_offset ? (NI_MEM_PAGE_ALIGNMENT - start_offset) : 0;
3283 total_start_len += p_frame->start_len[i];
3284 }
3285 }
3286 else
3287 {
3288 start_offset = (uintptr_t)p_frame->p_data[0] % NI_MEM_PAGE_ALIGNMENT;
3289 p_frame->start_len[0] = start_offset ? (NI_MEM_PAGE_ALIGNMENT - start_offset) : 0;
3290 p_frame->start_len[1] = p_frame->start_len[2] = 0;
3291 total_start_len = p_frame->start_len[0];
3292 }
3293 p_frame->total_start_len = total_start_len;
3294
3295 if (ni_encoder_metadata_buffer_alloc(p_frame, extra_len))
3296 {
3297 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_metadata_buffer buffer.\n",
3298 NI_ERRNO, __func__);
3300 LRETURN;
3301 }
3302 p_frame->separate_metadata = 1;
3303
3304 if (total_start_len)
3305 {
3306 if (ni_encoder_start_buffer_alloc(p_frame))
3307 {
3308 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_start_buffer buffer.\n",
3309 NI_ERRNO, __func__);
3311 LRETURN;
3312 }
3313 p_frame->separate_start = 1;
3314
3315 // copy non-4k-aligned part at the start of YUV data
3316 int start_buffer_offset = 0;
3317 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
3318 {
3319 if (p_frame->p_data[i])
3320 {
3321 memcpy(p_frame->p_start_buffer+start_buffer_offset, p_frame->p_data[i],
3322 p_frame->start_len[i]);
3323 start_buffer_offset += p_frame->start_len[i];
3324 }
3325 }
3326 }
3327
3328 p_frame->data_len[0] = luma_size;
3329 p_frame->data_len[1] = chroma_b_size;
3330 p_frame->data_len[2] = chroma_r_size;
3331 p_frame->data_len[3] = 0;//unused by hwdesc
3332
3333 p_frame->video_width = video_width;
3334 p_frame->video_height = video_height;
3335
3337 "%s: success: p_metadata_buffer %p metadata_buffer_size %u "
3338 "p_start_buffer %p start_buffer_size %u data_len %u %u %u\n",
3339 __func__, p_frame->p_metadata_buffer, p_frame->metadata_buffer_size,
3340 p_frame->p_start_buffer, p_frame->start_buffer_size,
3341 p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2]);
3342
3343END:
3344
3345 return retval;
3346}
3347
3348
3349/*!*****************************************************************************
3350 * \brief Check if incoming frame is hwupload zero copy compatible or not
3351 *
3352 * \param[in] p_upl_ctx pointer to uploader context
3353 * [in] width input width
3354 * [in] height input height
3355 * [in] linesize input linesizes (pointer to array)
3356 * [in] pixel_format input pixel format
3357 *
3358 * \return on success and can do zero copy
3359 * NI_RETCODE_SUCCESS
3360 *
3361 * cannot do zero copy
3362 * NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
3363 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
3364 * NI_RETCODE_INVALID_PARAM
3365 *
3366*******************************************************************************/
3368 int width, int height,
3369 const int linesize[], int pixel_format)
3370{
3371 // check pixel format / width / height / linesize can be supported
3372 if ((!p_upl_ctx) || (!linesize)
3373 || (linesize[0]<=0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3374 || (width>NI_MAX_RESOLUTION_WIDTH) || (width<=0)
3375 || (height>NI_MAX_RESOLUTION_HEIGHT) || (height<=0))
3376 {
3377 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s passed parameters are null or not supported, "
3378 "p_enc_ctx %p, linesize %p, "
3379 "width %d, height %d linesize[0] %d\n",
3380 __func__, p_upl_ctx, linesize,
3381 width, height, (linesize) ? linesize[0] : 0);
3383 }
3384
3385 // check fw revision (if fw_rev has been populated in open session)
3388 "6S") < 0))
3389 {
3390 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: not supported on device with FW API version < 6.S\n", __func__);
3392 }
3393
3394 // upload does not have zeroCopyMode parameter, currently only allows resolution >= 1080p
3395 if ((width * height) < NI_NUM_OF_PIXELS_1080P)
3397
3398 // check zero copy compatibilty
3399 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s pixel_format %d "
3400 "p_upl_ctx %p, linesize %p, "
3401 "width %d, height %d, linesize[0] %d\n",
3402 __func__, pixel_format, p_upl_ctx, linesize,
3403 width, height, linesize[0]);
3404
3405 int bit_depth_factor;
3406 bool isrgba = false;
3407 bool isplanar = false;
3408 bool issemiplanar = false;
3409
3410 switch (pixel_format)
3411 {
3412 case NI_PIX_FMT_YUV420P:
3413 isplanar = true;
3414 bit_depth_factor = 1;
3415 break;
3417 isplanar = true;
3418 bit_depth_factor = 2;
3419 break;
3420 case NI_PIX_FMT_NV12:
3421 issemiplanar = true;
3422 bit_depth_factor = 1;
3423 break;
3424 case NI_PIX_FMT_P010LE:
3425 issemiplanar = true;
3426 bit_depth_factor = 2;
3427 break;
3428 case NI_PIX_FMT_ABGR:
3429 case NI_PIX_FMT_ARGB:
3430 case NI_PIX_FMT_RGBA:
3431 case NI_PIX_FMT_BGRA:
3432 isrgba = true;
3433 bit_depth_factor = 4; // not accurate, only for linesize check
3434 break;
3435 default:
3436 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: pixel_format %d not supported\n", __func__);
3438 }
3439
3440 // check fw revision (if fw_rev has been populated in open session)
3441 if (issemiplanar &&
3444 "6q") < 0))
3445 {
3446 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: semi-planar not supported on device with FW API version < 6.q\n", __func__);
3448 }
3449
3450 int max_linesize = isrgba ? (NI_MAX_RESOLUTION_RGBA_WIDTH*4) : NI_MAX_RESOLUTION_LINESIZE;
3451 if (linesize[0] <= max_linesize &&
3452 width % 2 == 0 && //even width
3453 height % 2 == 0 && //even height
3454 width >= NI_MIN_WIDTH && height >= NI_MIN_HEIGHT)
3455 {
3456 // yuv only support default 128 bytes aligned linesize, because downstream filter or encoder expect HW frame 128 bytes aligned
3457 if (isplanar &&
3458 linesize[0] == NI_VPU_ALIGN128(width * bit_depth_factor) &&
3459 linesize[1] == NI_VPU_ALIGN128(width * bit_depth_factor / 2) &&
3460 linesize[2] == linesize[1])
3461 return NI_RETCODE_SUCCESS;
3462
3463 // yuv only support default 128 bytes aligned linesize, because downstream filter or encoder expect HW frame 128 bytes aligned
3464 if (issemiplanar &&
3465 linesize[0] == NI_VPU_ALIGN128(width * bit_depth_factor) &&
3466 linesize[1] == linesize[0])
3467 return NI_RETCODE_SUCCESS;
3468
3469 // rgba only support 64 bytes aligned for 2D
3470 if (isrgba &&
3471 linesize[0] == NI_VPU_ALIGN64(width * bit_depth_factor))
3472 return NI_RETCODE_SUCCESS;
3473 }
3474
3476}
3477
3478/*!*****************************************************************************
3479 * \brief Allocate memory for the frame buffer for encoding based on given
3480 * parameters, taking into account pic line size and extra data.
3481 * Applicable to YUV420p AVFrame only. 8 or 10 bit/pixel.
3482 * Cb/Cr size matches that of Y.
3483 *
3484 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3485 *
3486 * \param[in] video_width Width of the video frame
3487 * \param[in] video_height Height of the video frame
3488 * \param[in] linesize Picture line size
3489 * \param[in] alignment Allignment requirement
3490 * \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3491 * to allocate any buffer (zero-copy from existing)
3492 * \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3493 *
3494 * \return On success
3495 * NI_RETCODE_SUCCESS
3496 * On failure
3497 * NI_RETCODE_INVALID_PARAM
3498 * NI_RETCODE_ERROR_MEM_ALOC
3499 *****************************************************************************/
3501 int video_height, int linesize[],
3502 int alignment, int extra_len,
3503 bool alignment_2pass_wa)
3504{
3505 void* p_buffer = NULL;
3506 int height_aligned;
3507 int retval = NI_RETCODE_SUCCESS;
3508
3509 if ((!p_frame) || (!linesize) || (linesize[0]<=0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3510 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
3511 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
3512 {
3513 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3514 "p_frame %p, linesize %p, video_width %d, video_height %d\n",
3515 __func__, p_frame, linesize, video_width, video_height);
3517 }
3518
3519 if (QUADRA)
3520 {
3521 height_aligned = ((video_height + 1) / 2) * 2;
3522 } else
3523 {
3524 height_aligned = ((video_height + 7) / 8) * 8;
3525
3526 if (alignment)
3527 {
3528 height_aligned = ((video_height + 15) / 16) * 16;
3529 }
3530 }
3531 if (height_aligned < NI_MIN_HEIGHT)
3532 {
3533 height_aligned = NI_MIN_HEIGHT;
3534 }
3535
3537 "%s: aligned=%dx%d org=%dx%d linesize=%d/%d/%d "
3538 "extra_len=%d\n",
3539 __func__, video_width, height_aligned, video_width, video_height,
3540 linesize[0], linesize[1], linesize[2], extra_len);
3541
3542 int luma_size = linesize[0] * height_aligned;
3543 int chroma_b_size;
3544 int chroma_r_size;
3545 if (QUADRA)
3546 {
3547 chroma_b_size = chroma_r_size = linesize[1] * (height_aligned / 2);
3548 if (alignment_2pass_wa)
3549 {
3550 // for 2-pass encode output mismatch WA, need to extend (and pad) Cr plane height, because 1st pass assume input 32 align
3551 chroma_r_size = linesize[1] * (((height_aligned + 31) / 32) * 32) / 2;
3552 }
3553 //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);
3554 }
3555 else
3556 {
3557 chroma_b_size = luma_size / 4;
3558 chroma_r_size = luma_size / 4;
3559 }
3560 if(extra_len >= 0)
3561 {
3562 int buffer_size = luma_size + chroma_b_size + chroma_r_size + extra_len;
3563
3565
3566 //Check if Need to free
3567 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
3568 {
3570 "%s: free current p_frame, "
3571 "p_frame->buffer_size=%u\n",
3572 __func__, p_frame->buffer_size);
3573 ni_frame_buffer_free(p_frame);
3574 }
3575
3576 //Check if need to realocate
3577 if (p_frame->buffer_size != buffer_size)
3578 {
3579 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3580 {
3581 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
3582 NI_ERRNO, __func__);
3584 LRETURN;
3585 }
3586
3587 // init once after allocation
3588 memset(p_buffer, 0, buffer_size);
3589 p_frame->buffer_size = buffer_size;
3590 p_frame->p_buffer = p_buffer;
3591
3592 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
3593 }
3594 else
3595 {
3596 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
3597 }
3598 p_frame->p_data[0] = (uint8_t*)p_frame->p_buffer;
3599 p_frame->p_data[1] = (uint8_t*)p_frame->p_data[0] + luma_size;
3600 p_frame->p_data[2] = (uint8_t*)p_frame->p_data[1] + chroma_b_size;
3601 }
3602 else
3603 {
3604 p_frame->buffer_size = 0; //no ownership
3605 }
3606
3607 p_frame->data_len[0] = luma_size;
3608 p_frame->data_len[1] = chroma_b_size;
3609 p_frame->data_len[2] = chroma_r_size;
3610 p_frame->data_len[3] = 0;//unused by hwdesc
3611
3612 p_frame->video_width = video_width;
3613 p_frame->video_height = height_aligned;
3614
3616 "%s: success: p_frame->p_buffer %p "
3617 "p_frame->buffer_size=%u\n",
3618 __func__, p_frame->p_buffer, p_frame->buffer_size);
3619
3620END:
3621
3622 if (NI_RETCODE_SUCCESS != retval)
3623 {
3624 ni_aligned_free(p_buffer);
3625 }
3626
3627 return retval;
3628}
3629
3630/*!*****************************************************************************
3631 * \brief allocate device destination frame from scaler hwframe pool
3632 *
3633 * \param
3634 *
3635 * \return 0 if successful, < 0 otherwise
3636 ******************************************************************************/
3638 ni_scaler_input_params_t scaler_params,
3639 niFrameSurface1_t *p_surface)
3640{
3641 int ret = 0;
3642 if (scaler_params.op != NI_SCALER_OPCODE_OVERLAY && scaler_params.op != NI_SCALER_OPCODE_WATERMARK)
3643 {
3645 p_ctx, scaler_params.output_width, scaler_params.output_height,
3646 scaler_params.output_format, NI_SCALER_FLAG_IO,
3647 scaler_params.out_rec_width, scaler_params.out_rec_height,
3648 scaler_params.out_rec_x, scaler_params.out_rec_y,
3649 scaler_params.rgba_color, -1, NI_DEVICE_TYPE_SCALER);
3650 } else
3651 {
3652 // in vf_overlay_ni.c: flags = (s->alpha_format ? NI_SCALER_FLAG_PA : 0) | NI_SCALER_FLAG_IO;
3654 p_ctx, scaler_params.output_width, scaler_params.output_height,
3655 scaler_params.output_format, NI_SCALER_FLAG_IO,
3656 scaler_params.out_rec_width, scaler_params.out_rec_height,
3657 scaler_params.out_rec_x, scaler_params.out_rec_y,
3658 p_surface->ui32nodeAddress, p_surface->ui16FrameIdx,
3660 }
3661 return ret;
3662}
3663
3664/*!*****************************************************************************
3665 * \brief allocate device input frame by hw descriptor. This call won't actually allocate
3666 a frame but sends the incoming hardware frame index to the scaler manager
3667 *
3668 * \param
3669 *
3670 * \return 0 if successful, < 0 otherwise
3671 ******************************************************************************/
3673 ni_scaler_input_params_t scaler_params,
3674 niFrameSurface1_t *p_src_surface)
3675{
3676 int ret = 0;
3677
3679 p_ctx, scaler_params.input_width, scaler_params.input_height,
3680 scaler_params.input_format, 0, scaler_params.in_rec_width,
3681 scaler_params.in_rec_height, scaler_params.in_rec_x,
3682 scaler_params.in_rec_y, p_src_surface->ui32nodeAddress,
3683 p_src_surface->ui16FrameIdx, NI_DEVICE_TYPE_SCALER);
3684 return ret;
3685}
3686
3687/*!*****************************************************************************
3688 * \brief init output pool of scaler frames
3689 *
3690 * \param
3691 *
3692 * \return 0 if successful, < 0 otherwise
3693 ******************************************************************************/
3695 ni_scaler_input_params_t scaler_params)
3696{
3697 int rc = 0;
3698 int options = NI_SCALER_FLAG_IO | NI_SCALER_FLAG_PC;
3699 if (p_ctx->isP2P)
3700 options |= NI_SCALER_FLAG_P2;
3701
3702 /* Allocate a pool of frames by the scaler */
3703 rc = ni_device_alloc_frame(p_ctx, scaler_params.output_width,
3704 scaler_params.output_height,
3705 scaler_params.output_format, options,
3706 0, // rec width
3707 0, // rec height
3708 0, // rec X pos
3709 0, // rec Y pos
3710 NI_MAX_FILTER_POOL_SIZE, // rgba color/pool size
3711 0, // frame index
3713 return rc;
3714}
3715
3716/*!*****************************************************************************
3717* \brief Allocate memory for the frame buffer based on provided parameters
3718* taking into account pic line size and extra data.
3719* Applicable to nv12 AVFrame only. Cb/Cr size matches that of Y.
3720*
3721* \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3722*
3723* \param[in] video_width Width of the video frame
3724* \param[in] video_height Height of the video frame
3725* \param[in] linesize Picture line size
3726* \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3727* to allocate any buffer (zero-copy from existing)
3728* \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3729*
3730* \return On success
3731* NI_RETCODE_SUCCESS
3732* On failure
3733* NI_RETCODE_INVALID_PARAM
3734* NI_RETCODE_ERROR_MEM_ALOC
3735*****************************************************************************/
3737 int video_height, int linesize[],
3738 int extra_len, bool alignment_2pass_wa)
3739{
3740 void* p_buffer = NULL;
3741 int height_aligned;
3742 int retval = NI_RETCODE_SUCCESS;
3743
3744 if ((!p_frame) || (!linesize) || (linesize[0] <= 0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3745 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width <= 0)
3746 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height <= 0))
3747 {
3748 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3749 "p_frame %p, linesize %p, video_width %d, video_height %d\n",
3750 __func__, p_frame, linesize, video_width, video_height);
3752 }
3753
3754 height_aligned = ((video_height + 1) / 2) * 2;
3755
3756 if (height_aligned < NI_MIN_HEIGHT)
3757 {
3758 height_aligned = NI_MIN_HEIGHT;
3759 }
3760
3762 "%s: aligned=%dx%d org=%dx%d linesize=%d/%d/%d extra_len=%d\n",
3763 __func__, video_width, height_aligned, video_width, video_height,
3764 linesize[0], linesize[1], linesize[2], extra_len);
3765
3766 int luma_size = linesize[0] * height_aligned;
3767 int chroma_br_size = luma_size / 2;
3768 //int chroma_r_size = luma_size / 4;
3769 if (alignment_2pass_wa)
3770 {
3771 // for 2-pass encode output mismatch WA, need to extend (and pad) CbCr plane height, because 1st pass assume input 32 align
3772 chroma_br_size = linesize[0] * ((((height_aligned + 31) / 32) * 32) / 2);
3773 }
3774 if (extra_len >= 0)
3775 {
3776 int buffer_size = luma_size + chroma_br_size + extra_len;
3777
3779
3780 //Check if Need to free
3781 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
3782 {
3783 ni_log(NI_LOG_DEBUG, "%s: free current p_frame->buffer_size=%u\n",
3784 __func__, p_frame->buffer_size);
3785 ni_frame_buffer_free(p_frame);
3786 }
3787
3788 //Check if need to realocate
3789 if (p_frame->buffer_size != buffer_size)
3790 {
3791 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3792 {
3793 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
3794 NI_ERRNO, __func__);
3796 LRETURN;
3797 }
3798
3799 // init once after allocation
3800 memset(p_buffer, 0, buffer_size);
3801 p_frame->buffer_size = buffer_size;
3802 p_frame->p_buffer = p_buffer;
3803
3804 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
3805 }
3806 else
3807 {
3808 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
3809 }
3810
3811 p_frame->p_data[0] = (uint8_t*)p_frame->p_buffer;
3812 p_frame->p_data[1] = (uint8_t*)p_frame->p_data[0] + luma_size;
3813 p_frame->p_data[2] = (uint8_t*)p_frame->p_data[1] + chroma_br_size;
3814 }
3815 else
3816 {
3817 p_frame->buffer_size = 0; //no ownership
3818 }
3819 p_frame->data_len[0] = luma_size;
3820 p_frame->data_len[1] = chroma_br_size;
3821 p_frame->data_len[2] = 0;
3822
3823 p_frame->video_width = video_width;
3824 p_frame->video_height = height_aligned;
3825
3826 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
3827 p_frame->buffer_size);
3828
3829END:
3830
3831 if (NI_RETCODE_SUCCESS != retval)
3832 {
3833 ni_aligned_free(p_buffer);
3834 }
3835
3836 return retval;
3837}
3838
3839/*!*****************************************************************************
3840 * \brief This API is a wrapper for ni_encoder_frame_buffer_alloc(), used
3841 * for planar pixel formats, and ni_frame_buffer_alloc_nv(), used for
3842 * semi-planar pixel formats. This API is meant to combine the
3843 * functionality for both individual format APIs.
3844 * Allocate memory for the frame buffer for encoding based on given
3845 * parameters, taking into account pic line size and extra data.
3846 * Applicable to YUV420p(8 or 10 bit/pixel) or nv12 AVFrame.
3847 * Cb/Cr size matches that of Y.
3848 *
3849 * \param[in] planar true: if planar:
3850 * pixel_format == (NI_PIX_FMT_YUV420P ||
3851 * NI_PIX_FMT_YUV420P10LE ||NI_PIX_FMT_RGBA).
3852 * false: semi-planar:
3853 * pixel_format == (NI_PIX_FMT_NV12 ||
3854 * NI_PIX_FMT_P010LE).
3855 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3856 * \param[in] video_width Width of the video frame
3857 * \param[in] video_height Height of the video frame
3858 * \param[in] linesize Picture line size
3859 * \param[in] alignment Allignment requirement. Only used for planar format.
3860 * \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3861 * to allocate any buffer (zero-copy from existing)
3862 * \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3863 *
3864 * \return On success
3865 * NI_RETCODE_SUCCESS
3866 * On failure
3867 * NI_RETCODE_INVALID_PARAM
3868 * NI_RETCODE_ERROR_MEM_ALOC
3869 *****************************************************************************/
3871 int video_width, int video_height,
3872 int linesize[], int alignment,
3873 int extra_len,
3874 bool alignment_2pass_wa)
3875{
3876 if (true == planar)
3877 {
3878 return ni_encoder_frame_buffer_alloc(p_frame, video_width, video_height,
3879 linesize, alignment, extra_len,
3880 alignment_2pass_wa);
3881 }
3882 else
3883 {
3884 return ni_frame_buffer_alloc_nv(p_frame, video_width, video_height,
3885 linesize, extra_len,
3886 alignment_2pass_wa);
3887 }
3888}
3889
3890/*!*****************************************************************************
3891 * \brief Free frame buffer that was previously allocated with either
3892 * ni_frame_buffer_alloc or ni_encoder_frame_buffer_alloc or
3893 * ni_frame_buffer_alloc_nv
3894 *
3895 * \param[in] p_frame Pointer to a previously allocated ni_frame_t struct
3896 *
3897 * \return On success NI_RETCODE_SUCCESS
3898 * On failure NI_RETCODE_INVALID_PARAM
3899 ******************************************************************************/
3901{
3902 int i;
3904
3905 ni_log(NI_LOG_TRACE, "%s: enter\n", __func__);
3906
3907 if (!p_frame)
3908 {
3909 ni_log(NI_LOG_DEBUG, "WARN: %s(): p_frame is NULL\n", __func__);
3910 LRETURN;
3911 }
3912
3913 if (!p_frame->p_buffer)
3914 {
3915 ni_log(NI_LOG_DEBUG, "WARN: %s(): already freed, nothing to free\n",
3916 __func__);
3917 }
3918
3919#ifndef _WIN32
3920 // If this is a hardware frame with a DMA buf fd attached, close the DMA buf fd
3921 if ((p_frame->data_len[3] > 0) && (p_frame->p_data[3] != NULL))
3922 {
3923 niFrameSurface1_t *p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
3924 if ((p_surface->dma_buf_fd > 0) && (p_surface->ui16FrameIdx > 0))
3925 {
3926 // Close the DMA buf fd
3928 "%s: close p_surface->dma_buf_fd %d "
3929 "ui16FrameIdx %u\n",
3930 __func__, p_surface->dma_buf_fd, p_surface->ui16FrameIdx);
3931 close(p_surface->dma_buf_fd);
3932 }
3933 }
3934#endif
3935
3936 if (p_frame->buffer_size)
3937 {
3938 p_frame->buffer_size = 0;
3939 ni_aligned_free(p_frame->p_buffer);
3940 }
3941
3942 for (i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
3943 {
3944 p_frame->data_len[i] = 0;
3945 p_frame->p_data[i] = NULL;
3946 }
3947
3948 ni_frame_wipe_aux_data(p_frame);
3949
3950 if (p_frame->metadata_buffer_size)
3951 {
3952 p_frame->metadata_buffer_size = 0;
3954 }
3955 p_frame->separate_metadata = 0;
3956
3957 if (p_frame->start_buffer_size)
3958 {
3959 p_frame->start_buffer_size = 0;
3961 }
3962 p_frame->separate_start = 0;
3963 memset(p_frame->start_len, 0, sizeof(p_frame->start_len));
3964 p_frame->total_start_len = 0;
3965 p_frame->inconsecutive_transfer = 0;
3966
3967END:
3968
3969 ni_log(NI_LOG_TRACE, "%s: exit\n", __func__);
3970
3971 return retval;
3972}
3973
3974/*!*****************************************************************************
3975 * \brief Free decoder frame buffer that was previously allocated with
3976 * ni_decoder_frame_buffer_alloc, returning memory to a buffer pool.
3977 *
3978 * \param[in] p_frame Pointer to a previously allocated ni_frame_t struct
3979 *
3980 * \return On success NI_RETCODE_SUCCESS
3981 * On failure NI_RETCODE_INVALID_PARAM
3982 ******************************************************************************/
3984{
3985 int i;
3987
3988 ni_log(NI_LOG_TRACE, "%s: enter\n", __func__);
3989
3990 if (!p_frame)
3991 {
3992 ni_log(NI_LOG_DEBUG, "WARN: %s(): p_frame is NULL\n", __func__);
3993 retval = NI_RETCODE_INVALID_PARAM;
3994 LRETURN;
3995 }
3996
3997 if (p_frame->dec_buf)
3998 {
4000 ni_log(NI_LOG_DEBUG, "%s(): Mem buf returned ptr %p buf %p !\n", __func__,
4001 p_frame->dec_buf->buf, p_frame->dec_buf);
4002 }
4003 else
4004 {
4005 ni_log(NI_LOG_DEBUG, "%s(): NO mem buf returned !\n", __func__);
4006 }
4007
4008 p_frame->dec_buf = NULL;
4009 p_frame->p_buffer = NULL;
4010 p_frame->buffer_size = 0;
4011 for (i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
4012 {
4013 p_frame->data_len[i] = 0;
4014 p_frame->p_data[i] = NULL;
4015 }
4016 ni_frame_wipe_aux_data(p_frame);
4017
4018END:
4019
4020 ni_log(NI_LOG_TRACE, "%s: exit\n", __func__);
4021
4022 return retval;
4023}
4024
4025/*!*****************************************************************************
4026 * \brief Return a memory buffer to memory buffer pool.
4027 *
4028 * \param[in] buf Buffer to be returned.
4029 * \param[in] p_buffer_pool Buffer pool to return buffer to.
4030 *
4031 * \return None
4032 ******************************************************************************/
4034 ni_buf_pool_t *p_buffer_pool)
4035{
4036 ni_buf_pool_return_buffer(buf, p_buffer_pool);
4037}
4038
4039/*!*****************************************************************************
4040 * \brief Allocate memory for the packet buffer based on provided packet size
4041 *
4042 * \param[in] p_packet Pointer to a caller allocated
4043 * ni_packet_t struct
4044 * \param[in] packet_size Required allocation size
4045 *
4046 * \return On success
4047 * NI_RETCODE_SUCCESS
4048 * On failure
4049 * NI_RETCODE_INVALID_PARAM
4050 * NI_RETCODE_ERROR_MEM_ALOC
4051 ******************************************************************************/
4053{
4054 void* p_buffer = NULL;
4055 int metadata_size = 0;
4056
4057 metadata_size = NI_FW_META_DATA_SZ;
4058
4059 int buffer_size = (((packet_size + metadata_size) / NI_MAX_PACKET_SZ) + 1) * NI_MAX_PACKET_SZ;
4060
4061 ni_log(NI_LOG_TRACE, "%s: packet_size=%d\n", __func__,
4062 packet_size + metadata_size);
4063
4064 if (!p_packet || !packet_size)
4065 {
4066 ni_log(NI_LOG_ERROR, "ERROR: %s: null pointer parameters passed\n",
4067 __func__);
4069 }
4070
4071 if (buffer_size % NI_MEM_PAGE_ALIGNMENT)
4072 {
4073 buffer_size = ( (buffer_size / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT ) + NI_MEM_PAGE_ALIGNMENT;
4074 }
4075
4076 if (p_packet->buffer_size == buffer_size)
4077 {
4078 // Already allocated the exact size.
4079 p_packet->p_data = p_packet->p_buffer;
4080 ni_log(NI_LOG_DEBUG, "%s: reuse current p_packet buffer\n", __func__);
4081 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4082 p_packet->buffer_size);
4083 return NI_RETCODE_SUCCESS;
4084 }
4085
4086 if (p_packet->buffer_size)
4087 {
4089 "%s: free current p_packet, p_packet->buffer_size=%u\n", __func__,
4090 p_packet->buffer_size);
4091 ni_packet_buffer_free(p_packet);
4092 }
4093
4094 ni_log(NI_LOG_DEBUG, "%s: Allocating p_frame buffer, buffer_size=%d\n",
4095 __func__, buffer_size);
4096
4097 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
4098 {
4099 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_packet buffer.\n",
4100 NI_ERRNO, __func__);
4101 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4102 p_packet->buffer_size);
4104 }
4105
4106 p_packet->buffer_size = buffer_size;
4107 p_packet->p_buffer = p_buffer;
4108 p_packet->p_data = p_packet->p_buffer;
4109
4110 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4111 p_packet->buffer_size);
4112
4113 return NI_RETCODE_SUCCESS;
4114}
4115
4116/*!*****************************************************************************
4117 * \brief Allocate packet buffer using a user provided pointer, the memory
4118 * is expected to have already been allocated.
4119 *
4120 * For ideal performance memory should be 4k aligned. If it is not 4K aligned
4121 * then a temporary 4k aligned memory will be used to copy data to and from
4122 * when writing and reading. This will negatively impact performance.
4123 *
4124 * This API will overwrite p_packet->buffer_size, p_packet->p_buffer and
4125 * p_packet->p_data fields in p_packet.
4126 *
4127 * This API will not free any memory associated with p_packet->p_buffer and
4128 * p_packet->p_data fields in p_packet.
4129 * Common use case could be,
4130 * 1. Allocate memory to pointer
4131 * 2. Call ni_custom_packet_buffer_alloc() with allocated pointer.
4132 * 3. Use p_packet as required.
4133 * 4. Call ni_packet_buffer_free() to free up the memory.
4134 *
4135 * \param[in] p_buffer User provided pointer to be used for buffer
4136 * \param[in] p_packet Pointer to a caller allocated
4137 * ni_packet_t struct
4138 * \param[in] buffer_size Buffer size
4139 *
4140 * \return On success
4141 * NI_RETCODE_SUCCESS
4142 * On failure
4143 * NI_RETCODE_INVALID_PARAM
4144 * NI_RETCODE_ERROR_MEM_ALOC
4145 ******************************************************************************/
4147 ni_packet_t *p_packet,
4148 int buffer_size)
4149{
4150 ni_log(NI_LOG_TRACE, "%s(): enter buffer_size=%d\n", __func__, buffer_size);
4151
4152 if (!p_buffer || !p_packet || !buffer_size)
4153 {
4154 ni_log(NI_LOG_ERROR, "ERROR: %s: null pointer parameters passed\n",
4155 __func__);
4157 }
4158 if (((uintptr_t)p_buffer) % NI_MEM_PAGE_ALIGNMENT)
4159 {
4160 ni_log(NI_LOG_INFO, "Info: %s: Warning buffer not 4k aligned = %p!. Will do an extra copy\n",
4161 __func__, p_buffer);
4162 }
4163
4164 p_packet->buffer_size = buffer_size;
4165 p_packet->p_buffer = p_buffer;
4166 p_packet->p_data = p_packet->p_buffer;
4167
4168 ni_log(NI_LOG_TRACE, "%s: exit: \n", __func__);
4169
4170 return NI_RETCODE_SUCCESS;
4171}
4172
4173/*!*****************************************************************************
4174 * \brief Free packet buffer that was previously allocated with
4175 * ni_packet_buffer_alloc
4176 *
4177 * \param[in] p_packet Pointer to a previously allocated ni_packet_t struct
4178 *
4179 * \return On success NI_RETCODE_SUCCESS
4180 * On failure NI_RETCODE_INVALID_PARAM
4181 ******************************************************************************/
4183{
4185
4186 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
4187
4188 if (!p_packet)
4189 {
4190 ni_log(NI_LOG_ERROR, "ERROR: %s(): p_packet is NULL\n", __func__);
4191 retval = NI_RETCODE_FAILURE;
4192 LRETURN;
4193 }
4194
4195 if (!p_packet->p_buffer)
4196 {
4197 ni_log(NI_LOG_DEBUG, "%s(): already freed, nothing to free\n", __func__);
4198 LRETURN;
4199 }
4200
4201 ni_aligned_free(p_packet->p_buffer);
4202 p_packet->p_buffer = NULL;
4203 p_packet->buffer_size = 0;
4204 p_packet->data_len = 0;
4205 p_packet->p_data = NULL;
4206
4207 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
4208
4209END:
4210
4211 return retval;
4212}
4213
4214/*!*****************************************************************************
4215 * \brief Free packet buffer that was previously allocated with
4216 * ni_packet_buffer_alloc for AV1 packets merge
4217 *
4218 * \param[in] p_packet Pointer to a previously allocated ni_packet_t struct
4219 *
4220 * \return On success NI_RETCODE_SUCCESS
4221 * On failure NI_RETCODE_INVALID_PARAM
4222 ******************************************************************************/
4224{
4225 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
4227 int i;
4228
4229 if (!p_packet)
4230 {
4231 ni_log(NI_LOG_ERROR, "ERROR: %s(): p_packet is NULL\n", __func__);
4232 retval = NI_RETCODE_FAILURE;
4233 LRETURN;
4234 }
4235
4236 if (!p_packet->av1_buffer_index)
4237 {
4239 "%s(): no need to free previous av1 packet buffers\n", __func__);
4240 LRETURN;
4241 }
4242
4243 for (i = 0; i < p_packet->av1_buffer_index; i++)
4244 {
4245 ni_log(NI_LOG_DEBUG, "%s(): free previous av1 packet buffer %d\n",
4246 __func__, i);
4247 ni_aligned_free(p_packet->av1_p_buffer[i]);
4248 p_packet->av1_p_buffer[i] = NULL;
4249 p_packet->av1_p_data[i] = NULL;
4250 p_packet->av1_buffer_size[i] = 0;
4251 p_packet->av1_data_len[i] = 0;
4252 }
4253
4254 p_packet->av1_buffer_index = 0;
4255
4256END:
4257
4258 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
4259
4260 return retval;
4261}
4262
4263/*!*****************************************************************************
4264 * \brief Copy video packet accounting for alignment
4265 *
4266 * \param[in] p_destination Destination to where to copy to
4267 * \param[in] p_source Source from where to copy from
4268 * \param[in] cur_size current size
4269 * \param[out] p_leftover Pointer to the data that was left over
4270 * \param[out] p_prev_size Size of the data leftover ??
4271 *
4272 * \return On success Total number of bytes that were copied
4273 * On failure NI_RETCODE_FAILURE
4274 ******************************************************************************/
4275int ni_packet_copy(void* p_destination, const void* const p_source, int cur_size, void* p_leftover, int* p_prev_size)
4276{
4277 int copy_size = 0;
4278 int padding_size = 0;
4279 int prev_size = p_prev_size == NULL? 0 : *p_prev_size;
4280
4281 int total_size = cur_size + prev_size;
4282 uint8_t* p_src = (uint8_t*)p_source;
4283 uint8_t* p_dst = (uint8_t*)p_destination;
4284 uint8_t* p_lftover = (uint8_t*)p_leftover;
4285
4286 if (!p_prev_size)
4287 {
4289 }
4290
4291 ni_log(NI_LOG_TRACE, "%s(): enter, *prev_size=%d\n", __func__, *p_prev_size);
4292
4293 if ((0 == cur_size) && (0 == prev_size))
4294 {
4295 return copy_size;
4296 }
4297
4298 if (((0 != cur_size) && (!p_source)) || (!p_destination) || (!p_leftover))
4299 {
4300 return NI_RETCODE_FAILURE;
4301 }
4302
4303 copy_size = ((total_size + NI_MEM_PAGE_ALIGNMENT - 1) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
4304
4305 if (copy_size > total_size)
4306 {
4307 padding_size = copy_size - total_size;
4308 }
4309
4310 if (prev_size > 0)
4311 {
4312 memcpy(p_dst, p_lftover, prev_size);
4313 }
4314
4315 p_dst += prev_size;
4316
4317 memcpy(p_dst, p_src, cur_size);
4318
4319 if (padding_size)
4320 {
4321 p_dst += cur_size;
4322 memset(p_dst, 0, padding_size);
4323 }
4324
4326 "%s(): exit, cur_size=%d, copy_size=%d, "
4327 "prev_size=%d, padding_size=%d\n", __func__, cur_size,
4328 copy_size, *p_prev_size, padding_size);
4329
4330 *p_prev_size = 0;
4331
4332 return copy_size;
4333}
4334
4335/*!*****************************************************************************
4336 * \brief Add a new auxiliary data to a frame
4337 *
4338 * \param[in/out] frame a frame to which the auxiliary data should be added
4339 * \param[in] type type of the added auxiliary 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 int data_size)
4346{
4347 ni_aux_data_t *ret;
4348
4350 !(ret = malloc(sizeof(ni_aux_data_t))))
4351 {
4353 "ERROR: %s No memory or exceeding max aux_data number !\n",
4354 __func__);
4355 return NULL;
4356 }
4357
4358 ret->type = type;
4359 ret->size = data_size;
4360 ret->data = calloc(1, data_size);
4361 if (!ret->data)
4362 {
4363 ni_log(NI_LOG_ERROR, "ERROR: %s No memory for aux data !\n", __func__);
4364 free(ret);
4365 ret = NULL;
4366 } else
4367 {
4368 frame->aux_data[frame->nb_aux_data++] = ret;
4369 }
4370
4371 return ret;
4372}
4373
4374/*!*****************************************************************************
4375 * \brief Add a new auxiliary data to a frame and copy in the raw data
4376 *
4377 * \param[in/out] frame a frame to which the auxiliary data should be added
4378 * \param[in] type type of the added auxiliary data
4379 * \param[in] raw_data the raw data of the aux data
4380 * \param[in] data_size size of the added auxiliary data
4381 *
4382 * \return a pointer to the newly added aux data on success, NULL otherwise
4383 ******************************************************************************/
4385 ni_aux_data_type_t type,
4386 const uint8_t *raw_data,
4387 int data_size)
4388{
4389 ni_aux_data_t *ret = ni_frame_new_aux_data(frame, type, data_size);
4390 if (ret)
4391 {
4392 memcpy(ret->data, raw_data, data_size);
4393 }
4394 return ret;
4395}
4396
4397/*!*****************************************************************************
4398 * \brief Retrieve from the frame auxiliary data of a given type if exists
4399 *
4400 * \param[in] frame a frame from which the auxiliary data should be retrieved
4401 * \param[in] type type of the auxiliary data to be retrieved
4402 *
4403 * \return a pointer to the aux data of a given type on success, NULL otherwise
4404 ******************************************************************************/
4406 ni_aux_data_type_t type)
4407{
4408 int i;
4409 for (i = 0; i < frame->nb_aux_data; i++)
4410 {
4411 if (frame->aux_data[i]->type == type)
4412 {
4413 return frame->aux_data[i];
4414 }
4415 }
4416 return NULL;
4417}
4418
4419/*!*****************************************************************************
4420 * \brief If auxiliary data of the given type exists in the frame, free it
4421 * and remove it from the frame.
4422 *
4423 * \param[in/out] frame a frame from which the auxiliary data should be removed
4424 * \param[in] type type of the auxiliary data to be removed
4425 *
4426 * \return None
4427 ******************************************************************************/
4429{
4430 int i;
4431 ni_aux_data_t *aux;
4432
4433 for (i = 0; i < frame->nb_aux_data; i++)
4434 {
4435 aux = frame->aux_data[i];
4436 if (aux->type == type)
4437 {
4438 frame->aux_data[i] = frame->aux_data[frame->nb_aux_data - 1];
4439 frame->aux_data[frame->nb_aux_data - 1] = NULL;
4440 frame->nb_aux_data--;
4441 free(aux->data);
4442 free(aux);
4443 }
4444 }
4445}
4446
4447/*!*****************************************************************************
4448 * \brief Free and remove all auxiliary data from the frame.
4449 *
4450 * \param[in/out] frame a frame from which the auxiliary data should be removed
4451 *
4452 * \return None
4453 ******************************************************************************/
4455{
4456 int i;
4457 ni_aux_data_t *aux;
4458
4459 for (i = 0; i < frame->nb_aux_data; i++)
4460 {
4461 aux = frame->aux_data[i];
4462 free(aux->data);
4463 free(aux);
4464 }
4465 frame->nb_aux_data = 0;
4466}
4467
4468/*!*****************************************************************************
4469 * \brief Initialize default encoder parameters
4470 *
4471 * \param[out] param Pointer to a user allocated ni_xcoder_params_t
4472 * to initialize to default parameters
4473 * \param[in] fps_num Frames per second
4474 * \param[in] fps_denom FPS denomination
4475 * \param[in] bit_rate bit rate
4476 * \param[in] width frame width
4477 * \param[in] height frame height
4478 * \param[in] codec_format codec from ni_codec_format_t
4479 *
4480 * \return On success
4481 * NI_RETCODE_SUCCESS
4482 * On failure
4483 * NI_RETCODE_FAILURE
4484 * NI_RETCODE_INVALID_PARAM
4485 ******************************************************************************/
4487 int fps_num, int fps_denom,
4488 long bit_rate, int width,
4489 int height,
4490 ni_codec_format_t codec_format)
4491{
4492 ni_encoder_cfg_params_t *p_enc = NULL;
4493 int i = 0, j = 0;
4495
4496 //Initialize p_param structure
4497 if (!p_param)
4498 {
4499 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameters passed\n",
4500 __func__);
4501 retval = NI_RETCODE_INVALID_PARAM;
4502 LRETURN;
4503 }
4504
4505 ni_log(NI_LOG_DEBUG, "%s()\n", __func__);
4506
4507 //Initialize p_param structure
4508 memset(p_param, 0, sizeof(ni_xcoder_params_t));
4509
4510 p_enc = &p_param->cfg_enc_params;
4511
4512 // Rev. B: unified for HEVC/H.264
4513 p_enc->profile = 0;
4514 p_enc->level_idc = 0;
4515 p_enc->high_tier = 0;
4516
4517 if (QUADRA)
4519 else
4521
4522 p_enc->use_recommend_enc_params = 0;
4523 p_enc->cu_size_mode = 7;
4524 p_enc->max_num_merge = 2;
4525 p_enc->enable_dynamic_8x8_merge = 1;
4526 p_enc->enable_dynamic_16x16_merge = 1;
4527 p_enc->enable_dynamic_32x32_merge = 1;
4528
4529 p_enc->rc.trans_rate = 0;
4530
4531 p_enc->rc.enable_rate_control = 0;
4532 if (QUADRA)
4534 else
4536 p_enc->rc.enable_hvs_qp = 0;
4537 p_enc->rc.enable_hvs_qp_scale = 1;
4538 p_enc->rc.hvs_qp_scale = 2;
4539 p_enc->rc.min_qp = 8;
4540 p_enc->rc.max_qp = 51;
4541 p_enc->rc.max_delta_qp = 10;
4542
4543 // hrd is disabled if vbv_buffer_size=0, hrd is enabled if vbv_buffer_size is [10, 3000]
4544 p_enc->rc.vbv_buffer_size = -1;
4545 p_enc->rc.enable_filler = 0;
4546 p_enc->rc.enable_pic_skip = 0;
4547 p_enc->rc.vbv_max_rate = 0;
4548
4549 p_enc->roi_enable = 0;
4550
4552 // feature not supported on JPEG/AV1 - disable by default
4553 if (codec_format == NI_CODEC_FORMAT_JPEG ||
4554 codec_format == NI_CODEC_FORMAT_AV1)
4555 {
4557 }
4558
4559 p_enc->long_term_ref_enable = 0;
4560 p_enc->long_term_ref_interval = 0;
4561 p_enc->long_term_ref_count = 2;
4562
4563 p_enc->conf_win_top = 0;
4564 p_enc->conf_win_bottom = 0;
4565 p_enc->conf_win_left = 0;
4566 p_enc->conf_win_right = 0;
4567
4568 p_enc->intra_period = 120;
4569 p_enc->rc.intra_qp = 22;
4570 p_enc->rc.intra_qp_delta = -2;
4571 if (QUADRA)
4572 p_enc->rc.enable_mb_level_rc = 0;
4573 else
4574 p_enc->rc.enable_mb_level_rc = 1;
4575
4576 p_enc->decoding_refresh_type = 1;
4577
4578 p_enc->slice_mode = 0;
4579 p_enc->slice_arg = 0;
4580
4581 // Rev. B: H.264 only parameters.
4582 p_enc->enable_transform_8x8 = 1;
4583 p_enc->entropy_coding_mode = 1;
4584
4585 p_enc->intra_mb_refresh_mode = 0;
4586 p_enc->intra_mb_refresh_arg = 0;
4587 p_enc->intra_reset_refresh = 0;
4588
4590#ifndef QUADRA
4591 if (!QUADRA)
4592 {
4593 for (i = 0; i < NI_MAX_GOP_NUM; i++)
4594 {
4597 p_enc->custom_gop_params.pic_param[i].pic_qp = 0;
4598 p_enc->custom_gop_params.pic_param[i].num_ref_pic_L0 = 0;
4599 p_enc->custom_gop_params.pic_param[i].ref_poc_L0 = 0;
4600 p_enc->custom_gop_params.pic_param[i].ref_poc_L1 = 0;
4602 }
4603 }
4604 else // QUADRA
4605#endif
4606 {
4607 for (i = 0; i < NI_MAX_GOP_NUM; i++)
4608 {
4612 (float)0.3; // QP Factor range is between 0.3 and 1, higher values mean lower quality and less bits
4616 for (j = 0; j < NI_MAX_REF_PIC; j++)
4617 {
4618 p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic = 0;
4619 p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic_used = -1;
4620 }
4621 }
4622 }
4623
4624 p_param->source_width = width;
4625 p_param->source_height = height;
4626
4627 p_param->fps_number = fps_num;
4628 p_param->fps_denominator = fps_denom;
4629
4630 if (p_param->fps_number && p_param->fps_denominator)
4631 {
4632 p_enc->frame_rate = (int)(p_param->fps_number / p_param->fps_denominator);
4633 }
4634 else
4635 {
4636 p_enc->frame_rate = 30;
4637 }
4638
4639 p_param->bitrate = (int)bit_rate;
4640 p_param->roi_demo_mode = 0;
4641 p_param->reconf_demo_mode = 0; // for encoder reconfiguration testing
4642 p_param->force_pic_qp_demo_mode = 0;
4643 p_param->force_frame_type = 0;
4644 p_param->hdrEnableVUI = 0;
4645 p_param->cacheRoi = 0;
4646 p_param->low_delay_mode = 0;
4647 p_param->padding = 1;
4648 p_param->generate_enc_hdrs = 0;
4649 p_param->use_low_delay_poc_type = 0;
4650 p_param->rootBufId = 0;
4651 p_param->staticMmapThreshold = 0;
4652 p_param->zerocopy_mode = 1;
4653 p_param->luma_linesize = 0;
4654 p_param->chroma_linesize = 0;
4655 p_param ->enableCpuAffinity = 0;
4656
4658
4659 p_param->dolby_vision_profile = 0;
4660
4661 // encoder stream header VUI setting
4662 p_param->color_primaries = 2; // default COL_PRI_UNSPECIFIED
4663 p_param->color_transfer_characteristic = 2; // default COL_TRC_UNSPECIFIED
4664 p_param->color_space = 2; // default COL_SPC_UNSPECIFIED
4665 p_param->sar_num = 0; // default SAR numerator 0
4666 p_param->sar_denom = 1; // default SAR denominator 1
4667 p_param->video_full_range_flag = -1;
4668
4669 p_param->enable2PassGop = 0;
4671 p_param->minFramesDelay = 0;
4672 p_param->interval_of_psnr = 1;
4673 for (i = 0; i < NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL; i++) {
4674 for (j = 0; j < NI_CUSTOMIZE_ROI_QP_NUM; j++) {
4675 // 127 is invalid for delta qp and absolute qp
4676 p_param->customize_roi_qp_map[i][j] = 127;
4677 }
4678 }
4679
4680 //QUADRA
4681 p_enc->EnableAUD = 0;
4682 p_enc->lookAheadDepth = 0;
4683 p_enc->rdoLevel = (codec_format == NI_CODEC_FORMAT_JPEG) ? 0 : 1;
4684 p_enc->crf = -1;
4685 p_enc->HDR10MaxLight = 0;
4686 p_enc->HDR10AveLight = 0;
4687 p_enc->HDR10CLLEnable = 0;
4688 p_enc->EnableRdoQuant = -1;
4689 p_enc->ctbRcMode = 0;
4690 p_enc->gopSize = 0;
4691 p_enc->gopLowdelay = 0;
4692 p_enc->gdrDuration = 0;
4693 p_enc->hrdEnable = 0;
4694 p_enc->ltrRefInterval = 0;
4695 p_enc->ltrRefQpOffset = 0;
4696 p_enc->ltrFirstGap = 0;
4697 p_enc->ltrNextInterval = 1;
4698 p_enc->multicoreJointMode = 0;
4699 p_enc->qlevel = -1;
4700 p_enc->maxFrameSize = 0;
4701 p_enc->maxFrameSizeRatio = 0;
4702 p_enc->chromaQpOffset = 0;
4703 p_enc->tolCtbRcInter = (float)0.1;
4704 p_enc->tolCtbRcIntra = (float)0.1;
4705 p_enc->bitrateWindow = -255;
4706 p_enc->inLoopDSRatio = 1;
4707 p_enc->blockRCSize = 0;
4708 p_enc->rcQpDeltaRange = 10;
4709 p_enc->ctbRowQpStep = 0;
4710 p_enc->newRcEnable = -1;
4711 p_enc->colorDescPresent = 0;
4712 p_enc->colorPrimaries = 2;
4713 p_enc->colorTrc = 2;
4714 p_enc->colorSpace = 2;
4715 p_enc->aspectRatioWidth = 0;
4716 p_enc->aspectRatioHeight = 1;
4717 p_enc->videoFullRange = 0;
4719 p_enc->enable_ssim = 0;
4720 p_enc->HDR10Enable = 0;
4721 p_enc->HDR10dx0 = 0;
4722 p_enc->HDR10dy0 = 0;
4723 p_enc->HDR10dx1 = 0;
4724 p_enc->HDR10dy1 = 0;
4725 p_enc->HDR10dx2 = 0;
4726 p_enc->HDR10dy2 = 0;
4727 p_enc->HDR10wx = 0;
4728 p_enc->HDR10wy = 0;
4729 p_enc->HDR10maxluma = 0;
4730 p_enc->HDR10minluma = 0;
4731 p_enc->avcc_hvcc = 0;
4732 p_enc->av1_error_resilient_mode = 0;
4733 p_enc->temporal_layers_enable = 0;
4734 p_enc->crop_width = 0;
4735 p_enc->crop_height = 0;
4736 p_enc->hor_offset = 0;
4737 p_enc->ver_offset = 0;
4738 p_enc->crfMax = -1;
4739 p_enc->qcomp = (float)0.6;
4740 p_enc->noMbtree = 0;
4741 p_enc->noHWMultiPassSupport = 0;
4742 p_enc->cuTreeFactor = 5;
4743 p_enc->ipRatio = (float)1.4;
4744 p_enc->pbRatio = (float)1.3;
4745 p_enc->cplxDecay = (float)0.5;
4746 p_enc->pps_init_qp = -1;
4747 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)
4748 p_enc->pass1_qp = -1;
4749 p_enc->crfFloat = -1.0f;
4750 p_enc->hvsBaseMbComplexity = 15;
4751 p_enc->statistic_output_level = 0;
4752 p_enc->skip_frame_enable = 0;
4753 p_enc->max_consecutive_skip_num = 1;
4754 p_enc->skip_frame_interval = 0;
4755 p_enc->enableipRatio = 0;
4756 p_enc->enable_all_sei_passthru = 0;
4757 p_enc->iframe_size_ratio = 100;
4758 p_enc->crf_max_iframe_enable = 0;
4759 p_enc->vbv_min_rate = 0;
4760 p_enc->totalCuTreeDepth = 0;
4761 p_enc->adaptiveCuTree = 0;
4762 p_enc->preIntraHandling = 1;
4763 p_enc->baseLayerOnly = 0;
4764 p_enc->pastFrameMaxIntraRatio = 20;
4765 p_enc->linkFrameMaxIntraRatio = 40;
4766 p_enc->adaptiveLamdaMode = 0;
4767 p_enc->adaptiveCrfMode = 0;
4768 p_enc->qpScaleEnable = 0;
4769#ifdef XCODER_311
4770 p_enc->disable_adaptive_buffers = 1;
4771#else
4772 p_enc->disable_adaptive_buffers = 0;
4773#endif
4774 p_enc->disableBframeRdoq = 0;
4775 p_enc->forceBframeQpfactor = (float)-1.0;
4776 p_enc->tune_bframe_visual = 0;
4777 p_enc->enable_acq_limit = 0;
4778 p_enc->get_psnr_mode = 3;
4780 p_enc->motionConstrainedMode = 0;
4781 p_enc->still_image_detect_level = 0;
4782 p_enc->scene_change_detect_level = 0;
4783 p_enc->encMallocStrategy = 0;
4784 p_enc->enable_smooth_crf = 0;
4785 p_enc->enable_compensate_qp = 0;
4786 p_enc->spatial_layers = 1;
4787 p_enc->enable_timecode = 0;
4789 p_enc->vbvBufferReencode = 0;
4790 p_enc->disableAv1TimingInfo = 0;
4792 p_enc->preset_enabled = 0;
4793 p_enc->reset_dts_offset = 1;
4794 p_enc->getBitstreamFeatures = 0;
4795 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
4796 {
4797 p_enc->spatialLayerBitrate[i] = 0;
4798 p_enc->av1OpLevel[i] = 0;
4799 }
4800 p_enc->intraCompensateMode = 0;
4801 p_enc->customMinCoeffDiv = 0;
4802
4803 if (codec_format == NI_CODEC_FORMAT_AV1)
4804 {
4805 if (p_param->source_width < NI_PARAM_AV1_MIN_WIDTH)
4806 {
4808 LRETURN;
4809 }
4811 {
4813 LRETURN;
4814 }
4815 if (p_param->source_width > NI_PARAM_AV1_MAX_WIDTH)
4816 {
4818 LRETURN;
4819 }
4821 {
4823 LRETURN;
4824 }
4825 if (p_param->source_height * p_param->source_width >
4827 {
4829 LRETURN;
4830 }
4831 // AV1 8x8 alignment HW limitation is now worked around by FW cropping input resolution
4833 {
4834 ni_log(NI_LOG_ERROR, "AV1 Picture Width not aligned to %d - picture will be cropped\n",
4836 }
4838 {
4839 ni_log(NI_LOG_ERROR, "AV1 Picture Height not aligned to %d - picture will be cropped\n",
4841 }
4842 }
4843
4844 if (codec_format == NI_CODEC_FORMAT_JPEG)
4845 {
4846 if (p_param->source_width < NI_MIN_WIDTH)
4847 {
4849 LRETURN;
4850 }
4851 if (p_param->source_height < NI_MIN_HEIGHT)
4852 {
4854 LRETURN;
4855 }
4856 }
4857
4858 if (p_param->source_width > NI_PARAM_MAX_WIDTH)
4859 {
4861 LRETURN;
4862 }
4863 if (p_param->source_width < NI_PARAM_MIN_WIDTH)
4864 {
4866 LRETURN;
4867 }
4868
4869 if (p_param->source_height > NI_PARAM_MAX_HEIGHT)
4870 {
4872 LRETURN;
4873 }
4874 if (p_param->source_height < NI_PARAM_MIN_HEIGHT)
4875 {
4877 LRETURN;
4878 }
4879 if (p_param->source_height*p_param->source_width > NI_MAX_RESOLUTION_AREA)
4880 {
4882 LRETURN;
4883 }
4884
4885END:
4886
4887 return retval;
4888}
4889
4890/*!*****************************************************************************
4891 * \brief Initialize default decoder parameters
4892 *
4893 * \param[out] param Pointer to a user allocated ni_xcoder_params_t
4894 * to initialize to default parameters
4895 * \param[in] fps_num Frames per second
4896 * \param[in] fps_denom FPS denomination
4897 * \param[in] bit_rate bit rate
4898 * \param[in] width frame width
4899 * \param[in] height frame height
4900 *
4901 * \return On success
4902 * NI_RETCODE_SUCCESS
4903 * On failure
4904 * NI_RETCODE_FAILURE
4905 * NI_RETCODE_INVALID_PARAM
4906 ******************************************************************************/
4908 int fps_num, int fps_denom,
4909 long bit_rate, int width,
4910 int height)
4911{
4912 ni_decoder_input_params_t* p_dec = NULL;
4913 int i;
4915
4916 //Initialize p_param structure
4917 if (!p_param)
4918 {
4919 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameter passed\n",
4920 __func__);
4921 retval = NI_RETCODE_INVALID_PARAM;
4922 LRETURN;
4923 }
4924
4925 ni_log(NI_LOG_DEBUG, "%s\n", __func__);
4926
4927 //Initialize p_param structure
4928 memset(p_param, 0, sizeof(ni_xcoder_params_t));
4929
4930 p_dec = &p_param->dec_input_params;
4931
4932 p_param->source_width = width;
4933 p_param->source_height = height;
4934
4935 if(fps_num <= 0 || fps_denom <= 0)
4936 {
4937 fps_num = 30;
4938 fps_denom = 1;
4939 ni_log(NI_LOG_INFO, "%s(): FPS is not set, setting the default FPS to 30\n", __func__);
4940 }
4941
4942 p_param->fps_number = fps_num;
4943 p_param->fps_denominator = fps_denom;
4944
4945 p_dec->hwframes = 0;
4946 p_dec->mcmode = 0;
4947 p_dec->nb_save_pkt = 0;
4948 p_dec->enable_out1 = 0;
4949 p_dec->enable_out2 = 0;
4950 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
4951 {
4952 p_dec->force_8_bit[i] = 0;
4953 p_dec->semi_planar[i] = 0;
4954 p_dec->crop_mode[i] = NI_DEC_CROP_MODE_AUTO;
4955 p_dec->crop_whxy[i][0] = width;
4956 p_dec->crop_whxy[i][1] = height;
4957 p_dec->crop_whxy[i][2] = 0;
4958 p_dec->crop_whxy[i][3] = 0;
4959 p_dec->scale_wh[i][0] = 0;
4960 p_dec->scale_wh[i][1] = 0;
4961 p_dec->scale_long_short_edge[i] = 0;
4962 p_dec->scale_resolution_ceil[i] = 2;
4963 p_dec->scale_round[i] = -1;
4964 }
4966 p_dec->decoder_low_delay = 0;
4967 p_dec->force_low_delay = false;
4968 p_dec->enable_low_delay_check = 0;
4969 p_dec->decoder_disable_reorder = 0;
4971 p_dec->custom_sei_passthru = -1;
4974 p_dec->enable_advanced_ec = 1;
4976 p_dec->enable_ppu_scale_adapt = 0;
4977 p_dec->enable_ppu_scale_limit = 0;
4978 p_dec->max_extra_hwframe_cnt = 255; //uint8_max
4979 p_dec->pkt_pts_unchange = 0;
4980 p_dec->enable_all_sei_passthru = 0;
4981 p_dec->enable_follow_iframe = 0;
4983#ifdef XCODER_311
4984 p_dec->disable_adaptive_buffers = 1;
4985 p_dec->min_packets_delay = true;
4986 p_dec->reduce_dpb_delay = 1;
4987#else
4988 p_dec->disable_adaptive_buffers = 0;
4989 p_dec->min_packets_delay = false;
4990 p_dec->reduce_dpb_delay = 0;
4991#endif
4992 p_dec->survive_stream_err = 0;
4993 p_dec->skip_extra_headers = 0;
4994
4995 //-------init unused param start----------
4996
4997 p_param->bitrate = (int)bit_rate;
4998 p_param->reconf_demo_mode = 0; // for encoder reconfiguration testing
4999 p_param->force_pic_qp_demo_mode = 0;
5000 p_param->force_frame_type = 0;
5001 p_param->hdrEnableVUI = 0;
5002 p_param->cacheRoi = 0;
5003 p_param->low_delay_mode = 0;
5004 p_param->padding = 1;
5005 p_param->generate_enc_hdrs = 0;
5006 p_param->use_low_delay_poc_type = 0;
5007 p_param->dolby_vision_profile = 0;
5008
5009 // encoder stream header VUI setting
5010 p_param->color_primaries = 2; // default COL_PRI_UNSPECIFIED
5011 p_param->color_transfer_characteristic = 2; // default COL_TRC_UNSPECIFIED
5012 p_param->color_space = 2; // default COL_SPC_UNSPECIFIED
5013 p_param->sar_num = 0; // default SAR numerator 0
5014 p_param->sar_denom = 1; // default SAR denominator 1
5015 p_param->video_full_range_flag = -1;
5016
5017 //-------init unused param done----------
5018
5019END:
5020
5021 return retval;
5022}
5023
5024// read demo reconfig data file and parse out reconfig key/values in the format:
5025// key:val1,val2,val3,...val9 (max 9 values); only digit/:/,/newline is allowed
5026ni_retcode_t ni_parse_reconf_file(const char *reconf_file,
5028{
5029 char keyChar[10] = "";
5030 int key;
5031 char valChar[10] = "";
5032 int val;
5033 int valIdx = 1;
5034 int parseKey = 1;
5035 int idx = 0;
5036 int readc = EOF;
5037 FILE *reconf = NULL;
5038
5039 if (!reconf_file)
5040 {
5041 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5042 __func__);
5044 }
5045
5046 ni_fopen(&reconf, reconf_file, "r");
5047 if (!reconf)
5048 {
5049 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): Cannot open reconfig_file: %s\n",
5050 NI_ERRNO, __func__, reconf_file);
5052 }
5054
5055 while ((readc = fgetc(reconf)) != EOF)
5056 {
5057 //parse lines
5058 if (isdigit(readc))
5059 {
5060 if (parseKey)
5061 {
5062 ni_strncat(keyChar, 10, (const char *)(&readc), 1);
5063 }
5064 else
5065 {
5066 ni_strncat(valChar, 10, (const char *)(&readc), 1);
5067 }
5068 }
5069 else if (readc == ':')
5070 {
5071 parseKey = 0;
5072 key = atoi(keyChar);
5073 hash_map[idx][0] = key;
5074 }
5075 else if (readc == ',')
5076 {
5078 {
5080 "ERROR: Number of entries per line in reconfig file is greater then the "
5081 "limit of %d\n",
5083 retval = NI_RETCODE_INVALID_PARAM;
5084 break;
5085 }
5086 val = atoi(valChar);
5087 hash_map[idx][valIdx] = val;
5088 valIdx++;
5089 memset(valChar, 0, 10);
5090 }
5091 else if (readc == '\n')
5092 {
5094 {
5096 "ERROR: Number of lines in reconfig file is greater then the "
5097 "limit of %d\n",
5099 retval = NI_RETCODE_INVALID_PARAM;
5100 break;
5101 }
5102 parseKey = 1;
5103 val = atoi (valChar);
5104 hash_map[idx][valIdx] = val;
5105 valIdx = 1;
5106 memset(keyChar,0,10);
5107 memset(valChar,0,10);
5108 idx ++;
5109 }
5110 else
5111 {
5112 ni_log(NI_LOG_ERROR, "ERROR: character %c in reconfig file. this may lead to mistaken reconfiguration values\n", readc);
5113 }
5114 }
5115
5116 fclose(reconf);
5117
5118 if (NI_RETCODE_SUCCESS == retval && parseKey != 1)
5119 {
5121 "ERROR %d: %s(): Incorrect format / "
5122 "incomplete Key/Value pair in reconfig_file: %s\n",
5123 NI_ERRNO, __func__, reconf_file);
5125 }
5126
5127 return retval;
5128}
5129
5131 int8_t qp_map[][NI_CUSTOMIZE_ROI_QP_NUM])
5132{
5133 char valChar[5] = "";
5134 int val;
5135 int negative = 0;
5136 int qpIdx = 0;
5137 int levelIdx = 0;
5138 int readc = EOF;
5139 FILE *reconf = NULL;
5140
5141 if (!customize_file)
5142 {
5143 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5144 __func__);
5146 }
5147
5148 ni_fopen(&reconf, customize_file, "r");
5149 if (!reconf)
5150 {
5151 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): Cannot open reconfig_file: %s\n",
5152 NI_ERRNO, __func__, customize_file);
5154 }
5156
5157 while ((readc = fgetc(reconf)) != EOF)
5158 {
5159 //parse lines
5160 if (isdigit(readc))
5161 {
5162 ni_strncat(valChar, 5, (const char *)(&readc), 1);
5163 }
5164 else if (readc == '-') {
5165 negative = 1;
5166 }
5167 else if (readc == ',')
5168 {
5169 if (qpIdx >= NI_CUSTOMIZE_ROI_QP_NUM || levelIdx >= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL)
5170 {
5172 "ERROR: Number of qpIdx %d greater then the limit of %d or"
5173 "Number of levelIdx %d greater then the limit of %d\n",
5175 retval = NI_RETCODE_INVALID_PARAM;
5176 break;
5177 }
5178 if (!negative) {
5179 val = clip3(0, NI_MAX_QP_INFO, atoi(valChar));
5180 qp_map[levelIdx][qpIdx] = val;
5181 } else {
5182 val = clip3(0, 32, atoi(valChar));
5183 qp_map[levelIdx][qpIdx] = val * -1;
5184 }
5185 negative = 0;
5186 memset(valChar, 0, 5);
5187 qpIdx++;
5188 }
5189 else if (readc == '\n')
5190 {
5191 if (qpIdx >= NI_CUSTOMIZE_ROI_QP_NUM || levelIdx >= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL)
5192 {
5194 "ERROR: Number of qpIdx %d greater then the limit of %d or"
5195 "Number of levelIdx %d greater then the limit of %d\n",
5197 retval = NI_RETCODE_INVALID_PARAM;
5198 break;
5199 }
5200 if (!negative) {
5201 val = clip3(0, NI_MAX_QP_INFO, atoi(valChar));
5202 qp_map[levelIdx][qpIdx] = val;
5203 } else {
5204 val = clip3(0, 32, atoi(valChar));
5205 qp_map[levelIdx][qpIdx] = val * -1;
5206 }
5207 negative = 0;
5208 memset(valChar, 0, 5);
5209 qpIdx = 0;
5210 levelIdx++;
5211 }
5212 else
5213 {
5214 ni_log(NI_LOG_ERROR, "ERROR: character %c in reconfig file. this may lead to mistaken reconfiguration values\n", readc);
5215 }
5216 }
5217 fclose(reconf);
5218
5219 return retval;
5220}
5221
5222
5223#undef atoi
5224#undef atof
5225#define atoi(p_str) ni_atoi(p_str, &b_error)
5226#define atof(p_str) ni_atof(p_str, &b_error)
5227#define atobool(p_str) (ni_atobool(p_str, &b_error))
5228/*!*****************************************************************************
5229* \brief Set value referenced by name in decoder parameters structure
5230*
5231* \param[in] p_params Pointer to a user allocated ni_xcoder_params_t (used
5232* for decoder too for now ) to find and set a particular
5233* parameter
5234* \param[in] name String represented parameter name to search
5235* \param[in] value Parameter value to set
5236*
5237* \return On success
5238* NI_RETCODE_SUCCESS
5239* On failure
5240* NI_RETCODE_FAILURE
5241* NI_RETCODE_INVALID_PARAM
5242*******************************************************************************/
5244 const char *name, char *value)
5245{
5246 bool b_error = false;
5247 bool bNameWasBool = false;
5248 bool bValueWasNull = !value;
5249 ni_decoder_input_params_t* p_dec = NULL;
5250 char nameBuf[64] = { 0 };
5251 const char delim[2] = ",";
5252 const char xdelim[2] = "x";
5253 char *chunk;//for parsing out multi param input
5254 int i, j, k, ppu_index;
5255
5256 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
5257
5258 if (!p_params)
5259 {
5260 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5261 __func__);
5263 }
5264
5265 if (!name)
5266 {
5267 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
5268 __func__);
5270 }
5271 p_dec = &p_params->dec_input_params;
5272
5273 // skip -- prefix if provided
5274 if (name[0] == '-' && name[1] == '-')
5275 {
5276 name += 2;
5277 }
5278
5279 // s/_/-/g
5280 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
5281 {
5282 char* c;
5283 ni_strcpy(nameBuf, sizeof(nameBuf), name);
5284 while ((c = strchr(nameBuf, '_')) != 0)
5285 {
5286 *c = '-';
5287 }
5288 name = nameBuf;
5289 }
5290
5291 if (!value)
5292 {
5293 value = "true";
5294 }
5295 else if (value[0] == '=')
5296 {
5297 value++;
5298 }
5299
5300#if defined(_MSC_VER)
5301#define OPT(STR) else if (!_stricmp(name, STR))
5302#define OPT2(STR1, STR2) \
5303 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2))
5304#define OPT6(STR1, STR2, STR3, STR4, STR5, STR6) \
5305 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2) || \
5306 !_stricmp(name, STR3) || !_stricmp(name, STR4) || \
5307 !_stricmp(name, STR5) || !_stricmp(name, STR6))
5308#else
5309#define OPT(STR) else if (!strcasecmp(name, STR))
5310#define OPT2(STR1, STR2) else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2))
5311#define OPT6(STR1, STR2, STR3, STR4, STR5, STR6) \
5312 else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2) || \
5313 !strcasecmp(name, STR3) || !strcasecmp(name, STR4) || \
5314 !strcasecmp(name, STR5) || !strcasecmp(name, STR6))
5315#endif
5316 if (0); // suppress cppcheck
5318 {
5319 if (!strncmp(value, "hw", sizeof("hw"))){
5320 p_dec->hwframes = 1;
5321 }
5322 else if (!strncmp(value, "sw", sizeof("sw"))) {
5323 p_dec->hwframes = 0;
5324 }
5325 else{
5326 ni_log(NI_LOG_ERROR, "ERROR: %s(): out can only be <hw,sw> got %s\n",
5327 __func__, value);
5329 }
5330 }
5332 {
5333 if (atoi(value) == 1)
5334 p_dec->enable_out1 = 1;
5335 }
5337 {
5338 if (atoi(value) == 1)
5339 p_dec->enable_out2 = 1;
5340 }
5342 {
5343 if (atoi(value) == 1)
5344 p_dec->force_8_bit[0] = 1;
5345 }
5347 {
5348 if (atoi(value) == 1)
5349 p_dec->force_8_bit[1] = 1;
5350 }
5352 {
5353 if (atoi(value) == 1)
5354 p_dec->force_8_bit[2] = 1;
5355 }
5357 {
5358 if (atoi(value) == 1 || atoi(value) == 2)
5359 p_dec->semi_planar[0] = atoi(value);
5360 }
5362 {
5363 if (atoi(value) == 1 || atoi(value) == 2)
5364 p_dec->semi_planar[1] = atoi(value);
5365 }
5367 {
5368 if (atoi(value) == 1 || atoi(value) == 2)
5369 p_dec->semi_planar[2] = atoi(value);
5370 }
5372 {
5373 if (!strncmp(value, "manual", sizeof("manual"))) {
5375 }
5376 else if (!strncmp(value, "auto", sizeof("auto"))) {
5377 p_dec->crop_mode[0] = NI_DEC_CROP_MODE_AUTO;
5378 }
5379 else{
5381 "ERROR: %s():cropMode0 input can only be <manual,auto> got %s\n",
5382 __func__, value);
5384 }
5385 }
5387 {
5388 if (!strncmp(value, "manual", sizeof("manual"))) {
5390 }
5391 else if (!strncmp(value, "auto", sizeof("auto"))) {
5392 p_dec->crop_mode[1] = NI_DEC_CROP_MODE_AUTO;
5393 }
5394 else {
5396 "ERROR: %s():cropMode1 input can only be <manual,auto> got %s\n",
5397 __func__, value);
5399 }
5400 }
5402 {
5403 if (!strncmp(value, "manual", sizeof("manual"))) {
5405 }
5406 else if (!strncmp(value, "auto", sizeof("auto"))) {
5407 p_dec->crop_mode[2] = NI_DEC_CROP_MODE_AUTO;
5408 }
5409 else {
5411 "ERROR: %s():cropMode2 input can only be <manual,auto> got %s\n",
5412 __func__, value);
5414 }
5415 }
5417 {
5418 char *saveptr = NULL;
5419 chunk = ni_strtok(value, delim, &saveptr);
5420 for (i = 0; i < 4; i++)
5421 {
5422 if (chunk != NULL)
5423 {
5424 j = k = 0;
5425 while (chunk[j])
5426 {
5427 if (chunk[j] != '\"' && chunk[j] != '\'')
5428 {
5429 p_dec->cr_expr[0][i][k] = chunk[j];
5430 k++;
5431 }
5433 {
5435 }
5436 }
5437 chunk = ni_strtok(NULL, delim, &saveptr);
5438 }
5439 else if (i == 2 ) //default offsets to centered image if not specified, may need recalc
5440 {
5441 ni_strcpy(p_dec->cr_expr[0][i], sizeof(p_dec->cr_expr[0][i]), "in_w/2-out_w/2");
5442 }
5443 else if (i == 3)
5444 {
5445 ni_strcpy(p_dec->cr_expr[0][i], sizeof(p_dec->cr_expr[0][i]), "in_h/2-out_h/2");
5446 } else
5447 {
5449 }
5450 }
5451 }
5453 {
5454 char *saveptr = NULL;
5455 chunk = ni_strtok(value, delim, &saveptr);
5456 for (i = 0; i < 4; i++)
5457 {
5458 if (chunk != NULL)
5459 {
5460 j = k = 0;
5461 while (chunk[j])
5462 {
5463 if (chunk[j] != '\"' && chunk[j] != '\'')
5464 {
5465 p_dec->cr_expr[1][i][k] = chunk[j];
5466 k++;
5467 }
5469 {
5471 }
5472 }
5473 chunk = ni_strtok(NULL, delim, &saveptr);
5474 }
5475 else if (i == 2) //default offsets to centered image if not specified, may need recalc
5476 {
5477 ni_strcpy(p_dec->cr_expr[1][i], sizeof(p_dec->cr_expr[1][i]), "in_w/2-out_w/2");
5478 }
5479 else if (i == 3)
5480 {
5481 ni_strcpy(p_dec->cr_expr[1][i], sizeof(p_dec->cr_expr[1][i]), "in_h/2-out_h/2");
5482 }
5483 else
5484 {
5486 }
5487 }
5488 }
5490 {
5491 char *saveptr = NULL;
5492 chunk = ni_strtok(value, delim, &saveptr);
5493 for (i = 0; i < 4; i++)
5494 {
5495 if (chunk != NULL)
5496 {
5497 j = k = 0;
5498 while (chunk[j])
5499 {
5500 if (chunk[j] != '\"' && chunk[j] != '\'')
5501 {
5502 p_dec->cr_expr[2][i][k] = chunk[j];
5503 k++;
5504 }
5506 {
5508 }
5509 }
5510 chunk = ni_strtok(NULL, delim, &saveptr);
5511 }
5512 else if (i == 2) //default offsets to centered image if not specified, may need recalc
5513 {
5514 ni_strcpy(p_dec->cr_expr[2][i], sizeof(p_dec->cr_expr[2][i]), "in_w/2-out_w/2");
5515 }
5516 else if (i == 3)
5517 {
5518 ni_strcpy(p_dec->cr_expr[2][i], sizeof(p_dec->cr_expr[2][i]), "in_h/2-out_h/2");
5519 }
5520 else
5521 {
5523 }
5524 }
5525 }
5527 {
5528 chunk = value;
5529 i = 0; // 'x' character counter
5530 while (*chunk++) {
5531 if (*chunk == xdelim[0]) {
5532 i++;
5533 }
5534 }
5535 if (i != 1) {
5537 }
5538 chunk = NULL;
5539
5540 char *saveptr = NULL;
5541 chunk = ni_strtok(value, xdelim, &saveptr);
5542 for (i = 0; i < 2; i++)
5543 {
5544 if (chunk != NULL)
5545 {
5546 j = k = 0;
5547 while (chunk[j])
5548 {
5549 if (chunk[j] != '\"' && chunk[j] != '\'')
5550 {
5551 p_dec->sc_expr[0][i][k] = chunk[j];
5552 k++;
5553 }
5555 {
5557 }
5558 }
5559 chunk = ni_strtok(NULL, xdelim, &saveptr);
5560 }
5561 else
5562 {
5564 }
5565 }
5566 }
5568 {
5569 chunk = value;
5570 i = 0; // 'x' character counter
5571 while (*chunk++) {
5572 if (*chunk == xdelim[0]) {
5573 i++;
5574 }
5575 }
5576 if (i != 1) {
5578 }
5579 chunk = NULL;
5580
5581 char *saveptr = NULL;
5582 chunk = ni_strtok(value, xdelim, &saveptr);
5583 for (i = 0; i < 2; i++)
5584 {
5585 if (chunk != NULL)
5586 {
5587 j = k = 0;
5588 while (chunk[j])
5589 {
5590 if (chunk[j] != '\"' && chunk[j] != '\'')
5591 {
5592 p_dec->sc_expr[1][i][k] = chunk[j];
5593 k++;
5594 }
5596 {
5598 }
5599 }
5600 chunk = ni_strtok(NULL, xdelim, &saveptr);
5601 }
5602 else
5603 {
5605 }
5606 }
5607 }
5609 {
5610 chunk = value;
5611 i = 0; // 'x' character counter
5612 while (*chunk++) {
5613 if (*chunk == xdelim[0]) {
5614 i++;
5615 }
5616 }
5617 if (i != 1) {
5619 }
5620 chunk = NULL;
5621
5622 char *saveptr = NULL;
5623 chunk = ni_strtok(value, xdelim, &saveptr);
5624 for (i = 0; i < 2; i++)
5625 {
5626 if (chunk != NULL)
5627 {
5628 j = k = 0;
5629 while (chunk[j])
5630 {
5631 if (chunk[j] != '\"' && chunk[j] != '\'')
5632 {
5633 p_dec->sc_expr[2][i][k] = chunk[j];
5634 k++;
5635 }
5637 {
5639 }
5640 }
5641 chunk = ni_strtok(NULL, xdelim, &saveptr);
5642 }
5643 else
5644 {
5646 }
5647 }
5648 }
5652 {
5653 chunk = value;
5654 if (chunk != NULL)
5655 {
5656 ppu_index = name[5] - '0';
5657 i = name[6] == 'w' ? 0 : 1;
5658 j = k = 0;
5659 while (chunk[j])
5660 {
5661 if (chunk[j] != '\"' && chunk[j] != '\'')
5662 {
5663 p_dec->sc_expr[ppu_index][i][k] = chunk[j];
5664 k++;
5665 }
5667 {
5669 }
5670 }
5671 }
5672 }
5674 {
5675 if ((atoi(value) < 0) || (atoi(value) > 2))
5676 {
5678 }
5679 p_dec->scale_long_short_edge[0] = atoi(value);
5680 }
5682 {
5683 if ((atoi(value) < 0) || (atoi(value) > 2))
5684 {
5686 }
5687 p_dec->scale_long_short_edge[1] = atoi(value);
5688 }
5690 {
5691 if ((atoi(value) < 0) || (atoi(value) > 2))
5692 {
5694 }
5695 p_dec->scale_long_short_edge[2] = atoi(value);
5696 }
5698 {
5699 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5700 {
5701 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5702 "and must be even number and less than or equal to 128. Got: %s\n",
5703 __func__, NI_DEC_PARAM_SCALE_0_RES_CEIL, value);
5704
5706 }
5707 p_dec->scale_resolution_ceil[0] = atoi(value);
5708 }
5710 {
5711 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5712 {
5713 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5714 "and must be even number and less than or equal to 128. Got: %s\n",
5715 __func__, NI_DEC_PARAM_SCALE_1_RES_CEIL, value);
5717 }
5718 p_dec->scale_resolution_ceil[1] = atoi(value);
5719 }
5721 {
5722 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5723 {
5724 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5725 "and must be even number and less than or equal to 128. Got: %s\n",
5726 __func__, NI_DEC_PARAM_SCALE_2_RES_CEIL, value);
5728 }
5729 p_dec->scale_resolution_ceil[2] = atoi(value);
5730 }
5732 {
5733 if (!strncmp(value, "up", sizeof("up"))){
5734 p_dec->scale_round[0] = 0;
5735 }
5736 else if (!strncmp(value, "down", sizeof("down"))) {
5737 p_dec->scale_round[0] = 1;
5738 }
5739 else{
5740 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5741 __func__, NI_DEC_PARAM_SCALE_0_ROUND, value);
5743 }
5744 }
5746 {
5747 if (!strncmp(value, "up", sizeof("up"))){
5748 p_dec->scale_round[1] = 0;
5749 }
5750 else if (!strncmp(value, "down", sizeof("down"))) {
5751 p_dec->scale_round[1] = 1;
5752 }
5753 else{
5754 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5755 __func__, NI_DEC_PARAM_SCALE_1_ROUND, value);
5757 }
5758 }
5760 {
5761 if (!strncmp(value, "up", sizeof("up"))){
5762 p_dec->scale_round[2] = 0;
5763 }
5764 else if (!strncmp(value, "down", sizeof("down"))) {
5765 p_dec->scale_round[2] = 1;
5766 }
5767 else{
5768 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5769 __func__, NI_DEC_PARAM_SCALE_2_ROUND, value);
5771 }
5772 }
5774 {
5775 if ((atoi(value) != 0) && (atoi(value) != 1))
5776 {
5778 }
5779 p_dec->mcmode = atoi(value);
5780 }
5782 {
5783 if (atoi(value) < 0)
5784 {
5786 }
5787 p_dec->nb_save_pkt = atoi(value);
5788 }
5790 {
5791 if ((atoi(value) < NI_MIN_KEEP_ALIVE_TIMEOUT) ||
5793 {
5795 }
5796 p_dec->keep_alive_timeout = atoi(value);
5797 }
5799 {
5800 if (atoi(value) < 0)
5801 {
5803 }
5804 p_dec->decoder_low_delay = atoi(value);
5805 }
5807 {
5808 if ((atoi(value) != 0) && (atoi(value) != 1))
5809 {
5811 }
5812 p_dec->force_low_delay = atoi(value);
5813 }
5815 {
5816 if (atoi(value) < 0)
5817 {
5819 }
5820 p_dec->enable_low_delay_check = atoi(value);
5821 }
5823 {
5824 if (atoi(value) < 0)
5825 {
5827 }
5828 p_dec->decoder_disable_reorder = atoi(value);
5829 }
5831 {
5832 if ((atoi(value) != 0) && (atoi(value) != 1))
5833 {
5835 }
5836 p_dec->min_packets_delay = atoi(value);
5837 }
5839 {
5840 if (atoi(value) != NI_ENABLE_USR_DATA_SEI_PASSTHRU &&
5842 {
5844 }
5845 p_dec->enable_user_data_sei_passthru = atoi(value);
5846 }
5848 {
5849 if (atoi(value) < NI_MIN_CUSTOM_SEI_PASSTHRU ||
5851 {
5853 }
5854 p_dec->custom_sei_passthru = atoi(value);
5855 }
5857 {
5859 {
5861 }
5862 p_dec->svct_decoding_layer = atoi(value);
5863 }
5865 {
5866 if (atoi(value) >= NI_DDR_PRIORITY_MAX ||
5867 atoi(value) <= NI_DDR_PRIORITY_NONE)
5868 {
5870 }
5871 p_params->ddr_priority_mode = atoi(value);
5872 }
5874 {
5875 if (strncmp(value, "tolerant", sizeof("tolerant")) == 0) {
5877 } else if (strncmp(value, "ignore", sizeof("ignore")) == 0) {
5879 } else if (strncmp(value, "skip", sizeof("skip")) == 0) {
5881 } else if (strncmp(value, "best_effort", sizeof("best_effort")) == 0) {
5883 } else if (strncmp(value, "limited_error", sizeof("limited_error")) == 0) {
5885 } else if (strncmp(value, "best_effort_out_dc", sizeof("best_effort_out_dc")) == 0) {
5887 } else {
5889 }
5890 }
5892 {
5893 if (atoi(value) != 0 &&
5894 atoi(value) != 1 &&
5895 atoi(value) != 2)
5896 {
5898 }
5899 p_dec->enable_advanced_ec = atoi(value);
5900 }
5902 {
5903 if (atoi(value) < 0 || (atoi(value) > 100))
5904 {
5906 }
5907 p_dec->error_ratio_threshold = atoi(value);
5908 }
5910 {
5911 if (atoi(value) < 0 || (atoi(value) > 2))
5912 {
5914 }
5915 p_dec->enable_ppu_scale_adapt = atoi(value);
5916 }
5918 {
5919 if (atoi(value) < 0 || (atoi(value) > 1))
5920 {
5922 }
5923 p_dec->enable_ppu_scale_limit = atoi(value);
5924 }
5926 {
5927 if (atoi(value) < 0 || atoi(value) > 255)
5928 {
5930 }
5931 p_dec->max_extra_hwframe_cnt = atoi(value);
5932 }
5934 {
5935 if (atoi(value) < 0 || atoi(value) > 1)
5936 {
5938 }
5939 p_dec->skip_pts_guess = atoi(value);
5940 }
5942 {
5943 if (atoi(value) != 0 && atoi(value) != 1)
5944 {
5946 }
5947 p_dec->pkt_pts_unchange = atoi(value);
5948 }
5950 {
5951 if (atoi(value) < 0 ||
5952 atoi(value) > 1)
5953 {
5955 }
5956 p_dec->enable_all_sei_passthru = atoi(value);
5957 }
5959 {
5960 if (atoi(value) != 0 && atoi(value) != 1)
5961 {
5963 }
5964 p_dec->enable_follow_iframe = atoi(value);
5965 }
5967 {
5968 if (atoi(value) < 0 ||
5969 atoi(value) > 1)
5970 {
5972 }
5973 p_dec->disable_adaptive_buffers = atoi(value);
5974 }
5976 {
5977 if (atoi(value) < 0 || atoi(value) > 1)
5978 {
5980 }
5981 p_dec->survive_stream_err = atoi(value);
5982 }
5984 {
5985 if ((atoi(value) != 0) && (atoi(value) != 1))
5986 {
5988 }
5989 p_dec->reduce_dpb_delay = atoi(value);
5990 }
5992 {
5993 if ((atoi(value) != 0) && (atoi(value) != 1))
5994 {
5996 }
5997 p_dec->skip_extra_headers = atoi(value);
5998 }
6000 {
6001 if ((atoi(value) != 0) && (atoi(value) != 1))
6002 {
6004 }
6005 p_params->enableCpuAffinity = atoi(value);
6006 }
6007 else
6008 {
6010 }
6011
6012#undef OPT
6013#undef atobool
6014#undef atoi
6015#undef atof
6016 b_error |= bValueWasNull && !bNameWasBool;
6017
6018 ni_log(NI_LOG_TRACE, "%s: exit, b_error=%d\n", __func__, b_error);
6019
6021}
6022
6023#undef atoi
6024#undef atof
6025#define atoi(p_str) ni_atoi(p_str, &b_error)
6026#define atof(p_str) ni_atof(p_str, &b_error)
6027#define atobool(p_str) (ni_atobool(p_str, &b_error))
6028
6029/*!*****************************************************************************
6030 * \brief Set value referenced by name in encoder parameters structure
6031 *
6032 * \param[in] p_params Pointer to a user allocated ni_xcoder_params_t
6033 * to find and set a particular parameter
6034 * \param[in] name String represented parameter name to search
6035 * \param[in] value Parameter value to set
6036*
6037 * \return On success
6038 * NI_RETCODE_SUCCESS
6039 * On failure
6040 * NI_RETCODE_FAILURE
6041 * NI_RETCODE_INVALID_PARAM
6042 ******************************************************************************/
6044 const char *name, const char *value)
6045{
6046 bool b_error = false;
6047 bool bNameWasBool = false;
6048 bool bValueWasNull = !value;
6049 ni_encoder_cfg_params_t *p_enc = NULL;
6050 char nameBuf[64] = { 0 };
6051 int i,j,k;
6052
6053 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
6054
6055 if (!p_params)
6056 {
6057 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
6058 __func__);
6060 }
6061
6062 if ( !name )
6063 {
6064 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
6065 __func__);
6067 }
6068 p_enc = &p_params->cfg_enc_params;
6069 // skip -- prefix if provided
6070 if (name[0] == '-' && name[1] == '-')
6071 {
6072 name += 2;
6073 }
6074
6075 // s/_/-/g
6076 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
6077 {
6078 char* c;
6079 ni_strcpy(nameBuf, sizeof(nameBuf), name);
6080 while ((c = strchr(nameBuf, '_')) != 0)
6081 {
6082 *c = '-';
6083 }
6084 name = nameBuf;
6085 }
6086
6087 if (!value)
6088 {
6089 value = "true";
6090 }
6091 else if (value[0] == '=')
6092 {
6093 value++;
6094 }
6095
6096#if defined(_MSC_VER)
6097#define OPT(STR) else if (!_stricmp(name, STR))
6098#define OPT2(STR1, STR2) \
6099 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2))
6100#else
6101#define OPT(STR) else if (!strcasecmp(name, STR))
6102#define OPT2(STR1, STR2) else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2))
6103#endif
6104#define COMPARE(STR1, STR2, STR3) \
6105 if ((atoi(STR1) > (STR2)) || (atoi(STR1) < (STR3))) \
6106 { \
6107 return NI_RETCODE_PARAM_ERROR_OOR; \
6108 }
6109 if (0); // suppress cppcheck
6111 {
6112 if (AV_CODEC_DEFAULT_BITRATE == p_params->bitrate)
6113 {
6114 if (atoi(value) > NI_MAX_BITRATE)
6115 {
6117 }
6118 if (atoi(value) < NI_MIN_BITRATE)
6119 {
6121 }
6122 p_params->bitrate = atoi(value);
6123 }
6124 }
6126 {
6127 p_params->reconf_demo_mode = atoi(value); // for encoder reconfiguration testing
6128 }
6130 {
6131 ni_retcode_t retval = ni_parse_reconf_file(value, p_params->reconf_hash);
6132 if (retval != NI_RETCODE_SUCCESS) // for encoder reconfiguration testing
6133 {
6134 return retval;
6135 }
6136 }
6138 {
6139 // for encoder reconfiguration testing
6140 p_params->roi_demo_mode = atoi(value);
6141 if ((p_params->roi_demo_mode < 0) || (p_params->roi_demo_mode > 2))
6142 {
6144 }
6145 }
6147 {
6148 if (0 > atoi(value))
6149 {
6151 }
6152 p_params->low_delay_mode = atoi(value);
6153 }
6155 {
6156 if (atoi(value) < 0 || atoi(value) > 7)
6157 {
6159 }
6160 p_params->minFramesDelay = atoi(value);
6161 }
6163 {
6164 p_params->padding = atoi(value);
6165 }
6166#ifndef DEPRECATION_AS_ERROR
6168 {
6169 if (0 != atoi(value) && 1 != atoi(value))
6170 {
6172 }
6173 p_params->generate_enc_hdrs = atoi(value);
6174 // genHdrs is deprecated in favour of libavcodec parameter -gen_global_headers
6176 }
6177#endif
6179 {
6180 if (0 != atoi(value) && 1 != atoi(value))
6181 {
6183 }
6184 p_params->use_low_delay_poc_type = atoi(value);
6185 }
6187 {
6188 if (QUADRA)
6189 {
6191 }
6192 p_params->force_frame_type = atoi(value);
6193 }
6195 {
6196 p_enc->profile = atoi(value);
6197 }
6199 {
6203 if (atof(value) <= 10)
6204 {
6205 p_enc->level_idc = (int)(10 * atof(value) + .5);
6206 }
6207 else
6208 {
6209 p_enc->level_idc = atoi(value);
6210 }
6211 }
6213 {
6214 p_enc->high_tier = atobool(value);
6215 }
6217 {
6218 p_params->log = atoi(value);
6219 if (b_error)
6220 {
6221 b_error = false;
6222 p_params->log = ni_parse_name(value, g_xcoder_log_names, &b_error) - 1;
6223 }
6224 }
6226 {
6227 if ((atoi(value) > NI_MAX_GOP_PRESET_IDX) || (atoi(value) < NI_MIN_GOP_PRESET_IDX))
6228 {
6230 }
6231 p_enc->gop_preset_index = atoi(value);
6232 }
6234 {
6236 {
6238 }
6239
6240 p_enc->use_recommend_enc_params = atoi(value);
6241 }
6243 {
6244 if (QUADRA)
6245 {
6247 }
6248 if (((atoi(value) > NI_MAX_CU_SIZE_MODE) || (atoi(value) < NI_MIN_CU_SIZE_MODE)) && (atoi(value) != NI_DEFAULT_CU_SIZE_MODE))
6249 {
6251 }
6252
6253 p_enc->cu_size_mode = atoi(value);
6254 }
6256 {
6257 if (QUADRA)
6258 {
6260 }
6261 if ((atoi(value) > NI_MAX_MAX_NUM_MERGE) || (atoi(value) < NI_MIN_MAX_NUM_MERGE))
6262 {
6264 }
6265
6266 p_enc->max_num_merge = atoi(value);
6267 }
6269 {
6270 if (QUADRA)
6271 {
6273 }
6274 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6275 {
6277 }
6278
6279 p_enc->enable_dynamic_8x8_merge = atoi(value);
6280 }
6282 {
6283 if (QUADRA)
6284 {
6286 }
6287 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6288 {
6290 }
6291
6292 p_enc->enable_dynamic_16x16_merge = atoi(value);
6293 }
6295 {
6296 if (QUADRA)
6297 {
6299 }
6300 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6301 {
6303 }
6304
6305 p_enc->enable_dynamic_32x32_merge = atoi(value);
6306 }
6308 {
6309 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6310 {
6312 }
6313
6314 p_enc->rc.enable_rate_control = atoi(value);
6315 }
6317 {
6318 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6319 {
6321 }
6322
6323 p_enc->rc.enable_cu_level_rate_control = atoi(value);
6324 }
6326 {
6327 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6328 {
6330 }
6331 p_enc->rc.enable_hvs_qp = atoi(value);
6332 }
6334 {
6335 if (QUADRA)
6336 {
6338 }
6339 p_enc->rc.enable_hvs_qp_scale = atoi(value);
6340 }
6342 {
6343 p_enc->rc.hvs_qp_scale = atoi(value);
6344 }
6346 {
6347 p_enc->rc.min_qp = atoi(value);
6348 }
6350 {
6351 p_enc->rc.max_qp = atoi(value);
6352 }
6354 {
6355 if (QUADRA)
6356 {
6358 }
6359 p_enc->rc.max_delta_qp = atoi(value);
6360 }
6361#ifndef DEPRECATION_AS_ERROR
6363 {
6364 if ((atoi(value) > 51) || (atoi(value) < -1))
6365 {
6367 }
6368 p_enc->crf = atoi(value);
6369 }
6370#endif
6372 {
6373 p_enc->rc.vbv_buffer_size = atoi(value);
6374 if (QUADRA)
6375 {
6376 // RcInitDelay is deprecated and replaced with vbvBufferSize. But still accept the value.
6378 }
6379 }
6381 {
6382 p_enc->rc.vbv_buffer_size = atoi(value);
6383 }
6385 {
6386 p_enc->rc.vbv_max_rate = atoi(value);
6387 }
6389 {
6390 p_enc->rc.enable_filler = atoi(value);
6391 if (QUADRA)
6392 {
6393 // cbr is deprecated and replaced with fillerEnable. But still accept the value.
6395 }
6396 }
6398 {
6399 p_enc->rc.enable_filler = atoi(value);
6400 }
6402 {
6403 if (0 != atoi(value) && 1 != atoi(value))
6404 {
6406 }
6407 // Currenly pic skip is supported for low delay gops only - pic skip issues tracked by QDFW-1785/1958
6408 p_enc->rc.enable_pic_skip = atoi(value);
6409 }
6410#ifndef DEPRECATION_AS_ERROR
6412#else
6414#endif
6415 {
6416#ifdef _MSC_VER
6417 if (!_strnicmp(value, "ratio", 5))
6418#else
6419 if (!strncasecmp(value, "ratio", 5))
6420#endif
6421 {
6422 char value_buf[32] = {0};
6423 for (i = 0; i < sizeof(value_buf); i++)
6424 {
6425 if (value[i+6] == ']')
6426 {
6427 break;
6428 }
6429 value_buf[i] = value[i+6];
6430 }
6431 if (i == sizeof(value_buf) || atoi(value_buf) < 0)
6432 {
6434 }
6435
6436 p_enc->maxFrameSizeRatio = atoi(value_buf);
6437 }
6438 else
6439 {
6440 int size = atoi(value);
6441 if (size < NI_MIN_FRAME_SIZE)
6442 {
6444 }
6445 p_enc->maxFrameSize = (size > NI_MAX_FRAME_SIZE) ? NI_MAX_FRAME_SIZE : size;
6446 }
6447 }
6449 {
6450#ifdef _MSC_VER
6451 if (!_strnicmp(value, "ratio", 5))
6452#else
6453 if (!strncasecmp(value, "ratio", 5))
6454#endif
6455 {
6456 char value_buf[32] = {0};
6457 for (i = 0; i < sizeof(value_buf); i++)
6458 {
6459 if (value[i+6] == ']')
6460 {
6461 break;
6462 }
6463 value_buf[i] = value[i+6];
6464 }
6465 if (i == sizeof(value_buf) || atoi(value_buf) < 0)
6466 {
6468 }
6469
6470 p_enc->maxFrameSizeRatio = atoi(value_buf);
6471 }
6472 else
6473 {
6474 int size = atoi(value) / 8;
6475 if (size < NI_MIN_FRAME_SIZE)
6476 {
6478 }
6479 p_enc->maxFrameSize = (size > NI_MAX_FRAME_SIZE) ? NI_MAX_FRAME_SIZE : size;
6480 }
6481 }
6483 {
6484 if (0 != atoi(value) && 1 != atoi(value))
6485 {
6487 }
6488 p_enc->forced_header_enable = atoi(value);
6489 }
6491 {
6492 p_enc->roi_enable = atoi(value);
6493 }
6495 {
6496 p_enc->conf_win_top = atoi(value);
6497 }
6499 {
6500 p_enc->conf_win_bottom = atoi(value);
6501 }
6503 {
6504 p_enc->conf_win_left = atoi(value);
6505 }
6507 {
6508 p_enc->conf_win_right = atoi(value);
6509 }
6511 {
6512 p_enc->intra_period = atoi(value);
6513 //p_enc->bitrateWindow = p_enc->intra_period;
6514 }
6516 {
6517 if (atoi(value) > NI_MAX_BITRATE)
6518 {
6520 }
6521 if (atoi(value) < NI_MIN_BITRATE)
6522 {
6524 }
6525 p_enc->rc.trans_rate = atoi(value);
6526 }
6528 {
6529 if (atoi(value) <= 0 )
6530 {
6532 }
6533 p_params->fps_number = atoi(value);
6534 p_params->fps_denominator = 1;
6535 p_enc->frame_rate = p_params->fps_number;
6536 }
6538 {
6539 if (atoi(value) <= 0)
6540 {
6542 }
6543 p_params->fps_denominator = atoi(value);
6544 p_enc->frame_rate = (int)(p_params->fps_number / p_params->fps_denominator);
6545 }
6547 {
6548 if ((atoi(value) > NI_MAX_INTRA_QP) || (atoi(value) < NI_MIN_INTRA_QP))
6549 {
6551 }
6552
6553 p_enc->rc.intra_qp = atoi(value);
6554 }
6556 {
6557 if ((atoi(value) > NI_MAX_INTRA_QP_DELTA) ||
6558 (atoi(value) < NI_MIN_INTRA_QP_DELTA))
6559 {
6561 }
6562
6563 p_enc->rc.intra_qp_delta = atoi(value);
6564 }
6566 {
6567 if ((atoi(value) > NI_MAX_INTRA_QP) || (atoi(value) < NI_MIN_INTRA_QP))
6568 {
6570 }
6571 p_params->force_pic_qp_demo_mode = atoi(value);
6572 }
6574 {
6575 if (QUADRA)
6576 {
6578 }
6580 {
6582 }
6583 p_enc->decoding_refresh_type = atoi(value);
6584 }
6586 {
6587 if (0 != atoi(value) && 1 != atoi(value))
6588 {
6590 }
6591 p_enc->intra_reset_refresh = atoi(value);
6592 }
6593 // Rev. B: H.264 only parameters.
6595 {
6596 if (QUADRA)
6597 {
6599 }
6600 p_enc->enable_transform_8x8 = atoi(value);
6601 }
6603 {
6604 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6605 {
6607 }
6608 p_enc->slice_mode = atoi(value);
6609 }
6611 {
6612 p_enc->slice_arg = atoi(value);
6613 }
6615 {
6616 if (0 != atoi(value) && 1 != atoi(value))
6617 {
6619 }
6620 p_enc->entropy_coding_mode = atoi(value);
6621 }
6622// Rev. B: shared between HEVC and H.264
6624 {
6625 p_enc->intra_mb_refresh_mode = atoi(value);
6626 }
6628 {
6629 p_enc->intra_mb_refresh_arg = atoi(value);
6630 }
6632 {
6633 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6634 {
6636 }
6637 p_enc->rc.enable_mb_level_rc = atoi(value);
6638 if (QUADRA)
6639 {
6640 // mbLevelRcEnable will be deprecated and cuLevelRCEnable should be used instead. But still accept the value.
6642 }
6643 }
6645 {
6646 if ((atoi(value) > 255) || (atoi(value) < 0))
6647 {
6649 }
6651 }
6653 {
6654 if (atoi(value) != 0 && atoi(value) != 5)
6655 {
6657 }
6658 p_params->dolby_vision_profile = atoi(value);
6659 }
6661 {
6662 if ((atoi(value) > 3) || (atoi(value) < 1))
6663 {
6665 }
6666 p_enc->rdoLevel = atoi(value);
6667 }
6669 {
6670 const char delim[2] = ",";
6671 char *chunk;
6672#ifdef _MSC_VER
6673 char *v = _strdup(value);
6674#else
6675 char *v = strdup(value);
6676#endif
6677 char *saveptr = NULL;
6678 chunk = ni_strtok(v, delim, &saveptr);
6679 if (chunk != NULL)
6680 {
6681 if ((atoi(chunk) > 65535) || (atoi(chunk) < 0))
6682 {
6683 free(v);
6685 }
6686 p_enc->HDR10MaxLight = atoi(chunk);
6687 chunk = ni_strtok(NULL, delim, &saveptr);
6688 if (chunk != NULL)
6689 {
6690 if ((atoi(chunk) > 65535) || (atoi(chunk) < 0))
6691 {
6692 free(v);
6694 }
6695 p_enc->HDR10AveLight = atoi(chunk);
6696 p_enc->HDR10CLLEnable = 1; //Both param populated so enable
6697 free(v);
6698 }
6699 else
6700 {
6701 free(v);
6703 }
6704 }
6705 else
6706 {
6707 free(v);
6709 }
6710 }
6711
6713 {
6714#ifdef _MSC_VER
6715#define STRDUP(value) _strdup(value);
6716#else
6717#define STRDUP(value) strdup(value);
6718#endif
6719 const char G[2] = "G";
6720 const char B[2] = "B";
6721 const char R[2] = "R";
6722 const char W[2] = "W";
6723 const char L[2] = "L";
6724 const char P[2] = "P";
6725 const char parL[2] = "(";
6726 const char comma[2] = ",";
6727 const char parR[2] = ")";
6728 int synCheck_GBRWLPCP[8];
6729 int posCheck_GBRWL[5] = {0};
6730 char *chunk;//for parsing out more complex inputs
6731 char *subchunk;
6732 char *v = STRDUP(value);
6733 //basic check syntax correct
6734 for (i = 0; i<8; i++)
6735 {
6736 synCheck_GBRWLPCP[i] = 0;
6737 }
6738 chunk = v;
6739 i = 0; // character index
6740
6741 //count keys and punctuation, save indicies to be parsed
6742 while (*chunk) {
6743 if (*chunk == G[0])
6744 {
6745 synCheck_GBRWLPCP[0]++;
6746 posCheck_GBRWL[0] = i;
6747 }
6748 else if (*chunk == B[0])
6749 {
6750 synCheck_GBRWLPCP[1]++;
6751 posCheck_GBRWL[1] = i;
6752 }
6753 else if (*chunk == R[0])
6754 {
6755 synCheck_GBRWLPCP[2]++;
6756 posCheck_GBRWL[2] = i;
6757 }
6758 else if (*chunk == W[0])
6759 {
6760 synCheck_GBRWLPCP[3]++;
6761 posCheck_GBRWL[3] = i;
6762 }
6763 else if (*chunk == L[0])
6764 {
6765 synCheck_GBRWLPCP[4]++;
6766 posCheck_GBRWL[4] = i;
6767 }
6768 else if (*chunk == parL[0])
6769 {
6770 synCheck_GBRWLPCP[5]++;
6771 }
6772 else if (*chunk == comma[0])
6773 {
6774 synCheck_GBRWLPCP[6]++;
6775 }
6776 else if (*chunk == parR[0])
6777 {
6778 synCheck_GBRWLPCP[7]++;
6779 }
6780 chunk++;
6781 i++;
6782 }
6783 free(v);
6784 if (synCheck_GBRWLPCP[0] != 1 || synCheck_GBRWLPCP[1] != 1 || synCheck_GBRWLPCP[2] != 1 ||
6785 synCheck_GBRWLPCP[3] != 1 || synCheck_GBRWLPCP[4] != 1 || synCheck_GBRWLPCP[5] != 5 ||
6786 synCheck_GBRWLPCP[6] != 5 || synCheck_GBRWLPCP[7] != 5)
6787 {
6789 }
6790
6791 //Parse a key-value set like G(%hu, %hu)
6792#define GBRWLPARSE(OUT1,OUT2,OFF,IDX) \
6793{ \
6794 char *v = STRDUP(value); \
6795 chunk = v + posCheck_GBRWL[IDX]; \
6796 i = j = k = 0; \
6797 while (chunk != NULL) \
6798 { \
6799 if (*chunk == parL[0] && i == 1+(OFF)) \
6800 { \
6801 j = 1; \
6802 } \
6803 if((OFF) == 1 && *chunk != P[0] && i == 1) \
6804 { \
6805 break; \
6806 } \
6807 if (*chunk == parR[0]) \
6808 { \
6809 k = 1; \
6810 break; \
6811 } \
6812 i++; \
6813 chunk++; \
6814 } \
6815 if (!j || !k) \
6816 { \
6817 free(v); \
6818 return NI_RETCODE_PARAM_INVALID_VALUE; \
6819 } \
6820 subchunk = malloc(i - 1 - (OFF)); \
6821 if (subchunk == NULL) \
6822 { \
6823 free(v); \
6824 return NI_RETCODE_ERROR_MEM_ALOC; \
6825 } \
6826 memcpy(subchunk, v + posCheck_GBRWL[IDX] + 2 + (OFF), i - 2 - (OFF)); \
6827 subchunk[i - 2 - (OFF)] = '\0'; \
6828 char *saveptr = NULL; \
6829 chunk = ni_strtok(subchunk, comma, &saveptr); \
6830 if (chunk != NULL) \
6831 { \
6832 if(atoi(chunk) < 0) \
6833 { \
6834 free(v); \
6835 if(subchunk != NULL){ \
6836 free(subchunk); \
6837 } \
6838 return NI_RETCODE_PARAM_INVALID_VALUE; \
6839 } \
6840 *(OUT1) = atoi(chunk); \
6841 } \
6842 chunk = ni_strtok(NULL, comma, &saveptr); \
6843 if (chunk != NULL) \
6844 { \
6845 if(atoi(chunk) < 0) \
6846 { \
6847 free(v); \
6848 if(subchunk != NULL){ \
6849 free(subchunk); \
6850 } \
6851 return NI_RETCODE_PARAM_INVALID_VALUE; \
6852 } \
6853 *(OUT2) = atoi(chunk); \
6854 } \
6855 free(subchunk); \
6856 free(v); \
6857}
6858 GBRWLPARSE(&p_enc->HDR10dx0, &p_enc->HDR10dy0, 0, 0);
6859 GBRWLPARSE(&p_enc->HDR10dx1, &p_enc->HDR10dy1, 0, 1);
6860 GBRWLPARSE(&p_enc->HDR10dx2, &p_enc->HDR10dy2, 0, 2);
6861 GBRWLPARSE(&p_enc->HDR10wx, &p_enc->HDR10wy, 1, 3);
6862 GBRWLPARSE(&p_enc->HDR10maxluma, &p_enc->HDR10minluma, 0, 4);
6863 p_enc->HDR10Enable = 1;
6864 }
6866 {
6867 if (atoi(value)!= 0 && ((atoi(value) > 40 ) || (atoi(value) < 4)))
6868 {
6870 }
6871 p_enc->lookAheadDepth = atoi(value);
6872 }
6874 {
6875 if (atoi(value) != 0 && atoi(value) != 1)
6876 {
6878 }
6879 p_enc->hrdEnable = atoi(value);
6880 }
6882 {
6883 if ((atoi(value) != 0) && (atoi(value) != 1))
6884 {
6886 }
6887 p_enc->EnableAUD = atoi(value);
6888 }
6890 {
6891 if (atoi(value) != 0 && atoi(value) != 1)
6892 {
6894 }
6895 p_params->cacheRoi = atoi(value);
6896 }
6898 {
6899 if (atoi(value) != 0 && atoi(value) != 1)
6900 {
6902 }
6903 p_enc->long_term_ref_enable = atoi(value);
6904 }
6906 {
6907 p_enc->long_term_ref_interval = atoi(value);
6908 }
6910 {
6911 if (atoi(value) < 1 || atoi(value) > 2)
6912 {
6914 }
6915 p_enc->long_term_ref_count = atoi(value);
6916 }
6918 {
6919 if ((atoi(value) != 0) && (atoi(value) != 1))
6920 {
6922 }
6923 p_enc->EnableRdoQuant = atoi(value);
6924 }
6926 {
6927 if (QUADRA)
6928 {
6930 }
6931
6932 if ((atoi(value) < 0) || (atoi(value) > 3))
6933 {
6935 }
6936 p_enc->ctbRcMode = atoi(value);
6937 }
6939 {
6940 if (QUADRA)
6941 {
6943 }
6944
6945 p_enc->gopSize = atoi(value);
6946 }
6948 {
6949 if (QUADRA)
6950 {
6952 }
6953
6954 if ((atoi(value) != 0) && (atoi(value) != 1))
6955 {
6957 }
6958 p_enc->gopLowdelay = atoi(value);
6959 }
6961 {
6962 if (QUADRA)
6963 {
6965 }
6966 p_enc->gdrDuration = atoi(value);
6967 }
6969 {
6970 p_enc->ltrRefInterval = atoi(value);
6971 }
6973 {
6974 p_enc->ltrRefQpOffset = atoi(value);
6975 }
6977 {
6978 p_enc->ltrFirstGap = atoi(value);
6979 }
6982 {
6983 if ((atoi(value) != 0) && (atoi(value) != 1))
6984 {
6986 }
6987 p_enc->multicoreJointMode = atoi(value);
6988 }
6990 {
6991 if ((atoi(value) < 0) || (atoi(value) > 9))
6992 {
6994 }
6995 p_enc->qlevel = atoi(value);
6996 }
6998 {
6999 if ((atoi(value) > 12) || (atoi(value) < -12))
7000 {
7002 }
7003 p_enc->chromaQpOffset = atoi(value);
7004 }
7005 OPT(NI_ENC_PARAM_TOL_RC_INTER) { p_enc->tolCtbRcInter = (float)atof(value); }
7006 OPT(NI_ENC_PARAM_TOL_RC_INTRA) { p_enc->tolCtbRcIntra = (float)atof(value); }
7008 {
7009 if ((atoi(value) > 300) || (atoi(value) < 1))
7010 {
7012 }
7013 p_enc->bitrateWindow = atoi(value);
7014 }
7016 {
7017 if ((atoi(value) > 2) || (atoi(value) < 0))
7018 {
7020 }
7021 p_enc->blockRCSize = atoi(value);
7022 }
7024 {
7025 if ((atoi(value) > 15) || (atoi(value) < 0))
7026 {
7028 }
7029 p_enc->rcQpDeltaRange = atoi(value);
7030 }
7032 {
7033 if ((atoi(value) > 500) || (atoi(value) < 0))
7034 {
7036 }
7037 p_enc->ctbRowQpStep = atoi(value);
7038 }
7040 {
7041 if ((atoi(value) > 1) || (atoi(value) < 0))
7042 {
7044 }
7045 p_enc->newRcEnable = atoi(value);
7046 }
7048 {
7049 if ((atoi(value) > 1) || (atoi(value) < 0))
7050 {
7052 }
7053 p_enc->inLoopDSRatio = atoi(value);
7054 }
7056 {
7057 COMPARE(value, 22, 0)
7058 p_params->color_primaries = p_enc->colorPrimaries = atoi(value);
7059 p_enc->colorDescPresent = 1;
7060 }
7062 {
7063 COMPARE(value, 18, 0)
7064 p_params->color_transfer_characteristic = p_enc->colorTrc = atoi(value);
7065 p_enc->colorDescPresent = 1;
7066 }
7068 {
7069 COMPARE(value, 14, 0)
7070 p_params->color_space = p_enc->colorSpace = atoi(value);
7071 p_enc->colorDescPresent = 1;
7072 }
7074 {
7075 p_params->sar_num = p_enc->aspectRatioWidth = atoi(value);
7076 }
7078 {
7079 p_params->sar_denom = p_enc->aspectRatioHeight = atoi(value);
7080 }
7082 {
7083 p_params->video_full_range_flag = p_enc->videoFullRange = atoi(value);
7084 }
7086 {
7087 if ((atoi(value) < NI_MIN_KEEP_ALIVE_TIMEOUT) ||
7089 {
7091 }
7092 p_enc->keep_alive_timeout = atoi(value);
7093 }
7095 {
7096 if (atoi(value) != 0 && atoi(value) != 1)
7097 {
7099 }
7100 p_params->enable_vfr = atoi(value);
7101 }
7103 {
7104 if (atoi(value) < 0 || atoi(value) > 3)
7105 {
7107 }
7108 p_enc->get_psnr_mode = atoi(value);
7109 }
7111 {
7112 if (atoi(value) < 1)
7113 {
7115 }
7116 p_params->interval_of_psnr = atoi(value);
7117 }
7119 {
7120 if (atoi(value) < 0 || atoi(value) > 1)
7121 {
7123 }
7124 p_enc->get_psnr_mode = atoi(value) + 3;
7125 }
7127 {
7128 if ((atoi(value) != 0) && (atoi(value) != 1))
7129 {
7131 }
7132 p_enc->enable_ssim = atoi(value);
7133 }
7135 {
7136 if ((atoi(value) != 0) && (atoi(value) != 1))
7137 {
7139 }
7140 p_enc->av1_error_resilient_mode = atoi(value);
7141 }
7143 {
7144 if ((atoi(value) != 0) && (atoi(value) != 1))
7145 {
7147 }
7148 p_params->staticMmapThreshold = atoi(value);
7149 }
7151 {
7152 p_enc->temporal_layers_enable = atoi(value);
7153 }
7155 {
7156 if ((atoi(value) != 0) && (atoi(value) != 1))
7157 {
7159 }
7160 p_params->enable_ai_enhance = atoi(value);
7161 }
7163 {
7164 if ((atoi(value) != 0) && (atoi(value) != 1))
7165 {
7167 }
7168 if(p_params->enable_ai_enhance)
7169 {
7170 ni_log(NI_LOG_ERROR, "Cannot set enableAIEnhance and enableHVSPlus at same time, just enableHVSPlus\n");
7171 }
7172 p_params->enable_ai_enhance = (atoi(value) == 1) ? 2 : 0;
7173 }
7175 {
7176 if ((atoi(value) != 0) && (atoi(value) != 1))
7177 {
7179 }
7180 p_params->enable2PassGop = atoi(value);
7181 }
7183 {
7184 if ((atoi(value) != 0) && (atoi(value) != 1) && (atoi(value) != -1))
7185 {
7187 }
7188 p_params->zerocopy_mode = atoi(value);
7189 }
7191 {
7192 if ((atoi(value) == 0) || (atoi(value) > 3))
7193 {
7195 }
7196 p_params->ai_enhance_level = atoi(value);
7197 }
7199 {
7200 if ((atoi(value) == 0) || (atoi(value) > 2))
7201 {
7203 }
7204 p_params->ai_enhance_level = atoi(value);
7205 }
7207 {
7208 if ((atoi(value) < NI_MIN_WIDTH) ||
7209 (atoi(value) > NI_PARAM_MAX_WIDTH))
7210 {
7212 }
7213 p_enc->crop_width = atoi(value);
7214 }
7216 {
7217 if ((atoi(value) < NI_MIN_HEIGHT) ||
7218 (atoi(value) > NI_PARAM_MAX_HEIGHT))
7219 {
7221 }
7222 p_enc->crop_height = atoi(value);
7223 }
7225 {
7226 if ((atoi(value) < 0) ||
7227 (atoi(value) > NI_PARAM_MAX_WIDTH))
7228 {
7230 }
7231 p_enc->hor_offset = atoi(value);
7232 }
7234 {
7235 if ((atoi(value) < 0) ||
7236 (atoi(value) > NI_PARAM_MAX_HEIGHT))
7237 {
7239 }
7240 p_enc->ver_offset = atoi(value);
7241 }
7243 {
7244 if ((atoi(value) > 51) || (atoi(value) < -1))
7245 {
7247 }
7248 p_enc->crfMax = atoi(value);
7249 }
7251 {
7252 if ((atof(value) > 1.0) || (atof(value) < 0.0))
7253 {
7255 }
7256 p_enc->qcomp = (float)atof(value);
7257 }
7259 {
7260 if ((atoi(value) != 0) && (atoi(value) != 1))
7261 {
7263 }
7264 p_enc->noMbtree = atoi(value);
7265 }
7267 {
7268 if ((atoi(value) != 0) && (atoi(value) != 1))
7269 {
7271 }
7272 p_enc->avcc_hvcc = atoi(value);
7273 }
7275 {
7276 if ((atoi(value) != 0) && (atoi(value) != 1))
7277 {
7279 }
7280 p_enc->noHWMultiPassSupport = atoi(value);
7281 }
7283 {
7284 if ((atoi(value) > 10) || (atoi(value) < 1))
7285 {
7287 }
7288 p_enc->cuTreeFactor = atoi(value);
7289 }
7291 {
7292 if ((atof(value) > 10.0) || (atof(value) < 0.01))
7293 {
7295 }
7296 p_enc->ipRatio = (float)atof(value);
7297 }
7299 {
7300 if ((atoi(value) != 0) && (atoi(value) != 1))
7301 {
7303 }
7304 p_enc->enableipRatio = atoi(value);
7305 }
7307 {
7308 if ((atof(value) > 10.0) || (atof(value) < 0.01))
7309 {
7311 }
7312 p_enc->pbRatio = (float)atof(value);
7313 }
7315 {
7316 if ((atof(value) > 1.0) || (atof(value) < 0.1))
7317 {
7319 }
7320 p_enc->cplxDecay = (float)atof(value);
7321 }
7323 {
7324 if ((atoi(value) > 51) || (atoi(value) < -1))
7325 {
7327 }
7328 p_enc->pps_init_qp = atoi(value);
7329 }
7331 {
7332 if (atoi(value) >= NI_DDR_PRIORITY_MAX ||
7333 atoi(value) <= NI_DDR_PRIORITY_NONE)
7334 {
7336 }
7337 p_params->ddr_priority_mode = atoi(value);
7338 }
7340 {
7341 if ((atoi(value) != 0) && (atoi(value) != 1))
7342 {
7344 }
7345 p_enc->bitrateMode = atoi(value);
7346 }
7348 {
7349 if ((atoi(value) > 51) || (atoi(value) < -1))
7350 {
7352 }
7353 p_enc->pass1_qp = atoi(value);
7354 }
7356 {
7357 if (((atof(value) < 0.0) && (atof(value) != -1.0)) ||
7358 (atof(value) > 51.00))
7359 {
7361 }
7362 p_enc->crfFloat = (float)atof(value);
7363 }
7365 {
7366 if ((atoi(value) < 0) || (atoi(value) > 31))
7367 {
7369 }
7370 p_enc->hvsBaseMbComplexity = atoi(value);
7371 }
7373 {
7374 if (atoi(value) != 0 && atoi(value) != 1 && atoi(value) != 6)
7375 {
7377 }
7378 p_enc->statistic_output_level = atoi(value);
7379 }
7381 {
7382 //Currently only support 6 stillImage detect level
7383 //0-3: no performance drop
7384 //4-6: performance drop
7385 if ((atoi(value) < 0 || atoi(value) > 6))
7386 {
7388 }
7389 p_enc->still_image_detect_level = atoi(value);
7390 }
7392 {
7393 //Currently only support 10 sceneChange detect level
7394 //1-5 : no performance drop
7395 //6-10: performance drop
7396 if ((atoi(value) < 0 || atoi(value) > 10))
7397 {
7399 }
7400 p_enc->scene_change_detect_level = atoi(value);
7401 }
7403 {
7404 if ((atoi(value) != 0) && (atoi(value) != 1))
7405 {
7407 }
7408 p_enc->enable_smooth_crf = atoi(value);
7409 }
7411 {
7412 if ((atoi(value) != 0) && (atoi(value) != 1))
7413 {
7415 }
7416 p_enc->enable_compensate_qp = atoi(value);
7417 }
7419 {
7420 if (atoi(value) < 0 || atoi(value) > 1)
7421 {
7423 }
7424 p_enc->skip_frame_enable = atoi(value);
7425 }
7427 {
7428 if (atoi(value) < 0)
7429 {
7431 }
7432 p_enc->max_consecutive_skip_num = atoi(value);
7433 }
7435 {
7436 if (atoi(value) < 0 || atoi(value) > 255)
7437 {
7439 }
7440 p_enc->skip_frame_interval = atoi(value);
7441 }
7443 {
7444 if (atoi(value) != 0 && atoi(value) != 1)
7445 {
7447 }
7448 p_enc->enable_all_sei_passthru = atoi(value);
7449 }
7451 {
7452 if (atoi(value) <= 0)
7453 {
7455 }
7456 p_enc->iframe_size_ratio = atoi(value);
7457 }
7459 {
7460 if ((atoi(value) < 0 || atoi(value) > 2) &&
7461 atoi(value) != 5 && atoi(value) != 6 && atoi(value) != 7) // 1 & 5=MEDIUM, 2 & 6=HIGH, 7=OPTIMAL
7462 {
7464 }
7465 p_enc->crf_max_iframe_enable = atoi(value);
7466 }
7468 {
7469 p_enc->vbv_min_rate = atoi(value);
7470 }
7472 {
7473 if (atoi(value) != 0 && atoi(value) != 1)
7474 {
7476 }
7477 p_enc->disable_adaptive_buffers = atoi(value);
7478 }
7480 {
7481 if ((atoi(value) != 0) && (atoi(value) != 1))
7482 {
7484 }
7485 p_enc->disableBframeRdoq = atoi(value);
7486 }
7488 {
7489 if ((atof(value) > 1.0) || (atof(value) < 0.0))
7490 {
7492 }
7493 p_enc->forceBframeQpfactor = (float)atof(value);
7494 }
7496 {
7497 if (atoi(value) < 0 || atoi(value) > 2)
7498 {
7500 }
7501 p_enc->tune_bframe_visual = atoi(value);
7502 }
7504 {
7505 if ((atoi(value) != 0) && (atoi(value) != 1))
7506 {
7508 }
7509 p_enc->enable_acq_limit = atoi(value);
7510 }
7512 {
7513 if (atoi(value) < NI_CUS_ROI_DISABLE || atoi(value) > NI_CUS_ROI_MERGE)
7514 {
7516 }
7517 p_enc->customize_roi_qp_level += atoi(value);
7518 }
7520 {
7522 if (retval != NI_RETCODE_SUCCESS)
7523 {
7524 return retval;
7525 }
7526 // indicate it need to upload roi qp map
7527 p_enc->customize_roi_qp_level += 64;
7528 }
7530 {
7531 if (atoi(value) < 0 || atoi(value) > 2)
7532 {
7534 }
7535 p_enc->motionConstrainedMode = atoi(value);
7536 }
7538 {
7541 {
7543 }
7544 p_enc->encMallocStrategy = atoi(value);
7545 }
7547 {
7548 if (atoi(value) < 1 || atoi(value) > 4)
7549 {
7551 }
7552 p_enc->spatial_layers = atoi(value);
7553 }
7555 {
7556 if (atoi(value) < 0 || atoi(value) > 1)
7557 {
7559 }
7560 p_enc->enable_timecode = atoi(value);
7561 }
7563 {
7564 if ((atoi(value) != 0) && (atoi(value) != 1))
7565 {
7567 }
7568 p_enc->spatial_layers_ref_base_layer = atoi(value);
7569 }
7571 {
7572 if ((atoi(value) != 0) && (atoi(value) != 1))
7573 {
7575 }
7576 p_enc->vbvBufferReencode = atoi(value);
7577 }
7579 {
7580 if (atoi(value)!= 0 && ((atoi(value) > 40 ) || (atoi(value) < 4)))
7581 {
7583 }
7584 p_enc->totalCuTreeDepth = atoi(value);
7585 }
7587 {
7588 if (atoi(value) != 0 && atoi(value) != 1)
7589 {
7591 }
7592 p_enc->adaptiveCuTree = atoi(value);
7593 }
7595 {
7596 if (atoi(value) != 0 && atoi(value) != 1)
7597 {
7599 }
7600 p_enc->preIntraHandling = atoi(value);
7601 }
7603 {
7604 if (atoi(value) != 0 && atoi(value) != 1)
7605 {
7607 }
7608 p_enc->baseLayerOnly = atoi(value);
7609 }
7611 {
7612 if (atoi(value) < 0 || atoi(value) > 100)
7613 {
7615 }
7616 p_enc->pastFrameMaxIntraRatio = atoi(value);
7617 }
7619 {
7620 if (atoi(value) < 0 || atoi(value) > 100)
7621 {
7623 }
7624 p_enc->linkFrameMaxIntraRatio = atoi(value);
7625 }
7627 {
7628 const char delim[2] = ",";
7629 char *chunk;
7630#ifdef _MSC_VER
7631 char *v = _strdup(value);
7632#else
7633 char *v = strdup(value);
7634#endif
7635 char *saveptr = NULL;
7636 i = 0;
7637 chunk = ni_strtok(v, delim, &saveptr);
7638 while (chunk != NULL && i < NI_MAX_SPATIAL_LAYERS)
7639 {
7640 if ((atoi(chunk) > NI_MAX_BITRATE) || (atoi(chunk) < NI_MIN_BITRATE))
7641 {
7642 free(v);
7644 }
7645 p_enc->spatialLayerBitrate[i] = atoi(chunk);
7646 chunk = ni_strtok(NULL, delim, &saveptr);
7647 i++;
7648 }
7649 free(v);
7650 }
7652 {
7653 const char delim[2] = ",";
7654 char *chunk;
7655#ifdef _MSC_VER
7656 char *v = _strdup(value);
7657#else
7658 char *v = strdup(value);
7659#endif
7660 char *saveptr = NULL;
7661 i = 0;
7662 chunk = ni_strtok(v, delim, &saveptr);
7663 while (chunk != NULL && i < NI_MAX_SPATIAL_LAYERS)
7664 {
7668 if (atof(chunk) <= 10)
7669 {
7670 p_enc->av1OpLevel[i] = (int)(10 * atof(chunk) + .5);
7671 }
7672 else
7673 {
7674 p_enc->av1OpLevel[i] = atoi(chunk);
7675 }
7676 chunk = ni_strtok(NULL, delim, &saveptr);
7677 i++;
7678 }
7679 free(v);
7680 }
7682 {
7683 if ((atoi(value) != 0) && (atoi(value) != 1))
7684 {
7686 }
7687 p_enc->disableAv1TimingInfo = atoi(value);
7688 }
7690 {
7691 if ((atoi(value) != 0) && (atoi(value) != 1))
7692 {
7694 }
7695 p_params->enableCpuAffinity = atoi(value);
7696 }
7698 {
7699 for (i = 0; i < NI_NUM_PRESETS_MAX; i++) {
7700 if (0 == strcmp(value, g_xcoder_preset_names[i])) {
7701 p_enc->preset_index = i;
7702 break;
7703 }
7704 else if(i == NI_NUM_PRESETS_MAX - 1) {
7706 }
7707 }
7708 }
7710 {
7711 if (atoi(value) < 0 || atoi(value) > 3)
7712 {
7714 }
7715 p_enc->adaptiveLamdaMode = atoi(value);
7716 }
7718 {
7719 if (atoi(value) < 0 || atoi(value) > 1)
7720 {
7722 }
7723 p_enc->qpScaleEnable = atoi(value);
7724 }
7726 {
7727 if (atoi(value) < 0 || atoi(value) > 2)
7728 {
7730 }
7731 p_enc->adaptiveCrfMode = atoi(value);
7732 }
7734 {
7735 if (atoi(value) < 0 || atoi(value) > 3)
7736 {
7738 }
7739 p_enc->intraCompensateMode = atoi(value);
7740 }
7742 {
7743 if (atoi(value) < 0 || atoi(value) > 255)
7744 {
7746 }
7747 p_enc->customMinCoeffDiv = atoi(value);
7748 }
7750 {
7751 if ((atoi(value) != 0) && (atoi(value) != 1))
7752 {
7754 }
7755 p_enc->getBitstreamFeatures = atoi(value);
7756 }
7757 else { return NI_RETCODE_PARAM_INVALID_NAME; }
7758
7759#undef OPT
7760#undef OPT2
7761#undef atobool
7762#undef atoi
7763#undef atof
7764
7765 b_error |= bValueWasNull && !bNameWasBool;
7766
7767 ni_log(NI_LOG_TRACE, "%s: exit, b_error=%d\n", __func__, b_error);
7768
7770}
7771
7772#undef atoi
7773#undef atof
7774#define atoi(p_str) ni_atoi(p_str, &b_error)
7775#define atof(p_str) ni_atof(p_str, &b_error)
7776#define atobool(p_str) (ni_atobool(p_str, &b_error))
7777
7778/*!*****************************************************************************
7779 * \brief Set GOP parameter value referenced by name in encoder parameters
7780 * structure
7781 *
7782 * \param[in] p_params Pointer to a user allocated ni_xcoder_params_t
7783 * to find and set a particular parameter
7784 * \param[in] name String represented parameter name to search
7785 * \param[in] value Parameter value to set
7786*
7787 * \return On success
7788 * NI_RETCODE_SUCCESS
7789 * On failure
7790 * NI_RETCODE_FAILURE
7791 * NI_RETCODE_INVALID_PARAM
7792 ******************************************************************************/
7794 const char *name,
7795 const char *value)
7796{
7797 bool b_error = false;
7798 bool bNameWasBool = false;
7799 bool bValueWasNull = !value;
7800 ni_encoder_cfg_params_t *p_enc = NULL;
7801 ni_custom_gop_params_t* p_gop = NULL;
7802 char nameBuf[64] = { 0 };
7803
7804 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
7805
7806 if (!p_params)
7807 {
7808 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
7809 __func__);
7811 }
7812
7813 if ( !name )
7814 {
7815 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
7816 __func__);
7818 }
7819 p_enc = &p_params->cfg_enc_params;
7820 p_gop = &p_enc->custom_gop_params;
7821
7822 // skip -- prefix if provided
7823 if (name[0] == '-' && name[1] == '-')
7824 {
7825 name += 2;
7826 }
7827
7828 // s/_/-/g
7829 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
7830 {
7831 char* c;
7832 ni_strcpy(nameBuf, sizeof(nameBuf), name);
7833 while ((c = strchr(nameBuf, '_')) != 0)
7834 {
7835 *c = '-';
7836 }
7837 name = nameBuf;
7838 }
7839
7840 if (!value)
7841 {
7842 value = "true";
7843 }
7844 else if (value[0] == '=')
7845 {
7846 value++;
7847 }
7848
7849#if defined(_MSC_VER)
7850#define OPT(STR) else if (!_stricmp(name, STR))
7851#else
7852#define OPT(STR) else if (!strcasecmp(name, STR))
7853#endif
7854 if (0); // suppress cppcheck
7856 {
7857 if (atoi(value) > NI_MAX_GOP_SIZE)
7858 {
7860 }
7861 if (atoi(value) < NI_MIN_GOP_SIZE)
7862 {
7864 }
7865 p_gop->custom_gop_size = atoi(value);
7866 }
7867
7868#ifndef QUADRA
7870 {
7871 p_gop->pic_param[0].pic_type = atoi(value);
7872 }
7874 {
7875 p_gop->pic_param[0].poc_offset = atoi(value);
7876 }
7877 OPT(NI_ENC_GOP_PARAMS_G0_PIC_QP)
7878 {
7879 p_gop->pic_param[0].pic_qp = atoi(value);
7880 }
7881 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC_L0)
7882 {
7883 p_gop->pic_param[0].num_ref_pic_L0 = atoi(value);
7884 }
7885 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_POC_L0)
7886 {
7887 p_gop->pic_param[0].ref_poc_L0 = atoi(value);
7888 }
7889 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_POC_L1)
7890 {
7891 p_gop->pic_param[0].ref_poc_L1 = atoi(value);
7892 }
7894 {
7895 p_gop->pic_param[0].temporal_id = atoi(value);
7896 }
7897
7899 {
7900 p_gop->pic_param[1].pic_type = atoi(value);
7901 }
7903 {
7904 p_gop->pic_param[1].poc_offset = atoi(value);
7905 }
7906 OPT(NI_ENC_GOP_PARAMS_G1_PIC_QP)
7907 {
7908 p_gop->pic_param[1].pic_qp = atoi(value);
7909 }
7910 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC_L0)
7911 {
7912 p_gop->pic_param[1].num_ref_pic_L0 = atoi(value);
7913 }
7914 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_POC_L0)
7915 {
7916 p_gop->pic_param[1].ref_poc_L0 = atoi(value);
7917 }
7918 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_POC_L1)
7919 {
7920 p_gop->pic_param[1].ref_poc_L1 = atoi(value);
7921 }
7923 {
7924 p_gop->pic_param[1].temporal_id = atoi(value);
7925 }
7926
7928 {
7929 p_gop->pic_param[2].pic_type = atoi(value);
7930 }
7932 {
7933 p_gop->pic_param[2].poc_offset = atoi(value);
7934 }
7935 OPT(NI_ENC_GOP_PARAMS_G2_PIC_QP)
7936 {
7937 p_gop->pic_param[2].pic_qp = atoi(value);
7938 }
7939 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC_L0)
7940 {
7941 p_gop->pic_param[2].num_ref_pic_L0 = atoi(value);
7942 }
7943 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_POC_L0)
7944 {
7945 p_gop->pic_param[2].ref_poc_L0 = atoi(value);
7946 }
7947 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_POC_L1)
7948 {
7949 p_gop->pic_param[2].ref_poc_L1 = atoi(value);
7950 }
7952 {
7953 p_gop->pic_param[2].temporal_id = atoi(value);
7954 }
7955
7957 {
7958 p_gop->pic_param[3].pic_type = atoi(value);
7959 }
7961 {
7962 p_gop->pic_param[3].poc_offset = atoi(value);
7963 }
7964 OPT(NI_ENC_GOP_PARAMS_G3_PIC_QP)
7965 {
7966 p_gop->pic_param[3].pic_qp = atoi(value);
7967 }
7968 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC_L0)
7969 {
7970 p_gop->pic_param[3].num_ref_pic_L0 = atoi(value);
7971 }
7972 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_POC_L0)
7973 {
7974 p_gop->pic_param[3].ref_poc_L0 = atoi(value);
7975 }
7976 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_POC_L1)
7977 {
7978 p_gop->pic_param[3].ref_poc_L1 = atoi(value);
7979 }
7981 {
7982 p_gop->pic_param[3].temporal_id = atoi(value);
7983 }
7984
7986 {
7987 p_gop->pic_param[4].pic_type = atoi(value);
7988 }
7990 {
7991 p_gop->pic_param[4].poc_offset = atoi(value);
7992 }
7993 OPT(NI_ENC_GOP_PARAMS_G4_PIC_QP)
7994 {
7995 p_gop->pic_param[4].pic_qp = atoi(value);
7996 }
7997 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC_L0)
7998 {
7999 p_gop->pic_param[4].num_ref_pic_L0 = atoi(value);
8000 }
8001 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_POC_L0)
8002 {
8003 p_gop->pic_param[4].ref_poc_L0 = atoi(value);
8004 }
8005 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_POC_L1)
8006 {
8007 p_gop->pic_param[4].ref_poc_L1 = atoi(value);
8008 }
8010 {
8011 p_gop->pic_param[4].temporal_id = atoi(value);
8012 }
8013
8015 {
8016 p_gop->pic_param[5].pic_type = atoi(value);
8017 }
8019 {
8020 p_gop->pic_param[5].poc_offset = atoi(value);
8021 }
8022 OPT(NI_ENC_GOP_PARAMS_G5_PIC_QP)
8023 {
8024 p_gop->pic_param[5].pic_qp = atoi(value);
8025 }
8026 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC_L0)
8027 {
8028 p_gop->pic_param[5].num_ref_pic_L0 = atoi(value);
8029 }
8030 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_POC_L0)
8031 {
8032 p_gop->pic_param[5].ref_poc_L0 = atoi(value);
8033 }
8034 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_POC_L1)
8035 {
8036 p_gop->pic_param[5].ref_poc_L1 = atoi(value);
8037 }
8039 {
8040 p_gop->pic_param[5].temporal_id = atoi(value);
8041 }
8042
8044 {
8045 p_gop->pic_param[6].pic_type = atoi(value);
8046 }
8048 {
8049 p_gop->pic_param[6].poc_offset = atoi(value);
8050 }
8051 OPT(NI_ENC_GOP_PARAMS_G6_PIC_QP)
8052 {
8053 p_gop->pic_param[6].pic_qp = atoi(value);
8054 }
8055 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC_L0)
8056 {
8057 p_gop->pic_param[6].num_ref_pic_L0 = atoi(value);
8058 }
8059 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_POC_L0)
8060 {
8061 p_gop->pic_param[6].ref_poc_L0 = atoi(value);
8062 }
8063 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_POC_L1)
8064 {
8065 p_gop->pic_param[6].ref_poc_L1 = atoi(value);
8066 }
8068 {
8069 p_gop->pic_param[6].temporal_id = atoi(value);
8070 }
8071
8073 {
8074 p_gop->pic_param[7].pic_type = atoi(value);
8075 }
8077 {
8078 p_gop->pic_param[7].poc_offset = atoi(value);
8079 }
8080 OPT(NI_ENC_GOP_PARAMS_G7_PIC_QP)
8081 {
8082 p_gop->pic_param[7].pic_qp = atoi(value);
8083 }
8084 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC_L0)
8085 {
8086 p_gop->pic_param[7].num_ref_pic_L0 = atoi(value);
8087 }
8088 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_POC_L0)
8089 {
8090 p_gop->pic_param[7].ref_poc_L0 = atoi(value);
8091 }
8092 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_POC_L1)
8093 {
8094 p_gop->pic_param[7].ref_poc_L1 = atoi(value);
8095 }
8097 {
8098 p_gop->pic_param[7].temporal_id = atoi(value);
8099 }
8100 else
8101 {
8102 ni_log(NI_LOG_ERROR, "%s(): Invalid parameter name passed\n", __func__);
8104 }
8105#else
8107 {
8108 p_gop->pic_param[0].poc_offset = atoi(value);
8109 }
8111 {
8112 p_gop->pic_param[0].qp_offset = atoi(value);
8113 }
8114 /*
8115 OPT(NI_ENC_GOP_PARAMS_G0_QP_FACTOR)
8116 {
8117 p_gop->pic_param[0].qp_factor = atof(value);
8118 }
8119 */
8121 {
8122 p_gop->pic_param[0].temporal_id = atoi(value);
8123 }
8125 {
8126 p_gop->pic_param[0].pic_type = atoi(value);
8127 }
8129 {
8130 p_gop->pic_param[0].num_ref_pics = atoi(value);
8131 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 num_ref_pics %d\n", __func__, p_gop->pic_param[0].num_ref_pics);
8132 }
8134 {
8135 p_gop->pic_param[0].rps[0].ref_pic = atoi(value);
8136 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 %d rps[0].ref_pic %d\n", __func__, p_gop->pic_param[0].rps[0].ref_pic);
8137 }
8139 {
8140 p_gop->pic_param[0].rps[0].ref_pic_used = atoi(value);
8141 //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);
8142 }
8144 {
8145 p_gop->pic_param[0].rps[1].ref_pic = atoi(value);
8146 }
8148 {
8149 p_gop->pic_param[0].rps[1].ref_pic_used = atoi(value);
8150 }
8152 {
8153 p_gop->pic_param[0].rps[2].ref_pic = atoi(value);
8154 }
8156 {
8157 p_gop->pic_param[0].rps[2].ref_pic_used = atoi(value);
8158 }
8160 {
8161 p_gop->pic_param[0].rps[3].ref_pic = atoi(value);
8162 }
8164 {
8165 p_gop->pic_param[0].rps[3].ref_pic_used = atoi(value);
8166 }
8167
8169 {
8170 p_gop->pic_param[1].poc_offset = atoi(value);
8171 }
8173 {
8174 p_gop->pic_param[1].qp_offset = atoi(value);
8175 }
8176 /*
8177 OPT(NI_ENC_GOP_PARAMS_G1_QP_FACTOR)
8178 {
8179 p_gop->pic_param[1].qp_factor = atof(value);
8180 }
8181 */
8183 {
8184 p_gop->pic_param[1].temporal_id = atoi(value);
8185 }
8187 {
8188 p_gop->pic_param[1].pic_type = atoi(value);
8189 }
8191 {
8192 p_gop->pic_param[1].num_ref_pics = atoi(value);
8193 }
8195 {
8196 p_gop->pic_param[1].rps[0].ref_pic = atoi(value);
8197 }
8199 {
8200 p_gop->pic_param[1].rps[0].ref_pic_used = atoi(value);
8201 }
8203 {
8204 p_gop->pic_param[1].rps[1].ref_pic = atoi(value);
8205 }
8207 {
8208 p_gop->pic_param[1].rps[1].ref_pic_used = atoi(value);
8209 }
8211 {
8212 p_gop->pic_param[1].rps[2].ref_pic = atoi(value);
8213 }
8215 {
8216 p_gop->pic_param[1].rps[2].ref_pic_used = atoi(value);
8217 }
8219 {
8220 p_gop->pic_param[1].rps[3].ref_pic = atoi(value);
8221 }
8223 {
8224 p_gop->pic_param[1].rps[3].ref_pic_used = atoi(value);
8225 }
8226
8228 {
8229 p_gop->pic_param[2].poc_offset = atoi(value);
8230 }
8232 {
8233 p_gop->pic_param[2].qp_offset = atoi(value);
8234 }
8235 /*
8236 OPT(NI_ENC_GOP_PARAMS_G2_QP_FACTOR)
8237 {
8238 p_gop->pic_param[2].qp_factor = atof(value);
8239 }
8240 */
8242 {
8243 p_gop->pic_param[2].temporal_id = atoi(value);
8244 }
8246 {
8247 p_gop->pic_param[2].pic_type = atoi(value);
8248 }
8250 {
8251 p_gop->pic_param[2].num_ref_pics = atoi(value);
8252 }
8254 {
8255 p_gop->pic_param[2].rps[0].ref_pic = atoi(value);
8256 }
8258 {
8259 p_gop->pic_param[2].rps[0].ref_pic_used = atoi(value);
8260 }
8262 {
8263 p_gop->pic_param[2].rps[1].ref_pic = atoi(value);
8264 }
8266 {
8267 p_gop->pic_param[2].rps[1].ref_pic_used = atoi(value);
8268 }
8270 {
8271 p_gop->pic_param[2].rps[2].ref_pic = atoi(value);
8272 }
8274 {
8275 p_gop->pic_param[2].rps[2].ref_pic_used = atoi(value);
8276 }
8278 {
8279 p_gop->pic_param[2].rps[3].ref_pic = atoi(value);
8280 }
8282 {
8283 p_gop->pic_param[2].rps[3].ref_pic_used = atoi(value);
8284 }
8285
8287 {
8288 p_gop->pic_param[3].poc_offset = atoi(value);
8289 }
8291 {
8292 p_gop->pic_param[3].qp_offset = atoi(value);
8293 }
8294 /*
8295 OPT(NI_ENC_GOP_PARAMS_G3_QP_FACTOR)
8296 {
8297 p_gop->pic_param[3].qp_factor = atof(value);
8298 }
8299 */
8301 {
8302 p_gop->pic_param[3].temporal_id = atoi(value);
8303 }
8305 {
8306 p_gop->pic_param[3].pic_type = atoi(value);
8307 }
8309 {
8310 p_gop->pic_param[3].num_ref_pics = atoi(value);
8311 }
8313 {
8314 p_gop->pic_param[3].rps[0].ref_pic = atoi(value);
8315 }
8317 {
8318 p_gop->pic_param[3].rps[0].ref_pic_used = atoi(value);
8319 }
8321 {
8322 p_gop->pic_param[3].rps[1].ref_pic = atoi(value);
8323 }
8325 {
8326 p_gop->pic_param[3].rps[1].ref_pic_used = atoi(value);
8327 }
8329 {
8330 p_gop->pic_param[3].rps[2].ref_pic = atoi(value);
8331 }
8333 {
8334 p_gop->pic_param[3].rps[2].ref_pic_used = atoi(value);
8335 }
8337 {
8338 p_gop->pic_param[3].rps[3].ref_pic = atoi(value);
8339 }
8341 {
8342 p_gop->pic_param[3].rps[3].ref_pic_used = atoi(value);
8343 }
8344
8346 {
8347 p_gop->pic_param[4].poc_offset = atoi(value);
8348 }
8350 {
8351 p_gop->pic_param[4].qp_offset = atoi(value);
8352 }
8353 /*
8354 OPT(NI_ENC_GOP_PARAMS_G4_QP_FACTOR)
8355 {
8356 p_gop->pic_param[4].qp_factor = atof(value);
8357 }
8358 */
8360 {
8361 p_gop->pic_param[4].temporal_id = atoi(value);
8362 }
8364 {
8365 p_gop->pic_param[4].pic_type = atoi(value);
8366 }
8368 {
8369 p_gop->pic_param[4].num_ref_pics = atoi(value);
8370 }
8372 {
8373 p_gop->pic_param[4].rps[0].ref_pic = atoi(value);
8374 }
8376 {
8377 p_gop->pic_param[4].rps[0].ref_pic_used = atoi(value);
8378 }
8380 {
8381 p_gop->pic_param[4].rps[1].ref_pic = atoi(value);
8382 }
8384 {
8385 p_gop->pic_param[4].rps[1].ref_pic_used = atoi(value);
8386 }
8388 {
8389 p_gop->pic_param[4].rps[2].ref_pic = atoi(value);
8390 }
8392 {
8393 p_gop->pic_param[4].rps[2].ref_pic_used = atoi(value);
8394 }
8396 {
8397 p_gop->pic_param[4].rps[3].ref_pic = atoi(value);
8398 }
8400 {
8401 p_gop->pic_param[4].rps[3].ref_pic_used = atoi(value);
8402 }
8403
8405 {
8406 p_gop->pic_param[5].poc_offset = atoi(value);
8407 }
8409 {
8410 p_gop->pic_param[5].qp_offset = atoi(value);
8411 }
8412 /*
8413 OPT(NI_ENC_GOP_PARAMS_G5_QP_FACTOR)
8414 {
8415 p_gop->pic_param[5].qp_factor = atof(value);
8416 }
8417 */
8419 {
8420 p_gop->pic_param[5].temporal_id = atoi(value);
8421 }
8423 {
8424 p_gop->pic_param[5].pic_type = atoi(value);
8425 }
8427 {
8428 p_gop->pic_param[5].num_ref_pics = atoi(value);
8429 }
8431 {
8432 p_gop->pic_param[5].rps[0].ref_pic = atoi(value);
8433 }
8435 {
8436 p_gop->pic_param[5].rps[0].ref_pic_used = atoi(value);
8437 }
8439 {
8440 p_gop->pic_param[5].rps[1].ref_pic = atoi(value);
8441 }
8443 {
8444 p_gop->pic_param[5].rps[1].ref_pic_used = atoi(value);
8445 }
8447 {
8448 p_gop->pic_param[5].rps[2].ref_pic = atoi(value);
8449 }
8451 {
8452 p_gop->pic_param[5].rps[2].ref_pic_used = atoi(value);
8453 }
8455 {
8456 p_gop->pic_param[5].rps[3].ref_pic = atoi(value);
8457 }
8459 {
8460 p_gop->pic_param[5].rps[3].ref_pic_used = atoi(value);
8461 }
8462
8464 {
8465 p_gop->pic_param[6].poc_offset = atoi(value);
8466 }
8468 {
8469 p_gop->pic_param[6].qp_offset = atoi(value);
8470 }
8471 /*
8472 OPT(NI_ENC_GOP_PARAMS_G6_QP_FACTOR)
8473 {
8474 p_gop->pic_param[6].qp_factor = atof(value);
8475 }
8476 */
8478 {
8479 p_gop->pic_param[6].temporal_id = atoi(value);
8480 }
8482 {
8483 p_gop->pic_param[6].pic_type = atoi(value);
8484 }
8486 {
8487 p_gop->pic_param[6].num_ref_pics = atoi(value);
8488 }
8490 {
8491 p_gop->pic_param[6].rps[0].ref_pic = atoi(value);
8492 }
8494 {
8495 p_gop->pic_param[6].rps[0].ref_pic_used = atoi(value);
8496 }
8498 {
8499 p_gop->pic_param[6].rps[1].ref_pic = atoi(value);
8500 }
8502 {
8503 p_gop->pic_param[6].rps[1].ref_pic_used = atoi(value);
8504 }
8506 {
8507 p_gop->pic_param[6].rps[2].ref_pic = atoi(value);
8508 }
8510 {
8511 p_gop->pic_param[6].rps[2].ref_pic_used = atoi(value);
8512 }
8514 {
8515 p_gop->pic_param[6].rps[3].ref_pic = atoi(value);
8516 }
8518 {
8519 p_gop->pic_param[6].rps[3].ref_pic_used = atoi(value);
8520 }
8521
8523 {
8524 p_gop->pic_param[7].poc_offset = atoi(value);
8525 }
8527 {
8528 p_gop->pic_param[7].qp_offset = atoi(value);
8529 }
8530 /*
8531 OPT(NI_ENC_GOP_PARAMS_G7_QP_FACTOR)
8532 {
8533 p_gop->pic_param[7].qp_factor = atof(value);
8534 }
8535 */
8537 {
8538 p_gop->pic_param[7].temporal_id = atoi(value);
8539 }
8541 {
8542 p_gop->pic_param[7].pic_type = atoi(value);
8543 }
8545 {
8546 p_gop->pic_param[7].num_ref_pics = atoi(value);
8547 }
8549 {
8550 p_gop->pic_param[7].rps[0].ref_pic = atoi(value);
8551 }
8553 {
8554 p_gop->pic_param[7].rps[0].ref_pic_used = atoi(value);
8555 }
8557 {
8558 p_gop->pic_param[7].rps[1].ref_pic = atoi(value);
8559 }
8561 {
8562 p_gop->pic_param[7].rps[1].ref_pic_used = atoi(value);
8563 }
8565 {
8566 p_gop->pic_param[7].rps[2].ref_pic = atoi(value);
8567 }
8569 {
8570 p_gop->pic_param[7].rps[2].ref_pic_used = atoi(value);
8571 }
8573 {
8574 p_gop->pic_param[7].rps[3].ref_pic = atoi(value);
8575 }
8577 {
8578 p_gop->pic_param[7].rps[3].ref_pic_used = atoi(value);
8579 }
8580 else
8581 {
8582 ni_log(NI_LOG_ERROR, "%s(): Invalid parameter name passed\n", __func__);
8584 }
8585#endif
8586
8587#undef OPT
8588#undef OPT2
8589#undef atobool
8590#undef atoi
8591#undef atof
8592
8593 b_error |= bValueWasNull && !bNameWasBool;
8594
8595 ni_log(NI_LOG_TRACE, "%s(): exit, b_error=%d\n", __func__, b_error);
8596
8598}
8599
8600/*!*****************************************************************************
8601* \brief Copy existing decoding session params for hw frame usage
8602*
8603* \param[in] src_p_ctx Pointer to a caller allocated source session context
8604* \param[in] dst_p_ctx Pointer to a caller allocated destination session
8605* context
8606* \return On success
8607* NI_RETCODE_SUCCESS
8608* On failure
8609* NI_RETCODE_INVALID_PARAM
8610******************************************************************************/
8612{
8613 return ni_decoder_session_copy_internal(src_p_ctx, dst_p_ctx);
8614}
8615
8616/*!*****************************************************************************
8617* \brief Read data from the device
8618* If device_type is NI_DEVICE_TYPE_DECODER reads data hwdesc from
8619* decoder
8620* If device_type is NI_DEVICE_TYPE_SCALER reads data hwdesc from
8621* scaler
8622*
8623* \param[in] p_ctx Pointer to a caller allocated
8624* ni_session_context_t struct
8625* \param[in] p_data Pointer to a caller allocated
8626* ni_session_data_io_t struct which contains either a
8627* ni_frame_t data frame or ni_packet_t data packet to
8628* send
8629* \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_SCALER
8630* If NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_SCALER is specified,
8631* hw descriptor info will be stored in p_data ni_frame
8632* \return On success
8633* Total number of bytes read
8634* On failure
8635* NI_RETCODE_INVALID_PARAM
8636* NI_RETCODE_ERROR_NVME_CMD_FAILED
8637* NI_RETCODE_ERROR_INVALID_SESSION
8638******************************************************************************/
8640{
8641 ni_log2(p_ctx, NI_LOG_DEBUG, "%s start\n", __func__);
8643 if ((!p_ctx) || (!p_data))
8644 {
8645 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
8646 __func__);
8648 }
8649
8650 // Here check if keep alive thread is closed.
8651#ifdef _WIN32
8652 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
8654#else
8655 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
8657#endif
8658 {
8659 ni_log2(p_ctx, NI_LOG_ERROR,
8660 "ERROR: %s() keep alive thread has been closed, "
8661 "hw:%d, session:%d\n",
8662 __func__, p_ctx->hw_id, p_ctx->session_id);
8664 }
8665
8667 // In close state, let the close process execute first.
8669 {
8670 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
8672 ni_usleep(100);
8674 }
8677
8678 switch (device_type)
8679 {
8681 {
8682 int seq_change_read_count = 0;
8683 p_data->data.frame.src_codec = p_ctx->codec_format;
8684 for (;;)
8685 {
8686 //retval = ni_decoder_session_read(p_ctx, &(p_data->data.frame));
8687 retval = ni_decoder_session_read_desc(p_ctx, &(p_data->data.frame));
8688 // check resolution change only after initial setting obtained
8689 // p_data->data.frame.video_width is picture width and will be 32-align
8690 // adjusted to frame size; p_data->data.frame.video_height is the same as
8691 // frame size, then compare them to saved one for resolution checking
8692 //
8693 uint32_t aligned_width;
8694 if(QUADRA)
8695 {
8696 aligned_width = ((((p_data->data.frame.video_width * p_ctx->bit_depth_factor) + 127) / 128) * 128);
8697 }
8698 else
8699 {
8700 aligned_width = ((p_data->data.frame.video_width + 31) / 32) * 32;
8701 }
8702
8703 ni_log2(p_ctx, NI_LOG_DEBUG,
8704 "FNum %" PRIu64
8705 ", DFVWxDFVH %u x %u, AlWid %u, AVW x AVH %u x %u\n",
8706 p_ctx->frame_num, p_data->data.frame.video_width,
8707 p_data->data.frame.video_height, aligned_width,
8709
8710 if (0 == retval && seq_change_read_count)
8711 {
8712 ni_log2(p_ctx, NI_LOG_DEBUG, "%s (decoder): seq change NO data, next time.\n",
8713 __func__);
8714 p_ctx->active_video_width = 0;
8715 p_ctx->active_video_height = 0;
8716 p_ctx->actual_video_width = 0;
8717 break;
8718 }
8719 else if (retval < 0)
8720 {
8721 ni_log2(p_ctx, NI_LOG_ERROR, "%s (decoder): failure ret %d, return ..\n",
8722 __func__, retval);
8723 break;
8724 }
8725 // aligned_width may equal to active_video_width if bit depth and width
8726 // are changed at the same time. So, check video_width != actual_video_width.
8727 else if (p_ctx->frame_num && (p_ctx->pixel_format_changed ||
8728 (p_data->data.frame.video_width &&
8729 p_data->data.frame.video_height &&
8730 (aligned_width != p_ctx->active_video_width ||
8731 p_data->data.frame.video_height != p_ctx->active_video_height))))
8732 {
8733 ni_log2(
8734 p_ctx, NI_LOG_DEBUG,
8735 "%s (decoder): resolution change, frame size %ux%u -> %ux%u, "
8736 "width %u bit %d, pix_fromat_changed %d, actual_video_width %d, continue read ...\n",
8737 __func__, p_ctx->active_video_width, p_ctx->active_video_height,
8738 aligned_width, p_data->data.frame.video_height,
8739 p_data->data.frame.video_width, p_ctx->bit_depth_factor,
8741 // reset active video resolution to 0 so it can be queried in the re-read
8742 p_ctx->active_video_width = 0;
8743 p_ctx->active_video_height = 0;
8744 p_ctx->actual_video_width = 0;
8745 seq_change_read_count++;
8746 //break;
8747 }
8748 else
8749 {
8750 break;
8751 }
8752 }
8753 break;
8754 }
8756 {
8757 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Encoder has no hwdesc to read\n");
8759 }
8760
8762 {
8763 retval = ni_scaler_session_read_hwdesc(p_ctx, &(p_data->data.frame));
8764 break;
8765 }
8766
8767 case NI_DEVICE_TYPE_AI:
8768 {
8769 retval = ni_ai_session_read_hwdesc(p_ctx, &(p_data->data.frame));
8770 break;
8771 }
8772
8773 default:
8774 {
8775 retval = NI_RETCODE_INVALID_PARAM;
8776 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
8777 __func__, device_type);
8778 break;
8779 }
8780 }
8781
8783 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
8785
8786 return retval;
8787}
8788
8789/*!*****************************************************************************
8790* \brief Reads YUV data from hw descriptor stored location on device
8791*
8792* \param[in] p_ctx Pointer to a caller allocated
8793* ni_session_context_t struct
8794* \param[in] p_data Pointer to a caller allocated
8795* ni_session_data_io_t struct which contains either a
8796* ni_frame_t data frame or ni_packet_t data packet to
8797* send
8798* \param[in] hwdesc HW descriptor to find frame in XCODER
8799* \return On success
8800* Total number of bytes read
8801* On failure
8802* NI_RETCODE_INVALID_PARAM
8803* NI_RETCODE_ERROR_NVME_CMD_FAILED
8804* NI_RETCODE_ERROR_INVALID_SESSION
8805*******************************************************************************/
8807{
8809 if ((!hwdesc) || (!p_data))
8810 {
8811 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8812 __func__);
8814 }
8815
8816 /* download by frameidx */
8817 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rd") >= 0))
8818 {
8819 if(hwdesc->ui16FrameIdx == 0)
8820 {
8821 ni_log(NI_LOG_ERROR, "%s(): Invaild frame index\n", __func__);
8823 }
8824 retval = ni_hwdownload_by_frame_idx(hwdesc, &(p_data->data.frame), p_ctx->is_auto_dl);
8825 } else {
8826 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
8827 {
8828 if (p_ctx->pext_mutex == &(p_ctx->mutex))
8829 {
8830 ni_log(NI_LOG_ERROR, "ERROR %s(): Invalid session\n",
8831 __func__);
8833 }
8834 }
8835
8837 bool use_external_mutex = false;
8838 uint32_t orig_session_id = p_ctx->session_id;
8839 ni_device_handle_t orig_blk_io_handle = p_ctx->blk_io_handle;
8840 uint32_t orig_codec_format = p_ctx->codec_format;
8841 int orig_bit_depth_factor = p_ctx->bit_depth_factor;
8842 int orig_hw_action = p_ctx->hw_action;
8843
8844 ni_pthread_mutex_t *p_ctx_mutex = &(p_ctx->mutex);
8845 if ((p_ctx_mutex != p_ctx->pext_mutex) ||
8848 "6r8") < 0)
8849 {
8850 use_external_mutex = true;
8851 p_ctx->session_id = hwdesc->ui16session_ID;
8852 p_ctx->blk_io_handle = (ni_device_handle_t)(int64_t)hwdesc->device_handle;
8853 p_ctx->codec_format = NI_CODEC_FORMAT_H264; //unused
8854 p_ctx->bit_depth_factor = (int)hwdesc->bit_depth;
8856 }
8857
8859
8860 retval = ni_hwdownload_session_read(p_ctx, &(p_data->data.frame), hwdesc); //cut me down as needed
8861
8862 p_ctx->xcoder_state &= ~NI_XCODER_HWDL_STATE;
8863 if (use_external_mutex)
8864 {
8865 p_ctx->session_id = orig_session_id;
8866 p_ctx->blk_io_handle = orig_blk_io_handle;
8867 p_ctx->codec_format = orig_codec_format;
8868 p_ctx->bit_depth_factor = orig_bit_depth_factor;
8869 p_ctx->hw_action = orig_hw_action;
8870 }
8872 }
8873
8874 return retval;
8875}
8876
8877/*!*****************************************************************************
8878* \brief Query the session if a buffer is available
8879*
8880* \param[in] p_ctx Pointer to a caller allocated
8881* ni_session_context_t struct
8882* [in] device_type Quadra device type
8883*
8884* \return On success
8885* NI_RETCODE_SUCCESS
8886* On failure
8887* NI_RETCODE_INVALID_PARAM
8888* NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
8889* NI_RETCODE_ERROR_NVME_CMD_FAILED
8890* NI_RETCODE_ERROR_INVALID_SESSION
8891*******************************************************************************/
8893 ni_device_type_t device_type)
8894{
8896
8897 if (!p_ctx)
8898 {
8899 ni_log(NI_LOG_ERROR, "ERROR: No session\n");
8901 }
8902
8905 "6rt") < 0)
8906 {
8907 ni_log2(p_ctx, NI_LOG_DEBUG,
8908 "%s function not supported in FW API version < 6rt\n",
8909 __func__);
8911 }
8912
8913 switch (device_type)
8914 {
8918
8920
8921 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
8923 break;
8924
8928
8930
8931 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
8933 break;
8934
8935 default:
8936 break;
8937 }
8938
8939 return retval;
8940}
8941
8942/*!*****************************************************************************
8943* \brief Sends raw YUV input to uploader instance and retrieves a HW descriptor
8944* to represent it
8945*
8946* \param[in] p_ctx Pointer to a caller allocated
8947* ni_session_context_t struct
8948* \param[in] p_src_data Pointer to a caller allocated
8949* ni_session_data_io_t struct which contains a
8950* ni_frame_t data frame to send to uploader
8951* \param[out] hwdesc HW descriptor to find frame in XCODER
8952* \return On success
8953* Total number of bytes read
8954* On failure
8955* NI_RETCODE_INVALID_PARAM
8956* NI_RETCODE_ERROR_NVME_CMD_FAILED
8957* NI_RETCODE_ERROR_INVALID_SESSION
8958*******************************************************************************/
8960{
8962 if ((!hwdesc) || (!p_src_data))
8963 {
8964 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8965 __func__);
8967 }
8970
8971 retval = ni_hwupload_session_write(p_ctx, &p_src_data->data.frame, hwdesc);
8972
8973 p_ctx->xcoder_state &= ~NI_XCODER_HWUP_STATE;
8975
8976 return retval;
8977}
8978
8979/*!*****************************************************************************
8980* \brief Allocate memory for the hwDescriptor buffer based on provided
8981* parameters taking into account pic size and extra data.
8982*
8983* \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
8984*
8985* \param[in] video_width Width of the video frame
8986* \param[in] video_height Height of the video frame
8987* \param[in] extra_len Extra data size (incl. meta data)
8988*
8989* \return On success
8990* NI_RETCODE_SUCCESS
8991* On failure
8992* NI_RETCODE_INVALID_PARAM
8993* NI_RETCODE_ERROR_MEM_ALOC
8994*****************************************************************************/
8996 int video_height, int extra_len)
8997{
8998 void* p_buffer = NULL;
8999 int height_aligned = video_height;
9000 int retval = NI_RETCODE_SUCCESS;
9001
9002 if (!p_frame)
9003 {
9004 ni_log(NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9005 __func__);
9007 }
9008
9009 ni_log(NI_LOG_DEBUG, "%s: extra_len=%d\n", __func__, extra_len);
9010
9011 int buffer_size = (int)sizeof(niFrameSurface1_t) + extra_len;
9012
9014
9015 //Check if Need to free
9016 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
9017 {
9018 ni_log(NI_LOG_DEBUG, "%s: free current p_frame->buffer_size=%u\n",
9019 __func__, p_frame->buffer_size);
9020 ni_frame_buffer_free(p_frame);
9021 }
9022
9023 //Check if need to realocate
9024 if (p_frame->buffer_size != buffer_size)
9025 {
9026 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
9027 {
9028 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
9029 NI_ERRNO, __func__);
9031 LRETURN;
9032 }
9033
9034 // init once after allocation
9035 memset(p_buffer, 0, buffer_size);
9036 p_frame->buffer_size = buffer_size;
9037 p_frame->p_buffer = p_buffer;
9038
9039 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
9040 }
9041 else
9042 {
9043 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
9044 }
9045
9046 p_frame->p_data[3] = p_frame->p_buffer;
9047 p_frame->p_data[0] = NULL;
9048 p_frame->p_data[1] = NULL;
9049 p_frame->p_data[2] = NULL;
9050
9051 p_frame->data_len[0] = 0;//luma_size;
9052 p_frame->data_len[1] = 0;//chroma_b_size;
9053 p_frame->data_len[2] = 0;//chroma_r_size;
9054 p_frame->data_len[3] = sizeof(niFrameSurface1_t);
9055
9056 p_frame->video_width = video_width;
9057 p_frame->video_height = height_aligned;
9058
9059 ((niFrameSurface1_t*)p_frame->p_data[3])->device_handle = (int32_t)NI_INVALID_DEVICE_HANDLE;
9060
9061 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
9062 p_frame->buffer_size);
9063
9064END:
9065
9066 if (NI_RETCODE_SUCCESS != retval)
9067 {
9068 ni_aligned_free(p_buffer);
9069 }
9070
9071 return retval;
9072}
9073
9074/*!*****************************************************************************
9075* \brief Recycle a frame buffer on card
9076*
9077* \param[in] surface Struct containing device and frame location to clear out
9078* \param[in] device_handle handle to access device memory buffer is stored in
9079*
9080* \return On success NI_RETCODE_SUCCESS
9081* On failure NI_RETCODE_INVALID_PARAM
9082*******************************************************************************/
9084 int32_t device_handle)
9085{
9087
9088 if (surface)
9089 {
9090 ni_log(NI_LOG_DEBUG, "%s(): Start cleaning out buffer\n", __func__);
9092 "%s(): ui16FrameIdx=%d sessionId=%d device_handle=0x%x\n",
9093 __func__, surface->ui16FrameIdx, surface->ui16session_ID,
9094 device_handle);
9095 retval = ni_clear_instance_buf(surface);
9096 }
9097 else
9098 {
9099 ni_log(NI_LOG_DEBUG, "%s(): Surface is empty\n", __func__);
9100 }
9101
9102 return retval;
9103}
9104
9105/*!*****************************************************************************
9106* \brief Recycle a frame buffer on card, only hwframe descriptor is needed
9107*
9108* \param[in] surface Struct containing device and frame location to clear out
9109*
9110* \return On success NI_RETCODE_SUCCESS
9111* On failure NI_RETCODE_INVALID_PARAM
9112*******************************************************************************/
9114{
9116 int32_t saved_dma_buf_fd;
9117 if (surface)
9118 {
9119 if(surface->ui16FrameIdx == 0)
9120 {
9121 ni_log(NI_LOG_DEBUG, "%s(): Invaild frame index\n", __func__);
9122 return retval;
9123 }
9124 ni_log(NI_LOG_DEBUG, "%s(): Start cleaning out buffer\n", __func__);
9126 "%s(): ui16FrameIdx=%d sessionId=%d device_handle=0x%x\n",
9127 __func__, surface->ui16FrameIdx, surface->ui16session_ID,
9128 surface->device_handle);
9129 retval = ni_clear_instance_buf(surface);
9130 saved_dma_buf_fd = surface->dma_buf_fd;
9131 memset(surface, 0, sizeof(niFrameSurface1_t));
9132 surface->dma_buf_fd = saved_dma_buf_fd;
9133 }
9134 else
9135 {
9136 ni_log(NI_LOG_DEBUG, "%s(): Surface is empty\n", __func__);
9137 retval = NI_RETCODE_INVALID_PARAM;
9138 }
9139
9140 return retval;
9141}
9142
9143/*!*****************************************************************************
9144* \brief Sends frame pool setup info to device
9145*
9146* \param[in] p_ctx Pointer to a caller allocated
9147* ni_session_context_t struct
9148* \param[in] pool_size Upload session initial allocated frames count
9149* must be > 0,
9150* \param[in] pool 0 use the normal pool
9151* 1 use a dedicated P2P pool
9152*
9153* \return On success Return code
9154* On failure
9155* NI_RETCODE_INVALID_PARAM
9156* NI_RETCODE_ERROR_NVME_CMD_FAILED
9157* NI_RETCODE_ERROR_INVALID_SESSION
9158* NI_RETCODE_ERROR_MEM_ALOC
9159*******************************************************************************/
9161 uint32_t pool_size, uint32_t pool)
9162{
9164 if (!p_ctx)
9165 {
9166 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9167 __func__);
9169 }
9170 if (pool_size == 0 || pool_size > NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL)
9171 {
9172 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Invalid poolsize == 0 or > 100\n");
9174 }
9175 if (pool & NI_UPLOADER_FLAG_LM)
9176 {
9177 ni_log2(p_ctx, NI_LOG_DEBUG, "uploader buffer acquisition is limited!\n");
9178 }
9181
9182 retval = ni_config_instance_set_uploader_params(p_ctx, pool_size, pool);
9183
9184 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9186
9187 return retval;
9188}
9189
9190/*!*****************************************************************************
9191* \brief Sends frame pool change info to device
9192*
9193* \param[in] p_ctx Pointer to a caller allocated
9194* ni_session_context_t struct
9195* \param[in] pool_size if pool_size = 0, free allocated device memory buffers
9196* if pool_size > 0, expand device frame buffer pool of
9197* current instance with pool_size more frame buffers
9198*
9199* \return On success Return code
9200* On failure
9201* NI_RETCODE_FAILURE
9202* NI_RETCODE_INVALID_PARAM
9203* NI_RETCODE_ERROR_NVME_CMD_FAILED
9204* NI_RETCODE_ERROR_INVALID_SESSION
9205* NI_RETCODE_ERROR_MEM_ALOC
9206* NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9207*******************************************************************************/
9209 uint32_t pool_size)
9210{
9212 if (!p_ctx)
9213 {
9214 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9215 __func__);
9217 }
9220 "6r3") < 0)
9221 {
9222 ni_log2(p_ctx, NI_LOG_ERROR,
9223 "ERROR: %s function not supported in FW API version < 6r3\n",
9224 __func__);
9226 }
9227 if (p_ctx->pool_type == NI_POOL_TYPE_NONE)
9228 {
9229 ni_log2(p_ctx, NI_LOG_ERROR,
9230 "ERROR: can't free or expand framepool of session 0x%x "
9231 "before init framepool\n", p_ctx->session_id);
9232 return NI_RETCODE_FAILURE;
9233 }
9234 if (pool_size > NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL)
9235 {
9236 ni_log2(p_ctx, NI_LOG_ERROR,
9237 "ERROR: Invalid poolsize > %u\n", NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL);
9239 }
9240 if (pool_size == 0)
9241 {
9242 ni_log2(p_ctx, NI_LOG_INFO, "Free frame pool of session 0x%x\n", p_ctx->session_id);
9243 }
9244
9247
9248 retval = ni_config_instance_set_uploader_params(p_ctx, pool_size, p_ctx->pool_type);
9249
9250 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9252
9253 return retval;
9254}
9255
9256/*!*****************************************************************************
9257 * \brief Set parameters on the device for the 2D engine
9258 *
9259 * \param[in] p_ctx pointer to session context
9260 * \param[in] p_params pointer to scaler parameters
9261 *
9262 * \return NI_RETCODE_INVALID_PARAM
9263 * NI_RETCODE_ERROR_INVALID_SESSION
9264 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9265 * NI_RETCODE_ERROR_MEM_ALOC
9266 ******************************************************************************/
9268 ni_scaler_params_t *p_params)
9269{
9271
9272 if (!p_ctx || !p_params)
9273 {
9274 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9275 __func__);
9277 }
9280
9281 retval = ni_config_instance_set_scaler_params(p_ctx, p_params);
9282
9283 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9285
9286 return retval;
9287}
9288
9289/*!******************************************************************************
9290 * \brief Send a p_config command to configure scaling drawbox parameters.
9291 *
9292 * \param ni_session_context_t p_ctx - xcoder Context
9293 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_drawbox params_t struct
9294 *
9295 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
9296*******************************************************************************/
9299{
9300 void *p_scaler_config = NULL;
9301 uint32_t buffer_size = sizeof(ni_scaler_multi_drawbox_params_t);
9303 uint32_t ui32LBA = 0;
9304
9305 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
9306
9307 if (!p_ctx || !p_params)
9308 {
9309 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n", __func__);
9310 retval = NI_RETCODE_INVALID_PARAM;
9311 LRETURN;
9312 }
9313
9314 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
9315 {
9316 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n", __func__);
9318 LRETURN;
9319 }
9320
9321 buffer_size =
9322 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
9324 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
9325 {
9326 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
9327 NI_ERRNO, __func__);
9329 LRETURN;
9330 }
9331 memset(p_scaler_config, 0, buffer_size);
9332
9333 //configure the session here
9336
9337 memcpy(p_scaler_config, p_params, buffer_size);
9338
9340 p_scaler_config, buffer_size, ui32LBA) < 0)
9341 {
9342 ni_log2(p_ctx, NI_LOG_ERROR,
9343 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
9344 ", hw_id, %d, xcoder_inst_id: %d\n",
9345 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
9346 // Close the session since we can't configure it as per fw
9347 retval = ni_scaler_session_close(p_ctx, 0);
9348 if (NI_RETCODE_SUCCESS != retval)
9349 {
9350 ni_log2(p_ctx, NI_LOG_ERROR,
9351 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
9352 "hw_id, %d, xcoder_inst_id: %d\n",
9353 __func__,
9354 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
9355 p_ctx->session_id);
9356 }
9357
9359 }
9360
9361END:
9362
9363 ni_aligned_free(p_scaler_config);
9364 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
9365
9366 return retval;
9367}
9368
9369/*!******************************************************************************
9370 * \brief Send a p_config command to configure scaling watermark parameters.
9371 *
9372 * \param ni_session_context_t p_ctx - xcoder Context
9373 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_watermark_params_t struct
9374 *
9375 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
9376*******************************************************************************/
9379{
9380 void *p_scaler_config = NULL;
9381 uint32_t buffer_size = sizeof(ni_scaler_multi_watermark_params_t);
9383 uint32_t ui32LBA = 0;
9384
9385 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
9386
9387 if (!p_ctx || !p_params)
9388 {
9389 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n", __func__);
9390 retval = NI_RETCODE_INVALID_PARAM;
9391 LRETURN;
9392 }
9393
9394 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
9395 {
9396 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n", __func__);
9398 LRETURN;
9399 }
9400
9401 buffer_size =
9402 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
9404 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
9405 {
9406 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
9407 NI_ERRNO, __func__);
9409 LRETURN;
9410 }
9411 memset(p_scaler_config, 0, buffer_size);
9412
9413 //configure the session here
9416
9417 memcpy(p_scaler_config, p_params, buffer_size);
9418
9420 p_scaler_config, buffer_size, ui32LBA) < 0)
9421 {
9422 ni_log2(p_ctx, NI_LOG_ERROR,
9423 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
9424 ", hw_id, %d, xcoder_inst_id: %d\n",
9425 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
9426 // Close the session since we can't configure it as per fw
9427 retval = ni_scaler_session_close(p_ctx, 0);
9428 if (NI_RETCODE_SUCCESS != retval)
9429 {
9430 ni_log2(p_ctx, NI_LOG_ERROR,
9431 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
9432 "hw_id, %d, xcoder_inst_id: %d\n",
9433 __func__,
9434 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
9435 p_ctx->session_id);
9436 }
9437
9439 }
9440
9441END:
9442
9443 ni_aligned_free(p_scaler_config);
9444 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
9445
9446 return retval;
9447}
9448
9449
9450/*!*****************************************************************************
9451 * \brief Allocate a frame on the device for 2D engine or AI engine
9452 * to work on based on provided parameters
9453 *
9454 * \param[in] p_ctx pointer to session context
9455 * \param[in] width width, in pixels
9456 * \param[in] height height, in pixels
9457 * \param[in] format pixel format
9458 * \param[in] options options bitmap flags, bit 0 (NI_SCALER_FLAG_IO) is
9459 * 0=input frame or 1=output frame. Bit 1 (NI_SCALER_FLAG_PC) is
9460 * 0=single allocation, 1=create pool. Bit 2 (NI_SCALER_FLAG_PA) is
9461 * 0=straight alpha, 1=premultiplied alpha
9462 * \param[in] rectangle_width clipping rectangle width
9463 * \param[in] rectangle_height clipping rectangle height
9464 * \param[in] rectangle_x horizontal position of clipping rectangle
9465 * \param[in] rectangle_y vertical position of clipping rectangle
9466 * \param[in] rgba_color RGBA fill colour (for padding only)
9467 * \param[in] frame_index input hwdesc index
9468 * \param[in] device_type only NI_DEVICE_TYPE_SCALER
9469 * and NI_DEVICE_TYPE_AI (only needs p_ctx and frame_index)
9470 *
9471 * \return NI_RETCODE_INVALID_PARAM
9472 * NI_RETCODE_ERROR_INVALID_SESSION
9473 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9474 * NI_RETCODE_ERROR_MEM_ALOC
9475 ******************************************************************************/
9477 int width,
9478 int height,
9479 int format,
9480 int options,
9481 int rectangle_width,
9482 int rectangle_height,
9483 int rectangle_x,
9484 int rectangle_y,
9485 int rgba_color,
9486 int frame_index,
9487 ni_device_type_t device_type)
9488{
9490
9491 if (!p_ctx)
9492 {
9493 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9494 __func__);
9496 }
9499
9500 switch (device_type)
9501 {
9503 retval = ni_scaler_alloc_frame(p_ctx,width, height, format, options,
9504 rectangle_width, rectangle_height,
9505 rectangle_x, rectangle_y,
9506 rgba_color, frame_index);
9507 break;
9508
9509 case NI_DEVICE_TYPE_AI:
9510 retval = ni_ai_alloc_hwframe(p_ctx, width, height, options, rgba_color,
9511 frame_index);
9512 break;
9513
9516 /* fall through */
9517
9518 default:
9519 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", device_type);
9520 retval = NI_RETCODE_INVALID_PARAM;
9521 break;
9522 }
9523
9524 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9526
9527 return retval;
9528}
9529
9530/*!*****************************************************************************
9531 * \brief Allocate a frame on the device and return the frame index
9532 *
9533 * \param[in] p_ctx pointer to session context
9534 * \param[in] p_out_surface pointer to output frame surface
9535 * \param[in] device_type currently only NI_DEVICE_TYPE_AI
9536 *
9537 * \return NI_RETCODE_INVALID_PARAM
9538 * NI_RETCODE_ERROR_INVALID_SESSION
9539 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9540 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9541 * NI_RETCODE_ERROR_MEM_ALOC
9542 ******************************************************************************/
9544 niFrameSurface1_t *p_out_surface,
9545 ni_device_type_t device_type)
9546{
9548
9549 if (!p_ctx)
9550 {
9551 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, %p, return\n",
9552 __func__, p_ctx);
9554 }
9557
9558 switch (device_type)
9559 {
9560 case NI_DEVICE_TYPE_AI:
9561 retval = ni_ai_alloc_dst_frame(p_ctx, p_out_surface);
9562 break;
9563
9567 /* fall through */
9568
9569 default:
9570 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", device_type);
9571 retval = NI_RETCODE_INVALID_PARAM;
9572 break;
9573 }
9574
9575 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9577
9578 return retval;
9579}
9580
9581/*!*****************************************************************************
9582 * \brief Copy the data of src hwframe to dst hwframe
9583 *
9584 * \param[in] p_ctx pointer to session context
9585 * \param[in] p_frameclone_desc pointer to the frameclone descriptor
9586 *
9587 * \return NI_RETCODE_INVALID_PARAM
9588 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9589 * NI_RETCODE_ERROR_INVALID_SESSION
9590 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9591 * NI_RETCODE_ERROR_MEM_ALOC
9592 ******************************************************************************/
9594 ni_frameclone_desc_t *p_frameclone_desc)
9595{
9597
9598 if (!p_ctx)
9599 {
9600 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9601 __func__);
9603 }
9604
9607 "6rL") < 0)
9608 {
9609 ni_log2(p_ctx, NI_LOG_ERROR,
9610 "Error: %s function not supported on device with FW API version < 6rL\n",
9611 __func__);
9613 }
9614
9617 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
9618 {
9619 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
9620 __func__);
9622 LRETURN;
9623 }
9624
9625 retval = ni_hwframe_clone(p_ctx, p_frameclone_desc);
9626
9627END:
9628 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9630
9631 return retval;
9632}
9633
9634/*!*****************************************************************************
9635 * \brief Configure the 2D engine to work based on provided parameters
9636 *
9637 * \param[in] p_ctx pointer to session context
9638 * \param[in] p_cfg pointer to frame configuration
9639 *
9640 * \return NI_RETCODE_INVALID_PARAM
9641 * NI_RETCODE_ERROR_INVALID_SESSION
9642 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9643 * NI_RETCODE_ERROR_MEM_ALOC
9644 ******************************************************************************/
9646 ni_frame_config_t *p_cfg)
9647{
9649
9650 if (!p_ctx || !p_cfg)
9651 {
9652 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9653 __func__);
9655 }
9656
9659
9660 switch (p_ctx->device_type)
9661 {
9663 retval = ni_scaler_config_frame(p_ctx, p_cfg);
9664 break;
9665
9666 default:
9667 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", p_ctx->device_type);
9668 retval = NI_RETCODE_INVALID_PARAM;
9669 break;
9670 }
9671
9672 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9674
9675 return retval;
9676}
9677
9678/*!*****************************************************************************
9679 * \brief Configure the 2D engine to work based on provided parameters
9680 *
9681 * \param[in] p_ctx pointer to session context
9682 * \param[in] p_cfg_in pointer to input frame configuration
9683 * \param[in] numInCfgs number of input frame configurations
9684 * \param[in] p_cfg_out pointer to output frame configuration
9685 *
9686 * \return NI_RETCODE_INVALID_PARAM
9687 * NI_RETCODE_ERROR_INVALID_SESSION
9688 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9689 * NI_RETCODE_ERROR_MEM_ALOC
9690 ******************************************************************************/
9692 ni_frame_config_t p_cfg_in[],
9693 int numInCfgs,
9694 ni_frame_config_t *p_cfg_out)
9695{
9697
9698 if (!p_ctx || !p_cfg_in)
9699 {
9700 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9701 __func__);
9703 }
9704
9707
9708 switch (p_ctx->device_type)
9709 {
9711 retval = ni_scaler_multi_config_frame(p_ctx, p_cfg_in, numInCfgs, p_cfg_out);
9712 break;
9713
9714 case NI_DEVICE_TYPE_AI:
9715 retval = ni_ai_multi_config_frame(p_ctx, p_cfg_in, numInCfgs, p_cfg_out);
9716 break;
9717
9718 default:
9719 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", p_ctx->device_type);
9720 retval = NI_RETCODE_INVALID_PARAM;
9721 break;
9722 }
9723
9724 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9726
9727 return retval;
9728}
9729
9730/*!*****************************************************************************
9731 * \brief Calculate the total size of a frame based on the upload
9732 * context attributes and includes rounding up to the page size
9733 *
9734 * \param[in] p_upl_ctx pointer to an uploader session context
9735 * \param[in] linesize array of line stride
9736 *
9737 * \return size
9738 * NI_RETCODE_INVALID_PARAM
9739 *
9740 ******************************************************************************/
9742 const int linesize[])
9743{
9744 int pixel_format;
9745 int width, height;
9746 int alignedh;
9747 int luma, chroma_b, chroma_r;
9748 int total;
9749
9750 pixel_format = p_upl_ctx->pixel_format;
9751 width = p_upl_ctx->active_video_width;
9752 height = p_upl_ctx->active_video_height;
9753
9754 switch (pixel_format)
9755 {
9756 case NI_PIX_FMT_YUV420P:
9758 case NI_PIX_FMT_NV12:
9759 case NI_PIX_FMT_P010LE:
9760 if (width < 0 || width > NI_MAX_RESOLUTION_WIDTH)
9761 {
9763 }
9764
9765 if ((height < 0) || (height > NI_MAX_RESOLUTION_HEIGHT))
9766 {
9768 }
9769 break;
9770
9771 case NI_PIX_FMT_RGBA:
9772 case NI_PIX_FMT_ABGR:
9773 case NI_PIX_FMT_ARGB:
9774 case NI_PIX_FMT_BGRA:
9775 case NI_PIX_FMT_BGR0:
9776 if ((width < 0) || (width > NI_MAX_RESOLUTION_WIDTH))
9777 {
9779 }
9780
9781 if ((height < 0) || (height > NI_MAX_RESOLUTION_HEIGHT))
9782 {
9784 }
9785 break;
9786
9787 default:
9789 }
9790
9791 alignedh = NI_VPU_CEIL(height, 2);
9792
9793 switch (pixel_format)
9794 {
9795 case NI_PIX_FMT_YUV420P:
9797 luma = linesize[0] * alignedh;
9798 chroma_b = linesize[1] * alignedh / 2;
9799 chroma_r = linesize[2] * alignedh / 2;
9800 total =
9801 luma + chroma_b + chroma_r + NI_APP_ENC_FRAME_META_DATA_SIZE;
9802 break;
9803
9804 case NI_PIX_FMT_NV12:
9805 case NI_PIX_FMT_P010LE:
9806 luma = linesize[0] * alignedh;
9807 chroma_b = linesize[1] * alignedh / 2;
9808 chroma_r = 0;
9809 total =
9810 luma + chroma_b + chroma_r + NI_APP_ENC_FRAME_META_DATA_SIZE;
9811 break;
9812
9813 case NI_PIX_FMT_RGBA:
9814 case NI_PIX_FMT_ABGR:
9815 case NI_PIX_FMT_ARGB:
9816 case NI_PIX_FMT_BGRA:
9817 case NI_PIX_FMT_BGR0:
9818 total = width * height * 4 + NI_APP_ENC_FRAME_META_DATA_SIZE;
9819 break;
9820
9821 default:
9823 break;
9824 }
9825
9827
9828 return total;
9829}
9830
9831/*!*****************************************************************************
9832 * \brief Allocate memory for the frame buffer based on provided parameters
9833 * taking into account the pixel format, width, height, stride,
9834 * alignment, and extra data
9835 * \param[in] p_frame Pointer to caller allocated ni_frame_t
9836 * \param[in] pixel_format a pixel format in ni_pix_fmt_t enum
9837 * \param[in] video_width width, in pixels
9838 * \param[in] video_height height, in pixels
9839 * \param[in] linesize horizontal stride
9840 * \param[in] alignment apply a 16 pixel height alignment (T408 only)
9841 * \param[in] extra_len meta data size
9842 *
9843 * \return NI_RETCODE_SUCCESS
9844 * NI_RETCODE_INVALID_PARAM
9845 * NI_RETCODE_ERROR_MEM_ALOC
9846 *
9847 ******************************************************************************/
9849 int video_width, int video_height,
9850 int linesize[], int alignment,
9851 int extra_len)
9852{
9853 int buffer_size;
9854 void *p_buffer = NULL;
9855 int retval = NI_RETCODE_SUCCESS;
9856 int height_aligned;
9857 int luma_size = 0;
9858 int chroma_b_size = 0;
9859 int chroma_r_size = 0;
9860
9861 if (!p_frame)
9862 {
9863 ni_log(NI_LOG_ERROR, "Invalid frame pointer\n");
9865 }
9866
9867 switch (pixel_format)
9868 {
9869 case NI_PIX_FMT_YUV420P:
9871 case NI_PIX_FMT_NV12:
9872 case NI_PIX_FMT_P010LE:
9873 case NI_PIX_FMT_NV16:
9874 case NI_PIX_FMT_YUYV422:
9875 case NI_PIX_FMT_UYVY422:
9876 if ((video_width < 0) || (video_width > NI_MAX_RESOLUTION_WIDTH))
9877 {
9878 ni_log(NI_LOG_ERROR, "Video resolution width %d out of range\n",
9879 video_width);
9881 }
9882
9883 if ((video_height < 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT))
9884 {
9885 ni_log(NI_LOG_ERROR, "Video resolution height %d out of range\n",
9886 video_width);
9888 }
9889 break;
9890
9891 case NI_PIX_FMT_RGBA:
9892 case NI_PIX_FMT_BGRA:
9893 case NI_PIX_FMT_ARGB:
9894 case NI_PIX_FMT_ABGR:
9895 case NI_PIX_FMT_BGR0:
9896 case NI_PIX_FMT_BGRP:
9897 /*
9898 * For 2D engine using RGBA, the minimum width is 32. There is no
9899 * height restriction. The 2D engine supports a height/width of up to
9900 * 32K but but we will limit the max height and width to 8K.
9901 */
9902 if ((video_width < 0) || (video_width > NI_MAX_RESOLUTION_WIDTH))
9903 {
9904 ni_log(NI_LOG_ERROR, "Video resolution width %d out of range\n",
9905 video_width);
9907 }
9908
9909 if ((video_height <= 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT))
9910 {
9911 ni_log(NI_LOG_ERROR, "Video resolution height %d out of range\n",
9912 video_height);
9914 }
9915 break;
9916
9917 default:
9918 ni_log(NI_LOG_ERROR, "Unknown pixel format %d\n",pixel_format);
9920 }
9921
9922 if (QUADRA)
9923 {
9924 /* Quadra requires an even-numbered height/width */
9925 height_aligned = NI_VPU_CEIL(video_height, 2);
9926 }
9927 else
9928 {
9929 height_aligned = NI_VPU_ALIGN8(video_height);
9930
9931 if (alignment)
9932 {
9933 /* 16-pixel aligned pixel height for Quadra */
9934 height_aligned = NI_VPU_ALIGN16(video_height);
9935 }
9936 }
9937
9938 switch (pixel_format)
9939 {
9940 case NI_PIX_FMT_YUV420P:
9942 luma_size = linesize[0] * height_aligned;
9943
9944 if (QUADRA)
9945 {
9946 chroma_b_size = linesize[1] * height_aligned / 2;
9947 chroma_r_size = linesize[2] * height_aligned / 2;
9948 }
9949 else
9950 {
9951 chroma_b_size = luma_size / 4;
9952 chroma_r_size = luma_size / 4;
9953 }
9954 break;
9955
9956 case NI_PIX_FMT_RGBA:
9957 case NI_PIX_FMT_BGRA:
9958 case NI_PIX_FMT_ARGB:
9959 case NI_PIX_FMT_ABGR:
9960 case NI_PIX_FMT_BGR0:
9961 luma_size = linesize[0] * video_height;
9962 chroma_b_size = 0;
9963 chroma_r_size = 0;
9964 break;
9965
9966 case NI_PIX_FMT_NV12:
9967 case NI_PIX_FMT_P010LE:
9968 if (QUADRA)
9969 {
9970 luma_size = linesize[0] * height_aligned;
9971 chroma_b_size = linesize[1] * height_aligned / 2;
9972 chroma_r_size = 0;
9973 break;
9974 }
9975 case NI_PIX_FMT_NV16:
9976 if (QUADRA)
9977 {
9978 luma_size = linesize[0] * video_height;
9979 chroma_b_size = linesize[1] * video_height;
9980 chroma_r_size = 0;
9981 break;
9982 }
9983 case NI_PIX_FMT_YUYV422:
9984 case NI_PIX_FMT_UYVY422:
9985 if (QUADRA)
9986 {
9987 luma_size = linesize[0] * video_height;
9988 chroma_b_size = 0;
9989 chroma_r_size = 0;
9990 break;
9991 }
9992 case NI_PIX_FMT_BGRP:
9993 if (QUADRA)
9994 {
9995 luma_size = NI_VPU_ALIGN32(linesize[0] * video_height);
9996 chroma_b_size = NI_VPU_ALIGN32(linesize[1] * video_height);
9997 chroma_r_size = NI_VPU_ALIGN32(linesize[2] * video_height);
9998 break;
9999 }
10000 /*fall through*/
10001 default:
10002 ni_log(NI_LOG_ERROR, "Error: unsupported pixel format %d\n",pixel_format);
10004 }
10005
10006 buffer_size = luma_size + chroma_b_size + chroma_r_size + extra_len;
10007
10008 /* Allocate a buffer size that is page aligned for the host */
10009 buffer_size = NI_VPU_CEIL(buffer_size,NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
10010
10011 /* If this buffer has a different size, realloc a new buffer */
10012 if ((p_frame->buffer_size > 0) && (p_frame->buffer_size != buffer_size))
10013 {
10014 ni_log(NI_LOG_DEBUG, "Free current p_frame, p_frame->buffer_size %u\n",
10015 p_frame->buffer_size);
10016 ni_frame_buffer_free(p_frame);
10017 }
10018
10019 if (p_frame->buffer_size != buffer_size)
10020 {
10021 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10022 {
10023 ni_log(NI_LOG_ERROR, "Error: Cannot allocate p_frame\n");
10025 LRETURN;
10026 }
10027
10028 memset(p_buffer, 0, buffer_size);
10029 p_frame->buffer_size = buffer_size;
10030 p_frame->p_buffer = p_buffer;
10031 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
10032 }
10033 else
10034 {
10035 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
10036 }
10037
10038 switch (pixel_format)
10039 {
10040 case NI_PIX_FMT_YUV420P:
10042 p_frame->p_data[0] = p_frame->p_buffer;
10043 p_frame->p_data[1] = p_frame->p_data[0] + luma_size;
10044 p_frame->p_data[2] = p_frame->p_data[1] + chroma_b_size;
10045 p_frame->p_data[3] = NULL;
10046
10047 p_frame->data_len[0] = luma_size;
10048 p_frame->data_len[1] = chroma_b_size;
10049 p_frame->data_len[2] = chroma_r_size;
10050 p_frame->data_len[3] = 0;
10051 video_width = NI_VPU_ALIGN128(video_width);
10052 break;
10053
10054 case NI_PIX_FMT_RGBA:
10055 case NI_PIX_FMT_BGRA:
10056 case NI_PIX_FMT_ARGB:
10057 case NI_PIX_FMT_ABGR:
10058 case NI_PIX_FMT_BGR0:
10059 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10060 p_frame->p_data[1] = NULL;
10061 p_frame->p_data[2] = NULL;
10062 p_frame->p_data[3] = NULL;
10063
10064 p_frame->data_len[0] = luma_size;
10065 p_frame->data_len[1] = 0;
10066 p_frame->data_len[2] = 0;
10067 p_frame->data_len[3] = 0;
10068 video_width = NI_VPU_ALIGN16(video_width);
10069 break;
10070
10071 case NI_PIX_FMT_NV12:
10072 case NI_PIX_FMT_P010LE:
10073 if (QUADRA)
10074 {
10075 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10076 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10077 p_frame->p_data[2] = NULL;
10078 p_frame->p_data[3] = NULL;
10079
10080 p_frame->data_len[0] = luma_size;
10081 p_frame->data_len[1] = chroma_b_size;
10082 p_frame->data_len[2] = 0;
10083 p_frame->data_len[3] = 0;
10084
10085 video_width = NI_VPU_ALIGN128(video_width);
10086 break;
10087 }
10088 case NI_PIX_FMT_NV16:
10089 if (QUADRA)
10090 {
10091 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10092 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10093 p_frame->p_data[2] = NULL;
10094 p_frame->p_data[3] = NULL;
10095
10096 p_frame->data_len[0] = luma_size;
10097 p_frame->data_len[1] = chroma_b_size;
10098 p_frame->data_len[2] = 0;
10099 p_frame->data_len[3] = 0;
10100
10101 video_width = NI_VPU_ALIGN64(video_width);
10102 break;
10103 }
10104
10105 case NI_PIX_FMT_YUYV422:
10106 case NI_PIX_FMT_UYVY422:
10107 if (QUADRA)
10108 {
10109 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10110 p_frame->p_data[1] = NULL;
10111 p_frame->p_data[2] = NULL;
10112 p_frame->p_data[3] = NULL;
10113
10114 p_frame->data_len[0] = luma_size;
10115 p_frame->data_len[1] = 0;
10116 p_frame->data_len[2] = 0;
10117 p_frame->data_len[3] = 0;
10118 video_width = NI_VPU_ALIGN16(video_width);
10119 break;
10120 }
10121 case NI_PIX_FMT_BGRP:
10122 if (QUADRA)
10123 {
10124 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10125 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10126 p_frame->p_data[2] = (uint8_t *)p_frame->p_data[1] + chroma_b_size;
10127 p_frame->p_data[3] = NULL;
10128
10129 p_frame->data_len[0] = luma_size;
10130 p_frame->data_len[1] = chroma_b_size;
10131 p_frame->data_len[2] = chroma_r_size;
10132 p_frame->data_len[3] = 0;
10133 break;
10134 }
10135 /* fall through */
10136 default:
10137 ni_log(NI_LOG_ERROR, "Error: unsupported pixel format %d\n",pixel_format);
10138 retval = NI_RETCODE_INVALID_PARAM;
10139 LRETURN;
10140 }
10141
10142 p_frame->video_width = video_width;
10143 p_frame->video_height = height_aligned;
10144
10145 ni_log(NI_LOG_DEBUG, "%s success: w=%d; h=%d; aligned buffer size=%d\n",
10146 __func__, video_width, video_height, buffer_size);
10147
10148END:
10149
10150 if (retval != NI_RETCODE_SUCCESS)
10151 {
10152 ni_aligned_free(p_buffer);
10153 }
10154
10155 return retval;
10156}
10157
10159 ni_network_data_t *p_network,
10160 const char *file)
10161{
10162 FILE *fp = NULL;
10163 struct stat file_stat;
10165 unsigned char *buffer = NULL;
10166
10167 if (!p_ctx)
10168 {
10169 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10170 __func__);
10172 }
10176
10177 char errmsg[NI_ERRNO_LEN] = {0};
10178 if (stat(file, &file_stat) != 0)
10179 {
10181 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to get network binary file stat, %s\n",
10182 __func__, errmsg);
10183 retval = NI_RETCODE_FAILURE;
10184 LRETURN;
10185 }
10186
10187 if (file_stat.st_size == 0)
10188 {
10189 ni_log2(p_ctx, NI_LOG_ERROR, "%s: network binary size is null\n", __func__);
10190 retval = NI_RETCODE_FAILURE;
10191 LRETURN;
10192 }
10193
10194 ni_fopen(&fp, file, "rb");
10195 if (!fp)
10196 {
10198 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to open network binary, %s\n", __func__,
10199 errmsg);
10200 retval = NI_RETCODE_FAILURE;
10201 LRETURN;
10202 }
10203
10204 buffer = malloc(file_stat.st_size);
10205 if (!buffer)
10206 {
10207 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to alloate memory\n", __func__);
10209 LRETURN;
10210 }
10211
10212 if (fread(buffer, file_stat.st_size, 1, fp) != 1)
10213 {
10214 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to read network binary\n", __func__);
10215 retval = NI_RETCODE_FAILURE;
10216 LRETURN;
10217 }
10218
10219 retval =
10220 ni_config_instance_network_binary(p_ctx, buffer, file_stat.st_size);
10221 if (retval != NI_RETCODE_SUCCESS)
10222 {
10223 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to configure instance, retval %d\n",
10224 __func__, retval);
10225 LRETURN;
10226 }
10227
10228 retval = ni_config_read_inout_layers(p_ctx, p_network);
10229 if (retval != NI_RETCODE_SUCCESS)
10230 {
10231 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to read network layers, retval %d\n",
10232 retval);
10233 }
10234
10235END:
10236
10237 if (fp)
10238 {
10239 fclose(fp);
10240 }
10241 free(buffer);
10242
10244 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10246
10247 return retval;
10248}
10249
10251 ni_network_data_t *p_network)
10252{
10254
10255 if (!p_ctx)
10256 {
10257 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10258 __func__);
10260 }
10261
10262 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6ro") < 0))
10263 {
10264 ni_log2(p_ctx, NI_LOG_ERROR, "Error: hvsplus filter not supported on device with FW API version < 6ro\n");
10266 }
10267
10271
10272 retval =
10273 ni_config_instance_hvsplus(p_ctx); //, buffer, file_stat.st_size);
10274 if (retval != NI_RETCODE_SUCCESS)
10275 {
10276 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to configure instance, retval %d\n",
10277 __func__, retval);
10278 LRETURN;
10279 }
10280
10281 retval = ni_config_read_inout_layers(p_ctx, p_network);
10282 if (retval != NI_RETCODE_SUCCESS)
10283 {
10284 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to read network layers, retval %d\n",
10285 retval);
10286 }
10287
10288END:
10289
10291 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10293
10294 return retval;
10295}
10296
10298 ni_network_data_t *p_network)
10299{
10300 uint32_t buffer_size = 0;
10301 void *p_buffer = NULL;
10302 int retval = NI_RETCODE_SUCCESS;
10303 uint32_t i, this_size;
10304 ni_network_layer_info_t *p_linfo;
10305
10306 if (!p_frame || !p_network)
10307 {
10308 ni_log(NI_LOG_ERROR, "Invalid frame or network layer pointer\n");
10310 }
10311
10312 p_linfo = &p_network->linfo;
10313 for (i = 0; i < p_network->input_num; i++)
10314 {
10315 this_size = ni_ai_network_layer_size(&p_linfo->in_param[i]);
10316 this_size =
10317 (this_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
10318 if (p_network->inset[i].offset != buffer_size)
10319 {
10321 "ERROR: %s(): invalid buffer_size of network\n", __func__);
10323 }
10324 buffer_size += this_size;
10325 }
10326
10327 /* fixed size */
10328 p_frame->data_len[0] = buffer_size;
10329
10330 /* Allocate a buffer size that is page aligned for the host */
10331 buffer_size = (buffer_size + NI_MEM_PAGE_ALIGNMENT - 1) &
10332 ~(NI_MEM_PAGE_ALIGNMENT - 1);
10333
10334 /* If this buffer has a different size, realloc a new buffer */
10335 if ((p_frame->buffer_size > 0) && (p_frame->buffer_size != buffer_size))
10336 {
10337 ni_log(NI_LOG_DEBUG, "Free current p_frame, p_frame->buffer_size %u\n",
10338 p_frame->buffer_size);
10339 ni_frame_buffer_free(p_frame);
10340 }
10341
10342 if (p_frame->buffer_size != buffer_size)
10343 {
10344 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10345 {
10346 ni_log(NI_LOG_ERROR, "Error: Cannot allocate p_frame\n");
10348 LRETURN;
10349 }
10350
10351 // memset(p_buffer, 0, buffer_size);
10352 p_frame->buffer_size = buffer_size;
10353 p_frame->p_buffer = p_buffer;
10354 ni_log(NI_LOG_DEBUG, "%s(): allocated new p_frame buffer\n", __func__);
10355 } else
10356 {
10357 ni_log(NI_LOG_DEBUG, "%s(): reuse p_frame buffer\n", __func__);
10358 }
10359
10360 p_frame->p_data[0] = p_frame->p_buffer;
10361 p_frame->p_data[1] = NULL;
10362 p_frame->p_data[2] = NULL;
10363 p_frame->p_data[3] = NULL;
10364
10365 p_frame->iovec = NULL;
10366 p_frame->iovec_num = 0;
10367
10368 ni_log(NI_LOG_DEBUG, "%s() success: aligned buffer size=%u\n", __func__,
10369 buffer_size);
10370
10371END:
10372
10373 if (retval != NI_RETCODE_SUCCESS)
10374 {
10375 ni_aligned_free(p_buffer);
10376 }
10377
10378 return retval;
10379}
10380
10382 ni_network_data_t *p_network)
10383{
10384 void *p_buffer = NULL;
10385 int retval = NI_RETCODE_SUCCESS;
10386 uint32_t buffer_size = 0;
10387 uint32_t i, data_size;
10388 ni_network_layer_info_t *p_linfo;
10389
10390 if (!p_packet || !p_network)
10391 {
10392 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameters passed\n",
10393 __func__);
10395 }
10396
10397 p_linfo = &p_network->linfo;
10398 for (i = 0; i < p_network->output_num; i++)
10399 {
10400 data_size = ni_ai_network_layer_size(&p_linfo->out_param[i]);
10401 data_size =
10402 (data_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
10403 if (p_network->outset[i].offset != buffer_size)
10404 {
10406 "ERROR: %s(): invalid buffer_size of network\n", __func__);
10408 }
10409 buffer_size += data_size;
10410 }
10411 data_size = buffer_size;
10412
10413 ni_log(NI_LOG_DEBUG, "%s(): packet_size=%u\n", __func__, buffer_size);
10414
10415 if (buffer_size & (NI_MEM_PAGE_ALIGNMENT - 1))
10416 {
10417 buffer_size = (buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
10418 ~(NI_MEM_PAGE_ALIGNMENT - 1);
10419 }
10420
10421 if (p_packet->buffer_size == buffer_size)
10422 {
10423 p_packet->p_data = p_packet->p_buffer;
10424 ni_log(NI_LOG_DEBUG, "%s(): reuse current p_packet buffer\n", __func__);
10425 LRETURN; //Already allocated the exact size
10426 } else if (p_packet->buffer_size > 0)
10427 {
10429 "%s(): free current p_packet, p_packet->buffer_size=%u\n",
10430 __func__, p_packet->buffer_size);
10431 ni_packet_buffer_free(p_packet);
10432 }
10433 ni_log(NI_LOG_DEBUG, "%s(): Allocating p_packet buffer, buffer_size=%u\n",
10434 __func__, buffer_size);
10435
10436 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10437 {
10438 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_packet buffer.\n",
10439 NI_ERRNO, __func__);
10441 LRETURN;
10442 }
10443
10444 p_packet->buffer_size = buffer_size;
10445 p_packet->p_buffer = p_buffer;
10446 p_packet->p_data = p_packet->p_buffer;
10447 p_packet->data_len = data_size;
10448
10449END:
10450
10451 if (NI_RETCODE_SUCCESS != retval)
10452 {
10453 ni_aligned_free(p_buffer);
10454 }
10455
10456 ni_log(NI_LOG_TRACE, "%s(): exit: p_packet->buffer_size=%u\n", __func__,
10457 p_packet->buffer_size);
10458
10459 return retval;
10460}
10461
10462/*!*****************************************************************************
10463 * \brief Reconfigure bitrate dynamically during encoding.
10464 *
10465 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10466 * \param[in] bitrate Target bitrate to set
10467 *
10468 * \return On success NI_RETCODE_SUCCESS
10469 * On failure NI_RETCODE_INVALID_PARAM
10470 ******************************************************************************/
10472{
10473 if (!p_ctx || bitrate < NI_MIN_BITRATE || bitrate > NI_MAX_BITRATE)
10474 {
10475 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid bitrate passed in %d\n",
10476 __func__, bitrate);
10478 }
10481
10482 if (p_ctx->target_bitrate > 0)
10483 {
10484 ni_log2(p_ctx, NI_LOG_DEBUG,
10485 "Warning: %s(): bitrate %d overwriting current one %d\n",
10486 __func__, bitrate, p_ctx->target_bitrate);
10487 }
10488
10489 p_ctx->target_bitrate = bitrate;
10490
10491 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10493
10494 return NI_RETCODE_SUCCESS;
10495}
10496
10497/*!*****************************************************************************
10498 * \brief Reconfigure intraPeriod dynamically during encoding.
10499 *
10500 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10501 * \param[in] intra_period Target intra period to set
10502 *
10503 *
10504 * \return On success NI_RETCODE_SUCCESS
10505 * On failure NI_RETCODE_INVALID_PARAM
10506 *
10507 * NOTE - the frame upon which intra period is reconfigured is encoded as IDR frame
10508 * NOTE - reconfigure intra period is not allowed if intraRefreshMode is enabled or if gopPresetIdx is 1
10509 *
10510 ******************************************************************************/
10512 int32_t intra_period)
10513{
10514 if (!p_ctx || intra_period < 0 || intra_period > 1024)
10515 {
10516 ni_log(NI_LOG_ERROR, "ERROR: %s(): invalid intraPeriod passed in %d\n",
10517 __func__, intra_period);
10519 }
10522
10523 if (p_ctx->reconfig_intra_period >= 0)
10524 {
10526 "Warning: %s(): intraPeriod %d overwriting current one %d\n",
10527 __func__, intra_period, p_ctx->reconfig_intra_period);
10528 }
10529
10530 p_ctx->reconfig_intra_period = intra_period;
10531
10532 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10534
10535 return NI_RETCODE_SUCCESS;
10536}
10537
10538/*!*****************************************************************************
10539 * \brief Reconfigure VUI HRD dynamically during encoding.
10540 *
10541 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10542 * \param[in] bitrate Target bitrate to set
10543 *
10544 * \return On success NI_RETCODE_SUCCESS
10545 * On failure NI_RETCODE_INVALID_PARAM
10546 ******************************************************************************/
10548{
10549 if (!p_ctx || vui->colorDescPresent < 0 || vui->colorDescPresent > 1)
10550 {
10551 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid colorDescPresent passed in %d\n",
10552 __func__, vui->colorDescPresent);
10554 }
10555
10557 {
10558 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid aspect ratio passed in (%dx%d)\n",
10559 __func__, vui->aspectRatioWidth, vui->aspectRatioHeight);
10561 }
10562
10563 if (vui->videoFullRange < 0 || vui->videoFullRange > 1)
10564 {
10565 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid videoFullRange passed in %d\n",
10566 __func__, vui->videoFullRange);
10568 }
10569
10572
10574 p_ctx->vui.colorPrimaries = vui->colorPrimaries;
10575 p_ctx->vui.colorTrc = vui->colorTrc;
10576 p_ctx->vui.colorSpace = vui->colorSpace;
10579 p_ctx->vui.videoFullRange = vui->videoFullRange;
10580
10581 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10583
10584 return NI_RETCODE_SUCCESS;
10585}
10586
10587/*!*****************************************************************************
10588 * \brief Force next frame to be IDR frame during encoding.
10589 *
10590 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10591 *
10592 * \return On success NI_RETCODE_SUCCESS
10593 ******************************************************************************/
10595{
10596 if (!p_ctx)
10597 {
10598 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10599 __func__);
10601 }
10604
10605 if (p_ctx->force_idr_frame)
10606 {
10607 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: %s(): already forcing IDR frame\n",
10608 __func__);
10609 }
10610
10611 p_ctx->force_idr_frame = 1;
10612
10613 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10615
10616 return NI_RETCODE_SUCCESS;
10617}
10618
10619/*!*****************************************************************************
10620 * \brief Set a frame's support of Long Term Reference frame during encoding.
10621 *
10622 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10623 * \param[in] ltr Pointer to struct specifying LTR support
10624 *
10625 * \return On success NI_RETCODE_SUCCESS
10626 * On failure NI_RETCODE_INVALID_PARAM
10627 ******************************************************************************/
10629{
10630 if (!p_ctx)
10631 {
10632 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10633 __func__);
10635 }
10637
10641
10643
10644 return NI_RETCODE_SUCCESS;
10645}
10646
10647/*!*****************************************************************************
10648 * \brief Set Long Term Reference interval
10649 *
10650 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10651 * \param[in] ltr_interval the new long term reference inteval value
10652 *
10653 * \return On success NI_RETCODE_SUCCESS
10654 * On failure NI_RETCODE_INVALID_PARAM
10655 ******************************************************************************/
10657 int32_t ltr_interval)
10658{
10659 if (!p_ctx)
10660 {
10661 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10662 __func__);
10664 }
10666
10667 p_ctx->ltr_interval = ltr_interval;
10668
10670
10671 return NI_RETCODE_SUCCESS;
10672}
10673
10674/*!*****************************************************************************
10675 * \brief Set frame reference invalidation
10676 *
10677 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10678 * \param[in] frame_num frame number after which all references shall be
10679 * invalidated
10680 *
10681 * \return On success NI_RETCODE_SUCCESS
10682 * On failure NI_RETCODE_INVALID_PARAM
10683 ******************************************************************************/
10685 int32_t frame_num)
10686{
10687 if (!p_ctx)
10688 {
10689 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10690 __func__);
10692 }
10694 p_ctx->ltr_frame_ref_invalid = frame_num;
10696
10697 return NI_RETCODE_SUCCESS;
10698}
10699
10700/*!*****************************************************************************
10701 * \brief Reconfigure framerate dynamically during encoding.
10702 *
10703 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10704 * \param[in] framerate Target framerate to set
10705 *
10706 * \return On success NI_RETCODE_SUCCESS
10707 * On failure NI_RETCODE_INVALID_PARAM
10708 ******************************************************************************/
10710 ni_framerate_t *framerate)
10711{
10712 int32_t framerate_num = framerate->framerate_num;
10713 int32_t framerate_denom = framerate->framerate_denom;
10714 if (!p_ctx || framerate_num <= 0 || framerate_denom <= 0)
10715 {
10716 ni_log2(p_ctx, NI_LOG_ERROR,
10717 "ERROR: %s(): invalid framerate passed in (%d/%d)\n", __func__,
10718 framerate_num, framerate_denom);
10720 }
10721
10722 if ((framerate_num % framerate_denom) != 0)
10723 {
10724 uint32_t numUnitsInTick = 1000;
10725 framerate_num = framerate_num / framerate_denom;
10726 framerate_denom = numUnitsInTick + 1;
10727 framerate_num += 1;
10728 framerate_num *= numUnitsInTick;
10729 } else
10730 {
10731 framerate_num = framerate_num / framerate_denom;
10732 framerate_denom = 1;
10733 }
10734
10735 if (((framerate_num + framerate_denom - 1) / framerate_denom) >
10737 {
10738 ni_log2(p_ctx, NI_LOG_ERROR,
10739 "ERROR: %s(): invalid framerate passed in (%d/%d)\n", __func__,
10740 framerate->framerate_num, framerate->framerate_denom);
10742 }
10743
10746
10747 if (p_ctx->framerate.framerate_num > 0)
10748 {
10749 ni_log2(p_ctx, NI_LOG_DEBUG,
10750 "Warning: %s(): framerate (%d/%d) overwriting current "
10751 "one (%d/%d)\n",
10752 __func__, framerate_num, framerate_denom,
10753 p_ctx->framerate.framerate_num,
10754 p_ctx->framerate.framerate_denom);
10755 }
10756
10757 p_ctx->framerate.framerate_num = framerate_num;
10758 p_ctx->framerate.framerate_denom = framerate_denom;
10759
10760 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10762
10763 return NI_RETCODE_SUCCESS;
10764}
10765
10766/*!*****************************************************************************
10767 * \brief Reconfigure maxFrameSize dynamically during encoding.
10768 *
10769 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10770 * \param[in] max_frame_size maxFrameSize to set
10771 *
10772 * \return On success NI_RETCODE_SUCCESS
10773 * On failure NI_RETCODE_INVALID_PARAM
10774 *
10775 * NOTE - maxFrameSize_Bytes value less than ((bitrate / 8) / framerate) will be rejected
10776 *
10777 ******************************************************************************/
10779{
10780 ni_xcoder_params_t *api_param;
10781 int32_t bitrate, framerate_num, framerate_denom;
10782 uint32_t maxFrameSize = (uint32_t)max_frame_size / 2000;
10783 uint32_t min_maxFrameSize;
10784
10785 if (!p_ctx || !p_ctx->p_session_config)
10786 {
10787 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10788 __func__);
10790 }
10791
10792 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10793
10794 if (!api_param->low_delay_mode)
10795 {
10796 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size is valid only when lowDelay mode is enabled\n",
10797 __func__, max_frame_size);
10799 }
10800
10801 bitrate = (p_ctx->target_bitrate > 0) ? p_ctx->target_bitrate : api_param->bitrate;
10802
10803 if ((p_ctx->framerate.framerate_num > 0) && (p_ctx->framerate.framerate_denom > 0))
10804 {
10805 framerate_num = p_ctx->framerate.framerate_num;
10806 framerate_denom = p_ctx->framerate.framerate_denom;
10807 }
10808 else
10809 {
10810 framerate_num = (int32_t) api_param->fps_number;
10811 framerate_denom = (int32_t) api_param->fps_denominator;
10812 }
10813
10814 min_maxFrameSize = (((uint32_t)bitrate / framerate_num * framerate_denom) / 8) / 2000;
10815
10816 if (maxFrameSize < min_maxFrameSize)
10817 {
10818 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size %d is too small (invalid)\n",
10819 __func__, max_frame_size);
10821 }
10822 if (max_frame_size > NI_MAX_FRAME_SIZE) {
10823 max_frame_size = NI_MAX_FRAME_SIZE;
10824 }
10825
10828
10829 if (p_ctx->max_frame_size > 0)
10830 {
10831 ni_log2(p_ctx, NI_LOG_DEBUG,
10832 "Warning: %s(): max_frame_size %d overwriting current one %d\n",
10833 __func__, max_frame_size, p_ctx->max_frame_size);
10834 }
10835
10836 p_ctx->max_frame_size = max_frame_size;
10837
10838 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10840
10841 return NI_RETCODE_SUCCESS;
10842}
10843
10844/*!*****************************************************************************
10845 * \brief Reconfigure min&max qp dynamically during encoding.
10846 *
10847 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10848 * \param[in] ni_rc_min_max_qp Target min&max qp to set
10849 *
10850 * \return On success NI_RETCODE_SUCCESS
10851 * On failure NI_RETCODE_INVALID_PARAM
10852 ******************************************************************************/
10854 ni_rc_min_max_qp *p_min_max_qp)
10855{
10856 int32_t minQpI, maxQpI, maxDeltaQp, minQpPB, maxQpPB;
10857
10858 if (!p_ctx || !p_min_max_qp)
10859 {
10860 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_min_max_qp pointer\n",
10861 __func__);
10863 }
10864
10865 minQpI = p_min_max_qp->minQpI;
10866 maxQpI = p_min_max_qp->maxQpI;
10867 maxDeltaQp = p_min_max_qp->maxDeltaQp;
10868 minQpPB = p_min_max_qp->minQpPB;
10869 maxQpPB = p_min_max_qp->maxQpPB;
10870
10871 if (minQpI > maxQpI || minQpPB > maxQpPB ||
10872 maxQpI > 51 || minQpI < 0 || maxQpPB > 51 || minQpPB < 0)
10873 {
10874 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid qp setting <%d %d %d %d %d>\n",
10875 __func__, minQpI, maxQpI, maxDeltaQp, minQpPB, maxQpPB);
10877 }
10878
10881
10882 p_ctx->enc_change_params->minQpI = minQpI;
10883 p_ctx->enc_change_params->maxQpI = maxQpI;
10884 p_ctx->enc_change_params->maxDeltaQp = maxDeltaQp;
10885 p_ctx->enc_change_params->minQpPB = minQpPB;
10886 p_ctx->enc_change_params->maxQpPB = maxQpPB;
10887
10888 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10890
10891 return NI_RETCODE_SUCCESS;
10892}
10893
10894/*!*****************************************************************************
10895 * \brief Reconfigure crf value dynamically during encoding.
10896 *
10897 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10898 * \param[in] crf crf value to reconfigure
10899 *
10900 * \return On success NI_RETCODE_SUCCESS
10901 * On failure NI_RETCODE_INVALID_PARAM
10902 ******************************************************************************/
10904 int32_t crf)
10905{
10906 ni_xcoder_params_t *api_param;
10907
10908 if (!p_ctx || !p_ctx->p_session_config)
10909 {
10910 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10911 __func__);
10913 }
10914
10915 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10916
10917 if (api_param->cfg_enc_params.crf < 0)
10918 {
10919 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %d is valid only in CRF mode\n",
10920 __func__, crf);
10922 }
10923
10924 if (crf < 0 || crf > 51)
10925 {
10926 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %d is invalid (valid range in [0..51])\n",
10927 __func__, crf);
10929 }
10930
10932
10934
10935 if (p_ctx->reconfig_crf >= 0)
10936 {
10937 ni_log2(p_ctx, NI_LOG_DEBUG,
10938 "Warning: %s(): crf reconfig value %d overwriting current reconfig_crf %d\n",
10939 __func__, crf, p_ctx->reconfig_crf);
10940 }
10941
10942 p_ctx->reconfig_crf = crf;
10943
10944 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10945
10947
10948 return NI_RETCODE_SUCCESS;
10949}
10950
10951/*!*****************************************************************************
10952 * \brief Reconfigure crf float point value dynamically during encoding.
10953 *
10954 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10955 * \param[in] crf crf float point value to reconfigure
10956 *
10957 * \return On success NI_RETCODE_SUCCESS
10958 * On failure NI_RETCODE_INVALID_PARAM
10959 ******************************************************************************/
10961 float crf)
10962{
10963 ni_xcoder_params_t *api_param;
10964
10965 if (!p_ctx || !p_ctx->p_session_config)
10966 {
10967 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10968 __func__);
10970 }
10971
10972 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10973
10974 if (api_param->cfg_enc_params.crfFloat < 0)
10975 {
10976 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %f is valid only in CRF mode\n",
10977 __func__, crf);
10979 }
10980
10981 if (crf < 0.0 || crf > 51.0)
10982 {
10983 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %f is invalid (valid range in [0..51])\n",
10984 __func__, crf);
10986 }
10987
10989
10991
10992 if (p_ctx->reconfig_crf >= 0 || p_ctx->reconfig_crf_decimal > 0)
10993 {
10994 ni_log2(p_ctx, NI_LOG_DEBUG,
10995 "Warning: %s(): crf reconfig value %d overwriting current "
10996 "reconfig_crf %d, reconfig_crf_decimal %d\n", __func__,
10997 crf, p_ctx->reconfig_crf, p_ctx->reconfig_crf_decimal);
10998 }
10999
11000 p_ctx->reconfig_crf = (int)crf;
11001 p_ctx->reconfig_crf_decimal = (int)((crf - (float)p_ctx->reconfig_crf) * 100);
11002
11003 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11004
11006
11007 return NI_RETCODE_SUCCESS;
11008}
11009
11010/*!*****************************************************************************
11011 * \brief Reconfigure vbv buffer size and vbv max rate dynamically during encoding.
11012 *
11013 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11014 * \param[in] vbvBufferSize Target vbvBufferSize to set
11015 * \param[in] vbvMaxRate Target vbvMaxRate to set
11016 *
11017 * \return On success NI_RETCODE_SUCCESS
11018 * On failure NI_RETCODE_INVALID_PARAM
11019 ******************************************************************************/
11021 int32_t vbvMaxRate, int32_t vbvBufferSize)
11022{
11023 ni_xcoder_params_t *api_param;
11024 if (!p_ctx || !p_ctx->p_session_config)
11025 {
11026 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11027 __func__);
11029 }
11030 if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
11031 {
11032 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): vbvBufferSize value %d\n",
11033 __func__, vbvBufferSize);
11035 }
11036 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11037 if (api_param->bitrate > 0 && vbvMaxRate > 0 && vbvMaxRate < api_param->bitrate) {
11038 ni_log2(p_ctx, NI_LOG_ERROR, "vbvMaxRate %u cannot be smaller than bitrate %d\n",
11039 vbvMaxRate, api_param->bitrate);
11041 }
11042 if (vbvBufferSize == 0 && vbvMaxRate > 0) {
11043 ni_log2(p_ctx, NI_LOG_INFO, "vbvMaxRate %d does not take effect when "
11044 "vbvBufferSize is 0, force vbvMaxRate to 0\n",
11045 vbvMaxRate);
11046 vbvMaxRate = 0;
11047 }
11048
11051
11052 p_ctx->reconfig_vbv_buffer_size = vbvBufferSize;
11053 p_ctx->reconfig_vbv_max_rate = vbvMaxRate;
11054
11055 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11057
11058 return NI_RETCODE_SUCCESS;
11059}
11060
11061/*!*****************************************************************************
11062 * \brief Reconfigure maxFrameSizeRatio dynamically during encoding.
11063 *
11064 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11065 * \param[in] max_frame_size_ratio maxFrameSizeRatio to set
11066 *
11067 * \return On success NI_RETCODE_SUCCESS
11068 * On failure NI_RETCODE_INVALID_PARAM
11069 ******************************************************************************/
11071{
11072 ni_xcoder_params_t *api_param;
11073 int32_t bitrate, framerate_num, framerate_denom;
11074 uint32_t min_maxFrameSize, maxFrameSize;
11075
11076 if (!p_ctx || !p_ctx->p_session_config)
11077 {
11078 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11079 __func__);
11081 }
11082
11083 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11084
11085 if (!api_param->low_delay_mode)
11086 {
11087 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size_ratio is valid only when lowDelay mode is enabled\n",
11088 __func__, max_frame_size_ratio);
11090 }
11091
11092 if (max_frame_size_ratio < 1) {
11093 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size_ratio %d cannot < 1\n",
11094 max_frame_size_ratio);
11096 }
11097
11098 bitrate = (p_ctx->target_bitrate > 0) ? p_ctx->target_bitrate : api_param->bitrate;
11099
11100 if ((p_ctx->framerate.framerate_num > 0) && (p_ctx->framerate.framerate_denom > 0))
11101 {
11102 framerate_num = p_ctx->framerate.framerate_num;
11103 framerate_denom = p_ctx->framerate.framerate_denom;
11104 }
11105 else
11106 {
11107 framerate_num = (int32_t) api_param->fps_number;
11108 framerate_denom = (int32_t) api_param->fps_denominator;
11109 }
11110
11111 min_maxFrameSize = (((uint32_t)bitrate / framerate_num * framerate_denom) / 8) / 2000;
11112
11113 maxFrameSize = min_maxFrameSize * max_frame_size_ratio > NI_MAX_FRAME_SIZE ?
11114 NI_MAX_FRAME_SIZE : min_maxFrameSize * max_frame_size_ratio;
11115
11118
11119 if (p_ctx->max_frame_size > 0)
11120 {
11121 ni_log2(p_ctx, NI_LOG_DEBUG,
11122 "Warning: %s(): max_frame_size %d overwriting current one %d\n",
11123 __func__, maxFrameSize, p_ctx->max_frame_size);
11124 }
11125
11126 p_ctx->max_frame_size = maxFrameSize;
11127
11128 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11130
11131 return NI_RETCODE_SUCCESS;
11132}
11133
11134/*!*****************************************************************************
11135 * \brief Reconfigure sliceArg dynamically during encoding.
11136 *
11137 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11138 * \param[in] sliceArg the new sliceArg value
11139 *
11140 * \return On success NI_RETCODE_SUCCESS
11141 * On failure NI_RETCODE_INVALID_PARAM
11142 ******************************************************************************/
11144{
11145 ni_xcoder_params_t *api_param;
11147
11148 if (!p_ctx || !p_ctx->p_session_config)
11149 {
11150 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11151 __func__);
11153 }
11154
11155 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11156 p_enc = &api_param->cfg_enc_params;
11157 if (p_enc->slice_mode == 0)
11158 {
11159 ni_log2(p_ctx, NI_LOG_ERROR, "%s():not support to reconfig slice_arg when slice_mode disable.\n",
11160 __func__);
11161 sliceArg = 0;
11162 }
11164 {
11165 ni_log2(p_ctx, NI_LOG_ERROR, "%s():sliceArg is only supported for H.264 or H.265.\n",
11166 __func__);
11167 sliceArg = 0;
11168 }
11169 int ctu_mb_size = (NI_CODEC_FORMAT_H264 == p_ctx->codec_format) ? 16 : 64;
11170 int max_num_ctu_mb_row = (api_param->source_height + ctu_mb_size - 1) / ctu_mb_size;
11171 if (sliceArg < 1 || sliceArg > max_num_ctu_mb_row)
11172 {
11173 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid data sliceArg %d\n", __func__,
11174 sliceArg);
11175 sliceArg = 0;
11176 }
11177
11180
11181 p_ctx->reconfig_slice_arg = sliceArg;
11182
11183 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11185
11186 return NI_RETCODE_SUCCESS;
11187}
11188
11189#ifndef _WIN32
11190/*!*****************************************************************************
11191* \brief Acquire a P2P frame buffer from the hwupload session
11192*
11193* \param[in] p_ctx Pointer to a caller allocated
11194* ni_session_context_t struct
11195* \param[out] p_frame Pointer to a caller allocated hw frame
11196*
11197* \return On success
11198* NI_RETCODE_SUCCESS
11199* On failure
11200* NI_RETCODE_INVALID_PARAM
11201* NI_RETCODE_ERROR_NVME_CMD_FAILED
11202* NI_RETCODE_ERROR_INVALID_SESSION
11203*******************************************************************************/
11205{
11207 struct netint_iocmd_export_dmabuf uexp;
11208 unsigned int offset;
11209 int ret, is_semi_planar;
11210 int linestride[NI_MAX_NUM_DATA_POINTERS];
11211 int alignedheight[NI_MAX_NUM_DATA_POINTERS];
11212 niFrameSurface1_t hwdesc = {0};
11213 niFrameSurface1_t *p_surface;
11214
11215 if (p_ctx == NULL || p_frame == NULL || p_frame->p_data[3] == NULL)
11216 {
11217 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
11218 __func__);
11220 }
11221
11222 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11223
11226
11227 retval = ni_hwupload_session_read_hwdesc(p_ctx, &hwdesc);
11228
11231
11232 if (retval != NI_RETCODE_SUCCESS)
11233 {
11234 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: hwdesc read failure %d\n", retval);
11235 return retval;
11236 }
11237
11238 retval = ni_get_memory_offset(p_ctx, &hwdesc, &offset);
11239 if (retval != NI_RETCODE_SUCCESS)
11240 {
11241 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: bad buffer id\n");
11243 }
11244
11245 is_semi_planar = ((p_ctx->pixel_format == NI_PIX_FMT_NV12) ||
11246 p_ctx->pixel_format == NI_PIX_FMT_P010LE) ?
11247 1 :
11248 0;
11249
11251 p_ctx->bit_depth_factor, is_semi_planar, linestride,
11252 alignedheight);
11253
11254 uexp.fd = -1;
11255 uexp.flags = 0;
11256 uexp.offset = offset;
11257
11258 uexp.length = ni_calculate_total_frame_size(p_ctx, linestride);
11259 uexp.domain = p_ctx->domain;
11260 uexp.bus = p_ctx->bus;
11261 uexp.dev = p_ctx->dev;
11262 uexp.fn = p_ctx->fn;
11263 uexp.bar = 4; // PCI BAR4 configuration space
11264
11265 ret = ioctl(p_ctx->netint_fd, NETINT_IOCTL_EXPORT_DMABUF, &uexp);
11266 if (ret < 0)
11267 {
11268 ni_log2(p_ctx, NI_LOG_ERROR, "%s: Failed to export dmabuf %d errno %d\n",
11269 __func__, ret, NI_ERRNO);
11270 return NI_RETCODE_FAILURE;
11271 }
11272
11273 *p_surface = hwdesc;
11274 p_surface->ui16width = p_ctx->active_video_width;
11275 p_surface->ui16height = p_ctx->active_video_height;
11276 p_surface->ui32nodeAddress = offset;
11277 p_surface->encoding_type = is_semi_planar ?
11280 p_surface->dma_buf_fd = uexp.fd;
11281
11282 return retval;
11283}
11284
11285/*!*****************************************************************************
11286* \brief Acquire a P2P frame buffer from the hwupload session for P2P read
11287*
11288* \param[in] p_ctx Pointer to a caller allocated
11289* ni_session_context_t struct
11290* \param[out] p_frame Pointer to a caller allocated hw frame
11291*
11292* \return On success
11293* NI_RETCODE_SUCCESS
11294* On failure
11295* NI_RETCODE_INVALID_PARAM
11296* NI_RETCODE_ERROR_NVME_CMD_FAILED
11297* NI_RETCODE_ERROR_INVALID_SESSION
11298*******************************************************************************/
11300{
11302
11303 int is_semi_planar;
11304 int linestride[NI_MAX_NUM_DATA_POINTERS];
11305 int alignedheight[NI_MAX_NUM_DATA_POINTERS];
11306 niFrameSurface1_t hwdesc = {0};
11307 niFrameSurface1_t *p_surface;
11308
11309 if (p_ctx == NULL || p_frame == NULL || p_frame->p_data[3] == NULL)
11310 {
11311 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
11312 __func__);
11314 }
11315
11316 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11317
11320
11321 retval = ni_hwupload_session_read_hwdesc(p_ctx, &hwdesc);
11322
11325
11326 if (retval != NI_RETCODE_SUCCESS)
11327 {
11328 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: hwdesc read failure %d\n", retval);
11329 return retval;
11330 }
11331
11332 is_semi_planar = ((p_ctx->pixel_format == NI_PIX_FMT_NV12) ||
11333 p_ctx->pixel_format == NI_PIX_FMT_P010LE) ?
11334 1 :
11335 0;
11336
11338 p_ctx->bit_depth_factor, is_semi_planar, linestride,
11339 alignedheight);
11340
11341 *p_surface = hwdesc;
11342 p_surface->ui16width = p_ctx->active_video_width;
11343 p_surface->ui16height = p_ctx->active_video_height;
11344 p_surface->ui32nodeAddress = 0;
11345 p_surface->encoding_type = is_semi_planar ?
11348 p_surface->dma_buf_fd = 0;
11349
11350 return retval;
11351}
11352
11353
11354/*!*****************************************************************************
11355 * \brief Lock a hardware P2P frame prior to encoding
11356 *
11357 * \param[in] p_upl_ctx pointer to caller allocated upload context
11358 * [in] p_frame pointer to caller allocated hardware P2P frame
11359 *
11360 * \return On success
11361 * NI_RETCODE_SUCCESS
11362 * On failure NI_RETCODE_FAILURE
11363 * NI_RETCODE_INVALID_PARAM
11364*******************************************************************************/
11366 ni_frame_t *p_frame)
11367{
11368 int ret;
11369 struct netint_iocmd_attach_rfence uatch = {0};
11370 struct pollfd pfds[1] = {0};
11371 niFrameSurface1_t *p_surface;
11372
11373 if (p_upl_ctx == NULL || p_frame == NULL)
11374 {
11375 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: bad parameters\n", __func__);
11377 }
11378
11379 if (p_frame->p_data[3] == NULL)
11380 {
11381 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: not a hardware frame\n", __func__);
11383 }
11384
11385 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11386
11387 pfds[0].fd = p_surface->dma_buf_fd;
11388 pfds[0].events = POLLIN;
11389 pfds[0].revents = 0;
11390
11391 ret = poll(pfds, 1, -1);
11392 char errmsg[NI_ERRNO_LEN] = {0};
11393 if (ret < 0)
11394 {
11396 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s:failed to poll dmabuf fd errno %s\n", __func__,
11397 errmsg);
11398 return ret;
11399 }
11400
11401 uatch.fd = p_surface->dma_buf_fd;
11402 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_ATTACH_RFENCE, &uatch);
11403 if (ret < 0)
11404 {
11406 ni_log2(p_upl_ctx, NI_LOG_ERROR,
11407 "%s: failed to attach dmabuf read fence errno %s\n", __func__,
11408 errmsg);
11409 return ret;
11410 }
11411
11412 return NI_RETCODE_SUCCESS;
11413}
11414
11415/*!*****************************************************************************
11416 * \brief Unlock a hardware P2P frame after encoding
11417 *
11418 * \param[in] p_upl_ctx pointer to caller allocated upload context
11419 * [in] p_frame pointer to caller allocated hardware P2P frame
11420 *
11421 * \return On success
11422 * NI_RETCODE_SUCCESS
11423 * On failure NI_RETCODE_FAILURE
11424 * NI_RETCODE_INVALID_PARAM
11425*******************************************************************************/
11427 ni_frame_t *p_frame)
11428{
11429 int ret;
11430 struct netint_iocmd_signal_rfence usigl = {0};
11431 niFrameSurface1_t *p_surface;
11432
11433 if ((p_upl_ctx == NULL) || (p_frame == NULL))
11434 {
11435 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid parameters %p %p\n", __func__,
11436 p_upl_ctx, p_frame);
11438 }
11439
11440 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11441
11442 if (p_surface == NULL)
11443 {
11444 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid hw frame\n", __func__);
11446 }
11447
11448 usigl.fd = p_surface->dma_buf_fd;
11449 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_SIGNAL_RFENCE, &usigl);
11450 if (ret < 0)
11451 {
11452 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Failed to signal dmabuf read fence\n");
11453 return NI_RETCODE_FAILURE;
11454 }
11455
11456 return NI_RETCODE_SUCCESS;
11457}
11458
11459/*!*****************************************************************************
11460 * \brief Special P2P test API function. Copies YUV data from the software
11461 * frame to the hardware P2P frame on the Quadra device
11462 *
11463 * \param[in] p_upl_ctx pointer to caller allocated uploader session
11464 * context
11465 * [in] p_swframe pointer to a caller allocated software frame
11466 * [in] p_hwframe pointer to a caller allocated hardware frame
11467 *
11468 * \return On success
11469 * NI_RETCODE_SUCCESS
11470 * On failure
11471 * NI_RETCODE_FAILURE
11472 * NI_RETCODE_INVALID_PARAM
11473*******************************************************************************/
11475 uint8_t *p_data, uint32_t len,
11476 ni_frame_t *p_hwframe)
11477{
11478 int ret;
11479 struct netint_iocmd_issue_request uis = {0};
11480 niFrameSurface1_t *p_surface;
11481
11482 if (p_upl_ctx == NULL || p_data == NULL || p_hwframe == NULL)
11483 {
11484 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: invalid null parameters\n", __func__);
11486 }
11487
11488 if (p_hwframe->p_data[3] == NULL)
11489 {
11490 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: empty frame\n", __func__);
11492 }
11493
11494 p_surface = (niFrameSurface1_t *)p_hwframe->p_data[3];
11495
11496 uis.fd = p_surface->dma_buf_fd;
11497 uis.data = p_data;
11498 uis.len = len;
11500
11501 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_ISSUE_REQ, &uis);
11502 if (ret < 0)
11503 {
11504 ni_log2(p_upl_ctx, NI_LOG_ERROR,
11505 "%s: Failed to request dmabuf rendering errno %d\n", __func__,
11506 NI_ERRNO);
11507 return NI_RETCODE_FAILURE;
11508 }
11509
11510 return NI_RETCODE_SUCCESS;
11511}
11512
11513/*!*****************************************************************************
11514 * \brief Special P2P test API function. Copies video data from the software
11515 * frame to the hardware P2P frame on the Quadra device. Does not
11516 * need the Netint kernel driver but requires root privilege.
11517 *
11518 * \param[in] p_upl_ctx pointer to caller allocated uploader session
11519 * context
11520 * [in] p_swframe pointer to a caller allocated software frame
11521 * [in] p_hwframe pointer to a caller allocated hardware frame
11522 *
11523 * \return On success
11524 * NI_RETCODE_SUCCESS
11525 * On failure
11526 * NI_RETCODE_FAILURE
11527 * NI_RETCODE_INVALID_PARAM
11528*******************************************************************************/
11530 uint8_t *p_data, uint32_t len,
11531 ni_frame_t *p_hwframe)
11532{
11533 int bar4_fd, ret;
11534 char bar4_name[128];
11535 char *bar4_mm;
11536 struct stat stat;
11537 niFrameSurface1_t *pSurf;
11538 uint32_t offset;
11539
11540 pSurf = (niFrameSurface1_t *) p_hwframe->p_data[3];
11541
11542 ret = ni_get_memory_offset(p_upl_ctx, pSurf, &offset);
11543 if (ret != 0)
11544 {
11545 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Error bad buffer id\n");
11546 return NI_RETCODE_FAILURE;
11547 }
11548
11549 snprintf(bar4_name, 128,
11550 "/sys/bus/pci/devices/%04x:%02x:%02x.%1x/resource4",
11551 p_upl_ctx->domain,p_upl_ctx->bus,p_upl_ctx->dev,p_upl_ctx->fn);
11552
11553 bar4_fd = open(bar4_name, O_RDWR | O_SYNC);
11554
11555 char errmsg[NI_ERRNO_LEN] = {0};
11556 if (bar4_fd < 0)
11557 {
11559 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't open bar4 %s (%s)\n",
11560 bar4_name, errmsg);
11561 return NI_RETCODE_FAILURE;
11562 }
11563
11564 if (fstat(bar4_fd, &stat) != 0)
11565 {
11567 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't stat bar4 (%s)\n",
11568 errmsg);
11569 close(bar4_fd);
11570 return NI_RETCODE_FAILURE;
11571 }
11572
11573 bar4_mm = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, bar4_fd, 0);
11574
11575 if (bar4_mm == MAP_FAILED)
11576 {
11578 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't mmap to bar4 (%s)\n",
11579 errmsg);
11580 close(bar4_fd);
11581 return NI_RETCODE_FAILURE;
11582 }
11583
11584 /* Copy the data directly into Quadra video memory */
11585 memcpy(bar4_mm + offset, p_data, len);
11586
11587 munmap(bar4_mm, 0);
11588 close(bar4_fd);
11589
11590 return NI_RETCODE_SUCCESS;
11591}
11592
11593
11594/*!*****************************************************************************
11595 * \brief Recycle hw P2P frames
11596 *
11597 * \param [in] p_frame pointer to an acquired P2P hw frame
11598 *
11599 * \return on success
11600 * NI_RETCODE_SUCCESS
11601 *
11602 * on failure
11603 * NI_RETCODE_INVALID_PARAM
11604*******************************************************************************/
11606{
11607 niFrameSurface1_t *p_surface;
11608
11609 if (p_frame == NULL)
11610 {
11611 ni_log(NI_LOG_ERROR, "%s: Invalid frame\n", __func__);
11613 }
11614
11615 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11616 if (p_surface == NULL)
11617 {
11618 ni_log(NI_LOG_ERROR, "%s: Invalid surface data\n", __func__);
11620 }
11621
11622 return ni_hwframe_buffer_recycle2(p_surface);
11623}
11624
11625/*!*****************************************************************************
11626 * \brief Acquire the scaler P2P DMA buffer for read/write
11627 *
11628 * \param [in] p_ctx pointer to caller allocated upload context
11629 * [in] p_surface pointer to a caller allocated hardware frame
11630 * [in] data_len scaler frame buffer data length
11631 *
11632 * \return on success
11633 * NI_RETCODE_SUCCESS
11634 *
11635 * on failure
11636 * NI_RETCODE_FAILURE
11637*******************************************************************************/
11639 niFrameSurface1_t *p_surface,
11640 int data_len)
11641{
11642 unsigned int offset;
11643 int ret;
11644
11645 ret = ni_get_memory_offset(p_ctx, p_surface, &offset);
11646 if (ret != 0)
11647 {
11648 ni_log2(p_ctx, NI_LOG_ERROR, "Error: bad buffer id\n");
11649 return NI_RETCODE_FAILURE;
11650 }
11651 p_surface->ui32nodeAddress = 0;
11652
11653 struct netint_iocmd_export_dmabuf uexp;
11654 uexp.fd = -1;
11655 uexp.flags = 0;
11656 uexp.offset = offset;
11657 uexp.length = data_len;
11658 uexp.domain = p_ctx->domain;
11659 uexp.bus = p_ctx->bus;
11660 uexp.dev = p_ctx->dev;
11661 uexp.fn = p_ctx->fn;
11662 uexp.bar = 4;
11663 ret = ioctl(p_ctx->netint_fd, NETINT_IOCTL_EXPORT_DMABUF, &uexp);
11664 if (ret < 0)
11665 {
11666 char errmsg[NI_ERRNO_LEN] = {0};
11668 ni_log2(p_ctx, NI_LOG_ERROR, "failed to export dmabuf: %s\n", errmsg);
11669 return NI_RETCODE_FAILURE;
11670 }
11671 p_surface->dma_buf_fd = uexp.fd;
11672 return ret;
11673}
11674#endif
11675
11676/*!*****************************************************************************
11677 * \brief Set the incoming frame format for the encoder
11678 *
11679 * \param[in] p_enc_ctx pointer to encoder context
11680 * [in] p_enc_params pointer to encoder parameters
11681 * [in] width input width
11682 * [in] height input height
11683 * [in] bit_depth 8 for 8-bit YUV, 10 for 10-bit YUV
11684 * [in] src_endian NI_FRAME_LITTLE_ENDIAN or NI_FRAME_BIG_ENDIAN
11685 * [in] planar 0 for semi-planar YUV, 1 for planar YUV
11686 *
11687 * \return on success
11688 * NI_RETCODE_SUCCESS
11689 *
11690 * on failure
11691 * NI_RETCODE_INVALID_PARAM
11692 *
11693*******************************************************************************/
11695 ni_xcoder_params_t *p_enc_params,
11696 int width, int height,
11697 int bit_depth, int src_endian,
11698 int planar)
11699{
11700 int alignedw;
11701 int alignedh;
11702
11703 if (p_enc_ctx == NULL || p_enc_params == NULL)
11704 {
11705 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: null ptr\n", __func__);
11707 }
11708
11709 if (!(bit_depth == 8) && !(bit_depth == 10))
11710 {
11711 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad bit depth %d\n", __func__, bit_depth);
11713 }
11714
11715 if (!(src_endian == NI_FRAME_LITTLE_ENDIAN) &&
11716 !(src_endian == NI_FRAME_BIG_ENDIAN))
11717 {
11718 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad endian %d\n", __func__, src_endian);
11720 }
11721
11722 if ((planar < 0) || (planar >= NI_PIXEL_PLANAR_MAX))
11723 {
11724 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad planar value %d\n", __func__, planar);
11726 }
11727
11728 p_enc_ctx->src_bit_depth = bit_depth;
11729 p_enc_ctx->bit_depth_factor = (bit_depth == 8) ? 1 : 2;
11730 p_enc_ctx->src_endian = src_endian;
11731
11732 alignedw = width;
11733
11734 if (alignedw < NI_MIN_WIDTH)
11735 {
11736 p_enc_params->cfg_enc_params.conf_win_right +=
11737 (NI_MIN_WIDTH - width) / 2 * 2;
11738 alignedw = NI_MIN_WIDTH;
11739 } else
11740 {
11741 alignedw = ((width + 1) / 2) * 2;
11742 p_enc_params->cfg_enc_params.conf_win_right +=
11743 (alignedw - width) / 2 * 2;
11744 }
11745
11746 p_enc_params->source_width = alignedw;
11747 alignedh = height;
11748
11749 if (alignedh < NI_MIN_HEIGHT)
11750 {
11751 p_enc_params->cfg_enc_params.conf_win_bottom +=
11752 (NI_MIN_HEIGHT - height) / 2 * 2;
11753 alignedh = NI_MIN_HEIGHT;
11754 } else
11755 {
11756 alignedh = ((height + 1) / 2) * 2;
11757 p_enc_params->cfg_enc_params.conf_win_bottom +=
11758 (alignedh - height) / 2 * 2;
11759 }
11760
11761 p_enc_params->source_height = alignedh;
11762 p_enc_params->cfg_enc_params.planar = planar;
11763
11764 return NI_RETCODE_SUCCESS;
11765}
11766
11767/*!*****************************************************************************
11768 * \brief Set the outgoing frame format for the uploader
11769 *
11770 * \param[in] p_upl_ctx pointer to uploader context
11771 * [in] width width
11772 * [in] height height
11773 * [in] pixel_format pixel format
11774 * [in] isP2P 0 = normal, 1 = P2P
11775 *
11776 * \return on success
11777 * NI_RETCODE_SUCCESS
11778 *
11779 * on failure
11780 * NI_RETCODE_INVALID_PARAM
11781*******************************************************************************/
11783 int width, int height,
11784 ni_pix_fmt_t pixel_format, int isP2P)
11785{
11786 if (p_upl_ctx == NULL)
11787 {
11788 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: null ptr\n", __func__);
11790 }
11791
11792 switch (pixel_format)
11793 {
11794 case NI_PIX_FMT_YUV420P:
11795 case NI_PIX_FMT_NV12:
11796 p_upl_ctx->src_bit_depth = 8;
11797 p_upl_ctx->bit_depth_factor = 1;
11798 break;
11800 case NI_PIX_FMT_P010LE:
11801 p_upl_ctx->src_bit_depth = 10;
11802 p_upl_ctx->bit_depth_factor = 2;
11803 break;
11804 case NI_PIX_FMT_RGBA:
11805 case NI_PIX_FMT_BGRA:
11806 case NI_PIX_FMT_ARGB:
11807 case NI_PIX_FMT_ABGR:
11808 case NI_PIX_FMT_BGR0:
11809 case NI_PIX_FMT_BGRP:
11810 p_upl_ctx->src_bit_depth = 8;
11811 p_upl_ctx->bit_depth_factor = 4;
11812 break;
11813 default:
11814 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid pixfmt %d\n", __func__,
11815 pixel_format);
11817 }
11818
11820 p_upl_ctx->pixel_format = pixel_format;
11821 p_upl_ctx->active_video_width = width;
11822 p_upl_ctx->active_video_height = height;
11823 p_upl_ctx->isP2P = isP2P;
11824
11825 return NI_RETCODE_SUCCESS;
11826}
11827
11828/*!*****************************************************************************
11829 * \brief Read encoder stream header from the device
11830 *
11831 * \param[in] p_ctx Pointer to a caller allocated
11832 * ni_session_context_t struct from encoder
11833 * \param[in] p_data Pointer to a caller allocated ni_session_data_io_t
11834 * struct which contains a ni_packet_t data packet to
11835 * receive
11836 * \return On success
11837 * Total number of bytes read
11838 * On failure
11839 * NI_RETCODE_INVALID_PARAM
11840 * NI_RETCODE_ERROR_NVME_CMD_FAILED
11841 * NI_RETCODE_ERROR_INVALID_SESSION
11842*******************************************************************************/
11844 ni_session_data_io_t *p_data)
11845{
11846 int rx_size;
11847 int done = 0;
11848 int bytes_read = 0;
11849
11850 /* This function should be called once at the start of encoder read */
11851 if (p_ctx->pkt_num != 0)
11852 {
11853 ni_log2(p_ctx, NI_LOG_ERROR, "Error: stream header has already been read\n");
11855 }
11856
11857 while (!done)
11858 {
11859 rx_size = ni_device_session_read(p_ctx, p_data, NI_DEVICE_TYPE_ENCODER);
11860
11861 if (rx_size > (int)p_ctx->meta_size)
11862 {
11863 /* stream header has been read, return size */
11864 bytes_read += (rx_size - (int)p_ctx->meta_size);
11865
11866 p_ctx->pkt_num = 1;
11867 ni_log2(p_ctx, NI_LOG_DEBUG, "Got encoded stream header\n");
11868 done = 1;
11869 } else if (rx_size != 0)
11870 {
11871 ni_log2(p_ctx, NI_LOG_ERROR, "Error: received rx_size = %d\n", rx_size);
11872 bytes_read = -1;
11873 done = 1;
11874 } else
11875 {
11876 ni_log2(p_ctx, NI_LOG_DEBUG, "No data, keep reading..\n");
11877 continue;
11878 }
11879 }
11880
11881 return bytes_read;
11882}
11883
11884/*!*****************************************************************************
11885 * \brief Get the DMA buffer file descriptor from the P2P frame
11886 *
11887 * \param[in] p_frame pointer to a P2P frame
11888 *
11889 * \return On success
11890 * DMA buffer file descriptor
11891 * On failure
11892 * NI_RETCODE_INVALID_PARAM
11893*******************************************************************************/
11895{
11896 const niFrameSurface1_t *p_surface;
11897
11898 if (p_frame == NULL)
11899 {
11900 ni_log(NI_LOG_ERROR, "%s: NULL frame\n", __func__);
11902 }
11903
11904 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11905
11906 if (p_surface == NULL)
11907 {
11908 ni_log(NI_LOG_ERROR, "%s: Invalid hw frame\n", __func__);
11910 }
11911
11912 return p_surface->dma_buf_fd;
11913}
11914
11915/*!*****************************************************************************
11916 * \brief Send sequence change information to device
11917 *
11918 * \param[in] p_ctx Pointer to a caller allocated
11919 * ni_session_context_t struct
11920 * \param[in] width input width
11921 * \param[in] height input height
11922 * \param[in] bit_depth_factor 1 for 8-bit YUV, 2 for 10-bit YUV
11923 * \param[in] device_type device type (must be encoder)
11924 * \return On success
11925 * NI_RETCODE_SUCCESS
11926 * On failure
11927 * NI_RETCODE_INVALID_PARAM
11928 * NI_RETCODE_ERROR_MEM_ALOC
11929 * NI_RETCODE_ERROR_NVME_CMD_FAILED
11930 * NI_RETCODE_ERROR_INVALID_SESSION
11931 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
11932 ******************************************************************************/
11934 int width, int height, int bit_depth_factor, ni_device_type_t device_type)
11935{
11936 ni_resolution_t resolution;
11938 ni_xcoder_params_t *p_param = NULL;
11939
11940 // requires API version >= 54
11942 "54") < 0)
11943 {
11944 ni_log2(p_ctx, NI_LOG_ERROR, "Error: %s function not supported on device with FW API version < 5.4\n", __func__);
11946 }
11947
11948 /* This function should be called only if sequence change is detected */
11950 {
11951 ni_log2(p_ctx, NI_LOG_ERROR, "Error: stream header has already been read\n");
11953 }
11954
11955 resolution.width = width;
11956 resolution.height = height;
11957 resolution.bit_depth_factor = bit_depth_factor;
11958 resolution.luma_linesize = 0;
11959 resolution.chroma_linesize = 0;
11960 if (p_ctx->p_session_config)
11961 {
11963 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11964 p_enc = &p_param->cfg_enc_params;
11965 if (p_enc->spatial_layers > 1)
11966 {
11967 retval = NI_RETCODE_INVALID_PARAM;
11968 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Config sequence change not supported when spatialLayers > 1\n");
11969 return retval;
11970 }
11971 resolution.luma_linesize = p_param->luma_linesize;
11972 resolution.chroma_linesize = p_param->chroma_linesize;
11973 }
11974 else
11975 {
11977 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: invalid p_session_config\n");
11978 return retval;
11979 }
11980
11981 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: resolution change config - width %d height %d bit_depth_factor %d "
11982 "luma_linesize %d chroma_linesize %d\n", __func__,
11983 resolution.width, resolution.height, resolution.bit_depth_factor,
11984 resolution.luma_linesize, resolution.chroma_linesize);
11985
11986 switch (device_type)
11987 {
11989 {
11990 // config sequence change
11991 retval = ni_encoder_session_sequence_change(p_ctx, &resolution);
11992 break;
11993 }
11994 default:
11995 {
11996 retval = NI_RETCODE_INVALID_PARAM;
11997 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Config sequence change not supported for device type: %d", device_type);
11998 return retval;
11999 }
12000 }
12001 return retval;
12002}
12003
12005 ni_network_perf_metrics_t *p_metrics)
12006{
12007 return ni_ai_session_query_metrics(p_ctx, p_metrics);
12008}
12009
12010ni_retcode_t ni_query_fl_fw_versions(ni_device_handle_t device_handle,
12011 ni_device_info_t *p_dev_info)
12012{
12013 void *buffer;
12014 uint32_t size;
12015 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12016 ni_log_fl_fw_versions_t fl_fw_versions;
12017
12018 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_info))
12019 {
12020 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12021 __func__);
12023 }
12024
12026 "6h") < 0)
12027 {
12029 "ERROR: %s function not supported on device with FW API version < 6.h\n",
12030 __func__);
12032 }
12033
12034 buffer = NULL;
12036
12037 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12038 {
12039 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12041 }
12042
12043 memset(buffer, 0, size);
12044
12045 if (ni_nvme_send_read_cmd(device_handle,
12046 event_handle,
12047 buffer,
12048 size,
12050 {
12051 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12052 ni_aligned_free(buffer);
12054 }
12055
12056 memcpy(&fl_fw_versions, buffer, sizeof(ni_log_fl_fw_versions_t));
12057
12058 memcpy(p_dev_info->fl_ver_last_ran,
12059 &fl_fw_versions.last_ran_fl_version,
12061 memcpy(p_dev_info->fl_ver_nor_flash,
12062 &fl_fw_versions.nor_flash_fl_version,
12064 memcpy(p_dev_info->fw_rev_nor_flash,
12065 &fl_fw_versions.nor_flash_fw_revision,
12067
12068 ni_aligned_free(buffer);
12069 return NI_RETCODE_SUCCESS;
12070}
12071
12073 ni_load_query_t *p_load_query)
12074{
12075 void *buffer;
12076 uint32_t size;
12077
12078 ni_instance_mgr_general_status_t general_status;
12079
12080 if (!p_ctx)
12081 {
12082 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: p_ctx cannot be null\n");
12084 }
12085 if (!p_load_query)
12086 {
12087 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: p_load_query cannot be null\n");
12089 }
12090
12092 "6O") < 0)
12093 {
12094 ni_log2(p_ctx, NI_LOG_ERROR,
12095 "ERROR: %s function not supported on device with FW API version < 6.O\n",
12096 __func__);
12098 }
12099
12100 buffer = NULL;
12102
12103 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12104 {
12105 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12107 }
12108
12109 memset(buffer, 0, size);
12110
12112 p_ctx->event_handle,
12113 buffer,
12114 size,
12116 {
12117 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12118 ni_aligned_free(buffer);
12120 }
12121
12122 memcpy(&general_status, buffer, sizeof(ni_instance_mgr_general_status_t));
12123
12124 p_load_query->tp_fw_load = general_status.tp_fw_load;
12125 p_load_query->pcie_load = general_status.pcie_load;
12126 p_load_query->pcie_throughput = general_status.pcie_throughput;
12127 p_load_query->fw_load = general_status.fw_load;
12128 p_load_query->fw_share_mem_usage = general_status.fw_share_mem_usage;
12129
12130 ni_aligned_free(buffer);
12131 return NI_RETCODE_SUCCESS;
12132}
12133
12134ni_retcode_t ni_query_vf_ns_id(ni_device_handle_t device_handle,
12135 ni_device_vf_ns_id_t *p_dev_ns_vf,
12136 uint8_t fw_rev[])
12137{
12138 void *p_buffer = NULL;
12139 uint32_t size;
12140 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12141
12142 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_ns_vf))
12143 {
12144 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12145 __func__);
12147 }
12148
12150 "6m") < 0)
12151 {
12153 "ERROR: %s function not supported on device with FW API version < 6.m\n",
12154 __func__);
12156 }
12157
12159
12160 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12161 {
12162 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12164 }
12165
12166 memset(p_buffer, 0, size);
12167
12168 if (ni_nvme_send_read_cmd(device_handle,
12169 event_handle,
12170 p_buffer,
12171 size,
12172 QUERY_GET_NS_VF_R) < 0)
12173 {
12174 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12175 ni_aligned_free(p_buffer);
12177 }
12178
12179 ni_device_vf_ns_id_t *p_dev_ns_vf_data = (ni_device_vf_ns_id_t *)p_buffer;
12180 p_dev_ns_vf->vf_id = p_dev_ns_vf_data->vf_id;
12181 p_dev_ns_vf->ns_id = p_dev_ns_vf_data->ns_id;
12182 ni_log(NI_LOG_DEBUG, "%s(): NS/VF %u/%u\n", __func__, p_dev_ns_vf->ns_id, p_dev_ns_vf->vf_id);
12183 ni_aligned_free(p_buffer);
12184 return NI_RETCODE_SUCCESS;
12185}
12186
12187ni_retcode_t ni_query_temperature(ni_device_handle_t device_handle,
12188 ni_device_temp_t *p_dev_temp,
12189 uint8_t fw_rev[])
12190{
12191 void *p_buffer = NULL;
12192 uint32_t size;
12193 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12194
12195 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_temp))
12196 {
12197 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12198 __func__);
12200 }
12201
12203 "6rC") < 0)
12204 {
12206 "ERROR: %s function not supported on device with FW API version < 6rC\n",
12207 __func__);
12209 }
12210
12212
12213 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12214 {
12215 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12217 }
12218
12219 memset(p_buffer, 0, size);
12220
12221 if (ni_nvme_send_read_cmd(device_handle,
12222 event_handle,
12223 p_buffer,
12224 size,
12226 {
12227 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12228 ni_aligned_free(p_buffer);
12230 }
12231
12232 ni_device_temp_t *p_dev_temp_data = (ni_device_temp_t *)p_buffer;
12233 p_dev_temp->composite_temp = p_dev_temp_data->composite_temp;
12234 p_dev_temp->on_board_temp = p_dev_temp_data->on_board_temp;
12235 p_dev_temp->on_die_temp = p_dev_temp_data->on_die_temp;
12236 ni_log(NI_LOG_DEBUG, "%s(): current composite temperature %d on board temperature %d on die temperature %d\n",
12237 __func__, p_dev_temp->composite_temp, p_dev_temp->on_board_temp, p_dev_temp->on_die_temp);
12238 ni_aligned_free(p_buffer);
12239 return NI_RETCODE_SUCCESS;
12240}
12241
12242ni_retcode_t ni_query_extra_info(ni_device_handle_t device_handle,
12243 ni_device_extra_info_t *p_dev_extra_info,
12244 uint8_t fw_rev[])
12245{
12246 void *p_buffer = NULL;
12247 uint32_t size;
12248 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12249
12250 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_extra_info))
12251 {
12252 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12253 __func__);
12255 }
12256
12258 "6rC") < 0)
12259 {
12261 "ERROR: %s function not supported on device with FW API version < 6rC\n",
12262 __func__);
12264 }
12265
12267
12268 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12269 {
12270 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12272 }
12273
12274 memset(p_buffer, 0, size);
12275
12276 if (ni_nvme_send_read_cmd(device_handle,
12277 event_handle,
12278 p_buffer,
12279 size,
12281 {
12282 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12283 ni_aligned_free(p_buffer);
12285 }
12286
12287 ni_device_extra_info_t *p_dev_extra_info_data = (ni_device_extra_info_t *)p_buffer;
12288 p_dev_extra_info->composite_temp = p_dev_extra_info_data->composite_temp;
12289 p_dev_extra_info->on_board_temp = p_dev_extra_info_data->on_board_temp;
12290 p_dev_extra_info->on_die_temp = p_dev_extra_info_data->on_die_temp;
12291 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sN") >= 0)
12292 {
12293 p_dev_extra_info->fw_flavour = p_dev_extra_info_data->fw_flavour;
12294 }
12295 else
12296 {
12297 p_dev_extra_info->fw_flavour = (uint8_t)'-';
12298 }
12299 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rC") >= 0 &&
12300 ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rR") < 0)
12301 {
12302 p_dev_extra_info->power_consumption = NI_INVALID_POWER;
12303 }
12304 else
12305 {
12306 p_dev_extra_info->power_consumption = p_dev_extra_info_data->power_consumption;
12307 }
12308 //QUADPV-1210-Remove ADC current measurement decoding from FW
12309 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6s4") >= 0 &&
12310 ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sR") <= 0)
12311 {
12312 p_dev_extra_info->current_consumption = p_dev_extra_info_data->current_consumption;
12313 ni_device_capability_t device_capability = {0};
12314 if (ni_device_capability_query2(device_handle, &device_capability, false) != NI_RETCODE_SUCCESS)
12315 {
12316 ni_log(NI_LOG_ERROR, "ERROR: unable to query capability\n");
12318 }
12319 p_dev_extra_info->power_consumption = ni_decode_power_measurement(p_dev_extra_info->current_consumption, device_capability.serial_number);
12320 }
12321
12322 //Temperature overshoot detection
12323 {
12324 ni_device_capability_t device_capability_t = {0};
12325 int32_t temp_deg = p_dev_extra_info->composite_temp - 273;
12326 if (ni_device_capability_query2(device_handle, &device_capability_t, false) != NI_RETCODE_SUCCESS)
12327 {
12328 ni_log(NI_LOG_ERROR, "ERROR: unable to query capability\n");
12330 }
12331 if (p_dev_extra_info->composite_temp >= device_capability_t.critical_temp)
12332 {
12333 ni_log(NI_LOG_ERROR, "ERROR: CRITICAL TEMP HIT %ddegC on SN %s\n",temp_deg, device_capability_t.serial_number);
12334#if __linux__
12335 syslog(LOG_WARNING, "ERROR: CRITICAL TEMP %ddegC HIT on SN %s!!!\n",temp_deg,device_capability_t.serial_number);
12336#endif
12337 }
12338 else if (p_dev_extra_info->composite_temp >= device_capability_t.warning_temp)
12339 {
12340 ni_log(NI_LOG_ERROR, "ERROR: WARNING TEMP HIT %ddegC on SN %s\n",temp_deg, device_capability_t.serial_number);
12341#if __linux__
12342 syslog(LOG_WARNING, "ERROR: WARNING TEMP %ddegC HIT on SN %s!!!\n",temp_deg, device_capability_t.serial_number);
12343#endif
12344 }
12345 }
12346
12347 ni_log(NI_LOG_DEBUG, "%s(): current composite temperature %d on board temperature %d "
12348 "on die temperature %d power consumption %d current consumption %d\n",
12349 __func__, p_dev_extra_info->composite_temp, p_dev_extra_info->on_board_temp,
12350 p_dev_extra_info->on_die_temp, p_dev_extra_info->power_consumption, p_dev_extra_info->current_consumption);
12351 ni_aligned_free(p_buffer);
12352 return NI_RETCODE_SUCCESS;
12353}
12354
12355ni_retcode_t ni_query_qos_info(ni_device_handle_t device_handle,
12356 ni_qos_header_info_log_page_t *p_dev_qos_header,
12357 uint8_t fw_rev[])
12358{
12359 void *buffer;
12360 uint32_t size;
12361 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12362
12363 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_qos_header) || (!fw_rev))
12364 {
12365 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12366 __func__);
12368 }
12369
12371 "6t0") < 0)
12372 {
12374 "ERROR: %s function not supported on device with FW API version < 6t0\n",
12375 __func__);
12377 }
12378
12379 buffer = NULL;
12380 size = ((sizeof(ni_qos_header_info_log_page_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) /
12382
12383 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12384 {
12385 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12387 }
12388
12389 memset(buffer, 0, size);
12390
12391 if (ni_nvme_send_read_cmd(device_handle,
12392 event_handle,
12393 buffer,
12394 size,
12396 {
12397 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12398 ni_aligned_free(buffer);
12400 }
12401
12403 p_dev_qos_header->ui16QosState = (uint8_t)(qos_header_info->ui16QosState & 0xFF);
12404 p_dev_qos_header->ui16ActiveNamespaces = qos_header_info->ui16ActiveNamespaces;
12405 p_dev_qos_header->fTotalAllowance = qos_header_info->fTotalAllowance;
12406
12407 ni_aligned_free(buffer);
12408 return NI_RETCODE_SUCCESS;
12409}
12410
12411/*!*****************************************************************************
12412 * \brief Query QoS information for a specific namespace
12413 *
12414 * \param[in] device_handle Device handle for the target namespace
12415 * \param[out] p_qos_ns_info Pointer to namespace QoS info structure
12416 * \param[in] fw_rev[] Firmware version array
12417 *
12418 * \return On success
12419 * NI_RETCODE_SUCCESS
12420 * On failure
12421 * NI_RETCODE_INVALID_PARAM
12422 * NI_RETCODE_ERROR_NVME_CMD_FAILED
12423 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
12424 * NI_RETCODE_ERROR_MEM_ALOC
12425 ******************************************************************************/
12426ni_retcode_t ni_query_qos_namespace_info(ni_device_handle_t device_handle,
12428 uint8_t fw_rev[])
12429{
12430 void *buffer;
12431 uint32_t size;
12432 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12433
12434 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_qos_ns) || (!fw_rev))
12435 {
12436 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12437 __func__);
12439 }
12440
12442 "6t0") < 0)
12443 {
12445 "ERROR: %s function not supported on device with FW API version < 6t0\n",
12446 __func__);
12448 }
12449
12450 buffer = NULL;
12453
12454 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12455 {
12456 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12458 }
12459
12460 memset(buffer, 0, size);
12461
12462 if (ni_nvme_send_read_cmd(device_handle,
12463 event_handle,
12464 buffer,
12465 size,
12466 QUERY_GET_QOS_NS_INFO_R) < 0) // NSID comes from device handle
12467 {
12468 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12469 ni_aligned_free(buffer);
12471 }
12472
12474
12475 p_dev_qos_ns->ui8VirtualFunction = qos_ns_info->ui8VirtualFunction;
12476 p_dev_qos_ns->ui8NamespaceId = qos_ns_info->ui8NamespaceId;
12477 p_dev_qos_ns->fAllowance = qos_ns_info->fAllowance;
12478 p_dev_qos_ns->ui32BaseSliceTimeUs = qos_ns_info->ui32BaseSliceTimeUs;
12479 p_dev_qos_ns->ui32OPmaxUs = qos_ns_info->ui32OPmaxUs;
12480
12481 ni_log(NI_LOG_DEBUG, "%s(): NS %u VF %u Allowance %.2f%% SliceTime %u OPmax %u\n",
12482 __func__,
12483 p_dev_qos_ns->ui8NamespaceId,
12484 p_dev_qos_ns->ui8VirtualFunction,
12485 p_dev_qos_ns->fAllowance,
12486 p_dev_qos_ns->ui32BaseSliceTimeUs,
12487 p_dev_qos_ns->ui32OPmaxUs);
12488
12489 ni_aligned_free(buffer);
12490 return NI_RETCODE_SUCCESS;
12491}
12492
12493/*!*****************************************************************************
12494 * \brief Allocate log buffer if needed and retrieve firmware logs from device
12495 *
12496 * \param[in] p_ctx Pointer to a caller allocated
12497 * ni_session_context_t struct
12498 * \param[in] p_log_buffer Reference to pointer to a log buffer
12499 * If log buffer pointer is NULL, this function will allocate log buffer
12500 * NOTE caller is responsible for freeing log buffer after calling this function
12501 * \param[in] gen_log_file Indicating whether it is required to generate log files
12502 *
12503 *
12504 * \return on success
12505 * NI_RETCODE_SUCCESS
12506 *
12507 * on failure
12508 * NI_RETCODE_ERROR_MEM_ALOC
12509 * NI_RETCODE_INVALID_PARAM
12510*******************************************************************************/
12511ni_retcode_t ni_device_alloc_and_get_firmware_logs(ni_session_context_t *p_ctx, void** p_log_buffer, bool gen_log_file)
12512{
12514 bool is_ext_buf = true;
12515 if (*p_log_buffer == NULL)
12516 {
12517 if (ni_posix_memalign(p_log_buffer, sysconf(_SC_PAGESIZE), TOTAL_CPU_LOG_BUFFER_SIZE))
12518 {
12519 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate log buffer\n",
12520 NI_ERRNO, __func__);
12522 }
12523 is_ext_buf = false;
12524 }
12525
12526 if(*p_log_buffer != NULL){
12527 memset(*p_log_buffer, 0, TOTAL_CPU_LOG_BUFFER_SIZE);
12528 retval = ni_dump_log_all_cores(p_ctx, *p_log_buffer, gen_log_file); // dump FW logs
12529 if(!is_ext_buf)
12530 ni_aligned_free(*p_log_buffer);
12531 }else{
12533 }
12534
12535 return retval;
12536}
12537
12538/*!*****************************************************************************
12539 * \brief Set up hard coded demo ROI map
12540 *
12541 * \param[in] p_enc_ctx Pointer to a caller allocated
12542 *
12543 * \return on success
12544 * NI_RETCODE_SUCCESS
12545 *
12546 * on failure
12547 * NI_RETCODE_ERROR_MEM_ALOC
12548*******************************************************************************/
12550{
12551 ni_xcoder_params_t *p_param =
12552 (ni_xcoder_params_t *)(p_enc_ctx->p_session_config);
12553 int sumQp = 0;
12554 uint32_t ctu, i, j;
12555 // mode 1: Set QP for center 1/3 of picture to highest - lowest quality
12556 // the rest to lowest - highest quality;
12557 // mode non-1: reverse of mode 1
12558 int importanceLevelCentre = p_param->roi_demo_mode == 1 ? 40 : 10;
12559 int importanceLevelRest = p_param->roi_demo_mode == 1 ? 10 : 40;
12560 int linesize_aligned = p_param->source_width;
12561 int height_aligned = p_param->source_height;
12562 if (QUADRA)
12563 {
12564 uint32_t block_size, max_cu_size, customMapSize;
12565 uint32_t mbWidth;
12566 uint32_t mbHeight;
12567 uint32_t numMbs;
12568 uint32_t roiMapBlockUnitSize;
12569 uint32_t entryPerMb;
12570
12571 max_cu_size = p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264 ? 16: 64;
12572 // AV1 non-8x8-aligned resolution is implicitly cropped due to Quadra HW limitation
12573 if (NI_CODEC_FORMAT_AV1 == p_enc_ctx->codec_format)
12574 {
12575 linesize_aligned = (linesize_aligned / 8) * 8;
12576 height_aligned = (height_aligned / 8) * 8;
12577 }
12578
12579 // (ROI map version >= 1) each QP info takes 8-bit, represent 8 x 8
12580 // pixel block
12581 block_size =
12582 ((linesize_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) *
12583 ((height_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12584 (8 * 8);
12585
12586 // need to align to 64 bytes
12587 customMapSize = ((block_size + 63) & (~63));
12588 if (!p_enc_ctx->roi_map)
12589 {
12590 p_enc_ctx->roi_map =
12591 (ni_enc_quad_roi_custom_map *)calloc(1, customMapSize);
12592 }
12593 if (!p_enc_ctx->roi_map)
12594 {
12596 }
12597
12598 // for H.264, select ROI Map Block Unit Size: 16x16
12599 // for H.265, select ROI Map Block Unit Size: 64x64
12600 roiMapBlockUnitSize = p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264 ? 16 : 64;
12601
12602 mbWidth =
12603 ((linesize_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12604 roiMapBlockUnitSize;
12605 mbHeight =
12606 ((height_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12607 roiMapBlockUnitSize;
12608 numMbs = mbWidth * mbHeight;
12609
12610 // copy roi MBs QPs into custom map
12611 // number of qp info (8x8) per mb or ctb
12612 entryPerMb = (roiMapBlockUnitSize / 8) * (roiMapBlockUnitSize / 8);
12613
12614 for (i = 0; i < numMbs; i++)
12615 {
12616 bool bIsCenter = (i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3);
12617 for (j = 0; j < entryPerMb; j++)
12618 {
12619 /*
12620 g_quad_roi_map[i*4+j].field.skip_flag = 0; // don't force
12621 skip mode g_quad_roi_map[i*4+j].field.roiAbsQp_flag = 1; //
12622 absolute QP g_quad_roi_map[i*4+j].field.qp_info = bIsCenter
12623 ? importanceLevelCentre : importanceLevelRest;
12624 */
12625 p_enc_ctx->roi_map[i * entryPerMb + j].field.ipcm_flag =
12626 0; // don't force skip mode
12627 p_enc_ctx->roi_map[i * entryPerMb + j]
12628 .field.roiAbsQp_flag = 1; // absolute QP
12629 p_enc_ctx->roi_map[i * entryPerMb + j].field.qp_info =
12630 bIsCenter ? importanceLevelCentre : importanceLevelRest;
12631 }
12632 sumQp += p_enc_ctx->roi_map[i * entryPerMb].field.qp_info;
12633 }
12634 p_enc_ctx->roi_len = customMapSize;
12635 p_enc_ctx->roi_avg_qp =
12636 // NOLINTNEXTLINE(clang-analyzer-core.DivideZero)
12637 (sumQp + (numMbs >> 1)) / numMbs; // round off
12638 }
12639 else if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264)
12640 {
12641 // roi for H.264 is specified for 16x16 pixel macroblocks - 1 MB
12642 // is stored in each custom map entry
12643
12644 // number of MBs in each row
12645 uint32_t mbWidth = (linesize_aligned + 16 - 1) >> 4;
12646 // number of MBs in each column
12647 uint32_t mbHeight = (height_aligned + 16 - 1) >> 4;
12648 uint32_t numMbs = mbWidth * mbHeight;
12649 uint32_t customMapSize =
12650 sizeof(ni_enc_avc_roi_custom_map_t) * numMbs;
12651 p_enc_ctx->avc_roi_map =
12652 (ni_enc_avc_roi_custom_map_t *)calloc(1, customMapSize);
12653 if (!p_enc_ctx->avc_roi_map)
12654 {
12656 }
12657
12658 // copy roi MBs QPs into custom map
12659 for (i = 0; i < numMbs; i++)
12660 {
12661 if ((i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3))
12662 {
12663 p_enc_ctx->avc_roi_map[i].field.mb_qp = importanceLevelCentre;
12664 }
12665 else
12666 {
12667 p_enc_ctx->avc_roi_map[i].field.mb_qp = importanceLevelRest;
12668 }
12669 sumQp += p_enc_ctx->avc_roi_map[i].field.mb_qp;
12670 }
12671 p_enc_ctx->roi_len = customMapSize;
12672 p_enc_ctx->roi_avg_qp =
12673 (sumQp + (numMbs >> 1)) / numMbs; // round off
12674 }
12675 else if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265)
12676 {
12677 // roi for H.265 is specified for 32x32 pixel subCTU blocks - 4
12678 // subCTU QPs are stored in each custom CTU map entry
12679
12680 // number of CTUs in each row
12681 uint32_t ctuWidth = (linesize_aligned + 64 - 1) >> 6;
12682 // number of CTUs in each column
12683 uint32_t ctuHeight = (height_aligned + 64 - 1) >> 6;
12684 // number of sub CTUs in each row
12685 uint32_t subCtuWidth = ctuWidth * 2;
12686 // number of CTUs in each column
12687 uint32_t subCtuHeight = ctuHeight * 2;
12688 uint32_t numSubCtus = subCtuWidth * subCtuHeight;
12689
12690 p_enc_ctx->hevc_sub_ctu_roi_buf = (uint8_t *)malloc(numSubCtus);
12691 if (!p_enc_ctx->hevc_sub_ctu_roi_buf)
12692 {
12694 }
12695 for (i = 0; i < numSubCtus; i++)
12696 {
12697 if ((i % subCtuWidth > subCtuWidth / 3) &&
12698 (i % subCtuWidth < subCtuWidth * 2 / 3))
12699 {
12700 p_enc_ctx->hevc_sub_ctu_roi_buf[i] = importanceLevelCentre;
12701 }
12702 else
12703 {
12704 p_enc_ctx->hevc_sub_ctu_roi_buf[i] = importanceLevelRest;
12705 }
12706 }
12707 p_enc_ctx->hevc_roi_map = (ni_enc_hevc_roi_custom_map_t *)calloc(
12708 1, sizeof(ni_enc_hevc_roi_custom_map_t) * ctuWidth * ctuHeight);
12709 if (!p_enc_ctx->hevc_roi_map)
12710 {
12712 }
12713
12714 for (i = 0; i < ctuHeight; i++)
12715 {
12716 uint8_t *ptr = &p_enc_ctx->hevc_sub_ctu_roi_buf[subCtuWidth * i * 2];
12717 for (j = 0; j < ctuWidth; j++, ptr += 2)
12718 {
12719 ctu = (i * ctuWidth + j);
12720 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_0 = *ptr;
12721 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_1 = *(ptr + 1);
12722 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_2 =
12723 *(ptr + subCtuWidth);
12724 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_3 =
12725 *(ptr + subCtuWidth + 1);
12726 sumQp += (p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_0 +
12727 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_1 +
12728 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_2 +
12729 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_3);
12730 }
12731 }
12732 p_enc_ctx->roi_len =
12733 ctuWidth * ctuHeight * sizeof(ni_enc_hevc_roi_custom_map_t);
12734 p_enc_ctx->roi_avg_qp =
12735 (sumQp + (numSubCtus >> 1)) / numSubCtus; // round off.
12736 }
12737 return NI_RETCODE_SUCCESS;
12738}
12739
12741{
12742 // for encoder reconfiguration testing
12743 // reset encoder change data buffer for reconf parameters
12744 ni_retcode_t retval = 0;
12745 ni_xcoder_params_t *p_param =
12747 ni_aux_data_t *aux_data = NULL;
12750 {
12751 memset(p_enc_ctx->enc_change_params, 0, sizeof(ni_encoder_change_params_t));
12752 }
12753
12754 switch (p_param->reconf_demo_mode) {
12756 if (p_enc_ctx->frame_num ==
12757 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12758 {
12759 aux_data = ni_frame_new_aux_data(
12760 p_frame, NI_FRAME_AUX_DATA_BITRATE, sizeof(int32_t));
12761 if (!aux_data)
12762 {
12764 }
12765 *((int32_t *)aux_data->data) =
12766 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12767
12768 p_enc_ctx->reconfigCount++;
12769 if (p_param->cfg_enc_params.hrdEnable)
12770 {
12771 p_frame->force_key_frame = 1;
12772 p_frame->ni_pict_type = PIC_TYPE_IDR;
12773 }
12774 }
12775 break;
12776 // reconfig intraperiod param
12778 if (p_enc_ctx->frame_num ==
12779 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12780 {
12781 aux_data = ni_frame_new_aux_data(
12782 p_frame, NI_FRAME_AUX_DATA_INTRAPRD, sizeof(int32_t));
12783 if (!aux_data)
12784 {
12786 }
12787 int32_t intraprd = *((int32_t *)aux_data->data) =
12788 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12789 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12790 "xcoder_send_frame: frame #%lu reconf "
12791 "intraPeriod %d\n",
12792 p_enc_ctx->frame_num,
12793 intraprd);
12794 p_enc_ctx->reconfigCount++;
12795 }
12796 break;
12797 // reconfig VUI parameters
12799 if (p_enc_ctx->frame_num ==
12800 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12801 {
12802 aux_data = ni_frame_new_aux_data(p_frame,
12804 sizeof(ni_vui_hrd_t));
12805 if (!aux_data)
12806 {
12808 }
12809 ni_vui_hrd_t *vui = (ni_vui_hrd_t *)aux_data->data;
12810 vui->colorDescPresent =
12811 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12812 vui->colorPrimaries =
12813 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12814 vui->colorTrc =
12815 p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
12816 vui->colorSpace =
12817 p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
12818 vui->aspectRatioWidth =
12819 p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
12820 vui->aspectRatioHeight =
12821 p_param->reconf_hash[p_enc_ctx->reconfigCount][6];
12822 vui->videoFullRange =
12823 p_param->reconf_hash[p_enc_ctx->reconfigCount][7];
12824 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12825 "xcoder_send_frame: frame #%lu reconf "
12826 "vui colorDescPresent %d colorPrimaries %d "
12827 "colorTrc %d colorSpace %d aspectRatioWidth %d "
12828 "aspectRatioHeight %d videoFullRange %d\n",
12829 p_enc_ctx->frame_num, vui->colorDescPresent,
12830 vui->colorPrimaries, vui->colorTrc,
12831 vui->colorSpace, vui->aspectRatioWidth,
12833
12834 p_enc_ctx->reconfigCount++;
12835 }
12836 break;
12837 // long term ref
12839 // the reconf file data line format for this is:
12840 // <frame-number>:useCurSrcAsLongtermPic,useLongtermRef where
12841 // values will stay the same on every frame until changed.
12842 if (p_enc_ctx->frame_num ==
12843 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12844 {
12845 ni_long_term_ref_t *p_ltr;
12846 aux_data = ni_frame_new_aux_data(
12848 sizeof(ni_long_term_ref_t));
12849 if (!aux_data)
12850 {
12852 }
12853 p_ltr = (ni_long_term_ref_t *)aux_data->data;
12855 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12856 p_ltr->use_long_term_ref =
12857 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12858 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12859 "xcoder_send_frame: frame #%lu metadata "
12860 "use_cur_src_as_long_term_pic %d use_long_term_ref "
12861 "%d\n",
12862 p_enc_ctx->frame_num,
12864 p_ltr->use_long_term_ref);
12865 p_enc_ctx->reconfigCount++;
12866 }
12867 break;
12868 // reconfig min / max QP
12871 if (p_enc_ctx->frame_num ==
12872 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12873 aux_data = ni_frame_new_aux_data(
12875 if (!aux_data) {
12877 }
12878
12879 ni_rc_min_max_qp *qp_info = (ni_rc_min_max_qp *)aux_data->data;
12880 qp_info->minQpI = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12881 qp_info->maxQpI = p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12882 qp_info->maxDeltaQp = p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
12883 qp_info->minQpPB = p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
12884 qp_info->maxQpPB = p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
12885
12886 p_enc_ctx->reconfigCount++;
12887 }
12888 break;
12889#ifdef QUADRA
12890 // reconfig LTR interval
12892 if (p_enc_ctx->frame_num ==
12893 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12894 aux_data = ni_frame_new_aux_data(p_frame,
12896 sizeof(int32_t));
12897 if (!aux_data) {
12899 }
12900 *((int32_t *)aux_data->data) =
12901 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12902 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12903 "xcoder_send_frame: frame #%lu reconf "
12904 "ltrInterval %d\n",
12905 p_enc_ctx->frame_num,
12906 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12907
12908 p_enc_ctx->reconfigCount++;
12909 }
12910 break;
12911 // invalidate reference frames
12913 if (p_enc_ctx->frame_num ==
12914 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12915 aux_data = ni_frame_new_aux_data(
12917 sizeof(int32_t));
12918 if (!aux_data) {
12920 }
12921 *((int32_t *)aux_data->data) =
12922 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12923 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12924 "xcoder_send_frame: frame #%lu reconf "
12925 "invalidFrameNum %d\n",
12926 p_enc_ctx->frame_num,
12927 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12928
12929 p_enc_ctx->reconfigCount++;
12930 }
12931 break;
12932 // reconfig framerate
12934 if (p_enc_ctx->frame_num ==
12935 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12936 ni_framerate_t *framerate;
12937
12938 aux_data = ni_frame_new_aux_data(p_frame,
12940 sizeof(ni_framerate_t));
12941 if (!aux_data) {
12943 }
12944
12945 framerate = (ni_framerate_t *)aux_data->data;
12946 framerate->framerate_num =
12947 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12948 framerate->framerate_denom =
12949 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12950 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12951 "xcoder_send_frame: frame #%lu reconf "
12952 "framerate (%d/%d)\n",
12953 p_enc_ctx->frame_num, framerate->framerate_num,
12954 framerate->framerate_denom);
12955 p_enc_ctx->reconfigCount++;
12956 }
12957 break;
12959 if (p_enc_ctx->frame_num ==
12960 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12961 aux_data = ni_frame_new_aux_data(
12962 p_frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
12963 if (!aux_data) {
12965 }
12966 *((int32_t *)aux_data->data) =
12967 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12968 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12969 "xcoder_send_frame: frame #%lu reconf "
12970 "maxFrameSize %d\n",
12971 p_enc_ctx->frame_num,
12972 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12973
12974 p_enc_ctx->reconfigCount++;
12975 }
12976 break;
12978 if (p_enc_ctx->frame_num ==
12979 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12980 aux_data = ni_frame_new_aux_data(
12981 p_frame, NI_FRAME_AUX_DATA_CRF, sizeof(int32_t));
12982 if (!aux_data) {
12984 }
12985 *((int32_t *)aux_data->data) =
12986 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12987 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12988 "xcoder_send_frame: frame #%lu reconf "
12989 "crf %d\n",
12990 p_enc_ctx->frame_num,
12991 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
12992
12993 p_enc_ctx->reconfigCount++;
12994 }
12995 break;
12997 if (p_enc_ctx->frame_num ==
12998 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12999 aux_data = ni_frame_new_aux_data(
13000 p_frame, NI_FRAME_AUX_DATA_CRF_FLOAT, sizeof(float));
13001 if (!aux_data) {
13003 }
13004 float crf = (float)(p_param->reconf_hash[p_enc_ctx->reconfigCount][1] +
13005 (float)p_param->reconf_hash[p_enc_ctx->reconfigCount][2] / 100.0);
13006 *((float *)aux_data->data) = crf;
13007 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13008 "xcoder_send_frame: frame #%lu reconf "
13009 "crf %f\n",
13010 p_enc_ctx->frame_num, crf);
13011
13012 p_enc_ctx->reconfigCount++;
13013 }
13014 break;
13016 if (p_enc_ctx->frame_num ==
13017 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13018 int32_t vbvBufferSize = p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13019 int32_t vbvMaxRate = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13020 if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
13021 {
13022 ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid vbvBufferSize value %d\n",
13023 __func__, vbvBufferSize);
13025 }
13026 if (p_param->bitrate > 0 && vbvMaxRate > 0 && vbvMaxRate < p_param->bitrate) {
13027 ni_log2(p_enc_ctx, NI_LOG_ERROR, "vbvMaxRate %u cannot be smaller than bitrate %d\n",
13028 vbvMaxRate, p_param->bitrate);
13030 }
13031 if (vbvBufferSize == 0 && vbvMaxRate > 0) {
13032 ni_log2(p_enc_ctx, NI_LOG_INFO, "vbvMaxRate %d does not take effect when "
13033 "vbvBufferSize is 0, force vbvMaxRate to 0\n",
13034 vbvMaxRate);
13035 vbvMaxRate = 0;
13036 }
13037
13038 aux_data = ni_frame_new_aux_data(
13039 p_frame, NI_FRAME_AUX_DATA_VBV_MAX_RATE, sizeof(int32_t));
13040 if (!aux_data) {
13042 }
13043 *((int32_t *)aux_data->data) = vbvMaxRate;
13044 aux_data = ni_frame_new_aux_data(
13045 p_frame, NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE, sizeof(int32_t));
13046 if (!aux_data) {
13048 }
13049 *((int32_t *)aux_data->data) = vbvBufferSize;
13050 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13051 "xcoder_send_frame: frame #%lu reconfig vbvMaxRate %d vbvBufferSize "
13052 "%d by frame aux data\n",
13053 p_enc_ctx->frame_num, vbvMaxRate, vbvBufferSize);
13054
13055 p_enc_ctx->reconfigCount++;
13056 }
13057 break;
13059 if (p_enc_ctx->frame_num ==
13060 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13061 int maxFrameSizeRatio = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13062 if (maxFrameSizeRatio < 1) {
13063 ni_log2(p_enc_ctx, NI_LOG_ERROR, "maxFrameSizeRatio %d cannot < 1\n",
13064 maxFrameSizeRatio);
13066 }
13067 aux_data = ni_frame_new_aux_data(
13068 p_frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
13069 if (!aux_data) {
13071 }
13072
13073 int32_t bitrate, framerate_num, framerate_denom;
13074 uint32_t min_maxFrameSize, maxFrameSize;
13075 bitrate = (p_enc_ctx->target_bitrate > 0) ? p_enc_ctx->target_bitrate : p_param->bitrate;
13076
13077 if ((p_enc_ctx->framerate.framerate_num > 0) && (p_enc_ctx->framerate.framerate_denom > 0))
13078 {
13079 framerate_num = p_enc_ctx->framerate.framerate_num;
13080 framerate_denom = p_enc_ctx->framerate.framerate_denom;
13081 }
13082 else
13083 {
13084 framerate_num = (int32_t) p_param->fps_number;
13085 framerate_denom = (int32_t) p_param->fps_denominator;
13086 }
13087
13088 min_maxFrameSize = ((uint32_t)bitrate / framerate_num * framerate_denom) / 8;
13089 maxFrameSize = min_maxFrameSize * maxFrameSizeRatio > NI_MAX_FRAME_SIZE ?
13090 NI_MAX_FRAME_SIZE : min_maxFrameSize * maxFrameSizeRatio;
13091 *((int32_t *)aux_data->data) = maxFrameSize;
13092 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13093 "xcoder_send_frame: frame #%lu reconf "
13094 "maxFrameSizeRatio %d maxFrameSize %d\n",
13095 p_enc_ctx->frame_num, maxFrameSizeRatio, maxFrameSize);
13096
13097 p_enc_ctx->reconfigCount++;
13098 }
13099 break;
13101 if (p_enc_ctx->frame_num ==
13102 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13103 aux_data = ni_frame_new_aux_data(
13104 p_frame, NI_FRAME_AUX_DATA_SLICE_ARG, sizeof(int16_t));
13105 if (!aux_data) {
13107 }
13108 *((int16_t *)aux_data->data) =
13109 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13110 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13111 "xcoder_send_frame: frame #%lu reconf "
13112 "sliceArg %d\n",
13113 p_enc_ctx->frame_num,
13114 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13115
13116 p_enc_ctx->reconfigCount++;
13117 }
13118 break;
13119 // force IDR frame through API test code
13121 if (p_enc_ctx->frame_num ==
13122 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13123 ni_force_idr_frame_type(p_enc_ctx);
13124 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13125 "xcoder_send_frame: frame #%lu force IDR frame\n",
13126 p_enc_ctx->frame_num);
13127
13128 p_enc_ctx->reconfigCount++;
13129 }
13130 break;
13131 // reconfig bit rate through API test code
13133 if (p_enc_ctx->frame_num ==
13134 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13135 if ((retval = ni_reconfig_bitrate(
13136 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))){
13137 return retval;
13138 }
13139 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13140 "xcoder_send_frame: frame #%lu API reconfig BR %d\n",
13141 p_enc_ctx->frame_num,
13142 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13143
13144 p_enc_ctx->reconfigCount++;
13145 }
13146 break;
13148 if (p_enc_ctx->frame_num ==
13149 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13150 int32_t intraprd =
13151 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13152 if ((retval = ni_reconfig_intraprd(p_enc_ctx, intraprd))){
13153 return retval;
13154 }
13156 "xcoder_send_frame: frame #%lu API reconfig intraPeriod %d\n",
13157 p_enc_ctx->frame_num,
13158 intraprd);
13159
13160 p_enc_ctx->reconfigCount++;
13161 }
13162 break;
13164 if (p_enc_ctx->frame_num ==
13165 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13166 ni_vui_hrd_t vui;
13167 vui.colorDescPresent =
13168 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13169 vui.colorPrimaries =
13170 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13171 vui.colorTrc =
13172 p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13173 vui.colorSpace =
13174 p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13175 vui.aspectRatioWidth =
13176 p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13177 vui.aspectRatioHeight =
13178 p_param->reconf_hash[p_enc_ctx->reconfigCount][6];
13179 vui.videoFullRange =
13180 p_param->reconf_hash[p_enc_ctx->reconfigCount][7];
13181 if ((retval = ni_reconfig_vui(p_enc_ctx, &vui))){
13182 return retval;
13183 }
13184 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13185 "xcoder_send_frame: frame #%lu reconf "
13186 "vui colorDescPresent %d colorPrimaries %d "
13187 "colorTrc %d colorSpace %d aspectRatioWidth %d "
13188 "aspectRatioHeight %d videoFullRange %d\n",
13189 p_enc_ctx->frame_num, vui.colorDescPresent,
13190 vui.colorPrimaries, vui.colorTrc,
13193 p_enc_ctx->reconfigCount++;
13194 }
13195 break;
13197 if (p_enc_ctx->frame_num ==
13198 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13201 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13202 ltr.use_long_term_ref =
13203 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13204
13205 if ((retval = ni_set_ltr(p_enc_ctx, &ltr))) {
13206 return retval;
13207 }
13208 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13209 "xcoder_send_frame(): frame #%lu API set LTR\n",
13210 p_enc_ctx->frame_num);
13211 p_enc_ctx->reconfigCount++;
13212 }
13213 break;
13216 if (p_enc_ctx->frame_num ==
13217 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13218 ni_rc_min_max_qp qp_info;
13219 qp_info.minQpI = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13220 qp_info.maxQpI = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13221 qp_info.maxDeltaQp = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13222 qp_info.minQpPB = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13223 qp_info.maxQpPB = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13224 if ((retval = ni_reconfig_min_max_qp(p_enc_ctx, &qp_info))) {
13225 return retval;
13226 }
13227 ni_log2(p_enc_ctx, NI_LOG_DEBUG,
13228 "%s(): frame %d minQpI %d maxQpI %d maxDeltaQp %d minQpPB %d maxQpPB %d\n",
13229 __func__, p_enc_ctx->frame_num,
13230 qp_info.minQpI, qp_info.maxQpI, qp_info.maxDeltaQp, qp_info.minQpPB, qp_info.maxQpPB);
13231 p_enc_ctx->reconfigCount++;
13232 }
13233 break;
13235 if (p_enc_ctx->frame_num ==
13236 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13237 if ((retval = ni_set_ltr_interval(
13238 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13239 return retval;
13240 }
13241 ni_log2(p_enc_ctx,
13243 "xcoder_send_frame(): frame #%lu API set LTR interval %d\n",
13244 p_enc_ctx->frame_num,
13245 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13246 p_enc_ctx->reconfigCount++;
13247 }
13248 break;
13250 if (p_enc_ctx->frame_num ==
13251 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13252 if ((retval = ni_set_frame_ref_invalid(
13253 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13254 return retval;
13255 }
13256 ni_log2(p_enc_ctx,
13258 "xcoder_send_frame(): frame #%lu API set frame ref invalid "
13259 "%d\n",
13260 p_enc_ctx->frame_num,
13261 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13262 p_enc_ctx->reconfigCount++;
13263 }
13264 break;
13266 if (p_enc_ctx->frame_num ==
13267 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13268 ni_framerate_t framerate;
13269 framerate.framerate_num =
13270 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13271 framerate.framerate_denom =
13272 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13273 if ((retval = ni_reconfig_framerate(p_enc_ctx, &framerate))) {
13274 return retval;
13275 }
13276 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13277 "xcoder_send_frame: frame #%lu API reconfig framerate "
13278 "(%d/%d)\n",
13279 p_enc_ctx->frame_num,
13280 p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13281 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13282
13283 p_enc_ctx->reconfigCount++;
13284 }
13285 break;
13287 if (p_enc_ctx->frame_num ==
13288 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13289 if ((retval = ni_reconfig_max_frame_size(
13290 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13291 return retval;
13292 }
13293 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13294 "xcoder_send_frame: frame #%lu API reconfig maxFrameSize %d\n",
13295 p_enc_ctx->frame_num,
13296 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13297
13298 p_enc_ctx->reconfigCount++;
13299 }
13300 break;
13302 if (p_enc_ctx->frame_num ==
13303 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13304 if ((retval = ni_reconfig_crf(
13305 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13306 return retval;
13307 }
13308 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13309 "xcoder_send_frame: frame #%lu API reconfig crf %d\n",
13310 p_enc_ctx->frame_num,
13311 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13312
13313 p_enc_ctx->reconfigCount++;
13314 }
13315 break;
13317 if (p_enc_ctx->frame_num ==
13318 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13319 float crf = (float)(p_param->reconf_hash[p_enc_ctx->reconfigCount][1] +
13320 (float)p_param->reconf_hash[p_enc_ctx->reconfigCount][2] / 100.0);
13321 if ((retval = ni_reconfig_crf2(p_enc_ctx, crf))) {
13322 return retval;
13323 }
13324 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13325 "xcoder_send_frame: frame #%lu API reconfig crf %f\n",
13326 p_enc_ctx->frame_num, crf);
13327
13328 p_enc_ctx->reconfigCount++;
13329 }
13330 break;
13332 if (p_enc_ctx->frame_num ==
13333 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13334 if ((retval = ni_reconfig_vbv_value(
13335 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13336 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]))) {
13337 return retval;
13338 }
13339 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13340 "xcoder_send_frame: frame #%lu API reconfig vbvMaxRate %d vbvBufferSize %d\n",
13341 p_enc_ctx->frame_num,
13342 p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13343 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13344
13345 p_enc_ctx->reconfigCount++;
13346 }
13347 break;
13349 if (p_enc_ctx->frame_num ==
13350 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13351
13353 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13354 return retval;
13355 }
13356 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13357 "xcoder_send_frame: frame #%lu reconf maxFrameSizeRatio %d\n",
13358 p_enc_ctx->frame_num, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13359
13360 p_enc_ctx->reconfigCount++;
13361 }
13362 break;
13364 if (p_enc_ctx->frame_num ==
13365 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13366 if ((retval = ni_reconfig_slice_arg(
13367 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]))) {
13368 return retval;
13369 }
13370 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13371 "xcoder_send_frame: frame #%lu API reconfig sliceArg %d\n",
13372 p_enc_ctx->frame_num,
13373 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13374
13375 p_enc_ctx->reconfigCount++;
13376 }
13377 break;
13378#endif
13380 default:
13381 ;
13382 }
13383 return NI_RETCODE_SUCCESS;
13384}
13385
13389static int ni_tolower(int c)
13390{
13391 if (c >= 'A' && c <= 'Z')
13392 c ^= 0x20;
13393 return c;
13394}
13395
13396int ni_strcasecmp(const char *a, const char *b)
13397{
13398 uint8_t c1, c2;
13399 do
13400 {
13401 c1 = ni_tolower(*a++);
13402 c2 = ni_tolower(*b++);
13403 } while (c1 && c1 == c2);
13404 return c1 - c2;
13405}
13406
13408{
13409 ni_encoder_cfg_params_t *p_enc = &p_param->cfg_enc_params;
13412 p_gop->pic_param[0].rps[0].ref_pic = 1;
13414 p_gop->pic_param[0].rps[0].ref_pic_used = 1;
13416 p_gop->pic_param[0].rps[1].ref_pic = 1;
13418 p_gop->pic_param[0].rps[1].ref_pic_used = 1;
13420 p_gop->pic_param[0].rps[2].ref_pic = 1;
13422 p_gop->pic_param[0].rps[2].ref_pic_used = 1;
13424 p_gop->pic_param[0].rps[3].ref_pic = 1;
13426 p_gop->pic_param[0].rps[3].ref_pic_used = 1;
13428 p_gop->pic_param[1].rps[0].ref_pic = 1;
13430 p_gop->pic_param[1].rps[0].ref_pic_used = 1;
13432 p_gop->pic_param[1].rps[1].ref_pic = 1;
13434 p_gop->pic_param[1].rps[1].ref_pic_used = 1;
13436 p_gop->pic_param[1].rps[2].ref_pic = 1;
13438 p_gop->pic_param[1].rps[2].ref_pic_used = 1;
13440 p_gop->pic_param[1].rps[3].ref_pic = 1;
13442 p_gop->pic_param[1].rps[3].ref_pic_used = 1;
13444 p_gop->pic_param[2].rps[0].ref_pic = 1;
13446 p_gop->pic_param[2].rps[0].ref_pic_used = 1;
13448 p_gop->pic_param[2].rps[1].ref_pic = 1;
13450 p_gop->pic_param[2].rps[1].ref_pic_used = 1;
13452 p_gop->pic_param[2].rps[2].ref_pic = 1;
13454 p_gop->pic_param[2].rps[2].ref_pic_used = 1;
13456 p_gop->pic_param[2].rps[3].ref_pic = 1;
13458 p_gop->pic_param[2].rps[3].ref_pic_used = 1;
13460 p_gop->pic_param[3].rps[0].ref_pic = 1;
13462 p_gop->pic_param[3].rps[0].ref_pic_used = 1;
13464 p_gop->pic_param[3].rps[1].ref_pic = 1;
13466 p_gop->pic_param[3].rps[1].ref_pic_used = 1;
13468 p_gop->pic_param[3].rps[2].ref_pic = 1;
13470 p_gop->pic_param[3].rps[2].ref_pic_used = 1;
13472 p_gop->pic_param[3].rps[3].ref_pic = 1;
13474 p_gop->pic_param[3].rps[3].ref_pic_used = 1;
13476 p_gop->pic_param[4].rps[0].ref_pic = 1;
13478 p_gop->pic_param[4].rps[0].ref_pic_used = 1;
13480 p_gop->pic_param[4].rps[1].ref_pic = 1;
13482 p_gop->pic_param[4].rps[1].ref_pic_used = 1;
13484 p_gop->pic_param[4].rps[2].ref_pic = 1;
13486 p_gop->pic_param[4].rps[2].ref_pic_used = 1;
13488 p_gop->pic_param[4].rps[3].ref_pic = 1;
13490 p_gop->pic_param[4].rps[3].ref_pic_used = 1;
13492 p_gop->pic_param[5].rps[0].ref_pic = 1;
13494 p_gop->pic_param[5].rps[0].ref_pic_used = 1;
13496 p_gop->pic_param[5].rps[1].ref_pic = 1;
13498 p_gop->pic_param[5].rps[1].ref_pic_used = 1;
13500 p_gop->pic_param[5].rps[2].ref_pic = 1;
13502 p_gop->pic_param[5].rps[2].ref_pic_used = 1;
13504 p_gop->pic_param[5].rps[3].ref_pic = 1;
13506 p_gop->pic_param[5].rps[3].ref_pic_used = 1;
13508 p_gop->pic_param[6].rps[0].ref_pic = 1;
13510 p_gop->pic_param[6].rps[0].ref_pic_used = 1;
13512 p_gop->pic_param[6].rps[1].ref_pic = 1;
13514 p_gop->pic_param[6].rps[1].ref_pic_used = 1;
13516 p_gop->pic_param[6].rps[2].ref_pic = 1;
13518 p_gop->pic_param[6].rps[2].ref_pic_used = 1;
13520 p_gop->pic_param[6].rps[3].ref_pic = 1;
13522 p_gop->pic_param[6].rps[3].ref_pic_used = 1;
13524 p_gop->pic_param[7].rps[0].ref_pic = 1;
13526 p_gop->pic_param[7].rps[0].ref_pic_used = 1;
13528 p_gop->pic_param[7].rps[1].ref_pic = 1;
13530 p_gop->pic_param[7].rps[1].ref_pic_used = 1;
13532 p_gop->pic_param[7].rps[2].ref_pic = 1;
13534 p_gop->pic_param[7].rps[2].ref_pic_used = 1;
13536 p_gop->pic_param[7].rps[3].ref_pic = 1;
13538 p_gop->pic_param[7].rps[3].ref_pic_used = 1;
13539
13540}
13541
13543{
13544 ni_encoder_cfg_params_t *p_enc = &p_param->cfg_enc_params;
13546 int i, j;
13547 for (i=0; i<NI_MAX_GOP_NUM; i++)
13548 {
13549 for (j=0; j<NI_MAX_REF_PIC; j++)
13550 {
13551 if (p_gop->pic_param[i].rps[j].ref_pic == 1 &&
13552 p_gop->pic_param[i].rps[j].ref_pic_used != 1)
13553 {
13555 "g%drefPic%d specified without g%drefPic%dUsed specified!\n",
13556 i, j, i, j);
13557 return false;
13558 }
13559 }
13560 }
13561 // set custom_gop_params default.
13562 for (i=0; i<NI_MAX_GOP_NUM; i++)
13563 {
13564 for (j=0; j<NI_MAX_REF_PIC; j++)
13565 {
13566 p_gop->pic_param[i].rps[j].ref_pic = 0;
13567 p_gop->pic_param[i].rps[j].ref_pic_used = 0;
13568 }
13569 }
13570 return true;
13571}
13572
13573#ifndef DEPRECATION_AS_ERROR
13574/*!*****************************************************************************
13575 * \brief Initiate P2P transfer (P2P write) (deprecated)
13576 *
13577 * \param[in] pSession Pointer to source card destination
13578 * \param[in] source Pointer to source frame to transmit
13579 * \param[in] ui64DestAddr Destination address on target device
13580 * \param[in] ui32FrameSize Size of frame to transfer
13581 *
13582 * \return always returns
13583 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13584*******************************************************************************/
13586 niFrameSurface1_t *source,
13587 uint64_t ui64DestAddr,
13588 uint32_t ui32FrameSize)
13589{
13590 // avoid compiler warnings
13591 (void) pSession;
13592 (void) source;
13593 (void) ui64DestAddr;
13594 (void) ui32FrameSize;
13595
13597}
13598#endif
13599
13600#ifndef DEPRECATION_AS_ERROR
13601/*!*****************************************************************************
13602 * \brief Initiate P2P transfer (P2P write) (deprecated)
13603 *
13604 * \param[in] pSession Pointer to source card destination
13605 * \param[in] source Pointer to source frame to transmit
13606 * \param[in] ui64DestAddr Destination address on target device
13607 * \param[in] ui32FrameSize Size of frame to transfer
13608 *
13609 * \return always returns
13610 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13611*******************************************************************************/
13613 niFrameSurface1_t *source,
13614 uint64_t ui64DestAddr, uint32_t ui32FrameSize)
13615{
13616 // avoid compiler warnings
13617 (void) pSession;
13618 (void) source;
13619 (void) ui64DestAddr;
13620 (void) ui32FrameSize;
13621
13623}
13624#endif
13625
13626/*!*****************************************************************************
13627 * \brief Initiate P2P transfer with sgl list (P2P write)
13628 *
13629 * \param[in] pSession Pointer to source card session
13630 * \param[in] source Pointer to source P2P frame
13631 * \param[in] dmaAddrs Destination DMA address on target device
13632 *
13633 * \return on success
13634 * NI_RETCODE_SUCCESS
13635 * on failure
13636 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13637 * NI_RETCODE_INVALID_PARAM
13638 * NI_RETCODE_ERROR_INVALID_SESSION
13639 * NI_RETCODE_ERROR_MEM_ALOC
13640 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13641*******************************************************************************/
13643 ni_frame_t *pSrcFrame,
13644 const ni_p2p_sgl_t *dmaAddrs)
13645{
13647
13648 if ((pSession == NULL) || (dmaAddrs == NULL) || (pSrcFrame == NULL))
13649 {
13651 }
13652
13653 /* Firmware compatibility check */
13654 if (ni_cmp_fw_api_ver((char *) &pSession->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sX") < 0)
13655 {
13656 ni_log2(pSession, NI_LOG_ERROR,
13657 "%s: FW doesn't support this operation\n", __func__);
13659 }
13660
13661 retval = ni_send_to_target_v2(pSession, pSrcFrame, dmaAddrs);
13662 if (retval < 0)
13663 {
13664 ni_log2(pSession, NI_LOG_ERROR, "%s(): Can't DMA to destination (%d)\n", __func__, retval);
13665 }
13666
13667 return retval;
13668}
13669
13670/*!*****************************************************************************
13671 * \brief Initiate a P2P transfer (P2P read)
13672 *
13673 * \param[in] pSession Pointer to destination upload session
13674 * \param[in] dmaAddrs Pointer to source DMA addresses
13675 * \param[in] pDstFrame Pointer to destination P2P frame
13676 *
13677 * \return on success
13678 * NI_RETCODE_SUCCESS
13679 * on failure
13680 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13681 * NI_RETCODE_INVALID_PARAM
13682 * NI_RETCODE_ERROR_INVALID_SESSION
13683 * NI_RETCODE_ERROR_MEM_ALOC
13684 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13685*******************************************************************************/
13687 const ni_p2p_sgl_t *dmaAddrs,
13688 ni_frame_t *pDstFrame)
13689{
13691
13692 if ((pSession == NULL) || (dmaAddrs == NULL) || (pDstFrame == NULL))
13693 {
13695 }
13696
13697 /* Firmware compatibility check */
13698 if (ni_cmp_fw_api_ver((char *) &pSession->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6re") < 0)
13699 {
13700 ni_log2(pSession, NI_LOG_ERROR,
13701 "%s: FW doesn't support this operation\n", __func__);
13703 }
13704
13705 retval = ni_recv_from_target(pSession, dmaAddrs, pDstFrame);
13706
13707 if (retval < 0)
13708 {
13709 ni_log2(pSession, NI_LOG_ERROR,
13710 "%s(): Can't DMA from source (%d)\n", __func__, retval);
13711 retval = NI_RETCODE_INVALID_PARAM;
13712 }
13713
13714 return retval;
13715}
13716
13717/*!*****************************************************************************
13718 * \brief Send a restart command after flush command
13719 * Only support Encoder now
13720 *
13721 * \param[in] p_ctx Pointer to a caller allocated
13722 * ni_session_context_t struct
13723 * \param[in] width width, in pixels
13724 * \param[in] height height, in pixels
13725 * \param[in] device_type NI_DEVICE_TYPE_ENCODER
13726 * \return On success
13727 * NI_RETCODE_SUCCESS
13728 * On failure
13729 * NI_RETCODE_INVALID_PARAM
13730 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13731 * NI_RETCODE_ERROR_INVALID_SESSION
13732 ******************************************************************************/
13734 int video_width,
13735 int video_height,
13736 ni_device_type_t device_type)
13737{
13738 ni_retcode_t retval = 0;
13739 ni_resolution_t resolution;
13740 ni_xcoder_params_t *p_param = NULL;
13741
13742 if (!p_ctx)
13743 {
13744 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
13745 __func__);
13747 }
13748
13749 switch (device_type)
13750 {
13752 {
13753 // requires API version >= 54
13755 "54") < 0)
13756 {
13757 ni_log2(p_ctx, NI_LOG_ERROR, "Error: %s function not supported on device with FW API version < 5.4\n", __func__);
13759 }
13760
13761 /* This function should be called only if flushing is detected */
13763 {
13764 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() wrong state %d\n",
13765 __func__, p_ctx->session_run_state);
13767 }
13768
13769 if (video_width < NI_MIN_WIDTH || video_width > NI_MAX_WIDTH ||
13770 video_height < NI_MIN_HEIGHT || video_height > NI_MAX_HEIGHT)
13771 {
13772 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() invalid width %d or height %d\n",
13773 __func__, video_width, video_height);
13775 }
13776 resolution.width = video_width;
13777 resolution.height = video_height;
13778 resolution.bit_depth_factor = p_ctx->bit_depth_factor;
13779 resolution.luma_linesize = 0;
13780 resolution.chroma_linesize = 0;
13781 if (p_ctx->p_session_config)
13782 {
13783 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
13784 resolution.luma_linesize = p_param->luma_linesize;
13785 resolution.chroma_linesize = p_param->chroma_linesize;
13786 }
13788
13789 // reconfig the encoder session
13790 retval = ni_encoder_session_sequence_change(p_ctx, &resolution);
13791 if (NI_RETCODE_SUCCESS != retval)
13792 {
13793 ni_log(NI_LOG_ERROR, "Failed to reconfig config the encoder session (status = %d)\n", retval);
13795 return retval;
13796 }
13797
13798 // update session context
13799 p_ctx->ready_to_close = 0;
13800 p_ctx->frame_num = 0;
13801 p_ctx->pkt_num = 0;
13803 break;
13804 }
13805 default:
13806 {
13807 retval = NI_RETCODE_INVALID_PARAM;
13808 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unsupported device type: %d",
13809 __func__, device_type);
13810 break;
13811 }
13812 }
13813 return retval;
13814}
13815
13816/*!******************************************************************************
13817* \brief Send a p_config command to reconfigure decoding ppu params.
13818*
13819* \param ni_session_context_t p_session_ctx - xcoder Context
13820* \param ni_xcoder_params_t p_param - xcoder Params
13821* \param ni_ppu_config_t p_ppu_config - Struct ni_ppu_config
13822*
13823* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
13824*******************************************************************************/
13826 ni_xcoder_params_t *p_param, ni_ppu_config_t *p_ppu_config)
13827{
13828 int ret = 0, i = 0;
13829 if (!p_session_ctx || !p_param || !p_ppu_config)
13830 {
13832 return ret;
13833 }
13834 if (p_session_ctx->ppu_reconfig_pkt_pos != 0)
13835 {
13836 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: Warning ignore ppu reconfig before last config done!\n", __func__);
13837 return 0;
13838 }
13839
13840 // check fw revision
13842 (char*) &p_session_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
13843 "6sF") < 0)
13844 {
13845 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: not supported on device with FW API version < 6sF\n", __func__);
13847 }
13848
13849 if (NI_CODEC_FORMAT_H264 != p_session_ctx->codec_format &&
13850 NI_CODEC_FORMAT_H265 != p_session_ctx->codec_format)
13851 {
13852 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): only supported for h264 and h265 decoder\n", __func__);
13854 }
13855
13856 ni_decoder_input_params_t *p_dec_input_param = &(p_param->dec_input_params);
13857 if (p_dec_input_param->hwframes != 1)
13858 {
13859 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): only supported for hw mode\n", __func__);
13861 }
13862 if (!p_dec_input_param->disable_adaptive_buffers)
13863 {
13864 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): not supported when disable_adaptive_buffers is disabled\n", __func__);
13866 }
13867 if (p_dec_input_param->mcmode)
13868 {
13869 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): not supported when MulticoreJointMode is enabled\n", __func__);
13871 }
13872 if (p_dec_input_param->enable_out1 == 0 &&
13873 p_ppu_config->ppu_set_enable & (0x01 << 1))
13874 {
13875 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Error reconfig ppu1 while ppu1 is not enabled\n", __func__);
13877 }
13878 if (p_dec_input_param->enable_out2 == 0 &&
13879 p_ppu_config->ppu_set_enable & (0x01 << 2))
13880 {
13881 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Error reconfig ppu2 while ppu2 is not enabled\n", __func__);
13883 }
13884 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
13885 {
13886 if (p_ppu_config->ppu_set_enable & (0x01 << i))
13887 {
13888 if (p_ppu_config->ppu_w[i] > NI_MAX_RESOLUTION_WIDTH ||
13889 p_ppu_config->ppu_h[i] > NI_MAX_RESOLUTION_HEIGHT ||
13890 p_ppu_config->ppu_w[i] < NI_MIN_RESOLUTION_WIDTH_SCALER ||
13891 p_ppu_config->ppu_h[i] < NI_MIN_RESOLUTION_WIDTH_SCALER)
13892 {
13893 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu[%d] width x height %ux%u "
13894 "out of range\n", __func__, i, p_ppu_config->ppu_w[i], p_ppu_config->ppu_h[i]);
13896 return ret;
13897 }
13898 if ((p_ppu_config->ppu_w[i] & 1) || (p_ppu_config->ppu_h[i] & 1))
13899 {
13900 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu[%d] wxh %dx%d not align to 2!\n",
13901 __func__, i, p_ppu_config->ppu_w[i], p_ppu_config->ppu_h[i]);
13903 return ret;
13904 }
13905 }
13906 }
13908 p_session_ctx, p_ppu_config, sizeof(ni_ppu_config_t));
13909 if (ret == NI_RETCODE_SUCCESS)
13910 {
13911 p_session_ctx->ppu_reconfig_pkt_pos = p_session_ctx->pkt_num;
13912 }
13913 return ret;
13914}
#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:596
@ NI_SCALER_OPCODE_WATERMARK
Definition ni_defs.h:601
#define NI_MEM_PAGE_ALIGNMENT
Definition ni_defs.h:263
#define TOTAL_CPU_LOG_BUFFER_SIZE
Definition ni_defs.h:376
#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:445
@ NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
Definition ni_defs.h:526
@ NI_RETCODE_PARAM_WARNING_DEPRECATED
Definition ni_defs.h:535
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_BIG
Definition ni_defs.h:517
@ NI_RETCODE_PARAM_ERROR_ZERO
Definition ni_defs.h:511
@ NI_RETCODE_FAILURE
Definition ni_defs.h:447
@ NI_RETCODE_ERROR_PERMISSION_DENIED
Definition ni_defs.h:542
@ NI_RETCODE_ERROR_INVALID_SESSION
Definition ni_defs.h:452
@ NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
Definition ni_defs.h:540
@ NI_RETCODE_ERROR_GET_DEVICE_POOL
Definition ni_defs.h:525
@ NI_RETCODE_ERROR_UNLOCK_DEVICE
Definition ni_defs.h:528
@ NI_RETCODE_PARAM_INVALID_NAME
Definition ni_defs.h:455
@ NI_RETCODE_PARAM_ERROR_AREA_TOO_BIG
Definition ni_defs.h:521
@ NI_RETCODE_SUCCESS
Definition ni_defs.h:446
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_SMALL
Definition ni_defs.h:519
@ NI_RETCODE_ERROR_INVALID_HANDLE
Definition ni_defs.h:530
@ NI_RETCODE_PARAM_ERROR_TOO_BIG
Definition ni_defs.h:508
@ NI_RETCODE_PARAM_INVALID_VALUE
Definition ni_defs.h:456
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_BIG
Definition ni_defs.h:513
@ NI_RETCODE_ERROR_NVME_CMD_FAILED
Definition ni_defs.h:451
@ NI_RETCODE_ERROR_MEM_ALOC
Definition ni_defs.h:450
@ NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
Definition ni_defs.h:541
@ NI_RETCODE_PARAM_ERROR_OOR
Definition ni_defs.h:512
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_SMALL
Definition ni_defs.h:515
@ NI_RETCODE_INVALID_PARAM
Definition ni_defs.h:448
@ NI_RETCODE_PARAM_ERROR_TOO_SMALL
Definition ni_defs.h:509
@ NI_RETCODE_ERROR_OPEN_DEVICE
Definition ni_defs.h:529
#define NI_MAX_PPU_PARAM_EXPR_CHAR
Definition ni_defs.h:259
#define IS_XCODER_DEVICE_TYPE(t)
Definition ni_defs.h:429
#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)
#define OPT6(STR1, STR2, STR3, STR4, STR5, STR6)
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_p2p_send_v2(ni_session_context_t *pSession, ni_frame_t *pSrcFrame, const ni_p2p_sgl_t *dmaAddrs)
Initiate P2P transfer with sgl list (P2P write)
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_device_config_qos_allowance(ni_device_handle_t device_handle, ni_device_handle_t device_handle_t, uint32_t allowance)
Set QoS allowance for a specific namespace.
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_DEPRECATED 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) (deprecated)
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_query_qos_info(ni_device_handle_t device_handle, ni_qos_header_info_log_page_t *p_dev_qos_header, uint8_t fw_rev[])
Query QoS information for the device.
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_query_qos_namespace_info(ni_device_handle_t device_handle, ni_qos_namespace_info_log_page_t *p_dev_qos_ns, uint8_t fw_rev[])
Query QoS information for a specific namespace.
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_DEC_PARAM_SCALE_2_W
#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_DEC_PARAM_SCALE_0_H
#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_DEC_PARAM_SCALE_1_H
#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_ALLOW_CONFIG_CODE
@ QOS_OP_CONFIG_CODE
@ QOS_ALLOW_CONFIG_REC_ALLOW_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_DEC_PARAM_SCALE_1_W
#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_QP_SCALE_ENABLE
#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_DEC_PARAM_SCALE_0_W
#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_DEC_PARAM_SCALE_2_H
#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
#define NI_ENC_PARAM_GET_BITSTREAM_FEATURES
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_send_to_target_v2(ni_session_context_t *p_ctx, ni_frame_t *pSrcFrame, const ni_p2p_sgl_t *dmaAddrs)
Generates and writes a nvme command with sgl list.
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_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:793
#define QUERY_GET_EXTTRA_INFO_R
Definition ni_nvme.h:802
#define QUERY_GET_QOS_INFO_R
Definition ni_nvme.h:804
#define CONFIG_INSTANCE_SetScalerDrawBoxPara_W(sid, instance)
Definition ni_nvme.h:832
#define QUERY_GET_NS_VF_R
Definition ni_nvme.h:798
#define QUERY_GET_TEMPERATURE_R
Definition ni_nvme.h:800
#define IDENTIFY_DEVICE_R
Definition ni_nvme.h:690
#define QUERY_GET_VERSIONS_R
Definition ni_nvme.h:795
#define NI_DATA_BUFFER_LEN
Definition ni_nvme.h:626
#define NI_NVME_IDENTITY_CMD_DATA_SZ
Definition ni_nvme.h:38
#define CONFIG_INSTANCE_SetScalerWatermarkPara_W(sid, instance)
Definition ni_nvme.h:838
#define QUERY_GET_QOS_NS_INFO_R
Definition ni_nvme.h:806
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_qos_header_info_log_page ni_qos_header_info_log_page_t
struct _ni_qos_namespace_info_log_page ni_qos_namespace_info_log_page_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