mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	spa: improve draining
Make a new DRAINED status. Place the DRAINED status on an input IO when a stream is out of buffers and draining. All nodes that don't have HAVE_DATA on the input io need to copy it to the output io and return the status. This makes sure the DRAINED is forwarded and nodes return DRAINED from _process() DRAINED on the resampler flushes out the last queued samples and then forwards the DRAINED in the next iteration. Emit a new drained signal from the context when a node returns DRAINED. Use this to trigger the drained signal in the stream.
This commit is contained in:
		
							parent
							
								
									029f431418
								
							
						
					
					
						commit
						b18dacde9a
					
				
					 10 changed files with 46 additions and 42 deletions
				
			
		| 
						 | 
				
			
			@ -865,7 +865,7 @@ impl_node_port_reuse_buffer(void *object, uint32_t port_id, uint32_t buffer_id)
 | 
			
		|||
static int impl_node_process(void *object)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this = object;
 | 
			
		||||
	int status;
 | 
			
		||||
	int status = 0;
 | 
			
		||||
 | 
			
		||||
	spa_log_trace_fp(this->log, "%p: process convert:%u master:%d",
 | 
			
		||||
			this, this->use_converter, this->master);
 | 
			
		||||
| 
						 | 
				
			
			@ -875,22 +875,17 @@ static int impl_node_process(void *object)
 | 
			
		|||
			status = spa_node_process(this->convert);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	status = spa_node_process(this->follower);
 | 
			
		||||
	if (status >= 0)
 | 
			
		||||
		status = spa_node_process(this->follower);
 | 
			
		||||
 | 
			
		||||
	if (this->direction == SPA_DIRECTION_OUTPUT &&
 | 
			
		||||
	    !this->master && this->use_converter) {
 | 
			
		||||
		while (true) {
 | 
			
		||||
		while (status >= 0) {
 | 
			
		||||
			status = spa_node_process(this->convert);
 | 
			
		||||
			if (status & SPA_STATUS_HAVE_DATA)
 | 
			
		||||
			if (status & (SPA_STATUS_HAVE_DATA | SPA_STATUS_DRAINED))
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			if (status & SPA_STATUS_NEED_DATA) {
 | 
			
		||||
			if (status & SPA_STATUS_NEED_DATA)
 | 
			
		||||
				status = spa_node_process(this->follower);
 | 
			
		||||
				if (!(status & SPA_STATUS_HAVE_DATA)) {
 | 
			
		||||
					spa_node_call_xrun(&this->callbacks, 0, 0, NULL);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	spa_log_trace_fp(this->log, "%p: process status:%d", this, status);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1084,7 +1084,7 @@ static int impl_node_process(void *object)
 | 
			
		|||
			if (SPA_UNLIKELY(i == 0))
 | 
			
		||||
				res |= r & SPA_STATUS_NEED_DATA;
 | 
			
		||||
			if (SPA_UNLIKELY(i == this->n_nodes-1))
 | 
			
		||||
				res |= r & SPA_STATUS_HAVE_DATA;
 | 
			
		||||
				res |= r & (SPA_STATUS_HAVE_DATA | SPA_STATUS_DRAINED);
 | 
			
		||||
		}
 | 
			
		||||
		if (res & SPA_STATUS_HAVE_DATA)
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -864,15 +864,13 @@ static int impl_node_process(void *object)
 | 
			
		|||
 | 
			
		||||
	if (SPA_UNLIKELY(outio->status == SPA_STATUS_HAVE_DATA))
 | 
			
		||||
		return SPA_STATUS_HAVE_DATA;
 | 
			
		||||
 | 
			
		||||
	if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
 | 
			
		||||
		return SPA_STATUS_NEED_DATA;
 | 
			
		||||
 | 
			
		||||
	/* recycle */
 | 
			
		||||
	if (SPA_LIKELY(outio->buffer_id < outport->n_buffers)) {
 | 
			
		||||
		recycle_buffer(this, outio->buffer_id);
 | 
			
		||||
		outio->buffer_id = SPA_ID_INVALID;
 | 
			
		||||
	}
 | 
			
		||||
	if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
 | 
			
		||||
		return outio->status = inio->status;
 | 
			
		||||
 | 
			
		||||
	if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers))
 | 
			
		||||
		return inio->status = -EINVAL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -844,7 +844,8 @@ static int impl_node_process(void *object)
 | 
			
		|||
		outio->buffer_id = SPA_ID_INVALID;
 | 
			
		||||
	}
 | 
			
		||||
	if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
 | 
			
		||||
		return SPA_STATUS_NEED_DATA;
 | 
			
		||||
		return outio->status = inio->status;
 | 
			
		||||
 | 
			
		||||
	if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers))
 | 
			
		||||
		return inio->status = -EINVAL;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,6 +118,7 @@ struct impl {
 | 
			
		|||
	int mode;
 | 
			
		||||
	unsigned int started:1;
 | 
			
		||||
	unsigned int peaks:1;
 | 
			
		||||
	unsigned int drained:1;
 | 
			
		||||
 | 
			
		||||
	struct resample resample;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -723,6 +724,7 @@ static int impl_node_process(void *object)
 | 
			
		|||
	void **dst_datas;
 | 
			
		||||
	bool flush_out = false;
 | 
			
		||||
	bool flush_in = false;
 | 
			
		||||
	bool draining = false;
 | 
			
		||||
 | 
			
		||||
	spa_return_val_if_fail(this != NULL, -EINVAL);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -741,15 +743,18 @@ static int impl_node_process(void *object)
 | 
			
		|||
 | 
			
		||||
	if (SPA_UNLIKELY(outio->status == SPA_STATUS_HAVE_DATA))
 | 
			
		||||
		return SPA_STATUS_HAVE_DATA;
 | 
			
		||||
 | 
			
		||||
	if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
 | 
			
		||||
		return SPA_STATUS_NEED_DATA;
 | 
			
		||||
 | 
			
		||||
	/* recycle */
 | 
			
		||||
	if (SPA_LIKELY(outio->buffer_id < outport->n_buffers)) {
 | 
			
		||||
		recycle_buffer(this, outio->buffer_id);
 | 
			
		||||
		outio->buffer_id = SPA_ID_INVALID;
 | 
			
		||||
	}
 | 
			
		||||
	if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA)) {
 | 
			
		||||
		if (inio->status != SPA_STATUS_DRAINED || this->drained)
 | 
			
		||||
			return outio->status = inio->status;
 | 
			
		||||
 | 
			
		||||
		inio->buffer_id = 0;
 | 
			
		||||
		inport->buffers[0].outbuf->datas[0].chunk->size = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers))
 | 
			
		||||
		return inio->status = -EINVAL;
 | 
			
		||||
| 
						 | 
				
			
			@ -784,7 +789,7 @@ static int impl_node_process(void *object)
 | 
			
		|||
		size = sb->datas[0].maxsize;
 | 
			
		||||
		memset(sb->datas[0].data, 0, size);
 | 
			
		||||
		inport->offset = 0;
 | 
			
		||||
		flush_in = true;
 | 
			
		||||
		flush_in = draining = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (this->io_rate_match) {
 | 
			
		||||
| 
						 | 
				
			
			@ -829,18 +834,19 @@ static int impl_node_process(void *object)
 | 
			
		|||
	if (inport->offset >= size || flush_in) {
 | 
			
		||||
		inio->status = SPA_STATUS_NEED_DATA;
 | 
			
		||||
		inport->offset = 0;
 | 
			
		||||
		SPA_FLAG_SET(res, SPA_STATUS_NEED_DATA);
 | 
			
		||||
		spa_log_trace_fp(this->log, NAME " %p: return input buffer", this);
 | 
			
		||||
		SPA_FLAG_SET(res, inio->status);
 | 
			
		||||
		spa_log_trace_fp(this->log, NAME " %p: return input buffer of size %d", this, size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	outport->offset += out_len * sizeof(float);
 | 
			
		||||
	if (outport->offset > 0 && (outport->offset >= maxsize || flush_out)) {
 | 
			
		||||
		outio->status = SPA_STATUS_HAVE_DATA;
 | 
			
		||||
		outio->buffer_id = dbuf->id;
 | 
			
		||||
		spa_log_trace_fp(this->log, NAME " %p: have output buffer of size %d", this, outport->offset);
 | 
			
		||||
		dequeue_buffer(this, dbuf);
 | 
			
		||||
		outport->offset = 0;
 | 
			
		||||
		this->drained = draining;
 | 
			
		||||
		SPA_FLAG_SET(res, SPA_STATUS_HAVE_DATA);
 | 
			
		||||
		spa_log_trace_fp(this->log, NAME " %p: have output buffer", this);
 | 
			
		||||
	}
 | 
			
		||||
	if (out_len == 0 && this->peaks) {
 | 
			
		||||
		outio->status = SPA_STATUS_HAVE_DATA;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -860,7 +860,7 @@ static int impl_node_process(void *object)
 | 
			
		|||
			inio, inio->status, inio->buffer_id);
 | 
			
		||||
 | 
			
		||||
	if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
 | 
			
		||||
		return SPA_STATUS_NEED_DATA;
 | 
			
		||||
		return inio->status;
 | 
			
		||||
 | 
			
		||||
	if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers))
 | 
			
		||||
		return inio->status = -EINVAL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue