[libcamera-devel,v4] v4l2: V4L2CameraProxy: Add EXPBUF as one of the supported ioctl
diff mbox series

Message ID 20211228185014.98895-1-vedantparanjape160201@gmail.com
State Accepted
Commit d769a595666bc4054fa59b9d13881a38497ea6ec
Headers show
Series
  • [libcamera-devel,v4] v4l2: V4L2CameraProxy: Add EXPBUF as one of the supported ioctl
Related show

Commit Message

Vedant Paranjape Dec. 28, 2021, 6:50 p.m. UTC
To support DMABUF as one of the memory buffer, we need to implement
EXPBUF in the v4l2 compat layer.

This patch implements vidioc_expbuf as one of the supported ioctls.

Bug: https://bugs.libcamera.org/show_bug.cgi?id=89

Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>
---
 src/v4l2/v4l2_camera_proxy.cpp | 30 ++++++++++++++++++++++++++++++
 src/v4l2/v4l2_camera_proxy.h   |  1 +
 2 files changed, 31 insertions(+)

Comments

Laurent Pinchart Dec. 29, 2021, 10:36 p.m. UTC | #1
Hi Vedant,

Thank you for the patch.

On Wed, Dec 29, 2021 at 12:20:14AM +0530, Vedant Paranjape wrote:
> To support DMABUF as one of the memory buffer, we need to implement
> EXPBUF in the v4l2 compat layer.
> 
> This patch implements vidioc_expbuf as one of the supported ioctls.
> 
> Bug: https://bugs.libcamera.org/show_bug.cgi?id=89
> 
> Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>

This looks fine. As soon as you can test it with v4l2-ctl and capture
images, I think it can be merged.

I've sent a patch for v4l2-ctl (which has been merged in the master
branch already) that should help with testing.

> ---
>  src/v4l2/v4l2_camera_proxy.cpp | 30 ++++++++++++++++++++++++++++++
>  src/v4l2/v4l2_camera_proxy.h   |  1 +
>  2 files changed, 31 insertions(+)
> 
> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> index c1375777c185..4d529bc29a4d 100644
> --- a/src/v4l2/v4l2_camera_proxy.cpp
> +++ b/src/v4l2/v4l2_camera_proxy.cpp
> @@ -624,6 +624,32 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
>  	return 0;
>  }
>  
> +int V4L2CameraProxy::vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg)
> +{
> +	LOG(V4L2Compat, Debug) << "Servicing vidioc_expbuf fd = " << file->efd();
> +
> +	if (!hasOwnership(file))
> +		return -EBUSY;
> +
> +	/* \todo Verify that the memory type is MMAP when adding DMABUF support */
> +	if (!validateBufferType(arg->type))
> +		return -EINVAL;
> +
> +	if (arg->index >= bufferCount_)
> +		return -EINVAL;
> +
> +	if (arg->flags & ~(O_CLOEXEC | O_ACCMODE))
> +		return -EINVAL;
> +
> +	memset(arg->reserved, 0, sizeof(arg->reserved));
> +
> +	/* \todo honor the O_ACCMODE flags passed to this function */
> +	arg->fd = fcntl(vcam_->getBufferFd(arg->index),
> +			arg->flags & O_CLOEXEC ? F_DUPFD_CLOEXEC : F_DUPFD, 0);
> +
> +	return 0;
> +}
> +
>  int V4L2CameraProxy::vidioc_streamon(V4L2CameraFile *file, int *arg)
>  {
>  	LOG(V4L2Compat, Debug) << "Servicing vidioc_streamon fd = " << file->efd();
> @@ -685,6 +711,7 @@ const std::set<unsigned long> V4L2CameraProxy::supportedIoctls_ = {
>  	VIDIOC_QUERYBUF,
>  	VIDIOC_QBUF,
>  	VIDIOC_DQBUF,
> +	VIDIOC_EXPBUF,
>  	VIDIOC_STREAMON,
>  	VIDIOC_STREAMOFF,
>  };
> @@ -755,6 +782,9 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *ar
>  	case VIDIOC_DQBUF:
>  		ret = vidioc_dqbuf(file, static_cast<struct v4l2_buffer *>(arg), &proxyMutex_);
>  		break;
> +	case VIDIOC_EXPBUF:
> +		ret = vidioc_expbuf(file, static_cast<struct v4l2_exportbuffer *>(arg));
> +		break;
>  	case VIDIOC_STREAMON:
>  		ret = vidioc_streamon(file, static_cast<int *>(arg));
>  		break;
> diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> index fa0a49e0439b..14e027c3e7d1 100644
> --- a/src/v4l2/v4l2_camera_proxy.h
> +++ b/src/v4l2/v4l2_camera_proxy.h
> @@ -60,6 +60,7 @@ private:
>  	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);
> +	int vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg);
>  	int vidioc_streamon(V4L2CameraFile *file, int *arg);
>  	int vidioc_streamoff(V4L2CameraFile *file, int *arg);
>
Vedant Paranjape Dec. 30, 2021, 3:58 a.m. UTC | #2
Hi Laurent,
Thanks for the v4l2-ctl patch. I'll test it soon and reply in this thread.

Regards,
Vedant Paranjape

On Thu, 30 Dec, 2021, 04:06 Laurent Pinchart, <
laurent.pinchart@ideasonboard.com> wrote:

> Hi Vedant,
>
> Thank you for the patch.
>
> On Wed, Dec 29, 2021 at 12:20:14AM +0530, Vedant Paranjape wrote:
> > To support DMABUF as one of the memory buffer, we need to implement
> > EXPBUF in the v4l2 compat layer.
> >
> > This patch implements vidioc_expbuf as one of the supported ioctls.
> >
> > Bug: https://bugs.libcamera.org/show_bug.cgi?id=89
> >
> > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>
>
> This looks fine. As soon as you can test it with v4l2-ctl and capture
> images, I think it can be merged.
>
> I've sent a patch for v4l2-ctl (which has been merged in the master
> branch already) that should help with testing.
>
> > ---
> >  src/v4l2/v4l2_camera_proxy.cpp | 30 ++++++++++++++++++++++++++++++
> >  src/v4l2/v4l2_camera_proxy.h   |  1 +
> >  2 files changed, 31 insertions(+)
> >
> > diff --git a/src/v4l2/v4l2_camera_proxy.cpp
> b/src/v4l2/v4l2_camera_proxy.cpp
> > index c1375777c185..4d529bc29a4d 100644
> > --- a/src/v4l2/v4l2_camera_proxy.cpp
> > +++ b/src/v4l2/v4l2_camera_proxy.cpp
> > @@ -624,6 +624,32 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile
> *file, struct v4l2_buffer *arg,
> >       return 0;
> >  }
> >
> > +int V4L2CameraProxy::vidioc_expbuf(V4L2CameraFile *file, struct
> v4l2_exportbuffer *arg)
> > +{
> > +     LOG(V4L2Compat, Debug) << "Servicing vidioc_expbuf fd = " <<
> file->efd();
> > +
> > +     if (!hasOwnership(file))
> > +             return -EBUSY;
> > +
> > +     /* \todo Verify that the memory type is MMAP when adding DMABUF
> support */
> > +     if (!validateBufferType(arg->type))
> > +             return -EINVAL;
> > +
> > +     if (arg->index >= bufferCount_)
> > +             return -EINVAL;
> > +
> > +     if (arg->flags & ~(O_CLOEXEC | O_ACCMODE))
> > +             return -EINVAL;
> > +
> > +     memset(arg->reserved, 0, sizeof(arg->reserved));
> > +
> > +     /* \todo honor the O_ACCMODE flags passed to this function */
> > +     arg->fd = fcntl(vcam_->getBufferFd(arg->index),
> > +                     arg->flags & O_CLOEXEC ? F_DUPFD_CLOEXEC :
> F_DUPFD, 0);
> > +
> > +     return 0;
> > +}
> > +
> >  int V4L2CameraProxy::vidioc_streamon(V4L2CameraFile *file, int *arg)
> >  {
> >       LOG(V4L2Compat, Debug) << "Servicing vidioc_streamon fd = " <<
> file->efd();
> > @@ -685,6 +711,7 @@ const std::set<unsigned long>
> V4L2CameraProxy::supportedIoctls_ = {
> >       VIDIOC_QUERYBUF,
> >       VIDIOC_QBUF,
> >       VIDIOC_DQBUF,
> > +     VIDIOC_EXPBUF,
> >       VIDIOC_STREAMON,
> >       VIDIOC_STREAMOFF,
> >  };
> > @@ -755,6 +782,9 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file,
> unsigned long request, void *ar
> >       case VIDIOC_DQBUF:
> >               ret = vidioc_dqbuf(file, static_cast<struct v4l2_buffer
> *>(arg), &proxyMutex_);
> >               break;
> > +     case VIDIOC_EXPBUF:
> > +             ret = vidioc_expbuf(file, static_cast<struct
> v4l2_exportbuffer *>(arg));
> > +             break;
> >       case VIDIOC_STREAMON:
> >               ret = vidioc_streamon(file, static_cast<int *>(arg));
> >               break;
> > diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> > index fa0a49e0439b..14e027c3e7d1 100644
> > --- a/src/v4l2/v4l2_camera_proxy.h
> > +++ b/src/v4l2/v4l2_camera_proxy.h
> > @@ -60,6 +60,7 @@ private:
> >       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);
> > +     int vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer
> *arg);
> >       int vidioc_streamon(V4L2CameraFile *file, int *arg);
> >       int vidioc_streamoff(V4L2CameraFile *file, int *arg);
> >
>
> --
> Regards,
>
> Laurent Pinchart
>
Vedant Paranjape Jan. 7, 2022, 9:40 p.m. UTC | #3
Hello Laurent,
I have been able to get v4l2-ctl working to stream using dmabuf, here
are the steps I followed:

1) Apply the patch in the trailing email (v4) on the latest branch of libcamera
2) Clone master of v4l-utils and apply this patch
https://patchwork.kernel.org/project/linux-media/patch/20220104130708.166638-1-vedantparanjape160201@gmail.com/
3) Compile v4l-utils
4) give alias v4l2-ctl-edge=<PATH OF COMPILED V4l2-ctl>
5) run the following command in libcamera root directory:
     LD_PRELOAD=./build/src/v4l2/v4l2-compat.so v4l2-ctl-edge -d0
--set-fmt-video=pixelformat='YUYV' --stream-mmap --out-device
/dev/video3 --stream-out-dmabuf --get-fmt-video --get-fmt-video-out

I have attached the output of lsv4l2 here as well:

video0: HD WebCam: HD WebCam
video1: HD WebCam: HD WebCam
video2: vivid-000-vid-cap
video3: vivid-000-vid-out

Here's the terminal output: https://paste.debian.net/1226342/

Regards,
Vedant Paranjape

On Thu, Dec 30, 2021 at 4:06 AM Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
>
> Hi Vedant,
>
> Thank you for the patch.
>
> On Wed, Dec 29, 2021 at 12:20:14AM +0530, Vedant Paranjape wrote:
> > To support DMABUF as one of the memory buffer, we need to implement
> > EXPBUF in the v4l2 compat layer.
> >
> > This patch implements vidioc_expbuf as one of the supported ioctls.
> >
> > Bug: https://bugs.libcamera.org/show_bug.cgi?id=89
> >
> > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>
>
> This looks fine. As soon as you can test it with v4l2-ctl and capture
> images, I think it can be merged.
>
> I've sent a patch for v4l2-ctl (which has been merged in the master
> branch already) that should help with testing.
>
> > ---
> >  src/v4l2/v4l2_camera_proxy.cpp | 30 ++++++++++++++++++++++++++++++
> >  src/v4l2/v4l2_camera_proxy.h   |  1 +
> >  2 files changed, 31 insertions(+)
> >
> > diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> > index c1375777c185..4d529bc29a4d 100644
> > --- a/src/v4l2/v4l2_camera_proxy.cpp
> > +++ b/src/v4l2/v4l2_camera_proxy.cpp
> > @@ -624,6 +624,32 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
> >       return 0;
> >  }
> >
> > +int V4L2CameraProxy::vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg)
> > +{
> > +     LOG(V4L2Compat, Debug) << "Servicing vidioc_expbuf fd = " << file->efd();
> > +
> > +     if (!hasOwnership(file))
> > +             return -EBUSY;
> > +
> > +     /* \todo Verify that the memory type is MMAP when adding DMABUF support */
> > +     if (!validateBufferType(arg->type))
> > +             return -EINVAL;
> > +
> > +     if (arg->index >= bufferCount_)
> > +             return -EINVAL;
> > +
> > +     if (arg->flags & ~(O_CLOEXEC | O_ACCMODE))
> > +             return -EINVAL;
> > +
> > +     memset(arg->reserved, 0, sizeof(arg->reserved));
> > +
> > +     /* \todo honor the O_ACCMODE flags passed to this function */
> > +     arg->fd = fcntl(vcam_->getBufferFd(arg->index),
> > +                     arg->flags & O_CLOEXEC ? F_DUPFD_CLOEXEC : F_DUPFD, 0);
> > +
> > +     return 0;
> > +}
> > +
> >  int V4L2CameraProxy::vidioc_streamon(V4L2CameraFile *file, int *arg)
> >  {
> >       LOG(V4L2Compat, Debug) << "Servicing vidioc_streamon fd = " << file->efd();
> > @@ -685,6 +711,7 @@ const std::set<unsigned long> V4L2CameraProxy::supportedIoctls_ = {
> >       VIDIOC_QUERYBUF,
> >       VIDIOC_QBUF,
> >       VIDIOC_DQBUF,
> > +     VIDIOC_EXPBUF,
> >       VIDIOC_STREAMON,
> >       VIDIOC_STREAMOFF,
> >  };
> > @@ -755,6 +782,9 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *ar
> >       case VIDIOC_DQBUF:
> >               ret = vidioc_dqbuf(file, static_cast<struct v4l2_buffer *>(arg), &proxyMutex_);
> >               break;
> > +     case VIDIOC_EXPBUF:
> > +             ret = vidioc_expbuf(file, static_cast<struct v4l2_exportbuffer *>(arg));
> > +             break;
> >       case VIDIOC_STREAMON:
> >               ret = vidioc_streamon(file, static_cast<int *>(arg));
> >               break;
> > diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> > index fa0a49e0439b..14e027c3e7d1 100644
> > --- a/src/v4l2/v4l2_camera_proxy.h
> > +++ b/src/v4l2/v4l2_camera_proxy.h
> > @@ -60,6 +60,7 @@ private:
> >       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);
> > +     int vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg);
> >       int vidioc_streamon(V4L2CameraFile *file, int *arg);
> >       int vidioc_streamoff(V4L2CameraFile *file, int *arg);
> >
>
> --
> Regards,
>
> Laurent Pinchart
Laurent Pinchart Jan. 8, 2022, 1:52 p.m. UTC | #4
Hi Vedant,

