]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
epggrab: reimplement the OTA grabber selection per mux
authorJaroslav Kysela <perex@perex.cz>
Mon, 7 Jan 2019 10:01:27 +0000 (11:01 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 8 Jan 2019 09:10:02 +0000 (10:10 +0100)
src/epggrab.h
src/epggrab/module/eit.c
src/epggrab/module/opentv.c
src/epggrab/module/psip.c
src/epggrab/otamux.c
src/epggrab/private.h
src/htsmsg.c
src/htsmsg.h
src/input/mpegts.h
src/input/mpegts/iptv/iptv_auto.c
src/input/mpegts/mpegts_mux.c

index 728b4bab2108f0f9e83f6bf9c786d7a730185437..230cef30f77b38caa4db969aca2ed72b0bb6f52e 100644 (file)
@@ -396,6 +396,8 @@ void epggrab_channel_mod ( struct channel *ch );
  */
 void epggrab_ota_queue_mux( struct mpegts_mux *mm );
 epggrab_ota_mux_t *epggrab_ota_find_mux ( struct mpegts_mux *mm );
+htsmsg_t *epggrab_ota_module_id_list( const char *lang );
+const char *epggrab_ota_check_module_id( const char *id );
 
 #endif /* __EPGGRAB_H__ */
 
index 93d2dfe76814d2b6943d9d64798e8dedca6f7de6..13c0e0e03fadc8d2cdb273bbc9b656064f551250 100644 (file)
@@ -55,6 +55,7 @@ typedef struct eit_sdt {
 typedef struct eit_private
 {
   TAILQ_ENTRY(eit_private) link;
+  lang_str_t *name;
   epggrab_module_ota_t *module;
   uint16_t pid;
   uint16_t bat_pid;
@@ -1457,6 +1458,7 @@ static void _eit_done0( eit_private_t *priv )
     free(nit);
   }
   free(priv->ops);
+  lang_str_destroy(priv->name);
   free(priv);
 }
 
@@ -1619,6 +1621,7 @@ static void eit_init_one ( const char *id, htsmsg_t *conf )
       }
     }
   }
+  priv->name = name_str;
   if (name_str) {
     priv->module = (epggrab_module_ota_t *)
       eit_module_ota_create(id, LS_TBL_EIT, NULL,
@@ -1629,7 +1632,6 @@ static void eit_init_one ( const char *id, htsmsg_t *conf )
     tvherror(LS_TBL_EIT, "missing name for '%s' in config", id);
     _eit_done0(priv);
   }
-  lang_str_destroy(name_str);
 }
 
 void eit_init ( void )
@@ -1651,6 +1653,34 @@ void eit_init ( void )
   htsmsg_destroy(c);
 }
 
+htsmsg_t *eit_module_id_list( const char *lang )
+{
+  eit_private_t *priv, *priv2;
+  htsmsg_t *e, *l = htsmsg_create_list();
+
+  TAILQ_FOREACH(priv, &eit_private_list, link) {
+    TAILQ_FOREACH(priv2, &eit_private_list, link)
+      if (strcmp(priv2->slave, priv->module->id) == 0)
+        break;
+    if (priv2) continue; /* show only parents */
+    e = htsmsg_create_key_val(priv->module->id, lang_str_get(priv->name, lang));
+    htsmsg_add_msg(l, NULL, e);
+  }
+  return l;
+}
+
+const char *eit_check_module_id ( const char *id )
+{
+  eit_private_t *priv;
+
+  if (!id) return NULL;
+  TAILQ_FOREACH(priv, &eit_private_list, link) {
+    if (strcmp(id, priv->module->id) == 0)
+      return priv->module->id;
+  }
+  return NULL;
+}
+
 void eit_done ( void )
 {
 }
index 62f8ff8e0bc34c647c1fb77bf941588d4fa7fd41..eae73d30a6d47cf8e5ae777e949bbd75a111f61d 100644 (file)
@@ -1066,6 +1066,31 @@ static void _opentv_prov_load ( htsmsg_t *m )
   htsmsg_destroy(m);
 }
 
