mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	v4l2: fix buffer recycle
Only set the OUTSTANDING flag when we placed the buffer in an io area and need to recycle it later. When we captured a frame, put it in the queue. Then dequeue it into the io area after recycling buffers. Fixes #217
This commit is contained in:
		
							parent
							
								
									441fdb2333
								
							
						
					
					
						commit
						a9b191971c
					
				
					 2 changed files with 23 additions and 15 deletions
				
			
		| 
						 | 
				
			
			@ -859,6 +859,7 @@ static int impl_node_process(void *object)
 | 
			
		|||
 | 
			
		||||
	b = spa_list_first(&port->queue, struct buffer, link);
 | 
			
		||||
	spa_list_remove(&b->link);
 | 
			
		||||
	SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUTSTANDING);
 | 
			
		||||
 | 
			
		||||
	spa_log_trace(this->log, NAME " %p: dequeue buffer %d", this, b->id);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1165,7 +1165,6 @@ static int mmap_read(struct impl *this)
 | 
			
		|||
{
 | 
			
		||||
	struct port *port = &this->out_ports[0];
 | 
			
		||||
	struct spa_v4l2_device *dev = &port->dev;
 | 
			
		||||
	struct spa_io_buffers *io;
 | 
			
		||||
	struct v4l2_buffer buf;
 | 
			
		||||
	struct buffer *b;
 | 
			
		||||
	struct spa_data *d;
 | 
			
		||||
| 
						 | 
				
			
			@ -1210,26 +1209,16 @@ static int mmap_read(struct impl *this)
 | 
			
		|||
	if (buf.flags & V4L2_BUF_FLAG_ERROR)
 | 
			
		||||
		d[0].flags |= SPA_CHUNK_FLAG_CORRUPTED;
 | 
			
		||||
 | 
			
		||||
	SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUTSTANDING);
 | 
			
		||||
 | 
			
		||||
	io = port->io;
 | 
			
		||||
	if (io != NULL && io->status != SPA_STATUS_HAVE_DATA) {
 | 
			
		||||
		io->buffer_id = b->id;
 | 
			
		||||
		io->status = SPA_STATUS_HAVE_DATA;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	spa_list_append(&port->queue, &b->link);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spa_log_trace(this->log, "v4l2 %p: now queued %d", this, b->id);
 | 
			
		||||
	spa_node_call_ready(&this->callbacks, SPA_STATUS_HAVE_DATA);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void v4l2_on_fd_events(struct spa_source *source)
 | 
			
		||||
{
 | 
			
		||||
	struct impl *this = source->data;
 | 
			
		||||
	struct spa_io_buffers *io;
 | 
			
		||||
	struct port *port = &this->out_ports[0];
 | 
			
		||||
	struct buffer *b;
 | 
			
		||||
 | 
			
		||||
	if (source->rmask & SPA_IO_ERR) {
 | 
			
		||||
		struct port *port = &this->out_ports[0];
 | 
			
		||||
| 
						 | 
				
			
			@ -1246,6 +1235,24 @@ static void v4l2_on_fd_events(struct spa_source *source)
 | 
			
		|||
 | 
			
		||||
	if (mmap_read(this) < 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (spa_list_is_empty(&port->queue))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	io = port->io;
 | 
			
		||||
	if (io != NULL && io->status != SPA_STATUS_HAVE_DATA) {
 | 
			
		||||
		if (io->buffer_id < port->n_buffers)
 | 
			
		||||
			spa_v4l2_buffer_recycle(this, io->buffer_id);
 | 
			
		||||
 | 
			
		||||
		b = spa_list_first(&port->queue, struct buffer, link);
 | 
			
		||||
		spa_list_remove(&b->link);
 | 
			
		||||
		SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUTSTANDING);
 | 
			
		||||
 | 
			
		||||
		io->buffer_id = b->id;
 | 
			
		||||
		io->status = SPA_STATUS_HAVE_DATA;
 | 
			
		||||
		spa_log_trace(this->log, "v4l2 %p: now queued %d", this, b->id);
 | 
			
		||||
	}
 | 
			
		||||
	spa_node_call_ready(&this->callbacks, SPA_STATUS_HAVE_DATA);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int spa_v4l2_use_buffers(struct impl *this, struct spa_buffer **buffers, uint32_t n_buffers)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue