]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
service streaming: add emm=1 support
authorJaroslav Kysela <perex@perex.cz>
Mon, 12 Oct 2015 10:59:43 +0000 (12:59 +0200)
committerJaroslav Kysela <perex@perex.cz>
Mon, 12 Oct 2015 10:59:43 +0000 (12:59 +0200)
src/input/mpegts.h
src/input/mpegts/mpegts_input.c
src/subscriptions.h
src/webui/webui.c

index 04f3e032d351acc90935cd1dc3c4fb08d4013c42..e87817a9b8df4b23c46d05096ee5838bfbeef043 100644 (file)
@@ -580,10 +580,11 @@ struct mpegts_service
   int64_t  s_pcr_drift;
 
   /**
-   * PMT monitoring
+   * PMT/CAT monitoring
    */
 
   mpegts_table_t *s_pmt_mon; ///< Table entry for monitoring PMT
+  mpegts_table_t *s_cat_mon; ///< Table entry for monitoring CAT
 
 };
 
index 33aed1614c9e1d1552185c250857d6a2e0ba5bdd..da1ab477038c802b21d96fd05f8a9a1290c37e0f 100644 (file)
@@ -553,6 +553,70 @@ static int mps_weight(elementary_stream_t *st)
      return MPS_WEIGHT_ESOTHER + MIN(st->es_index, 49);
 }
 
+static int
+mpegts_input_cat_pass_callback
+  (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
+{
+  int r, sect, last, ver;
+  uint8_t dtag, dlen;
+  uint16_t pid;
+  uintptr_t caid;
+  mpegts_mux_t             *mm  = mt->mt_mux;
+  mpegts_psi_table_state_t *st  = NULL;
+  service_t                *s   = mt->mt_opaque;
+  elementary_stream_t      *es;
+  mpegts_input_t           *mi;
+
+  /* Start */
+  r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len,
+                      tableid, 0, 5, &st, &sect, &last, &ver);
+  if (r != 1) return r;
+  ptr += 5;
+  len -= 5;
+
+  /* Send CAT data for descramblers */
+  descrambler_cat_data(mm, ptr, len);
+
+  while(len > 2) {
+    dtag = *ptr++;
+    dlen = *ptr++;
+    len -= 2;
+
+    switch(dtag) {
+      case DVB_DESC_CA:
+        if (len >= 4 && dlen >= 4 && mm->mm_active) {
+          caid = ( ptr[0]         << 8) | ptr[1];
+          pid  = ((ptr[2] & 0x1f) << 8) | ptr[3];
+          tvhdebug("cat", "  pass: caid %04X (%d) pid %04X (%d)",
+                   (uint16_t)caid, (uint16_t)caid, pid, pid);
+          pthread_mutex_lock(&s->s_stream_mutex);
+          es = NULL;
+          if (service_stream_find((service_t *)s, pid) == NULL) {
+            es = service_stream_create(s, pid, SCT_CA);
+            es->es_pid_opened = 1;
+          }
+          pthread_mutex_unlock(&s->s_stream_mutex);
+          if (es && mm->mm_active && (mi = mm->mm_active->mmi_input) != NULL) {
+            pthread_mutex_lock(&mi->mi_output_lock);
+            if ((mi = mm->mm_active->mmi_input) != NULL)
+              mpegts_input_open_pid(mi, mm, pid,
+                                    MPS_SERVICE, MPS_WEIGHT_CAT, s);
+            pthread_mutex_unlock(&mi->mi_output_lock);
+          }
+        }
+        break;
+      default:
+        break;
+    }
+
+    ptr += dlen;
+    len -= dlen;
+  }
+
+  /* Finish */
+  return dvb_table_end((mpegts_psi_table_t *)mt, st, sect);
+}
+
 void
 mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, int init )
 {
@@ -629,6 +693,13 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags,
       mpegts_table_add(mm, DVB_PMT_BASE, DVB_PMT_MASK,
                        dvb_pmt_callback, s, "pmt",
                        MT_CRC, s->s_pmt_pid, MPS_WEIGHT_PMT);
+    if (s->s_scrambled_pass && (flags & SUBSCRIPTION_EMM) != 0) {
+      s->s_cat_mon =
+        mpegts_table_add(mm, DVB_CAT_BASE, DVB_CAT_MASK,
+                         mpegts_input_cat_pass_callback, s, "cat",
+                         MT_QUICKREQ | MT_CRC, DVB_CAT_PID,
+                         MPS_WEIGHT_CAT);
+    }
   }
 
   mpegts_mux_update_pids(mm);
@@ -642,9 +713,13 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s )
   mpegts_apids_t *pids;
   mpegts_service_t *s2;
 
-  /* Close PMT table */
-  if (s->s_type == STYPE_STD && s->s_pmt_mon)
-    mpegts_table_destroy(s->s_pmt_mon);
+  /* Close PMT/CAT tables */
+  if (s->s_type == STYPE_STD) {
+    if (s->s_pmt_mon)
+      mpegts_table_destroy(s->s_pmt_mon);
+    if (s->s_cat_mon)
+      mpegts_table_destroy(s->s_cat_mon);
+  }
   s->s_pmt_mon = NULL;
 
   /* Remove from list */
index 3ce5442884e55626dc3f5d1d967e1f9dadd0879d..2f537967dfe17370062ac5b91bbd4d327efc902f 100644 (file)
@@ -36,6 +36,7 @@ extern struct th_subscription_list subscriptions;
 #define SUBSCRIPTION_TABLES     0x100
 #define SUBSCRIPTION_MINIMAL    0x200
 #define SUBSCRIPTION_NODESCR    0x400 ///< no decramble
+#define SUBSCRIPTION_EMM        0x800 ///< add EMM PIDs for no descramble subscription
 #define SUBSCRIPTION_INITSCAN  0x1000 ///< for mux subscriptions
 #define SUBSCRIPTION_IDLESCAN  0x2000 ///< for mux subscriptions
 #define SUBSCRIPTION_USERSCAN  0x4000 ///< for mux subscriptions
index 4180c95c9478261d790545e6fd57c59546bf5e24..d1362675fab1d7fa834318e326f7c47332485bfd 100644 (file)
@@ -1061,6 +1061,10 @@ http_stream_service(http_connection_t *hc, service_t *service, int weight)
     if (strcmp(str ?: "", "0") == 0)
       eflags |= SUBSCRIPTION_NODESCR;
 
+  if ((str = http_arg_get(&hc->hc_req_args, "emm")))
+    if (strcmp(str ?: "", "1") == 0)
+      eflags |= SUBSCRIPTION_EMM;
+
   flags = SUBSCRIPTION_MPEGTS | eflags;
   if ((eflags & SUBSCRIPTION_NODESCR) == 0)
     flags |= SUBSCRIPTION_PACKET;