]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/video/ivtv/ivtv-vbi.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[karo-tx-linux.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 ivtv_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 }