From a47f8e7da7c66c453d134654d9795f9e8345f90e Mon Sep 17 00:00:00 2001 From: Tobias Grimm Date: Sun, 10 Mar 2013 16:58:24 +0100 Subject: Updated patch for VDR 1.7.40 --- .../0001-Record-teletext-subtitles.patch | 243 ----- ...-option-to-enable-teletext-subtitle-recor.patch | 470 --------- ...l-configuration-of-teletetxt-subtitle-pag.patch | 112 --- .../0004-Decrypt-teletext-stream.patch | 35 - ...-Capture-teletext-subtitle-pages-from-PMT.patch | 92 -- .../0006-Ttxtsubs-plugin-hook.patch | 256 ----- .../0001-Record-teletext-subtitles.patch | 243 +++++ ...-option-to-enable-teletext-subtitle-recor.patch | 470 +++++++++ ...l-configuration-of-teletetxt-subtitle-pag.patch | 112 +++ .../0004-Decrypt-teletext-stream.patch | 35 + ...-Capture-teletext-subtitle-pages-from-PMT.patch | 92 ++ .../0006-Ttxtsubs-plugin-hook.patch | 256 +++++ patches/vdr-1.7.38-ttxtsubs.patch | 1016 -------------------- patches/vdr-1.7.40-ttxtsubs.patch | 1016 ++++++++++++++++++++ 14 files changed, 2224 insertions(+), 2224 deletions(-) delete mode 100644 patches/patch-set.1.7.38/0001-Record-teletext-subtitles.patch delete mode 100644 patches/patch-set.1.7.38/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch delete mode 100644 patches/patch-set.1.7.38/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch delete mode 100644 patches/patch-set.1.7.38/0004-Decrypt-teletext-stream.patch delete mode 100644 patches/patch-set.1.7.38/0005-Capture-teletext-subtitle-pages-from-PMT.patch delete mode 100644 patches/patch-set.1.7.38/0006-Ttxtsubs-plugin-hook.patch create mode 100644 patches/patch-set.1.7.40/0001-Record-teletext-subtitles.patch create mode 100644 patches/patch-set.1.7.40/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch create mode 100644 patches/patch-set.1.7.40/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch create mode 100644 patches/patch-set.1.7.40/0004-Decrypt-teletext-stream.patch create mode 100644 patches/patch-set.1.7.40/0005-Capture-teletext-subtitle-pages-from-PMT.patch create mode 100644 patches/patch-set.1.7.40/0006-Ttxtsubs-plugin-hook.patch delete mode 100644 patches/vdr-1.7.38-ttxtsubs.patch create mode 100644 patches/vdr-1.7.40-ttxtsubs.patch diff --git a/patches/patch-set.1.7.38/0001-Record-teletext-subtitles.patch b/patches/patch-set.1.7.38/0001-Record-teletext-subtitles.patch deleted file mode 100644 index 77f5bdd..0000000 --- a/patches/patch-set.1.7.38/0001-Record-teletext-subtitles.patch +++ /dev/null @@ -1,243 +0,0 @@ -From a932f6d2b2569e64d7fc56b5f128917709ff5a8c Mon Sep 17 00:00:00 2001 -From: etobi -Date: Fri, 12 Feb 2010 21:55:04 +0100 -Subject: [PATCH 1/6] Record teletext subtitles - ---- - channels.c | 20 ++++++++++++++++++++ - channels.h | 16 ++++++++++++++++ - pat.c | 18 +++++++++++++++++- - receiver.c | 3 ++- - remux.c | 29 +++++++++++++++++++++++++++++ - remux.h | 3 +++ - 6 files changed, 87 insertions(+), 2 deletions(-) - -diff --git a/channels.c b/channels.c -index 4c04608..3eb31ce 100644 ---- a/channels.c -+++ b/channels.c -@@ -408,6 +408,26 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos - } - } - -+void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages) -+{ -+ int mod = CHANNELMOD_NONE; -+ if (totalTtxtSubtitlePages != numberOfPages) -+ mod |= CHANNELMOD_PIDS; -+ totalTtxtSubtitlePages = 0; -+ for (int i = 0; (i < numberOfPages) && (totalTtxtSubtitlePages < MAXTXTPAGES); i++) { -+ if (teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine != pages[i].ttxtMagazine || -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage != pages[i].ttxtPage || -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType != pages[i].ttxtType || -+ strcmp(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, pages[i].ttxtLanguage)) { -+ mod |= CHANNELMOD_PIDS; -+ teletextSubtitlePages[totalTtxtSubtitlePages] = pages[i]; -+ } -+ totalTtxtSubtitlePages++; -+ } -+ modification |= mod; -+ Channels.SetModified(); -+} -+ - void cChannel::SetCaIds(const int *CaIds) - { - if (caids[0] && caids[0] <= CA_USER_MAX) -diff --git a/channels.h b/channels.h -index 815cb47..dbdcb17 100644 ---- a/channels.h -+++ b/channels.h -@@ -35,6 +35,7 @@ - #define MAXDPIDS 16 // dolby (AC3 + DTS) - #define MAXSPIDS 32 // subtitles - #define MAXCAIDS 12 // conditional access -+#define MAXTXTPAGES 8 // teletext pages - - #define MAXLANGCODE1 4 // a 3 letter language code, zero terminated - #define MAXLANGCODE2 8 // up to two 3 letter language codes, separated by '+' and zero terminated -@@ -71,6 +72,16 @@ public: - static const tChannelID InvalidID; - }; - -+struct tTeletextSubtitlePage { -+ tTeletextSubtitlePage(void) { ttxtPage = ttxtMagazine = 0; ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } -+ tTeletextSubtitlePage(int page) { ttxtMagazine = (page / 100) & 0x7; ttxtPage = (((page % 100) / 10) << 4) + (page % 10); ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } -+ char ttxtLanguage[MAXLANGCODE1]; -+ uchar ttxtPage; -+ uchar ttxtMagazine; -+ uchar ttxtType; -+ int PageNumber(void) const { return BCDCHARTOINT(ttxtMagazine) * 100 + BCDCHARTOINT(ttxtPage); } -+ }; -+ - class cChannel; - - class cLinkChannel : public cListObject { -@@ -115,6 +126,8 @@ private: - uint16_t compositionPageIds[MAXSPIDS]; - uint16_t ancillaryPageIds[MAXSPIDS]; - int tpid; -+ int totalTtxtSubtitlePages; -+ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; - int caids[MAXCAIDS + 1]; // list is zero-terminated - int nid; - int tid; -@@ -166,6 +179,8 @@ public: - uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } - uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } - int Tpid(void) const { return tpid; } -+ const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } -+ int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } - const int *Caids(void) const { return caids; } - int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } - int Nid(void) const { return nid; } -@@ -192,6 +207,7 @@ public: - void SetName(const char *Name, const char *ShortName, const char *Provider); - void SetPortalName(const char *PortalName); - void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); -+ void SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages); - void SetCaIds(const int *CaIds); // list must be zero-terminated - void SetCaDescriptors(int Level); - void SetLinkChannels(cLinkChannels *LinkChannels); -diff --git a/pat.c b/pat.c -index a7791e2..3f89258 100644 ---- a/pat.c -+++ b/pat.c -@@ -343,6 +343,8 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length - char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" }; - char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" }; - int Tpid = 0; -+ tTeletextSubtitlePage TeletextSubtitlePages[MAXTXTPAGES]; -+ int NumTPages = 0; - int NumApids = 0; - int NumDpids = 0; - int NumSpids = 0; -@@ -434,8 +436,21 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length - NumSpids++; - } - break; -- case SI::TeletextDescriptorTag: -+ case SI::TeletextDescriptorTag: { - Tpid = esPid; -+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; -+ SI::TeletextDescriptor::Teletext ttxt; -+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { -+ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); -+ if ((NumTPages < MAXTXTPAGES) && ttxt.languageCode[0] && isSubtitlePage) { -+ strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); -+ TeletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber(); -+ TeletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); -+ TeletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType(); -+ NumTPages++; -+ } -+ } -+ } - break; - case SI::ISO639LanguageDescriptorTag: { - SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; -@@ -547,6 +562,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length - } - if (Setup.UpdateChannels >= 2) { - Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid); -+ Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages); - Channel->SetCaIds(CaDescriptors->CaIds()); - Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); - } -diff --git a/receiver.c b/receiver.c -index bde60e4..8a27b99 100644 ---- a/receiver.c -+++ b/receiver.c -@@ -67,7 +67,8 @@ bool cReceiver::SetPids(const cChannel *Channel) - (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) && - AddPids(Channel->Apids()) && - AddPids(Channel->Dpids()) && -- AddPids(Channel->Spids()); -+ AddPids(Channel->Spids()) && -+ AddPid(Channel->Tpid()); - } - return true; - } -diff --git a/remux.c b/remux.c -index 9be3078..2e31012 100644 ---- a/remux.c -+++ b/remux.c -@@ -385,6 +385,29 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua - return i; - } - -+int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount) -+{ -+ int i = 0, j = 0; -+ Target[i++] = SI::TeletextDescriptorTag; -+ int l = i; -+ Target[i++] = 0x00; // length -+ for (int n = 0; n < pageCount; n++) { -+ const char* Language = pages[n].ttxtLanguage; -+ Target[i++] = *Language++; -+ Target[i++] = *Language++; -+ Target[i++] = *Language++; -+ Target[i++] = (pages[n].ttxtType << 3) + pages[n].ttxtMagazine; -+ Target[i++] = pages[n].ttxtPage; -+ j++; -+ } -+ if (j > 0) { -+ Target[l] = j * 5; // update length -+ IncEsInfoLength(i); -+ return i; -+ } -+ return 0; -+} -+ - int cPatPmtGenerator::MakeLanguageDescriptor(uchar *Target, const char *Language) - { - int i = 0; -@@ -472,6 +495,7 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) - if (Channel) { - int Vpid = Channel->Vpid(); - int Ppid = Channel->Ppid(); -+ int Tpid = Channel->Tpid(); - uchar *p = buf; - int i = 0; - p[i++] = 0x02; // table id -@@ -504,6 +528,10 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) - i += MakeStream(buf + i, 0x06, Channel->Spid(n)); - i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n), Channel->SubtitlingType(n), Channel->CompositionPageId(n), Channel->AncillaryPageId(n)); - } -+ if (Tpid) { -+ i += MakeStream(buf + i, 0x06, Tpid); -+ i += MakeTeletextDescriptor(buf + i, Channel->TeletextSubtitlePages(), Channel->TotalTeletextSubtitlePages()); -+ } - - int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC - buf[SectionLength] |= (sl >> 8) & 0x0F; -@@ -670,6 +698,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) - spids[0] = 0; - atypes[0] = 0; - dtypes[0] = 0; -+ totalTtxtSubtitlePages = 0; - SI::PMT::Stream stream; - for (SI::Loop::Iterator it; Pmt.streamLoop.getNext(stream, it); ) { - dbgpatpmt(" stream type = %02X, pid = %d", stream.getStreamType(), stream.getPid()); -diff --git a/remux.h b/remux.h -index 67eda4c..4cef4da 100644 ---- a/remux.h -+++ b/remux.h -@@ -294,6 +294,7 @@ protected: - int MakeStream(uchar *Target, uchar Type, int Pid); - int MakeAC3Descriptor(uchar *Target, uchar Type); - int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId); -+ int MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount); - int MakeLanguageDescriptor(uchar *Target, const char *Language); - int MakeCRC(uchar *Target, const uchar *Data, int Length); - void GeneratePmtPid(const cChannel *Channel); -@@ -353,6 +354,8 @@ private: - uint16_t compositionPageIds[MAXSPIDS]; - uint16_t ancillaryPageIds[MAXSPIDS]; - bool updatePrimaryDevice; -+ int totalTtxtSubtitlePages; -+ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; - protected: - int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; } - public: --- -1.7.10.4 - diff --git a/patches/patch-set.1.7.38/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch b/patches/patch-set.1.7.38/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch deleted file mode 100644 index f492f11..0000000 --- a/patches/patch-set.1.7.38/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch +++ /dev/null @@ -1,470 +0,0 @@ -From 52b572646b476bbe402fc56e929de310b949efdf Mon Sep 17 00:00:00 2001 -From: etobi -Date: Sat, 13 Feb 2010 14:42:30 +0100 -Subject: [PATCH 2/6] Added setup option to enable teletext subtitle recording - ---- - MANUAL | 3 +++ - config.c | 3 +++ - config.h | 1 + - menu.c | 1 + - po/ca_ES.po | 3 +++ - po/cs_CZ.po | 3 +++ - po/da_DK.po | 3 +++ - po/de_DE.po | 3 +++ - po/el_GR.po | 3 +++ - po/es_ES.po | 3 +++ - po/et_EE.po | 3 +++ - po/fi_FI.po | 3 +++ - po/fr_FR.po | 3 +++ - po/hr_HR.po | 3 +++ - po/hu_HU.po | 3 +++ - po/it_IT.po | 3 +++ - po/lt_LT.po | 3 +++ - po/nl_NL.po | 3 +++ - po/nn_NO.po | 3 +++ - po/pl_PL.po | 3 +++ - po/pt_PT.po | 3 +++ - po/ro_RO.po | 3 +++ - po/ru_RU.po | 3 +++ - po/sk_SK.po | 3 +++ - po/sl_SI.po | 3 +++ - po/sv_SE.po | 3 +++ - po/tr_TR.po | 3 +++ - po/uk_UA.po | 3 +++ - po/zh_CN.po | 3 +++ - receiver.c | 2 +- - 30 files changed, 84 insertions(+), 1 deletion(-) - -diff --git a/MANUAL b/MANUAL -index e8321a4..f96b183 100644 ---- a/MANUAL -+++ b/MANUAL -@@ -756,6 +756,9 @@ Version 1.6 - background transparency. By default the values as broadcast - are used. - -+ Enable teletext support = yes -+ If set to 'yes', enables teletext subtitles. -+ - LNB: - - Use DiSEqC = no Generally turns DiSEqC support on or off. -diff --git a/config.c b/config.c -index 2c87985..9ed5435 100644 ---- a/config.c -+++ b/config.c -@@ -397,6 +397,7 @@ cSetup::cSetup(void) - MarginStop = 10; - AudioLanguages[0] = -1; - DisplaySubtitles = 0; -+ SupportTeletext = 1; - SubtitleLanguages[0] = -1; - SubtitleOffset = 0; - SubtitleFgTransparency = 0; -@@ -601,6 +602,7 @@ bool cSetup::Parse(const char *Name, const char *Value) - else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value); - else if (!strcasecmp(Name, "AudioLanguages")) return ParseLanguages(Value, AudioLanguages); - else if (!strcasecmp(Name, "DisplaySubtitles")) DisplaySubtitles = atoi(Value); -+ else if (!strcasecmp(Name, "SupportTeletext")) SupportTeletext = atoi(Value); - else if (!strcasecmp(Name, "SubtitleLanguages")) return ParseLanguages(Value, SubtitleLanguages); - else if (!strcasecmp(Name, "SubtitleOffset")) SubtitleOffset = atoi(Value); - else if (!strcasecmp(Name, "SubtitleFgTransparency")) SubtitleFgTransparency = atoi(Value); -@@ -709,6 +711,7 @@ bool cSetup::Save(void) - Store("MarginStop", MarginStop); - StoreLanguages("AudioLanguages", AudioLanguages); - Store("DisplaySubtitles", DisplaySubtitles); -+ Store("SupportTeletext", SupportTeletext); - StoreLanguages("SubtitleLanguages", SubtitleLanguages); - Store("SubtitleOffset", SubtitleOffset); - Store("SubtitleFgTransparency", SubtitleFgTransparency); -diff --git a/config.h b/config.h -index 693e927..b5ca1a5 100644 ---- a/config.h -+++ b/config.h -@@ -273,6 +273,7 @@ public: - int MarginStart, MarginStop; - int AudioLanguages[I18N_MAX_LANGUAGES + 1]; - int DisplaySubtitles; -+ int SupportTeletext; - int SubtitleLanguages[I18N_MAX_LANGUAGES + 1]; - int SubtitleOffset; - int SubtitleFgTransparency, SubtitleBgTransparency; -diff --git a/menu.c b/menu.c -index 69fe6d5..5df7fbb 100644 ---- a/menu.c -+++ b/menu.c -@@ -2840,6 +2840,7 @@ void cMenuSetupDVB::Setup(void) - Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); - Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); - } -+ Add(new cMenuEditBoolItem(tr("Setup.DVB$Enable teletext support"), &data.SupportTeletext)); - - SetCurrent(Get(current)); - Display(); -diff --git a/po/ca_ES.po b/po/ca_ES.po -index f1a24fc..c2e0379 100644 ---- a/po/ca_ES.po -+++ b/po/ca_ES.po -@@ -971,6 +971,9 @@ msgstr "Transpar - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparncia fons subttols" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "Configuraci de l'LNB" - -diff --git a/po/cs_CZ.po b/po/cs_CZ.po -index a4f2515..02360b3 100644 ---- a/po/cs_CZ.po -+++ b/po/cs_CZ.po -@@ -970,6 +970,9 @@ msgstr "Průhlednost písma titulků" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Průhlednost pozadí titulků" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/da_DK.po b/po/da_DK.po -index 511e03f..4b6b9bb 100644 ---- a/po/da_DK.po -+++ b/po/da_DK.po -@@ -968,6 +968,9 @@ msgstr "Undertekst forgrundsgennemsigtighed" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Undertekst baggrundsgennemsigtighed" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/de_DE.po b/po/de_DE.po -index 77af04a..a8c28c5 100644 ---- a/po/de_DE.po -+++ b/po/de_DE.po -@@ -968,6 +968,9 @@ msgstr "Untertitel-Transparenz Vordergrund" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Untertitel-Transparenz Hintergrund" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "Videotext-Untersttzung aktivieren" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/el_GR.po b/po/el_GR.po -index d0c1c7d..7d32ec6 100644 ---- a/po/el_GR.po -+++ b/po/el_GR.po -@@ -968,6 +968,9 @@ msgstr "" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/es_ES.po b/po/es_ES.po -index 9e120e7..7e03fdf 100644 ---- a/po/es_ES.po -+++ b/po/es_ES.po -@@ -969,6 +969,9 @@ msgstr "Transparencia primer plano subt - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparencia fondo subttulos" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/et_EE.po b/po/et_EE.po -index ffb3c91..397d0d5 100644 ---- a/po/et_EE.po -+++ b/po/et_EE.po -@@ -968,6 +968,9 @@ msgstr "Subtiitri läbipaistvus" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Subtiitri tausta läbipaistvus" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "Teleteksti tugi" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/fi_FI.po b/po/fi_FI.po -index 164a376..db4b455 100644 ---- a/po/fi_FI.po -+++ b/po/fi_FI.po -@@ -971,6 +971,9 @@ msgstr "Tekstityksen läpinäkyvyys" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Tekstityksen taustan läpinäkyvyys" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "Salli teksti-TV-tuki" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/fr_FR.po b/po/fr_FR.po -index eaf31b1..a6a2433 100644 ---- a/po/fr_FR.po -+++ b/po/fr_FR.po -@@ -978,6 +978,9 @@ msgstr "Transparence de l'avant-plan des sous-titres" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparence du fond des sous-titres" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/hr_HR.po b/po/hr_HR.po -index af63cc1..65a644a 100644 ---- a/po/hr_HR.po -+++ b/po/hr_HR.po -@@ -970,6 +970,9 @@ msgstr "Transparentnost titla" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparentnost pozadine titla" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/hu_HU.po b/po/hu_HU.po -index a2cc9d0..00637e7 100644 ---- a/po/hu_HU.po -+++ b/po/hu_HU.po -@@ -971,6 +971,9 @@ msgstr "Felirat transzparenci - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Felirat htternek transzparencija" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/it_IT.po b/po/it_IT.po -index e6c848b..dd92b7c 100644 ---- a/po/it_IT.po -+++ b/po/it_IT.po -@@ -975,6 +975,9 @@ msgstr "Trasparenza sottotitoli" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Trasparenza sfondo sottotitoli" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/lt_LT.po b/po/lt_LT.po -index e9f24ca..2e881ad 100644 ---- a/po/lt_LT.po -+++ b/po/lt_LT.po -@@ -968,6 +968,9 @@ msgstr "Subtitrų fonto permatomumas" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Subtitrų fono permatomumas" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "Konverteris (LNB)" - -diff --git a/po/nl_NL.po b/po/nl_NL.po -index ab16a2a..ce4938d 100644 ---- a/po/nl_NL.po -+++ b/po/nl_NL.po -@@ -972,6 +972,9 @@ msgstr "Transparantie voorgrond ondertiteling" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparantie achtergrond ondertiteling" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/nn_NO.po b/po/nn_NO.po -index 664018b..2a8df35 100644 ---- a/po/nn_NO.po -+++ b/po/nn_NO.po -@@ -969,6 +969,9 @@ msgstr "" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/pl_PL.po b/po/pl_PL.po -index 1580b0b..b0ecc72 100644 ---- a/po/pl_PL.po -+++ b/po/pl_PL.po -@@ -969,6 +969,9 @@ msgstr "Prze - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Przerocze podtytuw: To" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/pt_PT.po b/po/pt_PT.po -index 9dec287..4947fb0 100644 ---- a/po/pt_PT.po -+++ b/po/pt_PT.po -@@ -969,6 +969,9 @@ msgstr "Transpar - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparncia de fundo das legendas" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/ro_RO.po b/po/ro_RO.po -index 4c257ad..77e47f8 100644 ---- a/po/ro_RO.po -+++ b/po/ro_RO.po -@@ -970,6 +970,9 @@ msgstr "Transparenţa prim-planului subtitrării" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparenţa fundalului subtitrării" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/ru_RU.po b/po/ru_RU.po -index 9bcf571..194c232 100644 ---- a/po/ru_RU.po -+++ b/po/ru_RU.po -@@ -969,6 +969,9 @@ msgstr " - msgid "Setup.DVB$Subtitle background transparency" - msgstr " " - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "" - -diff --git a/po/sk_SK.po b/po/sk_SK.po -index 6aea45c..26fbe99 100644 ---- a/po/sk_SK.po -+++ b/po/sk_SK.po -@@ -968,6 +968,9 @@ msgstr "Prieh - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Priehadnos pozadia titulkov" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/sl_SI.po b/po/sl_SI.po -index 6c6abb5..248894d 100644 ---- a/po/sl_SI.po -+++ b/po/sl_SI.po -@@ -969,6 +969,9 @@ msgstr "Transparentnost podnapisov" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparentnost ozadja podnapisov" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/sv_SE.po b/po/sv_SE.po -index b5df87d..b7cbf83 100644 ---- a/po/sv_SE.po -+++ b/po/sv_SE.po -@@ -971,6 +971,9 @@ msgstr "Transparent f - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparent bakgrund textremsa" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/tr_TR.po b/po/tr_TR.po -index 30e3fbd..45c79a5 100644 ---- a/po/tr_TR.po -+++ b/po/tr_TR.po -@@ -968,6 +968,9 @@ msgstr "Altyaz - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Altyaz arka effaflk" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/uk_UA.po b/po/uk_UA.po -index 82b8d2a..5484634 100644 ---- a/po/uk_UA.po -+++ b/po/uk_UA.po -@@ -969,6 +969,9 @@ msgstr "Прозорість переднього плану субтитрів" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Прозорість заднього плану субтитрів" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "Конвертер" - -diff --git a/po/zh_CN.po b/po/zh_CN.po -index 3f4a6c6..6724c9c 100644 ---- a/po/zh_CN.po -+++ b/po/zh_CN.po -@@ -971,6 +971,9 @@ msgstr "字幕前景透明度" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "字幕背景透明度" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "切换器设置" - -diff --git a/receiver.c b/receiver.c -index 8a27b99..fa9c436 100644 ---- a/receiver.c -+++ b/receiver.c -@@ -68,7 +68,7 @@ bool cReceiver::SetPids(const cChannel *Channel) - AddPids(Channel->Apids()) && - AddPids(Channel->Dpids()) && - AddPids(Channel->Spids()) && -- AddPid(Channel->Tpid()); -+ (!Setup.SupportTeletext || AddPid(Channel->Tpid())); - } - return true; - } --- -1.7.10.4 - diff --git a/patches/patch-set.1.7.38/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch b/patches/patch-set.1.7.38/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch deleted file mode 100644 index 9b2d4ba..0000000 --- a/patches/patch-set.1.7.38/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 1c37c1a96eaac460f3905ec46899a3361044fe16 Mon Sep 17 00:00:00 2001 -From: etobi -Date: Fri, 12 Feb 2010 21:56:41 +0100 -Subject: [PATCH 3/6] Allow manual configuration of teletetxt subtitle pages - in channels.conf - ---- - channels.c | 39 ++++++++++++++++++++++++++++++++++++--- - channels.h | 1 + - vdr.5 | 6 ++++++ - 3 files changed, 43 insertions(+), 3 deletions(-) - -diff --git a/channels.c b/channels.c -index 3eb31ce..a7f69a9 100644 ---- a/channels.c -+++ b/channels.c -@@ -411,9 +411,9 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos - void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages) - { - int mod = CHANNELMOD_NONE; -- if (totalTtxtSubtitlePages != numberOfPages) -+ if (totalTtxtSubtitlePages != (fixedTtxtSubtitlePages + numberOfPages)) - mod |= CHANNELMOD_PIDS; -- totalTtxtSubtitlePages = 0; -+ totalTtxtSubtitlePages = fixedTtxtSubtitlePages; - for (int i = 0; (i < numberOfPages) && (totalTtxtSubtitlePages < MAXTXTPAGES); i++) { - if (teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine != pages[i].ttxtMagazine || - teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage != pages[i].ttxtPage || -@@ -556,10 +556,17 @@ cString cChannel::ToText(const cChannel *Channel) - q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs, Channel->dtypes); - } - *q = 0; -- const int TBufferSize = MAXSPIDS * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid -+ const int TBufferSize = (MAXTXTPAGES * MAXSPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid - char tpidbuf[TBufferSize]; - q = tpidbuf; - q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid); -+ if (Channel->fixedTtxtSubtitlePages > 0) { -+ *q++ = '+'; -+ for (int i = 0; i < Channel->fixedTtxtSubtitlePages; ++i) { -+ tTeletextSubtitlePage page = Channel->teletextSubtitlePages[i]; -+ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), "%d=%s", page.PageNumber(), page.ttxtLanguage); -+ } -+ } - if (Channel->spids[0]) { - *q++ = ';'; - q += IntArrayToString(q, Channel->spids, 10, Channel->slangs); -@@ -730,6 +737,32 @@ bool cChannel::Parse(const char *s) - } - spids[NumSpids] = 0; - } -+ fixedTtxtSubtitlePages = 0; -+ if ((p = strchr(tpidbuf, '+')) != NULL) { -+ *p++ = 0; -+ char *q; -+ char *strtok_next; -+ while ((q = strtok_r(p, ",", &strtok_next)) != NULL) { -+ if (fixedTtxtSubtitlePages < MAXTXTPAGES) { -+ int page; -+ char *l = strchr(q, '='); -+ if (l) -+ *l++ = 0; -+ if (sscanf(q, "%d", &page) == 1) { -+ teletextSubtitlePages[fixedTtxtSubtitlePages] = tTeletextSubtitlePage(page); -+ if (l) -+ strn0cpy(teletextSubtitlePages[fixedTtxtSubtitlePages].ttxtLanguage, l, MAXLANGCODE2); -+ fixedTtxtSubtitlePages++; -+ } -+ else -+ esyslog("ERROR: invalid Teletext page!"); // no need to set ok to 'false' -+ } -+ else -+ esyslog("ERROR: too many Teletext pages!"); // no need to set ok to 'false' -+ p = NULL; -+ } -+ totalTtxtSubtitlePages = fixedTtxtSubtitlePages; -+ } - if (sscanf(tpidbuf, "%d", &tpid) != 1) - return false; - if (caidbuf) { -diff --git a/channels.h b/channels.h -index dbdcb17..b407672 100644 ---- a/channels.h -+++ b/channels.h -@@ -126,6 +126,7 @@ private: - uint16_t compositionPageIds[MAXSPIDS]; - uint16_t ancillaryPageIds[MAXSPIDS]; - int tpid; -+ int fixedTtxtSubtitlePages; - int totalTtxtSubtitlePages; - tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; - int caids[MAXCAIDS + 1]; // list is zero-terminated -diff --git a/vdr.5 b/vdr.5 -index 4003a5e..cb1552d 100644 ---- a/vdr.5 -+++ b/vdr.5 -@@ -233,6 +233,12 @@ by an '=' sign, as in - - .B ...:201;2001=deu,2002=eng:... - -+Manual teletext subtitling pages can be defined separated by a '+' sign. -+The pages (separated by commas) can contain language codes, delimited by a '=' -+sign, as in -+ -+.B ...:201+150=deu,151=fin;2001,2002:... -+ - .TP - .B Conditional access - A hexadecimal integer defining how this channel can be accessed: --- -1.7.10.4 - diff --git a/patches/patch-set.1.7.38/0004-Decrypt-teletext-stream.patch b/patches/patch-set.1.7.38/0004-Decrypt-teletext-stream.patch deleted file mode 100644 index fb432d0..0000000 --- a/patches/patch-set.1.7.38/0004-Decrypt-teletext-stream.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 08f2963cfb42038575a741e2902b9b7a95c0a0f8 Mon Sep 17 00:00:00 2001 -From: etobi -Date: Sun, 14 Feb 2010 01:30:34 +0100 -Subject: [PATCH 4/6] Decrypt teletext stream - ---- - ci.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/ci.c b/ci.c -index 9a4a829..ec84027 100644 ---- a/ci.c -+++ b/ci.c -@@ -1914,6 +1914,8 @@ void cCamSlot::AddChannel(const cChannel *Channel) - AddPid(Channel->Sid(), *Dpid, STREAM_TYPE_PRIVATE); - for (const int *Spid = Channel->Spids(); *Spid; Spid++) - AddPid(Channel->Sid(), *Spid, STREAM_TYPE_PRIVATE); -+ if (Channel->Tpid() && Setup.SupportTeletext) -+ AddPid(Channel->Sid(), Channel->Tpid(), STREAM_TYPE_PRIVATE); - } - } - -@@ -1937,6 +1939,9 @@ bool cCamSlot::CanDecrypt(const cChannel *Channel) - CaPmt.AddPid(*Dpid, STREAM_TYPE_PRIVATE); - for (const int *Spid = Channel->Spids(); *Spid; Spid++) - CaPmt.AddPid(*Spid, STREAM_TYPE_PRIVATE); -+ if (Channel->Tpid() && Setup.SupportTeletext) { -+ CaPmt.AddPid(Channel->Tpid(), STREAM_TYPE_PRIVATE); -+ } - cas->SendPMT(&CaPmt); - cTimeMs Timeout(QUERY_REPLY_TIMEOUT); - do { --- -1.7.10.4 - diff --git a/patches/patch-set.1.7.38/0005-Capture-teletext-subtitle-pages-from-PMT.patch b/patches/patch-set.1.7.38/0005-Capture-teletext-subtitle-pages-from-PMT.patch deleted file mode 100644 index f6b689d..0000000 --- a/patches/patch-set.1.7.38/0005-Capture-teletext-subtitle-pages-from-PMT.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0460f10ead868f796e642adf6a3bdc1b6d8ca190 Mon Sep 17 00:00:00 2001 -From: etobi -Date: Fri, 12 Feb 2010 22:06:19 +0100 -Subject: [PATCH 5/6] Capture teletext subtitle pages from PMT - ---- - remux.c | 24 ++++++++++++++++++++++++ - remux.h | 5 +++++ - 2 files changed, 29 insertions(+) - -diff --git a/remux.c b/remux.c -index 2e31012..3c7a156 100644 ---- a/remux.c -+++ b/remux.c -@@ -605,6 +605,7 @@ void cPatPmtParser::Reset(void) - pmtPids[0] = 0; - vpid = vtype = 0; - ppid = 0; -+ tpid = 0; - } - - void cPatPmtParser::ParsePat(const uchar *Data, int Length) -@@ -693,6 +694,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) - int NumSpids = 0; - vpid = vtype = 0; - ppid = 0; -+ tpid = 0; - apids[0] = 0; - dpids[0] = 0; - spids[0] = 0; -@@ -797,6 +799,28 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) - spids[NumSpids]= 0; - } - break; -+ case SI::TeletextDescriptorTag: { -+ dbgpatpmt(" teletext"); -+ tpid = stream.getPid(); -+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; -+ SI::TeletextDescriptor::Teletext ttxt; -+ if (totalTtxtSubtitlePages < MAXTXTPAGES) { -+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { -+ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); -+ if (isSubtitlePage && ttxt.languageCode[0]) { -+ dbgpatpmt(" '%s:%x.%x'", ttxt.languageCode, ttxt.getTeletextMagazineNumber(), ttxt.getTeletextPageNumber()); -+ strn0cpy(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage = ttxt.getTeletextPageNumber(); -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType = ttxt.getTeletextType(); -+ totalTtxtSubtitlePages++; -+ if (totalTtxtSubtitlePages >= MAXTXTPAGES) -+ break; -+ } -+ } -+ } -+ } -+ break; - case SI::ISO639LanguageDescriptorTag: { - SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; - dbgpatpmt(" '%s'", ld->languageCode); -diff --git a/remux.h b/remux.h -index 4cef4da..203ed34 100644 ---- a/remux.h -+++ b/remux.h -@@ -342,6 +342,7 @@ private: - int vpid; - int ppid; - int vtype; -+ int tpid; - int apids[MAXAPIDS + 1]; // list is zero-terminated - int atypes[MAXAPIDS + 1]; // list is zero-terminated - char alangs[MAXAPIDS][MAXLANGCODE2]; -@@ -392,6 +393,9 @@ public: - int Vtype(void) const { return vtype; } - ///< Returns the video stream type as defined by the current PMT, or 0 if no video - ///< stream type has been detected, yet. -+ int Tpid(void) { return tpid; } -+ ///< Returns the teletext pid as defined by the current PMT, or 0 if no teletext -+ ///< pid has been detected, yet. - const int *Apids(void) const { return apids; } - const int *Dpids(void) const { return dpids; } - const int *Spids(void) const { return spids; } -@@ -406,6 +410,7 @@ public: - uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS) ? subtitlingTypes[i] : uchar(0); } - uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } - uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } -+ const tTeletextSubtitlePage* TeletextSubtitlePages() const { return teletextSubtitlePages; } - }; - - // TS to PES converter: --- -1.7.10.4 - diff --git a/patches/patch-set.1.7.38/0006-Ttxtsubs-plugin-hook.patch b/patches/patch-set.1.7.38/0006-Ttxtsubs-plugin-hook.patch deleted file mode 100644 index 9f0fec2..0000000 --- a/patches/patch-set.1.7.38/0006-Ttxtsubs-plugin-hook.patch +++ /dev/null @@ -1,256 +0,0 @@ -From 321f443bfd3273602e62ecc5f008a7f2a78bb17d Mon Sep 17 00:00:00 2001 -From: etobi -Date: Sat, 13 Feb 2010 00:28:21 +0100 -Subject: [PATCH 6/6] Ttxtsubs plugin hook - ---- - Makefile | 2 ++ - device.c | 20 +++++++++++++++++ - device.h | 1 + - pat.c | 6 +++++ - remux.h | 3 ++- - vdrttxtsubshooks.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - vdrttxtsubshooks.h | 46 ++++++++++++++++++++++++++++++++++++++ - 7 files changed, 140 insertions(+), 1 deletion(-) - create mode 100644 vdrttxtsubshooks.c - create mode 100644 vdrttxtsubshooks.h - -diff --git a/Makefile b/Makefile -index db59754..d6afb7e 100644 ---- a/Makefile -+++ b/Makefile -@@ -73,6 +73,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d - skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\ - timers.o tools.o transfer.o vdr.o videodir.o - -+OBJS += vdrttxtsubshooks.o -+ - DEFINES += $(CDEFINES) - INCLUDES += $(CINCLUDES) - -diff --git a/device.c b/device.c -index ca897b0..f22c6eb 100644 ---- a/device.c -+++ b/device.c -@@ -18,6 +18,7 @@ - #include "receiver.h" - #include "status.h" - #include "transfer.h" -+#include "vdrttxtsubshooks.h" - - // --- cLiveSubtitle --------------------------------------------------------- - -@@ -1313,6 +1314,13 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly) - } - break; - case 0xBD: { // private stream 1 -+ // EBU Teletext data, ETSI EN 300 472 -+ // if PES data header length = 24 and data_identifier = 0x10..0x1F (EBU Data) -+ if (Data[8] == 0x24 && Data[45] >= 0x10 && Data[45] < 0x20) { -+ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uint8_t*)Data, Length); -+ break; -+ } -+ - int PayloadOffset = Data[8] + 9; - - // Compatibility mode for old subtitles plugin: -@@ -1472,6 +1480,7 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) - tsToPesVideo.Reset(); - tsToPesAudio.Reset(); - tsToPesSubtitle.Reset(); -+ tsToPesTeletext.Reset(); - } - else if (Length < TS_SIZE) { - esyslog("ERROR: skipped %d bytes of TS fragment", Length); -@@ -1517,6 +1526,17 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) - if (!VideoOnly || HasIBPTrickSpeed()) - PlayTsSubtitle(Data, TS_SIZE); - } -+ else if (Pid == patPmtParser.Tpid()) { -+ if (!VideoOnly || HasIBPTrickSpeed()) { -+ int l; -+ tsToPesTeletext.PutTs(Data, Length); -+ if (const uchar *p = tsToPesTeletext.GetPes(l)) { -+ if ((l > 45) && (p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xbd) && (p[8] == 0x24) && (p[45] >= 0x10) && (p[45] < 0x20)) -+ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uchar *)p, l, false, patPmtParser.TeletextSubtitlePages(), patPmtParser.TotalTeletextSubtitlePages()); -+ tsToPesTeletext.Reset(); -+ } -+ } -+ } - } - } - else if (Pid == patPmtParser.Ppid()) { -diff --git a/device.h b/device.h -index fd010d4..41d410c 100644 ---- a/device.h -+++ b/device.h -@@ -584,6 +584,7 @@ private: - cTsToPes tsToPesVideo; - cTsToPes tsToPesAudio; - cTsToPes tsToPesSubtitle; -+ cTsToPes tsToPesTeletext; - bool isPlayingVideo; - protected: - const cPatPmtParser *PatPmtParser(void) const { return &patPmtParser; } -diff --git a/pat.c b/pat.c -index 3f89258..d9731f8 100644 ---- a/pat.c -+++ b/pat.c -@@ -13,6 +13,7 @@ - #include "libsi/section.h" - #include "libsi/descriptor.h" - #include "thread.h" -+#include "vdrttxtsubshooks.h" - - #define PMT_SCAN_TIMEOUT 10 // seconds - -@@ -562,6 +563,11 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length - } - if (Setup.UpdateChannels >= 2) { - Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid); -+ if (NumTPages < MAXTXTPAGES) { -+ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel); -+ if (manualPageNumber) -+ TeletextSubtitlePages[NumTPages++] = tTeletextSubtitlePage(manualPageNumber); -+ } - Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages); - Channel->SetCaIds(CaDescriptors->CaIds()); - Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); -diff --git a/remux.h b/remux.h -index 203ed34..396f41d 100644 ---- a/remux.h -+++ b/remux.h -@@ -410,7 +410,8 @@ public: - uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS) ? subtitlingTypes[i] : uchar(0); } - uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } - uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } -- const tTeletextSubtitlePage* TeletextSubtitlePages() const { return teletextSubtitlePages; } -+ const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } -+ int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } - }; - - // TS to PES converter: -diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c -new file mode 100644 -index 0000000..2471788 ---- /dev/null -+++ b/vdrttxtsubshooks.c -@@ -0,0 +1,63 @@ -+/* -+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2003 - 2008 Ragnar Sundblad -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include "vdrttxtsubshooks.h" -+ -+// XXX Really should be a list... -+static cVDRTtxtsubsHookListener *gListener; -+ -+// ------ class cVDRTtxtsubsHookProxy ------ -+ -+class cVDRTtxtsubsHookProxy : public cVDRTtxtsubsHookListener -+{ -+ public: -+ virtual void HideOSD(void) { if(gListener) gListener->HideOSD(); }; -+ virtual void ShowOSD(void) { if(gListener) gListener->ShowOSD(); }; -+ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) -+ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording, teletextSubtitlePages, pageCount); }; -+ virtual int ManualPageNumber(const cChannel *channel) -+ { if(gListener) return gListener->ManualPageNumber(channel); else return 0; }; -+}; -+ -+ -+// ------ class cVDRTtxtsubsHookListener ------ -+ -+cVDRTtxtsubsHookListener::~cVDRTtxtsubsHookListener() -+{ -+ gListener = 0; -+} -+ -+void cVDRTtxtsubsHookListener::HookAttach(void) -+{ -+ gListener = this; -+ //printf("cVDRTtxtsubsHookListener::HookAttach\n"); -+} -+ -+static cVDRTtxtsubsHookProxy gProxy; -+ -+cVDRTtxtsubsHookListener *cVDRTtxtsubsHookListener::Hook(void) -+{ -+ return &gProxy; -+} -+ -diff --git a/vdrttxtsubshooks.h b/vdrttxtsubshooks.h -new file mode 100644 -index 0000000..2f97969 ---- /dev/null -+++ b/vdrttxtsubshooks.h -@@ -0,0 +1,46 @@ -+/* -+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2003 - 2008 Ragnar Sundblad -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#ifndef __VDRTTXTSUBSHOOKS_H -+#define __VDRTTXTSUBSHOOKS_H -+ -+#define TTXTSUBSVERSNUM 2 -+ -+class cDevice; -+class cChannel; -+struct tTeletextSubtitlePage; -+ -+class cVDRTtxtsubsHookListener { -+ public: -+ cVDRTtxtsubsHookListener(void) {}; -+ virtual ~cVDRTtxtsubsHookListener(); -+ -+ void HookAttach(void); -+ -+ virtual void HideOSD(void) {}; -+ virtual void ShowOSD(void) {}; -+ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording = true, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) {}; -+ virtual int ManualPageNumber(const cChannel *channel) { return 0; }; -+ -+ // used by VDR to call hook listeners -+ static cVDRTtxtsubsHookListener *Hook(void); -+}; -+ -+#endif --- -1.7.10.4 - diff --git a/patches/patch-set.1.7.40/0001-Record-teletext-subtitles.patch b/patches/patch-set.1.7.40/0001-Record-teletext-subtitles.patch new file mode 100644 index 0000000..3f826e2 --- /dev/null +++ b/patches/patch-set.1.7.40/0001-Record-teletext-subtitles.patch @@ -0,0 +1,243 @@ +From 9a23ec1bd9ccbb80bd860e03def6d90fae82d3c7 Mon Sep 17 00:00:00 2001 +From: etobi +Date: Fri, 12 Feb 2010 21:55:04 +0100 +Subject: [PATCH 1/6] Record teletext subtitles + +--- + channels.c | 20 ++++++++++++++++++++ + channels.h | 16 ++++++++++++++++ + pat.c | 18 +++++++++++++++++- + receiver.c | 3 ++- + remux.c | 29 +++++++++++++++++++++++++++++ + remux.h | 3 +++ + 6 files changed, 87 insertions(+), 2 deletions(-) + +diff --git a/channels.c b/channels.c +index 4c04608..3eb31ce 100644 +--- a/channels.c ++++ b/channels.c +@@ -408,6 +408,26 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos + } + } + ++void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages) ++{ ++ int mod = CHANNELMOD_NONE; ++ if (totalTtxtSubtitlePages != numberOfPages) ++ mod |= CHANNELMOD_PIDS; ++ totalTtxtSubtitlePages = 0; ++ for (int i = 0; (i < numberOfPages) && (totalTtxtSubtitlePages < MAXTXTPAGES); i++) { ++ if (teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine != pages[i].ttxtMagazine || ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage != pages[i].ttxtPage || ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType != pages[i].ttxtType || ++ strcmp(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, pages[i].ttxtLanguage)) { ++ mod |= CHANNELMOD_PIDS; ++ teletextSubtitlePages[totalTtxtSubtitlePages] = pages[i]; ++ } ++ totalTtxtSubtitlePages++; ++ } ++ modification |= mod; ++ Channels.SetModified(); ++} ++ + void cChannel::SetCaIds(const int *CaIds) + { + if (caids[0] && caids[0] <= CA_USER_MAX) +diff --git a/channels.h b/channels.h +index 815cb47..dbdcb17 100644 +--- a/channels.h ++++ b/channels.h +@@ -35,6 +35,7 @@ + #define MAXDPIDS 16 // dolby (AC3 + DTS) + #define MAXSPIDS 32 // subtitles + #define MAXCAIDS 12 // conditional access ++#define MAXTXTPAGES 8 // teletext pages + + #define MAXLANGCODE1 4 // a 3 letter language code, zero terminated + #define MAXLANGCODE2 8 // up to two 3 letter language codes, separated by '+' and zero terminated +@@ -71,6 +72,16 @@ public: + static const tChannelID InvalidID; + }; + ++struct tTeletextSubtitlePage { ++ tTeletextSubtitlePage(void) { ttxtPage = ttxtMagazine = 0; ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } ++ tTeletextSubtitlePage(int page) { ttxtMagazine = (page / 100) & 0x7; ttxtPage = (((page % 100) / 10) << 4) + (page % 10); ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } ++ char ttxtLanguage[MAXLANGCODE1]; ++ uchar ttxtPage; ++ uchar ttxtMagazine; ++ uchar ttxtType; ++ int PageNumber(void) const { return BCDCHARTOINT(ttxtMagazine) * 100 + BCDCHARTOINT(ttxtPage); } ++ }; ++ + class cChannel; + + class cLinkChannel : public cListObject { +@@ -115,6 +126,8 @@ private: + uint16_t compositionPageIds[MAXSPIDS]; + uint16_t ancillaryPageIds[MAXSPIDS]; + int tpid; ++ int totalTtxtSubtitlePages; ++ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; + int caids[MAXCAIDS + 1]; // list is zero-terminated + int nid; + int tid; +@@ -166,6 +179,8 @@ public: + uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } + uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } + int Tpid(void) const { return tpid; } ++ const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } ++ int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } + const int *Caids(void) const { return caids; } + int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } + int Nid(void) const { return nid; } +@@ -192,6 +207,7 @@ public: + void SetName(const char *Name, const char *ShortName, const char *Provider); + void SetPortalName(const char *PortalName); + void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); ++ void SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages); + void SetCaIds(const int *CaIds); // list must be zero-terminated + void SetCaDescriptors(int Level); + void SetLinkChannels(cLinkChannels *LinkChannels); +diff --git a/pat.c b/pat.c +index a7791e2..3f89258 100644 +--- a/pat.c ++++ b/pat.c +@@ -343,6 +343,8 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length + char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" }; + char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" }; + int Tpid = 0; ++ tTeletextSubtitlePage TeletextSubtitlePages[MAXTXTPAGES]; ++ int NumTPages = 0; + int NumApids = 0; + int NumDpids = 0; + int NumSpids = 0; +@@ -434,8 +436,21 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length + NumSpids++; + } + break; +- case SI::TeletextDescriptorTag: ++ case SI::TeletextDescriptorTag: { + Tpid = esPid; ++ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; ++ SI::TeletextDescriptor::Teletext ttxt; ++ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { ++ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); ++ if ((NumTPages < MAXTXTPAGES) && ttxt.languageCode[0] && isSubtitlePage) { ++ strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); ++ TeletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber(); ++ TeletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); ++ TeletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType(); ++ NumTPages++; ++ } ++ } ++ } + break; + case SI::ISO639LanguageDescriptorTag: { + SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; +@@ -547,6 +562,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length + } + if (Setup.UpdateChannels >= 2) { + Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid); ++ Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages); + Channel->SetCaIds(CaDescriptors->CaIds()); + Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); + } +diff --git a/receiver.c b/receiver.c +index bde60e4..8a27b99 100644 +--- a/receiver.c ++++ b/receiver.c +@@ -67,7 +67,8 @@ bool cReceiver::SetPids(const cChannel *Channel) + (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) && + AddPids(Channel->Apids()) && + AddPids(Channel->Dpids()) && +- AddPids(Channel->Spids()); ++ AddPids(Channel->Spids()) && ++ AddPid(Channel->Tpid()); + } + return true; + } +diff --git a/remux.c b/remux.c +index 587d7e5..fa5a650 100644 +--- a/remux.c ++++ b/remux.c +@@ -385,6 +385,29 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua + return i; + } + ++int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount) ++{ ++ int i = 0, j = 0; ++ Target[i++] = SI::TeletextDescriptorTag; ++ int l = i; ++ Target[i++] = 0x00; // length ++ for (int n = 0; n < pageCount; n++) { ++ const char* Language = pages[n].ttxtLanguage; ++ Target[i++] = *Language++; ++ Target[i++] = *Language++; ++ Target[i++] = *Language++; ++ Target[i++] = (pages[n].ttxtType << 3) + pages[n].ttxtMagazine; ++ Target[i++] = pages[n].ttxtPage; ++ j++; ++ } ++ if (j > 0) { ++ Target[l] = j * 5; // update length ++ IncEsInfoLength(i); ++ return i; ++ } ++ return 0; ++} ++ + int cPatPmtGenerator::MakeLanguageDescriptor(uchar *Target, const char *Language) + { + int i = 0; +@@ -472,6 +495,7 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) + if (Channel) { + int Vpid = Channel->Vpid(); + int Ppid = Channel->Ppid(); ++ int Tpid = Channel->Tpid(); + uchar *p = buf; + int i = 0; + p[i++] = 0x02; // table id +@@ -504,6 +528,10 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) + i += MakeStream(buf + i, 0x06, Channel->Spid(n)); + i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n), Channel->SubtitlingType(n), Channel->CompositionPageId(n), Channel->AncillaryPageId(n)); + } ++ if (Tpid) { ++ i += MakeStream(buf + i, 0x06, Tpid); ++ i += MakeTeletextDescriptor(buf + i, Channel->TeletextSubtitlePages(), Channel->TotalTeletextSubtitlePages()); ++ } + + int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC + buf[SectionLength] |= (sl >> 8) & 0x0F; +@@ -670,6 +698,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) + spids[0] = 0; + atypes[0] = 0; + dtypes[0] = 0; ++ totalTtxtSubtitlePages = 0; + SI::PMT::Stream stream; + for (SI::Loop::Iterator it; Pmt.streamLoop.getNext(stream, it); ) { + dbgpatpmt(" stream type = %02X, pid = %d", stream.getStreamType(), stream.getPid()); +diff --git a/remux.h b/remux.h +index 67eda4c..4cef4da 100644 +--- a/remux.h ++++ b/remux.h +@@ -294,6 +294,7 @@ protected: + int MakeStream(uchar *Target, uchar Type, int Pid); + int MakeAC3Descriptor(uchar *Target, uchar Type); + int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId); ++ int MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount); + int MakeLanguageDescriptor(uchar *Target, const char *Language); + int MakeCRC(uchar *Target, const uchar *Data, int Length); + void GeneratePmtPid(const cChannel *Channel); +@@ -353,6 +354,8 @@ private: + uint16_t compositionPageIds[MAXSPIDS]; + uint16_t ancillaryPageIds[MAXSPIDS]; + bool updatePrimaryDevice; ++ int totalTtxtSubtitlePages; ++ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; + protected: + int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; } + public: +-- +1.7.10.4 + diff --git a/patches/patch-set.1.7.40/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch b/patches/patch-set.1.7.40/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch new file mode 100644 index 0000000..28bcfca --- /dev/null +++ b/patches/patch-set.1.7.40/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch @@ -0,0 +1,470 @@ +From 49c6ee503914b199fe0eedbfc701d9c76cbee6ff Mon Sep 17 00:00:00 2001 +From: etobi +Date: Sat, 13 Feb 2010 14:42:30 +0100 +Subject: [PATCH 2/6] Added setup option to enable teletext subtitle recording + +--- + MANUAL | 3 +++ + config.c | 3 +++ + config.h | 1 + + menu.c | 1 + + po/ca_ES.po | 3 +++ + po/cs_CZ.po | 3 +++ + po/da_DK.po | 3 +++ + po/de_DE.po | 3 +++ + po/el_GR.po | 3 +++ + po/es_ES.po | 3 +++ + po/et_EE.po | 3 +++ + po/fi_FI.po | 3 +++ + po/fr_FR.po | 3 +++ + po/hr_HR.po | 3 +++ + po/hu_HU.po | 3 +++ + po/it_IT.po | 3 +++ + po/lt_LT.po | 3 +++ + po/nl_NL.po | 3 +++ + po/nn_NO.po | 3 +++ + po/pl_PL.po | 3 +++ + po/pt_PT.po | 3 +++ + po/ro_RO.po | 3 +++ + po/ru_RU.po | 3 +++ + po/sk_SK.po | 3 +++ + po/sl_SI.po | 3 +++ + po/sv_SE.po | 3 +++ + po/tr_TR.po | 3 +++ + po/uk_UA.po | 3 +++ + po/zh_CN.po | 3 +++ + receiver.c | 2 +- + 30 files changed, 84 insertions(+), 1 deletion(-) + +diff --git a/MANUAL b/MANUAL +index e1f79f8..716fd78 100644 +--- a/MANUAL ++++ b/MANUAL +@@ -761,6 +761,9 @@ Version 1.6 + background transparency. By default the values as broadcast + are used. + ++ Enable teletext support = yes ++ If set to 'yes', enables teletext subtitles. ++ + LNB: + + Use DiSEqC = no Generally turns DiSEqC support on or off. +diff --git a/config.c b/config.c +index 3dc9fe8..0c348de 100644 +--- a/config.c ++++ b/config.c +@@ -397,6 +397,7 @@ cSetup::cSetup(void) + MarginStop = 10; + AudioLanguages[0] = -1; + DisplaySubtitles = 0; ++ SupportTeletext = 1; + SubtitleLanguages[0] = -1; + SubtitleOffset = 0; + SubtitleFgTransparency = 0; +@@ -602,6 +603,7 @@ bool cSetup::Parse(const char *Name, const char *Value) + else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value); + else if (!strcasecmp(Name, "AudioLanguages")) return ParseLanguages(Value, AudioLanguages); + else if (!strcasecmp(Name, "DisplaySubtitles")) DisplaySubtitles = atoi(Value); ++ else if (!strcasecmp(Name, "SupportTeletext")) SupportTeletext = atoi(Value); + else if (!strcasecmp(Name, "SubtitleLanguages")) return ParseLanguages(Value, SubtitleLanguages); + else if (!strcasecmp(Name, "SubtitleOffset")) SubtitleOffset = atoi(Value); + else if (!strcasecmp(Name, "SubtitleFgTransparency")) SubtitleFgTransparency = atoi(Value); +@@ -711,6 +713,7 @@ bool cSetup::Save(void) + Store("MarginStop", MarginStop); + StoreLanguages("AudioLanguages", AudioLanguages); + Store("DisplaySubtitles", DisplaySubtitles); ++ Store("SupportTeletext", SupportTeletext); + StoreLanguages("SubtitleLanguages", SubtitleLanguages); + Store("SubtitleOffset", SubtitleOffset); + Store("SubtitleFgTransparency", SubtitleFgTransparency); +diff --git a/config.h b/config.h +index 9d88d6c..d6d94ff 100644 +--- a/config.h ++++ b/config.h +@@ -273,6 +273,7 @@ public: + int MarginStart, MarginStop; + int AudioLanguages[I18N_MAX_LANGUAGES + 1]; + int DisplaySubtitles; ++ int SupportTeletext; + int SubtitleLanguages[I18N_MAX_LANGUAGES + 1]; + int SubtitleOffset; + int SubtitleFgTransparency, SubtitleBgTransparency; +diff --git a/menu.c b/menu.c +index 7732697..376fe54 100644 +--- a/menu.c ++++ b/menu.c +@@ -2843,6 +2843,7 @@ void cMenuSetupDVB::Setup(void) + Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); + Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); + } ++ Add(new cMenuEditBoolItem(tr("Setup.DVB$Enable teletext support"), &data.SupportTeletext)); + + SetCurrent(Get(current)); + Display(); +diff --git a/po/ca_ES.po b/po/ca_ES.po +index 22aeb05..3c80544 100644 +--- a/po/ca_ES.po ++++ b/po/ca_ES.po +@@ -974,6 +974,9 @@ msgstr "Transpar + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparncia fons subttols" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "Configuraci de l'LNB" + +diff --git a/po/cs_CZ.po b/po/cs_CZ.po +index 818c9c1..1daf868 100644 +--- a/po/cs_CZ.po ++++ b/po/cs_CZ.po +@@ -974,6 +974,9 @@ msgstr "Průhlednost písma titulků" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Průhlednost pozadí titulků" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/da_DK.po b/po/da_DK.po +index 73a2122..da3870c 100644 +--- a/po/da_DK.po ++++ b/po/da_DK.po +@@ -971,6 +971,9 @@ msgstr "Undertekst forgrundsgennemsigtighed" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Undertekst baggrundsgennemsigtighed" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/de_DE.po b/po/de_DE.po +index 9e87977..1df2172 100644 +--- a/po/de_DE.po ++++ b/po/de_DE.po +@@ -971,6 +971,9 @@ msgstr "Untertitel-Transparenz Vordergrund" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Untertitel-Transparenz Hintergrund" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "Videotext-Untersttzung aktivieren" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/el_GR.po b/po/el_GR.po +index 50fe460..9582eda 100644 +--- a/po/el_GR.po ++++ b/po/el_GR.po +@@ -971,6 +971,9 @@ msgstr "" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/es_ES.po b/po/es_ES.po +index 2ef8807..dd3b0e4 100644 +--- a/po/es_ES.po ++++ b/po/es_ES.po +@@ -972,6 +972,9 @@ msgstr "Transparencia primer plano subt + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparencia fondo subttulos" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/et_EE.po b/po/et_EE.po +index e60cf5a..e962415 100644 +--- a/po/et_EE.po ++++ b/po/et_EE.po +@@ -971,6 +971,9 @@ msgstr "Subtiitri läbipaistvus" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Subtiitri tausta läbipaistvus" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "Teleteksti tugi" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/fi_FI.po b/po/fi_FI.po +index 7475eb7..a42f159 100644 +--- a/po/fi_FI.po ++++ b/po/fi_FI.po +@@ -975,6 +975,9 @@ msgstr "Tekstityksen läpinäkyvyys" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Tekstityksen taustan läpinäkyvyys" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "Salli teksti-TV-tuki" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/fr_FR.po b/po/fr_FR.po +index 57a6927..04e8f4c 100644 +--- a/po/fr_FR.po ++++ b/po/fr_FR.po +@@ -981,6 +981,9 @@ msgstr "Transparence de l'avant-plan des sous-titres" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparence du fond des sous-titres" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/hr_HR.po b/po/hr_HR.po +index 3a0f73a..d3ab985 100644 +--- a/po/hr_HR.po ++++ b/po/hr_HR.po +@@ -973,6 +973,9 @@ msgstr "Transparentnost titla" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparentnost pozadine titla" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/hu_HU.po b/po/hu_HU.po +index 26ed167..8bb405f 100644 +--- a/po/hu_HU.po ++++ b/po/hu_HU.po +@@ -975,6 +975,9 @@ msgstr "Felirat transzparenciája" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Felirat hátterének transzparenciája" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/it_IT.po b/po/it_IT.po +index ebd68f9..c174668 100644 +--- a/po/it_IT.po ++++ b/po/it_IT.po +@@ -978,6 +978,9 @@ msgstr "Trasparenza sottotitoli" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Trasparenza sfondo sottotitoli" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/lt_LT.po b/po/lt_LT.po +index 6337db4..33dcb42 100644 +--- a/po/lt_LT.po ++++ b/po/lt_LT.po +@@ -971,6 +971,9 @@ msgstr "Subtitrų fonto permatomumas" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Subtitrų fono permatomumas" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "Konverteris (LNB)" + +diff --git a/po/nl_NL.po b/po/nl_NL.po +index 1d1bb73..c7c97f9 100644 +--- a/po/nl_NL.po ++++ b/po/nl_NL.po +@@ -976,6 +976,9 @@ msgstr "Transparantie voorgrond ondertiteling" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparantie achtergrond ondertiteling" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/nn_NO.po b/po/nn_NO.po +index c8491e1..d73a9c1 100644 +--- a/po/nn_NO.po ++++ b/po/nn_NO.po +@@ -972,6 +972,9 @@ msgstr "" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/pl_PL.po b/po/pl_PL.po +index 35a39c4..3143d14 100644 +--- a/po/pl_PL.po ++++ b/po/pl_PL.po +@@ -973,6 +973,9 @@ msgstr "Prze + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Przerocze podtytuw: To" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/pt_PT.po b/po/pt_PT.po +index a485e2b..e3e151e 100644 +--- a/po/pt_PT.po ++++ b/po/pt_PT.po +@@ -972,6 +972,9 @@ msgstr "Transpar + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparncia de fundo das legendas" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/ro_RO.po b/po/ro_RO.po +index a7b6ce8..4a42b9f 100644 +--- a/po/ro_RO.po ++++ b/po/ro_RO.po +@@ -973,6 +973,9 @@ msgstr "Transparenţa prim-planului subtitrării" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparenţa fundalului subtitrării" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/ru_RU.po b/po/ru_RU.po +index ea09a3f..cacb789 100644 +--- a/po/ru_RU.po ++++ b/po/ru_RU.po +@@ -972,6 +972,9 @@ msgstr " + msgid "Setup.DVB$Subtitle background transparency" + msgstr " " + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "" + +diff --git a/po/sk_SK.po b/po/sk_SK.po +index 977d763..98ffd35 100644 +--- a/po/sk_SK.po ++++ b/po/sk_SK.po +@@ -971,6 +971,9 @@ msgstr "Prieh + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Priehadnos pozadia titulkov" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB (nzko umov jednotka)" + +diff --git a/po/sl_SI.po b/po/sl_SI.po +index 86fefbc..01f7b24 100644 +--- a/po/sl_SI.po ++++ b/po/sl_SI.po +@@ -972,6 +972,9 @@ msgstr "Transparentnost podnapisov" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparentnost ozadja podnapisov" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/sv_SE.po b/po/sv_SE.po +index 9b2ce7c..881fa4a 100644 +--- a/po/sv_SE.po ++++ b/po/sv_SE.po +@@ -975,6 +975,9 @@ msgstr "Transparent f + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparent bakgrund textremsa" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/tr_TR.po b/po/tr_TR.po +index b5f57b0..5751a46 100644 +--- a/po/tr_TR.po ++++ b/po/tr_TR.po +@@ -971,6 +971,9 @@ msgstr "Altyaz + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Altyaz arka effaflk" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/uk_UA.po b/po/uk_UA.po +index 4753432..62cc7bb 100644 +--- a/po/uk_UA.po ++++ b/po/uk_UA.po +@@ -972,6 +972,9 @@ msgstr "Прозорість переднього плану субтитрів" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Прозорість заднього плану субтитрів" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "Конвертер" + +diff --git a/po/zh_CN.po b/po/zh_CN.po +index efb0300..dcff6a0 100644 +--- a/po/zh_CN.po ++++ b/po/zh_CN.po +@@ -973,6 +973,9 @@ msgstr "字幕前景透明度" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "字幕背景透明度" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "切换器设置" + +diff --git a/receiver.c b/receiver.c +index 8a27b99..fa9c436 100644 +--- a/receiver.c ++++ b/receiver.c +@@ -68,7 +68,7 @@ bool cReceiver::SetPids(const cChannel *Channel) + AddPids(Channel->Apids()) && + AddPids(Channel->Dpids()) && + AddPids(Channel->Spids()) && +- AddPid(Channel->Tpid()); ++ (!Setup.SupportTeletext || AddPid(Channel->Tpid())); + } + return true; + } +-- +1.7.10.4 + diff --git a/patches/patch-set.1.7.40/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch b/patches/patch-set.1.7.40/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch new file mode 100644 index 0000000..760f74c --- /dev/null +++ b/patches/patch-set.1.7.40/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch @@ -0,0 +1,112 @@ +From 0351ee0c356deee5075ae4e730dbbaa53388ea3f Mon Sep 17 00:00:00 2001 +From: etobi +Date: Fri, 12 Feb 2010 21:56:41 +0100 +Subject: [PATCH 3/6] Allow manual configuration of teletetxt subtitle pages + in channels.conf + +--- + channels.c | 39 ++++++++++++++++++++++++++++++++++++--- + channels.h | 1 + + vdr.5 | 6 ++++++ + 3 files changed, 43 insertions(+), 3 deletions(-) + +diff --git a/channels.c b/channels.c +index 3eb31ce..a7f69a9 100644 +--- a/channels.c ++++ b/channels.c +@@ -411,9 +411,9 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos + void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages) + { + int mod = CHANNELMOD_NONE; +- if (totalTtxtSubtitlePages != numberOfPages) ++ if (totalTtxtSubtitlePages != (fixedTtxtSubtitlePages + numberOfPages)) + mod |= CHANNELMOD_PIDS; +- totalTtxtSubtitlePages = 0; ++ totalTtxtSubtitlePages = fixedTtxtSubtitlePages; + for (int i = 0; (i < numberOfPages) && (totalTtxtSubtitlePages < MAXTXTPAGES); i++) { + if (teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine != pages[i].ttxtMagazine || + teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage != pages[i].ttxtPage || +@@ -556,10 +556,17 @@ cString cChannel::ToText(const cChannel *Channel) + q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs, Channel->dtypes); + } + *q = 0; +- const int TBufferSize = MAXSPIDS * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid ++ const int TBufferSize = (MAXTXTPAGES * MAXSPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid + char tpidbuf[TBufferSize]; + q = tpidbuf; + q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid); ++ if (Channel->fixedTtxtSubtitlePages > 0) { ++ *q++ = '+'; ++ for (int i = 0; i < Channel->fixedTtxtSubtitlePages; ++i) { ++ tTeletextSubtitlePage page = Channel->teletextSubtitlePages[i]; ++ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), "%d=%s", page.PageNumber(), page.ttxtLanguage); ++ } ++ } + if (Channel->spids[0]) { + *q++ = ';'; + q += IntArrayToString(q, Channel->spids, 10, Channel->slangs); +@@ -730,6 +737,32 @@ bool cChannel::Parse(const char *s) + } + spids[NumSpids] = 0; + } ++ fixedTtxtSubtitlePages = 0; ++ if ((p = strchr(tpidbuf, '+')) != NULL) { ++ *p++ = 0; ++ char *q; ++ char *strtok_next; ++ while ((q = strtok_r(p, ",", &strtok_next)) != NULL) { ++ if (fixedTtxtSubtitlePages < MAXTXTPAGES) { ++ int page; ++ char *l = strchr(q, '='); ++ if (l) ++ *l++ = 0; ++ if (sscanf(q, "%d", &page) == 1) { ++ teletextSubtitlePages[fixedTtxtSubtitlePages] = tTeletextSubtitlePage(page); ++ if (l) ++ strn0cpy(teletextSubtitlePages[fixedTtxtSubtitlePages].ttxtLanguage, l, MAXLANGCODE2); ++ fixedTtxtSubtitlePages++; ++ } ++ else ++ esyslog("ERROR: invalid Teletext page!"); // no need to set ok to 'false' ++ } ++ else ++ esyslog("ERROR: too many Teletext pages!"); // no need to set ok to 'false' ++ p = NULL; ++ } ++ totalTtxtSubtitlePages = fixedTtxtSubtitlePages; ++ } + if (sscanf(tpidbuf, "%d", &tpid) != 1) + return false; + if (caidbuf) { +diff --git a/channels.h b/channels.h +index dbdcb17..b407672 100644 +--- a/channels.h ++++ b/channels.h +@@ -126,6 +126,7 @@ private: + uint16_t compositionPageIds[MAXSPIDS]; + uint16_t ancillaryPageIds[MAXSPIDS]; + int tpid; ++ int fixedTtxtSubtitlePages; + int totalTtxtSubtitlePages; + tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; + int caids[MAXCAIDS + 1]; // list is zero-terminated +diff --git a/vdr.5 b/vdr.5 +index ca705d4..dc5c339 100644 +--- a/vdr.5 ++++ b/vdr.5 +@@ -235,6 +235,12 @@ by an '=' sign, as in + + .B ...:201;2001=deu,2002=eng:... + ++Manual teletext subtitling pages can be defined separated by a '+' sign. ++The pages (separated by commas) can contain language codes, delimited by a '=' ++sign, as in ++ ++.B ...:201+150=deu,151=fin;2001,2002:... ++ + .TP + .B Conditional access + A hexadecimal integer defining how this channel can be accessed: +-- +1.7.10.4 + diff --git a/patches/patch-set.1.7.40/0004-Decrypt-teletext-stream.patch b/patches/patch-set.1.7.40/0004-Decrypt-teletext-stream.patch new file mode 100644 index 0000000..75d8fae --- /dev/null +++ b/patches/patch-set.1.7.40/0004-Decrypt-teletext-stream.patch @@ -0,0 +1,35 @@ +From f82d1c37c866904ef32975ddfd6bb297048f214f Mon Sep 17 00:00:00 2001 +From: etobi +Date: Sun, 14 Feb 2010 01:30:34 +0100 +Subject: [PATCH 4/6] Decrypt teletext stream + +--- + ci.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/ci.c b/ci.c +index 9a4a829..ec84027 100644 +--- a/ci.c ++++ b/ci.c +@@ -1914,6 +1914,8 @@ void cCamSlot::AddChannel(const cChannel *Channel) + AddPid(Channel->Sid(), *Dpid, STREAM_TYPE_PRIVATE); + for (const int *Spid = Channel->Spids(); *Spid; Spid++) + AddPid(Channel->Sid(), *Spid, STREAM_TYPE_PRIVATE); ++ if (Channel->Tpid() && Setup.SupportTeletext) ++ AddPid(Channel->Sid(), Channel->Tpid(), STREAM_TYPE_PRIVATE); + } + } + +@@ -1937,6 +1939,9 @@ bool cCamSlot::CanDecrypt(const cChannel *Channel) + CaPmt.AddPid(*Dpid, STREAM_TYPE_PRIVATE); + for (const int *Spid = Channel->Spids(); *Spid; Spid++) + CaPmt.AddPid(*Spid, STREAM_TYPE_PRIVATE); ++ if (Channel->Tpid() && Setup.SupportTeletext) { ++ CaPmt.AddPid(Channel->Tpid(), STREAM_TYPE_PRIVATE); ++ } + cas->SendPMT(&CaPmt); + cTimeMs Timeout(QUERY_REPLY_TIMEOUT); + do { +-- +1.7.10.4 + diff --git a/patches/patch-set.1.7.40/0005-Capture-teletext-subtitle-pages-from-PMT.patch b/patches/patch-set.1.7.40/0005-Capture-teletext-subtitle-pages-from-PMT.patch new file mode 100644 index 0000000..d4c0df7 --- /dev/null +++ b/patches/patch-set.1.7.40/0005-Capture-teletext-subtitle-pages-from-PMT.patch @@ -0,0 +1,92 @@ +From b5178c0a9c1eff2a1b90f891b19286524ad53b5d Mon Sep 17 00:00:00 2001 +From: etobi +Date: Fri, 12 Feb 2010 22:06:19 +0100 +Subject: [PATCH 5/6] Capture teletext subtitle pages from PMT + +--- + remux.c | 24 ++++++++++++++++++++++++ + remux.h | 5 +++++ + 2 files changed, 29 insertions(+) + +diff --git a/remux.c b/remux.c +index fa5a650..00dbf05 100644 +--- a/remux.c ++++ b/remux.c +@@ -605,6 +605,7 @@ void cPatPmtParser::Reset(void) + pmtPids[0] = 0; + vpid = vtype = 0; + ppid = 0; ++ tpid = 0; + } + + void cPatPmtParser::ParsePat(const uchar *Data, int Length) +@@ -693,6 +694,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) + int NumSpids = 0; + vpid = vtype = 0; + ppid = 0; ++ tpid = 0; + apids[0] = 0; + dpids[0] = 0; + spids[0] = 0; +@@ -797,6 +799,28 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) + spids[NumSpids] = 0; + } + break; ++ case SI::TeletextDescriptorTag: { ++ dbgpatpmt(" teletext"); ++ tpid = stream.getPid(); ++ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; ++ SI::TeletextDescriptor::Teletext ttxt; ++ if (totalTtxtSubtitlePages < MAXTXTPAGES) { ++ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { ++ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); ++ if (isSubtitlePage && ttxt.languageCode[0]) { ++ dbgpatpmt(" '%s:%x.%x'", ttxt.languageCode, ttxt.getTeletextMagazineNumber(), ttxt.getTeletextPageNumber()); ++ strn0cpy(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage = ttxt.getTeletextPageNumber(); ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType = ttxt.getTeletextType(); ++ totalTtxtSubtitlePages++; ++ if (totalTtxtSubtitlePages >= MAXTXTPAGES) ++ break; ++ } ++ } ++ } ++ } ++ break; + case SI::ISO639LanguageDescriptorTag: { + SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; + dbgpatpmt(" '%s'", ld->languageCode); +diff --git a/remux.h b/remux.h +index 4cef4da..203ed34 100644 +--- a/remux.h ++++ b/remux.h +@@ -342,6 +342,7 @@ private: + int vpid; + int ppid; + int vtype; ++ int tpid; + int apids[MAXAPIDS + 1]; // list is zero-terminated + int atypes[MAXAPIDS + 1]; // list is zero-terminated + char alangs[MAXAPIDS][MAXLANGCODE2]; +@@ -392,6 +393,9 @@ public: + int Vtype(void) const { return vtype; } + ///< Returns the video stream type as defined by the current PMT, or 0 if no video + ///< stream type has been detected, yet. ++ int Tpid(void) { return tpid; } ++ ///< Returns the teletext pid as defined by the current PMT, or 0 if no teletext ++ ///< pid has been detected, yet. + const int *Apids(void) const { return apids; } + const int *Dpids(void) const { return dpids; } + const int *Spids(void) const { return spids; } +@@ -406,6 +410,7 @@ public: + uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS) ? subtitlingTypes[i] : uchar(0); } + uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } + uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } ++ const tTeletextSubtitlePage* TeletextSubtitlePages() const { return teletextSubtitlePages; } + }; + + // TS to PES converter: +-- +1.7.10.4 + diff --git a/patches/patch-set.1.7.40/0006-Ttxtsubs-plugin-hook.patch b/patches/patch-set.1.7.40/0006-Ttxtsubs-plugin-hook.patch new file mode 100644 index 0000000..e5fc478 --- /dev/null +++ b/patches/patch-set.1.7.40/0006-Ttxtsubs-plugin-hook.patch @@ -0,0 +1,256 @@ +From dca35e2df3a731d4fe878e0d404bb607773fed2c Mon Sep 17 00:00:00 2001 +From: etobi +Date: Sat, 13 Feb 2010 00:28:21 +0100 +Subject: [PATCH 6/6] Ttxtsubs plugin hook + +--- + Makefile | 2 ++ + device.c | 20 +++++++++++++++++ + device.h | 1 + + pat.c | 6 +++++ + remux.h | 3 ++- + vdrttxtsubshooks.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + vdrttxtsubshooks.h | 46 ++++++++++++++++++++++++++++++++++++++ + 7 files changed, 140 insertions(+), 1 deletion(-) + create mode 100644 vdrttxtsubshooks.c + create mode 100644 vdrttxtsubshooks.h + +diff --git a/Makefile b/Makefile +index 913173b..990a47f 100644 +--- a/Makefile ++++ b/Makefile +@@ -73,6 +73,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d + skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\ + timers.o tools.o transfer.o vdr.o videodir.o + ++OBJS += vdrttxtsubshooks.o ++ + DEFINES += $(CDEFINES) + INCLUDES += $(CINCLUDES) + +diff --git a/device.c b/device.c +index ff51a11..bd720ba 100644 +--- a/device.c ++++ b/device.c +@@ -18,6 +18,7 @@ + #include "receiver.h" + #include "status.h" + #include "transfer.h" ++#include "vdrttxtsubshooks.h" + + // --- cLiveSubtitle --------------------------------------------------------- + +@@ -1312,6 +1313,13 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly) + } + break; + case 0xBD: { // private stream 1 ++ // EBU Teletext data, ETSI EN 300 472 ++ // if PES data header length = 24 and data_identifier = 0x10..0x1F (EBU Data) ++ if (Data[8] == 0x24 && Data[45] >= 0x10 && Data[45] < 0x20) { ++ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uint8_t*)Data, Length); ++ break; ++ } ++ + int PayloadOffset = Data[8] + 9; + + // Compatibility mode for old subtitles plugin: +@@ -1471,6 +1479,7 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) + tsToPesVideo.Reset(); + tsToPesAudio.Reset(); + tsToPesSubtitle.Reset(); ++ tsToPesTeletext.Reset(); + } + else if (Length < TS_SIZE) { + esyslog("ERROR: skipped %d bytes of TS fragment", Length); +@@ -1515,6 +1524,17 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) + if (!VideoOnly || HasIBPTrickSpeed()) + PlayTsSubtitle(Data, TS_SIZE); + } ++ else if (Pid == patPmtParser.Tpid()) { ++ if (!VideoOnly || HasIBPTrickSpeed()) { ++ int l; ++ tsToPesTeletext.PutTs(Data, Length); ++ if (const uchar *p = tsToPesTeletext.GetPes(l)) { ++ if ((l > 45) && (p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xbd) && (p[8] == 0x24) && (p[45] >= 0x10) && (p[45] < 0x20)) ++ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uchar *)p, l, false, patPmtParser.TeletextSubtitlePages(), patPmtParser.TotalTeletextSubtitlePages()); ++ tsToPesTeletext.Reset(); ++ } ++ } ++ } + } + } + else if (Pid == patPmtParser.Ppid()) { +diff --git a/device.h b/device.h +index fd010d4..41d410c 100644 +--- a/device.h ++++ b/device.h +@@ -584,6 +584,7 @@ private: + cTsToPes tsToPesVideo; + cTsToPes tsToPesAudio; + cTsToPes tsToPesSubtitle; ++ cTsToPes tsToPesTeletext; + bool isPlayingVideo; + protected: + const cPatPmtParser *PatPmtParser(void) const { return &patPmtParser; } +diff --git a/pat.c b/pat.c +index 3f89258..d9731f8 100644 +--- a/pat.c ++++ b/pat.c +@@ -13,6 +13,7 @@ + #include "libsi/section.h" + #include "libsi/descriptor.h" + #include "thread.h" ++#include "vdrttxtsubshooks.h" + + #define PMT_SCAN_TIMEOUT 10 // seconds + +@@ -562,6 +563,11 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length + } + if (Setup.UpdateChannels >= 2) { + Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid); ++ if (NumTPages < MAXTXTPAGES) { ++ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel); ++ if (manualPageNumber) ++ TeletextSubtitlePages[NumTPages++] = tTeletextSubtitlePage(manualPageNumber); ++ } + Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages); + Channel->SetCaIds(CaDescriptors->CaIds()); + Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); +diff --git a/remux.h b/remux.h +index 203ed34..396f41d 100644 +--- a/remux.h ++++ b/remux.h +@@ -410,7 +410,8 @@ public: + uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS) ? subtitlingTypes[i] : uchar(0); } + uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } + uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } +- const tTeletextSubtitlePage* TeletextSubtitlePages() const { return teletextSubtitlePages; } ++ const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } ++ int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } + }; + + // TS to PES converter: +diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c +new file mode 100644 +index 0000000..2471788 +--- /dev/null ++++ b/vdrttxtsubshooks.c +@@ -0,0 +1,63 @@ ++/* ++ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder ++ * Copyright (c) 2003 - 2008 Ragnar Sundblad ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include "vdrttxtsubshooks.h" ++ ++// XXX Really should be a list... ++static cVDRTtxtsubsHookListener *gListener; ++ ++// ------ class cVDRTtxtsubsHookProxy ------ ++ ++class cVDRTtxtsubsHookProxy : public cVDRTtxtsubsHookListener ++{ ++ public: ++ virtual void HideOSD(void) { if(gListener) gListener->HideOSD(); }; ++ virtual void ShowOSD(void) { if(gListener) gListener->ShowOSD(); }; ++ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) ++ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording, teletextSubtitlePages, pageCount); }; ++ virtual int ManualPageNumber(const cChannel *channel) ++ { if(gListener) return gListener->ManualPageNumber(channel); else return 0; }; ++}; ++ ++ ++// ------ class cVDRTtxtsubsHookListener ------ ++ ++cVDRTtxtsubsHookListener::~cVDRTtxtsubsHookListener() ++{ ++ gListener = 0; ++} ++ ++void cVDRTtxtsubsHookListener::HookAttach(void) ++{ ++ gListener = this; ++ //printf("cVDRTtxtsubsHookListener::HookAttach\n"); ++} ++ ++static cVDRTtxtsubsHookProxy gProxy; ++ ++cVDRTtxtsubsHookListener *cVDRTtxtsubsHookListener::Hook(void) ++{ ++ return &gProxy; ++} ++ +diff --git a/vdrttxtsubshooks.h b/vdrttxtsubshooks.h +new file mode 100644 +index 0000000..2f97969 +--- /dev/null ++++ b/vdrttxtsubshooks.h +@@ -0,0 +1,46 @@ ++/* ++ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder ++ * Copyright (c) 2003 - 2008 Ragnar Sundblad ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++#ifndef __VDRTTXTSUBSHOOKS_H ++#define __VDRTTXTSUBSHOOKS_H ++ ++#define TTXTSUBSVERSNUM 2 ++ ++class cDevice; ++class cChannel; ++struct tTeletextSubtitlePage; ++ ++class cVDRTtxtsubsHookListener { ++ public: ++ cVDRTtxtsubsHookListener(void) {}; ++ virtual ~cVDRTtxtsubsHookListener(); ++ ++ void HookAttach(void); ++ ++ virtual void HideOSD(void) {}; ++ virtual void ShowOSD(void) {}; ++ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording = true, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) {}; ++ virtual int ManualPageNumber(const cChannel *channel) { return 0; }; ++ ++ // used by VDR to call hook listeners ++ static cVDRTtxtsubsHookListener *Hook(void); ++}; ++ ++#endif +-- +1.7.10.4 + diff --git a/patches/vdr-1.7.38-ttxtsubs.patch b/patches/vdr-1.7.38-ttxtsubs.patch deleted file mode 100644 index d4eea3b..0000000 --- a/patches/vdr-1.7.38-ttxtsubs.patch +++ /dev/null @@ -1,1016 +0,0 @@ -diff --git a/MANUAL b/MANUAL -index e8321a4..f96b183 100644 ---- a/MANUAL -+++ b/MANUAL -@@ -756,6 +756,9 @@ Version 1.6 - background transparency. By default the values as broadcast - are used. - -+ Enable teletext support = yes -+ If set to 'yes', enables teletext subtitles. -+ - LNB: - - Use DiSEqC = no Generally turns DiSEqC support on or off. -diff --git a/Makefile b/Makefile -index db59754..d6afb7e 100644 ---- a/Makefile -+++ b/Makefile -@@ -73,6 +73,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d - skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\ - timers.o tools.o transfer.o vdr.o videodir.o - -+OBJS += vdrttxtsubshooks.o -+ - DEFINES += $(CDEFINES) - INCLUDES += $(CINCLUDES) - -diff --git a/channels.c b/channels.c -index 4c04608..a7f69a9 100644 ---- a/channels.c -+++ b/channels.c -@@ -408,6 +408,26 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos - } - } - -+void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages) -+{ -+ int mod = CHANNELMOD_NONE; -+ if (totalTtxtSubtitlePages != (fixedTtxtSubtitlePages + numberOfPages)) -+ mod |= CHANNELMOD_PIDS; -+ totalTtxtSubtitlePages = fixedTtxtSubtitlePages; -+ for (int i = 0; (i < numberOfPages) && (totalTtxtSubtitlePages < MAXTXTPAGES); i++) { -+ if (teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine != pages[i].ttxtMagazine || -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage != pages[i].ttxtPage || -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType != pages[i].ttxtType || -+ strcmp(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, pages[i].ttxtLanguage)) { -+ mod |= CHANNELMOD_PIDS; -+ teletextSubtitlePages[totalTtxtSubtitlePages] = pages[i]; -+ } -+ totalTtxtSubtitlePages++; -+ } -+ modification |= mod; -+ Channels.SetModified(); -+} -+ - void cChannel::SetCaIds(const int *CaIds) - { - if (caids[0] && caids[0] <= CA_USER_MAX) -@@ -536,10 +556,17 @@ cString cChannel::ToText(const cChannel *Channel) - q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs, Channel->dtypes); - } - *q = 0; -- const int TBufferSize = MAXSPIDS * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid -+ const int TBufferSize = (MAXTXTPAGES * MAXSPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid - char tpidbuf[TBufferSize]; - q = tpidbuf; - q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid); -+ if (Channel->fixedTtxtSubtitlePages > 0) { -+ *q++ = '+'; -+ for (int i = 0; i < Channel->fixedTtxtSubtitlePages; ++i) { -+ tTeletextSubtitlePage page = Channel->teletextSubtitlePages[i]; -+ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), "%d=%s", page.PageNumber(), page.ttxtLanguage); -+ } -+ } - if (Channel->spids[0]) { - *q++ = ';'; - q += IntArrayToString(q, Channel->spids, 10, Channel->slangs); -@@ -710,6 +737,32 @@ bool cChannel::Parse(const char *s) - } - spids[NumSpids] = 0; - } -+ fixedTtxtSubtitlePages = 0; -+ if ((p = strchr(tpidbuf, '+')) != NULL) { -+ *p++ = 0; -+ char *q; -+ char *strtok_next; -+ while ((q = strtok_r(p, ",", &strtok_next)) != NULL) { -+ if (fixedTtxtSubtitlePages < MAXTXTPAGES) { -+ int page; -+ char *l = strchr(q, '='); -+ if (l) -+ *l++ = 0; -+ if (sscanf(q, "%d", &page) == 1) { -+ teletextSubtitlePages[fixedTtxtSubtitlePages] = tTeletextSubtitlePage(page); -+ if (l) -+ strn0cpy(teletextSubtitlePages[fixedTtxtSubtitlePages].ttxtLanguage, l, MAXLANGCODE2); -+ fixedTtxtSubtitlePages++; -+ } -+ else -+ esyslog("ERROR: invalid Teletext page!"); // no need to set ok to 'false' -+ } -+ else -+ esyslog("ERROR: too many Teletext pages!"); // no need to set ok to 'false' -+ p = NULL; -+ } -+ totalTtxtSubtitlePages = fixedTtxtSubtitlePages; -+ } - if (sscanf(tpidbuf, "%d", &tpid) != 1) - return false; - if (caidbuf) { -diff --git a/channels.h b/channels.h -index 815cb47..b407672 100644 ---- a/channels.h -+++ b/channels.h -@@ -35,6 +35,7 @@ - #define MAXDPIDS 16 // dolby (AC3 + DTS) - #define MAXSPIDS 32 // subtitles - #define MAXCAIDS 12 // conditional access -+#define MAXTXTPAGES 8 // teletext pages - - #define MAXLANGCODE1 4 // a 3 letter language code, zero terminated - #define MAXLANGCODE2 8 // up to two 3 letter language codes, separated by '+' and zero terminated -@@ -71,6 +72,16 @@ public: - static const tChannelID InvalidID; - }; - -+struct tTeletextSubtitlePage { -+ tTeletextSubtitlePage(void) { ttxtPage = ttxtMagazine = 0; ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } -+ tTeletextSubtitlePage(int page) { ttxtMagazine = (page / 100) & 0x7; ttxtPage = (((page % 100) / 10) << 4) + (page % 10); ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } -+ char ttxtLanguage[MAXLANGCODE1]; -+ uchar ttxtPage; -+ uchar ttxtMagazine; -+ uchar ttxtType; -+ int PageNumber(void) const { return BCDCHARTOINT(ttxtMagazine) * 100 + BCDCHARTOINT(ttxtPage); } -+ }; -+ - class cChannel; - - class cLinkChannel : public cListObject { -@@ -115,6 +126,9 @@ private: - uint16_t compositionPageIds[MAXSPIDS]; - uint16_t ancillaryPageIds[MAXSPIDS]; - int tpid; -+ int fixedTtxtSubtitlePages; -+ int totalTtxtSubtitlePages; -+ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; - int caids[MAXCAIDS + 1]; // list is zero-terminated - int nid; - int tid; -@@ -166,6 +180,8 @@ public: - uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } - uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } - int Tpid(void) const { return tpid; } -+ const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } -+ int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } - const int *Caids(void) const { return caids; } - int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } - int Nid(void) const { return nid; } -@@ -192,6 +208,7 @@ public: - void SetName(const char *Name, const char *ShortName, const char *Provider); - void SetPortalName(const char *PortalName); - void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); -+ void SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages); - void SetCaIds(const int *CaIds); // list must be zero-terminated - void SetCaDescriptors(int Level); - void SetLinkChannels(cLinkChannels *LinkChannels); -diff --git a/ci.c b/ci.c -index 9a4a829..ec84027 100644 ---- a/ci.c -+++ b/ci.c -@@ -1914,6 +1914,8 @@ void cCamSlot::AddChannel(const cChannel *Channel) - AddPid(Channel->Sid(), *Dpid, STREAM_TYPE_PRIVATE); - for (const int *Spid = Channel->Spids(); *Spid; Spid++) - AddPid(Channel->Sid(), *Spid, STREAM_TYPE_PRIVATE); -+ if (Channel->Tpid() && Setup.SupportTeletext) -+ AddPid(Channel->Sid(), Channel->Tpid(), STREAM_TYPE_PRIVATE); - } - } - -@@ -1937,6 +1939,9 @@ bool cCamSlot::CanDecrypt(const cChannel *Channel) - CaPmt.AddPid(*Dpid, STREAM_TYPE_PRIVATE); - for (const int *Spid = Channel->Spids(); *Spid; Spid++) - CaPmt.AddPid(*Spid, STREAM_TYPE_PRIVATE); -+ if (Channel->Tpid() && Setup.SupportTeletext) { -+ CaPmt.AddPid(Channel->Tpid(), STREAM_TYPE_PRIVATE); -+ } - cas->SendPMT(&CaPmt); - cTimeMs Timeout(QUERY_REPLY_TIMEOUT); - do { -diff --git a/config.c b/config.c -index 2c87985..9ed5435 100644 ---- a/config.c -+++ b/config.c -@@ -397,6 +397,7 @@ cSetup::cSetup(void) - MarginStop = 10; - AudioLanguages[0] = -1; - DisplaySubtitles = 0; -+ SupportTeletext = 1; - SubtitleLanguages[0] = -1; - SubtitleOffset = 0; - SubtitleFgTransparency = 0; -@@ -601,6 +602,7 @@ bool cSetup::Parse(const char *Name, const char *Value) - else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value); - else if (!strcasecmp(Name, "AudioLanguages")) return ParseLanguages(Value, AudioLanguages); - else if (!strcasecmp(Name, "DisplaySubtitles")) DisplaySubtitles = atoi(Value); -+ else if (!strcasecmp(Name, "SupportTeletext")) SupportTeletext = atoi(Value); - else if (!strcasecmp(Name, "SubtitleLanguages")) return ParseLanguages(Value, SubtitleLanguages); - else if (!strcasecmp(Name, "SubtitleOffset")) SubtitleOffset = atoi(Value); - else if (!strcasecmp(Name, "SubtitleFgTransparency")) SubtitleFgTransparency = atoi(Value); -@@ -709,6 +711,7 @@ bool cSetup::Save(void) - Store("MarginStop", MarginStop); - StoreLanguages("AudioLanguages", AudioLanguages); - Store("DisplaySubtitles", DisplaySubtitles); -+ Store("SupportTeletext", SupportTeletext); - StoreLanguages("SubtitleLanguages", SubtitleLanguages); - Store("SubtitleOffset", SubtitleOffset); - Store("SubtitleFgTransparency", SubtitleFgTransparency); -diff --git a/config.h b/config.h -index 693e927..b5ca1a5 100644 ---- a/config.h -+++ b/config.h -@@ -273,6 +273,7 @@ public: - int MarginStart, MarginStop; - int AudioLanguages[I18N_MAX_LANGUAGES + 1]; - int DisplaySubtitles; -+ int SupportTeletext; - int SubtitleLanguages[I18N_MAX_LANGUAGES + 1]; - int SubtitleOffset; - int SubtitleFgTransparency, SubtitleBgTransparency; -diff --git a/device.c b/device.c -index ca897b0..f22c6eb 100644 ---- a/device.c -+++ b/device.c -@@ -18,6 +18,7 @@ - #include "receiver.h" - #include "status.h" - #include "transfer.h" -+#include "vdrttxtsubshooks.h" - - // --- cLiveSubtitle --------------------------------------------------------- - -@@ -1313,6 +1314,13 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly) - } - break; - case 0xBD: { // private stream 1 -+ // EBU Teletext data, ETSI EN 300 472 -+ // if PES data header length = 24 and data_identifier = 0x10..0x1F (EBU Data) -+ if (Data[8] == 0x24 && Data[45] >= 0x10 && Data[45] < 0x20) { -+ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uint8_t*)Data, Length); -+ break; -+ } -+ - int PayloadOffset = Data[8] + 9; - - // Compatibility mode for old subtitles plugin: -@@ -1472,6 +1480,7 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) - tsToPesVideo.Reset(); - tsToPesAudio.Reset(); - tsToPesSubtitle.Reset(); -+ tsToPesTeletext.Reset(); - } - else if (Length < TS_SIZE) { - esyslog("ERROR: skipped %d bytes of TS fragment", Length); -@@ -1517,6 +1526,17 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) - if (!VideoOnly || HasIBPTrickSpeed()) - PlayTsSubtitle(Data, TS_SIZE); - } -+ else if (Pid == patPmtParser.Tpid()) { -+ if (!VideoOnly || HasIBPTrickSpeed()) { -+ int l; -+ tsToPesTeletext.PutTs(Data, Length); -+ if (const uchar *p = tsToPesTeletext.GetPes(l)) { -+ if ((l > 45) && (p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xbd) && (p[8] == 0x24) && (p[45] >= 0x10) && (p[45] < 0x20)) -+ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uchar *)p, l, false, patPmtParser.TeletextSubtitlePages(), patPmtParser.TotalTeletextSubtitlePages()); -+ tsToPesTeletext.Reset(); -+ } -+ } -+ } - } - } - else if (Pid == patPmtParser.Ppid()) { -diff --git a/device.h b/device.h -index fd010d4..41d410c 100644 ---- a/device.h -+++ b/device.h -@@ -584,6 +584,7 @@ private: - cTsToPes tsToPesVideo; - cTsToPes tsToPesAudio; - cTsToPes tsToPesSubtitle; -+ cTsToPes tsToPesTeletext; - bool isPlayingVideo; - protected: - const cPatPmtParser *PatPmtParser(void) const { return &patPmtParser; } -diff --git a/menu.c b/menu.c -index 69fe6d5..5df7fbb 100644 ---- a/menu.c -+++ b/menu.c -@@ -2840,6 +2840,7 @@ void cMenuSetupDVB::Setup(void) - Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); - Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); - } -+ Add(new cMenuEditBoolItem(tr("Setup.DVB$Enable teletext support"), &data.SupportTeletext)); - - SetCurrent(Get(current)); - Display(); -diff --git a/pat.c b/pat.c -index a7791e2..d9731f8 100644 ---- a/pat.c -+++ b/pat.c -@@ -13,6 +13,7 @@ - #include "libsi/section.h" - #include "libsi/descriptor.h" - #include "thread.h" -+#include "vdrttxtsubshooks.h" - - #define PMT_SCAN_TIMEOUT 10 // seconds - -@@ -343,6 +344,8 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length - char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" }; - char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" }; - int Tpid = 0; -+ tTeletextSubtitlePage TeletextSubtitlePages[MAXTXTPAGES]; -+ int NumTPages = 0; - int NumApids = 0; - int NumDpids = 0; - int NumSpids = 0; -@@ -434,8 +437,21 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length - NumSpids++; - } - break; -- case SI::TeletextDescriptorTag: -+ case SI::TeletextDescriptorTag: { - Tpid = esPid; -+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; -+ SI::TeletextDescriptor::Teletext ttxt; -+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { -+ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); -+ if ((NumTPages < MAXTXTPAGES) && ttxt.languageCode[0] && isSubtitlePage) { -+ strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); -+ TeletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber(); -+ TeletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); -+ TeletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType(); -+ NumTPages++; -+ } -+ } -+ } - break; - case SI::ISO639LanguageDescriptorTag: { - SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; -@@ -547,6 +563,12 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length - } - if (Setup.UpdateChannels >= 2) { - Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid); -+ if (NumTPages < MAXTXTPAGES) { -+ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel); -+ if (manualPageNumber) -+ TeletextSubtitlePages[NumTPages++] = tTeletextSubtitlePage(manualPageNumber); -+ } -+ Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages); - Channel->SetCaIds(CaDescriptors->CaIds()); - Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); - } -diff --git a/po/ca_ES.po b/po/ca_ES.po -index f1a24fc..c2e0379 100644 ---- a/po/ca_ES.po -+++ b/po/ca_ES.po -@@ -971,6 +971,9 @@ msgstr "Transpar - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparncia fons subttols" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "Configuraci de l'LNB" - -diff --git a/po/cs_CZ.po b/po/cs_CZ.po -index a4f2515..02360b3 100644 ---- a/po/cs_CZ.po -+++ b/po/cs_CZ.po -@@ -970,6 +970,9 @@ msgstr "Průhlednost písma titulků" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Průhlednost pozadí titulků" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/da_DK.po b/po/da_DK.po -index 511e03f..4b6b9bb 100644 ---- a/po/da_DK.po -+++ b/po/da_DK.po -@@ -968,6 +968,9 @@ msgstr "Undertekst forgrundsgennemsigtighed" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Undertekst baggrundsgennemsigtighed" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/de_DE.po b/po/de_DE.po -index 77af04a..a8c28c5 100644 ---- a/po/de_DE.po -+++ b/po/de_DE.po -@@ -968,6 +968,9 @@ msgstr "Untertitel-Transparenz Vordergrund" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Untertitel-Transparenz Hintergrund" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "Videotext-Untersttzung aktivieren" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/el_GR.po b/po/el_GR.po -index d0c1c7d..7d32ec6 100644 ---- a/po/el_GR.po -+++ b/po/el_GR.po -@@ -968,6 +968,9 @@ msgstr "" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/es_ES.po b/po/es_ES.po -index 9e120e7..7e03fdf 100644 ---- a/po/es_ES.po -+++ b/po/es_ES.po -@@ -969,6 +969,9 @@ msgstr "Transparencia primer plano subt - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparencia fondo subttulos" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/et_EE.po b/po/et_EE.po -index ffb3c91..397d0d5 100644 ---- a/po/et_EE.po -+++ b/po/et_EE.po -@@ -968,6 +968,9 @@ msgstr "Subtiitri läbipaistvus" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Subtiitri tausta läbipaistvus" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "Teleteksti tugi" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/fi_FI.po b/po/fi_FI.po -index 164a376..db4b455 100644 ---- a/po/fi_FI.po -+++ b/po/fi_FI.po -@@ -971,6 +971,9 @@ msgstr "Tekstityksen läpinäkyvyys" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Tekstityksen taustan läpinäkyvyys" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "Salli teksti-TV-tuki" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/fr_FR.po b/po/fr_FR.po -index eaf31b1..a6a2433 100644 ---- a/po/fr_FR.po -+++ b/po/fr_FR.po -@@ -978,6 +978,9 @@ msgstr "Transparence de l'avant-plan des sous-titres" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparence du fond des sous-titres" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/hr_HR.po b/po/hr_HR.po -index af63cc1..65a644a 100644 ---- a/po/hr_HR.po -+++ b/po/hr_HR.po -@@ -970,6 +970,9 @@ msgstr "Transparentnost titla" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparentnost pozadine titla" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/hu_HU.po b/po/hu_HU.po -index a2cc9d0..00637e7 100644 ---- a/po/hu_HU.po -+++ b/po/hu_HU.po -@@ -971,6 +971,9 @@ msgstr "Felirat transzparenci - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Felirat htternek transzparencija" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/it_IT.po b/po/it_IT.po -index e6c848b..dd92b7c 100644 ---- a/po/it_IT.po -+++ b/po/it_IT.po -@@ -975,6 +975,9 @@ msgstr "Trasparenza sottotitoli" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Trasparenza sfondo sottotitoli" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/lt_LT.po b/po/lt_LT.po -index e9f24ca..2e881ad 100644 ---- a/po/lt_LT.po -+++ b/po/lt_LT.po -@@ -968,6 +968,9 @@ msgstr "Subtitrų fonto permatomumas" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Subtitrų fono permatomumas" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "Konverteris (LNB)" - -diff --git a/po/nl_NL.po b/po/nl_NL.po -index ab16a2a..ce4938d 100644 ---- a/po/nl_NL.po -+++ b/po/nl_NL.po -@@ -972,6 +972,9 @@ msgstr "Transparantie voorgrond ondertiteling" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparantie achtergrond ondertiteling" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/nn_NO.po b/po/nn_NO.po -index 664018b..2a8df35 100644 ---- a/po/nn_NO.po -+++ b/po/nn_NO.po -@@ -969,6 +969,9 @@ msgstr "" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/pl_PL.po b/po/pl_PL.po -index 1580b0b..b0ecc72 100644 ---- a/po/pl_PL.po -+++ b/po/pl_PL.po -@@ -969,6 +969,9 @@ msgstr "Prze - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Przerocze podtytuw: To" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/pt_PT.po b/po/pt_PT.po -index 9dec287..4947fb0 100644 ---- a/po/pt_PT.po -+++ b/po/pt_PT.po -@@ -969,6 +969,9 @@ msgstr "Transpar - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparncia de fundo das legendas" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/ro_RO.po b/po/ro_RO.po -index 4c257ad..77e47f8 100644 ---- a/po/ro_RO.po -+++ b/po/ro_RO.po -@@ -970,6 +970,9 @@ msgstr "Transparenţa prim-planului subtitrării" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparenţa fundalului subtitrării" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/ru_RU.po b/po/ru_RU.po -index 9bcf571..194c232 100644 ---- a/po/ru_RU.po -+++ b/po/ru_RU.po -@@ -969,6 +969,9 @@ msgstr " - msgid "Setup.DVB$Subtitle background transparency" - msgstr " " - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "" - -diff --git a/po/sk_SK.po b/po/sk_SK.po -index 6aea45c..26fbe99 100644 ---- a/po/sk_SK.po -+++ b/po/sk_SK.po -@@ -968,6 +968,9 @@ msgstr "Prieh - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Priehadnos pozadia titulkov" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/sl_SI.po b/po/sl_SI.po -index 6c6abb5..248894d 100644 ---- a/po/sl_SI.po -+++ b/po/sl_SI.po -@@ -969,6 +969,9 @@ msgstr "Transparentnost podnapisov" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparentnost ozadja podnapisov" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/sv_SE.po b/po/sv_SE.po -index b5df87d..b7cbf83 100644 ---- a/po/sv_SE.po -+++ b/po/sv_SE.po -@@ -971,6 +971,9 @@ msgstr "Transparent f - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Transparent bakgrund textremsa" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/tr_TR.po b/po/tr_TR.po -index 30e3fbd..45c79a5 100644 ---- a/po/tr_TR.po -+++ b/po/tr_TR.po -@@ -968,6 +968,9 @@ msgstr "Altyaz - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Altyaz arka effaflk" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "LNB" - -diff --git a/po/uk_UA.po b/po/uk_UA.po -index 82b8d2a..5484634 100644 ---- a/po/uk_UA.po -+++ b/po/uk_UA.po -@@ -969,6 +969,9 @@ msgstr "Прозорість переднього плану субтитрів" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "Прозорість заднього плану субтитрів" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "Конвертер" - -diff --git a/po/zh_CN.po b/po/zh_CN.po -index 3f4a6c6..6724c9c 100644 ---- a/po/zh_CN.po -+++ b/po/zh_CN.po -@@ -971,6 +971,9 @@ msgstr "字幕前景透明度" - msgid "Setup.DVB$Subtitle background transparency" - msgstr "字幕背景透明度" - -+msgid "Setup.DVB$Enable teletext support" -+msgstr "" -+ - msgid "LNB" - msgstr "切换器设置" - -diff --git a/receiver.c b/receiver.c -index bde60e4..fa9c436 100644 ---- a/receiver.c -+++ b/receiver.c -@@ -67,7 +67,8 @@ bool cReceiver::SetPids(const cChannel *Channel) - (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) && - AddPids(Channel->Apids()) && - AddPids(Channel->Dpids()) && -- AddPids(Channel->Spids()); -+ AddPids(Channel->Spids()) && -+ (!Setup.SupportTeletext || AddPid(Channel->Tpid())); - } - return true; - } -diff --git a/remux.c b/remux.c -index 9be3078..3c7a156 100644 ---- a/remux.c -+++ b/remux.c -@@ -385,6 +385,29 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua - return i; - } - -+int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount) -+{ -+ int i = 0, j = 0; -+ Target[i++] = SI::TeletextDescriptorTag; -+ int l = i; -+ Target[i++] = 0x00; // length -+ for (int n = 0; n < pageCount; n++) { -+ const char* Language = pages[n].ttxtLanguage; -+ Target[i++] = *Language++; -+ Target[i++] = *Language++; -+ Target[i++] = *Language++; -+ Target[i++] = (pages[n].ttxtType << 3) + pages[n].ttxtMagazine; -+ Target[i++] = pages[n].ttxtPage; -+ j++; -+ } -+ if (j > 0) { -+ Target[l] = j * 5; // update length -+ IncEsInfoLength(i); -+ return i; -+ } -+ return 0; -+} -+ - int cPatPmtGenerator::MakeLanguageDescriptor(uchar *Target, const char *Language) - { - int i = 0; -@@ -472,6 +495,7 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) - if (Channel) { - int Vpid = Channel->Vpid(); - int Ppid = Channel->Ppid(); -+ int Tpid = Channel->Tpid(); - uchar *p = buf; - int i = 0; - p[i++] = 0x02; // table id -@@ -504,6 +528,10 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) - i += MakeStream(buf + i, 0x06, Channel->Spid(n)); - i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n), Channel->SubtitlingType(n), Channel->CompositionPageId(n), Channel->AncillaryPageId(n)); - } -+ if (Tpid) { -+ i += MakeStream(buf + i, 0x06, Tpid); -+ i += MakeTeletextDescriptor(buf + i, Channel->TeletextSubtitlePages(), Channel->TotalTeletextSubtitlePages()); -+ } - - int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC - buf[SectionLength] |= (sl >> 8) & 0x0F; -@@ -577,6 +605,7 @@ void cPatPmtParser::Reset(void) - pmtPids[0] = 0; - vpid = vtype = 0; - ppid = 0; -+ tpid = 0; - } - - void cPatPmtParser::ParsePat(const uchar *Data, int Length) -@@ -665,11 +694,13 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) - int NumSpids = 0; - vpid = vtype = 0; - ppid = 0; -+ tpid = 0; - apids[0] = 0; - dpids[0] = 0; - spids[0] = 0; - atypes[0] = 0; - dtypes[0] = 0; -+ totalTtxtSubtitlePages = 0; - SI::PMT::Stream stream; - for (SI::Loop::Iterator it; Pmt.streamLoop.getNext(stream, it); ) { - dbgpatpmt(" stream type = %02X, pid = %d", stream.getStreamType(), stream.getPid()); -@@ -768,6 +799,28 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) - spids[NumSpids]= 0; - } - break; -+ case SI::TeletextDescriptorTag: { -+ dbgpatpmt(" teletext"); -+ tpid = stream.getPid(); -+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; -+ SI::TeletextDescriptor::Teletext ttxt; -+ if (totalTtxtSubtitlePages < MAXTXTPAGES) { -+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { -+ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); -+ if (isSubtitlePage && ttxt.languageCode[0]) { -+ dbgpatpmt(" '%s:%x.%x'", ttxt.languageCode, ttxt.getTeletextMagazineNumber(), ttxt.getTeletextPageNumber()); -+ strn0cpy(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage = ttxt.getTeletextPageNumber(); -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); -+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType = ttxt.getTeletextType(); -+ totalTtxtSubtitlePages++; -+ if (totalTtxtSubtitlePages >= MAXTXTPAGES) -+ break; -+ } -+ } -+ } -+ } -+ break; - case SI::ISO639LanguageDescriptorTag: { - SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; - dbgpatpmt(" '%s'", ld->languageCode); -diff --git a/remux.h b/remux.h -index 67eda4c..396f41d 100644 ---- a/remux.h -+++ b/remux.h -@@ -294,6 +294,7 @@ protected: - int MakeStream(uchar *Target, uchar Type, int Pid); - int MakeAC3Descriptor(uchar *Target, uchar Type); - int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId); -+ int MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount); - int MakeLanguageDescriptor(uchar *Target, const char *Language); - int MakeCRC(uchar *Target, const uchar *Data, int Length); - void GeneratePmtPid(const cChannel *Channel); -@@ -341,6 +342,7 @@ private: - int vpid; - int ppid; - int vtype; -+ int tpid; - int apids[MAXAPIDS + 1]; // list is zero-terminated - int atypes[MAXAPIDS + 1]; // list is zero-terminated - char alangs[MAXAPIDS][MAXLANGCODE2]; -@@ -353,6 +355,8 @@ private: - uint16_t compositionPageIds[MAXSPIDS]; - uint16_t ancillaryPageIds[MAXSPIDS]; - bool updatePrimaryDevice; -+ int totalTtxtSubtitlePages; -+ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; - protected: - int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; } - public: -@@ -389,6 +393,9 @@ public: - int Vtype(void) const { return vtype; } - ///< Returns the video stream type as defined by the current PMT, or 0 if no video - ///< stream type has been detected, yet. -+ int Tpid(void) { return tpid; } -+ ///< Returns the teletext pid as defined by the current PMT, or 0 if no teletext -+ ///< pid has been detected, yet. - const int *Apids(void) const { return apids; } - const int *Dpids(void) const { return dpids; } - const int *Spids(void) const { return spids; } -@@ -403,6 +410,8 @@ public: - uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS) ? subtitlingTypes[i] : uchar(0); } - uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } - uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } -+ const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } -+ int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } - }; - - // TS to PES converter: -diff --git a/vdr.5 b/vdr.5 -index 4003a5e..cb1552d 100644 ---- a/vdr.5 -+++ b/vdr.5 -@@ -233,6 +233,12 @@ by an '=' sign, as in - - .B ...:201;2001=deu,2002=eng:... - -+Manual teletext subtitling pages can be defined separated by a '+' sign. -+The pages (separated by commas) can contain language codes, delimited by a '=' -+sign, as in -+ -+.B ...:201+150=deu,151=fin;2001,2002:... -+ - .TP - .B Conditional access - A hexadecimal integer defining how this channel can be accessed: -diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c -new file mode 100644 -index 0000000..2471788 ---- /dev/null -+++ b/vdrttxtsubshooks.c -@@ -0,0 +1,63 @@ -+/* -+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2003 - 2008 Ragnar Sundblad -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include "vdrttxtsubshooks.h" -+ -+// XXX Really should be a list... -+static cVDRTtxtsubsHookListener *gListener; -+ -+// ------ class cVDRTtxtsubsHookProxy ------ -+ -+class cVDRTtxtsubsHookProxy : public cVDRTtxtsubsHookListener -+{ -+ public: -+ virtual void HideOSD(void) { if(gListener) gListener->HideOSD(); }; -+ virtual void ShowOSD(void) { if(gListener) gListener->ShowOSD(); }; -+ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) -+ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording, teletextSubtitlePages, pageCount); }; -+ virtual int ManualPageNumber(const cChannel *channel) -+ { if(gListener) return gListener->ManualPageNumber(channel); else return 0; }; -+}; -+ -+ -+// ------ class cVDRTtxtsubsHookListener ------ -+ -+cVDRTtxtsubsHookListener::~cVDRTtxtsubsHookListener() -+{ -+ gListener = 0; -+} -+ -+void cVDRTtxtsubsHookListener::HookAttach(void) -+{ -+ gListener = this; -+ //printf("cVDRTtxtsubsHookListener::HookAttach\n"); -+} -+ -+static cVDRTtxtsubsHookProxy gProxy; -+ -+cVDRTtxtsubsHookListener *cVDRTtxtsubsHookListener::Hook(void) -+{ -+ return &gProxy; -+} -+ -diff --git a/vdrttxtsubshooks.h b/vdrttxtsubshooks.h -new file mode 100644 -index 0000000..2f97969 ---- /dev/null -+++ b/vdrttxtsubshooks.h -@@ -0,0 +1,46 @@ -+/* -+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder -+ * Copyright (c) 2003 - 2008 Ragnar Sundblad -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -+ * details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -+ * -+ */ -+ -+#ifndef __VDRTTXTSUBSHOOKS_H -+#define __VDRTTXTSUBSHOOKS_H -+ -+#define TTXTSUBSVERSNUM 2 -+ -+class cDevice; -+class cChannel; -+struct tTeletextSubtitlePage; -+ -+class cVDRTtxtsubsHookListener { -+ public: -+ cVDRTtxtsubsHookListener(void) {}; -+ virtual ~cVDRTtxtsubsHookListener(); -+ -+ void HookAttach(void); -+ -+ virtual void HideOSD(void) {}; -+ virtual void ShowOSD(void) {}; -+ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording = true, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) {}; -+ virtual int ManualPageNumber(const cChannel *channel) { return 0; }; -+ -+ // used by VDR to call hook listeners -+ static cVDRTtxtsubsHookListener *Hook(void); -+}; -+ -+#endif diff --git a/patches/vdr-1.7.40-ttxtsubs.patch b/patches/vdr-1.7.40-ttxtsubs.patch new file mode 100644 index 0000000..73aa458 --- /dev/null +++ b/patches/vdr-1.7.40-ttxtsubs.patch @@ -0,0 +1,1016 @@ +diff --git a/MANUAL b/MANUAL +index e1f79f8..716fd78 100644 +--- a/MANUAL ++++ b/MANUAL +@@ -761,6 +761,9 @@ Version 1.6 + background transparency. By default the values as broadcast + are used. + ++ Enable teletext support = yes ++ If set to 'yes', enables teletext subtitles. ++ + LNB: + + Use DiSEqC = no Generally turns DiSEqC support on or off. +diff --git a/Makefile b/Makefile +index 913173b..990a47f 100644 +--- a/Makefile ++++ b/Makefile +@@ -73,6 +73,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d + skinclassic.o skinlcars.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\ + timers.o tools.o transfer.o vdr.o videodir.o + ++OBJS += vdrttxtsubshooks.o ++ + DEFINES += $(CDEFINES) + INCLUDES += $(CINCLUDES) + +diff --git a/channels.c b/channels.c +index 4c04608..a7f69a9 100644 +--- a/channels.c ++++ b/channels.c +@@ -408,6 +408,26 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos + } + } + ++void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages) ++{ ++ int mod = CHANNELMOD_NONE; ++ if (totalTtxtSubtitlePages != (fixedTtxtSubtitlePages + numberOfPages)) ++ mod |= CHANNELMOD_PIDS; ++ totalTtxtSubtitlePages = fixedTtxtSubtitlePages; ++ for (int i = 0; (i < numberOfPages) && (totalTtxtSubtitlePages < MAXTXTPAGES); i++) { ++ if (teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine != pages[i].ttxtMagazine || ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage != pages[i].ttxtPage || ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType != pages[i].ttxtType || ++ strcmp(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, pages[i].ttxtLanguage)) { ++ mod |= CHANNELMOD_PIDS; ++ teletextSubtitlePages[totalTtxtSubtitlePages] = pages[i]; ++ } ++ totalTtxtSubtitlePages++; ++ } ++ modification |= mod; ++ Channels.SetModified(); ++} ++ + void cChannel::SetCaIds(const int *CaIds) + { + if (caids[0] && caids[0] <= CA_USER_MAX) +@@ -536,10 +556,17 @@ cString cChannel::ToText(const cChannel *Channel) + q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs, Channel->dtypes); + } + *q = 0; +- const int TBufferSize = MAXSPIDS * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid ++ const int TBufferSize = (MAXTXTPAGES * MAXSPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia and tpid + char tpidbuf[TBufferSize]; + q = tpidbuf; + q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid); ++ if (Channel->fixedTtxtSubtitlePages > 0) { ++ *q++ = '+'; ++ for (int i = 0; i < Channel->fixedTtxtSubtitlePages; ++i) { ++ tTeletextSubtitlePage page = Channel->teletextSubtitlePages[i]; ++ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), "%d=%s", page.PageNumber(), page.ttxtLanguage); ++ } ++ } + if (Channel->spids[0]) { + *q++ = ';'; + q += IntArrayToString(q, Channel->spids, 10, Channel->slangs); +@@ -710,6 +737,32 @@ bool cChannel::Parse(const char *s) + } + spids[NumSpids] = 0; + } ++ fixedTtxtSubtitlePages = 0; ++ if ((p = strchr(tpidbuf, '+')) != NULL) { ++ *p++ = 0; ++ char *q; ++ char *strtok_next; ++ while ((q = strtok_r(p, ",", &strtok_next)) != NULL) { ++ if (fixedTtxtSubtitlePages < MAXTXTPAGES) { ++ int page; ++ char *l = strchr(q, '='); ++ if (l) ++ *l++ = 0; ++ if (sscanf(q, "%d", &page) == 1) { ++ teletextSubtitlePages[fixedTtxtSubtitlePages] = tTeletextSubtitlePage(page); ++ if (l) ++ strn0cpy(teletextSubtitlePages[fixedTtxtSubtitlePages].ttxtLanguage, l, MAXLANGCODE2); ++ fixedTtxtSubtitlePages++; ++ } ++ else ++ esyslog("ERROR: invalid Teletext page!"); // no need to set ok to 'false' ++ } ++ else ++ esyslog("ERROR: too many Teletext pages!"); // no need to set ok to 'false' ++ p = NULL; ++ } ++ totalTtxtSubtitlePages = fixedTtxtSubtitlePages; ++ } + if (sscanf(tpidbuf, "%d", &tpid) != 1) + return false; + if (caidbuf) { +diff --git a/channels.h b/channels.h +index 815cb47..b407672 100644 +--- a/channels.h ++++ b/channels.h +@@ -35,6 +35,7 @@ + #define MAXDPIDS 16 // dolby (AC3 + DTS) + #define MAXSPIDS 32 // subtitles + #define MAXCAIDS 12 // conditional access ++#define MAXTXTPAGES 8 // teletext pages + + #define MAXLANGCODE1 4 // a 3 letter language code, zero terminated + #define MAXLANGCODE2 8 // up to two 3 letter language codes, separated by '+' and zero terminated +@@ -71,6 +72,16 @@ public: + static const tChannelID InvalidID; + }; + ++struct tTeletextSubtitlePage { ++ tTeletextSubtitlePage(void) { ttxtPage = ttxtMagazine = 0; ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } ++ tTeletextSubtitlePage(int page) { ttxtMagazine = (page / 100) & 0x7; ttxtPage = (((page % 100) / 10) << 4) + (page % 10); ttxtType = 0x02; strcpy(ttxtLanguage, "und"); } ++ char ttxtLanguage[MAXLANGCODE1]; ++ uchar ttxtPage; ++ uchar ttxtMagazine; ++ uchar ttxtType; ++ int PageNumber(void) const { return BCDCHARTOINT(ttxtMagazine) * 100 + BCDCHARTOINT(ttxtPage); } ++ }; ++ + class cChannel; + + class cLinkChannel : public cListObject { +@@ -115,6 +126,9 @@ private: + uint16_t compositionPageIds[MAXSPIDS]; + uint16_t ancillaryPageIds[MAXSPIDS]; + int tpid; ++ int fixedTtxtSubtitlePages; ++ int totalTtxtSubtitlePages; ++ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; + int caids[MAXCAIDS + 1]; // list is zero-terminated + int nid; + int tid; +@@ -166,6 +180,8 @@ public: + uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } + uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } + int Tpid(void) const { return tpid; } ++ const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } ++ int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } + const int *Caids(void) const { return caids; } + int Ca(int Index = 0) const { return Index < MAXCAIDS ? caids[Index] : 0; } + int Nid(void) const { return nid; } +@@ -192,6 +208,7 @@ public: + void SetName(const char *Name, const char *ShortName, const char *Provider); + void SetPortalName(const char *PortalName); + void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, int *Dtypes, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid); ++ void SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages); + void SetCaIds(const int *CaIds); // list must be zero-terminated + void SetCaDescriptors(int Level); + void SetLinkChannels(cLinkChannels *LinkChannels); +diff --git a/ci.c b/ci.c +index 9a4a829..ec84027 100644 +--- a/ci.c ++++ b/ci.c +@@ -1914,6 +1914,8 @@ void cCamSlot::AddChannel(const cChannel *Channel) + AddPid(Channel->Sid(), *Dpid, STREAM_TYPE_PRIVATE); + for (const int *Spid = Channel->Spids(); *Spid; Spid++) + AddPid(Channel->Sid(), *Spid, STREAM_TYPE_PRIVATE); ++ if (Channel->Tpid() && Setup.SupportTeletext) ++ AddPid(Channel->Sid(), Channel->Tpid(), STREAM_TYPE_PRIVATE); + } + } + +@@ -1937,6 +1939,9 @@ bool cCamSlot::CanDecrypt(const cChannel *Channel) + CaPmt.AddPid(*Dpid, STREAM_TYPE_PRIVATE); + for (const int *Spid = Channel->Spids(); *Spid; Spid++) + CaPmt.AddPid(*Spid, STREAM_TYPE_PRIVATE); ++ if (Channel->Tpid() && Setup.SupportTeletext) { ++ CaPmt.AddPid(Channel->Tpid(), STREAM_TYPE_PRIVATE); ++ } + cas->SendPMT(&CaPmt); + cTimeMs Timeout(QUERY_REPLY_TIMEOUT); + do { +diff --git a/config.c b/config.c +index 3dc9fe8..0c348de 100644 +--- a/config.c ++++ b/config.c +@@ -397,6 +397,7 @@ cSetup::cSetup(void) + MarginStop = 10; + AudioLanguages[0] = -1; + DisplaySubtitles = 0; ++ SupportTeletext = 1; + SubtitleLanguages[0] = -1; + SubtitleOffset = 0; + SubtitleFgTransparency = 0; +@@ -602,6 +603,7 @@ bool cSetup::Parse(const char *Name, const char *Value) + else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value); + else if (!strcasecmp(Name, "AudioLanguages")) return ParseLanguages(Value, AudioLanguages); + else if (!strcasecmp(Name, "DisplaySubtitles")) DisplaySubtitles = atoi(Value); ++ else if (!strcasecmp(Name, "SupportTeletext")) SupportTeletext = atoi(Value); + else if (!strcasecmp(Name, "SubtitleLanguages")) return ParseLanguages(Value, SubtitleLanguages); + else if (!strcasecmp(Name, "SubtitleOffset")) SubtitleOffset = atoi(Value); + else if (!strcasecmp(Name, "SubtitleFgTransparency")) SubtitleFgTransparency = atoi(Value); +@@ -711,6 +713,7 @@ bool cSetup::Save(void) + Store("MarginStop", MarginStop); + StoreLanguages("AudioLanguages", AudioLanguages); + Store("DisplaySubtitles", DisplaySubtitles); ++ Store("SupportTeletext", SupportTeletext); + StoreLanguages("SubtitleLanguages", SubtitleLanguages); + Store("SubtitleOffset", SubtitleOffset); + Store("SubtitleFgTransparency", SubtitleFgTransparency); +diff --git a/config.h b/config.h +index 9d88d6c..d6d94ff 100644 +--- a/config.h ++++ b/config.h +@@ -273,6 +273,7 @@ public: + int MarginStart, MarginStop; + int AudioLanguages[I18N_MAX_LANGUAGES + 1]; + int DisplaySubtitles; ++ int SupportTeletext; + int SubtitleLanguages[I18N_MAX_LANGUAGES + 1]; + int SubtitleOffset; + int SubtitleFgTransparency, SubtitleBgTransparency; +diff --git a/device.c b/device.c +index ff51a11..bd720ba 100644 +--- a/device.c ++++ b/device.c +@@ -18,6 +18,7 @@ + #include "receiver.h" + #include "status.h" + #include "transfer.h" ++#include "vdrttxtsubshooks.h" + + // --- cLiveSubtitle --------------------------------------------------------- + +@@ -1312,6 +1313,13 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly) + } + break; + case 0xBD: { // private stream 1 ++ // EBU Teletext data, ETSI EN 300 472 ++ // if PES data header length = 24 and data_identifier = 0x10..0x1F (EBU Data) ++ if (Data[8] == 0x24 && Data[45] >= 0x10 && Data[45] < 0x20) { ++ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uint8_t*)Data, Length); ++ break; ++ } ++ + int PayloadOffset = Data[8] + 9; + + // Compatibility mode for old subtitles plugin: +@@ -1471,6 +1479,7 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) + tsToPesVideo.Reset(); + tsToPesAudio.Reset(); + tsToPesSubtitle.Reset(); ++ tsToPesTeletext.Reset(); + } + else if (Length < TS_SIZE) { + esyslog("ERROR: skipped %d bytes of TS fragment", Length); +@@ -1515,6 +1524,17 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) + if (!VideoOnly || HasIBPTrickSpeed()) + PlayTsSubtitle(Data, TS_SIZE); + } ++ else if (Pid == patPmtParser.Tpid()) { ++ if (!VideoOnly || HasIBPTrickSpeed()) { ++ int l; ++ tsToPesTeletext.PutTs(Data, Length); ++ if (const uchar *p = tsToPesTeletext.GetPes(l)) { ++ if ((l > 45) && (p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xbd) && (p[8] == 0x24) && (p[45] >= 0x10) && (p[45] < 0x20)) ++ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uchar *)p, l, false, patPmtParser.TeletextSubtitlePages(), patPmtParser.TotalTeletextSubtitlePages()); ++ tsToPesTeletext.Reset(); ++ } ++ } ++ } + } + } + else if (Pid == patPmtParser.Ppid()) { +diff --git a/device.h b/device.h +index fd010d4..41d410c 100644 +--- a/device.h ++++ b/device.h +@@ -584,6 +584,7 @@ private: + cTsToPes tsToPesVideo; + cTsToPes tsToPesAudio; + cTsToPes tsToPesSubtitle; ++ cTsToPes tsToPesTeletext; + bool isPlayingVideo; + protected: + const cPatPmtParser *PatPmtParser(void) const { return &patPmtParser; } +diff --git a/menu.c b/menu.c +index 7732697..376fe54 100644 +--- a/menu.c ++++ b/menu.c +@@ -2843,6 +2843,7 @@ void cMenuSetupDVB::Setup(void) + Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle foreground transparency"), &data.SubtitleFgTransparency, 0, 9)); + Add(new cMenuEditIntItem( tr("Setup.DVB$Subtitle background transparency"), &data.SubtitleBgTransparency, 0, 10)); + } ++ Add(new cMenuEditBoolItem(tr("Setup.DVB$Enable teletext support"), &data.SupportTeletext)); + + SetCurrent(Get(current)); + Display(); +diff --git a/pat.c b/pat.c +index a7791e2..d9731f8 100644 +--- a/pat.c ++++ b/pat.c +@@ -13,6 +13,7 @@ + #include "libsi/section.h" + #include "libsi/descriptor.h" + #include "thread.h" ++#include "vdrttxtsubshooks.h" + + #define PMT_SCAN_TIMEOUT 10 // seconds + +@@ -343,6 +344,8 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length + char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" }; + char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" }; + int Tpid = 0; ++ tTeletextSubtitlePage TeletextSubtitlePages[MAXTXTPAGES]; ++ int NumTPages = 0; + int NumApids = 0; + int NumDpids = 0; + int NumSpids = 0; +@@ -434,8 +437,21 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length + NumSpids++; + } + break; +- case SI::TeletextDescriptorTag: ++ case SI::TeletextDescriptorTag: { + Tpid = esPid; ++ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; ++ SI::TeletextDescriptor::Teletext ttxt; ++ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { ++ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); ++ if ((NumTPages < MAXTXTPAGES) && ttxt.languageCode[0] && isSubtitlePage) { ++ strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); ++ TeletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber(); ++ TeletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); ++ TeletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType(); ++ NumTPages++; ++ } ++ } ++ } + break; + case SI::ISO639LanguageDescriptorTag: { + SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; +@@ -547,6 +563,12 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length + } + if (Setup.UpdateChannels >= 2) { + Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid); ++ if (NumTPages < MAXTXTPAGES) { ++ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel); ++ if (manualPageNumber) ++ TeletextSubtitlePages[NumTPages++] = tTeletextSubtitlePage(manualPageNumber); ++ } ++ Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages); + Channel->SetCaIds(CaDescriptors->CaIds()); + Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); + } +diff --git a/po/ca_ES.po b/po/ca_ES.po +index 22aeb05..3c80544 100644 +--- a/po/ca_ES.po ++++ b/po/ca_ES.po +@@ -974,6 +974,9 @@ msgstr "Transpar + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparncia fons subttols" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "Configuraci de l'LNB" + +diff --git a/po/cs_CZ.po b/po/cs_CZ.po +index 818c9c1..1daf868 100644 +--- a/po/cs_CZ.po ++++ b/po/cs_CZ.po +@@ -974,6 +974,9 @@ msgstr "Průhlednost písma titulků" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Průhlednost pozadí titulků" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/da_DK.po b/po/da_DK.po +index 73a2122..da3870c 100644 +--- a/po/da_DK.po ++++ b/po/da_DK.po +@@ -971,6 +971,9 @@ msgstr "Undertekst forgrundsgennemsigtighed" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Undertekst baggrundsgennemsigtighed" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/de_DE.po b/po/de_DE.po +index 9e87977..1df2172 100644 +--- a/po/de_DE.po ++++ b/po/de_DE.po +@@ -971,6 +971,9 @@ msgstr "Untertitel-Transparenz Vordergrund" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Untertitel-Transparenz Hintergrund" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "Videotext-Untersttzung aktivieren" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/el_GR.po b/po/el_GR.po +index 50fe460..9582eda 100644 +--- a/po/el_GR.po ++++ b/po/el_GR.po +@@ -971,6 +971,9 @@ msgstr "" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/es_ES.po b/po/es_ES.po +index 2ef8807..dd3b0e4 100644 +--- a/po/es_ES.po ++++ b/po/es_ES.po +@@ -972,6 +972,9 @@ msgstr "Transparencia primer plano subt + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparencia fondo subttulos" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/et_EE.po b/po/et_EE.po +index e60cf5a..e962415 100644 +--- a/po/et_EE.po ++++ b/po/et_EE.po +@@ -971,6 +971,9 @@ msgstr "Subtiitri läbipaistvus" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Subtiitri tausta läbipaistvus" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "Teleteksti tugi" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/fi_FI.po b/po/fi_FI.po +index 7475eb7..a42f159 100644 +--- a/po/fi_FI.po ++++ b/po/fi_FI.po +@@ -975,6 +975,9 @@ msgstr "Tekstityksen läpinäkyvyys" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Tekstityksen taustan läpinäkyvyys" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "Salli teksti-TV-tuki" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/fr_FR.po b/po/fr_FR.po +index 57a6927..04e8f4c 100644 +--- a/po/fr_FR.po ++++ b/po/fr_FR.po +@@ -981,6 +981,9 @@ msgstr "Transparence de l'avant-plan des sous-titres" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparence du fond des sous-titres" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/hr_HR.po b/po/hr_HR.po +index 3a0f73a..d3ab985 100644 +--- a/po/hr_HR.po ++++ b/po/hr_HR.po +@@ -973,6 +973,9 @@ msgstr "Transparentnost titla" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparentnost pozadine titla" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/hu_HU.po b/po/hu_HU.po +index 26ed167..8bb405f 100644 +--- a/po/hu_HU.po ++++ b/po/hu_HU.po +@@ -975,6 +975,9 @@ msgstr "Felirat transzparenciája" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Felirat hátterének transzparenciája" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/it_IT.po b/po/it_IT.po +index ebd68f9..c174668 100644 +--- a/po/it_IT.po ++++ b/po/it_IT.po +@@ -978,6 +978,9 @@ msgstr "Trasparenza sottotitoli" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Trasparenza sfondo sottotitoli" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/lt_LT.po b/po/lt_LT.po +index 6337db4..33dcb42 100644 +--- a/po/lt_LT.po ++++ b/po/lt_LT.po +@@ -971,6 +971,9 @@ msgstr "Subtitrų fonto permatomumas" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Subtitrų fono permatomumas" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "Konverteris (LNB)" + +diff --git a/po/nl_NL.po b/po/nl_NL.po +index 1d1bb73..c7c97f9 100644 +--- a/po/nl_NL.po ++++ b/po/nl_NL.po +@@ -976,6 +976,9 @@ msgstr "Transparantie voorgrond ondertiteling" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparantie achtergrond ondertiteling" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/nn_NO.po b/po/nn_NO.po +index c8491e1..d73a9c1 100644 +--- a/po/nn_NO.po ++++ b/po/nn_NO.po +@@ -972,6 +972,9 @@ msgstr "" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/pl_PL.po b/po/pl_PL.po +index 35a39c4..3143d14 100644 +--- a/po/pl_PL.po ++++ b/po/pl_PL.po +@@ -973,6 +973,9 @@ msgstr "Prze + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Przerocze podtytuw: To" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/pt_PT.po b/po/pt_PT.po +index a485e2b..e3e151e 100644 +--- a/po/pt_PT.po ++++ b/po/pt_PT.po +@@ -972,6 +972,9 @@ msgstr "Transpar + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparncia de fundo das legendas" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/ro_RO.po b/po/ro_RO.po +index a7b6ce8..4a42b9f 100644 +--- a/po/ro_RO.po ++++ b/po/ro_RO.po +@@ -973,6 +973,9 @@ msgstr "Transparenţa prim-planului subtitrării" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparenţa fundalului subtitrării" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/ru_RU.po b/po/ru_RU.po +index ea09a3f..cacb789 100644 +--- a/po/ru_RU.po ++++ b/po/ru_RU.po +@@ -972,6 +972,9 @@ msgstr " + msgid "Setup.DVB$Subtitle background transparency" + msgstr " " + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "" + +diff --git a/po/sk_SK.po b/po/sk_SK.po +index 977d763..98ffd35 100644 +--- a/po/sk_SK.po ++++ b/po/sk_SK.po +@@ -971,6 +971,9 @@ msgstr "Prieh + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Priehadnos pozadia titulkov" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB (nzko umov jednotka)" + +diff --git a/po/sl_SI.po b/po/sl_SI.po +index 86fefbc..01f7b24 100644 +--- a/po/sl_SI.po ++++ b/po/sl_SI.po +@@ -972,6 +972,9 @@ msgstr "Transparentnost podnapisov" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparentnost ozadja podnapisov" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/sv_SE.po b/po/sv_SE.po +index 9b2ce7c..881fa4a 100644 +--- a/po/sv_SE.po ++++ b/po/sv_SE.po +@@ -975,6 +975,9 @@ msgstr "Transparent f + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Transparent bakgrund textremsa" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/tr_TR.po b/po/tr_TR.po +index b5f57b0..5751a46 100644 +--- a/po/tr_TR.po ++++ b/po/tr_TR.po +@@ -971,6 +971,9 @@ msgstr "Altyaz + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Altyaz arka effaflk" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "LNB" + +diff --git a/po/uk_UA.po b/po/uk_UA.po +index 4753432..62cc7bb 100644 +--- a/po/uk_UA.po ++++ b/po/uk_UA.po +@@ -972,6 +972,9 @@ msgstr "Прозорість переднього плану субтитрів" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "Прозорість заднього плану субтитрів" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "Конвертер" + +diff --git a/po/zh_CN.po b/po/zh_CN.po +index efb0300..dcff6a0 100644 +--- a/po/zh_CN.po ++++ b/po/zh_CN.po +@@ -973,6 +973,9 @@ msgstr "字幕前景透明度" + msgid "Setup.DVB$Subtitle background transparency" + msgstr "字幕背景透明度" + ++msgid "Setup.DVB$Enable teletext support" ++msgstr "" ++ + msgid "LNB" + msgstr "切换器设置" + +diff --git a/receiver.c b/receiver.c +index bde60e4..fa9c436 100644 +--- a/receiver.c ++++ b/receiver.c +@@ -67,7 +67,8 @@ bool cReceiver::SetPids(const cChannel *Channel) + (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) && + AddPids(Channel->Apids()) && + AddPids(Channel->Dpids()) && +- AddPids(Channel->Spids()); ++ AddPids(Channel->Spids()) && ++ (!Setup.SupportTeletext || AddPid(Channel->Tpid())); + } + return true; + } +diff --git a/remux.c b/remux.c +index 587d7e5..00dbf05 100644 +--- a/remux.c ++++ b/remux.c +@@ -385,6 +385,29 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua + return i; + } + ++int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount) ++{ ++ int i = 0, j = 0; ++ Target[i++] = SI::TeletextDescriptorTag; ++ int l = i; ++ Target[i++] = 0x00; // length ++ for (int n = 0; n < pageCount; n++) { ++ const char* Language = pages[n].ttxtLanguage; ++ Target[i++] = *Language++; ++ Target[i++] = *Language++; ++ Target[i++] = *Language++; ++ Target[i++] = (pages[n].ttxtType << 3) + pages[n].ttxtMagazine; ++ Target[i++] = pages[n].ttxtPage; ++ j++; ++ } ++ if (j > 0) { ++ Target[l] = j * 5; // update length ++ IncEsInfoLength(i); ++ return i; ++ } ++ return 0; ++} ++ + int cPatPmtGenerator::MakeLanguageDescriptor(uchar *Target, const char *Language) + { + int i = 0; +@@ -472,6 +495,7 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) + if (Channel) { + int Vpid = Channel->Vpid(); + int Ppid = Channel->Ppid(); ++ int Tpid = Channel->Tpid(); + uchar *p = buf; + int i = 0; + p[i++] = 0x02; // table id +@@ -504,6 +528,10 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) + i += MakeStream(buf + i, 0x06, Channel->Spid(n)); + i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n), Channel->SubtitlingType(n), Channel->CompositionPageId(n), Channel->AncillaryPageId(n)); + } ++ if (Tpid) { ++ i += MakeStream(buf + i, 0x06, Tpid); ++ i += MakeTeletextDescriptor(buf + i, Channel->TeletextSubtitlePages(), Channel->TotalTeletextSubtitlePages()); ++ } + + int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC + buf[SectionLength] |= (sl >> 8) & 0x0F; +@@ -577,6 +605,7 @@ void cPatPmtParser::Reset(void) + pmtPids[0] = 0; + vpid = vtype = 0; + ppid = 0; ++ tpid = 0; + } + + void cPatPmtParser::ParsePat(const uchar *Data, int Length) +@@ -665,11 +694,13 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) + int NumSpids = 0; + vpid = vtype = 0; + ppid = 0; ++ tpid = 0; + apids[0] = 0; + dpids[0] = 0; + spids[0] = 0; + atypes[0] = 0; + dtypes[0] = 0; ++ totalTtxtSubtitlePages = 0; + SI::PMT::Stream stream; + for (SI::Loop::Iterator it; Pmt.streamLoop.getNext(stream, it); ) { + dbgpatpmt(" stream type = %02X, pid = %d", stream.getStreamType(), stream.getPid()); +@@ -768,6 +799,28 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) + spids[NumSpids] = 0; + } + break; ++ case SI::TeletextDescriptorTag: { ++ dbgpatpmt(" teletext"); ++ tpid = stream.getPid(); ++ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d; ++ SI::TeletextDescriptor::Teletext ttxt; ++ if (totalTtxtSubtitlePages < MAXTXTPAGES) { ++ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) { ++ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05); ++ if (isSubtitlePage && ttxt.languageCode[0]) { ++ dbgpatpmt(" '%s:%x.%x'", ttxt.languageCode, ttxt.getTeletextMagazineNumber(), ttxt.getTeletextPageNumber()); ++ strn0cpy(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1); ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage = ttxt.getTeletextPageNumber(); ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine = ttxt.getTeletextMagazineNumber(); ++ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType = ttxt.getTeletextType(); ++ totalTtxtSubtitlePages++; ++ if (totalTtxtSubtitlePages >= MAXTXTPAGES) ++ break; ++ } ++ } ++ } ++ } ++ break; + case SI::ISO639LanguageDescriptorTag: { + SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; + dbgpatpmt(" '%s'", ld->languageCode); +diff --git a/remux.h b/remux.h +index 67eda4c..396f41d 100644 +--- a/remux.h ++++ b/remux.h +@@ -294,6 +294,7 @@ protected: + int MakeStream(uchar *Target, uchar Type, int Pid); + int MakeAC3Descriptor(uchar *Target, uchar Type); + int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId); ++ int MakeTeletextDescriptor(uchar *Target, const tTeletextSubtitlePage *pages, int pageCount); + int MakeLanguageDescriptor(uchar *Target, const char *Language); + int MakeCRC(uchar *Target, const uchar *Data, int Length); + void GeneratePmtPid(const cChannel *Channel); +@@ -341,6 +342,7 @@ private: + int vpid; + int ppid; + int vtype; ++ int tpid; + int apids[MAXAPIDS + 1]; // list is zero-terminated + int atypes[MAXAPIDS + 1]; // list is zero-terminated + char alangs[MAXAPIDS][MAXLANGCODE2]; +@@ -353,6 +355,8 @@ private: + uint16_t compositionPageIds[MAXSPIDS]; + uint16_t ancillaryPageIds[MAXSPIDS]; + bool updatePrimaryDevice; ++ int totalTtxtSubtitlePages; ++ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES]; + protected: + int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; } + public: +@@ -389,6 +393,9 @@ public: + int Vtype(void) const { return vtype; } + ///< Returns the video stream type as defined by the current PMT, or 0 if no video + ///< stream type has been detected, yet. ++ int Tpid(void) { return tpid; } ++ ///< Returns the teletext pid as defined by the current PMT, or 0 if no teletext ++ ///< pid has been detected, yet. + const int *Apids(void) const { return apids; } + const int *Dpids(void) const { return dpids; } + const int *Spids(void) const { return spids; } +@@ -403,6 +410,8 @@ public: + uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS) ? subtitlingTypes[i] : uchar(0); } + uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); } + uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); } ++ const tTeletextSubtitlePage *TeletextSubtitlePages() const { return teletextSubtitlePages; } ++ int TotalTeletextSubtitlePages() const { return totalTtxtSubtitlePages; } + }; + + // TS to PES converter: +diff --git a/vdr.5 b/vdr.5 +index ca705d4..dc5c339 100644 +--- a/vdr.5 ++++ b/vdr.5 +@@ -235,6 +235,12 @@ by an '=' sign, as in + + .B ...:201;2001=deu,2002=eng:... + ++Manual teletext subtitling pages can be defined separated by a '+' sign. ++The pages (separated by commas) can contain language codes, delimited by a '=' ++sign, as in ++ ++.B ...:201+150=deu,151=fin;2001,2002:... ++ + .TP + .B Conditional access + A hexadecimal integer defining how this channel can be accessed: +diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c +new file mode 100644 +index 0000000..2471788 +--- /dev/null ++++ b/vdrttxtsubshooks.c +@@ -0,0 +1,63 @@ ++/* ++ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder ++ * Copyright (c) 2003 - 2008 Ragnar Sundblad ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include "vdrttxtsubshooks.h" ++ ++// XXX Really should be a list... ++static cVDRTtxtsubsHookListener *gListener; ++ ++// ------ class cVDRTtxtsubsHookProxy ------ ++ ++class cVDRTtxtsubsHookProxy : public cVDRTtxtsubsHookListener ++{ ++ public: ++ virtual void HideOSD(void) { if(gListener) gListener->HideOSD(); }; ++ virtual void ShowOSD(void) { if(gListener) gListener->ShowOSD(); }; ++ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) ++ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording, teletextSubtitlePages, pageCount); }; ++ virtual int ManualPageNumber(const cChannel *channel) ++ { if(gListener) return gListener->ManualPageNumber(channel); else return 0; }; ++}; ++ ++ ++// ------ class cVDRTtxtsubsHookListener ------ ++ ++cVDRTtxtsubsHookListener::~cVDRTtxtsubsHookListener() ++{ ++ gListener = 0; ++} ++ ++void cVDRTtxtsubsHookListener::HookAttach(void) ++{ ++ gListener = this; ++ //printf("cVDRTtxtsubsHookListener::HookAttach\n"); ++} ++ ++static cVDRTtxtsubsHookProxy gProxy; ++ ++cVDRTtxtsubsHookListener *cVDRTtxtsubsHookListener::Hook(void) ++{ ++ return &gProxy; ++} ++ +diff --git a/vdrttxtsubshooks.h b/vdrttxtsubshooks.h +new file mode 100644 +index 0000000..2f97969 +--- /dev/null ++++ b/vdrttxtsubshooks.h +@@ -0,0 +1,46 @@ ++/* ++ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder ++ * Copyright (c) 2003 - 2008 Ragnar Sundblad ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++#ifndef __VDRTTXTSUBSHOOKS_H ++#define __VDRTTXTSUBSHOOKS_H ++ ++#define TTXTSUBSVERSNUM 2 ++ ++class cDevice; ++class cChannel; ++struct tTeletextSubtitlePage; ++ ++class cVDRTtxtsubsHookListener { ++ public: ++ cVDRTtxtsubsHookListener(void) {}; ++ virtual ~cVDRTtxtsubsHookListener(); ++ ++ void HookAttach(void); ++ ++ virtual void HideOSD(void) {}; ++ virtual void ShowOSD(void) {}; ++ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording = true, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL, int pageCount = 0) {}; ++ virtual int ManualPageNumber(const cChannel *channel) { return 0; }; ++ ++ // used by VDR to call hook listeners ++ static cVDRTtxtsubsHookListener *Hook(void); ++}; ++ ++#endif -- cgit v1.2.3