Commit 1eb9c838 authored by Simon Evans's avatar Simon Evans Committed by Greg Kroah-Hartman

[PATCH] 2.5.12 - make usbvideo.c use USBVIDEO_NUMFRAMES correctly

This patch makes usbvideo.c use the correct value of USBVIDEO_NUMFRAMES.
A few places in the code assumed it was 2. This patch was tested with
USBVIDEO_NUMFRAMES = 2,3,4,8,11,32
parent 2babc05b
...@@ -1192,7 +1192,7 @@ static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1192,7 +1192,7 @@ static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma)
if (!CAMERA_IS_OPERATIONAL(uvd)) if (!CAMERA_IS_OPERATIONAL(uvd))
return -EFAULT; return -EFAULT;
if (size > (((2 * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) if (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
return -EINVAL; return -EINVAL;
pos = (unsigned long) uvd->fbuf; pos = (unsigned long) uvd->fbuf;
...@@ -1471,12 +1471,14 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, ...@@ -1471,12 +1471,14 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file,
case VIDIOCGMBUF: case VIDIOCGMBUF:
{ {
struct video_mbuf *vm = arg; struct video_mbuf *vm = arg;
int i;
memset(vm, 0, sizeof(*vm)); memset(vm, 0, sizeof(*vm));
vm->size = uvd->max_frame_size * 2; vm->size = uvd->max_frame_size * USBVIDEO_NUMFRAMES;
vm->frames = 2; vm->frames = USBVIDEO_NUMFRAMES;
vm->offsets[0] = 0; for(i = 0; i < USBVIDEO_NUMFRAMES; i++)
vm->offsets[1] = uvd->max_frame_size; vm->offsets[i] = i * uvd->max_frame_size;
return 0; return 0;
} }
case VIDIOCMCAPTURE: case VIDIOCMCAPTURE:
...@@ -1518,8 +1520,8 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file, ...@@ -1518,8 +1520,8 @@ static int usbvideo_v4l_do_ioctl(struct inode *inode, struct file *file,
} }
return -EINVAL; return -EINVAL;
} }
if ((vm->frame != 0) && (vm->frame != 1)) { if ((vm->frame < 0) || (vm->frame >= USBVIDEO_NUMFRAMES)) {
err("VIDIOCMCAPTURE: vm.frame=%d. !E [0,1]", vm->frame); err("VIDIOCMCAPTURE: vm.frame=%d. !E [0-%d]", vm->frame, USBVIDEO_NUMFRAMES-1);
return -EINVAL; return -EINVAL;
} }
if (uvd->frame[vm->frame].frameState == FrameState_Grabbing) { if (uvd->frame[vm->frame].frameState == FrameState_Grabbing) {
...@@ -1618,7 +1620,7 @@ static int usbvideo_v4l_read(struct file *file, char *buf, ...@@ -1618,7 +1620,7 @@ static int usbvideo_v4l_read(struct file *file, char *buf,
static const char proc[] = "usbvideo_v4l_read"; static const char proc[] = "usbvideo_v4l_read";
uvd_t *uvd = file->private_data; uvd_t *uvd = file->private_data;
int noblock = file->f_flags & O_NONBLOCK; int noblock = file->f_flags & O_NONBLOCK;
int frmx = -1; int frmx = -1, i;
usbvideo_frame_t *frame; usbvideo_frame_t *frame;
if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL)) if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL))
...@@ -1630,14 +1632,13 @@ static int usbvideo_v4l_read(struct file *file, char *buf, ...@@ -1630,14 +1632,13 @@ static int usbvideo_v4l_read(struct file *file, char *buf,
down(&uvd->lock); down(&uvd->lock);
/* See if a frame is completed, then use it. */ /* See if a frame is completed, then use it. */
if ((uvd->frame[0].frameState == FrameState_Done) || for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
(uvd->frame[0].frameState == FrameState_Done_Hold) || if ((uvd->frame[i].frameState == FrameState_Done) ||
(uvd->frame[0].frameState == FrameState_Error)) { (uvd->frame[i].frameState == FrameState_Done_Hold) ||
frmx = 0; (uvd->frame[i].frameState == FrameState_Error)) {
} else if ((uvd->frame[1].frameState >= FrameState_Done) || frmx = i;
(uvd->frame[1].frameState == FrameState_Done_Hold) || break;
(uvd->frame[1].frameState >= FrameState_Done)) { }
frmx = 1;
} }
/* FIXME: If we don't start a frame here then who ever does? */ /* FIXME: If we don't start a frame here then who ever does? */
...@@ -1652,10 +1653,12 @@ static int usbvideo_v4l_read(struct file *file, char *buf, ...@@ -1652,10 +1653,12 @@ static int usbvideo_v4l_read(struct file *file, char *buf,
* We will need to wait until it becomes cooked, of course. * We will need to wait until it becomes cooked, of course.
*/ */
if (frmx == -1) { if (frmx == -1) {
if (uvd->frame[0].frameState == FrameState_Grabbing) for(i = 0; i < USBVIDEO_NUMFRAMES; i++) {
frmx = 0; if (uvd->frame[i].frameState == FrameState_Grabbing) {
else if (uvd->frame[1].frameState == FrameState_Grabbing) frmx = i;
frmx = 1; break;
}
}
} }
/* /*
...@@ -1753,7 +1756,7 @@ static int usbvideo_v4l_read(struct file *file, char *buf, ...@@ -1753,7 +1756,7 @@ static int usbvideo_v4l_read(struct file *file, char *buf,
/* Mark it as available to be used again. */ /* Mark it as available to be used again. */
uvd->frame[frmx].frameState = FrameState_Unused; uvd->frame[frmx].frameState = FrameState_Unused;
if (usbvideo_NewFrame(uvd, frmx ? 0 : 1)) { if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES)) {
err("%s: usbvideo_NewFrame failed.", proc); err("%s: usbvideo_NewFrame failed.", proc);
} }
} }
...@@ -1990,7 +1993,7 @@ static int usbvideo_NewFrame(uvd_t *uvd, int framenum) ...@@ -1990,7 +1993,7 @@ static int usbvideo_NewFrame(uvd_t *uvd, int framenum)
uvd->settingsAdjusted = 1; uvd->settingsAdjusted = 1;
} }
n = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES; n = (framenum + 1) % USBVIDEO_NUMFRAMES;
if (uvd->frame[n].frameState == FrameState_Ready) if (uvd->frame[n].frameState == FrameState_Ready)
framenum = n; framenum = n;
...@@ -2022,7 +2025,8 @@ static int usbvideo_NewFrame(uvd_t *uvd, int framenum) ...@@ -2022,7 +2025,8 @@ static int usbvideo_NewFrame(uvd_t *uvd, int framenum)
*/ */
if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) { if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) {
/* This copies previous frame into this one to mask losses */ /* This copies previous frame into this one to mask losses */
memmove(frame->data, uvd->frame[1-framenum].data, uvd->max_frame_size); int prev = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
memmove(frame->data, uvd->frame[prev].data, uvd->max_frame_size);
} else { } else {
if (uvd->flags & FLAGS_CLEAN_FRAMES) { if (uvd->flags & FLAGS_CLEAN_FRAMES) {
/* This provides a "clean" frame but slows things down */ /* This provides a "clean" frame but slows things down */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment