]> git.sesse.net Git - vlc/blobdiff - modules/access/dtv/access.c
Initial HTCPCP implementation
[vlc] / modules / access / dtv / access.c
index c7b825ead7c1af540e58b157fe7de43e9da76cb7..94df171627a290b2194b0688ab8a360d4016d514 100644 (file)
@@ -28,6 +28,7 @@
 #include <vlc_access.h>
 #include <vlc_plugin.h>
 #include <vlc_dialog.h>
+#include <search.h>
 
 #include "dtv/dtv.h"
 
     "Only useful programs are normally demultiplexed from the transponder. " \
     "This option will disable demultiplexing and receive all programs.")
 
+#define NAME_TEXT N_("Network name")
+#define NAME_LONGTEXT N_("Unique network name in the System Tuning Spaces")
+
+#define CREATE_TEXT N_("Network name to create")
+#define CREATE_LONGTEXT N_("Create unique name in the System Tuning Spaces")
+
 #define FREQ_TEXT N_("Frequency (kHz)")
 #define FREQ_LONGTEXT N_( \
     "TV channels are grouped by transponder (a.k.a. multiplex) " \
@@ -91,7 +98,7 @@ static const char *const auto_off_on_user[] = { N_("Automatic"),
 #define CODE_RATE_LONGTEXT N_( \
     "The code rate for Forward Error Correction can be specified.")
 static const char *const code_rate_vlc[] = { "",
-    "none", /*"1/4", "1/3",*/ "1/2", "3/5", "2/3", "3/4",
+    "0", /*"1/4", "1/3",*/ "1/2", "3/5", "2/3", "3/4",
     "4/5", "5/6", "6/7", "7/8", "8/9", "9/10",
 };
 static const char *const code_rate_user[] = { N_("Automatic"),
@@ -132,6 +139,7 @@ static const char *const hierarchy_user[] = { N_("Automatic"),
 };
 
 #define PILOT_TEXT N_("Pilot")
+
 #define ROLLOFF_TEXT N_("Roll-off factor")
 const int rolloff_vlc[] = { -1,
     35, 20, 25,
@@ -155,19 +163,66 @@ static const char *const polarization_user[] = { N_("Unspecified (0V)"),
     "the receiver are long, higher voltage may be required.\n" \
     "Not all receivers support this.")
 
+#define LNB_LOW_TEXT N_("Local oscillator low frequency (kHz)")
+#define LNB_HIGH_TEXT N_("Local oscillator high frequency (kHz)")
+#define LNB_LONGTEXT N_( \
+    "The downconverter (LNB) will substract the local oscillator frequency " \
+    "from the satellite transmission frequency. " \
+    "The intermediate frequency (IF) on the RF cable is the result.")
+#define LNB_SWITCH_TEXT N_("Universal LNB switch frequency (kHz)")
+#define LNB_SWITCH_LONGTEXT N_( \
+    "If the satellite transmission frequency exceeds the switch frequency, " \
+    "the oscillator high frequency will be used as reference. " \
+    "Furthermore the automatic continuous 22kHz tone will be sent.")
+#define TONE_TEXT N_("Continuous 22kHz tone")
+#define TONE_LONGTEXT N_( \
+    "A continuous tone at 22kHz can be sent on the cable. " \
+    "This normally selects the higher frequency band from a universal LNB.")
+
+#define SATNO_TEXT N_("DiSEqC LNB number")
+#define SATNO_LONGTEXT N_( \
+    "If the satellite receiver is connected to multiple " \
+    "low noise block-downconverters (LNB) through a DiSEqC 1.0 switch, " \
+    "the correct LNB can be selected (1 to 4). " \
+    "If there is no switch, this parameter should be 0.")
+#ifdef __linux__
+static const int satno_vlc[] = { 0, 1, 2, 3, 4 };
+static const char *const satno_user[] = { N_("Unspecified"),
+    "A/1", "B/2", "C/3", "D/4" };
+#endif
+
+/* BDA module additional DVB-S Parameters */
+#define NETID_TEXT N_("Network identifier")
+#define AZIMUTH_TEXT N_("Satellite azimuth")
+#define AZIMUTH_LONGTEXT N_("Satellite azimuth in tenths of degree")
+#define ELEVATION_TEXT N_("Satellite elevation")
+#define ELEVATION_LONGTEXT N_("Satellite elevation in tenths of degree")
+#define LONGITUDE_TEXT N_("Satellite longitude")
+#define LONGITUDE_LONGTEXT N_( \
+    "Satellite longitude in tenths of degree. West is negative.")
+
+#define RANGE_TEXT N_("Satellite range code")
+#define RANGE_LONGTEXT N_("Satellite range code as defined by manufacturer " \
+   "e.g. DISEqC switch code")
+
+/* ATSC */
+#define MAJOR_CHANNEL_TEXT N_("Major channel")
+#define MINOR_CHANNEL_TEXT N_("ATSC minor channel")
+#define PHYSICAL_CHANNEL_TEXT N_("Physical channel")
+
 static int  Open (vlc_object_t *);
 static void Close (vlc_object_t *);
 
 vlc_module_begin ()
     set_shortname (N_("DTV"))
