-/* $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 <robert@openbsd.org>
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,
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);
}
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);
}
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);
* 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];
/* 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);
-/* $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 <robert@openbsd.org>
};
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;