RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / drivers / media / video / ivtv / ivtv-vbi.c
bloba7282a91bd9719c029badf20569b1472d5ce24ac
1 /*
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"
22 #include "ivtv-vbi.h"
23 #include "ivtv-ioctl.h"
24 #include "ivtv-queue.h"
26 static int odd_parity(u8 c)
28 c ^= (c >> 4);
29 c ^= (c >> 2);
30 c ^= (c >> 1);
32 return c & 1;
35 static void passthrough_vbi_data(struct ivtv *itv, int cnt)
37 int wss = 0;
38 u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
39 u8 vps[13];
40 int found_cc = 0;
41 int found_wss = 0;
42 int found_vps = 0;
43 int cc_pos = itv->vbi.cc_pos;
44 int i;
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) {
50 found_cc = 1;
51 if (d->field) {
52 cc[2] = d->data[0];
53 cc[3] = d->data[1];
54 } else {
55 cc[0] = d->data[0];
56 cc[1] = d->data[1];
59 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
60 memcpy(vps, d->data, sizeof(vps));
61 found_vps = 1;
63 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
64 wss = d->data[0] | d->data[1] << 8;
65 found_wss = 1;
69 if (itv->vbi.wss_found != found_wss || itv->vbi.wss != wss) {
70 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)
97 int line = 0;
98 int i;
99 u32 linemask[2] = { 0, 0 };
100 unsigned short size;
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++) {
112 int f, l;
114 if (itv->vbi.sliced_data[i].id == 0)
115 continue;
117 l = itv->vbi.sliced_data[i].line - 6;
118 f = itv->vbi.sliced_data[i].field;
119 if (f)
120 l += 18;
121 if (l < 32)
122 linemask[0] |= (1 << l);
123 else
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);
127 line++;
129 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
130 if (line == 36) {
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);
137 } else {
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)
154 u32 linemask[2];
155 int i, l, id2;
156 int line = 0;
158 if (!memcmp(p, "itv0", 4)) {
159 memcpy(linemask, p + 4, 8);
160 p += 12;
161 } else if (!memcmp(p, "ITV0", 4)) {
162 linemask[0] = 0xffffffff;
163 linemask[1] = 0xf;
164 p += 4;
165 } else {
166 /* unknown VBI data stream */
167 return 0;
169 for (i = 0; i < 36; i++) {
170 int err = 0;
172 if (i < 32 && !(linemask[0] & (1 << i)))
173 continue;
174 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
175 continue;
176 id2 = *p & 0xf;
177 switch (id2) {
178 case IVTV_SLICED_TYPE_TELETEXT_B:
179 id2 = V4L2_SLICED_TELETEXT_B;
180 break;
181 case IVTV_SLICED_TYPE_CAPTION_525:
182 id2 = V4L2_SLICED_CAPTION_525;
183 err = !odd_parity(p[1]) || !odd_parity(p[2]);
184 break;
185 case IVTV_SLICED_TYPE_VPS:
186 id2 = V4L2_SLICED_VPS;
187 break;
188 case IVTV_SLICED_TYPE_WSS_625:
189 id2 = V4L2_SLICED_WSS_625;
190 break;
191 default:
192 id2 = 0;
193 break;
195 if (err == 0) {
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);
201 line++;
203 p += 43;
205 while (line < 36) {
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;
209 line++;
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 };
219 int found_cc = 0;
220 int cc_pos = itv->vbi.cc_pos;
222 while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
223 switch (p->id) {
224 case V4L2_SLICED_CAPTION_525:
225 if (p->line == 21) {
226 found_cc = 1;
227 if (p->field) {
228 cc[2] = p->data[0];
229 cc[3] = p->data[1];
230 } else {
231 cc[0] = p->data[0];
232 cc[1] = p->data[1];
235 break;
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);
247 break;
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);
256 break;
258 default:
259 break;
261 count -= sizeof(*p);
262 p++;
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
278 field.
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;
286 u8 *q = buf;
287 u8 *p;
288 int i;
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)) {
295 break;
297 memcpy(q, p + 4, line_size - 4);
298 q += 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;
310 int i;
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)
315 break;
318 size -= i;
319 if (size < line_size) {
320 return line;
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) {
327 continue;
329 vbi.p = p + 4;
330 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
331 if (vbi.type) {
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);
336 line++;
339 return line;
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;
347 int y;
349 /* Raw VBI data */
350 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
351 u8 type;
353 ivtv_buf_swap(buf);
355 type = p[3];
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. */
363 p += size - 4;
364 memcpy(p, &itv->vbi.frame, 4);
365 itv->vbi.frame++;
367 return;
370 /* Sliced VBI data with data insertion */
371 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
372 int lines;
374 ivtv_buf_swap(buf);
376 /* first field */
377 lines = compress_sliced_buf(itv, 0, p, size / 2,
378 itv->vbi.sliced_decoder_sav_odd_field);
379 /* second 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 */
385 if (lines == 0) {
386 itv->vbi.sliced_data[0].id = 0;
387 itv->vbi.sliced_data[0].line = 0;
388 itv->vbi.sliced_data[0].field = 0;
389 lines = 1;
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);
397 itv->vbi.frame++;
398 return;
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;
411 int cnt;
413 if (offset) {
414 p += 4 - offset;
416 /* Swap Buffer */
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]));
426 return;
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;
439 itv->vbi.wss = 0;
440 itv->vbi.cc_pos = 0;
444 void ivtv_vbi_work_handler(struct ivtv *itv)
446 struct v4l2_sliced_vbi_data data;
448 /* Lock */
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. */
452 if (itv->is_50hz) {
453 data.id = V4L2_SLICED_WSS_625;
454 data.field = 0;
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 */
461 } else {
462 itv->vbi.wss_no_update++;
465 else {
466 u8 c1 = 0, c2 = 0, c3 = 0, c4 = 0;
467 int mode = 0;
469 data.id = V4L2_SLICED_CAPTION_525;
470 data.field = 0;
471 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
472 mode |= 1;
473 c1 = data.data[0];
474 c2 = data.data[1];
476 data.field = 1;
477 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
478 mode |= 2;
479 c3 = data.data[0];
480 c4 = data.data[1];
482 if (mode) {
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);
487 } else {
488 itv->vbi.cc_no_update++;
491 return;
494 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
495 /* Lock */
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)
513 continue;
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);
519 break;
523 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
524 /* Lock */
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]);