gst: add client-properties

To update the client properties of the connection.

Fixes #1573
This commit is contained in:
Wim Taymans 2022-06-03 13:00:52 +02:00
parent 6276253c30
commit 6c310cf5e2
4 changed files with 87 additions and 19 deletions

View file

@ -62,6 +62,7 @@ enum
PROP_PATH, PROP_PATH,
PROP_TARGET_OBJECT, PROP_TARGET_OBJECT,
PROP_CLIENT_NAME, PROP_CLIENT_NAME,
PROP_CLIENT_PROPERTIES,
PROP_STREAM_PROPERTIES, PROP_STREAM_PROPERTIES,
PROP_MODE, PROP_MODE,
PROP_FD PROP_FD
@ -122,8 +123,10 @@ gst_pipewire_sink_finalize (GObject * object)
g_object_unref (pwsink->pool); g_object_unref (pwsink->pool);
if (pwsink->properties) if (pwsink->stream_properties)
gst_structure_free (pwsink->properties); gst_structure_free (pwsink->stream_properties);
if (pwsink->client_properties)
gst_structure_free (pwsink->client_properties);
g_free (pwsink->path); g_free (pwsink->path);
g_free (pwsink->target_object); g_free (pwsink->target_object);
g_free (pwsink->client_name); g_free (pwsink->client_name);
@ -183,6 +186,15 @@ gst_pipewire_sink_class_init (GstPipeWireSinkClass * klass)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_CLIENT_PROPERTIES,
g_param_spec_boxed ("client-properties",
"Client properties",
"List of PipeWire client properties",
GST_TYPE_STRUCTURE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_STREAM_PROPERTIES, PROP_STREAM_PROPERTIES,
g_param_spec_boxed ("stream-properties", g_param_spec_boxed ("stream-properties",
@ -361,10 +373,17 @@ gst_pipewire_sink_set_property (GObject * object, guint prop_id,
pwsink->client_name = g_value_dup_string (value); pwsink->client_name = g_value_dup_string (value);
break; break;
case PROP_CLIENT_PROPERTIES:
if (pwsink->client_properties)
gst_structure_free (pwsink->client_properties);
pwsink->client_properties =
gst_structure_copy (gst_value_get_structure (value));
break;
case PROP_STREAM_PROPERTIES: case PROP_STREAM_PROPERTIES:
if (pwsink->properties) if (pwsink->stream_properties)
gst_structure_free (pwsink->properties); gst_structure_free (pwsink->stream_properties);
pwsink->properties = pwsink->stream_properties =
gst_structure_copy (gst_value_get_structure (value)); gst_structure_copy (gst_value_get_structure (value));
break; break;
@ -401,8 +420,12 @@ gst_pipewire_sink_get_property (GObject * object, guint prop_id,
g_value_set_string (value, pwsink->client_name); g_value_set_string (value, pwsink->client_name);
break; break;
case PROP_CLIENT_PROPERTIES:
gst_value_set_structure (value, pwsink->client_properties);
break;
case PROP_STREAM_PROPERTIES: case PROP_STREAM_PROPERTIES:
gst_value_set_structure (value, pwsink->properties); gst_value_set_structure (value, pwsink->stream_properties);
break; break;
case PROP_MODE: case PROP_MODE:
@ -733,16 +756,17 @@ gst_pipewire_sink_start (GstBaseSink * basesink)
pwsink->negotiated = FALSE; pwsink->negotiated = FALSE;
pw_thread_loop_lock (pwsink->core->loop);
props = pw_properties_new (NULL, NULL); props = pw_properties_new (NULL, NULL);
if (pwsink->client_name) { if (pwsink->client_name) {
pw_properties_set (props, PW_KEY_NODE_NAME, pwsink->client_name); pw_properties_set (props, PW_KEY_NODE_NAME, pwsink->client_name);
pw_properties_set (props, PW_KEY_NODE_DESCRIPTION, pwsink->client_name); pw_properties_set (props, PW_KEY_NODE_DESCRIPTION, pwsink->client_name);
} }
if (pwsink->properties) { if (pwsink->stream_properties) {
gst_structure_foreach (pwsink->properties, copy_properties, props); gst_structure_foreach (pwsink->stream_properties, copy_properties, props);
} }
pw_thread_loop_lock (pwsink->core->loop);
if ((pwsink->stream = pw_stream_new (pwsink->core->core, pwsink->client_name, props)) == NULL) if ((pwsink->stream = pw_stream_new (pwsink->core->core, pwsink->client_name, props)) == NULL)
goto no_stream; goto no_stream;
@ -786,10 +810,24 @@ gst_pipewire_sink_stop (GstBaseSink * basesink)
static gboolean static gboolean
gst_pipewire_sink_open (GstPipeWireSink * pwsink) gst_pipewire_sink_open (GstPipeWireSink * pwsink)
{ {
struct pw_properties *props;
GST_DEBUG_OBJECT (pwsink, "open");
pwsink->core = gst_pipewire_core_get(pwsink->fd); pwsink->core = gst_pipewire_core_get(pwsink->fd);
if (pwsink->core == NULL) if (pwsink->core == NULL)
goto connect_error; goto connect_error;
pw_thread_loop_lock (pwsink->core->loop);
props = pw_properties_new (NULL, NULL);
if (pwsink->client_properties) {
gst_structure_foreach (pwsink->client_properties, copy_properties, props);
pw_core_update_properties (pwsink->core->core, &props->dict);
}
pw_properties_free(props);
pw_thread_loop_unlock (pwsink->core->loop);
return TRUE; return TRUE;
/* ERRORS */ /* ERRORS */

View file

@ -87,11 +87,12 @@ struct _GstPipeWireSink {
GstPipeWireCore *core; GstPipeWireCore *core;
struct spa_hook core_listener; struct spa_hook core_listener;
GstStructure *client_properties;
struct pw_stream *stream; struct pw_stream *stream;
struct spa_hook stream_listener; struct spa_hook stream_listener;
GstStructure *properties; GstStructure *stream_properties;
GstPipeWireSinkMode mode; GstPipeWireSinkMode mode;
GstPipeWirePool *pool; GstPipeWirePool *pool;

View file

@ -69,6 +69,7 @@ enum
PROP_PATH, PROP_PATH,
PROP_TARGET_OBJECT, PROP_TARGET_OBJECT,
PROP_CLIENT_NAME, PROP_CLIENT_NAME,
PROP_CLIENT_PROPERTIES,
PROP_STREAM_PROPERTIES, PROP_STREAM_PROPERTIES,
PROP_ALWAYS_COPY, PROP_ALWAYS_COPY,
PROP_MIN_BUFFERS, PROP_MIN_BUFFERS,
@ -127,10 +128,17 @@ gst_pipewire_src_set_property (GObject * object, guint prop_id,
pwsrc->client_name = g_value_dup_string (value); pwsrc->client_name = g_value_dup_string (value);
break; break;
case PROP_CLIENT_PROPERTIES:
if (pwsrc->client_properties)
gst_structure_free (pwsrc->client_properties);
pwsrc->client_properties =
gst_structure_copy (gst_value_get_structure (value));
break;
case PROP_STREAM_PROPERTIES: case PROP_STREAM_PROPERTIES:
if (pwsrc->properties) if (pwsrc->stream_properties)
gst_structure_free (pwsrc->properties); gst_structure_free (pwsrc->stream_properties);
pwsrc->properties = pwsrc->stream_properties =
gst_structure_copy (gst_value_get_structure (value)); gst_structure_copy (gst_value_get_structure (value));
break; break;
@ -183,8 +191,12 @@ gst_pipewire_src_get_property (GObject * object, guint prop_id,
g_value_set_string (value, pwsrc->client_name); g_value_set_string (value, pwsrc->client_name);
break; break;
case PROP_CLIENT_PROPERTIES:
gst_value_set_structure (value, pwsrc->client_properties);
break;
case PROP_STREAM_PROPERTIES: case PROP_STREAM_PROPERTIES:
gst_value_set_structure (value, pwsrc->properties); gst_value_set_structure (value, pwsrc->stream_properties);
break; break;
case PROP_ALWAYS_COPY: case PROP_ALWAYS_COPY:
@ -249,8 +261,10 @@ gst_pipewire_src_finalize (GObject * object)
{ {
GstPipeWireSrc *pwsrc = GST_PIPEWIRE_SRC (object); GstPipeWireSrc *pwsrc = GST_PIPEWIRE_SRC (object);
if (pwsrc->properties) if (pwsrc->stream_properties)
gst_structure_free (pwsrc->properties); gst_structure_free (pwsrc->stream_properties);
if (pwsrc->client_properties)
gst_structure_free (pwsrc->client_properties);
if (pwsrc->clock) if (pwsrc->clock)
gst_object_unref (pwsrc->clock); gst_object_unref (pwsrc->clock);
g_free (pwsrc->path); g_free (pwsrc->path);
@ -306,6 +320,15 @@ gst_pipewire_src_class_init (GstPipeWireSrcClass * klass)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class,
PROP_CLIENT_PROPERTIES,
g_param_spec_boxed ("client-properties",
"client properties",
"list of PipeWire client properties",
GST_TYPE_STRUCTURE,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_STREAM_PROPERTIES, PROP_STREAM_PROPERTIES,
g_param_spec_boxed ("stream-properties", g_param_spec_boxed ("stream-properties",
@ -1187,12 +1210,17 @@ gst_pipewire_src_open (GstPipeWireSrc * pwsrc)
pw_thread_loop_lock (pwsrc->core->loop); pw_thread_loop_lock (pwsrc->core->loop);
props = pw_properties_new (NULL, NULL); props = pw_properties_new (NULL, NULL);
if (pwsrc->client_properties) {
gst_structure_foreach (pwsrc->client_properties, copy_properties, props);
pw_core_update_properties (pwsrc->core->core, &props->dict);
pw_properties_clear(props);
}
if (pwsrc->client_name) { if (pwsrc->client_name) {
pw_properties_set (props, PW_KEY_NODE_NAME, pwsrc->client_name); pw_properties_set (props, PW_KEY_NODE_NAME, pwsrc->client_name);
pw_properties_set (props, PW_KEY_NODE_DESCRIPTION, pwsrc->client_name); pw_properties_set (props, PW_KEY_NODE_DESCRIPTION, pwsrc->client_name);
} }
if (pwsrc->properties) { if (pwsrc->stream_properties) {
gst_structure_foreach (pwsrc->properties, copy_properties, props); gst_structure_foreach (pwsrc->stream_properties, copy_properties, props);
} }
if ((pwsrc->stream = pw_stream_new (pwsrc->core->core, if ((pwsrc->stream = pw_stream_new (pwsrc->core->core,

View file

@ -80,6 +80,7 @@ struct _GstPipeWireSrc {
GstClockTime min_latency; GstClockTime min_latency;
GstClockTime max_latency; GstClockTime max_latency;
GstStructure *client_properties;
GstPipeWireCore *core; GstPipeWireCore *core;
struct spa_hook core_listener; struct spa_hook core_listener;
int last_seq; int last_seq;
@ -89,7 +90,7 @@ struct _GstPipeWireSrc {
struct spa_hook stream_listener; struct spa_hook stream_listener;
GstBuffer *last_buffer; GstBuffer *last_buffer;
GstStructure *properties; GstStructure *stream_properties;
GstPipeWirePool *pool; GstPipeWirePool *pool;
GstClock *clock; GstClock *clock;