1 /*****************************************************************************
2 * access.c: DVB card input v4l2 only
3 *****************************************************************************
4 * Copyright (C) 1998-2010 the VideoLAN team
6 * Authors: Johan Bilien <jobi@via.ecp.fr>
7 * Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
8 * Christophe Massiot <massiot@via.ecp.fr>
9 * Laurent Aimar <fenrir@via.ecp.fr>
10 * David Kaplan <david@2of1.org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
28 /*****************************************************************************
30 *****************************************************************************/
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_access.h>
38 #include <vlc_input.h>
39 #include <vlc_interface.h>
40 #include <vlc_dialog.h>
47 #include <sys/types.h>
52 /* Include dvbpsi headers */
53 #ifdef HAVE_DVBPSI_DR_H
54 # include <dvbpsi/dvbpsi.h>
55 # include <dvbpsi/descriptor.h>
56 # include <dvbpsi/pat.h>
57 # include <dvbpsi/pmt.h>
58 # include <dvbpsi/dr.h>
59 # include <dvbpsi/psi.h>
60 # include <dvbpsi/demux.h>
61 # include <dvbpsi/sdt.h>
64 # include "descriptor.h"
65 # include "tables/pat.h"
66 # include "tables/pmt.h"
67 # include "descriptors/dr.h"
70 # include "tables/sdt.h"
74 # include <vlc_httpd.h>
79 /*****************************************************************************
81 *****************************************************************************/
82 static int Open( vlc_object_t
*p_this
);
83 static void Close( vlc_object_t
*p_this
);
85 #define CACHING_TEXT N_("Caching value in ms")
86 #define CACHING_LONGTEXT N_( \
87 "Caching value for DVB streams. This " \
88 "value should be set in milliseconds." )
90 #define ADAPTER_TEXT N_("Adapter card to tune")
91 #define ADAPTER_LONGTEXT N_("Adapter cards have a device file in directory named /dev/dvb/adapter[n] with n>=0.")
93 #define DEVICE_TEXT N_("Device number to use on adapter")
94 #define DEVICE_LONGTEXT ""
96 #define FREQ_TEXT N_("Transponder/multiplex frequency")
97 #define FREQ_LONGTEXT N_("In kHz for DVB-S or Hz for DVB-C/T")
99 #define INVERSION_TEXT N_("Inversion mode")
100 #define INVERSION_LONGTEXT N_("Inversion mode [0=off, 1=on, 2=auto]")
102 #define PROBE_TEXT N_("Probe DVB card for capabilities")
103 #define PROBE_LONGTEXT N_("Some DVB cards do not like to be probed for their capabilities, you can disable this feature if you experience some trouble.")
105 #define BUDGET_TEXT N_("Budget mode")
106 #define BUDGET_LONGTEXT N_("This allows you to stream an entire transponder with a \"budget\" card.")
109 #define SATELLITE_TEXT N_("Satellite scanning config")
110 #define SATELLITE_LONGTEXT N_("filename of config file in share/dvb/dvb-s")
112 #define SATNO_TEXT N_("Satellite number in the Diseqc system")
113 #define SATNO_LONGTEXT N_("[0=no diseqc, 1-4=satellite number].")
115 #define VOLTAGE_TEXT N_("LNB voltage")
116 #define VOLTAGE_LONGTEXT N_("In Volts [0, 13=vertical, 18=horizontal].")
118 #define HIGH_VOLTAGE_TEXT N_("High LNB voltage")
119 #define HIGH_VOLTAGE_LONGTEXT N_("Enable high voltage if your cables are " \
120 "particularly long. This is not supported by all frontends.")
122 #define TONE_TEXT N_("22 kHz tone")
123 #define TONE_LONGTEXT N_("[0=off, 1=on, -1=auto].")
125 #define FEC_TEXT N_("Transponder FEC")
126 #define FEC_LONGTEXT N_("FEC=Forward Error Correction mode [9=auto].")
128 #define SRATE_TEXT N_("Transponder symbol rate in kHz")
129 #define SRATE_LONGTEXT ""
131 #define LNB_LOF1_TEXT N_("Antenna lnb_lof1 (kHz)")
132 #define LNB_LOF1_LONGTEXT ""
134 #define LNB_LOF2_TEXT N_("Antenna lnb_lof2 (kHz)")
135 #define LNB_LOF2_LONGTEXT ""
137 #define LNB_SLOF_TEXT N_("Antenna lnb_slof (kHz)")
138 #define LNB_SLOF_LONGTEXT ""
141 #define MODULATION_TEXT N_("Modulation type")
142 #define MODULATION_LONGTEXT N_("Modulation type for front-end device.")
145 #define CODE_RATE_HP_TEXT N_("Terrestrial high priority stream code rate (FEC)")
146 #define CODE_RATE_HP_LONGTEXT ""
148 #define CODE_RATE_LP_TEXT N_("Terrestrial low priority stream code rate (FEC)")
149 #define CODE_RATE_LP_LONGTEXT ""
151 #define BANDWIDTH_TEXT N_("Terrestrial bandwidth")
152 #define BANDWIDTH_LONGTEXT N_("Terrestrial bandwidth [0=auto,6,7,8 in MHz]")
154 #define GUARD_TEXT N_("Terrestrial guard interval")
155 #define GUARD_LONGTEXT ""
157 #define TRANSMISSION_TEXT N_("Terrestrial transmission mode")
158 #define TRANSMISSION_LONGTEXT ""
160 #define HIERARCHY_TEXT N_("Terrestrial hierarchy mode")
161 #define HIERARCHY_LONGTEXT ""
163 #define HOST_TEXT N_( "HTTP Host address" )
164 #define HOST_LONGTEXT N_( \
165 "To enable the internal HTTP server, set its address and port here." )
167 #define USER_TEXT N_( "HTTP user name" )
168 #define USER_LONGTEXT N_( \
169 "User name the administrator will use to log into " \
170 "the internal HTTP server." )
172 #define PASSWORD_TEXT N_( "HTTP password" )
173 #define PASSWORD_LONGTEXT N_( \
174 "Password the administrator will use to log into " \
175 "the internal HTTP server." )
177 #define ACL_TEXT N_( "HTTP ACL" )
178 #define ACL_LONGTEXT N_( \
179 "Access control list (equivalent to .hosts) file path, " \
180 "which will limit the range of IPs entitled to log into the internal " \
183 #define CERT_TEXT N_( "Certificate file" )
184 #define CERT_LONGTEXT N_( "HTTP interface x509 PEM certificate file " \
187 #define KEY_TEXT N_( "Private key file" )
188 #define KEY_LONGTEXT N_( "HTTP interface x509 PEM private key file" )
190 #define CA_TEXT N_( "Root CA file" )
191 #define CA_LONGTEXT N_( "HTTP interface x509 PEM trusted root CA " \
192 "certificates file" )
194 #define CRL_TEXT N_( "CRL file" )
195 #define CRL_LONGTEXT N_( "HTTP interface Certificates Revocation List file" )
198 set_shortname( N_("DVB") )
199 set_description( N_("DVB input with v4l2 support") )
200 set_category( CAT_INPUT
)
201 set_subcategory( SUBCAT_INPUT_ACCESS
)
203 add_integer( "dvb-caching", DEFAULT_PTS_DELAY
/ 1000, NULL
, CACHING_TEXT
,
204 CACHING_LONGTEXT
, true )
206 add_integer( "dvb-adapter", 0, NULL
, ADAPTER_TEXT
, ADAPTER_LONGTEXT
,
208 add_integer( "dvb-device", 0, NULL
, DEVICE_TEXT
, DEVICE_LONGTEXT
,
210 add_integer( "dvb-frequency", 0, NULL
, FREQ_TEXT
, FREQ_LONGTEXT
,
213 add_integer( "dvb-inversion", 2, NULL
, INVERSION_TEXT
, INVERSION_LONGTEXT
,
215 add_bool( "dvb-probe", true, NULL
, PROBE_TEXT
, PROBE_LONGTEXT
, true )
216 add_bool( "dvb-budget-mode", false, NULL
, BUDGET_TEXT
, BUDGET_LONGTEXT
,
218 /* DVB-S (satellite) */
219 add_string( "dvb-satellite", NULL
, SATELLITE_TEXT
, SATELLITE_LONGTEXT
,
221 add_integer( "dvb-satno", 0, NULL
, SATNO_TEXT
, SATNO_LONGTEXT
,
223 add_integer( "dvb-voltage", 13, NULL
, VOLTAGE_TEXT
, VOLTAGE_LONGTEXT
,
225 add_bool( "dvb-high-voltage", false, NULL
, HIGH_VOLTAGE_TEXT
,
226 HIGH_VOLTAGE_LONGTEXT
, true )
227 add_integer( "dvb-tone", -1, NULL
, TONE_TEXT
, TONE_LONGTEXT
,
229 add_integer( "dvb-fec", 9, NULL
, FEC_TEXT
, FEC_LONGTEXT
, true )
230 add_integer( "dvb-srate", 27500000, NULL
, SRATE_TEXT
, SRATE_LONGTEXT
,
232 add_integer( "dvb-lnb-lof1", 0, NULL
, LNB_LOF1_TEXT
,
233 LNB_LOF1_LONGTEXT
, true )
234 add_integer( "dvb-lnb-lof2", 0, NULL
, LNB_LOF2_TEXT
,
235 LNB_LOF2_LONGTEXT
, true )
236 add_integer( "dvb-lnb-slof", 0, NULL
, LNB_SLOF_TEXT
,
237 LNB_SLOF_LONGTEXT
, true )
239 add_integer( "dvb-modulation", 0, NULL
, MODULATION_TEXT
,
240 MODULATION_LONGTEXT
, true )
241 /* DVB-T (terrestrial) */
242 add_integer( "dvb-code-rate-hp", 9, NULL
, CODE_RATE_HP_TEXT
,
243 CODE_RATE_HP_LONGTEXT
, true )
244 add_integer( "dvb-code-rate-lp", 9, NULL
, CODE_RATE_LP_TEXT
,
245 CODE_RATE_LP_LONGTEXT
, true )
246 add_integer( "dvb-bandwidth", 0, NULL
, BANDWIDTH_TEXT
, BANDWIDTH_LONGTEXT
,
249 add_integer( "dvb-guard", 0, NULL
, GUARD_TEXT
, GUARD_LONGTEXT
, true )
250 add_integer( "dvb-transmission", 0, NULL
, TRANSMISSION_TEXT
,
251 TRANSMISSION_LONGTEXT
, true )
252 add_integer( "dvb-hierarchy", 0, NULL
, HIERARCHY_TEXT
, HIERARCHY_LONGTEXT
,
255 /* MMI HTTP interface */
256 set_section( N_("HTTP server" ), 0 )
257 add_string( "dvb-http-host", NULL
, HOST_TEXT
, HOST_LONGTEXT
,
259 add_string( "dvb-http-user", NULL
, USER_TEXT
, USER_LONGTEXT
,
261 add_password( "dvb-http-password", NULL
, NULL
, PASSWORD_TEXT
,
262 PASSWORD_LONGTEXT
, true )
263 add_string( "dvb-http-acl", NULL
, ACL_TEXT
, ACL_LONGTEXT
,
265 add_string( "dvb-http-intf-cert", NULL
, CERT_TEXT
, CERT_LONGTEXT
,
267 add_string( "dvb-http-intf-key", NULL
, KEY_TEXT
, KEY_LONGTEXT
,
269 add_string( "dvb-http-intf-ca", NULL
, CA_TEXT
, CA_LONGTEXT
,
271 add_string( "dvb-http-intf-crl", NULL
, CRL_TEXT
, CRL_LONGTEXT
,
275 set_capability( "access", 0 )
276 add_shortcut( "dvb", /* Generic name */
277 "dvb-s", "qpsk", "satellite", /* Satellite */
278 "dvb-c", "cable", /* Cable */
279 "dvb-t", "terrestrial", /* Terrestrial */
281 add_shortcut( "usdigital" )
283 set_callbacks( Open
, Close
)
288 /*****************************************************************************
290 *****************************************************************************/
291 static block_t
*Block( access_t
* );
292 static int Control( access_t
*, int, va_list );
294 static block_t
*BlockScan( access_t
* );
296 #define DVB_READ_ONCE 20
297 #define DVB_READ_ONCE_START 2
298 #define DVB_READ_ONCE_SCAN 1
299 #define TS_PACKET_SIZE 188
301 #define DVB_SCAN_MAX_SIGNAL_TIME (1000*1000)
302 #define DVB_SCAN_MAX_LOCK_TIME (5000*1000)
303 #define DVB_SCAN_MAX_PROBE_TIME (45000*1000)
305 static void FilterUnset( access_t
*, int i_max
);
306 static void FilterUnsetPID( access_t
*, int i_pid
);
307 static void FilterSet( access_t
*, int i_pid
, int i_type
);
309 static void VarInit( access_t
* );
310 static int ParseMRL( access_t
* );
312 /*****************************************************************************
313 * Open: open the frontend device
314 *****************************************************************************/
315 static int Open( vlc_object_t
*p_this
)
317 access_t
*p_access
= (access_t
*)p_this
;
320 /* Only if selected */
321 if( *p_access
->psz_access
== '\0' )
325 p_access
->pf_read
= NULL
;
326 p_access
->pf_block
= Block
;
327 p_access
->pf_control
= Control
;
328 p_access
->pf_seek
= NULL
;
330 access_InitFields( p_access
);
332 p_access
->p_sys
= p_sys
= calloc( 1, sizeof( access_sys_t
) );
336 /* Create all variables */
339 /* Parse the command line */
340 if( ParseMRL( p_access
) )
346 /* Getting frontend info */
347 if( FrontendOpen( p_access
) )
354 p_sys
->b_scan_mode
= var_GetInteger( p_access
, "dvb-frequency" ) == 0;
355 if( p_sys
->b_scan_mode
)
357 msg_Dbg( p_access
, "DVB scan mode selected" );
358 p_access
->pf_block
= BlockScan
;
362 /* Setting frontend parameters for tuning the hardware */
363 msg_Dbg( p_access
, "trying to tune the frontend...");
364 if( FrontendSet( p_access
) < 0 )
366 FrontendClose( p_access
);
372 /* Opening DVR device */
373 if( DVROpen( p_access
) < 0 )
375 FrontendClose( p_access
);
380 if( p_sys
->b_scan_mode
)
382 scan_parameter_t parameter
;
384 msg_Dbg( p_access
, "setting filter on PAT/NIT/SDT (DVB only)" );
385 FilterSet( p_access
, 0x00, OTHER_TYPE
); // PAT
386 FilterSet( p_access
, 0x10, OTHER_TYPE
); // NIT
387 FilterSet( p_access
, 0x11, OTHER_TYPE
); // SDT
389 if( FrontendGetScanParameter( p_access
, ¶meter
) ||
390 scan_Init( VLC_OBJECT(p_access
), &p_sys
->scan
, ¶meter
) )
392 Close( VLC_OBJECT(p_access
) );
398 p_sys
->b_budget_mode
= var_GetBool( p_access
, "dvb-budget-mode" );
399 if( p_sys
->b_budget_mode
)
401 msg_Dbg( p_access
, "setting filter on all PIDs" );
402 FilterSet( p_access
, 0x2000, OTHER_TYPE
);
406 msg_Dbg( p_access
, "setting filter on PAT" );
407 FilterSet( p_access
, 0x0, OTHER_TYPE
);
413 HTTPOpen( p_access
);
417 if( p_sys
->b_scan_mode
)
418 p_sys
->i_read_once
= DVB_READ_ONCE_SCAN
;
419 else if( p_sys
->b_budget_mode
)
420 p_sys
->i_read_once
= DVB_READ_ONCE
;
422 p_sys
->i_read_once
= DVB_READ_ONCE_START
;
424 free( p_access
->psz_demux
);
425 p_access
->psz_demux
= strdup( p_sys
->b_scan_mode
? "m3u8" : "ts" );
429 /*****************************************************************************
430 * Close : Close the device
431 *****************************************************************************/
432 static void Close( vlc_object_t
*p_this
)
434 access_t
*p_access
= (access_t
*)p_this
;
435 access_sys_t
*p_sys
= p_access
->p_sys
;
437 FilterUnset( p_access
, p_sys
->b_budget_mode
&& !p_sys
->b_scan_mode
? 1 : MAX_DEMUX
);
439 DVRClose( p_access
);
440 FrontendClose( p_access
);
441 if( p_sys
->b_scan_mode
)
442 scan_Clean( &p_sys
->scan
);
444 CAMClose( p_access
);
447 if( !p_sys
->b_scan_mode
)
448 HTTPClose( p_access
);
454 /*****************************************************************************
456 *****************************************************************************/
457 static block_t
*Block( access_t
*p_access
)
459 access_sys_t
*p_sys
= p_access
->p_sys
;
464 struct pollfd ufds
[2];
467 /* Initialize file descriptor sets */
468 memset (ufds
, 0, sizeof (ufds
));
469 ufds
[0].fd
= p_sys
->i_handle
;
470 ufds
[0].events
= POLLIN
;
471 ufds
[1].fd
= p_sys
->i_frontend_handle
;
472 ufds
[1].events
= POLLPRI
;
474 /* We'll wait 0.5 second if nothing happens */
475 /* Find if some data is available */
476 i_ret
= poll( ufds
, 2, 500 );
478 if ( !vlc_object_alive (p_access
) )
486 msg_Err( p_access
, "poll error: %m" );
490 if ( p_sys
->i_ca_handle
&& mdate() > p_sys
->i_ca_next_event
)
493 p_sys
->i_ca_next_event
= mdate() + p_sys
->i_ca_timeout
;
496 if ( ufds
[1].revents
)
498 FrontendPoll( p_access
);
502 if ( p_sys
->i_httpd_timeout
&& mdate() > p_sys
->i_httpd_timeout
)
504 vlc_mutex_lock( &p_sys
->httpd_mutex
);
505 if ( p_sys
->b_request_frontend_info
)
507 msg_Warn( p_access
, "frontend timeout for HTTP interface" );
508 p_sys
->b_request_frontend_info
= false;
509 p_sys
->psz_frontend_info
= strdup( "Timeout getting info\n" );
511 if ( p_sys
->b_request_mmi_info
)
513 msg_Warn( p_access
, "MMI timeout for HTTP interface" );
514 p_sys
->b_request_mmi_info
= false;
515 p_sys
->psz_mmi_info
= strdup( "Timeout getting info\n" );
517 vlc_cond_signal( &p_sys
->httpd_cond
);
518 vlc_mutex_unlock( &p_sys
->httpd_mutex
);
521 if ( p_sys
->b_request_frontend_info
)
523 FrontendStatus( p_access
);
526 if ( p_sys
->b_request_mmi_info
)
528 CAMStatus( p_access
);
532 if ( p_sys
->i_frontend_timeout
&& mdate() > p_sys
->i_frontend_timeout
)
534 msg_Warn( p_access
, "no lock, tuning again" );
535 FrontendSet( p_access
);
538 if ( ufds
[0].revents
)
540 p_block
= block_New( p_access
,
541 p_sys
->i_read_once
* TS_PACKET_SIZE
);
542 if( ( i_ret
= read( p_sys
->i_handle
, p_block
->p_buffer
,
543 p_sys
->i_read_once
* TS_PACKET_SIZE
) ) <= 0 )
545 msg_Warn( p_access
, "read failed (%m)" );
546 block_Release( p_block
);
549 p_block
->i_buffer
= i_ret
;
554 if( p_sys
->i_read_once
< DVB_READ_ONCE
)
555 p_sys
->i_read_once
++;
557 /* Update moderatly the signal properties */
558 if( (p_sys
->i_stat_counter
++ % 100) == 0 )
559 p_access
->info
.i_update
|= INPUT_UPDATE_SIGNAL
;
564 /*****************************************************************************
566 *****************************************************************************/
567 static block_t
*BlockScan( access_t
*p_access
)
569 access_sys_t
*p_sys
= p_access
->p_sys
;
570 scan_t
*p_scan
= &p_sys
->scan
;
571 scan_configuration_t cfg
;
572 scan_session_t session
;
574 /* set satellite config file path */
575 if( p_scan
->parameter
.type
== SCAN_DVB_S
)
576 p_scan
->parameter
.sat_info
.psz_name
= var_GetString( p_access
, "dvb-satellite" );
579 if( scan_Next( p_scan
, &cfg
) )
581 const bool b_first_eof
= !p_access
->info
.b_eof
;
584 msg_Warn( p_access
, "Scanning finished" );
587 p_access
->info
.b_eof
= true;
588 return b_first_eof
? scan_GetM3U( p_scan
) : NULL
;
593 if( scan_session_Init( VLC_OBJECT(p_access
), &session
, &cfg
) )
597 if( p_scan
->parameter
.type
== SCAN_DVB_S
)
600 "Scanning frequency %d, symbol rate = %d, fec = %d",
606 msg_Dbg( p_access
, "Scanning frequency %d, bandwidth = %d",
610 var_SetInteger( p_access
, "dvb-frequency", cfg
.i_frequency
);
611 var_SetInteger( p_access
, "dvb-bandwidth", cfg
.i_bandwidth
);
613 var_SetInteger( p_access
, "dvb-fec", cfg
.i_fec
);
614 if ( cfg
.c_polarization
)
615 var_SetInteger( p_access
, "dvb-voltage", cfg
.c_polarization
== 'H' ? 18 : 13 );
617 /* Setting frontend parameters for tuning the hardware */
618 if( FrontendSet( p_access
) < 0 )
620 msg_Err( p_access
, "Failed to tune the frontend" );
621 p_access
->info
.b_eof
= true;
626 int64_t i_scan_start
= mdate();
628 bool b_has_dvb_signal
= false;
629 bool b_has_lock
= false;
634 struct pollfd ufds
[2];
637 /* Initialize file descriptor sets */
638 memset (ufds
, 0, sizeof (ufds
));
639 ufds
[0].fd
= p_sys
->i_handle
;
640 ufds
[0].events
= POLLIN
;
641 ufds
[1].fd
= p_sys
->i_frontend_handle
;
642 ufds
[1].events
= POLLPRI
;
644 /* We'll wait 0.1 second if nothing happens */
645 /* Find if some data is available */
646 i_ret
= poll( ufds
, 2, 100 );
648 if( !vlc_object_alive (p_access
) || scan_IsCancelled( p_scan
) )
653 const mtime_t i_scan_time
= mdate() - i_scan_start
;
654 frontend_status_t status
;
656 FrontendGetStatus( p_access
, &status
);
658 b_has_dvb_signal
|= status
.b_has_carrier
;
659 b_has_lock
|= status
.b_has_lock
;
661 if( ( !b_has_dvb_signal
&& i_scan_time
> DVB_SCAN_MAX_SIGNAL_TIME
) ||
662 ( !b_has_lock
&& i_scan_time
> DVB_SCAN_MAX_LOCK_TIME
) ||
663 ( i_scan_time
> DVB_SCAN_MAX_PROBE_TIME
) )
665 msg_Dbg( p_access
, "timed out scanning current frequency (s=%d l=%d)", b_has_dvb_signal
, b_has_lock
);
675 msg_Err( p_access
, "poll error: %m" );
676 scan_session_Clean( p_scan
, &session
);
678 p_access
->info
.b_eof
= true;
682 if( ufds
[1].revents
)
684 frontend_statistic_t stat
;
686 FrontendPoll( p_access
);
688 if( !FrontendGetStatistic( p_access
, &stat
) )
690 if( stat
.i_snr
> i_best_snr
)
691 i_best_snr
= stat
.i_snr
;
695 if ( p_sys
->i_frontend_timeout
&& mdate() > p_sys
->i_frontend_timeout
)
697 msg_Warn( p_access
, "no lock, tuning again" );
698 FrontendSet( p_access
);
701 if ( ufds
[0].revents
)
703 const int i_read_once
= 1;
704 block_t
*p_block
= block_New( p_access
, i_read_once
* TS_PACKET_SIZE
);
706 if( ( i_ret
= read( p_sys
->i_handle
, p_block
->p_buffer
,
707 i_read_once
* TS_PACKET_SIZE
) ) <= 0 )
709 msg_Warn( p_access
, "read failed (%m)" );
710 block_Release( p_block
);
713 p_block
->i_buffer
= i_ret
;
716 if( scan_session_Push( &session
, p_block
) )
718 msg_Dbg( p_access
, "finished scanning current frequency" );
726 scan_service_SetSNR( &session
, i_best_snr
);
728 scan_session_Clean( p_scan
, &session
);
732 /*****************************************************************************
734 *****************************************************************************/
735 static int Control( access_t
*p_access
, int i_query
, va_list args
)
737 access_sys_t
*p_sys
= p_access
->p_sys
;
738 bool *pb_bool
, b_bool
;
743 frontend_statistic_t stat
;
748 case ACCESS_CAN_SEEK
:
749 case ACCESS_CAN_FASTSEEK
:
750 case ACCESS_CAN_PAUSE
:
751 case ACCESS_CAN_CONTROL_PACE
:
752 pb_bool
= (bool*)va_arg( args
, bool* );
756 case ACCESS_GET_PTS_DELAY
:
757 pi_64
= (int64_t*)va_arg( args
, int64_t * );
758 *pi_64
= var_GetInteger( p_access
, "dvb-caching" ) * 1000;
762 case ACCESS_SET_PAUSE_STATE
:
763 case ACCESS_GET_TITLE_INFO
:
764 case ACCESS_SET_TITLE
:
765 case ACCESS_SET_SEEKPOINT
:
766 case ACCESS_GET_CONTENT_TYPE
:
769 case ACCESS_GET_SIGNAL
:
770 pf1
= (double*)va_arg( args
, double * );
771 pf2
= (double*)va_arg( args
, double * );
774 if( !FrontendGetStatistic( p_access
, &stat
) )
776 *pf1
= (double)stat
.i_snr
/ 65535.0;
777 *pf2
= (double)stat
.i_signal_strenth
/ 65535.0;
781 case ACCESS_SET_PRIVATE_ID_STATE
:
782 if( p_sys
->b_scan_mode
)
785 i_int
= (int)va_arg( args
, int ); /* Private data (pid for now)*/
786 b_bool
= (bool)va_arg( args
, int ); /* b_selected */
787 if( !p_sys
->b_budget_mode
)
789 /* FIXME we may want to give the real type (me ?, I don't ;) */
791 FilterSet( p_access
, i_int
, OTHER_TYPE
);
793 FilterUnsetPID( p_access
, i_int
);
797 case ACCESS_SET_PRIVATE_ID_CA
:
798 if( p_sys
->b_scan_mode
)
801 p_pmt
= (dvbpsi_pmt_t
*)va_arg( args
, dvbpsi_pmt_t
* );
803 CAMSet( p_access
, p_pmt
);
807 msg_Warn( p_access
, "unimplemented query in control" );
814 /*****************************************************************************
815 * FilterSet/FilterUnset:
816 *****************************************************************************/
817 static void FilterSet( access_t
*p_access
, int i_pid
, int i_type
)
819 access_sys_t
*p_sys
= p_access
->p_sys
;
822 /* Find first free slot */
823 for( i
= 0; i
< MAX_DEMUX
; i
++ )
825 if( !p_sys
->p_demux_handles
[i
].i_type
)
828 if( p_sys
->p_demux_handles
[i
].i_pid
== i_pid
)
829 return; /* Already set */
834 msg_Err( p_access
, "no free p_demux_handles !" );
838 if( DMXSetFilter( p_access
, i_pid
,
839 &p_sys
->p_demux_handles
[i
].i_handle
, i_type
) )
841 msg_Err( p_access
, "DMXSetFilter failed" );
844 p_sys
->p_demux_handles
[i
].i_type
= i_type
;
845 p_sys
->p_demux_handles
[i
].i_pid
= i_pid
;
847 if( p_sys
->i_read_once
< DVB_READ_ONCE
)
848 p_sys
->i_read_once
++;
851 static void FilterUnset( access_t
*p_access
, int i_max
)
853 access_sys_t
*p_sys
= p_access
->p_sys
;
856 for( i
= 0; i
< i_max
; i
++ )
858 if( p_sys
->p_demux_handles
[i
].i_type
)
860 DMXUnsetFilter( p_access
, p_sys
->p_demux_handles
[i
].i_handle
);
861 p_sys
->p_demux_handles
[i
].i_type
= 0;
866 static void FilterUnsetPID( access_t
*p_access
, int i_pid
)
868 access_sys_t
*p_sys
= p_access
->p_sys
;
871 for( i
= 0; i
< MAX_DEMUX
; i
++ )
873 if( p_sys
->p_demux_handles
[i
].i_type
&&
874 p_sys
->p_demux_handles
[i
].i_pid
== i_pid
)
876 DMXUnsetFilter( p_access
, p_sys
->p_demux_handles
[i
].i_handle
);
877 p_sys
->p_demux_handles
[i
].i_type
= 0;
882 /*****************************************************************************
884 *****************************************************************************/
885 static void VarInit( access_t
*p_access
)
888 var_Create( p_access
, "dvb-caching", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
891 var_Create( p_access
, "dvb-adapter", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
892 var_Create( p_access
, "dvb-device", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
893 var_Create( p_access
, "dvb-frequency", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
894 var_Create( p_access
, "dvb-inversion", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
895 var_Create( p_access
, "dvb-probe", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
896 var_Create( p_access
, "dvb-budget-mode", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
899 var_Create( p_access
, "dvb-satellite", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
900 var_Create( p_access
, "dvb-satno", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
901 var_Create( p_access
, "dvb-voltage", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
902 var_Create( p_access
, "dvb-high-voltage", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
903 var_Create( p_access
, "dvb-tone", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
904 var_Create( p_access
, "dvb-fec", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
905 var_Create( p_access
, "dvb-srate", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
906 var_Create( p_access
, "dvb-lnb-lof1", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
907 var_Create( p_access
, "dvb-lnb-lof2", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
908 var_Create( p_access
, "dvb-lnb-slof", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
911 var_Create( p_access
, "dvb-modulation", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
914 var_Create( p_access
, "dvb-code-rate-hp", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
915 var_Create( p_access
, "dvb-code-rate-lp", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
916 var_Create( p_access
, "dvb-bandwidth", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
917 var_Create( p_access
, "dvb-transmission", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
918 var_Create( p_access
, "dvb-guard", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
919 var_Create( p_access
, "dvb-hierarchy", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
922 var_Create( p_access
, "dvb-http-host", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
923 var_Create( p_access
, "dvb-http-user", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
924 var_Create( p_access
, "dvb-http-password", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
925 var_Create( p_access
, "dvb-http-acl", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
926 var_Create( p_access
, "dvb-http-intf-cert", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
927 var_Create( p_access
, "dvb-http-intf-key", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
928 var_Create( p_access
, "dvb-http-intf-ca", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
929 var_Create( p_access
, "dvb-http-intf-crl", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
934 static int ParseMRL( access_t
*p_access
)
936 char *psz_dup
= strdup( p_access
->psz_location
);
937 char *psz_parser
= psz_dup
;
941 #define GET_OPTION_INT( option ) \
942 if ( !strncmp( psz_parser, option "=", strlen(option "=") ) ) \
944 val.i_int = strtol( psz_parser + strlen(option "="), &psz_parser, \
946 var_Set( p_access, "dvb-" option, val ); \
949 #define GET_OPTION_BOOL( option ) \
950 if ( !strncmp( psz_parser, option "=", strlen(option "=") ) ) \
952 val.b_bool = strtol( psz_parser + strlen(option "="), &psz_parser, \
954 var_Set( p_access, "dvb-" option, val ); \
957 #define GET_OPTION_STRING( option ) \
958 if ( !strncmp( psz_parser, option "=", strlen( option "=" ) ) ) \
960 psz_parser += strlen( option "=" ); \
961 val.psz_string = psz_parser; \
963 char *tok = strtok_r(val.psz_string, ":", &p_save); \
964 val.psz_string[tok - val.psz_string - 1] = 0; \
965 var_Set( p_access, "dvb-" option, val ); \
966 psz_parser += strlen( val.psz_string ); \
969 /* Test for old syntax */
970 strtol( psz_parser
, &psz_next
, 10 );
971 if( psz_next
!= psz_parser
)
973 msg_Err( p_access
, "the DVB input old syntax is deprecated, use vlc "
974 "-p dvb to see an explanation of the new syntax" );
975 dialog_FatalWait( p_access
, _("Input syntax is deprecated"), "%s",
976 _("The given syntax is deprecated. Run \"vlc -p dvb\" to see an " \
977 "explanation of the new syntax.") );
984 GET_OPTION_INT("adapter")
985 else GET_OPTION_INT("device")
986 else GET_OPTION_INT("frequency")
987 else GET_OPTION_INT("inversion")
988 else GET_OPTION_BOOL("probe")
989 else GET_OPTION_BOOL("budget-mode")
991 else GET_OPTION_STRING("satellite")
992 else GET_OPTION_INT("voltage")
993 else GET_OPTION_BOOL("high-voltage")
994 else GET_OPTION_INT("tone")
995 else GET_OPTION_INT("satno")
996 else GET_OPTION_INT("fec")
997 else GET_OPTION_INT("srate")
998 else GET_OPTION_INT("lnb-lof1")
999 else GET_OPTION_INT("lnb-lof2")
1000 else GET_OPTION_INT("lnb-slof")
1002 else GET_OPTION_INT("modulation")
1004 else GET_OPTION_INT("code-rate-hp")
1005 else GET_OPTION_INT("code-rate-lp")
1006 else GET_OPTION_INT("bandwidth")
1007 else GET_OPTION_INT("transmission")
1008 else GET_OPTION_INT("guard")
1009 else GET_OPTION_INT("hierarchy")
1011 /* Redundant with voltage but much easier to use */
1012 else if( !strncmp( psz_parser
, "polarization=",
1013 strlen( "polarization=" ) ) )
1015 psz_parser
+= strlen( "polarization=" );
1016 if ( *psz_parser
== 'V' || *psz_parser
== 'v' )
1018 else if ( *psz_parser
== 'H' || *psz_parser
== 'h' )
1022 msg_Err( p_access
, "illegal polarization %c", *psz_parser
);
1023 dialog_Fatal( p_access
, _("Invalid polarization"),
1024 _("The provided polarization \"%c\" is not valid."),
1027 return VLC_EGENERIC
;
1029 var_Set( p_access
, "dvb-voltage", val
);
1033 msg_Err( p_access
, "unknown option (%s)", psz_parser
);
1035 return VLC_EGENERIC
;
1041 #undef GET_OPTION_INT
1042 #undef GET_OPTION_BOOL
1043 #undef GET_OPTION_STRING