changeset 9610:76c6d8f1ebf5

this is a combo patch that: 1) adds an experimental TS demuxer to mplayer 2) adds an input (streaming) interface from DVB cards. It compiles and runs with the following versions of the drivers: dvb-kernel (HEAD) (with stock kernel 2.4.20) and 0.9.4 (with kernel 2.4.18) patch by Nico <nsabbi@libero.it> some cleanups, ts demuxer fixes by me
author arpi
date Sun, 16 Mar 2003 20:13:28 +0000
parents bb8593ea37cb
children 4847392922be
files cfg-common.h configure libmpdemux/Makefile libmpdemux/demux_ts.c libmpdemux/demuxer.c libmpdemux/demuxer.h libmpdemux/dvb_defaults.h libmpdemux/dvb_tune.c libmpdemux/dvbin.c libmpdemux/dvbin.h libmpdemux/open.c libmpdemux/stream.c libmpdemux/stream.h libmpdemux/video.c mencoder.c mplayer.c
diffstat 16 files changed, 2714 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/cfg-common.h	Sun Mar 16 16:38:16 2003 +0000
+++ b/cfg-common.h	Sun Mar 16 20:13:28 2003 +0000
@@ -64,8 +64,8 @@
 	{"forceidx", &index_mode, CONF_TYPE_FLAG, 0, -1, 2, NULL},
 
 	// select audio/videosubtitle stream
-	{"aid", &audio_id, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL},
-	{"vid", &video_id, CONF_TYPE_INT, CONF_RANGE, 0, 255, NULL},
+	{"aid", &audio_id, CONF_TYPE_INT, CONF_RANGE, 0, 8192, NULL},
+	{"vid", &video_id, CONF_TYPE_INT, CONF_RANGE, 0, 8192, NULL},
 	{"sid", &dvdsub_id, CONF_TYPE_INT, CONF_RANGE, 0, 31, NULL},
 
 	{ "hr-mp3-seek", &hr_mp3_seek, CONF_TYPE_FLAG, 0, 0, 1, NULL },