On Sat, Jan 08, 2022 at 03:10:15AM +0530, Vedant Paranjape wrote:
> Hello Laurent,
> I have been able to get v4l2-ctl working to stream using dmabuf, here
> are the steps I followed:
> 
> 1) Apply the patch in the trailing email (v4) on the latest branch of libcamera
> 2) Clone master of v4l-utils and apply this patch
> https://patchwork.kernel.org/project/linux-media/patch/20220104130708.166638-1-vedantparanjape160201@gmail.com/
> 3) Compile v4l-utils
> 4) give alias v4l2-ctl-edge=<PATH OF COMPILED V4l2-ctl>
> 5) run the following command in libcamera root directory:
>      LD_PRELOAD=./build/src/v4l2/v4l2-compat.so v4l2-ctl-edge -d0
> --set-fmt-video=pixelformat='YUYV' --stream-mmap --out-device
> /dev/video3 --stream-out-dmabuf --get-fmt-video --get-fmt-video-out

You can drop the last two arguments.

While this show that the EXPBUF implementation works, in a real use case
you would still potentially have different formats on the capture and
output side, which would lead to garbled output. You should specify the
format and resolution explicitly on both the capture and output side.

I'll merge the patch.

> I have attached the output of lsv4l2 here as well:
> 
> video0: HD WebCam: HD WebCam
> video1: HD WebCam: HD WebCam
> video2: vivid-000-vid-cap
> video3: vivid-000-vid-out
> 
> Here's the terminal output: https://paste.debian.net/1226342/
> 
> Regards,
> Vedant Paranjape
> 
> On Thu, Dec 30, 2021 at 4:06 AM Laurent Pinchart wrote:
> > On Wed, Dec 29, 2021 at 12:20:14AM +0530, Vedant Paranjape wrote:
> > > To support DMABUF as one of the memory buffer, we need to implement
> > > EXPBUF in the v4l2 compat layer.
> > >
> > > This patch implements vidioc_expbuf as one of the supported ioctls.
> > >
> > > Bug: https://bugs.libcamera.org/show_bug.cgi?id=89
> > >
> > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>
> >
> > This looks fine. As soon as you can test it with v4l2-ctl and capture
> > images, I think it can be merged.
> >
> > I've sent a patch for v4l2-ctl (which has been merged in the master
> > branch already) that should help with testing.
> >
> > > ---
> > >  src/v4l2/v4l2_camera_proxy.cpp | 30 ++++++++++++++++++++++++++++++
> > >  src/v4l2/v4l2_camera_proxy.h   |  1 +
> > >  2 files changed, 31 insertions(+)
> > >
> > > diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> > > index c1375777c185..4d529bc29a4d 100644
> > > --- a/src/v4l2/v4l2_camera_proxy.cpp
> > > +++ b/src/v4l2/v4l2_camera_proxy.cpp
> > > @@ -624,6 +624,32 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
> > >       return 0;
> > >  }
> > >
> > > +int V4L2CameraProxy::vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg)
> > > +{
> > > +     LOG(V4L2Compat, Debug) << "Servicing vidioc_expbuf fd = " << file->efd();
> > > +
> > > +     if (!hasOwnership(file))
> > > +             return -EBUSY;
> > > +
> > > +     /* \todo Verify that the memory type is MMAP when adding DMABUF support */
> > > +     if (!validateBufferType(arg->type))
> > > +             return -EINVAL;
> > > +
> > > +     if (arg->index >= bufferCount_)
> > > +             return -EINVAL;
> > > +
> > > +     if (arg->flags & ~(O_CLOEXEC | O_ACCMODE))
> > > +             return -EINVAL;
> > > +
> > > +     memset(arg->reserved, 0, sizeof(arg->reserved));
> > > +
> > > +     /* \todo honor the O_ACCMODE flags passed to this function */
> > > +     arg->fd = fcntl(vcam_->getBufferFd(arg->index),
> > > +                     arg->flags & O_CLOEXEC ? F_DUPFD_CLOEXEC : F_DUPFD, 0);
> > > +
> > > +     return 0;
> > > +}
> > > +
> > >  int V4L2CameraProxy::vidioc_streamon(V4L2CameraFile *file, int *arg)
> > >  {
> > >       LOG(V4L2Compat, Debug) << "Servicing vidioc_streamon fd = " << file->efd();
> > > @@ -685,6 +711,7 @@ const std::set<unsigned long> V4L2CameraProxy::supportedIoctls_ = {
> > >       VIDIOC_QUERYBUF,
> > >       VIDIOC_QBUF,
> > >       VIDIOC_DQBUF,
> > > +     VIDIOC_EXPBUF,
> > >       VIDIOC_STREAMON,
> > >       VIDIOC_STREAMOFF,
> > >  };
> > > @@ -755,6 +782,9 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *ar
> > >       case VIDIOC_DQBUF:
> > >               ret = vidioc_dqbuf(file, static_cast<struct v4l2_buffer *>(arg), &proxyMutex_);
> > >               break;
> > > +     case VIDIOC_EXPBUF:
> > > +             ret = vidioc_expbuf(file, static_cast<struct v4l2_exportbuffer *>(arg));
> > > +             break;
> > >       case VIDIOC_STREAMON:
> > >               ret = vidioc_streamon(file, static_cast<int *>(arg));
> > >               break;
> > > diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> > > index fa0a49e0439b..14e027c3e7d1 100644
> > > --- a/src/v4l2/v4l2_camera_proxy.h
> > > +++ b/src/v4l2/v4l2_camera_proxy.h
> > > @@ -60,6 +60,7 @@ private:
> > >       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);
> > > +     int vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg);
> > >       int vidioc_streamon(V4L2CameraFile *file, int *arg);
> > >       int vidioc_streamoff(V4L2CameraFile *file, int *arg);
> > >
Vedant Paranjape Jan. 8, 2022, 2:04 p.m. UTC | #5
Hi Laurent,

On Sat, 8 Jan, 2022, 19:22 Laurent Pinchart, <
laurent.pinchart@ideasonboard.com> wrote:

> Hi Vedant,
>
> On Sat, Jan 08, 2022 at 03:10:15AM +0530, Vedant Paranjape wrote:
> > Hello Laurent,
> > I have been able to get v4l2-ctl working to stream using dmabuf, here
> > are the steps I followed:
> >
> > 1) Apply the patch in the trailing email (v4) on the latest branch of
> libcamera
> > 2) Clone master of v4l-utils and apply this patch
> >
> https://patchwork.kernel.org/project/linux-media/patch/20220104130708.166638-1-vedantparanjape160201@gmail.com/
> > 3) Compile v4l-utils
> > 4) give alias v4l2-ctl-edge=<PATH OF COMPILED V4l2-ctl>
> > 5) run the following command in libcamera root directory:
> >      LD_PRELOAD=./build/src/v4l2/v4l2-compat.so v4l2-ctl-edge -d0
> > --set-fmt-video=pixelformat='YUYV' --stream-mmap --out-device
> > /dev/video3 --stream-out-dmabuf --get-fmt-video --get-fmt-video-out
>
> You can drop the last two arguments.
>
> While this show that the EXPBUF implementation works, in a real use case
> you would still potentially have different formats on the capture and
> output side, which would lead to garbled output. You should specify the
> format and resolution explicitly on both the capture and output side.
>

Makes sense, I'll keep this in mind.

I'll merge the patch.
>
> > I have attached the output of lsv4l2 here as well:
> >
> > video0: HD WebCam: HD WebCam
> > video1: HD WebCam: HD WebCam
> > video2: vivid-000-vid-cap
> > video3: vivid-000-vid-out
> >
> > Here's the terminal output: https://paste.debian.net/1226342/
> >
> > Regards,
> > Vedant Paranjape
> >
> > On Thu, Dec 30, 2021 at 4:06 AM Laurent Pinchart wrote:
> > > On Wed, Dec 29, 2021 at 12:20:14AM +0530, Vedant Paranjape wrote:
> > > > To support DMABUF as one of the memory buffer, we need to implement
> > > > EXPBUF in the v4l2 compat layer.
> > > >
> > > > This patch implements vidioc_expbuf as one of the supported ioctls.
> > > >
> > > > Bug: https://bugs.libcamera.org/show_bug.cgi?id=89
> > > >
> > > > Signed-off-by: Vedant Paranjape <vedantparanjape160201@gmail.com>
> > >
> > > This looks fine. As soon as you can test it with v4l2-ctl and capture
> > > images, I think it can be merged.
> > >
> > > I've sent a patch for v4l2-ctl (which has been merged in the master
> > > branch already) that should help with testing.
> > >
> > > > ---
> > > >  src/v4l2/v4l2_camera_proxy.cpp | 30 ++++++++++++++++++++++++++++++
> > > >  src/v4l2/v4l2_camera_proxy.h   |  1 +
> > > >  2 files changed, 31 insertions(+)
> > > >
> > > > diff --git a/src/v4l2/v4l2_camera_proxy.cpp
> b/src/v4l2/v4l2_camera_proxy.cpp
> > > > index c1375777c185..4d529bc29a4d 100644
> > > > --- a/src/v4l2/v4l2_camera_proxy.cpp
> > > > +++ b/src/v4l2/v4l2_camera_proxy.cpp
> > > > @@ -624,6 +624,32 @@ int
> V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
> > > >       return 0;
> > > >  }
> > > >
> > > > +int V4L2CameraProxy::vidioc_expbuf(V4L2CameraFile *file, struct
> v4l2_exportbuffer *arg)
> > > > +{
> > > > +     LOG(V4L2Compat, Debug) << "Servicing vidioc_expbuf fd = " <<
> file->efd();
> > > > +
> > > > +     if (!hasOwnership(file))
> > > > +             return -EBUSY;
> > > > +
> > > > +     /* \todo Verify that the memory type is MMAP when adding
> DMABUF support */
> > > > +     if (!validateBufferType(arg->type))
> > > > +             return -EINVAL;
> > > > +
> > > > +     if (arg->index >= bufferCount_)
> > > > +             return -EINVAL;
> > > > +
> > > > +     if (arg->flags & ~(O_CLOEXEC | O_ACCMODE))
> > > > +             return -EINVAL;
> > > > +
> > > > +     memset(arg->reserved, 0, sizeof(arg->reserved));
> > > > +
> > > > +     /* \todo honor the O_ACCMODE flags passed to this function */
> > > > +     arg->fd = fcntl(vcam_->getBufferFd(arg->index),
> > > > +                     arg->flags & O_CLOEXEC ? F_DUPFD_CLOEXEC :
> F_DUPFD, 0);
> > > > +
> > > > +     return 0;
> > > > +}
> > > > +
> > > >  int V4L2CameraProxy::vidioc_streamon(V4L2CameraFile *file, int *arg)
> > > >  {
> > > >       LOG(V4L2Compat, Debug) << "Servicing vidioc_streamon fd = " <<
> file->efd();
> > > > @@ -685,6 +711,7 @@ const std::set<unsigned long>
> V4L2CameraProxy::supportedIoctls_ = {
> > > >       VIDIOC_QUERYBUF,
> > > >       VIDIOC_QBUF,
> > > >       VIDIOC_DQBUF,
> > > > +     VIDIOC_EXPBUF,
> > > >       VIDIOC_STREAMON,
> > > >       VIDIOC_STREAMOFF,
> > > >  };
> > > > @@ -755,6 +782,9 @@ int V4L2CameraProxy::ioctl(V4L2CameraFile *file,
> unsigned long request, void *ar
> > > >       case VIDIOC_DQBUF:
> > > >               ret = vidioc_dqbuf(file, static_cast<struct
> v4l2_buffer *>(arg), &proxyMutex_);
> > > >               break;
> > > > +     case VIDIOC_EXPBUF:
> > > > +             ret = vidioc_expbuf(file, static_cast<struct
> v4l2_exportbuffer *>(arg));
> > > > +             break;
> > > >       case VIDIOC_STREAMON:
> > > >               ret = vidioc_streamon(file, static_cast<int *>(arg));
> > > >               break;
> > > > diff --git a/src/v4l2/v4l2_camera_proxy.h
> b/src/v4l2/v4l2_camera_proxy.h
> > > > index fa0a49e0439b..14e027c3e7d1 100644
> > > > --- a/src/v4l2/v4l2_camera_proxy.h
> > > > +++ b/src/v4l2/v4l2_camera_proxy.h
> > > > @@ -60,6 +60,7 @@ private:
> > > >       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);
> > > > +     int vidioc_expbuf(V4L2CameraFile *file, struct
> v4l2_exportbuffer *arg);
> > > >       int vidioc_streamon(V4L2CameraFile *file, int *arg);
> > > >       int vidioc_streamoff(V4L2CameraFile *file, int *arg);
> > > >
>
> --
> Regards,
>
> Laurent Pinchart


>
Regards,
Vedant Paranjape

Patch
diff mbox series

diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index c1375777c185..4d529bc29a4d 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -624,6 +624,32 @@  int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
 	return 0;
 }
 
