Commit ceee3c48 authored by Julian Bouzas's avatar Julian Bouzas
Browse files

wip

parent 850a3de1
Pipeline #255573 passed with stages
in 1 minute and 5 seconds
......@@ -18,6 +18,9 @@
#define default_endpoint_key(dir) ((dir == WP_DIRECTION_INPUT) ? \
"default.session.endpoint.sink" : "default.session.endpoint.source")
#define default_audio_node_key(dir) ((dir == WP_DIRECTION_INPUT) ? \
"default.audio.sink" : "default.audio.source")
struct _WpDefaultEndpoints
{
void *self;
......@@ -70,6 +73,56 @@ timeout_save_profiles (WpDefaultMetadata *self, guint dir, guint ms)
self->default_endpoints + dir, NULL);
}
static WpEndpoint *
find_endpoint_with_session_id (WpDefaultMetadata * self, guint session_id,
guint ep_id, WpSession **session)
{
g_autoptr (WpSession) s = NULL;
g_autoptr (WpEndpoint) ep = NULL;
s = wp_object_manager_lookup (self->sessions_om, WP_TYPE_SESSION,
WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", session_id, NULL);
if (!s)
return NULL;
ep = wp_session_lookup_endpoint (s, WP_CONSTRAINT_TYPE_G_PROPERTY,
"bound-id", "=u", ep_id, NULL);
if (!ep)
return NULL;
if (session)
*session = g_object_ref (s);
return g_object_ref (ep);
}
static WpEndpoint *
find_endpoint_with_associated_node_id (WpDefaultMetadata * self, guint node_id,
WpSession **session)
{
g_autoptr (WpIterator) it = NULL;
g_auto (GValue) value = G_VALUE_INIT;
it = wp_object_manager_iterate (self->sessions_om);
for (; wp_iterator_next (it, &value); g_value_unset (&value)) {
WpSession *s = g_value_get_object (&value);
g_autoptr (WpIterator) it_ep = wp_session_iterate_endpoints (s);
g_auto (GValue) value_ep = G_VALUE_INIT;
for (; wp_iterator_next (it_ep, &value_ep); g_value_unset (&value_ep)) {
WpEndpoint *ep = g_value_get_object (&value_ep);
g_autoptr (WpNode) node = wp_session_item_get_associated_proxy (
WP_SESSION_ITEM (ep), WP_TYPE_NODE);
if (wp_proxy_get_bound_id (WP_PROXY (node)) == node_id) {
if (session)
*session = g_object_ref (s);
return g_object_ref (ep);
}
}
}
return NULL;
}
static void
on_default_metadata_changed (WpMetadata *m, guint32 subject,
const gchar *key, const gchar *type, const gchar *value, gpointer *d)
......@@ -79,26 +132,42 @@ on_default_metadata_changed (WpMetadata *m, guint32 subject,
g_autoptr (WpEndpoint) ep = NULL;
const gchar *session_name = NULL, *ep_name = NULL;
guint dir = WP_DIRECTION_INPUT;
gboolean default_ep = FALSE;
/* Get the direction */
if (!g_strcmp0 (key, default_endpoint_key (WP_DIRECTION_INPUT)))
if (!g_strcmp0 (key, default_endpoint_key (WP_DIRECTION_INPUT))) {
dir = WP_DIRECTION_INPUT;
default_ep = TRUE;
} else if (!g_strcmp0 (key, default_endpoint_key (WP_DIRECTION_OUTPUT))) {
dir = WP_DIRECTION_OUTPUT;
default_ep = TRUE;
} else if (!g_strcmp0 (key, default_audio_node_key (WP_DIRECTION_INPUT))) {
dir = WP_DIRECTION_INPUT;
else if (!g_strcmp0 (key, default_endpoint_key (WP_DIRECTION_OUTPUT)))
default_ep = FALSE;
} else if (!g_strcmp0 (key, default_audio_node_key (WP_DIRECTION_OUTPUT))) {
dir = WP_DIRECTION_OUTPUT;
else
default_ep = FALSE;
} else {
return;
}
/* Find the session */
session = wp_object_manager_lookup (self->sessions_om, WP_TYPE_SESSION,
WP_CONSTRAINT_TYPE_G_PROPERTY, "bound-id", "=u", subject, NULL);
if (!session)
/* Get the edpoint and session */
ep = default_ep ?
find_endpoint_with_session_id (self, subject, atoi (value), &session) :
find_endpoint_with_associated_node_id (self, atoi (value), &session);
if (!ep || !session)
return;
/* Find the endpoint */
ep = wp_session_lookup_endpoint (session, WP_CONSTRAINT_TYPE_G_PROPERTY,
"bound-id", "=u", atoi (value), NULL);
if (!ep)
return;
/* Update the default endpoint in the metadata if default_ep is FALSE */
if (!default_ep) {
g_signal_handlers_block_by_func (m, on_default_metadata_changed, self);
g_autofree gchar *v = g_strdup_printf ("%d",
wp_proxy_get_bound_id (WP_PROXY (ep)));
wp_metadata_set (m, wp_proxy_get_bound_id (WP_PROXY (session)),
default_endpoint_key (dir), "Spa:Int", v);
g_signal_handlers_unblock_by_func (m, on_default_metadata_changed, self);
}
/* Get the session name and endpoint name */
session_name = wp_session_get_name (session);
......@@ -111,13 +180,13 @@ on_default_metadata_changed (WpMetadata *m, guint32 subject,
timeout_save_profiles (self, dir, SAVE_INTERVAL_MS);
}
static guint32
find_highest_prio (WpSession * session, WpDirection dir)
static WpEndpoint *
find_highest_priority_endpoint (WpSession * session, WpDirection dir)
{
g_autoptr (WpIterator) it = NULL;
g_auto (GValue) val = G_VALUE_INIT;
gint highest_prio = 0;
guint32 id = 0;
WpEndpoint *res = 0;
it = wp_session_iterate_endpoints_filtered (session,
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s",
......@@ -125,17 +194,18 @@ find_highest_prio (WpSession * session, WpDirection dir)
NULL);
for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
WpProxy *ep = g_value_get_object (&val);
WpEndpoint *ep = g_value_get_object (&val);
const gchar *prio_str = wp_pipewire_object_get_property (
WP_PIPEWIRE_OBJECT (ep), "endpoint.priority");
gint prio = atoi (prio_str);
if (prio > highest_prio || id == 0) {
if (prio > highest_prio || res == NULL) {
highest_prio = prio;
id = wp_proxy_get_bound_id (ep);
g_clear_object (&res);
res = g_object_ref (ep);
}
}
return id;
return res;
}
static void
......@@ -143,8 +213,10 @@ reevaluate_default_endpoints (WpDefaultMetadata * self, WpSession *session,
guint dir)
{
g_autoptr (WpMetadata) m = g_weak_ref_get (&self->metadata);
guint32 ep_id = 0;
g_autoptr (WpEndpoint) ep = NULL;
g_autoptr (WpNode) node = NULL;
const gchar *session_name = NULL, *ep_name = NULL;
guint ep_id = 0;
g_return_if_fail (self->default_endpoints[dir].props);
......@@ -152,31 +224,46 @@ reevaluate_default_endpoints (WpDefaultMetadata * self, WpSession *session,
session_name = wp_session_get_name (session);
ep_name = wp_properties_get (self->default_endpoints[dir].props, session_name);
if (ep_name) {
g_autoptr (WpEndpoint) ep = wp_session_lookup_endpoint (session,
ep = wp_session_lookup_endpoint (session,
WP_CONSTRAINT_TYPE_PW_PROPERTY, "endpoint.name", "=s", ep_name,
WP_CONSTRAINT_TYPE_PW_PROPERTY, "media.class", "#s",
(dir == WP_DIRECTION_INPUT) ? "*/Sink" : "*/Source", NULL);
if (ep)
ep_id = wp_proxy_get_bound_id (WP_PROXY (ep));
}
/* If not found, use the highest priority one */
if (ep_id == 0)
ep_id = find_highest_prio (session, dir);
if (!ep)
ep = find_highest_priority_endpoint (session, dir);
g_return_if_fail (ep);
ep_id = wp_proxy_get_bound_id (WP_PROXY (ep));
if (m && ep_id != 0) {
if (m && ep) {
/* block the signal to avoid storing this; only selections done by the user
* should be stored */
g_autofree gchar *value = g_strdup_printf ("%d", ep_id);
g_signal_handlers_block_by_func (m, on_default_metadata_changed, self);
/* Set default endpoint */
g_autofree gchar *value = g_strdup_printf ("%d", ep_id);
wp_metadata_set (m, wp_proxy_get_bound_id (WP_PROXY (session)),
default_endpoint_key (dir), "Spa:Int", value);
/* Set also the default audio node if associated node is an audio node */
node = wp_session_item_get_associated_proxy (WP_SESSION_ITEM (ep),
WP_TYPE_NODE);
if (node) {
const char *media_class = wp_pipewire_object_get_property (
WP_PIPEWIRE_OBJECT (node), "media.class");
if (g_str_has_prefix (media_class, "Audio/")) {
g_autofree gchar *v = g_strdup_printf ("%d",
wp_proxy_get_bound_id (WP_PROXY (node)));
wp_metadata_set (m, 0, default_audio_node_key (dir), "Spa:Int", v);
}
}
g_signal_handlers_unblock_by_func (m, on_default_metadata_changed, self);
wp_info_object (self, "set default %s endpoint with id %d on session '%s'",
direction_to_dbg_string (dir), ep_id, session_name);
}
}
static void
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment