|
MythTV
0.26-pre
|
00001 // POSIX headers 00002 #include <unistd.h> 00003 #include <fcntl.h> 00004 00005 #include <sys/ioctl.h> 00006 00007 // ANSI C headers 00008 #include <stdlib.h> 00009 #include <string.h> 00010 #include <stdio.h> 00011 #include <stdarg.h> 00012 00013 #ifdef USING_V4L2 00014 // HACK. Broken kernel headers < 2.6.25 fail compile in videodev2.h when 00015 // compiling with -std=c99. We could remove this in the .pro file, 00016 // but that would disable it for all .c files. 00017 #undef __STRICT_ANSI__ 00018 #ifdef USING_V4L1 00019 #include <linux/videodev.h> 00020 #endif // USING_V4L1 00021 #include <linux/videodev2.h> 00022 #endif // USING_V4L2 00023 00024 // vbitext headers 00025 #include "vt.h" 00026 #include "vbi.h" 00027 #include "hamm.h" 00028 00029 #define FAC (1<<16) // factor for fix-point arithmetic 00030 00031 static unsigned char *rawbuf; // one common buffer for raw vbi data. 00032 #ifdef USING_V4L2 00033 static int rawbuf_size; // its current size 00034 #endif // USING_V4L2 00035 00036 /***** bttv api *****/ 00037 #define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int) 00038 00039 00040 static void 00041 error(const char *str, ...) 00042 { 00043 va_list ap; 00044 00045 va_start(ap, str); 00046 vfprintf(stderr, str, ap); 00047 fprintf(stderr, "\n"); 00048 va_end(ap); 00049 } 00050 00051 static void 00052 out_of_sync(struct vbi *vbi) 00053 { 00054 int i; 00055 00056 // discard all in progress pages 00057 for (i = 0; i < 8; ++i) 00058 vbi->rpage[i].page->flags &= ~PG_ACTIVE; 00059 } 00060 00061 00062 // send an event to all clients 00063 00064 static void 00065 vbi_send(struct vbi *vbi, int type, int i1, int i2, int i3, void *p1) 00066 { 00067 struct vt_event ev[1]; 00068 struct vbi_client *cl, *cln; 00069 00070 ev->resource = vbi; 00071 ev->type = type; 00072 ev->i1 = i1; 00073 ev->i2 = i2; 00074 ev->i3 = i3; 00075 ev->p1 = p1; 00076 00077 for (cl = (void*)vbi->clients->first; (cln = (void*)cl->node->next); 00078 (cl = cln)) 00079 cl->handler(cl->data, ev); 00080 } 00081 00082 static void 00083 vbi_send_page(struct vbi *vbi, struct raw_page *rvtp, int page) 00084 { 00085 struct vt_page *cvtp = 0; 00086 00087 if (rvtp->page->flags & PG_ACTIVE) 00088 { 00089 if (rvtp->page->pgno % 256 != page) 00090 { 00091 rvtp->page->flags &= ~PG_ACTIVE; 00092 enhance(rvtp->enh, rvtp->page); 00093 // if (vbi->cache) 00094 // cvtp = vbi->cache->op->put(vbi->cache, rvtp->page); 00095 vbi_send(vbi, EV_PAGE, 0, 0, 0, cvtp ?: rvtp->page); 00096 } 00097 } 00098 } 00099 00100 // fine tune pll 00101 // this routines tries to adjust the sampling point of the decoder. 00102 // it collects parity and hamming errors and moves the sampling point 00103 // a 10th of a bitlength left or right. 00104 00105 #define PLL_SAMPLES 4 // number of err vals to collect 00106 #define PLL_ERROR 4 // if this err val is crossed, readjust 00107 //#define PLL_ADJUST 4 // max/min adjust (10th of bitlength) 00108 00109 static void 00110 pll_add(struct vbi *vbi, int n, int err) 00111 { 00112 if (vbi->pll_fixed) 00113 return; 00114 00115 if (err > PLL_ERROR*2/3) // limit burst errors 00116 err = PLL_ERROR*2/3; 00117 00118 vbi->pll_err += err; 00119 vbi->pll_cnt += n; 00120 if (vbi->pll_cnt < PLL_SAMPLES) 00121 return; 00122 00123 if (vbi->pll_err > PLL_ERROR) 00124 { 00125 if (vbi->pll_err > vbi->pll_lerr) 00126 vbi->pll_dir = -vbi->pll_dir; 00127 vbi->pll_lerr = vbi->pll_err; 00128 00129 vbi->pll_adj += vbi->pll_dir; 00130 if (vbi->pll_adj < -PLL_ADJUST || vbi->pll_adj > PLL_ADJUST) 00131 { 00132 vbi->pll_adj = 0; 00133 vbi->pll_dir = -1; 00134 vbi->pll_lerr = 0; 00135 } 00136 00137 #ifdef DEBUG 00138 printf("pll_adj = %2d\n", vbi->pll_adj); 00139 #endif 00140 } 00141 vbi->pll_cnt = 0; 00142 vbi->pll_err = 0; 00143 } 00144 00145 void 00146 vbi_pll_reset(struct vbi *vbi, int fine_tune) 00147 { 00148 vbi->pll_fixed = fine_tune >= -PLL_ADJUST && fine_tune <= PLL_ADJUST; 00149 00150 vbi->pll_err = 0; 00151 vbi->pll_lerr = 0; 00152 vbi->pll_cnt = 0; 00153 vbi->pll_dir = -1; 00154 vbi->pll_adj = 0; 00155 if (vbi->pll_fixed) 00156 vbi->pll_adj = fine_tune; 00157 #ifdef DEBUG 00158 if (vbi->pll_fixed) 00159 printf("pll_reset (fixed@%d)\n", vbi->pll_adj); 00160 else 00161 printf("pll_reset (auto)\n"); 00162 #endif 00163 } 00164 00165 // process one videotext packet 00166 00167 static int 00168 vt_line(struct vbi *vbi, unsigned char *p) 00169 { 00170 struct vt_page *cvtp; 00171 struct raw_page *rvtp; 00172 int hdr, mag, mag8, pkt, i; 00173 int err = 0; 00174 00175 hdr = hamm16(p, &err); 00176 if (err & 0xf000) 00177 return -4; 00178 00179 mag = hdr & 7; 00180 mag8 = mag?: 8; 00181 pkt = (hdr >> 3) & 0x1f; 00182 p += 2; 00183 00184 rvtp = vbi->rpage + mag; 00185 cvtp = rvtp->page; 00186 00187 switch (pkt) 00188 { 00189 case 0: 00190 { 00191 int b1, b2, b3, b4; 00192 00193 b1 = hamm16(p, &err); // page number 00194 b2 = hamm16(p+2, &err); // subpage number + flags 00195 b3 = hamm16(p+4, &err); // subpage number + flags 00196 b4 = hamm16(p+6, &err); // language code + more flags 00197 00198 if (vbi->ppage->page->flags & PG_MAGSERIAL) 00199 vbi_send_page(vbi, vbi->ppage, b1); 00200 vbi_send_page(vbi, rvtp, b1); 00201 00202 if (err & 0xf000) 00203 return 4; 00204 00205 cvtp->errors = (err >> 8) + chk_parity(p + 8, 32);; 00206 cvtp->pgno = mag8 * 256 + b1; 00207 cvtp->subno = (b2 + b3 * 256) & 0x3f7f; 00208 cvtp->lang = "\0\4\2\6\1\5\3\7"[b4 >> 5] + (latin1 ? 0 : 8); 00209 cvtp->flags = b4 & 0x1f; 00210 cvtp->flags |= b3 & 0xc0; 00211 cvtp->flags |= (b2 & 0x80) >> 2; 00212 cvtp->lines = 1; 00213 cvtp->flof = 0; 00214 vbi->ppage = rvtp; 00215 00216 pll_add(vbi, 1, cvtp->errors); 00217 00218 conv2latin(p + 8, 32, cvtp->lang); 00219 vbi_send(vbi, EV_HEADER, cvtp->pgno, cvtp->subno, cvtp->flags, p); 00220 00221 if (b1 == 0xff) 00222 return 0; 00223 00224 cvtp->flags |= PG_ACTIVE; 00225 init_enhance(rvtp->enh); 00226 memcpy(cvtp->data[0]+0, p, 40); 00227 memset(cvtp->data[0]+40, ' ', sizeof(cvtp->data)-40); 00228 return 0; 00229 } 00230 00231 case 1 ... 24: 00232 { 00233 pll_add(vbi, 1, err = chk_parity(p, 40)); 00234 00235 if (~cvtp->flags & PG_ACTIVE) 00236 return 0; 00237 00238 cvtp->errors += err; 00239 cvtp->lines |= 1 << pkt; 00240 conv2latin(p, 40, cvtp->lang); 00241 memcpy(cvtp->data[pkt], p, 40); 00242 return 0; 00243 } 00244 case 26: 00245 { 00246 int d, t[13]; 00247 00248 if (~cvtp->flags & PG_ACTIVE) 00249 return 0; 00250 00251 00252 d = hamm8(p, &err); 00253 if (err & 0xf000) 00254 return 4; 00255 00256 for (i = 0; i < 13; ++i) 00257 t[i] = hamm24(p + 1 + 3*i, &err); 00258 if (err & 0xf000) 00259 return 4; 00260 00261 //printf("enhance on %x/%x\n", cvtp->pgno, cvtp->subno); 00262 add_enhance(rvtp->enh, d, (unsigned int *)t); 00263 return 0; 00264 } 00265 case 27: 00266 { 00267 // FLOF data (FastText) 00268 int b1,b2,b3,x; 00269 00270 if (~cvtp->flags & PG_ACTIVE) 00271 return 0; // -1 flushes all pages. we may never resync again :( 00272 00273 b1 = hamm8(p, &err); 00274 b2 = hamm8(p + 37, &err); 00275 if (err & 0xf000) 00276 return 4; 00277 if (b1 != 0 || !(b2 & 8)) 00278 return 0; 00279 00280 for (i = 0; i < 6; ++i) 00281 { 00282 err = 0; 00283 b1 = hamm16(p+1+6*i, &err); 00284 b2 = hamm16(p+3+6*i, &err); 00285 b3 = hamm16(p+5+6*i, &err); 00286 if (err & 0xf000) 00287 return 1; 00288 x = (b2 >> 7) | ((b3 >> 5) & 0x06); 00289 cvtp->link[i].pgno = ((mag ^ x) ?: 8) * 256 + b1; 00290 cvtp->link[i].subno = (b2 + b3 * 256) & 0x3f7f; 00291 } 00292 cvtp->flof = 1; 00293 return 0; 00294 } 00295 case 30: 00296 { 00297 if (mag8 != 8) 00298 return 0; 00299 00300 p[0] = hamm8(p, &err); // designation code 00301 p[1] = hamm16(p+1, &err); // initial page 00302 p[3] = hamm16(p+3, &err); // initial subpage + mag 00303 p[5] = hamm16(p+5, &err); // initial subpage + mag 00304 if (err & 0xf000) 00305 return 4; 00306 00307 err += chk_parity(p+20, 20); 00308 conv2latin(p+20, 20, 0); 00309 00310 vbi_send(vbi, EV_XPACKET, mag8, pkt, err, p); 00311 return 0; 00312 } 00313 default: 00314 // unused at the moment... 00315 //vbi_send(vbi, EV_XPACKET, mag8, pkt, err, p); 00316 return 0; 00317 } 00318 return 0; 00319 } 00320 00321 00322 00323 // process one raw vbi line 00324 00325 static int 00326 vbi_line(struct vbi *vbi, unsigned char *p) 00327 { 00328 unsigned char data[43], min, max; 00329 int dt[256], hi[6], lo[6]; 00330 int i, n, sync, thr; 00331 int bpb = vbi->bpb; 00332 00333 /* remove DC. edge-detector */ 00334 for (i = vbi->soc; i < vbi->eoc; ++i) 00335 dt[i] = p[i+bpb/FAC] - p[i]; // amplifies the edges best. 00336 00337 /* set barrier */ 00338 for (i = vbi->eoc; i < vbi->eoc+16; i += 2) 00339 dt[i] = 100, dt[i+1] = -100; 00340 00341 /* find 6 rising and falling edges */ 00342 for (i = vbi->soc, n = 0; n < 6; ++n) 00343 { 00344 while (dt[i] < 32) 00345 i++; 00346 hi[n] = i; 00347 while (dt[i] > -32) 00348 i++; 00349 lo[n] = i; 00350 } 00351 if (i >= vbi->eoc) 00352 return -1; // not enough periods found 00353 00354 i = hi[5] - hi[1]; // length of 4 periods (8 bits) 00355 if (i < vbi->bp8bl || i > vbi->bp8bh) 00356 return -1; // bad frequency 00357 00358 /* AGC and sync-reference */ 00359 min = 255, max = 0, sync = 0; 00360 for (i = hi[4]; i < hi[5]; ++i) 00361 if (p[i] > max) 00362 max = p[i], sync = i; 00363 for (i = lo[4]; i < lo[5]; ++i) 00364 if (p[i] < min) 00365 min = p[i]; 00366 thr = (min + max) / 2; 00367 00368 p += sync; 00369 00370 /* search start-byte 11100100 */ 00371 for (i = 4*bpb + vbi->pll_adj*bpb/10; i < 16*bpb; i += bpb) 00372 if (p[i/FAC] > thr && p[(i+bpb)/FAC] > thr) // two ones is enough... 00373 { 00374 /* got it... */ 00375 memset(data, 0, sizeof(data)); 00376 00377 for (n = 0; n < 43*8; ++n, i += bpb) 00378 if (p[i/FAC] > thr) 00379 data[n/8] |= 1 << (n%8); 00380 00381 if (data[0] != 0x27) // really 11100100? (rev order!) 00382 return -1; 00383 00384 if ((i = vt_line(vbi, data+1))) 00385 { 00386 if (i < 0) 00387 pll_add(vbi, 2, -i); 00388 else 00389 pll_add(vbi, 1, i); 00390 } 00391 return 0; 00392 } 00393 return -1; 00394 } 00395 00396 00397 00398 // called when new vbi data is waiting 00399 00400 void 00401 vbi_handler(struct vbi *vbi, int fd) 00402 { 00403 int n, i; 00404 unsigned int seq; 00405 00406 (void)fd; 00407 00408 n = read(vbi->fd, rawbuf, vbi->bufsize); 00409 00410 if (dl_empty(vbi->clients)) 00411 return; 00412 00413 if (n != vbi->bufsize) 00414 return; 00415 00416 seq = *(unsigned int *)&rawbuf[n - 4]; 00417 if (vbi->seq+1 != seq) 00418 { 00419 out_of_sync(vbi); 00420 if (seq < 3 && vbi->seq >= 3) 00421 vbi_reset(vbi); 00422 } 00423 vbi->seq = seq; 00424 00425 if (seq > 1) // the first may contain data from prev channel 00426 { 00427 #if 1 00428 for (i = 0; i+vbi->bpl <= n; i += vbi->bpl) 00429 vbi_line(vbi, rawbuf + i); 00430 #else 00431 /* work-around for old saa7134 driver versions (prior 0.2.6) */ 00432 for (i = 16 * vbi->bpl; i + vbi->bpl <= n; i += vbi->bpl) 00433 vbi_line(vbi, rawbuf + i); 00434 00435 for (i = 0; i + vbi->bpl <= 16 * vbi->bpl; i += vbi->bpl) 00436 vbi_line(vbi, rawbuf + i); 00437 #endif 00438 } 00439 } 00440 00441 00442 00443 int 00444 vbi_add_handler(struct vbi *vbi, void *handler, void *data) 00445 { 00446 struct vbi_client *cl; 00447 00448 if (!(cl = malloc(sizeof(*cl)))) 00449 return -1; 00450 cl->handler = handler; 00451 cl->data = data; 00452 // cl is not leaking, the first struct element has the same address 00453 // as the struct 00454 dl_insert_last(vbi->clients, cl->node); 00455 return 0; 00456 } 00457 00458 00459 00460 void 00461 vbi_del_handler(struct vbi *vbi, void *handler, void *data) 00462 { 00463 struct vbi_client *cl; 00464 00465 for (cl = (void*) vbi->clients->first; cl->node->next; cl = (void*) cl->node->next) 00466 if (cl->handler == handler && cl->data == data) 00467 { 00468 dl_remove(cl->node); 00469 break; 00470 } 00471 return; 00472 } 00473 00474 #ifdef USING_V4L2 00475 static int 00476 set_decode_parms(struct vbi *vbi, struct v4l2_vbi_format *p) 00477 { 00478 double fs; // sampling rate 00479 double bpb; // bytes per bit 00480 int soc, eoc; // start/end of clock run-in 00481 int bpl; // bytes per line 00482 00483 if (p->sample_format != V4L2_PIX_FMT_GREY) 00484 { 00485 fprintf(stderr, "got pix fmt %x\n", p->sample_format); 00486 error("v4l2: unsupported vbi data format"); 00487 return -1; 00488 } 00489 00490 // some constants from the standard: 00491 // horizontal frequency fh = 15625Hz 00492 // teletext bitrate ft = 444*fh = 6937500Hz 00493 // teletext identification sequence 10101010 10101010 11100100 00494 // 13th bit of seq rel to falling hsync 12us -1us +0.4us 00495 // I search for the clock run-in (10101010 10101010) from 12us-1us-12.5/ft 00496 // (earliest first bit) to 12us+0.4us+3.5/ft (latest last bit) 00497 // earlist first bit tf = 12us-1us-12.5/ft = 9.2us 00498 // latest last bit tl = 12us+0.4us+3.5/ft = 12.9us 00499 // total number of used bits n = (2+1+2+40)*8 = 360 00500 00501 bpl = p->samples_per_line; 00502 fs = p->sampling_rate; 00503 bpb = fs/6937500.0; 00504 soc = (int)(9.2e-6*fs) - (int)p->offset; 00505 eoc = (int)(12.9e-6*fs) - (int)p->offset; 00506 if (soc < 0) 00507 soc = 0; 00508 if (eoc > bpl - (int)(43*8*bpb)) 00509 eoc = bpl - (int)(43*8*bpb); 00510 if (eoc - soc < (int)(16*bpb)) 00511 { 00512 // line too short or offset too large or wrong sample_rate 00513 error("v4l2: broken vbi format specification"); 00514 return -1; 00515 } 00516 if (eoc > 240) 00517 { 00518 // the vbi_line routine can hold max 240 values in its work buffer 00519 error("v4l2: unable to handle these sampling parameters"); 00520 return -1; 00521 } 00522 00523 vbi->bpb = bpb * FAC + 0.5; 00524 vbi->soc = soc; 00525 vbi->eoc = eoc; 00526 vbi->bp8bl = 0.97 * 8*bpb; // -3% tolerance 00527 vbi->bp8bh = 1.03 * 8*bpb; // +3% tolerance 00528 00529 vbi->bpl = bpl; 00530 vbi->bufsize = bpl * (p->count[0] + p->count[1]); 00531 00532 return 0; 00533 } 00534 #endif // USING_V4L2 00535 00536 static int 00537 setup_dev(struct vbi *vbi) 00538 { 00539 #ifdef USING_V4L2 00540 struct v4l2_format v4l2_format; 00541 struct v4l2_vbi_format *vbifmt = &v4l2_format.fmt.vbi; 00542 00543 memset(&v4l2_format, 0, sizeof(v4l2_format)); 00544 v4l2_format.type = V4L2_BUF_TYPE_VBI_CAPTURE; 00545 if (ioctl(vbi->fd, VIDIOC_G_FMT, &v4l2_format) == -1) 00546 { 00547 #ifdef USING_V4L1 00548 // not a v4l2 device. assume bttv and create a standard fmt-struct. 00549 int size; 00550 perror("ioctl VIDIOC_G_FMT"); 00551 00552 vbifmt->sample_format = V4L2_PIX_FMT_GREY; 00553 vbifmt->sampling_rate = 35468950; 00554 vbifmt->samples_per_line = 2048; 00555 vbifmt->offset = 244; 00556 if ((size = ioctl(vbi->fd, BTTV_VBISIZE, 0)) == -1) 00557 { 00558 // BSD or older bttv driver. 00559 vbifmt->count[0] = 16; 00560 vbifmt->count[1] = 16; 00561 } 00562 else if (size % 2048) 00563 { 00564 error("broken bttv driver (bad buffer size)"); 00565 return -1; 00566 } 00567 else 00568 { 00569 size /= 2048; 00570 vbifmt->count[0] = size/2; 00571 vbifmt->count[1] = size - size/2; 00572 } 00573 #else 00574 error("Video 4 Linux version 1 support is not enabled."); 00575 return -1; 00576 #endif 00577 } 00578 00579 if (set_decode_parms(vbi, vbifmt) == -1) 00580 return -1; 00581 00582 if (vbi->bpl < 1 || vbi->bufsize < vbi->bpl || vbi->bufsize % vbi->bpl != 0) 00583 { 00584 error("strange size of vbi buffer (%d/%d)", vbi->bufsize, vbi->bpl); 00585 return -1; 00586 } 00587 00588 // grow buffer if necessary 00589 if (rawbuf_size < vbi->bufsize) 00590 { 00591 if (rawbuf) 00592 free(rawbuf); 00593 if (!(rawbuf = malloc(rawbuf_size = vbi->bufsize))) 00594 error("malloc refused in setup_dev()\n"); 00595 } 00596 00597 return 0; 00598 #else 00599 return -1; 00600 #endif // USING_V4L2 00601 } 00602 00603 00604 00605 struct vbi * 00606 vbi_open(const char *vbi_name, struct cache *ca, int fine_tune, int big_buf) 00607 { 00608 static int inited = 0; 00609 struct vbi *vbi = 0; 00610 00611 (void)ca; 00612 00613 if (! inited) 00614 lang_init(); 00615 inited = 1; 00616 00617 if (!(vbi = malloc(sizeof(*vbi)))) 00618 { 00619 error("out of memory"); 00620 goto fail1; 00621 } 00622 00623 if ((vbi->fd = open(vbi_name, O_RDONLY)) == -1) 00624 { 00625 error("cannot open vbi device"); 00626 goto fail2; 00627 } 00628 00629 if (big_buf != -1) 00630 error("-oldbttv/-newbttv is obsolete. option ignored."); 00631 00632 if (setup_dev(vbi) == -1) 00633 goto fail3; 00634 00635 // vbi->cache = ca; 00636 00637 dl_init(vbi->clients); 00638 vbi->seq = 0; 00639 out_of_sync(vbi); 00640 vbi->ppage = vbi->rpage; 00641 00642 vbi_pll_reset(vbi, fine_tune); 00643 // ECA removed fdset_add_fd(fds, vbi->fd, vbi_handler, vbi); 00644 return vbi; 00645 00646 fail3: 00647 close(vbi->fd); 00648 fail2: 00649 free(vbi); 00650 fail1: 00651 return 0; 00652 } 00653 00654 00655 00656 void 00657 vbi_close(struct vbi *vbi) 00658 { 00659 // fdset_del_fd(fds, vbi->fd); 00660 // if (vbi->cache) 00661 // vbi->cache->op->close(vbi->cache); 00662 close(vbi->fd); 00663 free(vbi); 00664 } 00665 00666 00667 struct vt_page * 00668 vbi_query_page(struct vbi *vbi, int pgno, int subno) 00669 { 00670 struct vt_page *vtp = 0; 00671 00672 (void)pgno; 00673 (void)subno; 00674 00675 // if (vbi->cache) 00676 // vtp = vbi->cache->op->get(vbi->cache, pgno, subno); 00677 if (vtp == 0) 00678 { 00679 // EV_PAGE will come later... 00680 return 0; 00681 } 00682 00683 vbi_send(vbi, EV_PAGE, 1, 0, 0, vtp); 00684 return vtp; 00685 } 00686 00687 void 00688 vbi_reset(struct vbi *vbi) 00689 { 00690 // if (vbi->cache) 00691 // vbi->cache->op->reset(vbi->cache); 00692 vbi_send(vbi, EV_RESET, 0, 0, 0, 0); 00693 } 00694
1.7.6.1