]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
mpegts: implemented weighted PID subscriptions (sequential PMT scan)
authorJaroslav Kysela <perex@perex.cz>
Mon, 27 Apr 2015 17:31:49 +0000 (19:31 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 27 Apr 2015 17:57:14 +0000 (19:57 +0200)
src/input/mpegts.h
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_mux.c
src/input/mpegts/mpegts_pid.c
src/input/mpegts/mpegts_service.c
src/input/mpegts/mpegts_table.c
src/input/mpegts/satip/satip_frontend.c
src/input/mpegts/tsdemux.c
src/satip/rtp.c
src/satip/rtsp.c
src/webui/webui.c

index 474551e84aba799567ef14814749c1a99d1bcd52..f81f0f777d1676174312cc47a90d43c4f5c74701 100644 (file)
@@ -37,7 +37,7 @@
 #define MPEGTS_PID_NONE         0xFFFF
 
 /* Types */
-typedef int16_t                     mpegts_apid_t;
+typedef struct mpegts_apid          mpegts_apid_t;
 typedef struct mpegts_apids         mpegts_apids_t;
 typedef struct mpegts_table         mpegts_table_t;
 typedef struct mpegts_network       mpegts_network_t;
@@ -78,11 +78,17 @@ void mpegts_done ( void );
  * PIDs
  * *************************************************************************/
 
+struct mpegts_apid {
+  uint16_t pid;
+  uint16_t weight;
+};
+
 struct mpegts_apids {
   mpegts_apid_t *pids;
   int alloc;
   int count;
   int all;
+  int sorted;
 };
 
 int mpegts_pid_init ( mpegts_apids_t *pids );
@@ -90,17 +96,21 @@ void mpegts_pid_done ( mpegts_apids_t *pids );
 mpegts_apids_t *mpegts_pid_alloc ( void );
 void mpegts_pid_destroy ( mpegts_apids_t **pids );
 void mpegts_pid_reset ( mpegts_apids_t *pids );
-int mpegts_pid_add ( mpegts_apids_t *pids, mpegts_apid_t pid );
+int mpegts_pid_add ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight );
 int mpegts_pid_add_group ( mpegts_apids_t *pids, mpegts_apids_t *vals );
-int mpegts_pid_del ( mpegts_apids_t *pids, mpegts_apid_t pid );
+int mpegts_pid_del ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight );
 int mpegts_pid_del_group ( mpegts_apids_t *pids, mpegts_apids_t *vals );
-int mpegts_pid_find_index ( mpegts_apids_t *pids, mpegts_apid_t pid );
-static inline int mpegts_pid_exists ( mpegts_apids_t *pids, mpegts_apid_t pid )
-  { return pids->all || mpegts_pid_find_index(pids, pid) >= 0; }
+int mpegts_pid_find_windex ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight );
+int mpegts_pid_find_rindex ( mpegts_apids_t *pids, uint16_t pid );
+static inline int mpegts_pid_wexists ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight )
+  { return pids->all || mpegts_pid_find_windex(pids, pid, weight) >= 0; }
+static inline int mpegts_pid_rexists ( mpegts_apids_t *pids, uint16_t pid )
+  { return pids->all || mpegts_pid_find_rindex(pids, pid) >= 0; }
 int mpegts_pid_copy ( mpegts_apids_t *dst, mpegts_apids_t *src );
 int mpegts_pid_compare ( mpegts_apids_t *dst, mpegts_apids_t *src,
                          mpegts_apids_t *add, mpegts_apids_t *del );
-int mpegts_pid_dump ( mpegts_apids_t *pids, char *buf, int len );
+int mpegts_pid_weighted( mpegts_apids_t *dst, mpegts_apids_t *src, int limit );
+int mpegts_pid_dump ( mpegts_apids_t *pids, char *buf, int len, int wflag, int raw );
 
 /* **************************************************************************
  * Data / SI processing
@@ -453,6 +463,7 @@ struct mpegts_mux
   int  (*mm_is_enabled)       (mpegts_mux_t *mm);
   void (*mm_stop)             (mpegts_mux_t *mm, int force, int reason);
   void (*mm_open_table)       (mpegts_mux_t*,mpegts_table_t*,int subscribe);
+  void (*mm_unsubscribe_table)(mpegts_mux_t*,mpegts_table_t*);
   void (*mm_close_table)      (mpegts_mux_t*,mpegts_table_t*);
   void (*mm_create_instances) (mpegts_mux_t*);
   int  (*mm_is_epg)           (mpegts_mux_t*);
@@ -826,6 +837,7 @@ int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid );
 int mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth );
 
 void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe );
+void mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt );
 void mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt );
 
 void mpegts_mux_remove_subscriber(mpegts_mux_t *mm, th_subscription_t *s, int reason);
index 46db8d6a101def2c81b53dbe632c313f16e950db..2baa3f1ce532e9c1e32b7072445c2b2c25d7ea3f 100644 (file)
@@ -548,6 +548,7 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags,
   mpegts_mux_t *mm = s->s_dvb_mux;
   elementary_stream_t *st;
   mpegts_apids_t *pids;
+  mpegts_apid_t *p;
   mpegts_service_t *s2;
   int i;
 
@@ -566,8 +567,8 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags,
 
     mi->mi_open_pid(mi, mm, s->s_pmt_pid, MPS_SERVICE, MPS_WEIGHT_PMT, s);
     mi->mi_open_pid(mi, mm, s->s_pcr_pid, MPS_SERVICE, MPS_WEIGHT_PCR, s);
-    mpegts_pid_add(pids, s->s_pmt_pid);
-    mpegts_pid_add(pids, s->s_pcr_pid);
+    mpegts_pid_add(pids, s->s_pmt_pid, MPS_WEIGHT_PMT);
+    mpegts_pid_add(pids, s->s_pcr_pid, MPS_WEIGHT_PCR);
     /* Open only filtered components here */
     TAILQ_FOREACH(st, &s->s_filt_components, es_filt_link)
       if (st->es_type != SCT_CA) {
@@ -578,7 +579,7 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags,
     /* Ensure that filtered PIDs are not send in ts_recv_raw */
     TAILQ_FOREACH(st, &s->s_filt_components, es_filt_link)
       if (st->es_type != SCT_CA && st->es_pid >= 0 && st->es_pid < 8192)
-        mpegts_pid_add(pids, st->es_pid);
+        mpegts_pid_add(pids, st->es_pid, mps_weight(st));
 
     LIST_FOREACH(s2, &s->s_masters, s_masters_link) {
       pthread_mutex_lock(&s2->s_stream_mutex);
@@ -593,8 +594,10 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags,
       if (pids->all) {
         mi->mi_open_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW | MPS_ALL, MPS_WEIGHT_RAW, s);
       } else {
-        for (i = 0; i < pids->count; i++)
-          mi->mi_open_pid(mi, mm, pids->pids[i], MPS_RAW, MPS_WEIGHT_RAW, s);
+        for (i = 0; i < pids->count; i++) {
+          p = &pids->pids[i];
+          mi->mi_open_pid(mi, mm, p->pid, MPS_RAW, p->weight, s);
+        }
       }
     } else if (flags & SUBSCRIPTION_TABLES) {
       mi->mi_open_pid(mi, mm, MPEGTS_TABLES_PID, MPS_RAW | MPS_TABLES, MPS_WEIGHT_PAT, s);
@@ -643,8 +646,8 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s )
 
     mi->mi_close_pid(mi, mm, s->s_pmt_pid, MPS_SERVICE, MPS_WEIGHT_PMT, s);
     mi->mi_close_pid(mi, mm, s->s_pcr_pid, MPS_SERVICE, MPS_WEIGHT_PCR, s);
-    mpegts_pid_del(pids, s->s_pmt_pid);
-    mpegts_pid_del(pids, s->s_pcr_pid);
+    mpegts_pid_del(pids, s->s_pmt_pid, MPS_WEIGHT_PMT);
+    mpegts_pid_del(pids, s->s_pcr_pid, MPS_WEIGHT_PCR);
     /* Close all opened PIDs (the component filter may be changed at runtime) */
     TAILQ_FOREACH(st, &s->s_components, es_link) {
       if (st->es_pid_opened) {
@@ -652,7 +655,7 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s )
         mi->mi_close_pid(mi, mm, st->es_pid, MPS_SERVICE, mps_weight(st), s);
       }
       if (st->es_pid >= 0 && st->es_pid < 8192)
-        mpegts_pid_del(pids, st->es_pid);
+        mpegts_pid_del(pids, st->es_pid, mps_weight(st));
     }
 
     LIST_FOREACH(s2, &s->s_masters, s_masters_link) {
index fb0db5a69bca1227884f8e0d6beb6426c8766d81..b6bc532d470f2962839006c3e9a696eba0abba95 100644 (file)
@@ -818,12 +818,35 @@ mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe )
 }
 
 void
-mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
+mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
 {
   mpegts_input_t *mi;
 
   lock_assert(&mm->mm_tables_lock);
 
+  mi = mm->mm_active->mmi_input;
+  if (mt->mt_subscribed) {
+    mpegts_table_grab(mt);
+    mt->mt_subscribed = 0;
+    pthread_mutex_unlock(&mm->mm_tables_lock);
+    pthread_mutex_lock(&mi->mi_output_lock);
+    mi->mi_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
+    pthread_mutex_unlock(&mi->mi_output_lock);
+    pthread_mutex_lock(&mm->mm_tables_lock);
+    mpegts_table_release(mt);
+  }
+  if ((mt->mt_flags & MT_DEFER) && mt->mt_defer_cmd == MT_DEFER_OPEN_PID) {
+    TAILQ_REMOVE(&mm->mm_defer_tables, mt, mt_defer_link);
+    mt->mt_defer_cmd = 0;
+    mpegts_table_release(mt);
+  }
+}
+
+void
+mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
+{
+  lock_assert(&mm->mm_tables_lock);
+
   if (!mm->mm_active || !mm->mm_active->mmi_input) {
     if (mt->mt_defer_cmd) {
       TAILQ_REMOVE(&mm->mm_defer_tables, mt, mt_defer_link);
@@ -852,19 +875,9 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
     TAILQ_INSERT_TAIL(&mm->mm_defer_tables, mt, mt_defer_link);
     return;
   }
-  mi = mm->mm_active->mmi_input;
   LIST_REMOVE(mt, mt_link);
   mm->mm_num_tables--;
-  if (mt->mt_subscribed) {
-    mpegts_table_grab(mt);
-    mt->mt_subscribed = 0;
-    pthread_mutex_unlock(&mm->mm_tables_lock);
-    pthread_mutex_lock(&mi->mi_output_lock);
-    mi->mi_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
-    pthread_mutex_unlock(&mi->mi_output_lock);
-    pthread_mutex_lock(&mm->mm_tables_lock);
-    mpegts_table_release(mt);
-  }
+  mm->mm_unsubscribe_table(mm, mt);
 }
 
 /* **************************************************************************
@@ -1030,6 +1043,7 @@ mpegts_mux_create0
 
   /* Table processing */
   mm->mm_open_table          = mpegts_mux_open_table;
+  mm->mm_unsubscribe_table   = mpegts_mux_unsubscribe_table;
   mm->mm_close_table         = mpegts_mux_close_table;
   pthread_mutex_init(&mm->mm_tables_lock, NULL);
   TAILQ_INIT(&mm->mm_table_queue);
index 9d4e8bc3748c28d6398b9c6d5b2d9ce36fb43d8b..5a94b344668c9826ceade66ff579a4751e09507d 100644 (file)
 #include "tvheadend.h"
 #include "input.h"
 
+static int
+pid_cmp(uint16_t pid, uint16_t weight, mpegts_apid_t *p2)
+{
+  if (pid < p2->pid)
+    return 1;
+  if (pid > p2->pid)
+    return -1;
+  if (weight < p2->weight)
+    return 1;
+  if (weight > p2->weight)
+    return -1;
+  return 0;
+}
+
+static int
+pid_wcmp(const void *_p1, const void *_p2)
+{
+  const mpegts_apid_t *p1 = _p1;
+  const mpegts_apid_t *p2 = _p2;
+  if (p1->weight < p2->weight)
+    return 1;
+  if (p1->weight > p2->weight)
+    return -1;
+  /* note: prefer lower PIDs - they usually contain more important streams */
+  if (p1->pid > p2->pid)
+    return 1;
+  if (p1->pid < p2->pid)
+    return -1;
+  return 0;
+}
+
 int
 mpegts_pid_init(mpegts_apids_t *pids)
 {
   assert(pids);
   memset(pids, 0, sizeof(*pids));
+  pids->sorted = 1;
   return 0;
 }
 
@@ -40,7 +72,10 @@ mpegts_pid_done(mpegts_apids_t *pids)
 mpegts_apids_t *
 mpegts_pid_alloc(void)
 {
-  return calloc(1, sizeof(mpegts_apids_t));
+  mpegts_apids_t *r = calloc(1, sizeof(mpegts_apids_t));
+  if (r)
+    r->sorted = 1;
+  return r;
 }
 
 void
@@ -60,12 +95,12 @@ mpegts_pid_reset(mpegts_apids_t *pids)
 }
 
 int
-mpegts_pid_add(mpegts_apids_t *pids, mpegts_apid_t pid)
+mpegts_pid_add(mpegts_apids_t *pids, uint16_t pid, uint16_t weight)
 {
   mpegts_apid_t *p;
   int i;
 
-  if (mpegts_pid_exists(pids, pid))
+  if (mpegts_pid_wexists(pids, pid, weight))
     return 0;
   assert(pids);
   assert(pid >= 0 && pid <= 8191);
@@ -78,9 +113,15 @@ mpegts_pid_add(mpegts_apids_t *pids, mpegts_apid_t pid)
     pids->alloc = i;
   }
   p = pids->pids;
-  for (i = pids->count++; i > 0 && p[i - 1] > pid; i--)
-    p[i] = p[i - 1];
-  p[i] = pid;
+  if (pids->sorted) {
+    for (i = pids->count++; i > 0 && pid_cmp(pid, weight, &p[i - 1]) > 0; i--)
+      p[i] = p[i - 1];
+    p[i].pid = pid;
+    p[i].weight = weight;
+  } else {
+    p[pids->count].pid = pid;
+    p[pids->count++].weight = weight;
+  }
   return 0;
 }
 
@@ -88,9 +129,11 @@ int
 mpegts_pid_add_group(mpegts_apids_t *pids, mpegts_apids_t *vals)
 {
   int i, r;
+  mpegts_apid_t *p;
 
   for (i = 0; i < vals->count; i++) {
-    r = mpegts_pid_add(pids, vals->pids[i]);
+    p = &vals->pids[i];
+    r = mpegts_pid_add(pids, p->pid, p->weight);
     if (r)
       return r;
   }
@@ -98,29 +141,64 @@ mpegts_pid_add_group(mpegts_apids_t *pids, mpegts_apids_t *vals)
 }
 
 int
-mpegts_pid_find_index(mpegts_apids_t *pids, mpegts_apid_t pid)
+mpegts_pid_find_windex(mpegts_apids_t *pids, uint16_t pid, uint16_t weight)
+{
+  mpegts_apid_t *p = pids->pids;
+  int first, last, i, cmp;
+
+  if (pids->sorted) {
+    first = 0;
+    last = pids->count - 1;
+    for (i = last / 2; first <= last; i = (first + last) / 2) {
+      cmp = pid_cmp(pid, weight, &p[i]);
+      if (cmp < 0)
+        first = i + 1;
+      else if (cmp == 0)
+        return i;
+      else
+        last = i - 1;
+    }
+  } else {
+    for (i = 0; i < pids->count; i++)
+      if (pid_cmp(pid, weight, &p[i]) == 0)
+        return i;
+  }
+  return -1;
+}
+
+int
+mpegts_pid_find_rindex(mpegts_apids_t *pids, uint16_t pid)
 {
   mpegts_apid_t *p = pids->pids;
-  int first = 0, last = pids->count - 1, i;
-  for (i = last / 2; first <= last; i = (first + last) / 2) {
-    if (p[i] < pid)
-      first = i + 1;
-    else if (p[i] == pid)
-      return i;
-    else
-      last = i - 1;
+  int i, first, last;
+
+  if (pids->sorted) {
+    first = 0;
+    last = pids->count - 1;
+    for (i = last / 2; first <= last; i = (first + last) / 2) {
+      if (pid > p[i].pid)
+        first = i + 1;
+      else if (pid == p[i].pid)
+        return i;
+      else
+        last = i - 1;
+    }
+  } else {
+    for (i = 0; i < pids->count; i++)
+      if (pids->pids[i].pid == pid)
+        return i;
   }
   return -1;
 }
 
 int
-mpegts_pid_del(mpegts_apids_t *pids, mpegts_apid_t pid)
+mpegts_pid_del(mpegts_apids_t *pids, uint16_t pid, uint16_t weight)
 {
   int i;
 
   assert(pids);
   assert(pid >= 0 && pid <= 8191);
-  if ((i = mpegts_pid_find_index(pids, pid)) >= 0) {
+  if ((i = mpegts_pid_find_windex(pids, pid, weight)) >= 0) {
     memmove(&pids->pids[i], &pids->pids[i+1],
             (pids->count - i - 1) * sizeof(mpegts_apid_t));
     pids->count--;
@@ -133,10 +211,12 @@ mpegts_pid_del(mpegts_apids_t *pids, mpegts_apid_t pid)
 int
 mpegts_pid_del_group(mpegts_apids_t *pids, mpegts_apids_t *vals)
 {
+  mpegts_apid_t *p;
   int i, r;
 
   for (i = 0; i < vals->count; i++) {
-    r = mpegts_pid_del(pids, vals->pids[i]);
+    p = &vals->pids[i];
+    r = mpegts_pid_del(pids, p->pid, p->weight);
     if (r)
       return r;
   }
@@ -159,6 +239,7 @@ mpegts_pid_copy(mpegts_apids_t *dst, mpegts_apids_t *src)
   }
   dst->count = src->count;
   dst->all = src->all;
+  dst->sorted = src->sorted;
   memcpy(dst->pids, src->pids, src->count * sizeof(mpegts_apid_t));
   return 0;
 }
@@ -167,6 +248,7 @@ int
 mpegts_pid_compare(mpegts_apids_t *dst, mpegts_apids_t *src,
                    mpegts_apids_t *add, mpegts_apids_t *del)
 {
+  mpegts_apid_t *p;
   int i;
 
   assert(dst);
@@ -178,28 +260,65 @@ mpegts_pid_compare(mpegts_apids_t *dst, mpegts_apids_t *src,
     mpegts_pid_copy(add, dst);
     return add->count > 0;
   }
-  for (i = 0; i < src->count; i++)
-    if (mpegts_pid_find_index(dst, src->pids[i]) < 0)
-      mpegts_pid_add(del, src->pids[i]);
-  for (i = 0; i < dst->count; i++)
-    if (mpegts_pid_find_index(src, dst->pids[i]) < 0)
-      mpegts_pid_add(add, dst->pids[i]);
+  for (i = 0; i < src->count; i++) {
+    p = &src->pids[i];
+    if (mpegts_pid_find_windex(dst, p->pid, p->weight) < 0)
+      mpegts_pid_add(del, p->pid, p->weight);
+  }
+  for (i = 0; i < dst->count; i++) {
+    p = &dst->pids[i];
+    if (mpegts_pid_find_windex(src, p->pid, p->weight) < 0)
+      mpegts_pid_add(add, p->pid, p->weight);
+  }
   return add->count || del->count;
 }
 
 int
-mpegts_pid_dump(mpegts_apids_t *pids, char *buf, int len)
+mpegts_pid_weighted(mpegts_apids_t *dst, mpegts_apids_t *pids, int limit)
 {
+  int i, j;
+  mpegts_pid_init(dst);
+  mpegts_pid_copy(dst, pids);
+  qsort(dst->pids, dst->count, sizeof(mpegts_apid_t), pid_wcmp);
+  for (i = j = 0; i < dst->count; i++)
+    if (j == 0 || (dst->pids[j-1].pid != dst->pids[i].pid)) {
+      if (j < limit || dst->pids[i].weight > MPS_WEIGHT_PMT_SCAN) {
+        dst->pids[j].weight = 0;
+        dst->pids[j++].pid = dst->pids[i].pid;
+      }
+    }
+  dst->count = j;
+  dst->sorted = 0;
+  return 0;
+}
+
+int
+mpegts_pid_dump(mpegts_apids_t *pids, char *buf, int len, int wflag, int raw)
+{
+  mpegts_apids_t spids;
+  mpegts_apid_t *p;
   int i, l = 0;
 
-  if (len < 1) {
-    if (len)
-      *buf = '\0';
+  if (len < 1)
     return len;
-  }
   if (pids->all)
     return snprintf(buf, len, "all");
-  for (i = 0; i < pids->count && l + 1 < len; i++)
-    tvh_strlcatf(buf, len, l, "%s%i", i > 0 ? "," : "", pids->pids[i]);
+  if (!raw)
+    mpegts_pid_weighted(&spids, pids, len / 2);
+  else {
+    mpegts_pid_init(&spids);
+    mpegts_pid_copy(&spids, pids);
+  }
+  *buf = '\0';
+  if (wflag) {
+    for (i = 0; i < spids.count && l + 1 < len; i++) {
+      p = &spids.pids[i];
+      tvh_strlcatf(buf, len, l, "%s%i(%i)", i > 0 ? "," : "", p->pid, p->weight);
+    }
+  } else {
+    for (i = 0; i < spids.count && l + 1 < len; i++)
+     tvh_strlcatf(buf, len, l, "%s%i", i > 0 ? "," : "", spids.pids[i].pid);
+  }
+  mpegts_pid_done(&spids);
   return l;
 }
index c781ff0781d0d48377664b45bc7421f5cbe3c21e..7b3215e952bc8e6c5fc1d0872e6ba64b63b3abab 100644 (file)
@@ -735,6 +735,7 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids)
   mpegts_mux_t *mm = t->s_dvb_mux;
   mpegts_apids_t *p, *x;
   mpegts_apids_t add, del;
+  mpegts_apid_t *pi;
   int i;
 
   lock_assert(&global_lock);
@@ -752,18 +753,24 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids)
     if (!pids->all && x && x->all) {
       mi->mi_close_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW, MPS_WEIGHT_RAW, t);
       mpegts_input_close_pids(mi, mm, t, 1);
-      for (i = 0; i < x->count; i++)
-        mi->mi_open_pid(mi, mm, x->pids[i], MPS_RAW, MPS_WEIGHT_RAW, t);
+      for (i = 0; i < x->count; i++) {
+        pi = &x->pids[i];
+        mi->mi_open_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t);
+      }
     } else {
       if (pids->all) {
         mpegts_input_close_pids(mi, mm, t, 1);
         mi->mi_open_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW, MPS_WEIGHT_RAW, t);
       } else {
         mpegts_pid_compare(p, x, &add, &del);
-        for (i = 0; i < del.count; i++)
-          mi->mi_close_pid(mi, mm, del.pids[i], MPS_RAW, MPS_WEIGHT_RAW, t);
-        for (i = 0; i < add.count; i++)
-          mi->mi_open_pid(mi, mm, add.pids[i], MPS_RAW, MPS_WEIGHT_RAW, t);
+        for (i = 0; i < del.count; i++) {
+          pi = &x->pids[i];
+          mi->mi_close_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t);
+        }
+        for (i = 0; i < add.count; i++) {
+          pi = &x->pids[i];
+          mi->mi_open_pid(mi, mm, pi->pid, MPS_RAW, pi->weight, t);
+        }
         mpegts_pid_done(&add);
         mpegts_pid_done(&del);
       }
index beac5649a9ea173c7e51b810e388e17d00863331..67526d2a7a386c875f7633b61cc2f0b2f459a1ef 100644 (file)
@@ -49,10 +49,16 @@ mpegts_table_fastswitch ( mpegts_mux_t *mm, mpegts_table_t *mtm )
 
   assert(mm == mtm->mt_mux);
 
-  if(mm->mm_scan_state != MM_SCAN_STATE_ACTIVE)
+  pthread_mutex_lock(&mm->mm_tables_lock);
+
+  if ((mtm->mt_flags & MT_ONESHOT) && (mtm->mt_complete && !mtm->mt_working))
+    mm->mm_unsubscribe_table(mm, mtm);
+
+  if (mm->mm_scan_state != MM_SCAN_STATE_ACTIVE) {
+    pthread_mutex_unlock(&mm->mm_tables_lock);
     return;
+  }
 
-  pthread_mutex_lock(&mm->mm_tables_lock);
   LIST_FOREACH(mt, &mm->mm_tables, mt_link) {
     if (!(mt->mt_flags & MT_QUICKREQ) && !mt->mt_working)
       continue;
@@ -61,8 +67,7 @@ mpegts_table_fastswitch ( mpegts_mux_t *mm, mpegts_table_t *mtm )
       return;
     }
   }
