📄 dvbtune.c
字号:
/* dvbtune - a program for tuning DVB TV and Radio channels. Initial transponders for "-x" option: Astra 28E: Astra 19E: 12670v - srate 22000 Hotbird 13E: 10911v - srate 27500 ?? Doesn't work! Thor etc 1W: 11247v - srate 24500 (Most channels!) Copyright (C) Dave Chapman 2001-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Or, point your browser to http://www.gnu.org/copyleft/gpl.html Added Switch -n that adds a network interface and switch -m that monitors the reception quality. Changed the tuning code Added command line parameters for spectral inversion. Changed code to allow L-Band frequencies with -f switch Copyright (C) Hilmar Linder 2002 */// Linux includes:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <sys/ioctl.h>#include <sys/poll.h>#include <fcntl.h>#include <unistd.h>// DVB includes:#ifdef NEWSTRUCT#include <linux/dvb/osd.h>#include <linux/dvb/dmx.h>#include <linux/dvb/frontend.h>#include <linux/dvb/video.h>#include <linux/dvb/audio.h>#include <linux/dvb/net.h>#else#include <ost/osd.h>#include <ost/dmx.h>#include <ost/sec.h>#include <ost/frontend.h>#include <ost/video.h>#include <ost/audio.h>#include <ost/net.h>#endif#include "tune.h"#define SECA_CA_SYSTEM 0x0100#define VIACCESS_CA_SYSTEM 0x0500#define IRDETO_CA_SYSTEM 0x0600#define VIDEOGUARD_CA_SYSTEM 0x0900#define BETA_CA_SYSTEM 0x1700#define NAGRA_CA_SYSTEM 0x1800#define CONAX_CA_SYSTEM 0x0b00int fd_demuxv,fd_demuxa,fd_demuxtt,fd_demuxsi,fd_demuxrec,fd_demuxd;int pnr=-1;int apid=0;int vpid=0;int card=0;fe_spectral_inversion_t specInv = INVERSION_AUTO;int tone = -1;#ifdef NEWSTRUCTchar* frontenddev[4]={"/dev/dvb/adapter0/frontend0","/dev/dvb/adapter1/frontend0","/dev/dvb/adapter2/frontend0","/dev/dvb/adapter3/frontend0"};char* dvrdev[4]={"/dev/dvb/adapter0/dvr0","/dev/dvb/adapter1/dvr0","/dev/dvb/adapter2/dvr0","/dev/dvb/adapter3/dvr0"};char* demuxdev[4]={"/dev/dvb/adapter0/demux0","/dev/dvb/adapter1/demux0","/dev/dvb/adapter2/demux0","/dev/dvb/adapter3/demux0"};#elsechar* frontenddev[4]={"/dev/ost/frontend0","/dev/ost/frontend1","/dev/ost/frontend2","/dev/ost/frontend3"};char* dvrdev[4]={"/dev/ost/dvr0","/dev/ost/dvr1","/dev/ost/dvr2","/dev/ost/dvr3"};char* secdev[4]={"/dev/ost/sec0","/dev/ost/sec1","/dev/ost/sec2","/dev/ost/sec3"};char* demuxdev[4]={"/dev/ost/demux0","/dev/ost/demux1","/dev/ost/demux2","/dev/ost/demux3"};#endiftypedef struct _transponder_t { int id; int onid; unsigned int freq; int srate; int pos; int we_flag; char pol; int mod; int scanned; struct _transponder_t* next;} transponder_t;transponder_t* transponders=NULL;int num_trans=0;transponder_t transponder;typedef struct _pat_t { int service_id; int pmt_pid; int scanned; struct _pat_t* next;} pat_t;pat_t* pats=NULL;/* Get the first unscanned transponder (or return NULL) */transponder_t* get_unscanned() { transponder_t* t; t=transponders; while (t!=NULL) { if (t->scanned==0) { return(t); }; t=t->next; } return NULL;}char xmlify_result[10];char* xmlify (char c) { switch(c) { case '&': strcpy(xmlify_result,"&"); break; case '<': strcpy(xmlify_result,"<"); break; case '>': strcpy(xmlify_result,">"); break; case '\"': strcpy(xmlify_result,"""); break; case 0: xmlify_result[0]=0; break; default: xmlify_result[0]=c; xmlify_result[1]=0; break; } return(xmlify_result);}void add_transponder(transponder_t transponder) { transponder_t* t; int found; if (transponders==NULL) { transponders=(transponder_t*)malloc(sizeof(transponder)); transponders->freq=transponder.freq; transponders->srate=transponder.srate; transponders->pol=transponder.pol; transponders->pos=transponder.pos; transponders->we_flag=transponder.we_flag; transponders->mod=transponder.mod; transponders->scanned=0; transponders->next=NULL; } else { t=transponders; found=0; while ((!found) && (t!=NULL)) { /* Some transponders appear with slightly different frequencies - ignore a new transponder if it is within 3MHz of another */ if ((abs(t->freq-transponder.freq)<=3000) && (t->pol==transponder.pol)) { found=1; } else { t=t->next; } } if (!found) { t=(transponder_t*)malloc(sizeof(transponder)); t->freq=transponder.freq; t->srate=transponder.srate; t->pol=transponder.pol; t->pos=transponder.pos; t->we_flag=transponder.we_flag; t->mod=transponder.mod; t->scanned=0; t->next=transponders; transponders=t; } }}void free_pat_list() { pat_t* t=pats; while (pats!=NULL) { t=pats->next; free(pats); pats=t; }}int get_pmt_pid(int service_id) { pat_t* t=pats; int found=0; while ((!found) && (t!=NULL)) { if (t->service_id==service_id) { found=1; } else { t=t->next; } } if (found) { return(t->pmt_pid); } else { return(0); }}void add_pat(pat_t pat) { pat_t* t; int found; if (pats==NULL) { pats=(pat_t*)malloc(sizeof(pat)); pats->service_id=pat.service_id; pats->pmt_pid=pat.pmt_pid; pats->scanned=0; pats->next=NULL; } else { t=pats; found=0; while ((!found) && (t!=NULL)) { if ((t->service_id==pat.service_id)) { found=1; } else { t=t->next; } } if (!found) { t=(pat_t*)malloc(sizeof(pat)); t->service_id=pat.service_id; t->pmt_pid=pat.pmt_pid; t->scanned=0; t->next=pats; pats=t; } }}void set_recpid(int fd, ushort ttpid) { struct dmx_pes_filter_params pesFilterParamsREC; if (ttpid==0 || ttpid==0xffff) { ioctl(fd, DMX_STOP, 0); return; } pesFilterParamsREC.pid = ttpid; pesFilterParamsREC.input = DMX_IN_FRONTEND; pesFilterParamsREC.output = DMX_OUT_TAP; #ifdef NEWSTRUCT pesFilterParamsREC.pes_type = DMX_PES_OTHER; #else pesFilterParamsREC.pesType = DMX_PES_OTHER; #endif pesFilterParamsREC.flags = DMX_IMMEDIATE_START; if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParamsREC) < 0) perror("set_recpid");}void set_sipid(ushort ttpid) { struct dmx_pes_filter_params pesFilterParamsSI; if (ttpid==0 || ttpid==0xffff) { ioctl(fd_demuxsi, DMX_STOP, 0); return; } pesFilterParamsSI.pid = ttpid; pesFilterParamsSI.input = DMX_IN_FRONTEND; pesFilterParamsSI.output = DMX_OUT_TS_TAP; #ifdef NEWSTRUCT pesFilterParamsSI.pes_type = DMX_PES_OTHER; #else pesFilterParamsSI.pesType = DMX_PES_OTHER; #endif pesFilterParamsSI.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxsi, DMX_SET_PES_FILTER, &pesFilterParamsSI) < 0) perror("set_sipid");}void set_ttpid(ushort ttpid) { struct dmx_pes_filter_params pesFilterParamsTT; if (ttpid==0 || ttpid==0xffff) { ioctl(fd_demuxtt, DMX_STOP, 0); return; } pesFilterParamsTT.pid = ttpid; pesFilterParamsTT.input = DMX_IN_FRONTEND; pesFilterParamsTT.output = DMX_OUT_DECODER; #ifdef NEWSTRUCT pesFilterParamsTT.pes_type = DMX_PES_TELETEXT; #else pesFilterParamsTT.pesType = DMX_PES_TELETEXT; #endif pesFilterParamsTT.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxtt, DMX_SET_PES_FILTER, &pesFilterParamsTT) < 0) perror("set_ttpid");}void set_vpid(ushort vpid) { struct dmx_pes_filter_params pesFilterParamsV; if (vpid==0 || vpid==0xffff) { ioctl(fd_demuxv, DMX_STOP, 0); return; } pesFilterParamsV.pid = vpid; pesFilterParamsV.input = DMX_IN_FRONTEND; pesFilterParamsV.output = DMX_OUT_DECODER; #ifdef NEWSTRUCT pesFilterParamsV.pes_type = DMX_PES_VIDEO; #else pesFilterParamsV.pesType = DMX_PES_VIDEO; #endif pesFilterParamsV.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxv, DMX_SET_PES_FILTER, &pesFilterParamsV) < 0) perror("set_vpid");}void set_apid(ushort apid) { struct dmx_pes_filter_params pesFilterParamsA; if (apid==0 || apid==0xffff) { ioctl(fd_demuxa, DMX_STOP, apid); return; } pesFilterParamsA.pid = apid; pesFilterParamsA.input = DMX_IN_FRONTEND; pesFilterParamsA.output = DMX_OUT_DECODER; #ifdef NEWSTRUCT pesFilterParamsA.pes_type = DMX_PES_AUDIO; #else pesFilterParamsA.pesType = DMX_PES_AUDIO; #endif pesFilterParamsA.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxa, DMX_SET_PES_FILTER, &pesFilterParamsA) < 0) perror("set_apid");}void set_dpid(ushort dpid) { struct dmx_sct_filter_params sctFilterParams; if (dpid==0 || dpid==0xffff) { ioctl(fd_demuxd, DMX_STOP, dpid); return; } memset(&sctFilterParams.filter,0,sizeof(sctFilterParams.filter)); sctFilterParams.pid = dpid; //sctFilterParams.filter.filter[0] = 0x3e; //sctFilterParams.filter.mask[0] = 0xff; sctFilterParams.timeout = 0; sctFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxd, DMX_SET_FILTER, &sctFilterParams) < 0) perror("set_dpid"); }void set_ts_filter(int fd,uint16_t pid){ struct dmx_pes_filter_params pesFilterParams; pesFilterParams.pid = pid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP;#ifdef NEWSTRUCT pesFilterParams.pes_type = DMX_PES_OTHER;#else pesFilterParams.pesType = DMX_PES_OTHER;#endif// A HACK TO DECODE STREAMS ON DVB-S CARD WHILST STREAMING// if (pid==255) pesFilterParams.pesType = DMX_PES_VIDEO;// if (pid==256) pesFilterParams.pesType = DMX_PES_AUDIO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { fprintf(stderr,"FILTER %i: ",pid); perror("DMX SET PES FILTER"); }}void parse_descriptors(int info_len,unsigned char *buf) { int i=0; int descriptor_tag,descriptor_length,j,k,pid,id; int service_type; char tmp[128]; unsigned int freq, pol, sr; while (i < info_len) { descriptor_tag=buf[i++]; descriptor_length=buf[i++]; // printf("Found descriptor: 0x%02x - length %02d\n",descriptor_tag,descriptor_length); while (descriptor_length > 0) { switch(descriptor_tag) { case 0x03: // audio_stream_descriptor printf("<audio_info tag=\"0x03\" info=\"%02x\" />\n",buf[i]); i+=descriptor_length; descriptor_length=0; break; case 0x06: // data_stream_alignmentdescriptor printf("<data_stream_alignment tag=\"0x06\" data=\"%02x\" />\n",buf[i]); i+=descriptor_length; descriptor_length=0; break; case 0x0a: // iso_639_language_descriptor for (j=0;j<((descriptor_length)/4);j++) { printf("<iso_639 language=\""); if (buf[i]!=0) printf("%c",buf[i]); if (buf[i+1]!=0) printf("%c",buf[i+1]); if (buf[i+2]!=0) printf("%c",buf[i+2]); printf("\" type=\"%d\" />\n",buf[i+3]); i+=4; descriptor_length-=4; } break; case 0x0b: // system_clock_descriptor printf("<system_clock tag=\"0x0b\" data=\"%02x%02x\" />\n",buf[i],buf[i+1]); i+=descriptor_length; descriptor_length=0; break; case 0x09: // ca_descriptor k=((buf[i]<<8)|buf[i+1]); switch(k&0xff00) { case SECA_CA_SYSTEM: for (j=2; j<descriptor_length; j+=15) { pid = ((buf[i+j] & 0x1f) << 8) | buf[i+j+1]; id = (buf[i+j+2] << 8) | buf[i+j+3]; printf("<ca_system_descriptor type=\"seca\" system_id=\"0x%04x\" ecm_pid=\"%d\" ecm_id=\"%06x\">\n",k,pid,id); } break; case VIACCESS_CA_SYSTEM: j = 4; while (j < descriptor_length) { if (buf[i+j]==0x14) { pid = ((buf[i+2] & 0x1f) << 8) | buf[i+3]; id = (buf[i+j+2] << 16) | (buf[i+j+3] << 8) | (buf[i+j+4] & 0xf0); printf("<ca_system_descriptor type=\"viaccess\" system_id=\"0x%04x\" ecm_pid=\"%d\" ecm_id=\"%06x\">\n",k,pid,id);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -