mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	link: add link state and error to info
Notify when state changes
This commit is contained in:
		
							parent
							
								
									0358e8b480
								
							
						
					
					
						commit
						f3dfe61aa0
					
				
					 6 changed files with 68 additions and 42 deletions
				
			
		| 
						 | 
					@ -1034,6 +1034,8 @@ static void link_marshal_info(void *object, struct pw_link_info *info)
 | 
				
			||||||
			    "i", info->output_port_id,
 | 
								    "i", info->output_port_id,
 | 
				
			||||||
			    "i", info->input_node_id,
 | 
								    "i", info->input_node_id,
 | 
				
			||||||
			    "i", info->input_port_id,
 | 
								    "i", info->input_port_id,
 | 
				
			||||||
 | 
								    "i", info->state,
 | 
				
			||||||
 | 
								    "s", info->error,
 | 
				
			||||||
			    "P", info->format,
 | 
								    "P", info->format,
 | 
				
			||||||
			    "i", n_items, NULL);
 | 
								    "i", n_items, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1064,6 +1066,8 @@ static int link_demarshal_info(void *object, void *data, size_t size)
 | 
				
			||||||
			"i", &info.output_port_id,
 | 
								"i", &info.output_port_id,
 | 
				
			||||||
			"i", &info.input_node_id,
 | 
								"i", &info.input_node_id,
 | 
				
			||||||
			"i", &info.input_port_id,
 | 
								"i", &info.input_port_id,
 | 
				
			||||||
 | 
								"i", &info.state,
 | 
				
			||||||
 | 
								"s", &info.error,
 | 
				
			||||||
			"P", &info.format,
 | 
								"P", &info.format,
 | 
				
			||||||
			"i", &props.n_items, NULL) < 0)
 | 
								"i", &props.n_items, NULL) < 0)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -399,6 +399,12 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info,
 | 
				
			||||||
		info->input_node_id = update->input_node_id;
 | 
							info->input_node_id = update->input_node_id;
 | 
				
			||||||
		info->input_port_id = update->input_port_id;
 | 
							info->input_port_id = update->input_port_id;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (update->change_mask & PW_LINK_CHANGE_MASK_STATE) {
 | 
				
			||||||
 | 
							info->state = update->state;
 | 
				
			||||||
 | 
							if (info->error)
 | 
				
			||||||
 | 
								free((void *) info->error);
 | 
				
			||||||
 | 
							info->error = update->error ? strdup(update->error) : NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if (update->change_mask & PW_LINK_CHANGE_MASK_FORMAT) {
 | 
						if (update->change_mask & PW_LINK_CHANGE_MASK_FORMAT) {
 | 
				
			||||||
		if (info->format)
 | 
							if (info->format)
 | 
				
			||||||
			free(info->format);
 | 
								free(info->format);
 | 
				
			||||||
| 
						 | 
					@ -414,6 +420,8 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pw_link_info_free(struct pw_link_info *info)
 | 
					void pw_link_info_free(struct pw_link_info *info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (info->error)
 | 
				
			||||||
 | 
							free((void *) info->error);
 | 
				
			||||||
	if (info->format)
 | 
						if (info->format)
 | 
				
			||||||
		free(info->format);
 | 
							free(info->format);
 | 
				
			||||||
	if (info->props)
 | 
						if (info->props)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -204,13 +204,16 @@ struct pw_link_info {
 | 
				
			||||||
	uint32_t id;			/**< id of the global */
 | 
						uint32_t id;			/**< id of the global */
 | 
				
			||||||
#define PW_LINK_CHANGE_MASK_OUTPUT		(1 << 0)
 | 
					#define PW_LINK_CHANGE_MASK_OUTPUT		(1 << 0)
 | 
				
			||||||
#define PW_LINK_CHANGE_MASK_INPUT		(1 << 1)
 | 
					#define PW_LINK_CHANGE_MASK_INPUT		(1 << 1)
 | 
				
			||||||
#define PW_LINK_CHANGE_MASK_FORMAT		(1 << 2)
 | 
					#define PW_LINK_CHANGE_MASK_STATE		(1 << 2)
 | 
				
			||||||
#define PW_LINK_CHANGE_MASK_PROPS		(1 << 3)
 | 
					#define PW_LINK_CHANGE_MASK_FORMAT		(1 << 4)
 | 
				
			||||||
 | 
					#define PW_LINK_CHANGE_MASK_PROPS		(1 << 4)
 | 
				
			||||||
	uint64_t change_mask;		/**< bitfield of changed fields since last call */
 | 
						uint64_t change_mask;		/**< bitfield of changed fields since last call */
 | 
				
			||||||
	uint32_t output_node_id;	/**< server side output node id */
 | 
						uint32_t output_node_id;	/**< server side output node id */
 | 
				
			||||||
	uint32_t output_port_id;	/**< output port id */
 | 
						uint32_t output_port_id;	/**< output port id */
 | 
				
			||||||
	uint32_t input_node_id;		/**< server side input node id */
 | 
						uint32_t input_node_id;		/**< server side input node id */
 | 
				
			||||||
	uint32_t input_port_id;		/**< input port id */
 | 
						uint32_t input_port_id;		/**< input port id */
 | 
				
			||||||
 | 
						enum pw_link_state state;	/**< the current state of the link */
 | 
				
			||||||
 | 
						const char *error;		/**< an error reason if \a state is error */
 | 
				
			||||||
	struct spa_pod *format;		/**< format over link */
 | 
						struct spa_pod *format;		/**< format over link */
 | 
				
			||||||
	struct spa_dict *props;		/**< the properties of the link */
 | 
						struct spa_dict *props;		/**< the properties of the link */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,10 +88,13 @@ static void debug_link(struct pw_link *link)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pw_link_update_state(struct pw_link *link, enum pw_link_state state, char *error)
 | 
					static void pw_link_update_state(struct pw_link *link, enum pw_link_state state, char *error)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum pw_link_state old = link->state;
 | 
						enum pw_link_state old = link->info.state;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (state != old) {
 | 
					 | 
				
			||||||
	struct pw_node *in = link->input->node, *out = link->output->node;
 | 
						struct pw_node *in = link->input->node, *out = link->output->node;
 | 
				
			||||||
 | 
						struct pw_resource *resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (state == old)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (state == PW_LINK_STATE_ERROR) {
 | 
						if (state == PW_LINK_STATE_ERROR) {
 | 
				
			||||||
		pw_log_error("link %p: update state %s -> error (%s)", link,
 | 
							pw_log_error("link %p: update state %s -> error (%s)", link,
 | 
				
			||||||
| 
						 | 
					@ -101,13 +104,21 @@ static void pw_link_update_state(struct pw_link *link, enum pw_link_state state,
 | 
				
			||||||
		     pw_link_state_as_string(old), pw_link_state_as_string(state));
 | 
							     pw_link_state_as_string(old), pw_link_state_as_string(state));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		link->state = state;
 | 
						link->info.state = state;
 | 
				
			||||||
		if (link->error)
 | 
						if (link->info.error)
 | 
				
			||||||
			free(link->error);
 | 
							free((char*)link->info.error);
 | 
				
			||||||
		link->error = error;
 | 
						link->info.error = error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_link_events_state_changed(link, old, state, error);
 | 
						pw_link_events_state_changed(link, old, state, error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						link->info.change_mask |= PW_LINK_CHANGE_MASK_STATE;
 | 
				
			||||||
 | 
						pw_link_events_info_changed(link, &link->info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_list_for_each(resource, &link->resource_list, link)
 | 
				
			||||||
 | 
							pw_link_resource_info(resource, &link->info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						link->info.change_mask = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	debug_link(link);
 | 
						debug_link(link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (old != PW_LINK_STATE_PAUSED && state == PW_LINK_STATE_PAUSED) {
 | 
						if (old != PW_LINK_STATE_PAUSED && state == PW_LINK_STATE_PAUSED) {
 | 
				
			||||||
| 
						 | 
					@ -125,8 +136,6 @@ static void pw_link_update_state(struct pw_link *link, enum pw_link_state state,
 | 
				
			||||||
		    in->n_ready_output_links == 0)
 | 
							    in->n_ready_output_links == 0)
 | 
				
			||||||
			pw_node_set_state(in, PW_NODE_STATE_IDLE);
 | 
								pw_node_set_state(in, PW_NODE_STATE_IDLE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void complete_ready(void *obj, void *data, int res, uint32_t id)
 | 
					static void complete_ready(void *obj, void *data, int res, uint32_t id)
 | 
				
			||||||
| 
						 | 
					@ -852,14 +861,14 @@ int pw_link_activate(struct pw_link *this)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
 | 
						struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_log_debug("link %p: activate %d %d", this, impl->activated, this->state);
 | 
						pw_log_debug("link %p: activate %d %d", this, impl->activated, this->info.state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (impl->activated)
 | 
						if (impl->activated)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pw_link_prepare(this);
 | 
						pw_link_prepare(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->state == PW_LINK_STATE_PAUSED) {
 | 
						if (this->info.state == PW_LINK_STATE_PAUSED) {
 | 
				
			||||||
		pw_loop_invoke(this->output->node->data_loop,
 | 
							pw_loop_invoke(this->output->node->data_loop,
 | 
				
			||||||
		       do_activate_link, SPA_ID_INVALID, NULL, 0, false, this);
 | 
							       do_activate_link, SPA_ID_INVALID, NULL, 0, false, this);
 | 
				
			||||||
		impl->activated = true;
 | 
							impl->activated = true;
 | 
				
			||||||
| 
						 | 
					@ -874,7 +883,7 @@ static int check_states(struct pw_link *this, void *user_data, int res)
 | 
				
			||||||
	struct pw_port *input, *output;
 | 
						struct pw_port *input, *output;
 | 
				
			||||||
	int in_mix_state, out_mix_state;
 | 
						int in_mix_state, out_mix_state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->state == PW_LINK_STATE_ERROR)
 | 
						if (this->info.state == PW_LINK_STATE_ERROR)
 | 
				
			||||||
		return -EIO;
 | 
							return -EIO;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	input = this->input;
 | 
						input = this->input;
 | 
				
			||||||
| 
						 | 
					@ -1318,7 +1327,7 @@ struct pw_link *pw_link_new(struct pw_core *core,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->core = core;
 | 
						this->core = core;
 | 
				
			||||||
	this->properties = properties;
 | 
						this->properties = properties;
 | 
				
			||||||
	this->state = PW_LINK_STATE_INIT;
 | 
						this->info.state = PW_LINK_STATE_INIT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->input = input;
 | 
						this->input = input;
 | 
				
			||||||
	this->output = output;
 | 
						this->output = output;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -462,9 +462,6 @@ struct pw_link {
 | 
				
			||||||
	struct pw_properties *properties;	/**< extra link properties */
 | 
						struct pw_properties *properties;	/**< extra link properties */
 | 
				
			||||||
	bool feedback;
 | 
						bool feedback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum pw_link_state state;	/**< link state */
 | 
					 | 
				
			||||||
	char *error;			/**< error message when state error */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct spa_list resource_list;	/**< list of bound resources */
 | 
						struct spa_list resource_list;	/**< list of bound resources */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_io_buffers *io;	/**< link io area */
 | 
						struct spa_io_buffers *io;	/**< link io area */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -426,12 +426,17 @@ static void link_event_info(void *object, struct pw_link_info *info)
 | 
				
			||||||
		printf("%c\toutput-port-id: %u\n", MARK_CHANGE(0), info->output_port_id);
 | 
							printf("%c\toutput-port-id: %u\n", MARK_CHANGE(0), info->output_port_id);
 | 
				
			||||||
		printf("%c\tinput-node-id: %u\n", MARK_CHANGE(1), info->input_node_id);
 | 
							printf("%c\tinput-node-id: %u\n", MARK_CHANGE(1), info->input_node_id);
 | 
				
			||||||
		printf("%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id);
 | 
							printf("%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id);
 | 
				
			||||||
		printf("%c\tformat:\n", MARK_CHANGE(2));
 | 
							printf("%c\tstate: \"%s\"", MARK_CHANGE(2), pw_link_state_as_string(info->state));
 | 
				
			||||||
 | 
							if (info->state == PW_LINK_STATE_ERROR && info->error)
 | 
				
			||||||
 | 
								printf(" \"%s\"\n", info->error);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								printf("\n");
 | 
				
			||||||
 | 
							printf("%c\tformat:\n", MARK_CHANGE(3));
 | 
				
			||||||
		if (info->format)
 | 
							if (info->format)
 | 
				
			||||||
			spa_debug_format(2, NULL, info->format);
 | 
								spa_debug_format(2, NULL, info->format);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			printf("\t\tnone\n");
 | 
								printf("\t\tnone\n");
 | 
				
			||||||
		print_properties(info->props, MARK_CHANGE(3));
 | 
							print_properties(info->props, MARK_CHANGE(4));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue