diff options
author | Andy Walls <awalls@radix.net> | 2008-12-12 18:00:29 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:38:33 -0500 |
commit | af009cf635141858642864a26602e379e97bf7d6 (patch) | |
tree | ab533c73375ed26f2575efe5ba12a3b3f9b22d4c /drivers/media/video/cx18 | |
parent | dd073434b5285121007860914a004320d644ee7e (diff) |
V4L/DVB (9806): cx18: Enable raw VBI capture
A combined authorship patch from Hans Verkuil and Andy Walls. Raw
VBI can now be captured but requires a video capture to be in progress as well.
Signed-off-by: Andy Walls <awalls@radix.net>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.c | 8 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.h | 5 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 49 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-fileops.c | 4 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 8 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-vbi.c | 3 |
6 files changed, 59 insertions, 18 deletions
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index fb9120d95f9..e274043657d 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c | |||
@@ -51,7 +51,7 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = { | |||
51 | static const struct cx18_card cx18_card_hvr1600_esmt = { | 51 | static const struct cx18_card cx18_card_hvr1600_esmt = { |
52 | .type = CX18_CARD_HVR_1600_ESMT, | 52 | .type = CX18_CARD_HVR_1600_ESMT, |
53 | .name = "Hauppauge HVR-1600", | 53 | .name = "Hauppauge HVR-1600", |
54 | .comment = "VBI is not yet supported\n", | 54 | .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", |
55 | .v4l2_capabilities = CX18_CAP_ENCODER, | 55 | .v4l2_capabilities = CX18_CAP_ENCODER, |
56 | .hw_audio_ctrl = CX18_HW_CX23418, | 56 | .hw_audio_ctrl = CX18_HW_CX23418, |
57 | .hw_muxer = CX18_HW_CS5345, | 57 | .hw_muxer = CX18_HW_CS5345, |
@@ -97,7 +97,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { | |||
97 | static const struct cx18_card cx18_card_hvr1600_samsung = { | 97 | static const struct cx18_card cx18_card_hvr1600_samsung = { |
98 | .type = CX18_CARD_HVR_1600_SAMSUNG, | 98 | .type = CX18_CARD_HVR_1600_SAMSUNG, |
99 | .name = "Hauppauge HVR-1600 (Preproduction)", | 99 | .name = "Hauppauge HVR-1600 (Preproduction)", |
100 | .comment = "VBI is not yet supported\n", | 100 | .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", |
101 | .v4l2_capabilities = CX18_CAP_ENCODER, | 101 | .v4l2_capabilities = CX18_CAP_ENCODER, |
102 | .hw_audio_ctrl = CX18_HW_CX23418, | 102 | .hw_audio_ctrl = CX18_HW_CX23418, |
103 | .hw_muxer = CX18_HW_CS5345, | 103 | .hw_muxer = CX18_HW_CS5345, |
@@ -152,7 +152,7 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = { | |||
152 | static const struct cx18_card cx18_card_h900 = { | 152 | static const struct cx18_card cx18_card_h900 = { |
153 | .type = CX18_CARD_COMPRO_H900, | 153 | .type = CX18_CARD_COMPRO_H900, |
154 | .name = "Compro VideoMate H900", | 154 | .name = "Compro VideoMate H900", |
155 | .comment = "VBI is not yet supported\n", | 155 | .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", |
156 | .v4l2_capabilities = CX18_CAP_ENCODER, | 156 | .v4l2_capabilities = CX18_CAP_ENCODER, |
157 | .hw_audio_ctrl = CX18_HW_CX23418, | 157 | .hw_audio_ctrl = CX18_HW_CX23418, |
158 | .hw_all = CX18_HW_TUNER, | 158 | .hw_all = CX18_HW_TUNER, |
@@ -249,7 +249,7 @@ static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = { | |||
249 | static const struct cx18_card cx18_card_cnxt_raptor_pal = { | 249 | static const struct cx18_card cx18_card_cnxt_raptor_pal = { |
250 | .type = CX18_CARD_CNXT_RAPTOR_PAL, | 250 | .type = CX18_CARD_CNXT_RAPTOR_PAL, |
251 | .name = "Conexant Raptor PAL/SECAM", | 251 | .name = "Conexant Raptor PAL/SECAM", |
252 | .comment = "VBI is not yet supported\n", | 252 | .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", |
253 | .v4l2_capabilities = CX18_CAP_ENCODER, | 253 | .v4l2_capabilities = CX18_CAP_ENCODER, |
254 | .hw_audio_ctrl = CX18_HW_CX23418, | 254 | .hw_audio_ctrl = CX18_HW_CX23418, |
255 | .hw_muxer = CX18_HW_GPIO, | 255 | .hw_muxer = CX18_HW_GPIO, |
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index a54aae9ed70..6fa7bcb42dd 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h | |||
@@ -48,8 +48,9 @@ | |||
48 | 48 | ||
49 | /* V4L2 capability aliases */ | 49 | /* V4L2 capability aliases */ |
50 | #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ | 50 | #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ |
51 | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE) | 51 | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \ |
52 | /* | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */ | 52 | V4L2_CAP_VBI_CAPTURE) |
53 | /* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */ | ||
53 | 54 | ||
54 | struct cx18_card_video_input { | 55 | struct cx18_card_video_input { |
55 | u8 video_type; /* video input type */ | 56 | u8 video_type; /* video input type */ |
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index e845cd653bb..863ebf06a82 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -596,13 +596,47 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) | |||
596 | /* VBI */ | 596 | /* VBI */ |
597 | cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; | 597 | cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; |
598 | cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; | 598 | cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; |
599 | cx->vbi.raw_size = 1456; | 599 | |
600 | cx->vbi.raw_decoder_line_size = 1456; | 600 | /* |
601 | cx->vbi.raw_decoder_sav_odd_field = 0x20; | 601 | * The VBI line sizes depend on the pixel clock and the horiz rate |
602 | cx->vbi.raw_decoder_sav_even_field = 0x60; | 602 | * |
603 | cx->vbi.sliced_decoder_line_size = 272; | 603 | * (1/Fh)*(2*Fp) = Samples/line |
604 | cx->vbi.sliced_decoder_sav_odd_field = 0xB0; | 604 | * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples |
605 | cx->vbi.sliced_decoder_sav_even_field = 0xF0; | 605 | * |
606 | * Sliced VBI is sent as ancillary data during horizontal blanking | ||
607 | * Raw VBI is sent as active video samples during vertcal blanking | ||
608 | * | ||
609 | * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line | ||
610 | * length of 720 pixels @ 4:2:2 sampling. Thus... | ||
611 | * | ||
612 | * For NTSC: | ||
613 | * | ||
614 | * (1/15,734 kHz) * 2 * 13.5 MHz = 1716 samples/line = | ||
615 | * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples | ||
616 | * | ||
617 | * For PAL: | ||
618 | * | ||
619 | * (1/15,625 kHz) * 2 * 13.5 MHz = 1728 samples/line = | ||
620 | * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples | ||
621 | * | ||
622 | */ | ||
623 | |||
624 | /* CX18-AV-Core number of VBI samples output per horizontal line */ | ||
625 | cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */ | ||
626 | cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */ | ||
627 | |||
628 | /* CX18-AV-Core VBI samples/line possibly rounded up */ | ||
629 | cx->vbi.raw_size = 1444; /* Real max size is 1444 */ | ||
630 | cx->vbi.sliced_size = 284; /* Real max size is 284 */ | ||
631 | |||
632 | /* | ||
633 | * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode | ||
634 | * Task Field VerticalBlank HorizontalBlank 0 0 0 0 | ||
635 | */ | ||
636 | cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */ | ||
637 | cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */ | ||
638 | cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */ | ||
639 | cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */ | ||
606 | return 0; | 640 | return 0; |
607 | } | 641 | } |
608 | 642 | ||
@@ -635,6 +669,7 @@ static void __devinit cx18_init_struct2(struct cx18 *cx) | |||
635 | cx->av_state.aud_input = CX18_AV_AUDIO8; | 669 | cx->av_state.aud_input = CX18_AV_AUDIO8; |
636 | cx->av_state.audclk_freq = 48000; | 670 | cx->av_state.audclk_freq = 48000; |
637 | cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; | 671 | cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; |
672 | /* FIXME - 8 is NTSC value, investigate */ | ||
638 | cx->av_state.vbi_line_offset = 8; | 673 | cx->av_state.vbi_line_offset = 8; |
639 | } | 674 | } |
640 | 675 | ||
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index 1856d59e0cf..425271a2951 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -185,7 +185,9 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, | |||
185 | !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { | 185 | !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { |
186 | while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { | 186 | while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { |
187 | /* byteswap and process VBI data */ | 187 | /* byteswap and process VBI data */ |
188 | /* cx18_process_vbi_data(cx, buf, s_vbi->dma_pts, s_vbi->type); */ | 188 | cx18_process_vbi_data(cx, buf, |
189 | s_vbi->dma_pts, | ||
190 | s_vbi->type); | ||
189 | cx18_stream_put_buf_fw(s_vbi, buf); | 191 | cx18_stream_put_buf_fw(s_vbi, buf); |
190 | } | 192 | } |
191 | } | 193 | } |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index c87cd5369a4..985bad89f31 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -358,8 +358,7 @@ static void cx18_vbi_setup(struct cx18_stream *s) | |||
358 | cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); | 358 | cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); |
359 | 359 | ||
360 | /* determine number of lines and total number of VBI bytes. | 360 | /* determine number of lines and total number of VBI bytes. |
361 | A raw line takes 1443 bytes: 2 * 720 + 4 byte frame header - 1 | 361 | A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720 |
362 | The '- 1' byte is probably an unused U or V byte. Or something... | ||
363 | A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal | 362 | A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal |
364 | header, 42 data bytes + checksum (to be confirmed) */ | 363 | header, 42 data bytes + checksum (to be confirmed) */ |
365 | if (raw) { | 364 | if (raw) { |
@@ -377,14 +376,15 @@ static void cx18_vbi_setup(struct cx18_stream *s) | |||
377 | /* Lines per field */ | 376 | /* Lines per field */ |
378 | data[1] = (lines / 2) | ((lines / 2) << 16); | 377 | data[1] = (lines / 2) | ((lines / 2) << 16); |
379 | /* bytes per line */ | 378 | /* bytes per line */ |
380 | data[2] = (raw ? cx->vbi.raw_size : cx->vbi.sliced_size); | 379 | data[2] = (raw ? cx->vbi.raw_decoder_line_size |
380 | : cx->vbi.sliced_decoder_line_size); | ||
381 | /* Every X number of frames a VBI interrupt arrives | 381 | /* Every X number of frames a VBI interrupt arrives |
382 | (frames as in 25 or 30 fps) */ | 382 | (frames as in 25 or 30 fps) */ |
383 | data[3] = 1; | 383 | data[3] = 1; |
384 | /* Setup VBI for the cx25840 digitizer */ | 384 | /* Setup VBI for the cx25840 digitizer */ |
385 | if (raw) { | 385 | if (raw) { |
386 | data[4] = 0x20602060; | 386 | data[4] = 0x20602060; |
387 | data[5] = 0x30703070; | 387 | data[5] = 0x307090d0; |
388 | } else { | 388 | } else { |
389 | data[4] = 0xB0F0B0F0; | 389 | data[4] = 0xB0F0B0F0; |
390 | data[5] = 0xA0E0A0E0; | 390 | data[5] = 0xA0E0A0E0; |
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c index 03f0e81307f..fb595bd548e 100644 --- a/drivers/media/video/cx18/cx18-vbi.c +++ b/drivers/media/video/cx18/cx18-vbi.c | |||
@@ -165,6 +165,9 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, | |||
165 | 165 | ||
166 | cx18_buf_swap(buf); | 166 | cx18_buf_swap(buf); |
167 | 167 | ||
168 | /* Skip 12 bytes of header that gets stuffed in */ | ||
169 | size -= 12; | ||
170 | memcpy(p, &buf->buf[12], size); | ||
168 | type = p[3]; | 171 | type = p[3]; |
169 | 172 | ||
170 | size = buf->bytesused = compress_raw_buf(cx, p, size); | 173 | size = buf->bytesused = compress_raw_buf(cx, p, size); |