mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
filter-chain: handle LADSPA_PATH as colon separated list of paths
Split up LADSPA_PATH at colons, and try to load the particular plugin from each directory specified in LADSPA_PATH. Fixes #1217.
This commit is contained in:
parent
67e588f382
commit
22d874cdeb
1 changed files with 65 additions and 24 deletions
|
|
@ -764,21 +764,11 @@ static void ladspa_handle_unref(struct ladspa_handle *hndl)
|
||||||
free(hndl);
|
free(hndl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ladspa_handle *ladspa_handle_load(struct impl *impl, const char *plugin)
|
static struct ladspa_handle *ladspa_handle_load_by_path(struct impl *impl, const char *path)
|
||||||
{
|
{
|
||||||
struct ladspa_handle *hndl;
|
struct ladspa_handle *hndl;
|
||||||
char path[PATH_MAX];
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (plugin[0] != '/') {
|
|
||||||
const char *e;
|
|
||||||
if ((e = getenv("LADSPA_PATH")) == NULL)
|
|
||||||
e = "/usr/lib64/ladspa";
|
|
||||||
snprintf(path, sizeof(path), "%s/%s.so", e, plugin);
|
|
||||||
} else {
|
|
||||||
snprintf(path, sizeof(path), "%s", plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
spa_list_for_each(hndl, &impl->ladspa_handle_list, link) {
|
spa_list_for_each(hndl, &impl->ladspa_handle_list, link) {
|
||||||
if (spa_streq(hndl->path, path)) {
|
if (spa_streq(hndl->path, path)) {
|
||||||
hndl->ref++;
|
hndl->ref++;
|
||||||
|
|
@ -787,27 +777,31 @@ static struct ladspa_handle *ladspa_handle_load(struct impl *impl, const char *p
|
||||||
}
|
}
|
||||||
|
|
||||||
hndl = calloc(1, sizeof(*hndl));
|
hndl = calloc(1, sizeof(*hndl));
|
||||||
|
if (!hndl)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
hndl->ref = 1;
|
hndl->ref = 1;
|
||||||
snprintf(hndl->path, sizeof(hndl->path), "%s", path);
|
snprintf(hndl->path, sizeof(hndl->path), "%s", path);
|
||||||
|
|
||||||
if (spa_streq(plugin, "builtin")) {
|
if (!spa_streq(path, "builtin")) {
|
||||||
hndl->desc_func = builtin_ladspa_descriptor;
|
|
||||||
} else {
|
|
||||||
hndl->handle = dlopen(path, RTLD_NOW);
|
hndl->handle = dlopen(path, RTLD_NOW);
|
||||||
if (hndl->handle == NULL) {
|
if (!hndl->handle) {
|
||||||
pw_log_error("plugin dlopen failed %s: %s", path, dlerror());
|
pw_log_debug("failed to open '%s': %s", path, dlerror());
|
||||||
res = -ENOENT;
|
res = -ENOENT;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
hndl->desc_func = (LADSPA_Descriptor_Function)dlsym(hndl->handle,
|
pw_log_info("successfully opened '%s'", path);
|
||||||
"ladspa_descriptor");
|
|
||||||
|
hndl->desc_func = (LADSPA_Descriptor_Function) dlsym(hndl->handle, "ladspa_descriptor");
|
||||||
|
if (!hndl->desc_func) {
|
||||||
|
pw_log_warn("cannot find descriptor function in '%s': %s", path, dlerror());
|
||||||
|
res = -ENOSYS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hndl->desc_func == NULL) {
|
else {
|
||||||
pw_log_error("cannot find descriptor function from %s: %s",
|
hndl->desc_func = builtin_ladspa_descriptor;
|
||||||
path, dlerror());
|
|
||||||
res = -ENOSYS;
|
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_list_init(&hndl->descriptor_list);
|
spa_list_init(&hndl->descriptor_list);
|
||||||
|
|
@ -816,13 +810,60 @@ static struct ladspa_handle *ladspa_handle_load(struct impl *impl, const char *p
|
||||||
return hndl;
|
return hndl;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (hndl->handle != NULL)
|
if (hndl->handle)
|
||||||
dlclose(hndl->handle);
|
dlclose(hndl->handle);
|
||||||
|
|
||||||
free(hndl);
|
free(hndl);
|
||||||
errno = -res;
|
errno = -res;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct ladspa_handle *ladspa_handle_load(struct impl *impl, const char *plugin)
|
||||||
|
{
|
||||||
|
struct ladspa_handle *hndl = NULL;
|
||||||
|
|
||||||
|
if (!spa_streq(plugin, "builtin") && plugin[0] != '/') {
|
||||||
|
const char *search_dirs, *p;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
search_dirs = getenv("LADSPA_PATH");
|
||||||
|
if (!search_dirs)
|
||||||
|
search_dirs = "/usr/lib64/ladspa";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set the errno for the case when `ladspa_handle_load_by_path()`
|
||||||
|
* is never called, which can only happen if the supplied
|
||||||
|
* LADSPA_PATH contains too long paths
|
||||||
|
*/
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
|
||||||
|
while ((p = pw_split_walk(NULL, ":", &len, &search_dirs))) {
|
||||||
|
int pathlen;
|
||||||
|
|
||||||
|
if (len >= sizeof(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pathlen = snprintf(path, sizeof(path), "%.*s/%s.so", (int) len, p, plugin);
|
||||||
|
if (pathlen < 0 || (size_t) pathlen >= sizeof(path))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hndl = ladspa_handle_load_by_path(impl, path);
|
||||||
|
if (hndl)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hndl = ladspa_handle_load_by_path(impl, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hndl)
|
||||||
|
pw_log_error("failed to load plugin '%s': %s", plugin, strerror(errno));
|
||||||
|
|
||||||
|
return hndl;
|
||||||
|
}
|
||||||
|
|
||||||
static void ladspa_descriptor_unref(struct ladspa_descriptor *desc)
|
static void ladspa_descriptor_unref(struct ladspa_descriptor *desc)
|
||||||
{
|
{
|
||||||
if (--desc->ref > 0)
|
if (--desc->ref > 0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue