diff --git a/src/context.c b/src/context.c index 7e87f3f91..0f3193794 100644 --- a/src/context.c +++ b/src/context.c @@ -97,6 +97,25 @@ struct global *pa_context_find_global(pa_context *c, uint32_t id) return NULL; } +struct global *pa_context_find_global_by_name(pa_context *c, uint32_t mask, const char *name) +{ + struct global *g; + const char *str; + uint32_t id = atoi(name); + + spa_list_for_each(g, &c->globals, link) { + if (!(g->mask & mask)) + continue; + if (g->props != NULL && + (str = pw_properties_get(g->props, "node.name")) != NULL && + strcmp(str, name) == 0) + return g; + if (g->id == id) + return g; + } + return NULL; +} + struct global *pa_context_find_linked(pa_context *c, uint32_t idx) { struct global *g, *f; diff --git a/src/introspect.c b/src/introspect.c index 426a52eda..7ccf44b35 100644 --- a/src/introspect.c +++ b/src/introspect.c @@ -363,24 +363,6 @@ static void sink_info(pa_operation *o, void *userdata) pa_operation_done(o); } -struct global *pa_context_find_global_by_name(pa_context *c, uint32_t mask, const char *name) -{ - struct global *g; - const char *str; - - spa_list_for_each(g, &c->globals, link) { - if (!(g->mask & mask)) - continue; - if (g->props == NULL) - continue; - if ((str = pw_properties_get(g->props, "node.name")) == NULL) - continue; - if (strcmp(str, name) == 0) - return g; - } - return NULL; -} - pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name, pa_sink_info_cb_t cb, void *userdata) { pa_operation *o; @@ -1269,6 +1251,7 @@ static void sink_input_callback(struct sink_input_data *d) { struct global *g = d->global, *l; struct pw_node_info *info = g->info; + const char *name; pa_sink_input_info i; pa_format_info ii[1]; pa_stream *s; @@ -1279,9 +1262,17 @@ static void sink_input_callback(struct sink_input_data *d) s = find_stream(d->context, g->id); + if (info->props) { + if ((name = spa_dict_lookup(info->props, "media.name")) == NULL && + (name = spa_dict_lookup(info->props, "application.name")) == NULL) + name = info->name; + } + else + name = info->name; + spa_zero(i); i.index = g->id; - i.name = info->name; + i.name = name ? name : "Unknown"; i.owner_module = PA_INVALID_INDEX; i.client = g->parent_id; if (s) { @@ -1525,6 +1516,7 @@ static void source_output_callback(struct source_output_data *d) { struct global *g = d->global, *l; struct pw_node_info *info = g->info; + const char *name; pa_source_output_info i; pa_format_info ii[1]; pa_stream *s; @@ -1535,9 +1527,17 @@ static void source_output_callback(struct source_output_data *d) s = find_stream(d->context, g->id); + if (info->props) { + if ((name = spa_dict_lookup(info->props, "media.name")) == NULL && + (name = spa_dict_lookup(info->props, "application.name")) == NULL) + name = info->name; + } + else + name = info->name; + spa_zero(i); i.index = g->id; - i.name = info->name; + i.name = name ? name : "Unknown"; i.owner_module = PA_INVALID_INDEX; i.client = g->parent_id; if (s) { diff --git a/src/proplist.c b/src/proplist.c index 281898f1e..fad5c1a5f 100644 --- a/src/proplist.c +++ b/src/proplist.c @@ -159,7 +159,13 @@ int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t * void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, const pa_proplist *other) { spa_assert(p); - pw_log_warn("Not Implemented"); + spa_assert(mode == PA_UPDATE_SET || mode == PA_UPDATE_MERGE || mode == PA_UPDATE_REPLACE); + spa_assert(other); + + if (mode == PA_UPDATE_SET) + pa_proplist_clear(p); + + pa_proplist_update_dict(p, &other->props->dict); } int pa_proplist_unset(pa_proplist *p, const char *key) @@ -274,7 +280,7 @@ int pa_proplist_contains(pa_proplist *p, const char *key) void pa_proplist_clear(pa_proplist *p) { spa_assert(p); - pw_log_warn("Not Implemented"); + pw_properties_clear(p->props); } pa_proplist* pa_proplist_copy(const pa_proplist *p) @@ -305,8 +311,27 @@ int pa_proplist_isempty(pa_proplist *p) int pa_proplist_equal(pa_proplist *a, pa_proplist *b) { + int i; + spa_assert(a); spa_assert(b); - pw_log_warn("Not Implemented"); - return 0; + + if (a == b) + return 1; + + if (pa_proplist_size(a) != pa_proplist_size(b)) + return 0; + + for (i = 0; i < a->props->dict.n_items; i++) { + const struct spa_dict_item *ai, *bi; + + ai = &a->props->dict.items[i]; + bi = spa_dict_lookup_item(&b->props->dict, ai->key); + + if (bi == NULL || bi->value == NULL || ai->value == NULL) + return 0; + if (strcmp(ai->value, bi->value) != 0) + return 0; + } + return 1; } diff --git a/src/stream.c b/src/stream.c index 1ed347c88..ed5144af7 100644 --- a/src/stream.c +++ b/src/stream.c @@ -337,6 +337,11 @@ static void stream_format_changed(void *data, const struct spa_pod *format) struct spa_audio_info info = { 0 }; int i, res; + if (format == NULL) { + res = 0; + goto done; + } + spa_format_parse(format, &info.media_type, &info.media_subtype); if (info.media_type != SPA_MEDIA_TYPE_audio || @@ -497,10 +502,11 @@ pa_stream* stream_new(pa_context *c, const char *name, if (name) pa_proplist_sets(s->proplist, PA_PROP_MEDIA_NAME, name); else - name = pa_proplist_gets(p, PA_PROP_MEDIA_NAME); + name = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME); props = pw_properties_new("client.api", "pulseaudio", NULL); + pw_properties_update(props, &s->proplist->props->dict); s->stream = pw_stream_new(c->remote, name, props); s->refcount = 1; @@ -762,6 +768,8 @@ static int create_stream(pa_stream_direction_t direction, spa_assert(s); spa_assert(s->refcount >= 1); + pw_log_debug("stream %p: connect %s %08x", s, dev, flags); + s->direction = direction; s->timing_info_valid = false; s->disconnecting = false; @@ -824,8 +832,18 @@ static int create_stream(pa_stream_direction_t direction, if ((str = getenv("PIPEWIRE_NODE")) != NULL) devid = atoi(str); } - else if ((g = pa_context_find_global_by_name(s->context, PA_SUBSCRIPTION_MASK_SINK, dev)) != NULL) { - devid = g->id; + else { + uint32_t mask; + + if (direction == PA_STREAM_PLAYBACK) + mask = PA_SUBSCRIPTION_MASK_SINK; + else if (direction == PA_STREAM_RECORD) + mask = PA_SUBSCRIPTION_MASK_SOURCE; + else + mask = 0; + + if ((g = pa_context_find_global_by_name(s->context, mask, dev)) != NULL) + devid = g->id; } if ((str = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_ROLE)) == NULL)