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;
1191 if (number_of_devices > 0)
1203 if (timeout_seconds == 0) {
1205 "and exit without wait\n");
1210 if (runtime >= (uint32_t)timeout_seconds)
1213 "Timeout exceeded/reached after %u seconds!\n",
1224 ret =
ni_rsrc_init_priv(should_match_rev, number_of_devices, device_names, limit_depth);
1257 ni_rsrc_shm_state state = NI_RSRC_SHM_IS_INVALID;
1259 int flags = O_RDWR | O_CLOEXEC;
1260 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
1261 char shm_name[32] = { 0 };
1262 char lck_name[32] = { 0 };
1269 if (ni_rsrc_try_get_shm_lock(lck_name, flags, mode, &lock) < 0) {
1274 if (ni_rsrc_open_shm(shm_name,
1277 (
int *)&shm_fd) < 0) {
1282 if ((ni_rsrc_mmap_shm(shm_name,
1285 (
void **)&p_device_queue)) < 0) {
1291 if (!p_device_context) {
1298 strncpy(p_device_context->
shm_name, shm_name,
sizeof(p_device_context->
shm_name));
1299 p_device_context->
lock = lock;
1303 lockf(lock, F_ULOCK, 0);
1305 #ifndef __OPENHARMONY__
1311 return p_device_context;
1324 if (p_device_context)
1328 ReleaseMutex(p_device_context->
lock);
1329 #elif __linux__ || __APPLE__
1330 close(p_device_context->
lock);
1334 free(p_device_context);
1360 bool b_release_pool_mtx =
false;
1362 if ( (NULL == p_device_info) || (NULL == p_device_count) )
1369 if (NULL == p_device_pool)
1376 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
1379 "mutex: %p\n", p_device_pool->
lock);
1383 #elif __linux__ || __APPLE__
1384 lockf(p_device_pool->
lock, F_LOCK, 0);
1387 b_release_pool_mtx =
true;
1390 count = p_device_queue->
xcoder_cnt[device_type];
1393 for (i = 0; i < count; i++)
1396 guid = p_device_queue->
xcoders[device_type][i];
1398 if (p_device_context)
1401 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1404 "mutex: %p\n", p_device_context->
lock);
1405 ReleaseMutex(p_device_pool->
lock);
1411 ReleaseMutex(p_device_context->
lock);
1412 #elif __linux__ || __APPLE__
1413 lockf(p_device_context->
lock, F_LOCK, 0);
1415 lockf(p_device_context->
lock, F_ULOCK, 0);
1420 (*p_device_count)++;
1430 if (b_release_pool_mtx)
1433 ReleaseMutex(p_device_pool->
lock);
1434 #elif __linux__ || __APPLE__
1435 lockf(p_device_pool->
lock, F_ULOCK, 0);
1462 if (NULL == p_device)
1512 if (list_uninitialized)
1519 if (!list_uninitialized)
1531 for (
int dev_index = 0;
1535 strcpy(initialized_dev_names[dev_index], p_dev_info->
dev_name);
1544 uint32_t tmp_io_size;
1546 ni_device_handle_t fd;
1548 for (
int dev_index = 0; dev_index < dev_count; dev_index++)
1550 if (is_str_in_str_array(dev_names[dev_index],
1557 if (NI_INVALID_DEVICE_HANDLE == fd)
1560 dev_names[dev_index]);
1569 dev_names[dev_index]);
1577 p_dev_info = &p_device->
xcoders[dev_type][dev_index];
1583 sizeof(capability.
fw_rev));
1595 strcpy(p_dev_info->
dev_name, dev_names[dev_index]);
1632 " Operations: Crop (ni_quadra_crop), Scale (ni_quadra_scale), Pad "
1633 "(ni_quadra_pad), Overlay (ni_quadra_overlay)\n"
1634 " Drawbox (ni_quadra_drawbox), Rotate (ni_quadra_rotate), XStack (ni_quadra_xstack)\n");
1640 " Operations: ROI (ni_quadra_roi), Background Replace (ni_quadra_bg)\n");
1650 ni_codec_format_str[p_device_info->
dev_cap[i]
1655 ni_dec_name_str[p_device_info->
dev_cap[i]
1657 ni_enc_name_str[p_device_info->
dev_cap[i]
1766 if (NULL == p_device_context)
1772 if (NULL == p_device_info)
1778 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1781 "mutex: %p\n", p_device_context->
lock);
1782 free(p_device_info);
1787 ReleaseMutex(p_device_context->
lock);
1789 lockf(p_device_context->
lock, F_LOCK, 0);
1793 lockf(p_device_context->
lock, F_ULOCK, 0);
1800 return p_device_info;
1835 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
1838 __FUNCTION__, p_device_pool->
lock);
1842 #elif __linux__ || __APPLE__
1843 lockf(p_device_pool->
lock, F_LOCK, 0);
1848 for (i = 0; i < num_coders; i++)
1853 if (p_device_context &&
1865 ReleaseMutex(p_device_pool->
lock);
1866 #elif __linux__ || __APPLE__
1867 lockf(p_device_pool->
lock, F_ULOCK, 0);
1894 if (!p_device_context || !sw_instance_info)
1901 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1904 __func__, p_device_context->
lock);
1907 #elif __linux__ || __APPLE__
1908 lockf(p_device_context->
lock, F_LOCK, 0);
1913 for (i = 0; i < sw_instance_cnt; i++)
1919 ReleaseMutex(p_device_context->
lock);
1920 #elif __linux__ || __APPLE__
1921 lockf(p_device_context->
lock, F_ULOCK, 0);
1951 return p_device_context;
1970 (void) p_device_context;
1975 if (!p_device_context)
1982 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
1985 __func__, p_device_context->
lock);
1987 #elif __linux__ || __APPLE__
1988 lockf(p_device_context->
lock, F_LOCK, 0);
1993 ni_log(
NI_LOG_INFO,
"Warning: releasing resource load %lu > current load %lu\n", load,
2001 #if __linux__ || __APPLE__
2005 "p_device_info: %s\n", __func__, strerror(
NI_ERRNO));
2011 ReleaseMutex(p_device_context->
lock);
2012 #elif __linux__ || __APPLE__
2013 lockf(p_device_context->
lock, F_ULOCK, 0);
2034 uint32_t max_nvme_io_size = 0;
2035 bool b_release_pool_mtx =
false;
2054 session_ctx.
hw_id = guid;
2093 if (WAIT_ABANDONED ==
2094 WaitForSingleObject(p_device_pool->
lock,
2098 "ERROR: ni_rsrc_list_devices() failed to obtain mutex: %p\n",
2099 p_device_pool->
lock);
2104 lockf(p_device_pool->
lock, F_LOCK, 0);
2106 b_release_pool_mtx =
true;
2123 if (NI_INVALID_EVENT_HANDLE == session_ctx.
event_handle)
2134 "guid %d. %s is not avaiable, type: %d, retval:%d\n",
2136 device_type, retval);
2156 "vpu recovery happened on guid %d. %s, retry "
2167 "session open error guid %d. %s, type: %d, "
2170 device_type, retval);
2180 "Error get device resource: guid %d, device_ctx %p\n", guid,
2187 if (b_release_pool_mtx)
2190 ReleaseMutex(p_device_pool->
lock);
2192 lockf(p_device_pool->
lock, F_ULOCK, 0);
2217 #if __linux__ || __APPLE__
2223 unsigned int guid_index_i, guid_index_j, ui_device_type;
2247 rValue = WaitForSingleObject(p_device_pool->
lock, INFINITE);
2248 if (rValue != WAIT_OBJECT_0)
2251 "ERROR: %s() Failed to obtain mutex %p\n",
2253 p_device_pool->
lock);
2257 #elif __linux__ || __APPLE__
2258 lockf(p_device_pool->
lock, F_LOCK, 0);
2268 guid = p_device_queue->
xcoders[ui_device_type][guid_index_i];
2275 if (!p_device_context)
2278 "ERROR: %s() Failed to obtain device context for "
2279 "%s with GUID %u! Undefined behavior!\n",
2294 "ERROR: %s() Devicename format mismatch %s %s\n",
2302 CloseHandle(p_device_context->
lock);
2303 #elif __linux__ || __APPLE__
2307 "%s %s %s deleted\n",
2315 "ERROR: %s(): %s %s %s failed to delete %s\n",
2327 #if __linux__ || __APPLE__
2329 if (!unlink(lck_name))
2332 "%s %s %s deleted\n",
2340 "ERROR: %s(): %s %s %s failed to delete %s\n",
2355 p_device_queue->
xcoders[ui_device_type][guid_index_i] = -1;
2356 p_device_queue->
xcoder_cnt[ui_device_type]--;
2367 memset(guids, -1,
sizeof(guids));
2371 guid = p_device_queue->
xcoders[ui_device_type][guid_index_i];
2374 guids[guid_index_j] = guid;
2376 if (guid_index_j == p_device_queue->
xcoder_cnt[ui_device_type])
2382 memcpy(p_device_queue->
xcoders[ui_device_type], guids,
sizeof(guids));
2385 #if __linux__ || __APPLE__
2387 if (!msync((
void *)p_device_queue,
2389 MS_SYNC|MS_INVALIDATE))
2396 "ERROR: %s(): msync() failed to delete %s: %s\n",
2406 ReleaseMutex(p_device_pool->
lock);
2407 #elif __linux__ || __APPLE__
2408 lockf(p_device_pool->
lock, F_ULOCK, 0);
2414 return return_value;
2429 int xcoder_dev_count = 0;
2451 strcpy(xcoder_dev_names[i],
2455 xcoder_dev_names[i]);
2461 "%d devices retrieved from current pool at start up\n",
2465 "%d devices retrieved from current pool at start up\n",
2476 for (i = 0; i < xcoder_dev_count; i++)
2479 xcoder_dev_names[i]);
2484 xcoder_dev_names[i]);
2488 xcoder_dev_names[i]);
2492 #if __linux__ || __APPLE__
2504 if (0 == unlink(XCODERS_RETRY_LCK_NAME[i]))
2507 i, XCODERS_RETRY_LCK_NAME[i]);
2512 i, XCODERS_RETRY_LCK_NAME[i]);
2544 uint32_t i, existing_number_of_devices;
2565 if (WAIT_ABANDONED == WaitForSingleObject(device_pool->
lock, INFINITE))
2568 "ERROR: %s(): Failed to obtain lock %p\n",
2573 #elif __linux__ || __APPLE__
2574 lockf(device_pool->
lock, F_LOCK, 0);
2581 existing_number_of_devices = device_queue->
xcoder_cnt[device_type];
2586 "ERROR: %s(): Limit of NI_MAX_DEVICE_CNT(%d) existing Quadra "
2587 "devices previously reached. Not adding %s.\n",
2595 for (i = 0; i < existing_number_of_devices; i++)
2599 device_queue->
xcoders[device_type][i]);
2606 "ERROR: %s(): %s already exists in resource pool\n",
2625 ReleaseMutex(device_pool->
lock);
2626 #elif __linux__ || __APPLE__
2627 lockf(device_pool->
lock, F_ULOCK, 0);
2644 if (NI_INVALID_LOCK_HANDLE != p_device_pool->
lock)
2647 CloseHandle(p_device_pool->
lock);
2648 #elif __linux__ || __APPLE__
2649 close(p_device_pool->
lock);
2659 free(p_device_pool);
2677 *lock = CreateMutex(NULL, FALSE, XCODERS_RETRY_LCK_NAME[device_type]);
2682 __func__, XCODERS_RETRY_LCK_NAME[device_type],
2691 open(XCODERS_RETRY_LCK_NAME[device_type], O_RDWR | O_CLOEXEC);
2695 ni_log(
NI_LOG_ERROR,
"Can not lock down the file lock. Error: %s\n", strerror(errno));
2712 DWORD ret = WaitForSingleObject(*lock, 1);
2713 if (WAIT_OBJECT_0 == ret)
2716 }
else if (WAIT_TIMEOUT != ret)
2722 status = lockf(*lock, F_LOCK, 0);
2734 while (status != 0);
2749 if (lock == NI_INVALID_LOCK_HANDLE)
2755 ni_lock_handle_t status = NI_INVALID_LOCK_HANDLE;
2763 if (ReleaseMutex(lock))
2765 status = (ni_lock_handle_t)(0);
2768 status = lockf(lock, F_ULOCK, 0);
2776 }
while (status != (ni_lock_handle_t)(0));
2782 #endif //_WIN32 defined
2804 static int int_cmp(
const void *a,
const void *b)
2806 const int *ia = (
const int *)a;
2807 const int *ib = (
const int *)b;
2808 return (*ia == *ib) ? 0 : ((*ia > *ib) ? 1 : -1);
2812 static int ni_hw_device_info_quadra_threshold_param_t_compare(
const void *pl,
const void *pr)
2835 int factor_8_10 = 1;
2836 uint32_t resolution = decoder_param->
h * decoder_param->
w;
2841 return resolution >= 1920*1080 ?
2842 (int)(((uint64_t)(resolution)*(uint64_t)(decoder_param->
fps)*(uint64_t)(factor_8_10)*100)/1440/1920/1080) :
2843 (
int)((uint64_t)(resolution)*(uint64_t)(decoder_param->
fps)*(uint64_t)(factor_8_10)*100/2880/1280/720);
2857 double factor = 1.0;
2858 double factor_codec = 1.0;
2859 double factor_rdoq = 1.0;
2860 double factor_rdoLevel = 1.0;
2861 double factor_lookahead = 1.0;
2862 double factor_8_10_bit = 1.0;
2863 double factor_720p = 1.0;
2865 int resolution = (int)(encoder_param->
w * encoder_param->
h);
2870 factor_codec = 0.67;
2882 factor_rdoLevel = (encoder_param->
rdoLevel == 2) ? 1.91 : 3.28;
2887 factor_lookahead = (double)(encoder_param->
lookaheadDepth * 0.0014 + 1.012);
2893 factor_8_10_bit = 2;
2896 factor_720p = 1.125;
2897 factor = factor_codec * factor_8_10_bit * factor_rdoq * factor_rdoLevel
2898 * factor_lookahead * factor_720p;
2904 ((uint32_t)((uint32_t)factor*encoder_param->
fps * resolution)) /
2905 ((3840 * 2160 * 60ULL) / 100 * 4));
2920 static int check_hw_info_shared_mem_calculate_b_scale(
int h,
int w,
int bit_8_10,
int rgba)
2922 const int stride = 128;
2923 int estimated_yuv_size = rgba ?
2926 ( ((w + stride - 1)/stride)*stride + ((w/2 + stride - 1)/stride)*stride ) * h:
2927 ( ((w * 2 + stride - 1)/stride)*stride + ((w + stride - 1)/stride)*stride ) * h;
2928 const int b_unit = 1601536;
2929 int b_scale = (estimated_yuv_size + b_unit -1) / b_unit;
2961 const int v32_ofCores_calculate = 0;
2963 int b_counts = (int)(v32_ofCores_calculate +
2966 (encoder_param->
uploader ? 1 : 0) * 3 +
2968 int b_scale = check_hw_info_shared_mem_calculate_b_scale(encoder_param->
h, encoder_param->
w,
2970 return b_scale * b_counts;
2994 const int hw_frame = decoder_param->
hw_frame;
2996 const int v30_xlsx = 0;
2997 int b_counts = 1 * (v30_xlsx +
2998 (hw_frame ? 0 : 1)*3 +
3000 int b_scale = check_hw_info_shared_mem_calculate_b_scale(decoder_param->
h, decoder_param->
w,
3002 return b_scale * b_counts;
3029 const int v30_xlsx = 0;
3030 int b_counts = 1 * (v30_xlsx +
3033 int b_scale = check_hw_info_shared_mem_calculate_b_scale(scaler_param->
h, scaler_param->
w,
3035 return b_scale * b_counts;
3053 const int total = 2456;
3054 int task_mem_usage = 0;
3055 int task_mem_precentage = 0;
3061 for(i = 0; i < card_num; ++i)
3070 task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16);
3074 task_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param);
3078 task_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3082 int decoder_shared_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16);
3083 int encoder_shared_mem_usage = check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param);
3084 int scaler_shared_mem_usage = check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3085 task_mem_usage = decoder_shared_mem_usage + ((encoder_shared_mem_usage > scaler_shared_mem_usage) ?
3086 encoder_shared_mem_usage : scaler_shared_mem_usage);
3091 task_mem_usage = check_hw_info_decoder_shared_mem_usage(coder_param->
decoder_param,16) +
3092 check_hw_info_encoder_shared_mem_usage(coder_param->
encoder_param)+
3093 check_hw_info_scaler_shared_mem_usage(coder_param->
scaler_param,16);
3096 task_mem_precentage = 100 * task_mem_usage / total;
3098 if(task_mem_precentage > 90)
3101 task_mem_precentage = 90;
3104 for(i = 0;i<card_num;++i)
3106 if(card_remove[i] == 1)
3131 if(p_coder_param == NULL)
3133 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_coder_param\n");
3134 return p_coder_param;
3143 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3144 free(p_coder_param);
3145 p_coder_param = NULL;
3146 return p_coder_param;
3154 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3155 free(p_coder_param);
3156 p_coder_param = NULL;
3157 return p_coder_param;
3165 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3166 free(p_coder_param);
3167 p_coder_param = NULL;
3168 return p_coder_param;
3174 if(p_coder_param->
ai_param == NULL)
3176 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3177 free(p_coder_param);
3178 p_coder_param = NULL;
3179 return p_coder_param;
3187 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_encoder_param\n");
3188 free(p_coder_param);
3189 p_coder_param = NULL;
3190 return p_coder_param;
3195 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_decoder_param\n");
3198 free(p_coder_param);
3199 p_coder_param = NULL;
3200 return p_coder_param;
3205 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_scaler_param\n");
3210 free(p_coder_param);
3211 p_coder_param = NULL;
3212 return p_coder_param;
3215 if(p_coder_param->
ai_param == NULL)
3217 ni_log(
NI_LOG_ERROR,
"Error: Failed to allocate memory for hw_device_info_quadra_ai_param\n");
3224 free(p_coder_param);
3225 p_coder_param = NULL;
3226 return p_coder_param;
3266 return p_coder_param;
3282 if(p_hw_device_info_quadra_coder_param == NULL)
3298 free(p_hw_device_info_quadra_coder_param->
scaler_param);
3299 p_hw_device_info_quadra_coder_param->
scaler_param = NULL;
3301 if(p_hw_device_info_quadra_coder_param->
ai_param)
3303 free(p_hw_device_info_quadra_coder_param->
ai_param);
3304 p_hw_device_info_quadra_coder_param->
ai_param = NULL;
3306 free(p_hw_device_info_quadra_coder_param);
3323 if(!p_hw_device_info)
3325 ni_log(
NI_LOG_ERROR,
"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t\n");
3326 goto p_hw_device_info_end;
3333 ni_log(
NI_LOG_ERROR,
"ERROR: Failed to allocate memory for p_hw_device_info_quadra_t->device_type\n");
3334 goto device_type_end;
3352 if(p_hw_device_info->
card_info[i] == NULL)
3355 goto card_info_i_end;
3359 return p_hw_device_info;
3376 free(p_hw_device_info);
3377 p_hw_device_info = NULL;
3378 p_hw_device_info_end:
3393 if(!p_hw_device_info)
3406 free(p_hw_device_info);
3423 int should_match_rev = 1;
3424 int module_count = 1;
3426 int32_t *module_id_arr = NULL;
3432 int *card_remove = NULL;
3435 uint64_t decoder_need_load = 0;
3436 uint64_t encoder_need_load = 0;
3439 int hw_info_param_num = hw_mode ? 4 : 1;
3440 int device_type_num = 1;
3441 const int all_device_type_num = 4;
3449 bool b_valid =
false;
3457 if(!pointer_to_p_hw_device_info)
3459 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: pointer_to_p_hw_device_info is NULL.\n");
3463 if(*pointer_to_p_hw_device_info)
3465 p_hw_device_info = *pointer_to_p_hw_device_info;
3477 }
else if(hw_mode && hw_mode != coder_param->
hw_mode)
3479 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: hw_mode = %d, coder_param->hw_mode = %d\n",
3480 hw_mode,coder_param->
hw_mode);
3486 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_ENCODER but coder_param->encoder_param == NULL\n");
3491 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_DECODER but coder_param->decoder_param == NULL\n");
3496 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_SCALER but coder_param->scaler_param == NULL\n");
3501 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: preferential_device_type == NI_DEVICE_TYPE_AI but coder_param->ai_param == NULL\n");
3507 if((task_mode != 0 && task_mode != 1) ||
3516 task_mode, preferential_device_type);
3520 if(!hw_info_threshold_param)
3526 ni_log(
NI_LOG_ERROR,
"Error: Invalid input params: hw_info_threshold_param is NULL.\n");
3529 for(i = 0;i < hw_info_param_num; ++i)
3531 if(hw_info_threshold_param[i].load_threshold < 0||
3532 hw_info_threshold_param[i].load_threshold > 100 ||
3533 hw_info_threshold_param[i].task_num_threshold < 0 ||
3544 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",
3545 (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);
3600 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
3605 #elif defined(__linux__)
3606 if (lockf(p_device_pool->
lock, F_LOCK, 0))
3632 for(i = 0; i < all_device_type_num; ++i)
3634 if(all_need_device_type[i] == preferential_device_type)
3637 all_need_device_type[i] = all_need_device_type[0];
3638 all_need_device_type[0] = tmp;
3643 qsort(&all_need_device_type[1], all_device_type_num - 1,
sizeof(
ni_device_type_t), int_cmp);
3649 device_type_num = 4;
3651 for(i = 0; i < device_type_num; ++i)
3653 if(hw_info_threshold_param[i].device_type == preferential_device_type)
3656 hw_info_threshold_param[i] = hw_info_threshold_param[0];
3657 hw_info_threshold_param[0] = tmp;
3661 qsort(&hw_info_threshold_param[1], device_type_num - 1,
3665 if(!(*pointer_to_p_hw_device_info))
3668 if(!p_hw_device_info)
3673 *pointer_to_p_hw_device_info = p_hw_device_info;
3684 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->device_type is NULL\n");
3690 ni_log(
NI_LOG_ERROR,
"ERROR: pointer_to_p_hw_device_info is not a pointer to NULL, but ->card_info is NULL\n");
3694 for(i = 0; i < device_type_num; ++i)
3698 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);
3712 p_hw_device_info->
device_type[i] = all_need_device_type[i];
3750 card_remove = (int32_t *)malloc(
sizeof(int32_t) * p_hw_device_info->
available_card_num);
3760 module_count = coders->
xcoder_cnt[preferential_device_type];
3768 module_id_arr = (int32_t *)malloc(
sizeof(int32_t) * module_count);
3777 memcpy(module_id_arr, coders->
xcoders[preferential_device_type],
sizeof(int32_t) * module_count);
3781 qsort(module_id_arr, module_count,
sizeof(int32_t), int_cmp);
3787 for(
int j = 0; j < device_type_num; ++j)
3789 memset(&xCtxt, 0,
sizeof(xCtxt));
3791 if(p_device_context)
3868 p_device_context = NULL;
3882 decoder_need_load = check_hw_info_decoder_need_load(coder_param->
decoder_param);
3886 encoder_need_load = check_hw_info_encoder_need_load(coder_param->
encoder_param);
3901 ni_log(
NI_LOG_DEBUG,
"%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3903 ni_log(
NI_LOG_INFO,
"%s Card[%3d], load: %3d, task_num: %3d, firmware_load: %3d, model_load: %3d, shared_mem_usage: %3d\n",
3915 if(card_remove[i] == 1)
3922 if(decoder_need_load + p_hw_device_info->card_info[j][i].model_load >= 100)
3970 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,10);
3972 else if(preferential_device_type == 0)
3974 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,0);
3976 else if(preferential_device_type == 1)
3978 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,1);
3980 else if(preferential_device_type == 2)
3982 check_hw_info_remove_card_with_memory(card_remove,p_hw_device_info,p_hw_device_info->available_card_num,coder_param,2);
3990 int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
3991 for (i = 0; i < p_hw_device_info->available_card_num; i++)
3993 if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
3994 card_remove[i] == 0)
3996 min_task_num = p_hw_device_info->card_info[0][i].task_num;
4001 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4003 if (p_hw_device_info->card_info[0][i].load < min_load &&
4004 card_remove[i] == 0 &&
4005 p_hw_device_info->card_info[0][i].task_num == min_task_num)
4007 min_load = p_hw_device_info->card_info[0][i].load;
4008 p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4016 int min_task_num = p_hw_device_info->card_info[0][0].max_task_num;
4017 for (i = 0; i < p_hw_device_info->available_card_num; i++)
4019 if (p_hw_device_info->card_info[0][i].task_num < min_task_num &&
4020 card_remove[i] == 0)
4022 p_hw_device_info->card_current_card = p_hw_device_info->card_info[0][i].card_idx;
4023 min_task_num = p_hw_device_info->card_info[0][i].task_num;
4028 if (p_hw_device_info->card_current_card >= 0)
4035 ReleaseMutex((HANDLE)p_device_pool->
lock);
4037 #elif defined(__linux__)
4038 if (lockf(p_device_pool->
lock, F_ULOCK,0))
4041 if(p_hw_device_info)
4048 p_device_context = NULL;
4053 free(module_id_arr);
4054 module_id_arr = NULL;
4059 dev_ctxt_arr = NULL;
4075 p_hw_device_info->card_current_card, retval);
4080 ni_log(
NI_LOG_DEBUG,
"In sw_mode select device_type %s card_current_card %d retval %d\n",
4082 ni_log(
NI_LOG_INFO,
"In sw_mode select device_type %s card_current_card %d retval %d\n",
4084 ((preferential_device_type == 0) ?
"decode" : (preferential_device_type == 1 ?
"encode" : (preferential_device_type == 2 ?
"scaler" :
"ai "))), p_hw_device_info->card_current_card, retval);
4116 int width,
int height,
4128 uint32_t num_sw_instances = 0;
4129 int least_model_load = 0;
4130 uint64_t job_mload = 0;
4150 if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->
lock, INFINITE))
4154 #elif __linux__ || __APPLE__
4155 lockf(p_device_pool->
lock, F_LOCK, 0);
4161 for (i = 0; i < count; i++)
4165 if (!p_device_context)
4168 "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4177 if (NI_INVALID_DEVICE_HANDLE == p_session_context.
device_handle)
4194 g_device_type_str[device_type],
4202 if (WAIT_ABANDONED == WaitForSingleObject(p_device_context->
lock, INFINITE))
4205 __func__, p_device_context->
lock);
4207 #elif __linux__ || __APPLE__
4208 lockf(p_device_context->
lock, F_LOCK, 0);
4216 load = p_device_info->
load;
4217 least_model_load = p_device_info->
model_load;
4221 ni_log(
NI_LOG_INFO,
"Coder [%d]: %d , load: %d (%d), activ_inst: %d , max_inst %d\n",
4242 if (p_device_info->
model_load < least_model_load)
4245 least_model_load = p_device_info->
model_load;
4248 else if (p_device_info->
load < load)
4251 load = p_device_info->
load;
4258 ReleaseMutex(p_device_context->
lock);
4259 #elif __linux__ || __APPLE__
4260 lockf(p_device_context->
lock, F_ULOCK, 0);
4268 if (!p_device_context)
4271 "ERROR: %s() ni_rsrc_get_device_context() failed\n", __func__);
4277 job_mload = width * height * frame_rate;
4283 p_device_context = NULL;
4288 ReleaseMutex(p_device_pool->
lock);
4289 #elif __linux__ || __APPLE__
4290 lockf(p_device_pool->
lock, F_ULOCK, 0);
4297 *p_load = job_mload;
4299 return p_device_context;