diff --git a/src/modules/module-protocol-pulse/collect.c b/src/modules/module-protocol-pulse/collect.c index 6edb468cd..f7c182146 100644 --- a/src/modules/module-protocol-pulse/collect.c +++ b/src/modules/module-protocol-pulse/collect.c @@ -6,6 +6,9 @@ #include #include #include + +#include + #include #include "collect.h" @@ -226,7 +229,7 @@ uint32_t find_profile_index(struct pw_manager_object *card, const char *name) return SPA_ID_INVALID; } -void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card, +static void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card, struct device_info *dev_info, bool monitor, struct defs *defs) { struct pw_manager_param *p; @@ -287,6 +290,57 @@ void collect_device_info(struct pw_manager_object *device, struct pw_manager_obj dev_info->volume_info.volume.channels = dev_info->map.channels; } +static void update_device_info(struct pw_manager *manager, struct pw_manager_object *o, + enum pw_direction direction, bool monitor, struct defs *defs) +{ + const char *str; + const char *key = monitor ? "device.info.monitor" : "device.info"; + struct pw_manager_object *card = NULL; + struct pw_node_info *info = o->info; + struct device_info *dev_info, di; + + if (info == NULL) + return; + + di = DEVICE_INFO_INIT(direction); + if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) + di.card_id = (uint32_t)atoi(str); + if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) + di.device = (uint32_t)atoi(str); + if (di.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = di.card_id, .type = pw_manager_object_is_card, }; + card = select_object(manager, &sel); + } + collect_device_info(o, card, &di, monitor, defs); + + dev_info = pw_manager_object_get_data(o, key); + if (dev_info) { + if (memcmp(dev_info, &di, sizeof(di)) != 0) { + if (monitor || direction == PW_DIRECTION_INPUT) + o->change_mask |= PW_MANAGER_OBJECT_FLAG_SOURCE; + else + o->change_mask |= PW_MANAGER_OBJECT_FLAG_SINK; + } + } else { + o->change_mask = ~0; + dev_info = pw_manager_object_add_data(o, key, sizeof(*dev_info)); + } + if (dev_info != NULL) + *dev_info = di; +} + +void get_device_info(struct pw_manager_object *o, struct device_info *info, + enum pw_direction direction, bool monitor) +{ + const char *key = monitor ? "device.info.monitor" : "device.info"; + struct device_info *di; + di = pw_manager_object_get_data(o, key); + if (di != NULL) + *info = *di; + else + *info = DEVICE_INFO_INIT(direction); +} + static bool array_contains(uint32_t *vals, uint32_t n_vals, uint32_t val) { uint32_t n; @@ -527,3 +581,21 @@ uint32_t collect_transport_codec_info(struct pw_manager_object *card, return n_codecs; } + +void update_object_info(struct pw_manager *manager, struct pw_manager_object *o, + struct defs *defs) +{ + if (pw_manager_object_is_sink(o)) { + update_device_info(manager, o, PW_DIRECTION_OUTPUT, false, defs); + update_device_info(manager, o, PW_DIRECTION_OUTPUT, true, defs); + } + if (pw_manager_object_is_source(o)) { + update_device_info(manager, o, PW_DIRECTION_INPUT, false, defs); + } + if (pw_manager_object_is_source_output(o)) { + update_device_info(manager, o, PW_DIRECTION_INPUT, false, defs); + } + if (pw_manager_object_is_sink_input(o)) { + update_device_info(manager, o, PW_DIRECTION_OUTPUT, false, defs); + } +} diff --git a/src/modules/module-protocol-pulse/collect.h b/src/modules/module-protocol-pulse/collect.h index c5059d91c..40b08d62f 100644 --- a/src/modules/module-protocol-pulse/collect.h +++ b/src/modules/module-protocol-pulse/collect.h @@ -35,6 +35,8 @@ struct selector { struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s); uint32_t id_to_index(struct pw_manager *m, uint32_t id); void select_best(struct selector *s, struct pw_manager_object *o); +void update_object_info(struct pw_manager *manager, struct pw_manager_object *o, + struct defs *defs); /* ========================================================================== */ @@ -47,9 +49,11 @@ struct device_info { unsigned int have_volume:1; unsigned int have_iec958codecs:1; + uint32_t card_id; uint32_t device; uint32_t active_port; const char *active_port_name; + }; #define DEVICE_INFO_INIT(_dir) \ @@ -58,12 +62,13 @@ struct device_info { .ss = SAMPLE_SPEC_INIT, \ .map = CHANNEL_MAP_INIT, \ .volume_info = VOLUME_INFO_INIT, \ + .card_id = SPA_ID_INVALID, \ .device = SPA_ID_INVALID, \ .active_port = SPA_ID_INVALID, \ } -void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card, - struct device_info *dev_info, bool monitor, struct defs *defs); +void get_device_info(struct pw_manager_object *device, struct device_info *info, + enum pw_direction direction, bool monitor); /* ========================================================================== */ diff --git a/src/modules/module-protocol-pulse/extensions/ext-device-restore.c b/src/modules/module-protocol-pulse/extensions/ext-device-restore.c index 5932b1c64..a67ab1e17 100644 --- a/src/modules/module-protocol-pulse/extensions/ext-device-restore.c +++ b/src/modules/module-protocol-pulse/extensions/ext-device-restore.c @@ -220,17 +220,15 @@ static int set_node_codecs(struct pw_manager_object *o, uint32_t n_codecs, uint3 static int do_extension_device_restore_save_formats(struct client *client, uint32_t command, uint32_t tag, struct message *m) { - struct impl *impl = client->impl; struct pw_manager *manager = client->manager; struct selector sel; struct pw_manager_object *o, *card = NULL; struct pw_node_info *info; int res; - uint32_t type, sink_index, card_id = SPA_ID_INVALID; + uint32_t type, sink_index; uint8_t i, n_formats; uint32_t n_codecs = 0, codec, iec958codecs[32]; struct device_info dev_info; - const char *str; if ((res = message_get(m, TAG_U32, &type, @@ -269,18 +267,12 @@ static int do_extension_device_restore_save_formats(struct client *client, if (o == NULL || (info = o->info) == NULL || info->props == NULL) return -ENOENT; - dev_info = DEVICE_INFO_INIT(SPA_DIRECTION_INPUT); + get_device_info(o, &dev_info, SPA_DIRECTION_INPUT, false); - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; card = select_object(manager, &sel); } - collect_device_info(o, card, &dev_info, false, &impl->defs); - if (card != NULL && dev_info.active_port != SPA_ID_INVALID) { res = set_card_codecs(card, dev_info.active_port, dev_info.device, n_codecs, iec958codecs); diff --git a/src/modules/module-protocol-pulse/manager.h b/src/modules/module-protocol-pulse/manager.h index da2b8e1e8..52dab04e4 100644 --- a/src/modules/module-protocol-pulse/manager.h +++ b/src/modules/module-protocol-pulse/manager.h @@ -75,6 +75,8 @@ struct pw_manager_object { struct spa_param_info *params; uint32_t n_params; +#define PW_MANAGER_OBJECT_FLAG_SOURCE (1<<0) +#define PW_MANAGER_OBJECT_FLAG_SINK (1<<1) uint64_t change_mask; /* object specific params change mask */ struct spa_list param_list; unsigned int creating:1; diff --git a/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c b/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c index 6a1dcd3e3..e83ccb90d 100644 --- a/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c +++ b/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c @@ -180,17 +180,14 @@ static char* channel_map_snprint(char *s, size_t l, const struct channel_map *ma static void fill_service_data(struct module_zeroconf_publish_data *d, struct service *s, struct pw_manager_object *o) { - struct impl *impl = d->module->impl; bool is_sink = pw_manager_object_is_sink(o); bool is_source = pw_manager_object_is_source(o); struct pw_node_info *info = o->info; - const char *name, *desc, *str; - uint32_t card_id = SPA_ID_INVALID; + const char *name, *desc; struct pw_manager *manager = d->manager; struct pw_manager_object *card = NULL; struct card_info card_info = CARD_INFO_INIT; - struct device_info dev_info = is_sink ? - DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT) : DEVICE_INFO_INIT(PW_DIRECTION_INPUT); + struct device_info dev_info; uint32_t flags = 0; if (info == NULL || info->props == NULL) @@ -202,19 +199,15 @@ static void fill_service_data(struct module_zeroconf_publish_data *d, struct ser if (name == NULL) name = "unknown"; - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; + get_device_info(o, &dev_info, is_sink ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT, false); + + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; card = select_object(manager, &sel); } if (card) collect_card_info(card, &card_info); - collect_device_info(o, card, &dev_info, false, &impl->defs); - if (!pw_manager_object_is_virtual(o)) { if (is_sink) flags |= SINK_HARDWARE; diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index dab41a2eb..09e4a8d2e 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -208,13 +208,15 @@ static int send_object_event(struct client *client, struct pw_manager_object *o, { uint32_t event = 0, mask = 0, res_index = o->index; - if (pw_manager_object_is_sink(o)) { + pw_log_debug("index:%d id:%d %08lx type:%u", o->index, o->id, o->change_mask, type); + + if (pw_manager_object_is_sink(o) && o->change_mask & PW_MANAGER_OBJECT_FLAG_SINK) { client_queue_subscribe_event(client, SUBSCRIPTION_MASK_SINK, SUBSCRIPTION_EVENT_SINK | type, res_index); } - if (pw_manager_object_is_source_or_monitor(o)) { + if (pw_manager_object_is_source_or_monitor(o) && o->change_mask & PW_MANAGER_OBJECT_FLAG_SOURCE) { mask = SUBSCRIPTION_MASK_SOURCE; event = SUBSCRIPTION_EVENT_SOURCE; } @@ -808,6 +810,7 @@ static void manager_added(void *data, struct pw_manager_object *o) { struct client *client = data; struct pw_manager *manager = client->manager; + struct impl *impl = client->impl; const char *str; register_object_message_handlers(o); @@ -869,8 +872,12 @@ static void manager_added(void *data, struct pw_manager_object *o) } } + update_object_info(manager, o, &impl->defs); + send_object_event(client, o, SUBSCRIPTION_EVENT_NEW); + o->change_mask = 0; + /* Adding sinks etc. may also change defaults */ send_default_change_subscribe_event(client, pw_manager_object_is_sink(o), pw_manager_object_is_source_or_monitor(o)); } @@ -878,9 +885,15 @@ static void manager_added(void *data, struct pw_manager_object *o) static void manager_updated(void *data, struct pw_manager_object *o) { struct client *client = data; + struct pw_manager *manager = client->manager; + struct impl *impl = client->impl; + + update_object_info(manager, o, &impl->defs); send_object_event(client, o, SUBSCRIPTION_EVENT_CHANGE); + o->change_mask = 0; + set_temporary_move_target(client, o, SPA_ID_INVALID); send_latency_offset_subscribe_event(client, o); @@ -1646,8 +1659,8 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui spa_zero(fix_ss); spa_zero(fix_map); if ((fix_format || fix_rate || fix_channels) && o != NULL) { - struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT); - collect_device_info(o, NULL, &dev_info, is_monitor, &impl->defs); + struct device_info dev_info; + get_device_info(o, &dev_info, PW_DIRECTION_OUTPUT, is_monitor); fix_ss.format = fix_format ? dev_info.ss.format : 0; fix_ss.rate = fix_rate ? dev_info.ss.rate : 0; fix_ss.channels = fix_channels ? dev_info.ss.channels : 0; @@ -1936,8 +1949,8 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint spa_zero(fix_ss); spa_zero(fix_map); if ((fix_format || fix_rate || fix_channels) && o != NULL) { - struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT); - collect_device_info(o, NULL, &dev_info, is_monitor, &impl->defs); + struct device_info dev_info; + get_device_info(o, &dev_info, PW_DIRECTION_INPUT, is_monitor); fix_ss.format = fix_format ? dev_info.ss.format : 0; fix_ss.rate = fix_rate ? dev_info.ss.rate : 0; fix_ss.channels = fix_channels ? dev_info.ss.channels : 0; @@ -2890,11 +2903,10 @@ done: static int do_set_volume(struct client *client, uint32_t command, uint32_t tag, struct message *m) { - struct impl *impl = client->impl; struct pw_manager *manager = client->manager; struct pw_node_info *info; - uint32_t index, card_id = SPA_ID_INVALID; - const char *name, *str; + uint32_t index; + const char *name; struct volume volume; struct pw_manager_object *o, *card = NULL; int res; @@ -2930,22 +2942,16 @@ static int do_set_volume(struct client *client, uint32_t command, uint32_t tag, if (o == NULL || (info = o->info) == NULL || info->props == NULL) return -ENOENT; - dev_info = DEVICE_INFO_INIT(direction); - - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; - card = select_object(manager, &sel); - } - collect_device_info(o, card, &dev_info, is_monitor, &impl->defs); + get_device_info(o, &dev_info, direction, is_monitor); if (dev_info.have_volume && volume_compare(&dev_info.volume_info.volume, &volume) == 0) goto done; + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; + card = select_object(manager, &sel); + } if (card != NULL && !is_monitor && dev_info.active_port != SPA_ID_INVALID) res = set_card_volume_mute_delay(card, dev_info.active_port, dev_info.device, &volume, NULL, NULL); @@ -2961,11 +2967,10 @@ done: static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, struct message *m) { - struct impl *impl = client->impl; struct pw_manager *manager = client->manager; struct pw_node_info *info; - uint32_t index, card_id = SPA_ID_INVALID; - const char *name, *str; + uint32_t index; + const char *name; bool mute; struct pw_manager_object *o, *card = NULL; int res; @@ -2996,22 +3001,17 @@ static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, st if (o == NULL || (info = o->info) == NULL || info->props == NULL) return -ENOENT; - dev_info = DEVICE_INFO_INIT(direction); - - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; - card = select_object(manager, &sel); - } - collect_device_info(o, card, &dev_info, is_monitor, &impl->defs); + get_device_info(o, &dev_info, direction, is_monitor); if (dev_info.have_volume && dev_info.volume_info.mute == mute) goto done; + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; + card = select_object(manager, &sel); + } + if (card != NULL && !is_monitor && dev_info.active_port != SPA_ID_INVALID) res = set_card_volume_mute_delay(card, dev_info.active_port, dev_info.device, NULL, &mute, NULL); @@ -3666,24 +3666,22 @@ static int fill_sink_info_proplist(struct message *m, const struct spa_dict *sin static bool validate_device_info(struct device_info *dev_info) { return sample_spec_valid(&dev_info->ss) && - channel_map_valid(&dev_info->map) && - volume_valid(&dev_info->volume_info.volume); + channel_map_valid(&dev_info->map) && + volume_valid(&dev_info->volume_info.volume); } static int fill_sink_info(struct client *client, struct message *m, struct pw_manager_object *o) { - struct impl *impl = client->impl; struct pw_node_info *info = o->info; struct pw_manager *manager = client->manager; const char *name, *desc, *str; char *monitor_name = NULL; uint32_t module_id = SPA_ID_INVALID; - uint32_t card_id = SPA_ID_INVALID; struct pw_manager_object *card = NULL; uint32_t flags; struct card_info card_info = CARD_INFO_INIT; - struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT); + struct device_info dev_info; size_t size; if (!pw_manager_object_is_sink(o) || info == NULL || info->props == NULL) @@ -3707,19 +3705,8 @@ static int fill_sink_info(struct client *client, struct message *m, if (module_id == SPA_ID_INVALID && (str = spa_dict_lookup(info->props, "pulse.module.id")) != NULL) module_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; - card = select_object(manager, &sel); - } - if (card) - collect_card_info(card, &card_info); - - collect_device_info(o, card, &dev_info, false, &impl->defs); + get_device_info(o, &dev_info, PW_DIRECTION_OUTPUT, false); if (!validate_device_info(&dev_info)) { pw_log_warn("%d: sink not ready: sample:%d map:%d volume:%d", o->id, sample_spec_valid(&dev_info.ss), @@ -3728,6 +3715,14 @@ static int fill_sink_info(struct client *client, struct message *m, return -ENOENT; } + + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; + card = select_object(manager, &sel); + } + if (card) + collect_card_info(card, &card_info); + flags = SINK_LATENCY | SINK_DYNAMIC_LATENCY | SINK_DECIBEL_VOLUME; if (!pw_manager_object_is_virtual(o)) flags |= SINK_HARDWARE; @@ -3880,7 +3875,6 @@ static int fill_source_info_proplist(struct message *m, const struct spa_dict *s static int fill_source_info(struct client *client, struct message *m, struct pw_manager_object *o) { - struct impl *impl = client->impl; struct pw_node_info *info = o->info; struct pw_manager *manager = client->manager; bool is_monitor; @@ -3888,11 +3882,10 @@ static int fill_source_info(struct client *client, struct message *m, char *monitor_name = NULL; char *monitor_desc = NULL; uint32_t module_id = SPA_ID_INVALID; - uint32_t card_id = SPA_ID_INVALID; struct pw_manager_object *card = NULL; uint32_t flags; struct card_info card_info = CARD_INFO_INIT; - struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT); + struct device_info dev_info; size_t size; is_monitor = pw_manager_object_is_monitor(o); @@ -3918,20 +3911,8 @@ static int fill_source_info(struct client *client, struct message *m, if (module_id == SPA_ID_INVALID && (str = spa_dict_lookup(info->props, "pulse.module.id")) != NULL) module_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL) - card_id = (uint32_t)atoi(str); - if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL) - dev_info.device = (uint32_t)atoi(str); - - if (card_id != SPA_ID_INVALID) { - struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, }; - card = select_object(manager, &sel); - } - if (card) - collect_card_info(card, &card_info); - - collect_device_info(o, card, &dev_info, is_monitor, &impl->defs); + get_device_info(o, &dev_info, PW_DIRECTION_INPUT, is_monitor); if (!validate_device_info(&dev_info)) { pw_log_warn("%d: source not ready: sample:%d map:%d volume:%d", o->id, sample_spec_valid(&dev_info.ss), @@ -3941,6 +3922,14 @@ static int fill_source_info(struct client *client, struct message *m, } flags = SOURCE_LATENCY | SOURCE_DYNAMIC_LATENCY | SOURCE_DECIBEL_VOLUME; + + if (dev_info.card_id != SPA_ID_INVALID) { + struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, }; + card = select_object(manager, &sel); + } + if (card) + collect_card_info(card, &card_info); + if (!pw_manager_object_is_virtual(o)) flags |= SOURCE_HARDWARE; if (pw_manager_object_is_network(o)) @@ -4050,13 +4039,12 @@ static const char *get_media_name(struct pw_node_info *info) static int fill_sink_input_info(struct client *client, struct message *m, struct pw_manager_object *o) { - struct impl *impl = client->impl; struct pw_node_info *info = o->info; struct pw_manager *manager = client->manager; const char *str; uint32_t module_id = SPA_ID_INVALID, client_id = SPA_ID_INVALID; uint32_t peer_index; - struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT); + struct device_info dev_info; if (!pw_manager_object_is_sink_input(o) || info == NULL || info->props == NULL) return -ENOENT; @@ -4071,8 +4059,7 @@ static int fill_sink_input_info(struct client *client, struct message *m, (str = spa_dict_lookup(info->props, PW_KEY_CLIENT_ID)) != NULL) client_id = (uint32_t)atoi(str); - collect_device_info(o, NULL, &dev_info, false, &impl->defs); - + get_device_info(o, &dev_info, PW_DIRECTION_OUTPUT, false); if (!validate_device_info(&dev_info)) return -ENOENT; @@ -4131,13 +4118,12 @@ static int fill_sink_input_info(struct client *client, struct message *m, static int fill_source_output_info(struct client *client, struct message *m, struct pw_manager_object *o) { - struct impl *impl = client->impl; struct pw_node_info *info = o->info; struct pw_manager *manager = client->manager; const char *str; uint32_t module_id = SPA_ID_INVALID, client_id = SPA_ID_INVALID; uint32_t peer_index; - struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT); + struct device_info dev_info; if (!pw_manager_object_is_source_output(o) || info == NULL || info->props == NULL) return -ENOENT; @@ -4152,8 +4138,7 @@ static int fill_source_output_info(struct client *client, struct message *m, (str = spa_dict_lookup(info->props, PW_KEY_CLIENT_ID)) != NULL) client_id = (uint32_t)atoi(str); - collect_device_info(o, NULL, &dev_info, false, &impl->defs); - + get_device_info(o, &dev_info, PW_DIRECTION_INPUT, false); if (!validate_device_info(&dev_info)) return -ENOENT;