]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
descrambler: separate ECM and EMM PID subscription
authorJaroslav Kysela <perex@perex.cz>
Mon, 11 May 2015 14:14:14 +0000 (16:14 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 11 May 2015 14:14:14 +0000 (16:14 +0200)
src/descrambler.h
src/descrambler/capmt.c
src/descrambler/cwc.c
src/descrambler/descrambler.c

index 10552023c3ee52e1e4da7fa59009e653a2c6ab90..c348804531e5734f675eb1ed7ad1db1fb65e2df7 100644 (file)
@@ -79,7 +79,7 @@ typedef struct th_descrambler_runtime {
 } th_descrambler_runtime_t;
 
 typedef void (*descrambler_section_callback_t)
-  (void *opaque, int pid, const uint8_t *section, int section_len);
+  (void *opaque, int pid, const uint8_t *section, int section_len, int emm);
 
 /**
  * Track required PIDs
index 3124ca6305b53cf54ef8dc2ce38d5a6f0dea0f97..e877656fe9cab79941fc3e51b3446d2b05737be6 100644 (file)
@@ -289,7 +289,7 @@ static void capmt_enumerate_services(capmt_t *capmt, int force);
 static void capmt_notify_server(capmt_t *capmt, capmt_service_t *ct, int force);
 static void capmt_send_request(capmt_service_t *ct, int lm);
 static void capmt_table_input(void *opaque, int pid,
-                              const uint8_t *data, int len);
+                              const uint8_t *data, int len, int emm);
 static void capmt_send_client_info(capmt_t *capmt);
 
 /**
@@ -400,6 +400,8 @@ capmt_pid_remove(capmt_t *capmt, int adapter, int pid, uint32_t flags)
   mux = mmi ? mmi->mmi_mux : NULL;
   o->pid = -1; /* block for new registrations */
   o->pid_refs = 0;
+  if (o->ecm)
+    pid = DESCRAMBLER_ECM_PID(pid);
   o->ecm = -1;
   if (mux) {
     pthread_mutex_unlock(&capmt->capmt_mutex);
@@ -1668,13 +1670,15 @@ capmt_thread(void *aux)
  *
  */
 static void
-capmt_table_input(void *opaque, int pid, const uint8_t *data, int len)
+capmt_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm)
 {
   capmt_opaque_t *o = opaque;
   capmt_t *capmt = o->capmt;
   int i, demux_index, filter_index;
+  capmt_dmx_t *df;
   capmt_filters_t *cf;
   dmx_filter_t *f;
+  int flags = emm ? 0 : CAPMT_MSG_FAST;
 
   /* Validate */
   if (data == NULL || len > 4096) return;
@@ -1685,8 +1689,9 @@ capmt_table_input(void *opaque, int pid, const uint8_t *data, int len)
     cf = &capmt->capmt_demuxes.filters[demux_index];
     if (cf->adapter != o->adapter)
       continue;
-    for (filter_index = 0; filter_index < cf->max; filter_index++)
-      if (cf->dmx[filter_index].pid == pid) {
+    for (filter_index = 0; filter_index < cf->max; filter_index++) {
+      df = &cf->dmx[filter_index];
+      if (df->pid == pid && (df->flags & CAPMT_MSG_FAST) == flags) {
         f = &cf->dmx[filter_index].filter;
         if (f->mode[0] != 0)
           continue;
@@ -1705,6 +1710,7 @@ capmt_table_input(void *opaque, int pid, const uint8_t *data, int len)
                             filter_index, data, len,
                             cf->dmx[filter_index].flags);
       }
+    }
   }
 
   pthread_mutex_unlock(&capmt->capmt_mutex);
index 3d04416c5651190048bb1c18672981691fb4f91a..7361b67d1518803696e320ac20ad7cb7794d9bb4 100644 (file)
@@ -1280,7 +1280,7 @@ cwc_emm_cache_lookup(cwc_t *cwc, uint32_t crc)
  *
  */
 static void
-cwc_emm(void *opaque, int pid, const uint8_t *data, int len)
+cwc_emm(void *opaque, int pid, const uint8_t *data, int len, int emm)
 {
   struct cs_card_data *pcard = opaque;
   cwc_t *cwc;
@@ -1606,7 +1606,7 @@ cwc_emm_viaccess(cwc_t *cwc, struct cs_card_data *pcard, const uint8_t *data, in
  * t->s_streaming_mutex is held
  */
 static void
-cwc_table_input(void *opaque, int pid, const uint8_t *data, int len)
+cwc_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm)
 {
   cwc_service_t *ct = opaque;
   elementary_stream_t *st;
@@ -1974,7 +1974,8 @@ cwc_service_destroy(th_descrambler_t *td)
 
   for (i = 0; i < CWC_ES_PIDS; i++)
     if (ct->cs_epids[i])
-      descrambler_close_pid(ct->cs_mux, ct, ct->cs_epids[i]);
+      descrambler_close_pid(ct->cs_mux, ct,
+                            DESCRAMBLER_ECM_PID(ct->cs_epids[i]));
 
   cwc_service_pid_free(ct);
 
index 620d7a9217833984bafc632ed660588f9fdbda90..bcf560b5d56795387d53b3db3166fc99f12efb1d 100644 (file)
@@ -584,7 +584,7 @@ descrambler_table_callback
       } else {
         des->last_data_len = 0;
       }
-      ds->callback(ds->opaque, mt->mt_pid, ptr, len);
+      ds->callback(ds->opaque, mt->mt_pid, ptr, len, emm);
       if (!emm) { /* ECM */
         mpegts_service_t *t = mt->mt_service;
         if (t) {
@@ -620,10 +620,10 @@ descrambler_open_pid_( mpegts_mux_t *mux, void *opaque, int pid,
     return 0;
   if (mux->mm_descrambler_flush)
     return 0;
-  flags  = pid >> 16;
+  flags  = (pid >> 16) & MT_FAST;
   pid   &= 0x1fff;
   TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
-    if (dt->table->mt_pid != pid)
+    if (dt->table->mt_pid != pid && (dt->table->mt_flags & MT_FAST) != flags)
       continue;
     TAILQ_FOREACH(ds, &dt->sections, link) {
       if (ds->opaque == opaque)
@@ -635,7 +635,7 @@ descrambler_open_pid_( mpegts_mux_t *mux, void *opaque, int pid,
     dt = calloc(1, sizeof(*dt));
     TAILQ_INIT(&dt->sections);
     dt->table = mpegts_table_add(mux, 0, 0, descrambler_table_callback,
-                                 dt, "descrambler",
+                                 dt, (flags & MT_FAST) ? "ecm" : "emm",
                                  MT_FULL | MT_DEFER | flags, pid,
                                  MPS_WEIGHT_CA);
     if (dt->table)
@@ -670,17 +670,19 @@ descrambler_close_pid_( mpegts_mux_t *mux, void *opaque, int pid )
   descrambler_table_t *dt;
   descrambler_section_t *ds;
   descrambler_ecmsec_t *des;
+  int flags;
 
   if (mux == NULL)
     return 0;
-  pid &= 0x1fff;
+  flags =  (pid >> 16) & MT_FAST;
+  pid   &= 0x1fff;
   TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) {
-    if (dt->table->mt_pid != pid)
+    if (dt->table->mt_pid != pid || (dt->table->mt_flags & MT_FAST) != flags)
       continue;
     TAILQ_FOREACH(ds, &dt->sections, link) {
       if (ds->opaque == opaque) {
         TAILQ_REMOVE(&dt->sections, ds, link);
-        ds->callback(ds->opaque, -1, NULL, 0);
+        ds->callback(ds->opaque, -1, NULL, 0, (flags & MT_FAST) == 0);
         while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
           LIST_REMOVE(des, link);
           free(des->last_data);
@@ -692,7 +694,7 @@ descrambler_close_pid_( mpegts_mux_t *mux, void *opaque, int pid )
           free(dt);
         }
         free(ds);
-        tvhtrace("descrambler", "mux %p close pid %04X (%i) for %p", mux, pid, pid, opaque);
+        tvhtrace("descrambler", "mux %p close pid %04X (%i) (flags 0x%04x) for %p", mux, pid, pid, flags, opaque);
         return 1;
       }
     }
@@ -728,7 +730,7 @@ descrambler_flush_tables( mpegts_mux_t *mux )
   while ((dt = TAILQ_FIRST(&mux->mm_descrambler_tables)) != NULL) {
     while ((ds = TAILQ_FIRST(&dt->sections)) != NULL) {
       TAILQ_REMOVE(&dt->sections, ds, link);
-      ds->callback(ds->opaque, -1, NULL, 0);
+      ds->callback(ds->opaque, -1, NULL, 0, (dt->table->mt_flags & MT_FAST) ? 0 : 1);
       while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) {
         LIST_REMOVE(des, link);
         free(des->last_data);