From a1811747d29df11f6633194ec62db424b75966a9 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 31 Jul 2014 11:36:25 +0200 Subject: [PATCH 1/5] esfilter: add logical stream index, enhance the CA type filtering - add the logical stream index - see help - add the PID filtering for the CA type - fix the service info dialog (do not show some filtered CAIDs) --- docs/html/config_esfilter.html | 10 +++++++++- src/api/api_service.c | 8 +++++--- src/esfilter.c | 30 ++++++++++++++++++++++++++++++ src/esfilter.h | 1 + src/service.c | 19 ++++++++++++++----- 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/docs/html/config_esfilter.html b/docs/html/config_esfilter.html index f1a7a40b..4cdf15a2 100644 --- a/docs/html/config_esfilter.html +++ b/docs/html/config_esfilter.html @@ -67,9 +67,17 @@ The columns have the following functions:
CA Provider
The CA provider to compare. Empty field means any. +
Stream Index +
The logical stream index to compare. Note that this index is computed + using all filters. Example: If filter is set to AC3 audio type and + the language to 'eng' and there are two AC3 'eng' streams in + the service, the first stream could be identified using number 1 + and the second using number 2. +
PID
Program identification (PID) number to compare. Zero means any. - This comparison is processed only when service comparison is active. + This comparison is processed only when service comparison is active + and for the Conditional Access filter.
Action
The rule action defines the operation when all comparisons succeeds. diff --git a/src/api/api_service.c b/src/api/api_service.c index e8b847e2..b0d3ec64 100644 --- a/src/api/api_service.c +++ b/src/api/api_service.c @@ -93,7 +93,7 @@ api_service_mapper_notify ( void ) } static htsmsg_t * -api_service_streams_get_one ( elementary_stream_t *es ) +api_service_streams_get_one ( elementary_stream_t *es, int use_filter ) { htsmsg_t *e = htsmsg_create_map(); htsmsg_add_u32(e, "index", es->es_index); @@ -115,6 +115,8 @@ api_service_streams_get_one ( elementary_stream_t *es ) caid_t *ca; htsmsg_t *e2, *l2 = htsmsg_create_list(); LIST_FOREACH(ca, &es->es_caids, link) { + if (use_filter && !ca->use) + continue; e2 = htsmsg_create_map(); htsmsg_add_u32(e2, "caid", ca->caid); htsmsg_add_u32(e2, "provider", ca->providerid); @@ -163,12 +165,12 @@ api_service_streams htsmsg_add_msg(st, NULL, e); } TAILQ_FOREACH(es, &s->s_components, es_link) - htsmsg_add_msg(st, NULL, api_service_streams_get_one(es)); + htsmsg_add_msg(st, NULL, api_service_streams_get_one(es, 0)); if (TAILQ_FIRST(&s->s_filt_components) == NULL || s->s_status == SERVICE_IDLE) service_build_filter(s); TAILQ_FOREACH(es, &s->s_filt_components, es_filt_link) - htsmsg_add_msg(stf, NULL, api_service_streams_get_one(es)); + htsmsg_add_msg(stf, NULL, api_service_streams_get_one(es, 1)); *resp = htsmsg_create_map(); htsmsg_add_str(*resp, "name", s->s_nicename); htsmsg_add_msg(*resp, "streams", st); diff --git a/src/esfilter.c b/src/esfilter.c index d5de70a6..8a6d8dba 100644 --- a/src/esfilter.c +++ b/src/esfilter.c @@ -642,6 +642,12 @@ const idclass_t esfilter_class_video = { .set = esfilter_class_service_set, .list = esfilter_class_service_enum, }, + { + .type = PT_INT, + .id = "sindex", + .name = "Stream Index", + .off = offsetof(esfilter_t, esf_sindex), + }, { .type = PT_INT, .id = "pid", @@ -703,6 +709,12 @@ const idclass_t esfilter_class_audio = { .set = esfilter_class_service_set, .list = esfilter_class_service_enum, }, + { + .type = PT_INT, + .id = "sindex", + .name = "Stream Index", + .off = offsetof(esfilter_t, esf_sindex), + }, { .type = PT_INT, .id = "pid", @@ -764,6 +776,12 @@ const idclass_t esfilter_class_teletext = { .set = esfilter_class_service_set, .list = esfilter_class_service_enum, }, + { + .type = PT_INT, + .id = "sindex", + .name = "Stream Index", + .off = offsetof(esfilter_t, esf_sindex), + }, { .type = PT_INT, .id = "pid", @@ -825,6 +843,12 @@ const idclass_t esfilter_class_subtit = { .set = esfilter_class_service_set, .list = esfilter_class_service_enum, }, + { + .type = PT_INT, + .id = "sindex", + .name = "Stream Index", + .off = offsetof(esfilter_t, esf_sindex), + }, { .type = PT_INT, .id = "pid", @@ -894,6 +918,12 @@ const idclass_t esfilter_class_ca = { .set = esfilter_class_service_set, .list = esfilter_class_service_enum, }, + { + .type = PT_INT, + .id = "sindex", + .name = "Stream Index", + .off = offsetof(esfilter_t, esf_sindex), + }, { .type = PT_INT, .id = "pid", diff --git a/src/esfilter.h b/src/esfilter.h index ec681269..f98d30d5 100644 --- a/src/esfilter.h +++ b/src/esfilter.h @@ -91,6 +91,7 @@ typedef struct esfilter { uint32_t esf_type; char esf_language[4]; char esf_service[UUID_HEX_SIZE]; + int esf_sindex; int esf_pid; uint16_t esf_caid; uint32_t esf_caprovider; diff --git a/src/service.c b/src/service.c index d1d1dcfb..bdf497c0 100644 --- a/src/service.c +++ b/src/service.c @@ -346,7 +346,7 @@ service_build_filter(service_t *t) elementary_stream_t *st, *st2, **sta; esfilter_t *esf; caid_t *ca, *ca2; - int i, n, p, o, exclusive; + int i, n, p, o, exclusive, sindex; uint32_t mask; /* rebuild the filtered and ordered components */ @@ -387,6 +387,7 @@ filter: TAILQ_FOREACH(esf, &esfilters[i], esf_link) { if (!esf->esf_enabled) continue; + sindex = 0; TAILQ_FOREACH(st, &t->s_components, es_link) { if ((mask & SCT_MASK(st->es_type)) == 0) continue; @@ -402,6 +403,8 @@ filter: continue; } if (i == ESF_CLASS_CA) { + if (esf->esf_pid && esf->esf_pid != st->es_pid) + continue; ca = NULL; if ((esf->esf_caid != (uint16_t)-1 || esf->esf_caprovider != -1)) { LIST_FOREACH(ca, &st->es_caids, link) { @@ -414,9 +417,12 @@ filter: if (ca == NULL) continue; } + sindex++; + if (esf->esf_sindex && esf->esf_sindex != sindex) + continue; if (esf->esf_log) - tvhlog(LOG_INFO, "service", "esfilter: %s %03d %05d %04x %06x \"%s\" %s", - esfilter_class2txt(i), esf->esf_index, st->es_pid, + tvhlog(LOG_INFO, "service", "esfilter: %s %03d %03d %05d %04x %06x \"%s\" %s", + esfilter_class2txt(i), st->es_index, esf->esf_index, st->es_pid, esf->esf_caid, esf->esf_caprovider, t->s_nicename, esfilter_action2txt(esf->esf_action)); switch (esf->esf_action) { @@ -464,9 +470,12 @@ ca_ignore: break; } } else { + sindex++; + if (esf->esf_sindex && esf->esf_sindex != sindex) + continue; if (esf->esf_log) - tvhlog(LOG_INFO, "service", "esfilter: %s %03d %05d %s %s \"%s\" %s", - esfilter_class2txt(i), esf->esf_index, + tvhlog(LOG_INFO, "service", "esfilter: %s %03d %03d %05d %s %s \"%s\" %s", + esfilter_class2txt(i), st->es_index, esf->esf_index, st->es_pid, streaming_component_type2txt(st->es_type), lang_code_get(st->es_lang), t->s_nicename, esfilter_action2txt(esf->esf_action)); From b6bd2400ebbbebb2ac5bd645a823eeeba5b59591 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 31 Jul 2014 11:50:39 +0200 Subject: [PATCH 2/5] service: show also network name in the service nicename --- src/service.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/service.c b/src/service.c index bdf497c0..954a19e1 100644 --- a/src/service.c +++ b/src/service.c @@ -850,7 +850,7 @@ service_stream_make_nicename(service_t *t, elementary_stream_t *st) void service_make_nicename(service_t *t) { - char buf[200]; + char buf[256]; source_info_t si; elementary_stream_t *st; @@ -859,8 +859,9 @@ service_make_nicename(service_t *t) t->s_setsourceinfo(t, &si); snprintf(buf, sizeof(buf), - "%s%s%s%s%s", - si.si_adapter ?: "", si.si_adapter && si.si_mux ? "/" : "", + "%s%s%s%s%s%s%s", + si.si_adapter ?: "", si.si_adapter && si.si_network ? "/" : "", + si.si_network ?: "", si.si_network && si.si_mux ? "/" : "", si.si_mux ?: "", si.si_mux && si.si_service ? "/" : "", si.si_service ?: ""); From 45492bfa772703b5ca6e6507663d6711d9409dd6 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 31 Jul 2014 17:42:19 +0200 Subject: [PATCH 3/5] service: esfilter - set use flag when no filters are applied --- src/service.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index 954a19e1..95128d95 100644 --- a/src/service.c +++ b/src/service.c @@ -356,8 +356,11 @@ service_build_filter(service_t *t) if (!TAILQ_EMPTY(&esfilters[i])) goto filter; - TAILQ_FOREACH(st, &t->s_components, es_link) + TAILQ_FOREACH(st, &t->s_components, es_link) { TAILQ_INSERT_TAIL(&t->s_filt_components, st, es_filt_link); + LIST_FOREACH(ca, &st->es_caids, link) + ca->use = 1; + } return; filter: From ea7a93b776f0e30576a463e494fd6874cf79a7f6 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 31 Jul 2014 17:45:10 +0200 Subject: [PATCH 4/5] service: esfilter - set CA use flag also for skipped types --- src/service.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index 95128d95..e1845985 100644 --- a/src/service.c +++ b/src/service.c @@ -381,8 +381,11 @@ filter: mask = esfilterclsmask[i]; if (TAILQ_EMPTY(&esfilters[i])) { TAILQ_FOREACH(st, &t->s_components, es_link) { - if ((mask & SCT_MASK(st->es_type)) != 0) + if ((mask & SCT_MASK(st->es_type)) != 0) { service_build_filter_add(t, st, sta, &p); + LIST_FOREACH(ca, &st->es_caids, link) + ca->use = 1; + } } continue; } From 43253f88c0ab082acc08ceed6d60e3343a42f8a7 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Thu, 31 Jul 2014 21:08:18 +0200 Subject: [PATCH 5/5] service: add PMT# for noname services and include full service name in service lists --- src/service.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- src/service.h | 2 ++ 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/service.c b/src/service.c index e1845985..532bf0da 100644 --- a/src/service.c +++ b/src/service.c @@ -128,7 +128,7 @@ service_class_channel_enum static const char * service_class_get_title ( idnode_t *self ) { - return service_get_channel_name((service_t*)self); + return service_get_full_channel_name((service_t *)self); } static const void * @@ -856,25 +856,39 @@ service_stream_make_nicename(service_t *t, elementary_stream_t *st) void service_make_nicename(service_t *t) { - char buf[256]; + char buf[256], buf2[16]; source_info_t si; elementary_stream_t *st; + char *service_name; + int prefidx; lock_assert(&t->s_stream_mutex); t->s_setsourceinfo(t, &si); + service_name = si.si_service; + if (service_name == NULL || si.si_service[0] == '0') { + snprintf(buf2, sizeof(buf2), "{PMT:%d}", t->s_pmt_pid); + service_name = buf2; + } + snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", si.si_adapter ?: "", si.si_adapter && si.si_network ? "/" : "", si.si_network ?: "", si.si_network && si.si_mux ? "/" : "", - si.si_mux ?: "", si.si_mux && si.si_service ? "/" : "", - si.si_service ?: ""); + si.si_mux ?: "", si.si_mux && service_name ? "/" : "", + service_name ?: ""); + prefidx = (si.si_adapter ? strlen(si.si_adapter) : 0) + + (si.si_adapter && si.si_network ? 1 : 0) + + (si.si_network ? strlen(si.si_network) : 0) + + (si.si_network && si.si_mux ? 1 : 0) + + (si.si_mux ? strlen(si.si_mux) : 0); service_source_info_free(&si); free(t->s_nicename); t->s_nicename = strdup(buf); + t->s_nicename_prefidx = prefidx; TAILQ_FOREACH(st, &t->s_components, es_link) service_stream_make_nicename(t, st); @@ -1482,6 +1496,33 @@ service_get_channel_name ( service_t *s ) return r; } +/* + * Get full name for channel from service + */ +const char * +service_get_full_channel_name ( service_t *s ) +{ + static char __thread buf[256]; + const char *r = NULL; + int len; + + if (s->s_channel_name) + r = s->s_channel_name(s); + if (r == NULL) + return s->s_nicename; + + len = s->s_nicename_prefidx; + if (len >= sizeof(buf)) + len = sizeof(buf) - 1; + strncpy(buf, s->s_nicename, len); + if (len < sizeof(buf) - 1) + buf[len++] = '/'; + buf[len] = '\0'; + if (len < sizeof(buf)) + snprintf(buf + len, sizeof(buf) - len, "%s", r); + return buf; +} + /* * Get number for service */ diff --git a/src/service.h b/src/service.h index 54b7f9ff..2361eead 100644 --- a/src/service.h +++ b/src/service.h @@ -300,6 +300,7 @@ typedef struct service { * Name usable for displaying to user */ char *s_nicename; + int s_nicename_prefidx; /** * Teletext... @@ -553,6 +554,7 @@ void service_save ( service_t *s, htsmsg_t *c ); void sort_elementary_streams(service_t *t); const char *service_get_channel_name (service_t *s); +const char *service_get_full_channel_name (service_t *s); int service_get_channel_number (service_t *s); #endif // SERVICE_H__