libxcoder  5.5.0
ni_rsrc_priv.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_priv.cpp
24  *
25  * \brief Private definitions used by ni_rsrc_api.cpp for management of
26  * NETINT video processing devices
27  ******************************************************************************/
28 
29 #include <signal.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <errno.h>
35 #include <ctype.h>
36 #include <setjmp.h>
37 
38 #if __linux__ || __APPLE__
39 #ifdef __OPENHARMONY__
40 #include <sys/ipc.h>
41 #include <sys/shm.h>
42 #endif
43 #include <sys/mman.h>
44 #include <sys/stat.h>
45 #include <sys/types.h>
46 #include <fcntl.h>
47 #include <unistd.h>
48 #include <dirent.h>
49 #include <limits.h>
50 #endif
51 
52 #if __APPLE__
53 #include <sys/syslimits.h>
54 #endif
55 
56 #ifdef _ANDROID
57 #include "ni_rsrc_api_android.h"
58 #endif
59 
60 #include "ni_device_api.h"
61 #include "ni_rsrc_api.h"
62 #include "ni_rsrc_priv.h"
63 #include "ni_nvme.h"
64 #include "ni_log.h"
65 #include "ni_util.h"
66 
67 #if __linux__ || __APPLE__
68 #ifndef _ANDROID
69 jmp_buf env;
70 #endif
71 #endif
72 
73 uint32_t g_xcoder_stop_process = 0;
74 
75 /*!******************************************************************************
76  * \brief
77  *
78  * \param
79  *
80  * \return
81  ******************************************************************************/
83  ni_hw_capability_t* p_hw_cap)
84 {
85  int i;
87 
88  if (!p_device_info)
89  {
90  ni_log(NI_LOG_ERROR, "ERROR: %s() p_device_info is null\n", __func__);
91  retval = NI_RETCODE_INVALID_PARAM;
92  LRETURN;
93  }
94 
95  ni_log(NI_LOG_DEBUG, "%s type %d fmt %d\n", __func__, type, fmt);
96 
97  for (i = 0; i < EN_CODEC_MAX; i++)
98  {
99  p_device_info->dev_cap[i].supports_codec = EN_INVALID;
100  }
101 
102  if (NI_DEVICE_TYPE_DECODER == type)
103  {
104  p_device_info->dev_cap[0].supports_codec = EN_H264;
105  p_device_info->dev_cap[0].max_res_width = p_hw_cap->max_video_width;
106  p_device_info->dev_cap[0].max_res_height = p_hw_cap->max_video_height;
107  p_device_info->dev_cap[0].min_res_width = p_hw_cap->min_video_width;
108  p_device_info->dev_cap[0].min_res_height = p_hw_cap->min_video_height;
109 
111  "Baseline, Main, High, High10", (NI_PROFILES_SUPP_STR_LEN-1));
112  ni_strncpy(p_device_info->dev_cap[0].level, NI_LEVELS_SUPP_STR_LEN, "6.2", (NI_LEVELS_SUPP_STR_LEN-1));
113 
114  p_device_info->dev_cap[1].supports_codec = EN_H265;
115  p_device_info->dev_cap[1].max_res_width = p_hw_cap->max_video_width;
116  p_device_info->dev_cap[1].max_res_height = p_hw_cap->max_video_height;
117  p_device_info->dev_cap[1].min_res_width = p_hw_cap->min_video_width;
118  p_device_info->dev_cap[1].min_res_height = p_hw_cap->min_video_height;
119 
120  ni_strncpy(p_device_info->dev_cap[1].profiles_supported, NI_PROFILES_SUPP_STR_LEN, "Main, Main10",
122  ni_strncpy(p_device_info->dev_cap[1].level, NI_LEVELS_SUPP_STR_LEN, "6.2", (NI_LEVELS_SUPP_STR_LEN-1));
123 
124  p_device_info->dev_cap[2].supports_codec = EN_JPEG;
125  p_device_info->dev_cap[2].max_res_width = p_hw_cap->max_video_width;
126  p_device_info->dev_cap[2].max_res_height = p_hw_cap->max_video_height;
128  p_device_info->dev_cap[2].min_res_height =
130 
131  ni_strncpy(p_device_info->dev_cap[2].profiles_supported, NI_PROFILES_SUPP_STR_LEN, "Baseline",
133  ni_strncpy(p_device_info->dev_cap[2].level, NI_LEVELS_SUPP_STR_LEN, "6.2", (NI_LEVELS_SUPP_STR_LEN-1));
134 
135  p_device_info->dev_cap[3].supports_codec = EN_VP9;
136  p_device_info->dev_cap[3].max_res_width = p_hw_cap->max_video_width;
137  p_device_info->dev_cap[3].max_res_height = p_hw_cap->max_video_height;
138  p_device_info->dev_cap[3].min_res_width = p_hw_cap->min_video_width;
139  p_device_info->dev_cap[3].min_res_height = p_hw_cap->min_video_height;
140 
143  ni_strncpy(p_device_info->dev_cap[3].level, NI_LEVELS_SUPP_STR_LEN, "6.2", (NI_LEVELS_SUPP_STR_LEN-1));
144  } else if (NI_DEVICE_TYPE_ENCODER == type)
145  {
146  p_device_info->dev_cap[0].supports_codec = EN_H264;
147  p_device_info->dev_cap[0].max_res_width = p_hw_cap->max_video_width;
148  p_device_info->dev_cap[0].max_res_height = p_hw_cap->max_video_height;
149  p_device_info->dev_cap[0].min_res_width = p_hw_cap->min_video_width;
150  p_device_info->dev_cap[0].min_res_height = p_hw_cap->min_video_height;
151 
153  "Baseline, Main, High, High10", (NI_PROFILES_SUPP_STR_LEN-1));
154  ni_strncpy(p_device_info->dev_cap[0].level, NI_LEVELS_SUPP_STR_LEN, "6.2", (NI_LEVELS_SUPP_STR_LEN-1));
155 
156  p_device_info->dev_cap[1].supports_codec = EN_H265;
157  p_device_info->dev_cap[1].max_res_width = p_hw_cap->max_video_width;
158  p_device_info->dev_cap[1].max_res_height = p_hw_cap->max_video_height;
159  p_device_info->dev_cap[1].min_res_width = p_hw_cap->min_video_width;
160  p_device_info->dev_cap[1].min_res_height = p_hw_cap->min_video_height;
161 
162  ni_strncpy(p_device_info->dev_cap[1].profiles_supported, NI_PROFILES_SUPP_STR_LEN, "Main, Main10",
164  ni_strncpy(p_device_info->dev_cap[1].level, NI_LEVELS_SUPP_STR_LEN, "6.2", (NI_LEVELS_SUPP_STR_LEN-1));
165 
166  p_device_info->dev_cap[2].supports_codec = EN_JPEG;
167  p_device_info->dev_cap[2].max_res_width = p_hw_cap->max_video_width;
168  p_device_info->dev_cap[2].max_res_height = p_hw_cap->max_video_height;
169  p_device_info->dev_cap[2].min_res_width = NI_MIN_WIDTH;
170  p_device_info->dev_cap[2].min_res_height = NI_MIN_HEIGHT;
171 
174  ni_strncpy(p_device_info->dev_cap[2].level, NI_LEVELS_SUPP_STR_LEN, "5.1", (NI_LEVELS_SUPP_STR_LEN-1));
175 
176  p_device_info->dev_cap[3].supports_codec = EN_AV1;
177  p_device_info->dev_cap[3].max_res_width = NI_PARAM_AV1_MAX_WIDTH;
178  p_device_info->dev_cap[3].max_res_height = NI_PARAM_AV1_MAX_HEIGHT;
179  p_device_info->dev_cap[3].min_res_width = p_hw_cap->min_video_width;
180  p_device_info->dev_cap[3].min_res_height = p_hw_cap->min_video_height;
181 
184  ni_strncpy(p_device_info->dev_cap[3].level, NI_LEVELS_SUPP_STR_LEN, "5.1", (NI_LEVELS_SUPP_STR_LEN-1));
185  } else if (NI_DEVICE_TYPE_SCALER == type || NI_DEVICE_TYPE_AI == type)
186  {
187  p_device_info->dev_cap[0].supports_codec =
188  p_device_info->dev_cap[1].supports_codec =
189  p_device_info->dev_cap[2].supports_codec =
190  p_device_info->dev_cap[3].supports_codec = EN_INVALID;
191  }
193 END:
194 
195  return retval;
196 }
197 
198 /*!******************************************************************************
199  * \brief
200  *
201  * \param
202  *
203  * \return
204  *******************************************************************************/
205 int ni_rsrc_strcmp(const void * p_str, const void* p_str1)
206 {
207  const char *l = (const char *)p_str;
208  const char *r = (const char *)p_str1;
209  int vl, vr;
210 
211  while (!isdigit(*l) && (*l) != '\0')
212  {
213  l++;
214  }
215  while (!isdigit(*r) && (*r) != '\0')
216  {
217  r++;
218  }
219  vl = atoi(l);
220  vr = atoi(r);
221  if (vl == vr)
222  {
223  return 0;
224  }
225  else if (vl < vr)
226  {
227  return -1;
228  }
229  else
230  {
231  return 1;
232  }
233 }
234 
235 /*!******************************************************************************
236  * \brief
237  *
238  * \param
239  *
240  * \return
241  *******************************************************************************/
242 void ni_rsrc_get_lock_name(ni_device_type_t device_type, int32_t guid, char* p_name, size_t max_name_len)
243 {
244  char type = g_device_type_chr[GET_XCODER_DEVICE_TYPE(device_type)];
245  if (NULL != p_name)
246  {
247  if (strcmp(CODERS_SHM_NAME, "NI_QUADRA_SHM_CODERS") == 0)
248  {
249  snprintf(p_name, max_name_len, "%s/NI_QUADRA_lck_%c%d", LOCK_DIR, type, guid);
250  }
251  else
252  {
253  snprintf(p_name, max_name_len, "%s/NI_lck_%c%d", LOCK_DIR, type, guid);
254  }
255  }
256 }
257 
258 /*!******************************************************************************
259  * \brief
260  *
261  * \param
262  *
263  * \return
264  *******************************************************************************/
265 void ni_rsrc_get_shm_name(ni_device_type_t device_type, int32_t guid, char* p_name, size_t max_name_len)
266 {
267  char type = g_device_type_chr[GET_XCODER_DEVICE_TYPE(device_type)];
269  if (NULL != p_name)
270  {
271  if (strcmp(CODERS_SHM_NAME, "NI_QUADRA_SHM_CODERS") == 0)
272  {
273  snprintf(p_name, max_name_len, "NI_QUADRA_shm_%c%d", type, guid);
274  }
275  else
276  {
277  snprintf(p_name, max_name_len, "NI_shm_%c%d", type, guid);
278  }
279  }
280 }
281 
282 static void fill_device_info(ni_device_info_t *device_info,
283  const int module_id,
284  const ni_device_handle_t device_handle,
285  const char device_name[NI_MAX_DEVICE_NAME_LEN],
286  const int fw_ver_compat_warning,
287  ni_device_capability_t *device_capability,
288  const ni_device_type_t device_type)
289 {
290  ni_hw_capability_t *hw_capability;
291 
292  hw_capability = &device_capability->xcoder_devices[device_type];
293 
294  ni_strncpy(device_info->dev_name, MAX_CHAR_IN_DEVICE_NAME, device_name, (MAX_CHAR_IN_DEVICE_NAME-1));
295  ni_strncpy(device_info->blk_name, MAX_CHAR_IN_DEVICE_NAME, device_name, (MAX_CHAR_IN_DEVICE_NAME-1));
296  device_info->hw_id = hw_capability->hw_id;
297  device_info->module_id = module_id;
298  device_info->fw_ver_compat_warning = fw_ver_compat_warning;
299 
300  memcpy(device_info->fw_rev,
301  device_capability->fw_rev,
302  sizeof(device_info->fw_rev));
303  memcpy(device_info->fw_branch_name,
304  device_capability->fw_branch_name,
305  sizeof(device_info->fw_branch_name) - 1);
306  memcpy(device_info->fw_commit_time,
307  device_capability->fw_commit_time,
308  sizeof(device_info->fw_commit_time) - 1);
309  memcpy(device_info->fw_commit_hash,
310  device_capability->fw_commit_hash,
311  sizeof(device_info->fw_commit_hash) - 1);
312  memcpy(device_info->fw_build_time,
313  device_capability->fw_build_time,
314  sizeof(device_info->fw_build_time) - 1);
315  memcpy(device_info->fw_build_id,
316  device_capability->fw_build_id,
317  sizeof(device_info->fw_build_id) - 1);
318  memcpy(device_info->serial_number,
319  device_capability->serial_number,
320  sizeof(device_info->serial_number));
321  memcpy(device_info->model_number,
322  device_capability->model_number,
323  sizeof(device_info->model_number));
324 
325  ni_query_fl_fw_versions(device_handle, device_info);
326 
327  device_info->max_fps_4k = hw_capability->max_4k_fps;
328  device_info->max_instance_cnt = hw_capability->max_number_of_contexts;
329  device_info->device_type = device_type;
330 
331  ni_rsrc_fill_device_info(device_info,
332  (ni_codec_t)hw_capability->codec_format,
333  device_type,
334  hw_capability);
335 }
336 
337 static void fill_shared_memory(ni_device_queue_t *device_queue,
338  const int should_match_rev,
339  const int existing_number_of_devices,
340  const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
341 {
342  int i, j, compatible_device_counter;
343 
344  memset(device_queue->xcoder_cnt, 0, sizeof(device_queue->xcoder_cnt));
346  {
347  for (j = 0; j < NI_MAX_DEVICE_CNT; j++)
348  {
349  device_queue->xcoders[i][j] = -1;
350  }
351  }
352 
353  compatible_device_counter = 0;
354  for (i = 0; i < existing_number_of_devices; i++)
355  {
356  if (!add_to_shared_memory(device_names[i],
357  false,
358  should_match_rev,
359  device_queue))
360  {
361  continue;
362  }
363  compatible_device_counter++;
364  if (compatible_device_counter >= NI_MAX_DEVICE_CNT)
365  {
367  "Maximum number of supported and compatible devices "
368  "reached. Ignoring other supported and compatible "
369  "devices.\n");
370  break;
371  }
372  }
373 }
374 
375 bool find_available_guid(ni_device_queue_t *device_queue, int device_type, int *guidn)
376 {
377  /*
378  Create a mask of all 128 guids, mark used by 1 and unused by 0.
379  */
380  int32_t temp_guid;
381  int32_t i, j;
382  uint32_t guid_mask[4] = {0};
383 
384  for (i = 0; i < NI_MAX_DEVICE_CNT; i++)
385  {
386  temp_guid = device_queue->xcoders[device_type][i];
387  if (temp_guid >= 0 && temp_guid < NI_MAX_DEVICE_CNT)
388  {
389  guid_mask[temp_guid / 32] |= (1u << ((uint32_t)temp_guid % 32));
390  }
391  }
392  //from the masks find the first available guidn
393  for (i = 0; i < 4; i++)
394  {
395  for (j = 0; j < 32; j++)
396  {
397  if ((guid_mask[i] & (1u << j)) == 0)
398  {
399  *guidn = (i * 32) + j;
400  return true;
401  }
402  }
403  }
404 
405  return false;
406 }
407 
408 bool add_to_shared_memory(const char device_name[NI_MAX_DEVICE_NAME_LEN],
409  const bool device_open_should_succeed,
410  const int should_match_rev,
411  ni_device_queue_t *device_queue)
412 {
413  int32_t guid;
414  int i, j, fw_compat_cmp;
415  char fw_api_ver_str[5];
416 
417  ni_device_capability_t device_capability = {0};
418  ni_device_handle_t device_handle;
419  ni_device_info_t device_info = {0};
420  bool success = true;
421 
422 #if __linux__
423  int ret_ts;
424 #endif
425 
426  device_handle = ni_device_open2(device_name, NI_DEVICE_READ_ONLY);
427  if (device_handle == NI_INVALID_DEVICE_HANDLE)
428  {
429  if (device_open_should_succeed)
430  {
432  "ERROR: %s(): Failed to add %s\n: Failed ni_device_open2()\n",
433  __FUNCTION__,
434  device_name);
435  return false;
436  }
437  return true;
438  }
439 
440  if (ni_device_capability_query2(device_handle, &device_capability, false) != NI_RETCODE_SUCCESS)
441  {
442  ni_log(NI_LOG_INFO, "Skipping %s init: unable to query capability\n",
443  device_name);
444  LRETURN;
445  }
446  if (!is_supported_xcoder(device_capability.device_is_xcoder))
447  {
448  ni_log(NI_LOG_INFO, "Skipping %s init: model not supported\n", device_name);
449  LRETURN;
450  }
452  &fw_api_ver_str[0]);
453  if (should_match_rev && \
454  ((uint8_t) device_capability.fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX] != \
456  {
458  "Skipping %s init: device FW v%s incompatible with this version of Libxcoder\n",
459  device_name,
460  fw_api_ver_str);
461  LRETURN;
462  }
463  fw_compat_cmp = ni_cmp_fw_api_ver((char*) &device_capability.fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
465 
467  {
468  if (!device_capability.xcoder_cnt[i])
469  {
471  "%s %s disabled...\n",
472  device_name,
474  continue;
475  }
476 
477  j = device_queue->xcoder_cnt[i];
478  guid = j ? device_queue->xcoders[i][j-1] + 1 : 0;
479  if (guid >= NI_MAX_DEVICE_CNT && !find_available_guid(device_queue, i, &guid))
480  {
481  ni_log(NI_LOG_ERROR, "ERROR: %s(): Skipping %s init: number of "
482  "initialized devices exceeds %d\n", __FUNCTION__,
483  device_name, NI_MAX_DEVICE_CNT);
484  success = false;
485  LRETURN;
486  }
487  device_queue->xcoders[i][j] = guid;
488  device_queue->xcoder_cnt[i]++;
489 
490  fill_device_info(&device_info,
491  guid,
492  device_handle,
493  device_name,
494  (should_match_rev && fw_compat_cmp) ? 1 : 0,
495  &device_capability,
496  (ni_device_type_t)i);
497 
498  ni_rsrc_get_one_device_info(&device_info);
499  }
500 
501  if (fw_compat_cmp < 0) {
502  ni_log(NI_LOG_INFO, "Initialized %s with FW API v%s that is older than "
503  "Libxcoder supported FW API version\n", device_name,
504  fw_api_ver_str);
505  } else if (fw_compat_cmp > 0) {
506  ni_log(NI_LOG_INFO, "Initialized %s with FW API v%s that is newer than "
507  "Libxcoder supported FW API version\n", device_name,
508  fw_api_ver_str);
509  } else {
510  ni_log(NI_LOG_INFO, "Initialized %s\n", device_name, fw_api_ver_str);
511  }
512 #if __linux__
513  ret_ts = system("host_ts.sh");
514  if (ret_ts != 0)
515  {
516  printf("Unable to send Host time\n");
517  }
518 #endif
519 
520 END:
521  ni_device_close(device_handle);
522 
523  return success;
524 }
525 
527 {
528 #ifdef _WIN32
529  return NI_RETCODE_SUCCESS;
530 #else
531  size_t i;
532  int retry_shm_fd;
533  for(i = 0; i < sizeof(XCODERS_RETRY_LCK_NAME) / sizeof(XCODERS_RETRY_LCK_NAME[0]); ++i)
534  {
535  retry_shm_fd = open(XCODERS_RETRY_LCK_NAME[i], O_RDWR | O_CREAT | O_CLOEXEC | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
536  if(retry_shm_fd < 0)
537  {
538  if(errno != EEXIST)
539  {
540  char errmsg[NI_ERRNO_LEN] = {0};
542  ni_log(NI_LOG_ERROR, "Failed to create %s ERROR: %s\n", XCODERS_RETRY_LCK_NAME[i], errmsg);
544  }
545  else
546  {
547  ni_log(NI_LOG_DEBUG, "%s already exists\n", XCODERS_RETRY_LCK_NAME[i]);
548  }
549  }
550  else
551  {
552  ni_log(NI_LOG_DEBUG, "Create XCODERS_RETRY_LCK: %s\n", XCODERS_RETRY_LCK_NAME[i]);
553  close(retry_shm_fd);
554  }
555  }
556 
557  return NI_RETCODE_SUCCESS;
558 
559 #endif
560 }
561 
562 #ifdef _WIN32
563 
564 /*!******************************************************************************
565  * \brief
566  *
567  * \param
568  *
569  * \return
570  *******************************************************************************/
572  char ni_devices[][NI_MAX_DEVICE_NAME_LEN],
573  int max_handles
574 )
575 {
576  return ni_nvme_enumerate_devices(ni_devices, max_handles);
577 }
578 
579 /*!******************************************************************************
580  * \brief
581  *
582  * \param
583  *
584  * \return
585  *******************************************************************************/
587 {
588  char shm_name[32] = { 0 };
589  char lck_name[32] = { 0 };
590  DWORD rc = 0;
591  ni_device_info_t * p_coder_info_map = NULL;
592  HANDLE map_file_handle = NULL;
593  ni_lock_handle_t mutex_handle = NULL;
594  SECURITY_DESCRIPTOR security_descriptor = { 0 };
595 
596  if(!p_device_info)
597  {
598  return;
599  }
600 
601  ni_rsrc_get_shm_name(p_device_info->device_type, p_device_info->module_id, shm_name, sizeof(shm_name));
602  ni_rsrc_get_lock_name(p_device_info->device_type, p_device_info->module_id, lck_name, sizeof(lck_name));
603  ni_log(NI_LOG_DEBUG, "%s(): shm_name %s, lck_name %s\n", __func__, shm_name, lck_name);
604 
605  //Create a mutex for protecting the memory area
606  mutex_handle = CreateMutex(NULL, // default security attributes
607  FALSE, // initially owned
608  lck_name); // unnamed mutex
609  if (NULL == mutex_handle)
610  {
611  ni_log(NI_LOG_ERROR, "CreateMutex error: %d\n", NI_ERRNO);
612  LRETURN;
613  }
614 
615  if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
616  {
617  ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_get_device_context() failed to "
618  "obtain mutex: %p\n", mutex_handle);
619  LRETURN;
620  }
621 
622  InitializeSecurityDescriptor(&security_descriptor, SECURITY_DESCRIPTOR_REVISION);
623  //security_descriptor.Control
624 
625  map_file_handle = CreateFileMapping(
626  INVALID_HANDLE_VALUE, // use paging file
627  NULL, // default security
628  PAGE_READWRITE, // read/write access
629  0, // maximum object size (high-order DWORD)
630  sizeof(ni_device_info_t),// maximum object size (low-order DWORD)
631  (LPCSTR)shm_name // name of mapping object
632  );
633 
634  if (NULL == map_file_handle)
635  {
636  rc = NI_ERRNO;
637  ni_log(NI_LOG_ERROR, "ERROR: CreateFileMapping returned (%d) for %s\n",
638  rc, shm_name);
639  LRETURN;
640  }
641  else
642  {
643  rc = NI_ERRNO;
644  if (ERROR_ALREADY_EXISTS == rc)
645  {
646  ni_log(NI_LOG_ERROR, "CreateFileMapping returned existing handle for"
647  " %s\n", shm_name);
648  }
649  else
650  {
651  ni_log(NI_LOG_INFO, "CreateFileMapping created a new mapFile for %s, handle: %p ..\n", shm_name, map_file_handle);
652  }
653  }
654 
655  p_coder_info_map = (ni_device_info_t *) MapViewOfFile(
656  map_file_handle, // handle to map object
657  FILE_MAP_ALL_ACCESS, // read/write permission
658  0,
659  0,
660  sizeof(ni_device_info_t)
661  );
662 
663  if (NULL == p_coder_info_map)
664  {
665  rc = NI_ERRNO;
666  ni_log(NI_LOG_INFO, "Could not map view of file, p_last error (%d).\n", rc);
667  LRETURN;
668  }
669 
670  memcpy(p_coder_info_map, p_device_info, sizeof(ni_device_info_t));
671 
672 END:
673  if (p_coder_info_map)
674  {
675  UnmapViewOfFile(p_coder_info_map);
676  }
677 
678  if (mutex_handle) {
679  ReleaseMutex(mutex_handle);
680  mutex_handle = NULL;
681  }
682 }
683 
684 
685 
686 
687 
688 /*!******************************************************************************
689  * \brief
690  *
691  * \param
692  *
693  * \return
694  *******************************************************************************/
695 void ni_rsrc_update_record(ni_device_context_t* p_device_context, ni_session_context_t* p_session_context)
696 {
697  uint32_t i = 0;
698 
699  if ((!p_device_context) || (!p_session_context))
700  {
701  return;
702  }
703 
704  p_device_context->p_device_info->load = p_session_context->load_query.current_load;
705  p_device_context->p_device_info->active_num_inst = p_session_context->load_query.total_contexts;
706  // Now we get the model load from the FW
707  p_device_context->p_device_info->model_load = p_session_context->load_query.fw_model_load;
708  if ( 0 == p_device_context->p_device_info->active_num_inst )
709  {
710  p_device_context->p_device_info->load = 0;
711  }
712 
713  for (i = 0; i < p_device_context->p_device_info->active_num_inst; i++)
714  {
715  p_device_context->p_device_info->sw_instance[i].id =
716  p_session_context->load_query.context_status[i].context_id;
717  p_device_context->p_device_info->sw_instance[i].status = (ni_sw_instance_status_t)
718  p_session_context->load_query.context_status[i].context_status;
719  p_device_context->p_device_info->sw_instance[i].codec = (ni_codec_t)
720  p_session_context->load_query.context_status[i].codec_format;
721  p_device_context->p_device_info->sw_instance[i].width =
722  p_session_context->load_query.context_status[i].video_width;
723  p_device_context->p_device_info->sw_instance[i].height =
724  p_session_context->load_query.context_status[i].video_height;
725  p_device_context->p_device_info->sw_instance[i].fps =
726  p_session_context->load_query.context_status[i].fps;
727  }
728 }
729 
730 /*!******************************************************************************
731  * \brief Initialize and create all resources required to work with NETINT NVMe
732  * transcoder devices. This is a high level API function which is used
733  * mostly with user application like FFmpeg that relies on those resources.
734  * In case of custom application integration, revised functionality might
735  * be necessary utilizing corresponding API functions.
736  *
737  * \param[in] should_match_rev 0: transcoder firmware revision matching the
738  * library's version is NOT required for placing
739  * the transcoder into resource pool; 1: otherwise
740  * timeout_seconds 0: No timeout amount, loop until init success
741  * or fail; else: timeout will fail init once reached
742  *
743  * \return
744  * NI_RETCODE_SUCCESS on success
745  * NI_RETCODE_FAILURE on failure
746  *
747  *******************************************************************************/
748 int ni_rsrc_init_priv(const int should_match_rev,
749  const int existing_number_of_devices,
750  const char existing_device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
751 {
752  DWORD rc = 0;
753  HANDLE lock = NULL;
754  HANDLE map_file_handle = NULL;
755  ni_device_queue_t* p_device_queue = NULL;
756  map_file_handle = CreateFileMapping(
757  INVALID_HANDLE_VALUE, // use paging file
758  NULL, // default security
759  PAGE_READWRITE, // read/write access
760  0, // maximum object size (high-order DWORD)
761  sizeof(ni_device_queue_t),// maximum object size (low-order DWORD)
762  CODERS_SHM_NAME // name of mapping object
763  );
764 
765  if (NULL == map_file_handle)
766  {
767  rc = NI_ERRNO;
768  ni_log(NI_LOG_ERROR, "ERROR: CreateFileMapping returned: %d\n", rc);
769  return NI_RETCODE_FAILURE;
770  }
771  else
772  {
773  rc = NI_ERRNO;
774  if(ERROR_ALREADY_EXISTS == rc)
775  {
776  ni_log(NI_LOG_INFO, "NETINT resources have been initialized already, exiting ..\n");
777  CloseHandle(map_file_handle);
778  return NI_RETCODE_SUCCESS;
779  }
780  else
781  {
782  ni_log(NI_LOG_INFO, "NETINT resources not initialized, starting initialization ..\n");
783  }
784  }
785 
786  p_device_queue = (ni_device_queue_t*)MapViewOfFile(
787  map_file_handle, // handle to map object
788  FILE_MAP_ALL_ACCESS, // read/write permission
789  0,
790  0,
791  sizeof(ni_device_queue_t)
792  );
793 
794  if (NULL == p_device_queue)
795  {
796  ni_log(NI_LOG_ERROR, "Could not map view of file, p_last error (%d).\n",
797  NI_ERRNO);
798  CloseHandle(map_file_handle);
799  return NI_RETCODE_FAILURE;
800  }
801 
802  lock = CreateMutex(NULL, FALSE, CODERS_LCK_NAME);
803  if (NULL == lock)
804  {
805  ni_log(NI_LOG_ERROR, "Init CreateMutex %s failed: %d\n", CODERS_LCK_NAME,
806  NI_ERRNO);
807  UnmapViewOfFile(p_device_queue);
808  CloseHandle(map_file_handle);
809  return NI_RETCODE_FAILURE;
810  }
811 
812  if (WAIT_ABANDONED == WaitForSingleObject(lock, INFINITE))
813  {
814  ni_log(NI_LOG_ERROR, "ERROR %d: failed to obtain mutex: %p\n",
815  NI_ERRNO, lock);
816  ReleaseMutex(lock);
817  UnmapViewOfFile(p_device_queue);
818  CloseHandle(map_file_handle);
819  return NI_RETCODE_FAILURE;
820  }
821 
822  fill_shared_memory(p_device_queue,
823  should_match_rev,
824  existing_number_of_devices,
825  existing_device_names);
826 
827  UnmapViewOfFile(p_device_queue);
828  ReleaseMutex(lock);
829  return NI_RETCODE_SUCCESS;
830 }
831 
832 #elif __linux__ || __APPLE__
833 
837 static bool check_correctness_count(const ni_device_queue_t *existing_device_queue,
838  const int should_match_rev,
839  const int existing_number_of_devices,
840  const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
841 {
842  int i, j, k;
843 
844  ni_device_capability_t device_capability;
845  ni_device_handle_t device_handle;
846  ni_device_queue_t device_queue;
847 
848  memset(device_queue.xcoder_cnt, 0, sizeof(device_queue.xcoder_cnt));
849 
850  for (i = 0; i < existing_number_of_devices; i++)
851  {
852  device_handle = ni_device_open2(device_names[i], NI_DEVICE_READ_ONLY);
853  if (device_handle == NI_INVALID_DEVICE_HANDLE)
854  {
855  continue;
856  }
857 
858  memset(&device_capability, 0, sizeof(ni_device_capability_t));
859  if (ni_device_capability_query2(device_handle, &device_capability, false) != NI_RETCODE_SUCCESS || \
860  !is_supported_xcoder(device_capability.device_is_xcoder) ||
861  (should_match_rev && \
862  ((uint8_t) device_capability.fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX] != \
864  {
865  goto NEXT;
866  }
867 
869  {
870  //Don't count if not in queue.
871  if (existing_device_queue->xcoders[j][i] == -1 && device_capability.xcoder_cnt[j] != 0)
872  {
873  //If not in queue then it shouldn't be in any device module.
875  {
876  if (existing_device_queue->xcoders[k][i] != -1)
877  {
879  "ERROR: %s(): Discovered device %s is not in queue for module %s but is in %s\n",
880  __func__,
881  device_names[i],
883  ni_device_close(device_handle);
884  return false;
885  }
886  }
887  continue;
888  }
889  device_queue.xcoder_cnt[j] += device_capability.xcoder_cnt[j];
890  }
891 NEXT:
892  ni_device_close(device_handle);
893  }
894 
896  {
897  if (device_queue.xcoder_cnt[i] == existing_device_queue->xcoder_cnt[i])
898  {
899  continue;
900  }
902  "WARNING: %s(): Discovered %u %s, expected %u\n",
903  __func__,
904  device_queue.xcoder_cnt[i],
906  existing_device_queue->xcoder_cnt[i]);
907  return false;
908  }
909 
910  return true;
911 }
912 
913 static bool check_device_queue(const ni_device_queue_t *existing_device_queue,
914  const int existing_number_of_devices,
915  const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
916 {
917  int32_t module_id;
918  int i, j;
919 
920  ni_device_context_t *device_context;
921 
922  for (i = 0; i < existing_number_of_devices; i++)
923  {
925  {
926  module_id = existing_device_queue->xcoders[j][i];
927  if (module_id == -1)
928  {
929  break;
930  }
931  device_context = ni_rsrc_get_device_context((ni_device_type_t)j,
932  module_id);
933  if (!device_context)
934  {
936  "WARNING: %s(): Missing device context for %s %s\n",
937  __func__,
938  device_names[i],
940  return false;
941  }
942  if (strcmp(device_context->p_device_info->dev_cap[3].additional_info, "Set") != 0)
943  {
944  ni_log(NI_LOG_ERROR, "ERROR %s() device info not populated %s\n", __func__, device_context->p_device_info->dev_cap[3].additional_info);
945  return false;
946  }
947  ni_rsrc_free_device_context(device_context);
948  }
949  }
950 
951  return true;
952 }
953 
954 #ifndef _ANDROID
955 static void sigbus_handler(int signal)
956 {
957  siglongjmp(env, 1);
958 }
959 
960 static void setup_signal_handler(struct sigaction *p, const int signum)
961 {
962  struct sigaction c;
963 
964  memset(&c, 0, sizeof(struct sigaction));
965  if (sigemptyset(&c.sa_mask) == -1)
966  {
968  "ERROR: %s(): Could not initialize signal set: %d\n",
969  __func__,
970  NI_ERRNO);
971  exit(EXIT_FAILURE);
972  }
973  c.sa_handler = sigbus_handler;
974 
975  if (sigaction(signum, NULL, p) == -1)
976  {
978  "ERROR: %s(): Could not save previous signal handler: %d\n",
979  __func__,
980  NI_ERRNO);
981  exit(EXIT_FAILURE);
982  }
983 
984  if (sigaction(signum, &c, NULL) == -1)
985  {
987  "ERROR: %s(): Could not register signal handler: %d\n",
988  __func__,
989  NI_ERRNO);
990  exit(EXIT_FAILURE);
991  }
992 }
993 #endif
994 
995 static bool check_correctness(const ni_device_queue_t *existing_device_queue,
996  const int should_match_rev,
997  const int existing_number_of_devices,
998  const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
999 {
1000  bool result = false;
1001 #ifndef _ANDROID
1002  const int signum = SIGBUS;
1003  struct sigaction p;
1004 
1005  setup_signal_handler(&p, signum);
1006 
1007  if (sigsetjmp(env, 1))
1008  {
1009  LRETURN;
1010  }
1011 #endif
1012 
1013  if (!check_correctness_count(existing_device_queue,
1014  should_match_rev,
1015  existing_number_of_devices,
1016  device_names))
1017  {
1018  LRETURN;
1019  }
1020 
1021  if (!check_device_queue(existing_device_queue,
1022  existing_number_of_devices,
1023  device_names))
1024  {
1025  LRETURN;
1026  }
1027 
1028  result = true;
1029  ni_log(NI_LOG_INFO, "%s ok\n", CODERS_SHM_NAME);
1030 
1031 end:
1032 #ifndef _ANDROID
1033  if (sigaction(signum, &p, NULL) == -1)
1034  {
1036  "ERROR: %s(): Could not restore previous signal handler: %d\n",
1037  __func__,
1038  NI_ERRNO);
1039  exit(EXIT_FAILURE);
1040  }
1041 #endif
1042  return result;
1043 }
1044 
1045 int ni_rsrc_init_priv(const int should_match_rev,
1046  const int existing_number_of_devices,
1047  const char existing_device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN],
1048  int limit_depth)
1049 {
1050  int return_value = 0;
1051  int lck_fd = -1;
1052  int shm_fd = -1;
1053  ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1054  int flags = O_CREAT | O_RDWR | O_CLOEXEC;
1055  mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1056  ni_device_queue_t *p_device_queue = NULL;
1057 
1058  if ((ni_rsrc_try_get_shm_lock(CODERS_LCK_NAME, flags, mode, &lck_fd) < 0) ||
1059  (ni_rsrc_open_shm(CODERS_SHM_NAME, sizeof(ni_device_queue_t), &state, &shm_fd) < 0)) {
1060  return_value = 1;
1061  LRETURN;
1062  }
1063 
1064  if ((ni_rsrc_mmap_shm(CODERS_SHM_NAME,
1065  shm_fd,
1066  sizeof(ni_device_queue_t),
1067  (void **)&p_device_queue)) < 0) {
1068  ni_log(NI_LOG_ERROR, "%s(): Failed to ni_rsrc_mmap_shm\n", __func__);
1069  return_value = 1;
1070  LRETURN;
1071  }
1072 
1073  //share momery exist
1074  if (NI_RSRC_SHM_IS_EXISTED == state) {
1075  if (check_correctness(p_device_queue,
1076  should_match_rev,
1077  existing_number_of_devices,
1078  existing_device_names))
1079  {
1080  LRETURN;
1081  }
1082 
1083  ni_rsrc_munmap_shm((void *)p_device_queue, sizeof(ni_device_queue_t));
1084  ni_log(NI_LOG_DEBUG, "in %s do munmap for %s, shm_flag is O_RDWR\n", __func__, CODERS_SHM_NAME);
1085 
1086  if (lockf(lck_fd, F_ULOCK, 0) < 0) {
1087  ni_log(NI_LOG_ERROR, "%s(): Failed to unlock lck_fd for %s\n", __func__, CODERS_SHM_NAME);
1088  }
1089 
1090  close(lck_fd);
1091 
1092 #ifndef __OPENHARMONY__
1093  close(shm_fd);
1094 #endif
1095  ni_rsrc_remove_all_shm();
1096 
1097  if (limit_depth <= 0)
1098  {
1099  return 1;
1100  }
1101  return ni_rsrc_init_priv(should_match_rev,
1102  existing_number_of_devices,
1103  existing_device_names,
1104  limit_depth - 1);
1105  }
1106 
1107  fill_shared_memory(p_device_queue,
1108  should_match_rev,
1109  existing_number_of_devices,
1110  existing_device_names);
1111 
1112 end:
1113  if (p_device_queue && p_device_queue != MAP_FAILED) {
1114  ni_rsrc_munmap_shm((void *)p_device_queue, sizeof(ni_device_queue_t));
1115  p_device_queue = NULL;
1116  ni_log(NI_LOG_DEBUG, "in %s do munmap for %s\n", __func__, CODERS_SHM_NAME);
1117  }
1118 
1119  if (lck_fd != -1) {
1120  if (lockf(lck_fd, F_ULOCK, 0) < 0) {
1121  ni_log(NI_LOG_ERROR, "Will exit from %s(), but failed to unlock lck_fd for %s\n", __func__, CODERS_SHM_NAME);
1122  }
1123 
1124  close(lck_fd);
1125  }
1126 
1127 #ifndef __OPENHARMONY__
1128  if (shm_fd >= 0) {
1129  close(shm_fd);
1130  }
1131 #endif
1132 
1133  return return_value;
1134 }
1135 
1136 /*!******************************************************************************
1137  * \brief
1138  *
1139  * \param
1140  *
1141  * \return
1142  *******************************************************************************/
1143 void ni_rsrc_get_one_device_info (ni_device_info_t * p_device_info)
1144 {
1145  int32_t shm_fd = -1;
1146  ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1147  int32_t lock = -1;
1148  int flags = O_CREAT | O_RDWR | O_CLOEXEC;
1149  mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1150  char shm_name[32] = { 0 };
1151  char lck_name[32] = { 0 };
1152  ni_device_info_t * p_coder_info_dst = NULL;
1153 
1154  if(! p_device_info) {
1155  return;
1156  }
1157 
1158  ni_rsrc_get_shm_name(p_device_info->device_type, p_device_info->module_id, shm_name, sizeof(shm_name));
1159  ni_rsrc_get_lock_name(p_device_info->device_type, p_device_info->module_id, lck_name, sizeof(lck_name));
1160 
1161  ni_log(NI_LOG_DEBUG, "%s(): shm_name %s, lck_name %s\n", __func__, shm_name, lck_name);
1162 
1163  if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, (int *)&lock) < 0) {
1164  ni_log(NI_LOG_ERROR, "%s: Failed to get lock\n", __func__);
1165  return ;
1166  }
1167 
1168  if (ni_rsrc_open_shm(shm_name,
1169  sizeof(ni_device_info_t),
1170  &state,
1171  (int *)&shm_fd) < 0) {
1172  ni_log(NI_LOG_ERROR, "%s: Failed to ni_rsrc_open_shm\n", __func__);
1173  LRETURN;
1174  }
1175 
1176  if ((ni_rsrc_mmap_shm(shm_name,
1177  (int)shm_fd,
1178  sizeof(ni_device_info_t),
1179  (void **)&p_coder_info_dst)) < 0) {
1180  ni_log(NI_LOG_ERROR, "%s(): Failed to ni_rsrc_mmap_shm\n", __func__);
1181  LRETURN;
1182  }
1183 
1184  memcpy(p_coder_info_dst, p_device_info, sizeof(ni_device_info_t));
1185 
1186 #ifndef __OPENHARMONY__
1187  if (msync((void*)p_coder_info_dst, sizeof(ni_device_info_t), MS_SYNC | MS_INVALIDATE)) {
1188  char errmsg[NI_ERRNO_LEN] = {0};
1189  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1190  ni_log(NI_LOG_ERROR, "ERROR %s() msync() p_coder_info_dst: %s\n",
1191  __func__, errmsg);
1192  } else {
1193  ni_log(NI_LOG_DEBUG, "%s(): written out\n", __func__);
1194  }
1195 #endif
1196 
1197 END:
1198  if (p_coder_info_dst && p_coder_info_dst != MAP_FAILED) {
1199  ni_rsrc_munmap_shm((void *)p_coder_info_dst, sizeof(ni_device_info_t));
1200  p_coder_info_dst = NULL;
1201  ni_log(NI_LOG_DEBUG, "in %s do munmap for %s\n", __func__, shm_name);
1202  }
1203 
1204 #ifndef __OPENHARMONY__
1205  if (shm_fd >= 0) {
1206  close(shm_fd);
1207  }
1208 #endif
1209 
1210  if (lockf(lock, F_ULOCK, 0) < 0) {
1211  ni_log(NI_LOG_ERROR, "Will exit from %s(), but failed to unlock lck_fd for %s\n", __func__, shm_name);
1212  }
1213 
1214  if (lock >= 0) {
1215  close(lock);
1216  }
1217 }
1218 
1219 /*!******************************************************************************
1220  * \brief
1221  *
1222  * \param
1223  *
1224  * \return
1225  *******************************************************************************/
1226 void ni_rsrc_update_record(ni_device_context_t *p_device_context, ni_session_context_t *p_session_context)
1227 {
1228  uint32_t j;
1229 
1230  if ((!p_device_context) || (!p_session_context))
1231  {
1232  return;
1233  }
1234 
1235  p_device_context->p_device_info->load = p_session_context->load_query.current_load;
1236  p_device_context->p_device_info->active_num_inst = p_session_context->load_query.total_contexts;
1237  // Now we get the model load from the FW
1238  p_device_context->p_device_info->model_load = p_session_context->load_query.fw_model_load;
1239  if (0 == p_device_context->p_device_info->active_num_inst)
1240  {
1241  p_device_context->p_device_info->load = 0;
1242  }
1243  for (j = 0; j < p_device_context->p_device_info->active_num_inst; j++)
1244  {
1245  p_device_context->p_device_info->sw_instance[j].id =
1246  p_session_context->load_query.context_status[j].context_id;
1247  p_device_context->p_device_info->sw_instance[j].status = (ni_sw_instance_status_t)
1248  p_session_context->load_query.context_status[j]
1249  .context_status;
1250  p_device_context->p_device_info->sw_instance[j].codec = (ni_codec_t)
1251  p_session_context->load_query.context_status[j]
1252  .codec_format;
1253  p_device_context->p_device_info->sw_instance[j].width =
1254  p_session_context->load_query.context_status[j].video_width;
1255  p_device_context->p_device_info->sw_instance[j].height =
1256  p_session_context->load_query.context_status[j].video_height;
1257  p_device_context->p_device_info->sw_instance[j].fps =
1258  p_session_context->load_query.context_status[j].fps;
1259  }
1260  if (msync((void *)p_device_context->p_device_info, sizeof(ni_device_info_t), MS_SYNC | MS_INVALIDATE))
1261  {
1262  char errmsg[NI_ERRNO_LEN] = {0};
1263  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1264  ni_log(NI_LOG_ERROR, "ERROR %s() msync() p_device_context->"
1265  "p_device_info: %s\n", __func__, errmsg);
1266  }
1267 }
1268 
1269 
1270 /*!******************************************************************************
1271  * \brief get PCIe address information from device name
1272  *
1273  * \param[in] char *device_name e.g. /dev/nvme0n1.
1274  * \param[out] char *pcie e.g. 0000:0a:00.0. Should be at least 13 bytes including null terminator
1275  * \param[out] char *domain, optional. Should be at least 5 bytes including null terminator
1276  * \param[out] char *slot, optional. Should be at least 3 bytes including null terminator
1277  * \param[out] char *dev, optional. Should be at least 3 bytes including null terminator
1278  * \param[out] char *func, optional. Should be at least 2 bytes including null terminator
1279  *
1280  * \return void
1281  * *******************************************************************************/
1282 void get_dev_pcie_addr(char *device_name,
1283  char *pcie,
1284  char *domain, char *slot, char *dev, char *func)
1285 {
1286 #ifndef __linux__
1287  return;
1288 #else
1289  int i=0;
1290  char *ptr = NULL;
1291  // path to nvme drive
1292  char path[PATH_MAX];
1293  int ret;
1294 
1295  if(!device_name || !strstr(device_name, "/dev/nvme") || !pcie)
1296  {
1297  return ;
1298  }
1299 
1300  // we need to skip '/dev/' in the device name
1301  char *start = device_name + 5;
1302 
1303  // construct the path to /sys/block
1304  snprintf(path, sizeof(path), "/sys/block/%s", start);
1305  ni_log2(NULL, NI_LOG_DEBUG,"path:%s\n", path);
1306 
1307  // read the target of the symbolic link
1308  char target[PATH_MAX];
1309  //e.g.: ../devices/pci0000:00/0000:00:03.1/0000:09:00.0/nvme/nvme0/nvme0n1
1310  ssize_t len = readlink(path, target, sizeof(target) - 1);
1311  if (len == -1) {
1312  perror("readlink");
1313  return;
1314  }
1315  target[len] = '\0'; // set the null-terminating character
1316  ni_log2(NULL, NI_LOG_DEBUG,"target:%s\n", target);
1317 
1318  // and find domain and slot from it
1319  char *saveptr = NULL;
1320  ptr = ni_strtok(target, "/", &saveptr);
1321  pcie[4] = pcie[7] = ':';
1322  pcie[10] = '.';
1323  //last pcie info is for the device
1324  while(ptr != NULL) {
1325  ni_log2(NULL, NI_LOG_DEBUG, "===%d ptr:%s\n", ++i, ptr);
1326  if (strlen(ptr) == 12)//e.g.: 0000:09:00.0
1327  {
1328  ret = sscanf(ptr, "%4c:%2c:%2c.%1c", pcie, pcie+5,pcie+8,pcie+11);
1329  if (ret != 4)
1330  {
1331  char errmsg[NI_ERRNO_LEN] = {0};
1332  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1333  ni_log2(NULL, NI_LOG_DEBUG, "\tsscanf error %d errno %d %s\n", ret, errno, errmsg);
1334  }
1335  }
1336  ni_log2(NULL, NI_LOG_DEBUG, "=====\n");
1337  ptr = ni_strtok(NULL, "/", &saveptr);
1338  }
1339  pcie[12] = '\0';
1340  ni_log2(NULL, NI_LOG_DEBUG, "PCIE:%s\n", pcie);
1341  if (!domain || !slot || !dev || !func)
1342  {
1343  goto end;
1344  }
1345  domain[4] = slot[2] = dev[2] = func[1] = '\0';
1346  sscanf(pcie, "%4[^:]:%2[^:]:%2[^.].%1s", domain, slot, dev, func);
1347  ni_log2(NULL, NI_LOG_DEBUG, "\t%d: Domain: %s, Slot: %s, Device: %s, Function: %s\n", i, domain, slot, dev, func);
1348 end:
1349  return;
1350 #endif
1351 }
1352 
1353 /*!******************************************************************************
1354  * \brief try to get lock for specified shared memory
1355  *
1356  * \param[in] const char *lck_name, specified lock name for shared memory
1357  * \param[in] int flags, open lock with specified flags
1358  * \param[in] const mode_t mode, open lock with specified mode
1359  * \param[out] int *lck_fd, Pointer to opened file handle for lock
1360  *
1361  * \return On success
1362  * NI_RETCODE_SUCCESS
1363  * On failure
1364  * NI_RETCODE_INVALID_PARAM
1365  * NI_RETCODE_FAILURE
1366  *******************************************************************************/
1367 ni_retcode_t ni_rsrc_try_get_shm_lock(const char *lck_name,
1368  int flags,
1369  const mode_t mode,
1370  int *lck_fd)
1371 {
1372  int lock = -1;
1373 
1374  if (!lck_name || !lck_fd) {
1375  ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1376  return NI_RETCODE_INVALID_PARAM;
1377  }
1378 
1379 #ifdef _ANDROID
1380  if (0 != access(LOCK_DIR, F_OK)) {
1381  if (0 != mkdir(LOCK_DIR, S_IRWXU | S_IRWXG | S_IRWXO)) {
1382  ni_log(NI_LOG_ERROR, "ERROR: Could not mkdir : %s directory", LOCK_DIR);
1383  return NI_RETCODE_FAILURE;
1384  }
1385  }
1386 #endif
1387 
1388  char errmsg[NI_ERRNO_LEN] = {0};
1389  lock = open(lck_name, flags, mode);
1390  if (lock < 0) {
1391  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1392  ni_log(NI_LOG_ERROR, "ERROR: %s() open() %s fail: %s\n",
1393  __func__, lck_name, errmsg);
1394  return NI_RETCODE_FAILURE;
1395  }
1396 
1397  int retry_cnt = 0;
1398  //use non blocking F_TLOCK in case broken instance has indefinitely locked it
1399  while (lockf(lock, F_TLOCK, 0) != 0)
1400  {
1401  retry_cnt++;
1402  ni_usleep(LOCK_WAIT); //10ms
1403  if (retry_cnt >= 900) //10s
1404  {
1405  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1406  ni_log(NI_LOG_ERROR, "ERROR %s() lockf() %s fail: %s\n", __func__, lck_name, errmsg);
1407  ni_log(NI_LOG_ERROR, "ERROR %s() If persists, stop traffic and run rm /dev/shm/NI_*\n", __func__);
1408  close(lock);
1409  return NI_RETCODE_FAILURE;
1410  }
1411  }
1412 
1413  *lck_fd = lock;
1414 
1415  return NI_RETCODE_SUCCESS;
1416 }
1417 
1418 #if defined(__OPENHARMONY__)
1419 static ni_retcode_t openharmony_open_shm(const char *shm_name,
1420  int shm_size,
1421  ni_rsrc_shm_state *state,
1422  int *shm_fd)
1423 {
1424  int shm_id = -1;
1425  int flag = IPC_CREAT | IPC_EXCL;
1426  char shm_path[PATH_MAX];
1427 
1428  if (!shm_name || !shm_fd) {
1429  ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1430  return NI_RETCODE_INVALID_PARAM;
1431  }
1432 
1433  memset(shm_path, 0, PATH_MAX);
1434  snprintf(shm_path, PATH_MAX, "%s/%s", LOCK_DIR, shm_name);
1435 
1436  char errmsg[NI_ERRNO_LEN] = {0};
1437  //If file not exist, create the file for ftok
1438  if (0 != access(shm_path, F_OK)) {
1439  int fd = open(shm_path, O_RDWR | O_CREAT | O_CLOEXEC,
1440  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1441  if (fd < 0) {
1442  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1443  ni_log(NI_LOG_ERROR, "ERROR: %s() open() %s fail: %s\n", __func__, shm_name, errmsg);
1444  return NI_RETCODE_FAILURE;
1445  }
1446 
1447  close(fd);
1448  }
1449 
1450  //create unique key for share memory
1451  key_t key = ftok(shm_path, PROJ_ID);
1452  if (key == -1) {
1453  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1454  ni_log(NI_LOG_ERROR, "ERROR: %s() ftok() fail: %s\n", __func__, errmsg);
1455  return NI_RETCODE_FAILURE;
1456  }
1457 
1458  *state = NI_RSRC_SHM_IS_CREATED;
1459 
1460  //create share memory
1461  mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1462  shm_id = shmget(key, shm_size, mode | flag);
1463  if (shm_id < 0) {
1464  if (EEXIST == NI_ERRNO) {
1465  *state = NI_RSRC_SHM_IS_EXISTED;
1466  flag = IPC_CREAT;
1467  shm_id = shmget(key, shm_size, mode | flag);
1468  }
1469 
1470  if (shm_id < 0) {
1471  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1472  ni_log(NI_LOG_ERROR, "ERROR: %s() shmget() fail: %s\n", __func__, errmsg);
1473  return NI_RETCODE_FAILURE;
1474  }
1475  }
1476  *shm_fd = shm_id;
1477 
1478  return NI_RETCODE_SUCCESS;
1479 }
1480 
1481 static ni_retcode_t openharmony_remove_shm(const char *shm_name,
1482  int shm_size)
1483 {
1484  int shm_id = -1;
1485  char shm_path[PATH_MAX];
1486 
1487  if (!shm_name) {
1488  ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1489  return NI_RETCODE_INVALID_PARAM;
1490  }
1491 
1492  memset(shm_path, 0, PATH_MAX);
1493  snprintf(shm_path, PATH_MAX, "%s/%s", LOCK_DIR, shm_name);
1494 
1495  //If file not exist, exit directly
1496  if (0 != access(shm_path, F_OK)) {
1497  return NI_RETCODE_SUCCESS;
1498  }
1499 
1500  char errmsg[NI_ERRNO_LEN] = {0};
1501  //create unique key for share memory
1502  key_t key = ftok(shm_path, PROJ_ID);
1503  if (key == -1) {
1504  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1505  ni_log(NI_LOG_ERROR, "ERROR: %s() ftok() fail: %s\n", __func__, errmsg);
1506  return NI_RETCODE_FAILURE;
1507  }
1508 
1509  //create share memory
1510  mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1511  shm_id = shmget(key, shm_size, mode);
1512  if (shm_id < 0) {
1513  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1514  ni_log(NI_LOG_ERROR, "ERROR: %s() shmget() fail: %s\n", __func__, errmsg);
1515  return NI_RETCODE_FAILURE;
1516  }
1517 
1518  shmctl(shm_id, IPC_RMID, nullptr);
1519 
1520  return NI_RETCODE_SUCCESS;
1521 }
1522 
1523 #elif defined(_ANDROID)
1524 static ni_retcode_t android_open_shm(const char *shm_name,
1525  int shm_size,
1526  ni_rsrc_shm_state *state,
1527  int *shm_fd)
1528 {
1529  int shm_fd_tmp = -1;
1530 
1531  if (!shm_name || !shm_fd) {
1532  ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1533  return NI_RETCODE_INVALID_PARAM;
1534  }
1535 
1536  int ret = ni_rsrc_android_init();
1537  if (ret < 0) {
1538  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to get android service\n", __func__);
1539  return NI_RETCODE_FAILURE;
1540  }
1541 
1542  *state = NI_RSRC_SHM_IS_CREATED;
1543 
1544  string param = shm_name;
1545  Return<void> retvalue =
1546  service->GetAppFlag(param, [&](int32_t ret, hidl_handle handle) {
1547  if (ret > 0) {
1548  *state = NI_RSRC_SHM_IS_EXISTED;
1549  shm_fd_tmp = dup(handle->data[0]);
1550  } else {
1551  ni_log(NI_LOG_ERROR, "ERROR: failed to get shm_fd when call GetAppFlag\n");
1552  }
1553  });
1554 
1555  if (!retvalue.isOk()) {
1556  ni_log(NI_LOG_ERROR, "ERROR: %s() maybe something is wrong with Android service\n");
1557  return NI_RETCODE_FAILURE;
1558  }
1559 
1560  if (shm_fd_tmp < 0) {
1561  int fd = ashmem_create_region(shm_name, shm_size);
1562  if (fd >= 0) {
1563  native_handle_t *native_handle = native_handle_create(1, 0);
1564  if (!native_handle) {
1565  close(fd);
1566  return NI_RETCODE_FAILURE;
1567  }
1568  native_handle->data[0] = fd;
1569 
1570  hidl_handle handle;
1571  handle.setTo(native_handle, true);
1572  service->SetAppFlag(param, handle);
1573  shm_fd_tmp = dup(fd);
1574  } else {
1575  ni_log(NI_LOG_ERROR, "Could not create ashmem under Android\n");
1576  return NI_RETCODE_FAILURE;
1577  }
1578  }
1579  *shm_fd = shm_fd_tmp;
1580 
1581  return NI_RETCODE_SUCCESS;
1582 }
1583 
1584 static ni_retcode_t android_remove_shm(const char *shm_name,
1585  int shm_size)
1586 {
1587  if (!shm_name) {
1588  ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1589  return NI_RETCODE_INVALID_PARAM;
1590  }
1591 
1592  int ret = ni_rsrc_android_init();
1593  if (ret < 0) {
1594  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to get android service\n", __func__);
1595  return NI_RETCODE_FAILURE;
1596  }
1597 
1598  string param = shm_name;
1599  Return<void> retvalue = service->RemoveAppFlag(param);
1600  if (!retvalue.isOk()) {
1601  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to remove shm\n", __func__);
1602  return NI_RETCODE_FAILURE;
1603  }
1604 
1605  return NI_RETCODE_SUCCESS;
1606 }
1607 
1608 static ni_retcode_t android_remove_all_shm()
1609 {
1610  int ret = ni_rsrc_android_init();
1611  if (ret < 0) {
1612  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to get android service\n", __func__);
1613  return NI_RETCODE_FAILURE;
1614  }
1615 
1616  Return<void> retvalue = service->RemoveAllAppFlags();
1617  if (!retvalue.isOk()) {
1618  ni_log(NI_LOG_ERROR, "ERROR: %s() failed to remove all shm\n", __func__);
1619  return NI_RETCODE_FAILURE;
1620  }
1621 
1622  return NI_RETCODE_SUCCESS;
1623 }
1624 
1625 #else
1626 static ni_retcode_t linux_open_shm(const char *shm_name,
1627  int shm_size,
1628  ni_rsrc_shm_state *state,
1629  int *shm_fd)
1630 {
1631  int shm_fd_tmp = -1;
1632  const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1633  int flag = O_CREAT | O_EXCL | O_RDWR;
1634  bool skip_ftruncate = false;
1635 
1636  if (!shm_name || !shm_fd) {
1637  ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1638  return NI_RETCODE_INVALID_PARAM;
1639  }
1640 
1641  *state = NI_RSRC_SHM_IS_CREATED;
1642 
1643  //create share memory
1644  shm_fd_tmp = shm_open(shm_name, flag, mode);
1645  if (shm_fd_tmp < 0) {
1646  if (EEXIST == NI_ERRNO) {
1647  skip_ftruncate = true;
1648  *state = NI_RSRC_SHM_IS_EXISTED;
1649  flag = O_RDWR;
1650  shm_fd_tmp = shm_open(shm_name, flag, mode);
1651  }
1652 
1653  if (shm_fd_tmp < 0) {
1654  char errmsg[NI_ERRNO_LEN] = {0};
1655  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1656  ni_log(NI_LOG_ERROR, "ERROR: %s() %s shm_open() fail: %s\n",
1657  __func__, shm_name, errmsg);
1658  return NI_RETCODE_FAILURE;
1659  }
1660  }
1661 
1662  //set share memory size
1663  if (!skip_ftruncate && ftruncate(shm_fd_tmp, shm_size) < 0) {
1664  close(shm_fd_tmp);
1665  shm_unlink(shm_name);
1666  return NI_RETCODE_FAILURE;
1667  }
1668 
1669  *shm_fd = shm_fd_tmp;
1670 
1671  return NI_RETCODE_SUCCESS;
1672 }
1673 #endif
1674 
1675 /*!******************************************************************************
1676  * \brief open shared memory for specified shm_name
1677  *
1678  * \param[in] const char *shm_name, specified shared memory name
1679  * \param[in] int shm_size, the size of shared memory
1680  * \param[out] ni_rsrc_shm_state *state, Pointer to the shared memory's state
1681  * if the shared memor isn't created, it will be created at first and
1682  * then open it, param "state" will be set to 0
1683  * if the shared memor has been created yet, only open it,
1684  * param "state" will be set to 1
1685  * \param[out] int *shm_fd, Pointer to opened file handle for shared memory
1686  *
1687  * \return On success
1688  * NI_RETCODE_SUCCESS
1689  * On failure
1690  * NI_RETCODE_INVALID_PARAM
1691  * NI_RETCODE_FAILURE
1692  *******************************************************************************/
1693 ni_retcode_t ni_rsrc_open_shm(const char *shm_name,
1694  int shm_size,
1695  ni_rsrc_shm_state *state,
1696  int *shm_fd)
1697 {
1698 #if defined(__OPENHARMONY__)
1699  return openharmony_open_shm(shm_name, shm_size, state, shm_fd);
1700 #elif defined(_ANDROID)
1701  return android_open_shm(shm_name, shm_size, state, shm_fd);
1702 #else
1703  return linux_open_shm(shm_name, shm_size, state, shm_fd);
1704 #endif
1705 }
1706 
1707 /*!******************************************************************************
1708  * \brief map shared memory to the address space of the calling process
1709  *
1710  * \param[in] const char *shm_name, specified shared memory name
1711  * \param[in] int shm_fd, file handle for shared memory
1712  * \param[in] int shm_size, the size of shared memory
1713  * \param[out] int *shm_addr, pointer to the mapped area
1714  *
1715  * \return On success
1716  * NI_RETCODE_SUCCESS
1717  * On failure
1718  * NI_RETCODE_INVALID_PARAM
1719  * NI_RETCODE_FAILURE
1720  *******************************************************************************/
1721 ni_retcode_t ni_rsrc_mmap_shm(const char *shm_name,
1722  int shm_fd,
1723  int shm_size,
1724  void **shm_addr)
1725 {
1726  if (!shm_name || !shm_addr) {
1727  ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1728  return NI_RETCODE_INVALID_PARAM;
1729  }
1730 
1731  char errmsg[NI_ERRNO_LEN] = {0};
1732 #ifdef __OPENHARMONY__
1733  *shm_addr = shmat(shm_fd, nullptr, 0);
1734  if ((void *)(-1) == *shm_addr) {
1735  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1736  ni_log(NI_LOG_ERROR, "%s(): %s shmat() fail: %s\n", __func__,
1737  shm_name, errmsg);
1738  return NI_RETCODE_FAILURE;
1739  }
1740 #else
1741  *shm_addr = mmap(0, shm_size, PROT_READ | PROT_WRITE,
1742  MAP_SHARED, shm_fd, 0);
1743  if (MAP_FAILED == *shm_addr) {
1744  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1745  ni_log(NI_LOG_ERROR, "%s(): %s mmap() fail: %s\n", __func__,
1746  shm_name, errmsg);
1747  return NI_RETCODE_FAILURE;
1748  }
1749 #endif
1750 
1751  return NI_RETCODE_SUCCESS;
1752 }
1753 
1754 /*!******************************************************************************
1755  * \brief do munmap for shared memory
1756  *
1757  * \param[in] int *shm_addr, pointer to the mapped area
1758  * \param[in] int shm_size, the size of shared memory
1759  *
1760  * \return On success
1761  * NI_RETCODE_SUCCESS
1762  * On failure
1763  * NI_RETCODE_INVALID_PARAM
1764  *******************************************************************************/
1765 ni_retcode_t ni_rsrc_munmap_shm(void *shm_addr,
1766  int shm_size)
1767 {
1768  if (!shm_addr) {
1769  ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1770  return NI_RETCODE_INVALID_PARAM;
1771  }
1772 
1773 #ifdef __OPENHARMONY__
1774  shmdt(shm_addr);
1775 #else
1776  munmap(shm_addr, shm_size);
1777 #endif
1778 
1779  return NI_RETCODE_SUCCESS;
1780 }
1781 
1782 /*!******************************************************************************
1783  * \brief delete shared memory
1784  *
1785  * \param[in] const char *shm_name, specified shared memory name
1786  * \param[in] int shm_size, the size of shared memory
1787  *
1788  * \return On success
1789  * NI_RETCODE_SUCCESS
1790  * On failure
1791  * NI_RETCODE_INVALID_PARAM
1792  * NI_RETCODE_FAILURE
1793  *******************************************************************************/
1794 ni_retcode_t ni_rsrc_remove_shm(const char *shm_name,
1795  int shm_size)
1796 {
1797 #ifdef __OPENHARMONY__
1798  return openharmony_remove_shm(shm_name, shm_size);
1799 #elif defined(_ANDROID)
1800  return android_remove_shm(shm_name, shm_size);
1801 #else
1802  shm_unlink(shm_name);
1803 #endif
1804 
1805  return NI_RETCODE_SUCCESS;
1806 }
1807 
1808 /*!******************************************************************************
1809  * \brief delete all shared memory
1810  *
1811  *
1812  * \return On success
1813  * NI_RETCODE_SUCCESS
1814  * On failure
1815  * NI_RETCODE_INVALID_PARAM
1816  * NI_RETCODE_FAILURE
1817  *******************************************************************************/
1818 ni_retcode_t ni_rsrc_remove_all_shm()
1819 {
1820  DIR *dir;
1821  struct dirent *dirent;
1822  char path_to_remove[PATH_MAX];
1823 
1824  ni_log(NI_LOG_ERROR, "Deleting shared memory files in %s\n", LOCK_DIR);
1825 
1826  char errmsg[NI_ERRNO_LEN] = {0};
1827  dir = opendir(LOCK_DIR);
1828  if (!dir) {
1829  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1830  ni_log(NI_LOG_ERROR, "ERROR: %s(): opendir failed for %s: %s\n",
1831  __func__, LOCK_DIR, errmsg);
1832  return NI_RETCODE_FAILURE;
1833  }
1834 
1835  while ((dirent = readdir(dir)) != NULL) {
1836  if (strncmp(dirent->d_name, "NI_", 3) != 0) {
1837  continue;
1838  }
1839 
1840  snprintf(path_to_remove, PATH_MAX, "%s/%s", LOCK_DIR, dirent->d_name);
1841 
1842 #ifndef _ANDROID
1843  if (strncasecmp(dirent->d_name, "NI_SHM", 6) == 0) {
1844 #ifdef __OPENHARMONY__
1845  openharmony_remove_shm(dirent->d_name, 1); //for created share mem we can ignore size
1846 #else
1847  shm_unlink(dirent->d_name);
1848 #endif
1849  }
1850 #endif
1851 
1852  remove(path_to_remove);
1853  }
1854 
1855 #ifdef _ANDROID
1856  android_remove_all_shm();
1857 #endif
1858 
1859  if (closedir(dir) == -1) {
1860  ni_strerror(errmsg, NI_ERRNO_LEN, NI_ERRNO);
1861  ni_log(NI_LOG_ERROR, "ERROR: %s(): closedir failed for %s: %s\n",
1862  __func__, LOCK_DIR, errmsg);
1863  return NI_RETCODE_FAILURE;
1864  }
1865 
1866  ni_log(NI_LOG_INFO, "Deleted shared memory files in %s\n", LOCK_DIR);
1867 
1868  return NI_RETCODE_SUCCESS;
1869 }
1870 
1871 #endif
_ni_device_info::fw_rev
uint8_t fw_rev[8]
Definition: ni_rsrc_api.h:115
_ni_context_query::codec_format
uint32_t codec_format
Definition: ni_device_api.h:1203
_ni_device_capability::fw_commit_time
uint8_t fw_commit_time[26]
Definition: ni_device_api.h:1180
_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_capability
hardware capability type
Definition: ni_device_api.h:1148
_ni_device_info::dev_cap
ni_device_video_capability_t dev_cap[EN_CODEC_MAX]
Definition: ni_rsrc_api.h:132
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_MIN_RESOLUTION_WIDTH_JPEG
#define NI_MIN_RESOLUTION_WIDTH_JPEG
Definition: ni_device_api.h:86
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....
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_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
LOCK_DIR
#define LOCK_DIR
Definition: ni_rsrc_priv.h:42
_ni_device_info::fw_commit_hash
uint8_t fw_commit_hash[41]
Definition: ni_rsrc_api.h:118
NI_PARAM_AV1_MAX_WIDTH
#define NI_PARAM_AV1_MAX_WIDTH
Definition: ni_device_api.h:148
_ni_device_video_capability::max_res_height
int max_res_height
Definition: ni_rsrc_api.h:78
_ni_device_capability::xcoder_devices
ni_hw_capability_t xcoder_devices[NI_MAX_DEVICES_PER_HW_INSTANCE]
Definition: ni_device_api.h:1173
_ni_device_capability::fw_branch_name
uint8_t fw_branch_name[256]
Definition: ni_device_api.h:1179
_ni_hw_capability::hw_id
uint8_t hw_id
Definition: ni_device_api.h:1150
ni_device_type_t
ni_device_type_t
Definition: ni_defs.h:355
ni_nvme_enumerate_devices
int ni_nvme_enumerate_devices(char ni_devices[][NI_MAX_DEVICE_NAME_LEN], int max_handles)
LOCK_WAIT
#define LOCK_WAIT
Definition: ni_rsrc_priv.h:59
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_sw_instance_status_t
ni_sw_instance_status_t
Definition: ni_rsrc_api.h:61
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_device_video_capability::min_res_width
int min_res_width
Definition: ni_rsrc_api.h:79
_ni_device_capability::xcoder_cnt
uint8_t xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
Definition: ni_device_api.h:1172
_ni_device_info::active_num_inst
uint32_t active_num_inst
Definition: ni_rsrc_api.h:128
EN_H265
@ EN_H265
Definition: ni_rsrc_api.h:51
ni_rsrc_strcmp
int ni_rsrc_strcmp(const void *p_str, const void *p_str1)
Definition: ni_rsrc_priv.cpp:205
ni_rsrc_api.h
Public definitions for managing NETINT video processing devices.
NI_XCODER_REVISION
#define NI_XCODER_REVISION
Definition: ni_defs.h:98
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_capability::max_4k_fps
uint8_t max_4k_fps
Definition: ni_device_api.h:1152
_ni_hw_capability::min_video_height
uint16_t min_video_height
Definition: ni_device_api.h:1158
_ni_sw_instance_info::height
int height
Definition: ni_rsrc_api.h:92
_ni_device_video_capability::additional_info
char additional_info[NI_ADDITIONAL_INFO_STR_LEN]
Definition: ni_rsrc_api.h:83
_ni_sw_instance_info::width
int width
Definition: ni_rsrc_api.h:91
NI_RETCODE_INVALID_PARAM
@ NI_RETCODE_INVALID_PARAM
Definition: ni_defs.h:443
_ni_sw_instance_info::fps
int fps
Definition: ni_rsrc_api.h:93
_ni_device_capability::fw_commit_hash
uint8_t fw_commit_hash[41]
Definition: ni_device_api.h:1181
service
android::sp< INidec > service
_ni_device_info::fw_ver_compat_warning
int fw_ver_compat_warning
Definition: ni_rsrc_api.h:111
EN_H264
@ EN_H264
Definition: ni_rsrc_api.h:50
_ni_device_info::fw_commit_time
uint8_t fw_commit_time[26]
Definition: ni_rsrc_api.h:117
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_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_t
ni_retcode_t
Definition: ni_defs.h:439
_ni_load_query::fw_model_load
uint32_t fw_model_load
Definition: ni_device_api.h:1213
NI_ERRNO_LEN
#define NI_ERRNO_LEN
Definition: ni_log.h:51
ni_log.h
Logging definitions.
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_context_query::fps
uint32_t fps
Definition: ni_device_api.h:1206
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_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
NI_PROFILES_SUPP_STR_LEN
#define NI_PROFILES_SUPP_STR_LEN
Definition: ni_rsrc_api.h:36
ni_rsrc_get_one_device_info
void ni_rsrc_get_one_device_info(ni_device_info_t *p_device_info)
EN_JPEG
@ EN_JPEG
Definition: ni_rsrc_api.h:53
_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_context_query::context_id
uint32_t context_id
Definition: ni_device_api.h:1200
_ni_hw_capability::max_video_height
uint16_t max_video_height
Definition: ni_device_api.h:1156
ni_rsrc_fill_device_info
ni_retcode_t ni_rsrc_fill_device_info(ni_device_info_t *p_device_info, ni_codec_t fmt, ni_device_type_t type, ni_hw_capability_t *p_hw_cap)
Definition: ni_rsrc_priv.cpp:82
NI_MIN_RESOLUTION_HEIGHT_JPEG
#define NI_MIN_RESOLUTION_HEIGHT_JPEG
Definition: ni_device_api.h:87
EN_AV1
@ EN_AV1
Definition: ni_rsrc_api.h:54
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_device_queue
Definition: ni_rsrc_api.h:67
ni_rsrc_create_retry_lck
ni_retcode_t ni_rsrc_create_retry_lck()
Definition: ni_rsrc_priv.cpp:526
_ni_hw_capability::min_video_width
uint16_t min_video_width
Definition: ni_device_api.h:1157
_ni_context_query::context_status
uint32_t context_status
Definition: ni_device_api.h:1201
_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_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_ADDITIONAL_INFO_STR_LEN
#define NI_ADDITIONAL_INFO_STR_LEN
Definition: ni_rsrc_api.h:38
NI_XCODER_REVISION_API_MAJOR_VER_IDX
#define NI_XCODER_REVISION_API_MAJOR_VER_IDX
Definition: ni_defs.h:99
_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
GET_XCODER_DEVICE_TYPE
#define GET_XCODER_DEVICE_TYPE(t)
Definition: ni_defs.h:427
CODERS_SHM_NAME
#define CODERS_SHM_NAME
Definition: ni_rsrc_priv.h:46
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_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
LRETURN
#define LRETURN
Definition: ni_defs.h:337
_ni_sw_instance_info::codec
ni_codec_t codec
Definition: ni_rsrc_api.h:90
_ni_device_info::fw_build_time
uint8_t fw_build_time[26]
Definition: ni_rsrc_api.h:119
NI_LEVELS_SUPP_STR_LEN
#define NI_LEVELS_SUPP_STR_LEN
Definition: ni_rsrc_api.h:37
_ni_device_context
Definition: ni_rsrc_api.h:145
EN_VP9
@ EN_VP9
Definition: ni_rsrc_api.h:52
_ni_device_capability::fw_build_time
uint8_t fw_build_time[26]
Definition: ni_device_api.h:1182
_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
EN_CODEC_MAX
@ EN_CODEC_MAX
Definition: ni_rsrc_api.h:55
NI_ERRNO
#define NI_ERRNO
Definition: ni_defs.h:229
_ni_session_context
Definition: ni_device_api.h:1435
NI_MAX_DEVICE_CNT
#define NI_MAX_DEVICE_CNT
Definition: ni_defs.h:235
_ni_sw_instance_info::status
ni_sw_instance_status_t status
Definition: ni_rsrc_api.h:89
NI_MAX_DEVICE_NAME_LEN
#define NI_MAX_DEVICE_NAME_LEN
Definition: ni_defs.h:236
NI_PARAM_AV1_MAX_HEIGHT
#define NI_PARAM_AV1_MAX_HEIGHT
Definition: ni_device_api.h:149
_ni_context_query::video_width
uint32_t video_width
Definition: ni_device_api.h:1204
ni_rsrc_priv.h
Private definitions used by ni_rsrc_api.cpp for management of NETINT video processing devices.
ni_strtok
char * ni_strtok(char *s, const char *delim, char **saveptr)
Definition: ni_util.c:424
find_available_guid
bool find_available_guid(ni_device_queue_t *device_queue, int device_type, int *guidn)
Definition: ni_rsrc_priv.cpp:375
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_device_capability::fw_rev
uint8_t fw_rev[8]
Definition: ni_device_api.h:1178
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_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
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_nvme.h
Private definitions for interfacing with NETINT video processing devices over NVMe.
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_sw_instance_info::id
int id
Definition: ni_rsrc_api.h:88
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_device_api.h
Public definitions for operating NETINT video processing devices for video processing.
_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_hw_capability::codec_format
uint8_t codec_format
Definition: ni_device_api.h:1153
NI_MIN_HEIGHT
#define NI_MIN_HEIGHT
Definition: ni_device_api.h:129
NI_RETCODE_FAILURE
@ NI_RETCODE_FAILURE
Definition: ni_defs.h:442
_ni_hw_capability::max_video_width
uint16_t max_video_width
Definition: ni_device_api.h:1155
_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_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_context_query::video_height
uint32_t video_height
Definition: ni_device_api.h:1205
ni_util.h
Utility definitions.
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_MIN_WIDTH
#define NI_MIN_WIDTH
Definition: ni_device_api.h:127
_ni_device_queue::xcoder_cnt
uint32_t xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
Definition: ni_rsrc_api.h:69
_ni_device_info::load
int load
Definition: ni_rsrc_api.h:108
MAX_CHAR_IN_DEVICE_NAME
#define MAX_CHAR_IN_DEVICE_NAME
Definition: ni_device_api.h:188
_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
get_dev_pcie_addr
void get_dev_pcie_addr(char *device_name, char *pcie, char *domain, char *slot, char *dev, char *func)
_ni_load_query::context_status
ni_context_query_t context_status[NI_MAX_CONTEXTS_PER_HW_INSTANCE]
Definition: ni_device_api.h:1233
_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_hw_capability::max_number_of_contexts
uint8_t max_number_of_contexts
Definition: ni_device_api.h:1151
NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
@ NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
Definition: ni_defs.h:521