3 * @brief Digital broadcasting input module for VLC media player
5 /*****************************************************************************
6 * Copyright © 2011 Rémi Denis-Courmont
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
13 * This library 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 General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 ****************************************************************************/
27 #include <vlc_common.h>
28 #include <vlc_access.h>
29 #include <vlc_plugin.h>
30 #include <vlc_dialog.h>
34 #define CACHING_TEXT N_("Caching value (ms)")
35 #define CACHING_LONGTEXT N_( \
36 "The cache size (delay) for digital broadcasts (in milliseconds).")
38 #define ADAPTER_TEXT N_("DVB adapter")
39 #define ADAPTER_LONGTEXT N_( \
40 "If there is more than one digital broadcasting adapter, " \
41 "the adapter number must be selected. Numbering start from zero.")
43 #define DEVICE_TEXT N_("DVB device")
44 #define DEVICE_LONGTEXT N_( \
45 "If the selected adapter has more than one tuner, " \
46 "the tuner number must be selected. Numbering start from zero.")
48 #define BUDGET_TEXT N_("Do not demultiplex")
49 #define BUDGET_LONGTEXT N_( \
50 "Only useful programs are normally demultiplexed from the transponder. " \
51 "This option will disable demultiplexing and receive all programs.")
53 #define FREQ_TEXT N_("Frequency (kHz)")
54 #define FREQ_LONGTEXT N_( \
55 "TV channels are grouped by transponder (a.k.a. multiplex) " \
56 "on a given frequency. This is required to tune the receiver.")
58 #define MODULATION_TEXT N_("Modulation / Constellation")
59 #define MODULATION_LONGTEXT N_( \
60 "The digital signal can be modulated according with different " \
61 "constellations (depending on the delivery system). " \
62 "If the demodulator cannot detect the constellation automatically, " \
63 "it needs to be configured manually.")
64 static const char *const modulation_vlc[] = { "",
65 "QAM", "16QAM", "32QAM", "64QAM", "128QAM", "256QAM",
67 "QPSK", "DQPSK", "8PSK", "16APSK", "32APSK",
69 static const char *const modulation_user[] = { N_("Undefined"),
70 "Auto QAM", "16-QAM", "32-QAM", "64-QAM", "128-QAM", "256-QAM",
72 "QPSK", "DQPSK", "8-PSK", "16-APSK", "32-APSK",
75 #define SRATE_TEXT N_("Symbol rate (bauds)")
76 #define SRATE_LONGTEXT N_( \
77 "The symbol rate must be specified manually for some systems, " \
78 "notably DVB-C, DVB-S and DVB-S2.")
80 #define INVERSION_TEXT N_("Spectrum inversion")
81 #define INVERSION_LONGTEXT N_( \
82 "If the demodulator cannot detect spectral inversion correctly, " \
83 "it needs to be configured manually.")
84 const int auto_off_on_vlc[] = { -1, 0, 1 };
85 static const char *const auto_off_on_user[] = { N_("Automatic"),
86 N_("Off"), N_("On") };
88 #define CODE_RATE_TEXT N_("FEC code rate")
89 #define CODE_RATE_HP_TEXT N_("High-priority code rate")
90 #define CODE_RATE_LP_TEXT N_("Low-priority code rate")
91 #define CODE_RATE_LONGTEXT N_( \
92 "The code rate for Forward Error Correction can be specified.")
93 static const char *const code_rate_vlc[] = { "",
94 "none", /*"1/4", "1/3",*/ "1/2", "3/5", "2/3", "3/4",
95 "4/5", "5/6", "6/7", "7/8", "8/9", "9/10",
97 static const char *const code_rate_user[] = { N_("Automatic"),
98 N_("None"), /*"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",
102 #define TRANSMISSION_TEXT N_("Transmission mode")
103 const int transmission_vlc[] = { -1,
106 static const char *const transmission_user[] = { N_("Automatic"),
107 "2k", "4k", "8k", /*"16k", "32k", */
110 #define BANDWIDTH_TEXT N_("Bandwidth (MHz)")
111 const int bandwidth_vlc[] = { 0,
114 static const char *const bandwidth_user[] = { N_("Automatic"),
115 N_("8 MHz"), N_("7 MHz"), N_("6 MHz"),
118 #define GUARD_TEXT N_("Guard interval")
119 const char *const guard_vlc[] = { "",
120 /*"1/128",*/ "1/32", "1/16", /*"19/128",*/ "1/8", /*"9/256",*/ "1/4",
122 static const char *const guard_user[] = { N_("Automatic"),
123 /*"1/128",*/ "1/32", "1/16", /*"19/128",*/ "1/8", /*"9/256",*/ "1/4",
126 #define HIERARCHY_TEXT N_("Hierarchy mode")
127 const int hierarchy_vlc[] = { -1,
130 static const char *const hierarchy_user[] = { N_("Automatic"),
131 N_("None"), "1", "2", "4",
134 #define PILOT_TEXT N_("Pilot")
135 #define ROLLOFF_TEXT N_("Roll-off factor")
136 const int rolloff_vlc[] = { -1,
139 static const char *const rolloff_user[] = { N_("Automatic"),
140 N_("0.35 (same as DVB-S)"), N_("0.20"), N_("0.25"),
143 #define POLARIZATION_TEXT N_("Polarization (Voltage)")
144 #define POLARIZATION_LONGTEXT N_( \
145 "To select the polarization of the transponder, a different voltage " \
146 "is normally applied to the low noise block-downconverter (LNB).")
147 static const char *const polarization_vlc[] = { "", "V", "H", "R", "L" };
148 static const char *const polarization_user[] = { N_("Unspecified (0V)"),
149 N_("Vertical (13V)"), N_("Horizontal (18V)"),
150 N_("Circular Right Hand (13V)"), N_("Circular Left Hand (18V)") };
152 #define HIGH_VOLTAGE_TEXT N_("High LNB voltage")
153 #define HIGH_VOLTAGE_LONGTEXT N_( \
154 "If the cables between the satellilte low noise block-downconverter and " \
155 "the receiver are long, higher voltage may be required.\n" \
156 "Not all receivers support this.")
158 static int Open (vlc_object_t *);
159 static void Close (vlc_object_t *);
162 set_shortname (N_("DTV"))
163 set_description (N_("Digital Television and Radio (Linux DVB)"))
164 set_category (CAT_INPUT)
165 set_subcategory (SUBCAT_INPUT_ACCESS)
166 set_capability ("access", 0)
167 set_callbacks (Open, Close)
168 add_shortcut ("dtv", "tv", "dvb", /* "radio", "dab",*/
169 "cable", "dvb-c", /*"satellite", "dvb-s", "dvb-s2",*/
170 "terrestrial", "dvb-t", "atsc")
172 /* All options starting with dvb- can be overriden in the MRL, so they
173 * must all be "safe". Nevertheless, we do not mark as safe those that are
174 * really specific to the local system (e.g. device ID...).
175 * It wouldn't make sense to deliver those through a playlist. */
177 add_integer ("dvb-caching", DEFAULT_PTS_DELAY / 1000,
178 CACHING_TEXT, CACHING_LONGTEXT, true)
179 change_integer_range (0, 60000)
182 add_integer ("dvb-adapter", 0, ADAPTER_TEXT, ADAPTER_LONGTEXT, false)
183 change_integer_range (0, 255)
184 add_integer ("dvb-device", 0, DEVICE_TEXT, DEVICE_LONGTEXT, false)
185 change_integer_range (0, 255)
186 add_bool ("dvb-budget-mode", false, BUDGET_TEXT, BUDGET_LONGTEXT, true)
188 add_integer ("dvb-frequency", 0, FREQ_TEXT, FREQ_LONGTEXT, false)
189 change_integer_range (0, 107999999)
191 add_integer ("dvb-inversion", -1, INVERSION_TEXT, INVERSION_LONGTEXT, true)
192 change_integer_list (auto_off_on_vlc, auto_off_on_user)
195 set_section (N_("Terrestrial reception parameters"), NULL)
196 add_integer ("dvb-bandwidth", -1, BANDWIDTH_TEXT, BANDWIDTH_TEXT, true)
197 change_integer_list (bandwidth_vlc, bandwidth_user)
199 add_string ("dvb-code-rate-hp", "",
200 CODE_RATE_HP_TEXT, CODE_RATE_LONGTEXT, false)
201 change_string_list (code_rate_vlc, code_rate_user, NULL)
203 add_string ("dvb-code-rate-lp", "",
204 CODE_RATE_LP_TEXT, CODE_RATE_LONGTEXT, false)
205 change_string_list (code_rate_vlc, code_rate_user, NULL)
207 add_integer ("dvb-transmission", 0,
208 TRANSMISSION_TEXT, TRANSMISSION_TEXT, true)
209 change_integer_list (transmission_vlc, transmission_user)
211 add_string ("dvb-guard", "", GUARD_TEXT, GUARD_TEXT, true)
212 change_string_list (guard_vlc, guard_user, NULL)
214 add_integer ("dvb-hierarchy", -1, HIERARCHY_TEXT, HIERARCHY_TEXT, true)
215 change_integer_list (hierarchy_vlc, hierarchy_user)
218 set_section (N_("Cable and satellite reception parameters"), NULL)
219 add_string ("dvb-modulation", 0,
220 MODULATION_TEXT, MODULATION_LONGTEXT, false)
221 change_string_list (modulation_vlc, modulation_user, NULL)
223 add_integer ("dvb-srate", 0, SRATE_TEXT, SRATE_LONGTEXT, false)
224 change_integer_range (0, UINT64_C(0xffffffff))
226 add_string ("dvb-code-rate", "", CODE_RATE_TEXT, CODE_RATE_LONGTEXT, true)
227 change_string_list (code_rate_vlc, code_rate_user, NULL)
229 add_integer ("dvb-fec", 9, " ", " ", true)
230 change_integer_range (0, 9)
233 set_section (N_("DVB-S2 parameters"), NULL)
234 add_integer ("dvb-pilot", -1, PILOT_TEXT, PILOT_TEXT, true)
235 change_integer_list (auto_off_on_vlc, auto_off_on_user)
237 add_integer ("dvb-rolloff", -1, ROLLOFF_TEXT, ROLLOFF_TEXT, true)
238 change_integer_list (rolloff_vlc, rolloff_user)
240 set_section (N_("Satellite equipment control"), NULL)
241 add_string ("dvb-polarization", "",
242 POLARIZATION_TEXT, POLARIZATION_LONGTEXT, false)
243 change_string_list (polarization_vlc, polarization_user, NULL)
245 add_integer ("dvb-voltage", 13, " ", " ", true)
246 change_integer_range (0, 18)
250 add_bool ("dvb-high-voltage", false,
251 HIGH_VOLTAGE_TEXT, HIGH_VOLTAGE_LONGTEXT, false)
254 add_integer ("dvb-tone", -1, TONE_TEXT, TONE_LONGTEXT, true)
255 change_integer_list (tone_vlc, auto_off_on)
257 add_integer ("dvb-lnb-lof1", 0, LNB_LOF1_TEXT, LNB_LOF1_LONGTEXT, true)
258 change_integer_range (0, 0x7fffffff)
260 add_integer ("dvb-lnb-lof2", 0, LNB_LOF2_TEXT, LNB_LOF2_LONGTEXT, true)
261 change_integer_range (0, 0x7fffffff)
263 add_integer ("dvb-lnb-slof", 0, LNB_SLOF_TEXT, LNB_SLOF_LONGTEXT, true)
264 change_integer_range (0, 0x7fffffff)
266 add_integer ("dvb-satno", 0, SATNO_TEXT, SATNO_LONGTEXT, true)
267 change_integer_list (satno_vlc, satno_user)
279 int (*setup) (vlc_object_t *, dvb_device_t *, unsigned freq);
280 /* TODO: scan stuff */
283 static block_t *Read (access_t *);
284 static int Control (access_t *, int, va_list);
285 static const delsys_t *GuessSystem (const char *, dvb_device_t *);
286 static int Tune (vlc_object_t *, dvb_device_t *, const delsys_t *, unsigned);
287 static unsigned var_InheritFrequency (vlc_object_t *);
289 static int Open (vlc_object_t *obj)
291 access_t *access = (access_t *)obj;
292 access_sys_t *sys = malloc (sizeof (*sys));
293 if (unlikely(sys == NULL))
296 var_LocationParse (obj, access->psz_location, "dvb-");
297 unsigned freq = var_InheritFrequency (obj);
299 dvb_device_t *dev = dvb_open (obj, freq != 0);
311 const delsys_t *delsys = GuessSystem (access->psz_access, dev);
312 if (delsys == NULL || Tune (obj, dev, delsys, freq))
314 msg_Err (obj, "tuning to %u kHz failed", freq);
315 dialog_Fatal (obj, N_("Digital broadcasting"),
316 N_("The selected digital tuner does not support "
317 "the specified parameters.\n"
318 "Please check the preferences."));
322 dvb_add_pid (dev, 0);
324 access->pf_block = Read;
325 access->pf_control = Control;
326 if (access->psz_demux == NULL || !access->psz_demux[0])
328 free (access->psz_demux);
329 access->psz_demux = strdup ("ts");
335 access->p_sys = NULL;
339 static void Close (vlc_object_t *obj)
341 access_t *access = (access_t *)obj;
342 access_sys_t *sys = access->p_sys;
344 dvb_close (sys->dev);
348 static block_t *Read (access_t *access)
350 #define BUFSIZE (20*188)
351 block_t *block = block_Alloc (BUFSIZE);
352 if (unlikely(block == NULL))
355 access_sys_t *sys = access->p_sys;
356 ssize_t val = dvb_read (sys->dev, block->p_buffer, BUFSIZE);
361 access->info.b_eof = true;
362 block_Release (block);
366 block->i_buffer = val;
370 static int Control (access_t *access, int query, va_list args)
372 access_sys_t *sys = access->p_sys;
373 dvb_device_t *dev = sys->dev;
377 case ACCESS_CAN_SEEK:
378 case ACCESS_CAN_FASTSEEK:
379 case ACCESS_CAN_PAUSE:
380 case ACCESS_CAN_CONTROL_PACE:
382 bool *v = va_arg (args, bool *);
387 case ACCESS_GET_PTS_DELAY:
389 int64_t *v = va_arg (args, int64_t *);
390 *v = var_InheritInteger (access, "dvb-caching") * INT64_C(1000);
394 case ACCESS_GET_TITLE_INFO:
395 case ACCESS_GET_META:
398 case ACCESS_GET_CONTENT_TYPE:
400 char **pt = va_arg (args, char **);
401 *pt = strdup ("video/MP2T");
405 case ACCESS_SET_PAUSE_STATE:
406 case ACCESS_SET_TITLE:
407 case ACCESS_SET_SEEKPOINT:
410 case ACCESS_GET_SIGNAL:
411 *va_arg (args, double *) = dvb_get_snr (dev);
412 *va_arg (args, double *) = dvb_get_signal_strength (dev);
415 case ACCESS_SET_PRIVATE_ID_STATE:
417 unsigned pid = va_arg (args, unsigned);
418 bool add = va_arg (args, unsigned);
420 if (unlikely(pid > 0x1FFF))
424 if (dvb_add_pid (dev, pid))
428 dvb_remove_pid (dev, pid);
432 case ACCESS_SET_PRIVATE_ID_CA:
436 case ACCESS_GET_PRIVATE_ID_STATE:
440 msg_Warn (access, "unimplemented query %d in control", query);
445 /*** Generic tuning ***/
447 /** Determines which delivery system to use. */
448 static const delsys_t *GuessSystem (const char *scheme, dvb_device_t *dev)
450 /* NOTE: We should guess the delivery system for the "cable", "satellite"
451 * and "terrestrial" shortcuts (i.e. DVB, ISDB, ATSC...). But there is
452 * seemingly no sane way to do get the info with Linux DVB version 5.2.
453 * In particular, the frontend infos distinguish only the modulator class
454 * (QPSK, QAM, OFDM or ATSC).
456 * Furthermore, if the demodulator supports 2G, we cannot guess whether
457 * 1G or 2G is intended. For backward compatibility, 1G is assumed
458 * (this is not a limitation of Linux DVB). We will probably need something
459 * smarter when 2G (semi automatic) scanning is implemented. */
460 if (!strcasecmp (scheme, "cable"))
463 if (!strcasecmp (scheme, "satellite"))
466 if (!strcasecmp (scheme, "terrestrial"))
469 if (!strcasecmp (scheme, "atsc"))
471 if (!strcasecmp (scheme, "dvb-c"))
473 if (!strcasecmp (scheme, "dvb-s"))
475 if (!strcasecmp (scheme, "dvb-s2"))
477 if (!strcasecmp (scheme, "dvb-t"))
480 return dvb_guess_system (dev);
483 /** Set parameters and tune the device */
484 static int Tune (vlc_object_t *obj, dvb_device_t *dev, const delsys_t *delsys,
487 if (delsys->setup (obj, dev, freq)
488 || dvb_set_inversion (dev, var_InheritInteger (obj, "dvb-inversion"))
494 static unsigned var_InheritFrequency (vlc_object_t *obj)
496 unsigned freq = var_InheritInteger (obj, "dvb-frequency");
497 if (freq >= 108000000)
499 msg_Err (obj, "%u kHz frequency is too high.", freq);
501 msg_Info (obj, "Assuming %u kHz carrier frequency instead.", freq);
506 static char *var_InheritCodeRate (vlc_object_t *obj)
508 char *code_rate = var_InheritString (obj, "dvb-code-rate");
509 if (code_rate != NULL)
512 /* Backward compatibility with VLC < 1.2 (= Linux DVBv3 enum) */
513 unsigned fec = var_InheritInteger (obj, "dvb-fec");
516 static const char linux_dvb[9][5] = {
517 "none", "1/2", "2/3", "3/4", "4/5", "5/6", "6/7", "7/8" };
518 msg_Warn (obj, "\"fec=%u\" option is obsolete. "
519 "Use \"code-rate=%s\" instead.", fec, linux_dvb[fec]);
520 return strdup (linux_dvb[fec]);
525 static char *var_InheritModulation (vlc_object_t *obj)
527 char *mod = var_InheritString (obj, "dvb-modulation");
532 unsigned long l = strtol (mod, &end, 0);
533 if (*end != '\0') /* not a number = not from VLC < 1.2 */
536 /* Backward compatibility with VLC < 1.2 */
540 case -1: str = "QPSK"; break;
541 case 0: str = "QAM"; break;
542 case 8: str = "8VSB"; break;
543 case 16: str = "16QAM"; break;
544 case 32: str = "32QAM"; break;
545 case 64: str = "64QAM"; break;
546 case 128: str = "128QAM"; break;
547 case 256: str = "256QAM"; break;
551 msg_Warn (obj, "\"modulation=%ld\" option is obsolete. "
552 "Use \"modulation=%s\" instead.", l, str);
558 static int atsc_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
560 char *mod = var_InheritModulation (obj);
562 int ret = dvb_set_atsc (dev, freq, mod);
567 const delsys_t atsc = { .setup = atsc_setup };
571 static int dvbc_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
573 char *mod = var_InheritModulation (obj);
574 char *fec = var_InheritCodeRate (obj);
575 unsigned srate = var_InheritInteger (obj, "dvb-srate");
577 int ret = dvb_set_dvbc (dev, freq, mod, srate, fec);
583 const delsys_t dvbc = { .setup = dvbc_setup };
587 static char var_InheritPolarization (vlc_object_t *obj)
590 char *polstr = var_InheritString (obj, "dvb-polarization");
595 if (unlikely(pol >= 'a' && pol <= 'z'))
600 /* Backward compatibility with VLC for Linux < 1.2 */
601 unsigned voltage = var_InheritInteger (obj, "dvb-voltage");
604 case 13: pol = 'V'; break;
605 case 18: pol = 'H'; break;
609 msg_Warn (obj, "\"voltage=%u\" option is obsolete. "
610 "Use \"polarization=%c\" instead.", voltage, pol);
614 static int sec_setup (vlc_object_t *obj, dvb_device_t *dev)
616 char pol = var_InheritPolarization (obj);
618 return dvb_set_sec (dev, pol);
621 static int dvbs_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
623 char *fec = var_InheritCodeRate (obj);
624 uint32_t srate = var_InheritInteger (obj, "dvb-srate");
626 /* FIXME: adjust frequency (offset) */
627 int ret = dvb_set_dvbs (dev, freq, srate, fec);
630 ret = sec_setup (obj, dev);
634 static int dvbs2_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
636 char *mod = var_InheritModulation (obj);
637 char *fec = var_InheritCodeRate (obj);
638 uint32_t srate = var_InheritInteger (obj, "dvb-srate");
639 int pilot = var_InheritInteger (obj, "dvb-pilot");
640 int rolloff = var_InheritInteger (obj, "dvb-rolloff");
642 /* FIXME: adjust frequency (offset)? */
643 int ret = dvb_set_dvbs2 (dev, freq, mod, srate, fec, pilot, rolloff);
647 ret = sec_setup (obj, dev);
651 const delsys_t dvbs = { .setup = dvbs_setup };
652 const delsys_t dvbs2 = { .setup = dvbs2_setup };
656 static int dvbt_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
658 char *mod = var_InheritModulation (obj);
659 char *fec_hp = var_InheritString (obj, "dvb-code-rate-hp");
660 char *fec_lp = var_InheritString (obj, "dvb-code-rate-lp");
661 char *guard = var_InheritString (obj, "dvb-guard");
662 uint32_t bw = var_InheritInteger (obj, "dvb-bandwidth");
663 int tx = var_InheritInteger (obj, "dvb-transmission");
664 int h = var_InheritInteger (obj, "dvb-hierarchy");
666 int ret = dvb_set_dvbt (dev, freq, mod, fec_hp, fec_lp, bw, tx, guard, h);
674 const delsys_t dvbt = { .setup = dvbt_setup };