Path: blob/master/Documentation/DocBook/dvb/examples.xml
10821 views
<title>Examples</title>1<para>In this section we would like to present some examples for using the DVB API.2</para>3<para>Maintainer note: This section is out of date. Please refer to the sample programs packaged4with the driver distribution from <ulink url="http://linuxtv.org/hg/dvb-apps" />.5</para>67<section id="tuning">8<title>Tuning</title>9<para>We will start with a generic tuning subroutine that uses the frontend and SEC, as well as10the demux devices. The example is given for QPSK tuners, but can easily be adjusted for11QAM.12</para>13<programlisting>14#include <sys/ioctl.h>15#include <stdio.h>16#include <stdint.h>17#include <sys/types.h>18#include <sys/stat.h>19#include <fcntl.h>20#include <time.h>21#include <unistd.h>2223#include <linux/dvb/dmx.h>24#include <linux/dvb/frontend.h>25#include <linux/dvb/sec.h>26#include <sys/poll.h>2728#define DMX "/dev/dvb/adapter0/demux1"29#define FRONT "/dev/dvb/adapter0/frontend1"30#define SEC "/dev/dvb/adapter0/sec1"3132/⋆ routine for checking if we have a signal and other status information⋆/33int FEReadStatus(int fd, fe_status_t ⋆stat)34{35int ans;3637if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){38perror("FE READ STATUS: ");39return -1;40}4142if (⋆stat & FE_HAS_POWER)43printf("FE HAS POWER\n");4445if (⋆stat & FE_HAS_SIGNAL)46printf("FE HAS SIGNAL\n");4748if (⋆stat & FE_SPECTRUM_INV)49printf("SPEKTRUM INV\n");5051return 0;52}535455/⋆ tune qpsk ⋆/56/⋆ freq: frequency of transponder ⋆/57/⋆ vpid, apid, tpid: PIDs of video, audio and teletext TS packets ⋆/58/⋆ diseqc: DiSEqC address of the used LNB ⋆/59/⋆ pol: Polarisation ⋆/60/⋆ srate: Symbol Rate ⋆/61/⋆ fec. FEC ⋆/62/⋆ lnb_lof1: local frequency of lower LNB band ⋆/63/⋆ lnb_lof2: local frequency of upper LNB band ⋆/64/⋆ lnb_slof: switch frequency of LNB ⋆/6566int set_qpsk_channel(int freq, int vpid, int apid, int tpid,67int diseqc, int pol, int srate, int fec, int lnb_lof1,68int lnb_lof2, int lnb_slof)69{70struct secCommand scmd;71struct secCmdSequence scmds;72struct dmx_pes_filter_params pesFilterParams;73FrontendParameters frp;74struct pollfd pfd[1];75FrontendEvent event;76int demux1, demux2, demux3, front;7778frequency = (uint32_t) freq;79symbolrate = (uint32_t) srate;8081if((front = open(FRONT,O_RDWR)) < 0){82perror("FRONTEND DEVICE: ");83return -1;84}8586if((sec = open(SEC,O_RDWR)) < 0){87perror("SEC DEVICE: ");88return -1;89}9091if (demux1 < 0){92if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))93< 0){94perror("DEMUX DEVICE: ");95return -1;96}97}9899if (demux2 < 0){100if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))101< 0){102perror("DEMUX DEVICE: ");103return -1;104}105}106107if (demux3 < 0){108if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))109< 0){110perror("DEMUX DEVICE: ");111return -1;112}113}114115if (freq < lnb_slof) {116frp.Frequency = (freq - lnb_lof1);117scmds.continuousTone = SEC_TONE_OFF;118} else {119frp.Frequency = (freq - lnb_lof2);120scmds.continuousTone = SEC_TONE_ON;121}122frp.Inversion = INVERSION_AUTO;123if (pol) scmds.voltage = SEC_VOLTAGE_18;124else scmds.voltage = SEC_VOLTAGE_13;125126scmd.type=0;127scmd.u.diseqc.addr=0x10;128scmd.u.diseqc.cmd=0x38;129scmd.u.diseqc.numParams=1;130scmd.u.diseqc.params[0] = 0xF0 | ((diseqc ⋆ 4) & 0x0F) |131(scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |132(scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);133134scmds.miniCommand=SEC_MINI_NONE;135scmds.numCommands=1;136scmds.commands=&scmd;137if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){138perror("SEC SEND: ");139return -1;140}141142if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){143perror("SEC SEND: ");144return -1;145}146147frp.u.qpsk.SymbolRate = srate;148frp.u.qpsk.FEC_inner = fec;149150if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){151perror("QPSK TUNE: ");152return -1;153}154155pfd[0].fd = front;156pfd[0].events = POLLIN;157158if (poll(pfd,1,3000)){159if (pfd[0].revents & POLLIN){160printf("Getting QPSK event\n");161if ( ioctl(front, FE_GET_EVENT, &event)162163== -EOVERFLOW){164perror("qpsk get event");165return -1;166}167printf("Received ");168switch(event.type){169case FE_UNEXPECTED_EV:170printf("unexpected event\n");171return -1;172case FE_FAILURE_EV:173printf("failure event\n");174return -1;175176case FE_COMPLETION_EV:177printf("completion event\n");178}179}180}181182183pesFilterParams.pid = vpid;184pesFilterParams.input = DMX_IN_FRONTEND;185pesFilterParams.output = DMX_OUT_DECODER;186pesFilterParams.pes_type = DMX_PES_VIDEO;187pesFilterParams.flags = DMX_IMMEDIATE_START;188if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){189perror("set_vpid");190return -1;191}192193pesFilterParams.pid = apid;194pesFilterParams.input = DMX_IN_FRONTEND;195pesFilterParams.output = DMX_OUT_DECODER;196pesFilterParams.pes_type = DMX_PES_AUDIO;197pesFilterParams.flags = DMX_IMMEDIATE_START;198if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){199perror("set_apid");200return -1;201}202203pesFilterParams.pid = tpid;204pesFilterParams.input = DMX_IN_FRONTEND;205pesFilterParams.output = DMX_OUT_DECODER;206pesFilterParams.pes_type = DMX_PES_TELETEXT;207pesFilterParams.flags = DMX_IMMEDIATE_START;208if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){209perror("set_tpid");210return -1;211}212213return has_signal(fds);214}215216</programlisting>217<para>The program assumes that you are using a universal LNB and a standard DiSEqC218switch with up to 4 addresses. Of course, you could build in some more checking if219tuning was successful and maybe try to repeat the tuning process. Depending on the220external hardware, i.e. LNB and DiSEqC switch, and weather conditions this may be221necessary.222</para>223</section>224225<section id="the_dvr_device">226<title>The DVR device</title>227<para>The following program code shows how to use the DVR device for recording.228</para>229<programlisting>230#include <sys/ioctl.h>231#include <stdio.h>232#include <stdint.h>233#include <sys/types.h>234#include <sys/stat.h>235#include <fcntl.h>236#include <time.h>237#include <unistd.h>238239#include <linux/dvb/dmx.h>240#include <linux/dvb/video.h>241#include <sys/poll.h>242#define DVR "/dev/dvb/adapter0/dvr1"243#define AUDIO "/dev/dvb/adapter0/audio1"244#define VIDEO "/dev/dvb/adapter0/video1"245246#define BUFFY (188⋆20)247#define MAX_LENGTH (1024⋆1024⋆5) /⋆ record 5MB ⋆/248249250/⋆ switch the demuxes to recording, assuming the transponder is tuned ⋆/251252/⋆ demux1, demux2: file descriptor of video and audio filters ⋆/253/⋆ vpid, apid: PIDs of video and audio channels ⋆/254255int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)256{257struct dmx_pes_filter_params pesFilterParams;258259if (demux1 < 0){260if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))261< 0){262perror("DEMUX DEVICE: ");263return -1;264}265}266267if (demux2 < 0){268if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))269< 0){270perror("DEMUX DEVICE: ");271return -1;272}273}274275pesFilterParams.pid = vpid;276pesFilterParams.input = DMX_IN_FRONTEND;277pesFilterParams.output = DMX_OUT_TS_TAP;278pesFilterParams.pes_type = DMX_PES_VIDEO;279pesFilterParams.flags = DMX_IMMEDIATE_START;280if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){281perror("DEMUX DEVICE");282return -1;283}284pesFilterParams.pid = apid;285pesFilterParams.input = DMX_IN_FRONTEND;286pesFilterParams.output = DMX_OUT_TS_TAP;287pesFilterParams.pes_type = DMX_PES_AUDIO;288pesFilterParams.flags = DMX_IMMEDIATE_START;289if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){290perror("DEMUX DEVICE");291return -1;292}293return 0;294}295296/⋆ start recording MAX_LENGTH , assuming the transponder is tuned ⋆/297298/⋆ demux1, demux2: file descriptor of video and audio filters ⋆/299/⋆ vpid, apid: PIDs of video and audio channels ⋆/300int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)301{302int i;303int len;304int written;305uint8_t buf[BUFFY];306uint64_t length;307struct pollfd pfd[1];308int dvr, dvr_out;309310/⋆ open dvr device ⋆/311if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){312perror("DVR DEVICE");313return -1;314}315316/⋆ switch video and audio demuxes to dvr ⋆/317printf ("Switching dvr on\n");318i = switch_to_record(demux1, demux2, vpid, apid);319printf("finished: ");320321printf("Recording %2.0f MB of test file in TS format\n",322MAX_LENGTH/(1024.0⋆1024.0));323length = 0;324325/⋆ open output file ⋆/326if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT327|O_TRUNC, S_IRUSR|S_IWUSR328|S_IRGRP|S_IWGRP|S_IROTH|329S_IWOTH)) < 0){330perror("Can't open file for dvr test");331return -1;332}333334pfd[0].fd = dvr;335pfd[0].events = POLLIN;336337/⋆ poll for dvr data and write to file ⋆/338while (length < MAX_LENGTH ) {339if (poll(pfd,1,1)){340if (pfd[0].revents & POLLIN){341len = read(dvr, buf, BUFFY);342if (len < 0){343perror("recording");344return -1;345}346if (len > 0){347written = 0;348while (written < len)349written +=350write (dvr_out,351buf, len);352length += len;353printf("written %2.0f MB\r",354length/1024./1024.);355}356}357}358}359return 0;360}361362</programlisting>363364</section>365366367