]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
descrambler: fix the missing zero pid check for multipid, cleanups for non-scrambled...
authorJaroslav Kysela <perex@perex.cz>
Fri, 1 Dec 2017 19:15:27 +0000 (20:15 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sat, 2 Dec 2017 15:51:53 +0000 (16:51 +0100)
src/descrambler.h
src/descrambler/descrambler.c

index b2d06fffa7a01e917a92f4a781715a1897267443..75a46c303827083d9da5b0c8212c90484fcfcaf9 100644 (file)
@@ -105,6 +105,7 @@ typedef struct th_descrambler_runtime {
   int64_t  dr_last_err;
   int64_t  dr_force_skip;
   th_descrambler_key_t dr_keys[DESCRAMBLER_MAX_KEYS];
+  th_descrambler_key_t *dr_key_last;
   TAILQ_HEAD(, th_descrambler_data) dr_queue;
   uint32_t dr_queue_total;
   uint32_t dr_paritycheck;
index 80dbf24e8882916fd74c638cf26f544ceefd5235..8cacef69407c6089668afa7ec972480f7c51c956 100644 (file)
@@ -906,6 +906,17 @@ key_started( th_descrambler_runtime_t *dr, uint8_t ki )
   return mclk() - dr->dr_ecm_start[kidx] < dr->dr_ecm_key_margin * 2;
 }
 
+static void
+old_key_flush ( th_descrambler_runtime_t *dr, service_t *t )
+{
+  th_descrambler_key_t *tk = dr->dr_key_last;
+
+  if (tk) {
+    tk->key_csa.csa_flush(&tk->key_csa, (mpegts_service_t *)t);
+    dr->dr_key_last = NULL;
+  }
+}
+
 static void
 key_flush( th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, uint8_t changed, service_t *t )
 {
@@ -928,17 +939,19 @@ key_flush( th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, uint8_t chang
 
 static th_descrambler_key_t *
 key_find_struct( th_descrambler_runtime_t *dr,
-                 th_descrambler_key_t *tk_old,
                  const uint8_t *tsb,
                  service_t *t )
 {
   th_descrambler_key_t *tk;
   int i, pid = extractpid(tsb);
+  if (dr->dr_key_last && dr->dr_key_last->key_pid == pid)
+    return dr->dr_key_last;
   for (i = 0; i < DESCRAMBLER_MAX_KEYS; i++) {
     tk = &dr->dr_keys[i];
+    if (tk->key_pid == 0)
+      break;
     if (tk->key_pid == pid) {
-      if (tk != tk_old && tk_old)
-        tk_old->key_csa.csa_flush(&tk_old->key_csa, (mpegts_service_t *)t);
+      old_key_flush(dr, t);
       return tk;
     }
   }
@@ -1010,13 +1023,19 @@ descrambler_descramble ( service_t *t,
   if (!dr->dr_key_multipid) {
     tk = &dr->dr_keys[0];
   } else {
-    tk = key_find_struct(dr, NULL, tsb, t);
+    tk = (tsb[3] & 0x80) != 0 ? key_find_struct(dr, tsb, t) : dr->dr_key_last;
   }  
-  if (tk == NULL || tk->key_csa.csa_type == DESCRAMBLER_NONE)
-    if (dr->dr_queue_total == 0 && (tsb[3] & 0x80) == 0) {
+
+  if (dr->dr_queue_total == 0 && (tsb[3] & 0x80) == 0) {
+    if (tk && tk->key_csa.csa_type != DESCRAMBLER_NONE) {
+      tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t *)t, tsb, len);
+      dr->dr_key_last = tk;
+    } else {
+      old_key_flush(dr, t);
       ts_recv_packet0((mpegts_service_t *)t, st, tsb, len);
-      return 1;
     }
+    return 1;
+  }
 
   update_tk = 0;
   flush_data = 0;
@@ -1040,7 +1059,7 @@ descrambler_descramble ( service_t *t,
       }
       if (dr->dr_key_multipid) {
         update_tk = 1;
-        tk = key_find_struct(dr, tk, tsb2, t);
+        tk = key_find_struct(dr, tsb2, t);
         if (tk == NULL) {
           if (t->s_start_time + 3000000 < mclk() &&
               tvhlog_limit(&dr->dr_loglimit_key, 10))
@@ -1098,6 +1117,7 @@ doit:
         len3 = mpegts_word_count(tsb2, len2, 0xFF0000C0);
         debug2("%p: descramble3 %d, %s[%d]", dr, len3, keystr(tsb2), extractpid(tsb2));
         tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t *)t, tsb2, len3);
+        dr->dr_key_last = tk;
       }
       if (len2 == 0)
         service_reset_streaming_status_flags(t, TSS_NO_ACCESS);
@@ -1106,7 +1126,7 @@ dd_destroy:
     }
 
     if (update_tk) {
-      tk = key_find_struct(dr, tk, tsb, t);
+      tk = key_find_struct(dr, tsb, t);
       if (tk == NULL) {
         if ((tsb[3] & 0x80) == 0) {
           ts_recv_packet0((mpegts_service_t *)t, st, tsb, len);
@@ -1135,6 +1155,7 @@ dd_destroy:
     dr->dr_skip = 1;
     debug2("%p: descramble %d, %s[%d]", dr, len, keystr(tsb), extractpid(tsb));
     tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t *)t, tsb, len);
+    dr->dr_key_last = tk;
     service_reset_streaming_status_flags(t, TSS_NO_ACCESS);
     return 1;
   }
@@ -1149,7 +1170,7 @@ next:
     ki = tsb[3];
     if ((ki & 0x80) != 0x00) {
       if (dr->dr_key_multipid) {
-        tk = key_find_struct(dr, tk, tsb, t);
+        tk = key_find_struct(dr, tsb, t);
         if (tk == NULL) goto queue;
       } else {
         tk = &dr->dr_keys[0];