From ff018eb9b747b802db9d6caeb3fb855405e5c248 Mon Sep 17 00:00:00 2001 From: mglocker Date: Mon, 14 Jul 2008 04:45:50 +0000 Subject: [PATCH] Finish support for uncompressed payloads (UDESCSUB_VS_FORMAT_UNCOMPRESSED). --- sys/dev/usb/uvideo.c | 76 ++++++++++++++++++++++++++++++++++++++------ sys/dev/usb/uvideo.h | 39 ++++++++++++++++++++--- 2 files changed, 102 insertions(+), 13 deletions(-) diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c index 51bbe4b4bf6..86df7d34944 100644 --- a/sys/dev/usb/uvideo.c +++ b/sys/dev/usb/uvideo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.c,v 1.51 2008/07/13 12:48:40 mglocker Exp $ */ +/* $OpenBSD: uvideo.c,v 1.52 2008/07/14 04:45:50 mglocker Exp $ */ /* * Copyright (c) 2008 Robert Nagy @@ -82,7 +82,7 @@ int uvideo_vs_parse_desc_frame(struct uvideo_softc *); int uvideo_vs_parse_desc_frame_mjpeg(struct uvideo_softc *, const usb_descriptor_t *, int *); int uvideo_vs_parse_desc_frame_uncompressed(struct uvideo_softc *, - const usb_descriptor_t *); + const usb_descriptor_t *, int *); int uvideo_vs_parse_desc_alt(struct uvideo_softc *, struct usb_attach_arg *uaa, int, int, int); int uvideo_vs_set_alt(struct uvideo_softc *, usbd_interface_handle, @@ -635,10 +635,13 @@ uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc *sc, DEVNAME(sc)); return (-1); } - sc->sc_fmtgrp[d->bFormatIndex].format = d; + sc->sc_fmtgrp[d->bFormatIndex].format = (struct uvideo_format_desc *)d; + sc->sc_fmtgrp[d->bFormatIndex].format_dfidx = + sc->sc_fmtgrp[d->bFormatIndex].format->u.mjpeg.bDefaultFrameIndex; - /* set MJPEG format as default */ - sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[d->bFormatIndex]; + if (sc->sc_fmtgrp_cur == NULL) + /* set MJPEG format */ + sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[d->bFormatIndex]; return (0); } @@ -657,7 +660,18 @@ uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc *sc, return (-1); } - /* TODO */ + if (d->bFormatIndex == UVIDEO_MAX_FORMAT) { + printf("%s: too many UNCOMPRESSED format descriptors found!\n", + DEVNAME(sc)); + return (-1); + } + sc->sc_fmtgrp[d->bFormatIndex].format = (struct uvideo_format_desc *)d; + sc->sc_fmtgrp[d->bFormatIndex].format_dfidx = + sc->sc_fmtgrp[d->bFormatIndex].format->u.uc.bDefaultFrameIndex; + + if (sc->sc_fmtgrp_cur == NULL) + /* set UNCOMPRESSED format */ + sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[d->bFormatIndex]; return (0); } @@ -684,6 +698,14 @@ uvideo_vs_parse_desc_frame(struct uvideo_softc *sc) if (uvideo_vs_parse_desc_frame_mjpeg(sc, desc, &fmtidx)) return (1); break; + case UDESCSUB_VS_FRAME_UNCOMPRESSED: + /* XXX do correct length calculation */ + if (desc->bLength == 38) { + if (uvideo_vs_parse_desc_frame_uncompressed(sc, + desc, &fmtidx)) + return (1); + } + break; } desc = usb_desc_iter_next(&iter); @@ -715,10 +737,46 @@ uvideo_vs_parse_desc_frame_mjpeg(struct uvideo_softc *sc, * use the first bFrameIndex available, otherwise * set it to the default one. */ - if (sc->sc_fmtgrp[*fmtidx].format->bDefaultFrameIndex == 0) { + if (sc->sc_fmtgrp[*fmtidx].format->u.mjpeg.bDefaultFrameIndex == 0) { + sc->sc_fmtgrp[*fmtidx].frame_cur = + sc->sc_fmtgrp[*fmtidx].frame[1]; + } else if (sc->sc_fmtgrp[*fmtidx].format->u.mjpeg.bDefaultFrameIndex == + d->bFrameIndex) { + sc->sc_fmtgrp[*fmtidx].frame_cur = + sc->sc_fmtgrp[*fmtidx].frame[d->bFrameIndex]; + } + + return (0); +} + +int +uvideo_vs_parse_desc_frame_uncompressed(struct uvideo_softc *sc, + const usb_descriptor_t *desc, int *fmtidx) +{ + struct usb_video_frame_uncompressed_desc *d; + + d = (struct usb_video_frame_uncompressed_desc *)(uint8_t *)desc; + + if (d->bFrameIndex == 1) + ++*fmtidx; + + if (d->bFrameIndex == UVIDEO_MAX_FRAME) { + printf("%s: too many UNCOMPRESSED frame descriptors found!\n", + DEVNAME(sc)); + return (1); + } + sc->sc_fmtgrp[*fmtidx].frame[d->bFrameIndex] = + (struct usb_video_frame_mjpeg_desc *)d; + + /* + * If bDefaultFrameIndex is not set by the device + * use the first bFrameIndex available, otherwise + * set it to the default one. + */ + if (sc->sc_fmtgrp[*fmtidx].format->u.uc.bDefaultFrameIndex == 0) { sc->sc_fmtgrp[*fmtidx].frame_cur = sc->sc_fmtgrp[*fmtidx].frame[1]; - } else if (sc->sc_fmtgrp[*fmtidx].format->bDefaultFrameIndex == + } else if (sc->sc_fmtgrp[*fmtidx].format->u.uc.bDefaultFrameIndex == d->bFrameIndex) { sc->sc_fmtgrp[*fmtidx].frame_cur = sc->sc_fmtgrp[*fmtidx].frame[d->bFrameIndex]; @@ -889,7 +947,7 @@ uvideo_vs_negotation(struct uvideo_softc *sc, int commit) /* set probe */ pc->bFormatIndex = sc->sc_fmtgrp_cur->format->bFormatIndex; - pc->bFrameIndex = sc->sc_fmtgrp_cur->format->bDefaultFrameIndex; + pc->bFrameIndex = sc->sc_fmtgrp_cur->format_dfidx; USETDW(pc->dwFrameInterval, UGETDW(sc->sc_fmtgrp_cur->frame_cur->dwDefaultFrameInterval)); USETDW(pc->dwMaxVideoFrameSize, 0); diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h index 67f1519ff92..0bbcb4584d5 100644 --- a/sys/dev/usb/uvideo.h +++ b/sys/dev/usb/uvideo.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.h,v 1.20 2008/07/13 11:49:31 mglocker Exp $ */ +/* $OpenBSD: uvideo.h,v 1.21 2008/07/14 04:45:50 mglocker Exp $ */ /* * Copyright (c) 2007 Robert Nagy @@ -406,11 +406,42 @@ struct uvideo_mmap { }; typedef SIMPLEQ_HEAD(, uvideo_mmap) q_mmap; +struct uvideo_format_desc { + uByte bLength; + uByte bDescriptorType; + uByte bDescriptorSubtype; + uByte bFormatIndex; + uByte bNumFrameDescriptors; + union { + /* mjpeg */ + struct { + uByte bmFlags; + uByte bDefaultFrameIndex; + uByte bAspectRatioX; + uByte bAspectRatioY; + uByte bmInterlaceFlags; + uByte bCopyProtect; + } mjpeg; + + /* uncompressed */ + struct { + uByte guidFormat[16]; + uByte bBitsPerPixel; + uByte bDefaultFrameIndex; + uByte bAspectRatioX; + uByte bAspectRatioY; + uByte bmInterlaceFlags; + uByte bCopyProtect; + } uc; + } u; +} __packed; + 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; + struct uvideo_format_desc *format; + uint8_t format_dfidx; + /* frame descriptors for mjpeg and uncompressed are identical */ #define UVIDEO_MAX_FRAME 16 + struct usb_video_frame_mjpeg_desc *frame_cur; struct usb_video_frame_mjpeg_desc *frame[UVIDEO_MAX_FRAME]; } __packed; -- 2.20.1