]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
scanfile: add support for new linux dvb file format
authorJaroslav Kysela <perex@perex.cz>
Sat, 13 Sep 2014 15:20:03 +0000 (17:20 +0200)
committerJaroslav Kysela <perex@perex.cz>
Sat, 13 Sep 2014 15:21:53 +0000 (17:21 +0200)
src/input/mpegts/dvb.h
src/input/mpegts/dvb_support.c
src/input/mpegts/scanfile.c

index 5682ddd004e068f508aff5cb670e5a05e9823bd9..2aee8a39dd5d62edceb34d9b2b9525c398737b6e 100644 (file)
@@ -400,7 +400,8 @@ typedef enum dvb_polarisation {
   DVB_POLARISATION_HORIZONTAL     = 0x00,
   DVB_POLARISATION_VERTICAL       = 0x01,
   DVB_POLARISATION_CIRCULAR_LEFT  = 0x02,
-  DVB_POLARISATION_CIRCULAR_RIGHT = 0x03
+  DVB_POLARISATION_CIRCULAR_RIGHT = 0x03,
+  DVB_POLARISATION_OFF            = 0x04
 } dvb_polarisation_t;
 
 typedef struct dvb_qpsk_config {
@@ -452,6 +453,7 @@ const char *dvb_fec2str     ( int fec );
 const char *dvb_qam2str     ( int qam );
 const char *dvb_bw2str      ( int bw );
 const char *dvb_mode2str    ( int mode );
+const char *dvb_inver2str   ( int inver );
 const char *dvb_guard2str   ( int guard );
 const char *dvb_hier2str    ( int hier );
 const char *dvb_pol2str     ( int pol );
@@ -465,6 +467,7 @@ int dvb_str2delsys  ( const char *str );
 int dvb_str2fec     ( const char *str );
 int dvb_str2qam     ( const char *str );
 int dvb_str2bw      ( const char *str );
+int dvb_str2inver   ( const char *str );
 int dvb_str2mode    ( const char *str );
 int dvb_str2guard   ( const char *str );
 int dvb_str2hier    ( const char *str );
index be67ceaa912394de7ee468204dc0a861cc3be57f..c8c6bcff32e9c931d07fbb39d845f0a4dfe67f1d 100644 (file)
@@ -510,8 +510,11 @@ int dvb_str2rolloff(const char *p)
 
 const static struct strtab delsystab[] = {
   { "NONE",         DVB_SYS_NONE },
+  { "DVBC/ANNEX_A", DVB_SYS_DVBC_ANNEX_A },
   { "DVBC_ANNEX_A", DVB_SYS_DVBC_ANNEX_A },
+  { "DVBC/ANNEX_B", DVB_SYS_DVBC_ANNEX_B },
   { "DVBC_ANNEX_B", DVB_SYS_DVBC_ANNEX_B },
+  { "DVBC/ANNEX_C", DVB_SYS_DVBC_ANNEX_C },
   { "DVBC_ANNEX_C", DVB_SYS_DVBC_ANNEX_C },
   { "DVBC_ANNEX_AC",DVB_SYS_DVBC_ANNEX_A }, /* for compatibility */
   { "DVBT",         DVB_SYS_DVBT },
@@ -622,14 +625,23 @@ const static struct strtab qamtab[] = {
   { "AUTO",      DVB_MOD_AUTO },
   { "QPSK",      DVB_MOD_QPSK },
   { "QAM4NR",    DVB_MOD_QAM_4_NR },
+  { "QAM/AUTO",  DVB_MOD_QAM_AUTO },
   { "QAM-AUTO",  DVB_MOD_QAM_AUTO },
+  { "QAM/16",    DVB_MOD_QAM_16 },
   { "QAM16",     DVB_MOD_QAM_16 },
+  { "QAM/32",    DVB_MOD_QAM_32 },
   { "QAM32",     DVB_MOD_QAM_32 },
+  { "QAM/64",    DVB_MOD_QAM_64 },
   { "QAM64",     DVB_MOD_QAM_64 },
+  { "QAM/128",   DVB_MOD_QAM_128 },
   { "QAM128",    DVB_MOD_QAM_128 },
+  { "QAM/256",   DVB_MOD_QAM_256 },
   { "QAM256",    DVB_MOD_QAM_256 },
+  { "VSB/8",     DVB_MOD_VSB_8 },
   { "8VSB",      DVB_MOD_VSB_8 },
+  { "VSB/16",    DVB_MOD_VSB_16 },
   { "16VSB",     DVB_MOD_VSB_16 },
+  { "PSK/8",     DVB_MOD_PSK_8 },
   { "8PSK",      DVB_MOD_PSK_8 },
   { "DQPSK",     DVB_MOD_DQPSK },
   { "BPSK",      DVB_MOD_BPSK },
@@ -684,6 +696,14 @@ int dvb_str2bw(const char *p)
   return dvb_verify(hi, bw_table);
 }
 
+const static struct strtab invertab[] = {
+  { "NONE",  DVB_INVERSION_UNDEFINED },
+  { "AUTO",  DVB_INVERSION_AUTO },
+  { "ON",    DVB_INVERSION_ON },
+  { "OFF",   DVB_INVERSION_OFF },
+};
+dvb_str2val(inver);
+
 const static struct strtab modetab[] = {
   { "NONE",  DVB_TRANSMISSION_MODE_NONE },
   { "AUTO",  DVB_TRANSMISSION_MODE_AUTO },
@@ -728,6 +748,7 @@ const static struct strtab poltab[] = {
   { "H", DVB_POLARISATION_HORIZONTAL },
   { "L", DVB_POLARISATION_CIRCULAR_LEFT },
   { "R", DVB_POLARISATION_CIRCULAR_RIGHT },
+  { "O", DVB_POLARISATION_OFF },
 };
 dvb_str2val(pol);
 
index a30f08291f1846cba8e161a5c5691b3876c64424..d8ad8e40407027adf8c7834124f3a218e014eaeb 100644 (file)
@@ -331,6 +331,215 @@ scanfile_load_one ( scanfile_network_t *net, const char *line )
   }
 }
 
+/*
+ * Process mux dvbv5 entry
+ */
+static char *
+str_trim(char *s)
+{
+  char *t;
+  while (*s && *s <= ' ')
+    s++;
+  if (*s) {
+    t = s + strlen(s);
+    while (t != s && *(t - 1) <= ' ')
+      t--;
+    *t = '\0';
+  }
+  for (t = s; *t; t++)
+    *t = toupper(*t);
+  return s;
+}
+
+#define mux_fail0(r, text) do { \
+  tvhtrace("scanfile", text); \
+  ((r) = -1); \
+} while (0)
+#define mux_fail(r, text, val) do { \
+  tvhtrace("scanfile", text, val); \
+  ((r) = -1); \
+} while (0)
+#define mux_ok(r)   ((r) = ((r) > 0) ? 0 : (r))
+
+static int
+scanfile_load_dvbv5 ( scanfile_network_t *net, char *line, fb_file *fp )
+{
+  int res = 1, r = 1;
+  char buf[256];
+  char *s, *t;
+  const char *x;
+  dvb_mux_conf_t *mux;
+  htsmsg_t *l;
+
+  /* validity check for [text] */
+  s = str_trim(line);
+  if (s == '\0' || s[strlen(s) - 1] != ']')
+    return 1;
+
+  l = htsmsg_create_map();
+
+  /* Process file */
+  while (!fb_eof(fp)) {
+    /* Get line */
+    buf[sizeof(buf)-1] = '\0';
+    if (!fb_gets(fp, buf, sizeof(buf) - 1)) break;
+    s = str_trim(buf);
+    if (*s == '#' || *s == '\0')
+      continue;
+    if (*s == '[') {
+      res = 0;
+      break;
+    }
+    if ((t = strchr(s, '=')) == NULL)
+      continue;
+    *t = '\0';
+    s = str_trim(s);
+    t = str_trim(t + 1);
+
+    htsmsg_add_str(l, s, t);
+  }
+
+  mux = calloc(1, sizeof(dvb_mux_conf_t));
+
+  x = htsmsg_get_str(l, "DELIVERY_SYSTEM");
+
+  if ((mux->dmc_fe_delsys = dvb_str2delsys(x)) == -1) {
+    if (!strcmp(s, "DVBC"))
+      mux->dmc_fe_delsys = DVB_SYS_DVBC_ANNEX_A;
+  }
+  if ((int)mux->dmc_fe_delsys < 0)
+    mux_fail(r, "wrong system '%s'", x);
+
+  if (mux->dmc_fe_delsys == DVB_SYS_DVBT ||
+      mux->dmc_fe_delsys == DVB_SYS_DVBT2) {
+
+    mux->dmc_fe_type = DVB_TYPE_T;
+    mux->u.dmc_fe_ofdm.bandwidth = DVB_BANDWIDTH_AUTO;
+    mux->u.dmc_fe_ofdm.code_rate_HP = DVB_FEC_AUTO;
+    mux->u.dmc_fe_ofdm.code_rate_LP = DVB_FEC_NONE;
+    mux->dmc_fe_modulation = DVB_MOD_QAM_64;
+    mux->u.dmc_fe_ofdm.transmission_mode = DVB_TRANSMISSION_MODE_8K;
+    mux->u.dmc_fe_ofdm.hierarchy_information = DVB_HIERARCHY_NONE;
+    mux->dmc_fe_inversion  = DVB_INVERSION_AUTO;
+
+    if ((x = htsmsg_get_str(l, "BANDWIDTH_HZ")))
+      if ((mux->u.dmc_fe_ofdm.bandwidth = dvb_str2bw(x)) == -1)
+        mux_fail(r, "wrong bandwidth '%s'", x);
+    if ((x = htsmsg_get_str(l, "CODE_RATE_HP")))
+      if ((mux->u.dmc_fe_ofdm.code_rate_HP = dvb_str2fec(x)) == -1)
+        mux_fail(r, "wrong code rate HP '%s'", x);
+    if ((x = htsmsg_get_str(l, "CODE_RATE_LP")))
+      if ((mux->u.dmc_fe_ofdm.code_rate_LP = dvb_str2fec(x)) == -1)
+        mux_fail(r, "wrong code rate LP '%s'", x);
+    if ((x = htsmsg_get_str(l, "MODULATION")))
+      if ((mux->dmc_fe_modulation = dvb_str2qam(x)) == -1)
+        mux_fail(r, "wrong modulation '%s'", x);
+    if ((x = htsmsg_get_str(l, "TRANSMISSION_MODE")))
+      if ((mux->u.dmc_fe_ofdm.transmission_mode = dvb_str2mode(x)) == -1)
+        mux_fail(r, "wrong transmission mode '%s'", x);
+    if ((x = htsmsg_get_str(l, "GUARD_INTERVAL")))
+      if ((mux->u.dmc_fe_ofdm.guard_interval = dvb_str2guard(x)) == -1)
+        mux_fail(r, "wrong guard interval '%s'", x);
+    if ((x = htsmsg_get_str(l, "HIERARCHY")))
+      if ((mux->u.dmc_fe_ofdm.hierarchy_information = dvb_str2hier(x)) == -1)
+        mux_fail(r, "wrong hierarchy '%s'", x);
+    if ((x = htsmsg_get_str(l, "INVERSION")))
+      if ((mux->dmc_fe_inversion = dvb_str2inver(x)) == -1)
+        mux_fail(r, "wrong inversion '%s'", x);
+
+  } else if (mux->dmc_fe_delsys == DVB_SYS_DVBS ||
+             mux->dmc_fe_delsys == DVB_SYS_DVBS2) {
+
+    mux->dmc_fe_type = DVB_TYPE_S;
+    mux->dmc_fe_modulation =
+      mux->dmc_fe_delsys == DVB_SYS_DVBS2 ? DVB_MOD_PSK_8 : DVB_MOD_QPSK;
+    mux->u.dmc_fe_qam.fec_inner = DVB_FEC_AUTO;
+    mux->dmc_fe_inversion  = DVB_INVERSION_AUTO;
+    mux->dmc_fe_rolloff    = DVB_ROLLOFF_35;
+    mux->dmc_fe_pilot      = DVB_PILOT_AUTO;
+
+    if ((x = htsmsg_get_str(l, "MODULATION")))
+      if ((mux->dmc_fe_modulation = dvb_str2qam(x)) == -1)
+        mux_fail(r, "wrong modulation '%s'", x);
+    if ((x = htsmsg_get_str(l, "INNER_FEC")))
+      if ((mux->u.dmc_fe_qpsk.fec_inner = dvb_str2fec(x)) == -1)
+        mux_fail(r, "wrong inner FEC '%s'", x);
+    if ((x = htsmsg_get_str(l, "INVERSION")))
+      if ((mux->dmc_fe_inversion = dvb_str2inver(x)) == -1)
+        mux_fail(r, "wrong inversion '%s'", x);
+    if ((x = htsmsg_get_str(l, "ROLLOFF")))
+      if ((mux->dmc_fe_rolloff = dvb_str2rolloff(x)) == -1)
+        mux_fail(r, "wrong rolloff '%s'", x);
+    if ((x = htsmsg_get_str(l, "PILOT")))
+      if ((mux->dmc_fe_pilot = dvb_str2rolloff(x)) == -1)
+        mux_fail(r, "wrong pilot '%s'", x);
+    if ((x = htsmsg_get_str(l, "POLARIZATION"))) {
+      char pol[2];
+      pol[0] = x[0]; pol[1] = '\0';
+      if ((mux->u.dmc_fe_qpsk.polarisation = dvb_str2pol(pol)) == -1)
+        mux_fail(r, "wrong polarisation '%s'", x);
+    } else {
+      mux_fail0(r, "dvb-s: undefined polarisation");
+    }
+    if (!htsmsg_get_u32(l, "SYMBOL_RATE", &mux->u.dmc_fe_qpsk.symbol_rate))
+      mux_fail0(r, "dvb-s: undefined symbol rate");
+
+  } else if (mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_A ||
+             mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_B ||
+             mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_C) {
+
+    mux->dmc_fe_type = DVB_TYPE_C;
+    mux->dmc_fe_modulation = DVB_MOD_QAM_128;
+    mux->u.dmc_fe_qam.fec_inner = DVB_FEC_NONE;
+    mux->dmc_fe_inversion  = DVB_INVERSION_AUTO;
+
+    if ((x = htsmsg_get_str(l, "MODULATION")))
+      if ((mux->dmc_fe_modulation = dvb_str2qam(x)) == -1)
+        mux_fail(r, "wrong modulation '%s'", x);
+    if ((x = htsmsg_get_str(l, "INNER_FEC")))
+      if ((mux->u.dmc_fe_qam.fec_inner = dvb_str2fec(x)) == -1)
+        mux_fail(r, "wrong inner FEC '%s'", x);
+    if ((x = htsmsg_get_str(l, "INVERSION")))
+      if ((mux->dmc_fe_inversion = dvb_str2inver(x)) == -1)
+        mux_fail(r, "wrong inversion '%s'", x);
+    if (!htsmsg_get_u32(l, "SYMBOL_RATE", &mux->u.dmc_fe_qam.symbol_rate))
+      mux_fail0(r, "dvb-c: undefined symbol rate");
+
+  } else if (mux->dmc_fe_delsys == DVB_SYS_ATSC) {
+
+    mux->dmc_fe_type = DVB_TYPE_ATSC;
+    mux->dmc_fe_modulation = DVB_MOD_VSB_8;
+    mux->dmc_fe_inversion  = DVB_INVERSION_AUTO;
+
+    if ((x = htsmsg_get_str(l, "MODULATION")))
+      if ((mux->dmc_fe_modulation = dvb_str2qam(x)) == -1)
+        mux_fail(r, "wrong modulation '%s'", x);
+    if ((x = htsmsg_get_str(l, "INVERSION")))
+      if ((mux->dmc_fe_inversion = dvb_str2inver(x)) == -1)
+        mux_fail(r, "wrong inversion '%s'", x);
+
+  } else {
+
+    mux_fail(r, "wrong delivery system '%s'", x);
+
+  }
+
+  if (!htsmsg_get_u32(l, "FREQUENCY", &mux->dmc_fe_freq))
+    mux_ok(r);
+
+  htsmsg_destroy(l);
+
+  if (r) {
+    free(mux);
+  } else {
+    dvb_mux_conf_str(mux, buf, sizeof(buf));
+    tvhtrace("scanfile", "mux %s", buf);
+    LIST_INSERT_HEAD(&net->sfn_muxes, mux, dmc_link);
+  }
+
+  return res;
+}
+
 /*
  * Process a file
  */
