3 * @brief Digital broadcasting input module for VLC media player
5 /*****************************************************************************
6 * Copyright © 2011 Rémi Denis-Courmont
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
27 #include <vlc_common.h>
28 #include <vlc_access.h>
29 #include <vlc_input.h>
30 #include <vlc_plugin.h>
31 #include <vlc_dialog.h>
36 #define ADAPTER_TEXT N_("DVB adapter")
37 #define ADAPTER_LONGTEXT N_( \
38 "If there is more than one digital broadcasting adapter, " \
39 "the adapter number must be selected. Numbering starts from zero.")
41 #define DEVICE_TEXT N_("DVB device")
42 #define DEVICE_LONGTEXT N_( \
43 "If the adapter provides multiple independent tuner devices, " \
44 "the device number must be selected. Numbering starts from zero.")
45 #define BUDGET_TEXT N_("Do not demultiplex")
46 #define BUDGET_LONGTEXT N_( \
47 "Only useful programs are normally demultiplexed from the transponder. " \
48 "This option will disable demultiplexing and receive all programs.")
50 #define NAME_TEXT N_("Network name")
51 #define NAME_LONGTEXT N_("Unique network name in the System Tuning Spaces")
53 #define CREATE_TEXT N_("Network name to create")
54 #define CREATE_LONGTEXT N_("Create unique name in the System Tuning Spaces")
56 #define FREQ_TEXT N_("Frequency (Hz)")
57 #define FREQ_LONGTEXT N_( \
58 "TV channels are grouped by transponder (a.k.a. multiplex) " \
59 "on a given frequency. This is required to tune the receiver.")
61 #define MODULATION_TEXT N_("Modulation / Constellation")
62 #define MODULATION_A_TEXT N_("Layer A modulation")
63 #define MODULATION_B_TEXT N_("Layer B modulation")
64 #define MODULATION_C_TEXT N_("Layer C modulation")
65 #define MODULATION_LONGTEXT N_( \
66 "The digital signal can be modulated according with different " \
67 "constellations (depending on the delivery system). " \
68 "If the demodulator cannot detect the constellation automatically, " \
69 "it needs to be configured manually.")
70 static const char *const modulation_vlc
[] = { "",
71 "QAM", "16QAM", "32QAM", "64QAM", "128QAM", "256QAM",
73 "QPSK", "DQPSK", "8PSK", "16APSK", "32APSK",
75 static const char *const modulation_user
[] = { N_("Undefined"),
76 "Auto QAM", "16-QAM", "32-QAM", "64-QAM", "128-QAM", "256-QAM",
78 "QPSK", "DQPSK", "8-PSK", "16-APSK", "32-APSK",
81 #define SRATE_TEXT N_("Symbol rate (bauds)")
82 #define SRATE_LONGTEXT N_( \
83 "The symbol rate must be specified manually for some systems, " \
84 "notably DVB-C, DVB-S and DVB-S2.")
86 #define INVERSION_TEXT N_("Spectrum inversion")
87 #define INVERSION_LONGTEXT N_( \
88 "If the demodulator cannot detect spectral inversion correctly, " \
89 "it needs to be configured manually.")
90 const int auto_off_on_vlc
[] = { -1, 0, 1 };
91 static const char *const auto_off_on_user
[] = { N_("Automatic"),
92 N_("Off"), N_("On") };
94 #define CODE_RATE_TEXT N_("FEC code rate")
95 #define CODE_RATE_HP_TEXT N_("High-priority code rate")
96 #define CODE_RATE_LP_TEXT N_("Low-priority code rate")
97 #define CODE_RATE_A_TEXT N_("Layer A code rate")
98 #define CODE_RATE_B_TEXT N_("Layer B code rate")
99 #define CODE_RATE_C_TEXT N_("Layer C code rate")
100 #define CODE_RATE_LONGTEXT N_( \
101 "The code rate for Forward Error Correction can be specified.")
102 static const char *const code_rate_vlc
[] = { "",
103 "0", /*"1/4", "1/3",*/ "1/2", "3/5", "2/3", "3/4",
104 "4/5", "5/6", "6/7", "7/8", "8/9", "9/10",
106 static const char *const code_rate_user
[] = { N_("Automatic"),
107 N_("None"), /*"1/4", "1/3",*/ "1/2", "3/5", "2/3", "3/4",
108 "4/5", "5/6", "6/7", "7/8", "8/9", "9/10",
111 #define TRANSMISSION_TEXT N_("Transmission mode")
112 const int transmission_vlc
[] = { -1,
115 static const char *const transmission_user
[] = { N_("Automatic"),
116 "1k", "2k", "4k", "8k", "16k", "32k",
119 #define BANDWIDTH_TEXT N_("Bandwidth (MHz)")
120 const int bandwidth_vlc
[] = { 0,
123 static const char *const bandwidth_user
[] = { N_("Automatic"),
124 N_("10 MHz"), N_("8 MHz"), N_("7 MHz"), N_("6 MHz"),
125 N_("5 MHz"), N_("1.712 MHz"),
128 #define GUARD_TEXT N_("Guard interval")
129 const char *const guard_vlc
[] = { "",
130 "1/128", "1/32", "1/16", "19/256", "1/8", "19/128", "1/4",
132 static const char *const guard_user
[] = { N_("Automatic"),
133 "1/128", "1/32", "1/16", "19/256", "1/8", "19/128", "1/4",
136 #define HIERARCHY_TEXT N_("Hierarchy mode")
137 const int hierarchy_vlc
[] = { -1,
140 static const char *const hierarchy_user
[] = { N_("Automatic"),
141 N_("None"), "1", "2", "4",
144 #define PLP_ID_TEXT N_("DVB-T2 Physical Layer Pipe")
146 #define SEGMENT_COUNT_A_TEXT N_("Layer A segments count")
147 #define SEGMENT_COUNT_B_TEXT N_("Layer B segments count")
148 #define SEGMENT_COUNT_C_TEXT N_("Layer C segments count")
150 #define TIME_INTERLEAVING_A_TEXT N_("Layer A time interleaving")
151 #define TIME_INTERLEAVING_B_TEXT N_("Layer B time interleaving")
152 #define TIME_INTERLEAVING_C_TEXT N_("Layer C time interleaving")
154 #define STREAM_ID_TEXT N_("Stream identifier")
156 #define PILOT_TEXT N_("Pilot")
158 #define ROLLOFF_TEXT N_("Roll-off factor")
159 const int rolloff_vlc
[] = { -1,
162 static const char *const rolloff_user
[] = { N_("Automatic"),
163 N_("0.35 (same as DVB-S)"), N_("0.20"), N_("0.25"),
166 #define TS_ID_TEXT N_("Transport stream ID")
168 #define POLARIZATION_TEXT N_("Polarization (Voltage)")
169 #define POLARIZATION_LONGTEXT N_( \
170 "To select the polarization of the transponder, a different voltage " \
171 "is normally applied to the low noise block-downconverter (LNB).")
172 static const char *const polarization_vlc
[] = { "", "V", "H", "R", "L" };
173 static const char *const polarization_user
[] = { N_("Unspecified (0V)"),
174 N_("Vertical (13V)"), N_("Horizontal (18V)"),
175 N_("Circular Right Hand (13V)"), N_("Circular Left Hand (18V)") };
177 #define HIGH_VOLTAGE_TEXT N_("High LNB voltage")
178 #define HIGH_VOLTAGE_LONGTEXT N_( \
179 "If the cables between the satellilte low noise block-downconverter and " \
180 "the receiver are long, higher voltage may be required.\n" \
181 "Not all receivers support this.")
183 #define LNB_LOW_TEXT N_("Local oscillator low frequency (kHz)")
184 #define LNB_HIGH_TEXT N_("Local oscillator high frequency (kHz)")
185 #define LNB_LONGTEXT N_( \
186 "The downconverter (LNB) will subtract the local oscillator frequency " \
187 "from the satellite transmission frequency. " \
188 "The intermediate frequency (IF) on the RF cable is the result.")
189 #define LNB_SWITCH_TEXT N_("Universal LNB switch frequency (kHz)")
190 #define LNB_SWITCH_LONGTEXT N_( \
191 "If the satellite transmission frequency exceeds the switch frequency, " \
192 "the oscillator high frequency will be used as reference. " \
193 "Furthermore the automatic continuous 22kHz tone will be sent.")
194 #define TONE_TEXT N_("Continuous 22kHz tone")
195 #define TONE_LONGTEXT N_( \
196 "A continuous tone at 22kHz can be sent on the cable. " \
197 "This normally selects the higher frequency band from a universal LNB.")
199 #define SATNO_TEXT N_("DiSEqC LNB number")
200 #define SATNO_LONGTEXT N_( \
201 "If the satellite receiver is connected to multiple " \
202 "low noise block-downconverters (LNB) through a DiSEqC 1.0 switch, " \
203 "the correct LNB can be selected (1 to 4). " \
204 "If there is no switch, this parameter should be 0.")
205 #ifdef HAVE_LINUX_DVB
206 static const int satno_vlc
[] = { 0, 1, 2, 3, 4 };
207 static const char *const satno_user
[] = { N_("Unspecified"),
208 "A/1", "B/2", "C/3", "D/4" };
211 #define UNCOMMITTED_TEXT N_("Uncommitted DiSEqC LNB number")
212 #define UNCOMMITTED_LONGTEXT N_( \
213 "If the satellite receiver is connected to multiple " \
214 "low noise block-downconverters (LNB) through a cascade formed from " \
215 "DiSEqC 1.1 uncommitted switch and DiSEqC 1.0 committed switch, " \
216 "the correct uncommitted LNB can be selected (1 to 4). " \
217 "If there is no uncommitted switch, this parameter should be 0.")
219 /* BDA module additional DVB-S Parameters */
220 #define NETID_TEXT N_("Network identifier")
221 #define AZIMUTH_TEXT N_("Satellite azimuth")
222 #define AZIMUTH_LONGTEXT N_("Satellite azimuth in tenths of degree")
223 #define ELEVATION_TEXT N_("Satellite elevation")
224 #define ELEVATION_LONGTEXT N_("Satellite elevation in tenths of degree")
225 #define LONGITUDE_TEXT N_("Satellite longitude")
226 #define LONGITUDE_LONGTEXT N_( \
227 "Satellite longitude in tenths of degree. West is negative.")
229 #define RANGE_TEXT N_("Satellite range code")
230 #define RANGE_LONGTEXT N_("Satellite range code as defined by manufacturer " \
231 "e.g. DISEqC switch code")
234 #define MAJOR_CHANNEL_TEXT N_("Major channel")
235 #define MINOR_CHANNEL_TEXT N_("ATSC minor channel")
236 #define PHYSICAL_CHANNEL_TEXT N_("Physical channel")
238 static int Open (vlc_object_t
*);
239 static void Close (vlc_object_t
*);
242 set_shortname (N_("DTV"))
243 set_description (N_("Digital Television and Radio"))
244 set_category (CAT_INPUT
)
245 set_subcategory (SUBCAT_INPUT_ACCESS
)
246 set_capability ("access", 0)
247 set_callbacks (Open
, Close
)
248 add_shortcut ("dtv", "tv", "dvb", /* "radio", "dab",*/
249 "cable", "dvb-c", "cqam", "isdb-c",
250 "satellite", "dvb-s", "dvb-s2", "isdb-s",
251 "terrestrial", "dvb-t", "dvb-t2", "isdb-t", "atsc"
257 #ifdef HAVE_LINUX_DVB
258 add_integer ("dvb-adapter", 0, ADAPTER_TEXT
, ADAPTER_LONGTEXT
, false)
259 change_integer_range (0, 255)
261 add_integer ("dvb-device", 0, DEVICE_TEXT
, DEVICE_LONGTEXT
, false)
262 change_integer_range (0, 255)
264 add_bool ("dvb-budget-mode", false, BUDGET_TEXT
, BUDGET_LONGTEXT
, true)
267 add_integer ("dvb-adapter", -1, ADAPTER_TEXT
, ADAPTER_LONGTEXT
, true)
269 add_string ("dvb-network-name", "", NAME_TEXT
, NAME_LONGTEXT
, true)
270 /* Hmm: is this one really safe??: */
271 add_string ("dvb-create-name", "", CREATE_TEXT
, CREATE_LONGTEXT
, true)
274 add_integer ("dvb-frequency", 0, FREQ_TEXT
, FREQ_LONGTEXT
, false)
275 change_integer_range (0, 107999999)
277 add_integer ("dvb-inversion", -1, INVERSION_TEXT
, INVERSION_LONGTEXT
, true)
278 change_integer_list (auto_off_on_vlc
, auto_off_on_user
)
281 set_section (N_("Terrestrial reception parameters"), NULL
)
282 add_integer ("dvb-bandwidth", 0, BANDWIDTH_TEXT
, BANDWIDTH_TEXT
, true)
283 change_integer_list (bandwidth_vlc
, bandwidth_user
)
285 add_integer ("dvb-transmission", 0,
286 TRANSMISSION_TEXT
, TRANSMISSION_TEXT
, true)
287 change_integer_list (transmission_vlc
, transmission_user
)
289 add_string ("dvb-guard", "", GUARD_TEXT
, GUARD_TEXT
, true)
290 change_string_list (guard_vlc
, guard_user
)
293 set_section (N_("DVB-T reception parameters"), NULL
)
294 add_string ("dvb-code-rate-hp", "",
295 CODE_RATE_HP_TEXT
, CODE_RATE_LONGTEXT
, true)
296 change_string_list (code_rate_vlc
, code_rate_user
)
298 add_string ("dvb-code-rate-lp", "",
299 CODE_RATE_LP_TEXT
, CODE_RATE_LONGTEXT
, true)
300 change_string_list (code_rate_vlc
, code_rate_user
)
302 add_integer ("dvb-hierarchy", -1, HIERARCHY_TEXT
, HIERARCHY_TEXT
, true)
303 change_integer_list (hierarchy_vlc
, hierarchy_user
)
305 add_integer ("dvb-plp-id", 0, PLP_ID_TEXT
, PLP_ID_TEXT
, false)
306 change_integer_range (0, 255)
309 set_section (N_("ISDB-T reception parameters"), NULL
)
310 add_string ("dvb-a-modulation", NULL
,
311 MODULATION_A_TEXT
, MODULATION_LONGTEXT
, true)
312 change_string_list (modulation_vlc
, modulation_user
)
314 add_string ("dvb-a-fec", NULL
, CODE_RATE_A_TEXT
, CODE_RATE_LONGTEXT
, true)
315 change_string_list (code_rate_vlc
, code_rate_user
)
317 add_integer ("dvb-a-count", 0, SEGMENT_COUNT_A_TEXT
, NULL
, true)
318 change_integer_range (0, 13)
320 add_integer ("dvb-a-interleaving", 0, TIME_INTERLEAVING_A_TEXT
, NULL
, true)
321 change_integer_range (0, 3)
323 add_string ("dvb-b-modulation", NULL
,
324 MODULATION_B_TEXT
, MODULATION_LONGTEXT
, true)
325 change_string_list (modulation_vlc
, modulation_user
)
327 add_string ("dvb-b-fec", NULL
, CODE_RATE_B_TEXT
, CODE_RATE_LONGTEXT
, true)
328 change_string_list (code_rate_vlc
, code_rate_user
)
330 add_integer ("dvb-b-count", 0, SEGMENT_COUNT_B_TEXT
, NULL
, true)
331 change_integer_range (0, 13)
333 add_integer ("dvb-b-interleaving", 0, TIME_INTERLEAVING_B_TEXT
, NULL
, true)
334 change_integer_range (0, 3)
336 add_string ("dvb-c-modulation", NULL
,
337 MODULATION_C_TEXT
, MODULATION_LONGTEXT
, true)
338 change_string_list (modulation_vlc
, modulation_user
)
340 add_string ("dvb-c-fec", NULL
, CODE_RATE_C_TEXT
, CODE_RATE_LONGTEXT
, true)
341 change_string_list (code_rate_vlc
, code_rate_user
)
343 add_integer ("dvb-c-count", 0, SEGMENT_COUNT_C_TEXT
, NULL
, true)
344 change_integer_range (0, 13)
346 add_integer ("dvb-c-interleaving", 0, TIME_INTERLEAVING_C_TEXT
, NULL
, true)
347 change_integer_range (0, 3)
350 set_section (N_("Cable and satellite reception parameters"), NULL
)
351 add_string ("dvb-modulation", NULL
,
352 MODULATION_TEXT
, MODULATION_LONGTEXT
, false)
353 change_string_list (modulation_vlc
, modulation_user
)
355 add_integer ("dvb-srate", 0, SRATE_TEXT
, SRATE_LONGTEXT
, false)
356 change_integer_range (0, UINT64_C(0xffffffff))
358 add_string ("dvb-fec", "", CODE_RATE_TEXT
, CODE_RATE_LONGTEXT
, true)
359 change_string_list (code_rate_vlc
, code_rate_user
)
362 set_section (N_("DVB-S2 parameters"), NULL
)
363 add_integer ("dvb-stream", 0, STREAM_ID_TEXT
, STREAM_ID_TEXT
, false)
364 change_integer_range (0, 255)
366 add_integer ("dvb-pilot", -1, PILOT_TEXT
, PILOT_TEXT
, true)
367 change_integer_list (auto_off_on_vlc
, auto_off_on_user
)
369 add_integer ("dvb-rolloff", -1, ROLLOFF_TEXT
, ROLLOFF_TEXT
, true)
370 change_integer_list (rolloff_vlc
, rolloff_user
)
373 set_section (N_("ISDB-S parameters"), NULL
)
374 add_integer ("dvb-ts-id", 0, TS_ID_TEXT
, TS_ID_TEXT
, false)
375 change_integer_range (0, 0xffff)
378 set_section (N_("Satellite equipment control"), NULL
)
379 add_string ("dvb-polarization", "",
380 POLARIZATION_TEXT
, POLARIZATION_LONGTEXT
, false)
381 change_string_list (polarization_vlc
, polarization_user
)
383 add_integer ("dvb-voltage", 13, "", "", true)
384 change_integer_range (0, 18)
387 #ifdef HAVE_LINUX_DVB
388 add_bool ("dvb-high-voltage", false,
389 HIGH_VOLTAGE_TEXT
, HIGH_VOLTAGE_LONGTEXT
, false)
391 add_integer ("dvb-lnb-low", 0, LNB_LOW_TEXT
, LNB_LONGTEXT
, true)
392 change_integer_range (0, 0x7fffffff)
393 add_obsolete_integer ("dvb-lnb-lof1") /* since 2.0.0 */
394 add_integer ("dvb-lnb-high", 0, LNB_HIGH_TEXT
, LNB_LONGTEXT
, true)
395 change_integer_range (0, 0x7fffffff)
396 add_obsolete_integer ("dvb-lnb-lof2") /* since 2.0.0 */
397 add_integer ("dvb-lnb-switch", 11700000,
398 LNB_SWITCH_TEXT
, LNB_SWITCH_LONGTEXT
, true)
399 change_integer_range (0, 0x7fffffff)
400 add_obsolete_integer ("dvb-lnb-slof") /* since 2.0.0 */
401 #ifdef HAVE_LINUX_DVB
402 add_integer ("dvb-satno", 0, SATNO_TEXT
, SATNO_LONGTEXT
, true)
403 change_integer_list (satno_vlc
, satno_user
)
405 add_integer ("dvb-uncommitted", 0, UNCOMMITTED_TEXT
, UNCOMMITTED_LONGTEXT
, true)
406 change_integer_list (satno_vlc
, satno_user
)
408 add_integer ("dvb-tone", -1, TONE_TEXT
, TONE_LONGTEXT
, true)
409 change_integer_list (auto_off_on_vlc
, auto_off_on_user
)
412 add_integer ("dvb-network-id", 0, NETID_TEXT
, NETID_TEXT
, true)
413 add_integer ("dvb-azimuth", 0, AZIMUTH_TEXT
, AZIMUTH_LONGTEXT
, true)
414 add_integer ("dvb-elevation", 0, ELEVATION_TEXT
, ELEVATION_LONGTEXT
, true)
415 add_integer ("dvb-longitude", 0, LONGITUDE_TEXT
, LONGITUDE_LONGTEXT
, true)
416 add_string ("dvb-range", "", RANGE_TEXT
, RANGE_LONGTEXT
, true)
417 /* dvb-range corresponds to the BDA InputRange parameter which is
418 * used by some drivers to control the diseqc */
420 set_section (N_("ATSC reception parameters"), NULL
)
421 add_integer ("dvb-major-channel", 0, MAJOR_CHANNEL_TEXT
, NULL
, true)
422 add_integer ("dvb-minor-channel", 0, MINOR_CHANNEL_TEXT
, NULL
, true)
423 add_integer ("dvb-physical-channel", 0, PHYSICAL_CHANNEL_TEXT
, NULL
, true)
431 tuner_setup_t pf_setup
;
434 static block_t
*Read (stream_t
*, bool *);
435 static int Control (stream_t
*, int, va_list);
436 static dtv_delivery_t
GuessSystem (const char *, dvb_device_t
*);
437 static dtv_delivery_t
GetDeliveryByScheme(const char *psz_scheme
);
438 static int Tune (vlc_object_t
*, dvb_device_t
*, tuner_setup_t
, uint64_t);
439 static uint64_t var_InheritFrequency (vlc_object_t
*);
441 tuner_setup_t
dtv_get_delivery_tuner_setup( dtv_delivery_t d
);
443 static int Open (vlc_object_t
*obj
)
445 stream_t
*access
= (stream_t
*)obj
;
446 access_sys_t
*sys
= malloc (sizeof (*sys
));
447 if (unlikely(sys
== NULL
))
450 var_LocationParse (obj
, access
->psz_location
, "dvb-");
452 dvb_device_t
*dev
= dvb_open (obj
);
460 sys
->signal_poll
= 0;
461 sys
->pf_setup
= NULL
;
464 uint64_t freq
= var_InheritFrequency (obj
);
467 dtv_delivery_t d
= GuessSystem (access
->psz_name
, dev
);
468 if(d
!= DTV_DELIVERY_NONE
)
469 sys
->pf_setup
= dtv_get_delivery_tuner_setup(d
);
471 if (sys
->pf_setup
== NULL
|| Tune (obj
, dev
, sys
->pf_setup
, freq
))
473 msg_Err (obj
, "tuning to %"PRIu64
" Hz failed", freq
);
474 vlc_dialog_display_error (obj
, N_("Digital broadcasting"),
475 N_("The selected digital tuner does not support "
476 "the specified parameters.\n"
477 "Please check the preferences."));
481 dvb_add_pid (dev
, 0);
483 access
->pf_block
= Read
;
484 access
->pf_control
= Control
;
489 access
->p_sys
= NULL
;
493 static void Close (vlc_object_t
*obj
)
495 stream_t
*access
= (stream_t
*)obj
;
496 access_sys_t
*sys
= access
->p_sys
;
498 dvb_close (sys
->dev
);
502 static block_t
*Read (stream_t
*access
, bool *restrict eof
)
504 #define BUFSIZE (20*188)
505 block_t
*block
= block_Alloc (BUFSIZE
);
506 if (unlikely(block
== NULL
))
509 access_sys_t
*sys
= access
->p_sys
;
510 ssize_t val
= dvb_read (sys
->dev
, block
->p_buffer
, BUFSIZE
, -1);
516 block_Release (block
);
520 block
->i_buffer
= val
;
525 static int Control (stream_t
*access
, int query
, va_list args
)
527 access_sys_t
*sys
= access
->p_sys
;
528 dvb_device_t
*dev
= sys
->dev
;
532 case STREAM_CAN_SEEK
:
533 case STREAM_CAN_FASTSEEK
:
534 case STREAM_CAN_PAUSE
:
535 case STREAM_CAN_CONTROL_PACE
:
536 *va_arg (args
, bool *) = false;
539 case STREAM_GET_PTS_DELAY
:
541 int64_t *v
= va_arg (args
, int64_t *);
542 *v
= var_InheritInteger (access
, "live-caching") * INT64_C(1000);
546 case STREAM_GET_CONTENT_TYPE
:
547 *va_arg (args
, char **) = strdup ("video/MP2T");
550 case STREAM_GET_SIGNAL
:
551 /* Fetch the signal levels only every so often to avoid stressing
553 if ((sys
->signal_poll
++))
556 *va_arg (args
, double *) = dvb_get_snr (dev
);
557 *va_arg (args
, double *) = dvb_get_signal_strength (dev
);
560 case STREAM_SET_PRIVATE_ID_STATE
:
562 unsigned pid
= va_arg (args
, int);
563 bool add
= va_arg (args
, int);
565 if (unlikely(pid
> 0x1FFF))
569 if (dvb_add_pid (dev
, pid
))
573 dvb_remove_pid (dev
, pid
);
577 case STREAM_SET_PRIVATE_ID_CA
:
579 en50221_capmt_info_t
*pmt
= va_arg (args
, en50221_capmt_info_t
*);
581 if( !dvb_set_ca_pmt (dev
, pmt
) )
586 case STREAM_GET_PRIVATE_ID_STATE
:
588 unsigned pid
= va_arg (args
, int);
589 bool *on
= va_arg (args
, bool *);
591 *on
= likely(pid
<= 0x1FFF) ? dvb_get_pid_state(dev
, pid
) : false;
603 /*** Generic tuning ***/
604 /** Set parameters and tune the device */
605 static int Tune (vlc_object_t
*obj
, dvb_device_t
*dev
, tuner_setup_t pf_setup
,
608 if (pf_setup(obj
, dev
, freq
)
609 || dvb_set_inversion (dev
, var_InheritInteger (obj
, "dvb-inversion"))
615 static uint64_t var_InheritFrequency (vlc_object_t
*obj
)
617 uint64_t freq
= var_InheritInteger (obj
, "dvb-frequency");
618 if (freq
!= 0 && freq
< 30000000)
620 msg_Err (obj
, "%"PRIu64
" Hz carrier frequency is too low.", freq
);
622 msg_Info (obj
, "Assuming %"PRIu64
" Hz frequency instead.", freq
);
627 static uint32_t var_InheritCodeRate (vlc_object_t
*obj
, const char *varname
)
629 char *code_rate
= var_InheritString (obj
, varname
);
630 if (code_rate
== NULL
)
634 int v
= sscanf (code_rate
, "%"SCNu16
"/%"SCNu16
, &a
, &b
);
639 return VLC_FEC(a
, b
);
643 /* Backward compatibility with VLC < 1.2 (= Linux DVBv3 enum) */
646 msg_Warn (obj
, "\"%s=%"PRIu16
"\" option is obsolete. "
647 "Use \"%s=%"PRIu16
"/%"PRIu16
"\" instead.",
648 varname
+ 4, a
, varname
+ 4, a
, a
+ 1);
649 return VLC_FEC(a
, a
+ 1);
652 msg_Warn (obj
, "\"fec=9\" option is obsolete.");
657 static int modcmp (const void *a
, const void *b
)
659 return strcasecmp (a
, *(const char *const *)b
);
662 static const char *var_InheritModulation (vlc_object_t
*obj
, const char *var
)
664 char *mod
= var_InheritString (obj
, var
);
668 size_t n
= sizeof (modulation_vlc
) / sizeof (modulation_vlc
[0]);
669 const char *const *p
= lfind (mod
, modulation_vlc
, &n
, sizeof (mod
), modcmp
);
676 /* Backward compatibility with VLC < 1.2 */
680 case -1: str
= "QPSK"; break;
681 case 0: str
= "QAM"; break;
682 case 8: str
= "8VSB"; break;
683 case 16: str
= "16QAM"; break;
684 case 32: str
= "32QAM"; break;
685 case 64: str
= "64QAM"; break;
686 case 128: str
= "128QAM"; break;
687 case 256: str
= "256QAM"; break;
691 msg_Warn (obj
, "\"modulation=%s\" option is obsolete. "
692 "Use \"modulation=%s\" instead.", mod
, str
);
697 static unsigned var_InheritGuardInterval (vlc_object_t
*obj
)
699 char *guard
= var_InheritString (obj
, "dvb-guard");
701 return VLC_GUARD_AUTO
;
704 int v
= sscanf (guard
, "%"SCNu16
"/%"SCNu16
, &a
, &b
);
709 /* Backward compatibility with VLC < 1.2 */
712 msg_Warn (obj
, "\"guard=%"PRIu16
"\" option is obsolete. "
713 "Use \"guard=1/%"PRIu16
" instead.", a
, a
);
718 return VLC_GUARD(a
, b
);
720 return VLC_GUARD_AUTO
;
725 static int atsc_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
727 const char *mod
= var_InheritModulation (obj
, "dvb-modulation");
729 return dvb_set_atsc (dev
, freq
, mod
);
732 static int cqam_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
734 const char *mod
= var_InheritModulation (obj
, "dvb-modulation");
736 return dvb_set_cqam (dev
, freq
, mod
);
740 static int dvbc_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
742 const char *mod
= var_InheritModulation (obj
, "dvb-modulation");
743 uint32_t fec
= var_InheritCodeRate (obj
, "dvb-fec");
744 unsigned srate
= var_InheritInteger (obj
, "dvb-srate");
746 return dvb_set_dvbc (dev
, freq
, mod
, srate
, fec
);
750 static char var_InheritPolarization (vlc_object_t
*obj
)
753 char *polstr
= var_InheritString (obj
, "dvb-polarization");
758 if (unlikely(pol
>= 'a' && pol
<= 'z'))
763 /* Backward compatibility with VLC for Linux < 1.2 */
764 unsigned voltage
= var_InheritInteger (obj
, "dvb-voltage");
767 case 13: pol
= 'V'; break;
768 case 18: pol
= 'H'; break;
772 msg_Warn (obj
, "\"voltage=%u\" option is obsolete. "
773 "Use \"polarization=%c\" instead.", voltage
, pol
);
777 static void sec_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
779 char pol
= var_InheritPolarization (obj
);
780 unsigned lowf
= var_InheritInteger (obj
, "dvb-lnb-low");
781 unsigned highf
= var_InheritInteger (obj
, "dvb-lnb-high");
782 unsigned switchf
= var_InheritInteger (obj
, "dvb-lnb-switch");
784 dvb_set_sec (dev
, freq
, pol
, lowf
, highf
, switchf
);
787 static int dvbs_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
789 uint32_t fec
= var_InheritCodeRate (obj
, "dvb-fec");
790 uint32_t srate
= var_InheritInteger (obj
, "dvb-srate");
792 int ret
= dvb_set_dvbs (dev
, freq
, srate
, fec
);
794 sec_setup (obj
, dev
, freq
);
798 static int dvbs2_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
800 const char *mod
= var_InheritModulation (obj
, "dvb-modulation");
801 uint32_t fec
= var_InheritCodeRate (obj
, "dvb-fec");
802 uint32_t srate
= var_InheritInteger (obj
, "dvb-srate");
803 int pilot
= var_InheritInteger (obj
, "dvb-pilot");
804 int rolloff
= var_InheritInteger (obj
, "dvb-rolloff");
805 uint8_t sid
= var_InheritInteger (obj
, "dvb-stream");
807 int ret
= dvb_set_dvbs2 (dev
, freq
, mod
, srate
, fec
, pilot
, rolloff
, sid
);
809 sec_setup (obj
, dev
, freq
);
814 static int dvbt_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
816 const char *mod
= var_InheritModulation (obj
, "dvb-modulation");
817 uint32_t fec_hp
= var_InheritCodeRate (obj
, "dvb-code-rate-hp");
818 uint32_t fec_lp
= var_InheritCodeRate (obj
, "dvb-code-rate-lp");
819 uint32_t guard
= var_InheritGuardInterval (obj
);
820 uint32_t bw
= var_InheritInteger (obj
, "dvb-bandwidth");
821 int tx
= var_InheritInteger (obj
, "dvb-transmission");
822 int h
= var_InheritInteger (obj
, "dvb-hierarchy");
824 return dvb_set_dvbt (dev
, freq
, mod
, fec_hp
, fec_lp
, bw
, tx
, guard
, h
);
827 static int dvbt2_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
829 const char *mod
= var_InheritModulation (obj
, "dvb-modulation");
830 uint32_t fec
= var_InheritCodeRate (obj
, "dvb-fec");
831 uint32_t guard
= var_InheritGuardInterval (obj
);
832 uint32_t bw
= var_InheritInteger (obj
, "dvb-bandwidth");
833 uint32_t plp
= var_InheritInteger (obj
, "dvb-plp-id");
834 int tx
= var_InheritInteger (obj
, "dvb-transmission");
836 return dvb_set_dvbt2 (dev
, freq
, mod
, fec
, bw
, tx
, guard
, plp
);
840 static int isdbc_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
842 const char *mod
= var_InheritModulation (obj
, "dvb-modulation");
843 uint32_t fec
= var_InheritCodeRate (obj
, "dvb-fec");
844 unsigned srate
= var_InheritInteger (obj
, "dvb-srate");
846 return dvb_set_isdbc (dev
, freq
, mod
, srate
, fec
);
850 static int isdbs_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
852 uint16_t ts_id
= var_InheritInteger (obj
, "dvb-ts-id");
854 int ret
= dvb_set_isdbs (dev
, freq
, ts_id
);
856 sec_setup (obj
, dev
, freq
);
861 static int isdbt_setup (vlc_object_t
*obj
, dvb_device_t
*dev
, uint64_t freq
)
863 isdbt_layer_t layers
[3];
864 uint32_t guard
= var_InheritGuardInterval (obj
);
865 uint32_t bw
= var_InheritInteger (obj
, "dvb-bandwidth");
866 int tx
= var_InheritInteger (obj
, "dvb-transmission");
868 for (unsigned i
= 0; i
< 3; i
++)
870 char varname
[sizeof ("dvb-X-interleaving")];
871 memcpy (varname
, "dvb-X-", 4);
872 varname
[4] = 'a' + i
;
874 strcpy (varname
+ 6, "modulation");
875 layers
[i
].modulation
= var_InheritModulation (obj
, varname
);
876 strcpy (varname
+ 6, "fec");
877 layers
[i
].code_rate
= var_InheritCodeRate (obj
, varname
);
878 strcpy (varname
+ 6, "count");
879 layers
[i
].segment_count
= var_InheritInteger (obj
, varname
);
880 strcpy (varname
+ 6, "interleaving");
881 layers
[i
].time_interleaving
= var_InheritInteger (obj
, varname
);
884 return dvb_set_isdbt (dev
, freq
, bw
, tx
, guard
, layers
);
889 const dtv_delivery_t delivery
;
890 tuner_setup_t
const pf_setup
;
891 const char *psz_scheme
;
892 } delsys_mappings
[] = {
893 { DTV_DELIVERY_ATSC
, atsc_setup
, "atsc" },
894 { DTV_DELIVERY_CQAM
, cqam_setup
, "cqam" },
895 { DTV_DELIVERY_DVB_C
, dvbc_setup
, "dvb-c" },
896 { DTV_DELIVERY_DVB_C2
, dvbc_setup
, "dvb-c2" },
897 { DTV_DELIVERY_DVB_S
, dvbs_setup
, "dvb-s" },
898 { DTV_DELIVERY_DVB_S2
, dvbs2_setup
, "dvb-s2" },
899 { DTV_DELIVERY_DVB_T
, dvbt_setup
, "dvb-t" },
900 { DTV_DELIVERY_DVB_T2
, dvbt2_setup
, "dvb-t2" },
901 { DTV_DELIVERY_ISDB_C
, isdbc_setup
, "isdb-c" },
902 { DTV_DELIVERY_ISDB_S
, isdbs_setup
, "isdb-s" },
903 { DTV_DELIVERY_ISDB_T
, isdbt_setup
, "isdb-t" },
906 tuner_setup_t
dtv_get_delivery_tuner_setup( dtv_delivery_t d
)
908 for (size_t i
=0; i
<ARRAY_SIZE(delsys_mappings
); i
++)
910 if ( delsys_mappings
[i
].delivery
== d
)
911 return delsys_mappings
[i
].pf_setup
;
916 static dtv_delivery_t
GetDeliveryByScheme(const char *psz_scheme
)
918 for (size_t i
=0; i
<ARRAY_SIZE(delsys_mappings
); i
++)
920 if(!strcasecmp(psz_scheme
, delsys_mappings
[i
].psz_scheme
))
921 return delsys_mappings
[i
].delivery
;
923 return DTV_DELIVERY_NONE
;
926 static inline dtv_delivery_t
GetSingleDelivery( dtv_delivery_t d
)
929 return DTV_DELIVERY_NONE
;
931 return 1 << ctz( d
);
934 /** Determines which delivery system to use. */
935 static dtv_delivery_t
GuessSystem (const char *scheme
, dvb_device_t
*dev
)
937 /* Specific delivery system is specified */
938 dtv_delivery_t d
= GetDeliveryByScheme(scheme
);
939 if(d
!= DTV_DELIVERY_NONE
)
942 /* If the demodulator supports 2G, we cannot guess whether
943 * 1G or 2G is intended. For backward compatibility, 1G is assumed
944 * (this is not a limitation of Linux DVB). We will probably need something
945 * smarter when 2G (semi automatic) scanning is implemented. */
946 unsigned systems
= dvb_enum_systems (dev
);
948 systems
&= ~DTV_DELGROUP_G2
;
952 /* Only wave carrier is specified */
953 if (!strcasecmp (scheme
, "cable"))
955 return GetSingleDelivery(systems
& DTV_DELGROUP_CABLE
);
957 else if (!strcasecmp (scheme
, "satellite"))
959 return GetSingleDelivery(systems
& DTV_DELGROUP_SAT
);
961 else if (!strcasecmp (scheme
, "terrestrial"))
963 return GetSingleDelivery(systems
& DTV_DELGROUP_TERRES
);
967 /* Only standards family or nothing is specified */
968 return GetSingleDelivery(systems
);
972 return DTV_DELIVERY_NONE
;