From: Jaroslav Kysela Date: Tue, 2 Oct 2018 16:18:51 +0000 (+0200) Subject: api/ui: status - show the PID lists for subscriptions and inputs, fixes #4934 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c50a763f630f91d5a0ee6687890b631c619a21f;p=thirdparty%2Ftvheadend.git api/ui: status - show the PID lists for subscriptions and inputs, fixes #4934 Original idea and implementation by Mono Polimorph --- diff --git a/src/input.c b/src/input.c index 7774c3454..d8c825a96 100644 --- a/src/input.c +++ b/src/input.c @@ -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); } diff --git a/src/input.h b/src/input.h index 516f850ef..d65b516e9 100644 --- a/src/input.h +++ b/src/input.h @@ -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 *); }; diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index 39ed536ce..aef0e2afd 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -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; diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index afef1d58c..b8da15ff7 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -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); diff --git a/src/service.h b/src/service.h index ed659ca56..e9ed28070 100644 --- a/src/service.h +++ b/src/service.h @@ -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); diff --git a/src/subscriptions.c b/src/subscriptions.c index 544b8d3ab..8c977725c 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -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)); diff --git a/src/webui/static/app/status.js b/src/webui/static/app/status.js index 5ee90a50d..3dda9067c 100644 --- a/src/webui/static/app/status.js +++ b/src/webui/static/app/status.js @@ -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)"),