mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -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;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (i = 0; i < sb->n_datas; i++) {
 | 
						size = sb->datas[0].chunk->size;
 | 
				
			||||||
			uint32_t in_len, out_len;
 | 
						maxsize = db->datas[0].maxsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			in_len = sb->datas[i].chunk->size / sizeof(float);
 | 
						in_len = (size - inport->offset) / sizeof(float);
 | 
				
			||||||
			out_len = db->datas[i].maxsize / sizeof(float);
 | 
						out_len = (maxsize - outport->offset) / sizeof(float);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			speex_resampler_process_float(this->state, i,
 | 
						for (i = 0; i < sb->n_datas; i++) {
 | 
				
			||||||
					sb->datas[i].data, &in_len,
 | 
							speex_resampler_process_float(this->state, i,
 | 
				
			||||||
					db->datas[i].data, &out_len);
 | 
									SPA_MEMBER(sb->datas[i].data, inport->offset, void), &in_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));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	outio->status = SPA_STATUS_HAVE_BUFFER;
 | 
						inport->offset += in_len * sizeof(float);
 | 
				
			||||||
	outio->buffer_id = dbuf->outbuf->id;
 | 
						if (inport->offset >= size) {
 | 
				
			||||||
 | 
							inio->status = SPA_STATUS_NEED_BUFFER;
 | 
				
			||||||
	inio->status = SPA_STATUS_NEED_BUFFER;
 | 
							inport->offset = 0;
 | 
				
			||||||
 | 
							SPA_FLAG_SET(res, SPA_STATUS_NEED_BUFFER);
 | 
				
			||||||
	return outio->status;
 | 
						}
 | 
				
			||||||
 | 
						outport->offset += out_len * sizeof(float);
 | 
				
			||||||
 | 
						if (outport->offset >= maxsize) {
 | 
				
			||||||
 | 
							outio->status = SPA_STATUS_HAVE_BUFFER;
 | 
				
			||||||
 | 
							outio->buffer_id = dbuf->outbuf->id;
 | 
				
			||||||
 | 
							dequeue_buffer(this, dbuf);
 | 
				
			||||||
 | 
							outport->offset = 0;
 | 
				
			||||||
 | 
							SPA_FLAG_SET(res, SPA_STATUS_HAVE_BUFFER);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						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