ivtv-vbi.c revision 1a0adaf37c30e89e44d1470ef604a930999a5826
1/* 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" 21#include "ivtv-video.h" 22#include "ivtv-vbi.h" 23#include "ivtv-ioctl.h" 24#include "ivtv-queue.h" 25 26static int odd_parity(u8 c) 27{ 28 c ^= (c >> 4); 29 c ^= (c >> 2); 30 c ^= (c >> 1); 31 32 return c & 1; 33} 34 35void vbi_schedule_work(struct ivtv *itv) 36{ 37 queue_work(itv->vbi.work_queues, &itv->vbi.work_queue); 38} 39 40static void passthrough_vbi_data(struct ivtv *itv, int cnt) 41{ 42 int wss = 0; 43 u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 }; 44 u8 vps[13]; 45 int found_cc = 0; 46 int found_wss = 0; 47 int found_vps = 0; 48 int cc_pos = itv->vbi.cc_pos; 49 int i; 50 51 for (i = 0; i < cnt; i++) { 52 struct v4l2_sliced_vbi_data *d = itv->vbi.sliced_dec_data + i; 53 54 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) { 55 found_cc = 1; 56 if (d->field) { 57 cc[2] = d->data[0]; 58 cc[3] = d->data[1]; 59 } else { 60 cc[0] = d->data[0]; 61 cc[1] = d->data[1]; 62 } 63 } 64 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) { 65 memcpy(vps, d->data, sizeof(vps)); 66 found_vps = 1; 67 } 68 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) { 69 wss = d->data[0] | d->data[1] << 8; 70 found_wss = 1; 71 } 72 } 73 74 if (itv->vbi.wss_found != found_wss || itv->vbi.wss != wss) { 75 itv->vbi.wss = wss; 76 itv->vbi.wss_found = found_wss; 77 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); 78 } 79 80 if (found_vps || itv->vbi.vps_found) { 81 itv->vbi.vps[0] = vps[2]; 82 itv->vbi.vps[1] = vps[8]; 83 itv->vbi.vps[2] = vps[9]; 84 itv->vbi.vps[3] = vps[10]; 85 itv->vbi.vps[4] = vps[11]; 86 itv->vbi.vps_found = found_vps; 87 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); 88 } 89 90 if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) { 91 itv->vbi.cc_data_odd[cc_pos] = cc[0]; 92 itv->vbi.cc_data_odd[cc_pos + 1] = cc[1]; 93 itv->vbi.cc_data_even[cc_pos] = cc[2]; 94 itv->vbi.cc_data_even[cc_pos + 1] = cc[3]; 95 itv->vbi.cc_pos = cc_pos + 2; 96 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); 97 } 98} 99 100static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) 101{ 102 int line = 0; 103 int i; 104 u32 linemask[2] = { 0, 0 }; 105 unsigned short size; 106 static const u8 mpeg_hdr_data[] = { 107 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66, 108 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff, 109 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80, 110 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff 111 }; 112 const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */ 113 int idx = itv->vbi.frame % IVTV_VBI_FRAMES; 114 u8 *dst = &itv->vbi.sliced_mpeg_data[idx][0]; 115 116 for (i = 0; i < lines; i++) { 117 int f, l; 118 119 if (itv->vbi.sliced_data[i].id == 0) 120 continue; 121 122 l = itv->vbi.sliced_data[i].line - 6; 123 f = itv->vbi.sliced_data[i].field; 124 if (f) 125 l += 18; 126 if (l < 32) 127 linemask[0] |= (1 << l); 128 else 129 linemask[1] |= (1 << (l - 32)); 130 dst[sd + 12 + line * 43] = service2vbi(itv->vbi.sliced_data[i].id); 131 memcpy(dst + sd + 12 + line * 43 + 1, itv->vbi.sliced_data[i].data, 42); 132 line++; 133 } 134 memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data)); 135 if (line == 36) { 136 /* All lines are used, so there is no space for the linemask 137 (the max size of the VBI data is 36 * 43 + 4 bytes). 138 So in this case we use the magic number 'ITV0'. */ 139 memcpy(dst + sd, "ITV0", 4); 140 memcpy(dst + sd + 4, dst + sd + 12, line * 43); 141 size = 4 + ((43 * line + 3) & ~3); 142 } else { 143 memcpy(dst + sd, "itv0", 4); 144 memcpy(dst + sd + 4, &linemask[0], 8); 145 size = 12 + ((43 * line + 3) & ~3); 146 } 147 dst[4+16] = (size + 10) >> 8; 148 dst[5+16] = (size + 10) & 0xff; 149 dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6); 150 dst[10+16] = (pts_stamp >> 22) & 0xff; 151 dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff); 152 dst[12+16] = (pts_stamp >> 7) & 0xff; 153 dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1); 154 itv->vbi.sliced_mpeg_size[idx] = sd + size; 155} 156 157static int ivtv_convert_ivtv_vbi(struct ivtv *itv, u8 *p) 158{ 159 u32 linemask[2]; 160 int i, l, id2; 161 int line = 0; 162 163 if (!memcmp(p, "itv0", 4)) { 164 memcpy(linemask, p + 4, 8); 165 p += 12; 166 } else if (!memcmp(p, "ITV0", 4)) { 167 linemask[0] = 0xffffffff; 168 linemask[1] = 0xf; 169 p += 4; 170 } else { 171 /* unknown VBI data stream */ 172 return 0; 173 } 174 for (i = 0; i < 36; i++) { 175 int err = 0; 176 177 if (i < 32 && !(linemask[0] & (1 << i))) 178 continue; 179 if (i >= 32 && !(linemask[1] & (1 << (i - 32)))) 180 continue; 181 id2 = *p & 0xf; 182 switch (id2) { 183 case IVTV_SLICED_TYPE_TELETEXT_B: 184 id2 = V4L2_SLICED_TELETEXT_B; 185 break; 186 case IVTV_SLICED_TYPE_CAPTION_525: 187 id2 = V4L2_SLICED_CAPTION_525; 188 err = !odd_parity(p[1]) || !odd_parity(p[2]); 189 break; 190 case IVTV_SLICED_TYPE_VPS: 191 id2 = V4L2_SLICED_VPS; 192 break; 193 case IVTV_SLICED_TYPE_WSS_625: 194 id2 = V4L2_SLICED_WSS_625; 195 break; 196 default: 197 id2 = 0; 198 break; 199 } 200 if (err == 0) { 201 l = (i < 18) ? i + 6 : i - 18 + 6; 202 itv->vbi.sliced_dec_data[line].line = l; 203 itv->vbi.sliced_dec_data[line].field = i >= 18; 204 itv->vbi.sliced_dec_data[line].id = id2; 205 memcpy(itv->vbi.sliced_dec_data[line].data, p + 1, 42); 206 line++; 207 } 208 p += 43; 209 } 210 while (line < 36) { 211 itv->vbi.sliced_dec_data[line].id = 0; 212 itv->vbi.sliced_dec_data[line].line = 0; 213 itv->vbi.sliced_dec_data[line].field = 0; 214 line++; 215 } 216 return line * sizeof(itv->vbi.sliced_dec_data[0]); 217} 218 219ssize_t ivtv_write_vbi(struct ivtv *itv, const char __user *ubuf, size_t count) 220{ 221 /* Should be a __user pointer, but sparse doesn't parse this bit correctly. */ 222 const struct v4l2_sliced_vbi_data *p = (const struct v4l2_sliced_vbi_data *)ubuf; 223 u8 cc[4] = { 0x80, 0x80, 0x80, 0x80 }; 224 int found_cc = 0; 225 int cc_pos = itv->vbi.cc_pos; 226 227 if (itv->vbi.service_set_out == 0) 228 return -EPERM; 229 230 while (count >= sizeof(struct v4l2_sliced_vbi_data)) { 231 switch (p->id) { 232 case V4L2_SLICED_CAPTION_525: 233 if (p->id == V4L2_SLICED_CAPTION_525 && 234 p->line == 21 && 235 (itv->vbi.service_set_out & 236 V4L2_SLICED_CAPTION_525) == 0) { 237 break; 238 } 239 found_cc = 1; 240 if (p->field) { 241 cc[2] = p->data[0]; 242 cc[3] = p->data[1]; 243 } else { 244 cc[0] = p->data[0]; 245 cc[1] = p->data[1]; 246 } 247 break; 248 249 case V4L2_SLICED_VPS: 250 if (p->line == 16 && p->field == 0 && 251 (itv->vbi.service_set_out & V4L2_SLICED_VPS)) { 252 itv->vbi.vps[0] = p->data[2]; 253 itv->vbi.vps[1] = p->data[8]; 254 itv->vbi.vps[2] = p->data[9]; 255 itv->vbi.vps[3] = p->data[10]; 256 itv->vbi.vps[4] = p->data[11]; 257 itv->vbi.vps_found = 1; 258 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); 259 } 260 break; 261 262 case V4L2_SLICED_WSS_625: 263 if (p->line == 23 && p->field == 0 && 264 (itv->vbi.service_set_out & V4L2_SLICED_WSS_625)) { 265 /* No lock needed for WSS */ 266 itv->vbi.wss = p->data[0] | (p->data[1] << 8); 267 itv->vbi.wss_found = 1; 268 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); 269 } 270 break; 271 272 default: 273 break; 274 } 275 count -= sizeof(*p); 276 p++; 277 } 278 279 if (found_cc && cc_pos < sizeof(itv->vbi.cc_data_even)) { 280 itv->vbi.cc_data_odd[cc_pos] = cc[0]; 281 itv->vbi.cc_data_odd[cc_pos + 1] = cc[1]; 282 itv->vbi.cc_data_even[cc_pos] = cc[2]; 283 itv->vbi.cc_data_even[cc_pos + 1] = cc[3]; 284 itv->vbi.cc_pos = cc_pos + 2; 285 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); 286 } 287 288 return (const char __user *)p - ubuf; 289} 290 291/* Compress raw VBI format, removes leading SAV codes and surplus space after the 292 field. 293 Returns new compressed size. */ 294static u32 compress_raw_buf(struct ivtv *itv, u8 *buf, u32 size) 295{ 296 u32 line_size = itv->vbi.raw_decoder_line_size; 297 u32 lines = itv->vbi.count; 298 u8 sav1 = itv->vbi.raw_decoder_sav_odd_field; 299 u8 sav2 = itv->vbi.raw_decoder_sav_even_field; 300 u8 *q = buf; 301 u8 *p; 302 int i; 303 304 for (i = 0; i < lines; i++) { 305 p = buf + i * line_size; 306 307 /* Look for SAV code */ 308 if (p[0] != 0xff || p[1] || p[2] || (p[3] != sav1 && p[3] != sav2)) { 309 break; 310 } 311 memcpy(q, p + 4, line_size - 4); 312 q += line_size - 4; 313 } 314 return lines * (line_size - 4); 315} 316 317 318/* Compressed VBI format, all found sliced blocks put next to one another 319 Returns new compressed size */ 320static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8 sav) 321{ 322 u32 line_size = itv->vbi.sliced_decoder_line_size; 323 struct v4l2_decode_vbi_line vbi; 324 int i; 325 326 /* find the first valid line */ 327 for (i = 0; i < size; i++, buf++) { 328 if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav) 329 break; 330 } 331 332 size -= i; 333 if (size < line_size) { 334 return line; 335 } 336 for (i = 0; i < size / line_size; i++) { 337 u8 *p = buf + i * line_size; 338 339 /* Look for SAV code */ 340 if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) { 341 continue; 342 } 343 vbi.p = p + 4; 344 itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi); 345 if (vbi.type) { 346 itv->vbi.sliced_data[line].id = vbi.type; 347 itv->vbi.sliced_data[line].field = vbi.is_second_field; 348 itv->vbi.sliced_data[line].line = vbi.line; 349 memcpy(itv->vbi.sliced_data[line].data, vbi.p, 42); 350 line++; 351 } 352 } 353 return line; 354} 355 356void ivtv_process_vbi_data(struct ivtv *itv, struct ivtv_buffer *buf, 357 u64 pts_stamp, int streamtype) 358{ 359 u8 *p = (u8 *) buf->buf; 360 u32 size = buf->bytesused; 361 int y; 362 363 /* Raw VBI data */ 364 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI && itv->vbi.sliced_in->service_set == 0) { 365 u8 type; 366 367 ivtv_buf_swap(buf); 368 369 type = p[3]; 370 371 size = buf->bytesused = compress_raw_buf(itv, p, size); 372 373 /* second field of the frame? */ 374 if (type == itv->vbi.raw_decoder_sav_even_field) { 375 /* Dirty hack needed for backwards 376 compatibility of old VBI software. */ 377 p += size - 4; 378 memcpy(p, &itv->vbi.frame, 4); 379 itv->vbi.frame++; 380 } 381 return; 382 } 383 384 /* Sliced VBI data with data insertion */ 385 if (streamtype == IVTV_ENC_STREAM_TYPE_VBI) { 386 int lines; 387 388 ivtv_buf_swap(buf); 389 390 /* first field */ 391 lines = compress_sliced_buf(itv, 0, p, size / 2, 392 itv->vbi.sliced_decoder_sav_odd_field); 393 /* second field */ 394 /* experimentation shows that the second half does not always begin 395 at the exact address. So start a bit earlier (hence 32). */ 396 lines = compress_sliced_buf(itv, lines, p + size / 2 - 32, size / 2 + 32, 397 itv->vbi.sliced_decoder_sav_even_field); 398 /* always return at least one empty line */ 399 if (lines == 0) { 400 itv->vbi.sliced_data[0].id = 0; 401 itv->vbi.sliced_data[0].line = 0; 402 itv->vbi.sliced_data[0].field = 0; 403 lines = 1; 404 } 405 buf->bytesused = size = lines * sizeof(itv->vbi.sliced_data[0]); 406 memcpy(p, &itv->vbi.sliced_data[0], size); 407 408 if (itv->vbi.insert_mpeg) { 409 copy_vbi_data(itv, lines, pts_stamp); 410 } 411 itv->vbi.frame++; 412 return; 413 } 414 415 /* Sliced VBI re-inserted from an MPEG stream */ 416 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) { 417 /* If the size is not 4-byte aligned, then the starting address 418 for the swapping is also shifted. After swapping the data the 419 real start address of the VBI data is exactly 4 bytes after the 420 original start. It's a bit fiddly but it works like a charm. 421 Non-4-byte alignment happens when an lseek is done on the input 422 mpeg file to a non-4-byte aligned position. So on arrival here 423 the VBI data is also non-4-byte aligned. */ 424 int offset = size & 3; 425 int cnt; 426 427 if (offset) { 428 p += 4 - offset; 429 } 430 /* Swap Buffer */ 431 for (y = 0; y < size; y += 4) { 432 swab32s((u32 *)(p + y)); 433 } 434 435 cnt = ivtv_convert_ivtv_vbi(itv, p + offset); 436 memcpy(buf->buf, itv->vbi.sliced_dec_data, cnt); 437 buf->bytesused = cnt; 438 439 passthrough_vbi_data(itv, cnt / sizeof(itv->vbi.sliced_dec_data[0])); 440 return; 441 } 442} 443 444void ivtv_disable_vbi(struct ivtv *itv) 445{ 446 clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); 447 clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); 448 clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); 449 ivtv_set_wss(itv, 0, 0); 450 ivtv_set_cc(itv, 0, 0, 0, 0, 0); 451 ivtv_set_vps(itv, 0, 0, 0, 0, 0, 0); 452 itv->vbi.vps_found = itv->vbi.wss_found = 0; 453 itv->vbi.wss = 0; 454 itv->vbi.cc_pos = 0; 455} 456 457void vbi_work_handler(struct work_struct *work) 458{ 459 struct vbi_info *info = container_of(work, struct vbi_info, work_queue); 460 struct ivtv *itv = container_of(info, struct ivtv, vbi); 461 struct v4l2_sliced_vbi_data data; 462 DEFINE_WAIT(wait); 463 464 /* Lock */ 465 if (itv->output_mode == OUT_PASSTHROUGH) { 466 /* Note: currently only the saa7115 is used in a PVR350, 467 so these commands are for now saa7115 specific. */ 468 if (itv->is_50hz) { 469 data.id = V4L2_SLICED_WSS_625; 470 data.field = 0; 471 472 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) { 473 ivtv_set_wss(itv, 1, data.data[0] & 0xf); 474 itv->vbi.wss_no_update = 0; 475 } else if (itv->vbi.wss_no_update == 4) { 476 ivtv_set_wss(itv, 1, 0x8); /* 4x3 full format */ 477 } else { 478 itv->vbi.wss_no_update++; 479 } 480 } 481 else { 482 u8 c1 = 0, c2 = 0, c3 = 0, c4 = 0; 483 int mode = 0; 484 485 data.id = V4L2_SLICED_CAPTION_525; 486 data.field = 0; 487 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) { 488 mode |= 1; 489 c1 = data.data[0]; 490 c2 = data.data[1]; 491 } 492 data.field = 1; 493 if (itv->video_dec_func(itv, VIDIOC_INT_G_VBI_DATA, &data) == 0) { 494 mode |= 2; 495 c3 = data.data[0]; 496 c4 = data.data[1]; 497 } 498 if (mode) { 499 itv->vbi.cc_no_update = 0; 500 ivtv_set_cc(itv, mode, c1, c2, c3, c4); 501 } else if (itv->vbi.cc_no_update == 4) { 502 ivtv_set_cc(itv, 0, 0, 0, 0, 0); 503 } else { 504 itv->vbi.cc_no_update++; 505 } 506 } 507 return; 508 } 509 510 if (test_and_clear_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags)) { 511 /* Lock */ 512 ivtv_set_wss(itv, itv->vbi.wss_found, itv->vbi.wss & 0xf); 513 } 514 515 if (test_and_clear_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags)) { 516 if (itv->vbi.cc_pos == 0) { 517 ivtv_set_cc(itv, 3, 0x80, 0x80, 0x80, 0x80); 518 } 519 while (itv->vbi.cc_pos) { 520 u8 cc_odd0 = itv->vbi.cc_data_odd[0]; 521 u8 cc_odd1 = itv->vbi.cc_data_odd[1]; 522 u8 cc_even0 = itv->vbi.cc_data_even[0]; 523 u8 cc_even1 = itv->vbi.cc_data_even[1]; 524 525 memcpy(itv->vbi.cc_data_odd, itv->vbi.cc_data_odd + 2, sizeof(itv->vbi.cc_data_odd) - 2); 526 memcpy(itv->vbi.cc_data_even, itv->vbi.cc_data_even + 2, sizeof(itv->vbi.cc_data_even) - 2); 527 itv->vbi.cc_pos -= 2; 528 if (itv->vbi.cc_pos && cc_odd0 == 0x80 && cc_odd1 == 0x80) 529 continue; 530 531 /* Send to Saa7127 */ 532 ivtv_set_cc(itv, 3, cc_odd0, cc_odd1, cc_even0, cc_even1); 533 if (itv->vbi.cc_pos == 0) 534 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); 535 break; 536 } 537 } 538 539 if (test_and_clear_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags)) { 540 /* Lock */ 541 ivtv_set_vps(itv, itv->vbi.vps_found, 542 itv->vbi.vps[0], itv->vbi.vps[1], 543 itv->vbi.vps[2], itv->vbi.vps[3], itv->vbi.vps[4]); 544 } 545} 546