]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - Documentation/DocBook/media/dvb/examples.xml
[media] DocBook: Fix typo in intro.xml
[karo-tx-linux.git] / Documentation / DocBook / media / dvb / examples.xml
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>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.
8 </para>
9
10 <section id="tuning">
11 <title>Tuning</title>
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
14 QAM.
15 </para>
16 <programlisting>
17  #include &#x003C;sys/ioctl.h&#x003E;
18  #include &#x003C;stdio.h&#x003E;
19  #include &#x003C;stdint.h&#x003E;
20  #include &#x003C;sys/types.h&#x003E;
21  #include &#x003C;sys/stat.h&#x003E;
22  #include &#x003C;fcntl.h&#x003E;
23  #include &#x003C;time.h&#x003E;
24  #include &#x003C;unistd.h&#x003E;
25
26  #include &#x003C;linux/dvb/dmx.h&#x003E;
27  #include &#x003C;linux/dvb/frontend.h&#x003E;
28  #include &#x003C;linux/dvb/sec.h&#x003E;
29  #include &#x003C;sys/poll.h&#x003E;
30
31  #define DMX "/dev/dvb/adapter0/demux1"
32  #define FRONT "/dev/dvb/adapter0/frontend1"
33  #define SEC "/dev/dvb/adapter0/sec1"
34
35  /&#x22C6; routine for checking if we have a signal and other status information&#x22C6;/
36  int FEReadStatus(int fd, fe_status_t &#x22C6;stat)
37  {
38          int ans;
39
40          if ( (ans = ioctl(fd,FE_READ_STATUS,stat) &#x003C; 0)){
41                  perror("FE READ STATUS: ");
42                  return -1;
43          }
44
45          if (&#x22C6;stat &amp; FE_HAS_POWER)
46                  printf("FE HAS POWER\n");
47
48          if (&#x22C6;stat &amp; FE_HAS_SIGNAL)
49                  printf("FE HAS SIGNAL\n");
50
51          if (&#x22C6;stat &amp; FE_SPECTRUM_INV)
52                  printf("SPEKTRUM INV\n");
53
54          return 0;
55  }
56
57
58  /&#x22C6; tune qpsk &#x22C6;/
59  /&#x22C6; freq:             frequency of transponder                      &#x22C6;/
60  /&#x22C6; vpid, apid, tpid: PIDs of video, audio and teletext TS packets  &#x22C6;/
61  /&#x22C6; diseqc:           DiSEqC address of the used LNB                &#x22C6;/
62  /&#x22C6; pol:              Polarisation                                  &#x22C6;/
63  /&#x22C6; srate:            Symbol Rate                                   &#x22C6;/
64  /&#x22C6; fec.              FEC                                           &#x22C6;/
65  /&#x22C6; lnb_lof1:         local frequency of lower LNB band             &#x22C6;/
66  /&#x22C6; lnb_lof2:         local frequency of upper LNB band             &#x22C6;/
67  /&#x22C6; lnb_slof:         switch frequency of LNB                       &#x22C6;/
68
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)
72  {
73          struct secCommand scmd;
74          struct secCmdSequence scmds;
75          struct dmx_pes_filter_params pesFilterParams;
76          FrontendParameters frp;
77          struct pollfd pfd[1];
78          FrontendEvent event;
79          int demux1, demux2, demux3, front;
80
81          frequency = (uint32_t) freq;
82          symbolrate = (uint32_t) srate;
83
84          if((front = open(FRONT,O_RDWR)) &#x003C; 0){
85                  perror("FRONTEND DEVICE: ");
86                  return -1;
87          }
88
89          if((sec = open(SEC,O_RDWR)) &#x003C; 0){
90                  perror("SEC DEVICE: ");
91                  return -1;
92          }
93
94          if (demux1 &#x003C; 0){
95                  if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
96                      &#x003C; 0){
97                          perror("DEMUX DEVICE: ");
98                          return -1;
99                  }
100          }
101
102          if (demux2 &#x003C; 0){
103                  if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
104                      &#x003C; 0){
105                          perror("DEMUX DEVICE: ");
106                          return -1;
107                  }
108          }
109
110          if (demux3 &#x003C; 0){
111                  if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
112                      &#x003C; 0){
113                          perror("DEMUX DEVICE: ");
114                          return -1;
115                  }
116          }
117
118          if (freq &#x003C; lnb_slof) {
119                  frp.Frequency = (freq - lnb_lof1);
120                  scmds.continuousTone = SEC_TONE_OFF;
121          } else {
122                  frp.Frequency = (freq - lnb_lof2);
123                  scmds.continuousTone = SEC_TONE_ON;
124          }
125          frp.Inversion = INVERSION_AUTO;
126          if (pol) scmds.voltage = SEC_VOLTAGE_18;
127          else scmds.voltage = SEC_VOLTAGE_13;
128
129          scmd.type=0;
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 &#x22C6; 4) &amp; 0x0F) |
134                  (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
135                  (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
136
137          scmds.miniCommand=SEC_MINI_NONE;
138          scmds.numCommands=1;
139          scmds.commands=&amp;scmd;
140          if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
141                  perror("SEC SEND: ");
142                  return -1;
143          }
144
145          if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
146                  perror("SEC SEND: ");
147                  return -1;
148          }
149
150          frp.u.qpsk.SymbolRate = srate;
151          frp.u.qpsk.FEC_inner = fec;
152
153          if (ioctl(front, FE_SET_FRONTEND, &amp;frp) &#x003C; 0){
154                  perror("QPSK TUNE: ");
155                  return -1;
156          }
157
158          pfd[0].fd = front;
159          pfd[0].events = POLLIN;
160
161          if (poll(pfd,1,3000)){
162                  if (pfd[0].revents &amp; POLLIN){
163                          printf("Getting QPSK event\n");
164                          if ( ioctl(front, FE_GET_EVENT, &amp;event)
165
166                               == -EOVERFLOW){
167                                  perror("qpsk get event");
168                                  return -1;
169                          }
170                          printf("Received ");
171                          switch(event.type){
172                          case FE_UNEXPECTED_EV:
173                                  printf("unexpected event\n");
174                                  return -1;
175                          case FE_FAILURE_EV:
176                                  printf("failure event\n");
177                                  return -1;
178
179                          case FE_COMPLETION_EV:
180                                  printf("completion event\n");
181                          }
182                  }
183          }
184
185
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, &amp;pesFilterParams) &#x003C; 0){
192                  perror("set_vpid");
193                  return -1;
194          }
195
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, &amp;pesFilterParams) &#x003C; 0){
202                  perror("set_apid");
203                  return -1;
204          }
205
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, &amp;pesFilterParams) &#x003C; 0){
212                  perror("set_tpid");
213                  return -1;
214          }
215
216          return has_signal(fds);
217  }
218
219 </programlisting>
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
224 necessary.
225 </para>
226 </section>
227
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.
231 </para>
232 <programlisting>
233  #include &#x003C;sys/ioctl.h&#x003E;
234  #include &#x003C;stdio.h&#x003E;
235  #include &#x003C;stdint.h&#x003E;
236  #include &#x003C;sys/types.h&#x003E;
237  #include &#x003C;sys/stat.h&#x003E;
238  #include &#x003C;fcntl.h&#x003E;
239  #include &#x003C;time.h&#x003E;
240  #include &#x003C;unistd.h&#x003E;
241
242  #include &#x003C;linux/dvb/dmx.h&#x003E;
243  #include &#x003C;linux/dvb/video.h&#x003E;
244  #include &#x003C;sys/poll.h&#x003E;
245  #define DVR "/dev/dvb/adapter0/dvr1"
246  #define AUDIO "/dev/dvb/adapter0/audio1"
247  #define VIDEO "/dev/dvb/adapter0/video1"
248
249  #define BUFFY (188&#x22C6;20)
250  #define MAX_LENGTH (1024&#x22C6;1024&#x22C6;5) /&#x22C6; record 5MB &#x22C6;/
251
252
253  /&#x22C6; switch the demuxes to recording, assuming the transponder is tuned &#x22C6;/
254
255  /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
256  /&#x22C6; vpid, apid:     PIDs of video and audio channels           &#x22C6;/
257
258  int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
259  {
260          struct dmx_pes_filter_params pesFilterParams;
261
262          if (demux1 &#x003C; 0){
263                  if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
264                      &#x003C; 0){
265                          perror("DEMUX DEVICE: ");
266                          return -1;
267                  }
268          }
269
270          if (demux2 &#x003C; 0){
271                  if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
272                      &#x003C; 0){
273                          perror("DEMUX DEVICE: ");
274                          return -1;
275                  }
276          }
277
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, &amp;pesFilterParams) &#x003C; 0){
284                  perror("DEMUX DEVICE");
285                  return -1;
286          }
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, &amp;pesFilterParams) &#x003C; 0){
293                  perror("DEMUX DEVICE");
294                  return -1;
295          }
296          return 0;
297  }
298
299  /&#x22C6; start recording MAX_LENGTH , assuming the transponder is tuned &#x22C6;/
300
301  /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
302  /&#x22C6; vpid, apid:     PIDs of video and audio channels           &#x22C6;/
303  int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
304  {
305          int i;
306          int len;
307          int written;
308          uint8_t buf[BUFFY];
309          uint64_t length;
310          struct pollfd pfd[1];
311          int dvr, dvr_out;
312
313          /&#x22C6; open dvr device &#x22C6;/
314          if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) &#x003C; 0){
315                          perror("DVR DEVICE");
316                          return -1;
317          }
318
319          /&#x22C6; switch video and audio demuxes to dvr &#x22C6;/
320          printf ("Switching dvr on\n");
321          i = switch_to_record(demux1, demux2, vpid, apid);
322          printf("finished: ");
323
324          printf("Recording %2.0f MB of test file in TS format\n",
325                 MAX_LENGTH/(1024.0&#x22C6;1024.0));
326          length = 0;
327
328          /&#x22C6; open output file &#x22C6;/
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)) &#x003C; 0){
333                  perror("Can't open file for dvr test");
334                  return -1;
335          }
336
337          pfd[0].fd = dvr;
338          pfd[0].events = POLLIN;
339
340          /&#x22C6; poll for dvr data and write to file &#x22C6;/
341          while (length &#x003C; MAX_LENGTH ) {
342                  if (poll(pfd,1,1)){
343                          if (pfd[0].revents &amp; POLLIN){
344                                  len = read(dvr, buf, BUFFY);
345                                  if (len &#x003C; 0){
346                                          perror("recording");
347                                          return -1;
348                                  }
349                                  if (len &#x003E; 0){
350                                          written = 0;
351                                          while (written &#x003C; len)
352                                                  written +=
353                                                          write (dvr_out,
354                                                                 buf, len);
355                                          length += len;
356                                          printf("written %2.0f MB\r",
357                                                 length/1024./1024.);
358                                  }
359                          }
360                  }
361          }
362          return 0;
363  }
364
365 </programlisting>
366
367 </section>