mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	v4l2: probe EXPBUF and disable alloc_buffer flag
After we set the format, probe if we can do EXPBUF and enable/disable the ALLOC_BUFFERS flag on the port. This should gracefully handle the case where EXPBUF is not available. Fixes #3821
This commit is contained in:
		
							parent
							
								
									18b112bcfe
								
							
						
					
					
						commit
						c690aedc89
					
				
					 2 changed files with 46 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -71,6 +71,7 @@ struct port {
 | 
			
		|||
	struct impl *impl;
 | 
			
		||||
 | 
			
		||||
	bool alloc_buffers;
 | 
			
		||||
	bool probed_expbuf;
 | 
			
		||||
	bool have_expbuf;
 | 
			
		||||
 | 
			
		||||
	bool next_fmtdesc;
 | 
			
		||||
| 
						 | 
				
			
			@ -1020,8 +1021,7 @@ impl_init(const struct spa_handle_factory *factory,
 | 
			
		|||
	port->info.params = port->params;
 | 
			
		||||
	port->info.n_params = N_PORT_PARAMS;
 | 
			
		||||
 | 
			
		||||
	port->alloc_buffers = true;
 | 
			
		||||
	port->have_expbuf = true;
 | 
			
		||||
	port->probed_expbuf = false;
 | 
			
		||||
	port->have_query_ext_ctrl = true;
 | 
			
		||||
	port->dev.log = this->log;
 | 
			
		||||
	port->dev.fd = -1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -867,6 +867,48 @@ do_enum_fmt:
 | 
			
		|||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int probe_expbuf(struct impl *this)
 | 
			
		||||
{
 | 
			
		||||
	struct port *port = &this->out_ports[0];
 | 
			
		||||
	struct spa_v4l2_device *dev = &port->dev;
 | 
			
		||||
	struct v4l2_requestbuffers reqbuf;
 | 
			
		||||
	struct v4l2_exportbuffer expbuf;
 | 
			
		||||
 | 
			
		||||
	if (port->probed_expbuf)
 | 
			
		||||
		return 0;
 | 
			
		||||
	port->probed_expbuf = true;
 | 
			
		||||
 | 
			
		||||
	spa_zero(reqbuf);
 | 
			
		||||
	reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 | 
			
		||||
	reqbuf.memory = V4L2_MEMORY_MMAP;
 | 
			
		||||
	reqbuf.count = 2;
 | 
			
		||||
 | 
			
		||||
	if (xioctl(dev->fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
 | 
			
		||||
		spa_log_error(this->log, "'%s' VIDIOC_REQBUFS: %m", this->props.device);
 | 
			
		||||
		return -errno;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	spa_zero(expbuf);
 | 
			
		||||
	expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 | 
			
		||||
	expbuf.index = 0;
 | 
			
		||||
	expbuf.flags = O_CLOEXEC | O_RDONLY;
 | 
			
		||||
	if (xioctl(dev->fd, VIDIOC_EXPBUF, &expbuf) < 0) {
 | 
			
		||||
		spa_log_info(this->log, "'%s' EXPBUF not supported: %m", this->props.device);
 | 
			
		||||
		port->have_expbuf = false;
 | 
			
		||||
		port->alloc_buffers = false;
 | 
			
		||||
	} else {
 | 
			
		||||
		port->have_expbuf = true;
 | 
			
		||||
		port->alloc_buffers = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reqbuf.count = 0;
 | 
			
		||||
	if (xioctl(dev->fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
 | 
			
		||||
		spa_log_error(this->log, "'%s' VIDIOC_REQBUFS: %m", this->props.device);
 | 
			
		||||
		return -errno;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format, uint32_t flags)
 | 
			
		||||
{
 | 
			
		||||
	struct port *port = &this->out_ports[0];
 | 
			
		||||
| 
						 | 
				
			
			@ -973,6 +1015,8 @@ static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format,
 | 
			
		|||
	port->rate.denom = framerate->num = streamparm.parm.capture.timeperframe.denominator;
 | 
			
		||||
	port->rate.num = framerate->denom = streamparm.parm.capture.timeperframe.numerator;
 | 
			
		||||
 | 
			
		||||
	probe_expbuf(this);
 | 
			
		||||
 | 
			
		||||
	port->fmt = fmt;
 | 
			
		||||
	port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_RATE;
 | 
			
		||||
	port->info.flags = (port->alloc_buffers ? SPA_PORT_FLAG_CAN_ALLOC_BUFFERS : 0) |
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue