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

📄 tvi_vbi.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 4 页
字号:
            }        }        return lang_chars[charset][p-0x20];    }else        return 0x20;}static void init_vbi_consts(priv_vbi_t* priv){    int i,j;    double ang;    for(i=0; i<256; i++){        j=i&0x7F;        j^= j+j;        j^= j<<2;        j^= j<<4;        fixParity[i]= i ^ (j&0x80) ^ 0x80;    }    for(i=0,ang=0; i<12; i++,ang+=M_PI/priv->bpb){        si[i]= sin(ang);        co[i]= cos(ang);    }    priv->bpb=(priv->ptsp->sampling_rate/6937500.0)*ONE_FIXP+0.5;    priv->soc=FFMAX(9.2e-6*priv->ptsp->sampling_rate-priv->ptsp->offset, 0);    priv->eoc=FFMIN(12.9e-6*priv->ptsp->sampling_rate-priv->ptsp->offset,                    priv->ptsp->samples_per_line-43*8*priv->bpb/ONE_FIXP);    if (priv->eoc - priv->soc<16*priv->bpb/ONE_FIXP){ // invalid [soc:eoc]        priv->soc=0;        priv->eoc=92;    }    priv->bp8bl=0.97*8*priv->bpb/ONE_FIXP; // -3% tolerance    priv->bp8bh=1.03*8*priv->bpb/ONE_FIXP; // +3% tolerance}/** * \brief calculate increased/decreased by given value page number * \param curr  current page number in hexadecimal for * \param direction decimal value (can be negative) to add to value *        of curr parameter * \return new page number in hexadecimal form * * VBI page numbers are represented in special hexadecimal form, e.g. * page with number 123 (as seen by user) internally has number 0x123. * and equation 0x123+8 should be equal to 0x131 instead of regular 0x12b. * * * Page numbers 0xYYY (where Y is not belongs to (0..9). * Page number belongs to [0x000,0x799] or [0x100:0x899] (first 0 can be  * treated as '8') */static int steppage(int p, int direction, int skip_hidden){    if(skip_hidden)        p=(p&15)+((p>>4)&15)*10+(p>>8)*100;    p+=direction;    if(skip_hidden){        p=(p+800)%800;        p=(p%10)+((p/10)%10)*16+(p/100)*256;    }    return p&0x7ff;}/*------------------------------------------------------------------   Cache stuff------------------------------------------------------------------*//** * \brief add/update entry in cache * \param priv private data structure * \param pg page to store in cache * \param line line to update (value below 0 means update entire page) */static void put_to_cache(priv_vbi_t* priv,tt_page* pg,int line){    tt_page* pgc; //page in cache    int i,j,count;    if(line<0){        i=0;        count=VBI_ROWS*VBI_COLUMNS;    }else if(line<VBI_ROWS){        i=line*VBI_COLUMNS;        count=(line+1)*VBI_COLUMNS;    }else        return;    pthread_mutex_lock(&(priv->buffer_mutex));    if(!priv->ptt_cache[pg->pagenum]){        priv->ptt_cache[pg->pagenum]=calloc(1,sizeof(tt_page));        pgc=priv->ptt_cache[pg->pagenum];    }else{        pgc=priv->ptt_cache[pg->pagenum];        while(pgc->next_subpage && pgc->subpagenum!=pg->subpagenum)            pgc=pgc->next_subpage;        if(pgc->subpagenum!=pg->subpagenum){            pgc->next_subpage=calloc(1,sizeof(tt_page));            pgc=pgc->next_subpage;        }    }    pgc->pagenum=pg->pagenum;    pgc->subpagenum=pg->subpagenum;    pgc->primary_lang=pg->primary_lang;    pgc->secondary_lang=pg->secondary_lang;    pgc->flags=pg->flags;    for(j=0;j<6;++j)        pgc->links[j]=pg->links[j];    //instead of copying entire page into cache, copy only undamaged    //symbols into cache    for(;i<count;i++){        if(!(pg->raw[i]&0x80))            pgc->raw[i]=pg->raw[i];        else            mp_msg(MSGT_TV,MSGL_DBG3,"char error. pg:%x, c[%d]=0x%x\n",                pg->pagenum,i,pg->raw[i]);    }    pgc->active=1;    pthread_mutex_unlock(&(priv->buffer_mutex));}/** * \brief get any subpage number of given page * \param priv private data structure * \param pagenum page number to search subpages in * * \return subpage number of first found subpage which belongs to * given page number * * \note page itself is subpage too (and usually has subpage number 0) */static inline int get_subpagenum_from_cache(priv_vbi_t* priv, int pagenum){    if (!priv->ptt_cache[pagenum])        return 0x3f7f;    else        return priv->ptt_cache[pagenum]->subpagenum;}/** * \brief get page from cache by it page and subpage number * \param priv private data structure * \param pagenum page number * \param subpagenum subpage number * * \return pointer to tt_page structure if requested page is found * and NULL otherwise */static inline tt_page* get_from_cache(priv_vbi_t* priv, int pagenum,int subpagenum){    tt_page* tp=priv->ptt_cache[pagenum];    while(tp && tp->subpagenum!=subpagenum)        tp=tp->next_subpage;    return tp;}/** * \brief clears cache * \param priv private data structure * * Deletes all tt_page structures from cache and frees allocated memory. * Only zero-filled array of pointers remains in memory */static void clear_cache(priv_vbi_t* priv){    int i;    tt_page* tp;        /*      Skip next 5 buffers to avoid mixing teletext pages from different      channels during channel switch    */    priv->cache_reset=5;    for(i=0;i<VBI_MAX_PAGES;i++){        while(priv->ptt_cache[i]){            tp=priv->ptt_cache[i];            priv->ptt_cache[i]=tp->next_subpage;            free(tp);        }    }    priv->initialsubpage=priv->networkid=0;    priv->timeoffset=0;    priv->juliandate=priv->universaltime=0;    memset(priv->networkname,0,21);}/** * \brief cache initialization * \param priv private data structure * * \note Has to be called before any cache operations! */static void init_cache(priv_vbi_t* priv){    priv->ptt_cache=calloc(VBI_MAX_PAGES,sizeof(tt_page*));}/** * \brief destroys cache * \param priv private data structure * * Frees all memory allocated for cache (including array of pointers). * It is safe to call this routine multiple times */static void destroy_cache(priv_vbi_t* priv){    if(priv->ptt_cache){        clear_cache(priv);        free(priv->ptt_cache);        priv->ptt_cache=NULL;    }}/*------------------------------------------------------------------   Decoder stuff------------------------------------------------------------------*//** * \brief converts raw teletext page into useful format (1st rendering stage) * \param pg page to decode * \param raw raw data to decode page from * \param primary_lang primary language code * \param secondary_lang secondary language code* * Routine fills tt_char structure of each teletext_page character with proper * info about foreground and background colors, character * type (graphics/control/text). */static void decode_page(tt_char* p,unsigned char* raw,int primary_lang,int secondary_lang,int flags){    int row,col;    int prim_charset=lang2charset(primary_lang);    int sec_charset=lang2charset(secondary_lang);    for(row=0;row<VBI_ROWS;row++)   {        int prim_lang=1;        int gfx=0;        int fg_color=7;        int bg_color=0;        int separated=0;        int conceal=0;        int hold=0;        int flash=0;        int box=0;        tt_char tt_held=tt_space;        for(col=0;col<VBI_COLUMNS;col++){            int i=row*VBI_COLUMNS+col;            int c=raw[i];            p[i].raw=c;            if(c&0x80){ //damaged char                p[i]=tt_error;                continue;            }            if((flags&TT_PGFL_SUBTITLE) || (flags&TT_PGFL_NEWFLASH))                p[i].hidden=!box;            else                p[i].hidden=0;            p[i].gfx=gfx?(separated?2:1):0;            p[i].lng=prim_lang;            p[i].ctl=(c&0x60)==0?1:0;            p[i].fg=fg_color;            p[i].bg=bg_color;            p[i].flh=flash;                        if ((c&0x60)==0){ //control chars                if(c>=0x08 && c<=0x09){//Flash/Steady                    flash=c==0x08;                    p[i].flh=flash;                    if(c==0x09){                        p[i].fg=fg_color;                        p[i].bg=bg_color;                    }                }else if(c>=0x0a && c<=0x0b){                    box=c&1;                }else if(c>=0x0c && c<=0x0f){                }else if (c<=0x17){ //colors                    fg_color=c&0x0f;                    gfx=c>>4;                    conceal=0;                    if(!gfx) hold=0;                }else if (c<=0x18){                    conceal=1;                }else if (c<=0x1a){ //Contiguous/Separated gfx                    separated=!(c&1);                }else if (c<=0x1b){                    prim_lang=!prim_lang;                }else if (c<=0x1d){                    bg_color=(c&1)?fg_color:0;                    p[i].bg=bg_color;                }else{ //Hold/Release Graphics                    hold=!(c&1);                }                p[i].ctl=1;                if(hold || c==0x1f){                    p[i]=tt_held;                    p[i].fg=fg_color;                    p[i].bg=bg_color;                }else                    p[i].unicode=p[i].gfx?0:' ';                continue;            }            if(conceal){                p[i].gfx=0;                p[i].unicode=' ';            }else if(gfx){                p[i].unicode=c-0x20;                if (p[i].unicode>0x3f) p[i].unicode-=0x20;                tt_held=p[i];            }else{                if(p[i].lng){                    p[i].unicode=conv2uni(c,prim_charset,primary_lang&7);                }else{                    p[i].unicode=conv2uni(c,sec_charset,secondary_lang&7);                }            }            p[i].fg=fg_color;            p[i].bg=bg_color;        }    }}/** * \brief prepares current page for displaying * \param priv_vbi private data structure * * Routine adds some useful info (time and page number of page, grabbed by * background thread to top line of current page). Displays "No teletext" * string if no vbi data available. */#define PRINT_HEX(dp,i,h) dp[i].unicode=((h)&0xf)>9?'A'+((h)&0xf)-10:'0'+((h)&0xf)static void prepare_visible_page(priv_vbi_t* priv){    tt_page *pg,*curr_pg;    unsigned char *p;    int i;    pthread_mutex_lock(&(priv->buffer_mutex));    mp_msg(MSGT_TV,MSGL_DBG3,"tvi_vbi: prepare_visible_page pg:0x%x, sub:0x%x\n",        priv->pagenum,priv->subpagenum);    if(priv->subpagenum==0x3f7f) //no page yet        priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum);    pg=get_from_cache(priv,priv->pagenum,priv->subpagenum);    mp_dbg(MSGT_TV,MSGL_DBG3,"tvi_vbi: prepare_vibible_page2 pg:0x%x, sub:0x%x\n",        priv->pagenum,priv->subpagenum);    curr_pg=get_from_cache(priv,priv->curr_pagenum,        get_subpagenum_from_cache(priv,priv->curr_pagenum));    if (!pg && !curr_pg){        p=MSGTR_TV_NoTeletext;        for(i=0;i<VBI_COLUMNS && *p;i++){            GET_UTF8(priv->display_page[i].unicode,*p++,break;);        }        for(;i<VBI_ROWS*VBI_COLUMNS;i++)            priv->display_page[i]=tt_space;        pthread_mutex_unlock(&(priv->buffer_mutex));        return;    }    if (!pg || !pg->active){        for(i=0;i<VBI_ROWS*VBI_COLUMNS;i++){            priv->display_page[i]=tt_space;        }    }else{        decode_page(priv->display_page,pg->raw,pg->primary_lang,pg->secondary_lang,pg->flags);        mp_msg(MSGT_TV,MSGL_DBG3,"page #%x was decoded!\n",pg->pagenum);    }    PRINT_HEX(priv->display_page,0,(priv->curr_pagenum&0x700)?priv->curr_pagenum>>8:8);    PRINT_HEX(priv->display_page,1,priv->curr_pagenum>>4);    PRINT_HEX(priv->display_page,2,priv->curr_pagenum);    priv->display_page[3].unicode=' ';    priv->display_page[4].unicode=' ';    switch(priv->pagenumdec>>12){    case 1:        priv->display_page[5].unicode='_';        priv->display_page[6].unicode='_';        PRINT_HEX(priv->display_page,7,priv->pagenumdec);        break;    case 2:        priv->display_page[5].unicode='_';        PRINT_HEX(priv->display_page,6,priv->pagenumdec>>4);        PRINT_HEX(priv->display_page,7,priv->pagenumdec);    break;    default:        PRINT_HEX(priv->display_page,5,(priv->pagenum&0x700)?priv->pagenum>>8:8);        PRINT_HEX(priv->display_page,6,priv->pagenum>>4);        PRINT_HEX(priv->display_page,7,priv->pagenum);    }    if(priv->subpagenum!=0x3f7f){        priv->display_page[8].unicode='.';        PRINT_HEX(priv->display_page,9,priv->subpagenum>>4);        PRINT_HEX(priv->display_page,10,priv->subpagenum);    }else{        priv->display_page[8].unicode=' ';        priv->display_page[9].unicode=' ';        priv->display_page[10].unicode=' ';    }    priv->display_page[11].unicode=' ';    for(i=VBI_COLUMNS;i>VBI_TIME_LINEPOS ||             ((curr_pg->raw[i]&0x60) && curr_pg->raw[i]!=0x20 && i>11);            --i)        if(curr_pg->raw[i]&0x60)            priv->display_page[i].unicode=curr_pg->raw[i];        else            priv->display_page[i].unicode=' ';    pthread_mutex_unlock(&(priv->buffer_mutex));}/*------------------------------------------------------------------   Renderer stuff------------------------------------------------------------------*/#ifdef DEBUG_DUMP/** * \brief renders teletext page into given file * \param pt page to render * \param f opened file descriptor * \param pagenum which page to render * \param colored use colors not implementede yet) * * Text will be UTF8 encoded */static void render2text(tt_page* pt,FILE* f,int colored){    int i,j;    unsigned int u;    unsigned char buf[8];    unsigned char tmp;    int pos;    tt_char dp[VBI_ROWS*VBI_COLUMNS];    int color=0;    int bkg=0;    int c1,b1;    if(!pt)        return;    fprintf(f,"+========================================+\n");    fprintf(f,"| lang:%d pagenum:0x%x subpagenum:%d flags:0x%x|\n",    pt->lang,    pt->pagenum,    pt->subpagenum,    0);    fprintf(f,"+----------------------------------------+\n");    decode_page(dp,pt->raw,pt->primary_lang,pt->secondary_lang,pt->flags);    for(i=0;i<VBI_ROWS;i++){        fprintf(f,"|");        if(colored) fprintf(f,"\033[40m");        for(j=0;j<VBI_COLUMNS;j++)        {             u=dp[i*VBI_COLUMNS+j].unicode;              if(dp[i*VBI_COLUMNS+j].fg <= 7)                c1=30+dp[i*VBI_COLUMNS+j].fg;              else                c1=38;              if(dp[i*VBI_COLUMNS+j].bg <= 7)                  b1=40+dp[i*VBI_COLUMNS+j].bg;              else                b1=40;            if (b1!=bkg  && colored){                fprintf(f,"\033[%dm",b1);                bkg=b1;            }            if(c1!=color && colored){

⌨️ 快捷键说明

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