mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2025-12-20 06:30:04 +01:00
policy: add a hack that allows some clients to be linked always
This allows the bluealsa gstreamer helper to link to the speakers constantly, with both A2DP and HFP streams. If this is not enabled, only one of those will manage to connect, randomly. This is definitely something to be superseeded by proper policy management implemented with configuration files
This commit is contained in:
parent
22957e6e6d
commit
50db6a5930
2 changed files with 50 additions and 10 deletions
|
|
@ -260,6 +260,7 @@ on_proxy_node_created(GObject *initable, GAsyncResult *res, gpointer data)
|
||||||
uint32_t ids[1] = { SPA_PARAM_Props };
|
uint32_t ids[1] = { SPA_PARAM_Props };
|
||||||
uint32_t n_ids = 1;
|
uint32_t n_ids = 1;
|
||||||
struct pw_node_proxy *node_proxy = NULL;
|
struct pw_node_proxy *node_proxy = NULL;
|
||||||
|
const struct spa_dict *props;
|
||||||
|
|
||||||
/* Get the proxy node */
|
/* Get the proxy node */
|
||||||
self->proxy_node = WP_PROXY_NODE (object_safe_new_finish (self, initable,
|
self->proxy_node = WP_PROXY_NODE (object_safe_new_finish (self, initable,
|
||||||
|
|
@ -267,11 +268,18 @@ on_proxy_node_created(GObject *initable, GAsyncResult *res, gpointer data)
|
||||||
if (!self->proxy_node)
|
if (!self->proxy_node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
props = wp_proxy_node_get_info (self->proxy_node)->props;
|
||||||
|
|
||||||
/* Set the role and target name */
|
/* Set the role and target name */
|
||||||
self->role = g_strdup (spa_dict_lookup (
|
self->role = g_strdup (spa_dict_lookup (props, "media.role"));
|
||||||
wp_proxy_node_get_info (self->proxy_node)->props, "media.role"));
|
self->target = g_strdup (spa_dict_lookup (props, "target.name"));
|
||||||
self->target = g_strdup (spa_dict_lookup (
|
|
||||||
wp_proxy_node_get_info (self->proxy_node)->props, "target.name"));
|
/* HACK to tell the policy module that this endpoint needs to be linked always */
|
||||||
|
if (spa_dict_lookup (props, "wireplumber.keep-linked")) {
|
||||||
|
g_autofree gchar *c = g_strdup_printf ("Persistent/%s",
|
||||||
|
spa_dict_lookup(props, "media.class"));
|
||||||
|
g_object_set (self, "media-class", c, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Emit the ports */
|
/* Emit the ports */
|
||||||
emit_endpoint_ports(self);
|
emit_endpoint_ports(self);
|
||||||
|
|
|
||||||
|
|
@ -273,10 +273,12 @@ handle_client (WpPolicy *policy, WpEndpoint *ep)
|
||||||
g_autoptr (WpEndpoint) target = NULL;
|
g_autoptr (WpEndpoint) target = NULL;
|
||||||
guint32 stream_id;
|
guint32 stream_id;
|
||||||
gboolean is_capture = FALSE;
|
gboolean is_capture = FALSE;
|
||||||
|
gboolean is_persistent = FALSE;
|
||||||
g_autofree gchar *role, *target_name = NULL;
|
g_autofree gchar *role, *target_name = NULL;
|
||||||
|
|
||||||
/* Detect if the client is doing capture or playback */
|
/* Detect if the client is doing capture or playback */
|
||||||
is_capture = g_str_has_prefix (media_class, "Stream/Input");
|
is_capture = g_str_has_prefix (media_class, "Stream/Input");
|
||||||
|
is_persistent = g_str_has_prefix (media_class, "Persistent/");
|
||||||
|
|
||||||
/* Locate the target endpoint */
|
/* Locate the target endpoint */
|
||||||
g_variant_dict_init (&d, NULL);
|
g_variant_dict_init (&d, NULL);
|
||||||
|
|
@ -334,11 +336,20 @@ handle_client (WpPolicy *policy, WpEndpoint *ep)
|
||||||
* this function is being called after sorting all the client endpoints
|
* this function is being called after sorting all the client endpoints
|
||||||
* and therefore we can safely unlink the previous client
|
* and therefore we can safely unlink the previous client
|
||||||
*/
|
*/
|
||||||
if (wp_endpoint_is_linked (target) && !is_capture) {
|
if (!is_capture && wp_endpoint_is_linked (target)) {
|
||||||
|
if (is_persistent) {
|
||||||
|
/* HACK: link persistent endpoints to the already linked stream,
|
||||||
|
as linking to another stream does not work properly
|
||||||
|
(floatmix on the master dsp port does not accept the link) */
|
||||||
|
GPtrArray *links = wp_endpoint_get_links (target);
|
||||||
|
WpEndpointLink *l = g_ptr_array_index (links, 0);
|
||||||
|
stream_id = wp_endpoint_link_get_sink_stream (l);
|
||||||
|
} else {
|
||||||
g_debug ("Unlink target '%s' from other clients",
|
g_debug ("Unlink target '%s' from other clients",
|
||||||
wp_endpoint_get_name (target));
|
wp_endpoint_get_name (target));
|
||||||
wp_endpoint_unlink (target);
|
wp_endpoint_unlink (target);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Link the client with the target */
|
/* Link the client with the target */
|
||||||
if (is_capture) {
|
if (is_capture) {
|
||||||
|
|
@ -411,6 +422,17 @@ simple_policy_rescan_in_idle (WpSimplePolicy *self)
|
||||||
handle_client (WP_POLICY (self), ep);
|
handle_client (WP_POLICY (self), ep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g_clear_pointer (&endpoints, g_ptr_array_unref);
|
||||||
|
|
||||||
|
endpoints = wp_endpoint_find (core, "Persistent/Stream/Input/Audio");
|
||||||
|
if (endpoints) {
|
||||||
|
/* link all persistent capture clients */
|
||||||
|
for (i = 0; i < endpoints->len; i++) {
|
||||||
|
ep = g_ptr_array_index (endpoints, i);
|
||||||
|
handle_client (WP_POLICY (self), ep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_clear_pointer (&endpoints, g_ptr_array_unref);
|
||||||
|
|
||||||
endpoints = wp_endpoint_find (core, "Stream/Output/Audio");
|
endpoints = wp_endpoint_find (core, "Stream/Output/Audio");
|
||||||
if (endpoints && endpoints->len > 0) {
|
if (endpoints && endpoints->len > 0) {
|
||||||
|
|
@ -422,6 +444,17 @@ simple_policy_rescan_in_idle (WpSimplePolicy *self)
|
||||||
ep = g_ptr_array_index (endpoints, 0);
|
ep = g_ptr_array_index (endpoints, 0);
|
||||||
handle_client (WP_POLICY (self), ep);
|
handle_client (WP_POLICY (self), ep);
|
||||||
}
|
}
|
||||||
|
g_clear_pointer (&endpoints, g_ptr_array_unref);
|
||||||
|
|
||||||
|
endpoints = wp_endpoint_find (core, "Persistent/Stream/Output/Audio");
|
||||||
|
if (endpoints) {
|
||||||
|
/* link all persistent output clients */
|
||||||
|
for (i = 0; i < endpoints->len; i++) {
|
||||||
|
ep = g_ptr_array_index (endpoints, i);
|
||||||
|
handle_client (WP_POLICY (self), ep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_clear_pointer (&endpoints, g_ptr_array_unref);
|
||||||
|
|
||||||
self->pending_rescan = 0;
|
self->pending_rescan = 0;
|
||||||
return G_SOURCE_REMOVE;
|
return G_SOURCE_REMOVE;
|
||||||
|
|
@ -443,8 +476,7 @@ simple_policy_handle_endpoint (WpPolicy *policy, WpEndpoint *ep)
|
||||||
|
|
||||||
/* TODO: For now we only accept audio stream clients */
|
/* TODO: For now we only accept audio stream clients */
|
||||||
media_class = wp_endpoint_get_media_class(ep);
|
media_class = wp_endpoint_get_media_class(ep);
|
||||||
if (!g_str_has_prefix (media_class, "Stream") ||
|
if (!g_str_has_suffix (media_class, "Audio")) {
|
||||||
!g_str_has_suffix (media_class, "Audio")) {
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue