]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
IPTV: rewrite weight handling (for #3732)
authorJaroslav Kysela <perex@perex.cz>
Tue, 19 Apr 2016 07:13:59 +0000 (09:13 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 19 Apr 2016 07:13:59 +0000 (09:13 +0200)
src/input/mpegts.h
src/input/mpegts/iptv/iptv.c
src/input/mpegts/linuxdvb/linuxdvb_frontend.c
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_service.c
src/input/mpegts/satip/satip_frontend.c
src/input/mpegts/satip/satip_satconf.c
src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c

index f6426f62a66d97b78e914f6940e68c03caaae7de..ca9b64bc7683ffd9e088aa28ed575f2aac23b884 100644 (file)
@@ -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 );
index 837e6abe343892ff7cb2e0a1cf2017d12fea9ac3..33808f3ec611f24137ffda458b41e8360740c21e 100644 (file)
@@ -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);
 }
index 65b2bec51ad79418bae24ea67959ebc73ea26766..9b1835cf21612b5108e235b3e6ec9290f5315b2b 100644 (file)
@@ -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
index d7fc92bd44a6d33a2a8d4d8cdcfc7af5212e9303..656b471fad59d478faf69bad7d0c36cdb3d5c68d 100644 (file)
@@ -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;
index 369c11ec3ba441f8d9fc277976a57d88fedfccdc..fe502afbec5acccfbeb47a521e8ef18b88b2b950 100644 (file)
@@ -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)
index c2e5da158d397bca53258f2073bdcd8be2fd9855..35f71653160dda60915eadf348cf151214848827 100644 (file)
@@ -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;
   }
index ed89f89039581ae9dc2b4858842dbdc637a630c7..3ca4d2764a7603eaa0132fd7f45d6f4fb290d124 100644 (file)
@@ -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) {
index 5aa318e2a17ececa69b9e3edfef4c43a4b7f636b..7c064dbab78c143cfdfbec32a39a6ddc76598f40 100644 (file)
@@ -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