From d9bb116d279b155d1ce034853cf1fa047d9d979c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 12 Apr 2017 11:24:11 +0200 Subject: [PATCH] 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. --- pinos/server/node.c | 25 +++++++++++++------------ spa/plugins/audiomixer/audiomixer.c | 8 ++++---- spa/tests/test-mixer.c | 2 +- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/pinos/server/node.c b/pinos/server/node.c index 07b3a2f82..810c9b082 100644 --- a/pinos/server/node.c +++ b/pinos/server/node.c @@ -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; } diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c index 9be4ecd9e..46f16b49a 100644 --- a/spa/plugins/audiomixer/audiomixer.c +++ b/spa/plugins/audiomixer/audiomixer.c @@ -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; diff --git a/spa/tests/test-mixer.c b/spa/tests/test-mixer.c index 745ffd754..05ae44ce2 100644 --- a/spa/tests/test-mixer.c +++ b/spa/tests/test-mixer.c @@ -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);