]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Optimize the PIDs filtering 377/head
authorJaroslav Kysela <perex@perex.cz>
Wed, 23 Apr 2014 10:50:18 +0000 (12:50 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 23 Apr 2014 11:25:14 +0000 (13:25 +0200)
- only used CA PIDs are opened
- all PMT PIDs are opened only at the initial scan

The SAT>IP boxes have limited count of PIDs filters (and probably some
linuxdvb hardware too), so try to use these resources better.

src/descrambler/capmt.c
src/descrambler/cwc.c
src/input/mpegts.h
src/input/mpegts/dvb_psi.c
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_table.c

index 779981a4d018a54aa0d8844b751bd62cefa93b4b..e7027262341884931a7fd34a671e3773a4ca2b8b 100644 (file)
@@ -1074,6 +1074,8 @@ capmt_service_start(service_t *s)
         tvhlog(LOG_DEBUG, "capmt",
           "New caid 0x%04X for service \"%s\"", c->caid, t->s_dvb_svcname);
 
+        mpegts_table_register_caid(((mpegts_service_t *)s)->s_dvb_mux, c->caid);
+
         /* add it to list */
         cce             = calloc(1, sizeof(capmt_caid_ecm_t));
         cce->cce_caid   = c->caid;
index 2d838f3b97c3a7ed1aeb03901ad0df3f3bc00bfa..63e3bb5d612a4ef7b6683301e4977e508a1854ac 100755 (executable)
@@ -2031,6 +2031,8 @@ cwc_service_start(service_t *t)
 
     if (ct) continue;
 
+    mpegts_table_register_caid(((mpegts_service_t *)t)->s_dvb_mux, pcard->cwc_caid);
+
     ct                   = calloc(1, sizeof(cwc_service_t));
     tvhcsa_init(&ct->cs_csa);
     ct->cs_cwc           = cwc;
index 80a5a0a59642de1d62a2e6c10c4d0540de4ac64a..24068b98600c491bea3e1075f9e85eb989109fe6 100644 (file)
@@ -140,10 +140,12 @@ struct mpegts_table
    */
   int mt_flags;
 
-#define MT_CRC      0x1
-#define MT_FULL     0x2
-#define MT_QUICKREQ 0x4
-#define MT_RECORD   0x8
+#define MT_CRC      0x01
+#define MT_FULL     0x02
+#define MT_QUICKREQ 0x04
+#define MT_RECORD   0x08
+#define MT_SKIPSUBS 0x10
+#define MT_SCANSUBS 0x20
 
   /**
    * Cycle queue
@@ -169,6 +171,7 @@ struct mpegts_table
   int mt_complete;
   int mt_incomplete;
   int mt_finished;
+  int mt_subscribed;
 
   int mt_count;
 
@@ -696,6 +699,8 @@ void mpegts_input_close_pid
 
 void mpegts_table_dispatch
   (const uint8_t *sec, size_t r, void *mt);
+static inline void mpegts_table_grab
+  (mpegts_table_t *mt) { mt->mt_refcount++; }
 void mpegts_table_release_
   (mpegts_table_t *mt);
 static inline void mpegts_table_release
@@ -710,6 +715,7 @@ mpegts_table_t *mpegts_table_add
 void mpegts_table_flush_all
   (mpegts_mux_t *mm);
 void mpegts_table_destroy ( mpegts_table_t *mt );
+void mpegts_table_register_caid ( mpegts_mux_t *mm, uint16_t caid );
 
 mpegts_service_t *mpegts_service_create0
   ( mpegts_service_t *ms, const idclass_t *class, const char *uuid,
index f4ce6b1145050532d023bd8859494e73ab7e7bfc..b912a0fd9fef7fbaa758a59cc8f2fc9aa8787a62 100644 (file)
@@ -592,7 +592,8 @@ dvb_pat_callback
       int save = 0;
       if ((s = mpegts_service_find(mm, sid, pid, 1, &save))) {
         mpegts_table_add(mm, DVB_PMT_BASE, DVB_PMT_MASK, dvb_pmt_callback,
-                         NULL, "pmt", MT_CRC | MT_QUICKREQ, pid);
+                         NULL, "pmt", MT_CRC | MT_QUICKREQ | MT_SCANSUBS,
+                         pid);
 
         if (save)
           service_request_save((service_t*)s, 1);
@@ -660,7 +661,7 @@ dvb_cat_callback
                  (uint16_t)caid, (uint16_t)caid, pid, pid);
         if(pid != 0)
           mpegts_table_add(mm, 0, 0, dvb_ca_callback,
-                           (void*)caid, "ca", MT_FULL, pid);
+                           (void*)caid, "ca", MT_FULL | MT_SKIPSUBS, pid);
         break;
       default:
         break;
index fa9bbc355941add82590550ba11bf68c24b731a2..2b3cd99074593e5d843ac7752b56e6cc67dc97ba 100644 (file)
@@ -678,8 +678,8 @@ mpegts_input_table_dispatch ( mpegts_mux_t *mm, mpegts_table_feed_t *mtf )
 
   /* Collate - tables may be removed during callbacks */
   LIST_FOREACH(mt, &mm->mm_tables, mt_link) {
+    mpegts_table_grab(mt);
     vec[i++] = mt;
-    mt->mt_refcount++;
   }
   assert(i == len);
 
index b3eb80940c0fab3d5146a0a3bf11b8deae7177a6..f0be04ad8e1495cb0f14acc47f48d86408717539 100644 (file)
@@ -105,7 +105,8 @@ mpegts_table_destroy ( mpegts_table_t *mt )
   LIST_REMOVE(mt, mt_link);
   mt->mt_destroyed = 1;
   mt->mt_mux->mm_num_tables--;
-  mt->mt_mux->mm_close_table(mt->mt_mux, mt);
+  if (mt->mt_subscribed)
+    mt->mt_mux->mm_close_table(mt->mt_mux, mt);
   while ((st = RB_FIRST(&mt->mt_state))) {
     RB_REMOVE(&mt->mt_state, st, link);
     free(st);
@@ -126,13 +127,34 @@ mpegts_table_add
     const char *name, int flags, int pid )
 {
   mpegts_table_t *mt;
+  int subscribe = 1;
 
   /* Check for existing */
   LIST_FOREACH(mt, &mm->mm_tables, mt_link) {
-    if ( mt->mt_pid      == pid      &&
-         mt->mt_callback == callback &&
-         mt->mt_opaque   == opaque )
-      return mt;
+    if (mt->mt_opaque != opaque)
+      continue;
+    if (mt->mt_pid < 0) {
+      if (strcmp(mt->mt_name, name))
+        continue;
+      mt->mt_callback   = callback;
+      mt->mt_pid        = pid;
+      mt->mt_table      = tableid;
+      mt->mt_subscribed = 1;
+      mm->mm_open_table(mm, mt);
+    } else if (pid >= 0) {
+      if (mt->mt_pid != pid)
+        continue;
+      if (mt->mt_callback != callback)
+        continue;
+    } else {
+      if (strcmp(mt->mt_name, name))
+        continue;
+      if (!(flags & MT_SKIPSUBS) && !mt->mt_subscribed) {
+        mt->mt_subscribed = 1;
+        mm->mm_open_table(mm, mt);
+      }
+    }
+    return mt;
   }
 
   tvhtrace("mpegts", "add %s table %02X/%02X (%d) pid %04X (%d)",
@@ -145,7 +167,7 @@ mpegts_table_add
   mt->mt_callback = callback;
   mt->mt_opaque   = opaque;
   mt->mt_pid      = pid;
-  mt->mt_flags    = flags;
+  mt->mt_flags    = flags & ~(MT_SKIPSUBS|MT_SCANSUBS);
   mt->mt_table    = tableid;
   mt->mt_mask     = mask;
   mt->mt_mux      = mm;
@@ -154,7 +176,18 @@ mpegts_table_add
   mm->mm_num_tables++;
 
   /* Open table */
-  mm->mm_open_table(mm, mt);
+  if (pid < 0) {
+    subscribe = 0;
+  } else if (flags & MT_SKIPSUBS) {
+    subscribe = 0;
+  } else if (flags & MT_SCANSUBS) {
+    if (mm->mm_initial_scan_status == MM_SCAN_DONE)
+      subscribe = 0;
+  }
+  if (subscribe) {
+    mt->mt_subscribed = 1;
+    mm->mm_open_table(mm, mt);
+  }
   return mt;
 }
 
@@ -169,6 +202,16 @@ mpegts_table_flush_all ( mpegts_mux_t *mm )
     mpegts_table_destroy(mt);
 }
 
+/**
+ * Register wanted CAID
+ */
+void
+mpegts_table_register_caid ( mpegts_mux_t *mm, uint16_t caid )
+{
+  uintptr_t ca = caid;
+  mpegts_table_add(mm, 0, 0, NULL, (void *)ca, "ca", MT_FULL, -1);
+}
+
 /*
  * Section assembly
  */