1 <title>Examples</title>
2 <para>In this section we would like to present some examples for using the DVB API.
4 <para>Maintainer note: This section is out of date. Please refer to the sample programs packaged
5 with the driver distribution from <ulink url="http://linuxtv.org/hg/dvb-apps" />.
10 <para>We will start with a generic tuning subroutine that uses the frontend and SEC, as well as
11 the demux devices. The example is given for QPSK tuners, but can easily be adjusted for
15 #include <sys/ioctl.h>
16 #include <stdio.h>
17 #include <stdint.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <time.h>
22 #include <unistd.h>
24 #include <linux/dvb/dmx.h>
25 #include <linux/dvb/frontend.h>
26 #include <linux/dvb/sec.h>
27 #include <sys/poll.h>
29 #define DMX "/dev/dvb/adapter0/demux1"
30 #define FRONT "/dev/dvb/adapter0/frontend1"
31 #define SEC "/dev/dvb/adapter0/sec1"
33 /⋆ routine for checking if we have a signal and other status information⋆/
34 int FEReadStatus(int fd, fe_status_t ⋆stat)
38 if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){
39 perror("FE READ STATUS: ");
43 if (⋆stat & FE_HAS_POWER)
44 printf("FE HAS POWER\n");
46 if (⋆stat & FE_HAS_SIGNAL)
47 printf("FE HAS SIGNAL\n");
49 if (⋆stat & FE_SPECTRUM_INV)
50 printf("SPEKTRUM INV\n");
56 /⋆ tune qpsk ⋆/
57 /⋆ freq: frequency of transponder ⋆/
58 /⋆ vpid, apid, tpid: PIDs of video, audio and teletext TS packets ⋆/
59 /⋆ diseqc: DiSEqC address of the used LNB ⋆/
60 /⋆ pol: Polarisation ⋆/
61 /⋆ srate: Symbol Rate ⋆/
62 /⋆ fec. FEC ⋆/
63 /⋆ lnb_lof1: local frequency of lower LNB band ⋆/
64 /⋆ lnb_lof2: local frequency of upper LNB band ⋆/
65 /⋆ lnb_slof: switch frequency of LNB ⋆/
67 int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
68 int diseqc, int pol, int srate, int fec, int lnb_lof1,
69 int lnb_lof2, int lnb_slof)
71 struct secCommand scmd;
72 struct secCmdSequence scmds;
73 struct dmx_pes_filter_params pesFilterParams;
74 FrontendParameters frp;
77 int demux1, demux2, demux3, front;
79 frequency = (uint32_t) freq;
80 symbolrate = (uint32_t) srate;
82 if((front = open(FRONT,O_RDWR)) < 0){
83 perror("FRONTEND DEVICE: ");
87 if((sec = open(SEC,O_RDWR)) < 0){
88 perror("SEC DEVICE: ");
92 if (demux1 < 0){
93 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
95 perror("DEMUX DEVICE: ");
100 if (demux2 < 0){
101 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
103 perror("DEMUX DEVICE: ");
108 if (demux3 < 0){
109 if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
111 perror("DEMUX DEVICE: ");
116 if (freq < lnb_slof) {
117 frp.Frequency = (freq - lnb_lof1);
118 scmds.continuousTone = SEC_TONE_OFF;
120 frp.Frequency = (freq - lnb_lof2);
121 scmds.continuousTone = SEC_TONE_ON;
123 frp.Inversion = INVERSION_AUTO;
124 if (pol) scmds.voltage = SEC_VOLTAGE_18;
125 else scmds.voltage = SEC_VOLTAGE_13;
128 scmd.u.diseqc.addr=0x10;
129 scmd.u.diseqc.cmd=0x38;
130 scmd.u.diseqc.numParams=1;
131 scmd.u.diseqc.params[0] = 0xF0 | ((diseqc ⋆ 4) & 0x0F) |
132 (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
133 (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
135 scmds.miniCommand=SEC_MINI_NONE;
137 scmds.commands=&scmd;
138 if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
139 perror("SEC SEND: ");
143 if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
144 perror("SEC SEND: ");
148 frp.u.qpsk.SymbolRate = srate;
149 frp.u.qpsk.FEC_inner = fec;
151 if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){
152 perror("QPSK TUNE: ");
157 pfd[0].events = POLLIN;
159 if (poll(pfd,1,3000)){
160 if (pfd[0].revents & POLLIN){
161 printf("Getting QPSK event\n");
162 if ( ioctl(front, FE_GET_EVENT, &event)
165 perror("qpsk get event");
170 case FE_UNEXPECTED_EV:
171 printf("unexpected event\n");
174 printf("failure event\n");
177 case FE_COMPLETION_EV:
178 printf("completion event\n");
184 pesFilterParams.pid = vpid;
185 pesFilterParams.input = DMX_IN_FRONTEND;
186 pesFilterParams.output = DMX_OUT_DECODER;
187 pesFilterParams.pes_type = DMX_PES_VIDEO;
188 pesFilterParams.flags = DMX_IMMEDIATE_START;
189 if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
194 pesFilterParams.pid = apid;
195 pesFilterParams.input = DMX_IN_FRONTEND;
196 pesFilterParams.output = DMX_OUT_DECODER;
197 pesFilterParams.pes_type = DMX_PES_AUDIO;
198 pesFilterParams.flags = DMX_IMMEDIATE_START;
199 if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
204 pesFilterParams.pid = tpid;
205 pesFilterParams.input = DMX_IN_FRONTEND;
206 pesFilterParams.output = DMX_OUT_DECODER;
207 pesFilterParams.pes_type = DMX_PES_TELETEXT;
208 pesFilterParams.flags = DMX_IMMEDIATE_START;
209 if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
214 return has_signal(fds);
218 <para>The program assumes that you are using a universal LNB and a standard DiSEqC
219 switch with up to 4 addresses. Of course, you could build in some more checking if
220 tuning was successful and maybe try to repeat the tuning process. Depending on the
221 external hardware, i.e. LNB and DiSEqC switch, and weather conditions this may be
226 <section id="the_dvr_device">
227 <title>The DVR device</title>
228 <para>The following program code shows how to use the DVR device for recording.
231 #include <sys/ioctl.h>
232 #include <stdio.h>
233 #include <stdint.h>
234 #include <sys/types.h>
235 #include <sys/stat.h>
236 #include <fcntl.h>
237 #include <time.h>
238 #include <unistd.h>
240 #include <linux/dvb/dmx.h>
241 #include <linux/dvb/video.h>
242 #include <sys/poll.h>
243 #define DVR "/dev/dvb/adapter0/dvr1"
244 #define AUDIO "/dev/dvb/adapter0/audio1"
245 #define VIDEO "/dev/dvb/adapter0/video1"
247 #define BUFFY (188⋆20)
248 #define MAX_LENGTH (1024⋆1024⋆5) /⋆ record 5MB ⋆/
251 /⋆ switch the demuxes to recording, assuming the transponder is tuned ⋆/
253 /⋆ demux1, demux2: file descriptor of video and audio filters ⋆/
254 /⋆ vpid, apid: PIDs of video and audio channels ⋆/
256 int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
258 struct dmx_pes_filter_params pesFilterParams;
260 if (demux1 < 0){
261 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
263 perror("DEMUX DEVICE: ");
268 if (demux2 < 0){
269 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
271 perror("DEMUX DEVICE: ");
276 pesFilterParams.pid = vpid;
277 pesFilterParams.input = DMX_IN_FRONTEND;
278 pesFilterParams.output = DMX_OUT_TS_TAP;
279 pesFilterParams.pes_type = DMX_PES_VIDEO;
280 pesFilterParams.flags = DMX_IMMEDIATE_START;
281 if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
282 perror("DEMUX DEVICE");
285 pesFilterParams.pid = apid;
286 pesFilterParams.input = DMX_IN_FRONTEND;
287 pesFilterParams.output = DMX_OUT_TS_TAP;
288 pesFilterParams.pes_type = DMX_PES_AUDIO;
289 pesFilterParams.flags = DMX_IMMEDIATE_START;
290 if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
291 perror("DEMUX DEVICE");
297 /⋆ start recording MAX_LENGTH , assuming the transponder is tuned ⋆/
299 /⋆ demux1, demux2: file descriptor of video and audio filters ⋆/
300 /⋆ vpid, apid: PIDs of video and audio channels ⋆/
301 int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
308 struct pollfd pfd[1];
311 /⋆ open dvr device ⋆/
312 if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){
313 perror("DVR DEVICE");
317 /⋆ switch video and audio demuxes to dvr ⋆/
318 printf ("Switching dvr on\n");
319 i = switch_to_record(demux1, demux2, vpid, apid);
320 printf("finished: ");
322 printf("Recording %2.0f MB of test file in TS format\n",
323 MAX_LENGTH/(1024.0⋆1024.0));
326 /⋆ open output file ⋆/
327 if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
328 |O_TRUNC, S_IRUSR|S_IWUSR
329 |S_IRGRP|S_IWGRP|S_IROTH|
330 S_IWOTH)) < 0){
331 perror("Can't open file for dvr test");
336 pfd[0].events = POLLIN;
338 /⋆ poll for dvr data and write to file ⋆/
339 while (length < MAX_LENGTH ) {
341 if (pfd[0].revents & POLLIN){
342 len = read(dvr, buf, BUFFY);
349 while (written < len)
354 printf("written %2.0f MB\r",