diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2008-05-27 17:47:29 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2008-05-27 17:47:29 +0000 |
commit | cdea530626fdeccb744b9c09c8070b33068df26c (patch) | |
tree | 2148723181373575c897117d54109b7ef087af91 /sys/dev | |
parent | 383c790b2a2a21f0a8c5b02dd3f9eeb35504ea58 (diff) |
Instead alloacting a fix frame buffer we allocate the maximum frame size
delivered by the device (dwMaxVideoFrameSize). Also check for too large
frames (buffer overflow), they get skipped.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/uvideo.c | 48 | ||||
-rw-r--r-- | sys/dev/usb/uvideo.h | 3 |
2 files changed, 32 insertions, 19 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c index 4d6230b7809..a6ce78372f2 100644 --- a/sys/dev/usb/uvideo.c +++ b/sys/dev/usb/uvideo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.c,v 1.19 2008/05/26 17:51:18 mglocker Exp $ */ +/* $OpenBSD: uvideo.c,v 1.20 2008/05/27 17:47:28 mglocker Exp $ */ /* * Copyright (c) 2008 Robert Nagy <robert@openbsd.org> @@ -919,14 +919,17 @@ uvideo_vs_alloc_sample(struct uvideo_softc *sc) { struct uvideo_sample_buffer *fb = &sc->sc_sample_buffer; - DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__); + fb->buf_size = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize); - fb->buf = malloc(32000, M_DEVBUF, M_NOWAIT); /* XXX find proper size */ + fb->buf = malloc(fb->buf_size, M_DEVBUF, M_NOWAIT); if (fb->buf == NULL) { printf("%s: can't allocate sample buffer!\n", DEVNAME(sc)); return (USBD_NOMEM); } + DPRINTF(1, "%s: %s: allocated %d bytes sample buffer\n", + DEVNAME(sc), __func__, fb->buf_size); + fb->fragment = 0; fb->fid = 0; fb->offset = 0; @@ -1167,30 +1170,37 @@ uvideo_vs_decode_stream_header(struct uvideo_softc *sc, uint8_t *frame, /* save sample fragment */ fragment_len = frame_size - header_len; - bcopy(frame + header_len, fb->buf + fb->offset, fragment_len); - fb->offset += fragment_len; + if ((fb->offset + fragment_len) <= fb->buf_size) { + bcopy(frame + header_len, fb->buf + fb->offset, fragment_len); + fb->offset += fragment_len; + } if (header_flags & UVIDEO_STREAM_EOF) { /* got a full sample */ DPRINTF(2, "%s: %s: EOF (sample size = %d bytes)\n", DEVNAME(sc), __func__, fb->offset); + + if (fb->offset <= fb->buf_size) { #ifdef UVIDEO_DEBUG - /* do the file write in process context */ - usb_rem_task(sc->sc_udev, &sc->sc_task_write); - usb_add_task(sc->sc_udev, &sc->sc_task_write); + /* do the file write in process context */ + usb_rem_task(sc->sc_udev, &sc->sc_task_write); + usb_add_task(sc->sc_udev, &sc->sc_task_write); #endif - /* - * Copy video frame to upper layer buffer and call - * upper layer interrupt. - */ - bzero(sc->sc_uplayer_fbuffer, 32000); - *sc->sc_uplayer_fsize = fb->offset; - bcopy(fb->buf, sc->sc_uplayer_fbuffer, fb->offset); - sc->sc_uplayer_intr(sc->sc_uplayer_arg); + /* + * Copy video frame to upper layer buffer and call + * upper layer interrupt. + */ + *sc->sc_uplayer_fsize = fb->offset; + bcopy(fb->buf, sc->sc_uplayer_fbuffer, fb->offset); + sc->sc_uplayer_intr(sc->sc_uplayer_arg); + } else { + DPRINTF(1, "%s: %s: sample too large, skipped!\n", + DEVNAME(sc), __func__); + } fb->fragment = 0; fb->fid = 0; -// fb->offset = 0; + //fb->offset = 0; } return (0); @@ -1677,10 +1687,12 @@ uvideo_enum_fmt(void *v, struct v4l2_fmtdesc *fmtdesc) int uvideo_s_fmt(void *v, struct v4l2_format *fmt) { + struct uvideo_softc *sc = v; + if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return (EINVAL); - fmt->fmt.pix.sizeimage = 32000; + fmt->fmt.pix.sizeimage = sc->sc_sample_buffer.buf_size; return (0); } diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h index 6950f5d76db..efb996ea0f2 100644 --- a/sys/dev/usb/uvideo.h +++ b/sys/dev/usb/uvideo.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.h,v 1.8 2008/05/24 19:37:34 mglocker Exp $ */ +/* $OpenBSD: uvideo.h,v 1.9 2008/05/27 17:47:28 mglocker Exp $ */ /* * Copyright (c) 2007 Robert Nagy <robert@openbsd.org> @@ -347,6 +347,7 @@ struct uvideo_sample_buffer { int fragment; uint8_t fid; int offset; + int buf_size; uint8_t *buf; }; |