From: Jaroslav Kysela Date: Sat, 18 Nov 2017 17:11:00 +0000 (+0100) Subject: mpegts: cat monitor - manage correctly EMM PID list X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5fcabf698893fb1bb615527cec84d090a971fce0;p=thirdparty%2Ftvheadend.git mpegts: cat monitor - manage correctly EMM PID list --- diff --git a/src/descrambler.h b/src/descrambler.h index a887f56f3..42528cb83 100644 --- a/src/descrambler.h +++ b/src/descrambler.h @@ -145,14 +145,13 @@ typedef struct descrambler_table { /** * List of CA ids */ -#define CAID_REMOVE_ME ((uint16_t)-1) - typedef struct caid { LIST_ENTRY(caid) link; uint16_t pid; uint16_t caid; uint32_t providerid; + uint8_t delete_me; uint8_t use; uint8_t filter; diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 0c8c014be..a4ea64c4c 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -1008,7 +1008,7 @@ int mpegts_input_close_pid void mpegts_input_close_pids ( mpegts_input_t *mi, mpegts_mux_t *mm, void *owner, int all ); -int mpegts_input_open_service_pid +elementary_stream_t *mpegts_input_open_service_pid ( mpegts_input_t *mi, mpegts_mux_t *mm, service_t *s, streaming_component_type_t stype, int pid, int weight, int create ); diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index e608096b6..c116747b6 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -2197,6 +2197,7 @@ psi_desc_add_ca if (c->pid > 0 && c->pid != pid) r |= PMT_UPDATE_CAID_PID; c->pid = pid; + c->delete_me = 0; if(c->providerid != provid) { c->providerid = provid; @@ -2212,6 +2213,8 @@ psi_desc_add_ca c->providerid = provid; c->use = 1; c->pid = pid; + c->delete_me = 0; + c->filter = 0; LIST_INSERT_HEAD(&st->es_caids, c, link); r |= PMT_UPDATE_NEW_CAID; return r; @@ -2378,7 +2381,7 @@ psi_parse_pmt st->es_delete_me = 1; LIST_FOREACH(c, &st->es_caids, link) - c->pid = CAID_REMOVE_ME; + c->delete_me = 1; } // Common descriptors @@ -2621,7 +2624,7 @@ psi_parse_pmt for(c = LIST_FIRST(&st->es_caids); c != NULL; c = cn) { cn = LIST_NEXT(c, link); - if (c->pid == CAID_REMOVE_ME) { + if (c->delete_me) { LIST_REMOVE(c, link); free(c); update |= PMT_UPDATE_CAID_DELETED; diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index b0a0f2502..dc3d74565 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -631,7 +631,7 @@ mpegts_input_close_pid return 0; } -int +elementary_stream_t * mpegts_input_open_service_pid ( mpegts_input_t *mi, mpegts_mux_t *mm, service_t *s, streaming_component_type_t stype, @@ -644,7 +644,7 @@ mpegts_input_open_service_pid es = NULL; if (service_stream_find((service_t *)s, pid) == NULL) { if (!create) - return -1; + return NULL; es = service_stream_create(s, pid, stype); es->es_pid_opened = 1; } @@ -652,7 +652,7 @@ mpegts_input_open_service_pid mpegts_input_open_pid(mi, mm, pid, MPS_SERVICE, weight, s, 0); } - return 0; + return es; } static void @@ -686,6 +686,8 @@ mpegts_input_cat_pass_callback mpegts_psi_table_state_t *st = NULL; service_t *s = mt->mt_opaque; mpegts_input_t *mi; + elementary_stream_t *es, *next; + caid_t *c, *cn; /* Start */ r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, @@ -697,6 +699,19 @@ mpegts_input_cat_pass_callback /* Send CAT data for descramblers */ descrambler_cat_data(mm, ptr, len); + mi = mm->mm_active ? mm->mm_active->mmi_input : NULL; + if (mi == NULL) goto fin; + + pthread_mutex_lock(&mi->mi_output_lock); + pthread_mutex_lock(&s->s_stream_mutex); + + TAILQ_FOREACH(es, &s->s_components, es_link) { + if (es->es_type != SCT_CAT) continue; + es->es_delete_me = 1; + LIST_FOREACH(c, &es->es_caids, link) + c->delete_me = 1; + } + while(len > 2) { dtag = *ptr++; dlen = *ptr++; @@ -709,13 +724,28 @@ mpegts_input_cat_pass_callback pid = ((ptr[2] & 0x1f) << 8) | ptr[3]; tvhdebug(LS_TBL_BASE, "cat: pass: caid %04X (%d) pid %04X (%d)", (uint16_t)caid, (uint16_t)caid, pid, pid); - mi = mm->mm_active ? mm->mm_active->mmi_input : NULL; - if (mi) { - pthread_mutex_lock(&mi->mi_output_lock); - pthread_mutex_lock(&s->s_stream_mutex); - mpegts_input_open_service_pid(mi, mm, s, SCT_CA, pid, MPS_WEIGHT_CAT, 1); - pthread_mutex_unlock(&s->s_stream_mutex); - pthread_mutex_unlock(&mi->mi_output_lock); + es = mpegts_input_open_service_pid(mi, mm, s, SCT_CAT, pid, + MPS_WEIGHT_CAT, 1); + if (es) { + LIST_FOREACH(c, &es->es_caids, link) { + if (c->pid == pid) { + c->caid = caid; + c->delete_me = 0; + es->es_delete_me = 0; + break; + } + } + if (c == NULL) { + c = malloc(sizeof(caid_t)); + c->caid = caid; + c->providerid = 0; + c->use = 1; + c->pid = pid; + c->delete_me = 0; + c->filter = 0; + LIST_INSERT_HEAD(&es->es_caids, c, link); + es->es_delete_me = 0; + } } } break; @@ -727,7 +757,25 @@ mpegts_input_cat_pass_callback len -= dlen; } + for (es = TAILQ_FIRST(&s->s_components); es != NULL; es = next) { + next = TAILQ_NEXT(es, es_link); + if (es->es_type != SCT_CAT) continue; + for (c = LIST_FIRST(&es->es_caids); c != NULL; c = cn) { + cn = LIST_NEXT(c, link); + if (cn->delete_me) { + LIST_REMOVE(c, link); + free(c); + } + if (es->es_delete_me) + service_stream_destroy(s, es); + } + } + + pthread_mutex_unlock(&s->s_stream_mutex); + pthread_mutex_unlock(&mi->mi_output_lock); + /* Finish */ +fin: return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); } diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index eb75ed560..d4d0191db 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -192,7 +192,7 @@ ts_recv_packet0 if (!streaming_pad_probe_type(&t->s_streaming_pad, SMT_PACKET)) continue; - if (st->es_type == SCT_CA) + if (st->es_type == SCT_CA || st->es_type == SCT_CAT) continue; if (st->es_type == SCT_HBBTV) { @@ -205,7 +205,7 @@ ts_recv_packet0 } - if (!t->s_scrambled_pass && st->es_type == SCT_CA) + if (!t->s_scrambled_pass && (st->es_type == SCT_CA || st->es_type == SCT_CAT)) return; skip_cc: diff --git a/src/service.c b/src/service.c index 45606cdbe..4551cc14f 100644 --- a/src/service.c +++ b/src/service.c @@ -2080,12 +2080,12 @@ void service_save ( service_t *t, htsmsg_t *m ) caid_t *c; htsmsg_t *v = htsmsg_create_list(); LIST_FOREACH(c, &st->es_caids, link) { - htsmsg_t *caid = htsmsg_create_map(); + htsmsg_t *caid = htsmsg_create_map(); - htsmsg_add_u32(caid, "caid", c->caid); - if(c->providerid) - htsmsg_add_u32(caid, "providerid", c->providerid); - htsmsg_add_msg(v, NULL, caid); + htsmsg_add_u32(caid, "caid", c->caid); + if(c->providerid) + htsmsg_add_u32(caid, "providerid", c->providerid); + htsmsg_add_msg(v, NULL, caid); } htsmsg_add_msg(sub, "caidlist", v); @@ -2183,6 +2183,7 @@ add_caid(elementary_stream_t *st, uint16_t caid, uint32_t providerid) c->pid = 0; c->use = 1; c->filter = 0; + c->delete_me = 0; LIST_INSERT_HEAD(&st->es_caids, c, link); } diff --git a/src/streaming.c b/src/streaming.c index 708af3930..fece10266 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -572,6 +572,7 @@ static struct strtab streamtypetab[] = { { "HBBTV", SCT_HBBTV }, { "THEORA", SCT_THEORA }, { "OPUS", SCT_OPUS }, + { "CAT", SCT_CAT }, }; /** diff --git a/src/tvheadend.h b/src/tvheadend.h index d3ee6820d..73144562d 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -305,7 +305,8 @@ typedef enum { SCT_HBBTV, SCT_THEORA, SCT_OPUS, - SCT_LAST = SCT_OPUS + SCT_CAT, /* MPEG-TS CAT (EMM) data */ + SCT_LAST = SCT_CAT } streaming_component_type_t; #define SCT_MASK(t) (1 << (t))