diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/uvideo.c | 58 | ||||
-rw-r--r-- | sys/dev/usb/uvideo.h | 16 |
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; |