Skip to content
Snippets Groups Projects
Commit de97be85 authored by Julian Bouzas's avatar Julian Bouzas
Browse files

adapter: do not use hardcoded format

parent 6786b13f
No related branches found
No related tags found
No related merge requests found
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "error.h" #include "error.h"
#include "proxy-node.h" #include "proxy-node.h"
#include <pipewire/pipewire.h> #include <pipewire/pipewire.h>
#include <spa/param/audio/format-utils.h>
struct _WpProxyNode struct _WpProxyNode
{ {
...@@ -22,6 +23,11 @@ struct _WpProxyNode ...@@ -22,6 +23,11 @@ struct _WpProxyNode
/* The node info */ /* The node info */
struct pw_node_info *info; struct pw_node_info *info;
/* The node format, if any */
uint32_t media_type;
uint32_t media_subtype;
struct spa_audio_info_raw format;
}; };
static void wp_proxy_node_async_initable_init (gpointer iface, static void wp_proxy_node_async_initable_init (gpointer iface,
...@@ -48,9 +54,33 @@ node_event_info(void *data, const struct pw_node_info *info) ...@@ -48,9 +54,33 @@ node_event_info(void *data, const struct pw_node_info *info)
g_clear_object (&self->init_task); g_clear_object (&self->init_task);
} }
static void
node_event_param(void *data, int seq, uint32_t id, uint32_t index,
uint32_t next, const struct spa_pod *param)
{
WpProxyNode *self = data;
/* Only handle EnumFormat */
if (id != SPA_PARAM_EnumFormat)
return;
/* Parse the format */
spa_format_parse(param, &self->media_type, &self->media_subtype);
/* Only handle raw audio formats for now */
if (self->media_type != SPA_MEDIA_TYPE_audio ||
self->media_subtype != SPA_MEDIA_SUBTYPE_raw)
return;
/* Parse the raw audio format */
spa_pod_fixate((struct spa_pod*)param);
spa_format_audio_raw_parse(param, &self->format);
}
static const struct pw_node_proxy_events node_events = { static const struct pw_node_proxy_events node_events = {
PW_VERSION_NODE_PROXY_EVENTS, PW_VERSION_NODE_PROXY_EVENTS,
.info = node_event_info, .info = node_event_info,
.param = node_event_param,
}; };
static void static void
...@@ -152,3 +182,16 @@ wp_proxy_node_get_info (WpProxyNode * self) ...@@ -152,3 +182,16 @@ wp_proxy_node_get_info (WpProxyNode * self)
{ {
return self->info; return self->info;
} }
const struct spa_audio_info_raw *
wp_proxy_node_get_format (WpProxyNode * self)
{
return &self->format;
}
void wp_proxy_node_enum_params(WpProxyNode * self, guint id, guint index,
guint num, guint next, gconstpointer filter)
{
pw_port_proxy_enum_params (wp_proxy_get_pw_proxy (WP_PROXY (self)), id,
index, num, next, filter);
}
...@@ -23,6 +23,10 @@ WpProxyNode *wp_proxy_node_new_finish(GObject *initable, GAsyncResult *res, ...@@ -23,6 +23,10 @@ WpProxyNode *wp_proxy_node_new_finish(GObject *initable, GAsyncResult *res,
GError **error); GError **error);
const struct pw_node_info *wp_proxy_node_get_info (WpProxyNode * self); const struct pw_node_info *wp_proxy_node_get_info (WpProxyNode * self);
const struct spa_audio_info_raw *wp_proxy_node_get_format (WpProxyNode * self);
void wp_proxy_node_enum_params(WpProxyNode * self, guint id, guint index,
guint num, guint next, gconstpointer filter);
G_END_DECLS G_END_DECLS
......
...@@ -26,6 +26,7 @@ struct _WpAudioAdapter ...@@ -26,6 +26,7 @@ struct _WpAudioAdapter
/* The task to signal the proxy is initialized */ /* The task to signal the proxy is initialized */
GTask *init_task; GTask *init_task;
gboolean init_abort; gboolean init_abort;
gboolean ports_done;
/* Props */ /* Props */
guint adapter_id; guint adapter_id;
...@@ -79,9 +80,45 @@ on_audio_adapter_done(WpProxy *proxy, gpointer data) ...@@ -79,9 +80,45 @@ on_audio_adapter_done(WpProxy *proxy, gpointer data)
{ {
WpAudioAdapter *self = data; WpAudioAdapter *self = data;
/* Emit the ports if not done and sync again */
if (!self->ports_done) {
enum pw_direction direction =
wp_audio_stream_get_direction ( WP_AUDIO_STREAM (self));
struct pw_node_proxy *pw_proxy = NULL;
uint8_t buf[1024];
struct spa_pod_builder pod_builder = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
struct spa_pod *param;
/* Emit the props param */
pw_proxy = wp_proxy_get_pw_proxy(WP_PROXY(self->proxy));
pw_node_proxy_enum_params (pw_proxy, 0, SPA_PARAM_Props, 0, -1, NULL);
/* Emit the ports */
if (self->convert) {
param = spa_pod_builder_add_object(&pod_builder,
SPA_TYPE_OBJECT_ParamPortConfig, SPA_PARAM_PortConfig,
SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(direction),
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_convert));
} else {
struct spa_audio_info_raw format = *wp_proxy_node_get_format (self->proxy);
param = spa_format_audio_raw_build(&pod_builder, SPA_PARAM_Format, &format);
param = spa_pod_builder_add_object(&pod_builder,
SPA_TYPE_OBJECT_ParamPortConfig, SPA_PARAM_PortConfig,
SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(direction),
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp),
SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param));
}
pw_node_proxy_set_param(pw_proxy, SPA_PARAM_PortConfig, 0, param);
/* Sync */
self->ports_done = TRUE;
wp_proxy_sync (WP_PROXY(self->proxy));
return;
}
/* Don't do anything if the audio adapter has already been initialized */ /* Don't do anything if the audio adapter has already been initialized */
if (!self->init_task) if (!self->init_task)
return; return;
/* Finish the creation of the audio adapter */ /* Finish the creation of the audio adapter */
g_task_return_boolean (self->init_task, TRUE); g_task_return_boolean (self->init_task, TRUE);
...@@ -93,12 +130,6 @@ on_audio_adapter_proxy_created(GObject *initable, GAsyncResult *res, ...@@ -93,12 +130,6 @@ on_audio_adapter_proxy_created(GObject *initable, GAsyncResult *res,
gpointer data) gpointer data)
{ {
WpAudioAdapter *self = data; WpAudioAdapter *self = data;
enum pw_direction direction =
wp_audio_stream_get_direction ( WP_AUDIO_STREAM (self));
struct pw_node_proxy *pw_proxy = NULL;
uint8_t buf[1024];
struct spa_pod_builder pod_builder = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
struct spa_pod *param;
/* Get the adapter proxy */ /* Get the adapter proxy */
self->proxy = WP_PROXY_NODE (object_safe_new_finish (self, initable, self->proxy = WP_PROXY_NODE (object_safe_new_finish (self, initable,
...@@ -106,39 +137,10 @@ on_audio_adapter_proxy_created(GObject *initable, GAsyncResult *res, ...@@ -106,39 +137,10 @@ on_audio_adapter_proxy_created(GObject *initable, GAsyncResult *res,
if (!self->proxy) if (!self->proxy)
return; return;
/* Get the pipewire proxy */ /* Emit the EnumFormat param */
pw_proxy = wp_proxy_get_pw_proxy(WP_PROXY(self->proxy)); wp_proxy_node_enum_params (self->proxy, 0, SPA_PARAM_EnumFormat, 0, -1, NULL);
g_return_if_fail (pw_proxy);
/* Emit the props param */
pw_node_proxy_enum_params (pw_proxy, 0, SPA_PARAM_Props, 0, -1, NULL);
/* Emit the ports */
if (self->convert) {
param = spa_pod_builder_add_object(&pod_builder,
SPA_TYPE_OBJECT_ParamPortConfig, SPA_PARAM_PortConfig,
SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(direction),
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_convert));
pw_node_proxy_set_param(pw_proxy, SPA_PARAM_PortConfig, 0, param);
} else {
struct spa_audio_info_raw format;
spa_zero(format);
format.format = SPA_AUDIO_FORMAT_F32P;
format.flags = 1;
format.rate = 48000;
format.channels = 2;
format.position[0] = SPA_AUDIO_CHANNEL_FL;
format.position[1] = SPA_AUDIO_CHANNEL_FR;
param = spa_format_audio_raw_build(&pod_builder, SPA_PARAM_Format, &format);
param = spa_pod_builder_add_object(&pod_builder,
SPA_TYPE_OBJECT_ParamPortConfig, SPA_PARAM_PortConfig,
SPA_PARAM_PORT_CONFIG_direction, SPA_POD_Id(direction),
SPA_PARAM_PORT_CONFIG_mode, SPA_POD_Id(SPA_PARAM_PORT_CONFIG_MODE_dsp),
SPA_PARAM_PORT_CONFIG_format, SPA_POD_Pod(param));
pw_node_proxy_set_param(pw_proxy, SPA_PARAM_PortConfig, 0, param);
}
/* Register a callback to know when all the adapter ports have been emitted */ /* Register the done callback */
g_signal_connect_object(self->proxy, "done", (GCallback)on_audio_adapter_done, g_signal_connect_object(self->proxy, "done", (GCallback)on_audio_adapter_done,
self, 0); self, 0);
wp_proxy_sync (WP_PROXY(self->proxy)); wp_proxy_sync (WP_PROXY(self->proxy));
...@@ -248,6 +250,7 @@ static void ...@@ -248,6 +250,7 @@ static void
wp_audio_adapter_init (WpAudioAdapter * self) wp_audio_adapter_init (WpAudioAdapter * self)
{ {
self->init_abort = FALSE; self->init_abort = FALSE;
self->ports_done = FALSE;
} }
static void static void
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment