summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Grimm <tobias@e-tobi.loc>2009-06-20 19:18:00 +0200
committerTobias Grimm <tobias@e-tobi.loc>2009-06-20 19:18:00 +0200
commit4a8fece0af807564ea21b426c57e89bc9971a734 (patch)
tree5b18e2279e1e75123d184f343d3c053ff347c563
parent6a04b5f426c7e7c08f7081743c6b4907f2116205 (diff)
downloadvdr-plugin-ttxtsubs-4a8fece0af807564ea21b426c57e89bc9971a734.tar.gz
vdr-plugin-ttxtsubs-4a8fece0af807564ea21b426c57e89bc9971a734.tar.bz2
Updated VDR patch for 1.7.8
-rw-r--r--HISTORY1
-rw-r--r--patches/vdr-1.7.8-ttxtsubs.patch510
2 files changed, 511 insertions, 0 deletions
diff --git a/HISTORY b/HISTORY
index c5a7be7..77ce93a 100644
--- a/HISTORY
+++ b/HISTORY
@@ -3,6 +3,7 @@ VDR Plugin 'ttxtsubs' Revision History
20xx-xx-xx: Version x.x.x
- Add Ukrainian translation by Yarema aka Knedlyk (Closes #130)
+- Updated VDR patch for 1.7.8
2009-04-26: Version 0.1.0
- Updated VDR patch and plugin to VDR 1.7.6 with support for the TS recording
diff --git a/patches/vdr-1.7.8-ttxtsubs.patch b/patches/vdr-1.7.8-ttxtsubs.patch
new file mode 100644
index 0000000..abde5c3
--- /dev/null
+++ b/patches/vdr-1.7.8-ttxtsubs.patch
@@ -0,0 +1,510 @@
+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