aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx231xx
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@hauppauge.com>2010-07-08 14:45:13 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:17:18 -0400
commit99d35a0e4c5f90fedd08b378be880308e3ef8cb3 (patch)
treebf77705c22c55550a16514f0d8a043fa1dea77fe /drivers/media/video/cx231xx
parentadc0356e9ba59b9b014a58c9e117b10c9ce522d9 (diff)
[media] cx231xx: Ensure VBI fields are sent in the correct order
The current code was sending one videobuf per field (despite having specified V4L2_FIELD_SEQ_TB during setup). As a result, application which used the read() interface would work, except they would sometimes have the fields reversed (depending on the luck of which field the device was on when the application started VBI capture). The net effect was that CC decoding would only work about 50% of the time. Restructure the VBI code a bit so that works like all the other drivers, such that both fields are delivered in a single videobuf buffer, which ensures that they are always received in a predictable order. Signed-off-by: Devin Heitmueller <dheitmueller@hauppauge.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx231xx')
-rw-r--r--drivers/media/video/cx231xx/cx231xx-vbi.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c
index d2147cadbfce..1d914488dbb3 100644
--- a/drivers/media/video/cx231xx/cx231xx-vbi.c
+++ b/drivers/media/video/cx231xx/cx231xx-vbi.c
@@ -180,7 +180,7 @@ vbi_buffer_setup(struct videobuf_queue *vq, unsigned int *count,
180 height = ((dev->norm & V4L2_STD_625_50) ? 180 height = ((dev->norm & V4L2_STD_625_50) ?
181 PAL_VBI_LINES : NTSC_VBI_LINES); 181 PAL_VBI_LINES : NTSC_VBI_LINES);
182 182
183 *size = (dev->width * height * 2); 183 *size = (dev->width * height * 2 * 2);
184 if (0 == *count) 184 if (0 == *count)
185 *count = CX231XX_DEF_VBI_BUF; 185 *count = CX231XX_DEF_VBI_BUF;
186 186
@@ -230,7 +230,7 @@ vbi_buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
230 230
231 height = ((dev->norm & V4L2_STD_625_50) ? 231 height = ((dev->norm & V4L2_STD_625_50) ?
232 PAL_VBI_LINES : NTSC_VBI_LINES); 232 PAL_VBI_LINES : NTSC_VBI_LINES);
233 buf->vb.size = ((dev->width << 1) * height); 233 buf->vb.size = ((dev->width << 1) * height * 2);
234 234
235 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 235 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
236 return -EINVAL; 236 return -EINVAL;
@@ -549,8 +549,13 @@ u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
549 struct cx231xx_buffer *buf; 549 struct cx231xx_buffer *buf;
550 u32 _line_size = dev->width * 2; 550 u32 _line_size = dev->width * 2;
551 551
552 if (dma_q->current_field != field_number) 552 if (dma_q->current_field == -1) {
553 /* Just starting up */
553 cx231xx_reset_vbi_buffer(dev, dma_q); 554 cx231xx_reset_vbi_buffer(dev, dma_q);
555 }
556
557 if (dma_q->current_field != field_number)
558 dma_q->lines_completed = 0;
554 559
555 /* get the buffer pointer */ 560 /* get the buffer pointer */
556 buf = dev->vbi_mode.bulk_ctl.buf; 561 buf = dev->vbi_mode.bulk_ctl.buf;
@@ -597,8 +602,8 @@ u32 cx231xx_copy_vbi_line(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
597 vbi_buffer_filled(dev, dma_q, buf); 602 vbi_buffer_filled(dev, dma_q, buf);
598 603
599 dma_q->pos = 0; 604 dma_q->pos = 0;
600 buf = NULL;
601 dma_q->lines_completed = 0; 605 dma_q->lines_completed = 0;
606 cx231xx_reset_vbi_buffer(dev, dma_q);
602 } 607 }
603 } 608 }
604 609
@@ -679,6 +684,11 @@ int cx231xx_do_vbi_copy(struct cx231xx *dev, struct cx231xx_dmaqueue *dma_q,
679 offset = (dma_q->lines_completed * _line_size) + 684 offset = (dma_q->lines_completed * _line_size) +
680 current_line_bytes_copied; 685 current_line_bytes_copied;
681 686
687 if (dma_q->current_field == 2) {
688 /* Populate the second half of the frame */
689 offset += (dev->width * 2 * dma_q->lines_per_field);
690 }
691
682 /* prepare destination address */ 692 /* prepare destination address */
683 startwrite = p_out_buffer + offset; 693 startwrite = p_out_buffer + offset;
684 694
@@ -697,5 +707,8 @@ u8 cx231xx_is_vbi_buffer_done(struct cx231xx *dev,
697 707
698 height = ((dev->norm & V4L2_STD_625_50) ? 708 height = ((dev->norm & V4L2_STD_625_50) ?
699 PAL_VBI_LINES : NTSC_VBI_LINES); 709 PAL_VBI_LINES : NTSC_VBI_LINES);
700 return (dma_q->lines_completed == height) ? 1 : 0; 710 if (dma_q->lines_completed == height && dma_q->current_field == 2)
711 return 1;
712 else
713 return 0;
701} 714}