]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
descrambler: add ECM section filtering
authorJaroslav Kysela <perex@perex.cz>
Fri, 19 Sep 2014 11:51:41 +0000 (13:51 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 19 Sep 2014 11:51:41 +0000 (13:51 +0200)
src/descrambler.h
src/descrambler/descrambler.c

index 54fbce8fe502b4ca9dac0a03cbdd1b15fc616ce9..8d5b220551d386fd4a04f9ec6652217b86f79706 100755 (executable)
@@ -80,12 +80,18 @@ typedef void (*descrambler_section_callback_t)
 /**
  * Track required PIDs
  */
+typedef struct descrambler_ecmsec {
+  LIST_ENTRY(descrambler_ecmsec) link;
+  uint8_t   number;
+  uint8_t  *last_data;
+  int       last_data_len;
+} descrambler_ecmsec_t;
+
 typedef struct descrambler_section {
   TAILQ_ENTRY(descrambler_section) link;
   descrambler_section_callback_t callback;
   void     *opaque;
-  uint8_t  *last_data;
-  int       last_data_len;
+  LIST_HEAD(, descrambler_ecmsec) ecmsecs;
 } descrambler_section_t;
 
 typedef struct descrambler_table {
index b0827f1b152e928f2bf7acb4b979a1782afcda63..efd48f8c92f944fe726e71dc99fc0d9152d9f6a9 100755 (executable)
@@ -273,6 +273,7 @@ descrambler_flush_table_data( service_t *t )
   mpegts_mux_t *mux = ms->s_dvb_mux;
   descrambler_table_t *dt;
   descrambler_section_t *ds;
+  descrambler_ecmsec_t *des;
 
   if (mux == NULL)
     return;
@@ -281,11 +282,12 @@ descrambler_flush_table_data( service_t *t )
   TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
     if (dt->table == NULL || dt->table->mt_service != ms)
       continue;
-    TAILQ_FOREACH(ds, &dt->sections, link) {
-      free(ds->last_data);
-      ds->last_data = NULL;
-      ds->last_data_len = 0;
-    }
+    TAILQ_FOREACH(ds, &dt->sections, link)
+      while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
+        LIST_REMOVE(des, link);
+        free(des->last_data);
+        free(des);
+      }
   }
   pthread_mutex_unlock(&mux->mm_descrambler_lock);
 }
@@ -476,19 +478,30 @@ descrambler_table_callback
 {
   descrambler_table_t *dt = mt->mt_opaque;
   descrambler_section_t *ds;
+  descrambler_ecmsec_t *des;
   th_descrambler_runtime_t *dr;
 
+  if (len < 6)
+    return 0;
   pthread_mutex_lock(&mt->mt_mux->mm_descrambler_lock);
-  TAILQ_FOREACH(ds, &dt->sections, link)
-    if (ds->last_data == NULL || len != ds->last_data_len ||
-        memcmp(ds->last_data, ptr, len)) {
-      free(ds->last_data);
-      ds->last_data = malloc(len);
-      if (ds->last_data) {
-        memcpy(ds->last_data, ptr, len);
-        ds->last_data_len = len;
+  TAILQ_FOREACH(ds, &dt->sections, link) {
+    LIST_FOREACH(des, &ds->ecmsecs, link)
+      if (des->number == ptr[4])
+        break;
+    if (des == NULL) {
+      des = calloc(1, sizeof(*des));
+      des->number = ptr[4];
+      LIST_INSERT_HEAD(&ds->ecmsecs, des, link);
+    }
+    if (des->last_data == NULL || len != des->last_data_len ||
+        memcmp(des->last_data, ptr, len)) {
+      free(des->last_data);
+      des->last_data = malloc(len);
+      if (des->last_data) {
+        memcpy(des->last_data, ptr, len);
+        des->last_data_len = len;
       } else {
-        ds->last_data_len = 0;
+        des->last_data_len = 0;
       }
       ds->callback(ds->opaque, mt->mt_pid, ptr, len);
       if ((mt->mt_flags & MT_FAST) != 0) { /* ECM */
@@ -506,6 +519,7 @@ descrambler_table_callback
                    len, mt->mt_pid);
       }
     }
+  }
   pthread_mutex_unlock(&mt->mt_mux->mm_descrambler_lock);
   return 0;
 }
@@ -547,6 +561,7 @@ descrambler_open_pid_( mpegts_mux_t *mux, void *opaque, int pid,
   ds = calloc(1, sizeof(*ds));
   ds->callback    = callback;
   ds->opaque      = opaque;
+  LIST_INIT(&ds->ecmsecs);
   TAILQ_INSERT_TAIL(&dt->sections, ds, link);
   tvhtrace("descrambler", "mux %p open pid %04X (%i) (flags 0x%04x)", mux, pid, pid, flags);
   return 1;
@@ -570,6 +585,7 @@ descrambler_close_pid_( mpegts_mux_t *mux, void *opaque, int pid )
 {
   descrambler_table_t *dt;
   descrambler_section_t *ds;
+  descrambler_ecmsec_t *des;
 
   if (mux == NULL)
     return 0;
@@ -580,8 +596,11 @@ descrambler_close_pid_( mpegts_mux_t *mux, void *opaque, int pid )
         if (ds->opaque == opaque) {
           TAILQ_REMOVE(&dt->sections, ds, link);
           ds->callback(ds->opaque, -1, NULL, 0);
-          free(ds->last_data);
-          free(ds);
+          while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
+            LIST_REMOVE(des, link);
+            free(des->last_data);
+            free(des);
+          }
           if (TAILQ_FIRST(&dt->sections) == NULL) {
             TAILQ_REMOVE(&mux->mm_descrambler_tables, dt, link);
             mpegts_table_destroy(dt->table);
@@ -612,6 +631,7 @@ descrambler_flush_tables( mpegts_mux_t *mux )
 {
   descrambler_table_t *dt;
   descrambler_section_t *ds;
+  descrambler_ecmsec_t *des;
   descrambler_emm_t *emm;
 
   if (mux == NULL)
@@ -626,8 +646,11 @@ descrambler_flush_tables( mpegts_mux_t *mux )
     while ((ds = TAILQ_FIRST(&dt->sections)) != NULL) {
       TAILQ_REMOVE(&dt->sections, ds, link);
       ds->callback(ds->opaque, -1, NULL, 0);
-      free(ds->last_data);
-      free(ds);
+      while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
+        LIST_REMOVE(des, link);
+        free(des->last_data);
+        free(des);
+      }
     }
     TAILQ_REMOVE(&mux->mm_descrambler_tables, dt, link);
     mpegts_table_destroy(dt->table);