summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Grimm <git@e-tobi.net>2010-02-13 16:59:35 +0100
committerTobias Grimm <git@e-tobi.net>2010-02-13 22:33:19 +0100
commit438ed4c380061d1f855e09e1c9625e233b5b0bb0 (patch)
tree46b9d8e5c63cf8e83f4f756b02c59e4205decf51
parente19403cc5f7996348d23528fbe6a3bc113da5e7d (diff)
downloadvdr-plugin-ttxtsubs-438ed4c380061d1f855e09e1c9625e233b5b0bb0.tar.gz
vdr-plugin-ttxtsubs-438ed4c380061d1f855e09e1c9625e233b5b0bb0.tar.bz2
Updated VDR patch (Closes #117)
-rw-r--r--HISTORY13
-rw-r--r--patches/patch-set/0001-Record-teletext-subtitles.patch210
-rw-r--r--patches/patch-set/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch696
-rw-r--r--patches/patch-set/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch137
-rw-r--r--patches/patch-set/0004-Capture-teletext-subtitle-pages-from-PMT.patch104
-rw-r--r--patches/patch-set/0005-Ttxtsubs-plugin-hook.patch244
-rw-r--r--patches/vdr-1.7.12-ttxtsubs-tpid-v2.patch516
-rw-r--r--patches/vdr-1.7.12-ttxtsubs.patch1003
-rw-r--r--patches/vdr-1.7.6-ttxtsubs.patch510
-rw-r--r--patches/vdr-1.7.8-ttxtsubs.patch510
10 files changed, 2304 insertions, 1639 deletions
diff --git a/HISTORY b/HISTORY
index a965ca6..fb0b32b 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3,14 +3,17 @@ VDR Plugin 'ttxtsubs' Revision History
2010-02-xx: Version 0.2.0
- Add Ukrainian translation by Yarema aka Knedlyk (Closes #130)
-- Updated VDR patch for 1.7.8
- Some code refactoring
-- Updated plugin and VDR patch for 1.7.12 - Thx to Rolf Ahrenberg (Closes #236)
+- Major VDR patch update for 1.7.12 (Closes #236, References #139)) - The patch
+ now covers the following changes to VDR:
+ - Record teletext subtitles
+ - Added setup option to enable teletext subtitle recording
+ - Allow configuration of fixed teletetxt subtitle pages
+ - Capture teletext subtitle pages from PMT
+ - Pass teletext date ttxtsubs plugin
+ Special Thx to Rolf Ahrenberg!
- Fixed replay when the current live ttxtsubs page differs from the
one in the recording - Thx to Rolf Ahrenberg (Closes #139)
-- Added VDR patch that stores the manual page selection with the channel settings
- in the channels.conf - patch provided by Rolf Ahrenberg (tpid-v2)
- (references #139)
- Show colored subtitles if color information is provided e.g. for
different speakers and dropped custom color settings (Closes #61)
- Position subtitles always centered at the bottom, independent of the
diff --git a/patches/patch-set/0001-Record-teletext-subtitles.patch b/patches/patch-set/0001-Record-teletext-subtitles.patch
new file mode 100644
index 0000000..05122c6
--- /dev/null
+++ b/patches/patch-set/0001-Record-teletext-subtitles.patch
@@ -0,0 +1,210 @@
+From 43914f1e49c368fbcc4d97e63e0e878de1238594 Mon Sep 17 00:00:00 2001
+From: etobi <git@e-tobi.net>
+Date: Fri, 12 Feb 2010 21:55:04 +0100
+Subject: [PATCH 1/5] Record teletext subtitles
+
+---
+ channels.c | 7 +++++++
+ channels.h | 14 ++++++++++++++
+ pat.c | 18 +++++++++++++++++-
+ receiver.c | 2 +-
+ remux.c | 28 ++++++++++++++++++++++++++++
+ remux.h | 1 +
+ 6 files changed, 68 insertions(+), 2 deletions(-)
+
+diff --git a/channels.c b/channels.c
+index c14df19..817b7d3 100644
+--- a/channels.c
++++ b/channels.c
+@@ -551,6 +551,13 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos
+ }
+ }
+
++void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[])
++{
++ for (int i = 0; i < MAXTXTPAGES; i++)
++ teletextSubtitlePages[i] = pages[i];
++ teletextSubtitlePages[MAXTXTPAGES].ttxtType = 0;
++}
++
+ void cChannel::SetCaIds(const int *CaIds)
+ {
+ if (caids[0] && caids[0] <= CA_USER_MAX)
+diff --git a/channels.h b/channels.h
+index b465f6a..18ed7c6 100644
+--- a/channels.h
++++ b/channels.h
+@@ -35,6 +35,7 @@
+ #define MAXDPIDS 16 // dolby (AC3 + DTS)
+ #define MAXSPIDS 32 // subtitles
+ #define MAXCAIDS 8 // 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
+@@ -92,6 +93,16 @@ public:
+ static const tChannelID InvalidID;
+ };
+
++struct tTeletextSubtitlePage {
++ tTeletextSubtitlePage(void) { ttxtPage = ttxtMagazine = ttxtType = ttxtLanguage[0] = 0; }
++ tTeletextSubtitlePage(int page) { ttxtMagazine = (page / 100) & 0x7; ttxtPage = (((page % 100) / 10) << 4) + (page % 10); ttxtType = 0x02; }
++ 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 {
+@@ -133,6 +144,7 @@ private:
+ uint16_t compositionPageIds[MAXSPIDS];
+ uint16_t ancillaryPageIds[MAXSPIDS];
+ int tpid;
++ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES + 1]; // list is termintated by ttxtType=0
+ int caids[MAXCAIDS + 1]; // list is zero-terminated
+ int nid;
+ int tid;
+@@ -192,6 +204,7 @@ 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 TeletextSubtitlePage(int i) const { return (0 <= i && i < MAXTXTPAGES) ? teletextSubtitlePages[i] : tTeletextSubtitlePage(); };
+ 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; }
+@@ -228,6 +241,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, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
++ void SetTeletextSubtitlePages(tTeletextSubtitlePage pages[]);
+ 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 9b3ded6..f4be6a6 100644
+--- a/pat.c
++++ b/pat.c
+@@ -341,6 +341,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;
+@@ -426,8 +428,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;
+@@ -458,6 +473,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, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
++ Channel->SetTeletextSubtitlePages(TeletextSubtitlePages);
+ Channel->SetCaIds(CaDescriptors->CaIds());
+ Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
+ }
+diff --git a/receiver.c b/receiver.c
+index f922e98..dab95b3 100644
+--- a/receiver.c
++++ b/receiver.c
+@@ -82,7 +82,7 @@ bool cReceiver::SetPids(const cChannel *Channel)
+ (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) &&
+ AddPids(Channel->Apids()) &&
+ (!Setup.UseDolbyDigital || AddPids(Channel->Dpids())) &&
+- AddPids(Channel->Spids());
++ AddPids(Channel->Spids()) && AddPid(Channel->Tpid());
+ }
+ return true;
+ }
+diff --git a/remux.c b/remux.c
+index 070a06a..869b6e4 100644
+--- a/remux.c
++++ b/remux.c
+@@ -215,6 +215,29 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua
+ return i;
+ }
+
++int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, const cChannel *Channel)
++{
++ int i = 0, j = 0;
++ Target[i++] = SI::TeletextDescriptorTag;
++ int l = i;
++ Target[i++] = 0x00; // length
++ for (int n = 0; Channel->TeletextSubtitlePage(n).ttxtType; n++) {
++ const char* Language = Channel->TeletextSubtitlePage(n).ttxtLanguage;
++ Target[i++] = *Language++;
++ Target[i++] = *Language++;
++ Target[i++] = *Language++;
++ Target[i++] = (Channel->TeletextSubtitlePage(n).ttxtType << 3) + Channel->TeletextSubtitlePage(n).ttxtMagazine;
++ Target[i++] = Channel->TeletextSubtitlePage(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;
+@@ -296,6 +319,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
+@@ -330,6 +354,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);
++ }
+
+ int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC
+ buf[SectionLength] |= (sl >> 8) & 0x0F;
+diff --git a/remux.h b/remux.h
+index 1115c4a..cef50d7 100644
+--- a/remux.h
++++ b/remux.h
+@@ -170,6 +170,7 @@ protected:
+ int MakeStream(uchar *Target, uchar Type, int Pid);
+ int MakeAC3Descriptor(uchar *Target);
+ int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId);
++ int MakeTeletextDescriptor(uchar *Target, const cChannel *Channel);
+ int MakeLanguageDescriptor(uchar *Target, const char *Language);
+ int MakeCRC(uchar *Target, const uchar *Data, int Length);
+ void GeneratePmtPid(const cChannel *Channel);
+--
+1.6.5
+
diff --git a/patches/patch-set/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch b/patches/patch-set/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch
new file mode 100644
index 0000000..80cfac5
--- /dev/null
+++ b/patches/patch-set/0002-Added-setup-option-to-enable-teletext-subtitle-recor.patch
@@ -0,0 +1,696 @@
+From 53a2a588490c058bb2a907d00dad88927bec4618 Mon Sep 17 00:00:00 2001
+From: etobi <git@e-tobi.net>
+Date: Sat, 13 Feb 2010 14:42:30 +0100
+Subject: [PATCH 2/5] Added setup option to enable teletext subtitle recording
+
+---
+ MANUAL | 3 +++
+ config.c | 3 +++
+ config.h | 1 +
+ menu.c | 1 +
+ po/ca_ES.po | 5 ++++-
+ po/cs_CZ.po | 5 ++++-
+ po/da_DK.po | 5 ++++-
+ po/de_DE.po | 5 ++++-
+ po/el_GR.po | 5 ++++-
+ po/es_ES.po | 5 ++++-
+ po/et_EE.po | 5 ++++-
+ po/fi_FI.po | 5 ++++-
+ po/fr_FR.po | 5 ++++-
+ po/hr_HR.po | 5 ++++-
+ po/hu_HU.po | 5 ++++-
+ po/it_IT.po | 5 ++++-
+ po/lt_LT.po | 5 ++++-
+ po/nl_NL.po | 5 ++++-
+ po/nn_NO.po | 5 ++++-
+ po/pl_PL.po | 5 ++++-
+ po/pt_PT.po | 5 ++++-
+ po/ro_RO.po | 5 ++++-
+ po/ru_RU.po | 5 ++++-
+ po/sk_SK.po | 5 ++++-
+ po/sl_SI.po | 5 ++++-
+ po/sv_SE.po | 5 ++++-
+ po/tr_TR.po | 5 ++++-
+ po/uk_UA.po | 5 ++++-
+ po/zh_CN.po | 5 ++++-
+ receiver.c | 3 ++-
+ 30 files changed, 110 insertions(+), 26 deletions(-)
+
+diff --git a/MANUAL b/MANUAL
+index 405f6a8..d1ce1f9 100644
+--- a/MANUAL
++++ b/MANUAL
+@@ -721,6 +721,9 @@ Version 1.6
+ background transparency. By default the values as broadcast
+ are used.
+
++ Record Teletext Subtitles = no
++ If set to 'yes', teletext subtitles will be recorded.
++
+ LNB:
+
+ SLOF = 11700 The switching frequency (in MHz) between low and
+diff --git a/config.c b/config.c
+index acdf4c4..4aaf720 100644
+--- a/config.c
++++ b/config.c
+@@ -333,6 +333,7 @@ cSetup::cSetup(void)
+ MarginStop = 10;
+ AudioLanguages[0] = -1;
+ DisplaySubtitles = 0;
++ RecordTtxtSubtitles = 0;
+ SubtitleLanguages[0] = -1;
+ SubtitleOffset = 0;
+ SubtitleFgTransparency = 0;
+@@ -521,6 +522,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, "RecordTtxtSubtitles")) RecordTtxtSubtitles = 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);
+@@ -614,6 +616,7 @@ bool cSetup::Save(void)
+ Store("MarginStop", MarginStop);
+ StoreLanguages("AudioLanguages", AudioLanguages);
+ Store("DisplaySubtitles", DisplaySubtitles);
++ Store("RecordTtxtSubtitles", RecordTtxtSubtitles);
+ StoreLanguages("SubtitleLanguages", SubtitleLanguages);
+ Store("SubtitleOffset", SubtitleOffset);
+ Store("SubtitleFgTransparency", SubtitleFgTransparency);
+diff --git a/config.h b/config.h
+index be1d7bd..5dcbe20 100644
+--- a/config.h
++++ b/config.h
+@@ -235,6 +235,7 @@ public:
+ int MarginStart, MarginStop;
+ int AudioLanguages[I18N_MAX_LANGUAGES + 1];
+ int DisplaySubtitles;
++ int RecordTtxtSubtitles;
+ int SubtitleLanguages[I18N_MAX_LANGUAGES + 1];
+ int SubtitleOffset;
+ int SubtitleFgTransparency, SubtitleBgTransparency;
+diff --git a/menu.c b/menu.c
+index 7ddf0cf..1f49f3d 100644
+--- a/menu.c
++++ b/menu.c
+@@ -2790,6 +2790,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$Record Teletext Subtitles"), &data.RecordTtxtSubtitles));
+
+ SetCurrent(Get(current));
+ Display();
+diff --git a/po/ca_ES.po b/po/ca_ES.po
+index fcdf672..1197fe1 100644
+--- a/po/ca_ES.po
++++ b/po/ca_ES.po
+@@ -10,7 +10,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-02 19:02+0100\n"
+ "Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
+ "Language-Team: Catalanian\n"
+@@ -934,6 +934,9 @@ msgstr "Transpar
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparncia fons subttols"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "Configuraci de l'LNB"
+
+diff --git a/po/cs_CZ.po b/po/cs_CZ.po
+index 3bbd6eb..c15fc13 100644
+--- a/po/cs_CZ.po
++++ b/po/cs_CZ.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-28 15:00+0200\n"
+ "Last-Translator: Vladimr Brta <vladimir.barta@k2atmitec.cz>, Ji Dobr <jdobry@centrum.cz>\n"
+ "Language-Team: Czech\n"
+@@ -932,6 +932,9 @@ msgstr "Pr
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Prhlednost pozad titulk"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/da_DK.po b/po/da_DK.po
+index fbad909..3416080 100644
+--- a/po/da_DK.po
++++ b/po/da_DK.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-12 14:17+0200\n"
+ "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n"
+ "Language-Team: Danish\n"
+@@ -931,6 +931,9 @@ msgstr "Undertekst forgrundsgennemsigtighed"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Undertekst baggrundsgennemsigtighed"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/de_DE.po b/po/de_DE.po
+index ad6401b..775fd30 100644
+--- a/po/de_DE.po
++++ b/po/de_DE.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2010-01-16 16:46+0100\n"
+ "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n"
+ "Language-Team: German\n"
+@@ -931,6 +931,9 @@ msgstr "Untertitel-Transparenz Vordergrund"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Untertitel-Transparenz Hintergrund"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr "Teletext-Untertitel aufnehmen"
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/el_GR.po b/po/el_GR.po
+index e8382b8..741cb4a 100644
+--- a/po/el_GR.po
++++ b/po/el_GR.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-12 14:17+0200\n"
+ "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n"
+ "Language-Team: Greek\n"
+@@ -931,6 +931,9 @@ msgstr ""
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr ""
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/es_ES.po b/po/es_ES.po
+index d2bf5b0..0515348 100644
+--- a/po/es_ES.po
++++ b/po/es_ES.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-02 19:02+0100\n"
+ "Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
+ "Language-Team: Spanish\n"
+@@ -932,6 +932,9 @@ msgstr "Transparencia primer plano subt
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparencia fondo subttulos"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/et_EE.po b/po/et_EE.po
+index 97e2aee..72a95ae 100644
+--- a/po/et_EE.po
++++ b/po/et_EE.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-12 14:17+0200\n"
+ "Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
+ "Language-Team: Estonian\n"
+@@ -931,6 +931,9 @@ msgstr "Subtiitri l
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Subtiitri tausta lbipaistvus"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/fi_FI.po b/po/fi_FI.po
+index 916b51e..372a1a2 100644
+--- a/po/fi_FI.po
++++ b/po/fi_FI.po
+@@ -10,7 +10,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-15 15:52+0200\n"
+ "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
+ "Language-Team: Finnish\n"
+@@ -934,6 +934,9 @@ msgstr "Tekstityksen l
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Tekstityksen taustan lpinkyvyys"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/fr_FR.po b/po/fr_FR.po
+index 4c4dcce..8ebfd3e 100644
+--- a/po/fr_FR.po
++++ b/po/fr_FR.po
+@@ -13,7 +13,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-27 18:14+0100\n"
+ "Last-Translator: Jean-Claude Repetto <jc@repetto.org>\n"
+ "Language-Team: French\n"
+@@ -937,6 +937,9 @@ msgstr "Transparence de l'avant-plan"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparence du fond"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/hr_HR.po b/po/hr_HR.po
+index b7cf5a0..d769dc1 100644
+--- a/po/hr_HR.po
++++ b/po/hr_HR.po
+@@ -9,7 +9,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-17 19:00+0100\n"
+ "Last-Translator: Adrian Caval <anrxc@sysphere.org>\n"
+ "Language-Team: Croatian\n"
+@@ -933,6 +933,9 @@ msgstr "Transparentnost titla"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparentnost pozadine titla"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/hu_HU.po b/po/hu_HU.po
+index d09c8dd..e2b9364 100644
+--- a/po/hu_HU.po
++++ b/po/hu_HU.po
+@@ -10,7 +10,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-12-01 21:42+0200\n"
+ "Last-Translator: Istvn Fley <ifuley@tigercomp.ro>\n"
+ "Language-Team: Hungarian\n"
+@@ -934,6 +934,9 @@ msgstr "Felirat transzparenci
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Felirat htternek transzparencija"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/it_IT.po b/po/it_IT.po
+index 3a8f2e2..41335d8 100644
+--- a/po/it_IT.po
++++ b/po/it_IT.po
+@@ -11,7 +11,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2010-01-12 23:53+0100\n"
+ "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
+ "Language-Team: Italian\n"
+@@ -938,6 +938,9 @@ msgstr "Trasparenza sottotitoli"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Trasparenza sfondo sottotitoli"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/lt_LT.po b/po/lt_LT.po
+index 93583c5..2b55e82 100644
+--- a/po/lt_LT.po
++++ b/po/lt_LT.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.7.9\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2009-10-17 14:19+0200\n"
+ "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
+ "Language-Team: Lithuanian\n"
+@@ -931,6 +931,9 @@ msgstr "Subtitrų priekinio vaizdo permatomumas"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Subtitrų fono permatomumas"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "Konverteris (LNB)"
+
+diff --git a/po/nl_NL.po b/po/nl_NL.po
+index fdfaf8d..56523f4 100644
+--- a/po/nl_NL.po
++++ b/po/nl_NL.po
+@@ -11,7 +11,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-26 17:20+0100\n"
+ "Last-Translator: Johan Schuring <johan.schuring@vetteblei.nl>\n"
+ "Language-Team: Dutch\n"
+@@ -935,6 +935,9 @@ msgstr "Transparantie voorgrond ondertiteling"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparantie achtergrond ondertiteling"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/nn_NO.po b/po/nn_NO.po
+index 1f50117..3e492ad 100644
+--- a/po/nn_NO.po
++++ b/po/nn_NO.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-12 14:17+0200\n"
+ "Last-Translator: Truls Slevigen <truls@slevigen.no>\n"
+ "Language-Team: Norwegian\n"
+@@ -932,6 +932,9 @@ msgstr ""
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr ""
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/pl_PL.po b/po/pl_PL.po
+index 038d058..e99d90e 100644
+--- a/po/pl_PL.po
++++ b/po/pl_PL.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-09 12:59+0100\n"
+ "Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
+ "Language-Team: Polish\n"
+@@ -932,6 +932,9 @@ msgstr "Prze
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Przerocze podtytuw: To"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/pt_PT.po b/po/pt_PT.po
+index e409581..f795bae 100644
+--- a/po/pt_PT.po
++++ b/po/pt_PT.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-18 17:04+0100\n"
+ "Last-Translator: anonymous\n"
+ "Language-Team: Portuguese\n"
+@@ -931,6 +931,9 @@ msgstr "Transpar
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparncia de background das legendas"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/ro_RO.po b/po/ro_RO.po
+index f52a7d8..c857472 100644
+--- a/po/ro_RO.po
++++ b/po/ro_RO.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-25 00:39+0100\n"
+ "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n"
+ "Language-Team: Romanian\n"
+@@ -934,6 +934,9 @@ msgstr "Transparen
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparena fundalului subtitrrii"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/ru_RU.po b/po/ru_RU.po
+index c6d6aca..e55f00d 100644
+--- a/po/ru_RU.po
++++ b/po/ru_RU.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-12-15 14:37+0100\n"
+ "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
+ "Language-Team: Russian\n"
+@@ -932,6 +932,9 @@ msgstr "
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr " "
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr ""
+
+diff --git a/po/sk_SK.po b/po/sk_SK.po
+index c66132a..44b0833 100644
+--- a/po/sk_SK.po
++++ b/po/sk_SK.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2009-09-30 12:50+0100\n"
+ "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
+ "Language-Team: Slovak\n"
+@@ -932,6 +932,9 @@ msgstr "Prieh
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Priehadnos pozadia titulkov"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/sl_SI.po b/po/sl_SI.po
+index 2c20440..2bd42ea 100644
+--- a/po/sl_SI.po
++++ b/po/sl_SI.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-28 19:44+0100\n"
+ "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n"
+ "Language-Team: Slovenian\n"
+@@ -932,6 +932,9 @@ msgstr "Transparentnost podnapisov"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparentnost ozadja podnapisov"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/sv_SE.po b/po/sv_SE.po
+index 4ac9a0f..1cceb44 100644
+--- a/po/sv_SE.po
++++ b/po/sv_SE.po
+@@ -10,7 +10,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-12 18:25+0100\n"
+ "Last-Translator: Magnus Andersson <svankan@bahnhof.se>\n"
+ "Language-Team: Swedish\n"
+@@ -934,6 +934,9 @@ msgstr "Transparent f
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparent bakgrund textremsa"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/tr_TR.po b/po/tr_TR.po
+index 02a9642..73fec22 100644
+--- a/po/tr_TR.po
++++ b/po/tr_TR.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-28 00:33+0100\n"
+ "Last-Translator: Oktay Yolgeen <oktay_73@yahoo.de>\n"
+ "Language-Team: Turkish\n"
+@@ -931,6 +931,9 @@ msgstr "Altyaz
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Altyaz arka effaflk"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/uk_UA.po b/po/uk_UA.po
+index 7e3010c..37e1f64 100644
+--- a/po/uk_UA.po
++++ b/po/uk_UA.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.7.7\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2009-05-31 13:17+0200\n"
+ "Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n"
+ "Language-Team: Ukrainian\n"
+@@ -931,6 +931,9 @@ msgstr "Прозорість переднього плану субтитрів"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Прозорість заднього плану субтитрів"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "Конвертер"
+
+diff --git a/po/zh_CN.po b/po/zh_CN.po
+index 1d12f71..2969540 100644
+--- a/po/zh_CN.po
++++ b/po/zh_CN.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2009-09-23 23:50+0800\n"
+ "Last-Translator: Nan Feng <nfgx@21cn.com>\n"
+ "Language-Team: Chinese\n"
+@@ -934,6 +934,9 @@ msgstr "字幕前景透明度"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "字幕背景透明度"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "切换器设置"
+
+diff --git a/receiver.c b/receiver.c
+index dab95b3..4403410 100644
+--- a/receiver.c
++++ b/receiver.c
+@@ -82,7 +82,8 @@ bool cReceiver::SetPids(const cChannel *Channel)
+ (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) &&
+ AddPids(Channel->Apids()) &&
+ (!Setup.UseDolbyDigital || AddPids(Channel->Dpids())) &&
+- AddPids(Channel->Spids()) && AddPid(Channel->Tpid());
++ AddPids(Channel->Spids()) &&
++ (!Setup.RecordTtxtSubtitles || AddPid(Channel->Tpid()));
+ }
+ return true;
+ }
+--
+1.6.5
+
diff --git a/patches/patch-set/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch b/patches/patch-set/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch
new file mode 100644
index 0000000..249185a
--- /dev/null
+++ b/patches/patch-set/0003-Allow-manual-configuration-of-teletetxt-subtitle-pag.patch
@@ -0,0 +1,137 @@
+From f33ffd78393792ba23c4ee48b3543e182663dc97 Mon Sep 17 00:00:00 2001
+From: etobi <git@e-tobi.net>
+Date: Fri, 12 Feb 2010 21:56:41 +0100
+Subject: [PATCH 3/5] Allow manual configuration of teletetxt subtitle pages in channels.conf
+
+---
+ channels.c | 49 +++++++++++++++++++++++++++++++++++++++++++++----
+ channels.h | 1 +
+ vdr.5 | 7 +++++++
+ 3 files changed, 53 insertions(+), 4 deletions(-)
+
+diff --git a/channels.c b/channels.c
+index 817b7d3..aaaea30 100644
+--- a/channels.c
++++ b/channels.c
+@@ -553,7 +553,7 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos
+
+ void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[])
+ {
+- for (int i = 0; i < MAXTXTPAGES; i++)
++ for (int i = fixedTeletextSubtitlePages; i < MAXTXTPAGES; i++)
+ teletextSubtitlePages[i] = pages[i];
+ teletextSubtitlePages[MAXTXTPAGES].ttxtType = 0;
+ }
+@@ -765,11 +765,22 @@ cString cChannel::ToText(const cChannel *Channel)
+ q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs);
+ }
+ *q = 0;
++ const int TBufferSize = 5 + 1 + (MAXTXTPAGES * (3 + 1 + MAXLANGCODE1 + 1)) + 10; // '12345;150=deu,151=fin,...', +10: paranoia
++ char tpidbuf[TBufferSize];
++ q = tpidbuf;
++ q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid);
++ if (Channel->fixedTeletextSubtitlePages > 0) {
++ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), ";");
++ for (int i = 0; i < Channel->fixedTeletextSubtitlePages; ++i) {
++ tTeletextSubtitlePage page = Channel->teletextSubtitlePages[i];
++ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), "%d=%s", page.PageNumber(), page.ttxtLanguage);
++ }
++ }
+ char caidbuf[MAXCAIDS * 5 + 10]; // 5: 4 digits plus delimiting ',', 10: paranoia
+ q = caidbuf;
+ q += IntArrayToString(q, Channel->caids, 16);
+ *q = 0;
+- buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
++ buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%s:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, tpidbuf, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
+ }
+ return buffer;
+ }
+@@ -803,8 +814,9 @@ bool cChannel::Parse(const char *s)
+ char *parambuf = NULL;
+ char *vpidbuf = NULL;
+ char *apidbuf = NULL;
++ char *tpidbuf = NULL;
+ char *caidbuf = NULL;
+- int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, &parambuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid);
++ int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%a[^:]:%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, &parambuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpidbuf, &caidbuf, &sid, &nid, &tid, &rid);
+ if (fields >= 9) {
+ if (fields == 9) {
+ // allow reading of old format
+@@ -886,7 +898,35 @@ bool cChannel::Parse(const char *s)
+ }
+ dpids[NumDpids] = 0;
+ }
+-
++ if (tpidbuf) {
++ char *p;
++ fixedTeletextSubtitlePages = 0;
++ // 2001;150=deu,151=fin
++ if ((p = strchr(tpidbuf, ';')) != NULL) {
++ char *q, *strtok_next;
++ *p++ = 0;
++ while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
++ if (fixedTeletextSubtitlePages < MAXTXTPAGES) {
++ int page;
++ char *l = strchr(q, '=');
++ if (l)
++ *l++ = 0;
++ if (sscanf(q, "%d", &page) == 1) {
++ teletextSubtitlePages[fixedTeletextSubtitlePages++] = tTeletextSubtitlePage(page);
++ strn0cpy(teletextSubtitlePages[fixedTeletextSubtitlePages].ttxtLanguage, l ? l : "und", MAXLANGCODE1);
++ }
++ 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;
++ }
++ teletextSubtitlePages[fixedTeletextSubtitlePages].ttxtType = 0; // end of list
++ }
++ if (sscanf(tpidbuf, "%d", &tpid) != 1)
++ return false;
++ }
+ if (caidbuf) {
+ char *p = caidbuf;
+ char *q;
+@@ -923,6 +963,7 @@ bool cChannel::Parse(const char *s)
+ free(sourcebuf);
+ free(vpidbuf);
+ free(apidbuf);
++ free(tpidbuf);
+ free(caidbuf);
+ free(namebuf);
+ if (!GetChannelID().Valid()) {
+diff --git a/channels.h b/channels.h
+index 18ed7c6..1ddef40 100644
+--- a/channels.h
++++ b/channels.h
+@@ -144,6 +144,7 @@ private:
+ uint16_t compositionPageIds[MAXSPIDS];
+ uint16_t ancillaryPageIds[MAXSPIDS];
+ int tpid;
++ int fixedTeletextSubtitlePages;
+ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES + 1]; // list is termintated by ttxtType=0
+ int caids[MAXCAIDS + 1]; // list is zero-terminated
+ int nid;
+diff --git a/vdr.5 b/vdr.5
+index 4b2cb90..c7da844 100644
+--- a/vdr.5
++++ b/vdr.5
+@@ -207,6 +207,13 @@ can be indicated by adding a second language code, delimited by a '+' sign, as i
+ .TP
+ .B TPID
+ The teletext PID.
++
++Fixed teletext subtitling pages can be defined separated by a semicolon.
++The pages (separated by commas) can contain ISO 639 language codes, delimited
++by a '=' sign, as in
++
++.B ...:2001;150=deu,151=fin:...
++
+ .TP
+ .B Conditional access
+ A hexadecimal integer defining how this channel can be accessed:
+--
+1.6.5
+
diff --git a/patches/patch-set/0004-Capture-teletext-subtitle-pages-from-PMT.patch b/patches/patch-set/0004-Capture-teletext-subtitle-pages-from-PMT.patch
new file mode 100644
index 0000000..4424838
--- /dev/null
+++ b/patches/patch-set/0004-Capture-teletext-subtitle-pages-from-PMT.patch
@@ -0,0 +1,104 @@
+From a0823f9a5d13174c8942a4c7dff52e0270ad483e Mon Sep 17 00:00:00 2001
+From: etobi <git@e-tobi.net>
+Date: Fri, 12 Feb 2010 22:06:19 +0100
+Subject: [PATCH 4/5] Capture teletext subtitle pages from PMT
+
+---
+ remux.c | 26 ++++++++++++++++++++++++++
+ remux.h | 6 ++++++
+ 2 files changed, 32 insertions(+), 0 deletions(-)
+
+diff --git a/remux.c b/remux.c
+index 869b6e4..24fcbd3 100644
+--- a/remux.c
++++ b/remux.c
+@@ -431,6 +431,7 @@ void cPatPmtParser::Reset(void)
+ pmtPid = -1;
+ vpid = vtype = 0;
+ ppid = 0;
++ tpid = 0;
+ }
+
+ void cPatPmtParser::ParsePat(const uchar *Data, int Length)
+@@ -514,8 +515,10 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
+ int NumApids = 0;
+ int NumDpids = 0;
+ int NumSpids = 0;
++ int NumTPages = 0;
+ vpid = vtype = 0;
+ ppid = 0;
++ tpid = 0;
+ apids[0] = 0;
+ dpids[0] = 0;
+ spids[0] = 0;
+@@ -614,6 +617,29 @@ 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 (NumTPages < 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[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1);
++ teletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber();
++ teletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber();
++ teletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType();
++ NumTPages++;
++ if (NumTPages >= MAXTXTPAGES)
++ break;
++ }
++ }
++ teletextSubtitlePages[NumTPages].ttxtType = 0; // indicates end of list
++ }
++ }
++ break;
+ case SI::ISO639LanguageDescriptorTag: {
+ SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
+ dbgpatpmt(" '%s'", ld->languageCode);
+diff --git a/remux.h b/remux.h
+index cef50d7..43809fc 100644
+--- a/remux.h
++++ b/remux.h
+@@ -216,6 +216,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];
+@@ -228,6 +229,7 @@ private:
+ uint16_t compositionPageIds[MAXSPIDS];
+ uint16_t ancillaryPageIds[MAXSPIDS];
+ bool updatePrimaryDevice;
++ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES + 1]; // list is zero-terminated
+ protected:
+ int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; }
+ public:
+@@ -260,6 +262,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; }
+@@ -274,6 +279,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.6.5
+
diff --git a/patches/patch-set/0005-Ttxtsubs-plugin-hook.patch b/patches/patch-set/0005-Ttxtsubs-plugin-hook.patch
new file mode 100644
index 0000000..b338345
--- /dev/null
+++ b/patches/patch-set/0005-Ttxtsubs-plugin-hook.patch
@@ -0,0 +1,244 @@
+From 122be8fa91973f031586fdd2026585cb0510e19f Mon Sep 17 00:00:00 2001
+From: etobi <git@e-tobi.net>
+Date: Sat, 13 Feb 2010 00:28:21 +0100
+Subject: [PATCH 5/5] Ttxtsubs plugin hook
+
+---
+ Makefile | 2 +
+ device.c | 20 ++++++++++++++++
+ device.h | 1 +
+ pat.c | 9 +++++++
+ vdrttxtsubshooks.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ vdrttxtsubshooks.h | 46 ++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 141 insertions(+), 0 deletions(-)
+ create mode 100644 vdrttxtsubshooks.c
+ create mode 100644 vdrttxtsubshooks.h
+
+diff --git a/Makefile b/Makefile
+index 01408cb..b280030 100644
+--- a/Makefile
++++ b/Makefile
+@@ -43,6 +43,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d
+ skinclassic.o skins.o skinsttng.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
++
+ ifndef NO_KBD
+ DEFINES += -DREMOTE_KBD
+ endif
+diff --git a/device.c b/device.c
+index cb31b83..86b6b2c 100644
+--- a/device.c
++++ b/device.c
+@@ -18,6 +18,7 @@
+ #include "receiver.h"
+ #include "status.h"
+ #include "transfer.h"
++#include "vdrttxtsubshooks.h"
+
+ // --- cLiveSubtitle ---------------------------------------------------------
+
+@@ -1190,6 +1191,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:
+@@ -1349,6 +1357,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);
+@@ -1394,6 +1403,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());
++ tsToPesTeletext.Reset();
++ }
++ }
++ }
+ }
+ }
+ else if (Pid == patPmtParser.Ppid()) {
+diff --git a/device.h b/device.h
+index 897de2a..2e36351 100644
+--- a/device.h
++++ b/device.h
+@@ -499,6 +499,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 f4be6a6..444be21 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
+
+@@ -473,6 +474,14 @@ 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, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
++ if (NumTPages < MAXTXTPAGES) {
++ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel);
++ if (manualPageNumber) {
++ TeletextSubtitlePages[NumTPages] = tTeletextSubtitlePage(manualPageNumber);
++ strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, "und", MAXLANGCODE1);
++ NumTPages++;
++ }
++ }
+ Channel->SetTeletextSubtitlePages(TeletextSubtitlePages);
+ Channel->SetCaIds(CaDescriptors->CaIds());
+ Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
+diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c
+new file mode 100644
+index 0000000..865596e
+--- /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 <ragge@nada.kth.se>
++ *
++ * 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 <stdlib.h>
++#include <stdio.h>
++#include <stdint.h>
++
++#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)
++ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording, teletextSubtitlePages); };
++ 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..2e8e9ba
+--- /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 <ragge@nada.kth.se>
++ *
++ * 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) {};
++ virtual int ManualPageNumber(const cChannel *channel) { return 0; };
++
++ // used by VDR to call hook listeners
++ static cVDRTtxtsubsHookListener *Hook(void);
++};
++
++#endif
+--
+1.6.5
+
diff --git a/patches/vdr-1.7.12-ttxtsubs-tpid-v2.patch b/patches/vdr-1.7.12-ttxtsubs-tpid-v2.patch
deleted file mode 100644
index 5080fd4..0000000
--- a/patches/vdr-1.7.12-ttxtsubs-tpid-v2.patch
+++ /dev/null
@@ -1,516 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 01408cb..b280030 100644
---- a/Makefile
-+++ b/Makefile
-@@ -43,6 +43,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d
- skinclassic.o skins.o skinsttng.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
-+
- ifndef NO_KBD
- DEFINES += -DREMOTE_KBD
- endif
-diff --git a/channels.c b/channels.c
-index c14df19..1759238 100644
---- a/channels.c
-+++ b/channels.c
-@@ -551,6 +551,15 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos
- }
- }
-
-+void cChannel::SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[])
-+{
-+ for (int i = manualtpages; i < MAXTPAGES; i++) {
-+ tpages[i] = TPages[i];
-+ strn0cpy(tlangs[i], TLangs[i], MAXLANGCODE2);
-+ }
-+ tpages[MAXTPAGES] = 0;
-+}
-+
- void cChannel::SetCaIds(const int *CaIds)
- {
- if (caids[0] && caids[0] <= CA_USER_MAX)
-@@ -758,11 +767,20 @@ cString cChannel::ToText(const cChannel *Channel)
- q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs);
- }
- *q = 0;
-+ const int TBufferSize = 5 + 1 + (MAXTPAGES * (MAXLANGCODE2 + 5 + 1)) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia
-+ char tpidbuf[TBufferSize];
-+ q = tpidbuf;
-+ q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid);
-+ if (Channel->manualtpages > 0) {
-+ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), ";");
-+ for (int i = 0; i < Channel->manualtpages; ++i)
-+ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), "%d%s%s", Channel->tpages[i], *Channel->tlangs[i] ? "=" : "", *Channel->tlangs[i] ? Channel->tlangs[i] : "");
-+ }
- char caidbuf[MAXCAIDS * 5 + 10]; // 5: 4 digits plus delimiting ',', 10: paranoia
- q = caidbuf;
- q += IntArrayToString(q, Channel->caids, 16);
- *q = 0;
-- buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
-+ buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%s:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, tpidbuf, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
- }
- return buffer;
- }
-@@ -796,8 +814,9 @@ bool cChannel::Parse(const char *s)
- char *parambuf = NULL;
- char *vpidbuf = NULL;
- char *apidbuf = NULL;
-+ char *tpidbuf = NULL;
- char *caidbuf = NULL;
-- int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, &parambuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid);
-+ int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%a[^:]:%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, &parambuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpidbuf, &caidbuf, &sid, &nid, &tid, &rid);
- if (fields >= 9) {
- if (fields == 9) {
- // allow reading of old format
-@@ -879,7 +898,35 @@ bool cChannel::Parse(const char *s)
- }
- dpids[NumDpids] = 0;
- }
--
-+ if (tpidbuf) {
-+ char *p;
-+ manualtpages = 0;
-+ // 2001;150=deu,151=fin
-+ if ((p = strchr(tpidbuf, ';')) != NULL) {
-+ char *q, *strtok_next;
-+ *p++ = 0;
-+ while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
-+ if (manualtpages < MAXTPAGES) {
-+ int page;
-+ char *l = strchr(q, '=');
-+ if (l) {
-+ *l++ = 0;
-+ strn0cpy(tlangs[manualtpages], l, MAXLANGCODE2);
-+ }
-+ if (sscanf(q, "%d", &page) == 1)
-+ tpages[manualtpages++] = (page & 0xFF) | (0x02 << 16); // set subtitling type
-+ 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;
-+ }
-+ tpages[manualtpages] = 0;
-+ }
-+ if (sscanf(tpidbuf, "%d", &tpid) != 1)
-+ return false;
-+ }
- if (caidbuf) {
- char *p = caidbuf;
- char *q;
-@@ -916,6 +963,7 @@ bool cChannel::Parse(const char *s)
- free(sourcebuf);
- free(vpidbuf);
- free(apidbuf);
-+ free(tpidbuf);
- free(caidbuf);
- free(namebuf);
- if (!GetChannelID().Valid()) {
-diff --git a/channels.h b/channels.h
-index b465f6a..69f0340 100644
---- a/channels.h
-+++ b/channels.h
-@@ -35,6 +35,7 @@
- #define MAXDPIDS 16 // dolby (AC3 + DTS)
- #define MAXSPIDS 32 // subtitles
- #define MAXCAIDS 8 // conditional access
-+#define MAXTPAGES 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
-@@ -133,6 +134,9 @@ private:
- uint16_t compositionPageIds[MAXSPIDS];
- uint16_t ancillaryPageIds[MAXSPIDS];
- int tpid;
-+ int manualtpages;
-+ char tlangs[MAXTPAGES][MAXLANGCODE2];
-+ int tpages[MAXTPAGES + 1]; // list is zero-terminated
- int caids[MAXCAIDS + 1]; // list is zero-terminated
- int nid;
- int tid;
-@@ -192,6 +196,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 char *Tlang(int i) const { return (0 <= i && i < MAXTPAGES) ? tlangs[i] : ""; }
-+ const int TPages(int i) const { return (0 <= i && i < MAXTPAGES) ? tpages[i] : 0; }
- 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; }
-@@ -228,6 +234,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, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
-+ void SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[]);
- void SetCaIds(const int *CaIds); // list must be zero-terminated
- void SetCaDescriptors(int Level);
- void SetLinkChannels(cLinkChannels *LinkChannels);
-diff --git a/device.c b/device.c
-index cb31b83..c05de91 100644
---- a/device.c
-+++ b/device.c
-@@ -18,6 +18,7 @@
- #include "receiver.h"
- #include "status.h"
- #include "transfer.h"
-+#include "vdrttxtsubshooks.h"
-
- // --- cLiveSubtitle ---------------------------------------------------------
-
-@@ -1190,6 +1191,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:
-@@ -1349,6 +1357,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);
-@@ -1394,6 +1403,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);
-+ tsToPesTeletext.Reset();
-+ }
-+ }
-+ }
- }
- }
- else if (Pid == patPmtParser.Ppid()) {
-diff --git a/device.h b/device.h
-index 897de2a..2e36351 100644
---- a/device.h
-+++ b/device.h
-@@ -499,6 +499,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 9b3ded6..c687ca6 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
-
-@@ -341,6 +342,9 @@ 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;
-+ char TLangs[MAXTPAGES][MAXLANGCODE2] = { "" };
-+ int TPages[MAXTPAGES + 1] = { 0 };
-+ int NumTPages = 0;
- int NumApids = 0;
- int NumDpids = 0;
- int NumSpids = 0;
-@@ -426,8 +430,19 @@ 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); ) {
-+ if ((NumTPages < MAXTPAGES) && ttxt.languageCode[0] && ((ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05))) {
-+ char *s = TLangs[NumTPages];
-+ strn0cpy(s, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1);
-+ TPages[NumTPages] = (ttxt.getTeletextPageNumber() & 0xff) | ((ttxt.getTeletextMagazineNumber() & 0xff) << 8) | ((ttxt.getTeletextType() & 0xff) << 16);
-+ NumTPages++;
-+ }
-+ }
-+ }
- break;
- case SI::ISO639LanguageDescriptorTag: {
- SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
-@@ -458,6 +473,16 @@ 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, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
-+ if (NumTPages < MAXTPAGES) {
-+ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel);
-+ if (manualPageNumber) {
-+ char *s = TLangs[NumTPages];
-+ strn0cpy(s, "man", MAXLANGCODE1);
-+ TPages[NumTPages] = manualPageNumber;
-+ NumTPages++;
-+ }
-+ }
-+ Channel->SetTPidData(TLangs, TPages);
- Channel->SetCaIds(CaDescriptors->CaIds());
- Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
- }
-diff --git a/receiver.c b/receiver.c
-index f922e98..dab95b3 100644
---- a/receiver.c
-+++ b/receiver.c
-@@ -82,7 +82,7 @@ bool cReceiver::SetPids(const cChannel *Channel)
- (Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) &&
- AddPids(Channel->Apids()) &&
- (!Setup.UseDolbyDigital || AddPids(Channel->Dpids())) &&
-- AddPids(Channel->Spids());
-+ AddPids(Channel->Spids()) && AddPid(Channel->Tpid());
- }
- return true;
- }
-diff --git a/remux.c b/remux.c
-index 070a06a..55604a8 100644
---- a/remux.c
-+++ b/remux.c
-@@ -215,6 +215,30 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua
- return i;
- }
-
-+int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, const cChannel *Channel)
-+{
-+ int i = 0, j = 0;
-+ Target[i++] = SI::TeletextDescriptorTag;
-+ int l = i;
-+ Target[i++] = 0x00; // length
-+ for (int n = 0; Channel->TPages(n); n++) {
-+ const char *Language = Channel->Tlang(n);
-+ int Pages = Channel->TPages(n);
-+ Target[i++] = *Language++;
-+ Target[i++] = *Language++;
-+ Target[i++] = *Language++;
-+ Target[i++] = ((Pages >> 13) & 0xf8) | ((Pages >> 8) & 0x7); // teletext type & magazine number
-+ Target[i++] = Pages & 0xff; // teletext page number
-+ 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;
-@@ -296,6 +320,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
-@@ -330,6 +355,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);
-+ }
-
- int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC
- buf[SectionLength] |= (sl >> 8) & 0x0F;
-@@ -403,6 +432,7 @@ void cPatPmtParser::Reset(void)
- pmtPid = -1;
- vpid = vtype = 0;
- ppid = 0;
-+ tpid = 0;
- }
-
- void cPatPmtParser::ParsePat(const uchar *Data, int Length)
-@@ -488,6 +518,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;
-@@ -586,6 +617,10 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
- spids[NumSpids]= 0;
- }
- break;
-+ case SI::TeletextDescriptorTag:
-+ dbgpatpmt(" teletext");
-+ tpid = stream.getPid();
-+ break;
- case SI::ISO639LanguageDescriptorTag: {
- SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
- dbgpatpmt(" '%s'", ld->languageCode);
-diff --git a/remux.h b/remux.h
-index 1115c4a..5d9af66 100644
---- a/remux.h
-+++ b/remux.h
-@@ -170,6 +170,7 @@ protected:
- int MakeStream(uchar *Target, uchar Type, int Pid);
- int MakeAC3Descriptor(uchar *Target);
- int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId);
-+ int MakeTeletextDescriptor(uchar *Target, const cChannel *Channel);
- int MakeLanguageDescriptor(uchar *Target, const char *Language);
- int MakeCRC(uchar *Target, const uchar *Data, int Length);
- void GeneratePmtPid(const cChannel *Channel);
-@@ -215,6 +216,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];
-@@ -259,6 +261,7 @@ 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; }
- const int *Apids(void) const { return apids; }
- const int *Dpids(void) const { return dpids; }
- const int *Spids(void) const { return spids; }
-diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c
-new file mode 100644
-index 0000000..4151552
---- /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 <ragge@nada.kth.se>
-+ *
-+ * 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 <stdlib.h>
-+#include <stdio.h>
-+#include <stdint.h>
-+
-+#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)
-+ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording); };
-+ 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..89d4b78
---- /dev/null
-+++ b/vdrttxtsubshooks.h
-@@ -0,0 +1,45 @@
-+/*
-+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder
-+ * Copyright (c) 2003 - 2008 Ragnar Sundblad <ragge@nada.kth.se>
-+ *
-+ * 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 1
-+
-+class cDevice;
-+class cChannel;
-+
-+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) {};
-+ 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.12-ttxtsubs.patch b/patches/vdr-1.7.12-ttxtsubs.patch
index 870c92e..fb85ffb 100644
--- a/patches/vdr-1.7.12-ttxtsubs.patch
+++ b/patches/vdr-1.7.12-ttxtsubs.patch
@@ -1,62 +1,226 @@
-diff -Nru vdr-1.7.12-vanilla/channels.c vdr-1.7.12-ttxtsubs/channels.c
---- vdr-1.7.12-vanilla/channels.c 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/channels.c 2010-02-03 09:21:21.000000000 +0200
-@@ -551,6 +551,15 @@
+diff --git a/MANUAL b/MANUAL
+index 405f6a8..d1ce1f9 100644
+--- a/MANUAL
++++ b/MANUAL
+@@ -721,6 +721,9 @@ Version 1.6
+ background transparency. By default the values as broadcast
+ are used.
+
++ Record Teletext Subtitles = no
++ If set to 'yes', teletext subtitles will be recorded.
++
+ LNB:
+
+ SLOF = 11700 The switching frequency (in MHz) between low and
+diff --git a/Makefile b/Makefile
+index 01408cb..b280030 100644
+--- a/Makefile
++++ b/Makefile
+@@ -43,6 +43,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d
+ skinclassic.o skins.o skinsttng.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
++
+ ifndef NO_KBD
+ DEFINES += -DREMOTE_KBD
+ endif
+diff --git a/channels.c b/channels.c
+index c14df19..aaaea30 100644
+--- a/channels.c
++++ b/channels.c
+@@ -551,6 +551,13 @@ void cChannel::SetSubtitlingDescriptors(uchar *SubtitlingTypes, uint16_t *Compos
}
}
-+void cChannel::SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[])
++void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[])
+{
-+ for (int i = 0; i < MAXTPAGES; i++) {
-+ tpages[i] = TPages[i];
-+ strn0cpy(tlangs[i], TLangs[i], MAXLANGCODE2);
-+ }
-+ tpages[MAXTPAGES] = 0;
++ for (int i = fixedTeletextSubtitlePages; i < MAXTXTPAGES; i++)
++ teletextSubtitlePages[i] = pages[i];
++ teletextSubtitlePages[MAXTXTPAGES].ttxtType = 0;
+}
+
void cChannel::SetCaIds(const int *CaIds)
{
if (caids[0] && caids[0] <= CA_USER_MAX)
-diff -Nru vdr-1.7.12-vanilla/channels.h vdr-1.7.12-ttxtsubs/channels.h
---- vdr-1.7.12-vanilla/channels.h 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/channels.h 2010-02-03 09:21:21.000000000 +0200
+@@ -758,11 +765,22 @@ cString cChannel::ToText(const cChannel *Channel)
+ q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs);
+ }
+ *q = 0;
++ const int TBufferSize = 5 + 1 + (MAXTXTPAGES * (3 + 1 + MAXLANGCODE1 + 1)) + 10; // '12345;150=deu,151=fin,...', +10: paranoia
++ char tpidbuf[TBufferSize];
++ q = tpidbuf;
++ q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid);
++ if (Channel->fixedTeletextSubtitlePages > 0) {
++ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), ";");
++ for (int i = 0; i < Channel->fixedTeletextSubtitlePages; ++i) {
++ tTeletextSubtitlePage page = Channel->teletextSubtitlePages[i];
++ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), "%d=%s", page.PageNumber(), page.ttxtLanguage);
++ }
++ }
+ char caidbuf[MAXCAIDS * 5 + 10]; // 5: 4 digits plus delimiting ',', 10: paranoia
+ q = caidbuf;
+ q += IntArrayToString(q, Channel->caids, 16);
+ *q = 0;
+- buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
++ buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%s:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->ParametersToString(), *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, tpidbuf, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
+ }
+ return buffer;
+ }
+@@ -796,8 +814,9 @@ bool cChannel::Parse(const char *s)
+ char *parambuf = NULL;
+ char *vpidbuf = NULL;
+ char *apidbuf = NULL;
++ char *tpidbuf = NULL;
+ char *caidbuf = NULL;
+- int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, &parambuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid);
++ int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%a[^:]:%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, &parambuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpidbuf, &caidbuf, &sid, &nid, &tid, &rid);
+ if (fields >= 9) {
+ if (fields == 9) {
+ // allow reading of old format
+@@ -879,7 +898,35 @@ bool cChannel::Parse(const char *s)
+ }
+ dpids[NumDpids] = 0;
+ }
+-
++ if (tpidbuf) {
++ char *p;
++ fixedTeletextSubtitlePages = 0;
++ // 2001;150=deu,151=fin
++ if ((p = strchr(tpidbuf, ';')) != NULL) {
++ char *q, *strtok_next;
++ *p++ = 0;
++ while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
++ if (fixedTeletextSubtitlePages < MAXTXTPAGES) {
++ int page;
++ char *l = strchr(q, '=');
++ if (l)
++ *l++ = 0;
++ if (sscanf(q, "%d", &page) == 1) {
++ teletextSubtitlePages[fixedTeletextSubtitlePages++] = tTeletextSubtitlePage(page);
++ strn0cpy(teletextSubtitlePages[fixedTeletextSubtitlePages].ttxtLanguage, l ? l : "und", MAXLANGCODE1);
++ }
++ 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;
++ }
++ teletextSubtitlePages[fixedTeletextSubtitlePages].ttxtType = 0; // end of list
++ }
++ if (sscanf(tpidbuf, "%d", &tpid) != 1)
++ return false;
++ }
+ if (caidbuf) {
+ char *p = caidbuf;
+ char *q;
+@@ -916,6 +963,7 @@ bool cChannel::Parse(const char *s)
+ free(sourcebuf);
+ free(vpidbuf);
+ free(apidbuf);
++ free(tpidbuf);
+ free(caidbuf);
+ free(namebuf);
+ if (!GetChannelID().Valid()) {
+diff --git a/channels.h b/channels.h
+index b465f6a..1ddef40 100644
+--- a/channels.h
++++ b/channels.h
@@ -35,6 +35,7 @@
#define MAXDPIDS 16 // dolby (AC3 + DTS)
#define MAXSPIDS 32 // subtitles
#define MAXCAIDS 8 // conditional access
-+#define MAXTPAGES 8 // teletext pages
++#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
-@@ -133,6 +134,8 @@
+@@ -92,6 +93,16 @@ public:
+ static const tChannelID InvalidID;
+ };
+
++struct tTeletextSubtitlePage {
++ tTeletextSubtitlePage(void) { ttxtPage = ttxtMagazine = ttxtType = ttxtLanguage[0] = 0; }
++ tTeletextSubtitlePage(int page) { ttxtMagazine = (page / 100) & 0x7; ttxtPage = (((page % 100) / 10) << 4) + (page % 10); ttxtType = 0x02; }
++ 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 {
+@@ -133,6 +144,8 @@ private:
uint16_t compositionPageIds[MAXSPIDS];
uint16_t ancillaryPageIds[MAXSPIDS];
int tpid;
-+ char tlangs[MAXTPAGES][MAXLANGCODE2];
-+ int tpages[MAXTPAGES + 1]; // list is zero-terminated
++ int fixedTeletextSubtitlePages;
++ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES + 1]; // list is termintated by ttxtType=0
int caids[MAXCAIDS + 1]; // list is zero-terminated
int nid;
int tid;
-@@ -192,6 +195,8 @@
+@@ -192,6 +205,7 @@ 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 char *Tlang(int i) const { return (0 <= i && i < MAXTPAGES) ? tlangs[i] : ""; }
-+ const int TPages(int i) const { return (0 <= i && i < MAXTPAGES) ? tpages[i] : 0; }
++ const tTeletextSubtitlePage TeletextSubtitlePage(int i) const { return (0 <= i && i < MAXTXTPAGES) ? teletextSubtitlePages[i] : tTeletextSubtitlePage(); };
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; }
-@@ -228,6 +233,7 @@
+@@ -228,6 +242,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, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
-+ void SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[]);
++ void SetTeletextSubtitlePages(tTeletextSubtitlePage pages[]);
void SetCaIds(const int *CaIds); // list must be zero-terminated
void SetCaDescriptors(int Level);
void SetLinkChannels(cLinkChannels *LinkChannels);
-diff -Nru vdr-1.7.12-vanilla/device.c vdr-1.7.12-ttxtsubs/device.c
---- vdr-1.7.12-vanilla/device.c 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/device.c 2010-02-03 09:21:21.000000000 +0200
+diff --git a/config.c b/config.c
+index acdf4c4..4aaf720 100644
+--- a/config.c
++++ b/config.c
+@@ -333,6 +333,7 @@ cSetup::cSetup(void)
+ MarginStop = 10;
+ AudioLanguages[0] = -1;
+ DisplaySubtitles = 0;
++ RecordTtxtSubtitles = 0;
+ SubtitleLanguages[0] = -1;
+ SubtitleOffset = 0;
+ SubtitleFgTransparency = 0;
+@@ -521,6 +522,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, "RecordTtxtSubtitles")) RecordTtxtSubtitles = 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);
+@@ -614,6 +616,7 @@ bool cSetup::Save(void)
+ Store("MarginStop", MarginStop);
+ StoreLanguages("AudioLanguages", AudioLanguages);
+ Store("DisplaySubtitles", DisplaySubtitles);
++ Store("RecordTtxtSubtitles", RecordTtxtSubtitles);
+ StoreLanguages("SubtitleLanguages", SubtitleLanguages);
+ Store("SubtitleOffset", SubtitleOffset);
+ Store("SubtitleFgTransparency", SubtitleFgTransparency);
+diff --git a/config.h b/config.h
+index be1d7bd..5dcbe20 100644
+--- a/config.h
++++ b/config.h
+@@ -235,6 +235,7 @@ public:
+ int MarginStart, MarginStop;
+ int AudioLanguages[I18N_MAX_LANGUAGES + 1];
+ int DisplaySubtitles;
++ int RecordTtxtSubtitles;
+ int SubtitleLanguages[I18N_MAX_LANGUAGES + 1];
+ int SubtitleOffset;
+ int SubtitleFgTransparency, SubtitleBgTransparency;
+diff --git a/device.c b/device.c
+index cb31b83..86b6b2c 100644
+--- a/device.c
++++ b/device.c
@@ -18,6 +18,7 @@
#include "receiver.h"
#include "status.h"
@@ -65,7 +229,7 @@ diff -Nru vdr-1.7.12-vanilla/device.c vdr-1.7.12-ttxtsubs/device.c
// --- cLiveSubtitle ---------------------------------------------------------
-@@ -1190,6 +1191,13 @@
+@@ -1190,6 +1191,13 @@ int cDevice::PlayPesPacket(const uchar *Data, int Length, bool VideoOnly)
}
break;
case 0xBD: { // private stream 1
@@ -79,7 +243,7 @@ diff -Nru vdr-1.7.12-vanilla/device.c vdr-1.7.12-ttxtsubs/device.c
int PayloadOffset = Data[8] + 9;
// Compatibility mode for old subtitles plugin:
-@@ -1349,6 +1357,7 @@
+@@ -1349,6 +1357,7 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
tsToPesVideo.Reset();
tsToPesAudio.Reset();
tsToPesSubtitle.Reset();
@@ -87,7 +251,7 @@ diff -Nru vdr-1.7.12-vanilla/device.c vdr-1.7.12-ttxtsubs/device.c
}
else if (Length < TS_SIZE) {
esyslog("ERROR: skipped %d bytes of TS fragment", Length);
-@@ -1394,6 +1403,17 @@
+@@ -1394,6 +1403,17 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly)
if (!VideoOnly || HasIBPTrickSpeed())
PlayTsSubtitle(Data, TS_SIZE);
}
@@ -97,7 +261,7 @@ diff -Nru vdr-1.7.12-vanilla/device.c vdr-1.7.12-ttxtsubs/device.c
+ 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);
++ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData((uchar *)p, l, false, patPmtParser.TeletextSubtitlePages());
+ tsToPesTeletext.Reset();
+ }
+ }
@@ -105,10 +269,11 @@ diff -Nru vdr-1.7.12-vanilla/device.c vdr-1.7.12-ttxtsubs/device.c
}
}
else if (Pid == patPmtParser.Ppid()) {
-diff -Nru vdr-1.7.12-vanilla/device.h vdr-1.7.12-ttxtsubs/device.h
---- vdr-1.7.12-vanilla/device.h 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/device.h 2010-02-03 09:21:21.000000000 +0200
-@@ -499,6 +499,7 @@
+diff --git a/device.h b/device.h
+index 897de2a..2e36351 100644
+--- a/device.h
++++ b/device.h
+@@ -499,6 +499,7 @@ private:
cTsToPes tsToPesVideo;
cTsToPes tsToPesAudio;
cTsToPes tsToPesSubtitle;
@@ -116,21 +281,22 @@ diff -Nru vdr-1.7.12-vanilla/device.h vdr-1.7.12-ttxtsubs/device.h
bool isPlayingVideo;
protected:
const cPatPmtParser *PatPmtParser(void) const { return &patPmtParser; }
-diff -Nru vdr-1.7.12-vanilla/Makefile vdr-1.7.12-ttxtsubs/Makefile
---- vdr-1.7.12-vanilla/Makefile 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/Makefile 2010-02-03 09:21:21.000000000 +0200
-@@ -43,6 +43,8 @@
- skinclassic.o skins.o skinsttng.o sources.o spu.o status.o svdrp.o themes.o thread.o\
- timers.o tools.o transfer.o vdr.o videodir.o
+diff --git a/menu.c b/menu.c
+index 7ddf0cf..1f49f3d 100644
+--- a/menu.c
++++ b/menu.c
+@@ -2790,6 +2790,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$Record Teletext Subtitles"), &data.RecordTtxtSubtitles));
-+OBJS += vdrttxtsubshooks.o
-+
- ifndef NO_KBD
- DEFINES += -DREMOTE_KBD
- endif
-diff -Nru vdr-1.7.12-vanilla/pat.c vdr-1.7.12-ttxtsubs/pat.c
---- vdr-1.7.12-vanilla/pat.c 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/pat.c 2010-02-03 09:30:12.000000000 +0200
+ SetCurrent(Get(current));
+ Display();
+diff --git a/pat.c b/pat.c
+index 9b3ded6..444be21 100644
+--- a/pat.c
++++ b/pat.c
@@ -13,6 +13,7 @@
#include "libsi/section.h"
#include "libsi/descriptor.h"
@@ -139,17 +305,16 @@ diff -Nru vdr-1.7.12-vanilla/pat.c vdr-1.7.12-ttxtsubs/pat.c
#define PMT_SCAN_TIMEOUT 10 // seconds
-@@ -341,6 +342,9 @@
+@@ -341,6 +342,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;
-+ char TLangs[MAXTPAGES][MAXLANGCODE2] = { "" };
-+ int TPages[MAXTPAGES + 1] = { 0 };
++ tTeletextSubtitlePage TeletextSubtitlePages[MAXTXTPAGES];
+ int NumTPages = 0;
int NumApids = 0;
int NumDpids = 0;
int NumSpids = 0;
-@@ -426,8 +430,19 @@
+@@ -426,8 +429,21 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
NumSpids++;
}
break;
@@ -159,10 +324,12 @@ diff -Nru vdr-1.7.12-vanilla/pat.c vdr-1.7.12-ttxtsubs/pat.c
+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d;
+ SI::TeletextDescriptor::Teletext ttxt;
+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) {
-+ if ((NumTPages < MAXTPAGES) && ttxt.languageCode[0] && ((ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05))) {
-+ char *s = TLangs[NumTPages];
-+ strn0cpy(s, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1);
-+ TPages[NumTPages] = (ttxt.getTeletextPageNumber() & 0xff) | ((ttxt.getTeletextMagazineNumber() & 0xff) << 8) | ((ttxt.getTeletextType() & 0xff) << 16);
++ 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++;
+ }
+ }
@@ -170,39 +337,616 @@ diff -Nru vdr-1.7.12-vanilla/pat.c vdr-1.7.12-ttxtsubs/pat.c
break;
case SI::ISO639LanguageDescriptorTag: {
SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
-@@ -458,6 +473,16 @@
+@@ -458,6 +474,15 @@ 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, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
-+ if (NumTPages < MAXTPAGES) {
++ if (NumTPages < MAXTXTPAGES) {
+ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel);
+ if (manualPageNumber) {
-+ char *s = TLangs[NumTPages];
-+ strn0cpy(s, "man", MAXLANGCODE1);
-+ TPages[NumTPages] = manualPageNumber;
++ TeletextSubtitlePages[NumTPages] = tTeletextSubtitlePage(manualPageNumber);
++ strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, "und", MAXLANGCODE1);
+ NumTPages++;
+ }
+ }
-+ Channel->SetTPidData(TLangs, TPages);
++ Channel->SetTeletextSubtitlePages(TeletextSubtitlePages);
Channel->SetCaIds(CaDescriptors->CaIds());
Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
}
-diff -Nru vdr-1.7.12-vanilla/receiver.c vdr-1.7.12-ttxtsubs/receiver.c
---- vdr-1.7.12-vanilla/receiver.c 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/receiver.c 2010-02-03 09:27:31.000000000 +0200
-@@ -82,7 +82,7 @@
+diff --git a/po/ca_ES.po b/po/ca_ES.po
+index fcdf672..1197fe1 100644
+--- a/po/ca_ES.po
++++ b/po/ca_ES.po
+@@ -10,7 +10,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-02 19:02+0100\n"
+ "Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
+ "Language-Team: Catalanian\n"
+@@ -934,6 +934,9 @@ msgstr "Transpar
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparncia fons subttols"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "Configuraci de l'LNB"
+
+diff --git a/po/cs_CZ.po b/po/cs_CZ.po
+index 3bbd6eb..c15fc13 100644
+--- a/po/cs_CZ.po
++++ b/po/cs_CZ.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-28 15:00+0200\n"
+ "Last-Translator: Vladimr Brta <vladimir.barta@k2atmitec.cz>, Ji Dobr <jdobry@centrum.cz>\n"
+ "Language-Team: Czech\n"
+@@ -932,6 +932,9 @@ msgstr "Pr
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Prhlednost pozad titulk"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/da_DK.po b/po/da_DK.po
+index fbad909..3416080 100644
+--- a/po/da_DK.po
++++ b/po/da_DK.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-12 14:17+0200\n"
+ "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n"
+ "Language-Team: Danish\n"
+@@ -931,6 +931,9 @@ msgstr "Undertekst forgrundsgennemsigtighed"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Undertekst baggrundsgennemsigtighed"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/de_DE.po b/po/de_DE.po
+index ad6401b..775fd30 100644
+--- a/po/de_DE.po
++++ b/po/de_DE.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2010-01-16 16:46+0100\n"
+ "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n"
+ "Language-Team: German\n"
+@@ -931,6 +931,9 @@ msgstr "Untertitel-Transparenz Vordergrund"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Untertitel-Transparenz Hintergrund"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr "Teletext-Untertitel aufnehmen"
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/el_GR.po b/po/el_GR.po
+index e8382b8..741cb4a 100644
+--- a/po/el_GR.po
++++ b/po/el_GR.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-12 14:17+0200\n"
+ "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n"
+ "Language-Team: Greek\n"
+@@ -931,6 +931,9 @@ msgstr ""
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr ""
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/es_ES.po b/po/es_ES.po
+index d2bf5b0..0515348 100644
+--- a/po/es_ES.po
++++ b/po/es_ES.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-02 19:02+0100\n"
+ "Last-Translator: Luca Olivetti <luca@ventoso.org>\n"
+ "Language-Team: Spanish\n"
+@@ -932,6 +932,9 @@ msgstr "Transparencia primer plano subt
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparencia fondo subttulos"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/et_EE.po b/po/et_EE.po
+index 97e2aee..72a95ae 100644
+--- a/po/et_EE.po
++++ b/po/et_EE.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-12 14:17+0200\n"
+ "Last-Translator: Arthur Konovalov <artlov@gmail.com>\n"
+ "Language-Team: Estonian\n"
+@@ -931,6 +931,9 @@ msgstr "Subtiitri l
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Subtiitri tausta lbipaistvus"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/fi_FI.po b/po/fi_FI.po
+index 916b51e..372a1a2 100644
+--- a/po/fi_FI.po
++++ b/po/fi_FI.po
+@@ -10,7 +10,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-15 15:52+0200\n"
+ "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n"
+ "Language-Team: Finnish\n"
+@@ -934,6 +934,9 @@ msgstr "Tekstityksen l
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Tekstityksen taustan lpinkyvyys"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/fr_FR.po b/po/fr_FR.po
+index 4c4dcce..8ebfd3e 100644
+--- a/po/fr_FR.po
++++ b/po/fr_FR.po
+@@ -13,7 +13,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-27 18:14+0100\n"
+ "Last-Translator: Jean-Claude Repetto <jc@repetto.org>\n"
+ "Language-Team: French\n"
+@@ -937,6 +937,9 @@ msgstr "Transparence de l'avant-plan"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparence du fond"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/hr_HR.po b/po/hr_HR.po
+index b7cf5a0..d769dc1 100644
+--- a/po/hr_HR.po
++++ b/po/hr_HR.po
+@@ -9,7 +9,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-17 19:00+0100\n"
+ "Last-Translator: Adrian Caval <anrxc@sysphere.org>\n"
+ "Language-Team: Croatian\n"
+@@ -933,6 +933,9 @@ msgstr "Transparentnost titla"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparentnost pozadine titla"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/hu_HU.po b/po/hu_HU.po
+index d09c8dd..e2b9364 100644
+--- a/po/hu_HU.po
++++ b/po/hu_HU.po
+@@ -10,7 +10,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-12-01 21:42+0200\n"
+ "Last-Translator: Istvn Fley <ifuley@tigercomp.ro>\n"
+ "Language-Team: Hungarian\n"
+@@ -934,6 +934,9 @@ msgstr "Felirat transzparenci
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Felirat htternek transzparencija"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/it_IT.po b/po/it_IT.po
+index 3a8f2e2..41335d8 100644
+--- a/po/it_IT.po
++++ b/po/it_IT.po
+@@ -11,7 +11,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2010-01-12 23:53+0100\n"
+ "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
+ "Language-Team: Italian\n"
+@@ -938,6 +938,9 @@ msgstr "Trasparenza sottotitoli"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Trasparenza sfondo sottotitoli"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/lt_LT.po b/po/lt_LT.po
+index 93583c5..2b55e82 100644
+--- a/po/lt_LT.po
++++ b/po/lt_LT.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.7.9\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2009-10-17 14:19+0200\n"
+ "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n"
+ "Language-Team: Lithuanian\n"
+@@ -931,6 +931,9 @@ msgstr "Subtitrų priekinio vaizdo permatomumas"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Subtitrų fono permatomumas"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "Konverteris (LNB)"
+
+diff --git a/po/nl_NL.po b/po/nl_NL.po
+index fdfaf8d..56523f4 100644
+--- a/po/nl_NL.po
++++ b/po/nl_NL.po
+@@ -11,7 +11,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-26 17:20+0100\n"
+ "Last-Translator: Johan Schuring <johan.schuring@vetteblei.nl>\n"
+ "Language-Team: Dutch\n"
+@@ -935,6 +935,9 @@ msgstr "Transparantie voorgrond ondertiteling"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparantie achtergrond ondertiteling"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/nn_NO.po b/po/nn_NO.po
+index 1f50117..3e492ad 100644
+--- a/po/nn_NO.po
++++ b/po/nn_NO.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2007-08-12 14:17+0200\n"
+ "Last-Translator: Truls Slevigen <truls@slevigen.no>\n"
+ "Language-Team: Norwegian\n"
+@@ -932,6 +932,9 @@ msgstr ""
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr ""
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/pl_PL.po b/po/pl_PL.po
+index 038d058..e99d90e 100644
+--- a/po/pl_PL.po
++++ b/po/pl_PL.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-09 12:59+0100\n"
+ "Last-Translator: Michael Rakowski <mrak@gmx.de>\n"
+ "Language-Team: Polish\n"
+@@ -932,6 +932,9 @@ msgstr "Prze
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Przerocze podtytuw: To"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/pt_PT.po b/po/pt_PT.po
+index e409581..f795bae 100644
+--- a/po/pt_PT.po
++++ b/po/pt_PT.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-18 17:04+0100\n"
+ "Last-Translator: anonymous\n"
+ "Language-Team: Portuguese\n"
+@@ -931,6 +931,9 @@ msgstr "Transpar
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparncia de background das legendas"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/ro_RO.po b/po/ro_RO.po
+index f52a7d8..c857472 100644
+--- a/po/ro_RO.po
++++ b/po/ro_RO.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-25 00:39+0100\n"
+ "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n"
+ "Language-Team: Romanian\n"
+@@ -934,6 +934,9 @@ msgstr "Transparen
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparena fundalului subtitrrii"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/ru_RU.po b/po/ru_RU.po
+index c6d6aca..e55f00d 100644
+--- a/po/ru_RU.po
++++ b/po/ru_RU.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-12-15 14:37+0100\n"
+ "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n"
+ "Language-Team: Russian\n"
+@@ -932,6 +932,9 @@ msgstr "
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr " "
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr ""
+
+diff --git a/po/sk_SK.po b/po/sk_SK.po
+index c66132a..44b0833 100644
+--- a/po/sk_SK.po
++++ b/po/sk_SK.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2009-09-30 12:50+0100\n"
+ "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
+ "Language-Team: Slovak\n"
+@@ -932,6 +932,9 @@ msgstr "Prieh
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Priehadnos pozadia titulkov"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/sl_SI.po b/po/sl_SI.po
+index 2c20440..2bd42ea 100644
+--- a/po/sl_SI.po
++++ b/po/sl_SI.po
+@@ -8,7 +8,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-28 19:44+0100\n"
+ "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n"
+ "Language-Team: Slovenian\n"
+@@ -932,6 +932,9 @@ msgstr "Transparentnost podnapisov"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparentnost ozadja podnapisov"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/sv_SE.po b/po/sv_SE.po
+index 4ac9a0f..1cceb44 100644
+--- a/po/sv_SE.po
++++ b/po/sv_SE.po
+@@ -10,7 +10,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-03-12 18:25+0100\n"
+ "Last-Translator: Magnus Andersson <svankan@bahnhof.se>\n"
+ "Language-Team: Swedish\n"
+@@ -934,6 +934,9 @@ msgstr "Transparent f
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Transparent bakgrund textremsa"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/tr_TR.po b/po/tr_TR.po
+index 02a9642..73fec22 100644
+--- a/po/tr_TR.po
++++ b/po/tr_TR.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2008-02-28 00:33+0100\n"
+ "Last-Translator: Oktay Yolgeen <oktay_73@yahoo.de>\n"
+ "Language-Team: Turkish\n"
+@@ -931,6 +931,9 @@ msgstr "Altyaz
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Altyaz arka effaflk"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "LNB"
+
+diff --git a/po/uk_UA.po b/po/uk_UA.po
+index 7e3010c..37e1f64 100644
+--- a/po/uk_UA.po
++++ b/po/uk_UA.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.7.7\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2009-05-31 13:17+0200\n"
+ "Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n"
+ "Language-Team: Ukrainian\n"
+@@ -931,6 +931,9 @@ msgstr "Прозорість переднього плану субтитрів"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "Прозорість заднього плану субтитрів"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "Конвертер"
+
+diff --git a/po/zh_CN.po b/po/zh_CN.po
+index 1d12f71..2969540 100644
+--- a/po/zh_CN.po
++++ b/po/zh_CN.po
+@@ -7,7 +7,7 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: VDR 1.6.0\n"
+ "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n"
+-"POT-Creation-Date: 2010-01-17 16:18+0100\n"
++"POT-Creation-Date: 2010-02-13 14:31+0100\n"
+ "PO-Revision-Date: 2009-09-23 23:50+0800\n"
+ "Last-Translator: Nan Feng <nfgx@21cn.com>\n"
+ "Language-Team: Chinese\n"
+@@ -934,6 +934,9 @@ msgstr "字幕前景透明度"
+ msgid "Setup.DVB$Subtitle background transparency"
+ msgstr "字幕背景透明度"
+
++msgid "Setup.DVB$Record Teletext Subtitles"
++msgstr ""
++
+ msgid "LNB"
+ msgstr "切换器设置"
+
+diff --git a/receiver.c b/receiver.c
+index f922e98..4403410 100644
+--- a/receiver.c
++++ b/receiver.c
+@@ -82,7 +82,8 @@ bool cReceiver::SetPids(const cChannel *Channel)
(Channel->Ppid() == Channel->Vpid() || AddPid(Channel->Ppid())) &&
AddPids(Channel->Apids()) &&
(!Setup.UseDolbyDigital || AddPids(Channel->Dpids())) &&
- AddPids(Channel->Spids());
-+ AddPids(Channel->Spids()) && AddPid(Channel->Tpid());
++ AddPids(Channel->Spids()) &&
++ (!Setup.RecordTtxtSubtitles || AddPid(Channel->Tpid()));
}
return true;
}
-diff -Nru vdr-1.7.12-vanilla/remux.c vdr-1.7.12-ttxtsubs/remux.c
---- vdr-1.7.12-vanilla/remux.c 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/remux.c 2010-02-03 09:28:25.000000000 +0200
-@@ -215,6 +215,30 @@
+diff --git a/remux.c b/remux.c
+index 070a06a..24fcbd3 100644
+--- a/remux.c
++++ b/remux.c
+@@ -215,6 +215,29 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua
return i;
}
@@ -212,14 +956,13 @@ diff -Nru vdr-1.7.12-vanilla/remux.c vdr-1.7.12-ttxtsubs/remux.c
+ Target[i++] = SI::TeletextDescriptorTag;
+ int l = i;
+ Target[i++] = 0x00; // length
-+ for (int n = 0; Channel->TPages(n); n++) {
-+ const char *Language = Channel->Tlang(n);
-+ int Pages = Channel->TPages(n);
++ for (int n = 0; Channel->TeletextSubtitlePage(n).ttxtType; n++) {
++ const char* Language = Channel->TeletextSubtitlePage(n).ttxtLanguage;
+ Target[i++] = *Language++;
+ Target[i++] = *Language++;
+ Target[i++] = *Language++;
-+ Target[i++] = ((Pages >> 13) & 0xf8) | ((Pages >> 8) & 0x7); // teletext type & magazine number
-+ Target[i++] = Pages & 0xff; // teletext page number
++ Target[i++] = (Channel->TeletextSubtitlePage(n).ttxtType << 3) + Channel->TeletextSubtitlePage(n).ttxtMagazine;
++ Target[i++] = Channel->TeletextSubtitlePage(n).ttxtPage;
+ j++;
+ }
+ if (j > 0) {
@@ -233,7 +976,7 @@ diff -Nru vdr-1.7.12-vanilla/remux.c vdr-1.7.12-ttxtsubs/remux.c
int cPatPmtGenerator::MakeLanguageDescriptor(uchar *Target, const char *Language)
{
int i = 0;
-@@ -296,6 +320,7 @@
+@@ -296,6 +319,7 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel)
if (Channel) {
int Vpid = Channel->Vpid();
int Ppid = Channel->Ppid();
@@ -241,7 +984,7 @@ diff -Nru vdr-1.7.12-vanilla/remux.c vdr-1.7.12-ttxtsubs/remux.c
uchar *p = buf;
int i = 0;
p[i++] = 0x02; // table id
-@@ -330,6 +355,10 @@
+@@ -330,6 +354,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));
}
@@ -252,7 +995,7 @@ diff -Nru vdr-1.7.12-vanilla/remux.c vdr-1.7.12-ttxtsubs/remux.c
int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC
buf[SectionLength] |= (sl >> 8) & 0x0F;
-@@ -403,6 +432,7 @@
+@@ -403,6 +431,7 @@ void cPatPmtParser::Reset(void)
pmtPid = -1;
vpid = vtype = 0;
ppid = 0;
@@ -260,29 +1003,52 @@ diff -Nru vdr-1.7.12-vanilla/remux.c vdr-1.7.12-ttxtsubs/remux.c
}
void cPatPmtParser::ParsePat(const uchar *Data, int Length)
-@@ -488,6 +518,7 @@
+@@ -486,8 +515,10 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
+ int NumApids = 0;
+ int NumDpids = 0;
int NumSpids = 0;
++ int NumTPages = 0;
vpid = vtype = 0;
ppid = 0;
+ tpid = 0;
apids[0] = 0;
dpids[0] = 0;
spids[0] = 0;
-@@ -586,6 +617,10 @@
+@@ -586,6 +617,29 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
spids[NumSpids]= 0;
}
break;
-+ case SI::TeletextDescriptorTag:
++ case SI::TeletextDescriptorTag: {
+ dbgpatpmt(" teletext");
+ tpid = stream.getPid();
++ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d;
++ SI::TeletextDescriptor::Teletext ttxt;
++ if (NumTPages < 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[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1);
++ teletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber();
++ teletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber();
++ teletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType();
++ NumTPages++;
++ if (NumTPages >= MAXTXTPAGES)
++ break;
++ }
++ }
++ teletextSubtitlePages[NumTPages].ttxtType = 0; // indicates end of list
++ }
++ }
+ break;
case SI::ISO639LanguageDescriptorTag: {
SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
dbgpatpmt(" '%s'", ld->languageCode);
-diff -Nru vdr-1.7.12-vanilla/remux.h vdr-1.7.12-ttxtsubs/remux.h
---- vdr-1.7.12-vanilla/remux.h 2010-01-31 16:56:52.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/remux.h 2010-02-03 09:29:15.000000000 +0200
-@@ -170,6 +170,7 @@
+diff --git a/remux.h b/remux.h
+index 1115c4a..43809fc 100644
+--- a/remux.h
++++ b/remux.h
+@@ -170,6 +170,7 @@ protected:
int MakeStream(uchar *Target, uchar Type, int Pid);
int MakeAC3Descriptor(uchar *Target);
int MakeSubtitlingDescriptor(uchar *Target, const char *Language, uchar SubtitlingType, uint16_t CompositionPageId, uint16_t AncillaryPageId);
@@ -290,7 +1056,7 @@ diff -Nru vdr-1.7.12-vanilla/remux.h vdr-1.7.12-ttxtsubs/remux.h
int MakeLanguageDescriptor(uchar *Target, const char *Language);
int MakeCRC(uchar *Target, const uchar *Data, int Length);
void GeneratePmtPid(const cChannel *Channel);
-@@ -215,6 +216,7 @@
+@@ -215,6 +216,7 @@ private:
int vpid;
int ppid;
int vtype;
@@ -298,17 +1064,55 @@ diff -Nru vdr-1.7.12-vanilla/remux.h vdr-1.7.12-ttxtsubs/remux.h
int apids[MAXAPIDS + 1]; // list is zero-terminated
int atypes[MAXAPIDS + 1]; // list is zero-terminated
char alangs[MAXAPIDS][MAXLANGCODE2];
-@@ -259,6 +261,7 @@
+@@ -227,6 +229,7 @@ private:
+ uint16_t compositionPageIds[MAXSPIDS];
+ uint16_t ancillaryPageIds[MAXSPIDS];
+ bool updatePrimaryDevice;
++ tTeletextSubtitlePage teletextSubtitlePages[MAXTXTPAGES + 1]; // list is zero-terminated
+ protected:
+ int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; }
+ public:
+@@ -259,6 +262,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; }
-diff -Nru vdr-1.7.12-vanilla/vdrttxtsubshooks.c vdr-1.7.12-ttxtsubs/vdrttxtsubshooks.c
---- vdr-1.7.12-vanilla/vdrttxtsubshooks.c 1970-01-01 02:00:00.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/vdrttxtsubshooks.c 2010-02-03 09:21:22.000000000 +0200
+@@ -273,6 +279,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:
+diff --git a/vdr.5 b/vdr.5
+index 4b2cb90..c7da844 100644
+--- a/vdr.5
++++ b/vdr.5
+@@ -207,6 +207,13 @@ can be indicated by adding a second language code, delimited by a '+' sign, as i
+ .TP
+ .B TPID
+ The teletext PID.
++
++Fixed teletext subtitling pages can be defined separated by a semicolon.
++The pages (separated by commas) can contain ISO 639 language codes, delimited
++by a '=' sign, as in
++
++.B ...:2001;150=deu,151=fin:...
++
+ .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..865596e
+--- /dev/null
++++ b/vdrttxtsubshooks.c
@@ -0,0 +1,63 @@
+/*
+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder
@@ -346,8 +1150,8 @@ diff -Nru vdr-1.7.12-vanilla/vdrttxtsubshooks.c vdr-1.7.12-ttxtsubs/vdrttxtsubsh
+ 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)
-+ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording); };
++ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL)
++ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording, teletextSubtitlePages); };
+ virtual int ManualPageNumber(const cChannel *channel)
+ { if(gListener) return gListener->ManualPageNumber(channel); else return 0; };
+};
@@ -373,10 +1177,12 @@ diff -Nru vdr-1.7.12-vanilla/vdrttxtsubshooks.c vdr-1.7.12-ttxtsubs/vdrttxtsubsh
+ return &gProxy;
+}
+
-diff -Nru vdr-1.7.12-vanilla/vdrttxtsubshooks.h vdr-1.7.12-ttxtsubs/vdrttxtsubshooks.h
---- vdr-1.7.12-vanilla/vdrttxtsubshooks.h 1970-01-01 02:00:00.000000000 +0200
-+++ vdr-1.7.12-ttxtsubs/vdrttxtsubshooks.h 2010-02-03 09:33:22.000000000 +0200
-@@ -0,0 +1,45 @@
+diff --git a/vdrttxtsubshooks.h b/vdrttxtsubshooks.h
+new file mode 100644
+index 0000000..2e8e9ba
+--- /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 <ragge@nada.kth.se>
@@ -400,10 +1206,11 @@ diff -Nru vdr-1.7.12-vanilla/vdrttxtsubshooks.h vdr-1.7.12-ttxtsubs/vdrttxtsubsh
+#ifndef __VDRTTXTSUBSHOOKS_H
+#define __VDRTTXTSUBSHOOKS_H
+
-+#define TTXTSUBSVERSNUM 1
++#define TTXTSUBSVERSNUM 2
+
+class cDevice;
+class cChannel;
++struct tTeletextSubtitlePage;
+
+class cVDRTtxtsubsHookListener {
+ public:
@@ -414,7 +1221,7 @@ diff -Nru vdr-1.7.12-vanilla/vdrttxtsubshooks.h vdr-1.7.12-ttxtsubs/vdrttxtsubsh
+
+ virtual void HideOSD(void) {};
+ virtual void ShowOSD(void) {};
-+ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording = true) {};
++ virtual void PlayerTeletextData(uint8_t *p, int length, bool IsPesRecording = true, const struct tTeletextSubtitlePage teletextSubtitlePages[] = NULL) {};
+ virtual int ManualPageNumber(const cChannel *channel) { return 0; };
+
+ // used by VDR to call hook listeners
diff --git a/patches/vdr-1.7.6-ttxtsubs.patch b/patches/vdr-1.7.6-ttxtsubs.patch
deleted file mode 100644
index 3209514..0000000
--- a/patches/vdr-1.7.6-ttxtsubs.patch
+++ /dev/null
@@ -1,510 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 74a6833..d8f43de 100644
---- a/Makefile
-+++ b/Makefile
-@@ -43,6 +43,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d
- skinclassic.o skins.o skinsttng.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
-+
- ifndef NO_KBD
- DEFINES += -DREMOTE_KBD
- endif
-diff --git a/channels.c b/channels.c
-index 1e85700..fb5bd84 100644
---- a/channels.c
-+++ b/channels.c
-@@ -533,6 +533,15 @@ void cChannel::SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][
- }
- }
-
-+void cChannel::SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[])
-+{
-+ for (int i = 0; i < MAXTPAGES; i++) {
-+ tpages[i] = TPages[i];
-+ strn0cpy(tlangs[i], TLangs[i], MAXLANGCODE2);
-+ }
-+ tpages[MAXTPAGES] = 0;
-+}
-+
- void cChannel::SetCaIds(const int *CaIds)
- {
- if (caids[0] && caids[0] <= CA_USER_MAX)
-diff --git a/channels.h b/channels.h
-index a3c1d43..d4b6c97 100644
---- a/channels.h
-+++ b/channels.h
-@@ -35,6 +35,7 @@
- #define MAXDPIDS 16 // dolby (AC3 + DTS)
- #define MAXSPIDS 32 // subtitles
- #define MAXCAIDS 8 // conditional access
-+#define MAXTPAGES 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
-@@ -130,6 +131,8 @@ private:
- int spids[MAXSPIDS + 1]; // list is zero-terminated
- char slangs[MAXSPIDS][MAXLANGCODE2];
- int tpid;
-+ char tlangs[MAXTPAGES][MAXLANGCODE2];
-+ int tpages[MAXTPAGES + 1]; // list is zero-terminated
- int caids[MAXCAIDS + 1]; // list is zero-terminated
- int nid;
- int tid;
-@@ -186,6 +189,8 @@ public:
- const char *Dlang(int i) const { return (0 <= i && i < MAXDPIDS) ? dlangs[i] : ""; }
- const char *Slang(int i) const { return (0 <= i && i < MAXSPIDS) ? slangs[i] : ""; }
- int Tpid(void) const { return tpid; }
-+ const char *Tlang(int i) const { return (0 <= i && i < MAXTPAGES) ? tlangs[i] : ""; }
-+ const int TPages(int i) const { return (0 <= i && i < MAXTPAGES) ? tpages[i] : 0; }
- 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; }
-@@ -222,6 +227,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, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
-+ void SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[]);
- void SetCaIds(const int *CaIds); // list must be zero-terminated
- void SetCaDescriptors(int Level);
- void SetLinkChannels(cLinkChannels *LinkChannels);
-diff --git a/device.c b/device.c
-index 6121620..9359f84 100644
---- a/device.c
-+++ b/device.c
-@@ -18,6 +18,7 @@
- #include "receiver.h"
- #include "status.h"
- #include "transfer.h"
-+#include "vdrttxtsubshooks.h"
-
- // --- cLiveSubtitle ---------------------------------------------------------
-
-@@ -1167,6 +1168,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:
-@@ -1322,6 +1330,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);
-@@ -1367,6 +1376,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);
-+ tsToPesTeletext.Reset();
-+ }
-+ }
-+ }
- }
- }
- Played += TS_SIZE;
-diff --git a/device.h b/device.h
-index c3a170b..4fa7e5f 100644
---- a/device.h
-+++ b/device.h
-@@ -477,6 +477,7 @@ private:
- cTsToPes tsToPesVideo;
- cTsToPes tsToPesAudio;
- cTsToPes tsToPesSubtitle;
-+ cTsToPes tsToPesTeletext;
- bool isPlayingVideo;
- protected:
- virtual bool CanReplay(void) const;
-diff --git a/menu.c b/menu.c
-index fa60065..476ebb9 100644
---- a/menu.c
-+++ b/menu.c
-@@ -3755,7 +3755,8 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
- isyslog("record %s", fileName);
- if (MakeDirs(fileName, true)) {
- const cChannel *ch = timer->Channel();
-- recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids());
-+ int TPid[2] = { ch->Tpid(), 0 };
-+ recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids(), TPid);
- if (device->AttachReceiver(recorder)) {
- Recording.WriteInfo();
- cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true);
-diff --git a/pat.c b/pat.c
-index 5285784..2848822 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
-
-@@ -337,6 +338,9 @@ 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;
-+ char TLangs[MAXTPAGES][MAXLANGCODE2] = { "" };
-+ int TPages[MAXTPAGES + 1] = { 0 };
-+ int NumTPages = 0;
- int NumApids = 0;
- int NumDpids = 0;
- int NumSpids = 0;
-@@ -414,8 +418,19 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
- NumSpids++;
- }
- break;
-- case SI::TeletextDescriptorTag:
-+ case SI::TeletextDescriptorTag: {
- Tpid = stream.getPid();
-+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d;
-+ SI::TeletextDescriptor::Teletext ttxt;
-+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) {
-+ if ((NumTPages < MAXTPAGES) && ttxt.languageCode[0] && ((ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05))) {
-+ char *s = TLangs[NumTPages];
-+ strn0cpy(s, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1);
-+ TPages[NumTPages] = (ttxt.getTeletextPageNumber() & 0xff) | ((ttxt.getTeletextMagazineNumber() & 0xff) << 8) | ((ttxt.getTeletextType() & 0xff) << 16);
-+ NumTPages++;
-+ }
-+ }
-+ }
- break;
- case SI::ISO639LanguageDescriptorTag: {
- SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
-@@ -444,6 +459,16 @@ 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, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
-+ if (NumTPages < MAXTPAGES) {
-+ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel);
-+ if (manualPageNumber) {
-+ char *s = TLangs[NumTPages];
-+ strn0cpy(s, "man", MAXLANGCODE1);
-+ TPages[NumTPages] = manualPageNumber;
-+ NumTPages++;
-+ }
-+ }
-+ Channel->SetTPidData(TLangs, TPages);
- Channel->SetCaIds(CaDescriptors->CaIds());
- }
- Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors));
-diff --git a/receiver.c b/receiver.c
-index f4c0a78..c19bd84 100644
---- a/receiver.c
-+++ b/receiver.c
-@@ -12,7 +12,7 @@
- #include <stdio.h>
- #include "tools.h"
-
--cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3)
-+cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3, const int *Pids4)
- {
- device = NULL;
- channelID = ChannelID;
-@@ -32,6 +32,10 @@ cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pid
- while (*Pids3 && numPids < MAXRECEIVEPIDS)
- pids[numPids++] = *Pids3++;
- }
-+ if (Pids4) {
-+ while (*Pids4 && numPids < MAXRECEIVEPIDS)
-+ pids[numPids++] = *Pids4++;
-+ }
- if (numPids >= MAXRECEIVEPIDS)
- dsyslog("too many PIDs in cReceiver");
- }
-diff --git a/receiver.h b/receiver.h
-index 35930d2..97d2b0f 100644
---- a/receiver.h
-+++ b/receiver.h
-@@ -38,10 +38,10 @@ protected:
- ///< will be delivered only ONCE, so the cReceiver must make sure that
- ///< it will be able to buffer the data if necessary.
- public:
-- cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL);
-+ cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL, const int *Pids4 = NULL);
- ///< Creates a new receiver for the channel with the given ChannelID with
- ///< the given Priority. Pid is a single PID (typically the video PID), while
-- ///< Pids1...Pids3 are pointers to zero terminated lists of PIDs.
-+ ///< Pids1...Pids4 are pointers to zero terminated lists of PIDs.
- ///< If any of these PIDs are 0, they will be silently ignored.
- ///< The total number of non-zero PIDs must not exceed MAXRECEIVEPIDS.
- ///< Priority may be any value in the range -99..99. Negative values indicate
-diff --git a/recorder.c b/recorder.c
-index d8f22ce..5857989 100644
---- a/recorder.c
-+++ b/recorder.c
-@@ -21,8 +21,8 @@
-
- // --- cRecorder -------------------------------------------------------------
-
--cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids)
--:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids)
-+cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, const int *EPids)
-+:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, EPids)
- ,cThread("recording")
- ,recordingInfo(FileName)
- {
-diff --git a/recorder.h b/recorder.h
-index 40a3222..6929e6f 100644
---- a/recorder.h
-+++ b/recorder.h
-@@ -34,7 +34,7 @@ protected:
- virtual void Receive(uchar *Data, int Length);
- virtual void Action(void);
- public:
-- cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids);
-+ cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, const int *EPids = NULL);
- // Creates a new recorder for the channel with the given ChannelID and
- // the given Priority that will record the given PIDs into the file FileName.
- virtual ~cRecorder();
-diff --git a/remux.c b/remux.c
-index 10e5145..96d51b7 100644
---- a/remux.c
-+++ b/remux.c
-@@ -215,6 +215,30 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua
- return i;
- }
-
-+int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, cChannel *Channel)
-+{
-+ int i = 0, j = 0;
-+ Target[i++] = SI::TeletextDescriptorTag;
-+ int l = i;
-+ Target[i++] = 0x00; // length
-+ for (int n = 0; Channel->TPages(n); n++) {
-+ const char *Language = Channel->Tlang(n);
-+ int Pages = Channel->TPages(n);
-+ Target[i++] = *Language++;
-+ Target[i++] = *Language++;
-+ Target[i++] = *Language++;
-+ Target[i++] = ((Pages >> 13) & 0xf8) | ((Pages >> 8) & 0x7); // teletext type & magazine number
-+ Target[i++] = Pages & 0xff; // teletext page number
-+ 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;
-@@ -295,6 +319,7 @@ void cPatPmtGenerator::GeneratePmt(cChannel *Channel)
- numPmtPackets = 0;
- if (Channel) {
- int Vpid = Channel->Vpid();
-+ int Tpid = Channel->Tpid();
- uchar *p = buf;
- int i = 0;
- p[i++] = 0x02; // table id
-@@ -329,6 +354,10 @@ void cPatPmtGenerator::GeneratePmt(cChannel *Channel)
- i += MakeStream(buf + i, 0x06, Channel->Spid(n));
- i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n));
- }
-+ if (Tpid) {
-+ i += MakeStream(buf + i, 0x06, Tpid);
-+ i += MakeTeletextDescriptor(buf + i, Channel);
-+ }
-
- int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC
- buf[SectionLength] |= (sl >> 8) & 0x0F;
-@@ -394,6 +423,7 @@ void cPatPmtParser::Reset(void)
- patVersion = pmtVersion = -1;
- pmtPid = -1;
- vpid = vtype = 0;
-+ tpid = 0;
- }
-
- void cPatPmtParser::ParsePat(const uchar *Data, int Length)
-@@ -477,6 +507,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
- int NumDpids = 0;
- int NumSpids = 0;
- vpid = vtype = 0;
-+ tpid = 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());
-@@ -554,6 +585,10 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
- NumSpids++;
- }
- break;
-+ case SI::TeletextDescriptorTag:
-+ dbgpatpmt(" teletext");
-+ tpid = stream.getPid();
-+ break;
- case SI::ISO639LanguageDescriptorTag: {
- SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
- dbgpatpmt(" '%s'", ld->languageCode);
-diff --git a/remux.h b/remux.h
-index 063acaa..c1437d3 100644
---- a/remux.h
-+++ b/remux.h
-@@ -169,6 +169,7 @@ protected:
- int MakeStream(uchar *Target, uchar Type, int Pid);
- int MakeAC3Descriptor(uchar *Target);
- int MakeSubtitlingDescriptor(uchar *Target, const char *Language);
-+ int MakeTeletextDescriptor(uchar *Target, cChannel *Channel);
- int MakeLanguageDescriptor(uchar *Target, const char *Language);
- int MakeCRC(uchar *Target, const uchar *Data, int Length);
- void GeneratePmtPid(cChannel *Channel);
-@@ -204,6 +205,7 @@ private:
- int pmtPid;
- int vpid;
- int vtype;
-+ int tpid;
- protected:
- int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; }
- public:
-@@ -227,6 +229,7 @@ public:
- int Vpid(void) { return vpid; }
- ///< Returns the video pid as defined by the current PMT.
- int Vtype(void) { return vtype; }
-+ int Tpid(void) { return tpid; }
- };
-
- // TS to PES converter:
-diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c
-new file mode 100644
-index 0000000..4151552
---- /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 <ragge@nada.kth.se>
-+ *
-+ * 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 <stdlib.h>
-+#include <stdio.h>
-+#include <stdint.h>
-+
-+#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)
-+ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording); };
-+ 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..a962980
---- /dev/null
-+++ b/vdrttxtsubshooks.h
-@@ -0,0 +1,48 @@
-+/*
-+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder
-+ * Copyright (c) 2003 - 2008 Ragnar Sundblad <ragge@nada.kth.se>
-+ *
-+ * 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 1
-+
-+class cDevice;
-+class cChannel;
-+
-+#define VDRTTXTSUBSHOOKS
-+
-+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) {};
-+ 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.8-ttxtsubs.patch b/patches/vdr-1.7.8-ttxtsubs.patch
deleted file mode 100644
index abde5c3..0000000
--- a/patches/vdr-1.7.8-ttxtsubs.patch
+++ /dev/null
@@ -1,510 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 74a6833..d8f43de 100644
---- a/Makefile
-+++ b/Makefile
-@@ -43,6 +43,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d
- skinclassic.o skins.o skinsttng.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
-+
- ifndef NO_KBD
- DEFINES += -DREMOTE_KBD
- endif
-diff --git a/channels.c b/channels.c
-index 1e85700..fb5bd84 100644
---- a/channels.c
-+++ b/channels.c
-@@ -533,6 +533,15 @@ void cChannel::SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][
- }
- }
-
-+void cChannel::SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[])
-+{
-+ for (int i = 0; i < MAXTPAGES; i++) {
-+ tpages[i] = TPages[i];
-+ strn0cpy(tlangs[i], TLangs[i], MAXLANGCODE2);
-+ }
-+ tpages[MAXTPAGES] = 0;
-+}
-+
- void cChannel::SetCaIds(const int *CaIds)
- {
- if (caids[0] && caids[0] <= CA_USER_MAX)
-diff --git a/channels.h b/channels.h
-index a3c1d43..d4b6c97 100644
---- a/channels.h
-+++ b/channels.h
-@@ -35,6 +35,7 @@
- #define MAXDPIDS 16 // dolby (AC3 + DTS)
- #define MAXSPIDS 32 // subtitles
- #define MAXCAIDS 8 // conditional access
-+#define MAXTPAGES 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
-@@ -130,6 +131,8 @@ private:
- int spids[MAXSPIDS + 1]; // list is zero-terminated
- char slangs[MAXSPIDS][MAXLANGCODE2];
- int tpid;
-+ char tlangs[MAXTPAGES][MAXLANGCODE2];
-+ int tpages[MAXTPAGES + 1]; // list is zero-terminated
- int caids[MAXCAIDS + 1]; // list is zero-terminated
- int nid;
- int tid;
-@@ -186,6 +189,8 @@ public:
- const char *Dlang(int i) const { return (0 <= i && i < MAXDPIDS) ? dlangs[i] : ""; }
- const char *Slang(int i) const { return (0 <= i && i < MAXSPIDS) ? slangs[i] : ""; }
- int Tpid(void) const { return tpid; }
-+ const char *Tlang(int i) const { return (0 <= i && i < MAXTPAGES) ? tlangs[i] : ""; }
-+ const int TPages(int i) const { return (0 <= i && i < MAXTPAGES) ? tpages[i] : 0; }
- 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; }
-@@ -222,6 +227,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, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
-+ void SetTPidData(char TLangs[][MAXLANGCODE2], int TPages[]);
- void SetCaIds(const int *CaIds); // list must be zero-terminated
- void SetCaDescriptors(int Level);
- void SetLinkChannels(cLinkChannels *LinkChannels);
-diff --git a/device.c b/device.c
-index 834b6ea..fa8dbac 100644
---- a/device.c
-+++ b/device.c
-@@ -18,6 +18,7 @@
- #include "receiver.h"
- #include "status.h"
- #include "transfer.h"
-+#include "vdrttxtsubshooks.h"
-
- // --- cLiveSubtitle ---------------------------------------------------------
-
-@@ -1182,6 +1183,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:
-@@ -1337,6 +1345,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);
-@@ -1382,6 +1391,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);
-+ tsToPesTeletext.Reset();
-+ }
-+ }
-+ }
- }
- }
- Played += TS_SIZE;
-diff --git a/device.h b/device.h
-index 8ac8594..b4b27ce 100644
---- a/device.h
-+++ b/device.h
-@@ -496,6 +496,7 @@ private:
- cTsToPes tsToPesVideo;
- cTsToPes tsToPesAudio;
- cTsToPes tsToPesSubtitle;
-+ cTsToPes tsToPesTeletext;
- bool isPlayingVideo;
- protected:
- virtual bool CanReplay(void) const;
-diff --git a/menu.c b/menu.c
-index cd1b30a..b4fca96 100644
---- a/menu.c
-+++ b/menu.c
-@@ -3755,7 +3755,8 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
- isyslog("record %s", fileName);
- if (MakeDirs(fileName, true)) {
- const cChannel *ch = timer->Channel();
-- recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids());
-+ int TPid[2] = { ch->Tpid(), 0 };
-+ recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids(), TPid);
- if (device->AttachReceiver(recorder)) {
- Recording.WriteInfo();
- cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true);
-diff --git a/pat.c b/pat.c
-index 5285784..2848822 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
-
-@@ -337,6 +338,9 @@ 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;
-+ char TLangs[MAXTPAGES][MAXLANGCODE2] = { "" };
-+ int TPages[MAXTPAGES + 1] = { 0 };
-+ int NumTPages = 0;
- int NumApids = 0;
- int NumDpids = 0;
- int NumSpids = 0;
-@@ -414,8 +418,19 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
- NumSpids++;
- }
- break;
-- case SI::TeletextDescriptorTag:
-+ case SI::TeletextDescriptorTag: {
- Tpid = stream.getPid();
-+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d;
-+ SI::TeletextDescriptor::Teletext ttxt;
-+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) {
-+ if ((NumTPages < MAXTPAGES) && ttxt.languageCode[0] && ((ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05))) {
-+ char *s = TLangs[NumTPages];
-+ strn0cpy(s, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1);
-+ TPages[NumTPages] = (ttxt.getTeletextPageNumber() & 0xff) | ((ttxt.getTeletextMagazineNumber() & 0xff) << 8) | ((ttxt.getTeletextType() & 0xff) << 16);
-+ NumTPages++;
-+ }
-+ }
-+ }
- break;
- case SI::ISO639LanguageDescriptorTag: {
- SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
-@@ -444,6 +459,16 @@ 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, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
-+ if (NumTPages < MAXTPAGES) {
-+ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel);
-+ if (manualPageNumber) {
-+ char *s = TLangs[NumTPages];
-+ strn0cpy(s, "man", MAXLANGCODE1);
-+ TPages[NumTPages] = manualPageNumber;
-+ NumTPages++;
-+ }
-+ }
-+ Channel->SetTPidData(TLangs, TPages);
- Channel->SetCaIds(CaDescriptors->CaIds());
- }
- Channel->SetCaDescriptors(CaDescriptorHandler.AddCaDescriptors(CaDescriptors));
-diff --git a/receiver.c b/receiver.c
-index f4c0a78..c19bd84 100644
---- a/receiver.c
-+++ b/receiver.c
-@@ -12,7 +12,7 @@
- #include <stdio.h>
- #include "tools.h"
-
--cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3)
-+cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1, const int *Pids2, const int *Pids3, const int *Pids4)
- {
- device = NULL;
- channelID = ChannelID;
-@@ -32,6 +32,10 @@ cReceiver::cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pid
- while (*Pids3 && numPids < MAXRECEIVEPIDS)
- pids[numPids++] = *Pids3++;
- }
-+ if (Pids4) {
-+ while (*Pids4 && numPids < MAXRECEIVEPIDS)
-+ pids[numPids++] = *Pids4++;
-+ }
- if (numPids >= MAXRECEIVEPIDS)
- dsyslog("too many PIDs in cReceiver");
- }
-diff --git a/receiver.h b/receiver.h
-index 35930d2..97d2b0f 100644
---- a/receiver.h
-+++ b/receiver.h
-@@ -38,10 +38,10 @@ protected:
- ///< will be delivered only ONCE, so the cReceiver must make sure that
- ///< it will be able to buffer the data if necessary.
- public:
-- cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL);
-+ cReceiver(tChannelID ChannelID, int Priority, int Pid, const int *Pids1 = NULL, const int *Pids2 = NULL, const int *Pids3 = NULL, const int *Pids4 = NULL);
- ///< Creates a new receiver for the channel with the given ChannelID with
- ///< the given Priority. Pid is a single PID (typically the video PID), while
-- ///< Pids1...Pids3 are pointers to zero terminated lists of PIDs.
-+ ///< Pids1...Pids4 are pointers to zero terminated lists of PIDs.
- ///< If any of these PIDs are 0, they will be silently ignored.
- ///< The total number of non-zero PIDs must not exceed MAXRECEIVEPIDS.
- ///< Priority may be any value in the range -99..99. Negative values indicate
-diff --git a/recorder.c b/recorder.c
-index 4e48a51..decc9e3 100644
---- a/recorder.c
-+++ b/recorder.c
-@@ -21,8 +21,8 @@
-
- // --- cRecorder -------------------------------------------------------------
-
--cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids)
--:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids)
-+cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, const int *EPids)
-+:cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, EPids)
- ,cThread("recording")
- ,recordingInfo(FileName)
- {
-diff --git a/recorder.h b/recorder.h
-index 40a3222..6929e6f 100644
---- a/recorder.h
-+++ b/recorder.h
-@@ -34,7 +34,7 @@ protected:
- virtual void Receive(uchar *Data, int Length);
- virtual void Action(void);
- public:
-- cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids);
-+ cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, const int *EPids = NULL);
- // Creates a new recorder for the channel with the given ChannelID and
- // the given Priority that will record the given PIDs into the file FileName.
- virtual ~cRecorder();
-diff --git a/remux.c b/remux.c
-index 97c139c..84fe17b 100644
---- a/remux.c
-+++ b/remux.c
-@@ -215,6 +215,30 @@ int cPatPmtGenerator::MakeSubtitlingDescriptor(uchar *Target, const char *Langua
- return i;
- }
-
-+int cPatPmtGenerator::MakeTeletextDescriptor(uchar *Target, cChannel *Channel)
-+{
-+ int i = 0, j = 0;
-+ Target[i++] = SI::TeletextDescriptorTag;
-+ int l = i;
-+ Target[i++] = 0x00; // length
-+ for (int n = 0; Channel->TPages(n); n++) {
-+ const char *Language = Channel->Tlang(n);
-+ int Pages = Channel->TPages(n);
-+ Target[i++] = *Language++;
-+ Target[i++] = *Language++;
-+ Target[i++] = *Language++;
-+ Target[i++] = ((Pages >> 13) & 0xf8) | ((Pages >> 8) & 0x7); // teletext type & magazine number
-+ Target[i++] = Pages & 0xff; // teletext page number
-+ 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;
-@@ -295,6 +319,7 @@ void cPatPmtGenerator::GeneratePmt(cChannel *Channel)
- numPmtPackets = 0;
- if (Channel) {
- int Vpid = Channel->Vpid();
-+ int Tpid = Channel->Tpid();
- uchar *p = buf;
- int i = 0;
- p[i++] = 0x02; // table id
-@@ -329,6 +354,10 @@ void cPatPmtGenerator::GeneratePmt(cChannel *Channel)
- i += MakeStream(buf + i, 0x06, Channel->Spid(n));
- i += MakeSubtitlingDescriptor(buf + i, Channel->Slang(n));
- }
-+ if (Tpid) {
-+ i += MakeStream(buf + i, 0x06, Tpid);
-+ i += MakeTeletextDescriptor(buf + i, Channel);
-+ }
-
- int sl = i - SectionLength - 2 + 4; // -2 = SectionLength storage, +4 = length of CRC
- buf[SectionLength] |= (sl >> 8) & 0x0F;
-@@ -401,6 +430,7 @@ void cPatPmtParser::Reset(void)
- patVersion = pmtVersion = -1;
- pmtPid = -1;
- vpid = vtype = 0;
-+ tpid = 0;
- }
-
- void cPatPmtParser::ParsePat(const uchar *Data, int Length)
-@@ -485,6 +515,7 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
- int NumDpids = 0;
- int NumSpids = 0;
- vpid = vtype = 0;
-+ tpid = 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());
-@@ -565,6 +596,10 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length)
- NumSpids++;
- }
- break;
-+ case SI::TeletextDescriptorTag:
-+ dbgpatpmt(" teletext");
-+ tpid = stream.getPid();
-+ break;
- case SI::ISO639LanguageDescriptorTag: {
- SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
- dbgpatpmt(" '%s'", ld->languageCode);
-diff --git a/remux.h b/remux.h
-index 0dd1a9a..c3c1d0a 100644
---- a/remux.h
-+++ b/remux.h
-@@ -169,6 +169,7 @@ protected:
- int MakeStream(uchar *Target, uchar Type, int Pid);
- int MakeAC3Descriptor(uchar *Target);
- int MakeSubtitlingDescriptor(uchar *Target, const char *Language);
-+ int MakeTeletextDescriptor(uchar *Target, cChannel *Channel);
- int MakeLanguageDescriptor(uchar *Target, const char *Language);
- int MakeCRC(uchar *Target, const uchar *Data, int Length);
- void GeneratePmtPid(cChannel *Channel);
-@@ -214,6 +215,7 @@ private:
- int vpid;
- int vtype;
- bool updatePrimaryDevice;
-+ int tpid;
- protected:
- int SectionLength(const uchar *Data, int Length) { return (Length >= 3) ? ((int(Data[1]) & 0x0F) << 8)| Data[2] : 0; }
- public:
-@@ -240,6 +242,7 @@ public:
- int Vpid(void) { return vpid; }
- ///< Returns the video pid as defined by the current PMT.
- int Vtype(void) { return vtype; }
-+ int Tpid(void) { return tpid; }
- };
-
- // TS to PES converter:
-diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c
-new file mode 100644
-index 0000000..4151552
---- /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 <ragge@nada.kth.se>
-+ *
-+ * 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 <stdlib.h>
-+#include <stdio.h>
-+#include <stdint.h>
-+
-+#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)
-+ { if(gListener) gListener->PlayerTeletextData(p, length, IsPesRecording); };
-+ 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..a962980
---- /dev/null
-+++ b/vdrttxtsubshooks.h
-@@ -0,0 +1,48 @@
-+/*
-+ * vdr-ttxtsubs - A plugin for the Linux Video Disk Recorder
-+ * Copyright (c) 2003 - 2008 Ragnar Sundblad <ragge@nada.kth.se>
-+ *
-+ * 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 1
-+
-+class cDevice;
-+class cChannel;
-+
-+#define VDRTTXTSUBSHOOKS
-+
-+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) {};
-+ virtual int ManualPageNumber(const cChannel *channel)
-+ { return 0; };
-+
-+ // used by VDR to call hook listeners
-+ static cVDRTtxtsubsHookListener *Hook(void);
-+};
-+
-+#endif