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 if (itv
->vbi
.service_set_out
== 0)
225 while (count
>= sizeof(struct v4l2_sliced_vbi_data
)) {
227 case V4L2_SLICED_CAPTION_525
:
228 if (p
->id
== V4L2_SLICED_CAPTION_525
&&
230 (itv
->vbi
.service_set_out
&
231 V4L2_SLICED_CAPTION_525
) == 0) {
244 case V4L2_SLICED_VPS
:
245 if (p
->line
== 16 && p
->field
== 0 &&
246 (itv
->vbi
.service_set_out
& V4L2_SLICED_VPS
)) {
247 itv
->vbi
.vps
[0] = p
->data
[2];
248 itv
->vbi
.vps
[1] = p
->data
[8];
249 itv
->vbi
.vps
[2] = p
->data
[9];
250 itv
->vbi
.vps
[3] = p
->data
[10];
251 itv
->vbi
.vps
[4] = p
->data
[11];
252 itv
->vbi
.vps_found
= 1;
253 set_bit(IVTV_F_I_UPDATE_VPS
, &itv
->i_flags
);
257 case V4L2_SLICED_WSS_625
:
258 if (p
->line
== 23 && p
->field
== 0 &&
259 (itv
->vbi
.service_set_out
& V4L2_SLICED_WSS_625
)) {
260 /* No lock needed for WSS */
261 itv
->vbi
.wss
= p
->data
[0] | (p
->data
[1] << 8);
262 itv
->vbi
.wss_found
= 1;
263 set_bit(IVTV_F_I_UPDATE_WSS
, &itv
->i_flags
);
274 if (found_cc
&& cc_pos
< sizeof(itv
->vbi
.cc_data_even
)) {
275 itv
->vbi
.cc_data_odd
[cc_pos
] = cc
[0];
276 itv
->vbi
.cc_data_odd
[cc_pos
+ 1] = cc
[1];
277 itv
->vbi
.cc_data_even
[cc_pos
] = cc
[2];
278 itv
->vbi
.cc_data_even
[cc_pos
+ 1] = cc
[3];
279 itv
->vbi
.cc_pos
= cc_pos
+ 2;
280 set_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
);
283 return (const char __user
*)p
- ubuf
;
286 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
288 Returns new compressed size. */
289 static u32
compress_raw_buf(struct ivtv
*itv
, u8
*buf
, u32 size
)
291 u32 line_size
= itv
->vbi
.raw_decoder_line_size
;
292 u32 lines
= itv
->vbi
.count
;
293 u8 sav1
= itv
->vbi
.raw_decoder_sav_odd_field
;
294 u8 sav2
= itv
->vbi
.raw_decoder_sav_even_field
;
299 for (i
= 0; i
< lines
; i
++) {
300 p
= buf
+ i
* line_size
;
302 /* Look for SAV code */
303 if (p
[0] != 0xff || p
[1] || p
[2] || (p
[3] != sav1
&& p
[3] != sav2
)) {
306 memcpy(q
, p
+ 4, line_size
- 4);
309 return lines
* (line_size
- 4);
313 /* Compressed VBI format, all found sliced blocks put next to one another
314 Returns new compressed size */
315 static u32
compress_sliced_buf(struct ivtv
*itv
, u32 line
, u8
*buf
, u32 size
, u8 sav
)
317 u32 line_size
= itv
->vbi
.sliced_decoder_line_size
;
318 struct v4l2_decode_vbi_line vbi
;
321 /* find the first valid line */
322 for (i
= 0; i
< size
; i
++, buf
++) {
323 if (buf
[0] == 0xff && !buf
[1] && !buf
[2] && buf
[3] == sav
)
328 if (size
< line_size
) {
331 for (i
= 0; i
< size
/ line_size
; i
++) {
332 u8
*p
= buf
+ i
* line_size
;
334 /* Look for SAV code */
335 if (p
[0] != 0xff || p
[1] || p
[2] || p
[3] != sav
) {
339 itv
->video_dec_func(itv
, VIDIOC_INT_DECODE_VBI_LINE
, &vbi
);
341 itv
->vbi
.sliced_data
[line
].id
= vbi
.type
;
342 itv
->vbi
.sliced_data
[line
].field
= vbi
.is_second_field
;
343 itv
->vbi
.sliced_data
[line
].line
= vbi
.line
;
344 memcpy(itv
->vbi
.sliced_data
[line
].data
, vbi
.p
, 42);
351 void ivtv_process_vbi_data(struct ivtv
*itv
, struct ivtv_buffer
*buf
,
352 u64 pts_stamp
, int streamtype
)
354 u8
*p
= (u8
*) buf
->buf
;
355 u32 size
= buf
->bytesused
;
359 if (streamtype
== IVTV_ENC_STREAM_TYPE_VBI
&& itv
->vbi
.sliced_in
->service_set
== 0) {
366 size
= buf
->bytesused
= compress_raw_buf(itv
, p
, size
);
368 /* second field of the frame? */
369 if (type
== itv
->vbi
.raw_decoder_sav_even_field
) {
370 /* Dirty hack needed for backwards
371 compatibility of old VBI software. */
373 memcpy(p
, &itv
->vbi
.frame
, 4);
379 /* Sliced VBI data with data insertion */
380 if (streamtype
== IVTV_ENC_STREAM_TYPE_VBI
) {
386 lines
= compress_sliced_buf(itv
, 0, p
, size
/ 2,
387 itv
->vbi
.sliced_decoder_sav_odd_field
);
389 /* experimentation shows that the second half does not always begin
390 at the exact address. So start a bit earlier (hence 32). */
391 lines
= compress_sliced_buf(itv
, lines
, p
+ size
/ 2 - 32, size
/ 2 + 32,
392 itv
->vbi
.sliced_decoder_sav_even_field
);
393 /* always return at least one empty line */
395 itv
->vbi
.sliced_data
[0].id
= 0;
396 itv
->vbi
.sliced_data
[0].line
= 0;
397 itv
->vbi
.sliced_data
[0].field
= 0;
400 buf
->bytesused
= size
= lines
* sizeof(itv
->vbi
.sliced_data
[0]);
401 memcpy(p
, &itv
->vbi
.sliced_data
[0], size
);
403 if (itv
->vbi
.insert_mpeg
) {
404 copy_vbi_data(itv
, lines
, pts_stamp
);
410 /* Sliced VBI re-inserted from an MPEG stream */
411 if (streamtype
== IVTV_DEC_STREAM_TYPE_VBI
) {
412 /* If the size is not 4-byte aligned, then the starting address
413 for the swapping is also shifted. After swapping the data the
414 real start address of the VBI data is exactly 4 bytes after the
415 original start. It's a bit fiddly but it works like a charm.
416 Non-4-byte alignment happens when an lseek is done on the input
417 mpeg file to a non-4-byte aligned position. So on arrival here
418 the VBI data is also non-4-byte aligned. */
419 int offset
= size
& 3;
426 for (y
= 0; y
< size
; y
+= 4) {
427 swab32s((u32
*)(p
+ y
));
430 cnt
= ivtv_convert_ivtv_vbi(itv
, p
+ offset
);
431 memcpy(buf
->buf
, itv
->vbi
.sliced_dec_data
, cnt
);
432 buf
->bytesused
= cnt
;
434 passthrough_vbi_data(itv
, cnt
/ sizeof(itv
->vbi
.sliced_dec_data
[0]));
439 void ivtv_disable_vbi(struct ivtv
*itv
)
441 clear_bit(IVTV_F_I_UPDATE_WSS
, &itv
->i_flags
);
442 clear_bit(IVTV_F_I_UPDATE_VPS
, &itv
->i_flags
);
443 clear_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
);
444 ivtv_set_wss(itv
, 0, 0);
445 ivtv_set_cc(itv
, 0, 0, 0, 0, 0);
446 ivtv_set_vps(itv
, 0, 0, 0, 0, 0, 0);
447 itv
->vbi
.vps_found
= itv
->vbi
.wss_found
= 0;
453 void vbi_work_handler(struct ivtv
*itv
)
455 struct v4l2_sliced_vbi_data data
;
458 if (itv
->output_mode
== OUT_PASSTHROUGH
) {
459 /* Note: currently only the saa7115 is used in a PVR350,
460 so these commands are for now saa7115 specific. */
462 data
.id
= V4L2_SLICED_WSS_625
;
465 if (itv
->video_dec_func(itv
, VIDIOC_INT_G_VBI_DATA
, &data
) == 0) {
466 ivtv_set_wss(itv
, 1, data
.data
[0] & 0xf);
467 itv
->vbi
.wss_no_update
= 0;
468 } else if (itv
->vbi
.wss_no_update
== 4) {
469 ivtv_set_wss(itv
, 1, 0x8); /* 4x3 full format */
471 itv
->vbi
.wss_no_update
++;
475 u8 c1
= 0, c2
= 0, c3
= 0, c4
= 0;
478 data
.id
= V4L2_SLICED_CAPTION_525
;
480 if (itv
->video_dec_func(itv
, VIDIOC_INT_G_VBI_DATA
, &data
) == 0) {
486 if (itv
->video_dec_func(itv
, VIDIOC_INT_G_VBI_DATA
, &data
) == 0) {
492 itv
->vbi
.cc_no_update
= 0;
493 ivtv_set_cc(itv
, mode
, c1
, c2
, c3
, c4
);
494 } else if (itv
->vbi
.cc_no_update
== 4) {
495 ivtv_set_cc(itv
, 0, 0, 0, 0, 0);
497 itv
->vbi
.cc_no_update
++;
503 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS
, &itv
->i_flags
)) {
505 ivtv_set_wss(itv
, itv
->vbi
.wss_found
, itv
->vbi
.wss
& 0xf);
508 if (test_and_clear_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
)) {
509 if (itv
->vbi
.cc_pos
== 0) {
510 ivtv_set_cc(itv
, 3, 0x80, 0x80, 0x80, 0x80);
512 while (itv
->vbi
.cc_pos
) {
513 u8 cc_odd0
= itv
->vbi
.cc_data_odd
[0];
514 u8 cc_odd1
= itv
->vbi
.cc_data_odd
[1];
515 u8 cc_even0
= itv
->vbi
.cc_data_even
[0];
516 u8 cc_even1
= itv
->vbi
.cc_data_even
[1];
518 memcpy(itv
->vbi
.cc_data_odd
, itv
->vbi
.cc_data_odd
+ 2, sizeof(itv
->vbi
.cc_data_odd
) - 2);
519 memcpy(itv
->vbi
.cc_data_even
, itv
->vbi
.cc_data_even
+ 2, sizeof(itv
->vbi
.cc_data_even
) - 2);
520 itv
->vbi
.cc_pos
-= 2;
521 if (itv
->vbi
.cc_pos
&& cc_odd0
== 0x80 && cc_odd1
== 0x80)
524 /* Send to Saa7127 */
525 ivtv_set_cc(itv
, 3, cc_odd0
, cc_odd1
, cc_even0
, cc_even1
);
526 if (itv
->vbi
.cc_pos
== 0)
527 set_bit(IVTV_F_I_UPDATE_CC
, &itv
->i_flags
);
532 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS
, &itv
->i_flags
)) {
534 ivtv_set_vps(itv
, itv
->vbi
.vps_found
,
535 itv
->vbi
.vps
[0], itv
->vbi
.vps
[1],
536 itv
->vbi
.vps
[2], itv
->vbi
.vps
[3], itv
->vbi
.vps
[4]);