blob: 4a37a7d2e69d53332341dd2f7cda8f66e6d6bc3e [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));
Hans Verkuilfeb5bce2008-05-01 09:22:13 -0300172 dst[sd + 12 + line * 43] =
173 ivtv_service2vbi(itv->vbi.sliced_data[i].id);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300174 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42);
175 line++;
176 }
177 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data));
178 if (line == 36) {
179 /* All lines are used, so there is no space for the linemask
180 (the max size of the VBI data is 36 * 43 + 4 bytes).
181 So in this case we use the magic number 'ITV0'. */
182 memcpy(dst + sd, "ITV0", 4);
183 memcpy(dst + sd + 4, dst + sd + 12, line * 43);
184 size = 4 + ((43 * line + 3) & ~3);
185 } else {
186 memcpy(dst + sd, "itv0", 4);
187 memcpy(dst + sd + 4, &linemask[0], 8);
188 size = 12 + ((43 * line + 3) & ~3);
189 }
190 dst[4+16] = (size + 10) >> 8;
191 dst[5+16] = (size + 10) & 0xff;
192 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6);
193 dst[10+16] = (pts_stamp >> 22) & 0xff;
194 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff);
195 dst[12+16] = (pts_stamp >> 7) & 0xff;
196 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1);
197 itv->vbi.sliced_mpeg_size[idx] = sd + size;
198}
199
200static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p)
201{
202 u32 linemask[2];
203 int i, l, id2;
204 int line = 0;
205
206 if (!memcmp(p, "itv0", 4)) {
207 memcpy(linemask, p + 4, 8);
208 p += 12;
209 } else if (!memcmp(p, "ITV0", 4)) {
210 linemask[0] = 0xffffffff;
211 linemask[1] = 0xf;
212 p += 4;
213 } else {
Hans Verkuil51a99c02007-08-18 15:16:00 -0300214 /* unknown VBI data, convert to empty VBI frame */
215 linemask[0] = linemask[1] = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300216 }
217 for (i = 0; i < 36; i++) {
218 int err = 0;
219
220 if (i < 32 && !(linemask[0] & (1 << i)))
221 continue;
222 if (i >= 32 && !(linemask[1] & (1 << (i - 32))))
223 continue;
224 id2 = *p & 0xf;
225 switch (id2) {
226 case IVTV_SLICED_TYPE_TELETEXT_B:
227 id2 = V4L2_SLICED_TELETEXT_B;
228 break;
229 case IVTV_SLICED_TYPE_CAPTION_525:
230 id2 = V4L2_SLICED_CAPTION_525;
231 err = !odd_parity(p[1]) || !odd_parity(p[2]);
232 break;
233 case IVTV_SLICED_TYPE_VPS:
234 id2 = V4L2_SLICED_VPS;
235 break;
236 case IVTV_SLICED_TYPE_WSS_625:
237 id2 = V4L2_SLICED_WSS_625;
238 break;
239 default:
240 id2 = 0;
241 break;
242 }
243 if (err == 0) {
244 l = (i < 18) ? i + 6 : i - 18 + 6;
245 itv->vbi.sliced_dec_data[line].line = l;
246 itv->vbi.sliced_dec_data[line].field = i >= 18;
247 itv->vbi.sliced_dec_data[line].id = id2;
248 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42);
249 line++;
250 }
251 p += 43;
252 }
253 while (line < 36) {
254 itv->vbi.sliced_dec_data[line].id = 0;
255 itv->vbi.sliced_dec_data[line].line = 0;
256 itv->vbi.sliced_dec_data[line].field = 0;
257 line++;
258 }
259 return line * sizeof(itv->vbi.sliced_dec_data[0]);
260}
261
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300262/* Compress raw VBI format, removes leading SAV codes and surplus space after the
263 field.
264 Returns new compressed size. */
265static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size)
266{
267 u32 line_size = itv->vbi.raw_decoder_line_size;
268 u32 lines = itv->vbi.count;
269 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field;
270 u8 sav2 = itv->vbi.raw_decoder_sav_even_field;
271 u8 *q = buf;
272 u8 *p;
273 int i;
274
275 for (i = 0; i < lines; i++) {
276 p = buf + i * line_size;
277
278 /* Look for SAV code */
279 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) {
280 break;
281 }
282 memcpy(q, p + 4, line_size - 4);
283 q += line_size - 4;
284 }
285 return lines * (line_size - 4);
286}
287
288
289/* Compressed VBI format, all found sliced blocks put next to one another
290 Returns new compressed size */
291static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav)
292{
293 u32 line_size = itv->vbi.sliced_decoder_line_size;
294 struct v4l2_decode_vbi_line vbi;
295 int i;
Hans Verkuild526afe2008-09-03 16:47:14 -0300296 unsigned lines = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300297
298 /* find the first valid line */
299 for (i = 0; i < size; i++, buf++) {
300 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
301 break;
302 }
303
304 size -= i;
305 if (size < line_size) {
306 return line;
307 }
308 for (i = 0; i < size / line_size; i++) {
309 u8 *p = buf + i * line_size;
310
311 /* Look for SAV code */
312 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) {
313 continue;
314 }
315 vbi.p = p + 4;
316 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
Hans Verkuild526afe2008-09-03 16:47:14 -0300317 if (vbi.type && !(lines & (1 << vbi.line))) {
318 lines |= 1 << vbi.line;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300319 itv->vbi.sliced_data[line].id = vbi.type;
320 itv->vbi.sliced_data[line].field = vbi.is_second_field;
321 itv->vbi.sliced_data[line].line = vbi.line;
322 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42);
323 line++;
324 }
325 }
326 return line;
327}
328
329void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf,
330 u64 pts_stamp, int streamtype)
331{
332 u8 *p = (u8 *) buf->buf;
333 u32 size = buf->bytesused;
334 int y;
335
336 /* Raw VBI data */
Hans Verkuila8b86432008-10-04 08:05:30 -0300337 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && ivtv_raw_vbi(itv)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300338 u8 type;
339
340 ivtv_buf_swap(buf);
341
342 type = p[3];
343
344 size = buf->bytesused = compress_raw_buf(itv, p, size);
345
346 /* second field of the frame? */
347 if (type == itv->vbi.raw_decoder_sav_even_field) {
348 /* Dirty hack needed for backwards
349 compatibility of old VBI software. */
350 p += size - 4;
351 memcpy(p, &itv->vbi.frame, 4);
352 itv->vbi.frame++;
353 }
354 return;
355 }
356
357 /* Sliced VBI data with data insertion */
358 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) {
359 int lines;
360
361 ivtv_buf_swap(buf);
362
363 /* first field */
364 lines = compress_sliced_buf(itv, 0, p, size / 2,
365 itv->vbi.sliced_decoder_sav_odd_field);
366 /* second field */
367 /* experimentation shows that the second half does not always begin
368 at the exact address. So start a bit earlier (hence 32). */
369 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32,
370 itv->vbi.sliced_decoder_sav_even_field);
371 /* always return at least one empty line */
372 if (lines == 0) {
373 itv->vbi.sliced_data[0].id = 0;
374 itv->vbi.sliced_data[0].line = 0;
375 itv->vbi.sliced_data[0].field = 0;
376 lines = 1;
377 }
378 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]);
379 memcpy(p, &itv->vbi.sliced_data[0], size);
380
381 if (itv->vbi.insert_mpeg) {
382 copy_vbi_data(itv, lines, pts_stamp);
383 }
384 itv->vbi.frame++;
385 return;
386 }
387
388 /* Sliced VBI re-inserted from an MPEG stream */
389 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
390 /* If the size is not 4-byte aligned, then the starting address
391 for the swapping is also shifted. After swapping the data the
392 real start address of the VBI data is exactly 4 bytes after the
393 original start. It's a bit fiddly but it works like a charm.
394 Non-4-byte alignment happens when an lseek is done on the input
395 mpeg file to a non-4-byte aligned position. So on arrival here
396 the VBI data is also non-4-byte aligned. */
397 int offset = size & 3;
398 int cnt;
399
400 if (offset) {
401 p += 4 - offset;
402 }
403 /* Swap Buffer */
404 for (y = 0; y < size; y += 4) {
405 swab32s((u32 *)(p + y));
406 }
407
408 cnt = ivtv_convert_ivtv_vbi(itv, p + offset);
409 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt);
410 buf->bytesused = cnt;
411
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300412 ivtv_write_vbi(itv, itv->vbi.sliced_dec_data,
413 cnt / sizeof(itv->vbi.sliced_dec_data[0]));
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300414 return;
415 }
416}
417
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300418void ivtv_disable_cc(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300419{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300420 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
421
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300422 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300423 ivtv_set_cc(itv, 0, &cc);
424 itv->vbi.cc_payload_idx = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300425}
426
Hans Verkuil1e13f9e2007-03-10 06:52:02 -0300427
Hans Verkuildc02d502007-05-19 14:07:16 -0300428void ivtv_vbi_work_handler(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300429{
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300430 struct vbi_info *vi = &itv->vbi;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300431 struct v4l2_sliced_vbi_data data;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300432 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300433
434 /* Lock */
435 if (itv->output_mode == OUT_PASSTHROUGH) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300436 if (itv->is_50hz) {
437 data.id = V4L2_SLICED_WSS_625;
438 data.field = 0;
439
440 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
441 ivtv_set_wss(itv, 1, data.data[0] & 0xf);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300442 vi->wss_missing_cnt = 0;
443 } else if (vi->wss_missing_cnt == 4) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300444 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */
445 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300446 vi->wss_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300447 }
448 }
449 else {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300450 int mode = 0;
451
452 data.id = V4L2_SLICED_CAPTION_525;
453 data.field = 0;
454 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
455 mode |= 1;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300456 cc.odd[0] = data.data[0];
457 cc.odd[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300458 }
459 data.field = 1;
460 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) {
461 mode |= 2;
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300462 cc.even[0] = data.data[0];
463 cc.even[1] = data.data[1];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300464 }
465 if (mode) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300466 vi->cc_missing_cnt = 0;
467 ivtv_set_cc(itv, mode, &cc);
468 } else if (vi->cc_missing_cnt == 4) {
469 ivtv_set_cc(itv, 0, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300470 } else {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300471 vi->cc_missing_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300472 }
473 }
474 return;
475 }
476
477 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300478 ivtv_set_wss(itv, 1, vi->wss_payload & 0xf);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300479 }
480
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300481 if (test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) {
482 if (vi->cc_payload_idx == 0) {
483 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
484 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300485 }
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300486 while (vi->cc_payload_idx) {
487 cc = vi->cc_payload[0];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300488
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300489 memcpy(vi->cc_payload, vi->cc_payload + 1,
490 sizeof(vi->cc_payload) - sizeof(vi->cc_payload[0]));
491 vi->cc_payload_idx--;
492 if (vi->cc_payload_idx && cc.odd[0] == 0x80 && cc.odd[1] == 0x80)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300493 continue;
494
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300495 ivtv_set_cc(itv, 3, &cc);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300496 break;
497 }
498 }
499
500 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) {
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300501 ivtv_set_vps(itv, 1);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300502 }
503}