libxcoder  5.2.0
ni_rsrc_api.cpp
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_rsrc_api.cpp
24  *
25  * \brief Public definitions for managing NETINT video processing devices
26  ******************************************************************************/
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <fcntl.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <ctype.h>
34 
35 #if __linux__ || __APPLE__
36 #include <unistd.h>
37 #include <fcntl.h> /* For O_* constants */
38 #include <dirent.h>
39 #include <sys/mman.h>
40 #include <sys/types.h>
41 #include <sys/stat.h> /* For mode constants */
42 #include <regex.h>
43 #endif
44 
45 #if __APPLE__
46 #include <sys/syslimits.h>
47 #endif
48 
49 #include "ni_rsrc_api.h"
50 #include "ni_rsrc_priv.h"
51 #include "ni_util.h"
52 
53 static const char *ni_codec_format_str[] = {"H.264", "H.265", "VP9", "JPEG",
54  "AV1"};
55 static const char *ni_dec_name_str[] = {"h264_ni_quadra_dec", "h265_ni_quadra_dec",
56  "vp9_ni_quadra_dec", "jpeg_ni_quadra_dec"};
57 static const char *ni_enc_name_str[] = {"h264_ni_quadra_enc", "h265_ni_quadra_enc", "empty",
58  "jpeg_ni_quadra_enc", "av1_ni_quadra_enc"};
59 
63 NI_DEPRECATED ni_device_handle_t g_dev_handle = NI_INVALID_DEVICE_HANDLE;
64 
65 // return true if string key is found in array of strings, false otherwise
66 static bool is_str_in_str_array(const char key[],
67  char arr[][NI_MAX_DEVICE_NAME_LEN],
68  int array_size)
69 {
70  int i;
71 
72  for (i = 0; i < array_size; i++)
73  {
74  if (0 == strcmp(key, arr[i]))
75  {
76  return true;
77  }
78  }
79  return false;
80 }
81 
82 void print_device(ni_device_t *p_device)
83 {
84  if (!p_device)
85  {
86  ni_log(NI_LOG_INFO, "WARNING: NULL parameter passed in!\n");
87  return;
88  }
89 
90  ni_device_info_t *p_dev_info = NULL;
91  for (int xcoder_index_1 = 0;
92  xcoder_index_1 < p_device->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
93  xcoder_index_1++)
94  {
95  p_dev_info = &p_device->xcoders[NI_DEVICE_TYPE_ENCODER][xcoder_index_1];
96  ni_log(NI_LOG_INFO, "Device #%d:\n", xcoder_index_1);
97  ni_log(NI_LOG_INFO, " Serial number: %.*s\n",
98  (int)sizeof(p_dev_info->serial_number),
99  p_dev_info->serial_number);
100  ni_log(NI_LOG_INFO, " Model number: %.*s\n",
101  (int)sizeof(p_dev_info->model_number),
102  p_dev_info->model_number);
103  ni_log(NI_LOG_INFO, " Last ran firmware loader version: %.8s\n",
104  p_dev_info->fl_ver_last_ran);
105  ni_log(NI_LOG_INFO, " NOR flash firmware loader version: %.8s\n",
106  p_dev_info->fl_ver_nor_flash);
107  ni_log(NI_LOG_INFO, " Current firmware revision: %.8s\n",
108  p_dev_info->fw_rev);
109  ni_log(NI_LOG_INFO, " NOR flash firmware revision: %.8s\n",
110  p_dev_info->fw_rev_nor_flash);
111  ni_log(NI_LOG_INFO, " F/W & S/W compatibility: %s\n",
112  p_dev_info->fw_ver_compat_warning ?
113  "no, possible missing features" : "yes");
114  ni_log(NI_LOG_INFO, " F/W branch: %s\n",
115  p_dev_info->fw_branch_name);
116  ni_log(NI_LOG_INFO, " F/W commit time: %s\n",
117  p_dev_info->fw_commit_time);
118  ni_log(NI_LOG_INFO, " F/W commit hash: %s\n",
119  p_dev_info->fw_commit_hash);
120  ni_log(NI_LOG_INFO, " F/W build time: %s\n",
121  p_dev_info->fw_build_time);
122  ni_log(NI_LOG_INFO, " F/W build id: %s\n",p_dev_info->fw_build_id);
123  ni_log(NI_LOG_INFO, " DeviceID: %s\n", p_dev_info->dev_name);
124  ni_log(NI_LOG_INFO, " PixelFormats: yuv420p, yuv420p10le, nv12, p010le"
125  ", ni_quadra\n");
126 
127  for (size_t dev_type = NI_DEVICE_TYPE_DECODER;
128  dev_type != NI_DEVICE_TYPE_XCODER_MAX; dev_type++)
129  {
130  for (int xcoder_index_2 = 0;
131  xcoder_index_2 < p_device->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
132  xcoder_index_2++)
133  {
134  if (strcmp(p_dev_info->dev_name,
135  p_device->xcoders[dev_type][xcoder_index_2].dev_name)
136  == 0 && p_dev_info->module_id >= 0)
137  {
138  ni_rsrc_print_device_info(&(p_device->xcoders[dev_type]
139  [xcoder_index_2]));
140  }
141  }
142  }
143  }
144 }
145 
146 /*!*****************************************************************************
147  * \brief Scan and refresh all resources on the host, taking into account
148  * hot-plugged and pulled out cards.
149  *
150  * \param[in] should_match_rev 0: transcoder firmware revision matching the
151  * library's version is NOT required for placing
152  * the transcoder into resource pool; 1: otherwise
153  *
154  * \return
155  * NI_RETCODE_SUCCESS on success
156  * NI_RETCODE_FAILURE on failure
157  *
158  ******************************************************************************/
159 ni_retcode_t ni_rsrc_refresh(int should_match_rev)
160 {
161  char xcoder_dev_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = {0};
162  int xcoder_dev_count = 0;
163  char curr_dev_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = {0};
164  int curr_dev_count = 0;
165  int i = 0;
166  ni_device_t *saved_coders = NULL;
167  char **xcoder_refresh_dev_names = NULL;
168  int xcoder_refresh_dev_count = 0;
169  saved_coders = (ni_device_t *)malloc(sizeof(ni_device_t));
170  if (!saved_coders)
171  {
172  ni_log(NI_LOG_ERROR, "ERROR %s() failed to malloc memory: %s\n",
173  __func__, strerror(NI_ERRNO));
174  return NI_RETCODE_FAILURE;
175  }
176  memset(saved_coders, 0, sizeof(ni_device_t));
177 
178  // retrieve saved info from resource pool at start up
179  if (NI_RETCODE_SUCCESS ==
182  saved_coders->xcoders[NI_DEVICE_TYPE_ENCODER],
183  &(saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER])))
184  {
185  for (i = 0; i < saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
186  i++)
187  {
188  strcpy(xcoder_dev_names[i],
189  saved_coders->xcoders[NI_DEVICE_TYPE_ENCODER][i]
190  .dev_name);
191  }
192  xcoder_dev_count =
193  saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
194 #ifdef XCODER_311
195  ni_log(NI_LOG_DEBUG,"%d devices retrieved from current pool at start up\n",
196  xcoder_dev_count);
197 #else
198  ni_log(NI_LOG_INFO,"%d devices retrieved from current pool at start up\n",
199  xcoder_dev_count);
200 #endif
201 
202  } else
203  {
204  ni_log(NI_LOG_ERROR, "Error retrieving from current pool at start "
205  "up\n");
206  }
207  free(saved_coders);
208 
209  if (xcoder_dev_count > 0)
210  {
211  xcoder_refresh_dev_names = (char **)malloc(xcoder_dev_count *
212  sizeof(char *));
213  for (i = 0; i < xcoder_dev_count; i++)
214  {
215  xcoder_refresh_dev_names[i] = (char *)malloc(NI_MAX_DEVICE_NAME_LEN);
216  strcpy(xcoder_refresh_dev_names[i], xcoder_dev_names[i]);
217  }
218  xcoder_refresh_dev_count = xcoder_dev_count;
219  }
220  curr_dev_count =
222  xcoder_refresh_dev_names, xcoder_refresh_dev_count);
223  if (0 == curr_dev_count)
224  {
225  ni_log(NI_LOG_ERROR, "No devices found on the host\n");
226  }
227  int devices_removed = 0;
228  int devices_added = 0;
229  // remove from resource pool any device that is not available now
230  for (i = 0; i < xcoder_dev_count; i++)
231  {
232  if (!is_str_in_str_array(xcoder_dev_names[i], curr_dev_names,
233  curr_dev_count))
234  {
236  "\n\n%d. %s NOT in current scanned list, removing !\n", i,
237  xcoder_dev_names[i]);
238  if (NI_RETCODE_SUCCESS ==
239  ni_rsrc_remove_device(xcoder_dev_names[i]))
240  {
241  ni_log(NI_LOG_INFO, "%s deleted successfully !\n",
242  xcoder_dev_names[i]);
243  devices_removed++;
244  } else
245  {
246  ni_log(NI_LOG_ERROR, "%s failed to delete !\n",
247  xcoder_dev_names[i]);
248  }
249  }
250  }
251 
252  // and add into resource pool any newly discoved ones
253  for (i = 0; i < curr_dev_count; i++)
254  {
255  if (!is_str_in_str_array(curr_dev_names[i], xcoder_dev_names,
256  xcoder_dev_count))
257  {
258  ni_log(NI_LOG_INFO, "\n\n%s NOT in previous list, adding !\n",
259  curr_dev_names[i]);
260  if (NI_RETCODE_SUCCESS ==
261  ni_rsrc_add_device(curr_dev_names[i], should_match_rev))
262  {
263  devices_added++;
264  ni_log(NI_LOG_INFO, "%s added successfully !\n", curr_dev_names[i]);
265  } else
266  {
267  ni_log(NI_LOG_ERROR, "%s failed to add !\n", curr_dev_names[i]);
268  }
269  }
270  }
271 
272  if (devices_added != devices_removed)
273  {
274  ni_log(NI_LOG_ERROR, "Total devices added %d removed %d\n",devices_added,
275  devices_removed);
276  for (i = 0; i < xcoder_dev_count; i++)
277  {
278  ni_log(NI_LOG_ERROR, "Previous device %s\n", xcoder_dev_names[i]);
279  }
280  for (i = 0; i < curr_dev_count; i++)
281  {
282  ni_log(NI_LOG_ERROR, "Current device %s\n", curr_dev_names[i]);
283  }
284  }
285  if (xcoder_refresh_dev_names) {
286  for (i = 0; i < xcoder_refresh_dev_count; i++)
287  free(xcoder_refresh_dev_names[i]);
288  free(xcoder_refresh_dev_names);
289  xcoder_refresh_dev_names = NULL;
290  }
291  return NI_RETCODE_SUCCESS;
292 }
293 
294 #ifdef _ANDROID
295 
296 #include "ni_rsrc_api_android.h"
297 
298 android::sp<INidec> service = NULL;
299 
300 /*!*****************************************************************************
301  * \brief Init android net.int.SharedBuffer service for binder using.
302  *
303  * \param none
304  *
305  * \return service (= 0) if get service , < 0 otherwise
306  *
307  ******************************************************************************/
309 {
310  if (service == NULL)
311  {
312  service = INidec::tryGetService();
313  if (service == nullptr)
314  {
315  ni_log(NI_LOG_ERROR, "Failed to get Netint service, maybe it's not launched\n");
316  return -2;
317  }
318  }
319  return 0;
320 }
321 
322 #endif
323 
324 #ifdef _WIN32
325 
326 /*!******************************************************************************
327  * \brief Scans system for all NVMe devices and returns the system device
328  * names to the user which were identified as NETINT transcoder deivices.
329  * Names are suitable for OpenFile api usage afterwards
330  * This function had been replaced by ni_rsrc_get_local_device_list2
331  * This function can't be callback with multi thread
332  *
333  *
334  * \param[out] ni_devices List of device names identified as NETINT NVMe transcoders
335  * \param[in] max_handles Max number of device names to return
336  *
337  * \return Number of devices found if successful operation completed
338  * 0 if no NETINT NVMe transcoder devices were found
339  * NI_RETCODE_ERROR_MEM_ALOC if memory allocation failed
340  *******************************************************************************/
342  char ni_devices[][NI_MAX_DEVICE_NAME_LEN],
343  int max_handles
344 )
345 {
346  if ((ni_devices == NULL)||(max_handles == 0))
347  {
348  ni_log(NI_LOG_ERROR, "Error with input parameters\n");
349  return 0;
350  }
351  return ni_rsrc_enumerate_devices(ni_devices, max_handles);
352 }
353 
354 /*!*****************************************************************************
355  * \brief Scans system for all NVMe devices and returns the system device
356  * names to the user which were identified as NETINT transcoder
357  * devices. Names are suitable for resource management API usage
358  * afterwards
359  * This function had replaced ni_rsrc_get_local_device_list
360  * This function can be callback with multi thread
361  *
362  * \param[out] ni_devices List of device names identified as NETINT NVMe
363  * transcoders
364  * \param[in] max_handles Max number of device names to return
365  * \param[in] xcoder_refresh_dev_names Xcoder fresh device name
366  * \param[in] xcoder_refresh_dev_count Xcoder fresh device number count
367  *
368  * \return Number of devices found. 0 if unsucessful.
369  ******************************************************************************/
371  int max_handles, char **xcoder_refresh_dev_names,
372  int xcoder_refresh_dev_count)
373 {
374  if ((ni_devices == NULL)||(max_handles == 0))
375  {
376  ni_log(NI_LOG_ERROR, "Error with input parameters\n");
377  return 0;
378  }
379  return ni_rsrc_enumerate_devices(ni_devices, max_handles);
380 }
381 
382 /*!******************************************************************************
383  * \brief
384  *
385  * \param
386  *
387  * \return
388  *******************************************************************************/
390 {
391  ni_device_queue_t* p_device_queue = NULL;
392  ni_device_pool_t* p_device_pool = NULL;
393  HANDLE map_file_handle = NULL;
394  HANDLE mutex_handle = NULL;
395 
396  //Create a mutex for protecting the memory area
397  mutex_handle = CreateMutex(NULL, // default security attributes
398  FALSE, // initially owned
399  CODERS_LCK_NAME // unnamed mutex
400  );
401 
402  if (NULL == mutex_handle)
403  {
404  ni_log(NI_LOG_ERROR, "CreateMutex %s failed: %d\n", CODERS_LCK_NAME,
405  NI_ERRNO);
406  return NULL;
407  }
408 
409  if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
410  {
411  ni_log(NI_LOG_ERROR, "ERROR: Failed to obtain mutex: %p\n", mutex_handle);
412  }
413 
414  map_file_handle = OpenFileMapping(
415  FILE_MAP_ALL_ACCESS, // read/write access
416  FALSE, // do not inherit the name
417  CODERS_SHM_NAME // name of mapping object
418  );
419 
420  if (NULL == map_file_handle)
421  {
422  ReleaseMutex(mutex_handle);
423  ni_log(NI_LOG_ERROR, "Could not open file mapping object %s, error: %d\n",
425  return NULL;
426  }
427 
428  p_device_queue = ( ni_device_queue_t*)MapViewOfFile(
429  map_file_handle, // handle to map object
430  FILE_MAP_ALL_ACCESS, // read/write permission
431  0,
432  0,
433  sizeof(ni_device_queue_t)
434  );
435 
436  if (NULL == p_device_queue)
437  {
438  ReleaseMutex(mutex_handle);
439  CloseHandle(map_file_handle);
440  return NULL;
441  }
442 
443  p_device_pool = (ni_device_pool_t *)malloc(sizeof(ni_device_pool_t));
444  if (NULL == p_device_pool)
445  {
446  ni_log(NI_LOG_ERROR, "ERROR %s() malloc() ni_device_pool_t: %s\n", __func__,
447  strerror(NI_ERRNO));
448  UnmapViewOfFile(p_device_queue);
449  }
450  else
451  {
452  p_device_pool->lock = mutex_handle;
453  p_device_pool->p_device_queue = p_device_queue;
454  }
455 
456  ReleaseMutex(mutex_handle);
457  CloseHandle(map_file_handle);
458  return p_device_pool;
459 }
460 
461 /*!******************************************************************************
462  * \brief Initialize and create all resources required to work with NETINT NVMe
463  * transcoder devices. This is a high level API function which is used
464  * mostly with user application like FFmpeg that relies on those resources.
465  * In case of custom application integration, revised functionality might
466  * be necessary utilizing coresponding API functions.
467  *
468  * \param[in] should_match_rev 0: transcoder firmware revision matching the
469  * library's version is NOT required for placing
470  * the transcoder into resource pool; 1: otherwise
471  * timeout_seconds -1: No timeout amount, loop until init success
472  * or fail; else: timeout will fail init once reached
473  *
474  * \return
475  * NI_RETCODE_SUCCESS on success
476  * NI_RETCODE_FAILURE on failure
477  *
478  *******************************************************************************/
479 int ni_rsrc_init(int should_match_rev, int timeout_seconds)
480 {
481  char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = { 0 };
482  char api_version[5];
483  int number_of_devices = 0;
484  uint32_t runtime = 0;
485  while (0 == number_of_devices)
486  {
487  number_of_devices = ni_rsrc_get_local_device_list2(device_names, NI_MAX_DEVICE_CNT,
488  NULL, 0);
489 
490  if (NI_RETCODE_ERROR_MEM_ALOC == number_of_devices)
491  {
492  ni_log(NI_LOG_FATAL, "FATAL: memory allocation failed\n");
493  return NI_RETCODE_FAILURE;
494  }
495  else if (0 == number_of_devices)
496  {
497  ni_log(NI_LOG_INFO, "Quadra devices not ready\n");
499  {
500  ni_log(NI_LOG_ERROR, "User requested to stop checking\n");
501  return NI_RETCODE_FAILURE;
502  }
503  if (timeout_seconds == 0) {
504  ni_log(NI_LOG_ERROR, "Quadra devices not ready "
505  "and exit without wait\n");
507  }
508  runtime += 1;
509  Sleep(1 * 1000);
510  if (runtime >= (uint32_t)timeout_seconds)
511  {
512  ni_log(NI_LOG_ERROR, "Timeout reached at %d seconds! Failing\n",
513  runtime);
515  }
516  }
517  }
518 
520  api_version);
521  ni_log(NI_LOG_INFO, "Compatible FW API version: %s\n", api_version);
522 
523  return ni_rsrc_init_priv(should_match_rev, number_of_devices, device_names);
524 }
525 
526 
527 /*!******************************************************************************
528 * \brief Allocates and returns a pointer to ni_device_context_t struct
529 * based on provided device_type and guid.
530 * To be used for load update and codec query.
531 *
532 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
533 * \param[in] guid GUID of the encoder or decoder device
534 *
535 * \return pointer to ni_device_context_t if found, NULL otherwise
536 *
537 * Note: The returned ni_device_context_t content is not supposed to be used by
538 * caller directly: should only be passed to API in the subsequent
539 * calls; also after its use, the context should be released by
540 * calling ni_rsrc_free_device_context.
541 *******************************************************************************/
543 {
544  char shm_name[32] = { 0 };
545  char lck_name[32] = { 0 };
546  ni_device_context_t* p_device_context = NULL;
547  ni_device_info_t* p_device_queue = NULL;
548  HANDLE map_file_handle = NULL;
549  HANDLE mutex_handle = NULL;
550 
552  ni_rsrc_get_shm_name(device_type, guid, shm_name, sizeof(shm_name));
553  ni_rsrc_get_lock_name(device_type, guid, lck_name, sizeof(lck_name));
554  //Create a mutex for protecting the memory area
555  mutex_handle = CreateMutex(NULL, // default security attributes
556  FALSE, // initially owned
557  lck_name); // unnamed mutex
558 
559  if (NULL == mutex_handle)
560  {
561  ni_log(NI_LOG_ERROR, "CreateMutex error: %d\n", NI_ERRNO);
562  p_device_context = NULL;
563  LRETURN;
564  }
565 
566  if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
567  {
568  ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_get_device_context() failed to "
569  "obtain mutex: %p\n", mutex_handle);
570  }
571 
572  map_file_handle = OpenFileMapping(
573  FILE_MAP_ALL_ACCESS, // read/write access
574  FALSE, // do not inherit the name
575  (LPCSTR)shm_name
576  ); // name of mapping object
577 
578  if (NULL == map_file_handle)
579  {
580  ni_log(NI_LOG_ERROR, "Could not open file mapping object %s, error: %d.\n",
581  shm_name, NI_ERRNO);
582  p_device_context = NULL;
583  LRETURN;
584  }
585 
586  p_device_queue = (ni_device_info_t*)MapViewOfFile(
587  map_file_handle, // handle to map object
588  FILE_MAP_ALL_ACCESS, // read/write permission
589  0,
590  0,
591  sizeof(ni_device_info_t)
592  );
593 
594  if (NULL == p_device_queue)
595  {
596  ni_log(NI_LOG_ERROR, "Could not map view of file, p_last error (%d).\n",
597  NI_ERRNO);
599  p_device_context = NULL;
600  LRETURN;
601  }
602 
603  p_device_context = (ni_device_context_t *)malloc(sizeof(ni_device_context_t));
604  if (NULL == p_device_context)
605  {
606  ni_log(NI_LOG_ERROR, "ERROR %s() malloc() ni_device_context_t: %s\n",
607  __func__, strerror(NI_ERRNO));
608  p_device_context = NULL;
609  LRETURN;
610  }
611 
612  strncpy(p_device_context->shm_name, shm_name, sizeof(p_device_context->shm_name));
613  p_device_context->lock = mutex_handle;
614  p_device_context->p_device_info = p_device_queue;
615 
616 END:
617 
618  if (NULL == p_device_context)
619  {
620  if (NULL != p_device_queue)
621  {
622  UnmapViewOfFile(p_device_queue);
623  }
624  if (NULL != mutex_handle)
625  {
626  ReleaseMutex(mutex_handle);
627  CloseHandle(mutex_handle);
628  }
629 
630  if (NULL != map_file_handle)
631  {
632  CloseHandle(map_file_handle);
633  }
634  } else
635  {
636  ReleaseMutex(mutex_handle);
637  CloseHandle(map_file_handle);
638  }
639 
640  return p_device_context;
641 }
642 
643 #elif __linux__ || __APPLE__
644 #if __APPLE__
645 #define DEV_NAME_PREFIX "rdisk"
646 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
647 #define DEV_NAME_PREFIX "vd"
648 #else
649 #define DEV_NAME_PREFIX "nvme"
650 #endif
651 
652 /*!*****************************************************************************
653  * \brief Scans system for all NVMe devices and returns the system device
654  * names to the user which were identified as NETINT transcoder
655  * devices. Names are suitable for resource management API usage
656  * afterwards
657  * This function had been replaced by ni_rsrc_get_local_device_list2
658  * This function can't be callback with multi thread
659  *
660  * \param[out] ni_devices List of device names identified as NETINT NVMe
661  * transcoders
662  * \param[in] max_handles Max number of device names to return
663  *
664  * \return Number of devices found. 0 if unsucessful.
665  ******************************************************************************/
667  int max_handles)
668 {
669  /* list all XCoder devices under /dev/.. */
670 #if defined(_ANDROID) || defined(__OPENHARMONY__)
671 #define ANDROID_MAX_DIR_NUM 2
672  int android_dir_num = 0;
673  const char* dir_name_array[ANDROID_MAX_DIR_NUM];
674  dir_name_array[0] = "/dev";
675  dir_name_array[1] = "/dev/block";
676 #else
677  const char* dir_name = "/dev";
678 #endif
679  int i, xcoder_device_cnt = 0;
680  DIR* FD;
681  struct dirent* in_file;
682  ni_device_info_t device_info;
683  ni_device_capability_t device_capabilites;
684  ni_device_handle_t dev_handle = NI_INVALID_DEVICE_HANDLE;
685  ni_retcode_t rc;
686  uint32_t tmp_io_size;
687  g_device_in_ctxt = false;
688 
689  if ((ni_devices == NULL)||(max_handles == 0))
690  {
691  ni_log(NI_LOG_ERROR, "ERROR: bad input parameters\n");
692  return 0;
693  }
694 
695  int nvme_dev_cnt = 0;
696  char nvme_devices[200][NI_MAX_DEVICE_NAME_LEN];
697 
698  regex_t regex;
699  // GNU ERE not support /d, use [0-9] or [[:digit:]] instead
700 #if __APPLE__
701  const char *pattern = "^rdisk[0-9]+$";
702 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
703  const char *pattern = "^vd[a-z]$";
704 #else
705  const char *pattern = "^nvme[0-9]+(c[0-9]+)?n[0-9]+$";
706 #endif
707  // Compile the regular expression
708  if(regcomp(&regex, pattern, REG_EXTENDED | REG_NOSUB)) {
709  ni_log(NI_LOG_ERROR, "Could not compile regex\n");
710  return 0;
711  }
712 
713 #if defined(_ANDROID) || defined(__OPENHARMONY__)
714  //find XCoder devices in folders of dir_name_array until find in one folder
715  //or not find in any folders
716  while(xcoder_device_cnt == 0 && android_dir_num < ANDROID_MAX_DIR_NUM)
717  {
718  const char *dir_name = dir_name_array[android_dir_num];
719  ++android_dir_num;
720 
721  nvme_dev_cnt = 0;
722  g_device_in_ctxt = false;
723  dev_handle = NI_INVALID_DEVICE_HANDLE;
724  // g_dev_handle = NI_INVALID_DEVICE_HANDLE;
725  size_t size_of_nvme_devices_x = sizeof(nvme_devices)/sizeof(nvme_devices[0]);
726  for(size_t dimx = 0; dimx < size_of_nvme_devices_x; ++dimx)
727  {
728  memset(nvme_devices[dimx], 0, sizeof(nvme_devices[0]));
729  }
730  //}//while brace below will end this
731 #endif
732 
733  if (NULL == (FD = opendir(dir_name)))
734  {
735 
736 #if defined(_ANDROID) || defined(__OPENHARMONY__)
737  ni_log(NI_LOG_INFO, "Failed to open directory %s\n", dir_name);
738  if(android_dir_num < ANDROID_MAX_DIR_NUM)
739  {
740  continue;
741  }
742  regfree(&regex);
743  return 0;
744 #else
745  ni_log(NI_LOG_ERROR, "ERROR: failed to open directory %s\n", dir_name);
746  regfree(&regex);
747  return 0;
748 #endif
749  }
750 
751  /* collect all the available NVMe devices and sort */
752  while ((in_file = readdir(FD)))
753  {
755  if (!strcmp(in_file->d_name, ".") || !strcmp(in_file->d_name, ".."))
756  {
757  continue;
758  }
759 
760  /* pick only those files with name nvmeX where X consists of 1-n
761  digits */
762  if (!strncmp(in_file->d_name, DEV_NAME_PREFIX, strlen(DEV_NAME_PREFIX)))
763  {
764  if (nvme_dev_cnt < 200)
765  {
766  int write_len = snprintf(nvme_devices[nvme_dev_cnt],
767  NI_MAX_DEVICE_NAME_LEN - 6, "%s/%s",
768  dir_name, in_file->d_name);
769  if (write_len < 0 || write_len >= (NI_MAX_DEVICE_NAME_LEN - 6))
770  {
772  "ERROR: failed to copy device %d name %s\n",
773  nvme_dev_cnt, in_file->d_name);
774  }
775  nvme_dev_cnt++;
776  }
777  int skip_this = 0;
778  skip_this = regexec(&regex, in_file->d_name, 0, NULL, 0);
779  ni_log(NI_LOG_TRACE, "name: %s skip %d\n", in_file->d_name, skip_this);
780 
781  if (!skip_this)
782  {
783  memset(&device_info, 0, sizeof(ni_device_info_t));
784  if (snprintf(device_info.dev_name, NI_MAX_DEVICE_NAME_LEN - 6,
785  "%s/%s", dir_name, in_file->d_name) < 0)
786  {
788  "ERROR: failed an snprintf() in "
789  "ni_rsrc_get_local_device_list()\n");
790  continue;
791  }
792  strncpy(device_info.blk_name, device_info.dev_name,
794  memset(&device_capabilites, 0, sizeof(ni_device_capability_t));
795 
796  g_device_in_ctxt = false;
797  for (int j = 0; j < g_xcoder_refresh_dev_count; j++)
798  {
799  if (0 ==
800  strcmp(device_info.dev_name,
802  {
803  g_device_in_ctxt = true;
804  break;
805  }
806  }
807  if (NI_RETCODE_SUCCESS != ni_check_dev_name(device_info.dev_name))
808  {
809  continue;
810  }
812  {
813  continue;
814  }
815  dev_handle = ni_device_open(device_info.dev_name, &tmp_io_size);
816 
817  if (NI_INVALID_DEVICE_HANDLE != dev_handle)
818  {
819  g_dev_handle = dev_handle;
820  rc = ni_device_capability_query(dev_handle,
821  &device_capabilites);
822  if (NI_RETCODE_SUCCESS == rc)
823  {
824  if (is_supported_xcoder(
825  device_capabilites.device_is_xcoder))
826  {
827  ni_devices[xcoder_device_cnt][0] = '\0';
828  strcat(ni_devices[xcoder_device_cnt],
829  device_info.dev_name);
830  xcoder_device_cnt++;
831  }
832  }
833  g_dev_handle = NI_INVALID_DEVICE_HANDLE;
834 
835  ni_device_close(dev_handle);
836  }
837  }
838  }
839  if ((NI_MAX_DEVICE_CNT <= xcoder_device_cnt) ||
840  (max_handles <= xcoder_device_cnt))
841  {
843  "Disregarding some Netint devices on system over "
844  "limit of NI_MAX_DEVICE_CNT(%d) or max_handles(%d)\n",
845  NI_MAX_DEVICE_CNT, max_handles);
846  break;
847  }
848  }
849  closedir(FD);
850 
851 #if defined(_ANDROID) || defined(__OPENHARMONY__)
852  }//while brace
853 #endif
854 
855  regfree(&regex);
856 
857  qsort(ni_devices, xcoder_device_cnt, (size_t)NI_MAX_DEVICE_NAME_LEN,
859  if (0 == xcoder_device_cnt)
860  {
861  ni_log(NI_LOG_INFO, "Found %d NVMe devices on system, none of them xcoder\n", nvme_dev_cnt);
862  for (i = 0; i < nvme_dev_cnt; i++)
863  {
864  ni_log(NI_LOG_INFO, "NVMe device %d: %s\n", i, nvme_devices[i]);
865  }
866  }
867  g_device_in_ctxt = false;
868  g_dev_handle = NI_INVALID_DEVICE_HANDLE;
869 
870  return xcoder_device_cnt;
871 }
872 
873 /*!*****************************************************************************
874  * \brief Scans system for all NVMe devices and returns the system device
875  * names to the user which were identified as NETINT transcoder
876  * devices. Names are suitable for resource management API usage
877  * afterwards
878  * This function had replaced ni_rsrc_get_local_device_list
879  * This function can be callback with multi thread
880  *
881  * \param[out] ni_devices List of device names identified as NETINT NVMe
882  * transcoders
883  * \param[in] max_handles Max number of device names to return
884  * \param[in] xcoder_refresh_dev_names Xcoder fresh device name
885  * \param[in] xcoder_refresh_dev_count Xcoder fresh device number count
886  *
887  * \return Number of devices found. 0 if unsucessful.
888  ******************************************************************************/
890  int max_handles, char **xcoder_refresh_dev_names,
891  int xcoder_refresh_dev_count)
892 {
893  /* list all XCoder devices under /dev/.. */
894 #ifdef _ANDROID
895 #define ANDROID_MAX_DIR_NUM 2
896  int android_dir_num = 0;
897  const char* dir_name_array[ANDROID_MAX_DIR_NUM];
898  dir_name_array[0] = "/dev";
899  dir_name_array[1] = "/dev/block";
900 #else
901  const char* dir_name = "/dev";
902 #endif
903  int i, xcoder_device_cnt = 0;
904  DIR* FD;
905  struct dirent* in_file;
906  ni_device_info_t device_info;
907  ni_device_capability_t device_capabilites;
908  ni_device_handle_t dev_handle = NI_INVALID_DEVICE_HANDLE;
909  ni_retcode_t rc;
910  uint32_t tmp_io_size;
911  bool device_in_ctxt = false;
912 
913  if ((ni_devices == NULL)||(max_handles == 0))
914  {
915  ni_log(NI_LOG_ERROR, "ERROR: bad input parameters\n");
916  return 0;
917  }
918 
919  int nvme_dev_cnt = 0;
920  char nvme_devices[200][NI_MAX_DEVICE_NAME_LEN];
921 
922  regex_t regex;
923  // GNU ERE not support /d, use [0-9] or [[:digit:]] instead
924 #if __APPLE__
925  const char *pattern = "^rdisk[0-9]+$";
926 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
927  const char *pattern = "^vd[a-z]$";
928 #else
929  const char *pattern = "^nvme[0-9]+(c[0-9]+)?n[0-9]+$";
930 #endif
931  // Compile the regular expression
932  if(regcomp(&regex, pattern, REG_EXTENDED | REG_NOSUB)) {
933  ni_log(NI_LOG_ERROR, "Could not compile regex\n");
934  return 0;
935  }
936 
937 #ifdef _ANDROID
938  //find XCoder devices in folders of dir_name_array until find in one folder
939  //or not find in any folders
940  while(xcoder_device_cnt == 0 && android_dir_num < ANDROID_MAX_DIR_NUM)
941  {
942  const char *dir_name = dir_name_array[android_dir_num];
943  ++android_dir_num;
944 
945  nvme_dev_cnt = 0;
946  device_in_ctxt = false;
947  dev_handle = NI_INVALID_DEVICE_HANDLE;
948  // g_dev_handle = NI_INVALID_DEVICE_HANDLE;
949  size_t size_of_nvme_devices_x = sizeof(nvme_devices)/sizeof(nvme_devices[0]);
950  for(size_t dimx = 0; dimx < size_of_nvme_devices_x; ++dimx)
951  {
952  memset(nvme_devices[dimx], 0, sizeof(nvme_devices[0]));
953  }
954  //}//while brace below will end this
955 #endif
956 
957  if (NULL == (FD = opendir(dir_name)))
958  {
959 
960 #ifdef _ANDROID
961  ni_log(NI_LOG_INFO, "Failed to open directory %s\n", dir_name);
962  if(android_dir_num < ANDROID_MAX_DIR_NUM)
963  {
964  continue;
965  }
966  regfree(&regex);
967  return 0;
968 #else
969  ni_log(NI_LOG_ERROR, "ERROR: failed to open directory %s\n", dir_name);
970  regfree(&regex);
971  return 0;
972 #endif
973  }
974 
975  /* collect all the available NVMe devices and sort */
976  while ((in_file = readdir(FD)))
977  {
979  if (!strcmp(in_file->d_name, ".") || !strcmp(in_file->d_name, ".."))
980  {
981  continue;
982  }
983 
984  /* pick only those files with name nvmeX where X consists of 1-n
985  digits */
986  if (!strncmp(in_file->d_name, DEV_NAME_PREFIX, strlen(DEV_NAME_PREFIX)))
987  {
988  if (nvme_dev_cnt < 200)
989  {
990  int write_len = snprintf(nvme_devices[nvme_dev_cnt],
991  NI_MAX_DEVICE_NAME_LEN - 6, "%s/%s",
992  dir_name, in_file->d_name);
993  if (write_len < 0 || write_len >= (NI_MAX_DEVICE_NAME_LEN - 6))
994  {
996  "ERROR: failed to copy device %d name %s\n",
997  nvme_dev_cnt, in_file->d_name);
998  }
999  nvme_dev_cnt++;
1000  }
1001  int skip_this = 0;
1002  skip_this = regexec(&regex, in_file->d_name, 0, NULL, 0);
1003  ni_log(NI_LOG_TRACE, "name: %s skip %d\n", in_file->d_name, skip_this);
1004 
1005  if (!skip_this)
1006  {
1007  memset(&device_info, 0, sizeof(ni_device_info_t));
1008  if (snprintf(device_info.dev_name, NI_MAX_DEVICE_NAME_LEN - 6,
1009  "%s/%s", dir_name, in_file->d_name) < 0)
1010  {
1012  "ERROR: failed an snprintf() in "
1013  "ni_rsrc_get_local_device_list2()\n");
1014  continue;
1015  }
1016  strncpy(device_info.blk_name, device_info.dev_name,
1018  memset(&device_capabilites, 0, sizeof(ni_device_capability_t));
1019 
1020  device_in_ctxt = false;
1021  for (int j = 0; j < xcoder_refresh_dev_count; j++)
1022  {
1023  if (0 ==
1024  strcmp(device_info.dev_name,
1025  xcoder_refresh_dev_names[j]))
1026  {
1027  device_in_ctxt = true;
1028  break;
1029  }
1030  }
1031  if (NI_RETCODE_SUCCESS != ni_check_dev_name(device_info.dev_name))
1032  {
1033  continue;
1034  }
1036  {
1037  continue;
1038  }
1039  dev_handle = ni_device_open(device_info.dev_name, &tmp_io_size);
1040 
1041  if (NI_INVALID_DEVICE_HANDLE != dev_handle)
1042  {
1043  rc = ni_device_capability_query2(dev_handle,
1044  &device_capabilites, device_in_ctxt);
1045  if (NI_RETCODE_SUCCESS == rc)
1046  {
1047  if (is_supported_xcoder(
1048  device_capabilites.device_is_xcoder))
1049  {
1050  ni_devices[xcoder_device_cnt][0] = '\0';
1051  strcat(ni_devices[xcoder_device_cnt],
1052  device_info.dev_name);
1053  xcoder_device_cnt++;
1054  }
1055  }
1056 
1057  ni_device_close(dev_handle);
1058  }
1059  }
1060  }
1061  if ((NI_MAX_DEVICE_CNT <= xcoder_device_cnt) ||
1062  (max_handles <= xcoder_device_cnt))
1063  {
1065  "Disregarding some Netint devices on system over "
1066  "limit of NI_MAX_DEVICE_CNT(%d) or max_handles(%d)\n",
1067  NI_MAX_DEVICE_CNT, max_handles);
1068  break;
1069  }
1070  }
1071  closedir(FD);
1072 
1073 #ifdef _ANDROID
1074  }//while brace
1075 #endif
1076 
1077  regfree(&regex);
1078 
1079  qsort(ni_devices, xcoder_device_cnt, (size_t)NI_MAX_DEVICE_NAME_LEN,
1080  ni_rsrc_strcmp);
1081  if (0 == xcoder_device_cnt)
1082  {
1083  ni_log(NI_LOG_INFO, "Found %d NVMe devices on system, none of them xcoder\n", nvme_dev_cnt);
1084  for (i = 0; i < nvme_dev_cnt; i++)
1085  {
1086  ni_log(NI_LOG_INFO, "NVMe device %d: %s\n", i, nvme_devices[i]);
1087  }
1088  }
1089 
1090  return xcoder_device_cnt;
1091 }
1092 
1093 /*!*****************************************************************************
1094  * \brief Create and return the allocated ni_device_pool_t struct
1095  *
1096  * \param None
1097  *
1098  * \return Pointer to ni_device_pool_t struct on success, or NULL on failure
1099  *******************************************************************************/
1101 {
1102  int shm_fd = -1;
1103  ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1104  int flags = O_RDWR | O_CLOEXEC;
1105  mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1106  ni_device_queue_t* p_device_queue = NULL;
1107  ni_lock_handle_t lock;
1108  ni_device_pool_t* p_device_pool = NULL;
1109 
1110  if (ni_rsrc_try_get_shm_lock(CODERS_LCK_NAME,
1111  flags, mode, (int *)&lock) < 0) {
1112  ni_log(NI_LOG_ERROR, "%s: Failed to get lock\n", __func__);
1113  return NULL;
1114  }
1115 
1116  if (ni_rsrc_open_shm(CODERS_SHM_NAME,
1117  sizeof(ni_device_queue_t),
1118  &state,
1119  (int *)&shm_fd) < 0) {
1120  ni_log(NI_LOG_ERROR, "%s: Failed to ni_rsrc_open_shm\n", __func__);
1121  LRETURN;
1122  }
1123 
1124  if ((ni_rsrc_mmap_shm(CODERS_SHM_NAME,
1125  shm_fd,
1126  sizeof(ni_device_queue_t),
1127  (void **)&p_device_queue)) < 0) {
1128  ni_log(NI_LOG_ERROR, "%s(): Failed to ni_rsrc_mmap_shm\n", __func__);
1129  LRETURN;
1130  }
1131 
1132  p_device_pool = (ni_device_pool_t *)malloc(sizeof(ni_device_pool_t));
1133  if (! p_device_pool) {
1134  ni_log(NI_LOG_ERROR, "ERROR %s() malloc() ni_device_pool_t: %s\n",
1135  __func__, strerror(NI_ERRNO));
1136  ni_rsrc_munmap_shm((void *)p_device_queue, sizeof(ni_device_queue_t));
1137  } else {
1138  p_device_pool->lock = lock;
1139  p_device_pool->p_device_queue = p_device_queue;
1140  }
1141 
1142 END:
1143  lockf(lock, F_ULOCK, 0);
1144 
1145  if (NULL == p_device_pool) {
1146  close(lock);
1147  }
1148 
1149 #ifndef __OPENHARMONY__
1150  if (shm_fd >= 0) {
1151  close(shm_fd);
1152  }
1153 #endif
1154 
1155  return p_device_pool;
1156 }
1157 
1158 /*!******************************************************************************
1159  * \brief Initialize and create all resources required to work with NETINT NVMe
1160  * transcoder devices. This is a high level API function which is used
1161  * mostly with user application like FFmpeg that relies on those resources.
1162  * In case of custom application integration, revised functionality might
1163  * be necessary utilizing corresponding API functions.
1164  *
1165  * \param[in] should_match_rev 0: transcoder firmware revision matching the
1166  * library's version is NOT required for placing
1167  * the transcoder into resource pool; 1: otherwise
1168  * timeout_seconds -1: No timeout amount, loop until init success
1169  * or fail; else: timeout will fail init once reached
1170  *
1171  * \return
1172  * NI_RETCODE_SUCCESS on success
1173  * NI_RETCODE_FAILURE on failure
1174  *
1175  *******************************************************************************/
1176 int ni_rsrc_init(int should_match_rev, int timeout_seconds)
1177 {
1178  char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN];
1179  char api_version[5];
1180  int number_of_devices;
1181  uint32_t runtime;
1182  int limit_depth = 3;
1183 
1184  runtime = 0;
1185  while (1)
1186  {
1187  number_of_devices = ni_rsrc_get_local_device_list2(device_names,
1189  NULL, 0);
1190  if (number_of_devices > 0)
1191  {
1192  break;
1193  }
1194  else
1195  {
1196  ni_log(NI_LOG_INFO, "Quadra devices not ready\n");
1198  {
1199  ni_log(NI_LOG_ERROR, "User requested to stop checking\n");
1200  return 1;
1201  }
1202  if (timeout_seconds == 0) {
1203  ni_log(NI_LOG_ERROR, "Quadra devices not ready "
1204  "and exit without wait\n");
1206  }
1207  sleep(1);
1208  runtime += 1;
1209  if (runtime >= (uint32_t)timeout_seconds)
1210  {
1212  "Timeout exceeded/reached after %u seconds!\n",
1213  runtime);
1215  }
1216  }
1217  }
1218 
1220  api_version);
1221  ni_log(NI_LOG_INFO, "Compatible FW API version: %s\n", api_version);
1222 
1223  return ni_rsrc_init_priv(should_match_rev, number_of_devices, device_names, limit_depth);
1224 }
1225 
1226 /*!******************************************************************************
1227 * \brief Allocates and returns a pointer to ni_device_context_t struct
1228 * based on provided device_type and guid.
1229 * To be used for load update and codec query.
1230 *
1231  * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1232  * \param[in] guid GUID of the encoder or decoder device
1233 *
1234 * \return pointer to ni_device_context_t if found, NULL otherwise
1235 *
1236 * Note: The returned ni_device_context_t content is not supposed to be used by
1237 * caller directly: should only be passed to API in the subsequent
1238 * calls; also after its use, the context should be released by
1239 * calling ni_rsrc_free_device_context.
1240 *******************************************************************************/
1242 {
1244  int shm_fd = -1;
1245  ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1246  int lock;
1247  int flags = O_RDWR | O_CLOEXEC;
1248  mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1249  char shm_name[32] = { 0 };
1250  char lck_name[32] = { 0 };
1251  ni_device_context_t *p_device_context = NULL;
1252  ni_device_info_t *p_device_queue = NULL;
1253 
1254  ni_rsrc_get_shm_name(device_type, guid, shm_name, sizeof(shm_name));
1255  ni_rsrc_get_lock_name(device_type, guid, lck_name, sizeof(lck_name));
1256 
1257  if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, &lock) < 0) {
1258  ni_log(NI_LOG_ERROR, "%s: Failed to get lock\n", __func__);
1259  return NULL;
1260  }
1261 
1262  if (ni_rsrc_open_shm(shm_name,
1263  sizeof(ni_device_info_t),
1264  &state,
1265  (int *)&shm_fd) < 0) {
1266  ni_log(NI_LOG_ERROR, "%s: Failed to ni_rsrc_open_shm\n", __func__);
1267  LRETURN;
1268  }
1269 
1270  if ((ni_rsrc_mmap_shm(shm_name,
1271  shm_fd,
1272  sizeof(ni_device_info_t),
1273  (void **)&p_device_queue)) < 0) {
1274  ni_log(NI_LOG_ERROR, "%s(): Failed to ni_rsrc_mmap_shm\n", __func__);
1275  LRETURN;
1276  }
1277 
1278  p_device_context = (ni_device_context_t *)malloc(sizeof(ni_device_context_t));
1279  if (!p_device_context) {
1280  ni_log(NI_LOG_ERROR, "ERROR %s() malloc() ni_device_context_t: %s\n",
1281  __func__, strerror(NI_ERRNO));
1282  ni_rsrc_munmap_shm((void *)p_device_queue, sizeof(ni_device_info_t));
1283  LRETURN;
1284  }
1285 
1286  strncpy(p_device_context->shm_name, shm_name, sizeof(p_device_context->shm_name));
1287  p_device_context->lock = lock;
1288  p_device_context->p_device_info = p_device_queue;
1289 
1290 END:
1291  lockf(lock, F_ULOCK, 0);
1292 
1293 #ifndef __OPENHARMONY__
1294  if (shm_fd >= 0) {
1295  close(shm_fd);
1296  }
1297 #endif
1298 
1299  return p_device_context;
1300 }
1301 #endif
1302 
1303 /*!******************************************************************************
1304  * \brief Free previously allocated device context
1305  *
1306  * \param p_device_context Pointer to previously allocated device context
1307  *
1308  * \return None
1309  *******************************************************************************/
1311 {
1312  if (p_device_context)
1313  {
1314 #ifdef _WIN32
1315  UnmapViewOfFile(p_device_context->p_device_info);
1316  ReleaseMutex(p_device_context->lock);
1317 #elif __linux__ || __APPLE__
1318  close(p_device_context->lock);
1319  ni_rsrc_munmap_shm((void *)p_device_context->p_device_info, sizeof(ni_device_info_t));
1320  ni_log(NI_LOG_DEBUG, "in %s do munmap for %s\n", __func__, p_device_context->shm_name);
1321 #endif
1322  free(p_device_context);
1323  }
1324 }
1325 
1326 /*!******************************************************************************
1327 * \brief List device(s) based on device type with full information
1328 * including s/w instances on the system.
1329 *
1330 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1331 * \param[out] p_device The device information returned.
1332 * \param[out] p_device_count The number of ni_device_info_t structs returned.
1333 *
1334 * \return
1335 * NI_RETCODE_SUCCESS
1336 * NI_RETCODE_FAILURE
1337 *
1338 * Note: Caller is responsible for allocating memory for "p_device".
1339 *******************************************************************************/
1341  ni_device_info_t *p_device_info, int * p_device_count)
1342 {
1343  int i, count;
1344  ni_device_queue_t *p_device_queue = NULL;
1345  ni_device_pool_t *p_device_pool = NULL;
1346  ni_device_context_t *p_device_context = NULL;
1348  bool b_release_pool_mtx = false;
1349 
1350  if ( (NULL == p_device_info) || (NULL == p_device_count) )
1351  {
1352  retval = NI_RETCODE_FAILURE;
1353  LRETURN;
1354  }
1355 
1356  p_device_pool = ni_rsrc_get_device_pool();
1357  if (NULL == p_device_pool)
1358  {
1359  retval = NI_RETCODE_FAILURE;
1360  LRETURN;
1361  }
1362 
1363 #ifdef _WIN32
1364  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval)
1365  {
1366  ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_list_devices() failed to obtain "
1367  "mutex: %p\n", p_device_pool->lock);
1368  retval = NI_RETCODE_FAILURE;
1369  LRETURN;
1370  }
1371 #elif __linux__ || __APPLE__
1372  lockf(p_device_pool->lock, F_LOCK, 0);
1373 #endif
1374 
1375  b_release_pool_mtx = true;
1376 
1377  p_device_queue = p_device_pool->p_device_queue;
1378  count = p_device_queue->xcoder_cnt[device_type];
1379 
1380  *p_device_count=0;
1381  for (i = 0; i < count; i++)
1382  {
1383  int guid = -1;
1384  guid = p_device_queue->xcoders[device_type][i];
1385  p_device_context = ni_rsrc_get_device_context(device_type, guid);
1386  if (p_device_context)
1387  {
1388 #ifdef _WIN32
1389  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
1390  {
1391  ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_list_devices() failed to obtain "
1392  "mutex: %p\n", p_device_context->lock);
1393  ReleaseMutex(p_device_pool->lock);
1394  retval = NI_RETCODE_FAILURE;
1395  LRETURN;
1396  }
1397 
1398  memcpy(&p_device_info[i], p_device_context->p_device_info, sizeof(ni_device_info_t));
1399  ReleaseMutex(p_device_context->lock);
1400 #elif __linux__ || __APPLE__
1401  lockf(p_device_context->lock, F_LOCK, 0);
1402  memcpy(&p_device_info[i], p_device_context->p_device_info, sizeof(ni_device_info_t));
1403  lockf(p_device_context->lock, F_ULOCK, 0);
1404 #endif
1405 
1406  ni_rsrc_free_device_context(p_device_context);
1407 
1408  (*p_device_count)++;
1409  }
1410  else
1411  {
1412  ni_log(NI_LOG_ERROR, "ERROR: cannot find decoder guid: %d\n", guid);
1413  }
1414  }
1415 
1416 END:
1417 
1418  if (b_release_pool_mtx)
1419  {
1420 #ifdef _WIN32
1421  ReleaseMutex(p_device_pool->lock);
1422 #elif __linux__ || __APPLE__
1423  lockf(p_device_pool->lock, F_ULOCK, 0);
1424 #endif
1425  }
1426 
1427  ni_rsrc_free_device_pool(p_device_pool);
1428 
1429  return retval;
1430 }
1431 
1432 /*!******************************************************************************
1433 * \brief List all devices with full information including s/w instances
1434 * on the system.
1435 
1436 * \param[out] p_device The device information returned.
1437 *
1438 * \return
1439 * NI_RETCODE_SUCCESS
1440 * NI_RETCODE_INVALID_PARAM
1441 * NI_RETCODE_FAILURE
1442 *
1443 * Note: Caller is responsible for allocating memory for "p_device".
1444 *******************************************************************************/
1446 {
1447  int k = 0;
1449 
1450  if (NULL == p_device)
1451  {
1452  retval = NI_RETCODE_INVALID_PARAM;
1453  LRETURN;
1454  }
1455 
1456  for (k = 0; k < NI_DEVICE_TYPE_XCODER_MAX; k++)
1457  {
1458  retval = ni_rsrc_list_devices((ni_device_type_t)k, p_device->xcoders[k],
1459  &(p_device->xcoder_cnt[k]));
1460  if (NI_RETCODE_FAILURE == retval)
1461  {
1462  ni_log(NI_LOG_ERROR, "ERROR: could not retrieve info for %d type "
1463  "devices\n", k);
1464  LRETURN;
1465  }
1466  }
1467 
1468 END:
1469 
1470  return retval;
1471 }
1472 
1473 /*!******************************************************************************
1474 * \brief Grabs information for every initialized and uninitialized
1475 * device.
1476 
1477 * \param list_uninitialized Flag to determine if uninitialized devices
1478 * should be grabbed.
1479 *
1480 * \return
1481 * NI_RETCODE_SUCCESS
1482 * NI_RETCODE_INVALID_PARAM
1483 * NI_RETCODE_FAILURE
1484 *
1485 * Note: Caller is responsible for allocating memory for "p_device".
1486 *******************************************************************************/
1487 ni_retcode_t ni_rsrc_list_all_devices2(ni_device_t* p_device, bool list_uninitialized)
1488 {
1490  if (!p_device)
1491  {
1492  retval = NI_RETCODE_INVALID_PARAM;
1493  return retval;
1494  }
1495 
1496  /* Grab initialized devices. */
1497 
1498  ni_log_level_t log_level = ni_log_get_level();
1499 
1500  if (list_uninitialized)
1501  {
1503  }
1504 
1505  ni_rsrc_list_all_devices(p_device);
1506 
1507  if (!list_uninitialized)
1508  {
1509  return retval;
1510  }
1511 
1512  ni_log_set_level(log_level);
1513 
1514  /* Store device names of initialized devices. */
1515 
1516  ni_device_info_t *p_dev_info;
1517  char initialized_dev_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = {0};
1518 
1519  for (int dev_index = 0;
1520  dev_index < p_device->xcoder_cnt[NI_DEVICE_TYPE_ENCODER]; dev_index++)
1521  {
1522  p_dev_info = &p_device->xcoders[NI_DEVICE_TYPE_ENCODER][dev_index];
1523  strcpy(initialized_dev_names[dev_index], p_dev_info->dev_name);
1524  }
1525 
1526  /* Retrieve uninitialized devices. */
1527 
1528  char dev_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = {0};
1529  int dev_count = ni_rsrc_get_local_device_list2(dev_names, NI_MAX_DEVICE_CNT,
1530  NULL, 0);
1531 
1532  uint32_t tmp_io_size;
1533  ni_device_capability_t capability;
1534  ni_device_handle_t fd;
1535 
1536  for (int dev_index = 0; dev_index < dev_count; dev_index++)
1537  {
1538  if (is_str_in_str_array(dev_names[dev_index],
1539  initialized_dev_names, NI_MAX_DEVICE_CNT))
1540  {
1541  continue;
1542  }
1543 
1544  fd = ni_device_open(dev_names[dev_index], &tmp_io_size);
1545  if (NI_INVALID_DEVICE_HANDLE == fd)
1546  {
1547  ni_log(NI_LOG_ERROR, "Failed to open device: %s\n",
1548  dev_names[dev_index]);
1549  return NI_RETCODE_FAILURE;
1550  }
1551 
1552  retval = ni_device_capability_query2(fd, &capability, false);
1553  if (NI_RETCODE_SUCCESS != retval)
1554  {
1555  ni_device_close(fd);
1556  ni_log(NI_LOG_ERROR, "Failed to query device capability: %s\n",
1557  dev_names[dev_index]);
1558  return retval;
1559  }
1560 
1561  for (int dev_type = 0; dev_type < NI_DEVICE_TYPE_XCODER_MAX; dev_type++)
1562  {
1563  p_device->xcoder_cnt[dev_type]++;
1564 
1565  p_dev_info = &p_device->xcoders[dev_type][dev_index];
1566  memcpy(p_dev_info->serial_number, capability.serial_number,
1567  sizeof(capability.serial_number));
1568  memcpy(p_dev_info->model_number, capability.model_number,
1569  sizeof(capability.model_number));
1570  memcpy(p_dev_info->fw_rev, capability.fw_rev,
1571  sizeof(capability.fw_rev));
1572  p_dev_info->fw_ver_compat_warning = ni_rsrc_is_fw_compat(capability.fw_rev) >= 2 ? 1 : 0;
1573  memcpy(p_dev_info->fw_branch_name, capability.fw_branch_name,
1574  sizeof(capability.fw_branch_name));
1575  memcpy(p_dev_info->fw_commit_time, capability.fw_commit_time,
1576  sizeof(capability.fw_commit_time));
1577  memcpy(p_dev_info->fw_commit_hash, capability.fw_commit_hash,
1578  sizeof(capability.fw_commit_hash));
1579  memcpy(p_dev_info->fw_build_time, capability.fw_build_time,
1580  sizeof(capability.fw_build_time));
1581  memcpy(p_dev_info->fw_build_id, capability.fw_build_id,
1582  sizeof(capability.fw_build_id));
1583  strcpy(p_dev_info->dev_name, dev_names[dev_index]);
1584  memcpy(p_dev_info->blk_name, p_dev_info->dev_name,
1585  sizeof(p_dev_info->dev_name));
1586  p_dev_info->device_type = (ni_device_type_t)dev_type;
1587  p_dev_info->module_id = -1; /* special value to indicate device is
1588  not initialized */
1589 
1590  ni_query_fl_fw_versions(fd, p_dev_info);
1591  }
1592 
1593  ni_device_close(fd);
1594  }
1595 
1596  return retval;
1597 }
1598 
1599 
1601 {
1602  int i;
1603 
1604  if (!p_device_info)
1605  {
1606  ni_log(NI_LOG_ERROR, "ERROR: Cannot print device info!\n");
1607  } else
1608  {
1609  ni_log(NI_LOG_INFO, " %s #%d\n",
1610  GET_XCODER_DEVICE_TYPE_STR(p_device_info->device_type),
1611  p_device_info->module_id);
1612  ni_log(NI_LOG_INFO, " H/W ID: %d\n", p_device_info->hw_id);
1613  ni_log(NI_LOG_INFO, " MaxNumInstances: %d\n",
1614  p_device_info->max_instance_cnt);
1615 
1616  if (NI_DEVICE_TYPE_SCALER == p_device_info->device_type)
1617  {
1618  ni_log(NI_LOG_INFO, " Capabilities:\n");
1620  " Operations: Crop (ni_quadra_crop), Scale (ni_quadra_scale), Pad "
1621  "(ni_quadra_pad), Overlay (ni_quadra_overlay)\n"
1622  " Drawbox (ni_quadra_drawbox), Rotate (ni_quadra_rotate), XStack (ni_quadra_xstack)\n");
1623  } else if (NI_DEVICE_TYPE_AI == p_device_info->device_type)
1624  {
1625  ni_log(NI_LOG_INFO, " Capabilities:\n");
1626  ni_log(
1627  NI_LOG_INFO,
1628  " Operations: ROI (ni_quadra_roi), Background Replace (ni_quadra_bg)\n");
1629  } else if (NI_DEVICE_TYPE_DECODER == p_device_info->device_type ||
1630  NI_DEVICE_TYPE_ENCODER == p_device_info->device_type)
1631  {
1632  ni_log(NI_LOG_INFO, " Max4KFps: %d\n", p_device_info->max_fps_4k);
1633  for (i = 0; i < EN_CODEC_MAX; i++)
1634  {
1635  if (EN_INVALID != p_device_info->dev_cap[i].supports_codec)
1636  {
1637  ni_log(NI_LOG_INFO, " %s ",
1638  ni_codec_format_str[p_device_info->dev_cap[i]
1639  .supports_codec]);
1640  ni_log(NI_LOG_INFO, "(%s) Capabilities:\n",
1642  p_device_info->device_type ?
1643  ni_dec_name_str[p_device_info->dev_cap[i]
1644  .supports_codec] :
1645  ni_enc_name_str[p_device_info->dev_cap[i]
1646  .supports_codec]);
1647  ni_log(NI_LOG_INFO, " MaxResolution: %dx%d\n",
1648  p_device_info->dev_cap[i].max_res_width,
1649  p_device_info->dev_cap[i].max_res_height);
1650  ni_log(NI_LOG_INFO, " MinResolution: %dx%d\n",
1651  p_device_info->dev_cap[i].min_res_width,
1652  p_device_info->dev_cap[i].min_res_height);
1653 
1654  // no profile for JPEG encode, or level for JPEG
1655  if (! (NI_DEVICE_TYPE_ENCODER == p_device_info->device_type &&
1656  EN_JPEG == p_device_info->dev_cap[i].supports_codec))
1657  {
1658  ni_log(NI_LOG_INFO, " Profiles: %s\n",
1659  p_device_info->dev_cap[i].profiles_supported);
1660  }
1661  if (EN_JPEG != p_device_info->dev_cap[i].supports_codec)
1662  {
1663  ni_log(NI_LOG_INFO, " Level: %s\n",
1664  p_device_info->dev_cap[i].level);
1665  }
1666  }
1667  }
1668  }
1669  }
1670 }
1671 
1672 /*!*****************************************************************************
1673 * \brief Print detailed capability information of all devices
1674 * on the system.
1675 
1676 * \param none
1677 *
1678 * \return none
1679 *
1680 *******************************************************************************/
1682 {
1683  ni_device_t *device = NULL;
1684  device = (ni_device_t *)malloc(sizeof(ni_device_t));
1685  if (!device)
1686  {
1687  ni_log(NI_LOG_ERROR, "ERROR %s() failed to malloc memory: %s\n",
1688  __func__, strerror(NI_ERRNO));
1689  return;
1690  }
1691  memset(device, 0, sizeof(ni_device_t));
1692 
1694  {
1695  free(device);
1696  return;
1697  }
1698 
1699  print_device(device);
1700  free(device);
1701 }
1702 
1703 /*!*****************************************************************************
1704 * \brief Prints detailed capability information for all initialized
1705 * devices and general information about uninitialized devices.
1706 
1707 * \param list_uninitialized Flag to determine if uninitialized devices
1708 * should be grabbed.
1709 *
1710 * \return none
1711 *
1712 *******************************************************************************/
1713 void ni_rsrc_print_all_devices_capability2(bool list_uninitialized)
1714 {
1715  ni_device_t *device = NULL;
1716  device = (ni_device_t *)malloc(sizeof(ni_device_t));
1717  if (!device)
1718  {
1719  ni_log(NI_LOG_ERROR, "ERROR %s() failed to malloc memory: %s\n",
1720  __func__, strerror(NI_ERRNO));
1721  return;
1722  }
1723  memset(device, 0, sizeof(ni_device_t));
1724 
1725  if (NI_RETCODE_SUCCESS != ni_rsrc_list_all_devices2(device, list_uninitialized))
1726  {
1727  free(device);
1728  return;
1729  }
1730 
1731  print_device(device);
1732  free(device);
1733 }
1734 
1735 /*!******************************************************************************
1736 * \brief Query a specific device with detailed information on the system
1737 
1738 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1739 * \param[in] guid unique device(decoder or encoder) id
1740 *
1741 * \return
1742 * pointer to ni_device_info_t if found
1743 * NULL otherwise
1744 *
1745 * Note: Caller is responsible for releasing memory that was allocated for the
1746 * returned pointer
1747 *******************************************************************************/
1749 {
1750  ni_device_info_t *p_device_info = NULL;
1751  ni_device_context_t* p_device_context = NULL;
1752 
1753  p_device_context = ni_rsrc_get_device_context(device_type, guid);
1754  if (NULL == p_device_context)
1755  {
1756  LRETURN;
1757  }
1758 
1759  p_device_info = (ni_device_info_t *)malloc(sizeof(ni_device_info_t));
1760  if (NULL == p_device_info)
1761  {
1762  LRETURN;
1763  }
1764 
1765 #ifdef _WIN32
1766  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
1767  {
1768  ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_get_device_info() failed to obtain "
1769  "mutex: %p\n", p_device_context->lock);
1770  free(p_device_info);
1771  LRETURN;
1772  }
1773 
1774  memcpy(p_device_info, p_device_context->p_device_info, sizeof(ni_device_info_t));
1775  ReleaseMutex(p_device_context->lock);
1776 #elif __linux
1777  lockf(p_device_context->lock, F_LOCK, 0);
1778 
1779  memcpy(p_device_info, p_device_context->p_device_info, sizeof(ni_device_info_t));
1780 
1781  lockf(p_device_context->lock, F_ULOCK, 0);
1782 #endif
1783 
1784 END:
1785 
1786  ni_rsrc_free_device_context(p_device_context);
1787 
1788  return p_device_info;
1789 }
1790 
1791 /*!****************************************************************************
1792 * \brief Get GUID of the device by block device name and type
1793 *
1794 * \param[in] blk_name device's block name
1795 * \param[in] type device type
1796 *
1797 * \return device GUID (>= 0) if found, NI_RETCODE_FAILURE (-1) otherwise
1798 *******************************************************************************/
1799 int ni_rsrc_get_device_by_block_name(const char *blk_name,
1800  ni_device_type_t device_type)
1801 {
1802  int i;
1803  int guid = NI_RETCODE_FAILURE, tmp_id;
1804  ni_device_pool_t *p_device_pool = NULL;
1805  ni_device_context_t *p_device_context = NULL;
1806  int num_coders = 0;
1807 
1808  //uploader shares instance with encoder
1809  if(device_type == NI_DEVICE_TYPE_UPLOAD)
1810  {
1811  device_type = NI_DEVICE_TYPE_ENCODER;
1812  }
1813 
1814  p_device_pool = ni_rsrc_get_device_pool();
1815  if (!p_device_pool)
1816  {
1817  ni_log(NI_LOG_ERROR, "ERROR: cannot get p_device_pool\n");
1818  return guid;
1819  }
1820 
1821 #ifdef _WIN32
1822  // no time-out interval (we got the mutex)
1823  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE))
1824  {
1825  ni_log(NI_LOG_ERROR, "ERROR: %s failed to obtain mutex: %p\n",
1826  __FUNCTION__, p_device_pool->lock);
1827  ni_rsrc_free_device_pool(p_device_pool);
1828  return NI_RETCODE_FAILURE;
1829  }
1830 #elif __linux__ || __APPLE__
1831  lockf(p_device_pool->lock, F_LOCK, 0);
1832 #endif
1833 
1834  num_coders = p_device_pool->p_device_queue->xcoder_cnt[device_type];
1835 
1836  for (i = 0; i < num_coders; i++)
1837  {
1838  tmp_id = p_device_pool->p_device_queue->xcoders[device_type][i];
1839  p_device_context = ni_rsrc_get_device_context(device_type, tmp_id);
1840 
1841  if (p_device_context &&
1842  0 == strcmp(p_device_context->p_device_info->dev_name, blk_name))
1843  {
1844  guid = p_device_context->p_device_info->module_id;
1845  ni_rsrc_free_device_context(p_device_context);
1846  break;
1847  }
1848 
1849  ni_rsrc_free_device_context(p_device_context);
1850  }
1851 
1852 #ifdef _WIN32
1853  ReleaseMutex(p_device_pool->lock);
1854 #elif __linux__ || __APPLE__
1855  lockf(p_device_pool->lock, F_ULOCK, 0);
1856 #endif
1857 
1858  ni_rsrc_free_device_pool(p_device_pool);
1859 
1860  ni_log(NI_LOG_DEBUG, "%s %s got guid: %d\n", __FUNCTION__, blk_name, guid);
1861 
1862  return guid;
1863 }
1864 
1865 /*!*****************************************************************************
1866 * \brief Update the load value and s/w instances info of a specific decoder or
1867 * encoder. This is used by resource management daemon to update periodically.
1868 *
1869 * \param[in] p_ctxt The device context returned by ni_rsrc_get_device_context
1870 * \param[in] p_load The latest load value to update
1871 * \param[in] sw_instance_cnt Number of s/w instances
1872 * \param[in] sw_instance_info Info of s/w instances
1873 *
1874 * \return
1875 * NI_RETCODE_SUCCESS
1876 * NI_RETCODE_FAILURE
1877 *******************************************************************************/
1878 int ni_rsrc_update_device_load(ni_device_context_t *p_device_context, int load,
1879  int sw_instance_cnt, const ni_sw_instance_info_t sw_instance_info[])
1880 {
1881  int i;
1882  if (!p_device_context || !sw_instance_info)
1883  {
1884  ni_log(NI_LOG_ERROR, "ERROR: %s() invalid input pointers\n", __func__);
1885  return NI_RETCODE_FAILURE;
1886  }
1887 
1888 #ifdef _WIN32
1889  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
1890  {
1891  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %p\n",
1892  __func__, p_device_context->lock);
1893  return NI_RETCODE_FAILURE;
1894  }
1895 #elif __linux__ || __APPLE__
1896  lockf(p_device_context->lock, F_LOCK, 0);
1897 #endif
1898 
1899  p_device_context->p_device_info->load = load;
1900  p_device_context->p_device_info->active_num_inst = sw_instance_cnt;
1901  for (i = 0; i < sw_instance_cnt; i++)
1902  {
1903  p_device_context->p_device_info->sw_instance[i] = sw_instance_info[i];
1904  }
1905 
1906 #ifdef _WIN32
1907  ReleaseMutex(p_device_context->lock);
1908 #elif __linux__ || __APPLE__
1909  lockf(p_device_context->lock, F_ULOCK, 0);
1910 #endif
1911 
1912  return NI_RETCODE_SUCCESS;
1913 }
1914 
1915 /*!*****************************************************************************
1916 * \brief Allocate resources for decoding/encoding, by designating explicitly
1917 * the device to use. do not track the load on the host side
1918 *
1919 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1920 * \param[in] guid unique device (decoder or encoder) module id
1921 * \return pointer to ni_device_context_t if found, NULL otherwise
1922 *
1923 * Note: only need to specify the device type and guid and codec type
1924 *
1925 *
1926 * Note: the returned ni_device_context_t content is not supposed to be used by
1927 * caller directly: should only be passed to API in the subsequent
1928 * calls; also after its use, the context should be released by
1929 * calling ni_rsrc_free_device_context.
1930 *******************************************************************************/
1933  ni_device_type_t device_type,
1934  int guid
1935 )
1936 {
1937  ni_device_context_t *p_device_context = ni_rsrc_get_device_context(device_type, guid);
1938 
1939  return p_device_context;
1940 }
1941 
1942 
1943 /*!*****************************************************************************
1944 * \brief Release resources allocated for decoding/encoding.
1945 * function This *must* be called at the end of transcoding
1946 * with previously assigned load value by allocate* functions.
1947 *
1948 * \param[in/out] p_ctxt the device context
1949 * \param[in] load the load value returned by allocate* functions
1950 *
1951 * \return None
1952 *******************************************************************************/
1954  uint64_t load)
1955 {
1956 
1957 #if 1
1958  (void) p_device_context;
1959  (void) load;
1960  return;
1961 
1962 #else
1963  if (!p_device_context)
1964  {
1965  ni_log(NI_LOG_ERROR, "ERROR: %s() invalid input pointers\n", __func__);
1966  return;
1967  }
1968 
1969 #ifdef _WIN32
1970  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
1971  {
1972  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %p\n",
1973  __func__, p_device_context->lock);
1974  }
1975 #elif __linux__ || __APPLE__
1976  lockf(p_device_context->lock, F_LOCK, 0);
1977 #endif
1978 
1979  if (p_device_context->p_device_info->xcode_load_pixel < load)
1980  {
1981  ni_log(NI_LOG_INFO, "Warning: releasing resource load %lu > current load %lu\n", load,
1982  p_device_context->p_device_info->xcode_load_pixel);
1983  }
1984  else
1985  {
1986  p_device_context->p_device_info->xcode_load_pixel -= load;
1987  // Remove as the value is getting from the FW
1988  // p_device_context->p_device_info->model_load = (int)((double)(p_device_context->p_device_info->xcode_load_pixel) * 100 / total_cap);
1989 #if __linux__ || __APPLE__
1990  if (msync((void *)p_device_context->p_device_info, sizeof(ni_device_info_t), MS_SYNC | MS_INVALIDATE))
1991  {
1992  ni_log(NI_LOG_ERROR, "ERROR %s() msync() p_device_context->"
1993  "p_device_info: %s\n", __func__, strerror(NI_ERRNO));
1994  }
1995 #endif
1996  }
1997 
1998 #ifdef _WIN32
1999  ReleaseMutex(p_device_context->lock);
2000 #elif __linux__ || __APPLE__
2001  lockf(p_device_context->lock, F_ULOCK, 0);
2002 #endif
2003 
2004 #endif
2005 }
2006 
2007 /*!*****************************************************************************
2008 * \brief check the NetInt h/w device in resource pool on the host.
2009 *
2010 * \param[in] guid the global unique device index in resource pool
2011 * device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
2012 *
2013 * \return
2014 * NI_RETCODE_SUCCESS
2015 *******************************************************************************/
2017 {
2018  ni_device_pool_t *p_device_pool = NULL;
2019  ni_device_context_t *p_device_ctx = NULL;
2020  ni_session_context_t session_ctx = {0};
2021  ni_xcoder_params_t api_param = {0};
2022  uint32_t max_nvme_io_size = 0;
2023  bool b_release_pool_mtx = false;
2025  int retry_cnt = 0;
2026 
2027  if (guid < 0)
2028  {
2029  ni_log(NI_LOG_ERROR, "ERROR invalid guid:%d\n", guid);
2030  return NI_RETCODE_INVALID_PARAM;
2031  }
2032 
2033  if (!IS_XCODER_DEVICE_TYPE(device_type))
2034  {
2035  ni_log(NI_LOG_ERROR, "ERROR: Unknown device type:%d\n", device_type);
2036  return NI_RETCODE_INVALID_PARAM;
2037  }
2038 
2039  ni_device_session_context_init(&session_ctx);
2041  session_ctx.src_bit_depth = 8;
2042  session_ctx.hw_id = guid;
2043 
2044  if (NI_DEVICE_TYPE_DECODER == device_type)
2045  {
2046  if (ni_decoder_init_default_params(&api_param, 30, 1, NI_MIN_BITRATE,
2049  {
2050  ni_log(NI_LOG_ERROR, "ERROR: set decoder default params error\n");
2051  return NI_RETCODE_INVALID_PARAM;
2052  }
2053  } else if (NI_DEVICE_TYPE_ENCODER == device_type)
2054  {
2056  &api_param, 30, 1, NI_MIN_BITRATE, XCODER_MIN_ENC_PIC_WIDTH,
2058  {
2059  ni_log(NI_LOG_ERROR, "ERROR: set encoder default params error\n");
2060  return NI_RETCODE_INVALID_PARAM;
2061  }
2062  } else if (NI_DEVICE_TYPE_SCALER == device_type)
2063  {
2064  session_ctx.device_type = NI_DEVICE_TYPE_SCALER;
2066  } else
2067  {
2068  session_ctx.device_type = NI_DEVICE_TYPE_AI;
2069  }
2070  session_ctx.p_session_config = &api_param;
2071 
2072  p_device_pool = ni_rsrc_get_device_pool();
2073  if (!p_device_pool)
2074  {
2075  ni_log(NI_LOG_ERROR, "ERROR: get device poll failed\n");
2077  LRETURN;
2078  }
2079 
2080 #ifdef _WIN32
2081  if (WAIT_ABANDONED ==
2082  WaitForSingleObject(p_device_pool->lock,
2083  INFINITE)) // no time-out interval)
2084  {
2086  "ERROR: ni_rsrc_list_devices() failed to obtain mutex: %p\n",
2087  p_device_pool->lock);
2088  retval = NI_RETCODE_FAILURE;
2089  LRETURN;
2090  }
2091 #elif __linux__
2092  lockf(p_device_pool->lock, F_LOCK, 0);
2093 #endif
2094  b_release_pool_mtx = true;
2095 
2096  // get device context
2097  p_device_ctx = ni_rsrc_get_device_context(device_type, guid);
2098  if (p_device_ctx)
2099  {
2100  session_ctx.device_handle = ni_device_open(
2101  p_device_ctx->p_device_info->dev_name, &max_nvme_io_size);
2102  session_ctx.blk_io_handle = session_ctx.device_handle;
2103  if (NI_INVALID_DEVICE_HANDLE == session_ctx.device_handle)
2104  {
2105  ni_log(NI_LOG_ERROR, "open device failed: %d\n", errno);
2107  } else
2108  {
2109 #ifdef _WIN32
2110  session_ctx.event_handle = ni_create_event();
2111  if (NI_INVALID_EVENT_HANDLE == session_ctx.event_handle)
2112  {
2113  ni_log(NI_LOG_INFO, "Error create envent:%d\n", GetLastError());
2114  retval = NI_RETCODE_FAILURE;
2115  LRETURN;
2116  }
2117 #endif
2118  retval = ni_device_session_query(&session_ctx, device_type);
2119  if (NI_RETCODE_SUCCESS != retval)
2120  {
2122  "guid %d. %s is not avaiable, type: %d, retval:%d\n",
2123  guid, p_device_ctx->p_device_info->dev_name,
2124  device_type, retval);
2125  retval = NI_RETCODE_FAILURE;
2126  } else
2127  {
2128  while (1)
2129  {
2130  retry_cnt++;
2131  retval = ni_device_session_open(&session_ctx, device_type);
2132  ni_device_session_close(&session_ctx, 0, device_type);
2133  if (retval == NI_RETCODE_SUCCESS)
2134  {
2135  ni_log(NI_LOG_INFO, "guid %d. %s is avaiable\n",
2136  guid, p_device_ctx->p_device_info->dev_name);
2137  break;
2138  } else if (
2139  retry_cnt < 10 &&
2140  retval ==
2141  NI_RETCODE_ERROR_VPU_RECOVERY) // max 2 seconds
2142  {
2144  "vpu recovery happened on guid %d. %s, retry "
2145  "cnt:%d\n",
2146  guid, p_device_ctx->p_device_info->dev_name,
2147  retry_cnt);
2148 #ifndef _WIN32
2149  ni_usleep(200000); // 200 ms
2150 #endif
2151  continue;
2152  } else
2153  {
2155  "session open error guid %d. %s, type: %d, "
2156  "retval:%d\n",
2157  guid, p_device_ctx->p_device_info->dev_name,
2158  device_type, retval);
2159  retval = NI_RETCODE_FAILURE;
2160  break;
2161  }
2162  }
2163  }
2164  }
2165  } else
2166  {
2168  "Error get device resource: guid %d, device_ctx %p\n", guid,
2169  p_device_ctx);
2170  retval = NI_RETCODE_FAILURE;
2171  }
2172 
2173 END:
2174 
2175  if (b_release_pool_mtx)
2176  {
2177 #ifdef _WIN32
2178  ReleaseMutex(p_device_pool->lock);
2179 #elif __linux__
2180  lockf(p_device_pool->lock, F_ULOCK, 0);
2181 #endif
2182  }
2183 
2184  ni_close_event(session_ctx.event_handle);
2185  ni_device_close(session_ctx.device_handle);
2186 
2187  ni_rsrc_free_device_context(p_device_ctx);
2188  ni_device_session_context_clear(&session_ctx);
2189  ni_rsrc_free_device_pool(p_device_pool);
2190 
2191  return retval;
2192 }
2193 
2194 /*!*****************************************************************************
2195 * \brief Remove an NetInt h/w device from resource pool on the host.
2196 *
2197 * \param[in] p_dev the NVMe device name
2198 *
2199 * \return
2200 * NI_RETCODE_SUCCESS
2201 * NI_RETCODE_FAILURE
2202 *******************************************************************************/
2203 int ni_rsrc_remove_device(const char* dev)
2204 {
2205 #if __linux__ || __APPLE__
2206  char lck_name[32];
2207 #endif
2208  int return_value = NI_RETCODE_SUCCESS;
2209  int32_t guid;
2210  int32_t guids[NI_MAX_DEVICE_CNT];
2211  unsigned int guid_index_i, guid_index_j, ui_device_type;
2212 #ifdef _WIN32
2213  DWORD rValue;
2214 #endif
2215  ni_device_context_t *p_device_context;
2216  ni_device_pool_t *p_device_pool = NULL;
2217  ni_device_queue_t *p_device_queue;
2218  ni_device_type_t device_type;
2219 
2220  if (!dev)
2221  {
2222  ni_log(NI_LOG_ERROR, "ERROR: %s() dev is NULL\n", __FUNCTION__);
2223  return_value = NI_RETCODE_INVALID_PARAM;
2224  LRETURN;
2225  }
2226 
2227  p_device_pool = ni_rsrc_get_device_pool();
2228  if (!p_device_pool)
2229  {
2230  return_value = NI_RETCODE_FAILURE;
2231  LRETURN;
2232  }
2233 
2234 #ifdef _WIN32
2235  rValue = WaitForSingleObject(p_device_pool->lock, INFINITE);
2236  if (rValue != WAIT_OBJECT_0)
2237  {
2239  "ERROR: %s() Failed to obtain mutex %p\n",
2240  __FUNCTION__,
2241  p_device_pool->lock);
2242  return_value = NI_RETCODE_FAILURE;
2243  LRETURN;
2244  }
2245 #elif __linux__ || __APPLE__
2246  lockf(p_device_pool->lock, F_LOCK, 0);
2247 #endif
2248 
2249  p_device_queue = p_device_pool->p_device_queue;
2250  for (guid_index_i = 0; guid_index_i < NI_MAX_DEVICE_CNT; guid_index_i++)
2251  {
2252  for (ui_device_type = NI_DEVICE_TYPE_DECODER;
2253  ui_device_type < NI_DEVICE_TYPE_XCODER_MAX;
2254  ui_device_type++)
2255  {
2256  guid = p_device_queue->xcoders[ui_device_type][guid_index_i];
2257  if (guid == -1)
2258  {
2259  continue;
2260  }
2261  device_type = (ni_device_type_t)ui_device_type;
2262  p_device_context = ni_rsrc_get_device_context(device_type, guid);
2263  if (!p_device_context)
2264  {
2266  "ERROR: %s() Failed to obtain device context for "
2267  "%s with GUID %u! Undefined behavior!\n",
2268  __func__,
2269  GET_XCODER_DEVICE_TYPE_STR(device_type),
2270  guid);
2271  return_value = NI_RETCODE_FAILURE;
2272  continue;
2273  }
2274 
2275  if (strncmp(dev,
2276  p_device_context->p_device_info->dev_name,
2277  NI_MAX_DEVICE_NAME_LEN) != 0)
2278  {
2279  continue;
2280  }
2281 
2282 #ifdef _WIN32
2283  CloseHandle(p_device_context->lock);
2284 #elif __linux__ || __APPLE__
2285  if (!ni_rsrc_remove_shm(p_device_context->shm_name, sizeof(ni_device_info_t)))
2286  {
2288  "%s %s %s deleted\n",
2289  dev,
2290  GET_XCODER_DEVICE_TYPE_STR(device_type),
2291  p_device_context->shm_name);
2292  }
2293  else
2294  {
2296  "ERROR: %s(): %s %s %s failed to delete %s\n",
2297  __FUNCTION__,
2298  dev,
2299  GET_XCODER_DEVICE_TYPE_STR(device_type),
2300  p_device_context->shm_name,
2301  strerror(NI_ERRNO));
2302  return_value = NI_RETCODE_FAILURE;
2303  }
2304 #endif
2305 
2306  ni_rsrc_free_device_context(p_device_context);
2307 
2308 #if __linux__ || __APPLE__
2309  ni_rsrc_get_lock_name(device_type, guid, lck_name, 32);
2310  if (!unlink(lck_name))
2311  {
2313  "%s %s %s deleted\n",
2314  dev,
2315  GET_XCODER_DEVICE_TYPE_STR(device_type),
2316  lck_name);
2317  }
2318  else
2319  {
2321  "ERROR: %s(): %s %s %s failed to delete %s\n",
2322  __FUNCTION__,
2323  dev,
2324  GET_XCODER_DEVICE_TYPE_STR(device_type),
2325  lck_name,
2326  strerror(NI_ERRNO));
2327  return_value = NI_RETCODE_FAILURE;
2328  }
2329 #endif
2330 
2331  if (return_value != NI_RETCODE_SUCCESS)
2332  {
2333  continue;
2334  }
2335 
2336  p_device_queue->xcoders[ui_device_type][guid_index_i] = -1;
2337  p_device_queue->xcoder_cnt[ui_device_type]--;
2338  }
2339  }
2340 
2341  // Take p_device_queue->xcoder_cnt[ui_device_type] to contain the value 2.
2342  // p_device_queue->xcoders[ui_device_type] could be [0, -1, 2, ...]
2343  // p_device_queue->xcoders[ui_device_type] should be [0, 2, -1, ...]
2344  for (ui_device_type = NI_DEVICE_TYPE_DECODER;
2345  ui_device_type < NI_DEVICE_TYPE_XCODER_MAX;
2346  ui_device_type++)
2347  {
2348  memset(guids, -1, sizeof(guids));
2349  guid_index_j = 0;
2350  for (guid_index_i = 0; guid_index_i < NI_MAX_DEVICE_CNT; guid_index_i++)
2351  {
2352  guid = p_device_queue->xcoders[ui_device_type][guid_index_i];
2353  if (guid != -1)
2354  {
2355  guids[guid_index_j] = guid;
2356  guid_index_j++;
2357  if (guid_index_j == p_device_queue->xcoder_cnt[ui_device_type])
2358  {
2359  break;
2360  }
2361  }
2362  }
2363  memcpy(p_device_queue->xcoders[ui_device_type], guids, sizeof(guids));
2364  }
2365 
2366 #if __linux__ || __APPLE__
2367 #ifndef _ANDROID
2368  if (!msync((void *)p_device_queue,
2369  sizeof(ni_device_queue_t),
2370  MS_SYNC|MS_INVALIDATE))
2371  {
2372  ni_log(NI_LOG_INFO, "%s deleted\n", dev);
2373  }
2374  else
2375  {
2377  "ERROR: %s(): msync() failed to delete %s: %s\n",
2378  __FUNCTION__,
2379  dev,
2380  strerror(NI_ERRNO));
2381  return_value = NI_RETCODE_FAILURE;
2382  }
2383 #endif
2384 #endif
2385 
2386 #ifdef _WIN32
2387  ReleaseMutex(p_device_pool->lock);
2388 #elif __linux__ || __APPLE__
2389  lockf(p_device_pool->lock, F_ULOCK, 0);
2390 #endif
2391 
2392 end:
2393  ni_rsrc_free_device_pool(p_device_pool);
2394 
2395  return return_value;
2396 }
2397 
2398 /*!*****************************************************************************
2399 * \brief Remove all NetInt h/w devices from resource pool on the host.
2400 *
2401 * \param none
2402 *
2403 * \return
2404 * NI_RETCODE_SUCCESS
2405 * NI_RETCODE_FAILURE
2406 *******************************************************************************/
2408 {
2409  char xcoder_dev_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = {0};
2410  int xcoder_dev_count = 0;
2411  int i = 0;
2412  ni_device_t *saved_coders = NULL;
2413  saved_coders = (ni_device_t *)malloc(sizeof(ni_device_t));
2414  if (!saved_coders)
2415  {
2416  ni_log(NI_LOG_ERROR, "ERROR %s() failed to malloc memory: %s\n",
2417  __func__, strerror(NI_ERRNO));
2418  return NI_RETCODE_FAILURE;
2419  }
2420  memset(saved_coders, 0, sizeof(ni_device_t));
2421 
2422  // retrieve saved info from resource pool at start up
2423  if (NI_RETCODE_SUCCESS ==
2426  saved_coders->xcoders[NI_DEVICE_TYPE_ENCODER],
2427  &(saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER])))
2428  {
2429  for (i = 0; i < saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
2430  i++)
2431  {
2432  strcpy(xcoder_dev_names[i],
2433  saved_coders->xcoders[NI_DEVICE_TYPE_ENCODER][i]
2434  .dev_name);
2435  ni_log(NI_LOG_INFO, "device %d %s retrieved\n", i,
2436  xcoder_dev_names[i]);
2437  }
2438  xcoder_dev_count =
2439  saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
2440 #ifdef XCODER_311
2442  "%d devices retrieved from current pool at start up\n",
2443  xcoder_dev_count);
2444 #else
2446  "%d devices retrieved from current pool at start up\n",
2447  xcoder_dev_count);
2448 #endif
2449  } else
2450  {
2451  ni_log(NI_LOG_ERROR, "Error retrieving from current pool at start "
2452  "up\n");
2453  }
2454  free(saved_coders);
2455 
2456  // remove from resource pool all devices
2457  for (i = 0; i < xcoder_dev_count; i++)
2458  {
2459  ni_log(NI_LOG_INFO, "removing device %d %s !\n", i,
2460  xcoder_dev_names[i]);
2461  if (NI_RETCODE_SUCCESS ==
2462  ni_rsrc_remove_device(xcoder_dev_names[i]))
2463  {
2464  ni_log(NI_LOG_INFO, "%s deleted successfully !\n",
2465  xcoder_dev_names[i]);
2466  } else
2467  {
2468  ni_log(NI_LOG_ERROR, "%s failed to delete !\n",
2469  xcoder_dev_names[i]);
2470  }
2471  }
2472 
2473 #if __linux__ || __APPLE__
2474  if (!ni_rsrc_remove_shm(CODERS_SHM_NAME, sizeof(ni_device_queue_t)))
2475  {
2476  ni_log(NI_LOG_INFO, "%s deleted.\n", CODERS_SHM_NAME);
2477  }
2478  else
2479  {
2480  ni_log(NI_LOG_ERROR, "%s failed to delete !\n", CODERS_SHM_NAME);
2481  }
2482 
2483  for (i = 0; i < NI_DEVICE_TYPE_XCODER_MAX; i++)
2484  {
2485  if (0 == unlink(XCODERS_RETRY_LCK_NAME[i]))
2486  {
2487  ni_log(NI_LOG_INFO, "%d %s deleted.\n",
2488  i, XCODERS_RETRY_LCK_NAME[i]);
2489  }
2490  else
2491  {
2492  ni_log(NI_LOG_ERROR, "%d %s failed to delete !\n",
2493  i, XCODERS_RETRY_LCK_NAME[i]);
2494  }
2495  }
2496 
2497  if (0 == unlink(CODERS_LCK_NAME))
2498  {
2499  ni_log(NI_LOG_INFO, "%s deleted.\n", CODERS_LCK_NAME);
2500  }
2501  else
2502  {
2503  ni_log(NI_LOG_ERROR, "%s failed to delete !\n", CODERS_LCK_NAME);
2504  }
2505 #endif
2506 
2507  return NI_RETCODE_SUCCESS;
2508 }
2509 
2510 /*!*****************************************************************************
2511 * \brief Add an NetInt h/w device into resource pool on the host.
2512 *
2513 * \param[in] p_dev Device name represented as C string. ex "/dev/nvme0"
2514 * \param[in] should_match_rev 0: transcoder firmware revision matching the
2515 * library's version is NOT required for placing
2516 * the transcoder into resource pool; 1: otherwise
2517 *
2518 * \return
2519 * NI_RETCODE_SUCCESS
2520 * NI_RETCODE_INVALID_PARAM
2521 * NI_RETCODE_FAILURE
2522 *******************************************************************************/
2523 int ni_rsrc_add_device(const char* dev, int should_match_rev)
2524 {
2525  uint32_t i, existing_number_of_devices;
2526 
2527  ni_device_type_t device_type;
2528  ni_device_context_t *device_context;
2529  ni_device_pool_t *device_pool;
2530  ni_device_queue_t *device_queue;
2531  ni_retcode_t retcode;
2532 
2533  if (!dev)
2534  {
2535  ni_log(NI_LOG_ERROR, "ERROR: %s(): dev is NULL\n", __FUNCTION__);
2536  return NI_RETCODE_INVALID_PARAM;
2537  }
2538 
2539  device_pool = ni_rsrc_get_device_pool();
2540  if (!device_pool)
2541  {
2542  return NI_RETCODE_SUCCESS;
2543  }
2544 
2545 #ifdef _WIN32
2546  if (WAIT_ABANDONED == WaitForSingleObject(device_pool->lock, INFINITE))
2547  {
2549  "ERROR: %s(): Failed to obtain lock %p\n",
2550  __FUNCTION__,
2551  device_pool->lock);
2552  return NI_RETCODE_FAILURE;
2553  }
2554 #elif __linux__ || __APPLE__
2555  lockf(device_pool->lock, F_LOCK, 0);
2556 #endif
2557 
2558  retcode = NI_RETCODE_SUCCESS;
2559 
2560  device_type = NI_DEVICE_TYPE_ENCODER;
2561  device_queue = device_pool->p_device_queue;
2562  existing_number_of_devices = device_queue->xcoder_cnt[device_type];
2563 
2564  if (existing_number_of_devices == NI_MAX_DEVICE_CNT)
2565  {
2567  "ERROR: %s(): Limit of NI_MAX_DEVICE_CNT(%d) existing Quadra "
2568  "devices previously reached. Not adding %s.\n",
2569  __FUNCTION__,
2571  dev);
2572  retcode = NI_RETCODE_FAILURE;
2573  LRETURN;
2574  }
2575 
2576  for (i = 0; i < existing_number_of_devices; i++)
2577  {
2578  device_context =
2579  ni_rsrc_get_device_context(device_type,
2580  device_queue->xcoders[device_type][i]);
2581  if (device_context && !strncmp(device_context->p_device_info->dev_name,
2582  dev,
2584  {
2585  retcode = NI_RETCODE_FAILURE;
2587  "ERROR: %s(): %s already exists in resource pool\n",
2588  __FUNCTION__,
2589  dev);
2590  ni_rsrc_free_device_context(device_context);
2591  LRETURN;
2592  }
2593  ni_rsrc_free_device_context(device_context);
2594  }
2595 
2596  if (!add_to_shared_memory(dev,
2597  true,
2598  should_match_rev,
2599  device_queue))
2600  {
2601  retcode = NI_RETCODE_FAILURE;
2602  }
2603 
2604 end:
2605 #ifdef _WIN32
2606  ReleaseMutex(device_pool->lock);
2607 #elif __linux__ || __APPLE__
2608  lockf(device_pool->lock, F_ULOCK, 0);
2609 #endif
2610  ni_rsrc_free_device_pool(device_pool);
2611  return retcode;
2612 }
2613 
2614 /*!*****************************************************************************
2615 * \brief Free all resources taken by the device pool
2616 *
2617 * \param[in] p_device_pool Poiner to a device pool struct
2618 *
2619 * \return None
2620 *******************************************************************************/
2622 {
2623  if (p_device_pool)
2624  {
2625  if (NI_INVALID_LOCK_HANDLE != p_device_pool->lock)
2626  {
2627 #ifdef _WIN32
2628  CloseHandle(p_device_pool->lock);
2629 #elif __linux__ || __APPLE__
2630  close(p_device_pool->lock);
2631 #endif
2632  }
2633 #ifdef _WIN32
2634  UnmapViewOfFile(p_device_pool->p_device_queue);
2635 #else
2636  ni_rsrc_munmap_shm((void *)p_device_pool->p_device_queue, sizeof(ni_device_queue_t));
2637  ni_log(NI_LOG_DEBUG, "in %s do munmap for %s\n", __func__, CODERS_SHM_NAME);
2638 #endif
2639 
2640  free(p_device_pool);
2641  }
2642 }
2643 
2644 /*!*****************************************************************************
2645  * \brief lock a file lock and open a session on a device
2646  *
2647  * \param device_type
2648  * \param lock
2649  *
2650  * \return None
2651  *******************************************************************************/
2652 int ni_rsrc_lock_and_open(int device_type, ni_lock_handle_t* lock)
2653 {
2654 
2655  int count = 0;
2656  int status = NI_RETCODE_ERROR_LOCK_DOWN_DEVICE;
2657 #ifdef _WIN32
2658  *lock = CreateMutex(NULL, FALSE, XCODERS_RETRY_LCK_NAME[device_type]);
2659 
2660  if (NULL == *lock)
2661  {
2662  ni_log(NI_LOG_ERROR, "ERROR: %s() CreateMutex() %s failed: %s\n",
2663  __func__, XCODERS_RETRY_LCK_NAME[device_type],
2664  strerror(NI_ERRNO));
2666  }
2667 #else
2668  do
2669  {
2670  if (count>=1)
2671  {
2672  //sleep 10ms if the file lock is locked by other FFmpeg process
2674  }
2675  // Here we try to open the file lock, retry if it failed
2676  *lock =
2677  open(XCODERS_RETRY_LCK_NAME[device_type], O_RDWR | O_CREAT | O_CLOEXEC,
2678  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
2679 
2680  if (*lock < 0)
2681  {
2682  count++;
2683  if (count > MAX_LOCK_RETRY)
2684  {
2685  ni_log(NI_LOG_ERROR, "Can not lock down the file lock after 6s");
2687  }
2688  }
2689  }
2690  while (*lock < 0);
2691 #endif
2692  // Now the lock is free so we lock it down
2693  count = 0;
2694  do
2695  {
2696  //sleep 10ms if the file lock is locked by other FFmpeg process
2697  if (count>=1)
2698  {
2699  //sleep 10ms if the file lock is locked by other FFmpeg process
2701  }
2702 #ifdef _WIN32
2703  DWORD ret = WaitForSingleObject(*lock, 1); // time-out 1ms
2704  if (WAIT_OBJECT_0 == ret)
2705  {
2706  status = NI_RETCODE_SUCCESS;
2707  } else if (WAIT_TIMEOUT != ret)
2708  {
2709  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %s\n",
2710  __func__, strerror(NI_ERRNO));
2711  }
2712 #else
2713  status = lockf(*lock, F_LOCK, 0);
2714 #endif
2715  if (status != 0)
2716  {
2717  count++;
2718  if (count > MAX_LOCK_RETRY)
2719  {
2720  ni_log(NI_LOG_ERROR, "Can not put down the lock after 6s");
2722  }
2723  }
2724  }
2725  while (status != 0);
2726 
2727  return NI_RETCODE_SUCCESS;
2728 }
2729 
2730 /*!*****************************************************************************
2731  * \brief unlock a file lock
2732  *
2733  * \param device_type
2734  * \param lock
2735  *
2736  * \return None
2737  *******************************************************************************/
2738 int ni_rsrc_unlock(int device_type, ni_lock_handle_t lock)
2739 {
2740  if (lock == NI_INVALID_LOCK_HANDLE)
2741  {
2742  return NI_RETCODE_FAILURE;
2743  }
2744 
2745  int count = 0;
2746  ni_lock_handle_t status = NI_INVALID_LOCK_HANDLE;
2747  do
2748  {
2749  if (count >= 1)
2750  {
2752  }
2753 #ifdef _WIN32
2754  if (ReleaseMutex(lock))
2755  {
2756  status = (ni_lock_handle_t)(0);
2757  }
2758 #else
2759  status = lockf(lock, F_ULOCK, 0);
2760 #endif
2761  count++;
2762  if (count > MAX_LOCK_RETRY)
2763  {
2764  ni_log(NI_LOG_ERROR, "Can not unlock the lock after 6s");
2766  }
2767  } while (status != (ni_lock_handle_t)(0));
2768 
2769 #ifdef _WIN32
2770  CloseHandle(lock);
2771 #else
2772  close(lock);
2773 #endif //_WIN32 defined
2774  return NI_RETCODE_SUCCESS;
2775 }
2776 
2777 /*!*****************************************************************************
2778 * \brief check if device FW revision is compatible with SW API
2779 *
2780 * \param fw_rev
2781 *
2782 * \return 1 for full compatibility, 2 for partial, 0 for none
2783 *******************************************************************************/
2784 int ni_rsrc_is_fw_compat(uint8_t fw_rev[8])
2785 {
2786  if ((uint8_t)fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX] ==
2790  } else {
2791  return 0;
2792  }
2793 }
2794 
2795 static int int_cmp(const void *a, const void *b)
2796 {
2797  const int *ia = (const int *)a;
2798  const int *ib = (const int *)b;
2799  return (*ia == *ib) ? 0 : ((*ia > *ib) ? 1 : -1);
2800  /* integer comparison: returns negative if b > a , 0 if a == b,and positive if a > b */
2801 }
2802 
2803 static int ni_hw_device_info_quadra_threshold_param_t_compare(const void *pl, const void *pr)
2804 {
2807  if(!ll || !rr)
2808  {
2809  return 0;
2810  }
2811  return (ll->device_type == rr->device_type) ? 0 : ((ll->device_type > rr->device_type) ? 1 : -1);
2812 }
2813 
2814 
2815 /*!*********************************************************************************************
2816 * \brief Calculate decoder load used in ni_check_hw_info()
2817 * The computing method is from firmware for 770.
2818 * This function is used for ni_check_hw_info()
2819 *
2820 * \param decoder_param
2821 *
2822 * \return task decoder load
2823 ***********************************************************************************************/
2824 static int check_hw_info_decoder_need_load(ni_hw_device_info_quadra_decoder_param_t *decoder_param)
2825 {
2826  int factor_8_10 = 1;
2827  uint32_t resolution = decoder_param->h * decoder_param->w;
2828  if(decoder_param->bit_8_10 == 10)
2829  {
2830  factor_8_10 = 2;
2831  }
2832  return resolution >= 1920*1080 ?
2833  (int)(((uint64_t)(resolution)*(uint64_t)(decoder_param->fps)*(uint64_t)(factor_8_10)*100)/1440/1920/1080) :
2834  (int)((uint64_t)(resolution)*(uint64_t)(decoder_param->fps)*(uint64_t)(factor_8_10)*100/2880/1280/720);
2835 }
2836 
2837 /*!**************************************************************************************
2838 * \brief Calculate encoder load used in ni_check_hw_info()
2839 * The computing method is from firmware->ModelLoadSet
2840 * This function is used for ni_check_hw_info()
2841 *
2842 * \param encoder_param
2843 *
2844 * \return task encoder load
2845 ****************************************************************************************/
2846 static int check_hw_info_encoder_need_load(ni_hw_device_info_quadra_encoder_param_t *encoder_param)
2847 {
2848  double factor = 1.0;
2849  double factor_codec = 1.0;
2850  double factor_rdoq = 1.0;
2851  double factor_rdoLevel = 1.0;
2852  double factor_lookahead = 1.0;
2853  double factor_8_10_bit = 1.0;
2854  double factor_720p = 1.0;
2855 
2856  int resolution = (int)(encoder_param->w * encoder_param->h);
2857 
2858 
2859  if(encoder_param->code_format == 3)//STD_JPGE
2860  {
2861  factor_codec = 0.67;
2862  }
2863  else{
2864  if((encoder_param->code_format == 0 || encoder_param->code_format == 1) &&
2865  encoder_param->ui8enableRdoQuant)//264 or 265
2866  {
2867  factor_rdoq = 1.32;
2868  }
2869 
2870  if((encoder_param->code_format == 1 || encoder_param->code_format ==2) &&
2871  encoder_param->rdoLevel > 1)
2872  {
2873  factor_rdoLevel = (encoder_param->rdoLevel == 2) ? 1.91 : 3.28;
2874  }
2875 
2876  if(encoder_param->lookaheadDepth != 0)
2877  {
2878  factor_lookahead = (double)(encoder_param->lookaheadDepth * 0.0014 + 1.012);
2879  }
2880  }
2881 
2882  if(encoder_param->bit_8_10 == 10)
2883  {
2884  factor_8_10_bit = 2;
2885  }
2886 
2887  factor_720p = 1.125;//consider h and w
2888  factor = factor_codec * factor_8_10_bit * factor_rdoq * factor_rdoLevel
2889  * factor_lookahead * factor_720p;
2890 
2891  //ENC_TOTAL_BIT_VOLUME_1_SEC (3840 * 2160 * 60ULL)
2892  //PERF_MODEL_LOAD_PERCENT = ((ENC_TOTAL_BIT_VOLUME_1_SEC / 100) * ENCODER_MULTICORE_NUM)
2893  //encoedr_need_load = sample_model_load/PERF_MODEL_LOAD_PERCENT
2894  return uint32_t(
2895  ((uint32_t)((uint32_t)factor*encoder_param->fps * resolution)) /
2896  ((3840 * 2160 * 60ULL) / 100 * 4));
2897 }
2898 
2899 /*!*****************************************************************************
2900 * \brief Calculate shared memeory uasge buffer scale
2901 * The computing method is from MemUsageCalculation_SR
2902 * This function is used for ni_check_hw_info()
2903 *
2904 * \param h
2905 * \param w
2906 * \param bit_8_10
2907 * \param rgba
2908 *
2909 * \return task shared memeory uasge buffer scale
2910 ********************************************************************************/
2911 static int check_hw_info_shared_mem_calculate_b_scale(int h,int w,int bit_8_10,int rgba)
2912 {
2913  const int stride = 128;
2914  int estimated_yuv_size = rgba ?
2915  w * h * 4 :
2916  bit_8_10 == 8 ?
2917  ( ((w + stride - 1)/stride)*stride + ((w/2 + stride - 1)/stride)*stride ) * h:
2918  ( ((w * 2 + stride - 1)/stride)*stride + ((w + stride - 1)/stride)*stride ) * h;
2919  const int b_unit = 1601536;//Bin_Unit_Size
2920  int b_scale = (estimated_yuv_size + b_unit -1) / b_unit;
2921  return b_scale;
2922 }
2923 
2924 /*!*****************************************************************************
2925 * \brief Calculate encoder shared memory usage
2926 * The computing method is from MemUsageCalculation_SR
2927 * This function is used for ni_check_hw_info()
2928 *
2929 * \param encoder_param
2930 *
2931 * \return task encoder shared memeory uasge
2932 ********************************************************************************/
2933 static int check_hw_info_encoder_shared_mem_usage(const ni_hw_device_info_quadra_encoder_param_t *encoder_param)
2934 {
2935  // const int p_1080 = 2073600;
2936  // const int p_1440 = 3686400;
2937  // const int p_4k = 8294400;
2938 
2939  if(!encoder_param)
2940  {
2941  return 0;
2942  }
2943 
2944  //cppcheck do not allow this
2945  // const int v32_ofCores = 0;
2946 
2947  // int encoder_shared_mem_usage = 0;
2948 
2949  // int v32_ofCores_calculate = ((v32_ofCores>0)?v32_ofCores:1)-1;
2950  //cppcheck do not allow this
2951 
2952  const int v32_ofCores_calculate = 0;
2953 
2954  int b_counts = (int)(v32_ofCores_calculate +
2955  ((encoder_param->lookaheadDepth > 0) ? encoder_param->lookaheadDepth + 8/2 + v32_ofCores_calculate : 0 )+
2956  8 +
2957  (encoder_param->uploader ? 1 : 0) * 3 +
2958  1) * 1;
2959  int b_scale = check_hw_info_shared_mem_calculate_b_scale(encoder_param->h, encoder_param->w,
2960  encoder_param->bit_8_10, encoder_param->rgba);
2961  return b_scale * b_counts;
2962 
2963 }
2964 
2965 /*!*****************************************************************************
2966 * \brief Calculate decoder shared memory usage
2967 * The computing method is from MemUsageCalculation_SR
2968 * This function is used for ni_check_hw_info()
2969 *
2970 * \param decoder_param
2971 * \param estimated_max_dpb
2972 *
2973 * \return task decoder shared memeory uasge
2974 ********************************************************************************/
2975 static int check_hw_info_decoder_shared_mem_usage(const ni_hw_device_info_quadra_decoder_param_t *decoder_param,int estimated_max_dpb)
2976 {
2977  // const int p_1080 = 2073600;
2978  // const int p_1440 = 3686400;
2979  // const int p_4k = 8294400;
2980 
2981  if(!decoder_param)
2982  {
2983  return 0;
2984  }
2985  const int hw_frame = decoder_param->hw_frame;
2986 
2987  const int v30_xlsx = 0;
2988  int b_counts = 1 * (v30_xlsx +
2989  (hw_frame ? 0 : 1)*3 +
2990  estimated_max_dpb);
2991  int b_scale = check_hw_info_shared_mem_calculate_b_scale(decoder_param->h, decoder_param->w,
2992  decoder_param->bit_8_10, decoder_param->rgba);
2993  return b_scale * b_counts;
2994 }
2995 
2996 /*!*****************************************************************************
2997 * \brief Calculate scaler shared memory usage
2998 * The computing method is from MemUsageCalculation_SR
2999 * This function is used for ni_check_hw_info()
3000 *
3001 * \param scaler_param
3002 * \param estimated_max_dpb
3003 *
3004 * \return task scaler shared memeory uasge
3005 ********************************************************************************/
3006 static int check_hw_info_scaler_shared_mem_usage(const ni_hw_device_info_quadra_scaler_param_t *scaler_param,int estimated_max_dpb)
3007 {
3008  // const int p_1080 = 2073600;
3009  // const int p_1440 = 3686400;
3010  // const int p_4k = 8294400;
3011 
3012 
3013  if(!scaler_param)
3014  {
3015  return 0;
3016  }
3017  // const int hw_frame = 1;
3018  //cppcheck do not allow this
3019 
3020  const int v30_xlsx = 0;
3021  int b_counts = 1 * (v30_xlsx +
3022  0/* (hw_frame ? 0 : 1)*3 */ +
3023  estimated_max_dpb);
3024  int b_scale = check_hw_info_shared_mem_calculate_b_scale(scaler_param->h, scaler_param->w,
3025  scaler_param->bit_8_10, scaler_param->rgba);
3026  return b_scale * b_counts;
3027 }
3028 
3029 
3030 /*!*************************************************************************************************
3031 * \brief Remove unsupported card in ni_check_hw_info() by memroy
3032 * This function is used for ni_check_hw_info()
3033 *
3034 * \param[in] card_remove
3035 * \param[in] ni_card_info
3036 * \param[in] card_num
3037 * \param[in] coder_param
3038 * \param[in] mode mode == 0->decoder, mode == 1->encoder, mode == 2->scaler, mode > 3->all
3039 *
3040 * \return NONE
3041 ****************************************************************************************************/
3042 static void check_hw_info_remove_card_with_memory(int *card_remove, const ni_hw_device_info_quadra_t *ni_card_info, int card_num, const ni_hw_device_info_quadra_coder_param_t *coder_param,int mode)
3043 {
3044  const int total = 2456;//buffer count summary
3045  int task_mem_usage = 0;
3046  int task_mem_precentage = 0;
3047  int i;
3048 
3049  if(!ni_card_info)
3050  {
3051  ni_log(NI_LOG_ERROR, "card_info is NULL mark all cards as removed\n");
3052  for(i = 0; i < card_num; ++i)
3053  {
3054  card_remove[i] = 1;
3055  }
3056  return;
3057  }
3058 
3059  if(mode == 0)
3060  {
3061  task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->decoder_param,16);
3062  }
3063  else if(mode == 1)
3064  {
3065  task_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->encoder_param);
3066  }
3067  else if(mode == 2)
3068  {
3069  task_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->scaler_param,16);
3070  }
3071  else if(mode > 3)
3072  {
3073  int decoder_shared_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->decoder_param,16);
3074  int encoder_shared_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->encoder_param);
3075  int scaler_shared_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->scaler_param,16);
3076  task_mem_usage = decoder_shared_mem_usage + ((encoder_shared_mem_usage > scaler_shared_mem_usage) ?
3077  encoder_shared_mem_usage : scaler_shared_mem_usage);
3078  }
3079  else
3080  {
3081  ni_log(NI_LOG_ERROR, "parameter:mode is out of range\n");
3082  task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->decoder_param,16) +
3083  check_hw_info_encoder_shared_mem_usage(coder_param->encoder_param)+
3084  check_hw_info_scaler_shared_mem_usage(coder_param->scaler_param,16);
3085  }
3086 
3087  task_mem_precentage = 100 * task_mem_usage / total;
3088 
3089  if(task_mem_precentage > 90)
3090  {
3091  //calculate mem usage is an estimated num , maybe too big
3092  task_mem_precentage = 90;
3093  }
3094 
3095  for(i = 0;i<card_num;++i)
3096  {
3097  if(card_remove[i] == 1)
3098  {
3099  continue;
3100  }
3101 
3102  if(task_mem_precentage + ni_card_info->card_info[0][i].shared_mem_usage >= 100)//all shared memory usages are the same in one card
3103  {
3104  card_remove[i] = 1;
3105  }
3106  }
3107 
3108 }
3109 
3110 /*!*********************************************************************************************
3111 * \brief Create and alloc a pointer to ni_hw_device_info_quadra_coder_param_t
3112 * This function is used for ni_check_hw_info()
3113 *
3114 * \param[in] mode 0 for decoder,1 for encoder,2 for scaler,3 for AI, >= 4 for hw_mode
3115 *
3116 * \return a pointer to ni_hw_device_info_quadra_coder_param_t on success,NULL for otherwise
3117 ***********************************************************************************************/
3119 {
3120  ni_hw_device_info_quadra_coder_param_t *p_coder_param = NULL;
3122  if(p_coder_param == NULL)
3123  {
3124  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_coder_param\n");
3125  return p_coder_param;
3126  }
3127  memset(p_coder_param,0,sizeof(ni_hw_device_info_quadra_coder_param_t));
3128  p_coder_param->hw_mode = 0;
3129  if(mode == 0)//decoder
3130  {
3132  if(p_coder_param->decoder_param == NULL)
3133  {
3134  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3135  free(p_coder_param);
3136  p_coder_param = NULL;
3137  return p_coder_param;
3138  }
3139  }
3140  else if(mode == 1)//encoder
3141  {
3143  if(p_coder_param->encoder_param == NULL)
3144  {
3145  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3146  free(p_coder_param);
3147  p_coder_param = NULL;
3148  return p_coder_param;
3149  }
3150  }
3151  else if(mode == 2)//scaler
3152  {
3154  if(p_coder_param->scaler_param == NULL)
3155  {
3156  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3157  free(p_coder_param);
3158  p_coder_param = NULL;
3159  return p_coder_param;
3160  }
3161  }
3162  else if(mode == 3)//AI
3163  {
3165  if(p_coder_param->ai_param == NULL)
3166  {
3167  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3168  free(p_coder_param);
3169  p_coder_param = NULL;
3170  return p_coder_param;
3171  }
3172  }
3173  else//hw_mode
3174  {
3176  if(p_coder_param->encoder_param == NULL)
3177  {
3178  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3179  free(p_coder_param);
3180  p_coder_param = NULL;
3181  return p_coder_param;
3182  }
3184  if(p_coder_param->decoder_param == NULL)
3185  {
3186  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3187  free(p_coder_param->encoder_param);
3188  p_coder_param->encoder_param = NULL;
3189  free(p_coder_param);
3190  p_coder_param = NULL;
3191  return p_coder_param;
3192  }
3194  if(p_coder_param->scaler_param == NULL)
3195  {
3196  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3197  free(p_coder_param->encoder_param);
3198  p_coder_param->encoder_param = NULL;
3199  free(p_coder_param->decoder_param);
3200  p_coder_param->decoder_param = NULL;
3201  free(p_coder_param);
3202  p_coder_param = NULL;
3203  return p_coder_param;
3204  }
3206  if(p_coder_param->ai_param == NULL)
3207  {
3208  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3209  free(p_coder_param->encoder_param);
3210  p_coder_param->encoder_param = NULL;
3211  free(p_coder_param->decoder_param);
3212  p_coder_param->decoder_param = NULL;
3213  free(p_coder_param->scaler_param);
3214  p_coder_param->scaler_param = NULL;
3215  free(p_coder_param);
3216  p_coder_param = NULL;
3217  return p_coder_param;
3218  }
3219  p_coder_param->hw_mode = 1;
3220  }
3221  if(p_coder_param->encoder_param)
3222  {
3223  p_coder_param->encoder_param->bit_8_10 = 8;
3224  p_coder_param->encoder_param->code_format = 0;
3225  p_coder_param->encoder_param->fps = 30;
3226  p_coder_param->encoder_param->lookaheadDepth = 0;
3227  p_coder_param->encoder_param->rdoLevel = 0;
3228  p_coder_param->encoder_param->w = 1920;
3229  p_coder_param->encoder_param->h = 1080;
3230  p_coder_param->encoder_param->ui8enableRdoQuant = 0;
3231  p_coder_param->encoder_param->uploader = 0;
3232  p_coder_param->encoder_param->rgba = 0;
3233  }
3234  if(p_coder_param->decoder_param)
3235  {
3236  p_coder_param->decoder_param->w = 1920;
3237  p_coder_param->decoder_param->h = 1080;
3238  p_coder_param->decoder_param->bit_8_10 = 8;
3239  p_coder_param->decoder_param->fps = 30;
3240  p_coder_param->decoder_param->rgba = 0;
3241  p_coder_param->decoder_param->hw_frame = 1;
3242  }
3243  if(p_coder_param->scaler_param)
3244  {
3245  p_coder_param->scaler_param->h = 1920;
3246  p_coder_param->scaler_param->w = 1080;
3247  p_coder_param->scaler_param->bit_8_10 = 8;
3248  p_coder_param->scaler_param->rgba = 0;
3249  }
3250  if(p_coder_param->ai_param)
3251  {
3252  p_coder_param->ai_param->h = 1920;
3253  p_coder_param->ai_param->w = 1080;
3254  p_coder_param->ai_param->bit_8_10 = 8;
3255  p_coder_param->ai_param->rgba = 0;
3256  }
3257  return p_coder_param;
3258 }
3259 
3260 
3261 /*!*********************************************************************************************
3262 * \brief Free resource in p_hw_device_info_quadra_coder_param
3263 * This function is used for ni_check_hw_info()
3264 *
3265 * \param[in] device_type_num
3266 *
3267 * \param[in] avaliable_card_num
3268 *
3269 * \return a pointer to ni_hw_device_info_quadra_t on success,NULL for otherwise
3270 ***********************************************************************************************/
3272 {
3273  if(p_hw_device_info_quadra_coder_param == NULL)
3274  {
3275  return;
3276  }
3277  if(p_hw_device_info_quadra_coder_param->encoder_param)
3278  {
3279  free(p_hw_device_info_quadra_coder_param->encoder_param);
3280  p_hw_device_info_quadra_coder_param->encoder_param = NULL;
3281  }
3282  if(p_hw_device_info_quadra_coder_param->decoder_param)
3283  {
3284  free(p_hw_device_info_quadra_coder_param->decoder_param);
3285  p_hw_device_info_quadra_coder_param->decoder_param = NULL;
3286  }
3287  if(p_hw_device_info_quadra_coder_param->scaler_param)
3288  {
3289  free(p_hw_device_info_quadra_coder_param->scaler_param);
3290  p_hw_device_info_quadra_coder_param->scaler_param = NULL;
3291  }
3292  if(p_hw_device_info_quadra_coder_param->ai_param)
3293  {
3294  free(p_hw_device_info_quadra_coder_param->ai_param);
3295  p_hw_device_info_quadra_coder_param->ai_param = NULL;
3296  }
3297  free(p_hw_device_info_quadra_coder_param);
3298  return;
3299 }
3300 
3301 /*!*********************************************************************************************
3302 * \brief Create a ni_hw_device_info_quadra_t
3303 * This function is used for ni_check_hw_info()
3304 *
3305 * \param[in] device_type_num
3306 * \param[in] avaliable_card_num
3307 *
3308 * \return a pointer to ni_hw_device_info_quadra_t on success,NULL for otherwise
3309 ***********************************************************************************************/
3310 ni_hw_device_info_quadra_t *ni_hw_device_info_alloc_quadra(int device_type_num,int avaliable_card_num)
3311 {
3312  int i;
3314  if(!p_hw_device_info)
3315  {
3316  ni_log(NI_LOG_ERROR,"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t\n");
3317  goto p_hw_device_info_end;
3318  }
3319 
3320  p_hw_device_info->device_type_num = device_type_num;
3321  p_hw_device_info->device_type = (ni_device_type_t *)malloc(sizeof(ni_device_type_t) * device_type_num);
3322  if(!p_hw_device_info->device_type)
3323  {
3324  ni_log(NI_LOG_ERROR,"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t->device_type\n");
3325  goto device_type_end;
3326  }
3327 
3328  p_hw_device_info->card_info = (ni_card_info_quadra_t **)malloc(sizeof(ni_card_info_quadra_t*) * p_hw_device_info->device_type_num);
3329  if(p_hw_device_info->card_info == NULL)
3330  {
3331  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for p_hw_device_info_quadra_t->card_info\n", NI_ERRNO);
3332  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3333  //unlock_and_return
3334  goto card_info_end;
3335  }
3336  memset(p_hw_device_info->card_info, 0, sizeof(ni_card_info_quadra_t*) * p_hw_device_info->device_type_num);
3337 
3338  p_hw_device_info->available_card_num = avaliable_card_num;
3339  p_hw_device_info->consider_mem = 0;
3340  for(i = 0; i < p_hw_device_info->device_type_num; ++i)
3341  {
3342  p_hw_device_info->card_info[i] = (ni_card_info_quadra_t *)malloc(sizeof(ni_card_info_quadra_t) * p_hw_device_info->available_card_num);
3343  if(p_hw_device_info->card_info[i] == NULL)
3344  {
3345  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for p_hw_device_info_quadra_t->card_info\n", NI_ERRNO);
3346  goto card_info_i_end;
3347  }
3348  }
3349 
3350  return p_hw_device_info;
3351 
3352 card_info_i_end:
3353  for(i = 0; i < p_hw_device_info->device_type_num; ++i)
3354  {
3355  if(p_hw_device_info->card_info[i])
3356  {
3357  free(p_hw_device_info->card_info[i]);
3358  p_hw_device_info->card_info[i] = NULL;
3359  }
3360  }
3361  free(p_hw_device_info->card_info);
3362  p_hw_device_info->card_info = NULL;
3363 card_info_end:
3364  free(p_hw_device_info->device_type);
3365  p_hw_device_info->device_type = NULL;
3366 device_type_end:
3367  free(p_hw_device_info);
3368  p_hw_device_info = NULL;
3369 p_hw_device_info_end:
3370  return NULL;
3371 }
3372 
3373 /*!*********************************************************************************************
3374 * \brief Free resource in a pointer of ni_hw_device_info_quadra_t
3375 * This function is used for ni_check_hw_info()
3376 *
3377 * \param[in] p_hw_device_info Poiner to a ni_hw_device_info_quadra_t struct
3378 *
3379 * \return None
3380 ***********************************************************************************************/
3382 {
3383  int i;
3384  if(!p_hw_device_info)
3385  {
3386  return;
3387  }
3388  free(p_hw_device_info->device_type);
3389  p_hw_device_info->device_type = NULL;
3390  for(i = 0; i < p_hw_device_info->device_type_num; ++i)
3391  {
3392  free(p_hw_device_info->card_info[i]);
3393  p_hw_device_info->card_info[i] = NULL;
3394  }
3395  free(p_hw_device_info->card_info);
3396  p_hw_device_info->card_info = NULL;
3397  free(p_hw_device_info);
3398  return;
3399 }
3400 
3401 int ni_check_hw_info(ni_hw_device_info_quadra_t **pointer_to_p_hw_device_info,
3402  int task_mode,
3403  ni_hw_device_info_quadra_threshold_param_t *hw_info_threshold_param,
3404  ni_device_type_t preferential_device_type,
3406  int hw_mode,
3407  int consider_mem)
3408 {
3409  //order of ni_hw_device_info_quadra_threshold_param_t *hw_info_threshold_param, order
3410  //order of ni_device_type_t all_need_device_type
3411  //ni_device_type_t preferential_device_type, in the first place
3412  //other order of device_type ni_device_type_t adjust to the order of all_need_device_type
3413  //int hw_info_param_num = hw_mode ? 2 : 1;adjust to 3
3414  int should_match_rev = 1;
3415  int module_count = 1;
3416  ni_device_context_t *dev_ctxt_arr = NULL;
3417  int32_t *module_id_arr = NULL;
3418  // int32_t best_load_module_id = -1;
3419  ni_device_pool_t *p_device_pool = NULL;
3420  ni_device_queue_t *coders = NULL;
3421  ni_device_context_t *p_device_context = NULL;
3422  ni_session_context_t xCtxt = { 0 };
3423  int *card_remove = NULL;//cards which are not satisfied threshold
3424  // uint64_t reserved_memory = 0;
3425  // int needed_memory = 0;
3426  uint64_t decoder_need_load = 0;
3427  uint64_t encoder_need_load = 0;
3428  int retval = 0;//1 for success , 0 for failure
3429  int ret = 0;
3430  int hw_info_param_num = hw_mode ? 4 : 1;
3431  int device_type_num = 1;
3432  const int all_device_type_num = 4;
3433 
3434  ni_device_type_t all_need_device_type[4] = {NI_DEVICE_TYPE_DECODER,NI_DEVICE_TYPE_ENCODER,NI_DEVICE_TYPE_SCALER,NI_DEVICE_TYPE_AI};//decoder encoder scaler and AI
3435  /*note: preference device type will be moved to all_need_device_type[0],
3436  * and sequence of device type in other structs(such as p_hw_device_info.device_type) will be changed in the order of all_need_device_type
3437  */
3438 
3439  int i = 0;
3440  bool b_valid = false;
3441 
3442 
3443  // int *mem_usage = NULL;
3444 
3445  ni_hw_device_info_quadra_t *p_hw_device_info = NULL;
3446 
3447  //check hw_info_param
3448  if(!pointer_to_p_hw_device_info)
3449  {
3450  ni_log(NI_LOG_ERROR, "Error: Invalid input params: pointer_to_p_hw_device_info is NULL.\n");
3451  return retval;
3452  }
3453 
3454  if(*pointer_to_p_hw_device_info)
3455  {
3456  p_hw_device_info = *pointer_to_p_hw_device_info;
3457  b_valid = true;
3458  }
3459 
3460  // Check input parameters here
3461  if(!coder_param){
3462  if(b_valid)
3463  {
3464  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3465  }
3466  ni_log(NI_LOG_ERROR, "Error: Invalid input params: coder_param is NULL.\n");
3467  return retval;
3468  }else if(hw_mode && hw_mode != coder_param->hw_mode)
3469  {
3470  ni_log(NI_LOG_ERROR, "Error: Invalid input params: hw_mode = %d, coder_param->hw_mode = %d\n",
3471  hw_mode,coder_param->hw_mode);
3472  return retval;
3473  }else if(!hw_mode)
3474  {
3475  if(preferential_device_type == NI_DEVICE_TYPE_ENCODER && coder_param->encoder_param == NULL)
3476  {
3477  ni_log(NI_LOG_ERROR, "Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_ENCODER but coder_param->encoder_param == NULL\n");
3478  return retval;
3479  }
3480  if(preferential_device_type == NI_DEVICE_TYPE_DECODER && coder_param->decoder_param == NULL)
3481  {
3482  ni_log(NI_LOG_ERROR, "Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_DECODER but coder_param->decoder_param == NULL\n");
3483  return retval;
3484  }
3485  if(preferential_device_type == NI_DEVICE_TYPE_SCALER && coder_param->scaler_param == NULL)
3486  {
3487  ni_log(NI_LOG_ERROR, "Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_SCALER but coder_param->scaler_param == NULL\n");
3488  return retval;
3489  }
3490  if(preferential_device_type == NI_DEVICE_TYPE_AI && coder_param->ai_param == NULL)
3491  {
3492  ni_log(NI_LOG_ERROR, "Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_AI but coder_param->ai_param == NULL\n");
3493  return retval;
3494  }
3495  }
3496 
3497 
3498  if((task_mode != 0 && task_mode != 1) ||
3499  (preferential_device_type != NI_DEVICE_TYPE_DECODER && preferential_device_type != NI_DEVICE_TYPE_ENCODER &&
3500  preferential_device_type != NI_DEVICE_TYPE_SCALER && preferential_device_type != NI_DEVICE_TYPE_AI))//scaler
3501  {
3502  if(b_valid)
3503  {
3504  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3505  }
3506  ni_log(NI_LOG_ERROR, "Error: Invalid input params: realtime %d device_type %d\n",
3507  task_mode, preferential_device_type);
3508  return retval;
3509  }
3510 
3511  if(!hw_info_threshold_param)
3512  {
3513  if(b_valid)
3514  {
3515  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3516  }
3517  ni_log(NI_LOG_ERROR, "Error: Invalid input params: hw_info_threshold_param is NULL.\n");
3518  return retval;
3519  }else{
3520  for(i = 0;i < hw_info_param_num; ++i)
3521  {
3522  if(hw_info_threshold_param[i].load_threshold < 0||//check this
3523  hw_info_threshold_param[i].load_threshold > 100 ||
3524  hw_info_threshold_param[i].task_num_threshold < 0 ||
3525  hw_info_threshold_param[i].task_num_threshold > NI_MAX_CONTEXTS_PER_HW_INSTANCE||
3526  ( hw_info_threshold_param[i].device_type != NI_DEVICE_TYPE_DECODER &&
3527  hw_info_threshold_param[i].device_type != NI_DEVICE_TYPE_ENCODER &&
3528  hw_info_threshold_param[i].device_type != NI_DEVICE_TYPE_SCALER &&
3529  hw_info_threshold_param[i].device_type != NI_DEVICE_TYPE_AI))
3530  {
3531  if(b_valid)
3532  {
3533  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3534  }
3535  ni_log(NI_LOG_ERROR, "Error: Invalid input params: In %s, hw_info_threshold_param[%d].device_type = %d, hw_info_threshold_param[%d].load_threshold = %d, hw_info_threshold_param[%d].task_num_threshold = %d\n",
3536  (hw_mode ? "hardware_mode":"software_mode"), i, hw_info_threshold_param[i].device_type, i, hw_info_threshold_param[i].load_threshold, i, hw_info_threshold_param[i].task_num_threshold);
3537  return retval;
3538  }
3539  }
3540  }
3541  // all parameters have been checked
3542 
3543  /* For load calculations and checking, restrict FPS to be within 5 - 120 */
3544  if(coder_param->encoder_param)
3545  {
3546  if(coder_param->encoder_param->fps > 120)
3547  {
3548  coder_param->encoder_param->fps = 120;
3549  }
3550  if(coder_param->encoder_param->fps < 5)
3551  {
3552  coder_param->encoder_param->fps = 5;
3553  }
3554  }
3555  if(coder_param->decoder_param)
3556  {
3557  if(coder_param->decoder_param->fps > 120)
3558  {
3559  coder_param->decoder_param->fps = 120;
3560  }
3561  if(coder_param->decoder_param->fps < 5)
3562  {
3563  coder_param->decoder_param->fps = 5;
3564  }
3565  }
3566 
3567  //ni_rsrc_init() is unsafe in multi process/thread ,do not call ni_rsrc_init() here
3568 
3569  if (NI_RETCODE_SUCCESS != (ret = ni_rsrc_refresh(should_match_rev)))
3570  {
3571  ni_log(NI_LOG_ERROR, "Error: resource pool records might be corrupted!!\n");
3572  if(b_valid)
3573  {
3574  p_hw_device_info->err_code = ret;
3575  }
3576  return retval;
3577  }
3578 
3579  p_device_pool = ni_rsrc_get_device_pool();
3580  if (!p_device_pool)
3581  {
3582  ni_log(NI_LOG_ERROR, "Error:Can not get device pool info ..\n");
3583  if(b_valid)
3584  {
3585  p_hw_device_info->err_code = NI_RETCODE_ERROR_GET_DEVICE_POOL;
3586  }
3587  return retval;
3588  }
3589 
3590 #ifdef _WIN32
3591  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval)
3592  {
3593  ni_log(NI_LOG_ERROR, "ERROR: Failed to obtain mutex: %p\n", p_device_pool->lock);
3594  LRETURN;
3595  }
3596 #elif defined(__linux__)
3597  if (lockf(p_device_pool->lock, F_LOCK, 0))
3598  {
3599  ni_log(NI_LOG_ERROR, "Error lockf() failed\n");
3600  if(b_valid)
3601  {
3602  p_hw_device_info->err_code = NI_RETCODE_ERROR_LOCK_DOWN_DEVICE;
3603  }
3604  LRETURN;
3605  }
3606 #endif
3607 
3608  coders = p_device_pool->p_device_queue;
3609  if (!coders)
3610  {
3611  ni_log(NI_LOG_ERROR, "Error pdevice_queue null!!\n");
3612  if(b_valid)
3613  {
3614  p_hw_device_info->err_code = NI_RETCODE_ERROR_GET_DEVICE_POOL;
3615  }
3616  LRETURN;
3617  }
3618 
3620 
3621 
3622  // move preferential_device_type in all_need_device_type to top
3623  for(i = 0; i < all_device_type_num; ++i)
3624  {
3625  if(all_need_device_type[i] == preferential_device_type)
3626  {
3627  ni_device_type_t tmp = all_need_device_type[i];
3628  all_need_device_type[i] = all_need_device_type[0];
3629  all_need_device_type[0] = tmp;
3630  break;
3631  }
3632  //ni_device_type_t is a enum
3633  }
3634  qsort(&all_need_device_type[1], all_device_type_num - 1, sizeof(ni_device_type_t), int_cmp);
3635 
3636  //adjust order of hw_info_threshold_param as all_need_device_type
3637  if(hw_mode)
3638  {
3639  // default device_type_num is 1
3640  device_type_num = 4;//decoder and encoder and scaler and AI
3641  //adjust order of hw_info_threshold_param as all_need_device_type
3642  for(i = 0; i < device_type_num; ++i)
3643  {
3644  if(hw_info_threshold_param[i].device_type == preferential_device_type)
3645  {
3646  ni_hw_device_info_quadra_threshold_param_t tmp = hw_info_threshold_param[i];
3647  hw_info_threshold_param[i] = hw_info_threshold_param[0];
3648  hw_info_threshold_param[0] = tmp;
3649  break;
3650  }
3651  }
3652  qsort(&hw_info_threshold_param[1], device_type_num - 1,
3653  sizeof(ni_hw_device_info_quadra_threshold_param_t), ni_hw_device_info_quadra_threshold_param_t_compare);
3654  }
3655 
3656  if(!(*pointer_to_p_hw_device_info))
3657  {
3658  p_hw_device_info = ni_hw_device_info_alloc_quadra(device_type_num,coders->xcoder_cnt[preferential_device_type]);
3659  if(!p_hw_device_info)
3660  {
3661  ni_log(NI_LOG_ERROR,"ERROR: Failed to allocate memory for p_hw_device_info\n");
3662  LRETURN;
3663  }
3664  *pointer_to_p_hw_device_info = p_hw_device_info;
3665  b_valid = true;
3666  }
3667  else
3668  {
3669  // p_hw_device_info = *pointer_to_p_hw_device_info;
3670  //already set this before
3671 
3672  //if user alloc hw_device_info themself check it
3673  if(!p_hw_device_info->device_type)
3674  {
3675  ni_log(NI_LOG_ERROR,"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->device_type is NULL\n");
3676  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3677  LRETURN;
3678  }
3679  if(!p_hw_device_info->card_info)
3680  {
3681  ni_log(NI_LOG_ERROR,"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->card_info is NULL\n");
3682  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3683  LRETURN;
3684  }
3685  for(i = 0; i < device_type_num; ++i)
3686  {
3687  if(!p_hw_device_info->card_info[i])
3688  {
3689  ni_log(NI_LOG_ERROR,"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->card_info[%d] is NULL\n", i);
3690  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3691  LRETURN;
3692  }
3693  }
3694  }
3695  //p_hw_device_info alloc succeed
3696 
3697  //coders->decoders_cnt == coder->encoders_cnt has checked in the ni_logan_rsrc_refresh
3698  p_hw_device_info->available_card_num = coders->xcoder_cnt[preferential_device_type];
3699  p_hw_device_info->device_type_num = device_type_num;
3700 
3701  for(i = 0; i < p_hw_device_info->device_type_num; ++i)
3702  {
3703  p_hw_device_info->device_type[i] = all_need_device_type[i];
3704  for(int j = 0; j < p_hw_device_info->available_card_num; ++j)
3705  {
3706  p_hw_device_info->card_info[i][j].card_idx = -1;
3707  p_hw_device_info->card_info[i][j].load = -1;
3708  p_hw_device_info->card_info[i][j].model_load = -1;
3709  p_hw_device_info->card_info[i][j].task_num = -1;
3710  p_hw_device_info->card_info[i][j].max_task_num = NI_MAX_CONTEXTS_PER_HW_INSTANCE;
3711  p_hw_device_info->card_info[i][j].shared_mem_usage = -1;
3712  p_hw_device_info->card_info[i][j].firmware_load = -1;
3713  }
3714  }
3715 
3716  p_hw_device_info->card_current_card = -1;
3717  p_hw_device_info->err_code = NI_RETCODE_SUCCESS;
3719 
3720  if(consider_mem)
3721  {
3722  // mem_usage = (int *)malloc(sizeof(int) * (p_hw_device_info->available_card_num));
3723  // if(!mem_usage)
3724  // {
3725  // ni_log(NI_LOG_ERROR,"ERROR: Failed to allocate memory for p_hw_device_info\n");
3726  // p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3727  // LRETURN;
3728  // }
3729  p_hw_device_info->consider_mem = 1;
3730  }
3731  else
3732  {
3733  p_hw_device_info->consider_mem = 0;
3734  }
3735 
3736  if (p_hw_device_info->available_card_num <= 0)
3737  {
3738  LRETURN;
3739  }
3740 
3741  card_remove = (int32_t *)malloc(sizeof(int32_t) * p_hw_device_info->available_card_num);
3742  if (!card_remove)
3743  {
3744  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for card_remove\n", NI_ERRNO);
3745  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3746  LRETURN;
3747  }
3748  memset(card_remove, 0, sizeof(int32_t) * p_hw_device_info->available_card_num);
3749 
3750 
3751  module_count = coders->xcoder_cnt[preferential_device_type];
3752  dev_ctxt_arr = (ni_device_context_t *)malloc(sizeof(ni_device_context_t) * module_count);
3753  if (!dev_ctxt_arr)
3754  {
3755  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for ni_rsrc_detect\n", NI_ERRNO);
3756  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3757  LRETURN;
3758  }
3759  module_id_arr = (int32_t *)malloc(sizeof(int32_t) * module_count);
3760  if (!module_id_arr)
3761  {
3762  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for ni_rsrc_detect\n", NI_ERRNO);
3763  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3764  LRETURN;
3765  }
3766 
3767  //info start
3768  memcpy(module_id_arr, coders->xcoders[preferential_device_type], sizeof(int32_t) * module_count);//copy useful card
3769 
3770  //First module ID in coders->decoders/encoders is of lowest load
3771  // memcpy((void *)&best_load_module_id, module_id_arr, sizeof(int32_t));
3772  qsort(module_id_arr, module_count, sizeof(int32_t), int_cmp);// why?
3773 
3774  // p_hw_device_info->card_current_card = best_load_module_id;
3775 
3776  for(i = 0; i < p_hw_device_info->available_card_num; ++i)
3777  {
3778  for(int j = 0; j < device_type_num; ++j)//need to fix this
3779  {
3780  memset(&xCtxt, 0, sizeof(xCtxt));
3781  p_device_context = ni_rsrc_get_device_context(all_need_device_type[j], module_id_arr[i]);
3782  if(p_device_context)
3783  {
3784  xCtxt.blk_io_handle = ni_device_open(p_device_context->p_device_info->blk_name,
3785  &(xCtxt.max_nvme_io_size));
3786  xCtxt.device_handle = xCtxt.blk_io_handle;
3787  //Check device can be opend
3788  if (NI_INVALID_DEVICE_HANDLE == xCtxt.device_handle)
3789  {
3790  ni_log(NI_LOG_ERROR, "Error open device %s, blk device %s\n",
3791  p_device_context->p_device_info->dev_name,
3792  p_device_context->p_device_info->blk_name);
3793  ni_rsrc_free_device_context(p_device_context);
3794  card_remove[i] = 1;
3795  continue;
3796  }
3797 #ifdef _WIN32
3798  xCtxt.event_handle = ni_create_event();
3799  if (NI_INVALID_EVENT_HANDLE == xCtxt.event_handle)
3800  {
3801  ni_rsrc_free_device_context(p_device_context);
3803  ni_log(NI_LOG_ERROR, "ERROR %d: print_perf() create event\n", NI_ERRNO);
3804  card_remove[i] = 1;
3805  continue;
3806  }
3807 #endif
3808  //Check decode/encode can be queired
3809  xCtxt.hw_id = p_device_context->p_device_info->hw_id;
3810  if (NI_RETCODE_SUCCESS != ni_device_session_query(&xCtxt, all_need_device_type[j]))
3811  {
3813 #ifdef _WIN32
3815 #endif
3816  ni_log(NI_LOG_ERROR, "Error query %s %s %s.%d\n",
3817  (all_need_device_type[j] == NI_DEVICE_TYPE_DECODER) ? "decoder" :
3818  (all_need_device_type[j] == NI_DEVICE_TYPE_ENCODER) ? "encoder" :
3819  (all_need_device_type[j] == NI_DEVICE_TYPE_SCALER) ? "scaler " : "AIs ",
3820  p_device_context->p_device_info->dev_name,
3821  p_device_context->p_device_info->blk_name,
3822  p_device_context->p_device_info->hw_id);
3823  ni_rsrc_free_device_context(p_device_context);
3824  card_remove[i] = 1;
3825  continue;
3826  }
3828 #ifdef _WIN32
3830 #endif
3831  if (0 == xCtxt.load_query.total_contexts)
3832  {
3833  xCtxt.load_query.current_load = 0;
3834  }
3835 
3836  p_hw_device_info->card_info[j][i].card_idx = p_device_context->p_device_info->module_id;
3837 
3838  //use model_load in card remove for encoder just like before
3839 #ifdef XCODER_311
3840  p_hw_device_info->card_info[j][i].load = xCtxt.load_query.current_load; //monitor changes this
3841 
3842 #else
3843  p_hw_device_info->card_info[j][i].load =
3845 #endif
3846  // module_load_user_can_not_see[j][i] = xCtxt.load_query.fw_model_load;
3847  p_hw_device_info->card_info[j][i].model_load = xCtxt.load_query.fw_model_load;
3848 
3849  p_hw_device_info->card_info[j][i].task_num = xCtxt.load_query.total_contexts;
3850  p_hw_device_info->card_info[j][i].max_task_num = NI_MAX_CONTEXTS_PER_HW_INSTANCE;
3851 
3852  p_hw_device_info->card_info[j][i].firmware_load = xCtxt.load_query.fw_load;
3853  if(consider_mem)
3854  {
3855  // mem_usage[i] = xCtxt.load_query.fw_share_mem_usage;
3856  p_hw_device_info->card_info[j][i].shared_mem_usage = xCtxt.load_query.fw_share_mem_usage;
3857  }
3858  ni_rsrc_free_device_context(p_device_context);
3859  p_device_context = NULL;
3860  }
3861  else
3862  {
3863  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to get device context\n", NI_ERRNO);
3864  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3865  LRETURN;
3866  }
3867  }
3868 
3869  }
3870 
3871  if(coder_param->decoder_param)
3872  {
3873  decoder_need_load = check_hw_info_decoder_need_load(coder_param->decoder_param);
3874  }
3875  if(coder_param->encoder_param)
3876  {
3877  encoder_need_load = check_hw_info_encoder_need_load(coder_param->encoder_param);
3878  }
3879  // if(coder_param->scaler_param)
3880  // {
3881  //cane not estimate scaler load now
3882  // }
3883 
3884  //mark the card removed depends on the load_threshold or task_num_threshold
3885  //in hw_mode ,device_type_num == 4 but only encoder and decoder will be taken into account,we can not estimate scaler load now
3886  //in sw mode ,device_type_num == 1 only preferitial_device_type will be taken into account
3887  for(i = 0; i < p_hw_device_info->available_card_num; ++i)
3888  {
3889  for(int j = 0; j < p_hw_device_info->device_type_num; ++j)
3890  {
3891 #ifdef XCODER_311
3892  ni_log(NI_LOG_DEBUG, "%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3893 #else
3894  ni_log(NI_LOG_INFO, "%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3895 #endif
3896  (p_hw_device_info->device_type[j] == NI_DEVICE_TYPE_DECODER ? "Decoder" :
3897  ((p_hw_device_info->device_type[j] == NI_DEVICE_TYPE_ENCODER) ? "Encoder" :
3898  (p_hw_device_info->device_type[j] == NI_DEVICE_TYPE_SCALER) ? "Scaler " : "AIs ")),
3899  p_hw_device_info->card_info[j][i].card_idx,
3900  p_hw_device_info->card_info[j][i].load,
3901  p_hw_device_info->card_info[j][i].task_num,
3902  p_hw_device_info->card_info[j][i].firmware_load,
3903  p_hw_device_info->card_info[j][i].model_load,
3904  p_hw_device_info->card_info[j][i].shared_mem_usage);
3905 
3906  if(card_remove[i] == 1)
3907  {
3908  continue;//for print
3909  }
3910 
3911  if(all_need_device_type[j] == NI_DEVICE_TYPE_DECODER)
3912  {
3913  if(decoder_need_load + p_hw_device_info->card_info[j][i].model_load >= 100)
3914  {
3915  card_remove[i] = 1;
3916  }
3917  }
3918 
3919  if(all_need_device_type[j] == NI_DEVICE_TYPE_ENCODER)
3920  {
3921  if(encoder_need_load + p_hw_device_info->card_info[j][i].model_load >= 100)
3922  {
3923  card_remove[i] =1;
3924  }
3925  }
3926 
3927  if (task_mode)
3928  {
3929  // replicate legacy behavior for task_mode to use enc model_load in place of enc real load
3930  if(all_need_device_type[i] == NI_DEVICE_TYPE_ENCODER)
3931  {
3932  if (p_hw_device_info->card_info[j][i].model_load > hw_info_threshold_param[j].load_threshold ||
3933  p_hw_device_info->card_info[j][i].task_num + 1 >= hw_info_threshold_param[j].task_num_threshold)
3934  {
3935  card_remove[i] = 1;
3936  }
3937  }
3938  else
3939  {
3940  if (p_hw_device_info->card_info[j][i].load > hw_info_threshold_param[j].load_threshold ||
3941  p_hw_device_info->card_info[j][i].task_num + 1 >= hw_info_threshold_param[j].task_num_threshold)
3942  {
3943  card_remove[i] = 1;
3944  }
3945  }
3946  }
3947  else
3948  {
3949  if (p_hw_device_info->card_info[j][i].task_num > hw_info_threshold_param[j].task_num_threshold)
3950  {
3951  card_remove[i] = 1;
3952  }
3953  }
3954  }
3955  }
3956 
3957  if(consider_mem)
3958  {
3959  if(hw_mode)
3960  {
3961  check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,10);
3962  }
3963  else if(preferential_device_type == 0)
3964  {
3965  check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,0);
3966  }
3967  else if(preferential_device_type == 1)
3968  {
3969  check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,1);
3970  }
3971  else if(preferential_device_type == 2)
3972  {
3973  check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,2);
3974  }
3975  }
3976 
3977  if (task_mode)
3978  {
3979  //select the min_task_num
3980  //p_hw_device_info->card_info[0] is the preferential_device_type
3981  int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
3982  for (i = 0; i < p_hw_device_info->available_card_num; i++)
3983  {
3984  if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
3985  card_remove[i] == 0)
3986  {
3987  min_task_num = p_hw_device_info->card_info[0][i].task_num;
3988  }
3989  }
3990  //select the min load
3991  int min_load = 100;
3992  for (i = 0; i < p_hw_device_info->available_card_num; i++)
3993  {
3994  if (p_hw_device_info->card_info[0][i].load < min_load &&
3995  card_remove[i] == 0 &&
3996  p_hw_device_info->card_info[0][i].task_num == min_task_num)
3997  {
3998  min_load = p_hw_device_info->card_info[0][i].load;
3999  p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4000  }
4001  }
4002  }
4003  else
4004  {
4005  //p_hw_device_info->card_info[0] is the preferential_device_type
4006  //select the min task num
4007  int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
4008  for (i = 0; i < p_hw_device_info->available_card_num; i++)
4009  {
4010  if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
4011  card_remove[i] == 0)
4012  {
4013  p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4014  min_task_num = p_hw_device_info->card_info[0][i].task_num;
4015  }
4016  }
4017  }
4018 
4019  if (p_hw_device_info->card_current_card >= 0)
4020  {
4021  retval = 1; //has the card to use
4022  }
4023 
4024 END:
4025 #ifdef _WIN32
4026  ReleaseMutex((HANDLE)p_device_pool->lock);
4027 
4028 #elif defined(__linux__)
4029  if (lockf(p_device_pool->lock, F_ULOCK,0))
4030  {
4031  ni_log(NI_LOG_ERROR, "Error lockf() failed\n");
4032  if(p_hw_device_info)
4033  {
4034  p_hw_device_info->err_code = NI_RETCODE_ERROR_UNLOCK_DEVICE;
4035  }
4036  retval = 0;
4037  }
4038  ni_rsrc_free_device_pool(p_device_pool);
4039  p_device_context = NULL;
4040 #endif
4041  fflush(stderr);
4042  if (module_id_arr)
4043  {
4044  free(module_id_arr);
4045  module_id_arr = NULL;
4046  }
4047  if (dev_ctxt_arr)
4048  {
4049  free(dev_ctxt_arr);
4050  dev_ctxt_arr = NULL;
4051  }
4052  if (card_remove)
4053  {
4054  free(card_remove);
4055  card_remove = NULL;
4056  }
4057  if(b_valid)
4058  {
4059  if(hw_mode)
4060  {
4061 #ifdef XCODER_311
4062  ni_log(NI_LOG_DEBUG, "In hw_mode select card_current_card %d retval %d\n",
4063 #else
4064  ni_log(NI_LOG_INFO, "In hw_mode select card_current_card %d retval %d\n",
4065 #endif
4066  p_hw_device_info->card_current_card, retval);
4067  }
4068  else
4069  {
4070 #ifdef XCODER_311
4071  ni_log(NI_LOG_DEBUG, "In sw_mode select device_type %s card_current_card %d retval %d\n",
4072 #else
4073  ni_log(NI_LOG_INFO, "In sw_mode select device_type %s card_current_card %d retval %d\n",
4074 #endif
4075  ((preferential_device_type == 0) ? "decode" : (preferential_device_type == 1 ? "encode" : (preferential_device_type == 2 ? "scaler" : "ai "))), p_hw_device_info->card_current_card, retval);
4076  }
4077  }
4078  return retval;
4079 }
4080 
4081 
4082 /*!*****************************************************************************
4083 * \brief Allocate resources for decoding/encoding, based on the provided rule
4084 *
4085 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
4086 * \param[in] rule allocation rule
4087 * \param[in] codec EN_H264 or EN_H265
4088 * \param[in] width width of video resolution
4089 * \param[in] height height of video resolution
4090 * \param[in] frame_rate video stream frame rate
4091 * \param[out] p_load the p_load that will be generated by this encoding
4092 * task. Returned *only* for encoder for now.
4093 *
4094 * \return pointer to ni_device_context_t if found, NULL otherwise
4095 *
4096 * Note: codec, width, height, fps need to be supplied for NI_DEVICE_TYPE_ENCODER only,
4097 * they are ignored otherwize.
4098 * Note: the returned ni_device_context_t content is not supposed to be used by
4099 * caller directly: should only be passed to API in the subsequent
4100 * calls; also after its use, the context should be released by
4101 * calling ni_rsrc_free_device_context.
4102 *******************************************************************************/
4104  ni_device_type_t device_type,
4105  ni_alloc_rule_t rule,
4106  ni_codec_t codec,
4107  int width, int height,
4108  int frame_rate,
4109  uint64_t *p_load)
4110 {
4111  ni_device_pool_t *p_device_pool = NULL;
4112  ni_device_info_t *p_device_info = NULL;
4113  ni_device_context_t *p_device_context = NULL;
4114  ni_session_context_t p_session_context = {0};
4115  int *coders = NULL;
4116  int i = 0, count = 0, rc = NI_RETCODE_FAILURE;
4117  int guid = -1;
4118  int load = 0;
4119  uint32_t num_sw_instances = 0;
4120  int least_model_load = 0;
4121  uint64_t job_mload = 0;
4122 
4123 
4124  if(device_type != NI_DEVICE_TYPE_DECODER && device_type != NI_DEVICE_TYPE_ENCODER)
4125  {
4126  ni_log2(NULL, NI_LOG_ERROR, "ERROR: Device type %d is not allowed\n", device_type);
4127  return NULL;
4128  }
4131  p_device_pool = ni_rsrc_get_device_pool();
4132 
4133  if (!p_device_pool)
4134  {
4135  ni_log2(NULL, NI_LOG_ERROR, "ERROR: %s() Could not get device pool\n", __func__);
4136  return NULL;
4137  }
4138 
4139  ni_device_session_context_init(&p_session_context);
4140 #ifdef _WIN32
4141  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval) //we got the mutex
4142  {
4143  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %p\n", __func__, p_device_pool->lock);
4144  }
4145 #elif __linux__ || __APPLE__
4146  lockf(p_device_pool->lock, F_LOCK, 0);
4147 #endif
4148 
4149  coders = p_device_pool->p_device_queue->xcoders[device_type];
4150  count = p_device_pool->p_device_queue->xcoder_cnt[device_type];
4151 
4152  for (i = 0; i < count; i++)
4153  {
4155  p_device_context = ni_rsrc_get_device_context(device_type, coders[i]);
4156  if (!p_device_context)
4157  {
4159  "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4160  continue;
4161  }
4162 
4163  // p_first retrieve status from f/w and update storage
4164 
4165  p_session_context.blk_io_handle = ni_device_open(p_device_context->p_device_info->dev_name, &p_session_context.max_nvme_io_size);
4166  p_session_context.device_handle = p_session_context.blk_io_handle;
4167 
4168  if (NI_INVALID_DEVICE_HANDLE == p_session_context.device_handle)
4169  {
4170  ni_log(NI_LOG_ERROR, "ERROR %s() ni_device_open() %s: %s\n",
4171  __func__, p_device_context->p_device_info->dev_name,
4172  strerror(NI_ERRNO));
4173  ni_rsrc_free_device_context(p_device_context);
4174  continue;
4175  }
4176 
4177  p_session_context.hw_id = p_device_context->p_device_info->hw_id;
4178  rc = ni_device_session_query(&p_session_context, device_type);
4179 
4180  ni_device_close(p_session_context.device_handle);
4181 
4182  if (NI_RETCODE_SUCCESS != rc)
4183  {
4184  ni_log(NI_LOG_ERROR, "ERROR: query %s %s.%d\n",
4185  g_device_type_str[device_type],
4186  p_device_context->p_device_info->dev_name,
4187  p_device_context->p_device_info->hw_id);
4188  ni_rsrc_free_device_context(p_device_context);
4189  continue;
4190  }
4191 
4192 #ifdef _WIN32
4193  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
4194  {
4195  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %p\n",
4196  __func__, p_device_context->lock);
4197  }
4198 #elif __linux__ || __APPLE__
4199  lockf(p_device_context->lock, F_LOCK, 0);
4200 #endif
4201  ni_rsrc_update_record(p_device_context, &p_session_context);
4202 
4203  p_device_info = p_device_context->p_device_info;
4204  if (i == 0)
4205  {
4206  guid = coders[i];
4207  load = p_device_info->load;
4208  least_model_load = p_device_info->model_load;
4209  num_sw_instances = p_device_info->active_num_inst;
4210  }
4211 
4212  ni_log(NI_LOG_INFO, "Coder [%d]: %d , load: %d (%d), activ_inst: %d , max_inst %d\n",
4213  i, coders[i], p_device_info->load, p_device_info->model_load, p_device_info->active_num_inst,
4214  p_device_info->max_instance_cnt);
4215 
4216  switch (rule)
4217  {
4219  {
4220  if (p_device_info->active_num_inst < num_sw_instances)
4221  {
4222  guid = coders[i];
4223  num_sw_instances = p_device_info->active_num_inst;
4224  }
4225  break;
4226  }
4227 
4228  case EN_ALLOC_LEAST_LOAD:
4229  default:
4230  {
4231  if (NI_DEVICE_TYPE_ENCODER == device_type)
4232  {
4233  if (p_device_info->model_load < least_model_load)
4234  {
4235  guid = coders[i];
4236  least_model_load = p_device_info->model_load;
4237  }
4238  }
4239  else if (p_device_info->load < load)
4240  {
4241  guid = coders[i];
4242  load = p_device_info->load;
4243  }
4244  break;
4245  }
4246  }
4247 
4248 #ifdef _WIN32
4249  ReleaseMutex(p_device_context->lock);
4250 #elif __linux__ || __APPLE__
4251  lockf(p_device_context->lock, F_ULOCK, 0);
4252 #endif
4253  ni_rsrc_free_device_context(p_device_context);
4254  }
4255 
4256  if (guid >= 0)
4257  {
4258  p_device_context = ni_rsrc_get_device_context(device_type, guid);
4259  if (!p_device_context)
4260  {
4262  "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4263  LRETURN;
4264  }
4265 
4266  if (NI_DEVICE_TYPE_ENCODER == device_type)
4267  {
4268  job_mload = width * height * frame_rate;
4269  }
4270  }
4271  else
4272  {
4273  ni_log(NI_LOG_ERROR, "ERROR: %s() cannot find guid\n", __func__);
4274  p_device_context = NULL;
4275  }
4276 
4277 END:
4278 #ifdef _WIN32
4279  ReleaseMutex(p_device_pool->lock);
4280 #elif __linux__ || __APPLE__
4281  lockf(p_device_pool->lock, F_ULOCK, 0);
4282 #endif
4283  ni_device_session_context_clear(&p_session_context);
4284  ni_rsrc_free_device_pool(p_device_pool);
4285 
4286  if (p_load)
4287  {
4288  *p_load = job_mload;
4289  }
4290  return p_device_context;
4291 }
_ni_card_info_quadra::firmware_load
int firmware_load
Definition: ni_rsrc_api.h:160
_ni_hw_device_info_quadra::card_current_card
int card_current_card
Definition: ni_rsrc_api.h:170
NI_RETCODE_ERROR_VPU_RECOVERY
@ NI_RETCODE_ERROR_VPU_RECOVERY
Definition: ni_defs.h:515
NI_LOG_FATAL
@ NI_LOG_FATAL
Definition: ni_log.h:59
_ni_device_info::fw_rev
uint8_t fw_rev[8]
Definition: ni_rsrc_api.h:115
ni_log_level_t
ni_log_level_t
Definition: ni_log.h:55
_ni_device_pool::lock
ni_lock_handle_t lock
Definition: ni_rsrc_api.h:98
ni_device_capability_query
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...
Definition: ni_device_api.c:587
_ni_device_capability::fw_commit_time
uint8_t fw_commit_time[26]
Definition: ni_device_api.h:1166
ni_rsrc_check_hw_available
int ni_rsrc_check_hw_available(int guid, ni_device_type_t device_type)
check the NetInt h/w device in resource pool on the host.
Definition: ni_rsrc_api.cpp:2016
_ni_device_info::serial_number
uint8_t serial_number[20]
Definition: ni_rsrc_api.h:122
EN_INVALID
@ EN_INVALID
Definition: ni_rsrc_api.h:49
NI_DEVICE_TYPE_ENCODER
@ NI_DEVICE_TYPE_ENCODER
Definition: ni_defs.h:347
_ni_hw_device_info_quadra::err_code
int err_code
Definition: ni_rsrc_api.h:171
_ni_device_info::dev_cap
ni_device_video_capability_t dev_cap[EN_CODEC_MAX]
Definition: ni_rsrc_api.h:132
_ni_hw_device_info_quadra_decoder_param::fps
uint32_t fps
Definition: ni_rsrc_api.h:190
ni_rsrc_free_device_pool
void ni_rsrc_free_device_pool(ni_device_pool_t *p_device_pool)
Free all resources taken by the device pool.
Definition: ni_rsrc_api.cpp:2621
_ni_device::xcoders
ni_device_info_t xcoders[NI_DEVICE_TYPE_XCODER_MAX][NI_MAX_DEVICE_CNT]
Definition: ni_rsrc_api.h:142
_ni_hw_device_info_quadra_encoder_param::uploader
int uploader
Definition: ni_rsrc_api.h:184
ni_rsrc_remove_device
int ni_rsrc_remove_device(const char *dev)
Remove an NetInt h/w device from resource pool on the host.
Definition: ni_rsrc_api.cpp:2203
ni_rsrc_print_all_devices_capability2
void ni_rsrc_print_all_devices_capability2(bool list_uninitialized)
Prints detailed capability information for all initialized devices and general information about unin...
Definition: ni_rsrc_api.cpp:1713
_ni_hw_device_info_quadra_ai_param
Definition: ni_rsrc_api.h:206
ni_rsrc_get_device_context
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....
ni_destory_hw_device_info_quadra_coder_param
void ni_destory_hw_device_info_quadra_coder_param(ni_hw_device_info_quadra_coder_param_t *p_hw_device_info_quadra_coder_param)
Free resource in p_hw_device_info_quadra_coder_param This function is used for ni_check_hw_info()
Definition: ni_rsrc_api.cpp:3271
XCODER_MIN_ENC_PIC_WIDTH
#define XCODER_MIN_ENC_PIC_WIDTH
Definition: ni_util.h:112
g_xcoder_stop_process
uint32_t g_xcoder_stop_process
Definition: ni_rsrc_priv.cpp:73
_ni_load_query::current_load
uint32_t current_load
Definition: ni_device_api.h:1198
_ni_load_query::total_contexts
uint32_t total_contexts
Definition: ni_device_api.h:1201
_ni_hw_device_info_quadra_encoder_param::code_format
uint32_t code_format
Definition: ni_rsrc_api.h:179
ni_device_session_query
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 ...
Definition: ni_device_api.c:1920
_ni_hw_device_info_quadra_encoder_param::rdoLevel
uint32_t rdoLevel
Definition: ni_rsrc_api.h:181
ni_device_close
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
Definition: ni_device_api.c:503
NI_DEVICE_TYPE_DECODER
@ NI_DEVICE_TYPE_DECODER
Definition: ni_defs.h:346
_ni_hw_device_info_quadra_encoder_param::w
uint32_t w
Definition: ni_rsrc_api.h:178
_ni_hw_device_info_quadra_encoder_param::lookaheadDepth
uint32_t lookaheadDepth
Definition: ni_rsrc_api.h:182
_ni_device_info::fw_commit_hash
uint8_t fw_commit_hash[41]
Definition: ni_rsrc_api.h:118
ni_rsrc_lock_and_open
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
Definition: ni_rsrc_api.cpp:2652
NI_RETCODE_ERROR_GET_DEVICE_POOL
@ NI_RETCODE_ERROR_GET_DEVICE_POOL
Definition: ni_defs.h:506
_ni_device_video_capability::max_res_height
int max_res_height
Definition: ni_rsrc_api.h:78
_ni_device_capability::fw_branch_name
uint8_t fw_branch_name[256]
Definition: ni_device_api.h:1165
ni_device_type_t
ni_device_type_t
Definition: ni_defs.h:341
_ni_hw_device_info_quadra_scaler_param::h
uint32_t h
Definition: ni_rsrc_api.h:200
LOCK_WAIT
#define LOCK_WAIT
Definition: ni_rsrc_priv.h:55
_ni_device_info::xcode_load_pixel
uint64_t xcode_load_pixel
Definition: ni_rsrc_api.h:110
ni_codec_t
ni_codec_t
Definition: ni_rsrc_api.h:47
_ni_device_capability::model_number
uint8_t model_number[40]
Definition: ni_device_api.h:1162
NI_RETCODE_SUCCESS
@ NI_RETCODE_SUCCESS
Definition: ni_defs.h:427
ni_rsrc_init_priv
int ni_rsrc_init_priv(const int should_match_rev, const int existing_number_of_devices, const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN], int limit_depth)
_ni_hw_device_info_quadra_decoder_param::bit_8_10
uint32_t bit_8_10
Definition: ni_rsrc_api.h:193
NI_DEVICE_TYPE_UPLOAD
@ NI_DEVICE_TYPE_UPLOAD
Definition: ni_defs.h:353
ni_device_open
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.
Definition: ni_device_api.c:360
_ni_hw_device_info_quadra_ai_param::h
uint32_t h
Definition: ni_rsrc_api.h:208
_ni_hw_device_info_quadra_scaler_param
Definition: ni_rsrc_api.h:198
g_dev_handle
NI_DEPRECATED ni_device_handle_t g_dev_handle
Definition: ni_rsrc_api.cpp:63
_ni_device_video_capability::min_res_width
int min_res_width
Definition: ni_rsrc_api.h:79
ni_rsrc_get_local_device_list2
LIB_API int ni_rsrc_get_local_device_list2(char ni_devices[][NI_MAX_DEVICE_NAME_LEN], int max_handles, char **xcoder_refresh_dev_names, int xcoder_refresh_dev_count)
Scans system for all NVMe devices and returns the system device names to the user which were identifi...
_ni_device_info::active_num_inst
uint32_t active_num_inst
Definition: ni_rsrc_api.h:128
ni_log_set_level
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
Definition: ni_log.c:202
ni_rsrc_strcmp
int ni_rsrc_strcmp(const void *p_str, const void *p_str1)
Definition: ni_rsrc_priv.cpp:205
ni_log_get_level
ni_log_level_t ni_log_get_level(void)
Get ni_log_level.
Definition: ni_log.c:212
ni_rsrc_api.h
Public definitions for managing NETINT video processing devices.
_ni_session_context::event_handle
ni_event_handle_t event_handle
Definition: ni_device_api.h:1574
_ni_device::xcoder_cnt
int xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
Definition: ni_rsrc_api.h:141
_ni_device_context::lock
ni_lock_handle_t lock
Definition: ni_rsrc_api.h:148
_ni_device
Definition: ni_rsrc_api.h:139
NI_XCODER_REVISION
#define NI_XCODER_REVISION
Definition: ni_defs.h:95
_ni_device_info::fl_ver_nor_flash
uint8_t fl_ver_nor_flash[8]
Definition: ni_rsrc_api.h:112
_ni_session_context::blk_io_handle
ni_device_handle_t blk_io_handle
Definition: ni_device_api.h:1465
ni_close_event
void ni_close_event(ni_event_handle_t event_handle)
Close event and release resources (Windows only)
Definition: ni_device_api.c:294
_ni_device_pool::p_device_queue
ni_device_queue_t * p_device_queue
Definition: ni_rsrc_api.h:99
ni_rsrc_update_record
void ni_rsrc_update_record(ni_device_context_t *p_device_context, ni_session_context_t *p_session_ctx)
_ni_hw_device_info_quadra_threshold_param::device_type
ni_device_type_t device_type
Definition: ni_rsrc_api.h:216
_ni_load_query::fw_share_mem_usage
uint32_t fw_share_mem_usage
Definition: ni_device_api.h:1210
ni_rsrc_add_device
int ni_rsrc_add_device(const char *dev, int should_match_rev)
Add an NetInt h/w device into resource pool on the host.
Definition: ni_rsrc_api.cpp:2523
_ni_hw_device_info_quadra_encoder_param::ui8enableRdoQuant
uint32_t ui8enableRdoQuant
Definition: ni_rsrc_api.h:180
ni_create_hw_device_info_quadra_coder_param
ni_hw_device_info_quadra_coder_param_t * ni_create_hw_device_info_quadra_coder_param(int mode)
Create and alloc a pointer to ni_hw_device_info_quadra_coder_param_t This function is used for ni_che...
Definition: ni_rsrc_api.cpp:3118
NI_RETCODE_INVALID_PARAM
@ NI_RETCODE_INVALID_PARAM
Definition: ni_defs.h:429
_ni_device_capability::fw_commit_hash
uint8_t fw_commit_hash[41]
Definition: ni_device_api.h:1167
ni_rsrc_get_local_device_list
LIB_API NI_DEPRECATED int ni_rsrc_get_local_device_list(char ni_devices[][NI_MAX_DEVICE_NAME_LEN], int max_handles)
Scans system for all NVMe devices and returns the system device names to the user which were identifi...
_ni_hw_device_info_quadra_threshold_param::task_num_threshold
int task_num_threshold
Definition: ni_rsrc_api.h:218
_ni_hw_device_info_quadra::device_type
ni_device_type_t * device_type
Definition: ni_rsrc_api.h:168
NI_DEFAULT_KEEP_ALIVE_TIMEOUT
#define NI_DEFAULT_KEEP_ALIVE_TIMEOUT
Definition: ni_device_api.h:311
_ni_hw_device_info_quadra_encoder_param::bit_8_10
uint32_t bit_8_10
Definition: ni_rsrc_api.h:183
service
android::sp< INidec > service
_ni_hw_device_info_quadra_ai_param::rgba
int rgba
Definition: ni_rsrc_api.h:211
_ni_device_info::fw_ver_compat_warning
int fw_ver_compat_warning
Definition: ni_rsrc_api.h:111
_ni_device_info::fw_commit_time
uint8_t fw_commit_time[26]
Definition: ni_rsrc_api.h:117
_ni_session_context::hw_id
int hw_id
Definition: ni_device_api.h:1478
ni_rsrc_api_android.h
Public definitions for managing NETINT video processing devices on Android.
_ni_device_info::hw_id
int hw_id
Definition: ni_rsrc_api.h:106
ni_cmp_fw_api_ver
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:3674
_ni_hw_device_info_quadra_coder_param::ai_param
ni_hw_device_info_quadra_ai_param_t * ai_param
Definition: ni_rsrc_api.h:227
_ni_device_capability::fw_build_id
uint8_t fw_build_id[256]
Definition: ni_device_api.h:1169
_ni_device_info::dev_name
char dev_name[NI_MAX_DEVICE_NAME_LEN]
Definition: ni_rsrc_api.h:104
NI_RETCODE_ERROR_MEM_ALOC
@ NI_RETCODE_ERROR_MEM_ALOC
Definition: ni_defs.h:431
ni_retcode_t
ni_retcode_t
Definition: ni_defs.h:425
EN_ALLOC_LEAST_LOAD
@ EN_ALLOC_LEAST_LOAD
Definition: ni_rsrc_api.h:254
_ni_load_query::fw_model_load
uint32_t fw_model_load
Definition: ni_device_api.h:1199
_ni_hw_device_info_quadra_ai_param::w
uint32_t w
Definition: ni_rsrc_api.h:209
_ni_hw_device_info_quadra_scaler_param::w
uint32_t w
Definition: ni_rsrc_api.h:201
NI_RETCODE_PARAM_INVALID_VALUE
@ NI_RETCODE_PARAM_INVALID_VALUE
Definition: ni_defs.h:437
_ni_card_info_quadra::model_load
int model_load
Definition: ni_rsrc_api.h:156
NI_MAX_CONTEXTS_PER_HW_INSTANCE
#define NI_MAX_CONTEXTS_PER_HW_INSTANCE
Definition: ni_defs.h:236
add_to_shared_memory
bool add_to_shared_memory(const char device_name[NI_MAX_DEVICE_NAME_LEN], const bool device_open_should_succeed, const int should_match_rev, ni_device_queue_t *device_queue)
Definition: ni_rsrc_priv.cpp:408
ni_rsrc_android_init
int ni_rsrc_android_init()
Init android net.int.SharedBuffer service for binder using.
NI_LOG_INFO
@ NI_LOG_INFO
Definition: ni_log.h:61
ni_rsrc_get_device_pool
LIB_API ni_device_pool_t * ni_rsrc_get_device_pool(void)
Create and return the allocated ni_device_pool_t struct.
ni_rsrc_release_resource
void ni_rsrc_release_resource(ni_device_context_t *p_device_context, uint64_t load)
Release resources allocated for decoding/encoding. function This must be called at the end of transco...
Definition: ni_rsrc_api.cpp:1953
_ni_hw_device_info_quadra_encoder_param
Definition: ni_rsrc_api.h:174
NI_LOG_ERROR
@ NI_LOG_ERROR
Definition: ni_log.h:60
_ni_device_queue::xcoders
int32_t xcoders[NI_DEVICE_TYPE_XCODER_MAX][NI_MAX_DEVICE_CNT]
Definition: ni_rsrc_api.h:70
IS_XCODER_DEVICE_TYPE
#define IS_XCODER_DEVICE_TYPE(t)
Definition: ni_defs.h:410
_ni_session_context::src_bit_depth
int src_bit_depth
Definition: ni_device_api.h:1492
ni_rsrc_get_device_info
ni_device_info_t * ni_rsrc_get_device_info(ni_device_type_t device_type, int guid)
Query a specific device with detailed information on the system.
Definition: ni_rsrc_api.cpp:1748
NI_RETCODE_ERROR_UNLOCK_DEVICE
@ NI_RETCODE_ERROR_UNLOCK_DEVICE
Definition: ni_defs.h:509
EN_JPEG
@ EN_JPEG
Definition: ni_rsrc_api.h:53
_ni_device_info::fw_rev_nor_flash
uint8_t fw_rev_nor_flash[8]
Definition: ni_rsrc_api.h:114
_ni_device_video_capability::profiles_supported
char profiles_supported[NI_PROFILES_SUPP_STR_LEN]
Definition: ni_rsrc_api.h:81
_ni_device_info::max_instance_cnt
int max_instance_cnt
Definition: ni_rsrc_api.h:127
_ni_device_info
Definition: ni_rsrc_api.h:102
NI_DEVICE_TYPE_AI
@ NI_DEVICE_TYPE_AI
Definition: ni_defs.h:349
_ni_hw_device_info_quadra_ai_param::bit_8_10
uint32_t bit_8_10
Definition: ni_rsrc_api.h:210
ni_alloc_rule_t
ni_alloc_rule_t
Definition: ni_rsrc_api.h:252
ni_encoder_init_default_params
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.
Definition: ni_device_api.c:4147
_ni_hw_device_info_quadra_encoder_param::fps
uint32_t fps
Definition: ni_rsrc_api.h:176
_ni_card_info_quadra::card_idx
int card_idx
Definition: ni_rsrc_api.h:154
ni_rsrc_is_fw_compat
int ni_rsrc_is_fw_compat(uint8_t fw_rev[8])
check if device FW revision is compatible with SW API
Definition: ni_rsrc_api.cpp:2784
_ni_hw_device_info_quadra_encoder_param::h
uint32_t h
Definition: ni_rsrc_api.h:177
_ni_device_info::fl_ver_last_ran
uint8_t fl_ver_last_ran[8]
Definition: ni_rsrc_api.h:113
NI_LOG_TRACE
@ NI_LOG_TRACE
Definition: ni_log.h:63
_ni_session_context::device_handle
ni_device_handle_t device_handle
Definition: ni_device_api.h:1462
_ni_session_context::p_session_config
void * p_session_config
Definition: ni_device_api.h:1473
ni_rsrc_free_device_context
void ni_rsrc_free_device_context(ni_device_context_t *p_device_context)
Free previously allocated device context.
Definition: ni_rsrc_api.cpp:1310
_ni_card_info_quadra::task_num
int task_num
Definition: ni_rsrc_api.h:157
NI_SCALER_OPCODE_SCALE
@ NI_SCALER_OPCODE_SCALE
Definition: ni_defs.h:573
_ni_device_queue
Definition: ni_rsrc_api.h:67
_ni_sw_instance_info
Definition: ni_rsrc_api.h:86
_ni_device_info::sw_instance
ni_sw_instance_info_t sw_instance[NI_MAX_CONTEXTS_PER_HW_INSTANCE]
Definition: ni_rsrc_api.h:134
ni_rsrc_print_device_info
void ni_rsrc_print_device_info(const ni_device_info_t *p_device_info)
Print the content of the ni_device_info_t struct.
Definition: ni_rsrc_api.cpp:1600
ni_log
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition: ni_log.c:183
NI_XCODER_REVISION_API_MAJOR_VER_IDX
#define NI_XCODER_REVISION_API_MAJOR_VER_IDX
Definition: ni_defs.h:96
ni_rsrc_unlock
int ni_rsrc_unlock(int device_type, ni_lock_handle_t lock)
unlock a file lock
Definition: ni_rsrc_api.cpp:2738
_ni_device_info::model_load
int model_load
Definition: ni_rsrc_api.h:109
_ni_device_info::module_id
int module_id
Definition: ni_rsrc_api.h:107
_ni_session_context::keep_alive_timeout
uint32_t keep_alive_timeout
Definition: ni_device_api.h:1521
CODERS_SHM_NAME
#define CODERS_SHM_NAME
Definition: ni_rsrc_priv.h:44
_ni_hw_device_info_quadra_coder_param
Definition: ni_rsrc_api.h:221
ni_fmt_fw_api_ver_str
void ni_fmt_fw_api_ver_str(const char ver_str[], char fmt_str[])
Get formatted FW API version string from unformatted FW API version string.
Definition: ni_util.c:3644
_ni_hw_device_info_quadra_coder_param::hw_mode
int hw_mode
Definition: ni_rsrc_api.h:223
ni_usleep
void ni_usleep(int64_t usec)
Definition: ni_util.c:358
ni_query_fl_fw_versions
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.
Definition: ni_device_api.c:11385
_ni_session_context::device_type
uint32_t device_type
Definition: ni_device_api.h:1484
LRETURN
#define LRETURN
Definition: ni_defs.h:323
ni_rsrc_print_all_devices_capability
void ni_rsrc_print_all_devices_capability(void)
Print detailed capability information of all devices on the system.
Definition: ni_rsrc_api.cpp:1681
_ni_device_info::fw_build_time
uint8_t fw_build_time[26]
Definition: ni_rsrc_api.h:119
ni_device_session_context_clear
void ni_device_session_context_clear(ni_session_context_t *p_ctx)
Clear already allocated session context.
Definition: ni_device_api.c:249
ni_rsrc_allocate_simple_direct
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....
Definition: ni_rsrc_api.cpp:1932
_ni_hw_device_info_quadra_decoder_param::h
uint32_t h
Definition: ni_rsrc_api.h:191
ni_rsrc_allocate_auto
ni_device_context_t * ni_rsrc_allocate_auto(ni_device_type_t device_type, ni_alloc_rule_t rule, ni_codec_t codec, int width, int height, int frame_rate, uint64_t *p_load)
Allocate resources for decoding/encoding, based on the provided rule.
Definition: ni_rsrc_api.cpp:4103
g_xcoder_refresh_dev_names
NI_DEPRECATED char ** g_xcoder_refresh_dev_names
Definition: ni_rsrc_api.cpp:60
_ni_device_context
Definition: ni_rsrc_api.h:145
ni_rsrc_update_device_load
int ni_rsrc_update_device_load(ni_device_context_t *p_device_context, int load, int sw_instance_cnt, const ni_sw_instance_info_t sw_instance_info[])
Update the load value and s/w instances info of a specific decoder or encoder. This is used by resour...
Definition: ni_rsrc_api.cpp:1878
_ni_device_capability::fw_build_time
uint8_t fw_build_time[26]
Definition: ni_device_api.h:1168
_ni_hw_device_info_quadra_scaler_param::bit_8_10
uint32_t bit_8_10
Definition: ni_rsrc_api.h:202
_ni_device_info::blk_name
char blk_name[NI_MAX_DEVICE_NAME_LEN]
Definition: ni_rsrc_api.h:105
NI_DEVICE_TYPE_SCALER
@ NI_DEVICE_TYPE_SCALER
Definition: ni_defs.h:348
ni_decoder_init_default_params
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.
Definition: ni_device_api.c:4546
EN_CODEC_MAX
@ EN_CODEC_MAX
Definition: ni_rsrc_api.h:55
NI_ERRNO
#define NI_ERRNO
Definition: ni_defs.h:217
_ni_hw_device_info_quadra_threshold_param::load_threshold
int load_threshold
Definition: ni_rsrc_api.h:217
_ni_session_context
Definition: ni_device_api.h:1408
NI_MAX_DEVICE_CNT
#define NI_MAX_DEVICE_CNT
Definition: ni_defs.h:223
NI_MAX_DEVICE_NAME_LEN
#define NI_MAX_DEVICE_NAME_LEN
Definition: ni_defs.h:224
_ni_hw_device_info_quadra_decoder_param::rgba
int rgba
Definition: ni_rsrc_api.h:194
NI_DEPRECATED
#define NI_DEPRECATED
Definition: ni_defs.h:77
ni_device_session_open
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...
Definition: ni_device_api.c:710
EN_ALLOC_LEAST_INSTANCE
@ EN_ALLOC_LEAST_INSTANCE
Definition: ni_rsrc_api.h:255
ni_rsrc_list_all_devices2
ni_retcode_t ni_rsrc_list_all_devices2(ni_device_t *p_device, bool list_uninitialized)
Grabs information for every initialized and uninitialized device.
Definition: ni_rsrc_api.cpp:1487
ni_rsrc_priv.h
Private definitions used by ni_rsrc_api.cpp for management of NETINT video processing devices.
ni_quadra_card_identify_precheck
ni_retcode_t ni_quadra_card_identify_precheck(const char *p_dev)
precheck a device can be read by ni_device_capability_query() INFO OR ERROR logs will not be printed ...
Definition: ni_util.c:4874
_ni_xcoder_params
Definition: ni_device_api.h:2713
_ni_hw_device_info_quadra::consider_mem
int consider_mem
Definition: ni_rsrc_api.h:167
_ni_hw_device_info_quadra_coder_param::scaler_param
ni_hw_device_info_quadra_scaler_param_t * scaler_param
Definition: ni_rsrc_api.h:226
_ni_card_info_quadra::shared_mem_usage
int shared_mem_usage
Definition: ni_rsrc_api.h:159
ni_rsrc_get_lock_name
void ni_rsrc_get_lock_name(ni_device_type_t device_type, int32_t guid, char *p_name, size_t max_name_len)
Definition: ni_rsrc_priv.cpp:242
_ni_load_query::fw_load
uint32_t fw_load
Definition: ni_device_api.h:1200
_ni_device_capability::fw_rev
uint8_t fw_rev[8]
Definition: ni_device_api.h:1164
_ni_hw_device_info_quadra::device_type_num
int device_type_num
Definition: ni_rsrc_api.h:166
XCODER_MIN_ENC_PIC_HEIGHT
#define XCODER_MIN_ENC_PIC_HEIGHT
Definition: ni_util.h:113
ni_rsrc_enumerate_devices
int ni_rsrc_enumerate_devices(char ni_devices[][NI_MAX_DEVICE_NAME_LEN], int max_handles)
_ni_device_capability
device capability type
Definition: ni_device_api.h:1153
_ni_device_info::max_fps_4k
int max_fps_4k
Definition: ni_rsrc_api.h:126
_ni_session_context::scaler_operation
uint32_t scaler_operation
Definition: ni_device_api.h:1610
_ni_card_info_quadra::load
int load
Definition: ni_rsrc_api.h:155
ni_log2
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
MAX_LOCK_RETRY
#define MAX_LOCK_RETRY
Definition: ni_rsrc_priv.h:54
print_device
void print_device(ni_device_t *p_device)
Definition: ni_rsrc_api.cpp:82
CODERS_LCK_NAME
#define CODERS_LCK_NAME
Definition: ni_rsrc_priv.h:43
_ni_device_context::p_device_info
ni_device_info_t * p_device_info
Definition: ni_rsrc_api.h:149
_ni_session_context::load_query
ni_load_query_t load_query
Definition: ni_device_api.h:1500
_ni_device_video_capability::min_res_height
int min_res_height
Definition: ni_rsrc_api.h:80
ni_create_event
ni_event_handle_t ni_create_event(void)
Create event and return event handle if successful (Windows only)
Definition: ni_device_api.c:266
_ni_device_video_capability::max_res_width
int max_res_width
Definition: ni_rsrc_api.h:77
END
#define END
Definition: ni_defs.h:324
_ni_hw_device_info_quadra_encoder_param::rgba
int rgba
Definition: ni_rsrc_api.h:185
ni_check_hw_info
int ni_check_hw_info(ni_hw_device_info_quadra_t **pointer_to_p_hw_device_info, int task_mode, ni_hw_device_info_quadra_threshold_param_t *hw_info_threshold_param, ni_device_type_t preferential_device_type, ni_hw_device_info_quadra_coder_param_t *coder_param, int hw_mode, int consider_mem)
check hw info, return the appropriate card number to use depends on the load&task_num&used resource
Definition: ni_rsrc_api.cpp:3401
ni_rsrc_list_all_devices
ni_retcode_t ni_rsrc_list_all_devices(ni_device_t *p_device)
List all devices with full information including s/w instances on the system.
Definition: ni_rsrc_api.cpp:1445
ni_rsrc_init
LIB_API int ni_rsrc_init(int should_match_rev, int timeout_seconds)
Initialize and create all resources required to work with NETINT NVMe transcoder devices....
_ni_hw_device_info_quadra::card_info
ni_card_info_quadra_t ** card_info
Definition: ni_rsrc_api.h:169
_ni_hw_device_info_quadra_scaler_param::rgba
int rgba
Definition: ni_rsrc_api.h:203
_ni_card_info_quadra::max_task_num
int max_task_num
Definition: ni_rsrc_api.h:158
_ni_device_capability::serial_number
uint8_t serial_number[20]
Definition: ni_device_api.h:1161
_ni_device_info::model_number
uint8_t model_number[40]
Definition: ni_rsrc_api.h:123
NI_DEVICE_TYPE_XCODER_MAX
@ NI_DEVICE_TYPE_XCODER_MAX
Definition: ni_defs.h:350
_ni_session_context::max_nvme_io_size
uint32_t max_nvme_io_size
Definition: ni_device_api.h:1476
NI_RETCODE_FAILURE
@ NI_RETCODE_FAILURE
Definition: ni_defs.h:428
NI_MIN_BITRATE
#define NI_MIN_BITRATE
Definition: ni_device_api.h:114
_ni_device_pool
Definition: ni_rsrc_api.h:96
_ni_hw_device_info_quadra_decoder_param::hw_frame
int hw_frame
Definition: ni_rsrc_api.h:195
_ni_device_video_capability::supports_codec
int supports_codec
Definition: ni_rsrc_api.h:76
_ni_device_info::fw_build_id
uint8_t fw_build_id[256]
Definition: ni_rsrc_api.h:120
_ni_device_context::shm_name
char shm_name[NI_MAX_DEVICE_NAME_LEN]
Definition: ni_rsrc_api.h:147
ni_rsrc_list_devices
ni_retcode_t ni_rsrc_list_devices(ni_device_type_t device_type, ni_device_info_t *p_device_info, int *p_device_count)
List device(s) based on device type with full information including s/w instances on the system.
Definition: ni_rsrc_api.cpp:1340
NI_LOG_NONE
@ NI_LOG_NONE
Definition: ni_log.h:58
ni_device_capability_query2
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...
Definition: ni_device_api.c:647
ni_util.h
Utility definitions.
_ni_hw_device_info_quadra_decoder_param::w
uint32_t w
Definition: ni_rsrc_api.h:192
_ni_hw_device_info_quadra_decoder_param
Definition: ni_rsrc_api.h:188
g_device_in_ctxt
NI_DEPRECATED bool g_device_in_ctxt
Definition: ni_rsrc_api.cpp:62
_ni_hw_device_info_quadra_threshold_param
Definition: ni_rsrc_api.h:214
_ni_hw_device_info_quadra
Definition: ni_rsrc_api.h:163
_ni_card_info_quadra
Definition: ni_rsrc_api.h:152
ni_hw_device_info_alloc_quadra
ni_hw_device_info_quadra_t * ni_hw_device_info_alloc_quadra(int device_type_num, int avaliable_card_num)
Create a ni_hw_device_info_quadra_t This function is used for ni_check_hw_info()
Definition: ni_rsrc_api.cpp:3310
NI_RETCODE_ERROR_INVALID_HANDLE
@ NI_RETCODE_ERROR_INVALID_HANDLE
Definition: ni_defs.h:511
ni_rsrc_refresh
ni_retcode_t ni_rsrc_refresh(int should_match_rev)
Scan and refresh all resources on the host, taking into account hot-plugged and pulled out cards.
Definition: ni_rsrc_api.cpp:159
NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_H264
Definition: ni_device_api.h:911
ni_check_dev_name
ni_retcode_t ni_check_dev_name(const char *p_dev)
check dev name
Definition: ni_util.c:1252
_ni_hw_device_info_quadra_coder_param::encoder_param
ni_hw_device_info_quadra_encoder_param_t * encoder_param
Definition: ni_rsrc_api.h:224
GET_XCODER_DEVICE_TYPE_STR
#define GET_XCODER_DEVICE_TYPE_STR(t)
Definition: ni_defs.h:417
ni_rsrc_get_shm_name
void ni_rsrc_get_shm_name(ni_device_type_t device_type, int32_t guid, char *p_name, size_t max_name_len)
Definition: ni_rsrc_priv.cpp:265
ni_device_session_context_init
ni_retcode_t ni_device_session_context_init(ni_session_context_t *p_ctx)
Initialize already allocated session context to a known state.
Definition: ni_device_api.c:156
_ni_hw_device_info_quadra::available_card_num
int available_card_num
Definition: ni_rsrc_api.h:165
_ni_device_queue::xcoder_cnt
uint32_t xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
Definition: ni_rsrc_api.h:69
ni_rsrc_remove_all_devices
int ni_rsrc_remove_all_devices(void)
Remove all NetInt h/w devices from resource pool on the host.
Definition: ni_rsrc_api.cpp:2407
_ni_device_info::load
int load
Definition: ni_rsrc_api.h:108
_ni_device_info::device_type
ni_device_type_t device_type
Definition: ni_rsrc_api.h:129
NI_LOG_DEBUG
@ NI_LOG_DEBUG
Definition: ni_log.h:62
g_xcoder_refresh_dev_count
NI_DEPRECATED int g_xcoder_refresh_dev_count
Definition: ni_rsrc_api.cpp:61
ni_device_session_close
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...
Definition: ni_device_api.c:1379
ni_hw_device_info_free_quadra
void ni_hw_device_info_free_quadra(ni_hw_device_info_quadra_t *p_hw_device_info)
Free resource in a pointer of ni_hw_device_info_quadra_t This function is used for ni_check_hw_info()
Definition: ni_rsrc_api.cpp:3381
_ni_device_info::fw_branch_name
uint8_t fw_branch_name[256]
Definition: ni_rsrc_api.h:116
_ni_device_capability::device_is_xcoder
uint8_t device_is_xcoder
Definition: ni_device_api.h:1155
_ni_device_video_capability::level
char level[NI_LEVELS_SUPP_STR_LEN]
Definition: ni_rsrc_api.h:82
NI_RETCODE_ERROR_RESOURCE_UNAVAILABLE
@ NI_RETCODE_ERROR_RESOURCE_UNAVAILABLE
Definition: ni_defs.h:434
_ni_hw_device_info_quadra_coder_param::decoder_param
ni_hw_device_info_quadra_decoder_param_t * decoder_param
Definition: ni_rsrc_api.h:225
ni_rsrc_get_device_by_block_name
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.
Definition: ni_rsrc_api.cpp:1799
NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
@ NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
Definition: ni_defs.h:507