About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / DocBook / media / dvb / examples.xml


Based on kernel version 4.7.2. Page generated on 2016-08-22 22:44 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>NOTE: This section is out of date, and the code below won't even
5	    compile. Please refer to the
6	    <ulink url="https://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>
Hide Line Numbers


About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog