work on separating port mixers

Make it possible to assign an arbitary node as the port mixer.
Also remove dynamically added ports.
Improve negotiation and allocation on the mixer ports
Add some more SSE optimisations
Move float mixer from the audio dsp to the port
Remove pw_node_get_free_port() and do things more explicitly.
Handle mixer ports in client-node
This commit is contained in:
Wim Taymans 2018-07-31 12:23:35 +02:00
parent f55cb422cb
commit ca898a00db
29 changed files with 2422 additions and 1504 deletions

View file

@ -160,9 +160,9 @@ struct impl {
bool started;
const struct conv_info *conv[2];
convert_func_t convert;
float empty[4096];
};
#define CHECK_FREE_PORT(this,d,id) (id < MAX_PORTS && !GET_PORT(this,d,id)->valid)
@ -196,6 +196,7 @@ static int setup_convert(struct impl *this)
uint32_t src_fmt, dst_fmt;
struct type *t = &this->type;
struct format informat, outformat;
const struct conv_info *conv;
if (collect_format(this, SPA_DIRECTION_INPUT, &informat) < 0)
return -1;
@ -222,19 +223,21 @@ static int setup_convert(struct impl *this)
return -EINVAL;
/* find fast path */
this->conv[0] = find_conv_info(&t->audio_format, src_fmt, dst_fmt);
if (this->conv[0] != NULL) {
conv = find_conv_info(&t->audio_format, src_fmt, dst_fmt, FEATURE_SSE);
if (conv != NULL) {
spa_log_info(this->log, NAME " %p: got converter features %08x", this,
conv->features);
if (informat.format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED) {
if (outformat.format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED)
this->convert = this->conv[0]->i2i;
this->convert = conv->i2i;
else
this->convert = this->conv[0]->i2d;
this->convert = conv->i2d;
}
else {
if (outformat.format.info.raw.layout == SPA_AUDIO_LAYOUT_INTERLEAVED)
this->convert = this->conv[0]->d2i;
this->convert = conv->d2i;
else
this->convert = this->conv[0]->i2i;
this->convert = conv->i2i;
}
return 0;
}
@ -972,18 +975,15 @@ static int process_merge(struct impl *this)
for (i = 0; i < n_ins; i++) {
inport = GET_IN_PORT(this, i);
inio = inport->io;
if (inio == NULL)
if ((inio = inport->io) == NULL ||
inio->status != SPA_STATUS_HAVE_BUFFER ||
inio->buffer_id >= inport->n_buffers)
continue;
spa_log_trace(this->log, NAME " %p: %d %p %d %d %d", this, i,
inio, inio->status, inio->buffer_id, inport->stride);
if (inio->status != SPA_STATUS_HAVE_BUFFER)
continue;
if (inio->buffer_id >= inport->n_buffers)
continue;
inbuf = &inport->buffers[inio->buffer_id];
inb = inbuf->outbuf;
@ -1063,13 +1063,14 @@ static int process_split(struct impl *this)
outport = GET_OUT_PORT(this, i);
outio = outport->io;
if (outio == NULL)
continue;
goto empty;
spa_log_trace(this->log, NAME " %p: %d %p %d %d %d", this, i,
outio, outio->status, outio->buffer_id, outport->stride);
if (outio->status == SPA_STATUS_HAVE_BUFFER) {
res |= SPA_STATUS_HAVE_BUFFER;
continue;
goto empty;
}
if (outio->buffer_id < outport->n_buffers) {
@ -1077,8 +1078,12 @@ static int process_split(struct impl *this)
outio->buffer_id = SPA_ID_INVALID;
}
if ((outbuf = peek_buffer(this, outport)) == NULL)
return outio->status = -EPIPE;
if ((outbuf = peek_buffer(this, outport)) == NULL) {
outio->status = -EPIPE;
empty:
dst_datas[n_dst_datas++] = this->empty;
continue;
}
outb = outbuf->outbuf;