Module Name:    src
Committed By:   jmcneill
Date:           Fri May 22 11:23:52 UTC 2020

Modified Files:
        src/sys/dev: video.c video_if.h

Log Message:
Support VIDIOC_G_PARM/VIDIOC_S_PARM


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/sys/dev/video.c
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/video_if.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/video.c
diff -u src/sys/dev/video.c:1.36 src/sys/dev/video.c:1.37
--- src/sys/dev/video.c:1.36	Fri Dec 27 09:41:50 2019
+++ src/sys/dev/video.c	Fri May 22 11:23:51 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: video.c,v 1.36 2019/12/27 09:41:50 msaitoh Exp $ */
+/* $NetBSD: video.c,v 1.37 2020/05/22 11:23:51 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2008 Patrick Mahoney <p...@polycrystal.org>
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: video.c,v 1.36 2019/12/27 09:41:50 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: video.c,v 1.37 2020/05/22 11:23:51 jmcneill Exp $");
 
 #include "video.h"
 #if NVIDEO > 0
@@ -262,6 +262,10 @@ static int	video_set_format(struct video
 				 struct v4l2_format *);
 static int	video_try_format(struct video_softc *,
 				 struct v4l2_format *);
+static int	video_get_parm(struct video_softc *,
+			       struct v4l2_streamparm *);
+static int	video_set_parm(struct video_softc *,
+			       struct v4l2_streamparm *);
 static int	video_enum_standard(struct video_softc *,
 				    struct v4l2_standard *);
 static int	video_get_standard(struct video_softc *, v4l2_std_id *);
@@ -871,6 +875,57 @@ video_try_format(struct video_softc *sc,
 	return 0;
 }
 
+static int
+video_get_parm(struct video_softc *sc, struct v4l2_streamparm *parm)
+{
+	struct video_fract fract;
+	const struct video_hw_if *hw;
+	int error;
+
+	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return EINVAL;
+
+	hw = sc->hw_if;
+	if (hw == NULL)
+		return ENXIO;
+
+	memset(&parm->parm, 0, sizeof(parm->parm));
+	if (hw->get_framerate != NULL) {
+		error = hw->get_framerate(sc->hw_softc, &fract);
+		if (error != 0)
+			return error;
+		parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+		parm->parm.capture.timeperframe.numerator = fract.numerator;
+		parm->parm.capture.timeperframe.denominator = fract.denominator;
+	}
+
+	return 0;
+}
+
+static int
+video_set_parm(struct video_softc *sc, struct v4l2_streamparm *parm)
+{
+	struct video_fract fract;
+	const struct video_hw_if *hw;
+	int error;
+
+	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return EINVAL;
+
+	hw = sc->hw_if;
+	if (hw == NULL || hw->set_framerate == NULL)
+		return ENXIO;
+
+	error = hw->set_framerate(sc->hw_softc, &fract);
+	if (error != 0)
+		return error;
+
+	parm->parm.capture.timeperframe.numerator = fract.numerator;
+	parm->parm.capture.timeperframe.denominator = fract.denominator;
+
+	return 0;
+}
+
 static void
 v4l2_standard_to_video_standard(v4l2_std_id stdid,
     enum video_standard *vstd)
@@ -1858,6 +1913,7 @@ videoioctl(dev_t dev, u_long cmd, void *
 	struct v4l2_queryctrl *query;
 	struct v4l2_requestbuffers *reqbufs;
 	struct v4l2_buffer *buf;
+	struct v4l2_streamparm *parm;
 	v4l2_std_id *stdid;
 	enum v4l2_buf_type *typep;
 	int *ip;
@@ -1914,6 +1970,14 @@ videoioctl(dev_t dev, u_long cmd, void *
 	case VIDIOC_TRY_FMT:
 		fmt = data;
 		return video_try_format(sc, fmt);
+	case VIDIOC_G_PARM:
+		parm = data;
+		return video_get_parm(sc, parm);
+	case VIDIOC_S_PARM:
+		parm = data;
+		if ((flag & FWRITE) == 0)
+			return EPERM;
+		return video_set_parm(sc, parm);
 	case VIDIOC_ENUMSTD:
 		std = data;
 		return video_enum_standard(sc, std);

Index: src/sys/dev/video_if.h
diff -u src/sys/dev/video_if.h:1.8 src/sys/dev/video_if.h:1.9
--- src/sys/dev/video_if.h:1.8	Fri Dec 27 09:41:50 2019
+++ src/sys/dev/video_if.h	Fri May 22 11:23:51 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: video_if.h,v 1.8 2019/12/27 09:41:50 msaitoh Exp $ */
+/* $NetBSD: video_if.h,v 1.9 2020/05/22 11:23:51 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2008 Patrick Mahoney <p...@polycrystal.org>
@@ -378,6 +378,12 @@ struct video_format {
 				 * Must be set to zero if not used. */
 };
 
+/* Represents the amount of time a single frame is displayed. */
+struct video_fract {
+	uint32_t	numerator;
+	uint32_t	denominator;
+};
+
 /* A payload is the smallest unit transferred from the hardware driver
  * to the video layer. Multiple video payloads make up one video
  * sample. */
@@ -488,6 +494,9 @@ struct video_hw_if {
 
 	int	(*get_frequency)(void *, struct video_frequency *);
 	int	(*set_frequency)(void *, struct video_frequency *);
+
+	int	(*get_framerate)(void *, struct video_fract *);
+	int	(*set_framerate)(void *, struct video_fract *);
 };
 
 struct video_attach_args {

Reply via email to