ivtv-vbi.c revision 1a0adaf37c30e89e44d1470ef604a930999a5826
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
26static 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
35void vbi_schedule_work(struct ivtv *itv)
36{
37	queue_work(itv->vbi.work_queues, &itv->vbi.work_queue);
38}
39
40static 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
100static 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
157static 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
219ssize_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. */
294static 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 */
320static 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
356void 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
444void 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
457void 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}
546