2 Vertical Blank Interval support functions
3 Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "ivtv-driver.h"
21 #include "ivtv-video.h"
23 #include "ivtv-ioctl.h"
24 #include "ivtv-queue.h"
26 static int odd_parity(u8 c
)
35 static void passthrough_vbi_data(struct ivtv
*itv
, int cnt
)
38 u8 cc
[4] = { 0x80, 0x80, 0x80, 0x80 };
43 int cc_pos
= itv
->vbi
.cc_pos
;
46 for (i
= 0; i
< cnt
; i
++) {
47 struct v4l2_sliced_vbi_data
*d
= itv
->vbi
.sliced_dec_data
+ i
;
49 if (d
->id
== V4L2_SLICED_CAPTION_525
&& d
->line
== 21) {
59 else if (d
->id
== V4L2_SLICED_VPS
&& d
->line
== 16 && d
->field
== 0) {
60 memcpy(vps
, d
->data
, sizeof(vps
));
63 else if (d
->id
== V4L2_SLICED_WSS_625
&& d
->line
== 23 && d
->field
== 0) {
64 wss
= d
->data
[0] | d
->data
[1] << 8;
69 if (itv
->vbi
.wss_found
!= found_wss
|| itv
->vbi
.wss
!= wss
) {
71 itv
->vbi
.wss_found
= found_wss
;
72 set_bit(IVTV_F_I_UPDATE_WSS
, &itv
->i_flags
);
75 if (found_vps
|| itv
->vbi
.vps_found
) {
76 itv
->vbi
.vps
[0] = vps
[2];
77 itv
->vbi
.vps
[1] = vps
[8];
78 itv
->vbi
.vps
[2] = vps
[9];
79 itv
->vbi
.vps
[3] = vps
[10];
80 itv
->vbi
.vps
[4] = vps
[11];
81 itv
->vbi
.vps_found
= found_vps
;
82 set_bit(IVTV_F_I_UPDATE_VPS
, &itv
->i_flags
);
85 if (found_cc
&& cc_pos
< sizeof(itv
->vbi
.cc_data_even
)) {
86 itv
->vbi
.cc_data_odd
[cc_pos
] = cc
[0];
87 itv
->vbi
.cc_data_odd
[cc_pos
+ 1] = cc
[1];
88 itv
->vbi
.cc_data_even
[cc_pos
] = cc
[2];
89 itv
->vbi
.cc_data_even
[cc_pos
+ 1] = cc
[3];
90 itv
->vbi
.cc_pos
= cc_pos
+ 2;
91 set_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
);
95 static void copy_vbi_data(struct ivtv
*itv
, int lines
, u32 pts_stamp
)
99 u32 linemask
[2] = { 0, 0 };
101 static const u8 mpeg_hdr_data
[] = {
102 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
103 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
104 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
105 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
107 const int sd
= sizeof(mpeg_hdr_data
); /* start of vbi data */
108 int idx
= itv
->vbi
.frame
% IVTV_VBI_FRAMES
;
109 u8
*dst
= &itv
->vbi
.sliced_mpeg_data
[idx
][0];
111 for (i
= 0; i
< lines
; i
++) {
114 if (itv
->vbi
.sliced_data
[i
].id
== 0)
117 l
= itv
->vbi
.sliced_data
[i
].line
- 6;
118 f
= itv
->vbi
.sliced_data
[i
].field
;
122 linemask
[0] |= (1 << l
);
124 linemask
[1] |= (1 << (l
- 32));
125 dst
[sd
+ 12 + line
* 43] = service2vbi(itv
->vbi
.sliced_data
[i
].id
);
126 memcpy(dst
+ sd
+ 12 + line
* 43 + 1, itv
->vbi
.sliced_data
[i
].data
, 42);
129 memcpy(dst
, mpeg_hdr_data
, sizeof(mpeg_hdr_data
));
131 /* All lines are used, so there is no space for the linemask
132 (the max size of the VBI data is 36 * 43 + 4 bytes).
133 So in this case we use the magic number 'ITV0'. */
134 memcpy(dst
+ sd
, "ITV0", 4);
135 memcpy(dst
+ sd
+ 4, dst
+ sd
+ 12, line
* 43);
136 size
= 4 + ((43 * line
+ 3) & ~3);
138 memcpy(dst
+ sd
, "itv0", 4);
139 memcpy(dst
+ sd
+ 4, &linemask
[0], 8);
140 size
= 12 + ((43 * line
+ 3) & ~3);
142 dst
[4+16] = (size
+ 10) >> 8;
143 dst
[5+16] = (size
+ 10) & 0xff;
144 dst
[9+16] = 0x21 | ((pts_stamp
>> 29) & 0x6);
145 dst
[10+16] = (pts_stamp
>> 22) & 0xff;
146 dst
[11+16] = 1 | ((pts_stamp
>> 14) & 0xff);
147 dst
[12+16] = (pts_stamp
>> 7) & 0xff;
148 dst
[13+16] = 1 | ((pts_stamp
& 0x7f) << 1);
149 itv
->vbi
.sliced_mpeg_size
[idx
] = sd
+ size
;
152 static int ivtv_convert_ivtv_vbi(struct ivtv
*itv
, u8
*p
)
158 if (!memcmp(p
, "itv0", 4)) {
159 memcpy(linemask
, p
+ 4, 8);
161 } else if (!memcmp(p
, "ITV0", 4)) {
162 linemask
[0] = 0xffffffff;
166 /* unknown VBI data stream */
169 for (i
= 0; i
< 36; i
++) {
172 if (i
< 32 && !(linemask
[0] & (1 << i
)))
174 if (i
>= 32 && !(linemask
[1] & (1 << (i
- 32))))
178 case IVTV_SLICED_TYPE_TELETEXT_B
:
179 id2
= V4L2_SLICED_TELETEXT_B
;
181 case IVTV_SLICED_TYPE_CAPTION_525
:
182 id2
= V4L2_SLICED_CAPTION_525
;
183 err
= !odd_parity(p
[1]) || !odd_parity(p
[2]);
185 case IVTV_SLICED_TYPE_VPS
:
186 id2
= V4L2_SLICED_VPS
;
188 case IVTV_SLICED_TYPE_WSS_625
:
189 id2
= V4L2_SLICED_WSS_625
;
196 l
= (i
< 18) ? i
+ 6 : i
- 18 + 6;
197 itv
->vbi
.sliced_dec_data
[line
].line
= l
;
198 itv
->vbi
.sliced_dec_data
[line
].field
= i
>= 18;
199 itv
->vbi
.sliced_dec_data
[line
].id
= id2
;
200 memcpy(itv
->vbi
.sliced_dec_data
[line
].data
, p
+ 1, 42);
206 itv
->vbi
.sliced_dec_data
[line
].id
= 0;
207 itv
->vbi
.sliced_dec_data
[line
].line
= 0;
208 itv
->vbi
.sliced_dec_data
[line
].field
= 0;
211 return line
* sizeof(itv
->vbi
.sliced_dec_data
[0]);
214 ssize_t
ivtv_write_vbi(struct ivtv
*itv
, const char __user
*ubuf
, size_t count
)
216 /* Should be a __user pointer, but sparse doesn't parse this bit correctly. */
217 const struct v4l2_sliced_vbi_data
*p
= (const struct v4l2_sliced_vbi_data
*)ubuf
;
218 u8 cc
[4] = { 0x80, 0x80, 0x80, 0x80 };
220 int cc_pos
= itv
->vbi
.cc_pos
;
222 while (count
>= sizeof(struct v4l2_sliced_vbi_data
)) {
224 case V4L2_SLICED_CAPTION_525
:
237 case V4L2_SLICED_VPS
:
238 if (p
->line
== 16 && p
->field
== 0) {
239 itv
->vbi
.vps
[0] = p
->data
[2];
240 itv
->vbi
.vps
[1] = p
->data
[8];
241 itv
->vbi
.vps
[2] = p
->data
[9];
242 itv
->vbi
.vps
[3] = p
->data
[10];
243 itv
->vbi
.vps
[4] = p
->data
[11];
244 itv
->vbi
.vps_found
= 1;
245 set_bit(IVTV_F_I_UPDATE_VPS
, &itv
->i_flags
);
249 case V4L2_SLICED_WSS_625
:
250 if (p
->line
== 23 && p
->field
== 0) {
251 /* No lock needed for WSS */
252 itv
->vbi
.wss
= p
->data
[0] | (p
->data
[1] << 8);
253 itv
->vbi
.wss_found
= 1;
254 set_bit(IVTV_F_I_UPDATE_WSS
, &itv
->i_flags
);
265 if (found_cc
&& cc_pos
< sizeof(itv
->vbi
.cc_data_even
)) {
266 itv
->vbi
.cc_data_odd
[cc_pos
] = cc
[0];
267 itv
->vbi
.cc_data_odd
[cc_pos
+ 1] = cc
[1];
268 itv
->vbi
.cc_data_even
[cc_pos
] = cc
[2];
269 itv
->vbi
.cc_data_even
[cc_pos
+ 1] = cc
[3];
270 itv
->vbi
.cc_pos
= cc_pos
+ 2;
271 set_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
);
274 return (const char __user
*)p
- ubuf
;
277 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
279 Returns new compressed size. */
280 static u32
compress_raw_buf(struct ivtv
*itv
, u8
*buf
, u32 size
)
282 u32 line_size
= itv
->vbi
.raw_decoder_line_size
;
283 u32 lines
= itv
->vbi
.count
;
284 u8 sav1
= itv
->vbi
.raw_decoder_sav_odd_field
;
285 u8 sav2
= itv
->vbi
.raw_decoder_sav_even_field
;
290 for (i
= 0; i
< lines
; i
++) {
291 p
= buf
+ i
* line_size
;
293 /* Look for SAV code */
294 if (p
[0] != 0xff || p
[1] || p
[2] || (p
[3] != sav1
&& p
[3] != sav2
)) {
297 memcpy(q
, p
+ 4, line_size
- 4);
300 return lines
* (line_size
- 4);
304 /* Compressed VBI format, all found sliced blocks put next to one another
305 Returns new compressed size */
306 static u32
compress_sliced_buf(struct ivtv
*itv
, u32 line
, u8
*buf
, u32 size
, u8 sav
)
308 u32 line_size
= itv
->vbi
.sliced_decoder_line_size
;
309 struct v4l2_decode_vbi_line vbi
;
312 /* find the first valid line */
313 for (i
= 0; i
< size
; i
++, buf
++) {
314 if (buf
[0] == 0xff && !buf
[1] && !buf
[2] && buf
[3] == sav
)
319 if (size
< line_size
) {
322 for (i
= 0; i
< size
/ line_size
; i
++) {
323 u8
*p
= buf
+ i
* line_size
;
325 /* Look for SAV code */
326 if (p
[0] != 0xff || p
[1] || p
[2] || p
[3] != sav
) {
330 itv
->video_dec_func(itv
, VIDIOC_INT_DECODE_VBI_LINE
, &vbi
);
332 itv
->vbi
.sliced_data
[line
].id
= vbi
.type
;
333 itv
->vbi
.sliced_data
[line
].field
= vbi
.is_second_field
;
334 itv
->vbi
.sliced_data
[line
].line
= vbi
.line
;
335 memcpy(itv
->vbi
.sliced_data
[line
].data
, vbi
.p
, 42);
342 void ivtv_process_vbi_data(struct ivtv
*itv
, struct ivtv_buffer
*buf
,
343 u64 pts_stamp
, int streamtype
)
345 u8
*p
= (u8
*) buf
->buf
;
346 u32 size
= buf
->bytesused
;
350 if (streamtype
== IVTV_ENC_STREAM_TYPE_VBI
&& itv
->vbi
.sliced_in
->service_set
== 0) {
357 size
= buf
->bytesused
= compress_raw_buf(itv
, p
, size
);
359 /* second field of the frame? */
360 if (type
== itv
->vbi
.raw_decoder_sav_even_field
) {
361 /* Dirty hack needed for backwards
362 compatibility of old VBI software. */
364 memcpy(p
, &itv
->vbi
.frame
, 4);
370 /* Sliced VBI data with data insertion */
371 if (streamtype
== IVTV_ENC_STREAM_TYPE_VBI
) {
377 lines
= compress_sliced_buf(itv
, 0, p
, size
/ 2,
378 itv
->vbi
.sliced_decoder_sav_odd_field
);
380 /* experimentation shows that the second half does not always begin
381 at the exact address. So start a bit earlier (hence 32). */
382 lines
= compress_sliced_buf(itv
, lines
, p
+ size
/ 2 - 32, size
/ 2 + 32,
383 itv
->vbi
.sliced_decoder_sav_even_field
);
384 /* always return at least one empty line */
386 itv
->vbi
.sliced_data
[0].id
= 0;
387 itv
->vbi
.sliced_data
[0].line
= 0;
388 itv
->vbi
.sliced_data
[0].field
= 0;
391 buf
->bytesused
= size
= lines
* sizeof(itv
->vbi
.sliced_data
[0]);
392 memcpy(p
, &itv
->vbi
.sliced_data
[0], size
);
394 if (itv
->vbi
.insert_mpeg
) {
395 copy_vbi_data(itv
, lines
, pts_stamp
);
401 /* Sliced VBI re-inserted from an MPEG stream */
402 if (streamtype
== IVTV_DEC_STREAM_TYPE_VBI
) {
403 /* If the size is not 4-byte aligned, then the starting address
404 for the swapping is also shifted. After swapping the data the
405 real start address of the VBI data is exactly 4 bytes after the
406 original start. It's a bit fiddly but it works like a charm.
407 Non-4-byte alignment happens when an lseek is done on the input
408 mpeg file to a non-4-byte aligned position. So on arrival here
409 the VBI data is also non-4-byte aligned. */
410 int offset
= size
& 3;
417 for (y
= 0; y
< size
; y
+= 4) {
418 swab32s((u32
*)(p
+ y
));
421 cnt
= ivtv_convert_ivtv_vbi(itv
, p
+ offset
);
422 memcpy(buf
->buf
, itv
->vbi
.sliced_dec_data
, cnt
);
423 buf
->bytesused
= cnt
;
425 passthrough_vbi_data(itv
, cnt
/ sizeof(itv
->vbi
.sliced_dec_data
[0]));
430 void ivtv_disable_vbi(struct ivtv
*itv
)
432 clear_bit(IVTV_F_I_UPDATE_WSS
, &itv
->i_flags
);
433 clear_bit(IVTV_F_I_UPDATE_VPS
, &itv
->i_flags
);
434 clear_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
);
435 ivtv_set_wss(itv
, 0, 0);
436 ivtv_set_cc(itv
, 0, 0, 0, 0, 0);
437 ivtv_set_vps(itv
, 0, 0, 0, 0, 0, 0);
438 itv
->vbi
.vps_found
= itv
->vbi
.wss_found
= 0;
444 void ivtv_vbi_work_handler(struct ivtv
*itv
)
446 struct v4l2_sliced_vbi_data data
;
449 if (itv
->output_mode
== OUT_PASSTHROUGH
) {
450 /* Note: currently only the saa7115 is used in a PVR350,
451 so these commands are for now saa7115 specific. */
453 data
.id
= V4L2_SLICED_WSS_625
;
456 if (itv
->video_dec_func(itv
, VIDIOC_INT_G_VBI_DATA
, &data
) == 0) {
457 ivtv_set_wss(itv
, 1, data
.data
[0] & 0xf);
458 itv
->vbi
.wss_no_update
= 0;
459 } else if (itv
->vbi
.wss_no_update
== 4) {
460 ivtv_set_wss(itv
, 1, 0x8); /* 4x3 full format */
462 itv
->vbi
.wss_no_update
++;
466 u8 c1
= 0, c2
= 0, c3
= 0, c4
= 0;
469 data
.id
= V4L2_SLICED_CAPTION_525
;
471 if (itv
->video_dec_func(itv
, VIDIOC_INT_G_VBI_DATA
, &data
) == 0) {
477 if (itv
->video_dec_func(itv
, VIDIOC_INT_G_VBI_DATA
, &data
) == 0) {
483 itv
->vbi
.cc_no_update
= 0;
484 ivtv_set_cc(itv
, mode
, c1
, c2
, c3
, c4
);
485 } else if (itv
->vbi
.cc_no_update
== 4) {
486 ivtv_set_cc(itv
, 0, 0, 0, 0, 0);
488 itv
->vbi
.cc_no_update
++;
494 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS
, &itv
->i_flags
)) {
496 ivtv_set_wss(itv
, itv
->vbi
.wss_found
, itv
->vbi
.wss
& 0xf);
499 if (test_and_clear_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
)) {
500 if (itv
->vbi
.cc_pos
== 0) {
501 ivtv_set_cc(itv
, 3, 0x80, 0x80, 0x80, 0x80);
503 while (itv
->vbi
.cc_pos
) {
504 u8 cc_odd0
= itv
->vbi
.cc_data_odd
[0];
505 u8 cc_odd1
= itv
->vbi
.cc_data_odd
[1];
506 u8 cc_even0
= itv
->vbi
.cc_data_even
[0];
507 u8 cc_even1
= itv
->vbi
.cc_data_even
[1];
509 memcpy(itv
->vbi
.cc_data_odd
, itv
->vbi
.cc_data_odd
+ 2, sizeof(itv
->vbi
.cc_data_odd
) - 2);
510 memcpy(itv
->vbi
.cc_data_even
, itv
->vbi
.cc_data_even
+ 2, sizeof(itv
->vbi
.cc_data_even
) - 2);
511 itv
->vbi
.cc_pos
-= 2;
512 if (itv
->vbi
.cc_pos
&& cc_odd0
== 0x80 && cc_odd1
== 0x80)
515 /* Send to Saa7127 */
516 ivtv_set_cc(itv
, 3, cc_odd0
, cc_odd1
, cc_even0
, cc_even1
);
517 if (itv
->vbi
.cc_pos
== 0)
518 set_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
);
523 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS
, &itv
->i_flags
)) {
525 ivtv_set_vps(itv
, itv
->vbi
.vps_found
,
526 itv
->vbi
.vps
[0], itv
->vbi
.vps
[1],
527 itv
->vbi
.vps
[2], itv
->vbi
.vps
[3], itv
->vbi
.vps
[4]);