diff --git a/src/pipewire/context.c b/src/pipewire/context.c index 7a727e78c..dc2b1490c 100644 --- a/src/pipewire/context.c +++ b/src/pipewire/context.c @@ -385,6 +385,8 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop, goto error_free; pw_log_info(NAME" %p: parsed %d context.exec items", this, res); + pw_settings_init(this); + pw_log_debug(NAME" %p: created", this); return this; diff --git a/src/pipewire/meson.build b/src/pipewire/meson.build index 7c9e835ac..37f811f3c 100644 --- a/src/pipewire/meson.build +++ b/src/pipewire/meson.build @@ -73,6 +73,7 @@ pipewire_sources = [ 'protocol.c', 'proxy.c', 'resource.c', + 'settings.c', 'stream.c', 'thread-loop.c', 'utils.c', diff --git a/src/pipewire/private.h b/src/pipewire/private.h index bc9930645..ba02cc196 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -1241,6 +1241,8 @@ void pw_log_log_object(enum spa_log_level level, const char *file, int line, bool pw_log_is_default(void); +int pw_settings_init(struct pw_context *context); + /** \endcond */ #ifdef __cplusplus diff --git a/src/pipewire/settings.c b/src/pipewire/settings.c new file mode 100644 index 000000000..e8aef12df --- /dev/null +++ b/src/pipewire/settings.c @@ -0,0 +1,146 @@ +/* PipeWire + * + * Copyright © 2021 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include +#include "pipewire/array.h" +#include "pipewire/core.h" + +#include + +#define NAME "settings" + +struct impl { + struct pw_context *context; + struct pw_impl_metadata *metadata; + + struct spa_hook metadata_listener; +}; + +static void metadata_destroy(void *data) +{ + struct impl *impl = data; + spa_hook_remove(&impl->metadata_listener); + impl->metadata = NULL; +} + +static int metadata_property(void *data, uint32_t subject, const char *key, + const char *type, const char *value) +{ + struct impl *impl = data; + struct pw_context *context = impl->context; + struct settings *d = &context->defaults; + struct settings *s = &context->settings; + uint32_t v; + bool recalc = false; + + if (subject != PW_ID_CORE) + return 0; + + if (spa_streq(key, "log.level")) { + v = value ? atoi(value) : 3; + pw_log_set_level(v); + } else if (spa_streq(key, "clock.min-quantum")) { + v = value ? atoi(value) : 0; + s->clock_min_quantum = v == 0 ? d->clock_min_quantum : v; + recalc = true; + } else if (spa_streq(key, "clock.max-quantum")) { + v = value ? atoi(value) : 0; + s->clock_max_quantum = v == 0 ? d->clock_max_quantum : v; + recalc = true; + } else if (spa_streq(key, "clock.force-rate")) { + v = value ? atoi(value) : 0; + s->clock_force_rate = v; + recalc = true; + } else if (spa_streq(key, "clock.force-quantum")) { + v = value ? atoi(value) : 0; + s->clock_force_quantum = SPA_MIN(v, 8192u); + recalc = true; + } + if (recalc) + pw_context_recalc_graph(context, "properties changed"); + + return 0; +} + +static struct pw_impl_metadata_events metadata_events = { + PW_VERSION_IMPL_METADATA_EVENTS, + .destroy = metadata_destroy, + .property = metadata_property, +}; + +static void init_defaults(struct impl *impl) +{ + struct settings *s = &impl->context->settings; + + pw_impl_metadata_set_propertyf(impl->metadata, + PW_ID_CORE, "log.level", "", "%d", s->log_level); + pw_impl_metadata_set_propertyf(impl->metadata, + PW_ID_CORE, "clock.min-quantum", "", "%d", s->clock_min_quantum); + pw_impl_metadata_set_propertyf(impl->metadata, + PW_ID_CORE, "clock.max-quantum", "", "%d", s->clock_max_quantum); + pw_impl_metadata_set_propertyf(impl->metadata, + PW_ID_CORE, "clock.force-quantum", "", "%d", s->clock_force_quantum); + pw_impl_metadata_set_propertyf(impl->metadata, + PW_ID_CORE, "clock.force-rate", "", "%d", s->clock_force_rate); +} + + +int pw_settings_init(struct pw_context *context) +{ + struct impl *impl; + int res; + + impl = calloc(1, sizeof(*impl)); + if (impl == NULL) + goto error_errno; + + impl->context = context; + impl->metadata = pw_context_create_metadata(context, "settings", NULL, 0); + + init_defaults(impl); + + pw_impl_metadata_add_listener(impl->metadata, + &impl->metadata_listener, + &metadata_events, impl); + + pw_impl_metadata_register(impl->metadata, NULL); + + return 0; + +error_errno: + res = -errno; + goto error_free; +error_free: + free(impl); + return res; +}