libxcoder 5.9.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#ifdef __linux__
217 pthread_condattr_t cond_attr;
218 if (pthread_condattr_init(&cond_attr))
219 {
220 ni_log2(p_ctx, NI_LOG_ERROR,
221 "ERROR %s(): pthread_condattr_init fail return\n",
222 __func__);
223 return NI_RETCODE_FAILURE;
224 }
225
226 if (pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC))
227 {
228 ni_log2(p_ctx, NI_LOG_ERROR,
229 "ERROR %s(): pthread_condattr_setclock fail return\n",
230 __func__);
231 pthread_condattr_destroy(&cond_attr);
232 return NI_RETCODE_FAILURE;
233 }
234
235 if (ni_pthread_cond_init(&p_ctx->low_delay_sync_cond, &cond_attr))
236 {
237 ni_log2(p_ctx, NI_LOG_ERROR,
238 "ERROR %s(): init xcoder_low_delay_sync_cond fail return\n",
239 __func__);
240 pthread_condattr_destroy(&cond_attr);
241 return NI_RETCODE_FAILURE;
242 }
243
244 pthread_condattr_destroy(&cond_attr);
245#else
246 if (ni_pthread_cond_init(&p_ctx->low_delay_sync_cond, NULL))
247 {
248 ni_log2(p_ctx, NI_LOG_ERROR,
249 "ERROR %s(): init xcoder_low_delay_sync_cond fail return\n",
250 __func__);
251 return NI_RETCODE_FAILURE;
252 }
253#endif
254
255 p_ctx->mutex_initialized = true;
256
257 // Init the max IO size to be invalid
261 p_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
262 p_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
263 p_ctx->hw_id = NI_INVALID_HWID;
264 p_ctx->event_handle = NI_INVALID_EVENT_HANDLE;
265 p_ctx->thread_event_handle = NI_INVALID_EVENT_HANDLE;
267 p_ctx->keep_alive_thread = (ni_pthread_t){0};
269 p_ctx->decoder_low_delay = 0;
270 p_ctx->enable_low_delay_check = 0;
271 p_ctx->low_delay_sync_flag = 0;
272 p_ctx->async_mode = 0;
274 p_ctx->buffered_frame_index = 0;
275 p_ctx->ppu_reconfig_pkt_pos = 0;
276 p_ctx->headers_length = 0;
277 // by default, select the least model load card
280#ifdef MY_SAVE
281 p_ctx->debug_write_ptr = NULL;
282 p_ctx->debug_write_index_ptr = NULL;
283 p_ctx->debug_write_sent_size = 0;
284#endif
285
286#ifdef MEASURE_LATENCY
287 p_ctx->frame_time_q = (void *)ni_lat_meas_q_create(2000);
288#endif
289
290 return NI_RETCODE_SUCCESS;
291}
292
293/*!*****************************************************************************
294 * \brief Clear already allocated session context
295 *
296 * \param[in] p_ctx Pointer to an already allocated ni_session_context_t
297 *
298 *
299 ******************************************************************************/
310
311/*!*****************************************************************************
312 * \brief Create event and return event handle if successful (Windows only)
313 *
314 * \return On success returns a event handle
315 * On failure returns NI_INVALID_EVENT_HANDLE
316 ******************************************************************************/
317ni_event_handle_t ni_create_event(void)
318{
319#ifdef _WIN32
320 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
321
322 // Input-0 determines whether the returned handle can be inherited by the child process.If lpEventAttributes is NULL, this handle cannot be inherited.
323 // 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.
324 // Input-2 specifies the initial state of the event object.If TRUE, the initial state is signaled;Otherwise, no signal state.
325 // Input-3 If the lpName is NULL, a nameless event object is created.。
326 event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
327 if (event_handle == NULL)
328 {
329 ni_log(NI_LOG_ERROR, "ERROR %d: %s() create event failed\n",
330 NI_ERRNO, __func__);
331 return NI_INVALID_EVENT_HANDLE;
332 }
333 return event_handle;
334#else
335 return NI_INVALID_EVENT_HANDLE;
336#endif
337}
338
339/*!*****************************************************************************
340 * \brief Close event and release resources (Windows only)
341 *
342 * \return NONE
343 *
344 ******************************************************************************/
345void ni_close_event(ni_event_handle_t event_handle)
346{
347 if ( NI_INVALID_DEVICE_HANDLE == event_handle )
348 {
349 ni_log(NI_LOG_DEBUG, "Warning %s: null parameter passed %x\n", __func__,
350 event_handle);
351 return;
352 }
353
354 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
355
356#ifdef _WIN32
357 BOOL retval;
358 ni_log(NI_LOG_DEBUG, "%s(): closing %p\n", __func__, event_handle);
359
360 retval = CloseHandle(event_handle);
361 if (FALSE == retval)
362 {
363 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): closing event_handle %p failed\n",
364 NI_ERRNO, __func__, event_handle);
365 }
366 else
367 {
368 ni_log(NI_LOG_DEBUG, "%s(): device %p closed successfuly\n", __func__,
369 event_handle);
370 }
371#else
372 int err = 0;
373 ni_log(NI_LOG_DEBUG, "%s(): closing %d\n", __func__, event_handle);
374 err = close(event_handle);
375 if (err)
376 {
377 char error_message[100] = {'\0'};
378 char unknown_error_message[20] = {'\0'};
379 ni_sprintf(error_message, 100, "ERROR: %s(): ", __func__);
380 switch (err)
381 {
382 case EBADF:
383 ni_strcat(error_message, 100, "EBADF\n");
384 break;
385 case EINTR:
386 ni_strcat(error_message, 100, "EINTR\n");
387 break;
388 case EIO:
389 ni_strcat(error_message, 100, "EIO\n");
390 break;
391 default:
392 ni_sprintf(unknown_error_message, 20, "Unknown error %d\n", err);
393 ni_strcat(error_message, 100, unknown_error_message);
394 }
395 ni_log(NI_LOG_ERROR, "%s\n", error_message);
396 }
397#endif
398 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
399}
400
401#ifndef DEPRECATION_AS_ERROR
402/*!*****************************************************************************
403 * \brief Open device and return device device_handle if successful
404 *
405 * \param[in] p_dev Device name represented as c string. ex: "/dev/nvme0"
406 * \param[out] p_max_io_size_out Maximum IO Transfer size supported, could be
407 * NULL
408 *
409 * \return On success returns a device device_handle
410 * On failure returns NI_INVALID_DEVICE_HANDLE
411 ******************************************************************************/
412NI_DEPRECATED ni_device_handle_t ni_device_open(const char * p_dev, uint32_t * p_max_io_size_out)
413{
414#ifdef _WIN32
415 DWORD retval;
416 HANDLE device_handle;
417
418 if (!p_dev)
419 {
420 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
421 return NI_INVALID_DEVICE_HANDLE;
422 }
423
424 if (p_max_io_size_out != NULL && *p_max_io_size_out == NI_INVALID_IO_SIZE)
425 {
426 // For now, we just use it to allocate p_leftover buffer
427 // NI_MAX_PACKET_SZ is big enough
428 *p_max_io_size_out = NI_MAX_PACKET_SZ;
429 }
430
431 device_handle = CreateFileA(p_dev, GENERIC_READ | GENERIC_WRITE,
432 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
433 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
434
435 ni_log(NI_LOG_DEBUG, "%s() device_name: %s", __func__, p_dev);
436 if (INVALID_HANDLE_VALUE == device_handle)
437 {
438 retval = GetLastError();
439 ni_log(NI_LOG_ERROR, "Failed to open %s, retval %d \n", p_dev, retval);
440 } else
441 {
442 ni_log(NI_LOG_DEBUG, "Found NVME Controller at %s \n", p_dev);
443 }
444
445 return device_handle;
446#else
447 int retval = -1;
448 ni_device_handle_t fd = NI_INVALID_DEVICE_HANDLE;
449
450 if (!p_dev)
451 {
452 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
454 }
455
456 if (p_max_io_size_out != NULL && *p_max_io_size_out == NI_INVALID_IO_SIZE)
457 {
458#if __linux__
459 *p_max_io_size_out = ni_get_kernel_max_io_size(p_dev);
460#elif __APPLE__
461 *p_max_io_size_out = MAX_IO_TRANSFER_SIZE;
462#endif
463 }
464
465 ni_log(NI_LOG_DEBUG, "%s: opening regular-io enabled %s\n", __func__,
466 p_dev);
467 //O_SYNC is added to ensure that data is written to the card when the pread/pwrite function returns
468 #if __linux__
469 //O_DIRECT is added to ensure that data can be sent directly to the card instead of to cache memory
470 fd = open(p_dev, O_RDWR | O_SYNC | O_DIRECT);
471 #elif __APPLE__
472 //O_DIRECT isn't available, so instead we use F_NOCACHE below
473 fd = open(p_dev, O_RDWR | O_SYNC);
474 #endif
475
476 if (fd < 0)
477 {
478 char errmsg[NI_ERRNO_LEN] = {0};
480 ni_log(NI_LOG_ERROR, "ERROR: %d %s open() failed on %s\n", NI_ERRNO,
481 errmsg, p_dev);
482 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
483 fd = NI_INVALID_DEVICE_HANDLE;
484 LRETURN;
485 }
486 else if(fd == 0)
487 {
488 //this code is just for the case that we do not initialize all fds to NI_INVALID_DEVICE_HANDLE
489
490 //if we make sure that all the fds in libxcoder is initialized to NI_INVALID_DEVICE_HANDLE
491 //we should remove this check
492
493 //we hold the fd = 0, so other threads could not visit these code
494 //thread safe unless other thread close fd=0 accidently
495 ni_log(NI_LOG_ERROR, "open fd = 0 is not as expeceted\n");
496 if(close_fd_zero_atexit == 0)
497 {
498 close_fd_zero_atexit = 1;
499 (void)atexit(close_fd_zero);
500 }
501 else
502 {
503 ni_log(NI_LOG_ERROR, "libxcoder has held the fd=0, but open fd=0 again, maybe fd=0 was closed accidently.");
504 }
505 fd = NI_INVALID_DEVICE_HANDLE;
506 }
507
508 #if __APPLE__
509 //F_NOCACHE is set to ensure that data can be sent directly to the card instead of to cache memory
510 retval = fcntl(fd, F_NOCACHE, 1);
511 if (retval < 0)
512 {
513 ni_log(NI_LOG_ERROR, "ERROR: fnctl() failed on %s\n", p_dev);
514 ni_log(NI_LOG_ERROR, "ERROR: ni_device_open() failed!\n");
515 (void)close(fd);
516 fd = NI_INVALID_DEVICE_HANDLE;
517 LRETURN;
518 }
519 #endif
520
521 retval = fstat(fd, &g_nvme_stat);
522 if (retval < 0)
523 {
524 ni_log(NI_LOG_ERROR, "ERROR: fstat() failed on %s\n", p_dev);
525 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
526 (void)close(fd);
527 fd = NI_INVALID_DEVICE_HANDLE;
528 LRETURN;
529 }
530
531 if (!S_ISCHR(g_nvme_stat.st_mode) && !S_ISBLK(g_nvme_stat.st_mode))
532 {
533 ni_log(NI_LOG_ERROR, "ERROR: %s is not a block or character device\n",
534 p_dev);
535 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
536 (void)close(fd);
537 fd = NI_INVALID_DEVICE_HANDLE;
538 LRETURN;
539 }
540
541 ni_log(NI_LOG_DEBUG, "%s: success, fd=%d\n", __func__, fd);
542
543END:
544
545 return fd;
546#endif
547}
548#endif
549
550/*!*****************************************************************************
551 * \brief Open device and return device device_handle if successful
552 *
553 * \param[in] p_dev Device name represented as c string. ex: "/dev/nvme0"
554 * \param[in] p_config Device configuration parameters
555 *
556 * \return On success returns a device device_handle
557 * On failure returns NI_INVALID_DEVICE_HANDLE
558 ******************************************************************************/
559ni_device_handle_t ni_device_open2(const char * p_dev, ni_device_mode_t mode)
560{
561#ifdef _WIN32
562 DWORD retval;
563 HANDLE device_handle;
564 DWORD dwDesiredAccess = 0;
565
566 if (!p_dev)
567 {
568 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
569 return NI_INVALID_DEVICE_HANDLE;
570 }
571
572 /* Convert access mode using bit operations */
573 switch(mode & NI_DEVICE_READ_WRITE)
574 {
576 /* Read-only mode */
577 dwDesiredAccess = GENERIC_READ;
578 break;
580 /* Write-only mode */
581 dwDesiredAccess = GENERIC_WRITE;
582 break;
584 default:
585 /* Read-write mode takes precedence */
586 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
587 break;
588 }
589
590 device_handle = CreateFileA(p_dev, dwDesiredAccess,
591 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
592 OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
593
594 ni_log(NI_LOG_DEBUG, "%s() device_name: %s", __func__, p_dev);
595 if (INVALID_HANDLE_VALUE == device_handle)
596 {
597 retval = GetLastError();
598 ni_log(NI_LOG_ERROR, "Failed to open %s, retval %d \n", p_dev, retval);
599 } else
600 {
601 ni_log(NI_LOG_DEBUG, "Found NVME Controller at %s \n", p_dev);
602 }
603
604 return device_handle;
605#else
606 int retval = -1;
607 ni_device_handle_t fd = NI_INVALID_DEVICE_HANDLE;
608 int open_flags = 0;
609
610 if (!p_dev)
611 {
612 ni_log(NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
614 }
615
616 ni_log(NI_LOG_DEBUG, "%s: opening regular-io enabled %s\n", __func__,
617 p_dev);
618
619 /* Set access mode using bit operations */
620 switch(mode & NI_DEVICE_READ_WRITE)
621 {
623 /* Read-only mode */
624 open_flags = O_RDONLY;
625 break;
627 /* Write-only mode */
628 open_flags = O_WRONLY;
629 break;
631 default:
632 /* Read-write mode takes precedence */
633 open_flags = O_RDWR;
634 break;
635 }
636
637 open_flags |= O_SYNC;
638#if __linux__
639 open_flags |= O_DIRECT;
640#elif __APPLE__
641 /* macOS doesn't support O_DIRECT, use F_NOCACHE instead */
642#endif
643
644 fd = open(p_dev, open_flags);
645 if (fd < 0)
646 {
647 ni_log(NI_LOG_ERROR, "ERROR: %d %s open() failed on %s\n", NI_ERRNO,
648 strerror(NI_ERRNO), p_dev); // NOLINT(concurrency-mt-unsafe)
649 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
650 fd = NI_INVALID_DEVICE_HANDLE;
651 LRETURN;
652 }
653
654#if __APPLE__
655 //F_NOCACHE is set to ensure that data can be sent directly to the card instead of to cache memory
656 retval = fcntl(fd, F_NOCACHE, 1);
657 if (retval < 0)
658 {
659 ni_log(NI_LOG_ERROR, "ERROR: fnctl() failed on %s\n", p_dev);
660 ni_log(NI_LOG_ERROR, "ERROR: ni_device_open2() failed!\n");
661 (void)close(fd);
662 fd = NI_INVALID_DEVICE_HANDLE;
663 LRETURN;
664 }
665#endif
666
667 retval = fstat(fd, &g_nvme_stat);
668 if (retval < 0)
669 {
670 ni_log(NI_LOG_ERROR, "ERROR: fstat() failed on %s\n", p_dev);
671 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
672 (void)close(fd);
673 fd = NI_INVALID_DEVICE_HANDLE;
674 LRETURN;
675 }
676
677 if (!S_ISCHR(g_nvme_stat.st_mode) && !S_ISBLK(g_nvme_stat.st_mode))
678 {
679 ni_log(NI_LOG_ERROR, "ERROR: %s is not a block or character device\n",
680 p_dev);
681 ni_log(NI_LOG_ERROR, "ERROR: %s() failed!\n", __func__);
682 (void)close(fd);
683 fd = NI_INVALID_DEVICE_HANDLE;
684 LRETURN;
685 }
686
687 ni_log(NI_LOG_DEBUG, "%s: success, fd=%d\n", __func__, fd);
688
689END:
690
691 return fd;
692#endif
693}
694
695/*!*****************************************************************************
696 * \brief Close device and release resources
697 *
698 * \param[in] device_handle Device handle obtained by calling ni_device_open()
699 *
700 * \return NONE
701 *
702 ******************************************************************************/
703void ni_device_close(ni_device_handle_t device_handle)
704{
705 if ( NI_INVALID_DEVICE_HANDLE == device_handle )
706 {
707 ni_log(NI_LOG_ERROR, "ERROR %s: null parameter passed %x\n", __func__,
708 device_handle);
709 return;
710 }
711
712 if(device_handle == 0)
713 {
714 //this code is just for the case that we do not initialize all fds to NI_INVALID_DEVICE_HANDLE
715
716 //if we make sure that all the fds in libxcoder is initialized to NI_INVALID_DEVICE_HANDLE
717 //we should remove this check
718 ni_log(NI_LOG_ERROR, "%s close fd=0 is not as expected", __func__);
719 return;
720 }
721
722 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
723
724#ifdef _WIN32
725 BOOL retval;
726
727 ni_log(NI_LOG_DEBUG, "%s(): closing %p\n", __func__, device_handle);
728
729 retval = CloseHandle(device_handle);
730 if (FALSE == retval)
731 {
733 "ERROR: %s(): closing device device_handle %p failed, error: %d\n",
734 __func__, device_handle, NI_ERRNO);
735 }
736 else
737 {
738 ni_log(NI_LOG_DEBUG, "%s(): device %p closed successfuly\n", __func__,
739 device_handle);
740 }
741#else
742 int err = 0;
743 ni_log(NI_LOG_DEBUG, "%s(): closing fd %d\n", __func__, device_handle);
744 err = close(device_handle);
745 if (err == -1)
746 {
747 char error_message[100] = {'\0'};
748 char unknown_error_message[20] = {'\0'};
749 ni_sprintf(error_message, 100, "ERROR: %s(): ", __func__);
750 switch (errno)
751 {
752 case EBADF:
753 ni_strcat(error_message, 100, "EBADF\n");
754 break;
755 case EINTR:
756 ni_strcat(error_message, 100, "EINTR\n");
757 break;
758 case EIO:
759 ni_strcat(error_message, 100, "EIO\n");
760 break;
761 default:
762 ni_sprintf(unknown_error_message, 20, "Unknown error %d\n", err);
763 ni_strcat(error_message, 100, unknown_error_message);
764 }
765 char errmsg[NI_ERRNO_LEN] = {0};
767 ni_log(NI_LOG_ERROR, "%s\n", errmsg);
768 ni_log(NI_LOG_ERROR, "%s\n", error_message);
769 }
770#endif
771 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
772}
773
774#ifndef DEPRECATION_AS_ERROR
775/*!*****************************************************************************
776 * \brief Query device and return device capability structure
777 * This function had been replaced by ni_device_capability_query2
778 * This function can't be callback in multi thread
779 *
780 * \param[in] device_handle Device handle obtained by calling ni_device_open
781 * \param[in] p_cap Pointer to a caller allocated ni_device_capability_t
782 * struct
783 * \return On success
784 * NI_RETCODE_SUCCESS
785 * On failure
786 * NI_RETCODE_INVALID_PARAM
787 * NI_RETCODE_ERROR_MEM_ALOC
788 * NI_RETCODE_ERROR_NVME_CMD_FAILED
789 ******************************************************************************/
791{
792 void * p_buffer = NULL;
794 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
795
796 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
797
798 if ( (NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_cap) )
799 {
800 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
801 __func__);
803 LRETURN;
804 }
805
806 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
808 {
809 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
810 NI_ERRNO, __func__);
812 LRETURN;
813 }
814
815 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
816
817 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
818 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer, NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
819 {
821 LRETURN;
822 }
823
825
826END:
827
828 ni_aligned_free(p_buffer);
829 ni_log(NI_LOG_DEBUG, "%s(): retval: %d\n", __func__, retval);
830
831 return retval;
832}
833#endif
834
835/*!*****************************************************************************
836 * \brief Query device and return device capability structure
837 * This function had replaced ni_device_capability_query
838 * This function can be callback with multi thread
839 *
840 * \param[in] device_handle Device handle obtained by calling ni_device_open
841 * \param[in] p_cap Pointer to a caller allocated ni_device_capability_t
842 * struct
843 * \param[in] device_in_ctxt If device is in ctx
844 * \return On success
845 * NI_RETCODE_SUCCESS
846 * On failure
847 * NI_RETCODE_INVALID_PARAM
848 * NI_RETCODE_ERROR_MEM_ALOC
849 * NI_RETCODE_ERROR_NVME_CMD_FAILED
850 ******************************************************************************/
851ni_retcode_t ni_device_capability_query2(ni_device_handle_t device_handle,
852 ni_device_capability_t *p_cap, bool device_in_ctxt)
853{
854 void * p_buffer = NULL;
856 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
857
858 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
859
860 if ( (NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_cap) )
861 {
862 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
863 __func__);
865 LRETURN;
866 }
867
868 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
870 {
871 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
872 NI_ERRNO, __func__);
874 LRETURN;
875 }
876
877 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
878
879 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
880 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer, NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
881 {
883 LRETURN;
884 }
885
886 ni_populate_device_capability_struct(p_cap, p_buffer, device_handle, device_in_ctxt);
887
888END:
889
890 ni_aligned_free(p_buffer);
891 ni_log(NI_LOG_DEBUG, "%s(): retval: %d\n", __func__, retval);
892
893 return retval;
894}
895
896/*!*****************************************************************************
897 * \brief Open a new device session depending on the device_type parameter
898 * If device_type is NI_DEVICE_TYPE_DECODER opens decoding session
899 * If device_type is NI_DEVICE_TYPE_ENCODER opens encoding session
900 * If device_type is NI_DEVICE_TYPE_SCALER opens scaling session
901 *
902 * \param[in] p_ctx Pointer to a caller allocated
903 * ni_session_context_t struct
904 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER,
905 * or NI_DEVICE_TYPE_SCALER
906 * \return On success
907 * NI_RETCODE_SUCCESS
908 * On failure
909 * NI_RETCODE_INVALID_PARAM
910 * NI_RETCODE_ERROR_MEM_ALOC
911 * NI_RETCODE_ERROR_NVME_CMD_FAILED
912 * NI_RETCODE_ERROR_INVALID_SESSION
913 ******************************************************************************/
915 ni_device_type_t device_type)
916{
918 ni_device_pool_t *p_device_pool = NULL;
919 ni_device_context_t *p_device_context = NULL;
920 ni_device_info_t *p_dev_info = NULL;
921 ni_device_info_t dev_info = { 0 };
923 ni_device_context_t *rsrc_ctx = NULL;
924 int i = 0;
925 int rc = 0;
926 int num_coders = 0;
927 bool use_model_load = true;
928 int least_load = 0;
929 int curr_load = 0;
930 int guid = -1;
931 uint32_t num_sw_instances = 0;
932 uint32_t pixel_load = 0xFFFFFFFFU;
933 int user_handles = false;
934 bool has_opened_fd = false;
935 bool session_created = false;
936 ni_lock_handle_t lock = NI_INVALID_LOCK_HANDLE;
937 ni_device_handle_t handle = NI_INVALID_DEVICE_HANDLE;
938 ni_device_handle_t handle1 = NI_INVALID_DEVICE_HANDLE;
939 // For none nvme block device we just need to pass in dummy
940 ni_session_context_t *p_session_context = NULL;
941 ni_device_type_t query_type = device_type;
942
943 if (!p_ctx)
944 {
945 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
946 __func__);
948 }
949
950#ifdef _WIN32
951 if (!IsUserAnAdmin())
952 {
953 ni_log(NI_LOG_ERROR, "ERROR: %s must be in admin priviledge\n", __func__);
955 }
956#endif
957
960
961 p_session_context = ni_device_session_context_alloc_init();
962 if (!p_session_context)
963 {
965 LRETURN;
966 }
967
968 if (NI_INVALID_SESSION_ID != p_ctx->session_id)
969 {
970 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: trying to overwrite existing session, "
971 "device_type %d, session id %d\n",
972 device_type, p_ctx->session_id);
974 LRETURN;
975 }
976
977 p_ctx->p_hdr_buf = NULL;
978 p_ctx->hdr_buf_size = 0;
979
980 p_ctx->roi_side_data_size = p_ctx->nb_rois = 0;
981 p_ctx->av_rois = NULL;
982 p_ctx->roi_map = NULL;
983 p_ctx->avc_roi_map = NULL;
984 p_ctx->hevc_roi_map = NULL;
985 p_ctx->hevc_sub_ctu_roi_buf = NULL;
986 p_ctx->p_master_display_meta_data = NULL;
987
988 p_ctx->enc_change_params = NULL;
989
990 p_ctx->target_bitrate = -1;
991 p_ctx->force_idr_frame = 0;
993 p_ctx->ltr_to_set.use_long_term_ref = 0;
994 p_ctx->ltr_interval = -1;
995 p_ctx->ltr_frame_ref_invalid = -1;
996 p_ctx->framerate.framerate_num = 0;
997 p_ctx->framerate.framerate_denom = 0;
998 p_ctx->vui.colorDescPresent = 0;
999 p_ctx->vui.colorPrimaries = 2; // 2 is unspecified
1000 p_ctx->vui.colorTrc = 2; // 2 is unspecified
1001 p_ctx->vui.colorSpace = 2; // 2 is unspecified
1002 p_ctx->vui.aspectRatioWidth = 0;
1003 p_ctx->vui.aspectRatioHeight = 0;
1004 p_ctx->vui.videoFullRange = 0;
1005 p_ctx->max_frame_size = 0;
1006 p_ctx->reconfig_crf = -1;
1007 p_ctx->reconfig_crf_decimal = 0;
1008 p_ctx->reconfig_vbv_buffer_size = 0;
1009 p_ctx->reconfig_vbv_max_rate = 0;
1010 p_ctx->last_gop_size = 0;
1011 p_ctx->initial_frame_delay = 0;
1012 p_ctx->current_frame_delay = 0;
1013 p_ctx->max_frame_delay = 0;
1014 p_ctx->av1_pkt_num = 0;
1015 p_ctx->avc_ltr_seen_idr = 0;
1017 p_ctx->force_low_delay = false;
1018 p_ctx->force_low_delay_cnt = 0;
1019 p_ctx->pkt_delay_cnt = 0;
1020 p_ctx->reconfig_intra_period = -1;
1021 p_ctx->reconfig_slice_arg = 0;
1022
1023 memset(p_ctx->input_frame_fifo, 0, sizeof(ni_input_frame) * 120);
1024 for (i = 0; i < 120; i++)
1025 {
1026 p_ctx->input_frame_fifo[i].usable = -1;
1027 }
1028
1029 handle = p_ctx->device_handle;
1030 handle1 = p_ctx->blk_io_handle;
1031
1032 ni_log2(p_ctx, NI_LOG_DEBUG,
1033 "%s: device type %d hw_id %d blk_dev_name: %s dev_xcoder_name: %s.\n",
1034 __func__, device_type, p_ctx->hw_id, p_ctx->blk_dev_name,
1035 p_ctx->dev_xcoder_name);
1036
1037 if (device_type == NI_DEVICE_TYPE_UPLOAD)
1038 {
1039 //uploader shares resources with encoder to query as encoder for load info
1040 query_type = NI_DEVICE_TYPE_ENCODER;
1041 }
1042
1043 // if caller requested device by block device name, try to find its GUID and
1044 // use it to override the hw_id which is the passed in device GUID
1045 if (0 != strcmp(p_ctx->blk_dev_name, ""))
1046 {
1047 int tmp_guid_id;
1048 tmp_guid_id =
1050 if (tmp_guid_id != NI_RETCODE_FAILURE)
1051 {
1052 ni_log2(p_ctx, NI_LOG_DEBUG,
1053 "%s: block device name %s type %d guid %d is to "
1054 "override passed in guid %d\n",
1055 __func__, p_ctx->blk_dev_name, device_type, tmp_guid_id,
1056 p_ctx->hw_id);
1057 p_ctx->hw_id = tmp_guid_id;
1058 } else
1059 {
1060 ni_log(NI_LOG_INFO, "%s: block device name %s type %d NOT found ..\n",
1061 __func__, p_ctx->blk_dev_name, device_type);
1063 LRETURN;
1064 }
1065 }
1066
1067 // User did not pass in any handle, so we create it for them
1068 if ((handle1 == NI_INVALID_DEVICE_HANDLE) && (handle == NI_INVALID_DEVICE_HANDLE))
1069 {
1070 if (p_ctx->hw_id >=0) // User selected the encder/ decoder number
1071 {
1072 rsrc_ctx = ni_rsrc_allocate_simple_direct(device_type, p_ctx->hw_id);
1073 if (rsrc_ctx == NULL)
1074 {
1075
1076 ni_log2(p_ctx, NI_LOG_ERROR, "Error XCoder resource allocation: inst %d\n",
1077 p_ctx->hw_id);
1079 LRETURN;
1080 }
1081 ni_log2(p_ctx, NI_LOG_DEBUG, "device %p\n", rsrc_ctx);
1082 // Now the device name is in the rsrc_ctx, we open this device to get the file handles
1083
1084#ifdef _WIN32
1085 if ((handle = ni_device_open2(rsrc_ctx->p_device_info->blk_name,
1086 NI_DEVICE_READ_WRITE)) == NI_INVALID_DEVICE_HANDLE)
1087 {
1090 LRETURN;
1091 } else
1092 {
1093 user_handles = true;
1094 has_opened_fd = true;
1095 p_ctx->device_handle = handle;
1096 p_ctx->blk_io_handle = handle;
1097 handle1 = handle;
1101 }
1102#else
1103 //The original design (code below) is to open char and block device file separately. And the ffmpeg will close the device twice.
1104 //However, in I/O version, char device can't be opened. For compatibility, and to avoid errors, open the block device twice.
1106 if (handle != NI_INVALID_DEVICE_HANDLE)
1108 if (handle == NI_INVALID_DEVICE_HANDLE || handle1 == NI_INVALID_DEVICE_HANDLE)
1109 {
1110 if (handle != NI_INVALID_DEVICE_HANDLE)
1111 {
1112 ni_device_close(handle);
1113 }
1114 if (handle1 != NI_INVALID_DEVICE_HANDLE)
1115 {
1116 ni_device_close(handle1);
1117 }
1120 LRETURN;
1121 } else
1122 {
1123 user_handles = true;
1124 has_opened_fd = true;
1125 p_ctx->device_handle = handle;
1126 p_ctx->blk_io_handle = handle1;
1127 // NOLINTNEXTLINE(clang-analyzer-core.NonNullParamChecker): Couldn't determine why it will be NULL.
1130
1132 }
1133#endif
1134 } else
1135 {
1136 int tmp_id = -1;
1137
1138 // Decide on model load or real load to be used, based on name passed
1139 // in from p_ctx->dev_xcoder_name; after checking it will be used to
1140 // store device file name.
1141 if (0 == strcmp(p_ctx->dev_xcoder_name, NI_BEST_REAL_LOAD_STR))
1142 {
1143 use_model_load = false;
1144 } else if (0 != strcmp(p_ctx->dev_xcoder_name, NI_BEST_MODEL_LOAD_STR))
1145 {
1146 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s unrecognized option: %s.\n",
1147 __func__, p_ctx->dev_xcoder_name);
1148 retval = NI_RETCODE_INVALID_PARAM;
1149 LRETURN;
1150 }
1151
1152 if (ni_rsrc_lock_and_open(query_type, &lock) != NI_RETCODE_SUCCESS)
1153 {
1155 LRETURN;
1156 }
1157
1158 // We need to query through all the boards to confirm the least load.
1159
1160 p_device_pool = ni_rsrc_get_device_pool();
1161
1162 if (!p_device_pool)
1163 {
1164 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Error calling ni_rsrc_get_device_pool()\n");
1166 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1167 {
1169 }
1170 LRETURN;
1171 }
1172 if (IS_XCODER_DEVICE_TYPE(query_type))
1173 {
1174 num_coders = (int)p_device_pool->p_device_queue->xcoder_cnt[query_type];
1175 } else
1176 {
1177 retval = NI_RETCODE_INVALID_PARAM;
1178 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1179 {
1181 LRETURN;
1182 }
1183 LRETURN;
1184 }
1185
1186 for (i = 0; i < num_coders; i++)
1187 {
1188 tmp_id = p_device_pool->p_device_queue->xcoders[query_type][i];
1189 p_device_context = ni_rsrc_get_device_context(query_type, tmp_id);
1190
1191 if (p_device_context == NULL)
1192 {
1193 ni_log2(p_ctx, NI_LOG_ERROR,
1194 "ERROR: %s() ni_rsrc_get_device_context() failed\n",
1195 __func__);
1196 continue;
1197 }
1198
1199 // Code is included in the for loop. In the loop, the device is
1200 // just opened once, and it will be closed once too.
1201 p_session_context->blk_io_handle = ni_device_open2(
1202 p_device_context->p_device_info->dev_name, NI_DEVICE_READ_WRITE);
1203 p_session_context->device_handle = p_session_context->blk_io_handle;
1204
1205 if (NI_INVALID_DEVICE_HANDLE == p_session_context->device_handle)
1206 {
1207 ni_log2(p_ctx, NI_LOG_ERROR, "Error open device");
1208 ni_rsrc_free_device_context(p_device_context);
1209 continue;
1210 }
1211
1212 p_session_context->hw_id = p_device_context->p_device_info->hw_id;
1213 rc = ni_device_session_query(p_session_context, query_type);
1214 if (NI_INVALID_DEVICE_HANDLE != p_session_context->device_handle)
1215 {
1216 ni_device_close(p_session_context->device_handle);
1217 }
1218
1219 if (NI_RETCODE_SUCCESS != rc)
1220 {
1221 ni_log2(p_ctx, NI_LOG_ERROR, "Error query %s %s.%d\n",
1222 g_device_type_str[query_type],
1223 p_device_context->p_device_info->dev_name,
1224 p_device_context->p_device_info->hw_id);
1225 ni_rsrc_free_device_context(p_device_context);
1226 continue;
1227 }
1228 ni_rsrc_update_record(p_device_context, p_session_context);
1229 p_dev_info = p_device_context->p_device_info;
1230
1231 // here we select the best load
1232 // for decoder/encoder: check the model_load/real_load
1233 // for hwuploader: check directly hwupload pixel load in query result
1234 if (NI_DEVICE_TYPE_UPLOAD == device_type)
1235 {
1236 if (lower_pixel_rate(&p_session_context->load_query, pixel_load))
1237 {
1238 guid = tmp_id;
1239 pixel_load = p_session_context->load_query.total_pixel_load;
1240 memcpy(&dev_info, p_dev_info, sizeof(ni_device_info_t));
1241 }
1242 } else
1243 {
1244 if (use_model_load)
1245 {
1246 curr_load = p_dev_info->model_load;
1247 } else
1248 {
1249 curr_load = p_dev_info->load;
1250 }
1251
1252 if (i == 0 || curr_load < least_load ||
1253 (curr_load == least_load &&
1254 p_dev_info->active_num_inst < num_sw_instances))
1255 {
1256 guid = tmp_id;
1257 least_load = curr_load;
1258 num_sw_instances = p_dev_info->active_num_inst;
1259 memcpy(&dev_info, p_dev_info, sizeof(ni_device_info_t));
1260 }
1261 }
1262 ni_rsrc_free_device_context(p_device_context);
1263 }
1264
1265#ifdef _WIN32
1266 // Now we have the device info that has the least load of the FW
1267 // we open this device and assign the FD
1268 if ((handle = ni_device_open2(dev_info.blk_name, NI_DEVICE_READ_WRITE)) ==
1269 NI_INVALID_DEVICE_HANDLE)
1270 {
1272 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1273 {
1275 LRETURN;
1276 }
1277 LRETURN;
1278 } else
1279 {
1280 has_opened_fd = true;
1281 p_ctx->device_handle = handle;
1282 p_ctx->blk_io_handle = handle;
1283 handle1 = handle;
1284 p_ctx->hw_id = guid;
1287 }
1288#else
1289 //The original design (code below) is to open char and block device file separately. And the ffmpeg will close the device twice.
1290 //However, in I/O version, char device can't be opened. For compatibility, and to avoid errors, open the block device twice.
1291 handle = ni_device_open2(dev_info.dev_name, NI_DEVICE_READ_WRITE);
1292 if (handle != NI_INVALID_DEVICE_HANDLE)
1293 handle1 = ni_device_open2(dev_info.dev_name, NI_DEVICE_READ_WRITE);
1294 if (handle == NI_INVALID_DEVICE_HANDLE || handle1 == NI_INVALID_DEVICE_HANDLE)
1295 {
1296 if (handle != NI_INVALID_DEVICE_HANDLE)
1297 {
1298 ni_device_close(handle);
1299 }
1300 if (handle1 != NI_INVALID_DEVICE_HANDLE)
1301 {
1302 ni_device_close(handle1);
1303 }
1305 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1306 {
1308 LRETURN;
1309 }
1310 LRETURN;
1311 }
1312 else
1313 {
1314 has_opened_fd = true;
1315 p_ctx->device_handle = handle;
1316 p_ctx->blk_io_handle = handle1;
1317 p_ctx->hw_id = guid;
1320 }
1321#endif
1322 }
1323 }
1324 // user passed in the handle, but one of them is invalid, this is error case so we return error
1325 else if((handle1 == NI_INVALID_DEVICE_HANDLE) || (handle == NI_INVALID_DEVICE_HANDLE))
1326 {
1328 LRETURN;
1329 }
1330 // User passed in both handles, so we do not need to allocate for it
1331 else
1332 {
1333 user_handles = true;
1334 }
1335
1336 ni_log2(p_ctx, NI_LOG_DEBUG,
1337 "Finish open the session dev:%s guid:%d handle:%p handle1:%p\n",
1338 p_ctx->dev_xcoder_name, p_ctx->hw_id,
1339 p_ctx->device_handle, p_ctx->blk_io_handle);
1342 // get FW API version
1343 p_device_context = ni_rsrc_get_device_context(device_type, p_ctx->hw_id);
1344 if (p_device_context == NULL)
1345 {
1346 ni_log2(p_ctx, NI_LOG_ERROR,
1347 "ERROR: %s() ni_rsrc_get_device_context() failed\n",
1348 __func__);
1349 if (user_handles != true)
1350 {
1351 if(ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1352 {
1354 LRETURN;
1355 }
1356 }
1358 LRETURN;
1359 }
1360
1361 if (!(strcmp(p_ctx->dev_xcoder_name, "")) || !(strcmp(p_ctx->dev_xcoder_name, NI_BEST_MODEL_LOAD_STR)) ||
1362 !(strcmp(p_ctx->dev_xcoder_name, NI_BEST_REAL_LOAD_STR)))
1363 {
1365 }
1366
1367 memcpy(p_ctx->fw_rev , p_device_context->p_device_info->fw_rev, 8);
1368
1369 ni_rsrc_free_device_context(p_device_context);
1370
1371 retval = ni_device_get_ddr_configuration(p_ctx);
1372 if (retval != NI_RETCODE_SUCCESS)
1373 {
1374 ni_log2(p_ctx, NI_LOG_ERROR,
1375 "ERROR: %s() cannot retrieve DDR configuration\n",
1376 __func__);
1377 if (user_handles != true)
1378 {
1379 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1380 {
1382 LRETURN;
1383 }
1384 }
1385 LRETURN;
1386 }
1387
1388 if (p_ctx->keep_alive_timeout == 0)
1389 {
1390 ni_log2(p_ctx, NI_LOG_ERROR,
1391 "ERROR: %s() keep_alive_timeout was 0, should be between 1-100. "
1392 "Setting to default of %u\n",
1395 }
1396 switch (device_type)
1397 {
1399 {
1400 retval = ni_decoder_session_open(p_ctx);
1401 session_created = p_ctx->session_id != NI_INVALID_SESSION_ID;
1402 if (user_handles != true)
1403 {
1404 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1405 {
1407 LRETURN;
1408 }
1409 }
1410 // send keep alive signal thread
1411 if (NI_RETCODE_SUCCESS != retval)
1412 {
1413 LRETURN;
1414 }
1415 break;
1416 }
1418 {
1419#ifndef _WIN32
1420 // p2p is not supported on Windows, so skip following assignments.
1421 ni_xcoder_params_t *p_enc_params;
1422
1423 p_enc_params = p_ctx->p_session_config;
1424
1425 if (p_enc_params && p_enc_params->hwframes &&
1426 p_enc_params->p_first_frame)
1427 {
1428 niFrameSurface1_t *pSurface;
1429 pSurface =
1430 (niFrameSurface1_t *)p_enc_params->p_first_frame->p_data[3];
1431 p_ctx->sender_handle =
1432 (ni_device_handle_t)(int64_t)pSurface->device_handle;
1433 p_enc_params->rootBufId = pSurface->ui16FrameIdx;
1434
1435 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: sender_handle and rootBufId %d set\n",
1436 __func__, p_enc_params->rootBufId);
1437 }
1438#endif
1439
1440 retval = ni_encoder_session_open(p_ctx);
1441 session_created = p_ctx->session_id != NI_INVALID_SESSION_ID;
1442 if (user_handles != true)
1443 {
1444 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1445 {
1447 LRETURN;
1448 }
1449 }
1450 // send keep alive signal thread
1451 if (NI_RETCODE_SUCCESS != retval)
1452 {
1453 LRETURN;
1454 }
1455 break;
1456 }
1458 {
1459 retval = ni_uploader_session_open(p_ctx);
1460 session_created = p_ctx->session_id != NI_INVALID_SESSION_ID;
1461 if (user_handles != true)
1462 {
1463 if (ni_rsrc_unlock(query_type, lock) != NI_RETCODE_SUCCESS)
1464 {
1466 LRETURN;
1467 }
1468 }
1469 // send keep alive signal thread
1470 if (NI_RETCODE_SUCCESS != retval)
1471 {
1472 LRETURN;
1473 }
1474 break;
1475 }
1477 {
1478 retval = ni_scaler_session_open(p_ctx);
1479 session_created = p_ctx->session_id != NI_INVALID_SESSION_ID;
1480 if (user_handles != true)
1481 {
1482 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1483 {
1485 LRETURN;
1486 }
1487 }
1488 // send keep alive signal thread
1489 if (NI_RETCODE_SUCCESS != retval)
1490 {
1491 LRETURN;
1492 }
1493 break;
1494 }
1495 case NI_DEVICE_TYPE_AI:
1496 {
1497 retval = ni_ai_session_open(p_ctx);
1498 session_created = p_ctx->session_id != NI_INVALID_SESSION_ID;
1499 if (user_handles != true)
1500 {
1501 if (ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1502 {
1504 LRETURN;
1505 }
1506 }
1507 // send keep alive signal thread
1508 if (NI_RETCODE_SUCCESS != retval)
1509 {
1510 LRETURN;
1511 }
1512 break;
1513 }
1514 default:
1515 {
1516 if (user_handles != true)
1517 {
1518 if( ni_rsrc_unlock(device_type, lock) != NI_RETCODE_SUCCESS)
1519 {
1521 LRETURN;
1522 }
1523 }
1524 retval = NI_RETCODE_INVALID_PARAM;
1525 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1526 __func__, device_type);
1527 LRETURN;
1528 }
1529 }
1530
1532 if (!p_ctx->keep_alive_thread_args)
1533 {
1534 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: thread_args allocation failed!\n");
1535 ni_device_session_close(p_ctx, 0, device_type);
1537 LRETURN;
1538 }
1539
1542 p_ctx->keep_alive_thread_args->device_type = device_type;
1545 p_ctx->keep_alive_thread_args->close_thread = false;
1548 p_ctx->keep_alive_thread_args->p_mutex = &p_ctx->mutex;
1549 p_ctx->keep_alive_thread_args->hw_id = p_ctx->hw_id;
1551
1553 sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
1554 {
1555 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: keep alive p_buffer allocation failed!\n");
1556 ni_device_session_close(p_ctx, 0, device_type);
1558 LRETURN;
1559 }
1561
1562 if (0 !=
1565 (void *)p_ctx->keep_alive_thread_args))
1566 {
1567 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to create keep alive thread\n");
1568 p_ctx->keep_alive_thread = (ni_pthread_t){0};
1571 ni_device_session_close(p_ctx, 0, device_type);
1573 LRETURN;
1574 }
1575 ni_log2(p_ctx, NI_LOG_DEBUG, "Enabled keep alive thread\n");
1576
1577 // allocate memory for encoder change data to be reused
1578 p_ctx->enc_change_params = calloc(1, sizeof(ni_encoder_change_params_t));
1579 if (!p_ctx->enc_change_params)
1580 {
1581 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: enc_change_params allocation failed!\n");
1582 ni_device_session_close(p_ctx, 0, device_type);
1584 }
1585
1586END:
1587 if (retval != NI_RETCODE_SUCCESS && session_created &&
1589 {
1590 (void)ni_device_session_close(p_ctx, 0, device_type);
1591 }
1592
1593 if (retval != NI_RETCODE_SUCCESS && has_opened_fd)
1594 {
1595 if (p_ctx->device_handle != NI_INVALID_DEVICE_HANDLE)
1596 {
1598 }
1599 if (p_ctx->blk_io_handle != NI_INVALID_DEVICE_HANDLE &&
1600 p_ctx->blk_io_handle != p_ctx->device_handle)
1601 {
1603 }
1604 p_ctx->device_handle = NI_INVALID_DEVICE_HANDLE;
1605 p_ctx->blk_io_handle = NI_INVALID_DEVICE_HANDLE;
1606 }
1607
1608 ni_device_session_context_free(p_session_context);
1609
1610 if (p_device_pool)
1611 {
1612 ni_rsrc_free_device_pool(p_device_pool);
1613 p_device_pool = NULL;
1614 }
1615
1616 p_ctx->xcoder_state &= ~NI_XCODER_OPEN_STATE;
1617
1619
1620 return retval;
1621}
1622
1623/*!*****************************************************************************
1624 * \brief Close device session that was previously opened by calling
1625 * ni_device_session_open()
1626 * If device_type is NI_DEVICE_TYPE_DECODER closes decoding session
1627 * If device_type is NI_DEVICE_TYPE_ENCODER closes encoding session
1628 * If device_type is NI_DEVICE_TYPE_SCALER closes scaling session
1629 *
1630 * \param[in] p_ctx Pointer to a caller allocated
1631 * ni_session_context_t struct
1632 * \param[in] eos_received Flag indicating if End Of Stream indicator was
1633 * received
1634 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER,
1635 * or NI_DEVICE_TYPE_SCALER
1636 * \return On success
1637 * NI_RETCODE_SUCCESS
1638 * On failure
1639 * NI_RETCODE_INVALID_PARAM
1640 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1641 * NI_RETCODE_ERROR_INVALID_SESSION
1642 ******************************************************************************/
1644 int eos_recieved,
1645 ni_device_type_t device_type)
1646{
1647 int ret;
1649
1650 if (!p_ctx)
1651 {
1652 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1653 __func__);
1655 }
1656
1660
1661#ifdef _WIN32
1662 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args)
1663#else
1664 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args)
1665#endif
1666 {
1667 p_ctx->keep_alive_thread_args->close_thread = true;
1668 ret = ni_pthread_join(p_ctx->keep_alive_thread, NULL);
1669 if (ret)
1670 {
1671 ni_log2(p_ctx, NI_LOG_ERROR,
1672 "join keep alive thread fail! : sid %u ret %d\n",
1673 p_ctx->session_id, ret);
1674 }
1677 } else
1678 {
1679 ni_log2(p_ctx, NI_LOG_ERROR, "invalid keep alive thread: %u\n",
1680 p_ctx->session_id);
1681 }
1682
1683 switch (device_type)
1684 {
1686 {
1687 retval = ni_decoder_session_close(p_ctx, eos_recieved);
1688 break;
1689 }
1691 {
1693 // fall through
1694 }
1696 {
1697 retval = ni_encoder_session_close(p_ctx, eos_recieved);
1698 break;
1699 }
1701 {
1702 retval = ni_scaler_session_close(p_ctx, eos_recieved);
1703 break;
1704 }
1705 case NI_DEVICE_TYPE_AI:
1706 {
1707 retval = ni_ai_session_close(p_ctx, eos_recieved);
1708 break;
1709 }
1710 default:
1711 {
1712 retval = NI_RETCODE_INVALID_PARAM;
1713 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1714 __func__, device_type);
1715 break;
1716 }
1717 }
1718
1720 // need set invalid after closed. May cause open invalid parameters.
1722
1723 ni_memfree(p_ctx->p_hdr_buf);
1724 ni_memfree(p_ctx->av_rois);
1725 ni_memfree(p_ctx->roi_map);
1726 ni_memfree(p_ctx->avc_roi_map);
1727 ni_memfree(p_ctx->hevc_roi_map);
1731 p_ctx->hdr_buf_size = 0;
1732 p_ctx->roi_side_data_size = 0;
1733 p_ctx->nb_rois = 0;
1734 p_ctx->target_bitrate = -1;
1735 p_ctx->force_idr_frame = 0;
1737 p_ctx->ltr_to_set.use_long_term_ref = 0;
1738 p_ctx->ltr_interval = -1;
1739 p_ctx->ltr_frame_ref_invalid = -1;
1740 p_ctx->max_frame_size = 0;
1741 p_ctx->reconfig_crf = -1;
1742 p_ctx->reconfig_crf_decimal = 0;
1743 p_ctx->reconfig_vbv_buffer_size = 0;
1744 p_ctx->reconfig_vbv_max_rate = 0;
1745 p_ctx->last_gop_size = 0;
1746 p_ctx->initial_frame_delay = 0;
1747 p_ctx->current_frame_delay = 0;
1748 p_ctx->max_frame_delay = 0;
1749 p_ctx->av1_pkt_num = 0;
1750 p_ctx->avc_ltr_seen_idr = 0;
1751 p_ctx->reconfig_intra_period = -1;
1752 p_ctx->reconfig_slice_arg = 0;
1753
1754 p_ctx->xcoder_state &= ~NI_XCODER_CLOSE_STATE;
1756
1757 return retval;
1758}
1759
1760/*!*****************************************************************************
1761 * \brief Send a flush command to the device
1762 * If device_type is NI_DEVICE_TYPE_DECODER sends EOS command to
1763 * decoder
1764 * If device_type is NI_DEVICE_TYPE_ENCODER sends EOS command to
1765 * encoder
1766 *
1767 * \param[in] p_ctx Pointer to a caller allocated
1768 * ni_session_context_t struct
1769 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1770 * \return On success
1771 * NI_RETCODE_SUCCESS
1772 * On failure
1773 * NI_RETCODE_INVALID_PARAM
1774 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1775 * NI_RETCODE_ERROR_INVALID_SESSION
1776 ******************************************************************************/
1778{
1780 if (!p_ctx)
1781 {
1782 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1783 __func__);
1785 }
1786
1789
1790 switch (device_type)
1791 {
1793 {
1794 retval = ni_decoder_session_send_eos(p_ctx);
1795 break;
1796 }
1798 {
1799 retval = ni_encoder_session_send_eos(p_ctx);
1800 break;
1801 }
1802 default:
1803 {
1804 retval = NI_RETCODE_INVALID_PARAM;
1805 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1806 __func__, device_type);
1807 break;
1808 }
1809 }
1810 p_ctx->ready_to_close = (NI_RETCODE_SUCCESS == retval);
1811 p_ctx->xcoder_state &= ~NI_XCODER_FLUSH_STATE;
1813 return retval;
1814}
1815
1816/*!*****************************************************************************
1817 * \brief Save a stream's headers in a decoder session that can be used later
1818 * for continuous decoding from the same source.
1819 *
1820 * \param[in] p_ctx Pointer to a caller allocated
1821 * ni_session_context_t struct
1822 * \param[in] hdr_data Pointer to header data
1823 * \param[in] hdr_size Size of header data in bytes
1824 * \return On success
1825 * NI_RETCODE_SUCCESS
1826 * On failure
1827 * NI_RETCODE_INVALID_PARAM
1828 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1829 * NI_RETCODE_ERROR_INVALID_SESSION
1830 ******************************************************************************/
1832 uint8_t *hdr_data,
1833 uint8_t hdr_size)
1834{
1836
1837 if (!p_ctx)
1838 {
1839 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s p_ctx null, return\n", __func__);
1841 }
1842
1843 if (!hdr_data)
1844 {
1845 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s hdr_data null, return\n", __func__);
1847 } else if (p_ctx->p_hdr_buf && p_ctx->hdr_buf_size == hdr_size &&
1848 0 == memcmp(p_ctx->p_hdr_buf, hdr_data, hdr_size))
1849 {
1850 // no change from the saved headers, success !
1851 return retval;
1852 }
1853
1854 // update the saved header data
1855 free(p_ctx->p_hdr_buf);
1856 p_ctx->hdr_buf_size = 0;
1857 p_ctx->p_hdr_buf = malloc(hdr_size);
1858 if (p_ctx->p_hdr_buf)
1859 {
1860 memcpy(p_ctx->p_hdr_buf, hdr_data, hdr_size);
1861 p_ctx->hdr_buf_size = hdr_size;
1862 ni_log2(p_ctx, NI_LOG_DEBUG, "%s saved hdr size %u\n", __func__,
1863 p_ctx->hdr_buf_size);
1864 } else
1865 {
1867 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s no memory.\n", __func__);
1868 }
1869 return retval;
1870}
1871
1872/*!*****************************************************************************
1873 * \brief Flush a decoder session to get ready to continue decoding.
1874 * Note: this is different from ni_device_session_flush in that it closes the
1875 * current decode session and opens a new one for continuous decoding.
1876 *
1877 * \param[in] p_ctx Pointer to a caller allocated
1878 * ni_session_context_t struct
1879 * \return On success
1880 * NI_RETCODE_SUCCESS
1881 * On failure
1882 * NI_RETCODE_INVALID_PARAM
1883 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1884 * NI_RETCODE_ERROR_INVALID_SESSION
1885 ******************************************************************************/
1887{
1889
1890 if (!p_ctx)
1891 {
1892 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s ctx null, return\n", __func__);
1894 }
1896 retval = ni_decoder_session_flush(p_ctx);
1897 if (NI_RETCODE_SUCCESS == retval) {
1898 p_ctx->ready_to_close = 0;
1899 }
1901 return retval;
1902}
1903
1904/*!*****************************************************************************
1905 * \brief Sends data to the device
1906 * If device_type is NI_DEVICE_TYPE_DECODER sends data packet to
1907 * decoder
1908 * If device_type is NI_DEVICE_TYPE_ENCODER sends data frame to encoder
1909 * If device_type is NI_DEVICE_TYPE_AI sends data frame to ai engine
1910 *
1911 * \param[in] p_ctx Pointer to a caller allocated
1912 * ni_session_context_t struct
1913 * \param[in] p_data Pointer to a caller allocated
1914 * ni_session_data_io_t struct which contains either a
1915 * ni_frame_t data frame or ni_packet_t data packet to
1916 * send
1917 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER or
1918 * NI_DEVICE_TYPE_AI
1919 * If NI_DEVICE_TYPE_DECODER is specified, it is
1920 * expected that the ni_packet_t struct inside the
1921 * p_data pointer contains data to send.
1922 * If NI_DEVICE_TYPE_ENCODER or NI_DEVICE_TYPE_AI is
1923 * specified, it is expected that the ni_frame_t
1924 * struct inside the p_data pointer contains data to
1925 * send.
1926 * \return On success
1927 * Total number of bytes written
1928 * On failure
1929 * NI_RETCODE_INVALID_PARAM
1930 * NI_RETCODE_ERROR_NVME_CMD_FAILED
1931 * NI_RETCODE_ERROR_INVALID_SESSION
1932 ******************************************************************************/
1934{
1936
1937 if (!p_ctx || !p_data)
1938 {
1939 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
1940 __func__);
1942 }
1943 // Here check if keep alive thread is closed.
1944#ifdef _WIN32
1945 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
1947#else
1948 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
1950#endif
1951 {
1952 ni_log2(p_ctx, NI_LOG_ERROR,
1953 "ERROR: %s() keep alive thread has been closed, "
1954 "hw:%d, session:%d\n",
1955 __func__, p_ctx->hw_id, p_ctx->session_id);
1957 }
1958
1960 // In close state, let the close process execute first.
1962 {
1963 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
1965 ni_usleep(100);
1967 }
1970
1971 switch (device_type)
1972 {
1974 {
1975 retval = ni_decoder_session_write(p_ctx, &(p_data->data.packet));
1976 break;
1977 }
1979 {
1980 retval = ni_encoder_session_write(p_ctx, &(p_data->data.frame));
1981 break;
1982 }
1983 case NI_DEVICE_TYPE_AI:
1984 {
1985 retval = ni_ai_session_write(p_ctx, &(p_data->data.frame));
1986 break;
1987 }
1988 default:
1989 {
1990 retval = NI_RETCODE_INVALID_PARAM;
1991 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
1992 __func__, device_type);
1993 break;
1994 }
1995 }
1996
1998 p_ctx->xcoder_state &= ~NI_XCODER_WRITE_STATE;
2000 return retval;
2001}
2002
2003/*!*****************************************************************************
2004 * \brief Read data from the device
2005 * If device_type is NI_DEVICE_TYPE_DECODER reads data packet from
2006 * decoder
2007 * If device_type is NI_DEVICE_TYPE_ENCODER reads data frame from
2008 * encoder
2009 * If device_type is NI_DEVICE_TYPE_AI reads data frame from AI engine
2010 *
2011 * \param[in] p_ctx Pointer to a caller allocated
2012 * ni_session_context_t struct
2013 * \param[in] p_data Pointer to a caller allocated ni_session_data_io_t
2014 * struct which contains either a ni_frame_t data frame
2015 * or ni_packet_t data packet to send
2016 * \param[in] device_type NI_DEVICE_TYPE_DECODER, NI_DEVICE_TYPE_ENCODER, or
2017 * NI_DEVICE_TYPE_SCALER
2018 * If NI_DEVICE_TYPE_DECODER is specified, data that
2019 * was read will be placed into ni_frame_t struct
2020 * inside the p_data pointer
2021 * If NI_DEVICE_TYPE_ENCODER is specified, data that
2022 * was read will be placed into ni_packet_t struct
2023 * inside the p_data pointer
2024 * If NI_DEVICE_TYPE_AI is specified, data that was
2025 * read will be placed into ni_frame_t struct inside
2026 * the p_data pointer
2027 * \return On success
2028 * Total number of bytes read
2029 * On failure
2030 * NI_RETCODE_INVALID_PARAM
2031 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2032 * NI_RETCODE_ERROR_INVALID_SESSION
2033 ******************************************************************************/
2035{
2037 if ((!p_ctx) || (!p_data))
2038 {
2039 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2040 __func__);
2042 }
2043
2044 // Here check if keep alive thread is closed.
2045#ifdef _WIN32
2046 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
2048#else
2049 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
2051#endif
2052 {
2053 ni_log2(p_ctx, NI_LOG_ERROR,
2054 "ERROR: %s() keep alive thread has been closed, "
2055 "hw:%d, session:%d\n",
2056 __func__, p_ctx->hw_id, p_ctx->session_id);
2058 }
2059
2061 // In close state, let the close process execute first.
2063 {
2064 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
2066 ni_usleep(100);
2068 }
2071
2072 switch (device_type)
2073 {
2075 {
2076 int seq_change_read_count = 0;
2077 p_data->data.frame.src_codec = p_ctx->codec_format;
2078 for (;;)
2079 {
2080 retval = ni_decoder_session_read(p_ctx, &(p_data->data.frame));
2081 // check resolution change only after initial setting obtained
2082 // p_data->data.frame.video_width is picture width and will be 32-align
2083 // adjusted to frame size; p_data->data.frame.video_height is the same as
2084 // frame size, then compare them to saved one for resolution checking
2085 //
2086 uint32_t aligned_width;
2087 if(QUADRA)
2088 {
2089 aligned_width = ((((p_data->data.frame.video_width * p_ctx->bit_depth_factor) + 127) / 128) * 128);
2090 }
2091 else
2092 {
2093 aligned_width = ((p_data->data.frame.video_width + 31) / 32) * 32;
2094 }
2095
2096 if (0 == retval && seq_change_read_count)
2097 {
2098 ni_log2(p_ctx, NI_LOG_DEBUG,
2099 "%s (decoder): seq change NO data, next time.\n", __func__);
2100 p_ctx->active_video_width = 0;
2101 p_ctx->active_video_height = 0;
2102 p_ctx->actual_video_width = 0;
2103 break;
2104 }
2105 else if (retval < 0)
2106 {
2107 ni_log2(p_ctx, NI_LOG_ERROR, "%s (decoder): failure ret %d, return ..\n",
2108 __func__, retval);
2109 break;
2110 }
2111 // aligned_width may equal to active_video_width if bit depth and width
2112 // are changed at the same time. So, check video_width != actual_video_width.
2113 else if (p_ctx->frame_num && (p_ctx->pixel_format_changed ||
2114 (p_data->data.frame.video_width &&
2115 p_data->data.frame.video_height &&
2116 (aligned_width != p_ctx->active_video_width ||
2117 p_data->data.frame.video_height != p_ctx->active_video_height))))
2118 {
2119 ni_log2(
2120 p_ctx, NI_LOG_DEBUG,
2121 "%s (decoder): resolution change, frame size %ux%u -> %ux%u, "
2122 "width %u bit %d, pix_fromat_changed %d, actual_video_width %d, continue read ...\n",
2123 __func__, p_ctx->active_video_width, p_ctx->active_video_height,
2124 aligned_width, p_data->data.frame.video_height,
2125 p_data->data.frame.video_width, p_ctx->bit_depth_factor,
2127 // reset active video resolution to 0 so it can be queried in the re-read
2128 p_ctx->active_video_width = 0;
2129 p_ctx->active_video_height = 0;
2130 p_ctx->actual_video_width = 0;
2131 seq_change_read_count++;
2132 }
2133 else
2134 {
2135 break;
2136 }
2137 }
2138 break;
2139 }
2141 {
2142 retval = ni_encoder_session_read(p_ctx, &(p_data->data.packet));
2143 break;
2144 }
2145 case NI_DEVICE_TYPE_AI:
2146 {
2147 retval = ni_ai_session_read(p_ctx, &(p_data->data.packet));
2148 break;
2149 }
2150 default:
2151 {
2152 retval = NI_RETCODE_INVALID_PARAM;
2153 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2154 __func__, device_type);
2155 break;
2156 }
2157 }
2158
2160 p_ctx->xcoder_state &= ~NI_XCODER_READ_STATE;
2162 return retval;
2163}
2164
2165/*!*****************************************************************************
2166 * \brief Query session data from the device -
2167 * If device_type is valid, will query session data
2168 * from specified device type
2169 *
2170 * \param[in] p_ctx Pointer to a caller allocated
2171 * ni_session_context_t struct
2172 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2173 * NI_DEVICE_TYPE_ENCODER or
2174 * NI_DEVICE_TYPE_SCALER or
2175 * NI_DEVICE_TYPE_AI or
2176 * NI_DEVICE_TYPE_UPLOADER
2177 *
2178 * \return On success
2179 * NI_RETCODE_SUCCESS
2180 * On failure
2181 * NI_RETCODE_INVALID_PARAM
2182 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2183 * NI_RETCODE_ERROR_INVALID_SESSION
2184 ******************************************************************************/
2186{
2188 if (!p_ctx)
2189 {
2190 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2191 __func__);
2193 }
2194
2195 if (IS_XCODER_DEVICE_TYPE(device_type))
2196 {
2197 retval = ni_xcoder_session_query(p_ctx, device_type);
2198 } else
2199 {
2200 retval = NI_RETCODE_INVALID_PARAM;
2201 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2202 __func__, device_type);
2203 }
2204
2205 return retval;
2206}
2207
2208/*!*****************************************************************************
2209 * \brief Query detail session data from the device -
2210 * If device_type is valid, will query session data
2211 * from specified device type
2212 *
2213 * \param[in] p_ctx Pointer to a caller allocated
2214 * ni_session_context_t struct
2215 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2216 * NI_DEVICE_TYPE_ENCODER or
2217 *
2218 * \return On success
2219 * NI_RETCODE_SUCCESS
2220 * On failure
2221 * NI_RETCODE_INVALID_PARAM
2222 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2223 * NI_RETCODE_ERROR_INVALID_SESSION
2224 ******************************************************************************/
2226{
2228 if (!p_ctx)
2229 {
2230 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2231 __func__);
2233 }
2234
2235 if (IS_XCODER_DEVICE_TYPE(device_type))
2236 {
2237 retval = ni_xcoder_session_query_detail(p_ctx, device_type, detail_data, 0);
2238 } else
2239 {
2240 retval = NI_RETCODE_INVALID_PARAM;
2241 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2242 __func__, device_type);
2243 }
2244
2245 return retval;
2246}
2247
2248/*!*****************************************************************************
2249 * \brief Query detail session data from the device -
2250 * If device_type is valid, will query session data
2251 * from specified device type
2252 *
2253 * \param[in] p_ctx Pointer to a caller allocated
2254 * ni_session_context_t struct
2255 * \param[in] device_type NI_DEVICE_TYPE_DECODER or
2256 * NI_DEVICE_TYPE_ENCODER or
2257 *
2258 * \return On success
2259 * NI_RETCODE_SUCCESS
2260 * On failure
2261 * NI_RETCODE_INVALID_PARAM
2262 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2263 * NI_RETCODE_ERROR_INVALID_SESSION
2264 ******************************************************************************/
2266{
2268 if (!p_ctx)
2269 {
2270 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null, return\n",
2271 __func__);
2273 }
2274
2275 if (IS_XCODER_DEVICE_TYPE(device_type))
2276 {
2277 retval = ni_xcoder_session_query_detail(p_ctx, device_type, detail_data, 1);
2278 } else
2279 {
2280 retval = NI_RETCODE_INVALID_PARAM;
2281 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
2282 __func__, device_type);
2283 }
2284
2285 return retval;
2286}
2287
2288/*!*****************************************************************************
2289 * \brief Send namespace num and SRIOv index to the device with specified logic block
2290 * address.
2291 *
2292 * \param[in] device_handle Device handle obtained by calling ni_device_open
2293 * \param[in] namespace_num Set the namespace number with designated sriov
2294 * \param[in] sriov_index Identify which sriov need to be set
2295 *
2296 * \return On success
2297 * NI_RETCODE_SUCCESS
2298 * On failure
2299 * NI_RETCODE_ERROR_MEM_ALOC
2300 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2301 ******************************************************************************/
2302ni_retcode_t ni_device_config_namespace_num(ni_device_handle_t device_handle,
2303 uint32_t namespace_num, uint32_t sriov_index)
2304{
2305 ni_log(NI_LOG_DEBUG, "%s namespace_num %u sriov_index %u\n",
2306 __func__, namespace_num, sriov_index);
2307 return ni_device_config_ns_qos(device_handle, namespace_num, sriov_index);
2308}
2309
2310/*!*****************************************************************************
2311 * \brief Send qos mode to the device with specified logic block
2312 * address.
2313 *
2314 * \param[in] device_handle Device handle obtained by calling ni_device_open
2315 * \param[in] mode The requested qos mode
2316 *
2317 * \return On success
2318 * NI_RETCODE_SUCCESS
2319 * On failure
2320 * NI_RETCODE_ERROR_MEM_ALOC
2321 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2322 ******************************************************************************/
2323ni_retcode_t ni_device_config_qos(ni_device_handle_t device_handle,
2324 uint32_t mode)
2325{
2326 ni_log(NI_LOG_DEBUG, "%s device_handle %p mode %u\n",
2327 __func__, device_handle, mode);
2328 return ni_device_config_ns_qos(device_handle, QOS_NAMESPACE_CODE, mode);
2329}
2330
2331/*!*****************************************************************************
2332 * \brief Send qos over provisioning mode to target namespace with specified logic
2333 * block address.
2334 *
2335 * \param[in] device_handle Device handle obtained by calling ni_device_open
2336 * \param[in] device_handle_t Target device handle of namespace required for OP
2337 * \param[in] over_provision The request overprovision percent
2338 *
2339 * \return On success
2340 * NI_RETCODE_SUCCESS
2341 * On failure
2342 * NI_RETCODE_ERROR_MEM_ALOC
2343 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2344 ******************************************************************************/
2345ni_retcode_t ni_device_config_qos_op(ni_device_handle_t device_handle,
2346 ni_device_handle_t device_handle_t,
2347 uint32_t over_provision)
2348{
2349 ni_retcode_t retval;
2350 float f_over_provision = 0;
2351 memcpy(&f_over_provision, &over_provision, sizeof(int32_t));
2352 ni_log(NI_LOG_DEBUG, "%s device_handle %p target %p over_provision %f\n",
2353 __func__, device_handle, device_handle_t, f_over_provision);
2354 retval = ni_device_config_ns_qos(device_handle, QOS_OP_CONFIG_REC_OP_CODE,
2355 over_provision);
2356 if (NI_RETCODE_SUCCESS != retval)
2357 {
2358 return retval;
2359 }
2360 retval = ni_device_config_ns_qos(device_handle_t, QOS_OP_CONFIG_CODE,
2361 0);
2362 return retval;
2363}
2364
2365/*!*****************************************************************************
2366 * \brief Set QoS allowance for a specific namespace
2367 *
2368 * \param[in] device_handle Device handle obtained by calling ni_device_open
2369 * \param[in] device_handle_t Target device handle of namespace required for allowance
2370 * \param[in] allowance Allowance percentage (0.0-100.0)
2371 *
2372 * \return On success
2373 * NI_RETCODE_SUCCESS
2374 * On failure
2375 * NI_RETCODE_ERROR_MEM_ALOC
2376 * NI_RETCODE_ERROR_NVME_CMD_FAILED
2377 ******************************************************************************/
2378ni_retcode_t ni_device_config_qos_allowance(ni_device_handle_t device_handle,
2379 ni_device_handle_t device_handle_t,
2380 uint32_t allowance)
2381{
2382 ni_retcode_t retval;
2383 float f_allowance = 0;
2384 memcpy(&f_allowance, &allowance, sizeof(int32_t));
2385 ni_log(NI_LOG_DEBUG, "%s device_handle %p target %p allowance %f\n",
2386 __func__, device_handle, device_handle_t, f_allowance);
2388 allowance);
2389 if (NI_RETCODE_SUCCESS != retval)
2390 {
2391 return retval;
2392 }
2393 retval = ni_device_config_ns_qos(device_handle_t, QOS_ALLOW_CONFIG_CODE,
2394 0);
2395 return retval;
2396}
2397
2398
2399/*!*****************************************************************************
2400 * \brief Allocate preliminary memory for the frame buffer based on provided
2401 * parameters. Applicable to YUV420 Planar pixel (8 or 10 bit/pixel)
2402 * format or 32-bit RGBA.
2403 *
2404 * \param[in] p_frame Pointer to a caller allocated
2405 * ni_frame_t struct
2406 * \param[in] video_width Width of the video frame
2407 * \param[in] video_height Height of the video frame
2408 * \param[in] alignment Allignment requirement
2409 * \param[in] metadata_flag Flag indicating if space for additional metadata
2410 * should be allocated
2411 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel,
2412 * 4 for 32 bits/pixel (RGBA)
2413 * \param[in] hw_frame_count Number of hw descriptors stored
2414 * \param[in] is_planar 0 if semiplanar else planar
2415 *
2416 * \return On success
2417 * NI_RETCODE_SUCCESS
2418 * On failure
2419 * NI_RETCODE_INVALID_PARAM
2420 * NI_RETCODE_ERROR_MEM_ALOC
2421 ******************************************************************************/
2423 int video_height, int alignment,
2424 int metadata_flag, int factor,
2425 int hw_frame_count, int is_planar)
2426{
2427 void* p_buffer = NULL;
2428 int metadata_size = 0;
2429 int retval = NI_RETCODE_SUCCESS;
2430 int width_aligned = video_width;
2431 int height_aligned = video_height;
2432
2433 if ((!p_frame) || ((factor!=1) && (factor!=2) && (factor !=4))
2434 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
2435 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
2436 {
2437 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2438 "factor %d, video_width %d, video_height %d\n",
2439 __func__, factor, video_width, video_height);
2441 }
2442
2443 if (metadata_flag)
2444 {
2445 metadata_size = NI_FW_META_DATA_SZ + NI_MAX_SEI_DATA;
2446 }
2447
2448 if (QUADRA)
2449 {
2450 switch (factor)
2451 {
2452 case 1: /* 8-bit YUV420 */
2453 case 2: /* 10-bit YUV420 */
2454 width_aligned = ((((video_width * factor) + 127) / 128) * 128) / factor;
2455 height_aligned = ((video_height + 1) / 2) * 2;
2456 break;
2457 case 4: /* 32-bit RGBA */
2458 //64byte aligned => 16 rgba pixels
2459 width_aligned = NI_VPU_ALIGN16(video_width);
2460 height_aligned = ((video_height + 1) / 2) * 2;
2461 break;
2462 default:
2464 }
2465 }
2466 else
2467 {
2468 width_aligned = ((video_width + 31) / 32) * 32;
2469 height_aligned = ((video_height + 7) / 8) * 8;
2470 if (alignment)
2471 {
2472 height_aligned = ((video_height + 15) / 16) * 16;
2473 }
2474 }
2475
2476 int luma_size = width_aligned * height_aligned * factor;
2477 int chroma_b_size;
2478 int chroma_r_size;
2479 if (QUADRA)
2480 {
2481 int chroma_width_aligned = ((((video_width / 2 * factor) + 127) / 128) * 128) / factor;
2482 if (is_planar == NI_PIXEL_PLANAR_FORMAT_TILED4X4 ||
2484 {
2485 chroma_width_aligned =
2486 ((((video_width * factor) + 127) / 128) * 128) / factor;
2487 }
2488 int chroma_height_aligned = height_aligned / 2;
2489 chroma_b_size = chroma_r_size = chroma_width_aligned * chroma_height_aligned * factor;
2490 if (is_planar == NI_PIXEL_PLANAR_FORMAT_TILED4X4 ||
2492 {
2493 chroma_r_size = 0;
2494 }
2495 if (4 == factor)
2496 {
2497 chroma_b_size = chroma_r_size = 0;
2498 }
2499 //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);
2500 }
2501 else
2502 {
2503 chroma_b_size = luma_size / 4;
2504 chroma_r_size = chroma_b_size;
2505 }
2506 int buffer_size;
2507
2508 /* if hw_frame_count is zero, this is a software frame */
2509 if (hw_frame_count == 0)
2510 buffer_size = luma_size + chroma_b_size + chroma_r_size + metadata_size;
2511 else
2512 buffer_size =
2513 (int)sizeof(niFrameSurface1_t) * hw_frame_count + metadata_size;
2514
2515 // added 2 blocks of 512 bytes buffer space to handle any extra metadata
2516 // retrieval from fw
2517 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT + NI_MEM_PAGE_ALIGNMENT * 3;
2518 //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);
2519
2520 //Check if need to free
2521 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
2522 {
2524 "%s: free current p_frame, p_frame->buffer_size=%u\n", __func__,
2525 p_frame->buffer_size);
2526 ni_frame_buffer_free(p_frame);
2527 }
2528
2529 //Check if need to realocate
2530 if (p_frame->buffer_size != buffer_size)
2531 {
2532 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
2533 {
2534 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
2535 NI_ERRNO, __func__);
2537 LRETURN;
2538 }
2539
2540 // init once after allocation
2541 //memset(p_buffer, 0, buffer_size);
2542 p_frame->buffer_size = buffer_size;
2543 p_frame->p_buffer = p_buffer;
2544
2545 ni_log(NI_LOG_DEBUG, "%s: Allocate new p_frame buffer\n", __func__);
2546 }
2547 else
2548 {
2549 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
2550 }
2551
2552 if (hw_frame_count)
2553 {
2554 p_frame->data_len[0] = 0;
2555 p_frame->data_len[1] = 0;
2556 p_frame->data_len[2] = 0;
2557 p_frame->data_len[3] = sizeof(niFrameSurface1_t)*hw_frame_count;
2558 }
2559 else
2560 {
2561 p_frame->data_len[0] = luma_size;
2562 p_frame->data_len[1] = chroma_b_size;
2563 p_frame->data_len[2] = chroma_r_size;
2564 p_frame->data_len[3] = 0;//unused by hwdesc
2565 }
2566
2567 p_frame->p_data[0] = p_frame->p_buffer;
2568 p_frame->p_data[1] = p_frame->p_data[0] + p_frame->data_len[0];
2569 p_frame->p_data[2] = p_frame->p_data[1] + p_frame->data_len[1];
2570 p_frame->p_data[3] = p_frame->p_data[2] + p_frame->data_len[2]; //hwdescriptor
2571
2572 // init p_data[3] to 0 so that ni_frame_buffer_free frees only valid DMA buf
2573 // fd in hw frame read from fw
2574 if (hw_frame_count)
2575 {
2576 memset(p_frame->p_data[3], 0, sizeof(niFrameSurface1_t) * hw_frame_count);
2577 }
2578
2579 p_frame->video_width = width_aligned;
2580 p_frame->video_height = height_aligned;
2581
2582 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);
2583 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2584 p_frame->buffer_size);
2585
2586END:
2587
2588 if (NI_RETCODE_SUCCESS != retval)
2589 {
2590 ni_aligned_free(p_buffer);
2591 }
2592
2593 return retval;
2594}
2595
2596/*!*****************************************************************************
2597 * \brief Wrapper function for ni_frame_buffer_alloc. Meant to handle RGBA min.
2598 * resoulution considerations for encoder.
2599 *
2600 * \param[in] p_frame Pointer to a caller allocated
2601 * ni_frame_t struct
2602 * \param[in] video_width Width of the video frame
2603 * \param[in] video_height Height of the video frame
2604 * \param[in] alignment Allignment requirement
2605 * \param[in] metadata_flag Flag indicating if space for additional metadata
2606 * should be allocated
2607 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel,
2608 * 4 for 32 bits/pixel (RGBA)
2609 * \param[in] hw_frame_count Number of hw descriptors stored
2610 * \param[in] is_planar 0 if semiplanar else planar
2611 * \param[in] pix_fmt pixel format to distinguish between planar types
2612 * and/or components
2613 *
2614 * \return On success
2615 * NI_RETCODE_SUCCESS
2616 * On failure
2617 * NI_RETCODE_INVALID_PARAM
2618 * NI_RETCODE_ERROR_MEM_ALOC
2619 ******************************************************************************/
2621 int video_height, int alignment,
2622 int metadata_flag, int factor,
2623 int hw_frame_count, int is_planar,
2624 ni_pix_fmt_t pix_fmt)
2625{
2626 (void)hw_frame_count;
2627 (void)is_planar;
2628 int extra_len = 0;
2629 int dst_stride[NI_MAX_NUM_DATA_POINTERS] = {0};
2630 int height_aligned[NI_MAX_NUM_DATA_POINTERS] = {0};
2631
2632 if (((factor!=1) && (factor!=2) && (factor !=4))
2633 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
2634 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
2635 {
2636 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2637 "factor %d, video_width %d, video_height %d\n",
2638 __func__, factor, video_width, video_height);
2640 }
2641
2642 switch (pix_fmt)
2643 {
2644 case NI_PIX_FMT_YUV420P:
2646 case NI_PIX_FMT_NV12:
2647 case NI_PIX_FMT_P010LE:
2648 case NI_PIX_FMT_NV16:
2649 case NI_PIX_FMT_YUYV422:
2650 case NI_PIX_FMT_UYVY422:
2651 case NI_PIX_FMT_ARGB:
2652 case NI_PIX_FMT_ABGR:
2653 case NI_PIX_FMT_RGBA:
2654 case NI_PIX_FMT_BGRA:
2655 case NI_PIX_FMT_BGR0:
2656 break;
2657 default:
2658 ni_log(NI_LOG_ERROR, "ERROR: %s pix_fmt %d not supported \n",
2659 __func__, pix_fmt);
2661 }
2662 //Get stride info for original resolution
2663 ni_get_frame_dim(video_width, video_height,
2664 pix_fmt,
2665 dst_stride, height_aligned);
2666
2667 if (metadata_flag)
2668 {
2669 extra_len = NI_FW_META_DATA_SZ + NI_MAX_SEI_DATA;
2670 }
2671
2672 return ni_frame_buffer_alloc_pixfmt(p_frame, pix_fmt, video_width,
2673 video_height, dst_stride, alignment,
2674 extra_len);
2675}
2676
2677/*!*****************************************************************************
2678 * \brief Allocate preliminary memory for the frame buffer based on provided
2679 * parameters.
2680 *
2681 * \param[in] p_frame Pointer to a caller allocated
2682 * ni_frame_t struct
2683 * \param[in] video_width Width of the video frame
2684 * \param[in] video_height Height of the video frame
2685 * \param[in] alignment Allignment requirement
2686 * \param[in] pixel_format Format for input
2687 *
2688 * \return On success
2689 * NI_RETCODE_SUCCESS
2690 * On failure
2691 * NI_RETCODE_INVALID_PARAM
2692 * NI_RETCODE_ERROR_MEM_ALOC
2693 ******************************************************************************/
2695 int video_height, int pixel_format)
2696{
2697 void *p_buffer = NULL;
2698 int retval = NI_RETCODE_SUCCESS;
2699 int width_aligned = video_width;
2700 int height_aligned = video_height;
2701 int buffer_size;
2702 int luma_size;
2703 int chroma_b_size;
2704 int chroma_r_size;
2705
2706 if ((!p_frame) || (video_width > NI_MAX_RESOLUTION_WIDTH) ||
2707 (video_width <= 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT) ||
2708 (video_height <= 0))
2709 {
2711 "ERROR: %s passed parameters are null or not supported, "
2712 "video_width %d, video_height %d\n",
2713 __func__, video_width, video_height);
2715 }
2716
2717 switch (pixel_format)
2718 {
2719 case NI_PIX_FMT_YUV420P:
2720 width_aligned = NI_VPU_ALIGN128(video_width);
2721 height_aligned = NI_VPU_CEIL(video_height, 2);
2722
2723 luma_size = width_aligned * height_aligned;
2724 chroma_b_size =
2725 NI_VPU_ALIGN128(video_width / 2) * height_aligned / 2;
2726 chroma_r_size = chroma_b_size;
2727 break;
2729 width_aligned = NI_VPU_ALIGN128(video_width * 2) / 2;
2730 height_aligned = NI_VPU_CEIL(video_height, 2);
2731
2732 luma_size = width_aligned * height_aligned * 2;
2733 chroma_b_size = NI_VPU_ALIGN128(video_width) * height_aligned / 2;
2734 chroma_r_size = chroma_b_size;
2735 break;
2736 case NI_PIX_FMT_NV12:
2737 width_aligned = NI_VPU_ALIGN128(video_width);
2738 height_aligned = NI_VPU_CEIL(video_height, 2);
2739
2740 luma_size = width_aligned * height_aligned;
2741 chroma_b_size = width_aligned * height_aligned / 2;
2742 chroma_r_size = 0;
2743 break;
2744 case NI_PIX_FMT_P010LE:
2745 width_aligned = NI_VPU_ALIGN128(video_width * 2) / 2;
2746 height_aligned = NI_VPU_CEIL(video_height, 2);
2747
2748 luma_size = width_aligned * height_aligned * 2;
2749 chroma_b_size = width_aligned * height_aligned;
2750 chroma_r_size = 0;
2751 break;
2752 case NI_PIX_FMT_NV16:
2753 width_aligned = NI_VPU_ALIGN64(video_width);
2754 height_aligned = video_height;
2755
2756 luma_size = width_aligned * height_aligned;
2757 chroma_b_size = luma_size;
2758 chroma_r_size = 0;
2759 break;
2760 case NI_PIX_FMT_YUYV422:
2761 case NI_PIX_FMT_UYVY422:
2762 width_aligned = NI_VPU_ALIGN16(video_width);
2763 height_aligned = video_height;
2764
2765 luma_size = width_aligned * height_aligned * 2;
2766 chroma_b_size = 0;
2767 chroma_r_size = 0;
2768 break;
2769 case NI_PIX_FMT_RGBA:
2770 case NI_PIX_FMT_BGRA:
2771 case NI_PIX_FMT_ARGB:
2772 case NI_PIX_FMT_ABGR:
2773 case NI_PIX_FMT_BGR0:
2774 width_aligned = NI_VPU_ALIGN16(video_width);
2775 height_aligned = video_height;
2776
2777 luma_size = width_aligned * height_aligned * 4;
2778 chroma_b_size = 0;
2779 chroma_r_size = 0;
2780 break;
2781 case NI_PIX_FMT_BGRP:
2782 width_aligned = NI_VPU_ALIGN32(video_width);
2783 height_aligned = video_height;
2784
2785 luma_size = width_aligned * height_aligned;
2786 chroma_b_size = luma_size;
2787 chroma_r_size = luma_size;
2788 break;
2789 default:
2790 ni_log(NI_LOG_ERROR, "Unknown pixel format %d\n", pixel_format);
2792 }
2793
2794 /* Allocate local memory to hold a software ni_frame */
2795 buffer_size = luma_size + chroma_b_size + chroma_r_size;
2796
2797 /* Round up to nearest 4K block */
2798 buffer_size = NI_VPU_ALIGN4096(buffer_size);
2799
2800 ni_log(NI_LOG_DEBUG, "%s: Rlen %d Glen %d Blen %d buffer_size %d\n",
2801 __func__, luma_size, chroma_b_size, chroma_r_size, buffer_size);
2802
2803 /* If the frame has changed, reallocate it */
2804 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
2805 {
2807 "%s: free current p_frame, p_frame->buffer_size=%u\n", __func__,
2808 p_frame->buffer_size);
2809 ni_frame_buffer_free(p_frame);
2810 }
2811
2812 /* Check if need to reallocate */
2813 if (p_frame->buffer_size != buffer_size)
2814 {
2815 ni_log(NI_LOG_DEBUG, "%s: Allocate new p_frame buffer\n", __func__);
2816 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
2817 {
2819 "ERROR %d: %s() Cannot allocate p_frame buffer.\n", NI_ERRNO,
2820 __func__);
2822 LRETURN;
2823 }
2824 } else
2825 {
2826 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
2827 p_buffer = p_frame->p_buffer;
2828 }
2829
2830 // init once after allocation
2831 // memset(p_buffer, 0, buffer_size);
2832
2833 p_frame->buffer_size = buffer_size;
2834 p_frame->p_buffer = p_buffer;
2835
2836 p_frame->data_len[0] = luma_size;
2837 p_frame->data_len[1] = chroma_b_size;
2838 p_frame->data_len[2] = chroma_r_size;
2839 p_frame->data_len[3] = 0;
2840
2841 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
2842 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + p_frame->data_len[0];
2843 p_frame->p_data[2] = (uint8_t *)p_frame->p_data[1] + p_frame->data_len[1];
2844 p_frame->p_data[3] = (uint8_t *)p_frame->p_data[2] + p_frame->data_len[2];
2845
2846 // init p_data[3] to 0 so that ni_frame_buffer_free frees only valid DMA buf
2847 // fd in hw frame read from fw
2848 p_frame->video_width = width_aligned;
2849 p_frame->video_height = height_aligned;
2850
2851 // 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);
2852 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
2853 p_frame->buffer_size);
2854END:
2855
2856 if (NI_RETCODE_SUCCESS != retval)
2857 {
2858 ni_aligned_free(p_buffer);
2859 }
2860
2861 return retval;
2862}
2863
2864/*!*****************************************************************************
2865 * \brief Allocate memory for decoder frame buffer based on provided
2866 * parameters; the memory is retrieved from a buffer pool and will be
2867 * returned to the same buffer pool by ni_decoder_frame_buffer_free.
2868 * Note: all attributes of ni_frame_t will be set up except for memory and
2869 * buffer, which rely on the pool being allocated; the pool will be
2870 * allocated only after the frame resolution is known.
2871 *
2872 * \param[in] p_pool Buffer pool to get the memory from
2873 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
2874 * \param[in] alloc_mem Whether to get memory from buffer pool
2875 * \param[in] video_width Width of the video frame
2876 * \param[in] video_height Height of the video frame
2877 * \param[in] alignment Alignment requirement
2878 * \param[in] factor 1 for 8 bits/pixel format, 2 for 10 bits/pixel
2879 * \param[in] is_planar 0 if semiplanar else planar
2880 *
2881 * \return On success
2882 * NI_RETCODE_SUCCESS
2883 * On failure
2884 * NI_RETCODE_INVALID_PARAM
2885 * NI_RETCODE_ERROR_MEM_ALOC
2886 ******************************************************************************/
2888 ni_frame_t *p_frame, int alloc_mem,
2889 int video_width, int video_height,
2890 int alignment, int factor,
2891 int is_planar)
2892{
2893 int retval = NI_RETCODE_SUCCESS;
2894
2895 int width_aligned;
2896 int height_aligned;
2897
2898 if ((!p_frame) || ((factor!=1) && (factor!=2))
2899 || (video_width > NI_MAX_RESOLUTION_WIDTH) || (video_width <= 0)
2900 || (video_height > NI_MAX_RESOLUTION_HEIGHT) || (video_height <= 0))
2901 {
2902 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
2903 "factor %d, video_width %d, video_height %d\n",
2904 __func__, factor, video_width, video_height);
2906 }
2907
2908 if (QUADRA)
2909 {
2910 width_aligned = ((((video_width * factor) + 127) / 128) * 128) / factor;
2911 height_aligned = video_height;
2912 }
2913 else
2914 {
2915 width_aligned = ((video_width + 31) / 32) * 32;
2916 height_aligned = ((video_height + 7) / 8) * 8;
2917 if (alignment)
2918 {
2919 height_aligned = ((video_height + 15) / 16) * 16;
2920 }
2921 }
2922
2923 ni_log(NI_LOG_DEBUG, "%s: aligned=%dx%d orig=%dx%d\n", __func__,
2924 width_aligned, height_aligned, video_width, video_height);
2925
2926 int luma_size = width_aligned * height_aligned * factor;
2927 int chroma_b_size;
2928 int chroma_r_size;
2929 if (QUADRA)
2930 {
2931 int chroma_width_aligned = ((((video_width / 2 * factor) + 127) / 128) * 128) / factor;
2932 if (!is_planar)
2933 {
2934 chroma_width_aligned =
2935 ((((video_width * factor) + 127) / 128) * 128) / factor;
2936 }
2937 int chroma_height_aligned = height_aligned / 2;
2938 chroma_b_size = chroma_r_size = chroma_width_aligned * chroma_height_aligned * factor;
2939 if (!is_planar)
2940 {
2941 chroma_r_size = 0;
2942 }
2943 }
2944 else
2945 {
2946 chroma_b_size = luma_size / 4;
2947 chroma_r_size = chroma_b_size;
2948 }
2949 int buffer_size = luma_size + chroma_b_size + chroma_r_size +
2951
2952 // added 2 blocks of 512 bytes buffer space to handle any extra metadata
2953 // retrieval from fw
2954 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT + NI_MEM_PAGE_ALIGNMENT * 3;
2955
2956 p_frame->buffer_size = buffer_size;
2957
2958 // if need to get a buffer from pool, pool must have been set up
2959 if (alloc_mem)
2960 {
2961 if (! p_pool)
2962 {
2963 ni_log(NI_LOG_ERROR, "ERROR %s: invalid pool!\n", __func__);
2965 LRETURN;
2966 }
2967
2968 p_frame->dec_buf = ni_buf_pool_get_buffer(p_pool);
2969 if (! p_frame->dec_buf)
2970 {
2972 LRETURN;
2973 }
2974
2975 p_frame->p_buffer = p_frame->dec_buf->buf;
2976
2977 ni_log(NI_LOG_DEBUG, "%s: got new frame ptr %p buffer %p\n", __func__,
2978 p_frame->p_buffer, p_frame->dec_buf);
2979 }
2980 else
2981 {
2982 p_frame->dec_buf = NULL;
2983 p_frame->p_buffer = NULL;
2984 ni_log(NI_LOG_DEBUG, "%s: NOT alloc mem buffer\n", __func__);
2985 }
2986
2987 if (p_frame->p_buffer)
2988 {
2989 p_frame->p_data[0] = p_frame->p_buffer;
2990 p_frame->p_data[1] = p_frame->p_data[0] + luma_size;
2991 p_frame->p_data[2] = p_frame->p_data[1] + chroma_b_size;
2992 p_frame->p_data[3] = p_frame->p_data[2] + chroma_r_size;
2993 }
2994 else
2995 {
2996 p_frame->p_data[0] = p_frame->p_data[1] = p_frame->p_data[2] = NULL;
2997 }
2998
2999 p_frame->data_len[0] = luma_size;
3000 p_frame->data_len[1] = chroma_b_size;
3001 p_frame->data_len[2] = chroma_r_size;
3002 p_frame->data_len[3] = 0; //for hwdesc
3003
3004 p_frame->video_width = width_aligned;
3005 p_frame->video_height = height_aligned;
3006
3007 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
3008 p_frame->buffer_size);
3009
3010END:
3011
3012 return retval;
3013}
3014
3015/*!*****************************************************************************
3016 * \brief Check if incoming frame is encoder zero copy compatible or not
3017 *
3018 * \param[in] p_enc_ctx pointer to encoder context
3019 * [in] p_enc_params pointer to encoder parameters
3020 * [in] width input width
3021 * [in] height input height
3022 * [in] linesize input linesizes (pointer to array)
3023 * [in] set_linesize setup linesizes 0 means not setup linesizes, 1 means setup linesizes (before encoder open)
3024 *
3025 * \return on success and can do zero copy
3026 * NI_RETCODE_SUCCESS
3027 *
3028 * cannot do zero copy
3029 * NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
3030 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
3031 * NI_RETCODE_INVALID_PARAM
3032 *
3033*******************************************************************************/
3035 ni_xcoder_params_t *p_enc_params,
3036 int width, int height,
3037 const int linesize[],
3038 bool set_linesize)
3039{
3040 // check pixel format / width / height / linesize can be supported
3041 if ((!p_enc_ctx) || (!p_enc_params) || (!linesize)
3042 || (linesize[0]<=0)
3043 || (width>NI_MAX_RESOLUTION_WIDTH) || (width<=0)
3044 || (height>NI_MAX_RESOLUTION_HEIGHT) || (height<=0))
3045 {
3046 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s passed parameters are null or not supported, "
3047 "p_enc_ctx %p, p_enc_params %p, linesize %p, "
3048 "width %d, height %d linesize[0] %d\n",
3049 __func__, p_enc_ctx, p_enc_params, linesize,
3050 width, height, (linesize) ? linesize[0] : 0);
3052 }
3053
3054 // check fw revision (if fw_rev has been populated in open session)
3057 "6Q") < 0))
3058 {
3059 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: not supported on device with FW API version < 6.Q\n", __func__);
3061 }
3062
3063 if (p_enc_params->useMCTF) // skip zero copy if MCTF enabled
3065
3066 bool isrgba = false;
3067 bool isplanar = false;
3068 bool issemiplanar = false;
3069
3070 switch (p_enc_ctx->pixel_format)
3071 {
3072 case NI_PIX_FMT_YUV420P:
3074 isplanar = true;
3075 break;
3076 case NI_PIX_FMT_NV12:
3077 case NI_PIX_FMT_P010LE:
3078 issemiplanar = true;
3079 break;
3080 case NI_PIX_FMT_ABGR:
3081 case NI_PIX_FMT_ARGB:
3082 case NI_PIX_FMT_RGBA:
3083 case NI_PIX_FMT_BGRA:
3084 isrgba = true;
3085 break;
3086 default:
3087 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: pixel_format %d not supported\n", __func__);
3089 }
3090
3091 // check fw revision (if fw_rev has been populated in open session)
3092 if (issemiplanar &&
3095 "6q") < 0))
3096 {
3097 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s: semi-planar not supported on device with FW API version < 6.q\n", __func__);
3099 }
3100
3101 // check zero copy compatibilty and set linesize
3102 if (p_enc_params->zerocopy_mode) // always allow zero copy for RGBA, because RGBA pixel format data copy currently not supported
3103 {
3104 if (set_linesize)
3105 {
3106 bool ishwframe = (p_enc_params->hwframes) ? true : false;
3107 int max_linesize = isrgba ? (NI_MAX_RESOLUTION_RGBA_WIDTH*4) : NI_MAX_RESOLUTION_LINESIZE;
3108 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s isrgba %u issemiplanar %u, ishwframe %u, "
3109 "p_enc_ctx %p, p_enc_params %p, linesize %p, "
3110 "width %d, height %d, linesize[0] %d linesize[1] %d\n",
3111 __func__, isrgba, issemiplanar, ishwframe, p_enc_ctx, p_enc_params, linesize,
3112 width, height, linesize[0], linesize[1]);
3113
3114 if (linesize[0] <= max_linesize &&
3115 linesize[0] % 2 == 0 && //even stride
3116 linesize[1] % 2 == 0 && //even stride
3117 width % 2 == 0 && //even width
3118 height % 2 == 0 && //even height
3119 (!p_enc_params->enable_ai_enhance || width % 128 == 0) && // align for AI engine
3120 width >= NI_MIN_WIDTH &&
3121 height >= NI_MIN_HEIGHT &&
3122 !ishwframe &&
3123 (!isplanar || linesize[2] == linesize[1]) // for planar, make sure cb linesize equal to cr linesize
3124 )
3125 {
3126 // send luma / chorma linesize to device (device is also aware frame will not be padded for 2-pass workaround)
3127 p_enc_params->luma_linesize = linesize[0];
3128 p_enc_params->chroma_linesize = (isrgba) ? 0 : linesize[1]; // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format
3129 return NI_RETCODE_SUCCESS;
3130 }
3131 else
3132 {
3133 p_enc_params->luma_linesize = 0;
3134 p_enc_params->chroma_linesize = 0;
3135 }
3136 }
3137 else if (p_enc_params->luma_linesize ||
3138 p_enc_params->chroma_linesize)
3139 {
3140 ni_log2(p_enc_ctx, NI_LOG_DEBUG, "%s "
3141 "luma_linesize %d, chroma_linesize %d, "
3142 "linesize[0] %d, linesize[1] %d\n",
3143 __func__, p_enc_params->luma_linesize, p_enc_params->chroma_linesize,
3144 linesize[0], linesize[1]);
3145 if (p_enc_params->luma_linesize != linesize[0] ||
3146 (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
3147 )
3148 {
3149#ifndef XCODER_311
3150 // linesizes can change during SW frame seqeunce change transcoding when FFmpeg noautoscale option is not set
3151 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: linesize changed from %u %u to %u %u - resolution change?\n", __func__,
3152 p_enc_params->luma_linesize, p_enc_params->chroma_linesize,
3153 linesize[0], linesize[1]);
3154#endif
3155 }
3156 else
3157 return NI_RETCODE_SUCCESS;
3158 }
3159 }
3160
3162}
3163
3164/*!*****************************************************************************
3165 * \brief Check if the frame data transferred is within a frame boundary and
3166 * adjust with offset if it doesn't. EP will re-adjust the data pointer
3167 * to the correct start address.
3168 *
3169 * \param[in] video_height Height of the video frame after filtering
3170 * [in] linesize Picture line size after filtering (i.e. cropping)
3171 * [in] data Picture data pointers after filtering (for each of YUV planes)
3172 * [in] buf_size0 Y frame size before any filtering (original size)
3173 * [in] buf_size1 U frame size before any filtering (original)
3174 * [in] buf_size2 V frame size before any filtering (original)
3175 * [in] buf_data0 Y picture data pointer before any filtering (original)
3176 * [in] buf_data1 U picture data pointer before any filtering (original)
3177 * [in] buf_data2 V picture data pointer before any filtering (original)
3178 *
3179 * \return On success
3180 * NI_RETCODE_SUCCESS
3181 * On failure
3182 * NI_RETCODE_INVALID_PARAM
3183 *****************************************************************************/
3185 ni_session_context_t *p_enc_ctx,
3186 ni_frame_t *p_frame, int video_height,
3187 const int linesize[], const uint8_t *data[],
3188 int buf_size0, int buf_size1, int buf_size2,
3189 uint8_t *buf_data0, uint8_t *buf_data1, uint8_t *buf_data2)
3190{
3191 int retval = NI_RETCODE_SUCCESS;
3192
3193 if (!p_frame || !p_enc_ctx || !data || !linesize)
3194 {
3195 ni_log(NI_LOG_ERROR, "ERROR: %s: null parameters: p_frame=%p, p_enc_ctx=%p, linesize=%p, data=%p\n",
3196 __func__, p_frame, p_enc_ctx, linesize, data);
3198 }
3199
3200 // Only newer firmware versions (6sU and above) support zero-copy with SW cropping corner
3201 // case handling. See the brief of this function.
3202 if (ni_cmp_fw_api_ver((char*)&p_enc_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sU") < 0)
3203 {
3204 p_frame->hor_adjust_offset = 0;
3205 return NI_RETCODE_SUCCESS;
3206 }
3207
3208 const uint8_t *buf_data[3] = { buf_data0, buf_data1, buf_data2 };
3209 const int buf_size[3] = { buf_size0, buf_size1, buf_size2 };
3210 const uint8_t *end_used, *end_alloc;
3211 int offset = 0;
3212 int i;
3213
3214 // num_planes = 1 if frame is directly from quadra decoder (out=sw) or from raw YUV file
3215 // num_planes = actual number of planes if frame is from ffmpeg SW decoder or after ffmpeg
3216 // pixel format conversion or after hwdownload from quadra decoder (out=hw)
3217 const int num_planes = (buf_size[2] != 0) ? 3 : (buf_size[1] != 0) ? 2 : 1;
3218
3219 // In case of num_planes==1, only index 0 of buf_data[] and buf_size[] exist,
3220 // but all 3 indices of data[] and linesize[] are available for yuv420p and 2 for nv12.
3221 // The same applies to both 8 and 10 bit pixel formats
3222 for (i = 0; i < num_planes; i++)
3223 {
3224 if (!data[i] || !buf_data[i] || buf_size[i] <= 0)
3225 {
3226 ni_log(NI_LOG_ERROR, "ERROR: %s: invalid parameter %d: data=%p, buf_data=%p, size=%d\n",
3227 __func__, i, data[i], buf_data[i], buf_size[i]);
3229 }
3230
3231 int plane_height = video_height >> (i > 0 ? 1 : 0);
3232
3233 // End of used data after filtering (e.g., cropping)
3234 if(num_planes == 1)
3235 {
3236 // Find end address used by last plane since it can reach the end of the buffer and buf_data[0] contains all YUV
3237 if (data[2])
3238 {
3239 // Planar pixel format if 3 data pointers are present
3240 end_used = data[2] + (ptrdiff_t)linesize[2] * (video_height >> 1);
3241 }
3242 else if (data[1])
3243 {
3244 // Semiplanar pixel format if only 2 data pointers are present
3245 end_used = data[1] + (ptrdiff_t)linesize[1] * (video_height >> 1);
3246 }
3247 else
3248 {
3249 ni_log(NI_LOG_ERROR, "ERROR: %s: Single-plane pixel format not supported\n", __func__);
3251 }
3252 }
3253 else
3254 {
3255 // Find Y, U, and V end address used
3256 end_used = data[i] + (ptrdiff_t)linesize[i] * plane_height;
3257 }
3258
3259 // End address of original allocated buffer.
3260 end_alloc = buf_data[i] + buf_size[i];
3261
3262 // Positive offset means filtered data to be transferred by zerocopy exceeds original buffer
3263 int plane_offset = (int)(end_used - end_alloc);
3264 plane_offset = (plane_offset > 0) ? plane_offset : 0;
3265
3266 if(num_planes == 1)
3267 {
3268 if (data[2])
3269 {
3270 offset = plane_offset * 2;
3271 ((uint8_t **)data)[0] -= offset;
3272 ((uint8_t **)data)[1] -= plane_offset;
3273 ((uint8_t **)data)[2] -= plane_offset;
3274 }
3275 else
3276 {
3277 offset = plane_offset;
3278 ((uint8_t **)data)[0] -= plane_offset;
3279 ((uint8_t **)data)[1] -= plane_offset;
3280 }
3281 }
3282 else
3283 {
3284 ((uint8_t **)data)[i] -= plane_offset;
3285 if (i == 0)
3286 {
3287 offset = plane_offset;
3288 }
3289 }
3290
3291 ni_log(NI_LOG_DEBUG, "%s: plane %d offset %d\n", __func__, i, offset);
3292 }
3293
3294 p_frame->hor_adjust_offset = offset;
3295
3296 return retval;
3297}
3298
3299/*!*****************************************************************************
3300 * \brief Allocate memory for encoder zero copy (metadata, etc.)
3301 * for encoding based on given
3302 * parameters, taking into account pic linesize and extra data.
3303 * Applicable to YUV planr / semi-planar 8 or 10 bit and RGBA pixel formats.
3304 *
3305 *
3306 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3307 * \param[in] video_width Width of the video frame
3308 * \param[in] video_height Height of the video frame
3309 * \param[in] linesize Picture line size
3310 * \param[in] data Picture data pointers (for each of YUV planes)
3311 * \param[in] extra_len Extra data size (incl. meta data)
3312 *
3313 * \return On success
3314 * NI_RETCODE_SUCCESS
3315 * On failure
3316 * NI_RETCODE_INVALID_PARAM
3317 * NI_RETCODE_ERROR_MEM_ALOC
3318 *****************************************************************************/
3320 int video_width, int video_height,
3321 const int linesize[], const uint8_t *data[],
3322 int extra_len)
3323{
3324 int retval = NI_RETCODE_SUCCESS;
3325
3326 if ((!p_frame) || (!linesize) || (!data))
3327 {
3328 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3329 "p_frame %p, linesize %p, data %p\n",
3330 __func__, p_frame, linesize, data);
3332 }
3333
3335 "%s: resolution=%dx%d linesize=%d/%d/%d "
3336 "data=%p %p %p extra_len=%d\n",
3337 __func__, video_width, video_height,
3338 linesize[0], linesize[1], linesize[2],
3339 data[0], data[1], data[2], extra_len);
3340
3341 if (p_frame->buffer_size)
3342 {
3343 p_frame->buffer_size = 0; //notify p_frame->p_buffer is not allocated
3344 ni_aligned_free(p_frame->p_buffer); // also free the temp p_buffer allocated for niFrameSurface1_t in encoder init stage
3345 }
3346
3347 p_frame->p_buffer = (uint8_t *)data[0];
3348 p_frame->p_data[0] = (uint8_t *)data[0];
3349 p_frame->p_data[1] = (uint8_t *)data[1];
3350 p_frame->p_data[2] = (uint8_t *)data[2];
3351
3352 int luma_size = linesize[0] * video_height;
3353 int chroma_b_size = 0;
3354 int chroma_r_size = 0;
3355
3356 // gstreamer assigns stride length to linesize[0] linesize[1] linesize[2] for RGBA pixel format, but only data[0] pointer is populated
3357 if (data[1]) // cb size is 0 for RGBA pixel format
3358 chroma_b_size = linesize[1] * (video_height / 2);
3359
3360 if (data[2]) // cr size is 0 for semi-planar or RGBA pixel format
3361 chroma_r_size = linesize[2] * (video_height / 2);
3362
3363 //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);
3364
3365 uint32_t start_offset;
3366 uint32_t total_start_len = 0;
3367 int i;
3368
3369 p_frame->inconsecutive_transfer = 0;
3370
3371 // rgba has one data pointer, semi-planar has two data pointers
3372 if ((data[1] && (data[0] + luma_size != data[1]))
3373 || (data[2] && (data[1] + chroma_b_size != data[2])))
3374 {
3375 p_frame->inconsecutive_transfer = 1;
3376 }
3377
3378 if (p_frame->inconsecutive_transfer)
3379 {
3380 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
3381 {
3382 start_offset = (uintptr_t)p_frame->p_data[i] % NI_MEM_PAGE_ALIGNMENT;
3383 p_frame->start_len[i] = start_offset ? (NI_MEM_PAGE_ALIGNMENT - start_offset) : 0;
3384 total_start_len += p_frame->start_len[i];
3385 }
3386 }
3387 else
3388 {
3389 start_offset = (uintptr_t)p_frame->p_data[0] % NI_MEM_PAGE_ALIGNMENT;
3390 p_frame->start_len[0] = start_offset ? (NI_MEM_PAGE_ALIGNMENT - start_offset) : 0;
3391 p_frame->start_len[1] = p_frame->start_len[2] = 0;
3392 total_start_len = p_frame->start_len[0];
3393 }
3394 p_frame->total_start_len = total_start_len;
3395
3396 if (ni_encoder_metadata_buffer_alloc(p_frame, extra_len))
3397 {
3398 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_metadata_buffer buffer.\n",
3399 NI_ERRNO, __func__);
3401 LRETURN;
3402 }
3403 p_frame->separate_metadata = 1;
3404
3405 if (total_start_len)
3406 {
3407 if (ni_encoder_start_buffer_alloc(p_frame))
3408 {
3409 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_start_buffer buffer.\n",
3410 NI_ERRNO, __func__);
3412 LRETURN;
3413 }
3414 p_frame->separate_start = 1;
3415
3416 // copy non-4k-aligned part at the start of YUV data
3417 int start_buffer_offset = 0;
3418 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
3419 {
3420 if (p_frame->p_data[i])
3421 {
3422 memcpy(p_frame->p_start_buffer+start_buffer_offset, p_frame->p_data[i],
3423 p_frame->start_len[i]);
3424 start_buffer_offset += (int)p_frame->start_len[i];
3425 }
3426 }
3427 }
3428
3429 p_frame->data_len[0] = luma_size;
3430 p_frame->data_len[1] = chroma_b_size;
3431 p_frame->data_len[2] = chroma_r_size;
3432 p_frame->data_len[3] = 0;//unused by hwdesc
3433
3434 p_frame->video_width = video_width;
3435 p_frame->video_height = video_height;
3436
3438 "%s: success: p_metadata_buffer %p metadata_buffer_size %u "
3439 "p_start_buffer %p start_buffer_size %u data_len %u %u %u\n",
3440 __func__, p_frame->p_metadata_buffer, p_frame->metadata_buffer_size,
3441 p_frame->p_start_buffer, p_frame->start_buffer_size,
3442 p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2]);
3443
3444END:
3445
3446 return retval;
3447}
3448
3449
3450/*!*****************************************************************************
3451 * \brief Check if incoming frame is hwupload zero copy compatible or not
3452 *
3453 * \param[in] p_upl_ctx pointer to uploader context
3454 * [in] width input width
3455 * [in] height input height
3456 * [in] linesize input linesizes (pointer to array)
3457 * [in] pixel_format input pixel format
3458 *
3459 * \return on success and can do zero copy
3460 * NI_RETCODE_SUCCESS
3461 *
3462 * cannot do zero copy
3463 * NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
3464 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
3465 * NI_RETCODE_INVALID_PARAM
3466 *
3467*******************************************************************************/
3469 int width, int height,
3470 const int linesize[], int pixel_format)
3471{
3472 // check pixel format / width / height / linesize can be supported
3473 if ((!p_upl_ctx) || (!linesize)
3474 || (linesize[0]<=0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3475 || (width>NI_MAX_RESOLUTION_WIDTH) || (width<=0)
3476 || (height>NI_MAX_RESOLUTION_HEIGHT) || (height<=0))
3477 {
3478 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s passed parameters are null or not supported, "
3479 "p_enc_ctx %p, linesize %p, "
3480 "width %d, height %d linesize[0] %d\n",
3481 __func__, p_upl_ctx, linesize,
3482 width, height, (linesize) ? linesize[0] : 0);
3484 }
3485
3486 // check fw revision (if fw_rev has been populated in open session)
3489 "6S") < 0))
3490 {
3491 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: not supported on device with FW API version < 6.S\n", __func__);
3493 }
3494
3495 // upload does not have zeroCopyMode parameter, currently only allows resolution >= 1080p
3496 if ((width * height) < NI_NUM_OF_PIXELS_1080P)
3498
3499 // check zero copy compatibilty
3500 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s pixel_format %d "
3501 "p_upl_ctx %p, linesize %p, "
3502 "width %d, height %d, linesize[0] %d\n",
3503 __func__, pixel_format, p_upl_ctx, linesize,
3504 width, height, linesize[0]);
3505
3506 int bit_depth_factor;
3507 bool isrgba = false;
3508 bool isplanar = false;
3509 bool issemiplanar = false;
3510
3511 switch (pixel_format)
3512 {
3513 case NI_PIX_FMT_YUV420P:
3514 isplanar = true;
3515 bit_depth_factor = 1;
3516 break;
3518 isplanar = true;
3519 bit_depth_factor = 2;
3520 break;
3521 case NI_PIX_FMT_NV12:
3522 issemiplanar = true;
3523 bit_depth_factor = 1;
3524 break;
3525 case NI_PIX_FMT_P010LE:
3526 issemiplanar = true;
3527 bit_depth_factor = 2;
3528 break;
3529 case NI_PIX_FMT_ABGR:
3530 case NI_PIX_FMT_ARGB:
3531 case NI_PIX_FMT_RGBA:
3532 case NI_PIX_FMT_BGRA:
3533 isrgba = true;
3534 bit_depth_factor = 4; // not accurate, only for linesize check
3535 break;
3536 default:
3537 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: pixel_format %d not supported\n", __func__);
3539 }
3540
3541 // check fw revision (if fw_rev has been populated in open session)
3542 if (issemiplanar &&
3545 "6q") < 0))
3546 {
3547 ni_log2(p_upl_ctx, NI_LOG_DEBUG, "%s: semi-planar not supported on device with FW API version < 6.q\n", __func__);
3549 }
3550
3551 int max_linesize = isrgba ? (NI_MAX_RESOLUTION_RGBA_WIDTH*4) : NI_MAX_RESOLUTION_LINESIZE;
3552 if (linesize[0] <= max_linesize &&
3553 width % 2 == 0 && //even width
3554 height % 2 == 0 && //even height
3555 width >= NI_MIN_WIDTH && height >= NI_MIN_HEIGHT)
3556 {
3557 // yuv only support default 128 bytes aligned linesize, because downstream filter or encoder expect HW frame 128 bytes aligned
3558 if (isplanar &&
3559 linesize[0] == NI_VPU_ALIGN128(width * bit_depth_factor) &&
3560 linesize[1] == NI_VPU_ALIGN128(width * bit_depth_factor / 2) &&
3561 linesize[2] == linesize[1])
3562 return NI_RETCODE_SUCCESS;
3563
3564 // yuv only support default 128 bytes aligned linesize, because downstream filter or encoder expect HW frame 128 bytes aligned
3565 if (issemiplanar &&
3566 linesize[0] == NI_VPU_ALIGN128(width * bit_depth_factor) &&
3567 linesize[1] == linesize[0])
3568 return NI_RETCODE_SUCCESS;
3569
3570 // rgba only support 64 bytes aligned for 2D
3571 if (isrgba &&
3572 linesize[0] == NI_VPU_ALIGN64(width * bit_depth_factor))
3573 return NI_RETCODE_SUCCESS;
3574 }
3575
3577}
3578
3579/*!*****************************************************************************
3580 * \brief Allocate memory for the frame buffer for encoding based on given
3581 * parameters, taking into account pic line size and extra data.
3582 * Applicable to YUV420p AVFrame only. 8 or 10 bit/pixel.
3583 * Cb/Cr size matches that of Y.
3584 *
3585 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3586 *
3587 * \param[in] video_width Width of the video frame
3588 * \param[in] video_height Height of the video frame
3589 * \param[in] linesize Picture line size
3590 * \param[in] alignment Allignment requirement
3591 * \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3592 * to allocate any buffer (zero-copy from existing)
3593 * \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3594 *
3595 * \return On success
3596 * NI_RETCODE_SUCCESS
3597 * On failure
3598 * NI_RETCODE_INVALID_PARAM
3599 * NI_RETCODE_ERROR_MEM_ALOC
3600 *****************************************************************************/
3602 int video_height, int linesize[],
3603 int alignment, int extra_len,
3604 bool alignment_2pass_wa)
3605{
3606 void* p_buffer = NULL;
3607 int height_aligned;
3608 int retval = NI_RETCODE_SUCCESS;
3609
3610 if ((!p_frame) || (!linesize) || (linesize[0]<=0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3611 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width<=0)
3612 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height<=0))
3613 {
3614 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3615 "p_frame %p, linesize %p, video_width %d, video_height %d\n",
3616 __func__, p_frame, linesize, video_width, video_height);
3618 }
3619
3620 if (QUADRA)
3621 {
3622 height_aligned = ((video_height + 1) / 2) * 2;
3623 } else
3624 {
3625 height_aligned = ((video_height + 7) / 8) * 8;
3626
3627 if (alignment)
3628 {
3629 height_aligned = ((video_height + 15) / 16) * 16;
3630 }
3631 }
3632 if (height_aligned < NI_MIN_HEIGHT)
3633 {
3634 height_aligned = NI_MIN_HEIGHT;
3635 }
3636
3638 "%s: aligned=%dx%d org=%dx%d linesize=%d/%d/%d "
3639 "extra_len=%d\n",
3640 __func__, video_width, height_aligned, video_width, video_height,
3641 linesize[0], linesize[1], linesize[2], extra_len);
3642
3643 int luma_size = linesize[0] * height_aligned;
3644 int chroma_b_size;
3645 int chroma_r_size;
3646 if (QUADRA)
3647 {
3648 chroma_b_size = chroma_r_size = linesize[1] * (height_aligned / 2);
3649 if (alignment_2pass_wa)
3650 {
3651 // for 2-pass encode output mismatch WA, need to extend (and pad) Cr plane height, because 1st pass assume input 32 align
3652 chroma_r_size = linesize[1] * (((height_aligned + 31) / 32) * 32) / 2;
3653 }
3654 //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);
3655 }
3656 else
3657 {
3658 chroma_b_size = luma_size / 4;
3659 chroma_r_size = luma_size / 4;
3660 }
3661 if(extra_len >= 0)
3662 {
3663 int buffer_size = luma_size + chroma_b_size + chroma_r_size + extra_len;
3664
3666
3667 //Check if Need to free
3668 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
3669 {
3671 "%s: free current p_frame, "
3672 "p_frame->buffer_size=%u\n",
3673 __func__, p_frame->buffer_size);
3674 ni_frame_buffer_free(p_frame);
3675 }
3676
3677 //Check if need to realocate
3678 if (p_frame->buffer_size != buffer_size)
3679 {
3680 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3681 {
3682 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
3683 NI_ERRNO, __func__);
3685 LRETURN;
3686 }
3687
3688 // init once after allocation
3689 memset(p_buffer, 0, buffer_size);
3690 p_frame->buffer_size = buffer_size;
3691 p_frame->p_buffer = p_buffer;
3692
3693 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
3694 }
3695 else
3696 {
3697 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
3698 }
3699 p_frame->p_data[0] = (uint8_t*)p_frame->p_buffer;
3700 p_frame->p_data[1] = (uint8_t*)p_frame->p_data[0] + luma_size;
3701 p_frame->p_data[2] = (uint8_t*)p_frame->p_data[1] + chroma_b_size;
3702 }
3703 else
3704 {
3705 p_frame->buffer_size = 0; //no ownership
3706 }
3707
3708 p_frame->data_len[0] = luma_size;
3709 p_frame->data_len[1] = chroma_b_size;
3710 p_frame->data_len[2] = chroma_r_size;
3711 p_frame->data_len[3] = 0;//unused by hwdesc
3712
3713 p_frame->video_width = video_width;
3714 p_frame->video_height = height_aligned;
3715
3717 "%s: success: p_frame->p_buffer %p "
3718 "p_frame->buffer_size=%u\n",
3719 __func__, p_frame->p_buffer, p_frame->buffer_size);
3720
3721END:
3722
3723 if (NI_RETCODE_SUCCESS != retval)
3724 {
3725 ni_aligned_free(p_buffer);
3726 }
3727
3728 return retval;
3729}
3730
3731/*!*****************************************************************************
3732 * \brief allocate device destination frame from scaler hwframe pool
3733 *
3734 * \param
3735 *
3736 * \return 0 if successful, < 0 otherwise
3737 ******************************************************************************/
3739 ni_scaler_input_params_t scaler_params,
3740 niFrameSurface1_t *p_surface)
3741{
3742 int ret = 0;
3743 if (scaler_params.op != NI_SCALER_OPCODE_OVERLAY && scaler_params.op != NI_SCALER_OPCODE_WATERMARK)
3744 {
3746 p_ctx, scaler_params.output_width, scaler_params.output_height,
3747 scaler_params.output_format, NI_SCALER_FLAG_IO | scaler_params.out_extra_flags,
3748 scaler_params.out_rec_width, scaler_params.out_rec_height,
3749 scaler_params.out_rec_x, scaler_params.out_rec_y,
3750 (int)scaler_params.rgba_color, -1, NI_DEVICE_TYPE_SCALER);
3751 } else
3752 {
3753 // in vf_overlay_ni.c: flags = (s->alpha_format ? NI_SCALER_FLAG_PA : 0) | NI_SCALER_FLAG_IO;
3755 p_ctx, scaler_params.output_width, scaler_params.output_height,
3756 scaler_params.output_format, NI_SCALER_FLAG_IO | scaler_params.out_extra_flags,
3757 scaler_params.out_rec_width, scaler_params.out_rec_height,
3758 scaler_params.out_rec_x, scaler_params.out_rec_y,
3759 (int)p_surface->ui32nodeAddress, (int)p_surface->ui16FrameIdx, // NOLINT(bugprone-narrowing-conversions)
3761 }
3762 return ret;
3763}
3764
3765/*!*****************************************************************************
3766 * \brief allocate device input frame by hw descriptor. This call won't actually allocate
3767 a frame but sends the incoming hardware frame index to the scaler manager
3768 *
3769 * \param
3770 *
3771 * \return 0 if successful, < 0 otherwise
3772 ******************************************************************************/
3774 ni_scaler_input_params_t scaler_params,
3775 niFrameSurface1_t *p_src_surface)
3776{
3777 int ret = 0;
3778
3779 /* BT.2020 not supported on scaler input */
3780 if (scaler_params.in_extra_flags & NI_SCALER_FLAG_CS)
3782
3784 p_ctx, scaler_params.input_width, scaler_params.input_height,
3785 scaler_params.input_format, scaler_params.in_extra_flags, scaler_params.in_rec_width,
3786 scaler_params.in_rec_height, scaler_params.in_rec_x,
3787 (int)scaler_params.in_rec_y, (int)p_src_surface->ui32nodeAddress, // NOLINT(bugprone-narrowing-conversions)
3788 p_src_surface->ui16FrameIdx, NI_DEVICE_TYPE_SCALER);
3789 return ret;
3790}
3791
3792/*!*****************************************************************************
3793 * \brief init output pool of scaler frames
3794 *
3795 * \param
3796 *
3797 * \return 0 if successful, < 0 otherwise
3798 ******************************************************************************/
3800 ni_scaler_input_params_t scaler_params)
3801{
3802 int rc = 0;
3803 int options = NI_SCALER_FLAG_IO | NI_SCALER_FLAG_PC;
3804 if (p_ctx->isP2P)
3805 options |= NI_SCALER_FLAG_P2;
3806
3807 /* Allocate a pool of frames by the scaler */
3808 rc = ni_device_alloc_frame(p_ctx, scaler_params.output_width,
3809 scaler_params.output_height,
3810 scaler_params.output_format, options,
3811 0, // rec width
3812 0, // rec height
3813 0, // rec X pos
3814 0, // rec Y pos
3815 NI_MAX_FILTER_POOL_SIZE, // rgba color/pool size
3816 0, // frame index
3818 return rc;
3819}
3820
3821/*!*****************************************************************************
3822* \brief Allocate memory for the frame buffer based on provided parameters
3823* taking into account pic line size and extra data.
3824* Applicable to nv12 AVFrame only. Cb/Cr size matches that of Y.
3825*
3826* \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3827*
3828* \param[in] video_width Width of the video frame
3829* \param[in] video_height Height of the video frame
3830* \param[in] linesize Picture line size
3831* \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3832* to allocate any buffer (zero-copy from existing)
3833* \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3834*
3835* \return On success
3836* NI_RETCODE_SUCCESS
3837* On failure
3838* NI_RETCODE_INVALID_PARAM
3839* NI_RETCODE_ERROR_MEM_ALOC
3840*****************************************************************************/
3842 int video_height, int linesize[],
3843 int extra_len, bool alignment_2pass_wa)
3844{
3845 void* p_buffer = NULL;
3846 int height_aligned;
3847 int retval = NI_RETCODE_SUCCESS;
3848
3849 if ((!p_frame) || (!linesize) || (linesize[0] <= 0) || (linesize[0]>NI_MAX_RESOLUTION_LINESIZE)
3850 || (video_width>NI_MAX_RESOLUTION_WIDTH) || (video_width <= 0)
3851 || (video_height>NI_MAX_RESOLUTION_HEIGHT) || (video_height <= 0))
3852 {
3853 ni_log(NI_LOG_ERROR, "ERROR: %s passed parameters are null or not supported, "
3854 "p_frame %p, linesize %p, video_width %d, video_height %d\n",
3855 __func__, p_frame, linesize, video_width, video_height);
3857 }
3858
3859 height_aligned = ((video_height + 1) / 2) * 2;
3860
3861 if (height_aligned < NI_MIN_HEIGHT)
3862 {
3863 height_aligned = NI_MIN_HEIGHT;
3864 }
3865
3867 "%s: aligned=%dx%d org=%dx%d linesize=%d/%d/%d extra_len=%d\n",
3868 __func__, video_width, height_aligned, video_width, video_height,
3869 linesize[0], linesize[1], linesize[2], extra_len);
3870
3871 int luma_size = linesize[0] * height_aligned;
3872 int chroma_br_size = luma_size / 2;
3873 //int chroma_r_size = luma_size / 4;
3874 if (alignment_2pass_wa)
3875 {
3876 // for 2-pass encode output mismatch WA, need to extend (and pad) CbCr plane height, because 1st pass assume input 32 align
3877 chroma_br_size = linesize[0] * ((((height_aligned + 31) / 32) * 32) / 2);
3878 }
3879 if (extra_len >= 0)
3880 {
3881 int buffer_size = luma_size + chroma_br_size + extra_len;
3882
3884
3885 //Check if Need to free
3886 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
3887 {
3888 ni_log(NI_LOG_DEBUG, "%s: free current p_frame->buffer_size=%u\n",
3889 __func__, p_frame->buffer_size);
3890 ni_frame_buffer_free(p_frame);
3891 }
3892
3893 //Check if need to realocate
3894 if (p_frame->buffer_size != buffer_size)
3895 {
3896 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3897 {
3898 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
3899 NI_ERRNO, __func__);
3901 LRETURN;
3902 }
3903
3904 // init once after allocation
3905 memset(p_buffer, 0, buffer_size);
3906 p_frame->buffer_size = buffer_size;
3907 p_frame->p_buffer = p_buffer;
3908
3909 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
3910 }
3911 else
3912 {
3913 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
3914 }
3915
3916 p_frame->p_data[0] = (uint8_t*)p_frame->p_buffer;
3917 p_frame->p_data[1] = (uint8_t*)p_frame->p_data[0] + luma_size;
3918 p_frame->p_data[2] = (uint8_t*)p_frame->p_data[1] + chroma_br_size;
3919 }
3920 else
3921 {
3922 p_frame->buffer_size = 0; //no ownership
3923 }
3924 p_frame->data_len[0] = luma_size;
3925 p_frame->data_len[1] = chroma_br_size;
3926 p_frame->data_len[2] = 0;
3927
3928 p_frame->video_width = video_width;
3929 p_frame->video_height = height_aligned;
3930
3931 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
3932 p_frame->buffer_size);
3933
3934END:
3935
3936 if (NI_RETCODE_SUCCESS != retval)
3937 {
3938 ni_aligned_free(p_buffer);
3939 }
3940
3941 return retval;
3942}
3943
3944/*!*****************************************************************************
3945 * \brief This API is a wrapper for ni_encoder_frame_buffer_alloc(), used
3946 * for planar pixel formats, and ni_frame_buffer_alloc_nv(), used for
3947 * semi-planar pixel formats. This API is meant to combine the
3948 * functionality for both individual format APIs.
3949 * Allocate memory for the frame buffer for encoding based on given
3950 * parameters, taking into account pic line size and extra data.
3951 * Applicable to YUV420p(8 or 10 bit/pixel) or nv12 AVFrame.
3952 * Cb/Cr size matches that of Y.
3953 *
3954 * \param[in] planar true: if planar:
3955 * pixel_format == (NI_PIX_FMT_YUV420P ||
3956 * NI_PIX_FMT_YUV420P10LE ||NI_PIX_FMT_RGBA).
3957 * false: semi-planar:
3958 * pixel_format == (NI_PIX_FMT_NV12 ||
3959 * NI_PIX_FMT_P010LE).
3960 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
3961 * \param[in] video_width Width of the video frame
3962 * \param[in] video_height Height of the video frame
3963 * \param[in] linesize Picture line size
3964 * \param[in] alignment Allignment requirement. Only used for planar format.
3965 * \param[in] extra_len Extra data size (incl. meta data). < 0 means not
3966 * to allocate any buffer (zero-copy from existing)
3967 * \param[in] alignment_2pass_wa set alignment to work with 2pass encode
3968 *
3969 * \return On success
3970 * NI_RETCODE_SUCCESS
3971 * On failure
3972 * NI_RETCODE_INVALID_PARAM
3973 * NI_RETCODE_ERROR_MEM_ALOC
3974 *****************************************************************************/
3976 int video_width, int video_height,
3977 int linesize[], int alignment,
3978 int extra_len,
3979 bool alignment_2pass_wa)
3980{
3981 if (true == planar)
3982 {
3983 return ni_encoder_frame_buffer_alloc(p_frame, video_width, video_height,
3984 linesize, alignment, extra_len,
3985 alignment_2pass_wa);
3986 }
3987 else
3988 {
3989 return ni_frame_buffer_alloc_nv(p_frame, video_width, video_height,
3990 linesize, extra_len,
3991 alignment_2pass_wa);
3992 }
3993}
3994
3995/*!*****************************************************************************
3996 * \brief Free frame buffer that was previously allocated with either
3997 * ni_frame_buffer_alloc or ni_encoder_frame_buffer_alloc or
3998 * ni_frame_buffer_alloc_nv
3999 *
4000 * \param[in] p_frame Pointer to a previously allocated ni_frame_t struct
4001 *
4002 * \return On success NI_RETCODE_SUCCESS
4003 * On failure NI_RETCODE_INVALID_PARAM
4004 ******************************************************************************/
4006{
4007 int i;
4009
4010 ni_log(NI_LOG_TRACE, "%s: enter\n", __func__);
4011
4012 if (!p_frame)
4013 {
4014 ni_log(NI_LOG_DEBUG, "WARN: %s(): p_frame is NULL\n", __func__);
4015 LRETURN;
4016 }
4017
4018 if (!p_frame->p_buffer)
4019 {
4020 ni_log(NI_LOG_DEBUG, "WARN: %s(): already freed, nothing to free\n",
4021 __func__);
4022 }
4023
4024#ifndef _WIN32
4025 // If this is a hardware frame with a DMA buf fd attached, close the DMA buf fd
4026 if ((p_frame->data_len[3] > 0) && (p_frame->p_data[3] != NULL))
4027 {
4028 niFrameSurface1_t *p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
4029 if ((p_surface->dma_buf_fd > 0) && (p_surface->ui16FrameIdx > 0))
4030 {
4031 // Close the DMA buf fd
4033 "%s: close p_surface->dma_buf_fd %d "
4034 "ui16FrameIdx %u\n",
4035 __func__, p_surface->dma_buf_fd, p_surface->ui16FrameIdx);
4036 (void)close(p_surface->dma_buf_fd);
4037 }
4038 }
4039#endif
4040
4041 if (p_frame->buffer_size)
4042 {
4043 p_frame->buffer_size = 0;
4044 ni_aligned_free(p_frame->p_buffer);
4045 }
4046
4047 for (i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
4048 {
4049 p_frame->data_len[i] = 0;
4050 p_frame->p_data[i] = NULL;
4051 }
4052
4053 ni_frame_wipe_aux_data(p_frame);
4054
4055 if (p_frame->metadata_buffer_size)
4056 {
4057 p_frame->metadata_buffer_size = 0;
4059 }
4060 p_frame->separate_metadata = 0;
4061
4062 if (p_frame->start_buffer_size)
4063 {
4064 p_frame->start_buffer_size = 0;
4066 }
4067 p_frame->separate_start = 0;
4068 memset(p_frame->start_len, 0, sizeof(p_frame->start_len));
4069 p_frame->total_start_len = 0;
4070 p_frame->inconsecutive_transfer = 0;
4071
4072END:
4073
4074 ni_log(NI_LOG_TRACE, "%s: exit\n", __func__);
4075
4076 return retval;
4077}
4078
4079/*!*****************************************************************************
4080 * \brief Free decoder frame buffer that was previously allocated with
4081 * ni_decoder_frame_buffer_alloc, returning memory to a buffer pool.
4082 *
4083 * \param[in] p_frame Pointer to a previously allocated ni_frame_t struct
4084 *
4085 * \return On success NI_RETCODE_SUCCESS
4086 * On failure NI_RETCODE_INVALID_PARAM
4087 ******************************************************************************/
4089{
4090 int i;
4092
4093 ni_log(NI_LOG_TRACE, "%s: enter\n", __func__);
4094
4095 if (!p_frame)
4096 {
4097 ni_log(NI_LOG_DEBUG, "WARN: %s(): p_frame is NULL\n", __func__);
4098 retval = NI_RETCODE_INVALID_PARAM;
4099 LRETURN;
4100 }
4101
4102 if (p_frame->dec_buf)
4103 {
4105 ni_log(NI_LOG_DEBUG, "%s(): Mem buf returned ptr %p buf %p !\n", __func__,
4106 p_frame->dec_buf->buf, p_frame->dec_buf);
4107 }
4108 else
4109 {
4110 ni_log(NI_LOG_DEBUG, "%s(): NO mem buf returned !\n", __func__);
4111 }
4112
4113 p_frame->dec_buf = NULL;
4114 p_frame->p_buffer = NULL;
4115 p_frame->buffer_size = 0;
4116 for (i = 0; i < NI_MAX_NUM_DATA_POINTERS; i++)
4117 {
4118 p_frame->data_len[i] = 0;
4119 p_frame->p_data[i] = NULL;
4120 }
4121 ni_frame_wipe_aux_data(p_frame);
4122
4123END:
4124
4125 ni_log(NI_LOG_TRACE, "%s: exit\n", __func__);
4126
4127 return retval;
4128}
4129
4130/*!*****************************************************************************
4131 * \brief Return a memory buffer to memory buffer pool.
4132 *
4133 * \param[in] buf Buffer to be returned.
4134 * \param[in] p_buffer_pool Buffer pool to return buffer to.
4135 *
4136 * \return None
4137 ******************************************************************************/
4139 ni_buf_pool_t *p_buffer_pool)
4140{
4141 ni_buf_pool_return_buffer(buf, p_buffer_pool);
4142}
4143
4144/*!*****************************************************************************
4145 * \brief Allocate memory for the packet buffer based on provided packet size
4146 *
4147 * \param[in] p_packet Pointer to a caller allocated
4148 * ni_packet_t struct
4149 * \param[in] packet_size Required allocation size
4150 *
4151 * \return On success
4152 * NI_RETCODE_SUCCESS
4153 * On failure
4154 * NI_RETCODE_INVALID_PARAM
4155 * NI_RETCODE_ERROR_MEM_ALOC
4156 ******************************************************************************/
4158{
4159 void* p_buffer = NULL;
4160 int metadata_size = 0;
4161
4162 metadata_size = NI_FW_META_DATA_SZ;
4163
4164 int buffer_size = (((packet_size + metadata_size) / NI_MAX_PACKET_SZ) + 1) * NI_MAX_PACKET_SZ;
4165
4166 ni_log(NI_LOG_TRACE, "%s: packet_size=%d\n", __func__,
4167 packet_size + metadata_size);
4168
4169 if (!p_packet || !packet_size)
4170 {
4171 ni_log(NI_LOG_ERROR, "ERROR: %s: null pointer parameters passed\n",
4172 __func__);
4174 }
4175
4176 if (buffer_size % NI_MEM_PAGE_ALIGNMENT)
4177 {
4178 buffer_size = ( (buffer_size / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT ) + NI_MEM_PAGE_ALIGNMENT;
4179 }
4180
4181 if (p_packet->buffer_size == buffer_size)
4182 {
4183 // Already allocated the exact size.
4184 p_packet->p_data = p_packet->p_buffer;
4185 ni_log(NI_LOG_DEBUG, "%s: reuse current p_packet buffer\n", __func__);
4186 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4187 p_packet->buffer_size);
4188 return NI_RETCODE_SUCCESS;
4189 }
4190
4191 if (p_packet->buffer_size)
4192 {
4194 "%s: free current p_packet, p_packet->buffer_size=%u\n", __func__,
4195 p_packet->buffer_size);
4196 ni_packet_buffer_free(p_packet);
4197 }
4198
4199 ni_log(NI_LOG_DEBUG, "%s: Allocating p_frame buffer, buffer_size=%d\n",
4200 __func__, buffer_size);
4201
4202 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
4203 {
4204 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_packet buffer.\n",
4205 NI_ERRNO, __func__);
4206 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4207 p_packet->buffer_size);
4209 }
4210
4211 p_packet->buffer_size = buffer_size;
4212 p_packet->p_buffer = p_buffer;
4213 p_packet->p_data = p_packet->p_buffer;
4214
4215 ni_log(NI_LOG_TRACE, "%s: exit: p_packet->buffer_size=%u\n", __func__,
4216 p_packet->buffer_size);
4217
4218 return NI_RETCODE_SUCCESS;
4219}
4220
4221/*!*****************************************************************************
4222 * \brief Allocate packet buffer using a user provided pointer, the memory
4223 * is expected to have already been allocated.
4224 *
4225 * For ideal performance memory should be 4k aligned. If it is not 4K aligned
4226 * then a temporary 4k aligned memory will be used to copy data to and from
4227 * when writing and reading. This will negatively impact performance.
4228 *
4229 * This API will overwrite p_packet->buffer_size, p_packet->p_buffer and
4230 * p_packet->p_data fields in p_packet.
4231 *
4232 * This API will not free any memory associated with p_packet->p_buffer and
4233 * p_packet->p_data fields in p_packet.
4234 * Common use case could be,
4235 * 1. Allocate memory to pointer
4236 * 2. Call ni_custom_packet_buffer_alloc() with allocated pointer.
4237 * 3. Use p_packet as required.
4238 * 4. Call ni_packet_buffer_free() to free up the memory.
4239 *
4240 * \param[in] p_buffer User provided pointer to be used for buffer
4241 * \param[in] p_packet Pointer to a caller allocated
4242 * ni_packet_t struct
4243 * \param[in] buffer_size Buffer size
4244 *
4245 * \return On success
4246 * NI_RETCODE_SUCCESS
4247 * On failure
4248 * NI_RETCODE_INVALID_PARAM
4249 * NI_RETCODE_ERROR_MEM_ALOC
4250 ******************************************************************************/
4252 ni_packet_t *p_packet,
4253 int buffer_size)
4254{
4255 ni_log(NI_LOG_TRACE, "%s(): enter buffer_size=%d\n", __func__, buffer_size);
4256
4257 if (!p_buffer || !p_packet || !buffer_size)
4258 {
4259 ni_log(NI_LOG_ERROR, "ERROR: %s: null pointer parameters passed\n",
4260 __func__);
4262 }
4263 if (((uintptr_t)p_buffer) % NI_MEM_PAGE_ALIGNMENT)
4264 {
4265 ni_log(NI_LOG_INFO, "Info: %s: Warning buffer not 4k aligned = %p!. Will do an extra copy\n",
4266 __func__, p_buffer);
4267 }
4268
4269 p_packet->buffer_size = buffer_size;
4270 p_packet->p_buffer = p_buffer;
4271 p_packet->p_data = p_packet->p_buffer;
4272
4273 ni_log(NI_LOG_TRACE, "%s: exit: \n", __func__);
4274
4275 return NI_RETCODE_SUCCESS;
4276}
4277
4278/*!*****************************************************************************
4279 * \brief Free packet buffer that was previously allocated with
4280 * ni_packet_buffer_alloc
4281 *
4282 * \param[in] p_packet Pointer to a previously allocated ni_packet_t struct
4283 *
4284 * \return On success NI_RETCODE_SUCCESS
4285 * On failure NI_RETCODE_INVALID_PARAM
4286 ******************************************************************************/
4288{
4290
4291 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
4292
4293 if (!p_packet)
4294 {
4295 ni_log(NI_LOG_ERROR, "ERROR: %s(): p_packet is NULL\n", __func__);
4296 retval = NI_RETCODE_FAILURE;
4297 LRETURN;
4298 }
4299
4300 if (!p_packet->p_buffer)
4301 {
4302 ni_log(NI_LOG_DEBUG, "%s(): already freed, nothing to free\n", __func__);
4303 LRETURN;
4304 }
4305
4306 ni_aligned_free(p_packet->p_buffer);
4307 p_packet->p_buffer = NULL;
4308 p_packet->buffer_size = 0;
4309 p_packet->data_len = 0;
4310 p_packet->p_data = NULL;
4311
4312 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
4313
4314END:
4315
4316 return retval;
4317}
4318
4319/*!*****************************************************************************
4320 * \brief Free packet buffer that was previously allocated with
4321 * ni_packet_buffer_alloc for AV1 packets merge
4322 *
4323 * \param[in] p_packet Pointer to a previously allocated ni_packet_t struct
4324 *
4325 * \return On success NI_RETCODE_SUCCESS
4326 * On failure NI_RETCODE_INVALID_PARAM
4327 ******************************************************************************/
4329{
4330 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
4332 int i;
4333
4334 if (!p_packet)
4335 {
4336 ni_log(NI_LOG_ERROR, "ERROR: %s(): p_packet is NULL\n", __func__);
4337 retval = NI_RETCODE_FAILURE;
4338 LRETURN;
4339 }
4340
4341 if (!p_packet->av1_buffer_index)
4342 {
4344 "%s(): no need to free previous av1 packet buffers\n", __func__);
4345 LRETURN;
4346 }
4347
4348 for (i = 0; i < p_packet->av1_buffer_index; i++)
4349 {
4350 ni_log(NI_LOG_DEBUG, "%s(): free previous av1 packet buffer %d\n",
4351 __func__, i);
4352 ni_aligned_free(p_packet->av1_p_buffer[i]);
4353 p_packet->av1_p_buffer[i] = NULL;
4354 p_packet->av1_p_data[i] = NULL;
4355 p_packet->av1_buffer_size[i] = 0;
4356 p_packet->av1_data_len[i] = 0;
4357 }
4358
4359 p_packet->av1_buffer_index = 0;
4360
4361END:
4362
4363 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
4364
4365 return retval;
4366}
4367
4368/*!*****************************************************************************
4369 * \brief Copy video packet accounting for alignment
4370 *
4371 * \param[in] p_destination Destination to where to copy to
4372 * \param[in] p_source Source from where to copy from
4373 * \param[in] cur_size current size
4374 * \param[out] p_leftover Pointer to the data that was left over
4375 * \param[out] p_prev_size Size of the data leftover ??
4376 *
4377 * \return On success Total number of bytes that were copied
4378 * On failure NI_RETCODE_FAILURE
4379 ******************************************************************************/
4380int ni_packet_copy(void* p_destination, const void* const p_source, int cur_size, void* p_leftover, int* p_prev_size)
4381{
4382 int copy_size = 0;
4383 int padding_size = 0;
4384 int prev_size = p_prev_size == NULL? 0 : *p_prev_size;
4385
4386 int total_size = cur_size + prev_size;
4387 uint8_t* p_src = (uint8_t*)p_source;
4388 uint8_t* p_dst = (uint8_t*)p_destination;
4389 uint8_t* p_lftover = (uint8_t*)p_leftover;
4390
4391 if (!p_prev_size)
4392 {
4394 }
4395
4396 ni_log(NI_LOG_TRACE, "%s(): enter, *prev_size=%d\n", __func__, *p_prev_size);
4397
4398 if ((0 == cur_size) && (0 == prev_size))
4399 {
4400 return copy_size;
4401 }
4402
4403 if (((0 != cur_size) && (!p_source)) || (!p_destination) || (!p_leftover))
4404 {
4405 return NI_RETCODE_FAILURE;
4406 }
4407
4408 copy_size = ((total_size + NI_MEM_PAGE_ALIGNMENT - 1) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
4409
4410 if (copy_size > total_size)
4411 {
4412 padding_size = copy_size - total_size;
4413 }
4414
4415 if (prev_size > 0)
4416 {
4417 memcpy(p_dst, p_lftover, prev_size);
4418 }
4419
4420 p_dst += prev_size;
4421
4422 memcpy(p_dst, p_src, cur_size);
4423
4424 if (padding_size)
4425 {
4426 p_dst += cur_size;
4427 memset(p_dst, 0, padding_size);
4428 }
4429
4431 "%s(): exit, cur_size=%d, copy_size=%d, "
4432 "prev_size=%d, padding_size=%d\n", __func__, cur_size,
4433 copy_size, *p_prev_size, padding_size);
4434
4435 *p_prev_size = 0;
4436
4437 return copy_size;
4438}
4439
4440/*!*****************************************************************************
4441 * \brief Add a new auxiliary data to a frame
4442 *
4443 * \param[in/out] frame a frame to which the auxiliary data should be added
4444 * \param[in] type type of the added auxiliary data
4445 * \param[in] data_size size of the added auxiliary data
4446 *
4447 * \return a pointer to the newly added aux data on success, NULL otherwise
4448 ******************************************************************************/
4450 int data_size)
4451{
4452 ni_aux_data_t *ret;
4453
4455 {
4456 ni_log(NI_LOG_ERROR, "ERROR: %s exceeding max aux_data number !\n",
4457 __func__);
4458 return NULL;
4459 }
4460
4461 ret = malloc(sizeof(ni_aux_data_t));
4462 if (!ret)
4463 {
4464 ni_log(NI_LOG_ERROR, "ERROR: %s No memory !\n", __func__);
4465 return NULL;
4466 }
4467
4468 ret->type = type;
4469 ret->size = data_size;
4470 ret->data = calloc(1, data_size);
4471 if (!ret->data)
4472 {
4473 ni_log(NI_LOG_ERROR, "ERROR: %s No memory for aux data !\n", __func__);
4474 free(ret);
4475 ret = NULL;
4476 } else
4477 {
4478 frame->aux_data[frame->nb_aux_data++] = ret;
4479 }
4480
4481 return ret;
4482}
4483
4484/*!*****************************************************************************
4485 * \brief Add a new auxiliary data to a frame and copy in the raw data
4486 *
4487 * \param[in/out] frame a frame to which the auxiliary data should be added
4488 * \param[in] type type of the added auxiliary data
4489 * \param[in] raw_data the raw data of the aux data
4490 * \param[in] data_size size of the added auxiliary data
4491 *
4492 * \return a pointer to the newly added aux data on success, NULL otherwise
4493 ******************************************************************************/
4495 ni_aux_data_type_t type,
4496 const uint8_t *raw_data,
4497 int data_size)
4498{
4499 ni_aux_data_t *ret = ni_frame_new_aux_data(frame, type, data_size);
4500 if (ret)
4501 {
4502 memcpy(ret->data, raw_data, data_size);
4503 }
4504 return ret;
4505}
4506
4507/*!*****************************************************************************
4508 * \brief Retrieve from the frame auxiliary data of a given type if exists
4509 *
4510 * \param[in] frame a frame from which the auxiliary data should be retrieved
4511 * \param[in] type type of the auxiliary data to be retrieved
4512 *
4513 * \return a pointer to the aux data of a given type on success, NULL otherwise
4514 ******************************************************************************/
4516 ni_aux_data_type_t type)
4517{
4518 int i;
4519 for (i = 0; i < frame->nb_aux_data; i++)
4520 {
4521 if (frame->aux_data[i]->type == type)
4522 {
4523 return frame->aux_data[i];
4524 }
4525 }
4526 return NULL;
4527}
4528
4529/*!*****************************************************************************
4530 * \brief If auxiliary data of the given type exists in the frame, free it
4531 * and remove it from the frame.
4532 *
4533 * \param[in/out] frame a frame from which the auxiliary data should be removed
4534 * \param[in] type type of the auxiliary data to be removed
4535 *
4536 * \return None
4537 ******************************************************************************/
4539{
4540 int i;
4541 ni_aux_data_t *aux;
4542
4543 for (i = 0; i < frame->nb_aux_data; i++)
4544 {
4545 aux = frame->aux_data[i];
4546 if (aux->type == type)
4547 {
4548 frame->aux_data[i] = frame->aux_data[frame->nb_aux_data - 1];
4549 frame->aux_data[frame->nb_aux_data - 1] = NULL;
4550 frame->nb_aux_data--;
4551 free(aux->data);
4552 free(aux);
4553 }
4554 }
4555}
4556
4557/*!*****************************************************************************
4558 * \brief Free and remove all auxiliary data from the frame.
4559 *
4560 * \param[in/out] frame a frame from which the auxiliary data should be removed
4561 *
4562 * \return None
4563 ******************************************************************************/
4565{
4566 int i;
4567 ni_aux_data_t *aux;
4568
4569 for (i = 0; i < frame->nb_aux_data; i++)
4570 {
4571 aux = frame->aux_data[i];
4572 free(aux->data);
4573 free(aux);
4574 }
4575 frame->nb_aux_data = 0;
4576}
4577
4578/*!*****************************************************************************
4579 * \brief Initialize default encoder parameters
4580 *
4581 * \param[out] param Pointer to a user allocated ni_xcoder_params_t
4582 * to initialize to default parameters
4583 * \param[in] fps_num Frames per second
4584 * \param[in] fps_denom FPS denomination
4585 * \param[in] bit_rate bit rate
4586 * \param[in] width frame width
4587 * \param[in] height frame height
4588 * \param[in] codec_format codec from ni_codec_format_t
4589 *
4590 * \return On success
4591 * NI_RETCODE_SUCCESS
4592 * On failure
4593 * NI_RETCODE_FAILURE
4594 * NI_RETCODE_INVALID_PARAM
4595 ******************************************************************************/
4597 int fps_num, int fps_denom,
4598 long bit_rate, int width,
4599 int height,
4600 ni_codec_format_t codec_format)
4601{
4602 ni_encoder_cfg_params_t *p_enc = NULL;
4603 int i = 0, j = 0;
4605
4606 //Initialize p_param structure
4607 if (!p_param)
4608 {
4609 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameters passed\n",
4610 __func__);
4611 retval = NI_RETCODE_INVALID_PARAM;
4612 LRETURN;
4613 }
4614
4615 ni_log(NI_LOG_DEBUG, "%s()\n", __func__);
4616
4617 //Initialize p_param structure
4618 memset(p_param, 0, sizeof(ni_xcoder_params_t));
4619
4620 p_enc = &p_param->cfg_enc_params;
4621
4622 // Rev. B: unified for HEVC/H.264
4623 p_enc->profile = 0;
4624 p_enc->level_idc = 0;
4625 p_enc->high_tier = 0;
4626
4627 if (QUADRA)
4629 else
4631
4632 p_enc->use_recommend_enc_params = 0;
4633 p_enc->cu_size_mode = 7;
4634 p_enc->max_num_merge = 2;
4635 p_enc->enable_dynamic_8x8_merge = 1;
4636 p_enc->enable_dynamic_16x16_merge = 1;
4637 p_enc->enable_dynamic_32x32_merge = 1;
4638
4639 p_enc->rc.trans_rate = 0;
4640
4641 p_enc->rc.enable_rate_control = 0;
4642 if (QUADRA)
4644 else
4646 p_enc->rc.enable_hvs_qp = 0;
4647 p_enc->rc.enable_hvs_qp_scale = 1;
4648 p_enc->rc.hvs_qp_scale = 2;
4649 p_enc->rc.min_qp = 8;
4650 p_enc->rc.max_qp = 51;
4651 p_enc->rc.max_delta_qp = 10;
4652
4653 // hrd is disabled if vbv_buffer_size=0, hrd is enabled if vbv_buffer_size is [10, 3000]
4654 p_enc->rc.vbv_buffer_size = -1;
4655 p_enc->rc.enable_filler = 0;
4656 p_enc->rc.enable_pic_skip = 0;
4657 p_enc->rc.vbv_max_rate = 0;
4658
4659 p_enc->roi_enable = 0;
4660
4662 // feature not supported on JPEG/AV1 - disable by default
4663 if (codec_format == NI_CODEC_FORMAT_JPEG ||
4664 codec_format == NI_CODEC_FORMAT_AV1)
4665 {
4667 }
4668
4669 p_enc->long_term_ref_enable = 0;
4670 p_enc->long_term_ref_interval = 0;
4671 p_enc->long_term_ref_count = 2;
4672
4673 p_enc->conf_win_top = 0;
4674 p_enc->conf_win_bottom = 0;
4675 p_enc->conf_win_left = 0;
4676 p_enc->conf_win_right = 0;
4677
4678 p_enc->intra_period = 120;
4679 p_enc->rc.intra_qp = 22;
4680 p_enc->rc.intra_qp_delta = -2;
4681 if (QUADRA)
4682 p_enc->rc.enable_mb_level_rc = 0;
4683 else
4684 p_enc->rc.enable_mb_level_rc = 1;
4685
4686 p_enc->decoding_refresh_type = 1;
4687
4688 p_enc->slice_mode = 0;
4689 p_enc->slice_arg = 0;
4690
4691 // Rev. B: H.264 only parameters.
4692 p_enc->enable_transform_8x8 = 1;
4693 p_enc->entropy_coding_mode = 1;
4694
4695 p_enc->intra_mb_refresh_mode = 0;
4696 p_enc->intra_mb_refresh_arg = 0;
4697 p_enc->intra_reset_refresh = 0;
4698
4700#ifndef QUADRA
4701 if (!QUADRA)
4702 {
4703 for (i = 0; i < NI_MAX_GOP_NUM; i++)
4704 {
4707 p_enc->custom_gop_params.pic_param[i].pic_qp = 0;
4708 p_enc->custom_gop_params.pic_param[i].num_ref_pic_L0 = 0;
4709 p_enc->custom_gop_params.pic_param[i].ref_poc_L0 = 0;
4710 p_enc->custom_gop_params.pic_param[i].ref_poc_L1 = 0;
4712 }
4713 }
4714 else // QUADRA
4715#endif
4716 {
4717 for (i = 0; i < NI_MAX_GOP_NUM; i++)
4718 {
4722 (float)0.3; // QP Factor range is between 0.3 and 1, higher values mean lower quality and less bits
4726 for (j = 0; j < NI_MAX_REF_PIC; j++)
4727 {
4728 p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic = 0;
4729 p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic_used = -1;
4730 }
4731 }
4732 }
4733
4734 p_param->source_width = width;
4735 p_param->source_height = height;
4736
4737 p_param->fps_number = fps_num;
4738 p_param->fps_denominator = fps_denom;
4739
4740 if (p_param->fps_number && p_param->fps_denominator)
4741 {
4742 p_enc->frame_rate = (int)(p_param->fps_number / p_param->fps_denominator);
4743 }
4744 else
4745 {
4746 p_enc->frame_rate = 30;
4747 }
4748
4749 p_param->bitrate = (int)bit_rate;
4750 p_param->roi_demo_mode = 0;
4751 p_param->reconf_demo_mode = 0; // for encoder reconfiguration testing
4752 p_param->force_pic_qp_demo_mode = 0;
4753 p_param->force_frame_type = 0;
4754 p_param->hdrEnableVUI = 0;
4755 p_param->cacheRoi = 0;
4756 p_param->low_delay_mode = 0;
4757 p_param->padding = 1;
4758 p_param->generate_enc_hdrs = 0;
4759 p_param->use_low_delay_poc_type = 0;
4760 p_param->rootBufId = 0;
4761 p_param->staticMmapThreshold = 0;
4762 p_param->zerocopy_mode = 1;
4763 p_param->luma_linesize = 0;
4764 p_param->chroma_linesize = 0;
4765 p_param ->enableCpuAffinity = 0;
4766
4768
4769 p_param->dolby_vision_profile = 0;
4770
4771 // encoder stream header VUI setting
4772 p_param->color_primaries = 2; // default COL_PRI_UNSPECIFIED
4773 p_param->color_transfer_characteristic = 2; // default COL_TRC_UNSPECIFIED
4774 p_param->color_space = 2; // default COL_SPC_UNSPECIFIED
4775 p_param->sar_num = 0; // default SAR numerator 0
4776 p_param->sar_denom = 1; // default SAR denominator 1
4777 p_param->video_full_range_flag = -1;
4778
4779 p_param->enable2PassGop = 0;
4781 p_param->minFramesDelay = 0;
4782 p_param->interval_of_psnr = 1;
4783 p_param->useMCTF = 0;
4784 for (i = 0; i < NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL; i++) {
4785 for (j = 0; j < NI_CUSTOMIZE_ROI_QP_NUM; j++) {
4786 // 127 is invalid for delta qp and absolute qp
4787 p_param->customize_roi_qp_map[i][j] = 127;
4788 }
4789 }
4790
4791 //QUADRA
4792 p_enc->EnableAUD = 0;
4793 p_enc->lookAheadDepth = 0;
4794 p_enc->rdoLevel = (codec_format == NI_CODEC_FORMAT_JPEG) ? 0 : 1;
4795 p_enc->crf = -1;
4796 p_enc->HDR10MaxLight = 0;
4797 p_enc->HDR10AveLight = 0;
4798 p_enc->HDR10CLLEnable = 0;
4799 p_enc->EnableRdoQuant = -1;
4800 p_enc->ctbRcMode = 0;
4801 p_enc->gopSize = 0;
4802 p_enc->gopLowdelay = 0;
4803 p_enc->gdrDuration = 0;
4804 p_enc->hrdEnable = 0;
4805 p_enc->ltrRefInterval = 0;
4806 p_enc->ltrRefQpOffset = 0;
4807 p_enc->ltrFirstGap = 0;
4808 p_enc->ltrNextInterval = 1;
4809 p_enc->multicoreJointMode = 0;
4810 p_enc->qlevel = -1;
4811 p_enc->maxFrameSize = 0;
4812 p_enc->maxFrameSizeRatio = 0;
4813 p_enc->chromaQpOffset = 0;
4814 p_enc->tolCtbRcInter = (float)0.1;
4815 p_enc->tolCtbRcIntra = (float)0.1;
4816 p_enc->bitrateWindow = -255;
4817 p_enc->inLoopDSRatio = 1;
4818 p_enc->blockRCSize = 0;
4819 p_enc->rcQpDeltaRange = 10;
4820 p_enc->ctbRowQpStep = 0;
4821 p_enc->newRcEnable = -1;
4822 p_enc->colorDescPresent = 0;
4823 p_enc->colorPrimaries = 2;
4824 p_enc->colorTrc = 2;
4825 p_enc->colorSpace = 2;
4826 p_enc->aspectRatioWidth = 0;
4827 p_enc->aspectRatioHeight = 1;
4828 p_enc->videoFullRange = 0;
4830 p_enc->enable_ssim = 0;
4831 p_enc->HDR10Enable = 0;
4832 p_enc->HDR10dx0 = 0;
4833 p_enc->HDR10dy0 = 0;
4834 p_enc->HDR10dx1 = 0;
4835 p_enc->HDR10dy1 = 0;
4836 p_enc->HDR10dx2 = 0;
4837 p_enc->HDR10dy2 = 0;
4838 p_enc->HDR10wx = 0;
4839 p_enc->HDR10wy = 0;
4840 p_enc->HDR10maxluma = 0;
4841 p_enc->HDR10minluma = 0;
4842 p_enc->avcc_hvcc = 0;
4843 p_enc->av1_error_resilient_mode = 0;
4844 p_enc->temporal_layers_enable = 0;
4845 p_enc->crop_width = 0;
4846 p_enc->crop_height = 0;
4847 p_enc->hor_offset = 0;
4848 p_enc->ver_offset = 0;
4849 p_enc->crfMax = -1;
4850 p_enc->qcomp = (float)0.6;
4851 p_enc->noMbtree = 0;
4852 p_enc->noHWMultiPassSupport = 0;
4853 p_enc->cuTreeFactor = 5;
4854 p_enc->ipRatio = (float)1.4;
4855 p_enc->pbRatio = (float)1.3;
4856 p_enc->cplxDecay = (float)0.5;
4857 p_enc->pps_init_qp = -1;
4858 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)
4859 p_enc->pass1_qp = -1;
4860 p_enc->crfFloat = -1.0f;
4861 p_enc->hvsBaseMbComplexity = 15;
4862 p_enc->statistic_output_level = 0;
4863 p_enc->skip_frame_enable = 0;
4864 p_enc->max_consecutive_skip_num = 1;
4865 p_enc->skip_frame_interval = 0;
4866 p_enc->enableipRatio = 0;
4867 p_enc->enable_all_sei_passthru = 0;
4868 p_enc->iframe_size_ratio = 100;
4869 p_enc->crf_max_iframe_enable = 0;
4870 p_enc->vbv_min_rate = 0;
4871 p_enc->totalCuTreeDepth = 0;
4872 p_enc->adaptiveCuTree = 0;
4873 p_enc->preIntraHandling = 1;
4874 p_enc->baseLayerOnly = 0;
4875 p_enc->pastFrameMaxIntraRatio = 20;
4876 p_enc->linkFrameMaxIntraRatio = 40;
4877 p_enc->adaptiveLamdaMode = 0;
4878 p_enc->adaptiveCrfMode = 0;
4879 p_enc->qpScaleEnable = 0;
4880#ifdef XCODER_311
4881 p_enc->disable_adaptive_buffers = 1;
4882#else
4883 p_enc->disable_adaptive_buffers = 0;
4884#endif
4885 p_enc->disableBframeRdoq = 0;
4886 p_enc->forceBframeQpfactor = (float)-1.0;
4887 p_enc->tune_bframe_visual = 0;
4888 p_enc->enable_acq_limit = 0;
4889 p_enc->get_psnr_mode = 3;
4891 p_enc->motionConstrainedMode = 0;
4892 p_enc->still_image_detect_level = 0;
4893 p_enc->scene_change_detect_level = 0;
4894 p_enc->encMallocStrategy = 0;
4895 p_enc->enable_smooth_crf = 0;
4896 p_enc->enable_compensate_qp = 0;
4897 p_enc->spatial_layers = 1;
4898 p_enc->enable_timecode = 0;
4900 p_enc->vbvBufferReencode = 0;
4901 p_enc->disableAv1TimingInfo = 0;
4903 p_enc->preset_enabled = 0;
4904 p_enc->reset_dts_offset = 1;
4905 p_enc->getBitstreamFeatures = 0;
4906 p_enc->clearRefListModification = 0;
4907 p_enc->longTermReferenceOldest = 0;
4908 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
4909 {
4910 p_enc->spatialLayerBitrate[i] = 0;
4911 p_enc->av1OpLevel[i] = 0;
4912 }
4913 p_enc->intraCompensateMode = 0;
4914 p_enc->customMinCoeffDiv = 0;
4915
4916 if (codec_format == NI_CODEC_FORMAT_AV1)
4917 {
4918 if (p_param->source_width < NI_PARAM_AV1_MIN_WIDTH)
4919 {
4921 LRETURN;
4922 }
4924 {
4926 LRETURN;
4927 }
4928 if (p_param->source_width > NI_PARAM_AV1_MAX_WIDTH)
4929 {
4931 LRETURN;
4932 }
4934 {
4936 LRETURN;
4937 }
4938 if (p_param->source_height * p_param->source_width >
4940 {
4942 LRETURN;
4943 }
4944 // AV1 8x8 alignment HW limitation is now worked around by FW cropping input resolution
4946 {
4947 ni_log(NI_LOG_ERROR, "AV1 Picture Width not aligned to %d - picture will be cropped\n",
4949 }
4951 {
4952 ni_log(NI_LOG_ERROR, "AV1 Picture Height not aligned to %d - picture will be cropped\n",
4954 }
4955 }
4956
4957 if (codec_format == NI_CODEC_FORMAT_JPEG)
4958 {
4959 if (p_param->source_width < NI_MIN_WIDTH)
4960 {
4962 LRETURN;
4963 }
4964 if (p_param->source_height < NI_MIN_HEIGHT)
4965 {
4967 LRETURN;
4968 }
4969 }
4970
4971 if (p_param->source_width > NI_PARAM_MAX_WIDTH)
4972 {
4974 LRETURN;
4975 }
4976 if (p_param->source_width < NI_PARAM_MIN_WIDTH)
4977 {
4979 LRETURN;
4980 }
4981
4982 if (p_param->source_height > NI_PARAM_MAX_HEIGHT)
4983 {
4985 LRETURN;
4986 }
4987 if (p_param->source_height < NI_PARAM_MIN_HEIGHT)
4988 {
4990 LRETURN;
4991 }
4992 if (p_param->source_height*p_param->source_width > NI_MAX_RESOLUTION_AREA)
4993 {
4995 LRETURN;
4996 }
4997
4998END:
4999
5000 return retval;
5001}
5002
5003/*!*****************************************************************************
5004 * \brief Initialize default decoder parameters
5005 *
5006 * \param[out] param Pointer to a user allocated ni_xcoder_params_t
5007 * to initialize to default parameters
5008 * \param[in] fps_num Frames per second
5009 * \param[in] fps_denom FPS denomination
5010 * \param[in] bit_rate bit rate
5011 * \param[in] width frame width
5012 * \param[in] height frame height
5013 *
5014 * \return On success
5015 * NI_RETCODE_SUCCESS
5016 * On failure
5017 * NI_RETCODE_FAILURE
5018 * NI_RETCODE_INVALID_PARAM
5019 ******************************************************************************/
5021 int fps_num, int fps_denom,
5022 long bit_rate, int width,
5023 int height)
5024{
5025 ni_decoder_input_params_t* p_dec = NULL;
5026 int i;
5028
5029 //Initialize p_param structure
5030 if (!p_param)
5031 {
5032 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameter passed\n",
5033 __func__);
5034 retval = NI_RETCODE_INVALID_PARAM;
5035 LRETURN;
5036 }
5037
5038 ni_log(NI_LOG_DEBUG, "%s\n", __func__);
5039
5040 //Initialize p_param structure
5041 memset(p_param, 0, sizeof(ni_xcoder_params_t));
5042
5043 p_dec = &p_param->dec_input_params;
5044
5045 p_param->source_width = width;
5046 p_param->source_height = height;
5047
5048 if(fps_num <= 0 || fps_denom <= 0 || (int64_t)fps_num > (int64_t)120 * fps_denom)
5049 {
5050 ni_log(NI_LOG_INFO, "%s(): FPS invalid or out of range (%d/%d), defaulting to 30\n",
5051 __func__, fps_num, fps_denom);
5052 fps_num = 30;
5053 fps_denom = 1;
5054 }
5055
5056 p_param->fps_number = fps_num;
5057 p_param->fps_denominator = fps_denom;
5058
5059 p_dec->hwframes = 0;
5060 p_dec->mcmode = 0;
5061 p_dec->nb_save_pkt = 0;
5062 p_dec->enable_out1 = 0;
5063 p_dec->enable_out2 = 0;
5064 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
5065 {
5066 p_dec->force_8_bit[i] = 0;
5067 p_dec->semi_planar[i] = 0;
5068 p_dec->crop_mode[i] = NI_DEC_CROP_MODE_AUTO;
5069 p_dec->crop_whxy[i][0] = width;
5070 p_dec->crop_whxy[i][1] = height;
5071 p_dec->crop_whxy[i][2] = 0;
5072 p_dec->crop_whxy[i][3] = 0;
5073 p_dec->scale_wh[i][0] = 0;
5074 p_dec->scale_wh[i][1] = 0;
5075 p_dec->scale_long_short_edge[i] = 0;
5076 p_dec->scale_resolution_ceil[i] = 2;
5077 p_dec->scale_round[i] = -1;
5078 }
5080 p_dec->decoder_low_delay = 0;
5081 p_dec->force_low_delay = false;
5082 p_dec->enable_low_delay_check = 0;
5083 p_dec->decoder_disable_reorder = 0;
5085 p_dec->custom_sei_passthru = -1;
5088 p_dec->enable_advanced_ec = 1;
5090 p_dec->enable_ppu_scale_adapt = 0;
5091 p_dec->enable_ppu_scale_limit = 0;
5092 p_dec->max_extra_hwframe_cnt = 255; //uint8_max
5093 p_dec->pkt_pts_unchange = 0;
5094 p_dec->enable_all_sei_passthru = 0;
5095 p_dec->enable_follow_iframe = 0;
5097#ifdef XCODER_311
5098 p_dec->disable_adaptive_buffers = 1;
5099 p_dec->min_packets_delay = true;
5100 p_dec->reduce_dpb_delay = 1;
5101#else
5102 p_dec->disable_adaptive_buffers = 0;
5103 p_dec->min_packets_delay = false;
5104 p_dec->reduce_dpb_delay = 0;
5105#endif
5106 p_dec->survive_stream_err = 0;
5107 p_dec->skip_extra_headers = 0;
5108 p_dec->extend_pool_size = 0;
5109 p_dec->decoder_mode = 0;
5110
5111 //-------init unused param start----------
5112
5113 p_param->bitrate = (int)bit_rate;
5114 p_param->reconf_demo_mode = 0; // for encoder reconfiguration testing
5115 p_param->force_pic_qp_demo_mode = 0;
5116 p_param->force_frame_type = 0;
5117 p_param->hdrEnableVUI = 0;
5118 p_param->cacheRoi = 0;
5119 p_param->low_delay_mode = 0;
5120 p_param->padding = 1;
5121 p_param->generate_enc_hdrs = 0;
5122 p_param->use_low_delay_poc_type = 0;
5123 p_param->dolby_vision_profile = 0;
5124
5125 // encoder stream header VUI setting
5126 p_param->color_primaries = 2; // default COL_PRI_UNSPECIFIED
5127 p_param->color_transfer_characteristic = 2; // default COL_TRC_UNSPECIFIED
5128 p_param->color_space = 2; // default COL_SPC_UNSPECIFIED
5129 p_param->sar_num = 0; // default SAR numerator 0
5130 p_param->sar_denom = 1; // default SAR denominator 1
5131 p_param->video_full_range_flag = -1;
5132
5133 //-------init unused param done----------
5134
5135END:
5136
5137 return retval;
5138}
5139
5140// read demo reconfig data file and parse out reconfig key/values in the format:
5141// key:val1,val2,val3,...val9 (max 9 values); digit/:/,/newline and a leading
5142// '-' on a value are allowed. A leading '-' applies to that value only.
5143ni_retcode_t ni_parse_reconf_file(const char *reconf_file,
5145{
5146 char keyChar[10] = "";
5147 int key;
5148 char valChar[10] = "";
5149 int val;
5150 int32_t tmp_val;
5151 int valIdx = 1;
5152 int parseKey = 1;
5153 int negative = 0;
5154 int idx = 0;
5155 int readc = EOF;
5156 FILE *reconf = NULL;
5157
5158 if (!reconf_file)
5159 {
5160 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5161 __func__);
5163 }
5164
5165 ni_fopen(&reconf, reconf_file, "r");
5166 if (!reconf)
5167 {
5168 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): Cannot open reconfig_file: %s\n",
5169 NI_ERRNO, __func__, reconf_file);
5171 }
5173
5174 while ((readc = fgetc(reconf)) != EOF)
5175 {
5176 //parse lines
5177 if (isdigit(readc))
5178 {
5179 if (parseKey)
5180 {
5181 ni_strncat(keyChar, 10, (const char *)(&readc), 1);
5182 }
5183 else
5184 {
5185 ni_strncat(valChar, 10, (const char *)(&readc), 1);
5186 }
5187 }
5188 else if (readc == ':')
5189 {
5190 parseKey = 0;
5191 if (ni_strtoi(keyChar, &tmp_val) != NI_RETCODE_SUCCESS)
5192 {
5194 "ERROR: %s(): invalid key value '%s' in reconfig file\n",
5195 __func__, keyChar);
5196 retval = NI_RETCODE_INVALID_PARAM;
5197 break;
5198 }
5199 key = (int)tmp_val;
5200 hash_map[idx][0] = key;
5201 }
5202 else if (readc == '-')
5203 {
5204 // A leading '-' is valid only at the start of a value, so a value can
5205 // be negative (for example invalidFrameNum=-1). The frame number key
5206 // stays unsigned.
5207 if (parseKey || valChar[0] != '\0' || negative)
5208 {
5210 "ERROR: character %c in reconfig file. this may lead to "
5211 "mistaken reconfiguration values\n",
5212 readc);
5213 }
5214 else
5215 {
5216 negative = 1;
5217 }
5218 }
5219 else if (readc == ',')
5220 {
5222 {
5224 "ERROR: Number of entries per line in reconfig file is greater then the "
5225 "limit of %d\n",
5227 retval = NI_RETCODE_INVALID_PARAM;
5228 break;
5229 }
5230 if (ni_strtoi(valChar, &tmp_val) != NI_RETCODE_SUCCESS)
5231 {
5233 "ERROR: %s(): invalid value '%s' in reconfig file\n",
5234 __func__, valChar);
5235 retval = NI_RETCODE_INVALID_PARAM;
5236 break;
5237 }
5238 val = (int)tmp_val;
5239 if (negative)
5240 {
5241 val = -val;
5242 }
5243 negative = 0;
5244 hash_map[idx][valIdx] = val;
5245 valIdx++;
5246 memset(valChar, 0, 10);
5247 }
5248 else if (readc == '\n')
5249 {
5251 {
5253 "ERROR: Number of lines in reconfig file is greater then the "
5254 "limit of %d\n",
5256 retval = NI_RETCODE_INVALID_PARAM;
5257 break;
5258 }
5259 parseKey = 1;
5260 if (ni_strtoi(valChar, &tmp_val) != NI_RETCODE_SUCCESS)
5261 {
5263 "ERROR: %s(): invalid value '%s' in reconfig file\n",
5264 __func__, valChar);
5265 retval = NI_RETCODE_INVALID_PARAM;
5266 break;
5267 }
5268 val = (int)tmp_val;
5269 if (negative)
5270 {
5271 val = -val;
5272 }
5273 negative = 0;
5274 hash_map[idx][valIdx] = val;
5275 valIdx = 1;
5276 memset(keyChar,0,10);
5277 memset(valChar,0,10);
5278 idx ++;
5279 }
5280 else
5281 {
5282 ni_log(NI_LOG_ERROR, "ERROR: character %c in reconfig file. this may lead to mistaken reconfiguration values\n", readc);
5283 }
5284 }
5285
5286 (void)fclose(reconf);
5287
5288 if (NI_RETCODE_SUCCESS == retval && parseKey != 1)
5289 {
5291 "ERROR %d: %s(): Incorrect format / "
5292 "incomplete Key/Value pair in reconfig_file: %s\n",
5293 NI_ERRNO, __func__, reconf_file);
5295 }
5296
5297 return retval;
5298}
5299
5301 int8_t qp_map[][NI_CUSTOMIZE_ROI_QP_NUM])
5302{
5303 char valChar[5] = "";
5304 int val;
5305 int32_t tmp_val;
5306 int negative = 0;
5307 int qpIdx = 0;
5308 int levelIdx = 0;
5309 int readc = EOF;
5310 FILE *reconf = NULL;
5311
5312 if (!customize_file)
5313 {
5314 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5315 __func__);
5317 }
5318
5319 ni_fopen(&reconf, customize_file, "r");
5320 if (!reconf)
5321 {
5322 ni_log(NI_LOG_ERROR, "ERROR %d: %s(): Cannot open reconfig_file: %s\n",
5323 NI_ERRNO, __func__, customize_file);
5325 }
5327
5328 while ((readc = fgetc(reconf)) != EOF)
5329 {
5330 //parse lines
5331 if (isdigit(readc))
5332 {
5333 ni_strncat(valChar, 5, (const char *)(&readc), 1);
5334 }
5335 else if (readc == '-') {
5336 negative = 1;
5337 }
5338 else if (readc == ',')
5339 {
5340 if (qpIdx >= NI_CUSTOMIZE_ROI_QP_NUM || levelIdx >= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL)
5341 {
5343 "ERROR: Number of qpIdx %d greater then the limit of %d or"
5344 "Number of levelIdx %d greater then the limit of %d\n",
5346 retval = NI_RETCODE_INVALID_PARAM;
5347 break;
5348 }
5349 if (ni_strtoi(valChar, &tmp_val) != NI_RETCODE_SUCCESS)
5350 {
5352 "ERROR: %s(): invalid value '%s' in customize file\n",
5353 __func__, valChar);
5354 retval = NI_RETCODE_INVALID_PARAM;
5355 break;
5356 }
5357 if (!negative) {
5358 val = clip3(0, NI_MAX_QP_INFO, (int)tmp_val);
5359 qp_map[levelIdx][qpIdx] = (int8_t)val;
5360 } else {
5361 val = clip3(0, 32, (int)tmp_val);
5362 qp_map[levelIdx][qpIdx] = (int8_t)(val * -1);
5363 }
5364 negative = 0;
5365 memset(valChar, 0, 5);
5366 qpIdx++;
5367 }
5368 else if (readc == '\n')
5369 {
5370 if (qpIdx >= NI_CUSTOMIZE_ROI_QP_NUM || levelIdx >= NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL)
5371 {
5373 "ERROR: Number of qpIdx %d greater then the limit of %d or"
5374 "Number of levelIdx %d greater then the limit of %d\n",
5376 retval = NI_RETCODE_INVALID_PARAM;
5377 break;
5378 }
5379 if (ni_strtoi(valChar, &tmp_val) != NI_RETCODE_SUCCESS)
5380 {
5382 "ERROR: %s(): invalid value '%s' in customize file\n",
5383 __func__, valChar);
5384 retval = NI_RETCODE_INVALID_PARAM;
5385 break;
5386 }
5387 if (!negative) {
5388 val = clip3(0, NI_MAX_QP_INFO, (int)tmp_val);
5389 qp_map[levelIdx][qpIdx] = (int8_t)val;
5390 } else {
5391 val = clip3(0, 32, (int)tmp_val);
5392 qp_map[levelIdx][qpIdx] = (int8_t)(val * -1);
5393 }
5394 negative = 0;
5395 memset(valChar, 0, 5);
5396 qpIdx = 0;
5397 levelIdx++;
5398 }
5399 else
5400 {
5401 ni_log(NI_LOG_ERROR, "ERROR: character %c in reconfig file. this may lead to mistaken reconfiguration values\n", readc);
5402 }
5403 }
5404 (void)fclose(reconf);
5405
5406 return retval;
5407}
5408
5409
5410#undef atoi
5411#undef atof
5412#define atoi(p_str) ni_atoi(p_str, &b_error)
5413#define atof(p_str) ni_atof(p_str, &b_error)
5414#define atobool(p_str) (ni_atobool(p_str, &b_error))
5415/*!*****************************************************************************
5416* \brief Set value referenced by name in decoder parameters structure
5417*
5418* \param[in] p_params Pointer to a user allocated ni_xcoder_params_t (used
5419* for decoder too for now ) to find and set a particular
5420* parameter
5421* \param[in] name String represented parameter name to search
5422* \param[in] value Parameter value to set
5423*
5424* \return On success
5425* NI_RETCODE_SUCCESS
5426* On failure
5427* NI_RETCODE_FAILURE
5428* NI_RETCODE_INVALID_PARAM
5429*******************************************************************************/
5431 const char *name, char *value)
5432{
5433 bool b_error = false;
5434 bool bNameWasBool = false;
5435 bool bValueWasNull = !value;
5436 ni_decoder_input_params_t* p_dec = NULL;
5437 char nameBuf[64] = { 0 };
5438 const char delim[2] = ",";
5439 const char xdelim[2] = "x";
5440 char *chunk;//for parsing out multi param input
5441 int i, j, k, ppu_index;
5442
5443 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
5444
5445 if (!p_params)
5446 {
5447 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
5448 __func__);
5450 }
5451
5452 if (!name)
5453 {
5454 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
5455 __func__);
5457 }
5458 p_dec = &p_params->dec_input_params;
5459
5460 // skip -- prefix if provided
5461 if (name[0] == '-' && name[1] == '-')
5462 {
5463 name += 2;
5464 }
5465
5466 // s/_/-/g
5467 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
5468 {
5469 char* c;
5470 ni_strcpy(nameBuf, sizeof(nameBuf), name);
5471 while ((c = strchr(nameBuf, '_')) != 0)
5472 {
5473 *c = '-';
5474 }
5475 name = nameBuf;
5476 }
5477
5478 if (!value)
5479 {
5480 value = "true";
5481 }
5482 else if (value[0] == '=')
5483 {
5484 value++;
5485 }
5486
5487#if defined(_MSC_VER)
5488#define OPT(STR) else if (!_stricmp(name, STR))
5489#define OPT2(STR1, STR2) \
5490 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2))
5491#define OPT6(STR1, STR2, STR3, STR4, STR5, STR6) \
5492 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2) || \
5493 !_stricmp(name, STR3) || !_stricmp(name, STR4) || \
5494 !_stricmp(name, STR5) || !_stricmp(name, STR6))
5495#else
5496#define OPT(STR) else if (!strcasecmp(name, STR))
5497#define OPT2(STR1, STR2) else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2))
5498#define OPT6(STR1, STR2, STR3, STR4, STR5, STR6) \
5499 else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2) || \
5500 !strcasecmp(name, STR3) || !strcasecmp(name, STR4) || \
5501 !strcasecmp(name, STR5) || !strcasecmp(name, STR6))
5502#endif
5503 if (0); // suppress cppcheck
5505 {
5506 if (!strncmp(value, "hw", sizeof("hw"))){
5507 p_dec->hwframes = 1;
5508 }
5509 else if (!strncmp(value, "sw", sizeof("sw"))) {
5510 p_dec->hwframes = 0;
5511 }
5512 else{
5513 ni_log(NI_LOG_ERROR, "ERROR: %s(): out can only be <hw,sw> got %s\n",
5514 __func__, value);
5516 }
5517 }
5519 {
5520 if (atoi(value) == 1)
5521 p_dec->enable_out1 = 1;
5522 }
5524 {
5525 if (atoi(value) == 1)
5526 p_dec->enable_out2 = 1;
5527 }
5529 {
5530 if (atoi(value) == 1)
5531 p_dec->force_8_bit[0] = 1;
5532 }
5534 {
5535 if (atoi(value) == 1)
5536 p_dec->force_8_bit[1] = 1;
5537 }
5539 {
5540 if (atoi(value) == 1)
5541 p_dec->force_8_bit[2] = 1;
5542 }
5544 {
5545 if (atoi(value) == 1 || atoi(value) == 2)
5546 p_dec->semi_planar[0] = atoi(value);
5547 }
5549 {
5550 if (atoi(value) == 1 || atoi(value) == 2)
5551 p_dec->semi_planar[1] = atoi(value);
5552 }
5554 {
5555 if (atoi(value) == 1 || atoi(value) == 2)
5556 p_dec->semi_planar[2] = atoi(value);
5557 }
5559 {
5560 if (!strncmp(value, "manual", sizeof("manual"))) {
5562 }
5563 else if (!strncmp(value, "auto", sizeof("auto"))) {
5564 p_dec->crop_mode[0] = NI_DEC_CROP_MODE_AUTO;
5565 }
5566 else{
5568 "ERROR: %s():cropMode0 input can only be <manual,auto> got %s\n",
5569 __func__, value);
5571 }
5572 }
5574 {
5575 if (!strncmp(value, "manual", sizeof("manual"))) {
5577 }
5578 else if (!strncmp(value, "auto", sizeof("auto"))) {
5579 p_dec->crop_mode[1] = NI_DEC_CROP_MODE_AUTO;
5580 }
5581 else {
5583 "ERROR: %s():cropMode1 input can only be <manual,auto> got %s\n",
5584 __func__, value);
5586 }
5587 }
5589 {
5590 if (!strncmp(value, "manual", sizeof("manual"))) {
5592 }
5593 else if (!strncmp(value, "auto", sizeof("auto"))) {
5594 p_dec->crop_mode[2] = NI_DEC_CROP_MODE_AUTO;
5595 }
5596 else {
5598 "ERROR: %s():cropMode2 input can only be <manual,auto> got %s\n",
5599 __func__, value);
5601 }
5602 }
5604 {
5605 char *saveptr = NULL;
5606 chunk = ni_strtok(value, delim, &saveptr);
5607 for (i = 0; i < 4; i++)
5608 {
5609 if (chunk != NULL)
5610 {
5611 j = k = 0;
5612 while (chunk[j])
5613 {
5614 if (chunk[j] != '\"' && chunk[j] != '\'')
5615 {
5616 p_dec->cr_expr[0][i][k] = chunk[j];
5617 k++;
5618 }
5620 {
5622 }
5623 }
5624 chunk = ni_strtok(NULL, delim, &saveptr);
5625 }
5626 else if (i == 2 ) //default offsets to centered image if not specified, may need recalc
5627 {
5628 ni_strcpy(p_dec->cr_expr[0][i], sizeof(p_dec->cr_expr[0][i]), "in_w/2-out_w/2");
5629 }
5630 else if (i == 3)
5631 {
5632 ni_strcpy(p_dec->cr_expr[0][i], sizeof(p_dec->cr_expr[0][i]), "in_h/2-out_h/2");
5633 } else
5634 {
5636 }
5637 }
5638 }
5640 {
5641 char *saveptr = NULL;
5642 chunk = ni_strtok(value, delim, &saveptr);
5643 for (i = 0; i < 4; i++)
5644 {
5645 if (chunk != NULL)
5646 {
5647 j = k = 0;
5648 while (chunk[j])
5649 {
5650 if (chunk[j] != '\"' && chunk[j] != '\'')
5651 {
5652 p_dec->cr_expr[1][i][k] = chunk[j];
5653 k++;
5654 }
5656 {
5658 }
5659 }
5660 chunk = ni_strtok(NULL, delim, &saveptr);
5661 }
5662 else if (i == 2) //default offsets to centered image if not specified, may need recalc
5663 {
5664 ni_strcpy(p_dec->cr_expr[1][i], sizeof(p_dec->cr_expr[1][i]), "in_w/2-out_w/2");
5665 }
5666 else if (i == 3)
5667 {
5668 ni_strcpy(p_dec->cr_expr[1][i], sizeof(p_dec->cr_expr[1][i]), "in_h/2-out_h/2");
5669 }
5670 else
5671 {
5673 }
5674 }
5675 }
5677 {
5678 char *saveptr = NULL;
5679 chunk = ni_strtok(value, delim, &saveptr);
5680 for (i = 0; i < 4; i++)
5681 {
5682 if (chunk != NULL)
5683 {
5684 j = k = 0;
5685 while (chunk[j])
5686 {
5687 if (chunk[j] != '\"' && chunk[j] != '\'')
5688 {
5689 p_dec->cr_expr[2][i][k] = chunk[j];
5690 k++;
5691 }
5693 {
5695 }
5696 }
5697 chunk = ni_strtok(NULL, delim, &saveptr);
5698 }
5699 else if (i == 2) //default offsets to centered image if not specified, may need recalc
5700 {
5701 ni_strcpy(p_dec->cr_expr[2][i], sizeof(p_dec->cr_expr[2][i]), "in_w/2-out_w/2");
5702 }
5703 else if (i == 3)
5704 {
5705 ni_strcpy(p_dec->cr_expr[2][i], sizeof(p_dec->cr_expr[2][i]), "in_h/2-out_h/2");
5706 }
5707 else
5708 {
5710 }
5711 }
5712 }
5714 {
5715 chunk = value;
5716 i = 0; // 'x' character counter
5717 while (*chunk++) {
5718 if (*chunk == xdelim[0]) {
5719 i++;
5720 }
5721 }
5722 if (i != 1) {
5724 }
5725 chunk = NULL;
5726
5727 char *saveptr = NULL;
5728 chunk = ni_strtok(value, xdelim, &saveptr);
5729 for (i = 0; i < 2; i++)
5730 {
5731 if (chunk != NULL)
5732 {
5733 j = k = 0;
5734 while (chunk[j])
5735 {
5736 if (chunk[j] != '\"' && chunk[j] != '\'')
5737 {
5738 p_dec->sc_expr[0][i][k] = chunk[j];
5739 k++;
5740 }
5742 {
5744 }
5745 }
5746 chunk = ni_strtok(NULL, xdelim, &saveptr);
5747 }
5748 else
5749 {
5751 }
5752 }
5753 }
5755 {
5756 chunk = value;
5757 i = 0; // 'x' character counter
5758 while (*chunk++) {
5759 if (*chunk == xdelim[0]) {
5760 i++;
5761 }
5762 }
5763 if (i != 1) {
5765 }
5766 chunk = NULL;
5767
5768 char *saveptr = NULL;
5769 chunk = ni_strtok(value, xdelim, &saveptr);
5770 for (i = 0; i < 2; i++)
5771 {
5772 if (chunk != NULL)
5773 {
5774 j = k = 0;
5775 while (chunk[j])
5776 {
5777 if (chunk[j] != '\"' && chunk[j] != '\'')
5778 {
5779 p_dec->sc_expr[1][i][k] = chunk[j];
5780 k++;
5781 }
5783 {
5785 }
5786 }
5787 chunk = ni_strtok(NULL, xdelim, &saveptr);
5788 }
5789 else
5790 {
5792 }
5793 }
5794 }
5796 {
5797 chunk = value;
5798 i = 0; // 'x' character counter
5799 while (*chunk++) {
5800 if (*chunk == xdelim[0]) {
5801 i++;
5802 }
5803 }
5804 if (i != 1) {
5806 }
5807 chunk = NULL;
5808
5809 char *saveptr = NULL;
5810 chunk = ni_strtok(value, xdelim, &saveptr);
5811 for (i = 0; i < 2; i++)
5812 {
5813 if (chunk != NULL)
5814 {
5815 j = k = 0;
5816 while (chunk[j])
5817 {
5818 if (chunk[j] != '\"' && chunk[j] != '\'')
5819 {
5820 p_dec->sc_expr[2][i][k] = chunk[j];
5821 k++;
5822 }
5824 {
5826 }
5827 }
5828 chunk = ni_strtok(NULL, xdelim, &saveptr);
5829 }
5830 else
5831 {
5833 }
5834 }
5835 }
5839 {
5840 chunk = value;
5841 if (chunk != NULL)
5842 {
5843 ppu_index = name[5] - '0';
5844 i = name[6] == 'w' ? 0 : 1;
5845 j = k = 0;
5846 while (chunk[j])
5847 {
5848 if (chunk[j] != '\"' && chunk[j] != '\'')
5849 {
5850 p_dec->sc_expr[ppu_index][i][k] = chunk[j];
5851 k++;
5852 }
5854 {
5856 }
5857 }
5858 }
5859 }
5861 {
5862 if ((atoi(value) < 0) || (atoi(value) > 2))
5863 {
5865 }
5866 p_dec->scale_long_short_edge[0] = atoi(value);
5867 }
5869 {
5870 if ((atoi(value) < 0) || (atoi(value) > 2))
5871 {
5873 }
5874 p_dec->scale_long_short_edge[1] = atoi(value);
5875 }
5877 {
5878 if ((atoi(value) < 0) || (atoi(value) > 2))
5879 {
5881 }
5882 p_dec->scale_long_short_edge[2] = atoi(value);
5883 }
5885 {
5886 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5887 {
5888 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5889 "and must be even number and less than or equal to 128. Got: %s\n",
5890 __func__, NI_DEC_PARAM_SCALE_0_RES_CEIL, value);
5891
5893 }
5894 p_dec->scale_resolution_ceil[0] = atoi(value);
5895 }
5897 {
5898 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5899 {
5900 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5901 "and must be even number and less than or equal to 128. Got: %s\n",
5902 __func__, NI_DEC_PARAM_SCALE_1_RES_CEIL, value);
5904 }
5905 p_dec->scale_resolution_ceil[1] = atoi(value);
5906 }
5908 {
5909 if (atoi(value) < 2 || atoi(value) % 2 != 0 || atoi(value) > 128)
5910 {
5911 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s must be greater than or equal to 2 "
5912 "and must be even number and less than or equal to 128. Got: %s\n",
5913 __func__, NI_DEC_PARAM_SCALE_2_RES_CEIL, value);
5915 }
5916 p_dec->scale_resolution_ceil[2] = atoi(value);
5917 }
5919 {
5920 if (!strncmp(value, "up", sizeof("up"))){
5921 p_dec->scale_round[0] = 0;
5922 }
5923 else if (!strncmp(value, "down", sizeof("down"))) {
5924 p_dec->scale_round[0] = 1;
5925 }
5926 else{
5927 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5928 __func__, NI_DEC_PARAM_SCALE_0_ROUND, value);
5930 }
5931 }
5933 {
5934 if (!strncmp(value, "up", sizeof("up"))){
5935 p_dec->scale_round[1] = 0;
5936 }
5937 else if (!strncmp(value, "down", sizeof("down"))) {
5938 p_dec->scale_round[1] = 1;
5939 }
5940 else{
5941 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5942 __func__, NI_DEC_PARAM_SCALE_1_ROUND, value);
5944 }
5945 }
5947 {
5948 if (!strncmp(value, "up", sizeof("up"))){
5949 p_dec->scale_round[2] = 0;
5950 }
5951 else if (!strncmp(value, "down", sizeof("down"))) {
5952 p_dec->scale_round[2] = 1;
5953 }
5954 else{
5955 ni_log(NI_LOG_ERROR, "ERROR: %s(): %s can only be {up, down}. Got: %s\n",
5956 __func__, NI_DEC_PARAM_SCALE_2_ROUND, value);
5958 }
5959 }
5961 {
5962 if ((atoi(value) != 0) && (atoi(value) != 1))
5963 {
5965 }
5966 p_dec->mcmode = atoi(value);
5967 }
5969 {
5970 if (atoi(value) < 0)
5971 {
5973 }
5974 p_dec->nb_save_pkt = atoi(value);
5975 }
5977 {
5978 if ((atoi(value) < NI_MIN_KEEP_ALIVE_TIMEOUT) ||
5980 {
5982 }
5983 p_dec->keep_alive_timeout = atoi(value);
5984 }
5986 {
5987 if (atoi(value) < 0)
5988 {
5990 }
5991 p_dec->decoder_low_delay = atoi(value);
5992 }
5994 {
5995 if ((atoi(value) != 0) && (atoi(value) != 1))
5996 {
5998 }
5999 p_dec->force_low_delay = atoi(value);
6000 }
6002 {
6003 if (atoi(value) < 0)
6004 {
6006 }
6007 p_dec->enable_low_delay_check = atoi(value);
6008 }
6010 {
6011 if (atoi(value) < 0)
6012 {
6014 }
6015 p_dec->decoder_disable_reorder = atoi(value);
6016 }
6018 {
6019 if ((atoi(value) != 0) && (atoi(value) != 1))
6020 {
6022 }
6023 p_dec->min_packets_delay = atoi(value);
6024 }
6026 {
6027 if (atoi(value) != NI_ENABLE_USR_DATA_SEI_PASSTHRU &&
6029 {
6031 }
6032 p_dec->enable_user_data_sei_passthru = atoi(value);
6033 }
6035 {
6036 if (atoi(value) < NI_MIN_CUSTOM_SEI_PASSTHRU ||
6038 {
6040 }
6041 p_dec->custom_sei_passthru = atoi(value);
6042 }
6044 {
6046 {
6048 }
6049 p_dec->svct_decoding_layer = atoi(value);
6050 }
6052 {
6053 if (atoi(value) >= NI_DDR_PRIORITY_MAX ||
6054 atoi(value) <= NI_DDR_PRIORITY_NONE)
6055 {
6057 }
6058 p_params->ddr_priority_mode = atoi(value);
6059 }
6061 {
6062 if (strncmp(value, "tolerant", sizeof("tolerant")) == 0) {
6064 } else if (strncmp(value, "ignore", sizeof("ignore")) == 0) {
6066 } else if (strncmp(value, "skip", sizeof("skip")) == 0) {
6068 } else if (strncmp(value, "best_effort", sizeof("best_effort")) == 0) {
6070 } else if (strncmp(value, "limited_error", sizeof("limited_error")) == 0) {
6072 } else if (strncmp(value, "best_effort_out_dc", sizeof("best_effort_out_dc")) == 0) {
6074 } else {
6076 }
6077 }
6079 {
6080 if (atoi(value) != 0 &&
6081 atoi(value) != 1 &&
6082 atoi(value) != 2)
6083 {
6085 }
6086 p_dec->enable_advanced_ec = atoi(value);
6087 }
6089 {
6090 if (atoi(value) < 0 || (atoi(value) > 100))
6091 {
6093 }
6094 p_dec->error_ratio_threshold = atoi(value);
6095 }
6097 {
6098 if (atoi(value) < 0 || (atoi(value) > 2))
6099 {
6101 }
6102 p_dec->enable_ppu_scale_adapt = atoi(value);
6103 }
6105 {
6106 if (atoi(value) < 0 || (atoi(value) > 1))
6107 {
6109 }
6110 p_dec->enable_ppu_scale_limit = atoi(value);
6111 }
6113 {
6114 if (atoi(value) < 0 || atoi(value) > 255)
6115 {
6117 }
6118 p_dec->max_extra_hwframe_cnt = atoi(value);
6119 }
6121 {
6122 if (atoi(value) < 0 || atoi(value) > 252)
6123 {
6125 }
6126 p_dec->extend_pool_size = atoi(value);
6127 }
6129 {
6130 if (strncmp(value, "normal", sizeof("normal")) == 0) {
6132 } else if (strncmp(value, "intra_only", sizeof("intra_only")) == 0) {
6134 } else {
6136 }
6137 }
6139 {
6140 if (atoi(value) < 0 || atoi(value) > 1)
6141 {
6143 }
6144 p_dec->skip_pts_guess = atoi(value);
6145 }
6147 {
6148 if (atoi(value) != 0 && atoi(value) != 1)
6149 {
6151 }
6152 p_dec->pkt_pts_unchange = atoi(value);
6153 }
6155 {
6156 if (atoi(value) < 0 ||
6157 atoi(value) > 1)
6158 {
6160 }
6161 p_dec->enable_all_sei_passthru = atoi(value);
6162 }
6164 {
6165 if (atoi(value) != 0 && atoi(value) != 1)
6166 {
6168 }
6169 p_dec->enable_follow_iframe = atoi(value);
6170 }
6172 {
6173 if (atoi(value) < 0 ||
6174 atoi(value) > 1)
6175 {
6177 }
6178 p_dec->disable_adaptive_buffers = atoi(value);
6179 }
6181 {
6182 if (atoi(value) < 0 || atoi(value) > 1)
6183 {
6185 }
6186 p_dec->survive_stream_err = atoi(value);
6187 }
6189 {
6190 if ((atoi(value) != 0) && (atoi(value) != 1))
6191 {
6193 }
6194 p_dec->reduce_dpb_delay = atoi(value);
6195 }
6197 {
6198 if ((atoi(value) != 0) && (atoi(value) != 1))
6199 {
6201 }
6202 p_dec->skip_extra_headers = atoi(value);
6203 }
6205 {
6206 if ((atoi(value) != 0) && (atoi(value) != 1))
6207 {
6209 }
6210 p_params->enableCpuAffinity = atoi(value);
6211 }
6212 else
6213 {
6215 }
6216
6217#undef OPT
6218#undef atobool
6219#undef atoi
6220#undef atof
6221 b_error |= bValueWasNull && !bNameWasBool;
6222
6223 ni_log(NI_LOG_TRACE, "%s: exit, b_error=%d\n", __func__, b_error);
6224
6226}
6227
6228#undef atoi
6229#undef atof
6230#define atoi(p_str) ni_atoi(p_str, &b_error)
6231#define atof(p_str) ni_atof(p_str, &b_error)
6232#define atobool(p_str) (ni_atobool(p_str, &b_error))
6233
6234/*!*****************************************************************************
6235 * \brief Set value referenced by name in encoder parameters structure
6236 *
6237 * \param[in] p_params Pointer to a user allocated ni_xcoder_params_t
6238 * to find and set a particular parameter
6239 * \param[in] name String represented parameter name to search
6240 * \param[in] value Parameter value to set
6241*
6242 * \return On success
6243 * NI_RETCODE_SUCCESS
6244 * On failure
6245 * NI_RETCODE_FAILURE
6246 * NI_RETCODE_INVALID_PARAM
6247 ******************************************************************************/
6249 const char *name, const char *value)
6250{
6251 bool b_error = false;
6252 bool bNameWasBool = false;
6253 bool bValueWasNull = !value;
6254 ni_encoder_cfg_params_t *p_enc = NULL;
6255 char nameBuf[64] = { 0 };
6256 int i,j,k;
6257
6258 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
6259
6260 if (!p_params)
6261 {
6262 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
6263 __func__);
6265 }
6266
6267 if ( !name )
6268 {
6269 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
6270 __func__);
6272 }
6273 p_enc = &p_params->cfg_enc_params;
6274 // skip -- prefix if provided
6275 if (name[0] == '-' && name[1] == '-')
6276 {
6277 name += 2;
6278 }
6279
6280 // s/_/-/g
6281 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
6282 {
6283 char* c;
6284 ni_strcpy(nameBuf, sizeof(nameBuf), name);
6285 while ((c = strchr(nameBuf, '_')) != 0)
6286 {
6287 *c = '-';
6288 }
6289 name = nameBuf;
6290 }
6291
6292 if (!value)
6293 {
6294 value = "true";
6295 }
6296 else if (value[0] == '=')
6297 {
6298 value++;
6299 }
6300
6301#if defined(_MSC_VER)
6302#define OPT(STR) else if (!_stricmp(name, STR))
6303#define OPT2(STR1, STR2) \
6304 else if (!_stricmp(name, STR1) || !_stricmp(name, STR2))
6305#else
6306#define OPT(STR) else if (!strcasecmp(name, STR))
6307#define OPT2(STR1, STR2) else if (!strcasecmp(name, STR1) || !strcasecmp(name, STR2))
6308#endif
6309#define COMPARE(STR1, STR2, STR3) \
6310 if ((atoi(STR1) > (STR2)) || (atoi(STR1) < (STR3))) \
6311 { \
6312 return NI_RETCODE_PARAM_ERROR_OOR; \
6313 }
6314 if (0); // suppress cppcheck
6316 {
6317 if (AV_CODEC_DEFAULT_BITRATE == p_params->bitrate)
6318 {
6319 if (atoi(value) > NI_MAX_BITRATE)
6320 {
6322 }
6323 if (atoi(value) < NI_MIN_BITRATE)
6324 {
6326 }
6327 p_params->bitrate = atoi(value);
6328 }
6329 }
6331 {
6332 p_params->reconf_demo_mode = atoi(value); // for encoder reconfiguration testing
6333 }
6335 {
6336 ni_retcode_t retval = ni_parse_reconf_file(value, p_params->reconf_hash);
6337 if (retval != NI_RETCODE_SUCCESS) // for encoder reconfiguration testing
6338 {
6339 return retval;
6340 }
6341 }
6343 {
6344 // for encoder reconfiguration testing
6345 p_params->roi_demo_mode = atoi(value);
6346 if ((p_params->roi_demo_mode < 0) || (p_params->roi_demo_mode > 2))
6347 {
6349 }
6350 }
6352 {
6353 if (0 > atoi(value))
6354 {
6356 }
6357 p_params->low_delay_mode = atoi(value);
6358 }
6360 {
6361 if (atoi(value) < 0 || atoi(value) > 7)
6362 {
6364 }
6365 p_params->minFramesDelay = atoi(value);
6366 }
6368 {
6369 if (0 != atoi(value) && 1 != atoi(value))
6370 {
6372 }
6373 p_params->useMCTF = atoi(value);
6374 }
6376 {
6377 p_params->padding = atoi(value);
6378 }
6379#ifndef DEPRECATION_AS_ERROR
6381 {
6382 if (0 != atoi(value) && 1 != atoi(value))
6383 {
6385 }
6386 p_params->generate_enc_hdrs = atoi(value);
6387 // genHdrs is deprecated in favour of libavcodec parameter -gen_global_headers
6389 }
6390#endif
6392 {
6393 if (0 != atoi(value) && 1 != atoi(value))
6394 {
6396 }
6397 p_params->use_low_delay_poc_type = atoi(value);
6398 }
6400 {
6401 if (QUADRA)
6402 {
6404 }
6405 p_params->force_frame_type = atoi(value);
6406 }
6408 {
6409 p_enc->profile = atoi(value);
6410 }
6412 {
6413 /* Check specifically for Level 1b for H.264 */
6414 if (!strcasecmp(value, "1b"))
6415 {
6416 p_enc->level_idc = 99;
6417 }
6418 else
6419 {
6423 if (atof(value) <= 10)
6424 {
6425 p_enc->level_idc = (int)(10 * atof(value) + .5);
6426 }
6427 else
6428 {
6429 p_enc->level_idc = atoi(value);
6430 }
6431 }
6432 }
6434 {
6435 p_enc->high_tier = atobool(value);
6436 }
6438 {
6439 p_params->log = atoi(value);
6440 if (b_error)
6441 {
6442 b_error = false;
6443 p_params->log = ni_parse_name(value, g_xcoder_log_names, &b_error) - 1;
6444 }
6445 }
6447 {
6448 if ((atoi(value) > NI_MAX_GOP_PRESET_IDX) || (atoi(value) < NI_MIN_GOP_PRESET_IDX))
6449 {
6451 }
6452 p_enc->gop_preset_index = atoi(value);
6453 }
6455 {
6457 {
6459 }
6460
6461 p_enc->use_recommend_enc_params = atoi(value);
6462 }
6464 {
6465 if (QUADRA)
6466 {
6468 }
6469 if (((atoi(value) > NI_MAX_CU_SIZE_MODE) || (atoi(value) < NI_MIN_CU_SIZE_MODE)) && (atoi(value) != NI_DEFAULT_CU_SIZE_MODE))
6470 {
6472 }
6473
6474 p_enc->cu_size_mode = atoi(value);
6475 }
6477 {
6478 if (QUADRA)
6479 {
6481 }
6482 if ((atoi(value) > NI_MAX_MAX_NUM_MERGE) || (atoi(value) < NI_MIN_MAX_NUM_MERGE))
6483 {
6485 }
6486
6487 p_enc->max_num_merge = atoi(value);
6488 }
6490 {
6491 if (QUADRA)
6492 {
6494 }
6495 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6496 {
6498 }
6499
6500 p_enc->enable_dynamic_8x8_merge = atoi(value);
6501 }
6503 {
6504 if (QUADRA)
6505 {
6507 }
6508 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6509 {
6511 }
6512
6513 p_enc->enable_dynamic_16x16_merge = atoi(value);
6514 }
6516 {
6517 if (QUADRA)
6518 {
6520 }
6521 if ((atoi(value) > NI_MAX_DYNAMIC_MERGE) || (atoi(value) < NI_MIN_DYNAMIC_MERGE))
6522 {
6524 }
6525
6526 p_enc->enable_dynamic_32x32_merge = atoi(value);
6527 }
6529 {
6530 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6531 {
6533 }
6534
6535 p_enc->rc.enable_rate_control = atoi(value);
6536 }
6538 {
6539 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6540 {
6542 }
6543
6544 p_enc->rc.enable_cu_level_rate_control = atoi(value);
6545 }
6547 {
6548 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6549 {
6551 }
6552 p_enc->rc.enable_hvs_qp = atoi(value);
6553 }
6555 {
6556 if (QUADRA)
6557 {
6559 }
6560 p_enc->rc.enable_hvs_qp_scale = atoi(value);
6561 }
6563 {
6564 p_enc->rc.hvs_qp_scale = atoi(value);
6565 }
6567 {
6568 p_enc->rc.min_qp = atoi(value);
6569 }
6571 {
6572 p_enc->rc.max_qp = atoi(value);
6573 }
6575 {
6576 if (QUADRA)
6577 {
6579 }
6580 p_enc->rc.max_delta_qp = atoi(value);
6581 }
6582#ifndef DEPRECATION_AS_ERROR
6584 {
6585 if ((atoi(value) > 51) || (atoi(value) < -1))
6586 {
6588 }
6589 p_enc->crf = atoi(value);
6590 }
6591#endif
6593 {
6594 p_enc->rc.vbv_buffer_size = atoi(value);
6595 if (QUADRA)
6596 {
6597 // RcInitDelay is deprecated and replaced with vbvBufferSize. But still accept the value.
6599 }
6600 }
6602 {
6603 p_enc->rc.vbv_buffer_size = atoi(value);
6604 }
6606 {
6607 p_enc->rc.vbv_max_rate = atoi(value);
6608 }
6610 {
6611 p_enc->rc.enable_filler = atoi(value);
6612 if (QUADRA)
6613 {
6614 // cbr is deprecated and replaced with fillerEnable. But still accept the value.
6616 }
6617 }
6619 {
6620 p_enc->rc.enable_filler = atoi(value);
6621 }
6623 {
6624 if (0 != atoi(value) && 1 != atoi(value))
6625 {
6627 }
6628 // Currenly pic skip is supported for low delay gops only - pic skip issues tracked by QDFW-1785/1958
6629 p_enc->rc.enable_pic_skip = atoi(value);
6630 }
6631#ifndef DEPRECATION_AS_ERROR
6633#else
6635#endif
6636 {
6637#ifdef _MSC_VER
6638 if (!_strnicmp(value, "ratio", 5))
6639#else
6640 if (!strncasecmp(value, "ratio", 5))
6641#endif
6642 {
6643 char value_buf[32] = {0};
6644 for (i = 0; i < sizeof(value_buf); i++)
6645 {
6646 if (value[i+6] == ']')
6647 {
6648 break;
6649 }
6650 value_buf[i] = value[i+6];
6651 }
6652 if (i == sizeof(value_buf) || atoi(value_buf) < 0)
6653 {
6655 }
6656
6657 p_enc->maxFrameSizeRatio = atoi(value_buf);
6658 }
6659 else
6660 {
6661 int size = atoi(value);
6662 if (size < NI_MIN_FRAME_SIZE)
6663 {
6665 }
6666 p_enc->maxFrameSize = (size > NI_MAX_FRAME_SIZE) ? NI_MAX_FRAME_SIZE : size;
6667 }
6668 }
6670 {
6671#ifdef _MSC_VER
6672 if (!_strnicmp(value, "ratio", 5))
6673#else
6674 if (!strncasecmp(value, "ratio", 5))
6675#endif
6676 {
6677 char value_buf[32] = {0};
6678 for (i = 0; i < sizeof(value_buf); i++)
6679 {
6680 if (value[i+6] == ']')
6681 {
6682 break;
6683 }
6684 value_buf[i] = value[i+6];
6685 }
6686 if (i == sizeof(value_buf) || atoi(value_buf) < 0)
6687 {
6689 }
6690
6691 p_enc->maxFrameSizeRatio = atoi(value_buf);
6692 }
6693 else
6694 {
6695 int size = atoi(value) / 8;
6696 if (size < NI_MIN_FRAME_SIZE)
6697 {
6699 }
6700 p_enc->maxFrameSize = (size > NI_MAX_FRAME_SIZE) ? NI_MAX_FRAME_SIZE : size;
6701 }
6702 }
6704 {
6705 if (0 != atoi(value) && 1 != atoi(value))
6706 {
6708 }
6709 p_enc->forced_header_enable = atoi(value);
6710 }
6712 {
6713 p_enc->roi_enable = atoi(value);
6714 }
6716 {
6717 p_enc->conf_win_top = atoi(value);
6718 }
6720 {
6721 p_enc->conf_win_bottom = atoi(value);
6722 }
6724 {
6725 p_enc->conf_win_left = atoi(value);
6726 }
6728 {
6729 p_enc->conf_win_right = atoi(value);
6730 }
6732 {
6733 p_enc->intra_period = atoi(value);
6734 //p_enc->bitrateWindow = p_enc->intra_period;
6735 }
6737 {
6738 if (atoi(value) > NI_MAX_BITRATE)
6739 {
6741 }
6742 if (atoi(value) < NI_MIN_BITRATE)
6743 {
6745 }
6746 p_enc->rc.trans_rate = atoi(value);
6747 }
6749 {
6750 if (atoi(value) <= 0 )
6751 {
6753 }
6754 p_params->fps_number = atoi(value);
6755 p_params->fps_denominator = 1;
6756 p_enc->frame_rate = (int)p_params->fps_number;
6757 }
6759 {
6760 if (atoi(value) <= 0)
6761 {
6763 }
6764 p_params->fps_denominator = atoi(value);
6765 p_enc->frame_rate = (int)(p_params->fps_number / p_params->fps_denominator);
6766 }
6768 {
6769 if ((atoi(value) > NI_MAX_INTRA_QP) || (atoi(value) < NI_MIN_INTRA_QP))
6770 {
6772 }
6773
6774 p_enc->rc.intra_qp = atoi(value);
6775 }
6777 {
6778 if ((atoi(value) > NI_MAX_INTRA_QP_DELTA) ||
6779 (atoi(value) < NI_MIN_INTRA_QP_DELTA))
6780 {
6782 }
6783
6784 p_enc->rc.intra_qp_delta = atoi(value);
6785 }
6787 {
6788 if ((atoi(value) > NI_MAX_INTRA_QP) || (atoi(value) < NI_MIN_INTRA_QP))
6789 {
6791 }
6792 p_params->force_pic_qp_demo_mode = atoi(value);
6793 }
6795 {
6796 if (QUADRA)
6797 {
6799 }
6801 {
6803 }
6804 p_enc->decoding_refresh_type = atoi(value);
6805 }
6807 {
6808 if (0 != atoi(value) && 1 != atoi(value))
6809 {
6811 }
6812 p_enc->intra_reset_refresh = atoi(value);
6813 }
6814 // Rev. B: H.264 only parameters.
6816 {
6817 if (QUADRA)
6818 {
6820 }
6821 p_enc->enable_transform_8x8 = atoi(value);
6822 }
6824 {
6825 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6826 {
6828 }
6829 p_enc->slice_mode = atoi(value);
6830 }
6832 {
6833 p_enc->slice_arg = atoi(value);
6834 }
6836 {
6837 if (0 != atoi(value) && 1 != atoi(value))
6838 {
6840 }
6841 p_enc->entropy_coding_mode = atoi(value);
6842 }
6843// Rev. B: shared between HEVC and H.264
6845 {
6846 p_enc->intra_mb_refresh_mode = atoi(value);
6847 }
6849 {
6850 p_enc->intra_mb_refresh_arg = atoi(value);
6851 }
6853 {
6854 if ((atoi(value) > NI_MAX_BIN) || (atoi(value) < NI_MIN_BIN))
6855 {
6857 }
6858 p_enc->rc.enable_mb_level_rc = atoi(value);
6859 if (QUADRA)
6860 {
6861 // mbLevelRcEnable will be deprecated and cuLevelRCEnable should be used instead. But still accept the value.
6863 }
6864 }
6866 {
6867 if ((atoi(value) > 255) || (atoi(value) < 0))
6868 {
6870 }
6872 }
6874 {
6875 if (atoi(value) != 0 && atoi(value) != 5)
6876 {
6878 }
6879 p_params->dolby_vision_profile = atoi(value);
6880 }
6882 {
6883 if ((atoi(value) > 3) || (atoi(value) < 1))
6884 {
6886 }
6887 p_enc->rdoLevel = atoi(value);
6888 }
6890 {
6891 const char delim[2] = ",";
6892 char *chunk;
6893#ifdef _MSC_VER
6894 char *v = _strdup(value);
6895#else
6896 char *v = strdup(value);
6897#endif
6898 char *saveptr = NULL;
6899 chunk = ni_strtok(v, delim, &saveptr);
6900 if (chunk != NULL)
6901 {
6902 if ((atoi(chunk) > 65535) || (atoi(chunk) < 0))
6903 {
6904 free(v);
6906 }
6907 p_enc->HDR10MaxLight = atoi(chunk);
6908 chunk = ni_strtok(NULL, delim, &saveptr);
6909 if (chunk != NULL)
6910 {
6911 if ((atoi(chunk) > 65535) || (atoi(chunk) < 0))
6912 {
6913 free(v);
6915 }
6916 p_enc->HDR10AveLight = atoi(chunk);
6917 p_enc->HDR10CLLEnable = 1; //Both param populated so enable
6918 free(v);
6919 }
6920 else
6921 {
6922 free(v);
6924 }
6925 }
6926 else
6927 {
6928 free(v);
6930 }
6931 }
6932
6934 {
6935#ifdef _MSC_VER
6936#define STRDUP(value) _strdup(value);
6937#else
6938#define STRDUP(value) strdup(value);
6939#endif
6940 const char G[2] = "G";
6941 const char B[2] = "B";
6942 const char R[2] = "R";
6943 const char W[2] = "W";
6944 const char L[2] = "L";
6945 const char P[2] = "P";
6946 const char parL[2] = "(";
6947 const char comma[2] = ",";
6948 const char parR[2] = ")";
6949 int synCheck_GBRWLPCP[8];
6950 int posCheck_GBRWL[5] = {0};
6951 char *chunk;//for parsing out more complex inputs
6952 char *subchunk;
6953 char *v = STRDUP(value);
6954 //basic check syntax correct
6955 for (i = 0; i<8; i++)
6956 {
6957 synCheck_GBRWLPCP[i] = 0;
6958 }
6959 chunk = v;
6960 i = 0; // character index
6961
6962 //count keys and punctuation, save indicies to be parsed
6963 while (*chunk) {
6964 if (*chunk == G[0])
6965 {
6966 synCheck_GBRWLPCP[0]++;
6967 posCheck_GBRWL[0] = i;
6968 }
6969 else if (*chunk == B[0])
6970 {
6971 synCheck_GBRWLPCP[1]++;
6972 posCheck_GBRWL[1] = i;
6973 }
6974 else if (*chunk == R[0])
6975 {
6976 synCheck_GBRWLPCP[2]++;
6977 posCheck_GBRWL[2] = i;
6978 }
6979 else if (*chunk == W[0])
6980 {
6981 synCheck_GBRWLPCP[3]++;
6982 posCheck_GBRWL[3] = i;
6983 }
6984 else if (*chunk == L[0])
6985 {
6986 synCheck_GBRWLPCP[4]++;
6987 posCheck_GBRWL[4] = i;
6988 }
6989 else if (*chunk == parL[0])
6990 {
6991 synCheck_GBRWLPCP[5]++;
6992 }
6993 else if (*chunk == comma[0])
6994 {
6995 synCheck_GBRWLPCP[6]++;
6996 }
6997 else if (*chunk == parR[0])
6998 {
6999 synCheck_GBRWLPCP[7]++;
7000 }
7001 chunk++;
7002 i++;
7003 }
7004 free(v);
7005 if (synCheck_GBRWLPCP[0] != 1 || synCheck_GBRWLPCP[1] != 1 || synCheck_GBRWLPCP[2] != 1 ||
7006 synCheck_GBRWLPCP[3] != 1 || synCheck_GBRWLPCP[4] != 1 || synCheck_GBRWLPCP[5] != 5 ||
7007 synCheck_GBRWLPCP[6] != 5 || synCheck_GBRWLPCP[7] != 5)
7008 {
7010 }
7011
7012 //Parse a key-value set like G(%hu, %hu)
7013#define GBRWLPARSE(OUT1,OUT2,OFF,IDX) \
7014{ \
7015 char *v = STRDUP(value); \
7016 chunk = v + posCheck_GBRWL[IDX]; \
7017 i = j = k = 0; \
7018 while (chunk != NULL) \
7019 { \
7020 if (*chunk == parL[0] && i == 1+(OFF)) \
7021 { \
7022 j = 1; \
7023 } \
7024 if((OFF) == 1 && *chunk != P[0] && i == 1) \
7025 { \
7026 break; \
7027 } \
7028 if (*chunk == parR[0]) \
7029 { \
7030 k = 1; \
7031 break; \
7032 } \
7033 i++; \
7034 chunk++; \
7035 } \
7036 if (!j || !k) \
7037 { \
7038 free(v); \
7039 return NI_RETCODE_PARAM_INVALID_VALUE; \
7040 } \
7041 subchunk = malloc(i - 1 - (OFF)); \
7042 if (subchunk == NULL) \
7043 { \
7044 free(v); \
7045 return NI_RETCODE_ERROR_MEM_ALOC; \
7046 } \
7047 memcpy(subchunk, v + posCheck_GBRWL[IDX] + 2 + (OFF), i - 2 - (OFF)); \
7048 subchunk[i - 2 - (OFF)] = '\0'; \
7049 char *saveptr = NULL; \
7050 chunk = ni_strtok(subchunk, comma, &saveptr); \
7051 if (chunk != NULL) \
7052 { \
7053 if(atoi(chunk) < 0) \
7054 { \
7055 free(v); \
7056 if(subchunk != NULL){ \
7057 free(subchunk); \
7058 } \
7059 return NI_RETCODE_PARAM_INVALID_VALUE; \
7060 } \
7061 *(OUT1) = atoi(chunk); \
7062 } \
7063 chunk = ni_strtok(NULL, comma, &saveptr); \
7064 if (chunk != NULL) \
7065 { \
7066 if(atoi(chunk) < 0) \
7067 { \
7068 free(v); \
7069 if(subchunk != NULL){ \
7070 free(subchunk); \
7071 } \
7072 return NI_RETCODE_PARAM_INVALID_VALUE; \
7073 } \
7074 *(OUT2) = atoi(chunk); \
7075 } \
7076 free(subchunk); \
7077 free(v); \
7078}
7079 GBRWLPARSE(&p_enc->HDR10dx0, &p_enc->HDR10dy0, 0, 0);
7080 GBRWLPARSE(&p_enc->HDR10dx1, &p_enc->HDR10dy1, 0, 1);
7081 GBRWLPARSE(&p_enc->HDR10dx2, &p_enc->HDR10dy2, 0, 2);
7082 GBRWLPARSE(&p_enc->HDR10wx, &p_enc->HDR10wy, 1, 3);
7083 GBRWLPARSE(&p_enc->HDR10maxluma, &p_enc->HDR10minluma, 0, 4);
7084 p_enc->HDR10Enable = 1;
7085 }
7087 {
7088 if (atoi(value)!= 0 && ((atoi(value) > 40 ) || (atoi(value) < 4)))
7089 {
7091 }
7092 p_enc->lookAheadDepth = atoi(value);
7093 }
7095 {
7096 if (atoi(value) != 0 && atoi(value) != 1)
7097 {
7099 }
7100 p_enc->hrdEnable = atoi(value);
7101 }
7103 {
7104 if ((atoi(value) != 0) && (atoi(value) != 1))
7105 {
7107 }
7108 p_enc->EnableAUD = atoi(value);
7109 }
7111 {
7112 if (atoi(value) != 0 && atoi(value) != 1)
7113 {
7115 }
7116 p_params->cacheRoi = atoi(value);
7117 }
7119 {
7120 if (atoi(value) != 0 && atoi(value) != 1)
7121 {
7123 }
7124 p_enc->long_term_ref_enable = atoi(value);
7125 }
7127 {
7128 p_enc->long_term_ref_interval = atoi(value);
7129 }
7131 {
7132 if (atoi(value) < 1 || atoi(value) > 2)
7133 {
7135 }
7136 p_enc->long_term_ref_count = atoi(value);
7137 }
7139 {
7140 if ((atoi(value) != 0) && (atoi(value) != 1))
7141 {
7143 }
7144 p_enc->EnableRdoQuant = atoi(value);
7145 }
7147 {
7148 if (QUADRA)
7149 {
7151 }
7152
7153 if ((atoi(value) < 0) || (atoi(value) > 3))
7154 {
7156 }
7157 p_enc->ctbRcMode = atoi(value);
7158 }
7160 {
7161 if (QUADRA)
7162 {
7164 }
7165
7166 p_enc->gopSize = atoi(value);
7167 }
7169 {
7170 if (QUADRA)
7171 {
7173 }
7174
7175 if ((atoi(value) != 0) && (atoi(value) != 1))
7176 {
7178 }
7179 p_enc->gopLowdelay = atoi(value);
7180 }
7182 {
7183 if (QUADRA)
7184 {
7186 }
7187 p_enc->gdrDuration = atoi(value);
7188 }
7190 {
7191 p_enc->ltrRefInterval = atoi(value);
7192 }
7194 {
7195 p_enc->ltrRefQpOffset = atoi(value);
7196 }
7198 {
7199 p_enc->ltrFirstGap = atoi(value);
7200 }
7203 {
7204 if ((atoi(value) != 0) && (atoi(value) != 1))
7205 {
7207 }
7208 p_enc->multicoreJointMode = atoi(value);
7209 }
7211 {
7212 if ((atoi(value) < 0) || (atoi(value) > 9))
7213 {
7215 }
7216 p_enc->qlevel = atoi(value);
7217 }
7219 {
7220 if ((atoi(value) > 12) || (atoi(value) < -12))
7221 {
7223 }
7224 p_enc->chromaQpOffset = atoi(value);
7225 }
7226 OPT(NI_ENC_PARAM_TOL_RC_INTER) { p_enc->tolCtbRcInter = (float)atof(value); }
7227 OPT(NI_ENC_PARAM_TOL_RC_INTRA) { p_enc->tolCtbRcIntra = (float)atof(value); }
7229 {
7230 if ((atoi(value) > 300) || (atoi(value) < 1))
7231 {
7233 }
7234 p_enc->bitrateWindow = atoi(value);
7235 }
7237 {
7238 if ((atoi(value) > 2) || (atoi(value) < 0))
7239 {
7241 }
7242 p_enc->blockRCSize = atoi(value);
7243 }
7245 {
7246 if ((atoi(value) > 15) || (atoi(value) < 0))
7247 {
7249 }
7250 p_enc->rcQpDeltaRange = atoi(value);
7251 }
7253 {
7254 if ((atoi(value) > 500) || (atoi(value) < 0))
7255 {
7257 }
7258 p_enc->ctbRowQpStep = atoi(value);
7259 }
7261 {
7262 if ((atoi(value) > 1) || (atoi(value) < 0))
7263 {
7265 }
7266 p_enc->newRcEnable = atoi(value);
7267 }
7269 {
7270 if ((atoi(value) > 1) || (atoi(value) < 0))
7271 {
7273 }
7274 p_enc->inLoopDSRatio = atoi(value);
7275 }
7277 {
7278 COMPARE(value, 22, 0)
7279 p_params->color_primaries = p_enc->colorPrimaries = atoi(value);
7280 p_enc->colorDescPresent = 1;
7281 }
7283 {
7284 COMPARE(value, 18, 0)
7285 p_params->color_transfer_characteristic = p_enc->colorTrc = atoi(value);
7286 p_enc->colorDescPresent = 1;
7287 }
7289 {
7290 COMPARE(value, 14, 0)
7291 p_params->color_space = p_enc->colorSpace = atoi(value);
7292 p_enc->colorDescPresent = 1;
7293 }
7295 {
7296 p_params->sar_num = p_enc->aspectRatioWidth = atoi(value);
7297 }
7299 {
7300 p_params->sar_denom = p_enc->aspectRatioHeight = atoi(value);
7301 }
7303 {
7304 p_params->video_full_range_flag = p_enc->videoFullRange = atoi(value);
7305 }
7307 {
7308 if ((atoi(value) < NI_MIN_KEEP_ALIVE_TIMEOUT) ||
7310 {
7312 }
7313 p_enc->keep_alive_timeout = atoi(value);
7314 }
7316 {
7317 if (atoi(value) != 0 && atoi(value) != 1)
7318 {
7320 }
7321 p_params->enable_vfr = atoi(value);
7322 }
7324 {
7325 if (atoi(value) < 0 || atoi(value) > 3)
7326 {
7328 }
7329 p_enc->get_psnr_mode = atoi(value);
7330 }
7332 {
7333 if (atoi(value) < 1)
7334 {
7336 }
7337 p_params->interval_of_psnr = atoi(value);
7338 }
7340 {
7341 if (atoi(value) < 0 || atoi(value) > 1)
7342 {
7344 }
7345 p_enc->get_psnr_mode = atoi(value) + 3;
7346 }
7348 {
7349 if ((atoi(value) != 0) && (atoi(value) != 1))
7350 {
7352 }
7353 p_enc->enable_ssim = atoi(value);
7354 }
7356 {
7357 if ((atoi(value) != 0) && (atoi(value) != 1))
7358 {
7360 }
7361 p_enc->av1_error_resilient_mode = atoi(value);
7362 }
7364 {
7365 if ((atoi(value) != 0) && (atoi(value) != 1))
7366 {
7368 }
7369 p_params->staticMmapThreshold = atoi(value);
7370 }
7372 {
7373 p_enc->temporal_layers_enable = atoi(value);
7374 }
7376 {
7377 if ((atoi(value) != 0) && (atoi(value) != 1))
7378 {
7380 }
7381 p_params->enable_ai_enhance = atoi(value);
7382 }
7384 {
7385 if ((atoi(value) != 0) && (atoi(value) != 1))
7386 {
7388 }
7389 if(p_params->enable_ai_enhance)
7390 {
7391 ni_log(NI_LOG_ERROR, "Cannot set enableAIEnhance and enableHVSPlus at same time, just enableHVSPlus\n");
7392 }
7393 p_params->enable_ai_enhance = (atoi(value) == 1) ? 2 : 0;
7394 }
7396 {
7397 if ((atoi(value) != 0) && (atoi(value) != 1))
7398 {
7400 }
7401 p_params->enable2PassGop = atoi(value);
7402 }
7404 {
7405 if ((atoi(value) != 0) && (atoi(value) != 1) && (atoi(value) != -1))
7406 {
7408 }
7409 p_params->zerocopy_mode = atoi(value);
7410 }
7412 {
7413 if ((atoi(value) == 0) || (atoi(value) > 3))
7414 {
7416 }
7417 p_params->ai_enhance_level = atoi(value);
7418 }
7420 {
7421 if ((atoi(value) == 0) || (atoi(value) > 2))
7422 {
7424 }
7425 p_params->ai_enhance_level = atoi(value);
7426 }
7428 {
7429 if ((atoi(value) < NI_MIN_WIDTH) ||
7430 (atoi(value) > NI_PARAM_MAX_WIDTH))
7431 {
7433 }
7434 p_enc->crop_width = atoi(value);
7435 }
7437 {
7438 if ((atoi(value) < NI_MIN_HEIGHT) ||
7439 (atoi(value) > NI_PARAM_MAX_HEIGHT))
7440 {
7442 }
7443 p_enc->crop_height = atoi(value);
7444 }
7446 {
7447 if ((atoi(value) < 0) ||
7448 (atoi(value) > NI_PARAM_MAX_WIDTH))
7449 {
7451 }
7452 p_enc->hor_offset = atoi(value);
7453 }
7455 {
7456 if ((atoi(value) < 0) ||
7457 (atoi(value) > NI_PARAM_MAX_HEIGHT))
7458 {
7460 }
7461 p_enc->ver_offset = atoi(value);
7462 }
7464 {
7465 if ((atoi(value) > 51) || (atoi(value) < -1))
7466 {
7468 }
7469 p_enc->crfMax = atoi(value);
7470 }
7472 {
7473 if ((atof(value) > 1.0) || (atof(value) < 0.0))
7474 {
7476 }
7477 p_enc->qcomp = (float)atof(value);
7478 }
7480 {
7481 if ((atoi(value) != 0) && (atoi(value) != 1))
7482 {
7484 }
7485 p_enc->noMbtree = atoi(value);
7486 }
7488 {
7489 if ((atoi(value) != 0) && (atoi(value) != 1))
7490 {
7492 }
7493 p_enc->avcc_hvcc = atoi(value);
7494 }
7496 {
7497 if ((atoi(value) != 0) && (atoi(value) != 1))
7498 {
7500 }
7501 p_enc->noHWMultiPassSupport = atoi(value);
7502 }
7504 {
7505 if ((atoi(value) > 10) || (atoi(value) < 1))
7506 {
7508 }
7509 p_enc->cuTreeFactor = atoi(value);
7510 }
7512 {
7513 if ((atof(value) > 10.0) || (atof(value) < 0.01))
7514 {
7516 }
7517 p_enc->ipRatio = (float)atof(value);
7518 }
7520 {
7521 if ((atoi(value) != 0) && (atoi(value) != 1))
7522 {
7524 }
7525 p_enc->enableipRatio = atoi(value);
7526 }
7528 {
7529 if ((atof(value) > 10.0) || (atof(value) < 0.01))
7530 {
7532 }
7533 p_enc->pbRatio = (float)atof(value);
7534 }
7536 {
7537 if ((atof(value) > 1.0) || (atof(value) < 0.1))
7538 {
7540 }
7541 p_enc->cplxDecay = (float)atof(value);
7542 }
7544 {
7545 if ((atoi(value) > 51) || (atoi(value) < -1))
7546 {
7548 }
7549 p_enc->pps_init_qp = atoi(value);
7550 }
7552 {
7553 if (atoi(value) >= NI_DDR_PRIORITY_MAX ||
7554 atoi(value) <= NI_DDR_PRIORITY_NONE)
7555 {
7557 }
7558 p_params->ddr_priority_mode = atoi(value);
7559 }
7561 {
7562 if ((atoi(value) != 0) && (atoi(value) != 1))
7563 {
7565 }
7566 p_enc->bitrateMode = atoi(value);
7567 }
7569 {
7570 if ((atoi(value) > 51) || (atoi(value) < -1))
7571 {
7573 }
7574 p_enc->pass1_qp = atoi(value);
7575 }
7577 {
7578 if (((atof(value) < 0.0) && (atof(value) != -1.0)) ||
7579 (atof(value) > 51.00))
7580 {
7582 }
7583 p_enc->crfFloat = (float)atof(value);
7584 }
7586 {
7587 if ((atoi(value) < 0) || (atoi(value) > 31))
7588 {
7590 }
7591 p_enc->hvsBaseMbComplexity = atoi(value);
7592 }
7594 {
7595 if (atoi(value) != 0 && atoi(value) != 1 && atoi(value) != 6)
7596 {
7598 }
7599 p_enc->statistic_output_level = atoi(value);
7600 }
7602 {
7603 //Currently only support 6 stillImage detect level
7604 //0-3: no performance drop
7605 //4-6: performance drop
7606 if ((atoi(value) < 0 || atoi(value) > 6))
7607 {
7609 }
7610 p_enc->still_image_detect_level = atoi(value);
7611 }
7613 {
7614 //Currently only support 10 sceneChange detect level
7615 //1-5 : no performance drop
7616 //6-10: performance drop
7617 if ((atoi(value) < 0 || atoi(value) > 10))
7618 {
7620 }
7621 p_enc->scene_change_detect_level = atoi(value);
7622 }
7624 {
7625 if ((atoi(value) != 0) && (atoi(value) != 1))
7626 {
7628 }
7629 p_enc->enable_smooth_crf = atoi(value);
7630 }
7632 {
7633 if ((atoi(value) != 0) && (atoi(value) != 1))
7634 {
7636 }
7637 p_enc->enable_compensate_qp = atoi(value);
7638 }
7640 {
7641 if (atoi(value) < 0 || atoi(value) > 1)
7642 {
7644 }
7645 p_enc->skip_frame_enable = atoi(value);
7646 }
7648 {
7649 if (atoi(value) < 0)
7650 {
7652 }
7653 p_enc->max_consecutive_skip_num = atoi(value);
7654 }
7656 {
7657 if (atoi(value) < 0 || atoi(value) > 255)
7658 {
7660 }
7661 p_enc->skip_frame_interval = atoi(value);
7662 }
7664 {
7665 if (atoi(value) != 0 && atoi(value) != 1)
7666 {
7668 }
7669 p_enc->enable_all_sei_passthru = atoi(value);
7670 }
7672 {
7673 if (atoi(value) <= 0)
7674 {
7676 }
7677 p_enc->iframe_size_ratio = atoi(value);
7678 }
7680 {
7681 if ((atoi(value) < 0 || atoi(value) > 2) &&
7682 atoi(value) != 5 && atoi(value) != 6 && atoi(value) != 7) // 1 & 5=MEDIUM, 2 & 6=HIGH, 7=OPTIMAL
7683 {
7685 }
7686 p_enc->crf_max_iframe_enable = atoi(value);
7687 }
7689 {
7690 p_enc->vbv_min_rate = atoi(value);
7691 }
7693 {
7694 if (atoi(value) != 0 && atoi(value) != 1)
7695 {
7697 }
7698 p_enc->disable_adaptive_buffers = atoi(value);
7699 }
7701 {
7702 if ((atoi(value) != 0) && (atoi(value) != 1))
7703 {
7705 }
7706 p_enc->disableBframeRdoq = atoi(value);
7707 }
7709 {
7710 if ((atof(value) > 1.0) || (atof(value) < 0.0))
7711 {
7713 }
7714 p_enc->forceBframeQpfactor = (float)atof(value);
7715 }
7717 {
7718 if (atoi(value) < 0 || atoi(value) > 2)
7719 {
7721 }
7722 p_enc->tune_bframe_visual = atoi(value);
7723 }
7725 {
7726 if ((atoi(value) != 0) && (atoi(value) != 1))
7727 {
7729 }
7730 p_enc->enable_acq_limit = atoi(value);
7731 }
7733 {
7734 if (atoi(value) < NI_CUS_ROI_DISABLE || atoi(value) > NI_CUS_ROI_MERGE)
7735 {
7737 }
7738 p_enc->customize_roi_qp_level += atoi(value);
7739 }
7741 {
7743 if (retval != NI_RETCODE_SUCCESS)
7744 {
7745 return retval;
7746 }
7747 // indicate it need to upload roi qp map
7748 p_enc->customize_roi_qp_level += 64;
7749 }
7751 {
7752 if (atoi(value) < 0 || atoi(value) > MOTION_CONSTRAINED_MODE_MAX)
7753 {
7755 }
7756 p_enc->motionConstrainedMode = atoi(value);
7757 }
7759 {
7762 {
7764 }
7765 p_enc->encMallocStrategy = atoi(value);
7766 }
7768 {
7769 if (atoi(value) < 1 || atoi(value) > 4)
7770 {
7772 }
7773 p_enc->spatial_layers = atoi(value);
7774 }
7776 {
7777 if (atoi(value) < 0 || atoi(value) > 1)
7778 {
7780 }
7781 p_enc->enable_timecode = atoi(value);
7782 }
7784 {
7785 if ((atoi(value) != 0) && (atoi(value) != 1))
7786 {
7788 }
7789 p_enc->spatial_layers_ref_base_layer = atoi(value);
7790 }
7792 {
7793 if ((atoi(value) != 0) && (atoi(value) != 1))
7794 {
7796 }
7797 p_enc->vbvBufferReencode = atoi(value);
7798 }
7800 {
7801 if (atoi(value)!= 0 && ((atoi(value) > 40 ) || (atoi(value) < 4)))
7802 {
7804 }
7805 p_enc->totalCuTreeDepth = atoi(value);
7806 }
7808 {
7809 if (atoi(value) != 0 && atoi(value) != 1)
7810 {
7812 }
7813 p_enc->adaptiveCuTree = atoi(value);
7814 }
7816 {
7817 if (atoi(value) != 0 && atoi(value) != 1)
7818 {
7820 }
7821 p_enc->preIntraHandling = atoi(value);
7822 }
7824 {
7825 if (atoi(value) != 0 && atoi(value) != 1)
7826 {
7828 }
7829 p_enc->baseLayerOnly = atoi(value);
7830 }
7832 {
7833 if (atoi(value) < 0 || atoi(value) > 100)
7834 {
7836 }
7837 p_enc->pastFrameMaxIntraRatio = atoi(value);
7838 }
7840 {
7841 if (atoi(value) < 0 || atoi(value) > 100)
7842 {
7844 }
7845 p_enc->linkFrameMaxIntraRatio = atoi(value);
7846 }
7848 {
7849 const char delim[2] = ",";
7850 char *chunk;
7851#ifdef _MSC_VER
7852 char *v = _strdup(value);
7853#else
7854 char *v = strdup(value);
7855#endif
7856 char *saveptr = NULL;
7857 i = 0;
7858 chunk = ni_strtok(v, delim, &saveptr);
7859 while (chunk != NULL && i < NI_MAX_SPATIAL_LAYERS)
7860 {
7861 if ((atoi(chunk) > NI_MAX_BITRATE) || (atoi(chunk) < NI_MIN_BITRATE))
7862 {
7863 free(v);
7865 }
7866 p_enc->spatialLayerBitrate[i] = atoi(chunk);
7867 chunk = ni_strtok(NULL, delim, &saveptr);
7868 i++;
7869 }
7870 free(v);
7871 }
7873 {
7874 const char delim[2] = ",";
7875 char *chunk;
7876#ifdef _MSC_VER
7877 char *v = _strdup(value);
7878#else
7879 char *v = strdup(value);
7880#endif
7881 char *saveptr = NULL;
7882 i = 0;
7883 chunk = ni_strtok(v, delim, &saveptr);
7884 while (chunk != NULL && i < NI_MAX_SPATIAL_LAYERS)
7885 {
7889 if (atof(chunk) <= 10)
7890 {
7891 p_enc->av1OpLevel[i] = (int)(10 * atof(chunk) + .5);
7892 }
7893 else
7894 {
7895 p_enc->av1OpLevel[i] = atoi(chunk);
7896 }
7897 chunk = ni_strtok(NULL, delim, &saveptr);
7898 i++;
7899 }
7900 free(v);
7901 }
7903 {
7904 if ((atoi(value) != 0) && (atoi(value) != 1))
7905 {
7907 }
7908 p_enc->disableAv1TimingInfo = atoi(value);
7909 }
7911 {
7912 if ((atoi(value) != 0) && (atoi(value) != 1))
7913 {
7915 }
7916 p_params->enableCpuAffinity = atoi(value);
7917 }
7919 {
7920 for (i = 0; i < NI_NUM_PRESETS_MAX; i++) {
7921 if (0 == strcmp(value, g_xcoder_preset_names[i])) {
7922 p_enc->preset_index = i;
7923 break;
7924 }
7925 else if(i == NI_NUM_PRESETS_MAX - 1) {
7927 }
7928 }
7929 }
7931 {
7932 if (atoi(value) < 0 || atoi(value) > 3)
7933 {
7935 }
7936 p_enc->adaptiveLamdaMode = atoi(value);
7937 }
7939 {
7940 if (atoi(value) < 0 || atoi(value) > 1)
7941 {
7943 }
7944 p_enc->qpScaleEnable = atoi(value);
7945 }
7947 {
7948 if (atoi(value) < 0 || atoi(value) > 2)
7949 {
7951 }
7952 p_enc->adaptiveCrfMode = atoi(value);
7953 }
7955 {
7956 if (atoi(value) < 0 || atoi(value) > 3)
7957 {
7959 }
7960 p_enc->intraCompensateMode = atoi(value);
7961 }
7963 {
7964 if (atoi(value) < 0 || atoi(value) > 255)
7965 {
7967 }
7968 p_enc->customMinCoeffDiv = atoi(value);
7969 }
7971 {
7972 if ((atoi(value) != 0) && (atoi(value) != 1))
7973 {
7975 }
7976 p_enc->getBitstreamFeatures = atoi(value);
7977 }
7979 {
7980 if ((atoi(value) != 0) && (atoi(value) != 1))
7981 {
7983 }
7984 p_enc->clearRefListModification = atoi(value);
7985 }
7987 {
7988 if ((atoi(value) != 0) && (atoi(value) != 1))
7989 {
7991 }
7992 p_enc->longTermReferenceOldest = atoi(value);
7993 }
7994 else { return NI_RETCODE_PARAM_INVALID_NAME; }
7995
7996#undef OPT
7997#undef OPT2
7998#undef atobool
7999#undef atoi
8000#undef atof
8001
8002 b_error |= bValueWasNull && !bNameWasBool;
8003
8004 ni_log(NI_LOG_TRACE, "%s: exit, b_error=%d\n", __func__, b_error);
8005
8007}
8008
8009#undef atoi
8010#undef atof
8011#define atoi(p_str) ni_atoi(p_str, &b_error)
8012#define atof(p_str) ni_atof(p_str, &b_error)
8013#define atobool(p_str) (ni_atobool(p_str, &b_error))
8014
8015/*!*****************************************************************************
8016 * \brief Set GOP parameter value referenced by name in encoder parameters
8017 * structure
8018 *
8019 * \param[in] p_params Pointer to a user allocated ni_xcoder_params_t
8020 * to find and set a particular parameter
8021 * \param[in] name String represented parameter name to search
8022 * \param[in] value Parameter value to set
8023*
8024 * \return On success
8025 * NI_RETCODE_SUCCESS
8026 * On failure
8027 * NI_RETCODE_FAILURE
8028 * NI_RETCODE_INVALID_PARAM
8029 ******************************************************************************/
8031 const char *name,
8032 const char *value)
8033{
8034 bool b_error = false;
8035 bool bNameWasBool = false;
8036 bool bValueWasNull = !value;
8037 ni_encoder_cfg_params_t *p_enc = NULL;
8038 ni_custom_gop_params_t* p_gop = NULL;
8039 char nameBuf[64] = { 0 };
8040
8041 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
8042
8043 if (!p_params)
8044 {
8045 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
8046 __func__);
8048 }
8049
8050 if ( !name )
8051 {
8052 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null name pointer parameters passed\n",
8053 __func__);
8055 }
8056 p_enc = &p_params->cfg_enc_params;
8057 p_gop = &p_enc->custom_gop_params;
8058
8059 // skip -- prefix if provided
8060 if (name[0] == '-' && name[1] == '-')
8061 {
8062 name += 2;
8063 }
8064
8065 // s/_/-/g
8066 if (strlen(name) + 1 < sizeof(nameBuf) && strchr(name, '_'))
8067 {
8068 char* c;
8069 ni_strcpy(nameBuf, sizeof(nameBuf), name);
8070 while ((c = strchr(nameBuf, '_')) != 0)
8071 {
8072 *c = '-';
8073 }
8074 name = nameBuf;
8075 }
8076
8077 if (!value)
8078 {
8079 value = "true";
8080 }
8081 else if (value[0] == '=')
8082 {
8083 value++;
8084 }
8085
8086#if defined(_MSC_VER)
8087#define OPT(STR) else if (!_stricmp(name, STR))
8088#else
8089#define OPT(STR) else if (!strcasecmp(name, STR))
8090#endif
8091 if (0); // suppress cppcheck
8093 {
8094 if (atoi(value) > NI_MAX_GOP_SIZE)
8095 {
8097 }
8098 if (atoi(value) < NI_MIN_GOP_SIZE)
8099 {
8101 }
8102 p_gop->custom_gop_size = atoi(value);
8103 }
8104
8105#ifndef QUADRA
8107 {
8108 p_gop->pic_param[0].pic_type = atoi(value);
8109 }
8111 {
8112 p_gop->pic_param[0].poc_offset = atoi(value);
8113 }
8114 OPT(NI_ENC_GOP_PARAMS_G0_PIC_QP)
8115 {
8116 p_gop->pic_param[0].pic_qp = atoi(value);
8117 }
8118 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_PIC_L0)
8119 {
8120 p_gop->pic_param[0].num_ref_pic_L0 = atoi(value);
8121 }
8122 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_POC_L0)
8123 {
8124 p_gop->pic_param[0].ref_poc_L0 = atoi(value);
8125 }
8126 OPT(NI_ENC_GOP_PARAMS_G0_NUM_REF_POC_L1)
8127 {
8128 p_gop->pic_param[0].ref_poc_L1 = atoi(value);
8129 }
8131 {
8132 p_gop->pic_param[0].temporal_id = atoi(value);
8133 }
8134
8136 {
8137 p_gop->pic_param[1].pic_type = atoi(value);
8138 }
8140 {
8141 p_gop->pic_param[1].poc_offset = atoi(value);
8142 }
8143 OPT(NI_ENC_GOP_PARAMS_G1_PIC_QP)
8144 {
8145 p_gop->pic_param[1].pic_qp = atoi(value);
8146 }
8147 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_PIC_L0)
8148 {
8149 p_gop->pic_param[1].num_ref_pic_L0 = atoi(value);
8150 }
8151 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_POC_L0)
8152 {
8153 p_gop->pic_param[1].ref_poc_L0 = atoi(value);
8154 }
8155 OPT(NI_ENC_GOP_PARAMS_G1_NUM_REF_POC_L1)
8156 {
8157 p_gop->pic_param[1].ref_poc_L1 = atoi(value);
8158 }
8160 {
8161 p_gop->pic_param[1].temporal_id = atoi(value);
8162 }
8163
8165 {
8166 p_gop->pic_param[2].pic_type = atoi(value);
8167 }
8169 {
8170 p_gop->pic_param[2].poc_offset = atoi(value);
8171 }
8172 OPT(NI_ENC_GOP_PARAMS_G2_PIC_QP)
8173 {
8174 p_gop->pic_param[2].pic_qp = atoi(value);
8175 }
8176 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_PIC_L0)
8177 {
8178 p_gop->pic_param[2].num_ref_pic_L0 = atoi(value);
8179 }
8180 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_POC_L0)
8181 {
8182 p_gop->pic_param[2].ref_poc_L0 = atoi(value);
8183 }
8184 OPT(NI_ENC_GOP_PARAMS_G2_NUM_REF_POC_L1)
8185 {
8186 p_gop->pic_param[2].ref_poc_L1 = atoi(value);
8187 }
8189 {
8190 p_gop->pic_param[2].temporal_id = atoi(value);
8191 }
8192
8194 {
8195 p_gop->pic_param[3].pic_type = atoi(value);
8196 }
8198 {
8199 p_gop->pic_param[3].poc_offset = atoi(value);
8200 }
8201 OPT(NI_ENC_GOP_PARAMS_G3_PIC_QP)
8202 {
8203 p_gop->pic_param[3].pic_qp = atoi(value);
8204 }
8205 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_PIC_L0)
8206 {
8207 p_gop->pic_param[3].num_ref_pic_L0 = atoi(value);
8208 }
8209 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_POC_L0)
8210 {
8211 p_gop->pic_param[3].ref_poc_L0 = atoi(value);
8212 }
8213 OPT(NI_ENC_GOP_PARAMS_G3_NUM_REF_POC_L1)
8214 {
8215 p_gop->pic_param[3].ref_poc_L1 = atoi(value);
8216 }
8218 {
8219 p_gop->pic_param[3].temporal_id = atoi(value);
8220 }
8221
8223 {
8224 p_gop->pic_param[4].pic_type = atoi(value);
8225 }
8227 {
8228 p_gop->pic_param[4].poc_offset = atoi(value);
8229 }
8230 OPT(NI_ENC_GOP_PARAMS_G4_PIC_QP)
8231 {
8232 p_gop->pic_param[4].pic_qp = atoi(value);
8233 }
8234 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_PIC_L0)
8235 {
8236 p_gop->pic_param[4].num_ref_pic_L0 = atoi(value);
8237 }
8238 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_POC_L0)
8239 {
8240 p_gop->pic_param[4].ref_poc_L0 = atoi(value);
8241 }
8242 OPT(NI_ENC_GOP_PARAMS_G4_NUM_REF_POC_L1)
8243 {
8244 p_gop->pic_param[4].ref_poc_L1 = atoi(value);
8245 }
8247 {
8248 p_gop->pic_param[4].temporal_id = atoi(value);
8249 }
8250
8252 {
8253 p_gop->pic_param[5].pic_type = atoi(value);
8254 }
8256 {
8257 p_gop->pic_param[5].poc_offset = atoi(value);
8258 }
8259 OPT(NI_ENC_GOP_PARAMS_G5_PIC_QP)
8260 {
8261 p_gop->pic_param[5].pic_qp = atoi(value);
8262 }
8263 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_PIC_L0)
8264 {
8265 p_gop->pic_param[5].num_ref_pic_L0 = atoi(value);
8266 }
8267 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_POC_L0)
8268 {
8269 p_gop->pic_param[5].ref_poc_L0 = atoi(value);
8270 }
8271 OPT(NI_ENC_GOP_PARAMS_G5_NUM_REF_POC_L1)
8272 {
8273 p_gop->pic_param[5].ref_poc_L1 = atoi(value);
8274 }
8276 {
8277 p_gop->pic_param[5].temporal_id = atoi(value);
8278 }
8279
8281 {
8282 p_gop->pic_param[6].pic_type = atoi(value);
8283 }
8285 {
8286 p_gop->pic_param[6].poc_offset = atoi(value);
8287 }
8288 OPT(NI_ENC_GOP_PARAMS_G6_PIC_QP)
8289 {
8290 p_gop->pic_param[6].pic_qp = atoi(value);
8291 }
8292 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_PIC_L0)
8293 {
8294 p_gop->pic_param[6].num_ref_pic_L0 = atoi(value);
8295 }
8296 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_POC_L0)
8297 {
8298 p_gop->pic_param[6].ref_poc_L0 = atoi(value);
8299 }
8300 OPT(NI_ENC_GOP_PARAMS_G6_NUM_REF_POC_L1)
8301 {
8302 p_gop->pic_param[6].ref_poc_L1 = atoi(value);
8303 }
8305 {
8306 p_gop->pic_param[6].temporal_id = atoi(value);
8307 }
8308
8310 {
8311 p_gop->pic_param[7].pic_type = atoi(value);
8312 }
8314 {
8315 p_gop->pic_param[7].poc_offset = atoi(value);
8316 }
8317 OPT(NI_ENC_GOP_PARAMS_G7_PIC_QP)
8318 {
8319 p_gop->pic_param[7].pic_qp = atoi(value);
8320 }
8321 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_PIC_L0)
8322 {
8323 p_gop->pic_param[7].num_ref_pic_L0 = atoi(value);
8324 }
8325 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_POC_L0)
8326 {
8327 p_gop->pic_param[7].ref_poc_L0 = atoi(value);
8328 }
8329 OPT(NI_ENC_GOP_PARAMS_G7_NUM_REF_POC_L1)
8330 {
8331 p_gop->pic_param[7].ref_poc_L1 = atoi(value);
8332 }
8334 {
8335 p_gop->pic_param[7].temporal_id = atoi(value);
8336 }
8337 else
8338 {
8339 ni_log(NI_LOG_ERROR, "%s(): Invalid parameter name passed\n", __func__);
8341 }
8342#else
8344 {
8345 p_gop->pic_param[0].poc_offset = atoi(value);
8346 }
8348 {
8349 p_gop->pic_param[0].qp_offset = atoi(value);
8350 }
8351 /*
8352 OPT(NI_ENC_GOP_PARAMS_G0_QP_FACTOR)
8353 {
8354 p_gop->pic_param[0].qp_factor = atof(value);
8355 }
8356 */
8358 {
8359 p_gop->pic_param[0].temporal_id = atoi(value);
8360 }
8362 {
8363 p_gop->pic_param[0].pic_type = atoi(value);
8364 }
8366 {
8367 p_gop->pic_param[0].num_ref_pics = atoi(value);
8368 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 num_ref_pics %d\n", __func__, p_gop->pic_param[0].num_ref_pics);
8369 }
8371 {
8372 p_gop->pic_param[0].rps[0].ref_pic = atoi(value);
8373 //ni_log(NI_LOG_DEBUG, "%s(): Frame1 %d rps[0].ref_pic %d\n", __func__, p_gop->pic_param[0].rps[0].ref_pic);
8374 }
8376 {
8377 p_gop->pic_param[0].rps[0].ref_pic_used = atoi(value);
8378 //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);
8379 }
8381 {
8382 p_gop->pic_param[0].rps[1].ref_pic = atoi(value);
8383 }
8385 {
8386 p_gop->pic_param[0].rps[1].ref_pic_used = atoi(value);
8387 }
8389 {
8390 p_gop->pic_param[0].rps[2].ref_pic = atoi(value);
8391 }
8393 {
8394 p_gop->pic_param[0].rps[2].ref_pic_used = atoi(value);
8395 }
8397 {
8398 p_gop->pic_param[0].rps[3].ref_pic = atoi(value);
8399 }
8401 {
8402 p_gop->pic_param[0].rps[3].ref_pic_used = atoi(value);
8403 }
8404
8406 {
8407 p_gop->pic_param[1].poc_offset = atoi(value);
8408 }
8410 {
8411 p_gop->pic_param[1].qp_offset = atoi(value);
8412 }
8413 /*
8414 OPT(NI_ENC_GOP_PARAMS_G1_QP_FACTOR)
8415 {
8416 p_gop->pic_param[1].qp_factor = atof(value);
8417 }
8418 */
8420 {
8421 p_gop->pic_param[1].temporal_id = atoi(value);
8422 }
8424 {
8425 p_gop->pic_param[1].pic_type = atoi(value);
8426 }
8428 {
8429 p_gop->pic_param[1].num_ref_pics = atoi(value);
8430 }
8432 {
8433 p_gop->pic_param[1].rps[0].ref_pic = atoi(value);
8434 }
8436 {
8437 p_gop->pic_param[1].rps[0].ref_pic_used = atoi(value);
8438 }
8440 {
8441 p_gop->pic_param[1].rps[1].ref_pic = atoi(value);
8442 }
8444 {
8445 p_gop->pic_param[1].rps[1].ref_pic_used = atoi(value);
8446 }
8448 {
8449 p_gop->pic_param[1].rps[2].ref_pic = atoi(value);
8450 }
8452 {
8453 p_gop->pic_param[1].rps[2].ref_pic_used = atoi(value);
8454 }
8456 {
8457 p_gop->pic_param[1].rps[3].ref_pic = atoi(value);
8458 }
8460 {
8461 p_gop->pic_param[1].rps[3].ref_pic_used = atoi(value);
8462 }
8463
8465 {
8466 p_gop->pic_param[2].poc_offset = atoi(value);
8467 }
8469 {
8470 p_gop->pic_param[2].qp_offset = atoi(value);
8471 }
8472 /*
8473 OPT(NI_ENC_GOP_PARAMS_G2_QP_FACTOR)
8474 {
8475 p_gop->pic_param[2].qp_factor = atof(value);
8476 }
8477 */
8479 {
8480 p_gop->pic_param[2].temporal_id = atoi(value);
8481 }
8483 {
8484 p_gop->pic_param[2].pic_type = atoi(value);
8485 }
8487 {
8488 p_gop->pic_param[2].num_ref_pics = atoi(value);
8489 }
8491 {
8492 p_gop->pic_param[2].rps[0].ref_pic = atoi(value);
8493 }
8495 {
8496 p_gop->pic_param[2].rps[0].ref_pic_used = atoi(value);
8497 }
8499 {
8500 p_gop->pic_param[2].rps[1].ref_pic = atoi(value);
8501 }
8503 {
8504 p_gop->pic_param[2].rps[1].ref_pic_used = atoi(value);
8505 }
8507 {
8508 p_gop->pic_param[2].rps[2].ref_pic = atoi(value);
8509 }
8511 {
8512 p_gop->pic_param[2].rps[2].ref_pic_used = atoi(value);
8513 }
8515 {
8516 p_gop->pic_param[2].rps[3].ref_pic = atoi(value);
8517 }
8519 {
8520 p_gop->pic_param[2].rps[3].ref_pic_used = atoi(value);
8521 }
8522
8524 {
8525 p_gop->pic_param[3].poc_offset = atoi(value);
8526 }
8528 {
8529 p_gop->pic_param[3].qp_offset = atoi(value);
8530 }
8531 /*
8532 OPT(NI_ENC_GOP_PARAMS_G3_QP_FACTOR)
8533 {
8534 p_gop->pic_param[3].qp_factor = atof(value);
8535 }
8536 */
8538 {
8539 p_gop->pic_param[3].temporal_id = atoi(value);
8540 }
8542 {
8543 p_gop->pic_param[3].pic_type = atoi(value);
8544 }
8546 {
8547 p_gop->pic_param[3].num_ref_pics = atoi(value);
8548 }
8550 {
8551 p_gop->pic_param[3].rps[0].ref_pic = atoi(value);
8552 }
8554 {
8555 p_gop->pic_param[3].rps[0].ref_pic_used = atoi(value);
8556 }
8558 {
8559 p_gop->pic_param[3].rps[1].ref_pic = atoi(value);
8560 }
8562 {
8563 p_gop->pic_param[3].rps[1].ref_pic_used = atoi(value);
8564 }
8566 {
8567 p_gop->pic_param[3].rps[2].ref_pic = atoi(value);
8568 }
8570 {
8571 p_gop->pic_param[3].rps[2].ref_pic_used = atoi(value);
8572 }
8574 {
8575 p_gop->pic_param[3].rps[3].ref_pic = atoi(value);
8576 }
8578 {
8579 p_gop->pic_param[3].rps[3].ref_pic_used = atoi(value);
8580 }
8581
8583 {
8584 p_gop->pic_param[4].poc_offset = atoi(value);
8585 }
8587 {
8588 p_gop->pic_param[4].qp_offset = atoi(value);
8589 }
8590 /*
8591 OPT(NI_ENC_GOP_PARAMS_G4_QP_FACTOR)
8592 {
8593 p_gop->pic_param[4].qp_factor = atof(value);
8594 }
8595 */
8597 {
8598 p_gop->pic_param[4].temporal_id = atoi(value);
8599 }
8601 {
8602 p_gop->pic_param[4].pic_type = atoi(value);
8603 }
8605 {
8606 p_gop->pic_param[4].num_ref_pics = atoi(value);
8607 }
8609 {
8610 p_gop->pic_param[4].rps[0].ref_pic = atoi(value);
8611 }
8613 {
8614 p_gop->pic_param[4].rps[0].ref_pic_used = atoi(value);
8615 }
8617 {
8618 p_gop->pic_param[4].rps[1].ref_pic = atoi(value);
8619 }
8621 {
8622 p_gop->pic_param[4].rps[1].ref_pic_used = atoi(value);
8623 }
8625 {
8626 p_gop->pic_param[4].rps[2].ref_pic = atoi(value);
8627 }
8629 {
8630 p_gop->pic_param[4].rps[2].ref_pic_used = atoi(value);
8631 }
8633 {
8634 p_gop->pic_param[4].rps[3].ref_pic = atoi(value);
8635 }
8637 {
8638 p_gop->pic_param[4].rps[3].ref_pic_used = atoi(value);
8639 }
8640
8642 {
8643 p_gop->pic_param[5].poc_offset = atoi(value);
8644 }
8646 {
8647 p_gop->pic_param[5].qp_offset = atoi(value);
8648 }
8649 /*
8650 OPT(NI_ENC_GOP_PARAMS_G5_QP_FACTOR)
8651 {
8652 p_gop->pic_param[5].qp_factor = atof(value);
8653 }
8654 */
8656 {
8657 p_gop->pic_param[5].temporal_id = atoi(value);
8658 }
8660 {
8661 p_gop->pic_param[5].pic_type = atoi(value);
8662 }
8664 {
8665 p_gop->pic_param[5].num_ref_pics = atoi(value);
8666 }
8668 {
8669 p_gop->pic_param[5].rps[0].ref_pic = atoi(value);
8670 }
8672 {
8673 p_gop->pic_param[5].rps[0].ref_pic_used = atoi(value);
8674 }
8676 {
8677 p_gop->pic_param[5].rps[1].ref_pic = atoi(value);
8678 }
8680 {
8681 p_gop->pic_param[5].rps[1].ref_pic_used = atoi(value);
8682 }
8684 {
8685 p_gop->pic_param[5].rps[2].ref_pic = atoi(value);
8686 }
8688 {
8689 p_gop->pic_param[5].rps[2].ref_pic_used = atoi(value);
8690 }
8692 {
8693 p_gop->pic_param[5].rps[3].ref_pic = atoi(value);
8694 }
8696 {
8697 p_gop->pic_param[5].rps[3].ref_pic_used = atoi(value);
8698 }
8699
8701 {
8702 p_gop->pic_param[6].poc_offset = atoi(value);
8703 }
8705 {
8706 p_gop->pic_param[6].qp_offset = atoi(value);
8707 }
8708 /*
8709 OPT(NI_ENC_GOP_PARAMS_G6_QP_FACTOR)
8710 {
8711 p_gop->pic_param[6].qp_factor = atof(value);
8712 }
8713 */
8715 {
8716 p_gop->pic_param[6].temporal_id = atoi(value);
8717 }
8719 {
8720 p_gop->pic_param[6].pic_type = atoi(value);
8721 }
8723 {
8724 p_gop->pic_param[6].num_ref_pics = atoi(value);
8725 }
8727 {
8728 p_gop->pic_param[6].rps[0].ref_pic = atoi(value);
8729 }
8731 {
8732 p_gop->pic_param[6].rps[0].ref_pic_used = atoi(value);
8733 }
8735 {
8736 p_gop->pic_param[6].rps[1].ref_pic = atoi(value);
8737 }
8739 {
8740 p_gop->pic_param[6].rps[1].ref_pic_used = atoi(value);
8741 }
8743 {
8744 p_gop->pic_param[6].rps[2].ref_pic = atoi(value);
8745 }
8747 {
8748 p_gop->pic_param[6].rps[2].ref_pic_used = atoi(value);
8749 }
8751 {
8752 p_gop->pic_param[6].rps[3].ref_pic = atoi(value);
8753 }
8755 {
8756 p_gop->pic_param[6].rps[3].ref_pic_used = atoi(value);
8757 }
8758
8760 {
8761 p_gop->pic_param[7].poc_offset = atoi(value);
8762 }
8764 {
8765 p_gop->pic_param[7].qp_offset = atoi(value);
8766 }
8767 /*
8768 OPT(NI_ENC_GOP_PARAMS_G7_QP_FACTOR)
8769 {
8770 p_gop->pic_param[7].qp_factor = atof(value);
8771 }
8772 */
8774 {
8775 p_gop->pic_param[7].temporal_id = atoi(value);
8776 }
8778 {
8779 p_gop->pic_param[7].pic_type = atoi(value);
8780 }
8782 {
8783 p_gop->pic_param[7].num_ref_pics = atoi(value);
8784 }
8786 {
8787 p_gop->pic_param[7].rps[0].ref_pic = atoi(value);
8788 }
8790 {
8791 p_gop->pic_param[7].rps[0].ref_pic_used = atoi(value);
8792 }
8794 {
8795 p_gop->pic_param[7].rps[1].ref_pic = atoi(value);
8796 }
8798 {
8799 p_gop->pic_param[7].rps[1].ref_pic_used = atoi(value);
8800 }
8802 {
8803 p_gop->pic_param[7].rps[2].ref_pic = atoi(value);
8804 }
8806 {
8807 p_gop->pic_param[7].rps[2].ref_pic_used = atoi(value);
8808 }
8810 {
8811 p_gop->pic_param[7].rps[3].ref_pic = atoi(value);
8812 }
8814 {
8815 p_gop->pic_param[7].rps[3].ref_pic_used = atoi(value);
8816 }
8817 else
8818 {
8819 ni_log(NI_LOG_ERROR, "%s(): Invalid parameter name passed\n", __func__);
8821 }
8822#endif
8823
8824#undef OPT
8825#undef OPT2
8826#undef atobool
8827#undef atoi
8828#undef atof
8829
8830 b_error |= bValueWasNull && !bNameWasBool;
8831
8832 ni_log(NI_LOG_TRACE, "%s(): exit, b_error=%d\n", __func__, b_error);
8833
8835}
8836
8837/*!*****************************************************************************
8838* \brief Copy existing decoding session params for hw frame usage
8839*
8840* \param[in] src_p_ctx Pointer to a caller allocated source session context
8841* \param[in] dst_p_ctx Pointer to a caller allocated destination session
8842* context
8843* \return On success
8844* NI_RETCODE_SUCCESS
8845* On failure
8846* NI_RETCODE_INVALID_PARAM
8847******************************************************************************/
8849{
8850 return ni_decoder_session_copy_internal(src_p_ctx, dst_p_ctx);
8851}
8852
8853/*!*****************************************************************************
8854* \brief Read data from the device
8855* If device_type is NI_DEVICE_TYPE_DECODER reads data hwdesc from
8856* decoder
8857* If device_type is NI_DEVICE_TYPE_SCALER reads data hwdesc from
8858* scaler
8859*
8860* \param[in] p_ctx Pointer to a caller allocated
8861* ni_session_context_t struct
8862* \param[in] p_data Pointer to a caller allocated
8863* ni_session_data_io_t struct which contains either a
8864* ni_frame_t data frame or ni_packet_t data packet to
8865* send
8866* \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_SCALER
8867* If NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_SCALER is specified,
8868* hw descriptor info will be stored in p_data ni_frame
8869* \return On success
8870* Total number of bytes read
8871* On failure
8872* NI_RETCODE_INVALID_PARAM
8873* NI_RETCODE_ERROR_NVME_CMD_FAILED
8874* NI_RETCODE_ERROR_INVALID_SESSION
8875******************************************************************************/
8877{
8878 ni_log2(p_ctx, NI_LOG_DEBUG, "%s start\n", __func__);
8880 if ((!p_ctx) || (!p_data))
8881 {
8882 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
8883 __func__);
8885 }
8886
8887 // Here check if keep alive thread is closed.
8888#ifdef _WIN32
8889 if (p_ctx->keep_alive_thread.handle && p_ctx->keep_alive_thread_args &&
8891#else
8892 if (p_ctx->keep_alive_thread && p_ctx->keep_alive_thread_args &&
8894#endif
8895 {
8896 ni_log2(p_ctx, NI_LOG_ERROR,
8897 "ERROR: %s() keep alive thread has been closed, "
8898 "hw:%d, session:%d\n",
8899 __func__, p_ctx->hw_id, p_ctx->session_id);
8901 }
8902
8904 // In close state, let the close process execute first.
8906 {
8907 ni_log2(p_ctx, NI_LOG_DEBUG, "%s close state, return\n", __func__);
8909 ni_usleep(100);
8911 }
8914
8915 switch (device_type)
8916 {
8918 {
8919 int seq_change_read_count = 0;
8920 p_data->data.frame.src_codec = p_ctx->codec_format;
8921 for (;;)
8922 {
8923 //retval = ni_decoder_session_read(p_ctx, &(p_data->data.frame));
8924 retval = ni_decoder_session_read_desc(p_ctx, &(p_data->data.frame));
8925 // check resolution change only after initial setting obtained
8926 // p_data->data.frame.video_width is picture width and will be 32-align
8927 // adjusted to frame size; p_data->data.frame.video_height is the same as
8928 // frame size, then compare them to saved one for resolution checking
8929 //
8930 uint32_t aligned_width;
8931 if(QUADRA)
8932 {
8933 aligned_width = ((((p_data->data.frame.video_width * p_ctx->bit_depth_factor) + 127) / 128) * 128);
8934 }
8935 else
8936 {
8937 aligned_width = ((p_data->data.frame.video_width + 31) / 32) * 32;
8938 }
8939
8940 ni_log2(p_ctx, NI_LOG_DEBUG,
8941 "FNum %" PRIu64
8942 ", DFVWxDFVH %u x %u, AlWid %u, AVW x AVH %u x %u\n",
8943 p_ctx->frame_num, p_data->data.frame.video_width,
8944 p_data->data.frame.video_height, aligned_width,
8946
8947 if (0 == retval && seq_change_read_count)
8948 {
8949 ni_log2(p_ctx, NI_LOG_DEBUG, "%s (decoder): seq change NO data, next time.\n",
8950 __func__);
8951 p_ctx->active_video_width = 0;
8952 p_ctx->active_video_height = 0;
8953 p_ctx->actual_video_width = 0;
8954 break;
8955 }
8956 else if (retval < 0)
8957 {
8958 ni_log2(p_ctx, NI_LOG_ERROR, "%s (decoder): failure ret %d, return ..\n",
8959 __func__, retval);
8960 break;
8961 }
8962 // aligned_width may equal to active_video_width if bit depth and width
8963 // are changed at the same time. So, check video_width != actual_video_width.
8964 else if (p_ctx->frame_num && (p_ctx->pixel_format_changed ||
8965 (p_data->data.frame.video_width &&
8966 p_data->data.frame.video_height &&
8967 (aligned_width != p_ctx->active_video_width ||
8968 p_data->data.frame.video_height != p_ctx->active_video_height))))
8969 {
8970 ni_log2(
8971 p_ctx, NI_LOG_DEBUG,
8972 "%s (decoder): resolution change, frame size %ux%u -> %ux%u, "
8973 "width %u bit %d, pix_fromat_changed %d, actual_video_width %d, continue read ...\n",
8974 __func__, p_ctx->active_video_width, p_ctx->active_video_height,
8975 aligned_width, p_data->data.frame.video_height,
8976 p_data->data.frame.video_width, p_ctx->bit_depth_factor,
8978 // reset active video resolution to 0 so it can be queried in the re-read
8979 p_ctx->active_video_width = 0;
8980 p_ctx->active_video_height = 0;
8981 p_ctx->actual_video_width = 0;
8982 seq_change_read_count++;
8983 //break;
8984 }
8985 else
8986 {
8987 break;
8988 }
8989 }
8990 break;
8991 }
8993 {
8994 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Encoder has no hwdesc to read\n");
8996 }
8997
8999 {
9000 retval = ni_scaler_session_read_hwdesc(p_ctx, &(p_data->data.frame));
9001 break;
9002 }
9003
9004 case NI_DEVICE_TYPE_AI:
9005 {
9006 retval = ni_ai_session_read_hwdesc(p_ctx, &(p_data->data.frame));
9007 break;
9008 }
9009
9010 default:
9011 {
9012 retval = NI_RETCODE_INVALID_PARAM;
9013 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unrecognized device type: %d",
9014 __func__, device_type);
9015 break;
9016 }
9017 }
9018
9020 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
9022
9023 return retval;
9024}
9025
9026/*!*****************************************************************************
9027* \brief Reads YUV data from hw descriptor stored location on device
9028*
9029* \param[in] p_ctx Pointer to a caller allocated
9030* ni_session_context_t struct
9031* \param[in] p_data Pointer to a caller allocated
9032* ni_session_data_io_t struct which contains either a
9033* ni_frame_t data frame or ni_packet_t data packet to
9034* send
9035* \param[in] hwdesc HW descriptor to find frame in XCODER
9036* \return On success
9037* Total number of bytes read
9038* On failure
9039* NI_RETCODE_INVALID_PARAM
9040* NI_RETCODE_ERROR_NVME_CMD_FAILED
9041* NI_RETCODE_ERROR_INVALID_SESSION
9042*******************************************************************************/
9044{
9046 if ((!hwdesc) || (!p_data))
9047 {
9048 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9049 __func__);
9051 }
9052
9053 /* download by frameidx */
9054 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rd") >= 0))
9055 {
9056 if(hwdesc->ui16FrameIdx == 0)
9057 {
9058 ni_log(NI_LOG_ERROR, "%s(): Invaild frame index\n", __func__);
9060 }
9061 retval = ni_hwdownload_by_frame_idx(hwdesc, &(p_data->data.frame), p_ctx->is_auto_dl);
9062 } else {
9063 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
9064 {
9065 if (p_ctx->pext_mutex == &(p_ctx->mutex))
9066 {
9067 ni_log(NI_LOG_ERROR, "ERROR %s(): Invalid session\n",
9068 __func__);
9070 }
9071 }
9072
9074 bool use_external_mutex = false;
9075 uint32_t orig_session_id = p_ctx->session_id;
9076 ni_device_handle_t orig_blk_io_handle = p_ctx->blk_io_handle;
9077 uint32_t orig_codec_format = p_ctx->codec_format;
9078 int orig_bit_depth_factor = p_ctx->bit_depth_factor;
9079 int orig_hw_action = p_ctx->hw_action;
9080
9081 ni_pthread_mutex_t *p_ctx_mutex = &(p_ctx->mutex);
9082 if ((p_ctx_mutex != p_ctx->pext_mutex) ||
9085 "6r8") < 0)
9086 {
9087 use_external_mutex = true;
9088 p_ctx->session_id = hwdesc->ui16session_ID;
9089 p_ctx->blk_io_handle = (ni_device_handle_t)(int64_t)hwdesc->device_handle;
9090 p_ctx->codec_format = NI_CODEC_FORMAT_H264; //unused
9091 p_ctx->bit_depth_factor = (int)hwdesc->bit_depth;
9093 }
9094
9096
9097 retval = ni_hwdownload_session_read(p_ctx, &(p_data->data.frame), hwdesc); //cut me down as needed
9098
9099 p_ctx->xcoder_state &= ~NI_XCODER_HWDL_STATE;
9100 if (use_external_mutex)
9101 {
9102 p_ctx->session_id = orig_session_id;
9103 p_ctx->blk_io_handle = orig_blk_io_handle;
9104 p_ctx->codec_format = orig_codec_format;
9105 p_ctx->bit_depth_factor = orig_bit_depth_factor;
9106 p_ctx->hw_action = orig_hw_action;
9107 }
9109 }
9110
9111 return retval;
9112}
9113
9114/*!*****************************************************************************
9115* \brief Query the session if a buffer is available
9116*
9117* \param[in] p_ctx Pointer to a caller allocated
9118* ni_session_context_t struct
9119* [in] device_type Quadra device type
9120*
9121* \return On success
9122* NI_RETCODE_SUCCESS
9123* On failure
9124* NI_RETCODE_INVALID_PARAM
9125* NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9126* NI_RETCODE_ERROR_NVME_CMD_FAILED
9127* NI_RETCODE_ERROR_INVALID_SESSION
9128*******************************************************************************/
9130 ni_device_type_t device_type)
9131{
9133
9134 if (!p_ctx)
9135 {
9136 ni_log(NI_LOG_ERROR, "ERROR: No session\n");
9138 }
9139
9142 "6rt") < 0)
9143 {
9144 ni_log2(p_ctx, NI_LOG_DEBUG,
9145 "%s function not supported in FW API version < 6rt\n",
9146 __func__);
9148 }
9149
9150 switch (device_type)
9151 {
9155
9157
9158 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
9160 break;
9161
9165
9167
9168 p_ctx->xcoder_state &= ~NI_XCODER_READ_DESC_STATE;
9170 break;
9171
9172 default:
9173 break;
9174 }
9175
9176 return retval;
9177}
9178
9179/*!*****************************************************************************
9180* \brief Sends raw YUV input to uploader instance and retrieves a HW descriptor
9181* to represent it
9182*
9183* \param[in] p_ctx Pointer to a caller allocated
9184* ni_session_context_t struct
9185* \param[in] p_src_data Pointer to a caller allocated
9186* ni_session_data_io_t struct which contains a
9187* ni_frame_t data frame to send to uploader
9188* \param[out] hwdesc HW descriptor to find frame in XCODER
9189* \return On success
9190* Total number of bytes read
9191* On failure
9192* NI_RETCODE_INVALID_PARAM
9193* NI_RETCODE_ERROR_NVME_CMD_FAILED
9194* NI_RETCODE_ERROR_INVALID_SESSION
9195*******************************************************************************/
9197{
9199 if ((!hwdesc) || (!p_src_data))
9200 {
9201 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9202 __func__);
9204 }
9207
9208 retval = ni_hwupload_session_write(p_ctx, &p_src_data->data.frame, hwdesc);
9209
9210 p_ctx->xcoder_state &= ~NI_XCODER_HWUP_STATE;
9212
9213 return retval;
9214}
9215
9216/*!*****************************************************************************
9217* \brief Allocate memory for the hwDescriptor buffer based on provided
9218* parameters taking into account pic size and extra data.
9219*
9220* \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
9221*
9222* \param[in] video_width Width of the video frame
9223* \param[in] video_height Height of the video frame
9224* \param[in] extra_len Extra data size (incl. meta data)
9225*
9226* \return On success
9227* NI_RETCODE_SUCCESS
9228* On failure
9229* NI_RETCODE_INVALID_PARAM
9230* NI_RETCODE_ERROR_MEM_ALOC
9231*****************************************************************************/
9233 int video_height, int extra_len)
9234{
9235 void* p_buffer = NULL;
9236 int height_aligned = video_height;
9237 int retval = NI_RETCODE_SUCCESS;
9238
9239 if (!p_frame)
9240 {
9241 ni_log(NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9242 __func__);
9244 }
9245
9246 ni_log(NI_LOG_DEBUG, "%s: extra_len=%d\n", __func__, extra_len);
9247
9248 int buffer_size = (int)sizeof(niFrameSurface1_t) + extra_len;
9249
9251
9252 //Check if Need to free
9253 if ((p_frame->buffer_size != buffer_size) && (p_frame->buffer_size > 0))
9254 {
9255 ni_log(NI_LOG_DEBUG, "%s: free current p_frame->buffer_size=%u\n",
9256 __func__, p_frame->buffer_size);
9257 ni_frame_buffer_free(p_frame);
9258 }
9259
9260 //Check if need to realocate
9261 if (p_frame->buffer_size != buffer_size)
9262 {
9263 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
9264 {
9265 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_frame buffer.\n",
9266 NI_ERRNO, __func__);
9268 LRETURN;
9269 }
9270
9271 // init once after allocation
9272 memset(p_buffer, 0, buffer_size);
9273 p_frame->buffer_size = buffer_size;
9274 p_frame->p_buffer = p_buffer;
9275
9276 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
9277 }
9278 else
9279 {
9280 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
9281 }
9282
9283 p_frame->p_data[3] = p_frame->p_buffer;
9284 p_frame->p_data[0] = NULL;
9285 p_frame->p_data[1] = NULL;
9286 p_frame->p_data[2] = NULL;
9287
9288 p_frame->data_len[0] = 0;//luma_size;
9289 p_frame->data_len[1] = 0;//chroma_b_size;
9290 p_frame->data_len[2] = 0;//chroma_r_size;
9291 p_frame->data_len[3] = sizeof(niFrameSurface1_t);
9292
9293 p_frame->video_width = video_width;
9294 p_frame->video_height = height_aligned;
9295
9296 ((niFrameSurface1_t*)p_frame->p_data[3])->device_handle = (int32_t)NI_INVALID_DEVICE_HANDLE;
9297
9298 ni_log(NI_LOG_DEBUG, "%s: success: p_frame->buffer_size=%u\n", __func__,
9299 p_frame->buffer_size);
9300
9301END:
9302
9303 if (NI_RETCODE_SUCCESS != retval)
9304 {
9305 ni_aligned_free(p_buffer);
9306 }
9307
9308 return retval;
9309}
9310
9311/*!*****************************************************************************
9312* \brief Recycle a frame buffer on card
9313*
9314* \param[in] surface Struct containing device and frame location to clear out
9315* \param[in] device_handle handle to access device memory buffer is stored in
9316*
9317* \return On success NI_RETCODE_SUCCESS
9318* On failure NI_RETCODE_INVALID_PARAM
9319*******************************************************************************/
9321 int32_t device_handle)
9322{
9324
9325 if (surface)
9326 {
9327 ni_log(NI_LOG_DEBUG, "%s(): Start cleaning out buffer\n", __func__);
9329 "%s(): ui16FrameIdx=%d sessionId=%d device_handle=0x%x\n",
9330 __func__, surface->ui16FrameIdx, surface->ui16session_ID,
9331 device_handle);
9332 retval = ni_clear_instance_buf(surface);
9333 }
9334 else
9335 {
9336 ni_log(NI_LOG_DEBUG, "%s(): Surface is empty\n", __func__);
9337 }
9338
9339 return retval;
9340}
9341
9342/*!*****************************************************************************
9343* \brief Recycle a frame buffer on card, only hwframe descriptor is needed
9344*
9345* \param[in] surface Struct containing device and frame location to clear out
9346*
9347* \return On success NI_RETCODE_SUCCESS
9348* On failure NI_RETCODE_INVALID_PARAM
9349*******************************************************************************/
9351{
9353 int32_t saved_dma_buf_fd;
9354 if (surface)
9355 {
9356 if(surface->ui16FrameIdx == 0)
9357 {
9358 ni_log(NI_LOG_DEBUG, "%s(): Invaild frame index\n", __func__);
9359 return retval;
9360 }
9361 ni_log(NI_LOG_DEBUG, "%s(): Start cleaning out buffer\n", __func__);
9363 "%s(): ui16FrameIdx=%d sessionId=%d device_handle=0x%x\n",
9364 __func__, surface->ui16FrameIdx, surface->ui16session_ID,
9365 surface->device_handle);
9366 retval = ni_clear_instance_buf(surface);
9367 saved_dma_buf_fd = surface->dma_buf_fd;
9368 memset(surface, 0, sizeof(niFrameSurface1_t));
9369 surface->dma_buf_fd = saved_dma_buf_fd;
9370 }
9371 else
9372 {
9373 ni_log(NI_LOG_DEBUG, "%s(): Surface is empty\n", __func__);
9374 retval = NI_RETCODE_INVALID_PARAM;
9375 }
9376
9377 return retval;
9378}
9379
9380/*!*****************************************************************************
9381* \brief Sends frame pool setup info to device
9382*
9383* \param[in] p_ctx Pointer to a caller allocated
9384* ni_session_context_t struct
9385* \param[in] pool_size Upload session initial allocated frames count
9386* must be > 0,
9387* \param[in] pool 0 use the normal pool
9388* 1 use a dedicated P2P pool
9389*
9390* \return On success Return code
9391* On failure
9392* NI_RETCODE_INVALID_PARAM
9393* NI_RETCODE_ERROR_NVME_CMD_FAILED
9394* NI_RETCODE_ERROR_INVALID_SESSION
9395* NI_RETCODE_ERROR_MEM_ALOC
9396*******************************************************************************/
9398 uint32_t pool_size, uint32_t pool)
9399{
9401 if (!p_ctx)
9402 {
9403 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9404 __func__);
9406 }
9407 if (pool_size == 0 || pool_size > NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL)
9408 {
9409 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Invalid poolsize == 0 or > 100\n");
9411 }
9412 if (pool & NI_UPLOADER_FLAG_LM)
9413 {
9414 ni_log2(p_ctx, NI_LOG_DEBUG, "uploader buffer acquisition is limited!\n");
9415 }
9418
9419 retval = ni_config_instance_set_uploader_params(p_ctx, pool_size, pool);
9420
9421 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9423
9424 return retval;
9425}
9426
9427/*!*****************************************************************************
9428* \brief Sends frame pool change info to device
9429*
9430* \param[in] p_ctx Pointer to a caller allocated
9431* ni_session_context_t struct
9432* \param[in] pool_size if pool_size = 0, free allocated device memory buffers
9433* if pool_size > 0, expand device frame buffer pool of
9434* current instance with pool_size more frame buffers
9435*
9436* \return On success Return code
9437* On failure
9438* NI_RETCODE_FAILURE
9439* NI_RETCODE_INVALID_PARAM
9440* NI_RETCODE_ERROR_NVME_CMD_FAILED
9441* NI_RETCODE_ERROR_INVALID_SESSION
9442* NI_RETCODE_ERROR_MEM_ALOC
9443* NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9444*******************************************************************************/
9446 uint32_t pool_size)
9447{
9449 if (!p_ctx)
9450 {
9451 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
9452 __func__);
9454 }
9457 "6r3") < 0)
9458 {
9459 ni_log2(p_ctx, NI_LOG_ERROR,
9460 "ERROR: %s function not supported in FW API version < 6r3\n",
9461 __func__);
9463 }
9464 if (p_ctx->pool_type == NI_POOL_TYPE_NONE)
9465 {
9466 ni_log2(p_ctx, NI_LOG_ERROR,
9467 "ERROR: can't free or expand framepool of session 0x%x "
9468 "before init framepool\n", p_ctx->session_id);
9469 return NI_RETCODE_FAILURE;
9470 }
9471 if (pool_size > NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL)
9472 {
9473 ni_log2(p_ctx, NI_LOG_ERROR,
9474 "ERROR: Invalid poolsize > %u\n", NI_MAX_UPLOAD_INSTANCE_FRAMEPOOL);
9476 }
9477 if (pool_size == 0)
9478 {
9479 ni_log2(p_ctx, NI_LOG_INFO, "Free frame pool of session 0x%x\n", p_ctx->session_id);
9480 }
9481
9484
9485 retval = ni_config_instance_set_uploader_params(p_ctx, pool_size, p_ctx->pool_type);
9486
9487 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9489
9490 return retval;
9491}
9492
9493/*!*****************************************************************************
9494 * \brief Set parameters on the device for the 2D engine
9495 *
9496 * \param[in] p_ctx pointer to session context
9497 * \param[in] p_params pointer to scaler parameters
9498 *
9499 * \return NI_RETCODE_INVALID_PARAM
9500 * NI_RETCODE_ERROR_INVALID_SESSION
9501 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9502 * NI_RETCODE_ERROR_MEM_ALOC
9503 ******************************************************************************/
9505 ni_scaler_params_t *p_params)
9506{
9508
9509 if (!p_ctx || !p_params)
9510 {
9511 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9512 __func__);
9514 }
9517
9518 retval = ni_config_instance_set_scaler_params(p_ctx, p_params);
9519
9520 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9522
9523 return retval;
9524}
9525
9526/*!******************************************************************************
9527 * \brief Send a p_config command to configure scaling drawbox parameters.
9528 *
9529 * \param ni_session_context_t p_ctx - xcoder Context
9530 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_drawbox params_t struct
9531 *
9532 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
9533*******************************************************************************/
9536{
9537 void *p_scaler_config = NULL;
9538 uint32_t buffer_size = sizeof(ni_scaler_multi_drawbox_params_t);
9540 uint32_t ui32LBA = 0;
9541
9542 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
9543
9544 if (!p_ctx || !p_params)
9545 {
9546 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n", __func__);
9547 retval = NI_RETCODE_INVALID_PARAM;
9548 LRETURN;
9549 }
9550
9551 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
9552 {
9553 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n", __func__);
9555 LRETURN;
9556 }
9557
9558 buffer_size =
9559 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
9561 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
9562 {
9563 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
9564 NI_ERRNO, __func__);
9566 LRETURN;
9567 }
9568 memset(p_scaler_config, 0, buffer_size);
9569
9570 //configure the session here
9573
9574 memcpy(p_scaler_config, p_params, buffer_size);
9575
9577 p_scaler_config, buffer_size, ui32LBA) < 0)
9578 {
9579 ni_log2(p_ctx, NI_LOG_ERROR,
9580 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
9581 ", hw_id, %d, xcoder_inst_id: %d\n",
9582 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
9583 // Close the session since we can't configure it as per fw
9584 retval = ni_scaler_session_close(p_ctx, 0);
9585 if (NI_RETCODE_SUCCESS != retval)
9586 {
9587 ni_log2(p_ctx, NI_LOG_ERROR,
9588 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
9589 "hw_id, %d, xcoder_inst_id: %d\n",
9590 __func__,
9591 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
9592 p_ctx->session_id);
9593 }
9594
9596 }
9597
9598END:
9599
9600 ni_aligned_free(p_scaler_config);
9601 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
9602
9603 return retval;
9604}
9605
9606/*!******************************************************************************
9607 * \brief Send a p_config command to configure scaling watermark parameters.
9608 *
9609 * \param ni_session_context_t p_ctx - xcoder Context
9610 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_watermark_params_t struct
9611 *
9612 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
9613*******************************************************************************/
9616{
9617 void *p_scaler_config = NULL;
9618 uint32_t buffer_size = sizeof(ni_scaler_multi_watermark_params_t);
9620 uint32_t ui32LBA = 0;
9621
9622 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
9623
9624 if (!p_ctx || !p_params)
9625 {
9626 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n", __func__);
9627 retval = NI_RETCODE_INVALID_PARAM;
9628 LRETURN;
9629 }
9630
9631 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
9632 {
9633 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n", __func__);
9635 LRETURN;
9636 }
9637
9638 buffer_size =
9639 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
9641 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
9642 {
9643 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
9644 NI_ERRNO, __func__);
9646 LRETURN;
9647 }
9648 memset(p_scaler_config, 0, buffer_size);
9649
9650 //configure the session here
9653
9654 memcpy(p_scaler_config, p_params, buffer_size);
9655
9657 p_scaler_config, buffer_size, ui32LBA) < 0)
9658 {
9659 ni_log2(p_ctx, NI_LOG_ERROR,
9660 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
9661 ", hw_id, %d, xcoder_inst_id: %d\n",
9662 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
9663 // Close the session since we can't configure it as per fw
9664 retval = ni_scaler_session_close(p_ctx, 0);
9665 if (NI_RETCODE_SUCCESS != retval)
9666 {
9667 ni_log2(p_ctx, NI_LOG_ERROR,
9668 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
9669 "hw_id, %d, xcoder_inst_id: %d\n",
9670 __func__,
9671 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
9672 p_ctx->session_id);
9673 }
9674
9676 }
9677
9678END:
9679
9680 ni_aligned_free(p_scaler_config);
9681 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
9682
9683 return retval;
9684}
9685
9686
9687/*!*****************************************************************************
9688 * \brief Allocate a frame on the device for 2D engine or AI engine
9689 * to work on based on provided parameters
9690 *
9691 * \param[in] p_ctx pointer to session context
9692 * \param[in] width width, in pixels
9693 * \param[in] height height, in pixels
9694 * \param[in] format pixel format
9695 * \param[in] options options bitmap flags, bit 0 (NI_SCALER_FLAG_IO) is
9696 * 0=input frame or 1=output frame. Bit 1 (NI_SCALER_FLAG_PC) is
9697 * 0=single allocation, 1=create pool. Bit 2 (NI_SCALER_FLAG_PA) is
9698 * 0=straight alpha, 1=premultiplied alpha
9699 * \param[in] rectangle_width clipping rectangle width
9700 * \param[in] rectangle_height clipping rectangle height
9701 * \param[in] rectangle_x horizontal position of clipping rectangle
9702 * \param[in] rectangle_y vertical position of clipping rectangle
9703 * \param[in] rgba_color RGBA fill colour (for padding only)
9704 * \param[in] frame_index input hwdesc index
9705 * \param[in] device_type only NI_DEVICE_TYPE_SCALER
9706 * and NI_DEVICE_TYPE_AI (only needs p_ctx and frame_index)
9707 *
9708 * \return NI_RETCODE_INVALID_PARAM
9709 * NI_RETCODE_ERROR_INVALID_SESSION
9710 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9711 * NI_RETCODE_ERROR_MEM_ALOC
9712 ******************************************************************************/
9714 int width,
9715 int height,
9716 int format,
9717 int options,
9718 int rectangle_width,
9719 int rectangle_height,
9720 int rectangle_x,
9721 int rectangle_y,
9722 int rgba_color,
9723 int frame_index,
9724 ni_device_type_t device_type)
9725{
9727
9728 if (!p_ctx)
9729 {
9730 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9731 __func__);
9733 }
9736
9737 switch (device_type)
9738 {
9740 retval = ni_scaler_alloc_frame(p_ctx,width, height, format, options,
9741 rectangle_width, rectangle_height,
9742 rectangle_x, rectangle_y,
9743 rgba_color, frame_index);
9744 break;
9745
9746 case NI_DEVICE_TYPE_AI:
9747 retval = ni_ai_alloc_hwframe(p_ctx, width, height, options, rgba_color,
9748 frame_index);
9749 break;
9750
9753 /* fall through */
9754
9755 default:
9756 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", device_type);
9757 retval = NI_RETCODE_INVALID_PARAM;
9758 break;
9759 }
9760
9761 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9763
9764 return retval;
9765}
9766
9767/*!*****************************************************************************
9768 * \brief Allocate a frame on the device and return the frame index
9769 *
9770 * \param[in] p_ctx pointer to session context
9771 * \param[in] p_out_surface pointer to output frame surface
9772 * \param[in] device_type currently only NI_DEVICE_TYPE_AI
9773 *
9774 * \return NI_RETCODE_INVALID_PARAM
9775 * NI_RETCODE_ERROR_INVALID_SESSION
9776 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9777 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9778 * NI_RETCODE_ERROR_MEM_ALOC
9779 ******************************************************************************/
9781 niFrameSurface1_t *p_out_surface,
9782 ni_device_type_t device_type)
9783{
9785
9786 if (!p_ctx)
9787 {
9788 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, %p, return\n",
9789 __func__, p_ctx);
9791 }
9794
9795 switch (device_type)
9796 {
9797 case NI_DEVICE_TYPE_AI:
9798 retval = ni_ai_alloc_dst_frame(p_ctx, p_out_surface);
9799 break;
9800
9804 /* fall through */
9805
9806 default:
9807 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", device_type);
9808 retval = NI_RETCODE_INVALID_PARAM;
9809 break;
9810 }
9811
9812 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9814
9815 return retval;
9816}
9817
9818/*!*****************************************************************************
9819 * \brief Copy the data of src hwframe to dst hwframe
9820 *
9821 * \param[in] p_ctx pointer to session context
9822 * \param[in] p_frameclone_desc pointer to the frameclone descriptor
9823 *
9824 * \return NI_RETCODE_INVALID_PARAM
9825 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
9826 * NI_RETCODE_ERROR_INVALID_SESSION
9827 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9828 * NI_RETCODE_ERROR_MEM_ALOC
9829 ******************************************************************************/
9831 ni_frameclone_desc_t *p_frameclone_desc)
9832{
9834
9835 if (!p_ctx)
9836 {
9837 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9838 __func__);
9840 }
9841
9844 "6rL") < 0)
9845 {
9846 ni_log2(p_ctx, NI_LOG_ERROR,
9847 "Error: %s function not supported on device with FW API version < 6rL\n",
9848 __func__);
9850 }
9851
9854 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
9855 {
9856 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
9857 __func__);
9859 LRETURN;
9860 }
9861
9862 retval = ni_hwframe_clone(p_ctx, p_frameclone_desc);
9863
9864END:
9865 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9867
9868 return retval;
9869}
9870
9871/*!*****************************************************************************
9872 * \brief Configure the 2D engine to work based on provided parameters
9873 *
9874 * \param[in] p_ctx pointer to session context
9875 * \param[in] p_cfg pointer to frame configuration
9876 *
9877 * \return NI_RETCODE_INVALID_PARAM
9878 * NI_RETCODE_ERROR_INVALID_SESSION
9879 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9880 * NI_RETCODE_ERROR_MEM_ALOC
9881 ******************************************************************************/
9883 ni_frame_config_t *p_cfg)
9884{
9886
9887 if (!p_ctx || !p_cfg)
9888 {
9889 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9890 __func__);
9892 }
9893
9896
9897 switch (p_ctx->device_type)
9898 {
9900 retval = ni_scaler_config_frame(p_ctx, p_cfg);
9901 break;
9902
9903 default:
9904 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", p_ctx->device_type);
9905 retval = NI_RETCODE_INVALID_PARAM;
9906 break;
9907 }
9908
9909 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9911
9912 return retval;
9913}
9914
9915/*!*****************************************************************************
9916 * \brief Configure the 2D engine to work based on provided parameters
9917 *
9918 * \param[in] p_ctx pointer to session context
9919 * \param[in] p_cfg_in pointer to input frame configuration
9920 * \param[in] numInCfgs number of input frame configurations
9921 * \param[in] p_cfg_out pointer to output frame configuration
9922 *
9923 * \return NI_RETCODE_INVALID_PARAM
9924 * NI_RETCODE_ERROR_INVALID_SESSION
9925 * NI_RETCODE_ERROR_NVME_CMD_FAILED
9926 * NI_RETCODE_ERROR_MEM_ALOC
9927 ******************************************************************************/
9929 ni_frame_config_t p_cfg_in[],
9930 int numInCfgs,
9931 ni_frame_config_t *p_cfg_out)
9932{
9934
9935 if (!p_ctx || !p_cfg_in)
9936 {
9937 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
9938 __func__);
9940 }
9941
9944
9945 switch (p_ctx->device_type)
9946 {
9948 retval = ni_scaler_multi_config_frame(p_ctx, p_cfg_in, numInCfgs, p_cfg_out);
9949 break;
9950
9951 case NI_DEVICE_TYPE_AI:
9952 retval = ni_ai_multi_config_frame(p_ctx, p_cfg_in, numInCfgs, p_cfg_out);
9953 break;
9954
9955 default:
9956 ni_log2(p_ctx, NI_LOG_ERROR, "Bad device type %d\n", p_ctx->device_type);
9957 retval = NI_RETCODE_INVALID_PARAM;
9958 break;
9959 }
9960
9961 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
9963
9964 return retval;
9965}
9966
9967/*!*****************************************************************************
9968 * \brief Calculate the total size of a frame based on the upload
9969 * context attributes and includes rounding up to the page size
9970 *
9971 * \param[in] p_upl_ctx pointer to an uploader session context
9972 * \param[in] linesize array of line stride
9973 *
9974 * \return size
9975 * NI_RETCODE_INVALID_PARAM
9976 *
9977 ******************************************************************************/
9979 const int linesize[])
9980{
9981 int pixel_format;
9982 int width, height;
9983 int alignedh;
9984 int luma, chroma_b, chroma_r;
9985 int total;
9986
9987 pixel_format = p_upl_ctx->pixel_format;
9988 width = (int)p_upl_ctx->active_video_width;
9989 height = (int)p_upl_ctx->active_video_height;
9990
9991 switch (pixel_format)
9992 {
9993 case NI_PIX_FMT_YUV420P:
9995 case NI_PIX_FMT_NV12:
9996 case NI_PIX_FMT_P010LE:
9997 if (width < 0 || width > NI_MAX_RESOLUTION_WIDTH)
9998 {
10000 }
10001
10002 if ((height < 0) || (height > NI_MAX_RESOLUTION_HEIGHT))
10003 {
10005 }
10006 break;
10007
10008 case NI_PIX_FMT_RGBA:
10009 case NI_PIX_FMT_ABGR:
10010 case NI_PIX_FMT_ARGB:
10011 case NI_PIX_FMT_BGRA:
10012 case NI_PIX_FMT_BGR0:
10013 if ((width < 0) || (width > NI_MAX_RESOLUTION_WIDTH))
10014 {
10016 }
10017
10018 if ((height < 0) || (height > NI_MAX_RESOLUTION_HEIGHT))
10019 {
10021 }
10022 break;
10023
10024 default:
10026 }
10027
10028 alignedh = NI_VPU_CEIL(height, 2);
10029
10030 switch (pixel_format)
10031 {
10032 case NI_PIX_FMT_YUV420P:
10034 luma = linesize[0] * alignedh;
10035 chroma_b = linesize[1] * alignedh / 2;
10036 chroma_r = linesize[2] * alignedh / 2;
10037 total =
10038 luma + chroma_b + chroma_r + NI_APP_ENC_FRAME_META_DATA_SIZE;
10039 break;
10040
10041 case NI_PIX_FMT_NV12:
10042 case NI_PIX_FMT_P010LE:
10043 luma = linesize[0] * alignedh;
10044 chroma_b = linesize[1] * alignedh / 2;
10045 chroma_r = 0;
10046 total =
10047 luma + chroma_b + chroma_r + NI_APP_ENC_FRAME_META_DATA_SIZE;
10048 break;
10049
10050 case NI_PIX_FMT_RGBA:
10051 case NI_PIX_FMT_ABGR:
10052 case NI_PIX_FMT_ARGB:
10053 case NI_PIX_FMT_BGRA:
10054 case NI_PIX_FMT_BGR0:
10055 total = width * height * 4 + NI_APP_ENC_FRAME_META_DATA_SIZE;
10056 break;
10057
10058 default:
10060 break;
10061 }
10062
10064
10065 return total;
10066}
10067
10068/*!*****************************************************************************
10069 * \brief Allocate memory for the frame buffer based on provided parameters
10070 * taking into account the pixel format, width, height, stride,
10071 * alignment, and extra data
10072 * \param[in] p_frame Pointer to caller allocated ni_frame_t
10073 * \param[in] pixel_format a pixel format in ni_pix_fmt_t enum
10074 * \param[in] video_width width, in pixels
10075 * \param[in] video_height height, in pixels
10076 * \param[in] linesize horizontal stride
10077 * \param[in] alignment apply a 16 pixel height alignment (T408 only)
10078 * \param[in] extra_len meta data size
10079 *
10080 * \return NI_RETCODE_SUCCESS
10081 * NI_RETCODE_INVALID_PARAM
10082 * NI_RETCODE_ERROR_MEM_ALOC
10083 *
10084 ******************************************************************************/
10086 int video_width, int video_height,
10087 int linesize[], int alignment,
10088 int extra_len)
10089{
10090 int buffer_size;
10091 void *p_buffer = NULL;
10092 int retval = NI_RETCODE_SUCCESS;
10093 int height_aligned;
10094 int luma_size = 0;
10095 int chroma_b_size = 0;
10096 int chroma_r_size = 0;
10097
10098 if (!p_frame)
10099 {
10100 ni_log(NI_LOG_ERROR, "Invalid frame pointer\n");
10102 }
10103
10104 switch (pixel_format)
10105 {
10106 case NI_PIX_FMT_YUV420P:
10108 case NI_PIX_FMT_NV12:
10109 case NI_PIX_FMT_P010LE:
10110 case NI_PIX_FMT_NV16:
10111 case NI_PIX_FMT_YUYV422:
10112 case NI_PIX_FMT_UYVY422:
10113 if ((video_width < 0) || (video_width > NI_MAX_RESOLUTION_WIDTH))
10114 {
10115 ni_log(NI_LOG_ERROR, "Video resolution width %d out of range\n",
10116 video_width);
10118 }
10119
10120 if ((video_height < 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT))
10121 {
10122 ni_log(NI_LOG_ERROR, "Video resolution height %d out of range\n",
10123 video_width);
10125 }
10126 break;
10127
10128 case NI_PIX_FMT_RGBA:
10129 case NI_PIX_FMT_BGRA:
10130 case NI_PIX_FMT_ARGB:
10131 case NI_PIX_FMT_ABGR:
10132 case NI_PIX_FMT_BGR0:
10133 case NI_PIX_FMT_BGRP:
10134 /*
10135 * For 2D engine using RGBA, the minimum width is 32. There is no
10136 * height restriction. The 2D engine supports a height/width of up to
10137 * 32K but but we will limit the max height and width to 8K.
10138 */
10139 if ((video_width < 0) || (video_width > NI_MAX_RESOLUTION_WIDTH))
10140 {
10141 ni_log(NI_LOG_ERROR, "Video resolution width %d out of range\n",
10142 video_width);
10144 }
10145
10146 if ((video_height <= 0) || (video_height > NI_MAX_RESOLUTION_HEIGHT))
10147 {
10148 ni_log(NI_LOG_ERROR, "Video resolution height %d out of range\n",
10149 video_height);
10151 }
10152 break;
10153
10154 default:
10155 ni_log(NI_LOG_ERROR, "Unknown pixel format %d\n",pixel_format);
10157 }
10158
10159 if (QUADRA)
10160 {
10161 /* Quadra requires an even-numbered height/width */
10162 height_aligned = NI_VPU_CEIL(video_height, 2);
10163 }
10164 else
10165 {
10166 height_aligned = NI_VPU_ALIGN8(video_height);
10167
10168 if (alignment)
10169 {
10170 /* 16-pixel aligned pixel height for Quadra */
10171 height_aligned = NI_VPU_ALIGN16(video_height);
10172 }
10173 }
10174
10175 switch (pixel_format)
10176 {
10177 case NI_PIX_FMT_YUV420P:
10179 luma_size = linesize[0] * height_aligned;
10180
10181 if (QUADRA)
10182 {
10183 chroma_b_size = linesize[1] * height_aligned / 2;
10184 chroma_r_size = linesize[2] * height_aligned / 2;
10185 }
10186 else
10187 {
10188 chroma_b_size = luma_size / 4;
10189 chroma_r_size = luma_size / 4;
10190 }
10191 break;
10192
10193 case NI_PIX_FMT_RGBA:
10194 case NI_PIX_FMT_BGRA:
10195 case NI_PIX_FMT_ARGB:
10196 case NI_PIX_FMT_ABGR:
10197 case NI_PIX_FMT_BGR0:
10198 luma_size = linesize[0] * video_height;
10199 chroma_b_size = 0;
10200 chroma_r_size = 0;
10201 break;
10202
10203 case NI_PIX_FMT_NV12:
10204 case NI_PIX_FMT_P010LE:
10205 if (QUADRA)
10206 {
10207 luma_size = linesize[0] * height_aligned;
10208 chroma_b_size = linesize[1] * height_aligned / 2;
10209 chroma_r_size = 0;
10210 break;
10211 }
10212 case NI_PIX_FMT_NV16:
10213 if (QUADRA)
10214 {
10215 luma_size = linesize[0] * video_height;
10216 chroma_b_size = linesize[1] * video_height;
10217 chroma_r_size = 0;
10218 break;
10219 }
10220 case NI_PIX_FMT_YUYV422:
10221 case NI_PIX_FMT_UYVY422:
10222 if (QUADRA)
10223 {
10224 luma_size = linesize[0] * video_height;
10225 chroma_b_size = 0;
10226 chroma_r_size = 0;
10227 break;
10228 }
10229 case NI_PIX_FMT_BGRP:
10230 if (QUADRA)
10231 {
10232 luma_size = NI_VPU_ALIGN32(linesize[0] * video_height);
10233 chroma_b_size = NI_VPU_ALIGN32(linesize[1] * video_height);
10234 chroma_r_size = NI_VPU_ALIGN32(linesize[2] * video_height);
10235 break;
10236 }
10237 /*fall through*/
10238 default:
10239 ni_log(NI_LOG_ERROR, "Error: unsupported pixel format %d\n",pixel_format);
10241 }
10242
10243 buffer_size = luma_size + chroma_b_size + chroma_r_size + extra_len;
10244
10245 /* Allocate a buffer size that is page aligned for the host */
10246 buffer_size = NI_VPU_CEIL(buffer_size,NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
10247
10248 /* If this buffer has a different size, realloc a new buffer */
10249 if ((p_frame->buffer_size > 0) && (p_frame->buffer_size != buffer_size))
10250 {
10251 ni_log(NI_LOG_DEBUG, "Free current p_frame, p_frame->buffer_size %u\n",
10252 p_frame->buffer_size);
10253 ni_frame_buffer_free(p_frame);
10254 }
10255
10256 if (p_frame->buffer_size != buffer_size)
10257 {
10258 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10259 {
10260 ni_log(NI_LOG_ERROR, "Error: Cannot allocate p_frame\n");
10262 LRETURN;
10263 }
10264
10265 memset(p_buffer, 0, buffer_size);
10266 p_frame->buffer_size = buffer_size;
10267 p_frame->p_buffer = p_buffer;
10268 ni_log(NI_LOG_DEBUG, "%s: allocated new p_frame buffer\n", __func__);
10269 }
10270 else
10271 {
10272 ni_log(NI_LOG_DEBUG, "%s: reuse p_frame buffer\n", __func__);
10273 }
10274
10275 switch (pixel_format)
10276 {
10277 case NI_PIX_FMT_YUV420P:
10279 p_frame->p_data[0] = p_frame->p_buffer;
10280 p_frame->p_data[1] = p_frame->p_data[0] + luma_size;
10281 p_frame->p_data[2] = p_frame->p_data[1] + chroma_b_size;
10282 p_frame->p_data[3] = NULL;
10283
10284 p_frame->data_len[0] = luma_size;
10285 p_frame->data_len[1] = chroma_b_size;
10286 p_frame->data_len[2] = chroma_r_size;
10287 p_frame->data_len[3] = 0;
10288 video_width = NI_VPU_ALIGN128(video_width);
10289 break;
10290
10291 case NI_PIX_FMT_RGBA:
10292 case NI_PIX_FMT_BGRA:
10293 case NI_PIX_FMT_ARGB:
10294 case NI_PIX_FMT_ABGR:
10295 case NI_PIX_FMT_BGR0:
10296 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10297 p_frame->p_data[1] = NULL;
10298 p_frame->p_data[2] = NULL;
10299 p_frame->p_data[3] = NULL;
10300
10301 p_frame->data_len[0] = luma_size;
10302 p_frame->data_len[1] = 0;
10303 p_frame->data_len[2] = 0;
10304 p_frame->data_len[3] = 0;
10305 video_width = NI_VPU_ALIGN16(video_width);
10306 break;
10307
10308 case NI_PIX_FMT_NV12:
10309 case NI_PIX_FMT_P010LE:
10310 if (QUADRA)
10311 {
10312 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10313 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10314 p_frame->p_data[2] = NULL;
10315 p_frame->p_data[3] = NULL;
10316
10317 p_frame->data_len[0] = luma_size;
10318 p_frame->data_len[1] = chroma_b_size;
10319 p_frame->data_len[2] = 0;
10320 p_frame->data_len[3] = 0;
10321
10322 video_width = NI_VPU_ALIGN128(video_width);
10323 break;
10324 }
10325 case NI_PIX_FMT_NV16:
10326 if (QUADRA)
10327 {
10328 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10329 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10330 p_frame->p_data[2] = NULL;
10331 p_frame->p_data[3] = NULL;
10332
10333 p_frame->data_len[0] = luma_size;
10334 p_frame->data_len[1] = chroma_b_size;
10335 p_frame->data_len[2] = 0;
10336 p_frame->data_len[3] = 0;
10337
10338 video_width = NI_VPU_ALIGN64(video_width);
10339 break;
10340 }
10341
10342 case NI_PIX_FMT_YUYV422:
10343 case NI_PIX_FMT_UYVY422:
10344 if (QUADRA)
10345 {
10346 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10347 p_frame->p_data[1] = NULL;
10348 p_frame->p_data[2] = NULL;
10349 p_frame->p_data[3] = NULL;
10350
10351 p_frame->data_len[0] = luma_size;
10352 p_frame->data_len[1] = 0;
10353 p_frame->data_len[2] = 0;
10354 p_frame->data_len[3] = 0;
10355 video_width = NI_VPU_ALIGN16(video_width);
10356 break;
10357 }
10358 case NI_PIX_FMT_BGRP:
10359 if (QUADRA)
10360 {
10361 p_frame->p_data[0] = (uint8_t *)p_frame->p_buffer;
10362 p_frame->p_data[1] = (uint8_t *)p_frame->p_data[0] + luma_size;
10363 p_frame->p_data[2] = (uint8_t *)p_frame->p_data[1] + chroma_b_size;
10364 p_frame->p_data[3] = NULL;
10365
10366 p_frame->data_len[0] = luma_size;
10367 p_frame->data_len[1] = chroma_b_size;
10368 p_frame->data_len[2] = chroma_r_size;
10369 p_frame->data_len[3] = 0;
10370 break;
10371 }
10372 /* fall through */
10373 default:
10374 ni_log(NI_LOG_ERROR, "Error: unsupported pixel format %d\n",pixel_format);
10375 retval = NI_RETCODE_INVALID_PARAM;
10376 LRETURN;
10377 }
10378
10379 p_frame->video_width = video_width;
10380 p_frame->video_height = height_aligned;
10381
10382 ni_log(NI_LOG_DEBUG, "%s success: w=%d; h=%d; aligned buffer size=%d\n",
10383 __func__, video_width, video_height, buffer_size);
10384
10385END:
10386
10387 if (retval != NI_RETCODE_SUCCESS)
10388 {
10389 ni_aligned_free(p_buffer);
10390 }
10391
10392 return retval;
10393}
10394
10396 ni_network_data_t *p_network,
10397 const char *file)
10398{
10399 FILE *fp = NULL;
10400 struct stat file_stat;
10402 unsigned char *buffer = NULL;
10403
10404 if (!p_ctx)
10405 {
10406 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10407 __func__);
10409 }
10413
10414 char errmsg[NI_ERRNO_LEN] = {0};
10415 if (stat(file, &file_stat) != 0)
10416 {
10418 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to get network binary file stat, %s\n",
10419 __func__, errmsg);
10420 retval = NI_RETCODE_FAILURE;
10421 LRETURN;
10422 }
10423
10424 if (file_stat.st_size == 0)
10425 {
10426 ni_log2(p_ctx, NI_LOG_ERROR, "%s: network binary size is null\n", __func__);
10427 retval = NI_RETCODE_FAILURE;
10428 LRETURN;
10429 }
10430
10431 ni_fopen(&fp, file, "rb");
10432 if (!fp)
10433 {
10435 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to open network binary, %s\n", __func__,
10436 errmsg);
10437 retval = NI_RETCODE_FAILURE;
10438 LRETURN;
10439 }
10440
10441 buffer = malloc(file_stat.st_size);
10442 if (!buffer)
10443 {
10444 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to alloate memory\n", __func__);
10446 (void)fclose(fp);
10447 fp = NULL;
10448 LRETURN;
10449 }
10450
10451 if (fread(buffer, file_stat.st_size, 1, fp) != 1)
10452 {
10453 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to read network binary\n", __func__);
10454 retval = NI_RETCODE_FAILURE;
10455 (void)fclose(fp);
10456 fp = NULL;
10457 LRETURN;
10458 }
10459
10460 (void)fclose(fp);
10461 fp = NULL;
10462
10463 retval =
10464 ni_config_instance_network_binary(p_ctx, buffer, file_stat.st_size);
10465 if (retval != NI_RETCODE_SUCCESS)
10466 {
10467 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to configure instance, retval %d\n",
10468 __func__, retval);
10469 LRETURN;
10470 }
10471
10472 retval = ni_config_read_inout_layers(p_ctx, p_network);
10473 if (retval != NI_RETCODE_SUCCESS)
10474 {
10475 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to read network layers, retval %d\n",
10476 retval);
10477 }
10478
10479END:
10480 /* fp is always closed explicitly before LRETURN or after fread above */
10481 free(buffer);
10482
10484 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10486
10487 return retval;
10488}
10489
10491 ni_network_data_t *p_network)
10492{
10494
10495 if (!p_ctx)
10496 {
10497 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10498 __func__);
10500 }
10501
10502 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6ro") < 0))
10503 {
10504 ni_log2(p_ctx, NI_LOG_ERROR, "Error: hvsplus filter not supported on device with FW API version < 6ro\n");
10506 }
10507
10511
10512 retval =
10513 ni_config_instance_hvsplus(p_ctx); //, buffer, file_stat.st_size);
10514 if (retval != NI_RETCODE_SUCCESS)
10515 {
10516 ni_log2(p_ctx, NI_LOG_ERROR, "%s: failed to configure instance, retval %d\n",
10517 __func__, retval);
10518 LRETURN;
10519 }
10520
10521 retval = ni_config_read_inout_layers(p_ctx, p_network);
10522 if (retval != NI_RETCODE_SUCCESS)
10523 {
10524 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: failed to read network layers, retval %d\n",
10525 retval);
10526 }
10527
10528END:
10529
10531 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10533
10534 return retval;
10535}
10536
10538 ni_network_data_t *p_network)
10539{
10540 uint32_t buffer_size = 0;
10541 void *p_buffer = NULL;
10542 int retval = NI_RETCODE_SUCCESS;
10543 uint32_t i, this_size;
10544 ni_network_layer_info_t *p_linfo;
10545
10546 if (!p_frame || !p_network)
10547 {
10548 ni_log(NI_LOG_ERROR, "Invalid frame or network layer pointer\n");
10550 }
10551
10552 p_linfo = &p_network->linfo;
10553 for (i = 0; i < p_network->input_num; i++)
10554 {
10555 this_size = ni_ai_network_layer_size(&p_linfo->in_param[i]);
10556 this_size =
10557 (this_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
10558 if (p_network->inset[i].offset != buffer_size)
10559 {
10561 "ERROR: %s(): invalid buffer_size of network\n", __func__);
10563 }
10564 buffer_size += this_size;
10565 }
10566
10567 /* fixed size */
10568 p_frame->data_len[0] = buffer_size;
10569
10570 /* Allocate a buffer size that is page aligned for the host */
10571 buffer_size = (buffer_size + NI_MEM_PAGE_ALIGNMENT - 1) &
10572 ~(NI_MEM_PAGE_ALIGNMENT - 1);
10573
10574 /* If this buffer has a different size, realloc a new buffer */
10575 if ((p_frame->buffer_size > 0) && (p_frame->buffer_size != buffer_size))
10576 {
10577 ni_log(NI_LOG_DEBUG, "Free current p_frame, p_frame->buffer_size %u\n",
10578 p_frame->buffer_size);
10579 ni_frame_buffer_free(p_frame);
10580 }
10581
10582 if (p_frame->buffer_size != buffer_size)
10583 {
10584 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10585 {
10586 ni_log(NI_LOG_ERROR, "Error: Cannot allocate p_frame\n");
10588 LRETURN;
10589 }
10590
10591 // memset(p_buffer, 0, buffer_size);
10592 p_frame->buffer_size = buffer_size;
10593 p_frame->p_buffer = p_buffer;
10594 ni_log(NI_LOG_DEBUG, "%s(): allocated new p_frame buffer\n", __func__);
10595 } else
10596 {
10597 ni_log(NI_LOG_DEBUG, "%s(): reuse p_frame buffer\n", __func__);
10598 }
10599
10600 p_frame->p_data[0] = p_frame->p_buffer;
10601 p_frame->p_data[1] = NULL;
10602 p_frame->p_data[2] = NULL;
10603 p_frame->p_data[3] = NULL;
10604
10605 p_frame->iovec = NULL;
10606 p_frame->iovec_num = 0;
10607
10608 ni_log(NI_LOG_DEBUG, "%s() success: aligned buffer size=%u\n", __func__,
10609 buffer_size);
10610
10611END:
10612
10613 if (retval != NI_RETCODE_SUCCESS)
10614 {
10615 ni_aligned_free(p_buffer);
10616 }
10617
10618 return retval;
10619}
10620
10622 ni_network_data_t *p_network)
10623{
10624 void *p_buffer = NULL;
10625 int retval = NI_RETCODE_SUCCESS;
10626 uint32_t buffer_size = 0;
10627 uint32_t i, data_size;
10628 ni_network_layer_info_t *p_linfo;
10629
10630 if (!p_packet || !p_network)
10631 {
10632 ni_log(NI_LOG_ERROR, "ERROR: %s(): null pointer parameters passed\n",
10633 __func__);
10635 }
10636
10637 p_linfo = &p_network->linfo;
10638 for (i = 0; i < p_network->output_num; i++)
10639 {
10640 data_size = ni_ai_network_layer_size(&p_linfo->out_param[i]);
10641 data_size =
10642 (data_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
10643 if (p_network->outset[i].offset != buffer_size)
10644 {
10646 "ERROR: %s(): invalid buffer_size of network\n", __func__);
10648 }
10649 buffer_size += data_size;
10650 }
10651 data_size = buffer_size;
10652
10653 ni_log(NI_LOG_DEBUG, "%s(): packet_size=%u\n", __func__, buffer_size);
10654
10655 if (buffer_size & (NI_MEM_PAGE_ALIGNMENT - 1))
10656 {
10657 buffer_size = (buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
10658 ~(NI_MEM_PAGE_ALIGNMENT - 1);
10659 }
10660
10661 if (p_packet->buffer_size == buffer_size)
10662 {
10663 p_packet->p_data = p_packet->p_buffer;
10664 ni_log(NI_LOG_DEBUG, "%s(): reuse current p_packet buffer\n", __func__);
10665 LRETURN; //Already allocated the exact size
10666 } else if (p_packet->buffer_size > 0)
10667 {
10669 "%s(): free current p_packet, p_packet->buffer_size=%u\n",
10670 __func__, p_packet->buffer_size);
10671 ni_packet_buffer_free(p_packet);
10672 }
10673 ni_log(NI_LOG_DEBUG, "%s(): Allocating p_packet buffer, buffer_size=%u\n",
10674 __func__, buffer_size);
10675
10676 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
10677 {
10678 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_packet buffer.\n",
10679 NI_ERRNO, __func__);
10681 LRETURN;
10682 }
10683
10684 p_packet->buffer_size = buffer_size;
10685 p_packet->p_buffer = p_buffer;
10686 p_packet->p_data = p_packet->p_buffer;
10687 p_packet->data_len = data_size;
10688
10689END:
10690
10691 if (NI_RETCODE_SUCCESS != retval)
10692 {
10693 ni_aligned_free(p_buffer);
10694 }
10695
10696 ni_log(NI_LOG_TRACE, "%s(): exit: p_packet->buffer_size=%u\n", __func__,
10697 p_packet->buffer_size);
10698
10699 return retval;
10700}
10701
10702/*!*****************************************************************************
10703 * \brief Reconfigure bitrate dynamically during encoding.
10704 *
10705 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10706 * \param[in] bitrate Target bitrate to set
10707 *
10708 * \return On success NI_RETCODE_SUCCESS
10709 * On failure NI_RETCODE_INVALID_PARAM
10710 ******************************************************************************/
10712{
10713 if (!p_ctx || bitrate < NI_MIN_BITRATE || bitrate > NI_MAX_BITRATE)
10714 {
10715 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid bitrate passed in %d\n",
10716 __func__, bitrate);
10718 }
10721
10722 if (p_ctx->target_bitrate > 0)
10723 {
10724 ni_log2(p_ctx, NI_LOG_DEBUG,
10725 "Warning: %s(): bitrate %d overwriting current one %d\n",
10726 __func__, bitrate, p_ctx->target_bitrate);
10727 }
10728
10729 p_ctx->target_bitrate = bitrate;
10730
10731 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10733
10734 return NI_RETCODE_SUCCESS;
10735}
10736
10737/*!*****************************************************************************
10738 * \brief Reconfigure intraPeriod dynamically during encoding.
10739 *
10740 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10741 * \param[in] intra_period Target intra period to set
10742 *
10743 *
10744 * \return On success NI_RETCODE_SUCCESS
10745 * On failure NI_RETCODE_INVALID_PARAM
10746 *
10747 * NOTE - the frame upon which intra period is reconfigured is encoded as IDR frame
10748 * NOTE - reconfigure intra period is not allowed if intraRefreshMode is enabled or if gopPresetIdx is 1
10749 *
10750 ******************************************************************************/
10752 int32_t intra_period)
10753{
10754 if (!p_ctx || intra_period < 0 || intra_period > 1024)
10755 {
10756 ni_log(NI_LOG_ERROR, "ERROR: %s(): invalid intraPeriod passed in %d\n",
10757 __func__, intra_period);
10759 }
10762
10763 if (p_ctx->reconfig_intra_period >= 0)
10764 {
10766 "Warning: %s(): intraPeriod %d overwriting current one %d\n",
10767 __func__, intra_period, p_ctx->reconfig_intra_period);
10768 }
10769
10770 p_ctx->reconfig_intra_period = intra_period;
10771
10772 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10774
10775 return NI_RETCODE_SUCCESS;
10776}
10777
10778/*!*****************************************************************************
10779 * \brief Reconfigure VUI HRD dynamically during encoding.
10780 *
10781 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10782 * \param[in] bitrate Target bitrate to set
10783 *
10784 * \return On success NI_RETCODE_SUCCESS
10785 * On failure NI_RETCODE_INVALID_PARAM
10786 ******************************************************************************/
10788{
10789 if (!p_ctx || vui->colorDescPresent < 0 || vui->colorDescPresent > 1)
10790 {
10791 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid colorDescPresent passed in %d\n",
10792 __func__, vui->colorDescPresent);
10794 }
10795
10797 {
10798 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid aspect ratio passed in (%dx%d)\n",
10799 __func__, vui->aspectRatioWidth, vui->aspectRatioHeight);
10801 }
10802
10803 if (vui->videoFullRange < 0 || vui->videoFullRange > 1)
10804 {
10805 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid videoFullRange passed in %d\n",
10806 __func__, vui->videoFullRange);
10808 }
10809
10812
10814 p_ctx->vui.colorPrimaries = vui->colorPrimaries;
10815 p_ctx->vui.colorTrc = vui->colorTrc;
10816 p_ctx->vui.colorSpace = vui->colorSpace;
10819 p_ctx->vui.videoFullRange = vui->videoFullRange;
10820
10821 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10823
10824 return NI_RETCODE_SUCCESS;
10825}
10826
10827/*!*****************************************************************************
10828 * \brief Force next frame to be IDR frame during encoding.
10829 *
10830 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10831 *
10832 * \return On success NI_RETCODE_SUCCESS
10833 ******************************************************************************/
10835{
10836 if (!p_ctx)
10837 {
10838 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10839 __func__);
10841 }
10844
10845 if (p_ctx->force_idr_frame)
10846 {
10847 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: %s(): already forcing IDR frame\n",
10848 __func__);
10849 }
10850
10851 p_ctx->force_idr_frame = 1;
10852
10853 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
10855
10856 return NI_RETCODE_SUCCESS;
10857}
10858
10859/*!*****************************************************************************
10860 * \brief Set a frame's support of Long Term Reference frame during encoding.
10861 *
10862 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10863 * \param[in] ltr Pointer to struct specifying LTR support
10864 *
10865 * \return On success NI_RETCODE_SUCCESS
10866 * On failure NI_RETCODE_INVALID_PARAM
10867 ******************************************************************************/
10869{
10870 if (!p_ctx)
10871 {
10872 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10873 __func__);
10875 }
10877
10881
10883
10884 return NI_RETCODE_SUCCESS;
10885}
10886
10887/*!*****************************************************************************
10888 * \brief Set Long Term Reference interval
10889 *
10890 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10891 * \param[in] ltr_interval the new long term reference inteval value
10892 *
10893 * \return On success NI_RETCODE_SUCCESS
10894 * On failure NI_RETCODE_INVALID_PARAM
10895 ******************************************************************************/
10897 int32_t ltr_interval)
10898{
10899 if (!p_ctx)
10900 {
10901 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10902 __func__);
10904 }
10906
10907 p_ctx->ltr_interval = ltr_interval;
10908
10910
10911 return NI_RETCODE_SUCCESS;
10912}
10913
10914/*!*****************************************************************************
10915 * \brief Set frame reference invalidation
10916 *
10917 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10918 * \param[in] frame_num frame number after which all references shall be
10919 * invalidated
10920 *
10921 * \return On success NI_RETCODE_SUCCESS
10922 * On failure NI_RETCODE_INVALID_PARAM
10923 ******************************************************************************/
10925 int32_t frame_num)
10926{
10927 if (!p_ctx)
10928 {
10929 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
10930 __func__);
10932 }
10934 p_ctx->ltr_frame_ref_invalid = frame_num;
10936
10937 return NI_RETCODE_SUCCESS;
10938}
10939
10940/*!*****************************************************************************
10941 * \brief Reconfigure framerate dynamically during encoding.
10942 *
10943 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
10944 * \param[in] framerate Target framerate to set
10945 *
10946 * \return On success NI_RETCODE_SUCCESS
10947 * On failure NI_RETCODE_INVALID_PARAM
10948 ******************************************************************************/
10950 ni_framerate_t *framerate)
10951{
10952 int32_t framerate_num = framerate->framerate_num;
10953 int32_t framerate_denom = framerate->framerate_denom;
10954 if (!p_ctx || framerate_num <= 0 || framerate_denom <= 0)
10955 {
10956 ni_log2(p_ctx, NI_LOG_ERROR,
10957 "ERROR: %s(): invalid framerate passed in (%d/%d)\n", __func__,
10958 framerate_num, framerate_denom);
10960 }
10961
10962 if ((framerate_num % framerate_denom) != 0)
10963 {
10964 uint32_t numUnitsInTick = 1000;
10965 framerate_num = framerate_num / framerate_denom;
10966 framerate_denom = (int)(numUnitsInTick + 1);
10967 framerate_num += 1;
10968 framerate_num *= (int)numUnitsInTick;
10969 } else
10970 {
10971 framerate_num = framerate_num / framerate_denom;
10972 framerate_denom = 1;
10973 }
10974
10975 if (((framerate_num + framerate_denom - 1) / framerate_denom) >
10977 {
10978 ni_log2(p_ctx, NI_LOG_ERROR,
10979 "ERROR: %s(): invalid framerate passed in (%d/%d)\n", __func__,
10980 framerate->framerate_num, framerate->framerate_denom);
10982 }
10983
10986
10987 if (p_ctx->framerate.framerate_num > 0)
10988 {
10989 ni_log2(p_ctx, NI_LOG_DEBUG,
10990 "Warning: %s(): framerate (%d/%d) overwriting current "
10991 "one (%d/%d)\n",
10992 __func__, framerate_num, framerate_denom,
10993 p_ctx->framerate.framerate_num,
10994 p_ctx->framerate.framerate_denom);
10995 }
10996
10997 p_ctx->framerate.framerate_num = framerate_num;
10998 p_ctx->framerate.framerate_denom = framerate_denom;
10999
11000 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11002
11003 return NI_RETCODE_SUCCESS;
11004}
11005
11006/*!*****************************************************************************
11007 * \brief Reconfigure maxFrameSize dynamically during encoding.
11008 *
11009 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11010 * \param[in] max_frame_size maxFrameSize to set
11011 *
11012 * \return On success NI_RETCODE_SUCCESS
11013 * On failure NI_RETCODE_INVALID_PARAM
11014 *
11015 * NOTE - maxFrameSize_Bytes value less than ((bitrate / 8) / framerate) will be rejected
11016 *
11017 ******************************************************************************/
11019{
11020 ni_xcoder_params_t *api_param;
11021 int32_t bitrate, framerate_num, framerate_denom;
11022 uint32_t maxFrameSize = (uint32_t)max_frame_size / 2000;
11023 uint32_t min_maxFrameSize;
11024
11025 if (!p_ctx || !p_ctx->p_session_config)
11026 {
11027 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11028 __func__);
11030 }
11031
11032 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11033
11034 if (!api_param->low_delay_mode)
11035 {
11036 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size is valid only when lowDelay mode is enabled\n",
11037 __func__, max_frame_size);
11039 }
11040
11041 bitrate = (p_ctx->target_bitrate > 0) ? p_ctx->target_bitrate : api_param->bitrate;
11042
11043 if ((p_ctx->framerate.framerate_num > 0) && (p_ctx->framerate.framerate_denom > 0))
11044 {
11045 framerate_num = p_ctx->framerate.framerate_num;
11046 framerate_denom = p_ctx->framerate.framerate_denom;
11047 }
11048 else
11049 {
11050 framerate_num = (int32_t) api_param->fps_number;
11051 framerate_denom = (int32_t) api_param->fps_denominator;
11052 }
11053
11054 min_maxFrameSize = (((uint32_t)bitrate / framerate_num * framerate_denom) / 8) / 2000;
11055
11056 if (maxFrameSize < min_maxFrameSize)
11057 {
11058 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size %d is too small (invalid)\n",
11059 __func__, max_frame_size);
11061 }
11062 if (max_frame_size > NI_MAX_FRAME_SIZE) {
11063 max_frame_size = NI_MAX_FRAME_SIZE;
11064 }
11065
11068
11069 if (p_ctx->max_frame_size > 0)
11070 {
11071 ni_log2(p_ctx, NI_LOG_DEBUG,
11072 "Warning: %s(): max_frame_size %d overwriting current one %d\n",
11073 __func__, max_frame_size, p_ctx->max_frame_size);
11074 }
11075
11076 p_ctx->max_frame_size = max_frame_size;
11077
11078 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11080
11081 return NI_RETCODE_SUCCESS;
11082}
11083
11084/*!*****************************************************************************
11085 * \brief Reconfigure min&max qp dynamically during encoding.
11086 *
11087 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11088 * \param[in] ni_rc_min_max_qp Target min&max qp to set
11089 *
11090 * \return On success NI_RETCODE_SUCCESS
11091 * On failure NI_RETCODE_INVALID_PARAM
11092 ******************************************************************************/
11094 ni_rc_min_max_qp *p_min_max_qp)
11095{
11096 int32_t minQpI, maxQpI, maxDeltaQp, minQpPB, maxQpPB;
11097
11098 if (!p_ctx || !p_min_max_qp)
11099 {
11100 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_min_max_qp pointer\n",
11101 __func__);
11103 }
11104
11105 minQpI = p_min_max_qp->minQpI;
11106 maxQpI = p_min_max_qp->maxQpI;
11107 maxDeltaQp = p_min_max_qp->maxDeltaQp;
11108 minQpPB = p_min_max_qp->minQpPB;
11109 maxQpPB = p_min_max_qp->maxQpPB;
11110
11111 if (minQpI > maxQpI || minQpPB > maxQpPB ||
11112 maxQpI > 51 || minQpI < 0 || maxQpPB > 51 || minQpPB < 0)
11113 {
11114 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid qp setting <%d %d %d %d %d>\n",
11115 __func__, minQpI, maxQpI, maxDeltaQp, minQpPB, maxQpPB);
11117 }
11118
11121
11122 p_ctx->enc_change_params->minQpI = minQpI;
11123 p_ctx->enc_change_params->maxQpI = maxQpI;
11124 p_ctx->enc_change_params->maxDeltaQp = maxDeltaQp;
11125 p_ctx->enc_change_params->minQpPB = minQpPB;
11126 p_ctx->enc_change_params->maxQpPB = maxQpPB;
11127
11128 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11130
11131 return NI_RETCODE_SUCCESS;
11132}
11133
11134/*!*****************************************************************************
11135 * \brief Reconfigure crf value dynamically during encoding.
11136 *
11137 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11138 * \param[in] crf crf value to reconfigure
11139 *
11140 * \return On success NI_RETCODE_SUCCESS
11141 * On failure NI_RETCODE_INVALID_PARAM
11142 ******************************************************************************/
11144 int32_t crf)
11145{
11146 ni_xcoder_params_t *api_param;
11147
11148 if (!p_ctx || !p_ctx->p_session_config)
11149 {
11150 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11151 __func__);
11153 }
11154
11155 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11156
11157 if (api_param->cfg_enc_params.crf < 0)
11158 {
11159 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %d is valid only in CRF mode\n",
11160 __func__, crf);
11162 }
11163
11164 if (crf < 0 || crf > 51)
11165 {
11166 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %d is invalid (valid range in [0..51])\n",
11167 __func__, crf);
11169 }
11170
11172
11174
11175 if (p_ctx->reconfig_crf >= 0)
11176 {
11177 ni_log2(p_ctx, NI_LOG_DEBUG,
11178 "Warning: %s(): crf reconfig value %d overwriting current reconfig_crf %d\n",
11179 __func__, crf, p_ctx->reconfig_crf);
11180 }
11181
11182 p_ctx->reconfig_crf = crf;
11183
11184 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11185
11187
11188 return NI_RETCODE_SUCCESS;
11189}
11190
11191/*!*****************************************************************************
11192 * \brief Reconfigure crf float point value dynamically during encoding.
11193 *
11194 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11195 * \param[in] crf crf float point value to reconfigure
11196 *
11197 * \return On success NI_RETCODE_SUCCESS
11198 * On failure NI_RETCODE_INVALID_PARAM
11199 ******************************************************************************/
11201 float crf)
11202{
11203 ni_xcoder_params_t *api_param;
11204
11205 if (!p_ctx || !p_ctx->p_session_config)
11206 {
11207 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11208 __func__);
11210 }
11211
11212 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11213
11214 if (api_param->cfg_enc_params.crfFloat < 0)
11215 {
11216 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): reconfigure crf value %f is valid only in CRF mode\n",
11217 __func__, crf);
11219 }
11220
11221 if (crf < 0.0 || crf > 51.0)
11222 {
11223 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): crf value %f is invalid (valid range in [0..51])\n",
11224 __func__, crf);
11226 }
11227
11229
11231
11232 if (p_ctx->reconfig_crf >= 0 || p_ctx->reconfig_crf_decimal > 0)
11233 {
11234 ni_log2(p_ctx, NI_LOG_DEBUG,
11235 "Warning: %s(): crf reconfig value %d overwriting current "
11236 "reconfig_crf %d, reconfig_crf_decimal %d\n", __func__,
11237 crf, p_ctx->reconfig_crf, p_ctx->reconfig_crf_decimal);
11238 }
11239
11240 p_ctx->reconfig_crf = (int)crf;
11241 p_ctx->reconfig_crf_decimal = (int)((crf - (float)p_ctx->reconfig_crf) * 100);
11242
11243 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11244
11246
11247 return NI_RETCODE_SUCCESS;
11248}
11249
11250/*!*****************************************************************************
11251 * \brief Reconfigure vbv buffer size and vbv max rate dynamically during encoding.
11252 *
11253 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11254 * \param[in] vbvBufferSize Target vbvBufferSize to set
11255 * \param[in] vbvMaxRate Target vbvMaxRate to set
11256 *
11257 * \return On success NI_RETCODE_SUCCESS
11258 * On failure NI_RETCODE_INVALID_PARAM
11259 ******************************************************************************/
11261 int32_t vbvMaxRate, int32_t vbvBufferSize)
11262{
11263 ni_xcoder_params_t *api_param;
11264 if (!p_ctx || !p_ctx->p_session_config)
11265 {
11266 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11267 __func__);
11269 }
11270 if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
11271 {
11272 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): vbvBufferSize value %d\n",
11273 __func__, vbvBufferSize);
11275 }
11276 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11277 if (api_param->bitrate > 0 && vbvMaxRate > 0 && vbvMaxRate < api_param->bitrate) {
11278 ni_log2(p_ctx, NI_LOG_ERROR, "vbvMaxRate %u cannot be smaller than bitrate %d\n",
11279 vbvMaxRate, api_param->bitrate);
11281 }
11282 if (vbvBufferSize == 0 && vbvMaxRate > 0) {
11283 ni_log2(p_ctx, NI_LOG_INFO, "vbvMaxRate %d does not take effect when "
11284 "vbvBufferSize is 0, force vbvMaxRate to 0\n",
11285 vbvMaxRate);
11286 vbvMaxRate = 0;
11287 }
11288
11291
11292 p_ctx->reconfig_vbv_buffer_size = vbvBufferSize;
11293 p_ctx->reconfig_vbv_max_rate = vbvMaxRate;
11294
11295 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11297
11298 return NI_RETCODE_SUCCESS;
11299}
11300
11301/*!*****************************************************************************
11302 * \brief Reconfigure maxFrameSizeRatio dynamically during encoding.
11303 *
11304 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11305 * \param[in] max_frame_size_ratio maxFrameSizeRatio to set
11306 *
11307 * \return On success NI_RETCODE_SUCCESS
11308 * On failure NI_RETCODE_INVALID_PARAM
11309 ******************************************************************************/
11311{
11312 ni_xcoder_params_t *api_param;
11313 int32_t bitrate, framerate_num, framerate_denom;
11314 uint32_t min_maxFrameSize, maxFrameSize;
11315
11316 if (!p_ctx || !p_ctx->p_session_config)
11317 {
11318 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11319 __func__);
11321 }
11322
11323 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11324
11325 if (!api_param->low_delay_mode)
11326 {
11327 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size_ratio is valid only when lowDelay mode is enabled\n",
11328 __func__, max_frame_size_ratio);
11330 }
11331
11332 if (max_frame_size_ratio < 1) {
11333 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): max_frame_size_ratio %d cannot < 1\n",
11334 max_frame_size_ratio);
11336 }
11337
11338 bitrate = (p_ctx->target_bitrate > 0) ? p_ctx->target_bitrate : api_param->bitrate;
11339
11340 if ((p_ctx->framerate.framerate_num > 0) && (p_ctx->framerate.framerate_denom > 0))
11341 {
11342 framerate_num = p_ctx->framerate.framerate_num;
11343 framerate_denom = p_ctx->framerate.framerate_denom;
11344 }
11345 else
11346 {
11347 framerate_num = (int32_t) api_param->fps_number;
11348 framerate_denom = (int32_t) api_param->fps_denominator;
11349 }
11350
11351 min_maxFrameSize = (((uint32_t)bitrate / framerate_num * framerate_denom) / 8) / 2000;
11352
11353 maxFrameSize = min_maxFrameSize * max_frame_size_ratio > NI_MAX_FRAME_SIZE ?
11354 NI_MAX_FRAME_SIZE : min_maxFrameSize * max_frame_size_ratio;
11355
11358
11359 if (p_ctx->max_frame_size > 0)
11360 {
11361 ni_log2(p_ctx, NI_LOG_DEBUG,
11362 "Warning: %s(): max_frame_size %d overwriting current one %d\n",
11363 __func__, maxFrameSize, p_ctx->max_frame_size);
11364 }
11365
11366 p_ctx->max_frame_size = (int32_t)maxFrameSize;
11367
11368 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11370
11371 return NI_RETCODE_SUCCESS;
11372}
11373
11374/*!*****************************************************************************
11375 * \brief Reconfigure sliceArg dynamically during encoding.
11376 *
11377 * \param[in] p_ctx Pointer to caller allocated ni_session_context_t
11378 * \param[in] sliceArg the new sliceArg value
11379 *
11380 * \return On success NI_RETCODE_SUCCESS
11381 * On failure NI_RETCODE_INVALID_PARAM
11382 ******************************************************************************/
11384{
11385 ni_xcoder_params_t *api_param;
11387
11388 if (!p_ctx || !p_ctx->p_session_config)
11389 {
11390 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid ni_session_context_t or p_session_config pointer\n",
11391 __func__);
11393 }
11394
11395 api_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
11396 p_enc = &api_param->cfg_enc_params;
11397 if (p_enc->slice_mode == 0)
11398 {
11399 ni_log2(p_ctx, NI_LOG_ERROR, "%s():not support to reconfig slice_arg when slice_mode disable.\n",
11400 __func__);
11401 sliceArg = 0;
11402 }
11404 {
11405 ni_log2(p_ctx, NI_LOG_ERROR, "%s():sliceArg is only supported for H.264 or H.265.\n",
11406 __func__);
11407 sliceArg = 0;
11408 }
11409 int ctu_mb_size = (NI_CODEC_FORMAT_H264 == p_ctx->codec_format) ? 16 : 64;
11410 int max_num_ctu_mb_row = (api_param->source_height + ctu_mb_size - 1) / ctu_mb_size;
11411 if (sliceArg < 1 || sliceArg > max_num_ctu_mb_row)
11412 {
11413 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid data sliceArg %d\n", __func__,
11414 sliceArg);
11415 sliceArg = 0;
11416 }
11417
11420
11421 p_ctx->reconfig_slice_arg = sliceArg;
11422
11423 p_ctx->xcoder_state &= ~NI_XCODER_GENERAL_STATE;
11425
11426 return NI_RETCODE_SUCCESS;
11427}
11428
11429#ifndef _WIN32
11430/*!*****************************************************************************
11431* \brief Acquire a P2P frame buffer from the hwupload session
11432*
11433* \param[in] p_ctx Pointer to a caller allocated
11434* ni_session_context_t struct
11435* \param[out] p_frame Pointer to a caller allocated hw frame
11436*
11437* \return On success
11438* NI_RETCODE_SUCCESS
11439* On failure
11440* NI_RETCODE_INVALID_PARAM
11441* NI_RETCODE_ERROR_NVME_CMD_FAILED
11442* NI_RETCODE_ERROR_INVALID_SESSION
11443*******************************************************************************/
11445{
11447 struct netint_iocmd_export_dmabuf uexp;
11448 unsigned int offset;
11449 int ret, is_semi_planar;
11450 int linestride[NI_MAX_NUM_DATA_POINTERS];
11451 int alignedheight[NI_MAX_NUM_DATA_POINTERS];
11452 niFrameSurface1_t hwdesc = {0};
11453 niFrameSurface1_t *p_surface;
11454
11455 if (p_ctx == NULL || p_frame == NULL || p_frame->p_data[3] == NULL)
11456 {
11457 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
11458 __func__);
11460 }
11461
11462 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11463
11466
11467 retval = ni_hwupload_session_read_hwdesc(p_ctx, &hwdesc);
11468
11471
11472 if (retval != NI_RETCODE_SUCCESS)
11473 {
11474 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: hwdesc read failure %d\n", retval);
11475 return retval;
11476 }
11477
11478 retval = ni_get_memory_offset(p_ctx, &hwdesc, &offset);
11479 if (retval != NI_RETCODE_SUCCESS)
11480 {
11481 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: bad buffer id\n");
11483 }
11484
11485 is_semi_planar = ((p_ctx->pixel_format == NI_PIX_FMT_NV12) ||
11486 p_ctx->pixel_format == NI_PIX_FMT_P010LE) ?
11487 1 :
11488 0;
11489
11491 p_ctx->bit_depth_factor, is_semi_planar, linestride,
11492 alignedheight);
11493
11494 uexp.fd = -1;
11495 uexp.flags = 0;
11496 uexp.offset = offset;
11497
11498 uexp.length = ni_calculate_total_frame_size(p_ctx, linestride);
11499 uexp.domain = p_ctx->domain;
11500 uexp.bus = p_ctx->bus;
11501 uexp.dev = p_ctx->dev;
11502 uexp.fn = p_ctx->fn;
11503 uexp.bar = 4; // PCI BAR4 configuration space
11504
11505 ret = ioctl(p_ctx->netint_fd, NETINT_IOCTL_EXPORT_DMABUF, &uexp);
11506 if (ret < 0)
11507 {
11508 ni_log2(p_ctx, NI_LOG_ERROR, "%s: Failed to export dmabuf %d errno %d\n",
11509 __func__, ret, NI_ERRNO);
11510 return NI_RETCODE_FAILURE;
11511 }
11512
11513 *p_surface = hwdesc;
11514 p_surface->ui16width = p_ctx->active_video_width;
11515 p_surface->ui16height = p_ctx->active_video_height;
11516 p_surface->ui32nodeAddress = offset;
11517 p_surface->encoding_type = is_semi_planar ?
11520 p_surface->dma_buf_fd = uexp.fd;
11521
11522 return retval;
11523}
11524
11525/*!*****************************************************************************
11526* \brief Acquire a P2P frame buffer from the hwupload session for P2P read
11527*
11528* \param[in] p_ctx Pointer to a caller allocated
11529* ni_session_context_t struct
11530* \param[out] p_frame Pointer to a caller allocated hw frame
11531*
11532* \return On success
11533* NI_RETCODE_SUCCESS
11534* On failure
11535* NI_RETCODE_INVALID_PARAM
11536* NI_RETCODE_ERROR_NVME_CMD_FAILED
11537* NI_RETCODE_ERROR_INVALID_SESSION
11538*******************************************************************************/
11540{
11542
11543 int is_semi_planar;
11544 int linestride[NI_MAX_NUM_DATA_POINTERS];
11545 int alignedheight[NI_MAX_NUM_DATA_POINTERS];
11546 niFrameSurface1_t hwdesc = {0};
11547 niFrameSurface1_t *p_surface;
11548
11549 if (p_ctx == NULL || p_frame == NULL || p_frame->p_data[3] == NULL)
11550 {
11551 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
11552 __func__);
11554 }
11555
11556 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11557
11560
11561 retval = ni_hwupload_session_read_hwdesc(p_ctx, &hwdesc);
11562
11565
11566 if (retval != NI_RETCODE_SUCCESS)
11567 {
11568 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: hwdesc read failure %d\n", retval);
11569 return retval;
11570 }
11571
11572 is_semi_planar = ((p_ctx->pixel_format == NI_PIX_FMT_NV12) ||
11573 p_ctx->pixel_format == NI_PIX_FMT_P010LE) ?
11574 1 :
11575 0;
11576
11578 p_ctx->bit_depth_factor, is_semi_planar, linestride,
11579 alignedheight);
11580
11581 *p_surface = hwdesc;
11582 p_surface->ui16width = p_ctx->active_video_width;
11583 p_surface->ui16height = p_ctx->active_video_height;
11584 p_surface->ui32nodeAddress = 0;
11585 p_surface->encoding_type = is_semi_planar ?
11588 p_surface->dma_buf_fd = 0;
11589
11590 return retval;
11591}
11592
11593
11594/*!*****************************************************************************
11595 * \brief Lock a hardware P2P frame prior to encoding
11596 *
11597 * \param[in] p_upl_ctx pointer to caller allocated upload context
11598 * [in] p_frame pointer to caller allocated hardware P2P frame
11599 *
11600 * \return On success
11601 * NI_RETCODE_SUCCESS
11602 * On failure NI_RETCODE_FAILURE
11603 * NI_RETCODE_INVALID_PARAM
11604*******************************************************************************/
11606 ni_frame_t *p_frame)
11607{
11608 int ret;
11609 struct netint_iocmd_attach_rfence uatch = {0};
11610 struct pollfd pfds[1] = {0};
11611 niFrameSurface1_t *p_surface;
11612
11613 if (p_upl_ctx == NULL || p_frame == NULL)
11614 {
11615 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: bad parameters\n", __func__);
11617 }
11618
11619 if (p_frame->p_data[3] == NULL)
11620 {
11621 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: not a hardware frame\n", __func__);
11623 }
11624
11625 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11626
11627 pfds[0].fd = p_surface->dma_buf_fd;
11628 pfds[0].events = POLLIN;
11629 pfds[0].revents = 0;
11630
11631 ret = poll(pfds, 1, -1);
11632 char errmsg[NI_ERRNO_LEN] = {0};
11633 if (ret < 0)
11634 {
11636 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s:failed to poll dmabuf fd errno %s\n", __func__,
11637 errmsg);
11638 return ret;
11639 }
11640
11641 uatch.fd = p_surface->dma_buf_fd;
11642 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_ATTACH_RFENCE, &uatch);
11643 if (ret < 0)
11644 {
11646 ni_log2(p_upl_ctx, NI_LOG_ERROR,
11647 "%s: failed to attach dmabuf read fence errno %s\n", __func__,
11648 errmsg);
11649 return ret;
11650 }
11651
11652 return NI_RETCODE_SUCCESS;
11653}
11654
11655/*!*****************************************************************************
11656 * \brief Unlock a hardware P2P frame after encoding
11657 *
11658 * \param[in] p_upl_ctx pointer to caller allocated upload context
11659 * [in] p_frame pointer to caller allocated hardware P2P frame
11660 *
11661 * \return On success
11662 * NI_RETCODE_SUCCESS
11663 * On failure NI_RETCODE_FAILURE
11664 * NI_RETCODE_INVALID_PARAM
11665*******************************************************************************/
11667 ni_frame_t *p_frame)
11668{
11669 int ret;
11670 struct netint_iocmd_signal_rfence usigl = {0};
11671 niFrameSurface1_t *p_surface;
11672
11673 if ((p_upl_ctx == NULL) || (p_frame == NULL))
11674 {
11675 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid parameters %p %p\n", __func__,
11676 p_upl_ctx, p_frame);
11678 }
11679
11680 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11681
11682 if (p_surface == NULL)
11683 {
11684 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid hw frame\n", __func__);
11686 }
11687
11688 usigl.fd = p_surface->dma_buf_fd;
11689 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_SIGNAL_RFENCE, &usigl);
11690 if (ret < 0)
11691 {
11692 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Failed to signal dmabuf read fence\n");
11693 return NI_RETCODE_FAILURE;
11694 }
11695
11696 return NI_RETCODE_SUCCESS;
11697}
11698
11699/*!*****************************************************************************
11700 * \brief Special P2P test API function. Copies YUV data from the software
11701 * frame to the hardware P2P frame on the Quadra device
11702 *
11703 * \param[in] p_upl_ctx pointer to caller allocated uploader session
11704 * context
11705 * [in] p_swframe pointer to a caller allocated software frame
11706 * [in] p_hwframe pointer to a caller allocated hardware frame
11707 *
11708 * \return On success
11709 * NI_RETCODE_SUCCESS
11710 * On failure
11711 * NI_RETCODE_FAILURE
11712 * NI_RETCODE_INVALID_PARAM
11713*******************************************************************************/
11715 uint8_t *p_data, uint32_t len,
11716 ni_frame_t *p_hwframe)
11717{
11718 int ret;
11719 struct netint_iocmd_issue_request uis = {0};
11720 niFrameSurface1_t *p_surface;
11721
11722 if (p_upl_ctx == NULL || p_data == NULL || p_hwframe == NULL)
11723 {
11724 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: invalid null parameters\n", __func__);
11726 }
11727
11728 if (p_hwframe->p_data[3] == NULL)
11729 {
11730 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: empty frame\n", __func__);
11732 }
11733
11734 p_surface = (niFrameSurface1_t *)p_hwframe->p_data[3];
11735
11736 uis.fd = p_surface->dma_buf_fd;
11737 uis.data = p_data;
11738 uis.len = len;
11740
11741 ret = ioctl(p_upl_ctx->netint_fd, NETINT_IOCTL_ISSUE_REQ, &uis);
11742 if (ret < 0)
11743 {
11744 ni_log2(p_upl_ctx, NI_LOG_ERROR,
11745 "%s: Failed to request dmabuf rendering errno %d\n", __func__,
11746 NI_ERRNO);
11747 return NI_RETCODE_FAILURE;
11748 }
11749
11750 return NI_RETCODE_SUCCESS;
11751}
11752
11753/*!*****************************************************************************
11754 * \brief Special P2P test API function. Copies video data from the software
11755 * frame to the hardware P2P frame on the Quadra device. Does not
11756 * need the Netint kernel driver but requires root privilege.
11757 *
11758 * \param[in] p_upl_ctx pointer to caller allocated uploader session
11759 * context
11760 * [in] p_swframe pointer to a caller allocated software frame
11761 * [in] p_hwframe pointer to a caller allocated hardware frame
11762 *
11763 * \return On success
11764 * NI_RETCODE_SUCCESS
11765 * On failure
11766 * NI_RETCODE_FAILURE
11767 * NI_RETCODE_INVALID_PARAM
11768*******************************************************************************/
11770 uint8_t *p_data, uint32_t len,
11771 ni_frame_t *p_hwframe)
11772{
11773 int bar4_fd, ret;
11774 char bar4_name[128];
11775 char *bar4_mm;
11776 struct stat stat;
11777 niFrameSurface1_t *pSurf;
11778 uint32_t offset;
11779
11780 pSurf = (niFrameSurface1_t *) p_hwframe->p_data[3];
11781
11782 ret = ni_get_memory_offset(p_upl_ctx, pSurf, &offset);
11783 if (ret != 0)
11784 {
11785 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Error bad buffer id\n");
11786 return NI_RETCODE_FAILURE;
11787 }
11788
11789 (void)snprintf(bar4_name, 128,
11790 "/sys/bus/pci/devices/%04x:%02x:%02x.%1x/resource4",
11791 p_upl_ctx->domain,p_upl_ctx->bus,p_upl_ctx->dev,p_upl_ctx->fn);
11792
11793 bar4_fd = open(bar4_name, O_RDWR | O_SYNC);
11794
11795 char errmsg[NI_ERRNO_LEN] = {0};
11796 if (bar4_fd < 0)
11797 {
11799 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't open bar4 %s (%s)\n",
11800 bar4_name, errmsg);
11801 return NI_RETCODE_FAILURE;
11802 }
11803
11804 if (fstat(bar4_fd, &stat) != 0)
11805 {
11807 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't stat bar4 (%s)\n",
11808 errmsg);
11809 (void)close(bar4_fd);
11810 return NI_RETCODE_FAILURE;
11811 }
11812
11813 bar4_mm = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, bar4_fd, 0);
11814
11815 if (bar4_mm == MAP_FAILED)
11816 {
11818 ni_log2(p_upl_ctx, NI_LOG_ERROR, "Can't mmap to bar4 (%s)\n",
11819 errmsg);
11820 (void)close(bar4_fd);
11821 return NI_RETCODE_FAILURE;
11822 }
11823
11824 /* Copy the data directly into Quadra video memory */
11825 memcpy(bar4_mm + offset, p_data, len);
11826
11827 (void)munmap(bar4_mm, 0);
11828 (void)close(bar4_fd);
11829
11830 return NI_RETCODE_SUCCESS;
11831}
11832
11833
11834/*!*****************************************************************************
11835 * \brief Recycle hw P2P frames
11836 *
11837 * \param [in] p_frame pointer to an acquired P2P hw frame
11838 *
11839 * \return on success
11840 * NI_RETCODE_SUCCESS
11841 *
11842 * on failure
11843 * NI_RETCODE_INVALID_PARAM
11844*******************************************************************************/
11846{
11847 niFrameSurface1_t *p_surface;
11848
11849 if (p_frame == NULL)
11850 {
11851 ni_log(NI_LOG_ERROR, "%s: Invalid frame\n", __func__);
11853 }
11854
11855 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
11856 if (p_surface == NULL)
11857 {
11858 ni_log(NI_LOG_ERROR, "%s: Invalid surface data\n", __func__);
11860 }
11861
11862 return ni_hwframe_buffer_recycle2(p_surface);
11863}
11864
11865/*!*****************************************************************************
11866 * \brief Acquire the scaler P2P DMA buffer for read/write
11867 *
11868 * \param [in] p_ctx pointer to caller allocated upload context
11869 * [in] p_surface pointer to a caller allocated hardware frame
11870 * [in] data_len scaler frame buffer data length
11871 *
11872 * \return on success
11873 * NI_RETCODE_SUCCESS
11874 *
11875 * on failure
11876 * NI_RETCODE_FAILURE
11877*******************************************************************************/
11879 niFrameSurface1_t *p_surface,
11880 int data_len)
11881{
11882 unsigned int offset;
11883 int ret;
11884
11885 ret = ni_get_memory_offset(p_ctx, p_surface, &offset);
11886 if (ret != 0)
11887 {
11888 ni_log2(p_ctx, NI_LOG_ERROR, "Error: bad buffer id\n");
11889 return NI_RETCODE_FAILURE;
11890 }
11891 p_surface->ui32nodeAddress = 0;
11892
11893 struct netint_iocmd_export_dmabuf uexp;
11894 uexp.fd = -1;
11895 uexp.flags = 0;
11896 uexp.offset = offset;
11897 uexp.length = data_len;
11898 uexp.domain = p_ctx->domain;
11899 uexp.bus = p_ctx->bus;
11900 uexp.dev = p_ctx->dev;
11901 uexp.fn = p_ctx->fn;
11902 uexp.bar = 4;
11903 ret = ioctl(p_ctx->netint_fd, NETINT_IOCTL_EXPORT_DMABUF, &uexp);
11904 if (ret < 0)
11905 {
11906 char errmsg[NI_ERRNO_LEN] = {0};
11908 ni_log2(p_ctx, NI_LOG_ERROR, "failed to export dmabuf: %s\n", errmsg);
11909 return NI_RETCODE_FAILURE;
11910 }
11911 p_surface->dma_buf_fd = uexp.fd;
11912 return ret;
11913}
11914#endif
11915
11916/*!*****************************************************************************
11917 * \brief Set the incoming frame format for the encoder
11918 *
11919 * \param[in] p_enc_ctx pointer to encoder context
11920 * [in] p_enc_params pointer to encoder parameters
11921 * [in] width input width
11922 * [in] height input height
11923 * [in] bit_depth 8 for 8-bit YUV, 10 for 10-bit YUV
11924 * [in] src_endian NI_FRAME_LITTLE_ENDIAN or NI_FRAME_BIG_ENDIAN
11925 * [in] planar 0 for semi-planar YUV, 1 for planar YUV
11926 *
11927 * \return on success
11928 * NI_RETCODE_SUCCESS
11929 *
11930 * on failure
11931 * NI_RETCODE_INVALID_PARAM
11932 *
11933*******************************************************************************/
11935 ni_xcoder_params_t *p_enc_params,
11936 int width, int height,
11937 int bit_depth, int src_endian,
11938 int planar)
11939{
11940 int alignedw;
11941 int alignedh;
11942
11943 if (p_enc_ctx == NULL || p_enc_params == NULL)
11944 {
11945 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: null ptr\n", __func__);
11947 }
11948
11949 if (!(bit_depth == 8) && !(bit_depth == 10))
11950 {
11951 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad bit depth %d\n", __func__, bit_depth);
11953 }
11954
11955 if (!(src_endian == NI_FRAME_LITTLE_ENDIAN) &&
11956 !(src_endian == NI_FRAME_BIG_ENDIAN))
11957 {
11958 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad endian %d\n", __func__, src_endian);
11960 }
11961
11962 if ((planar < 0) || (planar >= NI_PIXEL_PLANAR_MAX))
11963 {
11964 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: bad planar value %d\n", __func__, planar);
11966 }
11967
11968 p_enc_ctx->src_bit_depth = bit_depth;
11969 p_enc_ctx->bit_depth_factor = (bit_depth == 8) ? 1 : 2;
11970 p_enc_ctx->src_endian = src_endian;
11971
11972 alignedw = width;
11973
11974 if (alignedw < NI_MIN_WIDTH)
11975 {
11976 p_enc_params->cfg_enc_params.conf_win_right +=
11977 (NI_MIN_WIDTH - width) / 2 * 2;
11978 alignedw = NI_MIN_WIDTH;
11979 } else
11980 {
11981 alignedw = ((width + 1) / 2) * 2;
11982 p_enc_params->cfg_enc_params.conf_win_right +=
11983 (alignedw - width) / 2 * 2;
11984 }
11985
11986 p_enc_params->source_width = alignedw;
11987 alignedh = height;
11988
11989 if (alignedh < NI_MIN_HEIGHT)
11990 {
11991 p_enc_params->cfg_enc_params.conf_win_bottom +=
11992 (NI_MIN_HEIGHT - height) / 2 * 2;
11993 alignedh = NI_MIN_HEIGHT;
11994 } else
11995 {
11996 alignedh = ((height + 1) / 2) * 2;
11997 p_enc_params->cfg_enc_params.conf_win_bottom +=
11998 (alignedh - height) / 2 * 2;
11999 }
12000
12001 p_enc_params->source_height = alignedh;
12002 p_enc_params->cfg_enc_params.planar = planar;
12003
12004 return NI_RETCODE_SUCCESS;
12005}
12006
12007/*!*****************************************************************************
12008 * \brief Set the outgoing frame format for the uploader
12009 *
12010 * \param[in] p_upl_ctx pointer to uploader context
12011 * [in] width width
12012 * [in] height height
12013 * [in] pixel_format pixel format
12014 * [in] isP2P 0 = normal, 1 = P2P
12015 *
12016 * \return on success
12017 * NI_RETCODE_SUCCESS
12018 *
12019 * on failure
12020 * NI_RETCODE_INVALID_PARAM
12021*******************************************************************************/
12023 int width, int height,
12024 ni_pix_fmt_t pixel_format, int isP2P)
12025{
12026 if (p_upl_ctx == NULL)
12027 {
12028 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: null ptr\n", __func__);
12030 }
12031
12032 switch (pixel_format)
12033 {
12034 case NI_PIX_FMT_YUV420P:
12035 case NI_PIX_FMT_NV12:
12036 case NI_PIX_FMT_NV16:
12037 case NI_PIX_FMT_YUYV422:
12038 case NI_PIX_FMT_UYVY422:
12039 p_upl_ctx->src_bit_depth = 8;
12040 p_upl_ctx->bit_depth_factor = 1;
12041 break;
12043 case NI_PIX_FMT_P010LE:
12044 p_upl_ctx->src_bit_depth = 10;
12045 p_upl_ctx->bit_depth_factor = 2;
12046 break;
12047 case NI_PIX_FMT_RGBA:
12048 case NI_PIX_FMT_BGRA:
12049 case NI_PIX_FMT_ARGB:
12050 case NI_PIX_FMT_ABGR:
12051 case NI_PIX_FMT_BGR0:
12052 case NI_PIX_FMT_BGRP:
12053 p_upl_ctx->src_bit_depth = 8;
12054 p_upl_ctx->bit_depth_factor = 4;
12055 break;
12056 default:
12057 ni_log2(p_upl_ctx, NI_LOG_ERROR, "%s: Invalid pixfmt %d\n", __func__,
12058 pixel_format);
12060 }
12061
12063 p_upl_ctx->pixel_format = pixel_format;
12064 p_upl_ctx->active_video_width = width;
12065 p_upl_ctx->active_video_height = height;
12066 p_upl_ctx->isP2P = isP2P;
12067
12068 return NI_RETCODE_SUCCESS;
12069}
12070
12071/*!*****************************************************************************
12072 * \brief Read encoder stream header from the device
12073 *
12074 * \param[in] p_ctx Pointer to a caller allocated
12075 * ni_session_context_t struct from encoder
12076 * \param[in] p_data Pointer to a caller allocated ni_session_data_io_t
12077 * struct which contains a ni_packet_t data packet to
12078 * receive
12079 * \return On success
12080 * Total number of bytes read
12081 * On failure
12082 * NI_RETCODE_INVALID_PARAM
12083 * NI_RETCODE_ERROR_NVME_CMD_FAILED
12084 * NI_RETCODE_ERROR_INVALID_SESSION
12085*******************************************************************************/
12087 ni_session_data_io_t *p_data)
12088{
12089 int rx_size;
12090 int done = 0;
12091 int bytes_read = 0;
12092
12093 /* This function should be called once at the start of encoder read */
12094 if (p_ctx->pkt_num != 0)
12095 {
12096 ni_log2(p_ctx, NI_LOG_ERROR, "Error: stream header has already been read\n");
12098 }
12099
12100 while (!done)
12101 {
12102 rx_size = ni_device_session_read(p_ctx, p_data, NI_DEVICE_TYPE_ENCODER);
12103
12104 if (rx_size > (int)p_ctx->meta_size)
12105 {
12106 /* stream header has been read, return size */
12107 bytes_read += (rx_size - (int)p_ctx->meta_size);
12108
12109 p_ctx->pkt_num = 1;
12110 ni_log2(p_ctx, NI_LOG_DEBUG, "Got encoded stream header\n");
12111 done = 1;
12112 } else if (rx_size != 0)
12113 {
12114 ni_log2(p_ctx, NI_LOG_ERROR, "Error: received rx_size = %d\n", rx_size);
12115 bytes_read = -1;
12116 done = 1;
12117 } else
12118 {
12119 ni_log2(p_ctx, NI_LOG_DEBUG, "No data, keep reading..\n");
12120 continue;
12121 }
12122 }
12123
12124 return bytes_read;
12125}
12126
12127/*!*****************************************************************************
12128 * \brief Get the DMA buffer file descriptor from the P2P frame
12129 *
12130 * \param[in] p_frame pointer to a P2P frame
12131 *
12132 * \return On success
12133 * DMA buffer file descriptor
12134 * On failure
12135 * NI_RETCODE_INVALID_PARAM
12136*******************************************************************************/
12138{
12139 const niFrameSurface1_t *p_surface;
12140
12141 if (p_frame == NULL)
12142 {
12143 ni_log(NI_LOG_ERROR, "%s: NULL frame\n", __func__);
12145 }
12146
12147 p_surface = (niFrameSurface1_t *)p_frame->p_data[3];
12148
12149 if (p_surface == NULL)
12150 {
12151 ni_log(NI_LOG_ERROR, "%s: Invalid hw frame\n", __func__);
12153 }
12154
12155 return p_surface->dma_buf_fd;
12156}
12157
12158/*!*****************************************************************************
12159 * \brief Send sequence change information to device
12160 *
12161 * \param[in] p_ctx Pointer to a caller allocated
12162 * ni_session_context_t struct
12163 * \param[in] width input width
12164 * \param[in] height input height
12165 * \param[in] bit_depth_factor 1 for 8-bit YUV, 2 for 10-bit YUV
12166 * \param[in] device_type device type (must be encoder)
12167 * \return On success
12168 * NI_RETCODE_SUCCESS
12169 * On failure
12170 * NI_RETCODE_INVALID_PARAM
12171 * NI_RETCODE_ERROR_MEM_ALOC
12172 * NI_RETCODE_ERROR_NVME_CMD_FAILED
12173 * NI_RETCODE_ERROR_INVALID_SESSION
12174 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
12175 ******************************************************************************/
12177 int width, int height, int bit_depth_factor, ni_device_type_t device_type)
12178{
12179 ni_resolution_t resolution;
12181 ni_xcoder_params_t *p_param = NULL;
12182
12183 // requires API version >= 54
12185 "54") < 0)
12186 {
12187 ni_log2(p_ctx, NI_LOG_ERROR, "Error: %s function not supported on device with FW API version < 5.4\n", __func__);
12189 }
12190
12191 /* This function should be called only if sequence change is detected */
12193 {
12194 ni_log2(p_ctx, NI_LOG_ERROR, "Error: stream header has already been read\n");
12196 }
12197
12198 resolution.width = width;
12199 resolution.height = height;
12200 resolution.bit_depth_factor = bit_depth_factor;
12201 resolution.luma_linesize = 0;
12202 resolution.chroma_linesize = 0;
12203 if (p_ctx->p_session_config)
12204 {
12206 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
12207 p_enc = &p_param->cfg_enc_params;
12208 if (p_enc->spatial_layers > 1)
12209 {
12210 retval = NI_RETCODE_INVALID_PARAM;
12211 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Config sequence change not supported when spatialLayers > 1\n");
12212 return retval;
12213 }
12214 resolution.luma_linesize = p_param->luma_linesize;
12215 resolution.chroma_linesize = p_param->chroma_linesize;
12216 }
12217 else
12218 {
12220 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: invalid p_session_config\n");
12221 return retval;
12222 }
12223
12224 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: resolution change config - width %d height %d bit_depth_factor %d "
12225 "luma_linesize %d chroma_linesize %d\n", __func__,
12226 resolution.width, resolution.height, resolution.bit_depth_factor,
12227 resolution.luma_linesize, resolution.chroma_linesize);
12228
12229 switch (device_type)
12230 {
12232 {
12233 // config sequence change
12234 retval = ni_encoder_session_sequence_change(p_ctx, &resolution);
12235 break;
12236 }
12237 default:
12238 {
12239 retval = NI_RETCODE_INVALID_PARAM;
12240 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Config sequence change not supported for device type: %d", device_type);
12241 return retval;
12242 }
12243 }
12244 return retval;
12245}
12246
12248 ni_network_perf_metrics_t *p_metrics)
12249{
12250 return ni_ai_session_query_metrics(p_ctx, p_metrics);
12251}
12252
12253ni_retcode_t ni_query_fl_fw_versions(ni_device_handle_t device_handle,
12254 ni_device_info_t *p_dev_info)
12255{
12256 void *buffer;
12257 uint32_t size;
12258 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12259 ni_log_fl_fw_versions_t fl_fw_versions;
12260
12261 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_info))
12262 {
12263 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12264 __func__);
12266 }
12267
12269 "6h") < 0)
12270 {
12272 "ERROR: %s function not supported on device with FW API version < 6.h\n",
12273 __func__);
12275 }
12276
12277 buffer = NULL;
12279
12280 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12281 {
12282 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12284 }
12285
12286 memset(buffer, 0, size);
12287
12288 if (ni_nvme_send_read_cmd(device_handle,
12289 event_handle,
12290 buffer,
12291 size,
12293 {
12294 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12295 ni_aligned_free(buffer);
12297 }
12298
12299 memcpy(&fl_fw_versions, buffer, sizeof(ni_log_fl_fw_versions_t));
12300
12301 memcpy(p_dev_info->fl_ver_last_ran,
12302 &fl_fw_versions.last_ran_fl_version,
12304 memcpy(p_dev_info->fl_ver_nor_flash,
12305 &fl_fw_versions.nor_flash_fl_version,
12307 memcpy(p_dev_info->fw_rev_nor_flash,
12308 &fl_fw_versions.nor_flash_fw_revision,
12310
12311 ni_aligned_free(buffer);
12312 return NI_RETCODE_SUCCESS;
12313}
12314
12316 ni_load_query_t *p_load_query)
12317{
12318 void *buffer;
12319 uint32_t size;
12320
12321 ni_instance_mgr_general_status_t general_status;
12322
12323 if (!p_ctx)
12324 {
12325 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: p_ctx cannot be null\n");
12327 }
12328 if (!p_load_query)
12329 {
12330 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: p_load_query cannot be null\n");
12332 }
12333
12335 "6O") < 0)
12336 {
12337 ni_log2(p_ctx, NI_LOG_ERROR,
12338 "ERROR: %s function not supported on device with FW API version < 6.O\n",
12339 __func__);
12341 }
12342
12343 buffer = NULL;
12345
12346 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12347 {
12348 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12350 }
12351
12352 memset(buffer, 0, size);
12353
12355 p_ctx->event_handle,
12356 buffer,
12357 size,
12359 {
12360 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12361 ni_aligned_free(buffer);
12363 }
12364
12365 memcpy(&general_status, buffer, sizeof(ni_instance_mgr_general_status_t));
12366
12367 p_load_query->tp_fw_load = general_status.tp_fw_load;
12368 p_load_query->pcie_load = general_status.pcie_load;
12369 p_load_query->pcie_throughput = general_status.pcie_throughput;
12370 p_load_query->fw_load = general_status.fw_load;
12371 p_load_query->fw_share_mem_usage = general_status.fw_share_mem_usage;
12372
12373 ni_aligned_free(buffer);
12374 return NI_RETCODE_SUCCESS;
12375}
12376
12377ni_retcode_t ni_query_vf_ns_id(ni_device_handle_t device_handle,
12378 ni_device_vf_ns_id_t *p_dev_ns_vf,
12379 uint8_t fw_rev[])
12380{
12381 void *p_buffer = NULL;
12382 uint32_t size;
12383 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12384
12385 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_ns_vf))
12386 {
12387 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12388 __func__);
12390 }
12391
12393 "6m") < 0)
12394 {
12396 "ERROR: %s function not supported on device with FW API version < 6.m\n",
12397 __func__);
12399 }
12400
12402
12403 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12404 {
12405 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12407 }
12408
12409 memset(p_buffer, 0, size);
12410
12411 if (ni_nvme_send_read_cmd(device_handle,
12412 event_handle,
12413 p_buffer,
12414 size,
12415 QUERY_GET_NS_VF_R) < 0)
12416 {
12417 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12418 ni_aligned_free(p_buffer);
12420 }
12421
12422 ni_device_vf_ns_id_t *p_dev_ns_vf_data = (ni_device_vf_ns_id_t *)p_buffer;
12423 p_dev_ns_vf->vf_id = p_dev_ns_vf_data->vf_id;
12424 p_dev_ns_vf->ns_id = p_dev_ns_vf_data->ns_id;
12425 ni_log(NI_LOG_DEBUG, "%s(): NS/VF %u/%u\n", __func__, p_dev_ns_vf->ns_id, p_dev_ns_vf->vf_id);
12426 ni_aligned_free(p_buffer);
12427 return NI_RETCODE_SUCCESS;
12428}
12429
12430ni_retcode_t ni_query_temperature(ni_device_handle_t device_handle,
12431 ni_device_temp_t *p_dev_temp,
12432 uint8_t fw_rev[])
12433{
12434 void *p_buffer = NULL;
12435 uint32_t size;
12436 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12437
12438 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_temp))
12439 {
12440 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12441 __func__);
12443 }
12444
12446 "6rC") < 0)
12447 {
12449 "ERROR: %s function not supported on device with FW API version < 6rC\n",
12450 __func__);
12452 }
12453
12455
12456 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12457 {
12458 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12460 }
12461
12462 memset(p_buffer, 0, size);
12463
12464 if (ni_nvme_send_read_cmd(device_handle,
12465 event_handle,
12466 p_buffer,
12467 size,
12469 {
12470 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12471 ni_aligned_free(p_buffer);
12473 }
12474
12475 ni_device_temp_t *p_dev_temp_data = (ni_device_temp_t *)p_buffer;
12476 p_dev_temp->composite_temp = p_dev_temp_data->composite_temp;
12477 p_dev_temp->on_board_temp = p_dev_temp_data->on_board_temp;
12478 p_dev_temp->on_die_temp = p_dev_temp_data->on_die_temp;
12479 ni_log(NI_LOG_DEBUG, "%s(): current composite temperature %d on board temperature %d on die temperature %d\n",
12480 __func__, p_dev_temp->composite_temp, p_dev_temp->on_board_temp, p_dev_temp->on_die_temp);
12481 ni_aligned_free(p_buffer);
12482 return NI_RETCODE_SUCCESS;
12483}
12484
12485ni_retcode_t ni_query_extra_info(ni_device_handle_t device_handle,
12486 ni_device_extra_info_t *p_dev_extra_info,
12487 uint8_t fw_rev[])
12488{
12489 void *p_buffer = NULL;
12490 uint32_t size;
12491 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12492
12493 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_extra_info))
12494 {
12495 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12496 __func__);
12498 }
12499
12501 "6rC") < 0)
12502 {
12504 "ERROR: %s function not supported on device with FW API version < 6rC\n",
12505 __func__);
12507 }
12508
12510
12511 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), size))
12512 {
12513 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12515 }
12516
12517 memset(p_buffer, 0, size);
12518
12519 if (ni_nvme_send_read_cmd(device_handle,
12520 event_handle,
12521 p_buffer,
12522 size,
12524 {
12525 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12526 ni_aligned_free(p_buffer);
12528 }
12529
12530 ni_device_extra_info_t *p_dev_extra_info_data = (ni_device_extra_info_t *)p_buffer;
12531 p_dev_extra_info->composite_temp = p_dev_extra_info_data->composite_temp;
12532 p_dev_extra_info->on_board_temp = p_dev_extra_info_data->on_board_temp;
12533 p_dev_extra_info->on_die_temp = p_dev_extra_info_data->on_die_temp;
12534 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sN") >= 0)
12535 {
12536 p_dev_extra_info->fw_flavour = p_dev_extra_info_data->fw_flavour;
12537 }
12538 else
12539 {
12540 p_dev_extra_info->fw_flavour = (uint8_t)'-';
12541 }
12542 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rC") >= 0 &&
12543 ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rR") < 0)
12544 {
12545 p_dev_extra_info->power_consumption = NI_INVALID_POWER;
12546 }
12547 else
12548 {
12549 p_dev_extra_info->power_consumption = p_dev_extra_info_data->power_consumption;
12550 }
12551 //QUADPV-1210-Remove ADC current measurement decoding from FW
12552 if (ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6s4") >= 0 &&
12553 ni_cmp_fw_api_ver((char*) &fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sR") <= 0)
12554 {
12555 p_dev_extra_info->current_consumption = p_dev_extra_info_data->current_consumption;
12556 ni_device_capability_t device_capability = {0};
12557 if (ni_device_capability_query2(device_handle, &device_capability, false) != NI_RETCODE_SUCCESS)
12558 {
12559 ni_log(NI_LOG_ERROR, "ERROR: unable to query capability\n");
12561 }
12562 p_dev_extra_info->power_consumption = ni_decode_power_measurement(p_dev_extra_info->current_consumption, device_capability.serial_number);
12563 }
12564
12565 ni_log(NI_LOG_DEBUG, "%s(): current composite temperature %d on board temperature %d "
12566 "on die temperature %d power consumption %d current consumption %d\n",
12567 __func__, p_dev_extra_info->composite_temp, p_dev_extra_info->on_board_temp,
12568 p_dev_extra_info->on_die_temp, p_dev_extra_info->power_consumption, p_dev_extra_info->current_consumption);
12569 ni_aligned_free(p_buffer);
12570 return NI_RETCODE_SUCCESS;
12571}
12572
12573ni_retcode_t ni_query_qos_info(ni_device_handle_t device_handle,
12574 ni_qos_header_info_log_page_t *p_dev_qos_header,
12575 uint8_t fw_rev[])
12576{
12577 void *buffer;
12578 uint32_t size;
12579 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12580
12581 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_qos_header) || (!fw_rev))
12582 {
12583 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12584 __func__);
12586 }
12587
12589 "6t0") < 0)
12590 {
12592 "INFO: %s function not supported on device with FW API version < 6t0\n",
12593 __func__);
12595 }
12596
12597 buffer = NULL;
12598 size = ((sizeof(ni_qos_header_info_log_page_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) /
12600
12601 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12602 {
12603 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12605 }
12606
12607 memset(buffer, 0, size);
12608
12609 if (ni_nvme_send_read_cmd(device_handle,
12610 event_handle,
12611 buffer,
12612 size,
12614 {
12615 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12616 ni_aligned_free(buffer);
12618 }
12619
12621 p_dev_qos_header->ui16QosState = (uint8_t)(qos_header_info->ui16QosState & 0xFF);
12622 p_dev_qos_header->ui16ActiveNamespaces = qos_header_info->ui16ActiveNamespaces;
12623 p_dev_qos_header->fTotalAllowance = qos_header_info->fTotalAllowance;
12624
12625 ni_aligned_free(buffer);
12626 return NI_RETCODE_SUCCESS;
12627}
12628
12629/*!*****************************************************************************
12630 * \brief Query QoS information for a specific namespace
12631 *
12632 * \param[in] device_handle Device handle for the target namespace
12633 * \param[out] p_qos_ns_info Pointer to namespace QoS info structure
12634 * \param[in] fw_rev[] Firmware version array
12635 *
12636 * \return On success
12637 * NI_RETCODE_SUCCESS
12638 * On failure
12639 * NI_RETCODE_INVALID_PARAM
12640 * NI_RETCODE_ERROR_NVME_CMD_FAILED
12641 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
12642 * NI_RETCODE_ERROR_MEM_ALOC
12643 ******************************************************************************/
12644ni_retcode_t ni_query_qos_namespace_info(ni_device_handle_t device_handle,
12646 uint8_t fw_rev[])
12647{
12648 void *buffer;
12649 uint32_t size;
12650 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
12651
12652 if ((NI_INVALID_DEVICE_HANDLE == device_handle) || (!p_dev_qos_ns) || (!fw_rev))
12653 {
12654 ni_log(NI_LOG_ERROR, "ERROR: %s(): passed parameters are null, return\n",
12655 __func__);
12657 }
12658
12660 "6t0") < 0)
12661 {
12663 "INFO: %s function not supported on device with FW API version < 6t0\n",
12664 __func__);
12666 }
12667
12668 buffer = NULL;
12671
12672 if (ni_posix_memalign((void **)&buffer, sysconf(_SC_PAGESIZE), size))
12673 {
12674 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n", NI_ERRNO, __func__);
12676 }
12677
12678 memset(buffer, 0, size);
12679
12680 if (ni_nvme_send_read_cmd(device_handle,
12681 event_handle,
12682 buffer,
12683 size,
12684 QUERY_GET_QOS_NS_INFO_R) < 0) // NSID comes from device handle
12685 {
12686 ni_log(NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
12687 ni_aligned_free(buffer);
12689 }
12690
12692
12693 p_dev_qos_ns->ui8VirtualFunction = qos_ns_info->ui8VirtualFunction;
12694 p_dev_qos_ns->ui8NamespaceId = qos_ns_info->ui8NamespaceId;
12695 p_dev_qos_ns->fAllowance = qos_ns_info->fAllowance;
12696 p_dev_qos_ns->ui32BaseSliceTimeUs = qos_ns_info->ui32BaseSliceTimeUs;
12697 p_dev_qos_ns->ui32OPmaxUs = qos_ns_info->ui32OPmaxUs;
12698
12699 ni_log(NI_LOG_DEBUG, "%s(): NS %u VF %u Allowance %.2f%% SliceTime %u OPmax %u\n",
12700 __func__,
12701 p_dev_qos_ns->ui8NamespaceId,
12702 p_dev_qos_ns->ui8VirtualFunction,
12703 p_dev_qos_ns->fAllowance,
12704 p_dev_qos_ns->ui32BaseSliceTimeUs,
12705 p_dev_qos_ns->ui32OPmaxUs);
12706
12707 ni_aligned_free(buffer);
12708 return NI_RETCODE_SUCCESS;
12709}
12710
12711/*!*****************************************************************************
12712 * \brief Allocate log buffer if needed and retrieve firmware logs from device
12713 *
12714 * \param[in] p_ctx Pointer to a caller allocated
12715 * ni_session_context_t struct
12716 * \param[in] p_log_buffer Reference to pointer to a log buffer
12717 * If log buffer pointer is NULL, this function will allocate log buffer
12718 * NOTE caller is responsible for freeing log buffer after calling this function
12719 * \param[in] gen_log_file Indicating whether it is required to generate log files
12720 *
12721 *
12722 * \return on success
12723 * NI_RETCODE_SUCCESS
12724 *
12725 * on failure
12726 * NI_RETCODE_ERROR_MEM_ALOC
12727 * NI_RETCODE_INVALID_PARAM
12728*******************************************************************************/
12729ni_retcode_t ni_device_alloc_and_get_firmware_logs(ni_session_context_t *p_ctx, void** p_log_buffer, bool gen_log_file)
12730{
12732 bool is_ext_buf = true;
12733 if (*p_log_buffer == NULL)
12734 {
12735 if (ni_posix_memalign(p_log_buffer, sysconf(_SC_PAGESIZE), TOTAL_CPU_LOG_BUFFER_SIZE))
12736 {
12737 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate log buffer\n",
12738 NI_ERRNO, __func__);
12740 }
12741 is_ext_buf = false;
12742 }
12743
12744 if(*p_log_buffer != NULL){
12745 memset(*p_log_buffer, 0, TOTAL_CPU_LOG_BUFFER_SIZE);
12746 retval = ni_dump_log_all_cores(p_ctx, *p_log_buffer, gen_log_file); // dump FW logs
12747 if(!is_ext_buf)
12748 ni_aligned_free(*p_log_buffer);
12749 }else{
12751 }
12752
12753 return retval;
12754}
12755
12756/*!*****************************************************************************
12757 * \brief Read log artifacts from the device and save to disk.
12758 *
12759 * \param[in] p_ctx Pointer to an open session context
12760 * \param[in] gen_artifacts_file Write artifacts_slot_X_domain.tar.gz to disk
12761 *
12762 * \return on success
12763 * NI_RETCODE_SUCCESS on success, error code otherwise
12764 * on failure
12765 * NI_RETCODE_INVALID_PARAM
12766 *
12767*******************************************************************************/
12769 bool gen_artifacts_file)
12770{
12771 if (!p_ctx)
12772 {
12773 ni_log(NI_LOG_ERROR, "ERROR: %s() p_ctx is NULL\n", __func__);
12775 }
12776
12777 /* Artifacts supported from fw version >= ("6tA") - version gating */
12778 if (p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX] != '\0' &&
12781 "6tA") < 0)
12782 {
12784 "%s: firmware %.8s does not support artifacts (< 6tA), skipping\n",
12785 __func__, (char *)p_ctx->fw_rev);
12786 return NI_RETCODE_SUCCESS;
12787 }
12788
12789 return ni_dump_log_artifacts(p_ctx, gen_artifacts_file);
12790}
12791
12792/*!*****************************************************************************
12793 * \brief Set up hard coded demo ROI map
12794 *
12795 * \param[in] p_enc_ctx Pointer to a caller allocated
12796 *
12797 * \return on success
12798 * NI_RETCODE_SUCCESS
12799 *
12800 * on failure
12801 * NI_RETCODE_ERROR_MEM_ALOC
12802*******************************************************************************/
12804{
12805 ni_xcoder_params_t *p_param =
12806 (ni_xcoder_params_t *)(p_enc_ctx->p_session_config);
12807 int sumQp = 0;
12808 uint32_t ctu, i, j;
12809 // mode 1: Set QP for center 1/3 of picture to highest - lowest quality
12810 // the rest to lowest - highest quality;
12811 // mode non-1: reverse of mode 1
12812 int importanceLevelCentre = p_param->roi_demo_mode == 1 ? 40 : 10;
12813 int importanceLevelRest = p_param->roi_demo_mode == 1 ? 10 : 40;
12814 int linesize_aligned = p_param->source_width;
12815 int height_aligned = p_param->source_height;
12816 if (QUADRA)
12817 {
12818 uint32_t block_size, max_cu_size, customMapSize;
12819 uint32_t mbWidth;
12820 uint32_t mbHeight;
12821 uint32_t numMbs;
12822 uint32_t roiMapBlockUnitSize;
12823 uint32_t entryPerMb;
12824
12825 max_cu_size = p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264 ? 16: 64;
12826 // AV1 non-8x8-aligned resolution is implicitly cropped due to Quadra HW limitation
12827 if (NI_CODEC_FORMAT_AV1 == p_enc_ctx->codec_format)
12828 {
12829 linesize_aligned = (linesize_aligned / 8) * 8;
12830 height_aligned = (height_aligned / 8) * 8;
12831 }
12832
12833 // (ROI map version >= 1) each QP info takes 8-bit, represent 8 x 8
12834 // pixel block
12835 block_size =
12836 ((linesize_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) *
12837 ((height_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12838 (8 * 8);
12839
12840 // need to align to 64 bytes
12841 customMapSize = ((block_size + 63) & (~63));
12842 if (!p_enc_ctx->roi_map)
12843 {
12844 p_enc_ctx->roi_map =
12845 (ni_enc_quad_roi_custom_map *)calloc(1, customMapSize);
12846 }
12847 if (!p_enc_ctx->roi_map)
12848 {
12850 }
12851
12852 // for H.264, select ROI Map Block Unit Size: 16x16
12853 // for H.265, select ROI Map Block Unit Size: 64x64
12854 roiMapBlockUnitSize = p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264 ? 16 : 64;
12855
12856 mbWidth =
12857 ((linesize_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12858 roiMapBlockUnitSize;
12859 mbHeight =
12860 ((height_aligned + max_cu_size - 1) & (~(max_cu_size - 1))) /
12861 roiMapBlockUnitSize;
12862 numMbs = mbWidth * mbHeight;
12863
12864 // copy roi MBs QPs into custom map
12865 // number of qp info (8x8) per mb or ctb
12866 entryPerMb = (roiMapBlockUnitSize / 8) * (roiMapBlockUnitSize / 8);
12867
12868 for (i = 0; i < numMbs; i++)
12869 {
12870 bool bIsCenter = (i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3);
12871 for (j = 0; j < entryPerMb; j++)
12872 {
12873 /*
12874 g_quad_roi_map[i*4+j].field.skip_flag = 0; // don't force
12875 skip mode g_quad_roi_map[i*4+j].field.roiAbsQp_flag = 1; //
12876 absolute QP g_quad_roi_map[i*4+j].field.qp_info = bIsCenter
12877 ? importanceLevelCentre : importanceLevelRest;
12878 */
12879 p_enc_ctx->roi_map[i * entryPerMb + j].field.ipcm_flag =
12880 0; // don't force skip mode
12881 p_enc_ctx->roi_map[i * entryPerMb + j]
12882 .field.roiAbsQp_flag = 1; // absolute QP
12883 p_enc_ctx->roi_map[i * entryPerMb + j].field.qp_info =
12884 bIsCenter ? importanceLevelCentre : importanceLevelRest;
12885 }
12886 sumQp += p_enc_ctx->roi_map[(ptrdiff_t)i * entryPerMb].field.qp_info;
12887 }
12888 p_enc_ctx->roi_len = customMapSize;
12889 p_enc_ctx->roi_avg_qp =
12890 (numMbs > 0) ? (sumQp + (numMbs >> 1)) / numMbs : 0; // round off
12891 }
12892 else if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264)
12893 {
12894 // roi for H.264 is specified for 16x16 pixel macroblocks - 1 MB
12895 // is stored in each custom map entry
12896
12897 // number of MBs in each row
12898 uint32_t mbWidth = (linesize_aligned + 16 - 1) >> 4;
12899 // number of MBs in each column
12900 uint32_t mbHeight = (height_aligned + 16 - 1) >> 4;
12901 uint32_t numMbs = mbWidth * mbHeight;
12902 uint32_t customMapSize =
12903 sizeof(ni_enc_avc_roi_custom_map_t) * numMbs;
12904 p_enc_ctx->avc_roi_map =
12905 (ni_enc_avc_roi_custom_map_t *)calloc(1, customMapSize);
12906 if (!p_enc_ctx->avc_roi_map)
12907 {
12909 }
12910
12911 // copy roi MBs QPs into custom map
12912 for (i = 0; i < numMbs; i++)
12913 {
12914 if ((i % mbWidth > mbWidth / 3) && (i % mbWidth < mbWidth * 2 / 3))
12915 {
12916 p_enc_ctx->avc_roi_map[i].field.mb_qp = importanceLevelCentre;
12917 }
12918 else
12919 {
12920 p_enc_ctx->avc_roi_map[i].field.mb_qp = importanceLevelRest;
12921 }
12922 sumQp += p_enc_ctx->avc_roi_map[i].field.mb_qp;
12923 }
12924 p_enc_ctx->roi_len = customMapSize;
12925 p_enc_ctx->roi_avg_qp =
12926 (numMbs > 0) ? (sumQp + (numMbs >> 1)) / numMbs : 0; // round off
12927 }
12928 else if (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265)
12929 {
12930 // roi for H.265 is specified for 32x32 pixel subCTU blocks - 4
12931 // subCTU QPs are stored in each custom CTU map entry
12932
12933 // number of CTUs in each row
12934 uint32_t ctuWidth = (linesize_aligned + 64 - 1) >> 6;
12935 // number of CTUs in each column
12936 uint32_t ctuHeight = (height_aligned + 64 - 1) >> 6;
12937 // number of sub CTUs in each row
12938 uint32_t subCtuWidth = ctuWidth * 2;
12939 // number of CTUs in each column
12940 uint32_t subCtuHeight = ctuHeight * 2;
12941 uint32_t numSubCtus = subCtuWidth * subCtuHeight;
12942
12943 p_enc_ctx->hevc_sub_ctu_roi_buf = (uint8_t *)malloc(numSubCtus);
12944 if (!p_enc_ctx->hevc_sub_ctu_roi_buf)
12945 {
12947 }
12948 for (i = 0; i < numSubCtus; i++)
12949 {
12950 if ((i % subCtuWidth > subCtuWidth / 3) &&
12951 (i % subCtuWidth < subCtuWidth * 2 / 3))
12952 {
12953 p_enc_ctx->hevc_sub_ctu_roi_buf[i] = importanceLevelCentre;
12954 }
12955 else
12956 {
12957 p_enc_ctx->hevc_sub_ctu_roi_buf[i] = importanceLevelRest;
12958 }
12959 }
12960 p_enc_ctx->hevc_roi_map = (ni_enc_hevc_roi_custom_map_t *)calloc(
12961 1, sizeof(ni_enc_hevc_roi_custom_map_t) * ctuWidth * ctuHeight);
12962 if (!p_enc_ctx->hevc_roi_map)
12963 {
12965 }
12966
12967 for (i = 0; i < ctuHeight; i++)
12968 {
12969 uint8_t *ptr = &p_enc_ctx->hevc_sub_ctu_roi_buf[(size_t)subCtuWidth * i * 2];
12970 for (j = 0; j < ctuWidth; j++, ptr += 2)
12971 {
12972 ctu = (i * ctuWidth + j);
12973 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_0 = *ptr;
12974 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_1 = *(ptr + 1);
12975 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_2 =
12976 *(ptr + subCtuWidth);
12977 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_3 =
12978 *(ptr + subCtuWidth + 1);
12979 sumQp += (p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_0 +
12980 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_1 +
12981 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_2 +
12982 p_enc_ctx->hevc_roi_map[ctu].field.sub_ctu_qp_3);
12983 }
12984 }
12985 p_enc_ctx->roi_len =
12986 (size_t)ctuWidth * ctuHeight * sizeof(ni_enc_hevc_roi_custom_map_t);
12987 p_enc_ctx->roi_avg_qp =
12988 (numSubCtus > 0) ? (sumQp + (numSubCtus >> 1)) / numSubCtus : 0; // round off
12989 }
12990 return NI_RETCODE_SUCCESS;
12991}
12992
12994{
12995 // for encoder reconfiguration testing
12996 // reset encoder change data buffer for reconf parameters
12997 ni_retcode_t retval = 0;
12998 ni_xcoder_params_t *p_param =
13000 ni_aux_data_t *aux_data = NULL;
13003 {
13004 memset(p_enc_ctx->enc_change_params, 0, sizeof(ni_encoder_change_params_t));
13005 }
13006
13007 switch (p_param->reconf_demo_mode) {
13009 if (p_enc_ctx->frame_num ==
13010 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
13011 {
13012 aux_data = ni_frame_new_aux_data(
13013 p_frame, NI_FRAME_AUX_DATA_BITRATE, sizeof(int32_t));
13014 if (!aux_data)
13015 {
13017 }
13018 *((int32_t *)aux_data->data) =
13019 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13020
13021 p_enc_ctx->reconfigCount++;
13022 if (p_param->cfg_enc_params.hrdEnable)
13023 {
13024 p_frame->force_key_frame = 1;
13025 p_frame->ni_pict_type = PIC_TYPE_IDR;
13026 }
13027 }
13028 break;
13029 // reconfig intraperiod param
13031 if (p_enc_ctx->frame_num ==
13032 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
13033 {
13034 aux_data = ni_frame_new_aux_data(
13035 p_frame, NI_FRAME_AUX_DATA_INTRAPRD, sizeof(int32_t));
13036 if (!aux_data)
13037 {
13039 }
13040 int32_t intraprd = *((int32_t *)aux_data->data) =
13041 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13042 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13043 "xcoder_send_frame: frame #%lu reconf "
13044 "intraPeriod %d\n",
13045 p_enc_ctx->frame_num,
13046 intraprd);
13047 p_enc_ctx->reconfigCount++;
13048 }
13049 break;
13050 // reconfig VUI parameters
13052 if (p_enc_ctx->frame_num ==
13053 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
13054 {
13055 aux_data = ni_frame_new_aux_data(p_frame,
13057 sizeof(ni_vui_hrd_t));
13058 if (!aux_data)
13059 {
13061 }
13062 ni_vui_hrd_t *vui = (ni_vui_hrd_t *)aux_data->data;
13063 vui->colorDescPresent =
13064 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13065 vui->colorPrimaries =
13066 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13067 vui->colorTrc =
13068 p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13069 vui->colorSpace =
13070 p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13071 vui->aspectRatioWidth =
13072 p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13073 vui->aspectRatioHeight =
13074 p_param->reconf_hash[p_enc_ctx->reconfigCount][6];
13075 vui->videoFullRange =
13076 p_param->reconf_hash[p_enc_ctx->reconfigCount][7];
13077 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13078 "xcoder_send_frame: frame #%lu reconf "
13079 "vui colorDescPresent %d colorPrimaries %d "
13080 "colorTrc %d colorSpace %d aspectRatioWidth %d "
13081 "aspectRatioHeight %d videoFullRange %d\n",
13082 p_enc_ctx->frame_num, vui->colorDescPresent,
13083 vui->colorPrimaries, vui->colorTrc,
13084 vui->colorSpace, vui->aspectRatioWidth,
13086
13087 p_enc_ctx->reconfigCount++;
13088 }
13089 break;
13090 // long term ref
13092 // the reconf file data line format for this is:
13093 // <frame-number>:useCurSrcAsLongtermPic,useLongtermRef where
13094 // values will stay the same on every frame until changed.
13095 if (p_enc_ctx->frame_num ==
13096 p_param->reconf_hash[p_enc_ctx->reconfigCount][0])
13097 {
13098 ni_long_term_ref_t *p_ltr;
13099 aux_data = ni_frame_new_aux_data(
13101 sizeof(ni_long_term_ref_t));
13102 if (!aux_data)
13103 {
13105 }
13106 p_ltr = (ni_long_term_ref_t *)aux_data->data;
13108 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13109 p_ltr->use_long_term_ref =
13110 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13111 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13112 "xcoder_send_frame: frame #%lu metadata "
13113 "use_cur_src_as_long_term_pic %d use_long_term_ref "
13114 "%d\n",
13115 p_enc_ctx->frame_num,
13117 p_ltr->use_long_term_ref);
13118 p_enc_ctx->reconfigCount++;
13119 }
13120 break;
13121 // reconfig min / max QP
13124 if (p_enc_ctx->frame_num ==
13125 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13126 aux_data = ni_frame_new_aux_data(
13128 if (!aux_data) {
13130 }
13131
13132 ni_rc_min_max_qp *qp_info = (ni_rc_min_max_qp *)aux_data->data;
13133 qp_info->minQpI = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13134 qp_info->maxQpI = p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13135 qp_info->maxDeltaQp = p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13136 qp_info->minQpPB = p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13137 qp_info->maxQpPB = p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13138
13139 p_enc_ctx->reconfigCount++;
13140 }
13141 break;
13142#ifdef QUADRA
13143 // reconfig LTR interval
13145 if (p_enc_ctx->frame_num ==
13146 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13147 aux_data = ni_frame_new_aux_data(p_frame,
13149 sizeof(int32_t));
13150 if (!aux_data) {
13152 }
13153 *((int32_t *)aux_data->data) =
13154 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13155 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13156 "xcoder_send_frame: frame #%lu reconf "
13157 "ltrInterval %d\n",
13158 p_enc_ctx->frame_num,
13159 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13160
13161 p_enc_ctx->reconfigCount++;
13162 }
13163 break;
13164 // invalidate reference frames
13166 if (p_enc_ctx->frame_num ==
13167 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13168 aux_data = ni_frame_new_aux_data(
13170 sizeof(int32_t));
13171 if (!aux_data) {
13173 }
13174 *((int32_t *)aux_data->data) =
13175 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13176 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13177 "xcoder_send_frame: frame #%lu reconf "
13178 "invalidFrameNum %d\n",
13179 p_enc_ctx->frame_num,
13180 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13181
13182 p_enc_ctx->reconfigCount++;
13183 }
13184 break;
13185 // reconfig framerate
13187 if (p_enc_ctx->frame_num ==
13188 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13189 ni_framerate_t *framerate;
13190
13191 aux_data = ni_frame_new_aux_data(p_frame,
13193 sizeof(ni_framerate_t));
13194 if (!aux_data) {
13196 }
13197
13198 framerate = (ni_framerate_t *)aux_data->data;
13199 framerate->framerate_num =
13200 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13201 framerate->framerate_denom =
13202 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13203 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13204 "xcoder_send_frame: frame #%lu reconf "
13205 "framerate (%d/%d)\n",
13206 p_enc_ctx->frame_num, framerate->framerate_num,
13207 framerate->framerate_denom);
13208 p_enc_ctx->reconfigCount++;
13209 }
13210 break;
13212 if (p_enc_ctx->frame_num ==
13213 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13214 aux_data = ni_frame_new_aux_data(
13215 p_frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
13216 if (!aux_data) {
13218 }
13219 *((int32_t *)aux_data->data) =
13220 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13221 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13222 "xcoder_send_frame: frame #%lu reconf "
13223 "maxFrameSize %d\n",
13224 p_enc_ctx->frame_num,
13225 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13226
13227 p_enc_ctx->reconfigCount++;
13228 }
13229 break;
13231 if (p_enc_ctx->frame_num ==
13232 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13233 aux_data = ni_frame_new_aux_data(
13234 p_frame, NI_FRAME_AUX_DATA_CRF, sizeof(int32_t));
13235 if (!aux_data) {
13237 }
13238 *((int32_t *)aux_data->data) =
13239 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13240 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13241 "xcoder_send_frame: frame #%lu reconf "
13242 "crf %d\n",
13243 p_enc_ctx->frame_num,
13244 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13245
13246 p_enc_ctx->reconfigCount++;
13247 }
13248 break;
13250 if (p_enc_ctx->frame_num ==
13251 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13252 aux_data = ni_frame_new_aux_data(
13253 p_frame, NI_FRAME_AUX_DATA_CRF_FLOAT, sizeof(float));
13254 if (!aux_data) {
13256 }
13257 float crf = (float)(p_param->reconf_hash[p_enc_ctx->reconfigCount][1] +
13258 (float)p_param->reconf_hash[p_enc_ctx->reconfigCount][2] / 100.0);
13259 *((float *)aux_data->data) = crf;
13260 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13261 "xcoder_send_frame: frame #%lu reconf "
13262 "crf %f\n",
13263 p_enc_ctx->frame_num, crf);
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 vbvBufferSize = p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13272 int32_t vbvMaxRate = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13273 if ((vbvBufferSize < 10 && vbvBufferSize != 0) || vbvBufferSize > 3000)
13274 {
13275 ni_log2(p_enc_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid vbvBufferSize value %d\n",
13276 __func__, vbvBufferSize);
13278 }
13279 if (p_param->bitrate > 0 && vbvMaxRate > 0 && vbvMaxRate < p_param->bitrate) {
13280 ni_log2(p_enc_ctx, NI_LOG_ERROR, "vbvMaxRate %u cannot be smaller than bitrate %d\n",
13281 vbvMaxRate, p_param->bitrate);
13283 }
13284 if (vbvBufferSize == 0 && vbvMaxRate > 0) {
13285 ni_log2(p_enc_ctx, NI_LOG_INFO, "vbvMaxRate %d does not take effect when "
13286 "vbvBufferSize is 0, force vbvMaxRate to 0\n",
13287 vbvMaxRate);
13288 vbvMaxRate = 0;
13289 }
13290
13291 aux_data = ni_frame_new_aux_data(
13292 p_frame, NI_FRAME_AUX_DATA_VBV_MAX_RATE, sizeof(int32_t));
13293 if (!aux_data) {
13295 }
13296 *((int32_t *)aux_data->data) = vbvMaxRate;
13297 aux_data = ni_frame_new_aux_data(
13298 p_frame, NI_FRAME_AUX_DATA_VBV_BUFFER_SIZE, sizeof(int32_t));
13299 if (!aux_data) {
13301 }
13302 *((int32_t *)aux_data->data) = vbvBufferSize;
13303 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13304 "xcoder_send_frame: frame #%lu reconfig vbvMaxRate %d vbvBufferSize "
13305 "%d by frame aux data\n",
13306 p_enc_ctx->frame_num, vbvMaxRate, vbvBufferSize);
13307
13308 p_enc_ctx->reconfigCount++;
13309 }
13310 break;
13312 if (p_enc_ctx->frame_num ==
13313 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13314 int maxFrameSizeRatio = p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13315 if (maxFrameSizeRatio < 1) {
13316 ni_log2(p_enc_ctx, NI_LOG_ERROR, "maxFrameSizeRatio %d cannot < 1\n",
13317 maxFrameSizeRatio);
13319 }
13320 aux_data = ni_frame_new_aux_data(
13321 p_frame, NI_FRAME_AUX_DATA_MAX_FRAME_SIZE, sizeof(int32_t));
13322 if (!aux_data) {
13324 }
13325
13326 int32_t bitrate, framerate_num, framerate_denom;
13327 uint32_t min_maxFrameSize, maxFrameSize;
13328 bitrate = (p_enc_ctx->target_bitrate > 0) ? p_enc_ctx->target_bitrate : p_param->bitrate;
13329
13330 if ((p_enc_ctx->framerate.framerate_num > 0) && (p_enc_ctx->framerate.framerate_denom > 0))
13331 {
13332 framerate_num = p_enc_ctx->framerate.framerate_num;
13333 framerate_denom = p_enc_ctx->framerate.framerate_denom;
13334 }
13335 else
13336 {
13337 framerate_num = (int32_t) p_param->fps_number;
13338 framerate_denom = (int32_t) p_param->fps_denominator;
13339 }
13340
13341 min_maxFrameSize = ((uint32_t)bitrate / framerate_num * framerate_denom) / 8;
13342 maxFrameSize = min_maxFrameSize * maxFrameSizeRatio > NI_MAX_FRAME_SIZE ?
13343 NI_MAX_FRAME_SIZE : min_maxFrameSize * maxFrameSizeRatio;
13344 *((int32_t *)aux_data->data) = (int32_t)maxFrameSize;
13345 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13346 "xcoder_send_frame: frame #%lu reconf "
13347 "maxFrameSizeRatio %d maxFrameSize %d\n",
13348 p_enc_ctx->frame_num, maxFrameSizeRatio, maxFrameSize);
13349
13350 p_enc_ctx->reconfigCount++;
13351 }
13352 break;
13354 if (p_enc_ctx->frame_num ==
13355 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13356 aux_data = ni_frame_new_aux_data(
13357 p_frame, NI_FRAME_AUX_DATA_SLICE_ARG, sizeof(int16_t));
13358 if (!aux_data) {
13360 }
13361 *((int16_t *)aux_data->data) =
13362 (int16_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13363 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13364 "xcoder_send_frame: frame #%lu reconf "
13365 "sliceArg %d\n",
13366 p_enc_ctx->frame_num,
13367 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13368
13369 p_enc_ctx->reconfigCount++;
13370 }
13371 break;
13372 // set LTR and/or invalidate reference frames on the same frame.
13373 // reconf file line format:
13374 // <frame-number>:useCurSrcAsLongtermPic,invalidFrameNum
13375 // LTR aux data is attached when useCurSrcAsLongtermPic is non-zero.
13376 // useLongtermRef is not sent; firmware ignores that flag.
13377 // invalidFrameNum -1 skips reference invalidation. A value >= 0
13378 // invalidates references from that frame number. Either action may be
13379 // omitted.
13381 if (p_enc_ctx->frame_num ==
13382 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13383 uint8_t use_cur_src_as_long_term_pic =
13384 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13385 int32_t invalid_frame_num =
13386 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13387
13388 if (use_cur_src_as_long_term_pic > 0) {
13389 ni_long_term_ref_t *p_ltr;
13390 aux_data = ni_frame_new_aux_data(
13392 sizeof(ni_long_term_ref_t));
13393 if (!aux_data) {
13395 }
13396 p_ltr = (ni_long_term_ref_t *)aux_data->data;
13398 use_cur_src_as_long_term_pic;
13399 p_ltr->use_long_term_ref = 0;
13400 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13401 "xcoder_send_frame: frame #%lu metadata "
13402 "use_cur_src_as_long_term_pic %d\n",
13403 p_enc_ctx->frame_num,
13405 }
13406
13407 if (invalid_frame_num != -1) {
13408 aux_data = ni_frame_new_aux_data(
13410 sizeof(int32_t));
13411 if (!aux_data) {
13413 }
13414 *((int32_t *)aux_data->data) = invalid_frame_num;
13415 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13416 "xcoder_send_frame: frame #%lu reconf "
13417 "invalidFrameNum %d\n",
13418 p_enc_ctx->frame_num, invalid_frame_num);
13419 }
13420
13421 p_enc_ctx->reconfigCount++;
13422 }
13423 break;
13424 // force IDR frame through API test code
13426 if (p_enc_ctx->frame_num ==
13427 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13428 ni_force_idr_frame_type(p_enc_ctx);
13429 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13430 "xcoder_send_frame: frame #%lu force IDR frame\n",
13431 p_enc_ctx->frame_num);
13432
13433 p_enc_ctx->reconfigCount++;
13434 }
13435 break;
13436 // reconfig bit rate through API test code
13438 if (p_enc_ctx->frame_num ==
13439 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13440 retval = ni_reconfig_bitrate(
13441 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13442 if (retval){
13443 return retval;
13444 }
13445 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13446 "xcoder_send_frame: frame #%lu API reconfig BR %d\n",
13447 p_enc_ctx->frame_num,
13448 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13449
13450 p_enc_ctx->reconfigCount++;
13451 }
13452 break;
13454 if (p_enc_ctx->frame_num ==
13455 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13456 int32_t intraprd =
13457 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13458 retval = ni_reconfig_intraprd(p_enc_ctx, intraprd);
13459 if (retval){
13460 return retval;
13461 }
13463 "xcoder_send_frame: frame #%lu API reconfig intraPeriod %d\n",
13464 p_enc_ctx->frame_num,
13465 intraprd);
13466
13467 p_enc_ctx->reconfigCount++;
13468 }
13469 break;
13471 if (p_enc_ctx->frame_num ==
13472 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13473 ni_vui_hrd_t vui;
13474 vui.colorDescPresent =
13475 p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13476 vui.colorPrimaries =
13477 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13478 vui.colorTrc =
13479 p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13480 vui.colorSpace =
13481 p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13482 vui.aspectRatioWidth =
13483 p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13484 vui.aspectRatioHeight =
13485 p_param->reconf_hash[p_enc_ctx->reconfigCount][6];
13486 vui.videoFullRange =
13487 p_param->reconf_hash[p_enc_ctx->reconfigCount][7];
13488 retval = ni_reconfig_vui(p_enc_ctx, &vui);
13489 if (retval){
13490 return retval;
13491 }
13492 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13493 "xcoder_send_frame: frame #%lu reconf "
13494 "vui colorDescPresent %d colorPrimaries %d "
13495 "colorTrc %d colorSpace %d aspectRatioWidth %d "
13496 "aspectRatioHeight %d videoFullRange %d\n",
13497 p_enc_ctx->frame_num, vui.colorDescPresent,
13498 vui.colorPrimaries, vui.colorTrc,
13501 p_enc_ctx->reconfigCount++;
13502 }
13503 break;
13505 if (p_enc_ctx->frame_num ==
13506 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13509 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13510 ltr.use_long_term_ref =
13511 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13512
13513 retval = ni_set_ltr(p_enc_ctx, &ltr);
13514 if (retval) {
13515 return retval;
13516 }
13517 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13518 "xcoder_send_frame(): frame #%lu API set LTR\n",
13519 p_enc_ctx->frame_num);
13520 p_enc_ctx->reconfigCount++;
13521 }
13522 break;
13525 if (p_enc_ctx->frame_num ==
13526 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13527 ni_rc_min_max_qp qp_info;
13528 qp_info.minQpI = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13529 qp_info.maxQpI = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13530 qp_info.maxDeltaQp = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][3];
13531 qp_info.minQpPB = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][4];
13532 qp_info.maxQpPB = (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][5];
13533 retval = ni_reconfig_min_max_qp(p_enc_ctx, &qp_info);
13534 if (retval) {
13535 return retval;
13536 }
13537 ni_log2(p_enc_ctx, NI_LOG_DEBUG,
13538 "%s(): frame %d minQpI %d maxQpI %d maxDeltaQp %d minQpPB %d maxQpPB %d\n",
13539 __func__, p_enc_ctx->frame_num,
13540 qp_info.minQpI, qp_info.maxQpI, qp_info.maxDeltaQp, qp_info.minQpPB, qp_info.maxQpPB);
13541 p_enc_ctx->reconfigCount++;
13542 }
13543 break;
13545 if (p_enc_ctx->frame_num ==
13546 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13547 retval = ni_set_ltr_interval(
13548 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13549 if (retval) {
13550 return retval;
13551 }
13552 ni_log2(p_enc_ctx,
13554 "xcoder_send_frame(): frame #%lu API set LTR interval %d\n",
13555 p_enc_ctx->frame_num,
13556 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13557 p_enc_ctx->reconfigCount++;
13558 }
13559 break;
13561 if (p_enc_ctx->frame_num ==
13562 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13563 retval = ni_set_frame_ref_invalid(
13564 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13565 if (retval) {
13566 return retval;
13567 }
13568 ni_log2(p_enc_ctx,
13570 "xcoder_send_frame(): frame #%lu API set frame ref invalid "
13571 "%d\n",
13572 p_enc_ctx->frame_num,
13573 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13574 p_enc_ctx->reconfigCount++;
13575 }
13576 break;
13578 if (p_enc_ctx->frame_num ==
13579 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13580 ni_framerate_t framerate;
13581 framerate.framerate_num =
13582 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13583 framerate.framerate_denom =
13584 (int32_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13585 retval = ni_reconfig_framerate(p_enc_ctx, &framerate);
13586 if (retval) {
13587 return retval;
13588 }
13589 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13590 "xcoder_send_frame: frame #%lu API reconfig framerate "
13591 "(%d/%d)\n",
13592 p_enc_ctx->frame_num,
13593 p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13594 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13595
13596 p_enc_ctx->reconfigCount++;
13597 }
13598 break;
13600 if (p_enc_ctx->frame_num ==
13601 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13603 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13604 if (retval) {
13605 return retval;
13606 }
13607 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13608 "xcoder_send_frame: frame #%lu API reconfig maxFrameSize %d\n",
13609 p_enc_ctx->frame_num,
13610 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13611
13612 p_enc_ctx->reconfigCount++;
13613 }
13614 break;
13616 if (p_enc_ctx->frame_num ==
13617 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13618 retval = ni_reconfig_crf(
13619 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13620 if (retval) {
13621 return retval;
13622 }
13623 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13624 "xcoder_send_frame: frame #%lu API reconfig crf %d\n",
13625 p_enc_ctx->frame_num,
13626 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13627
13628 p_enc_ctx->reconfigCount++;
13629 }
13630 break;
13632 if (p_enc_ctx->frame_num ==
13633 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13634 float crf = (float)(p_param->reconf_hash[p_enc_ctx->reconfigCount][1] +
13635 (float)p_param->reconf_hash[p_enc_ctx->reconfigCount][2] / 100.0);
13636 retval = ni_reconfig_crf2(p_enc_ctx, crf);
13637 if (retval) {
13638 return retval;
13639 }
13640 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13641 "xcoder_send_frame: frame #%lu API reconfig crf %f\n",
13642 p_enc_ctx->frame_num, crf);
13643
13644 p_enc_ctx->reconfigCount++;
13645 }
13646 break;
13648 if (p_enc_ctx->frame_num ==
13649 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13650 retval = ni_reconfig_vbv_value(
13651 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13652 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13653 if (retval) {
13654 return retval;
13655 }
13656 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13657 "xcoder_send_frame: frame #%lu API reconfig vbvMaxRate %d vbvBufferSize %d\n",
13658 p_enc_ctx->frame_num,
13659 p_param->reconf_hash[p_enc_ctx->reconfigCount][1],
13660 p_param->reconf_hash[p_enc_ctx->reconfigCount][2]);
13661
13662 p_enc_ctx->reconfigCount++;
13663 }
13664 break;
13666 if (p_enc_ctx->frame_num ==
13667 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13668
13670 p_enc_ctx, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13671 if (retval) {
13672 return retval;
13673 }
13674 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13675 "xcoder_send_frame: frame #%lu reconf maxFrameSizeRatio %d\n",
13676 p_enc_ctx->frame_num, p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13677
13678 p_enc_ctx->reconfigCount++;
13679 }
13680 break;
13682 if (p_enc_ctx->frame_num ==
13683 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13684 retval = ni_reconfig_slice_arg(
13685 p_enc_ctx, (int16_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13686 if (retval) {
13687 return retval;
13688 }
13689 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13690 "xcoder_send_frame: frame #%lu API reconfig sliceArg %d\n",
13691 p_enc_ctx->frame_num,
13692 p_param->reconf_hash[p_enc_ctx->reconfigCount][1]);
13693
13694 p_enc_ctx->reconfigCount++;
13695 }
13696 break;
13697 // set LTR and/or invalidate reference frames through API.
13698 // reconf file line format matches XCODER_TEST_RECONF_LTR_INVALID_REF.
13700 if (p_enc_ctx->frame_num ==
13701 p_param->reconf_hash[p_enc_ctx->reconfigCount][0]) {
13702 uint8_t use_cur_src_as_long_term_pic =
13703 (uint8_t)p_param->reconf_hash[p_enc_ctx->reconfigCount][1];
13704 int32_t invalid_frame_num =
13705 p_param->reconf_hash[p_enc_ctx->reconfigCount][2];
13706
13707 if (use_cur_src_as_long_term_pic > 0) {
13709 ltr.use_cur_src_as_long_term_pic = use_cur_src_as_long_term_pic;
13710 ltr.use_long_term_ref = 0;
13711 retval = ni_set_ltr(p_enc_ctx, &ltr);
13712 if (retval) {
13713 return retval;
13714 }
13715 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13716 "xcoder_send_frame(): frame #%lu API set LTR "
13717 "use_cur_src_as_long_term_pic %u\n",
13718 p_enc_ctx->frame_num, use_cur_src_as_long_term_pic);
13719 }
13720
13721 if (invalid_frame_num != -1) {
13722 retval = ni_set_frame_ref_invalid(p_enc_ctx, invalid_frame_num);
13723 if (retval) {
13724 return retval;
13725 }
13726 ni_log2(p_enc_ctx, NI_LOG_TRACE,
13727 "xcoder_send_frame(): frame #%lu API set frame ref "
13728 "invalid %d\n",
13729 p_enc_ctx->frame_num, invalid_frame_num);
13730 }
13731
13732 p_enc_ctx->reconfigCount++;
13733 }
13734 break;
13735#endif
13737 default:
13738 ;
13739 }
13740 return NI_RETCODE_SUCCESS;
13741}
13742
13746static int ni_tolower(int c)
13747{
13748 if (c >= 'A' && c <= 'Z')
13749 c ^= 0x20;
13750 return c;
13751}
13752
13753int ni_strcasecmp(const char *a, const char *b)
13754{
13755 uint8_t c1, c2;
13756 do
13757 {
13758 c1 = ni_tolower(*a++);
13759 c2 = ni_tolower(*b++);
13760 } while (c1 && c1 == c2);
13761 return c1 - c2;
13762}
13763
13765{
13766 ni_encoder_cfg_params_t *p_enc = &p_param->cfg_enc_params;
13769 p_gop->pic_param[0].rps[0].ref_pic = 1;
13771 p_gop->pic_param[0].rps[0].ref_pic_used = 1;
13773 p_gop->pic_param[0].rps[1].ref_pic = 1;
13775 p_gop->pic_param[0].rps[1].ref_pic_used = 1;
13777 p_gop->pic_param[0].rps[2].ref_pic = 1;
13779 p_gop->pic_param[0].rps[2].ref_pic_used = 1;
13781 p_gop->pic_param[0].rps[3].ref_pic = 1;
13783 p_gop->pic_param[0].rps[3].ref_pic_used = 1;
13785 p_gop->pic_param[1].rps[0].ref_pic = 1;
13787 p_gop->pic_param[1].rps[0].ref_pic_used = 1;
13789 p_gop->pic_param[1].rps[1].ref_pic = 1;
13791 p_gop->pic_param[1].rps[1].ref_pic_used = 1;
13793 p_gop->pic_param[1].rps[2].ref_pic = 1;
13795 p_gop->pic_param[1].rps[2].ref_pic_used = 1;
13797 p_gop->pic_param[1].rps[3].ref_pic = 1;
13799 p_gop->pic_param[1].rps[3].ref_pic_used = 1;
13801 p_gop->pic_param[2].rps[0].ref_pic = 1;
13803 p_gop->pic_param[2].rps[0].ref_pic_used = 1;
13805 p_gop->pic_param[2].rps[1].ref_pic = 1;
13807 p_gop->pic_param[2].rps[1].ref_pic_used = 1;
13809 p_gop->pic_param[2].rps[2].ref_pic = 1;
13811 p_gop->pic_param[2].rps[2].ref_pic_used = 1;
13813 p_gop->pic_param[2].rps[3].ref_pic = 1;
13815 p_gop->pic_param[2].rps[3].ref_pic_used = 1;
13817 p_gop->pic_param[3].rps[0].ref_pic = 1;
13819 p_gop->pic_param[3].rps[0].ref_pic_used = 1;
13821 p_gop->pic_param[3].rps[1].ref_pic = 1;
13823 p_gop->pic_param[3].rps[1].ref_pic_used = 1;
13825 p_gop->pic_param[3].rps[2].ref_pic = 1;
13827 p_gop->pic_param[3].rps[2].ref_pic_used = 1;
13829 p_gop->pic_param[3].rps[3].ref_pic = 1;
13831 p_gop->pic_param[3].rps[3].ref_pic_used = 1;
13833 p_gop->pic_param[4].rps[0].ref_pic = 1;
13835 p_gop->pic_param[4].rps[0].ref_pic_used = 1;
13837 p_gop->pic_param[4].rps[1].ref_pic = 1;
13839 p_gop->pic_param[4].rps[1].ref_pic_used = 1;
13841 p_gop->pic_param[4].rps[2].ref_pic = 1;
13843 p_gop->pic_param[4].rps[2].ref_pic_used = 1;
13845 p_gop->pic_param[4].rps[3].ref_pic = 1;
13847 p_gop->pic_param[4].rps[3].ref_pic_used = 1;
13849 p_gop->pic_param[5].rps[0].ref_pic = 1;
13851 p_gop->pic_param[5].rps[0].ref_pic_used = 1;
13853 p_gop->pic_param[5].rps[1].ref_pic = 1;
13855 p_gop->pic_param[5].rps[1].ref_pic_used = 1;
13857 p_gop->pic_param[5].rps[2].ref_pic = 1;
13859 p_gop->pic_param[5].rps[2].ref_pic_used = 1;
13861 p_gop->pic_param[5].rps[3].ref_pic = 1;
13863 p_gop->pic_param[5].rps[3].ref_pic_used = 1;
13865 p_gop->pic_param[6].rps[0].ref_pic = 1;
13867 p_gop->pic_param[6].rps[0].ref_pic_used = 1;
13869 p_gop->pic_param[6].rps[1].ref_pic = 1;
13871 p_gop->pic_param[6].rps[1].ref_pic_used = 1;
13873 p_gop->pic_param[6].rps[2].ref_pic = 1;
13875 p_gop->pic_param[6].rps[2].ref_pic_used = 1;
13877 p_gop->pic_param[6].rps[3].ref_pic = 1;
13879 p_gop->pic_param[6].rps[3].ref_pic_used = 1;
13881 p_gop->pic_param[7].rps[0].ref_pic = 1;
13883 p_gop->pic_param[7].rps[0].ref_pic_used = 1;
13885 p_gop->pic_param[7].rps[1].ref_pic = 1;
13887 p_gop->pic_param[7].rps[1].ref_pic_used = 1;
13889 p_gop->pic_param[7].rps[2].ref_pic = 1;
13891 p_gop->pic_param[7].rps[2].ref_pic_used = 1;
13893 p_gop->pic_param[7].rps[3].ref_pic = 1;
13895 p_gop->pic_param[7].rps[3].ref_pic_used = 1;
13896
13897}
13898
13900{
13901 ni_encoder_cfg_params_t *p_enc = &p_param->cfg_enc_params;
13903 int i, j;
13904 for (i=0; i<NI_MAX_GOP_NUM; i++)
13905 {
13906 for (j=0; j<NI_MAX_REF_PIC; j++)
13907 {
13908 if (p_gop->pic_param[i].rps[j].ref_pic == 1 &&
13909 p_gop->pic_param[i].rps[j].ref_pic_used != 1)
13910 {
13912 "g%drefPic%d specified without g%drefPic%dUsed specified!\n",
13913 i, j, i, j);
13914 return false;
13915 }
13916 }
13917 }
13918 // set custom_gop_params default.
13919 for (i=0; i<NI_MAX_GOP_NUM; i++)
13920 {
13921 for (j=0; j<NI_MAX_REF_PIC; j++)
13922 {
13923 p_gop->pic_param[i].rps[j].ref_pic = 0;
13924 p_gop->pic_param[i].rps[j].ref_pic_used = 0;
13925 }
13926 }
13927 return true;
13928}
13929
13930#ifndef DEPRECATION_AS_ERROR
13931/*!*****************************************************************************
13932 * \brief Initiate P2P transfer (P2P write) (deprecated)
13933 *
13934 * \param[in] pSession Pointer to source card destination
13935 * \param[in] source Pointer to source frame to transmit
13936 * \param[in] ui64DestAddr Destination address on target device
13937 * \param[in] ui32FrameSize Size of frame to transfer
13938 *
13939 * \return always returns
13940 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13941*******************************************************************************/
13943 niFrameSurface1_t *source,
13944 uint64_t ui64DestAddr,
13945 uint32_t ui32FrameSize)
13946{
13947 // avoid compiler warnings
13948 (void) pSession;
13949 (void) source;
13950 (void) ui64DestAddr;
13951 (void) ui32FrameSize;
13952
13954}
13955#endif
13956
13957#ifndef DEPRECATION_AS_ERROR
13958/*!*****************************************************************************
13959 * \brief Initiate P2P transfer (P2P write) (deprecated)
13960 *
13961 * \param[in] pSession Pointer to source card destination
13962 * \param[in] source Pointer to source frame to transmit
13963 * \param[in] ui64DestAddr Destination address on target device
13964 * \param[in] ui32FrameSize Size of frame to transfer
13965 *
13966 * \return always returns
13967 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13968*******************************************************************************/
13970 niFrameSurface1_t *source,
13971 uint64_t ui64DestAddr, uint32_t ui32FrameSize)
13972{
13973 // avoid compiler warnings
13974 (void) pSession;
13975 (void) source;
13976 (void) ui64DestAddr;
13977 (void) ui32FrameSize;
13978
13980}
13981#endif
13982
13983/*!*****************************************************************************
13984 * \brief Initiate P2P transfer with sgl list (P2P write)
13985 *
13986 * \param[in] pSession Pointer to source card session
13987 * \param[in] source Pointer to source P2P frame
13988 * \param[in] dmaAddrs Destination DMA address on target device
13989 *
13990 * \return on success
13991 * NI_RETCODE_SUCCESS
13992 * on failure
13993 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
13994 * NI_RETCODE_INVALID_PARAM
13995 * NI_RETCODE_ERROR_INVALID_SESSION
13996 * NI_RETCODE_ERROR_MEM_ALOC
13997 * NI_RETCODE_ERROR_NVME_CMD_FAILED
13998*******************************************************************************/
14000 ni_frame_t *pSrcFrame,
14001 const ni_p2p_sgl_t *dmaAddrs)
14002{
14004
14005 if ((pSession == NULL) || (dmaAddrs == NULL) || (pSrcFrame == NULL))
14006 {
14008 }
14009
14010 /* Firmware compatibility check */
14011 if (ni_cmp_fw_api_ver((char *) &pSession->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sX") < 0)
14012 {
14013 ni_log2(pSession, NI_LOG_ERROR,
14014 "%s: FW doesn't support this operation\n", __func__);
14016 }
14017
14018 retval = ni_send_to_target_v2(pSession, pSrcFrame, dmaAddrs);
14019 if (retval < 0)
14020 {
14021 ni_log2(pSession, NI_LOG_ERROR, "%s(): Can't DMA to destination (%d)\n", __func__, retval);
14022 }
14023
14024 return retval;
14025}
14026
14027/*!*****************************************************************************
14028 * \brief Initiate a P2P transfer (P2P read)
14029 *
14030 * \param[in] pSession Pointer to destination upload session
14031 * \param[in] dmaAddrs Pointer to source DMA addresses
14032 * \param[in] pDstFrame Pointer to destination P2P frame
14033 *
14034 * \return on success
14035 * NI_RETCODE_SUCCESS
14036 * on failure
14037 * NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
14038 * NI_RETCODE_INVALID_PARAM
14039 * NI_RETCODE_ERROR_INVALID_SESSION
14040 * NI_RETCODE_ERROR_MEM_ALOC
14041 * NI_RETCODE_ERROR_NVME_CMD_FAILED
14042*******************************************************************************/
14044 const ni_p2p_sgl_t *dmaAddrs,
14045 ni_frame_t *pDstFrame)
14046{
14048
14049 if ((pSession == NULL) || (dmaAddrs == NULL) || (pDstFrame == NULL))
14050 {
14052 }
14053
14054 /* Firmware compatibility check */
14055 if (ni_cmp_fw_api_ver((char *) &pSession->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6re") < 0)
14056 {
14057 ni_log2(pSession, NI_LOG_ERROR,
14058 "%s: FW doesn't support this operation\n", __func__);
14060 }
14061
14062 retval = ni_recv_from_target(pSession, dmaAddrs, pDstFrame);
14063
14064 if (retval < 0)
14065 {
14066 ni_log2(pSession, NI_LOG_ERROR,
14067 "%s(): Can't DMA from source (%d)\n", __func__, retval);
14068 retval = NI_RETCODE_INVALID_PARAM;
14069 }
14070
14071 return retval;
14072}
14073
14074/*!*****************************************************************************
14075 * \brief Send a restart command after flush command
14076 * Only support Encoder now
14077 *
14078 * \param[in] p_ctx Pointer to a caller allocated
14079 * ni_session_context_t struct
14080 * \param[in] width width, in pixels
14081 * \param[in] height height, in pixels
14082 * \param[in] device_type NI_DEVICE_TYPE_ENCODER
14083 * \return On success
14084 * NI_RETCODE_SUCCESS
14085 * On failure
14086 * NI_RETCODE_INVALID_PARAM
14087 * NI_RETCODE_ERROR_NVME_CMD_FAILED
14088 * NI_RETCODE_ERROR_INVALID_SESSION
14089 ******************************************************************************/
14091 int video_width,
14092 int video_height,
14093 ni_device_type_t device_type)
14094{
14095 ni_retcode_t retval = 0;
14096 ni_resolution_t resolution;
14097 ni_xcoder_params_t *p_param = NULL;
14098
14099 if (!p_ctx)
14100 {
14101 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null, return\n",
14102 __func__);
14104 }
14105
14106 switch (device_type)
14107 {
14109 {
14110 // requires API version >= 54
14112 "54") < 0)
14113 {
14114 ni_log2(p_ctx, NI_LOG_ERROR, "Error: %s function not supported on device with FW API version < 5.4\n", __func__);
14116 }
14117
14118 /* This function should be called only if flushing is detected */
14120 {
14121 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() wrong state %d\n",
14122 __func__, p_ctx->session_run_state);
14124 }
14125
14126 if (video_width < NI_MIN_WIDTH || video_width > NI_MAX_WIDTH ||
14127 video_height < NI_MIN_HEIGHT || video_height > NI_MAX_HEIGHT)
14128 {
14129 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() invalid width %d or height %d\n",
14130 __func__, video_width, video_height);
14132 }
14133 resolution.width = video_width;
14134 resolution.height = video_height;
14135 resolution.bit_depth_factor = p_ctx->bit_depth_factor;
14136 resolution.luma_linesize = 0;
14137 resolution.chroma_linesize = 0;
14138 if (p_ctx->p_session_config)
14139 {
14140 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
14141 resolution.luma_linesize = p_param->luma_linesize;
14142 resolution.chroma_linesize = p_param->chroma_linesize;
14143 }
14145
14146 // reconfig the encoder session
14147 retval = ni_encoder_session_sequence_change(p_ctx, &resolution);
14148 if (NI_RETCODE_SUCCESS != retval)
14149 {
14150 ni_log(NI_LOG_ERROR, "Failed to reconfig config the encoder session (status = %d)\n", retval);
14152 return retval;
14153 }
14154
14155 // update session context
14156 p_ctx->ready_to_close = 0;
14157 p_ctx->frame_num = 0;
14158 p_ctx->pkt_num = 0;
14160 break;
14161 }
14162 default:
14163 {
14164 retval = NI_RETCODE_INVALID_PARAM;
14165 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unsupported device type: %d",
14166 __func__, device_type);
14167 break;
14168 }
14169 }
14170 return retval;
14171}
14172
14173/*!******************************************************************************
14174* \brief Send a p_config command to reconfigure decoding ppu params.
14175*
14176* \param ni_session_context_t p_session_ctx - xcoder Context
14177* \param ni_xcoder_params_t p_param - xcoder Params
14178* \param ni_ppu_config_t p_ppu_config - Struct ni_ppu_config
14179*
14180* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
14181*******************************************************************************/
14183 ni_xcoder_params_t *p_param, ni_ppu_config_t *p_ppu_config)
14184{
14185 int ret = 0, i = 0;
14186 if (!p_session_ctx || !p_param || !p_ppu_config)
14187 {
14189 return ret;
14190 }
14191 if (p_session_ctx->ppu_reconfig_pkt_pos != 0)
14192 {
14193 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: Warning ignore ppu reconfig before last config done!\n", __func__);
14194 return 0;
14195 }
14196
14197 // check fw revision
14199 (char*) &p_session_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
14200 "6sF") < 0)
14201 {
14202 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s: not supported on device with FW API version < 6sF\n", __func__);
14204 }
14205
14206 if (NI_CODEC_FORMAT_H264 != p_session_ctx->codec_format &&
14207 NI_CODEC_FORMAT_H265 != p_session_ctx->codec_format)
14208 {
14209 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): only supported for h264 and h265 decoder\n", __func__);
14211 }
14212
14213 ni_decoder_input_params_t *p_dec_input_param = &(p_param->dec_input_params);
14214 if (p_dec_input_param->hwframes != 1)
14215 {
14216 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): only supported for hw mode\n", __func__);
14218 }
14219 if (!p_dec_input_param->disable_adaptive_buffers)
14220 {
14221 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): not supported when disable_adaptive_buffers is disabled\n", __func__);
14223 }
14224 if (p_dec_input_param->mcmode)
14225 {
14226 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): not supported when MulticoreJointMode is enabled\n", __func__);
14228 }
14229 if (p_dec_input_param->enable_out1 == 0 &&
14230 p_ppu_config->ppu_set_enable & (0x01 << 1))
14231 {
14232 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Error reconfig ppu1 while ppu1 is not enabled\n", __func__);
14234 }
14235 if (p_dec_input_param->enable_out2 == 0 &&
14236 p_ppu_config->ppu_set_enable & (0x01 << 2))
14237 {
14238 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): Error reconfig ppu2 while ppu2 is not enabled\n", __func__);
14240 }
14241 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
14242 {
14243 if (p_ppu_config->ppu_set_enable & (0x01 << i))
14244 {
14245 if (p_ppu_config->ppu_w[i] > NI_MAX_RESOLUTION_WIDTH ||
14246 p_ppu_config->ppu_h[i] > NI_MAX_RESOLUTION_HEIGHT ||
14247 p_ppu_config->ppu_w[i] < NI_MIN_RESOLUTION_WIDTH_SCALER ||
14248 p_ppu_config->ppu_h[i] < NI_MIN_RESOLUTION_WIDTH_SCALER)
14249 {
14250 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu[%d] width x height %ux%u "
14251 "out of range\n", __func__, i, p_ppu_config->ppu_w[i], p_ppu_config->ppu_h[i]);
14253 return ret;
14254 }
14255 if ((p_ppu_config->ppu_w[i] & 1) || (p_ppu_config->ppu_h[i] & 1))
14256 {
14257 ni_log2(p_session_ctx, NI_LOG_ERROR, "%s(): ppu[%d] wxh %dx%d not align to 2!\n",
14258 __func__, i, p_ppu_config->ppu_w[i], p_ppu_config->ppu_h[i]);
14260 return ret;
14261 }
14262 }
14263 }
14265 p_session_ctx, p_ppu_config, sizeof(ni_ppu_config_t));
14266 if (ret == NI_RETCODE_SUCCESS)
14267 {
14268 p_session_ctx->ppu_reconfig_pkt_pos = p_session_ctx->pkt_num;
14269 }
14270 return ret;
14271}
14272
14273float ni_bicubic_coeff_default(int filtersize, double offset, double B, double C)
14274{
14275 double t = offset < 0 ? -offset : offset;
14276 (void)filtersize;
14277 double tt = t * t;
14278
14279 if (t < 0)
14280 t = -t;
14281
14282 if (t < 1.0)
14283 {
14284 t = (((12.0 - 9.0 * B - 6.0 * C) * (t * tt))
14285 + ((-18.0 + 12.0 * B + 6.0 * C) * tt)
14286 + (6.0 - 2 * B));
14287 return (float)(t / 6.0);
14288 }
14289 else if (t < 2.0)
14290 {
14291 t = (((-1.0 * B - 6.0 * C) * (t * tt))
14292 + ((6.0 * B + 30.0 * C) * tt)
14293 + ((-12.0 * B - 48.0 * C) * t)
14294 + (8.0 * B + 24 * C));
14295 return (float)(t / 6.0);
14296 }
14297 return 0.0f;
14298}
14299
14301{
14302 if (!p_session_ctx)
14303 {
14305 }
14306 p_session_ctx->scaler_coeff_fn = fn ? fn : ni_bicubic_coeff_default;
14307 return NI_RETCODE_SUCCESS;
14308}
14309
14311 uint16_t kernel_array[], int kernel_taps, double param_b,
14312 double param_c, int SrcSize, int DstSize)
14313{
14314 int padding;
14315 int kernelHalf;
14316 float fSubpixelStep;
14317 int subpixelPos;
14318 int kernelPos;
14319 float fSubpixelOffset;
14320
14321 if (!p_session_ctx)
14322 {
14324 }
14325
14326 if (!p_session_ctx->scaler_coeff_fn)
14327 {
14329 "ni_scaler_build_kernel: scaler_coeff_fn is NULL\n");
14331 }
14332
14333 if (kernel_taps < 1 || kernel_taps > NI_SCALER_MAX_KERNEL_TAPS) {
14335 "ni_scaler_build_kernel: kernel_taps=%d out of range [1, %d]\n",
14336 kernel_taps, NI_SCALER_MAX_KERNEL_TAPS);
14338 }
14339
14340 (void)SrcSize;
14341 (void)DstSize;
14342
14343 /* Zero the horizontal table — left/right padding slots remain 0 */
14344 memset(kernel_array, 0,
14345 (size_t)NI_SCALER_KERNEL_POSITIONS * NI_SCALER_KERNEL_SLOTS * sizeof(uint16_t));
14346
14347 padding = (NI_SCALER_KERNEL_SLOTS - kernel_taps) / 2;
14348 kernelHalf = kernel_taps >> 1;
14349
14350 /* Calculate the subpixel step. */
14351 fSubpixelStep = (float)(1.0f / 32.0f);
14352 /* Init the subpixel offset. */
14353 fSubpixelOffset = 0.5f;
14354
14355 for (subpixelPos = 0; subpixelPos < NI_SCALER_KERNEL_POSITIONS; subpixelPos++) {
14356 float fSubpixelSet[9] = {0.0f};
14357 int offset = subpixelPos * NI_SCALER_KERNEL_SLOTS;
14358 /* Init the sum of all weights for the current subpixel. */
14359 float fWeightSum = 0.0f;
14360 uint16_t weightSum = 0;
14361 int16_t adjustCount, adjustFrom;
14362 int16_t adjustment;
14363 int16_t overCnt=0;
14364 int16_t underCnt=0;
14365
14366 for (kernelPos = 0; kernelPos < NI_SCALER_KERNEL_SLOTS; kernelPos++) {
14367 int index = kernelPos - padding;
14368 /* Pad with zeros. */
14369 if ((index < 0) || (index >= kernel_taps))
14370 {
14371 fSubpixelSet[kernelPos] = 0.0f;
14372 }
14373 else
14374 {
14375 float fX = ((float)(index - kernelHalf ) + fSubpixelOffset);
14376 fSubpixelSet[kernelPos] =
14377 (float)p_session_ctx->scaler_coeff_fn(
14378 kernel_taps, (float)fX, param_b, param_c);
14379 }
14380 /* Update the sum of weights. */
14381 fWeightSum = fWeightSum + fSubpixelSet[kernelPos];
14382 }
14383 /* Adjust weights so that the sum will be 1.0. */
14384 for (kernelPos = 0; kernelPos < NI_SCALER_KERNEL_SLOTS; kernelPos++)
14385 {
14386 /* Normalize the current weight. */
14387 float fWeight = fSubpixelSet[kernelPos] / fWeightSum;
14388
14389 /* Convert the weight to fixed point and store in the table. */
14390 if (fWeight == 0.0f)
14391 {
14392 kernel_array[kernelPos + offset] = 0x0000;
14393 }
14394 else if (fWeight >= 1.0f)
14395 {
14396 kernel_array[kernelPos + offset] = 0x4000;
14397 overCnt++;
14398 }
14399 else if (fWeight <= -1.0f)
14400 {
14401 kernel_array[kernelPos + offset] = 0xC000;
14402 underCnt++;
14403 }
14404 else
14405 {
14406 kernel_array[kernelPos + offset] = (int16_t) (fWeight * 16384.0f);
14407 }
14408
14409 weightSum += kernel_array[kernelPos + offset];
14410 }
14411
14412 /* Adjust the fixed point coefficients. */
14413 adjustCount = (int16_t)(0x4000 - weightSum);
14414 if (adjustCount < 0)
14415 {
14416 adjustCount = (int16_t)(-adjustCount);
14417 adjustment = -1;
14418 }
14419 else
14420 {
14421 adjustment = 1;
14422 }
14423
14424 if (adjustCount < kernel_taps)
14425 {
14426 adjustFrom = (int16_t)((NI_SCALER_KERNEL_SLOTS - adjustCount) / 2);
14427 for (kernelPos = 0; kernelPos < adjustCount; kernelPos++)
14428 {
14429 kernel_array[adjustFrom + kernelPos + offset] += adjustment;
14430 }
14431 }
14432 else
14433 {
14434 adjustFrom = (int16_t)((NI_SCALER_KERNEL_SLOTS - kernel_taps) / 2);
14435 adjustment = (int16_t)((0x4000 - weightSum) / (kernel_taps - overCnt - underCnt));
14436 weightSum = 0;
14437 for (kernelPos = 0; kernelPos < kernel_taps; kernelPos++)
14438 {
14439 if (kernel_array[adjustFrom+kernelPos + offset] != 0x4000 &&
14440 kernel_array[adjustFrom+kernelPos + offset] != 0xC000)
14441 {
14442 kernel_array[adjustFrom + kernelPos + offset] += adjustment;
14443 }
14444 weightSum += kernel_array[adjustFrom + kernelPos + offset];
14445 }
14446 }
14447 /* Advance to the next subpixel. */
14448 fSubpixelOffset = fSubpixelOffset - fSubpixelStep;
14449 }
14450 return NI_RETCODE_SUCCESS;
14451}
#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 Extra Info 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_LTR_INVALID_REF
@ 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_LTR_INVALID_REF_API
@ 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_LONG_TERM_REFERENCE_OLDEST
#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_ENC_PARAM_CLEAR_REF_LIST_MODIFICATION
#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)
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:4892
int ni_pthread_mutex_lock(ni_pthread_mutex_t *mutex)
thread mutex lock
Definition ni_util.c:4772
int ni_pthread_cond_destroy(ni_pthread_cond_t *cond)
destroy condition variables
Definition ni_util.c:4911
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:4836
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:4754
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:2747
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:4074
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:4863
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:2799
int ni_pthread_mutex_unlock(ni_pthread_mutex_t *mutex)
thread mutex unlock
Definition ni_util.c:4798
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:4716
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:5099
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:4387
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