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