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;
 | 
			
		||||
 | 
			
		||||
	struct spa_buffer *outbuf;
 | 
			
		||||
	struct spa_ringbuffer *rb;
 | 
			
		||||
 | 
			
		||||
	struct spa_meta_header *h;
 | 
			
		||||
	struct spa_meta_ringbuffer *rb;
 | 
			
		||||
 | 
			
		||||
	bool have_ringbuffer;
 | 
			
		||||
	struct spa_ringbuffer ringbuffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct port {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +63,6 @@ struct port {
 | 
			
		|||
	uint32_t n_buffers;
 | 
			
		||||
 | 
			
		||||
	struct spa_list queue;
 | 
			
		||||
	size_t queued_offset;
 | 
			
		||||
	size_t queued_bytes;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -581,12 +583,23 @@ impl_node_port_use_buffers(struct spa_node *node,
 | 
			
		|||
	for (i = 0; i < n_buffers; i++) {
 | 
			
		||||
		struct buffer *b;
 | 
			
		||||
		struct spa_data *d = buffers[i]->datas;
 | 
			
		||||
		struct spa_meta_ringbuffer *rb;
 | 
			
		||||
 | 
			
		||||
		b = &port->buffers[i];
 | 
			
		||||
		b->outbuf = buffers[i];
 | 
			
		||||
		b->outstanding = (direction == SPA_DIRECTION_INPUT);
 | 
			
		||||
		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 ||
 | 
			
		||||
		       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;
 | 
			
		||||
	struct buffer *b;
 | 
			
		||||
	struct spa_data *id;
 | 
			
		||||
	uint32_t index = 0, offset, len1, len2;
 | 
			
		||||
	mix_func_t mix = layer == 0 ? this->copy : this->add;
 | 
			
		||||
 | 
			
		||||
	b = spa_list_first(&port->queue, struct buffer, link);
 | 
			
		||||
 | 
			
		||||
	id = b->outbuf->datas;
 | 
			
		||||
	if (b->rb) {
 | 
			
		||||
		insize = spa_ringbuffer_get_read_index(&b->rb->ringbuffer, &index);
 | 
			
		||||
		outsize = SPA_MIN(outsize, insize);
 | 
			
		||||
	insize = spa_ringbuffer_get_read_index(b->rb, &index);
 | 
			
		||||
	outsize = SPA_MIN(outsize, insize);
 | 
			
		||||
 | 
			
		||||
		offset = index % b->rb->ringbuffer.size;
 | 
			
		||||
		if (offset + outsize > b->rb->ringbuffer.size)
 | 
			
		||||
			len1 = b->rb->ringbuffer.size - offset;
 | 
			
		||||
		else
 | 
			
		||||
			len1 = outsize;
 | 
			
		||||
	offset = index % b->rb->size;
 | 
			
		||||
	if (offset + outsize > b->rb->size) {
 | 
			
		||||
		len1 = b->rb->size - offset;
 | 
			
		||||
		len2 = outsize - len1;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		offset = port->queued_offset + id[0].chunk->offset;
 | 
			
		||||
		insize = id[0].chunk->size - offset;
 | 
			
		||||
		outsize = SPA_MIN(outsize, insize);
 | 
			
		||||
		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)
 | 
			
		||||
		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->ringbuffer, index + outsize);
 | 
			
		||||
	spa_ringbuffer_read_update(b->rb, index + 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",
 | 
			
		||||
			      this, b->outbuf->id, port, outsize);
 | 
			
		||||
		port->io->buffer_id = b->outbuf->id;
 | 
			
		||||
		spa_list_remove(&b->link);
 | 
			
		||||
		b->outstanding = true;
 | 
			
		||||
		port->queued_offset = 0;
 | 
			
		||||
		port->queued_bytes = 0;
 | 
			
		||||
	} else {
 | 
			
		||||
		spa_log_trace(this->log, NAME " %p: keeping buffer %d on port %p %zd %zd",
 | 
			
		||||
			      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 spa_port_io *outio;
 | 
			
		||||
	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);
 | 
			
		||||
	outio = outport->io;
 | 
			
		||||
| 
						 | 
				
			
			@ -751,23 +755,26 @@ static int mix_output(struct impl *this, size_t n_bytes)
 | 
			
		|||
 | 
			
		||||
	od = outbuf->outbuf->datas;
 | 
			
		||||
 | 
			
		||||
	if (outbuf->rb) {
 | 
			
		||||
		int32_t filled, avail;
 | 
			
		||||
		filled = spa_ringbuffer_get_write_index(&outbuf->rb->ringbuffer, &index);
 | 
			
		||||
		avail = outbuf->rb->ringbuffer.size - filled;
 | 
			
		||||
		offset = index % outbuf->rb->ringbuffer.size;
 | 
			
		||||
	if (!outbuf->have_ringbuffer) {
 | 
			
		||||
		outbuf->rb->readindex = outbuf->rb->writeindex = 0;
 | 
			
		||||
		od[0].chunk->offset = 0;
 | 
			
		||||
		od[0].chunk->size = n_bytes;
 | 
			
		||||
		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)
 | 
			
		||||
			len1 = outbuf->rb->ringbuffer.size - offset;
 | 
			
		||||
		else
 | 
			
		||||
			len1 = n_bytes;
 | 
			
		||||
	n_bytes = SPA_MIN(n_bytes, avail);
 | 
			
		||||
 | 
			
		||||
	if (offset + n_bytes > outbuf->rb->size) {
 | 
			
		||||
		len1 = outbuf->rb->size - offset;
 | 
			
		||||
		len2 = n_bytes - len1;
 | 
			
		||||
	} else {
 | 
			
		||||
		n_bytes = SPA_MIN(n_bytes, od[0].maxsize);
 | 
			
		||||
		offset = 0;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		len1 = n_bytes;
 | 
			
		||||
		len2 = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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)) {
 | 
			
		||||
			spa_log_warn(this->log, NAME " %p: underrun stream %d", this, i);
 | 
			
		||||
			in_port->queued_bytes = 0;
 | 
			
		||||
			in_port->queued_offset = 0;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		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);
 | 
			
		||||
		layer++;
 | 
			
		||||
	}
 | 
			
		||||
	if (outbuf->rb) {
 | 
			
		||||
		spa_ringbuffer_write_update(&outbuf->rb->ringbuffer, index + n_bytes);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		od[0].chunk->offset = 0;
 | 
			
		||||
		od[0].chunk->size = n_bytes;
 | 
			
		||||
		od[0].chunk->stride = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spa_ringbuffer_write_update(outbuf->rb, index + n_bytes);
 | 
			
		||||
 | 
			
		||||
	outio->buffer_id = outbuf->outbuf->id;
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
			if (b->rb)
 | 
			
		||||
				inport->queued_bytes += spa_ringbuffer_get_read_index(&b->rb->ringbuffer, &index);
 | 
			
		||||
			else
 | 
			
		||||
				inport->queued_bytes += b->outbuf->datas[0].chunk->size;
 | 
			
		||||
			if (!b->have_ringbuffer) {
 | 
			
		||||
				b->rb->readindex = 0;
 | 
			
		||||
				b->rb->writeindex = 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",
 | 
			
		||||
				      this, b->outbuf->id, i, inport->queued_bytes, min_queued);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue