From: Jaroslav Kysela Date: Tue, 9 May 2017 16:52:30 +0000 (+0200) Subject: streaming - PCR changes - handle non-shared PCR PIDs correctly, fixes #4361 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=683309133e681828d3431cc9ae7a9591c915c41d;p=thirdparty%2Ftvheadend.git streaming - PCR changes - handle non-shared PCR PIDs correctly, fixes #4361 --- diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 8d6158542..d01fb944a 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -2237,6 +2237,7 @@ psi_parse_pmt int position; int tt_position; int video_stream; + int pcr_shared = 0; const char *lang; uint8_t audio_type, audio_version; mpegts_mux_t *mux = mt->mt_mux; @@ -2477,10 +2478,23 @@ psi_parse_pmt st->es_ancillary_id = ancillary_id; update |= PMT_UPDATE_ANCILLARY_ID; } + + if (st->es_pid == t->s_pcr_pid) + pcr_shared = 1; } position++; } + /* Handle PCR 'elementary stream' */ + if (!pcr_shared) { + st = service_stream_type_find((service_t *)t, SCT_PCR); + if (st) + st->es_pid = t->s_pcr_pid; + else + st = service_stream_create((service_t*)t, t->s_pcr_pid, SCT_PCR); + st->es_delete_me = 0; + } + /* Scan again to see if any streams should be deleted */ for(st = TAILQ_FIRST(&t->s_components); st != NULL; st = next) { next = TAILQ_NEXT(st, es_link); diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index 5333dd1c1..b6bdf399b 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -85,12 +85,6 @@ ts_recv_packet0 st->es_cc = (cc + 1) & 0xf; } - if (!streaming_pad_probe_type(&t->s_streaming_pad, SMT_PACKET)) - continue; - - if (st->es_type == SCT_CA) - continue; - if (tsb2[3] & 0xc0) /* scrambled */ continue; @@ -122,6 +116,12 @@ ts_recv_packet0 off = 4; } + if (!streaming_pad_probe_type(&t->s_streaming_pad, SMT_PACKET)) + continue; + + if (st->es_type == SCT_CA) + continue; + if (off <= 188 && t->s_status == SERVICE_RUNNING) parse_mpeg_ts((service_t*)t, st, tsb2 + off, 188 - off, pusi, error); diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index 08b02dd81..4b64973b0 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -1835,8 +1835,10 @@ parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt) diff = st->es_type == SCT_DVBSUB ? 4*90000 : 3*90000; if (pts_diff(pkt->pkt_pcr, pkt->pkt_pts) > diff) { + printf("%s: PTS and PCR diff is very big (%"PRId64")\n", + service_component_nicename(st), pts_diff(pkt->pkt_pcr, pkt->pkt_pts)); if (tvhlog_limit(&st->es_pcr_log, 2)) - tvhwarn(LS_PARSER, "%s: PTS and PCR diff is very large (%"PRId64")", + tvhwarn(LS_PARSER, "%s: PTS and PCR diff is very big (%"PRId64")", service_component_nicename(st), pts_diff(pkt->pkt_pcr, pkt->pkt_pts)); goto end; } diff --git a/src/service.c b/src/service.c index 978736e63..a11876a16 100644 --- a/src/service.c +++ b/src/service.c @@ -429,26 +429,26 @@ service_build_filter_add(service_t *t, elementary_stream_t *st, static void service_print_filter(service_t *t) { -#if 0 elementary_stream_t *st; caid_t *ca; + if (!tvhtrace_enabled()) + return; TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) { if (LIST_EMPTY(&st->es_caids)) { - tvhinfo(LS_SERVICE, "esfilter: \"%s\" %03d %05d %s %s", + tvhtrace(LS_SERVICE, "esfilter: \"%s\" %03d %05d %s %s", t->s_nicename, st->es_index, st->es_pid, streaming_component_type2txt(st->es_type), lang_code_get(st->es_lang)); } else { LIST_FOREACH(ca, &st->es_caids, link) if (ca->use) - tvhinfo(LS_SERVICE, "esfilter: \"%s\" %03d %05d %s %04x %06x", + tvhtrace(LS_SERVICE, "esfilter: \"%s\" %03d %05d %s %04x %06x", t->s_nicename, st->es_index, st->es_pid, streaming_component_type2txt(st->es_type), ca->caid, ca->providerid); } } -#endif } /** @@ -1211,6 +1211,22 @@ service_stream_find_(service_t *t, int pid) return NULL; } +/** + * Find a first elementary stream in a service (by type) + */ +elementary_stream_t * +service_stream_type_find(service_t *t, streaming_component_type_t type) +{ + elementary_stream_t *st; + + lock_assert(&t->s_stream_mutex); + + TAILQ_FOREACH(st, &t->s_components, es_link) + if(st->es_type == type) + return st; + return NULL; +} + /** * */ @@ -1978,6 +1994,10 @@ void service_save ( service_t *t, htsmsg_t *m ) list = htsmsg_create_list(); TAILQ_FOREACH(st, &t->s_components, es_link) { + + if (st->es_type == SCT_PCR) + continue; + sub = htsmsg_create_map(); htsmsg_add_u32(sub, "pid", st->es_pid); @@ -2176,7 +2196,7 @@ void service_load ( service_t *t, htsmsg_t *c ) continue; type = streaming_component_txt2type(v); - if(type == -1) + if(type == -1 || type == SCT_PCR) continue; if(htsmsg_get_u32(c, "pid", &pid)) diff --git a/src/service.h b/src/service.h index d85e49762..8bb6794dd 100644 --- a/src/service.h +++ b/src/service.h @@ -544,6 +544,9 @@ service_stream_find(service_t *t, int pid) return t->s_last_es; } +elementary_stream_t * +service_stream_type_find(service_t *t, streaming_component_type_t type); + elementary_stream_t *service_stream_create(service_t *t, int pid, streaming_component_type_t type); diff --git a/src/streaming.c b/src/streaming.c index 873a104a2..6e223d29a 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -538,6 +538,8 @@ streaming_start_component_find_by_index(streaming_start_t *ss, int idx) static struct strtab streamtypetab[] = { { "NONE", SCT_NONE }, { "UNKNOWN", SCT_UNKNOWN }, + { "RAW", SCT_RAW }, + { "PCR", SCT_PCR }, { "MPEG2VIDEO", SCT_MPEG2VIDEO }, { "MPEG2AUDIO", SCT_MPEG2AUDIO }, { "H264", SCT_H264 }, diff --git a/src/tvheadend.h b/src/tvheadend.h index ec8d8b925..69e532170 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -273,6 +273,7 @@ typedef enum { SCT_NONE = -1, SCT_UNKNOWN = 0, SCT_RAW = 1, + SCT_PCR, SCT_MPEG2VIDEO, SCT_MPEG2AUDIO, SCT_H264,