]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/media/video/ivtv/ivtv-vbi.c
V4L/DVB (8648): ivtv: improve CC support
[linux-2.6-omap-h63xx.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-i2c.h"
22 #include "ivtv-ioctl.h"
23 #include "ivtv-queue.h"
24 #include "ivtv-vbi.h"
25
26 static void ivtv_set_vps(struct ivtv *itv, int enabled)
27 {
28         struct v4l2_sliced_vbi_data data;
29
30         if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
31                 return;
32         data.id = V4L2_SLICED_VPS;
33         data.field = 0;
34         data.line = enabled ? 16 : 0;
35         data.data[2] = itv->vbi.vps_payload.data[0];
36         data.data[8] = itv->vbi.vps_payload.data[1];
37         data.data[9] = itv->vbi.vps_payload.data[2];
38         data.data[10] = itv->vbi.vps_payload.data[3];
39         data.data[11] = itv->vbi.vps_payload.data[4];
40         ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
41 }
42
43 static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
44 {
45         struct v4l2_sliced_vbi_data data;
46
47         if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
48                 return;
49         data.id = V4L2_SLICED_CAPTION_525;
50         data.field = 0;
51         data.line = (mode & 1) ? 21 : 0;
52         data.data[0] = cc->odd[0];
53         data.data[1] = cc->odd[1];
54         ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
55         data.field = 1;
56         data.line = (mode & 2) ? 21 : 0;
57         data.data[0] = cc->even[0];
58         data.data[1] = cc->even[1];
59         ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
60 }
61
62 static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
63 {
64         struct v4l2_sliced_vbi_data data;
65
66         if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
67                 return;
68         /* When using a 50 Hz system, always turn on the
69            wide screen signal with 4x3 ratio as the default.
70            Turning this signal on and off can confuse certain
71            TVs. As far as I can tell there is no reason not to
72            transmit this signal. */
73         if ((itv->std & V4L2_STD_625_50) && !enabled) {
74                 enabled = 1;
75                 mode = 0x08;  /* 4x3 full format */
76         }
77         data.id = V4L2_SLICED_WSS_625;
78         data.field = 0;
79         data.line = enabled ? 23 : 0;
80         data.data[0] = mode & 0xff;
81         data.data[1] = (mode >> 8) & 0xff;
82         ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
83 }
84
85 static int odd_parity(u8 c)
86 {
87         c ^= (c >> 4);
88         c ^= (c >> 2);
89         c ^= (c >> 1);
90
91         return c & 1;
92 }
93
94 void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
95 {
96         struct vbi_info *vi = &itv->vbi;
97         struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
98         int found_cc = 0;
99         size_t i;
100
101         for (i = 0; i < cnt; i++) {
102                 const struct v4l2_sliced_vbi_data *d = sliced + i;
103
104                 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
105                         if (d->field) {
106                                 cc.even[0] = d->data[0];
107                                 cc.even[1] = d->data[1];
108                         } else {
109                                 cc.odd[0] = d->data[0];
110                                 cc.odd[1] = d->data[1];
111                         }
112                         found_cc = 1;
113                 }
114                 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
115                         struct vbi_vps vps;
116
117                         vps.data[0] = d->data[2];
118                         vps.data[1] = d->data[8];
119                         vps.data[2] = d->data[9];
120                         vps.data[3] = d->data[10];
121                         vps.data[4] = d->data[11];
122                         if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
123                                 vi->vps_payload = vps;
124                                 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
125                         }
126                 }
127                 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
128                         int wss = d->data[0] | d->data[1] << 8;
129
130                         if (vi->wss_payload != wss) {
131                                 vi->wss_payload = wss;
132                                 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
133                         }
134                 }
135         }
136         if (found_cc && vi->cc_payload_idx < sizeof(vi->cc_payload)) {
137                 vi->cc_payload[vi->cc_payload_idx++] = cc;
138                 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
139         }
140 }
141
142 static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
143 {
144         int line = 0;
145         int i;
146         u32 linemask[2] = { 0, 0 };
147         unsigned short size;
148         static const u8 mpeg_hdr_data[] = {
149                 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
150                 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
151                 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
152                 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
153         };
154         const int sd = sizeof(mpeg_hdr_data);   /* start of vbi data */
155         int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
156         u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
157
158         for (i = 0; i < lines; i++) {
159                 int f, l;
160
161                 if (itv->vbi.sliced_data[i].id == 0)
162                         continue;
163
164                 l = itv->vbi.sliced_data[i].line - 6;
165                 f = itv->vbi.sliced_data[i].field;
166                 if (f)
167                         l += 18;
168                 if (l < 32)
169                         linemask[0] |= (1 << l);
170                 else
171                         linemask[1] |= (1 << (l - 32));
172                 dst[sd + 12 + line * 43] =
173                         ivtv_service2vbi(itv->vbi.sliced_data[i].id);
174                 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
175                 line++;
176         }
177         memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
178         if (line == 36) {
179                 /* All lines are used, so there is no space for the linemask
180                    (the max size of the VBI data is 36 * 43 + 4 bytes).
181                    So in this case we use the magic number 'ITV0'. */
182                 memcpy(dst + sd, "ITV0", 4);
183                 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
184                 size = 4 + ((43 * line + 3) & ~3);
185         } else {
186                 memcpy(dst + sd, "itv0", 4);
187                 memcpy(dst + sd + 4, &linemask[0], 8);
188                 size = 12 + ((43 * line + 3) & ~3);
189         }
190         dst[4+16] = (size + 10) >> 8;
191         dst[5+16] = (size + 10) & 0xff;
192         dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
193         dst[10+16] = (pts_stamp >> 22) & 0xff;
194         dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
195         dst[12+16] = (pts_stamp >> 7) & 0xff;
196         dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
197         itv->vbi.sliced_mpeg_size[idx] = sd + size;
198 }
199
200 static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
201 {
202         u32 linemask[2];
203         int i, l, id2;
204         int line = 0;
205
206         if (!memcmp(p, "itv0", 4)) {
207                 memcpy(linemask, p + 4, 8);
208                 p += 12;
209         } else if (!memcmp(p, "ITV0", 4)) {
210                 linemask[0] = 0xffffffff;
211                 linemask[1] = 0xf;
212                 p += 4;
213         } else {
214                 /* unknown VBI data, convert to empty VBI frame */
215                 linemask[0] = linemask[1] = 0;
216         }
217         for (i = 0; i < 36; i++) {
218                 int err = 0;
219
220                 if (i < 32 && !(linemask[0] & (1 << i)))
221                         continue;
222                 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
223                         continue;
224                 id2 = *p & 0xf;
225                 switch (id2) {
226                 case IVTV_SLICED_TYPE_TELETEXT_B:
227                         id2 = V4L2_SLICED_TELETEXT_B;
228                         break;
229                 case IVTV_SLICED_TYPE_CAPTION_525:
230                         id2 = V4L2_SLICED_CAPTION_525;
231                         err = !odd_parity(p[1]) || !odd_parity(p[2]);
232                         break;
233                 case IVTV_SLICED_TYPE_VPS:
234                         id2 = V4L2_SLICED_VPS;
235                         break;
236                 case IVTV_SLICED_TYPE_WSS_625:
237                         id2 = V4L2_SLICED_WSS_625;
238                         break;
239                 default:
240                         id2 = 0;
241                         break;
242                 }
243                 if (err == 0) {
244                         l = (i < 18) ? i + 6 : i - 18 + 6;
245                         itv->vbi.sliced_dec_data[line].line = l;
246                         itv->vbi.sliced_dec_data[line].field = i >= 18;
247                         itv->vbi.sliced_dec_data[line].id = id2;
248                         memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
249                         line++;
250                 }
251                 p += 43;
252         }
253         while (line < 36) {
254                 itv->vbi.sliced_dec_data[line].id = 0;
255                 itv->vbi.sliced_dec_data[line].line = 0;
256                 itv->vbi.sliced_dec_data[line].field = 0;
257                 line++;
258         }
259         return line * sizeof(itv->vbi.sliced_dec_data[0]);
260 }
261
262 /* Compress raw VBI format, removes leading SAV codes and surplus space after the
263    field.
264    Returns new compressed size. */
265 static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
266 {
267         u32 line_size = itv->vbi.raw_decoder_line_size;
268         u32 lines = itv->vbi.count;
269         u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
270         u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
271         u8 *q = buf;
272         u8 *p;
273         int i;
274
275         for (i = 0; i < lines; i++) {
276                 p = buf + i * line_size;
277
278                 /* Look for SAV code */
279                 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
280                         break;
281                 }
282                 memcpy(q, p + 4, line_size - 4);
283                 q += line_size - 4;
284         }
285         return lines * (line_size - 4);
286 }
287
288
289 /* Compressed VBI format, all found sliced blocks put next to one another
290    Returns new compressed size */
291 static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
292 {
293         u32 line_size = itv->vbi.sliced_decoder_line_size;
294         struct v4l2_decode_vbi_line vbi;
295         int i;
296         unsigned lines = 0;
297
298         /* find the first valid line */
299         for (i = 0; i < size; i++, buf++) {
300                 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
301                         break;
302         }
303
304         size -= i;
305         if (size < line_size) {
306                 return line;
307         }
308         for (i = 0; i < size / line_size; i++) {
309                 u8 *p = buf + i * line_size;
310
311                 /* Look for SAV code  */
312                 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
313                         continue;
314                 }
315                 vbi.p = p + 4;
316                 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
317                 if (vbi.type && !(lines & (1 << vbi.line))) {
318                         lines |= 1 << vbi.line;
319                         itv->vbi.sliced_data[line].id = vbi.type;
320                         itv->vbi.sliced_data[line].field = vbi.is_second_field;
321                         itv->vbi.sliced_data[line].line = vbi.line;
322                         memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
323                         line++;
324                 }
325         }
326         return line;
327 }
328
329 void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
330                            u64 pts_stamp, int streamtype)
331 {
332         u8 *p = (u8 *) buf->buf;
333         u32 size = buf->bytesused;
334         int y;
335
336         /* Raw VBI data */
337         if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
338                 u8 type;
339
340                 ivtv_buf_swap(buf);
341
342                 type = p[3];
343
344                 size = buf->bytesused = compress_raw_buf(itv, p, size);
345
346                 /* second field of the frame? */
347                 if (type == itv->vbi.raw_decoder_sav_even_field) {
348                         /* Dirty hack needed for backwards
349                            compatibility of old VBI software. */
350                         p += size - 4;
351                         memcpy(p, &itv->vbi.frame, 4);
352                         itv->vbi.frame++;
353                 }
354                 return;
355         }
356
357         /* Sliced VBI data with data insertion */
358         if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
359                 int lines;
360
361                 ivtv_buf_swap(buf);
362
363                 /* first field */
364                 lines = compress_sliced_buf(itv, 0, p, size / 2,
365                         itv->vbi.sliced_decoder_sav_odd_field);
366                 /* second field */
367                 /* experimentation shows that the second half does not always begin
368                    at the exact address. So start a bit earlier (hence 32). */
369                 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
370                         itv->vbi.sliced_decoder_sav_even_field);
371                 /* always return at least one empty line */
372                 if (lines == 0) {
373                         itv->vbi.sliced_data[0].id = 0;
374                         itv->vbi.sliced_data[0].line = 0;
375                         itv->vbi.sliced_data[0].field = 0;
376                         lines = 1;
377                 }
378                 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
379                 memcpy(p, &itv->vbi.sliced_data[0], size);
380
381                 if (itv->vbi.insert_mpeg) {
382                         copy_vbi_data(itv, lines, pts_stamp);
383                 }
384                 itv->vbi.frame++;
385                 return;
386         }
387
388         /* Sliced VBI re-inserted from an MPEG stream */
389         if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
390                 /* If the size is not 4-byte aligned, then the starting address
391                    for the swapping is also shifted. After swapping the data the
392                    real start address of the VBI data is exactly 4 bytes after the
393                    original start. It's a bit fiddly but it works like a charm.
394                    Non-4-byte alignment happens when an lseek is done on the input
395                    mpeg file to a non-4-byte aligned position. So on arrival here
396                    the VBI data is also non-4-byte aligned. */
397                 int offset = size & 3;
398                 int cnt;
399
400                 if (offset) {
401                         p += 4 - offset;
402                 }
403                 /* Swap Buffer */
404                 for (y = 0; y < size; y += 4) {
405                        swab32s((u32 *)(p + y));
406                 }
407
408                 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
409                 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
410                 buf->bytesused = cnt;
411
412                 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
413                                cnt / sizeof(itv->vbi.sliced_dec_data[0]));
414                 return;
415         }
416 }
417
418 void ivtv_disable_cc(struct ivtv *itv)
419 {
420         struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
421
422         clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
423         ivtv_set_cc(itv, 0, &cc);
424         itv->vbi.cc_payload_idx = 0;
425 }
426
427
428 void ivtv_vbi_work_handler(struct ivtv *itv)
429 {
430         struct vbi_info *vi = &itv->vbi;
431         struct v4l2_sliced_vbi_data data;
432         struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
433
434         /* Lock */
435         if (itv->output_mode == OUT_PASSTHROUGH) {
436                 if (itv->is_50hz) {
437                         data.id = V4L2_SLICED_WSS_625;
438                         data.field = 0;
439
440                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
441                                 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
442                                 vi->wss_missing_cnt = 0;
443                         } else if (vi->wss_missing_cnt == 4) {
444                                 ivtv_set_wss(itv, 1, 0x8);  /* 4x3 full format */
445                         } else {
446                                 vi->wss_missing_cnt++;
447                         }
448                 }
449                 else {
450                         int mode = 0;
451
452                         data.id = V4L2_SLICED_CAPTION_525;
453                         data.field = 0;
454                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
455                                 mode |= 1;
456                                 cc.odd[0] = data.data[0];
457                                 cc.odd[1] = data.data[1];
458                         }
459                         data.field = 1;
460                         if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
461                                 mode |= 2;
462                                 cc.even[0] = data.data[0];
463                                 cc.even[1] = data.data[1];
464                         }
465                         if (mode) {
466                                 vi->cc_missing_cnt = 0;
467                                 ivtv_set_cc(itv, mode, &cc);
468                         } else if (vi->cc_missing_cnt == 4) {
469                                 ivtv_set_cc(itv, 0, &cc);
470                         } else {
471                                 vi->cc_missing_cnt++;
472                         }
473                 }
474                 return;
475         }
476
477         if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
478                 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
479         }
480
481         if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
482                 if (vi->cc_payload_idx == 0) {
483                         clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
484                         ivtv_set_cc(itv, 3, &cc);
485                 }
486                 while (vi->cc_payload_idx) {
487                         cc = vi->cc_payload[0];
488
489                         memcpy(vi->cc_payload, vi->cc_payload + 1,
490                                         sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
491                         vi->cc_payload_idx--;
492                         if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
493                                 continue;
494
495                         ivtv_set_cc(itv, 3, &cc);
496                         break;
497                 }
498         }
499
500         if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
501                 ivtv_set_vps(itv, 1);
502         }
503 }