@@ -94,6 +94,10 @@
 	{"tv", "MPlayer was compiled without TV Interface support\n", CONF_TYPE_PRINT, 0, 0, 0, NULL},
 #endif
 	{"vivo", vivoopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
+#ifdef HAS_DVBIN_SUPPORT
+	        {"dvbin", dvbin_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
+#endif
+
 
 // ------------------------- a-v sync options --------------------
 
@@ -164,6 +168,7 @@
 
         {"flip", &flip, CONF_TYPE_FLAG, 0, -1, 1, NULL},
         {"noflip", &flip, CONF_TYPE_FLAG, 0, -1, 0, NULL},
+	{"tsfastparse", &ts_fastparse, CONF_TYPE_INT, 0, 0, 0, NULL},
 
 #ifdef USE_LIBAVCODEC
 	{"lavdopts", lavc_decode_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
@@ -243,6 +248,7 @@
 extern char* audio_stream;
 extern char* sub_stream;
 extern int demuxer_type, audio_demuxer_type, sub_demuxer_type;
+extern int ts_fastparse;
 
 #include "libmpdemux/tv.h"
 
@@ -290,6 +296,12 @@
 };
 #endif
 
+#ifdef HAS_DVBIN_SUPPORT
+#include "libmpdemux/dvbin.h"
+extern struct config dvbin_opts_conf[];
+#endif
+
+
 extern int sws_chr_vshift;
 extern int sws_chr_hshift;
 extern float sws_chr_gblur;
--- a/configure	Sun Mar 16 16:38:16 2003 +0000
+++ b/configure	Sun Mar 16 20:13:28 2003 +0000
@@ -2848,6 +2848,7 @@
 fi
 if test "$_dvb" = yes ; then
   _def_dvb='#define HAVE_DVB 1'
+  _def_dvb_in='#define HAS_DVBIN_SUPPORT 1'
   _aomodules="mpegpes(dvb) $_aomodules"
   _vomodules="mpegpes(dvb) $_vomodules"
 fi
@@ -2888,12 +2889,14 @@
   fi
   if test "$_dvbhead" = yes ; then
     _def_dvb='#define HAVE_DVB_HEAD 1'
+    _def_dvb_in='#define HAS_DVBIN_SUPPORT 1'
     _aomodules="mpegpes(dvb) $_aomodules"
     _vomodules="mpegpes(dvb) $_vomodules"
   fi
 fi
 if test "$_dvbhead" = no && test "$_dvb" = no ; then
   _def_dvb='#undef HAVE_DVB'
+  _def_dvb_in='#undef HAS_DVBIN_SUPPORT '
   _aomodules="mpegpes(file) $_aomodules"
   _vomodules="mpegpes(file) $_vomodules"
 fi
@@ -5497,6 +5500,7 @@
 $_def_dxr2
 $_def_dxr3
 $_def_dvb
+$_def_dvb_in
 $_def_svga
 $_def_vesa
 $_def_xdpms
--- a/libmpdemux/Makefile	Sun Mar 16 16:38:16 2003 +0000
+++ b/libmpdemux/Makefile	Sun Mar 16 20:13:28 2003 +0000
@@ -3,7 +3,7 @@
 
 include ../config.mak
 
-SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_pva.c demux_viv.c demuxer.c dvdauth.c dvdnav_stream.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c demux_bmp.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_oss.c audio_in.c demux_smjpeg.c cue_read.c extension.c demux_gif.c
+SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c muxer.c muxer_avi.c muxer_mpeg.c demux_asf.c demux_avi.c demux_mov.c parse_mp4.c demux_mpg.c demux_pva.c demux_viv.c demuxer.c dvdauth.c dvdnav_stream.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c tvi_bsdbt848.c frequencies.c demux_fli.c demux_real.c demux_y4m.c yuv4mpeg.c yuv4mpeg_ratio.c demux_nuv.c demux_film.c demux_roq.c mf.c demux_mf.c demux_audio.c demux_demuxers.c demux_ogg.c demux_bmp.c cdda.c demux_rawaudio.c demux_rawvideo.c cddb.c cdinfo.c demux_rawdv.c ai_alsa.c ai_oss.c audio_in.c demux_smjpeg.c cue_read.c extension.c demux_gif.c demux_ts.c
 ifeq ($(XMMS_PLUGINS),yes)
 SRCS += demux_xmms.c
 endif 
@@ -20,6 +20,15 @@
 endif
 endif
 
+DVBIN = yes
+ifeq ($(DVBIN),yes)
+SRCS += dvbin.c
+SRCS += dvb_tune.c
+endif
+
+
+
+
 OBJS	= $(SRCS:.c=.o)
 OBJS   += $(CPLUSPLUSSRCS:.cpp=.o)
 INCLUDE = -I../loader $(CSS_INC) $(EXTRA_INC)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpdemux/demux_ts.c	Sun Mar 16 20:13:28 2003 +0000
@@ -0,0 +1,903 @@
+/*
+ * Copyright (C) 2000-2002 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+ *
+ * $Id$
+ *
+ * Demultiplexer for MPEG2 Transport Streams.
+ *
+ * For the purposes of playing video, we make some assumptions about the
+ * kinds of TS we have to process. The most important simplification is to
+ * assume that the TS contains a single program (SPTS) because this then
+ * allows significant simplifications to be made in processing PATs.
+
+
+
+ /* 
+ * WARNING: Quite a hack was required in order to get files by MultiDec played back correctly.
+ * If it breaks anything else, just comment out the "#define DEMUX_PVA_MULTIDEC_HACK" below
+ * and it will not be compiled in.
+ *
+ * Feedback is appreciated.
+ *
+ * written by Matteo Giani
+ */
+ 
+ 
+/*
+ * MPEG2 transport stream (aka DVB) demux
+ * Copyright (c) 2002 Fabrice Bellard.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+ 
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+
+#include "stream.h"
+#include "demuxer.h"
+#include "stheader.h"
+
+#include "bswap.h"
+
+
+typedef struct {
+	off_t offset;
+	long size;
+	uint8_t type;
+	uint8_t is_packet_start;
+	float pts;
+	uint8_t packet_size;
+} ts_payload_t;
+
+
+typedef struct {
+	float last_audio_pts;
+	float last_video_pts;
+	uint8_t just_synced;
+	uint8_t synced_stream_id;
+	char *buffer;		
+	int buffer_size;
+	int buffer_offset;
+	int packet_size;
+} ts_priv_t;
+
+#define TS_FEC_PACKET_SIZE 204
+#define TS_PACKET_SIZE 188
+#define NB_PID_MAX 8192
+    
+#define MAX_HEADER_SIZE 6			/* enough for PES header + length */
+#define MAX_PROBE_SIZE	1000000
+#define NUM_CONSECUTIVE_TS_PACKETS 5
+
+
+enum MpegTSState {
+    MPEGTS_HEADER = 0,
+    MPEGTS_PESHEADER_FILL,
+    MPEGTS_PESHEADER_FLAGS,
+    MPEGTS_PESHEADER_SIZE,
+    MPEGTS_PESHEADER_READ,
+    MPEGTS_PAYLOAD,
+    MPEGTS_SKIP,
+};
+
+
+int ts_fastparse = 0;
+
+typedef enum  
+{
+	UNKNOWN		= -1,
+	VIDEO_MPEG2 	= 0x10000002,
+	AUDIO_MP2   	= 0x50,
+	AUDIO_A52   	= 0x2000,
+	AUDIO_LPCM_BE  	= 0x2000000,
+	SPU_DVD		= 0x3000000,
+	SPU_DVB		= 0x3000001,
+} es_stream_type_t;    
+
+typedef struct MpegTSStream 		// IT'S AN ES
+{
+    int pid;
+    enum MpegTSState state;
+    int last_cc; /* last cc code (-1 if first packet) */
+    /* used to get the format */
+    int header_size;
+    int payload_size;
+    int pes_header_size;
+    //AVStream *st;
+    es_stream_type_t type;    
+    unsigned char header[MAX_HEADER_SIZE];
+    char *pes_buffer;
+    int offset;
+    float pts;
+    float last_pts;
+} MpegTSStream;
+
+
+typedef struct MpegTSContext {
+    int raw_packet_size; 	/* raw packet size, including FEC if present */
+    MpegTSStream *pids[NB_PID_MAX];
+    demuxer_t *demuxer;
+} MpegTSContext;
+
+
+typedef struct {
+    int size;
+    unsigned char *start;
+    es_stream_type_t type;    
+    float pts;
+    int pid;
+} ES_info_t;
+
+MpegTSContext ts;
+
+//FILE *outfile;
+
+
+static uint8_t get_packet_size(const unsigned char *buf, int size)
+{
+    int i;
+
+    if (size < (TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS))
+        return 0;
+	
+    for(i=0; i<NUM_CONSECUTIVE_TS_PACKETS; i++) 
+    {
+        if (buf[i * TS_PACKET_SIZE] != 0x47)
+	{
+	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "GET_PACKET_SIZE, pos %d, char: %2x\n", i, buf[i * TS_PACKET_SIZE]);	
+            goto try_fec;
+	}
+    }
+    return TS_PACKET_SIZE;
+    
+ try_fec:
+    for(i=0; i<NUM_CONSECUTIVE_TS_PACKETS; i++) 
+    {
+        if (buf[i * TS_FEC_PACKET_SIZE] != 0x47)
+            return 0;
+    }
+    return TS_FEC_PACKET_SIZE;
+}
+
+
+
+
+int ts_check_file(demuxer_t * demuxer)
+{
+	const int buf_size = (TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS);
+	char buf[buf_size], c, done = 0;
+	uint32_t _read, i=1;
+	uint8_t size = 0;
+	off_t pos = 0;
+	
+	mp_msg(MSGT_DEMUX, MSGL_V, "************Checking for TS************\n");
+	
+	while(! done)
+	{	
+	    while(((c=stream_read_char(demuxer->stream)) != 0x47) 
+		&& (i < MAX_PROBE_SIZE)
+		&& ! demuxer->stream->eof
+		) i++; 
+	    
+	    if(c != 0x47)
+	    {
+		mp_msg(MSGT_DEMUX, MSGL_V, "NOT A TS FILE1\n");
+		done = 1;
+		continue;
+	    }
+	
+	    pos = stream_tell(demuxer->stream) - 1;
+	    buf[0] = c;
+	    _read = stream_read(demuxer->stream, &buf[1], buf_size-1);
+	
+	    if(_read < buf_size-1)
+	    {
+		mp_msg(MSGT_DEMUX, MSGL_V, "COULDN'T READ ENOUGH DATA, EXITING TS_CHECK\n");
+		stream_reset(demuxer->stream);
+		return 0;
+	    }
+	    
+	    size = get_packet_size(buf, buf_size);
+	    if(size)
+		done = 1;
+	}
+	
+	mp_msg(MSGT_DEMUX, MSGL_V, "TRIED UP TO POSITION %u, FUOND %x, packet_size= %d\n", i, c, size);
+	stream_seek(demuxer->stream, pos);
+	return size;
+}
+
+
+
+
+
+demuxer_t *demux_open_ts(demuxer_t * demuxer)
+{
+	uint8_t packet_size;
+	//demuxer_t *vd, *ad;
+	//stream_t *s;
+	sh_video_t *sh_video;
+	sh_audio_t *sh_audio;
+	ts_priv_t * priv;
+	int i;
+	
+	
+	mp_msg(MSGT_DEMUX, MSGL_V, "DEMUX OPEN, AUDIO_ID: %d, VIDEO_ID: %d, SUBTITLE_ID: %d,\n", 
+	    demuxer->audio->id, demuxer->video->id, demuxer->sub->id);
+	
+	for(i=0; i < 8192; i++)
+	    ts.pids[i] = NULL;
+	
+	demuxer->type= DEMUXER_TYPE_MPEG_TS;
+	
+	stream_reset(demuxer->stream);
+	stream_seek(demuxer->stream, 0);
+	
+	packet_size = ts_check_file(demuxer);
+	if(!packet_size)
+	    return NULL;
+	
+	priv = malloc(sizeof(ts_priv_t));
+	priv->last_video_pts=-1;
+    	priv->last_audio_pts=-1;
+	priv->packet_size = packet_size;
+	demuxer->priv = priv;
+	
+	if(demuxer->stream->type != STREAMTYPE_FILE) demuxer->seekable=0;
+	else demuxer->seekable = 1;
+		
+	
+	sh_video = new_sh_video(demuxer, 0);
+	sh_video->ds = demuxer->video;
+	demuxer->video->sh = sh_video;
+	
+        
+	
+	sh_audio = new_sh_audio(demuxer, 0);		
+	sh_audio->ds = demuxer->audio;
+	demuxer->audio->sh = sh_audio;
+	
+	
+	mp_msg(MSGT_DEMUXER,MSGL_INFO, "Opened TS demuxer...");
+
+	if(! ts_fastparse)	
+	    ts_detect_streams(demuxer);
+	
+	
+	/*
+	demuxer->movi_start = 0;
+	demuxer->movi_end = demuxer->stream->end_pos;
+	*/
+	    
+	
+	/*    
+	s= new_ds_stream(demuxer->video);
+	return demux_open_stream(s, DEMUXER_TYPE_MPEG_ES, demuxer->audio->id, demuxer->video->id, demuxer->sub->id, NULL); 
+	*/
+	
+	stream_seek(demuxer->stream, 0);		//IF IT'S FROM A PIPE IT WILL FAIL, BUT WHO CARES?
+	return demuxer;	
+}
+
+
+
+void ts_detect_streams(demuxer_t *demuxer)
+{
+	int video_found = 0, audio_found = 0;
+	off_t pos=0;
+	ES_info_t es;
+	int *apid, *vpid, *spid;
+	unsigned char tmp[TS_FEC_PACKET_SIZE];
+	sh_video_t *sh_video = demuxer->video->sh;
+	sh_audio_t *sh_audio = demuxer->audio->sh;
+	
+	apid = &(demuxer->audio->id);
+	vpid = &(demuxer->video->id);
+	spid = &(demuxer->sub->id);
+	
+	
+	mp_msg(MSGT_DEMUXER, MSGL_INFO, "PROBING UP TO %u\n", MAX_PROBE_SIZE);
+	while(pos <= MAX_PROBE_SIZE)
+	{
+	    if(ts_parse(demuxer, &es, tmp))
+	    {
+		mp_msg(MSGT_DEMUXER, MSGL_V, "TYPE: %x, PID: %d\n", es.type, es.pid);
+		if(es.type == VIDEO_MPEG2)
+		{
+		    sh_video->format = VIDEO_MPEG2;	//MPEG2 video
+		    if(*vpid == -1)
+			*vpid = es.pid;
+		    video_found = 1;
+		}
+		    
+		if(es.type == AUDIO_MP2)
+		{
+		    sh_audio->format = AUDIO_MP2;	//MPEG1L2 audio
+		    if(*apid == -1)
+			*apid = es.pid;
+		    audio_found = 1;
+		}
+		    
+		if(es.type == AUDIO_A52)
+		{
+		    sh_audio->format = AUDIO_MP2;	//MPEG1L2 audio
+		    if(*apid == -1)
+			*apid = es.pid;
+		    audio_found = 1;
+		}
+		
+		pos = stream_tell(demuxer->stream);
+		if(video_found && audio_found)
+		    break;
+	    }
+	}
+	
+	if(video_found)
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG2...");
+	else
+	{
+	    *vpid = -2;		//WE DIDN'T MATCH ANY VIDEO STREAM, SO WE FORCE THE DEMUXER TO IGNORE VIDEO
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "NO VIDEO!\n");
+	}
+	    
+	if(sh_audio->format == AUDIO_MP2)
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO MP2\n");
+	else if(sh_audio->format == AUDIO_A52)
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO A52\n");
+	else    
+	{
+	    *apid = -2;		//WE DIDN'T MATCH ANY AUDIO STREAM, SO WE FORCE THE DEMUXER TO IGNORE AUDIO
+	    mp_msg(MSGT_DEMUXER, MSGL_INFO, "NO AUDIO!\n");
+	}
+}
+
+
+void demux_close_ts(demuxer_t * demuxer)
+{
+	if(demuxer->priv)
+	{
+		free(demuxer->priv);
+		demuxer->priv=NULL;
+	}
+}
+			
+
+
+
+//MpegTSStream *tss,  const unsigned char *buf, int buf_size, int is_start, ES_info_t *es
+static int pes_parse2(MpegTSStream *tss, unsigned char *buf, uint16_t packet_len, int is_start, ES_info_t *es) 
+{
+    unsigned char *p;
+    uint32_t       header_len;
+    int64_t        pts;
+    uint32_t       stream_id;
+    uint32_t       pkt_len;
+
+    mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2(%X, %X, %d, %d, ): \n", tss, buf, packet_len, is_start);
+
+    if(packet_len == 0)
+    {
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2(,PACKET_LEN = 0, EXIT\n");
+        return 0;
+    }
+    
+    if(packet_len > 184)
+    {
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2, BUFFER LEN IS TOO BIG: %d, EXIT\n", packet_len);
+        return 0;
+    }
+    
+    
+    p = buf;
+    pkt_len = packet_len;
+
+    if(! is_start)
+    {
+	tss->pts = tss->last_pts;
+	es->start = p;
+	es->size = packet_len;
+	return es->size;
+    }
+  
+    /* we should have a PES packet here */
+
+    if (p[0] || p[1] || (p[2] != 1)) 
+    {
+        mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: error HEADER %02x %02x %02x (should be 0x000001) \n", p[0], p[1], p[2]);
+	return 0 ;
+    }
+
+    packet_len -= 6;
+  
+    tss->payload_size = p[4] << 8 | p[5];
+    if (tss->payload_size == 0)
+        tss->payload_size = 65536;
+		
+    stream_id  = p[3];
+
+    if(packet_len==0)
+	return 0;
+
+  //mp_msg(MSGT_DEMUX, MSGL_V, "pes_parse2: packet stream id: %.2X (%d) len: %d (%x)\n", stream_id, stream_id, packet_len, packet_len);
+
+    if (p[7] & 0x80) 
+    { /* pts avail */
+	pts  = (int64_t)(p[9] & 0x0E) << 29 ;
+	pts |=  p[10]         << 22 ;
+	pts |= (p[11] & 0xFE) << 14 ;
+	pts |=  p[12]         <<  7 ;
+	pts |= (p[13] & 0xFE) >>  1 ;
+    
+	tss->pts = tss->last_pts = pts / 90000.0f;
+    } 
+    else
+	tss->pts = tss->last_pts;
+
+    header_len = p[8];
+
+    /* sometimes corruption on header_len causes segfault in memcpy below */
+    if (header_len + 9 > pkt_len) 
+    {
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_ts: illegal value for PES_header_data_length (0x%02x)\n", header_len);
+	return 0;
+    }
+
+    p += header_len + 9;
+    packet_len -= header_len + 3;
+
+    if (stream_id == 0xbd) 
+    {
+	int track, spu_id;
+    
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: audio buf = %02X %02X %02X %02X %02X %02X %02X %02X\n",
+	    p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+    
+	track = p[0] & 0x0F; /* hack : ac3 track */
+	/*
+        * we check the descriptor tag first because some stations
+        * do not include any of the ac3 header info in their audio tracks
+        * these "raw" streams may begin with a byte that looks like a stream type.
+        */
+	if(		//(m->descriptor_tag == 0x81) ||    /* ac3 - raw */ 
+    	    (p[0] == 0x0B && p[1] == 0x77))   /* ac3 - syncword */
+	{ 						
+    	    es->start = p;
+    	    es->size = packet_len;
+    	    tss->type = AUDIO_A52;
+    	    return es->size;
+	} 
+	else if (//m->descriptor_tag == 0x06 && 
+	    p[0] == 0x20 && p[1] == 0x00) 
+	{
+    	    /* DVBSUB */
+    	    long payload_len = ((buf[4] << 8) | buf[5]) - header_len - 3;
+    	    es->start = p;
+    	    es->size  = packet_len;
+    	    tss->type = SPU_DVB + payload_len;
+      
+    	    return es->size;
+	} 
+	else if ((p[0] & 0xE0) == 0x20) 
+	{
+    	    spu_id      = (p[0] & 0x1f);
+            es->start   = p+1;
+    	    es->size    = packet_len-1;
+    	    tss->type   = SPU_DVD + spu_id;
+    	    return es->size;
+	} 
+	else if ((p[0] & 0xF0) == 0x80) 
+	{
+    	    es->start   = p+4;
+    	    es->size    = packet_len - 4;
+    	    tss->type   = AUDIO_A52; // + track;
+    	    return es->size;
+	} 
+	else if ((p[0]&0xf0) == 0xa0) 
+	{
+    	    int pcm_offset;
+
+    	    for (pcm_offset=0; ++pcm_offset < packet_len-1 ; )
+    	    {
+    		if (p[pcm_offset] == 0x01 && p[pcm_offset+1] == 0x80) 
+		{ 	/* START */
+        	    pcm_offset += 2;
+        	    break;
+    		}
+    	    }
+
+    	    es->start   = p + pcm_offset;
+    	    es->size    = packet_len - pcm_offset;
+    	    tss->type   = AUDIO_LPCM_BE; // + track;
+    	    return es->size;
+	}
+    } 
+    else if ((stream_id >= 0xbc) && ((stream_id & 0xf0) == 0xe0)) 
+    {
+	es->start   = p;
+	es->size    = packet_len;
+	tss->type   = VIDEO_MPEG2;
+	return es->size;
+    } 
+    else if ((stream_id & 0xe0) == 0xc0) 
+    {
+	int track;
+	track 	    = stream_id & 0x1f;
+	es->start   = p;
+	es->size    = packet_len;
+	tss->type   = AUDIO_MP2; // + track;
+	return es->size;
+    } 
+    else 
+    {
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "pes_parse2: unknown packet, id: %x\n", stream_id);
+    }
+
+    return 0;
+}
+
+
+
+
+int ts_sync(demuxer_t *demuxer)
+{
+    uint8_t c=0;
+    
+    mp_msg(MSGT_DEMUX, MSGL_DBG2, "TS_SYNC \n");
+    
+    while(((c=stream_read_char(demuxer->stream)) != 0x47) && ! demuxer->stream->eof);
+    
+    if(c == 0x47)
+	return c;
+    else
+	return 0;
+}
+
+
+
+
+
+
+// 0 = EOF or no stream found
+// 1 = successfully read a packet
+int ts_parse(demuxer_t * demuxer , ES_info_t *es, unsigned char *packet)
+{
+    MpegTSStream *tss;
+    uint8_t done = 0;
+    ts_priv_t *priv = demuxer->priv;
+    uint16_t buf_size, is_start; 
+    int len, pid, cc, cc_ok, afc;
+    unsigned char *p;
+    
+    while(! done)
+    {
+	if(! ts_sync(demuxer))
+	{	
+	    mp_msg(MSGT_DEMUX, MSGL_V, "TS_FILL_BUFFER: COULDN'T SYNC\n");        
+	    return 0;
+        }
+	
+	len = stream_read(demuxer->stream, &packet[1], priv->packet_size-1);
+        if (len != priv->packet_size-1)
+            return 0;
+        
+	
+	
+        pid = ((packet[1] & 0x1f) << 8) | packet[2];
+	tss = ts.pids[pid];	//an ES stream
+        if(tss == NULL) 
+	{
+            /* if no pid found, then add a pid context */
+	    tss = malloc(sizeof(MpegTSStream));
+	    if (!tss)
+    		continue;
+	    memset(tss, 0, sizeof(MpegTSStream));
+            ts.pids[pid] = tss;
+            tss->pid = pid;
+            tss->last_cc = -1;
+	    tss->type = UNKNOWN;
+            mp_msg(MSGT_DEMUX, MSGL_DBG2, "new TS pid=%u\n", pid);
+        }
+	
+	cc = (packet[3] & 0xf);
+        cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));
+	if(! cc_ok)
+	{
+	    mp_msg(MSGT_DEMUX, MSGL_V, "ts_parse: CCCheck NOT OK: %d -> %d\n", tss->last_cc, cc);	
+	}
+        tss->last_cc = cc;        
+    
+	
+        
+        /* skip adaptation field */
+        afc = (packet[3] >> 4) & 3;
+        p = packet + 4;
+        if (afc == 0) /* reserved value */
+            continue;
+        if (afc == 2) /* adaptation field only */
+            continue;
+        if (afc == 3) 
+	{
+            /* skip adapation field */
+            p += p[0] + 1;
+        }
+        /* if past the end of packet, ignore */
+        if (p >= packet + TS_PACKET_SIZE)
+            continue;
+    
+	// PES CONTENT STARTS HERE
+	
+	buf_size = TS_PACKET_SIZE - (p - packet);
+	
+	is_start = packet[1] & 0x40;
+	if((len = pes_parse2(tss, p, buf_size, is_start, es)))
+	{
+	    tss->offset += es->size;
+	    es->pid = tss->pid;
+	    es->pts = tss->pts;
+	    es->type = tss->type;
+            
+	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "ts_parse, type=%X, start=%X, len=%d\n", tss->type, es->start, es->size);
+	
+	    return len;
+	}    
+    }
+    
+    return 0;
+}
+
+
+int demux_ts_fill_buffer(demuxer_t * demuxer)
+{
+    ES_info_t es;
+    demux_packet_t *dp;
+    int len;
+    unsigned char packet[TS_FEC_PACKET_SIZE];
+    int *apid, *vpid, *spid;
+    
+    apid = &(demuxer->audio->id);
+    vpid = &(demuxer->video->id);
+    spid = &(demuxer->sub->id);
+    
+    while(len = ts_parse(demuxer, &es, packet))
+    {
+	    mp_msg(MSGT_DEMUX, MSGL_V, "NEW_FILL_BUFFER, NEW_ADD_PACKET(%x, %d) type: %x, PTS: %f\n", es.start, es.size, es.type, es.pts);    
+	
+	    if(es.type == VIDEO_MPEG2)
+	    {
+		if(ts_fastparse)
+		{
+		    if(*vpid == -2)
+			continue;
+		    
+		    if(*vpid == -1)
+			*vpid = es.pid;
+		}
+		    
+		if(*vpid != es.pid)
+	    	    continue;
+	
+		dp = new_demux_packet(es.size);
+		if(! dp || ! dp->buffer)
+		{
+	    	    fprintf(stderr, "fill_buffer, NEW_ADD_PACKET(%d) FAILED\n", es.size);    
+	    	    continue;
+		}		
+		memcpy(dp->buffer, es.start, es.size); 
+		dp->pts = es.pts;
+		dp->flags = 0;
+		dp->pos = stream_tell(demuxer->stream);
+		ds_add_packet(demuxer->video, dp);
+		mp_msg(MSGT_DEMUX, MSGL_V, "VIDEO pts=%f\n", es.pts);
+		return len;
+	    }
+	
+	    if((es.type == AUDIO_MP2) || (es.type == AUDIO_A52))
+	    {
+		if(ts_fastparse)
+		{
+		    if(*apid == -2)
+			continue;
+		    
+		    if(*apid == -1)
+	    		*apid = es.pid;
+		}
+		        
+		if(*apid != es.pid)
+	    	    continue;
+		    
+		dp = new_demux_packet(es.size);
+		if(! dp || ! dp->buffer)
+		{
+	    	    fprintf(stderr, "fill_buffer, NEW_ADD_PACKET(%d) FAILED\n", es.size);    
+	    	    continue;
+		}
+		memcpy(dp->buffer, es.start, es.size);    
+		dp->flags = 0;
+		dp->pts = es.pts;
+		dp->pos = stream_tell(demuxer->stream);
+		ds_add_packet(demuxer->audio, dp);    
+		mp_msg(MSGT_DEMUX, MSGL_V, "AUDIO pts=%f\r\n", es.pts);
+		return len;
+	    }
+	
+	    mp_msg(MSGT_DEMUX, MSGL_V, "SKIP--------\n");    
+    }
+}
+
+
+
+
+int stringent_ts_sync(demuxer_t *demuxer)
+{
+    ts_priv_t *priv = demuxer->priv;
+    uint8_t c = 0, done = 0, i, buf[TS_FEC_PACKET_SIZE * NUM_CONSECUTIVE_TS_PACKETS];
+    off_t pos;
+    
+    mp_msg(MSGT_DEMUX, MSGL_DBG2, "STRINGENT_TS_SYNC packet_size: %d\n", priv->packet_size);
+    
+    
+    if(! demuxer->seekable)
+	return 0;
+    
+	
+    while(! done)
+    {   
+	while(((c=stream_read_char(demuxer->stream)) != 0x47) && !demuxer->stream->eof);
+	
+	if(c != 0x47)
+	{
+	    stream_reset(demuxer->stream);
+	    return 0;
+	}
+	    
+	pos = stream_tell(demuxer->stream);
+	if(pos < 1)
+	    pos = 1;
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "dopo il while, pos=%u\n", pos);
+	    
+	done = 1;
+	buf[0] = c;
+	stream_read(demuxer->stream, &buf[1], (priv->packet_size * NUM_CONSECUTIVE_TS_PACKETS) - 1);	
+	for(i = 0; i < 5; i++)
+	{	
+	    if (buf[i * priv->packet_size] != 0x47)
+        	done = 0;
+	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "i: %d, char:  %x\n", i, buf[i * priv->packet_size]);	
+	}
+	
+	if(done)
+	    stream_seek(demuxer->stream, pos); 
+	else
+	    stream_seek(demuxer->stream, pos); 
+    }
+    //stream_seek(demuxer->stream, pos+1); 
+    mp_msg(MSGT_DEMUX, MSGL_DBG2, "STRINGENT_TS_SYNC, STREAM_POS: %lu\n", stream_tell(demuxer->stream));	
+    return 0x47;
+}
+
+
+extern void resync_audio_stream(sh_audio_t *);
+
+
+int demux_seek_ts(demuxer_t * demuxer, float rel_seek_secs, int flags)
+{
+	int total_bitrate=0;
+	off_t dest_offset;
+	ts_priv_t * priv = demuxer->priv;
+	int a_bps, v_bps;
+	demux_stream_t *d_audio=demuxer->audio;
+	demux_stream_t *d_video=demuxer->video;
+	sh_audio_t *sh_audio=d_audio->sh;
+	sh_video_t *sh_video=d_video->sh;
+
+
+	/*
+	 * Compute absolute offset inside the stream. Approximate total bitrate with sum of bitrates
+	 * reported by the audio and video codecs. The seek is not accurate because, just like
+	 * with MPEG streams, the bitrate is not constant. Moreover, we do not take into account
+	 * the overhead caused by PVA and PES headers.
+	 * If the calculated absolute offset is negative, seek to the beginning of the file.
+	 */
+
+	
+	if(demuxer->audio->id != -2)
+	{
+	    a_bps = ((sh_audio_t *)demuxer->audio->sh)->i_bps;
+	    total_bitrate += a_bps;
+	}
+	
+	if(demuxer->video->id != -2)	
+	{
+	    v_bps = ((sh_video_t *)demuxer->video->sh)->i_bps;
+	    total_bitrate += v_bps;
+	}
+	
+	if(! total_bitrate)	
+	{
+	    mp_msg(MSGT_DEMUX, MSGL_V, "SEEK_TS, couldn't determine bitrate, no seek\n");
+	    return 0;
+	}
+	
+	dest_offset = stream_tell(demuxer->stream) + rel_seek_secs*total_bitrate;
+	if(dest_offset < 0) dest_offset = 0;
+	
+	mp_msg(MSGT_DEMUX, MSGL_V, "SEEK TO: %f, BITRATE: %lu, FINAL_POS: %u \n", rel_seek_secs, total_bitrate, dest_offset);
+	
+	stream_seek(demuxer->stream, dest_offset);
+
+	/*if(!ts_sync(demuxer))
+	{
+		mp_msg(MSGT_DEMUX, MSGL_V, "demux_ts: Couldn't seek!\n");
+		return 0;
+	}
+	*/
+	
+	ds_fill_buffer(d_video);
+	if(sh_audio)
+	{
+	  ds_fill_buffer(d_audio);
+	  resync_audio_stream(sh_audio);
+	}
+
+	
+	/*
+	 * Reset the PTS info inside the ts_priv_t structure. This way we don't deliver
+	 * data with the wrong PTSs (the ones we had before seeking).
+	 *
+	 */
+	
+	
+	priv->last_video_pts=-1;
+	priv->last_audio_pts=-1;
+	
+	return 1;
+}
+
+
+
+
+
+static int mpegts_read_close(MpegTSContext *ts)
+{
+    int i;
+    for(i=0;i<NB_PID_MAX;i++)
+        free(ts->pids[i]);
+    return 0;
+}
+
+
+
--- a/libmpdemux/demuxer.c	Sun Mar 16 16:38:16 2003 +0000
+++ b/libmpdemux/demuxer.c	Sun Mar 16 20:13:28 2003 +0000
@@ -134,6 +134,7 @@
 extern void demux_close_smjpeg(demuxer_t* demuxer);
 extern void demux_close_xmms(demuxer_t* demuxer);
 extern void demux_close_gif(demuxer_t* demuxer);
