⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tvi_vbi.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 4 页
字号:
                fprintf(f,"\033[%dm",c1);                color=c1;            }            if(dp[i*VBI_COLUMNS+j].gfx){                fprintf(f,"*");            }else{                pos=0;                PUT_UTF8(u,tmp,if(pos<7) buf[pos++]=tmp;);                buf[pos]='\0';                fprintf(f,"%s",buf);            }        }        if (colored) fprintf(f,"\033[0m");        color=-1;bkg=-1;        fprintf(f,"|\n");    }#if 1    //for debug    fprintf(f,"+====================raw=================+\n");    for(i=0;i<VBI_ROWS;i++){        for(j=0;j<VBI_COLUMNS;j++)            fprintf(f,"%02x ",dp[i*VBI_COLUMNS+j].raw);        fprintf(f,"\n");    }    fprintf(f,"+====================lng=================+\n");    for(i=0;i<VBI_ROWS;i++){        for(j=0;j<VBI_COLUMNS;j++)            fprintf(f,"%02x ",dp[i*VBI_COLUMNS+j].lng);        fprintf(f,"\n");    }#endif    fprintf(f,"+========================================+\n");}/** * \brief dump page into pgXXX.txt file in vurrent directory * \param pt page to dump * * \note XXX in filename is page number * \note use only for debug purposes */static void dump_page(tt_page* pt){    FILE*f;    char name[100];    snprintf(name,99,"pg%x.txt",pt->pagenum);    f=fopen(name,"wb");    render2text(pt,f,1);    fclose(f);}#endif //DEBUG_DUMP/** * \brief checks whether page is ready and copies it into cache array if so * \param priv private data structure * \param magAddr page's magazine address (0-7) * * Routine also calls decode_page to perform 1st stage of rendering */static void store_in_cache(priv_vbi_t* priv, int magAddr, int line){    mp_msg(MSGT_TV,MSGL_DBG2,"store_in_cache(%d): pagenum:%x\n",        priv->mag[magAddr].order,        priv->mag[magAddr].pt->pagenum);    put_to_cache(priv,priv->mag[magAddr].pt,line);    priv->curr_pagenum=priv->mag[magAddr].pt->pagenum;#ifdef DEBUG_DUMP    dump_page(get_from_cache(priv,        priv->mag[magAddr].pt->pagenum,        priv->mag[magAddr].pt->subpagenum));#endif}/*------------------------------------------------------------------  Grabber stuff------------------------------------------------------------------*/#define PLL_SAMPLES 4#define PLL_ERROR   4#define PLL_ADJUST  4/** * \brief adjust current phase for better signal decoding * \param n count of bytes processed (?) * \param err count of error bytes (?) * * \remarks code was got from MythTV project */static void pll_add(priv_vbi_t* priv,int n,int err){    if(priv->pll_fixed)        return;    if(err>PLL_ERROR*2/3)        err=PLL_ERROR*2/3;    priv->pll_err+=err;    priv->pll_cnt+=n;    if(priv->pll_cnt<PLL_SAMPLES)        return;    if(priv->pll_err>PLL_ERROR)    {        if(priv->pll_err>priv->pll_lerr)            priv->pll_dir= -priv->pll_dir;        priv->pll_lerr=priv->pll_err;        priv->pll_adj+=priv->pll_dir;        if (priv->pll_adj<-PLL_ADJUST || priv->pll_adj>PLL_ADJUST)        {            priv->pll_adj=0;            priv->pll_dir=-1;            priv->pll_lerr=0;        }        mp_msg(MSGT_TV,MSGL_DBG3,"vbi: pll_adj=%2d\n",priv->pll_adj);    }    priv->pll_cnt=0;    priv->pll_err=0;}/** * \brief reset error correction * \param priv private data structure * \param fine_tune shift value for adjusting * * \remarks code was got from MythTV project */static void pll_reset(priv_vbi_t* priv,int fine_tune){    priv->pll_fixed=fine_tune >= -PLL_ADJUST && fine_tune <= PLL_ADJUST;    priv->pll_err=0;    priv->pll_lerr=0;    priv->pll_cnt=0;    priv->pll_dir=-1;    priv->pll_adj=0;    if(priv->pll_fixed)        priv->pll_adj=fine_tune;    if(priv->pll_fixed)        mp_msg(MSGT_TV,MSGL_DBG3,"pll_reset (fixed@%2d)\n",priv->pll_adj);    else        mp_msg(MSGT_TV,MSGL_DBG3,"pll_reset (auto)\n");}/** * \brief decode packet 0 (teletext page header) * \param priv private data structure * \param data raw teletext data (with not applied hamm correction yet) * \param magAddr teletext page's magazine address * * \remarks * data buffer was shifted by 6 and now contains: *  0..1 page number *  2..5 sub-code *  6..7 control codes *  8..39 display data * *  only first 8 bytes protected by Hamm 8/4 code */static int decode_pkt0(priv_vbi_t* priv,unsigned char* data,int magAddr){    int d[8];    int i,err;    if (magAddr<0 || magAddr>7)        return 0;    for(i=0;i<8;i++){        d[i]= corrHamm48[ data[i] ];        if(d[i]&0x80){            pll_add(priv,2,4);            if(priv->mag[magAddr].pt)                  free(priv->mag[magAddr].pt);            priv->mag[magAddr].pt=NULL;            priv->mag[magAddr].order=0;            return 0;        }    }    if (!priv->mag[magAddr].pt)        priv->mag[magAddr].pt= malloc(sizeof(tt_page));    if(priv->primary_language)        priv->mag[magAddr].pt->primary_lang=priv->primary_language;    else        priv->mag[magAddr].pt->primary_lang= (d[7]&7)>>1;    priv->mag[magAddr].pt->secondary_lang=priv->secondary_language;    priv->mag[magAddr].pt->subpagenum=(d[2]|(d[3]<<4)|(d[4]<<8)|(d[5]<<12))&0x3f7f;    priv->mag[magAddr].pt->pagenum=(magAddr<<8) | d[0] | (d[1]<<4);    priv->mag[magAddr].pt->flags=((d[7]&1)<<7) | ((d[3]&8)<<3) | ((d[5]&12)<<2) | d[6];    memset(priv->mag[magAddr].pt->raw, 0x00, VBI_COLUMNS*VBI_ROWS);    priv->mag[magAddr].order=0;    for(i=0;i<8;i++){        priv->mag[magAddr].pt->raw[i]=0x20;    }    err=0;    for(i=8; i<VBI_COLUMNS; i++){        data[i]= fixParity[data[i]];        priv->mag[magAddr].pt->raw[i]=data[i];        if(data[i]&0x80) //Error            err++;        pll_add(priv,1,err);    }    store_in_cache(priv,magAddr,0);    return 1;}/** * \brief decode teletext 8/30 Format 1 packet * \param priv private data structure * \param data raw teletext data (with not applied hamm correction yet) * \param magAddr teletext page's magazine address * * \remarks * packet contains: * 0      designation code * 1..2   initial page * 3..6   initial subpage & magazine address * 7..8   network id * 9      time offset * 10..12 julian date * 13..15 universal time * 20..40 network name * * First 7 bytes are protected by Hamm 8/4 code. * Bytes 20-40 has odd parity check. * * See subcaluse 9.8.1 of specification for details */static int decode_pkt30(priv_vbi_t* priv,unsigned char* data,int magAddr){    int d[8];    int i,err;    for(i=0;i<7;i++){        d[i]= corrHamm48[ data[i] ];        if(d[i]&0x80){            pll_add(priv,2,4);            return 0;        }        d[i]&=0xf;    }    err=0;    for(i=20; i<40; i++){        data[i]= fixParity[data[i]];        if(data[i]&0x80)//Unrecoverable error            err++;        pll_add(priv,1,err);    }    if (err) return 0;    if (d[0]&0xe) //This is not 8/30 Format 1 packet        return 1;    priv->initialpage=d[1] | d[2]<<4 | (d[6]&0xc)<<7 | (d[4]&1)<<8;    priv->initialsubpage=d[3] | d[4]<<4 | d[5]<<8 | d[6]<<12;    priv->networkid=data[7]<<8 | data[8];    priv->timeoffset=(data[9]>>1)&0xf;    if(data[9]&0x40)        priv->timeoffset=-priv->timeoffset;    priv->juliandate=(data[10]&0xf)<<16 | data[11]<<8 | data[12];    priv->juliandate-=0x11111;    priv->universaltime=data[13]<<16 | data[14]<<8 | data[15];    priv->universaltime-=0x111111;    snprintf(priv->networkname,21,"%s",data+20);    return 1;}/** * \brief decode packets 1..24 (teletext page header) * \param priv private data structure * \param data raw teletext data * \param magAddr teletext page's magazine address * \param rowAddr teletext page's row number * * \remarks * data buffer was shifted by 6 and now contains 40 bytes of display data: * this type of packet is not proptected by Hamm 8/4 code */static void decode_pkt_page(priv_vbi_t* priv,unsigned char*data,int magAddr,int rowAddr){    int i,err;    if (!priv->mag[magAddr].pt)        return;    priv->mag[magAddr].order=rowAddr;    err=0;    for(i=0; i<VBI_COLUMNS; i++){        data[i]= fixParity[ data[i] ];        priv->mag[magAddr].pt->raw[i+rowAddr*VBI_COLUMNS]=data[i];        if( data[i]&0x80) //HammError            err++;    }    pll_add(priv,1,err);    store_in_cache(priv,magAddr,rowAddr);}/** * \brief decode packets 27 (teletext links) * \param priv private data structure * \param data raw teletext data * \param magAddr teletext page's magazine address */static int decode_pkt27(priv_vbi_t* priv,unsigned char* data,int magAddr){    int i,hpg;    if (!priv->mag[magAddr].pt)        return 0;    for(i=0;i<38;++i)        if ((data[i] = corrHamm48[ data[i] ]) & 0x80){            pll_add(priv,2,4);            return 0;        }    /*       Not a X/27/0 Format 1 packet or      flag "show links on row 24" is not set.    */    if (data[0] || !(data[37] & 8))        return 1;    for(i=0;i<6;++i) {        hpg = (magAddr<<8) ^ ((data[4+i*6]&0x8)<<5 | (data[6+i*6]&0xc)<<7);        if (!hpg) hpg=0x800;        priv->mag[magAddr].pt->links[i].pagenum = (data[1+i*6] & 0xf) |                ((data[2+i*6] & 0xf) << 4) | hpg;        priv->mag[magAddr].pt->links[i].subpagenum = ((data[3+i*6] & 0xf) |                (data[4+i*6] & 0xf) << 4 | (data[5+i*6] & 0xf) << 8 |                (data[6+i*6] & 0xf) << 12) & 0x3f7f;    }    put_to_cache(priv,priv->mag[magAddr].pt,-1);    return 1;}/** * \brief Decode teletext X/28/0 Format 1 packet * \param priv private data structure * \param data raw teletext data * * Primary G0 charset is transmitted in bits 14-8 of Triplet 1 * See Table 32 of specification for details. * * Secondary G0 charset is transmitted in bits 3-1 of Triplet 2 and * bits 18-15 of Triplet 1 * See Table 33 of specification for details. * */static void decode_pkt28(priv_vbi_t* priv,unsigned char*data){    int d;    int t1,t2;    d=corrHamm48[ data[0] ];    if(d) return; //this is not X/28/0 Format 1 packet or error occured    t1=corrHamm24(data+1);    t2=corrHamm24(data+4);    if (t1<0 || t2<0){        pll_add(priv,1,4);        return;    }    priv->primary_language=(t1>>7)&0x7f;    priv->secondary_language=((t2<<4) | (t1>>14))&0x7f;    if (priv->secondary_language==0x7f)         //No secondary language required        priv->secondary_language=priv->primary_language;    else // Swapping bits 1 and 3        priv->secondary_language=(priv->secondary_language&0x7a) |                                (priv->secondary_language&4)>>2 |                                (priv->secondary_language&1)<<2;    mp_msg(MSGT_TV,MSGL_DBG2,"pkt28: language: primary=%02x secondary=0x%02x\n",        priv->primary_language,priv->secondary_language);}/** * \brief decodes raw vbi data (signal amplitudes) into sequence of bytes * \param priv private data structure * \param buf raw vbi data (one line of frame) * \param data output buffer for decoded bytes (at least 45 bytes long) * * Used XawTV's algorithm. Signal phase is calculated with help of starting clock * run-in sequence (min/max values and bit distance values are calculated) */static int decode_raw_line_runin(priv_vbi_t* priv,unsigned char* buf,unsigned char* data){    const int magic= 0x27; // reversed 1110010    int dt[256],hi[6],lo[6];    int i,x,r;    int decoded;    int sync;    unsigned char min,max;    int thr=0; //threshold    //stubs    int soc=priv->soc;    int eoc=priv->eoc;    for(i=soc;i<eoc;i++)        dt[i]=buf[i+priv->bpb/ONE_FIXP]-buf[i];    // amplifies the edges best.    /* set barrier */    for (i=eoc; i<eoc+16; i+=2)        dt[i]=100, dt[i+1]=-100;    /* find 6 rising and falling edges */    for (i=soc, x=0; x<6; ++x)    {        while (dt[i]<32)            i++;        hi[x]=i;        while (dt[i]>-32)            i++;        lo[x]=i;    }    if (i>=eoc)    {        return 0;      // not enough periods found    }    i=hi[5]-hi[1]; // length of 4 periods (8 bits)    if (i<priv->bp8bl || i>priv->bp8bh)    {        mp_msg(MSGT_TV,MSGL_DBG3,"vbi: wrong freq %d (%d,%d)\n",            i,priv->bp8bl,priv->bp8bh);        return 0;      // bad frequency    }    /* AGC and sync-reference */    min=255, max=0, sync=0;    for (i=hi[4]; i<hi[5]; ++i)        if (buf[i]>max)            max=buf[i], sync=i;    for (i=lo[4]; i<lo[5]; ++i)        if (buf[i]<min)            min=buf[i];    thr=(min+max)/2;    buf+=sync;    // searching for '11'    for(i=priv->pll_adj*priv->bpb/10;i<16*priv->bpb;i+=priv->bpb)        if(buf[FIXP2INT(i)]>thr && buf[FIXP2INT(i+priv->bpb)]>thr)            break;    r=0;    for(decoded=1; decoded<= (VBI_COLUMNS+3)<<3;decoded++){        r>>=1;        if(buf[FIXP2INT(i)]>thr) r|=0x80;        if(!(decoded & 0x07)){            data[(decoded>>3) - 1]=r;            r=0;        }        i+=priv->bpb;    }    if(data[0]!=magic)        return 0; //magic not found    //stub    for(i=0;i<43;i++){        data[i]=data[i+1];    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -