libxcoder 5.8.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 // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
31#if __linux__
32#include <linux/types.h>
33#endif
34#include <unistd.h>
35#include <sys/ioctl.h>
36#include <sys/mman.h>
37#include <stddef.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
70#ifdef _WIN32
71#define strcasecmp _stricmp
72#else
73#include <strings.h>
74#endif
75
92#if __linux__ || __APPLE__
93static struct stat g_nvme_stat = { 0 };
94
95static int close_fd_zero_atexit = 0;
96
97static void close_fd_zero(void)
98{
99 (void)close(0);
100}
101
102#endif
103
104/*!*****************************************************************************
105 * \brief Allocate and initialize a new ni_session_context_t struct
106 *
107 *
108 * \return On success returns a valid pointer to newly allocated context
109 * On failure returns NULL
110 ******************************************************************************/
112{
113 ni_session_context_t *p_ctx = NULL;
114
115 p_ctx = malloc(sizeof(ni_session_context_t));
116 if (!p_ctx)
117 {
119 "ERROR: %s() Failed to allocate memory for session context\n",
120 __func__);
121 } else
122 {
123 memset(p_ctx, 0, sizeof(ni_session_context_t));
124
126 {
127 ni_log(NI_LOG_ERROR, "ERROR: %s() Failed to init session context\n",
128 __func__);
130 return NULL;
131 }
132 }
133 return p_ctx;
134}
135
136/*!*****************************************************************************
137 * \brief Free previously allocated session context
138 *
139 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
140 * struct
141 *
142 ******************************************************************************/
144{
145 if (p_ctx)
146 {
148#ifdef MEASURE_LATENCY
149 if (p_ctx->frame_time_q)
150 {
152 }
153#endif
154 free(p_ctx);
155 }
156}
157
158/*!*****************************************************************************
159 * \brief Initialize already allocated session context to a known state
160 *
161 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
162 * struct
163 * \return On success
164 * NI_RETCODE_SUCCESS
165 * On failure
166 * NI_RETCODE_INVALID_PARAM
167 * NI_RETCODE_FAILURE
168 ******************************************************************************/
170{
171 int bitrate = 0;
172 int framerate_num = 0;
173 int framerate_denom = 0;
174
175 if (!p_ctx)
176 {
178 }
179
181 {
182 // session context will reset so save the last values for sequence change
183 if (p_ctx->last_bitrate < NI_MIN_BITRATE)
184 bitrate = NI_MIN_BITRATE;
185 else if (p_ctx->last_bitrate > NI_MAX_BITRATE)
186 bitrate = NI_MAX_BITRATE;
187 else
188 bitrate = p_ctx->last_bitrate;
189 framerate_num = p_ctx->last_framerate.framerate_num;
190 framerate_denom = p_ctx->last_framerate.framerate_denom;
191 }
192
193 memset(p_ctx, 0, sizeof(ni_session_context_t));
194
195 p_ctx->last_bitrate = bitrate;
196 p_ctx->last_framerate.framerate_num = framerate_num;
197 p_ctx->last_framerate.framerate_denom = framerate_denom;
198
199 // Xcoder thread mutex init
200 if (ni_pthread_mutex_init(&p_ctx->mutex))
201 {
202 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): init xcoder_mutex fail, return\n",
203 __func__);
204 return NI_RETCODE_FAILURE;
205 }
206 p_ctx->pext_mutex = &p_ctx->mutex; //used exclusively for hwdl
207
208 // low delay send/recv sync init
210 {
211 ni_log2(p_ctx, NI_LOG_ERROR,
212 "ERROR %s(): init xcoder_low_delay_sync_mutex fail return\n",
213 __func__);
214 return NI_RETCODE_FAILURE;
215 }
216 if (ni_pthread_cond_init(&p_ctx->low_delay_sync_cond, NULL))
217 {
218 ni_log2(p_ctx, NI_LOG_ERROR,
219 "ERROR %s(): init xcoder_low_delay_sync_cond fail return\n",
220 __func__);
221 return NI_RETCODE_FAILURE;
222 }
223
224 p_ctx->mutex_initialized = true;
225
226 // Init the max IO size to be invalid
230 p_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
231 p_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
232 p_ctx->hw_id = NI_INVALID_HWID;
233 p_ctx->event_handle = NI_INVALID_EVENT_HANDLE;
234 p_ctx->thread_event_handle = NI_INVALID_EVENT_HANDLE;
236 p_ctx->keep_alive_thread = (ni_pthread_t){0};
238 p_ctx->decoder_low_delay = 0;
239 p_ctx->enable_low_delay_check = 0;
240 p_ctx->low_delay_sync_flag = 0;
241 p_ctx->async_mode = 0;
243 p_ctx->buffered_frame_index = 0;
244 p_ctx->ppu_reconfig_pkt_pos = 0;
245 p_ctx->headers_length = 0;
246 // by default, select the least model load card
249#ifdef MY_SAVE
250 p_ctx->debug_write_ptr = NULL;
251 p_ctx->debug_write_index_ptr = NULL;
252 p_ctx->debug_write_sent_size = 0;
253#endif
254
255#ifdef MEASURE_LATENCY
256 p_ctx->frame_time_q = (void *)ni_lat_meas_q_create(2000);
257#endif
258
259 return NI_RETCODE_SUCCESS;
260}
261
262/*!*****************************************************************************
263 * \brief Clear already allocated session context
264 *
265 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
266 *
267 *
268 ******************************************************************************/
279
280/*!*****************************************************************************
281 * \brief Create event and return event handle if successful (Windows only)
282 *
283 * \return On success returns a event handle
284 * On failure returns NI_INVALID_EVENT_HANDLE
285 ******************************************************************************/
286ni_event_handle_t ni_create_event(void)
287{
288#ifdef _WIN32
289 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
290
291 // Input-0 determines whether the returned handle can be inherited by the child process.If lpEventAttributes is NULL, this handle cannot be inherited.
292 // 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.
293 // Input-2 specifies the initial state of the event object.If TRUE, the initial state is signaled;Otherwise, no signal state.
294 // Input-3 If the lpName is NULL, a nameless event object is created.。
295 event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
296 if (event_handle == NULL)
297 {
298 ni_log(NI_LOG_ERROR, "ERROR %d: %s() create event failed\n",
299 NI_ERRNO, __func__);
300 return NI_INVALID_EVENT_HANDLE;
301 }
302 return event_handle;
303#else
304 return NI_INVALID_EVENT_HANDLE;
305#endif
306}
307
308/*!*****************************************************************************
309 * \brief Close event and release resources (Windows only)
310 *
311 * \return NONE
312 *
313 ******************************************************************************/
314void ni_close_event(ni_event_handle_t event_handle)
315{
316 if ( NI_INVALID_DEVICE_HANDLE == event_handle )
317 {
318 ni_log(NI_LOG_DEBUG, "Warning %s: null parameter passed %x\n", __func__,
319 event_handle);
320 return;
321 }
322
323 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
324
325#ifdef _WIN32
326 BOOL retval;
327 ni_log(NI_LOG_DEBUG, "%s(): closing %p\n", __func__, event_handle);
328
329 retval = CloseHandle(event_handle);
330 if (FALSE == retval)
331 {
332 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): closing event_handle %p failed\n",
333 NI_ERRNO, __func__, event_handle);
334 }
335 else
336 {
337 ni_log(NI_LOG_DEBUG, "%s(): device %p closed successfuly\n", __func__,
338 event_handle);
339 }
340#else
341 int err = 0;
342 ni_log(NI_LOG_DEBUG, "%s(): closing %d\n", __func__, event_handle);
343 err = close(event_handle);
344 if (err)
345 {
346 char error_message[100] = {'\0'};
347 char unknown_error_message[20] = {'\0'};
348 ni_sprintf(error_message, 100, "ERROR: %s(): ", __func__);
349 switch (err)
350 {
351 case EBADF:
352 ni_strcat(error_message, 100, "EBADF\n");
353 break;
354 case EINTR:
355 ni_strcat(error_message, 100, "EINTR\n");
356 break;
357 case EIO:
358 ni_strcat(error_message, 100, "EIO\n");
359 break;
360 default:
361 ni_sprintf(unknown_error_message, 20, "Unknown error %d\n", err);
362 ni_strcat(error_message, 100, unknown_error_message);
363 }
364 ni_log(NI_LOG_ERROR, "%s\n", error_message);
365 }
366#endif
367 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
368}
369
370#ifndef DEPRECATION_AS_ERROR
371/*!*****************************************************************************
372 * \brief Open device and return device device_handle if successful
373 *
374 * \param[in] p_dev Device name represented as c string. ex: "/dev/nvme0"
375 * \param[out] p_max_io_size_out Maximum IO Transfer size supported, could be
376 * NULL
377 *
378 * \return On success returns a device device_handle
379 * On failure returns NI_INVALID_DEVICE_HANDLE
380 ******************************************************************************/
381NI_DEPRECATED ni_device_handle_t ni_device_open(const char * p_dev, uint32_t * p_max_io_size_out)
382{
383#ifdef _WIN32
384 DWORD retval;
385 HANDLE device_handle;
386
387 if (!p_dev)
388 {
389 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
390 return NI_INVALID_DEVICE_HANDLE;
391 }
392
393 if (p_max_io_size_out != NULL && *p_max_io_size_out == NI_INVALID_IO_SIZE)
394 {
395 // For now, we just use it to allocate p_leftover buffer
396 // NI_MAX_PACKET_SZ is big enough
397 *p_max_io_size_out = NI_MAX_PACKET_SZ;
398 }
399
400 device_handle = CreateFileA(p_dev, GENERIC_READ | GENERIC_WRITE,
401 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
402 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
403
404 ni_log(NI_LOG_DEBUG, "%s() device_name: %s", __func__, p_dev);
405 if (INVALID_HANDLE_VALUE == device_handle)
406 {
407 retval = GetLastError();
408 ni_log(NI_LOG_ERROR, "Failed to open %s, retval %d \n", p_dev, retval);
409 } else
410 {
411 ni_log(NI_LOG_DEBUG, "Found NVME Controller at %s \n", p_dev);
412 }
413
414 return device_handle;
415#else
416 int retval = -1;
417 ni_device_handle_t fd = NI_INVALID_DEVICE_HANDLE;
418
419 if (!p_dev)
420 {
421 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
423 }
424
425 if (p_max_io_size_out != NULL && *p_max_io_size_out == NI_INVALID_IO_SIZE)
426 {
427#if __linux__
428 *p_max_io_size_out = ni_get_kernel_max_io_size(p_dev);
429#elif __APPLE__
430 *p_max_io_size_out = MAX_IO_TRANSFER_SIZE;
431#endif
432 }
433
434 ni_log(NI_LOG_DEBUG, "%s: opening regular-io enabled %s\n", __func__,
435 p_dev);
436 //O_SYNC is added to ensure that data is written to the card when the pread/pwrite function returns
437 #if __linux__
438 //O_DIRECT is added to ensure that data can be sent directly to the card instead of to cache memory
439 fd = open(p_dev, O_RDWR | O_SYNC | O_DIRECT);
440 #elif __APPLE__
441 //O_DIRECT isn't available, so instead we use F_NOCACHE below
442 fd = open(p_dev, O_RDWR | O_SYNC);
443 #endif
444
445 if (fd < 0)
446 {
447 char errmsg[NI_ERRNO_LEN] = {0};
449 ni_log(NI_LOG_ERROR, "ERROR: %d %s open() failed on %s\n", NI_ERRNO,
450 errmsg, p_dev);
451 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
452 fd = NI_INVALID_DEVICE_HANDLE;
453 LRETURN;
454 }
455 else if(fd == 0)
456 {
457 //this code is just for the case that we do not initialize all fds to NI_INVALID_DEVICE_HANDLE
458
459 //if we make sure that all the fds in libxcoder is initialized to NI_INVALID_DEVICE_HANDLE
460 //we should remove this check
461
462 //we hold the fd = 0, so other threads could not visit these code
463 //thread safe unless other thread close fd=0 accidently
464 ni_log(NI_LOG_ERROR, "open fd = 0 is not as expeceted\n");
465 if(close_fd_zero_atexit == 0)
466 {
467 close_fd_zero_atexit = 1;
468 (void)atexit(close_fd_zero);
469 }
470 else
471 {
472 ni_log(NI_LOG_ERROR, "libxcoder has held the fd=0, but open fd=0 again, maybe fd=0 was closed accidently.");
473 }
474 fd = NI_INVALID_DEVICE_HANDLE;
475 }
476
477 #if __APPLE__
478 //F_NOCACHE is set to ensure that data can be sent directly to the card instead of to cache memory
479 retval = fcntl(fd, F_NOCACHE, 1);
480 if (retval < 0)
481 {
482 ni_log(NI_LOG_ERROR, "ERROR: fnctl() failed on %s\n", p_dev);
483 ni_log(NI_LOG_ERROR, "ERROR: ni_device_open() failed!\n");
484 (void)close(fd);
485 fd = NI_INVALID_DEVICE_HANDLE;
486 LRETURN;
487 }
488 #endif
489
490 retval = fstat(fd, &g_nvme_stat);
491 if (retval < 0)
492 {
493 ni_log(NI_LOG_ERROR, "ERROR: fstat() failed on %s\n", p_dev);
494 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
495 (void)close(fd);
496 fd = NI_INVALID_DEVICE_HANDLE;
497 LRETURN;
498 }
499
500 if (!S_ISCHR(g_nvme_stat.st_mode) && !S_ISBLK(g_nvme_stat.st_mode))
501 {
502 ni_log(NI_LOG_ERROR, "ERROR: %s is not a block or character device\n",
503 p_dev);
504 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
505 (void)close(fd);
506 fd = NI_INVALID_DEVICE_HANDLE;
507 LRETURN;
508 }
509
510 ni_log(NI_LOG_DEBUG, "%s: success, fd=%d\n", __func__, fd);
511
512END:
513
514 return fd;
515#endif
516}
517#endif
518
519/*!*****************************************************************************
520 * \brief Open device and return device device_handle if successful
521 *
522 * \param[in] p_dev Device name represented as c string. ex: "/dev/nvme0"
523 * \param[in] p_config Device configuration parameters
524 *
525 * \return On success returns a device device_handle
526 * On failure returns NI_INVALID_DEVICE_HANDLE
527 ******************************************************************************/
528ni_device_handle_t ni_device_open2(const char * p_dev, ni_device_mode_t mode)
529{
530#ifdef _WIN32
531 DWORD retval;
532 HANDLE device_handle;
533 DWORD dwDesiredAccess = 0;
534
535 if (!p_dev)
536 {
537 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
538 return NI_INVALID_DEVICE_HANDLE;
539 }
540
541 /* Convert access mode using bit operations */
542 switch(mode & NI_DEVICE_READ_WRITE)
543 {
545 /* Read-only mode */
546 dwDesiredAccess = GENERIC_READ;
547 break;
549 /* Write-only mode */
550 dwDesiredAccess = GENERIC_WRITE;
551 break;
553 default:
554 /* Read-write mode takes precedence */
555 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
556 break;
557 }
558
559 device_handle = CreateFileA(p_dev, dwDesiredAccess,
560 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
561 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
562
563 ni_log(NI_LOG_DEBUG, "%s() device_name: %s", __func__, p_dev);
564 if (INVALID_HANDLE_VALUE == device_handle)
565 {
566 retval = GetLastError();
567 ni_log(NI_LOG_ERROR, "Failed to open %s, retval %d \n", p_dev, retval);
568 } else
569 {
570 ni_log(NI_LOG_DEBUG, "Found NVME Controller at %s \n", p_dev);
571 }
572
573 return device_handle;
574#else
575 int retval = -1;
576 ni_device_handle_t fd = NI_INVALID_DEVICE_HANDLE;
577 int open_flags = 0;
578
579 if (!p_dev)
580 {
581 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
583 }
584
585 ni_log(NI_LOG_DEBUG, "%s: opening regular-io enabled %s\n", __func__,
586 p_dev);
587
588 /* Set access mode using bit operations */
589 switch(mode & NI_DEVICE_READ_WRITE)
590 {
592 /* Read-only mode */
593 open_flags = O_RDONLY;
594 break;
596 /* Write-only mode */
597 open_flags = O_WRONLY;
598 break;
600 default:
601 /* Read-write mode takes precedence */
602 open_flags = O_RDWR;
603 break;
604 }
605
606 open_flags |= O_SYNC;
607#if __linux__
608 open_flags |= O_DIRECT;
609#elif __APPLE__
610 /* macOS doesn't support O_DIRECT, use F_NOCACHE instead */
611#endif
612
613 fd = open(p_dev, open_flags);
614 if (fd < 0)
615 {
616 ni_log(NI_LOG_ERROR, "ERROR: %d %s open() failed on %s\n", NI_ERRNO,
617 strerror(NI_ERRNO), p_dev); // NOLINT(concurrency-mt-unsafe)
618 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
619 fd = NI_INVALID_DEVICE_HANDLE;
620 LRETURN;
621 }
622
623#if __APPLE__
624 //F_NOCACHE is set to ensure that data can be sent directly to the card instead of to cache memory
625 retval = fcntl(fd, F_NOCACHE, 1);
626 if (retval < 0)
627 {
628 ni_log(NI_LOG_ERROR, "ERROR: fnctl() failed on %s\n", p_dev);
629 ni_log(NI_LOG_ERROR, "ERROR: ni_device_open2() failed!\n");
630 (void)close(fd);
631 fd = NI_INVALID_DEVICE_HANDLE;
632 LRETURN;
633 }
634#endif
635
636 retval = fstat(fd, &g_nvme_stat);
637 if (retval < 0)
638 {
639 ni_log(NI_LOG_ERROR, "ERROR: fstat() failed on %s\n", p_dev);
640 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
641 (void)close(fd);
642 fd = NI_INVALID_DEVICE_HANDLE;
643 LRETURN;
644 }
645
646 if (!S_ISCHR(g_nvme_stat.st_mode) && !S_ISBLK(g_nvme_stat.st_mode))
647 {
648 ni_log(NI_LOG_ERROR, "ERROR: %s is not a block or character device\n",
649 p_dev);
650 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
651 (void)close(fd);
652 fd = NI_INVALID_DEVICE_HANDLE;
653 LRETURN;
654 }
655
656 ni_log(NI_LOG_DEBUG, "%s: success, fd=%d\n", __func__, fd);
657
658END:
659
660 return fd;
661#endif
662}
663
664/*!*****************************************************************************
665 * \brief Close device and release resources
666 *
667 * \param[in] device_handle Device handle obtained by calling ni_device_open()
668 *
669 * \return NONE
670 *
671 ******************************************************************************/
672void ni_device_close(ni_device_handle_t device_handle)
673{
674 if ( NI_INVALID_DEVICE_HANDLE == device_handle )
675 {
676 ni_log(NI_LOG_ERROR, "ERROR %s: null parameter passed %x\n", __func__,
677 device_handle);
678 return;
679 }
680
681 if(device_handle == 0)
682 {
683 //this code is just for the case that we do not initialize all fds to NI_INVALID_DEVICE_HANDLE
684
685 //if we make sure that all the fds in libxcoder is initialized to NI_INVALID_DEVICE_HANDLE
686 //we should remove this check
687 ni_log(NI_LOG_ERROR, "%s close fd=0 is not as expected", __func__);
688 return;
689 }
690
691 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
692
693#ifdef _WIN32
694 BOOL retval;
695
696 ni_log(NI_LOG_DEBUG, "%s(): closing %p\n", __func__, device_handle);
697
698 retval = CloseHandle(device_handle);
699 if (FALSE == retval)
700 {
702 "ERROR: %s(): closing device device_handle %p failed, error: %d\n",
703 __func__, device_handle, NI_ERRNO);
704 }
705 else
706 {
707 ni_log(NI_LOG_DEBUG, "%s(): device %p closed successfuly\n", __func__,
708 device_handle);
709 }
710#else
711 int err = 0;
712 ni_log(NI_LOG_DEBUG, "%s(): closing fd %d\n", __func__, device_handle);
713 err = close(device_handle);
714 if (err == -1)
715 {
716 char error_message[100] = {'\0'};
717 char unknown_error_message[20] = {'\0'};
718 ni_sprintf(error_message, 100, "ERROR: %s(): ", __func__);
719 switch (errno)
720 {
721 case EBADF:
722 ni_strcat(error_message, 100, "EBADF\n");
723 break;
724 case EINTR:
725 ni_strcat(error_message, 100, "EINTR\n");
726 break;
727 case EIO:
728 ni_strcat(error_message, 100, "EIO\n");
729 break;
730 default:
731 ni_sprintf(unknown_error_message, 20, "Unknown error %d\n", err);
732 ni_strcat(error_message, 100, unknown_error_message);
733 }
734 char errmsg[NI_ERRNO_LEN] = {0};
736 ni_log(NI_LOG_ERROR, "%s\n", errmsg);
737 ni_log(NI_LOG_ERROR, "%s\n", error_message);
738 }
739#endif
740 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
741}
742
743#ifndef DEPRECATION_AS_ERROR
744/*!*****************************************************************************
745 * \brief Query device and return device capability structure
746 * This function had been replaced by ni_device_capability_query2
747 * This function can't be callback in multi thread
748 *
749 * \param[in] device_handle Device handle obtained by calling ni_device_open
750 * \param[in] p_cap Pointer to a caller allocated ni_device_capability_t
751 * struct
752 * \return On success
753 * NI_RETCODE_SUCCESS
754 * On failure
755 * NI_RETCODE_INVALID_PARAM
756 * NI_RETCODE_ERROR_MEM_ALOC
757 * NI_RETCODE_ERROR_NVME_CMD_FAILED
758 ******************************************************************************/
760{
761 void * p_buffer = NULL;
763 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
764
765 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
766
767 if ( (NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_cap) )
768 {
769 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
770 __func__);
772 LRETURN;
773 }
774
775 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
777 {
778 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
779 NI_ERRNO, __func__);
781 LRETURN;
782 }
783
784 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
785
786 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
787 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer, NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
788 {
790 LRETURN;
791 }
792
794
795END:
796
797 ni_aligned_free(p_buffer);
798 ni_log(NI_LOG_DEBUG, "%s(): retval: %d\n", __func__, retval);
799
800 return retval;
801}
802#endif
803
804/*!*****************************************************************************
805 * \brief Query device and return device capability structure
806 * This function had replaced ni_device_capability_query
807 * This function can be callback with multi thread
808 *
809 * \param[in] device_handle Device handle obtained by calling ni_device_open
810 * \param[in] p_cap Pointer to a caller allocated ni_device_capability_t
811 * struct
812 * \param[in] device_in_ctxt If device is in ctx
813 * \return On success
814 * NI_RETCODE_SUCCESS
815 * On failure
816 * NI_RETCODE_INVALID_PARAM
817 * NI_RETCODE_ERROR_MEM_ALOC
818 * NI_RETCODE_ERROR_NVME_CMD_FAILED
819 ******************************************************************************/
820ni_retcode_t ni_device_capability_query2(ni_device_handle_t device_handle,
821 ni_device_capability_t *p_cap, bool device_in_ctxt)
822{
823 void * p_buffer = NULL;
825 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
826
827 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
828
829 if ( (NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_cap) )
830 {
831 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
832 __func__);
834 LRETURN;
835 }
836
837 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
839 {
840 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
841 NI_ERRNO, __func__);
843 LRETURN;
844 }
845
846 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
847
848 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
849 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer, NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
850 {
852 LRETURN;
853 }
854
855 ni_populate_device_capability_struct(p_cap, p_buffer, device_handle, device_in_ctxt);
856
857END:
858
859 ni_aligned_free(p_buffer);
860 ni_log(NI_LOG_DEBUG, "%s(): retval: %d\n", __func__, retval);
861
862 return retval;
863}
864
865/*!*****************************************************************************
866 * \brief Open a new device session depending on the device_type parameter
867 * If device_type is NI_DEVICE_TYPE_DECODER opens decoding session
868 * If device_type is NI_DEVICE_TYPE_ENCODER opens encoding session
869 * If device_type is NI_DEVICE_TYPE_SCALER opens scaling session
870 *
871 * \param[in] p_ctx Pointer to a caller allocated
872 * ni_session_context_t struct
873 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER,
874 * or NI_DEVICE_TYPE_SCALER
875 * \return On success
876 * NI_RETCODE_SUCCESS
877 * On failure
878 * NI_RETCODE_INVALID_PARAM
879 * NI_RETCODE_ERROR_MEM_ALOC
880 * NI_RETCODE_ERROR_NVME_CMD_FAILED
881 * NI_RETCODE_ERROR_INVALID_SESSION
882 ******************************************************************************/
884 ni_device_type_t device_type)
885{
887 ni_device_pool_t *p_device_pool = NULL;
888 ni_device_context_t *p_device_context = NULL;
889 ni_device_info_t *p_dev_info = NULL;
890 ni_device_info_t dev_info = { 0 };
892 ni_device_context_t *rsrc_ctx = NULL;
893 int i = 0;
894 int rc = 0;
895 int num_coders = 0;
896 bool use_model_load = true;
897 int least_load = 0;
898 int curr_load = 0;
899 int guid = -1;
900 uint32_t num_sw_instances = 0;
901 uint32_t pixel_load = 0xFFFFFFFFU;
902 int user_handles = false;
903 ni_lock_handle_t lock = NI_INVALID_LOCK_HANDLE;
904 ni_device_handle_t handle = NI_INVALID_DEVICE_HANDLE;
905 ni_device_handle_t handle1 = NI_INVALID_DEVICE_HANDLE;
906 // For none nvme block device we just need to pass in dummy
907 ni_session_context_t *p_session_context = NULL;
908 ni_device_type_t query_type = device_type;
909
910 if (!p_ctx)
911 {
912 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
913 __func__);
915 }
916
917#ifdef _WIN32
918 if (!IsUserAnAdmin())
919 {
920 ni_log(NI_LOG_ERROR, "ERROR: %s must be in admin priviledge\n", __func__);
922 }
923#endif
924
927
928 p_session_context = ni_device_session_context_alloc_init();
929 if (!p_session_context)
930 {
932 LRETURN;
933 }
934
935 if (NI_INVALID_SESSION_ID != p_ctx->session_id)
936 {
937 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: trying to overwrite existing session, "
938 "device_type %d, session id %d\n",
939 device_type, p_ctx->session_id);
941 LRETURN;
942 }
943
944 p_ctx->p_hdr_buf = NULL;
945 p_ctx->hdr_buf_size = 0;
946
947 p_ctx->roi_side_data_size = p_ctx->nb_rois = 0;
948 p_ctx->av_rois = NULL;
949 p_ctx->roi_map = NULL;
950 p_ctx->avc_roi_map = NULL;
951 p_ctx->hevc_roi_map = NULL;
952 p_ctx->hevc_sub_ctu_roi_buf = NULL;
953 p_ctx->p_master_display_meta_data = NULL;
954
955 p_ctx->enc_change_params = NULL;
956
957 p_ctx->target_bitrate = -1;
958 p_ctx->force_idr_frame = 0;
960 p_ctx->ltr_to_set.use_long_term_ref = 0;
961 p_ctx->ltr_interval = -1;
962 p_ctx->ltr_frame_ref_invalid = -1;
963 p_ctx->framerate.framerate_num = 0;
964 p_ctx->framerate.framerate_denom = 0;
965 p_ctx->vui.colorDescPresent = 0;
966 p_ctx->vui.colorPrimaries = 2; // 2 is unspecified
967 p_ctx->vui.colorTrc = 2; // 2 is unspecified
968 p_ctx->vui.colorSpace = 2; // 2 is unspecified
969 p_ctx->vui.aspectRatioWidth = 0;
970 p_ctx->vui.aspectRatioHeight = 0;
971 p_ctx->vui.videoFullRange = 0;
972 p_ctx->max_frame_size = 0;
973 p_ctx->reconfig_crf = -1;
974 p_ctx->reconfig_crf_decimal = 0;
975 p_ctx->reconfig_vbv_buffer_size = 0;
976 p_ctx->reconfig_vbv_max_rate = 0;
977 p_ctx->last_gop_size = 0;
978 p_ctx->initial_frame_delay = 0;
979 p_ctx->current_frame_delay = 0;
980 p_ctx->max_frame_delay = 0;
981 p_ctx->av1_pkt_num = 0;
983 p_ctx->force_low_delay = false;
984 p_ctx->force_low_delay_cnt = 0;
985 p_ctx->pkt_delay_cnt = 0;
986 p_ctx->reconfig_intra_period = -1;
987 p_ctx->reconfig_slice_arg = 0;
988
989 memset(p_ctx->input_frame_fifo, 0, sizeof(ni_input_frame) * 120);
990 for (i = 0; i < 120; i++)
991 {
992 p_ctx->input_frame_fifo[i].usable = -1;
993 }
994
995 handle = p_ctx->device_handle;
996 handle1 = p_ctx->blk_io_handle;
997
998 ni_log2(p_ctx, NI_LOG_DEBUG,
999 "%s: device type %d hw_id %d blk_dev_name: %s dev_xcoder_name: %s.\n",
1000 __func__, device_type, p_ctx->hw_id, p_ctx->blk_dev_name,
1001 p_ctx->dev_xcoder_name);
1002
1003 if (device_type == NI_DEVICE_TYPE_UPLOAD)
1004 {
1005 //uploader shares resources with encoder to query as encoder for load info
1006 query_type = NI_DEVICE_TYPE_ENCODER;
1007 }
1008
1009 // if caller requested device by block device name, try to find its GUID and
1010 // use it to override the hw_id which is the passed in device GUID
1011 if (0 != strcmp(p_ctx->blk_dev_name, ""))
1012 {
1013 int tmp_guid_id;
1014 tmp_guid_id =
1016 if (tmp_guid_id != NI_RETCODE_FAILURE)
1017 {
1018 ni_log2(p_ctx, NI_LOG_DEBUG,
1019 "%s: block device name %s type %d guid %d is to "
1020 "override passed in guid %d\n",
1021 __func__, p_ctx->blk_dev_name, device_type, tmp_guid_id,
1022 p_ctx->hw_id);
1023 p_ctx->hw_id = tmp_guid_id;
1024 } else
1025 {
1026 ni_log(NI_LOG_INFO, "%s: block device name %s type %d NOT found ..\n",
1027 __func__, p_ctx->blk_dev_name, device_type);
1029 LRETURN;
1030 }
1031 }
1032
1033 // User did not pass in any handle, so we create it for them
1034 if ((handle1 == NI_INVALID_DEVICE_HANDLE) && (handle == NI_INVALID_DEVICE_HANDLE))
1035 {
1036 if (p_ctx->hw_id >=0) // User selected the encder/ decoder number
1037 {
1038 rsrc_ctx = ni_rsrc_allocate_simple_direct(device_type, p_ctx->hw_id);
1039 if (rsrc_ctx == NULL)
1040 {
1041
1042 ni_log2(p_ctx, NI_LOG_ERROR, "Error XCoder resource allocation: inst %d\n",
1043 p_ctx->hw_id);
1045 LRETURN;
1046 }
1047 ni_log2(p_ctx, NI_LOG_DEBUG, "device %p\n", rsrc_ctx);
1048 // Now the device name is in the rsrc_ctx, we open this device to get the file handles
1049
1050#ifdef _WIN32
1051 if ((handle = ni_device_open2(rsrc_ctx->p_device_info->blk_name,
1052 NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE)
1053 {
1056 LRETURN;
1057 } else
1058 {
1059 user_handles = true;
1060 p_ctx->device_handle = handle;
1061 p_ctx->blk_io_handle = handle;
1062 handle1 = handle;
1066 }
1067#else
1068 //The original design (code below) is to open char and block device file separately. And the ffmpeg will close the device twice.
1069 //However, in I/O version, char device can't be opened. For compatibility, and to avoid errors, open the block device twice.
1071 if (handle != NI_INVALID_DEVICE_HANDLE)
1073 if (handle == NI_INVALID_DEVICE_HANDLE || handle1 == NI_INVALID_DEVICE_HANDLE)
1074 {
1077 LRETURN;
1078 } else
1079 {
1080 user_handles = true;
1081 p_ctx->device_handle = handle;
1082 p_ctx->blk_io_handle = handle1;
1083 // NOLINTNEXTLINE(clang-analyzer-core.NonNullParamChecker): Couldn't determine why it will be NULL.
1086
1088 }
1089#endif
1090 } else
1091 {
1092 int tmp_id = -1;
1093
1094 // Decide on model load or real load to be used, based on name passed
1095 // in from p_ctx->dev_xcoder_name; after checking it will be used to
1096 // store device file name.
1097 if (0 == strcmp(p_ctx->dev_xcoder_name, NI_BEST_REAL_LOAD_STR))
1098 {
1099 use_model_load = false;
1100 } else if (0 != strcmp(p_ctx->dev_xcoder_name, NI_BEST_MODEL_LOAD_STR))
1101 {
1102 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s unrecognized option: %s.\n",
1103 __func__, p_ctx->dev_xcoder_name);
1104 retval = NI_RETCODE_INVALID_PARAM;
1105 LRETURN;
1106 }
1107
1108 if (ni_rsrc_lock_and_open(query_type, &lock) != NI_RETCODE_SUCCESS)
1109 {
1111 LRETURN;
1112 }
1113
1114 // We need to query through all the boards to confirm the least load.
1115
1116 p_device_pool = ni_rsrc_get_device_pool();
1117
1118 if (!p_device_pool)
1119 {
1120 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Error calling ni_rsrc_get_device_pool()\n");
1122 LRETURN;
1123 }
1124 if (IS_XCODER_DEVICE_TYPE(query_type))
1125 {
1126 num_coders = (int)p_device_pool->p_device_queue->xcoder_cnt[query_type];
1127 } else
1128 {
1129 retval = NI_RETCODE_INVALID_PARAM;
1130 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1131 {
1133 LRETURN;
1134 }
1135 LRETURN;
1136 }
1137
1138 for (i = 0; i < num_coders; i++)
1139 {
1140 tmp_id = p_device_pool->p_device_queue->xcoders[query_type][i];
1141 p_device_context = ni_rsrc_get_device_context(query_type, tmp_id);
1142
1143 if (p_device_context == NULL)
1144 {
1145 ni_log2(p_ctx, NI_LOG_ERROR,
1146 "ERROR: %s() ni_rsrc_get_device_context() failed\n",
1147 __func__);
1148 continue;
1149 }
1150
1151 // Code is included in the for loop. In the loop, the device is
1152 // just opened once, and it will be closed once too.
1153 p_session_context->blk_io_handle = ni_device_open2(
1154 p_device_context->p_device_info->dev_name, NI_DEVICE_READ_WRITE);
1155 p_session_context->device_handle = p_session_context->blk_io_handle;
1156
1157 if (NI_INVALID_DEVICE_HANDLE == p_session_context->device_handle)
1158 {
1159 ni_log2(p_ctx, NI_LOG_ERROR, "Error open device");
1160 ni_rsrc_free_device_context(p_device_context);
1161 continue;
1162 }
1163
1164 p_session_context->hw_id = p_device_context->p_device_info->hw_id;
1165 rc = ni_device_session_query(p_session_context, query_type);
1166 if (NI_INVALID_DEVICE_HANDLE != p_session_context->device_handle)
1167 {
1168 ni_device_close(p_session_context->device_handle);
1169 }
1170
1171 if (NI_RETCODE_SUCCESS != rc)
1172 {
1173 ni_log2(p_ctx, NI_LOG_ERROR, "Error query %s %s.%d\n",
1174 g_device_type_str[query_type],
1175 p_device_context->p_device_info->dev_name,
1176 p_device_context->p_device_info->hw_id);
1177 ni_rsrc_free_device_context(p_device_context);
1178 continue;
1179 }
1180 ni_rsrc_update_record(p_device_context, p_session_context);
1181 p_dev_info = p_device_context->p_device_info;
1182
1183 // here we select the best load
1184 // for decoder/encoder: check the model_load/real_load
1185 // for hwuploader: check directly hwupload pixel load in query result
1186 if (NI_DEVICE_TYPE_UPLOAD == device_type)
1187 {
1188 if (lower_pixel_rate(&p_session_context->load_query, pixel_load))
1189 {
1190 guid = tmp_id;
1191 pixel_load = p_session_context->load_query.total_pixel_load;
1192 memcpy(&dev_info, p_dev_info, sizeof(ni_device_info_t));
1193 }
1194 } else
1195 {
1196 if (use_model_load)
1197 {
1198 curr_load = p_dev_info->model_load;
1199 } else
1200 {
1201 curr_load = p_dev_info->load;
1202 }
1203
1204 if (i == 0 || curr_load < least_load ||
1205 (curr_load == least_load &&
1206 p_dev_info->active_num_inst < num_sw_instances))
1207 {
1208 guid = tmp_id;
1209 least_load = curr_load;
1210 num_sw_instances = p_dev_info->active_num_inst;
1211 memcpy(&dev_info, p_dev_info, sizeof(ni_device_info_t));
1212 }
1213 }
1214 ni_rsrc_free_device_context(p_device_context);
1215 }
1216
1217#ifdef _WIN32
1218 // Now we have the device info that has the least load of the FW
1219 // we open this device and assign the FD
1220 if ((handle = ni_device_open2(dev_info.blk_name, NI_DEVICE_READ_WRITE)) ==
1221 NI_INVALID_DEVICE_HANDLE)
1222 {
1224 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1225 {
1227 LRETURN;
1228 }
1229 LRETURN;
1230 } else
1231 {
1232 p_ctx->device_handle = handle;
1233 p_ctx->blk_io_handle = handle;
1234 handle1 = handle;
1235 p_ctx->hw_id = guid;
1238 }
1239#else
1240 //The original design (code below) is to open char and block device file separately. And the ffmpeg will close the device twice.
1241 //However, in I/O version, char device can't be opened. For compatibility, and to avoid errors, open the block device twice.
1242 handle = ni_device_open2(dev_info.dev_name, NI_DEVICE_READ_WRITE);
1243 if (handle != NI_INVALID_DEVICE_HANDLE)
1244 handle1 = ni_device_open2(dev_info.dev_name, NI_DEVICE_READ_WRITE);
1245 if (handle == NI_INVALID_DEVICE_HANDLE || handle1 == NI_INVALID_DEVICE_HANDLE)
1246 {
1248 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1249 {
1251 LRETURN;
1252 }
1253 LRETURN;
1254 }
1255 else
1256 {
1257 p_ctx->device_handle = handle;
1258 p_ctx->blk_io_handle = handle1;
1259 p_ctx->hw_id = guid;
1262 }
1263#endif
1264 }
1265 }
1266 // user passed in the handle, but one of them is invalid, this is error case so we return error
1267 else if((handle1 == NI_INVALID_DEVICE_HANDLE) || (handle == NI_INVALID_DEVICE_HANDLE))
1268 {
1270 LRETURN;
1271 }
1272 // User passed in both handles, so we do not need to allocate for it
1273 else
1274 {
1275 user_handles = true;
1276 }
1277
1278 ni_log2(p_ctx, NI_LOG_DEBUG,
1279 "Finish open the session dev:%s guid:%d handle:%p handle1:%p\n",
1280 p_ctx->dev_xcoder_name, p_ctx->hw_id,
1281 p_ctx->device_handle, p_ctx->blk_io_handle);
1284 // get FW API version
1285 p_device_context = ni_rsrc_get_device_context(device_type, p_ctx->hw_id);
1286 if (p_device_context == NULL)
1287 {
1288 ni_log2(p_ctx, NI_LOG_ERROR,
1289 "ERROR: %s() ni_rsrc_get_device_context() failed\n",
1290 __func__);
1291 if (user_handles != true)
1292 {
1293 if(ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1294 {
1296 LRETURN;
1297 }
1298 }
1300 LRETURN;
1301 }
1302
1303 if (!(strcmp(p_ctx->dev_xcoder_name, "")) || !(strcmp(p_ctx->dev_xcoder_name, NI_BEST_MODEL_LOAD_STR)) ||
1304 !(strcmp(p_ctx->dev_xcoder_name, NI_BEST_REAL_LOAD_STR)))
1305 {
1307 }
1308
1309 memcpy(p_ctx->fw_rev , p_device_context->p_device_info->fw_rev, 8);
1310
1311 ni_rsrc_free_device_context(p_device_context);
1312
1313 retval = ni_device_get_ddr_configuration(p_ctx);
1314 if (retval != NI_RETCODE_SUCCESS)
1315 {
1316 ni_log2(p_ctx, NI_LOG_ERROR,
1317 "ERROR: %s() cannot retrieve DDR configuration\n",
1318 __func__);
1319 if (user_handles != true)
1320 {
1321 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1322 {
1324 LRETURN;
1325 }
1326 }
1327 LRETURN;
1328 }
1329
1330 if (p_ctx->keep_alive_timeout == 0)
1331 {
1332 ni_log2(p_ctx, NI_LOG_ERROR,
1333 "ERROR: %s() keep_alive_timeout was 0, should be between 1-100. "
1334 "Setting to default of %u\n",
1337 }
1338 switch (device_type)
1339 {
1341 {
1342 retval = ni_decoder_session_open(p_ctx);
1343 if (user_handles != true)
1344 {
1345 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1346 {
1348 LRETURN;
1349 }
1350 }
1351 // send keep alive signal thread
1352 if (NI_RETCODE_SUCCESS != retval)
1353 {
1354 LRETURN;
1355 }
1356 break;
1357 }
1359 {
1360#ifndef _WIN32
1361 // p2p is not supported on Windows, so skip following assignments.
1362 ni_xcoder_params_t *p_enc_params;
1363
1364 p_enc_params = p_ctx->p_session_config;
1365
1366 if (p_enc_params && p_enc_params->hwframes &&
1367 p_enc_params->p_first_frame)
1368 {
1369 niFrameSurface1_t *pSurface;
1370 pSurface =
1371 (niFrameSurface1_t *)p_enc_params->p_first_frame->p_data[3];
1372 p_ctx->sender_handle =
1373 (ni_device_handle_t)(int64_t)pSurface->device_handle;
1374 p_enc_params->rootBufId = pSurface->ui16FrameIdx;
1375
1376 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: sender_handle and rootBufId %d set\n",
1377 __func__, p_enc_params->rootBufId);
1378 }
1379#endif
1380
1381 retval = ni_encoder_session_open(p_ctx);
1382 if (user_handles != true)
1383 {
1384 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1385 {
1387 LRETURN;
1388 }
1389 }
1390 // send keep alive signal thread
1391 if (NI_RETCODE_SUCCESS != retval)
1392 {
1393 LRETURN;
1394 }
1395 break;
1396 }
1398 {
1399 retval = ni_uploader_session_open(p_ctx);
1400 if (user_handles != true)
1401 {
1402 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1403 {
1405 LRETURN;
1406 }
1407 }
1408 // send keep alive signal thread
1409 if (NI_RETCODE_SUCCESS != retval)
1410 {
1411 LRETURN;
1412 }
1413 break;
1414 }
1416 {
1417 retval = ni_scaler_session_open(p_ctx);
1418 if (user_handles != true)
1419 {
1420 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1421 {
1423 LRETURN;
1424 }
1425 }
1426 // send keep alive signal thread
1427 if (NI_RETCODE_SUCCESS != retval)
1428 {
1429 LRETURN;
1430 }
1431 break;
1432 }
1433 case NI_DEVICE_TYPE_AI:
1434 {
1435 retval = ni_ai_session_open(p_ctx);
1436 if (user_handles != true)
1437 {
1438 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1439 {
1441 LRETURN;
1442 }
1443 }
1444 // send keep alive signal thread
1445 if (NI_RETCODE_SUCCESS != retval)
1446 {
1447 LRETURN;
1448 }
1449 break;
1450 }
1451 default:
1452 {
1453 if (user_handles != true)
1454 {
1455 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1456 {
1458 LRETURN;
1459 }
1460 }
1461 retval = NI_RETCODE_INVALID_PARAM;
1462 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1463 __func__, device_type);
1464 LRETURN;
1465 }
1466 }
1467
1469 if (!p_ctx->keep_alive_thread_args)
1470 {
1471 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: thread_args allocation failed!\n");
1472 ni_device_session_close(p_ctx, 0, device_type);
1474 LRETURN;
1475 }
1476
1479 p_ctx->keep_alive_thread_args->device_type = device_type;
1482 p_ctx->keep_alive_thread_args->close_thread = false;
1485 p_ctx->keep_alive_thread_args->p_mutex = &p_ctx->mutex;
1486 p_ctx->keep_alive_thread_args->hw_id = p_ctx->hw_id;
1488
1490 sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
1491 {
1492 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: keep alive p_buffer allocation failed!\n");
1493 ni_device_session_close(p_ctx, 0, device_type);
1495 LRETURN;
1496 }
1498
1499 if (0 !=
1502 (void *)p_ctx->keep_alive_thread_args))
1503 {
1504 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to create keep alive thread\n");
1505 p_ctx->keep_alive_thread = (ni_pthread_t){0};
1508 ni_device_session_close(p_ctx, 0, device_type);
1510 LRETURN;
1511 }
1512 ni_log2(p_ctx, NI_LOG_DEBUG, "Enabled keep alive thread\n");
1513
1514 // allocate memory for encoder change data to be reused
1515 p_ctx->enc_change_params = calloc(1, sizeof(ni_encoder_change_params_t));
1516 if (!p_ctx->enc_change_params)
1517 {
1518 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: enc_change_params allocation failed!\n");
1519 ni_device_session_close(p_ctx, 0, device_type);
1521 }
1522
1523END:
1524 ni_device_session_context_free(p_session_context);
1525
1526 if (p_device_pool)
1527 {
1528 ni_rsrc_free_device_pool(p_device_pool);
1529 p_device_pool = NULL;
1530 }
1531
1532 p_ctx->xcoder_state &= ~NI_XCODER_OPEN_STATE;
1533
1535
1536 return retval;
1537}
1538
1539/*!*****************************************************************************
1540 * \brief Close device session that was previously opened by calling
1541 * ni_device_session_open()
1542 * If device_type is NI_DEVICE_TYPE_DECODER closes decoding session
1543 * If device_type is NI_DEVICE_TYPE_ENCODER closes encoding session
1544 * If device_type is NI_DEVICE_TYPE_SCALER closes scaling session
1545 *
1546 * \param[in] p_ctx Pointer to a caller allocated
1547 * ni_session_context_t struct
1548 * \param[in] eos_received Flag indicating if End Of Stream indicator was
1549 * received
1550 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER,
1551 * or NI_DEVICE_TYPE_SCALER
1552 * \return On success
1553 * NI_RETCODE_SUCCESS
1554 * On failure
1555 * NI_RETCODE_INVALID_PARAM
1556 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1557 * NI_RETCODE_ERROR_INVALID_SESSION
1558 ******************************************************************************/
1560 int eos_recieved,
1561 ni_device_type_t device_type)
1562{
1563 int ret;
1565
1566 if (!p_ctx)
1567 {
1568 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1569 __func__);
1571 }
1572
1576
1577#ifdef _WIN32
1578 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args)
1579#else
1580 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args)
1581#endif
1582 {
1583 p_ctx->keep_alive_thread_args->close_thread = true;
1584 ret = ni_pthread_join(p_ctx->keep_alive_thread, NULL);
1585 if (ret)
1586 {
1587 ni_log2(p_ctx, NI_LOG_ERROR,
1588 "join keep alive thread fail! : sid %u ret %d\n",
1589 p_ctx->session_id, ret);
1590 }
1593 } else
1594 {
1595 ni_log2(p_ctx, NI_LOG_ERROR, "invalid keep alive thread: %u\n",
1596 p_ctx->session_id);
1597 }
1598
1599 switch (device_type)
1600 {
1602 {
1603 retval = ni_decoder_session_close(p_ctx, eos_recieved);
1604 break;
1605 }
1607 {
1609 // fall through
1610 }
1612 {
1613 retval = ni_encoder_session_close(p_ctx, eos_recieved);
1614 break;
1615 }
1617 {
1618 retval = ni_scaler_session_close(p_ctx, eos_recieved);
1619 break;
1620 }
1621 case NI_DEVICE_TYPE_AI:
1622 {
1623 retval = ni_ai_session_close(p_ctx, eos_recieved);
1624 break;
1625 }
1626 default:
1627 {
1628 retval = NI_RETCODE_INVALID_PARAM;
1629 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1630 __func__, device_type);
1631 break;
1632 }
1633 }
1634
1636 // need set invalid after closed. May cause open invalid parameters.
1638
1639 ni_memfree(p_ctx->p_hdr_buf);
1640 ni_memfree(p_ctx->av_rois);
1641 ni_memfree(p_ctx->roi_map);
1642 ni_memfree(p_ctx->avc_roi_map);
1643 ni_memfree(p_ctx->hevc_roi_map);
1647 p_ctx->hdr_buf_size = 0;
1648 p_ctx->roi_side_data_size = 0;
1649 p_ctx->nb_rois = 0;
1650 p_ctx->target_bitrate = -1;
1651 p_ctx->force_idr_frame = 0;
1653 p_ctx->ltr_to_set.use_long_term_ref = 0;
1654 p_ctx->ltr_interval = -1;
1655 p_ctx->ltr_frame_ref_invalid = -1;
1656 p_ctx->max_frame_size = 0;
1657 p_ctx->reconfig_crf = -1;
1658 p_ctx->reconfig_crf_decimal = 0;
1659 p_ctx->reconfig_vbv_buffer_size = 0;
1660 p_ctx->reconfig_vbv_max_rate = 0;
1661 p_ctx->last_gop_size = 0;
1662 p_ctx->initial_frame_delay = 0;
1663 p_ctx->current_frame_delay = 0;
1664 p_ctx->max_frame_delay = 0;
1665 p_ctx->av1_pkt_num = 0;
1666 p_ctx->reconfig_intra_period = -1;
1667 p_ctx->reconfig_slice_arg = 0;
1668
1669 p_ctx->xcoder_state &= ~NI_XCODER_CLOSE_STATE;
1671
1672 return retval;
1673}
1674
1675/*!*****************************************************************************
1676 * \brief Send a flush command to the device
1677 * If device_type is NI_DEVICE_TYPE_DECODER sends EOS command to
1678 * decoder
1679 * If device_type is NI_DEVICE_TYPE_ENCODER sends EOS command to
1680 * encoder
1681 *
1682 * \param[in] p_ctx Pointer to a caller allocated
1683 * ni_session_context_t struct
1684 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1685 * \return On success
1686 * NI_RETCODE_SUCCESS
1687 * On failure
1688 * NI_RETCODE_INVALID_PARAM
1689 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1690 * NI_RETCODE_ERROR_INVALID_SESSION
1691 ******************************************************************************/
1693{
1695 if (!p_ctx)
1696 {
1697 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1698 __func__);
1700 }
1701
1704
1705 switch (device_type)
1706 {
1708 {
1709 retval = ni_decoder_session_send_eos(p_ctx);
1710 break;
1711 }
1713 {
1714 retval = ni_encoder_session_send_eos(p_ctx);
1715 break;
1716 }
1717 default:
1718 {
1719 retval = NI_RETCODE_INVALID_PARAM;
1720 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1721 __func__, device_type);
1722 break;
1723 }
1724 }
1725 p_ctx->ready_to_close = (NI_RETCODE_SUCCESS == retval);
1726 p_ctx->xcoder_state &= ~NI_XCODER_FLUSH_STATE;
1728 return retval;
1729}
1730
1731/*!*****************************************************************************
1732 * \brief Save a stream's headers in a decoder session that can be used later
1733 * for continuous decoding from the same source.
1734 *
1735 * \param[in] p_ctx Pointer to a caller allocated
1736 * ni_session_context_t struct
1737 * \param[in] hdr_data Pointer to header data
1738 * \param[in] hdr_size Size of header data in bytes
1739 * \return On success
1740 * NI_RETCODE_SUCCESS
1741 * On failure
1742 * NI_RETCODE_INVALID_PARAM
1743 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1744 * NI_RETCODE_ERROR_INVALID_SESSION
1745 ******************************************************************************/
1747 uint8_t *hdr_data,
1748 uint8_t hdr_size)
1749{
1751
1752 if (!p_ctx)
1753 {
1754 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s p_ctx null, return\n", __func__);
1756 }
1757
1758 if (!hdr_data)
1759 {
1760 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s hdr_data null, return\n", __func__);
1762 } else if (p_ctx->p_hdr_buf && p_ctx->hdr_buf_size == hdr_size &&
1763 0 == memcmp(p_ctx->p_hdr_buf, hdr_data, hdr_size))
1764 {
1765 // no change from the saved headers, success !
1766 return retval;
1767 }
1768
1769 // update the saved header data
1770 free(p_ctx->p_hdr_buf);
1771 p_ctx->hdr_buf_size = 0;
1772 p_ctx->p_hdr_buf = malloc(hdr_size);
1773 if (p_ctx->p_hdr_buf)
1774 {
1775 memcpy(p_ctx->p_hdr_buf, hdr_data, hdr_size);
1776 p_ctx->hdr_buf_size = hdr_size;
1777 ni_log2(p_ctx, NI_LOG_DEBUG, "%s saved hdr size %u\n", __func__,
1778 p_ctx->hdr_buf_size);
1779 } else
1780 {
1782 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s no memory.\n", __func__);
1783 }
1784 return retval;
1785}
1786
1787/*!*****************************************************************************
1788 * \brief Flush a decoder session to get ready to continue decoding.
1789 * Note: this is different from ni_device_session_flush in that it closes the
1790 * current decode session and opens a new one for continuous decoding.
1791 *
1792 * \param[in] p_ctx Pointer to a caller allocated
1793 * ni_session_context_t struct
1794 * \return On success
1795 * NI_RETCODE_SUCCESS
1796 * On failure
1797 * NI_RETCODE_INVALID_PARAM
1798 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1799 * NI_RETCODE_ERROR_INVALID_SESSION
1800 ******************************************************************************/
1802{
1804
1805 if (!p_ctx)
1806 {
1807 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s ctx null, return\n", __func__);
1809 }
1811 retval = ni_decoder_session_flush(p_ctx);
1812 if (NI_RETCODE_SUCCESS == retval) {
1813 p_ctx->ready_to_close = 0;
1814 }
1816 return retval;
1817}
1818
1819/*!*****************************************************************************
1820 * \brief Sends data to the device
1821 * If device_type is NI_DEVICE_TYPE_DECODER sends data packet to
1822 * decoder
1823 * If device_type is NI_DEVICE_TYPE_ENCODER sends data frame to encoder
1824 * If device_type is NI_DEVICE_TYPE_AI sends data frame to ai engine
1825 *
1826 * \param[in] p_ctx Pointer to a caller allocated
1827 * ni_session_context_t struct
1828 * \param[in] p_data Pointer to a caller allocated
1829 * ni_session_data_io_t struct which contains either a
1830 * ni_frame_t data frame or ni_packet_t data packet to
1831 * send
1832 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER or
1833 * NI_DEVICE_TYPE_AI
1834 * If NI_DEVICE_TYPE_DECODER is specified, it is
1835 * expected that the ni_packet_t struct inside the
1836 * p_data pointer contains data to send.
1837 * If NI_DEVICE_TYPE_ENCODER or NI_DEVICE_TYPE_AI is
1838 * specified, it is expected that the ni_frame_t
1839 * struct inside the p_data pointer contains data to
1840 * send.
1841 * \return On success
1842 * Total number of bytes written
1843 * On failure
1844 * NI_RETCODE_INVALID_PARAM
1845 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1846 * NI_RETCODE_ERROR_INVALID_SESSION
1847 ******************************************************************************/
1849{
1851
1852 if (!p_ctx || !p_data)
1853 {
1854 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1855 __func__);
1857 }
1858 // Here check if keep alive thread is closed.
1859#ifdef _WIN32
1860 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
1862#else
1863 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
1865#endif
1866 {
1867 ni_log2(p_ctx, NI_LOG_ERROR,
1868 "ERROR: %s() keep alive thread has been closed, "
1869 "hw:%d, session:%d\n",
1870 __func__, p_ctx->hw_id, p_ctx->session_id);
1872 }
1873
1875 // In close state, let the close process execute first.
1877 {
1878 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
1880 ni_usleep(100);
1882 }
1885
1886 switch (device_type)
1887 {
1889 {
1890 retval = ni_decoder_session_write(p_ctx, &(p_data->data.packet));
1891 break;
1892 }
1894 {
1895 retval = ni_encoder_session_write(p_ctx, &(p_data->data.frame));
1896 break;
1897 }
1898 case NI_DEVICE_TYPE_AI:
1899 {
1900 retval = ni_ai_session_write(p_ctx, &(p_data->data.frame));
1901 break;
1902 }
1903 default:
1904 {
1905 retval = NI_RETCODE_INVALID_PARAM;
1906 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1907 __func__, device_type);
1908 break;
1909 }
1910 }
1911
1913 p_ctx->xcoder_state &= ~NI_XCODER_WRITE_STATE;
1915 return retval;
1916}
1917
1918/*!*****************************************************************************
1919 * \brief Read data from the device
1920 * If device_type is NI_DEVICE_TYPE_DECODER reads data packet from
1921 * decoder
1922 * If device_type is NI_DEVICE_TYPE_ENCODER reads data frame from
1923 * encoder
1924 * If device_type is NI_DEVICE_TYPE_AI reads data frame from AI engine
1925 *
1926 * \param[in] p_ctx Pointer to a caller allocated
1927 * ni_session_context_t struct
1928 * \param[in] p_data Pointer to a caller allocated ni_session_data_io_t
1929 * struct which contains either a ni_frame_t data frame
1930 * or ni_packet_t data packet to send
1931 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER, or
1932 * NI_DEVICE_TYPE_SCALER
1933 * If NI_DEVICE_TYPE_DECODER is specified, data that
1934 * was read will be placed into ni_frame_t struct
1935 * inside the p_data pointer
1936 * If NI_DEVICE_TYPE_ENCODER is specified, data that
1937 * was read will be placed into ni_packet_t struct
1938 * inside the p_data pointer
1939 * If NI_DEVICE_TYPE_AI is specified, data that was
1940 * read will be placed into ni_frame_t struct inside
1941 * the p_data pointer
1942 * \return On success
1943 * Total number of bytes read
1944 * On failure
1945 * NI_RETCODE_INVALID_PARAM
1946 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1947 * NI_RETCODE_ERROR_INVALID_SESSION
1948 ******************************************************************************/
1950{
1952 if ((!p_ctx) || (!p_data))
1953 {
1954 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1955 __func__);
1957 }
1958
1959 // Here check if keep alive thread is closed.
1960#ifdef _WIN32
1961 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
1963#else
1964 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
1966#endif
1967 {
1968 ni_log2(p_ctx, NI_LOG_ERROR,
1969 "ERROR: %s() keep alive thread has been closed, "
1970 "hw:%d, session:%d\n",
1971 __func__, p_ctx->hw_id, p_ctx->session_id);
1973 }
1974
1976 // In close state, let the close process execute first.
1978 {
1979 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
1981 ni_usleep(100);
1983 }
1986
1987 switch (device_type)
1988 {
1990 {
1991 int seq_change_read_count = 0;
1992 p_data->data.frame.src_codec = p_ctx->codec_format;
1993 for (;;)
1994 {
1995 retval = ni_decoder_session_read(p_ctx, &(p_data->data.frame));
1996 // check resolution change only after initial setting obtained
1997 // p_data->data.frame.video_width is picture width and will be 32-align
1998 // adjusted to frame size; p_data->data.frame.video_height is the same as
1999 // frame size, then compare them to saved one for resolution checking
2000 //
2001 uint32_t aligned_width;
2002 if(QUADRA)
2003 {
2004 aligned_width = ((((p_data->data.frame.video_width * p_ctx->bit_depth_factor) + 127) / 128) * 128);
2005 }
2006 else
2007 {
2008 aligned_width = ((p_data->data.frame.video_width + 31) / 32) * 32;
2009 }
2010
2011 if (0 == retval && seq_change_read_count)
2012 {
2013 ni_log2(p_ctx, NI_LOG_DEBUG,
2014 "%s (decoder): seq change NO data, next time.\n", __func__);
2015 p_ctx->active_video_width = 0;
2016 p_ctx->active_video_height = 0;
2017 p_ctx->actual_video_width = 0;
2018 break;
2019 }
2020 else if (retval < 0)
2021 {
2022 ni_log2(p_ctx, NI_LOG_ERROR, "%s (decoder): failure ret %d, return ..\n",
2023 __func__, retval);
2024 break;
2025 }
2026 // aligned_width may equal to active_video_width if bit depth and width
2027 // are changed at the same time. So, check video_width != actual_video_width.
2028 else if (p_ctx->frame_num && (p_ctx->pixel_format_changed ||
2029 (p_data->data.frame.video_width &&
2030 p_data->data.frame.video_height &&
2031 (aligned_width != p_ctx->active_video_width ||
2032 p_data->data.frame.video_height != p_ctx->active_video_height))))
2033 {
2034 ni_log2(
2035 p_ctx, NI_LOG_DEBUG,
2036 "%s (decoder): resolution change, frame size %ux%u -> %ux%u, "
2037 "width %u bit %d, pix_fromat_changed %d, actual_video_width %d, continue read ...\n",
2038 __func__, p_ctx->active_video_width, p_ctx->active_video_height,
2039 aligned_width, p_data->data.frame.video_height,
2040 p_data->data.frame.video_width, p_ctx->bit_depth_factor,
2042 // reset active video resolution to 0 so it can be queried in the re-read
2043 p_ctx->active_video_width = 0;
2044 p_ctx->active_video_height = 0;
2045 p_ctx->actual_video_width = 0;
2046 seq_change_read_count++;
2047 }
2048 else
2049 {
2050 break;
2051 }
2052 }
2053 break;
2054 }
2056 {
2057 retval = ni_encoder_session_read(p_ctx, &(p_data->data.packet));
2058 break;
2059 }
2060 case NI_DEVICE_TYPE_AI:
2061 {
2062 retval = ni_ai_session_read(p_ctx, &(p_data->data.packet));
2063 break;
2064 }
2065 default:
2066 {
2067 retval = NI_RETCODE_INVALID_PARAM;
2068 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2069 __func__, device_type);
2070 break;
2071 }
2072 }
2073
2075 p_ctx->xcoder_state &= ~NI_XCODER_READ_STATE;
2077 return retval;
2078}
2079
2080/*!*****************************************************************************
2081 * \brief Query session data from the device -
2082 * If device_type is valid, will query session data
2083 * from specified device type
2084 *
2085 * \param[in] p_ctx Pointer to a caller allocated
2086 * ni_session_context_t struct
2087 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2088 * NI_DEVICE_TYPE_ENCODER or
2089 * NI_DEVICE_TYPE_SCALER or
2090 * NI_DEVICE_TYPE_AI or
2091 * NI_DEVICE_TYPE_UPLOADER
2092 *
2093 * \return On success
2094 * NI_RETCODE_SUCCESS
2095 * On failure
2096 * NI_RETCODE_INVALID_PARAM
2097 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2098 * NI_RETCODE_ERROR_INVALID_SESSION
2099 ******************************************************************************/
2101{
2103 if (!p_ctx)
2104 {
2105 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2106 __func__);
2108 }
2109
2110 if (IS_XCODER_DEVICE_TYPE(device_type))
2111 {
2112 retval = ni_xcoder_session_query(p_ctx, device_type);
2113 } else
2114 {
2115 retval = NI_RETCODE_INVALID_PARAM;
2116 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2117 __func__, device_type);
2118 }
2119
2120 return retval;
2121}
2122
2123/*!*****************************************************************************
2124 * \brief Query detail session data from the device -
2125 * If device_type is valid, will query session data
2126 * from specified device type
2127 *
2128 * \param[in] p_ctx Pointer to a caller allocated
2129 * ni_session_context_t struct
2130 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2131 * NI_DEVICE_TYPE_ENCODER or
2132 *
2133 * \return On success
2134 * NI_RETCODE_SUCCESS
2135 * On failure
2136 * NI_RETCODE_INVALID_PARAM
2137 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2138 * NI_RETCODE_ERROR_INVALID_SESSION
2139 ******************************************************************************/
2141{
2143 if (!p_ctx)
2144 {
2145 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2146 __func__);
2148 }
2149
2150 if (IS_XCODER_DEVICE_TYPE(device_type))
2151 {
2152 retval = ni_xcoder_session_query_detail(p_ctx, device_type, detail_data, 0);
2153 } else
2154 {
2155 retval = NI_RETCODE_INVALID_PARAM;
2156 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2157 __func__, device_type);
2158 }
2159
2160 return retval;
2161}
2162
2163/*!*****************************************************************************
2164 * \brief Query detail session data from the device -
2165 * If device_type is valid, will query session data
2166 * from specified device type
2167 *
2168 * \param[in] p_ctx Pointer to a caller allocated
2169 * ni_session_context_t struct
2170 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2171 * NI_DEVICE_TYPE_ENCODER or
2172 *
2173 * \return On success
2174 * NI_RETCODE_SUCCESS
2175 * On failure
2176 * NI_RETCODE_INVALID_PARAM
2177 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2178 * NI_RETCODE_ERROR_INVALID_SESSION
2179 ******************************************************************************/
2181{
2183 if (!p_ctx)
2184 {
2185 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2186 __func__);
2188 }
2189
2190 if (IS_XCODER_DEVICE_TYPE(device_type))
2191 {
2192 retval = ni_xcoder_session_query_detail(p_ctx, device_type, detail_data, 1);
2193 } else
2194 {
2195 retval = NI_RETCODE_INVALID_PARAM;
2196 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2197 __func__, device_type);
2198 }
2199
2200 return retval;
2201}
2202
2203/*!*****************************************************************************
2204 * \brief Send namespace num and SRIOv index to the device with specified logic block
2205 * address.
2206 *
2207 * \param[in] device_handle Device handle obtained by calling ni_device_open
2208 * \param[in] namespace_num Set the namespace number with designated sriov
2209 * \param[in] sriov_index Identify which sriov need to be set
2210 *
2211 * \return On success
2212 * NI_RETCODE_SUCCESS
2213 * On failure
2214 * NI_RETCODE_ERROR_MEM_ALOC
2215 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2216 ******************************************************************************/
2217ni_retcode_t ni_device_config_namespace_num(ni_device_handle_t device_handle,
2218 uint32_t namespace_num, uint32_t sriov_index)
2219{
2220 ni_log(NI_LOG_DEBUG, "%s namespace_num %u sriov_index %u\n",
2221 __func__, namespace_num, sriov_index);
2222 return ni_device_config_ns_qos(device_handle, namespace_num, sriov_index);
2223}
2224
2225/*!*****************************************************************************
2226 * \brief Send qos mode to the device with specified logic block
2227 * address.
2228 *
2229 * \param[in] device_handle Device handle obtained by calling ni_device_open
2230 * \param[in] mode The requested qos mode
2231 *
2232 * \return On success
2233 * NI_RETCODE_SUCCESS
2234 * On failure
2235 * NI_RETCODE_ERROR_MEM_ALOC
2236 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2237 ******************************************************************************/
2238ni_retcode_t ni_device_config_qos(ni_device_handle_t device_handle,
2239 uint32_t mode)
2240{
2241 ni_log(NI_LOG_DEBUG, "%s device_handle %p mode %u\n",
2242 __func__, device_handle, mode);
2243 return ni_device_config_ns_qos(device_handle, QOS_NAMESPACE_CODE, mode);
2244}
2245
2246/*!*****************************************************************************
2247 * \brief Send qos over provisioning mode to target namespace with specified logic
2248 * block address.
2249 *
2250 * \param[in] device_handle Device handle obtained by calling ni_device_open
2251 * \param[in] device_handle_t Target device handle of namespace required for OP
2252 * \param[in] over_provision The request overprovision percent
2253 *
2254 * \return On success
2255 * NI_RETCODE_SUCCESS
2256 * On failure
2257 * NI_RETCODE_ERROR_MEM_ALOC
2258 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2259 ******************************************************************************/
2260ni_retcode_t ni_device_config_qos_op(ni_device_handle_t device_handle,
2261 ni_device_handle_t device_handle_t,
2262 uint32_t over_provision)
2263{
2264 ni_retcode_t retval;
2265 float f_over_provision = 0;
2266 memcpy(&f_over_provision, &over_provision, sizeof(int32_t));
2267 ni_log(NI_LOG_DEBUG, "%s device_handle %p target %p over_provision %f\n",
2268 __func__, device_handle, device_handle_t, f_over_provision);
2269 retval = ni_device_config_ns_qos(device_handle, QOS_OP_CONFIG_REC_OP_CODE,
2270 over_provision);
2271 if (NI_RETCODE_SUCCESS != retval)
2272 {
2273 return retval;
2274 }
2275 retval = ni_device_config_ns_qos(device_handle_t, QOS_OP_CONFIG_CODE,
2276 0);
2277 return retval;
2278}
2279
2280/*!*****************************************************************************
2281 * \brief Set QoS allowance for a specific namespace
2282 *
2283 * \param[in] device_handle Device handle obtained by calling ni_device_open
2284 * \param[in] device_handle_t Target device handle of namespace required for allowance
2285 * \param[in] allowance Allowance percentage (0.0-100.0)
2286 *
2287 * \return On success
2288 * NI_RETCODE_SUCCESS
2289 * On failure
2290 * NI_RETCODE_ERROR_MEM_ALOC
2291 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2292 ******************************************************************************/
2293ni_retcode_t ni_device_config_qos_allowance(ni_device_handle_t device_handle,
2294 ni_device_handle_t device_handle_t,
2295 uint32_t allowance)
2296{
2297 ni_retcode_t retval;
2298 float f_allowance = 0;
2299 memcpy(&f_allowance, &allowance, sizeof(int32_t));
2300 ni_log(NI_LOG_DEBUG, "%s device_handle %p target %p allowance %f\n",
2301 __func__, device_handle, device_handle_t, f_allowance);
2303 allowance);
2304 if (NI_RETCODE_SUCCESS != retval)
2305 {
2306 return retval;
2307 }
2308 retval = ni_device_config_ns_qos(device_handle_t, QOS_ALLOW_CONFIG_CODE,
2309 0);
2310 return retval;
2311}
2312
2313
2314/*!*****************************************************************************
2315 * \brief Allocate preliminary memory for the frame buffer based on provided
2316 * parameters. Applicable to YUV420 Planar pixel (8 or 10 bit/pixel)
2317 * format or 32-bit RGBA.
2318 *
2319 * \param[in] p_frame Pointer to a caller allocated
2320 * ni_frame_t struct
2321 * \param[in] video_width Width of the video frame
2322 * \param[in] video_height Height of the video frame
2323 * \param[in] alignment Allignment requirement
2324 * \param[in] metadata_flag Flag indicating if space for additional metadata
2325 * should be allocated
2326 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel,
2327 * 4 for 32 bits/pixel (RGBA)
2328 * \param[in] hw_frame_count Number of hw descriptors stored
2329 * \param[in] is_planar 0 if semiplanar else planar
2330 *
2331 * \return On success
2332 * NI_RETCODE_SUCCESS
2333 * On failure
2334 * NI_RETCODE_INVALID_PARAM
2335 * NI_RETCODE_ERROR_MEM_ALOC
2336 ******************************************************************************/
2338 int video_height, int alignment,
2339 int metadata_flag, int factor,
2340 int hw_frame_count, int is_planar)
2341{
2342 void* p_buffer = NULL;
2343 int metadata_size = 0;
2344 int retval = NI_RETCODE_SUCCESS;
2345 int width_aligned = video_width;
2346 int height_aligned = video_height;
2347
2348 if ((!p_frame) || ((factor!=1) && (factor!=2) && (factor !=4))
2349 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
2350 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
2351 {
2352 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2353 "factor %d, video_width %d, video_height %d\n",
2354 __func__, factor, video_width, video_height);
2356 }
2357
2358 if (metadata_flag)
2359 {
2360 metadata_size = NI_FW_META_DATA_SZ + NI_MAX_SEI_DATA;
2361 }
2362
2363 if (QUADRA)
2364 {
2365 switch (factor)
2366 {
2367 case 1: /* 8-bit YUV420 */
2368 case 2: /* 10-bit YUV420 */
2369 width_aligned = ((((video_width * factor) + 127) / 128) * 128) / factor;
2370 height_aligned = ((video_height + 1) / 2) * 2;
2371 break;
2372 case 4: /* 32-bit RGBA */
2373 //64byte aligned => 16 rgba pixels
2374 width_aligned = NI_VPU_ALIGN16(video_width);
2375 height_aligned = ((video_height + 1) / 2) * 2;
2376 break;
2377 default:
2379 }
2380 }
2381 else
2382 {
2383 width_aligned = ((video_width + 31) / 32) * 32;
2384 height_aligned = ((video_height + 7) / 8) * 8;
2385 if (alignment)
2386 {
2387 height_aligned = ((video_height + 15) / 16) * 16;
2388 }
2389 }
2390
2391 int luma_size = width_aligned * height_aligned * factor;
2392 int chroma_b_size;
2393 int chroma_r_size;
2394 if (QUADRA)
2395 {
2396 int chroma_width_aligned = ((((video_width / 2 * factor) + 127) / 128) * 128) / factor;
2397 if (is_planar == NI_PIXEL_PLANAR_FORMAT_TILED4X4 ||
2399 {
2400 chroma_width_aligned =
2401 ((((video_width * factor) + 127) / 128) * 128) / factor;
2402 }
2403 int chroma_height_aligned = height_aligned / 2;
2404 chroma_b_size = chroma_r_size = chroma_width_aligned * chroma_height_aligned * factor;
2405 if (is_planar == NI_PIXEL_PLANAR_FORMAT_TILED4X4 ||
2407 {
2408 chroma_r_size = 0;
2409 }
2410 if (4 == factor)
2411 {
2412 chroma_b_size = chroma_r_size = 0;
2413 }
2414 //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);
2415 }
2416 else
2417 {
2418 chroma_b_size = luma_size / 4;
2419 chroma_r_size = chroma_b_size;
2420 }
2421 int buffer_size;
2422
2423 /* if hw_frame_count is zero, this is a software frame */
2424 if (hw_frame_count == 0)
2425 buffer_size = luma_size + chroma_b_size + chroma_r_size + metadata_size;
2426 else
2427 buffer_size =
2428 (int)sizeof(niFrameSurface1_t) * hw_frame_count + metadata_size;
2429
2430 // added 2 blocks of 512 bytes buffer space to handle any extra metadata
2431 // retrieval from fw
2432 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT + NI_MEM_PAGE_ALIGNMENT * 3;
2433 //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);
2434
2435 //Check if need to free
2436 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
2437 {
2439 "%s: free current p_frame, p_frame->buffer_size=%u\n", __func__,
2440 p_frame->buffer_size);
2441 ni_frame_buffer_free(p_frame);
2442 }
2443
2444 //Check if need to realocate
2445 if (p_frame->buffer_size != buffer_size)
2446 {
2447 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
2448 {
2449 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
2450 NI_ERRNO, __func__);
2452 LRETURN;
2453 }
2454
2455 // init once after allocation
2456 //memset(p_buffer, 0, buffer_size);
2457 p_frame->buffer_size = buffer_size;
2458 p_frame->p_buffer = p_buffer;
2459
2460 ni_log(NI_LOG_DEBUG, "%s: Allocate new p_frame buffer\n", __func__);
2461 }
2462 else
2463 {
2464 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
2465 }
2466
2467 if (hw_frame_count)
2468 {
2469 p_frame->data_len[0] = 0;
2470 p_frame->data_len[1] = 0;
2471 p_frame->data_len[2] = 0;
2472 p_frame->data_len[3] = sizeof(niFrameSurface1_t)*hw_frame_count;
2473 }
2474 else
2475 {
2476 p_frame->data_len[0] = luma_size;
2477 p_frame->data_len[1] = chroma_b_size;
2478 p_frame->data_len[2] = chroma_r_size;
2479 p_frame->data_len[3] = 0;//unused by hwdesc
2480 }
2481
2482 p_frame->p_data[0] = p_frame->p_buffer;
2483 p_frame->p_data[1] = p_frame->p_data[0] + p_frame->data_len[0];
2484 p_frame->p_data[2] = p_frame->p_data[1] + p_frame->data_len[1];
2485 p_frame->p_data[3] = p_frame->p_data[2] + p_frame->data_len[2]; //hwdescriptor
2486
2487 // init p_data[3] to 0 so that ni_frame_buffer_free frees only valid DMA buf
2488 // fd in hw frame read from fw
2489 if (hw_frame_count)
2490 {
2491 memset(p_frame->p_data[3], 0, sizeof(niFrameSurface1_t) * hw_frame_count);
2492 }
2493
2494 p_frame->video_width = width_aligned;
2495 p_frame->video_height = height_aligned;
2496
2497 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);
2498 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2499 p_frame->buffer_size);
2500
2501END:
2502
2503 if (NI_RETCODE_SUCCESS != retval)
2504 {
2505 ni_aligned_free(p_buffer);
2506 }
2507
2508 return retval;
2509}
2510
2511/*!*****************************************************************************
2512 * \brief Wrapper function for ni_frame_buffer_alloc. Meant to handle RGBA min.
2513 * resoulution considerations for encoder.
2514 *
2515 * \param[in] p_frame Pointer to a caller allocated
2516 * ni_frame_t struct
2517 * \param[in] video_width Width of the video frame
2518 * \param[in] video_height Height of the video frame
2519 * \param[in] alignment Allignment requirement
2520 * \param[in] metadata_flag Flag indicating if space for additional metadata
2521 * should be allocated
2522 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel,
2523 * 4 for 32 bits/pixel (RGBA)
2524 * \param[in] hw_frame_count Number of hw descriptors stored
2525 * \param[in] is_planar 0 if semiplanar else planar
2526 * \param[in] pix_fmt pixel format to distinguish between planar types
2527 * and/or components
2528 *
2529 * \return On success
2530 * NI_RETCODE_SUCCESS
2531 * On failure
2532 * NI_RETCODE_INVALID_PARAM
2533 * NI_RETCODE_ERROR_MEM_ALOC
2534 ******************************************************************************/
2536 int video_height, int alignment,
2537 int metadata_flag, int factor,
2538 int hw_frame_count, int is_planar,
2539 ni_pix_fmt_t pix_fmt)
2540{
2541 (void)hw_frame_count;
2542 (void)is_planar;
2543 int extra_len = 0;
2544 int dst_stride[NI_MAX_NUM_DATA_POINTERS] = {0};
2545 int height_aligned[NI_MAX_NUM_DATA_POINTERS] = {0};
2546
2547 if (((factor!=1) && (factor!=2) && (factor !=4))
2548 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
2549 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
2550 {
2551 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2552 "factor %d, video_width %d, video_height %d\n",
2553 __func__, factor, video_width, video_height);
2555 }
2556
2557 switch (pix_fmt)
2558 {
2559 case NI_PIX_FMT_YUV420P:
2561 case NI_PIX_FMT_NV12:
2562 case NI_PIX_FMT_P010LE:
2563 case NI_PIX_FMT_NV16:
2564 case NI_PIX_FMT_YUYV422:
2565 case NI_PIX_FMT_UYVY422:
2566 case NI_PIX_FMT_ARGB:
2567 case NI_PIX_FMT_ABGR:
2568 case NI_PIX_FMT_RGBA:
2569 case NI_PIX_FMT_BGRA:
2570 case NI_PIX_FMT_BGR0:
2571 break;
2572 default:
2573 ni_log(NI_LOG_ERROR, "ERROR: %s pix_fmt %d not supported \n",
2574 __func__, pix_fmt);
2576 }
2577 //Get stride info for original resolution
2578 ni_get_frame_dim(video_width, video_height,
2579 pix_fmt,
2580 dst_stride, height_aligned);
2581
2582 if (metadata_flag)
2583 {
2584 extra_len = NI_FW_META_DATA_SZ + NI_MAX_SEI_DATA;
2585 }
2586
2587 return ni_frame_buffer_alloc_pixfmt(p_frame, pix_fmt, video_width,
2588 video_height, dst_stride, alignment,
2589 extra_len);
2590}
2591
2592/*!*****************************************************************************
2593 * \brief Allocate preliminary memory for the frame buffer based on provided
2594 * parameters.
2595 *
2596 * \param[in] p_frame Pointer to a caller allocated
2597 * ni_frame_t struct
2598 * \param[in] video_width Width of the video frame
2599 * \param[in] video_height Height of the video frame
2600 * \param[in] alignment Allignment requirement
2601 * \param[in] pixel_format Format for input
2602 *
2603 * \return On success
2604 * NI_RETCODE_SUCCESS
2605 * On failure
2606 * NI_RETCODE_INVALID_PARAM
2607 * NI_RETCODE_ERROR_MEM_ALOC
2608 ******************************************************************************/
2610 int video_height, int pixel_format)
2611{
2612 void *p_buffer = NULL;
2613 int retval = NI_RETCODE_SUCCESS;
2614 int width_aligned = video_width;
2615 int height_aligned = video_height;
2616 int buffer_size;
2617 int luma_size;
2618 int chroma_b_size;
2619 int chroma_r_size;
2620
2621 if ((!p_frame) || (video_width > NI_MAX_RESOLUTION_WIDTH) ||
2622 (video_width <= 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT) ||
2623 (video_height <= 0))
2624 {
2626 "ERROR: %s passed parameters are null or not supported, "
2627 "video_width %d, video_height %d\n",
2628 __func__, video_width, video_height);
2630 }
2631
2632 switch (pixel_format)
2633 {
2634 case NI_PIX_FMT_YUV420P:
2635 width_aligned = NI_VPU_ALIGN128(video_width);
2636 height_aligned = NI_VPU_CEIL(video_height, 2);
2637
2638 luma_size = width_aligned * height_aligned;
2639 chroma_b_size =
2640 NI_VPU_ALIGN128(video_width / 2) * height_aligned / 2;
2641 chroma_r_size = chroma_b_size;
2642 break;
2644 width_aligned = NI_VPU_ALIGN128(video_width * 2) / 2;
2645 height_aligned = NI_VPU_CEIL(video_height, 2);
2646
2647 luma_size = width_aligned * height_aligned * 2;
2648 chroma_b_size = NI_VPU_ALIGN128(video_width) * height_aligned / 2;
2649 chroma_r_size = chroma_b_size;
2650 break;
2651 case NI_PIX_FMT_NV12:
2652 width_aligned = NI_VPU_ALIGN128(video_width);
2653 height_aligned = NI_VPU_CEIL(video_height, 2);
2654
2655 luma_size = width_aligned * height_aligned;
2656 chroma_b_size = width_aligned * height_aligned / 2;
2657 chroma_r_size = 0;
2658 break;
2659 case NI_PIX_FMT_P010LE:
2660 width_aligned = NI_VPU_ALIGN128(video_width * 2) / 2;
2661 height_aligned = NI_VPU_CEIL(video_height, 2);
2662
2663 luma_size = width_aligned * height_aligned * 2;
2664 chroma_b_size = width_aligned * height_aligned;
2665 chroma_r_size = 0;
2666 break;
2667 case NI_PIX_FMT_NV16:
2668 width_aligned = NI_VPU_ALIGN64(video_width);
2669 height_aligned = video_height;
2670
2671 luma_size = width_aligned * height_aligned;
2672 chroma_b_size = luma_size;
2673 chroma_r_size = 0;
2674 break;
2675 case NI_PIX_FMT_YUYV422:
2676 case NI_PIX_FMT_UYVY422:
2677 width_aligned = NI_VPU_ALIGN16(video_width);
2678 height_aligned = video_height;
2679
2680 luma_size = width_aligned * height_aligned * 2;
2681 chroma_b_size = 0;
2682 chroma_r_size = 0;
2683 break;
2684 case NI_PIX_FMT_RGBA:
2685 case NI_PIX_FMT_BGRA:
2686 case NI_PIX_FMT_ARGB:
2687 case NI_PIX_FMT_ABGR:
2688 case NI_PIX_FMT_BGR0:
2689 width_aligned = NI_VPU_ALIGN16(video_width);
2690 height_aligned = video_height;
2691
2692 luma_size = width_aligned * height_aligned * 4;
2693 chroma_b_size = 0;
2694 chroma_r_size = 0;
2695 break;
2696 case NI_PIX_FMT_BGRP:
2697 width_aligned = NI_VPU_ALIGN32(video_width);
2698 height_aligned = video_height;
2699
2700 luma_size = width_aligned * height_aligned;
2701 chroma_b_size = luma_size;
2702 chroma_r_size = luma_size;
2703 break;
2704 default:
2705 ni_log(NI_LOG_ERROR, "Unknown pixel format %d\n", pixel_format);
2707 }
2708
2709 /* Allocate local memory to hold a software ni_frame */
2710 buffer_size = luma_size + chroma_b_size + chroma_r_size;
2711
2712 /* Round up to nearest 4K block */
2713 buffer_size = NI_VPU_ALIGN4096(buffer_size);
2714
2715 ni_log(NI_LOG_DEBUG, "%s: Rlen %d Glen %d Blen %d buffer_size %d\n",
2716 __func__, luma_size, chroma_b_size, chroma_r_size, buffer_size);
2717
2718 /* If the frame has changed, reallocate it */
2719 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
2720 {
2722 "%s: free current p_frame, p_frame->buffer_size=%u\n", __func__,
2723 p_frame->buffer_size);
2724 ni_frame_buffer_free(p_frame);
2725 }
2726
2727 /* Check if need to reallocate */
2728 if (p_frame->buffer_size != buffer_size)
2729 {
2730 ni_log(NI_LOG_DEBUG, "%s: Allocate new p_frame buffer\n", __func__);
2731 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
2732 {
2734 "ERROR %d: %s() Cannot allocate p_frame buffer.\n", NI_ERRNO,
2735 __func__);
2737 LRETURN;
2738 }
2739 } else
2740 {
2741 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
2742 p_buffer = p_frame->p_buffer;
2743 }
2744
2745 // init once after allocation
2746 // memset(p_buffer, 0, buffer_size);
2747
2748 p_frame->buffer_size = buffer_size;
2749 p_frame->p_buffer = p_buffer;
2750
2751 p_frame->data_len[0] = luma_size;
2752 p_frame->data_len[1] = chroma_b_size;
2753 p_frame->data_len[2] = chroma_r_size;
2754 p_frame->data_len[3] = 0;
2755
2756 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
2757 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + p_frame->data_len[0];
2758 p_frame->p_data[2] = (uint8_t *)p_frame->p_data[1] + p_frame->data_len[1];
2759 p_frame->p_data[3] = (uint8_t *)p_frame->p_data[2] + p_frame->data_len[2];
2760
2761 // init p_data[3] to 0 so that ni_frame_buffer_free frees only valid DMA buf
2762 // fd in hw frame read from fw
2763 p_frame->video_width = width_aligned;
2764 p_frame->video_height = height_aligned;
2765
2766 // 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);
2767 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2768 p_frame->buffer_size);
2769END:
2770
2771 if (NI_RETCODE_SUCCESS != retval)
2772 {
2773 ni_aligned_free(p_buffer);
2774 }
2775
2776 return retval;
2777}
2778
2779/*!*****************************************************************************
2780 * \brief Allocate memory for decoder frame buffer based on provided
2781 * parameters; the memory is retrieved from a buffer pool and will be
2782 * returned to the same buffer pool by ni_decoder_frame_buffer_free.
2783 * Note: all attributes of ni_frame_t will be set up except for memory and
2784 * buffer, which rely on the pool being allocated; the pool will be
2785 * allocated only after the frame resolution is known.
2786 *
2787 * \param[in] p_pool Buffer pool to get the memory from
2788 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
2789 * \param[in] alloc_mem Whether to get memory from buffer pool
2790 * \param[in] video_width Width of the video frame
2791 * \param[in] video_height Height of the video frame
2792 * \param[in] alignment Alignment requirement
2793 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel
2794 * \param[in] is_planar 0 if semiplanar else planar
2795 *
2796 * \return On success
2797 * NI_RETCODE_SUCCESS
2798 * On failure
2799 * NI_RETCODE_INVALID_PARAM
2800 * NI_RETCODE_ERROR_MEM_ALOC
2801 ******************************************************************************/
2803 ni_frame_t *p_frame, int alloc_mem,
2804 int video_width, int video_height,
2805 int alignment, int factor,
2806 int is_planar)
2807{
2808 int retval = NI_RETCODE_SUCCESS;
2809
2810 int width_aligned;
2811 int height_aligned;
2812
2813 if ((!p_frame) || ((factor!=1) && (factor!=2))
2814 || (video_width > NI_MAX_RESOLUTION_WIDTH) || (video_width <= 0)
2815 || (video_height > NI_MAX_RESOLUTION_HEIGHT) || (video_height <= 0))
2816 {
2817 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2818 "factor %d, video_width %d, video_height %d\n",
2819 __func__, factor, video_width, video_height);
2821 }
2822
2823 if (QUADRA)
2824 {
2825 width_aligned = ((((video_width * factor) + 127) / 128) * 128) / factor;
2826 height_aligned = video_height;
2827 }
2828 else
2829 {
2830 width_aligned = ((video_width + 31) / 32) * 32;
2831 height_aligned = ((video_height + 7) / 8) * 8;
2832 if (alignment)
2833 {
2834 height_aligned = ((video_height + 15) / 16) * 16;
2835 }
2836 }
2837
2838 ni_log(NI_LOG_DEBUG, "%s: aligned=%dx%d orig=%dx%d\n", __func__,
2839 width_aligned, height_aligned, video_width, video_height);
2840
2841 int luma_size = width_aligned * height_aligned * factor;
2842 int chroma_b_size;
2843 int chroma_r_size;
2844 if (QUADRA)
2845 {
2846 int chroma_width_aligned = ((((video_width / 2 * factor) + 127) / 128) * 128) / factor;
2847 if (!is_planar)
2848 {
2849 chroma_width_aligned =
2850 ((((video_width * factor) + 127) / 128) * 128) / factor;
2851 }
2852 int chroma_height_aligned = height_aligned / 2;
2853 chroma_b_size = chroma_r_size = chroma_width_aligned * chroma_height_aligned * factor;
2854 if (!is_planar)
2855 {
2856 chroma_r_size = 0;
2857 }
2858 }
2859 else
2860 {
2861 chroma_b_size = luma_size / 4;
2862 chroma_r_size = chroma_b_size;
2863 }
2864 int buffer_size = luma_size + chroma_b_size + chroma_r_size +
2866
2867 // added 2 blocks of 512 bytes buffer space to handle any extra metadata
2868 // retrieval from fw
2869 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT + NI_MEM_PAGE_ALIGNMENT * 3;
2870
2871 p_frame->buffer_size = buffer_size;
2872
2873 // if need to get a buffer from pool, pool must have been set up
2874 if (alloc_mem)
2875 {
2876 if (! p_pool)
2877 {
2878 ni_log(NI_LOG_ERROR, "ERROR %s: invalid pool!\n", __func__);
2880 LRETURN;
2881 }
2882
2883 p_frame->dec_buf = ni_buf_pool_get_buffer(p_pool);
2884 if (! p_frame->dec_buf)
2885 {
2887 LRETURN;
2888 }
2889
2890 p_frame->p_buffer = p_frame->dec_buf->buf;
2891
2892 ni_log(NI_LOG_DEBUG, "%s: got new frame ptr %p buffer %p\n", __func__,
2893 p_frame->p_buffer, p_frame->dec_buf);
2894 }
2895 else
2896 {
2897 p_frame->dec_buf = NULL;
2898 p_frame->p_buffer = NULL;
2899 ni_log(NI_LOG_DEBUG, "%s: NOT alloc mem buffer\n", __func__);
2900 }
2901
2902 if (p_frame->p_buffer)
2903 {
2904 p_frame->p_data[0] = p_frame->p_buffer;
2905 p_frame->p_data[1] = p_frame->p_data[0] + luma_size;
2906 p_frame->p_data[2] = p_frame->p_data[1] + chroma_b_size;
2907 p_frame->p_data[3] = p_frame->p_data[2] + chroma_r_size;
2908 }
2909 else
2910 {
2911 p_frame->p_data[0] = p_frame->p_data[1] = p_frame->p_data[2] = NULL;
2912 }
2913
2914 p_frame->data_len[0] = luma_size;
2915 p_frame->data_len[1] = chroma_b_size;
2916 p_frame->data_len[2] = chroma_r_size;
2917 p_frame->data_len[3] = 0; //for hwdesc
2918
2919 p_frame->video_width = width_aligned;
2920 p_frame->video_height = height_aligned;
2921
2922 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2923 p_frame->buffer_size);
2924
2925END:
2926
2927 return retval;
2928}
2929
2930/*!*****************************************************************************
2931 * \brief Check if incoming frame is encoder zero copy compatible or not
2932 *
2933 * \param[in] p_enc_ctx pointer to encoder context
2934 * [in] p_enc_params pointer to encoder parameters
2935 * [in] width input width
2936 * [in] height input height
2937 * [in] linesize input linesizes (pointer to array)
2938 * [in] set_linesize setup linesizes 0 means not setup linesizes, 1 means setup linesizes (before encoder open)
2939 *
2940 * \return on success and can do zero copy
2941 * NI_RETCODE_SUCCESS
2942 *
2943 * cannot do zero copy
2944 * NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
2945 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
2946 * NI_RETCODE_INVALID_PARAM
2947 *
2948*******************************************************************************/
2950 ni_xcoder_params_t *p_enc_params,
2951 int width, int height,
2952 const int linesize[],
2953 bool set_linesize)
2954{
2955 // check pixel format / width / height / linesize can be supported
2956 if ((!p_enc_ctx) || (!p_enc_params) || (!linesize)
2957 || (linesize[0]<=0)
2958 || (width>NI_MAX_RESOLUTION_WIDTH) || (width<=0)
2959 || (height>NI_MAX_RESOLUTION_HEIGHT) || (height<=0))
2960 {
2961 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s passed parameters are null or not supported, "
2962 "p_enc_ctx %p, p_enc_params %p, linesize %p, "
2963 "width %d, height %d linesize[0] %d\n",
2964 __func__, p_enc_ctx, p_enc_params, linesize,
2965 width, height, (linesize) ? linesize[0] : 0);
2967 }
2968
2969 // check fw revision (if fw_rev has been populated in open session)
2972 "6Q") < 0))
2973 {
2974 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: not supported on device with FW API version < 6.Q\n", __func__);
2976 }
2977
2978 if (p_enc_params->useMCTF) // skip zero copy if MCTF enabled
2980
2981 bool isrgba = false;
2982 bool isplanar = false;
2983 bool issemiplanar = false;
2984
2985 switch (p_enc_ctx->pixel_format)
2986 {
2987 case NI_PIX_FMT_YUV420P:
2989 isplanar = true;
2990 break;
2991 case NI_PIX_FMT_NV12:
2992 case NI_PIX_FMT_P010LE:
2993 issemiplanar = true;
2994 break;
2995 case NI_PIX_FMT_ABGR:
2996 case NI_PIX_FMT_ARGB:
2997 case NI_PIX_FMT_RGBA:
2998 case NI_PIX_FMT_BGRA:
2999 isrgba = true;
3000 break;
3001 default:
3002 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: pixel_format %d not supported\n", __func__);
3004 }
3005
3006 // check fw revision (if fw_rev has been populated in open session)
3007 if (issemiplanar &&
3010 "6q") < 0))
3011 {
3012 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: semi-planar not supported on device with FW API version < 6.q\n", __func__);
3014 }
3015
3016 // check zero copy compatibilty and set linesize
3017 if (p_enc_params->zerocopy_mode) // always allow zero copy for RGBA, because RGBA pixel format data copy currently not supported
3018 {
3019 if (set_linesize)
3020 {
3021 bool ishwframe = (p_enc_params->hwframes) ? true : false;
3022 int max_linesize = isrgba ? (NI_MAX_RESOLUTION_RGBA_WIDTH*4) : NI_MAX_RESOLUTION_LINESIZE;
3023 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s isrgba %u issemiplanar %u, ishwframe %u, "
3024 "p_enc_ctx %p, p_enc_params %p, linesize %p, "
3025 "width %d, height %d, linesize[0] %d linesize[1] %d\n",
3026 __func__, isrgba, issemiplanar, ishwframe, p_enc_ctx, p_enc_params, linesize,
3027 width, height, linesize[0], linesize[1]);
3028
3029 if (linesize[0] <= max_linesize &&
3030 linesize[0] % 2 == 0 && //even stride
3031 linesize[1] % 2 == 0 && //even stride
3032 width % 2 == 0 && //even width
3033 height % 2 == 0 && //even height
3034 (!p_enc_params->enable_ai_enhance || width % 128 == 0) && // align for AI engine
3035 width >= NI_MIN_WIDTH &&
3036 height >= NI_MIN_HEIGHT &&
3037 !ishwframe &&
3038 (!isplanar || linesize[2] == linesize[1]) // for planar, make sure cb linesize equal to cr linesize
3039 )
3040 {
3041 // send luma / chorma linesize to device (device is also aware frame will not be padded for 2-pass workaround)
3042 p_enc_params->luma_linesize = linesize[0];
3043 p_enc_params->chroma_linesize = (isrgba) ? 0 : linesize[1]; // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format
3044 return NI_RETCODE_SUCCESS;
3045 }
3046 else
3047 {
3048 p_enc_params->luma_linesize = 0;
3049 p_enc_params->chroma_linesize = 0;
3050 }
3051 }
3052 else if (p_enc_params->luma_linesize ||
3053 p_enc_params->chroma_linesize)
3054 {
3055 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s "
3056 "luma_linesize %d, chroma_linesize %d, "
3057 "linesize[0] %d, linesize[1] %d\n",
3058 __func__, p_enc_params->luma_linesize, p_enc_params->chroma_linesize,
3059 linesize[0], linesize[1]);
3060 if (p_enc_params->luma_linesize != linesize[0] ||
3061 (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
3062 )
3063 {
3064#ifndef XCODER_311
3065 // linesizes can change during SW frame seqeunce change transcoding when FFmpeg noautoscale option is not set
3066 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: linesize changed from %u %u to %u %u - resolution change?\n", __func__,
3067 p_enc_params->luma_linesize, p_enc_params->chroma_linesize,
3068 linesize[0], linesize[1]);
3069#endif
3070 }
3071 else
3072 return NI_RETCODE_SUCCESS;
3073 }
3074 }
3075
3077}
3078
3079/*!*****************************************************************************
3080 * \brief Check if the frame data transferred is within a frame boundary and
3081 * adjust with offset if it doesn't. EP will re-adjust the data pointer
3082 * to the correct start address.
3083 *
3084 * \param[in] video_height Height of the video frame after filtering
3085 * [in] linesize Picture line size after filtering (i.e. cropping)
3086 * [in] data Picture data pointers after filtering (for each of YUV planes)
3087 * [in] buf_size0 Y frame size before any filtering (original size)
3088 * [in] buf_size1 U frame size before any filtering (original)
3089 * [in] buf_size2 V frame size before any filtering (original)
3090 * [in] buf_data0 Y picture data pointer before any filtering (original)
3091 * [in] buf_data1 U picture data pointer before any filtering (original)
3092 * [in] buf_data2 V picture data pointer before any filtering (original)
3093 *
3094 * \return On success
3095 * NI_RETCODE_SUCCESS
3096 * On failure
3097 * NI_RETCODE_INVALID_PARAM
3098 *****************************************************************************/
3100 ni_session_context_t *p_enc_ctx,
3101 ni_frame_t *p_frame, int video_height,
3102 const int linesize[], const uint8_t *data[],
3103 int buf_size0, int buf_size1, int buf_size2,
3104 uint8_t *buf_data0, uint8_t *buf_data1, uint8_t *buf_data2)
3105{
3106 int retval = NI_RETCODE_SUCCESS;
3107
3108 if (!p_frame || !p_enc_ctx || !data || !linesize)
3109 {
3110 ni_log(NI_LOG_ERROR, "ERROR: %s: null parameters: p_frame=%p, p_enc_ctx=%p, linesize=%p, data=%p\n",
3111 __func__, p_frame, p_enc_ctx, linesize, data);
3113 }
3114
3115 // Only newer firmware versions (6sU and above) support zero-copy with SW cropping corner
3116 // case handling. See the brief of this function.
3117 if (ni_cmp_fw_api_ver((char*)&p_enc_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sU") < 0)
3118 {
3119 p_frame->hor_adjust_offset = 0;
3120 return NI_RETCODE_SUCCESS;
3121 }
3122
3123 const uint8_t *buf_data[3] = { buf_data0, buf_data1, buf_data2 };
3124 const int buf_size[3] = { buf_size0, buf_size1, buf_size2 };
3125 const uint8_t *end_used, *end_alloc;
3126 int offset = 0;
3127 int i;
3128
3129 // num_planes = 1 if frame is directly from quadra decoder (out=sw) or from raw YUV file
3130 // num_planes = actual number of planes if frame is from ffmpeg SW decoder or after ffmpeg
3131 // pixel format conversion or after hwdownload from quadra decoder (out=hw)
3132 const int num_planes = (buf_size[2] != 0) ? 3 : (buf_size[1] != 0) ? 2 : 1;
3133
3134 // In case of num_planes==1, only index 0 of buf_data[] and buf_size[] exist,
3135 // but all 3 indices of data[] and linesize[] are available for yuv420p and 2 for nv12.
3136 // The same applies to both 8 and 10 bit pixel formats
3137 for (i = 0; i < num_planes; i++)
3138 {
3139 if (!data[i] || !buf_data[i] || buf_size[i] <= 0)
3140 {
3141 ni_log(NI_LOG_ERROR, "ERROR: %s: invalid parameter %d: data=%p, buf_data=%p, size=%d\n",
3142 __func__, i, data[i], buf_data[i], buf_size[i]);
3144 }
3145
3146 int plane_height = video_height >> (i > 0 ? 1 : 0);
3147
3148 // End of used data after filtering (e.g., cropping)
3149 if(num_planes == 1)
3150 {
3151 // Find end address used by last plane since it can reach the end of the buffer and buf_data[0] contains all YUV
3152 if (data[2])
3153 {
3154 // Planar pixel format if 3 data pointers are present
3155 end_used = data[2] + (ptrdiff_t)linesize[2] * (video_height >> 1);
3156 }
3157 else if (data[1])
3158 {
3159 // Semiplanar pixel format if only 2 data pointers are present
3160 end_used = data[1] + (ptrdiff_t)linesize[1] * (video_height >> 1);
3161 }
3162 else
3163 {
3164 ni_log(NI_LOG_ERROR, "ERROR: %s: Single-plane pixel format not supported\n", __func__);
3166 }
3167 }
3168 else
3169 {
3170 // Find Y, U, and V end address used
3171 end_used = data[i] + (ptrdiff_t)linesize[i] * plane_height;
3172 }
3173
3174 // End address of original allocated buffer.
3175 end_alloc = buf_data[i] + buf_size[i];
3176
3177 // Positive offset means filtered data to be transferred by zerocopy exceeds original buffer
3178 int plane_offset = (int)(end_used - end_alloc);
3179 plane_offset = (plane_offset > 0) ? plane_offset : 0;
3180
3181 if(num_planes == 1)
3182 {
3183 if (data[2])
3184 {
3185 offset = plane_offset * 2;
3186 ((uint8_t **)data)[0] -= offset;
3187 ((uint8_t **)data)[1] -= plane_offset;
3188 ((uint8_t **)data)[2] -= plane_offset;
3189 }
3190 else
3191 {
3192 offset = plane_offset;
3193 ((uint8_t **)data)[0] -= plane_offset;
3194 ((uint8_t **)data)[1] -= plane_offset;
3195 }
3196 }
3197 else
3198 {
3199 ((uint8_t **)data)[i] -= plane_offset;
3200 if (i == 0)
3201 {
3202 offset = plane_offset;
3203 }
3204 }
3205
3206 ni_log(NI_LOG_DEBUG, "%s: plane %d offset %d\n", __func__, i, offset);
3207 }
3208
3209 p_frame->hor_adjust_offset = offset;
3210
3211 return retval;
3212}
3213
3214/*!*****************************************************************************
3215 * \brief Allocate memory for encoder zero copy (metadata, etc.)
3216 * for encoding based on given
3217 * parameters, taking into account pic linesize and extra data.
3218 * Applicable to YUV planr / semi-planar 8 or 10 bit and RGBA pixel formats.
3219 *
3220 *
3221 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3222 * \param[in] video_width Width of the video frame
3223 * \param[in] video_height Height of the video frame
3224 * \param[in] linesize Picture line size
3225 * \param[in] data Picture data pointers (for each of YUV planes)
3226 * \param[in] extra_len Extra data size (incl. meta data)
3227 *
3228 * \return On success
3229 * NI_RETCODE_SUCCESS
3230 * On failure
3231 * NI_RETCODE_INVALID_PARAM
3232 * NI_RETCODE_ERROR_MEM_ALOC
3233 *****************************************************************************/
3235 int video_width, int video_height,
3236 const int linesize[], const uint8_t *data[],
3237 int extra_len)
3238{
3239 int retval = NI_RETCODE_SUCCESS;
3240
3241 if ((!p_frame) || (!linesize) || (!data))
3242 {
3243 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3244 "p_frame %p, linesize %p, data %p\n",
3245 __func__, p_frame, linesize, data);
3247 }
3248
3250 "%s: resolution=%dx%d linesize=%d/%d/%d "
3251 "data=%p %p %p extra_len=%d\n",
3252 __func__, video_width, video_height,
3253 linesize[0], linesize[1], linesize[2],
3254 data[0], data[1], data[2], extra_len);
3255
3256 if (p_frame->buffer_size)
3257 {
3258 p_frame->buffer_size = 0; //notify p_frame->p_buffer is not allocated
3259 ni_aligned_free(p_frame->p_buffer); // also free the temp p_buffer allocated for niFrameSurface1_t in encoder init stage
3260 }
3261
3262 p_frame->p_buffer = (uint8_t *)data[0];
3263 p_frame->p_data[0] = (uint8_t *)data[0];
3264 p_frame->p_data[1] = (uint8_t *)data[1];
3265 p_frame->p_data[2] = (uint8_t *)data[2];
3266
3267 int luma_size = linesize[0] * video_height;
3268 int chroma_b_size = 0;
3269 int chroma_r_size = 0;
3270
3271 // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format, but only data[0] pointer is populated
3272 if (data[1]) // cb size is 0 for RGBA pixel format
3273 chroma_b_size = linesize[1] * (video_height / 2);
3274
3275 if (data[2]) // cr size is 0 for semi-planar or RGBA pixel format
3276 chroma_r_size = linesize[2] * (video_height / 2);
3277
3278 //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);
3279
3280 uint32_t start_offset;
3281 uint32_t total_start_len = 0;
3282 int i;
3283
3284 p_frame->inconsecutive_transfer = 0;
3285
3286 // rgba has one data pointer, semi-planar has two data pointers
3287 if ((data[1] && (data[0] + luma_size != data[1]))
3288 || (data[2] && (data[1] + chroma_b_size != data[2])))
3289 {
3290 p_frame->inconsecutive_transfer = 1;
3291 }
3292
3293 if (p_frame->inconsecutive_transfer)
3294 {
3295 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
3296 {
3297 start_offset = (uintptr_t)p_frame->p_data[i] % NI_MEM_PAGE_ALIGNMENT;
3298 p_frame->start_len[i] = start_offset ? (NI_MEM_PAGE_ALIGNMENT - start_offset) : 0;
3299 total_start_len += p_frame->start_len[i];
3300 }
3301 }
3302 else
3303 {
3304 start_offset = (uintptr_t)p_frame->p_data[0] % NI_MEM_PAGE_ALIGNMENT;
3305 p_frame->start_len[0] = start_offset ? (NI_MEM_PAGE_ALIGNMENT - start_offset) : 0;
3306 p_frame->start_len[1] = p_frame->start_len[2] = 0;
3307 total_start_len = p_frame->start_len[0];
3308 }
3309 p_frame->total_start_len = total_start_len;
3310
3311 if (ni_encoder_metadata_buffer_alloc(p_frame, extra_len))
3312 {
3313 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_metadata_buffer buffer.\n",
3314 NI_ERRNO, __func__);
3316 LRETURN;
3317 }
3318 p_frame->separate_metadata = 1;
3319
3320 if (total_start_len)
3321 {
3322 if (ni_encoder_start_buffer_alloc(p_frame))
3323 {
3324 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_start_buffer buffer.\n",
3325 NI_ERRNO, __func__);
3327 LRETURN;
3328 }
3329 p_frame->separate_start = 1;
3330
3331 // copy non-4k-aligned part at the start of YUV data
3332 int start_buffer_offset = 0;
3333 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
3334 {
3335 if (p_frame->p_data[i])
3336 {
3337 memcpy(p_frame->p_start_buffer+start_buffer_offset, p_frame->p_data[i],
3338 p_frame->start_len[i]);
3339 start_buffer_offset += (int)p_frame->start_len[i];
3340 }
3341 }
3342 }
3343
3344 p_frame->data_len[0] = luma_size;
3345 p_frame->data_len[1] = chroma_b_size;
3346 p_frame->data_len[2] = chroma_r_size;
3347 p_frame->data_len[3] = 0;//unused by hwdesc
3348
3349 p_frame->video_width = video_width;
3350 p_frame->video_height = video_height;
3351
3353 "%s: success: p_metadata_buffer %p metadata_buffer_size %u "
3354 "p_start_buffer %p start_buffer_size %u data_len %u %u %u\n",
3355 __func__, p_frame->p_metadata_buffer, p_frame->metadata_buffer_size,
3356 p_frame->p_start_buffer, p_frame->start_buffer_size,
3357 p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2]);
3358
3359END:
3360
3361 return retval;
3362}
3363
3364
3365/*!*****************************************************************************
3366 * \brief Check if incoming frame is hwupload zero copy compatible or not
3367 *
3368 * \param[in] p_upl_ctx pointer to uploader context
3369 * [in] width input width
3370 * [in] height input height
3371 * [in] linesize input linesizes (pointer to array)
3372 * [in] pixel_format input pixel format
3373 *
3374 * \return on success and can do zero copy
3375 * NI_RETCODE_SUCCESS
3376 *
3377 * cannot do zero copy
3378 * NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
3379 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
3380 * NI_RETCODE_INVALID_PARAM
3381 *
3382*******************************************************************************/
3384 int width, int height,
3385 const int linesize[], int pixel_format)
3386{
3387 // check pixel format / width / height / linesize can be supported
3388 if ((!p_upl_ctx) || (!linesize)
3389 || (linesize[0]<=0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3390 || (width>NI_MAX_RESOLUTION_WIDTH) || (width<=0)
3391 || (height>NI_MAX_RESOLUTION_HEIGHT) || (height<=0))
3392 {
3393 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s passed parameters are null or not supported, "
3394 "p_enc_ctx %p, linesize %p, "
3395 "width %d, height %d linesize[0] %d\n",
3396 __func__, p_upl_ctx, linesize,
3397 width, height, (linesize) ? linesize[0] : 0);
3399 }
3400
3401 // check fw revision (if fw_rev has been populated in open session)
3404 "6S") < 0))
3405 {
3406 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: not supported on device with FW API version < 6.S\n", __func__);
3408 }
3409
3410 // upload does not have zeroCopyMode parameter, currently only allows resolution >= 1080p
3411 if ((width * height) < NI_NUM_OF_PIXELS_1080P)
3413
3414 // check zero copy compatibilty
3415 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s pixel_format %d "
3416 "p_upl_ctx %p, linesize %p, "
3417 "width %d, height %d, linesize[0] %d\n",
3418 __func__, pixel_format, p_upl_ctx, linesize,
3419 width, height, linesize[0]);
3420
3421 int bit_depth_factor;
3422 bool isrgba = false;
3423 bool isplanar = false;
3424 bool issemiplanar = false;
3425
3426 switch (pixel_format)
3427 {
3428 case NI_PIX_FMT_YUV420P:
3429 isplanar = true;
3430 bit_depth_factor = 1;
3431 break;
3433 isplanar = true;
3434 bit_depth_factor = 2;
3435 break;
3436 case NI_PIX_FMT_NV12:
3437 issemiplanar = true;
3438 bit_depth_factor = 1;
3439 break;
3440 case NI_PIX_FMT_P010LE:
3441 issemiplanar = true;
3442 bit_depth_factor = 2;
3443 break;
3444 case NI_PIX_FMT_ABGR:
3445 case NI_PIX_FMT_ARGB:
3446 case NI_PIX_FMT_RGBA:
3447 case NI_PIX_FMT_BGRA:
3448 isrgba = true;
3449 bit_depth_factor = 4; // not accurate, only for linesize check
3450 break;
3451 default:
3452 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: pixel_format %d not supported\n", __func__);
3454 }
3455
3456 // check fw revision (if fw_rev has been populated in open session)
3457 if (issemiplanar &&
3460 "6q") < 0))
3461 {
3462 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: semi-planar not supported on device with FW API version < 6.q\n", __func__);
3464 }
3465
3466 int max_linesize = isrgba ? (NI_MAX_RESOLUTION_RGBA_WIDTH*4) : NI_MAX_RESOLUTION_LINESIZE;
3467 if (linesize[0] <= max_linesize &&
3468 width % 2 == 0 && //even width
3469 height % 2 == 0 && //even height
3470 width >= NI_MIN_WIDTH && height >= NI_MIN_HEIGHT)
3471 {
3472 // yuv only support default 128 bytes aligned linesize, because downstream filter or encoder expect HW frame 128 bytes aligned
3473 if (isplanar &&
3474 linesize[0] == NI_VPU_ALIGN128(width * bit_depth_factor) &&
3475 linesize[1] == NI_VPU_ALIGN128(width * bit_depth_factor / 2) &&
3476 linesize[2] == linesize[1])
3477 return NI_RETCODE_SUCCESS;
3478
3479 // yuv only support default 128 bytes aligned linesize, because downstream filter or encoder expect HW frame 128 bytes aligned
3480 if (issemiplanar &&
3481 linesize[0] == NI_VPU_ALIGN128(width * bit_depth_factor) &&
3482 linesize[1] == linesize[0])
3483 return NI_RETCODE_SUCCESS;
3484
3485 // rgba only support 64 bytes aligned for 2D
3486 if (isrgba &&
3487 linesize[0] == NI_VPU_ALIGN64(width * bit_depth_factor))
3488 return NI_RETCODE_SUCCESS;
3489 }
3490
3492}
3493
3494/*!*****************************************************************************
3495 * \brief Allocate memory for the frame buffer for encoding based on given
3496 * parameters, taking into account pic line size and extra data.
3497 * Applicable to YUV420p AVFrame only. 8 or 10 bit/pixel.
3498 * Cb/Cr size matches that of Y.
3499 *
3500 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3501 *
3502 * \param[in] video_width Width of the video frame
3503 * \param[in] video_height Height of the video frame
3504 * \param[in] linesize Picture line size
3505 * \param[in] alignment Allignment requirement
3506 * \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3507 * to allocate any buffer (zero-copy from existing)
3508 * \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3509 *
3510 * \return On success
3511 * NI_RETCODE_SUCCESS
3512 * On failure
3513 * NI_RETCODE_INVALID_PARAM
3514 * NI_RETCODE_ERROR_MEM_ALOC
3515 *****************************************************************************/
3517 int video_height, int linesize[],
3518 int alignment, int extra_len,
3519 bool alignment_2pass_wa)
3520{
3521 void* p_buffer = NULL;
3522 int height_aligned;
3523 int retval = NI_RETCODE_SUCCESS;
3524
3525 if ((!p_frame) || (!linesize) || (linesize[0]<=0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3526 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
3527 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
3528 {
3529 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3530 "p_frame %p, linesize %p, video_width %d, video_height %d\n",
3531 __func__, p_frame, linesize, video_width, video_height);
3533 }
3534
3535 if (QUADRA)
3536 {
3537 height_aligned = ((video_height + 1) / 2) * 2;
3538 } else
3539 {
3540 height_aligned = ((video_height + 7) / 8) * 8;
3541
3542 if (alignment)
3543 {
3544 height_aligned = ((video_height + 15) / 16) * 16;
3545 }
3546 }
3547 if (height_aligned < NI_MIN_HEIGHT)
3548 {
3549 height_aligned = NI_MIN_HEIGHT;
3550 }
3551
3553 "%s: aligned=%dx%d org=%dx%d linesize=%d/%d/%d "
3554 "extra_len=%d\n",
3555 __func__, video_width, height_aligned, video_width, video_height,
3556 linesize[0], linesize[1], linesize[2], extra_len);
3557
3558 int luma_size = linesize[0] * height_aligned;
3559 int chroma_b_size;
3560 int chroma_r_size;
3561 if (QUADRA)
3562 {
3563 chroma_b_size = chroma_r_size = linesize[1] * (height_aligned / 2);
3564 if (alignment_2pass_wa)
3565 {
3566 // for 2-pass encode output mismatch WA, need to extend (and pad) Cr plane height, because 1st pass assume input 32 align
3567 chroma_r_size = linesize[1] * (((height_aligned + 31) / 32) * 32) / 2;
3568 }
3569 //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);
3570 }
3571 else
3572 {
3573 chroma_b_size = luma_size / 4;
3574 chroma_r_size = luma_size / 4;
3575 }
3576 if(extra_len >= 0)
3577 {
3578 int buffer_size = luma_size + chroma_b_size + chroma_r_size + extra_len;
3579
3581
3582 //Check if Need to free
3583 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
3584 {
3586 "%s: free current p_frame, "
3587 "p_frame->buffer_size=%u\n",
3588 __func__, p_frame->buffer_size);
3589 ni_frame_buffer_free(p_frame);
3590 }
3591
3592 //Check if need to realocate
3593 if (p_frame->buffer_size != buffer_size)
3594 {
3595 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3596 {
3597 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
3598 NI_ERRNO, __func__);
3600 LRETURN;
3601 }
3602
3603 // init once after allocation
3604 memset(p_buffer, 0, buffer_size);
3605 p_frame->buffer_size = buffer_size;
3606 p_frame->p_buffer = p_buffer;
3607
3608 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
3609 }
3610 else
3611 {
3612 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
3613 }
3614 p_frame->p_data[0] = (uint8_t*)p_frame->p_buffer;
3615 p_frame->p_data[1] = (uint8_t*)p_frame->p_data[0] + luma_size;
3616 p_frame->p_data[2] = (uint8_t*)p_frame->p_data[1] + chroma_b_size;
3617 }
3618 else
3619 {
3620 p_frame->buffer_size = 0; //no ownership
3621 }
3622
3623 p_frame->data_len[0] = luma_size;
3624 p_frame->data_len[1] = chroma_b_size;
3625 p_frame->data_len[2] = chroma_r_size;
3626 p_frame->data_len[3] = 0;//unused by hwdesc
3627
3628 p_frame->video_width = video_width;
3629 p_frame->video_height = height_aligned;
3630
3632 "%s: success: p_frame->p_buffer %p "
3633 "p_frame->buffer_size=%u\n",
3634 __func__, p_frame->p_buffer, p_frame->buffer_size);
3635
3636END:
3637
3638 if (NI_RETCODE_SUCCESS != retval)
3639 {
3640 ni_aligned_free(p_buffer);
3641 }
3642
3643 return retval;
3644}
3645
3646/*!*****************************************************************************
3647 * \brief allocate device destination frame from scaler hwframe pool
3648 *
3649 * \param
3650 *
3651 * \return 0 if successful, < 0 otherwise
3652 ******************************************************************************/
3654 ni_scaler_input_params_t scaler_params,
3655 niFrameSurface1_t *p_surface)
3656{
3657 int ret = 0;
3658 if (scaler_params.op != NI_SCALER_OPCODE_OVERLAY && scaler_params.op != NI_SCALER_OPCODE_WATERMARK)
3659 {
3661 p_ctx, scaler_params.output_width, scaler_params.output_height,
3662 scaler_params.output_format, NI_SCALER_FLAG_IO | scaler_params.out_extra_flags,
3663 scaler_params.out_rec_width, scaler_params.out_rec_height,
3664 scaler_params.out_rec_x, scaler_params.out_rec_y,
3665 (int)scaler_params.rgba_color, -1, NI_DEVICE_TYPE_SCALER);
3666 } else
3667 {
3668 // in vf_overlay_ni.c: flags = (s->alpha_format ? NI_SCALER_FLAG_PA : 0) | NI_SCALER_FLAG_IO;
3670 p_ctx, scaler_params.output_width, scaler_params.output_height,
3671 scaler_params.output_format, NI_SCALER_FLAG_IO | scaler_params.out_extra_flags,
3672 scaler_params.out_rec_width, scaler_params.out_rec_height,
3673 scaler_params.out_rec_x, scaler_params.out_rec_y,
3674 (int)p_surface->ui32nodeAddress, (int)p_surface->ui16FrameIdx, // NOLINT(bugprone-narrowing-conversions)
3676 }
3677 return ret;
3678}
3679
3680/*!*****************************************************************************
3681 * \brief allocate device input frame by hw descriptor. This call won't actually allocate
3682 a frame but sends the incoming hardware frame index to the scaler manager
3683 *
3684 * \param
3685 *
3686 * \return 0 if successful, < 0 otherwise
3687 ******************************************************************************/
3689 ni_scaler_input_params_t scaler_params,
3690 niFrameSurface1_t *p_src_surface)
3691{
3692 int ret = 0;
3693
3694 /* BT.2020 not supported on scaler input */
3695 if (scaler_params.in_extra_flags & NI_SCALER_FLAG_CS)
3697
3699 p_ctx, scaler_params.input_width, scaler_params.input_height,
3700 scaler_params.input_format, scaler_params.in_extra_flags, scaler_params.in_rec_width,
3701 scaler_params.in_rec_height, scaler_params.in_rec_x,
3702 (int)scaler_params.in_rec_y, (int)p_src_surface->ui32nodeAddress, // NOLINT(bugprone-narrowing-conversions)
3703 p_src_surface->ui16FrameIdx, NI_DEVICE_TYPE_SCALER);
3704 return ret;
3705}
3706
3707/*!*****************************************************************************
3708 * \brief init output pool of scaler frames
3709 *
3710 * \param
3711 *
3712 * \return 0 if successful, < 0 otherwise
3713 ******************************************************************************/
3715 ni_scaler_input_params_t scaler_params)
3716{
3717 int rc = 0;
3718 int options = NI_SCALER_FLAG_IO | NI_SCALER_FLAG_PC;
3719 if (p_ctx->isP2P)
3720 options |= NI_SCALER_FLAG_P2;
3721
3722 /* Allocate a pool of frames by the scaler */
3723 rc = ni_device_alloc_frame(p_ctx, scaler_params.output_width,
3724 scaler_params.output_height,
3725 scaler_params.output_format, options,
3726 0, // rec width
3727 0, // rec height
3728 0, // rec X pos
3729 0, // rec Y pos
3730 NI_MAX_FILTER_POOL_SIZE, // rgba color/pool size
3731 0, // frame index
3733 return rc;
3734}
3735
3736/*!*****************************************************************************
3737* \brief Allocate memory for the frame buffer based on provided parameters
3738* taking into account pic line size and extra data.
3739* Applicable to nv12 AVFrame only. Cb/Cr size matches that of Y.
3740*
3741* \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3742*
3743* \param[in] video_width Width of the video frame
3744* \param[in] video_height Height of the video frame
3745* \param[in] linesize Picture line size
3746* \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3747* to allocate any buffer (zero-copy from existing)
3748* \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3749*
3750* \return On success
3751* NI_RETCODE_SUCCESS
3752* On failure
3753* NI_RETCODE_INVALID_PARAM
3754* NI_RETCODE_ERROR_MEM_ALOC
3755*****************************************************************************/
3757 int video_height, int linesize[],
3758 int extra_len, bool alignment_2pass_wa)
3759{
3760 void* p_buffer = NULL;
3761 int height_aligned;
3762 int retval = NI_RETCODE_SUCCESS;
3763
3764 if ((!p_frame) || (!linesize) || (linesize[0] <= 0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3765 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width <= 0)
3766 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height <= 0))
3767 {
3768 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3769 "p_frame %p, linesize %p, video_width %d, video_height %d\n",
3770 __func__, p_frame, linesize, video_width, video_height);
3772 }
3773
3774 height_aligned = ((video_height + 1) / 2) * 2;
3775
3776 if (height_aligned < NI_MIN_HEIGHT)
3777 {
3778 height_aligned = NI_MIN_HEIGHT;
3779 }
3780
3782 "%s: aligned=%dx%d org=%dx%d linesize=%d/%d/%d extra_len=%d\n",
3783 __func__, video_width, height_aligned, video_width, video_height,
3784 linesize[0], linesize[1], linesize[2], extra_len);
3785
3786 int luma_size = linesize[0] * height_aligned;
3787 int chroma_br_size = luma_size / 2;
3788 //int chroma_r_size = luma_size / 4;
3789 if (alignment_2pass_wa)
3790 {
3791 // for 2-pass encode output mismatch WA, need to extend (and pad) CbCr plane height, because 1st pass assume input 32 align
3792 chroma_br_size = linesize[0] * ((((height_aligned + 31) / 32) * 32) / 2);
3793 }
3794 if (extra_len >= 0)
3795 {
3796 int buffer_size = luma_size + chroma_br_size + extra_len;
3797
3799
3800 //Check if Need to free
3801 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
3802 {
3803 ni_log(NI_LOG_DEBUG, "%s: free current p_frame->buffer_size=%u\n",
3804 __func__, p_frame->buffer_size);
3805 ni_frame_buffer_free(p_frame);
3806 }
3807
3808 //Check if need to realocate
3809 if (p_frame->buffer_size != buffer_size)
3810 {
3811 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3812 {
3813 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
3814 NI_ERRNO, __func__);
3816 LRETURN;
3817 }
3818
3819 // init once after allocation
3820 memset(p_buffer, 0, buffer_size);
3821 p_frame->buffer_size = buffer_size;
3822 p_frame->p_buffer = p_buffer;
3823
3824 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
3825 }
3826 else
3827 {
3828 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
3829 }
3830
3831 p_frame->p_data[0] = (uint8_t*)p_frame->p_buffer;
3832 p_frame->p_data[1] = (uint8_t*)p_frame->p_data[0] + luma_size;
3833 p_frame->p_data[2] = (uint8_t*)p_frame->p_data[1] + chroma_br_size;
3834 }
3835 else
3836 {
3837 p_frame->buffer_size = 0; //no ownership
3838 }
3839 p_frame->data_len[0] = luma_size;
3840 p_frame->data_len[1] = chroma_br_size;
3841 p_frame->data_len[2] = 0;
3842
3843 p_frame->video_width = video_width;
3844 p_frame->video_height = height_aligned;
3845
3846 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
3847 p_frame->buffer_size);
3848
3849END:
3850
3851 if (NI_RETCODE_SUCCESS != retval)
3852 {
3853 ni_aligned_free(p_buffer);
3854 }
3855
3856 return retval;
3857}
3858
3859/*!*****************************************************************************
3860 * \brief This API is a wrapper for ni_encoder_frame_buffer_alloc(), used
3861 * for planar pixel formats, and ni_frame_buffer_alloc_nv(), used for
3862 * semi-planar pixel formats. This API is meant to combine the
3863 * functionality for both individual format APIs.
3864 * Allocate memory for the frame buffer for encoding based on given
3865 * parameters, taking into account pic line size and extra data.
3866 * Applicable to YUV420p(8 or 10 bit/pixel) or nv12 AVFrame.
3867 * Cb/Cr size matches that of Y.
3868 *
3869 * \param[in] planar true: if planar:
3870 * pixel_format == (NI_PIX_FMT_YUV420P ||
3871 * NI_PIX_FMT_YUV420P10LE ||NI_PIX_FMT_RGBA).
3872 * false: semi-planar:
3873 * pixel_format == (NI_PIX_FMT_NV12 ||
3874 * NI_PIX_FMT_P010LE).
3875 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3876 * \param[in] video_width Width of the video frame
3877 * \param[in] video_height Height of the video frame
3878 * \param[in] linesize Picture line size
3879 * \param[in] alignment Allignment requirement. Only used for planar format.
3880 * \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3881 * to allocate any buffer (zero-copy from existing)
3882 * \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3883 *
3884 * \return On success
3885 * NI_RETCODE_SUCCESS
3886 * On failure
3887 * NI_RETCODE_INVALID_PARAM
3888 * NI_RETCODE_ERROR_MEM_ALOC
3889 *****************************************************************************/
3891 int video_width, int video_height,
3892 int linesize[], int alignment,
3893 int extra_len,
3894 bool alignment_2pass_wa)
3895{
3896 if (true == planar)
3897 {
3898 return ni_encoder_frame_buffer_alloc(p_frame, video_width, video_height,
3899 linesize, alignment, extra_len,
3900 alignment_2pass_wa);
3901 }
3902 else
3903 {
3904 return ni_frame_buffer_alloc_nv(p_frame, video_width, video_height,
3905 linesize, extra_len,
3906 alignment_2pass_wa);
3907 }
3908}
3909
3910/*!*****************************************************************************
3911 * \brief Free frame buffer that was previously allocated with either
3912 * ni_frame_buffer_alloc or ni_encoder_frame_buffer_alloc or
3913 * ni_frame_buffer_alloc_nv
3914 *
3915 * \param[in] p_frame Pointer to a previously allocated ni_frame_t struct
3916 *
3917 * \return On success NI_RETCODE_SUCCESS
3918 * On failure NI_RETCODE_INVALID_PARAM
3919 ******************************************************************************/
3921{
3922 int i;
3924
3925 ni_log(NI_LOG_TRACE, "%s: enter\n", __func__);
3926
3927 if (!p_frame)
3928 {
3929 ni_log(NI_LOG_DEBUG, "WARN: %s(): p_frame is NULL\n", __func__);
3930 LRETURN;
3931 }
3932
3933 if (!p_frame->p_buffer)
3934 {
3935 ni_log(NI_LOG_DEBUG, "WARN: %s(): already freed, nothing to free\n",
3936 __func__);
3937 }
3938
3939#ifndef _WIN32
3940 // If this is a hardware frame with a DMA buf fd attached, close the DMA buf fd
3941 if ((p_frame->data_len[3] > 0) && (p_frame->p_data[3] != NULL))
3942 {
3943 niFrameSurface1_t *p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
3944 if ((p_surface->dma_buf_fd > 0) && (p_surface->ui16FrameIdx > 0))
3945 {
3946 // Close the DMA buf fd
3948 "%s: close p_surface->dma_buf_fd %d "
3949 "ui16FrameIdx %u\n",
3950 __func__, p_surface->dma_buf_fd, p_surface->ui16FrameIdx);
3951 (void)close(p_surface->dma_buf_fd);
3952 }
3953 }
3954#endif
3955
3956 if (p_frame->buffer_size)
3957 {
3958 p_frame->buffer_size = 0;
3959 ni_aligned_free(p_frame->p_buffer);
3960 }
3961
3962 for (i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
3963 {
3964 p_frame->data_len[i] = 0;
3965 p_frame->p_data[i] = NULL;
3966 }
3967
3968 ni_frame_wipe_aux_data(p_frame);
3969
3970 if (p_frame->metadata_buffer_size)
3971 {
3972 p_frame->metadata_buffer_size = 0;
3974 }
3975 p_frame->separate_metadata = 0;
3976
3977 if (p_frame->start_buffer_size)
3978 {
3979 p_frame->start_buffer_size = 0;
3981 }
3982 p_frame->separate_start = 0;
3983 memset(p_frame->start_len, 0, sizeof(p_frame->start_len));
3984 p_frame->total_start_len = 0;
3985 p_frame->inconsecutive_transfer = 0;
3986
3987END:
3988
3989 ni_log(NI_LOG_TRACE, "%s: exit\n", __func__);
3990
3991 return retval;
3992}
3993
3994/*!*****************************************************************************
3995 * \brief Free decoder frame buffer that was previously allocated with
3996 * ni_decoder_frame_buffer_alloc, returning memory to a buffer pool.
3997 *
3998 * \param[in] p_frame Pointer to a previously allocated ni_frame_t struct
3999 *
4000 * \return On success NI_RETCODE_SUCCESS
4001 * On failure NI_RETCODE_INVALID_PARAM
4002 ******************************************************************************/
4004{
4005 int i;
4007
4008 ni_log(NI_LOG_TRACE, "%s: enter\n", __func__);
4009
4010 if (!p_frame)
4011 {
4012 ni_log(NI_LOG_DEBUG, "WARN: %s(): p_frame is NULL\n", __func__);
4013 retval = NI_RETCODE_INVALID_PARAM;
4014 LRETURN;
4015 }
4016
4017 if (p_frame->dec_buf)
4018 {
4020 ni_log(NI_LOG_DEBUG, "%s(): Mem buf returned ptr %p buf %p !\n", __func__,
4021 p_frame->dec_buf->buf, p_frame->dec_buf);
4022 }
4023 else
4024 {
4025 ni_log(NI_LOG_DEBUG, "%s(): NO mem buf returned !\n", __func__);
4026 }
4027
4028 p_frame->dec_buf = NULL;
4029 p_frame->p_buffer = NULL;
4030 p_frame->buffer_size = 0;
4031 for (i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
4032 {
4033 p_frame->data_len[i] = 0;
4034 p_frame->p_data[i] = NULL;
4035 }
4036 ni_frame_wipe_aux_data(p_frame);
4037
4038END:
4039
4040 ni_log(NI_LOG_TRACE, "%s: exit\n", __func__);
4041
4042 return retval;
4043}
4044
4045/*!*****************************************************************************
4046 * \brief Return a memory buffer to memory buffer pool.
4047 *
4048 * \param[in] buf Buffer to be returned.
4049 * \param[in] p_buffer_pool Buffer pool to return buffer to.
4050 *
4051 * \return None
4052 ******************************************************************************/
4054 ni_buf_pool_t *p_buffer_pool)
4055{
4056 ni_buf_pool_return_buffer(buf, p_buffer_pool);
4057}
4058
4059/*!*****************************************************************************
4060 * \brief Allocate memory for the packet buffer based on provided packet size
4061 *
4062 * \param[in] p_packet Pointer to a caller allocated
4063 * ni_packet_t struct
4064 * \param[in] packet_size Required allocation size
4065 *
4066 * \return On success
4067 * NI_RETCODE_SUCCESS
4068 * On failure
4069 * NI_RETCODE_INVALID_PARAM
4070 * NI_RETCODE_ERROR_MEM_ALOC
4071 ******************************************************************************/
4073{
4074 void* p_buffer = NULL;
4075 int metadata_size = 0;
4076
4077 metadata_size = NI_FW_META_DATA_SZ;
4078
4079 int buffer_size = (((packet_size + metadata_size) / NI_MAX_PACKET_SZ) + 1) * NI_MAX_PACKET_SZ;
4080
4081 ni_log(NI_LOG_TRACE, "%s: packet_size=%d\n", __func__,
4082 packet_size + metadata_size);
4083
4084 if (!p_packet || !packet_size)
4085 {
4086 ni_log(NI_LOG_ERROR, "ERROR: %s: null pointer parameters passed\n",
4087 __func__);
4089 }
4090
4091 if (buffer_size % NI_MEM_PAGE_ALIGNMENT)
4092 {
4093 buffer_size = ( (buffer_size / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT ) + NI_MEM_PAGE_ALIGNMENT;
4094 }
4095
4096 if (p_packet->buffer_size == buffer_size)
4097 {
4098 // Already allocated the exact size.
4099 p_packet->p_data = p_packet->p_buffer;
4100 ni_log(NI_LOG_DEBUG, "%s: reuse current p_packet buffer\n", __func__);
4101 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4102 p_packet->buffer_size);
4103 return NI_RETCODE_SUCCESS;
4104 }
4105
4106 if (p_packet->buffer_size)
4107 {
4109 "%s: free current p_packet, p_packet->buffer_size=%u\n", __func__,
4110 p_packet->buffer_size);
4111 ni_packet_buffer_free(p_packet);
4112 }
4113
4114 ni_log(NI_LOG_DEBUG, "%s: Allocating p_frame buffer, buffer_size=%d\n",
4115 __func__, buffer_size);
4116
4117 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
4118 {
4119 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_packet buffer.\n",
4120 NI_ERRNO, __func__);
4121 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4122 p_packet->buffer_size);
4124 }
4125
4126 p_packet->buffer_size = buffer_size;
4127 p_packet->p_buffer = p_buffer;
4128 p_packet->p_data = p_packet->p_buffer;
4129
4130 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4131 p_packet->buffer_size);
4132
4133 return NI_RETCODE_SUCCESS;
4134}
4135
4136/*!*****************************************************************************
4137 * \brief Allocate packet buffer using a user provided pointer, the memory
4138 * is expected to have already been allocated.
4139 *
4140 * For ideal performance memory should be 4k aligned. If it is not 4K aligned
4141 * then a temporary 4k aligned memory will be used to copy data to and from
4142 * when writing and reading. This will negatively impact performance.
4143 *
4144 * This API will overwrite p_packet->buffer_size, p_packet->p_buffer and
4145 * p_packet->p_data fields in p_packet.
4146 *
4147 * This API will not free any memory associated with p_packet->p_buffer and
4148 * p_packet->p_data fields in p_packet.
4149 * Common use case could be,
4150 * 1. Allocate memory to pointer
4151 * 2. Call ni_custom_packet_buffer_alloc() with allocated pointer.
4152 * 3. Use p_packet as required.
4153 * 4. Call ni_packet_buffer_free() to free up the memory.
4154 *
4155 * \param[in] p_buffer User provided pointer to be used for buffer
4156 * \param[in] p_packet Pointer to a caller allocated
4157 * ni_packet_t struct
4158 * \param[in] buffer_size Buffer size
4159 *
4160 * \return On success
4161 * NI_RETCODE_SUCCESS
4162 * On failure
4163 * NI_RETCODE_INVALID_PARAM
4164 * NI_RETCODE_ERROR_MEM_ALOC
4165 ******************************************************************************/
4167 ni_packet_t *p_packet,
4168 int buffer_size)
4169{
4170 ni_log(NI_LOG_TRACE, "%s(): enter buffer_size=%d\n", __func__, buffer_size);
4171
4172 if (!p_buffer || !p_packet || !buffer_size)
4173 {
4174 ni_log(NI_LOG_ERROR, "ERROR: %s: null pointer parameters passed\n",
4175 __func__);
4177 }
4178 if (((uintptr_t)p_buffer) % NI_MEM_PAGE_ALIGNMENT)
4179 {
4180 ni_log(NI_LOG_INFO, "Info: %s: Warning buffer not 4k aligned = %p!. Will do an extra copy\n",
4181 __func__, p_buffer);
4182 }
4183
4184 p_packet->buffer_size = buffer_size;
4185 p_packet->p_buffer = p_buffer;
4186 p_packet->p_data = p_packet->p_buffer;
4187
4188 ni_log(NI_LOG_TRACE, "%s: exit: \n", __func__);
4189
4190 return NI_RETCODE_SUCCESS;
4191}
4192
4193/*!*****************************************************************************
4194 * \brief Free packet buffer that was previously allocated with
4195 * ni_packet_buffer_alloc
4196 *
4197 * \param[in] p_packet Pointer to a previously allocated ni_packet_t struct
4198 *
4199 * \return On success NI_RETCODE_SUCCESS
4200 * On failure NI_RETCODE_INVALID_PARAM
4201 ******************************************************************************/
4203{
4205
4206 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
4207
4208 if (!p_packet)
4209 {
4210 ni_log(NI_LOG_ERROR, "ERROR: %s(): p_packet is NULL\n", __func__);
4211 retval = NI_RETCODE_FAILURE;
4212 LRETURN;
4213 }
4214
4215 if (!p_packet->p_buffer)
4216 {
4217 ni_log(NI_LOG_DEBUG, "%s(): already freed, nothing to free\n", __func__);
4218 LRETURN;
4219 }
4220
4221 ni_aligned_free(p_packet->p_buffer);
4222 p_packet->p_buffer = NULL;
4223 p_packet->buffer_size = 0;
4224 p_packet->data_len = 0;
4225 p_packet->p_data = NULL;
4226
4227 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
4228
4229END:
4230
4231 return retval;
4232}
4233
4234/*!*****************************************************************************
4235 * \brief Free packet buffer that was previously allocated with
4236 * ni_packet_buffer_alloc for AV1 packets merge
4237 *
4238 * \param[in] p_packet Pointer to a previously allocated ni_packet_t struct
4239 *
4240 * \return On success NI_RETCODE_SUCCESS
4241 * On failure NI_RETCODE_INVALID_PARAM
4242 ******************************************************************************/
4244{
4245 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
4247 int i;
4248
4249 if (!p_packet)
4250 {
4251 ni_log(NI_LOG_ERROR, "ERROR: %s(): p_packet is NULL\n", __func__);
4252 retval = NI_RETCODE_FAILURE;
4253 LRETURN;
4254 }
4255
4256 if (!p_packet->av1_buffer_index)
4257 {
4259 "%s(): no need to free previous av1 packet buffers\n", __func__);
4260 LRETURN;
4261 }
4262
4263 for (i = 0; i < p_packet->av1_buffer_index; i++)
4264 {
4265 ni_log(NI_LOG_DEBUG, "%s(): free previous av1 packet buffer %d\n",
4266 __func__, i);
4267 ni_aligned_free(p_packet->av1_p_buffer[i]);
4268 p_packet->av1_p_buffer[i] = NULL;
4269 p_packet->av1_p_data[i] = NULL;
4270 p_packet->av1_buffer_size[i] = 0;
4271 p_packet->av1_data_len[i] = 0;
4272 }
4273
4274 p_packet->av1_buffer_index = 0;
4275
4276END:
4277
4278 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
4279
4280 return retval;
4281}
4282
4283/*!*****************************************************************************
4284 * \brief Copy video packet accounting for alignment
4285 *
4286 * \param[in] p_destination Destination to where to copy to
4287 * \param[in] p_source Source from where to copy from
4288 * \param[in] cur_size current size
4289 * \param[out] p_leftover Pointer to the data that was left over
4290 * \param[out] p_prev_size Size of the data leftover ??
4291 *
4292 * \return On success Total number of bytes that were copied
4293 * On failure NI_RETCODE_FAILURE
4294 ******************************************************************************/
4295int ni_packet_copy(void* p_destination, const void* const p_source, int cur_size, void* p_leftover, int* p_prev_size)
4296{
4297 int copy_size = 0;
4298 int padding_size = 0;
4299 int prev_size = p_prev_size == NULL? 0 : *p_prev_size;
4300
4301 int total_size = cur_size + prev_size;
4302 uint8_t* p_src = (uint8_t*)p_source;
4303 uint8_t* p_dst = (uint8_t*)p_destination;
4304 uint8_t* p_lftover = (uint8_t*)p_leftover;
4305
4306 if (!p_prev_size)
4307 {
4309 }
4310
4311 ni_log(NI_LOG_TRACE, "%s(): enter, *prev_size=%d\n", __func__, *p_prev_size);
4312
4313 if ((0 == cur_size) && (0 == prev_size))
4314 {
4315 return copy_size;
4316 }
4317
4318 if (((0 != cur_size) && (!p_source)) || (!p_destination) || (!p_leftover))
4319 {
4320 return NI_RETCODE_FAILURE;
4321 }
4322
4323 copy_size = ((total_size + NI_MEM_PAGE_ALIGNMENT - 1) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
4324
4325 if (copy_size > total_size)
4326 {
4327 padding_size = copy_size - total_size;
4328 }
4329
4330 if (prev_size > 0)
4331 {
4332 memcpy(p_dst, p_lftover, prev_size);
4333 }
4334
4335 p_dst += prev_size;
4336
4337 memcpy(p_dst, p_src, cur_size);
4338
4339 if (padding_size)
4340 {
4341 p_dst += cur_size;
4342 memset(p_dst, 0, padding_size);
4343 }
4344
4346 "%s(): exit, cur_size=%d, copy_size=%d, "
4347 "prev_size=%d, padding_size=%d\n", __func__, cur_size,
4348 copy_size, *p_prev_size, padding_size);
4349
4350 *p_prev_size = 0;
4351
4352 return copy_size;
4353}
4354
4355/*!*****************************************************************************
4356 * \brief Add a new auxiliary data to a frame
4357 *
4358 * \param[in/out] frame a frame to which the auxiliary data should be added
4359 * \param[in] type type of the added auxiliary data
4360 * \param[in] data_size size of the added auxiliary data
4361 *
4362 * \return a pointer to the newly added aux data on success, NULL otherwise
4363 ******************************************************************************/
4365 int data_size)
4366{
4367 ni_aux_data_t *ret;
4368
4370 {
4371 ni_log(NI_LOG_ERROR, "ERROR: %s exceeding max aux_data number !\n",
4372 __func__);
4373 return NULL;
4374 }
4375
4376 ret = malloc(sizeof(ni_aux_data_t));
4377 if (!ret)
4378 {
4379 ni_log(NI_LOG_ERROR, "ERROR: %s No memory !\n", __func__);
4380 return NULL;
4381 }
4382
4383 ret->type = type;
4384 ret->size = data_size;
4385 ret->data = calloc(1, data_size);
4386 if (!ret->data)
4387 {
4388 ni_log(NI_LOG_ERROR, "ERROR: %s No memory for aux data !\n", __func__);
4389 free(ret);
4390 ret = NULL;
4391 } else
4392 {
4393 frame->aux_data[frame->nb_aux_data++] = ret;
4394 }
4395
4396 return ret;
4397}
4398
4399/*!*****************************************************************************
4400 * \brief Add a new auxiliary data to a frame and copy in the raw data
4401 *
4402 * \param[in/out] frame a frame to which the auxiliary data should be added
4403 * \param[in] type type of the added auxiliary data
4404 * \param[in] raw_data the raw data of the aux data
4405 * \param[in] data_size size of the added auxiliary data
4406 *
4407 * \return a pointer to the newly added aux data on success, NULL otherwise
4408 ******************************************************************************/
4410 ni_aux_data_type_t type,
4411 const uint8_t *raw_data,
4412 int data_size)
4413{
4414 ni_aux_data_t *ret = ni_frame_new_aux_data(frame, type, data_size);
4415 if (ret)
4416 {
4417 memcpy(ret->data, raw_data, data_size);
4418 }
4419 return ret;
4420}
4421
4422/*!*****************************************************************************
4423 * \brief Retrieve from the frame auxiliary data of a given type if exists
4424 *
4425 * \param[in] frame a frame from which the auxiliary data should be retrieved
4426 * \param[in] type type of the auxiliary data to be retrieved
4427 *
4428 * \return a pointer to the aux data of a given type on success, NULL otherwise
4429 ******************************************************************************/
4431 ni_aux_data_type_t type)
4432{
4433 int i;
4434 for (i = 0; i < frame->nb_aux_data; i++)
4435 {
4436 if (frame->aux_data[i]->type == type)
4437 {
4438 return frame->aux_data[i];
4439 }
4440 }
4441 return NULL;
4442}
4443
4444/*!*****************************************************************************
4445 * \brief If auxiliary data of the given type exists in the frame, free it
4446 * and remove it from the frame.
4447 *
4448 * \param[in/out] frame a frame from which the auxiliary data should be removed
4449 * \param[in] type type of the auxiliary data to be removed
4450 *
4451 * \return None
4452 ******************************************************************************/
4454{
4455 int i;
4456 ni_aux_data_t *aux;
4457
4458 for (i = 0; i < frame->nb_aux_data; i++)
4459 {
4460 aux = frame->aux_data[i];
4461 if (aux->type == type)
4462 {
4463 frame->aux_data[i] = frame->aux_data[frame->nb_aux_data - 1];
4464 frame->aux_data[frame->nb_aux_data - 1] = NULL;
4465 frame->nb_aux_data--;
4466 free(aux->data);
4467 free(aux);
4468 }
4469 }
4470}
4471
4472/*!*****************************************************************************
4473 * \brief Free and remove all auxiliary data from the frame.
4474 *
4475 * \param[in/out] frame a frame from which the auxiliary data should be removed
4476 *
4477 * \return None
4478 ******************************************************************************/
4480{
4481 int i;
4482 ni_aux_data_t *aux;
4483
4484 for (i = 0; i < frame->nb_aux_data; i++)
4485 {
4486 aux = frame->aux_data[i];
4487 free(aux->data);
4488 free(aux);
4489 }
4490 frame->nb_aux_data = 0;
4491}
4492
4493/*!*****************************************************************************
4494 * \brief Initialize default encoder parameters
4495 *
4496 * \param[out] param Pointer to a user allocated ni_xcoder_params_t
4497 * to initialize to default parameters
4498 * \param[in] fps_num Frames per second
4499 * \param[in] fps_denom FPS denomination
4500 * \param[in] bit_rate bit rate
4501 * \param[in] width frame width
4502 * \param[in] height frame height
4503 * \param[in] codec_format codec from ni_codec_format_t
4504 *
4505 * \return On success
4506 * NI_RETCODE_SUCCESS
4507 * On failure
4508 * NI_RETCODE_FAILURE
4509 * NI_RETCODE_INVALID_PARAM
4510 ******************************************************************************/
4512 int fps_num, int fps_denom,
4513 long bit_rate, int width,
4514 int height,
4515 ni_codec_format_t codec_format)
4516{
4517 ni_encoder_cfg_params_t *p_enc = NULL;
4518 int i = 0, j = 0;
4520
4521 //Initialize p_param structure
4522 if (!p_param)
4523 {
4524 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameters passed\n",
4525 __func__);
4526 retval = NI_RETCODE_INVALID_PARAM;
4527 LRETURN;
4528 }
4529
4530 ni_log(NI_LOG_DEBUG, "%s()\n", __func__);
4531
4532 //Initialize p_param structure
4533 memset(p_param, 0, sizeof(ni_xcoder_params_t));
4534
4535 p_enc = &p_param->cfg_enc_params;
4536
4537 // Rev. B: unified for HEVC/H.264
4538 p_enc->profile = 0;
4539 p_enc->level_idc = 0;
4540 p_enc->high_tier = 0;
4541
4542 if (QUADRA)
4544 else
4546
4547 p_enc->use_recommend_enc_params = 0;
4548 p_enc->cu_size_mode = 7;
4549 p_enc->max_num_merge = 2;
4550 p_enc->enable_dynamic_8x8_merge = 1;
4551 p_enc->enable_dynamic_16x16_merge = 1;
4552 p_enc->enable_dynamic_32x32_merge = 1;
4553
4554 p_enc->rc.trans_rate = 0;
4555
4556 p_enc->rc.enable_rate_control = 0;
4557 if (QUADRA)
4559 else
4561 p_enc->rc.enable_hvs_qp = 0;
4562 p_enc->rc.enable_hvs_qp_scale = 1;
4563 p_enc->rc.hvs_qp_scale = 2;
4564 p_enc->rc.min_qp = 8;
4565 p_enc->rc.max_qp = 51;
4566 p_enc->rc.max_delta_qp = 10;
4567
4568 // hrd is disabled if vbv_buffer_size=0, hrd is enabled if vbv_buffer_size is [10, 3000]
4569 p_enc->rc.vbv_buffer_size = -1;
4570 p_enc->rc.enable_filler = 0;
4571 p_enc->rc.enable_pic_skip = 0;
4572 p_enc->rc.vbv_max_rate = 0;
4573
4574 p_enc->roi_enable = 0;
4575
4577 // feature not supported on JPEG/AV1 - disable by default
4578 if (codec_format == NI_CODEC_FORMAT_JPEG ||
4579 codec_format == NI_CODEC_FORMAT_AV1)
4580 {
4582 }
4583
4584 p_enc->long_term_ref_enable = 0;
4585 p_enc->long_term_ref_interval = 0;
4586 p_enc->long_term_ref_count = 2;
4587
4588 p_enc->conf_win_top = 0;
4589 p_enc->conf_win_bottom = 0;
4590 p_enc->conf_win_left = 0;
4591 p_enc->conf_win_right = 0;
4592
4593 p_enc->intra_period = 120;
4594 p_enc->rc.intra_qp = 22;
4595 p_enc->rc.intra_qp_delta = -2;
4596 if (QUADRA)
4597 p_enc->rc.enable_mb_level_rc = 0;
4598 else
4599 p_enc->rc.enable_mb_level_rc = 1;
4600
4601 p_enc->decoding_refresh_type = 1;
4602
4603 p_enc->slice_mode = 0;
4604 p_enc->slice_arg = 0;
4605
4606 // Rev. B: H.264 only parameters.
4607 p_enc->enable_transform_8x8 = 1;
4608 p_enc->entropy_coding_mode = 1;
4609
4610 p_enc->intra_mb_refresh_mode = 0;
4611 p_enc->intra_mb_refresh_arg = 0;
4612 p_enc->intra_reset_refresh = 0;
4613
4615#ifndef QUADRA
4616 if (!QUADRA)
4617 {
4618 for (i = 0; i < NI_MAX_GOP_NUM; i++)
4619 {
4622 p_enc->custom_gop_params.pic_param[i].pic_qp = 0;
4623 p_enc->custom_gop_params.pic_param[i].num_ref_pic_L0 = 0;
4624 p_enc->custom_gop_params.pic_param[i].ref_poc_L0 = 0;
4625 p_enc->custom_gop_params.pic_param[i].ref_poc_L1 = 0;
4627 }
4628 }
4629 else // QUADRA
4630#endif
4631 {
4632 for (i = 0; i < NI_MAX_GOP_NUM; i++)
4633 {
4637 (float)0.3; // QP Factor range is between 0.3 and 1, higher values mean lower quality and less bits
4641 for (j = 0; j < NI_MAX_REF_PIC; j++)
4642 {
4643 p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic = 0;
4644 p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic_used = -1;
4645 }
4646 }
4647 }
4648
4649 p_param->source_width = width;
4650 p_param->source_height = height;
4651
4652 p_param->fps_number = fps_num;
4653 p_param->fps_denominator = fps_denom;
4654
4655 if (p_param->fps_number && p_param->fps_denominator)
4656 {
4657 p_enc->frame_rate = (int)(p_param->fps_number / p_param->fps_denominator);
4658 }
4659 else
4660 {
4661 p_enc->frame_rate = 30;
4662 }
4663
4664 p_param->bitrate = (int)bit_rate;
4665 p_param->roi_demo_mode = 0;
4666 p_param->reconf_demo_mode = 0; // for encoder reconfiguration testing
4667 p_param->force_pic_qp_demo_mode = 0;
4668 p_param->force_frame_type = 0;
4669 p_param->hdrEnableVUI = 0;
4670 p_param->cacheRoi = 0;
4671 p_param->low_delay_mode = 0;
4672 p_param->padding = 1;
4673 p_param->generate_enc_hdrs = 0;
4674 p_param->use_low_delay_poc_type = 0;
4675 p_param->rootBufId = 0;
4676 p_param->staticMmapThreshold = 0;
4677 p_param->zerocopy_mode = 1;
4678 p_param->luma_linesize = 0;
4679 p_param->chroma_linesize = 0;
4680 p_param ->enableCpuAffinity = 0;
4681
4683
4684 p_param->dolby_vision_profile = 0;
4685
4686 // encoder stream header VUI setting
4687 p_param->color_primaries = 2; // default COL_PRI_UNSPECIFIED
4688 p_param->color_transfer_characteristic = 2; // default COL_TRC_UNSPECIFIED
4689 p_param->color_space = 2; // default COL_SPC_UNSPECIFIED
4690 p_param->sar_num = 0; // default SAR numerator 0
4691 p_param->sar_denom = 1; // default SAR denominator 1
4692 p_param->video_full_range_flag = -1;
4693
4694 p_param->enable2PassGop = 0;
4696 p_param->minFramesDelay = 0;
4697 p_param->interval_of_psnr = 1;
4698 p_param->useMCTF = 0;
4699 for (i = 0; i < NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL; i++) {
4700 for (j = 0; j < NI_CUSTOMIZE_ROI_QP_NUM; j++) {
4701 // 127 is invalid for delta qp and absolute qp
4702 p_param->customize_roi_qp_map[i][j] = 127;
4703 }
4704 }
4705
4706 //QUADRA
4707 p_enc->EnableAUD = 0;
4708 p_enc->lookAheadDepth = 0;
4709 p_enc->rdoLevel = (codec_format == NI_CODEC_FORMAT_JPEG) ? 0 : 1;
4710 p_enc->crf = -1;
4711 p_enc->HDR10MaxLight = 0;
4712 p_enc->HDR10AveLight = 0;
4713 p_enc->HDR10CLLEnable = 0;
4714 p_enc->EnableRdoQuant = -1;
4715 p_enc->ctbRcMode = 0;
4716 p_enc->gopSize = 0;
4717 p_enc->gopLowdelay = 0;
4718 p_enc->gdrDuration = 0;
4719 p_enc->hrdEnable = 0;
4720 p_enc->ltrRefInterval = 0;
4721 p_enc->ltrRefQpOffset = 0;
4722 p_enc->ltrFirstGap = 0;
4723 p_enc->ltrNextInterval = 1;
4724 p_enc->multicoreJointMode = 0;
4725 p_enc->qlevel = -1;
4726 p_enc->maxFrameSize = 0;
4727 p_enc->maxFrameSizeRatio = 0;
4728 p_enc->chromaQpOffset = 0;
4729 p_enc->tolCtbRcInter = (float)0.1;
4730 p_enc->tolCtbRcIntra = (float)0.1;
4731 p_enc->bitrateWindow = -255;
4732 p_enc->inLoopDSRatio = 1;
4733 p_enc->blockRCSize = 0;
4734 p_enc->rcQpDeltaRange = 10;
4735 p_enc->ctbRowQpStep = 0;
4736 p_enc->newRcEnable = -1;
4737 p_enc->colorDescPresent = 0;
4738 p_enc->colorPrimaries = 2;
4739 p_enc->colorTrc = 2;
4740 p_enc->colorSpace = 2;
4741 p_enc->aspectRatioWidth = 0;
4742 p_enc->aspectRatioHeight = 1;
4743 p_enc->videoFullRange = 0;
4745 p_enc->enable_ssim = 0;
4746 p_enc->HDR10Enable = 0;
4747 p_enc->HDR10dx0 = 0;
4748 p_enc->HDR10dy0 = 0;
4749 p_enc->HDR10dx1 = 0;
4750 p_enc->HDR10dy1 = 0;
4751 p_enc->HDR10dx2 = 0;
4752 p_enc->HDR10dy2 = 0;
4753 p_enc->HDR10wx = 0;
4754 p_enc->HDR10wy = 0;
4755 p_enc->HDR10maxluma = 0;
4756 p_enc->HDR10minluma = 0;
4757 p_enc->avcc_hvcc = 0;
4758 p_enc->av1_error_resilient_mode = 0;
4759 p_enc->temporal_layers_enable = 0;
4760 p_enc->crop_width = 0;
4761 p_enc->crop_height = 0;
4762 p_enc->hor_offset = 0;
4763 p_enc->ver_offset = 0;
4764 p_enc->crfMax = -1;
4765 p_enc->qcomp = (float)0.6;
4766 p_enc->noMbtree = 0;
4767 p_enc->noHWMultiPassSupport = 0;
4768 p_enc->cuTreeFactor = 5;
4769 p_enc->ipRatio = (float)1.4;
4770 p_enc->pbRatio = (float)1.3;
4771 p_enc->cplxDecay = (float)0.5;
4772 p_enc->pps_init_qp = -1;
4773 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)
4774 p_enc->pass1_qp = -1;
4775 p_enc->crfFloat = -1.0f;
4776 p_enc->hvsBaseMbComplexity = 15;
4777 p_enc->statistic_output_level = 0;
4778 p_enc->skip_frame_enable = 0;
4779 p_enc->max_consecutive_skip_num = 1;
4780 p_enc->skip_frame_interval = 0;
4781 p_enc->enableipRatio = 0;
4782 p_enc->enable_all_sei_passthru = 0;
4783 p_enc->iframe_size_ratio = 100;
4784 p_enc->crf_max_iframe_enable = 0;
4785 p_enc->vbv_min_rate = 0;
4786 p_enc->totalCuTreeDepth = 0;
4787 p_enc->adaptiveCuTree = 0;
4788 p_enc->preIntraHandling = 1;
4789 p_enc->baseLayerOnly = 0;
4790 p_enc->pastFrameMaxIntraRatio = 20;
4791 p_enc->linkFrameMaxIntraRatio = 40;
4792 p_enc->adaptiveLamdaMode = 0;
4793 p_enc->adaptiveCrfMode = 0;
4794 p_enc->qpScaleEnable = 0;
4795#ifdef XCODER_311
4796 p_enc->disable_adaptive_buffers = 1;
4797#else
4798 p_enc->disable_adaptive_buffers = 0;
4799#endif
4800 p_enc->disableBframeRdoq = 0;
4801 p_enc->forceBframeQpfactor = (float)-1.0;
4802 p_enc->tune_bframe_visual = 0;
4803 p_enc->enable_acq_limit = 0;
4804 p_enc->get_psnr_mode = 3;
4806 p_enc->motionConstrainedMode = 0;
4807 p_enc->still_image_detect_level = 0;
4808 p_enc->scene_change_detect_level = 0;
4809 p_enc->encMallocStrategy = 0;
4810 p_enc->enable_smooth_crf = 0;
4811 p_enc->enable_compensate_qp = 0;
4812 p_enc->spatial_layers = 1;
4813 p_enc->enable_timecode = 0;
4815 p_enc->vbvBufferReencode = 0;
4816 p_enc->disableAv1TimingInfo = 0;
4818 p_enc->preset_enabled = 0;
4819 p_enc->reset_dts_offset = 1;
4820 p_enc->getBitstreamFeatures = 0;
4821 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
4822 {
4823 p_enc->spatialLayerBitrate[i] = 0;
4824 p_enc->av1OpLevel[i] = 0;
4825 }
4826 p_enc->intraCompensateMode = 0;
4827 p_enc->customMinCoeffDiv = 0;
4828
4829 if (codec_format == NI_CODEC_FORMAT_AV1)
4830 {
4831 if (p_param->source_width < NI_PARAM_AV1_MIN_WIDTH)
4832 {
4834 LRETURN;
4835 }
4837 {
4839 LRETURN;
4840 }
4841 if (p_param->source_width > NI_PARAM_AV1_MAX_WIDTH)
4842 {
4844 LRETURN;
4845 }
4847 {
4849 LRETURN;
4850 }
4851 if (p_param->source_height * p_param->source_width >
4853 {
4855 LRETURN;
4856 }
4857 // AV1 8x8 alignment HW limitation is now worked around by FW cropping input resolution
4859 {
4860 ni_log(NI_LOG_ERROR, "AV1 Picture Width not aligned to %d - picture will be cropped\n",
4862 }
4864 {
4865 ni_log(NI_LOG_ERROR, "AV1 Picture Height not aligned to %d - picture will be cropped\n",
4867 }
4868 }
4869
4870 if (codec_format == NI_CODEC_FORMAT_JPEG)
4871 {
4872 if (p_param->source_width < NI_MIN_WIDTH)
4873 {
4875 LRETURN;
4876 }
4877 if (p_param->source_height < NI_MIN_HEIGHT)
4878 {
4880 LRETURN;
4881 }
4882 }
4883
4884 if (p_param->source_width > NI_PARAM_MAX_WIDTH)
4885 {
4887 LRETURN;
4888 }
4889 if (p_param->source_width < NI_PARAM_MIN_WIDTH)
4890 {
4892 LRETURN;
4893 }
4894
4895 if (p_param->source_height > NI_PARAM_MAX_HEIGHT)
4896 {
4898 LRETURN;
4899 }
4900 if (p_param->source_height < NI_PARAM_MIN_HEIGHT)
4901 {
4903 LRETURN;
4904 }
4905 if (p_param->source_height*p_param->source_width > NI_MAX_RESOLUTION_AREA)
4906 {
4908 LRETURN;
4909 }
4910
4911END:
4912
4913 return retval;
4914}
4915
4916/*!*****************************************************************************
4917 * \brief Initialize default decoder parameters
4918 *
4919 * \param[out] param Pointer to a user allocated ni_xcoder_params_t
4920 * to initialize to default parameters
4921 * \param[in] fps_num Frames per second
4922 * \param[in] fps_denom FPS denomination
4923 * \param[in] bit_rate bit rate
4924 * \param[in] width frame width
4925 * \param[in] height frame height
4926 *
4927 * \return On success
4928 * NI_RETCODE_SUCCESS
4929 * On failure
4930 * NI_RETCODE_FAILURE
4931 * NI_RETCODE_INVALID_PARAM
4932 ******************************************************************************/
4934 int fps_num, int fps_denom,
4935 long bit_rate, int width,
4936 int height)
4937{
4938 ni_decoder_input_params_t* p_dec = NULL;
4939 int i;
4941
4942 //Initialize p_param structure
4943 if (!p_param)
4944 {
4945 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameter passed\n",
4946 __func__);
4947 retval = NI_RETCODE_INVALID_PARAM;
4948 LRETURN;
4949 }
4950
4951 ni_log(NI_LOG_DEBUG, "%s\n", __func__);
4952
4953 //Initialize p_param structure
4954 memset(p_param, 0, sizeof(ni_xcoder_params_t));
4955
4956 p_dec = &p_param->dec_input_params;
4957
4958 p_param->source_width = width;
4959 p_param->source_height = height;
4960
4961 if(fps_num <= 0 || fps_denom <= 0)
4962 {
4963 fps_num = 30;
4964 fps_denom = 1;
4965 ni_log(NI_LOG_INFO, "%s(): FPS is not set, setting the default FPS to 30\n", __func__);
4966 }
4967
4968 p_param->fps_number = fps_num;
4969 p_param->fps_denominator = fps_denom;
4970
4971 p_dec->hwframes = 0;
4972 p_dec->mcmode = 0;
4973 p_dec->nb_save_pkt = 0;
4974 p_dec->enable_out1 = 0;
4975 p_dec->enable_out2 = 0;
4976 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
4977 {
4978 p_dec->force_8_bit[i] = 0;
4979 p_dec->semi_planar[i] = 0;
4980 p_dec->crop_mode[i] = NI_DEC_CROP_MODE_AUTO;
4981 p_dec->crop_whxy[i][0] = width;
4982 p_dec->crop_whxy[i][1] = height;
4983 p_dec->crop_whxy[i][2] = 0;
4984 p_dec->crop_whxy[i][3] = 0;
4985 p_dec->scale_wh[i][0] = 0;
4986 p_dec->scale_wh[i][1] = 0;
4987 p_dec->scale_long_short_edge[i] = 0;
4988 p_dec->scale_resolution_ceil[i] = 2;
4989 p_dec->scale_round[i] = -1;
4990 }
4992 p_dec->decoder_low_delay = 0;
4993 p_dec->force_low_delay = false;
4994 p_dec->enable_low_delay_check = 0;
4995 p_dec->decoder_disable_reorder = 0;
4997 p_dec->custom_sei_passthru = -1;
5000 p_dec->enable_advanced_ec = 1;
5002 p_dec->enable_ppu_scale_adapt = 0;
5003 p_dec->enable_ppu_scale_limit = 0;
5004 p_dec->max_extra_hwframe_cnt = 255; //uint8_max
5005 p_dec->pkt_pts_unchange = 0;
5006 p_dec->enable_all_sei_passthru = 0;
5007 p_dec->enable_follow_iframe = 0;
5009#ifdef XCODER_311
5010 p_dec->disable_adaptive_buffers = 1;
5011 p_dec->min_packets_delay = true;
5012 p_dec->reduce_dpb_delay = 1;
5013#else
5014 p_dec->disable_adaptive_buffers = 0;
5015 p_dec->min_packets_delay = false;
5016 p_dec->reduce_dpb_delay = 0;
5017#endif
5018 p_dec->survive_stream_err = 0;
5019 p_dec->skip_extra_headers = 0;
5020 p_dec->extend_pool_size = 0;
5021 p_dec->decoder_mode = 0;
5022
5023 //-------init unused param start----------
5024
5025 p_param->bitrate = (int)bit_rate;
5026 p_param->reconf_demo_mode = 0; // for encoder reconfiguration testing
5027 p_param->force_pic_qp_demo_mode = 0;
5028 p_param->force_frame_type = 0;
5029 p_param->hdrEnableVUI = 0;
5030 p_param->cacheRoi = 0;
5031 p_param->low_delay_mode = 0;
5032 p_param->padding = 1;
5033 p_param->generate_enc_hdrs = 0;
5034 p_param->use_low_delay_poc_type = 0;
5035 p_param->dolby_vision_profile = 0;
5036
5037 // encoder stream header VUI setting
5038 p_param->color_primaries = 2; // default COL_PRI_UNSPECIFIED
5039 p_param->color_transfer_characteristic = 2; // default COL_TRC_UNSPECIFIED
5040 p_param->color_space = 2; // default COL_SPC_UNSPECIFIED
5041 p_param->sar_num = 0; // default SAR numerator 0
5042 p_param->sar_denom = 1; // default SAR denominator 1
5043 p_param->video_full_range_flag = -1;
5044
5045 //-------init unused param done----------
5046
5047END:
5048
5049 return retval;
5050}
5051
5052// read demo reconfig data file and parse out reconfig key/values in the format:
5053// key:val1,val2,val3,...val9 (max 9 values); only digit/:/,/newline is allowed
5054ni_retcode_t ni_parse_reconf_file(const char *reconf_file,
5056{
5057 char keyChar[10] = "";
5058 int key;
5059 char valChar[10] = "";
5060 int val;
5061 int32_t tmp_val;
5062 int valIdx = 1;
5063 int parseKey = 1;
5064 int idx = 0;
5065 int readc = EOF;
5066 FILE *reconf = NULL;
5067
5068 if (!reconf_file)
5069 {
5070 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5071 __func__);
5073 }
5074
5075 ni_fopen(&reconf, reconf_file, "r");
5076 if (!reconf)
5077 {
5078 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): Cannot open reconfig_file: %s\n",
5079 NI_ERRNO, __func__, reconf_file);
5081 }
5083
5084 while ((readc = fgetc(reconf)) != EOF)
5085 {
5086 //parse lines
5087 if (isdigit(readc))
5088 {
5089 if (parseKey)
5090 {
5091 ni_strncat(keyChar, 10, (const char *)(&readc), 1);
5092 }
5093 else
5094 {
5095 ni_strncat(valChar, 10, (const char *)(&readc), 1);
5096 }
5097 }
5098 else if (readc == ':')
5099 {
5100 parseKey = 0;
5101 if (ni_strtoi(keyChar, &tmp_val) != NI_RETCODE_SUCCESS)
5102 {
5104 "ERROR: %s(): invalid key value '%s' in reconfig file\n",
5105 __func__, keyChar);
5106 retval = NI_RETCODE_INVALID_PARAM;
5107 break;
5108 }
5109 key = (int)tmp_val;
5110 hash_map[idx][0] = key;
5111 }
5112 else if (readc == ',')
5113 {
5115 {
5117 "ERROR: Number of entries per line in reconfig file is greater then the "
5118 "limit of %d\n",
5120 retval = NI_RETCODE_INVALID_PARAM;
5121 break;
5122 }
5123 if (ni_strtoi(valChar, &tmp_val) != NI_RETCODE_SUCCESS)
5124 {
5126 "ERROR: %s(): invalid value '%s' in reconfig file\n",
5127 __func__, valChar);
5128 retval = NI_RETCODE_INVALID_PARAM;
5129 break;
5130 }
5131 val = (int)tmp_val;
5132 hash_map[idx][valIdx] = val;
5133 valIdx++;
5134 memset(valChar, 0, 10);
5135 }
5136 else if (readc == '\n')
5137 {
5139 {
5141 "ERROR: Number of lines in reconfig file is greater then the "
5142 "limit of %d\n",
5144 retval = NI_RETCODE_INVALID_PARAM;
5145 break;
5146 }
5147 parseKey = 1;
5148 if (ni_strtoi(valChar, &tmp_val) != NI_RETCODE_SUCCESS)
5149 {
5151 "ERROR: %s(): invalid value '%s' in reconfig file\n",
5152 __func__, valChar);
5153 retval = NI_RETCODE_INVALID_PARAM;
5154 break;
5155 }
5156 val = (int)tmp_val;
5157 hash_map[idx][valIdx] = val;
5158 valIdx = 1;
5159 memset(keyChar,0,10);
5160 memset(valChar,0,10);
5161 idx ++;
5162 }
5163 else
5164 {
5165 ni_log(NI_LOG_ERROR, "ERROR: character %c in reconfig file. this may lead to mistaken reconfiguration values\n", readc);
5166 }
5167 }
5168
5169 (void)fclose(reconf);
5170
5171 if (NI_RETCODE_SUCCESS == retval && parseKey != 1)
5172 {
5174 "ERROR %d: %s(): Incorrect format / "
5175 "incomplete Key/Value pair in reconfig_file: %s\n",
5176 NI_ERRNO, __func__, reconf_file);
5178 }
5179
5180 return retval;
5181}
5182
5184 int8_t qp_map[][NI_CUSTOMIZE_ROI_QP_NUM])
5185{
5186 char valChar[5] = "";
5187 int val;
5188 int32_t tmp_val;
5189 int negative = 0;
5190 int qpIdx = 0;
5191 int levelIdx = 0;
5192 int readc = EOF;
5193 FILE *reconf = NULL;
5194
5195 if (!customize_file)
5196 {
5197 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5198 __func__);
5200 }
5201
5202 ni_fopen(&reconf, customize_file, "r");
5203 if (!reconf)
5204 {
5205 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): Cannot open reconfig_file: %s\n",
5206 NI_ERRNO, __func__, customize_file);
5208 }
5210
5211 while ((readc = fgetc(reconf)) != EOF)
5212 {
5213 //parse lines
5214 if (isdigit(readc))
5215 {
5216 ni_strncat(valChar, 5, (const char *)(&readc), 1);
5217 }
5218 else if (readc == '-') {
5219 negative = 1;
5220 }
5221 else if (readc == ',')
5222 {
5223 if (qpIdx >= NI_CUSTOMIZE_ROI_QP_NUM || levelIdx >= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL)
5224 {
5226 "ERROR: Number of qpIdx %d greater then the limit of %d or"
5227 "Number of levelIdx %d greater then the limit of %d\n",
5229 retval = NI_RETCODE_INVALID_PARAM;
5230 break;
5231 }
5232 if (ni_strtoi(valChar, &tmp_val) != NI_RETCODE_SUCCESS)
5233 {
5235 "ERROR: %s(): invalid value '%s' in customize file\n",
5236 __func__, valChar);
5237 retval = NI_RETCODE_INVALID_PARAM;
5238 break;
5239 }
5240 if (!negative) {
5241 val = clip3(0, NI_MAX_QP_INFO, (int)tmp_val);
5242 qp_map[levelIdx][qpIdx] = (int8_t)val;
5243 } else {
5244 val = clip3(0, 32, (int)tmp_val);
5245 qp_map[levelIdx][qpIdx] = (int8_t)(val * -1);
5246 }
5247 negative = 0;
5248 memset(valChar, 0, 5);
5249 qpIdx++;
5250 }
5251 else if (readc == '\n')
5252 {
5253 if (qpIdx >= NI_CUSTOMIZE_ROI_QP_NUM || levelIdx >= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL)
5254 {
5256 "ERROR: Number of qpIdx %d greater then the limit of %d or"
5257 "Number of levelIdx %d greater then the limit of %d\n",
5259 retval = NI_RETCODE_INVALID_PARAM;
5260 break;
5261 }
5262 if (ni_strtoi(valChar, &tmp_val) != NI_RETCODE_SUCCESS)
5263 {
5265 "ERROR: %s(): invalid value '%s' in customize file\n",
5266 __func__, valChar);
5267 retval = NI_RETCODE_INVALID_PARAM;
5268 break;
5269 }
5270 if (!negative) {
5271 val = clip3(0, NI_MAX_QP_INFO, (int)tmp_val);
5272 qp_map[levelIdx][qpIdx] = (int8_t)val;
5273 } else {
5274 val = clip3(0, 32, (int)tmp_val);
5275 qp_map[levelIdx][qpIdx] = (int8_t)(val * -1);
5276 }
5277 negative = 0;
5278 memset(valChar, 0, 5);
5279 qpIdx = 0;
5280 levelIdx++;
5281 }
5282 else
5283 {
5284 ni_log(NI_LOG_ERROR, "ERROR: character %c in reconfig file. this may lead to mistaken reconfiguration values\n", readc);
5285 }
5286 }
5287 (void)fclose(reconf);
5288
5289 return retval;
5290}
5291
5292
5293#undef atoi
5294#undef atof
5295#define atoi(p_str) ni_atoi(p_str, &b_error)
5296#define atof(p_str) ni_atof(p_str, &b_error)
5297#define atobool(p_str) (ni_atobool(p_str, &b_error))
5298/*!*****************************************************************************
5299* \brief Set value referenced by name in decoder parameters structure
5300*
5301* \param[in] p_params Pointer to a user allocated ni_xcoder_params_t (used
5302* for decoder too for now ) to find and set a particular
5303* parameter
5304* \param[in] name String represented parameter name to search
5305* \param[in] value Parameter value to set
5306*
5307* \return On success
5308* NI_RETCODE_SUCCESS
5309* On failure
5310* NI_RETCODE_FAILURE
5311* NI_RETCODE_INVALID_PARAM
5312*******************************************************************************/
5314 const char *name, char *value)
5315{
5316 bool b_error = false;
5317 bool bNameWasBool = false;
5318 bool bValueWasNull = !value;
5319 ni_decoder_input_params_t* p_dec = NULL;
5320 char nameBuf[64] = { 0 };
5321 const char delim[2] = ",";
5322 const char xdelim[2] = "x";
5323 char *chunk;//for parsing out multi param input
5324 int i, j, k, ppu_index;
5325
5326 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
5327
5328 if (!p_params)
5329 {
5330 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5331 __func__);
5333 }
5334
5335 if (!name)
5336 {
5337 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
5338 __func__);
5340 }
5341 p_dec = &p_params->dec_input_params;
5342
5343 // skip -- prefix if provided
5344 if (name[0] == '-' && name[1] == '-')
5345 {
5346 name += 2;
5347 }
5348
5349 // s/_/-/g
5350 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
5351 {
5352 char* c;
5353 ni_strcpy(nameBuf, sizeof(nameBuf), name);
5354 while ((c = strchr(nameBuf, '_')) != 0)
5355 {
5356 *c = '-';
5357 }
5358 name = nameBuf;
5359 }
5360
5361 if (!value)
5362 {
5363 value = "true";
5364 }
5365 else if (value[0] == '=')
5366 {
5367 value++;
5368 }
5369
5370#if defined(_MSC_VER)
5371#define OPT(STR) else if (!_stricmp(name, STR))
5372#define OPT2(STR1, STR2) \
5373 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2))
5374#define OPT6(STR1, STR2, STR3, STR4, STR5, STR6) \
5375 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2) || \
5376 !_stricmp(name, STR3) || !_stricmp(name, STR4) || \
5377 !_stricmp(name, STR5) || !_stricmp(name, STR6))
5378#else
5379#define OPT(STR) else if (!strcasecmp(name, STR))
5380#define OPT2(STR1, STR2) else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2))
5381#define OPT6(STR1, STR2, STR3, STR4, STR5, STR6) \
5382 else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2) || \
5383 !strcasecmp(name, STR3) || !strcasecmp(name, STR4) || \
5384 !strcasecmp(name, STR5) || !strcasecmp(name, STR6))
5385#endif
5386 if (0); // suppress cppcheck
5388 {
5389 if (!strncmp(value, "hw", sizeof("hw"))){
5390 p_dec->hwframes = 1;
5391 }
5392 else if (!strncmp(value, "sw", sizeof("sw"))) {
5393 p_dec->hwframes = 0;
5394 }
5395 else{
5396 ni_log(NI_LOG_ERROR, "ERROR: %s(): out can only be <hw,sw> got %s\n",
5397 __func__, value);
5399 }
5400 }
5402 {
5403 if (atoi(value) == 1)
5404 p_dec->enable_out1 = 1;
5405 }
5407 {
5408 if (atoi(value) == 1)
5409 p_dec->enable_out2 = 1;
5410 }
5412 {
5413 if (atoi(value) == 1)
5414 p_dec->force_8_bit[0] = 1;
5415 }
5417 {
5418 if (atoi(value) == 1)
5419 p_dec->force_8_bit[1] = 1;
5420 }
5422 {
5423 if (atoi(value) == 1)
5424 p_dec->force_8_bit[2] = 1;
5425 }
5427 {
5428 if (atoi(value) == 1 || atoi(value) == 2)
5429 p_dec->semi_planar[0] = atoi(value);
5430 }
5432 {
5433 if (atoi(value) == 1 || atoi(value) == 2)
5434 p_dec->semi_planar[1] = atoi(value);
5435 }
5437 {
5438 if (atoi(value) == 1 || atoi(value) == 2)
5439 p_dec->semi_planar[2] = atoi(value);
5440 }
5442 {
5443 if (!strncmp(value, "manual", sizeof("manual"))) {
5445 }
5446 else if (!strncmp(value, "auto", sizeof("auto"))) {
5447 p_dec->crop_mode[0] = NI_DEC_CROP_MODE_AUTO;
5448 }
5449 else{
5451 "ERROR: %s():cropMode0 input can only be <manual,auto> got %s\n",
5452 __func__, value);
5454 }
5455 }
5457 {
5458 if (!strncmp(value, "manual", sizeof("manual"))) {
5460 }
5461 else if (!strncmp(value, "auto", sizeof("auto"))) {
5462 p_dec->crop_mode[1] = NI_DEC_CROP_MODE_AUTO;
5463 }
5464 else {
5466 "ERROR: %s():cropMode1 input can only be <manual,auto> got %s\n",
5467 __func__, value);
5469 }
5470 }
5472 {
5473 if (!strncmp(value, "manual", sizeof("manual"))) {
5475 }
5476 else if (!strncmp(value, "auto", sizeof("auto"))) {
5477 p_dec->crop_mode[2] = NI_DEC_CROP_MODE_AUTO;
5478 }
5479 else {
5481 "ERROR: %s():cropMode2 input can only be <manual,auto> got %s\n",
5482 __func__, value);
5484 }
5485 }
5487 {
5488 char *saveptr = NULL;
5489 chunk = ni_strtok(value, delim, &saveptr);
5490 for (i = 0; i < 4; i++)
5491 {
5492 if (chunk != NULL)
5493 {
5494 j = k = 0;
5495 while (chunk[j])
5496 {
5497 if (chunk[j] != '\"' && chunk[j] != '\'')
5498 {
5499 p_dec->cr_expr[0][i][k] = chunk[j];
5500 k++;
5501 }
5503 {
5505 }
5506 }
5507 chunk = ni_strtok(NULL, delim, &saveptr);
5508 }
5509 else if (i == 2 ) //default offsets to centered image if not specified, may need recalc
5510 {
5511 ni_strcpy(p_dec->cr_expr[0][i], sizeof(p_dec->cr_expr[0][i]), "in_w/2-out_w/2");
5512 }
5513 else if (i == 3)
5514 {
5515 ni_strcpy(p_dec->cr_expr[0][i], sizeof(p_dec->cr_expr[0][i]), "in_h/2-out_h/2");
5516 } else
5517 {
5519 }
5520 }
5521 }
5523 {
5524 char *saveptr = NULL;
5525 chunk = ni_strtok(value, delim, &saveptr);
5526 for (i = 0; i < 4; i++)
5527 {
5528 if (chunk != NULL)
5529 {
5530 j = k = 0;
5531 while (chunk[j])
5532 {
5533 if (chunk[j] != '\"' && chunk[j] != '\'')
5534 {
5535 p_dec->cr_expr[1][i][k] = chunk[j];
5536 k++;
5537 }
5539 {
5541 }
5542 }
5543 chunk = ni_strtok(NULL, delim, &saveptr);
5544 }
5545 else if (i == 2) //default offsets to centered image if not specified, may need recalc
5546 {
5547 ni_strcpy(p_dec->cr_expr[1][i], sizeof(p_dec->cr_expr[1][i]), "in_w/2-out_w/2");
5548 }
5549 else if (i == 3)
5550 {
5551 ni_strcpy(p_dec->cr_expr[1][i], sizeof(p_dec->cr_expr[1][i]), "in_h/2-out_h/2");
5552 }
5553 else
5554 {
5556 }
5557 }
5558 }
5560 {
5561 char *saveptr = NULL;
5562 chunk = ni_strtok(value, delim, &saveptr);
5563 for (i = 0; i < 4; i++)
5564 {
5565 if (chunk != NULL)
5566 {
5567 j = k = 0;
5568 while (chunk[j])
5569 {
5570 if (chunk[j] != '\"' && chunk[j] != '\'')
5571 {
5572 p_dec->cr_expr[2][i][k] = chunk[j];
5573 k++;
5574 }
5576 {
5578 }
5579 }
5580 chunk = ni_strtok(NULL, delim, &saveptr);
5581 }
5582 else if (i == 2) //default offsets to centered image if not specified, may need recalc
5583 {
5584 ni_strcpy(p_dec->cr_expr[2][i], sizeof(p_dec->cr_expr[2][i]), "in_w/2-out_w/2");
5585 }
5586 else if (i == 3)
5587 {
5588 ni_strcpy(p_dec->cr_expr[2][i], sizeof(p_dec->cr_expr[2][i]), "in_h/2-out_h/2");
5589 }
5590 else
5591 {
5593 }
5594 }
5595 }
5597 {
5598 chunk = value;
5599 i = 0; // 'x' character counter
5600 while (*chunk++) {
5601 if (*chunk == xdelim[0]) {
5602 i++;
5603 }
5604 }
5605 if (i != 1) {
5607 }
5608 chunk = NULL;
5609
5610 char *saveptr = NULL;
5611 chunk = ni_strtok(value, xdelim, &saveptr);
5612 for (i = 0; i < 2; i++)
5613 {
5614 if (chunk != NULL)
5615 {
5616 j = k = 0;
5617 while (chunk[j])
5618 {
5619 if (chunk[j] != '\"' && chunk[j] != '\'')
5620 {
5621 p_dec->sc_expr[0][i][k] = chunk[j];
5622 k++;
5623 }
5625 {
5627 }
5628 }
5629 chunk = ni_strtok(NULL, xdelim, &saveptr);
5630 }
5631 else
5632 {
5634 }
5635 }
5636 }
5638 {
5639 chunk = value;
5640 i = 0; // 'x' character counter
5641 while (*chunk++) {
5642 if (*chunk == xdelim[0]) {
5643 i++;
5644 }
5645 }
5646 if (i != 1) {
5648 }
5649 chunk = NULL;
5650
5651 char *saveptr = NULL;
5652 chunk = ni_strtok(value, xdelim, &saveptr);
5653 for (i = 0; i < 2; i++)
5654 {
5655 if (chunk != NULL)
5656 {
5657 j = k = 0;
5658 while (chunk[j])
5659 {
5660 if (chunk[j] != '\"' && chunk[j] != '\'')
5661 {
5662 p_dec->sc_expr[1][i][k] = chunk[j];
5663 k++;
5664 }
5666 {
5668 }
5669 }
5670 chunk = ni_strtok(NULL, xdelim, &saveptr);
5671 }
5672 else
5673 {
5675 }
5676 }
5677 }
5679 {
5680 chunk = value;
5681 i = 0; // 'x' character counter
5682 while (*chunk++) {
5683 if (*chunk == xdelim[0]) {
5684 i++;
5685 }
5686 }
5687 if (i != 1) {
5689 }
5690 chunk = NULL;
5691
5692 char *saveptr = NULL;
5693 chunk = ni_strtok(value, xdelim, &saveptr);
5694 for (i = 0; i < 2; i++)
5695 {
5696 if (chunk != NULL)
5697 {
5698 j = k = 0;
5699 while (chunk[j])
5700 {
5701 if (chunk[j] != '\"' && chunk[j] != '\'')
5702 {
5703 p_dec->sc_expr[2][i][k] = chunk[j];
5704 k++;
5705 }
5707 {
5709 }
5710 }
5711 chunk = ni_strtok(NULL, xdelim, &saveptr);
5712 }
5713 else
5714 {
5716 }
5717 }
5718 }
5722 {
5723 chunk = value;
5724 if (chunk != NULL)
5725 {
5726 ppu_index = name[5] - '0';
5727 i = name[6] == 'w' ? 0 : 1;
5728 j = k = 0;
5729 while (chunk[j])
5730 {
5731 if (chunk[j] != '\"' && chunk[j] != '\'')
5732 {
5733 p_dec->sc_expr[ppu_index][i][k] = chunk[j];
5734 k++;
5735 }
5737 {
5739 }
5740 }
5741 }
5742 }
5744 {
5745 if ((atoi(value) < 0) || (atoi(value) > 2))
5746 {
5748 }
5749 p_dec->scale_long_short_edge[0] = atoi(value);
5750 }
5752 {
5753 if ((atoi(value) < 0) || (atoi(value) > 2))
5754 {
5756 }
5757 p_dec->scale_long_short_edge[1] = atoi(value);
5758 }
5760 {
5761 if ((atoi(value) < 0) || (atoi(value) > 2))
5762 {
5764 }
5765 p_dec->scale_long_short_edge[2] = atoi(value);
5766 }
5768 {
5769 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5770 {
5771 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5772 "and must be even number and less than or equal to 128. Got: %s\n",
5773 __func__, NI_DEC_PARAM_SCALE_0_RES_CEIL, value);
5774
5776 }
5777 p_dec->scale_resolution_ceil[0] = atoi(value);
5778 }
5780 {
5781 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5782 {
5783 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5784 "and must be even number and less than or equal to 128. Got: %s\n",
5785 __func__, NI_DEC_PARAM_SCALE_1_RES_CEIL, value);
5787 }
5788 p_dec->scale_resolution_ceil[1] = atoi(value);
5789 }
5791 {
5792 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5793 {
5794 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5795 "and must be even number and less than or equal to 128. Got: %s\n",
5796 __func__, NI_DEC_PARAM_SCALE_2_RES_CEIL, value);
5798 }
5799 p_dec->scale_resolution_ceil[2] = atoi(value);
5800 }
5802 {
5803 if (!strncmp(value, "up", sizeof("up"))){
5804 p_dec->scale_round[0] = 0;
5805 }
5806 else if (!strncmp(value, "down", sizeof("down"))) {
5807 p_dec->scale_round[0] = 1;
5808 }
5809 else{
5810 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5811 __func__, NI_DEC_PARAM_SCALE_0_ROUND, value);
5813 }
5814 }
5816 {
5817 if (!strncmp(value, "up", sizeof("up"))){
5818 p_dec->scale_round[1] = 0;
5819 }
5820 else if (!strncmp(value, "down", sizeof("down"))) {
5821 p_dec->scale_round[1] = 1;
5822 }
5823 else{
5824 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5825 __func__, NI_DEC_PARAM_SCALE_1_ROUND, value);
5827 }
5828 }
5830 {
5831 if (!strncmp(value, "up", sizeof("up"))){
5832 p_dec->scale_round[2] = 0;
5833 }
5834 else if (!strncmp(value, "down", sizeof("down"))) {
5835 p_dec->scale_round[2] = 1;
5836 }
5837 else{
5838 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5839 __func__, NI_DEC_PARAM_SCALE_2_ROUND, value);
5841 }
5842 }
5844 {
5845 if ((atoi(value) != 0) && (atoi(value) != 1))
5846 {
5848 }
5849 p_dec->mcmode = atoi(value);
5850 }
5852 {
5853 if (atoi(value) < 0)
5854 {
5856 }
5857 p_dec->nb_save_pkt = atoi(value);
5858 }
5860 {
5861 if ((atoi(value) < NI_MIN_KEEP_ALIVE_TIMEOUT) ||
5863 {
5865 }
5866 p_dec->keep_alive_timeout = atoi(value);
5867 }
5869 {
5870 if (atoi(value) < 0)
5871 {
5873 }
5874 p_dec->decoder_low_delay = atoi(value);
5875 }
5877 {
5878 if ((atoi(value) != 0) && (atoi(value) != 1))
5879 {
5881 }
5882 p_dec->force_low_delay = atoi(value);
5883 }
5885 {
5886 if (atoi(value) < 0)
5887 {
5889 }
5890 p_dec->enable_low_delay_check = atoi(value);
5891 }
5893 {
5894 if (atoi(value) < 0)
5895 {
5897 }
5898 p_dec->decoder_disable_reorder = atoi(value);
5899 }
5901 {
5902 if ((atoi(value) != 0) && (atoi(value) != 1))
5903 {
5905 }
5906 p_dec->min_packets_delay = atoi(value);
5907 }
5909 {
5910 if (atoi(value) != NI_ENABLE_USR_DATA_SEI_PASSTHRU &&
5912 {
5914 }
5915 p_dec->enable_user_data_sei_passthru = atoi(value);
5916 }
5918 {
5919 if (atoi(value) < NI_MIN_CUSTOM_SEI_PASSTHRU ||
5921 {
5923 }
5924 p_dec->custom_sei_passthru = atoi(value);
5925 }
5927 {
5929 {
5931 }
5932 p_dec->svct_decoding_layer = atoi(value);
5933 }
5935 {
5936 if (atoi(value) >= NI_DDR_PRIORITY_MAX ||
5937 atoi(value) <= NI_DDR_PRIORITY_NONE)
5938 {
5940 }
5941 p_params->ddr_priority_mode = atoi(value);
5942 }
5944 {
5945 if (strncmp(value, "tolerant", sizeof("tolerant")) == 0) {
5947 } else if (strncmp(value, "ignore", sizeof("ignore")) == 0) {
5949 } else if (strncmp(value, "skip", sizeof("skip")) == 0) {
5951 } else if (strncmp(value, "best_effort", sizeof("best_effort")) == 0) {
5953 } else if (strncmp(value, "limited_error", sizeof("limited_error")) == 0) {
5955 } else if (strncmp(value, "best_effort_out_dc", sizeof("best_effort_out_dc")) == 0) {
5957 } else {
5959 }
5960 }
5962 {
5963 if (atoi(value) != 0 &&
5964 atoi(value) != 1 &&
5965 atoi(value) != 2)
5966 {
5968 }
5969 p_dec->enable_advanced_ec = atoi(value);
5970 }
5972 {
5973 if (atoi(value) < 0 || (atoi(value) > 100))
5974 {
5976 }
5977 p_dec->error_ratio_threshold = atoi(value);
5978 }
5980 {
5981 if (atoi(value) < 0 || (atoi(value) > 2))
5982 {
5984 }
5985 p_dec->enable_ppu_scale_adapt = atoi(value);
5986 }
5988 {
5989 if (atoi(value) < 0 || (atoi(value) > 1))
5990 {
5992 }
5993 p_dec->enable_ppu_scale_limit = atoi(value);
5994 }
5996 {
5997 if (atoi(value) < 0 || atoi(value) > 255)
5998 {
6000 }
6001 p_dec->max_extra_hwframe_cnt = atoi(value);
6002 }
6004 {
6005 if (atoi(value) < 0 || atoi(value) > 252)
6006 {
6008 }
6009 p_dec->extend_pool_size = atoi(value);
6010 }
6012 {
6013 if (strncmp(value, "normal", sizeof("normal")) == 0) {
6015 } else if (strncmp(value, "intra_only", sizeof("intra_only")) == 0) {
6017 } else {
6019 }
6020 }
6022 {
6023 if (atoi(value) < 0 || atoi(value) > 1)
6024 {
6026 }
6027 p_dec->skip_pts_guess = atoi(value);
6028 }
6030 {
6031 if (atoi(value) != 0 && atoi(value) != 1)
6032 {
6034 }
6035 p_dec->pkt_pts_unchange = atoi(value);
6036 }
6038 {
6039 if (atoi(value) < 0 ||
6040 atoi(value) > 1)
6041 {
6043 }
6044 p_dec->enable_all_sei_passthru = atoi(value);
6045 }
6047 {
6048 if (atoi(value) != 0 && atoi(value) != 1)
6049 {
6051 }
6052 p_dec->enable_follow_iframe = atoi(value);
6053 }
6055 {
6056 if (atoi(value) < 0 ||
6057 atoi(value) > 1)
6058 {
6060 }
6061 p_dec->disable_adaptive_buffers = atoi(value);
6062 }
6064 {
6065 if (atoi(value) < 0 || atoi(value) > 1)
6066 {
6068 }
6069 p_dec->survive_stream_err = atoi(value);
6070 }
6072 {
6073 if ((atoi(value) != 0) && (atoi(value) != 1))
6074 {
6076 }
6077 p_dec->reduce_dpb_delay = atoi(value);
6078 }
6080 {
6081 if ((atoi(value) != 0) && (atoi(value) != 1))
6082 {
6084 }
6085 p_dec->skip_extra_headers = atoi(value);
6086 }
6088 {
6089 if ((atoi(value) != 0) && (atoi(value) != 1))
6090 {
6092 }
6093 p_params->enableCpuAffinity = atoi(value);
6094 }
6095 else
6096 {
6098 }
6099
6100#undef OPT
6101#undef atobool
6102#undef atoi
6103#undef atof
6104 b_error |= bValueWasNull && !bNameWasBool;
6105
6106 ni_log(NI_LOG_TRACE, "%s: exit, b_error=%d\n", __func__, b_error);
6107
6109}
6110
6111#undef atoi
6112#undef atof
6113#define atoi(p_str) ni_atoi(p_str, &b_error)
6114#define atof(p_str) ni_atof(p_str, &b_error)
6115#define atobool(p_str) (ni_atobool(p_str, &b_error))
6116
6117/*!*****************************************************************************
6118 * \brief Set value referenced by name in encoder parameters structure
6119 *
6120 * \param[in] p_params Pointer to a user allocated ni_xcoder_params_t
6121 * to find and set a particular parameter
6122 * \param[in] name String represented parameter name to search
6123 * \param[in] value Parameter value to set
6124*
6125 * \return On success
6126 * NI_RETCODE_SUCCESS
6127 * On failure
6128 * NI_RETCODE_FAILURE
6129 * NI_RETCODE_INVALID_PARAM
6130 ******************************************************************************/
6132 const char *name, const char *value)
6133{
6134 bool b_error = false;
6135 bool bNameWasBool = false;
6136 bool bValueWasNull = !value;
6137 ni_encoder_cfg_params_t *p_enc = NULL;
6138 char nameBuf[64] = { 0 };
6139 int i,j,k;
6140
6141 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
6142
6143 if (!p_params)
6144 {
6145 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
6146 __func__);
6148 }
6149
6150 if ( !name )
6151 {
6152 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
6153 __func__);
6155 }
6156 p_enc = &p_params->cfg_enc_params;
6157 // skip -- prefix if provided
6158 if (name[0] == '-' && name[1] == '-')
6159 {
6160 name += 2;
6161 }
6162
6163 // s/_/-/g
6164 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
6165 {
6166 char* c;
6167 ni_strcpy(nameBuf, sizeof(nameBuf), name);
6168 while ((c = strchr(nameBuf, '_')) != 0)
6169 {
6170 *c = '-';
6171 }
6172 name = nameBuf;
6173 }
6174
6175 if (!value)
6176 {
6177 value = "true";
6178 }
6179 else if (value[0] == '=')
6180 {
6181 value++;
6182 }
6183
6184#if defined(_MSC_VER)
6185#define OPT(STR) else if (!_stricmp(name, STR))
6186#define OPT2(STR1, STR2) \
6187 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2))
6188#else
6189#define OPT(STR) else if (!strcasecmp(name, STR))
6190#define OPT2(STR1, STR2) else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2))
6191#endif
6192#define COMPARE(STR1, STR2, STR3) \
6193 if ((atoi(STR1) > (STR2)) || (atoi(STR1) < (STR3))) \
6194 { \
6195 return NI_RETCODE_PARAM_ERROR_OOR; \
6196 }
6197 if (0); // suppress cppcheck
6199 {
6200 if (AV_CODEC_DEFAULT_BITRATE == p_params->bitrate)
6201 {
6202 if (atoi(value) > NI_MAX_BITRATE)
6203 {
6205 }
6206 if (atoi(value) < NI_MIN_BITRATE)
6207 {
6209 }
6210 p_params->bitrate = atoi(value);
6211 }
6212 }
6214 {
6215 p_params->reconf_demo_mode = atoi(value); // for encoder reconfiguration testing
6216 }
6218 {
6219 ni_retcode_t retval = ni_parse_reconf_file(value, p_params->reconf_hash);
6220 if (retval != NI_RETCODE_SUCCESS) // for encoder reconfiguration testing
6221 {
6222 return retval;
6223 }
6224 }
6226 {
6227 // for encoder reconfiguration testing
6228 p_params->roi_demo_mode = atoi(value);
6229 if ((p_params->roi_demo_mode < 0) || (p_params->roi_demo_mode > 2))
6230 {
6232 }
6233 }
6235 {
6236 if (0 > atoi(value))
6237 {
6239 }
6240 p_params->low_delay_mode = atoi(value);
6241 }
6243 {
6244 if (atoi(value) < 0 || atoi(value) > 7)
6245 {
6247 }
6248 p_params->minFramesDelay = atoi(value);
6249 }
6251 {
6252 if (0 != atoi(value) && 1 != atoi(value))
6253 {
6255 }
6256 p_params->useMCTF = atoi(value);
6257 }
6259 {
6260 p_params->padding = atoi(value);
6261 }
6262#ifndef DEPRECATION_AS_ERROR
6264 {
6265 if (0 != atoi(value) && 1 != atoi(value))
6266 {
6268 }
6269 p_params->generate_enc_hdrs = atoi(value);
6270 // genHdrs is deprecated in favour of libavcodec parameter -gen_global_headers
6272 }
6273#endif
6275 {
6276 if (0 != atoi(value) && 1 != atoi(value))
6277 {
6279 }
6280 p_params->use_low_delay_poc_type = atoi(value);
6281 }
6283 {
6284 if (QUADRA)
6285 {
6287 }
6288 p_params->force_frame_type = atoi(value);
6289 }
6291 {
6292 p_enc->profile = atoi(value);
6293 }
6295 {
6296 /* Check specifically for Level 1b for H.264 */
6297 if (!strcasecmp(value, "1b"))
6298 {
6299 p_enc->level_idc = 99;
6300 }
6301 else
6302 {
6306 if (atof(value) <= 10)
6307 {
6308 p_enc->level_idc = (int)(10 * atof(value) + .5);
6309 }
6310 else
6311 {
6312 p_enc->level_idc = atoi(value);
6313 }
6314 }
6315 }
6317 {
6318 p_enc->high_tier = atobool(value);
6319 }
6321 {
6322 p_params->log = atoi(value);
6323 if (b_error)
6324 {
6325 b_error = false;
6326 p_params->log = ni_parse_name(value, g_xcoder_log_names, &b_error) - 1;
6327 }
6328 }
6330 {
6331 if ((atoi(value) > NI_MAX_GOP_PRESET_IDX) || (atoi(value) < NI_MIN_GOP_PRESET_IDX))
6332 {
6334 }
6335 p_enc->gop_preset_index = atoi(value);
6336 }
6338 {
6340 {
6342 }
6343
6344 p_enc->use_recommend_enc_params = atoi(value);
6345 }
6347 {
6348 if (QUADRA)
6349 {
6351 }
6352 if (((atoi(value) > NI_MAX_CU_SIZE_MODE) || (atoi(value) < NI_MIN_CU_SIZE_MODE)) && (atoi(value) != NI_DEFAULT_CU_SIZE_MODE))
6353 {
6355 }
6356
6357 p_enc->cu_size_mode = atoi(value);
6358 }
6360 {
6361 if (QUADRA)
6362 {
6364 }
6365 if ((atoi(value) > NI_MAX_MAX_NUM_MERGE) || (atoi(value) < NI_MIN_MAX_NUM_MERGE))
6366 {
6368 }
6369
6370 p_enc->max_num_merge = atoi(value);
6371 }
6373 {
6374 if (QUADRA)
6375 {
6377 }
6378 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6379 {
6381 }
6382
6383 p_enc->enable_dynamic_8x8_merge = atoi(value);
6384 }
6386 {
6387 if (QUADRA)
6388 {
6390 }
6391 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6392 {
6394 }
6395
6396 p_enc->enable_dynamic_16x16_merge = atoi(value);
6397 }
6399 {
6400 if (QUADRA)
6401 {
6403 }
6404 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6405 {
6407 }
6408
6409 p_enc->enable_dynamic_32x32_merge = atoi(value);
6410 }
6412 {
6413 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6414 {
6416 }
6417
6418 p_enc->rc.enable_rate_control = atoi(value);
6419 }
6421 {
6422 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6423 {
6425 }
6426
6427 p_enc->rc.enable_cu_level_rate_control = atoi(value);
6428 }
6430 {
6431 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6432 {
6434 }
6435 p_enc->rc.enable_hvs_qp = atoi(value);
6436 }
6438 {
6439 if (QUADRA)
6440 {
6442 }
6443 p_enc->rc.enable_hvs_qp_scale = atoi(value);
6444 }
6446 {
6447 p_enc->rc.hvs_qp_scale = atoi(value);
6448 }
6450 {
6451 p_enc->rc.min_qp = atoi(value);
6452 }
6454 {
6455 p_enc->rc.max_qp = atoi(value);
6456 }
6458 {
6459 if (QUADRA)
6460 {
6462 }
6463 p_enc->rc.max_delta_qp = atoi(value);
6464 }
6465#ifndef DEPRECATION_AS_ERROR
6467 {
6468 if ((atoi(value) > 51) || (atoi(value) < -1))
6469 {
6471 }
6472 p_enc->crf = atoi(value);
6473 }
6474#endif
6476 {
6477 p_enc->rc.vbv_buffer_size = atoi(value);
6478 if (QUADRA)
6479 {
6480 // RcInitDelay is deprecated and replaced with vbvBufferSize. But still accept the value.
6482 }
6483 }
6485 {
6486 p_enc->rc.vbv_buffer_size = atoi(value);
6487 }
6489 {
6490 p_enc->rc.vbv_max_rate = atoi(value);
6491 }
6493 {
6494 p_enc->rc.enable_filler = atoi(value);
6495 if (QUADRA)
6496 {
6497 // cbr is deprecated and replaced with fillerEnable. But still accept the value.
6499 }
6500 }
6502 {
6503 p_enc->rc.enable_filler = atoi(value);
6504 }
6506 {
6507 if (0 != atoi(value) && 1 != atoi(value))
6508 {
6510 }
6511 // Currenly pic skip is supported for low delay gops only - pic skip issues tracked by QDFW-1785/1958
6512 p_enc->rc.enable_pic_skip = atoi(value);
6513 }
6514#ifndef DEPRECATION_AS_ERROR
6516#else
6518#endif
6519 {
6520#ifdef _MSC_VER
6521 if (!_strnicmp(value, "ratio", 5))
6522#else
6523 if (!strncasecmp(value, "ratio", 5))
6524#endif
6525 {
6526 char value_buf[32] = {0};
6527 for (i = 0; i < sizeof(value_buf); i++)
6528 {
6529 if (value[i+6] == ']')
6530 {
6531 break;
6532 }
6533 value_buf[i] = value[i+6];
6534 }
6535 if (i == sizeof(value_buf) || atoi(value_buf) < 0)
6536 {
6538 }
6539
6540 p_enc->maxFrameSizeRatio = atoi(value_buf);
6541 }
6542 else
6543 {
6544 int size = atoi(value);
6545 if (size < NI_MIN_FRAME_SIZE)
6546 {
6548 }
6549 p_enc->maxFrameSize = (size > NI_MAX_FRAME_SIZE) ? NI_MAX_FRAME_SIZE : size;
6550 }
6551 }
6553 {
6554#ifdef _MSC_VER
6555 if (!_strnicmp(value, "ratio", 5))
6556#else
6557 if (!strncasecmp(value, "ratio", 5))
6558#endif
6559 {
6560 char value_buf[32] = {0};
6561 for (i = 0; i < sizeof(value_buf); i++)
6562 {
6563 if (value[i+6] == ']')
6564 {
6565 break;
6566 }
6567 value_buf[i] = value[i+6];
6568 }
6569 if (i == sizeof(value_buf) || atoi(value_buf) < 0)
6570 {
6572 }
6573
6574 p_enc->maxFrameSizeRatio = atoi(value_buf);
6575 }
6576 else
6577 {
6578 int size = atoi(value) / 8;
6579 if (size < NI_MIN_FRAME_SIZE)
6580 {
6582 }
6583 p_enc->maxFrameSize = (size > NI_MAX_FRAME_SIZE) ? NI_MAX_FRAME_SIZE : size;
6584 }
6585 }
6587 {
6588 if (0 != atoi(value) && 1 != atoi(value))
6589 {
6591 }
6592 p_enc->forced_header_enable = atoi(value);
6593 }
6595 {
6596 p_enc->roi_enable = atoi(value);
6597 }
6599 {
6600 p_enc->conf_win_top = atoi(value);
6601 }
6603 {
6604 p_enc->conf_win_bottom = atoi(value);
6605 }
6607 {
6608 p_enc->conf_win_left = atoi(value);
6609 }
6611 {
6612 p_enc->conf_win_right = atoi(value);
6613 }
6615 {
6616 p_enc->intra_period = atoi(value);
6617 //p_enc->bitrateWindow = p_enc->intra_period;
6618 }
6620 {
6621 if (atoi(value) > NI_MAX_BITRATE)
6622 {
6624 }
6625 if (atoi(value) < NI_MIN_BITRATE)
6626 {
6628 }
6629 p_enc->rc.trans_rate = atoi(value);
6630 }
6632 {
6633 if (atoi(value) <= 0 )
6634 {
6636 }
6637 p_params->fps_number = atoi(value);
6638 p_params->fps_denominator = 1;
6639 p_enc->frame_rate = (int)p_params->fps_number;
6640 }
6642 {
6643 if (atoi(value) <= 0)
6644 {
6646 }
6647 p_params->fps_denominator = atoi(value);
6648 p_enc->frame_rate = (int)(p_params->fps_number / p_params->fps_denominator);
6649 }
6651 {
6652 if ((atoi(value) > NI_MAX_INTRA_QP) || (atoi(value) < NI_MIN_INTRA_QP))
6653 {
6655 }
6656
6657 p_enc->rc.intra_qp = atoi(value);
6658 }
6660 {
6661 if ((atoi(value) > NI_MAX_INTRA_QP_DELTA) ||
6662 (atoi(value) < NI_MIN_INTRA_QP_DELTA))
6663 {
6665 }
6666
6667 p_enc->rc.intra_qp_delta = atoi(value);
6668 }
6670 {
6671 if ((atoi(value) > NI_MAX_INTRA_QP) || (atoi(value) < NI_MIN_INTRA_QP))
6672 {
6674 }
6675 p_params->force_pic_qp_demo_mode = atoi(value);
6676 }
6678 {
6679 if (QUADRA)
6680 {
6682 }
6684 {
6686 }
6687 p_enc->decoding_refresh_type = atoi(value);
6688 }
6690 {
6691 if (0 != atoi(value) && 1 != atoi(value))
6692 {
6694 }
6695 p_enc->intra_reset_refresh = atoi(value);
6696 }
6697 // Rev. B: H.264 only parameters.
6699 {
6700 if (QUADRA)
6701 {
6703 }
6704 p_enc->enable_transform_8x8 = atoi(value);
6705 }
6707 {
6708 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6709 {
6711 }
6712 p_enc->slice_mode = atoi(value);
6713 }
6715 {
6716 p_enc->slice_arg = atoi(value);
6717 }
6719 {
6720 if (0 != atoi(value) && 1 != atoi(value))
6721 {
6723 }
6724 p_enc->entropy_coding_mode = atoi(value);
6725 }
6726// Rev. B: shared between HEVC and H.264
6728 {
6729 p_enc->intra_mb_refresh_mode = atoi(value);
6730 }
6732 {
6733 p_enc->intra_mb_refresh_arg = atoi(value);
6734 }
6736 {
6737 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6738 {
6740 }
6741 p_enc->rc.enable_mb_level_rc = atoi(value);
6742 if (QUADRA)
6743 {
6744 // mbLevelRcEnable will be deprecated and cuLevelRCEnable should be used instead. But still accept the value.
6746 }
6747 }
6749 {
6750 if ((atoi(value) > 255) || (atoi(value) < 0))
6751 {
6753 }
6755 }
6757 {
6758 if (atoi(value) != 0 && atoi(value) != 5)
6759 {
6761 }
6762 p_params->dolby_vision_profile = atoi(value);
6763 }
6765 {
6766 if ((atoi(value) > 3) || (atoi(value) < 1))
6767 {
6769 }
6770 p_enc->rdoLevel = atoi(value);
6771 }
6773 {
6774 const char delim[2] = ",";
6775 char *chunk;
6776#ifdef _MSC_VER
6777 char *v = _strdup(value);
6778#else
6779 char *v = strdup(value);
6780#endif
6781 char *saveptr = NULL;
6782 chunk = ni_strtok(v, delim, &saveptr);
6783 if (chunk != NULL)
6784 {
6785 if ((atoi(chunk) > 65535) || (atoi(chunk) < 0))
6786 {
6787 free(v);
6789 }
6790 p_enc->HDR10MaxLight = atoi(chunk);
6791 chunk = ni_strtok(NULL, delim, &saveptr);
6792 if (chunk != NULL)
6793 {
6794 if ((atoi(chunk) > 65535) || (atoi(chunk) < 0))
6795 {
6796 free(v);
6798 }
6799 p_enc->HDR10AveLight = atoi(chunk);
6800 p_enc->HDR10CLLEnable = 1; //Both param populated so enable
6801 free(v);
6802 }
6803 else
6804 {
6805 free(v);
6807 }
6808 }
6809 else
6810 {
6811 free(v);
6813 }
6814 }
6815
6817 {
6818#ifdef _MSC_VER
6819#define STRDUP(value) _strdup(value);
6820#else
6821#define STRDUP(value) strdup(value);
6822#endif
6823 const char G[2] = "G";
6824 const char B[2] = "B";
6825 const char R[2] = "R";
6826 const char W[2] = "W";
6827 const char L[2] = "L";
6828 const char P[2] = "P";
6829 const char parL[2] = "(";
6830 const char comma[2] = ",";
6831 const char parR[2] = ")";
6832 int synCheck_GBRWLPCP[8];
6833 int posCheck_GBRWL[5] = {0};
6834 char *chunk;//for parsing out more complex inputs
6835 char *subchunk;
6836 char *v = STRDUP(value);
6837 //basic check syntax correct
6838 for (i = 0; i<8; i++)
6839 {
6840 synCheck_GBRWLPCP[i] = 0;
6841 }
6842 chunk = v;
6843 i = 0; // character index
6844
6845 //count keys and punctuation, save indicies to be parsed
6846 while (*chunk) {
6847 if (*chunk == G[0])
6848 {
6849 synCheck_GBRWLPCP[0]++;
6850 posCheck_GBRWL[0] = i;
6851 }
6852 else if (*chunk == B[0])
6853 {
6854 synCheck_GBRWLPCP[1]++;
6855 posCheck_GBRWL[1] = i;
6856 }
6857 else if (*chunk == R[0])
6858 {
6859 synCheck_GBRWLPCP[2]++;
6860 posCheck_GBRWL[2] = i;
6861 }
6862 else if (*chunk == W[0])
6863 {
6864 synCheck_GBRWLPCP[3]++;
6865 posCheck_GBRWL[3] = i;
6866 }
6867 else if (*chunk == L[0])
6868 {
6869 synCheck_GBRWLPCP[4]++;
6870 posCheck_GBRWL[4] = i;
6871 }
6872 else if (*chunk == parL[0])
6873 {
6874 synCheck_GBRWLPCP[5]++;
6875 }
6876 else if (*chunk == comma[0])
6877 {
6878 synCheck_GBRWLPCP[6]++;
6879 }
6880 else if (*chunk == parR[0])
6881 {
6882 synCheck_GBRWLPCP[7]++;
6883 }
6884 chunk++;
6885 i++;
6886 }
6887 free(v);
6888 if (synCheck_GBRWLPCP[0] != 1 || synCheck_GBRWLPCP[1] != 1 || synCheck_GBRWLPCP[2] != 1 ||
6889 synCheck_GBRWLPCP[3] != 1 || synCheck_GBRWLPCP[4] != 1 || synCheck_GBRWLPCP[5] != 5 ||
6890 synCheck_GBRWLPCP[6] != 5 || synCheck_GBRWLPCP[7] != 5)
6891 {
6893 }
6894
6895 //Parse a key-value set like G(%hu, %hu)
6896#define GBRWLPARSE(OUT1,OUT2,OFF,IDX) \
6897{ \
6898 char *v = STRDUP(value); \
6899 chunk = v + posCheck_GBRWL[IDX]; \
6900 i = j = k = 0; \
6901 while (chunk != NULL) \
6902 { \
6903 if (*chunk == parL[0] && i == 1+(OFF)) \
6904 { \
6905 j = 1; \
6906 } \
6907 if((OFF) == 1 && *chunk != P[0] && i == 1) \
6908 { \
6909 break; \
6910 } \
6911 if (*chunk == parR[0]) \
6912 { \
6913 k = 1; \
6914 break; \
6915 } \
6916 i++; \
6917 chunk++; \
6918 } \
6919 if (!j || !k) \
6920 { \
6921 free(v); \
6922 return NI_RETCODE_PARAM_INVALID_VALUE; \
6923 } \
6924 subchunk = malloc(i - 1 - (OFF)); \
6925 if (subchunk == NULL) \
6926 { \
6927 free(v); \
6928 return NI_RETCODE_ERROR_MEM_ALOC; \
6929 } \
6930 memcpy(subchunk, v + posCheck_GBRWL[IDX] + 2 + (OFF), i - 2 - (OFF)); \
6931 subchunk[i - 2 - (OFF)] = '\0'; \
6932 char *saveptr = NULL; \
6933 chunk = ni_strtok(subchunk, comma, &saveptr); \
6934 if (chunk != NULL) \
6935 { \
6936 if(atoi(chunk) < 0) \
6937 { \
6938 free(v); \
6939 if(subchunk != NULL){ \
6940 free(subchunk); \
6941 } \
6942 return NI_RETCODE_PARAM_INVALID_VALUE; \
6943 } \
6944 *(OUT1) = atoi(chunk); \
6945 } \
6946 chunk = ni_strtok(NULL, comma, &saveptr); \
6947 if (chunk != NULL) \
6948 { \
6949 if(atoi(chunk) < 0) \
6950 { \
6951 free(v); \
6952 if(subchunk != NULL){ \
6953 free(subchunk); \
6954 } \
6955 return NI_RETCODE_PARAM_INVALID_VALUE; \
6956 } \
6957 *(OUT2) = atoi(chunk); \
6958 } \
6959 free(subchunk); \
6960 free(v); \
6961}
6962 GBRWLPARSE(&p_enc->HDR10dx0, &p_enc->HDR10dy0, 0, 0);
6963 GBRWLPARSE(&p_enc->HDR10dx1, &p_enc->HDR10dy1, 0, 1);
6964 GBRWLPARSE(&p_enc->HDR10dx2, &p_enc->HDR10dy2, 0, 2);
6965 GBRWLPARSE(&p_enc->HDR10wx, &p_enc->HDR10wy, 1, 3);
6966 GBRWLPARSE(&p_enc->HDR10maxluma, &p_enc->HDR10minluma, 0, 4);
6967 p_enc->HDR10Enable = 1;
6968 }
6970 {
6971 if (atoi(value)!= 0 && ((atoi(value) > 40 ) || (atoi(value) < 4)))
6972 {
6974 }
6975 p_enc->lookAheadDepth = atoi(value);
6976 }
6978 {
6979 if (atoi(value) != 0 && atoi(value) != 1)
6980 {
6982 }
6983 p_enc->hrdEnable = atoi(value);
6984 }
6986 {
6987 if ((atoi(value) != 0) && (atoi(value) != 1))
6988 {
6990 }
6991 p_enc->EnableAUD = atoi(value);
6992 }
6994 {
6995 if (atoi(value) != 0 && atoi(value) != 1)
6996 {
6998 }
6999 p_params->cacheRoi = atoi(value);
7000 }
7002 {
7003 if (atoi(value) != 0 && atoi(value) != 1)
7004 {
7006 }
7007 p_enc->long_term_ref_enable = atoi(value);
7008 }
7010 {
7011 p_enc->long_term_ref_interval = atoi(value);
7012 }
7014 {
7015 if (atoi(value) < 1 || atoi(value) > 2)
7016 {
7018 }
7019 p_enc->long_term_ref_count = atoi(value);
7020 }
7022 {
7023 if ((atoi(value) != 0) && (atoi(value) != 1))
7024 {
7026 }
7027 p_enc->EnableRdoQuant = atoi(value);
7028 }
7030 {
7031 if (QUADRA)
7032 {
7034 }
7035
7036 if ((atoi(value) < 0) || (atoi(value) > 3))
7037 {
7039 }
7040 p_enc->ctbRcMode = atoi(value);
7041 }
7043 {
7044 if (QUADRA)
7045 {
7047 }
7048
7049 p_enc->gopSize = atoi(value);
7050 }
7052 {
7053 if (QUADRA)
7054 {
7056 }
7057
7058 if ((atoi(value) != 0) && (atoi(value) != 1))
7059 {
7061 }
7062 p_enc->gopLowdelay = atoi(value);
7063 }
7065 {
7066 if (QUADRA)
7067 {
7069 }
7070 p_enc->gdrDuration = atoi(value);
7071 }
7073 {
7074 p_enc->ltrRefInterval = atoi(value);
7075 }
7077 {
7078 p_enc->ltrRefQpOffset = atoi(value);
7079 }
7081 {
7082 p_enc->ltrFirstGap = atoi(value);
7083 }
7086 {
7087 if ((atoi(value) != 0) && (atoi(value) != 1))
7088 {
7090 }
7091 p_enc->multicoreJointMode = atoi(value);
7092 }
7094 {
7095 if ((atoi(value) < 0) || (atoi(value) > 9))
7096 {
7098 }
7099 p_enc->qlevel = atoi(value);
7100 }
7102 {
7103 if ((atoi(value) > 12) || (atoi(value) < -12))
7104 {
7106 }
7107 p_enc->chromaQpOffset = atoi(value);
7108 }
7109 OPT(NI_ENC_PARAM_TOL_RC_INTER) { p_enc->tolCtbRcInter = (float)atof(value); }
7110 OPT(NI_ENC_PARAM_TOL_RC_INTRA) { p_enc->tolCtbRcIntra = (float)atof(value); }
7112 {
7113 if ((atoi(value) > 300) || (atoi(value) < 1))
7114 {
7116 }
7117 p_enc->bitrateWindow = atoi(value);
7118 }
7120 {
7121 if ((atoi(value) > 2) || (atoi(value) < 0))
7122 {
7124 }
7125 p_enc->blockRCSize = atoi(value);
7126 }
7128 {
7129 if ((atoi(value) > 15) || (atoi(value) < 0))
7130 {
7132 }
7133 p_enc->rcQpDeltaRange = atoi(value);
7134 }
7136 {
7137 if ((atoi(value) > 500) || (atoi(value) < 0))
7138 {
7140 }
7141 p_enc->ctbRowQpStep = atoi(value);
7142 }
7144 {
7145 if ((atoi(value) > 1) || (atoi(value) < 0))
7146 {
7148 }
7149 p_enc->newRcEnable = atoi(value);
7150 }
7152 {
7153 if ((atoi(value) > 1) || (atoi(value) < 0))
7154 {
7156 }
7157 p_enc->inLoopDSRatio = atoi(value);
7158 }
7160 {
7161 COMPARE(value, 22, 0)
7162 p_params->color_primaries = p_enc->colorPrimaries = atoi(value);
7163 p_enc->colorDescPresent = 1;
7164 }
7166 {
7167 COMPARE(value, 18, 0)
7168 p_params->color_transfer_characteristic = p_enc->colorTrc = atoi(value);
7169 p_enc->colorDescPresent = 1;
7170 }
7172 {
7173 COMPARE(value, 14, 0)
7174 p_params->color_space = p_enc->colorSpace = atoi(value);
7175 p_enc->colorDescPresent = 1;
7176 }
7178 {
7179 p_params->sar_num = p_enc->aspectRatioWidth = atoi(value);
7180 }
7182 {
7183 p_params->sar_denom = p_enc->aspectRatioHeight = atoi(value);
7184 }
7186 {
7187 p_params->video_full_range_flag = p_enc->videoFullRange = atoi(value);
7188 }
7190 {
7191 if ((atoi(value) < NI_MIN_KEEP_ALIVE_TIMEOUT) ||
7193 {
7195 }
7196 p_enc->keep_alive_timeout = atoi(value);
7197 }
7199 {
7200 if (atoi(value) != 0 && atoi(value) != 1)
7201 {
7203 }
7204 p_params->enable_vfr = atoi(value);
7205 }
7207 {
7208 if (atoi(value) < 0 || atoi(value) > 3)
7209 {
7211 }
7212 p_enc->get_psnr_mode = atoi(value);
7213 }
7215 {
7216 if (atoi(value) < 1)
7217 {
7219 }
7220 p_params->interval_of_psnr = atoi(value);
7221 }
7223 {
7224 if (atoi(value) < 0 || atoi(value) > 1)
7225 {
7227 }
7228 p_enc->get_psnr_mode = atoi(value) + 3;
7229 }
7231 {
7232 if ((atoi(value) != 0) && (atoi(value) != 1))
7233 {
7235 }
7236 p_enc->enable_ssim = atoi(value);
7237 }
7239 {
7240 if ((atoi(value) != 0) && (atoi(value) != 1))
7241 {
7243 }
7244 p_enc->av1_error_resilient_mode = atoi(value);
7245 }
7247 {
7248 if ((atoi(value) != 0) && (atoi(value) != 1))
7249 {
7251 }
7252 p_params->staticMmapThreshold = atoi(value);
7253 }
7255 {
7256 p_enc->temporal_layers_enable = atoi(value);
7257 }
7259 {
7260 if ((atoi(value) != 0) && (atoi(value) != 1))
7261 {
7263 }
7264 p_params->enable_ai_enhance = atoi(value);
7265 }
7267 {
7268 if ((atoi(value) != 0) && (atoi(value) != 1))
7269 {
7271 }
7272 if(p_params->enable_ai_enhance)
7273 {
7274 ni_log(NI_LOG_ERROR, "Cannot set enableAIEnhance and enableHVSPlus at same time, just enableHVSPlus\n");
7275 }
7276 p_params->enable_ai_enhance = (atoi(value) == 1) ? 2 : 0;
7277 }
7279 {
7280 if ((atoi(value) != 0) && (atoi(value) != 1))
7281 {
7283 }
7284 p_params->enable2PassGop = atoi(value);
7285 }
7287 {
7288 if ((atoi(value) != 0) && (atoi(value) != 1) && (atoi(value) != -1))
7289 {
7291 }
7292 p_params->zerocopy_mode = atoi(value);
7293 }
7295 {
7296 if ((atoi(value) == 0) || (atoi(value) > 3))
7297 {
7299 }
7300 p_params->ai_enhance_level = atoi(value);
7301 }
7303 {
7304 if ((atoi(value) == 0) || (atoi(value) > 2))
7305 {
7307 }
7308 p_params->ai_enhance_level = atoi(value);
7309 }
7311 {
7312 if ((atoi(value) < NI_MIN_WIDTH) ||
7313 (atoi(value) > NI_PARAM_MAX_WIDTH))
7314 {
7316 }
7317 p_enc->crop_width = atoi(value);
7318 }
7320 {
7321 if ((atoi(value) < NI_MIN_HEIGHT) ||
7322 (atoi(value) > NI_PARAM_MAX_HEIGHT))
7323 {
7325 }
7326 p_enc->crop_height = atoi(value);
7327 }
7329 {
7330 if ((atoi(value) < 0) ||
7331 (atoi(value) > NI_PARAM_MAX_WIDTH))
7332 {
7334 }
7335 p_enc->hor_offset = atoi(value);
7336 }
7338 {
7339 if ((atoi(value) < 0) ||
7340 (atoi(value) > NI_PARAM_MAX_HEIGHT))
7341 {
7343 }
7344 p_enc->ver_offset = atoi(value);
7345 }
7347 {
7348 if ((atoi(value) > 51) || (atoi(value) < -1))
7349 {
7351 }
7352 p_enc->crfMax = atoi(value);
7353 }
7355 {
7356 if ((atof(value) > 1.0) || (atof(value) < 0.0))
7357 {
7359 }
7360 p_enc->qcomp = (float)atof(value);
7361 }
7363 {
7364 if ((atoi(value) != 0) && (atoi(value) != 1))
7365 {
7367 }
7368 p_enc->noMbtree = atoi(value);
7369 }
7371 {
7372 if ((atoi(value) != 0) && (atoi(value) != 1))
7373 {
7375 }
7376 p_enc->avcc_hvcc = atoi(value);
7377 }
7379 {
7380 if ((atoi(value) != 0) && (atoi(value) != 1))
7381 {
7383 }
7384 p_enc->noHWMultiPassSupport = atoi(value);
7385 }
7387 {
7388 if ((atoi(value) > 10) || (atoi(value) < 1))
7389 {
7391 }
7392 p_enc->cuTreeFactor = atoi(value);
7393 }
7395 {
7396 if ((atof(value) > 10.0) || (atof(value) < 0.01))
7397 {
7399 }
7400 p_enc->ipRatio = (float)atof(value);
7401 }
7403 {
7404 if ((atoi(value) != 0) && (atoi(value) != 1))
7405 {
7407 }
7408 p_enc->enableipRatio = atoi(value);
7409 }
7411 {
7412 if ((atof(value) > 10.0) || (atof(value) < 0.01))
7413 {
7415 }
7416 p_enc->pbRatio = (float)atof(value);
7417 }
7419 {
7420 if ((atof(value) > 1.0) || (atof(value) < 0.1))
7421 {
7423 }
7424 p_enc->cplxDecay = (float)atof(value);
7425 }
7427 {
7428 if ((atoi(value) > 51) || (atoi(value) < -1))
7429 {
7431 }
7432 p_enc->pps_init_qp = atoi(value);
7433 }
7435 {
7436 if (atoi(value) >= NI_DDR_PRIORITY_MAX ||
7437 atoi(value) <= NI_DDR_PRIORITY_NONE)
7438 {
7440 }
7441 p_params->ddr_priority_mode = atoi(value);
7442 }
7444 {
7445 if ((atoi(value) != 0) && (atoi(value) != 1))
7446 {
7448 }
7449 p_enc->bitrateMode = atoi(value);
7450 }
7452 {
7453 if ((atoi(value) > 51) || (atoi(value) < -1))
7454 {
7456 }
7457 p_enc->pass1_qp = atoi(value);
7458 }
7460 {
7461 if (((atof(value) < 0.0) && (atof(value) != -1.0)) ||
7462 (atof(value) > 51.00))
7463 {
7465 }
7466 p_enc->crfFloat = (float)atof(value);
7467 }
7469 {
7470 if ((atoi(value) < 0) || (atoi(value) > 31))
7471 {
7473 }
7474 p_enc->hvsBaseMbComplexity = atoi(value);
7475 }
7477 {
7478 if (atoi(value) != 0 && atoi(value) != 1 && atoi(value) != 6)
7479 {
7481 }
7482 p_enc->statistic_output_level = atoi(value);
7483 }
7485 {
7486 //Currently only support 6 stillImage detect level
7487 //0-3: no performance drop
7488 //4-6: performance drop
7489 if ((atoi(value) < 0 || atoi(value) > 6))
7490 {
7492 }
7493 p_enc->still_image_detect_level = atoi(value);
7494 }
7496 {
7497 //Currently only support 10 sceneChange detect level
7498 //1-5 : no performance drop
7499 //6-10: performance drop
7500 if ((atoi(value) < 0 || atoi(value) > 10))
7501 {
7503 }
7504 p_enc->scene_change_detect_level = atoi(value);
7505 }
7507 {
7508 if ((atoi(value) != 0) && (atoi(value) != 1))
7509 {
7511 }
7512 p_enc->enable_smooth_crf = atoi(value);
7513 }
7515 {
7516 if ((atoi(value) != 0) && (atoi(value) != 1))
7517 {
7519 }
7520 p_enc->enable_compensate_qp = atoi(value);
7521 }
7523 {
7524 if (atoi(value) < 0 || atoi(value) > 1)
7525 {
7527 }
7528 p_enc->skip_frame_enable = atoi(value);
7529 }
7531 {
7532 if (atoi(value) < 0)
7533 {
7535 }
7536 p_enc->max_consecutive_skip_num = atoi(value);
7537 }
7539 {
7540 if (atoi(value) < 0 || atoi(value) > 255)
7541 {
7543 }
7544 p_enc->skip_frame_interval = atoi(value);
7545 }
7547 {
7548 if (atoi(value) != 0 && atoi(value) != 1)
7549 {
7551 }
7552 p_enc->enable_all_sei_passthru = atoi(value);
7553 }
7555 {
7556 if (atoi(value) <= 0)
7557 {
7559 }
7560 p_enc->iframe_size_ratio = atoi(value);
7561 }
7563 {
7564 if ((atoi(value) < 0 || atoi(value) > 2) &&
7565 atoi(value) != 5 && atoi(value) != 6 && atoi(value) != 7) // 1 & 5=MEDIUM, 2 & 6=HIGH, 7=OPTIMAL
7566 {
7568 }
7569 p_enc->crf_max_iframe_enable = atoi(value);
7570 }
7572 {
7573 p_enc->vbv_min_rate = atoi(value);
7574 }
7576 {
7577 if (atoi(value) != 0 && atoi(value) != 1)
7578 {
7580 }
7581 p_enc->disable_adaptive_buffers = atoi(value);
7582 }
7584 {
7585 if ((atoi(value) != 0) && (atoi(value) != 1))
7586 {
7588 }
7589 p_enc->disableBframeRdoq = atoi(value);
7590 }
7592 {
7593 if ((atof(value) > 1.0) || (atof(value) < 0.0))
7594 {
7596 }
7597 p_enc->forceBframeQpfactor = (float)atof(value);
7598 }
7600 {
7601 if (atoi(value) < 0 || atoi(value) > 2)
7602 {
7604 }
7605 p_enc->tune_bframe_visual = atoi(value);
7606 }
7608 {
7609 if ((atoi(value) != 0) && (atoi(value) != 1))
7610 {
7612 }
7613 p_enc->enable_acq_limit = atoi(value);
7614 }
7616 {
7617 if (atoi(value) < NI_CUS_ROI_DISABLE || atoi(value) > NI_CUS_ROI_MERGE)
7618 {
7620 }
7621 p_enc->customize_roi_qp_level += atoi(value);
7622 }
7624 {
7626 if (retval != NI_RETCODE_SUCCESS)
7627 {
7628 return retval;
7629 }
7630 // indicate it need to upload roi qp map
7631 p_enc->customize_roi_qp_level += 64;
7632 }
7634 {
7635 if (atoi(value) < 0 || atoi(value) > MOTION_CONSTRAINED_MODE_MAX)
7636 {
7638 }
7639 p_enc->motionConstrainedMode = atoi(value);
7640 }
7642 {
7645 {
7647 }
7648 p_enc->encMallocStrategy = atoi(value);
7649 }
7651 {
7652 if (atoi(value) < 1 || atoi(value) > 4)
7653 {
7655 }
7656 p_enc->spatial_layers = atoi(value);
7657 }
7659 {
7660 if (atoi(value) < 0 || atoi(value) > 1)
7661 {
7663 }
7664 p_enc->enable_timecode = atoi(value);
7665 }
7667 {
7668 if ((atoi(value) != 0) && (atoi(value) != 1))
7669 {
7671 }
7672 p_enc->spatial_layers_ref_base_layer = atoi(value);
7673 }
7675 {
7676 if ((atoi(value) != 0) && (atoi(value) != 1))
7677 {
7679 }
7680 p_enc->vbvBufferReencode = atoi(value);
7681 }
7683 {
7684 if (atoi(value)!= 0 && ((atoi(value) > 40 ) || (atoi(value) < 4)))
7685 {
7687 }
7688 p_enc->totalCuTreeDepth = atoi(value);
7689 }
7691 {
7692 if (atoi(value) != 0 && atoi(value) != 1)
7693 {
7695 }
7696 p_enc->adaptiveCuTree = atoi(value);
7697 }
7699 {
7700 if (atoi(value) != 0 && atoi(value) != 1)
7701 {
7703 }
7704 p_enc->preIntraHandling = atoi(value);
7705 }
7707 {
7708 if (atoi(value) != 0 && atoi(value) != 1)
7709 {
7711 }
7712 p_enc->baseLayerOnly = atoi(value);
7713 }
7715 {
7716 if (atoi(value) < 0 || atoi(value) > 100)
7717 {
7719 }
7720 p_enc->pastFrameMaxIntraRatio = atoi(value);
7721 }
7723 {
7724 if (atoi(value) < 0 || atoi(value) > 100)
7725 {
7727 }
7728 p_enc->linkFrameMaxIntraRatio = atoi(value);
7729 }
7731 {
7732 const char delim[2] = ",";
7733 char *chunk;
7734#ifdef _MSC_VER
7735 char *v = _strdup(value);
7736#else
7737 char *v = strdup(value);
7738#endif
7739 char *saveptr = NULL;
7740 i = 0;
7741 chunk = ni_strtok(v, delim, &saveptr);
7742 while (chunk != NULL && i < NI_MAX_SPATIAL_LAYERS)
7743 {
7744 if ((atoi(chunk) > NI_MAX_BITRATE) || (atoi(chunk) < NI_MIN_BITRATE))
7745 {
7746 free(v);
7748 }
7749 p_enc->spatialLayerBitrate[i] = atoi(chunk);
7750 chunk = ni_strtok(NULL, delim, &saveptr);
7751 i++;
7752 }
7753 free(v);
7754 }
7756 {
7757 const char delim[2] = ",";
7758 char *chunk;
7759#ifdef _MSC_VER
7760 char *v = _strdup(value);
7761#else
7762 char *v = strdup(value);
7763#endif
7764 char *saveptr = NULL;
7765 i = 0;
7766 chunk = ni_strtok(v, delim, &saveptr);
7767 while (chunk != NULL && i < NI_MAX_SPATIAL_LAYERS)
7768 {
7772 if (atof(chunk) <= 10)
7773 {
7774 p_enc->av1OpLevel[i] = (int)(10 * atof(chunk) + .5);
7775 }
7776 else
7777 {
7778 p_enc->av1OpLevel[i] = atoi(chunk);
7779 }
7780 chunk = ni_strtok(NULL, delim, &saveptr);
7781 i++;
7782 }
7783 free(v);
7784 }
7786 {
7787 if ((atoi(value) != 0) && (atoi(value) != 1))
7788 {
7790 }
7791 p_enc->disableAv1TimingInfo = atoi(value);
7792 }
7794 {
7795 if ((atoi(value) != 0) && (atoi(value) != 1))
7796 {
7798 }
7799 p_params->enableCpuAffinity = atoi(value);
7800 }
7802 {
7803 for (i = 0; i < NI_NUM_PRESETS_MAX; i++) {
7804 if (0 == strcmp(value, g_xcoder_preset_names[i])) {
7805 p_enc->preset_index = i;
7806 break;
7807 }
7808 else if(i == NI_NUM_PRESETS_MAX - 1) {
7810 }
7811 }
7812 }
7814 {
7815 if (atoi(value) < 0 || atoi(value) > 3)
7816 {
7818 }
7819 p_enc->adaptiveLamdaMode = atoi(value);
7820 }
7822 {
7823 if (atoi(value) < 0 || atoi(value) > 1)
7824 {
7826 }
7827 p_enc->qpScaleEnable = atoi(value);
7828 }
7830 {
7831 if (atoi(value) < 0 || atoi(value) > 2)
7832 {
7834 }
7835 p_enc->adaptiveCrfMode = atoi(value);
7836 }
7838 {
7839 if (atoi(value) < 0 || atoi(value) > 3)
7840 {
7842 }
7843 p_enc->intraCompensateMode = atoi(value);
7844 }
7846 {
7847 if (atoi(value) < 0 || atoi(value) > 255)
7848 {
7850 }
7851 p_enc->customMinCoeffDiv = atoi(value);
7852 }
7854 {
7855 if ((atoi(value) != 0) && (atoi(value) != 1))
7856 {
7858 }
7859 p_enc->getBitstreamFeatures = atoi(value);
7860 }
7861 else { return NI_RETCODE_PARAM_INVALID_NAME; }
7862
7863#undef OPT
7864#undef OPT2
7865#undef atobool
7866#undef atoi
7867#undef atof
7868
7869 b_error |= bValueWasNull && !bNameWasBool;
7870
7871 ni_log(NI_LOG_TRACE, "%s: exit, b_error=%d\n", __func__, b_error);
7872
7874}
7875
7876#undef atoi
7877#undef atof
7878#define atoi(p_str) ni_atoi(p_str, &b_error)
7879#define atof(p_str) ni_atof(p_str, &b_error)
7880#define atobool(p_str) (ni_atobool(p_str, &b_error))
7881
7882/*!*****************************************************************************
7883 * \brief Set GOP parameter value referenced by name in encoder parameters
7884 * structure
7885 *
7886 * \param[in] p_params Pointer to a user allocated ni_xcoder_params_t
7887 * to find and set a particular parameter
7888 * \param[in] name String represented parameter name to search
7889 * \param[in] value Parameter value to set
7890*
7891 * \return On success
7892 * NI_RETCODE_SUCCESS
7893 * On failure
7894 * NI_RETCODE_FAILURE
7895 * NI_RETCODE_INVALID_PARAM
7896 ******************************************************************************/
7898 const char *name,
7899 const char *value)
7900{
7901 bool b_error = false;
7902 bool bNameWasBool = false;
7903 bool bValueWasNull = !value;
7904 ni_encoder_cfg_params_t *p_enc = NULL;
7905 ni_custom_gop_params_t* p_gop = NULL;
7906 char nameBuf[64] = { 0 };
7907
7908 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
7909
7910 if (!p_params)
7911 {
7912 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
7913 __func__);
7915 }
7916
7917 if ( !name )
7918 {
7919 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
7920 __func__);
7922 }
7923 p_enc = &p_params->cfg_enc_params;
7924 p_gop = &p_enc->custom_gop_params;
7925
7926 // skip -- prefix if provided
7927 if (name[0] == '-' && name[1] == '-')
7928 {
7929 name += 2;
7930 }
7931
7932 // s/_/-/g
7933 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
7934 {
7935 char* c;
7936 ni_strcpy(nameBuf, sizeof(nameBuf), name);
7937 while ((c = strchr(nameBuf, '_')) != 0)
7938 {
7939 *c = '-';
7940 }
7941 name = nameBuf;
7942 }
7943
7944 if (!value)
7945 {
7946 value = "true";
7947 }
7948 else if (value[0] == '=')
7949 {
7950 value++;
7951 }
7952
7953#if defined(_MSC_VER)
7954#define OPT(STR) else if (!_stricmp(name, STR))
7955#else
7956#define OPT(STR) else if (!strcasecmp(name, STR))
7957#endif
7958 if (0); // suppress cppcheck
7960 {
7961 if (atoi(value) > NI_MAX_GOP_SIZE)
7962 {
7964 }
7965 if (atoi(value) < NI_MIN_GOP_SIZE)
7966 {
7968 }
7969 p_gop->custom_gop_size = atoi(value);
7970 }
7971
7972#ifndef QUADRA
7974 {
7975 p_gop->pic_param[0].pic_type = atoi(value);
7976 }
7978 {
7979 p_gop->pic_param[0].poc_offset = atoi(value);
7980 }
7981 OPT(NI_ENC_GOP_PARAMS_G0_PIC_QP)
7982 {
7983 p_gop->pic_param[0].pic_qp = atoi(value);
7984 }
7985 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC_L0)
7986 {
7987 p_gop->pic_param[0].num_ref_pic_L0 = atoi(value);
7988 }
7989 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_POC_L0)
7990 {
7991 p_gop->pic_param[0].ref_poc_L0 = atoi(value);
7992 }
7993 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_POC_L1)
7994 {
7995 p_gop->pic_param[0].ref_poc_L1 = atoi(value);
7996 }
7998 {
7999 p_gop->pic_param[0].temporal_id = atoi(value);
8000 }
8001
8003 {
8004 p_gop->pic_param[1].pic_type = atoi(value);
8005 }
8007 {
8008 p_gop->pic_param[1].poc_offset = atoi(value);
8009 }
8010 OPT(NI_ENC_GOP_PARAMS_G1_PIC_QP)
8011 {
8012 p_gop->pic_param[1].pic_qp = atoi(value);
8013 }
8014 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC_L0)
8015 {
8016 p_gop->pic_param[1].num_ref_pic_L0 = atoi(value);
8017 }
8018 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_POC_L0)
8019 {
8020 p_gop->pic_param[1].ref_poc_L0 = atoi(value);
8021 }
8022 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_POC_L1)
8023 {
8024 p_gop->pic_param[1].ref_poc_L1 = atoi(value);
8025 }
8027 {
8028 p_gop->pic_param[1].temporal_id = atoi(value);
8029 }
8030
8032 {
8033 p_gop->pic_param[2].pic_type = atoi(value);
8034 }
8036 {
8037 p_gop->pic_param[2].poc_offset = atoi(value);
8038 }
8039 OPT(NI_ENC_GOP_PARAMS_G2_PIC_QP)
8040 {
8041 p_gop->pic_param[2].pic_qp = atoi(value);
8042 }
8043 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC_L0)
8044 {
8045 p_gop->pic_param[2].num_ref_pic_L0 = atoi(value);
8046 }
8047 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_POC_L0)
8048 {
8049 p_gop->pic_param[2].ref_poc_L0 = atoi(value);
8050 }
8051 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_POC_L1)
8052 {
8053 p_gop->pic_param[2].ref_poc_L1 = atoi(value);
8054 }
8056 {
8057 p_gop->pic_param[2].temporal_id = atoi(value);
8058 }
8059
8061 {
8062 p_gop->pic_param[3].pic_type = atoi(value);
8063 }
8065 {
8066 p_gop->pic_param[3].poc_offset = atoi(value);
8067 }
8068 OPT(NI_ENC_GOP_PARAMS_G3_PIC_QP)
8069 {
8070 p_gop->pic_param[3].pic_qp = atoi(value);
8071 }
8072 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC_L0)
8073 {
8074 p_gop->pic_param[3].num_ref_pic_L0 = atoi(value);
8075 }
8076 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_POC_L0)
8077 {
8078 p_gop->pic_param[3].ref_poc_L0 = atoi(value);
8079 }
8080 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_POC_L1)
8081 {
8082 p_gop->pic_param[3].ref_poc_L1 = atoi(value);
8083 }
8085 {
8086 p_gop->pic_param[3].temporal_id = atoi(value);
8087 }
8088
8090 {
8091 p_gop->pic_param[4].pic_type = atoi(value);
8092 }
8094 {
8095 p_gop->pic_param[4].poc_offset = atoi(value);
8096 }
8097 OPT(NI_ENC_GOP_PARAMS_G4_PIC_QP)
8098 {
8099 p_gop->pic_param[4].pic_qp = atoi(value);
8100 }
8101 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC_L0)
8102 {
8103 p_gop->pic_param[4].num_ref_pic_L0 = atoi(value);
8104 }
8105 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_POC_L0)
8106 {
8107 p_gop->pic_param[4].ref_poc_L0 = atoi(value);
8108 }
8109 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_POC_L1)
8110 {
8111 p_gop->pic_param[4].ref_poc_L1 = atoi(value);
8112 }
8114 {
8115 p_gop->pic_param[4].temporal_id = atoi(value);
8116 }
8117
8119 {
8120 p_gop->pic_param[5].pic_type = atoi(value);
8121 }
8123 {
8124 p_gop->pic_param[5].poc_offset = atoi(value);
8125 }
8126 OPT(NI_ENC_GOP_PARAMS_G5_PIC_QP)
8127 {
8128 p_gop->pic_param[5].pic_qp = atoi(value);
8129 }
8130 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC_L0)
8131 {
8132 p_gop->pic_param[5].num_ref_pic_L0 = atoi(value);
8133 }
8134 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_POC_L0)
8135 {
8136 p_gop->pic_param[5].ref_poc_L0 = atoi(value);
8137 }
8138 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_POC_L1)
8139 {
8140 p_gop->pic_param[5].ref_poc_L1 = atoi(value);
8141 }
8143 {
8144 p_gop->pic_param[5].temporal_id = atoi(value);
8145 }
8146
8148 {
8149 p_gop->pic_param[6].pic_type = atoi(value);
8150 }
8152 {
8153 p_gop->pic_param[6].poc_offset = atoi(value);
8154 }
8155 OPT(NI_ENC_GOP_PARAMS_G6_PIC_QP)
8156 {
8157 p_gop->pic_param[6].pic_qp = atoi(value);
8158 }
8159 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC_L0)
8160 {
8161 p_gop->pic_param[6].num_ref_pic_L0 = atoi(value);
8162 }
8163 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_POC_L0)
8164 {
8165 p_gop->pic_param[6].ref_poc_L0 = atoi(value);
8166 }
8167 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_POC_L1)
8168 {
8169 p_gop->pic_param[6].ref_poc_L1 = atoi(value);
8170 }
8172 {
8173 p_gop->pic_param[6].temporal_id = atoi(value);
8174 }
8175
8177 {
8178 p_gop->pic_param[7].pic_type = atoi(value);
8179 }
8181 {
8182 p_gop->pic_param[7].poc_offset = atoi(value);
8183 }
8184 OPT(NI_ENC_GOP_PARAMS_G7_PIC_QP)
8185 {
8186 p_gop->pic_param[7].pic_qp = atoi(value);
8187 }
8188 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC_L0)
8189 {
8190 p_gop->pic_param[7].num_ref_pic_L0 = atoi(value);
8191 }
8192 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_POC_L0)
8193 {
8194 p_gop->pic_param[7].ref_poc_L0 = atoi(value);
8195 }
8196 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_POC_L1)
8197 {
8198 p_gop->pic_param[7].ref_poc_L1 = atoi(value);
8199 }
8201 {
8202 p_gop->pic_param[7].temporal_id = atoi(value);
8203 }
8204 else
8205 {
8206 ni_log(NI_LOG_ERROR, "%s(): Invalid parameter name passed\n", __func__);
8208 }
8209#else
8211 {
8212 p_gop->pic_param[0].poc_offset = atoi(value);
8213 }
8215 {
8216 p_gop->pic_param[0].qp_offset = atoi(value);
8217 }
8218 /*
8219 OPT(NI_ENC_GOP_PARAMS_G0_QP_FACTOR)
8220 {
8221 p_gop->pic_param[0].qp_factor = atof(value);
8222 }
8223 */
8225 {
8226 p_gop->pic_param[0].temporal_id = atoi(value);
8227 }
8229 {
8230 p_gop->pic_param[0].pic_type = atoi(value);
8231 }
8233 {
8234 p_gop->pic_param[0].num_ref_pics = atoi(value);
8235 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 num_ref_pics %d\n", __func__, p_gop->pic_param[0].num_ref_pics);
8236 }
8238 {
8239 p_gop->pic_param[0].rps[0].ref_pic = atoi(value);
8240 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 %d rps[0].ref_pic %d\n", __func__, p_gop->pic_param[0].rps[0].ref_pic);
8241 }
8243 {
8244 p_gop->pic_param[0].rps[0].ref_pic_used = atoi(value);
8245 //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);
8246 }
8248 {
8249 p_gop->pic_param[0].rps[1].ref_pic = atoi(value);
8250 }
8252 {
8253 p_gop->pic_param[0].rps[1].ref_pic_used = atoi(value);
8254 }
8256 {
8257 p_gop->pic_param[0].rps[2].ref_pic = atoi(value);
8258 }
8260 {
8261 p_gop->pic_param[0].rps[2].ref_pic_used = atoi(value);
8262 }
8264 {
8265 p_gop->pic_param[0].rps[3].ref_pic = atoi(value);
8266 }
8268 {
8269 p_gop->pic_param[0].rps[3].ref_pic_used = atoi(value);
8270 }
8271
8273 {
8274 p_gop->pic_param[1].poc_offset = atoi(value);
8275 }
8277 {
8278 p_gop->pic_param[1].qp_offset = atoi(value);
8279 }
8280 /*
8281 OPT(NI_ENC_GOP_PARAMS_G1_QP_FACTOR)
8282 {
8283 p_gop->pic_param[1].qp_factor = atof(value);
8284 }
8285 */
8287 {
8288 p_gop->pic_param[1].temporal_id = atoi(value);
8289 }
8291 {
8292 p_gop->pic_param[1].pic_type = atoi(value);
8293 }
8295 {
8296 p_gop->pic_param[1].num_ref_pics = atoi(value);
8297 }
8299 {
8300 p_gop->pic_param[1].rps[0].ref_pic = atoi(value);
8301 }
8303 {
8304 p_gop->pic_param[1].rps[0].ref_pic_used = atoi(value);
8305 }
8307 {
8308 p_gop->pic_param[1].rps[1].ref_pic = atoi(value);
8309 }
8311 {
8312 p_gop->pic_param[1].rps[1].ref_pic_used = atoi(value);
8313 }
8315 {
8316 p_gop->pic_param[1].rps[2].ref_pic = atoi(value);
8317 }
8319 {
8320 p_gop->pic_param[1].rps[2].ref_pic_used = atoi(value);
8321 }
8323 {
8324 p_gop->pic_param[1].rps[3].ref_pic = atoi(value);
8325 }
8327 {
8328 p_gop->pic_param[1].rps[3].ref_pic_used = atoi(value);
8329 }
8330
8332 {
8333 p_gop->pic_param[2].poc_offset = atoi(value);
8334 }
8336 {
8337 p_gop->pic_param[2].qp_offset = atoi(value);
8338 }
8339 /*
8340 OPT(NI_ENC_GOP_PARAMS_G2_QP_FACTOR)
8341 {
8342 p_gop->pic_param[2].qp_factor = atof(value);
8343 }
8344 */
8346 {
8347 p_gop->pic_param[2].temporal_id = atoi(value);
8348 }
8350 {
8351 p_gop->pic_param[2].pic_type = atoi(value);
8352 }
8354 {
8355 p_gop->pic_param[2].num_ref_pics = atoi(value);
8356 }
8358 {
8359 p_gop->pic_param[2].rps[0].ref_pic = atoi(value);
8360 }
8362 {
8363 p_gop->pic_param[2].rps[0].ref_pic_used = atoi(value);
8364 }
8366 {
8367 p_gop->pic_param[2].rps[1].ref_pic = atoi(value);
8368 }
8370 {
8371 p_gop->pic_param[2].rps[1].ref_pic_used = atoi(value);
8372 }
8374 {
8375 p_gop->pic_param[2].rps[2].ref_pic = atoi(value);
8376 }
8378 {
8379 p_gop->pic_param[2].rps[2].ref_pic_used = atoi(value);
8380 }
8382 {
8383 p_gop->pic_param[2].rps[3].ref_pic = atoi(value);
8384 }
8386 {
8387 p_gop->pic_param[2].rps[3].ref_pic_used = atoi(value);
8388 }
8389
8391 {
8392 p_gop->pic_param[3].poc_offset = atoi(value);
8393 }
8395 {
8396 p_gop->pic_param[3].qp_offset = atoi(value);
8397 }
8398 /*
8399 OPT(NI_ENC_GOP_PARAMS_G3_QP_FACTOR)
8400 {
8401 p_gop->pic_param[3].qp_factor = atof(value);
8402 }
8403 */
8405 {
8406 p_gop->pic_param[3].temporal_id = atoi(value);
8407 }
8409 {
8410 p_gop->pic_param[3].pic_type = atoi(value);
8411 }
8413 {
8414 p_gop->pic_param[3].num_ref_pics = atoi(value);
8415 }
8417 {
8418 p_gop->pic_param[3].rps[0].ref_pic = atoi(value);
8419 }
8421 {
8422 p_gop->pic_param[3].rps[0].ref_pic_used = atoi(value);
8423 }
8425 {
8426 p_gop->pic_param[3].rps[1].ref_pic = atoi(value);
8427 }
8429 {
8430 p_gop->pic_param[3].rps[1].ref_pic_used = atoi(value);
8431 }
8433 {
8434 p_gop->pic_param[3].rps[2].ref_pic = atoi(value);
8435 }
8437 {
8438 p_gop->pic_param[3].rps[2].ref_pic_used = atoi(value);
8439 }
8441 {
8442 p_gop->pic_param[3].rps[3].ref_pic = atoi(value);
8443 }
8445 {
8446 p_gop->pic_param[3].rps[3].ref_pic_used = atoi(value);
8447 }
8448
8450 {
8451 p_gop->pic_param[4].poc_offset = atoi(value);
8452 }
8454 {
8455 p_gop->pic_param[4].qp_offset = atoi(value);
8456 }
8457 /*
8458 OPT(NI_ENC_GOP_PARAMS_G4_QP_FACTOR)
8459 {
8460 p_gop->pic_param[4].qp_factor = atof(value);
8461 }
8462 */
8464 {
8465 p_gop->pic_param[4].temporal_id = atoi(value);
8466 }
8468 {
8469 p_gop->pic_param[4].pic_type = atoi(value);
8470 }
8472 {
8473 p_gop->pic_param[4].num_ref_pics = atoi(value);
8474 }
8476 {
8477 p_gop->pic_param[4].rps[0].ref_pic = atoi(value);
8478 }
8480 {
8481 p_gop->pic_param[4].rps[0].ref_pic_used = atoi(value);
8482 }
8484 {
8485 p_gop->pic_param[4].rps[1].ref_pic = atoi(value);
8486 }
8488 {
8489 p_gop->pic_param[4].rps[1].ref_pic_used = atoi(value);
8490 }
8492 {
8493 p_gop->pic_param[4].rps[2].ref_pic = atoi(value);
8494 }
8496 {
8497 p_gop->pic_param[4].rps[2].ref_pic_used = atoi(value);
8498 }
8500 {
8501 p_gop->pic_param[4].rps[3].ref_pic = atoi(value);
8502 }
8504 {
8505 p_gop->pic_param[4].rps[3].ref_pic_used = atoi(value);
8506 }
8507
8509 {
8510 p_gop->pic_param[5].poc_offset = atoi(value);
8511 }
8513 {
8514 p_gop->pic_param[5].qp_offset = atoi(value);
8515 }
8516 /*
8517 OPT(NI_ENC_GOP_PARAMS_G5_QP_FACTOR)
8518 {
8519 p_gop->pic_param[5].qp_factor = atof(value);
8520 }
8521 */
8523 {
8524 p_gop->pic_param[5].temporal_id = atoi(value);
8525 }
8527 {
8528 p_gop->pic_param[5].pic_type = atoi(value);
8529 }
8531 {
8532 p_gop->pic_param[5].num_ref_pics = atoi(value);
8533 }
8535 {
8536 p_gop->pic_param[5].rps[0].ref_pic = atoi(value);
8537 }
8539 {
8540 p_gop->pic_param[5].rps[0].ref_pic_used = atoi(value);
8541 }
8543 {
8544 p_gop->pic_param[5].rps[1].ref_pic = atoi(value);
8545 }
8547 {
8548 p_gop->pic_param[5].rps[1].ref_pic_used = atoi(value);
8549 }
8551 {
8552 p_gop->pic_param[5].rps[2].ref_pic = atoi(value);
8553 }
8555 {
8556 p_gop->pic_param[5].rps[2].ref_pic_used = atoi(value);
8557 }
8559 {
8560 p_gop->pic_param[5].rps[3].ref_pic = atoi(value);
8561 }
8563 {
8564 p_gop->pic_param[5].rps[3].ref_pic_used = atoi(value);
8565 }
8566
8568 {
8569 p_gop->pic_param[6].poc_offset = atoi(value);
8570 }
8572 {
8573 p_gop->pic_param[6].qp_offset = atoi(value);
8574 }
8575 /*
8576 OPT(NI_ENC_GOP_PARAMS_G6_QP_FACTOR)
8577 {
8578 p_gop->pic_param[6].qp_factor = atof(value);
8579 }
8580 */
8582 {
8583 p_gop->pic_param[6].temporal_id = atoi(value);
8584 }
8586 {
8587 p_gop->pic_param[6].pic_type = atoi(value);
8588 }
8590 {
8591 p_gop->pic_param[6].num_ref_pics = atoi(value);
8592 }
8594 {
8595 p_gop->pic_param[6].rps[0].ref_pic = atoi(value);
8596 }
8598 {
8599 p_gop->pic_param[6].rps[0].ref_pic_used = atoi(value);
8600 }
8602 {
8603 p_gop->pic_param[6].rps[1].ref_pic = atoi(value);
8604 }
8606 {
8607 p_gop->pic_param[6].rps[1].ref_pic_used = atoi(value);
8608 }
8610 {
8611 p_gop->pic_param[6].rps[2].ref_pic = atoi(value);
8612 }
8614 {
8615 p_gop->pic_param[6].rps[2].ref_pic_used = atoi(value);
8616 }
8618 {
8619 p_gop->pic_param[6].rps[3].ref_pic = atoi(value);
8620 }
8622 {
8623 p_gop->pic_param[6].rps[3].ref_pic_used = atoi(value);
8624 }
8625
8627 {
8628 p_gop->pic_param[7].poc_offset = atoi(value);
8629 }
8631 {
8632 p_gop->pic_param[7].qp_offset = atoi(value);
8633 }
8634 /*
8635 OPT(NI_ENC_GOP_PARAMS_G7_QP_FACTOR)
8636 {
8637 p_gop->pic_param[7].qp_factor = atof(value);
8638 }
8639 */
8641 {
8642 p_gop->pic_param[7].temporal_id = atoi(value);
8643 }
8645 {
8646 p_gop->pic_param[7].pic_type = atoi(value);
8647 }
8649 {
8650 p_gop->pic_param[7].num_ref_pics = atoi(value);
8651 }
8653 {
8654 p_gop->pic_param[7].rps[0].ref_pic = atoi(value);
8655 }
8657 {
8658 p_gop->pic_param[7].rps[0].ref_pic_used = atoi(value);
8659 }
8661 {
8662 p_gop->pic_param[7].rps[1].ref_pic = atoi(value);
8663 }
8665 {
8666 p_gop->pic_param[7].rps[1].ref_pic_used = atoi(value);
8667 }
8669 {
8670 p_gop->pic_param[7].rps[2].ref_pic = atoi(value);
8671 }
8673 {
8674 p_gop->pic_param[7].rps[2].ref_pic_used = atoi(value);
8675 }
8677 {
8678 p_gop->pic_param[7].rps[3].ref_pic = atoi(value);
8679 }
8681 {
8682 p_gop->pic_param[7].rps[3].ref_pic_used = atoi(value);
8683 }
8684 else
8685 {
8686 ni_log(NI_LOG_ERROR, "%s(): Invalid parameter name passed\n", __func__);
8688 }
8689#endif
8690
8691#undef OPT
8692#undef OPT2
8693#undef atobool
8694#undef atoi
8695#undef atof
8696
8697 b_error |= bValueWasNull && !bNameWasBool;
8698
8699 ni_log(NI_LOG_TRACE, "%s(): exit, b_error=%d\n", __func__, b_error);
8700
8702}
8703
8704/*!*****************************************************************************
8705* \brief Copy existing decoding session params for hw frame usage
8706*
8707* \param[in] src_p_ctx Pointer to a caller allocated source session context
8708* \param[in] dst_p_ctx Pointer to a caller allocated destination session
8709* context
8710* \return On success
8711* NI_RETCODE_SUCCESS
8712* On failure
8713* NI_RETCODE_INVALID_PARAM
8714******************************************************************************/
8716{
8717 return ni_decoder_session_copy_internal(src_p_ctx, dst_p_ctx);
8718}
8719
8720/*!*****************************************************************************
8721* \brief Read data from the device
8722* If device_type is NI_DEVICE_TYPE_DECODER reads data hwdesc from
8723* decoder
8724* If device_type is NI_DEVICE_TYPE_SCALER reads data hwdesc from
8725* scaler
8726*
8727* \param[in] p_ctx Pointer to a caller allocated
8728* ni_session_context_t struct
8729* \param[in] p_data Pointer to a caller allocated
8730* ni_session_data_io_t struct which contains either a
8731* ni_frame_t data frame or ni_packet_t data packet to
8732* send
8733* \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_SCALER
8734* If NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_SCALER is specified,
8735* hw descriptor info will be stored in p_data ni_frame
8736* \return On success
8737* Total number of bytes read
8738* On failure
8739* NI_RETCODE_INVALID_PARAM
8740* NI_RETCODE_ERROR_NVME_CMD_FAILED
8741* NI_RETCODE_ERROR_INVALID_SESSION
8742******************************************************************************/
8744{
8745 ni_log2(p_ctx, NI_LOG_DEBUG, "%s start\n", __func__);
8747 if ((!p_ctx) || (!p_data))
8748 {
8749 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
8750 __func__);
8752 }
8753
8754 // Here check if keep alive thread is closed.
8755#ifdef _WIN32
8756 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
8758#else
8759 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
8761#endif
8762 {
8763 ni_log2(p_ctx, NI_LOG_ERROR,
8764 "ERROR: %s() keep alive thread has been closed, "
8765 "hw:%d, session:%d\n",
8766 __func__, p_ctx->hw_id, p_ctx->session_id);
8768 }
8769
8771 // In close state, let the close process execute first.
8773 {
8774 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
8776 ni_usleep(100);
8778 }
8781
8782 switch (device_type)
8783 {
8785 {
8786 int seq_change_read_count = 0;
8787 p_data->data.frame.src_codec = p_ctx->codec_format;
8788 for (;;)
8789 {
8790 //retval = ni_decoder_session_read(p_ctx, &(p_data->data.frame));
8791 retval = ni_decoder_session_read_desc(p_ctx, &(p_data->data.frame));
8792 // check resolution change only after initial setting obtained
8793 // p_data->data.frame.video_width is picture width and will be 32-align
8794 // adjusted to frame size; p_data->data.frame.video_height is the same as
8795 // frame size, then compare them to saved one for resolution checking
8796 //
8797 uint32_t aligned_width;
8798 if(QUADRA)
8799 {
8800 aligned_width = ((((p_data->data.frame.video_width * p_ctx->bit_depth_factor) + 127) / 128) * 128);
8801 }
8802 else
8803 {
8804 aligned_width = ((p_data->data.frame.video_width + 31) / 32) * 32;
8805 }
8806
8807 ni_log2(p_ctx, NI_LOG_DEBUG,
8808 "FNum %" PRIu64
8809 ", DFVWxDFVH %u x %u, AlWid %u, AVW x AVH %u x %u\n",
8810 p_ctx->frame_num, p_data->data.frame.video_width,
8811 p_data->data.frame.video_height, aligned_width,
8813
8814 if (0 == retval && seq_change_read_count)
8815 {
8816 ni_log2(p_ctx, NI_LOG_DEBUG, "%s (decoder): seq change NO data, next time.\n",
8817 __func__);
8818 p_ctx->active_video_width = 0;
8819 p_ctx->active_video_height = 0;
8820 p_ctx->actual_video_width = 0;
8821 break;
8822 }
8823 else if (retval < 0)
8824 {
8825 ni_log2(p_ctx, NI_LOG_ERROR, "%s (decoder): failure ret %d, return ..\n",
8826 __func__, retval);
8827 break;
8828 }
8829 // aligned_width may equal to active_video_width if bit depth and width
8830 // are changed at the same time. So, check video_width != actual_video_width.
8831 else if (p_ctx->frame_num && (p_ctx->pixel_format_changed ||
8832 (p_data->data.frame.video_width &&
8833 p_data->data.frame.video_height &&
8834 (aligned_width != p_ctx->active_video_width ||
8835 p_data->data.frame.video_height != p_ctx->active_video_height))))
8836 {
8837 ni_log2(
8838 p_ctx, NI_LOG_DEBUG,
8839 "%s (decoder): resolution change, frame size %ux%u -> %ux%u, "
8840 "width %u bit %d, pix_fromat_changed %d, actual_video_width %d, continue read ...\n",
8841 __func__, p_ctx->active_video_width, p_ctx->active_video_height,
8842 aligned_width, p_data->data.frame.video_height,
8843 p_data->data.frame.video_width, p_ctx->bit_depth_factor,
8845 // reset active video resolution to 0 so it can be queried in the re-read
8846 p_ctx->active_video_width = 0;
8847 p_ctx->active_video_height = 0;
8848 p_ctx->actual_video_width = 0;
8849 seq_change_read_count++;
8850 //break;
8851 }
8852 else
8853 {
8854 break;
8855 }
8856 }
8857 break;
8858 }
8860 {
8861 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Encoder has no hwdesc to read\n");
8863 }
8864
8866 {
8867 retval = ni_scaler_session_read_hwdesc(p_ctx, &(p_data->data.frame));
8868 break;
8869 }
8870
8871 case NI_DEVICE_TYPE_AI:
8872 {
8873 retval = ni_ai_session_read_hwdesc(p_ctx, &(p_data->data.frame));
8874 break;
8875 }
8876
8877 default:
8878 {
8879 retval = NI_RETCODE_INVALID_PARAM;
8880 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
8881 __func__, device_type);
8882 break;
8883 }
8884 }
8885
8887 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
8889
8890 return retval;
8891}
8892
8893/*!*****************************************************************************
8894* \brief Reads YUV data from hw descriptor stored location on device
8895*
8896* \param[in] p_ctx Pointer to a caller allocated
8897* ni_session_context_t struct
8898* \param[in] p_data Pointer to a caller allocated
8899* ni_session_data_io_t struct which contains either a
8900* ni_frame_t data frame or ni_packet_t data packet to
8901* send
8902* \param[in] hwdesc HW descriptor to find frame in XCODER
8903* \return On success
8904* Total number of bytes read
8905* On failure
8906* NI_RETCODE_INVALID_PARAM
8907* NI_RETCODE_ERROR_NVME_CMD_FAILED
8908* NI_RETCODE_ERROR_INVALID_SESSION
8909*******************************************************************************/
8911{
8913 if ((!hwdesc) || (!p_data))
8914 {
8915 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8916 __func__);
8918 }
8919
8920 /* download by frameidx */
8921 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rd") >= 0))
8922 {
8923 if(hwdesc->ui16FrameIdx == 0)
8924 {
8925 ni_log(NI_LOG_ERROR, "%s(): Invaild frame index\n", __func__);
8927 }
8928 retval = ni_hwdownload_by_frame_idx(hwdesc, &(p_data->data.frame), p_ctx->is_auto_dl);
8929 } else {
8930 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
8931 {
8932 if (p_ctx->pext_mutex == &(p_ctx->mutex))
8933 {
8934 ni_log(NI_LOG_ERROR, "ERROR %s(): Invalid session\n",
8935 __func__);
8937 }
8938 }
8939
8941 bool use_external_mutex = false;
8942 uint32_t orig_session_id = p_ctx->session_id;
8943 ni_device_handle_t orig_blk_io_handle = p_ctx->blk_io_handle;
8944 uint32_t orig_codec_format = p_ctx->codec_format;
8945 int orig_bit_depth_factor = p_ctx->bit_depth_factor;
8946 int orig_hw_action = p_ctx->hw_action;
8947
8948 ni_pthread_mutex_t *p_ctx_mutex = &(p_ctx->mutex);
8949 if ((p_ctx_mutex != p_ctx->pext_mutex) ||
8952 "6r8") < 0)
8953 {
8954 use_external_mutex = true;
8955 p_ctx->session_id = hwdesc->ui16session_ID;
8956 p_ctx->blk_io_handle = (ni_device_handle_t)(int64_t)hwdesc->device_handle;
8957 p_ctx->codec_format = NI_CODEC_FORMAT_H264; //unused
8958 p_ctx->bit_depth_factor = (int)hwdesc->bit_depth;
8960 }
8961
8963
8964 retval = ni_hwdownload_session_read(p_ctx, &(p_data->data.frame), hwdesc); //cut me down as needed
8965
8966 p_ctx->xcoder_state &= ~NI_XCODER_HWDL_STATE;
8967 if (use_external_mutex)
8968 {
8969 p_ctx->session_id = orig_session_id;
8970 p_ctx->blk_io_handle = orig_blk_io_handle;
8971 p_ctx->codec_format = orig_codec_format;
8972 p_ctx->bit_depth_factor = orig_bit_depth_factor;
8973 p_ctx->hw_action = orig_hw_action;
8974 }
8976 }
8977
8978 return retval;
8979}
8980
8981/*!*****************************************************************************
8982* \brief Query the session if a buffer is available
8983*
8984* \param[in] p_ctx Pointer to a caller allocated
8985* ni_session_context_t struct
8986* [in] device_type Quadra device type
8987*
8988* \return On success
8989* NI_RETCODE_SUCCESS
8990* On failure
8991* NI_RETCODE_INVALID_PARAM
8992* NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
8993* NI_RETCODE_ERROR_NVME_CMD_FAILED
8994* NI_RETCODE_ERROR_INVALID_SESSION
8995*******************************************************************************/
8997 ni_device_type_t device_type)
8998{
9000
9001 if (!p_ctx)
9002 {
9003 ni_log(NI_LOG_ERROR, "ERROR: No session\n");
9005 }
9006
9009 "6rt") < 0)
9010 {
9011 ni_log2(p_ctx, NI_LOG_DEBUG,
9012 "%s function not supported in FW API version < 6rt\n",
9013 __func__);
9015 }
9016
9017 switch (device_type)
9018 {
9022
9024
9025 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
9027 break;
9028
9032
9034
9035 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
9037 break;
9038
9039 default:
9040 break;
9041 }
9042
9043 return retval;
9044}
9045
9046/*!*****************************************************************************
9047* \brief Sends raw YUV input to uploader instance and retrieves a HW descriptor
9048* to represent it
9049*
9050* \param[in] p_ctx Pointer to a caller allocated
9051* ni_session_context_t struct
9052* \param[in] p_src_data Pointer to a caller allocated
9053* ni_session_data_io_t struct which contains a
9054* ni_frame_t data frame to send to uploader
9055* \param[out] hwdesc HW descriptor to find frame in XCODER
9056* \return On success
9057* Total number of bytes read
9058* On failure
9059* NI_RETCODE_INVALID_PARAM
9060* NI_RETCODE_ERROR_NVME_CMD_FAILED
9061* NI_RETCODE_ERROR_INVALID_SESSION
9062*******************************************************************************/
9064{
9066 if ((!hwdesc) || (!p_src_data))
9067 {
9068 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9069 __func__);
9071 }
9074
9075 retval = ni_hwupload_session_write(p_ctx, &p_src_data->data.frame, hwdesc);
9076
9077 p_ctx->xcoder_state &= ~NI_XCODER_HWUP_STATE;
9079
9080 return retval;
9081}
9082
9083/*!*****************************************************************************
9084* \brief Allocate memory for the hwDescriptor buffer based on provided
9085* parameters taking into account pic size and extra data.
9086*
9087* \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
9088*
9089* \param[in] video_width Width of the video frame
9090* \param[in] video_height Height of the video frame
9091* \param[in] extra_len Extra data size (incl. meta data)
9092*
9093* \return On success
9094* NI_RETCODE_SUCCESS
9095* On failure
9096* NI_RETCODE_INVALID_PARAM
9097* NI_RETCODE_ERROR_MEM_ALOC
9098*****************************************************************************/
9100 int video_height, int extra_len)
9101{
9102 void* p_buffer = NULL;
9103 int height_aligned = video_height;
9104 int retval = NI_RETCODE_SUCCESS;
9105
9106 if (!p_frame)
9107 {
9108 ni_log(NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9109 __func__);
9111 }
9112
9113 ni_log(NI_LOG_DEBUG, "%s: extra_len=%d\n", __func__, extra_len);
9114
9115 int buffer_size = (int)sizeof(niFrameSurface1_t) + extra_len;
9116
9118
9119 //Check if Need to free
9120 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
9121 {
9122 ni_log(NI_LOG_DEBUG, "%s: free current p_frame->buffer_size=%u\n",
9123 __func__, p_frame->buffer_size);
9124 ni_frame_buffer_free(p_frame);
9125 }
9126
9127 //Check if need to realocate
9128 if (p_frame->buffer_size != buffer_size)
9129 {
9130 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
9131 {
9132 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
9133 NI_ERRNO, __func__);
9135 LRETURN;
9136 }
9137
9138 // init once after allocation
9139 memset(p_buffer, 0, buffer_size);
9140 p_frame->buffer_size = buffer_size;
9141 p_frame->p_buffer = p_buffer;
9142
9143 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
9144 }
9145 else
9146 {
9147 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
9148 }
9149
9150 p_frame->p_data[3] = p_frame->p_buffer;
9151 p_frame->p_data[0] = NULL;
9152 p_frame->p_data[1] = NULL;
9153 p_frame->p_data[2] = NULL;
9154
9155 p_frame->data_len[0] = 0;//luma_size;
9156 p_frame->data_len[1] = 0;//chroma_b_size;
9157 p_frame->data_len[2] = 0;//chroma_r_size;
9158 p_frame->data_len[3] = sizeof(niFrameSurface1_t);
9159
9160 p_frame->video_width = video_width;
9161 p_frame->video_height = height_aligned;
9162
9163 ((niFrameSurface1_t*)p_frame->p_data[3])->device_handle = (int32_t)NI_INVALID_DEVICE_HANDLE;
9164
9165 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
9166 p_frame->buffer_size);
9167
9168END:
9169
9170 if (NI_RETCODE_SUCCESS != retval)
9171 {
9172 ni_aligned_free(p_buffer);
9173 }
9174
9175 return retval;
9176}
9177
9178/*!*****************************************************************************
9179* \brief Recycle a frame buffer on card
9180*
9181* \param[in] surface Struct containing device and frame location to clear out
9182* \param[in] device_handle handle to access device memory buffer is stored in
9183*
9184* \return On success NI_RETCODE_SUCCESS
9185* On failure NI_RETCODE_INVALID_PARAM
9186*******************************************************************************/
9188 int32_t device_handle)
9189{
9191
9192 if (surface)
9193 {
9194 ni_log(NI_LOG_DEBUG, "%s(): Start cleaning out buffer\n", __func__);
9196 "%s(): ui16FrameIdx=%d sessionId=%d device_handle=0x%x\n",
9197 __func__, surface->ui16FrameIdx, surface->ui16session_ID,
9198 device_handle);
9199 retval = ni_clear_instance_buf(surface);
9200 }
9201 else
9202 {
9203 ni_log(NI_LOG_DEBUG, "%s(): Surface is empty\n", __func__);
9204 }
9205
9206 return retval;
9207}
9208
9209/*!*****************************************************************************
9210* \brief Recycle a frame buffer on card, only hwframe descriptor is needed
9211*
9212* \param[in] surface Struct containing device and frame location to clear out
9213*
9214* \return On success NI_RETCODE_SUCCESS
9215* On failure NI_RETCODE_INVALID_PARAM
9216*******************************************************************************/
9218{
9220 int32_t saved_dma_buf_fd;
9221 if (surface)
9222 {
9223 if(surface->ui16FrameIdx == 0)
9224 {
9225 ni_log(NI_LOG_DEBUG, "%s(): Invaild frame index\n", __func__);
9226 return retval;
9227 }
9228 ni_log(NI_LOG_DEBUG, "%s(): Start cleaning out buffer\n", __func__);
9230 "%s(): ui16FrameIdx=%d sessionId=%d device_handle=0x%x\n",
9231 __func__, surface->ui16FrameIdx, surface->ui16session_ID,
9232 surface->device_handle);
9233 retval = ni_clear_instance_buf(surface);
9234 saved_dma_buf_fd = surface->dma_buf_fd;
9235 memset(surface, 0, sizeof(niFrameSurface1_t));
9236 surface->dma_buf_fd = saved_dma_buf_fd;
9237 }
9238 else
9239 {
9240 ni_log(NI_LOG_DEBUG, "%s(): Surface is empty\n", __func__);
9241 retval = NI_RETCODE_INVALID_PARAM;
9242 }
9243
9244 return retval;
9245}
9246
9247/*!*****************************************************************************
9248* \brief Sends frame pool setup info to device
9249*
9250* \param[in] p_ctx Pointer to a caller allocated
9251* ni_session_context_t struct
9252* \param[in] pool_size Upload session initial allocated frames count
9253* must be > 0,
9254* \param[in] pool 0 use the normal pool
9255* 1 use a dedicated P2P pool
9256*
9257* \return On success Return code
9258* On failure
9259* NI_RETCODE_INVALID_PARAM
9260* NI_RETCODE_ERROR_NVME_CMD_FAILED
9261* NI_RETCODE_ERROR_INVALID_SESSION
9262* NI_RETCODE_ERROR_MEM_ALOC
9263*******************************************************************************/
9265 uint32_t pool_size, uint32_t pool)
9266{
9268 if (!p_ctx)
9269 {
9270 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9271 __func__);
9273 }
9274 if (pool_size == 0 || pool_size > NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL)
9275 {
9276 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Invalid poolsize == 0 or > 100\n");
9278 }
9279 if (pool & NI_UPLOADER_FLAG_LM)
9280 {
9281 ni_log2(p_ctx, NI_LOG_DEBUG, "uploader buffer acquisition is limited!\n");
9282 }
9285
9286 retval = ni_config_instance_set_uploader_params(p_ctx, pool_size, pool);
9287
9288 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9290
9291 return retval;
9292}
9293
9294/*!*****************************************************************************
9295* \brief Sends frame pool change info to device
9296*
9297* \param[in] p_ctx Pointer to a caller allocated
9298* ni_session_context_t struct
9299* \param[in] pool_size if pool_size = 0, free allocated device memory buffers
9300* if pool_size > 0, expand device frame buffer pool of
9301* current instance with pool_size more frame buffers
9302*
9303* \return On success Return code
9304* On failure
9305* NI_RETCODE_FAILURE
9306* NI_RETCODE_INVALID_PARAM
9307* NI_RETCODE_ERROR_NVME_CMD_FAILED
9308* NI_RETCODE_ERROR_INVALID_SESSION
9309* NI_RETCODE_ERROR_MEM_ALOC
9310* NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9311*******************************************************************************/
9313 uint32_t pool_size)
9314{
9316 if (!p_ctx)
9317 {
9318 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9319 __func__);
9321 }
9324 "6r3") < 0)
9325 {
9326 ni_log2(p_ctx, NI_LOG_ERROR,
9327 "ERROR: %s function not supported in FW API version < 6r3\n",
9328 __func__);
9330 }
9331 if (p_ctx->pool_type == NI_POOL_TYPE_NONE)
9332 {
9333 ni_log2(p_ctx, NI_LOG_ERROR,
9334 "ERROR: can't free or expand framepool of session 0x%x "
9335 "before init framepool\n", p_ctx->session_id);
9336 return NI_RETCODE_FAILURE;
9337 }
9338 if (pool_size > NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL)
9339 {
9340 ni_log2(p_ctx, NI_LOG_ERROR,
9341 "ERROR: Invalid poolsize > %u\n", NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL);
9343 }
9344 if (pool_size == 0)
9345 {
9346 ni_log2(p_ctx, NI_LOG_INFO, "Free frame pool of session 0x%x\n", p_ctx->session_id);
9347 }
9348
9351
9352 retval = ni_config_instance_set_uploader_params(p_ctx, pool_size, p_ctx->pool_type);
9353
9354 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9356
9357 return retval;
9358}
9359
9360/*!*****************************************************************************
9361 * \brief Set parameters on the device for the 2D engine
9362 *
9363 * \param[in] p_ctx pointer to session context
9364 * \param[in] p_params pointer to scaler parameters
9365 *
9366 * \return NI_RETCODE_INVALID_PARAM
9367 * NI_RETCODE_ERROR_INVALID_SESSION
9368 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9369 * NI_RETCODE_ERROR_MEM_ALOC
9370 ******************************************************************************/
9372 ni_scaler_params_t *p_params)
9373{
9375
9376 if (!p_ctx || !p_params)
9377 {
9378 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9379 __func__);
9381 }
9384
9385 retval = ni_config_instance_set_scaler_params(p_ctx, p_params);
9386
9387 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9389
9390 return retval;
9391}
9392
9393/*!******************************************************************************
9394 * \brief Send a p_config command to configure scaling drawbox parameters.
9395 *
9396 * \param ni_session_context_t p_ctx - xcoder Context
9397 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_drawbox params_t struct
9398 *
9399 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
9400*******************************************************************************/
9403{
9404 void *p_scaler_config = NULL;
9405 uint32_t buffer_size = sizeof(ni_scaler_multi_drawbox_params_t);
9407 uint32_t ui32LBA = 0;
9408
9409 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
9410
9411 if (!p_ctx || !p_params)
9412 {
9413 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n", __func__);
9414 retval = NI_RETCODE_INVALID_PARAM;
9415 LRETURN;
9416 }
9417
9418 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
9419 {
9420 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n", __func__);
9422 LRETURN;
9423 }
9424
9425 buffer_size =
9426 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
9428 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
9429 {
9430 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
9431 NI_ERRNO, __func__);
9433 LRETURN;
9434 }
9435 memset(p_scaler_config, 0, buffer_size);
9436
9437 //configure the session here
9440
9441 memcpy(p_scaler_config, p_params, buffer_size);
9442
9444 p_scaler_config, buffer_size, ui32LBA) < 0)
9445 {
9446 ni_log2(p_ctx, NI_LOG_ERROR,
9447 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
9448 ", hw_id, %d, xcoder_inst_id: %d\n",
9449 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
9450 // Close the session since we can't configure it as per fw
9451 retval = ni_scaler_session_close(p_ctx, 0);
9452 if (NI_RETCODE_SUCCESS != retval)
9453 {
9454 ni_log2(p_ctx, NI_LOG_ERROR,
9455 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
9456 "hw_id, %d, xcoder_inst_id: %d\n",
9457 __func__,
9458 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
9459 p_ctx->session_id);
9460 }
9461
9463 }
9464
9465END:
9466
9467 ni_aligned_free(p_scaler_config);
9468 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
9469
9470 return retval;
9471}
9472
9473/*!******************************************************************************
9474 * \brief Send a p_config command to configure scaling watermark parameters.
9475 *
9476 * \param ni_session_context_t p_ctx - xcoder Context
9477 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_watermark_params_t struct
9478 *
9479 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
9480*******************************************************************************/
9483{
9484 void *p_scaler_config = NULL;
9485 uint32_t buffer_size = sizeof(ni_scaler_multi_watermark_params_t);
9487 uint32_t ui32LBA = 0;
9488
9489 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
9490
9491 if (!p_ctx || !p_params)
9492 {
9493 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n", __func__);
9494 retval = NI_RETCODE_INVALID_PARAM;
9495 LRETURN;
9496 }
9497
9498 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
9499 {
9500 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n", __func__);
9502 LRETURN;
9503 }
9504
9505 buffer_size =
9506 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
9508 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
9509 {
9510 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
9511 NI_ERRNO, __func__);
9513 LRETURN;
9514 }
9515 memset(p_scaler_config, 0, buffer_size);
9516
9517 //configure the session here
9520
9521 memcpy(p_scaler_config, p_params, buffer_size);
9522
9524 p_scaler_config, buffer_size, ui32LBA) < 0)
9525 {
9526 ni_log2(p_ctx, NI_LOG_ERROR,
9527 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
9528 ", hw_id, %d, xcoder_inst_id: %d\n",
9529 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
9530 // Close the session since we can't configure it as per fw
9531 retval = ni_scaler_session_close(p_ctx, 0);
9532 if (NI_RETCODE_SUCCESS != retval)
9533 {
9534 ni_log2(p_ctx, NI_LOG_ERROR,
9535 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
9536 "hw_id, %d, xcoder_inst_id: %d\n",
9537 __func__,
9538 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
9539 p_ctx->session_id);
9540 }
9541
9543 }
9544
9545END:
9546
9547 ni_aligned_free(p_scaler_config);
9548 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
9549
9550 return retval;
9551}
9552
9553
9554/*!*****************************************************************************
9555 * \brief Allocate a frame on the device for 2D engine or AI engine
9556 * to work on based on provided parameters
9557 *
9558 * \param[in] p_ctx pointer to session context
9559 * \param[in] width width, in pixels
9560 * \param[in] height height, in pixels
9561 * \param[in] format pixel format
9562 * \param[in] options options bitmap flags, bit 0 (NI_SCALER_FLAG_IO) is
9563 * 0=input frame or 1=output frame. Bit 1 (NI_SCALER_FLAG_PC) is
9564 * 0=single allocation, 1=create pool. Bit 2 (NI_SCALER_FLAG_PA) is
9565 * 0=straight alpha, 1=premultiplied alpha
9566 * \param[in] rectangle_width clipping rectangle width
9567 * \param[in] rectangle_height clipping rectangle height
9568 * \param[in] rectangle_x horizontal position of clipping rectangle
9569 * \param[in] rectangle_y vertical position of clipping rectangle
9570 * \param[in] rgba_color RGBA fill colour (for padding only)
9571 * \param[in] frame_index input hwdesc index
9572 * \param[in] device_type only NI_DEVICE_TYPE_SCALER
9573 * and NI_DEVICE_TYPE_AI (only needs p_ctx and frame_index)
9574 *
9575 * \return NI_RETCODE_INVALID_PARAM
9576 * NI_RETCODE_ERROR_INVALID_SESSION
9577 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9578 * NI_RETCODE_ERROR_MEM_ALOC
9579 ******************************************************************************/
9581 int width,
9582 int height,
9583 int format,
9584 int options,
9585 int rectangle_width,
9586 int rectangle_height,
9587 int rectangle_x,
9588 int rectangle_y,
9589 int rgba_color,
9590 int frame_index,
9591 ni_device_type_t device_type)
9592{
9594
9595 if (!p_ctx)
9596 {
9597 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9598 __func__);
9600 }
9603
9604 switch (device_type)
9605 {
9607 retval = ni_scaler_alloc_frame(p_ctx,width, height, format, options,
9608 rectangle_width, rectangle_height,
9609 rectangle_x, rectangle_y,
9610 rgba_color, frame_index);
9611 break;
9612
9613 case NI_DEVICE_TYPE_AI:
9614 retval = ni_ai_alloc_hwframe(p_ctx, width, height, options, rgba_color,
9615 frame_index);
9616 break;
9617
9620 /* fall through */
9621
9622 default:
9623 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", device_type);
9624 retval = NI_RETCODE_INVALID_PARAM;
9625 break;
9626 }
9627
9628 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9630
9631 return retval;
9632}
9633
9634/*!*****************************************************************************
9635 * \brief Allocate a frame on the device and return the frame index
9636 *
9637 * \param[in] p_ctx pointer to session context
9638 * \param[in] p_out_surface pointer to output frame surface
9639 * \param[in] device_type currently only NI_DEVICE_TYPE_AI
9640 *
9641 * \return NI_RETCODE_INVALID_PARAM
9642 * NI_RETCODE_ERROR_INVALID_SESSION
9643 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9644 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9645 * NI_RETCODE_ERROR_MEM_ALOC
9646 ******************************************************************************/
9648 niFrameSurface1_t *p_out_surface,
9649 ni_device_type_t device_type)
9650{
9652
9653 if (!p_ctx)
9654 {
9655 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, %p, return\n",
9656 __func__, p_ctx);
9658 }
9661
9662 switch (device_type)
9663 {
9664 case NI_DEVICE_TYPE_AI:
9665 retval = ni_ai_alloc_dst_frame(p_ctx, p_out_surface);
9666 break;
9667
9671 /* fall through */
9672
9673 default:
9674 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", device_type);
9675 retval = NI_RETCODE_INVALID_PARAM;
9676 break;
9677 }
9678
9679 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9681
9682 return retval;
9683}
9684
9685/*!*****************************************************************************
9686 * \brief Copy the data of src hwframe to dst hwframe
9687 *
9688 * \param[in] p_ctx pointer to session context
9689 * \param[in] p_frameclone_desc pointer to the frameclone descriptor
9690 *
9691 * \return NI_RETCODE_INVALID_PARAM
9692 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9693 * NI_RETCODE_ERROR_INVALID_SESSION
9694 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9695 * NI_RETCODE_ERROR_MEM_ALOC
9696 ******************************************************************************/
9698 ni_frameclone_desc_t *p_frameclone_desc)
9699{
9701
9702 if (!p_ctx)
9703 {
9704 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9705 __func__);
9707 }
9708
9711 "6rL") < 0)
9712 {
9713 ni_log2(p_ctx, NI_LOG_ERROR,
9714 "Error: %s function not supported on device with FW API version < 6rL\n",
9715 __func__);
9717 }
9718
9721 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
9722 {
9723 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
9724 __func__);
9726 LRETURN;
9727 }
9728
9729 retval = ni_hwframe_clone(p_ctx, p_frameclone_desc);
9730
9731END:
9732 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9734
9735 return retval;
9736}
9737
9738/*!*****************************************************************************
9739 * \brief Configure the 2D engine to work based on provided parameters
9740 *
9741 * \param[in] p_ctx pointer to session context
9742 * \param[in] p_cfg pointer to frame configuration
9743 *
9744 * \return NI_RETCODE_INVALID_PARAM
9745 * NI_RETCODE_ERROR_INVALID_SESSION
9746 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9747 * NI_RETCODE_ERROR_MEM_ALOC
9748 ******************************************************************************/
9750 ni_frame_config_t *p_cfg)
9751{
9753
9754 if (!p_ctx || !p_cfg)
9755 {
9756 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9757 __func__);
9759 }
9760
9763
9764 switch (p_ctx->device_type)
9765 {
9767 retval = ni_scaler_config_frame(p_ctx, p_cfg);
9768 break;
9769
9770 default:
9771 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", p_ctx->device_type);
9772 retval = NI_RETCODE_INVALID_PARAM;
9773 break;
9774 }
9775
9776 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9778
9779 return retval;
9780}
9781
9782/*!*****************************************************************************
9783 * \brief Configure the 2D engine to work based on provided parameters
9784 *
9785 * \param[in] p_ctx pointer to session context
9786 * \param[in] p_cfg_in pointer to input frame configuration
9787 * \param[in] numInCfgs number of input frame configurations
9788 * \param[in] p_cfg_out pointer to output frame configuration
9789 *
9790 * \return NI_RETCODE_INVALID_PARAM
9791 * NI_RETCODE_ERROR_INVALID_SESSION
9792 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9793 * NI_RETCODE_ERROR_MEM_ALOC
9794 ******************************************************************************/
9796 ni_frame_config_t p_cfg_in[],
9797 int numInCfgs,
9798 ni_frame_config_t *p_cfg_out)
9799{
9801
9802 if (!p_ctx || !p_cfg_in)
9803 {
9804 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9805 __func__);
9807 }
9808
9811
9812 switch (p_ctx->device_type)
9813 {
9815 retval = ni_scaler_multi_config_frame(p_ctx, p_cfg_in, numInCfgs, p_cfg_out);
9816 break;
9817
9818 case NI_DEVICE_TYPE_AI:
9819 retval = ni_ai_multi_config_frame(p_ctx, p_cfg_in, numInCfgs, p_cfg_out);
9820 break;
9821
9822 default:
9823 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", p_ctx->device_type);
9824 retval = NI_RETCODE_INVALID_PARAM;
9825 break;
9826 }
9827
9828 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9830
9831 return retval;
9832}
9833
9834/*!*****************************************************************************
9835 * \brief Calculate the total size of a frame based on the upload
9836 * context attributes and includes rounding up to the page size
9837 *
9838 * \param[in] p_upl_ctx pointer to an uploader session context
9839 * \param[in] linesize array of line stride
9840 *
9841 * \return size
9842 * NI_RETCODE_INVALID_PARAM
9843 *
9844 ******************************************************************************/
9846 const int linesize[])
9847{
9848 int pixel_format;
9849 int width, height;
9850 int alignedh;
9851 int luma, chroma_b, chroma_r;
9852 int total;
9853
9854 pixel_format = p_upl_ctx->pixel_format;
9855 width = (int)p_upl_ctx->active_video_width;
9856 height = (int)p_upl_ctx->active_video_height;
9857
9858 switch (pixel_format)
9859 {
9860 case NI_PIX_FMT_YUV420P:
9862 case NI_PIX_FMT_NV12:
9863 case NI_PIX_FMT_P010LE:
9864 if (width < 0 || width > NI_MAX_RESOLUTION_WIDTH)
9865 {
9867 }
9868
9869 if ((height < 0) || (height > NI_MAX_RESOLUTION_HEIGHT))
9870 {
9872 }
9873 break;
9874
9875 case NI_PIX_FMT_RGBA:
9876 case NI_PIX_FMT_ABGR:
9877 case NI_PIX_FMT_ARGB:
9878 case NI_PIX_FMT_BGRA:
9879 case NI_PIX_FMT_BGR0:
9880 if ((width < 0) || (width > NI_MAX_RESOLUTION_WIDTH))
9881 {
9883 }
9884
9885 if ((height < 0) || (height > NI_MAX_RESOLUTION_HEIGHT))
9886 {
9888 }
9889 break;
9890
9891 default:
9893 }
9894
9895 alignedh = NI_VPU_CEIL(height, 2);
9896
9897 switch (pixel_format)
9898 {
9899 case NI_PIX_FMT_YUV420P:
9901 luma = linesize[0] * alignedh;
9902 chroma_b = linesize[1] * alignedh / 2;
9903 chroma_r = linesize[2] * alignedh / 2;
9904 total =
9905 luma + chroma_b + chroma_r + NI_APP_ENC_FRAME_META_DATA_SIZE;
9906 break;
9907
9908 case NI_PIX_FMT_NV12:
9909 case NI_PIX_FMT_P010LE:
9910 luma = linesize[0] * alignedh;
9911 chroma_b = linesize[1] * alignedh / 2;
9912 chroma_r = 0;
9913 total =
9914 luma + chroma_b + chroma_r + NI_APP_ENC_FRAME_META_DATA_SIZE;
9915 break;
9916
9917 case NI_PIX_FMT_RGBA:
9918 case NI_PIX_FMT_ABGR:
9919 case NI_PIX_FMT_ARGB:
9920 case NI_PIX_FMT_BGRA:
9921 case NI_PIX_FMT_BGR0:
9922 total = width * height * 4 + NI_APP_ENC_FRAME_META_DATA_SIZE;
9923 break;
9924
9925 default:
9927 break;
9928 }
9929
9931
9932 return total;
9933}
9934
9935/*!*****************************************************************************
9936 * \brief Allocate memory for the frame buffer based on provided parameters
9937 * taking into account the pixel format, width, height, stride,
9938 * alignment, and extra data
9939 * \param[in] p_frame Pointer to caller allocated ni_frame_t
9940 * \param[in] pixel_format a pixel format in ni_pix_fmt_t enum
9941 * \param[in] video_width width, in pixels
9942 * \param[in] video_height height, in pixels
9943 * \param[in] linesize horizontal stride
9944 * \param[in] alignment apply a 16 pixel height alignment (T408 only)
9945 * \param[in] extra_len meta data size
9946 *
9947 * \return NI_RETCODE_SUCCESS
9948 * NI_RETCODE_INVALID_PARAM
9949 * NI_RETCODE_ERROR_MEM_ALOC
9950 *
9951 ******************************************************************************/
9953 int video_width, int video_height,
9954 int linesize[], int alignment,
9955 int extra_len)
9956{
9957 int buffer_size;
9958 void *p_buffer = NULL;
9959 int retval = NI_RETCODE_SUCCESS;
9960 int height_aligned;
9961 int luma_size = 0;
9962 int chroma_b_size = 0;
9963 int chroma_r_size = 0;
9964
9965 if (!p_frame)
9966 {
9967 ni_log(NI_LOG_ERROR, "Invalid frame pointer\n");
9969 }
9970
9971 switch (pixel_format)
9972 {
9973 case NI_PIX_FMT_YUV420P:
9975 case NI_PIX_FMT_NV12:
9976 case NI_PIX_FMT_P010LE:
9977 case NI_PIX_FMT_NV16:
9978 case NI_PIX_FMT_YUYV422:
9979 case NI_PIX_FMT_UYVY422:
9980 if ((video_width < 0) || (video_width > NI_MAX_RESOLUTION_WIDTH))
9981 {
9982 ni_log(NI_LOG_ERROR, "Video resolution width %d out of range\n",
9983 video_width);
9985 }
9986
9987 if ((video_height < 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT))
9988 {
9989 ni_log(NI_LOG_ERROR, "Video resolution height %d out of range\n",
9990 video_width);
9992 }
9993 break;
9994
9995 case NI_PIX_FMT_RGBA:
9996 case NI_PIX_FMT_BGRA:
9997 case NI_PIX_FMT_ARGB:
9998 case NI_PIX_FMT_ABGR:
9999 case NI_PIX_FMT_BGR0:
10000 case NI_PIX_FMT_BGRP:
10001 /*
10002 * For 2D engine using RGBA, the minimum width is 32. There is no
10003 * height restriction. The 2D engine supports a height/width of up to
10004 * 32K but but we will limit the max height and width to 8K.
10005 */
10006 if ((video_width < 0) || (video_width > NI_MAX_RESOLUTION_WIDTH))
10007 {
10008 ni_log(NI_LOG_ERROR, "Video resolution width %d out of range\n",
10009 video_width);
10011 }
10012
10013 if ((video_height <= 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT))
10014 {
10015 ni_log(NI_LOG_ERROR, "Video resolution height %d out of range\n",
10016 video_height);
10018 }
10019 break;
10020
10021 default:
10022 ni_log(NI_LOG_ERROR, "Unknown pixel format %d\n",pixel_format);
10024 }
10025
10026 if (QUADRA)
10027 {
10028 /* Quadra requires an even-numbered height/width */
10029 height_aligned = NI_VPU_CEIL(video_height, 2);
10030 }
10031 else
10032 {
10033 height_aligned = NI_VPU_ALIGN8(video_height);
10034
10035 if (alignment)
10036 {
10037 /* 16-pixel aligned pixel height for Quadra */
10038 height_aligned = NI_VPU_ALIGN16(video_height);
10039 }
10040 }
10041
10042 switch (pixel_format)
10043 {
10044 case NI_PIX_FMT_YUV420P:
10046 luma_size = linesize[0] * height_aligned;
10047
10048 if (QUADRA)
10049 {
10050 chroma_b_size = linesize[1] * height_aligned / 2;
10051 chroma_r_size = linesize[2] * height_aligned / 2;
10052 }
10053 else
10054 {
10055 chroma_b_size = luma_size / 4;
10056 chroma_r_size = luma_size / 4;
10057 }
10058 break;
10059
10060 case NI_PIX_FMT_RGBA:
10061 case NI_PIX_FMT_BGRA:
10062 case NI_PIX_FMT_ARGB:
10063 case NI_PIX_FMT_ABGR:
10064 case NI_PIX_FMT_BGR0:
10065 luma_size = linesize[0] * video_height;
10066 chroma_b_size = 0;
10067 chroma_r_size = 0;
10068 break;
10069
10070 case NI_PIX_FMT_NV12:
10071 case NI_PIX_FMT_P010LE:
10072 if (QUADRA)
10073 {
10074 luma_size = linesize[0] * height_aligned;
10075 chroma_b_size = linesize[1] * height_aligned / 2;
10076 chroma_r_size = 0;
10077 break;
10078 }
10079 case NI_PIX_FMT_NV16:
10080 if (QUADRA)
10081 {
10082 luma_size = linesize[0] * video_height;
10083 chroma_b_size = linesize[1] * video_height;
10084 chroma_r_size = 0;
10085 break;
10086 }
10087 case NI_PIX_FMT_YUYV422:
10088 case NI_PIX_FMT_UYVY422:
10089 if (QUADRA)
10090 {
10091 luma_size = linesize[0] * video_height;
10092 chroma_b_size = 0;
10093 chroma_r_size = 0;
10094 break;
10095 }
10096 case NI_PIX_FMT_BGRP:
10097 if (QUADRA)
10098 {
10099 luma_size = NI_VPU_ALIGN32(linesize[0] * video_height);
10100 chroma_b_size = NI_VPU_ALIGN32(linesize[1] * video_height);
10101 chroma_r_size = NI_VPU_ALIGN32(linesize[2] * video_height);
10102 break;
10103 }
10104 /*fall through*/
10105 default:
10106 ni_log(NI_LOG_ERROR, "Error: unsupported pixel format %d\n",pixel_format);
10108 }
10109
10110 buffer_size = luma_size + chroma_b_size + chroma_r_size + extra_len;
10111
10112 /* Allocate a buffer size that is page aligned for the host */
10113 buffer_size = NI_VPU_CEIL(buffer_size,NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
10114
10115 /* If this buffer has a different size, realloc a new buffer */
10116 if ((p_frame->buffer_size > 0) && (p_frame->buffer_size != buffer_size))
10117 {
10118 ni_log(NI_LOG_DEBUG, "Free current p_frame, p_frame->buffer_size %u\n",
10119 p_frame->buffer_size);
10120 ni_frame_buffer_free(p_frame);
10121 }
10122
10123 if (p_frame->buffer_size != buffer_size)
10124 {
10125 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10126 {
10127 ni_log(NI_LOG_ERROR, "Error: Cannot allocate p_frame\n");
10129 LRETURN;
10130 }
10131
10132 memset(p_buffer, 0, buffer_size);
10133 p_frame->buffer_size = buffer_size;
10134 p_frame->p_buffer = p_buffer;
10135 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
10136 }
10137 else
10138 {
10139 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
10140 }
10141
10142 switch (pixel_format)
10143 {
10144 case NI_PIX_FMT_YUV420P:
10146 p_frame->p_data[0] = p_frame->p_buffer;
10147 p_frame->p_data[1] = p_frame->p_data[0] + luma_size;
10148 p_frame->p_data[2] = p_frame->p_data[1] + chroma_b_size;
10149 p_frame->p_data[3] = NULL;
10150
10151 p_frame->data_len[0] = luma_size;
10152 p_frame->data_len[1] = chroma_b_size;
10153 p_frame->data_len[2] = chroma_r_size;
10154 p_frame->data_len[3] = 0;
10155 video_width = NI_VPU_ALIGN128(video_width);
10156 break;
10157
10158 case NI_PIX_FMT_RGBA:
10159 case NI_PIX_FMT_BGRA:
10160 case NI_PIX_FMT_ARGB:
10161 case NI_PIX_FMT_ABGR:
10162 case NI_PIX_FMT_BGR0:
10163 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10164 p_frame->p_data[1] = NULL;
10165 p_frame->p_data[2] = NULL;
10166 p_frame->p_data[3] = NULL;
10167
10168 p_frame->data_len[0] = luma_size;
10169 p_frame->data_len[1] = 0;
10170 p_frame->data_len[2] = 0;
10171 p_frame->data_len[3] = 0;
10172 video_width = NI_VPU_ALIGN16(video_width);
10173 break;
10174
10175 case NI_PIX_FMT_NV12:
10176 case NI_PIX_FMT_P010LE:
10177 if (QUADRA)
10178 {
10179 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10180 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10181 p_frame->p_data[2] = NULL;
10182 p_frame->p_data[3] = NULL;
10183
10184 p_frame->data_len[0] = luma_size;
10185 p_frame->data_len[1] = chroma_b_size;
10186 p_frame->data_len[2] = 0;
10187 p_frame->data_len[3] = 0;
10188
10189 video_width = NI_VPU_ALIGN128(video_width);
10190 break;
10191 }
10192 case NI_PIX_FMT_NV16:
10193 if (QUADRA)
10194 {
10195 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10196 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10197 p_frame->p_data[2] = NULL;
10198 p_frame->p_data[3] = NULL;
10199
10200 p_frame->data_len[0] = luma_size;
10201 p_frame->data_len[1] = chroma_b_size;
10202 p_frame->data_len[2] = 0;
10203 p_frame->data_len[3] = 0;
10204
10205 video_width = NI_VPU_ALIGN64(video_width);
10206 break;
10207 }
10208
10209 case NI_PIX_FMT_YUYV422:
10210 case NI_PIX_FMT_UYVY422:
10211 if (QUADRA)
10212 {
10213 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10214 p_frame->p_data[1] = NULL;
10215 p_frame->p_data[2] = NULL;
10216 p_frame->p_data[3] = NULL;
10217
10218 p_frame->data_len[0] = luma_size;
10219 p_frame->data_len[1] = 0;
10220 p_frame->data_len[2] = 0;
10221 p_frame->data_len[3] = 0;
10222 video_width = NI_VPU_ALIGN16(video_width);
10223 break;
10224 }
10225 case NI_PIX_FMT_BGRP:
10226 if (QUADRA)
10227 {
10228 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10229 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10230 p_frame->p_data[2] = (uint8_t *)p_frame->p_data[1] + chroma_b_size;
10231 p_frame->p_data[3] = NULL;
10232
10233 p_frame->data_len[0] = luma_size;
10234 p_frame->data_len[1] = chroma_b_size;
10235 p_frame->data_len[2] = chroma_r_size;
10236 p_frame->data_len[3] = 0;
10237 break;
10238 }
10239 /* fall through */
10240 default:
10241 ni_log(NI_LOG_ERROR, "Error: unsupported pixel format %d\n",pixel_format);
10242 retval = NI_RETCODE_INVALID_PARAM;
10243 LRETURN;
10244 }
10245
10246 p_frame->video_width = video_width;
10247 p_frame->video_height = height_aligned;
10248
10249 ni_log(NI_LOG_DEBUG, "%s success: w=%d; h=%d; aligned buffer size=%d\n",
10250 __func__, video_width, video_height, buffer_size);
10251
10252END:
10253
10254 if (retval != NI_RETCODE_SUCCESS)
10255 {
10256 ni_aligned_free(p_buffer);
10257 }
10258
10259 return retval;
10260}
10261
10263 ni_network_data_t *p_network,
10264 const char *file)
10265{
10266 FILE *fp = NULL;
10267 struct stat file_stat;
10269 unsigned char *buffer = NULL;
10270
10271 if (!p_ctx)
10272 {
10273 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10274 __func__);
10276 }
10280
10281 char errmsg[NI_ERRNO_LEN] = {0};
10282 if (stat(file, &file_stat) != 0)
10283 {
10285 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to get network binary file stat, %s\n",
10286 __func__, errmsg);
10287 retval = NI_RETCODE_FAILURE;
10288 LRETURN;
10289 }
10290
10291 if (file_stat.st_size == 0)
10292 {
10293 ni_log2(p_ctx, NI_LOG_ERROR, "%s: network binary size is null\n", __func__);
10294 retval = NI_RETCODE_FAILURE;
10295 LRETURN;
10296 }
10297
10298 ni_fopen(&fp, file, "rb");
10299 if (!fp)
10300 {
10302 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to open network binary, %s\n", __func__,
10303 errmsg);
10304 retval = NI_RETCODE_FAILURE;
10305 LRETURN;
10306 }
10307
10308 buffer = malloc(file_stat.st_size);
10309 if (!buffer)
10310 {
10311 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to alloate memory\n", __func__);
10313 (void)fclose(fp);
10314 fp = NULL;
10315 LRETURN;
10316 }
10317
10318 if (fread(buffer, file_stat.st_size, 1, fp) != 1)
10319 {
10320 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to read network binary\n", __func__);
10321 retval = NI_RETCODE_FAILURE;
10322 (void)fclose(fp);
10323 fp = NULL;
10324 LRETURN;
10325 }
10326
10327 (void)fclose(fp);
10328 fp = NULL;
10329
10330 retval =
10331 ni_config_instance_network_binary(p_ctx, buffer, file_stat.st_size);
10332 if (retval != NI_RETCODE_SUCCESS)
10333 {
10334 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to configure instance, retval %d\n",
10335 __func__, retval);
10336 LRETURN;
10337 }
10338
10339 retval = ni_config_read_inout_layers(p_ctx, p_network);
10340 if (retval != NI_RETCODE_SUCCESS)
10341 {
10342 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to read network layers, retval %d\n",
10343 retval);
10344 }
10345
10346END:
10347 /* fp is always closed explicitly before LRETURN or after fread above */
10348 free(buffer);
10349
10351 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10353
10354 return retval;
10355}
10356
10358 ni_network_data_t *p_network)
10359{
10361
10362 if (!p_ctx)
10363 {
10364 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10365 __func__);
10367 }
10368
10369 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6ro") < 0))
10370 {
10371 ni_log2(p_ctx, NI_LOG_ERROR, "Error: hvsplus filter not supported on device with FW API version < 6ro\n");
10373 }
10374
10378
10379 retval =
10380 ni_config_instance_hvsplus(p_ctx); //, buffer, file_stat.st_size);
10381 if (retval != NI_RETCODE_SUCCESS)
10382 {
10383 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to configure instance, retval %d\n",
10384 __func__, retval);
10385 LRETURN;
10386 }
10387
10388 retval = ni_config_read_inout_layers(p_ctx, p_network);
10389 if (retval != NI_RETCODE_SUCCESS)
10390 {
10391 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to read network layers, retval %d\n",
10392 retval);
10393 }
10394
10395END:
10396
10398 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10400
10401 return retval;
10402}
10403
10405 ni_network_data_t *p_network)
10406{
10407 uint32_t buffer_size = 0;
10408 void *p_buffer = NULL;
10409 int retval = NI_RETCODE_SUCCESS;
10410 uint32_t i, this_size;
10411 ni_network_layer_info_t *p_linfo;
10412
10413 if (!p_frame || !p_network)
10414 {
10415 ni_log(NI_LOG_ERROR, "Invalid frame or network layer pointer\n");
10417 }
10418
10419 p_linfo = &p_network->linfo;
10420 for (i = 0; i < p_network->input_num; i++)
10421 {
10422 this_size = ni_ai_network_layer_size(&p_linfo->in_param[i]);
10423 this_size =
10424 (this_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
10425 if (p_network->inset[i].offset != buffer_size)
10426 {
10428 "ERROR: %s(): invalid buffer_size of network\n", __func__);
10430 }
10431 buffer_size += this_size;
10432 }
10433
10434 /* fixed size */
10435 p_frame->data_len[0] = buffer_size;
10436
10437 /* Allocate a buffer size that is page aligned for the host */
10438 buffer_size = (buffer_size + NI_MEM_PAGE_ALIGNMENT - 1) &
10439 ~(NI_MEM_PAGE_ALIGNMENT - 1);
10440
10441 /* If this buffer has a different size, realloc a new buffer */
10442 if ((p_frame->buffer_size > 0) && (p_frame->buffer_size != buffer_size))
10443 {
10444 ni_log(NI_LOG_DEBUG, "Free current p_frame, p_frame->buffer_size %u\n",
10445 p_frame->buffer_size);
10446 ni_frame_buffer_free(p_frame);
10447 }
10448
10449 if (p_frame->buffer_size != buffer_size)
10450 {
10451 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10452 {
10453 ni_log(NI_LOG_ERROR, "Error: Cannot allocate p_frame\n");
10455 LRETURN;
10456 }
10457
10458 // memset(p_buffer, 0, buffer_size);
10459 p_frame->buffer_size = buffer_size;
10460 p_frame->p_buffer = p_buffer;
10461 ni_log(NI_LOG_DEBUG, "%s(): allocated new p_frame buffer\n", __func__);
10462 } else
10463 {
10464 ni_log(NI_LOG_DEBUG, "%s(): reuse p_frame buffer\n", __func__);
10465 }
10466
10467 p_frame->p_data[0] = p_frame->p_buffer;
10468 p_frame->p_data[1] = NULL;
10469 p_frame->p_data[2] = NULL;
10470 p_frame->p_data[3] = NULL;
10471
10472 p_frame->iovec = NULL;
10473 p_frame->iovec_num = 0;
10474
10475 ni_log(NI_LOG_DEBUG, "%s() success: aligned buffer size=%u\n", __func__,
10476 buffer_size);
10477
10478END:
10479
10480 if (retval != NI_RETCODE_SUCCESS)
10481 {
10482 ni_aligned_free(p_buffer);
10483 }
10484
10485 return retval;
10486}
10487
10489 ni_network_data_t *p_network)
10490{
10491 void *p_buffer = NULL;
10492 int retval = NI_RETCODE_SUCCESS;
10493 uint32_t buffer_size = 0;
10494 uint32_t i, data_size;
10495 ni_network_layer_info_t *p_linfo;
10496
10497 if (!p_packet || !p_network)
10498 {
10499 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameters passed\n",
10500 __func__);
10502 }
10503
10504 p_linfo = &p_network->linfo;
10505 for (i = 0; i < p_network->output_num; i++)
10506 {
10507 data_size = ni_ai_network_layer_size(&p_linfo->out_param[i]);
10508 data_size =
10509 (data_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
10510 if (p_network->outset[i].offset != buffer_size)
10511 {
10513 "ERROR: %s(): invalid buffer_size of network\n", __func__);
10515 }
10516 buffer_size += data_size;
10517 }
10518 data_size = buffer_size;
10519
10520 ni_log(NI_LOG_DEBUG, "%s(): packet_size=%u\n", __func__, buffer_size);
10521
10522 if (buffer_size & (NI_MEM_PAGE_ALIGNMENT - 1))
10523 {
10524 buffer_size = (buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
10525 ~(NI_MEM_PAGE_ALIGNMENT - 1);
10526 }
10527
10528 if (p_packet->buffer_size == buffer_size)
10529 {
10530 p_packet->p_data = p_packet->p_buffer;
10531 ni_log(NI_LOG_DEBUG, "%s(): reuse current p_packet buffer\n", __func__);
10532 LRETURN; //Already allocated the exact size
10533 } else if (p_packet->buffer_size > 0)
10534 {
10536 "%s(): free current p_packet, p_packet->buffer_size=%u\n",
10537 __func__, p_packet->buffer_size);
10538 ni_packet_buffer_free(p_packet);
10539 }
10540 ni_log(NI_LOG_DEBUG, "%s(): Allocating p_packet buffer, buffer_size=%u\n",
10541 __func__, buffer_size);
10542
10543 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10544 {
10545 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_packet buffer.\n",
10546 NI_ERRNO, __func__);
10548 LRETURN;
10549 }
10550
10551 p_packet->buffer_size = buffer_size;
10552 p_packet->p_buffer = p_buffer;
10553 p_packet->p_data = p_packet->p_buffer;
10554 p_packet->data_len = data_size;
10555
10556END:
10557
10558 if (NI_RETCODE_SUCCESS != retval)
10559 {
10560 ni_aligned_free(p_buffer);
10561 }
10562
10563 ni_log(NI_LOG_TRACE, "%s(): exit: p_packet->buffer_size=%u\n", __func__,
10564 p_packet->buffer_size);
10565
10566 return retval;
10567}
10568
10569/*!*****************************************************************************
10570 * \brief Reconfigure bitrate dynamically during encoding.
10571 *
10572 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10573 * \param[in] bitrate Target bitrate to set
10574 *
10575 * \return On success NI_RETCODE_SUCCESS
10576 * On failure NI_RETCODE_INVALID_PARAM
10577 ******************************************************************************/
10579{
10580 if (!p_ctx || bitrate < NI_MIN_BITRATE || bitrate > NI_MAX_BITRATE)
10581 {
10582 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid bitrate passed in %d\n",
10583 __func__, bitrate);
10585 }
10588
10589 if (p_ctx->target_bitrate > 0)
10590 {
10591 ni_log2(p_ctx, NI_LOG_DEBUG,
10592 "Warning: %s(): bitrate %d overwriting current one %d\n",
10593 __func__, bitrate, p_ctx->target_bitrate);
10594 }
10595
10596 p_ctx->target_bitrate = bitrate;
10597
10598 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10600
10601 return NI_RETCODE_SUCCESS;
10602}
10603
10604/*!*****************************************************************************
10605 * \brief Reconfigure intraPeriod dynamically during encoding.
10606 *
10607 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10608 * \param[in] intra_period Target intra period to set
10609 *
10610 *
10611 * \return On success NI_RETCODE_SUCCESS
10612 * On failure NI_RETCODE_INVALID_PARAM
10613 *
10614 * NOTE - the frame upon which intra period is reconfigured is encoded as IDR frame
10615 * NOTE - reconfigure intra period is not allowed if intraRefreshMode is enabled or if gopPresetIdx is 1
10616 *
10617 ******************************************************************************/
10619 int32_t intra_period)
10620{
10621 if (!p_ctx || intra_period < 0 || intra_period > 1024)
10622 {
10623 ni_log(NI_LOG_ERROR, "ERROR: %s(): invalid intraPeriod passed in %d\n",
10624 __func__, intra_period);
10626 }
10629
10630 if (p_ctx->reconfig_intra_period >= 0)
10631 {
10633 "Warning: %s(): intraPeriod %d overwriting current one %d\n",
10634 __func__, intra_period, p_ctx->reconfig_intra_period);
10635 }
10636
10637 p_ctx->reconfig_intra_period = intra_period;
10638
10639 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10641
10642 return NI_RETCODE_SUCCESS;
10643}
10644
10645/*!*****************************************************************************
10646 * \brief Reconfigure VUI HRD dynamically during encoding.
10647 *
10648 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10649 * \param[in] bitrate Target bitrate to set
10650 *
10651 * \return On success NI_RETCODE_SUCCESS
10652 * On failure NI_RETCODE_INVALID_PARAM
10653 ******************************************************************************/
10655{
10656 if (!p_ctx || vui->colorDescPresent < 0 || vui->colorDescPresent > 1)
10657 {
10658 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid colorDescPresent passed in %d\n",
10659 __func__, vui->colorDescPresent);
10661 }
10662
10664 {
10665 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid aspect ratio passed in (%dx%d)\n",
10666 __func__, vui->aspectRatioWidth, vui->aspectRatioHeight);
10668 }
10669
10670 if (vui->videoFullRange < 0 || vui->videoFullRange > 1)
10671 {
10672 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid videoFullRange passed in %d\n",
10673 __func__, vui->videoFullRange);
10675 }
10676
10679
10681 p_ctx->vui.colorPrimaries = vui->colorPrimaries;
10682 p_ctx->vui.colorTrc = vui->colorTrc;
10683 p_ctx->vui.colorSpace = vui->colorSpace;
10686 p_ctx->vui.videoFullRange = vui->videoFullRange;
10687
10688 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10690
10691 return NI_RETCODE_SUCCESS;
10692}
10693
10694/*!*****************************************************************************
10695 * \brief Force next frame to be IDR frame during encoding.
10696 *
10697 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10698 *
10699 * \return On success NI_RETCODE_SUCCESS
10700 ******************************************************************************/
10702{
10703 if (!p_ctx)
10704 {
10705 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10706 __func__);
10708 }
10711
10712 if (p_ctx->force_idr_frame)
10713 {
10714 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: %s(): already forcing IDR frame\n",
10715 __func__);
10716 }
10717
10718 p_ctx->force_idr_frame = 1;
10719
10720 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10722
10723 return NI_RETCODE_SUCCESS;
10724}
10725
10726/*!*****************************************************************************
10727 * \brief Set a frame's support of Long Term Reference frame during encoding.
10728 *
10729 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10730 * \param[in] ltr Pointer to struct specifying LTR support
10731 *
10732 * \return On success NI_RETCODE_SUCCESS
10733 * On failure NI_RETCODE_INVALID_PARAM
10734 ******************************************************************************/
10736{
10737 if (!p_ctx)
10738 {
10739 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10740 __func__);
10742 }
10744
10748
10750
10751 return NI_RETCODE_SUCCESS;
10752}
10753
10754/*!*****************************************************************************
10755 * \brief Set Long Term Reference interval
10756 *
10757 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10758 * \param[in] ltr_interval the new long term reference inteval value
10759 *
10760 * \return On success NI_RETCODE_SUCCESS
10761 * On failure NI_RETCODE_INVALID_PARAM
10762 ******************************************************************************/
10764 int32_t ltr_interval)
10765{
10766 if (!p_ctx)
10767 {
10768 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10769 __func__);
10771 }
10773
10774 p_ctx->ltr_interval = ltr_interval;
10775
10777
10778 return NI_RETCODE_SUCCESS;
10779}
10780
10781/*!*****************************************************************************
10782 * \brief Set frame reference invalidation
10783 *
10784 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10785 * \param[in] frame_num frame number after which all references shall be
10786 * invalidated
10787 *
10788 * \return On success NI_RETCODE_SUCCESS
10789 * On failure NI_RETCODE_INVALID_PARAM
10790 ******************************************************************************/
10792 int32_t frame_num)
10793{
10794 if (!p_ctx)
10795 {
10796 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10797 __func__);
10799 }
10801 p_ctx->ltr_frame_ref_invalid = frame_num;
10803
10804 return NI_RETCODE_SUCCESS;
10805}
10806
10807/*!*****************************************************************************
10808 * \brief Reconfigure framerate dynamically during encoding.
10809 *
10810 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10811 * \param[in] framerate Target framerate to set
10812 *
10813 * \return On success NI_RETCODE_SUCCESS
10814 * On failure NI_RETCODE_INVALID_PARAM
10815 ******************************************************************************/
10817 ni_framerate_t *framerate)
10818{
10819 int32_t framerate_num = framerate->framerate_num;
10820 int32_t framerate_denom = framerate->framerate_denom;
10821 if (!p_ctx || framerate_num <= 0 || framerate_denom <= 0)
10822 {
10823 ni_log2(p_ctx, NI_LOG_ERROR,
10824 "ERROR: %s(): invalid framerate passed in (%d/%d)\n", __func__,
10825 framerate_num, framerate_denom);
10827 }
10828
10829 if ((framerate_num % framerate_denom) != 0)
10830 {
10831 uint32_t numUnitsInTick = 1000;
10832 framerate_num = framerate_num / framerate_denom;
10833 framerate_denom = (int)(numUnitsInTick + 1);
10834 framerate_num += 1;
10835 framerate_num *= (int)numUnitsInTick;
10836 } else
10837 {
10838 framerate_num = framerate_num / framerate_denom;
10839 framerate_denom = 1;
10840 }
10841
10842 if (((framerate_num + framerate_denom - 1) / framerate_denom) >
10844 {
10845 ni_log2(p_ctx, NI_LOG_ERROR,
10846 "ERROR: %s(): invalid framerate passed in (%d/%d)\n", __func__,
10847 framerate->framerate_num, framerate->framerate_denom);
10849 }
10850
10853
10854 if (p_ctx->framerate.framerate_num > 0)
10855 {
10856 ni_log2(p_ctx, NI_LOG_DEBUG,
10857 "Warning: %s(): framerate (%d/%d) overwriting current "
10858 "one (%d/%d)\n",
10859 __func__, framerate_num, framerate_denom,
10860 p_ctx->framerate.framerate_num,
10861 p_ctx->framerate.framerate_denom);
10862 }
10863
10864 p_ctx->framerate.framerate_num = framerate_num;
10865 p_ctx->framerate.framerate_denom = framerate_denom;
10866
10867 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10869
10870 return NI_RETCODE_SUCCESS;
10871}
10872
10873/*!*****************************************************************************
10874 * \brief Reconfigure maxFrameSize dynamically during encoding.
10875 *
10876 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10877 * \param[in] max_frame_size maxFrameSize to set
10878 *
10879 * \return On success NI_RETCODE_SUCCESS
10880 * On failure NI_RETCODE_INVALID_PARAM
10881 *
10882 * NOTE - maxFrameSize_Bytes value less than ((bitrate / 8) / framerate) will be rejected
10883 *
10884 ******************************************************************************/
10886{
10887 ni_xcoder_params_t *api_param;
10888 int32_t bitrate, framerate_num, framerate_denom;
10889 uint32_t maxFrameSize = (uint32_t)max_frame_size / 2000;
10890 uint32_t min_maxFrameSize;
10891
10892 if (!p_ctx || !p_ctx->p_session_config)
10893 {
10894 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
10895 __func__);
10897 }
10898
10899 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
10900
10901 if (!api_param->low_delay_mode)
10902 {
10903 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size is valid only when lowDelay mode is enabled\n",
10904 __func__, max_frame_size);
10906 }
10907
10908 bitrate = (p_ctx->target_bitrate > 0) ? p_ctx->target_bitrate : api_param->bitrate;
10909
10910 if ((p_ctx->framerate.framerate_num > 0) && (p_ctx->framerate.framerate_denom > 0))
10911 {
10912 framerate_num = p_ctx->framerate.framerate_num;
10913 framerate_denom = p_ctx->framerate.framerate_denom;
10914 }
10915 else
10916 {
10917 framerate_num = (int32_t) api_param->fps_number;
10918 framerate_denom = (int32_t) api_param->fps_denominator;
10919 }
10920
10921 min_maxFrameSize = (((uint32_t)bitrate / framerate_num * framerate_denom) / 8) / 2000;
10922
10923 if (maxFrameSize < min_maxFrameSize)
10924 {
10925 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size %d is too small (invalid)\n",
10926 __func__, max_frame_size);
10928 }
10929 if (max_frame_size > NI_MAX_FRAME_SIZE) {
10930 max_frame_size = NI_MAX_FRAME_SIZE;
10931 }
10932
10935
10936 if (p_ctx->max_frame_size > 0)
10937 {
10938 ni_log2(p_ctx, NI_LOG_DEBUG,
10939 "Warning: %s(): max_frame_size %d overwriting current one %d\n",
10940 __func__, max_frame_size, p_ctx->max_frame_size);
10941 }
10942
10943 p_ctx->max_frame_size = max_frame_size;
10944
10945 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10947
10948 return NI_RETCODE_SUCCESS;
10949}
10950
10951/*!*****************************************************************************
10952 * \brief Reconfigure min&max qp dynamically during encoding.
10953 *
10954 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10955 * \param[in] ni_rc_min_max_qp Target min&max qp to set
10956 *
10957 * \return On success NI_RETCODE_SUCCESS
10958 * On failure NI_RETCODE_INVALID_PARAM
10959 ******************************************************************************/
10961 ni_rc_min_max_qp *p_min_max_qp)
10962{
10963 int32_t minQpI, maxQpI, maxDeltaQp, minQpPB, maxQpPB;
10964
10965 if (!p_ctx || !p_min_max_qp)
10966 {
10967 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_min_max_qp pointer\n",
10968 __func__);
10970 }
10971
10972 minQpI = p_min_max_qp->minQpI;
10973 maxQpI = p_min_max_qp->maxQpI;
10974 maxDeltaQp = p_min_max_qp->maxDeltaQp;
10975 minQpPB = p_min_max_qp->minQpPB;
10976 maxQpPB = p_min_max_qp->maxQpPB;
10977
10978 if (minQpI > maxQpI || minQpPB > maxQpPB ||
10979 maxQpI > 51 || minQpI < 0 || maxQpPB > 51 || minQpPB < 0)
10980 {
10981 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid qp setting <%d %d %d %d %d>\n",
10982 __func__, minQpI, maxQpI, maxDeltaQp, minQpPB, maxQpPB);
10984 }
10985
10988
10989 p_ctx->enc_change_params->minQpI = minQpI;
10990 p_ctx->enc_change_params->maxQpI = maxQpI;
10991 p_ctx->enc_change_params->maxDeltaQp = maxDeltaQp;
10992 p_ctx->enc_change_params->minQpPB = minQpPB;
10993 p_ctx->enc_change_params->maxQpPB = maxQpPB;
10994
10995 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10997
10998 return NI_RETCODE_SUCCESS;
10999}
11000
11001/*!*****************************************************************************
11002 * \brief Reconfigure crf value dynamically during encoding.
11003 *
11004 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11005 * \param[in] crf crf value to reconfigure
11006 *
11007 * \return On success NI_RETCODE_SUCCESS
11008 * On failure NI_RETCODE_INVALID_PARAM
11009 ******************************************************************************/
11011 int32_t crf)
11012{
11013 ni_xcoder_params_t *api_param;
11014
11015 if (!p_ctx || !p_ctx->p_session_config)
11016 {
11017 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11018 __func__);
11020 }
11021
11022 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11023
11024 if (api_param->cfg_enc_params.crf < 0)
11025 {
11026 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %d is valid only in CRF mode\n",
11027 __func__, crf);
11029 }
11030
11031 if (crf < 0 || crf > 51)
11032 {
11033 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %d is invalid (valid range in [0..51])\n",
11034 __func__, crf);
11036 }
11037
11039
11041
11042 if (p_ctx->reconfig_crf >= 0)
11043 {
11044 ni_log2(p_ctx, NI_LOG_DEBUG,
11045 "Warning: %s(): crf reconfig value %d overwriting current reconfig_crf %d\n",
11046 __func__, crf, p_ctx->reconfig_crf);
11047 }
11048
11049 p_ctx->reconfig_crf = crf;
11050
11051 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11052
11054
11055 return NI_RETCODE_SUCCESS;
11056}
11057
11058/*!*****************************************************************************
11059 * \brief Reconfigure crf float point value dynamically during encoding.
11060 *
11061 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11062 * \param[in] crf crf float point value to reconfigure
11063 *
11064 * \return On success NI_RETCODE_SUCCESS
11065 * On failure NI_RETCODE_INVALID_PARAM
11066 ******************************************************************************/
11068 float crf)
11069{
11070 ni_xcoder_params_t *api_param;
11071
11072 if (!p_ctx || !p_ctx->p_session_config)
11073 {
11074 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11075 __func__);
11077 }
11078
11079 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11080
11081 if (api_param->cfg_enc_params.crfFloat < 0)
11082 {
11083 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %f is valid only in CRF mode\n",
11084 __func__, crf);
11086 }
11087
11088 if (crf < 0.0 || crf > 51.0)
11089 {
11090 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %f is invalid (valid range in [0..51])\n",
11091 __func__, crf);
11093 }
11094
11096
11098
11099 if (p_ctx->reconfig_crf >= 0 || p_ctx->reconfig_crf_decimal > 0)
11100 {
11101 ni_log2(p_ctx, NI_LOG_DEBUG,
11102 "Warning: %s(): crf reconfig value %d overwriting current "
11103 "reconfig_crf %d, reconfig_crf_decimal %d\n", __func__,
11104 crf, p_ctx->reconfig_crf, p_ctx->reconfig_crf_decimal);
11105 }
11106
11107 p_ctx->reconfig_crf = (int)crf;
11108 p_ctx->reconfig_crf_decimal = (int)((crf - (float)p_ctx->reconfig_crf) * 100);
11109
11110 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11111
11113
11114 return NI_RETCODE_SUCCESS;
11115}
11116
11117/*!*****************************************************************************
11118 * \brief Reconfigure vbv buffer size and vbv max rate dynamically during encoding.
11119 *
11120 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11121 * \param[in] vbvBufferSize Target vbvBufferSize to set
11122 * \param[in] vbvMaxRate Target vbvMaxRate to set
11123 *
11124 * \return On success NI_RETCODE_SUCCESS
11125 * On failure NI_RETCODE_INVALID_PARAM
11126 ******************************************************************************/
11128 int32_t vbvMaxRate, int32_t vbvBufferSize)
11129{
11130 ni_xcoder_params_t *api_param;
11131 if (!p_ctx || !p_ctx->p_session_config)
11132 {
11133 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11134 __func__);
11136 }
11137 if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
11138 {
11139 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): vbvBufferSize value %d\n",
11140 __func__, vbvBufferSize);
11142 }
11143 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11144 if (api_param->bitrate > 0 && vbvMaxRate > 0 && vbvMaxRate < api_param->bitrate) {
11145 ni_log2(p_ctx, NI_LOG_ERROR, "vbvMaxRate %u cannot be smaller than bitrate %d\n",
11146 vbvMaxRate, api_param->bitrate);
11148 }
11149 if (vbvBufferSize == 0 && vbvMaxRate > 0) {
11150 ni_log2(p_ctx, NI_LOG_INFO, "vbvMaxRate %d does not take effect when "
11151 "vbvBufferSize is 0, force vbvMaxRate to 0\n",
11152 vbvMaxRate);
11153 vbvMaxRate = 0;
11154 }
11155
11158
11159 p_ctx->reconfig_vbv_buffer_size = vbvBufferSize;
11160 p_ctx->reconfig_vbv_max_rate = vbvMaxRate;
11161
11162 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11164
11165 return NI_RETCODE_SUCCESS;
11166}
11167
11168/*!*****************************************************************************
11169 * \brief Reconfigure maxFrameSizeRatio dynamically during encoding.
11170 *
11171 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11172 * \param[in] max_frame_size_ratio maxFrameSizeRatio to set
11173 *
11174 * \return On success NI_RETCODE_SUCCESS
11175 * On failure NI_RETCODE_INVALID_PARAM
11176 ******************************************************************************/
11178{
11179 ni_xcoder_params_t *api_param;
11180 int32_t bitrate, framerate_num, framerate_denom;
11181 uint32_t min_maxFrameSize, maxFrameSize;
11182
11183 if (!p_ctx || !p_ctx->p_session_config)
11184 {
11185 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11186 __func__);
11188 }
11189
11190 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11191
11192 if (!api_param->low_delay_mode)
11193 {
11194 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size_ratio is valid only when lowDelay mode is enabled\n",
11195 __func__, max_frame_size_ratio);
11197 }
11198
11199 if (max_frame_size_ratio < 1) {
11200 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size_ratio %d cannot < 1\n",
11201 max_frame_size_ratio);
11203 }
11204
11205 bitrate = (p_ctx->target_bitrate > 0) ? p_ctx->target_bitrate : api_param->bitrate;
11206
11207 if ((p_ctx->framerate.framerate_num > 0) && (p_ctx->framerate.framerate_denom > 0))
11208 {
11209 framerate_num = p_ctx->framerate.framerate_num;
11210 framerate_denom = p_ctx->framerate.framerate_denom;
11211 }
11212 else
11213 {
11214 framerate_num = (int32_t) api_param->fps_number;
11215 framerate_denom = (int32_t) api_param->fps_denominator;
11216 }
11217
11218 min_maxFrameSize = (((uint32_t)bitrate / framerate_num * framerate_denom) / 8) / 2000;
11219
11220 maxFrameSize = min_maxFrameSize * max_frame_size_ratio > NI_MAX_FRAME_SIZE ?
11221 NI_MAX_FRAME_SIZE : min_maxFrameSize * max_frame_size_ratio;
11222
11225
11226 if (p_ctx->max_frame_size > 0)
11227 {
11228 ni_log2(p_ctx, NI_LOG_DEBUG,
11229 "Warning: %s(): max_frame_size %d overwriting current one %d\n",
11230 __func__, maxFrameSize, p_ctx->max_frame_size);
11231 }
11232
11233 p_ctx->max_frame_size = (int32_t)maxFrameSize;
11234
11235 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11237
11238 return NI_RETCODE_SUCCESS;
11239}
11240
11241/*!*****************************************************************************
11242 * \brief Reconfigure sliceArg dynamically during encoding.
11243 *
11244 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11245 * \param[in] sliceArg the new sliceArg value
11246 *
11247 * \return On success NI_RETCODE_SUCCESS
11248 * On failure NI_RETCODE_INVALID_PARAM
11249 ******************************************************************************/
11251{
11252 ni_xcoder_params_t *api_param;
11254
11255 if (!p_ctx || !p_ctx->p_session_config)
11256 {
11257 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11258 __func__);
11260 }
11261
11262 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11263 p_enc = &api_param->cfg_enc_params;
11264 if (p_enc->slice_mode == 0)
11265 {
11266 ni_log2(p_ctx, NI_LOG_ERROR, "%s():not support to reconfig slice_arg when slice_mode disable.\n",
11267 __func__);
11268 sliceArg = 0;
11269 }
11271 {
11272 ni_log2(p_ctx, NI_LOG_ERROR, "%s():sliceArg is only supported for H.264 or H.265.\n",
11273 __func__);
11274 sliceArg = 0;
11275 }
11276 int ctu_mb_size = (NI_CODEC_FORMAT_H264 == p_ctx->codec_format) ? 16 : 64;
11277 int max_num_ctu_mb_row = (api_param->source_height + ctu_mb_size - 1) / ctu_mb_size;
11278 if (sliceArg < 1 || sliceArg > max_num_ctu_mb_row)
11279 {
11280 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid data sliceArg %d\n", __func__,
11281 sliceArg);
11282 sliceArg = 0;
11283 }
11284
11287
11288 p_ctx->reconfig_slice_arg = sliceArg;
11289
11290 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11292
11293 return NI_RETCODE_SUCCESS;
11294}
11295
11296#ifndef _WIN32
11297/*!*****************************************************************************
11298* \brief Acquire a P2P frame buffer from the hwupload session
11299*
11300* \param[in] p_ctx Pointer to a caller allocated
11301* ni_session_context_t struct
11302* \param[out] p_frame Pointer to a caller allocated hw frame
11303*
11304* \return On success
11305* NI_RETCODE_SUCCESS
11306* On failure
11307* NI_RETCODE_INVALID_PARAM
11308* NI_RETCODE_ERROR_NVME_CMD_FAILED
11309* NI_RETCODE_ERROR_INVALID_SESSION
11310*******************************************************************************/
11312{
11314 struct netint_iocmd_export_dmabuf uexp;
11315 unsigned int offset;
11316 int ret, is_semi_planar;
11317 int linestride[NI_MAX_NUM_DATA_POINTERS];
11318 int alignedheight[NI_MAX_NUM_DATA_POINTERS];
11319 niFrameSurface1_t hwdesc = {0};
11320 niFrameSurface1_t *p_surface;
11321
11322 if (p_ctx == NULL || p_frame == NULL || p_frame->p_data[3] == NULL)
11323 {
11324 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
11325 __func__);
11327 }
11328
11329 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11330
11333
11334 retval = ni_hwupload_session_read_hwdesc(p_ctx, &hwdesc);
11335
11338
11339 if (retval != NI_RETCODE_SUCCESS)
11340 {
11341 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: hwdesc read failure %d\n", retval);
11342 return retval;
11343 }
11344
11345 retval = ni_get_memory_offset(p_ctx, &hwdesc, &offset);
11346 if (retval != NI_RETCODE_SUCCESS)
11347 {
11348 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: bad buffer id\n");
11350 }
11351
11352 is_semi_planar = ((p_ctx->pixel_format == NI_PIX_FMT_NV12) ||
11353 p_ctx->pixel_format == NI_PIX_FMT_P010LE) ?
11354 1 :
11355 0;
11356
11358 p_ctx->bit_depth_factor, is_semi_planar, linestride,
11359 alignedheight);
11360
11361 uexp.fd = -1;
11362 uexp.flags = 0;
11363 uexp.offset = offset;
11364
11365 uexp.length = ni_calculate_total_frame_size(p_ctx, linestride);
11366 uexp.domain = p_ctx->domain;
11367 uexp.bus = p_ctx->bus;
11368 uexp.dev = p_ctx->dev;
11369 uexp.fn = p_ctx->fn;
11370 uexp.bar = 4; // PCI BAR4 configuration space
11371
11372 ret = ioctl(p_ctx->netint_fd, NETINT_IOCTL_EXPORT_DMABUF, &uexp);
11373 if (ret < 0)
11374 {
11375 ni_log2(p_ctx, NI_LOG_ERROR, "%s: Failed to export dmabuf %d errno %d\n",
11376 __func__, ret, NI_ERRNO);
11377 return NI_RETCODE_FAILURE;
11378 }
11379
11380 *p_surface = hwdesc;
11381 p_surface->ui16width = p_ctx->active_video_width;
11382 p_surface->ui16height = p_ctx->active_video_height;
11383 p_surface->ui32nodeAddress = offset;
11384 p_surface->encoding_type = is_semi_planar ?
11387 p_surface->dma_buf_fd = uexp.fd;
11388
11389 return retval;
11390}
11391
11392/*!*****************************************************************************
11393* \brief Acquire a P2P frame buffer from the hwupload session for P2P read
11394*
11395* \param[in] p_ctx Pointer to a caller allocated
11396* ni_session_context_t struct
11397* \param[out] p_frame Pointer to a caller allocated hw frame
11398*
11399* \return On success
11400* NI_RETCODE_SUCCESS
11401* On failure
11402* NI_RETCODE_INVALID_PARAM
11403* NI_RETCODE_ERROR_NVME_CMD_FAILED
11404* NI_RETCODE_ERROR_INVALID_SESSION
11405*******************************************************************************/
11407{
11409
11410 int is_semi_planar;
11411 int linestride[NI_MAX_NUM_DATA_POINTERS];
11412 int alignedheight[NI_MAX_NUM_DATA_POINTERS];
11413 niFrameSurface1_t hwdesc = {0};
11414 niFrameSurface1_t *p_surface;
11415
11416 if (p_ctx == NULL || p_frame == NULL || p_frame->p_data[3] == NULL)
11417 {
11418 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
11419 __func__);
11421 }
11422
11423 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11424
11427
11428 retval = ni_hwupload_session_read_hwdesc(p_ctx, &hwdesc);
11429
11432
11433 if (retval != NI_RETCODE_SUCCESS)
11434 {
11435 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: hwdesc read failure %d\n", retval);
11436 return retval;
11437 }
11438
11439 is_semi_planar = ((p_ctx->pixel_format == NI_PIX_FMT_NV12) ||
11440 p_ctx->pixel_format == NI_PIX_FMT_P010LE) ?
11441 1 :
11442 0;
11443
11445 p_ctx->bit_depth_factor, is_semi_planar, linestride,
11446 alignedheight);
11447
11448 *p_surface = hwdesc;
11449 p_surface->ui16width = p_ctx->active_video_width;
11450 p_surface->ui16height = p_ctx->active_video_height;
11451 p_surface->ui32nodeAddress = 0;
11452 p_surface->encoding_type = is_semi_planar ?
11455 p_surface->dma_buf_fd = 0;
11456
11457 return retval;
11458}
11459
11460
11461/*!*****************************************************************************
11462 * \brief Lock a hardware P2P frame prior to encoding
11463 *
11464 * \param[in] p_upl_ctx pointer to caller allocated upload context
11465 * [in] p_frame pointer to caller allocated hardware P2P frame
11466 *
11467 * \return On success
11468 * NI_RETCODE_SUCCESS
11469 * On failure NI_RETCODE_FAILURE
11470 * NI_RETCODE_INVALID_PARAM
11471*******************************************************************************/
11473 ni_frame_t *p_frame)
11474{
11475 int ret;
11476 struct netint_iocmd_attach_rfence uatch = {0};
11477 struct pollfd pfds[1] = {0};
11478 niFrameSurface1_t *p_surface;
11479
11480 if (p_upl_ctx == NULL || p_frame == NULL)
11481 {
11482 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: bad parameters\n", __func__);
11484 }
11485
11486 if (p_frame->p_data[3] == NULL)
11487 {
11488 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: not a hardware frame\n", __func__);
11490 }
11491
11492 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11493
11494 pfds[0].fd = p_surface->dma_buf_fd;
11495 pfds[0].events = POLLIN;
11496 pfds[0].revents = 0;
11497
11498 ret = poll(pfds, 1, -1);
11499 char errmsg[NI_ERRNO_LEN] = {0};
11500 if (ret < 0)
11501 {
11503 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s:failed to poll dmabuf fd errno %s\n", __func__,
11504 errmsg);
11505 return ret;
11506 }
11507
11508 uatch.fd = p_surface->dma_buf_fd;
11509 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_ATTACH_RFENCE, &uatch);
11510 if (ret < 0)
11511 {
11513 ni_log2(p_upl_ctx, NI_LOG_ERROR,
11514 "%s: failed to attach dmabuf read fence errno %s\n", __func__,
11515 errmsg);
11516 return ret;
11517 }
11518
11519 return NI_RETCODE_SUCCESS;
11520}
11521
11522/*!*****************************************************************************
11523 * \brief Unlock a hardware P2P frame after encoding
11524 *
11525 * \param[in] p_upl_ctx pointer to caller allocated upload context
11526 * [in] p_frame pointer to caller allocated hardware P2P frame
11527 *
11528 * \return On success
11529 * NI_RETCODE_SUCCESS
11530 * On failure NI_RETCODE_FAILURE
11531 * NI_RETCODE_INVALID_PARAM
11532*******************************************************************************/
11534 ni_frame_t *p_frame)
11535{
11536 int ret;
11537 struct netint_iocmd_signal_rfence usigl = {0};
11538 niFrameSurface1_t *p_surface;
11539
11540 if ((p_upl_ctx == NULL) || (p_frame == NULL))
11541 {
11542 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid parameters %p %p\n", __func__,
11543 p_upl_ctx, p_frame);
11545 }
11546
11547 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11548
11549 if (p_surface == NULL)
11550 {
11551 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid hw frame\n", __func__);
11553 }
11554
11555 usigl.fd = p_surface->dma_buf_fd;
11556 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_SIGNAL_RFENCE, &usigl);
11557 if (ret < 0)
11558 {
11559 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Failed to signal dmabuf read fence\n");
11560 return NI_RETCODE_FAILURE;
11561 }
11562
11563 return NI_RETCODE_SUCCESS;
11564}
11565
11566/*!*****************************************************************************
11567 * \brief Special P2P test API function. Copies YUV data from the software
11568 * frame to the hardware P2P frame on the Quadra device
11569 *
11570 * \param[in] p_upl_ctx pointer to caller allocated uploader session
11571 * context
11572 * [in] p_swframe pointer to a caller allocated software frame
11573 * [in] p_hwframe pointer to a caller allocated hardware frame
11574 *
11575 * \return On success
11576 * NI_RETCODE_SUCCESS
11577 * On failure
11578 * NI_RETCODE_FAILURE
11579 * NI_RETCODE_INVALID_PARAM
11580*******************************************************************************/
11582 uint8_t *p_data, uint32_t len,
11583 ni_frame_t *p_hwframe)
11584{
11585 int ret;
11586 struct netint_iocmd_issue_request uis = {0};
11587 niFrameSurface1_t *p_surface;
11588
11589 if (p_upl_ctx == NULL || p_data == NULL || p_hwframe == NULL)
11590 {
11591 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: invalid null parameters\n", __func__);
11593 }
11594
11595 if (p_hwframe->p_data[3] == NULL)
11596 {
11597 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: empty frame\n", __func__);
11599 }
11600
11601 p_surface = (niFrameSurface1_t *)p_hwframe->p_data[3];
11602
11603 uis.fd = p_surface->dma_buf_fd;
11604 uis.data = p_data;
11605 uis.len = len;
11607
11608 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_ISSUE_REQ, &uis);
11609 if (ret < 0)
11610 {
11611 ni_log2(p_upl_ctx, NI_LOG_ERROR,
11612 "%s: Failed to request dmabuf rendering errno %d\n", __func__,
11613 NI_ERRNO);
11614 return NI_RETCODE_FAILURE;
11615 }
11616
11617 return NI_RETCODE_SUCCESS;
11618}
11619
11620/*!*****************************************************************************
11621 * \brief Special P2P test API function. Copies video data from the software
11622 * frame to the hardware P2P frame on the Quadra device. Does not
11623 * need the Netint kernel driver but requires root privilege.
11624 *
11625 * \param[in] p_upl_ctx pointer to caller allocated uploader session
11626 * context
11627 * [in] p_swframe pointer to a caller allocated software frame
11628 * [in] p_hwframe pointer to a caller allocated hardware frame
11629 *
11630 * \return On success
11631 * NI_RETCODE_SUCCESS
11632 * On failure
11633 * NI_RETCODE_FAILURE
11634 * NI_RETCODE_INVALID_PARAM
11635*******************************************************************************/
11637 uint8_t *p_data, uint32_t len,
11638 ni_frame_t *p_hwframe)
11639{
11640 int bar4_fd, ret;
11641 char bar4_name[128];
11642 char *bar4_mm;
11643 struct stat stat;
11644 niFrameSurface1_t *pSurf;
11645 uint32_t offset;
11646
11647 pSurf = (niFrameSurface1_t *) p_hwframe->p_data[3];
11648
11649 ret = ni_get_memory_offset(p_upl_ctx, pSurf, &offset);
11650 if (ret != 0)
11651 {
11652 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Error bad buffer id\n");
11653 return NI_RETCODE_FAILURE;
11654 }
11655
11656 (void)snprintf(bar4_name, 128,
11657 "/sys/bus/pci/devices/%04x:%02x:%02x.%1x/resource4",
11658 p_upl_ctx->domain,p_upl_ctx->bus,p_upl_ctx->dev,p_upl_ctx->fn);
11659
11660 bar4_fd = open(bar4_name, O_RDWR | O_SYNC);
11661
11662 char errmsg[NI_ERRNO_LEN] = {0};
11663 if (bar4_fd < 0)
11664 {
11666 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't open bar4 %s (%s)\n",
11667 bar4_name, errmsg);
11668 return NI_RETCODE_FAILURE;
11669 }
11670
11671 if (fstat(bar4_fd, &stat) != 0)
11672 {
11674 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't stat bar4 (%s)\n",
11675 errmsg);
11676 (void)close(bar4_fd);
11677 return NI_RETCODE_FAILURE;
11678 }
11679
11680 bar4_mm = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, bar4_fd, 0);
11681
11682 if (bar4_mm == MAP_FAILED)
11683 {
11685 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't mmap to bar4 (%s)\n",
11686 errmsg);
11687 (void)close(bar4_fd);
11688 return NI_RETCODE_FAILURE;
11689 }
11690
11691 /* Copy the data directly into Quadra video memory */
11692 memcpy(bar4_mm + offset, p_data, len);
11693
11694 (void)munmap(bar4_mm, 0);
11695 (void)close(bar4_fd);
11696
11697 return NI_RETCODE_SUCCESS;
11698}
11699
11700
11701/*!*****************************************************************************
11702 * \brief Recycle hw P2P frames
11703 *
11704 * \param [in] p_frame pointer to an acquired P2P hw frame
11705 *
11706 * \return on success
11707 * NI_RETCODE_SUCCESS
11708 *
11709 * on failure
11710 * NI_RETCODE_INVALID_PARAM
11711*******************************************************************************/
11713{
11714 niFrameSurface1_t *p_surface;
11715
11716 if (p_frame == NULL)
11717 {
11718 ni_log(NI_LOG_ERROR, "%s: Invalid frame\n", __func__);
11720 }
11721
11722 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11723 if (p_surface == NULL)
11724 {
11725 ni_log(NI_LOG_ERROR, "%s: Invalid surface data\n", __func__);
11727 }
11728
11729 return ni_hwframe_buffer_recycle2(p_surface);
11730}
11731
11732/*!*****************************************************************************
11733 * \brief Acquire the scaler P2P DMA buffer for read/write
11734 *
11735 * \param [in] p_ctx pointer to caller allocated upload context
11736 * [in] p_surface pointer to a caller allocated hardware frame
11737 * [in] data_len scaler frame buffer data length
11738 *
11739 * \return on success
11740 * NI_RETCODE_SUCCESS
11741 *
11742 * on failure
11743 * NI_RETCODE_FAILURE
11744*******************************************************************************/
11746 niFrameSurface1_t *p_surface,
11747 int data_len)
11748{
11749 unsigned int offset;
11750 int ret;
11751
11752 ret = ni_get_memory_offset(p_ctx, p_surface, &offset);
11753 if (ret != 0)
11754 {
11755 ni_log2(p_ctx, NI_LOG_ERROR, "Error: bad buffer id\n");
11756 return NI_RETCODE_FAILURE;
11757 }
11758 p_surface->ui32nodeAddress = 0;
11759
11760 struct netint_iocmd_export_dmabuf uexp;
11761 uexp.fd = -1;
11762 uexp.flags = 0;
11763 uexp.offset = offset;
11764 uexp.length = data_len;
11765 uexp.domain = p_ctx->domain;
11766 uexp.bus = p_ctx->bus;
11767 uexp.dev = p_ctx->dev;
11768 uexp.fn = p_ctx->fn;
11769 uexp.bar = 4;
11770 ret = ioctl(p_ctx->netint_fd, NETINT_IOCTL_EXPORT_DMABUF, &uexp);
11771 if (ret < 0)
11772 {
11773 char errmsg[NI_ERRNO_LEN] = {0};
11775 ni_log2(p_ctx, NI_LOG_ERROR, "failed to export dmabuf: %s\n", errmsg);
11776 return NI_RETCODE_FAILURE;
11777 }
11778 p_surface->dma_buf_fd = uexp.fd;
11779 return ret;
11780}
11781#endif
11782
11783/*!*****************************************************************************
11784 * \brief Set the incoming frame format for the encoder
11785 *
11786 * \param[in] p_enc_ctx pointer to encoder context
11787 * [in] p_enc_params pointer to encoder parameters
11788 * [in] width input width
11789 * [in] height input height
11790 * [in] bit_depth 8 for 8-bit YUV, 10 for 10-bit YUV
11791 * [in] src_endian NI_FRAME_LITTLE_ENDIAN or NI_FRAME_BIG_ENDIAN
11792 * [in] planar 0 for semi-planar YUV, 1 for planar YUV
11793 *
11794 * \return on success
11795 * NI_RETCODE_SUCCESS
11796 *
11797 * on failure
11798 * NI_RETCODE_INVALID_PARAM
11799 *
11800*******************************************************************************/
11802 ni_xcoder_params_t *p_enc_params,
11803 int width, int height,
11804 int bit_depth, int src_endian,
11805 int planar)
11806{
11807 int alignedw;
11808 int alignedh;
11809
11810 if (p_enc_ctx == NULL || p_enc_params == NULL)
11811 {
11812 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: null ptr\n", __func__);
11814 }
11815
11816 if (!(bit_depth == 8) && !(bit_depth == 10))
11817 {
11818 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad bit depth %d\n", __func__, bit_depth);
11820 }
11821
11822 if (!(src_endian == NI_FRAME_LITTLE_ENDIAN) &&
11823 !(src_endian == NI_FRAME_BIG_ENDIAN))
11824 {
11825 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad endian %d\n", __func__, src_endian);
11827 }
11828
11829 if ((planar < 0) || (planar >= NI_PIXEL_PLANAR_MAX))
11830 {
11831 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad planar value %d\n", __func__, planar);
11833 }
11834
11835 p_enc_ctx->src_bit_depth = bit_depth;
11836 p_enc_ctx->bit_depth_factor = (bit_depth == 8) ? 1 : 2;
11837 p_enc_ctx->src_endian = src_endian;
11838
11839 alignedw = width;
11840
11841 if (alignedw < NI_MIN_WIDTH)
11842 {
11843 p_enc_params->cfg_enc_params.conf_win_right +=
11844 (NI_MIN_WIDTH - width) / 2 * 2;
11845 alignedw = NI_MIN_WIDTH;
11846 } else
11847 {
11848 alignedw = ((width + 1) / 2) * 2;
11849 p_enc_params->cfg_enc_params.conf_win_right +=
11850 (alignedw - width) / 2 * 2;
11851 }
11852
11853 p_enc_params->source_width = alignedw;
11854 alignedh = height;
11855
11856 if (alignedh < NI_MIN_HEIGHT)
11857 {
11858 p_enc_params->cfg_enc_params.conf_win_bottom +=
11859 (NI_MIN_HEIGHT - height) / 2 * 2;
11860 alignedh = NI_MIN_HEIGHT;
11861 } else
11862 {
11863 alignedh = ((height + 1) / 2) * 2;
11864 p_enc_params->cfg_enc_params.conf_win_bottom +=
11865 (alignedh - height) / 2 * 2;
11866 }
11867
11868 p_enc_params->source_height = alignedh;
11869 p_enc_params->cfg_enc_params.planar = planar;
11870
11871 return NI_RETCODE_SUCCESS;
11872}
11873
11874/*!*****************************************************************************
11875 * \brief Set the outgoing frame format for the uploader
11876 *
11877 * \param[in] p_upl_ctx pointer to uploader context
11878 * [in] width width
11879 * [in] height height
11880 * [in] pixel_format pixel format
11881 * [in] isP2P 0 = normal, 1 = P2P
11882 *
11883 * \return on success
11884 * NI_RETCODE_SUCCESS
11885 *
11886 * on failure
11887 * NI_RETCODE_INVALID_PARAM
11888*******************************************************************************/
11890 int width, int height,
11891 ni_pix_fmt_t pixel_format, int isP2P)
11892{
11893 if (p_upl_ctx == NULL)
11894 {
11895 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: null ptr\n", __func__);
11897 }
11898
11899 switch (pixel_format)
11900 {
11901 case NI_PIX_FMT_YUV420P:
11902 case NI_PIX_FMT_NV12:
11903 case NI_PIX_FMT_NV16:
11904 case NI_PIX_FMT_YUYV422:
11905 case NI_PIX_FMT_UYVY422:
11906 p_upl_ctx->src_bit_depth = 8;
11907 p_upl_ctx->bit_depth_factor = 1;
11908 break;
11910 case NI_PIX_FMT_P010LE:
11911 p_upl_ctx->src_bit_depth = 10;
11912 p_upl_ctx->bit_depth_factor = 2;
11913 break;
11914 case NI_PIX_FMT_RGBA:
11915 case NI_PIX_FMT_BGRA:
11916 case NI_PIX_FMT_ARGB:
11917 case NI_PIX_FMT_ABGR:
11918 case NI_PIX_FMT_BGR0:
11919 case NI_PIX_FMT_BGRP:
11920 p_upl_ctx->src_bit_depth = 8;
11921 p_upl_ctx->bit_depth_factor = 4;
11922 break;
11923 default:
11924 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid pixfmt %d\n", __func__,
11925 pixel_format);
11927 }
11928
11930 p_upl_ctx->pixel_format = pixel_format;
11931 p_upl_ctx->active_video_width = width;
11932 p_upl_ctx->active_video_height = height;
11933 p_upl_ctx->isP2P = isP2P;
11934
11935 return NI_RETCODE_SUCCESS;
11936}
11937
11938/*!*****************************************************************************
11939 * \brief Read encoder stream header from the device
11940 *
11941 * \param[in] p_ctx Pointer to a caller allocated
11942 * ni_session_context_t struct from encoder
11943 * \param[in] p_data Pointer to a caller allocated ni_session_data_io_t
11944 * struct which contains a ni_packet_t data packet to
11945 * receive
11946 * \return On success
11947 * Total number of bytes read
11948 * On failure
11949 * NI_RETCODE_INVALID_PARAM
11950 * NI_RETCODE_ERROR_NVME_CMD_FAILED
11951 * NI_RETCODE_ERROR_INVALID_SESSION
11952*******************************************************************************/
11954 ni_session_data_io_t *p_data)
11955{
11956 int rx_size;
11957 int done = 0;
11958 int bytes_read = 0;
11959
11960 /* This function should be called once at the start of encoder read */
11961 if (p_ctx->pkt_num != 0)
11962 {
11963 ni_log2(p_ctx, NI_LOG_ERROR, "Error: stream header has already been read\n");
11965 }
11966
11967 while (!done)
11968 {
11969 rx_size = ni_device_session_read(p_ctx, p_data, NI_DEVICE_TYPE_ENCODER);
11970
11971 if (rx_size > (int)p_ctx->meta_size)
11972 {
11973 /* stream header has been read, return size */
11974 bytes_read += (rx_size - (int)p_ctx->meta_size);
11975
11976 p_ctx->pkt_num = 1;
11977 ni_log2(p_ctx, NI_LOG_DEBUG, "Got encoded stream header\n");
11978 done = 1;
11979 } else if (rx_size != 0)
11980 {
11981 ni_log2(p_ctx, NI_LOG_ERROR, "Error: received rx_size = %d\n", rx_size);
11982 bytes_read = -1;
11983 done = 1;
11984 } else
11985 {
11986 ni_log2(p_ctx, NI_LOG_DEBUG, "No data, keep reading..\n");
11987 continue;
11988 }
11989 }
11990
11991 return bytes_read;
11992}
11993
11994/*!*****************************************************************************
11995 * \brief Get the DMA buffer file descriptor from the P2P frame
11996 *
11997 * \param[in] p_frame pointer to a P2P frame
11998 *
11999 * \return On success
12000 * DMA buffer file descriptor
12001 * On failure
12002 * NI_RETCODE_INVALID_PARAM
12003*******************************************************************************/
12005{
12006 const niFrameSurface1_t *p_surface;
12007
12008 if (p_frame == NULL)
12009 {
12010 ni_log(NI_LOG_ERROR, "%s: NULL frame\n", __func__);
12012 }
12013
12014 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
12015
12016 if (p_surface == NULL)
12017 {
12018 ni_log(NI_LOG_ERROR, "%s: Invalid hw frame\n", __func__);
12020 }
12021
12022 return p_surface->dma_buf_fd;
12023}
12024
12025/*!*****************************************************************************
12026 * \brief Send sequence change information to device
12027 *
12028 * \param[in] p_ctx Pointer to a caller allocated
12029 * ni_session_context_t struct
12030 * \param[in] width input width
12031 * \param[in] height input height
12032 * \param[in] bit_depth_factor 1 for 8-bit YUV, 2 for 10-bit YUV
12033 * \param[in] device_type device type (must be encoder)
12034 * \return On success
12035 * NI_RETCODE_SUCCESS
12036 * On failure
12037 * NI_RETCODE_INVALID_PARAM
12038 * NI_RETCODE_ERROR_MEM_ALOC
12039 * NI_RETCODE_ERROR_NVME_CMD_FAILED
12040 * NI_RETCODE_ERROR_INVALID_SESSION
12041 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
12042 ******************************************************************************/
12044 int width, int height, int bit_depth_factor, ni_device_type_t device_type)
12045{
12046 ni_resolution_t resolution;
12048 ni_xcoder_params_t *p_param = NULL;
12049
12050 // requires API version >= 54
12052 "54") < 0)
12053 {
12054 ni_log2(p_ctx, NI_LOG_ERROR, "Error: %s function not supported on device with FW API version < 5.4\n", __func__);
12056 }
12057
12058 /* This function should be called only if sequence change is detected */
12060 {
12061 ni_log2(p_ctx, NI_LOG_ERROR, "Error: stream header has already been read\n");
12063 }
12064
12065 resolution.width = width;
12066 resolution.height = height;
12067 resolution.bit_depth_factor = bit_depth_factor;
12068 resolution.luma_linesize = 0;
12069 resolution.chroma_linesize = 0;
12070 if (p_ctx->p_session_config)
12071 {
12073 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
12074 p_enc = &p_param->cfg_enc_params;
12075 if (p_enc->spatial_layers > 1)
12076 {
12077 retval = NI_RETCODE_INVALID_PARAM;
12078 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Config sequence change not supported when spatialLayers > 1\n");
12079 return retval;
12080 }
12081 resolution.luma_linesize = p_param->luma_linesize;
12082 resolution.chroma_linesize = p_param->chroma_linesize;
12083 }
12084 else
12085 {
12087 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: invalid p_session_config\n");
12088 return retval;
12089 }
12090
12091 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: resolution change config - width %d height %d bit_depth_factor %d "
12092 "luma_linesize %d chroma_linesize %d\n", __func__,
12093 resolution.width, resolution.height, resolution.bit_depth_factor,
12094 resolution.luma_linesize, resolution.chroma_linesize);
12095
12096 switch (device_type)
12097 {
12099 {
12100 // config sequence change
12101 retval = ni_encoder_session_sequence_change(p_ctx, &resolution);
12102 break;
12103 }
12104 default:
12105 {
12106 retval = NI_RETCODE_INVALID_PARAM;
12107 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Config sequence change not supported for device type: %d", device_type);
12108 return retval;
12109 }
12110 }
12111 return retval;
12112}
12113
12115 ni_network_perf_metrics_t *p_metrics)
12116{
12117 return ni_ai_session_query_metrics(p_ctx, p_metrics);
12118}
12119
12120ni_retcode_t ni_query_fl_fw_versions(ni_device_handle_t device_handle,
12121 ni_device_info_t *p_dev_info)
12122{
12123 void *buffer;
12124 uint32_t size;
12125 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12126 ni_log_fl_fw_versions_t fl_fw_versions;
12127
12128 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_info))
12129 {
12130 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12131 __func__);
12133 }
12134
12136 "6h") < 0)
12137 {
12139 "ERROR: %s function not supported on device with FW API version < 6.h\n",
12140 __func__);
12142 }
12143
12144 buffer = NULL;
12146
12147 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12148 {
12149 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12151 }
12152
12153 memset(buffer, 0, size);
12154
12155 if (ni_nvme_send_read_cmd(device_handle,
12156 event_handle,
12157 buffer,
12158 size,
12160 {
12161 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12162 ni_aligned_free(buffer);
12164 }
12165
12166 memcpy(&fl_fw_versions, buffer, sizeof(ni_log_fl_fw_versions_t));
12167
12168 memcpy(p_dev_info->fl_ver_last_ran,
12169 &fl_fw_versions.last_ran_fl_version,
12171 memcpy(p_dev_info->fl_ver_nor_flash,
12172 &fl_fw_versions.nor_flash_fl_version,
12174 memcpy(p_dev_info->fw_rev_nor_flash,
12175 &fl_fw_versions.nor_flash_fw_revision,
12177
12178 ni_aligned_free(buffer);
12179 return NI_RETCODE_SUCCESS;
12180}
12181
12183 ni_load_query_t *p_load_query)
12184{
12185 void *buffer;
12186 uint32_t size;
12187
12188 ni_instance_mgr_general_status_t general_status;
12189
12190 if (!p_ctx)
12191 {
12192 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: p_ctx cannot be null\n");
12194 }
12195 if (!p_load_query)
12196 {
12197 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: p_load_query cannot be null\n");
12199 }
12200
12202 "6O") < 0)
12203 {
12204 ni_log2(p_ctx, NI_LOG_ERROR,
12205 "ERROR: %s function not supported on device with FW API version < 6.O\n",
12206 __func__);
12208 }
12209
12210 buffer = NULL;
12212
12213 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12214 {
12215 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12217 }
12218
12219 memset(buffer, 0, size);
12220
12222 p_ctx->event_handle,
12223 buffer,
12224 size,
12226 {
12227 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12228 ni_aligned_free(buffer);
12230 }
12231
12232 memcpy(&general_status, buffer, sizeof(ni_instance_mgr_general_status_t));
12233
12234 p_load_query->tp_fw_load = general_status.tp_fw_load;
12235 p_load_query->pcie_load = general_status.pcie_load;
12236 p_load_query->pcie_throughput = general_status.pcie_throughput;
12237 p_load_query->fw_load = general_status.fw_load;
12238 p_load_query->fw_share_mem_usage = general_status.fw_share_mem_usage;
12239
12240 ni_aligned_free(buffer);
12241 return NI_RETCODE_SUCCESS;
12242}
12243
12244ni_retcode_t ni_query_vf_ns_id(ni_device_handle_t device_handle,
12245 ni_device_vf_ns_id_t *p_dev_ns_vf,
12246 uint8_t fw_rev[])
12247{
12248 void *p_buffer = NULL;
12249 uint32_t size;
12250 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12251
12252 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_ns_vf))
12253 {
12254 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12255 __func__);
12257 }
12258
12260 "6m") < 0)
12261 {
12263 "ERROR: %s function not supported on device with FW API version < 6.m\n",
12264 __func__);
12266 }
12267
12269
12270 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12271 {
12272 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12274 }
12275
12276 memset(p_buffer, 0, size);
12277
12278 if (ni_nvme_send_read_cmd(device_handle,
12279 event_handle,
12280 p_buffer,
12281 size,
12282 QUERY_GET_NS_VF_R) < 0)
12283 {
12284 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12285 ni_aligned_free(p_buffer);
12287 }
12288
12289 ni_device_vf_ns_id_t *p_dev_ns_vf_data = (ni_device_vf_ns_id_t *)p_buffer;
12290 p_dev_ns_vf->vf_id = p_dev_ns_vf_data->vf_id;
12291 p_dev_ns_vf->ns_id = p_dev_ns_vf_data->ns_id;
12292 ni_log(NI_LOG_DEBUG, "%s(): NS/VF %u/%u\n", __func__, p_dev_ns_vf->ns_id, p_dev_ns_vf->vf_id);
12293 ni_aligned_free(p_buffer);
12294 return NI_RETCODE_SUCCESS;
12295}
12296
12297ni_retcode_t ni_query_temperature(ni_device_handle_t device_handle,
12298 ni_device_temp_t *p_dev_temp,
12299 uint8_t fw_rev[])
12300{
12301 void *p_buffer = NULL;
12302 uint32_t size;
12303 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12304
12305 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_temp))
12306 {
12307 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12308 __func__);
12310 }
12311
12313 "6rC") < 0)
12314 {
12316 "ERROR: %s function not supported on device with FW API version < 6rC\n",
12317 __func__);
12319 }
12320
12322
12323 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12324 {
12325 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12327 }
12328
12329 memset(p_buffer, 0, size);
12330
12331 if (ni_nvme_send_read_cmd(device_handle,
12332 event_handle,
12333 p_buffer,
12334 size,
12336 {
12337 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12338 ni_aligned_free(p_buffer);
12340 }
12341
12342 ni_device_temp_t *p_dev_temp_data = (ni_device_temp_t *)p_buffer;
12343 p_dev_temp->composite_temp = p_dev_temp_data->composite_temp;
12344 p_dev_temp->on_board_temp = p_dev_temp_data->on_board_temp;
12345 p_dev_temp->on_die_temp = p_dev_temp_data->on_die_temp;
12346 ni_log(NI_LOG_DEBUG, "%s(): current composite temperature %d on board temperature %d on die temperature %d\n",
12347 __func__, p_dev_temp->composite_temp, p_dev_temp->on_board_temp, p_dev_temp->on_die_temp);
12348 ni_aligned_free(p_buffer);
12349 return NI_RETCODE_SUCCESS;
12350}
12351
12352ni_retcode_t ni_query_extra_info(ni_device_handle_t device_handle,
12353 ni_device_extra_info_t *p_dev_extra_info,
12354 uint8_t fw_rev[])
12355{
12356 void *p_buffer = NULL;
12357 uint32_t size;
12358 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12359
12360 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_extra_info))
12361 {
12362 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12363 __func__);
12365 }
12366
12368 "6rC") < 0)
12369 {
12371 "ERROR: %s function not supported on device with FW API version < 6rC\n",
12372 __func__);
12374 }
12375
12377
12378 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12379 {
12380 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12382 }
12383
12384 memset(p_buffer, 0, size);
12385
12386 if (ni_nvme_send_read_cmd(device_handle,
12387 event_handle,
12388 p_buffer,
12389 size,
12391 {
12392 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12393 ni_aligned_free(p_buffer);
12395 }
12396
12397 ni_device_extra_info_t *p_dev_extra_info_data = (ni_device_extra_info_t *)p_buffer;
12398 p_dev_extra_info->composite_temp = p_dev_extra_info_data->composite_temp;
12399 p_dev_extra_info->on_board_temp = p_dev_extra_info_data->on_board_temp;
12400 p_dev_extra_info->on_die_temp = p_dev_extra_info_data->on_die_temp;
12401 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sN") >= 0)
12402 {
12403 p_dev_extra_info->fw_flavour = p_dev_extra_info_data->fw_flavour;
12404 }
12405 else
12406 {
12407 p_dev_extra_info->fw_flavour = (uint8_t)'-';
12408 }
12409 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rC") >= 0 &&
12410 ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rR") < 0)
12411 {
12412 p_dev_extra_info->power_consumption = NI_INVALID_POWER;
12413 }
12414 else
12415 {
12416 p_dev_extra_info->power_consumption = p_dev_extra_info_data->power_consumption;
12417 }
12418 //QUADPV-1210-Remove ADC current measurement decoding from FW
12419 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6s4") >= 0 &&
12420 ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sR") <= 0)
12421 {
12422 p_dev_extra_info->current_consumption = p_dev_extra_info_data->current_consumption;
12423 ni_device_capability_t device_capability = {0};
12424 if (ni_device_capability_query2(device_handle, &device_capability, false) != NI_RETCODE_SUCCESS)
12425 {
12426 ni_log(NI_LOG_ERROR, "ERROR: unable to query capability\n");
12428 }
12429 p_dev_extra_info->power_consumption = ni_decode_power_measurement(p_dev_extra_info->current_consumption, device_capability.serial_number);
12430 }
12431
12432 ni_log(NI_LOG_DEBUG, "%s(): current composite temperature %d on board temperature %d "
12433 "on die temperature %d power consumption %d current consumption %d\n",
12434 __func__, p_dev_extra_info->composite_temp, p_dev_extra_info->on_board_temp,
12435 p_dev_extra_info->on_die_temp, p_dev_extra_info->power_consumption, p_dev_extra_info->current_consumption);
12436 ni_aligned_free(p_buffer);
12437 return NI_RETCODE_SUCCESS;
12438}
12439
12440ni_retcode_t ni_query_qos_info(ni_device_handle_t device_handle,
12441 ni_qos_header_info_log_page_t *p_dev_qos_header,
12442 uint8_t fw_rev[])
12443{
12444 void *buffer;
12445 uint32_t size;
12446 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12447
12448 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_qos_header) || (!fw_rev))
12449 {
12450 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12451 __func__);
12453 }
12454
12456 "6t0") < 0)
12457 {
12459 "INFO: %s function not supported on device with FW API version < 6t0\n",
12460 __func__);
12462 }
12463
12464 buffer = NULL;
12465 size = ((sizeof(ni_qos_header_info_log_page_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) /
12467
12468 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12469 {
12470 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12472 }
12473
12474 memset(buffer, 0, size);
12475
12476 if (ni_nvme_send_read_cmd(device_handle,
12477 event_handle,
12478 buffer,
12479 size,
12481 {
12482 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12483 ni_aligned_free(buffer);
12485 }
12486
12488 p_dev_qos_header->ui16QosState = (uint8_t)(qos_header_info->ui16QosState & 0xFF);
12489 p_dev_qos_header->ui16ActiveNamespaces = qos_header_info->ui16ActiveNamespaces;
12490 p_dev_qos_header->fTotalAllowance = qos_header_info->fTotalAllowance;
12491
12492 ni_aligned_free(buffer);
12493 return NI_RETCODE_SUCCESS;
12494}
12495
12496/*!*****************************************************************************
12497 * \brief Query QoS information for a specific namespace
12498 *
12499 * \param[in] device_handle Device handle for the target namespace
12500 * \param[out] p_qos_ns_info Pointer to namespace QoS info structure
12501 * \param[in] fw_rev[] Firmware version array
12502 *
12503 * \return On success
12504 * NI_RETCODE_SUCCESS
12505 * On failure
12506 * NI_RETCODE_INVALID_PARAM
12507 * NI_RETCODE_ERROR_NVME_CMD_FAILED
12508 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
12509 * NI_RETCODE_ERROR_MEM_ALOC
12510 ******************************************************************************/
12511ni_retcode_t ni_query_qos_namespace_info(ni_device_handle_t device_handle,
12513 uint8_t fw_rev[])
12514{
12515 void *buffer;
12516 uint32_t size;
12517 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12518
12519 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_qos_ns) || (!fw_rev))
12520 {
12521 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12522 __func__);
12524 }
12525
12527 "6t0") < 0)
12528 {
12530 "INFO: %s function not supported on device with FW API version < 6t0\n",
12531 __func__);
12533 }
12534
12535 buffer = NULL;
12538
12539 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12540 {
12541 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12543 }
12544
12545 memset(buffer, 0, size);
12546
12547 if (ni_nvme_send_read_cmd(device_handle,
12548 event_handle,
12549 buffer,
12550 size,
12551 QUERY_GET_QOS_NS_INFO_R) < 0) // NSID comes from device handle
12552 {
12553 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12554 ni_aligned_free(buffer);
12556 }
12557
12559
12560 p_dev_qos_ns->ui8VirtualFunction = qos_ns_info->ui8VirtualFunction;
12561 p_dev_qos_ns->ui8NamespaceId = qos_ns_info->ui8NamespaceId;
12562 p_dev_qos_ns->fAllowance = qos_ns_info->fAllowance;
12563 p_dev_qos_ns->ui32BaseSliceTimeUs = qos_ns_info->ui32BaseSliceTimeUs;
12564 p_dev_qos_ns->ui32OPmaxUs = qos_ns_info->ui32OPmaxUs;
12565
12566 ni_log(NI_LOG_DEBUG, "%s(): NS %u VF %u Allowance %.2f%% SliceTime %u OPmax %u\n",
12567 __func__,
12568 p_dev_qos_ns->ui8NamespaceId,
12569 p_dev_qos_ns->ui8VirtualFunction,
12570 p_dev_qos_ns->fAllowance,
12571 p_dev_qos_ns->ui32BaseSliceTimeUs,
12572 p_dev_qos_ns->ui32OPmaxUs);
12573
12574 ni_aligned_free(buffer);
12575 return NI_RETCODE_SUCCESS;
12576}
12577
12578/*!*****************************************************************************
12579 * \brief Allocate log buffer if needed and retrieve firmware logs from device
12580 *
12581 * \param[in] p_ctx Pointer to a caller allocated
12582 * ni_session_context_t struct
12583 * \param[in] p_log_buffer Reference to pointer to a log buffer
12584 * If log buffer pointer is NULL, this function will allocate log buffer
12585 * NOTE caller is responsible for freeing log buffer after calling this function
12586 * \param[in] gen_log_file Indicating whether it is required to generate log files
12587 *
12588 *
12589 * \return on success
12590 * NI_RETCODE_SUCCESS
12591 *
12592 * on failure
12593 * NI_RETCODE_ERROR_MEM_ALOC
12594 * NI_RETCODE_INVALID_PARAM
12595*******************************************************************************/
12596ni_retcode_t ni_device_alloc_and_get_firmware_logs(ni_session_context_t *p_ctx, void** p_log_buffer, bool gen_log_file)
12597{
12599 bool is_ext_buf = true;
12600 if (*p_log_buffer == NULL)
12601 {
12602 if (ni_posix_memalign(p_log_buffer, sysconf(_SC_PAGESIZE), TOTAL_CPU_LOG_BUFFER_SIZE))
12603 {
12604 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate log buffer\n",
12605 NI_ERRNO, __func__);
12607 }
12608 is_ext_buf = false;
12609 }
12610
12611 if(*p_log_buffer != NULL){
12612 memset(*p_log_buffer, 0, TOTAL_CPU_LOG_BUFFER_SIZE);
12613 retval = ni_dump_log_all_cores(p_ctx, *p_log_buffer, gen_log_file); // dump FW logs
12614 if(!is_ext_buf)
12615 ni_aligned_free(*p_log_buffer);
12616 }else{
12618 }
12619
12620 return retval;
12621}
12622
12623/*!*****************************************************************************
12624 * \brief Read log artifacts from the device and save to disk.
12625 *
12626 * \param[in] p_ctx Pointer to an open session context
12627 * \param[in] gen_artifacts_file Write artifacts_slot_X_domain.tar.gz to disk
12628 *
12629 * \return on success
12630 * NI_RETCODE_SUCCESS on success, error code otherwise
12631 * on failure
12632 * NI_RETCODE_INVALID_PARAM
12633 *
12634*******************************************************************************/
12636 bool gen_artifacts_file)
12637{
12638 if (!p_ctx)
12639 {
12640 ni_log(NI_LOG_ERROR, "ERROR: %s() p_ctx is NULL\n", __func__);
12642 }
12643
12644 /* Artifacts supported from fw version >= ("6tA") - version gating */
12645 if (p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX] != '\0' &&
12648 "6tA") < 0)
12649 {
12651 "%s: firmware %.8s does not support artifacts (< 6tA), skipping\n",
12652 __func__, (char *)p_ctx->fw_rev);
12653 return NI_RETCODE_SUCCESS;
12654 }
12655
12656 return ni_dump_log_artifacts(p_ctx, gen_artifacts_file);
12657}
12658
12659/*!*****************************************************************************
12660 * \brief Set up hard coded demo ROI map
12661 *
12662 * \param[in] p_enc_ctx Pointer to a caller allocated
12663 *
12664 * \return on success
12665 * NI_RETCODE_SUCCESS
12666 *
12667 * on failure
12668 * NI_RETCODE_ERROR_MEM_ALOC
12669*******************************************************************************/
12671{
12672 ni_xcoder_params_t *p_param =
12673 (ni_xcoder_params_t *)(p_enc_ctx->p_session_config);
12674 int sumQp = 0;
12675 uint32_t ctu, i, j;
12676 // mode 1: Set QP for center 1/3 of picture to highest - lowest quality
12677 // the rest to lowest - highest quality;
12678 // mode non-1: reverse of mode 1
12679 int importanceLevelCentre = p_param->roi_demo_mode == 1 ? 40 : 10;
12680 int importanceLevelRest = p_param->roi_demo_mode == 1 ? 10 : 40;
12681 int linesize_aligned = p_param->source_width;
12682 int height_aligned = p_param->source_height;
12683 if (QUADRA)
12684 {
12685 uint32_t block_size, max_cu_size, customMapSize;
12686 uint32_t mbWidth;
12687 uint32_t mbHeight;
12688 uint32_t numMbs;
12689 uint32_t roiMapBlockUnitSize;
12690 uint32_t entryPerMb;
12691
12692 max_cu_size = p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264 ? 16: 64;
12693 // AV1 non-8x8-aligned resolution is implicitly cropped due to Quadra HW limitation
12694 if (NI_CODEC_FORMAT_AV1 == p_enc_ctx->codec_format)
12695 {
12696 linesize_aligned = (linesize_aligned / 8) * 8;
12697 height_aligned = (height_aligned / 8) * 8;
12698 }
12699
12700 // (ROI map version >= 1) each QP info takes 8-bit, represent 8 x 8
12701 // pixel block
12702 block_size =
12703 ((linesize_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) *
12704 ((height_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12705 (8 * 8);
12706
12707 // need to align to 64 bytes
12708 customMapSize = ((block_size + 63) & (~63));
12709 if (!p_enc_ctx->roi_map)
12710 {
12711 p_enc_ctx->roi_map =
12712 (ni_enc_quad_roi_custom_map *)calloc(1, customMapSize);
12713 }
12714 if (!p_enc_ctx->roi_map)
12715 {
12717 }
12718
12719 // for H.264, select ROI Map Block Unit Size: 16x16
12720 // for H.265, select ROI Map Block Unit Size: 64x64
12721 roiMapBlockUnitSize = p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264 ? 16 : 64;
12722
12723 mbWidth =
12724 ((linesize_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12725 roiMapBlockUnitSize;
12726 mbHeight =
12727 ((height_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12728 roiMapBlockUnitSize;
12729 numMbs = mbWidth * mbHeight;
12730
12731 // copy roi MBs QPs into custom map
12732 // number of qp info (8x8) per mb or ctb
12733 entryPerMb = (roiMapBlockUnitSize / 8) * (roiMapBlockUnitSize / 8);
12734
12735 for (i = 0; i < numMbs; i++)
12736 {
12737 bool bIsCenter = (i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3);
12738 for (j = 0; j < entryPerMb; j++)
12739 {
12740 /*
12741 g_quad_roi_map[i*4+j].field.skip_flag = 0; // don't force
12742 skip mode g_quad_roi_map[i*4+j].field.roiAbsQp_flag = 1; //
12743 absolute QP g_quad_roi_map[i*4+j].field.qp_info = bIsCenter
12744 ? importanceLevelCentre : importanceLevelRest;
12745 */
12746 p_enc_ctx->roi_map[i * entryPerMb + j].field.ipcm_flag =
12747 0; // don't force skip mode
12748 p_enc_ctx->roi_map[i * entryPerMb + j]
12749 .field.roiAbsQp_flag = 1; // absolute QP
12750 p_enc_ctx->roi_map[i * entryPerMb + j].field.qp_info =
12751 bIsCenter ? importanceLevelCentre : importanceLevelRest;
12752 }
12753 sumQp += p_enc_ctx->roi_map[(ptrdiff_t)i * entryPerMb].field.qp_info;
12754 }
12755 p_enc_ctx->roi_len = customMapSize;
12756 p_enc_ctx->roi_avg_qp =
12757 (numMbs > 0) ? (sumQp + (numMbs >> 1)) / numMbs : 0; // round off
12758 }
12759 else if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264)
12760 {
12761 // roi for H.264 is specified for 16x16 pixel macroblocks - 1 MB
12762 // is stored in each custom map entry
12763
12764 // number of MBs in each row
12765 uint32_t mbWidth = (linesize_aligned + 16 - 1) >> 4;
12766 // number of MBs in each column
12767 uint32_t mbHeight = (height_aligned + 16 - 1) >> 4;
12768 uint32_t numMbs = mbWidth * mbHeight;
12769 uint32_t customMapSize =
12770 sizeof(ni_enc_avc_roi_custom_map_t) * numMbs;
12771 p_enc_ctx->avc_roi_map =
12772 (ni_enc_avc_roi_custom_map_t *)calloc(1, customMapSize);
12773 if (!p_enc_ctx->avc_roi_map)
12774 {
12776 }
12777
12778 // copy roi MBs QPs into custom map
12779 for (i = 0; i < numMbs; i++)
12780 {
12781 if ((i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3))
12782 {
12783 p_enc_ctx->avc_roi_map[i].field.mb_qp = importanceLevelCentre;
12784 }
12785 else
12786 {
12787 p_enc_ctx->avc_roi_map[i].field.mb_qp = importanceLevelRest;
12788 }
12789 sumQp += p_enc_ctx->avc_roi_map[i].field.mb_qp;
12790 }
12791 p_enc_ctx->roi_len = customMapSize;
12792 p_enc_ctx->roi_avg_qp =
12793 (numMbs > 0) ? (sumQp + (numMbs >> 1)) / numMbs : 0; // round off
12794 }
12795 else if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265)
12796 {
12797 // roi for H.265 is specified for 32x32 pixel subCTU blocks - 4
12798 // subCTU QPs are stored in each custom CTU map entry
12799
12800 // number of CTUs in each row
12801 uint32_t ctuWidth = (linesize_aligned + 64 - 1) >> 6;
12802 // number of CTUs in each column
12803 uint32_t ctuHeight = (height_aligned + 64 - 1) >> 6;
12804 // number of sub CTUs in each row
12805 uint32_t subCtuWidth = ctuWidth * 2;
12806 // number of CTUs in each column
12807 uint32_t subCtuHeight = ctuHeight * 2;
12808 uint32_t numSubCtus = subCtuWidth * subCtuHeight;
12809
12810 p_enc_ctx->hevc_sub_ctu_roi_buf = (uint8_t *)malloc(numSubCtus);
12811 if (!p_enc_ctx->hevc_sub_ctu_roi_buf)
12812 {
12814 }
12815 for (i = 0; i < numSubCtus; i++)
12816 {
12817 if ((i % subCtuWidth > subCtuWidth / 3) &&
12818 (i % subCtuWidth < subCtuWidth * 2 / 3))
12819 {
12820 p_enc_ctx->hevc_sub_ctu_roi_buf[i] = importanceLevelCentre;
12821 }
12822 else
12823 {
12824 p_enc_ctx->hevc_sub_ctu_roi_buf[i] = importanceLevelRest;
12825 }
12826 }
12827 p_enc_ctx->hevc_roi_map = (ni_enc_hevc_roi_custom_map_t *)calloc(
12828 1, sizeof(ni_enc_hevc_roi_custom_map_t) * ctuWidth * ctuHeight);
12829 if (!p_enc_ctx->hevc_roi_map)
12830 {
12832 }
12833
12834 for (i = 0; i < ctuHeight; i++)
12835 {
12836 uint8_t *ptr = &p_enc_ctx->hevc_sub_ctu_roi_buf[(size_t)subCtuWidth * i * 2];
12837 for (j = 0; j < ctuWidth; j++, ptr += 2)
12838 {
12839 ctu = (i * ctuWidth + j);
12840 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_0 = *ptr;
12841 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_1 = *(ptr + 1);
12842 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_2 =
12843 *(ptr + subCtuWidth);
12844 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_3 =
12845 *(ptr + subCtuWidth + 1);
12846 sumQp += (p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_0 +
12847 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_1 +
12848 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_2 +
12849 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_3);
12850 }
12851 }
12852 p_enc_ctx->roi_len =
12853 (size_t)ctuWidth * ctuHeight * sizeof(ni_enc_hevc_roi_custom_map_t);
12854 p_enc_ctx->roi_avg_qp =
12855 (numSubCtus > 0) ? (sumQp + (numSubCtus >> 1)) / numSubCtus : 0; // round off
12856 }
12857 return NI_RETCODE_SUCCESS;
12858}
12859
12861{
12862 // for encoder reconfiguration testing
12863 // reset encoder change data buffer for reconf parameters
12864 ni_retcode_t retval = 0;
12865 ni_xcoder_params_t *p_param =
12867 ni_aux_data_t *aux_data = NULL;
12870 {
12871 memset(p_enc_ctx->enc_change_params, 0, sizeof(ni_encoder_change_params_t));
12872 }
12873
12874 switch (p_param->reconf_demo_mode) {
12876 if (p_enc_ctx->frame_num ==
12877 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12878 {
12879 aux_data = ni_frame_new_aux_data(
12880 p_frame, NI_FRAME_AUX_DATA_BITRATE, sizeof(int32_t));
12881 if (!aux_data)
12882 {
12884 }
12885 *((int32_t *)aux_data->data) =
12886 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12887
12888 p_enc_ctx->reconfigCount++;
12889 if (p_param->cfg_enc_params.hrdEnable)
12890 {
12891 p_frame->force_key_frame = 1;
12892 p_frame->ni_pict_type = PIC_TYPE_IDR;
12893 }
12894 }
12895 break;
12896 // reconfig intraperiod param
12898 if (p_enc_ctx->frame_num ==
12899 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12900 {
12901 aux_data = ni_frame_new_aux_data(
12902 p_frame, NI_FRAME_AUX_DATA_INTRAPRD, sizeof(int32_t));
12903 if (!aux_data)
12904 {
12906 }
12907 int32_t intraprd = *((int32_t *)aux_data->data) =
12908 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12909 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12910 "xcoder_send_frame: frame #%lu reconf "
12911 "intraPeriod %d\n",
12912 p_enc_ctx->frame_num,
12913 intraprd);
12914 p_enc_ctx->reconfigCount++;
12915 }
12916 break;
12917 // reconfig VUI parameters
12919 if (p_enc_ctx->frame_num ==
12920 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12921 {
12922 aux_data = ni_frame_new_aux_data(p_frame,
12924 sizeof(ni_vui_hrd_t));
12925 if (!aux_data)
12926 {
12928 }
12929 ni_vui_hrd_t *vui = (ni_vui_hrd_t *)aux_data->data;
12930 vui->colorDescPresent =
12931 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12932 vui->colorPrimaries =
12933 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12934 vui->colorTrc =
12935 p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
12936 vui->colorSpace =
12937 p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
12938 vui->aspectRatioWidth =
12939 p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
12940 vui->aspectRatioHeight =
12941 p_param->reconf_hash[p_enc_ctx->reconfigCount][6];
12942 vui->videoFullRange =
12943 p_param->reconf_hash[p_enc_ctx->reconfigCount][7];
12944 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12945 "xcoder_send_frame: frame #%lu reconf "
12946 "vui colorDescPresent %d colorPrimaries %d "
12947 "colorTrc %d colorSpace %d aspectRatioWidth %d "
12948 "aspectRatioHeight %d videoFullRange %d\n",
12949 p_enc_ctx->frame_num, vui->colorDescPresent,
12950 vui->colorPrimaries, vui->colorTrc,
12951 vui->colorSpace, vui->aspectRatioWidth,
12953
12954 p_enc_ctx->reconfigCount++;
12955 }
12956 break;
12957 // long term ref
12959 // the reconf file data line format for this is:
12960 // <frame-number>:useCurSrcAsLongtermPic,useLongtermRef where
12961 // values will stay the same on every frame until changed.
12962 if (p_enc_ctx->frame_num ==
12963 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
12964 {
12965 ni_long_term_ref_t *p_ltr;
12966 aux_data = ni_frame_new_aux_data(
12968 sizeof(ni_long_term_ref_t));
12969 if (!aux_data)
12970 {
12972 }
12973 p_ltr = (ni_long_term_ref_t *)aux_data->data;
12975 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
12976 p_ltr->use_long_term_ref =
12977 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
12978 ni_log2(p_enc_ctx, NI_LOG_TRACE,
12979 "xcoder_send_frame: frame #%lu metadata "
12980 "use_cur_src_as_long_term_pic %d use_long_term_ref "
12981 "%d\n",
12982 p_enc_ctx->frame_num,
12984 p_ltr->use_long_term_ref);
12985 p_enc_ctx->reconfigCount++;
12986 }
12987 break;
12988 // reconfig min / max QP
12991 if (p_enc_ctx->frame_num ==
12992 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
12993 aux_data = ni_frame_new_aux_data(
12995 if (!aux_data) {
12997 }
12998
12999 ni_rc_min_max_qp *qp_info = (ni_rc_min_max_qp *)aux_data->data;
13000 qp_info->minQpI = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13001 qp_info->maxQpI = p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13002 qp_info->maxDeltaQp = p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13003 qp_info->minQpPB = p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13004 qp_info->maxQpPB = p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13005
13006 p_enc_ctx->reconfigCount++;
13007 }
13008 break;
13009#ifdef QUADRA
13010 // reconfig LTR interval
13012 if (p_enc_ctx->frame_num ==
13013 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13014 aux_data = ni_frame_new_aux_data(p_frame,
13016 sizeof(int32_t));
13017 if (!aux_data) {
13019 }
13020 *((int32_t *)aux_data->data) =
13021 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13022 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13023 "xcoder_send_frame: frame #%lu reconf "
13024 "ltrInterval %d\n",
13025 p_enc_ctx->frame_num,
13026 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13027
13028 p_enc_ctx->reconfigCount++;
13029 }
13030 break;
13031 // invalidate reference frames
13033 if (p_enc_ctx->frame_num ==
13034 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13035 aux_data = ni_frame_new_aux_data(
13037 sizeof(int32_t));
13038 if (!aux_data) {
13040 }
13041 *((int32_t *)aux_data->data) =
13042 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13043 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13044 "xcoder_send_frame: frame #%lu reconf "
13045 "invalidFrameNum %d\n",
13046 p_enc_ctx->frame_num,
13047 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13048
13049 p_enc_ctx->reconfigCount++;
13050 }
13051 break;
13052 // reconfig framerate
13054 if (p_enc_ctx->frame_num ==
13055 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13056 ni_framerate_t *framerate;
13057
13058 aux_data = ni_frame_new_aux_data(p_frame,
13060 sizeof(ni_framerate_t));
13061 if (!aux_data) {
13063 }
13064
13065 framerate = (ni_framerate_t *)aux_data->data;
13066 framerate->framerate_num =
13067 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13068 framerate->framerate_denom =
13069 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13070 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13071 "xcoder_send_frame: frame #%lu reconf "
13072 "framerate (%d/%d)\n",
13073 p_enc_ctx->frame_num, framerate->framerate_num,
13074 framerate->framerate_denom);
13075 p_enc_ctx->reconfigCount++;
13076 }
13077 break;
13079 if (p_enc_ctx->frame_num ==
13080 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13081 aux_data = ni_frame_new_aux_data(
13082 p_frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
13083 if (!aux_data) {
13085 }
13086 *((int32_t *)aux_data->data) =
13087 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13088 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13089 "xcoder_send_frame: frame #%lu reconf "
13090 "maxFrameSize %d\n",
13091 p_enc_ctx->frame_num,
13092 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13093
13094 p_enc_ctx->reconfigCount++;
13095 }
13096 break;
13098 if (p_enc_ctx->frame_num ==
13099 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13100 aux_data = ni_frame_new_aux_data(
13101 p_frame, NI_FRAME_AUX_DATA_CRF, sizeof(int32_t));
13102 if (!aux_data) {
13104 }
13105 *((int32_t *)aux_data->data) =
13106 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13107 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13108 "xcoder_send_frame: frame #%lu reconf "
13109 "crf %d\n",
13110 p_enc_ctx->frame_num,
13111 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13112
13113 p_enc_ctx->reconfigCount++;
13114 }
13115 break;
13117 if (p_enc_ctx->frame_num ==
13118 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13119 aux_data = ni_frame_new_aux_data(
13120 p_frame, NI_FRAME_AUX_DATA_CRF_FLOAT, sizeof(float));
13121 if (!aux_data) {
13123 }
13124 float crf = (float)(p_param->reconf_hash[p_enc_ctx->reconfigCount][1] +
13125 (float)p_param->reconf_hash[p_enc_ctx->reconfigCount][2] / 100.0);
13126 *((float *)aux_data->data) = crf;
13127 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13128 "xcoder_send_frame: frame #%lu reconf "
13129 "crf %f\n",
13130 p_enc_ctx->frame_num, crf);
13131
13132 p_enc_ctx->reconfigCount++;
13133 }
13134 break;
13136 if (p_enc_ctx->frame_num ==
13137 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13138 int32_t vbvBufferSize = p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13139 int32_t vbvMaxRate = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13140 if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
13141 {
13142 ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid vbvBufferSize value %d\n",
13143 __func__, vbvBufferSize);
13145 }
13146 if (p_param->bitrate > 0 && vbvMaxRate > 0 && vbvMaxRate < p_param->bitrate) {
13147 ni_log2(p_enc_ctx, NI_LOG_ERROR, "vbvMaxRate %u cannot be smaller than bitrate %d\n",
13148 vbvMaxRate, p_param->bitrate);
13150 }
13151 if (vbvBufferSize == 0 && vbvMaxRate > 0) {
13152 ni_log2(p_enc_ctx, NI_LOG_INFO, "vbvMaxRate %d does not take effect when "
13153 "vbvBufferSize is 0, force vbvMaxRate to 0\n",
13154 vbvMaxRate);
13155 vbvMaxRate = 0;
13156 }
13157
13158 aux_data = ni_frame_new_aux_data(
13159 p_frame, NI_FRAME_AUX_DATA_VBV_MAX_RATE, sizeof(int32_t));
13160 if (!aux_data) {
13162 }
13163 *((int32_t *)aux_data->data) = vbvMaxRate;
13164 aux_data = ni_frame_new_aux_data(
13165 p_frame, NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE, sizeof(int32_t));
13166 if (!aux_data) {
13168 }
13169 *((int32_t *)aux_data->data) = vbvBufferSize;
13170 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13171 "xcoder_send_frame: frame #%lu reconfig vbvMaxRate %d vbvBufferSize "
13172 "%d by frame aux data\n",
13173 p_enc_ctx->frame_num, vbvMaxRate, vbvBufferSize);
13174
13175 p_enc_ctx->reconfigCount++;
13176 }
13177 break;
13179 if (p_enc_ctx->frame_num ==
13180 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13181 int maxFrameSizeRatio = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13182 if (maxFrameSizeRatio < 1) {
13183 ni_log2(p_enc_ctx, NI_LOG_ERROR, "maxFrameSizeRatio %d cannot < 1\n",
13184 maxFrameSizeRatio);
13186 }
13187 aux_data = ni_frame_new_aux_data(
13188 p_frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
13189 if (!aux_data) {
13191 }
13192
13193 int32_t bitrate, framerate_num, framerate_denom;
13194 uint32_t min_maxFrameSize, maxFrameSize;
13195 bitrate = (p_enc_ctx->target_bitrate > 0) ? p_enc_ctx->target_bitrate : p_param->bitrate;
13196
13197 if ((p_enc_ctx->framerate.framerate_num > 0) && (p_enc_ctx->framerate.framerate_denom > 0))
13198 {
13199 framerate_num = p_enc_ctx->framerate.framerate_num;
13200 framerate_denom = p_enc_ctx->framerate.framerate_denom;
13201 }
13202 else
13203 {
13204 framerate_num = (int32_t) p_param->fps_number;
13205 framerate_denom = (int32_t) p_param->fps_denominator;
13206 }
13207
13208 min_maxFrameSize = ((uint32_t)bitrate / framerate_num * framerate_denom) / 8;
13209 maxFrameSize = min_maxFrameSize * maxFrameSizeRatio > NI_MAX_FRAME_SIZE ?
13210 NI_MAX_FRAME_SIZE : min_maxFrameSize * maxFrameSizeRatio;
13211 *((int32_t *)aux_data->data) = (int32_t)maxFrameSize;
13212 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13213 "xcoder_send_frame: frame #%lu reconf "
13214 "maxFrameSizeRatio %d maxFrameSize %d\n",
13215 p_enc_ctx->frame_num, maxFrameSizeRatio, maxFrameSize);
13216
13217 p_enc_ctx->reconfigCount++;
13218 }
13219 break;
13221 if (p_enc_ctx->frame_num ==
13222 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13223 aux_data = ni_frame_new_aux_data(
13224 p_frame, NI_FRAME_AUX_DATA_SLICE_ARG, sizeof(int16_t));
13225 if (!aux_data) {
13227 }
13228 *((int16_t *)aux_data->data) =
13229 (int16_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13230 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13231 "xcoder_send_frame: frame #%lu reconf "
13232 "sliceArg %d\n",
13233 p_enc_ctx->frame_num,
13234 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13235
13236 p_enc_ctx->reconfigCount++;
13237 }
13238 break;
13239 // force IDR frame through API test code
13241 if (p_enc_ctx->frame_num ==
13242 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13243 ni_force_idr_frame_type(p_enc_ctx);
13244 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13245 "xcoder_send_frame: frame #%lu force IDR frame\n",
13246 p_enc_ctx->frame_num);
13247
13248 p_enc_ctx->reconfigCount++;
13249 }
13250 break;
13251 // reconfig bit rate through API test code
13253 if (p_enc_ctx->frame_num ==
13254 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13255 retval = ni_reconfig_bitrate(
13256 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13257 if (retval){
13258 return retval;
13259 }
13260 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13261 "xcoder_send_frame: frame #%lu API reconfig BR %d\n",
13262 p_enc_ctx->frame_num,
13263 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13264
13265 p_enc_ctx->reconfigCount++;
13266 }
13267 break;
13269 if (p_enc_ctx->frame_num ==
13270 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13271 int32_t intraprd =
13272 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13273 retval = ni_reconfig_intraprd(p_enc_ctx, intraprd);
13274 if (retval){
13275 return retval;
13276 }
13278 "xcoder_send_frame: frame #%lu API reconfig intraPeriod %d\n",
13279 p_enc_ctx->frame_num,
13280 intraprd);
13281
13282 p_enc_ctx->reconfigCount++;
13283 }
13284 break;
13286 if (p_enc_ctx->frame_num ==
13287 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13288 ni_vui_hrd_t vui;
13289 vui.colorDescPresent =
13290 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13291 vui.colorPrimaries =
13292 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13293 vui.colorTrc =
13294 p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13295 vui.colorSpace =
13296 p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13297 vui.aspectRatioWidth =
13298 p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13299 vui.aspectRatioHeight =
13300 p_param->reconf_hash[p_enc_ctx->reconfigCount][6];
13301 vui.videoFullRange =
13302 p_param->reconf_hash[p_enc_ctx->reconfigCount][7];
13303 retval = ni_reconfig_vui(p_enc_ctx, &vui);
13304 if (retval){
13305 return retval;
13306 }
13307 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13308 "xcoder_send_frame: frame #%lu reconf "
13309 "vui colorDescPresent %d colorPrimaries %d "
13310 "colorTrc %d colorSpace %d aspectRatioWidth %d "
13311 "aspectRatioHeight %d videoFullRange %d\n",
13312 p_enc_ctx->frame_num, vui.colorDescPresent,
13313 vui.colorPrimaries, vui.colorTrc,
13316 p_enc_ctx->reconfigCount++;
13317 }
13318 break;
13320 if (p_enc_ctx->frame_num ==
13321 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13324 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13325 ltr.use_long_term_ref =
13326 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13327
13328 retval = ni_set_ltr(p_enc_ctx, &ltr);
13329 if (retval) {
13330 return retval;
13331 }
13332 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13333 "xcoder_send_frame(): frame #%lu API set LTR\n",
13334 p_enc_ctx->frame_num);
13335 p_enc_ctx->reconfigCount++;
13336 }
13337 break;
13340 if (p_enc_ctx->frame_num ==
13341 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13342 ni_rc_min_max_qp qp_info;
13343 qp_info.minQpI = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13344 qp_info.maxQpI = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13345 qp_info.maxDeltaQp = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13346 qp_info.minQpPB = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13347 qp_info.maxQpPB = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13348 retval = ni_reconfig_min_max_qp(p_enc_ctx, &qp_info);
13349 if (retval) {
13350 return retval;
13351 }
13352 ni_log2(p_enc_ctx, NI_LOG_DEBUG,
13353 "%s(): frame %d minQpI %d maxQpI %d maxDeltaQp %d minQpPB %d maxQpPB %d\n",
13354 __func__, p_enc_ctx->frame_num,
13355 qp_info.minQpI, qp_info.maxQpI, qp_info.maxDeltaQp, qp_info.minQpPB, qp_info.maxQpPB);
13356 p_enc_ctx->reconfigCount++;
13357 }
13358 break;
13360 if (p_enc_ctx->frame_num ==
13361 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13362 retval = ni_set_ltr_interval(
13363 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13364 if (retval) {
13365 return retval;
13366 }
13367 ni_log2(p_enc_ctx,
13369 "xcoder_send_frame(): frame #%lu API set LTR interval %d\n",
13370 p_enc_ctx->frame_num,
13371 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13372 p_enc_ctx->reconfigCount++;
13373 }
13374 break;
13376 if (p_enc_ctx->frame_num ==
13377 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13378 retval = ni_set_frame_ref_invalid(
13379 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13380 if (retval) {
13381 return retval;
13382 }
13383 ni_log2(p_enc_ctx,
13385 "xcoder_send_frame(): frame #%lu API set frame ref invalid "
13386 "%d\n",
13387 p_enc_ctx->frame_num,
13388 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13389 p_enc_ctx->reconfigCount++;
13390 }
13391 break;
13393 if (p_enc_ctx->frame_num ==
13394 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13395 ni_framerate_t framerate;
13396 framerate.framerate_num =
13397 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13398 framerate.framerate_denom =
13399 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13400 retval = ni_reconfig_framerate(p_enc_ctx, &framerate);
13401 if (retval) {
13402 return retval;
13403 }
13404 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13405 "xcoder_send_frame: frame #%lu API reconfig framerate "
13406 "(%d/%d)\n",
13407 p_enc_ctx->frame_num,
13408 p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13409 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13410
13411 p_enc_ctx->reconfigCount++;
13412 }
13413 break;
13415 if (p_enc_ctx->frame_num ==
13416 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13418 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13419 if (retval) {
13420 return retval;
13421 }
13422 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13423 "xcoder_send_frame: frame #%lu API reconfig maxFrameSize %d\n",
13424 p_enc_ctx->frame_num,
13425 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13426
13427 p_enc_ctx->reconfigCount++;
13428 }
13429 break;
13431 if (p_enc_ctx->frame_num ==
13432 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13433 retval = ni_reconfig_crf(
13434 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13435 if (retval) {
13436 return retval;
13437 }
13438 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13439 "xcoder_send_frame: frame #%lu API reconfig crf %d\n",
13440 p_enc_ctx->frame_num,
13441 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13442
13443 p_enc_ctx->reconfigCount++;
13444 }
13445 break;
13447 if (p_enc_ctx->frame_num ==
13448 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13449 float crf = (float)(p_param->reconf_hash[p_enc_ctx->reconfigCount][1] +
13450 (float)p_param->reconf_hash[p_enc_ctx->reconfigCount][2] / 100.0);
13451 retval = ni_reconfig_crf2(p_enc_ctx, crf);
13452 if (retval) {
13453 return retval;
13454 }
13455 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13456 "xcoder_send_frame: frame #%lu API reconfig crf %f\n",
13457 p_enc_ctx->frame_num, crf);
13458
13459 p_enc_ctx->reconfigCount++;
13460 }
13461 break;
13463 if (p_enc_ctx->frame_num ==
13464 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13465 retval = ni_reconfig_vbv_value(
13466 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13467 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13468 if (retval) {
13469 return retval;
13470 }
13471 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13472 "xcoder_send_frame: frame #%lu API reconfig vbvMaxRate %d vbvBufferSize %d\n",
13473 p_enc_ctx->frame_num,
13474 p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13475 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13476
13477 p_enc_ctx->reconfigCount++;
13478 }
13479 break;
13481 if (p_enc_ctx->frame_num ==
13482 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13483
13485 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13486 if (retval) {
13487 return retval;
13488 }
13489 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13490 "xcoder_send_frame: frame #%lu reconf maxFrameSizeRatio %d\n",
13491 p_enc_ctx->frame_num, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13492
13493 p_enc_ctx->reconfigCount++;
13494 }
13495 break;
13497 if (p_enc_ctx->frame_num ==
13498 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13499 retval = ni_reconfig_slice_arg(
13500 p_enc_ctx, (int16_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13501 if (retval) {
13502 return retval;
13503 }
13504 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13505 "xcoder_send_frame: frame #%lu API reconfig sliceArg %d\n",
13506 p_enc_ctx->frame_num,
13507 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13508
13509 p_enc_ctx->reconfigCount++;
13510 }
13511 break;
13512#endif
13514 default:
13515 ;
13516 }
13517 return NI_RETCODE_SUCCESS;
13518}
13519
13523static int ni_tolower(int c)
13524{
13525 if (c >= 'A' && c <= 'Z')
13526 c ^= 0x20;
13527 return c;
13528}
13529
13530int ni_strcasecmp(const char *a, const char *b)
13531{
13532 uint8_t c1, c2;
13533 do
13534 {
13535 c1 = ni_tolower(*a++);
13536 c2 = ni_tolower(*b++);
13537 } while (c1 && c1 == c2);
13538 return c1 - c2;
13539}
13540
13542{
13543 ni_encoder_cfg_params_t *p_enc = &p_param->cfg_enc_params;
13546 p_gop->pic_param[0].rps[0].ref_pic = 1;
13548 p_gop->pic_param[0].rps[0].ref_pic_used = 1;
13550 p_gop->pic_param[0].rps[1].ref_pic = 1;
13552 p_gop->pic_param[0].rps[1].ref_pic_used = 1;
13554 p_gop->pic_param[0].rps[2].ref_pic = 1;
13556 p_gop->pic_param[0].rps[2].ref_pic_used = 1;
13558 p_gop->pic_param[0].rps[3].ref_pic = 1;
13560 p_gop->pic_param[0].rps[3].ref_pic_used = 1;
13562 p_gop->pic_param[1].rps[0].ref_pic = 1;
13564 p_gop->pic_param[1].rps[0].ref_pic_used = 1;
13566 p_gop->pic_param[1].rps[1].ref_pic = 1;
13568 p_gop->pic_param[1].rps[1].ref_pic_used = 1;
13570 p_gop->pic_param[1].rps[2].ref_pic = 1;
13572 p_gop->pic_param[1].rps[2].ref_pic_used = 1;
13574 p_gop->pic_param[1].rps[3].ref_pic = 1;
13576 p_gop->pic_param[1].rps[3].ref_pic_used = 1;
13578 p_gop->pic_param[2].rps[0].ref_pic = 1;
13580 p_gop->pic_param[2].rps[0].ref_pic_used = 1;
13582 p_gop->pic_param[2].rps[1].ref_pic = 1;
13584 p_gop->pic_param[2].rps[1].ref_pic_used = 1;
13586 p_gop->pic_param[2].rps[2].ref_pic = 1;
13588 p_gop->pic_param[2].rps[2].ref_pic_used = 1;
13590 p_gop->pic_param[2].rps[3].ref_pic = 1;
13592 p_gop->pic_param[2].rps[3].ref_pic_used = 1;
13594 p_gop->pic_param[3].rps[0].ref_pic = 1;
13596 p_gop->pic_param[3].rps[0].ref_pic_used = 1;
13598 p_gop->pic_param[3].rps[1].ref_pic = 1;
13600 p_gop->pic_param[3].rps[1].ref_pic_used = 1;
13602 p_gop->pic_param[3].rps[2].ref_pic = 1;
13604 p_gop->pic_param[3].rps[2].ref_pic_used = 1;
13606 p_gop->pic_param[3].rps[3].ref_pic = 1;
13608 p_gop->pic_param[3].rps[3].ref_pic_used = 1;
13610 p_gop->pic_param[4].rps[0].ref_pic = 1;
13612 p_gop->pic_param[4].rps[0].ref_pic_used = 1;
13614 p_gop->pic_param[4].rps[1].ref_pic = 1;
13616 p_gop->pic_param[4].rps[1].ref_pic_used = 1;
13618 p_gop->pic_param[4].rps[2].ref_pic = 1;
13620 p_gop->pic_param[4].rps[2].ref_pic_used = 1;
13622 p_gop->pic_param[4].rps[3].ref_pic = 1;
13624 p_gop->pic_param[4].rps[3].ref_pic_used = 1;
13626 p_gop->pic_param[5].rps[0].ref_pic = 1;
13628 p_gop->pic_param[5].rps[0].ref_pic_used = 1;
13630 p_gop->pic_param[5].rps[1].ref_pic = 1;
13632 p_gop->pic_param[5].rps[1].ref_pic_used = 1;
13634 p_gop->pic_param[5].rps[2].ref_pic = 1;
13636 p_gop->pic_param[5].rps[2].ref_pic_used = 1;
13638 p_gop->pic_param[5].rps[3].ref_pic = 1;
13640 p_gop->pic_param[5].rps[3].ref_pic_used = 1;
13642 p_gop->pic_param[6].rps[0].ref_pic = 1;
13644 p_gop->pic_param[6].rps[0].ref_pic_used = 1;
13646 p_gop->pic_param[6].rps[1].ref_pic = 1;
13648 p_gop->pic_param[6].rps[1].ref_pic_used = 1;
13650 p_gop->pic_param[6].rps[2].ref_pic = 1;
13652 p_gop->pic_param[6].rps[2].ref_pic_used = 1;
13654 p_gop->pic_param[6].rps[3].ref_pic = 1;
13656 p_gop->pic_param[6].rps[3].ref_pic_used = 1;
13658 p_gop->pic_param[7].rps[0].ref_pic = 1;
13660 p_gop->pic_param[7].rps[0].ref_pic_used = 1;
13662 p_gop->pic_param[7].rps[1].ref_pic = 1;
13664 p_gop->pic_param[7].rps[1].ref_pic_used = 1;
13666 p_gop->pic_param[7].rps[2].ref_pic = 1;
13668 p_gop->pic_param[7].rps[2].ref_pic_used = 1;
13670 p_gop->pic_param[7].rps[3].ref_pic = 1;
13672 p_gop->pic_param[7].rps[3].ref_pic_used = 1;
13673
13674}
13675
13677{
13678 ni_encoder_cfg_params_t *p_enc = &p_param->cfg_enc_params;
13680 int i, j;
13681 for (i=0; i<NI_MAX_GOP_NUM; i++)
13682 {
13683 for (j=0; j<NI_MAX_REF_PIC; j++)
13684 {
13685 if (p_gop->pic_param[i].rps[j].ref_pic == 1 &&
13686 p_gop->pic_param[i].rps[j].ref_pic_used != 1)
13687 {
13689 "g%drefPic%d specified without g%drefPic%dUsed specified!\n",
13690 i, j, i, j);
13691 return false;
13692 }
13693 }
13694 }
13695 // set custom_gop_params default.
13696 for (i=0; i<NI_MAX_GOP_NUM; i++)
13697 {
13698 for (j=0; j<NI_MAX_REF_PIC; j++)
13699 {
13700 p_gop->pic_param[i].rps[j].ref_pic = 0;
13701 p_gop->pic_param[i].rps[j].ref_pic_used = 0;
13702 }
13703 }
13704 return true;
13705}
13706
13707#ifndef DEPRECATION_AS_ERROR
13708/*!*****************************************************************************
13709 * \brief Initiate P2P transfer (P2P write) (deprecated)
13710 *
13711 * \param[in] pSession Pointer to source card destination
13712 * \param[in] source Pointer to source frame to transmit
13713 * \param[in] ui64DestAddr Destination address on target device
13714 * \param[in] ui32FrameSize Size of frame to transfer
13715 *
13716 * \return always returns
13717 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13718*******************************************************************************/
13720 niFrameSurface1_t *source,
13721 uint64_t ui64DestAddr,
13722 uint32_t ui32FrameSize)
13723{
13724 // avoid compiler warnings
13725 (void) pSession;
13726 (void) source;
13727 (void) ui64DestAddr;
13728 (void) ui32FrameSize;
13729
13731}
13732#endif
13733
13734#ifndef DEPRECATION_AS_ERROR
13735/*!*****************************************************************************
13736 * \brief Initiate P2P transfer (P2P write) (deprecated)
13737 *
13738 * \param[in] pSession Pointer to source card destination
13739 * \param[in] source Pointer to source frame to transmit
13740 * \param[in] ui64DestAddr Destination address on target device
13741 * \param[in] ui32FrameSize Size of frame to transfer
13742 *
13743 * \return always returns
13744 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13745*******************************************************************************/
13747 niFrameSurface1_t *source,
13748 uint64_t ui64DestAddr, uint32_t ui32FrameSize)
13749{
13750 // avoid compiler warnings
13751 (void) pSession;
13752 (void) source;
13753 (void) ui64DestAddr;
13754 (void) ui32FrameSize;
13755
13757}
13758#endif
13759
13760/*!*****************************************************************************
13761 * \brief Initiate P2P transfer with sgl list (P2P write)
13762 *
13763 * \param[in] pSession Pointer to source card session
13764 * \param[in] source Pointer to source P2P frame
13765 * \param[in] dmaAddrs Destination DMA address on target device
13766 *
13767 * \return on success
13768 * NI_RETCODE_SUCCESS
13769 * on failure
13770 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13771 * NI_RETCODE_INVALID_PARAM
13772 * NI_RETCODE_ERROR_INVALID_SESSION
13773 * NI_RETCODE_ERROR_MEM_ALOC
13774 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13775*******************************************************************************/
13777 ni_frame_t *pSrcFrame,
13778 const ni_p2p_sgl_t *dmaAddrs)
13779{
13781
13782 if ((pSession == NULL) || (dmaAddrs == NULL) || (pSrcFrame == NULL))
13783 {
13785 }
13786
13787 /* Firmware compatibility check */
13788 if (ni_cmp_fw_api_ver((char *) &pSession->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sX") < 0)
13789 {
13790 ni_log2(pSession, NI_LOG_ERROR,
13791 "%s: FW doesn't support this operation\n", __func__);
13793 }
13794
13795 retval = ni_send_to_target_v2(pSession, pSrcFrame, dmaAddrs);
13796 if (retval < 0)
13797 {
13798 ni_log2(pSession, NI_LOG_ERROR, "%s(): Can't DMA to destination (%d)\n", __func__, retval);
13799 }
13800
13801 return retval;
13802}
13803
13804/*!*****************************************************************************
13805 * \brief Initiate a P2P transfer (P2P read)
13806 *
13807 * \param[in] pSession Pointer to destination upload session
13808 * \param[in] dmaAddrs Pointer to source DMA addresses
13809 * \param[in] pDstFrame Pointer to destination P2P frame
13810 *
13811 * \return on success
13812 * NI_RETCODE_SUCCESS
13813 * on failure
13814 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13815 * NI_RETCODE_INVALID_PARAM
13816 * NI_RETCODE_ERROR_INVALID_SESSION
13817 * NI_RETCODE_ERROR_MEM_ALOC
13818 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13819*******************************************************************************/
13821 const ni_p2p_sgl_t *dmaAddrs,
13822 ni_frame_t *pDstFrame)
13823{
13825
13826 if ((pSession == NULL) || (dmaAddrs == NULL) || (pDstFrame == NULL))
13827 {
13829 }
13830
13831 /* Firmware compatibility check */
13832 if (ni_cmp_fw_api_ver((char *) &pSession->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6re") < 0)
13833 {
13834 ni_log2(pSession, NI_LOG_ERROR,
13835 "%s: FW doesn't support this operation\n", __func__);
13837 }
13838
13839 retval = ni_recv_from_target(pSession, dmaAddrs, pDstFrame);
13840
13841 if (retval < 0)
13842 {
13843 ni_log2(pSession, NI_LOG_ERROR,
13844 "%s(): Can't DMA from source (%d)\n", __func__, retval);
13845 retval = NI_RETCODE_INVALID_PARAM;
13846 }
13847
13848 return retval;
13849}
13850
13851/*!*****************************************************************************
13852 * \brief Send a restart command after flush command
13853 * Only support Encoder now
13854 *
13855 * \param[in] p_ctx Pointer to a caller allocated
13856 * ni_session_context_t struct
13857 * \param[in] width width, in pixels
13858 * \param[in] height height, in pixels
13859 * \param[in] device_type NI_DEVICE_TYPE_ENCODER
13860 * \return On success
13861 * NI_RETCODE_SUCCESS
13862 * On failure
13863 * NI_RETCODE_INVALID_PARAM
13864 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13865 * NI_RETCODE_ERROR_INVALID_SESSION
13866 ******************************************************************************/
13868 int video_width,
13869 int video_height,
13870 ni_device_type_t device_type)
13871{
13872 ni_retcode_t retval = 0;
13873 ni_resolution_t resolution;
13874 ni_xcoder_params_t *p_param = NULL;
13875
13876 if (!p_ctx)
13877 {
13878 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
13879 __func__);
13881 }
13882
13883 switch (device_type)
13884 {
13886 {
13887 // requires API version >= 54
13889 "54") < 0)
13890 {
13891 ni_log2(p_ctx, NI_LOG_ERROR, "Error: %s function not supported on device with FW API version < 5.4\n", __func__);
13893 }
13894
13895 /* This function should be called only if flushing is detected */
13897 {
13898 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() wrong state %d\n",
13899 __func__, p_ctx->session_run_state);
13901 }
13902
13903 if (video_width < NI_MIN_WIDTH || video_width > NI_MAX_WIDTH ||
13904 video_height < NI_MIN_HEIGHT || video_height > NI_MAX_HEIGHT)
13905 {
13906 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() invalid width %d or height %d\n",
13907 __func__, video_width, video_height);
13909 }
13910 resolution.width = video_width;
13911 resolution.height = video_height;
13912 resolution.bit_depth_factor = p_ctx->bit_depth_factor;
13913 resolution.luma_linesize = 0;
13914 resolution.chroma_linesize = 0;
13915 if (p_ctx->p_session_config)
13916 {
13917 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
13918 resolution.luma_linesize = p_param->luma_linesize;
13919 resolution.chroma_linesize = p_param->chroma_linesize;
13920 }
13922
13923 // reconfig the encoder session
13924 retval = ni_encoder_session_sequence_change(p_ctx, &resolution);
13925 if (NI_RETCODE_SUCCESS != retval)
13926 {
13927 ni_log(NI_LOG_ERROR, "Failed to reconfig config the encoder session (status = %d)\n", retval);
13929 return retval;
13930 }
13931
13932 // update session context
13933 p_ctx->ready_to_close = 0;
13934 p_ctx->frame_num = 0;
13935 p_ctx->pkt_num = 0;
13937 break;
13938 }
13939 default:
13940 {
13941 retval = NI_RETCODE_INVALID_PARAM;
13942 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unsupported device type: %d",
13943 __func__, device_type);
13944 break;
13945 }
13946 }
13947 return retval;
13948}
13949
13950/*!******************************************************************************
13951* \brief Send a p_config command to reconfigure decoding ppu params.
13952*
13953* \param ni_session_context_t p_session_ctx - xcoder Context
13954* \param ni_xcoder_params_t p_param - xcoder Params
13955* \param ni_ppu_config_t p_ppu_config - Struct ni_ppu_config
13956*
13957* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
13958*******************************************************************************/
13960 ni_xcoder_params_t *p_param, ni_ppu_config_t *p_ppu_config)
13961{
13962 int ret = 0, i = 0;
13963 if (!p_session_ctx || !p_param || !p_ppu_config)
13964 {
13966 return ret;
13967 }
13968 if (p_session_ctx->ppu_reconfig_pkt_pos != 0)
13969 {
13970 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: Warning ignore ppu reconfig before last config done!\n", __func__);
13971 return 0;
13972 }
13973
13974 // check fw revision
13976 (char*) &p_session_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
13977 "6sF") < 0)
13978 {
13979 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: not supported on device with FW API version < 6sF\n", __func__);
13981 }
13982
13983 if (NI_CODEC_FORMAT_H264 != p_session_ctx->codec_format &&
13984 NI_CODEC_FORMAT_H265 != p_session_ctx->codec_format)
13985 {
13986 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): only supported for h264 and h265 decoder\n", __func__);
13988 }
13989
13990 ni_decoder_input_params_t *p_dec_input_param = &(p_param->dec_input_params);
13991 if (p_dec_input_param->hwframes != 1)
13992 {
13993 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): only supported for hw mode\n", __func__);
13995 }
13996 if (!p_dec_input_param->disable_adaptive_buffers)
13997 {
13998 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): not supported when disable_adaptive_buffers is disabled\n", __func__);
14000 }
14001 if (p_dec_input_param->mcmode)
14002 {
14003 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): not supported when MulticoreJointMode is enabled\n", __func__);
14005 }
14006 if (p_dec_input_param->enable_out1 == 0 &&
14007 p_ppu_config->ppu_set_enable & (0x01 << 1))
14008 {
14009 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Error reconfig ppu1 while ppu1 is not enabled\n", __func__);
14011 }
14012 if (p_dec_input_param->enable_out2 == 0 &&
14013 p_ppu_config->ppu_set_enable & (0x01 << 2))
14014 {
14015 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Error reconfig ppu2 while ppu2 is not enabled\n", __func__);
14017 }
14018 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
14019 {
14020 if (p_ppu_config->ppu_set_enable & (0x01 << i))
14021 {
14022 if (p_ppu_config->ppu_w[i] > NI_MAX_RESOLUTION_WIDTH ||
14023 p_ppu_config->ppu_h[i] > NI_MAX_RESOLUTION_HEIGHT ||
14024 p_ppu_config->ppu_w[i] < NI_MIN_RESOLUTION_WIDTH_SCALER ||
14025 p_ppu_config->ppu_h[i] < NI_MIN_RESOLUTION_WIDTH_SCALER)
14026 {
14027 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu[%d] width x height %ux%u "
14028 "out of range\n", __func__, i, p_ppu_config->ppu_w[i], p_ppu_config->ppu_h[i]);
14030 return ret;
14031 }
14032 if ((p_ppu_config->ppu_w[i] & 1) || (p_ppu_config->ppu_h[i] & 1))
14033 {
14034 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu[%d] wxh %dx%d not align to 2!\n",
14035 __func__, i, p_ppu_config->ppu_w[i], p_ppu_config->ppu_h[i]);
14037 return ret;
14038 }
14039 }
14040 }
14042 p_session_ctx, p_ppu_config, sizeof(ni_ppu_config_t));
14043 if (ret == NI_RETCODE_SUCCESS)
14044 {
14045 p_session_ctx->ppu_reconfig_pkt_pos = p_session_ctx->pkt_num;
14046 }
14047 return ret;
14048}
14049
14050float ni_bicubic_coeff_default(int filtersize, double offset, double B, double C)
14051{
14052 double t = offset < 0 ? -offset : offset;
14053 (void)filtersize;
14054 double tt = t * t;
14055
14056 if (t < 0)
14057 t = -t;
14058
14059 if (t < 1.0)
14060 {
14061 t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt))
14062 + ((-18.0 + 12.0 * B + 6.0 * C) * tt)
14063 + (6.0 - 2 * B));
14064 return (float)(t / 6.0);
14065 }
14066 else if (t < 2.0)
14067 {
14068 t = (((-1.0 * B - 6.0 * C) * (t * tt))
14069 + ((6.0 * B + 30.0 * C) * tt)
14070 + ((-12.0 * B - 48.0 * C) * t)
14071 + (8.0 * B + 24 * C));
14072 return (float)(t / 6.0);
14073 }
14074 return 0.0f;
14075}
14076
14078{
14079 if (!p_session_ctx)
14080 {
14082 }
14083 p_session_ctx->scaler_coeff_fn = fn ? fn : ni_bicubic_coeff_default;
14084 return NI_RETCODE_SUCCESS;
14085}
14086
14088 uint16_t kernel_array[], int kernel_taps, double param_b,
14089 double param_c, int SrcSize, int DstSize)
14090{
14091 int padding;
14092 int kernelHalf;
14093 float fSubpixelStep;
14094 int subpixelPos;
14095 int kernelPos;
14096 float fSubpixelOffset;
14097
14098 if (!p_session_ctx)
14099 {
14101 }
14102
14103 if (!p_session_ctx->scaler_coeff_fn)
14104 {
14106 "ni_scaler_build_kernel: scaler_coeff_fn is NULL\n");
14108 }
14109
14110 if (kernel_taps < 1 || kernel_taps > NI_SCALER_MAX_KERNEL_TAPS) {
14112 "ni_scaler_build_kernel: kernel_taps=%d out of range [1, %d]\n",
14113 kernel_taps, NI_SCALER_MAX_KERNEL_TAPS);
14115 }
14116
14117 (void)SrcSize;
14118 (void)DstSize;
14119
14120 /* Zero the horizontal table — left/right padding slots remain 0 */
14121 memset(kernel_array, 0,
14122 (size_t)NI_SCALER_KERNEL_POSITIONS * NI_SCALER_KERNEL_SLOTS * sizeof(uint16_t));
14123
14124 padding = (NI_SCALER_KERNEL_SLOTS - kernel_taps) / 2;
14125 kernelHalf = kernel_taps >> 1;
14126
14127 /* Calculate the subpixel step. */
14128 fSubpixelStep = (float)(1.0f / 32.0f);
14129 /* Init the subpixel offset. */
14130 fSubpixelOffset = 0.5f;
14131
14132 for (subpixelPos = 0; subpixelPos < NI_SCALER_KERNEL_POSITIONS; subpixelPos++) {
14133 float fSubpixelSet[9] = {0.0f};
14134 int offset = subpixelPos * NI_SCALER_KERNEL_SLOTS;
14135 /* Init the sum of all weights for the current subpixel. */
14136 float fWeightSum = 0.0f;
14137 uint16_t weightSum = 0;
14138 int16_t adjustCount, adjustFrom;
14139 int16_t adjustment;
14140 int16_t overCnt=0;
14141 int16_t underCnt=0;
14142
14143 for (kernelPos = 0; kernelPos < NI_SCALER_KERNEL_SLOTS; kernelPos++) {
14144 int index = kernelPos - padding;
14145 /* Pad with zeros. */
14146 if ((index < 0) || (index >= kernel_taps))
14147 {
14148 fSubpixelSet[kernelPos] = 0.0f;
14149 }
14150 else
14151 {
14152 float fX = ((float)(index - kernelHalf ) + fSubpixelOffset);
14153 fSubpixelSet[kernelPos] =
14154 (float)p_session_ctx->scaler_coeff_fn(
14155 kernel_taps, (float)fX, param_b, param_c);
14156 }
14157 /* Update the sum of weights. */
14158 fWeightSum = fWeightSum + fSubpixelSet[kernelPos];
14159 }
14160 /* Adjust weights so that the sum will be 1.0. */
14161 for (kernelPos = 0; kernelPos < NI_SCALER_KERNEL_SLOTS; kernelPos++)
14162 {
14163 /* Normalize the current weight. */
14164 float fWeight = fSubpixelSet[kernelPos] / fWeightSum;
14165
14166 /* Convert the weight to fixed point and store in the table. */
14167 if (fWeight == 0.0f)
14168 {
14169 kernel_array[kernelPos + offset] = 0x0000;
14170 }
14171 else if (fWeight >= 1.0f)
14172 {
14173 kernel_array[kernelPos + offset] = 0x4000;
14174 overCnt++;
14175 }
14176 else if (fWeight <= -1.0f)
14177 {
14178 kernel_array[kernelPos + offset] = 0xC000;
14179 underCnt++;
14180 }
14181 else
14182 {
14183 kernel_array[kernelPos + offset] = (int16_t) (fWeight * 16384.0f);
14184 }
14185
14186 weightSum += kernel_array[kernelPos + offset];
14187 }
14188
14189 /* Adjust the fixed point coefficients. */
14190 adjustCount = (int16_t)(0x4000 - weightSum);
14191 if (adjustCount < 0)
14192 {
14193 adjustCount = (int16_t)(-adjustCount);
14194 adjustment = -1;
14195 }
14196 else
14197 {
14198 adjustment = 1;
14199 }
14200
14201 if (adjustCount < kernel_taps)
14202 {
14203 adjustFrom = (int16_t)((NI_SCALER_KERNEL_SLOTS - adjustCount) / 2);
14204 for (kernelPos = 0; kernelPos < adjustCount; kernelPos++)
14205 {
14206 kernel_array[adjustFrom + kernelPos + offset] += adjustment;
14207 }
14208 }
14209 else
14210 {
14211 adjustFrom = (int16_t)((NI_SCALER_KERNEL_SLOTS - kernel_taps) / 2);
14212 adjustment = (int16_t)((0x4000 - weightSum) / (kernel_taps - overCnt - underCnt));
14213 weightSum = 0;
14214 for (kernelPos = 0; kernelPos < kernel_taps; kernelPos++)
14215 {
14216 if (kernel_array[adjustFrom+kernelPos + offset] != 0x4000 &&
14217 kernel_array[adjustFrom+kernelPos + offset] != 0xC000)
14218 {
14219 kernel_array[adjustFrom + kernelPos + offset] += adjustment;
14220 }
14221 weightSum += kernel_array[adjustFrom + kernelPos + offset];
14222 }
14223 }
14224 /* Advance to the next subpixel. */
14225 fSubpixelOffset = fSubpixelOffset - fSubpixelStep;
14226 }
14227 return NI_RETCODE_SUCCESS;
14228}
#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:598
@ NI_SCALER_OPCODE_WATERMARK
Definition ni_defs.h:603
#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:447
@ NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
Definition ni_defs.h:528
@ NI_RETCODE_PARAM_WARNING_DEPRECATED
Definition ni_defs.h:537
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_BIG
Definition ni_defs.h:519
@ NI_RETCODE_PARAM_ERROR_ZERO
Definition ni_defs.h:513
@ NI_RETCODE_FAILURE
Definition ni_defs.h:449
@ NI_RETCODE_ERROR_PERMISSION_DENIED
Definition ni_defs.h:544
@ NI_RETCODE_ERROR_INVALID_SESSION
Definition ni_defs.h:454
@ NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
Definition ni_defs.h:542
@ NI_RETCODE_ERROR_GET_DEVICE_POOL
Definition ni_defs.h:527
@ NI_RETCODE_ERROR_UNLOCK_DEVICE
Definition ni_defs.h:530
@ NI_RETCODE_PARAM_INVALID_NAME
Definition ni_defs.h:457
@ NI_RETCODE_PARAM_ERROR_AREA_TOO_BIG
Definition ni_defs.h:523
@ NI_RETCODE_SUCCESS
Definition ni_defs.h:448
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_SMALL
Definition ni_defs.h:521
@ NI_RETCODE_ERROR_INVALID_HANDLE
Definition ni_defs.h:532
@ NI_RETCODE_PARAM_ERROR_TOO_BIG
Definition ni_defs.h:510
@ NI_RETCODE_PARAM_INVALID_VALUE
Definition ni_defs.h:458
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_BIG
Definition ni_defs.h:515
@ NI_RETCODE_ERROR_NVME_CMD_FAILED
Definition ni_defs.h:453
@ NI_RETCODE_ERROR_MEM_ALOC
Definition ni_defs.h:452
@ NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
Definition ni_defs.h:543
@ NI_RETCODE_PARAM_ERROR_OOR
Definition ni_defs.h:514
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_SMALL
Definition ni_defs.h:517
@ NI_RETCODE_INVALID_PARAM
Definition ni_defs.h:450
@ NI_RETCODE_PARAM_ERROR_TOO_SMALL
Definition ni_defs.h:511
@ NI_RETCODE_ERROR_OPEN_DEVICE
Definition ni_defs.h:531
#define NI_MAX_PPU_PARAM_EXPR_CHAR
Definition ni_defs.h:259
#define IS_XCODER_DEVICE_TYPE(t)
Definition ni_defs.h:431
#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.
float ni_bicubic_coeff_default(int filtersize, double offset, double B, double C)
#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_kernel_set_callback(ni_session_context_t *p_session_ctx, ni_kernel_coeff_fn fn)
Replace the kernel coefficient callback.
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_alloc_and_get_fw_log_artifacts(ni_session_context_t *p_ctx, bool gen_artifacts_file)
Read log artifacts from the device and save to disk.
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.
ni_retcode_t ni_scaler_build_kernel(ni_session_context_t *p_session_ctx, uint16_t kernel_array[], int kernel_taps, double param_b, double param_c, int SrcSize, int DstSize)
Build scaler kernal array.
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_DEC_PARAM_DECODER_MODE
#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 MOTION_CONSTRAINED_MODE_MAX
#define NI_ENC_PARAM_MAX_CONSUTIVE_SKIP_FRAME_NUMBER
#define NI_ENC_GOP_PARAMS_G7_POC_OFFSET
#define NI_DEC_PARAM_EXTEND_POOL_SIZE
#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
float(* ni_kernel_coeff_fn)(int filtersize, double offset, double B, double C)
#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_SCALER_KERNEL_SLOTS
#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_SCALER_FLAG_CS
#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
#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_ENC_PARAM_USE_MCTF
#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
#define NI_SCALER_MAX_KERNEL_TAPS
@ 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_SCALER_KERNEL_POSITIONS
#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_DEC_MODE_INTRA_ONLY
#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_DEC_MODE_NORMAL
#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_dump_log_artifacts(ni_session_context_t *p_ctx, bool gen_artifacts_file)
Read log artifacts (tar.gz) from the device via NVMe and write them to "artifacts_slot_s_dddd....
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:661
Private definitions for interfacing with NETINT video processing devices over NVMe.
#define QUERY_GET_NVME_STATUS_R
Definition ni_nvme.h:795
#define QUERY_GET_EXTTRA_INFO_R
Definition ni_nvme.h:804
#define QUERY_GET_QOS_INFO_R
Definition ni_nvme.h:806
#define CONFIG_INSTANCE_SetScalerDrawBoxPara_W(sid, instance)
Definition ni_nvme.h:834
#define QUERY_GET_NS_VF_R
Definition ni_nvme.h:800
#define QUERY_GET_TEMPERATURE_R
Definition ni_nvme.h:802
#define IDENTIFY_DEVICE_R
Definition ni_nvme.h:692
#define QUERY_GET_VERSIONS_R
Definition ni_nvme.h:797
#define NI_DATA_BUFFER_LEN
Definition ni_nvme.h:627
#define NI_NVME_IDENTITY_CMD_DATA_SZ
Definition ni_nvme.h:38
#define CONFIG_INSTANCE_SetScalerWatermarkPara_W(sid, instance)
Definition ni_nvme.h:840
#define QUERY_GET_QOS_NS_INFO_R
Definition ni_nvme.h:808
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:4888
int ni_pthread_mutex_lock(ni_pthread_mutex_t *mutex)
thread mutex lock
Definition ni_util.c:4768
int ni_pthread_cond_destroy(ni_pthread_cond_t *cond)
destroy condition variables
Definition ni_util.c:4907
int32_t ni_parse_name(const char *arg, const char *const *names, bool *b_error)
Parse name.
Definition ni_util.c:2673
ni_retcode_t ni_strncpy(char *dest, size_t dmax, const char *src, size_t slen)
Definition ni_util.c:525
int ni_posix_memalign(void **memptr, size_t alignment, size_t size)
Allocate aligned memory.
Definition ni_util.c:206
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:4832
ni_retcode_t ni_strncat(char *dest, size_t dmax, const char *src, size_t slen)
Definition ni_util.c:822
ni_buf_t * ni_buf_pool_get_buffer(ni_buf_pool_t *p_buffer_pool)
Definition ni_util.c:1105
ni_retcode_t ni_strerror(char *dest, size_t dmax, int errnum)
Definition ni_util.c:663
int ni_pthread_mutex_destroy(ni_pthread_mutex_t *mutex)
destory a mutex
Definition ni_util.c:4750
ni_retcode_t ni_strcat(char *dest, size_t dmax, const char *src)
Definition ni_util.c:704
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:2743
char * ni_strtok(char *s, const char *delim, char **saveptr)
Definition ni_util.c:429
ni_retcode_t ni_fopen(FILE **fp, const char *filename, const char *mode)
Definition ni_util.c:998
ni_retcode_t ni_strcpy(char *dest, size_t dmax, const char *src)
Definition ni_util.c:460
uint32_t ni_ai_network_layer_size(ni_network_layer_params_t *p_param)
Definition ni_util.c:4070
void ni_usleep(int64_t usec)
Definition ni_util.c:366
void ni_buf_pool_return_buffer(ni_buf_t *buf, ni_buf_pool_t *p_buffer_pool)
Definition ni_util.c:1166
uint64_t ni_gettime_ns(void)
Definition ni_util.c:2701
int ni_pthread_join(ni_pthread_t thread, void **value_ptr)
join with a terminated thread
Definition ni_util.c:4859
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:2795
int ni_pthread_mutex_unlock(ni_pthread_mutex_t *mutex)
thread mutex unlock
Definition ni_util.c:4794
int ni_sprintf(char *dest, size_t dmax, const char *fmt,...)
Definition ni_util.c:1077
int ni_pthread_mutex_init(ni_pthread_mutex_t *mutex)
initialize a mutex
Definition ni_util.c:4712
ni_retcode_t ni_strtoi(const char *str, int32_t *out_val)
Safely convert a decimal string to a 32-bit integer with full validation. Trailing whitespace is tole...
Definition ni_util.c:2577
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:5095
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:4383
Utility definitions.
#define NI_INVALID_POWER
Definition ni_util.h:44
#define ni_aligned_free(p_memptr)
Definition ni_util.h:402
#define ni_memfree(p_memptr)
Definition ni_util.h:412
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_kernel_coeff_fn scaler_coeff_fn
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