blob: c151bcf5519ae92be2fd189b8f3856f593c04e74 [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 Verkuil33c0fca2007-08-23 06:32:46 -030024#include "ivtv-vbi.h"
25
Hans Verkuil2f3a9892007-08-25 14:11:23 -030026static void ivtv_set_vps(struct ivtv *itv, int enabled)
Hans Verkuil33c0fca2007-08-23 06:32:46 -030027{
28 struct v4l2_sliced_vbi_data data;
29
30 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
31 return;
32 data.id = V4L2_SLICED_VPS;
33 data.field = 0;
34 data.line = enabled ? 16 : 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030035 data.data[2] = itv->vbi.vps_payload.data[0];
36 data.data[8] = itv->vbi.vps_payload.data[1];
37 data.data[9] = itv->vbi.vps_payload.data[2];
38 data.data[10] = itv->vbi.vps_payload.data[3];
39 data.data[11] = itv->vbi.vps_payload.data[4];
Hans Verkuil33c0fca2007-08-23 06:32:46 -030040 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
41}
42
Hans Verkuil2f3a9892007-08-25 14:11:23 -030043static void ivtv_set_cc(struct ivtv *itv, int mode, const struct vbi_cc *cc)
Hans Verkuil33c0fca2007-08-23 06:32:46 -030044{
45 struct v4l2_sliced_vbi_data data;
46
47 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
48 return;
49 data.id = V4L2_SLICED_CAPTION_525;
50 data.field = 0;
51 data.line = (mode & 1) ? 21 : 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030052 data.data[0] = cc->odd[0];
53 data.data[1] = cc->odd[1];
Hans Verkuil33c0fca2007-08-23 06:32:46 -030054 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
55 data.field = 1;
56 data.line = (mode & 2) ? 21 : 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030057 data.data[0] = cc->even[0];
58 data.data[1] = cc->even[1];
Hans Verkuil33c0fca2007-08-23 06:32:46 -030059 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
60}
61
62static void ivtv_set_wss(struct ivtv *itv, int enabled, int mode)
63{
64 struct v4l2_sliced_vbi_data data;
65
66 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
67 return;
68 /* When using a 50 Hz system, always turn on the
69 wide screen signal with 4x3 ratio as the default.
70 Turning this signal on and off can confuse certain
71 TVs. As far as I can tell there is no reason not to
72 transmit this signal. */
73 if ((itv->std & V4L2_STD_625_50) && !enabled) {
74 enabled = 1;
75 mode = 0x08; /* 4x3 full format */
76 }
77 data.id = V4L2_SLICED_WSS_625;
78 data.field = 0;
79 data.line = enabled ? 23 : 0;
80 data.data[0] = mode & 0xff;
81 data.data[1] = (mode >> 8) & 0xff;
82 ivtv_saa7127(itv, VIDIOC_INT_S_VBI_DATA, &data);
83}
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030084
85static int odd_parity(u8 c)
86{
87 c ^= (c >> 4);
88 c ^= (c >> 2);
89 c ^= (c >> 1);
90
91 return c & 1;
92}
93
Hans Verkuil2f3a9892007-08-25 14:11:23 -030094void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030095{
Hans Verkuil2f3a9892007-08-25 14:11:23 -030096 struct vbi_info *vi = &itv->vbi;
97 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030098 int found_cc = 0;
Hans Verkuil2f3a9892007-08-25 14:11:23 -030099 size_t i;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300100
101 for (i = 0; i < cnt; i++) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300102 const struct v4l2_sliced_vbi_data *d = sliced + i;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300103
104 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300105 if (d->field) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300106 cc.even[0] = d->data[0];
107 cc.even[1] = d->data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300108 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300109 cc.odd[0] = d->data[0];
110 cc.odd[1] = d->data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300111 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300112 found_cc = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300113 }
114 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300115 struct vbi_vps vps;
116
117 vps.data[0] = d->data[2];
118 vps.data[1] = d->data[8];
119 vps.data[2] = d->data[9];
120 vps.data[3] = d->data[10];
121 vps.data[4] = d->data[11];
122 if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
123 vi->vps_payload = vps;
124 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
125 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300126 }
127 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300128 int wss = d->data[0] | d->data[1] << 8;
129
130 if (vi->wss_payload != wss) {
131 vi->wss_payload = wss;
132 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
133 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300134 }
135 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300136 if (found_cc && vi->cc_payload_idx < sizeof(vi->cc_payload)) {
137 vi->cc_payload[vi->cc_payload_idx++] = cc;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300138 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
139 }
140}
141
142static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
143{
144 int line = 0;
145 int i;
146 u32 linemask[2] = { 0, 0 };
147 unsigned short size;
148 static const u8 mpeg_hdr_data[] = {
149 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
150 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
151 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
152 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
153 };
154 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
155 int idx = itv->vbi.frame % IVTV_VBI_FRAMES;
156 u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0];
157
158 for (i = 0; i < lines; i++) {
159 int f, l;
160
161 if (itv->vbi.sliced_data[i].id == 0)
162 continue;
163
164 l = itv->vbi.sliced_data[i].line - 6;
165 f = itv->vbi.sliced_data[i].field;
166 if (f)
167 l += 18;
168 if (l < 32)
169 linemask[0] |= (1 << l);
170 else
171 linemask[1] |= (1 << (l - 32));
172 dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id);
173 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
174 line++;
175 }
176 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
177 if (line == 36) {
178 /* All lines are used, so there is no space for the linemask
179 (the max size of the VBI data is 36 * 43 + 4 bytes).
180 So in this case we use the magic number 'ITV0'. */
181 memcpy(dst + sd, "ITV0", 4);
182 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
183 size = 4 + ((43 * line + 3) & ~3);
184 } else {
185 memcpy(dst + sd, "itv0", 4);
186 memcpy(dst + sd + 4, &linemask[0], 8);
187 size = 12 + ((43 * line + 3) & ~3);
188 }
189 dst[4+16] = (size + 10) >> 8;
190 dst[5+16] = (size + 10) & 0xff;
191 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
192 dst[10+16] = (pts_stamp >> 22) & 0xff;
193 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
194 dst[12+16] = (pts_stamp >> 7) & 0xff;
195 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
196 itv->vbi.sliced_mpeg_size[idx] = sd + size;
197}
198
199static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
200{
201 u32 linemask[2];
202 int i, l, id2;
203 int line = 0;
204
205 if (!memcmp(p, "itv0", 4)) {
206 memcpy(linemask, p + 4, 8);
207 p += 12;
208 } else if (!memcmp(p, "ITV0", 4)) {
209 linemask[0] = 0xffffffff;
210 linemask[1] = 0xf;
211 p += 4;
212 } else {
Hans Verkuil51a99c02007-08-18 15:16:00 -0300213 /* unknown VBI data, convert to empty VBI frame */
214 linemask[0] = linemask[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300215 }
216 for (i = 0; i < 36; i++) {
217 int err = 0;
218
219 if (i < 32 && !(linemask[0] & (1 << i)))
220 continue;
221 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
222 continue;
223 id2 = *p & 0xf;
224 switch (id2) {
225 case IVTV_SLICED_TYPE_TELETEXT_B:
226 id2 = V4L2_SLICED_TELETEXT_B;
227 break;
228 case IVTV_SLICED_TYPE_CAPTION_525:
229 id2 = V4L2_SLICED_CAPTION_525;
230 err = !odd_parity(p[1]) || !odd_parity(p[2]);
231 break;
232 case IVTV_SLICED_TYPE_VPS:
233 id2 = V4L2_SLICED_VPS;
234 break;
235 case IVTV_SLICED_TYPE_WSS_625:
236 id2 = V4L2_SLICED_WSS_625;
237 break;
238 default:
239 id2 = 0;
240 break;
241 }
242 if (err == 0) {
243 l = (i < 18) ? i + 6 : i - 18 + 6;
244 itv->vbi.sliced_dec_data[line].line = l;
245 itv->vbi.sliced_dec_data[line].field = i >= 18;
246 itv->vbi.sliced_dec_data[line].id = id2;
247 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
248 line++;
249 }
250 p += 43;
251 }
252 while (line < 36) {
253 itv->vbi.sliced_dec_data[line].id = 0;
254 itv->vbi.sliced_dec_data[line].line = 0;
255 itv->vbi.sliced_dec_data[line].field = 0;
256 line++;
257 }
258 return line * sizeof(itv->vbi.sliced_dec_data[0]);
259}
260
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300261/* Compress raw VBI format, removes leading SAV codes and surplus space after the
262 field.
263 Returns new compressed size. */
264static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
265{
266 u32 line_size = itv->vbi.raw_decoder_line_size;
267 u32 lines = itv->vbi.count;
268 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
269 u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
270 u8 *q = buf;
271 u8 *p;
272 int i;
273
274 for (i = 0; i < lines; i++) {
275 p = buf + i * line_size;
276
277 /* Look for SAV code */
278 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
279 break;
280 }
281 memcpy(q, p + 4, line_size - 4);
282 q += line_size - 4;
283 }
284 return lines * (line_size - 4);
285}
286
287
288/* Compressed VBI format, all found sliced blocks put next to one another
289 Returns new compressed size */
290static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
291{
292 u32 line_size = itv->vbi.sliced_decoder_line_size;
293 struct v4l2_decode_vbi_line vbi;
294 int i;
295
296 /* find the first valid line */
297 for (i = 0; i < size; i++, buf++) {
298 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
299 break;
300 }
301
302 size -= i;
303 if (size < line_size) {
304 return line;
305 }
306 for (i = 0; i < size / line_size; i++) {
307 u8 *p = buf + i * line_size;
308
309 /* Look for SAV code */
310 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
311 continue;
312 }
313 vbi.p = p + 4;
314 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
315 if (vbi.type) {
316 itv->vbi.sliced_data[line].id = vbi.type;
317 itv->vbi.sliced_data[line].field = vbi.is_second_field;
318 itv->vbi.sliced_data[line].line = vbi.line;
319 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
320 line++;
321 }
322 }
323 return line;
324}
325
326void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
327 u64 pts_stamp, int streamtype)
328{
329 u8 *p = (u8 *) buf->buf;
330 u32 size = buf->bytesused;
331 int y;
332
333 /* Raw VBI data */
334 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) {
335 u8 type;
336
337 ivtv_buf_swap(buf);
338
339 type = p[3];
340
341 size = buf->bytesused = compress_raw_buf(itv, p, size);
342
343 /* second field of the frame? */
344 if (type == itv->vbi.raw_decoder_sav_even_field) {
345 /* Dirty hack needed for backwards
346 compatibility of old VBI software. */
347 p += size - 4;
348 memcpy(p, &itv->vbi.frame, 4);
349 itv->vbi.frame++;
350 }
351 return;
352 }
353
354 /* Sliced VBI data with data insertion */
355 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
356 int lines;
357
358 ivtv_buf_swap(buf);
359
360 /* first field */
361 lines = compress_sliced_buf(itv, 0, p, size / 2,
362 itv->vbi.sliced_decoder_sav_odd_field);
363 /* second field */
364 /* experimentation shows that the second half does not always begin
365 at the exact address. So start a bit earlier (hence 32). */
366 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
367 itv->vbi.sliced_decoder_sav_even_field);
368 /* always return at least one empty line */
369 if (lines == 0) {
370 itv->vbi.sliced_data[0].id = 0;
371 itv->vbi.sliced_data[0].line = 0;
372 itv->vbi.sliced_data[0].field = 0;
373 lines = 1;
374 }
375 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
376 memcpy(p, &itv->vbi.sliced_data[0], size);
377
378 if (itv->vbi.insert_mpeg) {
379 copy_vbi_data(itv, lines, pts_stamp);
380 }
381 itv->vbi.frame++;
382 return;
383 }
384
385 /* Sliced VBI re-inserted from an MPEG stream */
386 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
387 /* If the size is not 4-byte aligned, then the starting address
388 for the swapping is also shifted. After swapping the data the
389 real start address of the VBI data is exactly 4 bytes after the
390 original start. It's a bit fiddly but it works like a charm.
391 Non-4-byte alignment happens when an lseek is done on the input
392 mpeg file to a non-4-byte aligned position. So on arrival here
393 the VBI data is also non-4-byte aligned. */
394 int offset = size & 3;
395 int cnt;
396
397 if (offset) {
398 p += 4 - offset;
399 }
400 /* Swap Buffer */
401 for (y = 0; y < size; y += 4) {
402 swab32s((u32 *)(p + y));
403 }
404
405 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
406 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
407 buf->bytesused = cnt;
408
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300409 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
410 cnt / sizeof(itv->vbi.sliced_dec_data[0]));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300411 return;
412 }
413}
414
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300415void ivtv_disable_cc(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300416{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300417 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
418
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300419 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300420 ivtv_set_cc(itv, 0, &cc);
421 itv->vbi.cc_payload_idx = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300422}
423
Hans Verkuil1e13f9e2007-03-10 06:52:02 -0300424
Hans Verkuildc02d502007-05-19 14:07:16 -0300425void ivtv_vbi_work_handler(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300426{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300427 struct vbi_info *vi = &itv->vbi;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300428 struct v4l2_sliced_vbi_data data;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300429 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300430
431 /* Lock */
432 if (itv->output_mode == OUT_PASSTHROUGH) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300433 if (itv->is_50hz) {
434 data.id = V4L2_SLICED_WSS_625;
435 data.field = 0;
436
437 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
438 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300439 vi->wss_missing_cnt = 0;
440 } else if (vi->wss_missing_cnt == 4) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300441 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
442 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300443 vi->wss_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300444 }
445 }
446 else {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300447 int mode = 0;
448
449 data.id = V4L2_SLICED_CAPTION_525;
450 data.field = 0;
451 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
452 mode |= 1;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300453 cc.odd[0] = data.data[0];
454 cc.odd[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300455 }
456 data.field = 1;
457 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
458 mode |= 2;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300459 cc.even[0] = data.data[0];
460 cc.even[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300461 }
462 if (mode) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300463 vi->cc_missing_cnt = 0;
464 ivtv_set_cc(itv, mode, &cc);
465 } else if (vi->cc_missing_cnt == 4) {
466 ivtv_set_cc(itv, 0, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300467 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300468 vi->cc_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300469 }
470 }
471 return;
472 }
473
474 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300475 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300476 }
477
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300478 if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
479 if (vi->cc_payload_idx == 0) {
480 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
481 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300482 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300483 while (vi->cc_payload_idx) {
484 cc = vi->cc_payload[0];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300485
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300486 memcpy(vi->cc_payload, vi->cc_payload + 1,
487 sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
488 vi->cc_payload_idx--;
489 if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300490 continue;
491
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300492 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300493 break;
494 }
495 }
496
497 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300498 ivtv_set_vps(itv, 1);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300499 }
500}