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"
22 #include "ivtv-ioctl.h"
23 #include "ivtv-queue.h"
24 #include "ivtv-cards.h"
27 static void ivtv_set_vps(struct ivtv *itv, int enabled)
29 struct v4l2_sliced_vbi_data data;
31 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
33 data.id = V4L2_SLICED_VPS;
35 data.line = enabled ? 16 : 0;
36 data.data[2] = itv->vbi.vps_payload.data[0];
37 data.data[8] = itv->vbi.vps_payload.data[1];
38 data.data[9] = itv->vbi.vps_payload.data[2];
39 data.data[10] = itv->vbi.vps_payload.data[3];
40 data.data[11] = itv->vbi.vps_payload.data[4];
41 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data);
44 static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
46 struct v4l2_sliced_vbi_data data;
48 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
50 data.id = V4L2_SLICED_CAPTION_525;
52 data.line = (mode & 1) ? 21 : 0;
53 data.data[0] = cc->odd[0];
54 data.data[1] = cc->odd[1];
55 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data);
57 data.line = (mode & 2) ? 21 : 0;
58 data.data[0] = cc->even[0];
59 data.data[1] = cc->even[1];
60 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data);
63 static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
65 struct v4l2_sliced_vbi_data data;
67 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
69 /* When using a 50 Hz system, always turn on the
70 wide screen signal with 4x3 ratio as the default.
71 Turning this signal on and off can confuse certain
72 TVs. As far as I can tell there is no reason not to
73 transmit this signal. */
74 if ((itv->std & V4L2_STD_625_50) && !enabled) {
76 mode = 0x08; /* 4x3 full format */
78 data.id = V4L2_SLICED_WSS_625;
80 data.line = enabled ? 23 : 0;
81 data.data[0] = mode & 0xff;
82 data.data[1] = (mode >> 8) & 0xff;
83 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_vbi_data, &data);
86 static int odd_parity(u8 c)
95 void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
97 struct vbi_info *vi = &itv->vbi;
98 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
102 for (i = 0; i < cnt; i++) {
103 const struct v4l2_sliced_vbi_data *d = sliced + i;
105 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
107 cc.even[0] = d->data[0];
108 cc.even[1] = d->data[1];
110 cc.odd[0] = d->data[0];
111 cc.odd[1] = d->data[1];
115 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
118 vps.data[0] = d->data[2];
119 vps.data[1] = d->data[8];
120 vps.data[2] = d->data[9];
121 vps.data[3] = d->data[10];
122 vps.data[4] = d->data[11];
123 if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
124 vi->vps_payload = vps;
125 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
128 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
129 int wss = d->data[0] | d->data[1] << 8;
131 if (vi->wss_payload != wss) {
132 vi->wss_payload = wss;
133 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
137 if (found_cc && vi->cc_payload_idx < sizeof(vi->cc_payload)) {
138 vi->cc_payload[vi->cc_payload_idx++] = cc;
139 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
143 static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
147 u32 linemask[2] = { 0, 0 };
149 static const u8 mpeg_hdr_data[] = {
150 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
151 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
152 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
153 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
155 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
156 int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
157 u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
159 for (i = 0; i < lines; i++) {
162 if (itv->vbi.sliced_data[i].id == 0)
165 l = itv->vbi.sliced_data[i].line - 6;
166 f = itv->vbi.sliced_data[i].field;
170 linemask[0] |= (1 << l);
172 linemask[1] |= (1 << (l - 32));
173 dst[sd + 12 + line * 43] =
174 ivtv_service2vbi(itv->vbi.sliced_data[i].id);
175 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
178 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
180 /* All lines are used, so there is no space for the linemask
181 (the max size of the VBI data is 36 * 43 + 4 bytes).
182 So in this case we use the magic number 'ITV0'. */
183 memcpy(dst + sd, "ITV0", 4);
184 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
185 size = 4 + ((43 * line + 3) & ~3);
187 memcpy(dst + sd, "itv0", 4);
188 memcpy(dst + sd + 4, &linemask[0], 8);
189 size = 12 + ((43 * line + 3) & ~3);
191 dst[4+16] = (size + 10) >> 8;
192 dst[5+16] = (size + 10) & 0xff;
193 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
194 dst[10+16] = (pts_stamp >> 22) & 0xff;
195 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
196 dst[12+16] = (pts_stamp >> 7) & 0xff;
197 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
198 itv->vbi.sliced_mpeg_size[idx] = sd + size;
201 static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
207 if (!memcmp(p, "itv0", 4)) {
208 memcpy(linemask, p + 4, 8);
210 } else if (!memcmp(p, "ITV0", 4)) {
211 linemask[0] = 0xffffffff;
215 /* unknown VBI data, convert to empty VBI frame */
216 linemask[0] = linemask[1] = 0;
218 for (i = 0; i < 36; i++) {
221 if (i < 32 && !(linemask[0] & (1 << i)))
223 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
227 case IVTV_SLICED_TYPE_TELETEXT_B:
228 id2 = V4L2_SLICED_TELETEXT_B;
230 case IVTV_SLICED_TYPE_CAPTION_525:
231 id2 = V4L2_SLICED_CAPTION_525;
232 err = !odd_parity(p[1]) || !odd_parity(p[2]);
234 case IVTV_SLICED_TYPE_VPS:
235 id2 = V4L2_SLICED_VPS;
237 case IVTV_SLICED_TYPE_WSS_625:
238 id2 = V4L2_SLICED_WSS_625;
245 l = (i < 18) ? i + 6 : i - 18 + 6;
246 itv->vbi.sliced_dec_data[line].line = l;
247 itv->vbi.sliced_dec_data[line].field = i >= 18;
248 itv->vbi.sliced_dec_data[line].id = id2;
249 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
255 itv->vbi.sliced_dec_data[line].id = 0;
256 itv->vbi.sliced_dec_data[line].line = 0;
257 itv->vbi.sliced_dec_data[line].field = 0;
260 return line * sizeof(itv->vbi.sliced_dec_data[0]);
263 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
265 Returns new compressed size. */
266 static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
268 u32 line_size = itv->vbi.raw_decoder_line_size;
269 u32 lines = itv->vbi.count;
270 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
271 u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
276 for (i = 0; i < lines; i++) {
277 p = buf + i * line_size;
279 /* Look for SAV code */
280 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
283 memcpy(q, p + 4, line_size - 4);
286 return lines * (line_size - 4);
290 /* Compressed VBI format, all found sliced blocks put next to one another
291 Returns new compressed size */
292 static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
294 u32 line_size = itv->vbi.sliced_decoder_line_size;
295 struct v4l2_decode_vbi_line vbi;
299 /* find the first valid line */
300 for (i = 0; i < size; i++, buf++) {
301 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
306 if (size < line_size) {
309 for (i = 0; i < size / line_size; i++) {
310 u8 *p = buf + i * line_size;
312 /* Look for SAV code */
313 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
317 v4l2_subdev_call(itv->sd_video, video, decode_vbi_line, &vbi);
318 if (vbi.type && !(lines & (1 << vbi.line))) {
319 lines |= 1 << vbi.line;
320 itv->vbi.sliced_data[line].id = vbi.type;
321 itv->vbi.sliced_data[line].field = vbi.is_second_field;
322 itv->vbi.sliced_data[line].line = vbi.line;
323 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
330 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
331 u64 pts_stamp, int streamtype)
333 u8 *p = (u8 *) buf->buf;
334 u32 size = buf->bytesused;
338 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
345 size = buf->bytesused = compress_raw_buf(itv, p, size);
347 /* second field of the frame? */
348 if (type == itv->vbi.raw_decoder_sav_even_field) {
349 /* Dirty hack needed for backwards
350 compatibility of old VBI software. */
352 memcpy(p, &itv->vbi.frame, 4);
358 /* Sliced VBI data with data insertion */
359 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
365 lines = compress_sliced_buf(itv, 0, p, size / 2,
366 itv->vbi.sliced_decoder_sav_odd_field);
368 /* experimentation shows that the second half does not always begin
369 at the exact address. So start a bit earlier (hence 32). */
370 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
371 itv->vbi.sliced_decoder_sav_even_field);
372 /* always return at least one empty line */
374 itv->vbi.sliced_data[0].id = 0;
375 itv->vbi.sliced_data[0].line = 0;
376 itv->vbi.sliced_data[0].field = 0;
379 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
380 memcpy(p, &itv->vbi.sliced_data[0], size);
382 if (itv->vbi.insert_mpeg) {
383 copy_vbi_data(itv, lines, pts_stamp);
389 /* Sliced VBI re-inserted from an MPEG stream */
390 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
391 /* If the size is not 4-byte aligned, then the starting address
392 for the swapping is also shifted. After swapping the data the
393 real start address of the VBI data is exactly 4 bytes after the
394 original start. It's a bit fiddly but it works like a charm.
395 Non-4-byte alignment happens when an lseek is done on the input
396 mpeg file to a non-4-byte aligned position. So on arrival here
397 the VBI data is also non-4-byte aligned. */
398 int offset = size & 3;
405 for (y = 0; y < size; y += 4) {
406 swab32s((u32 *)(p + y));
409 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
410 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
411 buf->bytesused = cnt;
413 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
414 cnt / sizeof(itv->vbi.sliced_dec_data[0]));
419 void ivtv_disable_cc(struct ivtv *itv)
421 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
423 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
424 ivtv_set_cc(itv, 0, &cc);
425 itv->vbi.cc_payload_idx = 0;
429 void ivtv_vbi_work_handler(struct ivtv *itv)
431 struct vbi_info *vi = &itv->vbi;
432 struct v4l2_sliced_vbi_data data;
433 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
436 if (itv->output_mode == OUT_PASSTHROUGH) {
438 data.id = V4L2_SLICED_WSS_625;
441 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
442 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
443 vi->wss_missing_cnt = 0;
444 } else if (vi->wss_missing_cnt == 4) {
445 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
447 vi->wss_missing_cnt++;
453 data.id = V4L2_SLICED_CAPTION_525;
455 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
457 cc.odd[0] = data.data[0];
458 cc.odd[1] = data.data[1];
461 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
463 cc.even[0] = data.data[0];
464 cc.even[1] = data.data[1];
467 vi->cc_missing_cnt = 0;
468 ivtv_set_cc(itv, mode, &cc);
469 } else if (vi->cc_missing_cnt == 4) {
470 ivtv_set_cc(itv, 0, &cc);
472 vi->cc_missing_cnt++;
478 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
479 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
482 if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
483 if (vi->cc_payload_idx == 0) {
484 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
485 ivtv_set_cc(itv, 3, &cc);
487 while (vi->cc_payload_idx) {
488 cc = vi->cc_payload[0];
490 memcpy(vi->cc_payload, vi->cc_payload + 1,
491 sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
492 vi->cc_payload_idx--;
493 if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
496 ivtv_set_cc(itv, 3, &cc);
501 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
502 ivtv_set_vps(itv, 1);