]> git.sesse.net Git - vlc/blob - modules/access/satellite/dvb.c
mkv.cpp: try to decode H.264 with the avc1 FourCC (same as used for the MP4 source)
[vlc] / modules / access / satellite / dvb.c
1 /*****************************************************************************
2  * dvb.c : functions to control a DVB card under Linux
3  *****************************************************************************
4  * Copyright (C) 1998-2001 VideoLAN
5  *
6  * Authors: Damien Lucas <nitrox@via.ecp.fr>
7  *          Johan Bilien <jobi@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA    02111, USA.
22  *****************************************************************************/
23
24 #include <vlc/vlc.h>
25
26 #include <sys/ioctl.h>
27 #include <stdio.h>
28 #ifdef HAVE_INTTYPES_H
29 #   include <inttypes.h>                                       /* int16_t .. */
30 #endif
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/poll.h>
39
40 /* DVB Card Drivers */
41 #include <ost/sec.h>
42 #include <ost/dmx.h>
43 #include <ost/frontend.h>
44
45
46 #include "dvb.h"
47
48 /*****************************************************************************
49  * ioctl_SECControl : commands the SEC device
50  *****************************************************************************/
51
52
53 int ioctl_SECControl( int sec_nb, int freq, int pol, int lnb_slof, int diseqc )
54 {
55     struct secCommand scmd;
56     struct secCmdSequence scmds;
57     int sec;
58     char psz_sec[255];
59
60     snprintf(psz_sec, sizeof(psz_sec), SEC "%d", sec_nb);
61
62     if((sec = open(psz_sec, O_RDWR)) < 0)
63     {
64         return -1;
65     }
66
67     /* Set the frequency of the transponder, taking into account the
68        local frequencies of the LNB */
69     scmds.continuousTone = (freq<lnb_slof) ? SEC_TONE_OFF : SEC_TONE_ON;
70
71     /* Set the polarity of the transponder by setting the correct
72        voltage on the universal LNB */
73     scmds.voltage = (pol) ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13;
74
75     /* In case we have a DiSEqC, set it to the correct address */
76     scmd.type=0;
77     scmd.u.diseqc.addr=0x10;
78     scmd.u.diseqc.cmd=0x38;
79     scmd.u.diseqc.numParams=1;
80     scmd.u.diseqc.params[0] = 0xF0 | ((diseqc * 4) & 0x0F) | 
81             (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
82             (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
83
84     scmds.miniCommand=SEC_MINI_NONE;
85     scmds.numCommands=1;
86     scmds.commands=&scmd;
87
88     /* Send the data to the SEC device to prepare the LNB for tuning  */
89     /*intf_Msg("Sec: Sending data\n");*/
90     if (ioctl(sec, SEC_SEND_SEQUENCE, &scmds) < 0)
91     {
92         return -1;
93     }
94
95     close(sec);
96
97     return 0;
98 }
99
100 static int check_qpsk( int );
101
102 /*****************************************************************************
103  * ioctl_SetQPSKFrontend : controls the FE device
104  *****************************************************************************/
105
106 int ioctl_SetQPSKFrontend (int fe_nb, int freq, int srate, int fec,\
107                         int lnb_lof1, int lnb_lof2, int lnb_slof)
108 {
109     FrontendParameters fep;
110     int front;
111     int rc;
112     char psz_fe[255];
113
114     snprintf(psz_fe, sizeof(psz_fe), FRONTEND "%d", fe_nb);
115
116     /* Open the frontend device */
117     if((front = open(psz_fe, O_RDWR)) < 0)
118     {
119         return -1;
120     }
121
122     /* Set the frequency of the transponder, taking into account the
123        local frequencies of the LNB */
124     fep.Frequency = (freq < lnb_slof) ? freq - lnb_lof1 : freq - lnb_lof2; 
125
126  /* Set symbol rate and FEC */
127     fep.u.qpsk.SymbolRate = srate;
128     fep.u.qpsk.FEC_inner = FEC_AUTO;
129
130     /* Now send it all to the frontend device */
131     if (ioctl(front, FE_SET_FRONTEND, &fep) < 0)
132     {
133         return -1;
134     }
135
136     /* Check if it worked */
137     rc=check_qpsk(front);
138
139     /* Close front end device */
140     close(front);
141     
142     return rc;
143 }
144
145
146
147 /******************************************************************
148  * Check completion of the frontend control sequence
149  ******************************************************************/
150 static int check_qpsk(int front)
151 {
152     struct pollfd pfd[1];
153     FrontendEvent event; 
154     /* poll for QPSK event to check if tuning worked */
155     pfd[0].fd = front;
156     pfd[0].events = POLLIN;
157
158     if (poll(pfd,1,3000))
159     {
160         if (pfd[0].revents & POLLIN)
161         {
162             if ( ioctl(front, FE_GET_EVENT, &event) == -EBUFFEROVERFLOW)
163             {
164                 return -5;
165             }
166         
167             switch(event.type)
168             {
169                 case FE_UNEXPECTED_EV:
170                     return -2;
171                 case FE_FAILURE_EV:
172                     return -1;
173                 case FE_COMPLETION_EV:
174                     break;
175             }
176         }
177         else
178         {
179             /* should come here */
180             return -3;
181         }
182     }
183     else
184     {
185         return -4;
186     }
187     
188     return 0;
189 }
190
191
192 /*****************************************************************************
193  * ioctl_SetDMXAudioFilter : controls the demux to add a filter
194  *****************************************************************************/
195
196 int ioctl_SetDMXFilter( int dmx_nb, int i_pid, int * pi_fd , int i_type ) 
197 {
198     struct dmxPesFilterParams s_filter_params;
199     char psz_dmx[255];
200
201     snprintf(psz_dmx, sizeof(psz_dmx), DMX "%d", dmx_nb);
202
203     /* We first open the device */
204     if ((*pi_fd = open(psz_dmx, O_RDWR|O_NONBLOCK))  < 0)
205     {
206         return -1;
207     }
208
209     /* We fill the DEMUX structure : */
210     s_filter_params.pid     =   i_pid;
211     s_filter_params.input   =   DMX_IN_FRONTEND;
212     s_filter_params.output  =   DMX_OUT_TS_TAP;
213     switch ( i_type )
214     {
215         /* AFAIK you shouldn't use DMX_PES_VIDEO and DMX_PES_AUDIO
216          * unless you want to use a hardware decoder. In all cases
217          * I know DMX_PES_OTHER is quite enough for what we want to
218          * do. In case you have problems, you can still try to
219          * reenable them here : --Meuuh */
220 #if 0
221         case 1:
222             s_filter_params.pesType =   DMX_PES_VIDEO;
223             break;
224         case 2:
225             s_filter_params.pesType =   DMX_PES_AUDIO;
226             break;
227         case 3:
228 #endif
229         default:
230             s_filter_params.pesType =   DMX_PES_OTHER;
231             break;
232     }
233     s_filter_params.flags   =   DMX_IMMEDIATE_START;
234
235     /* We then give the order to the device : */
236     if (ioctl(*pi_fd, DMX_SET_PES_FILTER, &s_filter_params) < 0)
237     {
238         return -1;
239     }
240
241     return 0;
242 }
243
244 /*****************************************************************************
245  * ioctl_UnsetDMXFilter : removes a filter
246  *****************************************************************************/
247 int ioctl_UnsetDMXFilter(int demux)
248 {
249     ioctl(demux, DMX_STOP);
250     close(demux);
251     return 0;
252 }
253
254
255 /*****************************************************************************
256  * ioctl_SetBufferSize :
257  *****************************************************************************/
258 int ioctl_SetBufferSize(int handle, size_t size)
259 {
260     return ioctl(handle, DMX_SET_BUFFER_SIZE, size);
261 }