Merge branch 'btrfs-3.0' of git://github.com/chrismason/linux
[pandora-kernel.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>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" />.
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 &#x003C;sys/ioctl.h&#x003E;
16  #include &#x003C;stdio.h&#x003E;
17  #include &#x003C;stdint.h&#x003E;
18  #include &#x003C;sys/types.h&#x003E;
19  #include &#x003C;sys/stat.h&#x003E;
20  #include &#x003C;fcntl.h&#x003E;
21  #include &#x003C;time.h&#x003E;
22  #include &#x003C;unistd.h&#x003E;
23
24  #include &#x003C;linux/dvb/dmx.h&#x003E;
25  #include &#x003C;linux/dvb/frontend.h&#x003E;
26  #include &#x003C;linux/dvb/sec.h&#x003E;
27  #include &#x003C;sys/poll.h&#x003E;
28
29  #define DMX "/dev/dvb/adapter0/demux1"
30  #define FRONT "/dev/dvb/adapter0/frontend1"
31  #define SEC "/dev/dvb/adapter0/sec1"
32
33  /&#x22C6; routine for checking if we have a signal and other status information&#x22C6;/
34  int FEReadStatus(int fd, fe_status_t &#x22C6;stat)
35  {
36          int ans;
37
38          if ( (ans = ioctl(fd,FE_READ_STATUS,stat) &#x003C; 0)){
39                  perror("FE READ STATUS: ");
40                  return -1;
41          }
42
43          if (&#x22C6;stat &amp; FE_HAS_POWER)
44                  printf("FE HAS POWER\n");
45
46          if (&#x22C6;stat &amp; FE_HAS_SIGNAL)
47                  printf("FE HAS SIGNAL\n");
48
49          if (&#x22C6;stat &amp; FE_SPECTRUM_INV)
50                  printf("SPEKTRUM INV\n");
51
52          return 0;
53  }
54
55
56  /&#x22C6; tune qpsk &#x22C6;/
57  /&#x22C6; freq:             frequency of transponder                      &#x22C6;/
58  /&#x22C6; vpid, apid, tpid: PIDs of video, audio and teletext TS packets  &#x22C6;/
59  /&#x22C6; diseqc:           DiSEqC address of the used LNB                &#x22C6;/
60  /&#x22C6; pol:              Polarisation                                  &#x22C6;/
61  /&#x22C6; srate:            Symbol Rate                                   &#x22C6;/
62  /&#x22C6; fec.              FEC                                           &#x22C6;/
63  /&#x22C6; lnb_lof1:         local frequency of lower LNB band             &#x22C6;/
64  /&#x22C6; lnb_lof2:         local frequency of upper LNB band             &#x22C6;/
65  /&#x22C6; lnb_slof:         switch frequency of LNB                       &#x22C6;/
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)) &#x003C; 0){
83                  perror("FRONTEND DEVICE: ");
84                  return -1;
85          }
86
87          if((sec = open(SEC,O_RDWR)) &#x003C; 0){
88                  perror("SEC DEVICE: ");
89                  return -1;
90          }
91
92          if (demux1 &#x003C; 0){
93                  if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
94                      &#x003C; 0){
95                          perror("DEMUX DEVICE: ");
96                          return -1;
97                  }
98          }
99
100          if (demux2 &#x003C; 0){
101                  if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
102                      &#x003C; 0){
103                          perror("DEMUX DEVICE: ");
104                          return -1;
105                  }
106          }
107
108          if (demux3 &#x003C; 0){
109                  if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
110                      &#x003C; 0){
111                          perror("DEMUX DEVICE: ");
112                          return -1;
113                  }
114          }
115
116          if (freq &#x003C; 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 &#x22C6; 4) &amp; 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=&amp;scmd;
138          if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
139                  perror("SEC SEND: ");
140                  return -1;
141          }
142
143          if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 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, &amp;frp) &#x003C; 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 &amp; POLLIN){
161                          printf("Getting QPSK event\n");
162                          if ( ioctl(front, FE_GET_EVENT, &amp;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, &amp;pesFilterParams) &#x003C; 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, &amp;pesFilterParams) &#x003C; 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, &amp;pesFilterParams) &#x003C; 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 &#x003C;sys/ioctl.h&#x003E;
232  #include &#x003C;stdio.h&#x003E;
233  #include &#x003C;stdint.h&#x003E;
234  #include &#x003C;sys/types.h&#x003E;
235  #include &#x003C;sys/stat.h&#x003E;
236  #include &#x003C;fcntl.h&#x003E;
237  #include &#x003C;time.h&#x003E;
238  #include &#x003C;unistd.h&#x003E;
239
240  #include &#x003C;linux/dvb/dmx.h&#x003E;
241  #include &#x003C;linux/dvb/video.h&#x003E;
242  #include &#x003C;sys/poll.h&#x003E;
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&#x22C6;20)
248  #define MAX_LENGTH (1024&#x22C6;1024&#x22C6;5) /&#x22C6; record 5MB &#x22C6;/
249
250
251  /&#x22C6; switch the demuxes to recording, assuming the transponder is tuned &#x22C6;/
252
253  /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
254  /&#x22C6; vpid, apid:     PIDs of video and audio channels           &#x22C6;/
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 &#x003C; 0){
261                  if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
262                      &#x003C; 0){
263                          perror("DEMUX DEVICE: ");
264                          return -1;
265                  }
266          }
267
268          if (demux2 &#x003C; 0){
269                  if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
270                      &#x003C; 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, &amp;pesFilterParams) &#x003C; 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, &amp;pesFilterParams) &#x003C; 0){
291                  perror("DEMUX DEVICE");
292                  return -1;
293          }
294          return 0;
295  }
296
297  /&#x22C6; start recording MAX_LENGTH , assuming the transponder is tuned &#x22C6;/
298
299  /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
300  /&#x22C6; vpid, apid:     PIDs of video and audio channels           &#x22C6;/
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          /&#x22C6; open dvr device &#x22C6;/
312          if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) &#x003C; 0){
313                          perror("DVR DEVICE");
314                          return -1;
315          }
316
317          /&#x22C6; switch video and audio demuxes to dvr &#x22C6;/
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&#x22C6;1024.0));
324          length = 0;
325
326          /&#x22C6; open output file &#x22C6;/
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)) &#x003C; 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          /&#x22C6; poll for dvr data and write to file &#x22C6;/
339          while (length &#x003C; MAX_LENGTH ) {
340                  if (poll(pfd,1,1)){
341                          if (pfd[0].revents &amp; POLLIN){
342                                  len = read(dvr, buf, BUFFY);
343                                  if (len &#x003C; 0){
344                                          perror("recording");
345                                          return -1;
346                                  }
347                                  if (len &#x003E; 0){
348                                          written = 0;
349                                          while (written &#x003C; 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>