[Mplayer-cvslog] CVS: main/libmpdemux demux_ts.c,NONE,1.1 dvb_defaults.h,NONE,1.1 dvb_tune.c,NONE,1.1 dvbin.c,NONE,1.1 dvbin.h,NONE,1.1 Makefile,1.51,1.52 demuxer.c,1.135,1.136 demuxer.h,1.56,1.57 open.c,1.69,1.70 stream.c,1.51,1.52 stream.h,1.55,1.56video.c,1.36,1.37

Arpi of Ize arpi at mplayerhq.hu
Sun Mar 16 21:13:33 CET 2003


Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var/tmp.root/cvs-serv15493/libmpdemux

Modified Files:
	Makefile demuxer.c demuxer.h open.c stream.c stream.h video.c 
Added Files:
	demux_ts.c dvb_defaults.h dvb_tune.c dvbin.c dvbin.h 
Log Message:
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 at libero.it>
some cleanups, ts demuxer fixes by me


--- NEW FILE ---
/*
 * 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: demux_ts.c,v 1.1 2003/03/16 20:13:27 arpi Exp $
 *
 * 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;
}




--- NEW FILE ---
/* 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

--- NEW FILE ---
/* 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));
}

--- NEW FILE ---
/*

dvbstream
(C) Dave Chapman <dave at 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]);
}

--- NEW FILE ---

#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

Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/Makefile,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -r1.51 -r1.52
--- Makefile	3 Feb 2003 10:27:50 -0000	1.51
+++ Makefile	16 Mar 2003 20:13:27 -0000	1.52
@@ -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 
@@ -19,6 +19,15 @@
 SRCS += rtp.c
 endif
 endif
+
+DVBIN = yes
+ifeq ($(DVBIN),yes)
+SRCS += dvbin.c
+SRCS += dvb_tune.c
+endif
+
+
+
 
 OBJS	= $(SRCS:.c=.o)
 OBJS   += $(CPLUSPLUSSRCS:.cpp=.o)

Index: demuxer.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demuxer.c,v
retrieving revision 1.135
retrieving revision 1.136
diff -u -r1.135 -r1.136
--- demuxer.c	16 Feb 2003 10:00:42 -0000	1.135
+++ demuxer.c	16 Mar 2003 20:13:27 -0000	1.136
@@ -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)
 

Index: demuxer.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demuxer.h,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- demuxer.h	28 Jan 2003 00:12:23 -0000	1.56
+++ demuxer.h	16 Mar 2003 20:13:28 -0000	1.57
@@ -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

Index: open.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/open.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- open.c	5 Mar 2003 10:56:47 -0000	1.69
+++ open.c	16 Mar 2003 20:13:28 -0000	1.70
@@ -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
@@ -477,6 +485,22 @@
   return stream;
 }
 #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)

Index: stream.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/stream.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -r1.51 -r1.52
--- stream.c	9 Feb 2003 20:18:22 -0000	1.51
+++ stream.c	16 Mar 2003 20:13:28 -0000	1.52
@@ -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);

Index: stream.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/stream.h,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- stream.h	4 Jan 2003 20:11:06 -0000	1.55
+++ stream.h	16 Mar 2003 20:13:28 -0000	1.56
@@ -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
 

Index: video.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/video.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- video.c	15 Mar 2003 21:07:45 -0000	1.36
+++ video.c	16 Mar 2003 20:13:28 -0000	1.37
@@ -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);



More information about the MPlayer-cvslog mailing list