mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-19 08:57:14 -05:00
Rework how clients connect.
Add buffer flags. The idea is to make it possible to easily check when a buffer contains control information that we need to parse to update the port fields. Make the client create remote nodes and ports and set up proxies for them. Make a port base class implementing most of the logic to pass buffers locally and remotely. Remove most code from stream.c, it's now in the port. Make a portsink and portsrc that can write and read to/from any port. We use these in the server to send and receive data. Rework format negotiation. The final format is now sent in-line before the data. The server will select a format on output ports.
This commit is contained in:
parent
e85c3002f7
commit
4a5ed1e1f5
35 changed files with 3111 additions and 761 deletions
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
struct _PinosClientPortPrivate
|
||||
{
|
||||
gint foo;
|
||||
GDBusProxy *proxy;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (PinosClientPort, pinos_client_port, PINOS_TYPE_PORT);
|
||||
|
|
@ -40,6 +40,7 @@ G_DEFINE_TYPE (PinosClientPort, pinos_client_port, PINOS_TYPE_PORT);
|
|||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PROXY,
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -49,8 +50,13 @@ pinos_client_port_get_property (GObject *_object,
|
|||
GParamSpec *pspec)
|
||||
{
|
||||
PinosClientPort *port = PINOS_CLIENT_PORT (_object);
|
||||
PinosClientPortPrivate *priv = port->priv;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PROXY:
|
||||
g_value_set_object (value, priv->proxy);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (port, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -64,20 +70,126 @@ pinos_client_port_set_property (GObject *_object,
|
|||
GParamSpec *pspec)
|
||||
{
|
||||
PinosClientPort *port = PINOS_CLIENT_PORT (_object);
|
||||
PinosClientPortPrivate *priv = port->priv;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PROXY:
|
||||
priv->proxy = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (port, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_g_properties_changed (GDBusProxy *_proxy,
|
||||
GVariant *changed_properties,
|
||||
GStrv invalidated_properties,
|
||||
gpointer user_data)
|
||||
{
|
||||
PinosClientPort *port = user_data;
|
||||
GVariantIter *iter;
|
||||
gchar *key;
|
||||
|
||||
g_variant_get (changed_properties, "a{sv}", &iter);
|
||||
while (g_variant_iter_next (iter, "{&sv}", &key, NULL)) {
|
||||
GVariant *variant;
|
||||
gsize size;
|
||||
gpointer data;
|
||||
GBytes *bytes;
|
||||
|
||||
g_debug ("changed %s", key);
|
||||
|
||||
variant = g_dbus_proxy_get_cached_property (_proxy, key);
|
||||
if (variant == NULL)
|
||||
continue;
|
||||
|
||||
if (strcmp (key, "Format") == 0) {
|
||||
data = g_variant_dup_string (variant, &size);
|
||||
bytes = g_bytes_new_take (data, size);
|
||||
g_object_set (port, "format", bytes, NULL);
|
||||
}
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
g_variant_iter_free (iter);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
proxy_set_property_cb (GDBusProxy *proxy,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GVariant *ret;
|
||||
GError *error = NULL;
|
||||
|
||||
ret = g_dbus_proxy_call_finish (proxy, res, &error);
|
||||
if (ret == NULL) {
|
||||
g_warning ("Error setting property: %s", error->message);
|
||||
g_error_free (error);
|
||||
} else
|
||||
g_variant_unref (ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_property_notify (GObject *obj,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
PinosPort *port = PINOS_PORT (obj);
|
||||
PinosClientPortPrivate *priv = PINOS_CLIENT_PORT (port)->priv;
|
||||
const gchar *prop_name = NULL;
|
||||
GVariant *variant;
|
||||
|
||||
g_debug ("update %s", pspec ? g_param_spec_get_name (pspec) : "NULL");
|
||||
|
||||
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "properties") == 0) {
|
||||
PinosProperties *props = pinos_port_get_properties (port);
|
||||
prop_name = "Properties";
|
||||
variant = props ? pinos_properties_to_variant (props) : NULL;
|
||||
}
|
||||
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "possible-formats") == 0) {
|
||||
GBytes *bytes = pinos_port_get_possible_formats (port);
|
||||
prop_name = "PossibleFormats";
|
||||
variant = bytes ? g_variant_new_string (g_bytes_get_data (bytes, NULL)) : NULL;
|
||||
}
|
||||
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "format") == 0) {
|
||||
GBytes *bytes = pinos_port_get_format (port);
|
||||
prop_name = "Format";
|
||||
variant = bytes ? g_variant_new_string (g_bytes_get_data (bytes, NULL)) : NULL;
|
||||
}
|
||||
if (prop_name) {
|
||||
g_dbus_proxy_call (G_DBUS_PROXY (priv->proxy),
|
||||
"org.freedesktop.DBus.Properties.Set",
|
||||
g_variant_new ("(ssv)",
|
||||
"org.pinos.Port1",
|
||||
prop_name,
|
||||
variant),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) proxy_set_property_cb,
|
||||
port);
|
||||
if (variant)
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
pinos_client_port_constructed (GObject * object)
|
||||
{
|
||||
PinosClientPort *port = PINOS_CLIENT_PORT (object);
|
||||
PinosClientPortPrivate *priv = port->priv;
|
||||
|
||||
g_debug ("client-port %p: constructed", port);
|
||||
g_signal_connect (priv->proxy,
|
||||
"g-properties-changed",
|
||||
(GCallback) proxy_g_properties_changed,
|
||||
port);
|
||||
|
||||
G_OBJECT_CLASS (pinos_client_port_parent_class)->constructed (object);
|
||||
}
|
||||
|
|
@ -92,12 +204,15 @@ pinos_client_port_dispose (GObject * object)
|
|||
G_OBJECT_CLASS (pinos_client_port_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pinos_client_port_finalize (GObject * object)
|
||||
{
|
||||
PinosClientPort *port = PINOS_CLIENT_PORT (object);
|
||||
PinosClientPortPrivate *priv = port->priv;
|
||||
|
||||
g_debug ("client-port %p: finalize", port);
|
||||
g_clear_object (&priv->proxy);
|
||||
|
||||
G_OBJECT_CLASS (pinos_client_port_parent_class)->finalize (object);
|
||||
}
|
||||
|
|
@ -114,6 +229,16 @@ pinos_client_port_class_init (PinosClientPortClass * klass)
|
|||
gobject_class->finalize = pinos_client_port_finalize;
|
||||
gobject_class->set_property = pinos_client_port_set_property;
|
||||
gobject_class->get_property = pinos_client_port_get_property;
|
||||
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_PROXY,
|
||||
g_param_spec_object ("proxy",
|
||||
"Proxy",
|
||||
"The Proxy",
|
||||
G_TYPE_DBUS_PROXY,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -121,3 +246,72 @@ pinos_client_port_init (PinosClientPort * port)
|
|||
{
|
||||
port->priv = PINOS_CLIENT_PORT_GET_PRIVATE (port);
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_client_port_new:
|
||||
* @node: a #PinosClientNode
|
||||
* @id: an id
|
||||
* @socket: a socket with the server port
|
||||
*
|
||||
* Create a new client port.
|
||||
*
|
||||
* Returns: a new client port
|
||||
*/
|
||||
PinosClientPort *
|
||||
pinos_client_port_new (PinosClientNode *node,
|
||||
gpointer id,
|
||||
GSocket *socket)
|
||||
{
|
||||
PinosClientPort *port;
|
||||
GDBusProxy *proxy = id;
|
||||
GVariant *variant;
|
||||
PinosDirection direction = PINOS_DIRECTION_INVALID;
|
||||
const gchar *name = "unknown";
|
||||
GBytes *possible_formats = NULL;
|
||||
GBytes *format = NULL;
|
||||
PinosProperties *properties = NULL;
|
||||
|
||||
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Direction");
|
||||
if (variant != NULL) {
|
||||
direction = g_variant_get_uint32 (variant);
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Name");
|
||||
if (variant != NULL) {
|
||||
name = g_variant_get_string (variant, NULL);
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "PossibleFormats");
|
||||
if (variant != NULL) {
|
||||
gsize size;
|
||||
gpointer data;
|
||||
data = g_variant_dup_string (variant, &size);
|
||||
possible_formats = g_bytes_new_take (data, size);
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Format");
|
||||
if (variant != NULL) {
|
||||
gsize size;
|
||||
gpointer data;
|
||||
data = g_variant_dup_string (variant, &size);
|
||||
format = g_bytes_new_take (data, size);
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
variant = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), "Properties");
|
||||
if (variant != NULL) {
|
||||
properties = pinos_properties_from_variant (variant);
|
||||
g_variant_unref (variant);
|
||||
}
|
||||
|
||||
port = g_object_new (PINOS_TYPE_CLIENT_PORT,
|
||||
"node", node,
|
||||
"direction", direction,
|
||||
"name", name,
|
||||
"possible-formats", possible_formats,
|
||||
"format", format,
|
||||
"properties", properties,
|
||||
"proxy", proxy,
|
||||
"socket", socket,
|
||||
NULL);
|
||||
return port;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue