support patch for media-plugins/vdr-ttxtsubs rebased for vdr-2.6.1 fixing segfault, reported on IRC #gentoo-vdr & vdr-portal.de https://www.vdr-portal.de/forum/index.php?thread/132017-videotextuntertitel-f%C3%BCr-vdr-2-4-0/&postID=1306478#post1306478 Signed-off-by: Joerg Bornkessel ( 2021 Feb 14 ) diff -Naur vdr-2.6.1.orig/MANUAL vdr-2.6.1/MANUAL --- vdr-2.6.1.orig/MANUAL 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/MANUAL 2022-06-20 01:17:40.241599868 +0200 @@ -963,6 +963,9 @@ 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 -Naur vdr-2.6.1.orig/Makefile vdr-2.6.1/Makefile --- vdr-2.6.1.orig/Makefile 2022-06-20 01:16:19.139838587 +0200 +++ vdr-2.6.1/Makefile 2022-06-20 01:17:40.241599868 +0200 @@ -94,6 +94,8 @@ 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 -Naur vdr-2.6.1.orig/channels.c vdr-2.6.1/channels.c --- vdr-2.6.1.orig/channels.c 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/channels.c 2022-06-20 01:17:40.241599868 +0200 @@ -434,6 +434,27 @@ return Modified; } +bool cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages) +{ + int mod = CHANNELMOD_NONE; + LOCK_CHANNELS_WRITE; + 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; + return true; +} + void cChannel::SetSeen(void) { seen = time(NULL); @@ -588,10 +609,17 @@ 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); @@ -763,6 +791,32 @@ } 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 -Naur vdr-2.6.1.orig/channels.h vdr-2.6.1/channels.h --- vdr-2.6.1.orig/channels.h 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/channels.h 2022-06-20 01:17:40.241599868 +0200 @@ -32,6 +32,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 @@ -68,6 +69,16 @@ 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 { @@ -114,6 +125,9 @@ 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; @@ -168,6 +182,8 @@ 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; } @@ -198,6 +214,7 @@ bool SetName(const char *Name, const char *ShortName, const char *Provider); bool SetPortalName(const char *PortalName); bool 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); + bool SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages); bool SetCaIds(const int *CaIds); // list must be zero-terminated bool SetCaDescriptors(int Level); bool SetLinkChannels(cLinkChannels *LinkChannels); diff -Naur vdr-2.6.1.orig/ci.c vdr-2.6.1/ci.c --- vdr-2.6.1.orig/ci.c 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/ci.c 2022-06-20 01:17:40.241599868 +0200 @@ -2732,6 +2732,8 @@ 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); } } @@ -2755,6 +2757,9 @@ 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); + } if (MtdMapper) CaPmt.MtdMapPids(MtdMapper); cas->SendPMT(&CaPmt); diff -Naur vdr-2.6.1.orig/config.c vdr-2.6.1/config.c --- vdr-2.6.1.orig/config.c 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/config.c 2022-06-20 01:17:40.241599868 +0200 @@ -403,6 +403,7 @@ MarginStop = 10; AudioLanguages[0] = -1; DisplaySubtitles = 0; + SupportTeletext = 1; SubtitleLanguages[0] = -1; SubtitleOffset = 0; SubtitleFgTransparency = 0; @@ -631,6 +632,7 @@ 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); @@ -763,6 +765,7 @@ Store("MarginStop", MarginStop); StoreLanguages("AudioLanguages", AudioLanguages); Store("DisplaySubtitles", DisplaySubtitles); + Store("SupportTeletext", SupportTeletext); StoreLanguages("SubtitleLanguages", SubtitleLanguages); Store("SubtitleOffset", SubtitleOffset); Store("SubtitleFgTransparency", SubtitleFgTransparency); diff -Naur vdr-2.6.1.orig/config.h vdr-2.6.1/config.h --- vdr-2.6.1.orig/config.h 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/config.h 2022-06-20 01:17:40.241599868 +0200 @@ -287,6 +287,7 @@ 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 -Naur vdr-2.6.1.orig/device.c vdr-2.6.1/device.c --- vdr-2.6.1.orig/device.c 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/device.c 2022-06-20 01:17:40.241599868 +0200 @@ -19,6 +19,7 @@ #include "receiver.h" #include "status.h" #include "transfer.h" +#include "vdrttxtsubshooks.h" // --- cLiveSubtitle --------------------------------------------------------- @@ -1443,6 +1444,13 @@ } 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: @@ -1601,6 +1609,7 @@ tsToPesVideo.Reset(); tsToPesAudio.Reset(); tsToPesSubtitle.Reset(); + tsToPesTeletext.Reset(); } else if (Length < TS_SIZE) { esyslog("ERROR: skipped %d bytes of TS fragment", Length); @@ -1640,6 +1649,17 @@ 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 -Naur vdr-2.6.1.orig/device.h vdr-2.6.1/device.h --- vdr-2.6.1.orig/device.h 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/device.h 2022-06-20 01:17:40.245599955 +0200 @@ -641,6 +641,7 @@ cTsToPes tsToPesVideo; cTsToPes tsToPesAudio; cTsToPes tsToPesSubtitle; + cTsToPes tsToPesTeletext; bool isPlayingVideo; protected: const cPatPmtParser *PatPmtParser(void) const { return &patPmtParser; } diff -Naur vdr-2.6.1.orig/menu.c vdr-2.6.1/menu.c --- vdr-2.6.1.orig/menu.c 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/menu.c 2022-06-20 01:17:40.245599955 +0200 @@ -3785,6 +3785,7 @@ 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 -Naur vdr-2.6.1.orig/pat.c vdr-2.6.1/pat.c --- vdr-2.6.1.orig/pat.c 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/pat.c 2022-06-20 01:17:40.245599955 +0200 @@ -12,6 +12,7 @@ #include "channels.h" #include "libsi/section.h" #include "libsi/descriptor.h" +#include "vdrttxtsubshooks.h" #define PMT_SCAN_TIMEOUT 1000 // ms @@ -632,6 +633,8 @@ 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; @@ -724,8 +727,21 @@ 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; @@ -839,6 +855,12 @@ } if (Setup.UpdateChannels >= 2) { ChannelsModified |= 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); + } + ChannelsModified |= Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages); ChannelsModified |= Channel->SetCaIds(CaDescriptors->CaIds()); ChannelsModified |= Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds); } diff -Naur vdr-2.6.1.orig/po/ar.po vdr-2.6.1/po/ar.po --- vdr-2.6.1.orig/po/ar.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/ar.po 2022-06-20 01:17:40.245599955 +0200 @@ -1123,6 +1123,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "شفافية الخلفية" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "الاقط" diff -Naur vdr-2.6.1.orig/po/ca_ES.po vdr-2.6.1/po/ca_ES.po --- vdr-2.6.1.orig/po/ca_ES.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/ca_ES.po 2022-06-20 01:17:40.245599955 +0200 @@ -1122,6 +1122,9 @@ 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 -Naur vdr-2.6.1.orig/po/cs_CZ.po vdr-2.6.1/po/cs_CZ.po --- vdr-2.6.1.orig/po/cs_CZ.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/cs_CZ.po 2022-06-20 01:17:40.245599955 +0200 @@ -1122,6 +1122,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Průhlednost pozadí titulků" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/da_DK.po vdr-2.6.1/po/da_DK.po --- vdr-2.6.1.orig/po/da_DK.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/da_DK.po 2022-06-20 01:17:40.245599955 +0200 @@ -1119,6 +1119,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Undertekst baggrundsgennemsigtighed" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/de_DE.po vdr-2.6.1/po/de_DE.po --- vdr-2.6.1.orig/po/de_DE.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/de_DE.po 2022-06-20 01:17:36.541519538 +0200 @@ -1120,6 +1120,9 @@ 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 -Naur vdr-2.6.1.orig/po/el_GR.po vdr-2.6.1/po/el_GR.po --- vdr-2.6.1.orig/po/el_GR.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/el_GR.po 2022-06-20 01:17:40.245599955 +0200 @@ -1119,6 +1119,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/es_ES.po vdr-2.6.1/po/es_ES.po --- vdr-2.6.1.orig/po/es_ES.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/es_ES.po 2022-06-20 01:17:40.245599955 +0200 @@ -1120,6 +1120,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparencia fondo subttulos" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/et_EE.po vdr-2.6.1/po/et_EE.po --- vdr-2.6.1.orig/po/et_EE.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/et_EE.po 2022-06-20 01:17:40.245599955 +0200 @@ -1119,6 +1119,9 @@ 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 -Naur vdr-2.6.1.orig/po/fi_FI.po vdr-2.6.1/po/fi_FI.po --- vdr-2.6.1.orig/po/fi_FI.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/fi_FI.po 2022-06-20 01:17:40.245599955 +0200 @@ -1123,6 +1123,9 @@ 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 -Naur vdr-2.6.1.orig/po/fr_FR.po vdr-2.6.1/po/fr_FR.po --- vdr-2.6.1.orig/po/fr_FR.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/fr_FR.po 2022-06-20 01:17:40.249600042 +0200 @@ -1130,6 +1130,9 @@ 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 -Naur vdr-2.6.1.orig/po/hr_HR.po vdr-2.6.1/po/hr_HR.po --- vdr-2.6.1.orig/po/hr_HR.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/hr_HR.po 2022-06-20 01:17:40.249600042 +0200 @@ -1121,6 +1121,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparentnost pozadine titla" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/hu_HU.po vdr-2.6.1/po/hu_HU.po --- vdr-2.6.1.orig/po/hu_HU.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/hu_HU.po 2022-06-20 01:17:40.249600042 +0200 @@ -1124,6 +1124,9 @@ 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 -Naur vdr-2.6.1.orig/po/it_IT.po vdr-2.6.1/po/it_IT.po --- vdr-2.6.1.orig/po/it_IT.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/it_IT.po 2022-06-20 01:17:40.249600042 +0200 @@ -1125,6 +1125,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Trasparenza sfondo sottotitoli" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/lt_LT.po vdr-2.6.1/po/lt_LT.po --- vdr-2.6.1.orig/po/lt_LT.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/lt_LT.po 2022-06-20 01:17:40.249600042 +0200 @@ -1119,6 +1119,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Subtitrų fono permatomumas" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "Konverteris (LNB)" diff -Naur vdr-2.6.1.orig/po/mk_MK.po vdr-2.6.1/po/mk_MK.po --- vdr-2.6.1.orig/po/mk_MK.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/mk_MK.po 2022-06-20 01:17:40.249600042 +0200 @@ -1121,6 +1121,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Провидност на позадината на титлот" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/nl_NL.po vdr-2.6.1/po/nl_NL.po --- vdr-2.6.1.orig/po/nl_NL.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/nl_NL.po 2022-06-20 01:17:40.249600042 +0200 @@ -1125,6 +1125,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparantie achtergrond ondertiteling" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/nn_NO.po vdr-2.6.1/po/nn_NO.po --- vdr-2.6.1.orig/po/nn_NO.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/nn_NO.po 2022-06-20 01:17:40.249600042 +0200 @@ -1120,6 +1120,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/pl_PL.po vdr-2.6.1/po/pl_PL.po --- vdr-2.6.1.orig/po/pl_PL.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/pl_PL.po 2022-06-20 01:17:40.249600042 +0200 @@ -1124,6 +1124,10 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Przeźrocze podtytułów: Tło" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/pt_PT.po vdr-2.6.1/po/pt_PT.po --- vdr-2.6.1.orig/po/pt_PT.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/pt_PT.po 2022-06-20 01:17:40.249600042 +0200 @@ -1120,6 +1120,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparncia de fundo das legendas" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/ro_RO.po vdr-2.6.1/po/ro_RO.po --- vdr-2.6.1.orig/po/ro_RO.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/ro_RO.po 2022-06-20 01:17:40.249600042 +0200 @@ -1121,6 +1121,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparenţa fundalului subtitrării" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/ru_RU.po vdr-2.6.1/po/ru_RU.po --- vdr-2.6.1.orig/po/ru_RU.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/ru_RU.po 2022-06-20 01:17:40.249600042 +0200 @@ -1120,6 +1120,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Прозрачность фона субтитров" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "Конвертер" diff -Naur vdr-2.6.1.orig/po/sk_SK.po vdr-2.6.1/po/sk_SK.po --- vdr-2.6.1.orig/po/sk_SK.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/sk_SK.po 2022-06-20 01:17:40.249600042 +0200 @@ -1120,6 +1120,9 @@ 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 -Naur vdr-2.6.1.orig/po/sl_SI.po vdr-2.6.1/po/sl_SI.po --- vdr-2.6.1.orig/po/sl_SI.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/sl_SI.po 2022-06-20 01:17:40.249600042 +0200 @@ -1120,6 +1120,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparentnost ozadja podnapisov" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/sr_RS.po vdr-2.6.1/po/sr_RS.po --- vdr-2.6.1.orig/po/sr_RS.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/sr_RS.po 2022-06-20 01:17:40.253600129 +0200 @@ -1120,6 +1120,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Providnost pozadine titla" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/sv_SE.po vdr-2.6.1/po/sv_SE.po --- vdr-2.6.1.orig/po/sv_SE.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/sv_SE.po 2022-06-20 01:17:40.253600129 +0200 @@ -1124,6 +1124,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Transparent bakgrund textremsa" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/tr_TR.po vdr-2.6.1/po/tr_TR.po --- vdr-2.6.1.orig/po/tr_TR.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/tr_TR.po 2022-06-20 01:17:40.253600129 +0200 @@ -1119,6 +1119,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Altyaz arka effaflk" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "LNB" diff -Naur vdr-2.6.1.orig/po/uk_UA.po vdr-2.6.1/po/uk_UA.po --- vdr-2.6.1.orig/po/uk_UA.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/uk_UA.po 2022-06-20 01:17:40.253600129 +0200 @@ -1120,6 +1120,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "Прозорість заднього плану субтитрів" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "Конвертер" diff -Naur vdr-2.6.1.orig/po/zh_CN.po vdr-2.6.1/po/zh_CN.po --- vdr-2.6.1.orig/po/zh_CN.po 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/po/zh_CN.po 2022-06-20 01:17:40.253600129 +0200 @@ -1121,6 +1121,9 @@ msgid "Setup.DVB$Subtitle background transparency" msgstr "字幕背景透明度" +msgid "Setup.DVB$Enable teletext support" +msgstr "" + msgid "LNB" msgstr "切换器设置" diff -Naur vdr-2.6.1.orig/receiver.c vdr-2.6.1/receiver.c --- vdr-2.6.1.orig/receiver.c 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/receiver.c 2022-06-20 01:17:40.253600129 +0200 @@ -82,7 +82,8 @@ (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 -Naur vdr-2.6.1.orig/remux.c vdr-2.6.1/remux.c --- vdr-2.6.1.orig/remux.c 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/remux.c 2022-06-20 01:17:40.253600129 +0200 @@ -429,6 +429,29 @@ 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; @@ -516,6 +539,7 @@ 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 @@ -548,6 +572,10 @@ 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; @@ -622,6 +650,7 @@ pmtPids[0] = 0; vpid = vtype = 0; ppid = 0; + tpid = 0; } void cPatPmtParser::ParsePat(const uchar *Data, int Length) @@ -710,11 +739,13 @@ 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()); @@ -814,6 +845,28 @@ 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 -Naur vdr-2.6.1.orig/remux.h vdr-2.6.1/remux.h --- vdr-2.6.1.orig/remux.h 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/remux.h 2022-06-20 01:17:40.253600129 +0200 @@ -313,6 +313,7 @@ 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); @@ -360,6 +361,7 @@ 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]; @@ -373,6 +375,8 @@ uint16_t ancillaryPageIds[MAXSPIDS]; bool updatePrimaryDevice; bool completed; + 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: @@ -409,6 +413,9 @@ 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. bool Completed(void) { return completed; } ///< Returns true if the PMT has been completely parsed. const int *Apids(void) const { return apids; } @@ -425,6 +432,8 @@ 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; } }; // EIT Generator: diff -Naur vdr-2.6.1.orig/vdr.5 vdr-2.6.1/vdr.5 --- vdr-2.6.1.orig/vdr.5 2022-02-02 10:56:43.000000000 +0100 +++ vdr-2.6.1/vdr.5 2022-06-20 01:17:40.253600129 +0200 @@ -249,6 +249,12 @@ .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 -Naur vdr-2.6.1.orig/vdrttxtsubshooks.c vdr-2.6.1/vdrttxtsubshooks.c --- vdr-2.6.1.orig/vdrttxtsubshooks.c 1970-01-01 01:00:00.000000000 +0100 +++ vdr-2.6.1/vdrttxtsubshooks.c 2022-06-20 01:17:40.253600129 +0200 @@ -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 -Naur vdr-2.6.1.orig/vdrttxtsubshooks.h vdr-2.6.1/vdrttxtsubshooks.h --- vdr-2.6.1.orig/vdrttxtsubshooks.h 1970-01-01 01:00:00.000000000 +0100 +++ vdr-2.6.1/vdrttxtsubshooks.h 2022-06-20 01:17:40.253600129 +0200 @@ -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