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 void vbi_schedule_work(struct ivtv *itv)
37 queue_work(itv->vbi.work_queues, &itv->vbi.work_queue);
40 static void passthrough_vbi_data(struct ivtv *itv, int cnt)
43 u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
48 int cc_pos = itv->vbi.cc_pos;
51 for (i = 0; i < cnt; i++) {
52 struct v4l2_sliced_vbi_data *d = itv->vbi.sliced_dec_data + i;
54 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
64 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
65 memcpy(vps, d->data, sizeof(vps));
68 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
69 wss = d->data[0] | d->data[1] << 8;
74 if (itv->vbi.wss_found != found_wss || itv->vbi.wss != wss) {
76 itv->vbi.wss_found = found_wss;
77 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
80 if (found_vps || itv->vbi.vps_found) {
81 itv->vbi.vps[0] = vps[2];
82 itv->vbi.vps[1] = vps[8];
83 itv->vbi.vps[2] = vps[9];
84 itv->vbi.vps[3] = vps[10];
85 itv->vbi.vps[4] = vps[11];
86 itv->vbi.vps_found = found_vps;
87 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
90 if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) {
91 itv->vbi.cc_data_odd[cc_pos] = cc[0];
92 itv->vbi.cc_data_odd[cc_pos + 1] = cc[1];
93 itv->vbi.cc_data_even[cc_pos] = cc[2];
94 itv->vbi.cc_data_even[cc_pos + 1] = cc[3];
95 itv->vbi.cc_pos = cc_pos + 2;
96 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
100 static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
104 u32 linemask[2] = { 0, 0 };
106 static const u8 mpeg_hdr_data[] = {
107 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
108 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
109 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
110 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
112 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
113 int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
114 u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
116 for (i = 0; i < lines; i++) {
119 if (itv->vbi.sliced_data[i].id == 0)
122 l = itv->vbi.sliced_data[i].line - 6;
123 f = itv->vbi.sliced_data[i].field;
127 linemask[0] |= (1 << l);
129 linemask[1] |= (1 << (l - 32));
130 dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
131 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
134 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
136 /* All lines are used, so there is no space for the linemask
137 (the max size of the VBI data is 36 * 43 + 4 bytes).
138 So in this case we use the magic number 'ITV0'. */
139 memcpy(dst + sd, "ITV0", 4);
140 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
141 size = 4 + ((43 * line + 3) & ~3);
143 memcpy(dst + sd, "itv0", 4);
144 memcpy(dst + sd + 4, &linemask[0], 8);
145 size = 12 + ((43 * line + 3) & ~3);
147 dst[4+16] = (size + 10) >> 8;
148 dst[5+16] = (size + 10) & 0xff;
149 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
150 dst[10+16] = (pts_stamp >> 22) & 0xff;
151 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
152 dst[12+16] = (pts_stamp >> 7) & 0xff;
153 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
154 itv->vbi.sliced_mpeg_size[idx] = sd + size;
157 static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
163 if (!memcmp(p, "itv0", 4)) {
164 memcpy(linemask, p + 4, 8);
166 } else if (!memcmp(p, "ITV0", 4)) {
167 linemask[0] = 0xffffffff;
171 /* unknown VBI data stream */
174 for (i = 0; i < 36; i++) {
177 if (i < 32 && !(linemask[0] & (1 << i)))
179 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
183 case IVTV_SLICED_TYPE_TELETEXT_B:
184 id2 = V4L2_SLICED_TELETEXT_B;
186 case IVTV_SLICED_TYPE_CAPTION_525:
187 id2 = V4L2_SLICED_CAPTION_525;
188 err = !odd_parity(p[1]) || !odd_parity(p[2]);
190 case IVTV_SLICED_TYPE_VPS:
191 id2 = V4L2_SLICED_VPS;
193 case IVTV_SLICED_TYPE_WSS_625:
194 id2 = V4L2_SLICED_WSS_625;
201 l = (i < 18) ? i + 6 : i - 18 + 6;
202 itv->vbi.sliced_dec_data[line].line = l;
203 itv->vbi.sliced_dec_data[line].field = i >= 18;
204 itv->vbi.sliced_dec_data[line].id = id2;
205 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
211 itv->vbi.sliced_dec_data[line].id = 0;
212 itv->vbi.sliced_dec_data[line].line = 0;
213 itv->vbi.sliced_dec_data[line].field = 0;
216 return line * sizeof(itv->vbi.sliced_dec_data[0]);
219 ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
221 /* Should be a __user pointer, but sparse doesn't parse this bit correctly. */
222 const struct v4l2_sliced_vbi_data *p = (const struct v4l2_sliced_vbi_data *)ubuf;
223 u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
225 int cc_pos = itv->vbi.cc_pos;
227 if (itv->vbi.service_set_out == 0)
230 while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
232 case V4L2_SLICED_CAPTION_525:
233 if (p->id == V4L2_SLICED_CAPTION_525 &&
235 (itv->vbi.service_set_out &
236 V4L2_SLICED_CAPTION_525) == 0) {
249 case V4L2_SLICED_VPS:
250 if (p->line == 16 && p->field == 0 &&
251 (itv->vbi.service_set_out & V4L2_SLICED_VPS)) {
252 itv->vbi.vps[0] = p->data[2];
253 itv->vbi.vps[1] = p->data[8];
254 itv->vbi.vps[2] = p->data[9];
255 itv->vbi.vps[3] = p->data[10];
256 itv->vbi.vps[4] = p->data[11];
257 itv->vbi.vps_found = 1;
258 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
262 case V4L2_SLICED_WSS_625:
263 if (p->line == 23 && p->field == 0 &&
264 (itv->vbi.service_set_out & V4L2_SLICED_WSS_625)) {
265 /* No lock needed for WSS */
266 itv->vbi.wss = p->data[0] | (p->data[1] << 8);
267 itv->vbi.wss_found = 1;
268 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
279 if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) {
280 itv->vbi.cc_data_odd[cc_pos] = cc[0];
281 itv->vbi.cc_data_odd[cc_pos + 1] = cc[1];
282 itv->vbi.cc_data_even[cc_pos] = cc[2];
283 itv->vbi.cc_data_even[cc_pos + 1] = cc[3];
284 itv->vbi.cc_pos = cc_pos + 2;
285 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
288 return (const char __user *)p - ubuf;
291 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
293 Returns new compressed size. */
294 static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
296 u32 line_size = itv->vbi.raw_decoder_line_size;
297 u32 lines = itv->vbi.count;
298 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
299 u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
304 for (i = 0; i < lines; i++) {
305 p = buf + i * line_size;
307 /* Look for SAV code */
308 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
311 memcpy(q, p + 4, line_size - 4);
314 return lines * (line_size - 4);
318 /* Compressed VBI format, all found sliced blocks put next to one another
319 Returns new compressed size */
320 static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
322 u32 line_size = itv->vbi.sliced_decoder_line_size;
323 struct v4l2_decode_vbi_line vbi;
326 /* find the first valid line */
327 for (i = 0; i < size; i++, buf++) {
328 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
333 if (size < line_size) {
336 for (i = 0; i < size / line_size; i++) {
337 u8 *p = buf + i * line_size;
339 /* Look for SAV code */
340 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
344 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
346 itv->vbi.sliced_data[line].id = vbi.type;
347 itv->vbi.sliced_data[line].field = vbi.is_second_field;
348 itv->vbi.sliced_data[line].line = vbi.line;
349 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
356 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
357 u64 pts_stamp, int streamtype)
359 u8 *p = (u8 *) buf->buf;
360 u32 size = buf->bytesused;
364 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
371 size = buf->bytesused = compress_raw_buf(itv, p, size);
373 /* second field of the frame? */
374 if (type == itv->vbi.raw_decoder_sav_even_field) {
375 /* Dirty hack needed for backwards
376 compatibility of old VBI software. */
378 memcpy(p, &itv->vbi.frame, 4);
384 /* Sliced VBI data with data insertion */
385 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
391 lines = compress_sliced_buf(itv, 0, p, size / 2,
392 itv->vbi.sliced_decoder_sav_odd_field);
394 /* experimentation shows that the second half does not always begin
395 at the exact address. So start a bit earlier (hence 32). */
396 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
397 itv->vbi.sliced_decoder_sav_even_field);
398 /* always return at least one empty line */
400 itv->vbi.sliced_data[0].id = 0;
401 itv->vbi.sliced_data[0].line = 0;
402 itv->vbi.sliced_data[0].field = 0;
405 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
406 memcpy(p, &itv->vbi.sliced_data[0], size);
408 if (itv->vbi.insert_mpeg) {
409 copy_vbi_data(itv, lines, pts_stamp);
415 /* Sliced VBI re-inserted from an MPEG stream */
416 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
417 /* If the size is not 4-byte aligned, then the starting address
418 for the swapping is also shifted. After swapping the data the
419 real start address of the VBI data is exactly 4 bytes after the
420 original start. It's a bit fiddly but it works like a charm.
421 Non-4-byte alignment happens when an lseek is done on the input
422 mpeg file to a non-4-byte aligned position. So on arrival here
423 the VBI data is also non-4-byte aligned. */
424 int offset = size & 3;
431 for (y = 0; y < size; y += 4) {
432 swab32s((u32 *)(p + y));
435 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
436 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
437 buf->bytesused = cnt;
439 passthrough_vbi_data(itv, cnt / sizeof(itv->vbi.sliced_dec_data[0]));
444 void ivtv_disable_vbi(struct ivtv *itv)
446 clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
447 clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
448 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
449 ivtv_set_wss(itv, 0, 0);
450 ivtv_set_cc(itv, 0, 0, 0, 0, 0);
451 ivtv_set_vps(itv, 0, 0, 0, 0, 0, 0);
452 itv->vbi.vps_found = itv->vbi.wss_found = 0;
457 void vbi_work_handler(struct work_struct *work)
459 struct vbi_info *info = container_of(work, struct vbi_info, work_queue);
460 struct ivtv *itv = container_of(info, struct ivtv, vbi);
461 struct v4l2_sliced_vbi_data data;
465 if (itv->output_mode == OUT_PASSTHROUGH) {
466 /* Note: currently only the saa7115 is used in a PVR350,
467 so these commands are for now saa7115 specific. */
469 data.id = V4L2_SLICED_WSS_625;
472 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
473 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
474 itv->vbi.wss_no_update = 0;
475 } else if (itv->vbi.wss_no_update == 4) {
476 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
478 itv->vbi.wss_no_update++;
482 u8 c1 = 0, c2 = 0, c3 = 0, c4 = 0;
485 data.id = V4L2_SLICED_CAPTION_525;
487 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
493 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
499 itv->vbi.cc_no_update = 0;
500 ivtv_set_cc(itv, mode, c1, c2, c3, c4);
501 } else if (itv->vbi.cc_no_update == 4) {
502 ivtv_set_cc(itv, 0, 0, 0, 0, 0);
504 itv->vbi.cc_no_update++;
510 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
512 ivtv_set_wss(itv, itv->vbi.wss_found, itv->vbi.wss & 0xf);
515 if (test_and_clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
516 if (itv->vbi.cc_pos == 0) {
517 ivtv_set_cc(itv, 3, 0x80, 0x80, 0x80, 0x80);
519 while (itv->vbi.cc_pos) {
520 u8 cc_odd0 = itv->vbi.cc_data_odd[0];
521 u8 cc_odd1 = itv->vbi.cc_data_odd[1];
522 u8 cc_even0 = itv->vbi.cc_data_even[0];
523 u8 cc_even1 = itv->vbi.cc_data_even[1];
525 memcpy(itv->vbi.cc_data_odd, itv->vbi.cc_data_odd + 2, sizeof(itv->vbi.cc_data_odd) - 2);
526 memcpy(itv->vbi.cc_data_even, itv->vbi.cc_data_even + 2, sizeof(itv->vbi.cc_data_even) - 2);
527 itv->vbi.cc_pos -= 2;
528 if (itv->vbi.cc_pos && cc_odd0 == 0x80 && cc_odd1 == 0x80)
531 /* Send to Saa7127 */
532 ivtv_set_cc(itv, 3, cc_odd0, cc_odd1, cc_even0, cc_even1);
533 if (itv->vbi.cc_pos == 0)
534 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
539 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
541 ivtv_set_vps(itv, itv->vbi.vps_found,
542 itv->vbi.vps[0], itv->vbi.vps[1],
543 itv->vbi.vps[2], itv->vbi.vps[3], itv->vbi.vps[4]);