MythTV  0.26-pre
vbi.c
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends