From c6c9e6a8b310ebdbf71d1338512c06b80a1e4728 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 7 Jun 2019 10:12:44 +0200 Subject: [PATCH] core: add method to load spa_handle Add a method that loads a spa handle based on the currently configured libraries in the core. Remove duplicate code. --- src/examples/bluez-session.c | 56 +++++-------------- .../module-client-node/client-stream.c | 18 +++--- src/modules/spa/spa-device.c | 26 +++------ src/modules/spa/spa-monitor.c | 34 ++--------- src/modules/spa/spa-node.c | 17 +----- src/pipewire/core.c | 38 ++++++++++++- src/pipewire/core.h | 4 ++ src/pipewire/device.c | 21 +------ src/pipewire/keys.h | 7 +-- src/pipewire/loop.c | 4 +- 10 files changed, 87 insertions(+), 138 deletions(-) diff --git a/src/examples/bluez-session.c b/src/examples/bluez-session.c index 0e250b0bf..4e32694e1 100644 --- a/src/examples/bluez-session.c +++ b/src/examples/bluez-session.c @@ -108,9 +108,6 @@ static struct node *create_node(struct object *obj, uint32_t id, struct node *node; struct impl *impl = obj->impl; struct pw_core *core = impl->core; - const struct spa_support *support; - const char *lib; - uint32_t n_support; struct spa_handle *handle; int res; void *iface; @@ -120,18 +117,9 @@ static struct node *create_node(struct object *obj, uint32_t id, if (info->type != SPA_TYPE_INTERFACE_Node) return NULL; - support = pw_core_get_support(core, &n_support); - - lib = pw_core_find_spa_lib(core, info->factory_name); - if (lib == NULL) { - pw_log_error("can't find spa lib for factory %s", info->factory_name); - goto exit; - } - - handle = pw_load_spa_handle(lib, + handle = pw_core_load_spa_handle(core, info->factory_name, - info->props, - n_support, support); + info->props); if (handle == NULL) { pw_log_error("can't make factory instance: %m"); goto exit; @@ -229,10 +217,7 @@ static struct object *create_object(struct impl *impl, uint32_t id, { struct pw_core *core = impl->core; struct object *obj; - const struct spa_support *support; - uint32_t n_support; struct spa_handle *handle; - const char *lib; int res; void *iface; @@ -241,18 +226,9 @@ static struct object *create_object(struct impl *impl, uint32_t id, if (info->type != SPA_TYPE_INTERFACE_Device) return NULL; - support = pw_core_get_support(core, &n_support); - - lib = pw_core_find_spa_lib(core, info->factory_name); - if (lib == NULL) { - pw_log_error("can't find spa lib for factory %s", info->factory_name); - goto exit; - } - - handle = pw_load_spa_handle(lib, + handle = pw_core_load_spa_handle(core, info->factory_name, - info->props, - n_support, support); + info->props); if (handle == NULL) { pw_log_error("can't make factory instance: %m"); goto exit; @@ -334,24 +310,19 @@ static const struct spa_monitor_callbacks monitor_callbacks = static int start_monitor(struct impl *impl) { - const struct spa_support *support; - uint32_t n_support; struct spa_handle *handle; int res; void *iface; - support = pw_core_get_support(impl->core, &n_support); - - handle = pw_load_spa_handle("bluez5/libspa-bluez5", - "bluez5-monitor", - NULL, - n_support, support); - if (handle == NULL) - goto no_mem; + handle = pw_core_load_spa_handle(impl->core, "api.bluez5.monitor", NULL); + if (handle == NULL) { + res = -errno; + goto out; + } if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Monitor, &iface)) < 0) { pw_log_error("can't get MONITOR interface: %d", res); - goto interface_failed; + goto out_unload; } impl->monitor_handle = handle; @@ -361,11 +332,10 @@ static int start_monitor(struct impl *impl) return 0; - interface_failed: + out_unload: pw_unload_spa_handle(handle); + out: return res; - no_mem: - return -ENOMEM; } static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remote_state state, const char *error) @@ -413,6 +383,8 @@ int main(int argc, char *argv[]) impl.core = pw_core_new(pw_main_loop_get_loop(impl.loop), NULL, 0); impl.remote = pw_remote_new(impl.core, NULL, 0); + pw_core_add_spa_lib(impl.core, "api.bluez5.*", "bluez5/libspa-bluez5"); + pw_module_load(impl.core, "libpipewire-module-client-device", NULL, NULL, NULL, NULL); clock_gettime(CLOCK_MONOTONIC, &impl.now); diff --git a/src/modules/module-client-node/client-stream.c b/src/modules/module-client-node/client-stream.c index 7ffad147f..f03033c6a 100644 --- a/src/modules/module-client-node/client-stream.c +++ b/src/modules/module-client-node/client-stream.c @@ -1043,7 +1043,8 @@ static void client_node_initialized(void *data) if (!exclusive && media_type == SPA_MEDIA_TYPE_audio && media_subtype == SPA_MEDIA_SUBTYPE_raw) { - struct spa_dict_item items[2]; + struct spa_dict_item items[3]; + uint32_t n_items; const char *mode; void *iface; @@ -1052,14 +1053,14 @@ static void client_node_initialized(void *data) else mode = "merge"; - items[0] = SPA_DICT_ITEM_INIT("factory.mode", mode); - items[1] = SPA_DICT_ITEM_INIT("resample.peaks", monitor ? "1" : "0"); + n_items = 0; + items[n_items++] = SPA_DICT_ITEM_INIT("factory.mode", mode); + items[n_items++] = SPA_DICT_ITEM_INIT("resample.peaks", monitor ? "1" : "0"); + items[n_items++] = SPA_DICT_ITEM_INIT(SPA_KEY_LIBRARY_NAME, "audioconvert/libspa-audioconvert"); - - if ((impl->handle = pw_load_spa_handle("audioconvert/libspa-audioconvert", - "audioconvert", - &SPA_DICT_INIT(items, 2), - 0, NULL)) == NULL) + if ((impl->handle = pw_core_load_spa_handle(impl->core, + "audioconvert", + &SPA_DICT_INIT(items, n_items))) == NULL) return; if ((res = spa_handle_get_interface(impl->handle, @@ -1277,7 +1278,6 @@ struct pw_client_stream *pw_client_stream_new(struct pw_resource *resource, spa_node_set_callbacks(impl->cnode, &node_callbacks, impl); support = pw_core_get_support(impl->core, &n_support); - node_init(&impl->node, NULL, support, n_support); impl->node.impl = impl; diff --git a/src/modules/spa/spa-device.c b/src/modules/spa/spa-device.c index f5f35504b..394049e7d 100644 --- a/src/modules/spa/spa-device.c +++ b/src/modules/spa/spa-device.c @@ -133,35 +133,27 @@ struct pw_device *pw_spa_device_load(struct pw_core *core, struct pw_device *this; struct impl *impl; struct spa_handle *handle; - const struct spa_support *support; - const char *lib = NULL; - uint32_t n_support; void *iface; int res; - support = pw_core_get_support(core, &n_support); - - if (lib == NULL && properties) - lib = pw_properties_get(properties, SPA_KEY_LIBRARY_NAME); - if (lib == NULL) - lib = pw_core_find_spa_lib(core, factory_name); - if (lib == NULL) - goto exit; - - handle = pw_load_spa_handle(lib, factory_name, - properties ? &properties->dict : NULL, n_support, support); - if (handle == NULL) + handle = pw_core_load_spa_handle(core, factory_name, + properties ? &properties->dict : NULL); + if (handle == NULL) { + pw_log_error("can't load device handle: %m"); goto exit; + } if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Device, &iface)) < 0) { - pw_log_error("can't get device interface %d\n", res); + pw_log_error("can't get device interface %d", res); goto exit_unload; } this = pw_spa_device_new(core, owner, parent, name, flags, iface, handle, properties, user_data_size); - if (this == NULL) + if (this == NULL) { + pw_log_error("can't create device: %m"); goto exit; + } impl = this->user_data; impl->factory_name = strdup(factory_name); diff --git a/src/modules/spa/spa-monitor.c b/src/modules/spa/spa-monitor.c index 25e771422..a88ae0d6d 100644 --- a/src/modules/spa/spa-monitor.c +++ b/src/modules/spa/spa-monitor.c @@ -89,11 +89,9 @@ static struct monitor_object *add_object(struct pw_spa_monitor *this, uint32_t i int res; struct spa_handle *handle; struct monitor_object *obj; - const char *name, *str, *lib; + const char *name, *str; void *iface; struct pw_properties *props = NULL; - const struct spa_support *support; - uint32_t n_support; if (info->props) props = pw_properties_new_dict(info->props); @@ -111,17 +109,8 @@ static struct monitor_object *add_object(struct pw_spa_monitor *this, uint32_t i if (now != 0 && pw_properties_get(props, PW_KEY_DEVICE_PLUGGED) == NULL) pw_properties_setf(props, PW_KEY_DEVICE_PLUGGED, "%"PRIu64, now); - lib = pw_core_find_spa_lib(core, info->factory_name); - if (lib == NULL) { - pw_log_warn("monitor %p: unknown library for %s", - this, info->factory_name); - goto error_free_props; - } - - support = pw_core_get_support(core, &n_support); - - handle = pw_load_spa_handle(lib, info->factory_name, - &props->dict, n_support, support); + handle = pw_core_load_spa_handle(core, info->factory_name, + &props->dict); if (handle == NULL) { pw_log_error("can't make factory instance: %m"); goto error_free_props; @@ -272,25 +261,12 @@ struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core, struct impl *impl; struct pw_spa_monitor *this; struct spa_handle *handle; - const char *lib = NULL; int res; void *iface; - const struct spa_support *support; - uint32_t n_support; - if (lib == NULL && properties) - lib = pw_properties_get(properties, SPA_KEY_LIBRARY_NAME); - if (lib == NULL) - lib = pw_core_find_spa_lib(core, factory_name); - if (lib == NULL) - goto exit; - - support = pw_core_get_support(core, &n_support); - - handle = pw_load_spa_handle(lib, + handle = pw_core_load_spa_handle(core, factory_name, - properties ? &properties->dict : NULL, - n_support, support); + properties ? &properties->dict : NULL); if (handle == NULL) goto exit; diff --git a/src/modules/spa/spa-node.c b/src/modules/spa/spa-node.c index 7a17788a8..5885b7580 100644 --- a/src/modules/spa/spa-node.c +++ b/src/modules/spa/spa-node.c @@ -249,26 +249,13 @@ struct pw_node *pw_spa_node_load(struct pw_core *core, struct pw_node *this; struct impl *impl; struct spa_node *spa_node; - const char *lib = NULL; int res; struct spa_handle *handle; void *iface; - const struct spa_support *support; - uint32_t n_support; - if (lib == NULL && properties) - lib = pw_properties_get(properties, SPA_KEY_LIBRARY_NAME); - if (lib == NULL) - lib = pw_core_find_spa_lib(core, factory_name); - if (lib == NULL) - goto exit; - - support = pw_core_get_support(core, &n_support); - - handle = pw_load_spa_handle(lib, + handle = pw_core_load_spa_handle(core, factory_name, - properties ? &properties->dict : NULL, - n_support, support); + properties ? &properties->dict : NULL); if (handle == NULL) goto exit; diff --git a/src/pipewire/core.c b/src/pipewire/core.c index afa8799cc..4b1647cf7 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -443,7 +443,7 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, { struct impl *impl; struct pw_core *this; - const char *name; + const char *name, *lib; void *dbus_iface = NULL; uint32_t n_support; int res = 0; @@ -488,7 +488,11 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, this->support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataSystem, this->data_system); this->support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataLoop, this->data_loop->loop); - impl->dbus_handle = pw_load_spa_handle("support/libspa-dbus", "dbus", NULL, n_support, this->support); + lib = pw_properties_get(properties, PW_KEY_LIBRARY_NAME_DBUS); + if (lib == NULL) + lib = "support/libspa-dbus"; + + impl->dbus_handle = pw_load_spa_handle(lib, "dbus", NULL, n_support, this->support); if (impl->dbus_handle == NULL || (res = spa_handle_get_interface(impl->dbus_handle, SPA_TYPE_INTERFACE_DBus, &dbus_iface)) < 0) { @@ -1113,3 +1117,33 @@ const char *pw_core_find_spa_lib(struct pw_core *core, const char *factory_name) } return NULL; } + +SPA_EXPORT +struct spa_handle *pw_core_load_spa_handle(struct pw_core *core, + const char *factory_name, + const struct spa_dict *info) +{ + const char *lib; + const struct spa_support *support; + uint32_t n_support; + struct spa_handle *handle; + + pw_log_debug("core %p: load factory %s", core, factory_name); + + lib = pw_core_find_spa_lib(core, factory_name); + if (lib == NULL && info != NULL) + lib = spa_dict_lookup(info, SPA_KEY_LIBRARY_NAME); + if (lib == NULL) { + pw_log_warn("core %p: no library for %s: %m", + core, factory_name); + errno = ENOENT; + return NULL; + } + + support = pw_core_get_support(core, &n_support); + + handle = pw_load_spa_handle(lib, factory_name, + info, n_support, support); + + return handle; +} diff --git a/src/pipewire/core.h b/src/pipewire/core.h index f2b44f0b1..7fdce82e9 100644 --- a/src/pipewire/core.h +++ b/src/pipewire/core.h @@ -153,6 +153,10 @@ int pw_core_add_spa_lib(struct pw_core *core, const char *factory_regex, const c /** find the library name for a spa factory */ const char * pw_core_find_spa_lib(struct pw_core *core, const char *factory_name); +struct spa_handle *pw_core_load_spa_handle(struct pw_core *core, + const char *factory_name, + const struct spa_dict *info); + #ifdef __cplusplus } #endif diff --git a/src/pipewire/device.c b/src/pipewire/device.c index 228a0a2a2..e9f7ef351 100644 --- a/src/pipewire/device.c +++ b/src/pipewire/device.c @@ -444,13 +444,10 @@ static void device_add(struct pw_device *device, uint32_t id, const struct spa_device_object_info *info) { struct pw_core *core = device->core; - const struct spa_support *support; - uint32_t n_support; struct spa_handle *handle; struct pw_node *node; struct node_data *nd; struct pw_properties *props; - const char *lib; int res; void *iface; @@ -463,22 +460,10 @@ static void device_add(struct pw_device *device, uint32_t id, return; } - lib = pw_core_find_spa_lib(core, info->factory_name); - if (lib == NULL) { - pw_log_warn("device %p: unknown library for %s", - device, info->factory_name); - return; - } - - pw_log_debug("device %p: add node %d", device, id); - support = pw_core_get_support(core, &n_support); - - handle = pw_load_spa_handle(lib, info->factory_name, - info->props, n_support, support); - + handle = pw_core_load_spa_handle(core, info->factory_name, info->props); if (handle == NULL) { - pw_log_warn("device %p: can't load handle %s:%s", - device, lib, info->factory_name); + pw_log_warn("device %p: can't load handle %s: %m", + device, info->factory_name); return; } diff --git a/src/pipewire/keys.h b/src/pipewire/keys.h index 42d404ada..07087f26a 100644 --- a/src/pipewire/keys.h +++ b/src/pipewire/keys.h @@ -61,10 +61,9 @@ extern "C" { #define PW_KEY_SEC_GID "pipewire.sec.gid" /**< client gid, set by protocol*/ #define PW_KEY_SEC_LABEL "pipewire.sec.label" /**< client security label, set by protocol*/ -#define PW_KEY_LOOP_LIBRARY_SYSTEM "loop.library.system" /**< name of the system library to use for - * a loop. */ -#define PW_KEY_LOOP_LIBRARY_LOOP "loop.library.loop" /**< name of the loop library to use for a - * a loop. */ +#define PW_KEY_LIBRARY_NAME_SYSTEM "library.name.system" /**< name of the system library to use */ +#define PW_KEY_LIBRARY_NAME_LOOP "library.name.loop" /**< name of the loop library to use */ +#define PW_KEY_LIBRARY_NAME_DBUS "library.name.dbus" /**< name of the dbus library to use */ #define PW_KEY_CORE_MONITORS "core.monitors" /**< the apis monitored by core. */ diff --git a/src/pipewire/loop.c b/src/pipewire/loop.c index 4cb0622c5..55dcd9e74 100644 --- a/src/pipewire/loop.c +++ b/src/pipewire/loop.c @@ -69,7 +69,7 @@ struct pw_loop *pw_loop_new(struct pw_properties *properties) impl->properties = properties; if (properties) - lib = pw_properties_get(properties, PW_KEY_LOOP_LIBRARY_SYSTEM); + lib = pw_properties_get(properties, PW_KEY_LIBRARY_NAME_SYSTEM); else lib = NULL; @@ -94,7 +94,7 @@ struct pw_loop *pw_loop_new(struct pw_properties *properties) support[n_support++] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_System, iface); if (properties) - lib = pw_properties_get(properties, PW_KEY_LOOP_LIBRARY_LOOP); + lib = pw_properties_get(properties, PW_KEY_LIBRARY_NAME_LOOP); else lib = NULL;