libxcoder  5.3.1
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  int ret;
1184 
1185  runtime = 0;
1186  while (1)
1187  {
1188  number_of_devices = ni_rsrc_get_local_device_list2(device_names,
1190  NULL, 0);
1191  if (number_of_devices > 0)
1192  {
1193  break;
1194  }
1195  else
1196  {
1197  ni_log(NI_LOG_INFO, "Quadra devices not ready\n");
1199  {
1200  ni_log(NI_LOG_ERROR, "User requested to stop checking\n");
1201  return 1;
1202  }
1203  if (timeout_seconds == 0) {
1204  ni_log(NI_LOG_ERROR, "Quadra devices not ready "
1205  "and exit without wait\n");
1207  }
1208  sleep(1);
1209  runtime += 1;
1210  if (runtime >= (uint32_t)timeout_seconds)
1211  {
1213  "Timeout exceeded/reached after %u seconds!\n",
1214  runtime);
1216  }
1217  }
1218  }
1219 
1221  api_version);
1222  ni_log(NI_LOG_INFO, "Compatible FW API version: %s\n", api_version);
1223 
1224  ret = ni_rsrc_init_priv(should_match_rev, number_of_devices, device_names, limit_depth);
1225 
1226  if (ret == NI_RETCODE_SUCCESS)
1227  {
1228  ret = ni_rsrc_create_retry_lck();
1229  }
1230 
1231  if (ret == NI_RETCODE_SUCCESS)
1232  {
1233  ret = ni_rsrc_refresh(should_match_rev);
1234  }
1235  return ret;
1236 }
1237 
1238 /*!******************************************************************************
1239 * \brief Allocates and returns a pointer to ni_device_context_t struct
1240 * based on provided device_type and guid.
1241 * To be used for load update and codec query.
1242 *
1243  * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1244  * \param[in] guid GUID of the encoder or decoder device
1245 *
1246 * \return pointer to ni_device_context_t if found, NULL otherwise
1247 *
1248 * Note: The returned ni_device_context_t content is not supposed to be used by
1249 * caller directly: should only be passed to API in the subsequent
1250 * calls; also after its use, the context should be released by
1251 * calling ni_rsrc_free_device_context.
1252 *******************************************************************************/
1254 {
1256  int shm_fd = -1;
1257  ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1258  int lock;
1259  int flags = O_RDWR | O_CLOEXEC;
1260  mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1261  char shm_name[32] = { 0 };
1262  char lck_name[32] = { 0 };
1263  ni_device_context_t *p_device_context = NULL;
1264  ni_device_info_t *p_device_queue = NULL;
1265 
1266  ni_rsrc_get_shm_name(device_type, guid, shm_name, sizeof(shm_name));
1267  ni_rsrc_get_lock_name(device_type, guid, lck_name, sizeof(lck_name));
1268 
1269  if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, &lock) < 0) {
1270  ni_log(NI_LOG_ERROR, "%s: Failed to get lock\n", __func__);
1271  return NULL;
1272  }
1273 
1274  if (ni_rsrc_open_shm(shm_name,
1275  sizeof(ni_device_info_t),
1276  &state,
1277  (int *)&shm_fd) < 0) {
1278  ni_log(NI_LOG_ERROR, "%s: Failed to ni_rsrc_open_shm\n", __func__);
1279  LRETURN;
1280  }
1281 
1282  if ((ni_rsrc_mmap_shm(shm_name,
1283  shm_fd,
1284  sizeof(ni_device_info_t),
1285  (void **)&p_device_queue)) < 0) {
1286  ni_log(NI_LOG_ERROR, "%s(): Failed to ni_rsrc_mmap_shm\n", __func__);
1287  LRETURN;
1288  }
1289 
1290  p_device_context = (ni_device_context_t *)malloc(sizeof(ni_device_context_t));
1291  if (!p_device_context) {
1292  ni_log(NI_LOG_ERROR, "ERROR %s() malloc() ni_device_context_t: %s\n",
1293  __func__, strerror(NI_ERRNO));
1294  ni_rsrc_munmap_shm((void *)p_device_queue, sizeof(ni_device_info_t));
1295  LRETURN;
1296  }
1297 
1298  strncpy(p_device_context->shm_name, shm_name, sizeof(p_device_context->shm_name));
1299  p_device_context->lock = lock;
1300  p_device_context->p_device_info = p_device_queue;
1301 
1302 END:
1303  lockf(lock, F_ULOCK, 0);
1304 
1305 #ifndef __OPENHARMONY__
1306  if (shm_fd >= 0) {
1307  close(shm_fd);
1308  }
1309 #endif
1310 
1311  return p_device_context;
1312 }
1313 #endif
1314 
1315 /*!******************************************************************************
1316  * \brief Free previously allocated device context
1317  *
1318  * \param p_device_context Pointer to previously allocated device context
1319  *
1320  * \return None
1321  *******************************************************************************/
1323 {
1324  if (p_device_context)
1325  {
1326 #ifdef _WIN32
1327  UnmapViewOfFile(p_device_context->p_device_info);
1328  ReleaseMutex(p_device_context->lock);
1329 #elif __linux__ || __APPLE__
1330  close(p_device_context->lock);
1331  ni_rsrc_munmap_shm((void *)p_device_context->p_device_info, sizeof(ni_device_info_t));
1332  ni_log(NI_LOG_DEBUG, "in %s do munmap for %s\n", __func__, p_device_context->shm_name);
1333 #endif
1334  free(p_device_context);
1335  }
1336 }
1337 
1338 /*!******************************************************************************
1339 * \brief List device(s) based on device type with full information
1340 * including s/w instances on the system.
1341 *
1342 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1343 * \param[out] p_device The device information returned.
1344 * \param[out] p_device_count The number of ni_device_info_t structs returned.
1345 *
1346 * \return
1347 * NI_RETCODE_SUCCESS
1348 * NI_RETCODE_FAILURE
1349 *
1350 * Note: Caller is responsible for allocating memory for "p_device".
1351 *******************************************************************************/
1353  ni_device_info_t *p_device_info, int * p_device_count)
1354 {
1355  int i, count;
1356  ni_device_queue_t *p_device_queue = NULL;
1357  ni_device_pool_t *p_device_pool = NULL;
1358  ni_device_context_t *p_device_context = NULL;
1360  bool b_release_pool_mtx = false;
1361 
1362  if ( (NULL == p_device_info) || (NULL == p_device_count) )
1363  {
1364  retval = NI_RETCODE_FAILURE;
1365  LRETURN;
1366  }
1367 
1368  p_device_pool = ni_rsrc_get_device_pool();
1369  if (NULL == p_device_pool)
1370  {
1371  retval = NI_RETCODE_FAILURE;
1372  LRETURN;
1373  }
1374 
1375 #ifdef _WIN32
1376  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval)
1377  {
1378  ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_list_devices() failed to obtain "
1379  "mutex: %p\n", p_device_pool->lock);
1380  retval = NI_RETCODE_FAILURE;
1381  LRETURN;
1382  }
1383 #elif __linux__ || __APPLE__
1384  lockf(p_device_pool->lock, F_LOCK, 0);
1385 #endif
1386 
1387  b_release_pool_mtx = true;
1388 
1389  p_device_queue = p_device_pool->p_device_queue;
1390  count = p_device_queue->xcoder_cnt[device_type];
1391 
1392  *p_device_count=0;
1393  for (i = 0; i < count; i++)
1394  {
1395  int guid = -1;
1396  guid = p_device_queue->xcoders[device_type][i];
1397  p_device_context = ni_rsrc_get_device_context(device_type, guid);
1398  if (p_device_context)
1399  {
1400 #ifdef _WIN32
1401  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
1402  {
1403  ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_list_devices() failed to obtain "
1404  "mutex: %p\n", p_device_context->lock);
1405  ReleaseMutex(p_device_pool->lock);
1406  retval = NI_RETCODE_FAILURE;
1407  LRETURN;
1408  }
1409 
1410  memcpy(&p_device_info[i], p_device_context->p_device_info, sizeof(ni_device_info_t));
1411  ReleaseMutex(p_device_context->lock);
1412 #elif __linux__ || __APPLE__
1413  lockf(p_device_context->lock, F_LOCK, 0);
1414  memcpy(&p_device_info[i], p_device_context->p_device_info, sizeof(ni_device_info_t));
1415  lockf(p_device_context->lock, F_ULOCK, 0);
1416 #endif
1417 
1418  ni_rsrc_free_device_context(p_device_context);
1419 
1420  (*p_device_count)++;
1421  }
1422  else
1423  {
1424  ni_log(NI_LOG_ERROR, "ERROR: cannot find decoder guid: %d\n", guid);
1425  }
1426  }
1427 
1428 END:
1429 
1430  if (b_release_pool_mtx)
1431  {
1432 #ifdef _WIN32
1433  ReleaseMutex(p_device_pool->lock);
1434 #elif __linux__ || __APPLE__
1435  lockf(p_device_pool->lock, F_ULOCK, 0);
1436 #endif
1437  }
1438 
1439  ni_rsrc_free_device_pool(p_device_pool);
1440 
1441  return retval;
1442 }
1443 
1444 /*!******************************************************************************
1445 * \brief List all devices with full information including s/w instances
1446 * on the system.
1447 
1448 * \param[out] p_device The device information returned.
1449 *
1450 * \return
1451 * NI_RETCODE_SUCCESS
1452 * NI_RETCODE_INVALID_PARAM
1453 * NI_RETCODE_FAILURE
1454 *
1455 * Note: Caller is responsible for allocating memory for "p_device".
1456 *******************************************************************************/
1458 {
1459  int k = 0;
1461 
1462  if (NULL == p_device)
1463  {
1464  retval = NI_RETCODE_INVALID_PARAM;
1465  LRETURN;
1466  }
1467 
1468  for (k = 0; k < NI_DEVICE_TYPE_XCODER_MAX; k++)
1469  {
1470  retval = ni_rsrc_list_devices((ni_device_type_t)k, p_device->xcoders[k],
1471  &(p_device->xcoder_cnt[k]));
1472  if (NI_RETCODE_FAILURE == retval)
1473  {
1474  ni_log(NI_LOG_ERROR, "ERROR: could not retrieve info for %d type "
1475  "devices\n", k);
1476  LRETURN;
1477  }
1478  }
1479 
1480 END:
1481 
1482  return retval;
1483 }
1484 
1485 /*!******************************************************************************
1486 * \brief Grabs information for every initialized and uninitialized
1487 * device.
1488 
1489 * \param list_uninitialized Flag to determine if uninitialized devices
1490 * should be grabbed.
1491 *
1492 * \return
1493 * NI_RETCODE_SUCCESS
1494 * NI_RETCODE_INVALID_PARAM
1495 * NI_RETCODE_FAILURE
1496 *
1497 * Note: Caller is responsible for allocating memory for "p_device".
1498 *******************************************************************************/
1499 ni_retcode_t ni_rsrc_list_all_devices2(ni_device_t* p_device, bool list_uninitialized)
1500 {
1502  if (!p_device)
1503  {
1504  retval = NI_RETCODE_INVALID_PARAM;
1505  return retval;
1506  }
1507 
1508  /* Grab initialized devices. */
1509 
1510  ni_log_level_t log_level = ni_log_get_level();
1511 
1512  if (list_uninitialized)
1513  {
1515  }
1516 
1517  ni_rsrc_list_all_devices(p_device);
1518 
1519  if (!list_uninitialized)
1520  {
1521  return retval;
1522  }
1523 
1524  ni_log_set_level(log_level);
1525 
1526  /* Store device names of initialized devices. */
1527 
1528  ni_device_info_t *p_dev_info;
1529  char initialized_dev_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = {0};
1530 
1531  for (int dev_index = 0;
1532  dev_index < p_device->xcoder_cnt[NI_DEVICE_TYPE_ENCODER]; dev_index++)
1533  {
1534  p_dev_info = &p_device->xcoders[NI_DEVICE_TYPE_ENCODER][dev_index];
1535  strcpy(initialized_dev_names[dev_index], p_dev_info->dev_name);
1536  }
1537 
1538  /* Retrieve uninitialized devices. */
1539 
1540  char dev_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = {0};
1541  int dev_count = ni_rsrc_get_local_device_list2(dev_names, NI_MAX_DEVICE_CNT,
1542  NULL, 0);
1543 
1544  uint32_t tmp_io_size;
1545  ni_device_capability_t capability;
1546  ni_device_handle_t fd;
1547 
1548  for (int dev_index = 0; dev_index < dev_count; dev_index++)
1549  {
1550  if (is_str_in_str_array(dev_names[dev_index],
1551  initialized_dev_names, NI_MAX_DEVICE_CNT))
1552  {
1553  continue;
1554  }
1555 
1556  fd = ni_device_open(dev_names[dev_index], &tmp_io_size);
1557  if (NI_INVALID_DEVICE_HANDLE == fd)
1558  {
1559  ni_log(NI_LOG_ERROR, "Failed to open device: %s\n",
1560  dev_names[dev_index]);
1561  return NI_RETCODE_FAILURE;
1562  }
1563 
1564  retval = ni_device_capability_query2(fd, &capability, false);
1565  if (NI_RETCODE_SUCCESS != retval)
1566  {
1567  ni_device_close(fd);
1568  ni_log(NI_LOG_ERROR, "Failed to query device capability: %s\n",
1569  dev_names[dev_index]);
1570  return retval;
1571  }
1572 
1573  for (int dev_type = 0; dev_type < NI_DEVICE_TYPE_XCODER_MAX; dev_type++)
1574  {
1575  p_device->xcoder_cnt[dev_type]++;
1576 
1577  p_dev_info = &p_device->xcoders[dev_type][dev_index];
1578  memcpy(p_dev_info->serial_number, capability.serial_number,
1579  sizeof(capability.serial_number));
1580  memcpy(p_dev_info->model_number, capability.model_number,
1581  sizeof(capability.model_number));
1582  memcpy(p_dev_info->fw_rev, capability.fw_rev,
1583  sizeof(capability.fw_rev));
1584  p_dev_info->fw_ver_compat_warning = ni_rsrc_is_fw_compat(capability.fw_rev) >= 2 ? 1 : 0;
1585  memcpy(p_dev_info->fw_branch_name, capability.fw_branch_name,
1586  sizeof(capability.fw_branch_name));
1587  memcpy(p_dev_info->fw_commit_time, capability.fw_commit_time,
1588  sizeof(capability.fw_commit_time));
1589  memcpy(p_dev_info->fw_commit_hash, capability.fw_commit_hash,
1590  sizeof(capability.fw_commit_hash));
1591  memcpy(p_dev_info->fw_build_time, capability.fw_build_time,
1592  sizeof(capability.fw_build_time));
1593  memcpy(p_dev_info->fw_build_id, capability.fw_build_id,
1594  sizeof(capability.fw_build_id));
1595  strcpy(p_dev_info->dev_name, dev_names[dev_index]);
1596  memcpy(p_dev_info->blk_name, p_dev_info->dev_name,
1597  sizeof(p_dev_info->dev_name));
1598  p_dev_info->device_type = (ni_device_type_t)dev_type;
1599  p_dev_info->module_id = -1; /* special value to indicate device is
1600  not initialized */
1601 
1602  ni_query_fl_fw_versions(fd, p_dev_info);
1603  }
1604 
1605  ni_device_close(fd);
1606  }
1607 
1608  return retval;
1609 }
1610 
1611 
1613 {
1614  int i;
1615 
1616  if (!p_device_info)
1617  {
1618  ni_log(NI_LOG_ERROR, "ERROR: Cannot print device info!\n");
1619  } else
1620  {
1621  ni_log(NI_LOG_INFO, " %s #%d\n",
1622  GET_XCODER_DEVICE_TYPE_STR(p_device_info->device_type),
1623  p_device_info->module_id);
1624  ni_log(NI_LOG_INFO, " H/W ID: %d\n", p_device_info->hw_id);
1625  ni_log(NI_LOG_INFO, " MaxNumInstances: %d\n",
1626  p_device_info->max_instance_cnt);
1627 
1628  if (NI_DEVICE_TYPE_SCALER == p_device_info->device_type)
1629  {
1630  ni_log(NI_LOG_INFO, " Capabilities:\n");
1632  " Operations: Crop (ni_quadra_crop), Scale (ni_quadra_scale), Pad "
1633  "(ni_quadra_pad), Overlay (ni_quadra_overlay)\n"
1634  " Drawbox (ni_quadra_drawbox), Rotate (ni_quadra_rotate), XStack (ni_quadra_xstack)\n");
1635  } else if (NI_DEVICE_TYPE_AI == p_device_info->device_type)
1636  {
1637  ni_log(NI_LOG_INFO, " Capabilities:\n");
1638  ni_log(
1639  NI_LOG_INFO,
1640  " Operations: ROI (ni_quadra_roi), Background Replace (ni_quadra_bg)\n");
1641  } else if (NI_DEVICE_TYPE_DECODER == p_device_info->device_type ||
1642  NI_DEVICE_TYPE_ENCODER == p_device_info->device_type)
1643  {
1644  ni_log(NI_LOG_INFO, " Max4KFps: %d\n", p_device_info->max_fps_4k);
1645  for (i = 0; i < EN_CODEC_MAX; i++)
1646  {
1647  if (EN_INVALID != p_device_info->dev_cap[i].supports_codec)
1648  {
1649  ni_log(NI_LOG_INFO, " %s ",
1650  ni_codec_format_str[p_device_info->dev_cap[i]
1651  .supports_codec]);
1652  ni_log(NI_LOG_INFO, "(%s) Capabilities:\n",
1654  p_device_info->device_type ?
1655  ni_dec_name_str[p_device_info->dev_cap[i]
1656  .supports_codec] :
1657  ni_enc_name_str[p_device_info->dev_cap[i]
1658  .supports_codec]);
1659  ni_log(NI_LOG_INFO, " MaxResolution: %dx%d\n",
1660  p_device_info->dev_cap[i].max_res_width,
1661  p_device_info->dev_cap[i].max_res_height);
1662  ni_log(NI_LOG_INFO, " MinResolution: %dx%d\n",
1663  p_device_info->dev_cap[i].min_res_width,
1664  p_device_info->dev_cap[i].min_res_height);
1665 
1666  // no profile for JPEG encode, or level for JPEG
1667  if (! (NI_DEVICE_TYPE_ENCODER == p_device_info->device_type &&
1668  EN_JPEG == p_device_info->dev_cap[i].supports_codec))
1669  {
1670  ni_log(NI_LOG_INFO, " Profiles: %s\n",
1671  p_device_info->dev_cap[i].profiles_supported);
1672  }
1673  if (EN_JPEG != p_device_info->dev_cap[i].supports_codec)
1674  {
1675  ni_log(NI_LOG_INFO, " Level: %s\n",
1676  p_device_info->dev_cap[i].level);
1677  }
1678  }
1679  }
1680  }
1681  }
1682 }
1683 
1684 /*!*****************************************************************************
1685 * \brief Print detailed capability information of all devices
1686 * on the system.
1687 
1688 * \param none
1689 *
1690 * \return none
1691 *
1692 *******************************************************************************/
1694 {
1695  ni_device_t *device = NULL;
1696  device = (ni_device_t *)malloc(sizeof(ni_device_t));
1697  if (!device)
1698  {
1699  ni_log(NI_LOG_ERROR, "ERROR %s() failed to malloc memory: %s\n",
1700  __func__, strerror(NI_ERRNO));
1701  return;
1702  }
1703  memset(device, 0, sizeof(ni_device_t));
1704 
1706  {
1707  free(device);
1708  return;
1709  }
1710 
1711  print_device(device);
1712  free(device);
1713 }
1714 
1715 /*!*****************************************************************************
1716 * \brief Prints detailed capability information for all initialized
1717 * devices and general information about uninitialized devices.
1718 
1719 * \param list_uninitialized Flag to determine if uninitialized devices
1720 * should be grabbed.
1721 *
1722 * \return none
1723 *
1724 *******************************************************************************/
1725 void ni_rsrc_print_all_devices_capability2(bool list_uninitialized)
1726 {
1727  ni_device_t *device = NULL;
1728  device = (ni_device_t *)malloc(sizeof(ni_device_t));
1729  if (!device)
1730  {
1731  ni_log(NI_LOG_ERROR, "ERROR %s() failed to malloc memory: %s\n",
1732  __func__, strerror(NI_ERRNO));
1733  return;
1734  }
1735  memset(device, 0, sizeof(ni_device_t));
1736 
1737  if (NI_RETCODE_SUCCESS != ni_rsrc_list_all_devices2(device, list_uninitialized))
1738  {
1739  free(device);
1740  return;
1741  }
1742 
1743  print_device(device);
1744  free(device);
1745 }
1746 
1747 /*!******************************************************************************
1748 * \brief Query a specific device with detailed information on the system
1749 
1750 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1751 * \param[in] guid unique device(decoder or encoder) id
1752 *
1753 * \return
1754 * pointer to ni_device_info_t if found
1755 * NULL otherwise
1756 *
1757 * Note: Caller is responsible for releasing memory that was allocated for the
1758 * returned pointer
1759 *******************************************************************************/
1761 {
1762  ni_device_info_t *p_device_info = NULL;
1763  ni_device_context_t* p_device_context = NULL;
1764 
1765  p_device_context = ni_rsrc_get_device_context(device_type, guid);
1766  if (NULL == p_device_context)
1767  {
1768  LRETURN;
1769  }
1770 
1771  p_device_info = (ni_device_info_t *)malloc(sizeof(ni_device_info_t));
1772  if (NULL == p_device_info)
1773  {
1774  LRETURN;
1775  }
1776 
1777 #ifdef _WIN32
1778  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
1779  {
1780  ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_get_device_info() failed to obtain "
1781  "mutex: %p\n", p_device_context->lock);
1782  free(p_device_info);
1783  LRETURN;
1784  }
1785 
1786  memcpy(p_device_info, p_device_context->p_device_info, sizeof(ni_device_info_t));
1787  ReleaseMutex(p_device_context->lock);
1788 #elif __linux
1789  lockf(p_device_context->lock, F_LOCK, 0);
1790 
1791  memcpy(p_device_info, p_device_context->p_device_info, sizeof(ni_device_info_t));
1792 
1793  lockf(p_device_context->lock, F_ULOCK, 0);
1794 #endif
1795 
1796 END:
1797 
1798  ni_rsrc_free_device_context(p_device_context);
1799 
1800  return p_device_info;
1801 }
1802 
1803 /*!****************************************************************************
1804 * \brief Get GUID of the device by block device name and type
1805 *
1806 * \param[in] blk_name device's block name
1807 * \param[in] type device type
1808 *
1809 * \return device GUID (>= 0) if found, NI_RETCODE_FAILURE (-1) otherwise
1810 *******************************************************************************/
1811 int ni_rsrc_get_device_by_block_name(const char *blk_name,
1812  ni_device_type_t device_type)
1813 {
1814  int i;
1815  int guid = NI_RETCODE_FAILURE, tmp_id;
1816  ni_device_pool_t *p_device_pool = NULL;
1817  ni_device_context_t *p_device_context = NULL;
1818  int num_coders = 0;
1819 
1820  //uploader shares instance with encoder
1821  if(device_type == NI_DEVICE_TYPE_UPLOAD)
1822  {
1823  device_type = NI_DEVICE_TYPE_ENCODER;
1824  }
1825 
1826  p_device_pool = ni_rsrc_get_device_pool();
1827  if (!p_device_pool)
1828  {
1829  ni_log(NI_LOG_ERROR, "ERROR: cannot get p_device_pool\n");
1830  return guid;
1831  }
1832 
1833 #ifdef _WIN32
1834  // no time-out interval (we got the mutex)
1835  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE))
1836  {
1837  ni_log(NI_LOG_ERROR, "ERROR: %s failed to obtain mutex: %p\n",
1838  __FUNCTION__, p_device_pool->lock);
1839  ni_rsrc_free_device_pool(p_device_pool);
1840  return NI_RETCODE_FAILURE;
1841  }
1842 #elif __linux__ || __APPLE__
1843  lockf(p_device_pool->lock, F_LOCK, 0);
1844 #endif
1845 
1846  num_coders = p_device_pool->p_device_queue->xcoder_cnt[device_type];
1847 
1848  for (i = 0; i < num_coders; i++)
1849  {
1850  tmp_id = p_device_pool->p_device_queue->xcoders[device_type][i];
1851  p_device_context = ni_rsrc_get_device_context(device_type, tmp_id);
1852 
1853  if (p_device_context &&
1854  0 == strcmp(p_device_context->p_device_info->dev_name, blk_name))
1855  {
1856  guid = p_device_context->p_device_info->module_id;
1857  ni_rsrc_free_device_context(p_device_context);
1858  break;
1859  }
1860 
1861  ni_rsrc_free_device_context(p_device_context);
1862  }
1863 
1864 #ifdef _WIN32
1865  ReleaseMutex(p_device_pool->lock);
1866 #elif __linux__ || __APPLE__
1867  lockf(p_device_pool->lock, F_ULOCK, 0);
1868 #endif
1869 
1870  ni_rsrc_free_device_pool(p_device_pool);
1871 
1872  ni_log(NI_LOG_DEBUG, "%s %s got guid: %d\n", __FUNCTION__, blk_name, guid);
1873 
1874  return guid;
1875 }
1876 
1877 /*!*****************************************************************************
1878 * \brief Update the load value and s/w instances info of a specific decoder or
1879 * encoder. This is used by resource management daemon to update periodically.
1880 *
1881 * \param[in] p_ctxt The device context returned by ni_rsrc_get_device_context
1882 * \param[in] p_load The latest load value to update
1883 * \param[in] sw_instance_cnt Number of s/w instances
1884 * \param[in] sw_instance_info Info of s/w instances
1885 *
1886 * \return
1887 * NI_RETCODE_SUCCESS
1888 * NI_RETCODE_FAILURE
1889 *******************************************************************************/
1890 int ni_rsrc_update_device_load(ni_device_context_t *p_device_context, int load,
1891  int sw_instance_cnt, const ni_sw_instance_info_t sw_instance_info[])
1892 {
1893  int i;
1894  if (!p_device_context || !sw_instance_info)
1895  {
1896  ni_log(NI_LOG_ERROR, "ERROR: %s() invalid input pointers\n", __func__);
1897  return NI_RETCODE_FAILURE;
1898  }
1899 
1900 #ifdef _WIN32
1901  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
1902  {
1903  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %p\n",
1904  __func__, p_device_context->lock);
1905  return NI_RETCODE_FAILURE;
1906  }
1907 #elif __linux__ || __APPLE__
1908  lockf(p_device_context->lock, F_LOCK, 0);
1909 #endif
1910 
1911  p_device_context->p_device_info->load = load;
1912  p_device_context->p_device_info->active_num_inst = sw_instance_cnt;
1913  for (i = 0; i < sw_instance_cnt; i++)
1914  {
1915  p_device_context->p_device_info->sw_instance[i] = sw_instance_info[i];
1916  }
1917 
1918 #ifdef _WIN32
1919  ReleaseMutex(p_device_context->lock);
1920 #elif __linux__ || __APPLE__
1921  lockf(p_device_context->lock, F_ULOCK, 0);
1922 #endif
1923 
1924  return NI_RETCODE_SUCCESS;
1925 }
1926 
1927 /*!*****************************************************************************
1928 * \brief Allocate resources for decoding/encoding, by designating explicitly
1929 * the device to use. do not track the load on the host side
1930 *
1931 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
1932 * \param[in] guid unique device (decoder or encoder) module id
1933 * \return pointer to ni_device_context_t if found, NULL otherwise
1934 *
1935 * Note: only need to specify the device type and guid and codec type
1936 *
1937 *
1938 * Note: the returned ni_device_context_t content is not supposed to be used by
1939 * caller directly: should only be passed to API in the subsequent
1940 * calls; also after its use, the context should be released by
1941 * calling ni_rsrc_free_device_context.
1942 *******************************************************************************/
1945  ni_device_type_t device_type,
1946  int guid
1947 )
1948 {
1949  ni_device_context_t *p_device_context = ni_rsrc_get_device_context(device_type, guid);
1950 
1951  return p_device_context;
1952 }
1953 
1954 
1955 /*!*****************************************************************************
1956 * \brief Release resources allocated for decoding/encoding.
1957 * function This *must* be called at the end of transcoding
1958 * with previously assigned load value by allocate* functions.
1959 *
1960 * \param[in/out] p_ctxt the device context
1961 * \param[in] load the load value returned by allocate* functions
1962 *
1963 * \return None
1964 *******************************************************************************/
1966  uint64_t load)
1967 {
1968 
1969 #if 1
1970  (void) p_device_context;
1971  (void) load;
1972  return;
1973 
1974 #else
1975  if (!p_device_context)
1976  {
1977  ni_log(NI_LOG_ERROR, "ERROR: %s() invalid input pointers\n", __func__);
1978  return;
1979  }
1980 
1981 #ifdef _WIN32
1982  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
1983  {
1984  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %p\n",
1985  __func__, p_device_context->lock);
1986  }
1987 #elif __linux__ || __APPLE__
1988  lockf(p_device_context->lock, F_LOCK, 0);
1989 #endif
1990 
1991  if (p_device_context->p_device_info->xcode_load_pixel < load)
1992  {
1993  ni_log(NI_LOG_INFO, "Warning: releasing resource load %lu > current load %lu\n", load,
1994  p_device_context->p_device_info->xcode_load_pixel);
1995  }
1996  else
1997  {
1998  p_device_context->p_device_info->xcode_load_pixel -= load;
1999  // Remove as the value is getting from the FW
2000  // p_device_context->p_device_info->model_load = (int)((double)(p_device_context->p_device_info->xcode_load_pixel) * 100 / total_cap);
2001 #if __linux__ || __APPLE__
2002  if (msync((void *)p_device_context->p_device_info, sizeof(ni_device_info_t), MS_SYNC | MS_INVALIDATE))
2003  {
2004  ni_log(NI_LOG_ERROR, "ERROR %s() msync() p_device_context->"
2005  "p_device_info: %s\n", __func__, strerror(NI_ERRNO));
2006  }
2007 #endif
2008  }
2009 
2010 #ifdef _WIN32
2011  ReleaseMutex(p_device_context->lock);
2012 #elif __linux__ || __APPLE__
2013  lockf(p_device_context->lock, F_ULOCK, 0);
2014 #endif
2015 
2016 #endif
2017 }
2018 
2019 /*!*****************************************************************************
2020 * \brief check the NetInt h/w device in resource pool on the host.
2021 *
2022 * \param[in] guid the global unique device index in resource pool
2023 * device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
2024 *
2025 * \return
2026 * NI_RETCODE_SUCCESS
2027 *******************************************************************************/
2029 {
2030  ni_device_pool_t *p_device_pool = NULL;
2031  ni_device_context_t *p_device_ctx = NULL;
2032  ni_session_context_t session_ctx = {0};
2033  ni_xcoder_params_t api_param = {0};
2034  uint32_t max_nvme_io_size = 0;
2035  bool b_release_pool_mtx = false;
2037  int retry_cnt = 0;
2038 
2039  if (guid < 0)
2040  {
2041  ni_log(NI_LOG_ERROR, "ERROR invalid guid:%d\n", guid);
2042  return NI_RETCODE_INVALID_PARAM;
2043  }
2044 
2045  if (!IS_XCODER_DEVICE_TYPE(device_type))
2046  {
2047  ni_log(NI_LOG_ERROR, "ERROR: Unknown device type:%d\n", device_type);
2048  return NI_RETCODE_INVALID_PARAM;
2049  }
2050 
2051  ni_device_session_context_init(&session_ctx);
2053  session_ctx.src_bit_depth = 8;
2054  session_ctx.hw_id = guid;
2055 
2056  if (NI_DEVICE_TYPE_DECODER == device_type)
2057  {
2058  if (ni_decoder_init_default_params(&api_param, 30, 1, NI_MIN_BITRATE,
2061  {
2062  ni_log(NI_LOG_ERROR, "ERROR: set decoder default params error\n");
2063  return NI_RETCODE_INVALID_PARAM;
2064  }
2065  } else if (NI_DEVICE_TYPE_ENCODER == device_type)
2066  {
2068  &api_param, 30, 1, NI_MIN_BITRATE, XCODER_MIN_ENC_PIC_WIDTH,
2070  {
2071  ni_log(NI_LOG_ERROR, "ERROR: set encoder default params error\n");
2072  return NI_RETCODE_INVALID_PARAM;
2073  }
2074  } else if (NI_DEVICE_TYPE_SCALER == device_type)
2075  {
2076  session_ctx.device_type = NI_DEVICE_TYPE_SCALER;
2078  } else
2079  {
2080  session_ctx.device_type = NI_DEVICE_TYPE_AI;
2081  }
2082  session_ctx.p_session_config = &api_param;
2083 
2084  p_device_pool = ni_rsrc_get_device_pool();
2085  if (!p_device_pool)
2086  {
2087  ni_log(NI_LOG_ERROR, "ERROR: get device poll failed\n");
2089  LRETURN;
2090  }
2091 
2092 #ifdef _WIN32
2093  if (WAIT_ABANDONED ==
2094  WaitForSingleObject(p_device_pool->lock,
2095  INFINITE)) // no time-out interval)
2096  {
2098  "ERROR: ni_rsrc_list_devices() failed to obtain mutex: %p\n",
2099  p_device_pool->lock);
2100  retval = NI_RETCODE_FAILURE;
2101  LRETURN;
2102  }
2103 #elif __linux__
2104  lockf(p_device_pool->lock, F_LOCK, 0);
2105 #endif
2106  b_release_pool_mtx = true;
2107 
2108  // get device context
2109  p_device_ctx = ni_rsrc_get_device_context(device_type, guid);
2110  if (p_device_ctx)
2111  {
2112  session_ctx.device_handle = ni_device_open(
2113  p_device_ctx->p_device_info->dev_name, &max_nvme_io_size);
2114  session_ctx.blk_io_handle = session_ctx.device_handle;
2115  if (NI_INVALID_DEVICE_HANDLE == session_ctx.device_handle)
2116  {
2117  ni_log(NI_LOG_ERROR, "open device failed: %d\n", errno);
2119  } else
2120  {
2121 #ifdef _WIN32
2122  session_ctx.event_handle = ni_create_event();
2123  if (NI_INVALID_EVENT_HANDLE == session_ctx.event_handle)
2124  {
2125  ni_log(NI_LOG_INFO, "Error create envent:%d\n", GetLastError());
2126  retval = NI_RETCODE_FAILURE;
2127  LRETURN;
2128  }
2129 #endif
2130  retval = ni_device_session_query(&session_ctx, device_type);
2131  if (NI_RETCODE_SUCCESS != retval)
2132  {
2134  "guid %d. %s is not avaiable, type: %d, retval:%d\n",
2135  guid, p_device_ctx->p_device_info->dev_name,
2136  device_type, retval);
2137  retval = NI_RETCODE_FAILURE;
2138  } else
2139  {
2140  while (1)
2141  {
2142  retry_cnt++;
2143  retval = ni_device_session_open(&session_ctx, device_type);
2144  ni_device_session_close(&session_ctx, 0, device_type);
2145  if (retval == NI_RETCODE_SUCCESS)
2146  {
2147  ni_log(NI_LOG_INFO, "guid %d. %s is avaiable\n",
2148  guid, p_device_ctx->p_device_info->dev_name);
2149  break;
2150  } else if (
2151  retry_cnt < 10 &&
2152  retval ==
2153  NI_RETCODE_ERROR_VPU_RECOVERY) // max 2 seconds
2154  {
2156  "vpu recovery happened on guid %d. %s, retry "
2157  "cnt:%d\n",
2158  guid, p_device_ctx->p_device_info->dev_name,
2159  retry_cnt);
2160 #ifndef _WIN32
2161  ni_usleep(200000); // 200 ms
2162 #endif
2163  continue;
2164  } else
2165  {
2167  "session open error guid %d. %s, type: %d, "
2168  "retval:%d\n",
2169  guid, p_device_ctx->p_device_info->dev_name,
2170  device_type, retval);
2171  retval = NI_RETCODE_FAILURE;
2172  break;
2173  }
2174  }
2175  }
2176  }
2177  } else
2178  {
2180  "Error get device resource: guid %d, device_ctx %p\n", guid,
2181  p_device_ctx);
2182  retval = NI_RETCODE_FAILURE;
2183  }
2184 
2185 END:
2186 
2187  if (b_release_pool_mtx)
2188  {
2189 #ifdef _WIN32
2190  ReleaseMutex(p_device_pool->lock);
2191 #elif __linux__
2192  lockf(p_device_pool->lock, F_ULOCK, 0);
2193 #endif
2194  }
2195 
2196  ni_close_event(session_ctx.event_handle);
2197  ni_device_close(session_ctx.device_handle);
2198 
2199  ni_rsrc_free_device_context(p_device_ctx);
2200  ni_device_session_context_clear(&session_ctx);
2201  ni_rsrc_free_device_pool(p_device_pool);
2202 
2203  return retval;
2204 }
2205 
2206 /*!*****************************************************************************
2207 * \brief Remove an NetInt h/w device from resource pool on the host.
2208 *
2209 * \param[in] p_dev the NVMe device name
2210 *
2211 * \return
2212 * NI_RETCODE_SUCCESS
2213 * NI_RETCODE_FAILURE
2214 *******************************************************************************/
2215 int ni_rsrc_remove_device(const char* dev)
2216 {
2217 #if __linux__ || __APPLE__
2218  char lck_name[32];
2219 #endif
2220  int return_value = NI_RETCODE_SUCCESS;
2221  int32_t guid;
2222  int32_t guids[NI_MAX_DEVICE_CNT];
2223  unsigned int guid_index_i, guid_index_j, ui_device_type;
2224 #ifdef _WIN32
2225  DWORD rValue;
2226 #endif
2227  ni_device_context_t *p_device_context;
2228  ni_device_pool_t *p_device_pool = NULL;
2229  ni_device_queue_t *p_device_queue;
2230  ni_device_type_t device_type;
2231 
2232  if (!dev)
2233  {
2234  ni_log(NI_LOG_ERROR, "ERROR: %s() dev is NULL\n", __FUNCTION__);
2235  return_value = NI_RETCODE_INVALID_PARAM;
2236  LRETURN;
2237  }
2238 
2239  p_device_pool = ni_rsrc_get_device_pool();
2240  if (!p_device_pool)
2241  {
2242  return_value = NI_RETCODE_FAILURE;
2243  LRETURN;
2244  }
2245 
2246 #ifdef _WIN32
2247  rValue = WaitForSingleObject(p_device_pool->lock, INFINITE);
2248  if (rValue != WAIT_OBJECT_0)
2249  {
2251  "ERROR: %s() Failed to obtain mutex %p\n",
2252  __FUNCTION__,
2253  p_device_pool->lock);
2254  return_value = NI_RETCODE_FAILURE;
2255  LRETURN;
2256  }
2257 #elif __linux__ || __APPLE__
2258  lockf(p_device_pool->lock, F_LOCK, 0);
2259 #endif
2260 
2261  p_device_queue = p_device_pool->p_device_queue;
2262  for (guid_index_i = 0; guid_index_i < NI_MAX_DEVICE_CNT; guid_index_i++)
2263  {
2264  for (ui_device_type = NI_DEVICE_TYPE_DECODER;
2265  ui_device_type < NI_DEVICE_TYPE_XCODER_MAX;
2266  ui_device_type++)
2267  {
2268  guid = p_device_queue->xcoders[ui_device_type][guid_index_i];
2269  if (guid == -1)
2270  {
2271  continue;
2272  }
2273  device_type = (ni_device_type_t)ui_device_type;
2274  p_device_context = ni_rsrc_get_device_context(device_type, guid);
2275  if (!p_device_context)
2276  {
2278  "ERROR: %s() Failed to obtain device context for "
2279  "%s with GUID %u! Undefined behavior!\n",
2280  __func__,
2281  GET_XCODER_DEVICE_TYPE_STR(device_type),
2282  guid);
2283  return_value = NI_RETCODE_FAILURE;
2284  continue;
2285  }
2286 
2287  if (strncmp(dev,
2288  p_device_context->p_device_info->dev_name,
2289  NI_MAX_DEVICE_NAME_LEN) != 0)
2290  {
2291  if (strncmp(dev, p_device_context->p_device_info->dev_name, strlen(dev)) == 0)
2292  {
2294  "ERROR: %s() Devicename format mismatch %s %s\n",
2295  __func__,dev,p_device_context->p_device_info->dev_name);
2296  return_value = NI_RETCODE_FAILURE;
2297  }
2298  continue;
2299  }
2300 
2301 #ifdef _WIN32
2302  CloseHandle(p_device_context->lock);
2303 #elif __linux__ || __APPLE__
2304  if (!ni_rsrc_remove_shm(p_device_context->shm_name, sizeof(ni_device_info_t)))
2305  {
2307  "%s %s %s deleted\n",
2308  dev,
2309  GET_XCODER_DEVICE_TYPE_STR(device_type),
2310  p_device_context->shm_name);
2311  }
2312  else
2313  {
2315  "ERROR: %s(): %s %s %s failed to delete %s\n",
2316  __FUNCTION__,
2317  dev,
2318  GET_XCODER_DEVICE_TYPE_STR(device_type),
2319  p_device_context->shm_name,
2320  strerror(NI_ERRNO));
2321  return_value = NI_RETCODE_FAILURE;
2322  }
2323 #endif
2324 
2325  ni_rsrc_free_device_context(p_device_context);
2326 
2327 #if __linux__ || __APPLE__
2328  ni_rsrc_get_lock_name(device_type, guid, lck_name, 32);
2329  if (!unlink(lck_name))
2330  {
2332  "%s %s %s deleted\n",
2333  dev,
2334  GET_XCODER_DEVICE_TYPE_STR(device_type),
2335  lck_name);
2336  }
2337  else
2338  {
2340  "ERROR: %s(): %s %s %s failed to delete %s\n",
2341  __FUNCTION__,
2342  dev,
2343  GET_XCODER_DEVICE_TYPE_STR(device_type),
2344  lck_name,
2345  strerror(NI_ERRNO));
2346  return_value = NI_RETCODE_FAILURE;
2347  }
2348 #endif
2349 
2350  if (return_value != NI_RETCODE_SUCCESS)
2351  {
2352  continue;
2353  }
2354 
2355  p_device_queue->xcoders[ui_device_type][guid_index_i] = -1;
2356  p_device_queue->xcoder_cnt[ui_device_type]--;
2357  }
2358  }
2359 
2360  // Take p_device_queue->xcoder_cnt[ui_device_type] to contain the value 2.
2361  // p_device_queue->xcoders[ui_device_type] could be [0, -1, 2, ...]
2362  // p_device_queue->xcoders[ui_device_type] should be [0, 2, -1, ...]
2363  for (ui_device_type = NI_DEVICE_TYPE_DECODER;
2364  ui_device_type < NI_DEVICE_TYPE_XCODER_MAX;
2365  ui_device_type++)
2366  {
2367  memset(guids, -1, sizeof(guids));
2368  guid_index_j = 0;
2369  for (guid_index_i = 0; guid_index_i < NI_MAX_DEVICE_CNT; guid_index_i++)
2370  {
2371  guid = p_device_queue->xcoders[ui_device_type][guid_index_i];
2372  if (guid != -1)
2373  {
2374  guids[guid_index_j] = guid;
2375  guid_index_j++;
2376  if (guid_index_j == p_device_queue->xcoder_cnt[ui_device_type])
2377  {
2378  break;
2379  }
2380  }
2381  }
2382  memcpy(p_device_queue->xcoders[ui_device_type], guids, sizeof(guids));
2383  }
2384 
2385 #if __linux__ || __APPLE__
2386 #ifndef _ANDROID
2387  if (!msync((void *)p_device_queue,
2388  sizeof(ni_device_queue_t),
2389  MS_SYNC|MS_INVALIDATE))
2390  {
2391  ni_log(NI_LOG_INFO, "%s deleted\n", dev);
2392  }
2393  else
2394  {
2396  "ERROR: %s(): msync() failed to delete %s: %s\n",
2397  __FUNCTION__,
2398  dev,
2399  strerror(NI_ERRNO));
2400  return_value = NI_RETCODE_FAILURE;
2401  }
2402 #endif
2403 #endif
2404 
2405 #ifdef _WIN32
2406  ReleaseMutex(p_device_pool->lock);
2407 #elif __linux__ || __APPLE__
2408  lockf(p_device_pool->lock, F_ULOCK, 0);
2409 #endif
2410 
2411 end:
2412  ni_rsrc_free_device_pool(p_device_pool);
2413 
2414  return return_value;
2415 }
2416 
2417 /*!*****************************************************************************
2418 * \brief Remove all NetInt h/w devices from resource pool on the host.
2419 *
2420 * \param none
2421 *
2422 * \return
2423 * NI_RETCODE_SUCCESS
2424 * NI_RETCODE_FAILURE
2425 *******************************************************************************/
2427 {
2428  char xcoder_dev_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN] = {0};
2429  int xcoder_dev_count = 0;
2430  int i = 0;
2431  ni_device_t *saved_coders = NULL;
2432  saved_coders = (ni_device_t *)malloc(sizeof(ni_device_t));
2433  if (!saved_coders)
2434  {
2435  ni_log(NI_LOG_ERROR, "ERROR %s() failed to malloc memory: %s\n",
2436  __func__, strerror(NI_ERRNO));
2437  return NI_RETCODE_FAILURE;
2438  }
2439  memset(saved_coders, 0, sizeof(ni_device_t));
2440 
2441  // retrieve saved info from resource pool at start up
2442  if (NI_RETCODE_SUCCESS ==
2445  saved_coders->xcoders[NI_DEVICE_TYPE_ENCODER],
2446  &(saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER])))
2447  {
2448  for (i = 0; i < saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
2449  i++)
2450  {
2451  strcpy(xcoder_dev_names[i],
2452  saved_coders->xcoders[NI_DEVICE_TYPE_ENCODER][i]
2453  .dev_name);
2454  ni_log(NI_LOG_INFO, "device %d %s retrieved\n", i,
2455  xcoder_dev_names[i]);
2456  }
2457  xcoder_dev_count =
2458  saved_coders->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
2459 #ifdef XCODER_311
2461  "%d devices retrieved from current pool at start up\n",
2462  xcoder_dev_count);
2463 #else
2465  "%d devices retrieved from current pool at start up\n",
2466  xcoder_dev_count);
2467 #endif
2468  } else
2469  {
2470  ni_log(NI_LOG_ERROR, "Error retrieving from current pool at start "
2471  "up\n");
2472  }
2473  free(saved_coders);
2474 
2475  // remove from resource pool all devices
2476  for (i = 0; i < xcoder_dev_count; i++)
2477  {
2478  ni_log(NI_LOG_INFO, "removing device %d %s !\n", i,
2479  xcoder_dev_names[i]);
2480  if (NI_RETCODE_SUCCESS ==
2481  ni_rsrc_remove_device(xcoder_dev_names[i]))
2482  {
2483  ni_log(NI_LOG_INFO, "%s deleted successfully !\n",
2484  xcoder_dev_names[i]);
2485  } else
2486  {
2487  ni_log(NI_LOG_ERROR, "%s failed to delete !\n",
2488  xcoder_dev_names[i]);
2489  }
2490  }
2491 
2492 #if __linux__ || __APPLE__
2493  if (!ni_rsrc_remove_shm(CODERS_SHM_NAME, sizeof(ni_device_queue_t)))
2494  {
2495  ni_log(NI_LOG_INFO, "%s deleted.\n", CODERS_SHM_NAME);
2496  }
2497  else
2498  {
2499  ni_log(NI_LOG_ERROR, "%s failed to delete !\n", CODERS_SHM_NAME);
2500  }
2501 
2502  for (i = 0; i < NI_DEVICE_TYPE_XCODER_MAX; i++)
2503  {
2504  if (0 == unlink(XCODERS_RETRY_LCK_NAME[i]))
2505  {
2506  ni_log(NI_LOG_INFO, "%d %s deleted.\n",
2507  i, XCODERS_RETRY_LCK_NAME[i]);
2508  }
2509  else
2510  {
2511  ni_log(NI_LOG_ERROR, "%d %s failed to delete !\n",
2512  i, XCODERS_RETRY_LCK_NAME[i]);
2513  }
2514  }
2515 
2516  if (0 == unlink(CODERS_LCK_NAME))
2517  {
2518  ni_log(NI_LOG_INFO, "%s deleted.\n", CODERS_LCK_NAME);
2519  }
2520  else
2521  {
2522  ni_log(NI_LOG_ERROR, "%s failed to delete !\n", CODERS_LCK_NAME);
2523  }
2524 #endif
2525 
2526  return NI_RETCODE_SUCCESS;
2527 }
2528 
2529 /*!*****************************************************************************
2530 * \brief Add an NetInt h/w device into resource pool on the host.
2531 *
2532 * \param[in] p_dev Device name represented as C string. ex "/dev/nvme0"
2533 * \param[in] should_match_rev 0: transcoder firmware revision matching the
2534 * library's version is NOT required for placing
2535 * the transcoder into resource pool; 1: otherwise
2536 *
2537 * \return
2538 * NI_RETCODE_SUCCESS
2539 * NI_RETCODE_INVALID_PARAM
2540 * NI_RETCODE_FAILURE
2541 *******************************************************************************/
2542 int ni_rsrc_add_device(const char* dev, int should_match_rev)
2543 {
2544  uint32_t i, existing_number_of_devices;
2545 
2546  ni_device_type_t device_type;
2547  ni_device_context_t *device_context;
2548  ni_device_pool_t *device_pool;
2549  ni_device_queue_t *device_queue;
2550  ni_retcode_t retcode;
2551 
2552  if (!dev)
2553  {
2554  ni_log(NI_LOG_ERROR, "ERROR: %s(): dev is NULL\n", __FUNCTION__);
2555  return NI_RETCODE_INVALID_PARAM;
2556  }
2557 
2558  device_pool = ni_rsrc_get_device_pool();
2559  if (!device_pool)
2560  {
2561  return NI_RETCODE_SUCCESS;
2562  }
2563 
2564 #ifdef _WIN32
2565  if (WAIT_ABANDONED == WaitForSingleObject(device_pool->lock, INFINITE))
2566  {
2568  "ERROR: %s(): Failed to obtain lock %p\n",
2569  __FUNCTION__,
2570  device_pool->lock);
2571  return NI_RETCODE_FAILURE;
2572  }
2573 #elif __linux__ || __APPLE__
2574  lockf(device_pool->lock, F_LOCK, 0);
2575 #endif
2576 
2577  retcode = NI_RETCODE_SUCCESS;
2578 
2579  device_type = NI_DEVICE_TYPE_ENCODER;
2580  device_queue = device_pool->p_device_queue;
2581  existing_number_of_devices = device_queue->xcoder_cnt[device_type];
2582 
2583  if (existing_number_of_devices == NI_MAX_DEVICE_CNT)
2584  {
2586  "ERROR: %s(): Limit of NI_MAX_DEVICE_CNT(%d) existing Quadra "
2587  "devices previously reached. Not adding %s.\n",
2588  __FUNCTION__,
2590  dev);
2591  retcode = NI_RETCODE_FAILURE;
2592  LRETURN;
2593  }
2594 
2595  for (i = 0; i < existing_number_of_devices; i++)
2596  {
2597  device_context =
2598  ni_rsrc_get_device_context(device_type,
2599  device_queue->xcoders[device_type][i]);
2600  if (device_context && !strncmp(device_context->p_device_info->dev_name,
2601  dev,
2603  {
2604  retcode = NI_RETCODE_FAILURE;
2606  "ERROR: %s(): %s already exists in resource pool\n",
2607  __FUNCTION__,
2608  dev);
2609  ni_rsrc_free_device_context(device_context);
2610  LRETURN;
2611  }
2612  ni_rsrc_free_device_context(device_context);
2613  }
2614 
2615  if (!add_to_shared_memory(dev,
2616  true,
2617  should_match_rev,
2618  device_queue))
2619  {
2620  retcode = NI_RETCODE_FAILURE;
2621  }
2622 
2623 end:
2624 #ifdef _WIN32
2625  ReleaseMutex(device_pool->lock);
2626 #elif __linux__ || __APPLE__
2627  lockf(device_pool->lock, F_ULOCK, 0);
2628 #endif
2629  ni_rsrc_free_device_pool(device_pool);
2630  return retcode;
2631 }
2632 
2633 /*!*****************************************************************************
2634 * \brief Free all resources taken by the device pool
2635 *
2636 * \param[in] p_device_pool Poiner to a device pool struct
2637 *
2638 * \return None
2639 *******************************************************************************/
2641 {
2642  if (p_device_pool)
2643  {
2644  if (NI_INVALID_LOCK_HANDLE != p_device_pool->lock)
2645  {
2646 #ifdef _WIN32
2647  CloseHandle(p_device_pool->lock);
2648 #elif __linux__ || __APPLE__
2649  close(p_device_pool->lock);
2650 #endif
2651  }
2652 #ifdef _WIN32
2653  UnmapViewOfFile(p_device_pool->p_device_queue);
2654 #else
2655  ni_rsrc_munmap_shm((void *)p_device_pool->p_device_queue, sizeof(ni_device_queue_t));
2656  ni_log(NI_LOG_DEBUG, "in %s do munmap for %s\n", __func__, CODERS_SHM_NAME);
2657 #endif
2658 
2659  free(p_device_pool);
2660  }
2661 }
2662 
2663 /*!*****************************************************************************
2664  * \brief lock a file lock and open a session on a device
2665  *
2666  * \param device_type
2667  * \param lock
2668  *
2669  * \return None
2670  *******************************************************************************/
2671 int ni_rsrc_lock_and_open(int device_type, ni_lock_handle_t* lock)
2672 {
2673 
2674  int count = 0;
2675  int status = NI_RETCODE_ERROR_LOCK_DOWN_DEVICE;
2676 #ifdef _WIN32
2677  *lock = CreateMutex(NULL, FALSE, XCODERS_RETRY_LCK_NAME[device_type]);
2678 
2679  if (NULL == *lock)
2680  {
2681  ni_log(NI_LOG_ERROR, "ERROR: %s() CreateMutex() %s failed: %s\n",
2682  __func__, XCODERS_RETRY_LCK_NAME[device_type],
2683  strerror(NI_ERRNO));
2685  }
2686 #else
2687  do
2688  {
2689  // the retry lock files should be created in ni_rsrc_init
2690  *lock =
2691  open(XCODERS_RETRY_LCK_NAME[device_type], O_RDWR | O_CLOEXEC);
2692 
2693  if (*lock < 0)
2694  {
2695  ni_log(NI_LOG_ERROR, "Can not lock down the file lock. Error: %s\n", strerror(errno));
2697  }
2698  }
2699  while (0);
2700 #endif
2701  // Now the lock is free so we lock it down
2702  count = 0;
2703  do
2704  {
2705  //sleep 10ms if the file lock is locked by other FFmpeg process
2706  if (count>=1)
2707  {
2708  //sleep 10ms if the file lock is locked by other FFmpeg process
2710  }
2711 #ifdef _WIN32
2712  DWORD ret = WaitForSingleObject(*lock, 1); // time-out 1ms
2713  if (WAIT_OBJECT_0 == ret)
2714  {
2715  status = NI_RETCODE_SUCCESS;
2716  } else if (WAIT_TIMEOUT != ret)
2717  {
2718  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %s\n",
2719  __func__, strerror(NI_ERRNO));
2720  }
2721 #else
2722  status = lockf(*lock, F_LOCK, 0);
2723 #endif
2724  if (status != 0)
2725  {
2726  count++;
2727  if (count > MAX_LOCK_RETRY)
2728  {
2729  ni_log(NI_LOG_ERROR, "Can not put down the lock after 6s");
2731  }
2732  }
2733  }
2734  while (status != 0);
2735 
2736  return NI_RETCODE_SUCCESS;
2737 }
2738 
2739 /*!*****************************************************************************
2740  * \brief unlock a file lock
2741  *
2742  * \param device_type
2743  * \param lock
2744  *
2745  * \return None
2746  *******************************************************************************/
2747 int ni_rsrc_unlock(int device_type, ni_lock_handle_t lock)
2748 {
2749  if (lock == NI_INVALID_LOCK_HANDLE)
2750  {
2751  return NI_RETCODE_FAILURE;
2752  }
2753 
2754  int count = 0;
2755  ni_lock_handle_t status = NI_INVALID_LOCK_HANDLE;
2756  do
2757  {
2758  if (count >= 1)
2759  {
2761  }
2762 #ifdef _WIN32
2763  if (ReleaseMutex(lock))
2764  {
2765  status = (ni_lock_handle_t)(0);
2766  }
2767 #else
2768  status = lockf(lock, F_ULOCK, 0);
2769 #endif
2770  count++;
2771  if (count > MAX_LOCK_RETRY)
2772  {
2773  ni_log(NI_LOG_ERROR, "Can not unlock the lock after 6s");
2775  }
2776  } while (status != (ni_lock_handle_t)(0));
2777 
2778 #ifdef _WIN32
2779  CloseHandle(lock);
2780 #else
2781  close(lock);
2782 #endif //_WIN32 defined
2783  return NI_RETCODE_SUCCESS;
2784 }
2785 
2786 /*!*****************************************************************************
2787 * \brief check if device FW revision is compatible with SW API
2788 *
2789 * \param fw_rev
2790 *
2791 * \return 1 for full compatibility, 2 for partial, 0 for none
2792 *******************************************************************************/
2793 int ni_rsrc_is_fw_compat(uint8_t fw_rev[8])
2794 {
2795  if ((uint8_t)fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX] ==
2799  } else {
2800  return 0;
2801  }
2802 }
2803 
2804 static int int_cmp(const void *a, const void *b)
2805 {
2806  const int *ia = (const int *)a;
2807  const int *ib = (const int *)b;
2808  return (*ia == *ib) ? 0 : ((*ia > *ib) ? 1 : -1);
2809  /* integer comparison: returns negative if b > a , 0 if a == b,and positive if a > b */
2810 }
2811 
2812 static int ni_hw_device_info_quadra_threshold_param_t_compare(const void *pl, const void *pr)
2813 {
2816  if(!ll || !rr)
2817  {
2818  return 0;
2819  }
2820  return (ll->device_type == rr->device_type) ? 0 : ((ll->device_type > rr->device_type) ? 1 : -1);
2821 }
2822 
2823 
2824 /*!*********************************************************************************************
2825 * \brief Calculate decoder load used in ni_check_hw_info()
2826 * The computing method is from firmware for 770.
2827 * This function is used for ni_check_hw_info()
2828 *
2829 * \param decoder_param
2830 *
2831 * \return task decoder load
2832 ***********************************************************************************************/
2833 static int check_hw_info_decoder_need_load(ni_hw_device_info_quadra_decoder_param_t *decoder_param)
2834 {
2835  int factor_8_10 = 1;
2836  uint32_t resolution = decoder_param->h * decoder_param->w;
2837  if(decoder_param->bit_8_10 == 10)
2838  {
2839  factor_8_10 = 2;
2840  }
2841  return resolution >= 1920*1080 ?
2842  (int)(((uint64_t)(resolution)*(uint64_t)(decoder_param->fps)*(uint64_t)(factor_8_10)*100)/1440/1920/1080) :
2843  (int)((uint64_t)(resolution)*(uint64_t)(decoder_param->fps)*(uint64_t)(factor_8_10)*100/2880/1280/720);
2844 }
2845 
2846 /*!**************************************************************************************
2847 * \brief Calculate encoder load used in ni_check_hw_info()
2848 * The computing method is from firmware->ModelLoadSet
2849 * This function is used for ni_check_hw_info()
2850 *
2851 * \param encoder_param
2852 *
2853 * \return task encoder load
2854 ****************************************************************************************/
2855 static int check_hw_info_encoder_need_load(ni_hw_device_info_quadra_encoder_param_t *encoder_param)
2856 {
2857  double factor = 1.0;
2858  double factor_codec = 1.0;
2859  double factor_rdoq = 1.0;
2860  double factor_rdoLevel = 1.0;
2861  double factor_lookahead = 1.0;
2862  double factor_8_10_bit = 1.0;
2863  double factor_720p = 1.0;
2864 
2865  int resolution = (int)(encoder_param->w * encoder_param->h);
2866 
2867 
2868  if(encoder_param->code_format == 3)//STD_JPGE
2869  {
2870  factor_codec = 0.67;
2871  }
2872  else{
2873  if((encoder_param->code_format == 0 || encoder_param->code_format == 1) &&
2874  encoder_param->ui8enableRdoQuant)//264 or 265
2875  {
2876  factor_rdoq = 1.32;
2877  }
2878 
2879  if((encoder_param->code_format == 1 || encoder_param->code_format ==2) &&
2880  encoder_param->rdoLevel > 1)
2881  {
2882  factor_rdoLevel = (encoder_param->rdoLevel == 2) ? 1.91 : 3.28;
2883  }
2884 
2885  if(encoder_param->lookaheadDepth != 0)
2886  {
2887  factor_lookahead = (double)(encoder_param->lookaheadDepth * 0.0014 + 1.012);
2888  }
2889  }
2890 
2891  if(encoder_param->bit_8_10 == 10)
2892  {
2893  factor_8_10_bit = 2;
2894  }
2895 
2896  factor_720p = 1.125;//consider h and w
2897  factor = factor_codec * factor_8_10_bit * factor_rdoq * factor_rdoLevel
2898  * factor_lookahead * factor_720p;
2899 
2900  //ENC_TOTAL_BIT_VOLUME_1_SEC (3840 * 2160 * 60ULL)
2901  //PERF_MODEL_LOAD_PERCENT = ((ENC_TOTAL_BIT_VOLUME_1_SEC / 100) * ENCODER_MULTICORE_NUM)
2902  //encoedr_need_load = sample_model_load/PERF_MODEL_LOAD_PERCENT
2903  return uint32_t(
2904  ((uint32_t)((uint32_t)factor*encoder_param->fps * resolution)) /
2905  ((3840 * 2160 * 60ULL) / 100 * 4));
2906 }
2907 
2908 /*!*****************************************************************************
2909 * \brief Calculate shared memeory uasge buffer scale
2910 * The computing method is from MemUsageCalculation_SR
2911 * This function is used for ni_check_hw_info()
2912 *
2913 * \param h
2914 * \param w
2915 * \param bit_8_10
2916 * \param rgba
2917 *
2918 * \return task shared memeory uasge buffer scale
2919 ********************************************************************************/
2920 static int check_hw_info_shared_mem_calculate_b_scale(int h,int w,int bit_8_10,int rgba)
2921 {
2922  const int stride = 128;
2923  int estimated_yuv_size = rgba ?
2924  w * h * 4 :
2925  bit_8_10 == 8 ?
2926  ( ((w + stride - 1)/stride)*stride + ((w/2 + stride - 1)/stride)*stride ) * h:
2927  ( ((w * 2 + stride - 1)/stride)*stride + ((w + stride - 1)/stride)*stride ) * h;
2928  const int b_unit = 1601536;//Bin_Unit_Size
2929  int b_scale = (estimated_yuv_size + b_unit -1) / b_unit;
2930  return b_scale;
2931 }
2932 
2933 /*!*****************************************************************************
2934 * \brief Calculate encoder shared memory usage
2935 * The computing method is from MemUsageCalculation_SR
2936 * This function is used for ni_check_hw_info()
2937 *
2938 * \param encoder_param
2939 *
2940 * \return task encoder shared memeory uasge
2941 ********************************************************************************/
2942 static int check_hw_info_encoder_shared_mem_usage(const ni_hw_device_info_quadra_encoder_param_t *encoder_param)
2943 {
2944  // const int p_1080 = 2073600;
2945  // const int p_1440 = 3686400;
2946  // const int p_4k = 8294400;
2947 
2948  if(!encoder_param)
2949  {
2950  return 0;
2951  }
2952 
2953  //cppcheck do not allow this
2954  // const int v32_ofCores = 0;
2955 
2956  // int encoder_shared_mem_usage = 0;
2957 
2958  // int v32_ofCores_calculate = ((v32_ofCores>0)?v32_ofCores:1)-1;
2959  //cppcheck do not allow this
2960 
2961  const int v32_ofCores_calculate = 0;
2962 
2963  int b_counts = (int)(v32_ofCores_calculate +
2964  ((encoder_param->lookaheadDepth > 0) ? encoder_param->lookaheadDepth + 8/2 + v32_ofCores_calculate : 0 )+
2965  8 +
2966  (encoder_param->uploader ? 1 : 0) * 3 +
2967  1) * 1;
2968  int b_scale = check_hw_info_shared_mem_calculate_b_scale(encoder_param->h, encoder_param->w,
2969  encoder_param->bit_8_10, encoder_param->rgba);
2970  return b_scale * b_counts;
2971 
2972 }
2973 
2974 /*!*****************************************************************************
2975 * \brief Calculate decoder shared memory usage
2976 * The computing method is from MemUsageCalculation_SR
2977 * This function is used for ni_check_hw_info()
2978 *
2979 * \param decoder_param
2980 * \param estimated_max_dpb
2981 *
2982 * \return task decoder shared memeory uasge
2983 ********************************************************************************/
2984 static int check_hw_info_decoder_shared_mem_usage(const ni_hw_device_info_quadra_decoder_param_t *decoder_param,int estimated_max_dpb)
2985 {
2986  // const int p_1080 = 2073600;
2987  // const int p_1440 = 3686400;
2988  // const int p_4k = 8294400;
2989 
2990  if(!decoder_param)
2991  {
2992  return 0;
2993  }
2994  const int hw_frame = decoder_param->hw_frame;
2995 
2996  const int v30_xlsx = 0;
2997  int b_counts = 1 * (v30_xlsx +
2998  (hw_frame ? 0 : 1)*3 +
2999  estimated_max_dpb);
3000  int b_scale = check_hw_info_shared_mem_calculate_b_scale(decoder_param->h, decoder_param->w,
3001  decoder_param->bit_8_10, decoder_param->rgba);
3002  return b_scale * b_counts;
3003 }
3004 
3005 /*!*****************************************************************************
3006 * \brief Calculate scaler shared memory usage
3007 * The computing method is from MemUsageCalculation_SR
3008 * This function is used for ni_check_hw_info()
3009 *
3010 * \param scaler_param
3011 * \param estimated_max_dpb
3012 *
3013 * \return task scaler shared memeory uasge
3014 ********************************************************************************/
3015 static int check_hw_info_scaler_shared_mem_usage(const ni_hw_device_info_quadra_scaler_param_t *scaler_param,int estimated_max_dpb)
3016 {
3017  // const int p_1080 = 2073600;
3018  // const int p_1440 = 3686400;
3019  // const int p_4k = 8294400;
3020 
3021 
3022  if(!scaler_param)
3023  {
3024  return 0;
3025  }
3026  // const int hw_frame = 1;
3027  //cppcheck do not allow this
3028 
3029  const int v30_xlsx = 0;
3030  int b_counts = 1 * (v30_xlsx +
3031  0/* (hw_frame ? 0 : 1)*3 */ +
3032  estimated_max_dpb);
3033  int b_scale = check_hw_info_shared_mem_calculate_b_scale(scaler_param->h, scaler_param->w,
3034  scaler_param->bit_8_10, scaler_param->rgba);
3035  return b_scale * b_counts;
3036 }
3037 
3038 
3039 /*!*************************************************************************************************
3040 * \brief Remove unsupported card in ni_check_hw_info() by memroy
3041 * This function is used for ni_check_hw_info()
3042 *
3043 * \param[in] card_remove
3044 * \param[in] ni_card_info
3045 * \param[in] card_num
3046 * \param[in] coder_param
3047 * \param[in] mode mode == 0->decoder, mode == 1->encoder, mode == 2->scaler, mode > 3->all
3048 *
3049 * \return NONE
3050 ****************************************************************************************************/
3051 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)
3052 {
3053  const int total = 2456;//buffer count summary
3054  int task_mem_usage = 0;
3055  int task_mem_precentage = 0;
3056  int i;
3057 
3058  if(!ni_card_info)
3059  {
3060  ni_log(NI_LOG_ERROR, "card_info is NULL mark all cards as removed\n");
3061  for(i = 0; i < card_num; ++i)
3062  {
3063  card_remove[i] = 1;
3064  }
3065  return;
3066  }
3067 
3068  if(mode == 0)
3069  {
3070  task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->decoder_param,16);
3071  }
3072  else if(mode == 1)
3073  {
3074  task_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->encoder_param);
3075  }
3076  else if(mode == 2)
3077  {
3078  task_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->scaler_param,16);
3079  }
3080  else if(mode > 3)
3081  {
3082  int decoder_shared_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->decoder_param,16);
3083  int encoder_shared_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->encoder_param);
3084  int scaler_shared_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->scaler_param,16);
3085  task_mem_usage = decoder_shared_mem_usage + ((encoder_shared_mem_usage > scaler_shared_mem_usage) ?
3086  encoder_shared_mem_usage : scaler_shared_mem_usage);
3087  }
3088  else
3089  {
3090  ni_log(NI_LOG_ERROR, "parameter:mode is out of range\n");
3091  task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->decoder_param,16) +
3092  check_hw_info_encoder_shared_mem_usage(coder_param->encoder_param)+
3093  check_hw_info_scaler_shared_mem_usage(coder_param->scaler_param,16);
3094  }
3095 
3096  task_mem_precentage = 100 * task_mem_usage / total;
3097 
3098  if(task_mem_precentage > 90)
3099  {
3100  //calculate mem usage is an estimated num , maybe too big
3101  task_mem_precentage = 90;
3102  }
3103 
3104  for(i = 0;i<card_num;++i)
3105  {
3106  if(card_remove[i] == 1)
3107  {
3108  continue;
3109  }
3110 
3111  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
3112  {
3113  card_remove[i] = 1;
3114  }
3115  }
3116 
3117 }
3118 
3119 /*!*********************************************************************************************
3120 * \brief Create and alloc a pointer to ni_hw_device_info_quadra_coder_param_t
3121 * This function is used for ni_check_hw_info()
3122 *
3123 * \param[in] mode 0 for decoder,1 for encoder,2 for scaler,3 for AI, >= 4 for hw_mode
3124 *
3125 * \return a pointer to ni_hw_device_info_quadra_coder_param_t on success,NULL for otherwise
3126 ***********************************************************************************************/
3128 {
3129  ni_hw_device_info_quadra_coder_param_t *p_coder_param = NULL;
3131  if(p_coder_param == NULL)
3132  {
3133  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_coder_param\n");
3134  return p_coder_param;
3135  }
3136  memset(p_coder_param,0,sizeof(ni_hw_device_info_quadra_coder_param_t));
3137  p_coder_param->hw_mode = 0;
3138  if(mode == 0)//decoder
3139  {
3141  if(p_coder_param->decoder_param == NULL)
3142  {
3143  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3144  free(p_coder_param);
3145  p_coder_param = NULL;
3146  return p_coder_param;
3147  }
3148  }
3149  else if(mode == 1)//encoder
3150  {
3152  if(p_coder_param->encoder_param == NULL)
3153  {
3154  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3155  free(p_coder_param);
3156  p_coder_param = NULL;
3157  return p_coder_param;
3158  }
3159  }
3160  else if(mode == 2)//scaler
3161  {
3163  if(p_coder_param->scaler_param == NULL)
3164  {
3165  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3166  free(p_coder_param);
3167  p_coder_param = NULL;
3168  return p_coder_param;
3169  }
3170  }
3171  else if(mode == 3)//AI
3172  {
3174  if(p_coder_param->ai_param == NULL)
3175  {
3176  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3177  free(p_coder_param);
3178  p_coder_param = NULL;
3179  return p_coder_param;
3180  }
3181  }
3182  else//hw_mode
3183  {
3185  if(p_coder_param->encoder_param == NULL)
3186  {
3187  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3188  free(p_coder_param);
3189  p_coder_param = NULL;
3190  return p_coder_param;
3191  }
3193  if(p_coder_param->decoder_param == NULL)
3194  {
3195  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3196  free(p_coder_param->encoder_param);
3197  p_coder_param->encoder_param = NULL;
3198  free(p_coder_param);
3199  p_coder_param = NULL;
3200  return p_coder_param;
3201  }
3203  if(p_coder_param->scaler_param == NULL)
3204  {
3205  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3206  free(p_coder_param->encoder_param);
3207  p_coder_param->encoder_param = NULL;
3208  free(p_coder_param->decoder_param);
3209  p_coder_param->decoder_param = NULL;
3210  free(p_coder_param);
3211  p_coder_param = NULL;
3212  return p_coder_param;
3213  }
3215  if(p_coder_param->ai_param == NULL)
3216  {
3217  ni_log(NI_LOG_ERROR, "Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3218  free(p_coder_param->encoder_param);
3219  p_coder_param->encoder_param = NULL;
3220  free(p_coder_param->decoder_param);
3221  p_coder_param->decoder_param = NULL;
3222  free(p_coder_param->scaler_param);
3223  p_coder_param->scaler_param = NULL;
3224  free(p_coder_param);
3225  p_coder_param = NULL;
3226  return p_coder_param;
3227  }
3228  p_coder_param->hw_mode = 1;
3229  }
3230  if(p_coder_param->encoder_param)
3231  {
3232  p_coder_param->encoder_param->bit_8_10 = 8;
3233  p_coder_param->encoder_param->code_format = 0;
3234  p_coder_param->encoder_param->fps = 30;
3235  p_coder_param->encoder_param->lookaheadDepth = 0;
3236  p_coder_param->encoder_param->rdoLevel = 0;
3237  p_coder_param->encoder_param->w = 1920;
3238  p_coder_param->encoder_param->h = 1080;
3239  p_coder_param->encoder_param->ui8enableRdoQuant = 0;
3240  p_coder_param->encoder_param->uploader = 0;
3241  p_coder_param->encoder_param->rgba = 0;
3242  }
3243  if(p_coder_param->decoder_param)
3244  {
3245  p_coder_param->decoder_param->w = 1920;
3246  p_coder_param->decoder_param->h = 1080;
3247  p_coder_param->decoder_param->bit_8_10 = 8;
3248  p_coder_param->decoder_param->fps = 30;
3249  p_coder_param->decoder_param->rgba = 0;
3250  p_coder_param->decoder_param->hw_frame = 1;
3251  }
3252  if(p_coder_param->scaler_param)
3253  {
3254  p_coder_param->scaler_param->h = 1920;
3255  p_coder_param->scaler_param->w = 1080;
3256  p_coder_param->scaler_param->bit_8_10 = 8;
3257  p_coder_param->scaler_param->rgba = 0;
3258  }
3259  if(p_coder_param->ai_param)
3260  {
3261  p_coder_param->ai_param->h = 1920;
3262  p_coder_param->ai_param->w = 1080;
3263  p_coder_param->ai_param->bit_8_10 = 8;
3264  p_coder_param->ai_param->rgba = 0;
3265  }
3266  return p_coder_param;
3267 }
3268 
3269 
3270 /*!*********************************************************************************************
3271 * \brief Free resource in p_hw_device_info_quadra_coder_param
3272 * This function is used for ni_check_hw_info()
3273 *
3274 * \param[in] device_type_num
3275 *
3276 * \param[in] avaliable_card_num
3277 *
3278 * \return a pointer to ni_hw_device_info_quadra_t on success,NULL for otherwise
3279 ***********************************************************************************************/
3281 {
3282  if(p_hw_device_info_quadra_coder_param == NULL)
3283  {
3284  return;
3285  }
3286  if(p_hw_device_info_quadra_coder_param->encoder_param)
3287  {
3288  free(p_hw_device_info_quadra_coder_param->encoder_param);
3289  p_hw_device_info_quadra_coder_param->encoder_param = NULL;
3290  }
3291  if(p_hw_device_info_quadra_coder_param->decoder_param)
3292  {
3293  free(p_hw_device_info_quadra_coder_param->decoder_param);
3294  p_hw_device_info_quadra_coder_param->decoder_param = NULL;
3295  }
3296  if(p_hw_device_info_quadra_coder_param->scaler_param)
3297  {
3298  free(p_hw_device_info_quadra_coder_param->scaler_param);
3299  p_hw_device_info_quadra_coder_param->scaler_param = NULL;
3300  }
3301  if(p_hw_device_info_quadra_coder_param->ai_param)
3302  {
3303  free(p_hw_device_info_quadra_coder_param->ai_param);
3304  p_hw_device_info_quadra_coder_param->ai_param = NULL;
3305  }
3306  free(p_hw_device_info_quadra_coder_param);
3307  return;
3308 }
3309 
3310 /*!*********************************************************************************************
3311 * \brief Create a ni_hw_device_info_quadra_t
3312 * This function is used for ni_check_hw_info()
3313 *
3314 * \param[in] device_type_num
3315 * \param[in] avaliable_card_num
3316 *
3317 * \return a pointer to ni_hw_device_info_quadra_t on success,NULL for otherwise
3318 ***********************************************************************************************/
3319 ni_hw_device_info_quadra_t *ni_hw_device_info_alloc_quadra(int device_type_num,int avaliable_card_num)
3320 {
3321  int i;
3323  if(!p_hw_device_info)
3324  {
3325  ni_log(NI_LOG_ERROR,"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t\n");
3326  goto p_hw_device_info_end;
3327  }
3328 
3329  p_hw_device_info->device_type_num = device_type_num;
3330  p_hw_device_info->device_type = (ni_device_type_t *)malloc(sizeof(ni_device_type_t) * device_type_num);
3331  if(!p_hw_device_info->device_type)
3332  {
3333  ni_log(NI_LOG_ERROR,"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t->device_type\n");
3334  goto device_type_end;
3335  }
3336 
3337  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);
3338  if(p_hw_device_info->card_info == NULL)
3339  {
3340  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for p_hw_device_info_quadra_t->card_info\n", NI_ERRNO);
3341  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3342  //unlock_and_return
3343  goto card_info_end;
3344  }
3345  memset(p_hw_device_info->card_info, 0, sizeof(ni_card_info_quadra_t*) * p_hw_device_info->device_type_num);
3346 
3347  p_hw_device_info->available_card_num = avaliable_card_num;
3348  p_hw_device_info->consider_mem = 0;
3349  for(i = 0; i < p_hw_device_info->device_type_num; ++i)
3350  {
3351  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);
3352  if(p_hw_device_info->card_info[i] == NULL)
3353  {
3354  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for p_hw_device_info_quadra_t->card_info\n", NI_ERRNO);
3355  goto card_info_i_end;
3356  }
3357  }
3358 
3359  return p_hw_device_info;
3360 
3361 card_info_i_end:
3362  for(i = 0; i < p_hw_device_info->device_type_num; ++i)
3363  {
3364  if(p_hw_device_info->card_info[i])
3365  {
3366  free(p_hw_device_info->card_info[i]);
3367  p_hw_device_info->card_info[i] = NULL;
3368  }
3369  }
3370  free(p_hw_device_info->card_info);
3371  p_hw_device_info->card_info = NULL;
3372 card_info_end:
3373  free(p_hw_device_info->device_type);
3374  p_hw_device_info->device_type = NULL;
3375 device_type_end:
3376  free(p_hw_device_info);
3377  p_hw_device_info = NULL;
3378 p_hw_device_info_end:
3379  return NULL;
3380 }
3381 
3382 /*!*********************************************************************************************
3383 * \brief Free resource in a pointer of ni_hw_device_info_quadra_t
3384 * This function is used for ni_check_hw_info()
3385 *
3386 * \param[in] p_hw_device_info Poiner to a ni_hw_device_info_quadra_t struct
3387 *
3388 * \return None
3389 ***********************************************************************************************/
3391 {
3392  int i;
3393  if(!p_hw_device_info)
3394  {
3395  return;
3396  }
3397  free(p_hw_device_info->device_type);
3398  p_hw_device_info->device_type = NULL;
3399  for(i = 0; i < p_hw_device_info->device_type_num; ++i)
3400  {
3401  free(p_hw_device_info->card_info[i]);
3402  p_hw_device_info->card_info[i] = NULL;
3403  }
3404  free(p_hw_device_info->card_info);
3405  p_hw_device_info->card_info = NULL;
3406  free(p_hw_device_info);
3407  return;
3408 }
3409 
3410 int ni_check_hw_info(ni_hw_device_info_quadra_t **pointer_to_p_hw_device_info,
3411  int task_mode,
3412  ni_hw_device_info_quadra_threshold_param_t *hw_info_threshold_param,
3413  ni_device_type_t preferential_device_type,
3415  int hw_mode,
3416  int consider_mem)
3417 {
3418  //order of ni_hw_device_info_quadra_threshold_param_t *hw_info_threshold_param, order
3419  //order of ni_device_type_t all_need_device_type
3420  //ni_device_type_t preferential_device_type, in the first place
3421  //other order of device_type ni_device_type_t adjust to the order of all_need_device_type
3422  //int hw_info_param_num = hw_mode ? 2 : 1;adjust to 3
3423  int should_match_rev = 1;
3424  int module_count = 1;
3425  ni_device_context_t *dev_ctxt_arr = NULL;
3426  int32_t *module_id_arr = NULL;
3427  // int32_t best_load_module_id = -1;
3428  ni_device_pool_t *p_device_pool = NULL;
3429  ni_device_queue_t *coders = NULL;
3430  ni_device_context_t *p_device_context = NULL;
3431  ni_session_context_t xCtxt = { 0 };
3432  int *card_remove = NULL;//cards which are not satisfied threshold
3433  // uint64_t reserved_memory = 0;
3434  // int needed_memory = 0;
3435  uint64_t decoder_need_load = 0;
3436  uint64_t encoder_need_load = 0;
3437  int retval = 0;//1 for success , 0 for failure
3438  int ret = 0;
3439  int hw_info_param_num = hw_mode ? 4 : 1;
3440  int device_type_num = 1;
3441  const int all_device_type_num = 4;
3442 
3443  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
3444  /*note: preference device type will be moved to all_need_device_type[0],
3445  * 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
3446  */
3447 
3448  int i = 0;
3449  bool b_valid = false;
3450 
3451 
3452  // int *mem_usage = NULL;
3453 
3454  ni_hw_device_info_quadra_t *p_hw_device_info = NULL;
3455 
3456  //check hw_info_param
3457  if(!pointer_to_p_hw_device_info)
3458  {
3459  ni_log(NI_LOG_ERROR, "Error: Invalid input params: pointer_to_p_hw_device_info is NULL.\n");
3460  return retval;
3461  }
3462 
3463  if(*pointer_to_p_hw_device_info)
3464  {
3465  p_hw_device_info = *pointer_to_p_hw_device_info;
3466  b_valid = true;
3467  }
3468 
3469  // Check input parameters here
3470  if(!coder_param){
3471  if(b_valid)
3472  {
3473  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3474  }
3475  ni_log(NI_LOG_ERROR, "Error: Invalid input params: coder_param is NULL.\n");
3476  return retval;
3477  }else if(hw_mode && hw_mode != coder_param->hw_mode)
3478  {
3479  ni_log(NI_LOG_ERROR, "Error: Invalid input params: hw_mode = %d, coder_param->hw_mode = %d\n",
3480  hw_mode,coder_param->hw_mode);
3481  return retval;
3482  }else if(!hw_mode)
3483  {
3484  if(preferential_device_type == NI_DEVICE_TYPE_ENCODER && coder_param->encoder_param == NULL)
3485  {
3486  ni_log(NI_LOG_ERROR, "Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_ENCODER but coder_param->encoder_param == NULL\n");
3487  return retval;
3488  }
3489  if(preferential_device_type == NI_DEVICE_TYPE_DECODER && coder_param->decoder_param == NULL)
3490  {
3491  ni_log(NI_LOG_ERROR, "Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_DECODER but coder_param->decoder_param == NULL\n");
3492  return retval;
3493  }
3494  if(preferential_device_type == NI_DEVICE_TYPE_SCALER && coder_param->scaler_param == NULL)
3495  {
3496  ni_log(NI_LOG_ERROR, "Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_SCALER but coder_param->scaler_param == NULL\n");
3497  return retval;
3498  }
3499  if(preferential_device_type == NI_DEVICE_TYPE_AI && coder_param->ai_param == NULL)
3500  {
3501  ni_log(NI_LOG_ERROR, "Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_AI but coder_param->ai_param == NULL\n");
3502  return retval;
3503  }
3504  }
3505 
3506 
3507  if((task_mode != 0 && task_mode != 1) ||
3508  (preferential_device_type != NI_DEVICE_TYPE_DECODER && preferential_device_type != NI_DEVICE_TYPE_ENCODER &&
3509  preferential_device_type != NI_DEVICE_TYPE_SCALER && preferential_device_type != NI_DEVICE_TYPE_AI))//scaler
3510  {
3511  if(b_valid)
3512  {
3513  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3514  }
3515  ni_log(NI_LOG_ERROR, "Error: Invalid input params: realtime %d device_type %d\n",
3516  task_mode, preferential_device_type);
3517  return retval;
3518  }
3519 
3520  if(!hw_info_threshold_param)
3521  {
3522  if(b_valid)
3523  {
3524  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3525  }
3526  ni_log(NI_LOG_ERROR, "Error: Invalid input params: hw_info_threshold_param is NULL.\n");
3527  return retval;
3528  }else{
3529  for(i = 0;i < hw_info_param_num; ++i)
3530  {
3531  if(hw_info_threshold_param[i].load_threshold < 0||//check this
3532  hw_info_threshold_param[i].load_threshold > 100 ||
3533  hw_info_threshold_param[i].task_num_threshold < 0 ||
3534  hw_info_threshold_param[i].task_num_threshold > NI_MAX_CONTEXTS_PER_HW_INSTANCE||
3535  ( hw_info_threshold_param[i].device_type != NI_DEVICE_TYPE_DECODER &&
3536  hw_info_threshold_param[i].device_type != NI_DEVICE_TYPE_ENCODER &&
3537  hw_info_threshold_param[i].device_type != NI_DEVICE_TYPE_SCALER &&
3538  hw_info_threshold_param[i].device_type != NI_DEVICE_TYPE_AI))
3539  {
3540  if(b_valid)
3541  {
3542  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3543  }
3544  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",
3545  (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);
3546  return retval;
3547  }
3548  }
3549  }
3550  // all parameters have been checked
3551 
3552  /* For load calculations and checking, restrict FPS to be within 5 - 120 */
3553  if(coder_param->encoder_param)
3554  {
3555  if(coder_param->encoder_param->fps > 120)
3556  {
3557  coder_param->encoder_param->fps = 120;
3558  }
3559  if(coder_param->encoder_param->fps < 5)
3560  {
3561  coder_param->encoder_param->fps = 5;
3562  }
3563  }
3564  if(coder_param->decoder_param)
3565  {
3566  if(coder_param->decoder_param->fps > 120)
3567  {
3568  coder_param->decoder_param->fps = 120;
3569  }
3570  if(coder_param->decoder_param->fps < 5)
3571  {
3572  coder_param->decoder_param->fps = 5;
3573  }
3574  }
3575 
3576  //ni_rsrc_init() is unsafe in multi process/thread ,do not call ni_rsrc_init() here
3577 
3578  if (NI_RETCODE_SUCCESS != (ret = ni_rsrc_refresh(should_match_rev)))
3579  {
3580  ni_log(NI_LOG_ERROR, "Error: resource pool records might be corrupted!!\n");
3581  if(b_valid)
3582  {
3583  p_hw_device_info->err_code = ret;
3584  }
3585  return retval;
3586  }
3587 
3588  p_device_pool = ni_rsrc_get_device_pool();
3589  if (!p_device_pool)
3590  {
3591  ni_log(NI_LOG_ERROR, "Error:Can not get device pool info ..\n");
3592  if(b_valid)
3593  {
3594  p_hw_device_info->err_code = NI_RETCODE_ERROR_GET_DEVICE_POOL;
3595  }
3596  return retval;
3597  }
3598 
3599 #ifdef _WIN32
3600  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval)
3601  {
3602  ni_log(NI_LOG_ERROR, "ERROR: Failed to obtain mutex: %p\n", p_device_pool->lock);
3603  LRETURN;
3604  }
3605 #elif defined(__linux__)
3606  if (lockf(p_device_pool->lock, F_LOCK, 0))
3607  {
3608  ni_log(NI_LOG_ERROR, "Error lockf() failed\n");
3609  if(b_valid)
3610  {
3611  p_hw_device_info->err_code = NI_RETCODE_ERROR_LOCK_DOWN_DEVICE;
3612  }
3613  LRETURN;
3614  }
3615 #endif
3616 
3617  coders = p_device_pool->p_device_queue;
3618  if (!coders)
3619  {
3620  ni_log(NI_LOG_ERROR, "Error pdevice_queue null!!\n");
3621  if(b_valid)
3622  {
3623  p_hw_device_info->err_code = NI_RETCODE_ERROR_GET_DEVICE_POOL;
3624  }
3625  LRETURN;
3626  }
3627 
3629 
3630 
3631  // move preferential_device_type in all_need_device_type to top
3632  for(i = 0; i < all_device_type_num; ++i)
3633  {
3634  if(all_need_device_type[i] == preferential_device_type)
3635  {
3636  ni_device_type_t tmp = all_need_device_type[i];
3637  all_need_device_type[i] = all_need_device_type[0];
3638  all_need_device_type[0] = tmp;
3639  break;
3640  }
3641  //ni_device_type_t is a enum
3642  }
3643  qsort(&all_need_device_type[1], all_device_type_num - 1, sizeof(ni_device_type_t), int_cmp);
3644 
3645  //adjust order of hw_info_threshold_param as all_need_device_type
3646  if(hw_mode)
3647  {
3648  // default device_type_num is 1
3649  device_type_num = 4;//decoder and encoder and scaler and AI
3650  //adjust order of hw_info_threshold_param as all_need_device_type
3651  for(i = 0; i < device_type_num; ++i)
3652  {
3653  if(hw_info_threshold_param[i].device_type == preferential_device_type)
3654  {
3655  ni_hw_device_info_quadra_threshold_param_t tmp = hw_info_threshold_param[i];
3656  hw_info_threshold_param[i] = hw_info_threshold_param[0];
3657  hw_info_threshold_param[0] = tmp;
3658  break;
3659  }
3660  }
3661  qsort(&hw_info_threshold_param[1], device_type_num - 1,
3662  sizeof(ni_hw_device_info_quadra_threshold_param_t), ni_hw_device_info_quadra_threshold_param_t_compare);
3663  }
3664 
3665  if(!(*pointer_to_p_hw_device_info))
3666  {
3667  p_hw_device_info = ni_hw_device_info_alloc_quadra(device_type_num,coders->xcoder_cnt[preferential_device_type]);
3668  if(!p_hw_device_info)
3669  {
3670  ni_log(NI_LOG_ERROR,"ERROR: Failed to allocate memory for p_hw_device_info\n");
3671  LRETURN;
3672  }
3673  *pointer_to_p_hw_device_info = p_hw_device_info;
3674  b_valid = true;
3675  }
3676  else
3677  {
3678  // p_hw_device_info = *pointer_to_p_hw_device_info;
3679  //already set this before
3680 
3681  //if user alloc hw_device_info themself check it
3682  if(!p_hw_device_info->device_type)
3683  {
3684  ni_log(NI_LOG_ERROR,"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->device_type is NULL\n");
3685  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3686  LRETURN;
3687  }
3688  if(!p_hw_device_info->card_info)
3689  {
3690  ni_log(NI_LOG_ERROR,"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->card_info is NULL\n");
3691  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3692  LRETURN;
3693  }
3694  for(i = 0; i < device_type_num; ++i)
3695  {
3696  if(!p_hw_device_info->card_info[i])
3697  {
3698  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);
3699  p_hw_device_info->err_code = NI_RETCODE_PARAM_INVALID_VALUE;
3700  LRETURN;
3701  }
3702  }
3703  }
3704  //p_hw_device_info alloc succeed
3705 
3706  //coders->decoders_cnt == coder->encoders_cnt has checked in the ni_logan_rsrc_refresh
3707  p_hw_device_info->available_card_num = coders->xcoder_cnt[preferential_device_type];
3708  p_hw_device_info->device_type_num = device_type_num;
3709 
3710  for(i = 0; i < p_hw_device_info->device_type_num; ++i)
3711  {
3712  p_hw_device_info->device_type[i] = all_need_device_type[i];
3713  for(int j = 0; j < p_hw_device_info->available_card_num; ++j)
3714  {
3715  p_hw_device_info->card_info[i][j].card_idx = -1;
3716  p_hw_device_info->card_info[i][j].load = -1;
3717  p_hw_device_info->card_info[i][j].model_load = -1;
3718  p_hw_device_info->card_info[i][j].task_num = -1;
3719  p_hw_device_info->card_info[i][j].max_task_num = NI_MAX_CONTEXTS_PER_HW_INSTANCE;
3720  p_hw_device_info->card_info[i][j].shared_mem_usage = -1;
3721  p_hw_device_info->card_info[i][j].firmware_load = -1;
3722  }
3723  }
3724 
3725  p_hw_device_info->card_current_card = -1;
3726  p_hw_device_info->err_code = NI_RETCODE_SUCCESS;
3728 
3729  if(consider_mem)
3730  {
3731  // mem_usage = (int *)malloc(sizeof(int) * (p_hw_device_info->available_card_num));
3732  // if(!mem_usage)
3733  // {
3734  // ni_log(NI_LOG_ERROR,"ERROR: Failed to allocate memory for p_hw_device_info\n");
3735  // p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3736  // LRETURN;
3737  // }
3738  p_hw_device_info->consider_mem = 1;
3739  }
3740  else
3741  {
3742  p_hw_device_info->consider_mem = 0;
3743  }
3744 
3745  if (p_hw_device_info->available_card_num <= 0)
3746  {
3747  LRETURN;
3748  }
3749 
3750  card_remove = (int32_t *)malloc(sizeof(int32_t) * p_hw_device_info->available_card_num);
3751  if (!card_remove)
3752  {
3753  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for card_remove\n", NI_ERRNO);
3754  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3755  LRETURN;
3756  }
3757  memset(card_remove, 0, sizeof(int32_t) * p_hw_device_info->available_card_num);
3758 
3759 
3760  module_count = coders->xcoder_cnt[preferential_device_type];
3761  dev_ctxt_arr = (ni_device_context_t *)malloc(sizeof(ni_device_context_t) * module_count);
3762  if (!dev_ctxt_arr)
3763  {
3764  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for ni_rsrc_detect\n", NI_ERRNO);
3765  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3766  LRETURN;
3767  }
3768  module_id_arr = (int32_t *)malloc(sizeof(int32_t) * module_count);
3769  if (!module_id_arr)
3770  {
3771  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to allocate memory for ni_rsrc_detect\n", NI_ERRNO);
3772  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3773  LRETURN;
3774  }
3775 
3776  //info start
3777  memcpy(module_id_arr, coders->xcoders[preferential_device_type], sizeof(int32_t) * module_count);//copy useful card
3778 
3779  //First module ID in coders->decoders/encoders is of lowest load
3780  // memcpy((void *)&best_load_module_id, module_id_arr, sizeof(int32_t));
3781  qsort(module_id_arr, module_count, sizeof(int32_t), int_cmp);// why?
3782 
3783  // p_hw_device_info->card_current_card = best_load_module_id;
3784 
3785  for(i = 0; i < p_hw_device_info->available_card_num; ++i)
3786  {
3787  for(int j = 0; j < device_type_num; ++j)//need to fix this
3788  {
3789  memset(&xCtxt, 0, sizeof(xCtxt));
3790  p_device_context = ni_rsrc_get_device_context(all_need_device_type[j], module_id_arr[i]);
3791  if(p_device_context)
3792  {
3793  xCtxt.blk_io_handle = ni_device_open(p_device_context->p_device_info->blk_name,
3794  &(xCtxt.max_nvme_io_size));
3795  xCtxt.device_handle = xCtxt.blk_io_handle;
3796  //Check device can be opend
3797  if (NI_INVALID_DEVICE_HANDLE == xCtxt.device_handle)
3798  {
3799  ni_log(NI_LOG_ERROR, "Error open device %s, blk device %s\n",
3800  p_device_context->p_device_info->dev_name,
3801  p_device_context->p_device_info->blk_name);
3802  ni_rsrc_free_device_context(p_device_context);
3803  card_remove[i] = 1;
3804  continue;
3805  }
3806 #ifdef _WIN32
3807  xCtxt.event_handle = ni_create_event();
3808  if (NI_INVALID_EVENT_HANDLE == xCtxt.event_handle)
3809  {
3810  ni_rsrc_free_device_context(p_device_context);
3812  ni_log(NI_LOG_ERROR, "ERROR %d: print_perf() create event\n", NI_ERRNO);
3813  card_remove[i] = 1;
3814  continue;
3815  }
3816 #endif
3817  //Check decode/encode can be queired
3818  xCtxt.hw_id = p_device_context->p_device_info->hw_id;
3819  if (NI_RETCODE_SUCCESS != ni_device_session_query(&xCtxt, all_need_device_type[j]))
3820  {
3822 #ifdef _WIN32
3824 #endif
3825  ni_log(NI_LOG_ERROR, "Error query %s %s %s.%d\n",
3826  (all_need_device_type[j] == NI_DEVICE_TYPE_DECODER) ? "decoder" :
3827  (all_need_device_type[j] == NI_DEVICE_TYPE_ENCODER) ? "encoder" :
3828  (all_need_device_type[j] == NI_DEVICE_TYPE_SCALER) ? "scaler " : "AIs ",
3829  p_device_context->p_device_info->dev_name,
3830  p_device_context->p_device_info->blk_name,
3831  p_device_context->p_device_info->hw_id);
3832  ni_rsrc_free_device_context(p_device_context);
3833  card_remove[i] = 1;
3834  continue;
3835  }
3837 #ifdef _WIN32
3839 #endif
3840  if (0 == xCtxt.load_query.total_contexts)
3841  {
3842  xCtxt.load_query.current_load = 0;
3843  }
3844 
3845  p_hw_device_info->card_info[j][i].card_idx = p_device_context->p_device_info->module_id;
3846 
3847  //use model_load in card remove for encoder just like before
3848 #ifdef XCODER_311
3849  p_hw_device_info->card_info[j][i].load = xCtxt.load_query.current_load; //monitor changes this
3850 
3851 #else
3852  p_hw_device_info->card_info[j][i].load =
3854 #endif
3855  // module_load_user_can_not_see[j][i] = xCtxt.load_query.fw_model_load;
3856  p_hw_device_info->card_info[j][i].model_load = xCtxt.load_query.fw_model_load;
3857 
3858  p_hw_device_info->card_info[j][i].task_num = xCtxt.load_query.total_contexts;
3859  p_hw_device_info->card_info[j][i].max_task_num = NI_MAX_CONTEXTS_PER_HW_INSTANCE;
3860 
3861  p_hw_device_info->card_info[j][i].firmware_load = xCtxt.load_query.fw_load;
3862  if(consider_mem)
3863  {
3864  // mem_usage[i] = xCtxt.load_query.fw_share_mem_usage;
3865  p_hw_device_info->card_info[j][i].shared_mem_usage = xCtxt.load_query.fw_share_mem_usage;
3866  }
3867  ni_rsrc_free_device_context(p_device_context);
3868  p_device_context = NULL;
3869  }
3870  else
3871  {
3872  ni_log(NI_LOG_ERROR, "ERROR %d: Failed to get device context\n", NI_ERRNO);
3873  p_hw_device_info->err_code = NI_RETCODE_ERROR_MEM_ALOC;
3874  LRETURN;
3875  }
3876  }
3877 
3878  }
3879 
3880  if(coder_param->decoder_param)
3881  {
3882  decoder_need_load = check_hw_info_decoder_need_load(coder_param->decoder_param);
3883  }
3884  if(coder_param->encoder_param)
3885  {
3886  encoder_need_load = check_hw_info_encoder_need_load(coder_param->encoder_param);
3887  }
3888  // if(coder_param->scaler_param)
3889  // {
3890  //cane not estimate scaler load now
3891  // }
3892 
3893  //mark the card removed depends on the load_threshold or task_num_threshold
3894  //in hw_mode ,device_type_num == 4 but only encoder and decoder will be taken into account,we can not estimate scaler load now
3895  //in sw mode ,device_type_num == 1 only preferitial_device_type will be taken into account
3896  for(i = 0; i < p_hw_device_info->available_card_num; ++i)
3897  {
3898  for(int j = 0; j < p_hw_device_info->device_type_num; ++j)
3899  {
3900 #ifdef XCODER_311
3901  ni_log(NI_LOG_DEBUG, "%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3902 #else
3903  ni_log(NI_LOG_INFO, "%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3904 #endif
3905  (p_hw_device_info->device_type[j] == NI_DEVICE_TYPE_DECODER ? "Decoder" :
3906  ((p_hw_device_info->device_type[j] == NI_DEVICE_TYPE_ENCODER) ? "Encoder" :
3907  (p_hw_device_info->device_type[j] == NI_DEVICE_TYPE_SCALER) ? "Scaler " : "AIs ")),
3908  p_hw_device_info->card_info[j][i].card_idx,
3909  p_hw_device_info->card_info[j][i].load,
3910  p_hw_device_info->card_info[j][i].task_num,
3911  p_hw_device_info->card_info[j][i].firmware_load,
3912  p_hw_device_info->card_info[j][i].model_load,
3913  p_hw_device_info->card_info[j][i].shared_mem_usage);
3914 
3915  if(card_remove[i] == 1)
3916  {
3917  continue;//for print
3918  }
3919 
3920  if(all_need_device_type[j] == NI_DEVICE_TYPE_DECODER)
3921  {
3922  if(decoder_need_load + p_hw_device_info->card_info[j][i].model_load >= 100)
3923  {
3924  card_remove[i] = 1;
3925  }
3926  }
3927 
3928  if(all_need_device_type[j] == NI_DEVICE_TYPE_ENCODER)
3929  {
3930  if(encoder_need_load + p_hw_device_info->card_info[j][i].model_load >= 100)
3931  {
3932  card_remove[i] =1;
3933  }
3934  }
3935 
3936  if (task_mode)
3937  {
3938  // replicate legacy behavior for task_mode to use enc model_load in place of enc real load
3939  if(all_need_device_type[i] == NI_DEVICE_TYPE_ENCODER)
3940  {
3941  if (p_hw_device_info->card_info[j][i].model_load > hw_info_threshold_param[j].load_threshold ||
3942  p_hw_device_info->card_info[j][i].task_num + 1 >= hw_info_threshold_param[j].task_num_threshold)
3943  {
3944  card_remove[i] = 1;
3945  }
3946  }
3947  else
3948  {
3949  if (p_hw_device_info->card_info[j][i].load > hw_info_threshold_param[j].load_threshold ||
3950  p_hw_device_info->card_info[j][i].task_num + 1 >= hw_info_threshold_param[j].task_num_threshold)
3951  {
3952  card_remove[i] = 1;
3953  }
3954  }
3955  }
3956  else
3957  {
3958  if (p_hw_device_info->card_info[j][i].task_num > hw_info_threshold_param[j].task_num_threshold)
3959  {
3960  card_remove[i] = 1;
3961  }
3962  }
3963  }
3964  }
3965 
3966  if(consider_mem)
3967  {
3968  if(hw_mode)
3969  {
3970  check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,10);
3971  }
3972  else if(preferential_device_type == 0)
3973  {
3974  check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,0);
3975  }
3976  else if(preferential_device_type == 1)
3977  {
3978  check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,1);
3979  }
3980  else if(preferential_device_type == 2)
3981  {
3982  check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,2);
3983  }
3984  }
3985 
3986  if (task_mode)
3987  {
3988  //select the min_task_num
3989  //p_hw_device_info->card_info[0] is the preferential_device_type
3990  int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
3991  for (i = 0; i < p_hw_device_info->available_card_num; i++)
3992  {
3993  if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
3994  card_remove[i] == 0)
3995  {
3996  min_task_num = p_hw_device_info->card_info[0][i].task_num;
3997  }
3998  }
3999  //select the min load
4000  int min_load = 100;
4001  for (i = 0; i < p_hw_device_info->available_card_num; i++)
4002  {
4003  if (p_hw_device_info->card_info[0][i].load < min_load &&
4004  card_remove[i] == 0 &&
4005  p_hw_device_info->card_info[0][i].task_num == min_task_num)
4006  {
4007  min_load = p_hw_device_info->card_info[0][i].load;
4008  p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4009  }
4010  }
4011  }
4012  else
4013  {
4014  //p_hw_device_info->card_info[0] is the preferential_device_type
4015  //select the min task num
4016  int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
4017  for (i = 0; i < p_hw_device_info->available_card_num; i++)
4018  {
4019  if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
4020  card_remove[i] == 0)
4021  {
4022  p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4023  min_task_num = p_hw_device_info->card_info[0][i].task_num;
4024  }
4025  }
4026  }
4027 
4028  if (p_hw_device_info->card_current_card >= 0)
4029  {
4030  retval = 1; //has the card to use
4031  }
4032 
4033 END:
4034 #ifdef _WIN32
4035  ReleaseMutex((HANDLE)p_device_pool->lock);
4036 
4037 #elif defined(__linux__)
4038  if (lockf(p_device_pool->lock, F_ULOCK,0))
4039  {
4040  ni_log(NI_LOG_ERROR, "Error lockf() failed\n");
4041  if(p_hw_device_info)
4042  {
4043  p_hw_device_info->err_code = NI_RETCODE_ERROR_UNLOCK_DEVICE;
4044  }
4045  retval = 0;
4046  }
4047  ni_rsrc_free_device_pool(p_device_pool);
4048  p_device_context = NULL;
4049 #endif
4050  fflush(stderr);
4051  if (module_id_arr)
4052  {
4053  free(module_id_arr);
4054  module_id_arr = NULL;
4055  }
4056  if (dev_ctxt_arr)
4057  {
4058  free(dev_ctxt_arr);
4059  dev_ctxt_arr = NULL;
4060  }
4061  if (card_remove)
4062  {
4063  free(card_remove);
4064  card_remove = NULL;
4065  }
4066  if(b_valid)
4067  {
4068  if(hw_mode)
4069  {
4070 #ifdef XCODER_311
4071  ni_log(NI_LOG_DEBUG, "In hw_mode select card_current_card %d retval %d\n",
4072 #else
4073  ni_log(NI_LOG_INFO, "In hw_mode select card_current_card %d retval %d\n",
4074 #endif
4075  p_hw_device_info->card_current_card, retval);
4076  }
4077  else
4078  {
4079 #ifdef XCODER_311
4080  ni_log(NI_LOG_DEBUG, "In sw_mode select device_type %s card_current_card %d retval %d\n",
4081 #else
4082  ni_log(NI_LOG_INFO, "In sw_mode select device_type %s card_current_card %d retval %d\n",
4083 #endif
4084  ((preferential_device_type == 0) ? "decode" : (preferential_device_type == 1 ? "encode" : (preferential_device_type == 2 ? "scaler" : "ai "))), p_hw_device_info->card_current_card, retval);
4085  }
4086  }
4087  return retval;
4088 }
4089 
4090 
4091 /*!*****************************************************************************
4092 * \brief Allocate resources for decoding/encoding, based on the provided rule
4093 *
4094 * \param[in] device_type NI_DEVICE_TYPE_DECODER or NI_DEVICE_TYPE_ENCODER
4095 * \param[in] rule allocation rule
4096 * \param[in] codec EN_H264 or EN_H265
4097 * \param[in] width width of video resolution
4098 * \param[in] height height of video resolution
4099 * \param[in] frame_rate video stream frame rate
4100 * \param[out] p_load the p_load that will be generated by this encoding
4101 * task. Returned *only* for encoder for now.
4102 *
4103 * \return pointer to ni_device_context_t if found, NULL otherwise
4104 *
4105 * Note: codec, width, height, fps need to be supplied for NI_DEVICE_TYPE_ENCODER only,
4106 * they are ignored otherwize.
4107 * Note: the returned ni_device_context_t content is not supposed to be used by
4108 * caller directly: should only be passed to API in the subsequent
4109 * calls; also after its use, the context should be released by
4110 * calling ni_rsrc_free_device_context.
4111 *******************************************************************************/
4113  ni_device_type_t device_type,
4114  ni_alloc_rule_t rule,
4115  ni_codec_t codec,
4116  int width, int height,
4117  int frame_rate,
4118  uint64_t *p_load)
4119 {
4120  ni_device_pool_t *p_device_pool = NULL;
4121  ni_device_info_t *p_device_info = NULL;
4122  ni_device_context_t *p_device_context = NULL;
4123  ni_session_context_t p_session_context = {0};
4124  int *coders = NULL;
4125  int i = 0, count = 0, rc = NI_RETCODE_FAILURE;
4126  int guid = -1;
4127  int load = 0;
4128  uint32_t num_sw_instances = 0;
4129  int least_model_load = 0;
4130  uint64_t job_mload = 0;
4131 
4132 
4133  if(device_type != NI_DEVICE_TYPE_DECODER && device_type != NI_DEVICE_TYPE_ENCODER)
4134  {
4135  ni_log2(NULL, NI_LOG_ERROR, "ERROR: Device type %d is not allowed\n", device_type);
4136  return NULL;
4137  }
4140  p_device_pool = ni_rsrc_get_device_pool();
4141 
4142  if (!p_device_pool)
4143  {
4144  ni_log2(NULL, NI_LOG_ERROR, "ERROR: %s() Could not get device pool\n", __func__);
4145  return NULL;
4146  }
4147 
4148  ni_device_session_context_init(&p_session_context);
4149 #ifdef _WIN32
4150  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval) //we got the mutex
4151  {
4152  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %p\n", __func__, p_device_pool->lock);
4153  }
4154 #elif __linux__ || __APPLE__
4155  lockf(p_device_pool->lock, F_LOCK, 0);
4156 #endif
4157 
4158  coders = p_device_pool->p_device_queue->xcoders[device_type];
4159  count = p_device_pool->p_device_queue->xcoder_cnt[device_type];
4160 
4161  for (i = 0; i < count; i++)
4162  {
4164  p_device_context = ni_rsrc_get_device_context(device_type, coders[i]);
4165  if (!p_device_context)
4166  {
4168  "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4169  continue;
4170  }
4171 
4172  // p_first retrieve status from f/w and update storage
4173 
4174  p_session_context.blk_io_handle = ni_device_open(p_device_context->p_device_info->dev_name, &p_session_context.max_nvme_io_size);
4175  p_session_context.device_handle = p_session_context.blk_io_handle;
4176 
4177  if (NI_INVALID_DEVICE_HANDLE == p_session_context.device_handle)
4178  {
4179  ni_log(NI_LOG_ERROR, "ERROR %s() ni_device_open() %s: %s\n",
4180  __func__, p_device_context->p_device_info->dev_name,
4181  strerror(NI_ERRNO));
4182  ni_rsrc_free_device_context(p_device_context);
4183  continue;
4184  }
4185 
4186  p_session_context.hw_id = p_device_context->p_device_info->hw_id;
4187  rc = ni_device_session_query(&p_session_context, device_type);
4188 
4189  ni_device_close(p_session_context.device_handle);
4190 
4191  if (NI_RETCODE_SUCCESS != rc)
4192  {
4193  ni_log(NI_LOG_ERROR, "ERROR: query %s %s.%d\n",
4194  g_device_type_str[device_type],
4195  p_device_context->p_device_info->dev_name,
4196  p_device_context->p_device_info->hw_id);
4197  ni_rsrc_free_device_context(p_device_context);
4198  continue;
4199  }
4200 
4201 #ifdef _WIN32
4202  if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->lock, INFINITE)) // no time-out interval) //we got the mutex
4203  {
4204  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to obtain mutex: %p\n",
4205  __func__, p_device_context->lock);
4206  }
4207 #elif __linux__ || __APPLE__
4208  lockf(p_device_context->lock, F_LOCK, 0);
4209 #endif
4210  ni_rsrc_update_record(p_device_context, &p_session_context);
4211 
4212  p_device_info = p_device_context->p_device_info;
4213  if (i == 0)
4214  {
4215  guid = coders[i];
4216  load = p_device_info->load;
4217  least_model_load = p_device_info->model_load;
4218  num_sw_instances = p_device_info->active_num_inst;
4219  }
4220 
4221  ni_log(NI_LOG_INFO, "Coder [%d]: %d , load: %d (%d), activ_inst: %d , max_inst %d\n",
4222  i, coders[i], p_device_info->load, p_device_info->model_load, p_device_info->active_num_inst,
4223  p_device_info->max_instance_cnt);
4224 
4225  switch (rule)
4226  {
4228  {
4229  if (p_device_info->active_num_inst < num_sw_instances)
4230  {
4231  guid = coders[i];
4232  num_sw_instances = p_device_info->active_num_inst;
4233  }
4234  break;
4235  }
4236 
4237  case EN_ALLOC_LEAST_LOAD:
4238  default:
4239  {
4240  if (NI_DEVICE_TYPE_ENCODER == device_type)
4241  {
4242  if (p_device_info->model_load < least_model_load)
4243  {
4244  guid = coders[i];
4245  least_model_load = p_device_info->model_load;
4246  }
4247  }
4248  else if (p_device_info->load < load)
4249  {
4250  guid = coders[i];
4251  load = p_device_info->load;
4252  }
4253  break;
4254  }
4255  }
4256 
4257 #ifdef _WIN32
4258  ReleaseMutex(p_device_context->lock);
4259 #elif __linux__ || __APPLE__
4260  lockf(p_device_context->lock, F_ULOCK, 0);
4261 #endif
4262  ni_rsrc_free_device_context(p_device_context);
4263  }
4264 
4265  if (guid >= 0)
4266  {
4267  p_device_context = ni_rsrc_get_device_context(device_type, guid);
4268  if (!p_device_context)
4269  {
4271  "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4272  LRETURN;
4273  }
4274 
4275  if (NI_DEVICE_TYPE_ENCODER == device_type)
4276  {
4277  job_mload = width * height * frame_rate;
4278  }
4279  }
4280  else
4281  {
4282  ni_log(NI_LOG_ERROR, "ERROR: %s() cannot find guid\n", __func__);
4283  p_device_context = NULL;
4284  }
4285 
4286 END:
4287 #ifdef _WIN32
4288  ReleaseMutex(p_device_pool->lock);
4289 #elif __linux__ || __APPLE__
4290  lockf(p_device_pool->lock, F_ULOCK, 0);
4291 #endif
4292  ni_device_session_context_clear(&p_session_context);
4293  ni_rsrc_free_device_pool(p_device_pool);
4294 
4295  if (p_load)
4296  {
4297  *p_load = job_mload;
4298  }
4299  return p_device_context;
4300 }
_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:527
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:1168
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:2028
_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:359
_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:2640
_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:2215
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:1725
_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:3280
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:1200
_ni_load_query::total_contexts
uint32_t total_contexts
Definition: ni_device_api.h:1203
_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:358
_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:2671
NI_RETCODE_ERROR_GET_DEVICE_POOL
@ NI_RETCODE_ERROR_GET_DEVICE_POOL
Definition: ni_defs.h:518
_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:1167
ni_device_type_t
ni_device_type_t
Definition: ni_defs.h:353
_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:59
_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:1164
NI_RETCODE_SUCCESS
@ NI_RETCODE_SUCCESS
Definition: ni_defs.h:439
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:365
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:1576
_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:98
_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:1467
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:1212
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:2542
_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:3127
NI_RETCODE_INVALID_PARAM
@ NI_RETCODE_INVALID_PARAM
Definition: ni_defs.h:441
_ni_device_capability::fw_commit_hash
uint8_t fw_commit_hash[41]
Definition: ni_device_api.h:1169
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:313
_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:1480
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:1171
_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:443
ni_retcode_t
ni_retcode_t
Definition: ni_defs.h:437
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:1201
_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:449
_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:248
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:1965
_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:422
_ni_session_context::src_bit_depth
int src_bit_depth
Definition: ni_device_api.h:1494
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:1760
NI_RETCODE_ERROR_UNLOCK_DEVICE
@ NI_RETCODE_ERROR_UNLOCK_DEVICE
Definition: ni_defs.h:521
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:361
_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:4148
_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:2793
_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:1464
_ni_session_context::p_session_config
void * p_session_config
Definition: ni_device_api.h:1475
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:1322
_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:585
_ni_device_queue
Definition: ni_rsrc_api.h:67
_ni_sw_instance_info
Definition: ni_rsrc_api.h:86
ni_rsrc_create_retry_lck
ni_retcode_t ni_rsrc_create_retry_lck()
Definition: ni_rsrc_priv.cpp:517
_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:1612
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:99
ni_rsrc_unlock
int ni_rsrc_unlock(int device_type, ni_lock_handle_t lock)
unlock a file lock
Definition: ni_rsrc_api.cpp:2747
_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:1523
CODERS_SHM_NAME
#define CODERS_SHM_NAME
Definition: ni_rsrc_priv.h:46
_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:11487
_ni_session_context::device_type
uint32_t device_type
Definition: ni_device_api.h:1486
LRETURN
#define LRETURN
Definition: ni_defs.h:335
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:1693
_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:1944
_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:4112
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:1890
_ni_device_capability::fw_build_time
uint8_t fw_build_time[26]
Definition: ni_device_api.h:1170
_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:360
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:4557
EN_CODEC_MAX
@ EN_CODEC_MAX
Definition: ni_rsrc_api.h:55
NI_ERRNO
#define NI_ERRNO
Definition: ni_defs.h:229
_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:1410
NI_MAX_DEVICE_CNT
#define NI_MAX_DEVICE_CNT
Definition: ni_defs.h:235
NI_MAX_DEVICE_NAME_LEN
#define NI_MAX_DEVICE_NAME_LEN
Definition: ni_defs.h:236
_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:80
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:1499
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:2743
_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:1202
_ni_device_capability::fw_rev
uint8_t fw_rev[8]
Definition: ni_device_api.h:1166
_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:1155
_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:1612
_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:58
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:45
_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:1502
_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:336
_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:3410
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:1457
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:1163
_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:362
_ni_session_context::max_nvme_io_size
uint32_t max_nvme_io_size
Definition: ni_device_api.h:1478
NI_RETCODE_FAILURE
@ NI_RETCODE_FAILURE
Definition: ni_defs.h:440
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:1352
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:3319
NI_RETCODE_ERROR_INVALID_HANDLE
@ NI_RETCODE_ERROR_INVALID_HANDLE
Definition: ni_defs.h:523
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:913
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:429
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:2426
_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:3390
_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:1157
_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:446
_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:1811
NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
@ NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
Definition: ni_defs.h:519