-/* $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>
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 *,
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);
}
{
usbd_desc_iter_t iter;
const usb_descriptor_t *desc;
+ int fmtidx = 0;
DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
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);
}
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);
* 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",
-/* $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>
};
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;
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;