-  if (mtm->mt_flags & MT_ONESHOT)
-    mm->mm_close_table(mm, mtm);
+
   pthread_mutex_unlock(&mm->mm_tables_lock);
 
   mpegts_mux_nice_name(mm, buf, sizeof(buf));
index 48fda65eb6a773deabd5fa910680953ff008029b..a60f6c0c5a468ea43a51d83d9addd4e9015fbb12 100644 (file)
@@ -530,7 +530,7 @@ satip_frontend_start_mux
 }
 
 static int
-satip_frontend_add_pid( satip_frontend_t *lfe, int pid)
+satip_frontend_add_pid( satip_frontend_t *lfe, int pid, int weight)
 {
   satip_tune_req_t *tr;
 
@@ -539,7 +539,7 @@ satip_frontend_add_pid( satip_frontend_t *lfe, int pid)
 
   tr = lfe->sf_req;
   if (tr) {
-    mpegts_pid_add(&tr->sf_pids, pid);
+    mpegts_pid_add(&tr->sf_pids, pid, weight);
     return 1;
   }
 
@@ -571,14 +571,14 @@ satip_frontend_open_pid
         mpegts_service_t *s;
         elementary_stream_t *st;
         LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) {
-          change |= satip_frontend_add_pid(lfe, s->s_pmt_pid);
-          change |= satip_frontend_add_pid(lfe, s->s_pcr_pid);
+          change |= satip_frontend_add_pid(lfe, s->s_pmt_pid, weight);
+          change |= satip_frontend_add_pid(lfe, s->s_pcr_pid, weight);
           TAILQ_FOREACH(st, &s->s_components, es_link)
-            change |= satip_frontend_add_pid(lfe, st->es_pid);
+            change |= satip_frontend_add_pid(lfe, st->es_pid, weight);
         }
       }
     } else {
-      change |= satip_frontend_add_pid(lfe, mp->mp_pid);
+      change |= satip_frontend_add_pid(lfe, mp->mp_pid, weight);
     }
     if (change)
       tvh_write(lfe->sf_dvr_pipe.wr, "c", 1);
@@ -614,7 +614,7 @@ satip_frontend_close_pid
         }
       }
     } else {
-      change = mpegts_pid_del(&tr->sf_pids, pid) >= 0;
+      change = mpegts_pid_del(&tr->sf_pids, pid, weight) >= 0;
     }
     if (change)
       tvh_write(lfe->sf_dvr_pipe.wr, "c", 1);
@@ -794,10 +794,10 @@ satip_frontend_pid_changed( http_client_t *rtsp,
 {
   satip_tune_req_t *tr;
   char *add, *del;
-  int i, j, r, any;
+  int i, j, r;
   int max_pids_len = lfe->sf_device->sd_pids_len;
   int max_pids_count = lfe->sf_device->sd_pids_max;
-  mpegts_apids_t padd, pdel;
+  mpegts_apids_t wpid, padd, pdel;
 
   pthread_mutex_lock(&lfe->sf_dvr_lock);
 
@@ -808,15 +808,12 @@ satip_frontend_pid_changed( http_client_t *rtsp,
     return 0;
   }
 
-  any = tr->sf_pids.all;
-
-  if (tr->sf_pids.count > max_pids_count)
-    any = lfe->sf_device->sd_fullmux_ok ? 1 : 0;
-
-  if (any) {
+  if (tr->sf_pids.all) {
 
+all:
     i = tr->sf_pids_tuned.all;
-    mpegts_pid_copy(&tr->sf_pids_tuned, &tr->sf_pids);
+    mpegts_pid_done(&tr->sf_pids_tuned);
+    tr->sf_pids_tuned.all = 1;
     pthread_mutex_unlock(&lfe->sf_dvr_lock);
     if (i)
       return 0;
@@ -828,17 +825,16 @@ satip_frontend_pid_changed( http_client_t *rtsp,
              tr->sf_pids_tuned.all ||
              tr->sf_pids.count == 0) {
 
-    j = tr->sf_pids.count;
-    if (j > lfe->sf_device->sd_pids_max)
-      j = lfe->sf_device->sd_pids_max;
+    mpegts_pid_weighted(&wpid, &tr->sf_pids, lfe->sf_device->sd_pids_max);
+    j = MIN(wpid.count, lfe->sf_device->sd_pids_max);
     add = alloca(1 + j * 5);
     add[0] = '\0';
-    /* prioritize higher PIDs (tables are low prio) */
-    for (i = tr->sf_pids.count - j; i < tr->sf_pids.count; i++)
-      sprintf(add + strlen(add), ",%i", tr->sf_pids.pids[i]);
-    mpegts_pid_copy(&tr->sf_pids_tuned, &tr->sf_pids);
+    for (i = 0; i < j; i++)
+      sprintf(add + strlen(add), ",%i", wpid.pids[i].pid);
+    mpegts_pid_copy(&tr->sf_pids_tuned, &wpid);
     tr->sf_pids_tuned.all = 0;
     pthread_mutex_unlock(&lfe->sf_dvr_lock);
+    mpegts_pid_done(&wpid);
 
     if (!j || add[0] == '\0')
       return 0;
@@ -848,27 +844,35 @@ satip_frontend_pid_changed( http_client_t *rtsp,
 
   } else {
 
-    mpegts_pid_compare(&tr->sf_pids, &tr->sf_pids_tuned, &padd, &pdel);
+    mpegts_pid_weighted(&wpid, &tr->sf_pids, lfe->sf_device->sd_pids_max);
+
+    if (wpid.count > max_pids_count) {
+      if (lfe->sf_device->sd_fullmux_ok) {
+        mpegts_pid_done(&wpid);
+        goto all;
+      }
+    }
+
+    mpegts_pid_compare(&wpid, &tr->sf_pids_tuned, &padd, &pdel);
 
     add = alloca(1 + padd.count * 5);
     del = alloca(1 + pdel.count * 5);
     add[0] = del[0] = '\0';
 
     for (i = 0; i < pdel.count; i++) {
-      sprintf(del + strlen(del), ",%i", pdel.pids[i]);
-      mpegts_pid_del(&tr->sf_pids_tuned, pdel.pids[i]);
+      sprintf(del + strlen(del), ",%i", pdel.pids[i].pid);
+      mpegts_pid_del(&tr->sf_pids_tuned, pdel.pids[i].pid, pdel.pids[i].weight);
     }
 
-    j = padd.count;
-    if (padd.count + tr->sf_pids_tuned.count > max_pids_count)
-      j = max_pids_count - tr->sf_pids_tuned.count;
-    /* prioritize higher PIDs (tables are low prio) */
-    for (i = padd.count - j; i < padd.count; i++)
-      sprintf(add + strlen(add), ",%i", padd.pids[i]);
+    j = MIN(padd.count, lfe->sf_device->sd_pids_max);
+    for (i = 0; i < j; i++)
+      sprintf(add + strlen(add), ",%i", padd.pids[i].pid);
 
-    mpegts_pid_copy(&tr->sf_pids_tuned, &tr->sf_pids);
+    mpegts_pid_copy(&tr->sf_pids_tuned, &wpid);
+    tr->sf_pids_tuned.all = 0;
     pthread_mutex_unlock(&lfe->sf_dvr_lock);
 
+    mpegts_pid_done(&wpid);
     mpegts_pid_done(&padd);
     mpegts_pid_done(&pdel);
 
index 44750bd9b1b0d4bc41a996c60dffaec505de509e..79269b7d41397adf10ec8c5326b75840cc7e979d 100644 (file)
@@ -239,7 +239,7 @@ ts_recv_raw(mpegts_service_t *t, const uint8_t *tsb, int len)
      * deliver this PID (decrambling)
      */
     pid = (tsb[1] & 0x1f) << 8 | tsb[2];
-    parent = mpegts_pid_exists(t->s_slaves_pids, pid);
+    parent = mpegts_pid_rexists(t->s_slaves_pids, pid);
     service_set_streaming_status_flags((service_t*)t, TSS_PACKETS);
     t->s_streaming_live |= TSS_LIVE;
   }
index 92a911da73e68868d622bee7ee9fb7cc2ce5309a..cfee3c041ebff8184e3fb1ae664fbc8449cd9531 100644 (file)
@@ -121,7 +121,7 @@ satip_rtp_loop(satip_rtp_session_t *rtp, uint8_t *data, int len)
     pid = ((data[1] & 0x1f) << 8) | data[2];
     if (pid != last_pid && !rtp->pids.all) {
       for (i = 0; i < rtp->pids.count; i++) {
-        j = pids[i];
+        j = pids[i].pid;
         if (pid < j) break;
         if (j == pid) goto found;
       }
@@ -399,7 +399,7 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len)
     break;
   }
 
-  mpegts_pid_dump(&rtp->pids, pids, sizeof(pids));
+  mpegts_pid_dump(&rtp->pids, pids, sizeof(pids), 0, 0);
 
   switch (rtp->dmc.dmc_fe_delsys) {
   case DVB_SYS_DVBS:
index c33ba862a8686b3bb27f3386dd4854e120c9a068..cc3e5c225fee939df754afd6a6a63be776148c31 100644 (file)
@@ -391,7 +391,7 @@ rtsp_validate_service(mpegts_service_t *s, mpegts_apids_t *pids)
     if (st->es_type == SCT_CA)
       enc = 1;
     if (st->es_pid > 0)
-      if (pids == NULL || mpegts_pid_exists(pids, st->es_pid))
+      if (pids == NULL || mpegts_pid_wexists(pids, st->es_pid, MPS_WEIGHT_RAW))
         if ((SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type)))
           av = 1;
   }
@@ -425,7 +425,7 @@ rtsp_manage_descramble(session_t *rs)
         idnode_set_add(found, &s->s_id, NULL);
   } else {
     for (i = 0; i < rs->pids.count; i++) {
-      s = mpegts_service_find_by_pid((mpegts_mux_t *)rs->mux, rs->pids.pids[i]);
+      s = mpegts_service_find_by_pid((mpegts_mux_t *)rs->mux, rs->pids.pids[i].pid);
       if (s != NULL && rtsp_validate_service(s, &rs->pids))
         if (!idnode_set_exists(found, &s->s_id))
           idnode_set_add(found, &s->s_id, NULL);
@@ -522,7 +522,7 @@ rtsp_start
     if (!rs->subs)
       goto endclean;
     if (!rs->pids.all && rs->pids.count == 0)
-      mpegts_pid_add(&rs->pids, 0);
+      mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW);
     /* retrigger play when new setup arrived */
     if (oldstate) {
       setup = 0;
@@ -533,7 +533,7 @@ pids:
     if (!rs->subs)
       goto endclean;
     if (!rs->pids.all && rs->pids.count == 0)
-      mpegts_pid_add(&rs->pids, 0);
+      mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW);
     svc = (mpegts_service_t *)rs->subs->ths_raw_service;
     svc->s_update_pids(svc, &rs->pids);
     satip_rtp_update_pids((void *)(intptr_t)rs->stream, &rs->pids);
@@ -548,7 +548,7 @@ pids:
                     rs->frontend, rs->findex, &rs->mux->lm_tuning,
                     &rs->pids);
     if (!rs->pids.all && rs->pids.count == 0)
-      mpegts_pid_add(&rs->pids, 0);
+      mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW);
     svc = (mpegts_service_t *)rs->subs->ths_raw_service;
     svc->s_update_pids(svc, &rs->pids);
     rs->state = STATE_PLAY;
@@ -750,7 +750,7 @@ parse_pids(char *p, mpegts_apids_t *pids)
       pid = atoi(x);
       if (pid < 0 || pid > 8191)
         return -1;
-      mpegts_pid_add(pids, pid);
+      mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW);
     }
     x = strtok_r(NULL, ",", &saveptr);
     i++;
@@ -1048,7 +1048,7 @@ play:
   dvb_mux_conf_str(dmc, buf, sizeof(buf));
   r = strlen(buf);
   tvh_strlcatf(buf, sizeof(buf), r, " pids ");
-  if (mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r) == 0)
+  if (mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r, 0, 0) == 0)
     tvh_strlcatf(buf, sizeof(buf), r, "<none>");
 
   tvhdebug("satips", "%i/%s/%d: %s from %s:%d %s",
index 4c4bbed622b9069166142ce2f45012f3b086f41b..e397925cf803a07ee408b049ded2c619f7c062cd 100644 (file)
@@ -831,7 +831,7 @@ http_stream_mux(http_connection_t *hc, mpegts_mux_t *mm, int weight)
         if (i == 8192)
           pids.all = 1;
         else
-          mpegts_pid_add(&pids, i);
+          mpegts_pid_add(&pids, i, MPS_WEIGHT_RAW);
       }
       p = strtok_r(NULL, ",", &saveptr);
     }