aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2010-01-22 00:34:32 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-17 23:50:14 -0400
commit5fee334039550bdd5efed9e69af7860a66a9de37 (patch)
tree8d73d74d6bbd0f50fae8fe32738909b54953d1dc /drivers
parent1744feab9a2241f2adf03be5ef8ecbd279f5944b (diff)
V4L/DVB: em28xx: rework buffer pointer tracking for offset to start of 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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 0fe20110bfd6..b6ac99de97d2 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -203,12 +203,6 @@ static void em28xx_copy_video(struct em28xx *dev,
203 if (dma_q->pos + len > buf->vb.size) 203 if (dma_q->pos + len > buf->vb.size)
204 len = buf->vb.size - dma_q->pos; 204 len = buf->vb.size - dma_q->pos;
205 205
206 if (p[0] != 0x88 && p[0] != 0x22) {
207 em28xx_isocdbg("frame is not complete\n");
208 len += 4;
209 } else
210 p += 4;
211
212 startread = p; 206 startread = p;
213 remain = len; 207 remain = len;
214 208
@@ -309,14 +303,6 @@ static void em28xx_copy_vbi(struct em28xx *dev,
309 if (dma_q->pos + len > buf->vb.size) 303 if (dma_q->pos + len > buf->vb.size)
310 len = buf->vb.size - dma_q->pos; 304 len = buf->vb.size - dma_q->pos;
311 305
312 if ((p[0] == 0x33 && p[1] == 0x95) ||
313 (p[0] == 0x88 && p[1] == 0x88)) {
314 /* Header field, advance past it */
315 p += 4;
316 } else {
317 len += 4;
318 }
319
320 startread = p; 306 startread = p;
321 307
322 startwrite = outp + dma_q->pos; 308 startwrite = outp + dma_q->pos;
@@ -507,8 +493,15 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
507 493
508 dma_q->pos = 0; 494 dma_q->pos = 0;
509 } 495 }
510 if (buf != NULL) 496 if (buf != NULL) {
497 if (p[0] != 0x88 && p[0] != 0x22) {
498 em28xx_isocdbg("frame is not complete\n");
499 len += 4;
500 } else {
501 p += 4;
502 }
511 em28xx_copy_video(dev, dma_q, buf, p, outp, len); 503 em28xx_copy_video(dev, dma_q, buf, p, outp, len);
504 }
512 } 505 }
513 return rc; 506 return rc;
514} 507}
@@ -555,8 +548,7 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
555 continue; 548 continue;
556 } 549 }
557 550
558 len = urb->iso_frame_desc[i].actual_length - 4; 551 len = urb->iso_frame_desc[i].actual_length;
559
560 if (urb->iso_frame_desc[i].actual_length <= 0) { 552 if (urb->iso_frame_desc[i].actual_length <= 0) {
561 /* em28xx_isocdbg("packet %d is empty",i); - spammy */ 553 /* em28xx_isocdbg("packet %d is empty",i); - spammy */
562 continue; 554 continue;
@@ -577,6 +569,17 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
577 dev->vbi_read = 0; 569 dev->vbi_read = 0;
578 em28xx_isocdbg("VBI START HEADER!!!\n"); 570 em28xx_isocdbg("VBI START HEADER!!!\n");
579 dev->cur_field = p[2]; 571 dev->cur_field = p[2];
572 p += 4;
573 len -= 4;
574 } else if (p[0] == 0x88 && p[1] == 0x88 &&
575 p[2] == 0x88 && p[3] == 0x88) {
576 /* continuation */
577 p += 4;
578 len -= 4;
579 } else if (p[0] == 0x22 && p[1] == 0x5a) {
580 /* start video */
581 p += 4;
582 len -= 4;
580 } 583 }
581 584
582 vbi_size = dev->vbi_width * dev->vbi_height; 585 vbi_size = dev->vbi_width * dev->vbi_height;
@@ -631,9 +634,6 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
631 634
632 if (dev->capture_type == 1) { 635 if (dev->capture_type == 1) {
633 dev->capture_type = 2; 636 dev->capture_type = 2;
634 em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
635 len, (p[2] & 1) ? "odd" : "even");
636
637 if (dev->progressive || !(dev->cur_field & 1)) { 637 if (dev->progressive || !(dev->cur_field & 1)) {
638 if (buf != NULL) 638 if (buf != NULL)
639 buffer_filled(dev, dma_q, buf); 639 buffer_filled(dev, dma_q, buf);
@@ -652,8 +652,25 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
652 652
653 dma_q->pos = 0; 653 dma_q->pos = 0;
654 } 654 }
655 if (buf != NULL && dev->capture_type == 2) 655
656 em28xx_copy_video(dev, dma_q, buf, p, outp, len); 656 if (buf != NULL && dev->capture_type == 2) {
657 if (len > 4 && p[0] == 0x88 && p[1] == 0x88 &&
658 p[2] == 0x88 && p[3] == 0x88) {
659 p += 4;
660 len -= 4;
661 }
662 if (len > 4 && p[0] == 0x22 && p[1] == 0x5a) {
663 em28xx_isocdbg("Video frame %d, len=%i, %s\n",
664 p[2], len, (p[2] & 1) ?
665 "odd" : "even");
666 p += 4;
667 len -= 4;
668 }
669
670 if (len > 0)
671 em28xx_copy_video(dev, dma_q, buf, p, outp,
672 len);
673 }
657 } 674 }
658 return rc; 675 return rc;
659} 676}