-    set_description (N_("Digital Television and Radio (Linux DVB)"))
+    set_description (N_("Digital Television and Radio"))
     set_category (CAT_INPUT)
     set_subcategory (SUBCAT_INPUT_ACCESS)
     set_capability ("access", 0)
     set_callbacks (Open, Close)
     add_shortcut ("dtv", "tv", "dvb", /* "radio", "dab",*/
-                  "cable", "dvb-c", /*"satellite", "dvb-s", "dvb-s2",*/
-                  "terrestrial", "dvb-t", "atsc")
+                  "cable", "dvb-c", "satellite", "dvb-s", "dvb-s2",
+                  "terrestrial", "dvb-t", "atsc", "cqam")
 
     /* All options starting with dvb- can be overriden in the MRL, so they
      * must all be "safe". Nevertheless, we do not mark as safe those that are
@@ -184,6 +239,13 @@ vlc_module_begin ()
     add_integer ("dvb-device", 0, DEVICE_TEXT, DEVICE_LONGTEXT, false)
         change_integer_range (0, 255)
     add_bool ("dvb-budget-mode", false, BUDGET_TEXT, BUDGET_LONGTEXT, true)
+#endif
+#ifdef WIN32
+    add_integer ("dvb-adapter", -1, ADAPTER_TEXT, ADAPTER_LONGTEXT, true)
+    add_string ("dvb-network-name", "", NAME_TEXT, NAME_LONGTEXT, true)
+    /* Hmm: is this one really safe??: */
+    add_string ("dvb-create-name", "", CREATE_TEXT, CREATE_LONGTEXT, true)
+        change_private ()
 #endif
     add_integer ("dvb-frequency", 0, FREQ_TEXT, FREQ_LONGTEXT, false)
         change_integer_range (0, 107999999)
@@ -193,7 +255,7 @@ vlc_module_begin ()
         change_safe ()
 
     set_section (N_("Terrestrial reception parameters"), NULL)
-    add_integer ("dvb-bandwidth", -1, BANDWIDTH_TEXT, BANDWIDTH_TEXT, true)
+    add_integer ("dvb-bandwidth", 0, BANDWIDTH_TEXT, BANDWIDTH_TEXT, true)
         change_integer_list (bandwidth_vlc, bandwidth_user)
         change_safe ()
     add_string ("dvb-code-rate-hp", "",
@@ -223,13 +285,10 @@ vlc_module_begin ()
     add_integer ("dvb-srate", 0, SRATE_TEXT, SRATE_LONGTEXT, false)
         change_integer_range (0, UINT64_C(0xffffffff))
         change_safe ()
-    add_string ("dvb-code-rate", "", CODE_RATE_TEXT, CODE_RATE_LONGTEXT, true)
+    add_string ("dvb-fec", "", CODE_RATE_TEXT, CODE_RATE_LONGTEXT, true)
         change_string_list (code_rate_vlc, code_rate_user, NULL)
         change_safe ()
-    add_integer ("dvb-fec", 9, " ", " ", true)
-        change_integer_range (0, 9)
-        change_private ()
-        change_safe ()
+
     set_section (N_("DVB-S2 parameters"), NULL)
     add_integer ("dvb-pilot", -1, PILOT_TEXT, PILOT_TEXT, true)
         change_integer_list (auto_off_on_vlc, auto_off_on_user)
@@ -237,6 +296,7 @@ vlc_module_begin ()
     add_integer ("dvb-rolloff", -1, ROLLOFF_TEXT, ROLLOFF_TEXT, true)
         change_integer_list (rolloff_vlc, rolloff_user)
         change_safe ()
+
     set_section (N_("Satellite equipment control"), NULL)
     add_string ("dvb-polarization", "",
                 POLARIZATION_TEXT, POLARIZATION_LONGTEXT, false)
@@ -250,22 +310,35 @@ vlc_module_begin ()
     add_bool ("dvb-high-voltage", false,
               HIGH_VOLTAGE_TEXT, HIGH_VOLTAGE_LONGTEXT, false)
 #endif
-#if 0
-    add_integer ("dvb-tone", -1, TONE_TEXT, TONE_LONGTEXT, true)
-        change_integer_list (tone_vlc, auto_off_on)
-        change_safe ()
-    add_integer ("dvb-lnb-lof1", 0, LNB_LOF1_TEXT, LNB_LOF1_LONGTEXT, true)
+    add_integer ("dvb-lnb-low", 0, LNB_LOW_TEXT, LNB_LONGTEXT, true)
         change_integer_range (0, 0x7fffffff)
-        change_safe ()
-    add_integer ("dvb-lnb-lof2", 0, LNB_LOF2_TEXT, LNB_LOF2_LONGTEXT, true)
+        add_deprecated_alias ("dvb-lnb-lof1")
+    add_integer ("dvb-lnb-high", 0, LNB_HIGH_TEXT, LNB_LONGTEXT, true)
         change_integer_range (0, 0x7fffffff)
-        change_safe ()
-    add_integer ("dvb-lnb-slof", 0, LNB_SLOF_TEXT, LNB_SLOF_LONGTEXT, true)
+        add_deprecated_alias ("dvb-lnb-lof2")
+    add_integer ("dvb-lnb-switch", 11700000,
+                 LNB_SWITCH_TEXT, LNB_SWITCH_LONGTEXT, true)
         change_integer_range (0, 0x7fffffff)
-        change_safe ()
+        add_deprecated_alias ("dvb-lnb-slof")
+#ifdef __linux
     add_integer ("dvb-satno", 0, SATNO_TEXT, SATNO_LONGTEXT, true)
         change_integer_list (satno_vlc, satno_user)
-        change_safe ()
+    add_integer ("dvb-tone", -1, TONE_TEXT, TONE_LONGTEXT, true)
+        change_integer_list (auto_off_on_vlc, auto_off_on_user)
+#endif
+#ifdef WIN32
+    add_integer ("dvb-network-id", 0, NETID_TEXT, NETID_TEXT, true)
+    add_integer ("dvb-azimuth", 0, AZIMUTH_TEXT, AZIMUTH_LONGTEXT, true)
+    add_integer ("dvb-elevation", 0, ELEVATION_TEXT, ELEVATION_LONGTEXT, true)
+    add_integer ("dvb-longitude", 0, LONGITUDE_TEXT, LONGITUDE_LONGTEXT, true)
+    add_string ("dvb-range", "", RANGE_TEXT, RANGE_LONGTEXT, true)
+    /* dvb-range corresponds to the BDA InputRange parameter which is
+    * used by some drivers to control the diseqc */
+
+    set_section (N_("ATSC reception parameters"), NULL)
+    add_integer ("dvb-major-channel", 0, MAJOR_CHANNEL_TEXT, NULL, true)
+    add_integer ("dvb-minor-channel", 0, MINOR_CHANNEL_TEXT, NULL, true)
+    add_integer ("dvb-physical-channel", 0, PHYSICAL_CHANNEL_TEXT, NULL, true)
 #endif
 vlc_module_end ()
 
@@ -468,6 +541,8 @@ static const delsys_t *GuessSystem (const char *scheme, dvb_device_t *dev)
 
     if (!strcasecmp (scheme, "atsc"))
         return &atsc;
+    if (!strcasecmp (scheme, "cqam"))
+        return &cqam;
     if (!strcasecmp (scheme, "dvb-c"))
         return &dvbc;
     if (!strcasecmp (scheme, "dvb-s"))
@@ -503,39 +578,58 @@ static unsigned var_InheritFrequency (vlc_object_t *obj)
     return freq;
 }
 
