[libcamera-devel] [PATCH v4 05/32] v4l2: camera: Handle memory mapping of buffers directly

Laurent Pinchart laurent.pinchart at ideasonboard.com
Sun Jan 12 14:41:21 CET 2020


Hi Niklas,

Thank you for the patch.

On Sun, Jan 12, 2020 at 02:01:45AM +0100, Niklas Söderlund wrote:
> In the upcoming FrameBuffer API the memory mapping of buffers will be
> left to the user of the FrameBuffer objects. Prepare the V4L2
> compatibility layer to this upcoming change to ease conversion to the
> new API.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> * Changes since v3
> - Return FileDescriptor from getBufferFd()
> - Call fops().munmap() in V4L2CameraProxy::munmap()
> ---
>  src/v4l2/v4l2_camera.cpp         | 12 ++++++------
>  src/v4l2/v4l2_camera.h           |  5 +++--
>  src/v4l2/v4l2_camera_proxy.cpp   | 24 +++++++++++++++++++-----
>  src/v4l2/v4l2_camera_proxy.h     |  2 +-
>  src/v4l2/v4l2_compat_manager.cpp |  2 +-
>  5 files changed, 30 insertions(+), 15 deletions(-)
> 
> diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
> index 2a507b9bb8318025..07f05a31261c1b25 100644
> --- a/src/v4l2/v4l2_camera.cpp
> +++ b/src/v4l2/v4l2_camera.cpp
> @@ -121,12 +121,6 @@ int V4L2Camera::configure(StreamConfiguration *streamConfigOut,
>  	return 0;
>  }
>  
> -void *V4L2Camera::mmap(unsigned int index)
> -{
> -	Stream *stream = *camera_->streams().begin();
> -	return stream->buffers()[index].planes()[0].mem();
> -}
> -
>  int V4L2Camera::allocBuffers(unsigned int count)
>  {
>  	int ret = camera_->allocateBuffers();
> @@ -138,6 +132,12 @@ void V4L2Camera::freeBuffers()
>  	camera_->freeBuffers();
>  }
>  
> +FileDescriptor V4L2Camera::getBufferFd(unsigned int index)
> +{
> +	Stream *stream = *camera_->streams().begin();
> +	return FileDescriptor(stream->buffers()[index].planes()[0].dmabuf());
> +}
> +
>  int V4L2Camera::streamOn()
>  {
>  	if (isRunning_)
> diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h
> index 81f7908e5e8a6beb..f760316c854fba2f 100644
> --- a/src/v4l2/v4l2_camera.h
> +++ b/src/v4l2/v4l2_camera.h
> @@ -14,6 +14,7 @@
>  
>  #include <libcamera/buffer.h>
>  #include <libcamera/camera.h>
> +#include <libcamera/file_descriptor.h>
>  
>  #include "semaphore.h"
>  
> @@ -53,14 +54,14 @@ public:
>  	void getStreamConfig(StreamConfiguration *streamConfig);
>  	std::vector<V4L2FrameMetadata> completedBuffers();
>  
> -	void *mmap(unsigned int index);
> -
>  	int configure(StreamConfiguration *streamConfigOut,
>  		      const Size &size, PixelFormat pixelformat,
>  		      unsigned int bufferCount);
>  
>  	int allocBuffers(unsigned int count);
>  	void freeBuffers();
> +	FileDescriptor getBufferFd(unsigned int index);
> +
>  	int streamOn();
>  	int streamOff();
>  
> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> index 52f8468cdaa06a7a..b4a9e2107c0f9f28 100644
> --- a/src/v4l2/v4l2_camera_proxy.cpp
> +++ b/src/v4l2/v4l2_camera_proxy.cpp
> @@ -75,7 +75,8 @@ void V4L2CameraProxy::close()
>  	vcam_->invokeMethod(&V4L2Camera::close, ConnectionTypeBlocking);
>  }
>  
> -void *V4L2CameraProxy::mmap(size_t length, int prot, int flags, off_t offset)
> +void *V4L2CameraProxy::mmap(void *addr, size_t length, int prot, int flags,
> +			    off_t offset)
>  {
>  	LOG(V4L2Compat, Debug) << "Servicing mmap";
>  
> @@ -91,13 +92,22 @@ void *V4L2CameraProxy::mmap(size_t length, int prot, int flags, off_t offset)
>  		return MAP_FAILED;
>  	}
>  
> -	void *val = vcam_->invokeMethod(&V4L2Camera::mmap,
> -					ConnectionTypeBlocking, index);
> +	FileDescriptor fd = vcam_->invokeMethod(&V4L2Camera::getBufferFd,
> +						ConnectionTypeBlocking, index);
> +	if (!fd.isValid()) {
> +		errno = EINVAL;
> +		return MAP_FAILED;
> +	}
> +
> +	void *map = V4L2CompatManager::instance()->fops().mmap(addr, length, prot,
> +							       flags, fd.fd(), 0);
> +	if (map == MAP_FAILED)
> +		return map;
>  
>  	buffers_[index].flags |= V4L2_BUF_FLAG_MAPPED;
> -	mmaps_[val] = index;
> +	mmaps_[map] = index;
>  
> -	return val;
> +	return map;
>  }
>  
>  int V4L2CameraProxy::munmap(void *addr, size_t length)
> @@ -110,6 +120,10 @@ int V4L2CameraProxy::munmap(void *addr, size_t length)
>  		return -1;
>  	}
>  
> +	if (V4L2CompatManager::instance()->fops().munmap(addr, length))
> +		LOG(V4L2Compat, Error) << "Unmapping " << addr
> +				       << " with length " << length;

How about explicitly stating that this is a failure ?

		LOG(V4L2Compat, Error) << "Failed to unmap " << addr
				       << " with length " << length;

Apart from that, you can keep my R-b.

> +
>  	buffers_[iter->second].flags &= ~V4L2_BUF_FLAG_MAPPED;
>  	mmaps_.erase(iter);
>  
> diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> index b59d19d707590d88..c8e61adf80f1b93b 100644
> --- a/src/v4l2/v4l2_camera_proxy.h
> +++ b/src/v4l2/v4l2_camera_proxy.h
> @@ -28,7 +28,7 @@ public:
>  	int open(bool nonBlocking);
>  	void dup();
>  	void close();
> -	void *mmap(size_t length, int prot, int flags, off_t offset);
> +	void *mmap(void *addr, size_t length, int prot, int flags, off_t offset);
>  	int munmap(void *addr, size_t length);
>  
>  	int ioctl(unsigned long request, void *arg);
> diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp
> index fe453445a9fb2cdd..f5a7b2ac4229d5d5 100644
> --- a/src/v4l2/v4l2_compat_manager.cpp
> +++ b/src/v4l2/v4l2_compat_manager.cpp
> @@ -223,7 +223,7 @@ void *V4L2CompatManager::mmap(void *addr, size_t length, int prot, int flags,
>  	if (!proxy)
>  		return fops_.mmap(addr, length, prot, flags, fd, offset);
>  
> -	void *map = proxy->mmap(length, prot, flags, offset);
> +	void *map = proxy->mmap(addr, length, prot, flags, offset);
>  	if (map == MAP_FAILED)
>  		return map;
>  

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list