mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
audioconvert: various fixes
This commit is contained in:
parent
3b8ffdfb4e
commit
06dd7095fc
4 changed files with 71 additions and 34 deletions
|
|
@ -783,7 +783,7 @@ impl_node_port_send_command(struct spa_node *node,
|
||||||
static int impl_node_process(struct spa_node *node)
|
static int impl_node_process(struct spa_node *node)
|
||||||
{
|
{
|
||||||
struct impl *this;
|
struct impl *this;
|
||||||
int i;
|
int i, res = SPA_STATUS_OK;
|
||||||
|
|
||||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||||
|
|
||||||
|
|
@ -791,10 +791,19 @@ static int impl_node_process(struct spa_node *node)
|
||||||
|
|
||||||
spa_log_trace(this->log, NAME " %p: process %d", this, this->n_links);
|
spa_log_trace(this->log, NAME " %p: process %d", this, this->n_links);
|
||||||
|
|
||||||
for (i = 1; i < this->n_links; i++)
|
for (i = 1; i < this->n_links; i++) {
|
||||||
spa_node_process(this->links[i].out_node);
|
res = spa_node_process(this->links[i].out_node);
|
||||||
|
if (!SPA_FLAG_CHECK(res, SPA_STATUS_HAVE_BUFFER)) {
|
||||||
|
if (SPA_FLAG_CHECK(res, SPA_STATUS_NEED_BUFFER) && i == 1)
|
||||||
|
break;
|
||||||
|
i = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SPA_STATUS_OK;
|
spa_log_trace(this->log, NAME " %p: process result: %d", this, res);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct spa_node impl_node = {
|
static const struct spa_node impl_node = {
|
||||||
|
|
|
||||||
|
|
@ -852,7 +852,6 @@ static int impl_node_process(struct spa_node *node)
|
||||||
inio->status = SPA_STATUS_NEED_BUFFER;
|
inio->status = SPA_STATUS_NEED_BUFFER;
|
||||||
inport->offset = 0;
|
inport->offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outio->status = SPA_STATUS_HAVE_BUFFER;
|
outio->status = SPA_STATUS_HAVE_BUFFER;
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ struct port {
|
||||||
uint32_t n_buffers;
|
uint32_t n_buffers;
|
||||||
|
|
||||||
struct spa_list queue;
|
struct spa_list queue;
|
||||||
|
uint32_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct type {
|
struct type {
|
||||||
|
|
@ -632,6 +633,8 @@ impl_node_port_use_buffers(struct spa_node *node,
|
||||||
spa_list_append(&port->queue, &b->link);
|
spa_list_append(&port->queue, &b->link);
|
||||||
else
|
else
|
||||||
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
|
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
|
||||||
|
|
||||||
|
port->offset = 0;
|
||||||
}
|
}
|
||||||
port->n_buffers = n_buffers;
|
port->n_buffers = n_buffers;
|
||||||
port->size = size;
|
port->size = size;
|
||||||
|
|
@ -689,7 +692,7 @@ static void recycle_buffer(struct impl *this, uint32_t id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct buffer *dequeue_buffer(struct impl *this, struct port *port)
|
static struct buffer *peek_buffer(struct impl *this, struct port *port)
|
||||||
{
|
{
|
||||||
struct buffer *b;
|
struct buffer *b;
|
||||||
|
|
||||||
|
|
@ -697,12 +700,14 @@ static struct buffer *dequeue_buffer(struct impl *this, struct port *port)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
b = spa_list_first(&port->queue, struct buffer, link);
|
b = spa_list_first(&port->queue, struct buffer, link);
|
||||||
spa_list_remove(&b->link);
|
|
||||||
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
|
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void dequeue_buffer(struct impl *this, struct buffer *b)
|
||||||
|
{
|
||||||
|
spa_list_remove(&b->link);
|
||||||
|
SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
static int impl_node_port_reuse_buffer(struct spa_node *node, uint32_t port_id, uint32_t buffer_id)
|
static int impl_node_port_reuse_buffer(struct spa_node *node, uint32_t port_id, uint32_t buffer_id)
|
||||||
{
|
{
|
||||||
|
|
@ -734,6 +739,9 @@ static int impl_node_process(struct spa_node *node)
|
||||||
struct port *outport, *inport;
|
struct port *outport, *inport;
|
||||||
struct spa_io_buffers *outio, *inio;
|
struct spa_io_buffers *outio, *inio;
|
||||||
struct buffer *sbuf, *dbuf;
|
struct buffer *sbuf, *dbuf;
|
||||||
|
struct spa_buffer *sb, *db;
|
||||||
|
uint32_t i, size, in_len, out_len, maxsize;
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
spa_return_val_if_fail(node != NULL, -EINVAL);
|
spa_return_val_if_fail(node != NULL, -EINVAL);
|
||||||
|
|
||||||
|
|
@ -751,7 +759,7 @@ static int impl_node_process(struct spa_node *node)
|
||||||
spa_log_trace(this->log, NAME " %p: status %d %d", this, inio->status, outio->status);
|
spa_log_trace(this->log, NAME " %p: status %d %d", this, inio->status, outio->status);
|
||||||
|
|
||||||
if (outio->status == SPA_STATUS_HAVE_BUFFER)
|
if (outio->status == SPA_STATUS_HAVE_BUFFER)
|
||||||
return outio->status;
|
return SPA_STATUS_HAVE_BUFFER;
|
||||||
|
|
||||||
if (inio->status != SPA_STATUS_HAVE_BUFFER)
|
if (inio->status != SPA_STATUS_HAVE_BUFFER)
|
||||||
return SPA_STATUS_NEED_BUFFER;
|
return SPA_STATUS_NEED_BUFFER;
|
||||||
|
|
@ -765,35 +773,47 @@ static int impl_node_process(struct spa_node *node)
|
||||||
if (inio->buffer_id >= inport->n_buffers)
|
if (inio->buffer_id >= inport->n_buffers)
|
||||||
return inio->status = -EINVAL;
|
return inio->status = -EINVAL;
|
||||||
|
|
||||||
if ((dbuf = dequeue_buffer(this, outport)) == NULL)
|
if ((dbuf = peek_buffer(this, outport)) == NULL)
|
||||||
return outio->status = -EPIPE;
|
return outio->status = -EPIPE;
|
||||||
|
|
||||||
sbuf = &inport->buffers[inio->buffer_id];
|
sbuf = &inport->buffers[inio->buffer_id];
|
||||||
|
|
||||||
{
|
sb = sbuf->outbuf;
|
||||||
int i;
|
db = dbuf->outbuf;
|
||||||
struct spa_buffer *sb = sbuf->outbuf, *db = dbuf->outbuf;
|
|
||||||
|
size = sb->datas[0].chunk->size;
|
||||||
|
maxsize = db->datas[0].maxsize;
|
||||||
|
|
||||||
|
in_len = (size - inport->offset) / sizeof(float);
|
||||||
|
out_len = (maxsize - outport->offset) / sizeof(float);
|
||||||
|
|
||||||
for (i = 0; i < sb->n_datas; i++) {
|
for (i = 0; i < sb->n_datas; i++) {
|
||||||
uint32_t in_len, out_len;
|
|
||||||
|
|
||||||
in_len = sb->datas[i].chunk->size / sizeof(float);
|
|
||||||
out_len = db->datas[i].maxsize / sizeof(float);
|
|
||||||
|
|
||||||
speex_resampler_process_float(this->state, i,
|
speex_resampler_process_float(this->state, i,
|
||||||
sb->datas[i].data, &in_len,
|
SPA_MEMBER(sb->datas[i].data, inport->offset, void), &in_len,
|
||||||
db->datas[i].data, &out_len);
|
SPA_MEMBER(db->datas[i].data, outport->offset, void), &out_len);
|
||||||
|
|
||||||
db->datas[i].chunk->size = out_len * sizeof(float);
|
spa_log_trace(this->log, NAME " %p: in %d/%ld %d out %d/%ld %d",
|
||||||
}
|
this, in_len, size / sizeof(float), inport->offset,
|
||||||
|
out_len, maxsize / sizeof(float), outport->offset);
|
||||||
|
|
||||||
|
db->datas[i].chunk->size = outport->offset + (out_len * sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inport->offset += in_len * sizeof(float);
|
||||||
|
if (inport->offset >= size) {
|
||||||
|
inio->status = SPA_STATUS_NEED_BUFFER;
|
||||||
|
inport->offset = 0;
|
||||||
|
SPA_FLAG_SET(res, SPA_STATUS_NEED_BUFFER);
|
||||||
|
}
|
||||||
|
outport->offset += out_len * sizeof(float);
|
||||||
|
if (outport->offset >= maxsize) {
|
||||||
outio->status = SPA_STATUS_HAVE_BUFFER;
|
outio->status = SPA_STATUS_HAVE_BUFFER;
|
||||||
outio->buffer_id = dbuf->outbuf->id;
|
outio->buffer_id = dbuf->outbuf->id;
|
||||||
|
dequeue_buffer(this, dbuf);
|
||||||
inio->status = SPA_STATUS_NEED_BUFFER;
|
outport->offset = 0;
|
||||||
|
SPA_FLAG_SET(res, SPA_STATUS_HAVE_BUFFER);
|
||||||
return outio->status;
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct spa_node impl_node = {
|
static const struct spa_node impl_node = {
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,8 @@ struct port {
|
||||||
int32_t *io_mute;
|
int32_t *io_mute;
|
||||||
|
|
||||||
struct spa_port_info info;
|
struct spa_port_info info;
|
||||||
|
struct spa_dict info_props;
|
||||||
|
struct spa_dict_item info_props_items[2];
|
||||||
|
|
||||||
bool have_format;
|
bool have_format;
|
||||||
|
|
||||||
|
|
@ -283,6 +285,10 @@ static int impl_node_add_port(struct spa_node *node, enum spa_direction directio
|
||||||
port->info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
|
port->info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
|
||||||
SPA_PORT_INFO_FLAG_REMOVABLE;
|
SPA_PORT_INFO_FLAG_REMOVABLE;
|
||||||
|
|
||||||
|
port->info_props_items[0] = SPA_DICT_ITEM_INIT("port.dsp", "32 bit float mono audio");
|
||||||
|
port->info_props = SPA_DICT_INIT(port->info_props_items, 1);
|
||||||
|
port->info.props = &port->info_props;
|
||||||
|
|
||||||
this->port_count++;
|
this->port_count++;
|
||||||
if (this->last_port <= port_id)
|
if (this->last_port <= port_id)
|
||||||
this->last_port = port_id + 1;
|
this->last_port = port_id + 1;
|
||||||
|
|
@ -588,15 +594,16 @@ static int port_set_format(struct spa_node *node,
|
||||||
info.info.raw.rate != this->format.info.raw.rate)
|
info.info.raw.rate != this->format.info.raw.rate)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
this->bpf = sizeof(float);
|
||||||
if (direction == SPA_DIRECTION_INPUT) {
|
if (direction == SPA_DIRECTION_INPUT) {
|
||||||
if (info.info.raw.channels != this->port_count)
|
if (info.info.raw.channels != this->port_count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
this->bpf *= this->port_count;
|
||||||
} else {
|
} else {
|
||||||
if (info.info.raw.channels != 1)
|
if (info.info.raw.channels != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->bpf = sizeof(float);
|
|
||||||
this->have_format = true;
|
this->have_format = true;
|
||||||
this->format = info;
|
this->format = info;
|
||||||
|
|
||||||
|
|
@ -779,7 +786,7 @@ static int impl_node_process(struct spa_node *node)
|
||||||
struct impl *this;
|
struct impl *this;
|
||||||
struct port *inport;
|
struct port *inport;
|
||||||
struct spa_io_buffers *inio;
|
struct spa_io_buffers *inio;
|
||||||
int i, size = 0;
|
int i, size = 0, res = 0;
|
||||||
struct spa_data *sd, *dd;
|
struct spa_data *sd, *dd;
|
||||||
struct buffer *sbuf, *dbuf;
|
struct buffer *sbuf, *dbuf;
|
||||||
|
|
||||||
|
|
@ -791,6 +798,8 @@ static int impl_node_process(struct spa_node *node)
|
||||||
inio = inport->io;
|
inio = inport->io;
|
||||||
spa_return_val_if_fail(inio != NULL, -EIO);
|
spa_return_val_if_fail(inio != NULL, -EIO);
|
||||||
|
|
||||||
|
spa_log_trace(this->log, NAME " %p: status %d", this, inio->status);
|
||||||
|
|
||||||
if (inio->status != SPA_STATUS_HAVE_BUFFER)
|
if (inio->status != SPA_STATUS_HAVE_BUFFER)
|
||||||
return SPA_STATUS_NEED_BUFFER;
|
return SPA_STATUS_NEED_BUFFER;
|
||||||
|
|
||||||
|
|
@ -799,8 +808,6 @@ static int impl_node_process(struct spa_node *node)
|
||||||
|
|
||||||
sbuf = &inport->buffers[inio->buffer_id];
|
sbuf = &inport->buffers[inio->buffer_id];
|
||||||
|
|
||||||
spa_log_trace(this->log, NAME " %p: status %d", this, inio->status);
|
|
||||||
|
|
||||||
/* produce more output if possible */
|
/* produce more output if possible */
|
||||||
for (i = 0; i < this->last_port; i++) {
|
for (i = 0; i < this->last_port; i++) {
|
||||||
struct port *outport = GET_OUT_PORT(this, i);
|
struct port *outport = GET_OUT_PORT(this, i);
|
||||||
|
|
@ -831,14 +838,16 @@ static int impl_node_process(struct spa_node *node)
|
||||||
|
|
||||||
outio->buffer_id = dbuf->buf->id;
|
outio->buffer_id = dbuf->buf->id;
|
||||||
outio->status = SPA_STATUS_HAVE_BUFFER;
|
outio->status = SPA_STATUS_HAVE_BUFFER;
|
||||||
|
SPA_FLAG_SET(res, SPA_STATUS_HAVE_BUFFER);
|
||||||
|
|
||||||
}
|
}
|
||||||
inport->offset += size;
|
inport->offset += size;
|
||||||
if (inport->offset >= sbuf->buf->datas[0].chunk->size) {
|
if (inport->offset >= sbuf->buf->datas[0].chunk->size) {
|
||||||
inport->offset = 0;
|
inport->offset = 0;
|
||||||
inio->status = SPA_STATUS_NEED_BUFFER;
|
inio->status = SPA_STATUS_NEED_BUFFER;
|
||||||
|
SPA_FLAG_SET(res, SPA_STATUS_NEED_BUFFER);
|
||||||
}
|
}
|
||||||
return SPA_STATUS_HAVE_BUFFER;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct spa_node impl_node = {
|
static const struct spa_node impl_node = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue