Commit 527bda5e authored by Christophe Massiot's avatar Christophe Massiot

* demux.c, en50221.c: Get rid of the libdvbpsi dependancy. * demux.c: New -C...

* demux.c, en50221.c: Get rid of the libdvbpsi dependancy. * demux.c: New -C "DVB compliance" option; -e only activates EIT schedule. * demux.c: In DVB compliance mode, generate a NIT (see -M and -N). * demux.c: In DVB compliance mode, pass through RST. * demux.c: Introduce a buffering scheme allowing several EIT sections per TS packet. * dvblast.h: Get rid of the inline function to access TS structures. * en50221.c: Fix a potential memory corruption with application info. * version.h: Bump up version to 2.0.0.
parent 6ece6b2d
......@@ -6,5 +6,9 @@ Installing DVBlast
No autotools yet... You have to tweak the Makefile by hand, especially
if your kernel is S2API-enabled but not your distribution (indicate the
path of your kernel where appropriate). Compile the program with `make`
and install with `make install`. It requires the installation of libdvbpsi
0.1.6 or later and libdvbpsi-devel (depending on your distribution).
and install with `make install`.
DVBlast no longer requires libdvbpsi runtime and libdvbpsi-devel for
compilation. Instead you must install biTStream on your build machine
(no runtime library needed). biTStream is currently available via SVN at:
svn://svn.videolan.org/bitstream/trunk
......@@ -8,7 +8,7 @@ CFLAGS += -Wall -O3 -fomit-frame-pointer
CFLAGS += -g
CFLAGS += -I/usr/src/kernel/linux-2.6.29.1/include
LDLIBS += -lrt
LDLIBS_DVBLAST += -ldvbpsi -lpthread
LDLIBS_DVBLAST += -lpthread
OBJ_DVBLAST = dvblast.o util.o dvb.o udp.o asi.o demux.o output.o en50221.o comm.o
OBJ_DVBLASTCTL = util.o dvblastctl.o
......
$Id$
Changes between 1.2 and 1.3:
Changes between 1.2 and 2.0:
----------------------------
* Fix latency and potential packet loss during CAM communication
* Add optional kernel patches for lower latency
* Smooth packet output with an extra buffer
* libdvbpsi runtime is no longer needed; biTStream development library
is used instead
* Add support for NIT in DVB compliance mode
* Syslog support with -l option
* Override FEC Inner with -F option
* Override Rolloff with -R option
......
......@@ -13,7 +13,7 @@ It outputs one or several RTP streams carrying transport streams with:
- hardware or software PID filtering
- PID-based or service-based demultiplexing
- optional descrambling via CAM device
- EIT, SDT and TDT pass-through for EPG information<
- optional DVB tables
DVBlast is written to be the core of a custom IRD, CID,or ASI gateway,
based on a PC with a Linux-supported card. It is very lightweight and
......@@ -24,7 +24,7 @@ Current features
================
- Lightweight program designed for extreme memory and CPU conditions
- Only one dependancy: libdvbpsi
- No runtime dependancy; one build dependancy (biTStream)
- CAM menus (MMI) support via an external application
- The configuration file describing outputs can be reloaded without losing
a single packet
......@@ -49,6 +49,12 @@ Please note that frequencies are in kHz for DVB-S/S2/C, but Hz for DVB-T.
Symbol rates are in symbols/s, and bandwidths in MHz. If you have several
linux-dvb cards in the machine, specify which one to use with -a.
You generally want to run DVBlast in DVB compliance mode with option -C.
This option will pass through or generate mandatory DVB tables (NIT, SDT,
EITp/f, TOT, TDT). If you also want to pass-through the EIT schedule tables,
use the -e switch. It is considered a good practice to configure the name
of the network (for the NIT) with the -M option.
Other rarely used options are available - run dvblast -h for more
information.
......@@ -226,8 +232,7 @@ Note that IPv6 addresses specified on command line may need to have the square
brackets escaped (\[ and \]), depending on your shell.
The -u switch disables the PID filters, so that all PIDs, even the
unused ones, can be output. With -e, dvblast also streams EIT and SDT packets
for the related services.
unused ones, can be output.
Other options are self-understandable, and are listed in dvblast -h.
- Test and enhance the API for DVB-C, H, and ATSC support
- Win32 support
- Improve build system (autostuff)
- bitstream support
......@@ -25,6 +25,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
......
......@@ -17,6 +17,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
......
This diff is collapsed.
......@@ -26,6 +26,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <pthread.h>
#include <netdb.h>
......@@ -63,8 +64,11 @@ int i_bandwidth = 8;
char *psz_modulation = NULL;
int b_budget_mode = 0;
int b_output_udp = 0;
int b_dvb_compliance = 0;
int b_enable_epg = 0;
int b_unique_tsid = 0;
uint16_t i_network_id = 0xffff;
const char *psz_network_name = "DVBlast - http://www.videolan.org/projects/dvblast.html";
mtime_t i_output_latency = DEFAULT_OUTPUT_LATENCY;
mtime_t i_max_retention = DEFAULT_MAX_RETENTION;
volatile int b_hup_received = 0;
......@@ -317,14 +321,13 @@ static void DisplayVersion()
*****************************************************************************/
void usage()
{
msg_Raw( NULL, "Usage: dvblast [-q] [-c <config file>] [-r <remote socket>] [-t <ttl>] [-o <SSRC IP>] [-i <RT priority>] [-a <adapter>] [-n <frontend number>] [-S <diseqc>] [-f <frequency>|-D <src mcast>:<port>|-A <ASI adapter>] [-F <fec inner>] [-R <rolloff>] [-s <symbol rate>] [-v <0|13|18>] [-p] [-b <bandwidth>] [-m <modulation] [-u] [-U] [-L <latency>] [-E <retention>] [-d <dest IP:port>] [-e] [-T]" );
msg_Raw( NULL, "Usage: dvblast [-q] [-c <config file>] [-r <remote socket>] [-t <ttl>] [-o <SSRC IP>] [-i <RT priority>] [-a <adapter>] [-n <frontend number>] [-S <diseqc>] [-f <frequency>|-D <src mcast>:<port>|-A <ASI adapter>] [-F <fec inner>] [-R <rolloff>] [-s <symbol rate>] [-v <0|13|18>] [-p] [-b <bandwidth>] [-m <modulation] [-u] [-U] [-L <latency>] [-E <retention>] [-d <dest IP:port>] [-C [-e] [-M <network name] [-N <network ID>]] [-T]" );
msg_Raw( NULL, "Input:" );
msg_Raw( NULL, " -a --adapter <adapter>" );
msg_Raw( NULL, " -A --asi-adapter read packets from an ASI adapter (0-n)" );
msg_Raw( NULL, " -b --bandwidth frontend bandwith" );
msg_Raw( NULL, " -D --rtp-input read packets from a multicast address instead of a DVB card" );
msg_Raw( NULL, " -e --epg-passthrough enable EPG pass through (EIT data)" );
msg_Raw( NULL, " -f --frequency frontend frequency" );
msg_Raw( NULL, " -F --fec-inner Forward Error Correction (FEC Inner)");
msg_Raw( NULL, " DVB-S2 0|12|23|34|35|56|78|89|910|999 (default auto: 999)");
......@@ -338,25 +341,29 @@ void usage()
msg_Raw( NULL, " DVB-S2 35=0.35|25=0.25|20=0.20|0=AUTO (default: 35)" );
msg_Raw( NULL, " -s --symbole-rate" );
msg_Raw( NULL, " -S --diseqc satellite number for diseqc (0: no diseqc, 1-4, A or B)" );
msg_Raw( NULL, " -T --unique-ts-id generate unique TS ID for each program" );
msg_Raw( NULL, " -u --budget-mode turn on budget mode (no hardware PID filtering)" );
msg_Raw( NULL, " -v --voltage voltage to apply to the LNB (QPSK)" );
msg_Raw( NULL, "Output:" );
msg_Raw( NULL, " -c --config-file <config file>" );
msg_Raw( NULL, " -L --latency maximum latency allowed between input and output (default: 100 ms)" );
msg_Raw( NULL, " -E --retention maximum retention allowed between input and output (default: 40 ms)" );
msg_Raw( NULL, " -C --dvb-compliance pass through or build the mandatory DVB tables" );
msg_Raw( NULL, " -d --duplicate duplicate all received packets to a given destination" );
msg_Raw( NULL, " -e --epg-passthrough pass through DVB EIT schedule tables" );
msg_Raw( NULL, " -E --retention maximum retention allowed between input and output (default: 40 ms)" );
msg_Raw( NULL, " -L --latency maximum latency allowed between input and output (default: 100 ms)" );
msg_Raw( NULL, " -M --network-name DVB network name to declare in the NIT" );
msg_Raw( NULL, " -N --network-id DVB network ID to declare in the NIT" );
msg_Raw( NULL, " -o --rtp-output <SSRC IP>" );
msg_Raw( NULL, " -t --ttl <ttl> TTL of the output stream" );
msg_Raw( NULL, " -T --unique-ts-id generate random unique TS ID for each output" );
msg_Raw( NULL, " -U --udp use raw UDP rather than RTP (required by some IPTV set top boxes)" );
msg_Raw( NULL, "Misc:" );
msg_Raw( NULL, " -h --help display this full help" );
msg_Raw( NULL, " -i --priority <RT pritority>" );
msg_Raw( NULL, " -q be quiet (less verbosity, repeat or use number for even quieter)" );
msg_Raw( NULL, " -l --logger use syslog for logging messages instead of stderr" );
msg_Raw( NULL, " -r --remote-socket <remote socket>" );
msg_Raw( NULL, " -l --logger use syslog for logging messages instead of stderr" );
msg_Raw( NULL, " -V --version only display the version" );
exit(1);
}
......@@ -401,14 +408,17 @@ int main( int i_argc, char **pp_argv )
{ "duplicate", required_argument, NULL, 'd' },
{ "rtp-input", required_argument, NULL, 'D' },
{ "asi-adapter", required_argument, NULL, 'A' },
{ "dvb-compliance", no_argument, NULL, 'C' },
{ "epg-passthrough", no_argument, NULL, 'e' },
{ "network-name", no_argument, NULL, 'M' },
{ "network-id", no_argument, NULL, 'N' },
{ "logger", no_argument, NULL, 'l' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ 0, 0, 0, 0}
};
while ( ( c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:f:F:R:s:S:v:pb:m:uUTL:E:d:D:A:lehV", long_options, NULL)) != -1 )
while ( ( c = getopt_long(i_argc, pp_argv, "q::c:r:t:o:i:a:n:f:F:R:s:S:v:pb:m:uUTL:E:d:D:A:lCeM:N:hV", long_options, NULL)) != -1 )
{
switch ( c )
{
......@@ -670,10 +680,22 @@ int main( int i_argc, char **pp_argv )
pf_UnsetFilter = asi_UnsetFilter;
break;
case 'C':
b_dvb_compliance = 1;
break;
case 'e':
b_enable_epg = 1;
break;
case 'M':
psz_network_name = optarg;
break;
case 'N':
i_network_id = strtoul( optarg, NULL, 0 );
break;
case 'l':
b_enable_syslog = 1;
break;
......@@ -705,6 +727,12 @@ int main( int i_argc, char **pp_argv )
msg_Warn( NULL, "for DVB-IP compliance you should use RTP." );
}
if ( b_enable_epg && !b_dvb_compliance )
{
msg_Dbg( NULL, "turning on DVB compliance, required by EPG information" );
b_dvb_compliance = 1;
}
signal( SIGHUP, SigHandler );
srand( time(NULL) * getpid() );
......
......@@ -22,12 +22,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <dvbpsi/dvbpsi.h>
#include <dvbpsi/descriptor.h>
#include <dvbpsi/pmt.h>
#include "netdb.h"
#include "sys/socket.h"
#include <netdb.h>
#include <sys/socket.h>
#define DEFAULT_PORT 3001
#define TS_SIZE 188
......@@ -42,6 +38,7 @@
#define MAX_POLL_TIMEOUT 100000 /* 100 ms */
#define DEFAULT_OUTPUT_LATENCY 200000 /* 200 ms */
#define DEFAULT_MAX_RETENTION 40000 /* 40 ms */
#define MAX_EIT_RETENTION 500000 /* 500 ms */
/*****************************************************************************
* Output configuration flags (for output_t -> i_config) - bit values
......@@ -89,13 +86,16 @@ typedef struct output_t
/* demux */
int i_nb_errors;
mtime_t i_last_error;
dvbpsi_psi_section_t *p_pat_section;
uint8_t *p_pat_section;
uint8_t i_pat_version, i_pat_cc;
dvbpsi_psi_section_t *p_pmt_section;
uint8_t *p_pmt_section;
uint8_t i_pmt_version, i_pmt_cc;
dvbpsi_psi_section_t *p_sdt_section;
uint8_t *p_nit_section;
uint8_t i_nit_version, i_nit_cc;
uint8_t *p_sdt_section;
uint8_t i_sdt_version, i_sdt_cc;
uint8_t i_eit_cc;
block_t *p_eit_ts_buffer;
uint8_t i_eit_ts_buffer_offset, i_eit_cc;
uint16_t i_ts_id;
/* configuration */
......@@ -126,8 +126,11 @@ extern int i_bandwidth;
extern char *psz_modulation;
extern int b_budget_mode;
extern int b_output_udp;
extern int b_dvb_compliance;
extern int b_enable_epg;
extern int b_unique_tsid;
extern uint16_t i_network_id;
extern const char *psz_network_name;
extern mtime_t i_output_latency;
extern mtime_t i_max_retention;
extern mtime_t i_wallclock;
......@@ -185,7 +188,7 @@ void demux_Run( block_t *p_ts );
void demux_Change( output_t *p_output, uint16_t i_sid,
uint16_t *pi_pids, int i_nb_pids );
void demux_ResendCAPMTs( void );
int PIDIsSelected( uint16_t i_pid );
bool demux_PIDIsSelected( uint16_t i_pid );
output_t *output_Create( uint8_t i_config, const char *psz_displayname,
void *p_init_data );
......@@ -229,86 +232,3 @@ static inline void block_DeleteChain( block_t *p_block )
p_block = p_next;
}
}
/*****************************************************************************
* block_GetSync
*****************************************************************************/
static inline uint8_t block_GetSync( block_t *p_block )
{
return p_block->p_ts[0];
}
/*****************************************************************************
* block_HasTransportError
*****************************************************************************/
static inline uint8_t block_HasTransportError( block_t *p_block )
{
return p_block->p_ts[1] & 0x80;
}
/*****************************************************************************
* block_UnitStart
*****************************************************************************/
static inline uint8_t block_UnitStart( block_t *p_block )
{
return p_block->p_ts[1] & 0x40;
}
/*****************************************************************************
* block_GetPID
*****************************************************************************/
static inline uint16_t block_GetPID( block_t *p_block )
{
return (((uint16_t)p_block->p_ts[1] & 0x1f) << 8)
| p_block->p_ts[2];
}
/*****************************************************************************
* block_GetScrambling
*****************************************************************************/
static inline uint8_t block_GetScrambling( block_t *p_block )
{
return p_block->p_ts[3] & 0xc0;
}
/*****************************************************************************
* block_GetCC
*****************************************************************************/
static inline uint8_t block_GetCC( block_t *p_block )
{
return p_block->p_ts[3] & 0xf;
}
/*****************************************************************************
* block_HasPCR
*****************************************************************************/
static inline int block_HasPCR( block_t *p_block )
{
return ( p_block->p_ts[3] & 0x20 ) && /* adaptation field present */
( p_block->p_ts[4] >= 7 ) && /* adaptation field size */
( p_block->p_ts[5] & 0x10 ); /* has PCR */
}
/*****************************************************************************
* block_GetPCR
*****************************************************************************/
static inline mtime_t block_GetPCR( block_t *p_block )
{
return ( (mtime_t)p_block->p_ts[6] << 25 ) |
( (mtime_t)p_block->p_ts[7] << 17 ) |
( (mtime_t)p_block->p_ts[8] << 9 ) |
( (mtime_t)p_block->p_ts[9] << 1 ) |
( (mtime_t)p_block->p_ts[10] >> 7 );
}
/*****************************************************************************
* block_GetPayload
*****************************************************************************/
static inline uint8_t *block_GetPayload( block_t *p_block )
{
if ( !(p_block->p_ts[3] & 0x10) )
return NULL;
if ( !(p_block->p_ts[3] & 0x20) )
return &p_block->p_ts[4];
return &p_block->p_ts[ 5 + p_block->p_ts[4] ];
}
......@@ -25,6 +25,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
......@@ -45,8 +46,8 @@ int i_syslog = 0;
void usage()
{
msg_Raw( NULL, "DVBlastctl %d.%d.%d%s", VERSION_MAJOR, VERSION_MINOR,
VERSION_REVISION, VERSION_EXTRA );
msg_Raw( NULL, "DVBlastctl %d.%d.%d%s", VERSION_MAJOR, VERSION_MINOR,
VERSION_REVISION, VERSION_EXTRA );
msg_Raw( NULL, "Usage: dvblastctl -r <remote socket> reload|shutdown|fe_status|mmi_status|mmi_open|mmi_close|mmi_get|mmi_send_text|mmi_send_choice [<CAM slot>] [<text/choice>]" );
exit(1);
}
......
This diff is collapsed.
......@@ -80,9 +80,9 @@ void en50221_Init( void );
void en50221_Reset( void );
void en50221_Read( void );
void en50221_Poll( void );
void en50221_AddPMT( dvbpsi_pmt_t *p_pmt );
void en50221_UpdatePMT( dvbpsi_pmt_t *p_pmt );
void en50221_DeletePMT( dvbpsi_pmt_t *p_pmt );
void en50221_AddPMT( uint8_t *p_pmt );
void en50221_UpdatePMT( uint8_t *p_pmt );
void en50221_DeletePMT( uint8_t *p_pmt );
uint8_t en50221_StatusMMI( uint8_t *p_answer, ssize_t *pi_size );
uint8_t en50221_StatusMMISlot( uint8_t *p_buffer, ssize_t i_size,
uint8_t *p_answer, ssize_t *pi_size );
......
......@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
......@@ -37,6 +38,8 @@
#include "dvblast.h"
#include <bitstream/mpeg/ts.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
......@@ -119,14 +122,19 @@ int output_Init( output_t *p_output, uint8_t i_config,
p_output->i_cc = rand() & 0xffff;
p_output->i_pat_cc = rand() & 0xf;
p_output->i_pmt_cc = rand() & 0xf;
p_output->i_nit_cc = rand() & 0xf;
p_output->i_sdt_cc = rand() & 0xf;
p_output->i_eit_cc = rand() & 0xf;
p_output->i_pat_version = rand() & 0xff;
p_output->i_pmt_version = rand() & 0xff;
p_output->i_nit_version = rand() & 0xff;
p_output->i_sdt_version = rand() & 0xff;
p_output->p_pat_section = NULL;
p_output->p_pmt_section = NULL;
p_output->p_nit_section = NULL;
p_output->p_sdt_section = NULL;
p_output->p_eit_ts_buffer = NULL;
p_output->i_eit_ts_buffer_offset = 0;
if ( b_unique_tsid )
p_output->i_ts_id = rand() & 0xffff;
p_output->i_ref_timestamp = 0;
......@@ -175,6 +183,12 @@ void output_Close( output_t *p_output )
p_output->p_packets = p_output->p_last_packet = NULL;
free( p_output->psz_displayname );
free( p_output->p_pat_section );
free( p_output->p_pmt_section );
free( p_output->p_nit_section );
free( p_output->p_sdt_section );
free( p_output->p_eit_ts_buffer );
free( p_output->p_addr );
p_output->i_config &= ~OUTPUT_VALID;
close( p_output->i_handle );
}
......@@ -251,7 +265,9 @@ void output_Put( output_t *p_output, block_t *p_block )
&& p_output->p_last_packet->i_dts + i_max_retention > p_block->i_dts )
{
p_packet = p_output->p_last_packet;
if ( block_HasPCR( p_block ) )
if ( ts_has_adaptation( p_block->p_ts )
&& ts_get_adaptation( p_block->p_ts )
&& tsaf_has_pcr( p_block->p_ts ) )
p_packet->i_dts = p_block->i_dts;
}
else
......
......@@ -25,6 +25,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
......
......@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdarg.h>
#include <sys/time.h>
......
......@@ -21,7 +21,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define VERSION_REVISION 0
#define VERSION_EXTRA "-svn"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment