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