From b5225f00cde0f84437349955050c27d89a76e550 Mon Sep 17 00:00:00 2001 From: Vedant Paranjape Date: Wed, 19 Jan 2022 11:25:12 +0530 Subject: v4l2: V4L2CameraProxy: Add support for PREPARE_BUF as one of the supported ioctl Add support for PREPARE_BUF as one of the ioctl. Since this is a compat layer, there doesn't seem to be an equivalent to the "transfer ownership of the buffer to kernel driver" in V4L2Camera class. Thus, simply duplicate the checks done by vidioc_qbuf. To match the error checks done by kernel implementation, we'd have to check if dmabuf fd is valid and that the buffer size is large enough. Doing so will not add any particular value to the program as applications most likely don't depend on these conditions being handled correctly. Signed-off-by: Vedant Paranjape Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder Signed-off-by: Laurent Pinchart --- src/v4l2/v4l2_camera_proxy.cpp | 35 ++++++++++++++++++++++++++++++++++- src/v4l2/v4l2_camera_proxy.h | 1 + 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index ec6daac6..f3470a6d 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -559,6 +559,38 @@ int V4L2CameraProxy::vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *a return 0; } +int V4L2CameraProxy::vidioc_prepare_buf(V4L2CameraFile *file, struct v4l2_buffer *arg) +{ + LOG(V4L2Compat, Debug) + << "[" << file->description() << "] " << __func__ + << "(index=" << arg->index << ")"; + + if (!hasOwnership(file)) + return -EBUSY; + + if (arg->index >= bufferCount_) + return -EINVAL; + + if (arg->flags & V4L2_BUF_FLAG_REQUEST_FD) + return -EINVAL; + + if (!validateBufferType(arg->type) || + !validateMemoryType(arg->memory)) + return -EINVAL; + + struct v4l2_buffer &buffer = buffers_[arg->index]; + + if (buffer.flags & V4L2_BUF_FLAG_QUEUED || + buffer.flags & V4L2_BUF_FLAG_PREPARED) + return -EINVAL; + + buffer.flags |= V4L2_BUF_FLAG_PREPARED; + + arg->flags = buffer.flags; + + return 0; +} + int V4L2CameraProxy::vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg) { LOG(V4L2Compat, Debug) @@ -627,7 +659,7 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg, struct v4l2_buffer &buf = buffers_[currentBuf_]; - buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE); + buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_PREPARED); buf.length = sizeimage_; *arg = buf; @@ -729,6 +761,7 @@ const std::set V4L2CameraProxy::supportedIoctls_ = { VIDIOC_S_INPUT, VIDIOC_REQBUFS, VIDIOC_QUERYBUF, + VIDIOC_PREPARE_BUF, VIDIOC_QBUF, VIDIOC_DQBUF, VIDIOC_EXPBUF, diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h index a38b28c7..76ca2d8a 100644 --- a/src/v4l2/v4l2_camera_proxy.h +++ b/src/v4l2/v4l2_camera_proxy.h @@ -58,6 +58,7 @@ private: int vidioc_s_input(V4L2CameraFile *file, int *arg); int vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuffers *arg); int vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *arg); + int vidioc_prepare_buf(V4L2CameraFile *file, struct v4l2_buffer *arg); int vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg); int vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg, libcamera::Mutex *lock) LIBCAMERA_TSA_REQUIRES(*lock); -- cgit v1.2.1