mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-14 06:59:57 -05:00
Remove direction
Direction is tied to the port id. Handle nodes with fixed ports.
This commit is contained in:
parent
7d8e2d53f7
commit
9485bd77e7
25 changed files with 246 additions and 165 deletions
|
|
@ -273,8 +273,7 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
|
|||
GError *error = NULL;
|
||||
|
||||
port = PINOS_NODE_CLASS (pinos_client_node_parent_class)->add_port (pnode,
|
||||
pa->direction,
|
||||
event->port_id,
|
||||
pa->port_id,
|
||||
&error);
|
||||
|
||||
if (port == NULL) {
|
||||
|
|
@ -339,7 +338,7 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
|
|||
if ((res = spa_node_port_pull_output (node, 1, info)) < 0)
|
||||
g_debug ("client-node %p: got pull error %d, %d", this, res, info[0].status);
|
||||
|
||||
port = pinos_node_find_port (PINOS_NODE (this), info[0].port_id);
|
||||
port = pinos_node_find_port_by_id (PINOS_NODE (this), info[0].port_id);
|
||||
|
||||
if (!pinos_port_send_buffer (port, info[0].buffer_id, &error)) {
|
||||
g_debug ("send failed: %s", error->message);
|
||||
|
|
@ -351,8 +350,9 @@ on_node_event (SpaNode *node, SpaEvent *event, void *user_data)
|
|||
{
|
||||
PinosPort *port;
|
||||
GError *error = NULL;
|
||||
SpaEventReuseBuffer *rb = event->data;
|
||||
|
||||
port = pinos_node_find_port (PINOS_NODE (this), event->port_id);
|
||||
port = pinos_node_find_port_by_id (PINOS_NODE (this), rb->port_id);
|
||||
pinos_port_send_event (port, event, &error);
|
||||
break;
|
||||
}
|
||||
|
|
@ -374,16 +374,15 @@ setup_node (PinosClientNode *this)
|
|||
|
||||
static PinosPort *
|
||||
add_port (PinosNode *node,
|
||||
PinosDirection direction,
|
||||
guint id,
|
||||
GError **error)
|
||||
{
|
||||
PinosPort *port;
|
||||
|
||||
if (spa_node_add_port (node->node, direction, id) < 0)
|
||||
if (spa_node_add_port (node->node, id) < 0)
|
||||
g_warning ("client-node %p: error adding port", node);
|
||||
|
||||
port = PINOS_NODE_CLASS (pinos_client_node_parent_class)->add_port (node, direction, id, error);
|
||||
port = PINOS_NODE_CLASS (pinos_client_node_parent_class)->add_port (node, id, error);
|
||||
|
||||
if (port) {
|
||||
pinos_port_set_received_cb (port, on_received_buffer, on_received_event, node, NULL);
|
||||
|
|
@ -393,12 +392,12 @@ add_port (PinosNode *node,
|
|||
|
||||
static gboolean
|
||||
remove_port (PinosNode *node,
|
||||
guint id)
|
||||
PinosPort *port)
|
||||
{
|
||||
if (spa_node_remove_port (node->node, id) < 0)
|
||||
if (spa_node_remove_port (node->node, port->id) < 0)
|
||||
g_warning ("client-node %p: error removing port", node);
|
||||
|
||||
return PINOS_NODE_CLASS (pinos_client_node_parent_class)->remove_port (node, id);
|
||||
return PINOS_NODE_CLASS (pinos_client_node_parent_class)->remove_port (node, port);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -573,11 +573,21 @@ pinos_daemon_find_port (PinosDaemon *daemon,
|
|||
}
|
||||
}
|
||||
if (best == NULL && node_found) {
|
||||
g_debug ("node %p: making port", n);
|
||||
best = pinos_node_add_port (n, direction, 0, NULL);
|
||||
if (best != NULL) {
|
||||
created_port = TRUE;
|
||||
break;
|
||||
guint id;
|
||||
|
||||
id = pinos_node_get_free_port_id (n, direction);
|
||||
if (id != SPA_ID_INVALID) {
|
||||
g_debug ("node %p: making port with id %u", n, id);
|
||||
best = pinos_node_add_port (n, id, NULL);
|
||||
if (best != NULL) {
|
||||
created_port = TRUE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
g_debug ("node %p: using port with id %u", n, id);
|
||||
best = pinos_node_find_port_by_id (n, id);
|
||||
if (best != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,13 @@ struct _PinosNodePrivate
|
|||
gchar *object_path;
|
||||
gchar *name;
|
||||
|
||||
unsigned int max_input_ports;
|
||||
unsigned int max_output_ports;
|
||||
unsigned int n_input_ports;
|
||||
unsigned int n_output_ports;
|
||||
uint32_t *input_port_ids;
|
||||
uint32_t *output_port_ids;
|
||||
|
||||
PinosNodeState state;
|
||||
GError *error;
|
||||
guint idle_timeout;
|
||||
|
|
@ -87,17 +94,53 @@ node_set_state (PinosNode *node,
|
|||
static void
|
||||
do_remove_port (PinosPort *port, PinosNode *node)
|
||||
{
|
||||
pinos_node_remove_port (node, port->id);
|
||||
pinos_node_remove_port (node, port);
|
||||
}
|
||||
|
||||
static void
|
||||
update_port_ids (PinosNode *node, gboolean create)
|
||||
{
|
||||
PinosNodePrivate *priv = node->priv;
|
||||
guint i;
|
||||
|
||||
if (node->node == NULL)
|
||||
return;
|
||||
|
||||
spa_node_get_n_ports (node->node,
|
||||
&priv->n_input_ports,
|
||||
&priv->max_input_ports,
|
||||
&priv->n_output_ports,
|
||||
&priv->max_output_ports);
|
||||
|
||||
priv->input_port_ids = g_realloc_n (priv->input_port_ids, priv->max_input_ports, sizeof (uint32_t));
|
||||
priv->output_port_ids = g_realloc_n (priv->output_port_ids, priv->max_output_ports, sizeof (uint32_t));
|
||||
|
||||
spa_node_get_port_ids (node->node,
|
||||
priv->max_input_ports,
|
||||
priv->input_port_ids,
|
||||
priv->max_output_ports,
|
||||
priv->output_port_ids);
|
||||
|
||||
if (create) {
|
||||
for (i = 0; i < priv->n_input_ports; i++)
|
||||
pinos_node_add_port (node, priv->input_port_ids[i], NULL);
|
||||
for (i = 0; i < priv->n_output_ports; i++)
|
||||
pinos_node_add_port (node, priv->output_port_ids[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static PinosPort *
|
||||
node_add_port (PinosNode *node,
|
||||
PinosDirection direction,
|
||||
guint id,
|
||||
GError **error)
|
||||
{
|
||||
PinosNodePrivate *priv = node->priv;
|
||||
PinosPort *port;
|
||||
PinosDirection direction;
|
||||
|
||||
update_port_ids (node, FALSE);
|
||||
|
||||
direction = id < priv->max_input_ports ? PINOS_DIRECTION_INPUT : PINOS_DIRECTION_OUTPUT;
|
||||
|
||||
port = g_object_new (PINOS_TYPE_PORT,
|
||||
"daemon", priv->daemon,
|
||||
|
|
@ -115,17 +158,16 @@ node_add_port (PinosNode *node,
|
|||
|
||||
static gboolean
|
||||
node_remove_port (PinosNode *node,
|
||||
guint id)
|
||||
PinosPort *port)
|
||||
{
|
||||
PinosNodePrivate *priv = node->priv;
|
||||
PinosPort *port;
|
||||
|
||||
g_debug ("node %p: removed port %u", node, id);
|
||||
port = g_hash_table_lookup (priv->ports, GUINT_TO_POINTER (id));
|
||||
if (port) {
|
||||
g_debug ("node %p: removed port %u", node, port->id);
|
||||
g_object_ref (port);
|
||||
if (g_hash_table_remove (priv->ports, GUINT_TO_POINTER (port->id)))
|
||||
g_signal_emit (node, signals[SIGNAL_PORT_REMOVED], 0, port);
|
||||
g_hash_table_remove (priv->ports, GUINT_TO_POINTER (id));
|
||||
}
|
||||
g_object_unref (port);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +188,7 @@ handle_add_port (PinosNode1 *interface,
|
|||
if (g_strcmp0 (priv->sender, sender) != 0)
|
||||
goto not_allowed;
|
||||
|
||||
port = pinos_node_add_port (node, arg_direction, arg_id, &error);
|
||||
port = pinos_node_add_port (node, arg_id, &error);
|
||||
if (port == NULL)
|
||||
goto no_port;
|
||||
|
||||
|
|
@ -182,12 +224,17 @@ handle_remove_port (PinosNode1 *interface,
|
|||
PinosNode *node = user_data;
|
||||
PinosNodePrivate *priv = node->priv;
|
||||
const gchar *sender;
|
||||
PinosPort *port;
|
||||
|
||||
sender = g_dbus_method_invocation_get_sender (invocation);
|
||||
if (g_strcmp0 (priv->sender, sender) != 0)
|
||||
goto not_allowed;
|
||||
|
||||
if (!pinos_node_remove_port (node, arg_id))
|
||||
port = pinos_node_find_port_by_id (node, arg_id);
|
||||
if (port == NULL)
|
||||
goto no_port;
|
||||
|
||||
if (!pinos_node_remove_port (node, port))
|
||||
goto no_port;
|
||||
|
||||
g_debug ("node %p: remove port %u", node, arg_id);
|
||||
|
|
@ -377,6 +424,8 @@ pinos_node_constructed (GObject * obj)
|
|||
g_signal_connect (node, "notify", (GCallback) on_property_notify, node);
|
||||
G_OBJECT_CLASS (pinos_node_parent_class)->constructed (obj);
|
||||
|
||||
update_port_ids (node, TRUE);
|
||||
|
||||
if (priv->sender == NULL) {
|
||||
priv->sender = g_strdup (pinos_daemon_get_sender (priv->daemon));
|
||||
}
|
||||
|
|
@ -415,6 +464,8 @@ pinos_node_finalize (GObject * obj)
|
|||
g_clear_error (&priv->error);
|
||||
if (priv->properties)
|
||||
pinos_properties_free (priv->properties);
|
||||
g_free (priv->input_port_ids);
|
||||
g_free (priv->output_port_ids);
|
||||
|
||||
G_OBJECT_CLASS (pinos_node_parent_class)->finalize (obj);
|
||||
}
|
||||
|
|
@ -743,7 +794,6 @@ pinos_node_remove (PinosNode *node)
|
|||
*/
|
||||
PinosPort *
|
||||
pinos_node_add_port (PinosNode *node,
|
||||
PinosDirection direction,
|
||||
guint id,
|
||||
GError **error)
|
||||
{
|
||||
|
|
@ -759,7 +809,7 @@ pinos_node_add_port (PinosNode *node,
|
|||
}
|
||||
|
||||
g_debug ("node %p: add port", node);
|
||||
port = klass->add_port (node, direction, id, error);
|
||||
port = klass->add_port (node, id, error);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
|
@ -767,31 +817,75 @@ pinos_node_add_port (PinosNode *node,
|
|||
/**
|
||||
* pinos_node_remove_port:
|
||||
* @node: a #PinosNode
|
||||
* @id: a #PinosPort id
|
||||
* @port: a #PinosPort
|
||||
*
|
||||
* Remove the #PinosPort with @id from @node
|
||||
* Remove @port from @node
|
||||
*
|
||||
* Returns: %TRUE when the port was removed
|
||||
*/
|
||||
gboolean
|
||||
pinos_node_remove_port (PinosNode *node, guint id)
|
||||
pinos_node_remove_port (PinosNode *node, PinosPort *port)
|
||||
{
|
||||
PinosNodeClass *klass;
|
||||
gboolean res = FALSE;
|
||||
|
||||
g_return_val_if_fail (PINOS_IS_NODE (node), FALSE);
|
||||
g_return_val_if_fail (PINOS_IS_PORT (port), FALSE);
|
||||
|
||||
klass = PINOS_NODE_GET_CLASS (node);
|
||||
|
||||
if (!klass->remove_port)
|
||||
return FALSE;
|
||||
|
||||
res = klass->remove_port (node, id);
|
||||
res = klass->remove_port (node, port);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_node_find_port:
|
||||
* pinos_node_get_free_port_id:
|
||||
* @node: a #PinosNode
|
||||
* @direction: a #PinosDirection
|
||||
*
|
||||
* Find a new unused port id in @node with @direction
|
||||
*
|
||||
* Returns: the new port id of %SPA_INVALID_ID on error
|
||||
*/
|
||||
guint
|
||||
pinos_node_get_free_port_id (PinosNode *node,
|
||||
PinosDirection direction)
|
||||
{
|
||||
PinosNodePrivate *priv;
|
||||
guint i, free_port = 0, n_ports, max_ports;
|
||||
uint32_t *ports;
|
||||
|
||||
g_return_val_if_fail (PINOS_IS_NODE (node), -1);
|
||||
priv = node->priv;
|
||||
|
||||
if (direction == PINOS_DIRECTION_INPUT) {
|
||||
max_ports = priv->max_input_ports;
|
||||
n_ports = priv->n_input_ports;
|
||||
ports = priv->input_port_ids;
|
||||
} else {
|
||||
max_ports = priv->max_output_ports;
|
||||
n_ports = priv->n_output_ports;
|
||||
ports = priv->output_port_ids;
|
||||
}
|
||||
|
||||
g_debug ("direction %d max %u, n %u\n", direction, max_ports, n_ports);
|
||||
|
||||
for (i = 0; i < n_ports; i++) {
|
||||
if (free_port < ports[i])
|
||||
break;
|
||||
free_port = ports[i] + 1;
|
||||
}
|
||||
if (free_port >= max_ports)
|
||||
return -1;
|
||||
|
||||
return free_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* pinos_node_find_port_by_id:
|
||||
* @node: a #PinosNode
|
||||
* @id: a #PinosPort id
|
||||
*
|
||||
|
|
@ -800,7 +894,7 @@ pinos_node_remove_port (PinosNode *node, guint id)
|
|||
* Returns: a #PinosPort with @id or %NULL when not found
|
||||
*/
|
||||
PinosPort *
|
||||
pinos_node_find_port (PinosNode *node, guint id)
|
||||
pinos_node_find_port_by_id (PinosNode *node, guint id)
|
||||
{
|
||||
PinosNodePrivate *priv;
|
||||
|
||||
|
|
@ -989,5 +1083,9 @@ pinos_node_update_node_state (PinosNode *node,
|
|||
g_debug ("node %p: update SPA state to %d", node, state);
|
||||
node->node_state = state;
|
||||
g_object_notify (G_OBJECT (node), "node-state");
|
||||
|
||||
if (state == SPA_NODE_STATE_CONFIGURE) {
|
||||
update_port_ids (node, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,11 +70,10 @@ struct _PinosNodeClass {
|
|||
PinosNodeState state);
|
||||
|
||||
PinosPort * (*add_port) (PinosNode *node,
|
||||
PinosDirection direction,
|
||||
guint id,
|
||||
GError **error);
|
||||
gboolean (*remove_port) (PinosNode *node,
|
||||
guint id);
|
||||
PinosPort *port);
|
||||
};
|
||||
|
||||
/* normal GObject stuff */
|
||||
|
|
@ -94,13 +93,14 @@ PinosDaemon * pinos_node_get_daemon (PinosNode *node);
|
|||
const gchar * pinos_node_get_sender (PinosNode *node);
|
||||
const gchar * pinos_node_get_object_path (PinosNode *node);
|
||||
|
||||
guint pinos_node_get_free_port_id (PinosNode *node,
|
||||
PinosDirection direction);
|
||||
PinosPort * pinos_node_add_port (PinosNode *node,
|
||||
PinosDirection direction,
|
||||
guint id,
|
||||
GError **error);
|
||||
gboolean pinos_node_remove_port (PinosNode *node,
|
||||
guint id);
|
||||
PinosPort * pinos_node_find_port (PinosNode *node,
|
||||
PinosPort *port);
|
||||
PinosPort * pinos_node_find_port_by_id (PinosNode *node,
|
||||
guint id);
|
||||
GList * pinos_node_get_ports (PinosNode *node);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue