[libcamera-devel,05/15] v4l2: v4l2_camera_proxy: Implement VIDIOC_ENUMINPUT, VIDIOC_G/S_INPUT

Message ID 20200616131244.70308-6-paul.elder@ideasonboard.com
State Superseded
Headers show
Series
  • Support v4l2-compliance
Related show

Commit Message

Paul Elder June 16, 2020, 1:12 p.m. UTC
Implement VIDIOC_ENUMINPUT, VIDIOC_G_INPUT, and VIDIOC_S_INPUT. Only the
zeroth input device is supported, and the info returned by enuminput is
hardcoded and basic. This is sufficient to pass v4l2-compliance.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
---
 src/v4l2/v4l2_camera_proxy.cpp | 54 ++++++++++++++++++++++++++++++++++
 src/v4l2/v4l2_camera_proxy.h   |  3 ++
 2 files changed, 57 insertions(+)

Comments

Jacopo Mondi June 17, 2020, 1:15 p.m. UTC | #1
Hi Paul,

On Tue, Jun 16, 2020 at 10:12:34PM +0900, Paul Elder wrote:
> Implement VIDIOC_ENUMINPUT, VIDIOC_G_INPUT, and VIDIOC_S_INPUT. Only the
> zeroth input device is supported, and the info returned by enuminput is
> hardcoded and basic. This is sufficient to pass v4l2-compliance.

I don't think we'll have much other usages for this IOCTLs apart from
this one :)

>
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> ---
>  src/v4l2/v4l2_camera_proxy.cpp | 54 ++++++++++++++++++++++++++++++++++
>  src/v4l2/v4l2_camera_proxy.h   |  3 ++
>  2 files changed, 57 insertions(+)
>
> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> index f268f7a..6c0dacc 100644
> --- a/src/v4l2/v4l2_camera_proxy.cpp
> +++ b/src/v4l2/v4l2_camera_proxy.cpp
> @@ -397,6 +397,51 @@ int V4L2CameraProxy::vidioc_s_priority(int fd, enum v4l2_priority *arg)
>  	return 0;
>  }
>
> +int V4L2CameraProxy::vidioc_enuminput(int fd, struct v4l2_input *arg)
> +{
> +	LOG(V4L2Compat, Debug) << "Servicing vidioc_enuminput fd = " << fd;
> +
> +	if (arg == nullptr)
> +		return -EFAULT;

This repeated patter makes me think we should probably centralize this
check as suggested by Laurent on a previous patch

> +
> +	if (arg->index != 0)
> +		return -EINVAL;
> +
> +	memset(arg, 0, sizeof(*arg));
> +
> +	utils::strlcpy(reinterpret_cast<char *>(arg->name),
> +		       reinterpret_cast<char *>(capabilities_.card),
> +		       sizeof(arg->name));
> +	arg->type = V4L2_INPUT_TYPE_CAMERA;
> +
> +	return 0;
> +}
> +
> +int V4L2CameraProxy::vidioc_g_input(int fd, int *arg)
> +{
> +	LOG(V4L2Compat, Debug) << "Servicing vidioc_g_input fd = " << fd;
> +
> +	if (arg == nullptr)
> +		return -EFAULT;
> +
> +	*arg = 0;
> +
> +	return 0;
> +}
> +
> +int V4L2CameraProxy::vidioc_s_input(int fd, int *arg)
> +{
> +	LOG(V4L2Compat, Debug) << "Servicing vidioc_s_input fd = " << fd;
> +
> +	if (arg == nullptr)
> +		return -EFAULT;
> +
> +	if (*arg != 0)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
>  int V4L2CameraProxy::freeBuffers()
>  {
>  	LOG(V4L2Compat, Debug) << "Freeing libcamera bufs";
> @@ -649,6 +694,15 @@ int V4L2CameraProxy::ioctl(int fd, unsigned long request, void *arg)
>  	case VIDIOC_S_PRIORITY:
>  		ret = vidioc_s_priority(fd, static_cast<enum v4l2_priority *>(arg));
>  		break;
> +	case VIDIOC_ENUMINPUT:
> +		ret = vidioc_enuminput(fd, static_cast<struct v4l2_input *>(arg));
> +		break;
> +	case VIDIOC_G_INPUT:
> +		ret = vidioc_g_input(fd, static_cast<int *>(arg));
> +		break;
> +	case VIDIOC_S_INPUT:
> +		ret = vidioc_s_input(fd, static_cast<int *>(arg));
> +		break;
>  	case VIDIOC_REQBUFS:
>  		ret = vidioc_reqbufs(fd, static_cast<struct v4l2_requestbuffers *>(arg));
>  		break;
> diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> index a0c373d..2e90bfd 100644
> --- a/src/v4l2/v4l2_camera_proxy.h
> +++ b/src/v4l2/v4l2_camera_proxy.h
> @@ -51,6 +51,9 @@ private:
>  	int vidioc_try_fmt(int fd, struct v4l2_format *arg);
>  	int vidioc_g_priority(int fd, enum v4l2_priority *arg);
>  	int vidioc_s_priority(int fd, enum v4l2_priority *arg);
> +	int vidioc_enuminput(int fd, struct v4l2_input *arg);
> +	int vidioc_g_input(int fd, int *arg);
> +	int vidioc_s_input(int fd, int *arg);

Looks good
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Thanks
  j

>  	int vidioc_reqbufs(int fd, struct v4l2_requestbuffers *arg);
>  	int vidioc_querybuf(int fd, struct v4l2_buffer *arg);
>  	int vidioc_qbuf(int fd, struct v4l2_buffer *arg);
> --
> 2.27.0
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
Laurent Pinchart June 17, 2020, 3:36 p.m. UTC | #2
Hi Jacopo,

On Wed, Jun 17, 2020 at 03:15:35PM +0200, Jacopo Mondi wrote:
> On Tue, Jun 16, 2020 at 10:12:34PM +0900, Paul Elder wrote:
> > Implement VIDIOC_ENUMINPUT, VIDIOC_G_INPUT, and VIDIOC_S_INPUT. Only the
> > zeroth input device is supported, and the info returned by enuminput is
> > hardcoded and basic. This is sufficient to pass v4l2-compliance.
> 
> I don't think we'll have much other usages for this IOCTLs apart from
> this one :)

Well... :-) In the future I could imagine S_INPUT being used to select
between different cameras handled by the same pipeline handler instance,
when they're mutually exclusive.

> > Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> > ---
> >  src/v4l2/v4l2_camera_proxy.cpp | 54 ++++++++++++++++++++++++++++++++++
> >  src/v4l2/v4l2_camera_proxy.h   |  3 ++
> >  2 files changed, 57 insertions(+)
> >
> > diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> > index f268f7a..6c0dacc 100644
> > --- a/src/v4l2/v4l2_camera_proxy.cpp
> > +++ b/src/v4l2/v4l2_camera_proxy.cpp
> > @@ -397,6 +397,51 @@ int V4L2CameraProxy::vidioc_s_priority(int fd, enum v4l2_priority *arg)
> >  	return 0;
> >  }
> >
> > +int V4L2CameraProxy::vidioc_enuminput(int fd, struct v4l2_input *arg)
> > +{
> > +	LOG(V4L2Compat, Debug) << "Servicing vidioc_enuminput fd = " << fd;
> > +
> > +	if (arg == nullptr)
> > +		return -EFAULT;
> 
> This repeated patter makes me think we should probably centralize this
> check as suggested by Laurent on a previous patch
> 
> > +
> > +	if (arg->index != 0)
> > +		return -EINVAL;
> > +
> > +	memset(arg, 0, sizeof(*arg));
> > +
> > +	utils::strlcpy(reinterpret_cast<char *>(arg->name),
> > +		       reinterpret_cast<char *>(capabilities_.card),
> > +		       sizeof(arg->name));
> > +	arg->type = V4L2_INPUT_TYPE_CAMERA;
> > +
> > +	return 0;
> > +}
> > +
> > +int V4L2CameraProxy::vidioc_g_input(int fd, int *arg)
> > +{
> > +	LOG(V4L2Compat, Debug) << "Servicing vidioc_g_input fd = " << fd;
> > +
> > +	if (arg == nullptr)
> > +		return -EFAULT;
> > +
> > +	*arg = 0;
> > +
> > +	return 0;
> > +}
> > +
> > +int V4L2CameraProxy::vidioc_s_input(int fd, int *arg)
> > +{
> > +	LOG(V4L2Compat, Debug) << "Servicing vidioc_s_input fd = " << fd;
> > +
> > +	if (arg == nullptr)
> > +		return -EFAULT;
> > +
> > +	if (*arg != 0)
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +
> >  int V4L2CameraProxy::freeBuffers()
> >  {
> >  	LOG(V4L2Compat, Debug) << "Freeing libcamera bufs";
> > @@ -649,6 +694,15 @@ int V4L2CameraProxy::ioctl(int fd, unsigned long request, void *arg)
> >  	case VIDIOC_S_PRIORITY:
> >  		ret = vidioc_s_priority(fd, static_cast<enum v4l2_priority *>(arg));
> >  		break;
> > +	case VIDIOC_ENUMINPUT:
> > +		ret = vidioc_enuminput(fd, static_cast<struct v4l2_input *>(arg));
> > +		break;
> > +	case VIDIOC_G_INPUT:
> > +		ret = vidioc_g_input(fd, static_cast<int *>(arg));
> > +		break;
> > +	case VIDIOC_S_INPUT:
> > +		ret = vidioc_s_input(fd, static_cast<int *>(arg));
> > +		break;
> >  	case VIDIOC_REQBUFS:
> >  		ret = vidioc_reqbufs(fd, static_cast<struct v4l2_requestbuffers *>(arg));
> >  		break;
> > diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> > index a0c373d..2e90bfd 100644
> > --- a/src/v4l2/v4l2_camera_proxy.h
> > +++ b/src/v4l2/v4l2_camera_proxy.h
> > @@ -51,6 +51,9 @@ private:
> >  	int vidioc_try_fmt(int fd, struct v4l2_format *arg);
> >  	int vidioc_g_priority(int fd, enum v4l2_priority *arg);
> >  	int vidioc_s_priority(int fd, enum v4l2_priority *arg);
> > +	int vidioc_enuminput(int fd, struct v4l2_input *arg);
> > +	int vidioc_g_input(int fd, int *arg);
> > +	int vidioc_s_input(int fd, int *arg);
> 
> Looks good
> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>

Likewise,

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> >  	int vidioc_reqbufs(int fd, struct v4l2_requestbuffers *arg);
> >  	int vidioc_querybuf(int fd, struct v4l2_buffer *arg);
> >  	int vidioc_qbuf(int fd, struct v4l2_buffer *arg);

Patch

diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index f268f7a..6c0dacc 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -397,6 +397,51 @@  int V4L2CameraProxy::vidioc_s_priority(int fd, enum v4l2_priority *arg)
 	return 0;
 }
 
+int V4L2CameraProxy::vidioc_enuminput(int fd, struct v4l2_input *arg)
+{
+	LOG(V4L2Compat, Debug) << "Servicing vidioc_enuminput fd = " << fd;
+
+	if (arg == nullptr)
+		return -EFAULT;
+
+	if (arg->index != 0)
+		return -EINVAL;
+
+	memset(arg, 0, sizeof(*arg));
+
+	utils::strlcpy(reinterpret_cast<char *>(arg->name),
+		       reinterpret_cast<char *>(capabilities_.card),
+		       sizeof(arg->name));
+	arg->type = V4L2_INPUT_TYPE_CAMERA;
+
+	return 0;
+}
+
+int V4L2CameraProxy::vidioc_g_input(int fd, int *arg)
+{
+	LOG(V4L2Compat, Debug) << "Servicing vidioc_g_input fd = " << fd;
+
+	if (arg == nullptr)
+		return -EFAULT;
+
+	*arg = 0;
+
+	return 0;
+}
+
+int V4L2CameraProxy::vidioc_s_input(int fd, int *arg)
+{
+	LOG(V4L2Compat, Debug) << "Servicing vidioc_s_input fd = " << fd;
+
+	if (arg == nullptr)
+		return -EFAULT;
+
+	if (*arg != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
 int V4L2CameraProxy::freeBuffers()
 {
 	LOG(V4L2Compat, Debug) << "Freeing libcamera bufs";
@@ -649,6 +694,15 @@  int V4L2CameraProxy::ioctl(int fd, unsigned long request, void *arg)
 	case VIDIOC_S_PRIORITY:
 		ret = vidioc_s_priority(fd, static_cast<enum v4l2_priority *>(arg));
 		break;
+	case VIDIOC_ENUMINPUT:
+		ret = vidioc_enuminput(fd, static_cast<struct v4l2_input *>(arg));
+		break;
+	case VIDIOC_G_INPUT:
+		ret = vidioc_g_input(fd, static_cast<int *>(arg));
+		break;
+	case VIDIOC_S_INPUT:
+		ret = vidioc_s_input(fd, static_cast<int *>(arg));
+		break;
 	case VIDIOC_REQBUFS:
 		ret = vidioc_reqbufs(fd, static_cast<struct v4l2_requestbuffers *>(arg));
 		break;
diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
index a0c373d..2e90bfd 100644
--- a/src/v4l2/v4l2_camera_proxy.h
+++ b/src/v4l2/v4l2_camera_proxy.h
@@ -51,6 +51,9 @@  private:
 	int vidioc_try_fmt(int fd, struct v4l2_format *arg);
 	int vidioc_g_priority(int fd, enum v4l2_priority *arg);
 	int vidioc_s_priority(int fd, enum v4l2_priority *arg);
+	int vidioc_enuminput(int fd, struct v4l2_input *arg);
+	int vidioc_g_input(int fd, int *arg);
+	int vidioc_s_input(int fd, int *arg);
 	int vidioc_reqbufs(int fd, struct v4l2_requestbuffers *arg);
 	int vidioc_querybuf(int fd, struct v4l2_buffer *arg);
 	int vidioc_qbuf(int fd, struct v4l2_buffer *arg);