diff --git a/spa/include/spa/buffer/buffer.h b/spa/include/spa/buffer/buffer.h index 13ed8d175..8c02e9e08 100644 --- a/spa/include/spa/buffer/buffer.h +++ b/spa/include/spa/buffer/buffer.h @@ -65,6 +65,9 @@ struct spa_data { #define SPA_DATA_FLAG_WRITABLE (1u<<1) /**< data is writable */ #define SPA_DATA_FLAG_DYNAMIC (1u<<2) /**< data pointer can be changed */ #define SPA_DATA_FLAG_READWRITE (SPA_DATA_FLAG_READABLE|SPA_DATA_FLAG_WRITABLE) +#define SPA_DATA_FLAG_MAPPABLE (1u<<3) /**< data is mappable with simple mmap/munmap. Some memory + * types are not simply mappable (DmaBuf) unless explicitly + * specified with this flag. */ uint32_t flags; /**< data flags */ int64_t fd; /**< optional fd for data */ uint32_t mapoffset; /**< offset to map fd at */ diff --git a/spa/plugins/libcamera/libcamera-utils.cpp b/spa/plugins/libcamera/libcamera-utils.cpp index c197248d3..4604f0000 100644 --- a/spa/plugins/libcamera/libcamera-utils.cpp +++ b/spa/plugins/libcamera/libcamera-utils.cpp @@ -805,6 +805,7 @@ mmap_init(struct impl *impl, struct port *port, if (port->memtype == SPA_DATA_DmaBuf || port->memtype == SPA_DATA_MemFd) { + d[j].flags |= SPA_DATA_FLAG_MAPPABLE; d[j].fd = bufs[i]->planes()[j].fd.get(); spa_log_debug(impl->log, "Got fd = %ld for buffer: #%d", d[j].fd, i); d[j].data = NULL; diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index 1ed46d62c..56ab07144 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -1652,7 +1652,7 @@ again: d[0].type = SPA_DATA_DmaBuf; else d[0].type = SPA_DATA_MemFd; - d[0].flags = SPA_DATA_FLAG_READABLE; + d[0].flags = SPA_DATA_FLAG_READABLE | SPA_DATA_FLAG_MAPPABLE; d[0].fd = expbuf.fd; d[0].data = NULL; SPA_FLAG_SET(b->flags, BUFFER_FLAG_ALLOCATED); diff --git a/src/pipewire/filter.h b/src/pipewire/filter.h index bb5081b70..b0ea4a2ac 100644 --- a/src/pipewire/filter.h +++ b/src/pipewire/filter.h @@ -120,7 +120,8 @@ enum pw_filter_flags { enum pw_filter_port_flags { PW_FILTER_PORT_FLAG_NONE = 0, /**< no flags */ - PW_FILTER_PORT_FLAG_MAP_BUFFERS = (1 << 0), /**< mmap the buffers except DmaBuf */ + PW_FILTER_PORT_FLAG_MAP_BUFFERS = (1 << 0), /**< mmap the buffers except DmaBuf that is not + * explicitly marked as mappable. */ PW_FILTER_PORT_FLAG_ALLOC_BUFFERS = (1 << 1), /**< the application will allocate buffer * memory. In the add_buffer event, the * data of the buffer should be set */ diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 51f6d2f06..696375b89 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -979,7 +979,8 @@ static int impl_port_use_buffers(void *object, if (SPA_FLAG_IS_SET(impl_flags, PW_STREAM_FLAG_MAP_BUFFERS)) { for (j = 0; j < buffers[i]->n_datas; j++) { struct spa_data *d = &buffers[i]->datas[j]; - if ((mappable_dataTypes & (1<type)) > 0) { + if (SPA_FLAG_IS_SET(d->flags, SPA_DATA_FLAG_MAPPABLE) || + (mappable_dataTypes & (1<type)) > 0) { if ((res = map_data(impl, d, prot)) < 0) return res; SPA_FLAG_SET(b->flags, BUFFER_FLAG_MAPPED); diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h index bea90b458..dd172d74e 100644 --- a/src/pipewire/stream.h +++ b/src/pipewire/stream.h @@ -371,7 +371,8 @@ enum pw_stream_flags { PW_STREAM_FLAG_INACTIVE = (1 << 1), /**< start the stream inactive, * pw_stream_set_active() needs to be * called explicitly */ - PW_STREAM_FLAG_MAP_BUFFERS = (1 << 2), /**< mmap the buffers except DmaBuf */ + PW_STREAM_FLAG_MAP_BUFFERS = (1 << 2), /**< mmap the buffers except DmaBuf that is not + * explicitly marked as mappable. */ PW_STREAM_FLAG_DRIVER = (1 << 3), /**< be a driver */ PW_STREAM_FLAG_RT_PROCESS = (1 << 4), /**< call process from the realtime * thread. You MUST use RT safe functions