mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-14 06:59:57 -05:00
pinossrc: handle latency and liveness
Use NULL filter when the port format enumeration returns nothing. Send clock update even when there is no clock. Don't send data to a port when the node is not streaming Add latency support to the clock update Copy the unset_mask when copying the formats
This commit is contained in:
parent
021eccb8ad
commit
b75d9786d4
13 changed files with 147 additions and 77 deletions
|
|
@ -216,7 +216,7 @@ on_port_added (PinosNode *node, PinosDirection direction, guint port_id, PinosCl
|
|||
|
||||
new_port = pinos_node_get_free_port (target, pinos_direction_reverse (direction));
|
||||
if (new_port == SPA_ID_INVALID) {
|
||||
g_debug ("daemon %p: can't create free port", this);
|
||||
g_warning ("daemon %p: can't get free port", this);
|
||||
return;
|
||||
}
|
||||
if (direction == PINOS_DIRECTION_OUTPUT)
|
||||
|
|
@ -224,6 +224,11 @@ on_port_added (PinosNode *node, PinosDirection direction, guint port_id, PinosCl
|
|||
else
|
||||
link = pinos_node_link (target, new_port, node, port_id, NULL, NULL);
|
||||
|
||||
if (link == NULL) {
|
||||
g_warning ("daemon %p: can't link nodes", this);
|
||||
return;
|
||||
}
|
||||
|
||||
pinos_client_add_object (client, G_OBJECT (link));
|
||||
g_object_unref (link);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ static SpaResult
|
|||
do_negotiate (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
||||
{
|
||||
SpaResult res;
|
||||
SpaFormat *filter, *format;
|
||||
SpaFormat *filter = NULL, *format;
|
||||
void *istate = NULL, *ostate = NULL;
|
||||
|
||||
/* both ports need a format */
|
||||
|
|
@ -231,8 +231,10 @@ again:
|
|||
&filter,
|
||||
NULL,
|
||||
&istate)) < 0) {
|
||||
g_warning ("error input enum formats: %d", res);
|
||||
goto error;
|
||||
if (res == SPA_RESULT_ENUM_END && istate != NULL) {
|
||||
g_warning ("error input enum formats: %d", res);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
spa_debug_format (filter);
|
||||
|
||||
|
|
@ -336,6 +338,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
|||
}
|
||||
memcpy (priv->out_buffers, priv->in_buffers, priv->n_in_buffers * sizeof (SpaBuffer*));
|
||||
priv->n_out_buffers = priv->n_in_buffers;
|
||||
g_debug ("allocated out_buffers %p, in_buffers %p", priv->out_buffers, priv->in_buffers);
|
||||
} else if ((out_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) &&
|
||||
(in_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS)) {
|
||||
out_flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
|
||||
|
|
@ -347,8 +350,10 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
|||
}
|
||||
} else if (in_state == SPA_NODE_STATE_READY && out_state > SPA_NODE_STATE_READY) {
|
||||
out_flags &= ~SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
|
||||
in_flags &= ~SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
|
||||
} else if (out_state == SPA_NODE_STATE_READY && in_state > SPA_NODE_STATE_READY) {
|
||||
in_flags &= ~SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
|
||||
out_flags &= ~SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
|
||||
} else
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
|
|
@ -363,6 +368,7 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
|||
g_warning ("error alloc buffers: %d", res);
|
||||
goto error;
|
||||
}
|
||||
g_debug ("allocated in_buffers %p", priv->in_buffers);
|
||||
}
|
||||
else if (out_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) {
|
||||
priv->n_out_buffers = 16;
|
||||
|
|
@ -372,8 +378,10 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
|||
g_warning ("error alloc buffers: %d", res);
|
||||
goto error;
|
||||
}
|
||||
g_debug ("allocated out_buffers %p", priv->out_buffers);
|
||||
}
|
||||
if (in_flags & SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS) {
|
||||
g_debug ("using out_buffers %p", priv->out_buffers);
|
||||
if ((res = spa_node_port_use_buffers (this->input_node->node, this->input_port,
|
||||
priv->out_buffers, priv->n_out_buffers)) < 0) {
|
||||
g_warning ("error use buffers: %d", res);
|
||||
|
|
@ -381,12 +389,14 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
|||
}
|
||||
}
|
||||
else if (out_flags & SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS) {
|
||||
g_debug ("using in_buffers %p", priv->out_buffers);
|
||||
if ((res = spa_node_port_use_buffers (this->output_node->node, this->output_port,
|
||||
priv->in_buffers, priv->n_in_buffers)) < 0) {
|
||||
g_warning ("error use buffers: %d", res);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} else
|
||||
return SPA_RESULT_NO_BUFFERS;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
||||
|
|
|
|||
|
|
@ -320,23 +320,32 @@ static void
|
|||
send_clock_update (PinosNode *this)
|
||||
{
|
||||
PinosNodePrivate *priv = this->priv;
|
||||
SpaNodeCommand cmd;
|
||||
SpaNodeCommandClockUpdate cu;
|
||||
SpaResult res;
|
||||
|
||||
cmd.type = SPA_NODE_COMMAND_CLOCK_UPDATE;
|
||||
cmd.data = &cu;
|
||||
cmd.size = sizeof (cu);
|
||||
|
||||
cu.flags = 0;
|
||||
cu.change_mask = SPA_NODE_COMMAND_CLOCK_UPDATE_TIME |
|
||||
SPA_NODE_COMMAND_CLOCK_UPDATE_SCALE |
|
||||
SPA_NODE_COMMAND_CLOCK_UPDATE_STATE |
|
||||
SPA_NODE_COMMAND_CLOCK_UPDATE_LATENCY;
|
||||
if (priv->clock) {
|
||||
SpaNodeCommand cmd;
|
||||
SpaNodeCommandClockUpdate cu;
|
||||
SpaResult res;
|
||||
|
||||
cmd.type = SPA_NODE_COMMAND_CLOCK_UPDATE;
|
||||
cmd.data = &cu;
|
||||
cmd.size = sizeof (cu);
|
||||
cu.change_mask = SPA_NODE_COMMAND_CLOCK_UPDATE_TIME;
|
||||
cu.flags = SPA_NODE_COMMAND_CLOCK_UPDATE_FLAG_LIVE;
|
||||
res = spa_clock_get_time (priv->clock, &cu.rate, &cu.ticks, &cu.monotonic_time);
|
||||
cu.scale = (1 << 16) | 1;
|
||||
cu.state = SPA_CLOCK_STATE_RUNNING;
|
||||
|
||||
if ((res = spa_node_send_command (this->node, &cmd)) < 0)
|
||||
g_debug ("got error %d", res);
|
||||
} else {
|
||||
cu.rate = 1;
|
||||
cu.ticks = 0;
|
||||
cu.monotonic_time = 0;
|
||||
}
|
||||
cu.scale = (1 << 16) | 1;
|
||||
cu.state = SPA_CLOCK_STATE_RUNNING;
|
||||
|
||||
if ((res = spa_node_send_command (this->node, &cmd)) < 0)
|
||||
g_debug ("got error %d", res);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -510,6 +519,9 @@ on_node_event (SpaNode *node, SpaNodeEvent *event, void *user_data)
|
|||
if (pl == NULL || pl->output_node->node != node || pl->output_port != oinfo[0].port_id)
|
||||
continue;
|
||||
|
||||
if (pl->input_node->node->state != SPA_NODE_STATE_STREAMING)
|
||||
continue;
|
||||
|
||||
iinfo[0].port_id = pl->input_port;
|
||||
iinfo[0].buffer_id = oinfo[0].buffer_id;
|
||||
iinfo[0].flags = SPA_PORT_INPUT_FLAG_NONE;
|
||||
|
|
@ -1229,19 +1241,22 @@ pinos_node_link (PinosNode *output_node,
|
|||
} else {
|
||||
uint32_t input_port, output_port;
|
||||
|
||||
output_port = get_free_node_port (output_node, PINOS_DIRECTION_OUTPUT);
|
||||
if (output_port == SPA_ID_INVALID && output_node->priv->n_output_ports > 0)
|
||||
output_port = output_node->priv->output_port_ids[0];
|
||||
else
|
||||
return NULL;
|
||||
|
||||
input_port = get_free_node_port (input_node, PINOS_DIRECTION_INPUT);
|
||||
if (input_port == SPA_ID_INVALID && input_node->priv->n_input_ports > 0)
|
||||
input_port = input_node->priv->input_port_ids[0];
|
||||
else
|
||||
return NULL;
|
||||
|
||||
if (output_node->priv->clock)
|
||||
input_node->priv->clock = output_node->priv->clock;
|
||||
|
||||
g_debug ("node %p: clock %p", output_node, output_node->priv->clock);
|
||||
|
||||
output_port = get_free_node_port (output_node, PINOS_DIRECTION_OUTPUT);
|
||||
if (output_port == SPA_ID_INVALID)
|
||||
output_port = output_node->priv->output_port_ids[0];
|
||||
|
||||
input_port = get_free_node_port (input_node, PINOS_DIRECTION_INPUT);
|
||||
if (input_port == SPA_ID_INVALID)
|
||||
input_port = input_node->priv->input_port_ids[0];
|
||||
|
||||
pl = g_object_new (PINOS_TYPE_LINK,
|
||||
"daemon", priv->daemon,
|
||||
"output-node", output_node,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue