Skip to content
Snippets Groups Projects
Commit ff2420b7 authored by Julian Bouzas's avatar Julian Bouzas
Browse files

modules: add support for multiple channels linking

parent be6256fb
No related branches found
No related tags found
No related merge requests found
......@@ -48,31 +48,57 @@ simple_endpoint_link_create (WpEndpointLink * epl, GVariant * src_data,
{
WpPipewireSimpleEndpointLink *self = WP_PIPEWIRE_SIMPLE_ENDPOINT_LINK(epl);
struct pw_properties *props;
guint32 output_node_id, input_node_id, output_port_id, input_port_id;
guint32 output_node_id, input_node_id;
GVariant *src_ports, *sink_ports;
GVariantIter *out_iter, *in_iter;
guint64 out_ptr, in_ptr;
/* Get the node ids and port ids */
if (!g_variant_lookup (src_data, "node-id", "u", &output_node_id))
return FALSE;
if (!g_variant_lookup (src_data, "node-port-id", "u", &output_port_id))
src_ports = g_variant_lookup_value (src_data, "ports", G_VARIANT_TYPE_ARRAY);
if (!src_ports)
return FALSE;
if (!g_variant_lookup (sink_data, "node-id", "u", &input_node_id))
return FALSE;
if (!g_variant_lookup (sink_data, "node-port-id", "u", &input_port_id))
sink_ports = g_variant_lookup_value (sink_data, "ports", G_VARIANT_TYPE_ARRAY);
if (!sink_ports)
return FALSE;
/* Create the properties */
props = pw_properties_new(NULL, NULL);
pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", output_node_id);
pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", output_port_id);
pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", input_node_id);
pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", input_port_id);
/* Create the link */
pw_core_proxy_create_object(self->core_proxy, "link-factory",
PW_TYPE_INTERFACE_Link, PW_VERSION_LINK, &props->dict, 0);
/* Clean up */
pw_properties_free(props);
/* Link all the output ports with the input ports */
g_variant_get (src_ports, "at", &out_iter);
while (g_variant_iter_loop (out_iter, "t", &out_ptr)) {
WpProxyPort *out_p = (gpointer)out_ptr;
enum pw_direction out_direction = wp_proxy_port_get_info(out_p)->direction;
guint out_id = wp_proxy_get_global_id(WP_PROXY(out_p));
if (out_direction == PW_DIRECTION_INPUT)
continue;
g_variant_get (sink_ports, "at", &in_iter);
while (g_variant_iter_loop (in_iter, "t", &in_ptr)) {
WpProxyPort *in_p = (gpointer)in_ptr;
enum pw_direction in_direction = wp_proxy_port_get_info(in_p)->direction;
guint in_id = wp_proxy_get_global_id(WP_PROXY(in_p));
if (in_direction == PW_DIRECTION_OUTPUT)
continue;
/* Create the properties */
props = pw_properties_new(NULL, NULL);
pw_properties_setf(props, PW_LINK_OUTPUT_NODE_ID, "%d", output_node_id);
pw_properties_setf(props, PW_LINK_OUTPUT_PORT_ID, "%d", out_id);
pw_properties_setf(props, PW_LINK_INPUT_NODE_ID, "%d", input_node_id);
pw_properties_setf(props, PW_LINK_INPUT_PORT_ID, "%d", in_id);
/* Create the link */
pw_core_proxy_create_object(self->core_proxy, "link-factory",
PW_TYPE_INTERFACE_Link, PW_VERSION_LINK, &props->dict, 0);
/* Clean up */
pw_properties_free(props);
}
g_variant_iter_free (in_iter);
}
g_variant_iter_free (out_iter);
return TRUE;
}
......
......@@ -363,19 +363,31 @@ simple_endpoint_get_property (GObject * object, guint property_id,
}
}
static void
proxies_port_foreach_func(gpointer data, gpointer user_data)
{
GVariantBuilder *b = user_data;
g_variant_builder_add (b, "t", data);
}
static gboolean
simple_endpoint_prepare_link (WpEndpoint * ep, guint32 stream_id,
WpEndpointLink * link, GVariant ** properties, GError ** error)
{
WpPipewireSimpleEndpoint *self = WP_PIPEWIRE_SIMPLE_ENDPOINT (ep);
GVariantBuilder b;
GVariantBuilder b, *b_ports;
GVariant *v_ports;
/* Create a variant array with all the ports */
b_ports = g_variant_builder_new (G_VARIANT_TYPE ("at"));
g_ptr_array_foreach(self->proxies_port, proxies_port_foreach_func, b_ports);
v_ports = g_variant_builder_end (b_ports);
/* Set the properties */
g_variant_builder_init (&b, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add (&b, "{sv}", "node-id",
g_variant_new_uint32 (self->global_id));
g_variant_builder_add (&b, "{sv}", "node-port-id",
g_variant_new_uint32 (-1));
g_variant_builder_add (&b, "{sv}", "ports", v_ports);
*properties = g_variant_builder_end (&b);
return TRUE;
......
......@@ -53,7 +53,6 @@ struct _WpPwAudioSoftdspEndpoint
gboolean master_mute;
/* DSP */
uint32_t dsp_port_id;
struct spa_hook dsp_listener;
struct pw_proxy *link_proxy;
};
......@@ -80,24 +79,37 @@ G_DEFINE_TYPE_WITH_CODE (WpPwAudioSoftdspEndpoint, endpoint, WP_TYPE_ENDPOINT,
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
wp_endpoint_async_initable_init))
static void
proxies_dsp_port_foreach_func(gpointer data, gpointer user_data)
{
GVariantBuilder *b = user_data;
g_variant_builder_add (b, "t", data);
}
static gboolean
endpoint_prepare_link (WpEndpoint * ep, guint32 stream_id,
WpEndpointLink * link, GVariant ** properties, GError ** error)
{
WpPwAudioSoftdspEndpoint *self = WP_PW_AUDIO_SOFTDSP_ENDPOINT (ep);
const struct pw_node_info *dsp_info = NULL;
GVariantBuilder b;
GVariantBuilder b, *b_ports;
GVariant *v_ports;
/* Get the dsp info */
dsp_info = wp_proxy_node_get_info(self->proxy_dsp);
g_return_val_if_fail (dsp_info, FALSE);
/* Create a variant array with all the ports */
b_ports = g_variant_builder_new (G_VARIANT_TYPE ("at"));
g_ptr_array_foreach(self->proxies_dsp_port, proxies_dsp_port_foreach_func,
b_ports);
v_ports = g_variant_builder_end (b_ports);
/* Set the properties */
g_variant_builder_init (&b, G_VARIANT_TYPE_VARDICT);
g_variant_builder_add (&b, "{sv}", "node-id",
g_variant_new_uint32 (dsp_info->id));
g_variant_builder_add (&b, "{sv}", "node-port-id",
g_variant_new_uint32 (self->dsp_port_id));
g_variant_builder_add (&b, "{sv}", "ports", v_ports);
*properties = g_variant_builder_end (&b);
return TRUE;
......@@ -436,36 +448,13 @@ static void
handle_dsp_port(WpPwAudioSoftdspEndpoint *self, guint id, guint parent_id,
const struct spa_dict *props)
{
const char *direction_prop = NULL;
struct pw_port_proxy *port_proxy = NULL;
enum pw_direction direction;
/* Create the proxy dsp port async */
port_proxy = wp_remote_pipewire_proxy_bind (self->remote_pipewire, id,
PW_TYPE_INTERFACE_Port);
g_return_if_fail(port_proxy);
wp_proxy_port_new(id, port_proxy, on_proxy_dsp_port_created, self);
/* Make sure the port has porperties */
g_return_if_fail(props);
/* TODO: For now we only handle 1 DSP port */
if (self->dsp_port_id != 0)
return;
/* Get the direction property */
direction_prop = spa_dict_lookup(props, "port.direction");
if (!direction_prop)
return;
direction =
!strcmp(direction_prop, "out") ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT;
/* Only handle ports with the opposite direction of the endpoint */
if (self->direction == direction)
return;
/* Set the dsp port id */
self->dsp_port_id = id;
}
static void
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment