diff options
author | Tobias Grimm <git@e-tobi.net> | 2010-02-05 22:10:16 +0100 |
---|---|---|
committer | Tobias Grimm <git@e-tobi.net> | 2010-02-05 22:10:16 +0100 |
commit | 1b6ff917211ba4728e4bb60b75e4598974326625 (patch) | |
tree | cff8c8be5631ecad43a15e8eeb0146abbafa085c | |
parent | 5fd4b06b7d21b44eff6918dbcbba691870023ae7 (diff) | |
download | vdr-plugin-ttxtsubs-1b6ff917211ba4728e4bb60b75e4598974326625.tar.gz vdr-plugin-ttxtsubs-1b6ff917211ba4728e4bb60b75e4598974326625.tar.bz2 |
Added VDR patch that stores the manual page selection with the channel settings
The manual page slection wil get stored in the channels.conf.
Patch provided by Rolf Ahrenberg (tpid-v2)
(references #139)
-rw-r--r-- | HISTORY | 3 | ||||
-rw-r--r-- | patches/vdr-1.7.12-ttxtsubs-tpid-v2.patch | 516 |
2 files changed, 519 insertions, 0 deletions
@@ -8,6 +8,9 @@ VDR Plugin 'ttxtsubs' Revision History - Updated plugin and VDR patch for 1.7.12 - Thx to Rolf Ahrenberg (Closes #236) - 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) 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.12-ttxtsubs-tpid-v2.patch b/patches/vdr-1.7.12-ttxtsubs-tpid-v2.patch new file mode 100644 index 0000000..5080fd4 --- /dev/null +++ b/patches/vdr-1.7.12-ttxtsubs-tpid-v2.patch @@ -0,0 +1,516 @@ +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, ¶mbuf, &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, ¶mbuf, &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 |