+int V4L2CameraProxy::vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg)
+{
+	LOG(V4L2Compat, Debug) << "Servicing vidioc_expbuf fd = " << file->efd();
+
+	if (!hasOwnership(file))
+		return -EBUSY;
+
+	/* \todo Verify that the memory type is MMAP when adding DMABUF support */
+	if (!validateBufferType(arg->type))
+		return -EINVAL;
+
+	if (arg->index >= bufferCount_)
+		return -EINVAL;
+
+	if (arg->flags & ~(O_CLOEXEC | O_ACCMODE))
+		return -EINVAL;
+
+	memset(arg->reserved, 0, sizeof(arg->reserved));
+
+	/* \todo honor the O_ACCMODE flags passed to this function */
+	arg->fd = fcntl(vcam_->getBufferFd(arg->index),
+			arg->flags & O_CLOEXEC ? F_DUPFD_CLOEXEC : F_DUPFD, 0);
+
+	return 0;
+}
+
 int V4L2CameraProxy::vidioc_streamon(V4L2CameraFile *file, int *arg)
 {
 	LOG(V4L2Compat, Debug) << "Servicing vidioc_streamon fd = " << file->efd();
@@ -685,6 +711,7 @@  const std::set<unsigned long> V4L2CameraProxy::supportedIoctls_ = {
 	VIDIOC_QUERYBUF,
 	VIDIOC_QBUF,
 	VIDIOC_DQBUF,
+	VIDIOC_EXPBUF,
 	VIDIOC_STREAMON,
 	VIDIOC_STREAMOFF,
 };
@@ -755,6 +782,9 @@  int V4L2CameraProxy::ioctl(V4L2CameraFile *file, unsigned long request, void *ar
 	case VIDIOC_DQBUF:
 		ret = vidioc_dqbuf(file, static_cast<struct v4l2_buffer *>(arg), &proxyMutex_);
 		break;
+	case VIDIOC_EXPBUF:
+		ret = vidioc_expbuf(file, static_cast<struct v4l2_exportbuffer *>(arg));
+		break;
 	case VIDIOC_STREAMON:
 		ret = vidioc_streamon(file, static_cast<int *>(arg));
 		break;
diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
index fa0a49e0439b..14e027c3e7d1 100644
--- a/src/v4l2/v4l2_camera_proxy.h
+++ b/src/v4l2/v4l2_camera_proxy.h
@@ -60,6 +60,7 @@  private:
 	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);
+	int vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffer *arg);
 	int vidioc_streamon(V4L2CameraFile *file, int *arg);
 	int vidioc_streamoff(V4L2CameraFile *file, int *arg);