v4l2: in alloc buffer, don't mmap, just pass the fd

If we can't use EXPBUF, just put the fd and mapoffset in the buffer
memory. This way we can pass the fd to the client and let it mmap .
This commit is contained in:
Wim Taymans 2020-09-27 17:07:29 +02:00
parent 59990ea049
commit 9f1d84e37c
2 changed files with 14 additions and 21 deletions

View file

@ -89,7 +89,8 @@ struct control {
struct port {
struct impl *impl;
bool export_buf;
bool alloc_buffers;
bool have_expbuf;
bool next_fmtdesc;
struct v4l2_fmtdesc fmtdesc;
@ -963,7 +964,8 @@ impl_init(const struct spa_handle_factory *factory,
port->info.params = port->params;
port->info.n_params = 6;
port->export_buf = true;
port->alloc_buffers = true;
port->have_expbuf = true;
port->have_query_ext_ctrl = true;
port->dev.log = this->log;
port->dev.fd = -1;

View file

@ -957,7 +957,7 @@ static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format,
port->fmt = fmt;
port->info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS | SPA_PORT_CHANGE_MASK_RATE;
port->info.flags = (port->export_buf ? SPA_PORT_FLAG_CAN_ALLOC_BUFFERS : 0) |
port->info.flags = (port->alloc_buffers ? SPA_PORT_FLAG_CAN_ALLOC_BUFFERS : 0) |
SPA_PORT_FLAG_LIVE |
SPA_PORT_FLAG_PHYSICAL |
SPA_PORT_FLAG_TERMINAL;
@ -1412,8 +1412,6 @@ mmap_init(struct impl *this,
this->props.device, reqbuf.count);
return -ENOMEM;
}
if (port->export_buf)
spa_log_debug(this->log, "v4l2: using EXPBUF");
for (i = 0; i < reqbuf.count; i++) {
struct buffer *b;
@ -1448,7 +1446,7 @@ mmap_init(struct impl *this,
d[0].chunk->stride = port->fmt.fmt.pix.bytesperline;
d[0].chunk->flags = 0;
if (port->export_buf) {
if (port->have_expbuf) {
struct v4l2_exportbuffer expbuf;
spa_zero(expbuf);
@ -1459,7 +1457,7 @@ mmap_init(struct impl *this,
if (errno == ENOTTY || errno == EINVAL) {
spa_log_debug(this->log, "v4l2: '%s' VIDIOC_EXPBUF not supported: %m",
this->props.device);
port->export_buf = false;
port->have_expbuf = false;
goto fallback;
}
spa_log_error(this->log, "v4l2: '%s' VIDIOC_EXPBUF: %m", this->props.device);
@ -1473,24 +1471,17 @@ mmap_init(struct impl *this,
spa_log_debug(this->log, "v4l2: EXPBUF fd:%d", expbuf.fd);
} else {
fallback:
d[0].type = SPA_DATA_MemPtr;
d[0].type = SPA_DATA_MemFd;
d[0].flags = SPA_DATA_FLAG_READABLE;
d[0].fd = -1;
d[0].data = mmap(NULL,
b->v4l2_buffer.length,
PROT_READ, MAP_SHARED,
dev->fd,
b->v4l2_buffer.m.offset);
if (d[0].data == MAP_FAILED) {
spa_log_error(this->log, "v4l2: '%s' mmap: %m", this->props.device);
return -errno;
}
b->ptr = d[0].data;
SPA_FLAG_SET(b->flags, BUFFER_FLAG_MAPPED);
spa_log_debug(this->log, "v4l2: mmap ptr:%p", d[0].data);
d[0].fd = dev->fd;
d[0].mapoffset = b->v4l2_buffer.m.offset;
spa_log_debug(this->log, "v4l2: mmap offset:%u", d[0].mapoffset);
}
spa_v4l2_buffer_recycle(this, i);
}
spa_log_info(this->log, "v4l2: have %u buffers using %s", reqbuf.count,
port->have_expbuf ? "EXPBUF" : "MMAP");
port->n_buffers = reqbuf.count;
return 0;