]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/media/video/ivtv/ivtv-vbi.c
b53ca508dacc56129e6d1af29e7e9a4d69712f73
[mv-sheeva.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 void vbi_schedule_work(struct ivtv *itv)
36 {
37         queue_work(itv->vbi.work_queues, &itv->vbi.work_queue);
38 }
39
40 static void passthrough_vbi_data(struct ivtv *itv, int cnt)
41 {
42         int wss = 0;
43         u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 };
44         u8 vps[13];
45         int found_cc = 0;
46         int found_wss = 0;
47         int found_vps = 0;
48         int cc_pos = itv->vbi.cc_pos;
49         int i;
50
51         for (i = 0; i < cnt; i++) {
52                 struct v4l2_sliced_vbi_data *d = itv->vbi.sliced_dec_data + i;
53
54                 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
55                         found_cc = 1;
56                         if (d->field) {
57                                 cc[2] = d->data[0];
58                                 cc[3] = d->data[1];
59                         } else {
60                                 cc[0] = d->data[0];
61                                 cc[1] = d->data[1];
62                         }
63                 }
64                 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
65                         memcpy(vps, d->data, sizeof(vps));
66                         found_vps = 1;
67                 }
68                 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
69                         wss = d->data[0] | d->data[1] << 8;
70                         found_wss = 1;
71                 }
72         }
73
74         if (itv->vbi.wss_found != found_wss || itv->vbi.wss != wss) {
75                 itv->vbi.wss = wss;
76                 itv->vbi.wss_found = found_wss;
77                 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
78         }
79
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);
88         }
89
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);
97         }
98 }
99
100 static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
101 {
102         int line = 0;
103         int i;
104         u32 linemask[2] = { 0, 0 };
105         unsigned short size;
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
111         };
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];
115
116         for (i = 0; i < lines; i++) {
117                 int f, l;
118
119                 if (itv->vbi.sliced_data[i].id == 0)
120                         continue;
121
122                 l = itv->vbi.sliced_data[i].line - 6;
123                 f = itv->vbi.sliced_data[i].field;
124                 if (f)
125                         l += 18;
126                 if (l < 32)
127                         linemask[0] |= (1 << l);
128                 else
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);
132                 line++;
133         }
134         memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
135         if (line == 36) {
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);
142         } else {
143                 memcpy(dst + sd, "itv0", 4);
144                 memcpy(dst + sd + 4, &linemask[0], 8);
145                 size = 12 + ((43 * line + 3) & ~3);
146         }
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;
155 }
156
157 static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
158 {
159         u32 linemask[2];
160         int i, l, id2;
161         int line = 0;
162
163         if (!memcmp(p, "itv0", 4)) {
164                 memcpy(linemask, p + 4, 8);
165                 p += 12;
166         } else if (!memcmp(p, "ITV0", 4)) {
167                 linemask[0] = 0xffffffff;
168                 linemask[1] = 0xf;
169                 p += 4;
170         } else {
171                 /* unknown VBI data stream */
172                 return 0;
173         }
174         for (i = 0; i < 36; i++) {
175                 int err = 0;
176
177                 if (i < 32 && !(linemask[0] & (1 << i)))
178                         continue;
179                 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
180                         continue;
181                 id2 = *p & 0xf;
182                 switch (id2) {
183                 case IVTV_SLICED_TYPE_TELETEXT_B:
184                         id2 = V4L2_SLICED_TELETEXT_B;
185                         break;
186                 case IVTV_SLICED_TYPE_CAPTION_525:
187                         id2 = V4L2_SLICED_CAPTION_525;
188                         err = !odd_parity(p[1]) || !odd_parity(p[2]);
189                         break;
190                 case IVTV_SLICED_TYPE_VPS:
191                         id2 = V4L2_SLICED_VPS;
192                         break;
193                 case IVTV_SLICED_TYPE_WSS_625:
194                         id2 = V4L2_SLICED_WSS_625;
195                         break;
196                 default:
197                         id2 = 0;
198                         break;
199                 }
200                 if (err == 0) {
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);
206                         line++;
207                 }
208                 p += 43;
209         }
210         while (line < 36) {
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;
214                 line++;
215         }
216         return line * sizeof(itv->vbi.sliced_dec_data[0]);
217 }
218
219 ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count)
220 {
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 };
224         int found_cc = 0;
225         int cc_pos = itv->vbi.cc_pos;
226
227         if (itv->vbi.service_set_out == 0)
228                 return -EPERM;
229
230         while (count >= sizeof(struct v4l2_sliced_vbi_data)) {
231                 switch (p->id) {
232                 case V4L2_SLICED_CAPTION_525:
233                         if (p->id == V4L2_SLICED_CAPTION_525 &&
234                             p->line == 21 &&
235                             (itv->vbi.service_set_out &
236                                 V4L2_SLICED_CAPTION_525) == 0) {
237                                 break;
238                         }
239                         found_cc = 1;
240                         if (p->field) {
241                                 cc[2] = p->data[0];
242                                 cc[3] = p->data[1];
243                         } else {
244                                 cc[0] = p->data[0];
245                                 cc[1] = p->data[1];
246                         }
247                         break;
248
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);
259                         }
260                         break;
261
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);
269                         }
270                         break;
271
272                 default:
273                         break;
274                 }
275                 count -= sizeof(*p);
276                 p++;
277         }
278
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);
286         }
287
288         return (const char __user *)p - ubuf;
289 }
290
291 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
292    field.
293    Returns new compressed size. */
294 static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
295 {
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;
300         u8 *q = buf;
301         u8 *p;
302         int i;
303
304         for (i = 0; i < lines; i++) {
305                 p = buf + i * line_size;
306
307                 /* Look for SAV code */
308                 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
309                         break;
310                 }
311                 memcpy(q, p + 4, line_size - 4);
312                 q += line_size - 4;
313         }
314         return lines * (line_size - 4);
315 }
316
317
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)
321 {
322         u32 line_size = itv->vbi.sliced_decoder_line_size;
323         struct v4l2_decode_vbi_line vbi;
324         int i;
325
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)
329                         break;
330         }
331
332         size -= i;
333         if (size < line_size) {
334                 return line;
335         }
336         for (i = 0; i < size / line_size; i++) {
337                 u8 *p = buf + i * line_size;
338
339                 /* Look for SAV code  */
340                 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
341                         continue;
342                 }
343                 vbi.p = p + 4;
344                 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
345                 if (vbi.type) {
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);
350                         line++;
351                 }
352         }
353         return line;
354 }
355
356 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
357                            u64 pts_stamp, int streamtype)
358 {
359         u8 *p = (u8 *) buf->buf;
360         u32 size = buf->bytesused;
361         int y;
362
363         /* Raw VBI data */
364         if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
365                 u8 type;
366
367                 ivtv_buf_swap(buf);
368
369                 type = p[3];
370
371                 size = buf->bytesused = compress_raw_buf(itv, p, size);
372
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. */
377                         p += size - 4;
378                         memcpy(p, &itv->vbi.frame, 4);
379                         itv->vbi.frame++;
380                 }
381                 return;
382         }
383
384         /* Sliced VBI data with data insertion */
385         if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
386                 int lines;
387
388                 ivtv_buf_swap(buf);
389
390                 /* first field */
391                 lines = compress_sliced_buf(itv, 0, p, size / 2,
392                         itv->vbi.sliced_decoder_sav_odd_field);
393                 /* second 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 */
399                 if (lines == 0) {
400                         itv->vbi.sliced_data[0].id = 0;
401                         itv->vbi.sliced_data[0].line = 0;
402                         itv->vbi.sliced_data[0].field = 0;
403                         lines = 1;
404                 }
405                 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
406                 memcpy(p, &itv->vbi.sliced_data[0], size);
407
408                 if (itv->vbi.insert_mpeg) {
409                         copy_vbi_data(itv, lines, pts_stamp);
410                 }
411                 itv->vbi.frame++;
412                 return;
413         }
414
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;
425                 int cnt;
426
427                 if (offset) {
428                         p += 4 - offset;
429                 }
430                 /* Swap Buffer */
431                 for (y = 0; y < size; y += 4) {
432                        swab32s((u32 *)(p + y));
433                 }
434
435                 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
436                 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
437                 buf->bytesused = cnt;
438
439                 passthrough_vbi_data(itv, cnt / sizeof(itv->vbi.sliced_dec_data[0]));
440                 return;
441         }
442 }
443
444 void ivtv_disable_vbi(struct ivtv *itv)
445 {
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;
453         itv->vbi.wss = 0;
454         itv->vbi.cc_pos = 0;
455 }
456
457 void vbi_work_handler(struct work_struct *work)
458 {
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;
462         DEFINE_WAIT(wait);
463
464         /* Lock */
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. */
468                 if (itv->is_50hz) {
469                         data.id = V4L2_SLICED_WSS_625;
470                         data.field = 0;
471
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 */
477                         } else {
478                                 itv->vbi.wss_no_update++;
479                         }
480                 }
481                 else {
482                         u8 c1 = 0, c2 = 0, c3 = 0, c4 = 0;
483                         int mode = 0;
484
485                         data.id = V4L2_SLICED_CAPTION_525;
486                         data.field = 0;
487                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
488                                 mode |= 1;
489                                 c1 = data.data[0];
490                                 c2 = data.data[1];
491                         }
492                         data.field = 1;
493                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
494                                 mode |= 2;
495                                 c3 = data.data[0];
496                                 c4 = data.data[1];
497                         }
498                         if (mode) {
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);
503                         } else {
504                                 itv->vbi.cc_no_update++;
505                         }
506                 }
507                 return;
508         }
509
510         if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
511                 /* Lock */
512                 ivtv_set_wss(itv, itv->vbi.wss_found, itv->vbi.wss & 0xf);
513         }
514
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);
518                 }
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];
524
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)
529                                 continue;
530
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);
535                         break;
536                 }
537         }
538
539         if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
540                 /* Lock */
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]);
544         }
545 }