aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/usb
diff options
context:
space:
mode:
authorFrank Schaefer2012-11-08 14:11:33 -0300
committerMauro Carvalho Chehab2012-12-22 17:55:34 -0200
commitc02ec71b014ea7bc6f50deb9db765bf57d593c53 (patch)
treed912f8c28c09895da71a1aa3e7afbb8c976a1e94 /drivers/media/usb
parent2f5741aa6a71aea6bc8f186e8753f270ae8742f1 (diff)
[media] em28xx: fix wrong data offset for non-interlaced mode in em28xx_copy_video
em28xx_copy_video uses a wrong offset for the target buffer when copying the data from an USB isoc packet. This happens only for the second and all following lines in the packet. The reason why this bug doesn't cause image corruption with my test device (SilverCrest Webcam 1.3 MPix) is, that this device never sends any packets that cross the end of a line. I don't know if all devices behave like this, so this patch should be considered for stable. With the upcoming patches to add support for USB bulk transfers, em28xx_copy_video will be called once per URB, which will always trigger this bug. Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/em28xx/em28xx-video.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
index 766ad125fc08..202e00bb2b6e 100644
--- a/drivers/media/usb/em28xx/em28xx-video.c
+++ b/drivers/media/usb/em28xx/em28xx-video.c
@@ -207,15 +207,10 @@ static void em28xx_copy_video(struct em28xx *dev,
startread = p;
remain = len;
- if (dev->progressive)
+ if (dev->progressive || buf->top_field)
fieldstart = outp;
- else {
- /* Interlaces two half frames */
- if (buf->top_field)
- fieldstart = outp;
- else
- fieldstart = outp + bytesperline;
- }
+ else /* interlaced mode, even nr. of lines */
+ fieldstart = outp + bytesperline;
linesdone = dma_q->pos / bytesperline;
currlinedone = dma_q->pos % bytesperline;
@@ -243,7 +238,10 @@ static void em28xx_copy_video(struct em28xx *dev,
remain -= lencopy;
while (remain > 0) {
- startwrite += lencopy + bytesperline;
+ if (dev->progressive)
+ startwrite += lencopy;
+ else
+ startwrite += lencopy + bytesperline;
startread += lencopy;
if (bytesperline > remain)
lencopy = remain;