]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
recode mpegts_mux_start() to follow rules as service_find_instance()
authorJaroslav Kysela <perex@perex.cz>
Mon, 26 May 2014 12:26:11 +0000 (14:26 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 10 Jun 2014 12:14:46 +0000 (14:14 +0200)
src/input/mpegts/mpegts_mux.c

index 4ac45073281c5ca034aea3591b22b9eb8fa4fafe..8352c9909f6f98376f4276f0ce9e3331122debb1 100644 (file)
@@ -444,17 +444,28 @@ mpegts_mux_create_instances ( mpegts_mux_t *mm )
 {
 }
 
-// TODO: this does not follow the same logic for ordering things
-//       as the service_enlist() routine that's used for service
-//       arbitration
+static int
+mpegts_mux_start1( mpegts_mux_instance_t *mmi )
+{
+  char buf[256], buf2[256];
+
+  if (mpegts_mux_instance_start(&mmi)) {
+    mmi->mmi_mux->mm_display_name(mmi->mmi_mux, buf, sizeof(buf));
+    mmi->mmi_input->mi_display_name(mmi->mmi_input, buf2, sizeof(buf2));
+    tvhwarn("mpegts", "%s - failed to start on %s, try another", buf, buf2);
+    return 1;
+  }
+  return 0;
+}
 
 static int
 mpegts_mux_start
   ( mpegts_mux_t *mm, const char *reason, int weight )
 {
-  int pass, havefree = 0, enabled = 0;
+  int havefree = 0, enabled = 0, index, count, size = 0;
   char buf[256];
-  mpegts_mux_instance_t *mmi, *tune;
+  mpegts_mux_instance_t *mmi, **all;
+  int64_t aweight, *allw;
 
   mm->mm_display_name(mm, buf, sizeof(buf));
   tvhtrace("mpegts", "%s - starting for '%s' (weight %d)",
@@ -480,75 +491,88 @@ mpegts_mux_start
     return SM_CODE_NO_VALID_ADAPTER;
   }
 
-  /* Find */
-  pass = 0;
-  mmi  = NULL;
-  while (pass < 2) {
-    tune = NULL;
-    if (!mmi) mmi = LIST_FIRST(&mm->mm_instances);
-    tvhtrace("mpegts", "%s - checking mmi %p", buf, mmi);
-
-    /* First pass - free only */
-    if (!pass) {
-      int e = mmi->mmi_input->mi_is_enabled(mmi->mmi_input, mm);
-      int f = mmi->mmi_input->mi_is_free(mmi->mmi_input);
-      tvhtrace("mpegts", "%s -   enabled %d free %d", buf, e, f);
-      if (e) enabled = 1;
-
-      if (e && f) {
-        havefree = 1;
-        if (!mmi->mmi_tune_failed) {
-          tune = mmi;
-          tvhtrace("mpegts", "%s - found free mmi %p", buf, mmi);
-        }
-      }
-    
-    /* Second pass - non-free */
-    } else {
+  /* Get the count of instances */
+  LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link)
+    size++;
+  all  = alloca(sizeof(mpegts_mux_instance_t *) * size);
+  allw = alloca(sizeof(int64_t) * size);
+
+  /* Calculate priority+weight and sort */
+  count = 0;
+  LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) {
+    int e = mmi->mmi_input->mi_is_enabled(mmi->mmi_input, mm);
+    tvhtrace("mpegts", "%s -   mmi %p enabled %d", buf, mmi, e);
+    if (!e) continue;
+    enabled = 1;
+
+    /* Already live? Try it... */
+    if (e && mmi->mmi_mux->mm_active == mmi) {
+      if (!mpegts_mux_start1(mmi))
+        return 0;
+      continue;
+    }
+
+    if (mmi->mmi_tune_failed) continue;
 
-      /* Enabled, valid and lower weight */
-      if (mmi->mmi_input->mi_is_enabled(mmi->mmi_input, mm) &&
-          !mmi->mmi_tune_failed &&
-          (weight > mmi->mmi_input->mi_get_weight(mmi->mmi_input))) {
-        tune = mmi;
-        tvhtrace("mpegts", "%s - found mmi %p to boot", buf, mmi);
+    tvhtrace("mpegts", "%s - found mmi %p", buf, mmi);
+
+    aweight = ((int64_t )mmi->mmi_input->mi_get_priority(mmi->mmi_input,
+                                                         mmi->mmi_mux) << 32) |
+                        mmi->mmi_input->mi_get_weight(mmi->mmi_input);
+    for (index = 0; index < count; index++) {
+      if (allw[index] >= index)
+        break;
+    }
+    if (index < count) {
+      int j;
+      for (j = count; j > index; j--) {
+        allw[j] = allw[j - 1];
+        all [j] = all [j - 1];
       }
     }
-    
-    /* Tune */
-    if (tune) {
-      tvhinfo("mpegts", "%s - starting for '%s' (weight %d)",
-              buf, reason, weight);
-      if (!mpegts_mux_instance_start(&tune)) break;
-      tune = NULL;
-      tvhwarn("mpegts", "%s - failed to start, try another", buf);
+    all [index] = mmi;
+    allw[index] = aweight;
+    count++;
+  }
+
+  /* Try free inputs */
+  for (index = count - 1; index >= 0; index--) {
+    mpegts_input_t *mi = all[index]->mmi_input;
+    if (mi->mi_is_free(mi)) {
+      havefree = 1;
+      tvhtrace("mpegts", "%s - found mmi %p to boot (free)", buf, mmi);
+      if (!mpegts_mux_start1(all[index]))
+        return 0;
+      all[index] = NULL;
     }
+  }
 
-    /* Next */
-    mmi = LIST_NEXT(mmi, mmi_mux_link);
-    if (!mmi) pass++;
+  /* Try the lowest weight */
+  for (index = 0; index < count; index++) {
+    if (all[index] && weight > allw[index]) {
+      tvhtrace("mpegts", "%s - found mmi %p to boot", buf, mmi);
+      if (!mpegts_mux_start1(all[index]))
+        return 0;
+      all[index] = NULL;
+    }
   }
-  
-  if (!tune) {
-    LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) {
-      if (!mmi->mmi_tune_failed) {
-        if (!enabled) {
-          tvhdebug("mpegts", "%s - no tuners enabled", buf);
-          return SM_CODE_NO_VALID_ADAPTER;
-        } else if (havefree) {
-          tvhdebug("mpegts", "%s - no valid tuner available", buf);
-          return SM_CODE_NO_VALID_ADAPTER;
-        } else {
-          tvhdebug("mpegts", "%s - no free tuner available", buf);
-          return SM_CODE_NO_FREE_ADAPTER;
-        }
+
+  LIST_FOREACH(mmi, &mm->mm_instances, mmi_mux_link) {
+    if (!mmi->mmi_tune_failed) {
+      if (!enabled) {
+        tvhdebug("mpegts", "%s - no tuners enabled", buf);
+        return SM_CODE_NO_VALID_ADAPTER;
+      } else if (havefree) {
+        tvhdebug("mpegts", "%s - no valid tuner available", buf);
+        return SM_CODE_NO_VALID_ADAPTER;
+      } else {
+        tvhdebug("mpegts", "%s - no free tuner available", buf);
+        return SM_CODE_NO_FREE_ADAPTER;
       }
     }
-    tvhdebug("mpegts", "%s - tuning failed, invalid config?", buf);
-    return SM_CODE_TUNING_FAILED;
   }
-  
-  return 0;
+  tvhdebug("mpegts", "%s - tuning failed, invalid config?", buf);
+  return SM_CODE_TUNING_FAILED;
 }
 
 static int