From 22a3957af7803a2ef4d3081ed25e9f5ee9dd0ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Thu, 25 Feb 2010 20:59:08 +0000 Subject: [PATCH] Create streams for each teletext subtitle page --- src/dvb/dvb_transport.c | 3 ++ src/psi.c | 63 +++++++++++++++++++++++++++++++++++++++-- src/transports.h | 2 ++ src/tvhead.h | 6 +++- 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/dvb/dvb_transport.c b/src/dvb/dvb_transport.c index 5487ab0e..b7064ab2 100644 --- a/src/dvb/dvb_transport.c +++ b/src/dvb/dvb_transport.c @@ -56,6 +56,9 @@ dvb_transport_open_demuxers(th_dvb_adapter_t *tda, th_transport_t *t) th_stream_t *st; LIST_FOREACH(st, &t->tht_components, st_link) { + if(st->st_pid >= 0x2000) + continue; + if(st->st_demuxer_fd != -1) continue; diff --git a/src/psi.c b/src/psi.c index 56e604ff..8c2f08d9 100644 --- a/src/psi.c +++ b/src/psi.c @@ -220,7 +220,7 @@ psi_build_pat(th_transport_t *t, uint8_t *buf, int maxlen, int pmtpid) #define PMT_UPDATE_NEW_CA_STREAM 0x80 #define PMT_UPDATE_NEW_CAID 0x100 #define PMT_UPDATE_CA_PROVIDER_CHANGE 0x200 - +#define PMT_UPDATE_PARENT_PID 0x400 /** @@ -299,6 +299,51 @@ psi_desc_ca(th_transport_t *t, const uint8_t *buffer, int size) return r; } +/** + * Parser for teletext descriptor + */ +static int +psi_desc_teletext(th_transport_t *t, const uint8_t *ptr, int size, + int parent_pid) +{ + int r = 0; + th_stream_t *st; + + while(size >= 5) { + int page = (ptr[3] & 0x7 ?: 8) * 100 + (ptr[4] >> 4) * 10 + (ptr[4] & 0xf); + int type = ptr[3] >> 3; + + if(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 = PID_TELETEXT_BASE + page; + + if((st = transport_stream_find(t, pid)) == NULL) { + r |= PMT_UPDATE_NEW_STREAM; + st = transport_stream_create(t, pid, SCT_TEXTSUB); + } + + st->st_delete_me = 0; + + if(memcmp(st->st_lang, ptr, 3)) { + r |= PMT_UPDATE_LANGUAGE; + memcpy(st->st_lang, ptr, 3); + } + + if(st->st_parent_pid != parent_pid) { + r |= PMT_UPDATE_PARENT_PID; + st->st_parent_pid = parent_pid; + } + } + ptr += 5; + size -= 5; + } + return r; +} + + /** * PMT parser, from ISO 13818-1 and ETSI EN 300 468 */ @@ -444,6 +489,8 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, case DVB_DESC_TELETEXT: if(estype == 0x06) hts_stream_type = SCT_TELETEXT; + + update |= psi_desc_teletext(t, ptr, dlen, pid); break; case DVB_DESC_AC3: @@ -516,7 +563,7 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, if(update) { tvhlog(LOG_DEBUG, "PSI", "Transport \"%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", transport_nicename(t), version, update&PMT_UPDATE_PCR ? ", PCR PID changed":"", update&PMT_UPDATE_NEW_STREAM ? ", New elementary stream":"", @@ -527,7 +574,8 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, update&PMT_UPDATE_STREAM_DELETED ? ", Stream deleted":"", 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_CA_PROVIDER_CHANGE? ", CA provider changed":"", + update&PMT_UPDATE_PARENT_PID ? ", Parent PID changed":""); transport_request_save(t); if(t->tht_status == TRANSPORT_RUNNING) @@ -761,6 +809,7 @@ static struct strtab streamtypetab[] = { { "PAT", SCT_PAT }, { "AAC", SCT_AAC }, { "MPEGTS", SCT_MPEGTS }, + { "TEXTSUB", SCT_TEXTSUB }, }; @@ -811,6 +860,9 @@ psi_save_transport_settings(htsmsg_t *m, th_transport_t *t) htsmsg_add_u32(sub, "ancillartyid", st->st_ancillary_id); } + if(st->st_type == SCT_TEXTSUB) + htsmsg_add_u32(sub, "parentpid", st->st_parent_pid); + if(st->st_frame_duration) htsmsg_add_u32(sub, "frameduration", st->st_frame_duration); @@ -883,5 +935,10 @@ psi_load_transport_settings(htsmsg_t *m, th_transport_t *t) if(!htsmsg_get_u32(c, "ancillartyid", &u32)) st->st_ancillary_id = u32; } + + if(type == SCT_TEXTSUB) { + if(!htsmsg_get_u32(c, "parentpid", &u32)) + st->st_parent_pid = u32; + } } } diff --git a/src/transports.h b/src/transports.h index e2e89d59..f55b7a1a 100644 --- a/src/transports.h +++ b/src/transports.h @@ -19,6 +19,8 @@ #ifndef TRANSPORTS_H #define TRANSPORTS_H +#define PID_TELETEXT_BASE 0x2000 + #include "channels.h" #include "htsmsg.h" #include "subscriptions.h" diff --git a/src/tvhead.h b/src/tvhead.h index 184cf3a3..c3c8fa38 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -159,6 +159,7 @@ typedef enum { SCT_PMT, SCT_AAC, SCT_MPEGTS, + SCT_TEXTSUB, } streaming_component_type_t; @@ -289,8 +290,11 @@ typedef struct th_stream { uint16_t st_composition_id; uint16_t st_ancillary_id; - int16_t st_pid; + uint16_t st_parent_pid; /* For subtitle streams originating from + a teletext stream. this is the pid + of the teletext stream */ + uint8_t st_cc; /* Last CC */ uint8_t st_cc_valid; /* Is CC valid at all? */