diff options
author | Devin Heitmueller <dheitmueller@hauppauge.com> | 2010-07-08 14:45:13 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-20 23:17:18 -0400 |
commit | 99d35a0e4c5f90fedd08b378be880308e3ef8cb3 (patch) | |
tree | bf77705c22c55550a16514f0d8a043fa1dea77fe /drivers/media/video/cx231xx | |
parent | adc0356e9ba59b9b014a58c9e117b10c9ce522d9 (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.c | 23 |
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 | } |