+extern void demux_close_ts(demuxer_t* demuxer);
 
 #ifdef USE_TV
 #include "tv.h"
@@ -204,6 +205,8 @@
     case DEMUXER_TYPE_GIF:
       demux_close_gif(demuxer); break;
 #endif
+    case DEMUXER_TYPE_MPEG_TS:
+      demux_close_ts(demuxer); break;
 
     }
     // free streams:
@@ -282,6 +285,7 @@
 int demux_pva_fill_buffer(demuxer_t *demux);
 int demux_xmms_fill_buffer(demuxer_t *demux,demux_stream_t *ds);
 int demux_gif_fill_buffer(demuxer_t *demux);
+int demux_ts_fill_buffer(demuxer_t *demux);
 
 extern int demux_demuxers_fill_buffer(demuxer_t *demux,demux_stream_t *ds);
 extern int demux_ogg_fill_buffer(demuxer_t *d);
@@ -334,6 +338,7 @@
 #ifdef HAVE_GIF
     case DEMUXER_TYPE_GIF: return demux_gif_fill_buffer(demux);
 #endif
+    case DEMUXER_TYPE_MPEG_TS: return demux_ts_fill_buffer(demux);
   }
   return 0;
 }
@@ -560,6 +565,7 @@
 extern int demux_xmms_open(demuxer_t* demuxer);
 extern int gif_check_file(demuxer_t *demuxer);
 extern int demux_open_gif(demuxer_t* demuxer);
+extern int ts_check_file(demuxer_t * demuxer);
 
 extern demuxer_t* init_avi_with_ogg(demuxer_t* demuxer);
 
@@ -817,6 +823,17 @@
 		demuxer=NULL;
 	}
 }
+//=============== Try to open as MPEG-TS file: =================
+if(file_format == DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPEG_TS){
+	demuxer=new_demuxer(stream,DEMUXER_TYPE_MPEG_TS,audio_id,video_id,dvdsub_id);
+	if(ts_check_file(demuxer)) {
+		mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_Detected_XXX_FileFormat,"TS");
+		file_format=DEMUXER_TYPE_MPEG_TS;
+	} else {
+		free_demuxer(demuxer);
+		demuxer=NULL;
+	}
+}
 //=============== Try to open as MPEG-PS file: =================
 if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MPEG_PS){
  int pes=1;
@@ -1127,6 +1144,10 @@
    break;
  }
 #endif
+ case DEMUXER_TYPE_MPEG_TS: {
+  demux_open_ts(demuxer);
+  break;
+ }
 } // switch(file_format)
 pts_from_bps=0; // !!!
 return demuxer;
@@ -1195,6 +1216,7 @@
 void demux_seek_mov(demuxer_t *demuxer,float pts,int flags);
 int demux_seek_real(demuxer_t *demuxer,float rel_seek_secs,int flags);
 int demux_seek_pva(demuxer_t *demuxer,float rel_seek_secs,int flags);
+int demux_seek_ts(demuxer_t *demuxer,float rel_seek_secs,int flags);
 
 #ifdef HAVE_LIBDV095
 int demux_seek_rawdv(demuxer_t *demuxer, float pts, int flags);
@@ -1294,7 +1316,8 @@
  case DEMUXER_TYPE_XMMS:
       demux_xmms_seek(demuxer,rel_seek_secs,flags); break;
 #endif
-
+ case DEMUXER_TYPE_MPEG_TS:
+      demux_seek_ts(demuxer,rel_seek_secs,flags); break;
 
 } // switch(demuxer->file_format)
 
--- a/libmpdemux/demuxer.h	Sun Mar 16 16:38:16 2003 +0000
+++ b/libmpdemux/demuxer.h	Sun Mar 16 20:13:28 2003 +0000
@@ -37,11 +37,12 @@
 #define DEMUXER_TYPE_RAWVIDEO 26
 #define DEMUXER_TYPE_MPEG4_ES 27
 #define DEMUXER_TYPE_GIF 28
+#define DEMUXER_TYPE_MPEG_TS 29
 
 // This should always match the higest demuxer type number.
 // Unless you want to disallow users to force the demuxer to some types
 #define DEMUXER_TYPE_MIN 0
-#define DEMUXER_TYPE_MAX 28
+#define DEMUXER_TYPE_MAX 29
 
 #define DEMUXER_TYPE_DEMUXERS (1<<16)
 // A virtual demuxer type for the network code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpdemux/dvb_defaults.h	Sun Mar 16 20:13:28 2003 +0000
@@ -0,0 +1,89 @@
+/* dvb_defaults.h
+
+   Provided by Tomi Ollila
+
+   Copyright (C) Dave Chapman 2002
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version 2
+   of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+
+*/
+
+#ifndef _DVB_DEFAULTS_H
+#define _DVB_DEFAULTS_H
+
+/* DVB-S */
+
+// With a diseqc system you may need different values per LNB.  I hope
+// no-one ever asks for that :-)
+
+#define SLOF (11700*1000UL)
+#define LOF1 (9750*1000UL)
+#define LOF2 (10600*1000UL)
+
+
+
+#ifdef FINLAND
+    /* FINLAND settings 1 */
+    #define DVB_T_LOCATION		"Suomessa"
+    #define BANDWIDTH_DEFAULT           BANDWIDTH_8_MHZ
+    #define HP_CODERATE_DEFAULT         FEC_2_3
+    #define CONSTELLATION_DEFAULT       QAM_64
+    #define TRANSMISSION_MODE_DEFAULT   TRANSMISSION_MODE_8K
+    #define GUARD_INTERVAL_DEFAULT	GUARD_INTERVAL_1_8
+    #define HIERARCHY_DEFAULT           HIERARCHY_NONE
+#endif
+
+
+#ifdef FINLAND2
+    /* FINLAND settings 2 (someone verify there is such environment) */
+    #define DVB_T_LOCATION		    "Suomessa II"
+    #define BANDWIDTH_DEFAULT           BANDWIDTH_8_MHZ
+    #define HP_CODERATE_DEFAULT         FEC_1_2
+    #define CONSTELLATION_DEFAULT       QAM_64
+    #define TRANSMISSION_MODE_DEFAULT   TRANSMISSION_MODE_2K
+    #define GUARD_INTERVAL_DEFAULT      GUARD_INTERVAL_1_8
+    #define HIERARCHY_DEFAULT           HIERARCHY_NONE
+#endif
+
+#if defined (UK) && defined (HP_CODERATE_DEFAULT)
+    #error Multible countries defined
+#endif
+
+
+
+#ifndef DVB_T_LOCATION
+    #ifndef UK
+	#warning No DVB-T country defined in dvb_defaults.h
+	#warning defaulting to UK
+	#warning Ignore this if using Satellite or Cable
+    #endif
+
+    /* UNITED KINGDOM settings */
+    #define DVB_T_LOCATION		"in United Kingdom"
+    #define BANDWIDTH_DEFAULT           BANDWIDTH_8_MHZ
+    #define HP_CODERATE_DEFAULT         FEC_2_3
+    #define CONSTELLATION_DEFAULT       QAM_64
+    #define TRANSMISSION_MODE_DEFAULT   TRANSMISSION_MODE_2K
+    #define GUARD_INTERVAL_DEFAULT      GUARD_INTERVAL_1_32
+    #define HIERARCHY_DEFAULT           HIERARCHY_NONE
+#endif
+
+
+#if HIERARCHY_DEFAULT == HIERARCHY_NONE && !defined (LP_CODERATE_DEFAULT)
+    #define LP_CODERATE_DEFAULT (0) /* unused if HIERARCHY_NONE */
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpdemux/dvb_tune.c	Sun Mar 16 20:13:28 2003 +0000
@@ -0,0 +1,803 @@
+/* dvbtune - tune.c
+
+   Copyright (C) Dave Chapman 2001,2002
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version 2
+   of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <error.h>
+#include "config.h"
+
+#ifdef HAVE_DVB_HEAD
+	#include <linux/dvb/dmx.h>
+	#include <linux/dvb/frontend.h>
+	char* frontenddev[4]={"/dev/dvb/adapter0/frontend0","/dev/dvb/adapter1/frontend0","/dev/dvb/adapter2/frontend0","/dev/dvb/adapter3/frontend0"};
+	char* dvrdev[4]={"/dev/dvb/adapter0/dvr0","/dev/dvb/adapter1/dvr0","/dev/dvb/adapter2/dvr0","/dev/dvb/adapter3/dvr0"};
+	char* demuxdev[4]={"/dev/dvb/adapter0/demux0","/dev/dvb/adapter1/demux0","/dev/dvb/adapter2/demux0","/dev/dvb/adapter3/demux0"};
+	char* secdev[4]={"","","",""};	//UNUSED, ONLY FOR UNIFORMITY
+#else
+	#include <ost/dmx.h>
+	#include <ost/sec.h>
+	#include <ost/frontend.h>
+	char* frontenddev[4]={"/dev/ost/frontend0","/dev/ost/frontend1","/dev/ost/frontend2","/dev/ost/frontend3"};
+	char* dvrdev[4]={"/dev/ost/dvr0","/dev/ost/dvr1","/dev/ost/dvr2","/dev/ost/dvr3"};
+	char* secdev[4]={"/dev/ost/sec0","/dev/ost/sec1","/dev/ost/sec2","/dev/ost/sec3"};
+	char* demuxdev[4]={"/dev/ost/demux0","/dev/ost/demux1","/dev/ost/demux2","/dev/ost/demux3"};
+#endif
+
+#include "dvbin.h"
+#include "dvb_defaults.h"
+#include "../mp_msg.h"
+
+
+extern int card;
+
+int open_fe(int* fd_frontend, int* fd_sec)
+{
+	if((*fd_frontend = open(frontenddev[card], O_RDWR)) < 0)
+	{
+		perror("ERROR IN OPENING FRONTEND DEVICE: ");
+		return -1;
+	}
+#ifdef HAVE_DVB_HEAD
+    	fd_sec=0;
+#else
+	if (fd_sec != 0)
+	{
+      		if((*fd_sec = open(secdev[card], O_RDWR)) < 0)
+      		{
+          		perror("ERROR IN OPENING SEC DEVICE: ");
+          		return -1;
+      		}
+    	}
+#endif
+    	return 1;
+}
+
+
+
+int set_ts_filt(int fd, uint16_t pid, dmx_pes_type_t pestype)
+{
+	int i;
+	struct dmx_pes_filter_params pesFilterParams;
+
+	pesFilterParams.pid     = pid;
+	pesFilterParams.input   = DMX_IN_FRONTEND;
+	pesFilterParams.output  = DMX_OUT_TS_TAP;
+#ifdef HAVE_DVB_HEAD
+	pesFilterParams.pes_type = pestype;
+#else
+	pesFilterParams.pesType = pestype;
+#endif
+
+	//pesFilterParams.pesType = pestype;
+
+	pesFilterParams.flags   = DMX_IMMEDIATE_START;
+
+	if ((i = ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams)) < 0)
+	{
+		mp_msg(MSGT_DEMUX, MSGL_DBG2, "ERROR IN SETTING DMX_FILTER %i: ", pid);
+	}
+
+	mp_msg(MSGT_DEMUX, MSGL_V, "SET PES FILTER ON PID %d, RESULT: %d\n", pid, i );
+	return 1;
+}
+
+
+int demux_stop(int fd)
+{
+	int i;
+	i = ioctl(fd, DMX_STOP);
+
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "STOPPING FD: %d, RESULT: %d\n", fd, i);
+
+	return (i==0);
+}
+
+
+
+void make_nonblock(int f)
+{
+	int oldflags;
+
+	if ((oldflags=fcntl(f, F_GETFL, 0)) < 0)
+	{
+		perror("ERROR IN F_GETFL");
+	}
+
+	oldflags|=O_NONBLOCK;
+	if (fcntl(f, F_SETFL, oldflags) < 0)
+	{
+		perror("F_SETFL");
+	}
+}
+
+
+static int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone,
+	fe_spectral_inversion_t specInv, unsigned int diseqc, fe_modulation_t modulation, fe_code_rate_t HP_CodeRate,
+	fe_transmit_mode_t TransmissionMode, fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth);
+
+
+//int dvb_tune(dvb_priv_t *priv, int freq, char pol, int srate, int diseqc, int tone)
+dvb_tune(dvb_priv_t *priv, int freq, char pol, int srate, int diseqc, int tone,
+		fe_spectral_inversion_t specInv, fe_modulation_t modulation, fe_guard_interval_t guardInterval,
+		fe_transmit_mode_t TransmissionMode, fe_bandwidth_t bandWidth, fe_code_rate_t HP_CodeRate)
+{
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "dvb_tune con Freq: %lu, pol: %c, srate: %lu, diseqc %d, tone %d\n", freq, pol, srate, diseqc, tone);
+	/* INPUT: frequency, polarization, srate */
+	if(freq > 100000000)
+	{
+		if(open_fe(&(priv->fe_fd), 0))
+		{
+		      //tune_it(fd_frontend, 0, freq, 0, 0, tone, specInv, diseqc,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth);
+			tune_it(priv->fe_fd, 0, freq, 0, 0, tone, specInv, diseqc, modulation, HP_CodeRate, TransmissionMode, guardInterval, bandWidth);
+
+			close(priv->fe_fd);
+		}
+		else
+			return 0;
+	}
+	else if ((freq != 0) && (pol != 0) && (srate != 0))
+	{
+		if (open_fe(&(priv->fe_fd), &(priv->sec_fd)))
+		{
+			tune_it(priv->fe_fd, priv->sec_fd, freq, srate, pol, tone, specInv, diseqc, modulation, HP_CodeRate, TransmissionMode, guardInterval, bandWidth);
+			close(priv->fe_fd);
+			close(priv->sec_fd);
+		}
+		else
+			return 0;
+	}
+
+	priv->channel.freq = freq;
+	priv->channel.srate = srate;
+	priv->channel.pol = pol;
+	priv->channel.diseqc = diseqc;
+	priv->channel.tone = tone;
+	priv->channel.inv = specInv;
+	priv->channel.mod = modulation;
+	priv->channel.gi = guardInterval;
+	priv->channel.trans = TransmissionMode;
+	priv->channel.bw = bandWidth;
+	priv->channel.cr = HP_CodeRate;
+
+	return 1;
+}
+
+
+
+
+
+#ifndef HAVE_DVB_HEAD
+static int OSTSelftest(int fd)
+{
+    int ans;
+
+    if ((ans = ioctl(fd, FE_SELFTEST,0) < 0))
+    {
+        mp_msg(MSGT_DEMUX, MSGL_ERR, "FE SELF TEST: ");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int OSTSetPowerState(int fd, uint32_t state)
+{
+    int ans;
+
+    if ((ans = ioctl(fd,FE_SET_POWER_STATE,state) < 0))
+    {
+        mp_msg(MSGT_DEMUX, MSGL_ERR, "OST SET POWER STATE: ");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int OSTGetPowerState(int fd, uint32_t *state)
+{
+    int ans;
+
+    if ((ans = ioctl(fd,FE_GET_POWER_STATE,state) < 0))
+    {
+        mp_msg(MSGT_DEMUX, MSGL_ERR, "OST GET POWER STATE: ");
+        return -1;
+    }
+
+    switch(*state)
+    {
+	case FE_POWER_ON:
+    	    mp_msg(MSGT_DEMUX, MSGL_V, "POWER ON (%d)\n",*state);
+    	    break;
+	case FE_POWER_STANDBY:
+    	    mp_msg(MSGT_DEMUX, MSGL_V, "POWER STANDBY (%d)\n",*state);
+    	    break;
+	case FE_POWER_SUSPEND:
+    	    mp_msg(MSGT_DEMUX, MSGL_V, "POWER SUSPEND (%d)\n",*state);
+    	    break;
+	case FE_POWER_OFF:
+    	    mp_msg(MSGT_DEMUX, MSGL_V, "POWER OFF (%d)\n",*state);
+    	    break;
+	default:
+    	    mp_msg(MSGT_DEMUX, MSGL_V, "unknown (%d)\n",*state);
+    	break;
+    }
+
+    return 0;
+}
+
+
+static int SecGetStatus (int fd, struct secStatus *state)
+{
+    int ans;
+
+    if ((ans = ioctl(fd, SEC_GET_STATUS, state) < 0))
+    {
+        mp_msg(MSGT_DEMUX, MSGL_ERR, ("SEC GET STATUS: "));
+        return -1;
+    }
+
+    switch (state->busMode)
+    {
+	case SEC_BUS_IDLE:
+    	    mp_msg(MSGT_DEMUX, MSGL_V, "SEC BUS MODE:  IDLE (%d)\n",state->busMode);
+    	    break;
+	case SEC_BUS_BUSY:
+    	    mp_msg(MSGT_DEMUX, MSGL_V, "SEC BUS MODE:  BUSY (%d)\n",state->busMode);
+	    break;
+        case SEC_BUS_OFF:
+	    mp_msg(MSGT_DEMUX, MSGL_V, "SEC BUS MODE:  OFF  (%d)\n",state->busMode);
+    	    break;
+        case SEC_BUS_OVERLOAD:
+	    mp_msg(MSGT_DEMUX, MSGL_V, "SEC BUS MODE:  OVERLOAD (%d)\n",state->busMode);
+    	    break;
+	default:
+    	    mp_msg(MSGT_DEMUX, MSGL_V, "SEC BUS MODE:  unknown  (%d)\n",state->busMode);
+            break;
+    }
+
+    switch (state->selVolt)
+    {
+	case SEC_VOLTAGE_OFF:
+		mp_msg(MSGT_DEMUX, MSGL_V, "SEC VOLTAGE:  OFF (%d)\n",state->selVolt);
+		break;
+	case SEC_VOLTAGE_LT:
+		mp_msg(MSGT_DEMUX, MSGL_V, "SEC VOLTAGE:  LT  (%d)\n",state->selVolt);
+		break;
+	case SEC_VOLTAGE_13:
+		mp_msg(MSGT_DEMUX, MSGL_V, "SEC VOLTAGE:  13  (%d)\n",state->selVolt);
+		break;
+	case SEC_VOLTAGE_13_5:
+		mp_msg(MSGT_DEMUX, MSGL_V, "SEC VOLTAGE:  13.5 (%d)\n",state->selVolt);
+		break;
+	case SEC_VOLTAGE_18:
+		mp_msg(MSGT_DEMUX, MSGL_V, "SEC VOLTAGE:  18 (%d)\n",state->selVolt);
+		break;
+	case SEC_VOLTAGE_18_5:
+		mp_msg(MSGT_DEMUX, MSGL_V, "SEC VOLTAGE:  18.5 (%d)\n",state->selVolt);
+		break;
+	default:
+		mp_msg(MSGT_DEMUX, MSGL_V, "SEC VOLTAGE:  unknown (%d)\n",state->selVolt);
+		break;
+    }
+
+ 	mp_msg(MSGT_DEMUX, MSGL_V, "SEC CONT TONE: %s\n", (state->contTone == SEC_TONE_ON ? "ON" : "OFF"));
+    return 0;
+}
+
+#endif
+
+static void print_status(fe_status_t festatus)
+{
+	mp_msg(MSGT_DEMUX, MSGL_V, "FE_STATUS:");
+	if (festatus & FE_HAS_SIGNAL) mp_msg(MSGT_DEMUX, MSGL_V," FE_HAS_SIGNAL");
+#ifdef HAVE_DVB_HEAD
+	if (festatus & FE_TIMEDOUT) mp_msg(MSGT_DEMUX, MSGL_V, " FE_TIMEDOUT");
+#else
+	if (festatus & FE_HAS_POWER) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_POWER");
+	if (festatus & FE_SPECTRUM_INV) mp_msg(MSGT_DEMUX, MSGL_V, " FE_SPECTRUM_INV");
+	if (festatus & FE_TUNER_HAS_LOCK) mp_msg(MSGT_DEMUX, MSGL_V, " FE_TUNER_HAS_LOCK");
+#endif
+	if (festatus & FE_HAS_LOCK) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_LOCK");
+	if (festatus & FE_HAS_CARRIER) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_CARRIER");
+	if (festatus & FE_HAS_VITERBI) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_VITERBI");
+	if (festatus & FE_HAS_SYNC) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_SYNC");
+	mp_msg(MSGT_DEMUX, MSGL_V, "\n");
+}
+
+
+#ifdef HAVE_DVB_HEAD
+static int check_status(int fd_frontend,struct dvb_frontend_parameters* feparams,int tone)
+{
+	int i,res;
+	int32_t strength;
+	fe_status_t festatus;
+	struct dvb_frontend_event event;
+	struct dvb_frontend_info fe_info;
+	struct pollfd pfd[1];
+
+	if (ioctl(fd_frontend,FE_SET_FRONTEND,feparams) < 0)
+	{
+	mp_msg(MSGT_DEMUX, MSGL_ERR, "ERROR tuning channel\n");
+	return -1;
+	}
+
+	pfd[0].fd = fd_frontend;
+	pfd[0].events = POLLIN;
+
+	event.status=0;
+	while (((event.status & FE_TIMEDOUT)==0) && ((event.status & FE_HAS_LOCK)==0))
+	{
+		mp_msg(MSGT_DEMUX, MSGL_V, "polling....\n");
+		if (poll(pfd,1,10000))
+		{
+			if (pfd[0].revents & POLLIN)
+			{
+				mp_msg(MSGT_DEMUX, MSGL_V, "Getting frontend event\n");
+				if ( ioctl(fd_frontend, FE_GET_EVENT, &event) < 0)
+				{
+					mp_msg(MSGT_DEMUX, MSGL_ERR, "FE_GET_EVENT");
+					return -1;
+				}
+			}
+			print_status(event.status);
+		}
+	}
+
+	if (event.status & FE_HAS_LOCK)
+	{
+		switch(fe_info.type)
+		{
+			case FE_OFDM:
+			mp_msg(MSGT_DEMUX, MSGL_V, "Event:  Frequency: %d\n",event.parameters.frequency);
+			break;
+			case FE_QPSK:
+			mp_msg(MSGT_DEMUX, MSGL_V, "Event:  Frequency: %d\n",(unsigned int)((event.parameters.frequency)+(tone==SEC_TONE_OFF ? LOF1 : LOF2)));
+			mp_msg(MSGT_DEMUX, MSGL_V, "        SymbolRate: %d\n",event.parameters.u.qpsk.symbol_rate);
+			mp_msg(MSGT_DEMUX, MSGL_V, "        FEC_inner:  %d\n",event.parameters.u.qpsk.fec_inner);
+			mp_msg(MSGT_DEMUX, MSGL_V, "\n");
+			break;
+			case FE_QAM:
+			mp_msg(MSGT_DEMUX, MSGL_V, "Event:  Frequency: %d\n",event.parameters.frequency);
+			mp_msg(MSGT_DEMUX, MSGL_V, "        SymbolRate: %d\n",event.parameters.u.qpsk.symbol_rate);
+			mp_msg(MSGT_DEMUX, MSGL_V, "        FEC_inner:  %d\n",event.parameters.u.qpsk.fec_inner);
+			break;
+			default:
+			break;
+		}
+
+		strength=0;
+		ioctl(fd_frontend,FE_READ_BER,&strength);
+		mp_msg(MSGT_DEMUX, MSGL_V, "Bit error rate: %d\n",strength);
+
+		strength=0;
+		ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength);
+		mp_msg(MSGT_DEMUX, MSGL_V, "Signal strength: %d\n",strength);
+
+		strength=0;
+		ioctl(fd_frontend,FE_READ_SNR,&strength);
+		mp_msg(MSGT_DEMUX, MSGL_V, "SNR: %d\n",strength);
+
+		festatus=0;
+		ioctl(fd_frontend,FE_READ_STATUS,&festatus);
+		print_status(festatus);
+	}
+	else
+	{
+		mp_msg(MSGT_DEMUX, MSGL_V, "Not able to lock to the signal on the given frequency\n");
+		return -1;
+	}
+	return 0;
+}
+
+#else
+
+static int check_status(int fd_frontend,FrontendParameters* feparams,int tone)
+{
+	int i,res;
+	int32_t strength;
+	fe_status_t festatus;
+	FrontendEvent event;
+	FrontendInfo fe_info;
+	struct pollfd pfd[1];
+
+	i = 0; res = -1;
+	while ((i < 3) && (res < 0))
+	{
+		if (ioctl(fd_frontend,FE_SET_FRONTEND,feparams) < 0)
+		{
+			mp_msg(MSGT_DEMUX, MSGL_ERR, "ERROR tuning channel\n");
+			return -1;
+		}
+
+		pfd[0].fd = fd_frontend;
+		pfd[0].events = POLLIN;
+
+		if (poll(pfd,1,10000))
+		{
+			if (pfd[0].revents & POLLIN)
+			{
+				mp_msg(MSGT_DEMUX, MSGL_V, "Getting frontend event\n");
+				if ( ioctl(fd_frontend, FE_GET_EVENT, &event) < 0)
+				{
+					mp_msg(MSGT_DEMUX, MSGL_ERR, "FE_GET_EVENT");
+					return -1;
+				}
+				mp_msg(MSGT_DEMUX, MSGL_V, "Received ");
+				switch(event.type)
+				{
+					case FE_UNEXPECTED_EV:
+					mp_msg(MSGT_DEMUX, MSGL_V, "unexpected event\n");
+					res = -1;
+					break;
+
+					case FE_FAILURE_EV:
+					mp_msg(MSGT_DEMUX, MSGL_V, "failure event\n");
+					res = -1;
+					break;
+
+					case FE_COMPLETION_EV:
+					mp_msg(MSGT_DEMUX, MSGL_V, "completion event\n");
+					res = 0;
+					break;
+				}
+			}
+			i++;
+		}
+	}
+
+	if (res > 0)
+	switch (event.type)
+	{
+		case FE_UNEXPECTED_EV: mp_msg(MSGT_DEMUX, MSGL_V, "FE_UNEXPECTED_EV\n");
+			break;
+		case FE_COMPLETION_EV: mp_msg(MSGT_DEMUX, MSGL_V, "FE_COMPLETION_EV\n");
+			break;
+		case FE_FAILURE_EV: mp_msg(MSGT_DEMUX, MSGL_V, "FE_FAILURE_EV\n");
+			break;
+	}
+
+	if (event.type == FE_COMPLETION_EV)
+	{
+		switch(fe_info.type)
+		{
+			case FE_OFDM:
+			mp_msg(MSGT_DEMUX, MSGL_V, "Event:  Frequency: %d\n",event.u.completionEvent.Frequency);
+			break;
+
+			case FE_QPSK:
+			mp_msg(MSGT_DEMUX, MSGL_V, "Event:  Frequency: %d\n",(unsigned int)((event.u.completionEvent.Frequency)+(tone==SEC_TONE_OFF ? LOF1 : LOF2)));
+			mp_msg(MSGT_DEMUX, MSGL_V, "        SymbolRate: %d\n",event.u.completionEvent.u.qpsk.SymbolRate);
+			mp_msg(MSGT_DEMUX, MSGL_V, "        FEC_inner:  %d\n",event.u.completionEvent.u.qpsk.FEC_inner);
+			mp_msg(MSGT_DEMUX, MSGL_V, "\n");
+			break;
+
+			case FE_QAM:
+			mp_msg(MSGT_DEMUX, MSGL_V, "Event:  Frequency: %d\n",event.u.completionEvent.Frequency);
+			mp_msg(MSGT_DEMUX, MSGL_V, "        SymbolRate: %d\n",event.u.completionEvent.u.qpsk.SymbolRate);
+			mp_msg(MSGT_DEMUX, MSGL_V, "        FEC_inner:  %d\n",event.u.completionEvent.u.qpsk.FEC_inner);
+			break;
+
+			default:
+			break;
+		}
+
+		strength=0;
+		ioctl(fd_frontend,FE_READ_BER,&strength);
+		mp_msg(MSGT_DEMUX, MSGL_V, "Bit error rate: %d\n",strength);
+
+		strength=0;
+		ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength);
+		mp_msg(MSGT_DEMUX, MSGL_V, "Signal strength: %d\n",strength);
+
+		strength=0;
+		ioctl(fd_frontend,FE_READ_SNR,&strength);
+		mp_msg(MSGT_DEMUX, MSGL_V, "SNR: %d\n",strength);
+
+		festatus=0;
+		ioctl(fd_frontend,FE_READ_STATUS,&festatus);
+
+		mp_msg(MSGT_DEMUX, MSGL_V, "FE_STATUS:");
+		if (festatus & FE_HAS_POWER) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_POWER");
+		if (festatus & FE_HAS_SIGNAL) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_SIGNAL");
+		if (festatus & FE_SPECTRUM_INV) mp_msg(MSGT_DEMUX, MSGL_V, " FE_SPECTRUM_INV");
+		if (festatus & FE_HAS_LOCK) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_LOCK");
+		if (festatus & FE_HAS_CARRIER) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_CARRIER");
+		if (festatus & FE_HAS_VITERBI) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_VITERBI");
+		if (festatus & FE_HAS_SYNC) mp_msg(MSGT_DEMUX, MSGL_V, " FE_HAS_SYNC");
+		if (festatus & FE_TUNER_HAS_LOCK) mp_msg(MSGT_DEMUX, MSGL_V, " FE_TUNER_HAS_LOCK");
+		mp_msg(MSGT_DEMUX, MSGL_V, "\n");
+	}
+	else
+	{
+		mp_msg(MSGT_DEMUX, MSGL_V, "Not able to lock to the signal on the given frequency\n");
+		return -1;
+	}
+	return 0;
+}
+#endif
+
+#ifdef HAVE_DVB_HEAD
+
+struct diseqc_cmd {
+   struct dvb_diseqc_master_cmd cmd;
+   uint32_t wait;
+};
+
+static void diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
+		     fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
+{
+   ioctl(fd, FE_SET_TONE, SEC_TONE_OFF);
+   ioctl(fd, FE_SET_VOLTAGE, v);
+   usleep(15 * 1000);
+   ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd);
+   usleep(cmd->wait * 1000);
+   usleep(15 * 1000);
+   ioctl(fd, FE_DISEQC_SEND_BURST, b);
+   usleep(15 * 1000);
+   ioctl(fd, FE_SET_TONE, t);
+}
+
+
+
+
+/* digital satellite equipment control,
+ * specification is available from http://www.eutelsat.com/
+ */
+static int head_diseqc(int secfd, int sat_no, int pol, int hi_lo)
+{
+   struct diseqc_cmd cmd =  { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
+
+   /* param: high nibble: reset bits, low nibble set bits,
+    * bits are: option, position, polarizaion, band
+    */
+   cmd.cmd.msg[3] =
+       0xf0 | (((sat_no * 4) & 0x0f) | (hi_lo ? 1 : 0) | (pol ? 0 : 2));
+
+   diseqc_send_msg(secfd, pol ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18,
+		   &cmd, hi_lo ? SEC_TONE_ON : SEC_TONE_OFF,
+		   (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A);
+
+   return 1;
+}
+
+#endif
+
+
+static int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone,
+	fe_spectral_inversion_t specInv, unsigned int diseqc, fe_modulation_t modulation, fe_code_rate_t HP_CodeRate,
+	fe_transmit_mode_t TransmissionMode, fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth)
+{
+  int res;
+#ifdef HAVE_DVB_HEAD
+  struct dvb_frontend_parameters feparams;
+  struct dvb_frontend_info fe_info;
+  fe_sec_voltage_t voltage;
+#else
+  FrontendParameters feparams;
+  FrontendInfo fe_info;
+  secVoltage voltage;
+  struct secStatus sec_state;
+#endif
+
+
+  mp_msg(MSGT_DEMUX, MSGL_V,  "TUNE_IT, fd_frontend %d, fd_sec %d, freq %lu, srate %lu, pol %c, tone %i, specInv, diseqc %u, fe_modulation_t modulation,fe_code_rate_t HP_CodeRate, fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth\n",
+	    fd_frontend, fd_sec, freq, srate, pol, tone, diseqc);
+
+
+  if ( (res = ioctl(fd_frontend,FE_GET_INFO, &fe_info) < 0))
+  {
+  	mp_msg(MSGT_DEMUX, MSGL_ERR, "FE_GET_INFO: ");
+	return -1;
+  }
+
+
+#ifdef HAVE_DVB_HEAD
+  mp_msg(MSGT_DEMUX, MSGL_V, "Using DVB card \"%s\"\n",fe_info.name);
+#endif
+
+  switch(fe_info.type)
+  {
+    case FE_OFDM:
+#ifdef HAVE_DVB_HEAD
+      if (freq < 1000000) freq*=1000UL;
+      feparams.frequency=freq;
+      feparams.inversion=INVERSION_OFF;
+      feparams.u.ofdm.bandwidth=bandwidth;
+      feparams.u.ofdm.code_rate_HP=HP_CodeRate;
+      feparams.u.ofdm.code_rate_LP=LP_CODERATE_DEFAULT;
+      feparams.u.ofdm.constellation=modulation;
+      feparams.u.ofdm.transmission_mode=TransmissionMode;
+      feparams.u.ofdm.guard_interval=guardInterval;
+      feparams.u.ofdm.hierarchy_information=HIERARCHY_DEFAULT;
+#else
+      if (freq < 1000000) freq*=1000UL;
+      feparams.Frequency=freq;
+      feparams.Inversion=INVERSION_OFF;
+      feparams.u.ofdm.bandWidth=bandwidth;
+      feparams.u.ofdm.HP_CodeRate=HP_CodeRate;
+      feparams.u.ofdm.LP_CodeRate=LP_CODERATE_DEFAULT;
+      feparams.u.ofdm.Constellation=modulation;
+      feparams.u.ofdm.TransmissionMode=TransmissionMode;
+      feparams.u.ofdm.guardInterval=guardInterval;
+      feparams.u.ofdm.HierarchyInformation=HIERARCHY_DEFAULT;
+#endif
+      mp_msg(MSGT_DEMUX, MSGL_V, "tuning DVB-T (%s) to %d Hz\n",DVB_T_LOCATION,freq);
+      break;
+    case FE_QPSK:
+#ifdef HAVE_DVB_HEAD
+      mp_msg(MSGT_DEMUX, MSGL_V, "tuning DVB-S to L-Band:%d, Pol:%c Srate=%d, 22kHz=%s\n",feparams.frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off");
+#else
+      mp_msg(MSGT_DEMUX, MSGL_V, "tuning DVB-S to L-Band:%d, Pol:%c Srate=%d, 22kHz=%s\n",feparams.Frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off");
+#endif
+      if ((pol=='h') || (pol=='H'))
+      {
+        voltage = SEC_VOLTAGE_18;
+      }
+      else
+      {
+        voltage = SEC_VOLTAGE_13;
+      }
+#ifdef HAVE_DVB_HEAD
+      if (ioctl(fd_frontend,FE_SET_VOLTAGE,voltage) < 0)
+      {
+#else
+      if (ioctl(fd_sec,SEC_SET_VOLTAGE,voltage) < 0)
+      {
+#endif
+         mp_msg(MSGT_DEMUX, MSGL_ERR, "ERROR setting voltage\n");
+      }
+
+      if (freq > 2200000)
+      {
+        // this must be an absolute frequency
+        if (freq < SLOF)
+	{
+#ifdef HAVE_DVB_HEAD
+          feparams.frequency=(freq-LOF1);
+#else
+          feparams.Frequency=(freq-LOF1);
+#endif
+          if (tone < 0) tone = SEC_TONE_OFF;
+        }
+	else
+	{
+#ifdef HAVE_DVB_HEAD
+          feparams.frequency=(freq-LOF2);
+#else
+          feparams.Frequency=(freq-LOF2);
+#endif
+          if (tone < 0) tone = SEC_TONE_ON;
+        }
+      }
+      else
+      {
+        // this is an L-Band frequency
+#ifdef HAVE_DVB_HEAD
+       feparams.frequency=freq;
+#else
+       feparams.Frequency=freq;
+#endif
+      }
+
+#ifdef HAVE_DVB_HEAD
+      feparams.inversion=specInv;
+      feparams.u.qpsk.symbol_rate=srate;
+      feparams.u.qpsk.fec_inner=FEC_AUTO;
+#else
+      feparams.Inversion=specInv;
+      feparams.u.qpsk.SymbolRate=srate;
+      feparams.u.qpsk.FEC_inner=FEC_AUTO;
+#endif
+
+#ifdef HAVE_DVB_HEAD
+      if (ioctl(fd_frontend, FE_SET_TONE,tone) < 0)
+      {
+         mp_msg(MSGT_DEMUX, MSGL_ERR, "ERROR setting tone\n");
+      }
+#else
+      if (ioctl(fd_sec, SEC_SET_TONE,tone) < 0)
+      {
+         mp_msg(MSGT_DEMUX, MSGL_ERR, "ERROR setting tone\n");
+      }
+#endif
+
+#ifdef HAVE_DVB_HEAD
+  //#warning DISEQC is unimplemented for HAVE_DVB_HEAD
+  if(diseqc > 0)
+  {
+    int ipol = (pol == 'V' ? 1 : 0);
+    int hiband = (freq >= SLOF);
+
+   if(head_diseqc(fd_frontend, diseqc-1, ipol, hiband))
+   {
+	mp_msg(MSGT_DEMUX, MSGL_V, "DISEQC SETTING SUCCEDED\n");
+   }
+   else
+   {
+	mp_msg(MSGT_DEMUX, MSGL_V, "DISEQC SETTING FAILED\n");
+   }
+  }
+#else
+      if (diseqc > 0)
+      {
+        struct secCommand scmd;
+        struct secCmdSequence scmds;
+
+        scmds.continuousTone = tone;
+        scmds.voltage = voltage;
+        /*
+        scmds.miniCommand = toneBurst ? SEC_MINI_B : SEC_MINI_A;
+        */
+        scmds.miniCommand = SEC_MINI_NONE;
+
+        scmd.type = 0;
+        scmds.numCommands = 1;
+        scmds.commands = &scmd;
+
+        scmd.u.diseqc.addr = 0x10;
+        scmd.u.diseqc.cmd = 0x38;
+        scmd.u.diseqc.numParams = 1;
+        scmd.u.diseqc.params[0] = 0xf0 |
+                                  (((diseqc - 1) << 2) & 0x0c) |
+                                  (voltage==SEC_VOLTAGE_18 ? 0x02 : 0) |
+                                  (tone==SEC_TONE_ON ? 0x01 : 0);
+
+        if (ioctl(fd_sec,SEC_SEND_SEQUENCE,&scmds) < 0)
+	{
+          mp_msg(MSGT_DEMUX, MSGL_ERR, "Error sending DisEqC");
+          return -1;
+        }
+      }
+#endif
+      break;
+    case FE_QAM:
+      mp_msg(MSGT_DEMUX, MSGL_V, "tuning DVB-C to %d, srate=%d\n",freq,srate);
+#ifdef HAVE_DVB_HEAD
+      feparams.frequency=freq;
+      feparams.inversion=INVERSION_OFF;
+      feparams.u.qam.symbol_rate = srate;
+      feparams.u.qam.fec_inner = FEC_AUTO;
+      feparams.u.qam.modulation = QAM_64;
+#else
+      feparams.Frequency=freq;
+      feparams.Inversion=INVERSION_OFF;
+      feparams.u.qam.SymbolRate = srate;
+      feparams.u.qam.FEC_inner = FEC_AUTO;
+      feparams.u.qam.QAM = QAM_64;
+#endif
+      break;
+    default:
+      mp_msg(MSGT_DEMUX, MSGL_V, "Unknown FE type. Aborting\n");
+      exit(-1);
+  }
+  usleep(100000);
+
+#ifndef HAVE_DVB_HEAD
+  if (fd_sec) SecGetStatus(fd_sec, &sec_state);
+#endif
+
+  return(check_status(fd_frontend,&feparams,tone));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpdemux/dvbin.c	Sun Mar 16 20:13:28 2003 +0000
@@ -0,0 +1,684 @@
+/*
+
+dvbstream
+(C) Dave Chapman <dave@dchapman.com> 2001, 2002.
+
+The latest version can be found at http://www.linuxstb.org/dvbstream
+
+Copyright notice:
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+// Linux includes:
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <resolv.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <values.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "config.h"
+
+// DVB includes:
+
+#include "stream.h"
+#include "demuxer.h"
+
+#include "../cfgparser.h"
+
+#include "dvbin.h"
+#include "dvb_defaults.h"
+
+extern int video_id, audio_id, demuxer_type;
+
+
+#define MAX_CHANNELS 8
+
+
+#define min(a, b) ((a) <= (b) ? (a) : (b))
+
+int dvbin_param_card, dvbin_param_freq, dvbin_param_srate, dvbin_param_diseqc = 0,
+	dvbin_param_tone = -1, dvbin_param_vid, dvbin_param_aid, dvbin_is_active = 0;
+int dvbin_param_mod, dvbin_param_gi, dvbin_param_tm, dvbin_param_bw, dvbin_param_cr;
+char *dvbin_param_pol = "", *dvbin_param_inv="INVERSION_AUTO",
+    *dvbin_param_type="SAT                                                                                          ",
+    *dvbin_param_prog = "                                                                                           ";
+dvb_history_t dvb_prev_next;
+
+struct config dvbin_opts_conf[] = {
+        {"on", &dvbin_param_on, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"type", &dvbin_param_type, CONF_TYPE_STRING, 0, 0, 1, NULL},
+        {"card", &dvbin_param_card, CONF_TYPE_INT, CONF_RANGE, 1, 4, NULL},
+        {"freq", &dvbin_param_freq, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"pol", &dvbin_param_pol, CONF_TYPE_STRING, 0, 0, 0, NULL},
+        {"srate", &dvbin_param_srate, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"diseqc", &dvbin_param_diseqc, CONF_TYPE_INT, CONF_RANGE, 1, 4,  NULL},
+        {"tone", &dvbin_param_tone, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"vid", &dvbin_param_vid, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"aid", &dvbin_param_aid, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"prog", &dvbin_param_prog, CONF_TYPE_STRING, 0, 0, 0, NULL},
+        {"inv", &dvbin_param_inv, CONF_TYPE_STRING, 0, 0, 0, NULL},
+        {"mod", &dvbin_param_mod, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"gi", &dvbin_param_gi, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"tm", &dvbin_param_tm, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"bw", &dvbin_param_bw, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {"cr", &dvbin_param_cr, CONF_TYPE_INT, 0, 0, 1, NULL},
+        {NULL, NULL, 0, 0, 0, 0, NULL}
+};
+
+
+int card=0;
+
+extern int open_fe(int* fd_frontend, int* fd_sec);
+extern int set_ts_filt(int fd, uint16_t pid, dmx_pes_type_t pestype);
+extern int demux_stop(int fd);
+extern void make_nonblock(int f);
+extern int dvb_tune(dvb_priv_t *priv, int freq, char pol, int srate, int diseqc, int tone,
+		fe_spectral_inversion_t specInv, fe_modulation_t modulation, fe_guard_interval_t guardInterval,
+		fe_transmit_mode_t TransmissionMode, fe_bandwidth_t bandWidth, fe_code_rate_t HP_CodeRate);
+extern char *frontenddev[4], *dvrdev[4], *secdev[4], *demuxdev[4];
+
+
+dvb_channels_list *dvb_get_channels(char *filename, const char *type)
+{
+	dvb_channels_list  *list;
+	FILE *f;
+	uint8_t line[128];
+	int fields, row_count;
+	dvb_channel_t *ptr;
+	char *tmp_lcr, *tmp_hier, *inv, *bw, *cr, *mod, *transm, *gi;
+	//const char *cbl_conf = "%a[^:]:%d:%c:%d:%a[^:]:%a[^:]:%d:%d\n";
+	const char *sat_conf = "%a[^:]:%d:%c:%d:%d:%d:%d:%d:%d:%d\n";
+	const char *ter_conf = "%a[^:]:%d:%a[^:]:%a[^:]:%a[^:]:%a[^:]:%a[^:]:%a[^:]:%a[^:]:%a[^:]:%d:%d\n";
+
+	list = malloc(sizeof(dvb_channels_list));
+	if(list == NULL)
+	{
+		mp_msg(MSGT_DEMUX, MSGL_V, "DVB_GET_CHANNELS: couldn't malloc enough memory\n");
+		return NULL;
+	}
+
+	mp_msg(MSGT_DEMUX, MSGL_V, "CONFIG_READ FILE: %s, type: %s\n", filename, type);
+	if((f=fopen(filename, "r"))==NULL)
+	{
+		mp_msg(MSGT_DEMUX, MSGL_FATAL, "CAN'T READ CONFIG FILE %s\n", filename);
+		return NULL;
+	}
+
+	list->NUM_CHANNELS = 0;
+	row_count = 0;
+	while(! feof(f) && row_count < 512)
+	{
+		if( fgets(line, 128, f) == NULL ) continue;
+
+		if(line[0] == '#')
+			continue;	//comment line
+
+		ptr =  &(list->channels[ list->NUM_CHANNELS ]);
+
+		if(! strcmp(type, "TER"))
+		{
+			fields = sscanf(line, ter_conf,
+				&ptr->name, &ptr->freq, &inv, &bw, &cr, tmp_lcr, &mod,
+				&transm, &gi, &tmp_hier, &ptr->vpid, &ptr->apid1);
+
+			if(! strcmp(inv, "INVERSION_ON"))
+				ptr->inv = INVERSION_ON;
+			else if(! strcmp(inv, "INVERSION_OFF"))
+				ptr->inv = INVERSION_OFF;
+			else
+				ptr->inv = INVERSION_AUTO;
+
+			if(! strcmp(bw, "BANDWIDTH_6_MHZ"))
+				ptr->bw = BANDWIDTH_6_MHZ;
+			else if(! strcmp(bw, "BANDWIDTH_7_MHZ"))
+				ptr->bw = BANDWIDTH_7_MHZ;
+			else if(! strcmp(bw, "BANDWIDTH_8_MHZ"))
+				ptr->bw = BANDWIDTH_8_MHZ;
+
+
+			if(! strcmp(cr, "FEC_1_2"))
+				ptr->cr =FEC_1_2;
+			else if(! strcmp(cr, "FEC_2_3"))
+				ptr->cr =FEC_2_3;
+			else if(! strcmp(cr, "FEC_3_4"))
+				ptr->cr =FEC_3_4;
+#ifdef HAVE_DVB_HEAD
+			else if(! strcmp(cr, "FEC_4_5"))
+				ptr->cr =FEC_4_5;
+			else if(! strcmp(cr, "FEC_6_7"))
+				ptr->cr =FEC_6_7;
+			else if(! strcmp(cr, "FEC_8_9"))
+				ptr->cr =FEC_8_9;
+#endif
+			else if(! strcmp(cr, "FEC_5_6"))
+				ptr->cr =FEC_5_6;
+			else if(! strcmp(cr, "FEC_7_8"))
+				ptr->cr =FEC_7_8;
+			else if(! strcmp(cr, "FEC_NONE"))
+				ptr->cr =FEC_NONE;
+			else ptr->cr =FEC_AUTO;
+
+			if(! strcmp(mod, "QAM_128"))
+				ptr->mod = QAM_128;
+			else if(! strcmp(mod, "QAM_256"))
+				ptr->mod = QAM_256;
+			else if(! strcmp(mod, "QAM_64"))
+				ptr->mod = QAM_64;
+			else if(! strcmp(mod, "QAM_32"))
+				ptr->mod = QAM_32;
+			else if(! strcmp(mod, "QAM_16"))
+				ptr->mod = QAM_16;
+			else ptr->mod = QPSK;
+
+
+			if(! strcmp(transm, "TRANSMISSION_MODE_2K"))
+				ptr->trans = TRANSMISSION_MODE_2K;
+			else if(! strcmp(transm, "TRANSMISSION_MODE_8K"))
+				ptr->trans = TRANSMISSION_MODE_8K;
+
+			if(! strcmp(gi, "GUARD_INTERVAL_1_32"))
+				ptr->gi = GUARD_INTERVAL_1_32;
+			else if(! strcmp(gi, "GUARD_INTERVAL_1_16"))
+				ptr->gi = GUARD_INTERVAL_1_16;
+			else if(! strcmp(gi, "GUARD_INTERVAL_1_8"))
+				ptr->gi = GUARD_INTERVAL_1_8;
+			else ptr->gi = GUARD_INTERVAL_1_4;
+
+
+		}
+		/*
+		else if(! strcmp(type, "CBL"))
+		{
+			fields = sscanf(line, cbl_conf,
+                                &ptr->name, &ptr->freq, &ptr->inv, &ptr->qam,
+                                &ptr->fec, &ptr->mod, &ptr->vpid, &ptr->apid1);
+
+
+		}
+		*/
+		else	//SATELLITE
+		{
+			fields = sscanf(line, sat_conf,
+				&ptr->name, &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate, &ptr->vpid, &ptr->apid1,
+				&ptr->tpid, &ptr->ca, &ptr->progid);
+			ptr->pol = toupper(ptr->pol);
+			ptr->freq *=  1000UL;
+			ptr->srate *=  1000UL;
+			ptr->tone = -1;
+			mp_msg(MSGT_DEMUX, MSGL_V,
+				"NUM_FIELDS: %d, NAME: %s, FREQ: %d, SRATE: %d, POL: %c, DISEQC: %d, TONE: %d, VPID: %d, APID1: %d, APID2: %d, TPID: %d, PROGID: %d, NUM: %d\n",
+				fields, ptr->name, ptr->freq, ptr->srate, ptr->pol, ptr->diseqc, ptr->tone, ptr->vpid, ptr->apid1, ptr->apid2, ptr->tpid, ptr->progid, list->NUM_CHANNELS);
+		}
+
+		list->NUM_CHANNELS++;
+		row_count++;
+	}
+
+	fclose(f);
+	return list;
+}
+
+
+static long getmsec()
+{
+	struct timeval tv;
+	gettimeofday(&tv, (struct timezone*) NULL);
+	return(tv.tv_sec%1000000)*1000 + tv.tv_usec/1000;
+}
+
+
+
+int dvb_streaming_read(int fd, char *buffer, unsigned int size, dvb_priv_t *priv)
+{
+	struct pollfd pfds[1];
+	uint32_t ok = 0, pos = 0, tot = 0, rk, d, r, m;
+
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "dvb_streaming_read(%u)\n", fd);
+
+	while(pos < size)
+	{
+	    ok = 0;
+	    tot = 0;
+	    //int m = min((size-pos), 188);
+	    m = size - pos;
+	    d = (int) (m / 188);
+	    r = m % 188;
+
+	    m = d * 188;
+	    m = (m ? m : r);
+
+	    pfds[0].fd = fd;
+	    pfds[0].events = POLLIN | POLLPRI;
+
+	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "DEVICE: %d, DVR: %d, PIPE: %d <-> %d\n", fd, priv->dvr_fd, priv->input, priv->output);
+
+	    poll(pfds, 1, 500);
+	    if((rk = read(fd, &buffer[pos], m)) > 0)
+	    	pos += rk;
+	}
+
+	return pos;
+}
+
+
+
+dvb_history_t *dvb_step_channel(dvb_priv_t *priv, int dir, dvb_history_t *h)
+{
+    //int new_freq, new_srate, new_diseqc, new_tone, new_vpid, new_apid;
+    //char new_pol;
+    int new_current;
+    dvb_channel_t *next;
+    dvb_channels_list *list;
+
+    if(priv == NULL)
+    {
+    	mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_step_channel: PRIV NULL PTR, quit\n");
+    	return 0;
+    }
+
+    list = priv->list;
+    if(list == NULL)
+    {
+    	mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_step_channel: LIST NULL PTR, quit\n");
+    	return 0;
+    }
+
+    mp_msg(MSGT_DEMUX, MSGL_V, "DVB_STEP_CHANNEL dir %d\n", dir);
+
+    if(dir == DVB_CHANNEL_HIGHER)
+    {
+    	if(list->current == list->NUM_CHANNELS)
+    		return 0;
+
+    	new_current = list->current + 1;
+    	next = &(list->channels[new_current]);
+    }
+    else
+    {
+    	if(list->current == 0)
+    		return 0;
+
+    	new_current = list->current - 1;
+    	next = &(list->channels[new_current]);
+
+    }
+
+    demux_stop(priv->demux_fd[0]);
+    demux_stop(priv->demux_fd[1]);
+
+    h->prev = list->current;
+    h->next = new_current;
+
+    list->current = new_current;
+
+    return h;
+}
+
+
+extern char *get_path(char *);
+
+dvb_channels_list  *list_ptr = NULL;
+
+int dvb_streaming_start(stream_t *stream)
+{
+	int pids[MAX_CHANNELS];
+	int pestypes[MAX_CHANNELS];
+	int npids, i;
+	char *filename, type[80];
+	unsigned long freq = 0;
+	char pol = 0;
+	unsigned long srate = 0;
+	int diseqc = 0, old_diseqc = 0;
+	int tone = -1;
+
+	dvb_priv_t *priv;
+	dvb_channel_t *channel = NULL;
+	fe_spectral_inversion_t 	specInv			=	INVERSION_AUTO;
+	fe_modulation_t 		modulation		=	CONSTELLATION_DEFAULT;
+	fe_transmit_mode_t 		TransmissionMode 	=	TRANSMISSION_MODE_DEFAULT;
+	fe_bandwidth_t 			bandWidth		=	BANDWIDTH_DEFAULT;
+	fe_guard_interval_t 		guardInterval		=	GUARD_INTERVAL_DEFAULT;
+	fe_code_rate_t 			HP_CodeRate		=	HP_CODERATE_DEFAULT;
+
+
+	stream->priv = (dvb_priv_t*) malloc(sizeof(dvb_priv_t));
+	if(stream->priv ==  NULL)
+	    return 0;
+	priv = (dvb_priv_t*) stream->priv;
+
+	if(!strncmp(dvbin_param_type, "CBL", 3))
+	    strncpy(type, "CBL", 3);
+	else if(!strncmp(dvbin_param_type, "TER", 3))
+	    strncpy(type, "TER", 3);
+	else
+	    strncpy(type, "SAT", 3);
+
+
+	filename = get_path("channels.conf");
+
+	if(list_ptr == NULL)
+	{
+		if(filename)
+		{
+			if((list_ptr = dvb_get_channels(filename, type)) == NULL)
+				mp_msg(MSGT_DEMUX, MSGL_WARN, "EMPTY CHANNELS LIST!\n");
+			else
+			{
+				priv->list = list_ptr;
+				priv->list->current = 0;
+			}
+		}
+		else
+		{
+			list_ptr = NULL;
+			mp_msg(MSGT_DEMUX, MSGL_WARN, "NO CHANNELS FILE FOUND!\n");
+		}
+	}
+
+
+	mp_msg(MSGT_DEMUX, MSGL_INFO, "code taken from dvbstream for mplayer v0.4pre1 - (C) Dave Chapman 2001\n");
+	mp_msg(MSGT_DEMUX, MSGL_INFO, "Released under the GPL.\n");
+	mp_msg(MSGT_DEMUX, MSGL_INFO, "Latest version available from http://www.linuxstb.org/\n");
+	mp_msg(MSGT_DEMUX, MSGL_V, "ON: %d, CARD: %d, FREQ: %d, SRATE: %d, POL: %s, VID: %d, AID: %d\n", dvbin_param_on,
+	    dvbin_param_card, dvbin_param_freq, dvbin_param_srate, dvbin_param_pol, dvbin_param_vid, dvbin_param_aid);
+
+	npids = 0;
+
+	if((dvb_prev_next.next > -1) && (dvb_prev_next.prev > -1) && (list_ptr != NULL))	//We are after a channel stepping
+	{
+	    list_ptr->current = dvb_prev_next.next;
+	    channel = &(list_ptr->channels[dvb_prev_next.next]);
+	    mp_msg(MSGT_DEMUX, MSGL_V, "PROGRAM NUMBER %d: name=%s, vid=%d, aid=%d, freq=%lu, srate=%lu, pol=%c, diseqc: %d, tone: %d\n", dvb_prev_next.next,
+		    channel->name, channel->vpid, channel->apid1,
+		    channel->freq, channel->srate, channel->pol, channel->diseqc, channel->tone);
+
+
+	    if((dvb_prev_next.prev >= 0) && (dvb_prev_next.prev < list_ptr->NUM_CHANNELS))
+	    {
+		dvb_channel_t *tmp = &(list_ptr->channels[dvb_prev_next.prev]);
+		old_diseqc = tmp->diseqc;
+	    }
+	}
+	else if(list_ptr != NULL && strlen(dvbin_param_prog))
+	{
+	    i = 0;
+	    while((channel == NULL) && i < list_ptr->NUM_CHANNELS)
+	    {
+		if(! strcmp(list_ptr->channels[i].name, dvbin_param_prog))
+		    channel = &(list_ptr->channels[i]);
+
+		i++;
+	    }
+	    if(channel != NULL)
+	    {
+		list_ptr->current = i-1;
+	    	mp_msg(MSGT_DEMUX, MSGL_V, "PROGRAM NUMBER %d: name=%s, vid=%d, aid=%d, freq=%lu, srate=%lu, pol=%c, diseqc: %d, tone: %d\n", i-1,
+		    channel->name, channel->vpid, channel->apid1,
+		    channel->freq, channel->srate, channel->pol, channel->diseqc, channel->tone);
+
+	    }
+	}
+
+
+	if(dvbin_param_vid > 0)
+	{
+	    pids[npids] = priv->channel.vpid = dvbin_param_vid;
+	}
+	else if(channel != NULL)
+	{
+	    pids[npids] = priv->channel.vpid = channel->vpid;
+	}
+	pestypes[npids] = DMX_PES_VIDEO;
+	npids++;
+
+	if(dvbin_param_aid > 0)
+	{
+	    pids[npids] = priv->channel.apid1 = dvbin_param_aid;
+	}
+	else if(channel != NULL)
+	{
+	    pids[npids] = priv->channel.vpid = channel->apid1;
+	}
+	pestypes[npids] = DMX_PES_AUDIO;
+	npids++;
+
+
+
+	if(dvbin_param_freq)
+	    freq  = dvbin_param_freq  * 1000UL;
+	else  if(channel != NULL)
+	    freq = channel->freq;
+
+
+	if(dvbin_param_srate)
+	    srate = dvbin_param_srate * 1000UL;
+	else  if(channel != NULL)
+	    srate = channel->srate;
+
+	if((1<= dvbin_param_diseqc)  && (dvbin_param_diseqc <= 4))
+	    diseqc = dvbin_param_diseqc;
+	else
+	    if(channel != NULL)
+		if(channel->diseqc != old_diseqc)
+		    diseqc = channel->diseqc;
+		else
+		    diseqc = 0;
+	    else
+		diseqc = 0;
+	mp_msg(MSGT_DEMUX, MSGL_INFO, "DISEQC: %d\n", diseqc);
+
+	if((dvbin_param_tone == 0) || (dvbin_param_tone == 1))
+	    tone = dvbin_param_tone;
+	else
+	    if(channel != NULL)
+		tone = channel->tone;
+	    else
+		tone = -1;
+
+	if(! strcmp(dvbin_param_pol, "V")) pol = 'V';
+	else if(! strcmp(dvbin_param_pol, "H")) pol = 'H';
+	else if(channel != NULL) pol = channel->pol;
+	else pol='V';
+	pol = toupper(pol);
+
+
+	if(!strcmp(dvbin_param_inv, "INVERSION_ON"))
+		specInv = INVERSION_ON;
+	else if(!strcmp(dvbin_param_inv, "INVERSION_OFF"))
+		specInv = INVERSION_OFF;
+	else if(!strcmp(dvbin_param_inv, "INVERSION_AUTO"))
+		specInv = INVERSION_AUTO;
+	else if(channel != NULL)
+		specInv = channel->inv;
+	else
+		specInv = INVERSION_AUTO;
+
+
+	if(dvbin_param_mod)
+	{
+		switch(dvbin_param_mod)
+		{
+			case 16:  modulation=QAM_16; break;
+			case 32:  modulation=QAM_32; break;
+			case 64:  modulation=QAM_64; break;
+			case 128: modulation=QAM_128; break;
+			case 256: modulation=QAM_256; break;
+			default:
+				mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid QAM rate: %s\n", dvbin_param_mod);
+				modulation=CONSTELLATION_DEFAULT;
+		}
+	}
+	else  if(channel != NULL)
+	    	modulation = channel->mod;
+	else
+		modulation=CONSTELLATION_DEFAULT;
+
+
+	if(dvbin_param_gi)
+	{
+		switch(dvbin_param_gi)
+		{
+			case 32:  guardInterval=GUARD_INTERVAL_1_32; break;
+			case 16:  guardInterval=GUARD_INTERVAL_1_16; break;
+			case 8:   guardInterval=GUARD_INTERVAL_1_8; break;
+			case 4:   guardInterval=GUARD_INTERVAL_1_4; break;
+			default:
+				mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid Guard Interval: %s\n", dvbin_param_gi);
+				guardInterval=GUARD_INTERVAL_DEFAULT;
+		}
+	}
+	else  if(channel != NULL)
+	    	guardInterval = channel->gi;
+	else
+		guardInterval=GUARD_INTERVAL_DEFAULT;
+
+	if(dvbin_param_tm)
+	{
+		switch(dvbin_param_tm)
+		{
+			case 8:   TransmissionMode=TRANSMISSION_MODE_8K; break;
+			case 2:   TransmissionMode=TRANSMISSION_MODE_2K; break;
+			default:
+				TransmissionMode=TRANSMISSION_MODE_DEFAULT;
+				mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid Transmission Mode: %s\n", dvbin_param_tm);
+		}
+	}
+	else  if(channel != NULL)
+	    	TransmissionMode = channel->trans;
+	else
+		TransmissionMode=TRANSMISSION_MODE_DEFAULT;
+
+
+	if(dvbin_param_bw)
+	{
+		switch(dvbin_param_bw)
+		{
+			case 8:   bandWidth=BANDWIDTH_8_MHZ; break;
+			case 7:   bandWidth=BANDWIDTH_7_MHZ; break;
+			case 6:   bandWidth=BANDWIDTH_6_MHZ; break;
+			default:
+				mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid DVB-T bandwidth: %s\n", dvbin_param_bw);
+			       	bandWidth=BANDWIDTH_DEFAULT;
+		}
+	}
+	else  if(channel != NULL)
+	    	bandWidth = channel->bw;
+	else
+		bandWidth=BANDWIDTH_DEFAULT;
+
+
+	if(dvbin_param_cr)
+	{
+		switch(dvbin_param_cr)
+		{
+			case -1: HP_CodeRate=FEC_AUTO; break;
+			case 12: HP_CodeRate=FEC_1_2; break;
+			case 23: HP_CodeRate=FEC_2_3; break;
+			case 34: HP_CodeRate=FEC_3_4; break;
+			case 56: HP_CodeRate=FEC_5_6; break;
+			case 78: HP_CodeRate=FEC_7_8; break;
+			default:
+				mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid Code Rate: %s\n", dvbin_param_cr);
+				HP_CodeRate=HP_CODERATE_DEFAULT;
+		}
+	}
+	else  if(channel != NULL)
+	    	HP_CodeRate = channel->cr;
+	else
+		HP_CodeRate=HP_CODERATE_DEFAULT;
+
+
+
+	card = dvbin_param_card - 1;
+	if((card < 0) || (card > 4))
+	    card = 0;
+
+
+	dvbin_param_on = 1;
+
+	mp_msg(MSGT_DEMUX, MSGL_V,  "CARD: %d, FREQ: %d, POL: %c, SRATE: %d, DISEQC: %d, TONE: %d, VPID: %d, APID: %d\n", card, freq, pol, srate, diseqc, tone, pids[0], pids[1]);
+
+	priv->channel.freq = freq;
+	priv->channel.srate = srate;
+	priv->channel.diseqc = diseqc;
+	priv->channel.pol = pol;
+	priv->channel.tone = tone;
+	priv->channel.inv = specInv;
+	priv->channel.mod = modulation;
+	priv->channel.gi = guardInterval;
+	priv->channel.trans = TransmissionMode;
+	priv->channel.bw = bandWidth;
+	priv->channel.cr = HP_CodeRate;
+
+	if(freq && pol && srate)
+		if (! dvb_tune(priv, freq, pol, srate, diseqc, tone, specInv, modulation, guardInterval, TransmissionMode, bandWidth, HP_CodeRate))
+			return 0;
+
+	for (i=0; i < npids; i++)
+	{
+		if((priv->demux_fd[i] = open(demuxdev[card], O_RDWR)) < 0)
+		{
+	  		mp_msg(MSGT_DEMUX, MSGL_ERR, "ERROR OPENING DEMUX %i: ", i);
+	  		return -1;
+		}
+	}
+
+	if((priv->dvr_fd = open(dvrdev[card], O_RDONLY| O_NONBLOCK)) < 0)
+	{
+		mp_msg(MSGT_DEMUX, MSGL_ERR, "DVR DEVICE: ");
+		return -1;
+	}
+
+
+	/* Now we set the filters */
+	for (i=0; i< npids; i++)
+	{
+	    set_ts_filt(priv->demux_fd[i], pids[i], pestypes[i]);
+	    //make_nonblock(fd[i]);
+	}
+
+
+	stream->fd = priv->dvr_fd;
+
+	dvbin_is_active = 1;
+
+	mp_msg(MSGT_DEMUX, MSGL_DBG2,  "ESCO da dvb_streaming_start(s)\n");
+
+	return 1;
+}
+
+
+int dvbin_close(dvb_priv_t *priv)
+{
+	//close(priv->dvr_fd);
+	close(priv->demux_fd[0]);
+	close(priv->demux_fd[1]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmpdemux/dvbin.h	Sun Mar 16 20:13:28 2003 +0000
@@ -0,0 +1,102 @@
+
+#ifndef DVBIN_H
+#define DVBIN_H
+
+extern int dvbin_param_on;
+
+#ifdef HAVE_DVB_HEAD
+	#include <linux/dvb/dmx.h>
+	#include <linux/dvb/frontend.h>
+#else
+	#include <ost/dmx.h>
+	#include <ost/sec.h>
+	#include <ost/frontend.h>
+	#define fe_status_t FrontendStatus
+	#define fe_spectral_inversion_t SpectralInversion
+	#define fe_modulation_t Modulation
+	#define fe_code_rate_t CodeRate
+	#define fe_transmit_mode_t TransmitMode
+	#define fe_guard_interval_t GuardInterval
+	#define fe_bandwidth_t BandWidth
+	#define fe_sec_voltage_t SecVoltage
+	#define dmx_pes_filter_params dmxPesFilterParams
+	#define dmx_sct_filter_params dmxSctFilterParams
+	#define dmx_pes_type_t dmxPesType_t
+#endif
+
+
+
+#define DVB_CHANNEL_LOWER -1
+#define DVB_CHANNEL_HIGHER 1
+
+
+typedef struct
+{
+    int next, prev;
+} dvb_history_t;
+
+typedef struct {
+	char 				*name;
+	int 				freq, srate, diseqc, tone;
+	char 				pol;
+	int 				vpid, apid1, apid2, tpid, dpid1, dpid2, progid, ca;
+	fe_spectral_inversion_t 	inv;
+	fe_modulation_t 		mod;
+	fe_transmit_mode_t 		trans;
+	fe_bandwidth_t 			bw;
+	fe_guard_interval_t 		gi;
+	fe_code_rate_t 			cr;
+} dvb_channel_t;
+
+
+typedef struct {
+	uint16_t NUM_CHANNELS;
+	uint16_t current;
+	dvb_channel_t channels[512];
+} dvb_channels_list;
+
+
+
+typedef struct {
+    int fe_fd;
+    int sec_fd;
+    int demux_fd[3];
+    int dvr_fd;
+    int input;
+    int output;
+    int discard;
+
+    dvb_channel_t channel;
+    dvb_channels_list *list;
+} dvb_priv_t;
+
+
+extern dvb_history_t *dvb_step_channel(dvb_priv_t*, int, dvb_history_t*);
+
+extern dvb_channels_list *dvb_get_channels(char *, const char *);
+extern dvb_history_t dvb_prev_next;
+
+
+
+
+#ifndef DVB_T_LOCATION
+    #ifndef UK
+    #warning No DVB-T country defined in dvb_defaults.h, defaulting to UK
+    #endif
+
+    /* UNITED KINGDOM settings */
+    #define DVB_T_LOCATION              "in United Kingdom"
+    #define BANDWIDTH_DEFAULT           BANDWIDTH_8_MHZ
+    #define HP_CODERATE_DEFAULT         FEC_2_3
+    #define CONSTELLATION_DEFAULT       QAM_64
+    #define TRANSMISSION_MODE_DEFAULT   TRANSMISSION_MODE_2K
+    #define GUARD_INTERVAL_DEFAULT      GUARD_INTERVAL_1_32
+    #define HIERARCHY_DEFAULT           HIERARCHY_NONE
+#endif
+
+#define HIERARCHY_DEFAULT           HIERARCHY_NONE
+#define LP_CODERATE_DEFAULT (0)
+
+
+
+#endif
--- a/libmpdemux/open.c	Sun Mar 16 16:38:16 2003 +0000
+++ b/libmpdemux/open.c	Sun Mar 16 20:13:28 2003 +0000
@@ -30,6 +30,8 @@
 static URL_t* url;
 #endif
 
+int dvbin_param_on=0;
+
 int dvd_title=0;
 int dvd_chapter=1;
 int dvd_last_chapter=0;
@@ -76,6 +78,12 @@
 extern int stream_open_tv(stream_t *stream, tvi_handle_t *tvh);
 #endif
 
+#ifdef HAS_DVBIN_SUPPORT
+#include "dvbin.h"
+#endif
+
+
+
 #ifdef HAVE_CDDA
 stream_t* open_cdda(char* dev,char* track);
 #ifdef STREAMING
@@ -478,6 +486,22 @@
 }
 #endif
 
+#ifdef HAS_DVBIN_SUPPORT
+if(dvbin_param_on == 1)
+{
+	stream = new_stream(-1, STREAMTYPE_DVB);
+	if (!stream)
+	   return(NULL);
+       	if (!dvb_streaming_start(stream))
+	   return NULL;
+
+       	return stream;
+}
+#endif
+
+
+
+
 //============ Check for TV-input or multi-file input ====
   if( (mf_support == 1)
 #ifdef USE_TV
--- a/libmpdemux/stream.c	Sun Mar 16 16:38:16 2003 +0000
+++ b/libmpdemux/stream.c	Sun Mar 16 20:13:28 2003 +0000
@@ -106,6 +106,15 @@
   case STREAMTYPE_DS:
     len = demux_read_data((demux_stream_t*)s->priv,s->buffer,STREAM_BUFFER_SIZE);
     break;
+  
+#ifdef HAS_DVBIN_SUPPORT
+  case STREAMTYPE_DVB:
+   len = dvb_streaming_read(s->fd, s->buffer, STREAM_BUFFER_SIZE, s->priv);
+  break;
+#endif
+
+
+    
   default: len=0;
   }
   if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; }
@@ -309,6 +318,12 @@
     close_cdda(s);
     break;
 #endif
+#ifdef HAS_DVBIN_SUPPORT
+  case STREAMTYPE_DVB:
+    dvbin_close(s->priv);
+  break;
+#endif
+
 #ifdef USE_DVDREAD
   case STREAMTYPE_DVD:
     dvd_close(s->priv);
--- a/libmpdemux/stream.h	Sun Mar 16 16:38:16 2003 +0000
+++ b/libmpdemux/stream.h	Sun Mar 16 20:13:28 2003 +0000
@@ -18,6 +18,7 @@
 #define STREAMTYPE_CDDA 10     // raw audio CD reader
 #define STREAMTYPE_SMB 11      // smb:// url, using libsmbclient (samba)
 #define STREAMTYPE_VCDBINCUE 12      // vcd directly from bin/cue files
+#define STREAMTYPE_DVB 13
 
 #define STREAM_BUFFER_SIZE 2048
 
--- a/libmpdemux/video.c	Sun Mar 16 16:38:16 2003 +0000
+++ b/libmpdemux/video.c	Sun Mar 16 20:13:28 2003 +0000
@@ -134,6 +134,7 @@
    // otherwise fall through to...
 #endif
  case DEMUXER_TYPE_PVA:
+ case DEMUXER_TYPE_MPEG_TS:
  case DEMUXER_TYPE_MPEG_ES:
  case DEMUXER_TYPE_MPEG_PS: {
 //mpeg_header_parser:
@@ -270,7 +271,7 @@
     *start=NULL;
 
   if(demuxer->file_format==DEMUXER_TYPE_MPEG_ES || demuxer->file_format==DEMUXER_TYPE_MPEG_PS
-		  || demuxer->file_format==DEMUXER_TYPE_PVA
+		  || demuxer->file_format==DEMUXER_TYPE_PVA || demuxer->file_format==DEMUXER_TYPE_MPEG_TS
 #ifdef STREAMING_LIVE_DOT_COM
     || (demuxer->file_format==DEMUXER_TYPE_RTP && demux_is_mpeg_rtp_stream(demuxer))
 #endif
@@ -422,6 +423,7 @@
     }
     
     if(demuxer->file_format==DEMUXER_TYPE_MPEG_PS ||
+       demuxer->file_format==DEMUXER_TYPE_MPEG_TS ||
        demuxer->file_format==DEMUXER_TYPE_MPEG_ES){
 
 //	if(pts>0.0001) printf("\r!!! pts: %5.3f [%d] (%5.3f)   \n",pts,picture_coding_type,i_pts);
--- a/mencoder.c	Sun Mar 16 16:38:16 2003 +0000
+++ b/mencoder.c	Sun Mar 16 20:13:28 2003 +0000
@@ -422,7 +422,7 @@
   }
 #endif
 
-  if(!filename && !vcd_track && !dvd_title && !tv_param_on){
+  if(!filename && !vcd_track && !dvd_title && !tv_param_on && !dvbin_param_on){
 	printf(MSGTR_MissingFilename);
 	mencoder_exit(1,NULL);
   }
--- a/mplayer.c	Sun Mar 16 16:38:16 2003 +0000
+++ b/mplayer.c	Sun Mar 16 20:13:28 2003 +0000
@@ -92,6 +92,13 @@
 extern int tv_param_on;
 #endif
 
+#ifdef HAS_DVBIN_SUPPORT
+#include "libmpdemux/dvbin.h"
+extern dvb_history_t dvb_prev_next;
+dvb_history_t *dvb_history;
+#endif
+
+
 //**************************************************************************//
 //             Playtree
 //**************************************************************************//
@@ -661,6 +668,13 @@
 
 int gui_no_filename=0;
 
+#ifdef HAS_DVBIN_SUPPORT
+        dvb_prev_next.prev = dvb_prev_next.next = -1;
+	dvb_history = &dvb_prev_next;
+#endif
+
+
+
   srand((int) time(NULL)); 
 
   mp_msg_init();
@@ -928,7 +942,7 @@
  }
 #endif
 
-    if(!filename && !vcd_track && !dvd_title && !dvd_nav && !tv_param_on){
+    if(!filename && !vcd_track && !dvd_title && !dvd_nav && !tv_param_on && !dvbin_param_on){
       if(!use_gui){
 	// no file/vcd/dvd -> show HELP:
 	mp_msg(MSGT_CPLAYER, MSGL_INFO, help_text);
@@ -2641,7 +2655,21 @@
 #endif
 	}
       }
-    } break;
+    } 
+#ifdef HAS_DVBIN_SUPPORT
+	if(dvbin_param_on == 1)
+	{
+		int v = cmd->args[0].v.i;
+		if(v > 0)
+			dvb_history = dvb_step_channel((dvb_priv_t*)(demuxer->stream->priv), DVB_CHANNEL_HIGHER, dvb_history);
+		else
+			dvb_history = dvb_step_channel((dvb_priv_t*)(demuxer->stream->priv), DVB_CHANNEL_LOWER, dvb_history);
+		uninit_player(INITED_ALL);
+		goto goto_next_file;
+	}
+#endif
+
+    break;
     case MP_CMD_TV_SET_CHANNEL :  {
       if (tv_param_on == 1) {
 	tv_set_channel((tvi_handle_t*)(demuxer->priv), cmd->args[0].v.s);
@@ -3363,7 +3391,11 @@
   }	
 #endif
 
-if(use_gui || playtree_iter != NULL){
+if(use_gui || playtree_iter != NULL
+#ifdef HAS_DVBIN_SUPPORT
+		    || dvbin_param_on
+#endif
+	){
 
   eof = 0;
   goto play_next_file;