From 9f1d84e37c1fd56b5386f309dc8cc95d29a06ffe Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 27 Sep 2020 17:07:29 +0200 Subject: [PATCH] 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 . --- spa/plugins/v4l2/v4l2-source.c | 6 ++++-- spa/plugins/v4l2/v4l2-utils.c | 29 ++++++++++------------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c index 036558189..87acb6f2d 100644 --- a/spa/plugins/v4l2/v4l2-source.c +++ b/spa/plugins/v4l2/v4l2-source.c @@ -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; diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index 5ec96896b..ed34c3ac5 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -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;