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