libxcoder 5.8.0
Loading...
Searching...
No Matches
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#if __linux__
67#include "ni_host_ts.h"
68#endif
69
70#if __linux__ || __APPLE__
71#ifndef _ANDROID
72jmp_buf env;
73#endif
74#endif
75
77
78
79#define PCI_BDF_STR_LEN 12
80#define PCIE_ADDRS_MAX 16
81#define PCIE_GEN4_LINK_SPEED 16
82
83#if __linux__
84namespace {
85int read_file_content(const char *path, char *buf, size_t bufsz)
86{
87 FILE *fp = fopen(path, "r");
88 const int n = (bufsz > (size_t)INT_MAX) ? INT_MAX : (int)bufsz;
89 if (!fp)
90 return -1;
91 if (!fgets(buf, n, fp))
92 {
93 (void)fclose(fp);
94 return -1;
95 }
96 (void)fclose(fp);
97 char *nl = strchr(buf, '\n');
98 if (nl)
99 *nl = '\0';
100 return 0;
101}
102
103int find_root_port_from_device(const char *device_bdf, char *root_port_bdf)
104{
105 char block_path[PATH_MAX];
106 char abs_path[PATH_MAX];
107 char *ptr, *saveptr = NULL;
108 char *pcie_addrs[PCIE_ADDRS_MAX] = {0};
109 int addr_count;
110 DIR *dir;
111 struct dirent *entry;
112
113 if (!device_bdf || !root_port_bdf)
114 return -1;
115
116 dir = opendir("/sys/block");
117 if (!dir)
118 return -1;
119
120 while ((entry = readdir(dir))) // NOLINT(concurrency-mt-unsafe) - thread-local dir, no shared DIR*
121 {
122 addr_count = 0;
123 if (strncmp(entry->d_name, "nvme", 4) != 0)
124 continue;
125
126 (void)snprintf(block_path, sizeof(block_path), "/sys/block/%s", entry->d_name);
127
128 if (realpath(block_path, abs_path) == NULL)
129 continue;
130
131 if (strstr(abs_path, device_bdf) == NULL)
132 continue;
133
134 ptr = strtok_r(abs_path, "/", &saveptr);
135 while (ptr != NULL)
136 {
137 if (strlen(ptr) == PCI_BDF_STR_LEN)
138 {
139 unsigned int d, b, dev, f;
140 if (sscanf(ptr, "%x:%x:%x.%x", &d, &b, &dev, &f) == 4) // NOLINT(cert-err34-c) - return value checked
141 {
142 if (addr_count < PCIE_ADDRS_MAX)
143 {
144 pcie_addrs[addr_count] = (char *)malloc(PCI_BDF_STR_LEN + 1);
145 if (pcie_addrs[addr_count]) {
146 strncpy(pcie_addrs[addr_count], ptr, PCI_BDF_STR_LEN);
147 pcie_addrs[addr_count][PCI_BDF_STR_LEN] = '\0';
148 addr_count++;
149 }
150 }
151 }
152 }
153 ptr = strtok_r(NULL, "/", &saveptr);
154 }
155
156 for (int i = addr_count - 2; i >= 0; i--)
157 {
158 char class_path[PATH_MAX];
159 char class_buf[32];
160 unsigned long class_val;
161
162 if (!pcie_addrs[i])
163 continue;
164
165 (void)snprintf(class_path, sizeof(class_path), "/sys/bus/pci/devices/%s/class", pcie_addrs[i]);
166 if (read_file_content(class_path, class_buf, sizeof(class_buf)) != 0)
167 continue;
168
169 class_val = strtoul(class_buf, NULL, 0);
170 if ((class_val & 0xffff00) != 0x060400)
171 continue;
172
173 strncpy(root_port_bdf, pcie_addrs[i], PCI_BDF_STR_LEN);
174 root_port_bdf[PCI_BDF_STR_LEN] = '\0';
175 for (int j = 0; j < addr_count; j++)
176 {
177 if (pcie_addrs[j])
178 free(pcie_addrs[j]);
179 }
180 closedir(dir);
181 return 0;
182 }
183
184 for (int j = 0; j < addr_count; j++)
185 {
186 if (pcie_addrs[j])
187 free(pcie_addrs[j]);
188 }
189 }
190
191 closedir(dir);
192 return -1;
193}
194
195int read_pcie_capability_sysfs(const char *bdf)
196{
197 char path[PATH_MAX];
198 char raw_buf[64] = {0};
199
200 if (!bdf)
201 return -1;
202
203 (void)snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/max_link_speed", bdf);
204 if (read_file_content(path, raw_buf, sizeof(raw_buf)) != 0)
205 return -1;
206
207 if (raw_buf[0] == '\0')
208 return -1;
209
210 unsigned int speed_num = 0;
211 if (sscanf(raw_buf, "%u", &speed_num) != 1) // NOLINT(cert-err34-c) - return value checked
212 return -1;
213 return (int)speed_num;
214}
215
216int get_pcie_gen3_on_gen4_status(const char *device_name, uint8_t fw_flavour)
217{
218 char pcie[64] = {0};
219 char host_port[64] = {0};
220 int device_speed_num = -1;
221 int host_speed_num = -1;
222
223 get_dev_pcie_addr(const_cast<char*>(device_name), pcie, NULL, NULL, NULL, NULL);
224 if (pcie[0] == '\0')
225 return -1;
226
227 device_speed_num = read_pcie_capability_sysfs(pcie);
228 if (find_root_port_from_device(pcie, host_port) == 0)
229 host_speed_num = read_pcie_capability_sysfs(host_port);
230
231 if (device_speed_num >= 0 && host_speed_num >= 0 &&
232 fw_flavour == 'C' && host_speed_num == PCIE_GEN4_LINK_SPEED)
233 return 1;
234 return 0;
235}
236} // namespace
237#endif
238
239/*!******************************************************************************
240 * \brief
241 *
242 * \param
243 *
244 * \return
245 ******************************************************************************/
247 ni_hw_capability_t* p_hw_cap)
248{
249 int i;
251
252 if (!p_device_info)
253 {
254 ni_log(NI_LOG_ERROR, "ERROR: %s() p_device_info is null\n", __func__);
256 LRETURN;
257 }
258
259 ni_log(NI_LOG_DEBUG, "%s type %d fmt %d\n", __func__, type, fmt);
260
261 for (i = 0; i < EN_CODEC_MAX; i++)
262 {
263 p_device_info->dev_cap[i].supports_codec = EN_INVALID;
264 }
265
266 if (NI_DEVICE_TYPE_DECODER == type)
267 {
268 p_device_info->dev_cap[0].supports_codec = EN_H264;
269 p_device_info->dev_cap[0].max_res_width = p_hw_cap->max_video_width;
270 p_device_info->dev_cap[0].max_res_height = p_hw_cap->max_video_height;
271 p_device_info->dev_cap[0].min_res_width = p_hw_cap->min_video_width;
272 p_device_info->dev_cap[0].min_res_height = p_hw_cap->min_video_height;
273
275 "Baseline, Main, High, High10", (NI_PROFILES_SUPP_STR_LEN-1));
277
278 p_device_info->dev_cap[1].supports_codec = EN_H265;
279 p_device_info->dev_cap[1].max_res_width = p_hw_cap->max_video_width;
280 p_device_info->dev_cap[1].max_res_height = p_hw_cap->max_video_height;
281 p_device_info->dev_cap[1].min_res_width = p_hw_cap->min_video_width;
282 p_device_info->dev_cap[1].min_res_height = p_hw_cap->min_video_height;
283
284 ni_strncpy(p_device_info->dev_cap[1].profiles_supported, NI_PROFILES_SUPP_STR_LEN, "Main, Main10",
287
288 p_device_info->dev_cap[2].supports_codec = EN_JPEG;
289 p_device_info->dev_cap[2].max_res_width = p_hw_cap->max_video_width;
290 p_device_info->dev_cap[2].max_res_height = p_hw_cap->max_video_height;
292 p_device_info->dev_cap[2].min_res_height =
294
295 ni_strncpy(p_device_info->dev_cap[2].profiles_supported, NI_PROFILES_SUPP_STR_LEN, "Baseline",
298
299 p_device_info->dev_cap[3].supports_codec = EN_VP9;
300 p_device_info->dev_cap[3].max_res_width = p_hw_cap->max_video_width;
301 p_device_info->dev_cap[3].max_res_height = p_hw_cap->max_video_height;
302 p_device_info->dev_cap[3].min_res_width = p_hw_cap->min_video_width;
303 p_device_info->dev_cap[3].min_res_height = p_hw_cap->min_video_height;
304
308 } else if (NI_DEVICE_TYPE_ENCODER == type)
309 {
310 p_device_info->dev_cap[0].supports_codec = EN_H264;
311 p_device_info->dev_cap[0].max_res_width = p_hw_cap->max_video_width;
312 p_device_info->dev_cap[0].max_res_height = p_hw_cap->max_video_height;
313 p_device_info->dev_cap[0].min_res_width = p_hw_cap->min_video_width;
314 p_device_info->dev_cap[0].min_res_height = p_hw_cap->min_video_height;
315
317 "Baseline, Main, High, High10", (NI_PROFILES_SUPP_STR_LEN-1));
319
320 p_device_info->dev_cap[1].supports_codec = EN_H265;
321 p_device_info->dev_cap[1].max_res_width = p_hw_cap->max_video_width;
322 p_device_info->dev_cap[1].max_res_height = p_hw_cap->max_video_height;
323 p_device_info->dev_cap[1].min_res_width = p_hw_cap->min_video_width;
324 p_device_info->dev_cap[1].min_res_height = p_hw_cap->min_video_height;
325
326 ni_strncpy(p_device_info->dev_cap[1].profiles_supported, NI_PROFILES_SUPP_STR_LEN, "Main, Main10",
329
330 p_device_info->dev_cap[2].supports_codec = EN_JPEG;
331 p_device_info->dev_cap[2].max_res_width = p_hw_cap->max_video_width;
332 p_device_info->dev_cap[2].max_res_height = p_hw_cap->max_video_height;
333 p_device_info->dev_cap[2].min_res_width = NI_MIN_WIDTH;
334 p_device_info->dev_cap[2].min_res_height = NI_MIN_HEIGHT;
335
339
340 p_device_info->dev_cap[3].supports_codec = EN_AV1;
341 p_device_info->dev_cap[3].max_res_width = NI_PARAM_AV1_MAX_WIDTH;
343 p_device_info->dev_cap[3].min_res_width = p_hw_cap->min_video_width;
344 p_device_info->dev_cap[3].min_res_height = p_hw_cap->min_video_height;
345
349 } else if (NI_DEVICE_TYPE_SCALER == type || NI_DEVICE_TYPE_AI == type)
350 {
351 p_device_info->dev_cap[0].supports_codec =
352 p_device_info->dev_cap[1].supports_codec =
353 p_device_info->dev_cap[2].supports_codec =
354 p_device_info->dev_cap[3].supports_codec = EN_INVALID;
355 }
357END:
358
359 return retval;
360}
361
362/*!******************************************************************************
363 * \brief
364 *
365 * \param
366 *
367 * \return
368 *******************************************************************************/
369int ni_rsrc_strcmp(const void * p_str, const void* p_str1)
370{
371 const char *l = (const char *)p_str;
372 const char *r = (const char *)p_str1;
373 int vl, vr;
374
375 if (!l || !r)
376 {
377 return (!l && !r) ? 0 : (!l ? -1 : 1);
378 }
379
380 while (!isdigit(*l) && (*l) != '\0')
381 {
382 l++;
383 }
384 while (!isdigit(*r) && (*r) != '\0')
385 {
386 r++;
387 }
388 {
389 char *end_l, *end_r;
390 vl = (int)strtol(l, &end_l, 10); // NOLINT(cert-err34-c)
391 vr = (int)strtol(r, &end_r, 10); // NOLINT(cert-err34-c)
392 if (end_l == l || end_r == r)
393 {
394 return strcmp((const char *)p_str, (const char *)p_str1);
395 }
396 }
397 if (vl == vr)
398 {
399 return 0;
400 }
401 else if (vl < vr)
402 {
403 return -1;
404 }
405 else
406 {
407 return 1;
408 }
409}
410
411/*!******************************************************************************
412 * \brief
413 *
414 * \param
415 *
416 * \return
417 *******************************************************************************/
418void ni_rsrc_get_lock_name(ni_device_type_t device_type, int32_t guid, char* p_name, size_t max_name_len)
419{
420 const char type = g_device_type_chr[GET_XCODER_DEVICE_TYPE(device_type)];
421 if (NULL != p_name)
422 {
423 if (strcmp(CODERS_SHM_NAME, "NI_QUADRA_SHM_CODERS") == 0)
424 {
425 (void)snprintf(p_name, max_name_len, "%s/NI_QUADRA_lck_%c%d", LOCK_DIR, type, guid);
426 }
427 else
428 {
429 (void)snprintf(p_name, max_name_len, "%s/NI_lck_%c%d", LOCK_DIR, type, guid);
430 }
431 }
432}
433
434/*!******************************************************************************
435 * \brief
436 *
437 * \param
438 *
439 * \return
440 *******************************************************************************/
441void ni_rsrc_get_shm_name(ni_device_type_t device_type, int32_t guid, char* p_name, size_t max_name_len)
442{
443 const char type = g_device_type_chr[GET_XCODER_DEVICE_TYPE(device_type)];
445 if (NULL != p_name)
446 {
447 if (strcmp(CODERS_SHM_NAME, "NI_QUADRA_SHM_CODERS") == 0)
448 {
449 (void)snprintf(p_name, max_name_len, "NI_QUADRA_shm_%c%d", type, guid);
450 }
451 else
452 {
453 (void)snprintf(p_name, max_name_len, "NI_shm_%c%d", type, guid);
454 }
455 }
456}
457
458namespace {
459void fill_device_info(ni_device_info_t *device_info,
460 const int module_id,
461 const ni_device_handle_t device_handle,
462 const char device_name[NI_MAX_DEVICE_NAME_LEN],
463 const int fw_ver_compat_warning,
464 ni_device_capability_t *device_capability,
465 const ni_device_type_t device_type)
466{
467 ni_hw_capability_t *hw_capability;
468 int gen3_on_gen4 = -1;
469
470 hw_capability = &device_capability->xcoder_devices[device_type];
471
474 device_info->hw_id = hw_capability->hw_id;
475 device_info->module_id = module_id;
476 device_info->fw_ver_compat_warning = fw_ver_compat_warning;
477
478 memcpy(device_info->fw_rev,
479 device_capability->fw_rev,
480 sizeof(device_info->fw_rev));
481 memcpy(device_info->fw_branch_name,
482 device_capability->fw_branch_name,
483 sizeof(device_info->fw_branch_name) - 1);
484 memcpy(device_info->fw_commit_time,
485 device_capability->fw_commit_time,
486 sizeof(device_info->fw_commit_time) - 1);
487 memcpy(device_info->fw_commit_hash,
488 device_capability->fw_commit_hash,
489 sizeof(device_info->fw_commit_hash) - 1);
490 memcpy(device_info->fw_build_time,
491 device_capability->fw_build_time,
492 sizeof(device_info->fw_build_time) - 1);
493 memcpy(device_info->fw_build_id,
494 device_capability->fw_build_id,
495 sizeof(device_info->fw_build_id) - 1);
496 memcpy(device_info->serial_number,
497 device_capability->serial_number,
498 sizeof(device_info->serial_number));
499 memcpy(device_info->model_number,
500 device_capability->model_number,
501 sizeof(device_info->model_number));
502
503 ni_query_fl_fw_versions(device_handle, device_info);
504
505 device_info->max_fps_4k = hw_capability->max_4k_fps;
506 device_info->max_instance_cnt = hw_capability->max_number_of_contexts;
507 device_info->device_type = device_type;
508
509 ni_rsrc_fill_device_info(device_info,
510 (ni_codec_t)hw_capability->codec_format,
511 device_type,
512 hw_capability);
513 {
514 ni_device_extra_info_t extra_info = {0};
515 if (ni_query_extra_info(device_handle, &extra_info, device_capability->fw_rev) == NI_RETCODE_SUCCESS)
516 {
517 device_info->fw_flavour = extra_info.fw_flavour;
518#if __linux__
519 gen3_on_gen4 = get_pcie_gen3_on_gen4_status(device_name, extra_info.fw_flavour);
520#endif
521 }
522#if __linux__
523 if (gen3_on_gen4 < 0)
524 gen3_on_gen4 = 0;
525#endif
526 }
527 device_info->pcie_gen3_on_gen4_host = gen3_on_gen4;
528
529}
530
531void fill_shared_memory(ni_device_queue_t *device_queue,
532 const int should_match_rev,
533 const int existing_number_of_devices,
534 const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
535{
536 int i, j, compatible_device_counter;
537
538 if (!device_queue)
539 {
540 ni_log(NI_LOG_ERROR, "ERROR: %s() device_queue is NULL\n", __func__);
541 return;
542 }
543
544 memset(device_queue->xcoder_cnt, 0, sizeof(device_queue->xcoder_cnt));
546 {
547 for (j = 0; j < NI_MAX_DEVICE_CNT; j++)
548 {
549 device_queue->xcoders[i][j] = -1;
550 }
551 }
552
553 compatible_device_counter = 0;
554 for (i = 0; i < existing_number_of_devices; i++)
555 {
556 if (!add_to_shared_memory(device_names[i],
557 false,
558 should_match_rev,
559 device_queue))
560 {
561 continue;
562 }
563 compatible_device_counter++;
564 if (compatible_device_counter >= NI_MAX_DEVICE_CNT)
565 {
567 "Maximum number of supported and compatible devices "
568 "reached. Ignoring other supported and compatible "
569 "devices.\n");
570 break;
571 }
572 }
573}
574
575bool find_available_guid(ni_device_queue_t *device_queue, int device_type, int *guidn)
576{
577 /*
578 Create a mask of all 128 guids, mark used by 1 and unused by 0.
579 */
580 int32_t temp_guid;
581 int32_t i, j;
582 uint32_t guid_mask[4] = {0};
583
584 for (i = 0; i < NI_MAX_DEVICE_CNT; i++)
585 {
586 temp_guid = device_queue->xcoders[device_type][i];
587 if (temp_guid >= 0 && temp_guid < NI_MAX_DEVICE_CNT)
588 {
589 guid_mask[temp_guid / 32] |= (1u << ((uint32_t)temp_guid % 32));
590 }
591 }
592 //from the masks find the first available guidn
593 for (i = 0; i < 4; i++)
594 {
595 for (j = 0; j < 32; j++)
596 {
597 if ((guid_mask[i] & (1u << j)) == 0)
598 {
599 *guidn = (i * 32) + j;
600 return true;
601 }
602 }
603 }
604
605 return false;
606}
607} // namespace
608
609bool add_to_shared_memory(const char device_name[NI_MAX_DEVICE_NAME_LEN],
610 const bool device_open_should_succeed,
611 const int should_match_rev,
612 ni_device_queue_t *device_queue)
613{
614 int32_t guid;
615 int i, j, fw_compat_cmp;
616 char fw_api_ver_str[5];
617
618 ni_device_capability_t device_capability = {0};
619 ni_device_handle_t device_handle;
620 ni_device_info_t device_info = {0};
621 bool success = true;
622
623 device_handle = ni_device_open2(device_name, NI_DEVICE_READ_ONLY);
624 if (device_handle == NI_INVALID_DEVICE_HANDLE)
625 {
626 if (device_open_should_succeed)
627 {
629 "ERROR: %s(): Failed to add %s\n: Failed ni_device_open2()\n",
630 __FUNCTION__,
631 device_name);
632 return false;
633 }
634 return true;
635 }
636
637 if (ni_device_capability_query2(device_handle, &device_capability, false) != NI_RETCODE_SUCCESS)
638 {
639 ni_log(NI_LOG_INFO, "Skipping %s init: unable to query capability\n",
640 device_name);
641 LRETURN;
642 }
643 if (!is_supported_xcoder(device_capability.device_is_xcoder))
644 {
645 ni_log(NI_LOG_INFO, "Skipping %s init: model not supported\n", device_name);
646 LRETURN;
647 }
649 &fw_api_ver_str[0]);
650 if (should_match_rev && \
651 ((uint8_t) device_capability.fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX] != \
653 {
655 "Skipping %s init: device FW v%s incompatible with this version of Libxcoder\n",
656 device_name,
657 fw_api_ver_str);
658 LRETURN;
659 }
660 fw_compat_cmp = ni_cmp_fw_api_ver((char*) &device_capability.fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX],
662
663
665 {
666 if (!device_capability.xcoder_cnt[i])
667 {
669 "%s %s disabled...\n",
670 device_name,
672 continue;
673 }
674
675 j = (int)device_queue->xcoder_cnt[i];
676 guid = j ? device_queue->xcoders[i][j-1] + 1 : 0;
677 if (guid >= NI_MAX_DEVICE_CNT && !find_available_guid(device_queue, i, &guid))
678 {
679 ni_log(NI_LOG_ERROR, "ERROR: %s(): Skipping %s init: number of "
680 "initialized devices exceeds %d\n", __FUNCTION__,
681 device_name, NI_MAX_DEVICE_CNT);
682 success = false;
683 LRETURN;
684 }
685 device_queue->xcoders[i][j] = guid;
686 device_queue->xcoder_cnt[i]++;
687
688 fill_device_info(&device_info,
689 guid,
690 device_handle,
691 device_name,
692 (should_match_rev && fw_compat_cmp) ? 1 : 0,
693 &device_capability,
695
696 ni_rsrc_get_one_device_info(&device_info);
697 }
698
699 if (fw_compat_cmp < 0) {
700 ni_log(NI_LOG_INFO, "Initialized %s with FW API v%s that is older than "
701 "Libxcoder supported FW API version\n", device_name,
702 fw_api_ver_str);
703 } else if (fw_compat_cmp > 0) {
704 ni_log(NI_LOG_INFO, "Initialized %s with FW API v%s that is newer than "
705 "Libxcoder supported FW API version\n", device_name,
706 fw_api_ver_str);
707 } else {
708 ni_log(NI_LOG_INFO, "Initialized %s with FW API v%s\n", device_name, fw_api_ver_str);
709 }
710#if __linux__
711 ni_host_ts_set();
712#endif
713
714END:
715 ni_device_close(device_handle);
716
717 return success;
718}
719
721{
722#ifdef _WIN32
723 return NI_RETCODE_SUCCESS;
724#else
725 size_t i;
726 int retry_shm_fd;
727 for(i = 0; i < sizeof(XCODERS_RETRY_LCK_NAME) / sizeof(XCODERS_RETRY_LCK_NAME[0]); ++i)
728 {
729 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);
730 if(retry_shm_fd < 0)
731 {
732 if(errno != EEXIST)
733 {
734 char errmsg[NI_ERRNO_LEN] = {0};
736 ni_log(NI_LOG_ERROR, "Failed to create %s ERROR: %s\n", XCODERS_RETRY_LCK_NAME[i], errmsg);
738 }
739 else
740 {
741 ni_log(NI_LOG_DEBUG, "%s already exists\n", XCODERS_RETRY_LCK_NAME[i]);
742 }
743 }
744 else
745 {
746 ni_log(NI_LOG_DEBUG, "Create XCODERS_RETRY_LCK: %s\n", XCODERS_RETRY_LCK_NAME[i]);
747 close(retry_shm_fd);
748 }
749 }
750
751 return NI_RETCODE_SUCCESS;
752
753#endif
754}
755
756#ifdef _WIN32
757
758/*!******************************************************************************
759 * \brief
760 *
761 * \param
762 *
763 * \return
764 *******************************************************************************/
766 char ni_devices[][NI_MAX_DEVICE_NAME_LEN],
767 int max_handles
768)
769{
770 return ni_nvme_enumerate_devices(ni_devices, max_handles);
771}
772
773/*!******************************************************************************
774 * \brief
775 *
776 * \param
777 *
778 * \return
779 *******************************************************************************/
781{
782 char shm_name[32] = { 0 };
783 char lck_name[32] = { 0 };
784 DWORD rc = 0;
785 ni_device_info_t * p_coder_info_map = NULL;
786 HANDLE map_file_handle = NULL;
787 ni_lock_handle_t mutex_handle = NULL;
788 SECURITY_DESCRIPTOR security_descriptor = { 0 };
789
790 if(!p_device_info)
791 {
792 return;
793 }
794
795 ni_rsrc_get_shm_name(p_device_info->device_type, p_device_info->module_id, shm_name, sizeof(shm_name));
796 ni_rsrc_get_lock_name(p_device_info->device_type, p_device_info->module_id, lck_name, sizeof(lck_name));
797 ni_log(NI_LOG_DEBUG, "%s(): shm_name %s, lck_name %s\n", __func__, shm_name, lck_name);
798
799 //Create a mutex for protecting the memory area
800 mutex_handle = CreateMutexA(NULL, // default security attributes
801 FALSE, // initially owned
802 lck_name); // unnamed mutex
803 if (NULL == mutex_handle)
804 {
805 ni_log(NI_LOG_ERROR, "CreateMutex error: %d\n", NI_ERRNO);
806 LRETURN;
807 }
808
809 if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
810 {
811 ni_log(NI_LOG_ERROR, "ERROR: ni_rsrc_get_device_context() failed to "
812 "obtain mutex: %p\n", mutex_handle);
813 LRETURN;
814 }
815
816 InitializeSecurityDescriptor(&security_descriptor, SECURITY_DESCRIPTOR_REVISION);
817 //security_descriptor.Control
818
819 map_file_handle = CreateFileMappingA(
820 INVALID_HANDLE_VALUE, // use paging file
821 NULL, // default security
822 PAGE_READWRITE, // read/write access
823 0, // maximum object size (high-order DWORD)
824 sizeof(ni_device_info_t),// maximum object size (low-order DWORD)
825 shm_name // name of mapping object
826 );
827
828 if (NULL == map_file_handle)
829 {
830 rc = NI_ERRNO;
831 ni_log(NI_LOG_ERROR, "ERROR: CreateFileMapping returned (%d) for %s\n",
832 rc, shm_name);
833 LRETURN;
834 }
835 else
836 {
837 rc = NI_ERRNO;
838 if (ERROR_ALREADY_EXISTS == rc)
839 {
840 ni_log(NI_LOG_ERROR, "CreateFileMapping returned existing handle for"
841 " %s\n", shm_name);
842 }
843 else
844 {
845 ni_log(NI_LOG_INFO, "CreateFileMapping created a new mapFile for %s, handle: %p ..\n", shm_name, map_file_handle);
846 }
847 }
848
849 p_coder_info_map = (ni_device_info_t *) MapViewOfFile(
850 map_file_handle, // handle to map object
851 FILE_MAP_ALL_ACCESS, // read/write permission
852 0,
853 0,
854 sizeof(ni_device_info_t)
855 );
856
857 if (NULL == p_coder_info_map)
858 {
859 rc = NI_ERRNO;
860 ni_log(NI_LOG_INFO, "Could not map view of file, p_last error (%d).\n", rc);
861 LRETURN;
862 }
863
864 memcpy(p_coder_info_map, p_device_info, sizeof(ni_device_info_t));
865
866END:
867 if (p_coder_info_map)
868 {
869 UnmapViewOfFile(p_coder_info_map);
870 }
871
872 if (mutex_handle) {
873 ReleaseMutex(mutex_handle);
874 mutex_handle = NULL;
875 }
876}
877
878
879
880
881
882/*!******************************************************************************
883 * \brief
884 *
885 * \param
886 *
887 * \return
888 *******************************************************************************/
889void ni_rsrc_update_record(ni_device_context_t* p_device_context, ni_session_context_t* p_session_context)
890{
891 uint32_t i = 0;
892
893 if ((!p_device_context) || (!p_session_context))
894 {
895 return;
896 }
897
898 p_device_context->p_device_info->load = p_session_context->load_query.current_load;
899 p_device_context->p_device_info->active_num_inst = p_session_context->load_query.total_contexts;
900 // Now we get the model load from the FW
901 p_device_context->p_device_info->model_load = p_session_context->load_query.fw_model_load;
902 if ( 0 == p_device_context->p_device_info->active_num_inst )
903 {
904 p_device_context->p_device_info->load = 0;
905 }
906
907 for (i = 0; i < p_device_context->p_device_info->active_num_inst; i++)
908 {
909 p_device_context->p_device_info->sw_instance[i].id =
910 p_session_context->load_query.context_status[i].context_id;
912 p_session_context->load_query.context_status[i].context_status;
913 p_device_context->p_device_info->sw_instance[i].codec = (ni_codec_t)
914 p_session_context->load_query.context_status[i].codec_format;
915 p_device_context->p_device_info->sw_instance[i].width =
916 p_session_context->load_query.context_status[i].video_width;
917 p_device_context->p_device_info->sw_instance[i].height =
918 p_session_context->load_query.context_status[i].video_height;
919 p_device_context->p_device_info->sw_instance[i].fps =
920 p_session_context->load_query.context_status[i].fps;
921 }
922}
923
924/*!******************************************************************************
925 * \brief Initialize and create all resources required to work with NETINT NVMe
926 * transcoder devices. This is a high level API function which is used
927 * mostly with user application like FFmpeg that relies on those resources.
928 * In case of custom application integration, revised functionality might
929 * be necessary utilizing corresponding API functions.
930 *
931 * \param[in] should_match_rev 0: transcoder firmware revision matching the
932 * library's version is NOT required for placing
933 * the transcoder into resource pool; 1: otherwise
934 * timeout_seconds 0: No timeout amount, loop until init success
935 * or fail; else: timeout will fail init once reached
936 *
937 * \return
938 * NI_RETCODE_SUCCESS on success
939 * NI_RETCODE_FAILURE on failure
940 *
941 *******************************************************************************/
942int ni_rsrc_init_priv(const int should_match_rev,
943 const int existing_number_of_devices,
944 const char existing_device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
945{
946 DWORD rc = 0;
947 HANDLE lock = NULL;
948 HANDLE map_file_handle = NULL;
949 ni_device_queue_t* p_device_queue = NULL;
950 map_file_handle = CreateFileMappingA(
951 INVALID_HANDLE_VALUE, // use paging file
952 NULL, // default security
953 PAGE_READWRITE, // read/write access
954 0, // maximum object size (high-order DWORD)
955 sizeof(ni_device_queue_t),// maximum object size (low-order DWORD)
956 CODERS_SHM_NAME // name of mapping object
957 );
958
959 if (NULL == map_file_handle)
960 {
961 rc = NI_ERRNO;
962 ni_log(NI_LOG_ERROR, "ERROR: CreateFileMapping returned: %d\n", rc);
963 return NI_RETCODE_FAILURE;
964 }
965 else
966 {
967 rc = NI_ERRNO;
968 if(ERROR_ALREADY_EXISTS == rc)
969 {
970 ni_log(NI_LOG_INFO, "NETINT resources have been initialized already, exiting ..\n");
971 CloseHandle(map_file_handle);
972 return NI_RETCODE_SUCCESS;
973 }
974 else
975 {
976 ni_log(NI_LOG_INFO, "NETINT resources not initialized, starting initialization ..\n");
977 }
978 }
979
980 p_device_queue = (ni_device_queue_t*)MapViewOfFile(
981 map_file_handle, // handle to map object
982 FILE_MAP_ALL_ACCESS, // read/write permission
983 0,
984 0,
985 sizeof(ni_device_queue_t)
986 );
987
988 if (NULL == p_device_queue)
989 {
990 ni_log(NI_LOG_ERROR, "Could not map view of file, p_last error (%d).\n",
991 NI_ERRNO);
992 CloseHandle(map_file_handle);
993 return NI_RETCODE_FAILURE;
994 }
995
996 lock = CreateMutexA(NULL, FALSE, CODERS_LCK_NAME);
997 if (NULL == lock)
998 {
999 ni_log(NI_LOG_ERROR, "Init CreateMutex %s failed: %d\n", CODERS_LCK_NAME,
1000 NI_ERRNO);
1001 UnmapViewOfFile(p_device_queue);
1002 CloseHandle(map_file_handle);
1003 return NI_RETCODE_FAILURE;
1004 }
1005
1006 if (WAIT_ABANDONED == WaitForSingleObject(lock, INFINITE))
1007 {
1008 ni_log(NI_LOG_ERROR, "ERROR %d: failed to obtain mutex: %p\n",
1009 NI_ERRNO, lock);
1010 ReleaseMutex(lock);
1011 CloseHandle(lock);
1012 UnmapViewOfFile(p_device_queue);
1013 CloseHandle(map_file_handle);
1014 return NI_RETCODE_FAILURE;
1015 }
1016
1017 fill_shared_memory(p_device_queue,
1018 should_match_rev,
1019 existing_number_of_devices,
1020 existing_device_names);
1021
1022 UnmapViewOfFile(p_device_queue);
1023 ReleaseMutex(lock);
1024 CloseHandle(lock);
1025 return NI_RETCODE_SUCCESS;
1026}
1027
1028#elif __linux__ || __APPLE__
1029
1030
1031typedef struct {
1032int32_t guid;
1033char dev_name[NI_MAX_DEVICE_NAME_LEN];
1034} guid_name_map_t;
1035
1036namespace {
1040bool check_correctness_count(const ni_device_queue_t *existing_device_queue,
1041 const int should_match_rev,
1042 const int existing_number_of_devices,
1043 const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
1044{
1045 int i, j, k;
1046 uint32_t queue_idx;
1047 int32_t guid;
1048 bool device_found_in_queue;
1049
1050 ni_device_capability_t device_capability;
1051 ni_device_handle_t device_handle;
1052 ni_device_queue_t device_queue;
1053 ni_device_context_t *device_context;
1054
1055 guid_name_map_t guid_map[NI_DEVICE_TYPE_XCODER_MAX][NI_MAX_DEVICE_CNT];
1056 uint32_t guid_map_count[NI_DEVICE_TYPE_XCODER_MAX] = {0};
1057
1058 memset(device_queue.xcoder_cnt, 0, sizeof(device_queue.xcoder_cnt));
1059
1060 // PHASE 1: GUID to device name mapping for all device types
1062 {
1063 for (queue_idx = 0; queue_idx < existing_device_queue->xcoder_cnt[j]; queue_idx++)
1064 {
1065 guid = existing_device_queue->xcoders[j][queue_idx];
1066 if (guid < 0 || guid >= NI_MAX_DEVICE_CNT)
1067 {
1068 continue;
1069 }
1070 device_context = ni_rsrc_get_device_context((ni_device_type_t)j, guid);
1071 if (device_context && device_context->p_device_info)
1072 {
1073 if (guid_map_count[j] >= NI_MAX_DEVICE_CNT)
1074 {
1075 ni_log(NI_LOG_ERROR, "ERROR: %s(): guid_map_count[%d] exceeds NI_MAX_DEVICE_CNT\n", __func__, j);
1076 ni_rsrc_free_device_context(device_context);
1077 return false;
1078 }
1079 guid_map[j][guid_map_count[j]].guid = guid;
1080 ni_strncpy(guid_map[j][guid_map_count[j]].dev_name, NI_MAX_DEVICE_NAME_LEN,
1081 device_context->p_device_info->dev_name, NI_MAX_DEVICE_NAME_LEN - 1);
1082 guid_map_count[j]++;
1083 ni_rsrc_free_device_context(device_context);
1084 }
1085 else if (device_context)
1086 {
1087 ni_rsrc_free_device_context(device_context);
1088 }
1089 }
1090 }
1091
1092 // PHASE 2: Check against pre-built maps
1093 for (i = 0; i < existing_number_of_devices; i++)
1094 {
1095 device_handle = ni_device_open2(device_names[i], NI_DEVICE_READ_ONLY);
1096 if (device_handle == NI_INVALID_DEVICE_HANDLE)
1097 {
1098 continue;
1099 }
1100 memset(&device_capability, 0, sizeof(ni_device_capability_t));
1101 if (ni_device_capability_query2(device_handle, &device_capability, false) != NI_RETCODE_SUCCESS || \
1102 !is_supported_xcoder(device_capability.device_is_xcoder) ||
1103 (should_match_rev && \
1104 ((uint8_t) device_capability.fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX] != \
1106 {
1107 ni_device_close(device_handle);
1108 continue;
1109 }
1111 {
1112 if (device_capability.xcoder_cnt[j] == 0)
1113 {
1114 continue;
1115 }
1116 device_found_in_queue = false;
1117 for (queue_idx = 0; queue_idx < guid_map_count[j]; queue_idx++)
1118 {
1119 if (strncmp(device_names[i], guid_map[j][queue_idx].dev_name, NI_MAX_DEVICE_NAME_LEN) == 0)
1120 {
1121 device_found_in_queue = true;
1122 break;
1123 }
1124 }
1125 if (!device_found_in_queue)
1126 {
1128 {
1129 if (k == j)
1130 {
1131 continue;
1132 }
1133 for (queue_idx = 0; queue_idx < guid_map_count[k]; queue_idx++)
1134 {
1135 if (strncmp(device_names[i], guid_map[k][queue_idx].dev_name, NI_MAX_DEVICE_NAME_LEN) == 0)
1136 {
1138 "ERROR: %s(): Discovered device %s is not in queue for module %s but is in %s\n",
1139 __func__,
1140 device_names[i],
1142 ni_device_close(device_handle);
1143 return false;
1144 }
1145 }
1146 }
1147 continue;
1148 }
1149 device_queue.xcoder_cnt[j] += device_capability.xcoder_cnt[j];
1150 }
1151 ni_device_close(device_handle);
1152 }
1153
1155 {
1156 if (device_queue.xcoder_cnt[i] == existing_device_queue->xcoder_cnt[i])
1157 {
1158 continue;
1159 }
1161 "WARNING: %s(): Discovered %u %s, expected %u\n",
1162 __func__,
1163 device_queue.xcoder_cnt[i],
1165 existing_device_queue->xcoder_cnt[i]);
1166 return false;
1167 }
1168 return true;
1169}
1170
1171bool check_device_queue(const ni_device_queue_t *existing_device_queue,
1172 const int existing_number_of_devices,
1173 const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
1174{
1175 int32_t module_id;
1176 int i, j;
1177
1178 ni_device_context_t *device_context;
1179
1180 for (i = 0; i < existing_number_of_devices; i++)
1181 {
1183 {
1184 module_id = existing_device_queue->xcoders[j][i];
1185 if (module_id == -1)
1186 {
1187 break;
1188 }
1189 device_context = ni_rsrc_get_device_context((ni_device_type_t)j,
1190 module_id);
1191 if (!device_context)
1192 {
1194 "WARNING: %s(): Missing device context for %s %s\n",
1195 __func__,
1196 device_names[i],
1198 return false;
1199 }
1200 if (strcmp(device_context->p_device_info->dev_cap[3].additional_info, "Set") != 0)
1201 {
1202 ni_log(NI_LOG_ERROR, "ERROR %s() device info not populated %s\n", __func__, device_context->p_device_info->dev_cap[3].additional_info);
1203 return false;
1204 }
1205 ni_rsrc_free_device_context(device_context);
1206 }
1207 }
1208
1209 return true;
1210}
1211
1212#ifndef _ANDROID
1213void sigbus_handler(int signal)
1214{
1215 (void)signal;
1216 siglongjmp(env, 1);
1217}
1218
1219void setup_signal_handler(struct sigaction *p, const int signum)
1220{
1221 struct sigaction c;
1222
1223 memset(&c, 0, sizeof(struct sigaction));
1224 if (sigemptyset(&c.sa_mask) == -1)
1225 {
1227 "ERROR: %s(): Could not initialize signal set: %d\n",
1228 __func__,
1229 NI_ERRNO);
1230 _Exit(EXIT_FAILURE);
1231 }
1232 c.sa_handler = sigbus_handler;
1233
1234 if (sigaction(signum, NULL, p) == -1)
1235 {
1237 "ERROR: %s(): Could not save previous signal handler: %d\n",
1238 __func__,
1239 NI_ERRNO);
1240 _Exit(EXIT_FAILURE);
1241 }
1242
1243 if (sigaction(signum, &c, NULL) == -1)
1244 {
1246 "ERROR: %s(): Could not register signal handler: %d\n",
1247 __func__,
1248 NI_ERRNO);
1249 _Exit(EXIT_FAILURE);
1250 }
1251}
1252#endif
1253
1254bool check_correctness(const ni_device_queue_t *existing_device_queue,
1255 const int should_match_rev,
1256 const int existing_number_of_devices,
1257 const char device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN])
1258{
1259 bool result = false;
1260#ifndef _ANDROID
1261 const int signum = SIGBUS;
1262 struct sigaction p;
1263
1264 setup_signal_handler(&p, signum);
1265
1266 if (sigsetjmp(env, 1))
1267 {
1268 LRETURN;
1269 }
1270#endif
1271
1272 if (!check_correctness_count(existing_device_queue,
1273 should_match_rev,
1274 existing_number_of_devices,
1275 device_names))
1276 {
1277 LRETURN;
1278 }
1279
1280 if (!check_device_queue(existing_device_queue,
1281 existing_number_of_devices,
1282 device_names))
1283 {
1284 LRETURN;
1285 }
1286
1287 result = true;
1288 ni_log(NI_LOG_INFO, "%s ok\n", CODERS_SHM_NAME);
1289
1290end:
1291#ifndef _ANDROID
1292 if (sigaction(signum, &p, NULL) == -1)
1293 {
1295 "ERROR: %s(): Could not restore previous signal handler: %d\n",
1296 __func__,
1297 NI_ERRNO);
1298 _Exit(EXIT_FAILURE);
1299 }
1300#endif
1301 return result;
1302}
1303} // namespace
1304
1305int ni_rsrc_init_priv(const int should_match_rev, // NOLINT(misc-no-recursion) - bounded: retries up to limit_depth (default 3) after wiping stale SHM
1306 const int existing_number_of_devices,
1307 const char existing_device_names[NI_MAX_DEVICE_CNT][NI_MAX_DEVICE_NAME_LEN],
1308 int limit_depth)
1309{
1310 int return_value = 0;
1311 int lck_fd = -1;
1312 int shm_fd = -1;
1313 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1314 const int flags = O_CREAT | O_RDWR | O_CLOEXEC;
1315 const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1316 ni_device_queue_t *p_device_queue = NULL;
1317
1318 if ((ni_rsrc_try_get_shm_lock(CODERS_LCK_NAME, flags, mode, &lck_fd) < 0) ||
1319 (ni_rsrc_open_shm(CODERS_SHM_NAME, sizeof(ni_device_queue_t), &state, &shm_fd) < 0)) {
1320 return_value = 1;
1321 LRETURN;
1322 }
1323
1324 if ((ni_rsrc_mmap_shm(CODERS_SHM_NAME,
1325 shm_fd,
1326 sizeof(ni_device_queue_t),
1327 (void **)&p_device_queue)) < 0) {
1328 ni_log(NI_LOG_ERROR, "%s(): Failed to ni_rsrc_mmap_shm\n", __func__);
1329 return_value = 1;
1330 LRETURN;
1331 }
1332
1333 //share momery exist
1334 if (NI_RSRC_SHM_IS_EXISTED == state) {
1335 if (check_correctness(p_device_queue,
1336 should_match_rev,
1337 existing_number_of_devices,
1338 existing_device_names))
1339 {
1340 LRETURN;
1341 }
1342
1343 ni_rsrc_munmap_shm((void *)p_device_queue, sizeof(ni_device_queue_t));
1344 ni_log(NI_LOG_DEBUG, "in %s do munmap for %s, shm_flag is O_RDWR\n", __func__, CODERS_SHM_NAME);
1345
1346 if (lockf(lck_fd, F_ULOCK, 0) < 0) {
1347 ni_log(NI_LOG_ERROR, "%s(): Failed to unlock lck_fd for %s\n", __func__, CODERS_SHM_NAME);
1348 }
1349
1350 close(lck_fd);
1351
1352#ifndef __OPENHARMONY__
1353 close(shm_fd);
1354#endif
1355 ni_rsrc_remove_all_shm();
1356
1357 if (limit_depth <= 0)
1358 {
1359 return 1;
1360 }
1361 return ni_rsrc_init_priv(should_match_rev,
1362 existing_number_of_devices,
1363 existing_device_names,
1364 limit_depth - 1);
1365 }
1366
1367 fill_shared_memory(p_device_queue,
1368 should_match_rev,
1369 existing_number_of_devices,
1370 existing_device_names);
1371
1372end:
1373 if (p_device_queue && p_device_queue != MAP_FAILED) {
1374 ni_rsrc_munmap_shm((void *)p_device_queue, sizeof(ni_device_queue_t));
1375 p_device_queue = NULL;
1376 ni_log(NI_LOG_DEBUG, "in %s do munmap for %s\n", __func__, CODERS_SHM_NAME);
1377 }
1378
1379 if (lck_fd != -1) {
1380 if (lockf(lck_fd, F_ULOCK, 0) < 0) {
1381 ni_log(NI_LOG_ERROR, "Will exit from %s(), but failed to unlock lck_fd for %s\n", __func__, CODERS_SHM_NAME);
1382 }
1383
1384 close(lck_fd);
1385 }
1386
1387#ifndef __OPENHARMONY__
1388 if (shm_fd >= 0) {
1389 close(shm_fd);
1390 }
1391#endif
1392
1393 return return_value;
1394}
1395
1396/*!******************************************************************************
1397 * \brief
1398 *
1399 * \param
1400 *
1401 * \return
1402 *******************************************************************************/
1403void ni_rsrc_get_one_device_info (ni_device_info_t * p_device_info)
1404{
1405 int32_t shm_fd = -1;
1406 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1407 int32_t lock = -1;
1408 const int flags = O_CREAT | O_RDWR | O_CLOEXEC;
1409 const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1410 char shm_name[32] = { 0 };
1411 char lck_name[32] = { 0 };
1412 ni_device_info_t * p_coder_info_dst = NULL;
1413
1414 if(! p_device_info) {
1415 return;
1416 }
1417
1418 ni_rsrc_get_shm_name(p_device_info->device_type, p_device_info->module_id, shm_name, sizeof(shm_name));
1419 ni_rsrc_get_lock_name(p_device_info->device_type, p_device_info->module_id, lck_name, sizeof(lck_name));
1420
1421 ni_log(NI_LOG_DEBUG, "%s(): shm_name %s, lck_name %s\n", __func__, shm_name, lck_name);
1422
1423 if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, (int *)&lock) < 0) {
1424 ni_log(NI_LOG_ERROR, "%s: Failed to get lock\n", __func__);
1425 return ;
1426 }
1427
1428 if (ni_rsrc_open_shm(shm_name,
1429 sizeof(ni_device_info_t),
1430 &state,
1431 (int *)&shm_fd) < 0) {
1432 ni_log(NI_LOG_ERROR, "%s: Failed to ni_rsrc_open_shm\n", __func__);
1433 LRETURN;
1434 }
1435
1436 if ((ni_rsrc_mmap_shm(shm_name,
1437 (int)shm_fd,
1438 sizeof(ni_device_info_t),
1439 (void **)&p_coder_info_dst)) < 0) {
1440 ni_log(NI_LOG_ERROR, "%s(): Failed to ni_rsrc_mmap_shm\n", __func__);
1441 LRETURN;
1442 }
1443
1444 memcpy(p_coder_info_dst, p_device_info, sizeof(ni_device_info_t));
1445
1446#ifndef __OPENHARMONY__
1447 if (msync((void*)p_coder_info_dst, sizeof(ni_device_info_t), MS_SYNC | MS_INVALIDATE)) {
1448 char errmsg[NI_ERRNO_LEN] = {0};
1450 ni_log(NI_LOG_ERROR, "ERROR %s() msync() p_coder_info_dst: %s\n",
1451 __func__, errmsg);
1452 } else {
1453 ni_log(NI_LOG_DEBUG, "%s(): written out\n", __func__);
1454 }
1455#endif
1456
1457END:
1458 if (p_coder_info_dst && p_coder_info_dst != MAP_FAILED) {
1459 ni_rsrc_munmap_shm((void *)p_coder_info_dst, sizeof(ni_device_info_t));
1460 p_coder_info_dst = NULL;
1461 ni_log(NI_LOG_DEBUG, "in %s do munmap for %s\n", __func__, shm_name);
1462 }
1463
1464#ifndef __OPENHARMONY__
1465 if (shm_fd >= 0) {
1466 close(shm_fd);
1467 }
1468#endif
1469
1470 /* lock is always valid here: failure to acquire lock exits via return, not LRETURN */
1471 if (lockf(lock, F_ULOCK, 0) < 0) {
1472 ni_log(NI_LOG_ERROR, "Will exit from %s(), but failed to unlock lck_fd for %s\n", __func__, shm_name);
1473 }
1474 close(lock);
1475}
1476
1477/*!******************************************************************************
1478 * \brief
1479 *
1480 * \param
1481 *
1482 * \return
1483 *******************************************************************************/
1484void ni_rsrc_update_record(ni_device_context_t *p_device_context, ni_session_context_t *p_session_context)
1485{
1486 uint32_t j;
1487
1488 if ((!p_device_context) || (!p_session_context))
1489 {
1490 return;
1491 }
1492
1493 p_device_context->p_device_info->load = (int)p_session_context->load_query.current_load;
1494 p_device_context->p_device_info->active_num_inst = p_session_context->load_query.total_contexts;
1495 // Now we get the model load from the FW
1496 p_device_context->p_device_info->model_load = (int)p_session_context->load_query.fw_model_load;
1497 if (0 == p_device_context->p_device_info->active_num_inst)
1498 {
1499 p_device_context->p_device_info->load = 0;
1500 }
1501 for (j = 0; j < p_device_context->p_device_info->active_num_inst; j++)
1502 {
1503 p_device_context->p_device_info->sw_instance[j].id =
1504 p_session_context->load_query.context_status[j].context_id;
1506 p_session_context->load_query.context_status[j]
1508 p_device_context->p_device_info->sw_instance[j].codec = (ni_codec_t)
1509 p_session_context->load_query.context_status[j]
1510 .codec_format;
1511 p_device_context->p_device_info->sw_instance[j].width =
1512 p_session_context->load_query.context_status[j].video_width;
1513 p_device_context->p_device_info->sw_instance[j].height =
1514 p_session_context->load_query.context_status[j].video_height;
1515 p_device_context->p_device_info->sw_instance[j].fps =
1516 p_session_context->load_query.context_status[j].fps;
1517 }
1518 if (msync((void *)p_device_context->p_device_info, sizeof(ni_device_info_t), MS_SYNC | MS_INVALIDATE))
1519 {
1520 char errmsg[NI_ERRNO_LEN] = {0};
1522 ni_log(NI_LOG_ERROR, "ERROR %s() msync() p_device_context->"
1523 "p_device_info: %s\n", __func__, errmsg);
1524 }
1525}
1526
1527
1528/*!******************************************************************************
1529 * \brief get PCIe address information from device name
1530 *
1531 * \param[in] char *device_name e.g. /dev/nvme0n1.
1532 * \param[out] char *pcie e.g. 0000:0a:00.0. Should be at least 13 bytes including null terminator
1533 * \param[out] char *domain, optional. Should be at least 5 bytes including null terminator
1534 * \param[out] char *slot, optional. Should be at least 3 bytes including null terminator
1535 * \param[out] char *dev, optional. Should be at least 3 bytes including null terminator
1536 * \param[out] char *func, optional. Should be at least 2 bytes including null terminator
1537 *
1538 * \return void
1539 * *******************************************************************************/
1540void get_dev_pcie_addr(char *device_name,
1541 char *pcie,
1542 char *domain, char *slot, char *dev, char *func)
1543{
1544#ifndef __linux__
1545 return;
1546#else
1547 int i=0;
1548 char *ptr = NULL;
1549 char path[PATH_MAX];
1550 int ret;
1551
1552 if (!device_name || !strstr(device_name, "/dev/nvme") || !pcie)
1553 {
1554 return ;
1555 }
1556
1557 char *start = device_name + 5;
1558
1559 (void)snprintf(path, sizeof(path), "/sys/block/%s", start);
1560 ni_log2(NULL, NI_LOG_DEBUG,"path:%s\n", path);
1561
1562 char target[PATH_MAX];
1563 const ssize_t len = readlink(path, target, sizeof(target) - 1);
1564 if (len == -1) {
1565 perror("readlink");
1566 return;
1567 }
1568 target[len] = '\0';
1569 ni_log2(NULL, NI_LOG_DEBUG,"target:%s\n", target);
1570
1571 char *saveptr = NULL;
1572 ptr = ni_strtok(target, "/", &saveptr);
1573 pcie[4] = pcie[7] = ':';
1574 pcie[10] = '.';
1575 while(ptr != NULL) {
1576 ni_log2(NULL, NI_LOG_DEBUG, "===%d ptr:%s\n", ++i, ptr);
1577 if (strlen(ptr) == PCI_BDF_STR_LEN)
1578 {
1579 ret = sscanf(ptr, "%4c:%2c:%2c.%1c", pcie, pcie+5,pcie+8,pcie+11);
1580 if (ret != 4)
1581 {
1582 char errmsg[NI_ERRNO_LEN] = {0};
1584 ni_log2(NULL, NI_LOG_DEBUG, "\tsscanf error %d errno %d %s\n", ret, errno, errmsg);
1585 }
1586 }
1587 ni_log2(NULL, NI_LOG_DEBUG, "=====\n");
1588 ptr = ni_strtok(NULL, "/", &saveptr);
1589 }
1590 pcie[PCI_BDF_STR_LEN] = '\0';
1591 ni_log2(NULL, NI_LOG_DEBUG, "PCIE:%s\n", pcie);
1592 if (!domain || !slot || !dev || !func)
1593 {
1594 goto end;
1595 }
1596 domain[4] = slot[2] = dev[2] = func[1] = '\0';
1597 (void)sscanf(pcie, "%4[^:]:%2[^:]:%2[^.].%1s", domain, slot, dev, func);
1598 ni_log2(NULL, NI_LOG_DEBUG, "\t%d: Domain: %s, Slot: %s, Device: %s, Function: %s\n", i, domain, slot, dev, func);
1599end:
1600 return;
1601#endif
1602}
1603
1604/*!******************************************************************************
1605 * \brief try to get lock for specified shared memory
1606 *
1607 * \param[in] const char *lck_name, specified lock name for shared memory
1608 * \param[in] int flags, open lock with specified flags
1609 * \param[in] const mode_t mode, open lock with specified mode
1610 * \param[out] int *lck_fd, Pointer to opened file handle for lock
1611 *
1612 * \return On success
1613 * NI_RETCODE_SUCCESS
1614 * On failure
1615 * NI_RETCODE_INVALID_PARAM
1616 * NI_RETCODE_FAILURE
1617 *******************************************************************************/
1618ni_retcode_t ni_rsrc_try_get_shm_lock(const char *lck_name,
1619 int flags,
1620 const mode_t mode,
1621 int *lck_fd)
1622{
1623 int lock = -1;
1624
1625 if (!lck_name || !lck_fd) {
1626 ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1628 }
1629
1630#ifdef _ANDROID
1631 if (0 != access(LOCK_DIR, F_OK)) {
1632 if (0 != mkdir(LOCK_DIR, S_IRWXU | S_IRWXG | S_IRWXO)) {
1633 ni_log(NI_LOG_ERROR, "ERROR: Could not mkdir : %s directory", LOCK_DIR);
1634 return NI_RETCODE_FAILURE;
1635 }
1636 }
1637#endif
1638
1639 char errmsg[NI_ERRNO_LEN] = {0};
1640 lock = open(lck_name, flags, mode);
1641 if (lock < 0) {
1643 ni_log(NI_LOG_ERROR, "ERROR: %s() open() %s fail: %s\n",
1644 __func__, lck_name, errmsg);
1645 return NI_RETCODE_FAILURE;
1646 }
1647
1648 int retry_cnt = 0;
1649 //use non blocking F_TLOCK in case broken instance has indefinitely locked it
1650 while (lockf(lock, F_TLOCK, 0) != 0)
1651 {
1652 retry_cnt++;
1653 ni_usleep(LOCK_WAIT); //10ms
1654 if (retry_cnt >= 900) //10s
1655 {
1657 ni_log(NI_LOG_ERROR, "ERROR %s() lockf() %s fail: %s\n", __func__, lck_name, errmsg);
1658 ni_log(NI_LOG_ERROR, "ERROR %s() If persists, stop traffic and run rm /dev/shm/NI_*\n", __func__);
1659 close(lock);
1660 return NI_RETCODE_FAILURE;
1661 }
1662 }
1663
1664 *lck_fd = lock;
1665
1666 return NI_RETCODE_SUCCESS;
1667}
1668
1669#if defined(__OPENHARMONY__)
1670static ni_retcode_t openharmony_open_shm(const char *shm_name,
1671 int shm_size,
1672 ni_rsrc_shm_state *state,
1673 int *shm_fd)
1674{
1675 int shm_id = -1;
1676 int flag = IPC_CREAT | IPC_EXCL;
1677 char shm_path[PATH_MAX];
1678
1679 if (!shm_name || !shm_fd) {
1680 ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1682 }
1683
1684 memset(shm_path, 0, PATH_MAX);
1685 snprintf(shm_path, PATH_MAX, "%s/%s", LOCK_DIR, shm_name);
1686
1687 char errmsg[NI_ERRNO_LEN] = {0};
1688 //If file not exist, create the file for ftok
1689 if (0 != access(shm_path, F_OK)) {
1690 int fd = open(shm_path, O_RDWR | O_CREAT | O_CLOEXEC,
1691 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1692 if (fd < 0) {
1694 ni_log(NI_LOG_ERROR, "ERROR: %s() open() %s fail: %s\n", __func__, shm_name, errmsg);
1695 return NI_RETCODE_FAILURE;
1696 }
1697
1698 close(fd);
1699 }
1700
1701 //create unique key for share memory
1702 key_t key = ftok(shm_path, PROJ_ID);
1703 if (key == -1) {
1705 ni_log(NI_LOG_ERROR, "ERROR: %s() ftok() fail: %s\n", __func__, errmsg);
1706 return NI_RETCODE_FAILURE;
1707 }
1708
1709 *state = NI_RSRC_SHM_IS_CREATED;
1710
1711 //create share memory
1712 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1713 shm_id = shmget(key, shm_size, mode | flag);
1714 if (shm_id < 0) {
1715 if (EEXIST == NI_ERRNO) {
1716 *state = NI_RSRC_SHM_IS_EXISTED;
1717 flag = IPC_CREAT;
1718 shm_id = shmget(key, shm_size, mode | flag);
1719 }
1720
1721 if (shm_id < 0) {
1723 ni_log(NI_LOG_ERROR, "ERROR: %s() shmget() fail: %s\n", __func__, errmsg);
1724 return NI_RETCODE_FAILURE;
1725 }
1726 }
1727 *shm_fd = shm_id;
1728
1729 return NI_RETCODE_SUCCESS;
1730}
1731
1732static ni_retcode_t openharmony_remove_shm(const char *shm_name,
1733 int shm_size)
1734{
1735 int shm_id = -1;
1736 char shm_path[PATH_MAX];
1737
1738 if (!shm_name) {
1739 ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1741 }
1742
1743 memset(shm_path, 0, PATH_MAX);
1744 snprintf(shm_path, PATH_MAX, "%s/%s", LOCK_DIR, shm_name);
1745
1746 //If file not exist, exit directly
1747 if (0 != access(shm_path, F_OK)) {
1748 return NI_RETCODE_SUCCESS;
1749 }
1750
1751 char errmsg[NI_ERRNO_LEN] = {0};
1752 //create unique key for share memory
1753 key_t key = ftok(shm_path, PROJ_ID);
1754 if (key == -1) {
1756 ni_log(NI_LOG_ERROR, "ERROR: %s() ftok() fail: %s\n", __func__, errmsg);
1757 return NI_RETCODE_FAILURE;
1758 }
1759
1760 //create share memory
1761 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
1762 shm_id = shmget(key, shm_size, mode);
1763 if (shm_id < 0) {
1765 ni_log(NI_LOG_ERROR, "ERROR: %s() shmget() fail: %s\n", __func__, errmsg);
1766 return NI_RETCODE_FAILURE;
1767 }
1768
1769 shmctl(shm_id, IPC_RMID, nullptr);
1770
1771 return NI_RETCODE_SUCCESS;
1772}
1773
1774#elif defined(_ANDROID)
1775static ni_retcode_t android_open_shm(const char *shm_name,
1776 int shm_size,
1777 ni_rsrc_shm_state *state,
1778 int *shm_fd)
1779{
1780 int shm_fd_tmp = -1;
1781
1782 if (!shm_name || !shm_fd) {
1783 ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1785 }
1786
1787 int ret = ni_rsrc_android_init();
1788 if (ret < 0) {
1789 ni_log(NI_LOG_ERROR, "ERROR: %s() failed to get android service\n", __func__);
1790 return NI_RETCODE_FAILURE;
1791 }
1792
1793 *state = NI_RSRC_SHM_IS_CREATED;
1794
1795 string param = shm_name;
1796 Return<void> retvalue =
1797 service->GetAppFlag(param, [&](int32_t ret, hidl_handle handle) {
1798 if (ret > 0) {
1799 *state = NI_RSRC_SHM_IS_EXISTED;
1800 shm_fd_tmp = dup(handle->data[0]);
1801 } else {
1802 ni_log(NI_LOG_ERROR, "ERROR: failed to get shm_fd when call GetAppFlag\n");
1803 }
1804 });
1805
1806 if (!retvalue.isOk()) {
1807 ni_log(NI_LOG_ERROR, "ERROR: %s() maybe something is wrong with Android service\n");
1808 return NI_RETCODE_FAILURE;
1809 }
1810
1811 if (shm_fd_tmp < 0) {
1812 int fd = ashmem_create_region(shm_name, shm_size);
1813 if (fd >= 0) {
1814 native_handle_t *native_handle = native_handle_create(1, 0);
1815 if (!native_handle) {
1816 close(fd);
1817 return NI_RETCODE_FAILURE;
1818 }
1819 native_handle->data[0] = fd;
1820
1821 hidl_handle handle;
1822 handle.setTo(native_handle, true);
1823 service->SetAppFlag(param, handle);
1824 shm_fd_tmp = dup(fd);
1825 } else {
1826 ni_log(NI_LOG_ERROR, "Could not create ashmem under Android\n");
1827 return NI_RETCODE_FAILURE;
1828 }
1829 }
1830 *shm_fd = shm_fd_tmp;
1831
1832 return NI_RETCODE_SUCCESS;
1833}
1834
1835static ni_retcode_t android_remove_shm(const char *shm_name,
1836 int shm_size)
1837{
1838 if (!shm_name) {
1839 ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1841 }
1842
1843 int ret = ni_rsrc_android_init();
1844 if (ret < 0) {
1845 ni_log(NI_LOG_ERROR, "ERROR: %s() failed to get android service\n", __func__);
1846 return NI_RETCODE_FAILURE;
1847 }
1848
1849 string param = shm_name;
1850 Return<void> retvalue = service->RemoveAppFlag(param);
1851 if (!retvalue.isOk()) {
1852 ni_log(NI_LOG_ERROR, "ERROR: %s() failed to remove shm\n", __func__);
1853 return NI_RETCODE_FAILURE;
1854 }
1855
1856 return NI_RETCODE_SUCCESS;
1857}
1858
1859static ni_retcode_t android_remove_all_shm()
1860{
1861 int ret = ni_rsrc_android_init();
1862 if (ret < 0) {
1863 ni_log(NI_LOG_ERROR, "ERROR: %s() failed to get android service\n", __func__);
1864 return NI_RETCODE_FAILURE;
1865 }
1866
1867 Return<void> retvalue = service->RemoveAllAppFlags();
1868 if (!retvalue.isOk()) {
1869 ni_log(NI_LOG_ERROR, "ERROR: %s() failed to remove all shm\n", __func__);
1870 return NI_RETCODE_FAILURE;
1871 }
1872
1873 return NI_RETCODE_SUCCESS;
1874}
1875
1876#else
1877namespace {
1878ni_retcode_t linux_open_shm(const char *shm_name,
1879 int shm_size,
1880 ni_rsrc_shm_state *state,
1881 int *shm_fd)
1882{
1883 int shm_fd_tmp = -1;
1884 const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1885 int flag = O_CREAT | O_EXCL | O_RDWR;
1886 bool skip_ftruncate = false;
1887
1888 if (!shm_name || !shm_fd) {
1889 ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1891 }
1892
1893 *state = NI_RSRC_SHM_IS_CREATED;
1894
1895 //create share memory
1896 shm_fd_tmp = shm_open(shm_name, flag, mode);
1897 if (shm_fd_tmp < 0) {
1898 if (EEXIST == NI_ERRNO) {
1899 skip_ftruncate = true;
1900 *state = NI_RSRC_SHM_IS_EXISTED;
1901 flag = O_RDWR;
1902 shm_fd_tmp = shm_open(shm_name, flag, mode);
1903 }
1904
1905 if (shm_fd_tmp < 0) {
1906 char errmsg[NI_ERRNO_LEN] = {0};
1908 ni_log(NI_LOG_ERROR, "ERROR: %s() %s shm_open() fail: %s\n",
1909 __func__, shm_name, errmsg);
1910 return NI_RETCODE_FAILURE;
1911 }
1912 }
1913
1914 //set share memory size
1915 if (!skip_ftruncate && ftruncate(shm_fd_tmp, shm_size) < 0) {
1916 close(shm_fd_tmp);
1917 shm_unlink(shm_name);
1918 return NI_RETCODE_FAILURE;
1919 }
1920
1921 *shm_fd = shm_fd_tmp;
1922
1923 return NI_RETCODE_SUCCESS;
1924}
1925} // namespace
1926#endif
1927
1928/*!******************************************************************************
1929 * \brief open shared memory for specified shm_name
1930 *
1931 * \param[in] const char *shm_name, specified shared memory name
1932 * \param[in] int shm_size, the size of shared memory
1933 * \param[out] ni_rsrc_shm_state *state, Pointer to the shared memory's state
1934 * if the shared memor isn't created, it will be created at first and
1935 * then open it, param "state" will be set to 0
1936 * if the shared memor has been created yet, only open it,
1937 * param "state" will be set to 1
1938 * \param[out] int *shm_fd, Pointer to opened file handle for shared memory
1939 *
1940 * \return On success
1941 * NI_RETCODE_SUCCESS
1942 * On failure
1943 * NI_RETCODE_INVALID_PARAM
1944 * NI_RETCODE_FAILURE
1945 *******************************************************************************/
1946ni_retcode_t ni_rsrc_open_shm(const char *shm_name,
1947 int shm_size,
1948 ni_rsrc_shm_state *state,
1949 int *shm_fd)
1950{
1951#if defined(__OPENHARMONY__)
1952 return openharmony_open_shm(shm_name, shm_size, state, shm_fd);
1953#elif defined(_ANDROID)
1954 return android_open_shm(shm_name, shm_size, state, shm_fd);
1955#else
1956 return linux_open_shm(shm_name, shm_size, state, shm_fd);
1957#endif
1958}
1959
1960/*!******************************************************************************
1961 * \brief map shared memory to the address space of the calling process
1962 *
1963 * \param[in] const char *shm_name, specified shared memory name
1964 * \param[in] int shm_fd, file handle for shared memory
1965 * \param[in] int shm_size, the size of shared memory
1966 * \param[out] int *shm_addr, pointer to the mapped area
1967 *
1968 * \return On success
1969 * NI_RETCODE_SUCCESS
1970 * On failure
1971 * NI_RETCODE_INVALID_PARAM
1972 * NI_RETCODE_FAILURE
1973 *******************************************************************************/
1974ni_retcode_t ni_rsrc_mmap_shm(const char *shm_name,
1975 int shm_fd,
1976 int shm_size,
1977 void **shm_addr)
1978{
1979 if (!shm_name || !shm_addr) {
1980 ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
1982 }
1983
1984 char errmsg[NI_ERRNO_LEN] = {0};
1985#ifdef __OPENHARMONY__
1986 *shm_addr = shmat(shm_fd, nullptr, 0);
1987 if ((void *)(-1) == *shm_addr) {
1989 ni_log(NI_LOG_ERROR, "%s(): %s shmat() fail: %s\n", __func__,
1990 shm_name, errmsg);
1991 return NI_RETCODE_FAILURE;
1992 }
1993#else
1994 *shm_addr = mmap(0, shm_size, PROT_READ | PROT_WRITE,
1995 MAP_SHARED, shm_fd, 0);
1996 if (MAP_FAILED == *shm_addr) {
1998 ni_log(NI_LOG_ERROR, "%s(): %s mmap() fail: %s\n", __func__,
1999 shm_name, errmsg);
2000 return NI_RETCODE_FAILURE;
2001 }
2002#endif
2003
2004 return NI_RETCODE_SUCCESS;
2005}
2006
2007/*!******************************************************************************
2008 * \brief do munmap for shared memory
2009 *
2010 * \param[in] int *shm_addr, pointer to the mapped area
2011 * \param[in] int shm_size, the size of shared memory
2012 *
2013 * \return On success
2014 * NI_RETCODE_SUCCESS
2015 * On failure
2016 * NI_RETCODE_INVALID_PARAM
2017 *******************************************************************************/
2018ni_retcode_t ni_rsrc_munmap_shm(void *shm_addr,
2019 int shm_size)
2020{
2021 if (!shm_addr) {
2022 ni_log(NI_LOG_ERROR, "ERROR: %s() input params is invalid\n", __func__);
2024 }
2025
2026#ifdef __OPENHARMONY__
2027 shmdt(shm_addr);
2028#else
2029 munmap(shm_addr, shm_size);
2030#endif
2031
2032 return NI_RETCODE_SUCCESS;
2033}
2034
2035/*!******************************************************************************
2036 * \brief delete shared memory
2037 *
2038 * \param[in] const char *shm_name, specified shared memory name
2039 * \param[in] int shm_size, the size of shared memory
2040 *
2041 * \return On success
2042 * NI_RETCODE_SUCCESS
2043 * On failure
2044 * NI_RETCODE_INVALID_PARAM
2045 * NI_RETCODE_FAILURE
2046 *******************************************************************************/
2047ni_retcode_t ni_rsrc_remove_shm(const char *shm_name,
2048 int shm_size)
2049{
2050 (void)shm_size;
2051#ifdef __OPENHARMONY__
2052 return openharmony_remove_shm(shm_name, shm_size);
2053#elif defined(_ANDROID)
2054 return android_remove_shm(shm_name, shm_size);
2055#else
2056 shm_unlink(shm_name);
2057#endif
2058
2059 return NI_RETCODE_SUCCESS;
2060}
2061
2062/*!******************************************************************************
2063 * \brief delete all shared memory
2064 *
2065 *
2066 * \return On success
2067 * NI_RETCODE_SUCCESS
2068 * On failure
2069 * NI_RETCODE_INVALID_PARAM
2070 * NI_RETCODE_FAILURE
2071 *******************************************************************************/
2072ni_retcode_t ni_rsrc_remove_all_shm()
2073{
2074 DIR *dir;
2075 struct dirent *dirent;
2076 char path_to_remove[PATH_MAX];
2077
2078 ni_log(NI_LOG_ERROR, "Deleting shared memory files in %s\n", LOCK_DIR);
2079
2080 char errmsg[NI_ERRNO_LEN] = {0};
2081 dir = opendir(LOCK_DIR);
2082 if (!dir) {
2084 ni_log(NI_LOG_ERROR, "ERROR: %s(): opendir failed for %s: %s\n",
2085 __func__, LOCK_DIR, errmsg);
2086 return NI_RETCODE_FAILURE;
2087 }
2088
2089 while ((dirent = readdir(dir)) != NULL) { // NOLINT(concurrency-mt-unsafe) - thread-local dir, no shared DIR*
2090 if (strncmp(dirent->d_name, "NI_", 3) != 0) {
2091 continue;
2092 }
2093
2094 (void)snprintf(path_to_remove, PATH_MAX, "%s/%s", LOCK_DIR, dirent->d_name);
2095
2096#ifndef _ANDROID
2097 if (strncasecmp(dirent->d_name, "NI_SHM", 6) == 0) {
2098#ifdef __OPENHARMONY__
2099 openharmony_remove_shm(dirent->d_name, 1); //for created share mem we can ignore size
2100#else
2101 shm_unlink(dirent->d_name);
2102#endif
2103 }
2104#endif
2105
2106 (void)remove(path_to_remove);
2107 }
2108
2109#ifdef _ANDROID
2110 android_remove_all_shm();
2111#endif
2112
2113 if (closedir(dir) == -1) {
2115 ni_log(NI_LOG_ERROR, "ERROR: %s(): closedir failed for %s: %s\n",
2116 __func__, LOCK_DIR, errmsg);
2117 return NI_RETCODE_FAILURE;
2118 }
2119
2120 ni_log(NI_LOG_INFO, "Deleted shared memory files in %s\n", LOCK_DIR);
2121
2122 return NI_RETCODE_SUCCESS;
2123}
2124
2125#endif
#define NI_XCODER_REVISION_API_MAJOR_VER_IDX
Definition ni_defs.h:99
#define NI_MAX_DEVICE_CNT
Definition ni_defs.h:235
#define END
Definition ni_defs.h:338
#define NI_XCODER_REVISION
Definition ni_defs.h:98
#define NI_MAX_DEVICE_NAME_LEN
Definition ni_defs.h:236
ni_device_type_t
Definition ni_defs.h:356
@ NI_DEVICE_TYPE_SCALER
Definition ni_defs.h:362
@ NI_DEVICE_TYPE_AI
Definition ni_defs.h:363
@ NI_DEVICE_TYPE_DECODER
Definition ni_defs.h:360
@ NI_DEVICE_TYPE_ENCODER
Definition ni_defs.h:361
@ NI_DEVICE_TYPE_XCODER_MAX
Definition ni_defs.h:364
#define NI_ERRNO
Definition ni_defs.h:229
#define GET_XCODER_DEVICE_TYPE(t)
Definition ni_defs.h:434
#define GET_XCODER_DEVICE_TYPE_STR(t)
Definition ni_defs.h:438
#define LRETURN
Definition ni_defs.h:337
ni_retcode_t
Definition ni_defs.h:447
@ NI_RETCODE_ERROR_LOCK_DOWN_DEVICE
Definition ni_defs.h:528
@ NI_RETCODE_FAILURE
Definition ni_defs.h:449
@ NI_RETCODE_SUCCESS
Definition ni_defs.h:448
@ NI_RETCODE_INVALID_PARAM
Definition ni_defs.h:450
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.
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...
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
ni_retcode_t ni_query_extra_info(ni_device_handle_t device_handle, ni_device_extra_info_t *p_dev_extra_info, uint8_t fw_rev[])
Query CompositeTemp from device.
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.
Public definitions for operating NETINT video processing devices for video processing.
#define NI_MIN_HEIGHT
#define NI_MIN_WIDTH
#define NI_PARAM_AV1_MAX_HEIGHT
@ NI_DEVICE_READ_ONLY
#define NI_PARAM_AV1_MAX_WIDTH
#define NI_MIN_RESOLUTION_WIDTH_JPEG
#define MAX_CHAR_IN_DEVICE_NAME
#define NI_MIN_RESOLUTION_HEIGHT_JPEG
Set host timestamp on Quadra NVMe controllers.
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
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition ni_log.c:183
Logging definitions.
#define NI_ERRNO_LEN
Definition ni_log.h:51
@ NI_LOG_DEBUG
Definition ni_log.h:64
@ NI_LOG_ERROR
Definition ni_log.h:62
@ NI_LOG_INFO
Definition ni_log.h:63
Private definitions for interfacing with NETINT video processing devices over NVMe.
int ni_nvme_enumerate_devices(char ni_devices[][NI_MAX_DEVICE_NAME_LEN], int max_handles)
void ni_rsrc_free_device_context(ni_device_context_t *p_device_context)
Free previously allocated device context.
Public definitions for managing NETINT video processing devices.
#define NI_LEVELS_SUPP_STR_LEN
Definition ni_rsrc_api.h:37
#define NI_PROFILES_SUPP_STR_LEN
Definition ni_rsrc_api.h:36
#define NI_ADDITIONAL_INFO_STR_LEN
Definition ni_rsrc_api.h:38
ni_sw_instance_status_t
Definition ni_rsrc_api.h:62
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_codec_t
Definition ni_rsrc_api.h:48
@ EN_JPEG
Definition ni_rsrc_api.h:53
@ EN_INVALID
Definition ni_rsrc_api.h:49
@ EN_AV1
Definition ni_rsrc_api.h:54
@ EN_H264
Definition ni_rsrc_api.h:50
@ EN_H265
Definition ni_rsrc_api.h:51
@ EN_CODEC_MAX
Definition ni_rsrc_api.h:55
@ EN_VP9
Definition ni_rsrc_api.h:52
Public definitions for managing NETINT video processing devices on Android.
android::sp< INidec > service
int ni_rsrc_android_init()
Init android net.int.SharedBuffer service for binder using.
#define PCIE_GEN4_LINK_SPEED
uint32_t g_xcoder_stop_process
void ni_rsrc_get_shm_name(ni_device_type_t device_type, int32_t guid, char *p_name, size_t max_name_len)
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)
ni_retcode_t ni_rsrc_create_retry_lck()
void ni_rsrc_get_lock_name(ni_device_type_t device_type, int32_t guid, char *p_name, size_t max_name_len)
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)
#define PCIE_ADDRS_MAX
int ni_rsrc_strcmp(const void *p_str, const void *p_str1)
#define PCI_BDF_STR_LEN
Private definitions used by ni_rsrc_api.cpp for management of NETINT video processing devices.
#define CODERS_LCK_NAME
void ni_rsrc_update_record(ni_device_context_t *p_device_context, ni_session_context_t *p_session_ctx)
#define CODERS_SHM_NAME
void ni_rsrc_get_one_device_info(ni_device_info_t *p_device_info)
#define LOCK_WAIT
#define LOCK_DIR
int ni_rsrc_enumerate_devices(char ni_devices[][NI_MAX_DEVICE_NAME_LEN], int max_handles)
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)
void get_dev_pcie_addr(char *device_name, char *pcie, char *domain, char *slot, char *dev, char *func)
ni_retcode_t ni_strncpy(char *dest, size_t dmax, const char *src, size_t slen)
Definition ni_util.c:525
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:4353
ni_retcode_t ni_strerror(char *dest, size_t dmax, int errnum)
Definition ni_util.c:663
char * ni_strtok(char *s, const char *delim, char **saveptr)
Definition ni_util.c:429
void ni_usleep(int64_t usec)
Definition ni_util.c:366
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:4383
Utility definitions.
device capability type
uint8_t xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
ni_hw_capability_t xcoder_devices[NI_MAX_DEVICES_PER_HW_INSTANCE]
uint8_t fw_branch_name[256]
ni_device_info_t * p_device_info
uint8_t fw_build_id[256]
uint8_t fw_commit_time[26]
uint8_t serial_number[20]
char dev_name[NI_MAX_DEVICE_NAME_LEN]
uint8_t fw_rev[8]
uint8_t fw_commit_hash[41]
char blk_name[NI_MAX_DEVICE_NAME_LEN]
ni_sw_instance_info_t sw_instance[NI_MAX_CONTEXTS_PER_HW_INSTANCE]
ni_device_type_t device_type
uint8_t fw_branch_name[256]
uint8_t model_number[40]
uint32_t active_num_inst
uint8_t fw_build_time[26]
ni_device_video_capability_t dev_cap[EN_CODEC_MAX]
int32_t xcoders[NI_DEVICE_TYPE_XCODER_MAX][NI_MAX_DEVICE_CNT]
Definition ni_rsrc_api.h:70
uint32_t xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
Definition ni_rsrc_api.h:69
char level[NI_LEVELS_SUPP_STR_LEN]
Definition ni_rsrc_api.h:82
char profiles_supported[NI_PROFILES_SUPP_STR_LEN]
Definition ni_rsrc_api.h:81
char additional_info[NI_ADDITIONAL_INFO_STR_LEN]
Definition ni_rsrc_api.h:83
hardware capability type
uint8_t max_number_of_contexts
ni_context_query_t context_status[NI_MAX_CONTEXTS_PER_HW_INSTANCE]
uint32_t fw_model_load
uint32_t current_load
uint32_t total_contexts
ni_load_query_t load_query
ni_sw_instance_status_t status
Definition ni_rsrc_api.h:89