+htsmsg_t *opentv_module_id_list( const char *lang )
+{
+  epggrab_module_t *m;
+  htsmsg_t *e, *l = htsmsg_create_list();
+
+  LIST_FOREACH(m, &epggrab_modules, link) {
+    if (strncmp(m->id, "opentv-", 7)) continue;
+    e = htsmsg_create_key_val(m->id, m->name);
+    htsmsg_add_msg(l, NULL, e);
+  }
+  return l;
+}
+
+const char *opentv_check_module_id ( const char *id )
+{
+  epggrab_module_t *m;
+
+  if (!id || strncmp(id, "opentv-", 7))
+    return NULL;
+  LIST_FOREACH(m, &epggrab_modules, link)
+    if (strcmp(m->id, id) == 0)
+      return m->id;
+  return NULL;
+}
+
 /* ************************************************************************
  * Module Setup
  * ***********************************************************************/
index 719e8a16b9e8e2d6f5f914b82162c7f892e6ac6e..aaf14dc0cd96b7ca224c0d288d05c0f0037deabd 100644 (file)
@@ -762,6 +762,21 @@ static int _psip_tune
   return r;
 }
 
+htsmsg_t *psip_module_id_list( const char *lang )
+{
+  htsmsg_t *e, *l = htsmsg_create_list();
+  e = htsmsg_create_key_val("psip", "PSIP: ATSC Grabber");
+  htsmsg_add_msg(l, NULL, e);
+  return l;
+}
+
+const char *psip_check_module_id ( const char *id )
+{
+  if (id && strcmp(id, "psip") == 0)
+    return "psip";
+  return NULL;
+}
+
 void psip_init ( void )
 {
   static epggrab_ota_module_ops_t ops = {
index 97128efdd2c1bd5d3ae8875cbe5dc5c4f4a62e83..d493eb773e2d30ce60c5a25f826bfa25bd43666f 100644 (file)
@@ -76,6 +76,21 @@ static void epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota
  * Utilities
  * *************************************************************************/
 
+htsmsg_t *epggrab_ota_module_id_list ( const char *lang )
+{
+  htsmsg_t *l = eit_module_id_list(lang);
+  htsmsg_concat(l, opentv_module_id_list(lang));
+  htsmsg_concat(l, psip_module_id_list(lang));
+  return l;
+}
+
+const char *epggrab_ota_check_module_id( const char *id )
+{
+  return eit_check_module_id(id) ?:
+         opentv_check_module_id(id) ?:
+         psip_check_module_id(id);
+}
+
 static int
 om_id_cmp   ( epggrab_ota_mux_t *a, epggrab_ota_mux_t *b )
 {
@@ -547,21 +562,6 @@ epggrab_ota_kick_cb ( void *p )
   } networks[64], *net;        /* more than 64 networks? - you're a king */
   int i, r, networks_count = 0, epg_flag, kick = 1;
   const char *modname;
-  static const char *modnames[] = {
-    [MM_EPG_DISABLE]                 = NULL,
-    [MM_EPG_ENABLE]                  = NULL,
-    [MM_EPG_FORCE]                   = NULL,
-    [MM_EPG_ONLY_EIT]                = "eit",
-    [MM_EPG_ONLY_PSIP]               = "psip",
-    [MM_EPG_ONLY_UK_FREESAT]         = "uk_freesat",
-    [MM_EPG_ONLY_UK_FREEVIEW]        = "uk_freeview",
-    [MM_EPG_ONLY_UK_CABLE_VIRGIN]    = "uk_cable_virgin",
-    [MM_EPG_ONLY_VIASAT_BALTIC]      = "viasat_baltic",
-    [MM_EPG_ONLY_BULSATCOM_39E]      = "Bulsatcom_39E",
-    [MM_EPG_ONLY_OPENTV_SKY_UK]      = "opentv-skyuk",
-    [MM_EPG_ONLY_OPENTV_SKY_ITALIA]  = "opentv-skyit",
-    [MM_EPG_ONLY_OPENTV_SKY_AUSAT]   = "opentv-ausat",
-  };
 
   lock_assert(&global_lock);
 
@@ -611,9 +611,12 @@ next_one:
   epg_flag = MM_EPG_DISABLE;
   if (mm->mm_is_enabled(mm)) {
     epg_flag = mm->mm_is_epg(mm);
-    if (epg_flag > MM_EPG_LAST)
+    if (epg_flag > MM_EPG_LAST) {
       epg_flag = MM_EPG_ENABLE;
-    modname  = epg_flag >= 0 ? modnames[epg_flag] : NULL;
+    } else if (epg_flag == MM_EPG_MANUAL) {
+      modname = epggrab_ota_check_module_id(mm->mm_epg_module_id);
+      if (!modname) epg_flag = MM_EPG_ENABLE;
+    }
   }
 
   if (epg_flag < 0 || epg_flag == MM_EPG_DISABLE) {
index 9dbc5a9c985d610481d1b2565545e4dd6cf60242..5f211ab631835d0fc5305f97afa5d9ca12d4d50b 100644 (file)
@@ -208,11 +208,17 @@ void eit_init    ( void );
 void eit_done    ( void );
 void eit_load    ( void );
 
+htsmsg_t *eit_module_id_list( const char *lang );
+const char *eit_check_module_id ( const char *id );
+
 /* OpenTV module */
 void opentv_init ( void );
 void opentv_done ( void );
 void opentv_load ( void );
 
+htsmsg_t *opentv_module_id_list( const char *lang );
+const char *opentv_check_module_id ( const char *id );
+
 /* XMLTV module */
 void xmltv_init  ( void );
 void xmltv_done  ( void );
@@ -223,4 +229,8 @@ void psip_init  ( void );
 void psip_done  ( void );
 void psip_load  ( void );
 
+htsmsg_t *psip_module_id_list( const char *lang );
+const char *psip_check_module_id ( const char *id );
+
+
 #endif /* __EPGGRAB_PRIVATE_H__ */
index 734419aa3df2e16285d9fd0e67efb38562562c43..5466cc1361d87951b4ba3e5e30e8ce9cd36a186b 100644 (file)
@@ -266,6 +266,23 @@ htsmsg_create_list(void)
 }
 
 
+
+/*
+ *
+ */
+void
+htsmsg_concat(htsmsg_t *msg, htsmsg_t *sub)
+{
+  if (sub == NULL)
+    return;
+  assert(msg->hm_islist == sub->hm_islist);
+  if (msg->hm_islist != sub->hm_islist)
+    return;
+  TAILQ_CONCAT(&msg->hm_fields, &sub->hm_fields, hmf_link);
+  htsmsg_destroy(sub);
+}
+
+
 /*
  *
  */
index d15c547e58b6632c939d619f85a84c66b19a1422..1be066e72dfbc954e23338b3d4ee7cc72e7fd71e 100644 (file)
@@ -130,6 +130,11 @@ htsmsg_t *htsmsg_create_map(void);
  */
 htsmsg_t *htsmsg_create_list(void);
 
+/**
+ * Concat msg2 to msg1 (list or map)
+ */
+void htsmsg_concat(htsmsg_t *msg1, htsmsg_t *msg2);
+
 /**
  * Remove a given field from a msg
  */
index 542640ce65d3f6a7d5ee781a86b7df68bae6b235..5054190770de686151baec858cd68c269febb98c 100644 (file)
@@ -411,18 +411,9 @@ enum mpegts_mux_epg_flag
   MM_EPG_DISABLE,
   MM_EPG_ENABLE,
   MM_EPG_FORCE,
-  MM_EPG_ONLY_EIT,
-  MM_EPG_ONLY_UK_FREESAT,
-  MM_EPG_ONLY_UK_FREEVIEW,
-  MM_EPG_ONLY_VIASAT_BALTIC,
-  MM_EPG_ONLY_OPENTV_SKY_UK,
-  MM_EPG_ONLY_OPENTV_SKY_ITALIA,
-  MM_EPG_ONLY_OPENTV_SKY_AUSAT,
-  MM_EPG_ONLY_BULSATCOM_39E,
-  MM_EPG_ONLY_PSIP,
-  MM_EPG_ONLY_UK_CABLE_VIRGIN
+  MM_EPG_MANUAL
 };
-#define MM_EPG_LAST MM_EPG_ONLY_UK_CABLE_VIRGIN
+#define MM_EPG_LAST MM_EPG_MANUAL
 
 enum mpegts_mux_ac3_flag
 {
@@ -540,6 +531,7 @@ struct mpegts_mux
   char    *mm_crid_authority;
   int      mm_enabled;
   int      mm_epg;
+  char    *mm_epg_module_id;
   char    *mm_charset;
   int      mm_pmt_ac3;
   int      mm_eit_tsid_nocheck;
index 0ee497df88b5318810afd3b24b18f3421b4a19d5..88fb7c1b575b6ff571af8e953597dc37aba70f3c 100644 (file)
@@ -22,6 +22,7 @@
 #include "iptv_private.h"
 #include "channels.h"
 #include "download.h"
+#include "epggrab.h"
 #include "misc/m3u.h"
 
 #include <fcntl.h>
@@ -36,7 +37,7 @@ typedef struct auto_private {
 /*
  *
  */
-static int _epgcfg_from_str(const char *str)
+static int _epgcfg_from_str(const char *str, char *manual, size_t manual_len)
 {
   static struct strtab cfgs[] = {
     { "0",                 MM_EPG_DISABLE },
@@ -48,18 +49,19 @@ static int _epgcfg_from_str(const char *str)
     { "enable",            MM_EPG_ENABLE },
     { "on",                MM_EPG_ENABLE },
     { "force",             MM_EPG_FORCE },
-    { "eit",               MM_EPG_ONLY_EIT },
-    { "uk_freesat",        MM_EPG_ONLY_UK_FREESAT },
-    { "uk_freeview",       MM_EPG_ONLY_UK_FREEVIEW },
-    { "viasat_baltic",     MM_EPG_ONLY_VIASAT_BALTIC },
-    { "opentv_sky_uk",     MM_EPG_ONLY_OPENTV_SKY_UK },
-    { "opentv_sky_italia", MM_EPG_ONLY_OPENTV_SKY_ITALIA },
-    { "opentv_sky_ausat",  MM_EPG_ONLY_OPENTV_SKY_AUSAT },
-    { "bulsatcom_39e",     MM_EPG_ONLY_BULSATCOM_39E },
-    { "psip",              MM_EPG_ONLY_PSIP },
     { NULL }
   };
-  return str ? str2val(str, cfgs) : -1;
+  int r = str ? str2val(str, cfgs) : -1;
+  if (manual) *manual = '\0';
+  if (r < 0) {
+    const char *s = epggrab_ota_check_module_id(str);
+    if (s) {
+      r = MM_EPG_MANUAL;
+      if (manual)
+        strlcpy(manual, s, manual_len);
+    }
+  }
+  return r;
 }
 
 /*
@@ -86,7 +88,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
   int64_t chnum2, vlcprog;
   const char *url, *url2, *name, *logo, *epgid, *tags;
   char *s;
-  char custom[512], name2[128], buf[32], *n;
+  char custom[512], name2[128], buf[32], *moduleid, *n;
 
   url = htsmsg_get_str(item, "m3u-url");
 
@@ -126,7 +128,8 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in,
     logo = htsmsg_get_str(item, "logo");
 
   epgid = htsmsg_get_str(item, "tvg-id");
-  epgcfg = _epgcfg_from_str(htsmsg_get_str(item, "tvh-epg"));
+  moduleid = alloca(64);
+  epgcfg = _epgcfg_from_str(htsmsg_get_str(item, "tvh-epg"), moduleid, 64);
   tags = htsmsg_get_str(item, "tvh-tags");
   if (!tags) tags = htsmsg_get_str(item, "group-title");
   if (tags) {
@@ -260,6 +263,11 @@ skip_url:
         im->mm_epg = epgcfg;
         change = 1;
       }
+      if (moduleid[0] && strcmp(im->mm_epg_module_id ?: "", moduleid)) {
+        free(im->mm_epg_module_id);
+        im->mm_epg_module_id = strdup(moduleid);
+        change = 1;
+      }
       if (muxprio >= 0 && im->mm_iptv_priority != muxprio) {
         im->mm_iptv_priority = muxprio;
         change = 1;
@@ -300,6 +308,8 @@ skip_url:
     htsmsg_add_str(conf, "iptv_hdr", custom);
   if (epgcfg >= 0)
     htsmsg_add_s32(conf, "epg", epgcfg);
+  if (moduleid[0])
+    htsmsg_add_str(conf, "epg_module_id", moduleid);
   if (in->in_tsid_accept_zero_value)
     htsmsg_add_s32(conf, "tsid_zero", 1);
   if (!htsmsg_get_s64(item, "vlc-program", &vlcprog) &&
index 58b132bb7a510d7027cdd11d5082c3ad9822747d..9d3bbbdd78d724d0f214e410afce6fe2fe3dcd5e 100644 (file)
@@ -26,6 +26,7 @@
 #include "access.h"
 #include "profile.h"
 #include "dvb_charset.h"
+#include "epggrab.h"
 
 #include <assert.h>
 
@@ -482,20 +483,17 @@ mpegts_mux_epg_list ( void *o, const char *lang )
     { N_("Disable"),                  MM_EPG_DISABLE },
     { N_("Enable (auto)"),            MM_EPG_ENABLE },
     { N_("Force (auto)"),             MM_EPG_FORCE },
-    { N_("Only EIT"),                 MM_EPG_ONLY_EIT },
-    { N_("Only PSIP (ATSC)"),         MM_EPG_ONLY_PSIP },
-    { N_("Only UK Freesat"),          MM_EPG_ONLY_UK_FREESAT },
-    { N_("Only UK Freeview"),         MM_EPG_ONLY_UK_FREEVIEW },
-    { N_("Only UK Cable Virgin"),     MM_EPG_ONLY_UK_CABLE_VIRGIN },
-    { N_("Only Viasat Baltic"),       MM_EPG_ONLY_VIASAT_BALTIC },
-    { N_("Only Bulsatcom 39E"),       MM_EPG_ONLY_BULSATCOM_39E },
-    { N_("Only OpenTV Sky UK"),       MM_EPG_ONLY_OPENTV_SKY_UK },
-    { N_("Only OpenTV Sky Italia"),   MM_EPG_ONLY_OPENTV_SKY_ITALIA },
-    { N_("Only OpenTV Sky Ausat"),    MM_EPG_ONLY_OPENTV_SKY_AUSAT },
+    { N_("Manual selection"),         MM_EPG_MANUAL },
   };
   return strtab2htsmsg(tab, 1, lang);
 }
 
+static htsmsg_t *
+mpegts_mux_epg_module_id_list ( void *o, const char *lang )
+{
+  return epggrab_ota_module_id_list(lang);
+}
+
 static htsmsg_t *
 mpegts_mux_ac3_list ( void *o, const char *lang )
 {
@@ -544,6 +542,16 @@ const idclass_t mpegts_mux_class =
       .list     = mpegts_mux_epg_list,
       .opts     = PO_DOC_NLIST,
     },
+    {
+      .type     = PT_STR,
+      .id       = "epg_module_id",
+      .name     = N_("EPG module id"),
+      .desc     = N_("The EPG grabber to use on the mux. "
+                     "The 'EPG scan' field must be set to 'manual'."),
+      .off      = offsetof(mpegts_mux_t, mm_epg_module_id),
+      .list     = mpegts_mux_epg_module_id_list,
+      .opts     = PO_DOC_NLIST,
+    },
     {
       .type     = PT_STR,
       .id       = "network",
@@ -755,6 +763,7 @@ mpegts_mux_free ( mpegts_mux_t *mm )
   free(mm->mm_provider_network_name);
   free(mm->mm_crid_authority);
   free(mm->mm_charset);
+  free(mm->mm_epg_module_id);
   free(mm->mm_nicename);
   free(mm);
 }