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