mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	audiomixer: simplify code
Pretend there are ringbuffers on input and output buffers and simulate them otherwise to make some code paths simpler.
This commit is contained in:
		
							parent
							
								
									e303485757
								
							
						
					
					
						commit
						3f020cd350
					
				
					 1 changed files with 52 additions and 51 deletions
				
			
		| 
						 | 
					@ -42,9 +42,12 @@ struct buffer {
 | 
				
			||||||
	bool outstanding;
 | 
						bool outstanding;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_buffer *outbuf;
 | 
						struct spa_buffer *outbuf;
 | 
				
			||||||
 | 
						struct spa_ringbuffer *rb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_meta_header *h;
 | 
						struct spa_meta_header *h;
 | 
				
			||||||
	struct spa_meta_ringbuffer *rb;
 | 
					
 | 
				
			||||||
 | 
						bool have_ringbuffer;
 | 
				
			||||||
 | 
						struct spa_ringbuffer ringbuffer;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct port {
 | 
					struct port {
 | 
				
			||||||
| 
						 | 
					@ -60,7 +63,6 @@ struct port {
 | 
				
			||||||
	uint32_t n_buffers;
 | 
						uint32_t n_buffers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_list queue;
 | 
						struct spa_list queue;
 | 
				
			||||||
	size_t queued_offset;
 | 
					 | 
				
			||||||
	size_t queued_bytes;
 | 
						size_t queued_bytes;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -581,12 +583,23 @@ impl_node_port_use_buffers(struct spa_node *node,
 | 
				
			||||||
	for (i = 0; i < n_buffers; i++) {
 | 
						for (i = 0; i < n_buffers; i++) {
 | 
				
			||||||
		struct buffer *b;
 | 
							struct buffer *b;
 | 
				
			||||||
		struct spa_data *d = buffers[i]->datas;
 | 
							struct spa_data *d = buffers[i]->datas;
 | 
				
			||||||
 | 
							struct spa_meta_ringbuffer *rb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		b = &port->buffers[i];
 | 
							b = &port->buffers[i];
 | 
				
			||||||
		b->outbuf = buffers[i];
 | 
							b->outbuf = buffers[i];
 | 
				
			||||||
		b->outstanding = (direction == SPA_DIRECTION_INPUT);
 | 
							b->outstanding = (direction == SPA_DIRECTION_INPUT);
 | 
				
			||||||
		b->h = spa_buffer_find_meta(buffers[i], t->meta.Header);
 | 
							b->h = spa_buffer_find_meta(buffers[i], t->meta.Header);
 | 
				
			||||||
		b->rb = spa_buffer_find_meta(buffers[i], t->meta.Ringbuffer);
 | 
					
 | 
				
			||||||
 | 
							if ((rb = spa_buffer_find_meta(buffers[i], t->meta.Ringbuffer))) {
 | 
				
			||||||
 | 
								b->rb = &rb->ringbuffer;
 | 
				
			||||||
 | 
								b->have_ringbuffer = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								b->rb = &b->ringbuffer;
 | 
				
			||||||
 | 
								b->rb->size = d[0].maxsize;
 | 
				
			||||||
 | 
								b->rb->mask = d[0].maxsize - 1;
 | 
				
			||||||
 | 
								b->have_ringbuffer = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!((d[0].type == t->data.MemPtr ||
 | 
							if (!((d[0].type == t->data.MemPtr ||
 | 
				
			||||||
		       d[0].type == t->data.MemFd ||
 | 
							       d[0].type == t->data.MemFd ||
 | 
				
			||||||
| 
						 | 
					@ -681,52 +694,42 @@ add_port_data(struct impl *this, void *out, size_t outsize, size_t next, struct
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t insize;
 | 
						size_t insize;
 | 
				
			||||||
	struct buffer *b;
 | 
						struct buffer *b;
 | 
				
			||||||
	struct spa_data *id;
 | 
					 | 
				
			||||||
	uint32_t index = 0, offset, len1, len2;
 | 
						uint32_t index = 0, offset, len1, len2;
 | 
				
			||||||
	mix_func_t mix = layer == 0 ? this->copy : this->add;
 | 
						mix_func_t mix = layer == 0 ? this->copy : this->add;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b = spa_list_first(&port->queue, struct buffer, link);
 | 
						b = spa_list_first(&port->queue, struct buffer, link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	id = b->outbuf->datas;
 | 
						insize = spa_ringbuffer_get_read_index(b->rb, &index);
 | 
				
			||||||
	if (b->rb) {
 | 
						outsize = SPA_MIN(outsize, insize);
 | 
				
			||||||
		insize = spa_ringbuffer_get_read_index(&b->rb->ringbuffer, &index);
 | 
					 | 
				
			||||||
		outsize = SPA_MIN(outsize, insize);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		offset = index % b->rb->ringbuffer.size;
 | 
						offset = index % b->rb->size;
 | 
				
			||||||
		if (offset + outsize > b->rb->ringbuffer.size)
 | 
						if (offset + outsize > b->rb->size) {
 | 
				
			||||||
			len1 = b->rb->ringbuffer.size - offset;
 | 
							len1 = b->rb->size - offset;
 | 
				
			||||||
		else
 | 
							len2 = outsize - len1;
 | 
				
			||||||
			len1 = outsize;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		offset = port->queued_offset + id[0].chunk->offset;
 | 
					 | 
				
			||||||
		insize = id[0].chunk->size - offset;
 | 
					 | 
				
			||||||
		outsize = SPA_MIN(outsize, insize);
 | 
					 | 
				
			||||||
		len1 = outsize;
 | 
							len1 = outsize;
 | 
				
			||||||
 | 
							len2 = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	len2 = outsize - len1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mix(out, SPA_MEMBER(id[0].data, offset, void), len1);
 | 
						mix(out, SPA_MEMBER(b->outbuf->datas[0].data, offset, void), len1);
 | 
				
			||||||
	if (len2 > 0)
 | 
						if (len2 > 0)
 | 
				
			||||||
		mix(out + len1, id[0].data, len2);
 | 
							mix(out + len1, b->outbuf->datas[0].data, len2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (b->rb)
 | 
						spa_ringbuffer_read_update(b->rb, index + outsize);
 | 
				
			||||||
		spa_ringbuffer_read_update(&b->rb->ringbuffer, index + outsize);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	port->queued_bytes -= outsize;
 | 
						port->queued_bytes -= outsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (outsize == insize || (b->rb && next == 0)) {
 | 
						if (outsize == insize || (b->have_ringbuffer && next == 0)) {
 | 
				
			||||||
		spa_log_trace(this->log, NAME " %p: return buffer %d on port %p %zd",
 | 
							spa_log_trace(this->log, NAME " %p: return buffer %d on port %p %zd",
 | 
				
			||||||
			      this, b->outbuf->id, port, outsize);
 | 
								      this, b->outbuf->id, port, outsize);
 | 
				
			||||||
		port->io->buffer_id = b->outbuf->id;
 | 
							port->io->buffer_id = b->outbuf->id;
 | 
				
			||||||
		spa_list_remove(&b->link);
 | 
							spa_list_remove(&b->link);
 | 
				
			||||||
		b->outstanding = true;
 | 
							b->outstanding = true;
 | 
				
			||||||
		port->queued_offset = 0;
 | 
					 | 
				
			||||||
		port->queued_bytes = 0;
 | 
							port->queued_bytes = 0;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		spa_log_trace(this->log, NAME " %p: keeping buffer %d on port %p %zd %zd",
 | 
							spa_log_trace(this->log, NAME " %p: keeping buffer %d on port %p %zd %zd",
 | 
				
			||||||
			      this, b->outbuf->id, port, port->queued_bytes, outsize);
 | 
								      this, b->outbuf->id, port, port->queued_bytes, outsize);
 | 
				
			||||||
		port->queued_offset += outsize;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -737,7 +740,8 @@ static int mix_output(struct impl *this, size_t n_bytes)
 | 
				
			||||||
	struct port *outport;
 | 
						struct port *outport;
 | 
				
			||||||
	struct spa_port_io *outio;
 | 
						struct spa_port_io *outio;
 | 
				
			||||||
	struct spa_data *od;
 | 
						struct spa_data *od;
 | 
				
			||||||
	uint32_t index = 0, len1, len2 = 0, offset;
 | 
						int32_t filled, avail;
 | 
				
			||||||
 | 
						uint32_t index = 0, len1, len2, offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	outport = GET_OUT_PORT(this, 0);
 | 
						outport = GET_OUT_PORT(this, 0);
 | 
				
			||||||
	outio = outport->io;
 | 
						outio = outport->io;
 | 
				
			||||||
| 
						 | 
					@ -751,23 +755,26 @@ static int mix_output(struct impl *this, size_t n_bytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	od = outbuf->outbuf->datas;
 | 
						od = outbuf->outbuf->datas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (outbuf->rb) {
 | 
						if (!outbuf->have_ringbuffer) {
 | 
				
			||||||
		int32_t filled, avail;
 | 
							outbuf->rb->readindex = outbuf->rb->writeindex = 0;
 | 
				
			||||||
		filled = spa_ringbuffer_get_write_index(&outbuf->rb->ringbuffer, &index);
 | 
							od[0].chunk->offset = 0;
 | 
				
			||||||
		avail = outbuf->rb->ringbuffer.size - filled;
 | 
							od[0].chunk->size = n_bytes;
 | 
				
			||||||
		offset = index % outbuf->rb->ringbuffer.size;
 | 
							od[0].chunk->stride = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		n_bytes = SPA_MIN(n_bytes, avail);
 | 
						filled = spa_ringbuffer_get_write_index(outbuf->rb, &index);
 | 
				
			||||||
 | 
						avail = outbuf->rb->size - filled;
 | 
				
			||||||
 | 
						offset = index % outbuf->rb->size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (offset + n_bytes > outbuf->rb->ringbuffer.size)
 | 
						n_bytes = SPA_MIN(n_bytes, avail);
 | 
				
			||||||
			len1 = outbuf->rb->ringbuffer.size - offset;
 | 
					
 | 
				
			||||||
		else
 | 
						if (offset + n_bytes > outbuf->rb->size) {
 | 
				
			||||||
			len1 = n_bytes;
 | 
							len1 = outbuf->rb->size - offset;
 | 
				
			||||||
		len2 = n_bytes - len1;
 | 
							len2 = n_bytes - len1;
 | 
				
			||||||
	} else {
 | 
						}
 | 
				
			||||||
		n_bytes = SPA_MIN(n_bytes, od[0].maxsize);
 | 
						else {
 | 
				
			||||||
		offset = 0;
 | 
					 | 
				
			||||||
		len1 = n_bytes;
 | 
							len1 = n_bytes;
 | 
				
			||||||
 | 
							len2 = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_trace(this->log, NAME " %p: dequeue output buffer %d %zd %d %d %d",
 | 
						spa_log_trace(this->log, NAME " %p: dequeue output buffer %d %zd %d %d %d",
 | 
				
			||||||
| 
						 | 
					@ -782,7 +789,6 @@ static int mix_output(struct impl *this, size_t n_bytes)
 | 
				
			||||||
		if (spa_list_is_empty(&in_port->queue)) {
 | 
							if (spa_list_is_empty(&in_port->queue)) {
 | 
				
			||||||
			spa_log_warn(this->log, NAME " %p: underrun stream %d", this, i);
 | 
								spa_log_warn(this->log, NAME " %p: underrun stream %d", this, i);
 | 
				
			||||||
			in_port->queued_bytes = 0;
 | 
								in_port->queued_bytes = 0;
 | 
				
			||||||
			in_port->queued_offset = 0;
 | 
					 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		add_port_data(this, SPA_MEMBER(od[0].data, offset, void), len1, len2, in_port, layer);
 | 
							add_port_data(this, SPA_MEMBER(od[0].data, offset, void), len1, len2, in_port, layer);
 | 
				
			||||||
| 
						 | 
					@ -790,14 +796,8 @@ static int mix_output(struct impl *this, size_t n_bytes)
 | 
				
			||||||
			add_port_data(this, od[0].data, len2, 0, in_port, layer);
 | 
								add_port_data(this, od[0].data, len2, 0, in_port, layer);
 | 
				
			||||||
		layer++;
 | 
							layer++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (outbuf->rb) {
 | 
					
 | 
				
			||||||
		spa_ringbuffer_write_update(&outbuf->rb->ringbuffer, index + n_bytes);
 | 
						spa_ringbuffer_write_update(outbuf->rb, index + n_bytes);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else {
 | 
					 | 
				
			||||||
		od[0].chunk->offset = 0;
 | 
					 | 
				
			||||||
		od[0].chunk->size = n_bytes;
 | 
					 | 
				
			||||||
		od[0].chunk->stride = 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	outio->buffer_id = outbuf->outbuf->id;
 | 
						outio->buffer_id = outbuf->outbuf->id;
 | 
				
			||||||
	outio->status = SPA_RESULT_HAVE_BUFFER;
 | 
						outio->status = SPA_RESULT_HAVE_BUFFER;
 | 
				
			||||||
| 
						 | 
					@ -849,10 +849,11 @@ static int impl_node_process_input(struct spa_node *node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			spa_list_append(&inport->queue, &b->link);
 | 
								spa_list_append(&inport->queue, &b->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (b->rb)
 | 
								if (!b->have_ringbuffer) {
 | 
				
			||||||
				inport->queued_bytes += spa_ringbuffer_get_read_index(&b->rb->ringbuffer, &index);
 | 
									b->rb->readindex = 0;
 | 
				
			||||||
			else
 | 
									b->rb->writeindex = b->outbuf->datas[0].chunk->size;
 | 
				
			||||||
				inport->queued_bytes += b->outbuf->datas[0].chunk->size;
 | 
								}
 | 
				
			||||||
 | 
								inport->queued_bytes += spa_ringbuffer_get_read_index(b->rb, &index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			spa_log_trace(this->log, NAME " %p: queue buffer %d on port %d %zd %zd",
 | 
								spa_log_trace(this->log, NAME " %p: queue buffer %d on port %d %zd %zd",
 | 
				
			||||||
				      this, b->outbuf->id, i, inport->queued_bytes, min_queued);
 | 
									      this, b->outbuf->id, i, inport->queued_bytes, min_queued);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue