summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uvideo.c
diff options
context:
space:
mode:
authorJacob Meuser <jakemsr@cvs.openbsd.org>2011-03-26 08:15:08 +0000
committerJacob Meuser <jakemsr@cvs.openbsd.org>2011-03-26 08:15:08 +0000
commit313fedfeab62fa685b3de3e087d846adcf6bbdd8 (patch)
treeefbd46fbdbb8cadaa647de52cc93accc917b015f /sys/dev/usb/uvideo.c
parent0ce7af11d44b572c932838786f93d41e47de1d4c (diff)
fill in support for VIDIOC_ENUM_FRAMEINTERVALS
Diffstat (limited to 'sys/dev/usb/uvideo.c')
-rw-r--r--sys/dev/usb/uvideo.c53
1 files changed, 47 insertions, 6 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index e901cc6537b..7480e7aeaf5 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.154 2011/03/26 08:13:05 jakemsr Exp $ */
+/* $OpenBSD: uvideo.c,v 1.155 2011/03/26 08:15:07 jakemsr Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -2817,20 +2817,61 @@ int
uvideo_enum_fivals(void *v, struct v4l2_frmivalenum *fivals)
{
struct uvideo_softc *sc = v;
- int idx, found = 0;
+ int idx;
+ struct uvideo_format_group *fmtgrp = NULL;
+ struct usb_video_frame_desc *frame = NULL;
+ uint8_t *p;
for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
if (sc->sc_fmtgrp[idx].pixelformat == fivals->pixel_format) {
- found = 1;
+ fmtgrp = &sc->sc_fmtgrp[idx];
break;
}
}
- if (found == 0)
+ if (fmtgrp == NULL)
return (EINVAL);
- /* TODO */
+ for (idx = 0; idx < fmtgrp->frame_num; idx++) {
+ if (UGETW(fmtgrp->frame[idx]->wWidth) == fivals->width &&
+ UGETW(fmtgrp->frame[idx]->wHeight) == fivals->height) {
+ frame = fmtgrp->frame[idx];
+ break;
+ }
+ }
+ if (frame == NULL)
+ return (EINVAL);
- return (EINVAL);
+ /* byte-wise pointer to start of frame intervals */
+ p = (uint8_t *)frame;
+ p += sizeof(struct usb_video_frame_desc);
+
+ if (frame->bFrameIntervalType == 0) {
+ if (fivals->index != 0)
+ return (EINVAL);
+ fivals->type = V4L2_FRMIVAL_TYPE_STEPWISE;
+ fivals->un.stepwise.min.numerator = UGETDW(p);
+ fivals->un.stepwise.min.denominator = 10000000;
+ p += sizeof(uDWord);
+ fivals->un.stepwise.max.numerator = UGETDW(p);
+ fivals->un.stepwise.max.denominator = 10000000;
+ p += sizeof(uDWord);
+ fivals->un.stepwise.step.numerator = UGETDW(p);
+ fivals->un.stepwise.step.denominator = 10000000;
+ p += sizeof(uDWord);
+ } else {
+ if (fivals->index >= frame->bFrameIntervalType)
+ return (EINVAL);
+ p += sizeof(uDWord) * fivals->index;
+ if (p > frame->bLength + (uint8_t *)frame) {
+ printf("%s: frame desc too short?\n", __func__);
+ return (EINVAL);
+ }
+ fivals->type = V4L2_FRMIVAL_TYPE_DISCRETE;
+ fivals->un.discrete.numerator = UGETDW(p);
+ fivals->un.discrete.denominator = 10000000;
+ }
+
+ return (0);
}
int