1 /*****************************************************************************
2 * access.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 *****************************************************************************/
31 #include <vlc/input.h>
33 #include "../../demux/mpeg/system.h"
40 #include <sys/types.h>
44 #ifdef STRNCASECMP_IN_STRINGS_H
50 #define SATELLITE_READ_ONCE 3
52 /*****************************************************************************
54 *****************************************************************************/
55 static ssize_t SatelliteRead( input_thread_t * p_input, byte_t * p_buffer,
57 static int SatelliteSetArea ( input_thread_t *, input_area_t * );
58 static int SatelliteSetProgram ( input_thread_t *, pgrm_descriptor_t * );
59 static void SatelliteSeek ( input_thread_t *, off_t );
61 /*****************************************************************************
62 * Open: open the dvr device
63 *****************************************************************************/
64 int E_(Open) ( vlc_object_t *p_this )
66 input_thread_t * p_input = (input_thread_t *)p_this;
67 input_socket_t * p_satellite;
81 /* parse the options passed in command line : */
83 psz_parser = strdup( p_input->psz_name );
90 p_input->pf_read = SatelliteRead;
91 p_input->pf_set_program = SatelliteSetProgram;
92 p_input->pf_set_area = SatelliteSetArea;
93 p_input->pf_seek = SatelliteSeek;
95 i_freq = (int)strtol( psz_parser, &psz_next, 10 );
99 psz_parser = psz_next + 1;
100 b_pol = (vlc_bool_t)strtol( psz_parser, &psz_next, 10 );
103 psz_parser = psz_next + 1;
104 i_fec = (int)strtol( psz_parser, &psz_next, 10 );
107 psz_parser = psz_next + 1;
108 i_srate = (int)strtol( psz_parser, &psz_next, 10 );
114 if( i_freq > 12999 || i_freq < 10000 )
116 msg_Warn( p_input, "invalid frequency, using default one" );
117 i_freq = config_GetInt( p_input, "frequency" );
118 if( i_freq > 12999 || i_freq < 10000 )
120 msg_Err( p_input, "invalid default frequency" );
125 if( i_srate > 30000 || i_srate < 1000 )
127 msg_Warn( p_input, "invalid symbol rate, using default one" );
128 i_srate = config_GetInt( p_input, "symbol-rate" );
129 if( i_srate > 30000 || i_srate < 1000 )
131 msg_Err( p_input, "invalid default symbol rate" );
136 if( b_pol && b_pol != 1 )
138 msg_Warn( p_input, "invalid polarization, using default one" );
139 b_pol = config_GetInt( p_input, "polarization" );
140 if( b_pol && b_pol != 1 )
142 msg_Err( p_input, "invalid default polarization" );
147 if( i_fec > 7 || i_fec < 1 )
149 msg_Warn( p_input, "invalid FEC, using default one" );
150 i_fec = config_GetInt( p_input, "fec" );
151 if( i_fec > 7 || i_fec < 1 )
153 msg_Err( p_input, "invalid default FEC" );
187 /* Initialise structure */
188 p_satellite = malloc( sizeof( input_socket_t ) );
190 if( p_satellite == NULL )
192 msg_Err( p_input, "out of memory" );
196 p_input->p_access_data = (void *)p_satellite;
198 /* Open the DVR device */
199 msg_Dbg( p_input, "opening DVR device `%s'", DVR );
201 if( (p_satellite->i_handle = open( DVR,
202 /*O_NONBLOCK | O_LARGEFILE*/0 )) == (-1) )
204 msg_Warn( p_input, "cannot open `%s' (%s)", DVR, strerror(errno) );
210 /* Get antenna configuration options */
211 b_diseqc = config_GetInt( p_input, "diseqc" );
212 i_lnb_lof1 = config_GetInt( p_input, "lnb-lof1" );
213 i_lnb_lof2 = config_GetInt( p_input, "lnb-lof2" );
214 i_lnb_slof = config_GetInt( p_input, "lnb-slof" );
216 /* Initialize the Satellite Card */
218 msg_Dbg( p_input, "initializing Sat Card with Freq: %d, Pol: %d, "
219 "FEC: %03f, Srate: %d", i_freq, b_pol, f_fec, i_srate );
221 if ( ioctl_SECControl( i_freq * 1000, b_pol, i_lnb_slof * 1000,
224 msg_Err( p_input, "an error occured when controling SEC" );
225 close( p_satellite->i_handle );
230 msg_Dbg( p_input, "initializing frontend device" );
231 switch (ioctl_SetQPSKFrontend ( i_freq * 1000, i_srate* 1000, f_fec,
232 i_lnb_lof1 * 1000, i_lnb_lof2 * 1000, i_lnb_slof * 1000))
235 msg_Err( p_input, "frontend returned an unexpected event" );
236 close( p_satellite->i_handle );
241 msg_Err( p_input, "frontend returned no event" );
242 close( p_satellite->i_handle );
247 msg_Err( p_input, "frontend: timeout when polling for event" );
248 close( p_satellite->i_handle );
253 msg_Err( p_input, "an error occured when polling frontend device" );
254 close( p_satellite->i_handle );
259 msg_Err( p_input, "frontend returned a failure event" );
260 close( p_satellite->i_handle );
268 msg_Dbg( p_input, "setting filter on PAT" );
270 if ( ioctl_SetDMXFilter( 0, &i_fd, 3 ) < 0 )
272 msg_Err( p_input, "an error occured when setting filter on PAT" );
273 close( p_satellite->i_handle );
278 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
280 msg_Err( p_input, "could not initialize stream structure" );
281 close( p_satellite->i_handle );
286 vlc_mutex_lock( &p_input->stream.stream_lock );
288 p_input->stream.b_pace_control = 1;
289 p_input->stream.b_seekable = 0;
290 p_input->stream.p_selected_area->i_tell = 0;
292 vlc_mutex_unlock( &p_input->stream.stream_lock );
294 p_input->i_mtu = SATELLITE_READ_ONCE * TS_PACKET_SIZE;
295 p_input->stream.i_method = INPUT_METHOD_SATELLITE;
300 /*****************************************************************************
301 * Close : Close the device
302 *****************************************************************************/
303 void E_(Close) ( vlc_object_t *p_this )
305 input_thread_t * p_input = (input_thread_t *)p_this;
306 input_socket_t * p_satellite;
307 unsigned int i_es_index;
309 if ( p_input->stream.p_selected_program )
311 for ( i_es_index = 1 ;
312 i_es_index < p_input->stream.p_selected_program->
316 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
317 if ( p_es->p_decoder_fifo )
319 ioctl_UnsetDMXFilter( p_es->i_demux_fd );
325 p_satellite = (input_socket_t *)p_input;
326 close( p_satellite->i_handle );
329 /*****************************************************************************
330 * SatelliteRead: reads data from the satellite card
331 *****************************************************************************/
332 static ssize_t SatelliteRead( input_thread_t * p_input, byte_t * p_buffer,
335 input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
340 /* if not set, set filters to the PMTs */
341 for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
343 if ( p_input->stream.pp_programs[i]->pp_es[0]->i_demux_fd == 0 )
345 msg_Dbg( p_input, "setting filter on pmt pid %d",
346 p_input->stream.pp_programs[i]->pp_es[0]->i_id );
347 ioctl_SetDMXFilter( p_input->stream.pp_programs[i]->pp_es[0]->i_id,
348 &p_input->stream.pp_programs[i]->pp_es[0]->i_demux_fd,
353 i_ret = read( p_access_data->i_handle, p_buffer, i_len );
358 msg_Err( p_input, "read failed (%s)", strerror(errno) );
360 msg_Err( p_input, "read failed" );
367 /*****************************************************************************
368 * SatelliteSetArea : Does nothing
369 *****************************************************************************/
370 static int SatelliteSetArea( input_thread_t * p_input, input_area_t * p_area )
375 /*****************************************************************************
376 * SatelliteSetProgram : Sets the card filters according to the
378 * and makes the appropriate changes to stream structure.
379 *****************************************************************************/
380 int SatelliteSetProgram( input_thread_t * p_input,
381 pgrm_descriptor_t * p_new_prg )
383 unsigned int i_es_index;
386 if ( p_input->stream.p_selected_program )
388 for ( i_es_index = 1 ; /* 0 should be the PMT */
389 i_es_index < p_input->stream.p_selected_program->
393 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
394 if ( p_es->p_decoder_fifo )
396 input_UnselectES( p_input , p_es );
398 if ( p_es->i_demux_fd )
400 ioctl_UnsetDMXFilter( p_es->i_demux_fd );
401 p_es->i_demux_fd = 0;
407 for (i_es_index = 1 ; i_es_index < p_new_prg->i_es_number ; i_es_index ++ )
409 #define p_es p_new_prg->pp_es[i_es_index]
410 switch( p_es->i_cat )
414 case MPEG2_MOTO_VIDEO_ES:
415 if ( input_SelectES( p_input , p_es ) == 0 )
417 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 1);
422 if ( input_SelectES( p_input , p_es ) == 0 )
424 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 2);
425 input_SelectES( p_input , p_es );
429 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 3);
430 input_SelectES( p_input , p_es );
436 p_input->stream.p_selected_program = p_new_prg;
438 /* Update the navigation variables without triggering a callback */
439 val.i_int = p_new_prg->i_number;
440 var_Change( p_input, "program", VLC_VAR_SETVALUE, &val, NULL );
445 /*****************************************************************************
446 * SatelliteSeek: does nothing (not a seekable stream
447 *****************************************************************************/
448 static void SatelliteSeek( input_thread_t * p_input, off_t i_off )