si-adapter: call format task if port param-info is triggered in non DSP mode

This is needed so that the async callback passed to _set_ports_format is called
when changing the adapter's port format and the port has not been removed or
added. Eg: when configuring the adapter in S16 convert mode to S32 convert mode.
This commit is contained in:
Julian Bouzas 2021-09-29 13:13:19 -04:00
parent 334d92b5cb
commit 30b1dd7b4c
2 changed files with 70 additions and 4 deletions

View file

@ -24,6 +24,7 @@ struct _WpSiAudioAdapter
/* configuration */
WpNode *node;
WpPort *port; /* only used for passthrough or convert mode */
gchar name[96];
gchar media_class[32];
gboolean control_port;
@ -63,6 +64,7 @@ si_audio_adapter_reset (WpSessionItem * item)
/* reset */
g_clear_object (&self->node);
g_clear_object (&self->port);
self->name[0] = '\0';
self->media_class[0] = '\0';
self->control_port = FALSE;
@ -392,15 +394,46 @@ on_node_enum_format_done (WpPipewireObject * proxy, GAsyncResult * res,
}
static void
on_node_ports_changed (WpObject * node, WpSiAudioAdapter *self)
on_port_param_info (WpPipewireObject * port, GParamSpec * param,
WpSiAudioAdapter *self)
{
/* finish the task started by _set_ports_format() */
if (self->format_task && wp_node_get_n_ports (self->node) > 0) {
if (self->format_task) {
g_autoptr (GTask) t = g_steal_pointer (&self->format_task);
g_task_return_boolean (t, TRUE);
}
}
static void
on_node_ports_changed (WpObject * node, WpSiAudioAdapter *self)
{
/* clear port and handler */
if (self->port) {
g_signal_handlers_disconnect_by_func (self->port, on_port_param_info, self);
g_clear_object (&self->port);
}
if (wp_node_get_n_ports (self->node) > 0) {
/* if non DSP mode, listen for param-info on the single port in order to
* be notified of format changed events */
if (g_strcmp0 (self->mode, "dsp") != 0) {
self->port = wp_node_lookup_port (self->node,
WP_CONSTRAINT_TYPE_PW_PROPERTY, "port.direction", "=s",
self->portconfig_direction == WP_DIRECTION_INPUT ? "in" : "out",
NULL);
if (self->port)
g_signal_connect_object (self->port, "notify::param-info",
G_CALLBACK (on_port_param_info), self, 0);
}
/* finish the task started by _set_ports_format() */
if (self->format_task) {
g_autoptr (GTask) t = g_steal_pointer (&self->format_task);
g_task_return_boolean (t, TRUE);
}
}
}
static void
on_feature_ports_ready (WpObject * node, GAsyncResult * res,
WpTransition * transition)

View file

@ -30,6 +30,7 @@ struct _WpSiAudioEndpoint
/* activation */
WpNode *node;
WpPort *port; /* only used for passthrough or convert mode */
/* export */
WpImplEndpoint *impl_endpoint;
@ -144,6 +145,7 @@ si_audio_endpoint_disable_active (WpSessionItem *si)
WpSiAudioEndpoint *self = WP_SI_AUDIO_ENDPOINT (si);
g_clear_object (&self->node);
g_clear_object (&self->port);
wp_object_update_features (WP_OBJECT (self), 0,
WP_SESSION_ITEM_FEATURE_ACTIVE);
}
@ -159,15 +161,46 @@ si_audio_endpoint_disable_exported (WpSessionItem *si)
}
static void
on_node_ports_changed (WpObject * node, WpSiAudioEndpoint *self)
on_port_param_info (WpPipewireObject * port, GParamSpec * param,
WpSiAudioEndpoint *self)
{
/* finish the task started by _set_ports_format() */
if (self->format_task && wp_node_get_n_ports (self->node) > 0) {
if (self->format_task) {
g_autoptr (GTask) t = g_steal_pointer (&self->format_task);
g_task_return_boolean (t, TRUE);
}
}
static void
on_node_ports_changed (WpObject * node, WpSiAudioEndpoint *self)
{
/* clear port and handler */
if (self->port) {
g_signal_handlers_disconnect_by_func (self->port, on_port_param_info, self);
g_clear_object (&self->port);
}
if (wp_node_get_n_ports (self->node) > 0) {
/* if non DSP mode, listen for param-info on the single port in order to
* be notified of format changed events */
if (g_strcmp0 (self->mode, "dsp") != 0) {
self->port = wp_node_lookup_port (self->node,
WP_CONSTRAINT_TYPE_PW_PROPERTY, "port.direction", "=s",
self->direction == WP_DIRECTION_INPUT ? "in" : "out",
NULL);
if (self->port)
g_signal_connect_object (self->port, "notify::param-info",
G_CALLBACK (on_port_param_info), self, 0);
}
/* finish the task started by _set_ports_format() */
if (self->format_task) {
g_autoptr (GTask) t = g_steal_pointer (&self->format_task);
g_task_return_boolean (t, TRUE);
}
}
}
static void
on_node_activate_done (WpObject * node, GAsyncResult * res,
WpTransition * transition)