view libmpdemux/dvbin.c @ 10252:d275152390ee

I've found some time to implement the encoding support for the new DivX API. Now it's possible to play and encode movies with the latest DivX release. One thing that doesn't work is the new Video Buffer Verifier (VBV) multipass encoding. The encoder segfaults. Maybe it just isn't supported with the standard profile of the released binary encoder. Andreas Hess <jaska@gmx.net>
author arpi
date Fri, 06 Jun 2003 19:57:37 +0000
parents 76c6d8f1ebf5
children 11826d9f90c7
line wrap: on
line source

/*

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]);
}