mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
stream: connect to source and sink
Stream: also connect to the right source, try to convert the name to index when lookup fails, just like what pulseaudio does. Implement more proplist functions, add some more info to the stream. stream: handle NULL format Improve introspection of the sink_input and source_output name, this should be the media.name when possible.
This commit is contained in:
parent
ad723e3793
commit
84a7bf671c
4 changed files with 89 additions and 27 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
24
src/stream.c
24
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue