blob: 5c5d1c462fefe7cd752e2ffa77b7ddc36ae4a024 [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 Verkuil67ec09f2008-11-29 19:38:23 -030041 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, 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 Verkuil67ec09f2008-11-29 19:38:23 -030055 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, 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 Verkuil67ec09f2008-11-29 19:38:23 -030060 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, 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 Verkuil67ec09f2008-11-29 19:38:23 -030083 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, 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 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300137 if (found_cc && vi->cc_payload_idx < sizeof(vi->cc_payload)) {
138 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);
188 memcpy(dst + sd + 4, &linemask[0], 8);
189 size = 12 + ((43 * line + 3) & ~3);
190 }
191 dst[4+16] = (size + 10) >> 8;
192 dst[5+16] = (size + 10) & 0xff;
193 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
194 dst[10+16] = (pts_stamp >> 22) & 0xff;
195 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
196 dst[12+16] = (pts_stamp >> 7) & 0xff;
197 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
198 itv->vbi.sliced_mpeg_size[idx] = sd + size;
199}
200
201static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
202{
203 u32 linemask[2];
204 int i, l, id2;
205 int line = 0;
206
207 if (!memcmp(p, "itv0", 4)) {
208 memcpy(linemask, p + 4, 8);
209 p += 12;
210 } else if (!memcmp(p, "ITV0", 4)) {
211 linemask[0] = 0xffffffff;
212 linemask[1] = 0xf;
213 p += 4;
214 } else {
Hans Verkuil51a99c02007-08-18 15:16:00 -0300215 /* unknown VBI data, convert to empty VBI frame */
216 linemask[0] = linemask[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300217 }
218 for (i = 0; i < 36; i++) {
219 int err = 0;
220
221 if (i < 32 && !(linemask[0] & (1 << i)))
222 continue;
223 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
224 continue;
225 id2 = *p & 0xf;
226 switch (id2) {
227 case IVTV_SLICED_TYPE_TELETEXT_B:
228 id2 = V4L2_SLICED_TELETEXT_B;
229 break;
230 case IVTV_SLICED_TYPE_CAPTION_525:
231 id2 = V4L2_SLICED_CAPTION_525;
232 err = !odd_parity(p[1]) || !odd_parity(p[2]);
233 break;
234 case IVTV_SLICED_TYPE_VPS:
235 id2 = V4L2_SLICED_VPS;
236 break;
237 case IVTV_SLICED_TYPE_WSS_625:
238 id2 = V4L2_SLICED_WSS_625;
239 break;
240 default:
241 id2 = 0;
242 break;
243 }
244 if (err == 0) {
245 l = (i < 18) ? i + 6 : i - 18 + 6;
246 itv->vbi.sliced_dec_data[line].line = l;
247 itv->vbi.sliced_dec_data[line].field = i >= 18;
248 itv->vbi.sliced_dec_data[line].id = id2;
249 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
250 line++;
251 }
252 p += 43;
253 }
254 while (line < 36) {
255 itv->vbi.sliced_dec_data[line].id = 0;
256 itv->vbi.sliced_dec_data[line].line = 0;
257 itv->vbi.sliced_dec_data[line].field = 0;
258 line++;
259 }
260 return line * sizeof(itv->vbi.sliced_dec_data[0]);
261}
262
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300263/* Compress raw VBI format, removes leading SAV codes and surplus space after the
264 field.
265 Returns new compressed size. */
266static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
267{
268 u32 line_size = itv->vbi.raw_decoder_line_size;
269 u32 lines = itv->vbi.count;
270 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
271 u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
272 u8 *q = buf;
273 u8 *p;
274 int i;
275
276 for (i = 0; i < lines; i++) {
277 p = buf + i * line_size;
278
279 /* Look for SAV code */
280 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
281 break;
282 }
283 memcpy(q, p + 4, line_size - 4);
284 q += line_size - 4;
285 }
286 return lines * (line_size - 4);
287}
288
289
290/* Compressed VBI format, all found sliced blocks put next to one another
291 Returns new compressed size */
292static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
293{
294 u32 line_size = itv->vbi.sliced_decoder_line_size;
295 struct v4l2_decode_vbi_line vbi;
296 int i;
Hans Verkuild526afe2008-09-03 16:47:14 -0300297 unsigned lines = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300298
299 /* find the first valid line */
300 for (i = 0; i < size; i++, buf++) {
301 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
302 break;
303 }
304
305 size -= i;
306 if (size < line_size) {
307 return line;
308 }
309 for (i = 0; i < size / line_size; i++) {
310 u8 *p = buf + i * line_size;
311
312 /* Look for SAV code */
313 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
314 continue;
315 }
316 vbi.p = p + 4;
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300317 v4l2_subdev_call(itv->sd_video, video, decode_vbi_line, &vbi);
Hans Verkuild526afe2008-09-03 16:47:14 -0300318 if (vbi.type && !(lines & (1 << vbi.line))) {
319 lines |= 1 << vbi.line;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300320 itv->vbi.sliced_data[line].id = vbi.type;
321 itv->vbi.sliced_data[line].field = vbi.is_second_field;
322 itv->vbi.sliced_data[line].line = vbi.line;
323 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
324 line++;
325 }
326 }
327 return line;
328}
329
330void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
331 u64 pts_stamp, int streamtype)
332{
333 u8 *p = (u8 *) buf->buf;
334 u32 size = buf->bytesused;
335 int y;
336
337 /* Raw VBI data */
Hans Verkuila8b86432008-10-04 08:05:30 -0300338 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300339 u8 type;
340
341 ivtv_buf_swap(buf);
342
343 type = p[3];
344
345 size = buf->bytesused = compress_raw_buf(itv, p, size);
346
347 /* second field of the frame? */
348 if (type == itv->vbi.raw_decoder_sav_even_field) {
349 /* Dirty hack needed for backwards
350 compatibility of old VBI software. */
351 p += size - 4;
352 memcpy(p, &itv->vbi.frame, 4);
353 itv->vbi.frame++;
354 }
355 return;
356 }
357
358 /* Sliced VBI data with data insertion */
359 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
360 int lines;
361
362 ivtv_buf_swap(buf);
363
364 /* first field */
365 lines = compress_sliced_buf(itv, 0, p, size / 2,
366 itv->vbi.sliced_decoder_sav_odd_field);
367 /* second field */
368 /* experimentation shows that the second half does not always begin
369 at the exact address. So start a bit earlier (hence 32). */
370 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
371 itv->vbi.sliced_decoder_sav_even_field);
372 /* always return at least one empty line */
373 if (lines == 0) {
374 itv->vbi.sliced_data[0].id = 0;
375 itv->vbi.sliced_data[0].line = 0;
376 itv->vbi.sliced_data[0].field = 0;
377 lines = 1;
378 }
379 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
380 memcpy(p, &itv->vbi.sliced_data[0], size);
381
382 if (itv->vbi.insert_mpeg) {
383 copy_vbi_data(itv, lines, pts_stamp);
384 }
385 itv->vbi.frame++;
386 return;
387 }
388
389 /* Sliced VBI re-inserted from an MPEG stream */
390 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
391 /* If the size is not 4-byte aligned, then the starting address
392 for the swapping is also shifted. After swapping the data the
393 real start address of the VBI data is exactly 4 bytes after the
394 original start. It's a bit fiddly but it works like a charm.
395 Non-4-byte alignment happens when an lseek is done on the input
396 mpeg file to a non-4-byte aligned position. So on arrival here
397 the VBI data is also non-4-byte aligned. */
398 int offset = size & 3;
399 int cnt;
400
401 if (offset) {
402 p += 4 - offset;
403 }
404 /* Swap Buffer */
405 for (y = 0; y < size; y += 4) {
406 swab32s((u32 *)(p + y));
407 }
408
409 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
410 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
411 buf->bytesused = cnt;
412
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300413 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
414 cnt / sizeof(itv->vbi.sliced_dec_data[0]));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300415 return;
416 }
417}
418
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300419void ivtv_disable_cc(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300420{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300421 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
422
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300423 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300424 ivtv_set_cc(itv, 0, &cc);
425 itv->vbi.cc_payload_idx = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300426}
427
Hans Verkuil1e13f9e2007-03-10 06:52:02 -0300428
Hans Verkuildc02d502007-05-19 14:07:16 -0300429void ivtv_vbi_work_handler(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300430{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300431 struct vbi_info *vi = &itv->vbi;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300432 struct v4l2_sliced_vbi_data data;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300433 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300434
435 /* Lock */
436 if (itv->output_mode == OUT_PASSTHROUGH) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300437 if (itv->is_50hz) {
438 data.id = V4L2_SLICED_WSS_625;
439 data.field = 0;
440
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300441 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300442 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300443 vi->wss_missing_cnt = 0;
444 } else if (vi->wss_missing_cnt == 4) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300445 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
446 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300447 vi->wss_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300448 }
449 }
450 else {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300451 int mode = 0;
452
453 data.id = V4L2_SLICED_CAPTION_525;
454 data.field = 0;
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300455 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300456 mode |= 1;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300457 cc.odd[0] = data.data[0];
458 cc.odd[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300459 }
460 data.field = 1;
Hans Verkuil67ec09f2008-11-29 19:38:23 -0300461 if (v4l2_subdev_call(itv->sd_video, video, g_vbi_data, &data) == 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300462 mode |= 2;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300463 cc.even[0] = data.data[0];
464 cc.even[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300465 }
466 if (mode) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300467 vi->cc_missing_cnt = 0;
468 ivtv_set_cc(itv, mode, &cc);
469 } else if (vi->cc_missing_cnt == 4) {
470 ivtv_set_cc(itv, 0, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300471 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300472 vi->cc_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300473 }
474 }
475 return;
476 }
477
478 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300479 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300480 }
481
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300482 if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
483 if (vi->cc_payload_idx == 0) {
484 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
485 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300486 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300487 while (vi->cc_payload_idx) {
488 cc = vi->cc_payload[0];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300489
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300490 memcpy(vi->cc_payload, vi->cc_payload + 1,
491 sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
492 vi->cc_payload_idx--;
493 if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300494 continue;
495
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300496 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300497 break;
498 }
499 }
500
501 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300502 ivtv_set_vps(itv, 1);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300503 }
504}