node: schedule upstream first

In pull mode, schedule all upstream nodes first, if any of them
produce output, push it into the current node.
Underrun streams without input on audiomixer, avoids glitch when
starting a new stream.
This commit is contained in:
Wim Taymans 2017-04-12 11:24:11 +02:00
parent 4c7b56020a
commit d9bb116d27
3 changed files with 18 additions and 17 deletions

View file

@ -258,6 +258,7 @@ do_pull (PinosNode *this)
{
SpaResult res = SPA_RESULT_OK;
PinosPort *inport;
bool have_output = false;
spa_list_for_each (inport, &this->input_ports, link) {
PinosLink *link;
@ -288,22 +289,22 @@ do_pull (PinosNode *this)
if (res == SPA_RESULT_NEED_INPUT) {
res = do_pull (outport->node);
*pi = *po;
pinos_log_trace ("node %p: pull return %d", outport->node, res);
}
else if (res == SPA_RESULT_HAVE_OUTPUT) {
*pi = *po;
}
else
else if (res < 0 && res != SPA_RESULT_HAVE_OUTPUT) {
pinos_log_warn ("node %p: got process output %d", outport->node, res);
}
if (res == SPA_RESULT_HAVE_OUTPUT) {
*pi = *po;
pinos_log_trace ("node %p: have output %d %d", this, pi->status, pi->buffer_id);
have_output = true;
}
}
if (pi->buffer_id != SPA_ID_INVALID) {
pinos_log_trace ("node %p: process input %d %d", this, pi->status, pi->buffer_id);
res = spa_node_process_input (this->node);
if (res == SPA_RESULT_HAVE_OUTPUT)
break;
}
}
if (have_output) {
pinos_log_trace ("node %p: doing process input", this);
res = spa_node_process_input (this->node);
}
return res;
}

View file

@ -733,7 +733,7 @@ spa_audiomixer_node_process_input (SpaNode *node)
spa_log_trace (this->log, "audiomixer %p: queue buffer %d on port %d %zd %zd",
this, b->outbuf->id, i, port->queued_bytes, min_queued);
}
if (min_queued == SIZE_MAX || port->queued_bytes < min_queued)
if (port->queued_bytes > 0 && port->queued_bytes < min_queued)
min_queued = port->queued_bytes;
}
@ -772,7 +772,7 @@ spa_audiomixer_node_process_output (SpaNode *node)
res = SPA_RESULT_NEED_INPUT;
/* produce more output if possible */
if (this->state == STATE_OUT) {
size_t min_queued = -1;
size_t min_queued = SIZE_MAX;
for (i = 0; i < MAX_PORTS; i++) {
SpaAudioMixerPort *port = &this->in_ports[i];
@ -780,10 +780,10 @@ spa_audiomixer_node_process_output (SpaNode *node)
if (port->io == NULL || port->n_buffers == 0)
continue;
if (min_queued == -1 || port->queued_bytes < min_queued)
if (port->queued_bytes > 0 && port->queued_bytes < min_queued)
min_queued = port->queued_bytes;
}
if (min_queued != -1 && min_queued > 0) {
if (min_queued != SIZE_MAX && min_queued > 0) {
res = mix_output (this, min_queued);
} else {
this->state = STATE_IN;

View file

@ -311,7 +311,7 @@ make_nodes (AppData *data)
spa_pod_builder_init (&b, buffer, sizeof (buffer));
spa_pod_builder_props (&b, &f[0], data->type.props,
SPA_POD_PROP (&f[1], data->type.props_device, 0, SPA_POD_TYPE_STRING, 1, "hw:0"),
SPA_POD_PROP (&f[1], data->type.props_device, 0, SPA_POD_TYPE_STRING, 1, "hw:1"),
SPA_POD_PROP (&f[1], data->type.props_min_latency, 0, SPA_POD_TYPE_INT, 1, 256),
SPA_POD_PROP (&f[1], data->type.props_live, 0, SPA_POD_TYPE_BOOL, 1, false));
props = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaProps);