From 12b2c00d0b6d3c6e0b0e877848731dffbc59d89e Mon Sep 17 00:00:00 2001 From: Julian Bouzas Date: Tue, 9 Mar 2021 13:13:14 -0500 Subject: [PATCH] lib: remove WpEndpointStream API Add all that goes with it. --- lib/wp/endpoint-link.c | 31 +- lib/wp/endpoint-link.h | 3 +- lib/wp/endpoint-stream.c | 591 ------------------ lib/wp/endpoint-stream.h | 36 -- lib/wp/endpoint.c | 354 +---------- lib/wp/endpoint.h | 35 -- lib/wp/meson.build | 2 - lib/wp/private/impl-endpoint.h | 10 - lib/wp/session-item.c | 81 +-- lib/wp/si-interfaces.c | 249 +++----- lib/wp/si-interfaces.h | 88 +-- lib/wp/wp.c | 1 - lib/wp/wp.h | 1 - modules/meson.build | 34 - modules/module-lua-scripting/api.c | 31 +- modules/module-si-adapter.c | 53 -- modules/module-si-audio-softdsp-endpoint.c | 309 --------- modules/module-si-bluez5-endpoint.c | 573 ----------------- modules/module-si-convert.c | 60 +- modules/module-si-fake-stream.c | 189 ------ modules/module-si-monitor-endpoint.c | 44 -- modules/module-si-simple-node-endpoint.c | 44 -- modules/module-si-standard-link.c | 180 +++--- .../config.lua.d/10-endpoint-support.lua | 3 - src/scripts/policy-endpoint.lua | 28 +- tests/examples/audiotestsrc-play.c | 12 +- tests/modules/meson.build | 11 +- ...-audio-softdsp-endpoint.c => si-adapter.c} | 170 +---- tests/modules/si-convert.c | 296 +++++++++ tests/modules/si-simple-node-endpoint.c | 36 +- tests/modules/si-standard-link.c | 26 +- tests/wp/endpoint.c | 50 +- tools/wpctl.c | 56 +- 33 files changed, 609 insertions(+), 3078 deletions(-) delete mode 100644 lib/wp/endpoint-stream.c delete mode 100644 lib/wp/endpoint-stream.h delete mode 100644 modules/module-si-audio-softdsp-endpoint.c delete mode 100644 modules/module-si-bluez5-endpoint.c delete mode 100644 modules/module-si-fake-stream.c rename tests/modules/{si-audio-softdsp-endpoint.c => si-adapter.c} (55%) create mode 100644 tests/modules/si-convert.c diff --git a/lib/wp/endpoint-link.c b/lib/wp/endpoint-link.c index 4262cd4e..2dfc7b57 100644 --- a/lib/wp/endpoint-link.c +++ b/lib/wp/endpoint-link.c @@ -187,12 +187,8 @@ wp_endpoint_link_pw_object_mixin_priv_interface_init ( * @self: the endpoint link * @output_endpoint: (out) (optional): the bound id of the output (source) * endpoint - * @output_stream: (out) (optional): the bound id of the output (source) - * endpoint's stream * @input_endpoint: (out) (optional): the bound id of the input (sink) * endpoint - * @input_stream: (out) (optional): the bound id of the input (sink) - * endpoint's stream * * Retrieves the ids of the objects that are linked by this endpoint link * @@ -200,8 +196,7 @@ wp_endpoint_link_pw_object_mixin_priv_interface_init ( */ void wp_endpoint_link_get_linked_object_ids (WpEndpointLink * self, - guint32 * output_endpoint, guint32 * output_stream, - guint32 * input_endpoint, guint32 * input_stream) + guint32 * output_endpoint, guint32 * input_endpoint) { g_return_if_fail (WP_IS_ENDPOINT_LINK (self)); @@ -211,12 +206,8 @@ wp_endpoint_link_get_linked_object_ids (WpEndpointLink * self, if (output_endpoint) *output_endpoint = info->output_endpoint_id; - if (output_stream) - *output_stream = info->output_stream_id; if (input_endpoint) *input_endpoint = info->input_endpoint_id; - if (input_stream) - *input_stream = info->input_stream_id; } /** @@ -408,7 +399,7 @@ wp_impl_endpoint_link_constructed (GObject * object) g_autoptr (GVariant) info = NULL; g_autoptr (GVariantIter) immutable_props = NULL; const gchar *key, *value; - WpSiStream *stream; + WpSiEndpoint *endpoint; self->info.version = PW_VERSION_ENDPOINT_LINK_INFO; self->info.error = NULL; @@ -426,21 +417,17 @@ wp_impl_endpoint_link_constructed (GObject * object) ? PW_ENDPOINT_LINK_STATE_ACTIVE : PW_ENDPOINT_LINK_STATE_INACTIVE; - /* associate with the session, the endpoints and the streams */ + /* associate with the session and the endpoints */ self->info.session_id = wp_session_item_get_associated_proxy_id ( WP_SESSION_ITEM (self->item), WP_TYPE_SESSION); - stream = wp_si_link_get_out_stream (self->item); + endpoint = wp_si_link_get_out_endpoint (self->item); self->info.output_endpoint_id = wp_session_item_get_associated_proxy_id ( - WP_SESSION_ITEM (stream), WP_TYPE_ENDPOINT); - self->info.output_stream_id = wp_session_item_get_associated_proxy_id ( - WP_SESSION_ITEM (stream), WP_TYPE_ENDPOINT_STREAM); + WP_SESSION_ITEM (endpoint), WP_TYPE_ENDPOINT); - stream = wp_si_link_get_in_stream (self->item); + endpoint = wp_si_link_get_in_endpoint (self->item); self->info.input_endpoint_id = wp_session_item_get_associated_proxy_id ( - WP_SESSION_ITEM (stream), WP_TYPE_ENDPOINT); - self->info.input_stream_id = wp_session_item_get_associated_proxy_id ( - WP_SESSION_ITEM (stream), WP_TYPE_ENDPOINT_STREAM); + WP_SESSION_ITEM (endpoint), WP_TYPE_ENDPOINT); /* construct export properties (these will come back through the registry and appear in wp_proxy_get_global_properties) */ @@ -449,12 +436,8 @@ wp_impl_endpoint_link_constructed (GObject * object) PW_KEY_SESSION_ID, "%d", self->info.session_id); wp_properties_setf (self->immutable_props, PW_KEY_ENDPOINT_LINK_OUTPUT_ENDPOINT, "%d", self->info.output_endpoint_id); - wp_properties_setf (self->immutable_props, - PW_KEY_ENDPOINT_LINK_OUTPUT_STREAM, "%d", self->info.output_stream_id); wp_properties_setf (self->immutable_props, PW_KEY_ENDPOINT_LINK_INPUT_ENDPOINT, "%d", self->info.input_endpoint_id); - wp_properties_setf (self->immutable_props, - PW_KEY_ENDPOINT_LINK_INPUT_STREAM, "%d", self->info.input_stream_id); /* populate immutable (global) properties */ while (g_variant_iter_next (immutable_props, "{&s&s}", &key, &value)) diff --git a/lib/wp/endpoint-link.h b/lib/wp/endpoint-link.h index 1ee5d1c4..63b44f56 100644 --- a/lib/wp/endpoint-link.h +++ b/lib/wp/endpoint-link.h @@ -44,8 +44,7 @@ struct _WpEndpointLinkClass WP_API void wp_endpoint_link_get_linked_object_ids (WpEndpointLink * self, - guint32 * output_endpoint, guint32 * output_stream, - guint32 * input_endpoint, guint32 * input_stream); + guint32 * output_endpoint, guint32 * input_endpoint); WP_API WpEndpointLinkState wp_endpoint_link_get_state (WpEndpointLink * self, diff --git a/lib/wp/endpoint-stream.c b/lib/wp/endpoint-stream.c deleted file mode 100644 index 41a093ea..00000000 --- a/lib/wp/endpoint-stream.c +++ /dev/null @@ -1,591 +0,0 @@ -/* WirePlumber - * - * Copyright © 2020 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -/** - * SECTION: endpoint-stream - * @title: PipeWire Endpoint Stream - */ - -#define G_LOG_DOMAIN "wp-endpoint-stream" - -#include "endpoint-stream.h" -#include "node.h" -#include "error.h" -#include "debug.h" -#include "spa-type.h" -#include "private/impl-endpoint.h" -#include "private/pipewire-object-mixin.h" - -#include -#include - -enum { - PROP_NAME = WP_PW_OBJECT_MIXIN_PROP_CUSTOM_START, -}; - -static void wp_endpoint_stream_pw_object_mixin_priv_interface_init ( - WpPwObjectMixinPrivInterface * iface); - -/** - * WpEndpointStream: - * - * The #WpEndpointStream class allows accessing the properties and methods of a - * PipeWire endpoint stream object (`struct pw_endpoint_stream` from the - * session-manager extension). - * - * A #WpEndpointStream is constructed internally when a new endpoint appears on - * the PipeWire registry and it is made available through the #WpObjectManager - * API. - */ -G_DEFINE_TYPE_WITH_CODE (WpEndpointStream, wp_endpoint_stream, WP_TYPE_GLOBAL_PROXY, - G_IMPLEMENT_INTERFACE (WP_TYPE_PIPEWIRE_OBJECT, - wp_pw_object_mixin_object_interface_init) - G_IMPLEMENT_INTERFACE (WP_TYPE_PW_OBJECT_MIXIN_PRIV, - wp_endpoint_stream_pw_object_mixin_priv_interface_init)) - -static void -wp_endpoint_stream_init (WpEndpointStream * self) -{ -} - -static void -wp_endpoint_stream_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (object); - - switch (property_id) { - case PROP_NAME: - g_value_set_string (value, d->info ? - ((struct pw_endpoint_stream_info *) d->info)->name : NULL); - break; - default: - wp_pw_object_mixin_get_property (object, property_id, value, pspec); - break; - } -} - -static void -wp_endpoint_stream_activate_execute_step (WpObject * object, - WpFeatureActivationTransition * transition, guint step, - WpObjectFeatures missing) -{ - switch (step) { - case WP_PW_OBJECT_MIXIN_STEP_BIND: - case WP_TRANSITION_STEP_ERROR: - /* base class can handle BIND and ERROR */ - WP_OBJECT_CLASS (wp_endpoint_stream_parent_class)-> - activate_execute_step (object, transition, step, missing); - break; - case WP_PW_OBJECT_MIXIN_STEP_WAIT_INFO: - /* just wait, info will be emitted anyway after binding */ - break; - case WP_PW_OBJECT_MIXIN_STEP_CACHE_PARAMS: - wp_pw_object_mixin_cache_params (object, missing); - break; - default: - g_assert_not_reached (); - } -} - -static void -wp_endpoint_stream_deactivate (WpObject * object, WpObjectFeatures features) -{ - wp_pw_object_mixin_deactivate (object, features); - WP_OBJECT_CLASS (wp_endpoint_stream_parent_class)->deactivate (object, features); -} - -static const struct pw_endpoint_stream_events endpoint_stream_events = { - PW_VERSION_ENDPOINT_STREAM_EVENTS, - .info = (HandleEventInfoFunc(endpoint_stream)) wp_pw_object_mixin_handle_event_info, - .param = wp_pw_object_mixin_handle_event_param, -}; - -static void -wp_endpoint_stream_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) -{ - wp_pw_object_mixin_handle_pw_proxy_created (proxy, pw_proxy, - endpoint_stream, &endpoint_stream_events); -} - -static void -wp_endpoint_stream_class_init (WpEndpointStreamClass * klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - WpObjectClass *wpobject_class = (WpObjectClass *) klass; - WpProxyClass *proxy_class = (WpProxyClass *) klass; - - object_class->get_property = wp_endpoint_stream_get_property; - - wpobject_class->get_supported_features = - wp_pw_object_mixin_get_supported_features; - wpobject_class->activate_get_next_step = - wp_pw_object_mixin_activate_get_next_step; - wpobject_class->activate_execute_step = - wp_endpoint_stream_activate_execute_step; - wpobject_class->deactivate = wp_endpoint_stream_deactivate; - - proxy_class->pw_iface_type = PW_TYPE_INTERFACE_EndpointStream; - proxy_class->pw_iface_version = PW_VERSION_ENDPOINT_STREAM; - proxy_class->pw_proxy_created = wp_endpoint_stream_pw_proxy_created; - proxy_class->pw_proxy_destroyed = - wp_pw_object_mixin_handle_pw_proxy_destroyed; - - wp_pw_object_mixin_class_override_properties (object_class); - - /** - * WpEndpointStream:name: - * - * The name of the endpoint stream - */ - g_object_class_install_property (object_class, PROP_NAME, - g_param_spec_string ("name", "name", "name", NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); -} - -static gint -wp_endpoint_stream_enum_params (gpointer instance, guint32 id, - guint32 start, guint32 num, WpSpaPod *filter) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance); - return pw_endpoint_stream_enum_params (d->iface, 0, id, start, num, - filter ? wp_spa_pod_get_spa_pod (filter) : NULL); -} - -static gint -wp_endpoint_stream_set_param (gpointer instance, guint32 id, guint32 flags, - WpSpaPod * param) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (instance); - return pw_endpoint_stream_set_param (d->iface, id, flags, - wp_spa_pod_get_spa_pod (param)); -} - -static void -wp_endpoint_stream_pw_object_mixin_priv_interface_init ( - WpPwObjectMixinPrivInterface * iface) -{ - wp_pw_object_mixin_priv_interface_info_init (iface, - endpoint_stream, ENDPOINT_STREAM); - iface->enum_params = wp_endpoint_stream_enum_params; - iface->set_param = wp_endpoint_stream_set_param; -} - -/** - * wp_endpoint_stream_get_name: - * @self: the endpoint stream - * - * Returns: the name of the endpoint stream - */ -const gchar * -wp_endpoint_stream_get_name (WpEndpointStream * self) -{ - g_return_val_if_fail (WP_IS_ENDPOINT_STREAM (self), NULL); - g_return_val_if_fail (wp_object_get_active_features (WP_OBJECT (self)) & - WP_PIPEWIRE_OBJECT_FEATURE_INFO, NULL); - - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - return ((struct pw_endpoint_stream_info *) d->info)->name; -} - - -/* WpImplEndpointStream */ - -enum { - IMPL_PROP_0, - IMPL_PROP_ITEM, -}; - -struct _WpImplEndpointStream -{ - WpEndpointStream parent; - - struct spa_interface iface; - struct pw_endpoint_stream_info info; - WpProperties *immutable_props; - - WpSiStream *item; -}; - -static void wp_endpoint_stream_impl_pw_object_mixin_priv_interface_init ( - WpPwObjectMixinPrivInterface * iface); - -G_DEFINE_TYPE_WITH_CODE (WpImplEndpointStream, wp_impl_endpoint_stream, WP_TYPE_ENDPOINT_STREAM, - G_IMPLEMENT_INTERFACE (WP_TYPE_PW_OBJECT_MIXIN_PRIV, - wp_endpoint_stream_impl_pw_object_mixin_priv_interface_init)) - -static struct spa_param_info impl_param_info[] = { - SPA_PARAM_INFO (SPA_PARAM_Props, SPA_PARAM_INFO_READWRITE), - SPA_PARAM_INFO (SPA_PARAM_PropInfo, SPA_PARAM_INFO_READ) -}; - -static const struct pw_endpoint_stream_methods impl_endpoint_stream = { - PW_VERSION_ENDPOINT_STREAM_METHODS, - .add_listener = - (ImplAddListenerFunc(endpoint_stream)) wp_pw_object_mixin_impl_add_listener, - .subscribe_params = wp_pw_object_mixin_impl_subscribe_params, - .enum_params = wp_pw_object_mixin_impl_enum_params, - .set_param = wp_pw_object_mixin_impl_set_param, -}; - -static void -wp_impl_endpoint_stream_init (WpImplEndpointStream * self) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - - self->iface = SPA_INTERFACE_INIT ( - PW_TYPE_INTERFACE_EndpointStream, - PW_VERSION_ENDPOINT_STREAM, - &impl_endpoint_stream, self); - - d->info = &self->info; - d->iface = &self->iface; -} - -static void -populate_properties (WpImplEndpointStream * self) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - - g_clear_pointer (&d->properties, wp_properties_unref); - d->properties = wp_si_stream_get_properties (self->item); - if (!d->properties) - d->properties = wp_properties_new_empty (); - d->properties = wp_properties_ensure_unique_owner (d->properties); - wp_properties_update (d->properties, self->immutable_props); - - self->info.props = (struct spa_dict *) wp_properties_peek_dict (d->properties); -} - -static void -on_si_stream_properties_changed (WpSiStream * item, WpImplEndpointStream * self) -{ - populate_properties (self); - wp_pw_object_mixin_notify_info (self, PW_ENDPOINT_STREAM_CHANGE_MASK_PROPS); -} - -static void -on_node_params_changed (WpNode * node, guint32 param_id, WpImplEndpoint * self) -{ - if (param_id == SPA_PARAM_PropInfo || param_id == SPA_PARAM_Props) - wp_pw_object_mixin_notify_params_changed (self, param_id); -} - -static void -wp_impl_endpoint_stream_constructed (GObject * object) -{ - WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object); - g_autoptr (GVariant) info = NULL; - g_autoptr (GVariantIter) immutable_props = NULL; - g_autoptr (WpObject) node = NULL; - const gchar *key, *value; - - self->info.version = PW_VERSION_ENDPOINT_STREAM_INFO; - - /* get info from the interface */ - info = wp_si_stream_get_registration_info (self->item); - g_variant_get (info, "(sa{ss})", &self->info.name, &immutable_props); - - /* associate with the endpoint */ - self->info.endpoint_id = wp_session_item_get_associated_proxy_id ( - WP_SESSION_ITEM (self->item), WP_TYPE_ENDPOINT); - - /* construct export properties (these will come back through - the registry and appear in wp_proxy_get_global_properties) */ - self->immutable_props = wp_properties_new ( - PW_KEY_ENDPOINT_STREAM_NAME, self->info.name, - NULL); - wp_properties_setf (self->immutable_props, PW_KEY_ENDPOINT_ID, - "%d", self->info.endpoint_id); - - /* populate immutable (global) properties */ - while (g_variant_iter_next (immutable_props, "{&s&s}", &key, &value)) - wp_properties_set (self->immutable_props, key, value); - - /* populate standard properties */ - populate_properties (self); - - /* subscribe to changes */ - g_signal_connect_object (self->item, "stream-properties-changed", - G_CALLBACK (on_si_stream_properties_changed), self, 0); - - /* if the item has a node, proxy its ParamProps */ - node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - if (node && (wp_object_get_active_features (node) & - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS)) { - self->info.params = impl_param_info; - self->info.n_params = G_N_ELEMENTS (impl_param_info); - - g_signal_connect_object (node, "params-changed", - G_CALLBACK (on_node_params_changed), self, 0); - - wp_object_update_features (WP_OBJECT (self), - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS, 0); - } else { - self->info.params = NULL; - self->info.n_params = 0; - } - - wp_object_update_features (WP_OBJECT (self), - WP_PIPEWIRE_OBJECT_FEATURE_INFO, 0); - - G_OBJECT_CLASS (wp_impl_endpoint_stream_parent_class)->constructed (object); -} - -static void -wp_impl_endpoint_stream_dispose (GObject * object) -{ - WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object); - - g_clear_pointer (&self->immutable_props, wp_properties_unref); - g_clear_pointer (&self->info.name, g_free); - - wp_object_update_features (WP_OBJECT (self), 0, - WP_PIPEWIRE_OBJECT_FEATURE_INFO | - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS); - - G_OBJECT_CLASS (wp_impl_endpoint_stream_parent_class)->dispose (object); -} - -static void -wp_impl_endpoint_stream_set_property (GObject * object, guint property_id, - const GValue * value, GParamSpec * pspec) -{ - WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object); - - switch (property_id) { - case IMPL_PROP_ITEM: - self->item = g_value_get_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -wp_impl_endpoint_stream_get_property (GObject * object, guint property_id, - GValue * value, GParamSpec * pspec) -{ - WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object); - - switch (property_id) { - case IMPL_PROP_ITEM: - g_value_set_object (value, self->item); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -enum { - STEP_ACTIVATE_NODE = WP_PW_OBJECT_MIXIN_STEP_CUSTOM_START, -}; - -static guint -wp_impl_endpoint_stream_activate_get_next_step (WpObject * object, - WpFeatureActivationTransition * transition, guint step, - WpObjectFeatures missing) -{ - WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object); - - /* before anything else, if the item has a node, - cache its props so that enum_params works */ - if (missing & WP_PIPEWIRE_OBJECT_FEATURES_ALL) { - g_autoptr (WpObject) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - - if (node && (wp_object_get_supported_features (node) & - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS) && - !(wp_object_get_active_features (node) & - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS)) - return STEP_ACTIVATE_NODE; - } - - return WP_OBJECT_CLASS (wp_impl_endpoint_stream_parent_class)-> - activate_get_next_step (object, transition, step, missing); -} - -static void -wp_impl_endpoint_stream_node_activated (WpObject * node, - GAsyncResult * res, WpTransition * transition) -{ - WpImplEndpointStream *self = wp_transition_get_source_object (transition); - g_autoptr (GError) error = NULL; - - if (!wp_object_activate_finish (node, res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - self->info.params = impl_param_info; - self->info.n_params = G_N_ELEMENTS (impl_param_info); - - g_signal_connect_object (node, "params-changed", - G_CALLBACK (on_node_params_changed), self, 0); - - wp_object_update_features (WP_OBJECT (self), - WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS, 0); - wp_pw_object_mixin_notify_info (self, PW_ENDPOINT_STREAM_CHANGE_MASK_PARAMS); -} - -static void -wp_impl_endpoint_stream_activate_execute_step (WpObject * object, - WpFeatureActivationTransition * transition, guint step, - WpObjectFeatures missing) -{ - WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (object); - - switch (step) { - case STEP_ACTIVATE_NODE: { - g_autoptr (WpObject) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - - wp_object_activate (node, - WP_PROXY_FEATURE_BOUND | WP_PIPEWIRE_OBJECT_FEATURE_PARAM_PROPS, - NULL, (GAsyncReadyCallback) wp_impl_endpoint_stream_node_activated, - transition); - break; - } - case WP_PW_OBJECT_MIXIN_STEP_BIND: { - g_autoptr (WpCore) core = wp_object_get_core (object); - struct pw_core *pw_core = wp_core_get_pw_core (core); - - /* no pw_core -> we are not connected */ - if (!pw_core) { - wp_transition_return_error (WP_TRANSITION (transition), g_error_new ( - WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, - "The WirePlumber core is not connected; " - "object cannot be exported to PipeWire")); - return; - } - - /* bind */ - wp_proxy_set_pw_proxy (WP_PROXY (self), pw_core_export (pw_core, - PW_TYPE_INTERFACE_EndpointStream, - wp_properties_peek_dict (self->immutable_props), - &self->iface, 0)); - break; - } - default: - WP_OBJECT_CLASS (wp_impl_endpoint_stream_parent_class)-> - activate_execute_step (object, transition, step, missing); - break; - } -} - -static void -wp_impl_endpoint_stream_class_init (WpImplEndpointStreamClass * klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - WpObjectClass *wpobject_class = (WpObjectClass *) klass; - WpProxyClass *proxy_class = (WpProxyClass *) klass; - - object_class->constructed = wp_impl_endpoint_stream_constructed; - object_class->dispose = wp_impl_endpoint_stream_dispose; - object_class->set_property = wp_impl_endpoint_stream_set_property; - object_class->get_property = wp_impl_endpoint_stream_get_property; - - wpobject_class->activate_get_next_step = - wp_impl_endpoint_stream_activate_get_next_step; - wpobject_class->activate_execute_step = - wp_impl_endpoint_stream_activate_execute_step; - - proxy_class->pw_proxy_created = NULL; - proxy_class->pw_proxy_destroyed = NULL; - - g_object_class_install_property (object_class, IMPL_PROP_ITEM, - g_param_spec_object ("item", "item", "item", WP_TYPE_SI_STREAM, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); -} - -static GPtrArray * -wp_impl_endpoint_stream_enum_params_sync (gpointer instance, guint32 id, - guint32 start, guint32 num, WpSpaPod *filter) -{ - WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (instance); - g_autoptr (WpPipewireObject) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - - if (!node) { - wp_warning_object (self, "associated node is no longer available"); - return NULL; - } - - /* bypass a few things, knowing that the node - caches params in the mixin param store */ - WpPwObjectMixinData *data = wp_pw_object_mixin_get_data (node); - GPtrArray *params = wp_pw_object_mixin_get_stored_params (data, id); - /* TODO filter */ - - return params; -} - -static gint -wp_impl_endpoint_stream_set_param (gpointer instance, guint32 id, guint32 flags, - WpSpaPod * param) -{ - WpImplEndpointStream *self = WP_IMPL_ENDPOINT_STREAM (instance); - g_autoptr (WpPipewireObject) node = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->item), WP_TYPE_NODE); - - if (!node) { - wp_warning_object (self, "associated node is no longer available"); - return -EPIPE; - } - - WpSpaIdValue idval = wp_spa_id_value_from_number ("Spa:Enum:ParamId", id); - if (!idval) { - wp_critical_object (self, "invalid param id: %u", id); - return -EINVAL; - } - - return wp_pipewire_object_set_param (node, wp_spa_id_value_short_name (idval), - flags, param) ? 0 : -EIO; -} - -#define pw_endpoint_stream_emit(hooks,method,version,...) \ - spa_hook_list_call_simple(hooks, struct pw_endpoint_stream_events, \ - method, version, ##__VA_ARGS__) - -static void -wp_impl_endpoint_stream_emit_info (struct spa_hook_list * hooks, gconstpointer info) -{ - pw_endpoint_stream_emit (hooks, info, 0, info); -} - -static void -wp_impl_endpoint_stream_emit_param (struct spa_hook_list * hooks, int seq, - guint32 id, guint32 index, guint32 next, const struct spa_pod *param) -{ - pw_endpoint_stream_emit (hooks, param, 0, seq, id, index, next, param); -} - -static void -wp_endpoint_stream_impl_pw_object_mixin_priv_interface_init ( - WpPwObjectMixinPrivInterface * iface) -{ - iface->flags |= WP_PW_OBJECT_MIXIN_PRIV_NO_PARAM_CACHE; - iface->enum_params_sync = wp_impl_endpoint_stream_enum_params_sync; - iface->set_param = wp_impl_endpoint_stream_set_param; - iface->emit_info = wp_impl_endpoint_stream_emit_info; - iface->emit_param = wp_impl_endpoint_stream_emit_param; -} - -WpImplEndpointStream * -wp_impl_endpoint_stream_new (WpCore * core, WpSiStream * item) -{ - g_return_val_if_fail (WP_IS_CORE (core), NULL); - - return g_object_new (WP_TYPE_IMPL_ENDPOINT_STREAM, - "core", core, - "item", item, - NULL); -} diff --git a/lib/wp/endpoint-stream.h b/lib/wp/endpoint-stream.h deleted file mode 100644 index 665e4b54..00000000 --- a/lib/wp/endpoint-stream.h +++ /dev/null @@ -1,36 +0,0 @@ -/* WirePlumber - * - * Copyright © 2020 Collabora Ltd. - * @author George Kiagiadakis - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __WIREPLUMBER_ENDPOINT_STREAM_H__ -#define __WIREPLUMBER_ENDPOINT_STREAM_H__ - -#include "global-proxy.h" - -G_BEGIN_DECLS - -/** - * WP_TYPE_ENDPOINT_STREAM: - * - * The #WpEndpointStream #GType - */ -#define WP_TYPE_ENDPOINT_STREAM (wp_endpoint_stream_get_type ()) -WP_API -G_DECLARE_DERIVABLE_TYPE (WpEndpointStream, wp_endpoint_stream, - WP, ENDPOINT_STREAM, WpGlobalProxy) - -struct _WpEndpointStreamClass -{ - WpGlobalProxyClass parent_class; -}; - -WP_API -const gchar * wp_endpoint_stream_get_name (WpEndpointStream * self); - -G_END_DECLS - -#endif diff --git a/lib/wp/endpoint.c b/lib/wp/endpoint.c index fa024cb1..123430a6 100644 --- a/lib/wp/endpoint.c +++ b/lib/wp/endpoint.c @@ -36,17 +36,10 @@ enum { PROP_DIRECTION, }; -enum { - SIGNAL_STREAMS_CHANGED, - N_SIGNALS, -}; - -static guint32 signals[N_SIGNALS] = {0}; - typedef struct _WpEndpointPrivate WpEndpointPrivate; struct _WpEndpointPrivate { - WpObjectManager *streams_om; + gint place_holder; }; static void wp_endpoint_pw_object_mixin_priv_interface_init ( @@ -99,76 +92,12 @@ wp_endpoint_get_property (GObject * object, guint property_id, } } -static void -wp_endpoint_on_streams_om_installed (WpObjectManager *streams_om, - WpEndpoint * self) -{ - wp_object_update_features (WP_OBJECT (self), WP_ENDPOINT_FEATURE_STREAMS, 0); -} - -static void -wp_endpoint_emit_streams_changed (WpObjectManager *streams_om, - WpEndpoint * self) -{ - g_signal_emit (self, signals[SIGNAL_STREAMS_CHANGED], 0); - wp_object_update_features (WP_OBJECT (self), WP_ENDPOINT_FEATURE_STREAMS, 0); -} - -static void -wp_endpoint_enable_feature_streams (WpEndpoint * self) -{ - WpPwObjectMixinData *d = wp_pw_object_mixin_get_data (self); - WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self); - g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self)); - guint32 bound_id = wp_proxy_get_bound_id (WP_PROXY (self)); - guint32 n_streams = ((struct pw_endpoint_info *) d->info)->n_streams; - - wp_debug_object (self, "enabling WP_ENDPOINT_FEATURE_STREAMS, bound_id:%u, " - "n_streams:%u", bound_id, n_streams); - - priv->streams_om = wp_object_manager_new (); - /* proxy endpoint stream -> check for endpoint.id in global properties */ - wp_object_manager_add_interest (priv->streams_om, - WP_TYPE_ENDPOINT_STREAM, - WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, PW_KEY_ENDPOINT_ID, "=u", bound_id, - NULL); - /* impl endpoint stream -> check for endpoint.id in standard properties */ - wp_object_manager_add_interest (priv->streams_om, - WP_TYPE_IMPL_ENDPOINT_STREAM, - WP_CONSTRAINT_TYPE_PW_PROPERTY, PW_KEY_ENDPOINT_ID, "=u", bound_id, - NULL); - wp_object_manager_request_object_features (priv->streams_om, - WP_TYPE_ENDPOINT_STREAM, WP_OBJECT_FEATURES_ALL); - - /* endpoints, under normal circumstances, always have streams. - When we export (self is a WpImplEndpoint), we have to export first - the endpoint and afterwards the streams (so that the streams can be - associated with the endpoint's bound id), but then the issue is that - the "installed" signal gets fired here without any streams being ready - and we get an endpoint with 0 streams in the WpSession's endpoints - object manager... so, unless the endpoint really has no streams, - wait for them to be prepared by waiting for the "objects-changed" only */ - if (G_UNLIKELY (n_streams == 0)) { - g_signal_connect_object (priv->streams_om, "installed", - G_CALLBACK (wp_endpoint_on_streams_om_installed), self, 0); - } - g_signal_connect_object (priv->streams_om, "objects-changed", - G_CALLBACK (wp_endpoint_emit_streams_changed), self, 0); - - wp_core_install_object_manager (core, priv->streams_om); -} - static WpObjectFeatures wp_endpoint_get_supported_features (WpObject * object) { - return wp_pw_object_mixin_get_supported_features(object) - | WP_ENDPOINT_FEATURE_STREAMS; + return wp_pw_object_mixin_get_supported_features(object); } -enum { - STEP_STREAMS = WP_PW_OBJECT_MIXIN_STEP_CUSTOM_START, -}; - static void wp_endpoint_activate_execute_step (WpObject * object, WpFeatureActivationTransition * transition, guint step, @@ -187,9 +116,6 @@ wp_endpoint_activate_execute_step (WpObject * object, case WP_PW_OBJECT_MIXIN_STEP_CACHE_PARAMS: wp_pw_object_mixin_cache_params (object, missing); break; - case STEP_STREAMS: - wp_endpoint_enable_feature_streams (WP_ENDPOINT (object)); - break; default: g_assert_not_reached (); } @@ -199,14 +125,6 @@ static void wp_endpoint_deactivate (WpObject * object, WpObjectFeatures features) { wp_pw_object_mixin_deactivate (object, features); - - if (features & WP_ENDPOINT_FEATURE_STREAMS) { - WpEndpoint *self = WP_ENDPOINT (object); - WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self); - g_clear_object (&priv->streams_om); - wp_object_update_features (object, 0, WP_ENDPOINT_FEATURE_STREAMS); - } - WP_OBJECT_CLASS (wp_endpoint_parent_class)->deactivate (object, features); } @@ -226,14 +144,9 @@ wp_endpoint_pw_proxy_created (WpProxy * proxy, struct pw_proxy * pw_proxy) static void wp_endpoint_pw_proxy_destroyed (WpProxy * proxy) { - WpEndpoint *self = WP_ENDPOINT (proxy); - WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self); - wp_pw_object_mixin_handle_pw_proxy_destroyed (proxy); - g_clear_object (&priv->streams_om); - wp_object_update_features (WP_OBJECT (proxy), 0, - WP_ENDPOINT_FEATURE_STREAMS); + wp_object_update_features (WP_OBJECT (proxy), 0, 0); } static void @@ -258,17 +171,6 @@ wp_endpoint_class_init (WpEndpointClass * klass) wp_pw_object_mixin_class_override_properties (object_class); - /** - * WpEndpoint::streams-changed: - * @self: the endpoint - * - * Emitted when the endpoints's streams change. This is only emitted - * when %WP_ENDPOINT_FEATURE_STREAMS is enabled. - */ - signals[SIGNAL_STREAMS_CHANGED] = g_signal_new ( - "streams-changed", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - /** * WpEndpoint:name: * @@ -381,138 +283,6 @@ wp_endpoint_get_direction (WpEndpoint * self) return (WpDirection) ((struct pw_endpoint_info *) d->info)->direction; } -/** - * wp_endpoint_get_n_streams: - * @self: the endpoint - * - * Requires %WP_ENDPOINT_FEATURE_STREAMS - * - * Returns: the number of streams of this endpoint - */ -guint -wp_endpoint_get_n_streams (WpEndpoint * self) -{ - g_return_val_if_fail (WP_IS_ENDPOINT (self), 0); - g_return_val_if_fail (wp_object_get_active_features (WP_OBJECT (self)) & - WP_ENDPOINT_FEATURE_STREAMS, 0); - - WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self); - return wp_object_manager_get_n_objects (priv->streams_om); -} - -/** - * wp_endpoint_new_streams_iterator: - * @self: the endpoint - * - * Requires %WP_ENDPOINT_FEATURE_STREAMS - * - * Returns: (transfer full): a #WpIterator that iterates over all - * the endpoint streams that belong to this endpoint - */ -WpIterator * -wp_endpoint_new_streams_iterator (WpEndpoint * self) -{ - g_return_val_if_fail (WP_IS_ENDPOINT (self), NULL); - g_return_val_if_fail (wp_object_get_active_features (WP_OBJECT (self)) & - WP_ENDPOINT_FEATURE_STREAMS, NULL); - - WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self); - return wp_object_manager_new_iterator (priv->streams_om); -} - -/** - * wp_endpoint_new_streams_filtered_iterator: - * @self: the endpoint - * @...: a list of constraints, terminated by %NULL - * - * Requires %WP_ENDPOINT_FEATURE_STREAMS - * - * The constraints specified in the variable arguments must follow the rules - * documented in wp_object_interest_new(). - * - * Returns: (transfer full): a #WpIterator that iterates over all - * the streams that belong to this endpoint and match the constraints - */ -WpIterator * -wp_endpoint_new_streams_filtered_iterator (WpEndpoint * self, ...) -{ - WpObjectInterest *interest; - va_list args; - va_start (args, self); - interest = wp_object_interest_new_valist (WP_TYPE_ENDPOINT_STREAM, &args); - va_end (args); - return wp_endpoint_new_streams_filtered_iterator_full (self, interest); -} - -/** - * wp_endpoint_new_streams_filtered_iterator_full: (rename-to wp_endpoint_new_streams_filtered_iterator) - * @self: the endpoint - * @interest: (transfer full): the interest - * - * Requires %WP_ENDPOINT_FEATURE_STREAMS - * - * Returns: (transfer full): a #WpIterator that iterates over all - * the streams that belong to this endpoint and match the @interest - */ -WpIterator * -wp_endpoint_new_streams_filtered_iterator_full (WpEndpoint * self, - WpObjectInterest * interest) -{ - g_return_val_if_fail (WP_IS_ENDPOINT (self), NULL); - g_return_val_if_fail (wp_object_get_active_features (WP_OBJECT (self)) & - WP_ENDPOINT_FEATURE_STREAMS, NULL); - - WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self); - return wp_object_manager_new_filtered_iterator_full (priv->streams_om, - interest); -} - -/** - * wp_endpoint_lookup_stream: - * @self: the endpoint - * @...: a list of constraints, terminated by %NULL - * - * Requires %WP_ENDPOINT_FEATURE_STREAMS - * - * The constraints specified in the variable arguments must follow the rules - * documented in wp_object_interest_new(). - * - * Returns: (transfer full) (nullable): the first stream that matches the - * constraints, or %NULL if there is no such stream - */ -WpEndpointStream * -wp_endpoint_lookup_stream (WpEndpoint * self, ...) -{ - WpObjectInterest *interest; - va_list args; - va_start (args, self); - interest = wp_object_interest_new_valist (WP_TYPE_ENDPOINT_STREAM, &args); - va_end (args); - return wp_endpoint_lookup_stream_full (self, interest); -} - -/** - * wp_endpoint_lookup_stream_full: (rename-to wp_endpoint_lookup_stream) - * @self: the endpoint - * @interest: (transfer full): the interest - * - * Requires %WP_ENDPOINT_FEATURE_STREAMS - * - * Returns: (transfer full) (nullable): the first stream that matches the - * @interest, or %NULL if there is no such stream - */ -WpEndpointStream * -wp_endpoint_lookup_stream_full (WpEndpoint * self, WpObjectInterest * interest) -{ - g_return_val_if_fail (WP_IS_ENDPOINT (self), NULL); - g_return_val_if_fail (wp_object_get_active_features (WP_OBJECT (self)) & - WP_ENDPOINT_FEATURE_STREAMS, NULL); - - WpEndpointPrivate *priv = wp_endpoint_get_instance_private (self); - return (WpEndpointStream *) - wp_object_manager_lookup_full (priv->streams_om, interest); -} - /** * wp_endpoint_create_link: * @self: the endpoint @@ -523,15 +293,8 @@ wp_endpoint_lookup_stream_full (WpEndpoint * self, WpObjectInterest * interest) * @props may contain: * - `endpoint-link.output.endpoint`: the bound id of the endpoint * that is in the %WP_DIRECTION_OUTPUT direction - * - `endpoint-link.output.stream`: the bound id of the endpoint stream - * that is in the %WP_DIRECTION_OUTPUT direction * - `endpoint-link.input.endpoint`: the bound id of the endpoint * that is in the %WP_DIRECTION_INPUT direction - * - `endpoint-link.input.stream`: the bound id of the endpoint stream - * that is in the %WP_DIRECTION_INPUT direction - * - * If either stream id are not specified (or set to -1), then the first - * available stream of this endpoint is used for the link. * * The id of @self is not necessary to be specified, so only one of * `endpoint-link.output.endpoint`, `endpoint-link.input.endpoint` @@ -596,14 +359,11 @@ static int impl_create_link (void *object, const struct spa_dict *props) { WpImplEndpoint *self = WP_IMPL_ENDPOINT (object); - const gchar *self_ep, *self_stream, *peer_ep, *peer_stream; - guint32 self_ep_id, self_stream_id, peer_ep_id, peer_stream_id; - WpSiStream *self_si_stream = NULL; - g_autoptr (WpSiStream) peer_si_stream = NULL; + const gchar *self_ep, *peer_ep; + guint32 peer_ep_id; + g_autoptr (WpSiEndpoint) peer_si_endpoint = NULL; g_autoptr (WpSession) session = NULL; - g_autoptr (WpEndpointStream) self_stream_proxy = NULL; g_autoptr (WpEndpoint) peer_ep_proxy = NULL; - g_autoptr (WpEndpointStream) peer_stream_proxy = NULL; /* find the session */ session = wp_session_item_get_associated_proxy ( @@ -612,18 +372,14 @@ impl_create_link (void *object, const struct spa_dict *props) if (self->info.direction == PW_DIRECTION_OUTPUT) { self_ep = spa_dict_lookup (props, PW_KEY_ENDPOINT_LINK_OUTPUT_ENDPOINT); - self_stream = spa_dict_lookup (props, PW_KEY_ENDPOINT_LINK_OUTPUT_STREAM); peer_ep = spa_dict_lookup (props, PW_KEY_ENDPOINT_LINK_INPUT_ENDPOINT); - peer_stream = spa_dict_lookup (props, PW_KEY_ENDPOINT_LINK_INPUT_STREAM); } else { self_ep = spa_dict_lookup (props, PW_KEY_ENDPOINT_LINK_INPUT_ENDPOINT); - self_stream = spa_dict_lookup (props, PW_KEY_ENDPOINT_LINK_INPUT_STREAM); peer_ep = spa_dict_lookup (props, PW_KEY_ENDPOINT_LINK_OUTPUT_ENDPOINT); - peer_stream = spa_dict_lookup (props, PW_KEY_ENDPOINT_LINK_OUTPUT_STREAM); } - wp_debug_object (self, "requested link between %s:%s [self] & %s:%s [peer]", - self_ep, self_stream, peer_ep, peer_stream); + wp_debug_object (self, "requested link between %s [self] & %s [peer]", + self_ep, peer_ep); /* verify arguments */ if (!peer_ep) { @@ -638,41 +394,10 @@ impl_create_link (void *object, const struct spa_dict *props) return -EACCES; } - /* convert to int - allow unspecified streams */ - self_ep_id = wp_proxy_get_bound_id (WP_PROXY (self)); - self_stream_id = self_stream ? (guint32) atoi (self_stream) : SPA_ID_INVALID; + /* convert to int */ peer_ep_id = (guint32) atoi (peer_ep); - peer_stream_id = peer_stream ? (guint32) atoi (peer_stream) : SPA_ID_INVALID; - /* find our stream */ - if (self_stream_id != SPA_ID_INVALID) { - WpSiStream *tmp; - guint32 tmp_id; - - for (guint i = 0; i < wp_si_endpoint_get_n_streams (self->item); i++) { - tmp = wp_si_endpoint_get_stream (self->item, i); - tmp_id = wp_session_item_get_associated_proxy_id (WP_SESSION_ITEM (tmp), - WP_TYPE_ENDPOINT_STREAM); - - if (tmp_id == self_stream_id) { - self_si_stream = tmp; - break; - } - } - } else { - self_si_stream = wp_si_endpoint_get_stream (self->item, 0); - } - - if (!self_si_stream) { - wp_warning_object (self, "stream %d not found in %d", self_stream_id, - self_ep_id); - return -EINVAL; - } - - self_stream_proxy = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self_si_stream), WP_TYPE_ENDPOINT_STREAM); - - /* find the peer stream */ + /* find the peer endpoint */ peer_ep_proxy = wp_session_lookup_endpoint (session, WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", peer_ep_id, NULL); if (!peer_ep_proxy) { @@ -680,44 +405,21 @@ impl_create_link (void *object, const struct spa_dict *props) return -EINVAL; } - if (peer_stream_id != SPA_ID_INVALID) { - peer_stream_proxy = wp_endpoint_lookup_stream (peer_ep_proxy, - WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", peer_stream_id, NULL); - } else { - peer_stream_proxy = wp_endpoint_lookup_stream (peer_ep_proxy, NULL); - } - - if (!peer_stream_proxy) { - wp_warning_object (self, "stream %d not found in %d", peer_stream_id, - peer_ep_id); - return -EINVAL; - } - - if (!WP_IS_IMPL_ENDPOINT_STREAM (peer_stream_proxy)) { - /* TODO - if the stream is not implemented by our session manager, - we can still make things work by calling the peer endpoint's - create_link() and negotiating ports, while creating a dummy - WpSiEndpoint / WpSiStream on our end to satisfy the API */ - return -ENAVAIL; - } - - g_object_get (peer_stream_proxy, "item", &peer_si_stream, NULL); + g_object_get (peer_ep_proxy, "item", &peer_si_endpoint, NULL); wp_info_object (self, "creating endpoint link between " - "%s|%s " WP_OBJECT_FORMAT ", %s|%s " WP_OBJECT_FORMAT, + "%s " WP_OBJECT_FORMAT ", %s " WP_OBJECT_FORMAT, wp_endpoint_get_name (WP_ENDPOINT (self)), - wp_endpoint_stream_get_name (self_stream_proxy), - WP_OBJECT_ARGS (self_si_stream), + WP_OBJECT_ARGS (self->item), wp_endpoint_get_name (peer_ep_proxy), - wp_endpoint_stream_get_name (peer_stream_proxy), - WP_OBJECT_ARGS (peer_si_stream)); + WP_OBJECT_ARGS (peer_si_endpoint)); /* create the link */ { g_autoptr (WpSessionItem) link = NULL; g_autoptr (WpCore) core = NULL; GVariantBuilder b; - guint64 out_stream_i, in_stream_i; + guint64 out_endpoint_i, in_endpoint_i; core = wp_object_get_core (WP_OBJECT (self)); link = wp_session_item_make (core, "si-standard-link"); @@ -727,18 +429,18 @@ impl_create_link (void *object, const struct spa_dict *props) } if (self->info.direction == PW_DIRECTION_OUTPUT) { - out_stream_i = (guint64) self_si_stream; - in_stream_i = (guint64) peer_si_stream; + out_endpoint_i = (guint64) self->item; + in_endpoint_i = (guint64) peer_si_endpoint; } else { - out_stream_i = (guint64) peer_si_stream; - in_stream_i = (guint64) self_si_stream; + out_endpoint_i = (guint64) peer_si_endpoint; + in_endpoint_i = (guint64) self->item; } g_variant_builder_init (&b, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&b, "{sv}", "out-stream", - g_variant_new_uint64 (out_stream_i)); - g_variant_builder_add (&b, "{sv}", "in-stream", - g_variant_new_uint64 (in_stream_i)); + g_variant_builder_add (&b, "{sv}", "out-endpoint", + g_variant_new_uint64 (out_endpoint_i)); + g_variant_builder_add (&b, "{sv}", "in-endpoint", + g_variant_new_uint64 (in_endpoint_i)); g_variant_builder_add (&b, "{sv}", "manage-lifetime", g_variant_new_boolean (TRUE)); if (G_UNLIKELY (!wp_session_item_configure (link, g_variant_builder_end (&b)))) { @@ -824,7 +526,6 @@ wp_impl_endpoint_constructed (GObject * object) &self->info.media_class, &direction, &immutable_props); self->info.direction = (enum pw_direction) direction; - self->info.n_streams = wp_si_endpoint_get_n_streams (self->item); /* associate with the session */ self->info.session_id = wp_session_item_get_associated_proxy_id ( @@ -922,7 +623,7 @@ wp_impl_endpoint_get_property (GObject * object, guint property_id, } enum { - STEP_ACTIVATE_NODE = STEP_STREAMS + 1, + STEP_ACTIVATE_NODE = WP_PW_OBJECT_MIXIN_STEP_CUSTOM_START + 1, }; static guint @@ -1020,12 +721,7 @@ wp_impl_endpoint_activate_execute_step (WpObject * object, static void wp_impl_endpoint_pw_proxy_destroyed (WpProxy * proxy) { - WpEndpointPrivate *priv = - wp_endpoint_get_instance_private (WP_ENDPOINT (proxy)); - - g_clear_object (&priv->streams_om); - wp_object_update_features (WP_OBJECT (proxy), 0, - WP_ENDPOINT_FEATURE_STREAMS); + wp_object_update_features (WP_OBJECT (proxy), 0, 0); } static void diff --git a/lib/wp/endpoint.h b/lib/wp/endpoint.h index 39a2a0cf..469a8024 100644 --- a/lib/wp/endpoint.h +++ b/lib/wp/endpoint.h @@ -11,24 +11,11 @@ #include "global-proxy.h" #include "port.h" -#include "endpoint-stream.h" #include "iterator.h" #include "object-interest.h" G_BEGIN_DECLS -/** - * WpEndpointFeatures: - * @WP_ENDPOINT_FEATURE_STREAMS: caches information about streams, enabling - * the use of wp_endpoint_get_n_streams(), wp_endpoint_lookup_stream(), - * wp_endpoint_new_streams_iterator() and related methods - * - * An extension of #WpProxyFeatures - */ -typedef enum { /*< flags >*/ - WP_ENDPOINT_FEATURE_STREAMS = (WP_PROXY_FEATURE_CUSTOM_START << 0), -} WpEndpointFeatures; - /** * WP_TYPE_ENDPOINT: * @@ -52,28 +39,6 @@ const gchar * wp_endpoint_get_media_class (WpEndpoint * self); WP_API WpDirection wp_endpoint_get_direction (WpEndpoint * self); -WP_API -guint wp_endpoint_get_n_streams (WpEndpoint * self); - -WP_API -WpIterator * wp_endpoint_new_streams_iterator (WpEndpoint * self); - -WP_API -WpIterator * wp_endpoint_new_streams_filtered_iterator (WpEndpoint * self, ...) - G_GNUC_NULL_TERMINATED; - -WP_API -WpIterator * wp_endpoint_new_streams_filtered_iterator_full (WpEndpoint * self, - WpObjectInterest * interest); - -WP_API -WpEndpointStream * wp_endpoint_lookup_stream (WpEndpoint * self, ...) - G_GNUC_NULL_TERMINATED; - -WP_API -WpEndpointStream * wp_endpoint_lookup_stream_full (WpEndpoint * self, - WpObjectInterest * interest); - WP_API void wp_endpoint_create_link (WpEndpoint * self, WpProperties * props); diff --git a/lib/wp/meson.build b/lib/wp/meson.build index addb93eb..53e1228e 100644 --- a/lib/wp/meson.build +++ b/lib/wp/meson.build @@ -7,7 +7,6 @@ wp_lib_sources = files( 'device.c', 'endpoint.c', 'endpoint-link.c', - 'endpoint-stream.c', 'error.c', 'global-proxy.c', 'iterator.c', @@ -43,7 +42,6 @@ wp_lib_headers = files( 'device.h', 'endpoint.h', 'endpoint-link.h', - 'endpoint-stream.h', 'error.h', 'global-proxy.h', 'iterator.h', diff --git a/lib/wp/private/impl-endpoint.h b/lib/wp/private/impl-endpoint.h index a22c51e4..39f68dcd 100644 --- a/lib/wp/private/impl-endpoint.h +++ b/lib/wp/private/impl-endpoint.h @@ -10,7 +10,6 @@ #define __WIREPLUMBER_PRIVATE_IMPL_ENDPOINT_H__ #include "endpoint.h" -#include "endpoint-stream.h" #include "endpoint-link.h" #include "si-interfaces.h" @@ -24,15 +23,6 @@ G_DECLARE_FINAL_TYPE (WpImplEndpoint, wp_impl_endpoint, WpImplEndpoint * wp_impl_endpoint_new (WpCore * core, WpSiEndpoint * item); -/* impl endpoint stream */ - -#define WP_TYPE_IMPL_ENDPOINT_STREAM (wp_impl_endpoint_stream_get_type ()) -G_DECLARE_FINAL_TYPE (WpImplEndpointStream, wp_impl_endpoint_stream, - WP, IMPL_ENDPOINT_STREAM, WpEndpointStream) - -WpImplEndpointStream * wp_impl_endpoint_stream_new (WpCore * core, - WpSiStream * item); - /* impl endpoint link */ #define WP_TYPE_IMPL_ENDPOINT_LINK (wp_impl_endpoint_link_get_type ()) diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c index abd972f9..4551c896 100644 --- a/lib/wp/session-item.c +++ b/lib/wp/session-item.c @@ -88,7 +88,6 @@ struct _WpSessionItemPrivate WpImplEndpoint *impl_endpoint; WpImplEndpointLink *impl_link; }; - GHashTable *impl_streams; }; enum { @@ -146,17 +145,9 @@ static gpointer wp_session_item_default_get_associated_proxy (WpSessionItem * self, GType proxy_type) { - WpSessionItemPrivate *priv; + WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); gpointer ret = NULL; - if (WP_IS_SI_STREAM (self)) { - g_autoptr (WpSiEndpoint) ep = - wp_si_stream_get_parent_endpoint (WP_SI_STREAM (self)); - priv = wp_session_item_get_instance_private (WP_SESSION_ITEM (ep)); - } else { - priv = wp_session_item_get_instance_private (self); - } - if (proxy_type == WP_TYPE_SESSION) { ret = g_weak_ref_get (&priv->session); } @@ -168,11 +159,6 @@ wp_session_item_default_get_associated_proxy (WpSessionItem * self, if (priv->impl_proxy && WP_IS_ENDPOINT_LINK (priv->impl_proxy)) ret = g_object_ref (priv->impl_proxy); } - else if (proxy_type == WP_TYPE_ENDPOINT_STREAM) { - gpointer impl_stream = priv->impl_streams ? - g_hash_table_lookup (priv->impl_streams, self) : NULL; - ret = impl_stream ? g_object_ref (impl_stream) : NULL; - } wp_trace_object (self, "associated %s: " WP_OBJECT_FORMAT, g_type_name (proxy_type), WP_OBJECT_ARGS (ret)); @@ -191,8 +177,6 @@ wp_session_item_default_activate_get_next_step (WpSessionItem * self, enum { EXPORT_STEP_ENDPOINT = WP_TRANSITION_STEP_CUSTOM_START, - EXPORT_STEP_STREAMS, - EXPORT_STEP_ENDPOINT_FT_STREAMS, EXPORT_STEP_LINK, EXPORT_STEP_CONNECT_DESTROYED, }; @@ -201,8 +185,6 @@ static guint wp_session_item_default_export_get_next_step (WpSessionItem * self, WpTransition * transition, guint step) { - WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); - switch (step) { case WP_TRANSITION_STEP_NONE: if (WP_IS_SI_ENDPOINT (self)) @@ -219,20 +201,6 @@ wp_session_item_default_export_get_next_step (WpSessionItem * self, case EXPORT_STEP_ENDPOINT: g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), WP_TRANSITION_STEP_ERROR); - return EXPORT_STEP_STREAMS; - - case EXPORT_STEP_STREAMS: - g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), WP_TRANSITION_STEP_ERROR); - g_return_val_if_fail (priv->impl_streams, WP_TRANSITION_STEP_ERROR); - - /* go to next step only when all impl proxies are activated */ - if (g_hash_table_size (priv->impl_streams) == - wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (self))) - return EXPORT_STEP_ENDPOINT_FT_STREAMS; - else - return step; - - case EXPORT_STEP_ENDPOINT_FT_STREAMS: return WP_TRANSITION_STEP_NONE; case EXPORT_STEP_LINK: @@ -252,7 +220,6 @@ on_export_proxy_activated (WpObject * proxy, GAsyncResult * res, gpointer data) { WpTransition *transition = WP_TRANSITION (data); WpSessionItem *self = wp_transition_get_source_object (transition); - WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); g_autoptr (GError) error = NULL; if (!wp_object_activate_finish (proxy, res, &error)) { @@ -260,15 +227,6 @@ on_export_proxy_activated (WpObject * proxy, GAsyncResult * res, gpointer data) return; } - if (WP_IS_IMPL_ENDPOINT_STREAM (proxy)) { - g_autoptr (WpSiStream) si_stream = NULL; - - g_object_get (proxy, "item", &si_stream, NULL); - g_return_if_fail (si_stream != NULL); - - g_hash_table_insert (priv->impl_streams, si_stream, g_object_ref (proxy)); - } - wp_debug_object (self, "export proxy " WP_OBJECT_FORMAT " activated", WP_OBJECT_ARGS (proxy)); @@ -324,39 +282,6 @@ wp_session_item_default_export_execute_step (WpSessionItem * self, transition); break; - case EXPORT_STEP_STREAMS: { - guint i, n_streams; - - priv->impl_streams = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_object_unref); - - n_streams = wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (self)); - for (i = 0; i < n_streams; i++) { - WpSiStream *stream = wp_si_endpoint_get_stream (WP_SI_ENDPOINT (self), i); - WpImplEndpointStream *impl_stream = - wp_impl_endpoint_stream_new (core, stream); - - wp_object_activate (WP_OBJECT (impl_stream), - WP_OBJECT_FEATURES_ALL, NULL, - (GAsyncReadyCallback) on_export_proxy_activated, - transition); - - /* the augment task holds a ref; object will be added to - priv->impl_streams when activated */ - g_object_unref (impl_stream); - } - break; - } - case EXPORT_STEP_ENDPOINT_FT_STREAMS: - /* add feature streams only after the streams are exported, otherwise - the endpoint will never be activated in the first place (because it - internally waits for the streams to be ready) */ - wp_object_activate (WP_OBJECT (priv->impl_endpoint), - WP_ENDPOINT_FEATURE_STREAMS, NULL, - (GAsyncReadyCallback) on_export_proxy_activated, - transition); - break; - case EXPORT_STEP_LINK: priv->impl_link = wp_impl_endpoint_link_new (core, WP_SI_LINK (self)); @@ -383,7 +308,6 @@ wp_session_item_default_export_rollback (WpSessionItem * self) WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); if (priv->impl_proxy) g_signal_handlers_disconnect_by_data (priv->impl_proxy, self); - g_clear_pointer (&priv->impl_streams, g_hash_table_unref); g_clear_object (&priv->impl_proxy); g_weak_ref_set (&priv->session, NULL); } @@ -546,9 +470,6 @@ wp_session_item_clear_flag (WpSessionItem * self, WpSiFlags flag) * - An exported #WpSiEndpoint should have at least: * - an associated #WpEndpoint * - an associated #WpSession - * - An exported #WpSiStream should have at least: - * - an associated #WpEndpointStream - * - an associated #WpEndpoint * - In cases where the item wraps a single PipeWire node, it should also * have an associated #WpNode * diff --git a/lib/wp/si-interfaces.c b/lib/wp/si-interfaces.c index 489cf51e..62a71213 100644 --- a/lib/wp/si-interfaces.c +++ b/lib/wp/si-interfaces.c @@ -29,8 +29,8 @@ wp_si_endpoint_default_get_properties (WpSiEndpoint * self) return NULL; } -static WpSiStreamAcquisition * -wp_si_endpoint_default_get_stream_acquisition (WpSiEndpoint * self) +static WpSiEndpointAcquisition * +wp_si_endpoint_default_get_endpoint_acquisition (WpSiEndpoint * self) { return NULL; } @@ -39,13 +39,11 @@ static void wp_si_endpoint_default_init (WpSiEndpointInterface * iface) { iface->get_properties = wp_si_endpoint_default_get_properties; - iface->get_stream_acquisition = wp_si_endpoint_default_get_stream_acquisition; + iface->get_endpoint_acquisition = + wp_si_endpoint_default_get_endpoint_acquisition; g_signal_new ("endpoint-properties-changed", G_TYPE_FROM_INTERFACE (iface), G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - - g_signal_new ("endpoint-streams-changed", G_TYPE_FROM_INTERFACE (iface), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); } /** @@ -86,125 +84,21 @@ wp_si_endpoint_get_properties (WpSiEndpoint * self) } /** - * wp_si_endpoint_get_n_streams: (virtual get_n_streams) + * wp_si_endpoint_get_endpoint_acquisition: (virtual get_endpoint_acquisition) * @self: the session item * - * Returns: the number of streams in the endpoint - */ -guint -wp_si_endpoint_get_n_streams (WpSiEndpoint * self) -{ - g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), 0); - g_return_val_if_fail (WP_SI_ENDPOINT_GET_IFACE (self)->get_n_streams, 0); - - return WP_SI_ENDPOINT_GET_IFACE (self)->get_n_streams (self); -} - -/** - * wp_si_endpoint_get_stream: (virtual get_stream) - * @self: the session item - * @index: the stream index, from 0 up to and excluding - * wp_si_endpoint_get_n_streams() - * - * Returns: (transfer none): the stream at @index - */ -WpSiStream * -wp_si_endpoint_get_stream (WpSiEndpoint * self, guint index) -{ - g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), NULL); - g_return_val_if_fail (WP_SI_ENDPOINT_GET_IFACE (self)->get_stream, NULL); - - return WP_SI_ENDPOINT_GET_IFACE (self)->get_stream (self, index); -} - -/** - * wp_si_endpoint_get_stream_acquisition: (virtual get_stream_acquisition) - * @self: the session item - * - * Returns: (transfer none) (nullable): the stream acquisition interface + * Returns: (transfer none) (nullable): the endpoint acquisition interface * associated with this endpoint, or %NULL if this endpoint does not require - * acquiring streams before linking them + * acquiring endpoints before linking them */ -WpSiStreamAcquisition * -wp_si_endpoint_get_stream_acquisition (WpSiEndpoint * self) +WpSiEndpointAcquisition * +wp_si_endpoint_get_endpoint_acquisition (WpSiEndpoint * self) { g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), NULL); - g_return_val_if_fail (WP_SI_ENDPOINT_GET_IFACE (self)->get_stream_acquisition, - NULL); + g_return_val_if_fail ( + WP_SI_ENDPOINT_GET_IFACE (self)->get_endpoint_acquisition, NULL); - return WP_SI_ENDPOINT_GET_IFACE (self)->get_stream_acquisition (self); -} - -/** - * WpSiStream: - * - * An interface for session items that provide a PipeWire endpoint stream. - */ -G_DEFINE_INTERFACE (WpSiStream, wp_si_stream, WP_TYPE_SESSION_ITEM) - -static WpProperties * -wp_si_stream_default_get_properties (WpSiStream * self) -{ - return NULL; -} - -static void -wp_si_stream_default_init (WpSiStreamInterface * iface) -{ - iface->get_properties = wp_si_stream_default_get_properties; - - g_signal_new ("stream-properties-changed", G_TYPE_FROM_INTERFACE (iface), - G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); -} - -/** - * wp_si_stream_get_registration_info: (virtual get_registration_info) - * @self: the session item - * - * This should return information that is used for registering the stream, - * as a GVariant tuple of type (sa{ss}) that contains, in order: - * - s: the stream's name - * - a{ss}: additional properties to be added to the list of global properties - * - * Returns: (transfer full): registration info for the stream - */ -GVariant * -wp_si_stream_get_registration_info (WpSiStream * self) -{ - g_return_val_if_fail (WP_IS_SI_STREAM (self), NULL); - g_return_val_if_fail (WP_SI_STREAM_GET_IFACE (self)->get_registration_info, NULL); - - return WP_SI_STREAM_GET_IFACE (self)->get_registration_info (self); -} - -/** - * wp_si_stream_get_properties: (virtual get_properties) - * @self: the session item - * - * Returns: (transfer full) (nullable): the properties of the stream - */ -WpProperties * -wp_si_stream_get_properties (WpSiStream * self) -{ - g_return_val_if_fail (WP_IS_SI_STREAM (self), NULL); - g_return_val_if_fail (WP_SI_STREAM_GET_IFACE (self)->get_properties, NULL); - - return WP_SI_STREAM_GET_IFACE (self)->get_properties (self); -} - -/** - * wp_si_stream_get_parent_endpoint: (virtual get_parent_endpoint) - * @self: the session item - * - * Returns: (transfer full): the endpoint that this stream belongs to - */ -WpSiEndpoint * -wp_si_stream_get_parent_endpoint (WpSiStream * self) -{ - g_return_val_if_fail (WP_IS_SI_STREAM (self), NULL); - g_return_val_if_fail (WP_SI_STREAM_GET_IFACE (self)->get_parent_endpoint, NULL); - - return WP_SI_STREAM_GET_IFACE (self)->get_parent_endpoint (self); + return WP_SI_ENDPOINT_GET_IFACE (self)->get_endpoint_acquisition (self); } /** @@ -264,33 +158,33 @@ wp_si_link_get_properties (WpSiLink * self) } /** - * wp_si_link_get_out_stream: (virtual get_out_stream) + * wp_si_link_get_out_endpoint: (virtual get_out_endpoint) * @self: the session item * - * Returns: (transfer none): the output stream that is linked by this link + * Returns: (transfer none): the output endpoint that is linked by this link */ -WpSiStream * -wp_si_link_get_out_stream (WpSiLink * self) +WpSiEndpoint * +wp_si_link_get_out_endpoint (WpSiLink * self) { g_return_val_if_fail (WP_IS_SI_LINK (self), NULL); - g_return_val_if_fail (WP_SI_LINK_GET_IFACE (self)->get_out_stream, NULL); + g_return_val_if_fail (WP_SI_LINK_GET_IFACE (self)->get_out_endpoint, NULL); - return WP_SI_LINK_GET_IFACE (self)->get_out_stream (self); + return WP_SI_LINK_GET_IFACE (self)->get_out_endpoint (self); } /** - * wp_si_link_get_in_stream: (virtual get_in_stream) + * wp_si_link_get_in_endpoint: (virtual get_in_endpoint) * @self: the session item * - * Returns: (transfer none): the input stream that is linked by this link + * Returns: (transfer none): the input endpoint that is linked by this link */ -WpSiStream * -wp_si_link_get_in_stream (WpSiLink * self) +WpSiEndpoint * +wp_si_link_get_in_endpoint (WpSiLink * self) { g_return_val_if_fail (WP_IS_SI_LINK (self), NULL); - g_return_val_if_fail (WP_SI_LINK_GET_IFACE (self)->get_in_stream, NULL); + g_return_val_if_fail (WP_SI_LINK_GET_IFACE (self)->get_in_endpoint, NULL); - return WP_SI_LINK_GET_IFACE (self)->get_in_stream (self); + return WP_SI_LINK_GET_IFACE (self)->get_in_endpoint (self); } /** @@ -300,8 +194,8 @@ wp_si_link_get_in_stream (WpSiLink * self) * This information is used to create links in the nodes graph. * * This is normally implemented by the same session items that implement - * #WpSiStream. The standard link implementation expects to be able to cast - * a #WpSiStream into a #WpSiPortInfo. + * #WpSiEndpoint. The standard link implementation expects to be able to cast + * a #WpSiEndpoint into a #WpSiPortInfo. */ G_DEFINE_INTERFACE (WpSiPortInfo, wp_si_port_info, WP_TYPE_SESSION_ITEM) @@ -338,15 +232,15 @@ wp_si_port_info_default_init (WpSiPortInfoInterface * iface) * Contexts other than %NULL may only be used internally to ease the * implementation of more complex endpoint relationships. For example, a * #WpSessionItem that is in control of an input (sink) adapter node may - * implement #WpSiStream and #WpSiPortInfo where the %NULL context will return - * the standard input ports and the "monitor" context will return the adapter's - * monitor ports. When linking this stream to another stream, the %NULL context + * implement #WpSiPortInfo where the %NULL context will return the standard + * input ports and the "monitor" context will return the adapter's monitor + * ports. When linking this endpoint to another endpoint, the %NULL context * will always be used, but the item may internally spawn a secondary - * #WpSessionItem that implements the "monitor" endpoint & stream. That - * secondary stream may implement #WpSiPortInfo, chaining calls to the - * #WpSiPortInfo of the original item using the "monitor" context. This way, - * the monitor #WpSessionItem does not need to share control of the underlying - * node; it only proxies calls to satisfy the API. + * #WpSessionItem that implements the "monitor" endpoint. That secondary + * endpoint may implement #WpSiPortInfo, chaining calls to the #WpSiPortInfo + * of the original item using the "monitor" context. This way, the monitor + * #WpSessionItem does not need to share control of the underlying node; it + * only proxies calls to satisfy the API. * * Returns: (transfer full): a #GVariant containing information about the * ports of this item @@ -361,92 +255,93 @@ wp_si_port_info_get_ports (WpSiPortInfo * self, const gchar * context) } /** - * WpSiStreamAcquisition: + * WpSiEndpointAcquisition: * - * This interface provides a way to request a stream for linking before doing - * so. This allows endpoint implementations to apply internal policy rules - * (such as, streams that can only be linked once or mutually exclusive streams). + * This interface provides a way to request an endpoint for linking before doing + * so. This allows endpoint implementations to apply internal policy rules. * - * A #WpSiStreamAcquisition is associated directly with a #WpSiEndpoint via - * wp_si_endpoint_get_stream_acquisition(). In order to allow switching policies, - * it is recommended that endpoint implementations use a separate session item - * to implement this interface and allow replacing it. + * A #WpSiEndpointAcquisition is associated directly with a #WpSiEndpoint via + * wp_si_endpoint_get_endpoint_acquisition(). In order to allow switching + * policies, it is recommended that endpoint implementations use a separate + * session item to implement this interface and allow replacing it. */ -G_DEFINE_INTERFACE (WpSiStreamAcquisition, wp_si_stream_acquisition, +G_DEFINE_INTERFACE (WpSiEndpointAcquisition, wp_si_endpoint_acquisition, WP_TYPE_SESSION_ITEM) static void -wp_si_stream_acquisition_default_init (WpSiStreamAcquisitionInterface * iface) +wp_si_endpoint_acquisition_default_init ( + WpSiEndpointAcquisitionInterface * iface) { } /** - * wp_si_stream_acquisition_acquire: (virtual acquire) + * wp_si_endpoint_acquisition_acquire: (virtual acquire) * @self: the session item - * @acquisitor: the link that is trying to acquire a stream - * @stream: the stream that is being acquired + * @acquisitor: the link that is trying to acquire an endpoint + * @endpoint: the endpoint that is being acquired * @callback: (scope async): the callback to call when the operation is done * @data: (closure): user data for @callback * - * Acquires the @stream for linking by @acquisitor. + * Acquires the @endpoint for linking by @acquisitor. * * When a link is not allowed by policy, this operation should return * an error. * * When a link needs to be delayed for a short amount of time (ex. to apply - * a fade out effect on another stream), this operation should finish with a + * a fade out effect on another endpoint), this operation should finish with a * delay. It is safe to assume that after this operation completes, - * the stream will be linked immediately. + * the endpoint will be linked immediately. */ void -wp_si_stream_acquisition_acquire (WpSiStreamAcquisition * self, - WpSiLink * acquisitor, WpSiStream * stream, +wp_si_endpoint_acquisition_acquire (WpSiEndpointAcquisition * self, + WpSiLink * acquisitor, WpSiEndpoint * endpoint, GAsyncReadyCallback callback, gpointer data) { - g_return_if_fail (WP_IS_SI_STREAM_ACQUISITION (self)); - g_return_if_fail (WP_SI_STREAM_ACQUISITION_GET_IFACE (self)->acquire); + g_return_if_fail (WP_IS_SI_ENDPOINT_ACQUISITION (self)); + g_return_if_fail (WP_SI_ENDPOINT_ACQUISITION_GET_IFACE (self)->acquire); - WP_SI_STREAM_ACQUISITION_GET_IFACE (self)->acquire (self, acquisitor, stream, - callback, data); + WP_SI_ENDPOINT_ACQUISITION_GET_IFACE (self)->acquire (self, acquisitor, + endpoint, callback, data); } /** - * wp_si_stream_acquisition_acquire_finish: (virtual acquire_finish) + * wp_si_endpoint_acquisition_acquire_finish: (virtual acquire_finish) * @self: the session item * @res: the async result * @error: (out) (optional): the operation's error, if it occurred * - * Finishes the operation started by wp_si_stream_acquisition_acquire(). + * Finishes the operation started by wp_si_endpoint_acquisition_acquire(). * This is meant to be called in the callback that was passed to that method. * * Returns: %TRUE on success, %FALSE if there was an error */ gboolean -wp_si_stream_acquisition_acquire_finish (WpSiStreamAcquisition * self, +wp_si_endpoint_acquisition_acquire_finish (WpSiEndpointAcquisition * self, GAsyncResult * res, GError ** error) { - g_return_val_if_fail (WP_IS_SI_STREAM_ACQUISITION (self), FALSE); + g_return_val_if_fail (WP_IS_SI_ENDPOINT_ACQUISITION (self), FALSE); g_return_val_if_fail ( - WP_SI_STREAM_ACQUISITION_GET_IFACE (self)->acquire_finish, FALSE); + WP_SI_ENDPOINT_ACQUISITION_GET_IFACE (self)->acquire_finish, FALSE); - return WP_SI_STREAM_ACQUISITION_GET_IFACE (self)->acquire_finish (self, res, + return WP_SI_ENDPOINT_ACQUISITION_GET_IFACE (self)->acquire_finish (self, res, error); } /** - * wp_si_stream_acquisition_release: (virtual release) + * wp_si_endpoint_acquisition_release: (virtual release) * @self: the session item - * @acquisitor: the link that had previously acquired the stream - * @stream: the stream that is being released + * @acquisitor: the link that had previously acquired the endpoint + * @endpoint: the endpoint that is being released * - * Releases the @stream, which means that it is being unlinked. + * Releases the @endpoint, which means that it is being unlinked. */ void -wp_si_stream_acquisition_release (WpSiStreamAcquisition * self, - WpSiLink * acquisitor, WpSiStream * stream) +wp_si_endpoint_acquisition_release (WpSiEndpointAcquisition * self, + WpSiLink * acquisitor, WpSiEndpoint * endpoint) { - g_return_if_fail (WP_IS_SI_STREAM_ACQUISITION (self)); - g_return_if_fail (WP_SI_STREAM_ACQUISITION_GET_IFACE (self)->release); + g_return_if_fail (WP_IS_SI_ENDPOINT_ACQUISITION (self)); + g_return_if_fail (WP_SI_ENDPOINT_ACQUISITION_GET_IFACE (self)->release); - WP_SI_STREAM_ACQUISITION_GET_IFACE (self)->release (self, acquisitor, stream); + WP_SI_ENDPOINT_ACQUISITION_GET_IFACE (self)->release (self, acquisitor, + endpoint); } diff --git a/lib/wp/si-interfaces.h b/lib/wp/si-interfaces.h index 3130db0a..ba030db7 100644 --- a/lib/wp/si-interfaces.h +++ b/lib/wp/si-interfaces.h @@ -16,8 +16,7 @@ G_BEGIN_DECLS -typedef struct _WpSiStream WpSiStream; -typedef struct _WpSiStreamAcquisition WpSiStreamAcquisition; +typedef struct _WpSiEndpointAcquisition WpSiEndpointAcquisition; /** * WP_TYPE_SI_ENDPOINT: @@ -36,10 +35,7 @@ struct _WpSiEndpointInterface GVariant * (*get_registration_info) (WpSiEndpoint * self); WpProperties * (*get_properties) (WpSiEndpoint * self); - guint (*get_n_streams) (WpSiEndpoint * self); - WpSiStream * (*get_stream) (WpSiEndpoint * self, guint index); - - WpSiStreamAcquisition * (*get_stream_acquisition) (WpSiEndpoint * self); + WpSiEndpointAcquisition * (*get_endpoint_acquisition) (WpSiEndpoint * self); }; WP_API @@ -49,42 +45,8 @@ WP_API WpProperties * wp_si_endpoint_get_properties (WpSiEndpoint * self); WP_API -guint wp_si_endpoint_get_n_streams (WpSiEndpoint * self); - -WP_API -WpSiStream * wp_si_endpoint_get_stream (WpSiEndpoint * self, guint index); - -WP_API -WpSiStreamAcquisition * wp_si_endpoint_get_stream_acquisition (WpSiEndpoint * self); - -/** - * WP_TYPE_SI_STREAM: - * - * The #WpSiStream #GType - */ -#define WP_TYPE_SI_STREAM (wp_si_stream_get_type ()) -WP_API -G_DECLARE_INTERFACE (WpSiStream, wp_si_stream, - WP, SI_STREAM, WpSessionItem) - -struct _WpSiStreamInterface -{ - GTypeInterface interface; - - GVariant * (*get_registration_info) (WpSiStream * self); - WpProperties * (*get_properties) (WpSiStream * self); - - WpSiEndpoint * (*get_parent_endpoint) (WpSiStream * self); -}; - -WP_API -GVariant * wp_si_stream_get_registration_info (WpSiStream * self); - -WP_API -WpProperties * wp_si_stream_get_properties (WpSiStream * self); - -WP_API -WpSiEndpoint * wp_si_stream_get_parent_endpoint (WpSiStream * self); +WpSiEndpointAcquisition * wp_si_endpoint_get_endpoint_acquisition ( + WpSiEndpoint * self); /** * WP_TYPE_SI_LINK: @@ -103,8 +65,8 @@ struct _WpSiLinkInterface GVariant * (*get_registration_info) (WpSiLink * self); WpProperties * (*get_properties) (WpSiLink * self); - WpSiStream * (*get_out_stream) (WpSiLink * self); - WpSiStream * (*get_in_stream) (WpSiLink * self); + WpSiEndpoint * (*get_out_endpoint) (WpSiLink * self); + WpSiEndpoint * (*get_in_endpoint) (WpSiLink * self); }; WP_API @@ -114,10 +76,10 @@ WP_API WpProperties * wp_si_link_get_properties (WpSiLink * self); WP_API -WpSiStream * wp_si_link_get_out_stream (WpSiLink * self); +WpSiEndpoint * wp_si_link_get_out_endpoint (WpSiLink * self); WP_API -WpSiStream * wp_si_link_get_in_stream (WpSiLink * self); +WpSiEndpoint * wp_si_link_get_in_endpoint (WpSiLink * self); /** * WP_TYPE_SI_PORT_INFO: @@ -141,40 +103,40 @@ GVariant * wp_si_port_info_get_ports (WpSiPortInfo * self, const gchar * context); /** - * WP_TYPE_SI_STREAM_ACQUISITION: + * WP_TYPE_SI_ENDPOINT_ACQUISITION: * - * The #WpSiStreamAcquisition #GType + * The #WpSiEndpointAcquisition #GType */ -#define WP_TYPE_SI_STREAM_ACQUISITION (wp_si_stream_acquisition_get_type ()) +#define WP_TYPE_SI_ENDPOINT_ACQUISITION (wp_si_endpoint_acquisition_get_type ()) WP_API -G_DECLARE_INTERFACE (WpSiStreamAcquisition, wp_si_stream_acquisition, - WP, SI_STREAM_ACQUISITION, WpSessionItem) +G_DECLARE_INTERFACE (WpSiEndpointAcquisition, wp_si_endpoint_acquisition, + WP, SI_ENDPOINT_ACQUISITION, WpSessionItem) -struct _WpSiStreamAcquisitionInterface +struct _WpSiEndpointAcquisitionInterface { GTypeInterface interface; - void (*acquire) (WpSiStreamAcquisition * self, WpSiLink * acquisitor, - WpSiStream * stream, GAsyncReadyCallback callback, gpointer data); - gboolean (*acquire_finish) (WpSiStreamAcquisition * self, + void (*acquire) (WpSiEndpointAcquisition * self, WpSiLink * acquisitor, + WpSiEndpoint * endpoint, GAsyncReadyCallback callback, gpointer data); + gboolean (*acquire_finish) (WpSiEndpointAcquisition * self, GAsyncResult * res, GError ** error); - void (*release) (WpSiStreamAcquisition * self, WpSiLink * acquisitor, - WpSiStream * stream); + void (*release) (WpSiEndpointAcquisition * self, WpSiLink * acquisitor, + WpSiEndpoint * endpoint); }; WP_API -void wp_si_stream_acquisition_acquire (WpSiStreamAcquisition * self, - WpSiLink * acquisitor, WpSiStream * stream, +void wp_si_endpoint_acquisition_acquire (WpSiEndpointAcquisition * self, + WpSiLink * acquisitor, WpSiEndpoint * endpoint, GAsyncReadyCallback callback, gpointer data); WP_API -gboolean wp_si_stream_acquisition_acquire_finish (WpSiStreamAcquisition * self, - GAsyncResult * res, GError ** error); +gboolean wp_si_endpoint_acquisition_acquire_finish ( + WpSiEndpointAcquisition * self, GAsyncResult * res, GError ** error); WP_API -void wp_si_stream_acquisition_release (WpSiStreamAcquisition * self, - WpSiLink * acquisitor, WpSiStream * stream); +void wp_si_endpoint_acquisition_release (WpSiEndpointAcquisition * self, + WpSiLink * acquisitor, WpSiEndpoint * endpoint); G_END_DECLS diff --git a/lib/wp/wp.c b/lib/wp/wp.c index 69aefa9b..94749059 100644 --- a/lib/wp/wp.c +++ b/lib/wp/wp.c @@ -71,7 +71,6 @@ wp_init (WpInitFlags flags) g_type_ensure (WP_TYPE_DEVICE); g_type_ensure (WP_TYPE_ENDPOINT); g_type_ensure (WP_TYPE_ENDPOINT_LINK); - g_type_ensure (WP_TYPE_ENDPOINT_STREAM); g_type_ensure (WP_TYPE_LINK); g_type_ensure (WP_TYPE_METADATA); g_type_ensure (WP_TYPE_NODE); diff --git a/lib/wp/wp.h b/lib/wp/wp.h index a94072d1..0ac1667b 100644 --- a/lib/wp/wp.h +++ b/lib/wp/wp.h @@ -16,7 +16,6 @@ #include "device.h" #include "endpoint.h" #include "endpoint-link.h" -#include "endpoint-stream.h" #include "error.h" #include "global-proxy.h" #include "iterator.h" diff --git a/modules/meson.build b/modules/meson.build index dbe2aa38..c7811016 100644 --- a/modules/meson.build +++ b/modules/meson.build @@ -112,17 +112,6 @@ shared_library( dependencies : [wp_dep, pipewire_dep], ) -shared_library( - 'wireplumber-module-si-fake-stream', - [ - 'module-si-fake-stream.c', - ], - c_args : [common_c_args, '-DG_LOG_DOMAIN="m-si-fake-stream"'], - install : true, - install_dir : wireplumber_module_dir, - dependencies : [wp_dep, pipewire_dep], -) - shared_library( 'wireplumber-module-si-simple-node-endpoint', [ @@ -134,17 +123,6 @@ shared_library( dependencies : [wp_dep, pipewire_dep], ) -shared_library( - 'wireplumber-module-si-audio-softdsp-endpoint', - [ - 'module-si-audio-softdsp-endpoint.c', - ], - c_args : [common_c_args, '-DG_LOG_DOMAIN="m-si-audio-softdsp-endpoint"'], - install : true, - install_dir : wireplumber_module_dir, - dependencies : [wp_dep, pipewire_dep], -) - shared_library( 'wireplumber-module-si-monitor-endpoint', [ @@ -156,18 +134,6 @@ shared_library( dependencies : [wp_dep, pipewire_dep], ) -shared_library( - 'wireplumber-module-si-bluez5-endpoint', - [ - 'module-si-bluez5-endpoint.c', - ], - c_args : [common_c_args, '-DG_LOG_DOMAIN="m-si-bluez5-endpoint"'], - install : true, - install_dir : wireplumber_module_dir, - dependencies : [wp_dep, pipewire_dep], -) - - shared_library( 'wireplumber-module-si-standard-link', [ diff --git a/modules/module-lua-scripting/api.c b/modules/module-lua-scripting/api.c index c7246331..2609d480 100644 --- a/modules/module-lua-scripting/api.c +++ b/modules/module-lua-scripting/api.c @@ -754,22 +754,6 @@ static const luaL_Reg impl_session_methods[] = { /* WpEndpoint */ -static int -endpoint_get_n_streams (lua_State *L) -{ - WpEndpoint *ep = wplua_checkobject (L, 1, WP_TYPE_ENDPOINT); - lua_pushnumber (L, wp_endpoint_get_n_streams (ep)); - return 1; -} - -static int -endpoint_iterate_streams (lua_State *L) -{ - WpEndpoint *ep = wplua_checkobject (L, 1, WP_TYPE_ENDPOINT); - WpIterator *it = wp_endpoint_new_streams_iterator (ep); - return push_wpiterator (L, it); -} - static int endpoint_create_link (lua_State *L) { @@ -781,8 +765,6 @@ endpoint_create_link (lua_State *L) } static const luaL_Reg endpoint_methods[] = { - { "get_n_streams", endpoint_get_n_streams }, - { "iterate_streams", endpoint_iterate_streams }, { "create_link", endpoint_create_link }, { NULL, NULL } }; @@ -817,16 +799,13 @@ static int endpoint_link_get_linked_object_ids (lua_State *L) { WpEndpointLink *eplink = wplua_checkobject (L, 1, WP_TYPE_ENDPOINT_LINK); - guint32 output_endpoint, output_stream; - guint32 input_endpoint, input_stream; - wp_endpoint_link_get_linked_object_ids (eplink, - &output_endpoint, &output_stream, - &input_endpoint, &input_stream); + guint32 output_endpoint; + guint32 input_endpoint; + wp_endpoint_link_get_linked_object_ids (eplink, &output_endpoint, + &input_endpoint); lua_pushinteger (L, output_endpoint); - lua_pushinteger (L, output_stream); lua_pushinteger (L, input_endpoint); - lua_pushinteger (L, input_stream); - return 4; + return 2; } static const luaL_Reg endpoint_link_methods[] = { diff --git a/modules/module-si-adapter.c b/modules/module-si-adapter.c index ad91e510..5dbf4717 100644 --- a/modules/module-si-adapter.c +++ b/modules/module-si-adapter.c @@ -42,13 +42,11 @@ struct _WpSiAdapter }; static void si_adapter_endpoint_init (WpSiEndpointInterface * iface); -static void si_adapter_stream_init (WpSiStreamInterface * iface); static void si_adapter_port_info_init (WpSiPortInfoInterface * iface); G_DECLARE_FINAL_TYPE(WpSiAdapter, si_adapter, WP, SI_ADAPTER, WpSessionItem) G_DEFINE_TYPE_WITH_CODE (WpSiAdapter, si_adapter, WP_TYPE_SESSION_ITEM, G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, si_adapter_endpoint_init) - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_STREAM, si_adapter_stream_init) G_IMPLEMENT_INTERFACE (WP_TYPE_SI_PORT_INFO, si_adapter_port_info_init)) static void @@ -431,62 +429,11 @@ si_adapter_get_properties (WpSiEndpoint * item) return result; } -static guint -si_adapter_get_n_streams (WpSiEndpoint * item) -{ - return 1; -} - -static WpSiStream * -si_adapter_get_stream (WpSiEndpoint * item, guint index) -{ - g_return_val_if_fail (index == 0, NULL); - return WP_SI_STREAM (item); -} - static void si_adapter_endpoint_init (WpSiEndpointInterface * iface) { iface->get_registration_info = si_adapter_get_registration_info; iface->get_properties = si_adapter_get_properties; - iface->get_n_streams = si_adapter_get_n_streams; - iface->get_stream = si_adapter_get_stream; -} - -static GVariant * -si_adapter_get_stream_registration_info (WpSiStream * stream) -{ - WpSiAdapter *self = WP_SI_ADAPTER (stream); - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("(sa{ss})")); - g_variant_builder_add (&b, "s", self->name); - g_variant_builder_add (&b, "a{ss}", NULL); - - return g_variant_builder_end (&b); -} - -static WpProperties * -si_adapter_get_stream_properties (WpSiStream * self) -{ - return NULL; -} - -static WpSiEndpoint * -si_adapter_get_stream_parent_endpoint (WpSiStream * self) -{ - WpSessionItem *parent = wp_session_item_get_parent (WP_SESSION_ITEM (self)); - if (!parent) - parent = g_object_ref (WP_SESSION_ITEM (self)); - return WP_SI_ENDPOINT (parent); -} - -static void -si_adapter_stream_init (WpSiStreamInterface * iface) -{ - iface->get_registration_info = si_adapter_get_stream_registration_info; - iface->get_properties = si_adapter_get_stream_properties; - iface->get_parent_endpoint = si_adapter_get_stream_parent_endpoint; } static GVariant * diff --git a/modules/module-si-audio-softdsp-endpoint.c b/modules/module-si-audio-softdsp-endpoint.c deleted file mode 100644 index 25cefa96..00000000 --- a/modules/module-si-audio-softdsp-endpoint.c +++ /dev/null @@ -1,309 +0,0 @@ -/* WirePlumber - * - * Copyright © 2020 Collabora Ltd. - * @author Julian Bouzas - * - * SPDX-License-Identifier: MIT - */ - -#include -#include - -enum { - STEP_VERIFY_CONFIG = WP_TRANSITION_STEP_CUSTOM_START, - STEP_ACTIVATE_ADAPTER, - STEP_ACTIVATE_STREAMS, -}; - -struct _WpSiAudioSoftdspEndpoint -{ - WpSessionBin parent; - - /* configuration */ - WpSessionItem *adapter; - - guint activated_streams; -}; - -static void si_audio_softdsp_endpoint_endpoint_init (WpSiEndpointInterface * iface); - -G_DECLARE_FINAL_TYPE(WpSiAudioSoftdspEndpoint, si_audio_softdsp_endpoint, - WP, SI_AUDIO_SOFTDSP_ENDPOINT, WpSessionBin) -G_DEFINE_TYPE_WITH_CODE (WpSiAudioSoftdspEndpoint, si_audio_softdsp_endpoint, WP_TYPE_SESSION_BIN, - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, si_audio_softdsp_endpoint_endpoint_init)) - -static GVariant * -si_audio_softdsp_endpoint_get_registration_info (WpSiEndpoint * item) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - - return wp_si_endpoint_get_registration_info (WP_SI_ENDPOINT (self->adapter)); -} - -static WpProperties * -si_audio_softdsp_endpoint_get_properties (WpSiEndpoint * item) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - - return wp_si_endpoint_get_properties (WP_SI_ENDPOINT (self->adapter)); -} - -static guint -si_audio_softdsp_endpoint_get_n_streams (WpSiEndpoint * item) -{ - guint n_streams = wp_session_bin_get_n_children (WP_SESSION_BIN (item)); - /* n_streams includes the adapter; remove it, unless it's the only one */ - return (n_streams > 1) ? (n_streams - 1) : 1; -} - -static WpSiStream * -si_audio_softdsp_endpoint_get_stream (WpSiEndpoint * item, guint index) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - g_autoptr (WpIterator) it = - wp_session_bin_new_iterator (WP_SESSION_BIN (self)); - g_auto (GValue) val = G_VALUE_INIT; - - if (wp_session_bin_get_n_children (WP_SESSION_BIN (item)) == 1) - return WP_SI_STREAM (self->adapter); - - /* TODO: do not asume the items are always sorted */ - guint i = 0; - for (; wp_iterator_next (it, &val); g_value_unset (&val)) { - if (index + 1 == i) - return g_value_get_object (&val); - i++; - } - - return NULL; -} - -static void -si_audio_softdsp_endpoint_endpoint_init (WpSiEndpointInterface * iface) -{ - iface->get_registration_info = si_audio_softdsp_endpoint_get_registration_info; - iface->get_properties = si_audio_softdsp_endpoint_get_properties; - iface->get_n_streams = si_audio_softdsp_endpoint_get_n_streams; - iface->get_stream = si_audio_softdsp_endpoint_get_stream; -} - -static void -si_audio_softdsp_endpoint_init (WpSiAudioSoftdspEndpoint * self) -{ - self->activated_streams = 0; -} - -static void -si_audio_softdsp_endpoint_reset (WpSessionItem * item) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - - /* unexport & deactivate first */ - WP_SESSION_ITEM_CLASS (si_audio_softdsp_endpoint_parent_class)->reset (item); - - g_clear_object (&self->adapter); - self->activated_streams = 0; - - wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED); -} - -static gpointer -si_audio_softdsp_endpoint_get_associated_proxy (WpSessionItem * item, - GType proxy_type) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - - if (proxy_type == WP_TYPE_NODE) - return wp_session_item_get_associated_proxy (self->adapter, proxy_type); - - return WP_SESSION_ITEM_CLASS ( - si_audio_softdsp_endpoint_parent_class)->get_associated_proxy ( - item, proxy_type); -} - -static gboolean -si_audio_softdsp_endpoint_configure (WpSessionItem * item, GVariant * args) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - guint64 adapter_i; - - if (wp_session_item_get_flags (item) & (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE)) - return FALSE; - - /* reset previous config */ - si_audio_softdsp_endpoint_reset (WP_SESSION_ITEM (self)); - - /* get the adapter */ - if (!g_variant_lookup (args, "adapter", "t", &adapter_i)) - return FALSE; - g_return_val_if_fail (WP_IS_SI_ENDPOINT (GUINT_TO_POINTER (adapter_i)), FALSE); - self->adapter = g_object_ref (GUINT_TO_POINTER (adapter_i)); - - /* add the adapter into the bin */ - wp_session_bin_add (WP_SESSION_BIN (self), g_object_ref (self->adapter)); - - wp_session_item_set_flag (item, WP_SI_FLAG_CONFIGURED); - return TRUE; -} - -static GVariant * -si_audio_softdsp_endpoint_get_configuration (WpSessionItem * item) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - GVariantBuilder b; - - /* Set the properties */ - g_variant_builder_init (&b, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&b, "{sv}", - "adapter", g_variant_new_uint64 ((guint64) self->adapter)); - return g_variant_builder_end (&b); -} - -static guint -si_audio_softdsp_endpoint_activate_get_next_step (WpSessionItem * item, - WpTransition * transition, guint step) -{ - WpSiAudioSoftdspEndpoint *self = wp_transition_get_source_object (transition); - - switch (step) { - case WP_TRANSITION_STEP_NONE: - return STEP_VERIFY_CONFIG; - - case STEP_VERIFY_CONFIG: - return STEP_ACTIVATE_ADAPTER; - - case STEP_ACTIVATE_ADAPTER: - if (wp_session_bin_get_n_children (WP_SESSION_BIN (self)) > 1) - return STEP_ACTIVATE_STREAMS; - else - return WP_TRANSITION_STEP_NONE; - - case STEP_ACTIVATE_STREAMS: - if ((self->activated_streams + 1) < - wp_session_bin_get_n_children (WP_SESSION_BIN (self))) - return STEP_ACTIVATE_STREAMS; - else - return WP_TRANSITION_STEP_NONE; - - default: - return WP_TRANSITION_STEP_ERROR; - } -} - -static void -on_adapter_activated (WpSessionItem * item, GAsyncResult * res, - WpTransition *transition) -{ - g_autoptr (GError) error = NULL; - if (!wp_session_item_activate_finish (item, res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - wp_transition_advance (transition); -} - -static void -on_convert_activated (WpSessionItem * item, GAsyncResult * res, - WpTransition *transition) -{ - WpSiAudioSoftdspEndpoint *self = wp_transition_get_source_object (transition); - g_autoptr (GError) error = NULL; - - if (!wp_session_item_activate_finish (item, res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - self->activated_streams++; - wp_transition_advance (transition); -} - -static void -si_audio_softdsp_endpoint_activate_execute_step (WpSessionItem * item, - WpTransition * transition, guint step) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - - switch (step) { - case STEP_VERIFY_CONFIG: - if (G_UNLIKELY (!(wp_session_item_get_flags (item) & WP_SI_FLAG_CONFIGURED))) { - wp_transition_return_error (transition, - g_error_new (WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVARIANT, - "si-audio-softdsp-endpoint: cannot activate item without it " - "being configured first")); - } - wp_transition_advance (transition); - break; - - case STEP_ACTIVATE_ADAPTER: - g_return_if_fail (self->activated_streams == 0); - wp_session_item_activate (self->adapter, - (GAsyncReadyCallback) on_adapter_activated, transition); - break; - - case STEP_ACTIVATE_STREAMS: - { - g_autoptr (WpIterator) it = - wp_session_bin_new_iterator (WP_SESSION_BIN (self)); - g_auto (GValue) val = G_VALUE_INIT; - for (; wp_iterator_next (it, &val); g_value_unset (&val)) { - WpSessionItem *item = g_value_get_object (&val); - if (item == self->adapter) - continue; - wp_session_item_activate (item, - (GAsyncReadyCallback) on_convert_activated, transition); - } - break; - } - - default: - g_return_if_reached (); - } -} - -static void -si_audio_softdsp_endpoint_activate_rollback (WpSessionItem * item) -{ - WpSiAudioSoftdspEndpoint *self = WP_SI_AUDIO_SOFTDSP_ENDPOINT (item); - g_autoptr (WpIterator) it = - wp_session_bin_new_iterator (WP_SESSION_BIN (self)); - g_auto (GValue) val = G_VALUE_INIT; - - /* deactivate all items */ - for (; wp_iterator_next (it, &val); g_value_unset (&val)) - wp_session_item_deactivate (g_value_get_object (&val)); - - self->activated_streams = 0; -} - -static void -si_audio_softdsp_endpoint_class_init (WpSiAudioSoftdspEndpointClass * klass) -{ - WpSessionItemClass *si_class = (WpSessionItemClass *) klass; - - si_class->reset = si_audio_softdsp_endpoint_reset; - si_class->get_associated_proxy = si_audio_softdsp_endpoint_get_associated_proxy; - si_class->configure = si_audio_softdsp_endpoint_configure; - si_class->get_configuration = si_audio_softdsp_endpoint_get_configuration; - si_class->activate_get_next_step = - si_audio_softdsp_endpoint_activate_get_next_step; - si_class->activate_execute_step = - si_audio_softdsp_endpoint_activate_execute_step; - si_class->activate_rollback = si_audio_softdsp_endpoint_activate_rollback; -} - -WP_PLUGIN_EXPORT gboolean -wireplumber__module_init (WpCore * core, GVariant * args, GError ** error) -{ - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("a(ssymv)")); - g_variant_builder_add (&b, "(ssymv)", "adapter", "t", - WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - - wp_si_factory_register (core, wp_si_factory_new_simple ( - "si-audio-softdsp-endpoint", si_audio_softdsp_endpoint_get_type (), - g_variant_builder_end (&b))); - return TRUE; -} diff --git a/modules/module-si-bluez5-endpoint.c b/modules/module-si-bluez5-endpoint.c deleted file mode 100644 index fae710ff..00000000 --- a/modules/module-si-bluez5-endpoint.c +++ /dev/null @@ -1,573 +0,0 @@ -/* WirePlumber - * - * Copyright © 2020 Collabora Ltd. - * @author Julian Bouzas - * - * SPDX-License-Identifier: MIT - */ - -#include -#include -#include - -#include - -enum { - STEP_VERIFY_CONFIG = WP_TRANSITION_STEP_CUSTOM_START, - STEP_ACTIVATE_STREAM_A2DP, - STEP_ACTIVATE_STREAM_SCO, -}; - -enum { - STREAM_ID_A2DP = 0, - STREAM_ID_SCO = 1, -}; - -static guint32 -get_stream_id_from_profile_name (const gchar *profile_name) { - if (g_str_has_prefix (profile_name, "a2dp")) - return STREAM_ID_A2DP; - else if (g_str_has_prefix (profile_name, "hsp") || - g_str_has_prefix (profile_name, "hfp")) - return STREAM_ID_SCO; - g_return_val_if_reached (SPA_ID_INVALID); -} - -static gint -get_profile_id_from_stream_id (guint32 stream_id) -{ - switch (stream_id) { - case STREAM_ID_A2DP: - return 1; - case STREAM_ID_SCO: - return 2; - default: - break; - } - g_return_val_if_reached (0); -} - -struct _WpSiBluez5Endpoint -{ - WpSessionBin parent; - - /* configuration */ - WpDevice *device; - WpDirection direction; - WpSessionItem *streams[2]; - guint priority; - guint32 stream_id; - gchar name[96]; - gboolean control_port; - gboolean monitor; - - gint64 last_switch; -}; - -static void si_bluez5_endpoint_endpoint_init (WpSiEndpointInterface * iface); -static void si_bluez5_endpoint_stream_acquisition_init (WpSiStreamAcquisitionInterface * iface); - -G_DECLARE_FINAL_TYPE(WpSiBluez5Endpoint, si_bluez5_endpoint, - WP, SI_BLUEZ5_ENDPOINT, WpSessionBin) -G_DEFINE_TYPE_WITH_CODE (WpSiBluez5Endpoint, si_bluez5_endpoint, WP_TYPE_SESSION_BIN, - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, si_bluez5_endpoint_endpoint_init) - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_STREAM_ACQUISITION, si_bluez5_endpoint_stream_acquisition_init)) - -static void -si_bluez5_endpoint_init (WpSiBluez5Endpoint * self) -{ -} - -static void -si_bluez5_endpoint_reset (WpSessionItem * item) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - - /* unexport & deactivate first */ - WP_SESSION_ITEM_CLASS (si_bluez5_endpoint_parent_class)->reset (item); - - g_clear_object (&self->streams[STREAM_ID_A2DP]); - g_clear_object (&self->streams[STREAM_ID_SCO]); - self->direction = WP_DIRECTION_INPUT; - self->stream_id = 0; - self->name[0] = '\0'; - self->control_port = FALSE; - self->monitor = FALSE; - - wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED); -} - -static gpointer -si_bluez5_endpoint_get_associated_proxy (WpSessionItem * item, GType proxy_type) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - - if (proxy_type == WP_TYPE_NODE) { - if (self->streams[STREAM_ID_A2DP]) - return wp_session_item_get_associated_proxy ( - self->streams[STREAM_ID_A2DP], proxy_type); - if (self->streams[STREAM_ID_SCO]) - return wp_session_item_get_associated_proxy ( - self->streams[STREAM_ID_SCO], proxy_type); - return NULL; - } - - return WP_SESSION_ITEM_CLASS (si_bluez5_endpoint_parent_class)-> - get_associated_proxy (item, proxy_type); -} - -static GVariant * -si_bluez5_endpoint_get_configuration (WpSessionItem * item) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - g_autoptr (WpNode) node = NULL; - GVariantBuilder b; - - /* Get the bluez5 node */ - if (self->streams[self->stream_id]) - node = wp_session_item_get_associated_proxy (self->streams[self->stream_id], - WP_TYPE_NODE); - - /* Set the properties */ - g_variant_builder_init (&b, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&b, "{sv}", "device", - g_variant_new_uint64 ((guint64) self->device)); - g_variant_builder_add (&b, "{sv}", "name", - g_variant_new_string (self->name)); - g_variant_builder_add (&b, "{sv}", "direction", - g_variant_new_uint32 (self->direction)); - g_variant_builder_add (&b, "{sv}", "s2dp-stream", - g_variant_new_boolean (self->streams[STREAM_ID_A2DP] != NULL)); - g_variant_builder_add (&b, "{sv}", "sco-stream", - g_variant_new_boolean (self->streams[STREAM_ID_SCO] != NULL)); - g_variant_builder_add (&b, "{sv}", "node", - g_variant_new_uint64 ((guint64) node)); - g_variant_builder_add (&b, "{sv}", "priority", - g_variant_new_uint32 (self->priority)); - g_variant_builder_add (&b, "{sv}", "enable-control-port", - g_variant_new_boolean (self->control_port)); - g_variant_builder_add (&b, "{sv}", "enable-monitor", - g_variant_new_boolean (self->monitor)); - return g_variant_builder_end (&b); -} - -static void -si_bluez5_endpoint_add_stream (WpSiBluez5Endpoint * self, guint32 stream_id, - const gchar *name, WpNode *node) -{ - g_autoptr (WpCore) core = wp_object_get_core (WP_OBJECT (self->device)); - g_auto (GVariantBuilder) b = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); - - /* Bluez5 stream or Fake stream */ - if (self->stream_id == stream_id && node) { - self->streams[stream_id] = wp_session_item_make (core, "si-adapter"); - g_variant_builder_add (&b, "{sv}", "node", - g_variant_new_uint64 ((guint64) node)); - g_variant_builder_add (&b, "{sv}", "name", - g_variant_new_string (name)); - g_variant_builder_add (&b, "{sv}", "enable-control-port", - g_variant_new_boolean (self->control_port)); - g_variant_builder_add (&b, "{sv}", "enable-monitor", - g_variant_new_boolean (self->monitor)); - } - else { - self->streams[stream_id] = wp_session_item_make (core, "si-fake-stream"); - g_variant_builder_add (&b, "{sv}", "name", - g_variant_new_string (name)); - } - - /* Configure */ - wp_session_item_configure (self->streams[stream_id], - g_variant_builder_end (&b)); - - /* Add stream to the bin */ - wp_session_bin_add (WP_SESSION_BIN (self), - g_object_ref (self->streams[stream_id])); -} - -static gboolean -si_bluez5_endpoint_configure (WpSessionItem * item, GVariant * args) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - guint64 device_i, node_i; - const gchar *name; - WpNode *node = NULL; - gboolean a2dp_stream = FALSE, sco_stream = FALSE; - - if (wp_session_item_get_flags (item) & (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE)) - return FALSE; - - /* reset previous config */ - si_bluez5_endpoint_reset (WP_SESSION_ITEM (self)); - - /* get the device */ - if (!g_variant_lookup (args, "device", "t", &device_i)) - return FALSE; - g_return_val_if_fail (WP_IS_DEVICE (GUINT_TO_POINTER (device_i)), FALSE); - self->device = g_object_ref (GUINT_TO_POINTER (device_i)); - - /* get the name */ - if (!g_variant_lookup (args, "name", "&s", &name)) - return FALSE; - strncpy (self->name, name, sizeof (self->name) - 1); - - /* get the node */ - if (g_variant_lookup (args, "node", "t", &node_i)) - node = GUINT_TO_POINTER (node_i); - - /* get the direction */ - if (node) { - const gchar *media_class = wp_pipewire_object_get_property ( - WP_PIPEWIRE_OBJECT (node), PW_KEY_MEDIA_CLASS); - self->direction = g_strcmp0 (media_class, "Audio/Sink") == 0 ? - WP_DIRECTION_INPUT : WP_DIRECTION_OUTPUT; - } else { - if (!g_variant_lookup (args, "direction", "u", &self->direction)) { - wp_warning_object (self, "direction not specified"); - return FALSE; - } - } - - /* get the a2dp-stream value */ - if (!g_variant_lookup (args, "a2dp-stream", "b", &a2dp_stream)) - return FALSE; - if (!g_variant_lookup (args, "sco-stream", "b", &sco_stream)) - return FALSE; - if (!a2dp_stream && !sco_stream) - return FALSE; - - /* get priority, control-port and monitor */ - g_variant_lookup (args, "priority", "b", &self->priority); - g_variant_lookup (args, "enable-control-port", "b", &self->control_port); - g_variant_lookup (args, "enable-monitor", "b", &self->monitor); - - /* get the current stream id */ - if (node) { - self->stream_id = get_stream_id_from_profile_name ( - wp_pipewire_object_get_property (WP_PIPEWIRE_OBJECT (node), - SPA_KEY_API_BLUEZ5_PROFILE)); - } else { - /* Otherwise, the device is set with the oposite profile */ - if (a2dp_stream && !sco_stream) - self->stream_id = STREAM_ID_SCO; - else if (sco_stream && !a2dp_stream) - self->stream_id = STREAM_ID_A2DP; - else - return FALSE; - } - - /* create the streams and add them into the bin */ - if (a2dp_stream) - si_bluez5_endpoint_add_stream (self, STREAM_ID_A2DP, "Multimedia", node); - if (sco_stream) - si_bluez5_endpoint_add_stream (self, STREAM_ID_SCO, "Call", node); - - /* update last profile switch time */ - self->last_switch = g_get_monotonic_time (); - - wp_session_item_set_flag (item, WP_SI_FLAG_CONFIGURED); - return TRUE; -} - -static guint -si_bluez5_endpoint_activate_get_next_step (WpSessionItem * item, - WpTransition * transition, guint step) -{ - switch (step) { - case WP_TRANSITION_STEP_NONE: - return STEP_VERIFY_CONFIG; - - case STEP_VERIFY_CONFIG: - return STEP_ACTIVATE_STREAM_A2DP; - - case STEP_ACTIVATE_STREAM_A2DP: - return STEP_ACTIVATE_STREAM_SCO; - - case STEP_ACTIVATE_STREAM_SCO: - return WP_TRANSITION_STEP_NONE; - - default: - return WP_TRANSITION_STEP_ERROR; - } -} - -static void -on_item_activated (WpSessionItem * item, GAsyncResult * res, - WpTransition *transition) -{ - g_autoptr (GError) error = NULL; - - if (!wp_session_item_activate_finish (item, res, &error)) { - wp_transition_return_error (transition, g_steal_pointer (&error)); - return; - } - - wp_transition_advance (transition); -} - -static void -activate_stream (WpSiBluez5Endpoint *self, guint32 id, WpTransition *transition) -{ - if (self->streams[id]) - wp_session_item_activate (self->streams[id], - (GAsyncReadyCallback) on_item_activated, transition); - else - wp_transition_advance (transition); -} - -static void -si_bluez5_endpoint_activate_execute_step (WpSessionItem * item, - WpTransition * transition, guint step) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - - switch (step) { - case STEP_VERIFY_CONFIG: - if (G_UNLIKELY (!(wp_session_item_get_flags (item) & WP_SI_FLAG_CONFIGURED))) { - wp_transition_return_error (transition, - g_error_new (WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVARIANT, - "si-bluez5-endpoint: cannot activate item without it " - "being configured first")); - } - wp_transition_advance (transition); - break; - - case STEP_ACTIVATE_STREAM_A2DP: - activate_stream (self, STREAM_ID_A2DP, transition); - break; - - case STEP_ACTIVATE_STREAM_SCO: - activate_stream (self, STREAM_ID_SCO, transition); - break; - - default: - g_return_if_reached (); - } -} - -static void -si_bluez5_endpoint_activate_rollback (WpSessionItem * item) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - g_autoptr (WpIterator) it = - wp_session_bin_new_iterator (WP_SESSION_BIN (self)); - g_auto (GValue) val = G_VALUE_INIT; - - /* deactivate all items */ - for (; wp_iterator_next (it, &val); g_value_unset (&val)) - wp_session_item_deactivate (g_value_get_object (&val)); -} - -static void -si_bluez5_endpoint_class_init (WpSiBluez5EndpointClass * klass) -{ - WpSessionItemClass *si_class = (WpSessionItemClass *) klass; - - si_class->reset = si_bluez5_endpoint_reset; - si_class->get_associated_proxy = si_bluez5_endpoint_get_associated_proxy; - si_class->configure = si_bluez5_endpoint_configure; - si_class->get_configuration = si_bluez5_endpoint_get_configuration; - si_class->activate_get_next_step = si_bluez5_endpoint_activate_get_next_step; - si_class->activate_execute_step = si_bluez5_endpoint_activate_execute_step; - si_class->activate_rollback = si_bluez5_endpoint_activate_rollback; -} - -static GVariant * -si_bluez5_endpoint_get_registration_info (WpSiEndpoint * item) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("(ssya{ss})")); - g_variant_builder_add (&b, "s", self->name); - g_variant_builder_add (&b, "s", self->direction == WP_DIRECTION_INPUT ? - "Audio/Sink" : "Audio/Source"); - g_variant_builder_add (&b, "y", self->direction); - g_variant_builder_add (&b, "a{ss}", NULL); - - return g_variant_builder_end (&b); -} - -static WpProperties * -si_bluez5_endpoint_get_properties (WpSiEndpoint * item) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - WpProperties *properties; - g_autofree gchar *description = NULL; - - properties = - wp_pipewire_object_get_properties (WP_PIPEWIRE_OBJECT (self->device)); - properties = wp_properties_ensure_unique_owner (properties); - description = g_strdup_printf ("Bluez5-%s of %s", - self->direction == WP_DIRECTION_INPUT ? "Sink" : "Source", - wp_properties_get (properties, PW_KEY_DEVICE_NAME)); - wp_properties_set (properties, "endpoint.description", description); - wp_properties_setf (properties, "endpoint.priority", "%d", self->priority); - - return properties; -} - -static guint -si_bluez5_endpoint_get_n_streams (WpSiEndpoint * item) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - guint res = 0; - if (self->streams[STREAM_ID_A2DP]) - res++; - if (self->streams[STREAM_ID_SCO]) - res++; - return res; -} - -static WpSiStream * -si_bluez5_endpoint_get_stream (WpSiEndpoint * item, guint index) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (item); - guint n_streams = si_bluez5_endpoint_get_n_streams (item); - WpSessionItem *res = NULL; - g_return_val_if_fail (index < n_streams, NULL); - if (!self->streams[STREAM_ID_A2DP]) - index++; - res = self->streams[index]; - g_return_val_if_fail (res, NULL); - return WP_SI_STREAM (g_object_ref (res)); -} - -static WpSiStreamAcquisition * -si_bluez5_endpoint_get_stream_acquisition (WpSiEndpoint * self) -{ - return WP_SI_STREAM_ACQUISITION (self); -} - -static void -si_bluez5_endpoint_endpoint_init (WpSiEndpointInterface * iface) -{ - iface->get_registration_info = si_bluez5_endpoint_get_registration_info; - iface->get_properties = si_bluez5_endpoint_get_properties; - iface->get_n_streams = si_bluez5_endpoint_get_n_streams; - iface->get_stream = si_bluez5_endpoint_get_stream; - iface->get_stream_acquisition = si_bluez5_endpoint_get_stream_acquisition; -} - -static void -set_device_profile (WpDevice *device, gint index) -{ - g_return_if_fail (device); - g_autoptr (WpSpaPod) profile = wp_spa_pod_new_object ( - "Spa:Pod:Object:Param:Profile", "Profile", - "index", "i", index, - NULL); - wp_pipewire_object_set_param (WP_PIPEWIRE_OBJECT (device), - "Profile", 0, profile); -} - -static void -abort_acquisition (WpSessionItem * ac, GTask *task, const gchar *msg) -{ - g_autoptr (WpGlobalProxy) link = NULL; - - /* return error to abort the link activation */ - g_task_return_new_error (task, WP_DOMAIN_LIBRARY, - WP_LIBRARY_ERROR_OPERATION_FAILED, "%s", msg); - - /* destroy the link */ - link = wp_session_item_get_associated_proxy (ac, WP_TYPE_ENDPOINT_LINK); - g_return_if_fail (link); - wp_global_proxy_request_destroy (link); -} - -static void -si_bluez5_endpoint_stream_acquisition_acquire (WpSiStreamAcquisition * sa, - WpSiLink * acquisitor, WpSiStream * stream, GAsyncReadyCallback callback, - gpointer data) -{ - WpSiBluez5Endpoint *self = WP_SI_BLUEZ5_ENDPOINT (sa); - g_autoptr (GTask) task = NULL; - gint64 now = g_get_monotonic_time (); - - /* create the task */ - task = g_task_new (self, NULL, callback, data); - - /* accept acquisition if stream is valid */ - if (WP_SESSION_ITEM (stream) == self->streams[self->stream_id]) { - g_task_return_boolean (task, TRUE); - return; - } - - /* abort acquisition if we changed the bluez5 profile less than a second ago. - * This prevents an switch profile infinite loop caused by the policy module - * when 2 or more clients with different profiles want to link with the same - * bluez5 endpoint */ - if (now - self->last_switch < 1000000) { - abort_acquisition (WP_SESSION_ITEM (acquisitor), task, - "already switched bluez5 profile recently"); - return; - } - - /* switch profile */ - set_device_profile (self->device, - get_profile_id_from_stream_id (self->stream_id) == 1 ? 2 : 1); - - /* update last switch time */ - self->last_switch = now; - - /* abort acquisition */ - abort_acquisition (WP_SESSION_ITEM (acquisitor), task, - "new bluez5 profile set"); -} - -static void -si_bluez5_endpoint_stream_acquisition_release (WpSiStreamAcquisition * sa, - WpSiLink * acquisitor, WpSiStream * stream) -{ -} - -static gboolean -si_bluez5_endpoint_stream_acquisition_acquire_finish ( - WpSiStreamAcquisition * sa, GAsyncResult * res, GError ** error) -{ - g_return_val_if_fail (WP_IS_SI_STREAM_ACQUISITION (sa), FALSE); - g_return_val_if_fail (g_task_is_valid (res, sa), FALSE); - - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -si_bluez5_endpoint_stream_acquisition_init ( - WpSiStreamAcquisitionInterface * iface) -{ - iface->acquire = si_bluez5_endpoint_stream_acquisition_acquire; - iface->acquire_finish = si_bluez5_endpoint_stream_acquisition_acquire_finish; - iface->release = si_bluez5_endpoint_stream_acquisition_release; -} - -WP_PLUGIN_EXPORT gboolean -wireplumber__module_init (WpCore * core, GVariant * args, GError ** error) -{ - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("a(ssymv)")); - g_variant_builder_add (&b, "(ssymv)", "device", "t", - WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - g_variant_builder_add (&b, "(ssymv)", "name", "s", - WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - g_variant_builder_add (&b, "(ssymv)", "direction", "u", - WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - g_variant_builder_add (&b, "(ssymv)", "a2dp-stream", "b", - WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - g_variant_builder_add (&b, "(ssymv)", "sco-stream", "b", - WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - g_variant_builder_add (&b, "(ssymv)", "node", "t", - WP_SI_CONFIG_OPTION_WRITEABLE, NULL); - g_variant_builder_add (&b, "(ssymv)", "priority", "u", - WP_SI_CONFIG_OPTION_WRITEABLE, NULL); - g_variant_builder_add (&b, "(ssymv)", "enable-control-port", "b", - WP_SI_CONFIG_OPTION_WRITEABLE, NULL); - g_variant_builder_add (&b, "(ssymv)", "enable-monitor", "b", - WP_SI_CONFIG_OPTION_WRITEABLE, NULL); - - wp_si_factory_register (core, wp_si_factory_new_simple ( - "si-bluez5-endpoint", si_bluez5_endpoint_get_type (), - g_variant_builder_end (&b))); - return TRUE; -} diff --git a/modules/module-si-convert.c b/modules/module-si-convert.c index 5b190db3..f081e155 100644 --- a/modules/module-si-convert.c +++ b/modules/module-si-convert.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -35,12 +36,12 @@ struct _WpSiConvert WpSessionItem *link_to_target; }; -static void si_convert_stream_init (WpSiStreamInterface * iface); +static void si_convert_endpoint_init (WpSiEndpointInterface * iface); static void si_convert_port_info_init (WpSiPortInfoInterface * iface); G_DECLARE_FINAL_TYPE(WpSiConvert, si_convert, WP, SI_CONVERT, WpSessionItem) G_DEFINE_TYPE_WITH_CODE (WpSiConvert, si_convert, WP_TYPE_SESSION_ITEM, - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_STREAM, si_convert_stream_init) + G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, si_convert_endpoint_init) G_IMPLEMENT_INTERFACE (WP_TYPE_SI_PORT_INFO, si_convert_port_info_init)) static void @@ -174,19 +175,19 @@ do_link_to_target (WpSiConvert *self) if (self->direction == WP_DIRECTION_INPUT) { /* Playback */ - g_variant_builder_add (&b, "{sv}", "out-stream", - g_variant_new_uint64 ((guint64) WP_SI_STREAM (self))); - g_variant_builder_add (&b, "{sv}", "out-stream-port-context", + g_variant_builder_add (&b, "{sv}", "out-endpoint", + g_variant_new_uint64 ((guint64) WP_SI_ENDPOINT (self))); + g_variant_builder_add (&b, "{sv}", "out-endpoint-port-context", g_variant_new_string ("reverse")); - g_variant_builder_add (&b, "{sv}", "in-stream", - g_variant_new_uint64 ((guint64) WP_SI_STREAM (self->target))); + g_variant_builder_add (&b, "{sv}", "in-endpoint", + g_variant_new_uint64 ((guint64) WP_SI_ENDPOINT (self->target))); } else { /* Capture */ - g_variant_builder_add (&b, "{sv}", "out-stream", - g_variant_new_uint64 ((guint64) WP_SI_STREAM (self->target))); - g_variant_builder_add (&b, "{sv}", "in-stream", - g_variant_new_uint64 ((guint64) WP_SI_STREAM (self))); - g_variant_builder_add (&b, "{sv}", "in-stream-port-context", + g_variant_builder_add (&b, "{sv}", "out-endpoint", + g_variant_new_uint64 ((guint64) WP_SI_ENDPOINT (self->target))); + g_variant_builder_add (&b, "{sv}", "in-endpoint", + g_variant_new_uint64 ((guint64) WP_SI_ENDPOINT (self))); + g_variant_builder_add (&b, "{sv}", "in-endpoint-port-context", g_variant_new_string ("reverse")); } @@ -280,7 +281,7 @@ si_convert_activate_execute_step (WpSessionItem * item, wp_properties_get (node_props, PW_KEY_NODE_NAME), self->name); wp_properties_setf (props, PW_KEY_NODE_DESCRIPTION, - "Stream volume for %s: %s", + "Converter volume for %s: %s", wp_properties_get (node_props, PW_KEY_NODE_DESCRIPTION), self->name); /* Create the node */ @@ -389,36 +390,43 @@ si_convert_activate_rollback (WpSessionItem * item) } static GVariant * -si_convert_get_stream_registration_info (WpSiStream * item) +si_convert_get_registration_info (WpSiEndpoint * item) { WpSiConvert *self = WP_SI_CONVERT (item); GVariantBuilder b; - g_variant_builder_init (&b, G_VARIANT_TYPE ("(sa{ss})")); + g_variant_builder_init (&b, G_VARIANT_TYPE ("(ssya{ss})")); g_variant_builder_add (&b, "s", self->name); + g_variant_builder_add (&b, "s", "Audio/Convert"); + g_variant_builder_add (&b, "y", (guchar) self->direction); g_variant_builder_add (&b, "a{ss}", NULL); return g_variant_builder_end (&b); } static WpProperties * -si_convert_get_stream_properties (WpSiStream * self) +si_convert_get_properties (WpSiEndpoint * item) { - return NULL; -} + WpSiConvert *self = WP_SI_CONVERT (item); + WpProperties *result = wp_properties_new_empty (); -static WpSiEndpoint * -si_convert_get_stream_parent_endpoint (WpSiStream * self) -{ - return WP_SI_ENDPOINT (wp_session_item_get_parent (WP_SESSION_ITEM (self))); + wp_properties_set (result, "endpoint.priority", NULL); + wp_properties_setf (result, "endpoint.description", "%s", "Audio Converter"); + wp_properties_setf (result, PW_KEY_ENDPOINT_AUTOCONNECT, "%d", FALSE); + wp_properties_set (result, PW_KEY_ENDPOINT_CLIENT_ID, NULL); + + /* associate with the node */ + wp_properties_setf (result, PW_KEY_NODE_ID, "%d", + wp_proxy_get_bound_id (WP_PROXY (self->node))); + + return result; } static void -si_convert_stream_init (WpSiStreamInterface * iface) +si_convert_endpoint_init (WpSiEndpointInterface * iface) { - iface->get_registration_info = si_convert_get_stream_registration_info; - iface->get_properties = si_convert_get_stream_properties; - iface->get_parent_endpoint = si_convert_get_stream_parent_endpoint; + iface->get_registration_info = si_convert_get_registration_info; + iface->get_properties = si_convert_get_properties; } static GVariant * diff --git a/modules/module-si-fake-stream.c b/modules/module-si-fake-stream.c deleted file mode 100644 index fbe0ad7d..00000000 --- a/modules/module-si-fake-stream.c +++ /dev/null @@ -1,189 +0,0 @@ -/* WirePlumber - * - * Copyright © 2020 Collabora Ltd. - * @author Julian Bouzas - * - * SPDX-License-Identifier: MIT - */ - -#include -#include - -enum { - STEP_VERIFY_CONFIG = WP_TRANSITION_STEP_CUSTOM_START, -}; - -struct _WpSiFakeStream -{ - WpSessionItem parent; - - /* configuration */ - gchar name[96]; -}; - -static void si_fake_stream_stream_init (WpSiStreamInterface * iface); -static void si_fake_stream_port_info_init (WpSiPortInfoInterface * iface); - -G_DECLARE_FINAL_TYPE(WpSiFakeStream, si_fake_stream, WP, SI_FAKE_STREAM, WpSessionItem) -G_DEFINE_TYPE_WITH_CODE (WpSiFakeStream, si_fake_stream, WP_TYPE_SESSION_ITEM, - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_STREAM, si_fake_stream_stream_init) - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_PORT_INFO, si_fake_stream_port_info_init)) - -static void -si_fake_stream_init (WpSiFakeStream * self) -{ -} - -static void -si_fake_stream_reset (WpSessionItem * item) -{ - WpSiFakeStream *self = WP_SI_FAKE_STREAM (item); - - /* unexport & deactivate first */ - WP_SESSION_ITEM_CLASS (si_fake_stream_parent_class)->reset (item); - - self->name[0] = '\0'; - - wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED); -} - -static gboolean -si_fake_stream_configure (WpSessionItem * item, GVariant * args) -{ - WpSiFakeStream *self = WP_SI_FAKE_STREAM (item); - const gchar *name; - - if (wp_session_item_get_flags (item) & (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE)) - return FALSE; - - /* reset previous config */ - si_fake_stream_reset (item); - - /* get name */ - if (!g_variant_lookup (args, "name", "&s", &name)) - return FALSE; - strncpy (self->name, name, sizeof (self->name) - 1); - - wp_session_item_set_flag (item, WP_SI_FLAG_CONFIGURED); - return TRUE; -} - -static GVariant * -si_fake_stream_get_configuration (WpSessionItem * item) -{ - WpSiFakeStream *self = WP_SI_FAKE_STREAM (item); - GVariantBuilder b; - - /* Set the properties */ - g_variant_builder_init (&b, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&b, "{sv}", - "name", g_variant_new_string (self->name)); - return g_variant_builder_end (&b); -} - -static guint -si_fake_stream_activate_get_next_step (WpSessionItem * item, - WpTransition * transition, guint step) -{ - switch (step) { - case WP_TRANSITION_STEP_NONE: - return STEP_VERIFY_CONFIG; - - case STEP_VERIFY_CONFIG: - return WP_TRANSITION_STEP_NONE; - - default: - return WP_TRANSITION_STEP_ERROR; - } -} - -static void -si_fake_stream_activate_execute_step (WpSessionItem * item, - WpTransition * transition, guint step) -{ - switch (step) { - case STEP_VERIFY_CONFIG: - if (G_UNLIKELY (!(wp_session_item_get_flags (item) & WP_SI_FLAG_CONFIGURED))) { - wp_transition_return_error (transition, - g_error_new (WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVARIANT, - "si-fake-stream: cannot activate item without it " - "being configured first")); - } - wp_transition_advance (transition); - break; - - default: - g_return_if_reached (); - } -} - -static GVariant * -si_fake_stream_get_stream_registration_info (WpSiStream * item) -{ - WpSiFakeStream *self = WP_SI_FAKE_STREAM (item); - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("(sa{ss})")); - g_variant_builder_add (&b, "s", self->name); - g_variant_builder_add (&b, "a{ss}", NULL); - - return g_variant_builder_end (&b); -} - -static WpProperties * -si_fake_stream_get_stream_properties (WpSiStream * self) -{ - return NULL; -} - -static WpSiEndpoint * -si_fake_stream_get_stream_parent_endpoint (WpSiStream * self) -{ - return WP_SI_ENDPOINT (wp_session_item_get_parent (WP_SESSION_ITEM (self))); -} - -static void -si_fake_stream_stream_init (WpSiStreamInterface * iface) -{ - iface->get_registration_info = si_fake_stream_get_stream_registration_info; - iface->get_properties = si_fake_stream_get_stream_properties; - iface->get_parent_endpoint = si_fake_stream_get_stream_parent_endpoint; -} - -static void -si_fake_stream_class_init (WpSiFakeStreamClass * klass) -{ - WpSessionItemClass *si_class = (WpSessionItemClass *) klass; - - si_class->reset = si_fake_stream_reset; - si_class->configure = si_fake_stream_configure; - si_class->get_configuration = si_fake_stream_get_configuration; - si_class->activate_get_next_step = si_fake_stream_activate_get_next_step; - si_class->activate_execute_step = si_fake_stream_activate_execute_step; -} - -static GVariant * -si_fake_stream_get_ports (WpSiPortInfo * item, const gchar * context) -{ - return NULL; -} - -static void -si_fake_stream_port_info_init (WpSiPortInfoInterface * iface) -{ - iface->get_ports = si_fake_stream_get_ports; -} - -WP_PLUGIN_EXPORT gboolean -wireplumber__module_init (WpCore * core, GVariant * args, GError ** error) -{ - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("a(ssymv)")); - g_variant_builder_add (&b, "(ssymv)", "name", "s", - WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - - wp_si_factory_register (core, wp_si_factory_new_simple ( - "si-fake-stream", si_fake_stream_get_type (), g_variant_builder_end (&b))); - return TRUE; -} diff --git a/modules/module-si-monitor-endpoint.c b/modules/module-si-monitor-endpoint.c index 6a0d1bcf..17a2d29f 100644 --- a/modules/module-si-monitor-endpoint.c +++ b/modules/module-si-monitor-endpoint.c @@ -25,14 +25,12 @@ struct _WpSiMonitorEndpoint }; static void si_monitor_endpoint_endpoint_init (WpSiEndpointInterface * iface); -static void si_monitor_endpoint_stream_init (WpSiStreamInterface * iface); static void si_monitor_endpoint_port_info_init (WpSiPortInfoInterface * iface); G_DECLARE_FINAL_TYPE(WpSiMonitorEndpoint, si_monitor_endpoint, WP, SI_MONITOR_ENDPOINT, WpSessionItem) G_DEFINE_TYPE_WITH_CODE (WpSiMonitorEndpoint, si_monitor_endpoint, WP_TYPE_SESSION_ITEM, G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, si_monitor_endpoint_endpoint_init) - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_STREAM, si_monitor_endpoint_stream_init) G_IMPLEMENT_INTERFACE (WP_TYPE_SI_PORT_INFO, si_monitor_endpoint_port_info_init)) static void @@ -224,53 +222,11 @@ si_monitor_endpoint_get_properties (WpSiEndpoint * item) return properties; } -static guint -si_monitor_endpoint_get_n_streams (WpSiEndpoint * item) -{ - return 1; -} - -static WpSiStream * -si_monitor_endpoint_get_stream (WpSiEndpoint * item, guint index) -{ - g_return_val_if_fail (index == 0, NULL); - return WP_SI_STREAM (item); -} - static void si_monitor_endpoint_endpoint_init (WpSiEndpointInterface * iface) { iface->get_registration_info = si_monitor_endpoint_get_registration_info; iface->get_properties = si_monitor_endpoint_get_properties; - iface->get_n_streams = si_monitor_endpoint_get_n_streams; - iface->get_stream = si_monitor_endpoint_get_stream; -} - -static GVariant * -si_monitor_endpoint_get_stream_registration_info (WpSiStream * self) -{ - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("(sa{ss})")); - g_variant_builder_add (&b, "s", "default"); - g_variant_builder_add (&b, "a{ss}", NULL); - - return g_variant_builder_end (&b); -} - -static WpSiEndpoint * -si_monitor_endpoint_get_stream_parent_endpoint (WpSiStream * self) -{ - return WP_SI_ENDPOINT (g_object_ref (self)); -} - -static void -si_monitor_endpoint_stream_init (WpSiStreamInterface * iface) -{ - iface->get_registration_info = - si_monitor_endpoint_get_stream_registration_info; - iface->get_parent_endpoint = - si_monitor_endpoint_get_stream_parent_endpoint; } static GVariant * diff --git a/modules/module-si-simple-node-endpoint.c b/modules/module-si-simple-node-endpoint.c index 1516fae2..9ccfb254 100644 --- a/modules/module-si-simple-node-endpoint.c +++ b/modules/module-si-simple-node-endpoint.c @@ -30,14 +30,12 @@ struct _WpSiSimpleNodeEndpoint }; static void si_simple_node_endpoint_endpoint_init (WpSiEndpointInterface * iface); -static void si_simple_node_endpoint_stream_init (WpSiStreamInterface * iface); static void si_simple_node_endpoint_port_info_init (WpSiPortInfoInterface * iface); G_DECLARE_FINAL_TYPE(WpSiSimpleNodeEndpoint, si_simple_node_endpoint, WP, SI_SIMPLE_NODE_ENDPOINT, WpSessionItem) G_DEFINE_TYPE_WITH_CODE (WpSiSimpleNodeEndpoint, si_simple_node_endpoint, WP_TYPE_SESSION_ITEM, G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, si_simple_node_endpoint_endpoint_init) - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_STREAM, si_simple_node_endpoint_stream_init) G_IMPLEMENT_INTERFACE (WP_TYPE_SI_PORT_INFO, si_simple_node_endpoint_port_info_init)) static void @@ -292,53 +290,11 @@ si_simple_node_endpoint_get_properties (WpSiEndpoint * item) return result; } -static guint -si_simple_node_endpoint_get_n_streams (WpSiEndpoint * item) -{ - return 1; -} - -static WpSiStream * -si_simple_node_endpoint_get_stream (WpSiEndpoint * item, guint index) -{ - g_return_val_if_fail (index == 0, NULL); - return WP_SI_STREAM (item); -} - static void si_simple_node_endpoint_endpoint_init (WpSiEndpointInterface * iface) { iface->get_registration_info = si_simple_node_endpoint_get_registration_info; iface->get_properties = si_simple_node_endpoint_get_properties; - iface->get_n_streams = si_simple_node_endpoint_get_n_streams; - iface->get_stream = si_simple_node_endpoint_get_stream; -} - -static GVariant * -si_simple_node_endpoint_get_stream_registration_info (WpSiStream * self) -{ - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("(sa{ss})")); - g_variant_builder_add (&b, "s", "default"); - g_variant_builder_add (&b, "a{ss}", NULL); - - return g_variant_builder_end (&b); -} - -static WpSiEndpoint * -si_simple_node_endpoint_get_stream_parent_endpoint (WpSiStream * self) -{ - return WP_SI_ENDPOINT (g_object_ref (self)); -} - -static void -si_simple_node_endpoint_stream_init (WpSiStreamInterface * iface) -{ - iface->get_registration_info = - si_simple_node_endpoint_get_stream_registration_info; - iface->get_parent_endpoint = - si_simple_node_endpoint_get_stream_parent_endpoint; } static GVariant * diff --git a/modules/module-si-standard-link.c b/modules/module-si-standard-link.c index 87636108..fa8db425 100644 --- a/modules/module-si-standard-link.c +++ b/modules/module-si-standard-link.c @@ -20,10 +20,10 @@ struct _WpSiStandardLink { WpSessionItem parent; - WpSiStream *out_stream; - WpSiStream *in_stream; - gchar *out_stream_port_context; - gchar *in_stream_port_context; + WpSiEndpoint *out_endpoint; + WpSiEndpoint *in_endpoint; + gchar *out_endpoint_port_context; + gchar *in_endpoint_port_context; gboolean manage_lifetime; gboolean passive; @@ -38,13 +38,13 @@ G_DEFINE_TYPE_WITH_CODE (WpSiStandardLink, si_standard_link, WP_TYPE_SESSION_ITE G_IMPLEMENT_INTERFACE (WP_TYPE_SI_LINK, si_standard_link_link_init)) static void -on_stream_flags_changed (WpSessionItem * stream, WpSiFlags flags, +on_flags_changed (WpSessionItem * endpoint, WpSiFlags flags, WpSessionItem * link) { - /* stream was deactivated; destroy the associated link */ + /* endpoint was deactivated; destroy the associated link */ if (!(flags & WP_SI_FLAG_ACTIVE)) { - wp_trace_object (link, "destroying because stream " WP_OBJECT_FORMAT - " was deactivated", WP_OBJECT_ARGS (stream)); + wp_trace_object (link, "destroying because endpoint " WP_OBJECT_FORMAT + " was deactivated", WP_OBJECT_ARGS (endpoint)); wp_session_item_reset (link); g_object_unref (link); } @@ -74,19 +74,19 @@ si_standard_link_reset (WpSessionItem * item) WP_SESSION_ITEM_CLASS (si_standard_link_parent_class)->reset (item); if (self->manage_lifetime) { - g_signal_handlers_disconnect_by_func (self->out_stream, - G_CALLBACK (on_stream_flags_changed), self); - g_signal_handlers_disconnect_by_func (self->in_stream, - G_CALLBACK (on_stream_flags_changed), self); + g_signal_handlers_disconnect_by_func (self->out_endpoint, + G_CALLBACK (on_flags_changed), self); + g_signal_handlers_disconnect_by_func (self->in_endpoint, + G_CALLBACK (on_flags_changed), self); g_signal_handlers_disconnect_by_func (self, G_CALLBACK (on_link_flags_changed), NULL); } self->manage_lifetime = FALSE; self->passive = FALSE; - self->out_stream = NULL; - self->in_stream = NULL; - g_clear_pointer (&self->out_stream_port_context, g_free); - g_clear_pointer (&self->in_stream_port_context, g_free); + self->out_endpoint = NULL; + self->in_endpoint = NULL; + g_clear_pointer (&self->out_endpoint_port_context, g_free); + g_clear_pointer (&self->in_endpoint_port_context, g_free); wp_session_item_clear_flag (item, WP_SI_FLAG_CONFIGURED); } @@ -100,15 +100,15 @@ si_standard_link_get_configuration (WpSessionItem * item) /* Set the properties */ g_variant_builder_init (&b, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&b, "{sv}", - "out-stream", g_variant_new_uint64 ((guint64) self->out_stream)); + "out-endpoint", g_variant_new_uint64 ((guint64) self->out_endpoint)); g_variant_builder_add (&b, "{sv}", - "in-stream", g_variant_new_uint64 ((guint64) self->in_stream)); + "in-endpoint", g_variant_new_uint64 ((guint64) self->in_endpoint)); g_variant_builder_add (&b, "{sv}", - "out-stream-port-context", - g_variant_new_string (self->out_stream_port_context)); + "out-endpoint-port-context", + g_variant_new_string (self->out_endpoint_port_context)); g_variant_builder_add (&b, "{sv}", - "in-stream-port-context", - g_variant_new_string (self->in_stream_port_context)); + "in-endpoint-port-context", + g_variant_new_string (self->in_endpoint_port_context)); g_variant_builder_add (&b, "{sv}", "manage-lifetime", g_variant_new_boolean (self->manage_lifetime)); g_variant_builder_add (&b, "{sv}", @@ -120,52 +120,52 @@ static gboolean si_standard_link_configure (WpSessionItem * item, GVariant * args) { WpSiStandardLink *self = WP_SI_STANDARD_LINK (item); - guint64 out_stream_i, in_stream_i; - WpSessionItem *out_stream, *in_stream; + guint64 out_endpoint_i, in_endpoint_i; + WpSessionItem *out_endpoint, *in_endpoint; if (wp_session_item_get_flags (item) & (WP_SI_FLAG_ACTIVATING | WP_SI_FLAG_ACTIVE | WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED)) return FALSE; - if (!g_variant_lookup (args, "out-stream", "t", &out_stream_i) || - !g_variant_lookup (args, "in-stream", "t", &in_stream_i)) + if (!g_variant_lookup (args, "out-endpoint", "t", &out_endpoint_i) || + !g_variant_lookup (args, "in-endpoint", "t", &in_endpoint_i)) return FALSE; - out_stream = GUINT_TO_POINTER (out_stream_i); - in_stream = GUINT_TO_POINTER (in_stream_i); + out_endpoint = GUINT_TO_POINTER (out_endpoint_i); + in_endpoint = GUINT_TO_POINTER (in_endpoint_i); - if (!WP_IS_SI_STREAM (out_stream) || !WP_IS_SI_STREAM (in_stream) || - !WP_IS_SI_PORT_INFO (out_stream) || !WP_IS_SI_PORT_INFO (in_stream) || - !(wp_session_item_get_flags (out_stream) & WP_SI_FLAG_ACTIVE) || - !(wp_session_item_get_flags (in_stream) & WP_SI_FLAG_ACTIVE)) + if (!WP_IS_SI_ENDPOINT (out_endpoint) || !WP_IS_SI_ENDPOINT (in_endpoint) || + !WP_IS_SI_PORT_INFO (out_endpoint) || !WP_IS_SI_PORT_INFO (in_endpoint) || + !(wp_session_item_get_flags (out_endpoint) & WP_SI_FLAG_ACTIVE) || + !(wp_session_item_get_flags (in_endpoint) & WP_SI_FLAG_ACTIVE)) return FALSE; /* clear previous configuration; we are not active or exported, so this doesn't have any other side-effects */ wp_session_item_reset (item); - self->out_stream = WP_SI_STREAM (out_stream); - self->in_stream = WP_SI_STREAM (in_stream); + self->out_endpoint = WP_SI_ENDPOINT (out_endpoint); + self->in_endpoint = WP_SI_ENDPOINT (in_endpoint); - g_variant_lookup (args, "out-stream-port-context", "s", - &self->out_stream_port_context); - g_variant_lookup (args, "in-stream-port-context", "s", - &self->in_stream_port_context); + g_variant_lookup (args, "out-endpoint-port-context", "s", + &self->out_endpoint_port_context); + g_variant_lookup (args, "in-endpoint-port-context", "s", + &self->in_endpoint_port_context); g_variant_lookup (args, "passive", "b", &self->passive); /* manage-lifetime == TRUE means that this si-standard-link item is * responsible for self-destructing if either - * - one of the streams is deactivated + * - one of the endpoints is deactivated * - if the WpImplEndpointLink is destroyed upon request * (wp_proxy_request_destroy()) */ if (g_variant_lookup (args, "manage-lifetime", "b", &self->manage_lifetime) && self->manage_lifetime) { - g_signal_connect_object (self->out_stream, "flags-changed", - G_CALLBACK (on_stream_flags_changed), self, 0); - g_signal_connect_object (self->in_stream, "flags-changed", - G_CALLBACK (on_stream_flags_changed), self, 0); + g_signal_connect_object (self->out_endpoint, "flags-changed", + G_CALLBACK (on_flags_changed), self, 0); + g_signal_connect_object (self->in_endpoint, "flags-changed", + G_CALLBACK (on_flags_changed), self, 0); g_signal_connect (self, "flags-changed", G_CALLBACK (on_link_flags_changed), NULL); } @@ -203,13 +203,13 @@ si_standard_link_activate_get_next_step (WpSessionItem * item, } static void -on_stream_acquired (WpSiStreamAcquisition * acq, GAsyncResult * res, +on_endpoint_acquired (WpSiEndpointAcquisition * acq, GAsyncResult * res, WpTransition * transition) { WpSiStandardLink *self = wp_transition_get_source_object (transition); g_autoptr (GError) error = NULL; - if (!wp_si_stream_acquisition_acquire_finish (acq, res, &error)) { + if (!wp_si_endpoint_acquisition_acquire_finish (acq, res, &error)) { wp_transition_return_error (transition, g_steal_pointer (&error)); return; } @@ -239,12 +239,12 @@ find_core (WpSiStandardLink * self) { /* session items are not associated with a core, but surely when linking we should be able to find a WpImplEndpointLink associated, or at the very - least a WpNode associated with one of the streams... */ + least a WpNode associated with one of the endpoints... */ g_autoptr (WpObject) proxy = wp_session_item_get_associated_proxy ( WP_SESSION_ITEM (self), WP_TYPE_ENDPOINT_LINK); if (!proxy) proxy = wp_session_item_get_associated_proxy ( - WP_SESSION_ITEM (self->out_stream), WP_TYPE_NODE); + WP_SESSION_ITEM (self->out_endpoint), WP_TYPE_NODE); return proxy ? wp_object_get_core (proxy) : NULL; } @@ -372,14 +372,12 @@ si_standard_link_activate_execute_step (WpSessionItem * item, switch (step) { case STEP_ACQUIRE: { - g_autoptr (WpSiEndpoint) out_endpoint = NULL; - g_autoptr (WpSiEndpoint) in_endpoint = NULL; - WpSiStreamAcquisition *out_acquisition, *in_acquisition; + WpSiEndpointAcquisition *out_acquisition, *in_acquisition; - out_endpoint = wp_si_stream_get_parent_endpoint (self->out_stream); - in_endpoint = wp_si_stream_get_parent_endpoint (self->in_stream); - out_acquisition = wp_si_endpoint_get_stream_acquisition (out_endpoint); - in_acquisition = wp_si_endpoint_get_stream_acquisition (in_endpoint); + out_acquisition = wp_si_endpoint_get_endpoint_acquisition ( + self->out_endpoint); + in_acquisition = wp_si_endpoint_get_endpoint_acquisition ( + self->in_endpoint); if (out_acquisition && in_acquisition) self->n_async_ops_wait = 2; @@ -392,13 +390,13 @@ si_standard_link_activate_execute_step (WpSessionItem * item, } if (out_acquisition) { - wp_si_stream_acquisition_acquire (out_acquisition, WP_SI_LINK (self), - self->out_stream, (GAsyncReadyCallback) on_stream_acquired, + wp_si_endpoint_acquisition_acquire (out_acquisition, WP_SI_LINK (self), + self->out_endpoint, (GAsyncReadyCallback) on_endpoint_acquired, transition); } if (in_acquisition) { - wp_si_stream_acquisition_acquire (in_acquisition, WP_SI_LINK (self), - self->in_stream, (GAsyncReadyCallback) on_stream_acquired, + wp_si_endpoint_acquisition_acquire (in_acquisition, WP_SI_LINK (self), + self->in_endpoint, (GAsyncReadyCallback) on_endpoint_acquired, transition); } break; @@ -407,15 +405,15 @@ si_standard_link_activate_execute_step (WpSessionItem * item, g_autoptr (GVariant) out_ports = NULL; g_autoptr (GVariant) in_ports = NULL; - out_ports = wp_si_port_info_get_ports (WP_SI_PORT_INFO (self->out_stream), - self->out_stream_port_context); - in_ports = wp_si_port_info_get_ports (WP_SI_PORT_INFO (self->in_stream), - self->in_stream_port_context); + out_ports = wp_si_port_info_get_ports (WP_SI_PORT_INFO (self->out_endpoint), + self->out_endpoint_port_context); + in_ports = wp_si_port_info_get_ports (WP_SI_PORT_INFO (self->in_endpoint), + self->in_endpoint_port_context); if (!create_links (self, transition, out_ports, in_ports)) { wp_transition_return_error (transition, g_error_new (WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVARIANT, - "Bad port info returned from one of the streams")); + "Bad port info returned from one of the endpoints")); } break; } @@ -428,27 +426,21 @@ static void si_standard_link_activate_rollback (WpSessionItem * item) { WpSiStandardLink *self = WP_SI_STANDARD_LINK (item); - g_autoptr (WpSiEndpoint) out_endpoint = NULL; - g_autoptr (WpSiEndpoint) in_endpoint = NULL; - WpSiStreamAcquisition *out_acquisition, *in_acquisition; + WpSiEndpointAcquisition *out_acquisition, *in_acquisition; - if (self->out_stream) { - out_endpoint = wp_si_stream_get_parent_endpoint (self->out_stream); - if (out_endpoint) { - out_acquisition = wp_si_endpoint_get_stream_acquisition (out_endpoint); - if (out_acquisition) - wp_si_stream_acquisition_release (out_acquisition, WP_SI_LINK (self), - self->out_stream); - } + if (self->out_endpoint) { + out_acquisition = + wp_si_endpoint_get_endpoint_acquisition (self->out_endpoint); + if (out_acquisition) + wp_si_endpoint_acquisition_release (out_acquisition, WP_SI_LINK (self), + self->out_endpoint); } - if (self->in_stream) { - in_endpoint = wp_si_stream_get_parent_endpoint (self->in_stream); - if (in_endpoint) { - in_acquisition = wp_si_endpoint_get_stream_acquisition (in_endpoint); - if (in_acquisition) - wp_si_stream_acquisition_release (in_acquisition, WP_SI_LINK (self), - self->in_stream); - } + if (self->in_endpoint) { + in_acquisition = + wp_si_endpoint_get_endpoint_acquisition (self->in_endpoint); + if (in_acquisition) + wp_si_endpoint_acquisition_release (in_acquisition, WP_SI_LINK (self), + self->in_endpoint); } g_clear_pointer (&self->node_links, g_ptr_array_unref); @@ -475,26 +467,26 @@ si_standard_link_get_registration_info (WpSiLink * item) return g_variant_builder_end (&b); } -static WpSiStream * -si_standard_link_get_out_stream (WpSiLink * item) +static WpSiEndpoint * +si_standard_link_get_out_endpoint (WpSiLink * item) { WpSiStandardLink *self = WP_SI_STANDARD_LINK (item); - return self->out_stream; + return self->out_endpoint; } -static WpSiStream * -si_standard_link_get_in_stream (WpSiLink * item) +static WpSiEndpoint * +si_standard_link_get_in_endpoint (WpSiLink * item) { WpSiStandardLink *self = WP_SI_STANDARD_LINK (item); - return self->in_stream; + return self->in_endpoint; } static void si_standard_link_link_init (WpSiLinkInterface * iface) { iface->get_registration_info = si_standard_link_get_registration_info; - iface->get_out_stream = si_standard_link_get_out_stream; - iface->get_in_stream = si_standard_link_get_in_stream; + iface->get_out_endpoint = si_standard_link_get_out_endpoint; + iface->get_in_endpoint = si_standard_link_get_in_endpoint; } WP_PLUGIN_EXPORT gboolean @@ -503,13 +495,13 @@ wireplumber__module_init (WpCore * core, GVariant * args, GError ** error) GVariantBuilder b; g_variant_builder_init (&b, G_VARIANT_TYPE ("a(ssymv)")); - g_variant_builder_add (&b, "(ssymv)", "out-stream", "t", + g_variant_builder_add (&b, "(ssymv)", "out-endpoint", "t", WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - g_variant_builder_add (&b, "(ssymv)", "in-stream", "t", + g_variant_builder_add (&b, "(ssymv)", "in-endpoint", "t", WP_SI_CONFIG_OPTION_WRITEABLE | WP_SI_CONFIG_OPTION_REQUIRED, NULL); - g_variant_builder_add (&b, "(ssymv)", "out-stream-port-context", "s", + g_variant_builder_add (&b, "(ssymv)", "out-endpoint-port-context", "s", WP_SI_CONFIG_OPTION_WRITEABLE, NULL); - g_variant_builder_add (&b, "(ssymv)", "in-stream-port-context", "s", + g_variant_builder_add (&b, "(ssymv)", "in-endpoint-port-context", "s", WP_SI_CONFIG_OPTION_WRITEABLE, NULL); g_variant_builder_add (&b, "(ssymv)", "manage-lifetime", "b", WP_SI_CONFIG_OPTION_WRITEABLE, NULL); diff --git a/src/config/config.lua.d/10-endpoint-support.lua b/src/config/config.lua.d/10-endpoint-support.lua index 18b2cacf..6a9e174a 100644 --- a/src/config/config.lua.d/10-endpoint-support.lua +++ b/src/config/config.lua.d/10-endpoint-support.lua @@ -17,10 +17,7 @@ function endpoint_support.enable() -- Session item factories, building blocks for the session management graph -- Do not disable these unless you really know what you are doing load_module("si-adapter") - load_module("si-audio-softdsp-endpoint") - load_module("si-bluez5-endpoint") load_module("si-convert") - load_module("si-fake-stream") load_module("si-monitor-endpoint") load_module("si-simple-node-endpoint") load_module("si-standard-link") diff --git a/src/scripts/policy-endpoint.lua b/src/scripts/policy-endpoint.lua index 7c03a37e..5bda1ba1 100644 --- a/src/scripts/policy-endpoint.lua +++ b/src/scripts/policy-endpoint.lua @@ -49,25 +49,23 @@ default_endpoint_target = { auto_linked_endpoints = {} function createLink (ep, target) - if ep:get_n_streams() > 0 and target:get_n_streams() > 0 then - local ep_id = ep['bound-id'] - local target_id = target['bound-id'] - local ep_is_output = (ep.direction == "output") - local props = { - ['endpoint-link.output.endpoint'] = (ep_is_output and ep_id) or target_id, - ['endpoint-link.output.stream'] = -1, - ['endpoint-link.input.endpoint'] = (ep_is_output and target_id) or ep_id, - ['endpoint-link.input.stream'] = -1, - } - ep:create_link (props) - end + local ep_id = ep['bound-id'] + local target_id = target['bound-id'] + local ep_is_output = (ep.direction == "output") + local props = { + ['endpoint-link.output.endpoint'] = (ep_is_output and ep_id) or target_id, + ['endpoint-link.output.stream'] = -1, + ['endpoint-link.input.endpoint'] = (ep_is_output and target_id) or ep_id, + ['endpoint-link.input.stream'] = -1, + } + ep:create_link (props) end function isEndpointLinkedWith (session, ep, target) local ep_id = ep["bound_id"] local target_id = target["bound_id"] for link in session:iterate_links() do - local out_ep, _, in_ep, _ = link:get_linked_object_ids() + local out_ep, in_ep = link:get_linked_object_ids() if (out_ep == ep_id and in_ep == target_id) or (out_ep == target_id and in_ep == ep_id) then return true @@ -89,7 +87,7 @@ function moveEndpoint (session, ep, target) -- destroy all previous links for link in session:iterate_links() do - local out_ep, _, in_ep, _ = link:get_linked_object_ids() + local out_ep, in_ep = link:get_linked_object_ids() if (ep_is_output and out_ep == ep_id) or (not ep_is_output and in_ep == ep_id) then local curr_target = nil @@ -224,7 +222,7 @@ function handleEndpoint (session, ep) -- check if this endpoint is already linked for link in session:iterate_links() do - local out_ep, _, in_ep, _ = link:get_linked_object_ids() + local out_ep, in_ep = link:get_linked_object_ids() if out_ep == ep_id or in_ep == ep_id then return end diff --git a/tests/examples/audiotestsrc-play.c b/tests/examples/audiotestsrc-play.c index 431b3cd7..48dede1f 100644 --- a/tests/examples/audiotestsrc-play.c +++ b/tests/examples/audiotestsrc-play.c @@ -72,14 +72,10 @@ on_endpoints_changed (WpSession * session, AppData * d) WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "=s", "Audio/Sink", NULL); if (src) { - g_print ("Got endpoint src: %s (%u streams)\n", - wp_endpoint_get_name (src), - wp_endpoint_get_n_streams (src)); + g_print ("Got endpoint src: %s\n", wp_endpoint_get_name (src)); } if (sink) { - g_print ("Got endpoint sink: %s (%u streams)\n", - wp_endpoint_get_name (sink), - wp_endpoint_get_n_streams (sink)); + g_print ("Got endpoint sink: %s\n", wp_endpoint_get_name (sink)); } if (src && sink) { @@ -356,10 +352,6 @@ appdata_init (AppData * d, GError ** error) "libwireplumber-module-si-simple-node-endpoint", "module", NULL, error))) return FALSE; - if (!(wp_core_load_component (d->core, - "libwireplumber-module-si-audio-softdsp-endpoint", "module", NULL, error))) - return FALSE; - if (!(wp_core_load_component (d->core, "libwireplumber-module-si-adapter", "module", NULL, error))) return FALSE; diff --git a/tests/modules/meson.build b/tests/modules/meson.build index 77139a20..7954583f 100644 --- a/tests/modules/meson.build +++ b/tests/modules/meson.build @@ -35,8 +35,15 @@ test( ) test( - 'test-si-audio-softdsp-endpoint', - executable('test-si-audio-softdsp-endpoint', 'si-audio-softdsp-endpoint.c', + 'test-si-adapter', + executable('test-si-adapter', 'si-adapter.c', + dependencies: common_deps, c_args: common_args), + env: common_env, +) + +test( + 'test-si-convert', + executable('test-si-convert', 'si-convert.c', dependencies: common_deps, c_args: common_args), env: common_env, ) diff --git a/tests/modules/si-audio-softdsp-endpoint.c b/tests/modules/si-adapter.c similarity index 55% rename from tests/modules/si-audio-softdsp-endpoint.c rename to tests/modules/si-adapter.c index 355a4de8..fe8aec20 100644 --- a/tests/modules/si-audio-softdsp-endpoint.c +++ b/tests/modules/si-adapter.c @@ -13,7 +13,7 @@ typedef struct { } TestFixture; static void -test_si_audio_softdsp_endpoint_setup (TestFixture * f, gconstpointer user_data) +test_si_adapter_setup (TestFixture * f, gconstpointer user_data) { wp_base_test_fixture_setup (&f->base, 0); @@ -26,8 +26,6 @@ test_si_audio_softdsp_endpoint_setup (TestFixture * f, gconstpointer user_data) "fake*", "test/libspa-test"), ==, 0); g_assert_cmpint (pw_context_add_spa_lib (f->base.server.context, "audiotestsrc", "audiotestsrc/libspa-audiotestsrc"), ==, 0); - g_assert_cmpint (pw_context_add_spa_lib (f->base.server.context, - "audio.convert", "audioconvert/libspa-audioconvert"), ==, 0); g_assert_nonnull (pw_context_load_module (f->base.server.context, "libpipewire-module-spa-node-factory", NULL, NULL)); g_assert_nonnull (pw_context_load_module (f->base.server.context, @@ -39,34 +37,20 @@ test_si_audio_softdsp_endpoint_setup (TestFixture * f, gconstpointer user_data) "libwireplumber-module-si-adapter", "module", NULL, &error); g_assert_no_error (error); } - { - g_autoptr (GError) error = NULL; - wp_core_load_component (f->base.core, - "libwireplumber-module-si-convert", "module", NULL, &error); - g_assert_no_error (error); - } - { - g_autoptr (GError) error = NULL; - wp_core_load_component (f->base.core, - "libwireplumber-module-si-audio-softdsp-endpoint", "module", NULL, &error); - g_assert_no_error (error); - } } static void -test_si_audio_softdsp_endpoint_teardown (TestFixture * f, gconstpointer user_data) +test_si_adapter_teardown (TestFixture * f, gconstpointer user_data) { wp_base_test_fixture_teardown (&f->base); } static void -test_si_audio_softdsp_endpoint_configure_activate (TestFixture * f, +test_si_adapter_configure_activate (TestFixture * f, gconstpointer user_data) { - guint requested_streams = GPOINTER_TO_UINT (user_data); g_autoptr (WpNode) node = NULL; g_autoptr (WpSessionItem) adapter = NULL; - g_autoptr (WpSessionItem) endpoint = NULL; /* create audiotestsrc adapter node */ node = wp_node_new_from_factory (f->base.core, @@ -120,122 +104,29 @@ test_si_audio_softdsp_endpoint_configure_activate (TestFixture * f, g_assert_cmpuint (channels, ==, 0); } - /* create audio softdsp endpoint */ - endpoint = wp_session_item_make (f->base.core, "si-audio-softdsp-endpoint"); - g_assert_nonnull (endpoint); - g_assert_true (WP_IS_SI_ENDPOINT (endpoint)); - - /* configure audio softdsp endpoint */ + /* activate adapter */ { - g_auto (GVariantBuilder) b = - G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&b, "{sv}", "adapter", - g_variant_new_uint64 ((guint64) adapter)); - g_assert_true ( - wp_session_item_configure (endpoint, g_variant_builder_end (&b))); - } - - g_assert_cmphex (wp_session_item_get_flags (endpoint), ==, - WP_SI_FLAG_CONFIGURED); - - { - g_autoptr (GVariant) v = wp_session_item_get_configuration (endpoint); - guint64 adapter_i; - g_assert_nonnull (v); - g_assert_true (g_variant_lookup (v, "adapter", "t", &adapter_i)); - g_assert_cmpuint (adapter_i, ==, (guint64) adapter); - } - - if (requested_streams > 1) { - for (guint i = 0; i < requested_streams; i++) { - g_autoptr (WpSessionItem) stream = - wp_session_item_make (f->base.core, "si-convert"); - g_assert_nonnull (stream); - g_assert_true (WP_IS_SI_STREAM (stream)); - - { - g_auto (GVariantBuilder) b = - G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&b, "{sv}", "target", - g_variant_new_uint64 ((guint64) adapter)); - g_variant_builder_add (&b, "{sv}", "name", - g_variant_new_printf ("stream-%u", i)); - g_assert_true ( - wp_session_item_configure (stream, g_variant_builder_end (&b))); - } - - g_assert_cmphex (wp_session_item_get_flags (stream), ==, - WP_SI_FLAG_CONFIGURED); - - g_assert_true (wp_session_bin_add (WP_SESSION_BIN (endpoint), - g_steal_pointer (&stream))); - } - } - - /* activate audio softdsp endpoint */ - { - wp_session_item_activate (endpoint, + wp_session_item_activate (adapter, (GAsyncReadyCallback) test_si_activate_finish_cb, f); g_main_loop_run (f->base.loop); } - g_assert_cmphex (wp_session_item_get_flags (endpoint), ==, - WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_ACTIVE); g_assert_cmphex (wp_session_item_get_flags (adapter), ==, WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_ACTIVE); g_assert_cmphex (wp_object_get_active_features (WP_OBJECT (node)), ==, WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL | WP_NODE_FEATURE_PORTS); - /* check streams */ - - g_assert_cmpuint (wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (endpoint)), - ==, requested_streams); - if (requested_streams == 1) { - WpSiStream *stream = - wp_si_endpoint_get_stream (WP_SI_ENDPOINT (endpoint), 0); - g_autoptr (GVariant) info = wp_si_stream_get_registration_info (stream); - const gchar *stream_name; - - g_variant_get (info, "(&sa{ss})", &stream_name, NULL); - g_assert_cmpstr (stream_name, ==, "audiotestsrc.adapter"); - g_assert_true ((gpointer) stream == (gpointer) adapter); - } else { - for (guint i = 0; i < requested_streams; i++) { - WpSiStream *stream = - wp_si_endpoint_get_stream (WP_SI_ENDPOINT (endpoint), i); - g_autoptr (GVariant) info = wp_si_stream_get_registration_info (stream); - g_autofree gchar *expected_name = g_strdup_printf ("stream-%u", i); - const gchar *stream_name; - - g_variant_get (info, "(&sa{ss})", &stream_name, NULL); - g_assert_cmpstr (stream_name, ==, expected_name); - g_assert_true ((gpointer) stream != (gpointer) adapter); - } - } - /* deactivate - configuration should not be altered */ - wp_session_item_deactivate (endpoint); - - g_assert_cmphex (wp_session_item_get_flags (endpoint), ==, - WP_SI_FLAG_CONFIGURED); + wp_session_item_deactivate (adapter); g_assert_cmphex (wp_session_item_get_flags (adapter), ==, 0); - - { - g_autoptr (GVariant) v = wp_session_item_get_configuration (endpoint); - guint64 adapter_i; - g_assert_nonnull (v); - g_assert_true (g_variant_lookup (v, "adapter", "t", &adapter_i)); - g_assert_cmpuint (adapter_i, ==, (guint64) adapter); - } } static void -test_si_audio_softdsp_endpoint_export (TestFixture * f, gconstpointer user_data) +test_si_adapter_export (TestFixture * f, gconstpointer user_data) { g_autoptr (WpNode) node = NULL; g_autoptr (WpSession) session = NULL; - g_autoptr (WpSessionItem) item = NULL; g_autoptr (WpSessionItem) adapter = NULL; g_autoptr (WpObjectManager) clients_om = NULL; g_autoptr (WpClient) self_client = NULL; @@ -280,23 +171,10 @@ test_si_audio_softdsp_endpoint_export (TestFixture * f, gconstpointer user_data) wp_session_item_configure (adapter, g_variant_builder_end (&b))); } - item = wp_session_item_make (f->base.core, "si-audio-softdsp-endpoint"); - g_assert_nonnull (item); - g_assert_true (WP_IS_SI_ENDPOINT (item)); - - { - g_auto (GVariantBuilder) b = - G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&b, "{sv}", "adapter", - g_variant_new_uint64 ((guint64) adapter)); - g_assert_true ( - wp_session_item_configure (item, g_variant_builder_end (&b))); - } - /* activate */ { - wp_session_item_activate (item, + wp_session_item_activate (adapter, (GAsyncReadyCallback) test_si_activate_finish_cb, f); g_main_loop_run (f->base.loop); } @@ -312,14 +190,12 @@ test_si_audio_softdsp_endpoint_export (TestFixture * f, gconstpointer user_data) /* export */ - wp_session_item_export (item, session, + wp_session_item_export (adapter, session, (GAsyncReadyCallback) test_si_export_finish_cb, f); g_main_loop_run (f->base.loop); - g_assert_cmphex (wp_session_item_get_flags (item), ==, - WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_ACTIVE | WP_SI_FLAG_EXPORTED); g_assert_cmphex (wp_session_item_get_flags (adapter), ==, - WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_ACTIVE); + WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_ACTIVE | WP_SI_FLAG_EXPORTED); { g_autoptr (WpEndpoint) ep = NULL; @@ -327,7 +203,7 @@ test_si_audio_softdsp_endpoint_export (TestFixture * f, gconstpointer user_data) gchar *tmp; g_assert_nonnull ( - ep = wp_session_item_get_associated_proxy (item, WP_TYPE_ENDPOINT)); + ep = wp_session_item_get_associated_proxy (adapter, WP_TYPE_ENDPOINT)); g_assert_nonnull ( props = wp_pipewire_object_get_properties (WP_PIPEWIRE_OBJECT (ep))); @@ -362,25 +238,19 @@ main (gint argc, gchar *argv[]) /* configure-activate */ - g_test_add ("/modules/si-audio-softdsp-endpoint/configure-activate/single-stream", - TestFixture, GUINT_TO_POINTER (1), - test_si_audio_softdsp_endpoint_setup, - test_si_audio_softdsp_endpoint_configure_activate, - test_si_audio_softdsp_endpoint_teardown); - - g_test_add ("/modules/si-audio-softdsp-endpoint/configure-activate/multi-stream", - TestFixture, GUINT_TO_POINTER (5), - test_si_audio_softdsp_endpoint_setup, - test_si_audio_softdsp_endpoint_configure_activate, - test_si_audio_softdsp_endpoint_teardown); + g_test_add ("/modules/si-adapter/configure-activate", + TestFixture, NULL, + test_si_adapter_setup, + test_si_adapter_configure_activate, + test_si_adapter_teardown); /* export */ - g_test_add ("/modules/si-audio-softdsp-endpoint/export", + g_test_add ("/modules/si-adapter/export", TestFixture, NULL, - test_si_audio_softdsp_endpoint_setup, - test_si_audio_softdsp_endpoint_export, - test_si_audio_softdsp_endpoint_teardown); + test_si_adapter_setup, + test_si_adapter_export, + test_si_adapter_teardown); return g_test_run (); } diff --git a/tests/modules/si-convert.c b/tests/modules/si-convert.c new file mode 100644 index 00000000..42108bdc --- /dev/null +++ b/tests/modules/si-convert.c @@ -0,0 +1,296 @@ +/* WirePlumber + * + * Copyright © 2020 Collabora Ltd. + * @author Julian Bouzas + * + * SPDX-License-Identifier: MIT + */ + +#include "../common/base-test-fixture.h" + +typedef struct { + WpBaseTestFixture base; +} TestFixture; + +static void +test_si_convert_setup (TestFixture * f, gconstpointer user_data) +{ + wp_base_test_fixture_setup (&f->base, 0); + + /* load modules */ + { + g_autoptr (WpTestServerLocker) lock = + wp_test_server_locker_new (&f->base.server); + + g_assert_cmpint (pw_context_add_spa_lib (f->base.server.context, + "fake*", "test/libspa-test"), ==, 0); + g_assert_cmpint (pw_context_add_spa_lib (f->base.server.context, + "audiotestsrc", "audiotestsrc/libspa-audiotestsrc"), ==, 0); + g_assert_cmpint (pw_context_add_spa_lib (f->base.server.context, + "audio.convert", "audioconvert/libspa-audioconvert"), ==, 0); + g_assert_nonnull (pw_context_load_module (f->base.server.context, + "libpipewire-module-spa-node-factory", NULL, NULL)); + g_assert_nonnull (pw_context_load_module (f->base.server.context, + "libpipewire-module-adapter", NULL, NULL)); + } + { + g_autoptr (GError) error = NULL; + wp_core_load_component (f->base.core, + "libwireplumber-module-si-adapter", "module", NULL, &error); + g_assert_no_error (error); + } + { + g_autoptr (GError) error = NULL; + wp_core_load_component (f->base.core, + "libwireplumber-module-si-convert", "module", NULL, &error); + g_assert_no_error (error); + } +} + +static void +test_si_convert_teardown (TestFixture * f, gconstpointer user_data) +{ + wp_base_test_fixture_teardown (&f->base); +} + +static void +test_si_convert_configure_activate (TestFixture * f, + gconstpointer user_data) +{ + g_autoptr (WpNode) target_node = NULL; + g_autoptr (WpSessionItem) target = NULL; + g_autoptr (WpSessionItem) convert = NULL; + + /* create target node */ + + target_node = wp_node_new_from_factory (f->base.core, + "adapter", + wp_properties_new ( + "factory.name", "audiotestsrc", + "node.name", "audiotestsrc.adapter", + NULL)); + g_assert_nonnull (target_node); + wp_object_activate (WP_OBJECT (target_node), + WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL, NULL, + (GAsyncReadyCallback) test_object_activate_finish_cb, f); + g_main_loop_run (f->base.loop); + + /* create target */ + + target = wp_session_item_make (f->base.core, "si-adapter"); + g_assert_nonnull (target); + g_assert_true (WP_IS_SI_ENDPOINT (target)); + + /* configure target */ + + { + g_auto (GVariantBuilder) b = + G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&b, "{sv}", "node", + g_variant_new_uint64 ((guint64) target_node)); + g_assert_true ( + wp_session_item_configure (target, g_variant_builder_end (&b))); + } + + g_assert_cmphex (wp_session_item_get_flags (target), ==, + WP_SI_FLAG_CONFIGURED); + + /* create convert */ + + convert = wp_session_item_make (f->base.core, "si-convert"); + g_assert_nonnull (convert); + g_assert_true (WP_IS_SI_ENDPOINT (convert)); + + /* configure convert */ + + { + g_auto (GVariantBuilder) b = + G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&b, "{sv}", "target", + g_variant_new_uint64 ((guint64) target)); + g_variant_builder_add (&b, "{sv}", "name", + g_variant_new_string ("convert")); + g_assert_true ( + wp_session_item_configure (convert, g_variant_builder_end (&b))); + + g_assert_cmphex (wp_session_item_get_flags (convert), ==, + WP_SI_FLAG_CONFIGURED); + } + + { + g_autoptr (GVariant) v = wp_session_item_get_configuration (convert); + guint64 target_i; + const gchar *name; + g_assert_nonnull (v); + g_assert_true (g_variant_lookup (v, "target", "t", &target_i)); + g_assert_cmpuint (target_i, ==, (guint64) target); + g_assert_true (g_variant_lookup (v, "name", "&s", &name)); + g_assert_cmpstr (name, ==, "convert"); + } + + /* activate convert */ + + { + wp_session_item_activate (convert, + (GAsyncReadyCallback) test_si_activate_finish_cb, f); + g_main_loop_run (f->base.loop); + } + + g_assert_cmphex (wp_session_item_get_flags (convert), ==, + WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_ACTIVE); + + /* deactivate */ + + wp_session_item_deactivate (convert); +} + +static void +test_si_convert_export (TestFixture * f, gconstpointer user_data) +{ + g_autoptr (WpNode) target_node = NULL; + g_autoptr (WpSessionItem) target = NULL; + g_autoptr (WpSessionItem) convert = NULL; + g_autoptr (WpSession) session = NULL; + g_autoptr (WpObjectManager) clients_om = NULL; + g_autoptr (WpClient) self_client = NULL; + + /* find self_client, to be used for verifying endpoint.client.id */ + + clients_om = wp_object_manager_new (); + wp_object_manager_add_interest (clients_om, WP_TYPE_CLIENT, NULL); + wp_object_manager_request_object_features (clients_om, + WP_TYPE_CLIENT, WP_PROXY_FEATURE_BOUND); + g_signal_connect_swapped (clients_om, "objects-changed", + G_CALLBACK (g_main_loop_quit), f->base.loop); + wp_core_install_object_manager (f->base.core, clients_om); + g_main_loop_run (f->base.loop); + g_assert_nonnull (self_client = + wp_object_manager_lookup (clients_om, WP_TYPE_CLIENT, NULL)); + + /* create target node */ + + target_node = wp_node_new_from_factory (f->base.core, + "adapter", + wp_properties_new ( + "factory.name", "audiotestsrc", + "node.name", "audiotestsrc.adapter", + NULL)); + g_assert_nonnull (target_node); + wp_object_activate (WP_OBJECT (target_node), + WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL, NULL, + (GAsyncReadyCallback) test_object_activate_finish_cb, f); + g_main_loop_run (f->base.loop); + + /* create target */ + + target = wp_session_item_make (f->base.core, "si-adapter"); + g_assert_nonnull (target); + g_assert_true (WP_IS_SI_ENDPOINT (target)); + + /* configure target */ + + { + g_auto (GVariantBuilder) b = + G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&b, "{sv}", "node", + g_variant_new_uint64 ((guint64) target_node)); + g_assert_true ( + wp_session_item_configure (target, g_variant_builder_end (&b))); + g_assert_cmphex (wp_session_item_get_flags (target), ==, + WP_SI_FLAG_CONFIGURED); + } + + /* create convert */ + + convert = wp_session_item_make (f->base.core, "si-convert"); + g_assert_nonnull (convert); + + /* configure convert */ + { + g_auto (GVariantBuilder) b = + G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&b, "{sv}", "target", + g_variant_new_uint64 ((guint64) target)); + g_variant_builder_add (&b, "{sv}", "name", + g_variant_new_string ("convert")); + g_assert_true ( + wp_session_item_configure (convert, g_variant_builder_end (&b))); + g_assert_cmphex (wp_session_item_get_flags (convert), ==, + WP_SI_FLAG_CONFIGURED); + } + + /* activate convert */ + + { + wp_session_item_activate (convert, + (GAsyncReadyCallback) test_si_activate_finish_cb, f); + g_main_loop_run (f->base.loop); + } + + /* create session */ + + session = WP_SESSION (wp_impl_session_new (f->base.core)); + g_assert_nonnull (session); + + wp_object_activate (WP_OBJECT (session), WP_OBJECT_FEATURES_ALL, NULL, + (GAsyncReadyCallback) test_object_activate_finish_cb, f); + g_main_loop_run (f->base.loop); + + /* export */ + + wp_session_item_export (convert, session, + (GAsyncReadyCallback) test_si_export_finish_cb, f); + g_main_loop_run (f->base.loop); + + g_assert_cmphex (wp_session_item_get_flags (convert), ==, + WP_SI_FLAG_CONFIGURED | WP_SI_FLAG_ACTIVE | WP_SI_FLAG_EXPORTED); + + { + g_autoptr (WpEndpoint) ep = NULL; + g_autoptr (WpProperties) props = NULL; + gchar *tmp; + + g_assert_nonnull ( + ep = wp_session_item_get_associated_proxy (convert, WP_TYPE_ENDPOINT)); + g_assert_nonnull ( + props = wp_pipewire_object_get_properties (WP_PIPEWIRE_OBJECT (ep))); + + g_assert_cmpstr (wp_endpoint_get_name (ep), ==, "convert"); + g_assert_cmpstr (wp_endpoint_get_media_class (ep), ==, + "Audio/Convert"); + g_assert_cmpint (wp_endpoint_get_direction (ep), ==, WP_DIRECTION_OUTPUT); + g_assert_cmpstr (wp_properties_get (props, "endpoint.name"), ==, + "convert"); + g_assert_cmpstr (wp_properties_get (props, "media.class"), ==, + "Audio/Convert"); + + tmp = g_strdup_printf ("%d", wp_proxy_get_bound_id (WP_PROXY (session))); + g_assert_cmpstr (wp_properties_get (props, "session.id"), ==, tmp); + g_free (tmp); + } +} + +gint +main (gint argc, gchar *argv[]) +{ + g_test_init (&argc, &argv, NULL); + wp_init (WP_INIT_ALL); + + /* configure-activate */ + + g_test_add ("/modules/si-convert/configure-activate", + TestFixture, NULL, + test_si_convert_setup, + test_si_convert_configure_activate, + test_si_convert_teardown); + + /* export */ + + g_test_add ("/modules/si-convert/export", + TestFixture, NULL, + test_si_convert_setup, + test_si_convert_export, + test_si_convert_teardown); + + return g_test_run (); +} diff --git a/tests/modules/si-simple-node-endpoint.c b/tests/modules/si-simple-node-endpoint.c index cf62c150..89979ba8 100644 --- a/tests/modules/si-simple-node-endpoint.c +++ b/tests/modules/si-simple-node-endpoint.c @@ -58,14 +58,12 @@ test_si_simple_node_endpoint_configure_activate (TestFixture * f, const TestData *data = user_data; g_autoptr (WpNode) node = NULL; g_autoptr (WpSessionItem) item = NULL; - WpSiStream *stream; /* create item */ item = wp_session_item_make (f->base.core, "si-simple-node-endpoint"); g_assert_nonnull (item); g_assert_true (WP_IS_SI_ENDPOINT (item)); - g_assert_true (WP_IS_SI_STREAM (item)); g_assert_true (WP_IS_SI_PORT_INFO (item)); node = wp_node_new_from_factory (f->base.core, @@ -130,11 +128,6 @@ test_si_simple_node_endpoint_configure_activate (TestFixture * f, g_assert_cmphex (wp_object_get_active_features (WP_OBJECT (node)), ==, WP_PIPEWIRE_OBJECT_FEATURES_MINIMAL | WP_NODE_FEATURE_PORTS); - g_assert_cmpint ( - wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (item)), ==, 1); - g_assert_nonnull ( - stream = wp_si_endpoint_get_stream (WP_SI_ENDPOINT (item), 0)); - if (data->expected_direction == WP_DIRECTION_INPUT) g_assert_cmpuint (wp_node_get_n_input_ports (node, NULL), ==, 1); else @@ -144,7 +137,7 @@ test_si_simple_node_endpoint_configure_activate (TestFixture * f, { guint32 node_id, port_id, channel; g_autoptr (GVariant) v = - wp_si_port_info_get_ports (WP_SI_PORT_INFO (stream), NULL); + wp_si_port_info_get_ports (WP_SI_PORT_INFO (item), NULL); g_assert_true (g_variant_is_of_type (v, G_VARIANT_TYPE ("a(uuu)"))); g_assert_cmpint (g_variant_n_children (v), ==, 1); @@ -229,7 +222,6 @@ test_si_simple_node_endpoint_export (TestFixture * f, gconstpointer user_data) g_autoptr (WpSessionItem) item = NULL; g_autoptr (WpObjectManager) clients_om = NULL; g_autoptr (WpClient) self_client = NULL; - WpSiStream *stream; /* find self_client, to be used for verifying endpoint.client.id */ @@ -284,11 +276,6 @@ test_si_simple_node_endpoint_export (TestFixture * f, gconstpointer user_data) (GAsyncReadyCallback) test_si_activate_finish_cb, f); g_main_loop_run (f->base.loop); - g_assert_cmpint ( - wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (item)), ==, 1); - g_assert_nonnull ( - stream = wp_si_endpoint_get_stream (WP_SI_ENDPOINT (item), 0)); - /* create session */ session = WP_SESSION (wp_impl_session_new (f->base.core)); @@ -342,27 +329,6 @@ test_si_simple_node_endpoint_export (TestFixture * f, gconstpointer user_data) g_free (tmp); } - { - g_autoptr (WpEndpointStream) epstr = NULL; - g_autoptr (WpProperties) props = NULL; - gchar *tmp; - - g_assert_nonnull ( - epstr = wp_session_item_get_associated_proxy (WP_SESSION_ITEM (stream), - WP_TYPE_ENDPOINT_STREAM)); - g_assert_nonnull ( - props = wp_pipewire_object_get_properties (WP_PIPEWIRE_OBJECT (epstr))); - - g_assert_cmpstr (wp_endpoint_stream_get_name (epstr), ==, "default"); - g_assert_cmpstr (wp_properties_get (props, "endpoint-stream.name"), ==, - "default"); - - tmp = g_strdup_printf ("%d", wp_session_item_get_associated_proxy_id ( - WP_SESSION_ITEM (stream), WP_TYPE_ENDPOINT)); - g_assert_cmpstr (wp_properties_get (props, "endpoint.id"), ==, tmp); - g_free (tmp); - } - wp_session_item_reset (item); g_assert_cmphex (wp_session_item_get_flags (item), ==, 0); } diff --git a/tests/modules/si-standard-link.c b/tests/modules/si-standard-link.c index eed84b20..c5f20da0 100644 --- a/tests/modules/si-standard-link.c +++ b/tests/modules/si-standard-link.c @@ -173,8 +173,6 @@ test_si_standard_link_main (TestFixture * f, gconstpointer user_data) g_assert_nonnull (sink_ep = wp_session_lookup_endpoint (session_proxy, WP_CONSTRAINT_TYPE_PW_PROPERTY, "endpoint.name", "=s", "fakesink", NULL)); - g_assert_cmpuint (wp_endpoint_get_n_streams (src_ep), ==, 1); - g_assert_cmpuint (wp_endpoint_get_n_streams (sink_ep), ==, 1); /* create the link */ { @@ -198,19 +196,11 @@ test_si_standard_link_main (TestFixture * f, gconstpointer user_data) g_assert_nonnull (ep_link = wp_session_lookup_link (session_proxy, NULL)); { - guint32 out_ep, out_stream, in_ep, in_stream; - g_autoptr (WpEndpointStream) src_stream = NULL; - g_autoptr (WpEndpointStream) sink_stream = NULL; + guint32 out_ep, in_ep; - g_assert_nonnull (src_stream = wp_endpoint_lookup_stream (src_ep, NULL)); - g_assert_nonnull (sink_stream = wp_endpoint_lookup_stream (sink_ep, NULL)); - - wp_endpoint_link_get_linked_object_ids (ep_link, &out_ep, &out_stream, - &in_ep, &in_stream); + wp_endpoint_link_get_linked_object_ids (ep_link, &out_ep, &in_ep); g_assert_cmpuint (out_ep, ==, wp_proxy_get_bound_id (WP_PROXY (src_ep))); g_assert_cmpuint (in_ep, ==, wp_proxy_get_bound_id (WP_PROXY (sink_ep))); - g_assert_cmpuint (out_stream, ==, wp_proxy_get_bound_id (WP_PROXY (src_stream))); - g_assert_cmpuint (in_stream, ==, wp_proxy_get_bound_id (WP_PROXY (sink_stream))); } { @@ -219,9 +209,7 @@ test_si_standard_link_main (TestFixture * f, gconstpointer user_data) g_assert_nonnull (p); g_assert_nonnull (wp_properties_get (p, "endpoint-link.input.endpoint")); - g_assert_nonnull (wp_properties_get (p, "endpoint-link.input.stream")); g_assert_nonnull (wp_properties_get (p, "endpoint-link.output.endpoint")); - g_assert_nonnull (wp_properties_get (p, "endpoint-link.output.stream")); } { @@ -367,13 +355,11 @@ test_si_standard_link_destroy (TestFixture * f, gconstpointer user_data) /* find the endpoints */ g_assert_nonnull (src_ep = wp_session_lookup_endpoint (session_proxy, - WP_CONSTRAINT_TYPE_PW_PROPERTY, "endpoint.name", "=s", "audiotestsrc", - NULL)); + WP_CONSTRAINT_TYPE_PW_PROPERTY, "endpoint.name", "=s", "audiotestsrc", + NULL)); g_assert_nonnull (sink_ep = wp_session_lookup_endpoint (session_proxy, - WP_CONSTRAINT_TYPE_PW_PROPERTY, "endpoint.name", "=s", "fakesink", - NULL)); - g_assert_cmpuint (wp_endpoint_get_n_streams (src_ep), ==, 1); - g_assert_cmpuint (wp_endpoint_get_n_streams (sink_ep), ==, 1); + WP_CONSTRAINT_TYPE_PW_PROPERTY, "endpoint.name", "=s", "fakesink", + NULL)); /* create the link */ { diff --git a/tests/wp/endpoint.c b/tests/wp/endpoint.c index eb61596b..421e3689 100644 --- a/tests/wp/endpoint.c +++ b/tests/wp/endpoint.c @@ -47,63 +47,15 @@ test_si_endpoint_get_properties (WpSiEndpoint * item) return wp_properties_new ("test.property", "test-value", NULL); } -static guint -test_si_endpoint_get_n_streams (WpSiEndpoint * item) -{ - return 1; -} - -static WpSiStream * -test_si_endpoint_get_stream (WpSiEndpoint * item, guint index) -{ - g_return_val_if_fail (index == 0, NULL); - return WP_SI_STREAM (item); -} - static void test_si_endpoint_endpoint_init (WpSiEndpointInterface * iface) { iface->get_registration_info = test_si_endpoint_get_registration_info; iface->get_properties = test_si_endpoint_get_properties; - iface->get_n_streams = test_si_endpoint_get_n_streams; - iface->get_stream = test_si_endpoint_get_stream; -} - -static GVariant * -test_si_endpoint_get_stream_registration_info (WpSiStream * self) -{ - GVariantBuilder b; - - g_variant_builder_init (&b, G_VARIANT_TYPE ("(sa{ss})")); - g_variant_builder_add (&b, "s", "default"); - g_variant_builder_add (&b, "a{ss}", NULL); - - return g_variant_builder_end (&b); -} - -static WpProperties * -test_si_endpoint_get_stream_properties (WpSiStream * self) -{ - return wp_properties_new ("stream.property", "test-value-2", NULL); -} - -static WpSiEndpoint * -test_si_endpoint_get_stream_parent_endpoint (WpSiStream * self) -{ - return WP_SI_ENDPOINT (g_object_ref (self)); -} - -static void -test_si_endpoint_stream_init (WpSiStreamInterface * iface) -{ - iface->get_registration_info = test_si_endpoint_get_stream_registration_info; - iface->get_properties = test_si_endpoint_get_stream_properties; - iface->get_parent_endpoint = test_si_endpoint_get_stream_parent_endpoint; } G_DEFINE_TYPE_WITH_CODE (TestSiEndpoint, test_si_endpoint, WP_TYPE_SESSION_ITEM, - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, test_si_endpoint_endpoint_init) - G_IMPLEMENT_INTERFACE (WP_TYPE_SI_STREAM, test_si_endpoint_stream_init)) + G_IMPLEMENT_INTERFACE (WP_TYPE_SI_ENDPOINT, test_si_endpoint_endpoint_init)) static void test_si_endpoint_init (TestSiEndpoint * self) diff --git a/tools/wpctl.c b/tools/wpctl.c index 0ac6bac5..4b007614 100644 --- a/tools/wpctl.c +++ b/tools/wpctl.c @@ -26,10 +26,6 @@ struct _WpCtl static struct { union { - struct { - gboolean show_streams; - } status; - struct { guint32 id; gboolean show_referenced; @@ -119,19 +115,6 @@ print_controls (WpPipewireObject * pwobj) printf ("\n"); } -static void -print_stream (const GValue *item, gpointer data) -{ - WpEndpointStream *stream = g_value_get_object (item); - guint32 id = wp_proxy_get_bound_id (WP_PROXY (stream)); - guint *n_streams = data; - - printf (TREE_INDENT_LINE TREE_INDENT_EMPTY " %s%4u. %-53s", - (--(*n_streams) == 0) ? TREE_INDENT_END : TREE_INDENT_NODE, - id, wp_endpoint_stream_get_name (stream)); - print_controls (WP_PIPEWIRE_OBJECT (stream)); -} - static const gchar * get_endpoint_friendly_name (WpEndpoint * ep) { @@ -152,13 +135,6 @@ print_endpoint (const GValue *item, gpointer data) printf (TREE_INDENT_LINE "%c %4u. %-60s", (default_id == id) ? '*' : ' ', id, get_endpoint_friendly_name (ep)); print_controls (WP_PIPEWIRE_OBJECT (ep)); - - if (cmdline.status.show_streams) { - g_autoptr (WpIterator) it = wp_endpoint_new_streams_iterator (ep); - guint n_streams = wp_endpoint_get_n_streams (ep); - wp_iterator_foreach (it, print_stream, &n_streams); - printf (TREE_INDENT_LINE "\n"); - } } static void @@ -167,30 +143,20 @@ print_endpoint_link (const GValue *item, gpointer data) WpEndpointLink *link = g_value_get_object (item); WpSession *session = data; guint32 id = wp_proxy_get_bound_id (WP_PROXY (link)); - guint32 out_ep_id, out_stream_id, in_ep_id, in_stream_id; + guint32 out_ep_id, in_ep_id; g_autoptr (WpEndpoint) out_ep = NULL; g_autoptr (WpEndpoint) in_ep = NULL; - g_autoptr (WpEndpointStream) out_stream = NULL; - g_autoptr (WpEndpointStream) in_stream = NULL; - wp_endpoint_link_get_linked_object_ids (link, - &out_ep_id, &out_stream_id, &in_ep_id, &in_stream_id); + wp_endpoint_link_get_linked_object_ids (link, &out_ep_id, &in_ep_id); out_ep = wp_session_lookup_endpoint (session, WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", out_ep_id, NULL); in_ep = wp_session_lookup_endpoint (session, WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", in_ep_id, NULL); - out_stream = wp_endpoint_lookup_stream (out_ep, - WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", out_stream_id, NULL); - in_stream = wp_endpoint_lookup_stream (in_ep, - WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", in_stream_id, NULL); - - printf (TREE_INDENT_EMPTY " %4u. [%u. %s|%s] ➞ [%u. %s|%s]\n", id, + printf (TREE_INDENT_EMPTY " %4u. [%u. %s] ➞ [%u. %s]\n", id, out_ep_id, get_endpoint_friendly_name (out_ep), - wp_endpoint_stream_get_name (out_stream), - in_ep_id, get_endpoint_friendly_name (in_ep), - wp_endpoint_stream_get_name (in_stream)); + in_ep_id, get_endpoint_friendly_name (in_ep)); } static void @@ -625,10 +591,6 @@ set_volume_prepare (WpCtl * self, GError ** error) WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "object.id", "=u", cmdline.set_volume.id, NULL); - wp_object_manager_add_interest (self->om, WP_TYPE_ENDPOINT_STREAM, - WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, - "object.id", "=u", cmdline.set_volume.id, - NULL); wp_object_manager_add_interest (self->om, WP_TYPE_NODE, WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "object.id", "=u", cmdline.set_volume.id, @@ -714,10 +676,6 @@ set_mute_prepare (WpCtl * self, GError ** error) WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "object.id", "=u", cmdline.set_mute.id, NULL); - wp_object_manager_add_interest (self->om, WP_TYPE_ENDPOINT_STREAM, - WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, - "object.id", "=u", cmdline.set_mute.id, - NULL); wp_object_manager_add_interest (self->om, WP_TYPE_NODE, WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY, "object.id", "=u", cmdline.set_mute.id, @@ -851,11 +809,7 @@ static const struct subcommand { .positional_args = "", .summary = "Displays the current state of objects in PipeWire", .description = NULL, - .entries = { - { "streams", 's', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, - &cmdline.status.show_streams, "Also show endpoint streams", NULL }, - { NULL } - }, + .entries = { { NULL } }, .parse_positional = NULL, .prepare = status_prepare, .run = status_run,