]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/media/video/ivtv/ivtv-vbi.c
Merge /pub/scm/linux/kernel/git/torvalds/linux-2.6
[mirror_ubuntu-artful-kernel.git] / drivers / media / video / ivtv / ivtv-vbi.c
1 /*
2 Vertical Blank Interval support functions
3 Copyright (C) 2004-2007 Hans Verkuil <hverkuil@xs4all.nl>
4
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.
9
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.
14
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
18 */
19
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"
25
26 static int odd_parity(u8 c)
27 {
28 c ^= (c >> 4);
29 c ^= (c >> 2);
30 c ^= (c >> 1);
31
32 return c & 1;
33 }
34
35 static void passthrough_vbi_data(struct ivtv *itv, int cnt)
36 {
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;
45
46 for (i = 0; i < cnt; i++) {
47 struct v4l2_sliced_vbi_data *d = itv->vbi.sliced_dec_data + i;
48
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];
57 }
58 }
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;
62 }
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;
66 }
67 }
68
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);
73 }
74
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);
83 }
84
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);
92 }
93 }
94
95 static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
96 {
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
106 };
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];
110
111 for (i = 0; i < lines; i++) {
112 int f, l;
113
114 if (itv->vbi.sliced_data[i].id == 0)
115 continue;
116
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++;
128 }
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);
141 }
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;
150 }
151
152 static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
153 {
154 u32 linemask[2];
155 int i, l, id2;
156 int line = 0;
157
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;
168 }
169 for (i = 0; i < 36; i++) {
170 int err = 0;
171
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;
194 }
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++;
202 }
203 p += 43;
204 }
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++;
210 }
211 return line * sizeof(itv->vbi.sliced_dec_data[0]);
212 }
213
214 ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
215 {
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;
221
222 if (itv->vbi.service_set_out == 0)
223 return -EPERM;
224
225 while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
226 switch (p->id) {
227 case V4L2_SLICED_CAPTION_525:
228 if (p->id == V4L2_SLICED_CAPTION_525 &&
229 p->line == 21 &&
230 (itv->vbi.service_set_out &
231 V4L2_SLICED_CAPTION_525) == 0) {
232 break;
233 }
234 found_cc = 1;
235 if (p->field) {
236 cc[2] = p->data[0];
237 cc[3] = p->data[1];
238 } else {
239 cc[0] = p->data[0];
240 cc[1] = p->data[1];
241 }
242 break;
243
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);
254 }
255 break;
256
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);
264 }
265 break;
266
267 default:
268 break;
269 }
270 count -= sizeof(*p);
271 p++;
272 }
273
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);
281 }
282
283 return (const char __user *)p - ubuf;
284 }
285
286 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
287 field.
288 Returns new compressed size. */
289 static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
290 {
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;
295 u8 *q = buf;
296 u8 *p;
297 int i;
298
299 for (i = 0; i < lines; i++) {
300 p = buf + i * line_size;
301
302 /* Look for SAV code */
303 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
304 break;
305 }
306 memcpy(q, p + 4, line_size - 4);
307 q += line_size - 4;
308 }
309 return lines * (line_size - 4);
310 }
311
312
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)
316 {
317 u32 line_size = itv->vbi.sliced_decoder_line_size;
318 struct v4l2_decode_vbi_line vbi;
319 int i;
320
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)
324 break;
325 }
326
327 size -= i;
328 if (size < line_size) {
329 return line;
330 }
331 for (i = 0; i < size / line_size; i++) {
332 u8 *p = buf + i * line_size;
333
334 /* Look for SAV code */
335 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
336 continue;
337 }
338 vbi.p = p + 4;
339 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
340 if (vbi.type) {
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);
345 line++;
346 }
347 }
348 return line;
349 }
350
351 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
352 u64 pts_stamp, int streamtype)
353 {
354 u8 *p = (u8 *) buf->buf;
355 u32 size = buf->bytesused;
356 int y;
357
358 /* Raw VBI data */
359 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
360 u8 type;
361
362 ivtv_buf_swap(buf);
363
364 type = p[3];
365
366 size = buf->bytesused = compress_raw_buf(itv, p, size);
367
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. */
372 p += size - 4;
373 memcpy(p, &itv->vbi.frame, 4);
374 itv->vbi.frame++;
375 }
376 return;
377 }
378
379 /* Sliced VBI data with data insertion */
380 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
381 int lines;
382
383 ivtv_buf_swap(buf);
384
385 /* first field */
386 lines = compress_sliced_buf(itv, 0, p, size / 2,
387 itv->vbi.sliced_decoder_sav_odd_field);
388 /* second 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 */
394 if (lines == 0) {
395 itv->vbi.sliced_data[0].id = 0;
396 itv->vbi.sliced_data[0].line = 0;
397 itv->vbi.sliced_data[0].field = 0;
398 lines = 1;
399 }
400 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
401 memcpy(p, &itv->vbi.sliced_data[0], size);
402
403 if (itv->vbi.insert_mpeg) {
404 copy_vbi_data(itv, lines, pts_stamp);
405 }
406 itv->vbi.frame++;
407 return;
408 }
409
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;
420 int cnt;
421
422 if (offset) {
423 p += 4 - offset;
424 }
425 /* Swap Buffer */
426 for (y = 0; y < size; y += 4) {
427 swab32s((u32 *)(p + y));
428 }
429
430 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
431 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
432 buf->bytesused = cnt;
433
434 passthrough_vbi_data(itv, cnt / sizeof(itv->vbi.sliced_dec_data[0]));
435 return;
436 }
437 }
438
439 void ivtv_disable_vbi(struct ivtv *itv)
440 {
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;
448 itv->vbi.wss = 0;
449 itv->vbi.cc_pos = 0;
450 }
451
452
453 void vbi_work_handler(struct ivtv *itv)
454 {
455 struct v4l2_sliced_vbi_data data;
456
457 /* Lock */
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. */
461 if (itv->is_50hz) {
462 data.id = V4L2_SLICED_WSS_625;
463 data.field = 0;
464
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 */
470 } else {
471 itv->vbi.wss_no_update++;
472 }
473 }
474 else {
475 u8 c1 = 0, c2 = 0, c3 = 0, c4 = 0;
476 int mode = 0;
477
478 data.id = V4L2_SLICED_CAPTION_525;
479 data.field = 0;
480 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
481 mode |= 1;
482 c1 = data.data[0];
483 c2 = data.data[1];
484 }
485 data.field = 1;
486 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
487 mode |= 2;
488 c3 = data.data[0];
489 c4 = data.data[1];
490 }
491 if (mode) {
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);
496 } else {
497 itv->vbi.cc_no_update++;
498 }
499 }
500 return;
501 }
502
503 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
504 /* Lock */
505 ivtv_set_wss(itv, itv->vbi.wss_found, itv->vbi.wss & 0xf);
506 }
507
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);
511 }
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];
517
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)
522 continue;
523
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);
528 break;
529 }
530 }
531
532 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
533 /* Lock */
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]);
537 }
538 }