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