node: add support for multiple input and output ports

Make it possible to have a mixer/spliter and converter for the gstreamer
sources and sinks.
Add logic to make a new input/output port when the existing ports are
not of the required format.
This commit is contained in:
Wim Taymans 2016-07-05 12:24:51 +02:00
parent e7e141a31d
commit ca4f3d84cd
12 changed files with 568 additions and 186 deletions

View file

@ -432,7 +432,8 @@ pinos_daemon_remove_node (PinosDaemon *daemon,
*
* Find the best port in @daemon that matches the given parameters.
*
* Returns: a #PinosPort or %NULL when no port could be found.
* Returns: a #PinosPort or %NULL when no port could be found. unref the port
* after usage.
*/
PinosPort *
pinos_daemon_find_port (PinosDaemon *daemon,
@ -445,7 +446,7 @@ pinos_daemon_find_port (PinosDaemon *daemon,
PinosDaemonPrivate *priv;
PinosServerPort *best = NULL;
GList *nodes, *ports;
gboolean have_name;
gboolean have_name, created_port = FALSE;
g_return_val_if_fail (PINOS_IS_DAEMON (daemon), NULL);
priv = daemon->priv;
@ -456,6 +457,8 @@ pinos_daemon_find_port (PinosDaemon *daemon,
PinosServerNode *n = nodes->data;
gboolean node_found = FALSE;
g_debug ("name %s, node path %s", name, pinos_server_node_get_object_path (n));
/* we found the node */
if (have_name && g_str_has_suffix (pinos_server_node_get_object_path (n), name)) {
g_debug ("name \"%s\" matches node %p", name, n);
@ -489,15 +492,23 @@ pinos_daemon_find_port (PinosDaemon *daemon,
break;
}
}
if (node_found)
break;
if (best == NULL && node_found) {
g_debug ("node %p: making port", n);
best = pinos_server_node_create_port_sync (n, direction, name, format_filter, props);
if (best != NULL) {
created_port = TRUE;
break;
}
}
}
if (best == NULL) {
if (error)
*error = g_error_new (G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"No matching Port found");
}
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"No matching Port found");
} else if (!created_port)
g_object_ref (best);
return PINOS_PORT (best);
}

View file

@ -61,16 +61,15 @@ server_node_set_state (PinosNode *node,
return FALSE;
}
static void
server_node_create_port (PinosNode *node,
PinosDirection direction,
const gchar *name,
GBytes *possible_formats,
PinosProperties *props,
GTask *task)
static PinosServerPort *
server_node_create_port_sync (PinosServerNode *node,
PinosDirection direction,
const gchar *name,
GBytes *possible_formats,
PinosProperties *props)
{
PinosServerNodePrivate *priv = PINOS_SERVER_NODE (node)->priv;
PinosPort *port;
PinosServerNodePrivate *priv = node->priv;
PinosServerPort *port;
port = g_object_new (PINOS_TYPE_SERVER_PORT,
"daemon", priv->daemon,
@ -80,6 +79,26 @@ server_node_create_port (PinosNode *node,
"possible-formats", possible_formats,
"properties", props,
NULL);
pinos_node_add_port (PINOS_NODE (node), PINOS_PORT (port));
return port;
}
static void
server_node_create_port (PinosNode *node,
PinosDirection direction,
const gchar *name,
GBytes *possible_formats,
PinosProperties *props,
GTask *task)
{
PinosServerPort *port;
port = pinos_server_node_create_port_sync (PINOS_SERVER_NODE (node),
direction,
name,
possible_formats,
props);
g_task_return_pointer (task, port, (GDestroyNotify) g_object_unref);
g_object_unref (task);
@ -91,6 +110,18 @@ server_node_remove_port (PinosNode *node,
{
}
static void
remove_port (PinosPort *port)
{
guint n_links;
pinos_port_get_links (port, &n_links);
if (n_links == 0) {
pinos_port_remove (port);
}
g_object_unref (port);
}
static void
on_port_created (GObject *source_object,
GAsyncResult *res,
@ -138,9 +169,11 @@ on_port_created (GObject *source_object,
direction = pinos_port_get_direction (port);
direction = pinos_direction_reverse (direction);
val = pinos_properties_get (props, "target-path");
peer = pinos_daemon_find_port (priv->daemon,
direction,
NULL,
val,
pinos_port_get_properties (port),
pinos_port_get_possible_formats (port),
&error);
@ -149,6 +182,11 @@ on_port_created (GObject *source_object,
if (!pinos_port_link (port, peer))
goto link_failed;
g_object_set_data_full (G_OBJECT (port),
"autoconnect-peer-port",
peer,
(GDestroyNotify) remove_port);
}
object_path = pinos_server_port_get_object_path (PINOS_SERVER_PORT (port));
@ -198,6 +236,7 @@ link_failed:
g_debug ("server-node %p: could not link port", node);
g_dbus_method_invocation_return_dbus_error (invocation,
"org.pinos.Error", "can't link port");
g_object_unref (peer);
g_object_unref (fdlist);
return;
}
@ -458,6 +497,8 @@ pinos_server_node_class_init (PinosServerNodeClass * klass)
node_class->set_state = server_node_set_state;
node_class->create_port = server_node_create_port;
node_class->remove_port = server_node_remove_port;
klass->create_port_sync = server_node_create_port_sync;
}
static void
@ -558,3 +599,29 @@ pinos_server_node_get_object_path (PinosServerNode *node)
return priv->object_path;
}
PinosServerPort *
pinos_server_node_create_port_sync (PinosServerNode *node,
PinosDirection direction,
const gchar *name,
GBytes *possible_formats,
PinosProperties *props)
{
PinosServerNodeClass *klass;
PinosServerPort *port;
g_return_val_if_fail (PINOS_IS_SERVER_NODE (node), NULL);
klass = PINOS_SERVER_NODE_GET_CLASS (node);
if (!klass->create_port_sync)
return NULL;
g_debug ("server-node %p: create port", node);
port = klass->create_port_sync (node,
direction,
name,
possible_formats,
props);
return port;
}

View file

@ -60,6 +60,12 @@ struct _PinosServerNode {
*/
struct _PinosServerNodeClass {
PinosNodeClass parent_class;
PinosServerPort * (*create_port_sync) (PinosServerNode *node,
PinosDirection direction,
const gchar *name,
GBytes *possible_formats,
PinosProperties *props);
};
/* normal GObject stuff */
@ -74,6 +80,12 @@ PinosDaemon * pinos_server_node_get_daemon (PinosServerNode *
const gchar * pinos_server_node_get_sender (PinosServerNode *node);
const gchar * pinos_server_node_get_object_path (PinosServerNode *node);
PinosServerPort * pinos_server_node_create_port_sync (PinosServerNode *node,
PinosDirection direction,
const gchar *name,
GBytes *possible_formats,
PinosProperties *props);
G_END_DECLS
#endif /* __PINOS_SERVER_NODE_H__ */