static void module_load_exports(struct obs_module *mod, struct darray *output_array, const char *type, const size_t data_size, void *callback_ptr) { bool (*enum_func)(size_t idx, const char **name); bool (*callback)(void*, const char*, const char*, void*); struct dstr enum_name; const char *name; size_t i = 0; callback = callback_ptr; dstr_init_copy(&enum_name, "enum_"); dstr_cat(&enum_name, type); enum_func = os_dlsym(mod->module, enum_name.array); if (!enum_func) goto complete; while (enum_func(i++, &name)) { void *info = bmalloc(data_size); if (!callback(mod->module, mod->name, name, info)) blog(LOG_ERROR, "Couldn't load '%s' because it " "was missing required functions", name); else darray_push_back(data_size, output_array, info); bfree(info); } complete: dstr_free(&enum_name); }
char *find_libobs_data_file(const char *file) { struct dstr path; dstr_init_copy(&path, OBS_INSTALL_DATA_PATH "/libobs/"); dstr_cat(&path, file); return path.array; }
void *os_dlopen(const char *path) { struct dstr dll_name; wchar_t *wpath; wchar_t *wpath_slash; HMODULE h_library = NULL; if (!path) return NULL; dstr_init_copy(&dll_name, path); dstr_replace(&dll_name, "\\", "/"); if (!dstr_find(&dll_name, ".dll")) dstr_cat(&dll_name, ".dll"); os_utf8_to_wcs_ptr(dll_name.array, 0, &wpath); /* to make module dependency issues easier to deal with, allow * dynamically loaded libraries on windows to search for dependent * libraries that are within the library's own directory */ wpath_slash = wcsrchr(wpath, L'/'); if (wpath_slash) { *wpath_slash = 0; SetDllDirectoryW(wpath); *wpath_slash = L'/'; } h_library = LoadLibraryW(wpath); bfree(wpath); dstr_free(&dll_name); if (wpath_slash) SetDllDirectoryW(NULL); if (!h_library) { DWORD error = GetLastError(); char *message = NULL; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPSTR)&message, 0, NULL); blog(LOG_INFO, "LoadLibrary failed for '%s': %s (%lu)", path, message, error); if (message) LocalFree(message); } return h_library; }
int os_mkdirs(const char *dir) { struct dstr dir_str; int ret; dstr_init_copy(&dir_str, dir); dstr_replace(&dir_str, "\\", "/"); ret = recursive_mkdir(dir_str.array); dstr_free(&dir_str); return ret; }
/* should return $HOME/.[name] */ char *os_get_config_path(const char *name) { char *path_ptr = getenv("HOME"); if (path_ptr == NULL) bcrash("Could not get $HOME\n"); struct dstr path; dstr_init_copy(&path, path_ptr); dstr_cat(&path, "/."); dstr_cat(&path, name); return path.array; }
static inline bool check_lib_path(const char* data, const char *path, struct dstr *output) { bool result = false; struct dstr tmp; dstr_init_copy(&tmp, data); dstr_cat(&tmp, ".dll"); result = check_path(tmp.array, path, output); dstr_free(&tmp); return result; }
void *os_dlopen(const char *path) { struct dstr dylib_name; dstr_init_copy(&dylib_name, path); if(!dstr_find(&dylib_name, ".so")) dstr_cat(&dylib_name, ".so"); void *res = dlopen(dylib_name.array, RTLD_LAZY); if(!res) blog(LOG_ERROR, "os_dlopen(%s->%s): %s\n", path, dylib_name.array, dlerror()); dstr_free(&dylib_name); return res; }
void *load_module_subfunc(void *module, const char *module_name, const char *name, const char *func, bool required) { struct dstr func_name; void *func_addr = NULL; dstr_init_copy(&func_name, name); dstr_cat(&func_name, "_"); dstr_cat(&func_name, func); func_addr = os_dlsym(module, func_name.array); if (required && !func_addr) blog(LOG_ERROR, "Could not load function '%s' from module '%s'", func_name.array, module_name); dstr_free(&func_name); return func_addr; }
void *os_dlopen(const char *path) { struct dstr dll_name; wchar_t *wpath; HMODULE h_library = NULL; dstr_init_copy(&dll_name, path); dstr_cat(&dll_name, ".dll"); os_utf8_to_wcs(dll_name.array, 0, &wpath); h_library = LoadLibraryW(wpath); bfree(wpath); dstr_free(&dll_name); if (!h_library) blog(LOG_INFO, "LoadLibrary failed for '%s', error: %u", path, GetLastError()); return h_library; }
obs_output_t obs_output_create(const char *id, const char *settings) { const struct output_info *info = find_output(id); struct obs_output *output; if (!info) { blog(LOG_WARNING, "Output '%s' not found", id); return NULL; } output = bmalloc(sizeof(struct obs_output)); output->data = info->create(settings, output); if (!output->data) { bfree(output); return NULL; } dstr_init_copy(&output->settings, settings); memcpy(&output->callbacks, info, sizeof(struct output_info)); return output; }
const char *os_get_path_extension(const char *path) { struct dstr temp; size_t pos = 0; char *period; char *slash; dstr_init_copy(&temp, path); dstr_replace(&temp, "\\", "/"); slash = strrchr(temp.array, '/'); period = strrchr(temp.array, '.'); if (period) pos = (size_t)(period - temp.array); dstr_free(&temp); if (!period || slash > period) return NULL; return path + pos; }
/* * List available devices */ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) { DIR *dirp; struct dirent *dp; struct dstr device; bool cur_device_found; size_t cur_device_index; const char *cur_device_name; #ifdef __FreeBSD__ dirp = opendir("/dev"); #else dirp = opendir("/sys/class/video4linux"); #endif if (!dirp) return; cur_device_found = false; cur_device_name = obs_data_get_string(settings, "device_id"); obs_property_list_clear(prop); dstr_init_copy(&device, "/dev/"); while ((dp = readdir(dirp)) != NULL) { int fd; uint32_t caps; struct v4l2_capability video_cap; #ifdef __FreeBSD__ if (strstr(dp->d_name, "video") == NULL) continue; #endif if (dp->d_type == DT_DIR) continue; dstr_resize(&device, 5); dstr_cat(&device, dp->d_name); if ((fd = v4l2_open(device.array, O_RDWR | O_NONBLOCK)) == -1) { blog(LOG_INFO, "Unable to open %s", device.array); continue; } if (v4l2_ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1) { blog(LOG_INFO, "Failed to query capabilities for %s", device.array); v4l2_close(fd); continue; } #ifndef V4L2_CAP_DEVICE_CAPS caps = video_cap.capabilities; #else /* ... since Linux 3.3 */ caps = (video_cap.capabilities & V4L2_CAP_DEVICE_CAPS) ? video_cap.device_caps : video_cap.capabilities; #endif if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { blog(LOG_INFO, "%s seems to not support video capture", device.array); v4l2_close(fd); continue; } obs_property_list_add_string(prop, (char *) video_cap.card, device.array); blog(LOG_INFO, "Found device '%s' at %s", video_cap.card, device.array); /* check if this is the currently used device */ if (cur_device_name && !strcmp(cur_device_name, device.array)) cur_device_found = true; v4l2_close(fd); } /* add currently selected device if not present, but disable it ... */ if (!cur_device_found && cur_device_name && strlen(cur_device_name)) { cur_device_index = obs_property_list_add_string(prop, cur_device_name, cur_device_name); obs_property_list_item_disable(prop, cur_device_index, true); } closedir(dirp); dstr_free(&device); }