blob: e1c347e5ebd8b25101475b5b9fc4d5f558ab449f [file] [log] [blame]
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001/*
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"
Hans Verkuil33c0fca2007-08-23 06:32:46 -030021#include "ivtv-i2c.h"
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030022#include "ivtv-ioctl.h"
23#include "ivtv-queue.h"
Hans Verkuil67ec09f2008-11-29 19:38:23 -030024#include "ivtv-cards.h"
Hans Verkuil33c0fca2007-08-23 06:32:46 -030025#include "ivtv-vbi.h"
26
Hans Verkuil2f3a9892007-08-25 14:11:23 -030027static void ivtv_set_vps(struct ivtv *itv, int enabled)
Hans Verkuil33c0fca2007-08-23 06:32:46 -030028{
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;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030036 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];
Hans Verkuil32cd5272010-03-14 09:57:30 -030041 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
Hans Verkuil33c0fca2007-08-23 06:32:46 -030042}
43
Hans Verkuil2f3a9892007-08-25 14:11:23 -030044static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
Hans Verkuil33c0fca2007-08-23 06:32:46 -030045{
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;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030053 data.data[0] = cc->odd[0];
54 data.data[1] = cc->odd[1];
Hans Verkuil32cd5272010-03-14 09:57:30 -030055 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
Hans Verkuil33c0fca2007-08-23 06:32:46 -030056 data.field = 1;
57 data.line = (mode & 2) ? 21 : 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030058 data.data[0] = cc->even[0];
59 data.data[1] = cc->even[1];
Hans Verkuil32cd5272010-03-14 09:57:30 -030060 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
Hans Verkuil33c0fca2007-08-23 06:32:46 -030061}
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;
Hans Verkuil32cd5272010-03-14 09:57:30 -030083 ivtv_call_hw(itv, IVTV_HW_SAA7127, vbi, s_vbi_data, &data);
Hans Verkuil33c0fca2007-08-23 06:32:46 -030084}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030085
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
Hans Verkuil2f3a9892007-08-25 14:11:23 -030095void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030096{
Hans Verkuil2f3a9892007-08-25 14:11:23 -030097 struct vbi_info *vi = &itv->vbi;
98 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030099 int found_cc = 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300100 size_t i;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300101
102 for (i = 0; i < cnt; i++) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300103 const struct v4l2_sliced_vbi_data *d = sliced + i;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300104
105 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300106 if (d->field) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300107 cc.even[0] = d->data[0];
108 cc.even[1] = d->data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300109 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300110 cc.odd[0] = d->data[0];
111 cc.odd[1] = d->data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300112 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300113 found_cc = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300114 }
115 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300116 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 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300127 }
128 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300129 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 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300135 }
136 }
Dan Carpenterd72d7c12010-03-17 12:11:56 -0300137 if (found_cc && vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300138 vi->cc_payload[vi->cc_payload_idx++] = cc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300139 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));
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300173 dst[sd + 12 + line * 43] =
174 ivtv_service2vbi(itv->vbi.sliced_data[i].id);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300175 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);
Andy Walls6e1a63722009-03-14 20:03:26 -0300188 cpu_to_le32s(&linemask[0]);
189 cpu_to_le32s(&linemask[1]);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300190 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 {
Hans Verkuil51a99c02007-08-18 15:16:00 -0300217 /* unknown VBI data, convert to empty VBI frame */
218 linemask[0] = linemask[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300219 }
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
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300265/* 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;
Hans Verkuild526afe2008-09-03 16:47:14 -0300299 unsigned lines = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300300
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;
Hans Verkuil32cd5272010-03-14 09:57:30 -0300319 v4l2_subdev_call(itv->sd_video, vbi, decode_vbi_line, &vbi);
Hans Verkuild526afe2008-09-03 16:47:14 -0300320 if (vbi.type && !(lines & (1 << vbi.line))) {
321 lines |= 1 << vbi.line;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300322 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 */
Hans Verkuila8b86432008-10-04 08:05:30 -0300340 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300341 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
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300415 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
416 cnt / sizeof(itv->vbi.sliced_dec_data[0]));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300417 return;
418 }
419}
420
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300421void ivtv_disable_cc(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300422{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300423 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
424
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300425 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300426 ivtv_set_cc(itv, 0, &cc);
427 itv->vbi.cc_payload_idx = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300428}
429
Hans Verkuil1e13f9e2007-03-10 06:52:02 -0300430
Hans Verkuildc02d502007-05-19 14:07:16 -0300431void ivtv_vbi_work_handler(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300432{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300433 struct vbi_info *vi = &itv->vbi;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300434 struct v4l2_sliced_vbi_data data;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300435 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300436
437 /* Lock */
438 if (itv->output_mode == OUT_PASSTHROUGH) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300439 if (itv->is_50hz) {
440 data.id = V4L2_SLICED_WSS_625;
441 data.field = 0;
442
Hans Verkuil32cd5272010-03-14 09:57:30 -0300443 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300444 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300445 vi->wss_missing_cnt = 0;
446 } else if (vi->wss_missing_cnt == 4) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300447 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
448 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300449 vi->wss_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300450 }
451 }
452 else {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300453 int mode = 0;
454
455 data.id = V4L2_SLICED_CAPTION_525;
456 data.field = 0;
Hans Verkuil32cd5272010-03-14 09:57:30 -0300457 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300458 mode |= 1;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300459 cc.odd[0] = data.data[0];
460 cc.odd[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300461 }
462 data.field = 1;
Hans Verkuil32cd5272010-03-14 09:57:30 -0300463 if (v4l2_subdev_call(itv->sd_video, vbi, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300464 mode |= 2;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300465 cc.even[0] = data.data[0];
466 cc.even[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300467 }
468 if (mode) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300469 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);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300473 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300474 vi->cc_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300475 }
476 }
477 return;
478 }
479
480 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300481 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300482 }
483
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300484 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);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300488 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300489 while (vi->cc_payload_idx) {
490 cc = vi->cc_payload[0];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300491
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300492 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)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300496 continue;
497
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300498 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300499 break;
500 }
501 }
502
503 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300504 ivtv_set_vps(itv, 1);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300505 }
506}