1 /*****************************************************************************
2 * access.c: DVB card input v4l2 only
3 *****************************************************************************
4 * Copyright (C) 1998-2003 VideoLAN
6 * Authors: Johan Bilien <jobi@via.ecp.fr>
7 * Jean-Paul Saman <saman@natlab.research.philips.com>
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.
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.
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 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 #include <vlc/input.h>
34 #include "../../demux/mpeg/system.h"
41 #include <sys/types.h>
48 #ifdef STRNCASECMP_IN_STRINGS_H
52 /* DVB Card Drivers */
53 #include <linux/dvb/dmx.h>
54 #include <linux/dvb/frontend.h>
58 #define SATELLITE_READ_ONCE 3
60 /*****************************************************************************
62 *****************************************************************************/
63 static ssize_t SatelliteRead( input_thread_t * p_input, byte_t * p_buffer,
65 static int SatelliteSetArea ( input_thread_t *, input_area_t * );
66 static int SatelliteSetProgram ( input_thread_t *, pgrm_descriptor_t * );
67 static void SatelliteSeek ( input_thread_t *, off_t );
69 /*****************************************************************************
70 * Open: open the frontend device
71 *****************************************************************************/
72 int E_(Open) ( vlc_object_t *p_this )
74 struct dvb_frontend_info frontend_info;
75 struct dvb_frontend_parameters fep;
76 input_thread_t * p_input = (input_thread_t *)p_this;
77 input_socket_t * p_satellite;
81 unsigned int u_adapter = 1;
82 unsigned int u_device = 0;
83 unsigned int u_freq = 0;
84 unsigned int u_srate = 0;
85 vlc_bool_t b_polarisation = 0;
87 fe_code_rate_t fe_fec = FEC_NONE;
94 char frontend[] = FRONTEND;
97 /* parse the options passed in command line : */
98 psz_parser = strdup( p_input->psz_name );
105 // Get adapter and device number to use for this dvb card
106 u_adapter = config_GetInt( p_input, "adapter" );
107 u_device = config_GetInt( p_input, "device" );
109 /* Determine frontend device information and capabilities */
110 b_probe = config_GetInt( p_input, "probe" );
113 if ( ioctl_InfoFrontend(p_input, &frontend_info, u_adapter, u_device) < 0 )
115 msg_Err( p_input, "(access) cannot determine frontend info" );
118 if (frontend_info.type != FE_QPSK)
120 msg_Err( p_input, "frontend not of type satellite" );
124 else /* no frontend probing is done so use default values. */
128 msg_Dbg( p_input, "using default values for frontend info" );
129 i_len = sizeof(FRONTEND);
130 if (snprintf(frontend, sizeof(FRONTEND), FRONTEND, u_adapter, u_device) >= i_len)
132 msg_Err( p_input, "snprintf() truncated string for FRONTEND" );
133 frontend[sizeof(FRONTEND)] = '\0';
135 strncpy(frontend_info.name, frontend, 128);
136 frontend_info.type = FE_QPSK;
137 frontend_info.frequency_max = 12999;
138 frontend_info.frequency_min = 10000;
139 frontend_info.symbol_rate_max = 30000;
140 frontend_info.symbol_rate_min = 1000;
144 /* Register Callback functions */
145 p_input->pf_read = SatelliteRead;
146 p_input->pf_set_program = SatelliteSetProgram;
147 p_input->pf_set_area = SatelliteSetArea;
148 p_input->pf_seek = SatelliteSeek;
150 u_freq = (unsigned int)strtol( psz_parser, &psz_next, 10 );
153 psz_parser = psz_next + 1;
154 b_polarisation = (vlc_bool_t)strtol( psz_parser, &psz_next, 10 );
157 psz_parser = psz_next + 1;
158 i_fec = (int)strtol( psz_parser, &psz_next, 10 );
161 psz_parser = psz_next + 1;
162 u_srate = (unsigned int)strtol( psz_parser, &psz_next, 10 );
167 if ( ((u_freq) > frontend_info.frequency_max) ||
168 ((u_freq) < frontend_info.frequency_min) )
170 msg_Warn( p_input, "invalid frequency %d, using default one", u_freq );
171 u_freq = config_GetInt( p_input, "frequency" );
172 if ( ((u_freq) > frontend_info.frequency_max) ||
173 ((u_freq) < frontend_info.frequency_min) )
175 msg_Err( p_input, "invalid default frequency" );
180 if ( ((u_srate) > frontend_info.symbol_rate_max) ||
181 ((u_srate) < frontend_info.symbol_rate_min) )
183 msg_Warn( p_input, "invalid symbol rate, using default one" );
184 u_srate = config_GetInt( p_input, "symbol-rate" );
185 if ( ((u_srate) > frontend_info.symbol_rate_max) ||
186 ((u_srate) < frontend_info.symbol_rate_min) )
188 msg_Err( p_input, "invalid default symbol rate" );
193 if( b_polarisation && (b_polarisation != 1) )
195 msg_Warn( p_input, "invalid polarization, using default one" );
196 b_polarisation = config_GetInt( p_input, "polarization" );
197 if( b_polarisation && b_polarisation != 1 )
199 msg_Err( p_input, "invalid default polarization" );
204 if( (i_fec > 9) || (i_fec < 1) )
206 msg_Warn( p_input, "invalid FEC, using default one" );
207 i_fec = config_GetInt( p_input, "fec" );
208 if( (i_fec > 9) || (i_fec < 1) )
210 msg_Err( p_input, "invalid default FEC" );
247 msg_Err( p_input, "invalid FEC (unknown)" );
251 switch( frontend_info.type )
254 fep.frequency = u_freq * 1000;
255 fep.inversion = INVERSION_AUTO;
256 fep.u.qpsk.symbol_rate = u_srate * 1000;
257 fep.u.qpsk.fec_inner = fe_fec;
258 msg_Dbg( p_input, "satellite frontend found on %s", frontend_info.name );
261 msg_Dbg( p_input, "cable frontend found on %s", frontend_info.name );
264 msg_Dbg( p_input, "terrestrial frontend found on %s", frontend_info.name );
267 msg_Err( p_input, "Could not determine frontend type on %s", frontend_info.name );
271 /* Initialise structure */
272 p_satellite = malloc( sizeof( input_socket_t ) );
274 if( p_satellite == NULL )
276 msg_Err( p_input, "out of memory" );
280 p_input->p_access_data = (void *)p_satellite;
282 /* Open the DVR device */
284 if (snprintf(dvr, sizeof(DVR), DVR, u_adapter, u_device) >= i_len)
286 msg_Err( p_input, "snprintf() truncated string for DVR" );
287 dvr[sizeof(DVR)] = '\0';
289 msg_Dbg( p_input, "opening DVR device '%s'", dvr );
291 if( (p_satellite->i_handle = open( dvr,
292 /*O_NONBLOCK | O_LARGEFILE*/0 )) == (-1) )
295 msg_Warn( p_input, "cannot open `%s' (%s)", dvr, strerror(errno) );
297 msg_Warn( p_input, "cannot open `%s'", dvr );
303 /* Get antenna configuration options */
304 b_diseqc = config_GetInt( p_input, "diseqc" );
305 i_lnb_lof1 = config_GetInt( p_input, "lnb-lof1" );
306 i_lnb_lof2 = config_GetInt( p_input, "lnb-lof2" );
307 i_lnb_slof = config_GetInt( p_input, "lnb-slof" );
309 /* Initialize the Satellite Card */
310 msg_Dbg( p_input, "initializing Sat Card with Freq: %u, Pol: %d, "
311 "FEC: %d, Srate: %u", u_freq, b_polarisation, fe_fec, u_srate );
313 switch (ioctl_SetQPSKFrontend (p_input, fep, b_polarisation, u_adapter, u_device ))
316 msg_Err( p_input, "frontend returned an unexpected event" );
317 close( p_satellite->i_handle );
321 msg_Err( p_input, "frontend returned no event" );
322 close( p_satellite->i_handle );
326 msg_Err( p_input, "frontend: timeout when polling for event" );
327 close( p_satellite->i_handle );
331 msg_Err( p_input, "an error occured when polling frontend device" );
332 close( p_satellite->i_handle );
336 msg_Err( p_input, "frontend returned a failure event" );
337 close( p_satellite->i_handle );
344 msg_Dbg( p_input, "setting filter on PAT" );
346 if ( ioctl_SetDMXFilter(p_input, 0, &i_fd, 3, u_adapter, u_device ) < 0 )
349 msg_Err( p_input, "an error occured when setting filter on PAT (%s)", strerror(errno) );
351 msg_Err( p_input, "an error occured when setting filter on PAT" );
353 close( p_satellite->i_handle );
358 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
360 msg_Err( p_input, "could not initialize stream structure" );
361 close( p_satellite->i_handle );
366 vlc_mutex_lock( &p_input->stream.stream_lock );
368 p_input->stream.b_pace_control = 1;
369 p_input->stream.b_seekable = 0;
370 p_input->stream.p_selected_area->i_tell = 0;
372 vlc_mutex_unlock( &p_input->stream.stream_lock );
374 p_input->i_mtu = SATELLITE_READ_ONCE * TS_PACKET_SIZE;
375 p_input->stream.i_method = INPUT_METHOD_SATELLITE;
380 /*****************************************************************************
381 * Close : Close the device
382 *****************************************************************************/
383 void E_(Close) ( vlc_object_t *p_this )
385 input_thread_t * p_input = (input_thread_t *)p_this;
386 input_socket_t * p_satellite;
387 unsigned int i_es_index;
389 if ( p_input->stream.p_selected_program )
391 for ( i_es_index = 1 ;
392 i_es_index < p_input->stream.p_selected_program->i_es_number;
395 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
396 if ( p_es->p_decoder_fifo )
398 ioctl_UnsetDMXFilter(p_input, p_es->i_demux_fd );
404 p_satellite = (input_socket_t *)p_input;
405 close( p_satellite->i_handle );
408 /*****************************************************************************
409 * SatelliteRead: reads data from the satellite card
410 *****************************************************************************/
411 static ssize_t SatelliteRead( input_thread_t * p_input, byte_t * p_buffer,
414 input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
416 unsigned int u_adapter = 1;
417 unsigned int u_device = 0;
420 // Get adapter and device number to use for this dvb card
421 u_adapter = config_GetInt( p_input, "adapter" );
422 u_device = config_GetInt( p_input, "device" );
424 /* if not set, set filters to the PMTs */
425 for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
427 if ( p_input->stream.pp_programs[i]->pp_es[0]->i_demux_fd == 0 )
429 ioctl_SetDMXFilter(p_input, p_input->stream.pp_programs[i]->pp_es[0]->i_id,
430 &p_input->stream.pp_programs[i]->pp_es[0]->i_demux_fd,
431 3, u_adapter, u_device );
435 i_ret = read( p_access_data->i_handle, p_buffer, i_len );
440 msg_Err( p_input, "read failed (%s)", strerror(errno) );
442 msg_Err( p_input, "read failed" );
449 /*****************************************************************************
450 * SatelliteSetArea : Does nothing
451 *****************************************************************************/
452 static int SatelliteSetArea( input_thread_t * p_input, input_area_t * p_area )
457 /*****************************************************************************
458 * SatelliteSetProgram : Sets the card filters according to the
460 * and makes the appropriate changes to stream structure.
461 *****************************************************************************/
462 int SatelliteSetProgram( input_thread_t * p_input,
463 pgrm_descriptor_t * p_new_prg )
465 unsigned int i_es_index;
466 unsigned int u_adapter = 1;
467 unsigned int u_device = 0;
469 // Get adapter and device number to use for this dvb card
470 u_adapter = config_GetInt( p_input, "adapter" );
471 u_device = config_GetInt( p_input, "device" );
473 if ( p_input->stream.p_selected_program )
475 for ( i_es_index = 1 ; /* 0 should be the PMT */
476 i_es_index < p_input->stream.p_selected_program->i_es_number ;
479 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
480 if ( p_es->p_decoder_fifo )
482 input_UnselectES( p_input , p_es );
484 if ( p_es->i_demux_fd )
486 ioctl_UnsetDMXFilter(p_input, p_es->i_demux_fd );
487 p_es->i_demux_fd = 0;
493 for (i_es_index = 1 ; i_es_index < p_new_prg->i_es_number ; i_es_index ++ )
495 #define p_es p_new_prg->pp_es[i_es_index]
496 switch( p_es->i_cat )
500 if ( input_SelectES( p_input , p_es ) == 0 )
502 ioctl_SetDMXFilter(p_input, p_es->i_id, &p_es->i_demux_fd, 1, u_adapter, u_device);
507 if ( input_SelectES( p_input , p_es ) == 0 )
509 ioctl_SetDMXFilter(p_input, p_es->i_id, &p_es->i_demux_fd, 2, u_adapter, u_device);
510 input_SelectES( p_input , p_es );
514 ioctl_SetDMXFilter(p_input, p_es->i_id, &p_es->i_demux_fd, 3, u_adapter, u_device);
515 input_SelectES( p_input , p_es );
521 p_input->stream.p_selected_program = p_new_prg;
526 /*****************************************************************************
527 * SatelliteSeek: does nothing (not a seekable stream
528 *****************************************************************************/
529 static void SatelliteSeek( input_thread_t * p_input, off_t i_off )