├── TODO ├── extra ├── kernel-patches │ ├── README │ ├── 03-cx88.patch │ ├── 01-cx23885.patch │ └── 02-saa7146.patch └── dvbiscovery │ ├── README │ ├── dvbiscovery_dvb-s.conf │ ├── dvbiscovery_dvb-c.conf │ ├── dvbiscovery_atsc.conf │ ├── dvbiscovery.sh │ └── dvbiscovery_dvb-t.conf ├── COPYING.WTFPL ├── AUTHORS ├── INSTALL ├── mrtg-cnt.h ├── asi-deltacast.h ├── config.h ├── Makefile ├── comm.h ├── NEWS ├── dvblast_mmi.sh ├── mrtg-cnt.c ├── en50221.h ├── dvblast.1 ├── asi-deltacast.c ├── asi.c ├── comm.c ├── asi.h ├── README ├── dvblast.h ├── udp.c ├── COPYING ├── util.c └── output.c /TODO: -------------------------------------------------------------------------------- 1 | - Win32 support 2 | - Improve build system (autostuff) 3 | -------------------------------------------------------------------------------- /extra/kernel-patches/README: -------------------------------------------------------------------------------- 1 | About DVBlast kernel patches 2 | ============================ 3 | 4 | These kernel patches are designed to dramatically improve the latency 5 | between the DVB card and DVBlast's output, especially on low symbol rate 6 | transponders, at the expense of a slightly higher CPU consumption. 7 | 8 | Basically they decrease the size of the transmission buffers from the card 9 | to 4 kB, so that TS packets are handled more frequently. 10 | -------------------------------------------------------------------------------- /extra/kernel-patches/03-cx88.patch: -------------------------------------------------------------------------------- 1 | --- linux/drivers/media/video/cx88/cx88-dvb.c.orig 2010-02-22 14:58:43.000000000 +0100 2 | +++ linux/drivers/media/video/cx88/cx88-dvb.c 2010-07-09 11:15:12.000000000 +0200 3 | @@ -80,7 +80,7 @@ 4 | struct cx8802_dev *dev = q->priv_data; 5 | 6 | dev->ts_packet_size = 188 * 4; 7 | - dev->ts_packet_count = 32; 8 | + dev->ts_packet_count = 5; 9 | 10 | *size = dev->ts_packet_size * dev->ts_packet_count; 11 | *count = 32; 12 | -------------------------------------------------------------------------------- /extra/kernel-patches/01-cx23885.patch: -------------------------------------------------------------------------------- 1 | --- linux/drivers/media/video/cx23885/cx23885-dvb.c.orig 2010-06-29 15:32:09.000000000 +0200 2 | +++ linux/drivers/media/video/cx23885/cx23885-dvb.c 2010-06-29 15:32:16.000000000 +0200 3 | @@ -83,7 +83,7 @@ 4 | struct cx23885_tsport *port = q->priv_data; 5 | 6 | port->ts_packet_size = 188 * 4; 7 | - port->ts_packet_count = 32; 8 | + port->ts_packet_count = 5; 9 | 10 | *size = port->ts_packet_size * port->ts_packet_count; 11 | *count = 32; 12 | -------------------------------------------------------------------------------- /COPYING.WTFPL: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /extra/kernel-patches/02-saa7146.patch: -------------------------------------------------------------------------------- 1 | --- linux/drivers/media/dvb/ttpci/budget-core.c.orig 2010-06-09 08:54:16.000000000 +0200 2 | +++ linux/drivers/media/dvb/ttpci/budget-core.c 2010-06-09 08:28:23.000000000 +0200 3 | @@ -145,7 +145,7 @@ 4 | saa7146_write(dev, BASE_EVEN3, 0); 5 | } 6 | saa7146_write(dev, PROT_ADDR3, budget->buffer_size); 7 | - saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); 8 | + saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x50); 9 | 10 | saa7146_write(dev, PITCH3, budget->buffer_width); 11 | saa7146_write(dev, NUM_LINE_BYTE3, 12 | -------------------------------------------------------------------------------- /extra/dvbiscovery/README: -------------------------------------------------------------------------------- 1 | About DVBiscovery 2 | ================= 3 | 4 | DVBiscovery is a shell script that tries to tune a number of frequencies 5 | (from a config file), and stops after it has found a match. It then dumps 6 | the output of DVBlast to the standard output, so that an external process 7 | can parse it and find relevant information there. Typically, you would 8 | want to get the network ID from the NIT, which unically identifies the 9 | network you are on. 10 | 11 | DVBiscovery is therefore a sort of scanning program, but doesn't aim at 12 | exhaustivity (there are already programs doing that). It tries to guess 13 | where you are without any external information. 14 | -------------------------------------------------------------------------------- /extra/dvbiscovery/dvbiscovery_dvb-s.conf: -------------------------------------------------------------------------------- 1 | # freq pol sr fec 2 | # Astra 19.2E 3 | S 12551500 V 22000000 5/6 4 | # Eurobird 9E 5 | S 11843000 V 27500000 AUTO 6 | # Hotbird 13E 7 | S 11727000 V 27500000 AUTO 8 | # Astra 23.5E 9 | S 11914000 H 27500000 AUTO 10 | # Eurobird 28.5E 11 | S 11623000 H 27500000 2/3 12 | # Eutelsat 16.0E & Telecom2 8.0W & Amos 4.0W 13 | S 10972000 V 27500000 AUTO 14 | # Sirius 5.0E & Nilesat 15 | S 11727000 H 27500000 AUTO 16 | # Turksat 42.0E 17 | S 10970000 V 30000000 5/6 18 | # Atlantic Bird 1 12.5W 19 | S 11408000 V 27500000 3/4 20 | # Atlantic Bird 3 5.0W 21 | S 11591000 V 20000000 2/3 22 | # Hispasat 30.0W 23 | S 12015000 V 27500000 3/4 24 | # Telstar 12 15.0W 25 | S 11060000 H 19279000 3/4 26 | # Thor 1.0W 27 | S 11216000 V 24500000 7/8 28 | # Express AM1 40.0E 29 | S 10967000 V 20000000 AUTO 30 | # Hellas Sat 39.0E 31 | S 12565000 V 30000000 AUTO 32 | # Eutelsat W3A 7.0E 33 | S 11283000 V 27500000 AUTO 34 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Contributors to DVBlast 2 | # 3 | # The format of this file was inspired by the Linux kernel CREDITS file. 4 | # Authors are listed alphabetically. 5 | # 6 | # The fields are: name (N), email (E), web-address (W), CVS account login (C), 7 | # PGP key ID and fingerprint (P), description (D), and snail-mail address (S). 8 | 9 | N: Georgi Chorbadzhiyski 10 | E: gf AT unixsol.org 11 | D: numerous bug fixes and enhancements 12 | 13 | N: Benjamin Cohen 14 | E: bencoh AT notk DOT org 15 | D: raw sockets 16 | 17 | N: Marian Ďurkovič 18 | E: md AT bts DOT sk 19 | C: md 20 | D: numerous bug fixes 21 | 22 | N: Andy Gatward 23 | E: a DOT j DOT gatward AT reading DOT ac DOT uk 24 | C: gatty 25 | D: EIT pass-through, IPv6 support, various bug fixes 26 | 27 | N: Peter Partin 28 | E: peter DOT martin AT tripleplay DASH servies DOT com 29 | D: ATSC, MRTG, PID remap 30 | 31 | N: Christophe Massiot 32 | E: massiot AT via DOT ecp DOT fr 33 | C: massiot 34 | D: Most of the code 35 | 36 | N: Jean-Paul Saman 37 | E: jpsaman AT videolan DOT org 38 | C: jpsaman 39 | D: DVB-S2 bug fixes, syslog support 40 | 41 | N: Simon Lockhart 42 | E: simon AT slimey DOT org 43 | D: Deltacast ASI card support 44 | -------------------------------------------------------------------------------- /extra/dvbiscovery/dvbiscovery_dvb-c.conf: -------------------------------------------------------------------------------- 1 | # Gathered from diverse sources 2 | C 113000000 6900000 NONE AUTO 3 | C 121000000 6900000 NONE AUTO 4 | C 123000000 6875000 NONE AUTO 5 | C 146000000 6900000 NONE AUTO 6 | C 154000000 6875000 NONE AUTO 7 | C 154000000 6900000 NONE AUTO 8 | C 163000000 6875000 NONE AUTO 9 | C 218000000 6900000 NONE AUTO 10 | C 241000000 6900000 NONE AUTO 11 | C 283000000 5900000 NONE AUTO 12 | C 289500000 6875000 NONE AUTO 13 | C 306000000 6900000 NONE AUTO 14 | C 313000000 6875000 NONE AUTO 15 | C 314000000 6900000 NONE AUTO 16 | C 330000000 6875000 NONE AUTO 17 | C 346000000 6875000 NONE AUTO 18 | C 354000000 6900000 NONE AUTO 19 | C 354000000 6950000 NONE AUTO 20 | C 372000000 6875000 NONE AUTO 21 | C 377750000 6900000 NONE AUTO 22 | C 386000000 6875000 NONE AUTO 23 | C 386000000 6900000 NONE AUTO 24 | C 394000000 6900000 NONE AUTO 25 | C 410000000 6900000 NONE AUTO 26 | C 418000000 6900000 NONE AUTO 27 | C 434000000 6900000 NONE AUTO 28 | C 442000000 6900000 NONE AUTO 29 | C 450000000 6875000 NONE AUTO 30 | C 490000000 6875000 NONE AUTO 31 | C 514000000 6900000 NONE AUTO 32 | C 530000000 6900000 NONE AUTO 33 | C 634000000 6900000 NONE AUTO 34 | C 714000000 6875000 NONE AUTO 35 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | 2 | Getting DVBlast 3 | =============== 4 | 5 | Offically released DVBlast versions can be downloaded at: 6 | ftp://ftp.videolan.org/pub/videolan/dvblast/ 7 | 8 | DVBlast is developed using git. To get the latest version clone 9 | the repository at: git://git.videolan.org/dvblast.git 10 | 11 | To see the latest developments visit the following url: 12 | http://git.videolan.org/?p=dvblast.git 13 | 14 | Installing DVBlast 15 | ================== 16 | 17 | Compile the program with `make` and install with `make install`. Your 18 | kernel must support DVB S2API which was merged in Linux 2.6.28 and released 19 | on 24 Dec 2008. 20 | 21 | DVBlast 3.X requires biTStream as a build dependancy, and libev as a runtime 22 | dependancy. 23 | 24 | To install biTStream, clone git repository and run `make install`. 25 | 26 | git clone git://git.videolan.org/bitstream.git 27 | cd bitstream 28 | make install 29 | 30 | To install libev, download it from the home page: 31 | 32 | http://libev.schmorp.de 33 | 34 | If you wish to support Deltacast ASI cards, you will first need to install 35 | the Deltacast StreamMaster drivers and SDK, which are downloadable from the 36 | Deltacast website (login required). 37 | -------------------------------------------------------------------------------- /mrtg-cnt.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * mrtg-cnt.h 3 | ***************************************************************************** 4 | * Copyright Tripleplay service 2004,2005,2011 5 | * 6 | * Author: Andy Lindsay 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 21 | *****************************************************************************/ 22 | 23 | /* vim: set shiftwidth=4 tabstop=4 expandtab autoindent : */ 24 | 25 | #ifndef MRTG_CNT_H 26 | #define MRTG_CNT_H 27 | 28 | int mrtgInit(char *mrtg_file); 29 | void mrtgClose(); 30 | void mrtgAnalyse(block_t * p_ts); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /extra/dvbiscovery/dvbiscovery_atsc.conf: -------------------------------------------------------------------------------- 1 | # US ATSC center frequencies 2 | A 57028615 8VSB 3 | A 63028615 8VSB 4 | A 69028615 8VSB 5 | A 79028615 8VSB 6 | A 85028615 8VSB 7 | A 177028615 8VSB 8 | A 183028615 8VSB 9 | A 189028615 8VSB 10 | A 195028615 8VSB 11 | A 201028615 8VSB 12 | A 207028615 8VSB 13 | A 213028615 8VSB 14 | A 473028615 8VSB 15 | A 479028615 8VSB 16 | A 485028615 8VSB 17 | A 491028615 8VSB 18 | A 497028615 8VSB 19 | A 503028615 8VSB 20 | A 509028615 8VSB 21 | A 515028615 8VSB 22 | A 521028615 8VSB 23 | A 527028615 8VSB 24 | A 533028615 8VSB 25 | A 539028615 8VSB 26 | A 545028615 8VSB 27 | A 551028615 8VSB 28 | A 557028615 8VSB 29 | A 563028615 8VSB 30 | A 569028615 8VSB 31 | A 575028615 8VSB 32 | A 581028615 8VSB 33 | A 587028615 8VSB 34 | A 593028615 8VSB 35 | A 599028615 8VSB 36 | A 605028615 8VSB 37 | A 611028615 8VSB 38 | A 617028615 8VSB 39 | A 623028615 8VSB 40 | A 629028615 8VSB 41 | A 635028615 8VSB 42 | A 641028615 8VSB 43 | A 647028615 8VSB 44 | A 653028615 8VSB 45 | A 659028615 8VSB 46 | A 665028615 8VSB 47 | A 671028615 8VSB 48 | A 677028615 8VSB 49 | A 683028615 8VSB 50 | A 689028615 8VSB 51 | A 695028615 8VSB 52 | A 701028615 8VSB 53 | A 707028615 8VSB 54 | A 713028615 8VSB 55 | A 719028615 8VSB 56 | A 725028615 8VSB 57 | A 731028615 8VSB 58 | A 737028615 8VSB 59 | A 743028615 8VSB 60 | A 749028615 8VSB 61 | A 755028615 8VSB 62 | A 761028615 8VSB 63 | A 767028615 8VSB 64 | A 773028615 8VSB 65 | A 779028615 8VSB 66 | A 785028615 8VSB 67 | A 791028615 8VSB 68 | A 797028615 8VSB 69 | A 803028615 8VSB 70 | -------------------------------------------------------------------------------- /asi-deltacast.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * asi-deltacast.h: support for Deltacast ASI cards 3 | ***************************************************************************** 4 | * Copyright (C) 2004, 2009 VideoLAN 5 | * 6 | * Authors: Simon Lockhart 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 21 | *****************************************************************************/ 22 | 23 | #ifndef _ASI_DELTACAST_H 24 | #define _ASI_DELTACAST_H 25 | 26 | typedef enum error_source 27 | { 28 | DCERR_SRC_WIN32 = 0, /*! Win32 error code */ 29 | DCERR_SRC_SDI_API, /*! DELTA-sdi VIDEOMASTER error code */ 30 | DCERR_SRC_SDI_DRIVER, /*! DELTA-sdi DRIVER error code */ 31 | DCERR_SRC_STREAMMASTER, /*! DELTA-asi StreamMaster error code */ 32 | DCERR_SRC_SYSTEMSMASTER /*! DELTA-asi SystemsMaster error code */ 33 | } ERRORSOURCE; 34 | 35 | ULONG WINAPI Dc_GetLastError (ERRORSOURCE *pErrorSource); 36 | 37 | #define DC_ERRORCODE_MASK 0x2FFF0000 /* facility mask */ 38 | #define DCERR_TIMEOUT 0x80000201 /*! A time-out occured */ 39 | 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * config.h 3 | ***************************************************************************** 4 | * Copyright (C) 2004, 2008-2011 VideoLAN 5 | * 6 | * Authors: Christophe Massiot 7 | * Andy Gatward 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 22 | *****************************************************************************/ 23 | 24 | #ifndef _DVBLAST_CONFIG_H_ 25 | #define _DVBLAST_CONFIG_H_ 26 | 27 | #if defined(__linux__) 28 | #define DVBAPI_VERSION ((DVB_API_VERSION)*100+(DVB_API_VERSION_MINOR)) 29 | #define HAVE_DVB_SUPPORT 30 | #define HAVE_ASI_SUPPORT 31 | #define HAVE_CLOCK_NANOSLEEP 32 | #endif 33 | 34 | #define HAVE_ICONV 35 | 36 | #define DEFAULT_PORT 3001 37 | #define TS_SIZE 188 38 | #define MAX_PIDS 8192 39 | #define DEFAULT_IPV4_MTU 1500 40 | #define DEFAULT_IPV6_MTU 1280 41 | #define PADDING_PID 8191 42 | #define WATCHDOG_WAIT 10000000LL 43 | #define WATCHDOG_REFRACTORY_PERIOD 60000000LL 44 | #define MAX_ERRORS 1000 45 | #define DEFAULT_VERBOSITY 4 46 | #define MAX_POLL_TIMEOUT 100000 /* 100 ms */ 47 | #define MIN_POLL_TIMEOUT 100 /* 100 us */ 48 | #define DEFAULT_OUTPUT_LATENCY 200000 /* 200 ms */ 49 | #define DEFAULT_MAX_RETENTION 40000 /* 40 ms */ 50 | #define MAX_EIT_RETENTION 500000 /* 500 ms */ 51 | #define DEFAULT_FRONTEND_TIMEOUT 30000000 /* 30 s */ 52 | #define EXIT_STATUS_FRONTEND_TIMEOUT 100 53 | 54 | // Compatability defines 55 | #if defined(__APPLE__) 56 | #define ip_mreqn ip_mreq 57 | #endif 58 | 59 | #ifndef IPV6_ADD_MEMBERSHIP 60 | #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 61 | #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP 62 | #endif 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION_MAJOR = 3 2 | VERSION_MINOR = 1 3 | TOPDIR = `basename ${PWD}` 4 | GIT_VER = $(shell git describe --tags --dirty --always 2>/dev/null) 5 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 6 | deltacast_inc := $(shell sh -c 'test -f /usr/include/StreamMaster.h && echo -n Y') 7 | 8 | CFLAGS ?= -O3 -fomit-frame-pointer -g 9 | CFLAGS += -Wall -Wformat-security -Wno-strict-aliasing 10 | CFLAGS += -DVERSION=\"$(VERSION_MAJOR).$(VERSION_MINOR)\" 11 | CFLAGS += -DVERSION_MAJOR=$(VERSION_MAJOR) 12 | CFLAGS += -DVERSION_MINOR=$(VERSION_MINOR) 13 | ifneq "$(GIT_VER)" "" 14 | CFLAGS += -DVERSION_EXTRA=\"git-$(GIT_VER)\" 15 | else 16 | CFLAGS += -DVERSION_EXTRA=\"release\" 17 | endif 18 | 19 | ifeq ($(uname_S),Linux) 20 | LDLIBS += -lrt 21 | endif 22 | ifeq ($(uname_S),Darwin) 23 | LDLIBS += -liconv 24 | endif 25 | 26 | ifeq ($(deltacast_inc),Y) 27 | CFLAGS += -DHAVE_ASI_DELTACAST_SUPPORT 28 | LDLIBS += -lstreammaster 29 | endif 30 | 31 | LDLIBS_DVBLAST += -lpthread -lev 32 | 33 | OBJ_DVBLAST = dvblast.o util.o dvb.o udp.o asi.o demux.o output.o en50221.o comm.o mrtg-cnt.o asi-deltacast.o 34 | OBJ_DVBLASTCTL = util.o dvblastctl.o 35 | 36 | ifndef V 37 | Q = @ 38 | endif 39 | 40 | CLEAN_OBJS = dvblast dvblastctl $(OBJ_DVBLAST) $(OBJ_DVBLASTCTL) 41 | INSTALL_BIN = dvblast dvblastctl dvblast_mmi.sh 42 | INSTALL_MAN = dvblast.1 43 | 44 | PREFIX ?= /usr/local 45 | BIN = $(subst //,/,$(DESTDIR)/$(PREFIX)/bin) 46 | MAN = $(subst //,/,$(DESTDIR)/$(PREFIX)/share/man/man1) 47 | 48 | all: dvblast dvblastctl 49 | 50 | .PHONY: clean install uninstall dist 51 | 52 | %.o: %.c Makefile config.h dvblast.h en50221.h comm.h asi.h mrtg-cnt.h asi-deltacast.h 53 | @echo "CC $<" 54 | $(Q)$(CROSS)$(CC) $(CFLAGS) $(CPPFLAGS) -c $< 55 | 56 | dvblast: $(OBJ_DVBLAST) 57 | @echo "LINK $@" 58 | $(Q)$(CROSS)$(CC) $(LDFLAGS) -o $@ $(OBJ_DVBLAST) $(LDLIBS_DVBLAST) $(LDLIBS) 59 | 60 | dvblastctl: $(OBJ_DVBLASTCTL) 61 | @echo "LINK $@" 62 | $(Q)$(CROSS)$(CC) $(LDFLAGS) -o $@ $(OBJ_DVBLASTCTL) $(LDLIBS) 63 | 64 | clean: 65 | @echo "CLEAN $(CLEAN_OBJS)" 66 | $(Q)rm -f $(CLEAN_OBJS) 67 | 68 | distclean: clean 69 | 70 | install: all 71 | @install -d "$(BIN)" 72 | @install -d "$(MAN)" 73 | @echo "INSTALL $(INSTALL_MAN) -> $(MAN)" 74 | $(Q)install -m 644 dvblast.1 "$(MAN)" 75 | @echo "INSTALL $(INSTALL_BIN) -> $(BIN)" 76 | $(Q)install dvblast dvblastctl dvblast_mmi.sh "$(BIN)" 77 | 78 | uninstall: 79 | @-for FILE in $(INSTALL_BIN); do \ 80 | echo "RM $(BIN)/$$FILE"; \ 81 | rm "$(BIN)/$$FILE"; \ 82 | done 83 | @-for FILE in $(INSTALL_MAN); do \ 84 | echo "RM $(MAN)/$$FILE"; \ 85 | rm "$(MAN)/$$FILE"; \ 86 | done 87 | 88 | dist: clean 89 | @echo "ARCHIVE dvblast-$(VERSION_MAJOR).$(VERSION_MINOR).tar.bz2" 90 | $(Q)git archive --format=tar --prefix=dvblast-$(VERSION_MAJOR).$(VERSION_MINOR)/ master | bzip2 -9 > dvblast-$(VERSION_MAJOR).$(VERSION_MINOR).tar.bz2 91 | $(Q)ls -l dvblast-$(VERSION_MAJOR).$(VERSION_MINOR).tar.bz2 92 | 93 | -------------------------------------------------------------------------------- /comm.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * comm.h 3 | ***************************************************************************** 4 | * Copyright (C) 2008 VideoLAN 5 | * 6 | * Authors: Christophe Massiot 7 | * 8 | * This program is free software. It comes without any warranty, to 9 | * the extent permitted by applicable law. You can redistribute it 10 | * and/or modify it under the terms of the Do What The Fuck You Want 11 | * To Public License, Version 2, as published by Sam Hocevar. See 12 | * http://sam.zoy.org/wtfpl/COPYING for more details. 13 | *****************************************************************************/ 14 | 15 | #ifdef HAVE_DVB_SUPPORT 16 | /* DVB Card Drivers */ 17 | #include 18 | #include 19 | #include 20 | #include 21 | #endif 22 | 23 | #include 24 | 25 | #define COMM_HEADER_SIZE 8 26 | #define COMM_BUFFER_SIZE (COMM_HEADER_SIZE + ((PSI_PRIVATE_MAX_SIZE + PSI_HEADER_SIZE) * (PSI_TABLE_MAX_SECTIONS / 2))) 27 | #define COMM_HEADER_MAGIC 0x49 28 | 29 | #define COMM_MAX_MSG_CHUNK 4096 30 | 31 | typedef enum { 32 | CMD_INVALID = 0, 33 | CMD_RELOAD = 1, 34 | CMD_SHUTDOWN = 2, 35 | CMD_FRONTEND_STATUS = 3, 36 | CMD_MMI_STATUS = 4, 37 | CMD_MMI_SLOT_STATUS = 5, /* arg: slot */ 38 | CMD_MMI_OPEN = 6, /* arg: slot */ 39 | CMD_MMI_CLOSE = 7, /* arg: slot */ 40 | CMD_MMI_RECV = 8, /* arg: slot */ 41 | CMD_GET_PAT = 10, 42 | CMD_GET_CAT = 11, 43 | CMD_GET_NIT = 12, 44 | CMD_GET_SDT = 13, 45 | CMD_GET_PMT = 14, /* arg: service_id (uint16_t) */ 46 | CMD_GET_PIDS = 15, 47 | CMD_GET_PID = 16, /* arg: pid (uint16_t) */ 48 | CMD_MMI_SEND_TEXT = 17, /* arg: slot, en50221_mmi_object_t */ 49 | CMD_MMI_SEND_CHOICE = 18, /* arg: slot, en50221_mmi_object_t */ 50 | } ctl_cmd_t; 51 | 52 | typedef enum { 53 | RET_OK = 0, 54 | RET_ERR = 1, 55 | RET_FRONTEND_STATUS = 2, 56 | RET_MMI_STATUS = 3, 57 | RET_MMI_SLOT_STATUS = 4, 58 | RET_MMI_RECV = 5, 59 | RET_MMI_WAIT = 6, 60 | RET_NODATA = 7, 61 | RET_PAT = 8, 62 | RET_CAT = 9, 63 | RET_NIT = 10, 64 | RET_SDT = 11, 65 | RET_PMT = 12, 66 | RET_PIDS = 13, 67 | RET_PID = 14, 68 | RET_HUH = 255, 69 | } ctl_cmd_answer_t; 70 | 71 | #ifdef HAVE_DVB_SUPPORT 72 | struct ret_frontend_status 73 | { 74 | struct dvb_frontend_info info; 75 | fe_status_t i_status; 76 | uint32_t i_ber; 77 | uint16_t i_strength, i_snr; 78 | }; 79 | 80 | struct ret_mmi_status 81 | { 82 | ca_caps_t caps; 83 | }; 84 | 85 | struct ret_mmi_slot_status 86 | { 87 | ca_slot_info_t sinfo; 88 | }; 89 | 90 | struct ret_mmi_recv 91 | { 92 | en50221_mmi_object_t object; 93 | }; 94 | 95 | struct cmd_mmi_send 96 | { 97 | uint8_t i_slot; 98 | en50221_mmi_object_t object; 99 | }; 100 | #endif 101 | 102 | struct cmd_pid_info 103 | { 104 | ts_pid_info_t pids[MAX_PIDS]; 105 | }; 106 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Changes between 3.0 and 3.1: 2 | ---------------------------- 3 | * Print source address in UDP input 4 | * Add DVB-T2 support 5 | * Add HEVC support 6 | * Add ONID remapping 7 | * Add PCR even when PCR PID is not selected, but drop non-PCR packets 8 | 9 | Changes between 2.2 and 3.0: 10 | ---------------------------- 11 | * Rewrite core to use libev event loop 12 | * Optimize allocations with a buffer pool 13 | * Add support for building DVBlast on OS X 14 | * Add support for uncommitted diseqc switches 15 | * Fix ECM pid selection 16 | * Add CA device addressing 17 | * Add support for remapping ES pids to fixed values globally and per output 18 | * Add support for multi-delivery system frontends 19 | * Add support for multistream that appeared in Linux 3.6 20 | * Add support for Deltacast ASI cards 21 | * Add support for stream pass-through from the config file 22 | * Add options to periodically print status of bitrate, errors and PIDs 23 | * Add output options to set network ID and network name 24 | * Switch default string charset to UTF-8 25 | * Do not remove padding with ASI 26 | 27 | Changes between 2.1 and 2.2: 28 | ---------------------------- 29 | * Fix a regression that prevented ECM pass-through (-Y) from working. 30 | * Handle ECM pids that are described in PMT ES descriptor loop. 31 | 32 | Changes between 2.0 and 2.1: 33 | ---------------------------- 34 | * Fix MMI menus which were accidentally broken in 2.0 35 | * Remove ecm and emm output options because they weren't working 36 | * Better handling of changed PSI tables with same version number 37 | 38 | Changes between 1.2 and 2.0: 39 | ---------------------------- 40 | * Fix latency and potential packet loss during CAM communication 41 | * Add optional kernel patches for lower latency 42 | * Smooth packet output with an extra buffer 43 | * libdvbpsi runtime is no longer needed; biTStream development library 44 | is used instead 45 | * Add the ability to bind to a specific network interface 46 | * Add a configurable MTU 47 | * Add support for NIT in DVB compliance mode 48 | * Syslog support with -l option 49 | * Override tuning parameters with new options 50 | * Output all PMTs with -w, all ESs (even unknown) for a program with -z 51 | * Add support for ECM and EMM packets pass-through 52 | * Fix diseqc command with high-band tranponders 53 | * Add basic support for ATSC 54 | * Add support for MRTG statistics 55 | * Add detailed information for TS errors 56 | * Add support for getting PAT/CAT/NIT/SDT tables in dvblastctl 57 | * Add support for getting PMT table for chosen service in dvblastctl 58 | * Add support for getting PID information (bps, error counters and more) 59 | * Add support for setting service name and provider name per output 60 | * Command socket is usable with any input (ASI, DVB, UDP), previously 61 | only DVB input worked 62 | 63 | Changes between 1.1 and 1.2: 64 | ---------------------------- 65 | * Support for IPv6 output and duplicate 66 | * Support input from Computer Modules ASI card 67 | * Support input from (IPv4) RTP / UDP stream 68 | * Miscellaneous CAM and demux fixes 69 | * Miscellaneous DVB-S2 fixes 70 | 71 | Changes between 1.0 and 1.1: 72 | ---------------------------- 73 | 74 | * Support for adapters with multiple frontends (-n) 75 | * Control of verbosity level with -q 76 | * Support for TS over raw UDP with -U or /udp in the config file 77 | * EIT, SDT and TDT pass-through for EPG information (-e) 78 | * Original TSID kept (randomized TSID via -T) 79 | * Miscellaneous CAM, demux and tuning fixes 80 | * DVB-S diseqc support 81 | -------------------------------------------------------------------------------- /dvblast_mmi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ############################################################################### 3 | # dvblast_mmi.sh 4 | ############################################################################### 5 | # Copyright (C) 1998-2008 VideoLAN 6 | # 7 | # Authors: Christophe Massiot 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 22 | ############################################################################### 23 | 24 | BASE_DIR=`dirname $_` 25 | 26 | 27 | # 28 | # Check args 29 | # 30 | 31 | if test x"$1" != x"-r" -o -z "$2"; then 32 | echo "Usage: $0 -r []" >&2 33 | exit 1 34 | fi 35 | 36 | SOCKET=$2 37 | SLOT=$3 38 | 39 | if which dvblastctl >/dev/null; then 40 | DVBLASTCTL="dvblastctl -r $SOCKET" 41 | elif test -x "$PWD/dvblastctl"; then 42 | DVBLASTCTL="$PWD/dvblastctl -r $SOCKET" 43 | elif test -x "$BASE_DIR/dvblastctl"; then 44 | DVBLASTCTL="$BASE_DIR/dvblastctl -r $SOCKET" 45 | else 46 | echo "Couldn't find dvblastctl" 47 | exit 1 48 | fi 49 | 50 | 51 | # 52 | # Check adapter status 53 | # 54 | 55 | $DVBLASTCTL mmi_status >/dev/null 56 | NUM_SLOTS=$? 57 | 58 | if test $NUM_SLOTS -eq 255; then 59 | echo "Unable to set up a connection" >&2 60 | exit 2 61 | fi 62 | if test $NUM_SLOTS -eq 0; then 63 | echo "Adapter has no available CAM module" >&2 64 | exit 3 65 | fi 66 | if test -z $SLOT; then 67 | echo "Defaulting to slot #0" 68 | SLOT=0 69 | fi 70 | if test "$SLOT" -ge $NUM_SLOTS; then 71 | echo "Slot out of range, pick in the range 0-`expr $NUM_SLOTS - 1`" >&2 72 | exit 3 73 | fi 74 | 75 | 76 | # 77 | # Check CAM status 78 | # 79 | 80 | $DVBLASTCTL mmi_slot_status $SLOT >/dev/null 81 | STATUS=$? 82 | 83 | if test $STATUS -ne 0; then 84 | echo "Slot is not ready, retry later" >&2 85 | exit 3 86 | fi 87 | 88 | $DVBLASTCTL mmi_get $SLOT >/dev/null 89 | STATUS=$? 90 | 91 | if test $STATUS -eq 255; then 92 | echo "Opening MMI session..." 93 | $DVBLASTCTL mmi_open $SLOT 94 | STATUS=$? 95 | if test $STATUS -eq 255; then 96 | echo "Communication error" >&2 97 | exit 2 98 | elif test $STATUS -ne 0; then 99 | echo "Couldn't open MMI session" >&2 100 | exit 4 101 | fi 102 | sleep 3 103 | fi 104 | 105 | 106 | # 107 | # Da loop 108 | # 109 | 110 | while :; do 111 | $DVBLASTCTL mmi_get $SLOT 112 | STATUS=$? 113 | 114 | case $STATUS in 115 | 255) 116 | echo "Connection closed" >&2 117 | exit 2 118 | ;; 119 | 254) 120 | echo -n "Your choice (empty for extra choices) ? " 121 | ;; 122 | 253) 123 | echo "CAUTION: the password won't be bulleted, be alone" 124 | echo -n "Your choice (empty for extra choices) ? " 125 | ;; 126 | 252) 127 | sleep 1 128 | continue 129 | ;; 130 | 0) 131 | echo -n "Your choice: (B)ack, (C)lose or (R)etry ? " 132 | ;; 133 | *) 134 | echo -n "Your choice: [0-$STATUS], (C)lose or (R)etry ? " 135 | ;; 136 | esac 137 | 138 | read -r ANSWER 139 | 140 | case $STATUS in 141 | 254|253) 142 | if test -z "$ANSWER"; then 143 | echo -n "(B)ack, (C)lose or (R)etry ? " 144 | read -r ANSWER 145 | 146 | case "$ANSWER" in 147 | B|b|Back|back|BACK) 148 | if ! $DVBLASTCTL mmi_send_text $SLOT; then 149 | echo "mmi_send_text failed, apparently" >&2 150 | else 151 | sleep 1 152 | fi 153 | ;; 154 | C|c|Close|close|CLOSE) 155 | $DVBLASTCTL mmi_close $SLOT 156 | exit 0 157 | ;; 158 | R|r|Retry|retry|RETRY) 159 | : 160 | ;; 161 | *) 162 | echo "Invalid string, retry..." 163 | ;; 164 | esac 165 | 166 | else 167 | if ! $DVBLASTCTL mmi_send_text $SLOT "$ANSWER"; then 168 | echo "mmi_send_text failed, apparently" >&2 169 | else 170 | sleep 1 171 | fi 172 | fi 173 | ;; 174 | 175 | *) 176 | case "$ANSWER" in 177 | B|b|Back|back|BACK) 178 | if ! $DVBLASTCTL mmi_send_choice $SLOT 0; then 179 | echo "mmi_send_choice failed, apparently" >&2 180 | else 181 | sleep 1 182 | fi 183 | ;; 184 | C|c|Close|close|CLOSE) 185 | $DVBLASTCTL mmi_close $SLOT 186 | exit 0 187 | ;; 188 | R|r|Retry|retry|RETRY) 189 | : 190 | ;; 191 | *) 192 | echo "$ANSWER" | grep -q "^[[:digit:]]\+\$" 193 | if test $? -ne 0; then 194 | echo "Invalid string, retry..." 195 | else 196 | if ! $DVBLASTCTL mmi_send_choice $SLOT "$ANSWER"; then 197 | echo "mmi_send_choice failed, apparently" >&2 198 | else 199 | sleep 1 200 | fi 201 | fi 202 | ;; 203 | esac 204 | ;; 205 | esac 206 | 207 | echo 208 | done 209 | -------------------------------------------------------------------------------- /mrtg-cnt.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * mrtg-cnt.c Handle dvb TS packets and count them for MRTG 3 | ***************************************************************************** 4 | * Copyright Tripleplay service 2004,2005,2011 5 | * 6 | * Author: Andy Lindsay 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 21 | *****************************************************************************/ 22 | 23 | /* vim: set shiftwidth=4 tabstop=4 expandtab autoindent : */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include "dvblast.h" 37 | 38 | // File handle 39 | static FILE *mrtg_fh = NULL; 40 | 41 | // Counts 42 | static long long l_mrtg_packets = 0; // Packets received 43 | static long long l_mrtg_seq_err_packets = 0; // Out of sequence packets received 44 | static long long l_mrtg_error_packets = 0; // Packets received with the error flag set 45 | static long long l_mrtg_scram_packets = 0; // Scrambled Packets received 46 | 47 | // Reporting timer 48 | #if defined( WIN32 ) 49 | static LARGE_INTEGER mrtg_time; 50 | static LARGE_INTEGER mrtg_inc; 51 | #else 52 | static struct timeval mrtg_time = { 0, 0 }; 53 | #endif 54 | 55 | // Define the dump period in seconds 56 | #define MRTG_INTERVAL 10 57 | 58 | // Pid sequence numbers 59 | #define PIDS 0x2000 60 | static signed char i_pid_seq[PIDS]; 61 | 62 | // Report the mrtg counters: bytes received, error packets & sequence errors 63 | static void dumpCounts() 64 | { 65 | unsigned int multiplier = 1; //MRTG_INTERVAL; 66 | if(mrtg_fh) { 67 | rewind(mrtg_fh); 68 | fprintf(mrtg_fh, "%lld %lld %lld %lld\n", 69 | l_mrtg_packets * 188 * multiplier, 70 | l_mrtg_error_packets * multiplier, 71 | l_mrtg_seq_err_packets * multiplier, 72 | l_mrtg_scram_packets * multiplier); 73 | fflush(mrtg_fh); 74 | } 75 | } 76 | 77 | // analyse the input block counting packets and errors 78 | // The input is a pointer to a block_t structure, which might be a linked list 79 | // of blocks. Each block has one TS packet. 80 | void mrtgAnalyse(block_t * p_ts) 81 | { 82 | unsigned int i_pid; 83 | block_t *p_block = p_ts; 84 | 85 | if (mrtg_fh == NULL) return; 86 | 87 | while (p_block != NULL) { 88 | uint8_t *ts_packet = p_block->p_ts; 89 | 90 | char i_seq, i_last_seq; 91 | l_mrtg_packets++; 92 | 93 | if (ts_packet[0] != 0x47) { 94 | l_mrtg_error_packets++; 95 | p_block = p_block->p_next; 96 | continue; 97 | } 98 | 99 | if (ts_packet[1] & 0x80) { 100 | l_mrtg_error_packets++; 101 | p_block = p_block->p_next; 102 | continue; 103 | } 104 | 105 | i_pid = (ts_packet[1] & 0x1f) << 8 | ts_packet[2]; 106 | 107 | // Just count null packets - don't check the sequence numbering 108 | if (i_pid == 0x1fff) { 109 | p_block = p_block->p_next; 110 | continue; 111 | } 112 | 113 | if (ts_packet[3] & 0xc0) { 114 | l_mrtg_scram_packets++; 115 | } 116 | // Check the sequence numbering 117 | i_seq = ts_packet[3] & 0xf; 118 | i_last_seq = i_pid_seq[i_pid]; 119 | 120 | if (i_last_seq == -1) { 121 | // First packet - ignore the sequence 122 | } else if (ts_packet[3] & 0x10) { 123 | // Packet contains payload - sequence should be up by one 124 | if (i_seq != ((i_last_seq + 1) & 0x0f)) { 125 | l_mrtg_seq_err_packets++; 126 | } 127 | } else { 128 | // Packet contains no payload - sequence should be unchanged 129 | if (i_seq != i_last_seq) { 130 | l_mrtg_seq_err_packets++; 131 | } 132 | } 133 | i_pid_seq[i_pid] = i_seq; 134 | 135 | // Look at next block 136 | p_block = p_block->p_next; 137 | } 138 | 139 | // All blocks processed. See if we need to dump the stats 140 | struct timeval now; 141 | gettimeofday(&now, NULL); 142 | if (timercmp(&now, &mrtg_time, >)) { 143 | // Time to report the mrtg counters 144 | dumpCounts(); 145 | 146 | // Set the timer for next time 147 | // 148 | // Normally we add the interval to the previous time so that if one 149 | // dump is a bit late, the next one still occurs at the correct time. 150 | // However, if there is a long gap (e.g. because the channel has 151 | // stopped for some time), then just rebase the timing to the current 152 | // time. I've chosen MRTG_INTERVAL as the long gap - this is arbitary 153 | if ((now.tv_sec - mrtg_time.tv_sec) > MRTG_INTERVAL) { 154 | msg_Dbg(NULL, "Dump is %d seconds late - reset timing\n", 155 | (int) (now.tv_sec - mrtg_time.tv_sec)); 156 | mrtg_time = now; 157 | } 158 | mrtg_time.tv_sec += MRTG_INTERVAL; 159 | } 160 | } 161 | 162 | int mrtgInit(char *mrtg_file) 163 | { 164 | if ( !mrtg_file ) 165 | return -1; 166 | 167 | /* Open MRTG file */ 168 | msg_Dbg(NULL, "Opening mrtg file %s.\n", mrtg_file); 169 | if ((mrtg_fh = fopen(mrtg_file, "wb")) == NULL) { 170 | msg_Err(NULL, "unable to open mrtg file"); 171 | return -1; 172 | } 173 | // Initialise the file 174 | fprintf(mrtg_fh, "0 0 0 0\n"); 175 | fflush(mrtg_fh); 176 | 177 | // Initialise the sequence numbering 178 | memset(&i_pid_seq[0], -1, sizeof(signed char) * PIDS); 179 | 180 | // Set the reporting timer 181 | gettimeofday(&mrtg_time, NULL); 182 | mrtg_time.tv_sec += MRTG_INTERVAL; 183 | 184 | return 0; 185 | } 186 | 187 | void mrtgClose() 188 | { 189 | // This is only for testing when using filetest. 190 | if (mrtg_fh) { 191 | dumpCounts(); 192 | fclose(mrtg_fh); 193 | mrtg_fh = NULL; 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /extra/dvbiscovery/dvbiscovery.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ############################################################################### 3 | # dvbiscovery.sh 4 | ############################################################################### 5 | # Copyright (C) 2010 VideoLAN 6 | # 7 | # Authors: Christophe Massiot 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 22 | ############################################################################### 23 | 24 | CONF_BASE="/usr/local/share/dvblast/dvbiscovery" 25 | #CONF_BASE="./" 26 | DVBLAST=dvblast 27 | LOCK_TIMEOUT=2500 28 | QUIT_TIMEOUT=20000 29 | 30 | usage() { 31 | echo "Usage: $0 [-a ] [-n ] [-S ] [-c ]" >&2 32 | exit 1 33 | } 34 | 35 | conf_file_passed="" 36 | adapter="" 37 | frontend="" 38 | diseqc="" 39 | 40 | TEMP=`getopt -o a:n:S:c: -n "$0" -- "$@"` 41 | 42 | if test $? -ne 0; then 43 | usage 44 | fi 45 | 46 | eval set -- "$TEMP" 47 | 48 | while :; do 49 | case "$1" in 50 | -a) 51 | adapter="-a $2" 52 | shift 2 53 | ;; 54 | -n) 55 | frontend="-n $2" 56 | shift 2 57 | ;; 58 | -c) 59 | conf_file_passed=$2 60 | shift 2 61 | ;; 62 | -S) 63 | diseqc="-S $2" 64 | shift 2 65 | ;; 66 | --) 67 | shift 68 | break 69 | ;; 70 | *) 71 | usage 72 | ;; 73 | esac 74 | done 75 | 76 | type=`$DVBLAST $diseqc $adapter $frontend -f 0 2>&1 | grep '^debug: Frontend' | sed 's/^debug: Frontend ".*" type "\(.*\)" supports:$/\1/'` 77 | tune="" 78 | conf_file="" 79 | 80 | case "$type" in 81 | "QPSK (DVB-S/S2)") 82 | conf_file="${CONF_BASE}_dvb-s.conf" 83 | tune=tune_sat 84 | ;; 85 | "QAM (DVB-C)") 86 | conf_file="${CONF_BASE}_dvb-c.conf" 87 | tune=tune_cable 88 | ;; 89 | "OFDM (DVB-T)") 90 | conf_file="${CONF_BASE}_dvb-t.conf" 91 | tune=tune_dtt 92 | ;; 93 | "ATSC") 94 | conf_file="${CONF_BASE}_atsc.conf" 95 | tune=tune_atsc 96 | ;; 97 | *) 98 | echo "unknown frontend type $type" >&2 99 | exit 1 100 | esac 101 | 102 | if test -n "$conf_file_passed"; then 103 | conf_file=$conf_file_passed 104 | fi 105 | 106 | if ! test -r "$conf_file"; then 107 | echo "unable to open $conf_file" >&2 108 | exit 1 109 | fi 110 | 111 | signal_catch() { 112 | if test $childpid -ne 0; then 113 | kill $childpid 114 | wait $childpid 115 | fi 116 | exit 1 117 | } 118 | 119 | exec_dvblast() { 120 | tmp_file=`mktemp` 121 | 122 | $DVBLAST $diseqc $adapter $frontend -O $LOCK_TIMEOUT -Q $QUIT_TIMEOUT -q4 -x xml $opts >| $tmp_file & 123 | childpid=$! 124 | wait $childpid 125 | if test $? -eq 0; then 126 | cat $tmp_file 127 | echo "" 128 | rm $tmp_file 129 | exit 0 130 | fi 131 | 132 | childpid=0 133 | rm $tmp_file 134 | } 135 | 136 | strtofec() { 137 | case "$1" in 138 | "NONE") opts="$opts $2 0" ;; 139 | "1/2") opts="$opts $2 12" ;; 140 | "2/3") opts="$opts $2 23" ;; 141 | "3/4") opts="$opts $2 34" ;; 142 | "4/5") opts="$opts $2 45" ;; 143 | "5/6") opts="$opts $2 56" ;; 144 | "6/7") opts="$opts $2 67" ;; 145 | "7/8") opts="$opts $2 78" ;; 146 | "8/9") opts="$opts $2 89" ;; 147 | "AUTO"|*) ;; 148 | esac 149 | } 150 | 151 | strtomod() { 152 | case "$1" in 153 | "QPSK") opts="$opts -m qpsk" ;; 154 | "QAM16") opts="$opts -m qam_16" ;; 155 | "QAM32") opts="$opts -m qam_32" ;; 156 | "QAM64") opts="$opts -m qam_64" ;; 157 | "QAM128") opts="$opts -m qam_128" ;; 158 | "8VSB") opts="$opts -m vsb_8" ;; 159 | "16VSB") opts="$opts -m vsb_16" ;; 160 | "AUTO"|*) ;; 161 | esac 162 | } 163 | 164 | tune_sat() { 165 | childpid=0 166 | trap signal_catch 1 2 3 15 167 | 168 | while read sys freq pol srate fec what mod; do 169 | opts="-f $freq -s $srate" 170 | 171 | case "$sys" in 172 | "S") ;; 173 | "S2") 174 | case "$mod" in 175 | "QPSK") opts="$opts -m qpsk" ;; 176 | "8PSK") opts="$opts -m psk_8" ;; 177 | *) 178 | echo "invalid modulation $mod" >&2 179 | ;; 180 | esac 181 | ;; 182 | *) 183 | echo "incompatible file" >&2 184 | exit 1 185 | ;; 186 | esac 187 | 188 | strtofec $fec "-F" 189 | 190 | case "$pol" in 191 | "V") opts="$opts -v 13" ;; 192 | "H") opts="$opts -v 18" ;; 193 | *) ;; 194 | esac 195 | 196 | exec_dvblast 197 | done 198 | } 199 | 200 | tune_cable() { 201 | childpid=0 202 | trap signal_catch 1 2 3 15 203 | 204 | while read sys freq srate fec mod; do 205 | opts="-f $freq -s $srate" 206 | 207 | case "$sys" in 208 | "C") ;; 209 | *) 210 | echo "incompatible file" >&2 211 | exit 1 212 | ;; 213 | esac 214 | 215 | strtofec $fec "-F" 216 | strtomod $mod 217 | 218 | exec_dvblast 219 | done 220 | } 221 | 222 | tune_dtt() { 223 | childpid=0 224 | trap signal_catch 1 2 3 15 225 | 226 | while read sys freq bw fec fec2 mod mode guard hier; do 227 | opts="-f $freq" 228 | 229 | case "$sys" in 230 | "T"|"T2") ;; 231 | *) 232 | echo "incompatible file" >&2 233 | exit 1 234 | ;; 235 | esac 236 | 237 | case "$bw" in 238 | "8MHz") opts="$opts -b 8" ;; 239 | "7MHz") opts="$opts -b 7" ;; 240 | "6MHz") opts="$opts -b 6" ;; 241 | "AUTO"|*) ;; 242 | esac 243 | 244 | strtofec $fec "-F" 245 | strtofec $fec2 "-K" 246 | strtomod $mod 247 | 248 | case "$mode" in 249 | "2k") opts="$opts -X 2" ;; 250 | "8k") opts="$opts -X 8" ;; 251 | "AUTO"|*) ;; 252 | esac 253 | 254 | case "$guard" in 255 | "1/32") opts="$opts -G 32" ;; 256 | "1/16") opts="$opts -G 16" ;; 257 | "1/8") opts="$opts -G 8" ;; 258 | "1/4") opts="$opts -G 4" ;; 259 | "AUTO"|*) ;; 260 | esac 261 | 262 | case "$hier" in 263 | "NONE") opts="$opts -H 0" ;; 264 | "1") opts="$opts -H 1" ;; 265 | "2") opts="$opts -H 2" ;; 266 | "4") opts="$opts -H 4" ;; 267 | "AUTO"|*) ;; 268 | esac 269 | 270 | exec_dvblast 271 | done 272 | } 273 | 274 | tune_atsc() { 275 | childpid=0 276 | trap signal_catch 1 2 3 15 277 | 278 | while read sys freq mod; do 279 | opts="-f $freq" 280 | 281 | case "$sys" in 282 | "A") ;; 283 | *) 284 | echo "incompatible file" >&2 285 | exit 1 286 | ;; 287 | esac 288 | 289 | strtomod $mod 290 | 291 | exec_dvblast 292 | done 293 | } 294 | 295 | childpid=0 296 | trap signal_catch 1 2 3 15 297 | 298 | grep -v "^#" < "$conf_file" 2>/dev/null | $tune & 299 | childpid=$! 300 | wait $childpid 301 | 302 | exit 100 303 | -------------------------------------------------------------------------------- /en50221.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * en50221.h 3 | ***************************************************************************** 4 | * Copyright (C) 2008 VideoLAN 5 | * 6 | * Authors: Christophe Massiot 7 | * 8 | * This program is free software. It comes without any warranty, to 9 | * the extent permitted by applicable law. You can redistribute it 10 | * and/or modify it under the terms of the Do What The Fuck You Want 11 | * To Public License, Version 2, as published by Sam Hocevar. See 12 | * http://sam.zoy.org/wtfpl/COPYING for more details. 13 | *****************************************************************************/ 14 | 15 | #include 16 | 17 | typedef void * access_t; 18 | 19 | #define STRINGIFY( z ) UGLY_KLUDGE( z ) 20 | #define UGLY_KLUDGE( z ) #z 21 | 22 | #define EN50221_MMI_NONE 0 23 | #define EN50221_MMI_ENQ 1 24 | #define EN50221_MMI_ANSW 2 25 | #define EN50221_MMI_MENU 3 26 | #define EN50221_MMI_MENU_ANSW 4 27 | #define EN50221_MMI_LIST 5 28 | 29 | typedef struct en50221_mmi_object_t 30 | { 31 | int i_object_type; 32 | 33 | union 34 | { 35 | struct 36 | { 37 | int b_blind; 38 | char *psz_text; 39 | } enq; 40 | 41 | struct 42 | { 43 | int b_ok; 44 | char *psz_answ; 45 | } answ; 46 | 47 | struct 48 | { 49 | char *psz_title, *psz_subtitle, *psz_bottom; 50 | char **ppsz_choices; 51 | int i_choices; 52 | } menu; /* menu and list are the same */ 53 | 54 | struct 55 | { 56 | int i_choice; 57 | } menu_answ; 58 | } u; 59 | } en50221_mmi_object_t; 60 | 61 | #define MAX_CI_SLOTS 16 62 | #define MAX_SESSIONS 32 63 | 64 | extern int i_ca_handle; 65 | extern int i_ca_type; 66 | 67 | /***************************************************************************** 68 | * Prototypes 69 | *****************************************************************************/ 70 | void en50221_Init( void ); 71 | void en50221_Reset( void ); 72 | void en50221_AddPMT( uint8_t *p_pmt ); 73 | void en50221_UpdatePMT( uint8_t *p_pmt ); 74 | void en50221_DeletePMT( uint8_t *p_pmt ); 75 | uint8_t en50221_StatusMMI( uint8_t *p_answer, ssize_t *pi_size ); 76 | uint8_t en50221_StatusMMISlot( uint8_t *p_buffer, ssize_t i_size, 77 | uint8_t *p_answer, ssize_t *pi_size ); 78 | uint8_t en50221_OpenMMI( uint8_t *p_buffer, ssize_t i_size ); 79 | uint8_t en50221_CloseMMI( uint8_t *p_buffer, ssize_t i_size ); 80 | uint8_t en50221_GetMMIObject( uint8_t *p_buffer, ssize_t i_size, 81 | uint8_t *p_answer, ssize_t *pi_size ); 82 | uint8_t en50221_SendMMIObject( uint8_t *p_buffer, ssize_t i_size ); 83 | 84 | 85 | /* 86 | * This is where it gets scary: do not show to < 18 yrs old 87 | */ 88 | 89 | /***************************************************************************** 90 | * en50221_SerializeMMIObject : 91 | *****************************************************************************/ 92 | static inline int en50221_SerializeMMIObject( uint8_t *p_answer, 93 | ssize_t *pi_size, 94 | en50221_mmi_object_t *p_object ) 95 | { 96 | ssize_t i_max_size = *pi_size; 97 | en50221_mmi_object_t *p_serialized = (en50221_mmi_object_t *)p_answer; 98 | char **pp_tmp; 99 | int i; 100 | 101 | #define STORE_MEMBER(pp_pointer, i_size) \ 102 | if ( i_size + *pi_size > i_max_size ) \ 103 | return -1; \ 104 | memcpy( p_answer, *pp_pointer, i_size ); \ 105 | *pp_pointer = (void *)*pi_size; \ 106 | *pi_size += i_size; \ 107 | p_answer += i_size; 108 | 109 | if ( sizeof(en50221_mmi_object_t) > i_max_size ) 110 | return -1; 111 | memcpy( p_answer, p_object, sizeof(en50221_mmi_object_t) ); 112 | *pi_size = sizeof(en50221_mmi_object_t); 113 | p_answer += sizeof(en50221_mmi_object_t); 114 | 115 | switch ( p_object->i_object_type ) 116 | { 117 | case EN50221_MMI_ENQ: 118 | STORE_MEMBER( &p_serialized->u.enq.psz_text, 119 | strlen(p_object->u.enq.psz_text) + 1 ); 120 | break; 121 | 122 | case EN50221_MMI_ANSW: 123 | STORE_MEMBER( &p_serialized->u.answ.psz_answ, 124 | strlen(p_object->u.answ.psz_answ) + 1 ); 125 | break; 126 | 127 | case EN50221_MMI_MENU: 128 | case EN50221_MMI_LIST: 129 | STORE_MEMBER( &p_serialized->u.menu.psz_title, 130 | strlen(p_object->u.menu.psz_title) + 1 ); 131 | STORE_MEMBER( &p_serialized->u.menu.psz_subtitle, 132 | strlen(p_object->u.menu.psz_subtitle) + 1 ); 133 | STORE_MEMBER( &p_serialized->u.menu.psz_bottom, 134 | strlen(p_object->u.menu.psz_bottom) + 1 ); 135 | /* pointer alignment */ 136 | i = ((*pi_size + 7) / 8) * 8 - *pi_size; 137 | *pi_size += i; 138 | p_answer += i; 139 | pp_tmp = (char **)p_answer; 140 | STORE_MEMBER( &p_serialized->u.menu.ppsz_choices, 141 | p_object->u.menu.i_choices * sizeof(char *) ); 142 | 143 | for ( i = 0; i < p_object->u.menu.i_choices; i++ ) 144 | { 145 | STORE_MEMBER( &pp_tmp[i], 146 | strlen(p_object->u.menu.ppsz_choices[i]) + 1 ); 147 | } 148 | break; 149 | 150 | default: 151 | break; 152 | } 153 | 154 | return 0; 155 | } 156 | 157 | /***************************************************************************** 158 | * en50221_UnserializeMMIObject : 159 | *****************************************************************************/ 160 | static inline int en50221_UnserializeMMIObject( en50221_mmi_object_t *p_object, 161 | ssize_t i_size ) 162 | { 163 | int i, j; 164 | 165 | #define CHECK_MEMBER(pp_member) \ 166 | if ( (ptrdiff_t)*pp_member >= i_size ) \ 167 | return -1; \ 168 | for ( i = 0; ((char *)p_object + (ptrdiff_t)*pp_member)[i] != '\0'; \ 169 | i++ ) \ 170 | if ( (ptrdiff_t)*pp_member + i >= i_size ) \ 171 | return -1; \ 172 | *pp_member += (ptrdiff_t)p_object; 173 | 174 | switch ( p_object->i_object_type ) 175 | { 176 | case EN50221_MMI_ENQ: 177 | CHECK_MEMBER(&p_object->u.enq.psz_text); 178 | break; 179 | 180 | case EN50221_MMI_ANSW: 181 | CHECK_MEMBER(&p_object->u.answ.psz_answ); 182 | break; 183 | 184 | case EN50221_MMI_MENU: 185 | case EN50221_MMI_LIST: 186 | CHECK_MEMBER(&p_object->u.menu.psz_title); 187 | CHECK_MEMBER(&p_object->u.menu.psz_subtitle); 188 | CHECK_MEMBER(&p_object->u.menu.psz_bottom); 189 | if ( (ptrdiff_t)p_object->u.menu.ppsz_choices 190 | + p_object->u.menu.i_choices * sizeof(char *) >= i_size ) 191 | return -1; 192 | p_object->u.menu.ppsz_choices = (char **)((char *)p_object 193 | + (ptrdiff_t)p_object->u.menu.ppsz_choices); 194 | 195 | for ( j = 0; j < p_object->u.menu.i_choices; j++ ) 196 | { 197 | CHECK_MEMBER(&p_object->u.menu.ppsz_choices[j]); 198 | } 199 | break; 200 | 201 | default: 202 | break; 203 | } 204 | 205 | return 0; 206 | } 207 | -------------------------------------------------------------------------------- /dvblast.1: -------------------------------------------------------------------------------- 1 | .TH DVBLAST "1" "April 2012" "DVBlast 2.2" "User Commands" 2 | .SH NAME 3 | DVBlast \- Simple and powerful dvb streaming application 4 | .SH SYNOPSIS 5 | .B dvblast 6 | [\fI-q\fR] [\fI-c \fR] [\fI-r \fR] [\fI-t \fR] [\fI-o \fR] 7 | [\fI-i \fR] [\fI-a \fR] [\fI-n \fR] [\fI-y \fR] [\fI-S \fR] [\fI-k \fR] 8 | [\fI-f \fR] [\fI-D [:][[@][:]][/]\fR] [\fI-A \fR] 9 | [\fI-s \fR] [\fI-v <0|13|18>\fR] [\fI-p\fR] [\fI-b \fR] [\fI-I \fR] 10 | [\fI-F \fR] [\fI-m \fR] [\fI-R \fR] [\fI-P \fR] [\fI-K \fR] 11 | [\fI-G \fR] [\fI-H \fR] [\fI-X \fR] [\fI-O \fR] 12 | [\fI-u\fR] [\fI-w\fR] [\fI-U\fR] [\fI-L \fR] [\fI-E \fR] [\fI-d [<:port>][/]\fR] 13 | [\fI-z\fR] [\fI-C\fR] [\fI-e\fR] [\fI-M \fR] [\fI-N \fR] [\fI-T\fR] [\fI-j \fR] 14 | [\fI-W\fR] [\fI-Y\fR] [\fI-l\fR] [\fI-g \fR] [\fI-Z \fR] [\fI-V\fR] [\fI-h\fR] 15 | [\fI-0 pid_mapping\fR] [\fI-1 \fR] [\fI-2 \fR] [\fI-5 \fR] 16 | [\fI-J \fR] [\fI-B \fR] [\fI-Q \fR] [\fI-x \fR] 17 | .SH DESCRIPTION 18 | DVBlast is a simple and powerful streaming application based on the linux-dvb 19 | API. It opens a DVB device, tunes it, places PID filters, configures a CAM 20 | module, and demultiplexes the packets to several RTP outputs. 21 | 22 | DVBlast is designed to be the core of a custom IRD or CID, based on a PC with 23 | Linux-supported DVB cards. 24 | 25 | DVBlast does not do any kind of processing on the elementary streams, such as 26 | transcoding or remultiplexing. it does not stream from plain 27 | files, only DVB devices. If you were looking for these features, switch to VLC. 28 | .SH OPTIONS 29 | .PP 30 | .TP 31 | \fB\-a\fR, \fB\-\-adapter\fR 32 | Address of the adapter 33 | .TP 34 | \fB\-A\fR, \fB\-\-asi\-adapter\fR 35 | Read packets from an ASI adapter (0-n). If support for Deltacast ASI cards is 36 | compiled in, prefix the adapter number with "deltacast:" to select a Deltacast 37 | input. Deltacast inputs are numbered as (100 * card number) + channel number. 38 | .TP 39 | \fB\-b\fR, \fB\-\-bandwidth\fR 40 | Frontend bandwidth 41 | .TP 42 | \fB\-B\fR, \fB\-\-provider-name\fR 43 | Service provider name to declare in the SDT. If you want to change 44 | provider name per output use /srvprovider= output option in the config 45 | file. 46 | .TP 47 | \fB\-c\fR, \fB\-\-config\-file\fR 48 | Use the given configuration file 49 | .TP 50 | \fB\-C\fR, \fB\-\-dvb-compliance\fR 51 | Pass through or build the mandatory DVB tables 52 | .TP 53 | \fB\-d\fR, \fB\-\-duplicate\fR 54 | Duplicate all received packets to a given destination 55 | .TP 56 | \fB\-D\fR, \fB\-\-rtp\-input\fR 57 | Read packets from a multicast address instead of a DVB card 58 | .TP 59 | \fB\-W\fR, \fB\-\-emm\-passthrough\fR 60 | Enable EMM pass through (CA system data) 61 | .TP 62 | \fB\-Y\fR, \fB\-\-ecm\-passthrough\fR 63 | Enable ECM pass through (CA program data) 64 | .TP 65 | \fB\-e\fR, \fB\-\-epg\-passthrough\fR 66 | Enable EPG pass through (EIT data) 67 | .TP 68 | \fB\-E\fR, \fB\-\-retention\fR 69 | Maximum retention allowed between input and output (default: 40 ms) 70 | .TP 71 | \fB\-f\fR, \fB\-\-frequency\fR 72 | Frontend frequency. If '\-' is specified instead of a numeric value, 73 | the frontend will be not be tuned by dvblast and you should use external 74 | tuning tool (szap) to tune it. 75 | .TP 76 | \fB\-F\fR, \fB\-\-fec\-inner\fR 77 | Forward Error Correction used by satellite (FEC Inner) 78 | .br 79 | DVB-S2 0|12|23|34|35|56|78|89|910|999 (default auto: 999) 80 | .TP 81 | \fB\-G\fR, \fB\-\-guard\fR 82 | DVB-T guard interval 83 | .br 84 | DVB-T 32 (1/32)|16 (1/16)|8 (1/8)|4 (1/4)|-1 (auto, default) 85 | .TP 86 | \fB\-h\fR, \fB\-\-help\fR 87 | Print the help message 88 | .TP 89 | \fB\-H\fR, \fB\-\-hierarchy\fR 90 | DVB-T hierarchy (0, 1, 2, 4 or -1 auto, default) 91 | .TP 92 | \fB\-i\fR, \fB\-\-priority\fR 93 | Real time priority 94 | .TP 95 | \fB\-I\fR, \fB\-\-inversion\fR 96 | Inversion (-1 auto, 0 off, 1 on) 97 | .TP 98 | \fB\-j\fR, \fB\-\-system-charset\fR 99 | Character set used for printing messages (default UTF-8) 100 | .TP 101 | \fB\-J\fR, \fB\-\-dvb-charset\fR 102 | Character set used in output DVB tables (default ISO-8859-1) 103 | .TP 104 | \fB\-k\fR, \fB\-\-uncommitted\fR 105 | Port number for uncommitted diseqc (0: no uncommitted diseqc, 1\-4) 106 | .TP 107 | \fB\-K\fR, \fB\-\-fec-lp\fR 108 | DVB-T low priority FEC (default auto) 109 | .TP 110 | \fB\-1\fR, \fB\-\-delsys\fR 111 | Select delivery system. Possible values: DVBS|DVBS2|DVBC_ANNEX_A|DVBT|ATSC (default guessed) 112 | .TP 113 | \fB\-5\fR, \fB\-\-multistream\-id\fR 114 | Set stream ID for multistream capable transponders. Value: 0-255 (default: 0) 115 | .TP 116 | \fB\-l\fR, \fB\-\-logger\fR 117 | Send messages to syslog instead of stderr 118 | .TP 119 | \fB\-g\fR, \fB\-\-logger-ident\fR 120 | Set the program name that will appear in syslog (default: dvblast /the executable name/). 121 | .TP 122 | \fB\-L\fR, \fB\-\-latency\fR 123 | Maximum latency allowed between input and output (default: 100 ms) 124 | .TP 125 | \fB\-m\fR, \fB\-\-modulation\fR 126 | Modulation 127 | .br 128 | DVB-C qpsk|qam_16|qam_32|qam_64|qam_128|qam_256 (default qam_auto) 129 | .br 130 | DVB-T qam_16|qam_32|qam_64|qam_128|qam_256 (default qam_auto) 131 | .br 132 | DVB-S2 qpsk|psk_8 (default legacy DVB-S) 133 | .TP 134 | \fB\-M\fR, \fB\-\-network-name\fR 135 | DVB network name to declare in the NIT 136 | .TP 137 | \fB\-n\fR, \fB\-\-frontend\-number\fR 138 | The frontend number 139 | .TP 140 | \fB\-y\fR, \fB\-\-ca\-number\fR 141 | CA device number. Default: 0 142 | .TP 143 | \fB\-2\fR, \fB\-\-dvr\-buf\-size\fR 144 | Sets the size of the DVR TS buffer in bytes. 145 | .TP 146 | \fB\-N\fR, \fB\-\-network-id\fR 147 | DVB network ID to declare in the NIT 148 | .TP 149 | \fB\-o\fR, \fB\-\-rtp-output\fR 150 | RTP output IP 151 | .TP 152 | \fB\-O\fR, \fB\-\-lock-timeout\fR 153 | Timeout for the lock operation (in ms) 154 | .TP 155 | \fB\-p\fR, \fB\-\-force\-pulse\fR 156 | Force 22kHz pulses for high-band selection (DVB-S) 157 | .TP 158 | \fB\-P\fR, \fB\-\-pilot\fR 159 | DVB-S2 Pilot (-1 auto, 0 off, 1 on) 160 | .TP 161 | \fB\-q\fR, \fB\-\-quiet\fR 162 | Be quiet (less verbosity, repeat or use number for even quieter) 163 | .TP 164 | \fB\-Q\fR, \fB\-\-quit-timeout\fR 165 | When locked, quit after this delay (in ms), or after the first lock timeout 166 | .TP 167 | \fB\-r\fR, \fB\-\-remote\-socket\fR 168 | Remote socket to use 169 | .TP 170 | \fB\-R\fR, \fB\-\-rolloff\fR 171 | Rolloff value to use 172 | .br 173 | DVB-S2 35=0.35|25=0.25|20=0.20|0=AUTO (default: 35) 174 | .TP 175 | \fB\-s\fR, \fB\-\-symbol\-rate\fR 176 | Symbole rate 177 | .TP 178 | \fB\-S\fR, \fB\-\-diseqc\fR 179 | Satellite number for diseqc (0: no diseqc, 1\-4, A or B) 180 | .TP 181 | \fB\-t\fR, \fB\-\-ttl\fR 182 | Time-To-Live of the multicast stream 183 | .TP 184 | \fB\-T\fR, \fB\-\-unique\-ts\-id\fR 185 | Generate unique TS ID for each program 186 | .TP 187 | \fB\-u\fR, \fB\-\-budget\-mode\fR 188 | Turn on budget mode (no hardware PID filtering) 189 | .TP 190 | \fB\-U\fR, \fB\-\-udp\fR 191 | Use raw UDP rather than RTP (required by some IPTV set top boxes) 192 | .TP 193 | \fB\-v\fR, \fB\-\-voltage\fR <0|13|18> 194 | Voltage to apply to the LNB (QPSK) 195 | .TP 196 | \fB\-V\fR, \fB\-\-version\fR 197 | Only display the version 198 | .TP 199 | \fB\-w\fR, \fB\-\-select-pmts\fR 200 | Set a PID filter on all PMTs. This option is automatically enabled 201 | when config file is used. To disable setting PMT filters in case of 202 | config file is used, add \-\-select-pmts \fBafter\fR \-\-config\-file 203 | parameter. 204 | .TP 205 | \fB\-x\fR, \fB\-\-print\fR 206 | Print interesting events on stdout in a given format 207 | .TP 208 | \fB\-X\fR, \fB\-\-transmission\fR 209 | DVB-T transmission (2, 4, 8 or -1 auto, default 210 | .TP 211 | \fB\-z\fR, \fB\-\-any\-type\fR 212 | pass through all ESs from the PMT, of any type 213 | .TP 214 | \fB\-Z\fR, \fB\-\-mrtg-file\fR 215 | Every 10 seconds log statistics in . The file has 4 numbers in it 216 | and the format is: 217 | .TP 218 | \fB\-0\fR, \fB\-\-pidmap\fR 219 | Map the elementary stream pids to the values given for all elementary 220 | streams. Where there are multiple audio pids, then these will be mapped to 221 | audiopid, auiopid+1, audiopid +2 and so on. 222 | .SH SEE ALSO 223 | Read the README file for more information about the configuration of dvblast. 224 | .SH AUTHORS 225 | Writen by Marian Ďurkovič, Andy Gatward, Christophe Massiot and Jean-Paul Saman 226 | .SH LICENSE 227 | This program is free software; you can redistribute it and/or modify it under 228 | the terms of version 2 of the GNU General Public License as published by the 229 | Free Software Foundation. 230 | -------------------------------------------------------------------------------- /asi-deltacast.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * asi-deltacast.c: support for Deltacast ASI cards 3 | ***************************************************************************** 4 | * Copyright (C) 2004, 2009, 2015 VideoLAN 5 | * 6 | * Authors: Simon Lockhart 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 21 | *****************************************************************************/ 22 | #include "config.h" 23 | 24 | #ifdef HAVE_ASI_DELTACAST_SUPPORT 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | 45 | #include 46 | 47 | #include 48 | // #include 49 | 50 | #include "asi-deltacast.h" 51 | 52 | #include "dvblast.h" 53 | 54 | /***************************************************************************** 55 | * Local declarations 56 | *****************************************************************************/ 57 | #define ASI_DELTACAST_PERIOD 1000 /* ms */ 58 | #define ASI_DELTACAST_LOCK_TIMEOUT 5000000 /* 5 s */ 59 | 60 | static HANDLE h_board, h_channel; 61 | static struct ev_timer asi_watcher, mute_watcher; 62 | static bool b_sync = false; 63 | 64 | static UCHAR *p_asibuf = NULL; 65 | static ULONG i_asibuf_len; 66 | 67 | /***************************************************************************** 68 | * asi_deltacast_Open 69 | *****************************************************************************/ 70 | void asi_deltacast_Open( void ) 71 | { 72 | ASICHANNELCONFIG RXConfig; 73 | ULONG ApiVersion, DrvVersion, NbBoards; 74 | ASIBOARDINFOEX BoardInfoEx; 75 | BOOL res; 76 | 77 | /* Get API information */ 78 | res = Asi_GetApiInfo(&ApiVersion,&DrvVersion,&NbBoards); 79 | if (!res) 80 | { 81 | msg_Err( NULL, "couldn't get Deltacast API Info: 0x%08lX", 82 | (unsigned long) Dc_GetLastError(NULL) ); 83 | exit(EXIT_FAILURE); 84 | } 85 | 86 | msg_Dbg( NULL, "Deltacast StreamMaster DLL v%d.%d", 87 | (int)ApiVersion>>16, 88 | (int)ApiVersion&0xFFFF); 89 | msg_Dbg( NULL, "Deltacast Driver v%d.%d.%d", 90 | (DrvVersion >> 24) & 0xFF, 91 | (DrvVersion >> 16) & 0xFF, 92 | (DrvVersion >> 8) & 0xFF); 93 | msg_Dbg( NULL, "Deltacast Board Count: %d", NbBoards); 94 | 95 | /* Get the board information */ 96 | res = Asi_GetBoardInfoEx((int)(i_asi_adapter / 100), &BoardInfoEx); 97 | if (!res) 98 | { 99 | msg_Err( NULL, "couldn't get Deltacast board Info: 0x%08lX", 100 | (unsigned long) Dc_GetLastError(NULL) ); 101 | exit(EXIT_FAILURE); 102 | } 103 | 104 | msg_Dbg( NULL, "Deltacast Board FPGA v%08lX", 105 | (unsigned long)BoardInfoEx.BaseInformation.FPGAVersion); 106 | msg_Dbg( NULL, "Deltacast Board PLD v%08lX", 107 | (unsigned long)BoardInfoEx.BaseInformation.PLDVersion); 108 | msg_Dbg( NULL, "Deltacast Board PLX v%08lX", 109 | (unsigned long)BoardInfoEx.BaseInformation.PLXRevision); 110 | msg_Dbg( NULL, "Deltacast Board Serial %08X%08X", 111 | (ULONG)(BoardInfoEx.BaseInformation.SerialNb>>32), 112 | (ULONG)(BoardInfoEx.BaseInformation.SerialNb&0xFFFFFFFF)); 113 | msg_Dbg( NULL, "Deltacast Board Input Count: %d", BoardInfoEx.NbRxChannels_i); 114 | msg_Dbg( NULL, "Deltacast Board Output Count: %d", BoardInfoEx.NbTxChannels_i); 115 | 116 | /* Open the board */ 117 | h_board = Asi_SetupBoard((int)(i_asi_adapter / 100)); 118 | if (h_board == NULL) 119 | { 120 | msg_Err( NULL, "couldn't setup deltacast board %d: 0x%08lX", 121 | (int)(i_asi_adapter / 100), (unsigned long) Dc_GetLastError(NULL) ); 122 | exit(EXIT_FAILURE); 123 | } 124 | 125 | /* Open the channel on the board */ 126 | memset(&RXConfig,0,sizeof(ASICHANNELCONFIG)); 127 | RXConfig.DriverBufferSize = 188 * 2400; /* Use a driver buffer size of 2400 packets */ 128 | RXConfig.BoardBufferSize = 1048576; /* Use 1MB of onboard buffer */ 129 | RXConfig.TSPacketType = ASI_PKT_188; /* Use 188-bytes TS packets */ 130 | RXConfig.NbPIDFilter = 0; /* No PID filtering */ 131 | RXConfig.pPIDFilterTable = NULL; /* No PID filtering */ 132 | RXConfig.BitrateIntPeriod = ASI_INTPER_100; /* Integrate over 100 msec */ 133 | RXConfig.AllowedBRDeviation= 10000000; /* Allow 10Mbps of deviation */ 134 | RXConfig.RXTimeStamp = FALSE; /* No timestamping */ 135 | 136 | /* Try to open RX0 channel on the board 0 */ 137 | h_channel = Asi_OpenChannel(h_board, ASI_CHN_RX0 + (i_asi_adapter % 100), &RXConfig); 138 | if (h_channel == NULL) 139 | { 140 | msg_Err( NULL, "couldn't setup deltacast channel %d: 0x%08lX", 141 | (i_asi_adapter % 100), (unsigned long) Dc_GetLastError(NULL) ); 142 | exit(EXIT_FAILURE); 143 | } 144 | 145 | ev_timer_init(&asi_watcher, asi_deltacast_Read, 146 | ASI_DELTACAST_PERIOD / 1000000., 147 | ASI_DELTACAST_PERIOD / 1000000.); 148 | ev_timer_start(event_loop, &asi_watcher); 149 | 150 | ev_timer_init(&mute_watcher, asi_deltacast_MuteCb, 151 | ASI_DELTACAST_LOCK_TIMEOUT / 1000000., 152 | ASI_DELTACAST_LOCK_TIMEOUT / 1000000.); 153 | } 154 | 155 | /***************************************************************************** 156 | * ASI deltacast events 157 | *****************************************************************************/ 158 | static void asi_deltacast_Read(struct ev_loop *loop, struct ev_io *w, int revents) 159 | { 160 | BOOL res; 161 | block_t *p_ts, **pp_current = &p_ts; 162 | int i; 163 | ULONG Err; 164 | 165 | res = Asi_GetInputBuffer(h_channel, &p_asibuf, &i_asibuf_len, 166 | ASI_DELTACAST_PERIOD); 167 | if (!res) 168 | { 169 | Err = Dc_GetLastError(NULL) & ~DC_ERRORCODE_MASK; 170 | 171 | if (Err != DCERR_TIMEOUT) 172 | { 173 | msg_Warn( NULL, "asi_deltacast_Read(): GetInputBuffer failed: 0x%08X!", Err); 174 | } 175 | return; 176 | } 177 | 178 | if ( !b_sync ) 179 | { 180 | msg_Info( NULL, "frontend has acquired lock" ); 181 | switch (i_print_type) { 182 | case PRINT_XML: 183 | fprintf(print_fh, "\n"); 184 | break; 185 | case PRINT_TEXT: 186 | fprintf(print_fh, "lock status: 1\n"); 187 | break; 188 | default: 189 | break; 190 | } 191 | 192 | b_sync = true; 193 | } 194 | 195 | ev_timer_again(loop, &mute_watcher); 196 | 197 | for (i = 0; i < i_asibuf_len / TS_SIZE; i++) 198 | { 199 | *pp_current = block_New(); 200 | memcpy((*pp_current)->p_ts, p_asibuf + (i * TS_SIZE), TS_SIZE); 201 | pp_current = &(*pp_current)->p_next; 202 | 203 | } 204 | 205 | res = Asi_ReleaseInputBuffer(h_channel); 206 | 207 | // msg_Warn( NULL, "asi_deltacast_Read(): returning %d blocks", i_asibuf_len / TS_SIZE ); 208 | 209 | demux_Run( p_ts ); 210 | } 211 | 212 | static void asi_deltacast_MuteCb(struct ev_loop *loop, struct ev_timer *w, int revents) 213 | { 214 | msg_Warn( NULL, "frontend has lost lock" ); 215 | ev_timer_stop(loop, w); 216 | 217 | switch (i_print_type) { 218 | case PRINT_XML: 219 | fprintf(print_fh, "\n"); 220 | break; 221 | case PRINT_TEXT: 222 | fprintf(print_fh, "lock status: 0\n" ); 223 | break; 224 | default: 225 | break; 226 | } 227 | } 228 | 229 | /***************************************************************************** 230 | * asi_deltacast_SetFilter 231 | *****************************************************************************/ 232 | int asi_deltacast_SetFilter( uint16_t i_pid ) 233 | { 234 | /* TODO: Support PID filtering */ 235 | msg_Warn( NULL, "asi_deltacast_SetFilter(%d) not yet implemented", i_pid ); 236 | return -1; 237 | } 238 | 239 | /***************************************************************************** 240 | * asi_deltacast_UnsetFilter: normally never called 241 | *****************************************************************************/ 242 | void asi_deltacast_UnsetFilter( int i_fd, uint16_t i_pid ) 243 | { 244 | /* TODO: Support PID filtering */ 245 | msg_Warn( NULL, "asi_deltacast_UnsetFilter() not yet implemented" ); 246 | } 247 | 248 | /***************************************************************************** 249 | * asi_deltacast_Reset 250 | *****************************************************************************/ 251 | void asi_deltacast_Reset( void ) 252 | { 253 | /* Called when retune required, so nothing required */ 254 | msg_Warn( NULL, "asi_deltacast_Reset() do nothing" ); 255 | } 256 | 257 | #endif 258 | -------------------------------------------------------------------------------- /asi.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * asi.c: support for Computer Modules ASI cards 3 | ***************************************************************************** 4 | * Copyright (C) 2004, 2009, 2015 VideoLAN 5 | * 6 | * Authors: Christophe Massiot 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. 21 | *****************************************************************************/ 22 | #include "config.h" 23 | 24 | #ifdef HAVE_ASI_SUPPORT 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | 45 | #include 46 | 47 | #include "asi.h" 48 | 49 | #include "dvblast.h" 50 | 51 | /* 52 | * The problem with hardware filtering is that on startup, when you only 53 | * set a filter on PID 0, it can take a very long time for a large buffer 54 | * (typically ~100 TS packets) to fill up. And the buffer size cannot be 55 | * adjusted afer startup. --Meuuh 56 | */ 57 | //#define USE_HARDWARE_FILTERING 58 | 59 | /***************************************************************************** 60 | * Local declarations 61 | *****************************************************************************/ 62 | #define ASI_DEVICE "/dev/asirx%u" 63 | #define ASI_TIMESTAMPS_FILE "/sys/class/asi/asirx%u/timestamps" 64 | #define ASI_BUFSIZE_FILE "/sys/class/asi/asirx%u/bufsize" 65 | #define ASI_LOCK_TIMEOUT 5000000 /* 5 s */ 66 | 67 | static int i_handle; 68 | static struct ev_io asi_watcher; 69 | static struct ev_timer mute_watcher; 70 | static int i_bufsize; 71 | static uint8_t p_pid_filter[8192 / 8]; 72 | static bool b_sync = false; 73 | 74 | /***************************************************************************** 75 | * Local prototypes 76 | *****************************************************************************/ 77 | static void asi_Read(struct ev_loop *loop, struct ev_io *w, int revents); 78 | static void asi_MuteCb(struct ev_loop *loop, struct ev_timer *w, int revents); 79 | 80 | /***************************************************************************** 81 | * Local helpers 82 | *****************************************************************************/ 83 | #define MAXLEN 256 84 | 85 | static int ReadULSysfs( const char *psz_fmt, unsigned int i_link ) 86 | { 87 | char psz_file[MAXLEN], psz_data[MAXLEN]; 88 | char *psz_tmp; 89 | int i_fd; 90 | ssize_t i_ret; 91 | unsigned int i_data; 92 | 93 | snprintf( psz_file, sizeof(psz_file), psz_fmt, i_link ); 94 | psz_file[sizeof(psz_file) - 1] = '\0'; 95 | 96 | if ( (i_fd = open( psz_file, O_RDONLY )) < 0 ) 97 | return i_fd; 98 | 99 | i_ret = read( i_fd, psz_data, sizeof(psz_data) ); 100 | close( i_fd ); 101 | 102 | if ( i_ret < 0 ) 103 | return i_ret; 104 | 105 | i_data = strtoul( psz_data, &psz_tmp, 0 ); 106 | if ( *psz_tmp != '\n' ) 107 | return -1; 108 | 109 | return i_data; 110 | } 111 | 112 | static ssize_t WriteULSysfs( const char *psz_fmt, unsigned int i_link, 113 | unsigned int i_buf ) 114 | { 115 | char psz_file[MAXLEN], psz_data[MAXLEN]; 116 | int i_fd; 117 | ssize_t i_ret; 118 | 119 | snprintf( psz_file, sizeof(psz_file), psz_fmt, i_link ); 120 | psz_file[sizeof(psz_file) - 1] = '\0'; 121 | 122 | snprintf( psz_data, sizeof(psz_data), "%u\n", i_buf ); 123 | psz_file[sizeof(psz_data) - 1] = '\0'; 124 | 125 | if ( (i_fd = open( psz_file, O_WRONLY )) < 0 ) 126 | return i_fd; 127 | 128 | i_ret = write( i_fd, psz_data, strlen(psz_data) + 1 ); 129 | close( i_fd ); 130 | return i_ret; 131 | } 132 | 133 | /***************************************************************************** 134 | * asi_Open 135 | *****************************************************************************/ 136 | void asi_Open( void ) 137 | { 138 | char psz_dev[MAXLEN]; 139 | 140 | /* No timestamp - we wouldn't know what to do with them */ 141 | if ( WriteULSysfs( ASI_TIMESTAMPS_FILE, i_asi_adapter, 0 ) < 0 ) 142 | { 143 | msg_Err( NULL, "couldn't write file " ASI_TIMESTAMPS_FILE, 144 | i_asi_adapter ); 145 | exit(EXIT_FAILURE); 146 | } 147 | 148 | if ( (i_bufsize = ReadULSysfs( ASI_BUFSIZE_FILE, i_asi_adapter )) < 0 ) 149 | { 150 | msg_Err( NULL, "couldn't read file " ASI_BUFSIZE_FILE, i_asi_adapter ); 151 | exit(EXIT_FAILURE); 152 | } 153 | 154 | if ( i_bufsize % TS_SIZE ) 155 | { 156 | msg_Err( NULL, ASI_BUFSIZE_FILE " must be a multiple of 188", 157 | i_asi_adapter ); 158 | exit(EXIT_FAILURE); 159 | } 160 | 161 | snprintf( psz_dev, sizeof(psz_dev), ASI_DEVICE, i_asi_adapter ); 162 | psz_dev[sizeof(psz_dev) - 1] = '\0'; 163 | if ( (i_handle = open( psz_dev, O_RDONLY, 0 )) < 0 ) 164 | { 165 | msg_Err( NULL, "couldn't open device " ASI_DEVICE " (%s)", 166 | i_asi_adapter, strerror(errno) ); 167 | exit(EXIT_FAILURE); 168 | } 169 | 170 | #ifdef USE_HARDWARE_FILTERING 171 | memset( p_pid_filter, 0x0, sizeof(p_pid_filter) ); 172 | #else 173 | memset( p_pid_filter, 0xff, sizeof(p_pid_filter) ); 174 | #endif 175 | if ( ioctl( i_handle, ASI_IOC_RXSETPF, p_pid_filter ) < 0 ) 176 | { 177 | msg_Warn( NULL, "couldn't filter padding" ); 178 | } 179 | 180 | fsync( i_handle ); 181 | 182 | ev_io_init(&asi_watcher, asi_Read, i_handle, EV_READ); 183 | ev_io_start(event_loop, &asi_watcher); 184 | 185 | ev_timer_init(&mute_watcher, asi_MuteCb, 186 | ASI_LOCK_TIMEOUT / 1000000., ASI_LOCK_TIMEOUT / 1000000.); 187 | } 188 | 189 | /***************************************************************************** 190 | * ASI events 191 | *****************************************************************************/ 192 | static void asi_Read(struct ev_loop *loop, struct ev_io *w, int revents) 193 | { 194 | unsigned int i_val; 195 | 196 | if ( ioctl(i_handle, ASI_IOC_RXGETEVENTS, &i_val) == 0 ) 197 | { 198 | if ( i_val & ASI_EVENT_RX_BUFFER ) 199 | msg_Warn( NULL, "driver receive buffer queue overrun" ); 200 | if ( i_val & ASI_EVENT_RX_FIFO ) 201 | msg_Warn( NULL, "onboard receive FIFO overrun" ); 202 | if ( i_val & ASI_EVENT_RX_CARRIER ) 203 | msg_Warn( NULL, "carrier status change" ); 204 | if ( i_val & ASI_EVENT_RX_LOS ) 205 | msg_Warn( NULL, "loss of packet synchronization" ); 206 | if ( i_val & ASI_EVENT_RX_AOS ) 207 | msg_Warn( NULL, "acquisition of packet synchronization" ); 208 | if ( i_val & ASI_EVENT_RX_DATA ) 209 | msg_Warn( NULL, "receive data status change" ); 210 | } 211 | 212 | struct iovec p_iov[i_bufsize / TS_SIZE]; 213 | block_t *p_ts, **pp_current = &p_ts; 214 | int i, i_len; 215 | 216 | for ( i = 0; i < i_bufsize / TS_SIZE; i++ ) 217 | { 218 | *pp_current = block_New(); 219 | p_iov[i].iov_base = (*pp_current)->p_ts; 220 | p_iov[i].iov_len = TS_SIZE; 221 | pp_current = &(*pp_current)->p_next; 222 | } 223 | 224 | if ( (i_len = readv(i_handle, p_iov, i_bufsize / TS_SIZE)) < 0 ) 225 | { 226 | msg_Err( NULL, "couldn't read from device " ASI_DEVICE " (%s)", 227 | i_asi_adapter, strerror(errno) ); 228 | i_len = 0; 229 | } 230 | i_len /= TS_SIZE; 231 | 232 | if ( i_len ) 233 | { 234 | if ( !b_sync ) 235 | { 236 | msg_Info( NULL, "frontend has acquired lock" ); 237 | switch (i_print_type) { 238 | case PRINT_XML: 239 | fprintf(print_fh, "\n"); 240 | break; 241 | case PRINT_TEXT: 242 | fprintf(print_fh, "lock status: 1\n"); 243 | break; 244 | default: 245 | break; 246 | } 247 | 248 | b_sync = true; 249 | } 250 | 251 | ev_timer_again(loop, &mute_watcher); 252 | } 253 | 254 | pp_current = &p_ts; 255 | while ( i_len && *pp_current ) 256 | { 257 | pp_current = &(*pp_current)->p_next; 258 | i_len--; 259 | } 260 | 261 | if ( *pp_current ) 262 | msg_Dbg( NULL, "partial buffer received" ); 263 | block_DeleteChain( *pp_current ); 264 | *pp_current = NULL; 265 | 266 | demux_Run( p_ts ); 267 | } 268 | 269 | static void asi_MuteCb(struct ev_loop *loop, struct ev_timer *w, int revents) 270 | { 271 | msg_Warn( NULL, "frontend has lost lock" ); 272 | ev_timer_stop(loop, w); 273 | 274 | switch (i_print_type) { 275 | case PRINT_XML: 276 | fprintf(print_fh, "\n"); 277 | break; 278 | case PRINT_TEXT: 279 | fprintf(print_fh, "lock status: 0\n" ); 280 | break; 281 | default: 282 | break; 283 | } 284 | } 285 | 286 | /***************************************************************************** 287 | * asi_SetFilter 288 | *****************************************************************************/ 289 | int asi_SetFilter( uint16_t i_pid ) 290 | { 291 | #ifdef USE_HARDWARE_FILTERING 292 | p_pid_filter[ i_pid / 8 ] |= (0x01 << (i_pid % 8)); 293 | if ( ioctl( i_handle, ASI_IOC_RXSETPF, p_pid_filter ) < 0 ) 294 | msg_Warn( NULL, "couldn't add filter on PID %u", i_pid ); 295 | 296 | return 1; 297 | #else 298 | return -1; 299 | #endif 300 | } 301 | 302 | /***************************************************************************** 303 | * asi_UnsetFilter: normally never called 304 | *****************************************************************************/ 305 | void asi_UnsetFilter( int i_fd, uint16_t i_pid ) 306 | { 307 | #ifdef USE_HARDWARE_FILTERING 308 | p_pid_filter[ i_pid / 8 ] &= ~(0x01 << (i_pid % 8)); 309 | if ( ioctl( i_handle, ASI_IOC_RXSETPF, p_pid_filter ) < 0 ) 310 | msg_Warn( NULL, "couldn't remove filter on PID %u", i_pid ); 311 | #endif 312 | } 313 | 314 | /***************************************************************************** 315 | * asi_Reset 316 | *****************************************************************************/ 317 | void asi_Reset( void ) 318 | { 319 | msg_Warn( NULL, "asi_Reset() do nothing" ); 320 | } 321 | 322 | #endif 323 | -------------------------------------------------------------------------------- /comm.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * comm.c: Handles the communication socket 3 | ***************************************************************************** 4 | * Copyright (C) 2008, 2015 VideoLAN 5 | * 6 | * Authors: Christophe Massiot 7 | * 8 | * This program is free software. It comes without any warranty, to 9 | * the extent permitted by applicable law. You can redistribute it 10 | * and/or modify it under the terms of the Do What The Fuck You Want 11 | * To Public License, Version 2, as published by Sam Hocevar. See 12 | * http://sam.zoy.org/wtfpl/COPYING for more details. 13 | *****************************************************************************/ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "dvblast.h" 32 | #include "en50221.h" 33 | #include "comm.h" 34 | 35 | /***************************************************************************** 36 | * Local declarations 37 | *****************************************************************************/ 38 | static int i_comm_fd = -1; 39 | static struct ev_io comm_watcher; 40 | 41 | /***************************************************************************** 42 | * Local prototypes 43 | *****************************************************************************/ 44 | static void comm_Read(struct ev_loop *loop, struct ev_io *w, int revents); 45 | 46 | /***************************************************************************** 47 | * comm_Open 48 | *****************************************************************************/ 49 | void comm_Open( void ) 50 | { 51 | int i_size = COMM_MAX_MSG_CHUNK; 52 | struct sockaddr_un sun_server; 53 | 54 | unlink( psz_srv_socket ); 55 | 56 | if ( (i_comm_fd = socket( AF_UNIX, SOCK_DGRAM, 0 )) == -1 ) 57 | { 58 | msg_Err( NULL, "cannot create comm socket (%s)", strerror(errno) ); 59 | return; 60 | } 61 | 62 | setsockopt( i_comm_fd, SOL_SOCKET, SO_RCVBUF, &i_size, sizeof(i_size) ); 63 | 64 | memset( &sun_server, 0, sizeof(sun_server) ); 65 | sun_server.sun_family = AF_UNIX; 66 | strncpy( sun_server.sun_path, psz_srv_socket, sizeof(sun_server.sun_path) ); 67 | sun_server.sun_path[sizeof(sun_server.sun_path) - 1] = '\0'; 68 | 69 | if ( bind( i_comm_fd, (struct sockaddr *)&sun_server, 70 | SUN_LEN(&sun_server) ) < 0 ) 71 | { 72 | msg_Err( NULL, "cannot bind comm socket (%s)", strerror(errno) ); 73 | close( i_comm_fd ); 74 | i_comm_fd = -1; 75 | return; 76 | } 77 | 78 | ev_io_init(&comm_watcher, comm_Read, i_comm_fd, EV_READ); 79 | ev_io_start(event_loop, &comm_watcher); 80 | } 81 | 82 | /***************************************************************************** 83 | * comm_Read 84 | *****************************************************************************/ 85 | static void comm_Read(struct ev_loop *loop, struct ev_io *w, int revents) 86 | { 87 | struct sockaddr_un sun_client; 88 | socklen_t sun_length = sizeof(sun_client); 89 | ssize_t i_size, i_answer_size = 0; 90 | uint8_t p_buffer[COMM_BUFFER_SIZE], p_answer[COMM_BUFFER_SIZE]; 91 | uint8_t i_command, i_answer; 92 | uint8_t *p_packed_section; 93 | unsigned int i_packed_section_size; 94 | uint8_t *p_input = p_buffer + COMM_HEADER_SIZE; 95 | uint8_t *p_output = p_answer + COMM_HEADER_SIZE; 96 | 97 | i_size = recvfrom( i_comm_fd, p_buffer, COMM_BUFFER_SIZE, 0, 98 | (struct sockaddr *)&sun_client, &sun_length ); 99 | if ( i_size < COMM_HEADER_SIZE ) 100 | { 101 | msg_Err( NULL, "cannot read comm socket (%zd:%s)\n", i_size, 102 | strerror(errno) ); 103 | return; 104 | } 105 | if ( sun_length == 0 || sun_length > sizeof(sun_client) ) 106 | { 107 | msg_Err( NULL, "anonymous packet from comm socket\n" ); 108 | return; 109 | } 110 | 111 | if ( p_buffer[0] != COMM_HEADER_MAGIC ) 112 | { 113 | msg_Err( NULL, "wrong protocol version 0x%x", p_buffer[0] ); 114 | return; 115 | } 116 | 117 | i_command = p_buffer[1]; 118 | 119 | if ( i_frequency == 0 ) /* ASI or UDP, disable DVB only commands */ 120 | { 121 | switch ( i_command ) 122 | { 123 | case CMD_FRONTEND_STATUS: 124 | case CMD_MMI_STATUS: 125 | case CMD_MMI_SLOT_STATUS: 126 | case CMD_MMI_OPEN: 127 | case CMD_MMI_CLOSE: 128 | case CMD_MMI_RECV: 129 | case CMD_MMI_SEND_TEXT: 130 | case CMD_MMI_SEND_CHOICE: 131 | i_answer = RET_NODATA; 132 | i_answer_size = 0; 133 | goto return_answer; 134 | } 135 | } 136 | 137 | switch ( i_command ) 138 | { 139 | case CMD_RELOAD: 140 | config_ReadFile(); 141 | i_answer = RET_OK; 142 | i_answer_size = 0; 143 | break; 144 | 145 | #ifdef HAVE_DVB_SUPPORT 146 | case CMD_FRONTEND_STATUS: 147 | i_answer = dvb_FrontendStatus( p_answer + COMM_HEADER_SIZE, 148 | &i_answer_size ); 149 | break; 150 | 151 | case CMD_MMI_STATUS: 152 | i_answer = en50221_StatusMMI( p_answer + COMM_HEADER_SIZE, 153 | &i_answer_size ); 154 | break; 155 | 156 | case CMD_MMI_SLOT_STATUS: 157 | i_answer = en50221_StatusMMISlot( p_input, i_size - COMM_HEADER_SIZE, 158 | p_answer + COMM_HEADER_SIZE, 159 | &i_answer_size ); 160 | break; 161 | 162 | case CMD_MMI_OPEN: 163 | i_answer = en50221_OpenMMI( p_input, i_size - COMM_HEADER_SIZE ); 164 | break; 165 | 166 | case CMD_MMI_CLOSE: 167 | i_answer = en50221_CloseMMI( p_input, i_size - COMM_HEADER_SIZE ); 168 | break; 169 | 170 | case CMD_MMI_RECV: 171 | i_answer = en50221_GetMMIObject( p_input, i_size - COMM_HEADER_SIZE, 172 | p_answer + COMM_HEADER_SIZE, 173 | &i_answer_size ); 174 | break; 175 | 176 | case CMD_MMI_SEND_TEXT: 177 | case CMD_MMI_SEND_CHOICE: 178 | i_answer = en50221_SendMMIObject( p_input, i_size - COMM_HEADER_SIZE ); 179 | break; 180 | #endif 181 | 182 | case CMD_SHUTDOWN: 183 | ev_break(loop, EVBREAK_ALL); 184 | i_answer = RET_OK; 185 | i_answer_size = 0; 186 | break; 187 | 188 | case CMD_GET_PAT: 189 | case CMD_GET_CAT: 190 | case CMD_GET_NIT: 191 | case CMD_GET_SDT: 192 | { 193 | #define CASE_TABLE(x) \ 194 | case CMD_GET_##x: \ 195 | { \ 196 | i_answer = RET_##x; \ 197 | p_packed_section = demux_get_current_packed_##x(&i_packed_section_size); \ 198 | break; \ 199 | } 200 | switch ( i_command ) 201 | { 202 | CASE_TABLE(PAT) 203 | CASE_TABLE(CAT) 204 | CASE_TABLE(NIT) 205 | CASE_TABLE(SDT) 206 | } 207 | #undef CASE_TABLE 208 | 209 | if ( p_packed_section && i_packed_section_size ) 210 | { 211 | if ( i_packed_section_size <= COMM_BUFFER_SIZE - COMM_HEADER_SIZE ) 212 | { 213 | i_answer_size = i_packed_section_size; 214 | memcpy( p_answer + COMM_HEADER_SIZE, p_packed_section, i_packed_section_size ); 215 | } else { 216 | msg_Err( NULL, "section size is too big (%u)\n", i_packed_section_size ); 217 | i_answer = RET_NODATA; 218 | } 219 | free( p_packed_section ); 220 | } else { 221 | i_answer = RET_NODATA; 222 | } 223 | 224 | break; 225 | } 226 | 227 | case CMD_GET_PMT: 228 | { 229 | if ( i_size < COMM_HEADER_SIZE + 2 ) 230 | { 231 | msg_Err( NULL, "command packet is too short (%zd)\n", i_size ); 232 | return; 233 | } 234 | 235 | uint16_t i_sid = (uint16_t)((p_input[0] << 8) | p_input[1]); 236 | p_packed_section = demux_get_packed_PMT(i_sid, &i_packed_section_size); 237 | 238 | if ( p_packed_section && i_packed_section_size ) 239 | { 240 | i_answer = RET_PMT; 241 | i_answer_size = i_packed_section_size; 242 | memcpy( p_answer + COMM_HEADER_SIZE, p_packed_section, i_packed_section_size ); 243 | free( p_packed_section ); 244 | } else { 245 | i_answer = RET_NODATA; 246 | } 247 | 248 | break; 249 | } 250 | 251 | case CMD_GET_PIDS: 252 | { 253 | i_answer = RET_PIDS; 254 | i_answer_size = sizeof(struct cmd_pid_info); 255 | demux_get_PIDS_info( p_output ); 256 | break; 257 | } 258 | 259 | case CMD_GET_PID: 260 | { 261 | if ( i_size < COMM_HEADER_SIZE + 2 ) 262 | { 263 | msg_Err( NULL, "command packet is too short (%zd)\n", i_size ); 264 | return; 265 | } 266 | 267 | uint16_t i_pid = (uint16_t)((p_input[0] << 8) | p_input[1]); 268 | if ( i_pid >= MAX_PIDS ) { 269 | i_answer = RET_NODATA; 270 | } else { 271 | i_answer = RET_PID; 272 | i_answer_size = sizeof(ts_pid_info_t); 273 | demux_get_PID_info( i_pid, p_output ); 274 | } 275 | break; 276 | } 277 | 278 | default: 279 | msg_Err( NULL, "wrong command %u", i_command ); 280 | i_answer = RET_HUH; 281 | i_answer_size = 0; 282 | break; 283 | } 284 | 285 | return_answer: 286 | p_answer[0] = COMM_HEADER_MAGIC; 287 | p_answer[1] = i_answer; 288 | p_answer[2] = 0; 289 | p_answer[3] = 0; 290 | uint32_t *p_size = (uint32_t *)&p_answer[4]; 291 | *p_size = i_answer_size + COMM_HEADER_SIZE; 292 | 293 | /* msg_Dbg( NULL, "answering %d to %d with size %zd", i_answer, i_command, 294 | i_answer_size ); */ 295 | 296 | #define min(a, b) (a < b ? a : b) 297 | ssize_t i_sended = 0; 298 | ssize_t i_to_send = i_answer_size + COMM_HEADER_SIZE; 299 | do { 300 | ssize_t i_sent = sendto( i_comm_fd, p_answer + i_sended, 301 | min(i_to_send, COMM_MAX_MSG_CHUNK), 0, 302 | (struct sockaddr *)&sun_client, sun_length ); 303 | 304 | if ( i_sent < 0 ) { 305 | msg_Err( NULL, "cannot send comm socket (%s)", strerror(errno) ); 306 | break; 307 | } 308 | 309 | i_sended += i_sent; 310 | i_to_send -= i_sent; 311 | } while ( i_to_send > 0 ); 312 | #undef min 313 | } 314 | 315 | /***************************************************************************** 316 | * comm_Close 317 | *****************************************************************************/ 318 | void comm_Close( void ) 319 | { 320 | if (i_comm_fd > -1) 321 | { 322 | ev_io_stop(event_loop, &comm_watcher); 323 | close(i_comm_fd); 324 | unlink(psz_srv_socket); 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /asi.h: -------------------------------------------------------------------------------- 1 | /* asi.h 2 | * 3 | * Shared header file for the Linux user-space API for 4 | * Linear Systems Ltd. DVB Master ASI interface boards. 5 | * 6 | * Copyright (C) 1999 Tony Bolger 7 | * Copyright (C) 2000-2010 Linear Systems Ltd. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * 3. Neither the name of Linear Systems Ltd. nor the names of its 20 | * contributors may be used to endorse or promote products derived from 21 | * this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY LINEAR SYSTEMS LTD. "AS IS" AND ANY 24 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL LINEAR SYSTEMS LTD. OR CONTRIBUTORS 27 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 28 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 33 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | * Linear Systems can be contacted at . 36 | * 37 | */ 38 | 39 | #ifndef _ASI_H 40 | #define _ASI_H 41 | 42 | /* Driver info */ 43 | #define ASI_DRIVER_NAME "asi" 44 | 45 | #define ASI_MAJOR 61 /* Set to 0 for dynamic allocation. 46 | * Otherwise, 61 is available. 47 | * See /usr/src/linux/Documentation/devices.txt */ 48 | 49 | #define ASI_TX_BUFFERS_MIN 2 /* This must be at least 2 */ 50 | /* The minimum transmit buffer size must be positive, divisible by 8, 51 | * and large enough that the buffers aren't transferred to the onboard FIFOs 52 | * too quickly for the machine to handle the interrupts. 53 | * This is especially a problem at startup, when the FIFOs are empty. 54 | * Relevant factors include onboard FIFO size, PCI bus throughput, 55 | * processor speed, and interrupt latency. */ 56 | #define ASI_TX_BUFSIZE_MIN 1024 57 | #define ASI_RX_BUFFERS_MIN 2 /* This must be at least 2 */ 58 | #define ASI_RX_BUFSIZE_MIN 8 /* This must be positive and divisible by 8 */ 59 | 60 | #define ASI_TX_BUFFERS 54 /* This must be at least 2 */ 61 | #define ASI_TX_BUFSIZE 38352 /* This must be positive and divisible by 8 */ 62 | #define ASI_RX_BUFFERS 54 /* This must be at least 2 */ 63 | #define ASI_RX_BUFSIZE 38352 /* This must be positive and divisible by 8 */ 64 | 65 | /* Ioctl () definitions */ 66 | #define ASI_IOC_MAGIC '?' /* This ioctl magic number is currently free. See 67 | * /usr/src/linux/Documentation/ioctl-number.txt */ 68 | 69 | #define ASI_IOC_TXGETCAP _IOR(ASI_IOC_MAGIC, 1, unsigned int) 70 | #define ASI_IOC_TXGETEVENTS _IOR(ASI_IOC_MAGIC, 2, unsigned int) 71 | #define ASI_IOC_TXGETBUFLEVEL _IOR(ASI_IOC_MAGIC, 3, unsigned int) 72 | #define ASI_IOC_TXSETSTUFFING _IOW(ASI_IOC_MAGIC, 4, struct asi_txstuffing) 73 | #define ASI_IOC_TXGETBYTECOUNT _IOR(ASI_IOC_MAGIC, 5, unsigned int) 74 | /* #define ASI_IOC_TXGETFIFO _IOR(ASI_IOC_MAGIC, 6, int) */ 75 | #define ASI_IOC_TXGETTXD _IOR(ASI_IOC_MAGIC, 7, int) 76 | #define ASI_IOC_TXGET27COUNT _IOR(ASI_IOC_MAGIC, 8, unsigned int) 77 | /* Provide compatibility with applications compiled for older API */ 78 | #define ASI_IOC_TXSETPID_DEPRECATED _IOR(ASI_IOC_MAGIC, 9, unsigned int) 79 | #define ASI_IOC_TXSETPID _IOW(ASI_IOC_MAGIC, 9, unsigned int) 80 | #define ASI_IOC_TXGETPCRSTAMP _IOR(ASI_IOC_MAGIC, 10, struct asi_pcrstamp) 81 | /* Provide compatibility with applications compiled for older API */ 82 | #define ASI_IOC_TXCHANGENEXTIP_DEPRECATED _IOR(ASI_IOC_MAGIC, 11, int) 83 | #define ASI_IOC_TXCHANGENEXTIP _IOW(ASI_IOC_MAGIC, 11, int) 84 | 85 | #define ASI_IOC_RXGETCAP _IOR(ASI_IOC_MAGIC, 65, unsigned int) 86 | #define ASI_IOC_RXGETEVENTS _IOR(ASI_IOC_MAGIC, 66, unsigned int) 87 | #define ASI_IOC_RXGETBUFLEVEL _IOR(ASI_IOC_MAGIC, 67, unsigned int) 88 | /* #define ASI_IOC_RXSETREFRAME _IOW(ASI_IOC_MAGIC, 68, int) */ 89 | #define ASI_IOC_RXGETSTATUS _IOR(ASI_IOC_MAGIC, 69, int) 90 | #define ASI_IOC_RXGETBYTECOUNT _IOR(ASI_IOC_MAGIC, 70, unsigned int) 91 | /* #define ASI_IOC_RXGETFIFO _IOR(ASI_IOC_MAGIC, 71, int) */ 92 | #define ASI_IOC_RXSETINVSYNC _IOW(ASI_IOC_MAGIC, 72, int) 93 | #define ASI_IOC_RXGETCARRIER _IOR(ASI_IOC_MAGIC, 73, int) 94 | #define ASI_IOC_RXSETDSYNC _IOW(ASI_IOC_MAGIC, 74, int) 95 | #define ASI_IOC_RXGETRXD _IOR(ASI_IOC_MAGIC, 75, int) 96 | #define ASI_IOC_RXSETPF _IOW(ASI_IOC_MAGIC, 76, unsigned int [256]) 97 | /* #define ASI_IOC_RXSETPFE _IOW(ASI_IOC_MAGIC, 77, int) */ 98 | #define ASI_IOC_RXSETPID0 _IOW(ASI_IOC_MAGIC, 78, int) 99 | #define ASI_IOC_RXGETPID0COUNT _IOR(ASI_IOC_MAGIC, 79, unsigned int) 100 | #define ASI_IOC_RXSETPID1 _IOW(ASI_IOC_MAGIC, 80, int) 101 | #define ASI_IOC_RXGETPID1COUNT _IOR(ASI_IOC_MAGIC, 81, unsigned int) 102 | #define ASI_IOC_RXSETPID2 _IOW(ASI_IOC_MAGIC, 82, int) 103 | #define ASI_IOC_RXGETPID2COUNT _IOR(ASI_IOC_MAGIC, 83, unsigned int) 104 | #define ASI_IOC_RXSETPID3 _IOW(ASI_IOC_MAGIC, 84, int) 105 | #define ASI_IOC_RXGETPID3COUNT _IOR(ASI_IOC_MAGIC, 85, unsigned int) 106 | /* #define ASI_IOC_RXGETSTAMP _IOR(ASI_IOC_MAGIC, 86, unsigned int) */ 107 | #define ASI_IOC_RXGET27COUNT _IOR(ASI_IOC_MAGIC, 87, unsigned int) 108 | #define ASI_IOC_RXGETSTATUS2 _IOR(ASI_IOC_MAGIC, 88, int) 109 | /* Provide compatibility with applications compiled for older API */ 110 | #define ASI_IOC_RXSETINPUT_DEPRECATED _IOR(ASI_IOC_MAGIC, 89, int) 111 | #define ASI_IOC_RXSETINPUT _IOW(ASI_IOC_MAGIC, 89, int) 112 | #define ASI_IOC_RXGETRXD2 _IOR(ASI_IOC_MAGIC, 90, int) 113 | 114 | #define ASI_IOC_GETID _IOR(ASI_IOC_MAGIC, 129, unsigned int) 115 | #define ASI_IOC_GETVERSION _IOR(ASI_IOC_MAGIC, 130, unsigned int) 116 | 117 | /* Transmitter event flag bit locations */ 118 | #define ASI_EVENT_TX_BUFFER_ORDER 0 119 | #define ASI_EVENT_TX_BUFFER (1 << ASI_EVENT_TX_BUFFER_ORDER) 120 | #define ASI_EVENT_TX_FIFO_ORDER 1 121 | #define ASI_EVENT_TX_FIFO (1 << ASI_EVENT_TX_FIFO_ORDER) 122 | #define ASI_EVENT_TX_DATA_ORDER 2 123 | #define ASI_EVENT_TX_DATA (1 << ASI_EVENT_TX_DATA_ORDER) 124 | 125 | /* Receiver event flag bit locations */ 126 | #define ASI_EVENT_RX_BUFFER_ORDER 0 127 | #define ASI_EVENT_RX_BUFFER (1 << ASI_EVENT_RX_BUFFER_ORDER) 128 | #define ASI_EVENT_RX_FIFO_ORDER 1 129 | #define ASI_EVENT_RX_FIFO (1 << ASI_EVENT_RX_FIFO_ORDER) 130 | #define ASI_EVENT_RX_CARRIER_ORDER 2 131 | #define ASI_EVENT_RX_CARRIER (1 << ASI_EVENT_RX_CARRIER_ORDER) 132 | #define ASI_EVENT_RX_AOS_ORDER 3 133 | #define ASI_EVENT_RX_AOS (1 << ASI_EVENT_RX_AOS_ORDER) 134 | #define ASI_EVENT_RX_LOS_ORDER 4 135 | #define ASI_EVENT_RX_LOS (1 << ASI_EVENT_RX_LOS_ORDER) 136 | #define ASI_EVENT_RX_DATA_ORDER 5 137 | #define ASI_EVENT_RX_DATA (1 << ASI_EVENT_RX_DATA_ORDER) 138 | 139 | /** 140 | * asi_txstuffing - Transmitter stuffing parameters 141 | * @ib: interbyte stuffing 142 | * @ip: interpacket stuffing 143 | * @normal_ip: FT0 144 | * @big_ip: FT1 145 | * @il_normal: IL0 146 | * @il_big: IL1 147 | **/ 148 | struct asi_txstuffing { 149 | /* Number of K28.5 characters to insert between packet bytes */ 150 | unsigned int ib; 151 | 152 | /* Base number of K28.5 characters to insert between packets, 153 | * not including the two required by ASI */ 154 | unsigned int ip; 155 | 156 | /* Number of packets with (ip) bytes of interpacket stuffing 157 | * per finetuning cycle */ 158 | unsigned int normal_ip; 159 | 160 | /* Number of packets with (ip + 1) bytes of interpacket stuffing 161 | * per finetuning cycle */ 162 | unsigned int big_ip; 163 | 164 | /* Number of packets with (ip) bytes of interpacket stuffing 165 | * per interleaved finetuning cycle */ 166 | unsigned int il_normal; 167 | 168 | /* Number of packets with (ip + 1) bytes of interpacket stuffing 169 | * per interleaved finetuning cycle */ 170 | unsigned int il_big; 171 | }; 172 | 173 | /** 174 | * asi_pcrstamp - PCR - departure time pair 175 | * @adaptation_field_length: adaptation field length 176 | * @adaptation_field_flags: adaptation field flags 177 | * @PCR: a program clock reference 178 | * @count: departure time of this PCR, in 1 / 27 MHz 179 | **/ 180 | struct asi_pcrstamp { 181 | unsigned char adaptation_field_length; 182 | unsigned char adaptation_field_flags; 183 | unsigned char PCR[6]; 184 | long long int count; 185 | }; 186 | 187 | /* Interface capabilities */ 188 | #define ASI_CAP_TX_MAKE204 0x00000004 189 | #define ASI_CAP_TX_FINETUNING 0x00000008 190 | #define ASI_CAP_TX_BYTECOUNTER 0x00000010 191 | #define ASI_CAP_TX_SETCLKSRC 0x00000020 192 | #define ASI_CAP_TX_FIFOUNDERRUN 0x00000040 193 | #define ASI_CAP_TX_LARGEIB 0x00000080 194 | #define ASI_CAP_TX_INTERLEAVING 0x00000100 195 | #define ASI_CAP_TX_DATA 0x00000200 196 | #define ASI_CAP_TX_RXCLKSRC 0x00000400 197 | /* #define ASI_CAP_TX_COMPOSITEREF 0x00000800 */ 198 | #define ASI_CAP_TX_PCRSTAMP 0x00001000 199 | #define ASI_CAP_TX_CHANGENEXTIP 0x00002000 200 | #define ASI_CAP_TX_27COUNTER 0x00004000 201 | #define ASI_CAP_TX_BYTESOR27 0x00008000 202 | #define ASI_CAP_TX_TIMESTAMPS 0x00010000 203 | #define ASI_CAP_TX_PTIMESTAMPS 0x00020000 204 | #define ASI_CAP_TX_NULLPACKETS 0x00040000 205 | #define ASI_CAP_TX_EXTCLKSRC2 0x00080000 206 | 207 | #define ASI_CAP_RX_SYNC 0x00000004 208 | #define ASI_CAP_RX_MAKE188 0x00000008 209 | #define ASI_CAP_RX_BYTECOUNTER 0x00000010 210 | /* #define ASI_CAP_RX_FIFOSTATUS 0x00000020 */ 211 | #define ASI_CAP_RX_INVSYNC 0x00000040 212 | #define ASI_CAP_RX_CD 0x00000080 213 | #define ASI_CAP_RX_DSYNC 0x00000100 214 | #define ASI_CAP_RX_DATA 0x00000200 215 | #define ASI_CAP_RX_PIDFILTER 0x00000400 216 | #define ASI_CAP_RX_PIDCOUNTER 0x00000800 217 | #define ASI_CAP_RX_4PIDCOUNTER 0x00001000 218 | #define ASI_CAP_RX_FORCEDMA 0x00002000 219 | #define ASI_CAP_RX_27COUNTER 0x00004000 220 | #define ASI_CAP_RX_BYTESOR27 0x00008000 221 | #define ASI_CAP_RX_TIMESTAMPS 0x00010000 222 | #define ASI_CAP_RX_PTIMESTAMPS 0x00020000 223 | #define ASI_CAP_RX_NULLPACKETS 0x00040000 224 | #define ASI_CAP_RX_REDUNDANT 0x00080000 225 | #define ASI_CAP_RX_DATA2 0x00100000 226 | 227 | /* Transmitter clock source settings */ 228 | #define ASI_CTL_TX_CLKSRC_ONBOARD 0 229 | #define ASI_CTL_TX_CLKSRC_EXT 1 230 | #define ASI_CTL_TX_CLKSRC_RX 2 231 | #define ASI_CTL_TX_CLKSRC_EXT2 3 232 | 233 | /* Transmitter mode settings */ 234 | #define ASI_CTL_TX_MODE_188 0 235 | #define ASI_CTL_TX_MODE_204 1 236 | #define ASI_CTL_TX_MODE_MAKE204 2 237 | 238 | /* Receiver mode settings */ 239 | #define ASI_CTL_RX_MODE_RAW 0 240 | #define ASI_CTL_RX_MODE_188 1 241 | #define ASI_CTL_RX_MODE_204 2 242 | #define ASI_CTL_RX_MODE_AUTO 3 243 | #define ASI_CTL_RX_MODE_AUTOMAKE188 4 244 | #define ASI_CTL_RX_MODE_204MAKE188 5 245 | 246 | /* Timestamping settings */ 247 | #define ASI_CTL_TSTAMP_NONE 0 248 | #define ASI_CTL_TSTAMP_APPEND 1 249 | #define ASI_CTL_TSTAMP_PREPEND 2 250 | 251 | /* Transport settings */ 252 | #define ASI_CTL_TRANSPORT_DVB_ASI 0 253 | #define ASI_CTL_TRANSPORT_SMPTE_310M 1 254 | 255 | #endif 256 | 257 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | Welcome to DVBlast! 3 | =================== 4 | 5 | DVBlast is a simple and powerful MPEG-2/TS demux and streaming 6 | application with several input methods: 7 | - linux-dvb-supported cards (DVB-S, DVB-S2, DVB-C, DVB-T...) 8 | - DVB-ASI cards 9 | - UDP or RTP stream carrying a transport stream 10 | 11 | It outputs one or several RTP streams carrying transport streams with: 12 | - hardware or software PID filtering 13 | - PID-based or service-based demultiplexing 14 | - optional descrambling via CAM device 15 | - optional DVB tables 16 | 17 | DVBlast is written to be the core of a custom IRD, CID,or ASI gateway, 18 | based on a PC with a Linux-supported card. It is very lightweight and 19 | stable, designed for 24/7 operation. 20 | 21 | 22 | Current features 23 | ================ 24 | 25 | - Lightweight program designed for extreme memory and CPU conditions 26 | - No runtime dependancy; one build dependancy (biTStream) 27 | - CAM menus (MMI) support via an external application 28 | - The configuration file describing outputs can be reloaded without losing 29 | a single packet 30 | - Support for the new S2API of linux-dvb 31 | - IPv6 network support 32 | - UDP rather than RTP output for IPTV STBs which don't support RTP 33 | 34 | 35 | Tuning DVBlast 36 | ============== 37 | 38 | You usually want to supply DVBlast with the parameters of a transponder, 39 | for instance for DVB-S : 40 | 41 | dvblast -f 11570000 -s 27500000 -v 18 42 | 43 | This tunes to frequency 11570 MHz, symbol rate 27500, horizontal (-v 18). For 44 | DVB-S2, you must indicate a modulation with -m qpsk or -m psk_8. For DVB-T, 45 | a bandwidth (usually -b 8 for 8 MHz multiplexes). 46 | 47 | Please note that frequencies are in kHz for DVB-S/S2/C, but Hz for DVB-T. 48 | Symbol rates are in symbols/s, and bandwidths in MHz. If you have several 49 | linux-dvb cards in the machine, specify which one to use with -a. 50 | 51 | You generally want to run DVBlast in DVB compliance mode with option -C. 52 | This option will pass through or generate mandatory DVB tables (NIT, SDT, 53 | EITp/f, TOT, TDT). If you also want to pass-through the EIT schedule tables, 54 | use the -e switch. It is considered a good practice to configure the name 55 | of the network (for the NIT) with the -M option. 56 | 57 | If you don't want to set these options on a general basis, you can set them 58 | per output - see below. 59 | 60 | Other rarely used options are available - run dvblast -h for more 61 | information. 62 | 63 | 64 | Alternative inputs 65 | ================== 66 | 67 | DVBlast may handle several DVB adapters in the same machine with the -a switch: 68 | -a 3 will use /dev/dvb/adapter3. Additionally, selecting between frontends on 69 | a single card is supported with the -n switch. This is useful for hybrid 70 | DVB/S + DVB/T cards. 71 | 72 | If you own a Computer Modules DVB-ASI input card, you can have DVBlast 73 | filter and demultiplex the inputs. You just need to specify the slot number 74 | with -A. 75 | 76 | If you own a Deltacast ASI input card, you can have DVBlast filter and 77 | demultiplex the inputs. You just need to specify the input as 78 | "-A deltacast:" where is 100 * the card number (0 based) + the channel 79 | number (0 based). 80 | 81 | DVBlast can also read from a UDP or RTP IPv4 source carrying for 82 | instance a multi-program transport stream. The address is specified with 83 | -D. See the 'advanced features' section for information on how to create 84 | such a stream for instance to cross network boundaries between the 85 | receivers and the target network. 86 | 87 | The syntax of the -D option is: 88 | [[:]@][:][/]* 89 | where is the multicast address carrying the stream, and is optionally the address of the source, for source-specific multicast. 91 | Options include: 92 | /udp (for streams without an RTP header) 93 | /mtu=XXXX (sets the maximum UDP packet size) 94 | /ifindex=X (binds to a specific network interface, by link number) 95 | /ifaddr=XXX.XXX.XXX.XXX (binds to a specific network interface, by address) 96 | 97 | For example: 98 | -D 239.255.0.2:1234/udp/ifindex=1 99 | 100 | 101 | Configuring outputs 102 | =================== 103 | 104 | DVBlast reads a configuration file containing one or several lines in the 105 | format : 106 | [:][@[:]][/