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>
8 * Christopher Ross <ross@natlab.research.philips.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
33 #include <vlc/input.h>
35 #include "../../demux/mpeg/system.h"
42 #include <sys/types.h>
46 #ifdef STRNCASECMP_IN_STRINGS_H
50 /* DVB Card Drivers */
51 #include <linux/dvb/dmx.h>
52 #include <linux/dvb/frontend.h>
56 #define SATELLITE_READ_ONCE 3
58 /*****************************************************************************
60 *****************************************************************************/
61 static ssize_t SatelliteRead( input_thread_t * p_input, byte_t * p_buffer,
63 static int SatelliteSetArea ( input_thread_t *, input_area_t * );
64 static int SatelliteSetProgram ( input_thread_t *, pgrm_descriptor_t * );
65 static void SatelliteSeek ( input_thread_t *, off_t );
67 /*****************************************************************************
68 * Open: open the frontend device
69 *****************************************************************************/
70 int E_(Open) ( vlc_object_t *p_this )
72 struct dvb_frontend_info frontend_info;
73 struct dvb_frontend_parameters fep;
74 input_thread_t * p_input = (input_thread_t *)p_this;
75 input_socket_t * p_satellite;
79 unsigned int u_adapter = 1;
80 unsigned int u_device = 0;
81 unsigned int u_freq = 0;
82 unsigned int u_srate = 0;
83 vlc_bool_t b_polarisation = 0;
85 fe_code_rate_t fe_fec = FEC_NONE;
87 vlc_bool_t b_no_probe;
92 char frontend[] = FRONTEND;
95 /* parse the options passed in command line : */
96 psz_parser = strdup( p_input->psz_name );
103 p_input->pf_read = SatelliteRead;
104 p_input->pf_set_program = SatelliteSetProgram;
105 p_input->pf_set_area = SatelliteSetArea;
106 p_input->pf_seek = SatelliteSeek;
108 // Get adapter and device number to use for this dvb card
109 u_adapter = config_GetInt( p_input, "adapter" );
110 u_device = config_GetInt( p_input, "device" );
112 /* Determine frontend device information and capabilities */
113 b_no_probe = config_GetInt( p_input, "no-probe" );
116 if ( ioctl_InfoFrontend(&frontend_info, u_adapter, u_device) < 0 )
118 msg_Err( p_input, "(access) cannot determine frontend info" );
121 if (frontend_info.type != FE_QPSK)
123 msg_Err( p_input, "frontend not of type satellite" );
127 else /* no frontend probing is done so use default values. */
131 msg_Dbg( p_input, "Using default values for frontend info" );
132 i_len = sizeof(FRONTEND);
133 if (snprintf(frontend, sizeof(FRONTEND), FRONTEND, u_adapter, u_device) >= i_len)
135 printf( "error: snprintf() truncated string for FRONTEND" );
136 frontend[sizeof(FRONTEND)] = '\0';
138 frontend_info.name = frontend;
139 frontend_info.type = FE_QPSK;
140 frontend_info.frequency_max = 12999;
141 frontend_info.frequency_min = 10000;
142 frontend_info.symbol_rate_max = 30000;
143 frontend_info.symbol_rate_min = 1000;
147 u_freq = (int)strtol( psz_parser, &psz_next, 10 );
150 psz_parser = psz_next + 1;
151 b_polarisation = (vlc_bool_t)strtol( psz_parser, &psz_next, 10 );
154 psz_parser = psz_next + 1;
155 i_fec = (int)strtol( psz_parser, &psz_next, 10 );
158 psz_parser = psz_next + 1;
159 u_srate = (int)strtol( psz_parser, &psz_next, 10 );
164 if ( ((u_freq) > frontend_info.frequency_max) ||
165 ((u_freq) < frontend_info.frequency_min) )
167 msg_Warn( p_input, "invalid frequency %d, using default one", u_freq );
168 u_freq = config_GetInt( p_input, "frequency" );
169 if ( ((u_freq) > frontend_info.frequency_max) ||
170 ((u_freq) < frontend_info.frequency_min) )
172 msg_Err( p_input, "invalid default frequency" );
177 if ( ((u_srate) > frontend_info.symbol_rate_max) ||
178 ((u_srate) < frontend_info.symbol_rate_min) )
180 msg_Warn( p_input, "invalid symbol rate, using default one" );
181 u_srate = config_GetInt( p_input, "symbol-rate" );
182 if ( ((u_srate) > frontend_info.symbol_rate_max) ||
183 ((u_srate) < frontend_info.symbol_rate_min) )
185 msg_Err( p_input, "invalid default symbol rate" );
190 if( b_polarisation && b_polarisation != 1 )
192 msg_Warn( p_input, "invalid polarization, using default one" );
193 b_polarisation = config_GetInt( p_input, "polarization" );
194 if( b_polarisation && b_polarisation != 1 )
196 msg_Err( p_input, "invalid default polarization" );
201 if( (i_fec > 7) || (i_fec < 1) )
203 msg_Warn( p_input, "invalid FEC, using default one" );
204 i_fec = config_GetInt( p_input, "fec" );
205 if( (i_fec > 7) || (i_fec < 1) )
207 msg_Err( p_input, "invalid default FEC" );
247 switch( frontend_info.type )
250 fep.frequency = u_freq * 1000;
251 fep.inversion = INVERSION_AUTO;
252 fep.u.qpsk.symbol_rate = u_srate * 1000;
253 fep.u.qpsk.fec_inner = fe_fec;
254 msg_Dbg( p_input, "satellite frontend found on %s", frontend_info.name );
257 msg_Dbg( p_input, "cable frontend found on %s", frontend_info.name );
260 msg_Dbg( p_input, "terrestrial frontend found on %s", frontend_info.name );
263 msg_Err( p_input, "Could not determine frontend type on %s", frontend_info.name );
267 /* Initialise structure */
268 p_satellite = malloc( sizeof( input_socket_t ) );
270 if( p_satellite == NULL )
272 msg_Err( p_input, "out of memory" );
276 p_input->p_access_data = (void *)p_satellite;
278 /* Open the DVR device */
280 if (snprintf(dvr, sizeof(DVR), DVR, u_adapter, u_device) >= i_len)
282 msg_Err( p_input, "error: snprintf() truncated string for DVR" );
283 dvr[sizeof(DVR)] = '\0';
285 msg_Dbg( p_input, "opening DVR device '%s'", dvr );
287 if( (p_satellite->i_handle = open( dvr,
288 /*O_NONBLOCK | O_LARGEFILE*/0 )) == (-1) )
290 msg_Warn( p_input, "cannot open `%s' (%s)", dvr, strerror(errno) );
295 /* Get antenna configuration options */
296 b_diseqc = config_GetInt( p_input, "diseqc" );
297 i_lnb_lof1 = config_GetInt( p_input, "lnb-lof1" );
298 i_lnb_lof2 = config_GetInt( p_input, "lnb-lof2" );
299 i_lnb_slof = config_GetInt( p_input, "lnb-slof" );
301 /* Initialize the Satellite Card */
302 msg_Dbg( p_input, "initializing Sat Card with Freq: %d, Pol: %d, "
303 "FEC: %d, Srate: %d", u_freq, b_polarisation, fe_fec, u_srate );
305 msg_Dbg( p_input, "initializing frontend device" );
306 // switch (ioctl_SetQPSKFrontend ( u_freq * 1000, i_srate* 1000, fe_fec,
307 // i_lnb_lof1 * 1000, i_lnb_lof2 * 1000, i_lnb_slof * 1000))
308 switch (ioctl_SetQPSKFrontend ( fep, b_polarisation, u_adapter, u_device ))
311 msg_Err( p_input, "frontend returned an unexpected event" );
312 close( p_satellite->i_handle );
316 msg_Err( p_input, "frontend returned no event" );
317 close( p_satellite->i_handle );
321 msg_Err( p_input, "frontend: timeout when polling for event" );
322 close( p_satellite->i_handle );
326 msg_Err( p_input, "an error occured when polling frontend device" );
327 close( p_satellite->i_handle );
331 msg_Err( p_input, "frontend returned a failure event" );
332 close( p_satellite->i_handle );
339 msg_Dbg( p_input, "setting filter on PAT\n" );
341 if ( ioctl_SetDMXFilter( 0, &i_fd, 3, u_adapter, u_device ) < 0 )
343 msg_Err( p_input, "an error occured when setting filter on PAT" );
344 close( p_satellite->i_handle );
349 msg_Dbg( p_input, "@@@ Initialising input stream\n" );
351 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
353 msg_Err( p_input, "could not initialize stream structure" );
354 close( p_satellite->i_handle );
359 vlc_mutex_lock( &p_input->stream.stream_lock );
361 p_input->stream.b_pace_control = 1;
362 p_input->stream.b_seekable = 0;
363 p_input->stream.p_selected_area->i_tell = 0;
365 vlc_mutex_unlock( &p_input->stream.stream_lock );
367 p_input->i_mtu = SATELLITE_READ_ONCE * TS_PACKET_SIZE;
368 p_input->stream.i_method = INPUT_METHOD_SATELLITE;
370 msg_Dbg( p_input, "@@@ Leaving E_(Open)\n" );
374 /*****************************************************************************
375 * Close : Close the device
376 *****************************************************************************/
377 void E_(Close) ( vlc_object_t *p_this )
379 input_thread_t * p_input = (input_thread_t *)p_this;
380 input_socket_t * p_satellite;
381 unsigned int i_es_index;
383 if ( p_input->stream.p_selected_program )
385 for ( i_es_index = 1 ;
386 i_es_index < p_input->stream.p_selected_program->i_es_number;
389 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
390 if ( p_es->p_decoder_fifo )
392 ioctl_UnsetDMXFilter( p_es->i_demux_fd );
398 p_satellite = (input_socket_t *)p_input;
399 close( p_satellite->i_handle );
402 /*****************************************************************************
403 * SatelliteRead: reads data from the satellite card
404 *****************************************************************************/
405 static ssize_t SatelliteRead( input_thread_t * p_input, byte_t * p_buffer,
408 input_socket_t * p_access_data = (input_socket_t *)p_input->p_access_data;
410 unsigned int u_adapter = 1;
411 unsigned int u_device = 0;
415 msg_Dbg( p_input, "@@@ SatelliteRead seeking for %d program\n", p_input->stream.i_pgrm_number );
417 // Get adapter and device number to use for this dvb card
418 u_adapter = config_GetInt( p_input, "adapter" );
419 u_device = config_GetInt( p_input, "device" );
421 /* if not set, set filters to the PMTs */
422 for( i = 0; i < p_input->stream.i_pgrm_number; i++ )
424 msg_Dbg( p_input, "@@@ trying to set filter on pmt pid %d",
425 p_input->stream.pp_programs[i]->pp_es[0]->i_id );
427 if ( p_input->stream.pp_programs[i]->pp_es[0]->i_demux_fd == 0 )
429 msg_Dbg( p_input, "setting filter on pmt pid %d",
430 p_input->stream.pp_programs[i]->pp_es[0]->i_id );
432 ioctl_SetDMXFilter( p_input->stream.pp_programs[i]->pp_es[0]->i_id,
433 &p_input->stream.pp_programs[i]->pp_es[0]->i_demux_fd,
434 3, u_adapter, u_device );
438 i_ret = read( p_access_data->i_handle, p_buffer, i_len );
443 msg_Err( p_input, "read failed (%s)", strerror(errno) );
445 msg_Err( p_input, "read failed" );
449 msg_Dbg( p_input, "@@@ Searched all, returning %d\n", i_ret );
454 /*****************************************************************************
455 * SatelliteSetArea : Does nothing
456 *****************************************************************************/
457 static int SatelliteSetArea( input_thread_t * p_input, input_area_t * p_area )
462 /*****************************************************************************
463 * SatelliteSetProgram : Sets the card filters according to the
465 * and makes the appropriate changes to stream structure.
466 *****************************************************************************/
467 int SatelliteSetProgram( input_thread_t * p_input,
468 pgrm_descriptor_t * p_new_prg )
470 unsigned int i_es_index;
471 unsigned int u_adapter = 1;
472 unsigned int u_device = 0;
474 msg_Dbg( p_input, "@@@ SatelliteSetProgram enter\n" );
476 // Get adapter and device number to use for this dvb card
477 u_adapter = config_GetInt( p_input, "adapter" );
478 u_device = config_GetInt( p_input, "device" );
480 if ( p_input->stream.p_selected_program )
482 for ( i_es_index = 1 ; /* 0 should be the PMT */
483 i_es_index < p_input->stream.p_selected_program->i_es_number ;
486 #define p_es p_input->stream.p_selected_program->pp_es[i_es_index]
487 if ( p_es->p_decoder_fifo )
489 input_UnselectES( p_input , p_es );
491 if ( p_es->i_demux_fd )
493 ioctl_UnsetDMXFilter( p_es->i_demux_fd );
494 p_es->i_demux_fd = 0;
500 for (i_es_index = 1 ; i_es_index < p_new_prg->i_es_number ; i_es_index ++ )
502 #define p_es p_new_prg->pp_es[i_es_index]
503 switch( p_es->i_cat )
507 if ( input_SelectES( p_input , p_es ) == 0 )
509 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 1, u_adapter, u_device);
514 if ( input_SelectES( p_input , p_es ) == 0 )
516 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 2, u_adapter, u_device);
517 input_SelectES( p_input , p_es );
521 ioctl_SetDMXFilter( p_es->i_id, &p_es->i_demux_fd, 3, u_adapter, u_device);
522 input_SelectES( p_input , p_es );
528 p_input->stream.p_selected_program = p_new_prg;
530 msg_Dbg( p_input, "@@@ SatelliteSetProgram exit\n" );
534 /*****************************************************************************
535 * SatelliteSeek: does nothing (not a seekable stream
536 *****************************************************************************/
537 static void SatelliteSeek( input_thread_t * p_input, off_t i_off )