]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
descrambler: improve TS error marking when no keys are available, fixes #3629
authorJaroslav Kysela <perex@perex.cz>
Mon, 14 Mar 2016 16:10:36 +0000 (17:10 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 14 Mar 2016 16:10:41 +0000 (17:10 +0100)
src/descrambler.h
src/descrambler/descrambler.c

index 42023e109715406c41a85e86a99921fa41d8d896..f6367b36a2fed8b02a8ed5b2a750f1f20685b226 100644 (file)
@@ -73,11 +73,12 @@ typedef struct th_descrambler_runtime {
   uint8_t  dr_key_valid;
   uint8_t  dr_key_changed;
   uint64_t dr_key_interval;
-  int64_t   dr_key_start;
-  int64_t   dr_key_timestamp[2];
-  int64_t   dr_ecm_start[2];
-  int64_t   dr_ecm_last_key_time;
-  int64_t   dr_last_err;
+  int64_t  dr_key_start;
+  int64_t  dr_key_timestamp[2];
+  int64_t  dr_ecm_start[2];
+  int64_t  dr_ecm_last_key_time;
+  int64_t  dr_last_err;
+  int64_t  dr_force_skip;
   TAILQ_HEAD(, th_descrambler_data) dr_queue;
   uint32_t dr_queue_total;
   tvhlog_limit_t dr_loglimit_key;
index 699c30043ee28221bf6a6705bea2a3a06a1ada1d..11779fb44f96f90a507cda177a0cab60302365e7 100644 (file)
@@ -104,9 +104,10 @@ descrambler_data_cut(th_descrambler_runtime_t *dr, int len)
   th_descrambler_data_t *dd;
 
   while (len > 0 && (dd = TAILQ_FIRST(&dr->dr_queue)) != NULL) {
+    if (dr->dr_skip)
+      ts_skip_packet2((mpegts_service_t *)dr->dr_service,
+                      dd->dd_sbuf.sb_data, MIN(len, dd->dd_sbuf.sb_ptr));
     if (len < dd->dd_sbuf.sb_ptr) {
-      if (dr->dr_skip)
-        ts_skip_packet2((mpegts_service_t *)dr->dr_service, dd->dd_sbuf.sb_data, len);
       sbuf_cut(&dd->dd_sbuf, len);
       dr->dr_queue_total -= len;
       break;
@@ -284,6 +285,7 @@ descrambler_service_start ( service_t *t )
     if (constcw)
       tvhtrace("descrambler", "using constcw for \"%s\"", t->s_nicename);
     dr->dr_skip = 0;
+    dr->dr_force_skip = 0;
     tvhcsa_init(&dr->dr_csa);
   }
   caclient_start(t);
@@ -775,6 +777,12 @@ descrambler_descramble ( service_t *t,
     return 1;
   }
 next:
+  if (!dr->dr_skip) {
+    if (!dr->dr_force_skip)
+      dr->dr_force_skip = mclk() + sec2mono(30);
+    else if (dr->dr_force_skip < mclk())
+      dr->dr_skip = 1;
+  }
   if (dr->dr_ecm_start[0] || dr->dr_ecm_start[1]) { /* ECM sent */
     ki = tsb[3];
     if ((ki & 0x80) != 0x00) {
@@ -820,6 +828,8 @@ next:
       service_set_streaming_status_flags(t, TSS_NO_ACCESS);
     }
   } else {
+    if (dr->dr_skip || count == 0)
+      ts_skip_packet2((mpegts_service_t *)dr->dr_service, tsb, len);
     service_set_streaming_status_flags(t, TSS_NO_ACCESS);
   }
   if (flush_data)