From cd1ec41253c44a51dd4a24747efbc734841151b9 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 5 Nov 2019 10:01:43 +0100 Subject: [PATCH] jack: use metadata when available --- pipewire-jack/src/meson.build | 1 - pipewire-jack/src/metadata.c | 22 ++++----- pipewire-jack/src/pipewire-jack.c | 77 ++++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/pipewire-jack/src/meson.build b/pipewire-jack/src/meson.build index 7287ab482..580735758 100644 --- a/pipewire-jack/src/meson.build +++ b/pipewire-jack/src/meson.build @@ -1,6 +1,5 @@ pipewire_jack_sources = [ 'pipewire-jack.c', - 'metadata.c', 'ringbuffer.c', 'uuid.c', ] diff --git a/pipewire-jack/src/metadata.c b/pipewire-jack/src/metadata.c index 8ec3b212b..5f8c5b640 100644 --- a/pipewire-jack/src/metadata.c +++ b/pipewire-jack/src/metadata.c @@ -29,15 +29,14 @@ #include #include - +#include static struct pw_properties * get_properties(void) { - static struct pw_properties *properties = NULL; - if (properties == NULL) { - properties = pw_properties_new(NULL, NULL); + if (globals.properties == NULL) { + globals.properties = pw_properties_new(NULL, NULL); } - return properties; + return globals.properties; } static void make_key(char *dst, jack_uuid_t subject, const char *key, int keylen) @@ -56,15 +55,14 @@ int jack_set_property(jack_client_t*client, const char* value, const char* type) { - int keylen = strlen(key); - char *dst = alloca(JACK_UUID_STRING_SIZE + keylen); - struct pw_properties * props = get_properties(); + struct client *c = (struct client *) client; + uint32_t id; - make_key(dst, subject, key, keylen); - - pw_properties_setf(props, dst, "%s@%s", value, type); - pw_log_debug("set '%s' to '%s@%s'", dst, value, type); + id = jack_uuid_to_index(subject); + pw_log_debug("set id:%u (%lu) '%s' to '%s@%s'", id, subject, key, value, type); + pw_metadata_set_property(c->metadata->proxy, + id, key, type, value); return 0; } diff --git a/pipewire-jack/src/pipewire-jack.c b/pipewire-jack/src/pipewire-jack.c index 736f65725..413e09bad 100644 --- a/pipewire-jack/src/pipewire-jack.c +++ b/pipewire-jack/src/pipewire-jack.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ #include #include "extensions/client-node.h" +#include "extensions/metadata.h" #define JACK_DEFAULT_VIDEO_TYPE "32 bit float RGBA video" @@ -77,6 +79,8 @@ struct port; struct globals { jack_thread_creator_t creator; + jack_client_t *client; + struct pw_properties *properties; }; static struct globals globals; @@ -214,6 +218,11 @@ struct context { #define GET_OUT_PORT(c,p) (&c->port_pool[SPA_DIRECTION_OUTPUT][p]) #define GET_PORT(c,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(c,p) : GET_OUT_PORT(c,p)) +struct metadata { + struct pw_metadata *proxy; + struct spa_hook listener; +}; + struct client { char name[JACK_CLIENT_NAME_SIZE+1]; @@ -236,6 +245,8 @@ struct client { struct spa_hook node_listener; struct spa_hook proxy_listener; + struct metadata *metadata; + uint32_t node_id; struct spa_source *socket_source; @@ -273,6 +284,8 @@ struct client { void *sync_arg; JackTimebaseCallback timebase_callback; void *timebase_arg; + JackPropertyChangeCallback property_callback; + void *property_arg; struct spa_io_position *position; uint32_t sample_rate; @@ -303,6 +316,8 @@ struct client { jack_transport_state_t jack_state; }; +#include "metadata.c" + static void init_port_pool(struct client *c, enum spa_direction direction) { int i; @@ -1791,6 +1806,44 @@ static const char* type_to_string(jack_port_type_id_t type_id) } } +static int metadata_property(void *object, uint32_t id, + const char *key, const char *type, const char *value) +{ + struct client *c = (struct client *) object; + int keylen = strlen(key); + char *dst = alloca(JACK_UUID_STRING_SIZE + keylen); + struct pw_properties * props = get_properties(); + jack_property_change_t change; + jack_uuid_t uuid; + + uuid = jack_port_uuid_generate(id); + + make_key(dst, uuid, key, keylen); + + if (value == NULL || type == NULL) { + pw_properties_setf(props, dst, NULL); + change = PropertyDeleted; + } else { + change = PropertyCreated; + if (pw_properties_get(props, dst) != NULL) + change = PropertyChanged; + + pw_properties_setf(props, dst, "%s@%s", value, type); + } + + pw_log_debug("set id:%u '%s' to '%s@%s'", id, dst, value, type); + + if (c->property_callback) + c->property_callback(uuid, key, change, c->property_arg); + + return 0; +} + +static const struct pw_metadata_events metadata_events = { + PW_VERSION_METADATA_EVENTS, + .property = metadata_property +}; + static void registry_event_global(void *data, uint32_t id, uint32_t permissions, uint32_t type, uint32_t version, const struct spa_dict *props) @@ -1926,6 +1979,24 @@ static void registry_event_global(void *data, uint32_t id, o->port_link.src, o->port_link.dst); break; + case PW_TYPE_INTERFACE_Metadata: + { + struct pw_proxy *proxy; + + if (c->metadata) + goto exit; + + proxy = pw_registry_proxy_bind(c->registry_proxy, + id, type, PW_VERSION_METADATA, sizeof(struct metadata)); + + c->metadata = pw_proxy_get_user_data(proxy); + c->metadata->proxy = (struct pw_metadata*)proxy; + + pw_proxy_add_object_listener(proxy, + &c->metadata->listener, + &metadata_events, c); + goto exit; + } default: goto exit; } @@ -2160,7 +2231,9 @@ jack_client_t * jack_client_open (const char *client_name, if (status) *status = 0; - pw_log_trace(NAME" %p: new", client); + globals.client = (jack_client_t *)client; + + pw_log_debug(NAME" %p: new", client); return (jack_client_t *)client; init_failed: @@ -2199,6 +2272,8 @@ int jack_client_close (jack_client_t *client) pw_log_debug(NAME" %p: close", client); + do_sync(c); + pw_thread_loop_stop(c->context.loop); c->destroyed = true;