]> git.sesse.net Git - vlc/blob - modules/access/dtv/access.c
0e2ed575493583a0fa617f042ac76ad0f7f13c82
[vlc] / modules / access / dtv / access.c
1 /**
2  * @file access.c
3  * @brief Digital broadcasting input module for VLC media player
4  */
5 /*****************************************************************************
6  * Copyright © 2011 Rémi Denis-Courmont
7  *
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.
12  *
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.
17  *
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  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <vlc_common.h>
28 #include <vlc_access.h>
29 #include <vlc_plugin.h>
30 #include <vlc_dialog.h>
31 #include <search.h>
32
33 #include "dtv/dtv.h"
34
35 #define ADAPTER_TEXT N_("DVB adapter")
36 #define ADAPTER_LONGTEXT N_( \
37     "If there is more than one digital broadcasting adapter, " \
38     "the adapter number must be selected. Numbering start from zero.")
39
40 #define BUDGET_TEXT N_("Do not demultiplex")
41 #define BUDGET_LONGTEXT N_( \
42     "Only useful programs are normally demultiplexed from the transponder. " \
43     "This option will disable demultiplexing and receive all programs.")
44
45 #define NAME_TEXT N_("Network name")
46 #define NAME_LONGTEXT N_("Unique network name in the System Tuning Spaces")
47
48 #define CREATE_TEXT N_("Network name to create")
49 #define CREATE_LONGTEXT N_("Create unique name in the System Tuning Spaces")
50
51 #define FREQ_TEXT N_("Frequency (Hz)")
52 #define FREQ_LONGTEXT N_( \
53     "TV channels are grouped by transponder (a.k.a. multiplex) " \
54     "on a given frequency. This is required to tune the receiver.")
55
56 #define MODULATION_TEXT N_("Modulation / Constellation")
57 #define MODULATION_A_TEXT N_("Layer A modulation")
58 #define MODULATION_B_TEXT N_("Layer B modulation")
59 #define MODULATION_C_TEXT N_("Layer C modulation")
60 #define MODULATION_LONGTEXT N_( \
61     "The digital signal can be modulated according with different " \
62     "constellations (depending on the delivery system). " \
63     "If the demodulator cannot detect the constellation automatically, " \
64     "it needs to be configured manually.")
65 static const char *const modulation_vlc[] = { "",
66     "QAM", "16QAM", "32QAM", "64QAM", "128QAM", "256QAM",
67     "8VSB", "16VSB",
68     "QPSK", "DQPSK", "8PSK", "16APSK", "32APSK",
69 };
70 static const char *const modulation_user[] = { N_("Undefined"),
71     "Auto QAM", "16-QAM", "32-QAM", "64-QAM", "128-QAM", "256-QAM",
72     "8-VSB", "16-VSB",
73     "QPSK", "DQPSK", "8-PSK", "16-APSK", "32-APSK",
74 };
75
76 #define SRATE_TEXT N_("Symbol rate (bauds)")
77 #define SRATE_LONGTEXT N_( \
78     "The symbol rate must be specified manually for some systems, " \
79     "notably DVB-C, DVB-S and DVB-S2.")
80
81 #define INVERSION_TEXT N_("Spectrum inversion")
82 #define INVERSION_LONGTEXT N_( \
83     "If the demodulator cannot detect spectral inversion correctly, " \
84     "it needs to be configured manually.")
85 const int auto_off_on_vlc[] = { -1, 0, 1 };
86 static const char *const auto_off_on_user[] = { N_("Automatic"),
87     N_("Off"), N_("On") };
88
89 #define CODE_RATE_TEXT N_("FEC code rate")
90 #define CODE_RATE_HP_TEXT N_("High-priority code rate")
91 #define CODE_RATE_LP_TEXT N_("Low-priority code rate")
92 #define CODE_RATE_A_TEXT N_("Layer A code rate")
93 #define CODE_RATE_B_TEXT N_("Layer B code rate")
94 #define CODE_RATE_C_TEXT N_("Layer C code rate")
95 #define CODE_RATE_LONGTEXT N_( \
96     "The code rate for Forward Error Correction can be specified.")
97 static const char *const code_rate_vlc[] = { "",
98     "0", /*"1/4", "1/3",*/ "1/2", "3/5", "2/3", "3/4",
99     "4/5", "5/6", "6/7", "7/8", "8/9", "9/10",
100 };
101 static const char *const code_rate_user[] = { N_("Automatic"),
102     N_("None"), /*"1/4", "1/3",*/ "1/2", "3/5", "2/3", "3/4",
103     "4/5", "5/6", "6/7", "7/8", "8/9", "9/10",
104 };
105
106 #define TRANSMISSION_TEXT N_("Transmission mode")
107 const int transmission_vlc[] = { -1,
108     1, 2, 4, 8, 16, 32,
109 };
110 static const char *const transmission_user[] = { N_("Automatic"),
111     "1k", "2k", "4k", "8k", "16k", "32k",
112 };
113
114 #define BANDWIDTH_TEXT N_("Bandwidth (MHz)")
115 const int bandwidth_vlc[] = { 0,
116     10, 8, 7, 6, 5, 2
117 };
118 static const char *const bandwidth_user[] = { N_("Automatic"),
119     N_("10 MHz"), N_("8 MHz"), N_("7 MHz"), N_("6 MHz"),
120     N_("5 MHz"), N_("1.712 MHz"),
121 };
122
123 #define GUARD_TEXT N_("Guard interval")
124 const char *const guard_vlc[] = { "",
125     "1/128", "1/32", "1/16", "19/256", "1/8", "19/128", "1/4",
126 };
127 static const char *const guard_user[] = { N_("Automatic"),
128     "1/128", "1/32", "1/16", "19/256", "1/8", "19/128", "1/4",
129 };
130
131 #define HIERARCHY_TEXT N_("Hierarchy mode")
132 const int hierarchy_vlc[] = { -1,
133     0, 1, 2, 4,
134 };
135 static const char *const hierarchy_user[] = { N_("Automatic"),
136     N_("None"), "1", "2", "4",
137 };
138
139 #define SEGMENT_COUNT_A_TEXT N_("Layer A segments count")
140 #define SEGMENT_COUNT_B_TEXT N_("Layer B segments count")
141 #define SEGMENT_COUNT_C_TEXT N_("Layer C segments count")
142
143 #define TIME_INTERLEAVING_A_TEXT N_("Layer A time interleaving")
144 #define TIME_INTERLEAVING_B_TEXT N_("Layer B time interleaving")
145 #define TIME_INTERLEAVING_C_TEXT N_("Layer C time interleaving")
146
147 #define PILOT_TEXT N_("Pilot")
148
149 #define ROLLOFF_TEXT N_("Roll-off factor")
150 const int rolloff_vlc[] = { -1,
151     35, 20, 25,
152 };
153 static const char *const rolloff_user[] = { N_("Automatic"),
154     N_("0.35 (same as DVB-S)"), N_("0.20"), N_("0.25"),
155 };
156
157 #define TS_ID_TEXT N_("Transport stream ID")
158
159 #define POLARIZATION_TEXT N_("Polarization (Voltage)")
160 #define POLARIZATION_LONGTEXT N_( \
161     "To select the polarization of the transponder, a different voltage " \
162     "is normally applied to the low noise block-downconverter (LNB).")
163 static const char *const polarization_vlc[] = { "", "V", "H", "R", "L" };
164 static const char *const polarization_user[] = { N_("Unspecified (0V)"),
165     N_("Vertical (13V)"), N_("Horizontal (18V)"),
166     N_("Circular Right Hand (13V)"), N_("Circular Left Hand (18V)") };
167
168 #define HIGH_VOLTAGE_TEXT N_("High LNB voltage")
169 #define HIGH_VOLTAGE_LONGTEXT N_( \
170     "If the cables between the satellilte low noise block-downconverter and " \
171     "the receiver are long, higher voltage may be required.\n" \
172     "Not all receivers support this.")
173
174 #define LNB_LOW_TEXT N_("Local oscillator low frequency (kHz)")
175 #define LNB_HIGH_TEXT N_("Local oscillator high frequency (kHz)")
176 #define LNB_LONGTEXT N_( \
177     "The downconverter (LNB) will substract the local oscillator frequency " \
178     "from the satellite transmission frequency. " \
179     "The intermediate frequency (IF) on the RF cable is the result.")
180 #define LNB_SWITCH_TEXT N_("Universal LNB switch frequency (kHz)")
181 #define LNB_SWITCH_LONGTEXT N_( \
182     "If the satellite transmission frequency exceeds the switch frequency, " \
183     "the oscillator high frequency will be used as reference. " \
184     "Furthermore the automatic continuous 22kHz tone will be sent.")
185 #define TONE_TEXT N_("Continuous 22kHz tone")
186 #define TONE_LONGTEXT N_( \
187     "A continuous tone at 22kHz can be sent on the cable. " \
188     "This normally selects the higher frequency band from a universal LNB.")
189
190 #define SATNO_TEXT N_("DiSEqC LNB number")
191 #define SATNO_LONGTEXT N_( \
192     "If the satellite receiver is connected to multiple " \
193     "low noise block-downconverters (LNB) through a DiSEqC 1.0 switch, " \
194     "the correct LNB can be selected (1 to 4). " \
195     "If there is no switch, this parameter should be 0.")
196 #ifdef __linux__
197 static const int satno_vlc[] = { 0, 1, 2, 3, 4 };
198 static const char *const satno_user[] = { N_("Unspecified"),
199     "A/1", "B/2", "C/3", "D/4" };
200 #endif
201
202 /* BDA module additional DVB-S Parameters */
203 #define NETID_TEXT N_("Network identifier")
204 #define AZIMUTH_TEXT N_("Satellite azimuth")
205 #define AZIMUTH_LONGTEXT N_("Satellite azimuth in tenths of degree")
206 #define ELEVATION_TEXT N_("Satellite elevation")
207 #define ELEVATION_LONGTEXT N_("Satellite elevation in tenths of degree")
208 #define LONGITUDE_TEXT N_("Satellite longitude")
209 #define LONGITUDE_LONGTEXT N_( \
210     "Satellite longitude in tenths of degree. West is negative.")
211
212 #define RANGE_TEXT N_("Satellite range code")
213 #define RANGE_LONGTEXT N_("Satellite range code as defined by manufacturer " \
214    "e.g. DISEqC switch code")
215
216 /* ATSC */
217 #define MAJOR_CHANNEL_TEXT N_("Major channel")
218 #define MINOR_CHANNEL_TEXT N_("ATSC minor channel")
219 #define PHYSICAL_CHANNEL_TEXT N_("Physical channel")
220
221 static int  Open (vlc_object_t *);
222 static void Close (vlc_object_t *);
223
224 vlc_module_begin ()
225     set_shortname (N_("DTV"))
226     set_description (N_("Digital Television and Radio"))
227     set_category (CAT_INPUT)
228     set_subcategory (SUBCAT_INPUT_ACCESS)
229     set_capability ("access", 0)
230     set_callbacks (Open, Close)
231     add_shortcut ("dtv", "tv", "dvb", /* "radio", "dab",*/
232                   "cable", "dvb-c", "cqam"
233                   "satellite", "dvb-s", "dvb-s2", "isdb-s",
234                   "terrestrial", "dvb-t", "dvb-t2", "isdb-t", "atsc")
235
236     /* All options starting with dvb- can be overridden in the MRL, so they
237      * must all be "safe". Nevertheless, we do not mark as safe those that are
238      * really specific to the local system (e.g. device ID...).
239      * It wouldn't make sense to deliver those through a playlist. */
240
241 #ifdef __linux__
242     add_integer ("dvb-adapter", 0, ADAPTER_TEXT, ADAPTER_LONGTEXT, false)
243         change_integer_range (0, 255)
244     add_obsolete_integer ("dvb-device")
245     add_bool ("dvb-budget-mode", false, BUDGET_TEXT, BUDGET_LONGTEXT, true)
246 #endif
247 #ifdef WIN32
248     add_integer ("dvb-adapter", -1, ADAPTER_TEXT, ADAPTER_LONGTEXT, true)
249     add_string ("dvb-network-name", "", NAME_TEXT, NAME_LONGTEXT, true)
250     /* Hmm: is this one really safe??: */
251     add_string ("dvb-create-name", "", CREATE_TEXT, CREATE_LONGTEXT, true)
252         change_private ()
253 #endif
254     add_integer ("dvb-frequency", 0, FREQ_TEXT, FREQ_LONGTEXT, false)
255         change_integer_range (0, 107999999)
256         change_safe ()
257     add_integer ("dvb-inversion", -1, INVERSION_TEXT, INVERSION_LONGTEXT, true)
258         change_integer_list (auto_off_on_vlc, auto_off_on_user)
259         change_safe ()
260
261     set_section (N_("Terrestrial reception parameters"), NULL)
262     add_integer ("dvb-bandwidth", 0, BANDWIDTH_TEXT, BANDWIDTH_TEXT, true)
263         change_integer_list (bandwidth_vlc, bandwidth_user)
264         change_safe ()
265     add_integer ("dvb-transmission", 0,
266                  TRANSMISSION_TEXT, TRANSMISSION_TEXT, true)
267         change_integer_list (transmission_vlc, transmission_user)
268         change_safe ()
269     add_string ("dvb-guard", "", GUARD_TEXT, GUARD_TEXT, true)
270         change_string_list (guard_vlc, guard_user, NULL)
271         change_safe ()
272
273     set_section (N_("DVB-T reception parameters"), NULL)
274     add_string ("dvb-code-rate-hp", "",
275                 CODE_RATE_HP_TEXT, CODE_RATE_LONGTEXT, true)
276         change_string_list (code_rate_vlc, code_rate_user, NULL)
277         change_safe ()
278     add_string ("dvb-code-rate-lp", "",
279                 CODE_RATE_LP_TEXT, CODE_RATE_LONGTEXT, true)
280         change_string_list (code_rate_vlc, code_rate_user, NULL)
281         change_safe ()
282     add_integer ("dvb-hierarchy", -1, HIERARCHY_TEXT, HIERARCHY_TEXT, true)
283         change_integer_list (hierarchy_vlc, hierarchy_user)
284         change_safe ()
285
286     set_section (N_("ISDB-T reception parameters"), NULL)
287     add_string ("dvb-a-modulation", NULL,
288                 MODULATION_A_TEXT, MODULATION_LONGTEXT, true)
289         change_string_list (modulation_vlc, modulation_user, NULL)
290         change_safe ()
291     add_string ("dvb-a-fec", NULL, CODE_RATE_A_TEXT, CODE_RATE_LONGTEXT, true)
292         change_string_list (code_rate_vlc, code_rate_user, NULL)
293         change_safe ()
294     add_integer ("dvb-a-count", 0, SEGMENT_COUNT_A_TEXT, NULL, true)
295         change_integer_range (0, 13)
296         change_safe ()
297     add_integer ("dvb-a-interleaving", 0, TIME_INTERLEAVING_A_TEXT, NULL, true)
298         change_integer_range (0, 3)
299         change_safe ()
300     add_string ("dvb-b-modulation", NULL,
301                 MODULATION_B_TEXT, MODULATION_LONGTEXT, true)
302         change_string_list (modulation_vlc, modulation_user, NULL)
303         change_safe ()
304     add_string ("dvb-b-fec", NULL, CODE_RATE_B_TEXT, CODE_RATE_LONGTEXT, true)
305         change_string_list (code_rate_vlc, code_rate_user, NULL)
306         change_safe ()
307     add_integer ("dvb-b-count", 0, SEGMENT_COUNT_B_TEXT, NULL, true)
308         change_integer_range (0, 13)
309         change_safe ()
310     add_integer ("dvb-b-interleaving", 0, TIME_INTERLEAVING_B_TEXT, NULL, true)
311         change_integer_range (0, 3)
312         change_safe ()
313     add_string ("dvb-c-modulation", NULL,
314                 MODULATION_C_TEXT, MODULATION_LONGTEXT, true)
315         change_string_list (modulation_vlc, modulation_user, NULL)
316         change_safe ()
317     add_string ("dvb-c-fec", NULL, CODE_RATE_C_TEXT, CODE_RATE_LONGTEXT, true)
318         change_string_list (code_rate_vlc, code_rate_user, NULL)
319         change_safe ()
320     add_integer ("dvb-c-count", 0, SEGMENT_COUNT_C_TEXT, NULL, true)
321         change_integer_range (0, 13)
322         change_safe ()
323     add_integer ("dvb-c-interleaving", 0, TIME_INTERLEAVING_C_TEXT, NULL, true)
324         change_integer_range (0, 3)
325         change_safe ()
326
327     set_section (N_("Cable and satellite reception parameters"), NULL)
328     add_string ("dvb-modulation", NULL,
329                  MODULATION_TEXT, MODULATION_LONGTEXT, false)
330         change_string_list (modulation_vlc, modulation_user, NULL)
331         change_safe ()
332     add_integer ("dvb-srate", 0, SRATE_TEXT, SRATE_LONGTEXT, false)
333         change_integer_range (0, UINT64_C(0xffffffff))
334         change_safe ()
335     add_string ("dvb-fec", "", CODE_RATE_TEXT, CODE_RATE_LONGTEXT, true)
336         change_string_list (code_rate_vlc, code_rate_user, NULL)
337         change_safe ()
338
339     set_section (N_("DVB-S2 parameters"), NULL)
340     add_integer ("dvb-pilot", -1, PILOT_TEXT, PILOT_TEXT, true)
341         change_integer_list (auto_off_on_vlc, auto_off_on_user)
342         change_safe ()
343     add_integer ("dvb-rolloff", -1, ROLLOFF_TEXT, ROLLOFF_TEXT, true)
344         change_integer_list (rolloff_vlc, rolloff_user)
345         change_safe ()
346
347     set_section (N_("ISDB-S parameters"), NULL)
348     add_integer ("dvb-ts-id", 0, TS_ID_TEXT, TS_ID_TEXT, false)
349         change_integer_range (0, 0xffff)
350         change_safe ()
351
352     set_section (N_("Satellite equipment control"), NULL)
353     add_string ("dvb-polarization", "",
354                 POLARIZATION_TEXT, POLARIZATION_LONGTEXT, false)
355         change_string_list (polarization_vlc, polarization_user, NULL)
356         change_safe ()
357     add_integer ("dvb-voltage", 13, "", "", true)
358         change_integer_range (0, 18)
359         change_private ()
360         change_safe ()
361 #ifdef __linux__
362     add_bool ("dvb-high-voltage", false,
363               HIGH_VOLTAGE_TEXT, HIGH_VOLTAGE_LONGTEXT, false)
364 #endif
365     add_integer ("dvb-lnb-low", 0, LNB_LOW_TEXT, LNB_LONGTEXT, true)
366         change_integer_range (0, 0x7fffffff)
367     add_obsolete_integer ("dvb-lnb-lof1") /* since 1.2.0 */
368     add_integer ("dvb-lnb-high", 0, LNB_HIGH_TEXT, LNB_LONGTEXT, true)
369         change_integer_range (0, 0x7fffffff)
370     add_obsolete_integer ("dvb-lnb-lof2") /* since 1.2.0 */
371     add_integer ("dvb-lnb-switch", 11700000,
372                  LNB_SWITCH_TEXT, LNB_SWITCH_LONGTEXT, true)
373         change_integer_range (0, 0x7fffffff)
374     add_obsolete_integer ("dvb-lnb-slof") /* since 1.2.0 */
375 #ifdef __linux__
376     add_integer ("dvb-satno", 0, SATNO_TEXT, SATNO_LONGTEXT, true)
377         change_integer_list (satno_vlc, satno_user)
378     add_integer ("dvb-tone", -1, TONE_TEXT, TONE_LONGTEXT, true)
379         change_integer_list (auto_off_on_vlc, auto_off_on_user)
380 #endif
381 #ifdef WIN32
382     add_integer ("dvb-network-id", 0, NETID_TEXT, NETID_TEXT, true)
383     add_integer ("dvb-azimuth", 0, AZIMUTH_TEXT, AZIMUTH_LONGTEXT, true)
384     add_integer ("dvb-elevation", 0, ELEVATION_TEXT, ELEVATION_LONGTEXT, true)
385     add_integer ("dvb-longitude", 0, LONGITUDE_TEXT, LONGITUDE_LONGTEXT, true)
386     add_string ("dvb-range", "", RANGE_TEXT, RANGE_LONGTEXT, true)
387     /* dvb-range corresponds to the BDA InputRange parameter which is
388     * used by some drivers to control the diseqc */
389
390     set_section (N_("ATSC reception parameters"), NULL)
391     add_integer ("dvb-major-channel", 0, MAJOR_CHANNEL_TEXT, NULL, true)
392     add_integer ("dvb-minor-channel", 0, MINOR_CHANNEL_TEXT, NULL, true)
393     add_integer ("dvb-physical-channel", 0, PHYSICAL_CHANNEL_TEXT, NULL, true)
394 #endif
395 vlc_module_end ()
396
397 struct access_sys_t
398 {
399     dvb_device_t *dev;
400 };
401
402 typedef struct delsys
403 {
404     int (*setup) (vlc_object_t *, dvb_device_t *, uint64_t freq);
405     /* TODO: scan stuff */
406 } delsys_t;
407
408 static const delsys_t dvbc, dvbs, dvbs2, dvbt, dvbt2;
409 static const delsys_t isdbs, isdbt;
410 static const delsys_t atsc, cqam;
411
412 static block_t *Read (access_t *);
413 static int Control (access_t *, int, va_list);
414 static const delsys_t *GuessSystem (const char *, dvb_device_t *);
415 static int Tune (vlc_object_t *, dvb_device_t *, const delsys_t *, uint64_t);
416 static uint64_t var_InheritFrequency (vlc_object_t *);
417
418 static int Open (vlc_object_t *obj)
419 {
420     access_t *access = (access_t *)obj;
421     access_sys_t *sys = malloc (sizeof (*sys));
422     if (unlikely(sys == NULL))
423         return VLC_ENOMEM;
424
425     var_LocationParse (obj, access->psz_location, "dvb-");
426
427     dvb_device_t *dev = dvb_open (obj);
428     if (dev == NULL)
429     {
430         free (sys);
431         return VLC_EGENERIC;
432     }
433
434     sys->dev = dev;
435     access->p_sys = sys;
436
437     uint64_t freq = var_InheritFrequency (obj);
438     if (freq != 0)
439     {
440         const delsys_t *delsys = GuessSystem (access->psz_access, dev);
441         if (delsys == NULL || Tune (obj, dev, delsys, freq))
442         {
443             msg_Err (obj, "tuning to %"PRIu64" Hz failed", freq);
444             dialog_Fatal (obj, N_("Digital broadcasting"),
445                           N_("The selected digital tuner does not support "
446                              "the specified parameters.\n"
447                              "Please check the preferences."));
448             goto error;
449         }
450     }
451     dvb_add_pid (dev, 0);
452
453     access->pf_block = Read;
454     access->pf_control = Control;
455     if (access->psz_demux == NULL || !access->psz_demux[0])
456     {
457         free (access->psz_demux);
458         access->psz_demux = strdup ("ts");
459     }
460     return VLC_SUCCESS;
461
462 error:
463     Close (obj);
464     access->p_sys = NULL;
465     return VLC_EGENERIC;
466 }
467
468 static void Close (vlc_object_t *obj)
469 {
470     access_t *access = (access_t *)obj;
471     access_sys_t *sys = access->p_sys;
472
473     dvb_close (sys->dev);
474     free (sys);
475 }
476
477 static block_t *Read (access_t *access)
478 {
479 #define BUFSIZE (20*188)
480     block_t *block = block_Alloc (BUFSIZE);
481     if (unlikely(block == NULL))
482         return NULL;
483
484     access_sys_t *sys = access->p_sys;
485     ssize_t val = dvb_read (sys->dev, block->p_buffer, BUFSIZE);
486
487     if (val <= 0)
488     {
489         if (val == 0)
490             access->info.b_eof = true;
491         block_Release (block);
492         return NULL;
493     }
494
495     block->i_buffer = val;
496     return block;
497 }
498
499 static int Control (access_t *access, int query, va_list args)
500 {
501     access_sys_t *sys = access->p_sys;
502     dvb_device_t *dev = sys->dev;
503
504     switch (query)
505     {
506         case ACCESS_CAN_SEEK:
507         case ACCESS_CAN_FASTSEEK:
508         case ACCESS_CAN_PAUSE:
509         case ACCESS_CAN_CONTROL_PACE:
510         {
511             bool *v = va_arg (args, bool *);
512             *v = false;
513             return VLC_SUCCESS;
514         }
515
516         case ACCESS_GET_PTS_DELAY:
517         {
518             int64_t *v = va_arg (args, int64_t *);
519             *v = var_InheritInteger (access, "live-caching") * INT64_C(1000);
520             return VLC_SUCCESS;
521         }
522
523         case ACCESS_GET_TITLE_INFO:
524         case ACCESS_GET_META:
525             return VLC_EGENERIC;
526
527         case ACCESS_GET_CONTENT_TYPE:
528         {
529             char **pt = va_arg (args, char **);
530             *pt = strdup ("video/MP2T");
531             return VLC_SUCCESS;
532         }
533
534         case ACCESS_SET_PAUSE_STATE:
535         case ACCESS_SET_TITLE:
536         case ACCESS_SET_SEEKPOINT:
537             return VLC_EGENERIC;
538
539         case ACCESS_GET_SIGNAL:
540             *va_arg (args, double *) = dvb_get_snr (dev);
541             *va_arg (args, double *) = dvb_get_signal_strength (dev);
542             return VLC_SUCCESS;
543
544         case ACCESS_SET_PRIVATE_ID_STATE:
545         {
546             unsigned pid = va_arg (args, unsigned);
547             bool add = va_arg (args, unsigned);
548
549             if (unlikely(pid > 0x1FFF))
550                 return VLC_EGENERIC;
551             if (add)
552             {
553                 if (dvb_add_pid (dev, pid))
554                     return VLC_EGENERIC;
555             }
556             else
557                 dvb_remove_pid (dev, pid);
558             return VLC_SUCCESS;
559         }
560
561         case ACCESS_SET_PRIVATE_ID_CA:
562 #ifdef HAVE_DVBPSI
563         {
564             struct dvbpsi_pmt_s *pmt = va_arg (args, struct dvbpsi_pmt_s *);
565
566             dvb_set_ca_pmt (dev, pmt);
567             return VLC_SUCCESS;
568         }
569 #endif
570
571         case ACCESS_GET_PRIVATE_ID_STATE:
572             return VLC_EGENERIC;
573     }
574
575     msg_Warn (access, "unimplemented query %d in control", query);
576     return VLC_EGENERIC;
577 }
578
579
580 /*** Generic tuning ***/
581
582 /** Determines which delivery system to use. */
583 static const delsys_t *GuessSystem (const char *scheme, dvb_device_t *dev)
584 {
585     /* NOTE: We should guess the delivery system for the "cable", "satellite"
586      * and "terrestrial" shortcuts (i.e. DVB, ISDB, ATSC...). But there is
587      * seemingly no sane way to do get the info with Linux DVB version 5.2.
588      * In particular, the frontend infos distinguish only the modulator class
589      * (QPSK, QAM, OFDM or ATSC).
590      *
591      * Furthermore, if the demodulator supports 2G, we cannot guess whether
592      * 1G or 2G is intended. For backward compatibility, 1G is assumed
593      * (this is not a limitation of Linux DVB). We will probably need something
594      * smarter when 2G (semi automatic) scanning is implemented. */
595     if (!strcasecmp (scheme, "cable"))
596         scheme = "dvb-c";
597     else
598     if (!strcasecmp (scheme, "satellite"))
599         scheme = "dvb-s";
600     else
601     if (!strcasecmp (scheme, "terrestrial"))
602         scheme = "dvb-t";
603
604     if (!strcasecmp (scheme, "atsc"))
605         return &atsc;
606     if (!strcasecmp (scheme, "cqam"))
607         return &cqam;
608     if (!strcasecmp (scheme, "dvb-c"))
609         return &dvbc;
610     if (!strcasecmp (scheme, "dvb-s"))
611         return &dvbs;
612     if (!strcasecmp (scheme, "dvb-s2"))
613         return &dvbs2;
614     if (!strcasecmp (scheme, "dvb-t"))
615         return &dvbt;
616     if (!strcasecmp (scheme, "dvb-t2"))
617         return &dvbt2;
618     if (!strcasecmp (scheme, "isdb-s"))
619         return &isdbs;
620     if (!strcasecmp (scheme, "isdb-t"))
621         return &isdbt;
622
623     unsigned systems = dvb_enum_systems (dev);
624     if (systems & ATSC)
625         return &atsc;
626     if (systems & DVB_C)
627         return &dvbc;
628     if (systems & DVB_S)
629         return &dvbc;
630     if (systems & DVB_T)
631         return &dvbt;
632     return NULL;
633 }
634
635 /** Set parameters and tune the device */
636 static int Tune (vlc_object_t *obj, dvb_device_t *dev, const delsys_t *delsys,
637                  uint64_t freq)
638 {
639     if (delsys->setup (obj, dev, freq)
640      || dvb_set_inversion (dev, var_InheritInteger (obj, "dvb-inversion"))
641      || dvb_tune (dev))
642         return VLC_EGENERIC;
643     return VLC_SUCCESS;
644 }
645
646 static uint64_t var_InheritFrequency (vlc_object_t *obj)
647 {
648     uint64_t freq = var_InheritInteger (obj, "dvb-frequency");
649     if (freq != 0 && freq <= 108000000)
650     {
651         msg_Err (obj, "%"PRIu64" Hz carrier frequency is too low.", freq);
652         freq *= 1000;
653         msg_Info (obj, "Assuming %"PRIu64" Hz frequency instead.", freq);
654     }
655     return freq;
656 }
657
658 static uint32_t var_InheritCodeRate (vlc_object_t *obj, const char *varname)
659 {
660     char *code_rate = var_InheritString (obj, varname);
661     if (code_rate == NULL)
662         return VLC_FEC_AUTO;
663
664     uint16_t a, b;
665     int v = sscanf (code_rate, "%"SCNu16"/%"SCNu16, &a, &b);
666     free (code_rate);
667     switch (v)
668     {
669         case 2:
670             return VLC_FEC(a, b);
671         case 1:
672             if (a == 0)
673                 return 0;
674             /* Backward compatibility with VLC < 1.2 (= Linux DVBv3 enum) */
675             if (a < 9)
676             {
677                 msg_Warn (obj, "\"%s=%"PRIu16"\" option is obsolete. "
678                           "Use \"%s=%"PRIu16"/%"PRIu16"\" instead.",
679                           varname + 4, a, varname + 4, a, a + 1);
680                 return VLC_FEC(a, a + 1);
681             }
682             else
683                 msg_Warn (obj, "\"fec=9\" option is obsolete.");
684     }
685     return VLC_FEC_AUTO;
686 }
687
688 static int modcmp (const void *a, const void *b)
689 {
690     return strcasecmp (a, *(const char *const *)b);
691 }
692
693 static const char *var_InheritModulation (vlc_object_t *obj, const char *var)
694 {
695     char *mod = var_InheritString (obj, var);
696     if (mod == NULL)
697         return "";
698
699     size_t n = sizeof (modulation_vlc) / sizeof (modulation_vlc[0]);
700     const char *const *p = lfind (mod, modulation_vlc, &n, sizeof (mod), modcmp);
701     if (p != NULL)
702     {
703         free (mod);
704         return *p;
705     }
706
707     /* Backward compatibility with VLC < 1.2 */
708     const char *str;
709     switch (atoi (mod))
710     {
711         case -1:  str = "QPSK";   break;
712         case 0:   str = "QAM";    break;
713         case 8:   str = "8VSB";   break;
714         case 16:  str = "16QAM";  break;
715         case 32:  str = "32QAM";  break;
716         case 64:  str = "64QAM";  break;
717         case 128: str = "128QAM"; break;
718         case 256: str = "256QAM"; break;
719         default:  return "";
720     }
721
722     msg_Warn (obj, "\"modulation=%s\" option is obsolete. "
723                    "Use \"modulation=%s\" instead.", mod, str);
724     free (mod);
725     return str;
726 }
727
728 static unsigned var_InheritGuardInterval (vlc_object_t *obj)
729 {
730     char *guard = var_InheritString (obj, "dvb-guard");
731     if (guard == NULL)
732         return VLC_GUARD_AUTO;
733
734     uint16_t a, b;
735     int v = sscanf (guard, "%"SCNu16"/%"SCNu16, &a, &b);
736     free (guard);
737     switch (v)
738     {
739         case 1:
740             /* Backward compatibility with VLC < 1.2 */
741             if (a == 0)
742                 break;
743             msg_Warn (obj, "\"guard=%"PRIu16"\" option is obsolete. "
744                            "Use \"guard=1/%"PRIu16" instead.", a, a);
745             b = a;
746             a = 1;
747         case 2:
748             return VLC_GUARD(a, b);
749     }
750     return VLC_GUARD_AUTO;
751 }
752
753
754 /*** ATSC ***/
755 static int atsc_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
756 {
757     const char *mod = var_InheritModulation (obj, "dvb-modulation");
758
759     return dvb_set_atsc (dev, freq, mod);
760 }
761
762 static const delsys_t atsc = { .setup = atsc_setup };
763
764 static int cqam_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
765 {
766     const char *mod = var_InheritModulation (obj, "dvb-modulation");
767
768     return dvb_set_cqam (dev, freq, mod);
769 }
770
771 static const delsys_t cqam = { .setup = cqam_setup };
772
773
774 /*** DVB-C ***/
775 static int dvbc_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
776 {
777     const char *mod = var_InheritModulation (obj, "dvb-modulation");
778     uint32_t fec = var_InheritCodeRate (obj, "dvb-fec");
779     unsigned srate = var_InheritInteger (obj, "dvb-srate");
780
781     return dvb_set_dvbc (dev, freq, mod, srate, fec);
782 }
783
784 static const delsys_t dvbc = { .setup = dvbc_setup };
785
786
787 /*** DVB-S ***/
788 static char var_InheritPolarization (vlc_object_t *obj)
789 {
790     char pol;
791     char *polstr = var_InheritString (obj, "dvb-polarization");
792     if (polstr != NULL)
793     {
794         pol = *polstr;
795         free (polstr);
796         if (unlikely(pol >= 'a' && pol <= 'z'))
797             pol -= 'a' - 'A';
798         return pol;
799     }
800
801     /* Backward compatibility with VLC for Linux < 1.2 */
802     unsigned voltage = var_InheritInteger (obj, "dvb-voltage");
803     switch (voltage)
804     {
805         case 13:  pol = 'V'; break;
806         case 18:  pol = 'H'; break;
807         default:  return 0;
808     }
809
810     msg_Warn (obj, "\"voltage=%u\" option is obsolete. "
811                    "Use \"polarization=%c\" instead.", voltage, pol);
812     return pol;
813 }
814
815 static int sec_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
816 {
817     char pol = var_InheritPolarization (obj);
818     unsigned lowf = var_InheritInteger (obj, "dvb-lnb-low");
819     unsigned highf = var_InheritInteger (obj, "dvb-lnb-high");
820     unsigned switchf = var_InheritInteger (obj, "dvb-lnb-switch");
821
822     return dvb_set_sec (dev, freq, pol, lowf, highf, switchf);
823 }
824
825 static int dvbs_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
826 {
827     uint32_t fec = var_InheritCodeRate (obj, "dvb-fec");
828     uint32_t srate = var_InheritInteger (obj, "dvb-srate");
829
830     int ret = dvb_set_dvbs (dev, freq, srate, fec);
831     if (ret == 0)
832         ret = sec_setup (obj, dev, freq);
833     return ret;
834 }
835
836 static int dvbs2_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
837 {
838     const char *mod = var_InheritModulation (obj, "dvb-modulation");
839     uint32_t fec = var_InheritCodeRate (obj, "dvb-fec");
840     uint32_t srate = var_InheritInteger (obj, "dvb-srate");
841     int pilot = var_InheritInteger (obj, "dvb-pilot");
842     int rolloff = var_InheritInteger (obj, "dvb-rolloff");
843
844     int ret = dvb_set_dvbs2 (dev, freq, mod, srate, fec, pilot, rolloff);
845     if (ret == 0)
846         ret = sec_setup (obj, dev, freq);
847     return ret;
848 }
849
850 static const delsys_t dvbs = { .setup = dvbs_setup };
851 static const delsys_t dvbs2 = { .setup = dvbs2_setup };
852
853
854 /*** DVB-T ***/
855 static int dvbt_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
856 {
857     const char *mod = var_InheritModulation (obj, "dvb-modulation");
858     uint32_t fec_hp = var_InheritCodeRate (obj, "dvb-code-rate-hp");
859     uint32_t fec_lp = var_InheritCodeRate (obj, "dvb-code-rate-lp");
860     uint32_t guard = var_InheritGuardInterval (obj);
861     uint32_t bw = var_InheritInteger (obj, "dvb-bandwidth");
862     int tx = var_InheritInteger (obj, "dvb-transmission");
863     int h = var_InheritInteger (obj, "dvb-hierarchy");
864
865     return dvb_set_dvbt (dev, freq, mod, fec_hp, fec_lp, bw, tx, guard, h);
866 }
867
868 static int dvbt2_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
869 {
870     const char *mod = var_InheritModulation (obj, "dvb-modulation");
871     uint32_t fec = var_InheritCodeRate (obj, "dvb-fec");
872     uint32_t guard = var_InheritGuardInterval (obj);
873     uint32_t bw = var_InheritInteger (obj, "dvb-bandwidth");
874     int tx = var_InheritInteger (obj, "dvb-transmission");
875
876     return dvb_set_dvbt2 (dev, freq, mod, fec, bw, tx, guard);
877 }
878
879 static const delsys_t dvbt = { .setup = dvbt_setup };
880 static const delsys_t dvbt2 = { .setup = dvbt2_setup };
881
882
883 /*** ISDB-S ***/
884 static int isdbs_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
885 {
886     uint16_t ts_id = var_InheritInteger (obj, "dvb-ts-id");
887
888     int ret = dvb_set_isdbs (dev, freq, ts_id);
889     if (ret == 0)
890         ret = sec_setup (obj, dev, freq);
891     return ret;
892 }
893
894 static const delsys_t isdbs = { .setup = isdbs_setup };
895
896
897 /*** ISDB-T ***/
898 static int isdbt_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
899 {
900     isdbt_layer_t layers[3];
901     uint32_t guard = var_InheritGuardInterval (obj);
902     uint32_t bw = var_InheritInteger (obj, "dvb-bandwidth");
903     int tx = var_InheritInteger (obj, "dvb-transmission");
904
905     for (unsigned i = 0; i < 3; i++)
906     {
907         char varname[sizeof ("dvb-X-interleaving")];
908         memcpy (varname, "dvb-X-", 4);
909         varname[4] = 'a' + i;
910
911         strcpy (varname + 6, "modulation");
912         layers[i].modulation = var_InheritModulation (obj, varname);
913         strcpy (varname + 6, "fec");
914         layers[i].code_rate = var_InheritCodeRate (obj, varname);
915         strcpy (varname + 6, "count");
916         layers[i].segment_count = var_InheritInteger (obj, varname);
917         strcpy (varname + 6, "interleaving");
918         layers[i].time_interleaving = var_InheritInteger (obj, varname);
919     }
920
921     return dvb_set_isdbt (dev, freq, bw, tx, guard, layers);
922 }
923
924 static const delsys_t isdbt = { .setup = isdbt_setup };