-static char *var_InheritCodeRate (vlc_object_t *obj)
+static uint32_t var_InheritCodeRate (vlc_object_t *obj, const char *varname)
 {
-    char *code_rate = var_InheritString (obj, "dvb-code-rate");
-    if (code_rate != NULL)
-        return code_rate;
-
-    /* Backward compatibility with VLC < 1.2 (= Linux DVBv3 enum) */
-    unsigned fec = var_InheritInteger (obj, "dvb-fec");
-    if (fec < 9)
+    char *code_rate = var_InheritString (obj, varname);
+    if (code_rate == NULL)
+        return VLC_FEC_AUTO;
+
+    uint16_t a, b;
+    int v = sscanf (code_rate, "%"SCNu16"/%"SCNu16, &a, &b);
+    free (code_rate);
+    switch (v)
     {
-        static const char linux_dvb[9][5] = {
-            "none", "1/2", "2/3", "3/4", "4/5", "5/6", "6/7", "7/8" };
-        msg_Warn (obj, "\"fec=%u\" option is obsolete. "
-                       "Use \"code-rate=%s\" instead.", fec, linux_dvb[fec]);
-        return strdup (linux_dvb[fec]);
+        case 2:
+            return VLC_FEC(a, b);
+        case 1:
+            if (a == 0)
+                return 0;
+            /* Backward compatibility with VLC < 1.2 (= Linux DVBv3 enum) */
+            if (a < 9)
+            {
+                msg_Warn (obj, "\"%s=%"PRIu16"\" option is obsolete. "
+                          "Use \"%s=%"PRIu16"/%"PRIu16"\" instead.",
+                          varname + 4, a, varname + 4, a, a + 1);
+                return VLC_FEC(a, a + 1);
+            }
+            else
+                msg_Warn (obj, "\"fec=9\" option is obsolete.");
     }
-    return NULL;
+    return VLC_FEC_AUTO;
+}
+
+static int modcmp (const void *a, const void *b)
+{
+    return strcasecmp (a, *(const char *const *)b);
 }
 
-static char *var_InheritModulation (vlc_object_t *obj)
+static const char *var_InheritModulation (vlc_object_t *obj)
 {
     char *mod = var_InheritString (obj, "dvb-modulation");
     if (mod == NULL)
-        return mod;
+        return "";
 
-    char *end;
-    unsigned long l = strtol (mod, &end, 0);
-    if (*end != '\0') /* not a number = not from VLC < 1.2 */
-        return mod;
+    size_t n = sizeof (modulation_vlc) / sizeof (modulation_vlc[0]);
+    const char *const *p = lfind (mod, modulation_vlc, &n, sizeof (mod), modcmp);
+    if (p != NULL)
+    {
+        free (mod);
+        return *p;
+    }
 
     /* Backward compatibility with VLC < 1.2 */
     const char *str;
-    switch (l)
+    switch (atoi (mod))
     {
         case -1:  str = "QPSK";   break;
         case 0:   str = "QAM";    break;
@@ -545,39 +639,69 @@ static char *var_InheritModulation (vlc_object_t *obj)
         case 64:  str = "64QAM";  break;
         case 128: str = "128QAM"; break;
         case 256: str = "256QAM"; break;
-        default:  return mod;
+        default:  return "";
     }
 
-    msg_Warn (obj, "\"modulation=%ld\" option is obsolete. "
-                   "Use \"modulation=%s\" instead.", l, str);
-    return strdup (str);
+    msg_Warn (obj, "\"modulation=%s\" option is obsolete. "
+                   "Use \"modulation=%s\" instead.", mod, str);
+    free (mod);
+    return str;
+}
+
+static unsigned var_InheritGuardInterval (vlc_object_t *obj)
+{
+    char *guard = var_InheritString (obj, "dvb-guard");
+    if (guard == NULL)
+        return VLC_GUARD_AUTO;
+
+    uint16_t a, b;
+    int v = sscanf (guard, "%"SCNu16"/%"SCNu16, &a, &b);
+    free (guard);
+    switch (v)
+    {
+        case 1:
+            /* Backward compatibility with VLC < 1.2 */
+            if (a == 0)
+                break;
+            msg_Warn (obj, "\"guard=%"PRIu16"\" option is obsolete. "
+                           "Use \"guard=1/%"PRIu16" instead.", a, a);
+            b = a;
+            a = 1;
+        case 2:
+            return VLC_GUARD(a, b);
+    }
+    return VLC_GUARD_AUTO;
 }
 
 
 /*** ATSC ***/
 static int atsc_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
 {
-    char *mod = var_InheritModulation (obj);
+    const char *mod = var_InheritModulation (obj);
 
-    int ret = dvb_set_atsc (dev, freq, mod);
-    free (mod);
-    return ret;
+    return dvb_set_atsc (dev, freq, mod);
 }
 
 const delsys_t atsc = { .setup = atsc_setup };
 
