From f55f1739e18a1dfa626ff9665efdec9f8871f62b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 14 Jun 2017 11:48:41 +0200 Subject: [PATCH] Rework support Load the mapper from the support plugin Move the support setup in pw_init --- pipewire/client/context.c | 9 +- pipewire/client/log.c | 87 ++--------------- pipewire/client/log.h | 3 +- pipewire/client/loop.c | 56 ++++++----- pipewire/client/mapper.c | 97 ------------------- pipewire/client/meson.build | 1 - pipewire/client/pipewire.c | 113 +++++++++++++++++++++++ pipewire/client/pipewire.h | 4 +- pipewire/client/type.c | 2 +- pipewire/server/core.c | 12 +-- spa/include/spa/plugin.h | 2 + spa/plugins/logger/meson.build | 9 -- spa/plugins/logger/plugin.c | 38 -------- spa/plugins/meson.build | 1 - spa/plugins/{logger => support}/logger.c | 0 spa/plugins/support/mapper.c | 28 +++--- spa/plugins/support/meson.build | 4 +- spa/plugins/support/plugin.c | 4 + 18 files changed, 192 insertions(+), 278 deletions(-) delete mode 100644 pipewire/client/mapper.c delete mode 100644 spa/plugins/logger/meson.build delete mode 100644 spa/plugins/logger/plugin.c rename spa/plugins/{logger => support}/logger.c (100%) diff --git a/pipewire/client/context.c b/pipewire/client/context.c index 68b364e8d..4c97b671d 100644 --- a/pipewire/client/context.c +++ b/pipewire/client/context.c @@ -445,12 +445,9 @@ struct pw_context *pw_context_new(struct pw_loop *loop, spa_debug_set_type_map(this->type.map); - impl->support[0].type = SPA_TYPE__TypeMap; - impl->support[0].data = this->type.map; - impl->support[1].type = SPA_TYPE_LOOP__MainLoop; - impl->support[1].data = this->loop->loop; - impl->support[2].type = SPA_TYPE__Log; - impl->support[2].data = pw_log_get(impl->support, 2); + impl->support[0] = SPA_SUPPORT_INIT (SPA_TYPE__TypeMap, this->type.map); + impl->support[1] = SPA_SUPPORT_INIT (SPA_TYPE_LOOP__MainLoop, this->loop->loop); + impl->support[2] = SPA_SUPPORT_INIT (SPA_TYPE__Log, pw_log_get()); this->support = impl->support; this->n_support = 3; diff --git a/pipewire/client/log.c b/pipewire/client/log.c index 12ea5692d..3a53c2fda 100644 --- a/pipewire/client/log.c +++ b/pipewire/client/log.c @@ -17,11 +17,6 @@ * Boston, MA 02110-1301, USA. */ -#include -#include -#include -#include - #include #include @@ -33,87 +28,23 @@ enum spa_log_level pw_log_level = DEFAULT_LOG_LEVEL; static struct spa_log *global_log = NULL; -struct spa_log *pw_spa_log_load(const char *lib, - const char *factory_name, - struct spa_support *support, - uint32_t n_support) +/** Set the global log interface + * \param log the global log to set + * \memberof pw_log + */ +void pw_log_set(struct spa_log *log) { - int res; - struct spa_handle *handle; - void *hnd; - uint32_t index, type_log; - spa_handle_factory_enum_func_t enum_func; - const struct spa_handle_factory *factory; - void *iface; - struct spa_type_map *map = NULL; - - for (index = 0; index < n_support; index++) { - if (strcmp(support[index].type, SPA_TYPE__TypeMap) == 0) - map = support[index].data; - } - if (map == NULL) { - fprintf(stderr, "no type map\n"); - return NULL; - } - - type_log = spa_type_map_get_id(map, SPA_TYPE__Log); - - if ((hnd = dlopen(lib, RTLD_NOW)) == NULL) { - fprintf(stderr, "can't load %s: %s\n", lib, dlerror()); - return NULL; - } - if ((enum_func = dlsym(hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) { - fprintf(stderr, "can't find enum function\n"); - goto no_symbol; - } - - for (index = 0;; index++) { - if ((res = enum_func(&factory, index)) < 0) { - if (res != SPA_RESULT_ENUM_END) - fprintf(stderr, "can't enumerate factories: %d\n", res); - goto enum_failed; - } - if (strcmp(factory->name, factory_name) == 0) - break; - } - - handle = calloc(1, factory->size); - if ((res = spa_handle_factory_init(factory, - handle, NULL, support, n_support)) < 0) { - fprintf(stderr, "can't make factory instance: %d\n", res); - goto init_failed; - } - if ((res = spa_handle_get_interface(handle, type_log, &iface)) < 0) { - fprintf(stderr, "can't get log interface %d\n", res); - goto interface_failed; - } - return iface; - - interface_failed: - spa_handle_clear(handle); - init_failed: - free(handle); - enum_failed: - no_symbol: - dlclose(hnd); - return NULL; + global_log = log; + if (global_log) + global_log->level = pw_log_level; } /** Get the global log interface * \return the global log * \memberof pw_log */ -struct spa_log *pw_log_get(struct spa_support *support, - uint32_t n_support) +struct spa_log *pw_log_get(void) { - if (global_log == NULL) { - global_log = pw_spa_log_load("build/spa/plugins/logger/libspa-logger.so", - "logger", - support, - n_support); - if (global_log) - global_log->level = pw_log_level; - } return global_log; } diff --git a/pipewire/client/log.h b/pipewire/client/log.h index 79755adc7..719dbbe63 100644 --- a/pipewire/client/log.h +++ b/pipewire/client/log.h @@ -39,7 +39,8 @@ extern "C" { /** The global log level */ extern enum spa_log_level pw_log_level; -struct spa_log *pw_log_get(struct spa_support *support, uint32_t n_support); +void pw_log_set(struct spa_log *log); +struct spa_log *pw_log_get(void); void pw_log_set_level(enum spa_log_level level); diff --git a/pipewire/client/loop.c b/pipewire/client/loop.c index c161c8f10..137147b98 100644 --- a/pipewire/client/loop.c +++ b/pipewire/client/loop.c @@ -577,6 +577,37 @@ static void loop_destroy_source(struct spa_source *source) spa_list_insert(&loop_impl->destroy_list, &impl->link); } +static const struct spa_loop loop_impl = { + sizeof(struct spa_loop), + loop_add_source, + loop_update_source, + loop_remove_source, + loop_invoke, +}; + +static const struct spa_loop_control loop_control_impl = { + sizeof(struct spa_loop_control), + loop_get_fd, + loop_set_hooks, + loop_enter, + loop_leave, + loop_iterate, +}; + +static const struct spa_loop_utils loop_utils_impl = { + sizeof(struct spa_loop_utils), + loop_add_io, + loop_update_io, + loop_add_idle, + loop_enable_idle, + loop_add_event, + loop_signal_event, + loop_add_timer, + loop_update_timer, + loop_add_signal, + loop_destroy_source, +}; + /** Create a new loop * \returns a newly allocated loop * \memberof pw_loop @@ -602,32 +633,13 @@ struct pw_loop *pw_loop_new(void) pw_signal_init(&this->before_iterate); pw_signal_init(&this->destroy_signal); - impl->loop.size = sizeof(struct spa_loop); - impl->loop.add_source = loop_add_source; - impl->loop.update_source = loop_update_source; - impl->loop.remove_source = loop_remove_source; - impl->loop.invoke = loop_invoke; + impl->loop = loop_impl; this->loop = &impl->loop; - impl->control.size = sizeof(struct spa_loop_control); - impl->control.get_fd = loop_get_fd; - impl->control.set_hooks = loop_set_hooks; - impl->control.enter = loop_enter; - impl->control.leave = loop_leave; - impl->control.iterate = loop_iterate; + impl->control = loop_control_impl; this->control = &impl->control; - impl->utils.size = sizeof(struct spa_loop_utils); - impl->utils.add_io = loop_add_io; - impl->utils.update_io = loop_update_io; - impl->utils.add_idle = loop_add_idle; - impl->utils.enable_idle = loop_enable_idle; - impl->utils.add_event = loop_add_event; - impl->utils.signal_event = loop_signal_event; - impl->utils.add_timer = loop_add_timer; - impl->utils.update_timer = loop_update_timer; - impl->utils.add_signal = loop_add_signal; - impl->utils.destroy_source = loop_destroy_source; + impl->utils = loop_utils_impl; this->utils = &impl->utils; spa_ringbuffer_init(&impl->buffer, DATAS_SIZE); diff --git a/pipewire/client/mapper.c b/pipewire/client/mapper.c deleted file mode 100644 index 1c908bed2..000000000 --- a/pipewire/client/mapper.c +++ /dev/null @@ -1,97 +0,0 @@ -/* PipeWire - * Copyright (C) 2016 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include - -#include - -#include - -/** \cond */ -struct impl { - struct spa_type_map map; - struct pw_map types; - struct pw_array strings; -}; -/** \endcond */ - -static uint32_t type_map_get_id(struct spa_type_map *map, const char *type) -{ - struct impl *this = SPA_CONTAINER_OF(map, struct impl, map); - uint32_t i = 0, len; - void *p; - off_t o; - - if (type != NULL) { - for (i = 0; i < pw_map_get_size(&this->types); i++) { - o = (off_t) pw_map_lookup_unchecked(&this->types, i); - if (strcmp(SPA_MEMBER(this->strings.data, o, char), type) == 0) - return i; - } - len = strlen(type); - p = pw_array_add(&this->strings, SPA_ROUND_UP_N(len + 1, 2)); - memcpy(p, type, len + 1); - o = (p - this->strings.data); - i = pw_map_insert_new(&this->types, (void *) o); - } - return i; -} - -static const char *type_map_get_type(const struct spa_type_map *map, uint32_t id) -{ - struct impl *this = SPA_CONTAINER_OF(map, struct impl, map); - - if (id == SPA_ID_INVALID) - return NULL; - - if (SPA_LIKELY(pw_map_check_id(&this->types, id))) { - off_t o = (off_t) pw_map_lookup_unchecked(&this->types, id); - return SPA_MEMBER(this->strings.data, o, char); - } - return NULL; -} - -static size_t type_map_get_size(const struct spa_type_map *map) -{ - struct impl *this = SPA_CONTAINER_OF(map, struct impl, map); - return pw_map_get_size(&this->types); -} - -static struct impl default_type_map = { - {sizeof(struct spa_type_map), - NULL, - type_map_get_id, - type_map_get_type, - type_map_get_size, - }, - PW_MAP_INIT(128), - PW_ARRAY_INIT(4096) -}; - -/** Get the default type map - * \return the default type map - * \memberof pw_pipewire - */ -struct spa_type_map *pw_type_map_get_default(void) -{ - return &default_type_map.map; -} diff --git a/pipewire/client/meson.build b/pipewire/client/meson.build index 53da8392f..acab158d3 100644 --- a/pipewire/client/meson.build +++ b/pipewire/client/meson.build @@ -28,7 +28,6 @@ pipewire_sources = [ 'introspect.c', 'log.c', 'loop.c', - 'mapper.c', 'mem.c', 'properties.c', 'protocol-native.c', diff --git a/pipewire/client/pipewire.c b/pipewire/client/pipewire.c index 02a6d4d9c..c1afdc9cd 100644 --- a/pipewire/client/pipewire.c +++ b/pipewire/client/pipewire.c @@ -22,11 +22,95 @@ #include #include #include +#include +#include #include "pipewire/client/pipewire.h" static char **categories = NULL; +static struct support_info { + void *hnd; + spa_handle_factory_enum_func_t enum_func; + struct spa_support support[4]; + uint32_t n_support; +} support_info; + +static void * find_support(struct support_info *info, const char *type) +{ + int i; + + for (i = 0; i < info->n_support; i++) { + if (strcmp(info->support->type, type) == 0) + return info->support->data; + } + return NULL; +} + +static bool +open_support(const char *lib, + struct support_info *info) +{ + if ((info->hnd = dlopen(lib, RTLD_NOW)) == NULL) { + fprintf(stderr, "can't load %s: %s\n", lib, dlerror()); + return false; + } + if ((info->enum_func = dlsym(info->hnd, SPA_HANDLE_FACTORY_ENUM_FUNC_NAME)) == NULL) { + fprintf(stderr, "can't find enum function\n"); + goto no_symbol; + } + return true; + + no_symbol: + dlclose(info->hnd); + return false; +} + +static void * +load_interface(struct support_info *info, + const char *factory_name, + const char *type) +{ + int res; + struct spa_handle *handle; + uint32_t index, type_id; + const struct spa_handle_factory *factory; + void *iface; + struct spa_type_map *map = NULL; + + map = find_support(info, SPA_TYPE__TypeMap); + type_id = map ? spa_type_map_get_id(map, type) : 0; + + for (index = 0;; index++) { + if ((res = info->enum_func(&factory, index)) < 0) { + if (res != SPA_RESULT_ENUM_END) + fprintf(stderr, "can't enumerate factories: %d\n", res); + goto enum_failed; + } + if (strcmp(factory->name, factory_name) == 0) + break; + } + + handle = calloc(1, factory->size); + if ((res = spa_handle_factory_init(factory, + handle, NULL, info->support, info->n_support)) < 0) { + fprintf(stderr, "can't make factory instance: %d\n", res); + goto init_failed; + } + if ((res = spa_handle_get_interface(handle, type_id, &iface)) < 0) { + fprintf(stderr, "can't get %s interface %d\n", type, res); + goto interface_failed; + } + return iface; + + interface_failed: + spa_handle_clear(handle); + init_failed: + free(handle); + enum_failed: + return NULL; +} + static void configure_debug(const char *str) { char **level; @@ -40,6 +124,32 @@ static void configure_debug(const char *str) categories = pw_split_strv(level[1], ",", INT_MAX, &n_tokens); } +static void configure_support(struct support_info *info) +{ + void *iface; + + iface = load_interface(info, "mapper", SPA_TYPE__TypeMap); + if (iface != NULL) { + info->support[info->n_support++] = SPA_SUPPORT_INIT(SPA_TYPE__TypeMap, iface); + } + + iface = load_interface(info, "logger", SPA_TYPE__Log); + if (iface != NULL) { + info->support[info->n_support++] = SPA_SUPPORT_INIT(SPA_TYPE__Log, iface); + pw_log_set(iface); + } +} + +/** Get a support interface + * \param type the interface type + * \return the interface or NULL when not configured + */ +void *pw_get_support(const char *type) +{ + return find_support(&support_info, type); +} + + /** Initialize PipeWire * * \param argc pointer to argc @@ -58,6 +168,9 @@ void pw_init(int *argc, char **argv[]) if ((str = getenv("PIPEWIRE_DEBUG"))) configure_debug(str); + + if (open_support("build/spa/plugins/support/libspa-support.so", &support_info)) + configure_support(&support_info); } /** Check if a debug category is enabled diff --git a/pipewire/client/pipewire.h b/pipewire/client/pipewire.h index 913b85cd9..93c92b710 100644 --- a/pipewire/client/pipewire.h +++ b/pipewire/client/pipewire.h @@ -119,8 +119,8 @@ pw_fill_stream_properties(struct pw_properties *properties); enum pw_direction pw_direction_reverse(enum pw_direction direction); -struct spa_type_map * -pw_type_map_get_default(void); +void * +pw_get_support(const char *type); #ifdef __cplusplus } diff --git a/pipewire/client/type.c b/pipewire/client/type.c index 7e8f8b85f..dd0e90756 100644 --- a/pipewire/client/type.c +++ b/pipewire/client/type.c @@ -37,7 +37,7 @@ */ void pw_type_init(struct pw_type *type) { - type->map = pw_type_map_get_default(); + type->map = pw_get_support(SPA_TYPE__TypeMap); type->core = spa_type_map_get_id(type->map, PIPEWIRE_TYPE__Core); type->registry = spa_type_map_get_id(type->map, PIPEWIRE_TYPE__Registry); diff --git a/pipewire/server/core.c b/pipewire/server/core.c index 7be4c5f1a..5ba83cd2b 100644 --- a/pipewire/server/core.c +++ b/pipewire/server/core.c @@ -287,14 +287,10 @@ struct pw_core *pw_core_new(struct pw_main_loop *main_loop, struct pw_properties spa_debug_set_type_map(this->type.map); - impl->support[0].type = SPA_TYPE__TypeMap; - impl->support[0].data = this->type.map; - impl->support[1].type = SPA_TYPE_LOOP__DataLoop; - impl->support[1].data = this->data_loop->loop->loop; - impl->support[2].type = SPA_TYPE_LOOP__MainLoop; - impl->support[2].data = this->main_loop->loop->loop; - impl->support[3].type = SPA_TYPE__Log; - impl->support[3].data = pw_log_get(impl->support, 3); + impl->support[0] = SPA_SUPPORT_INIT(SPA_TYPE__TypeMap, this->type.map); + impl->support[1] = SPA_SUPPORT_INIT(SPA_TYPE_LOOP__DataLoop, this->data_loop->loop->loop); + impl->support[2] = SPA_SUPPORT_INIT(SPA_TYPE_LOOP__MainLoop, this->main_loop->loop->loop); + impl->support[3] = SPA_SUPPORT_INIT(SPA_TYPE__Log, pw_log_get()); this->support = impl->support; this->n_support = 4; diff --git a/spa/include/spa/plugin.h b/spa/include/spa/plugin.h index 56c21c30c..83ac1143b 100644 --- a/spa/include/spa/plugin.h +++ b/spa/include/spa/plugin.h @@ -85,6 +85,8 @@ struct spa_support { void *data; }; +#define SPA_SUPPORT_INIT(type,data) (struct spa_support) { (type), (data) } + struct spa_handle_factory { /** * spa_handle_factory::name diff --git a/spa/plugins/logger/meson.build b/spa/plugins/logger/meson.build deleted file mode 100644 index b9f135898..000000000 --- a/spa/plugins/logger/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -spa_logger_sources = ['logger.c', 'plugin.c'] - -spa_logger_lib = shared_library('spa-logger', - spa_logger_sources, - include_directories : [ spa_inc, spa_libinc], - dependencies : threads_dep, - link_with : spalib, - install : true, - install_dir : '@0@/spa'.format(get_option('libdir'))) diff --git a/spa/plugins/logger/plugin.c b/spa/plugins/logger/plugin.c deleted file mode 100644 index 09dce11c7..000000000 --- a/spa/plugins/logger/plugin.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Spa Video Test Source plugin - * Copyright (C) 2016 Axis Communications AB - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include -#include - -extern const struct spa_handle_factory spa_logger_factory; - -int -spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t index) -{ - spa_return_val_if_fail(factory != NULL, SPA_RESULT_INVALID_ARGUMENTS); - - switch (index) { - case 0: - *factory = &spa_logger_factory; - break; - default: - return SPA_RESULT_ENUM_END; - } - return SPA_RESULT_OK; -} diff --git a/spa/plugins/meson.build b/spa/plugins/meson.build index 225df4bd2..332cc2cc8 100644 --- a/spa/plugins/meson.build +++ b/spa/plugins/meson.build @@ -2,7 +2,6 @@ subdir('alsa') subdir('audiomixer') subdir('audiotestsrc') subdir('ffmpeg') -subdir('logger') subdir('support') subdir('test') subdir('videotestsrc') diff --git a/spa/plugins/logger/logger.c b/spa/plugins/support/logger.c similarity index 100% rename from spa/plugins/logger/logger.c rename to spa/plugins/support/logger.c diff --git a/spa/plugins/support/mapper.c b/spa/plugins/support/mapper.c index f5b2a2023..74b2a7b7e 100644 --- a/spa/plugins/support/mapper.c +++ b/spa/plugins/support/mapper.c @@ -77,24 +77,26 @@ static uint32_t impl_type_map_get_id(struct spa_type_map *map, const char *type) { struct impl *impl = SPA_CONTAINER_OF(map, struct impl, map); - uint32_t i = 0, len; + uint32_t i, len; void *p; off_t o, *off; - if (type != NULL) { - for (i = 0; i < impl->types.size / sizeof(off_t); i++) { - o = ((off_t *)impl->types.data)[i]; - if (strcmp(SPA_MEMBER(impl->strings.data, o, char), type) == 0) - return i; - } - len = strlen(type); - p = alloc_size(&impl->strings, len+1, 1024); - memcpy(p, type, len + 1); + if (type == NULL) + return SPA_ID_INVALID; - off = alloc_size(&impl->types, sizeof(off_t), 128); - *off = SPA_PTRDIFF(p, impl->strings.data); - i = SPA_PTRDIFF(off, impl->types.data) / sizeof(off_t); + for (i = 0; i < impl->types.size / sizeof(off_t); i++) { + o = ((off_t *)impl->types.data)[i]; + if (strcmp(SPA_MEMBER(impl->strings.data, o, char), type) == 0) + return i; } + len = strlen(type); + p = alloc_size(&impl->strings, len+1, 1024); + memcpy(p, type, len + 1); + + off = alloc_size(&impl->types, sizeof(off_t), 128); + *off = SPA_PTRDIFF(p, impl->strings.data); + i = SPA_PTRDIFF(off, impl->types.data) / sizeof(off_t); + return i; } diff --git a/spa/plugins/support/meson.build b/spa/plugins/support/meson.build index a865a7981..c5097acac 100644 --- a/spa/plugins/support/meson.build +++ b/spa/plugins/support/meson.build @@ -1,4 +1,6 @@ -spa_support_sources = ['mapper.c', 'plugin.c'] +spa_support_sources = ['mapper.c', + 'logger.c', + 'plugin.c'] spa_support_lib = shared_library('spa-support', spa_support_sources, diff --git a/spa/plugins/support/plugin.c b/spa/plugins/support/plugin.c index 6c22bb20f..891fa0746 100644 --- a/spa/plugins/support/plugin.c +++ b/spa/plugins/support/plugin.c @@ -20,6 +20,7 @@ #include #include +extern const struct spa_handle_factory spa_logger_factory; extern const struct spa_handle_factory spa_type_map_factory; int @@ -31,6 +32,9 @@ spa_handle_factory_enum(const struct spa_handle_factory **factory, uint32_t inde case 0: *factory = &spa_type_map_factory; break; + case 1: + *factory = &spa_logger_factory; + break; default: return SPA_RESULT_ENUM_END; }