@@ -338,7 +547,7 @@ static void
 scanfile_load_file
   ( const char *type, fb_dir *dir, const char *name )
 {
-  int i, opos;
+  int opos, load;
   fb_file *fp;
   scanfile_region_t *reg = NULL;
   scanfile_network_t *net;
@@ -390,19 +599,19 @@ scanfile_load_file
   LIST_INSERT_SORTED(&reg->sfr_networks, net, sfn_link, scanfile_network_cmp);
 
   /* Process file */
+  load = 1;
   while (!fb_eof(fp)) {
 
     /* Get line */
-    memset(buf, 0, sizeof(buf));
-    if (!fb_gets(fp, buf, sizeof(buf) - 1)) break;
-    i = 0;
-    while (buf[i]) {
-      if (buf[i] == '#') 
-        buf[i] = '\0';
-      else
-        i++;
+    if (load) {
+      buf[sizeof(buf)-1] = '\0';
+      if (!fb_gets(fp, buf, sizeof(buf) - 1)) break;
+      if (buf[0])
+        buf[strlen(buf)-1] = '\0';
+      while (buf[0] && buf[strlen(buf)-1] <= ' ')
+        buf[strlen(buf)-1] = '\0';
     }
-    while (i > 0 && buf[i-1] < 32) buf[--i] = 0;
+    load = 1;
 
     /* Process mux */
     switch (*buf) {
@@ -411,6 +620,10 @@ scanfile_load_file
       case 'T':
       case 'S':
         scanfile_load_one(net, buf);
+        break;
+      case '[':
+        load = scanfile_load_dvbv5(net, buf, fp);
+        break;
       default:
         break;
     }