diff options
Diffstat (limited to 'Documentation/DocBook/dvb/examples.xml')
-rw-r--r-- | Documentation/DocBook/dvb/examples.xml | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/Documentation/DocBook/dvb/examples.xml b/Documentation/DocBook/dvb/examples.xml new file mode 100644 index 000000000000..b89dceda6048 --- /dev/null +++ b/Documentation/DocBook/dvb/examples.xml | |||
@@ -0,0 +1,365 @@ | |||
1 | <title>Examples</title> | ||
2 | <para>In this section we would like to present some examples for using the DVB API. | ||
3 | </para> | ||
4 | <para>Maintainer note: This section is out of date. Please refer to the sample programs packaged | ||
5 | with the driver distribution from <emphasis role="tt">http://linuxtv.org/</emphasis>. | ||
6 | </para> | ||
7 | |||
8 | <section id="tuning"> | ||
9 | <title>Tuning</title> | ||
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 | ||
12 | QAM. | ||
13 | </para> | ||
14 | <programlisting> | ||
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> | ||
23 | |||
24 | #include <linux/dvb/dmx.h> | ||
25 | #include <linux/dvb/frontend.h> | ||
26 | #include <linux/dvb/sec.h> | ||
27 | #include <sys/poll.h> | ||
28 | |||
29 | #define DMX "/dev/dvb/adapter0/demux1" | ||
30 | #define FRONT "/dev/dvb/adapter0/frontend1" | ||
31 | #define SEC "/dev/dvb/adapter0/sec1" | ||
32 | |||
33 | /⋆ routine for checking if we have a signal and other status information⋆/ | ||
34 | int FEReadStatus(int fd, fe_status_t ⋆stat) | ||
35 | { | ||
36 | int ans; | ||
37 | |||
38 | if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ | ||
39 | perror("FE READ STATUS: "); | ||
40 | return -1; | ||
41 | } | ||
42 | |||
43 | if (⋆stat & FE_HAS_POWER) | ||
44 | printf("FE HAS POWER\n"); | ||
45 | |||
46 | if (⋆stat & FE_HAS_SIGNAL) | ||
47 | printf("FE HAS SIGNAL\n"); | ||
48 | |||
49 | if (⋆stat & FE_SPECTRUM_INV) | ||
50 | printf("SPEKTRUM INV\n"); | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | |||
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 ⋆/ | ||
66 | |||
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) | ||
70 | { | ||
71 | struct secCommand scmd; | ||
72 | struct secCmdSequence scmds; | ||
73 | struct dmx_pes_filter_params pesFilterParams; | ||
74 | FrontendParameters frp; | ||
75 | struct pollfd pfd[1]; | ||
76 | FrontendEvent event; | ||
77 | int demux1, demux2, demux3, front; | ||
78 | |||
79 | frequency = (uint32_t) freq; | ||
80 | symbolrate = (uint32_t) srate; | ||
81 | |||
82 | if((front = open(FRONT,O_RDWR)) < 0){ | ||
83 | perror("FRONTEND DEVICE: "); | ||
84 | return -1; | ||
85 | } | ||
86 | |||
87 | if((sec = open(SEC,O_RDWR)) < 0){ | ||
88 | perror("SEC DEVICE: "); | ||
89 | return -1; | ||
90 | } | ||
91 | |||
92 | if (demux1 < 0){ | ||
93 | if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) | ||
94 | < 0){ | ||
95 | perror("DEMUX DEVICE: "); | ||
96 | return -1; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | if (demux2 < 0){ | ||
101 | if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) | ||
102 | < 0){ | ||
103 | perror("DEMUX DEVICE: "); | ||
104 | return -1; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | if (demux3 < 0){ | ||
109 | if ((demux3=open(DMX, O_RDWR|O_NONBLOCK)) | ||
110 | < 0){ | ||
111 | perror("DEMUX DEVICE: "); | ||
112 | return -1; | ||
113 | } | ||
114 | } | ||
115 | |||
116 | if (freq < lnb_slof) { | ||
117 | frp.Frequency = (freq - lnb_lof1); | ||
118 | scmds.continuousTone = SEC_TONE_OFF; | ||
119 | } else { | ||
120 | frp.Frequency = (freq - lnb_lof2); | ||
121 | scmds.continuousTone = SEC_TONE_ON; | ||
122 | } | ||
123 | frp.Inversion = INVERSION_AUTO; | ||
124 | if (pol) scmds.voltage = SEC_VOLTAGE_18; | ||
125 | else scmds.voltage = SEC_VOLTAGE_13; | ||
126 | |||
127 | scmd.type=0; | ||
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); | ||
134 | |||
135 | scmds.miniCommand=SEC_MINI_NONE; | ||
136 | scmds.numCommands=1; | ||
137 | scmds.commands=&scmd; | ||
138 | if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ | ||
139 | perror("SEC SEND: "); | ||
140 | return -1; | ||
141 | } | ||
142 | |||
143 | if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){ | ||
144 | perror("SEC SEND: "); | ||
145 | return -1; | ||
146 | } | ||
147 | |||
148 | frp.u.qpsk.SymbolRate = srate; | ||
149 | frp.u.qpsk.FEC_inner = fec; | ||
150 | |||
151 | if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){ | ||
152 | perror("QPSK TUNE: "); | ||
153 | return -1; | ||
154 | } | ||
155 | |||
156 | pfd[0].fd = front; | ||
157 | pfd[0].events = POLLIN; | ||
158 | |||
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) | ||
163 | |||
164 | == -EOVERFLOW){ | ||
165 | perror("qpsk get event"); | ||
166 | return -1; | ||
167 | } | ||
168 | printf("Received "); | ||
169 | switch(event.type){ | ||
170 | case FE_UNEXPECTED_EV: | ||
171 | printf("unexpected event\n"); | ||
172 | return -1; | ||
173 | case FE_FAILURE_EV: | ||
174 | printf("failure event\n"); | ||
175 | return -1; | ||
176 | |||
177 | case FE_COMPLETION_EV: | ||
178 | printf("completion event\n"); | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | |||
183 | |||
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){ | ||
190 | perror("set_vpid"); | ||
191 | return -1; | ||
192 | } | ||
193 | |||
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){ | ||
200 | perror("set_apid"); | ||
201 | return -1; | ||
202 | } | ||
203 | |||
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){ | ||
210 | perror("set_tpid"); | ||
211 | return -1; | ||
212 | } | ||
213 | |||
214 | return has_signal(fds); | ||
215 | } | ||
216 | |||
217 | </programlisting> | ||
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 | ||
222 | necessary. | ||
223 | </para> | ||
224 | </section> | ||
225 | |||
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. | ||
229 | </para> | ||
230 | <programlisting> | ||
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> | ||
239 | |||
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" | ||
246 | |||
247 | #define BUFFY (188⋆20) | ||
248 | #define MAX_LENGTH (1024⋆1024⋆5) /⋆ record 5MB ⋆/ | ||
249 | |||
250 | |||
251 | /⋆ switch the demuxes to recording, assuming the transponder is tuned ⋆/ | ||
252 | |||
253 | /⋆ demux1, demux2: file descriptor of video and audio filters ⋆/ | ||
254 | /⋆ vpid, apid: PIDs of video and audio channels ⋆/ | ||
255 | |||
256 | int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid) | ||
257 | { | ||
258 | struct dmx_pes_filter_params pesFilterParams; | ||
259 | |||
260 | if (demux1 < 0){ | ||
261 | if ((demux1=open(DMX, O_RDWR|O_NONBLOCK)) | ||
262 | < 0){ | ||
263 | perror("DEMUX DEVICE: "); | ||
264 | return -1; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | if (demux2 < 0){ | ||
269 | if ((demux2=open(DMX, O_RDWR|O_NONBLOCK)) | ||
270 | < 0){ | ||
271 | perror("DEMUX DEVICE: "); | ||
272 | return -1; | ||
273 | } | ||
274 | } | ||
275 | |||
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"); | ||
283 | return -1; | ||
284 | } | ||
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"); | ||
292 | return -1; | ||
293 | } | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | /⋆ start recording MAX_LENGTH , assuming the transponder is tuned ⋆/ | ||
298 | |||
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) | ||
302 | { | ||
303 | int i; | ||
304 | int len; | ||
305 | int written; | ||
306 | uint8_t buf[BUFFY]; | ||
307 | uint64_t length; | ||
308 | struct pollfd pfd[1]; | ||
309 | int dvr, dvr_out; | ||
310 | |||
311 | /⋆ open dvr device ⋆/ | ||
312 | if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){ | ||
313 | perror("DVR DEVICE"); | ||
314 | return -1; | ||
315 | } | ||
316 | |||
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: "); | ||
321 | |||
322 | printf("Recording %2.0f MB of test file in TS format\n", | ||
323 | MAX_LENGTH/(1024.0⋆1024.0)); | ||
324 | length = 0; | ||
325 | |||
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"); | ||
332 | return -1; | ||
333 | } | ||
334 | |||
335 | pfd[0].fd = dvr; | ||
336 | pfd[0].events = POLLIN; | ||
337 | |||
338 | /⋆ poll for dvr data and write to file ⋆/ | ||
339 | while (length < MAX_LENGTH ) { | ||
340 | if (poll(pfd,1,1)){ | ||
341 | if (pfd[0].revents & POLLIN){ | ||
342 | len = read(dvr, buf, BUFFY); | ||
343 | if (len < 0){ | ||
344 | perror("recording"); | ||
345 | return -1; | ||
346 | } | ||
347 | if (len > 0){ | ||
348 | written = 0; | ||
349 | while (written < len) | ||
350 | written += | ||
351 | write (dvr_out, | ||
352 | buf, len); | ||
353 | length += len; | ||
354 | printf("written %2.0f MB\r", | ||
355 | length/1024./1024.); | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | </programlisting> | ||
364 | |||
365 | </section> | ||