From 4eb80bd1c1e6dfafe59ad0fd3247db1a13316f65 Mon Sep 17 00:00:00 2001 From: Sergey Linnik Date: Fri, 31 Aug 2012 01:35:39 +0400 Subject: [PATCH] Add "Skip service availability check when mapping" option --- src/dvb/dvb.h | 6 +- src/dvb/dvb_adapter.c | 19 +++++ src/serviceprobe.c | 161 +++++++++++++++++++----------------- src/webui/extjs_dvb.c | 4 + src/webui/static/app/dvb.js | 8 +- 5 files changed, 119 insertions(+), 79 deletions(-) diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 958eb845..d1bb3117 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -174,6 +174,8 @@ typedef struct th_dvb_adapter { char *tda_identifier; uint32_t tda_autodiscovery; uint32_t tda_idlescan; + uint32_t tda_skip_initialscan; + uint32_t tda_skip_checksubscr; uint32_t tda_qmon; uint32_t tda_poweroff; uint32_t tda_nitoid; @@ -219,8 +221,6 @@ typedef struct th_dvb_adapter { uint32_t tda_extrapriority; // extra priority for choosing the best adapter/service - uint32_t tda_skip_initialscan; // skip the initial scan - } th_dvb_adapter_t; /** @@ -285,6 +285,8 @@ void dvb_adapter_set_skip_initialscan(th_dvb_adapter_t *tda, int on); void dvb_adapter_set_idlescan(th_dvb_adapter_t *tda, int on); +void dvb_adapter_set_skip_checksubscr(th_dvb_adapter_t *tda, int on); + void dvb_adapter_set_qmon(th_dvb_adapter_t *tda, int on); void dvb_adapter_set_dump_muxes(th_dvb_adapter_t *tda, int on); diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index 3c8b140c..302fd8e1 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -85,6 +85,7 @@ tda_save(th_dvb_adapter_t *tda) htsmsg_add_str(m, "displayname", tda->tda_displayname); htsmsg_add_u32(m, "autodiscovery", tda->tda_autodiscovery); htsmsg_add_u32(m, "idlescan", tda->tda_idlescan); + htsmsg_add_u32(m, "skip_checksubscr", tda->tda_skip_checksubscr); htsmsg_add_u32(m, "qmon", tda->tda_qmon); htsmsg_add_u32(m, "dump_muxes", tda->tda_dump_muxes); htsmsg_add_u32(m, "poweroff", tda->tda_poweroff); @@ -176,6 +177,23 @@ dvb_adapter_set_idlescan(th_dvb_adapter_t *tda, int on) tda_save(tda); } +/** + * + */ +void +dvb_adapter_set_skip_checksubscr(th_dvb_adapter_t *tda, int on) +{ + if(tda->tda_skip_checksubscr == on) + return; + + lock_assert(&global_lock); + + tvhlog(LOG_NOTICE, "dvb", "Adapter \"%s\" skip service availability check when mapping set to: %s", + tda->tda_displayname, on ? "On" : "Off"); + + tda->tda_skip_checksubscr = on; + tda_save(tda); +} /** * @@ -440,6 +458,7 @@ dvb_adapter_init(uint32_t adapter_mask) htsmsg_get_u32(c, "autodiscovery", &tda->tda_autodiscovery); htsmsg_get_u32(c, "idlescan", &tda->tda_idlescan); + htsmsg_get_u32(c, "skip_checksubscr", &tda->tda_skip_checksubscr); htsmsg_get_u32(c, "qmon", &tda->tda_qmon); htsmsg_get_u32(c, "dump_muxes", &tda->tda_dump_muxes); htsmsg_get_u32(c, "poweroff", &tda->tda_poweroff); diff --git a/src/serviceprobe.c b/src/serviceprobe.c index 9deb43d5..68c70db4 100644 --- a/src/serviceprobe.c +++ b/src/serviceprobe.c @@ -24,15 +24,13 @@ #include #include - - - #include "tvheadend.h" #include "channels.h" #include "subscriptions.h" #include "serviceprobe.h" #include "streaming.h" #include "service.h" +#include "dvb/dvb.h" /* List of transports to be probed, protected with global_lock */ static struct service_queue serviceprobe_queue; @@ -87,6 +85,7 @@ serviceprobe_thread(void *aux) int run; const char *err; channel_t *ch; + uint32_t checksubscr; pthread_mutex_lock(&global_lock); @@ -98,8 +97,8 @@ serviceprobe_thread(void *aux) while((t = TAILQ_FIRST(&serviceprobe_queue)) == NULL) { if(was_doing_work) { - tvhlog(LOG_INFO, "serviceprobe", "Now idle"); - was_doing_work = 0; + tvhlog(LOG_INFO, "serviceprobe", "Now idle"); + was_doing_work = 0; } pthread_cond_wait(&serviceprobe_cond, &global_lock); } @@ -109,102 +108,114 @@ serviceprobe_thread(void *aux) was_doing_work = 1; } - tvhlog(LOG_INFO, "serviceprobe", "%20s: checking...", - t->s_svcname); + checksubscr = !t->s_dvb_mux_instance->tdmi_adapter->tda_skip_checksubscr; - s = subscription_create_from_service(t, "serviceprobe", &sq.sq_st, 0); - if(s == NULL) { - t->s_sp_onqueue = 0; - TAILQ_REMOVE(&serviceprobe_queue, t, s_sp_link); - tvhlog(LOG_INFO, "serviceprobe", "%20s: could not subscribe", - t->s_svcname); - continue; + if (checksubscr) { + tvhlog(LOG_INFO, "serviceprobe", "%20s: checking...", + t->s_svcname); + + s = subscription_create_from_service(t, "serviceprobe", &sq.sq_st, 0); + if(s == NULL) { + t->s_sp_onqueue = 0; + TAILQ_REMOVE(&serviceprobe_queue, t, s_sp_link); + tvhlog(LOG_INFO, "serviceprobe", "%20s: could not subscribe", + t->s_svcname); + continue; + } } service_ref(t); pthread_mutex_unlock(&global_lock); - run = 1; - pthread_mutex_lock(&sq.sq_mutex); + if (checksubscr) { + run = 1; + pthread_mutex_lock(&sq.sq_mutex); - while(run) { + while(run) { - while((sm = TAILQ_FIRST(&sq.sq_queue)) == NULL) - pthread_cond_wait(&sq.sq_cond, &sq.sq_mutex); - TAILQ_REMOVE(&sq.sq_queue, sm, sm_link); + while((sm = TAILQ_FIRST(&sq.sq_queue)) == NULL) + pthread_cond_wait(&sq.sq_cond, &sq.sq_mutex); - pthread_mutex_unlock(&sq.sq_mutex); + TAILQ_REMOVE(&sq.sq_queue, sm, sm_link); - if(sm->sm_type == SMT_SERVICE_STATUS) { - int status = sm->sm_code; + pthread_mutex_unlock(&sq.sq_mutex); - if(status & TSS_PACKETS) { - run = 0; - err = NULL; - } else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) { - run = 0; - err = service_tss2text(status); - } + if(sm->sm_type == SMT_SERVICE_STATUS) { + int status = sm->sm_code; + + if(status & TSS_PACKETS) { + run = 0; + err = NULL; + } else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) { + run = 0; + err = service_tss2text(status); + } + } + + streaming_msg_free(sm); + pthread_mutex_lock(&sq.sq_mutex); } - streaming_msg_free(sm); - pthread_mutex_lock(&sq.sq_mutex); + streaming_queue_clear(&sq.sq_queue); + pthread_mutex_unlock(&sq.sq_mutex); + } else { + err = NULL; } - - streaming_queue_clear(&sq.sq_queue); - pthread_mutex_unlock(&sq.sq_mutex); - + pthread_mutex_lock(&global_lock); - subscription_unsubscribe(s); + + if (checksubscr) { + subscription_unsubscribe(s); + } if(t->s_status != SERVICE_ZOMBIE) { if(err != NULL) { - tvhlog(LOG_INFO, "serviceprobe", "%20s: skipped: %s", - t->s_svcname, err); + tvhlog(LOG_INFO, "serviceprobe", "%20s: skipped: %s", + t->s_svcname, err); } else if(t->s_ch == NULL) { - const char *str; + const char *str; - ch = channel_find_by_name(t->s_svcname, 1, t->s_channel_number); - service_map_channel(t, ch, 1); + ch = channel_find_by_name(t->s_svcname, 1, t->s_channel_number); + service_map_channel(t, ch, 1); - tvhlog(LOG_INFO, "serviceprobe", "%20s: mapped to channel \"%s\"", - t->s_svcname, t->s_svcname); + tvhlog(LOG_INFO, "serviceprobe", "%20s: mapped to channel \"%s\"", + t->s_svcname, t->s_svcname); - if(service_is_tv(t)) { - channel_tag_map(ch, channel_tag_find_by_name("TV channels", 1), 1); - tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", - t->s_svcname, "TV channels"); - } + if(service_is_tv(t)) { + channel_tag_map(ch, channel_tag_find_by_name("TV channels", 1), 1); + tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", + t->s_svcname, "TV channels"); + } - switch(t->s_servicetype) { - case ST_SDTV: - case ST_AC_SDTV: - str = "SDTV"; - break; - case ST_HDTV: - case ST_AC_HDTV: - str = "HDTV"; - break; - case ST_RADIO: - str = "Radio"; - break; - default: - str = NULL; - } + switch(t->s_servicetype) { + case ST_SDTV: + case ST_AC_SDTV: + str = "SDTV"; + break; + case ST_HDTV: + case ST_AC_HDTV: + str = "HDTV"; + break; + case ST_RADIO: + str = "Radio"; + break; + default: + str = NULL; + } - if(str != NULL) { - channel_tag_map(ch, channel_tag_find_by_name(str, 1), 1); - tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", - t->s_svcname, str); - } + if(str != NULL) { + channel_tag_map(ch, channel_tag_find_by_name(str, 1), 1); + tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", + t->s_svcname, str); + } - if(t->s_provider != NULL) { - channel_tag_map(ch, channel_tag_find_by_name(t->s_provider, 1), 1); - tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", - t->s_svcname, t->s_provider); - } - channel_save(ch); + if(t->s_provider != NULL) { + channel_tag_map(ch, channel_tag_find_by_name(t->s_provider, 1), 1); + tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", + t->s_svcname, t->s_provider); + } + channel_save(ch); } t->s_sp_onqueue = 0; diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index 84f9d87f..4b0dc002 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -150,6 +150,7 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) htsmsg_add_u32(r, "automux", tda->tda_autodiscovery); htsmsg_add_u32(r, "skip_initialscan", tda->tda_skip_initialscan); htsmsg_add_u32(r, "idlescan", tda->tda_idlescan); + htsmsg_add_u32(r, "skip_checksubscr", tda->tda_skip_checksubscr); htsmsg_add_u32(r, "qmon", tda->tda_qmon); htsmsg_add_u32(r, "dumpmux", tda->tda_dump_muxes); htsmsg_add_u32(r, "poweroff", tda->tda_poweroff); @@ -175,6 +176,9 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) s = http_arg_get(&hc->hc_req_args, "idlescan"); dvb_adapter_set_idlescan(tda, !!s); + s = http_arg_get(&hc->hc_req_args, "skip_checksubscr"); + dvb_adapter_set_skip_checksubscr(tda, !!s); + s = http_arg_get(&hc->hc_req_args, "qmon"); dvb_adapter_set_qmon(tda, !!s); diff --git a/src/webui/static/app/dvb.js b/src/webui/static/app/dvb.js index 6f793e88..61b46ce4 100644 --- a/src/webui/static/app/dvb.js +++ b/src/webui/static/app/dvb.js @@ -252,7 +252,7 @@ tvheadend.dvb_muxes = function(adapterData, satConfStore) { } } } - }), + }) ]; if (satConf) @@ -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', - 'dumpmux', 'poweroff', 'nitoid','extrapriority']); + 'skip_checksubscr', 'dumpmux', 'poweroff', 'nitoid','extrapriority']); function saveConfForm () { @@ -1135,6 +1135,10 @@ tvheadend.dvb_adapter_general = function(adapterData, satConfStore) { fieldLabel: 'Idle scanning', name: 'idlescan' }), + new Ext.form.Checkbox({ + fieldLabel: 'Skip service availability check when mapping', + name: 'skip_checksubscr' + }), new Ext.form.Checkbox({ fieldLabel: 'Monitor signal quality', name: 'qmon'