Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Support VIDIOC_G_PARM/VIDIOC_S_PARM



details:   https://anonhg.NetBSD.org/src/rev/3123e28510c4
branches:  trunk
changeset: 972266:3123e28510c4
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Fri May 22 11:23:51 2020 +0000

description:
Support VIDIOC_G_PARM/VIDIOC_S_PARM

diffstat:

 sys/dev/video.c    |  68 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/dev/video_if.h |  11 +++++++-
 2 files changed, 76 insertions(+), 3 deletions(-)

diffs (142 lines):

diff -r e370d7875ac1 -r 3123e28510c4 sys/dev/video.c
--- a/sys/dev/video.c   Fri May 22 04:46:26 2020 +0000
+++ b/sys/dev/video.c   Fri May 22 11:23:51 2020 +0000
@@ -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 <pat%polycrystal.org@localhost>
@@ -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 @@
                                 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 @@
        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 @@
        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 @@
        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);
diff -r e370d7875ac1 -r 3123e28510c4 sys/dev/video_if.h
--- a/sys/dev/video_if.h        Fri May 22 04:46:26 2020 +0000
+++ b/sys/dev/video_if.h        Fri May 22 11:23:51 2020 +0000
@@ -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 <pat%polycrystal.org@localhost>
@@ -378,6 +378,12 @@
                                 * 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 @@
 
        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 {



Home | Main Index | Thread Index | Old Index