+static int cqam_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
+{
+    const char *mod = var_InheritModulation (obj);
+
+    return dvb_set_cqam (dev, freq, mod);
+}
+
+const delsys_t cqam = { .setup = cqam_setup };
+
 
 /*** DVB-C ***/
 static int dvbc_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
 {
-    char *mod = var_InheritModulation (obj);
-    char *fec = var_InheritCodeRate (obj);
+    const char *mod = var_InheritModulation (obj);
+    uint32_t fec = var_InheritCodeRate (obj, "dvb-fec");
     unsigned srate = var_InheritInteger (obj, "dvb-srate");
 
-    int ret = dvb_set_dvbc (dev, freq, mod, srate, fec);
-    free (fec);
-    free (mod);
-    return ret;
+    return dvb_set_dvbc (dev, freq, mod, srate, fec);
 }
 
 const delsys_t dvbc = { .setup = dvbc_setup };
@@ -611,40 +735,38 @@ static char var_InheritPolarization (vlc_object_t *obj)
     return pol;
 }
 
-static int sec_setup (vlc_object_t *obj, dvb_device_t *dev)
+static int sec_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
 {
     char pol = var_InheritPolarization (obj);
+    unsigned lowf = var_InheritInteger (obj, "dvb-lnb-low");
+    unsigned highf = var_InheritInteger (obj, "dvb-lnb-high");
+    unsigned switchf = var_InheritInteger (obj, "dvb-lnb-switch");
 
-    return dvb_set_sec (dev, pol);
+    return dvb_set_sec (dev, freq, pol, lowf, highf, switchf);
 }
 
 static int dvbs_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
 {
-    char *fec = var_InheritCodeRate (obj);
+    uint32_t fec = var_InheritCodeRate (obj, "dvb-fec");
     uint32_t srate = var_InheritInteger (obj, "dvb-srate");
 
-    /* FIXME: adjust frequency (offset) */
     int ret = dvb_set_dvbs (dev, freq, srate, fec);
-    free (fec);
     if (ret == 0)
-        ret = sec_setup (obj, dev);
+        ret = sec_setup (obj, dev, freq);
     return ret;
 }
 
 static int dvbs2_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
 {
-    char *mod = var_InheritModulation (obj);
-    char *fec = var_InheritCodeRate (obj);
+    const char *mod = var_InheritModulation (obj);
+    uint32_t fec = var_InheritCodeRate (obj, "dvb-fec");
     uint32_t srate = var_InheritInteger (obj, "dvb-srate");
     int pilot = var_InheritInteger (obj, "dvb-pilot");
     int rolloff = var_InheritInteger (obj, "dvb-rolloff");
 
-    /* FIXME: adjust frequency (offset)? */
     int ret = dvb_set_dvbs2 (dev, freq, mod, srate, fec, pilot, rolloff);
-    free (fec);
-    free (mod);
     if (ret == 0)
-        ret = sec_setup (obj, dev);
+        ret = sec_setup (obj, dev, freq);
     return ret;
 }
 
@@ -655,20 +777,15 @@ const delsys_t dvbs2 = { .setup = dvbs2_setup };
 /*** DVB-T ***/
 static int dvbt_setup (vlc_object_t *obj, dvb_device_t *dev, unsigned freq)
 {
-    char *mod = var_InheritModulation (obj);
-    char *fec_hp = var_InheritString (obj, "dvb-code-rate-hp");
-    char *fec_lp = var_InheritString (obj, "dvb-code-rate-lp");
-    char *guard = var_InheritString (obj, "dvb-guard");
+    const char *mod = var_InheritModulation (obj);
+    uint32_t fec_hp = var_InheritCodeRate (obj, "dvb-code-rate-hp");
+    uint32_t fec_lp = var_InheritCodeRate (obj, "dvb-code-rate-lp");
+    uint32_t guard = var_InheritGuardInterval (obj);
     uint32_t bw = var_InheritInteger (obj, "dvb-bandwidth");
     int tx = var_InheritInteger (obj, "dvb-transmission");
     int h = var_InheritInteger (obj, "dvb-hierarchy");
 
-    int ret = dvb_set_dvbt (dev, freq, mod, fec_hp, fec_lp, bw, tx, guard, h);
-    free (guard);
-    free (fec_lp);
-    free (fec_hp);
-    free (mod);
-    return ret;
+    return dvb_set_dvbt (dev, freq, mod, fec_hp, fec_lp, bw, tx, guard, h);
 }
 
 const delsys_t dvbt = { .setup = dvbt_setup };