1 /*****************************************************************************
2 * input_satellite.c: Satellite card input
3 *****************************************************************************
4 * Copyright (C) 1998-2002 VideoLAN
6 * Authors: Johan Bilien <jobi@via.ecp.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
30 #include <videolan/vlc.h>
37 #include <sys/types.h>
41 #ifdef STRNCASECMP_IN_STRINGS_H
45 #include "stream_control.h"
46 #include "input_ext-intf.h"
47 #include "input_ext-dec.h"
48 #include "input_ext-plugins.h"
50 #include "satellite_tools.h"
52 #define SATELLITE_READ_ONCE 3
54 /*****************************************************************************
56 *****************************************************************************/
57 static int SatelliteOpen ( input_thread_t * );
58 static void SatelliteClose ( input_thread_t * );
59 static ssize_t SatelliteRead( input_thread_t * p_input, byte_t * p_buffer,
61 static int SatelliteSetArea ( input_thread_t *, input_area_t * );
62 static int SatelliteSetProgram ( input_thread_t *, pgrm_descriptor_t * );
63 static void SatelliteSeek ( input_thread_t *, off_t );
65 /*****************************************************************************
66 * Functions exported as capabilities. They are declared as static so that
67 * we don't pollute the namespace too much.
68 *****************************************************************************/
69 void _M( access_getfunctions )( function_list_t * p_function_list )
71 #define access p_function_list->functions.access
72 access.pf_open = SatelliteOpen;
73 access.pf_close = SatelliteClose;
74 access.pf_read = SatelliteRead;
75 access.pf_set_area = SatelliteSetArea;
76 access.pf_set_program = SatelliteSetProgram;
77 access.pf_seek = SatelliteSeek;
81 /*****************************************************************************
82 * SatelliteOpen : open the dvr device
83 *****************************************************************************/
84 static int SatelliteOpen( input_thread_t * p_input )
86 input_socket_t * p_satellite;
100 /* parse the options passed in command line : */
102 psz_parser = strdup( p_input->psz_name );
109 i_freq = (int)strtol( psz_parser, &psz_next, 10 );
113 psz_parser = psz_next + 1;
114 b_pol = (boolean_t)strtol( psz_parser, &psz_next, 10 );
117 psz_parser = psz_next + 1;
118 i_fec = (int)strtol( psz_parser, &psz_next, 10 );
121 psz_parser = psz_next + 1;
122 i_srate = (int)strtol( psz_parser, &psz_next, 10 );
128 if( i_freq > 12999 || i_freq < 10000 )
130 intf_WarnMsg( 1, "input: satellite: invalid frequency, using "\
132 i_freq = config_GetIntVariable( "frequency" );
133 if( i_freq > 12999 || i_freq < 10000 )
135 intf_ErrMsg( "input: satellite: invalid default frequency" );
140 if( i_srate > 30000 || i_srate < 1000 )
142 intf_WarnMsg( 1, "input: satellite: invalid symbol rate, using "\
144 i_srate = config_GetIntVariable( "symbol-rate" );
145 if( i_srate > 30000 || i_srate < 1000 )
147 intf_ErrMsg( "input: satellite: invalid default symbol rate" );
152 if( b_pol && b_pol != 1 )
154 intf_WarnMsg( 1, "input: satellite: invalid polarization, using "\
156 b_pol = config_GetIntVariable( "polarization" );
157 fprintf(stderr, "%d\n", b_pol);
158 if( b_pol && b_pol != 1 )
160 intf_ErrMsg( "input: satellite: invalid default polarization" );
165 if( i_fec > 7 || i_fec < 1 )
167 intf_WarnMsg( 1, "input: satellite: invalid FEC, using default one " );
168 i_fec = config_GetIntVariable( "fec" );
169 if( i_fec > 7 || i_fec < 1 )
171 intf_ErrMsg( "input: satellite: invalid default FEC" );
205 /* Initialise structure */
206 p_satellite = malloc( sizeof( input_socket_t ) );
208 if( p_satellite == NULL )
210 intf_ErrMsg( "input: satellite: Out of memory" );
214 p_input->p_access_data = (void *)p_satellite;
216 /* Open the DVR device */
218 intf_WarnMsg( 2, "input: opening file `%s'", DVR);
220 if( (p_satellite->i_handle = open( DVR,
221 /*O_NONBLOCK | O_LARGEFILE*/0 )) == (-1) )
223 intf_ErrMsg( "input error: cannot open file (%s)", strerror(errno) );
229 /* Get antenna configuration options */
230 b_diseqc = config_GetIntVariable( "diseqc" );
231 i_lnb_lof1 = config_GetIntVariable( "lnb-lof1" );
232 i_lnb_lof2 = config_GetIntVariable( "lnb-lof2" );
233 i_lnb_slof = config_GetIntVariable( "lnb-slof" );
235 /* Initialize the Satellite Card */
237 intf_WarnMsg( 2, "Initializing Sat Card with Freq: %d, Pol: %d, "\
238 "FEC: %03f, Srate: %d",
239 i_freq, b_pol, f_fec, i_srate );
241 if ( ioctl_SECControl( i_freq * 1000, b_pol, i_lnb_slof * 1000,
244 intf_ErrMsg("input: satellite: An error occured when controling SEC");
245 close( p_satellite->i_handle );
250 intf_WarnMsg( 3, "Initializing Frontend device" );
251 switch (ioctl_SetQPSKFrontend ( i_freq * 1000, i_srate* 1000, f_fec,
252 i_lnb_lof1 * 1000, i_lnb_lof2 * 1000, i_lnb_slof * 1000))
255 intf_ErrMsg( "input: satellite: Frontend returned"\
256 "an unexpected event" );
257 close( p_satellite->i_handle );
262 intf_ErrMsg( "input: satellite: Frontend returned\
264 close( p_satellite->i_handle );
269 intf_ErrMsg( "input: satellite: Frontend: time out\
270 when polling for event" );
271 close( p_satellite->i_handle );
276 intf_ErrMsg( "input: satellite: An error occured when polling\
278 close( p_satellite->i_handle );
283 intf_ErrMsg( "input: satellite: Frontend returned\
285 close( p_satellite->i_handle );
293 intf_WarnMsg( 3, " Setting filter on PAT " );
295 if ( ioctl_SetDMXFilter( 0, &i_fd, 3 ) < 0 )
297 intf_ErrMsg( "input: satellite: An error occured when setting\
299 close( p_satellite->i_handle );
304 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
306 intf_ErrMsg( "input: satellite: Not enough memory to allow stream\
308 close( p_satellite->i_handle );
313 vlc_mutex_lock( &p_input->stream.stream_lock );
315 p_input->stream.b_pace_control = 1;
316 p_input->stream.b_seekable = 0;
317 p_input->stream.p_selected_area->i_tell = 0;
319 vlc_mutex_unlock( &p_input->stream.stream_lock );
321 p_input->i_mtu = SATELLITE_READ_ONCE * TS_PACKET_SIZE;
322 p_input->stream.i_method = INPUT_METHOD_SATELLITE;
327 /*****************************************************************************
328 * SatelliteClose : Closes the device
329 *****************************************************************************/
330 static void SatelliteClose( input_thread_t * p_input )
332 input_socket_t * p_satellite;
335 if ( p_input->stream.p_selected_program )
337 for ( i_es_index = 1 ;
338 i_es_index < p_input->stream.p_selected_program->
342 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
343 if ( p_es->p_decoder_fifo )
345 ioctl_UnsetDMXFilter( p_es->i_demux_fd );
351 p_satellite = (input_socket_t *)p_input;
352 close( p_satellite->i_handle );
356 /*****************************************************************************
357 * SatelliteRead: reads data from the satellite card
358 *****************************************************************************/
359 static ssize_t SatelliteRead( input_thread_t * p_input, byte_t * p_buffer,
364 /* if not set, set filters to the PMTs */
365 for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
367 if ( p_input->stream.pp_programs[i]->pp_es[0]->i_demux_fd == 0 )
369 intf_WarnMsg( 2, "input: satellite: setting filter on pmt pid %d",
370 p_input->stream.pp_programs[i]->pp_es[0]->i_id);
371 ioctl_SetDMXFilter( p_input->stream.pp_programs[i]->pp_es[0]->i_id,
372 &p_input->stream.pp_programs[i]->pp_es[0]->i_demux_fd,
377 return input_FDRead( p_input, p_buffer, i_len );
383 /*****************************************************************************
384 * SatelliteSetArea : Does nothing
385 *****************************************************************************/
386 static int SatelliteSetArea( input_thread_t * p_input, input_area_t * p_area )
391 /*****************************************************************************
392 * SatelliteSetProgram : Sets the card filters according to the
394 * and makes the appropriate changes to stream structure.
395 *****************************************************************************/
396 int SatelliteSetProgram( input_thread_t * p_input,
397 pgrm_descriptor_t * p_new_prg )
401 if ( p_input->stream.p_selected_program )
403 for ( i_es_index = 1 ; /* 0 should be the PMT */
404 i_es_index < p_input->stream.p_selected_program->
408 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
409 if ( p_es->p_decoder_fifo )
411 input_UnselectES( p_input , p_es );
413 if ( p_es->i_demux_fd )
415 ioctl_UnsetDMXFilter( p_es->i_demux_fd );
416 p_es->i_demux_fd = 0;
422 for (i_es_index = 1 ; i_es_index < p_new_prg->i_es_number ; i_es_index ++ )
424 #define p_es p_new_prg->pp_es[i_es_index]
425 switch( p_es->i_cat )
429 if ( p_main->b_video )
431 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 1);
432 input_SelectES( p_input , p_es );
437 if ( p_main->b_audio )
439 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 2);
440 input_SelectES( p_input , p_es );
444 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 3);
445 input_SelectES( p_input , p_es );
451 p_input->stream.p_selected_program = p_new_prg;
456 /*****************************************************************************
457 * SatelliteSeek: does nothing (not a seekable stream
458 *****************************************************************************/
459 static void SatelliteSeek( input_thread_t * p_input, off_t i_off )