1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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, video, 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, video, 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, video, 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
70
71
72
73
74 if ((itv->std & V4L2_STD_625_50) && !enabled) {
75 enabled = 1;
76 mode = 0x08;
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, video, 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 < sizeof(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);
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
181
182
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
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
266
267
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
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
293
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
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
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, video, 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
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
350 if (type == itv->vbi.raw_decoder_sav_even_field) {
351
352
353 p += size - 4;
354 memcpy(p, &itv->vbi.frame, 4);
355 itv->vbi.frame++;
356 }
357 return;
358 }
359
360
361 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
362 int lines;
363
364 ivtv_buf_swap(buf);
365
366
367 lines = compress_sliced_buf(itv, 0, p, size / 2,
368 itv->vbi.sliced_decoder_sav_odd_field);
369
370
371
372 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
373 itv->vbi.sliced_decoder_sav_even_field);
374
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
392 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
393
394
395
396
397
398
399
400 int offset = size & 3;
401 int cnt;
402
403 if (offset) {
404 p += 4 - offset;
405 }
406
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
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, video, 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);
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, video, 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, video, 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