summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/uvideo.c58
-rw-r--r--sys/dev/usb/uvideo.h16
2 files changed, 51 insertions, 23 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 330cfc2bcfa..b9a420c0126 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.49 2008/07/10 04:49:12 mglocker Exp $ */
+/* $OpenBSD: uvideo.c,v 1.50 2008/07/13 11:49:31 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -80,7 +80,7 @@ int uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc *,
const usb_descriptor_t *);
int uvideo_vs_parse_desc_frame(struct uvideo_softc *);
int uvideo_vs_parse_desc_frame_mjpeg(struct uvideo_softc *,
- const usb_descriptor_t *);
+ const usb_descriptor_t *, int *);
int uvideo_vs_parse_desc_frame_uncompressed(struct uvideo_softc *,
const usb_descriptor_t *);
int uvideo_vs_parse_desc_alt(struct uvideo_softc *,
@@ -630,7 +630,15 @@ uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc *sc,
return (-1);
}
- sc->sc_desc_format_mjpeg = d;
+ if (d->bFormatIndex == UVIDEO_MAX_FORMAT) {
+ printf("%s: too many MJPEG format descriptors found!\n",
+ DEVNAME(sc));
+ return (-1);
+ }
+ sc->sc_fmtgrp[d->bFormatIndex].format = d;
+
+ /* set MJPEG format as default */
+ sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[d->bFormatIndex];
return (0);
}
@@ -659,6 +667,7 @@ uvideo_vs_parse_desc_frame(struct uvideo_softc *sc)
{
usbd_desc_iter_t iter;
const usb_descriptor_t *desc;
+ int fmtidx = 0;
DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
@@ -672,39 +681,48 @@ uvideo_vs_parse_desc_frame(struct uvideo_softc *sc)
switch (desc->bDescriptorSubtype) {
case UDESCSUB_VS_FRAME_MJPEG:
- if (uvideo_vs_parse_desc_frame_mjpeg(sc, desc) == 0)
- return (0);
+ if (uvideo_vs_parse_desc_frame_mjpeg(sc, desc, &fmtidx))
+ return (1);
break;
}
desc = usb_desc_iter_next(&iter);
}
- printf("%s: no default frame descriptor found!\n", DEVNAME(sc));
-
- return (1);
+ return (0);
}
int
uvideo_vs_parse_desc_frame_mjpeg(struct uvideo_softc *sc,
- const usb_descriptor_t *desc)
+ const usb_descriptor_t *desc, int *fmtidx)
{
struct usb_video_frame_mjpeg_desc *d;
d = (struct usb_video_frame_mjpeg_desc *)(uint8_t *)desc;
+ if (d->bFrameIndex == 1)
+ ++*fmtidx;
+
+ if (d->bFrameIndex == UVIDEO_MAX_FRAME) {
+ printf("%s: too many MJPEG frame descriptors found!\n",
+ DEVNAME(sc));
+ return (1);
+ }
+ sc->sc_fmtgrp[*fmtidx].frame[d->bFrameIndex] = d;
+
/*
* If bDefaultFrameIndex is not set by the device
* use the first bFrameIndex available, otherwise
* set it to the default one.
*/
- if (!sc->sc_desc_format_mjpeg->bDefaultFrameIndex)
- goto set;
- else if (d->bFrameIndex != sc->sc_desc_format_mjpeg->bDefaultFrameIndex)
- return (1);
-
-set:
- sc->sc_desc_frame_mjpeg = d;
+ if (sc->sc_fmtgrp[*fmtidx].format->bDefaultFrameIndex == 0) {
+ sc->sc_fmtgrp[*fmtidx].frame_cur =
+ sc->sc_fmtgrp[*fmtidx].frame[1];
+ } else if (sc->sc_fmtgrp[*fmtidx].format->bDefaultFrameIndex ==
+ d->bFrameIndex) {
+ sc->sc_fmtgrp[*fmtidx].frame_cur =
+ sc->sc_fmtgrp[*fmtidx].frame[d->bFrameIndex];
+ }
return (0);
}
@@ -870,10 +888,10 @@ uvideo_vs_negotation(struct uvideo_softc *sc, int commit)
return (error);
/* set probe */
- pc->bFormatIndex = sc->sc_desc_format_mjpeg->bFormatIndex;
- pc->bFrameIndex = sc->sc_desc_format_mjpeg->bDefaultFrameIndex;
+ pc->bFormatIndex = sc->sc_fmtgrp_cur->format->bFormatIndex;
+ pc->bFrameIndex = sc->sc_fmtgrp_cur->format->bDefaultFrameIndex;
USETDW(pc->dwFrameInterval,
- UGETDW(sc->sc_desc_frame_mjpeg->dwDefaultFrameInterval));
+ UGETDW(sc->sc_fmtgrp_cur->frame_cur->dwDefaultFrameInterval));
USETDW(pc->dwMaxVideoFrameSize, 0);
USETDW(pc->dwMaxPayloadTransferSize, 0);
error = uvideo_vs_set_probe(sc, probe_data);
@@ -1923,7 +1941,7 @@ uvideo_enum_fmt(void *v, struct v4l2_fmtdesc *fmtdesc)
* XXX We need to create a sc->sc_desc_format pointer array
* which contains all available format descriptors.
*/
- switch (sc->sc_desc_format_mjpeg->bDescriptorSubtype) {
+ switch (sc->sc_fmtgrp_cur->format->bDescriptorSubtype) {
case UDESCSUB_VS_FORMAT_MJPEG:
fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
(void)strlcpy(fmtdesc->description, "MJPEG",
diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h
index 1687e49bece..67f1519ff92 100644
--- a/sys/dev/usb/uvideo.h
+++ b/sys/dev/usb/uvideo.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.h,v 1.19 2008/07/12 06:26:06 mglocker Exp $ */
+/* $OpenBSD: uvideo.h,v 1.20 2008/07/13 11:49:31 mglocker Exp $ */
/*
* Copyright (c) 2007 Robert Nagy <robert@openbsd.org>
@@ -406,6 +406,14 @@ struct uvideo_mmap {
};
typedef SIMPLEQ_HEAD(, uvideo_mmap) q_mmap;
+struct uvideo_format_group {
+ /* XXX format descriptor should be union */
+ struct usb_video_format_mjpeg_desc *format;
+ struct usb_video_frame_mjpeg_desc *frame_cur;
+#define UVIDEO_MAX_FRAME 16
+ struct usb_video_frame_mjpeg_desc *frame[UVIDEO_MAX_FRAME];
+} __packed;
+
struct uvideo_softc {
struct device sc_dev;
usbd_device_handle sc_udev;
@@ -451,8 +459,10 @@ struct uvideo_softc {
struct usb_video_probe_commit sc_desc_probe;
struct usb_video_header_desc_all sc_desc_vc_header;
struct usb_video_input_header_desc_all sc_desc_vs_input_header;
- struct usb_video_format_mjpeg_desc *sc_desc_format_mjpeg;
- struct usb_video_frame_mjpeg_desc *sc_desc_frame_mjpeg;
+
+#define UVIDEO_MAX_FORMAT 8
+ struct uvideo_format_group *sc_fmtgrp_cur;
+ struct uvideo_format_group sc_fmtgrp[UVIDEO_MAX_FORMAT];
#define UVIDEO_MAX_VS_NUM 8
struct uvideo_vs_iface *sc_vs_curr;