Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] VDR: Tuning stability



Klaus Schmidinger writes:
 > In order to make channel tuning more stable I have extracted
 > the code that VDR uses to change channels and made a small
 > test example that does nothing else but switching channels
 > (so basicly it does some "heavy zapping").
 > 
 > The file can be found at
 > 
 >   ftp://ftp.cadsoft.de/pub/people/kls/ctest.c

There is some really strange stuff in that tuning routine. Here is
something that works:



typedef struct fd_list_s{
	int front;
	int sec;
	int demux1;
	int demux2;
	int demux3;
	int dvr;
	int dvr_out;
	int dvr_in;
	int apid;
	int vpid;
	int video;
	int audio;
	int playing;
	char fronts[80];
	char secs[80];
	char demuxs[80];
	char dvrs[80];
	char audios[80];
	char videos[80];
	int dev_nr;
	int sat;
} fd_list;


int set_qpsk_channel(fd_list *fds, int freq, int vpid, int apid, int tpid,
		int diseqc, int pol, int srate, int fec, int lnb_lof1, 
		int lnb_lof2, int lnb_slof)
{
	struct secCommand scmd;
	struct secCmdSequence scmds;
	struct dmxPesFilterParams pesFilterParams; 
	struct qpskParameters qpsk;
	struct pollfd pfd[1];
	struct qpskEvent event;

	frequency = (uint32_t) freq;
	symbolrate = (uint32_t) srate;
	if (fds->demux1 < 0){
		if ((fds->demux1=open(fds->demuxs, O_RDWR|O_NONBLOCK)) 
		    < 0){
			perror("DEMUX DEVICE: ");
			return -1;
		}
	}

	if (fds->demux2 < 0){
		if ((fds->demux2=open(fds->demuxs, O_RDWR|O_NONBLOCK)) 
		    < 0){
			perror("DEMUX DEVICE: ");
			return -1;
		}
	}

	if (fds->demux3 < 0){
		if ((fds->demux3=open(fds->demuxs, O_RDWR|O_NONBLOCK)) 
		    < 0){
			perror("DEMUX DEVICE: ");
			return -1;
		}
	}

	if (freq < lnb_slof) {
		qpsk.iFrequency = (freq - lnb_lof1);
		scmds.continuousTone = SEC_TONE_OFF;
	} else {
		qpsk.iFrequency = (freq - lnb_lof2);
		scmds.continuousTone = SEC_TONE_ON;
	}
	if (pol) scmds.voltage = SEC_VOLTAGE_18;
	else scmds.voltage = SEC_VOLTAGE_13;
        
	scmd.type=0;
	scmd.u.diseqc.addr=0x10;
	scmd.u.diseqc.cmd=0x38;
	scmd.u.diseqc.numParams=1;
	scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) | 
		(scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
		(scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);

	scmds.miniCommand=SEC_MINI_NONE;
	scmds.numCommands=1;
	scmds.commands=&scmd;
	if (ioctl(fds->sec, SEC_SEND_SEQUENCE, &scmds) < 0){
		perror("SEC SEND: ");
		return -1;
	}

	qpsk.SymbolRate = srate;
	qpsk.FEC_inner = fec;

	if (ioctl(fds->front, QPSK_TUNE, &qpsk) < 0){
		perror("QPSK TUNE: ");
		return -1;
	}
 
	pfd[0].fd = fds->front;
	pfd[0].events = POLLIN;

	if (poll(pfd,1,1000)){
		if (pfd[0].revents & POLLIN){
			printf("Getting QPSK event\n");
			if ( ioctl(fds->front, QPSK_GET_EVENT, &event)  

			     == -EBUFFEROVERFLOW){
				perror("qpsk get event");
				return -1;
			}
			printf("Received ");
			switch(event.type){
			case FE_UNEXPECTED_EV:
				printf("unexpected event\n");
				return -1;
			case FE_FAILURE_EV:
				printf("failure event\n");
				return -1;
				
			case FE_COMPLETION_EV:
				printf("completion event\n");
			}
		}
	}
      

        pesFilterParams.pid     = vpid;
        pesFilterParams.input   = DMX_IN_FRONTEND; 
	pesFilterParams.output  = DMX_OUT_DECODER; 
        pesFilterParams.pesType = DMX_PES_VIDEO; 
        pesFilterParams.flags   = DMX_IMMEDIATE_START;
        if (ioctl(fds->demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
                perror("set_vpid");
		return -1;
	}

        pesFilterParams.pid     = apid;
        pesFilterParams.input   = DMX_IN_FRONTEND; 
	pesFilterParams.output  = DMX_OUT_DECODER; 
        pesFilterParams.pesType = DMX_PES_AUDIO; 
        pesFilterParams.flags   = DMX_IMMEDIATE_START;
        if (ioctl(fds->demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
                perror("set_apid");
		return -1;
	}

        pesFilterParams.pid     = tpid;
        pesFilterParams.input   = DMX_IN_FRONTEND; 
	pesFilterParams.output  = DMX_OUT_DECODER; 
        pesFilterParams.pesType = DMX_PES_TELETEXT; 
        pesFilterParams.flags   = DMX_IMMEDIATE_START;
        if (ioctl(fds->demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
                perror("set_tpid");
		return -1;
	}


	return 0;
}


I don't know if that will compile without the rest of the file, but
the important stuff is the QPSK_GET_EVENT call, which should be polled
if a large enough timeout to ensure that the channel is tuned.
Running Klausī example leads to the described errors, but running
tuxzap immediately after that lets you tune again. So you can either
use the tuning example in DVB.cc in the libdvb directory, which is
maybe a little obscured or look at the example above. 
All the above is not valid for the new Haupauge cards with the new
frontend chipset. In that case we still have some problems.

Marcus

-- 
---------------------------------------------------------------------
Dr. Marcus Metzler                             
mocm@netcologne.de                     http://www.metzlerbros.de
mocm@convergence.de                    http://www.convergence.de

Convergence Integrated Media GmbH          
Rosenthaler Str. 51                   
D-10178 Berlin                             
---------------------------------------------------------------------


--
Info:
To unsubscribe send a mail to listar@linuxtv.org with "unsubscribe linux-dvb" as subject.



Home | Main Index | Thread Index