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;
697 uint32_t tmp_io_size;
700 if ((ni_devices == NULL)||(max_handles == 0))
706 int nvme_dev_cnt = 0;
712 const char *pattern =
"^rdisk[0-9]+$";
713 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
714 const char *pattern =
"^vd[a-z]$";
716 const char *pattern =
"^nvme[0-9]+(c[0-9]+)?n[0-9]+$";
719 if(regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB)) {
724 #if defined(_ANDROID) || defined(__OPENHARMONY__)
727 while(xcoder_device_cnt == 0 && android_dir_num < ANDROID_MAX_DIR_NUM)
729 const char *dir_name = dir_name_array[android_dir_num];
734 dev_handle = NI_INVALID_DEVICE_HANDLE;
736 size_t size_of_nvme_devices_x =
sizeof(nvme_devices)/
sizeof(nvme_devices[0]);
737 for(
size_t dimx = 0; dimx < size_of_nvme_devices_x; ++dimx)
739 memset(nvme_devices[dimx], 0,
sizeof(nvme_devices[0]));
744 if (NULL == (FD = opendir(dir_name)))
747 #if defined(_ANDROID) || defined(__OPENHARMONY__)
749 if(android_dir_num < ANDROID_MAX_DIR_NUM)
763 while ((in_file = readdir(FD)))
766 if (!strcmp(in_file->d_name,
".") || !strcmp(in_file->d_name,
".."))
773 if (!strncmp(in_file->d_name, DEV_NAME_PREFIX, strlen(DEV_NAME_PREFIX)))
775 if (nvme_dev_cnt < 200)
777 int write_len = snprintf(nvme_devices[nvme_dev_cnt],
779 dir_name, in_file->d_name);
783 "ERROR: failed to copy device %d name %s\n",
784 nvme_dev_cnt, in_file->d_name);
789 skip_this = regexec(®ex, in_file->d_name, 0, NULL, 0);
796 "%s/%s", dir_name, in_file->d_name) < 0)
799 "ERROR: failed an snprintf() in "
800 "ni_rsrc_get_local_device_list()\n");
828 if (NI_INVALID_DEVICE_HANDLE != dev_handle)
832 &device_capabilites);
835 if (is_supported_xcoder(
838 ni_devices[xcoder_device_cnt][0] =
'\0';
851 (max_handles <= xcoder_device_cnt))
854 "Disregarding some Netint devices on system over "
855 "limit of NI_MAX_DEVICE_CNT(%d) or max_handles(%d)\n",
862 #if defined(_ANDROID) || defined(__OPENHARMONY__)
870 if (0 == xcoder_device_cnt)
872 ni_log(
NI_LOG_INFO,
"Found %d NVMe devices on system, none of them xcoder\n", nvme_dev_cnt);
873 for (i = 0; i < nvme_dev_cnt; i++)
881 return xcoder_device_cnt;
902 int max_handles,
char **xcoder_refresh_dev_names,
903 int xcoder_refresh_dev_count)
907 #define ANDROID_MAX_DIR_NUM 2
908 int android_dir_num = 0;
909 const char* dir_name_array[ANDROID_MAX_DIR_NUM];
910 dir_name_array[0] =
"/dev";
911 dir_name_array[1] =
"/dev/block";
913 const char* dir_name =
"/dev";
915 int i, xcoder_device_cnt = 0;
917 struct dirent* in_file;
920 ni_device_handle_t dev_handle = NI_INVALID_DEVICE_HANDLE;
922 uint32_t tmp_io_size;
923 bool device_in_ctxt =
false;
925 if ((ni_devices == NULL)||(max_handles == 0))
931 int nvme_dev_cnt = 0;
937 const char *pattern =
"^rdisk[0-9]+$";
938 #elif defined(XCODER_LINUX_VIRTIO_DRIVER_ENABLED)
939 const char *pattern =
"^vd[a-z]$";
941 const char *pattern =
"^nvme[0-9]+(c[0-9]+)?n[0-9]+$";
944 if(regcomp(®ex, pattern, REG_EXTENDED | REG_NOSUB)) {
952 while(xcoder_device_cnt == 0 && android_dir_num < ANDROID_MAX_DIR_NUM)
954 const char *dir_name = dir_name_array[android_dir_num];
958 device_in_ctxt =
false;
959 dev_handle = NI_INVALID_DEVICE_HANDLE;
961 size_t size_of_nvme_devices_x =
sizeof(nvme_devices)/
sizeof(nvme_devices[0]);
962 for(
size_t dimx = 0; dimx < size_of_nvme_devices_x; ++dimx)
964 memset(nvme_devices[dimx], 0,
sizeof(nvme_devices[0]));
969 if (NULL == (FD = opendir(dir_name)))
974 if(android_dir_num < ANDROID_MAX_DIR_NUM)
988 while ((in_file = readdir(FD)))
991 if (!strcmp(in_file->d_name,
".") || !strcmp(in_file->d_name,
".."))
998 if (!strncmp(in_file->d_name, DEV_NAME_PREFIX, strlen(DEV_NAME_PREFIX)))
1000 if (nvme_dev_cnt < 200)
1002 int write_len = snprintf(nvme_devices[nvme_dev_cnt],
1004 dir_name, in_file->d_name);
1008 "ERROR: failed to copy device %d name %s\n",
1009 nvme_dev_cnt, in_file->d_name);
1014 skip_this = regexec(®ex, in_file->d_name, 0, NULL, 0);
1021 "%s/%s", dir_name, in_file->d_name) < 0)
1024 "ERROR: failed an snprintf() in "
1025 "ni_rsrc_get_local_device_list2()\n");
1032 device_in_ctxt =
false;
1033 for (
int j = 0; j < xcoder_refresh_dev_count; j++)
1037 xcoder_refresh_dev_names[j]))
1039 device_in_ctxt =
true;
1053 if (NI_INVALID_DEVICE_HANDLE != dev_handle)
1056 &device_capabilites, device_in_ctxt);
1059 if (is_supported_xcoder(
1062 ni_devices[xcoder_device_cnt][0] =
'\0';
1065 xcoder_device_cnt++;
1074 (max_handles <= xcoder_device_cnt))
1077 "Disregarding some Netint devices on system over "
1078 "limit of NI_MAX_DEVICE_CNT(%d) or max_handles(%d)\n",
1093 if (0 == xcoder_device_cnt)
1095 ni_log(
NI_LOG_INFO,
"Found %d NVMe devices on system, none of them xcoder\n", nvme_dev_cnt);
1096 for (i = 0; i < nvme_dev_cnt; i++)
1102 return xcoder_device_cnt;
1115 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1116 int flags = O_RDWR | O_CLOEXEC;
1117 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1119 ni_lock_handle_t lock;
1123 flags, mode, (
int *)&lock) < 0) {
1131 (
int *)&shm_fd) < 0) {
1139 (
void **)&p_device_queue)) < 0) {
1145 if (! p_device_pool) {
1152 p_device_pool->
lock = lock;
1157 lockf(lock, F_ULOCK, 0);
1159 if (NULL == p_device_pool) {
1163 #ifndef __OPENHARMONY__
1169 return p_device_pool;
1190 int ni_rsrc_init(
int should_match_rev,
int timeout_seconds)
1193 char api_version[5];
1194 int number_of_devices;
1196 int limit_depth = 3;
1205 if (number_of_devices > 0)
1217 if (timeout_seconds == 0) {
1219 "and exit without wait\n");
1224 if (runtime >= (uint32_t)timeout_seconds)
1227 "Timeout exceeded/reached after %u seconds!\n",
1238 ret =
ni_rsrc_init_priv(should_match_rev, number_of_devices, device_names, limit_depth);
1271 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1273 int flags = O_RDWR | O_CLOEXEC;
1274 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1275 char shm_name[32] = { 0 };
1276 char lck_name[32] = { 0 };
1283 if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, &lock) < 0) {
1288 if (ni_rsrc_open_shm(shm_name,
1291 (
int *)&shm_fd) < 0) {
1296 if ((ni_rsrc_mmap_shm(shm_name,
1299 (
void **)&p_device_queue)) < 0) {
1305 if (!p_device_context) {
1315 p_device_context->
lock = lock;
1319 lockf(lock, F_ULOCK, 0);
1321 #ifndef __OPENHARMONY__
1327 return p_device_context;
1340 if (p_device_context)
1344 ReleaseMutex(p_device_context->
lock);
1345 #elif __linux__ || __APPLE__
1346 close(p_device_context->
lock);
1350 free(p_device_context);
1376 bool b_release_pool_mtx =
false;
1378 if ( (NULL == p_device_info) || (NULL == p_device_count) )
1385 if (NULL == p_device_pool)
1392 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
1395 "mutex: %p\n", p_device_pool->
lock);
1399 #elif __linux__ || __APPLE__
1400 lockf(p_device_pool->
lock, F_LOCK, 0);
1403 b_release_pool_mtx =
true;
1406 count = p_device_queue->
xcoder_cnt[device_type];
1409 for (i = 0; i < count; i++)
1412 guid = p_device_queue->
xcoders[device_type][i];
1414 if (p_device_context)
1417 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1420 "mutex: %p\n", p_device_context->
lock);
1421 ReleaseMutex(p_device_pool->
lock);
1427 ReleaseMutex(p_device_context->
lock);
1428 #elif __linux__ || __APPLE__
1429 lockf(p_device_context->
lock, F_LOCK, 0);
1431 lockf(p_device_context->
lock, F_ULOCK, 0);
1436 (*p_device_count)++;
1446 if (b_release_pool_mtx)
1449 ReleaseMutex(p_device_pool->
lock);
1450 #elif __linux__ || __APPLE__
1451 lockf(p_device_pool->
lock, F_ULOCK, 0);
1478 if (NULL == p_device)
1528 if (list_uninitialized)
1535 if (!list_uninitialized)
1547 for (
int dev_index = 0;
1560 uint32_t tmp_io_size;
1562 ni_device_handle_t fd;
1564 for (
int dev_index = 0; dev_index < dev_count; dev_index++)
1566 if (is_str_in_str_array(dev_names[dev_index],
1573 if (NI_INVALID_DEVICE_HANDLE == fd)
1576 dev_names[dev_index]);
1585 dev_names[dev_index]);
1593 p_dev_info = &p_device->
xcoders[dev_type][dev_index];
1599 sizeof(capability.
fw_rev));
1648 " Operations: Crop (ni_quadra_crop), Scale (ni_quadra_scale), Pad "
1649 "(ni_quadra_pad), Overlay (ni_quadra_overlay)\n"
1650 " Drawbox (ni_quadra_drawbox), Rotate (ni_quadra_rotate), XStack (ni_quadra_xstack)\n");
1656 " Operations: ROI (ni_quadra_roi), Background Replace (ni_quadra_bg)\n");
1666 ni_codec_format_str[p_device_info->
dev_cap[i]
1671 ni_dec_name_str[p_device_info->
dev_cap[i]
1673 ni_enc_name_str[p_device_info->
dev_cap[i]
1786 if (NULL == p_device_context)
1792 if (NULL == p_device_info)
1798 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1801 "mutex: %p\n", p_device_context->
lock);
1802 free(p_device_info);
1807 ReleaseMutex(p_device_context->
lock);
1809 lockf(p_device_context->
lock, F_LOCK, 0);
1813 lockf(p_device_context->
lock, F_ULOCK, 0);
1820 return p_device_info;
1855 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
1858 __FUNCTION__, p_device_pool->
lock);
1862 #elif __linux__ || __APPLE__
1863 lockf(p_device_pool->
lock, F_LOCK, 0);
1868 for (i = 0; i < num_coders; i++)
1873 if (p_device_context &&
1885 ReleaseMutex(p_device_pool->
lock);
1886 #elif __linux__ || __APPLE__
1887 lockf(p_device_pool->
lock, F_ULOCK, 0);
1914 if (!p_device_context || !sw_instance_info)
1921 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1924 __func__, p_device_context->
lock);
1927 #elif __linux__ || __APPLE__
1928 lockf(p_device_context->
lock, F_LOCK, 0);
1933 for (i = 0; i < sw_instance_cnt; i++)
1939 ReleaseMutex(p_device_context->
lock);
1940 #elif __linux__ || __APPLE__
1941 lockf(p_device_context->
lock, F_ULOCK, 0);
1971 return p_device_context;
1990 (void) p_device_context;
1995 if (!p_device_context)
2002 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
2005 __func__, p_device_context->
lock);
2007 #elif __linux__ || __APPLE__
2008 lockf(p_device_context->
lock, F_LOCK, 0);
2013 ni_log(
NI_LOG_INFO,
"Warning: releasing resource load %lu > current load %lu\n", load,
2021 #if __linux__ || __APPLE__
2027 "p_device_info: %s\n", __func__, errmsg);
2033 ReleaseMutex(p_device_context->
lock);
2034 #elif __linux__ || __APPLE__
2035 lockf(p_device_context->
lock, F_ULOCK, 0);
2056 uint32_t max_nvme_io_size = 0;
2057 bool b_release_pool_mtx =
false;
2076 session_ctx.
hw_id = guid;
2115 if (WAIT_ABANDONED ==
2116 WaitForSingleObject(p_device_pool->
lock,
2120 "ERROR: ni_rsrc_list_devices() failed to obtain mutex: %p\n",
2121 p_device_pool->
lock);
2126 lockf(p_device_pool->
lock, F_LOCK, 0);
2128 b_release_pool_mtx =
true;
2145 if (NI_INVALID_EVENT_HANDLE == session_ctx.
event_handle)
2156 "guid %d. %s is not avaiable, type: %d, retval:%d\n",
2158 device_type, retval);
2178 "vpu recovery happened on guid %d. %s, retry "
2189 "session open error guid %d. %s, type: %d, "
2192 device_type, retval);
2202 "Error get device resource: guid %d, device_ctx %p\n", guid,
2209 if (b_release_pool_mtx)
2212 ReleaseMutex(p_device_pool->
lock);
2214 lockf(p_device_pool->
lock, F_ULOCK, 0);
2239 #if __linux__ || __APPLE__
2245 unsigned int guid_index_i, guid_index_j, ui_device_type;
2270 rValue = WaitForSingleObject(p_device_pool->
lock, INFINITE);
2271 if (rValue != WAIT_OBJECT_0)
2274 "ERROR: %s() Failed to obtain mutex %p\n",
2276 p_device_pool->
lock);
2280 #elif __linux__ || __APPLE__
2281 lockf(p_device_pool->
lock, F_LOCK, 0);
2291 guid = p_device_queue->
xcoders[ui_device_type][guid_index_i];
2298 if (!p_device_context)
2301 "ERROR: %s() Failed to obtain device context for "
2302 "%s with GUID %u! Undefined behavior!\n",
2317 "ERROR: %s() Devicename format mismatch %s %s\n",
2325 CloseHandle(p_device_context->
lock);
2326 #elif __linux__ || __APPLE__
2330 "%s %s %s deleted\n",
2339 "ERROR: %s(): %s %s %s failed to delete %s\n",
2351 #if __linux__ || __APPLE__
2353 if (!unlink(lck_name))
2356 "%s %s %s deleted\n",
2365 "ERROR: %s(): %s %s %s failed to delete %s\n",
2380 p_device_queue->
xcoders[ui_device_type][guid_index_i] = -1;
2381 p_device_queue->
xcoder_cnt[ui_device_type]--;
2392 memset(guids, -1,
sizeof(guids));
2396 guid = p_device_queue->
xcoders[ui_device_type][guid_index_i];
2399 guids[guid_index_j] = guid;
2401 if (guid_index_j == p_device_queue->
xcoder_cnt[ui_device_type])
2407 memcpy(p_device_queue->
xcoders[ui_device_type], guids,
sizeof(guids));
2410 #if __linux__ || __APPLE__
2412 if (!msync((
void *)p_device_queue,
2414 MS_SYNC|MS_INVALIDATE))
2422 "ERROR: %s(): msync() failed to delete %s: %s\n",
2432 ReleaseMutex(p_device_pool->
lock);
2433 #elif __linux__ || __APPLE__
2434 lockf(p_device_pool->
lock, F_ULOCK, 0);
2440 return return_value;
2455 int xcoder_dev_count = 0;
2483 xcoder_dev_names[i]);
2489 "%d devices retrieved from current pool at start up\n",
2493 "%d devices retrieved from current pool at start up\n",
2504 for (i = 0; i < xcoder_dev_count; i++)
2507 xcoder_dev_names[i]);
2512 xcoder_dev_names[i]);
2516 xcoder_dev_names[i]);
2520 #if __linux__ || __APPLE__
2532 if (0 == unlink(XCODERS_RETRY_LCK_NAME[i]))
2535 i, XCODERS_RETRY_LCK_NAME[i]);
2540 i, XCODERS_RETRY_LCK_NAME[i]);
2572 uint32_t i, existing_number_of_devices;
2593 if (WAIT_ABANDONED == WaitForSingleObject(device_pool->
lock, INFINITE))
2596 "ERROR: %s(): Failed to obtain lock %p\n",
2601 #elif __linux__ || __APPLE__
2602 lockf(device_pool->
lock, F_LOCK, 0);
2609 existing_number_of_devices = device_queue->
xcoder_cnt[device_type];
2614 "ERROR: %s(): Limit of NI_MAX_DEVICE_CNT(%d) existing Quadra "
2615 "devices previously reached. Not adding %s.\n",
2623 for (i = 0; i < existing_number_of_devices; i++)
2627 device_queue->
xcoders[device_type][i]);
2634 "ERROR: %s(): %s already exists in resource pool\n",
2653 ReleaseMutex(device_pool->
lock);
2654 #elif __linux__ || __APPLE__
2655 lockf(device_pool->
lock, F_ULOCK, 0);
2672 if (NI_INVALID_LOCK_HANDLE != p_device_pool->
lock)
2675 CloseHandle(p_device_pool->
lock);
2676 #elif __linux__ || __APPLE__
2677 close(p_device_pool->
lock);
2687 free(p_device_pool);
2706 *lock = CreateMutex(NULL, FALSE, XCODERS_RETRY_LCK_NAME[device_type]);
2712 __func__, XCODERS_RETRY_LCK_NAME[device_type],
2721 open(XCODERS_RETRY_LCK_NAME[device_type], O_RDWR | O_CLOEXEC);
2743 DWORD ret = WaitForSingleObject(*lock, 1);
2744 if (WAIT_OBJECT_0 == ret)
2747 }
else if (WAIT_TIMEOUT != ret)
2754 status = lockf(*lock, F_LOCK, 0);
2766 while (status != 0);
2781 if (lock == NI_INVALID_LOCK_HANDLE)
2787 ni_lock_handle_t status = NI_INVALID_LOCK_HANDLE;
2795 if (ReleaseMutex(lock))
2797 status = (ni_lock_handle_t)(0);
2800 status = lockf(lock, F_ULOCK, 0);
2808 }
while (status != (ni_lock_handle_t)(0));
2814 #endif //_WIN32 defined
2852 char cmd[128] = {0};
2853 char cmd_ret[64] = {0};
2859 ptr = device_name + 5;
2860 snprintf(cmd,
sizeof(cmd) - 1,
"cat /sys/block/%s/device/*/numa_node",ptr);
2861 cmd_fp = popen(cmd,
"r");
2866 if (fgets(cmd_ret,
sizeof(cmd_ret)/
sizeof(cmd_ret[0]), cmd_fp) == 0)
2868 goto get_numa_node_ret;
2870 ret =
atoi(cmd_ret);
2878 static int int_cmp(
const void *a,
const void *b)
2880 const int *ia = (
const int *)a;
2881 const int *ib = (
const int *)b;
2882 return (*ia == *ib) ? 0 : ((*ia > *ib) ? 1 : -1);
2886 static int ni_hw_device_info_quadra_threshold_param_t_compare(
const void *pl,
const void *pr)
2909 int factor_8_10 = 1;
2910 uint32_t resolution = decoder_param->
h * decoder_param->
w;
2915 return resolution >= 1920*1080 ?
2916 (int)(((uint64_t)(resolution)*(uint64_t)(decoder_param->
fps)*(uint64_t)(factor_8_10)*100)/1440/1920/1080) :
2917 (
int)((uint64_t)(resolution)*(uint64_t)(decoder_param->
fps)*(uint64_t)(factor_8_10)*100/2880/1280/720);
2931 double factor = 1.0;
2932 double factor_codec = 1.0;
2933 double factor_rdoq = 1.0;
2934 double factor_rdoLevel = 1.0;
2935 double factor_lookahead = 1.0;
2936 double factor_8_10_bit = 1.0;
2937 double factor_720p = 1.0;
2939 int resolution = (int)(encoder_param->
w * encoder_param->
h);
2944 factor_codec = 0.67;
2956 factor_rdoLevel = (encoder_param->
rdoLevel == 2) ? 1.91 : 3.28;
2961 factor_lookahead = (double)(encoder_param->
lookaheadDepth * 0.0014 + 1.012);
2967 factor_8_10_bit = 2;
2970 factor_720p = 1.125;
2971 factor = factor_codec * factor_8_10_bit * factor_rdoq * factor_rdoLevel
2972 * factor_lookahead * factor_720p;
2978 ((uint32_t)((uint32_t)factor*encoder_param->
fps * resolution)) /
2979 ((3840 * 2160 * 60ULL) / 100 * 4));
2994 static int check_hw_info_shared_mem_calculate_b_scale(
int h,
int w,
int bit_8_10,
int rgba)
2996 const int stride = 128;
2997 int estimated_yuv_size = rgba ?
3000 ( ((w + stride - 1)/stride)*stride + ((w/2 + stride - 1)/stride)*stride ) * h:
3001 ( ((w * 2 + stride - 1)/stride)*stride + ((w + stride - 1)/stride)*stride ) * h;
3002 const int b_unit = 1601536;
3003 int b_scale = (estimated_yuv_size + b_unit -1) / b_unit;
3035 const int v32_ofCores_calculate = 0;
3037 int b_counts = (int)(v32_ofCores_calculate +
3040 (encoder_param->
uploader ? 1 : 0) * 3 +
3042 int b_scale = check_hw_info_shared_mem_calculate_b_scale(encoder_param->
h, encoder_param->
w,
3044 return b_scale * b_counts;
3068 const int hw_frame = decoder_param->
hw_frame;
3070 const int v30_xlsx = 0;
3071 int b_counts = 1 * (v30_xlsx +
3072 (hw_frame ? 0 : 1)*3 +
3074 int b_scale = check_hw_info_shared_mem_calculate_b_scale(decoder_param->
h, decoder_param->
w,
3076 return b_scale * b_counts;
3103 const int v30_xlsx = 0;
3104 int b_counts = 1 * (v30_xlsx +
3107 int b_scale = check_hw_info_shared_mem_calculate_b_scale(scaler_param->
h, scaler_param->
w,
3109 return b_scale * b_counts;
3127 const int total = 2456;
3128 int task_mem_usage = 0;
3129 int task_mem_precentage = 0;
3135 for(i = 0; i < card_num; ++i)
3144 task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16);
3148 task_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param);
3152 task_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3156 int decoder_shared_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16);
3157 int encoder_shared_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param);
3158 int scaler_shared_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3159 task_mem_usage = decoder_shared_mem_usage + ((encoder_shared_mem_usage > scaler_shared_mem_usage) ?
3160 encoder_shared_mem_usage : scaler_shared_mem_usage);
3165 task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16) +
3166 check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param)+
3167 check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3170 task_mem_precentage = 100 * task_mem_usage / total;
3172 if(task_mem_precentage > 90)
3175 task_mem_precentage = 90;
3178 for(i = 0;i<card_num;++i)
3180 if(card_remove[i] == 1)
3205 if(p_coder_param == NULL)
3207 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_coder_param\n");
3208 return p_coder_param;
3217 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3218 free(p_coder_param);
3219 p_coder_param = NULL;
3220 return p_coder_param;
3228 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3229 free(p_coder_param);
3230 p_coder_param = NULL;
3231 return p_coder_param;
3239 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3240 free(p_coder_param);
3241 p_coder_param = NULL;
3242 return p_coder_param;
3248 if(p_coder_param->
ai_param == NULL)
3250 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3251 free(p_coder_param);
3252 p_coder_param = NULL;
3253 return p_coder_param;
3261 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3262 free(p_coder_param);
3263 p_coder_param = NULL;
3264 return p_coder_param;
3269 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3272 free(p_coder_param);
3273 p_coder_param = NULL;
3274 return p_coder_param;
3279 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3284 free(p_coder_param);
3285 p_coder_param = NULL;
3286 return p_coder_param;
3289 if(p_coder_param->
ai_param == NULL)
3291 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3298 free(p_coder_param);
3299 p_coder_param = NULL;
3300 return p_coder_param;
3340 return p_coder_param;
3356 if(p_hw_device_info_quadra_coder_param == NULL)
3372 free(p_hw_device_info_quadra_coder_param->
scaler_param);
3373 p_hw_device_info_quadra_coder_param->
scaler_param = NULL;
3375 if(p_hw_device_info_quadra_coder_param->
ai_param)
3377 free(p_hw_device_info_quadra_coder_param->
ai_param);
3378 p_hw_device_info_quadra_coder_param->
ai_param = NULL;
3380 free(p_hw_device_info_quadra_coder_param);
3397 if(!p_hw_device_info)
3399 ni_log(
NI_LOG_ERROR,
"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t\n");
3400 goto p_hw_device_info_end;
3407 ni_log(
NI_LOG_ERROR,
"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t->device_type\n");
3408 goto device_type_end;
3426 if(p_hw_device_info->
card_info[i] == NULL)
3429 goto card_info_i_end;
3433 return p_hw_device_info;
3450 free(p_hw_device_info);
3451 p_hw_device_info = NULL;
3452 p_hw_device_info_end:
3467 if(!p_hw_device_info)
3480 free(p_hw_device_info);
3497 int should_match_rev = 1;
3498 int module_count = 1;
3500 int32_t *module_id_arr = NULL;
3506 int *card_remove = NULL;
3509 uint64_t decoder_need_load = 0;
3510 uint64_t encoder_need_load = 0;
3513 int hw_info_param_num = hw_mode ? 4 : 1;
3514 int device_type_num = 1;
3515 const int all_device_type_num = 4;
3523 bool b_valid =
false;
3531 if(!pointer_to_p_hw_device_info)
3533 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: pointer_to_p_hw_device_info is NULL.\n");
3537 if(*pointer_to_p_hw_device_info)
3539 p_hw_device_info = *pointer_to_p_hw_device_info;
3551 }
else if(hw_mode && hw_mode != coder_param->
hw_mode)
3553 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: hw_mode = %d, coder_param->hw_mode = %d\n",
3554 hw_mode,coder_param->
hw_mode);
3560 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_ENCODER but coder_param->encoder_param == NULL\n");
3565 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_DECODER but coder_param->decoder_param == NULL\n");
3570 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_SCALER but coder_param->scaler_param == NULL\n");
3575 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_AI but coder_param->ai_param == NULL\n");
3581 if((task_mode != 0 && task_mode != 1) ||
3590 task_mode, preferential_device_type);
3594 if(!hw_info_threshold_param)
3600 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: hw_info_threshold_param is NULL.\n");
3603 for(i = 0;i < hw_info_param_num; ++i)
3605 if(hw_info_threshold_param[i].load_threshold < 0||
3606 hw_info_threshold_param[i].load_threshold > 100 ||
3607 hw_info_threshold_param[i].task_num_threshold < 0 ||
3618 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",
3619 (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);
3674 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
3679 #elif defined(__linux__)
3680 if (lockf(p_device_pool->
lock, F_LOCK, 0))
3706 for(i = 0; i < all_device_type_num; ++i)
3708 if(all_need_device_type[i] == preferential_device_type)
3711 all_need_device_type[i] = all_need_device_type[0];
3712 all_need_device_type[0] = tmp;
3717 qsort(&all_need_device_type[1], all_device_type_num - 1,
sizeof(
ni_device_type_t), int_cmp);
3723 device_type_num = 4;
3725 for(i = 0; i < device_type_num; ++i)
3727 if(hw_info_threshold_param[i].device_type == preferential_device_type)
3730 hw_info_threshold_param[i] = hw_info_threshold_param[0];
3731 hw_info_threshold_param[0] = tmp;
3735 qsort(&hw_info_threshold_param[1], device_type_num - 1,
3739 if(!(*pointer_to_p_hw_device_info))
3742 if(!p_hw_device_info)
3747 *pointer_to_p_hw_device_info = p_hw_device_info;
3758 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->device_type is NULL\n");
3764 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->card_info is NULL\n");
3768 for(i = 0; i < device_type_num; ++i)
3772 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);
3786 p_hw_device_info->
device_type[i] = all_need_device_type[i];
3824 card_remove = (int32_t *)malloc(
sizeof(int32_t) * p_hw_device_info->
available_card_num);
3834 module_count = coders->
xcoder_cnt[preferential_device_type];
3842 module_id_arr = (int32_t *)malloc(
sizeof(int32_t) * module_count);
3851 memcpy(module_id_arr, coders->
xcoders[preferential_device_type],
sizeof(int32_t) * module_count);
3855 qsort(module_id_arr, module_count,
sizeof(int32_t), int_cmp);
3861 for(
int j = 0; j < device_type_num; ++j)
3863 memset(&xCtxt, 0,
sizeof(xCtxt));
3865 if(p_device_context)
3942 p_device_context = NULL;
3956 decoder_need_load = check_hw_info_decoder_need_load(coder_param->
decoder_param);
3960 encoder_need_load = check_hw_info_encoder_need_load(coder_param->
encoder_param);
3975 ni_log(
NI_LOG_DEBUG,
"%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3977 ni_log(
NI_LOG_INFO,
"%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3989 if(card_remove[i] == 1)
3996 if(decoder_need_load + p_hw_device_info->card_info[j][i].model_load >= 100)
4044 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,10);
4046 else if(preferential_device_type == 0)
4048 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,0);
4050 else if(preferential_device_type == 1)
4052 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,1);
4054 else if(preferential_device_type == 2)
4056 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,2);
4064 int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
4065 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4067 if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
4068 card_remove[i] == 0)
4070 min_task_num = p_hw_device_info->card_info[0][i].task_num;
4075 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4077 if (p_hw_device_info->card_info[0][i].load < min_load &&
4078 card_remove[i] == 0 &&
4079 p_hw_device_info->card_info[0][i].task_num == min_task_num)
4081 min_load = p_hw_device_info->card_info[0][i].load;
4082 p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4090 int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
4091 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4093 if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
4094 card_remove[i] == 0)
4096 p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4097 min_task_num = p_hw_device_info->card_info[0][i].task_num;
4102 if (p_hw_device_info->card_current_card >= 0)
4109 ReleaseMutex((HANDLE)p_device_pool->
lock);
4111 #elif defined(__linux__)
4112 if (lockf(p_device_pool->
lock, F_ULOCK,0))
4115 if(p_hw_device_info)
4122 p_device_context = NULL;
4127 free(module_id_arr);
4128 module_id_arr = NULL;
4133 dev_ctxt_arr = NULL;
4149 p_hw_device_info->card_current_card, retval);
4154 ni_log(
NI_LOG_DEBUG,
"In sw_mode select device_type %s card_current_card %d retval %d\n",
4156 ni_log(
NI_LOG_INFO,
"In sw_mode select device_type %s card_current_card %d retval %d\n",
4158 ((preferential_device_type == 0) ?
"decode" : (preferential_device_type == 1 ?
"encode" : (preferential_device_type == 2 ?
"scaler" :
"ai "))), p_hw_device_info->card_current_card, retval);
4190 int width,
int height,
4202 uint32_t num_sw_instances = 0;
4203 int least_model_load = 0;
4204 uint64_t job_mload = 0;
4224 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
4228 #elif __linux__ || __APPLE__
4229 lockf(p_device_pool->
lock, F_LOCK, 0);
4235 for (i = 0; i < count; i++)
4239 if (!p_device_context)
4242 "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4251 if (NI_INVALID_DEVICE_HANDLE == p_session_context.
device_handle)
4270 g_device_type_str[device_type],
4278 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
4281 __func__, p_device_context->
lock);
4283 #elif __linux__ || __APPLE__
4284 lockf(p_device_context->
lock, F_LOCK, 0);
4292 load = p_device_info->
load;
4293 least_model_load = p_device_info->
model_load;
4297 ni_log(
NI_LOG_INFO,
"Coder [%d]: %d , load: %d (%d), activ_inst: %d , max_inst %d\n",
4318 if (p_device_info->
model_load < least_model_load)
4321 least_model_load = p_device_info->
model_load;
4324 else if (p_device_info->
load < load)
4327 load = p_device_info->
load;
4334 ReleaseMutex(p_device_context->
lock);
4335 #elif __linux__ || __APPLE__
4336 lockf(p_device_context->
lock, F_ULOCK, 0);
4344 if (!p_device_context)
4347 "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4353 job_mload = width * height * frame_rate;
4359 p_device_context = NULL;
4364 ReleaseMutex(p_device_pool->
lock);
4365 #elif __linux__ || __APPLE__
4366 lockf(p_device_pool->
lock, F_ULOCK, 0);
4373 *p_load = job_mload;
4375 return p_device_context;