1 <title>Examples</title>
2 <para>In this section we would like to present some examples for using the DVB API.
4 <para>NOTE: This section is out of date, and the code below won't even
5 compile. Please refer to the
6 <ulink url="http://linuxtv.org/docs/libdvbv5/index.html">libdvbv5</ulink>
7 for updated/recommended examples.
12 <para>We will start with a generic tuning subroutine that uses the frontend and SEC, as well as
13 the demux devices. The example is given for QPSK tuners, but can easily be adjusted for
17 #include <sys/ioctl.h>
18 #include <stdio.h>
19 #include <stdint.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <time.h>
24 #include <unistd.h>
26 #include <linux/dvb/dmx.h>
27 #include <linux/dvb/frontend.h>
28 #include <linux/dvb/sec.h>
29 #include <sys/poll.h>
31 #define DMX "/dev/dvb/adapter0/demux1"
32 #define FRONT "/dev/dvb/adapter0/frontend1"
33 #define SEC "/dev/dvb/adapter0/sec1"
35 /⋆ routine for checking if we have a signal and other status information⋆/
36 int FEReadStatus(int fd, fe_status_t ⋆stat)
40 if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){
41 perror("FE READ STATUS: ");
45 if (⋆stat & FE_HAS_POWER)
46 printf("FE HAS POWER\n");
48 if (⋆stat & FE_HAS_SIGNAL)
49 printf("FE HAS SIGNAL\n");
51 if (⋆stat & FE_SPECTRUM_INV)
52 printf("SPEKTRUM INV\n");
58 /⋆ tune qpsk ⋆/
59 /⋆ freq: frequency of transponder ⋆/
60 /⋆ vpid, apid, tpid: PIDs of video, audio and teletext TS packets ⋆/
61 /⋆ diseqc: DiSEqC address of the used LNB ⋆/
62 /⋆ pol: Polarisation ⋆/
63 /⋆ srate: Symbol Rate ⋆/
64 /⋆ fec. FEC ⋆/
65 /⋆ lnb_lof1: local frequency of lower LNB band ⋆/
66 /⋆ lnb_lof2: local frequency of upper LNB band ⋆/
67 /⋆ lnb_slof: switch frequency of LNB ⋆/
69 int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
70 int diseqc, int pol, int srate, int fec, int lnb_lof1,
71 int lnb_lof2, int lnb_slof)
73 struct secCommand scmd;
74 struct secCmdSequence scmds;
75 struct dmx_pes_filter_params pesFilterParams;
76 FrontendParameters frp;
79 int demux1, demux2, demux3, front;
81 frequency = (uint32_t) freq;
82 symbolrate = (uint32_t) srate;
84 if((front = open(FRONT,O_RDWR)) < 0){
85 perror("FRONTEND DEVICE: ");
89 if((sec = open(SEC,O_RDWR)) < 0){
90 perror("SEC DEVICE: ");
94 if (demux1 < 0){
95 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
97 perror("DEMUX DEVICE: ");
102 if (demux2 < 0){
103 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
105 perror("DEMUX DEVICE: ");
110 if (demux3 < 0){
111 if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
113 perror("DEMUX DEVICE: ");
118 if (freq < lnb_slof) {
119 frp.Frequency = (freq - lnb_lof1);
120 scmds.continuousTone = SEC_TONE_OFF;
122 frp.Frequency = (freq - lnb_lof2);
123 scmds.continuousTone = SEC_TONE_ON;
125 frp.Inversion = INVERSION_AUTO;
126 if (pol) scmds.voltage = SEC_VOLTAGE_18;
127 else scmds.voltage = SEC_VOLTAGE_13;
130 scmd.u.diseqc.addr=0x10;
131 scmd.u.diseqc.cmd=0x38;
132 scmd.u.diseqc.numParams=1;
133 scmd.u.diseqc.params[0] = 0xF0 | ((diseqc ⋆ 4) & 0x0F) |
134 (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
135 (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
137 scmds.miniCommand=SEC_MINI_NONE;
139 scmds.commands=&scmd;
140 if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
141 perror("SEC SEND: ");
145 if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
146 perror("SEC SEND: ");
150 frp.u.qpsk.SymbolRate = srate;
151 frp.u.qpsk.FEC_inner = fec;
153 if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){
154 perror("QPSK TUNE: ");
159 pfd[0].events = POLLIN;
161 if (poll(pfd,1,3000)){
162 if (pfd[0].revents & POLLIN){
163 printf("Getting QPSK event\n");
164 if ( ioctl(front, FE_GET_EVENT, &event)
167 perror("qpsk get event");
172 case FE_UNEXPECTED_EV:
173 printf("unexpected event\n");
176 printf("failure event\n");
179 case FE_COMPLETION_EV:
180 printf("completion event\n");
186 pesFilterParams.pid = vpid;
187 pesFilterParams.input = DMX_IN_FRONTEND;
188 pesFilterParams.output = DMX_OUT_DECODER;
189 pesFilterParams.pes_type = DMX_PES_VIDEO;
190 pesFilterParams.flags = DMX_IMMEDIATE_START;
191 if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
196 pesFilterParams.pid = apid;
197 pesFilterParams.input = DMX_IN_FRONTEND;
198 pesFilterParams.output = DMX_OUT_DECODER;
199 pesFilterParams.pes_type = DMX_PES_AUDIO;
200 pesFilterParams.flags = DMX_IMMEDIATE_START;
201 if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
206 pesFilterParams.pid = tpid;
207 pesFilterParams.input = DMX_IN_FRONTEND;
208 pesFilterParams.output = DMX_OUT_DECODER;
209 pesFilterParams.pes_type = DMX_PES_TELETEXT;
210 pesFilterParams.flags = DMX_IMMEDIATE_START;
211 if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
216 return has_signal(fds);
220 <para>The program assumes that you are using a universal LNB and a standard DiSEqC
221 switch with up to 4 addresses. Of course, you could build in some more checking if
222 tuning was successful and maybe try to repeat the tuning process. Depending on the
223 external hardware, i.e. LNB and DiSEqC switch, and weather conditions this may be
228 <section id="the_dvr_device">
229 <title>The DVR device</title>
230 <para>The following program code shows how to use the DVR device for recording.
233 #include <sys/ioctl.h>
234 #include <stdio.h>
235 #include <stdint.h>
236 #include <sys/types.h>
237 #include <sys/stat.h>
238 #include <fcntl.h>
239 #include <time.h>
240 #include <unistd.h>
242 #include <linux/dvb/dmx.h>
243 #include <linux/dvb/video.h>
244 #include <sys/poll.h>
245 #define DVR "/dev/dvb/adapter0/dvr1"
246 #define AUDIO "/dev/dvb/adapter0/audio1"
247 #define VIDEO "/dev/dvb/adapter0/video1"
249 #define BUFFY (188⋆20)
250 #define MAX_LENGTH (1024⋆1024⋆5) /⋆ record 5MB ⋆/
253 /⋆ switch the demuxes to recording, assuming the transponder is tuned ⋆/
255 /⋆ demux1, demux2: file descriptor of video and audio filters ⋆/
256 /⋆ vpid, apid: PIDs of video and audio channels ⋆/
258 int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
260 struct dmx_pes_filter_params pesFilterParams;
262 if (demux1 < 0){
263 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
265 perror("DEMUX DEVICE: ");
270 if (demux2 < 0){
271 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
273 perror("DEMUX DEVICE: ");
278 pesFilterParams.pid = vpid;
279 pesFilterParams.input = DMX_IN_FRONTEND;
280 pesFilterParams.output = DMX_OUT_TS_TAP;
281 pesFilterParams.pes_type = DMX_PES_VIDEO;
282 pesFilterParams.flags = DMX_IMMEDIATE_START;
283 if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
284 perror("DEMUX DEVICE");
287 pesFilterParams.pid = apid;
288 pesFilterParams.input = DMX_IN_FRONTEND;
289 pesFilterParams.output = DMX_OUT_TS_TAP;
290 pesFilterParams.pes_type = DMX_PES_AUDIO;
291 pesFilterParams.flags = DMX_IMMEDIATE_START;
292 if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
293 perror("DEMUX DEVICE");
299 /⋆ start recording MAX_LENGTH , assuming the transponder is tuned ⋆/
301 /⋆ demux1, demux2: file descriptor of video and audio filters ⋆/
302 /⋆ vpid, apid: PIDs of video and audio channels ⋆/
303 int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
310 struct pollfd pfd[1];
313 /⋆ open dvr device ⋆/
314 if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){
315 perror("DVR DEVICE");
319 /⋆ switch video and audio demuxes to dvr ⋆/
320 printf ("Switching dvr on\n");
321 i = switch_to_record(demux1, demux2, vpid, apid);
322 printf("finished: ");
324 printf("Recording %2.0f MB of test file in TS format\n",
325 MAX_LENGTH/(1024.0⋆1024.0));
328 /⋆ open output file ⋆/
329 if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
330 |O_TRUNC, S_IRUSR|S_IWUSR
331 |S_IRGRP|S_IWGRP|S_IROTH|
332 S_IWOTH)) < 0){
333 perror("Can't open file for dvr test");
338 pfd[0].events = POLLIN;
340 /⋆ poll for dvr data and write to file ⋆/
341 while (length < MAX_LENGTH ) {
343 if (pfd[0].revents & POLLIN){
344 len = read(dvr, buf, BUFFY);
351 while (written < len)
356 printf("written %2.0f MB\r",