From: Jaroslav Kysela Date: Sun, 20 Mar 2016 16:30:50 +0000 (+0100) Subject: SAT>IP client: override tuners with lower weight for master/slave config X-Git-Tag: v4.2.1~834 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60157d0dd06475d3c15859bed22cd11357724676;p=thirdparty%2Ftvheadend.git SAT>IP client: override tuners with lower weight for master/slave config --- diff --git a/src/input/mpegts.h b/src/input/mpegts.h index ff515ad21..0642d0b45 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -924,6 +924,7 @@ void mpegts_input_recv_packets int mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ); int mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ); int mpegts_input_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm ); +int mpegts_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ); void mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *c ); diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index a247bca66..d7fc92bd4 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -405,7 +405,7 @@ mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) return mi->mi_priority; } -static int +int mpegts_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { mpegts_mux_instance_t *cur; diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index e464985dc..840c665c0 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -451,22 +451,48 @@ satip_frontend_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm ) } static int -satip_frontend_match_satcfg ( satip_frontend_t *lfe2, mpegts_mux_t *mm2 ) +satip_frontend_get_max_weight ( satip_frontend_t *lfe, mpegts_mux_t *mm, int flags ) +{ + satip_frontend_t *lfe2; + int w = 0, w2; + + TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { + if (!lfe2->sf_running) continue; + if (lfe2->sf_type != DVB_TYPE_S) continue; + if (lfe2 != lfe) continue; + if (lfe->sf_master != lfe2->sf_number && + lfe2->sf_master != lfe->sf_number) continue; + w2 = lfe2->mi_get_weight((mpegts_input_t *)lfe2, mm, flags); + if (w2 > w) + w = w2; + } + return w; +} + +int +satip_frontend_match_satcfg + ( satip_frontend_t *lfe2, mpegts_mux_t *mm2, int flags, int weight ) { satip_frontend_t *lfe_master; mpegts_mux_t *mm1 = NULL; dvb_mux_conf_t *mc1, *mc2; - int position, high1, high2; + int position, weight2, high1, high2; - if (lfe2->sf_req == NULL || lfe2->sf_req->sf_mmi == NULL) + if (!lfe2->sf_running) return 0; lfe_master = lfe2; if (lfe2->sf_master) lfe_master = satip_frontend_find_by_number(lfe2->sf_device, lfe2->sf_master) ?: lfe2; + if (weight > 0) { + weight2 = satip_frontend_get_max_weight(lfe2, mm2, flags); + if (weight2 > 0 && weight2 < weight) + return 1; + } + mm1 = lfe2->sf_req->sf_mmi->mmi_mux; - position = satip_satconf_get_position(lfe2, mm2, NULL, 0); + position = satip_satconf_get_position(lfe2, mm2, NULL, 0, 0, -1); if (position <= 0 || lfe_master->sf_position != position) return 0; mc1 = &((dvb_mux_t *)mm1)->lm_tuning; @@ -479,7 +505,9 @@ satip_frontend_match_satcfg ( satip_frontend_t *lfe2, mpegts_mux_t *mm2 ) high2 = mc2->dmc_fe_freq > 11700000; if (high1 != high2) return 0; - return 1; + + /* return unique hash for the active satcfg greater than zero */ + return 1 | (high1 ? 2 : 0) | ((int)mc1->u.dmc_fe_qpsk.polarisation << 8) | (position << 16); } static int @@ -497,18 +525,18 @@ satip_frontend_is_enabled if (lfe->sf_type != DVB_TYPE_S) return 1; /* try to reuse any input for limited networks if allowed */ if (lfe->sf_device->sd_all_tuners) { - position = satip_satconf_get_position(lfe, mm, &netlimit, 0); + position = satip_satconf_get_position(lfe, mm, &netlimit, 0, 0, -1); if (position <= 0) return 0; if (netlimit <= 0) goto cont; /* try to reuse any tuner input as slave */ TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { if (lfe2 == lfe) continue; - if (satip_frontend_match_satcfg(lfe2, mm)) + if (satip_frontend_match_satcfg(lfe2, mm, flags, weight)) return 1; } } /* check if the position is enabled */ - position = satip_satconf_get_position(lfe, mm, NULL, 1); + position = satip_satconf_get_position(lfe, mm, NULL, 1, flags, weight); if (position <= 0) return 0; /* check if any "blocking" tuner is running */ @@ -519,13 +547,10 @@ cont: if (lfe->sf_master == lfe2->sf_number) { if (!lfe2->sf_running) return 0; /* master must be running */ - return satip_frontend_match_satcfg(lfe2, mm); - } - if (lfe2->sf_master == lfe->sf_number && lfe2->sf_running) { - if (lfe2->sf_req == NULL || lfe2->sf_req->sf_mmi == NULL) - return 0; - return satip_frontend_match_satcfg(lfe2, mm); + return satip_frontend_match_satcfg(lfe2, mm, flags, weight); } + if (lfe2->sf_master == lfe->sf_number && lfe2->sf_running) + return satip_frontend_match_satcfg(lfe2, mm, flags, weight); } return 1; } @@ -560,20 +585,34 @@ satip_frontend_stop_mux } static int -satip_frontend_start_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight ) +satip_frontend_warm_mux + ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { satip_frontend_t *lfe = (satip_frontend_t*)mi; - dvb_mux_t *lm = (dvb_mux_t *)mmi->mmi_mux; - satip_tune_req_t *tr; - char buf1[256], buf2[256]; + int r; + + r = mpegts_input_warm_mux(mi, mmi); + if (r) + return r; if (lfe->sf_positions > 0) { - lfe->sf_position = satip_satconf_get_position(lfe, mmi->mmi_mux, NULL, 0); + lfe->sf_position = satip_satconf_get_position(lfe, mmi->mmi_mux, NULL, 2, 0, -1); if (lfe->sf_position <= 0) return SM_CODE_TUNING_FAILED; } + return 0; +} + +static int +satip_frontend_start_mux + ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight ) +{ + satip_frontend_t *lfe = (satip_frontend_t*)mi; + dvb_mux_t *lm = (dvb_mux_t *)mmi->mmi_mux; + satip_tune_req_t *tr; + char buf1[256], buf2[256]; + lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1)); mpegts_mux_nice_name(mmi->mmi_mux, buf2, sizeof(buf2)); tvhdebug("satip", "%s - starting %s", buf1, buf2); @@ -1956,6 +1995,7 @@ satip_frontend_create lfe->ti_wizard_get = satip_frontend_wizard_get; lfe->ti_wizard_set = satip_frontend_wizard_set; lfe->mi_is_enabled = satip_frontend_is_enabled; + lfe->mi_warm_mux = satip_frontend_warm_mux; lfe->mi_start_mux = satip_frontend_start_mux; lfe->mi_stop_mux = satip_frontend_stop_mux; lfe->mi_network_list = satip_frontend_network_list; diff --git a/src/input/mpegts/satip/satip_private.h b/src/input/mpegts/satip/satip_private.h index a829f457e..347bcedb2 100644 --- a/src/input/mpegts/satip/satip_private.h +++ b/src/input/mpegts/satip/satip_private.h @@ -209,6 +209,9 @@ void satip_device_destroy_later( satip_device_t *sd, int after_ms ); char *satip_device_nicename ( satip_device_t *sd, char *buf, int len ); +int satip_frontend_match_satcfg + ( satip_frontend_t *lfe2, mpegts_mux_t *mm2, int flags, int weight ); + satip_frontend_t * satip_frontend_create ( htsmsg_t *conf, satip_device_t *sd, dvb_fe_type_t type, int v2, int num ); @@ -237,7 +240,7 @@ int satip_satconf_get_grace ( satip_frontend_t *lfe, mpegts_mux_t *mm ); int satip_satconf_get_position - ( satip_frontend_t *lfe, mpegts_mux_t *mm, int *netlimit, int check ); + ( satip_frontend_t *lfe, mpegts_mux_t *mm, int *netlimit, int check, int flags, int weight ); /* * RTSP part diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index d835f5a0b..de8d2513e 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -66,41 +66,121 @@ satip_satconf_get_grace } static int -satip_satconf_check_network_limit - ( satip_frontend_t *lfe, satip_satconf_t *sfc, idnode_t *mn ) +satip_satconf_master_or_slave + ( satip_frontend_t *lfe1, satip_frontend_t *lfe2 ) +{ + return lfe1->sf_number == lfe2->sf_master || + lfe2->sf_number == lfe1->sf_master; +} + +static int +satip_satconf_in_network_group + ( satip_frontend_t *lfe, int network_group, idnode_t *mn ) { - satip_frontend_t *lfe2; satip_satconf_t *sfc2; - int count; - count = 0; + TAILQ_FOREACH(sfc2, &lfe->sf_satconf, sfc_link) { + if (network_group > 0 && + sfc2->sfc_network_group > 0 && + sfc2->sfc_network_group == network_group) + break; + else if (idnode_set_exists(sfc2->sfc_networks, mn)) + break; + } + return sfc2 != NULL; +} + +static int +satip_satconf_check_limits + ( satip_frontend_t *lfe, satip_satconf_t *sfc, mpegts_mux_t *mm, + int flags, int weight, int manage ) +{ + satip_frontend_t *lfe2, *lowest_lfe; + mpegts_mux_t *mm2; + mpegts_input_t *mi2; + idnode_t *mn = &mm->mm_network->mn_id; + int count, size, lowest, w2, r, i, limit, *hashes; + + size = 0; TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) - TAILQ_FOREACH(sfc2, &lfe2->sf_satconf, sfc_link) { - if (!lfe2->sf_running) continue; - if (sfc->sfc_network_group > 0 && - sfc2->sfc_network_group > 0 && - sfc2->sfc_network_group == sfc->sfc_network_group) - count++; - else if (idnode_set_exists(sfc2->sfc_networks, mn)) + size++; + hashes = alloca(size * sizeof(int)); + + limit = sfc->sfc_network_limit > 0 ? sfc->sfc_network_limit : 1; + +retry: + memset(hashes, 0, size * sizeof(int)); + count = 1; + lowest = INT_MAX; + lowest_lfe = NULL; + TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { + if (lfe == lfe2 || !lfe2->sf_running || lfe2->sf_type != DVB_TYPE_S) + continue; + if (sfc->sfc_network_limit) { + if (!satip_satconf_in_network_group(lfe2, sfc->sfc_network_group, mn)) + continue; + } else { + if (!satip_satconf_master_or_slave(lfe, lfe2)) + continue; + } + mi2 = (mpegts_input_t *)lfe2; + mm2 = lfe2->sf_req->sf_mmi->mmi_mux; + if (weight > 0) { + w2 = lfe2->mi_get_weight(mi2, mm2, flags); + if (w2 < weight) + continue; + } else { + w2 = -1; + } + r = satip_frontend_match_satcfg(lfe2, mm, 0, -1); + if (r && manage) { + w2 = lfe2->mi_get_weight(mi2, mm2, flags);; + if (w2 < lowest) { + lowest = w2; + lowest_lfe = lfe2; + } + } + for (i = 0; i < size; i++) { + if (hashes[i] == r) + break; + if (!hashes[i]) { + hashes[i] = r; count++; + break; + } } - - return count <= sfc->sfc_network_limit; + } + if (count <= limit) + return 1; + if (manage) { + /* free tuner with lowest weight */ + mm2 = lowest_lfe->sf_req->sf_mmi->mmi_mux; + mm2->mm_stop(mm2, 1, SM_CODE_SUBSCRIPTION_OVERRIDDEN); + goto retry; + } + return 0; } int satip_satconf_get_position - ( satip_frontend_t *lfe, mpegts_mux_t *mm, int *netlimit, int check ) + ( satip_frontend_t *lfe, mpegts_mux_t *mm, int *netlimit, int check, int flags, int weight ) { satip_satconf_t *sfc; sfc = satip_satconf_find_ele(lfe, mm); if (sfc && sfc->sfc_enabled) { if (netlimit) *netlimit = sfc->sfc_network_limit; - if (!check || sfc->sfc_network_limit <= 0) + if (!check) return sfc->sfc_position; - if (satip_satconf_check_network_limit(lfe, sfc, &mm->mm_network->mn_id)) + if (check > 1) { + satip_satconf_check_limits(lfe, sfc, mm, flags, weight, 1); return sfc->sfc_position; + } else { + if (sfc->sfc_network_limit <= 0) + return sfc->sfc_position; + if (satip_satconf_check_limits(lfe, sfc, mm, flags, weight, 0)) + return sfc->sfc_position; + } } else { if (netlimit) *netlimit = 0;