summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2008-08-13 20:29:35 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2008-08-13 20:29:35 +0000
commitb836f59f2bb98f50cbe6fcaf1ece40f5959a37b8 (patch)
tree0a1dabc108a0911bfd7e14d7ca8e306408547854 /sys/dev
parentab11b24f7dcb98e06df61cd23ffdd66ccf568f92 (diff)
Add VIDIOC_ENUM_FRAMESIZES ioctl. This permits applications to query the
available formats and resolutions of a device (e.g. "luvcview -L").
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/uvideo.c64
-rw-r--r--sys/dev/video.c12
-rw-r--r--sys/dev/video_if.h4
3 files changed, 77 insertions, 3 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index e07a6aa2e47..4d6b12734ca 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.80 2008/08/12 08:26:42 mglocker Exp $ */
+/* $OpenBSD: uvideo.c,v 1.81 2008/08/13 20:29:34 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -149,6 +149,8 @@ void uvideo_debug_file_write_frame(void *);
*/
int uvideo_querycap(void *, struct v4l2_capability *);
int uvideo_enum_fmt(void *, struct v4l2_fmtdesc *);
+int uvideo_enum_fsizes(void *, struct v4l2_frmsizeenum *);
+int uvideo_enum_fivals(void *, struct v4l2_frmivalenum *);
int uvideo_s_fmt(void *, struct v4l2_format *);
int uvideo_g_fmt(void *, struct v4l2_format *);
int uvideo_enum_input(void *, struct v4l2_input *);
@@ -185,6 +187,8 @@ struct video_hw_if uvideo_hw_if = {
uvideo_close, /* close */
uvideo_querycap, /* VIDIOC_QUERYCAP */
uvideo_enum_fmt, /* VIDIOC_ENUM_FMT */
+ uvideo_enum_fsizes, /* VIDIOC_ENUM_FRAMESIZES */
+ uvideo_enum_fivals, /* VIDIOC_ENUM_FRAMEINTERVALS */
uvideo_s_fmt, /* VIDIOC_S_FMT */
uvideo_g_fmt, /* VIDIOC_G_FMT */
uvideo_enum_input, /* VIDIOC_ENUMINPUT */
@@ -2158,6 +2162,64 @@ uvideo_enum_fmt(void *v, struct v4l2_fmtdesc *fmtdesc)
}
int
+uvideo_enum_fsizes(void *v, struct v4l2_frmsizeenum *fsizes)
+{
+ struct uvideo_softc *sc = v;
+ int i, idx, found = 0;
+
+ for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
+ if (sc->sc_fmtgrp[idx].pixelformat == fsizes->pixel_format) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0)
+ return (EINVAL);
+
+ i = fsizes->index + 1;
+ if (i > sc->sc_fmtgrp[idx].frame_num)
+ /* no more frames left */
+ return (EINVAL);
+
+ if (sc->sc_fmtgrp[idx].frame[i]->bFrameIntervalType == 0) {
+ /* TODO */
+ fsizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
+ fsizes->stepwise.min_width = 0;
+ fsizes->stepwise.min_height = 0;
+ fsizes->stepwise.max_width = 0;
+ fsizes->stepwise.max_height = 0;
+ } else {
+ fsizes->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsizes->discrete.width =
+ UGETW(sc->sc_fmtgrp[idx].frame[i]->wWidth);
+ fsizes->discrete.height =
+ UGETW(sc->sc_fmtgrp[idx].frame[i]->wHeight);
+ }
+
+ return (0);
+}
+
+int
+uvideo_enum_fivals(void *v, struct v4l2_frmivalenum *fivals)
+{
+ struct uvideo_softc *sc = v;
+ int idx, found = 0;
+
+ for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
+ if (sc->sc_fmtgrp[idx].pixelformat == fivals->pixel_format) {
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0)
+ return (EINVAL);
+
+ /* TODO */
+
+ return (EINVAL);
+}
+
+int
uvideo_s_fmt(void *v, struct v4l2_format *fmt)
{
struct uvideo_softc *sc = v;
diff --git a/sys/dev/video.c b/sys/dev/video.c
index dd741a85ac6..0f8e3cc2414 100644
--- a/sys/dev/video.c
+++ b/sys/dev/video.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: video.c,v 1.20 2008/07/31 15:26:25 mglocker Exp $ */
+/* $OpenBSD: video.c,v 1.21 2008/08/13 20:29:34 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
* Copyright (c) 2008 Marcus Glocker <mglocker@openbsd.org>
@@ -199,6 +199,16 @@ videoioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
error = (sc->hw_if->enum_fmt)(sc->hw_hdl,
(struct v4l2_fmtdesc *)data);
break;
+ case VIDIOC_ENUM_FRAMESIZES:
+ if (sc->hw_if->enum_fsizes)
+ error = (sc->hw_if->enum_fsizes)(sc->hw_hdl,
+ (struct v4l2_frmsizeenum *)data);
+ break;
+ case VIDIOC_ENUM_FRAMEINTERVALS:
+ if (sc->hw_if->enum_fivals)
+ error = (sc->hw_if->enum_fivals)(sc->hw_hdl,
+ (struct v4l2_frmivalenum *)data);
+ break;
case VIDIOC_S_FMT:
if (!(flags & FWRITE))
return (EACCES);
diff --git a/sys/dev/video_if.h b/sys/dev/video_if.h
index 69ff3174164..ea8836aa61a 100644
--- a/sys/dev/video_if.h
+++ b/sys/dev/video_if.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: video_if.h,v 1.14 2008/07/31 15:26:25 mglocker Exp $ */
+/* $OpenBSD: video_if.h,v 1.15 2008/08/13 20:29:34 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
* Copyright (c) 2008 Marcus Glocker <mglocker@openbsd.org>
@@ -36,6 +36,8 @@ struct video_hw_if {
/* ioctl's */
int (*querycap)(void *, struct v4l2_capability *);
int (*enum_fmt)(void *, struct v4l2_fmtdesc *);
+ int (*enum_fsizes)(void *, struct v4l2_frmsizeenum *);
+ int (*enum_fivals)(void *, struct v4l2_frmivalenum *);
int (*s_fmt)(void *, struct v4l2_format *);
int (*g_fmt)(void *, struct v4l2_format *);
int (*enum_input)(void *, struct v4l2_input *);