About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / DocBook / media / dvb / examples.xml




Custom Search

Based on kernel version 3.16. Page generated on 2014-08-06 21:38 EST.

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>
Hide Line Numbers
About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Information is copyright its respective author. All material is available from the Linux Kernel Source distributed under a GPL License. This page is provided as a free service by mjmwired.net.