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"};
66 static bool is_str_in_str_array(
const char key[],
72 for (i = 0; i < array_size; i++)
74 if (0 == strcmp(key, arr[i]))
91 for (
int xcoder_index_1 = 0;
113 "no, possible missing features" :
"yes");
130 for (
int xcoder_index_2 = 0;
162 int xcoder_dev_count = 0;
164 int curr_dev_count = 0;
167 char **xcoder_refresh_dev_names = NULL;
168 int xcoder_refresh_dev_count = 0;
188 strcpy(xcoder_dev_names[i],
209 if (xcoder_dev_count > 0)
211 xcoder_refresh_dev_names = (
char **)malloc(xcoder_dev_count *
213 for (i = 0; i < xcoder_dev_count; i++)
216 strcpy(xcoder_refresh_dev_names[i], xcoder_dev_names[i]);
218 xcoder_refresh_dev_count = xcoder_dev_count;
222 xcoder_refresh_dev_names, xcoder_refresh_dev_count);
223 if (0 == curr_dev_count)
227 int devices_removed = 0;
228 int devices_added = 0;
230 for (i = 0; i < xcoder_dev_count; i++)
232 if (!is_str_in_str_array(xcoder_dev_names[i], curr_dev_names,
236 "\n\n%d. %s NOT in current scanned list, removing !\n", i,
237 xcoder_dev_names[i]);
242 xcoder_dev_names[i]);
247 xcoder_dev_names[i]);
253 for (i = 0; i < curr_dev_count; i++)
255 if (!is_str_in_str_array(curr_dev_names[i], xcoder_dev_names,
272 if (devices_added != devices_removed)
276 for (i = 0; i < xcoder_dev_count; i++)
280 for (i = 0; i < curr_dev_count; i++)
285 if (xcoder_refresh_dev_names) {
286 for (i = 0; i < xcoder_refresh_dev_count; i++)
287 free(xcoder_refresh_dev_names[i]);
288 free(xcoder_refresh_dev_names);
289 xcoder_refresh_dev_names = NULL;
298 android::sp<INidec>
service = NULL;
312 service = INidec::tryGetService();
346 if ((ni_devices == NULL)||(max_handles == 0))
371 int max_handles,
char **xcoder_refresh_dev_names,
372 int xcoder_refresh_dev_count)
374 if ((ni_devices == NULL)||(max_handles == 0))
393 HANDLE map_file_handle = NULL;
394 HANDLE mutex_handle = NULL;
397 mutex_handle = CreateMutex(NULL,
402 if (NULL == mutex_handle)
409 if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
414 map_file_handle = OpenFileMapping(
420 if (NULL == map_file_handle)
422 ReleaseMutex(mutex_handle);
436 if (NULL == p_device_queue)
438 ReleaseMutex(mutex_handle);
439 CloseHandle(map_file_handle);
444 if (NULL == p_device_pool)
448 UnmapViewOfFile(p_device_queue);
452 p_device_pool->
lock = mutex_handle;
456 ReleaseMutex(mutex_handle);
457 CloseHandle(map_file_handle);
458 return p_device_pool;
479 int ni_rsrc_init(
int should_match_rev,
int timeout_seconds)
483 int number_of_devices = 0;
484 uint32_t runtime = 0;
485 while (0 == number_of_devices)
495 else if (0 == number_of_devices)
503 if (timeout_seconds == 0) {
505 "and exit without wait\n");
510 if (runtime >= (uint32_t)timeout_seconds)
544 char shm_name[32] = { 0 };
545 char lck_name[32] = { 0 };
548 HANDLE map_file_handle = NULL;
549 HANDLE mutex_handle = NULL;
555 mutex_handle = CreateMutex(NULL,
559 if (NULL == mutex_handle)
562 p_device_context = NULL;
566 if (WAIT_ABANDONED == WaitForSingleObject(mutex_handle, INFINITE))
569 "obtain mutex: %p\n", mutex_handle);
572 map_file_handle = OpenFileMapping(
578 if (NULL == map_file_handle)
582 p_device_context = NULL;
594 if (NULL == p_device_queue)
599 p_device_context = NULL;
604 if (NULL == p_device_context)
608 p_device_context = NULL;
612 strncpy(p_device_context->
shm_name, shm_name,
sizeof(p_device_context->
shm_name));
613 p_device_context->
lock = mutex_handle;
618 if (NULL == p_device_context)
620 if (NULL != p_device_queue)
622 UnmapViewOfFile(p_device_queue);
624 if (NULL != mutex_handle)
626 ReleaseMutex(mutex_handle);
627 CloseHandle(mutex_handle);
630 if (NULL != map_file_handle)
632 CloseHandle(map_file_handle);
636 ReleaseMutex(mutex_handle);
637 CloseHandle(map_file_handle);
640 return p_device_context;
643 #elif __linux__ || __APPLE__
645 #define DEV_NAME_PREFIX "rdisk"
646 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
647 #define DEV_NAME_PREFIX "vd"
649 #define DEV_NAME_PREFIX "nvme"
670 #if defined(_ANDROID) || defined(__OPENHARMONY__)
671 #define ANDROID_MAX_DIR_NUM 2
672 int android_dir_num = 0;
673 const char* dir_name_array[ANDROID_MAX_DIR_NUM];
674 dir_name_array[0] =
"/dev";
675 dir_name_array[1] =
"/dev/block";
677 const char* dir_name =
"/dev";
679 int i, xcoder_device_cnt = 0;
681 struct dirent* in_file;
684 ni_device_handle_t dev_handle = NI_INVALID_DEVICE_HANDLE;
686 uint32_t tmp_io_size;
689 if ((ni_devices == NULL)||(max_handles == 0))
695 int nvme_dev_cnt = 0;
701 const char *pattern =
"^rdisk[0-9]+$";
702 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
703 const char *pattern =
"^vd[a-z]$";
705 const char *pattern =
"^nvme[0-9]+(c[0-9]+)?n[0-9]+$";
708 if(regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB)) {
713 #if defined(_ANDROID) || defined(__OPENHARMONY__)
716 while(xcoder_device_cnt == 0 && android_dir_num < ANDROID_MAX_DIR_NUM)
718 const char *dir_name = dir_name_array[android_dir_num];
723 dev_handle = NI_INVALID_DEVICE_HANDLE;
725 size_t size_of_nvme_devices_x =
sizeof(nvme_devices)/
sizeof(nvme_devices[0]);
726 for(
size_t dimx = 0; dimx < size_of_nvme_devices_x; ++dimx)
728 memset(nvme_devices[dimx], 0,
sizeof(nvme_devices[0]));
733 if (NULL == (FD = opendir(dir_name)))
736 #if defined(_ANDROID) || defined(__OPENHARMONY__)
738 if(android_dir_num < ANDROID_MAX_DIR_NUM)
752 while ((in_file = readdir(FD)))
755 if (!strcmp(in_file->d_name,
".") || !strcmp(in_file->d_name,
".."))
762 if (!strncmp(in_file->d_name, DEV_NAME_PREFIX, strlen(DEV_NAME_PREFIX)))
764 if (nvme_dev_cnt < 200)
766 int write_len = snprintf(nvme_devices[nvme_dev_cnt],
768 dir_name, in_file->d_name);
772 "ERROR: failed to copy device %d name %s\n",
773 nvme_dev_cnt, in_file->d_name);
778 skip_this = regexec(®ex, in_file->d_name, 0, NULL, 0);
785 "%s/%s", dir_name, in_file->d_name) < 0)
788 "ERROR: failed an snprintf() in "
789 "ni_rsrc_get_local_device_list()\n");
817 if (NI_INVALID_DEVICE_HANDLE != dev_handle)
821 &device_capabilites);
824 if (is_supported_xcoder(
827 ni_devices[xcoder_device_cnt][0] =
'\0';
828 strcat(ni_devices[xcoder_device_cnt],
840 (max_handles <= xcoder_device_cnt))
843 "Disregarding some Netint devices on system over "
844 "limit of NI_MAX_DEVICE_CNT(%d) or max_handles(%d)\n",
851 #if defined(_ANDROID) || defined(__OPENHARMONY__)
859 if (0 == xcoder_device_cnt)
861 ni_log(
NI_LOG_INFO,
"Found %d NVMe devices on system, none of them xcoder\n", nvme_dev_cnt);
862 for (i = 0; i < nvme_dev_cnt; i++)
870 return xcoder_device_cnt;
890 int max_handles,
char **xcoder_refresh_dev_names,
891 int xcoder_refresh_dev_count)
895 #define ANDROID_MAX_DIR_NUM 2
896 int android_dir_num = 0;
897 const char* dir_name_array[ANDROID_MAX_DIR_NUM];
898 dir_name_array[0] =
"/dev";
899 dir_name_array[1] =
"/dev/block";
901 const char* dir_name =
"/dev";
903 int i, xcoder_device_cnt = 0;
905 struct dirent* in_file;
908 ni_device_handle_t dev_handle = NI_INVALID_DEVICE_HANDLE;
910 uint32_t tmp_io_size;
911 bool device_in_ctxt =
false;
913 if ((ni_devices == NULL)||(max_handles == 0))
919 int nvme_dev_cnt = 0;
925 const char *pattern =
"^rdisk[0-9]+$";
926 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
927 const char *pattern =
"^vd[a-z]$";
929 const char *pattern =
"^nvme[0-9]+(c[0-9]+)?n[0-9]+$";
932 if(regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB)) {
940 while(xcoder_device_cnt == 0 && android_dir_num < ANDROID_MAX_DIR_NUM)
942 const char *dir_name = dir_name_array[android_dir_num];
946 device_in_ctxt =
false;
947 dev_handle = NI_INVALID_DEVICE_HANDLE;
949 size_t size_of_nvme_devices_x =
sizeof(nvme_devices)/
sizeof(nvme_devices[0]);
950 for(
size_t dimx = 0; dimx < size_of_nvme_devices_x; ++dimx)
952 memset(nvme_devices[dimx], 0,
sizeof(nvme_devices[0]));
957 if (NULL == (FD = opendir(dir_name)))
962 if(android_dir_num < ANDROID_MAX_DIR_NUM)
976 while ((in_file = readdir(FD)))
979 if (!strcmp(in_file->d_name,
".") || !strcmp(in_file->d_name,
".."))
986 if (!strncmp(in_file->d_name, DEV_NAME_PREFIX, strlen(DEV_NAME_PREFIX)))
988 if (nvme_dev_cnt < 200)
990 int write_len = snprintf(nvme_devices[nvme_dev_cnt],
992 dir_name, in_file->d_name);
996 "ERROR: failed to copy device %d name %s\n",
997 nvme_dev_cnt, in_file->d_name);
1002 skip_this = regexec(®ex, in_file->d_name, 0, NULL, 0);
1009 "%s/%s", dir_name, in_file->d_name) < 0)
1012 "ERROR: failed an snprintf() in "
1013 "ni_rsrc_get_local_device_list2()\n");
1020 device_in_ctxt =
false;
1021 for (
int j = 0; j < xcoder_refresh_dev_count; j++)
1025 xcoder_refresh_dev_names[j]))
1027 device_in_ctxt =
true;
1041 if (NI_INVALID_DEVICE_HANDLE != dev_handle)
1044 &device_capabilites, device_in_ctxt);
1047 if (is_supported_xcoder(
1050 ni_devices[xcoder_device_cnt][0] =
'\0';
1051 strcat(ni_devices[xcoder_device_cnt],
1053 xcoder_device_cnt++;
1062 (max_handles <= xcoder_device_cnt))
1065 "Disregarding some Netint devices on system over "
1066 "limit of NI_MAX_DEVICE_CNT(%d) or max_handles(%d)\n",
1081 if (0 == xcoder_device_cnt)
1083 ni_log(
NI_LOG_INFO,
"Found %d NVMe devices on system, none of them xcoder\n", nvme_dev_cnt);
1084 for (i = 0; i < nvme_dev_cnt; i++)
1090 return xcoder_device_cnt;
1103 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1104 int flags = O_RDWR | O_CLOEXEC;
1105 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1107 ni_lock_handle_t lock;
1111 flags, mode, (
int *)&lock) < 0) {
1119 (
int *)&shm_fd) < 0) {
1127 (
void **)&p_device_queue)) < 0) {
1133 if (! p_device_pool) {
1138 p_device_pool->
lock = lock;
1143 lockf(lock, F_ULOCK, 0);
1145 if (NULL == p_device_pool) {
1149 #ifndef __OPENHARMONY__
1155 return p_device_pool;
1176 int ni_rsrc_init(
int should_match_rev,
int timeout_seconds)
1179 char api_version[5];
1180 int number_of_devices;
1182 int limit_depth = 3;
1190 if (number_of_devices > 0)
1202 if (timeout_seconds == 0) {
1204 "and exit without wait\n");
1209 if (runtime >= (uint32_t)timeout_seconds)
1212 "Timeout exceeded/reached after %u seconds!\n",
1223 return ni_rsrc_init_priv(should_match_rev, number_of_devices, device_names, limit_depth);
1245 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1247 int flags = O_RDWR | O_CLOEXEC;
1248 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1249 char shm_name[32] = { 0 };
1250 char lck_name[32] = { 0 };
1257 if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, &lock) < 0) {
1262 if (ni_rsrc_open_shm(shm_name,
1265 (
int *)&shm_fd) < 0) {
1270 if ((ni_rsrc_mmap_shm(shm_name,
1273 (
void **)&p_device_queue)) < 0) {
1279 if (!p_device_context) {
1286 strncpy(p_device_context->
shm_name, shm_name,
sizeof(p_device_context->
shm_name));
1287 p_device_context->
lock = lock;
1291 lockf(lock, F_ULOCK, 0);
1293 #ifndef __OPENHARMONY__
1299 return p_device_context;
1312 if (p_device_context)
1316 ReleaseMutex(p_device_context->
lock);
1317 #elif __linux__ || __APPLE__
1318 close(p_device_context->
lock);
1322 free(p_device_context);
1348 bool b_release_pool_mtx =
false;
1350 if ( (NULL == p_device_info) || (NULL == p_device_count) )
1357 if (NULL == p_device_pool)
1364 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
1367 "mutex: %p\n", p_device_pool->
lock);
1371 #elif __linux__ || __APPLE__
1372 lockf(p_device_pool->
lock, F_LOCK, 0);
1375 b_release_pool_mtx =
true;
1378 count = p_device_queue->
xcoder_cnt[device_type];
1381 for (i = 0; i < count; i++)
1384 guid = p_device_queue->
xcoders[device_type][i];
1386 if (p_device_context)
1389 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1392 "mutex: %p\n", p_device_context->
lock);
1393 ReleaseMutex(p_device_pool->
lock);
1399 ReleaseMutex(p_device_context->
lock);
1400 #elif __linux__ || __APPLE__
1401 lockf(p_device_context->
lock, F_LOCK, 0);
1403 lockf(p_device_context->
lock, F_ULOCK, 0);
1408 (*p_device_count)++;
1418 if (b_release_pool_mtx)
1421 ReleaseMutex(p_device_pool->
lock);
1422 #elif __linux__ || __APPLE__
1423 lockf(p_device_pool->
lock, F_ULOCK, 0);
1450 if (NULL == p_device)
1500 if (list_uninitialized)
1507 if (!list_uninitialized)
1519 for (
int dev_index = 0;
1523 strcpy(initialized_dev_names[dev_index], p_dev_info->
dev_name);
1532 uint32_t tmp_io_size;
1534 ni_device_handle_t fd;
1536 for (
int dev_index = 0; dev_index < dev_count; dev_index++)
1538 if (is_str_in_str_array(dev_names[dev_index],
1545 if (NI_INVALID_DEVICE_HANDLE == fd)
1548 dev_names[dev_index]);
1557 dev_names[dev_index]);
1565 p_dev_info = &p_device->
xcoders[dev_type][dev_index];
1571 sizeof(capability.
fw_rev));
1583 strcpy(p_dev_info->
dev_name, dev_names[dev_index]);
1620 " Operations: Crop (ni_quadra_crop), Scale (ni_quadra_scale), Pad "
1621 "(ni_quadra_pad), Overlay (ni_quadra_overlay)\n"
1622 " Drawbox (ni_quadra_drawbox), Rotate (ni_quadra_rotate), XStack (ni_quadra_xstack)\n");
1628 " Operations: ROI (ni_quadra_roi), Background Replace (ni_quadra_bg)\n");
1638 ni_codec_format_str[p_device_info->
dev_cap[i]
1643 ni_dec_name_str[p_device_info->
dev_cap[i]
1645 ni_enc_name_str[p_device_info->
dev_cap[i]
1754 if (NULL == p_device_context)
1760 if (NULL == p_device_info)
1766 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1769 "mutex: %p\n", p_device_context->
lock);
1770 free(p_device_info);
1775 ReleaseMutex(p_device_context->
lock);
1777 lockf(p_device_context->
lock, F_LOCK, 0);
1781 lockf(p_device_context->
lock, F_ULOCK, 0);
1788 return p_device_info;
1823 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
1826 __FUNCTION__, p_device_pool->
lock);
1830 #elif __linux__ || __APPLE__
1831 lockf(p_device_pool->
lock, F_LOCK, 0);
1836 for (i = 0; i < num_coders; i++)
1841 if (p_device_context &&
1853 ReleaseMutex(p_device_pool->
lock);
1854 #elif __linux__ || __APPLE__
1855 lockf(p_device_pool->
lock, F_ULOCK, 0);
1882 if (!p_device_context || !sw_instance_info)
1889 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1892 __func__, p_device_context->
lock);
1895 #elif __linux__ || __APPLE__
1896 lockf(p_device_context->
lock, F_LOCK, 0);
1901 for (i = 0; i < sw_instance_cnt; i++)
1907 ReleaseMutex(p_device_context->
lock);
1908 #elif __linux__ || __APPLE__
1909 lockf(p_device_context->
lock, F_ULOCK, 0);
1939 return p_device_context;
1958 (void) p_device_context;
1963 if (!p_device_context)
1970 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1973 __func__, p_device_context->
lock);
1975 #elif __linux__ || __APPLE__
1976 lockf(p_device_context->
lock, F_LOCK, 0);
1981 ni_log(
NI_LOG_INFO,
"Warning: releasing resource load %lu > current load %lu\n", load,
1989 #if __linux__ || __APPLE__
1993 "p_device_info: %s\n", __func__, strerror(
NI_ERRNO));
1999 ReleaseMutex(p_device_context->
lock);
2000 #elif __linux__ || __APPLE__
2001 lockf(p_device_context->
lock, F_ULOCK, 0);
2022 uint32_t max_nvme_io_size = 0;
2023 bool b_release_pool_mtx =
false;
2042 session_ctx.
hw_id = guid;
2081 if (WAIT_ABANDONED ==
2082 WaitForSingleObject(p_device_pool->
lock,
2086 "ERROR: ni_rsrc_list_devices() failed to obtain mutex: %p\n",
2087 p_device_pool->
lock);
2092 lockf(p_device_pool->
lock, F_LOCK, 0);
2094 b_release_pool_mtx =
true;
2111 if (NI_INVALID_EVENT_HANDLE == session_ctx.
event_handle)
2122 "guid %d. %s is not avaiable, type: %d, retval:%d\n",
2124 device_type, retval);
2144 "vpu recovery happened on guid %d. %s, retry "
2155 "session open error guid %d. %s, type: %d, "
2158 device_type, retval);
2168 "Error get device resource: guid %d, device_ctx %p\n", guid,
2175 if (b_release_pool_mtx)
2178 ReleaseMutex(p_device_pool->
lock);
2180 lockf(p_device_pool->
lock, F_ULOCK, 0);
2205 #if __linux__ || __APPLE__
2211 unsigned int guid_index_i, guid_index_j, ui_device_type;
2235 rValue = WaitForSingleObject(p_device_pool->
lock, INFINITE);
2236 if (rValue != WAIT_OBJECT_0)
2239 "ERROR: %s() Failed to obtain mutex %p\n",
2241 p_device_pool->
lock);
2245 #elif __linux__ || __APPLE__
2246 lockf(p_device_pool->
lock, F_LOCK, 0);
2256 guid = p_device_queue->
xcoders[ui_device_type][guid_index_i];
2263 if (!p_device_context)
2266 "ERROR: %s() Failed to obtain device context for "
2267 "%s with GUID %u! Undefined behavior!\n",
2283 CloseHandle(p_device_context->
lock);
2284 #elif __linux__ || __APPLE__
2288 "%s %s %s deleted\n",
2296 "ERROR: %s(): %s %s %s failed to delete %s\n",
2308 #if __linux__ || __APPLE__
2310 if (!unlink(lck_name))
2313 "%s %s %s deleted\n",
2321 "ERROR: %s(): %s %s %s failed to delete %s\n",
2336 p_device_queue->
xcoders[ui_device_type][guid_index_i] = -1;
2337 p_device_queue->
xcoder_cnt[ui_device_type]--;
2348 memset(guids, -1,
sizeof(guids));
2352 guid = p_device_queue->
xcoders[ui_device_type][guid_index_i];
2355 guids[guid_index_j] = guid;
2357 if (guid_index_j == p_device_queue->
xcoder_cnt[ui_device_type])
2363 memcpy(p_device_queue->
xcoders[ui_device_type], guids,
sizeof(guids));
2366 #if __linux__ || __APPLE__
2368 if (!msync((
void *)p_device_queue,
2370 MS_SYNC|MS_INVALIDATE))
2377 "ERROR: %s(): msync() failed to delete %s: %s\n",
2387 ReleaseMutex(p_device_pool->
lock);
2388 #elif __linux__ || __APPLE__
2389 lockf(p_device_pool->
lock, F_ULOCK, 0);
2395 return return_value;
2410 int xcoder_dev_count = 0;
2432 strcpy(xcoder_dev_names[i],
2436 xcoder_dev_names[i]);
2442 "%d devices retrieved from current pool at start up\n",
2446 "%d devices retrieved from current pool at start up\n",
2457 for (i = 0; i < xcoder_dev_count; i++)
2460 xcoder_dev_names[i]);
2465 xcoder_dev_names[i]);
2469 xcoder_dev_names[i]);
2473 #if __linux__ || __APPLE__
2485 if (0 == unlink(XCODERS_RETRY_LCK_NAME[i]))
2488 i, XCODERS_RETRY_LCK_NAME[i]);
2493 i, XCODERS_RETRY_LCK_NAME[i]);
2525 uint32_t i, existing_number_of_devices;
2546 if (WAIT_ABANDONED == WaitForSingleObject(device_pool->
lock, INFINITE))
2549 "ERROR: %s(): Failed to obtain lock %p\n",
2554 #elif __linux__ || __APPLE__
2555 lockf(device_pool->
lock, F_LOCK, 0);
2562 existing_number_of_devices = device_queue->
xcoder_cnt[device_type];
2567 "ERROR: %s(): Limit of NI_MAX_DEVICE_CNT(%d) existing Quadra "
2568 "devices previously reached. Not adding %s.\n",
2576 for (i = 0; i < existing_number_of_devices; i++)
2580 device_queue->
xcoders[device_type][i]);
2587 "ERROR: %s(): %s already exists in resource pool\n",
2606 ReleaseMutex(device_pool->
lock);
2607 #elif __linux__ || __APPLE__
2608 lockf(device_pool->
lock, F_ULOCK, 0);
2625 if (NI_INVALID_LOCK_HANDLE != p_device_pool->
lock)
2628 CloseHandle(p_device_pool->
lock);
2629 #elif __linux__ || __APPLE__
2630 close(p_device_pool->
lock);
2640 free(p_device_pool);
2658 *lock = CreateMutex(NULL, FALSE, XCODERS_RETRY_LCK_NAME[device_type]);
2663 __func__, XCODERS_RETRY_LCK_NAME[device_type],
2677 open(XCODERS_RETRY_LCK_NAME[device_type], O_RDWR | O_CREAT | O_CLOEXEC,
2678 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
2703 DWORD ret = WaitForSingleObject(*lock, 1);
2704 if (WAIT_OBJECT_0 == ret)
2707 }
else if (WAIT_TIMEOUT != ret)
2713 status = lockf(*lock, F_LOCK, 0);
2725 while (status != 0);
2740 if (lock == NI_INVALID_LOCK_HANDLE)
2746 ni_lock_handle_t status = NI_INVALID_LOCK_HANDLE;
2754 if (ReleaseMutex(lock))
2756 status = (ni_lock_handle_t)(0);
2759 status = lockf(lock, F_ULOCK, 0);
2767 }
while (status != (ni_lock_handle_t)(0));
2773 #endif //_WIN32 defined
2795 static int int_cmp(
const void *a,
const void *b)
2797 const int *ia = (
const int *)a;
2798 const int *ib = (
const int *)b;
2799 return (*ia == *ib) ? 0 : ((*ia > *ib) ? 1 : -1);
2803 static int ni_hw_device_info_quadra_threshold_param_t_compare(
const void *pl,
const void *pr)
2826 int factor_8_10 = 1;
2827 uint32_t resolution = decoder_param->
h * decoder_param->
w;
2832 return resolution >= 1920*1080 ?
2833 (int)(((uint64_t)(resolution)*(uint64_t)(decoder_param->
fps)*(uint64_t)(factor_8_10)*100)/1440/1920/1080) :
2834 (
int)((uint64_t)(resolution)*(uint64_t)(decoder_param->
fps)*(uint64_t)(factor_8_10)*100/2880/1280/720);
2848 double factor = 1.0;
2849 double factor_codec = 1.0;
2850 double factor_rdoq = 1.0;
2851 double factor_rdoLevel = 1.0;
2852 double factor_lookahead = 1.0;
2853 double factor_8_10_bit = 1.0;
2854 double factor_720p = 1.0;
2856 int resolution = (int)(encoder_param->
w * encoder_param->
h);
2861 factor_codec = 0.67;
2873 factor_rdoLevel = (encoder_param->
rdoLevel == 2) ? 1.91 : 3.28;
2878 factor_lookahead = (double)(encoder_param->
lookaheadDepth * 0.0014 + 1.012);
2884 factor_8_10_bit = 2;
2887 factor_720p = 1.125;
2888 factor = factor_codec * factor_8_10_bit * factor_rdoq * factor_rdoLevel
2889 * factor_lookahead * factor_720p;
2895 ((uint32_t)((uint32_t)factor*encoder_param->
fps * resolution)) /
2896 ((3840 * 2160 * 60ULL) / 100 * 4));
2911 static int check_hw_info_shared_mem_calculate_b_scale(
int h,
int w,
int bit_8_10,
int rgba)
2913 const int stride = 128;
2914 int estimated_yuv_size = rgba ?
2917 ( ((w + stride - 1)/stride)*stride + ((w/2 + stride - 1)/stride)*stride ) * h:
2918 ( ((w * 2 + stride - 1)/stride)*stride + ((w + stride - 1)/stride)*stride ) * h;
2919 const int b_unit = 1601536;
2920 int b_scale = (estimated_yuv_size + b_unit -1) / b_unit;
2952 const int v32_ofCores_calculate = 0;
2954 int b_counts = (int)(v32_ofCores_calculate +
2957 (encoder_param->
uploader ? 1 : 0) * 3 +
2959 int b_scale = check_hw_info_shared_mem_calculate_b_scale(encoder_param->
h, encoder_param->
w,
2961 return b_scale * b_counts;
2985 const int hw_frame = decoder_param->
hw_frame;
2987 const int v30_xlsx = 0;
2988 int b_counts = 1 * (v30_xlsx +
2989 (hw_frame ? 0 : 1)*3 +
2991 int b_scale = check_hw_info_shared_mem_calculate_b_scale(decoder_param->
h, decoder_param->
w,
2993 return b_scale * b_counts;
3020 const int v30_xlsx = 0;
3021 int b_counts = 1 * (v30_xlsx +
3024 int b_scale = check_hw_info_shared_mem_calculate_b_scale(scaler_param->
h, scaler_param->
w,
3026 return b_scale * b_counts;
3044 const int total = 2456;
3045 int task_mem_usage = 0;
3046 int task_mem_precentage = 0;
3052 for(i = 0; i < card_num; ++i)
3061 task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16);
3065 task_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param);
3069 task_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3073 int decoder_shared_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16);
3074 int encoder_shared_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param);
3075 int scaler_shared_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3076 task_mem_usage = decoder_shared_mem_usage + ((encoder_shared_mem_usage > scaler_shared_mem_usage) ?
3077 encoder_shared_mem_usage : scaler_shared_mem_usage);
3082 task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16) +
3083 check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param)+
3084 check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3087 task_mem_precentage = 100 * task_mem_usage / total;
3089 if(task_mem_precentage > 90)
3092 task_mem_precentage = 90;
3095 for(i = 0;i<card_num;++i)
3097 if(card_remove[i] == 1)
3122 if(p_coder_param == NULL)
3124 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_coder_param\n");
3125 return p_coder_param;
3134 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3135 free(p_coder_param);
3136 p_coder_param = NULL;
3137 return p_coder_param;
3145 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3146 free(p_coder_param);
3147 p_coder_param = NULL;
3148 return p_coder_param;
3156 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3157 free(p_coder_param);
3158 p_coder_param = NULL;
3159 return p_coder_param;
3165 if(p_coder_param->
ai_param == NULL)
3167 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3168 free(p_coder_param);
3169 p_coder_param = NULL;
3170 return p_coder_param;
3178 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3179 free(p_coder_param);
3180 p_coder_param = NULL;
3181 return p_coder_param;
3186 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3189 free(p_coder_param);
3190 p_coder_param = NULL;
3191 return p_coder_param;
3196 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3201 free(p_coder_param);
3202 p_coder_param = NULL;
3203 return p_coder_param;
3206 if(p_coder_param->
ai_param == NULL)
3208 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3215 free(p_coder_param);
3216 p_coder_param = NULL;
3217 return p_coder_param;
3257 return p_coder_param;
3273 if(p_hw_device_info_quadra_coder_param == NULL)
3289 free(p_hw_device_info_quadra_coder_param->
scaler_param);
3290 p_hw_device_info_quadra_coder_param->
scaler_param = NULL;
3292 if(p_hw_device_info_quadra_coder_param->
ai_param)
3294 free(p_hw_device_info_quadra_coder_param->
ai_param);
3295 p_hw_device_info_quadra_coder_param->
ai_param = NULL;
3297 free(p_hw_device_info_quadra_coder_param);
3314 if(!p_hw_device_info)
3316 ni_log(
NI_LOG_ERROR,
"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t\n");
3317 goto p_hw_device_info_end;
3324 ni_log(
NI_LOG_ERROR,
"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t->device_type\n");
3325 goto device_type_end;
3343 if(p_hw_device_info->
card_info[i] == NULL)
3346 goto card_info_i_end;
3350 return p_hw_device_info;
3367 free(p_hw_device_info);
3368 p_hw_device_info = NULL;
3369 p_hw_device_info_end:
3384 if(!p_hw_device_info)
3397 free(p_hw_device_info);
3414 int should_match_rev = 1;
3415 int module_count = 1;
3417 int32_t *module_id_arr = NULL;
3423 int *card_remove = NULL;
3426 uint64_t decoder_need_load = 0;
3427 uint64_t encoder_need_load = 0;
3430 int hw_info_param_num = hw_mode ? 4 : 1;
3431 int device_type_num = 1;
3432 const int all_device_type_num = 4;
3440 bool b_valid =
false;
3448 if(!pointer_to_p_hw_device_info)
3450 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: pointer_to_p_hw_device_info is NULL.\n");
3454 if(*pointer_to_p_hw_device_info)
3456 p_hw_device_info = *pointer_to_p_hw_device_info;
3468 }
else if(hw_mode && hw_mode != coder_param->
hw_mode)
3470 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: hw_mode = %d, coder_param->hw_mode = %d\n",
3471 hw_mode,coder_param->
hw_mode);
3477 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_ENCODER but coder_param->encoder_param == NULL\n");
3482 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_DECODER but coder_param->decoder_param == NULL\n");
3487 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_SCALER but coder_param->scaler_param == NULL\n");
3492 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_AI but coder_param->ai_param == NULL\n");
3498 if((task_mode != 0 && task_mode != 1) ||
3507 task_mode, preferential_device_type);
3511 if(!hw_info_threshold_param)
3517 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: hw_info_threshold_param is NULL.\n");
3520 for(i = 0;i < hw_info_param_num; ++i)
3522 if(hw_info_threshold_param[i].load_threshold < 0||
3523 hw_info_threshold_param[i].load_threshold > 100 ||
3524 hw_info_threshold_param[i].task_num_threshold < 0 ||
3535 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",
3536 (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);
3591 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
3596 #elif defined(__linux__)
3597 if (lockf(p_device_pool->
lock, F_LOCK, 0))
3623 for(i = 0; i < all_device_type_num; ++i)
3625 if(all_need_device_type[i] == preferential_device_type)
3628 all_need_device_type[i] = all_need_device_type[0];
3629 all_need_device_type[0] = tmp;
3634 qsort(&all_need_device_type[1], all_device_type_num - 1,
sizeof(
ni_device_type_t), int_cmp);
3640 device_type_num = 4;
3642 for(i = 0; i < device_type_num; ++i)
3644 if(hw_info_threshold_param[i].device_type == preferential_device_type)
3647 hw_info_threshold_param[i] = hw_info_threshold_param[0];
3648 hw_info_threshold_param[0] = tmp;
3652 qsort(&hw_info_threshold_param[1], device_type_num - 1,
3656 if(!(*pointer_to_p_hw_device_info))
3659 if(!p_hw_device_info)
3664 *pointer_to_p_hw_device_info = p_hw_device_info;
3675 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->device_type is NULL\n");
3681 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->card_info is NULL\n");
3685 for(i = 0; i < device_type_num; ++i)
3689 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);
3703 p_hw_device_info->
device_type[i] = all_need_device_type[i];
3741 card_remove = (int32_t *)malloc(
sizeof(int32_t) * p_hw_device_info->
available_card_num);
3751 module_count = coders->
xcoder_cnt[preferential_device_type];
3759 module_id_arr = (int32_t *)malloc(
sizeof(int32_t) * module_count);
3768 memcpy(module_id_arr, coders->
xcoders[preferential_device_type],
sizeof(int32_t) * module_count);
3772 qsort(module_id_arr, module_count,
sizeof(int32_t), int_cmp);
3778 for(
int j = 0; j < device_type_num; ++j)
3780 memset(&xCtxt, 0,
sizeof(xCtxt));
3782 if(p_device_context)
3859 p_device_context = NULL;
3873 decoder_need_load = check_hw_info_decoder_need_load(coder_param->
decoder_param);
3877 encoder_need_load = check_hw_info_encoder_need_load(coder_param->
encoder_param);
3892 ni_log(
NI_LOG_DEBUG,
"%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3894 ni_log(
NI_LOG_INFO,
"%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3906 if(card_remove[i] == 1)
3913 if(decoder_need_load + p_hw_device_info->card_info[j][i].model_load >= 100)
3961 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,10);
3963 else if(preferential_device_type == 0)
3965 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,0);
3967 else if(preferential_device_type == 1)
3969 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,1);
3971 else if(preferential_device_type == 2)
3973 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,2);
3981 int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
3982 for (i = 0; i < p_hw_device_info->available_card_num; i++)
3984 if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
3985 card_remove[i] == 0)
3987 min_task_num = p_hw_device_info->card_info[0][i].task_num;
3992 for (i = 0; i < p_hw_device_info->available_card_num; i++)
3994 if (p_hw_device_info->card_info[0][i].load < min_load &&
3995 card_remove[i] == 0 &&
3996 p_hw_device_info->card_info[0][i].task_num == min_task_num)
3998 min_load = p_hw_device_info->card_info[0][i].load;
3999 p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4007 int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
4008 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4010 if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
4011 card_remove[i] == 0)
4013 p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4014 min_task_num = p_hw_device_info->card_info[0][i].task_num;
4019 if (p_hw_device_info->card_current_card >= 0)
4026 ReleaseMutex((HANDLE)p_device_pool->
lock);
4028 #elif defined(__linux__)
4029 if (lockf(p_device_pool->
lock, F_ULOCK,0))
4032 if(p_hw_device_info)
4039 p_device_context = NULL;
4044 free(module_id_arr);
4045 module_id_arr = NULL;
4050 dev_ctxt_arr = NULL;
4066 p_hw_device_info->card_current_card, retval);
4071 ni_log(
NI_LOG_DEBUG,
"In sw_mode select device_type %s card_current_card %d retval %d\n",
4073 ni_log(
NI_LOG_INFO,
"In sw_mode select device_type %s card_current_card %d retval %d\n",
4075 ((preferential_device_type == 0) ?
"decode" : (preferential_device_type == 1 ?
"encode" : (preferential_device_type == 2 ?
"scaler" :
"ai "))), p_hw_device_info->card_current_card, retval);
4107 int width,
int height,
4119 uint32_t num_sw_instances = 0;
4120 int least_model_load = 0;
4121 uint64_t job_mload = 0;
4141 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
4145 #elif __linux__ || __APPLE__
4146 lockf(p_device_pool->
lock, F_LOCK, 0);
4152 for (i = 0; i < count; i++)
4156 if (!p_device_context)
4159 "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4168 if (NI_INVALID_DEVICE_HANDLE == p_session_context.
device_handle)
4185 g_device_type_str[device_type],
4193 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
4196 __func__, p_device_context->
lock);
4198 #elif __linux__ || __APPLE__
4199 lockf(p_device_context->
lock, F_LOCK, 0);
4207 load = p_device_info->
load;
4208 least_model_load = p_device_info->
model_load;
4212 ni_log(
NI_LOG_INFO,
"Coder [%d]: %d , load: %d (%d), activ_inst: %d , max_inst %d\n",
4233 if (p_device_info->
model_load < least_model_load)
4236 least_model_load = p_device_info->
model_load;
4239 else if (p_device_info->
load < load)
4242 load = p_device_info->
load;
4249 ReleaseMutex(p_device_context->
lock);
4250 #elif __linux__ || __APPLE__
4251 lockf(p_device_context->
lock, F_ULOCK, 0);
4259 if (!p_device_context)
4262 "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4268 job_mload = width * height * frame_rate;
4274 p_device_context = NULL;
4279 ReleaseMutex(p_device_pool->
lock);
4280 #elif __linux__ || __APPLE__
4281 lockf(p_device_pool->
lock, F_ULOCK, 0);
4288 *p_load = job_mload;
4290 return p_device_context;