mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	node: make add_listener method
Make struct spa_node_events for events emited from the main thread and keep the spa_node_callbacks for the data thread callbacks. The add_listener method installs the events and it's possible to install multiple handles. Adding a listener first emits the info and port_info events when installed, similar to how the PipeWire proxy bind works. This removes the need for the spa_pending_queue and makes it easier to implement the _sync versions. Add some helpers to make it easier for plugins to emit all the info to new listeners. Use the listeners for devices as well.
This commit is contained in:
		
							parent
							
								
									61ce4e77f6
								
							
						
					
					
						commit
						0390969228
					
				
					 53 changed files with 1774 additions and 1307 deletions
				
			
		| 
						 | 
				
			
			@ -67,8 +67,7 @@ struct impl {
 | 
			
		|||
	struct spa_log *log;
 | 
			
		||||
	struct spa_loop *main_loop;
 | 
			
		||||
 | 
			
		||||
	const struct spa_device_callbacks *callbacks;
 | 
			
		||||
	void *callbacks_data;
 | 
			
		||||
	struct spa_hook_list hooks;
 | 
			
		||||
 | 
			
		||||
	struct props props;
 | 
			
		||||
	uint32_t n_nodes;
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +126,7 @@ static int emit_node(struct impl *this, snd_pcm_info_t *pcminfo, uint32_t id)
 | 
			
		|||
	items[5] = SPA_DICT_ITEM_INIT("alsa.pcm.subclass",   get_subclass(pcminfo));
 | 
			
		||||
	info.props = &SPA_DICT_INIT_ARRAY(items);
 | 
			
		||||
 | 
			
		||||
	this->callbacks->object_info(this->callbacks_data, id, &info);
 | 
			
		||||
	spa_device_emit_object_info(&this->hooks, id, &info);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -141,11 +140,9 @@ static int activate_profile(struct impl *this, snd_ctl_t *ctl_hndl, uint32_t id)
 | 
			
		|||
	spa_log_debug(this->log, "profile %d", id);
 | 
			
		||||
	this->profile = id;
 | 
			
		||||
 | 
			
		||||
	if (this->callbacks->object_info) {
 | 
			
		||||
		for (i = 0; i < this->n_nodes; i++) {
 | 
			
		||||
			this->callbacks->object_info(this->callbacks_data, i, NULL);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for (i = 0; i < this->n_nodes; i++)
 | 
			
		||||
		spa_device_emit_object_info(&this->hooks, i, NULL);
 | 
			
		||||
 | 
			
		||||
	this->n_nodes = 0;
 | 
			
		||||
 | 
			
		||||
	if (id == 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +167,7 @@ static int activate_profile(struct impl *this, snd_ctl_t *ctl_hndl, uint32_t id)
 | 
			
		|||
			if (err != -ENOENT)
 | 
			
		||||
				spa_log_error(this->log, "error pcm info: %s", snd_strerror(err));
 | 
			
		||||
		}
 | 
			
		||||
		if (err >= 0 && this->callbacks->object_info)
 | 
			
		||||
		if (err >= 0)
 | 
			
		||||
			emit_node(this, pcminfo, i++);
 | 
			
		||||
 | 
			
		||||
		snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
 | 
			
		||||
| 
						 | 
				
			
			@ -178,7 +175,7 @@ static int activate_profile(struct impl *this, snd_ctl_t *ctl_hndl, uint32_t id)
 | 
			
		|||
			if (err != -ENOENT)
 | 
			
		||||
				spa_log_error(this->log, "error pcm info: %s", snd_strerror(err));
 | 
			
		||||
		}
 | 
			
		||||
		if (err >= 0 && this->callbacks->object_info)
 | 
			
		||||
		if (err >= 0)
 | 
			
		||||
			emit_node(this, pcminfo, i++);
 | 
			
		||||
	}
 | 
			
		||||
	this->n_nodes = i;
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +203,7 @@ static int set_profile(struct impl *this, uint32_t id)
 | 
			
		|||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int emit_info(struct impl *this)
 | 
			
		||||
static int emit_info(struct impl *this, bool full)
 | 
			
		||||
{
 | 
			
		||||
	int err = 0;
 | 
			
		||||
	struct spa_dict_item items[10];
 | 
			
		||||
| 
						 | 
				
			
			@ -249,8 +246,7 @@ static int emit_info(struct impl *this)
 | 
			
		|||
	dinfo.n_params = SPA_N_ELEMENTS(params);
 | 
			
		||||
	dinfo.params = params;
 | 
			
		||||
 | 
			
		||||
	if (this->callbacks->info)
 | 
			
		||||
		this->callbacks->info(this->callbacks_data, &dinfo);
 | 
			
		||||
	spa_device_emit_info(&this->hooks, &dinfo);
 | 
			
		||||
 | 
			
		||||
	activate_profile(this, ctl_hndl, 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -260,21 +256,24 @@ static int emit_info(struct impl *this)
 | 
			
		|||
	return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int impl_set_callbacks(struct spa_device *device,
 | 
			
		||||
			   const struct spa_device_callbacks *callbacks,
 | 
			
		||||
			   void *data)
 | 
			
		||||
static int impl_add_listener(struct spa_device *device,
 | 
			
		||||
			struct spa_hook *listener,
 | 
			
		||||
			const struct spa_device_events *events,
 | 
			
		||||
			void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this;
 | 
			
		||||
	struct spa_hook_list save;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(device != NULL, -EINVAL);
 | 
			
		||||
	spa_return_val_if_fail(events != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = SPA_CONTAINER_OF(device, struct impl, device);
 | 
			
		||||
	spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
 | 
			
		||||
 | 
			
		||||
	this->callbacks = callbacks;
 | 
			
		||||
	this->callbacks_data = data;
 | 
			
		||||
	if (events->info || events->object_info)
 | 
			
		||||
		emit_info(this, true);
 | 
			
		||||
 | 
			
		||||
	if (callbacks)
 | 
			
		||||
		emit_info(this);
 | 
			
		||||
	spa_hook_list_join(&this->hooks, &save);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -290,13 +289,11 @@ static int impl_enum_params(struct spa_device *device, int seq,
 | 
			
		|||
	uint8_t buffer[1024];
 | 
			
		||||
	struct spa_result_device_params result;
 | 
			
		||||
	uint32_t count = 0;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(device != NULL, -EINVAL);
 | 
			
		||||
	spa_return_val_if_fail(num != 0, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = SPA_CONTAINER_OF(device, struct impl, device);
 | 
			
		||||
	spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
 | 
			
		||||
 | 
			
		||||
	result.id = id;
 | 
			
		||||
	result.next = start;
 | 
			
		||||
| 
						 | 
				
			
			@ -346,8 +343,7 @@ static int impl_enum_params(struct spa_device *device, int seq,
 | 
			
		|||
	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
			
		||||
		goto next;
 | 
			
		||||
 | 
			
		||||
	if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
 | 
			
		||||
		return res;
 | 
			
		||||
	spa_device_emit_result(&this->hooks, seq, 0, &result);
 | 
			
		||||
 | 
			
		||||
	if (++count != num)
 | 
			
		||||
		goto next;
 | 
			
		||||
| 
						 | 
				
			
			@ -390,7 +386,7 @@ static int impl_set_param(struct spa_device *device,
 | 
			
		|||
 | 
			
		||||
static const struct spa_device impl_device = {
 | 
			
		||||
	SPA_VERSION_DEVICE,
 | 
			
		||||
	impl_set_callbacks,
 | 
			
		||||
	impl_add_listener,
 | 
			
		||||
	impl_enum_params,
 | 
			
		||||
	impl_set_param,
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -455,6 +451,7 @@ impl_init(const struct spa_handle_factory *factory,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	this->device = impl_device;
 | 
			
		||||
	spa_hook_list_init(&this->hooks);
 | 
			
		||||
 | 
			
		||||
	reset_props(&this->props);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,13 +59,11 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
 | 
			
		|||
	uint8_t buffer[1024];
 | 
			
		||||
	struct spa_result_node_params result;
 | 
			
		||||
	uint32_t count = 0;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(node != NULL, -EINVAL);
 | 
			
		||||
	spa_return_val_if_fail(num != 0, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = SPA_CONTAINER_OF(node, struct state, node);
 | 
			
		||||
	spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
 | 
			
		||||
 | 
			
		||||
	result.id = id;
 | 
			
		||||
	result.next = start;
 | 
			
		||||
| 
						 | 
				
			
			@ -146,8 +144,7 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
 | 
			
		|||
	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
			
		||||
		goto next;
 | 
			
		||||
 | 
			
		||||
	if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
 | 
			
		||||
		return res;
 | 
			
		||||
	spa_node_emit_result(&this->hooks, seq, 0, &result);
 | 
			
		||||
 | 
			
		||||
	if (++count != num)
 | 
			
		||||
		goto next;
 | 
			
		||||
| 
						 | 
				
			
			@ -239,24 +236,50 @@ static const struct spa_dict_item node_info_items[] = {
 | 
			
		|||
	{ "node.driver", "true" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void emit_node_info(struct state *this)
 | 
			
		||||
static void emit_node_info(struct state *this, bool full)
 | 
			
		||||
{
 | 
			
		||||
	if (this->callbacks && this->callbacks->info && this->info.change_mask) {
 | 
			
		||||
	if (full)
 | 
			
		||||
		this->info.change_mask = this->info_all;
 | 
			
		||||
	if (this->info.change_mask) {
 | 
			
		||||
		this->info.props = &SPA_DICT_INIT_ARRAY(node_info_items);
 | 
			
		||||
		this->callbacks->info(this->callbacks_data, &this->info);
 | 
			
		||||
		spa_node_emit_info(&this->hooks, &this->info);
 | 
			
		||||
		this->info.change_mask = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void emit_port_info(struct state *this)
 | 
			
		||||
static void emit_port_info(struct state *this, bool full)
 | 
			
		||||
{
 | 
			
		||||
	if (this->callbacks && this->callbacks->port_info && this->port_info.change_mask) {
 | 
			
		||||
		this->callbacks->port_info(this->callbacks_data,
 | 
			
		||||
	if (full)
 | 
			
		||||
		this->port_info.change_mask = this->port_info_all;
 | 
			
		||||
	if (this->port_info.change_mask) {
 | 
			
		||||
		spa_node_emit_port_info(&this->hooks,
 | 
			
		||||
				SPA_DIRECTION_INPUT, 0, &this->port_info);
 | 
			
		||||
		this->port_info.change_mask = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
impl_node_add_listener(struct spa_node *node,
 | 
			
		||||
		struct spa_hook *listener,
 | 
			
		||||
		const struct spa_node_events *events,
 | 
			
		||||
		void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct state *this;
 | 
			
		||||
	struct spa_hook_list save;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(node != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = SPA_CONTAINER_OF(node, struct state, node);
 | 
			
		||||
	spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
 | 
			
		||||
 | 
			
		||||
	emit_node_info(this, true);
 | 
			
		||||
	emit_port_info(this, true);
 | 
			
		||||
 | 
			
		||||
	spa_hook_list_join(&this->hooks, &save);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
impl_node_set_callbacks(struct spa_node *node,
 | 
			
		||||
			const struct spa_node_callbacks *callbacks,
 | 
			
		||||
| 
						 | 
				
			
			@ -271,9 +294,6 @@ impl_node_set_callbacks(struct spa_node *node,
 | 
			
		|||
	this->callbacks = callbacks;
 | 
			
		||||
	this->callbacks_data = data;
 | 
			
		||||
 | 
			
		||||
	emit_node_info(this);
 | 
			
		||||
	emit_port_info(this);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -301,13 +321,11 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
 | 
			
		|||
	uint8_t buffer[1024];
 | 
			
		||||
	struct spa_result_node_params result;
 | 
			
		||||
	uint32_t count = 0;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(node != NULL, -EINVAL);
 | 
			
		||||
	spa_return_val_if_fail(num != 0, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = SPA_CONTAINER_OF(node, struct state, node);
 | 
			
		||||
	spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -394,8 +412,7 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
 | 
			
		|||
	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
			
		||||
		goto next;
 | 
			
		||||
 | 
			
		||||
	if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
 | 
			
		||||
		return res;
 | 
			
		||||
	spa_node_emit_result(&this->hooks, seq, 0, &result);
 | 
			
		||||
 | 
			
		||||
	if (++count != num)
 | 
			
		||||
		goto next;
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +467,7 @@ static int port_set_format(struct spa_node *node,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_RATE;
 | 
			
		||||
	this->port_info.rate = this->rate;
 | 
			
		||||
	this->port_info.rate = SPA_FRACTION(1, this->rate);
 | 
			
		||||
	this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
 | 
			
		||||
	if (this->have_format) {
 | 
			
		||||
		this->port_params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
 | 
			
		||||
| 
						 | 
				
			
			@ -459,7 +476,7 @@ static int port_set_format(struct spa_node *node,
 | 
			
		|||
		this->port_params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
 | 
			
		||||
		this->port_params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
 | 
			
		||||
	}
 | 
			
		||||
	emit_port_info(this);
 | 
			
		||||
	emit_port_info(this, false);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -630,6 +647,7 @@ static int impl_node_process(struct spa_node *node)
 | 
			
		|||
 | 
			
		||||
static const struct spa_node impl_node = {
 | 
			
		||||
	SPA_VERSION_NODE,
 | 
			
		||||
	.add_listener = impl_node_add_listener,
 | 
			
		||||
	.set_callbacks = impl_node_set_callbacks,
 | 
			
		||||
	.enum_params = impl_node_enum_params,
 | 
			
		||||
	.set_param = impl_node_set_param,
 | 
			
		||||
| 
						 | 
				
			
			@ -707,12 +725,16 @@ impl_init(const struct spa_handle_factory *factory,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	this->node = impl_node;
 | 
			
		||||
	spa_hook_list_init(&this->hooks);
 | 
			
		||||
 | 
			
		||||
	this->stream = SND_PCM_STREAM_PLAYBACK;
 | 
			
		||||
 | 
			
		||||
	this->info_all = SPA_NODE_CHANGE_MASK_FLAGS |
 | 
			
		||||
			SPA_NODE_CHANGE_MASK_PROPS |
 | 
			
		||||
			SPA_NODE_CHANGE_MASK_PARAMS;
 | 
			
		||||
	this->info = SPA_NODE_INFO_INIT();
 | 
			
		||||
	this->info.max_input_ports = 1;
 | 
			
		||||
	this->info.change_mask = SPA_NODE_CHANGE_MASK_PROPS;
 | 
			
		||||
	this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
 | 
			
		||||
	this->info.flags = SPA_NODE_FLAG_RT;
 | 
			
		||||
	this->params[0] = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ);
 | 
			
		||||
	this->params[1] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE);
 | 
			
		||||
	this->info.params = this->params;
 | 
			
		||||
| 
						 | 
				
			
			@ -720,14 +742,13 @@ impl_init(const struct spa_handle_factory *factory,
 | 
			
		|||
 | 
			
		||||
	reset_props(&this->props);
 | 
			
		||||
 | 
			
		||||
	this->port_info_all = SPA_PORT_CHANGE_MASK_FLAGS |
 | 
			
		||||
				 SPA_PORT_CHANGE_MASK_PARAMS;
 | 
			
		||||
	this->port_info = SPA_PORT_INFO_INIT();
 | 
			
		||||
	this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
 | 
			
		||||
	this->port_info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS |
 | 
			
		||||
			   SPA_PORT_FLAG_LIVE |
 | 
			
		||||
			   SPA_PORT_FLAG_PHYSICAL |
 | 
			
		||||
			   SPA_PORT_FLAG_TERMINAL;
 | 
			
		||||
 | 
			
		||||
	this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
 | 
			
		||||
	this->port_params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
 | 
			
		||||
	this->port_params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
 | 
			
		||||
	this->port_params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,13 +60,11 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
 | 
			
		|||
	struct props *p;
 | 
			
		||||
	struct spa_result_node_params result;
 | 
			
		||||
	uint32_t count = 0;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(node != NULL, -EINVAL);
 | 
			
		||||
	spa_return_val_if_fail(num != 0, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = SPA_CONTAINER_OF(node, struct state, node);
 | 
			
		||||
	spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
 | 
			
		||||
	p = &this->props;
 | 
			
		||||
 | 
			
		||||
	result.id = id;
 | 
			
		||||
| 
						 | 
				
			
			@ -142,8 +140,7 @@ static int impl_node_enum_params(struct spa_node *node, int seq,
 | 
			
		|||
	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
			
		||||
		goto next;
 | 
			
		||||
 | 
			
		||||
	if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
 | 
			
		||||
		return res;
 | 
			
		||||
	spa_node_emit_result(&this->hooks, seq, 0, &result);
 | 
			
		||||
 | 
			
		||||
	if (++count != num)
 | 
			
		||||
		goto next;
 | 
			
		||||
| 
						 | 
				
			
			@ -239,24 +236,50 @@ static const struct spa_dict_item node_info_items[] = {
 | 
			
		|||
	{ "node.driver", "true" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void emit_node_info(struct state *this)
 | 
			
		||||
static void emit_node_info(struct state *this, bool full)
 | 
			
		||||
{
 | 
			
		||||
	if (this->callbacks && this->callbacks->info && this->info.change_mask) {
 | 
			
		||||
	if (full)
 | 
			
		||||
		this->info.change_mask = this->info_all;
 | 
			
		||||
	if (this->info.change_mask) {
 | 
			
		||||
		this->info.props = &SPA_DICT_INIT_ARRAY(node_info_items);
 | 
			
		||||
		this->callbacks->info(this->callbacks_data, &this->info);
 | 
			
		||||
		spa_node_emit_info(&this->hooks, &this->info);
 | 
			
		||||
		this->info.change_mask = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void emit_port_info(struct state *this)
 | 
			
		||||
static void emit_port_info(struct state *this, bool full)
 | 
			
		||||
{
 | 
			
		||||
	if (this->callbacks && this->callbacks->port_info && this->port_info.change_mask) {
 | 
			
		||||
		this->callbacks->port_info(this->callbacks_data,
 | 
			
		||||
	if (full)
 | 
			
		||||
		this->port_info.change_mask = this->port_info_all;
 | 
			
		||||
	if (this->port_info.change_mask) {
 | 
			
		||||
		spa_node_emit_port_info(&this->hooks,
 | 
			
		||||
				SPA_DIRECTION_OUTPUT, 0, &this->port_info);
 | 
			
		||||
		this->port_info.change_mask = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
impl_node_add_listener(struct spa_node *node,
 | 
			
		||||
		struct spa_hook *listener,
 | 
			
		||||
		const struct spa_node_events *events,
 | 
			
		||||
		void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct state *this;
 | 
			
		||||
	struct spa_hook_list save;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(node != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = SPA_CONTAINER_OF(node, struct state, node);
 | 
			
		||||
	spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
 | 
			
		||||
 | 
			
		||||
	emit_node_info(this, true);
 | 
			
		||||
	emit_port_info(this, true);
 | 
			
		||||
 | 
			
		||||
	spa_hook_list_join(&this->hooks, &save);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
impl_node_set_callbacks(struct spa_node *node,
 | 
			
		||||
			const struct spa_node_callbacks *callbacks,
 | 
			
		||||
| 
						 | 
				
			
			@ -271,9 +294,6 @@ impl_node_set_callbacks(struct spa_node *node,
 | 
			
		|||
	this->callbacks = callbacks;
 | 
			
		||||
	this->callbacks_data = data;
 | 
			
		||||
 | 
			
		||||
	emit_node_info(this);
 | 
			
		||||
	emit_port_info(this);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -311,17 +331,14 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
 | 
			
		|||
	uint8_t buffer[1024];
 | 
			
		||||
	struct spa_result_node_params result;
 | 
			
		||||
	uint32_t count = 0;
 | 
			
		||||
	int res;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(node != NULL, -EINVAL);
 | 
			
		||||
	spa_return_val_if_fail(num != 0, -EINVAL);
 | 
			
		||||
 | 
			
		||||
	this = SPA_CONTAINER_OF(node, struct state, node);
 | 
			
		||||
	spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO);
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	result.id = id;
 | 
			
		||||
	result.next = start;
 | 
			
		||||
      next:
 | 
			
		||||
| 
						 | 
				
			
			@ -399,8 +416,7 @@ impl_node_port_enum_params(struct spa_node *node, int seq,
 | 
			
		|||
	if (spa_pod_filter(&b, &result.param, param, filter) < 0)
 | 
			
		||||
		goto next;
 | 
			
		||||
 | 
			
		||||
	if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0)
 | 
			
		||||
		return res;
 | 
			
		||||
	spa_node_emit_result(&this->hooks, seq, 0, &result);
 | 
			
		||||
 | 
			
		||||
	if (++count != num)
 | 
			
		||||
		goto next;
 | 
			
		||||
| 
						 | 
				
			
			@ -454,7 +470,7 @@ static int port_set_format(struct spa_node *node,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_RATE;
 | 
			
		||||
	this->port_info.rate = this->rate;
 | 
			
		||||
	this->port_info.rate = SPA_FRACTION(1, this->rate);
 | 
			
		||||
	this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
 | 
			
		||||
	if (this->have_format) {
 | 
			
		||||
		this->port_params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
 | 
			
		||||
| 
						 | 
				
			
			@ -463,7 +479,7 @@ static int port_set_format(struct spa_node *node,
 | 
			
		|||
		this->port_params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
 | 
			
		||||
		this->port_params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
 | 
			
		||||
	}
 | 
			
		||||
	emit_port_info(this);
 | 
			
		||||
	emit_port_info(this, false);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -647,11 +663,12 @@ static int impl_node_process(struct spa_node *node)
 | 
			
		|||
 | 
			
		||||
static const struct spa_node impl_node = {
 | 
			
		||||
	SPA_VERSION_NODE,
 | 
			
		||||
	.add_listener = impl_node_add_listener,
 | 
			
		||||
	.set_callbacks = impl_node_set_callbacks,
 | 
			
		||||
	.enum_params = impl_node_enum_params,
 | 
			
		||||
	.set_param = impl_node_set_param,
 | 
			
		||||
	.set_io = impl_node_set_io,
 | 
			
		||||
	.send_command = impl_node_send_command,
 | 
			
		||||
	.set_callbacks = impl_node_set_callbacks,
 | 
			
		||||
	.add_port = impl_node_add_port,
 | 
			
		||||
	.remove_port = impl_node_remove_port,
 | 
			
		||||
	.port_enum_params = impl_node_port_enum_params,
 | 
			
		||||
| 
						 | 
				
			
			@ -728,24 +745,27 @@ impl_init(const struct spa_handle_factory *factory,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	this->node = impl_node;
 | 
			
		||||
	spa_hook_list_init(&this->hooks);
 | 
			
		||||
	this->stream = SND_PCM_STREAM_CAPTURE;
 | 
			
		||||
 | 
			
		||||
	this->info_all = SPA_NODE_CHANGE_MASK_FLAGS |
 | 
			
		||||
			SPA_NODE_CHANGE_MASK_PROPS |
 | 
			
		||||
			SPA_NODE_CHANGE_MASK_PARAMS;
 | 
			
		||||
	this->info.max_output_ports = 1;
 | 
			
		||||
	this->info.change_mask = SPA_NODE_CHANGE_MASK_PROPS;
 | 
			
		||||
	this->info.change_mask |= SPA_NODE_CHANGE_MASK_PARAMS;
 | 
			
		||||
	this->info.flags = SPA_NODE_FLAG_RT;
 | 
			
		||||
	this->params[0] = SPA_PARAM_INFO(SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ);
 | 
			
		||||
	this->params[1] = SPA_PARAM_INFO(SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE);
 | 
			
		||||
	this->info.params = this->params;
 | 
			
		||||
	this->info.n_params = 2;
 | 
			
		||||
	reset_props(&this->props);
 | 
			
		||||
 | 
			
		||||
	this->port_info_all = SPA_PORT_CHANGE_MASK_FLAGS |
 | 
			
		||||
			SPA_PORT_CHANGE_MASK_PARAMS;
 | 
			
		||||
	this->port_info = SPA_PORT_INFO_INIT();
 | 
			
		||||
	this->port_info.change_mask = SPA_PORT_CHANGE_MASK_FLAGS;
 | 
			
		||||
	this->port_info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS |
 | 
			
		||||
			   SPA_PORT_FLAG_LIVE |
 | 
			
		||||
			   SPA_PORT_FLAG_PHYSICAL |
 | 
			
		||||
			   SPA_PORT_FLAG_TERMINAL;
 | 
			
		||||
	this->port_info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
 | 
			
		||||
	this->port_params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
 | 
			
		||||
	this->port_params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
 | 
			
		||||
	this->port_params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -359,15 +359,13 @@ spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num,
 | 
			
		|||
	if ((res = spa_pod_filter(&b, &result.param, fmt, filter)) < 0)
 | 
			
		||||
		goto next;
 | 
			
		||||
 | 
			
		||||
	if ((res = state->callbacks->result(state->callbacks_data, seq, 0, &result)) != 0)
 | 
			
		||||
		goto exit;
 | 
			
		||||
	spa_node_emit_result(&state->hooks, seq, 0, &result);
 | 
			
		||||
 | 
			
		||||
	if (++count != num)
 | 
			
		||||
		goto next;
 | 
			
		||||
 | 
			
		||||
      enum_end:
 | 
			
		||||
	res = 0;
 | 
			
		||||
      exit:
 | 
			
		||||
	if (!opened)
 | 
			
		||||
		spa_alsa_close(state);
 | 
			
		||||
	return res;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,9 +87,11 @@ struct state {
 | 
			
		|||
	snd_pcm_stream_t stream;
 | 
			
		||||
	snd_output_t *output;
 | 
			
		||||
 | 
			
		||||
	struct spa_hook_list hooks;
 | 
			
		||||
	const struct spa_node_callbacks *callbacks;
 | 
			
		||||
	void *callbacks_data;
 | 
			
		||||
 | 
			
		||||
	uint64_t info_all;
 | 
			
		||||
	struct spa_node_info info;
 | 
			
		||||
	struct spa_param_info params[8];
 | 
			
		||||
	struct props props;
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +110,7 @@ struct state {
 | 
			
		|||
	int channels;
 | 
			
		||||
	size_t frame_size;
 | 
			
		||||
 | 
			
		||||
	uint64_t port_info_all;
 | 
			
		||||
	struct spa_port_info port_info;
 | 
			
		||||
	struct spa_param_info port_params[8];
 | 
			
		||||
	struct spa_io_buffers *io;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue