fb: adv7393: off by one in probe function
[deliverable/linux.git] / Documentation / media / uapi / dvb / examples.rst
1 .. -*- coding: utf-8; mode: rst -*-
2
3 .. _dvb_examples:
4
5 ********
6 Examples
7 ********
8
9 In this section we would like to present some examples for using the DVB
10 API.
11
12 ..note:: This section is out of date, and the code below won't even
13 compile. Please refer to the
14 `libdvbv5 <https://linuxtv.org/docs/libdvbv5/index.html>`__ for
15 updated/recommended examples.
16
17
18 .. _tuning:
19
20 Example: Tuning
21 ===============
22
23 We will start with a generic tuning subroutine that uses the frontend
24 and SEC, as well as the demux devices. The example is given for QPSK
25 tuners, but can easily be adjusted for QAM.
26
27
28 .. code-block:: c
29
30 #include <sys/ioctl.h>
31 #include <stdio.h>
32 #include <stdint.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <time.h>
37 #include <unistd.h>
38
39 #include <linux/dvb/dmx.h>
40 #include <linux/dvb/frontend.h>
41 #include <linux/dvb/sec.h>
42 #include <sys/poll.h>
43
44 #define DMX "/dev/dvb/adapter0/demux1"
45 #define FRONT "/dev/dvb/adapter0/frontend1"
46 #define SEC "/dev/dvb/adapter0/sec1"
47
48 /* routine for checking if we have a signal and other status information*/
49 int FEReadStatus(int fd, fe_status_t *stat)
50 {
51 int ans;
52
53 if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){
54 perror("FE READ STATUS: ");
55 return -1;
56 }
57
58 if (*stat & FE_HAS_POWER)
59 printf("FE HAS POWER\\n");
60
61 if (*stat & FE_HAS_SIGNAL)
62 printf("FE HAS SIGNAL\\n");
63
64 if (*stat & FE_SPECTRUM_INV)
65 printf("SPEKTRUM INV\\n");
66
67 return 0;
68 }
69
70
71 /* tune qpsk */
72 /* freq: frequency of transponder */
73 /* vpid, apid, tpid: PIDs of video, audio and teletext TS packets */
74 /* diseqc: DiSEqC address of the used LNB */
75 /* pol: Polarisation */
76 /* srate: Symbol Rate */
77 /* fec. FEC */
78 /* lnb_lof1: local frequency of lower LNB band */
79 /* lnb_lof2: local frequency of upper LNB band */
80 /* lnb_slof: switch frequency of LNB */
81
82 int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
83 int diseqc, int pol, int srate, int fec, int lnb_lof1,
84 int lnb_lof2, int lnb_slof)
85 {
86 struct secCommand scmd;
87 struct secCmdSequence scmds;
88 struct dmx_pes_filter_params pesFilterParams;
89 FrontendParameters frp;
90 struct pollfd pfd[1];
91 FrontendEvent event;
92 int demux1, demux2, demux3, front;
93
94 frequency = (uint32_t) freq;
95 symbolrate = (uint32_t) srate;
96
97 if((front = open(FRONT,O_RDWR)) < 0){
98 perror("FRONTEND DEVICE: ");
99 return -1;
100 }
101
102 if((sec = open(SEC,O_RDWR)) < 0){
103 perror("SEC DEVICE: ");
104 return -1;
105 }
106
107 if (demux1 < 0){
108 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
109 < 0){
110 perror("DEMUX DEVICE: ");
111 return -1;
112 }
113 }
114
115 if (demux2 < 0){
116 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
117 < 0){
118 perror("DEMUX DEVICE: ");
119 return -1;
120 }
121 }
122
123 if (demux3 < 0){
124 if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
125 < 0){
126 perror("DEMUX DEVICE: ");
127 return -1;
128 }
129 }
130
131 if (freq < lnb_slof) {
132 frp.Frequency = (freq - lnb_lof1);
133 scmds.continuousTone = SEC_TONE_OFF;
134 } else {
135 frp.Frequency = (freq - lnb_lof2);
136 scmds.continuousTone = SEC_TONE_ON;
137 }
138 frp.Inversion = INVERSION_AUTO;
139 if (pol) scmds.voltage = SEC_VOLTAGE_18;
140 else scmds.voltage = SEC_VOLTAGE_13;
141
142 scmd.type=0;
143 scmd.u.diseqc.addr=0x10;
144 scmd.u.diseqc.cmd=0x38;
145 scmd.u.diseqc.numParams=1;
146 scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) |
147 (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
148 (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
149
150 scmds.miniCommand=SEC_MINI_NONE;
151 scmds.numCommands=1;
152 scmds.commands=&scmd;
153 if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
154 perror("SEC SEND: ");
155 return -1;
156 }
157
158 if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0){
159 perror("SEC SEND: ");
160 return -1;
161 }
162
163 frp.u.qpsk.SymbolRate = srate;
164 frp.u.qpsk.FEC_inner = fec;
165
166 if (ioctl(front, FE_SET_FRONTEND, &frp) < 0){
167 perror("QPSK TUNE: ");
168 return -1;
169 }
170
171 pfd[0].fd = front;
172 pfd[0].events = POLLIN;
173
174 if (poll(pfd,1,3000)){
175 if (pfd[0].revents & POLLIN){
176 printf("Getting QPSK event\\n");
177 if ( ioctl(front, FE_GET_EVENT, &event)
178
179 == -EOVERFLOW){
180 perror("qpsk get event");
181 return -1;
182 }
183 printf("Received ");
184 switch(event.type){
185 case FE_UNEXPECTED_EV:
186 printf("unexpected event\\n");
187 return -1;
188 case FE_FAILURE_EV:
189 printf("failure event\\n");
190 return -1;
191
192 case FE_COMPLETION_EV:
193 printf("completion event\\n");
194 }
195 }
196 }
197
198
199 pesFilterParams.pid = vpid;
200 pesFilterParams.input = DMX_IN_FRONTEND;
201 pesFilterParams.output = DMX_OUT_DECODER;
202 pesFilterParams.pes_type = DMX_PES_VIDEO;
203 pesFilterParams.flags = DMX_IMMEDIATE_START;
204 if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
205 perror("set_vpid");
206 return -1;
207 }
208
209 pesFilterParams.pid = apid;
210 pesFilterParams.input = DMX_IN_FRONTEND;
211 pesFilterParams.output = DMX_OUT_DECODER;
212 pesFilterParams.pes_type = DMX_PES_AUDIO;
213 pesFilterParams.flags = DMX_IMMEDIATE_START;
214 if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
215 perror("set_apid");
216 return -1;
217 }
218
219 pesFilterParams.pid = tpid;
220 pesFilterParams.input = DMX_IN_FRONTEND;
221 pesFilterParams.output = DMX_OUT_DECODER;
222 pesFilterParams.pes_type = DMX_PES_TELETEXT;
223 pesFilterParams.flags = DMX_IMMEDIATE_START;
224 if (ioctl(demux3, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
225 perror("set_tpid");
226 return -1;
227 }
228
229 return has_signal(fds);
230 }
231
232 The program assumes that you are using a universal LNB and a standard
233 DiSEqC switch with up to 4 addresses. Of course, you could build in some
234 more checking if tuning was successful and maybe try to repeat the
235 tuning process. Depending on the external hardware, i.e. LNB and DiSEqC
236 switch, and weather conditions this may be necessary.
237
238
239 .. _the_dvr_device:
240
241 Example: The DVR device
242 ========================
243
244 The following program code shows how to use the DVR device for
245 recording.
246
247
248 .. code-block:: c
249
250 #include <sys/ioctl.h>
251 #include <stdio.h>
252 #include <stdint.h>
253 #include <sys/types.h>
254 #include <sys/stat.h>
255 #include <fcntl.h>
256 #include <time.h>
257 #include <unistd.h>
258
259 #include <linux/dvb/dmx.h>
260 #include <linux/dvb/video.h>
261 #include <sys/poll.h>
262 #define DVR "/dev/dvb/adapter0/dvr1"
263 #define AUDIO "/dev/dvb/adapter0/audio1"
264 #define VIDEO "/dev/dvb/adapter0/video1"
265
266 #define BUFFY (188*20)
267 #define MAX_LENGTH (1024*1024*5) /* record 5MB */
268
269
270 /* switch the demuxes to recording, assuming the transponder is tuned */
271
272 /* demux1, demux2: file descriptor of video and audio filters */
273 /* vpid, apid: PIDs of video and audio channels */
274
275 int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
276 {
277 struct dmx_pes_filter_params pesFilterParams;
278
279 if (demux1 < 0){
280 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
281 < 0){
282 perror("DEMUX DEVICE: ");
283 return -1;
284 }
285 }
286
287 if (demux2 < 0){
288 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
289 < 0){
290 perror("DEMUX DEVICE: ");
291 return -1;
292 }
293 }
294
295 pesFilterParams.pid = vpid;
296 pesFilterParams.input = DMX_IN_FRONTEND;
297 pesFilterParams.output = DMX_OUT_TS_TAP;
298 pesFilterParams.pes_type = DMX_PES_VIDEO;
299 pesFilterParams.flags = DMX_IMMEDIATE_START;
300 if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
301 perror("DEMUX DEVICE");
302 return -1;
303 }
304 pesFilterParams.pid = apid;
305 pesFilterParams.input = DMX_IN_FRONTEND;
306 pesFilterParams.output = DMX_OUT_TS_TAP;
307 pesFilterParams.pes_type = DMX_PES_AUDIO;
308 pesFilterParams.flags = DMX_IMMEDIATE_START;
309 if (ioctl(demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0){
310 perror("DEMUX DEVICE");
311 return -1;
312 }
313 return 0;
314 }
315
316 /* start recording MAX_LENGTH , assuming the transponder is tuned */
317
318 /* demux1, demux2: file descriptor of video and audio filters */
319 /* vpid, apid: PIDs of video and audio channels */
320 int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
321 {
322 int i;
323 int len;
324 int written;
325 uint8_t buf[BUFFY];
326 uint64_t length;
327 struct pollfd pfd[1];
328 int dvr, dvr_out;
329
330 /* open dvr device */
331 if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) < 0){
332 perror("DVR DEVICE");
333 return -1;
334 }
335
336 /* switch video and audio demuxes to dvr */
337 printf ("Switching dvr on\\n");
338 i = switch_to_record(demux1, demux2, vpid, apid);
339 printf("finished: ");
340
341 printf("Recording %2.0f MB of test file in TS format\\n",
342 MAX_LENGTH/(1024.0*1024.0));
343 length = 0;
344
345 /* open output file */
346 if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
347 |O_TRUNC, S_IRUSR|S_IWUSR
348 |S_IRGRP|S_IWGRP|S_IROTH|
349 S_IWOTH)) < 0){
350 perror("Can't open file for dvr test");
351 return -1;
352 }
353
354 pfd[0].fd = dvr;
355 pfd[0].events = POLLIN;
356
357 /* poll for dvr data and write to file */
358 while (length < MAX_LENGTH ) {
359 if (poll(pfd,1,1)){
360 if (pfd[0].revents & POLLIN){
361 len = read(dvr, buf, BUFFY);
362 if (len < 0){
363 perror("recording");
364 return -1;
365 }
366 if (len > 0){
367 written = 0;
368 while (written < len)
369 written +=
370 write (dvr_out,
371 buf, len);
372 length += len;
373 printf("written %2.0f MB\\r",
374 length/1024./1024.);
375 }
376 }
377 }
378 }
379 return 0;
380 }
This page took 0.064702 seconds and 5 git commands to generate.