From b5cfa017895dce20b7b05d48692897ea37e62580 Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Sat, 25 Aug 2012 23:26:12 +0100 Subject: [PATCH] Add option to disable PMT monitoring to reduce PID filters used. Fixes #194. --- src/dvb/dvb.h | 12 ++++++++++++ src/dvb/dvb_adapter.c | 21 +++++++++++++++++++++ src/dvb/dvb_tables.c | 31 +++++++++++++++++++++++++------ src/dvb/dvb_transport.c | 10 ++++++++++ src/webui/extjs_dvb.c | 4 ++++ src/webui/static/app/dvb.js | 6 +++++- 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 0f769ec2..b1fb734e 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -181,6 +181,7 @@ typedef struct th_dvb_adapter { uint32_t tda_sidtochan; uint32_t tda_nitoid; uint32_t tda_diseqc_version; + uint32_t tda_disable_pmt_monitor; char *tda_displayname; int tda_fe_fd; @@ -300,6 +301,8 @@ void dvb_adapter_set_nitoid(th_dvb_adapter_t *tda, int nitoid); void dvb_adapter_set_diseqc_version(th_dvb_adapter_t *tda, unsigned int v); +void dvb_adapter_set_disable_pmt_monitor(th_dvb_adapter_t *tda, int on); + void dvb_adapter_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src); void dvb_adapter_clean(th_dvb_adapter_t *tda); @@ -386,6 +389,10 @@ struct service *dvb_transport_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, const char *identifier); +struct service *dvb_transport_find2(th_dvb_mux_instance_t *tdmi, + uint16_t sid, int pmt_pid, + const char *identifier, int *save); + void dvb_transport_notify(struct service *t); void dvb_transport_notify_by_adapter(th_dvb_adapter_t *tda); @@ -409,7 +416,12 @@ void dvb_table_add_default(th_dvb_mux_instance_t *tdmi); void dvb_table_flush_all(th_dvb_mux_instance_t *tdmi); +void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid); + +void dvb_table_rem_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid); + struct dmx_sct_filter_params *dvb_fparams_alloc(void); + void tdt_add(th_dvb_mux_instance_t *tdmi, struct dmx_sct_filter_params *fparams, int (*callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index 73d852c4..cb5ae097 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -93,6 +93,7 @@ tda_save(th_dvb_adapter_t *tda) htsmsg_add_u32(m, "diseqc_version", tda->tda_diseqc_version); htsmsg_add_u32(m, "extrapriority", tda->tda_extrapriority); htsmsg_add_u32(m, "skip_initialscan", tda->tda_skip_initialscan); + htsmsg_add_u32(m, "disable_pmt_monitor", tda->tda_disable_pmt_monitor); hts_settings_save(m, "dvbadapters/%s", tda->tda_identifier); htsmsg_destroy(m); } @@ -329,6 +330,25 @@ dvb_adapter_set_extrapriority(th_dvb_adapter_t *tda, int extrapriority) tda_save(tda); } +/** + * + */ +void +dvb_adapter_set_disable_pmt_monitor(th_dvb_adapter_t *tda, int on) +{ + if(tda->tda_disable_pmt_monitor == on) + return; + + lock_assert(&global_lock); + + tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" disabled PMT monitoring set to: %s", + tda->tda_displayname, on ? "On" : "Off"); + + tda->tda_disable_pmt_monitor = on; + tda_save(tda); +} + + /** * */ @@ -483,6 +503,7 @@ dvb_adapter_init(uint32_t adapter_mask) htsmsg_get_u32(c, "diseqc_version", &tda->tda_diseqc_version); htsmsg_get_u32(c, "extrapriority", &tda->tda_extrapriority); htsmsg_get_u32(c, "skip_initialscan", &tda->tda_skip_initialscan); + htsmsg_get_u32(c, "disable_pmt_monitor", &tda->tda_disable_pmt_monitor); } htsmsg_destroy(l); } diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index c58913d1..cee8bae1 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -42,8 +42,6 @@ #include "notify.h" #include "cwc.h" -static void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid); - static int tdt_id_tally; /** @@ -520,8 +518,10 @@ dvb_pat_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, pmt = (ptr[2] & 0x1f) << 8 | ptr[3]; if(service != 0 && pmt != 0) { - dvb_transport_find(tdmi, service, pmt, NULL); - dvb_table_add_pmt(tdmi, pmt); + int save = 0; + dvb_transport_find2(tdmi, service, pmt, NULL, &save); + if (save || !tda->tda_disable_pmt_monitor) + dvb_table_add_pmt(tdmi, pmt); } ptr += 4; len -= 4; @@ -985,13 +985,21 @@ static int dvb_pmt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, uint8_t tableid, void *opaque) { + int active = 0; service_t *t; + th_dvb_table_t *tdt = opaque; LIST_FOREACH(t, &tdmi->tdmi_transports, s_group_link) { pthread_mutex_lock(&t->s_stream_mutex); psi_parse_pmt(t, ptr, len, 1, 1); + if (t->s_pmt_pid == tdt->tdt_pid && t->s_status == SERVICE_RUNNING) + active = 1; pthread_mutex_unlock(&t->s_stream_mutex); } + + if (tdmi->tdmi_adapter->tda_disable_pmt_monitor && !active) + dvb_tdt_destroy(tdmi->tdmi_adapter, tdmi, tdt); + return 0; } @@ -1101,7 +1109,7 @@ dvb_table_add_default(th_dvb_mux_instance_t *tdmi) /** * Setup FD + demux for a services PMT */ -static void +void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid) { struct dmx_sct_filter_params *fp; @@ -1112,7 +1120,18 @@ dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid) fp->filter.filter[0] = 0x02; fp->filter.mask[0] = 0xff; tdt_add(tdmi, fp, dvb_pmt_callback, NULL, pmtname, - TDT_CRC | TDT_QUICKREQ, pmt_pid, NULL); + TDT_CRC | TDT_QUICKREQ | TDT_TDT, pmt_pid, NULL); +} + +void +dvb_table_rem_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid) +{ + th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + th_dvb_table_t *tdt = NULL; + LIST_FOREACH(tdt, &tdmi->tdmi_tables, tdt_link) + if (tdt->tdt_pid == pmt_pid && tdt->tdt_callback == dvb_pmt_callback) + break; + if (tdt) dvb_tdt_destroy(tda, tdmi, tdt); } diff --git a/src/dvb/dvb_transport.c b/src/dvb/dvb_transport.c index 38f27768..1835d481 100644 --- a/src/dvb/dvb_transport.c +++ b/src/dvb/dvb_transport.c @@ -142,6 +142,8 @@ dvb_transport_start(service_t *t, unsigned int weight, int force_start) if(!r) dvb_transport_open_demuxers(tda, t); + dvb_table_add_pmt(tdmi, t->s_pmt_pid); + return r; } @@ -364,6 +366,13 @@ dvb_grace_period(service_t *t) service_t * dvb_transport_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, const char *identifier) +{ + return dvb_transport_find2(tdmi, sid, pmt_pid, identifier, NULL); +} + +service_t * +dvb_transport_find2(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, + const char *identifier, int *save) { service_t *t; char tmp[200]; @@ -388,6 +397,7 @@ dvb_transport_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, tvhlog(LOG_DEBUG, "dvb", "Add service \"%s\" on \"%s\"", identifier, buf); t = service_create(identifier, SERVICE_TYPE_DVB, S_MPEG_TS); + if (save) *save = 1; t->s_dvb_service_id = sid; t->s_pmt_pid = pmt_pid; diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index b5643e11..45bcb8d9 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -156,6 +156,7 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) htsmsg_add_u32(r, "poweroff", tda->tda_poweroff); htsmsg_add_u32(r, "sidtochan", tda->tda_sidtochan); htsmsg_add_u32(r, "nitoid", tda->tda_nitoid); + htsmsg_add_u32(r, "disable_pmt_monitor", tda->tda_disable_pmt_monitor); htsmsg_add_str(r, "diseqcversion", ((const char *[]){"DiSEqC 1.0 / 2.0", "DiSEqC 1.1 / 2.1"}) @@ -192,6 +193,9 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) s = http_arg_get(&hc->hc_req_args, "dumpmux"); dvb_adapter_set_dump_muxes(tda, !!s); + s = http_arg_get(&hc->hc_req_args, "disable_pmt_monitor"); + dvb_adapter_set_disable_pmt_monitor(tda, !!s); + if((s = http_arg_get(&hc->hc_req_args, "nitoid")) != NULL) dvb_adapter_set_nitoid(tda, atoi(s)); diff --git a/src/webui/static/app/dvb.js b/src/webui/static/app/dvb.js index ebaea6a7..649ddb2f 100644 --- a/src/webui/static/app/dvb.js +++ b/src/webui/static/app/dvb.js @@ -1106,7 +1106,7 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { var confreader = new Ext.data.JsonReader({ root: 'dvbadapters' }, ['name', 'automux', 'skip_initialscan', 'idlescan', 'diseqcversion', 'qmon', - 'skip_checksubscr', 'dumpmux', 'poweroff', 'sidtochan', 'nitoid','extrapriority']); + 'skip_checksubscr', 'dumpmux', 'poweroff', 'sidtochan', 'nitoid','extrapriority', 'disable_pmt_monitor']); function saveConfForm () { @@ -1143,6 +1143,10 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { fieldLabel: 'Monitor signal quality', name: 'qmon' }), + new Ext.form.Checkbox({ + fieldLabel: 'Disable PMT monitoring', + name: 'disable_pmt_monitor' + }), new Ext.form.Checkbox({ fieldLabel: 'Write full DVB MUX to disk', name: 'dumpmux',