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

📄 dvbstream.c

📁 DVBstream is based on the ts-rtp package available at http://www.linuxtv.org. It broadcasts a (subs
💻 C
📖 第 1 页 / 共 2 页
字号:
/* dvbstream - RTP-ize a DVB transport stream.(C) Dave Chapman <dave@dchapman.com> 2001, 2002.The latest version can be found at http://www.linuxstb.org/dvbstreamCopyright notice:This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    */// Linux includes:#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <sys/ioctl.h>#include <sys/time.h>#include <sys/poll.h>#include <sys/stat.h>#include <resolv.h>#include <fcntl.h>#include <unistd.h>#include <signal.h>#include <values.h>#include <string.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>// DVB includes:#ifdef NEWSTRUCT#include <linux/dvb/dmx.h>#include <linux/dvb/frontend.h>#else#include <ost/dmx.h>#include <ost/sec.h>#include <ost/frontend.h>#endif#include "rtp.h"#include "mpegtools/transform.h"#include "mpegtools/remux.h"#include "tune.h"// The default telnet port.#define DEFAULT_PORT 12345#define USAGE "\nUSAGE: dvbstream tpid1 tpid2 tpid3 .. tpid8\n\n"#define PACKET_SIZE 188// How often (in seconds) to update the "now" variable#define ALARM_TIME 5/* Thanks to Giancarlo Baracchino for this fix */#define MTU 1500#define IP_HEADER_SIZE 20#define UDP_HEADER_SIZE 8#define RTP_HEADER_SIZE 12#define MAX_RTP_SIZE (MTU-IP_HEADER_SIZE-UDP_HEADER_SIZE-RTP_HEADER_SIZE)#define writes(f,x) write((f),(x),strlen(x))/* Signal handling code shamelessly copied from VDR by Klaus Schmidinger    - see http://www.cadsoft.de/people/kls/vdr/index.htm */#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"};#endifint card=0;long now;long real_start_time;int Interrupted=0;fe_spectral_inversion_t specInv=INVERSION_AUTO;int tone=-1;fe_modulation_t modulation=CONSTELLATION_DEFAULT;fe_transmit_mode_t TransmissionMode=TRANSMISSION_MODE_DEFAULT;fe_bandwidth_t bandWidth=BANDWIDTH_DEFAULT;fe_guard_interval_t guardInterval=GUARD_INTERVAL_DEFAULT;fe_code_rate_t HP_CodeRate=HP_CODERATE_DEFAULT;unsigned int diseqc=0;char pol=0;int open_fe(int* fd_frontend,int* fd_sec) {    if((*fd_frontend = open(frontenddev[card],O_RDWR)) < 0){        perror("FRONTEND DEVICE: ");        return -1;    }#ifdef NEWSTRUCT    fd_sec=0;#else    if (fd_sec!=0) {      if((*fd_sec = open(secdev[card],O_RDWR)) < 0){          perror("SEC DEVICE: ");          return -1;      }    }#endif    return 1;}static void SignalHandler(int signum) {  struct timeval tv;  if (signum == SIGALRM) {    gettimeofday(&tv,(struct timezone*) NULL);    now=tv.tv_sec-real_start_time;    //    fprintf(stderr,"now=%ld\n",now);    alarm(ALARM_TIME);  } else if (signum != SIGPIPE) {    Interrupted=signum;  }  signal(signum,SignalHandler);}long getmsec() {  struct timeval tv;  gettimeofday(&tv,(struct timezone*) NULL);  return(tv.tv_sec%1000000)*1000 + tv.tv_usec/1000;}// There seems to be a limit of 8 simultaneous filters in the driver#ifdef NEWSTRUCT  #define MAX_CHANNELS 16#else  #define MAX_CHANNELS 8#endifvoid set_ts_filt(int fd,uint16_t pid, dmx_pes_type_t pestype){  struct dmx_pes_filter_params pesFilterParams;  fprintf(stderr,"Setting filter for PID %d\n",pid);  pesFilterParams.pid     = pid;  pesFilterParams.input   = DMX_IN_FRONTEND;  pesFilterParams.output  = DMX_OUT_TS_TAP;#ifdef NEWSTRUCT  pesFilterParams.pes_type = pestype;#else  pesFilterParams.pesType = pestype;#endif  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 make_nonblock(int f) {  int oldflags;  if ((oldflags=fcntl(f,F_GETFL,0)) < 0) {    perror("F_GETFL");  }  oldflags|=O_NONBLOCK;  if (fcntl(f,F_SETFL,oldflags) < 0) {    perror("F_SETFL");  }}typedef enum {STREAM_ON,STREAM_OFF} state_t;  int socketIn, ns;  int pids[MAX_CHANNELS];  int pestypes[MAX_CHANNELS];  unsigned char hi_mappids[8192];  unsigned char lo_mappids[8192];  int fd_sec;  int fd_frontend;  int pid,pid2;  int connectionOpen;  int fromlen;  char hostname[64];  char in_ch;  struct hostent *hp;  struct sockaddr_in name, fsin;  int ReUseAddr=1;  int oldflags;  int npids = 0;  int fd[MAX_CHANNELS];  int to_stdout = 0; /* to stdout instead of rtp stream */  /* rtp */  struct rtpheader hdr;  struct sockaddr_in sOut;  int socketOut;  ipack pa, pv;#define IPACKS 2048#define TS_SIZE 188#define IN_SIZE TS_SIZEint process_telnet() {  char cmd[1024];  int cmd_i=0;  int i;  char* ch;  dmx_pes_type_t pestype;  unsigned long freq=0;  unsigned long srate=0;    /* Open a new telnet session if a client is trying to connect */    if (ns==-1) {      if ((ns = accept(socketIn, (struct sockaddr *)&fsin, &fromlen)) > 0) {        make_nonblock(ns);        cmd_i=0;              cmd[0]=0;        printf("Opened connection\n");        writes(ns,"220-DVBSTREAM - ");        writes(ns,hostname);        writes(ns,"\r\nDONE\r\n");        connectionOpen=1;      }    }    /* If a telnet session is open, receive and process any input */    if (connectionOpen) {      /* Read in at most a line of text - any ctrl character ends the line */      while (read(ns,&in_ch,1)>0) {          if (in_ch < 32) break;          /* Prevent buffer overflows */          if (cmd_i < 1024-1) {            cmd[cmd_i++]=in_ch;            cmd[cmd_i]=0;          }      }      if (in_ch > 0) {        if (cmd_i > 0) {          printf("CMD: \"%s\"\n",cmd);          if (strcasecmp(cmd,"QUIT")==0) {            writes(ns,"DONE\r\n");            close(ns);            ns=-1;            connectionOpen=0;             printf("Closed connection\n");          } else if (strcasecmp(cmd,"STOP")==0) {            writes(ns,"STOP\n");            for (i=0;i<npids;i++) {              if (ioctl(fd[i], DMX_STOP) < 0)  {                 perror("DMX_STOP");              }            }            for (i=0;i<8192;i++) {              hi_mappids[i]=(i >> 8);              lo_mappids[i]=(i&0xff);            }            writes(ns,"DONE\r\n");          } else if (strncasecmp(cmd,"ADD",3)==0) {            i=4;            if ((cmd[3]=='V') || (cmd[3]=='v')) pestype=DMX_PES_VIDEO;            else if ((cmd[3]=='A') || (cmd[3]=='a')) pestype=DMX_PES_AUDIO;            else if ((cmd[3]=='T') || (cmd[3]=='t')) pestype=DMX_PES_TELETEXT;            else { pestype=DMX_PES_OTHER; i=3; }            while (cmd[i]==' ') i++;            if ((ch=(char*)strstr(&cmd[i],":"))!=NULL) {              pid2=atoi(&ch[1]);              ch[0]=0;            } else {              pid2=-1;            }            pid=atoi(&cmd[i]);            if (pid) {              if (npids == MAX_CHANNELS) {                fprintf(stderr,"\nsorry, you can only set up to 8 filters.\n\n");                return(-1);              } else {                pestypes[npids]=pestype;                pestype=DMX_PES_OTHER;                pids[npids]=pid;                if (pid2!=-1) {                  hi_mappids[pid]=pid2>>8;                  lo_mappids[pid]=pid2&0xff;                  fprintf(stderr,"Mapping %d to %d\n",pid,pid2);                }                                if((fd[npids] = open(demuxdev[card],O_RDWR)) < 0){                  fprintf(stderr,"FD %i: ",i);                  perror("DEMUX DEVICE: ");                } else {                  set_ts_filt(fd[npids],pids[npids],pestypes[npids]);                  npids++;                }              }            }            writes(ns,"DONE\r\n");          } else if (strcasecmp(cmd,"START")==0) {            writes(ns,"START\n");            for (i=0;i<npids;i++) {              set_ts_filt(fd[i],pids[i],pestypes[i]);            }            writes(ns,"DONE\r\n");          } else if (strncasecmp(cmd,"TUNE",4)==0) {            for (i=0;i<8192;i++) {              hi_mappids[i]=(i >> 8);              lo_mappids[i]=(i&0xff);            }            for (i=0;i<npids;i++) {              if (ioctl(fd[i], DMX_STOP) < 0)  {                 perror("DMX_STOP");                  close(fd[i]);              }            }            npids=0;            i=4;            while (cmd[i]==' ') i++;            freq=atoi(&cmd[i])*1000UL;            while ((cmd[i]!=' ') && (cmd[i]!=0)) i++;            if (cmd[i]!=0) {              while (cmd[i]==' ') i++;              pol=cmd[i];              while ((cmd[i]!=' ') && (cmd[i]!=0)) i++;              if (cmd[i]!=0) {                while (cmd[i]==' ') i++;                srate=atoi(&cmd[i])*1000UL;                fprintf(stderr,"Tuning to %ld,%ld,%c\n",freq,srate,pol);                tune_it(fd_frontend,fd_sec,freq,srate,pol,tone,specInv,diseqc,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth);              }            }          }          cmd_i=0;          cmd[0]=0;          writes(ns,"DONE\r\n");        }      }    }    return(0);}/* The output routine for sending a PS */void my_write_out(uint8_t *buf, int count,void  *p){  /* to fix: change this buffer size and check for overflow */  static uint8_t out_buffer[1000000];  static int out_buffer_n=0;  int i;  if (to_stdout) {    /* This one is easy. */    write(STDOUT_FILENO, buf, count);  } else { /* We are streaming it. */    /* Copy data to write to the end of out_buffer */    memcpy(&out_buffer[out_buffer_n],buf,count);    out_buffer_n+=count;    /* Send as many full packets as possible */    i=0;    while ((i + MAX_RTP_SIZE) < out_buffer_n) {       hdr.timestamp = getmsec()*90;       sendrtp2(socketOut,&sOut,&hdr,&out_buffer[i],MAX_RTP_SIZE);       i+=MAX_RTP_SIZE;    }    /* Move whatever data is left to the start of the buffer */    memmove(&out_buffer[0],&out_buffer[i],out_buffer_n-i);    out_buffer_n-=i;  }}void my_ts_to_ps( uint8_t* buf, uint16_t pida, uint16_t pidv){  uint16_t pid;  ipack *p;  uint8_t off = 0;  pid = get_pid(buf+1);  if (!(buf[3]&0x10)) // no payload?    return;  if (pid == pidv){    p = &pv;  } else {    if (pid == pida){      p = &pa;    } else return;  }  if ( buf[1]&0x40) {    if (p->plength == MMAX_PLENGTH-6){      p->plength = p->found-6;      p->found = 0;      send_ipack(p);      reset_ipack(p);    }  }  if ( buf[3] & 0x20) {  // adaptation field?    off = buf[4] + 1;  }          instant_repack(buf+4+off, TS_SIZE-4-off, p);}typedef struct {  char *filename;  int fd;  int pids[MAX_CHANNELS];  int num;  long start_time; // in seconds  long end_time;   // in seconds} pids_map_t;pids_map_t *pids_map;int map_cnt;int main(int argc, char **argv){  //  state_t state=STREAM_OFF;  unsigned short int port=DEFAULT_PORT;  int fd_dvr;  int i,j;  unsigned char buf[MTU];  struct pollfd pfds[2];  // DVR device and Telnet connection  unsigned int secs = 0;  unsigned long freq=0;  unsigned long srate=0;  int count;  char* ch;  dmx_pes_type_t pestype;  int bytes_read;  int do_analyse=0;  unsigned char* free_bytes;  int output_type=RTP_TS;  int64_t counts[8192];  double f;  long start_time=-1;  long end_time=-1;  struct timeval tv;  /* Output: {uni,multi,broad}cast socket */  char ipOut[20];  int portOut;  int ttl;    pids_map = NULL;  map_cnt = 0;

⌨️ 快捷键说明

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