From: Jaroslav Kysela Date: Tue, 19 Apr 2016 07:13:59 +0000 (+0200) Subject: IPTV: rewrite weight handling (for #3732) X-Git-Tag: v4.2.1~621 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b17d157105b7b50c3858409fd17e9456614192fd;p=thirdparty%2Ftvheadend.git IPTV: rewrite weight handling (for #3732) --- diff --git a/src/input/mpegts.h b/src/input/mpegts.h index f6426f62a..ca9b64bc7 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -708,7 +708,7 @@ struct mpegts_input int (*mi_is_enabled) (mpegts_input_t*, mpegts_mux_t *mm, int flags, int weight); void (*mi_enabled_updated)(mpegts_input_t*); void (*mi_display_name) (mpegts_input_t*, char *buf, size_t len); - int (*mi_get_weight) (mpegts_input_t*, mpegts_mux_t *mm, int flags); + int (*mi_get_weight) (mpegts_input_t*, mpegts_mux_t *mm, int flags, int weight); int (*mi_get_priority) (mpegts_input_t*, mpegts_mux_t *mm, int flags); int (*mi_get_grace) (mpegts_input_t*, mpegts_mux_t *mm); int (*mi_warm_mux) (mpegts_input_t*,mpegts_mux_instance_t*); @@ -925,7 +925,7 @@ void mpegts_input_recv_packets (mpegts_input_t *mi, mpegts_mux_instance_t *mmi, sbuf_t *sb, int flags, mpegts_pcr_t *pcr); -int mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ); +int mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ); 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 ); diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index 837e6abe3..33808f3ec 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -149,58 +149,61 @@ const idclass_t iptv_input_class = { } }; -static int -iptv_input_is_free ( mpegts_input_t *mi, mpegts_mux_t *mm, int active ) +static mpegts_mux_instance_t * +iptv_input_is_free ( mpegts_input_t *mi, mpegts_mux_t *mm, + int active, int weight, int *lweight ) { - int c = active; - mpegts_mux_instance_t *mmi; + int h = 0, l = 0, w, rw = INT_MAX; + mpegts_mux_instance_t *mmi, *rmmi = NULL; iptv_network_t *in = (iptv_network_t *)mm->mm_network; + pthread_mutex_lock(&mi->mi_output_lock); LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) - if (mmi->mmi_mux->mm_network == (mpegts_network_t *)in) - c++; - + if (mmi->mmi_mux->mm_network == (mpegts_network_t *)in) { + w = mpegts_mux_instance_weight(mmi); + if (w < rw) { + rmmi = mmi; + rw = w; + } + if (w >= weight) h++; else l++; + } + pthread_mutex_unlock(&mi->mi_output_lock); + + if (lweight) + *lweight = rw == INT_MAX ? 0 : rw; + /* Limit reached */ - if (in->in_max_streams && c >= in->in_max_streams) - return 0; + if (in->in_max_streams && h >= in->in_max_streams) { + if (active) { + if (l == 0) + return rmmi; + } else { + return rmmi; + } + } /* Bandwidth reached */ - if (in->in_bw_limited) - return 0; + if (in->in_bw_limited && l == 0) + return rmmi; - return 1; + return NULL; } static int iptv_input_is_enabled ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) { - return iptv_input_is_free(mi, mm, 0); + if (!mpegts_input_is_enabled(mi, mm, flags, weight)) return 0; + return iptv_input_is_free(mi, mm, 0, weight, NULL) == NULL; } static int -iptv_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) +iptv_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) { - int w = 0; - const th_subscription_t *ths; - const service_t *s; - mpegts_mux_instance_t *mmi; + int w; /* Find the "min" weight */ - if (!iptv_input_is_free(mi, mm, 0)) { - w = INT_MAX; - - /* Service subs */ - pthread_mutex_lock(&mi->mi_output_lock); - LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) - LIST_FOREACH(s, &mmi->mmi_mux->mm_transports, s_active_link) - LIST_FOREACH(ths, &s->s_subscriptions, ths_service_link) - w = MIN(w, ths->ths_weight); - pthread_mutex_unlock(&mi->mi_output_lock); - - if (w == INT_MAX) - w = 0; - } + iptv_input_is_free(mi, mm, 1, weight, &w); return w; @@ -232,28 +235,17 @@ static int iptv_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux; + mpegts_mux_instance_t *lmmi; /* Already active */ if (im->mm_active) return 0; /* Do we need to stop something? */ - if (!iptv_input_is_free(mi, mmi->mmi_mux, 1)) { - pthread_mutex_lock(&mi->mi_output_lock); - mpegts_mux_instance_t *m, *s = NULL; - int w = INT_MAX; - LIST_FOREACH(m, &mi->mi_mux_active, mmi_active_link) { - int t = mpegts_mux_instance_weight(m); - if (t < w) { - s = m; - w = t; - } - } - pthread_mutex_unlock(&mi->mi_output_lock); - + lmmi = iptv_input_is_free(mi, mmi->mmi_mux, 1, mmi->mmi_start_weight, NULL); + if (lmmi) { /* Stop */ - if (s) - s->mmi_mux->mm_stop(s->mmi_mux, 1, SM_CODE_ABORTED); + lmmi->mmi_mux->mm_stop(lmmi->mmi_mux, 1, SM_CODE_ABORTED); } return 0; } @@ -375,7 +367,6 @@ static void iptv_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) { iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux; - mpegts_network_link_t *mnl; pthread_mutex_lock(&iptv_lock); @@ -403,10 +394,7 @@ iptv_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) sbuf_free(&im->mm_iptv_buffer); /* Clear bw limit */ - LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) { - iptv_network_t *in = (iptv_network_t*)mnl->mnl_network; - in->in_bw_limited = 0; - } + ((iptv_network_t *)im->mm_network)->in_bw_limited = 0; pthread_mutex_unlock(&iptv_lock); } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 65b2bec51..9b1835cf2 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -428,18 +428,18 @@ linuxdvb_frontend_enabled_updated ( mpegts_input_t *mi ) } static int -linuxdvb_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) +linuxdvb_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) { - int weight = 0; + int w = 0; linuxdvb_adapter_t *la = ((linuxdvb_frontend_t*)mi)->lfe_adapter; linuxdvb_frontend_t *lfe; if (la->la_exclusive) { LIST_FOREACH(lfe, &la->la_frontends, lfe_link) - weight = MAX(weight, mpegts_input_get_weight((mpegts_input_t*)lfe, mm, flags)); + w = MAX(weight, mpegts_input_get_weight((mpegts_input_t*)lfe, mm, flags, weight)); } else { - weight = mpegts_input_get_weight(mi, mm, flags); + w = mpegts_input_get_weight(mi, mm, flags, weight); } - return weight; + return w; } static int diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index d7fc92bd4..656b471fa 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -376,7 +376,7 @@ mpegts_input_display_name ( mpegts_input_t *mi, char *buf, size_t len ) } int -mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) +mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) { const mpegts_mux_instance_t *mmi; const service_t *s; diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 369c11ec3..fe502afbe 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -313,7 +313,7 @@ mpegts_service_enlist w = -1; p = -1; } else { - w = mi->mi_get_weight(mi, mmi->mmi_mux, flags); + w = mi->mi_get_weight(mi, mmi->mmi_mux, flags, weight); p = mi->mi_get_priority(mi, mmi->mmi_mux, flags); if (w > 0 && mi->mi_free_weight && weight >= mi->mi_free_weight && w < mi->mi_free_weight) diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index c2e5da158..35f716531 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -430,9 +430,9 @@ const idclass_t satip_frontend_atsc_c_class = * *************************************************************************/ static int -satip_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) +satip_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) { - return mpegts_input_get_weight(mi, mm, flags); + return mpegts_input_get_weight(mi, mm, flags, weight); } static int @@ -467,7 +467,7 @@ satip_frontend_get_max_weight ( satip_frontend_t *lfe, mpegts_mux_t *mm, int fla 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); + w2 = lfe2->mi_get_weight((mpegts_input_t *)lfe2, mm, flags, 0); if (w2 > w) w = w2; } diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index ed89f8903..3ca4d2764 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -145,7 +145,7 @@ retry: mm2 = lfe2->sf_req->sf_mmi->mmi_mux; w2 = -1; if (weight > 0 || manage) - w2 = lfe2->mi_get_weight(mi2, mm2, flags); + w2 = lfe2->mi_get_weight(mi2, mm2, flags, 0); if (!manage && w2 < weight) continue; if (manage && w2 < lowest) { diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c index 5aa318e2a..7c064dbab 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c @@ -25,9 +25,9 @@ #include "tvhdhomerun_private.h" static int -tvhdhomerun_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) +tvhdhomerun_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) { - return mpegts_input_get_weight(mi, mm, flags); + return mpegts_input_get_weight(mi, mm, flags, weight); } static int