35 #if __linux__ || __APPLE__
40 #include <sys/types.h>
46 #include <sys/syslimits.h>
53 static const char *ni_codec_format_str[] = {
"H.264",
"H.265",
"VP9",
"JPEG",
55 static const char *ni_dec_name_str[] = {
"h264_ni_quadra_dec",
"h265_ni_quadra_dec",
56 "vp9_ni_quadra_dec",
"jpeg_ni_quadra_dec"};
57 static const char *ni_enc_name_str[] = {
"h264_ni_quadra_enc",
"h265_ni_quadra_enc",
"empty",
58 "jpeg_ni_quadra_enc",
"av1_ni_quadra_enc"};
60 #ifndef DEPRECATION_AS_ERROR
68 static bool is_str_in_str_array(
const char key[],
74 for (i = 0; i < array_size; i++)
76 if (0 == strcmp(key, arr[i]))
93 for (
int xcoder_index_1 = 0;
115 "no, possible missing features" :
"yes");
132 for (
int xcoder_index_2 = 0;
164 int xcoder_dev_count = 0;
166 int curr_dev_count = 0;
169 char **xcoder_refresh_dev_names = NULL;
170 int xcoder_refresh_dev_count = 0;
192 ni_strcpy(xcoder_dev_names[i],
sizeof(xcoder_dev_names[i]),
213 if (xcoder_dev_count > 0)
215 xcoder_refresh_dev_names = (
char **)malloc(xcoder_dev_count *
217 for (i = 0; i < xcoder_dev_count; i++)
222 xcoder_refresh_dev_count = xcoder_dev_count;
226 xcoder_refresh_dev_names, xcoder_refresh_dev_count);
227 if (0 == curr_dev_count)
231 int devices_removed = 0;
232 int devices_added = 0;
234 for (i = 0; i < xcoder_dev_count; i++)
236 if (!is_str_in_str_array(xcoder_dev_names[i], curr_dev_names,
240 "\n\n%d. %s NOT in current scanned list, removing !\n", i,
241 xcoder_dev_names[i]);
246 xcoder_dev_names[i]);
251 xcoder_dev_names[i]);
257 for (i = 0; i < curr_dev_count; i++)
259 if (!is_str_in_str_array(curr_dev_names[i], xcoder_dev_names,
276 if (devices_added != devices_removed)
280 for (i = 0; i < xcoder_dev_count; i++)
284 for (i = 0; i < curr_dev_count; i++)
289 if (xcoder_refresh_dev_names) {
290 for (i = 0; i < xcoder_refresh_dev_count; i++)
291 free(xcoder_refresh_dev_names[i]);
292 free(xcoder_refresh_dev_names);
293 xcoder_refresh_dev_names = NULL;
302 android::sp<INidec>
service = NULL;
316 service = INidec::tryGetService();
330 #ifndef DEPRECATION_AS_ERROR
351 if ((ni_devices == NULL)||(max_handles == 0))
377 int max_handles,
char **xcoder_refresh_dev_names,
378 int xcoder_refresh_dev_count)
380 if ((ni_devices == NULL)||(max_handles == 0))
399 HANDLE map_file_handle = NULL;
400 HANDLE mutex_handle = NULL;
403 mutex_handle = CreateMutex(NULL,
408 if (NULL == mutex_handle)
415 if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
420 map_file_handle = OpenFileMapping(
426 if (NULL == map_file_handle)
428 ReleaseMutex(mutex_handle);
442 if (NULL == p_device_queue)
444 ReleaseMutex(mutex_handle);
445 CloseHandle(map_file_handle);
450 if (NULL == p_device_pool)
456 UnmapViewOfFile(p_device_queue);
460 p_device_pool->
lock = mutex_handle;
464 ReleaseMutex(mutex_handle);
465 CloseHandle(map_file_handle);
466 return p_device_pool;
487 int ni_rsrc_init(
int should_match_rev,
int timeout_seconds)
491 int number_of_devices = 0;
492 uint32_t runtime = 0;
493 while (0 == number_of_devices)
503 else if (0 == number_of_devices)
511 if (timeout_seconds == 0) {
513 "and exit without wait\n");
518 if (runtime >= (uint32_t)timeout_seconds)
552 char shm_name[32] = { 0 };
553 char lck_name[32] = { 0 };
556 HANDLE map_file_handle = NULL;
557 HANDLE mutex_handle = NULL;
563 mutex_handle = CreateMutex(NULL,
567 if (NULL == mutex_handle)
570 p_device_context = NULL;
574 if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
577 "obtain mutex: %p\n", mutex_handle);
580 map_file_handle = OpenFileMapping(
586 if (NULL == map_file_handle)
590 p_device_context = NULL;
602 if (NULL == p_device_queue)
607 p_device_context = NULL;
612 if (NULL == p_device_context)
618 p_device_context = NULL;
623 p_device_context->
lock = mutex_handle;
628 if (NULL == p_device_context)
630 if (NULL != p_device_queue)
632 UnmapViewOfFile(p_device_queue);
634 if (NULL != mutex_handle)
636 ReleaseMutex(mutex_handle);
637 CloseHandle(mutex_handle);
640 if (NULL != map_file_handle)
642 CloseHandle(map_file_handle);
646 ReleaseMutex(mutex_handle);
647 CloseHandle(map_file_handle);
650 return p_device_context;
653 #elif __linux__ || __APPLE__
655 #define DEV_NAME_PREFIX "rdisk"
656 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
657 #define DEV_NAME_PREFIX "vd"
659 #define DEV_NAME_PREFIX "nvme"
662 #ifndef DEPRECATION_AS_ERROR
681 #if defined(_ANDROID) || defined(__OPENHARMONY__)
682 #define ANDROID_MAX_DIR_NUM 2
683 int android_dir_num = 0;
684 const char* dir_name_array[ANDROID_MAX_DIR_NUM];
685 dir_name_array[0] =
"/dev";
686 dir_name_array[1] =
"/dev/block";
688 const char* dir_name =
"/dev";
690 int i, xcoder_device_cnt = 0;
692 struct dirent* in_file;
695 ni_device_handle_t dev_handle = NI_INVALID_DEVICE_HANDLE;
699 if ((ni_devices == NULL)||(max_handles == 0))
705 int nvme_dev_cnt = 0;
711 const char *pattern =
"^rdisk[0-9]+$";
712 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
713 const char *pattern =
"^vd[a-z]$";
715 const char *pattern =
"^nvme[0-9]+(c[0-9]+)?n[0-9]+$";
718 if(regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB)) {
723 #if defined(_ANDROID) || defined(__OPENHARMONY__)
726 while(xcoder_device_cnt == 0 && android_dir_num < ANDROID_MAX_DIR_NUM)
728 const char *dir_name = dir_name_array[android_dir_num];
733 dev_handle = NI_INVALID_DEVICE_HANDLE;
735 size_t size_of_nvme_devices_x =
sizeof(nvme_devices)/
sizeof(nvme_devices[0]);
736 for(
size_t dimx = 0; dimx < size_of_nvme_devices_x; ++dimx)
738 memset(nvme_devices[dimx], 0,
sizeof(nvme_devices[0]));
743 if (NULL == (FD = opendir(dir_name)))
746 #if defined(_ANDROID) || defined(__OPENHARMONY__)
748 if(android_dir_num < ANDROID_MAX_DIR_NUM)
762 while ((in_file = readdir(FD)))
765 if (!strcmp(in_file->d_name,
".") || !strcmp(in_file->d_name,
".."))
772 if (!strncmp(in_file->d_name, DEV_NAME_PREFIX, strlen(DEV_NAME_PREFIX)))
774 if (nvme_dev_cnt < 200)
776 int write_len = snprintf(nvme_devices[nvme_dev_cnt],
778 dir_name, in_file->d_name);
782 "ERROR: failed to copy device %d name %s\n",
783 nvme_dev_cnt, in_file->d_name);
788 skip_this = regexec(®ex, in_file->d_name, 0, NULL, 0);
795 "%s/%s", dir_name, in_file->d_name) < 0)
798 "ERROR: failed an snprintf() in "
799 "ni_rsrc_get_local_device_list()\n");
827 if (NI_INVALID_DEVICE_HANDLE != dev_handle)
831 &device_capabilites);
834 if (is_supported_xcoder(
837 ni_devices[xcoder_device_cnt][0] =
'\0';
850 (max_handles <= xcoder_device_cnt))
853 "Disregarding some Netint devices on system over "
854 "limit of NI_MAX_DEVICE_CNT(%d) or max_handles(%d)\n",
861 #if defined(_ANDROID) || defined(__OPENHARMONY__)
869 if (0 == xcoder_device_cnt)
871 ni_log(
NI_LOG_INFO,
"Found %d NVMe devices on system, none of them xcoder\n", nvme_dev_cnt);
872 for (i = 0; i < nvme_dev_cnt; i++)
880 return xcoder_device_cnt;
901 int max_handles,
char **xcoder_refresh_dev_names,
902 int xcoder_refresh_dev_count)
906 #define ANDROID_MAX_DIR_NUM 2
907 int android_dir_num = 0;
908 const char* dir_name_array[ANDROID_MAX_DIR_NUM];
909 dir_name_array[0] =
"/dev";
910 dir_name_array[1] =
"/dev/block";
912 const char* dir_name =
"/dev";
914 int i, xcoder_device_cnt = 0;
916 struct dirent* in_file;
919 ni_device_handle_t dev_handle = NI_INVALID_DEVICE_HANDLE;
921 bool device_in_ctxt =
false;
923 if ((ni_devices == NULL)||(max_handles == 0))
929 int nvme_dev_cnt = 0;
935 const char *pattern =
"^rdisk[0-9]+$";
936 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
937 const char *pattern =
"^vd[a-z]$";
939 const char *pattern =
"^nvme[0-9]+(c[0-9]+)?n[0-9]+$";
942 if(regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB)) {
950 while(xcoder_device_cnt == 0 && android_dir_num < ANDROID_MAX_DIR_NUM)
952 const char *dir_name = dir_name_array[android_dir_num];
956 device_in_ctxt =
false;
957 dev_handle = NI_INVALID_DEVICE_HANDLE;
959 size_t size_of_nvme_devices_x =
sizeof(nvme_devices)/
sizeof(nvme_devices[0]);
960 for(
size_t dimx = 0; dimx < size_of_nvme_devices_x; ++dimx)
962 memset(nvme_devices[dimx], 0,
sizeof(nvme_devices[0]));
967 if (NULL == (FD = opendir(dir_name)))
972 if(android_dir_num < ANDROID_MAX_DIR_NUM)
986 while ((in_file = readdir(FD)))
989 if (!strcmp(in_file->d_name,
".") || !strcmp(in_file->d_name,
".."))
996 if (!strncmp(in_file->d_name, DEV_NAME_PREFIX, strlen(DEV_NAME_PREFIX)))
998 if (nvme_dev_cnt < 200)
1000 int write_len = snprintf(nvme_devices[nvme_dev_cnt],
1002 dir_name, in_file->d_name);
1006 "ERROR: failed to copy device %d name %s\n",
1007 nvme_dev_cnt, in_file->d_name);
1012 skip_this = regexec(®ex, in_file->d_name, 0, NULL, 0);
1019 "%s/%s", dir_name, in_file->d_name) < 0)
1022 "ERROR: failed an snprintf() in "
1023 "ni_rsrc_get_local_device_list2()\n");
1030 device_in_ctxt =
false;
1031 for (
int j = 0; j < xcoder_refresh_dev_count; j++)
1035 xcoder_refresh_dev_names[j]))
1037 device_in_ctxt =
true;
1051 if (NI_INVALID_DEVICE_HANDLE != dev_handle)
1054 &device_capabilites, device_in_ctxt);
1057 if (is_supported_xcoder(
1060 ni_devices[xcoder_device_cnt][0] =
'\0';
1063 xcoder_device_cnt++;
1072 (max_handles <= xcoder_device_cnt))
1075 "Disregarding some Netint devices on system over "
1076 "limit of NI_MAX_DEVICE_CNT(%d) or max_handles(%d)\n",
1091 if (0 == xcoder_device_cnt)
1093 ni_log(
NI_LOG_INFO,
"Found %d NVMe devices on system, none of them xcoder\n", nvme_dev_cnt);
1094 for (i = 0; i < nvme_dev_cnt; i++)
1100 return xcoder_device_cnt;
1113 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1114 int flags = O_RDWR | O_CLOEXEC;
1115 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1117 ni_lock_handle_t lock;
1121 flags, mode, (
int *)&lock) < 0) {
1129 (
int *)&shm_fd) < 0) {
1137 (
void **)&p_device_queue)) < 0) {
1143 if (! p_device_pool) {
1150 p_device_pool->
lock = lock;
1155 lockf(lock, F_ULOCK, 0);
1157 if (NULL == p_device_pool) {
1161 #ifndef __OPENHARMONY__
1167 return p_device_pool;
1188 int ni_rsrc_init(
int should_match_rev,
int timeout_seconds)
1191 char api_version[5];
1192 int number_of_devices;
1194 int limit_depth = 3;
1203 if (number_of_devices > 0)
1215 if (timeout_seconds == 0) {
1217 "and exit without wait\n");
1222 if (runtime >= (uint32_t)timeout_seconds)
1225 "Timeout exceeded/reached after %u seconds!\n",
1236 ret =
ni_rsrc_init_priv(should_match_rev, number_of_devices, device_names, limit_depth);
1269 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1271 int flags = O_RDWR | O_CLOEXEC;
1272 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1273 char shm_name[32] = { 0 };
1274 char lck_name[32] = { 0 };
1281 if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, &lock) < 0) {
1286 if (ni_rsrc_open_shm(shm_name,
1289 (
int *)&shm_fd) < 0) {
1294 if ((ni_rsrc_mmap_shm(shm_name,
1297 (
void **)&p_device_queue)) < 0) {
1303 if (!p_device_context) {
1313 p_device_context->
lock = lock;
1317 lockf(lock, F_ULOCK, 0);
1319 #ifndef __OPENHARMONY__
1325 return p_device_context;
1338 if (p_device_context)
1342 ReleaseMutex(p_device_context->
lock);
1343 #elif __linux__ || __APPLE__
1344 close(p_device_context->
lock);
1348 free(p_device_context);
1374 bool b_release_pool_mtx =
false;
1376 if ( (NULL == p_device_info) || (NULL == p_device_count) )
1383 if (NULL == p_device_pool)
1390 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
1393 "mutex: %p\n", p_device_pool->
lock);
1397 #elif __linux__ || __APPLE__
1398 lockf(p_device_pool->
lock, F_LOCK, 0);
1401 b_release_pool_mtx =
true;
1404 count = p_device_queue->
xcoder_cnt[device_type];
1407 for (i = 0; i < count; i++)
1410 guid = p_device_queue->
xcoders[device_type][i];
1412 if (p_device_context)
1415 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1418 "mutex: %p\n", p_device_context->
lock);
1419 ReleaseMutex(p_device_pool->
lock);
1425 ReleaseMutex(p_device_context->
lock);
1426 #elif __linux__ || __APPLE__
1427 lockf(p_device_context->
lock, F_LOCK, 0);
1429 lockf(p_device_context->
lock, F_ULOCK, 0);
1434 (*p_device_count)++;
1444 if (b_release_pool_mtx)
1447 ReleaseMutex(p_device_pool->
lock);
1448 #elif __linux__ || __APPLE__
1449 lockf(p_device_pool->
lock, F_ULOCK, 0);
1476 if (NULL == p_device)
1526 if (list_uninitialized)
1533 if (!list_uninitialized)
1545 for (
int dev_index = 0;
1559 ni_device_handle_t fd;
1561 for (
int dev_index = 0; dev_index < dev_count; dev_index++)
1563 if (is_str_in_str_array(dev_names[dev_index],
1570 if (NI_INVALID_DEVICE_HANDLE == fd)
1573 dev_names[dev_index]);
1582 dev_names[dev_index]);
1590 p_dev_info = &p_device->
xcoders[dev_type][dev_index];
1596 sizeof(capability.
fw_rev));
1645 " Operations: Crop (ni_quadra_crop), Scale (ni_quadra_scale), Pad "
1646 "(ni_quadra_pad), Overlay (ni_quadra_overlay)\n"
1647 " Drawbox (ni_quadra_drawbox), Rotate (ni_quadra_rotate), XStack (ni_quadra_xstack)\n");
1653 " Operations: ROI (ni_quadra_roi), Background Replace (ni_quadra_bg)\n");
1663 ni_codec_format_str[p_device_info->
dev_cap[i]
1668 ni_dec_name_str[p_device_info->
dev_cap[i]
1670 ni_enc_name_str[p_device_info->
dev_cap[i]
1783 if (NULL == p_device_context)
1789 if (NULL == p_device_info)
1795 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1798 "mutex: %p\n", p_device_context->
lock);
1799 free(p_device_info);
1804 ReleaseMutex(p_device_context->
lock);
1806 lockf(p_device_context->
lock, F_LOCK, 0);
1810 lockf(p_device_context->
lock, F_ULOCK, 0);
1817 return p_device_info;
1852 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
1855 __FUNCTION__, p_device_pool->
lock);
1859 #elif __linux__ || __APPLE__
1860 lockf(p_device_pool->
lock, F_LOCK, 0);
1865 for (i = 0; i < num_coders; i++)
1870 if (p_device_context &&
1882 ReleaseMutex(p_device_pool->
lock);
1883 #elif __linux__ || __APPLE__
1884 lockf(p_device_pool->
lock, F_ULOCK, 0);
1911 if (!p_device_context || !sw_instance_info)
1918 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1921 __func__, p_device_context->
lock);
1924 #elif __linux__ || __APPLE__
1925 lockf(p_device_context->
lock, F_LOCK, 0);
1930 for (i = 0; i < sw_instance_cnt; i++)
1936 ReleaseMutex(p_device_context->
lock);
1937 #elif __linux__ || __APPLE__
1938 lockf(p_device_context->
lock, F_ULOCK, 0);
1968 return p_device_context;
1987 (void) p_device_context;
1992 if (!p_device_context)
1999 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
2002 __func__, p_device_context->
lock);
2004 #elif __linux__ || __APPLE__
2005 lockf(p_device_context->
lock, F_LOCK, 0);
2010 ni_log(
NI_LOG_INFO,
"Warning: releasing resource load %lu > current load %lu\n", load,
2018 #if __linux__ || __APPLE__
2024 "p_device_info: %s\n", __func__, errmsg);
2030 ReleaseMutex(p_device_context->
lock);
2031 #elif __linux__ || __APPLE__
2032 lockf(p_device_context->
lock, F_ULOCK, 0);
2053 bool b_release_pool_mtx =
false;
2072 session_ctx.
hw_id = guid;
2111 if (WAIT_ABANDONED ==
2112 WaitForSingleObject(p_device_pool->
lock,
2116 "ERROR: ni_rsrc_list_devices() failed to obtain mutex: %p\n",
2117 p_device_pool->
lock);
2122 lockf(p_device_pool->
lock, F_LOCK, 0);
2124 b_release_pool_mtx =
true;
2141 if (NI_INVALID_EVENT_HANDLE == session_ctx.
event_handle)
2152 "guid %d. %s is not avaiable, type: %d, retval:%d\n",
2154 device_type, retval);
2174 "vpu recovery happened on guid %d. %s, retry "
2185 "session open error guid %d. %s, type: %d, "
2188 device_type, retval);
2198 "Error get device resource: guid %d, device_ctx %p\n", guid,
2205 if (b_release_pool_mtx)
2208 ReleaseMutex(p_device_pool->
lock);
2210 lockf(p_device_pool->
lock, F_ULOCK, 0);
2235 #if __linux__ || __APPLE__
2241 unsigned int guid_index_i, guid_index_j, ui_device_type;
2266 rValue = WaitForSingleObject(p_device_pool->
lock, INFINITE);
2267 if (rValue != WAIT_OBJECT_0)
2270 "ERROR: %s() Failed to obtain mutex %p\n",
2272 p_device_pool->
lock);
2276 #elif __linux__ || __APPLE__
2277 lockf(p_device_pool->
lock, F_LOCK, 0);
2287 guid = p_device_queue->
xcoders[ui_device_type][guid_index_i];
2294 if (!p_device_context)
2297 "ERROR: %s() Failed to obtain device context for "
2298 "%s with GUID %u! Undefined behavior!\n",
2313 "ERROR: %s() Devicename format mismatch %s %s\n",
2321 CloseHandle(p_device_context->
lock);
2322 #elif __linux__ || __APPLE__
2326 "%s %s %s deleted\n",
2335 "ERROR: %s(): %s %s %s failed to delete %s\n",
2347 #if __linux__ || __APPLE__
2349 if (!unlink(lck_name))
2352 "%s %s %s deleted\n",
2361 "ERROR: %s(): %s %s %s failed to delete %s\n",
2376 p_device_queue->
xcoders[ui_device_type][guid_index_i] = -1;
2377 p_device_queue->
xcoder_cnt[ui_device_type]--;
2388 memset(guids, -1,
sizeof(guids));
2392 guid = p_device_queue->
xcoders[ui_device_type][guid_index_i];
2395 guids[guid_index_j] = guid;
2397 if (guid_index_j == p_device_queue->
xcoder_cnt[ui_device_type])
2403 memcpy(p_device_queue->
xcoders[ui_device_type], guids,
sizeof(guids));
2406 #if __linux__ || __APPLE__
2408 if (!msync((
void *)p_device_queue,
2410 MS_SYNC|MS_INVALIDATE))
2418 "ERROR: %s(): msync() failed to delete %s: %s\n",
2428 ReleaseMutex(p_device_pool->
lock);
2429 #elif __linux__ || __APPLE__
2430 lockf(p_device_pool->
lock, F_ULOCK, 0);
2436 return return_value;
2451 int xcoder_dev_count = 0;
2479 xcoder_dev_names[i]);
2485 "%d devices retrieved from current pool at start up\n",
2489 "%d devices retrieved from current pool at start up\n",
2500 for (i = 0; i < xcoder_dev_count; i++)
2503 xcoder_dev_names[i]);
2508 xcoder_dev_names[i]);
2512 xcoder_dev_names[i]);
2516 #if __linux__ || __APPLE__
2528 if (0 == unlink(XCODERS_RETRY_LCK_NAME[i]))
2531 i, XCODERS_RETRY_LCK_NAME[i]);
2536 i, XCODERS_RETRY_LCK_NAME[i]);
2568 uint32_t i, existing_number_of_devices;
2589 if (WAIT_ABANDONED == WaitForSingleObject(device_pool->
lock, INFINITE))
2592 "ERROR: %s(): Failed to obtain lock %p\n",
2597 #elif __linux__ || __APPLE__
2598 lockf(device_pool->
lock, F_LOCK, 0);
2605 existing_number_of_devices = device_queue->
xcoder_cnt[device_type];
2610 "ERROR: %s(): Limit of NI_MAX_DEVICE_CNT(%d) existing Quadra "
2611 "devices previously reached. Not adding %s.\n",
2619 for (i = 0; i < existing_number_of_devices; i++)
2623 device_queue->
xcoders[device_type][i]);
2630 "ERROR: %s(): %s already exists in resource pool\n",
2649 ReleaseMutex(device_pool->
lock);
2650 #elif __linux__ || __APPLE__
2651 lockf(device_pool->
lock, F_ULOCK, 0);
2668 if (NI_INVALID_LOCK_HANDLE != p_device_pool->
lock)
2671 CloseHandle(p_device_pool->
lock);
2672 #elif __linux__ || __APPLE__
2673 close(p_device_pool->
lock);
2683 free(p_device_pool);
2702 *lock = CreateMutex(NULL, FALSE, XCODERS_RETRY_LCK_NAME[device_type]);
2708 __func__, XCODERS_RETRY_LCK_NAME[device_type],
2717 open(XCODERS_RETRY_LCK_NAME[device_type], O_RDWR | O_CLOEXEC);
2739 DWORD ret = WaitForSingleObject(*lock, 1);
2740 if (WAIT_OBJECT_0 == ret)
2743 }
else if (WAIT_TIMEOUT != ret)
2750 status = lockf(*lock, F_LOCK, 0);
2767 while (status != 0);
2782 if (lock == NI_INVALID_LOCK_HANDLE)
2788 ni_lock_handle_t status = NI_INVALID_LOCK_HANDLE;
2796 if (ReleaseMutex(lock))
2798 status = (ni_lock_handle_t)(0);
2801 status = lockf(lock, F_ULOCK, 0);
2814 }
while (status != (ni_lock_handle_t)(0));
2820 #endif //_WIN32 defined
2858 char cmd[128] = {0};
2859 char cmd_ret[64] = {0};
2865 ptr = device_name + 5;
2866 snprintf(cmd,
sizeof(cmd) - 1,
"cat /sys/block/%s/device/*/numa_node",ptr);
2867 cmd_fp = popen(cmd,
"r");
2872 if (fgets(cmd_ret,
sizeof(cmd_ret)/
sizeof(cmd_ret[0]), cmd_fp) == 0)
2874 goto get_numa_node_ret;
2876 ret =
atoi(cmd_ret);
2884 static int int_cmp(
const void *a,
const void *b)
2886 const int *ia = (
const int *)a;
2887 const int *ib = (
const int *)b;
2888 return (*ia == *ib) ? 0 : ((*ia > *ib) ? 1 : -1);
2892 static int ni_hw_device_info_quadra_threshold_param_t_compare(
const void *pl,
const void *pr)
2915 int factor_8_10 = 1;
2916 uint32_t resolution = decoder_param->
h * decoder_param->
w;
2921 return resolution >= 1920*1080 ?
2922 (int)(((uint64_t)(resolution)*(uint64_t)(decoder_param->
fps)*(uint64_t)(factor_8_10)*100)/1440/1920/1080) :
2923 (
int)((uint64_t)(resolution)*(uint64_t)(decoder_param->
fps)*(uint64_t)(factor_8_10)*100/2880/1280/720);
2937 double factor = 1.0;
2938 double factor_codec = 1.0;
2939 double factor_rdoq = 1.0;
2940 double factor_rdoLevel = 1.0;
2941 double factor_lookahead = 1.0;
2942 double factor_8_10_bit = 1.0;
2943 double factor_720p = 1.0;
2945 int resolution = (int)(encoder_param->
w * encoder_param->
h);
2950 factor_codec = 0.67;
2962 factor_rdoLevel = (encoder_param->
rdoLevel == 2) ? 1.91 : 3.28;
2967 factor_lookahead = (double)(encoder_param->
lookaheadDepth * 0.0014 + 1.012);
2973 factor_8_10_bit = 2;
2976 factor_720p = 1.125;
2977 factor = factor_codec * factor_8_10_bit * factor_rdoq * factor_rdoLevel
2978 * factor_lookahead * factor_720p;
2984 ((uint32_t)((uint32_t)factor*encoder_param->
fps * resolution)) /
2985 ((3840 * 2160 * 60ULL) / 100 * 4));
3000 static int check_hw_info_shared_mem_calculate_b_scale(
int h,
int w,
int bit_8_10,
int rgba)
3002 const int stride = 128;
3003 int estimated_yuv_size = rgba ?
3006 ( ((w + stride - 1)/stride)*stride + ((w/2 + stride - 1)/stride)*stride ) * h:
3007 ( ((w * 2 + stride - 1)/stride)*stride + ((w + stride - 1)/stride)*stride ) * h;
3008 const int b_unit = 1601536;
3009 int b_scale = (estimated_yuv_size + b_unit -1) / b_unit;
3041 const int v32_ofCores_calculate = 0;
3043 int b_counts = (int)(v32_ofCores_calculate +
3046 (encoder_param->
uploader ? 1 : 0) * 3 +
3048 int b_scale = check_hw_info_shared_mem_calculate_b_scale(encoder_param->
h, encoder_param->
w,
3050 return b_scale * b_counts;
3074 const int hw_frame = decoder_param->
hw_frame;
3076 const int v30_xlsx = 0;
3077 int b_counts = 1 * (v30_xlsx +
3078 (hw_frame ? 0 : 1)*3 +
3080 int b_scale = check_hw_info_shared_mem_calculate_b_scale(decoder_param->
h, decoder_param->
w,
3082 return b_scale * b_counts;
3109 const int v30_xlsx = 0;
3110 int b_counts = 1 * (v30_xlsx +
3113 int b_scale = check_hw_info_shared_mem_calculate_b_scale(scaler_param->
h, scaler_param->
w,
3115 return b_scale * b_counts;
3133 const int total = 2456;
3134 int task_mem_usage = 0;
3135 int task_mem_precentage = 0;
3141 for(i = 0; i < card_num; ++i)
3150 task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16);
3154 task_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param);
3158 task_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3162 int decoder_shared_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16);
3163 int encoder_shared_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param);
3164 int scaler_shared_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3165 task_mem_usage = decoder_shared_mem_usage + ((encoder_shared_mem_usage > scaler_shared_mem_usage) ?
3166 encoder_shared_mem_usage : scaler_shared_mem_usage);
3171 task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16) +
3172 check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param)+
3173 check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3176 task_mem_precentage = 100 * task_mem_usage / total;
3178 if(task_mem_precentage > 90)
3181 task_mem_precentage = 90;
3184 for(i = 0;i<card_num;++i)
3186 if(card_remove[i] == 1)
3211 if(p_coder_param == NULL)
3213 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_coder_param\n");
3214 return p_coder_param;
3223 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3224 free(p_coder_param);
3225 p_coder_param = NULL;
3226 return p_coder_param;
3234 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3235 free(p_coder_param);
3236 p_coder_param = NULL;
3237 return p_coder_param;
3245 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3246 free(p_coder_param);
3247 p_coder_param = NULL;
3248 return p_coder_param;
3254 if(p_coder_param->
ai_param == NULL)
3256 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3257 free(p_coder_param);
3258 p_coder_param = NULL;
3259 return p_coder_param;
3267 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3268 free(p_coder_param);
3269 p_coder_param = NULL;
3270 return p_coder_param;
3275 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3278 free(p_coder_param);
3279 p_coder_param = NULL;
3280 return p_coder_param;
3285 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3290 free(p_coder_param);
3291 p_coder_param = NULL;
3292 return p_coder_param;
3295 if(p_coder_param->
ai_param == NULL)
3297 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3304 free(p_coder_param);
3305 p_coder_param = NULL;
3306 return p_coder_param;
3346 return p_coder_param;
3362 if(p_hw_device_info_quadra_coder_param == NULL)
3378 free(p_hw_device_info_quadra_coder_param->
scaler_param);
3379 p_hw_device_info_quadra_coder_param->
scaler_param = NULL;
3381 if(p_hw_device_info_quadra_coder_param->
ai_param)
3383 free(p_hw_device_info_quadra_coder_param->
ai_param);
3384 p_hw_device_info_quadra_coder_param->
ai_param = NULL;
3386 free(p_hw_device_info_quadra_coder_param);
3403 if(!p_hw_device_info)
3405 ni_log(
NI_LOG_ERROR,
"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t\n");
3406 goto p_hw_device_info_end;
3413 ni_log(
NI_LOG_ERROR,
"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t->device_type\n");
3414 goto device_type_end;
3432 if(p_hw_device_info->
card_info[i] == NULL)
3435 goto card_info_i_end;
3439 return p_hw_device_info;
3456 free(p_hw_device_info);
3457 p_hw_device_info = NULL;
3458 p_hw_device_info_end:
3473 if(!p_hw_device_info)
3486 free(p_hw_device_info);
3503 int should_match_rev = 1;
3504 int module_count = 1;
3506 int32_t *module_id_arr = NULL;
3512 int *card_remove = NULL;
3515 uint64_t decoder_need_load = 0;
3516 uint64_t encoder_need_load = 0;
3519 int hw_info_param_num = hw_mode ? 4 : 1;
3520 int device_type_num = 1;
3521 const int all_device_type_num = 4;
3529 bool b_valid =
false;
3537 if(!pointer_to_p_hw_device_info)
3539 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: pointer_to_p_hw_device_info is NULL.\n");
3543 if(*pointer_to_p_hw_device_info)
3545 p_hw_device_info = *pointer_to_p_hw_device_info;
3557 }
else if(hw_mode && hw_mode != coder_param->
hw_mode)
3559 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: hw_mode = %d, coder_param->hw_mode = %d\n",
3560 hw_mode,coder_param->
hw_mode);
3566 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_ENCODER but coder_param->encoder_param == NULL\n");
3571 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_DECODER but coder_param->decoder_param == NULL\n");
3576 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_SCALER but coder_param->scaler_param == NULL\n");
3581 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_AI but coder_param->ai_param == NULL\n");
3587 if((task_mode != 0 && task_mode != 1) ||
3596 task_mode, preferential_device_type);
3600 if(!hw_info_threshold_param)
3606 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: hw_info_threshold_param is NULL.\n");
3609 for(i = 0;i < hw_info_param_num; ++i)
3611 if(hw_info_threshold_param[i].load_threshold < 0||
3612 hw_info_threshold_param[i].load_threshold > 100 ||
3613 hw_info_threshold_param[i].task_num_threshold < 0 ||
3624 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: In %s, hw_info_threshold_param[%d].device_type = %d, hw_info_threshold_param[%d].load_threshold = %d, hw_info_threshold_param[%d].task_num_threshold = %d\n",
3625 (hw_mode ?
"hardware_mode":
"software_mode"), i, hw_info_threshold_param[i].device_type, i, hw_info_threshold_param[i].load_threshold, i, hw_info_threshold_param[i].task_num_threshold);
3680 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
3685 #elif defined(__linux__)
3686 if (lockf(p_device_pool->
lock, F_LOCK, 0))
3712 for(i = 0; i < all_device_type_num; ++i)
3714 if(all_need_device_type[i] == preferential_device_type)
3717 all_need_device_type[i] = all_need_device_type[0];
3718 all_need_device_type[0] = tmp;
3723 qsort(&all_need_device_type[1], all_device_type_num - 1,
sizeof(
ni_device_type_t), int_cmp);
3729 device_type_num = 4;
3731 for(i = 0; i < device_type_num; ++i)
3733 if(hw_info_threshold_param[i].device_type == preferential_device_type)
3736 hw_info_threshold_param[i] = hw_info_threshold_param[0];
3737 hw_info_threshold_param[0] = tmp;
3741 qsort(&hw_info_threshold_param[1], device_type_num - 1,
3745 if(!(*pointer_to_p_hw_device_info))
3748 if(!p_hw_device_info)
3753 *pointer_to_p_hw_device_info = p_hw_device_info;
3764 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->device_type is NULL\n");
3770 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->card_info is NULL\n");
3774 for(i = 0; i < device_type_num; ++i)
3778 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->card_info[%d] is NULL\n", i);
3792 p_hw_device_info->
device_type[i] = all_need_device_type[i];
3830 card_remove = (int32_t *)malloc(
sizeof(int32_t) * p_hw_device_info->
available_card_num);
3840 module_count = coders->
xcoder_cnt[preferential_device_type];
3848 module_id_arr = (int32_t *)malloc(
sizeof(int32_t) * module_count);
3857 memcpy(module_id_arr, coders->
xcoders[preferential_device_type],
sizeof(int32_t) * module_count);
3861 qsort(module_id_arr, module_count,
sizeof(int32_t), int_cmp);
3867 memset(&xCtxt, 0,
sizeof(xCtxt));
3869 if (p_device_context)
3903 for(
int j = 0; j < device_type_num; ++j)
3907 if(p_device_context)
3953 p_device_context = NULL;
3974 decoder_need_load = check_hw_info_decoder_need_load(coder_param->
decoder_param);
3978 encoder_need_load = check_hw_info_encoder_need_load(coder_param->
encoder_param);
3993 ni_log(
NI_LOG_DEBUG,
"%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3995 ni_log(
NI_LOG_INFO,
"%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
4007 if(card_remove[i] == 1)
4014 if(decoder_need_load + p_hw_device_info->card_info[j][i].model_load >= 100)
4062 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,10);
4064 else if(preferential_device_type == 0)
4066 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,0);
4068 else if(preferential_device_type == 1)
4070 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,1);
4072 else if(preferential_device_type == 2)
4074 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,2);
4082 int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
4083 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4085 if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
4086 card_remove[i] == 0)
4088 min_task_num = p_hw_device_info->card_info[0][i].task_num;
4093 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4095 if (p_hw_device_info->card_info[0][i].load < min_load &&
4096 card_remove[i] == 0 &&
4097 p_hw_device_info->card_info[0][i].task_num == min_task_num)
4099 min_load = p_hw_device_info->card_info[0][i].load;
4100 p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4108 int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
4109 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4111 if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
4112 card_remove[i] == 0)
4114 p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4115 min_task_num = p_hw_device_info->card_info[0][i].task_num;
4120 if (p_hw_device_info->card_current_card >= 0)
4127 ReleaseMutex((HANDLE)p_device_pool->
lock);
4129 #elif defined(__linux__)
4130 if (lockf(p_device_pool->
lock, F_ULOCK,0))
4133 if(p_hw_device_info)
4140 p_device_context = NULL;
4145 free(module_id_arr);
4146 module_id_arr = NULL;
4151 dev_ctxt_arr = NULL;
4167 p_hw_device_info->card_current_card, retval);
4172 ni_log(
NI_LOG_DEBUG,
"In sw_mode select device_type %s card_current_card %d retval %d\n",
4174 ni_log(
NI_LOG_INFO,
"In sw_mode select device_type %s card_current_card %d retval %d\n",
4176 ((preferential_device_type == 0) ?
"decode" : (preferential_device_type == 1 ?
"encode" : (preferential_device_type == 2 ?
"scaler" :
"ai "))), p_hw_device_info->card_current_card, retval);
4208 int width,
int height,
4220 uint32_t num_sw_instances = 0;
4221 int least_model_load = 0;
4222 uint64_t job_mload = 0;
4242 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
4246 #elif __linux__ || __APPLE__
4247 lockf(p_device_pool->
lock, F_LOCK, 0);
4253 for (i = 0; i < count; i++)
4257 if (!p_device_context)
4260 "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4269 if (NI_INVALID_DEVICE_HANDLE == p_session_context.
device_handle)
4288 g_device_type_str[device_type],
4296 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
4299 __func__, p_device_context->
lock);
4301 #elif __linux__ || __APPLE__
4302 lockf(p_device_context->
lock, F_LOCK, 0);
4310 load = p_device_info->
load;
4311 least_model_load = p_device_info->
model_load;
4315 ni_log(
NI_LOG_INFO,
"Coder [%d]: %d , load: %d (%d), activ_inst: %d , max_inst %d\n",
4336 if (p_device_info->
model_load < least_model_load)
4339 least_model_load = p_device_info->
model_load;
4342 else if (p_device_info->
load < load)
4345 load = p_device_info->
load;
4352 ReleaseMutex(p_device_context->
lock);
4353 #elif __linux__ || __APPLE__
4354 lockf(p_device_context->
lock, F_ULOCK, 0);
4362 if (!p_device_context)
4365 "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4371 job_mload = width * height * frame_rate;
4377 p_device_context = NULL;
4382 ReleaseMutex(p_device_pool->
lock);
4383 #elif __linux__ || __APPLE__
4384 lockf(p_device_pool->
lock, F_ULOCK, 0);
4391 *p_load = job_mload;
4393 return p_device_context;