Skip to content

Commit

Permalink
V4L/DVB: em28xx: rework buffer pointer tracking for offset to start o…
Browse files Browse the repository at this point in the history
…f video

Rework the logic for tracking the amount of data copied to the VBI buffer, to
address problem found where the video lines are several bytes shifted to the
right (and the leading pixels in the first line rendered are garbage).  This
would occur because the copy function would advance the pointer when detecting
headers, but the caller would not adjust the length actually copied.

This work was sponsored by EyeMagnet Limited.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed May 18, 2010
1 parent 1744fea commit 5fee334
Showing 1 changed file with 39 additions and 22 deletions.
61 changes: 39 additions & 22 deletions drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,6 @@ static void em28xx_copy_video(struct em28xx *dev,
if (dma_q->pos + len > buf->vb.size)
len = buf->vb.size - dma_q->pos;

if (p[0] != 0x88 && p[0] != 0x22) {
em28xx_isocdbg("frame is not complete\n");
len += 4;
} else
p += 4;

startread = p;
remain = len;

Expand Down Expand Up @@ -309,14 +303,6 @@ static void em28xx_copy_vbi(struct em28xx *dev,
if (dma_q->pos + len > buf->vb.size)
len = buf->vb.size - dma_q->pos;

if ((p[0] == 0x33 && p[1] == 0x95) ||
(p[0] == 0x88 && p[1] == 0x88)) {
/* Header field, advance past it */
p += 4;
} else {
len += 4;
}

startread = p;

startwrite = outp + dma_q->pos;
Expand Down Expand Up @@ -507,8 +493,15 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)

dma_q->pos = 0;
}
if (buf != NULL)
if (buf != NULL) {
if (p[0] != 0x88 && p[0] != 0x22) {
em28xx_isocdbg("frame is not complete\n");
len += 4;
} else {
p += 4;
}
em28xx_copy_video(dev, dma_q, buf, p, outp, len);
}
}
return rc;
}
Expand Down Expand Up @@ -555,8 +548,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
continue;
}

len = urb->iso_frame_desc[i].actual_length - 4;

len = urb->iso_frame_desc[i].actual_length;
if (urb->iso_frame_desc[i].actual_length <= 0) {
/* em28xx_isocdbg("packet %d is empty",i); - spammy */
continue;
Expand All @@ -577,6 +569,17 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
dev->vbi_read = 0;
em28xx_isocdbg("VBI START HEADER!!!\n");
dev->cur_field = p[2];
p += 4;
len -= 4;
} else if (p[0] == 0x88 && p[1] == 0x88 &&
p[2] == 0x88 && p[3] == 0x88) {
/* continuation */
p += 4;
len -= 4;
} else if (p[0] == 0x22 && p[1] == 0x5a) {
/* start video */
p += 4;
len -= 4;
}

vbi_size = dev->vbi_width * dev->vbi_height;
Expand Down Expand Up @@ -631,9 +634,6 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)

if (dev->capture_type == 1) {
dev->capture_type = 2;
em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
len, (p[2] & 1) ? "odd" : "even");

if (dev->progressive || !(dev->cur_field & 1)) {
if (buf != NULL)
buffer_filled(dev, dma_q, buf);
Expand All @@ -652,8 +652,25 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)

dma_q->pos = 0;
}
if (buf != NULL && dev->capture_type == 2)
em28xx_copy_video(dev, dma_q, buf, p, outp, len);

if (buf != NULL && dev->capture_type == 2) {
if (len > 4 && p[0] == 0x88 && p[1] == 0x88 &&
p[2] == 0x88 && p[3] == 0x88) {
p += 4;
len -= 4;
}
if (len > 4 && p[0] == 0x22 && p[1] == 0x5a) {
em28xx_isocdbg("Video frame %d, len=%i, %s\n",
p[2], len, (p[2] & 1) ?
"odd" : "even");
p += 4;
len -= 4;
}

if (len > 0)
em28xx_copy_video(dev, dma_q, buf, p, outp,
len);
}
}
return rc;
}
Expand Down

0 comments on commit 5fee334

Please sign in to comment.