From: Jaroslav Kysela Date: Sat, 15 Dec 2018 20:08:08 +0000 (+0100) Subject: dvb psi pmt: change the teletext subtitle handling for multiple teletext descriptors... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d07a12e013c8bff2e59accb9d948fddd8488389d;p=thirdparty%2Ftvheadend.git dvb psi pmt: change the teletext subtitle handling for multiple teletext descriptors, issue #5422 --- diff --git a/src/esstream.c b/src/esstream.c index bb7262584..31d391d9c 100644 --- a/src/esstream.c +++ b/src/esstream.c @@ -447,21 +447,23 @@ ignore: * Add a new stream to a service */ elementary_stream_t * -elementary_stream_create - (elementary_set_t *set, int pid, streaming_component_type_t type) +elementary_stream_create_parent + (elementary_set_t *set, int pid, int parent_pid, streaming_component_type_t type) { elementary_stream_t *st; - int i = 0; int idx = 0; TAILQ_FOREACH(st, &set->set_all, es_link) { if(st->es_index > idx) idx = st->es_index; - i++; - if(pid != -1 && st->es_pid == pid) + if(pid != -1 && st->es_pid == pid) { + if (parent_pid >= 0 && st->es_parent_pid != parent_pid) + goto create; return st; + } } +create: st = calloc(1, sizeof(elementary_stream_t)); st->es_index = idx + 1; @@ -472,6 +474,7 @@ elementary_stream_create st->es_service = set->set_service; st->es_pid = pid; + st->es_parent_pid = parent_pid > 0 ? parent_pid : 0; elementary_stream_make_nicename(st, set->set_nicename); @@ -496,6 +499,21 @@ elementary_stream_find_(elementary_set_t *set, int pid) return NULL; } +/** + * Find an elementary stream in a service with specific parent pid + */ +elementary_stream_t * +elementary_stream_find_parent(elementary_set_t *set, int pid, int parent_pid) +{ + elementary_stream_t *st; + + TAILQ_FOREACH(st, &set->set_all, es_link) { + if(st->es_pid == pid && st->es_parent_pid == parent_pid) + return st; + } + return NULL; +} + /** * Find a first elementary stream in a service (by type) */ diff --git a/src/esstream.h b/src/esstream.h index 41b704d6c..9d756bf0e 100644 --- a/src/esstream.h +++ b/src/esstream.h @@ -168,8 +168,11 @@ void elementary_set_clean_streams(elementary_set_t *set); void elementary_set_stream_destroy(elementary_set_t *set, elementary_stream_t *es); void elementary_set_init_filter_streams(elementary_set_t *set); void elementary_set_filter_build(elementary_set_t *set); -elementary_stream_t *elementary_stream_create - (elementary_set_t *set, int pid, streaming_component_type_t type); +elementary_stream_t *elementary_stream_create_parent + (elementary_set_t *set, int pid, int parent_pid, streaming_component_type_t type); +static inline elementary_stream_t *elementary_stream_create + (elementary_set_t *set, int pid, streaming_component_type_t type) +{ return elementary_stream_create_parent(set, pid, -1, type); } elementary_stream_t *elementary_stream_find_(elementary_set_t *set, int pid); elementary_stream_t *elementary_stream_type_find (elementary_set_t *set, streaming_component_type_t type); @@ -181,6 +184,7 @@ static inline elementary_stream_t *elementary_stream_find else return set->set_last_es; } +elementary_stream_t *elementary_stream_find_parent(elementary_set_t *set, int pid, int parent_pid); elementary_stream_t *elementary_stream_type_modify (elementary_set_t *set, int pid, streaming_component_type_t type); void elementary_stream_type_destroy diff --git a/src/input/mpegts/dvb_psi_pmt.c b/src/input/mpegts/dvb_psi_pmt.c index 9b39fb3a7..9c59a5778 100644 --- a/src/input/mpegts/dvb_psi_pmt.c +++ b/src/input/mpegts/dvb_psi_pmt.c @@ -183,17 +183,17 @@ psi_desc_teletext(elementary_set_t *set, const uint8_t *ptr, int size, int page = (ptr[3] & 0x7 ?: 8) * 100 + (ptr[4] >> 4) * 10 + (ptr[4] & 0xf); int type = ptr[3] >> 3; - if(type == 2 || type == 5) { + if(page > 0 && (type == 2 || type == 5)) { // 2 = subtitle page, 5 = subtitle page [hearing impaired] // We put the teletext subtitle driven streams on a list of pids // higher than normal MPEG TS (0x2000 ++) int pid = DVB_TELETEXT_BASE + page; - st = elementary_stream_find(set, pid); + st = elementary_stream_find_parent(set, pid, parent_pid); if (st == NULL || st->es_type != SCT_TEXTSUB) { r |= PMT_UPDATE_NEW_STREAM; - st = elementary_stream_create(set, pid, SCT_TEXTSUB); + st = elementary_stream_create_parent(set, pid, parent_pid, SCT_TEXTSUB); } lang = lang_code_get2((const char*)ptr, 3); @@ -202,11 +202,6 @@ psi_desc_teletext(elementary_set_t *set, const uint8_t *ptr, int size, memcpy(st->es_lang, lang, 4); } - if(st->es_parent_pid != parent_pid) { - r |= PMT_UPDATE_PARENT_PID; - st->es_parent_pid = parent_pid; - } - // Check es_delete_me so we only compute position once per PMT update if(st->es_position != *position && st->es_delete_me) { st->es_position = *position; @@ -390,10 +385,10 @@ dvb_psi_parse_pmt break; case DVB_DESC_TELETEXT: - if(estype == 0x06) + if(estype == 0x06) { hts_stream_type = SCT_TELETEXT; - - update |= psi_desc_teletext(set, ptr, dlen, pid, &tt_position); + update |= psi_desc_teletext(set, ptr, dlen, pid, &tt_position); + } break; case DVB_DESC_AC3: @@ -524,7 +519,7 @@ dvb_psi_parse_pmt if (update) { tvhdebug(mt->mt_subsys, "%s: Service \"%s\" PMT (version %d) updated" - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", mt->mt_name, nicename, version, update&PMT_UPDATE_PCR ? ", PCR PID changed":"", @@ -540,7 +535,6 @@ dvb_psi_parse_pmt update&PMT_UPDATE_NEW_CA_STREAM ? ", New CA stream":"", update&PMT_UPDATE_NEW_CAID ? ", New CAID":"", update&PMT_UPDATE_CA_PROVIDER_CHANGE? ", CA provider changed":"", - update&PMT_UPDATE_PARENT_PID ? ", Parent PID changed":"", update&PMT_UPDATE_CAID_DELETED ? ", CAID deleted":"", update&PMT_UPDATE_CAID_PID ? ", CAID PID changed":"", update&PMT_REORDERED ? ", PIDs reordered":""); diff --git a/src/input/mpegts/dvb_psi_pmt.h b/src/input/mpegts/dvb_psi_pmt.h index 10be68cda..805891afa 100644 --- a/src/input/mpegts/dvb_psi_pmt.h +++ b/src/input/mpegts/dvb_psi_pmt.h @@ -37,10 +37,9 @@ #define PMT_UPDATE_NEW_CA_STREAM (1<<10) #define PMT_UPDATE_NEW_CAID (1<<11) #define PMT_UPDATE_CA_PROVIDER_CHANGE (1<<12) -#define PMT_UPDATE_PARENT_PID (1<<13) -#define PMT_UPDATE_CAID_DELETED (1<<14) -#define PMT_UPDATE_CAID_PID (1<<15) -#define PMT_REORDERED (1<<16) +#define PMT_UPDATE_CAID_DELETED (1<<13) +#define PMT_UPDATE_CAID_PID (1<<14) +#define PMT_REORDERED (1<<15) uint32_t dvb_psi_parse_pmt (mpegts_table_t *mt, const char *nicename, elementary_set_t *set, diff --git a/src/parsers/parser_teletext.c b/src/parsers/parser_teletext.c index eb567c153..c2cdbed8e 100644 --- a/src/parsers/parser_teletext.c +++ b/src/parsers/parser_teletext.c @@ -845,6 +845,7 @@ tt_subtitle_deliver(parser_t *t, parser_es_t *parent, tt_mag_t *ttm) TAILQ_FOREACH(es, &t->prs_components.set_filter, es_filter_link) { st = (parser_es_t *)es; + if (st->es_type != SCT_TELETEXT) continue; if (parent->es_pid == st->es_parent_pid && ttm->ttm_curpage == st->es_pid - PID_TELETEXT_BASE) { if (extract_subtitle(t, st, ttm, ttm->ttm_current_pts)) diff --git a/support/pid-count.py b/support/pid-count.py index 793b5f7dd..028aabd83 100755 --- a/support/pid-count.py +++ b/support/pid-count.py @@ -41,7 +41,7 @@ while True: if cc & 0x10: cc &= 0x0f if pid in pids_cc and pids_cc[pid] != cc: - print 'cc err 0x%x != 0x%x for pid %04X (%4d) %d' % (cc, pids_cc[pid], pid, pid, fp.tell()) + print 'cc err 0x%x != 0x%x for pid %04X (%4d) at %d' % (cc, pids_cc[pid], pid, pid, fp.tell()) if pid not in pids_cc_err: pids_cc_err[pid] = 1 else: