diff --git a/lib/wp/endpoint.c b/lib/wp/endpoint.c index 2ce211a4dce7c85eee7497cd343e0684530ca850..a2f86350a739d1cbc30495b68b8cd996fc79025d 100644 --- a/lib/wp/endpoint.c +++ b/lib/wp/endpoint.c @@ -737,39 +737,199 @@ wp_endpoint_get_links (WpEndpoint * self) typedef struct _WpEndpointLinkPrivate WpEndpointLinkPrivate; struct _WpEndpointLinkPrivate { - WpEndpoint *src; + /* The task to signal the endpoint link is initialized */ + GTask *init_task; + + GWeakRef src; guint32 src_stream; - WpEndpoint *sink; + GWeakRef sink; guint32 sink_stream; }; -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (WpEndpointLink, wp_endpoint_link, G_TYPE_OBJECT) +enum { + LINKPROP_0, + LINKPROP_SRC, + LINKPROP_SRC_STREAM, + LINKPROP_SINK, + LINKPROP_SINK_STREAM, +}; + +static void wp_endpoint_link_async_initable_init (gpointer iface, + gpointer iface_data); + +G_DEFINE_ABSTRACT_TYPE_WITH_CODE (WpEndpointLink, wp_endpoint_link, G_TYPE_OBJECT, + G_ADD_PRIVATE (WpEndpointLink) + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, + wp_endpoint_link_async_initable_init)) static void -wp_endpoint_link_init (WpEndpointLink * self) +endpoint_link_finalize (GObject * object) { + WpEndpointLinkPrivate *priv = + wp_endpoint_link_get_instance_private (WP_ENDPOINT_LINK (object)); + + /* Destroy the init task */ + g_clear_object(&priv->init_task); + + /* Clear the endpoint weak reaferences */ + g_weak_ref_clear(&priv->src); + g_weak_ref_clear(&priv->sink); } static void -wp_endpoint_link_class_init (WpEndpointLinkClass * klass) +endpoint_link_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) { + WpEndpointLinkPrivate *priv = + wp_endpoint_link_get_instance_private (WP_ENDPOINT_LINK (object)); + + switch (property_id) { + case LINKPROP_SRC: + g_weak_ref_set (&priv->src, g_value_get_object (value)); + break; + case LINKPROP_SRC_STREAM: + priv->src_stream = g_value_get_uint(value); + break; + case LINKPROP_SINK: + g_weak_ref_set (&priv->sink, g_value_get_object (value)); + break; + case LINKPROP_SINK_STREAM: + priv->sink_stream = g_value_get_uint(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } } -void -wp_endpoint_link_set_endpoints (WpEndpointLink * self, WpEndpoint * src, - guint32 src_stream, WpEndpoint * sink, guint32 sink_stream) +static void +endpoint_link_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) { - WpEndpointLinkPrivate *priv; + WpEndpointLinkPrivate *priv = + wp_endpoint_link_get_instance_private (WP_ENDPOINT_LINK (object)); - g_return_if_fail (WP_IS_ENDPOINT_LINK (self)); - g_return_if_fail (WP_IS_ENDPOINT (src)); - g_return_if_fail (WP_IS_ENDPOINT (sink)); + switch (property_id) { + case LINKPROP_SRC: + g_value_take_object (value, g_weak_ref_get (&priv->src)); + break; + case LINKPROP_SRC_STREAM: + g_value_set_uint (value, priv->src_stream); + break; + case LINKPROP_SINK: + g_value_take_object (value, g_weak_ref_get (&priv->sink)); + break; + case LINKPROP_SINK_STREAM: + g_value_set_uint (value, priv->sink_stream); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} - priv = wp_endpoint_link_get_instance_private (self); - priv->src = src; - priv->src_stream = src_stream; - priv->sink = sink; - priv->sink_stream = sink_stream; +static void +wp_endpoint_link_init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data) +{ + WpEndpointLink *link = WP_ENDPOINT_LINK(initable); + WpEndpointLinkPrivate *priv = + wp_endpoint_link_get_instance_private (WP_ENDPOINT_LINK (initable)); + g_autoptr (WpEndpoint) src = g_weak_ref_get (&priv->src); + g_autoptr (WpEndpoint) sink = g_weak_ref_get (&priv->sink); + g_autoptr (GError) error = NULL; + g_autoptr (GVariant) src_props = NULL; + g_autoptr (GVariant) sink_props = NULL; + WpEndpointPrivate *endpoint_priv; + + /* Create the async task */ + priv->init_task = g_task_new (initable, cancellable, callback, data); + + /* Prepare the endpoints */ + if (!WP_ENDPOINT_GET_CLASS (src)->prepare_link (src, priv->src_stream, link, + &src_props, &error)) { + g_task_return_error (priv->init_task, error); + g_clear_object(&priv->init_task); + return; + } + if (!WP_ENDPOINT_GET_CLASS (sink)->prepare_link (sink, priv->sink_stream, + link, &sink_props, &error)) { + g_task_return_error (priv->init_task, error); + g_clear_object(&priv->init_task); + return; + } + + /* Create the link */ + g_return_if_fail (WP_ENDPOINT_LINK_GET_CLASS (link)->create); + if (!WP_ENDPOINT_LINK_GET_CLASS (link)->create (link, src_props, + sink_props, &error)) { + g_task_return_error (priv->init_task, error); + g_clear_object(&priv->init_task); + return; + } + + /* Register the link on the endpoints */ + endpoint_priv = wp_endpoint_get_instance_private (src); + g_ptr_array_add (endpoint_priv->links, g_object_ref (link)); + endpoint_priv = wp_endpoint_get_instance_private (sink); + g_ptr_array_add (endpoint_priv->links, g_object_ref (link)); + + /* Finish the creation of the endpoint */ + g_task_return_boolean (priv->init_task, TRUE); + g_clear_object(&priv->init_task); +} + +static gboolean +wp_endpoint_link_init_finish (GAsyncInitable *initable, GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (result, initable), FALSE); + + return g_task_propagate_boolean (G_TASK (result), error); +} + +static void +wp_endpoint_link_async_initable_init (gpointer iface, gpointer iface_data) +{ + GAsyncInitableIface *ai_iface = iface; + + ai_iface->init_async = wp_endpoint_link_init_async; + ai_iface->init_finish = wp_endpoint_link_init_finish; +} + +static void +wp_endpoint_link_init (WpEndpointLink * self) +{ + WpEndpointLinkPrivate *priv = wp_endpoint_link_get_instance_private (self); + + /* Init the endpoint weak references */ + g_weak_ref_init (&priv->src, NULL); + g_weak_ref_init (&priv->sink, NULL); +} + +static void +wp_endpoint_link_class_init (WpEndpointLinkClass * klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + + object_class->finalize = endpoint_link_finalize; + object_class->set_property = endpoint_link_set_property; + object_class->get_property = endpoint_link_get_property; + + g_object_class_install_property (object_class, LINKPROP_SRC, + g_param_spec_object ("src", "src", "The src endpoint", WP_TYPE_ENDPOINT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, LINKPROP_SRC_STREAM, + g_param_spec_uint ("src-stream", "src-stream", "The src stream", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, LINKPROP_SINK, + g_param_spec_object ("sink", "sink", "The sink endpoint", WP_TYPE_ENDPOINT, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, LINKPROP_SINK_STREAM, + g_param_spec_uint ("sink-stream", "sink-stream", "The sink stream", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } WpEndpoint * @@ -780,7 +940,7 @@ wp_endpoint_link_get_source_endpoint (WpEndpointLink * self) g_return_val_if_fail (WP_IS_ENDPOINT_LINK (self), NULL); priv = wp_endpoint_link_get_instance_private (self); - return priv->src; + return g_weak_ref_get (&priv->src); } guint32 @@ -802,7 +962,7 @@ wp_endpoint_link_get_sink_endpoint (WpEndpointLink * self) g_return_val_if_fail (WP_IS_ENDPOINT_LINK (self), NULL); priv = wp_endpoint_link_get_instance_private (self); - return priv->sink; + return g_weak_ref_get (&priv->sink); } guint32 @@ -816,19 +976,19 @@ wp_endpoint_link_get_sink_stream (WpEndpointLink * self) return priv->sink_stream; } -WpEndpointLink * wp_endpoint_link_new (WpCore * core, WpEndpoint * src, - guint32 src_stream, WpEndpoint * sink, guint32 sink_stream, GError ** error) +void +wp_endpoint_link_new (WpCore * core, WpEndpoint * src, guint32 src_stream, + WpEndpoint * sink, guint32 sink_stream, GAsyncReadyCallback ready, + gpointer data) { - g_autoptr (WpEndpointLink) link = NULL; - g_autoptr (GVariant) src_props = NULL; - g_autoptr (GVariant) sink_props = NULL; const gchar *src_factory = NULL, *sink_factory = NULL; - WpEndpointPrivate *endpoint_priv; + GVariantBuilder b; + g_autoptr (GVariant) link_props = NULL; - g_return_val_if_fail (WP_IS_ENDPOINT (src), NULL); - g_return_val_if_fail (WP_IS_ENDPOINT (sink), NULL); - g_return_val_if_fail (WP_ENDPOINT_GET_CLASS (src)->prepare_link, NULL); - g_return_val_if_fail (WP_ENDPOINT_GET_CLASS (sink)->prepare_link, NULL); + g_return_if_fail (WP_IS_ENDPOINT (src)); + g_return_if_fail (WP_IS_ENDPOINT (sink)); + g_return_if_fail (WP_ENDPOINT_GET_CLASS (src)->prepare_link); + g_return_if_fail (WP_ENDPOINT_GET_CLASS (sink)->prepare_link); /* find the factory */ @@ -839,52 +999,38 @@ WpEndpointLink * wp_endpoint_link_new (WpCore * core, WpEndpoint * src, if (src_factory || sink_factory) { if (src_factory && sink_factory && strcmp (src_factory, sink_factory) != 0) { - g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT, - "It is not possible to link endpoints that both specify different " - "custom link factories"); - return NULL; + g_critical ("It is not possible to link endpoints that both specify" + "different custom link factories"); + return; } else if (sink_factory) src_factory = sink_factory; } else { src_factory = "pipewire-simple-endpoint-link"; } - /* create link object */ - - link = wp_factory_make (core, src_factory, WP_TYPE_ENDPOINT_LINK, NULL); - if (!link) { - g_set_error (error, WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, - "Failed to create link object from factory %s", src_factory); - return NULL; - } - g_return_val_if_fail (WP_ENDPOINT_LINK_GET_CLASS (link)->create, NULL); - - /* prepare the link */ - - wp_endpoint_link_set_endpoints (link, src, src_stream, sink, sink_stream); - - if (!WP_ENDPOINT_GET_CLASS (src)->prepare_link (src, src_stream, link, - &src_props, error)) - return NULL; - if (!WP_ENDPOINT_GET_CLASS (sink)->prepare_link (sink, sink_stream, link, - &sink_props, error)) - return NULL; - - /* create the link */ - - if (!WP_ENDPOINT_LINK_GET_CLASS (link)->create (link, src_props, sink_props, - error)) - return NULL; - - /* register the link on the endpoints */ - - endpoint_priv = wp_endpoint_get_instance_private (src); - g_ptr_array_add (endpoint_priv->links, g_object_ref (link)); - - endpoint_priv = wp_endpoint_get_instance_private (sink); - g_ptr_array_add (endpoint_priv->links, g_object_ref (link)); + /* Build the properties */ + g_variant_builder_init (&b, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&b, "{sv}", "src", + g_variant_new_uint64 ((guint64)src)); + g_variant_builder_add (&b, "{sv}", "src-stream", + g_variant_new_uint32 (src_stream)); + g_variant_builder_add (&b, "{sv}", "sink", + g_variant_new_uint64 ((guint64)sink)); + g_variant_builder_add (&b, "{sv}", "sink-stream", + g_variant_new_uint32 (sink_stream)); + link_props = g_variant_builder_end (&b); + + /* Create the link object async */ + wp_factory_make (core, src_factory, WP_TYPE_ENDPOINT_LINK, link_props, ready, + data); +} - return link; +WpEndpointLink * +wp_endpoint_link_new_finish (GObject *initable, GAsyncResult *res, + GError **error) +{ + GAsyncInitable *ai = G_ASYNC_INITABLE(initable); + return WP_ENDPOINT_LINK(g_async_initable_new_finish(ai, res, error)); } void @@ -892,21 +1038,29 @@ wp_endpoint_link_destroy (WpEndpointLink * self) { WpEndpointLinkPrivate *priv; WpEndpointPrivate *endpoint_priv; + g_autoptr (WpEndpoint) src = NULL; + g_autoptr (WpEndpoint) sink = NULL; g_return_if_fail (WP_IS_ENDPOINT_LINK (self)); g_return_if_fail (WP_ENDPOINT_LINK_GET_CLASS (self)->destroy); priv = wp_endpoint_link_get_instance_private (self); + src = g_weak_ref_get (&priv->src); + sink = g_weak_ref_get (&priv->sink); - WP_ENDPOINT_LINK_GET_CLASS (self)->destroy (self); - if (WP_ENDPOINT_GET_CLASS (priv->src)->release_link) - WP_ENDPOINT_GET_CLASS (priv->src)->release_link (priv->src, self); - if (WP_ENDPOINT_GET_CLASS (priv->sink)->release_link) - WP_ENDPOINT_GET_CLASS (priv->sink)->release_link (priv->sink, self); + if (src && WP_ENDPOINT_GET_CLASS (src)->release_link) + WP_ENDPOINT_GET_CLASS (src)->release_link (src, self); + if (sink && WP_ENDPOINT_GET_CLASS (sink)->release_link) + WP_ENDPOINT_GET_CLASS (sink)->release_link (sink, self); - endpoint_priv = wp_endpoint_get_instance_private (priv->src); - g_ptr_array_remove_fast (endpoint_priv->links, self); + if (src) { + endpoint_priv = wp_endpoint_get_instance_private (src); + g_ptr_array_remove_fast (endpoint_priv->links, self); + } + if (sink) { + endpoint_priv = wp_endpoint_get_instance_private (sink); + g_ptr_array_remove_fast (endpoint_priv->links, self); + } - endpoint_priv = wp_endpoint_get_instance_private (priv->sink); - g_ptr_array_remove_fast (endpoint_priv->links, self); + WP_ENDPOINT_LINK_GET_CLASS (self)->destroy (self); } diff --git a/lib/wp/endpoint.h b/lib/wp/endpoint.h index 4c5c4b5ad9cd717b82dfa7add8b8babb3bd4f69c..a6cdfa8185d6b7d36d337d6b2cb37907f9395f58 100644 --- a/lib/wp/endpoint.h +++ b/lib/wp/endpoint.h @@ -78,17 +78,16 @@ struct _WpEndpointLinkClass void (*destroy) (WpEndpointLink * self); }; -void wp_endpoint_link_set_endpoints (WpEndpointLink * self, WpEndpoint * src, - guint32 src_stream, WpEndpoint * sink, guint32 sink_stream); - WpEndpoint * wp_endpoint_link_get_source_endpoint (WpEndpointLink * self); guint32 wp_endpoint_link_get_source_stream (WpEndpointLink * self); WpEndpoint * wp_endpoint_link_get_sink_endpoint (WpEndpointLink * self); guint32 wp_endpoint_link_get_sink_stream (WpEndpointLink * self); -WpEndpointLink * wp_endpoint_link_new (WpCore * core, WpEndpoint * src, +void wp_endpoint_link_new (WpCore * core, WpEndpoint * src, guint32 src_stream, WpEndpoint * sink, guint32 sink_stream, - GError ** error); + GAsyncReadyCallback ready, gpointer data); +WpEndpointLink * wp_endpoint_link_new_finish (GObject *initable, + GAsyncResult *res, GError **error); void wp_endpoint_link_destroy (WpEndpointLink * self); G_END_DECLS diff --git a/modules/module-pipewire.c b/modules/module-pipewire.c index 9394b1e6e30b27fbb4287b252ae21857ca4e867a..5df312395704471b13ca9b7ec94338febd237d81 100644 --- a/modules/module-pipewire.c +++ b/modules/module-pipewire.c @@ -19,8 +19,8 @@ void remote_endpoint_init (WpCore * core, struct pw_core * pw_core, struct pw_remote * remote); void simple_endpoint_factory (WpFactory * factory, GType type, GVariant * properties, GAsyncReadyCallback ready, gpointer user_data); -gpointer simple_endpoint_link_factory (WpFactory * factory, GType type, - GVariant * properties); +void simple_endpoint_link_factory (WpFactory * factory, GType type, + GVariant * properties, GAsyncReadyCallback ready, gpointer user_data); struct module_data { @@ -89,7 +89,7 @@ on_node_added (WpRemotePipewire *rp, guint id, guint parent_id, gconstpointer p, endpoint_props = g_variant_builder_end (&b); /* Create the endpoint async */ - wp_factory_make_async (core, "pipewire-simple-endpoint", WP_TYPE_ENDPOINT, + wp_factory_make (core, "pipewire-simple-endpoint", WP_TYPE_ENDPOINT, endpoint_props, on_endpoint_created, data); } @@ -162,7 +162,7 @@ wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) remote_endpoint_init (core, pw_core, pw_remote); /* Register simple-endpoint and simple-endpoint-link */ - wp_factory_new_async (core, "pipewire-simple-endpoint", + wp_factory_new (core, "pipewire-simple-endpoint", simple_endpoint_factory); wp_factory_new (core, "pipewire-simple-endpoint-link", simple_endpoint_link_factory); diff --git a/modules/module-pipewire/simple-endpoint-link.c b/modules/module-pipewire/simple-endpoint-link.c index a7e8edc71090c2cfa32fadd1d7a9c6c9356459b0..a0dc2b8db175d048e25cbe4eb237e122d7290fd9 100644 --- a/modules/module-pipewire/simple-endpoint-link.c +++ b/modules/module-pipewire/simple-endpoint-link.c @@ -27,8 +27,13 @@ struct _WpPipewireSimpleEndpointLink { WpEndpointLink parent; - /* The core proxy */ - struct pw_core_proxy *core_proxy; + /* The wireplumber core */ + GWeakRef core; +}; + +enum { + PROP_0, + PROP_CORE, }; G_DECLARE_FINAL_TYPE (WpPipewireSimpleEndpointLink, @@ -40,6 +45,51 @@ G_DEFINE_TYPE (WpPipewireSimpleEndpointLink, static void simple_endpoint_link_init (WpPipewireSimpleEndpointLink * self) { + /* Init the core weak reference */ + g_weak_ref_init (&self->core, NULL); +} + +static void +simple_endpoint_link_finalize (GObject * object) +{ + WpPipewireSimpleEndpointLink *self = WP_PIPEWIRE_SIMPLE_ENDPOINT_LINK(object); + + /* Clear the core weak reference */ + g_weak_ref_clear (&self->core); +} + +static void +simple_endpoint_link_set_property (GObject * object, guint property_id, + const GValue * value, GParamSpec * pspec) +{ + WpPipewireSimpleEndpointLink *self = + WP_PIPEWIRE_SIMPLE_ENDPOINT_LINK (object); + + switch (property_id) { + case PROP_CORE: + g_weak_ref_set (&self->core, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +simple_endpoint_link_get_property (GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + WpPipewireSimpleEndpointLink *self = + WP_PIPEWIRE_SIMPLE_ENDPOINT_LINK (object); + + switch (property_id) { + case PROP_CORE: + g_value_take_object (value, g_weak_ref_get (&self->core)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } } static gboolean @@ -47,12 +97,18 @@ simple_endpoint_link_create (WpEndpointLink * epl, GVariant * src_data, GVariant * sink_data, GError ** error) { WpPipewireSimpleEndpointLink *self = WP_PIPEWIRE_SIMPLE_ENDPOINT_LINK(epl); + g_autoptr (WpCore) core = g_weak_ref_get (&self->core); + WpRemotePipewire *remote_pipewire; struct pw_properties *props; guint32 output_node_id, input_node_id; GVariant *src_ports, *sink_ports; GVariantIter *out_iter, *in_iter; guint64 out_ptr, in_ptr; + /* Get the remote pipewire */ + remote_pipewire = wp_core_get_global (core, WP_GLOBAL_REMOTE_PIPEWIRE); + g_return_val_if_fail (remote_pipewire, FALSE); + /* Get the node ids and port ids */ if (!g_variant_lookup (src_data, "node-id", "u", &output_node_id)) return FALSE; @@ -90,8 +146,8 @@ simple_endpoint_link_create (WpEndpointLink * epl, GVariant * src_data, 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); + wp_remote_pipewire_create_object(remote_pipewire, "link-factory", + PW_TYPE_INTERFACE_Link, &props->dict); /* Clean up */ pw_properties_free(props); @@ -112,49 +168,54 @@ simple_endpoint_link_destroy (WpEndpointLink * self) static void simple_endpoint_link_class_init (WpPipewireSimpleEndpointLinkClass * klass) { + GObjectClass *object_class = (GObjectClass *) klass; WpEndpointLinkClass *link_class = (WpEndpointLinkClass *) klass; + object_class->finalize = simple_endpoint_link_finalize; + object_class->set_property = simple_endpoint_link_set_property; + object_class->get_property = simple_endpoint_link_get_property; + link_class->create = simple_endpoint_link_create; link_class->destroy = simple_endpoint_link_destroy; + + g_object_class_install_property (object_class, PROP_CORE, + g_param_spec_object ("core", "core", + "The wireplumber core object this links belongs to", WP_TYPE_CORE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } -gpointer +void simple_endpoint_link_factory (WpFactory * factory, GType type, - GVariant * properties) + GVariant * properties, GAsyncReadyCallback ready, gpointer data) { - WpCore *wp_core = NULL; - WpRemote *remote; - struct pw_remote *pw_remote; + g_autoptr(WpCore) core = NULL; + guint64 src, sink; + guint src_stream, sink_stream; /* Make sure the type is an endpoint link */ - if (type != WP_TYPE_ENDPOINT_LINK) - return NULL; - - /* Get the WirePlumber core */ - wp_core = wp_factory_get_core(factory); - if (!wp_core) { - g_warning("failed to get wireplumbe core. Skipping..."); - return NULL; - } - - /* Get the remote */ - remote = wp_core_get_global(wp_core, WP_GLOBAL_REMOTE_PIPEWIRE); - if (!remote) { - g_warning("failed to get core remote. Skipping..."); - return NULL; - } + g_return_if_fail (type == WP_TYPE_ENDPOINT_LINK); + + /* Get the Core */ + core = wp_factory_get_core (factory); + g_return_if_fail (core); + + /* Get the properties */ + if (!g_variant_lookup (properties, "src", "t", &src)) + return; + if (!g_variant_lookup (properties, "src-stream", "u", &src_stream)) + return; + if (!g_variant_lookup (properties, "sink", "t", &sink)) + return; + if (!g_variant_lookup (properties, "sink-stream", "u", &sink_stream)) + return; /* Create the endpoint link */ - WpPipewireSimpleEndpointLink *epl = g_object_new ( - simple_endpoint_link_get_type (), NULL); - - /* Set the core proxy */ - g_object_get (remote, "pw-remote", &pw_remote, NULL); - epl->core_proxy = pw_remote_get_core_proxy(pw_remote); - if (!epl->core_proxy) { - g_warning("failed to get core proxy. Skipping..."); - return NULL; - } - - return epl; + g_async_initable_new_async ( + simple_endpoint_link_get_type (), G_PRIORITY_DEFAULT, NULL, ready, data, + "src", (gpointer)src, + "src-stream", src_stream, + "sink", (gpointer)sink, + "sink-stream", sink_stream, + "core", core, + NULL); } diff --git a/modules/module-pw-alsa-udev.c b/modules/module-pw-alsa-udev.c index 74c34979e6e326224e771735aab63926fec4d60d..a353cad4636d2ce6d5e971748d93be3a11426647 100644 --- a/modules/module-pw-alsa-udev.c +++ b/modules/module-pw-alsa-udev.c @@ -76,7 +76,7 @@ on_node_added(WpRemotePipewire *rp, guint id, guint parent_id, gconstpointer p, endpoint_props = g_variant_builder_end (&b); /* Create the endpoint async */ - wp_factory_make_async (core, "pw-audio-softdsp-endpoint", WP_TYPE_ENDPOINT, + wp_factory_make (core, "pw-audio-softdsp-endpoint", WP_TYPE_ENDPOINT, endpoint_props, on_endpoint_created, impl); } diff --git a/modules/module-pw-audio-softdsp-endpoint.c b/modules/module-pw-audio-softdsp-endpoint.c index dd2d5bc7a6c0f2150b9d5d1c047a5f5c96894e1b..49a5c6c0d066cbacb927262103136c133926d8f8 100644 --- a/modules/module-pw-audio-softdsp-endpoint.c +++ b/modules/module-pw-audio-softdsp-endpoint.c @@ -727,5 +727,5 @@ void wireplumber__module_init (WpModule * module, WpCore * core, GVariant * args) { /* Register the softdsp endpoint */ - wp_factory_new_async (core, "pw-audio-softdsp-endpoint", endpoint_factory); + wp_factory_new (core, "pw-audio-softdsp-endpoint", endpoint_factory); } diff --git a/modules/module-simple-policy.c b/modules/module-simple-policy.c index d47818eab699f0fd2f5e7ce2ef7bcc396041fb25..161586f61294e4144ced30bb335dd6a26c14bcc7 100644 --- a/modules/module-simple-policy.c +++ b/modules/module-simple-policy.c @@ -225,6 +225,29 @@ simple_policy_endpoint_removed (WpPolicy *policy, WpEndpoint *ep) g_object_ref (self), g_object_unref); } +static void +on_endpoint_link_created(GObject *initable, GAsyncResult *res, gpointer d) +{ + g_autoptr (WpEndpointLink) link = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (WpEndpoint) src_ep = NULL; + g_autoptr (WpEndpoint) sink_ep = NULL; + + /* Get the link */ + link = wp_endpoint_link_new_finish(initable, res, &error); + g_return_if_fail (link); + + /* Log linking info */ + if (error) { + g_warning ("Could not link endpoints: %s\n", error->message); + } else { + src_ep = wp_endpoint_link_get_source_endpoint (link); + sink_ep = wp_endpoint_link_get_sink_endpoint (link); + g_info ("Sucessfully linked '%s' to '%s'\n", wp_endpoint_get_name (src_ep), + wp_endpoint_get_name (sink_ep)); + } +} + static gboolean simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep) { @@ -232,7 +255,6 @@ simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep) GVariantDict d; g_autoptr (WpCore) core = NULL; g_autoptr (WpEndpoint) target = NULL; - g_autoptr (GError) error = NULL; guint32 stream_id; /* TODO: For now we only accept audio output clients */ @@ -255,12 +277,8 @@ simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep) } /* Link the client with the target */ - if (!wp_endpoint_link_new (core, ep, 0, target, stream_id, &error)) { - g_warning ("Could not link endpoints: %s\n", error->message); - } else { - g_info ("Sucessfully linked '%s' to '%s'\n", wp_endpoint_get_name (ep), - wp_endpoint_get_name (target)); - } + wp_endpoint_link_new (core, ep, 0, target, stream_id, + on_endpoint_link_created, NULL); return TRUE; }