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