mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05: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
					
				
					 3 changed files with 44 additions and 3 deletions
				
			
		| 
						 | 
					@ -71,6 +71,30 @@ struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s
 | 
				
			||||||
	return s->best;
 | 
						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 *find_linked(struct pw_manager *m, uint32_t obj_id, enum pw_direction direction)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pw_manager_object *o, *p;
 | 
						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_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);
 | 
					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);
 | 
					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
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3467,9 +3467,17 @@ static int fill_sink_info(struct client *client, struct message *m,
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (client->version >= 15) {
 | 
						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,
 | 
							message_put(m,
 | 
				
			||||||
			TAG_VOLUME, dev_info.volume_info.base,	/* base volume */
 | 
								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, dev_info.volume_info.steps,	/* n_volume_steps */
 | 
				
			||||||
			TAG_U32, card_id,			/* card index */
 | 
								TAG_U32, card_id,			/* card index */
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
| 
						 | 
					@ -3611,9 +3619,17 @@ static int fill_source_info(struct client *client, struct message *m,
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (client->version >= 15) {
 | 
						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,
 | 
							message_put(m,
 | 
				
			||||||
			TAG_VOLUME, dev_info.volume_info.base,	/* base volume */
 | 
								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, dev_info.volume_info.steps,	/* n_volume_steps */
 | 
				
			||||||
			TAG_U32, card_id,			/* card index */
 | 
								TAG_U32, card_id,			/* card index */
 | 
				
			||||||
			TAG_INVALID);
 | 
								TAG_INVALID);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue