mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
gst: use target.object instead of node.target, soft-deprecate ids
Use target-object=<serial/name> instead of path=<id> for specifying sink/src targets. Deprecate path= argument. Change device provider to preferably expose serials instead of ids.
This commit is contained in:
parent
d66e9f1ae1
commit
67a27d80c6
6 changed files with 128 additions and 12 deletions
|
|
@ -44,6 +44,7 @@ G_DEFINE_TYPE (GstPipeWireDevice, gst_pipewire_device, GST_TYPE_DEVICE);
|
|||
enum
|
||||
{
|
||||
PROP_ID = 1,
|
||||
PROP_SERIAL,
|
||||
};
|
||||
|
||||
static GstElement *
|
||||
|
|
@ -51,12 +52,16 @@ gst_pipewire_device_create_element (GstDevice * device, const gchar * name)
|
|||
{
|
||||
GstPipeWireDevice *pipewire_dev = GST_PIPEWIRE_DEVICE (device);
|
||||
GstElement *elem;
|
||||
gchar *str;
|
||||
gchar *id_str, *serial_str;
|
||||
|
||||
elem = gst_element_factory_make (pipewire_dev->element, name);
|
||||
str = g_strdup_printf ("%u", pipewire_dev->id);
|
||||
g_object_set (elem, "path", str, NULL);
|
||||
g_free (str);
|
||||
|
||||
/* XXX: eventually only add target-object here */
|
||||
id_str = g_strdup_printf ("%u", pipewire_dev->id);
|
||||
serial_str = g_strdup_printf ("%"PRIu64, pipewire_dev->serial);
|
||||
g_object_set (elem, "path", id_str, "target-object", serial_str, NULL);
|
||||
g_free (id_str);
|
||||
g_free (serial_str);
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
|
@ -65,7 +70,7 @@ static gboolean
|
|||
gst_pipewire_device_reconfigure_element (GstDevice * device, GstElement * element)
|
||||
{
|
||||
GstPipeWireDevice *pipewire_dev = GST_PIPEWIRE_DEVICE (device);
|
||||
gchar *str;
|
||||
gchar *id_str, *serial_str;
|
||||
|
||||
if (spa_streq(pipewire_dev->element, "pipewiresrc")) {
|
||||
if (!GST_IS_PIPEWIRE_SRC (element))
|
||||
|
|
@ -77,9 +82,12 @@ gst_pipewire_device_reconfigure_element (GstDevice * device, GstElement * elemen
|
|||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
str = g_strdup_printf ("%u", pipewire_dev->id);
|
||||
g_object_set (element, "path", str, NULL);
|
||||
g_free (str);
|
||||
/* XXX: eventually only add target-object here */
|
||||
id_str = g_strdup_printf ("%u", pipewire_dev->id);
|
||||
serial_str = g_strdup_printf ("%"PRIu64, pipewire_dev->serial);
|
||||
g_object_set (element, "path", id_str, "target-object", serial_str, NULL);
|
||||
g_free (id_str);
|
||||
g_free (serial_str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -97,6 +105,9 @@ gst_pipewire_device_get_property (GObject * object, guint prop_id,
|
|||
case PROP_ID:
|
||||
g_value_set_uint (value, device->id);
|
||||
break;
|
||||
case PROP_SERIAL:
|
||||
g_value_set_uint64 (value, device->serial);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -115,6 +126,9 @@ gst_pipewire_device_set_property (GObject * object, guint prop_id,
|
|||
case PROP_ID:
|
||||
device->id = g_value_get_uint (value);
|
||||
break;
|
||||
case PROP_SERIAL:
|
||||
device->serial = g_value_get_uint64 (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -144,6 +158,11 @@ gst_pipewire_device_class_init (GstPipeWireDeviceClass * klass)
|
|||
g_param_spec_uint ("id", "Id",
|
||||
"The internal id of the PipeWire device", 0, G_MAXUINT32, SPA_ID_INVALID,
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SERIAL,
|
||||
g_param_spec_uint64 ("serial", "Serial",
|
||||
"The internal serial of the PipeWire device", 0, G_MAXUINT64, SPA_ID_INVALID,
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -176,6 +195,7 @@ struct node_data {
|
|||
struct pw_node *proxy;
|
||||
struct spa_hook proxy_listener;
|
||||
uint32_t id;
|
||||
uint64_t serial;
|
||||
struct spa_hook node_listener;
|
||||
struct pw_node_info *info;
|
||||
GstCaps *caps;
|
||||
|
|
@ -187,6 +207,7 @@ struct port_data {
|
|||
struct pw_port *proxy;
|
||||
struct spa_hook proxy_listener;
|
||||
uint32_t id;
|
||||
uint64_t serial;
|
||||
struct spa_hook port_listener;
|
||||
};
|
||||
|
||||
|
|
@ -236,9 +257,10 @@ new_node (GstPipeWireDeviceProvider *self, struct node_data *data)
|
|||
|
||||
gstdev = g_object_new (GST_TYPE_PIPEWIRE_DEVICE,
|
||||
"display-name", name, "caps", data->caps, "device-class", klass,
|
||||
"id", data->id, "properties", props, NULL);
|
||||
"id", data->id, "serial", data->serial, "properties", props, NULL);
|
||||
|
||||
gstdev->id = data->id;
|
||||
gstdev->serial = data->serial;
|
||||
gstdev->type = type;
|
||||
gstdev->element = element;
|
||||
if (props)
|
||||
|
|
@ -476,6 +498,8 @@ static void registry_event_global(void *data, uint32_t id, uint32_t permissions,
|
|||
nd->self = self;
|
||||
nd->proxy = node;
|
||||
nd->id = id;
|
||||
if (!props || !spa_atou64(spa_dict_lookup(props, PW_KEY_OBJECT_SERIAL), &nd->serial, 0))
|
||||
nd->serial = SPA_ID_INVALID;
|
||||
spa_list_append(&rd->nodes, &nd->link);
|
||||
pw_node_add_listener(node, &nd->node_listener, &node_events, nd);
|
||||
pw_proxy_add_listener((struct pw_proxy*)node, &nd->proxy_listener, &proxy_node_events, nd);
|
||||
|
|
@ -500,6 +524,8 @@ static void registry_event_global(void *data, uint32_t id, uint32_t permissions,
|
|||
pd->node_data = nd;
|
||||
pd->proxy = port;
|
||||
pd->id = id;
|
||||
if (!props || !spa_atou64(spa_dict_lookup(props, PW_KEY_OBJECT_SERIAL), &pd->serial, 0))
|
||||
pd->serial = SPA_ID_INVALID;
|
||||
pw_port_add_listener(port, &pd->port_listener, &port_events, pd);
|
||||
pw_proxy_add_listener((struct pw_proxy*)port, &pd->proxy_listener, &proxy_port_events, pd);
|
||||
resync(self);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ struct _GstPipeWireDevice {
|
|||
|
||||
GstPipeWireDeviceType type;
|
||||
uint32_t id;
|
||||
uint64_t serial;
|
||||
const gchar *element;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ enum
|
|||
{
|
||||
PROP_0,
|
||||
PROP_PATH,
|
||||
PROP_TARGET_OBJECT,
|
||||
PROP_CLIENT_NAME,
|
||||
PROP_STREAM_PROPERTIES,
|
||||
PROP_MODE,
|
||||
|
|
@ -124,6 +125,7 @@ gst_pipewire_sink_finalize (GObject * object)
|
|||
if (pwsink->properties)
|
||||
gst_structure_free (pwsink->properties);
|
||||
g_free (pwsink->path);
|
||||
g_free (pwsink->target_object);
|
||||
g_free (pwsink->client_name);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
|
|
@ -160,6 +162,16 @@ gst_pipewire_sink_class_init (GstPipeWireSinkClass * klass)
|
|||
"The sink path to connect to (NULL = default)",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_DEPRECATED));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_TARGET_OBJECT,
|
||||
g_param_spec_string ("target-object",
|
||||
"Target object",
|
||||
"The sink name/serial to connect to (NULL = default)",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
|
|
@ -339,6 +351,11 @@ gst_pipewire_sink_set_property (GObject * object, guint prop_id,
|
|||
pwsink->path = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_TARGET_OBJECT:
|
||||
g_free (pwsink->target_object);
|
||||
pwsink->target_object = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_CLIENT_NAME:
|
||||
g_free (pwsink->client_name);
|
||||
pwsink->client_name = g_value_dup_string (value);
|
||||
|
|
@ -376,6 +393,10 @@ gst_pipewire_sink_get_property (GObject * object, guint prop_id,
|
|||
g_value_set_string (value, pwsink->path);
|
||||
break;
|
||||
|
||||
case PROP_TARGET_OBJECT:
|
||||
g_value_set_string (value, pwsink->target_object);
|
||||
break;
|
||||
|
||||
case PROP_CLIENT_NAME:
|
||||
g_value_set_string (value, pwsink->client_name);
|
||||
break;
|
||||
|
|
@ -522,15 +543,37 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
|||
|
||||
if (state == PW_STREAM_STATE_UNCONNECTED) {
|
||||
enum pw_stream_flags flags = 0;
|
||||
uint32_t target_id;
|
||||
|
||||
if (pwsink->mode != GST_PIPEWIRE_SINK_MODE_PROVIDE)
|
||||
flags |= PW_STREAM_FLAG_AUTOCONNECT;
|
||||
else
|
||||
flags |= PW_STREAM_FLAG_DRIVER;
|
||||
|
||||
target_id = pwsink->path ? (uint32_t)atoi(pwsink->path) : PW_ID_ANY;
|
||||
|
||||
if (pwsink->target_object) {
|
||||
struct spa_dict_item items[2] = {
|
||||
SPA_DICT_ITEM_INIT(PW_KEY_TARGET_OBJECT, pwsink->target_object),
|
||||
SPA_DICT_ITEM_INIT(PW_KEY_NODE_TARGET, NULL),
|
||||
};
|
||||
struct spa_dict dict = SPA_DICT_INIT_ARRAY(items);
|
||||
uint64_t serial;
|
||||
|
||||
/* If target.object is a name, set it also to node.target */
|
||||
if (spa_atou64(pwsink->target_object, &serial, 0)) {
|
||||
dict.n_items = 1;
|
||||
} else {
|
||||
target_id = PW_ID_ANY;
|
||||
items[1].value = pwsink->target_object;
|
||||
}
|
||||
|
||||
pw_stream_update_properties (pwsink->stream, &dict);
|
||||
}
|
||||
|
||||
pw_stream_connect (pwsink->stream,
|
||||
PW_DIRECTION_OUTPUT,
|
||||
pwsink->path ? (uint32_t)atoi(pwsink->path) : PW_ID_ANY,
|
||||
target_id,
|
||||
flags,
|
||||
(const struct spa_pod **) possible->pdata,
|
||||
possible->len);
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ struct _GstPipeWireSink {
|
|||
|
||||
/*< private >*/
|
||||
gchar *path;
|
||||
gchar *target_object;
|
||||
gchar *client_name;
|
||||
int fd;
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ enum
|
|||
{
|
||||
PROP_0,
|
||||
PROP_PATH,
|
||||
PROP_TARGET_OBJECT,
|
||||
PROP_CLIENT_NAME,
|
||||
PROP_STREAM_PROPERTIES,
|
||||
PROP_ALWAYS_COPY,
|
||||
|
|
@ -116,6 +117,11 @@ gst_pipewire_src_set_property (GObject * object, guint prop_id,
|
|||
pwsrc->path = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_TARGET_OBJECT:
|
||||
g_free (pwsrc->target_object);
|
||||
pwsrc->target_object = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_CLIENT_NAME:
|
||||
g_free (pwsrc->client_name);
|
||||
pwsrc->client_name = g_value_dup_string (value);
|
||||
|
|
@ -169,6 +175,10 @@ gst_pipewire_src_get_property (GObject * object, guint prop_id,
|
|||
g_value_set_string (value, pwsrc->path);
|
||||
break;
|
||||
|
||||
case PROP_TARGET_OBJECT:
|
||||
g_value_set_string (value, pwsrc->target_object);
|
||||
break;
|
||||
|
||||
case PROP_CLIENT_NAME:
|
||||
g_value_set_string (value, pwsrc->client_name);
|
||||
break;
|
||||
|
|
@ -244,6 +254,7 @@ gst_pipewire_src_finalize (GObject * object)
|
|||
if (pwsrc->clock)
|
||||
gst_object_unref (pwsrc->clock);
|
||||
g_free (pwsrc->path);
|
||||
g_free (pwsrc->target_object);
|
||||
g_free (pwsrc->client_name);
|
||||
g_object_unref(pwsrc->pool);
|
||||
|
||||
|
|
@ -274,6 +285,16 @@ gst_pipewire_src_class_init (GstPipeWireSrcClass * klass)
|
|||
"The source path to connect to (NULL = default)",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_DEPRECATED));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_TARGET_OBJECT,
|
||||
g_param_spec_string ("target-object",
|
||||
"Target object",
|
||||
"The source name/serial to connect to (NULL = default)",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
|
|
@ -675,6 +696,7 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
|
|||
GPtrArray *possible;
|
||||
const char *error = NULL;
|
||||
struct timespec abstime;
|
||||
uint32_t target_id;
|
||||
|
||||
/* first see what is possible on our source pad */
|
||||
thiscaps = gst_pad_query_caps (GST_BASE_SRC_PAD (basesrc), NULL);
|
||||
|
|
@ -727,11 +749,33 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
|
|||
}
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pwsrc->path);
|
||||
target_id = pwsrc->path ? (uint32_t)atoi(pwsrc->path) : PW_ID_ANY;
|
||||
|
||||
if (pwsrc->target_object) {
|
||||
struct spa_dict_item items[2] = {
|
||||
SPA_DICT_ITEM_INIT(PW_KEY_TARGET_OBJECT, pwsrc->target_object),
|
||||
SPA_DICT_ITEM_INIT(PW_KEY_NODE_TARGET, NULL),
|
||||
};
|
||||
struct spa_dict dict = SPA_DICT_INIT_ARRAY(items);
|
||||
uint64_t serial;
|
||||
|
||||
/* If target.object is a name, set it also to node.target */
|
||||
if (spa_atou64(pwsrc->target_object, &serial, 0)) {
|
||||
dict.n_items = 1;
|
||||
} else {
|
||||
target_id = PW_ID_ANY;
|
||||
items[1].value = pwsrc->target_object;
|
||||
}
|
||||
|
||||
pw_stream_update_properties (pwsrc->stream, &dict);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s, target-object %s",
|
||||
pwsrc->path, pwsrc->target_object);
|
||||
pwsrc->negotiated = FALSE;
|
||||
pw_stream_connect (pwsrc->stream,
|
||||
PW_DIRECTION_INPUT,
|
||||
pwsrc->path ? (uint32_t)atoi(pwsrc->path) : PW_ID_ANY,
|
||||
target_id,
|
||||
PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_DONT_RECONNECT,
|
||||
(const struct spa_pod **)possible->pdata,
|
||||
possible->len);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ struct _GstPipeWireSrc {
|
|||
|
||||
/*< private >*/
|
||||
gchar *path;
|
||||
gchar *target_object;
|
||||
gchar *client_name;
|
||||
gboolean always_copy;
|
||||
gint min_buffers;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue