From: Jaroslav Kysela Date: Fri, 1 Dec 2017 19:15:27 +0000 (+0100) Subject: descrambler: fix the missing zero pid check for multipid, cleanups for non-scrambled... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2ef96cfca037cd8054913a5c8cc334d7239d765;p=thirdparty%2Ftvheadend.git descrambler: fix the missing zero pid check for multipid, cleanups for non-scrambled packet processing, fixes #4749 --- diff --git a/src/descrambler.h b/src/descrambler.h index b2d06fffa..75a46c303 100644 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -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; diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index 80dbf24e8..8cacef694 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -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];