/* dvbtext - a teletext decoder for DVB cards. (C) Dave Chapman 2001. The latest version can be found at http://www.linuxstb.org/dvbtext Thanks to: Ralph Metzler for his work on both the DVB driver and his old vbidecode package (some code and ideas in dvbtext are borrowed from vbidecode). Copyright notice: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #ifdef NEWSTRUCT #include #else #include #endif #include "tables.h" #define VERSION "0.1" #define VTXDIR "/run/ttxd/spool" //#define VTXDIR "/opt/TTx_Server/spool" //#define VTXDIR "/video/vtx" #define USAGE "\nUSAGE: dvbtext tpid1 tpid2 tpid3 .. tpid8\n\n" // There seems to be a limit of 8 teletext streams - OK for most (but // not all) transponders. #define MAX_CHANNELS 9 typedef struct mag_struct_ { int valid; int mag; unsigned char flags; unsigned char lang; int pnum,sub; unsigned char pagebuf[25*40]; } mag_struct; // FROM vbidecode // unham 2 bytes into 1, report 2 bit errors but ignore them unsigned char unham(unsigned char a,unsigned char b) { unsigned char c1,c2; c1=unhamtab[a]; c2=unhamtab[b]; // if ((c1|c2)&0x40) // fprintf(stderr,"bad ham!"); return (c2<<4)|(0x0f&c1); } void write_data(unsigned char* b, int n) { int i; for (i=0;ivalid=1; memset(mag->pagebuf,' ', 25*40); mag->pnum=unham(data[0],data[1]); // The lower two (hex) numbers of page if (mag->pnum==0xff) return; // These are filler lines. Can use to update clock // fprintf(stderr,"pagenum: %03x\n",c+mag->mag*0x100); mag->flags=unham(data[2],data[3])&0x80; mag->flags|=(c&0x40)|((c>>2)&0x20); c=unham(data[6],data[7]); mag->flags|=((c<<4)&0x10)|((c<<2)&0x08)|(c&0x04)|((c>>1)&0x02)|((c>>4)&0x01); mag->lang=((c>>5) & 0x07); mag->sub=(unham(data[4],data[5])<<8)|(unham(data[2],data[3])&0x3f7f); // mag->pnum = (mag->mag<<8)|((mag->sub&0x3f7f)<<16)|page; // fprintf(stderr,"page: %x, pnum: %x, sub: %x\n",page,mag->pnum,mag->sub); } if (mag->valid) { if (line <= 23) { memcpy(mag->pagebuf+40*line,data,40); } if (line==23) { sprintf(fname,"%s/%d/%03x_%02x.vtx",VTXDIR,pnr,mag->pnum+(mag->mag*0x100),mag->sub&0xff); // fprintf(stderr,"Writing to file %s\n",fname); if ((fd=fopen(fname,"w"))) { fwrite("VTXV4",1,5,fd); buf=0x01; fwrite(&buf,1,1,fd); buf=mag->mag; fwrite(&buf,1,1,fd); buf=mag->pnum; fwrite(&buf,1,1,fd); buf=0x00; fwrite(&buf,1,1,fd); /* subpage?? */ buf=0x00; fwrite(&buf,1,1,fd); buf=0x00; fwrite(&buf,1,1,fd); buf=0x00; fwrite(&buf,1,1,fd); fwrite(mag->pagebuf,1,24*40,fd); fclose(fd); } mag->valid=0; } } } #ifdef NEWSTRUCT void set_tt_filt(int fd,uint16_t tt_pid) { struct dmx_pes_filter_params pesFilterParams; pesFilterParams.pid = tt_pid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; pesFilterParams.pes_type = DMX_PES_OTHER; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { fprintf(stderr,"FILTER %i: ",tt_pid); perror("DMX SET PES FILTER"); } } #else void set_tt_filt(int fd,uint16_t tt_pid) { struct dmxPesFilterParams pesFilterParams; pesFilterParams.pid = tt_pid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; pesFilterParams.pesType = DMX_PES_OTHER; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { fprintf(stderr,"FILTER %i: ",tt_pid); perror("DMX SET PES FILTER"); } } #endif int main(int argc, char **argv) { int pid; int i,j,n,m; unsigned char buf[188]; /* data buffer */ unsigned char mpag,mag,pack; int fd_dvr; /* Test channels - Astra 19E, 11837h, SR 27500 - e.g. ARD */ int pids[MAX_CHANNELS]; int pnrs[MAX_CHANNELS]={ 1,2,3,4,5,6,7,8 }; /* Directory names */ mag_struct mags[MAX_CHANNELS][8]; int fd[MAX_CHANNELS]; int count; printf("dvbtext v%s - (C) Dave Chapman 2001\n",VERSION); printf("Latest version available from http://www.linuxstb.org/dvbtext\n"); if (argc==1) { printf(USAGE); return(-1); } else { count=0; for (i=1;i 8) { printf("\nSorry, you can only set up to 8 filters.\n\n"); return(-1); } else { printf("Decoding %d teletext stream%s into %s/*\n",count,(count==1 ? "" : "s"),VTXDIR); } } else { printf(USAGE); return(-1); } for (m=0;m