[libcamera-devel] [PATCH v3 05/33] v4l2: camera: Handle memory mapping of buffers directly
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Sat Jan 11 00:27:45 CET 2020
Hi Niklas,
Thank you for the patch.
On Fri, Jan 10, 2020 at 08:37:40PM +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>
> ---
> src/v4l2/v4l2_camera.cpp | 12 ++++++------
> src/v4l2/v4l2_camera.h | 4 ++--
> src/v4l2/v4l2_camera_proxy.cpp | 20 +++++++++++++++-----
> src/v4l2/v4l2_camera_proxy.h | 2 +-
> src/v4l2/v4l2_compat_manager.cpp | 2 +-
> 5 files changed, 25 insertions(+), 15 deletions(-)
>
> diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
> index 2a507b9bb8318025..ba3783876101b284 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();
> }
>
> +int V4L2Camera::getBufferFd(unsigned int index)
How about returning a FileDescriptor instance, especially given that
further in the series you will get a FileDescriptor from FrameBuffer.
> +{
> + Stream *stream = *camera_->streams().begin();
> + return 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..afa20a232235e778 100644
> --- a/src/v4l2/v4l2_camera.h
> +++ b/src/v4l2/v4l2_camera.h
> @@ -53,14 +53,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();
> + int 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..3c8eba6b29be4811 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);
> + int fd = vcam_->invokeMethod(&V4L2Camera::getBufferFd,
> + ConnectionTypeBlocking, index);
> + if (fd < 0) {
> + errno = -fd;
> + return MAP_FAILED;
> + }
> +
> + void *map = V4L2CompatManager::instance()->fops().mmap(addr, length, prot,
> + flags, 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)
We also need to patch munmap() to call fops().munmap(). This should be
fairly trivial as V4L2CompatManager::munmap() doesn't allow partial
unmapping, so we don't need to care about that. You just need to call
fops().munmap() in V4L2CameraProxy::munmap() without real error handling
(but logging an Error message would be useful).
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> 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