From: Jaroslav Kysela Date: Mon, 21 Mar 2016 08:47:05 +0000 (+0100) Subject: SAT>IP client: block master tuners until slaves are fine X-Git-Tag: v4.2.1~833 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39df47d334e8dee1a1bb16bd210ccdf6d508a17f;p=thirdparty%2Ftvheadend.git SAT>IP client: block master tuners until slaves are fine --- diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 840c665c0..13c61c2bd 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -505,9 +505,7 @@ satip_frontend_match_satcfg high2 = mc2->dmc_fe_freq > 11700000; if (high1 != high2) return 0; - - /* 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); + return 1; } static int @@ -986,6 +984,39 @@ skip: return 0; } +static int +satip_frontend_other_is_waiting( satip_frontend_t *lfe ) +{ + satip_frontend_t *lfe2; + int r; + + TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { + if (lfe == lfe2) continue; + pthread_mutex_lock(&lfe2->sf_dvr_lock); + r = lfe2->sf_wait_for & (1 << lfe->sf_number); + pthread_mutex_unlock(&lfe2->sf_dvr_lock); + if (r) + return 1; + } + return 0; +} + +static void +satip_frontend_wake_other_waiting( satip_frontend_t *lfe ) +{ + satip_frontend_t *lfe2; + + TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { + if (lfe == lfe2) continue; + pthread_mutex_lock(&lfe2->sf_dvr_lock); + if (lfe2->sf_running && lfe2->sf_wait_for & (1 << lfe->sf_number)) { + lfe2->sf_wait_for &= ~(1 << lfe->sf_number); + tvh_write(lfe2->sf_dvr_pipe.wr, "o", 1); + } + pthread_mutex_unlock(&lfe2->sf_dvr_lock); + } +} + static void satip_frontend_extra_shutdown ( satip_frontend_t *lfe, uint8_t *session, long stream_id ) @@ -1120,6 +1151,7 @@ satip_frontend_close_rtsp tvhpoll_add(efd, &ev, 1); http_client_close(*rtsp); + satip_frontend_wake_other_waiting(lfe); *rtsp = NULL; } @@ -1282,12 +1314,21 @@ new_tune: u64_2 = getfastmonoclock(); - while (!start) { + pthread_mutex_lock(&lfe->sf_dvr_lock); + if (lfe->sf_wait_for == 0) start |= 2; else start &= ~2; + pthread_mutex_unlock(&lfe->sf_dvr_lock); + + while (start != 3) { + + nfds = tvhpoll_wait(efd, ev, 1, rtsp ? 55 : -1); - nfds = tvhpoll_wait(efd, ev, 1, rtsp ? 50 : -1); + pthread_mutex_lock(&lfe->sf_dvr_lock); + if (lfe->sf_wait_for == 0) start |= 2; else start &= ~2; + pthread_mutex_unlock(&lfe->sf_dvr_lock); if (!tvheadend_is_running()) { exit_flag = 1; goto done; } - if (rtsp && getfastmonoclock() - u64_2 > 50000) /* 50ms */ + if (rtsp && (getfastmonoclock() - u64_2 > 50000 || /* 50ms */ + satip_frontend_other_is_waiting(lfe))) satip_frontend_close_rtsp(lfe, buf, efd, &rtsp); if (nfds <= 0) continue; @@ -1428,6 +1469,8 @@ new_tune: } else if (b[0] == 's') { start = 1; goto done; + } else if (b[0] == 'o') { + continue; } } tvhtrace("satip", "%s - input thread received mux close", buf); @@ -1544,6 +1587,8 @@ new_tune: } else if (b[0] == 's') { start = 1; running = 0; continue; + } else if (b[0] == 'o') { + continue; } } tvhtrace("satip", "%s - input thread received mux close", buf); @@ -1607,6 +1652,7 @@ new_tune: satip_frontend_tuning_error(lfe, tr); fatal = 1; } else { + satip_frontend_wake_other_waiting(lfe); strncpy((char *)session, rtsp->hc_rtsp_session ?: "", sizeof(session)); session[sizeof(session)-1] = '\0'; stream_id = rtsp->hc_rtsp_stream_id; @@ -1810,6 +1856,9 @@ done: tvhpoll_destroy(efd); lfe->sf_display_name = NULL; lfe->sf_curmux = NULL; + + satip_frontend_wake_other_waiting(lfe); + return NULL; #undef PKTS } diff --git a/src/input/mpegts/satip/satip_private.h b/src/input/mpegts/satip/satip_private.h index 347bcedb2..42e6e814b 100644 --- a/src/input/mpegts/satip/satip_private.h +++ b/src/input/mpegts/satip/satip_private.h @@ -157,6 +157,7 @@ struct satip_frontend uint32_t sf_seq; dvb_mux_t *sf_curmux; time_t sf_last_data_tstamp; + uint32_t sf_wait_for; /* * Configuration diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index de8d2513e..5699c2346 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -90,6 +90,16 @@ satip_satconf_in_network_group return sfc2 != NULL; } +static int +satip_satconf_hash ( mpegts_mux_t *mm, int position ) +{ + dvb_mux_conf_t *mc = &((dvb_mux_t *)mm)->lm_tuning; + assert(position <= 0x7fff); + return 1 | (mc->dmc_fe_freq > 11700000 ? 2 : 0) | + ((int)mc->u.dmc_fe_qpsk.polarisation << 8) | + (position << 16); +} + static int satip_satconf_check_limits ( satip_frontend_t *lfe, satip_satconf_t *sfc, mpegts_mux_t *mm, @@ -110,9 +120,13 @@ satip_satconf_check_limits retry: memset(hashes, 0, size * sizeof(int)); - count = 1; lowest = INT_MAX; lowest_lfe = NULL; + + /* add wanted mux to hashes */ + hashes[0] = satip_satconf_hash(mm, sfc->sfc_position); + count = 1; + TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { if (lfe == lfe2 || !lfe2->sf_running || lfe2->sf_type != DVB_TYPE_S) continue; @@ -132,14 +146,14 @@ retry: } else { w2 = -1; } - r = satip_frontend_match_satcfg(lfe2, mm, 0, -1); - if (r && manage) { + if (manage) { w2 = lfe2->mi_get_weight(mi2, mm2, flags);; if (w2 < lowest) { lowest = w2; lowest_lfe = lfe2; } } + r = satip_satconf_hash(mm2, lfe2->sf_position); for (i = 0; i < size; i++) { if (hashes[i] == r) break; @@ -154,6 +168,9 @@ retry: return 1; if (manage) { /* free tuner with lowest weight */ + pthread_mutex_lock(&lfe->sf_dvr_lock); + lfe->sf_wait_for |= 1 << lowest_lfe->sf_number; + pthread_mutex_unlock(&lfe->sf_dvr_lock); mm2 = lowest_lfe->sf_req->sf_mmi->mmi_mux; mm2->mm_stop(mm2, 1, SM_CODE_SUBSCRIPTION_OVERRIDDEN); goto retry;