]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
api/ui: status - show the PID lists for subscriptions and inputs, fixes #4934
authorJaroslav Kysela <perex@perex.cz>
Tue, 2 Oct 2018 16:18:51 +0000 (18:18 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 2 Oct 2018 16:19:07 +0000 (18:19 +0200)
Original idea and implementation by Mono Polimorph

src/input.c
src/input.h
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_service.c
src/service.h
src/subscriptions.c
src/webui/static/app/status.js

index 7774c34547012ffc55eda2582054601810b5cb8e..d8c825a9606b998e4d8df30e1cc3fa5f2c997e9f 100644 (file)
@@ -113,6 +113,10 @@ tvh_input_stream_create_msg
   ( tvh_input_stream_t *st )
 {
   htsmsg_t *m = htsmsg_create_map();
+  htsmsg_t *l = NULL;
+  mpegts_apids_t *pids;
+  int i;
+
   htsmsg_add_str(m, "uuid", st->uuid);
   if (st->input_name)
     htsmsg_add_str(m, "input",  st->input_name);
@@ -120,6 +124,16 @@ tvh_input_stream_create_msg
     htsmsg_add_str(m, "stream", st->stream_name);
   htsmsg_add_u32(m, "subs", st->subs_count);
   htsmsg_add_u32(m, "weight", st->max_weight);
+  if ((pids = st->pids) != NULL) {
+    l = htsmsg_create_list();
+    if (pids->all) {
+      htsmsg_add_u32(l, NULL, 65535);
+    } else {
+      for (i = 0; i < pids->count; i++)
+        htsmsg_add_u32(l, NULL, pids->pids[i].pid);
+    }
+    htsmsg_add_msg(m, "pids", l);
+  }
   htsmsg_add_s32(m, "signal", st->stats.signal);
   htsmsg_add_u32(m, "signal_scale", st->stats.signal_scale);
   htsmsg_add_u32(m, "ber", st->stats.ber);
@@ -143,4 +157,5 @@ tvh_input_stream_destroy
   free(st->uuid);
   free(st->input_name);
   free(st->stream_name);
+  mpegts_pid_destroy(&st->pids);
 }
index 516f850ef9193117dc9c8a8005a15ea05f5f6977..d65b516e96663cf7a4093f04490e8172fa7b02e6 100644 (file)
@@ -24,6 +24,7 @@
 #include "streaming.h"
 
 struct htsmsg;
+struct mpegts_apids;
 
 /*
  * Type-defs
@@ -77,6 +78,8 @@ struct tvh_input_stream {
   int   subs_count;   ///< Number of subcscriptions
   int   max_weight;   ///< Current max weight
 
+  struct mpegts_apids *pids; ///< active PID list
+
   tvh_input_stream_stats_t stats;
 };
 
@@ -90,6 +93,7 @@ struct tvh_input {
 
   void (*ti_get_streams) (tvh_input_t *, tvh_input_stream_list_t*);
   void (*ti_clear_stats) (tvh_input_t *);
+
   struct htsmsg *(*ti_wizard_get) (tvh_input_t *, const char *);
   void (*ti_wizard_set)  (tvh_input_t *, struct htsmsg *, const char *);
 };
index 39ed536cea26e9944f284b957593f46f9722cd7a..aef0e2afd4153622537f3253595510e23d591eaa 100644 (file)
@@ -851,7 +851,8 @@ mpegts_input_open_service
     TAILQ_FOREACH(st, &s->s_components.set_filter, es_filter_link)
       if ((s->s_scrambled_pass || st->es_type != SCT_CA) &&
           st->es_pid != s->s_components.set_pmt_pid &&
-          st->es_pid != s->s_components.set_pcr_pid) {
+          st->es_pid != s->s_components.set_pcr_pid &&
+          st->es_pid < 8192) {
         st->es_pid_opened = 1;
         mpegts_input_open_pid(mi, mm, st->es_pid, MPS_SERVICE, mpegts_mps_weight(st), s, reopen);
       }
@@ -1824,6 +1825,7 @@ mpegts_input_stream_status
   const service_t *t;
   mpegts_mux_t *mm = mmi->mmi_mux;
   mpegts_input_t *mi = mmi->mmi_input;
+  mpegts_pid_t *mp;
 
   LIST_FOREACH(t, &mm->mm_transports, s_active_link)
     if (((mpegts_service_t *)t)->s_dvb_mux == mm)
@@ -1839,6 +1841,17 @@ mpegts_input_stream_status
   st->stream_name = strdup(buf);
   st->subs_count  = s;
   st->max_weight  = w;
+
+  st->pids = mpegts_pid_alloc();
+  RB_FOREACH(mp, &mm->mm_pids, mp_link) {
+    if (mp->mp_pid == MPEGTS_TABLES_PID)
+      continue;
+    if (mp->mp_pid == MPEGTS_FULLMUX_PID)
+      st->pids->all = 1;
+    else
+      mpegts_pid_add(st->pids, mp->mp_pid, 0);
+  }
+
   pthread_mutex_lock(&mmi->tii_stats_mutex);
   st->stats.signal = mmi->tii_stats.signal;
   st->stats.snr    = mmi->tii_stats.snr;
index afef1d58cac39ad79b1d748773c8f13bb4a5ed91..b8da15ff712cb38973dc3b2c6d7cc6568e4e9a1e 100644 (file)
@@ -767,6 +767,39 @@ mpegts_service_satip_source ( service_t *t )
   return mn ? mn->mn_satip_source : -1;
 }
 
+static mpegts_apids_t *
+mpegts_service_pid_list_ ( service_t *t, void *owner )
+{
+  mpegts_service_t *ms = (mpegts_service_t*)t;
+  mpegts_apids_t *pids = NULL;
+  mpegts_input_t *mi = ms->s_dvb_active_input;
+  mpegts_mux_t *mm;
+  mpegts_pid_sub_t *mps;
+  mpegts_pid_t *mp;
+
+  if (mi == NULL) return NULL;
+  pthread_mutex_lock(&mi->mi_output_lock);
+  mm = ms->s_dvb_mux;
+  RB_FOREACH(mp, &mm->mm_pids, mp_link) {
+    RB_FOREACH(mps, &mp->mp_subs, mps_link) {
+      if (owner == NULL || mps->mps_owner == owner) {
+        if (pids == NULL)
+          pids = mpegts_pid_alloc();
+        mpegts_pid_add(pids, mp->mp_pid, 0);
+        break;
+      }
+    }
+  }
+  pthread_mutex_unlock(&mi->mi_output_lock);
+  return pids;
+}
+
+static mpegts_apids_t *
+mpegts_service_pid_list ( service_t *t )
+{
+  return mpegts_service_pid_list_(t, t);
+}
+
 static void
 mpegts_service_memoryinfo ( service_t *t, int64_t *size )
 {
@@ -843,6 +876,7 @@ mpegts_service_create0
   s->s_channel_icon   = mpegts_service_channel_icon;
   s->s_mapped         = mpegts_service_mapped;
   s->s_satip_source   = mpegts_service_satip_source;
+  s->s_pid_list       = mpegts_service_pid_list;
   s->s_memoryinfo     = mpegts_service_memoryinfo;
   s->s_unseen         = mpegts_service_unseen;
 
@@ -1116,6 +1150,12 @@ mpegts_service_unlink ( mpegts_service_t *master, mpegts_service_t *slave )
   return 0;
 }
 
+static mpegts_apids_t *
+mpegts_service_raw_pid_list ( service_t *t )
+{
+  return mpegts_service_pid_list_(t, NULL);
+}
+
 mpegts_service_t *
 mpegts_service_create_raw ( mpegts_mux_t *mm )
 {
@@ -1151,6 +1191,7 @@ mpegts_service_create_raw ( mpegts_mux_t *mm )
   s->s_link           = mpegts_service_link;
   s->s_unlink         = mpegts_service_unlink;
   s->s_satip_source   = mpegts_service_satip_source;
+  s->s_pid_list       = mpegts_service_raw_pid_list;
   s->s_memoryinfo     = mpegts_service_memoryinfo;
 
   pthread_mutex_lock(&s->s_stream_mutex);
index ed659ca56882af3be63ee8146186d695127610fe..e9ed280702a72aa3879cb21b5c7cb36fecce40af 100644 (file)
@@ -43,6 +43,7 @@ struct mpegts_apids;
 struct profile_chain;
 struct source_info;
 struct descramble_info;
+struct mpegts_apids;
 
 /**
  *
@@ -225,6 +226,8 @@ typedef struct service {
 
   void (*s_unref)(struct service *t);
 
+  struct mpegts_apids *(*s_pid_list)(struct service *t);
+
   int (*s_satip_source)(struct service *t);
 
   void (*s_memoryinfo)(struct service *t, int64_t *size);
index 544b8d3ab1ea653cb9f62044fc7620e4e27f573d..8c977725c76d24daccd9aa967da0d9b073de33fc 100644 (file)
@@ -1020,6 +1020,8 @@ subscription_create_msg(th_subscription_t *s, const char *lang)
   profile_t *pro;
   char buf[284];
   const char *state;
+  htsmsg_t *l;
+  mpegts_apids_t *pids = NULL;
 
   htsmsg_add_u32(m, "id", s->ths_id);
   htsmsg_add_u32(m, "start", s->ths_start);
@@ -1045,25 +1047,25 @@ subscription_create_msg(th_subscription_t *s, const char *lang)
 
   htsmsg_add_str(m, "state", lang ? tvh_gettext_lang(lang, state) : state);
 
-  if(s->ths_hostname != NULL)
+  if (s->ths_hostname != NULL)
     htsmsg_add_str(m, "hostname", s->ths_hostname);
 
-  if(s->ths_username != NULL)
+  if (s->ths_username != NULL)
     htsmsg_add_str(m, "username", s->ths_username);
 
-  if(s->ths_client != NULL)
+  if (s->ths_client != NULL)
     htsmsg_add_str(m, "title", s->ths_client);
-  else if(s->ths_title != NULL)
+  else if (s->ths_title != NULL)
     htsmsg_add_str(m, "title", s->ths_title);
   
-  if(s->ths_channel != NULL)
+  if (s->ths_channel != NULL)
     htsmsg_add_str(m, "channel", channel_get_name(s->ths_channel, tvh_gettext_lang(lang, channel_blank_name)));
   
-  if((t = s->ths_service) != NULL) {
+  if ((t = s->ths_service) != NULL) {
     htsmsg_add_str(m, "service", service_adapter_nicename(t, buf, sizeof(buf)));
 
     pthread_mutex_lock(&t->s_stream_mutex);
-    if ((di = s->ths_service->s_descramble_info) != NULL) {
+    if ((di = t->s_descramble_info) != NULL) {
       if (di->caid == 0 && di->ecmtime == 0) {
         snprintf(buf, sizeof(buf), N_("Failed"));
       } else {
@@ -1075,6 +1077,23 @@ subscription_create_msg(th_subscription_t *s, const char *lang)
     }
     pthread_mutex_unlock(&t->s_stream_mutex);
 
+    if (t->s_pid_list) {
+      pids = t->s_pid_list(t);
+      if (pids) {
+        l = htsmsg_create_list();
+        if (pids->all) {
+          htsmsg_add_u32(l, NULL, 65535);
+        } else {
+          int i;
+          for (i = 0; i < pids->count; i++) {
+            htsmsg_add_u32(l, NULL, pids->pids[i].pid);
+          }
+        }
+        htsmsg_add_msg(m, "pids", l);
+        mpegts_pid_destroy(&pids);
+      }
+    }
+
     if (s->ths_prch != NULL) {
       pro = s->ths_prch->prch_pro;
       if (pro)
@@ -1082,8 +1101,9 @@ subscription_create_msg(th_subscription_t *s, const char *lang)
                        idnode_get_title(&pro->pro_id, lang, buf, sizeof(buf)));
     }
 
-  } else if(s->ths_dvrfile != NULL)
+  } else if (s->ths_dvrfile != NULL) {
     htsmsg_add_str(m, "service", s->ths_dvrfile ?: "");
+  }
 
   htsmsg_add_u32(m, "in", atomic_get(&s->ths_bytes_in_avg));
   htsmsg_add_u32(m, "out", atomic_get(&s->ths_bytes_out_avg));
index 5ee90a50d862f8220e2e4d8ea33e2f6cfbb43bda..3dda9067c582db8588232383df89b50b89238ae6 100644 (file)
@@ -20,6 +20,7 @@ tvheadend.status_subs = function(panel, index)
             r.data.channel = m.channel;
             r.data.service = m.service;
             r.data.state = m.state;
+            if (m.pids) r.data.pids = m.pids;
             if (m.descramble) r.data.descramble = m.descramble;
             if (m.profile) r.data.profile = m.profile;
             r.data.errors = m.errors;
@@ -49,6 +50,7 @@ tvheadend.status_subs = function(panel, index)
                 { name: 'service', sortType: stype },
                 { name: 'profile', sortType: stype },
                 { name: 'state', sortType: stype },
+                { name: 'pids' },
                 { name: 'descramble', sortType: stype },
                 { name: 'errors', sortType: stypei },
                 { name: 'in', sortType: stypei },
@@ -115,7 +117,7 @@ tvheadend.status_subs = function(panel, index)
                 sortable: true
             },
             {
-                width: 250,
+                width: 210,
                 id: 'service',
                 header: _("Service"),
                 dataIndex: 'service',
@@ -146,6 +148,23 @@ tvheadend.status_subs = function(panel, index)
                 dataIndex: 'state',
                 sortable: true
             },
+            {
+                width: 90,
+                id: 'pids',
+                header: _("PID list"),
+                dataIndex: 'pids',
+                sortable: false,
+                renderer: function(v) {
+                    var r = [];
+                    Ext.each(v, function(pid) {
+                      r.push(pid);
+                    });
+                    if (r.length < 1) return "";
+                    r.sort(function(a, b){return a-b});
+                    if (r[r.length - 1] == 65535) return _("all");
+                    return r.join(',');
+                }
+            },
             {
                 width: 80,
                 id: 'descramble',
@@ -258,6 +277,7 @@ tvheadend.status_streams = function(panel, index)
         }
         r.data.subs = m.subs;
         r.data.weight = m.weight;
+        r.data.pids = m.pids;
         r.data.signal = m.signal;
         r.data.ber = m.ber;
         r.data.unc = m.unc;
@@ -319,6 +339,7 @@ tvheadend.status_streams = function(panel, index)
                 { name: 'stream', sortType: stype },
                 { name: 'subs', sortType: stypei },
                 { name: 'weight', sortType: stypei },
+                { name: 'pids' },
                 { name: 'signal', sortType: stypei },
                 { name: 'ber', sortType: stypei },
                 { name: 'unc', sortType: stypei },
@@ -391,6 +412,23 @@ tvheadend.status_streams = function(panel, index)
                 dataIndex: 'weight',
                 sortable: true
             },
+            {
+                width: 100,
+                id: 'pids',
+                header: _("PID list"),
+                dataIndex: 'pids',
+                sortable: false,
+                renderer: function(v) {
+                    var r = [];
+                    Ext.each(v, function(pid) {
+                      r.push(pid);
+                    });
+                    if (r.length < 1) return "";
+                    r.sort(function(a, b){return a-b});
+                    if (r[r.length - 1] == 65535) return _("all");
+                    return r.join(',');
+                }
+            },
             {
                 width: 50,
                 header: _("Bandwidth (kb/s)"),