mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-09-20 00:11:31 +00:00
pulse-server: improve sink/source state
When a sink is RUNNING but there is nothing linked to the input it must be the monitor that is keeping it active, report IDLE for the sink in that case. When a source is RUNNING but there is nothing linked to the output it must be the sink part that is keeping it active, report IDLE for the source. Fixes #1345
This commit is contained in:
parent
eb262beb22
commit
0c14ec769f
|
@ -71,6 +71,30 @@ struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s
|
|||
return s->best;
|
||||
}
|
||||
|
||||
bool collect_is_linked(struct pw_manager *m, uint32_t obj_id, enum pw_direction direction)
|
||||
{
|
||||
struct pw_manager_object *o;
|
||||
const char *str;
|
||||
uint32_t in_node, out_node;
|
||||
|
||||
spa_list_for_each(o, &m->object_list, link) {
|
||||
if (o->props == NULL || !pw_manager_object_is_link(o))
|
||||
continue;
|
||||
|
||||
if ((str = pw_properties_get(o->props, PW_KEY_LINK_OUTPUT_NODE)) == NULL)
|
||||
continue;
|
||||
out_node = pw_properties_parse_int(str);
|
||||
if ((str = pw_properties_get(o->props, PW_KEY_LINK_INPUT_NODE)) == NULL)
|
||||
continue;
|
||||
in_node = pw_properties_parse_int(str);
|
||||
|
||||
if ((direction == PW_DIRECTION_OUTPUT && obj_id == out_node) ||
|
||||
(direction == PW_DIRECTION_INPUT && obj_id == in_node))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct pw_manager_object *find_linked(struct pw_manager *m, uint32_t obj_id, enum pw_direction direction)
|
||||
{
|
||||
struct pw_manager_object *o, *p;
|
||||
|
|
|
@ -155,5 +155,6 @@ struct spa_dict *collect_props(struct spa_pod *info, struct spa_dict *dict);
|
|||
uint32_t find_profile_id(struct pw_manager_object *card, const char *name);
|
||||
uint32_t find_port_id(struct pw_manager_object *card, uint32_t direction, const char *port_name);
|
||||
struct pw_manager_object *find_linked(struct pw_manager *m, uint32_t obj_id, enum pw_direction direction);
|
||||
bool collect_is_linked(struct pw_manager *m, uint32_t obj_id, enum pw_direction direction);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3467,11 +3467,19 @@ static int fill_sink_info(struct client *client, struct message *m,
|
|||
TAG_INVALID);
|
||||
}
|
||||
if (client->version >= 15) {
|
||||
bool is_linked = collect_is_linked(manager, o->id, SPA_DIRECTION_INPUT);
|
||||
int state = node_state(info->state);
|
||||
|
||||
/* running with nothing linked is probably the monitor that is
|
||||
* keeping this sink busy */
|
||||
if (state == STATE_RUNNING && !is_linked)
|
||||
state = STATE_IDLE;
|
||||
|
||||
message_put(m,
|
||||
TAG_VOLUME, dev_info.volume_info.base, /* base volume */
|
||||
TAG_U32, node_state(info->state), /* state */
|
||||
TAG_U32, state, /* state */
|
||||
TAG_U32, dev_info.volume_info.steps, /* n_volume_steps */
|
||||
TAG_U32, card_id, /* card index */
|
||||
TAG_U32, card_id, /* card index */
|
||||
TAG_INVALID);
|
||||
}
|
||||
if (client->version >= 16) {
|
||||
|
@ -3611,9 +3619,17 @@ static int fill_source_info(struct client *client, struct message *m,
|
|||
TAG_INVALID);
|
||||
}
|
||||
if (client->version >= 15) {
|
||||
bool is_linked = collect_is_linked(manager, o->id, SPA_DIRECTION_OUTPUT);
|
||||
int state = node_state(info->state);
|
||||
|
||||
/* running with nothing linked is probably the sink that is
|
||||
* keeping this source busy */
|
||||
if (state == STATE_RUNNING && !is_linked)
|
||||
state = STATE_IDLE;
|
||||
|
||||
message_put(m,
|
||||
TAG_VOLUME, dev_info.volume_info.base, /* base volume */
|
||||
TAG_U32, node_state(info->state), /* state */
|
||||
TAG_U32, state, /* state */
|
||||
TAG_U32, dev_info.volume_info.steps, /* n_volume_steps */
|
||||
TAG_U32, card_id, /* card index */
|
||||
TAG_INVALID);
|
||||
|
|
Loading…
Reference in a new issue