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

📄 tvi_vbi.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 4 页
字号:
    mp_msg(MSGT_TV,MSGL_DBG3,"thr:%d sync:%d ",thr,sync);    return 1;}#if 0//See comment in vbi_decode for a reason of commenting out this routine./** * \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 Michael Niedermayer's algorithm. * Signal phase is calculated using correlation between given samples data and * pure sine */static int decode_raw_line_sine(priv_vbi_t* priv,unsigned char* buf,unsigned char* data){    int i,x,r,amp,xFixp;    int avg=0;    double sin_sum=0, cos_sum=0;    for(x=0; x< FIXP2INT(10*priv->bpb); x++)      avg+=buf[x];    avg/=FIXP2INT(10*priv->bpb);    for(x=0; x<12; x++){      amp= buf[x<<1];      sin_sum+= si[x]*(amp-avg);      cos_sum+= co[x]*(amp-avg);    }    //this is always zero. Why ?    xFixp= atan(sin_sum/cos_sum)*priv->bpb/M_PI;    //Without this line the result is full of errors    //and routine is unable to find magic sequence    buf+=FIXP2INT(10*priv->bpb);    r=0;    for(x=FIXP2INT(xFixp);x<70;x=FIXP2INT(xFixp)){      r=(r<<1) & 0xFFFF;      if(buf[x]>avg) r|=1;      xFixp+=priv->bpb;      if(r==0xAAE4) break;    }    //this is not teletext    if (r!=0xaae4) return 0;    //Decode remaining 45-2(clock run-in)-1(framing code)=42 bytes    for(i=1; i<=(42<<3); i++){      r>>=1;      x=FIXP2INT(xFixp);      if(buf[x]> avg)          r|=0x80;      if(!(i & 0x07)){          data[(i>>3)-1]=r;          r=0;      }      xFixp+=priv->bpb;    }    return 1;}#endif/** * \brief decodes all vbi lines from one video frame * \param priv private data structure * \param buf buffer with raw vbi data in it * * \note buffer size have to be at least priv->ptsp->bufsize bytes */static void vbi_decode(priv_vbi_t* priv,unsigned char*buf){    int magAddr;    int pkt;    unsigned char data[64];    unsigned char* linep;    int d0,d1;    int i=0;    mp_msg(MSGT_TV,MSGL_DBG3,"vbi: vbi_decode\n");    for(linep=buf; !priv->cache_reset && linep<buf+priv->ptsp->bufsize; linep+=priv->ptsp->samples_per_line,i++){#if 0        /*          This routine is alternative implementation of raw VBI data decoding.          Unfortunately, it detects only about 20% of incoming data,          but Michael says that this algorithm is better, and he wants to fix it.        */        if(decode_raw_line_sine(priv,linep,data)<=0){#endif        if(decode_raw_line_runin(priv,linep,data)<=0){             continue; //this is not valid teletext line        }        d0= corrHamm48[ data[0] ];        d1= corrHamm48[ data[1] ];        if(d0&0x80 || d1&0x80){           pll_add(priv,2,4);           mp_msg(MSGT_TV,MSGL_V,"vbi_decode(%d):HammErr after decode_raw_line\n",i);           continue; //hamError        }        magAddr=d0 & 0x7;        pkt=(d0>>3)|(d1<<1);        mp_msg(MSGT_TV,MSGL_DBG3,"vbi_decode(%d):%x %x (mag:%x, pkt:%d)\n",            i,d0,d1,magAddr,pkt);        if(!pkt){            decode_pkt0(priv,data+2,magAddr); //skip MRGA        }else if(pkt>0 && pkt<VBI_ROWS){            if(!priv->mag[magAddr].pt) continue;            decode_pkt_page(priv,data+2,magAddr,pkt);//skip MRGA        }else if(pkt==27) {            decode_pkt27(priv,data+2,magAddr);        }else if(pkt==28){            decode_pkt28(priv,data+2);        }else if(pkt==30){            decode_pkt30(priv,data+2,magAddr);        } else {            mp_msg(MSGT_TV,MSGL_DBG3,"unsupported packet:%d\n",pkt);        }    }    if (priv->cache_reset){        pthread_mutex_lock(&(priv->buffer_mutex));        priv->cache_reset--;        pthread_mutex_unlock(&(priv->buffer_mutex));    }}/*---------------------------------------------------------------------------------    Public routines---------------------------------------------------------------------------------*//** * \brief toggles teletext page displaying format * \param priv_vbi private data structure * \param flag new format * \return *   TVI_CONTROL_TRUE is success, *   TVI_CONTROL_FALSE otherwise * * flag: * 0 - opaque * 1 - transparent * 2 - opaque  with black foreground color (only in bw mode) * 3 - transparent  with black foreground color (only in bw mode) */static int teletext_set_format(priv_vbi_t * priv, teletext_format flag){    flag&=3;    mp_msg(MSGT_TV,MSGL_DBG3,"teletext_set_format_is called. mode:%d\n",flag);    pthread_mutex_lock(&(priv->buffer_mutex));    priv->tformat=flag;    priv->pagenumdec=0;    pthread_mutex_unlock(&(priv->buffer_mutex));    return TVI_CONTROL_TRUE;}/** * \brief append just entered digit to editing page number * \param priv_vbi private data structure * \param dec decimal digit to append * *  dec: *   '0'..'9' append digit *    '-' remove last digit (backspace emulation) * * This routine allows user to jump to arbitrary page. * It implements simple page number editing algorithm. * * Subsystem can be on one of two modes: normal and page number edit mode. * Zero value of priv->pagenumdec means normal mode * Non-zero value means page number edit mode and equals to packed * decimal number of already entered part of page number. * * How this works. * Let's assume that current mode is normal (pagenumdec is zero), teletext page * 100 are displayed as usual. topmost left corner of page contains page number. * Then vbi_add_dec is sequentially called (through slave * command of course) with 1,4,-,2,3 * values of dec parameter. * * +-----+------------+------------------+ * | dec | pagenumdec | displayed number | * +-----+------------+------------------+ * |     | 0x000      | 100              | * +-----+------------+------------------+ * | 1   | 0x001      | __1              | * +-----+------------+------------------+ * | 4   | 0x014      | _14              | * +-----+------------+------------------+ * | -   | 0x001      | __1              | * +-----+------------+------------------+ * | 2   | 0x012      | _12              | * +-----+------------+------------------+ * | 3   | 0x123      | 123              | * +-----+------------+------------------+ * |     | 0x000      | 123              | * +-----+------------+------------------+ * * pagenumdec will automatically receive zero value after third digit of page * number is entered and current page will be switched to another one with * entered page number. */static void vbi_add_dec(priv_vbi_t * priv, char *dec){    int count, shift;    if (!dec)        return;    if (!priv->on)        return;    if ((*dec<'0' || *dec>'9') && *dec!='-')        return;    if (!priv->pagenumdec) //first digit cannot be '0','9' or '-'        if(*dec=='-' || *dec=='0' || *dec=='9')            return;    pthread_mutex_lock(&(priv->buffer_mutex));    count=(priv->pagenumdec>>12)&0xf;    if (*dec=='-') {        count--;        if (count)            priv->pagenumdec=((priv->pagenumdec>>4)&0xfff)|(count<<12);        else            priv->pagenumdec=0;    } else {        shift = count * 4;        count++;        priv->pagenumdec=            (((priv->pagenumdec)<<4|(*dec-'0'))&0xfff)|(count<<12);        if (count==3) {            priv->pagenum=priv->pagenumdec&0x7ff;            priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum);            priv->pagenumdec=0;        }    }    pthread_mutex_unlock(&(priv->buffer_mutex));}/** * \brief Teletext control routine * \param priv_vbi private data structure * \param cmd command * \param arg command parameter (has to be not null) */int teletext_control(void* p, int cmd, void *arg){    int fine_tune=99;    priv_vbi_t* priv=(priv_vbi_t*)p;    tt_page* pgc;    if (!priv && cmd!=TV_VBI_CONTROL_START)        return TVI_CONTROL_FALSE;    if (!arg && cmd!=TV_VBI_CONTROL_STOP && cmd!=TV_VBI_CONTROL_MARK_UNCHANGED)        return TVI_CONTROL_FALSE;    switch (cmd) {    case TV_VBI_CONTROL_RESET:    {        int i;        tv_param_t* tv_param=arg;        pthread_mutex_lock(&(priv->buffer_mutex));        priv->pagenumdec=0;        clear_cache(priv);        priv->pagenum=steppage(0,tv_param->tpage&0x7ff,1);        priv->tformat=tv_param->tformat;        priv->subpagenum=0x3f7f;        pll_reset(priv,fine_tune);        if(tv_param->tlang==-1){            mp_msg(MSGT_TV,MSGL_INFO,MSGTR_TV_TTSupportedLanguages);            for(i=0; tt_languages[i].lang_code; i++){                mp_msg(MSGT_TV,MSGL_INFO,"  %3d  %s\n",                    tt_languages[i].lang_code, tt_languages[i].lang_name);            }            mp_msg(MSGT_TV,MSGL_INFO,"  %3d  %s\n",                tt_languages[i].lang_code, tt_languages[i].lang_name);        }else{            for(i=0; tt_languages[i].lang_code; i++){                if(tt_languages[i].lang_code==tv_param->tlang)                    break;            }            if (priv->primary_language!=tt_languages[i].lang_code){                mp_msg(MSGT_TV,MSGL_INFO,MSGTR_TV_TTSelectedLanguage,                    tt_languages[i].lang_name);                priv->primary_language=tt_languages[i].lang_code;            }        }        priv->page_changed=1;        pthread_mutex_unlock(&(priv->buffer_mutex));        return TVI_CONTROL_TRUE;    }    case TV_VBI_CONTROL_START:    {        int i;        tt_stream_props* ptsp=*(tt_stream_props**)arg;        if(!ptsp)            return TVI_CONTROL_FALSE;        priv=calloc(1,sizeof(priv_vbi_t));        priv->ptsp=malloc(sizeof(tt_stream_props));        memcpy(priv->ptsp,ptsp,sizeof(tt_stream_props));        *(priv_vbi_t**)arg=priv;        priv->subpagenum=0x3f7f;        pthread_mutex_init(&priv->buffer_mutex, NULL);        priv->pagenumdec=0;        for(i=0;i<VBI_ROWS*VBI_COLUMNS;i++)            priv->display_page[i]=tt_space;        priv->mag=calloc(8,sizeof(mag_t));        init_cache(priv);        init_vbi_consts(priv);        pll_reset(priv,fine_tune);        priv->page_changed=1;        return TVI_CONTROL_TRUE;    }    case TV_VBI_CONTROL_STOP:    {        if(priv->mag)            free(priv->mag);        if(priv->ptsp)            free(priv->ptsp);        destroy_cache(priv);        priv->page_changed=1;        free(priv);        return TVI_CONTROL_TRUE;    }    case TV_VBI_CONTROL_SET_MODE:        priv->on=(*(int*)arg%2);        priv->page_changed=1;        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_GET_MODE:        *(int*)arg=priv->on;        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_SET_FORMAT:        priv->page_changed=1;        return teletext_set_format(priv, *(int *) arg);    case TV_VBI_CONTROL_GET_FORMAT:        pthread_mutex_lock(&(priv->buffer_mutex));        *(int*)arg=priv->tformat;        pthread_mutex_unlock(&(priv->buffer_mutex));        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_GET_HALF_PAGE:        if(!priv->on)            return TVI_CONTROL_FALSE;        *(int *)arg=priv->zoom;        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_SET_HALF_PAGE:    {        int val=*(int*)arg;        val%=3;        if(val<0)            val+=3;        pthread_mutex_lock(&(priv->buffer_mutex));        priv->zoom=val;        priv->page_changed=1;        pthread_mutex_unlock(&(priv->buffer_mutex));        return TVI_CONTROL_TRUE;    }    case TV_VBI_CONTROL_GO_LINK:    {        int val=*(int *) arg;        if(val<1 || val>6)            return TVI_CONTROL_FALSE;        pthread_mutex_lock(&(priv->buffer_mutex));        if (!(pgc = priv->ptt_cache[priv->pagenum])) {            pthread_mutex_unlock(&(priv->buffer_mutex));            return TVI_CONTROL_FALSE;        }        if (!pgc->links[val-1].pagenum || pgc->links[val-1].pagenum>0x7ff) {            pthread_mutex_unlock(&(priv->buffer_mutex));            return TVI_CONTROL_FALSE;        }        priv->pagenum=pgc->links[val-1].pagenum;        if(pgc->links[val-1].subpagenum!=0x3f7f)            priv->subpagenum=pgc->links[val-1].subpagenum;        else            priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum);        priv->page_changed=1;        pthread_mutex_unlock(&(priv->buffer_mutex));        return TVI_CONTROL_TRUE;    }    case TV_VBI_CONTROL_SET_PAGE:    {        int val=*(int *) arg;        if(val<100 || val>0x899)            return TVI_CONTROL_FALSE;        pthread_mutex_lock(&(priv->buffer_mutex));        priv->pagenum=val&0x7ff;        priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum);        priv->pagenumdec=0;        priv->page_changed=1;        pthread_mutex_unlock(&(priv->buffer_mutex));        return TVI_CONTROL_TRUE;    }    case TV_VBI_CONTROL_STEP_PAGE:    {        int direction=*(int *) arg;        pthread_mutex_lock(&(priv->buffer_mutex));        priv->pagenum=steppage(priv->pagenum, direction,1);        priv->subpagenum=get_subpagenum_from_cache(priv,priv->pagenum);        priv->pagenumdec=0;        priv->page_changed=1;        pthread_mutex_unlock(&(priv->buffer_mutex));        return TVI_CONTROL_TRUE;    }    case TV_VBI_CONTROL_GET_PAGE:        *(int*)arg=((priv->pagenum+0x700)&0x7ff)+0x100;        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_SET_SUBPAGE:        pthread_mutex_lock(&(priv->buffer_mutex));        priv->pagenumdec=0;        priv->subpagenum=*(int*)arg;        if(priv->subpagenum<0)            priv->subpagenum=0x3f7f;        if(priv->subpagenum>=VBI_MAX_SUBPAGES)            priv->subpagenum=VBI_MAX_SUBPAGES-1;        priv->page_changed=1;        pthread_mutex_unlock(&(priv->buffer_mutex));        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_GET_SUBPAGE:        *(int*)arg=priv->subpagenum;        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_ADD_DEC:        vbi_add_dec(priv, *(char **) arg);        priv->page_changed=1;        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_DECODE_PAGE:        vbi_decode(priv,*(unsigned char**)arg);        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_GET_VBIPAGE:        if(!priv->on)            return TVI_CONTROL_FALSE;        prepare_visible_page(priv);        *(void **)arg=priv->display_page;        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_GET_NETWORKNAME:        *(void **)arg=priv->networkname;        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_MARK_UNCHANGED:        priv->page_changed=0;        priv->last_rendered=GetTimerMS();        return TVI_CONTROL_TRUE;    case TV_VBI_CONTROL_IS_CHANGED:        if(GetTimerMS()-priv->last_rendered> 250)  //forcing page update every 1/4 sec            priv->page_changed=3; //mark that header update is enough        *(int*)arg=priv->page_changed;        return TVI_CONTROL_TRUE;    }    return TVI_CONTROL_UNKNOWN;}

⌨️ 快捷键说明

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