📄 dvbstream.c
字号:
fprintf(stderr,"dvbstream v0.5 - (C) Dave Chapman 2001-2004\n"); fprintf(stderr,"Released under the GPL.\n"); fprintf(stderr,"Latest version available from http://www.linuxstb.org/\n"); /* Initialise PID map */ for (i=0;i<8192;i++) { hi_mappids[i]=(i >> 8); lo_mappids[i]=(i&0xff); counts[i]=0; } /* Set default IP and port */ strcpy(ipOut,"224.0.1.2"); portOut = 5004; if (argc==1) { fprintf(stderr,"Usage: dvbtune [OPTIONS] pid1 pid2 ... pid8\n\n"); fprintf(stderr,"-i IP multicast address\n"); fprintf(stderr,"-r IP multicast port\n"); fprintf(stderr,"-o Stream to stdout instead of network\n"); fprintf(stderr,"-o:file.ts Stream to named file instead of network\n"); fprintf(stderr,"-n secs Stop after secs seconds\n"); fprintf(stderr,"-ps Convert stream to Program Stream format (needs exactly 2 pids)\n"); fprintf(stderr,"-v vpid Decode video PID (full cards only)\n"); fprintf(stderr,"-a apid Decode audio PID (full cards only)\n"); fprintf(stderr,"-t ttpid Decode teletext PID (full cards only)\n"); fprintf(stderr,"\nStandard tuning options:\n\n"); fprintf(stderr,"-f freq absolute Frequency (DVB-S in Hz or DVB-T in Hz)\n"); fprintf(stderr," or L-band Frequency (DVB-S in Hz or DVB-T in Hz)\n"); fprintf(stderr,"-p [H,V] Polarity (DVB-S only)\n"); fprintf(stderr,"-s N Symbol rate (DVB-S or DVB-C)\n"); fprintf(stderr,"\nAdvanced tuning options:\n\n"); fprintf(stderr,"-c [0-3] Use DVB card #[0-3]\n"); fprintf(stderr,"-qam X DVB-T modulation - 16%s, 32%s, 64%s, 128%s or 256%s\n",(CONSTELLATION_DEFAULT==QAM_16 ? " (default)" : ""),(CONSTELLATION_DEFAULT==QAM_32 ? " (default)" : ""),(CONSTELLATION_DEFAULT==QAM_64 ? " (default)" : ""),(CONSTELLATION_DEFAULT==QAM_128 ? " (default)" : ""),(CONSTELLATION_DEFAULT==QAM_256 ? " (default)" : "")); fprintf(stderr,"-gi N DVB-T guard interval 1_N (N=32%s, 16%s, 8%s or 4%s)\n",(GUARD_INTERVAL_DEFAULT==GUARD_INTERVAL_1_32 ? " (default)" : ""),(GUARD_INTERVAL_DEFAULT==GUARD_INTERVAL_1_16 ? " (default)" : ""),(GUARD_INTERVAL_DEFAULT==GUARD_INTERVAL_1_8 ? " (default)" : ""),(GUARD_INTERVAL_DEFAULT==GUARD_INTERVAL_1_4 ? " (default)" : "")); fprintf(stderr,"-cr N DVB-T code rate. N=AUTO%s, 1_2%s, 2_3%s, 3_4%s, 5_6%s, 7_8%s\n",(HP_CODERATE_DEFAULT==FEC_AUTO ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_1_2 ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_2_3 ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_3_4 ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_5_6 ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_7_8 ? " (default)" : "")); fprintf(stderr,"-bw N DVB-T bandwidth (Mhz) - N=6%s, 7%s or 8%s\n",(BANDWIDTH_DEFAULT==BANDWIDTH_6_MHZ ? " (default)" : ""),(BANDWIDTH_DEFAULT==BANDWIDTH_7_MHZ ? " (default)" : ""),(BANDWIDTH_DEFAULT==BANDWIDTH_8_MHZ ? " (default)" : "")); fprintf(stderr,"-tm N DVB-T transmission mode - N=2%s or 8%s\n",(TRANSMISSION_MODE_DEFAULT==TRANSMISSION_MODE_2K ? " (default)" : ""),(TRANSMISSION_MODE_DEFAULT==TRANSMISSION_MODE_8K ? " (default)" : "")); fprintf(stderr,"\n-analyse Perform a simple analysis of the bitrates of the PIDs in the transport stream\n"); fprintf(stderr,"\n"); fprintf(stderr,"NOTE: Use pid1=8192 to broadcast whole TS stream from a budget card\n"); return(-1); } else { npids=0; pestype=DMX_PES_OTHER; // Default PES type for (i=1;i<argc;i++) { if (strcmp(argv[i],"-ps")==0) { output_type=RTP_PS; } else if (strcmp(argv[i],"-analyse")==0) { do_analyse=1; output_type=RTP_NONE; if (secs==0) { secs=10; } } else if (strcmp(argv[i],"-i")==0) { i++; strcpy(ipOut,argv[i]); } else if (strcmp(argv[i],"-r")==0) { i++; portOut=atoi(argv[i]); } else if (strcmp(argv[i],"-f")==0) { i++; freq=atoi(argv[i])*1000UL; } else if (strcmp(argv[i],"-p")==0) { i++; if (argv[i][1]==0) { if (tolower(argv[i][0])=='v') { pol='V'; } else if (tolower(argv[i][0])=='h') { pol='H'; } } } else if (strcmp(argv[i],"-s")==0) { i++; srate=atoi(argv[i])*1000UL; } else if (strcmp(argv[i],"-D")==0) { i++; diseqc=atoi(argv[i]); if(diseqc < 0 || diseqc > 4) diseqc = 0; } else if (strcmp(argv[i],"-o")==0) { to_stdout = 1; } else if (strcmp(argv[i],"-n")==0) { i++; secs=atoi(argv[i]); } else if (strcmp(argv[i],"-c")==0) { i++; card=atoi(argv[i]); if ((card < 0) || (card > 3)) { fprintf(stderr,"ERROR: card parameter must be between 0 and 4\n"); } } else if (strcmp(argv[i],"-v")==0) { pestype=DMX_PES_VIDEO; } else if (strcmp(argv[i],"-a")==0) { pestype=DMX_PES_AUDIO; } else if (strcmp(argv[i],"-t")==0) { pestype=DMX_PES_TELETEXT; } else if (strcmp(argv[i],"-qam")==0) { i++; switch(atoi(argv[i])) { case 16: modulation=QAM_16; break; case 32: modulation=QAM_32; break; case 64: modulation=QAM_64; break; case 128: modulation=QAM_128; break; case 256: modulation=QAM_256; break; default: fprintf(stderr,"Invalid QAM rate: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-gi")==0) { i++; switch(atoi(argv[i])) { case 32: guardInterval=GUARD_INTERVAL_1_32; break; case 16: guardInterval=GUARD_INTERVAL_1_16; break; case 8: guardInterval=GUARD_INTERVAL_1_8; break; case 4: guardInterval=GUARD_INTERVAL_1_4; break; default: fprintf(stderr,"Invalid Guard Interval: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-tm")==0) { i++; switch(atoi(argv[i])) { case 8: TransmissionMode=TRANSMISSION_MODE_8K; break; case 2: TransmissionMode=TRANSMISSION_MODE_2K; break; default: fprintf(stderr,"Invalid Transmission Mode: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-bw")==0) { i++; switch(atoi(argv[i])) { case 8: bandWidth=BANDWIDTH_8_MHZ; break; case 7: bandWidth=BANDWIDTH_7_MHZ; break; case 6: bandWidth=BANDWIDTH_6_MHZ; break; default: fprintf(stderr,"Invalid DVB-T bandwidth: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-cr")==0) { i++; if (!strcmp(argv[i],"AUTO")) { HP_CodeRate=FEC_AUTO; } else if (!strcmp(argv[i],"1_2")) { HP_CodeRate=FEC_1_2; } else if (!strcmp(argv[i],"2_3")) { HP_CodeRate=FEC_2_3; } else if (!strcmp(argv[i],"3_4")) { HP_CodeRate=FEC_3_4; } else if (!strcmp(argv[i],"5_6")) { HP_CodeRate=FEC_5_6; } else if (!strcmp(argv[i],"7_8")) { HP_CodeRate=FEC_7_8; } else { fprintf(stderr,"Invalid Code Rate: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-from")==0) { i++; if (map_cnt) { pids_map[map_cnt-1].start_time=atoi(argv[i]); } else { start_time=atoi(argv[i]); } } else if (strcmp(argv[i],"-to")==0) { i++; if (map_cnt) { pids_map[map_cnt-1].end_time=atoi(argv[i]); } else { end_time=atoi(argv[i]); } } else if (strstr(argv[i], "-o:")==argv[i]) { if (strlen(argv[i]) > 3) { int pid_cnt = 0, pid, j; map_cnt++; pids_map = (pids_map_t*) realloc(pids_map, sizeof(pids_map_t) * map_cnt); pids_map[map_cnt-1].start_time=start_time; pids_map[map_cnt-1].end_time=end_time; for(j=0; j < MAX_CHANNELS; j++) pids_map[map_cnt-1].pids[j] = -1; pids_map[map_cnt-1].filename = (char *) malloc(strlen(argv[i]) - 2); strcpy(pids_map[map_cnt-1].filename, &argv[i][3]); i++; while(i < argc) { int found; if (sscanf(argv[i], "%d", &pid) == 0) { i--; break; } // block for the map found = 0; for (j=0;j<MAX_CHANNELS;j++) { if(pids_map[map_cnt-1].pids[j] == pid) found = 1; } if (found == 0) { pids_map[map_cnt-1].pids[pid_cnt] = pid; pid_cnt++; } // block for the list of pids to demux found = 0; for (j=0;j<npids;j++) { if(pids[j] == pid) found = 1; } if (found==0) { pestypes[npids] = DMX_PES_OTHER; pids[npids++] = pid; } i++; } if (pid_cnt > 0) { FILE *f; f = fopen(pids_map[map_cnt-1].filename, "w+b"); if (f != NULL) { pids_map[map_cnt-1].fd = fileno(f); make_nonblock(pids_map[map_cnt-1].fd); fprintf(stderr, "Open file %s\n", pids_map[map_cnt-1].filename); } else { pids_map[map_cnt-1].fd = -1; fprintf(stderr, "Couldn't open file %s, errno:%d\n", pids_map[map_cnt-1].filename, errno); } } output_type = MAP_TS; } } else { if ((ch=(char*)strstr(argv[i],":"))!=NULL) { pid2=atoi(&ch[1]); ch[0]=0; } else { pid2=-1; } pid=atoi(argv[i]); if (pid) { if (npids == MAX_CHANNELS) { fprintf(stderr,"\nSorry, you can only set up to %d filters.\n\n",MAX_CHANNELS); 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 ((output_type==RTP_PS) && (npids!=2)) { fprintf(stderr,"ERROR: PS requires exactly two PIDS - video and audio.\n"); exit; } if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN); if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN); if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN); if (signal(SIGALRM, SignalHandler) == SIG_IGN) signal(SIGALRM, SIG_IGN); alarm(ALARM_TIME); if ( (freq>100000000)) { if (open_fe(&fd_frontend,0)) { i=tune_it(fd_frontend,0,freq,srate,0,tone,specInv,diseqc,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth); } } else if ((freq!=0) && (pol!=0) && (srate!=0)) { if (open_fe(&fd_frontend,&fd_sec)) { i=tune_it(fd_frontend,fd_sec,freq,srate,pol,tone,specInv,diseqc,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth); } } if (i<0) { exit(i); } for (i=0;i<map_cnt;i++) { fprintf(stderr,"MAP %d, file %s: From %ld secs, To %ld secs, %d PIDs - ",i,pids_map[i].filename,pids_map[i].start_time,pids_map[i].end_time,pids_map[i].num); for (j=0;j<MAX_CHANNELS;j++) { if (pids_map[i].pids[j]!=-1) fprintf(stderr," %d",pids_map[i].pids[j]); } fprintf(stderr,"\n"); } for (i=0;i<npids;i++) { if((fd[i] = open(demuxdev[card],O_RDWR)) < 0){ fprintf(stderr,"FD %i: ",i); perror("DEMUX DEVICE: "); return -1; } } if((fd_dvr = open(dvrdev[card],O_RDONLY|O_NONBLOCK)) < 0){ perror("DVR DEVICE: "); return -1; } /* Now we set the filters */ for (i=0;i<npids;i++) set_ts_filt(fd[i],pids[i],pestypes[i]); gettimeofday(&tv,(struct timezone*) NULL); real_start_time=tv.tv_sec; now=0; if (do_analyse) { fprintf(stderr,"Analysing PIDS\n"); } else { if (to_stdout) { fprintf(stderr,"Output to stdout\n"); } else { ttl = 2; fprintf(stderr,"Using %s:%d:%d\n",ipOut,portOut,ttl); /* Init RTP */ socketOut = makesocket(ipOut,portOut,ttl,&sOut); #warning WHAT SHOULD THE PAYLOAD TYPE BE FOR "MPEG-2 PS" ? initrtp(&hdr,(output_type==RTP_TS ? 33 : 34)); fprintf(stderr,"version=%X\n",hdr.b.v); } fprintf(stderr,"Streaming %d stream%s\n",npids,(npids==1 ? "" : "s")); } if (output_type==RTP_PS) { init_ipack(&pa, IPACKS,my_write_out, 1); init_ipack(&pv, IPACKS,my_write_out, 1); } /* Read packets */ free_bytes = buf; /* Setup socket to accept input from a client */ gethostname(hostname, sizeof(hostname)); if ((hp = gethostbyname(hostname)) == NULL) { fprintf(stderr, "%s: host unknown.\n", hostname); exit(1); } if ((socketIn = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("server: socket"); exit(1); } setsockopt(socketIn,SOL_SOCKET,SO_REUSEADDR,&ReUseAddr,sizeof(ReUseAddr)); name.sin_family = AF_INET; name.sin_port = htons(port); name.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(socketIn,(struct sockaddr* )&name,sizeof(name)) < 0) { perror("server: bind"); exit(1); } make_nonblock(socketIn); if (listen(socketIn, 1) < 0) { perror("server: listen"); exit(1); } connectionOpen=0; ns=-1; pfds[0].fd=fd_dvr; pfds[0].events=POLLIN|POLLPRI; pfds[1].events=POLLIN|POLLPRI; /* Set up timer */ // if (secs > 0) alarm(secs); while ( !Interrupted) { /* Poll the open file descriptors */ if (ns==-1) { poll(pfds,1,500); } else { pfds[1].fd=ns; // This can change poll(pfds,2,500); } process_telnet(); // See if there is an incoming telnet connection if (output_type==RTP_TS) { /* Attempt to read 188 bytes from /dev/ost/dvr */ if ((bytes_read = read(fd_dvr,free_bytes,PACKET_SIZE)) > 0) { if (bytes_read!=PACKET_SIZE) { fprintf(stderr,"No bytes left to read - aborting\n"); break; } pid=((free_bytes[1]&0x1f) << 8) | (free_bytes[2]); free_bytes[1]=(free_bytes[1]&0xe0)|hi_mappids[pid]; free_bytes[2]=lo_mappids[pid]; free_bytes+=bytes_read; // If there isn't enough room for 1 more packet, then send it. if ((free_bytes+PACKET_SIZE-buf)>MAX_RTP_SIZE) { hdr.timestamp = getmsec()*90; if (to_stdout) { write(1, buf, free_bytes-buf); } else { sendrtp2(socketOut,&sOut,&hdr,buf,free_bytes-buf); } free_bytes = buf; } count++; } } else if (output_type==RTP_PS) { if (read(fd_dvr,buf,TS_SIZE) > 0) { my_ts_to_ps((uint8_t*)buf, pids[0], pids[1]); } } else if(output_type==MAP_TS) { if(read(fd_dvr, buf, TS_SIZE) > 0) { if(buf[0] == 0x47) { int pid, i, j; pid = ((buf[1] & 0x1f) << 8) | buf[2]; if (pids_map != NULL) { for (i = 0; i < map_cnt; i++) { if ( ((pids_map[i].start_time==-1) || (pids_map[i].start_time >= now)) && ((pids_map[i].end_time==-1) || (pids_map[i].end_time <= now))) { for (j = 0; j < MAX_CHANNELS; j++) { if (pids_map[i].pids[j] == pid) { errno = 0; write(pids_map[i].fd, buf, TS_SIZE); } } } } } } else { fprintf(stderr, "NON 0X47\n"); } } } else { if (do_analyse) { if (read(fd_dvr,buf,TS_SIZE) > 0) { pid=((buf[1]&0x1f) << 8) | (buf[2]); counts[pid]++; } } } } if (Interrupted) { fprintf(stderr,"Caught signal %d - closing cleanly.\n",Interrupted); } if (ns!=-1) close(ns); close(socketIn); if (!to_stdout) close(socketOut); for (i=0;i<npids;i++) close(fd[i]); close(fd_dvr); close(fd_frontend); if (fd_sec) close(fd_sec); if (do_analyse) { for (i=0;i<8192;i++) { if (counts[i]) { f=(counts[i]*184.0*8.0)/(secs*1024.0*1024.0); if (f >= 1.0) { fprintf(stdout,"%d,%.3f Mbit/s\n",i,f); } else { fprintf(stdout,"%d,%.0f kbit/s\n",i,f*1024); } } } } return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -