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:
Wim Taymans 2016-05-17 09:38:30 +02:00
parent e85c3002f7
commit 4a5ed1e1f5
35 changed files with 3111 additions and 761 deletions

View file

@ -174,7 +174,7 @@ handle_create_node (PinosClient1 *interface,
client);
object_path = pinos_server_node_get_object_path (PINOS_SERVER_NODE (node));
g_debug ("client %p: add node %p, %s", client, node, object_path);
g_debug ("client %p: add node %p %d, %s", client, node, G_OBJECT (node)->ref_count, object_path);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(o)", object_path));

View file

@ -439,7 +439,11 @@ pinos_daemon_find_port (PinosDaemon *daemon,
break;
}
format = pinos_port_get_formats (PINOS_PORT (p), format_filter, NULL);
g_debug ("port %s with filter %s",
pinos_server_port_get_object_path (p),
format_filter ? (gchar*)g_bytes_get_data (format_filter, NULL) : "ANY");
format = pinos_port_filter_formats (PINOS_PORT (p), format_filter, NULL);
if (format != NULL) {
g_debug ("port %s with format %s matches filter %s",
pinos_server_port_get_object_path (p),

View file

@ -20,6 +20,7 @@
#include <string.h>
#include <gio/gio.h>
#include <gio/gunixfdlist.h>
#include "pinos/client/pinos.h"
#include "pinos/client/enumtypes.h"
@ -80,6 +81,7 @@ server_node_create_port (PinosNode *node,
NULL);
g_task_return_pointer (task, port, (GDestroyNotify) g_object_unref);
g_object_unref (task);
}
static void
@ -94,19 +96,55 @@ on_port_created (GObject *source_object,
gpointer user_data)
{
PinosNode *node = PINOS_NODE (source_object);
PinosServerNodePrivate *priv = PINOS_SERVER_NODE (node)->priv;
GDBusMethodInvocation *invocation = user_data;
PinosPort *port;
PinosPort *port, *peer;
const gchar *object_path;
GError *error = NULL;
GUnixFDList *fdlist;
GSocket *socket;
int fd, fdidx;
PinosDirection direction;
port = pinos_node_create_port_finish (node, res, &error);
if (port == NULL)
goto no_port;
g_debug ("server-node %p %d: port %p created", node, G_OBJECT (node)->ref_count, port);
socket = pinos_port_get_socket_pair (port, &error);
if (socket == NULL)
goto no_sockets;
fd = g_socket_get_fd (socket);
fdlist = g_unix_fd_list_new ();
fdidx = g_unix_fd_list_append (fdlist, fd, &error);
g_object_unref (socket);
if (fdidx == -1)
goto no_fdlist;
direction = pinos_port_get_direction (port);
direction = pinos_direction_reverse (direction);
peer = pinos_daemon_find_port (priv->daemon,
direction,
NULL,
pinos_port_get_properties (port),
pinos_port_get_possible_formats (port),
&error);
if (peer == NULL)
goto no_port_found;
pinos_port_link (port, peer);
object_path = pinos_server_port_get_object_path (PINOS_SERVER_PORT (port));
g_debug ("node %p: add port %p, %s", node, port, object_path);
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(o)", object_path));
g_debug ("server-node %p: add port %p, remote fd %d, %s", node, port, fd, object_path);
g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,
g_variant_new ("(oh)",
object_path,
fdidx),
fdlist);
return;
@ -117,6 +155,31 @@ no_port:
"org.pinos.Error", "can't create port");
return;
}
no_sockets:
{
g_debug ("server-node %p: could create socketpair %s", node, error->message);
g_dbus_method_invocation_return_gerror (invocation, error);
g_clear_error (&error);
g_object_unref (port);
return;
}
no_fdlist:
{
g_debug ("server-node %p: could add to fdlist", node);
g_dbus_method_invocation_return_gerror (invocation, error);
g_clear_error (&error);
g_object_unref (fdlist);
g_object_unref (port);
return;
}
no_port_found:
{
g_debug ("server-node %p: could not find matching port", node);
g_dbus_method_invocation_return_gerror (invocation, error);
g_clear_error (&error);
g_object_unref (fdlist);
return;
}
}
@ -142,6 +205,7 @@ handle_create_port (PinosNode1 *interface,
formats = g_bytes_new (arg_possible_formats, strlen (arg_possible_formats) + 1);
props = pinos_properties_from_variant (arg_properties);
g_debug ("server-node %p %d: create port", node, G_OBJECT (node)->ref_count);
pinos_node_create_port (node,
arg_direction,
arg_name,
@ -173,7 +237,7 @@ handle_remove (PinosNode1 *interface,
{
PinosNode *node = user_data;
g_debug ("server-node %p: remove", node);
g_debug ("server-node %p %d: remove", node, G_OBJECT (node)->ref_count);
pinos_node_remove (node);
g_dbus_method_invocation_return_value (invocation,
@ -264,15 +328,34 @@ node_unregister_object (PinosServerNode *node)
pinos_daemon_remove_node (priv->daemon, node);
}
static void
on_property_notify (GObject *obj,
GParamSpec *pspec,
gpointer user_data)
{
PinosNode *node = user_data;
PinosServerNodePrivate *priv = PINOS_SERVER_NODE (node)->priv;
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "name")) {
pinos_node1_set_name (priv->iface, pinos_node_get_name (node));
}
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "properties")) {
PinosProperties *props = pinos_node_get_properties (node);
pinos_node1_set_properties (priv->iface, props ? pinos_properties_to_variant (props) : NULL);
}
}
static void
pinos_server_node_constructed (GObject * obj)
{
PinosServerNode *node = PINOS_SERVER_NODE (obj);
g_debug ("server-node %p: constructed", node);
node_register_object (node);
g_signal_connect (node, "notify", (GCallback) on_property_notify, node);
G_OBJECT_CLASS (pinos_server_node_parent_class)->constructed (obj);
node_register_object (node);
}
static void

View file

@ -18,6 +18,8 @@
*/
#include <string.h>
#include <sys/socket.h>
#include <gst/gst.h>
#include <gio/gio.h>
@ -38,6 +40,7 @@ struct _PinosServerPortPrivate
PinosDaemon *daemon;
PinosPort1 *iface;
gchar *object_path;
gboolean have_sockets;
};
G_DEFINE_TYPE (PinosServerPort, pinos_server_port, PINOS_TYPE_PORT);
@ -49,6 +52,17 @@ enum
PROP_OBJECT_PATH,
};
const gchar *
pinos_server_port_get_object_path (PinosServerPort *port)
{
PinosServerPortPrivate *priv;
g_return_val_if_fail (PINOS_IS_SERVER_PORT (port), NULL);
priv = port->priv;
return priv->object_path;
}
static gboolean
handle_remove (PinosPort1 *interface,
GDBusMethodInvocation *invocation,
@ -142,15 +156,51 @@ port_unregister_object (PinosServerPort *port)
pinos_daemon_unexport (priv->daemon, priv->object_path);
}
static void
on_property_notify (GObject *obj,
GParamSpec *pspec,
gpointer user_data)
{
PinosPort *port = PINOS_PORT (obj);
PinosServerPortPrivate *priv = PINOS_SERVER_PORT (port)->priv;
g_debug ("update %s", pspec ? g_param_spec_get_name (pspec) : "NULL");
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "node") == 0) {
PinosServerNode *node = PINOS_SERVER_NODE (pinos_port_get_node (port));
pinos_port1_set_node (priv->iface, pinos_server_node_get_object_path (node));
}
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "direction") == 0) {
pinos_port1_set_direction (priv->iface, pinos_port_get_direction (port));
}
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "name") == 0) {
pinos_port1_set_name (priv->iface, pinos_port_get_name (port));
}
if (pspec == NULL || strcmp (g_param_spec_get_name (pspec), "properties") == 0) {
PinosProperties *props = pinos_port_get_properties (port);
pinos_port1_set_properties (priv->iface, 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);
pinos_port1_set_possible_formats (priv->iface, bytes ? 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);
pinos_port1_set_format (priv->iface, bytes ? g_bytes_get_data (bytes, NULL) : NULL);
}
}
static void
pinos_server_port_constructed (GObject * object)
{
PinosServerPort *port = PINOS_SERVER_PORT (object);
g_debug ("server-port %p: constructed", port);
port_register_object (port);
g_signal_connect (port, "notify", (GCallback) on_property_notify, port);
G_OBJECT_CLASS (pinos_server_port_parent_class)->constructed (object);
port_register_object (port);
}
static void
@ -182,6 +232,7 @@ static void
pinos_server_port_class_init (PinosServerPortClass * klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
//PinosPortClass *port_class = PINOS_PORT_CLASS (klass);
g_type_class_add_private (klass, sizeof (PinosServerPortPrivate));
@ -222,14 +273,3 @@ pinos_server_port_init (PinosServerPort * port)
port);
}
const gchar *
pinos_server_port_get_object_path (PinosServerPort *port)
{
PinosServerPortPrivate *priv;
g_return_val_if_fail (PINOS_IS_SERVER_PORT (port), NULL);
priv = port->priv;
return priv->object_path;
}