r479 - in vdr/vdr/trunk/debian: . patches
Darren Salt
pkg-vdr-dvb-changes@lists.alioth.debian.org
Mon, 18 Apr 2005 22:29:34 +0000
Author: dsalt-guest
Date: 2005-04-18 22:29:29 +0000 (Mon, 18 Apr 2005)
New Revision: 479
Added:
vdr/vdr/trunk/debian/patches/09_sort_options.dpatch
vdr/vdr/trunk/debian/patches/10_livelock.dpatch
vdr/vdr/trunk/debian/patches/11_memleak.dpatch
vdr/vdr/trunk/debian/patches/12_nptl.dpatch
vdr/vdr/trunk/debian/patches/15_dvbplayer.dpatch
vdr/vdr/trunk/debian/patches/16_dvbspu.dpatch
vdr/vdr/trunk/debian/patches/17_replay.dpatch
vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch
Removed:
vdr/vdr/trunk/debian/patches/opt-21_ttxtsubs.dpatch
Modified:
vdr/vdr/trunk/debian/changelog
vdr/vdr/trunk/debian/patches/00list
Log:
Add some patches from my vdr package.
Replace the ttxtsubs patch with a combined subtitles/ttxtsubs patch.
Modified: vdr/vdr/trunk/debian/changelog
===================================================================
--- vdr/vdr/trunk/debian/changelog 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/changelog 2005-04-18 22:29:29 UTC (rev 479)
@@ -21,8 +21,18 @@
* Tobias Grimm <tg@e-tobi.net>
- Don't restrict root capabilities with --allow-root anymore
- Passing $OPTIONS to binary compatibility test in plugin loader now
+ * Darren Salt <linux@youmustbejoking.demon.co.uk>
+ - Added patches:
+ + 09_sort_options: extra channel sort options
+ + 10_livelock: don't hang when jumping between editing marks
+ + 11_memleak: fix two small memory leaks
+ + 12_nptl: don't abort if NPTL is in use
+ + 15_dvbplayer: send proper I-frames [Reinhard Nissl]
+ + 16_dvbspu: fix some SPU bugs [Reinhard Nissl]
+ + 17_replay: improve end-of-recording handling [Reinhard Nissl]
+ - Replaced the ttxtsubs patch with a combined subtitles+ttxtsubs patch.
- -- Debian VDR Team <pkg-vdr-dvb-devel@lists.alioth.debian.org> Sat, 09 Apr 2005 20:43:31 +0200
+ -- Debian VDR Team <pkg-vdr-dvb-devel@lists.alioth.debian.org> Mon, 18 Apr 2005 23:26:21 +0100
vdr (1.2.6-12) unstable; urgency=low
Modified: vdr/vdr/trunk/debian/patches/00list
===================================================================
--- vdr/vdr/trunk/debian/patches/00list 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/00list 2005-04-18 22:29:29 UTC (rev 479)
@@ -6,15 +6,22 @@
06_default_svdrp_port_0
07_not_as_root
08_security_CAN-2005-0071
+09_sort_options
+10_livelock
+11_memleak
+12_nptl
13_remote
14_update-resume
+15_dvbplayer
+16_dvbspu
+17_replay
# The Elchi AIO 4d patch for a nicer OSD, inlcuding the frames and black
# square fix.
# opt-20_elchiaio4d+1
-# Patch needed for ttxtsubs (does not work with AC3-patch)
-# opt-21_ttxtsubs
+# Patch needed for DVB subtitles or ttxtsubs (does not work with AC3-patch)
+# opt-21_subtitles_and_ttxtsubs
# This patch fixes a problem with 256 color, by changing char to unsigned
# char.
Added: vdr/vdr/trunk/debian/patches/09_sort_options.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/09_sort_options.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/09_sort_options.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -0,0 +1,103 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 11_sort_options.dpatch by Darren Salt and Luca Olivetti <luca@ventoso.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: [LO] Add sort-by-source options.
+## DP: [DS] Add sort-by-provider-then-channel-number options.
+
+@DPATCH@
+diff -urNad vdr-1.3.17/menu.c /tmp/dpep.AB4AkR/vdr-1.3.17/menu.c
+--- vdr-1.3.17/menu.c 2004-12-04 20:12:35.000000000 +0000
++++ /tmp/dpep.AB4AkR/vdr-1.3.17/menu.c 2004-12-04 20:22:04.000000000 +0000
+@@ -328,14 +328,18 @@
+
+ class cMenuChannelItem : public cOsdItem {
+ public:
+- enum eChannelSortMode { csmNumber, csmName, csmProvider };
++ enum eChannelSortMode {
++ csmNumber, csmName, csmProvider, csmProviderNumber,
++ csmSourceNumber, csmSourceName, csmSourceProvider, csmSourceProviderNumber,
++ csmLAST
++ };
+ private:
+ static eChannelSortMode sortMode;
+ cChannel *channel;
+ public:
+ cMenuChannelItem(cChannel *Channel);
+ static void SetSortMode(eChannelSortMode SortMode) { sortMode = SortMode; }
+- static void IncSortMode(void) { sortMode = eChannelSortMode((sortMode == csmProvider) ? csmNumber : sortMode + 1); }
++ static void IncSortMode(void) { sortMode = eChannelSortMode(sortMode + 1); if (sortMode == csmLAST) sortMode = csmNumber; }
+ virtual int Compare(const cListObject &ListObject) const;
+ virtual void Set(void);
+ cChannel *Channel(void) { return channel; }
+@@ -352,13 +356,46 @@
+ Set();
+ }
+
++static int snum(int source)
++{
++ int stype = (source & cSource::st_Mask);
++ // arbitrary order: sat, cable, terrestrial, none
++ int r;
++ switch(stype) {
++ case cSource::stCable:
++ r=0x7FF0;
++ break;
++ case cSource::stTerr:
++ r=0x7FF2;
++ break;
++ case cSource::stSat:
++ r=source & cSource::st_Pos;
++ if (source & cSource::st_Neg) r*=-1;
++ break;
++ default: //stNone or unknown
++ r=0x7FFF;
++ }
++ return r;
++}
++
+ int cMenuChannelItem::Compare(const cListObject &ListObject) const
+ {
+ cMenuChannelItem *p = (cMenuChannelItem *)&ListObject;
+ int r = -1;
+- if (sortMode == csmProvider)
++ if (sortMode >= csmSourceNumber) {
++ int rsource = snum(channel->Source()) - snum(p->channel->Source());
++ if (sortMode == csmSourceProvider && rsource == 0)
++ r = strcoll(channel->Provider(), p->channel->Provider());
++ if ((sortMode == csmSourceName ||
++ (r == 0 && sortMode != csmSourceProviderNumber)) && rsource == 0)
++ r = strcoll(channel->Name(), p->channel->Name());
++ if ((sortMode == csmSourceNumber || r == 0) && rsource == 0)
++ r = channel->Number() - p->channel->Number();
++ return ((rsource == 0) ? r : rsource);
++ }
++ if (sortMode == csmProvider || sortMode == csmProviderNumber)
+ r = strcoll(channel->Provider(), p->channel->Provider());
+- if (sortMode == csmName || r == 0)
++ if (sortMode == csmName || (r == 0 && sortMode != csmProviderNumber))
+ r = strcoll(channel->Name(), p->channel->Name());
+ if (sortMode == csmNumber || r == 0)
+ r = channel->Number() - p->channel->Number();
+@@ -369,10 +406,17 @@
+ {
+ char *buffer = NULL;
+ if (!channel->GroupSep()) {
+- if (sortMode == csmProvider)
+- asprintf(&buffer, "%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name());
+- else
+- asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name());
++ if (sortMode >= csmSourceNumber) {
++ if (sortMode == csmSourceProvider || sortMode == csmSourceProviderNumber)
++ asprintf(&buffer, "%d\t%s - %s - %s", channel->Number(), *cSource::ToString(channel->Source()), channel->Provider(), channel->Name());
++ else
++ asprintf(&buffer, "%d\t%s - %s", channel->Number(), *cSource::ToString(channel->Source()), channel->Name());
++ } else {
++ if (sortMode == csmProvider || sortMode == csmProviderNumber)
++ asprintf(&buffer, "%d\t%s - %s", channel->Number(), channel->Provider(), channel->Name());
++ else
++ asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name());
++ }
+ }
+ else
+ asprintf(&buffer, "---\t%s ----------------------------------------------------------------", channel->Name());
Property changes on: vdr/vdr/trunk/debian/patches/09_sort_options.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: vdr/vdr/trunk/debian/patches/10_livelock.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/10_livelock.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/10_livelock.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -0,0 +1,18 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 10_livelock.dpatch by Timothy Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Fix a livelock problem when jumping between editing marks.
+
+@DPATCH@
+diff -urNad vdr-1.3.23/dvbplayer.c /tmp/dpep.KvgOVM/vdr-1.3.23/dvbplayer.c
+--- vdr-1.3.23/dvbplayer.c 2005-04-12 01:28:23.392793314 +0100
++++ /tmp/dpep.KvgOVM/vdr-1.3.23/dvbplayer.c 2005-04-12 01:28:23.978745831 +0100
+@@ -464,6 +464,7 @@
+ cPoller Poller;
+ if (DevicePoll(Poller, 100)) {
+
++ sched_yield();
+ LOCK_THREAD;
+
+ // Read the next frame from the file:
Property changes on: vdr/vdr/trunk/debian/patches/10_livelock.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: vdr/vdr/trunk/debian/patches/11_memleak.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/11_memleak.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/11_memleak.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -0,0 +1,32 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 11_memleak.dpatch by Stefan Huelswitt <s.huelswitt@gmx.de> and Daniel Thompson <daniel.thompson@st.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Kill some memory leaks.
+
+@DPATCH@
+diff -urNad vdr-1.3.23/dvbplayer.c /tmp/dpep.HpFRhI/vdr-1.3.23/dvbplayer.c
+--- vdr-1.3.23/dvbplayer.c 2005-04-12 01:28:38.278587027 +0100
++++ /tmp/dpep.HpFRhI/vdr-1.3.23/dvbplayer.c 2005-04-12 01:28:38.569563448 +0100
+@@ -296,6 +296,7 @@
+ nonBlockingFileReader->Clear();
+ if ((readIndex = backTrace->Get(playDir == pdForward)) < 0)
+ readIndex = writeIndex;
++ delete readFrame;
+ readFrame = NULL;
+ playFrame = NULL;
+ ringBuffer->Clear();
+diff -urNad vdr-1.3.23/epg.c /tmp/dpep.HpFRhI/vdr-1.3.23/epg.c
+--- vdr-1.3.23/epg.c 2005-04-12 01:28:38.241590025 +0100
++++ /tmp/dpep.HpFRhI/vdr-1.3.23/epg.c 2005-04-12 01:29:20.344178196 +0100
+@@ -29,9 +29,7 @@
+ {
+ unsigned int Stream, Type;
+ int n = sscanf(s, "%X %02X %3c %a[^\n]", &Stream, &Type, language, &description);
+- if (n != 4)
+- description = NULL;
+- else if (isempty(description)) {
++ if (n != 4 || isempty(description)) {
+ free(description);
+ description = NULL;
+ }
Property changes on: vdr/vdr/trunk/debian/patches/11_memleak.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: vdr/vdr/trunk/debian/patches/12_nptl.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/12_nptl.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/12_nptl.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -0,0 +1,20 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 01_nptl.dpatch by <ds@flibble.youmustbejoking.demon.co.uk>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+@DPATCH@
+diff -urNad vdr-1.3.16/vdr.c /tmp/dpep.AffX44/vdr-1.3.16/vdr.c
+--- vdr-1.3.16/vdr.c 2004-11-14 20:05:59.000000000 +0000
++++ /tmp/dpep.AffX44/vdr-1.3.16/vdr.c 2004-11-14 20:08:18.000000000 +0000
+@@ -92,8 +92,7 @@
+ char LibPthreadVersion[128];
+ if (confstr(_CS_GNU_LIBPTHREAD_VERSION, LibPthreadVersion, sizeof(LibPthreadVersion)) > 0) {
+ if (strstr(LibPthreadVersion, "NPTL")) {
+- fprintf(stderr, "vdr: please turn off NPTL by setting 'export LD_ASSUME_KERNEL=2.4.1' before starting VDR\n");
+- return 2;
++ fprintf(stderr, "vdr: warning: NPTL is active - there may be problems\n");
+ }
+ }
+ #endif
Property changes on: vdr/vdr/trunk/debian/patches/12_nptl.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: vdr/vdr/trunk/debian/patches/15_dvbplayer.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/15_dvbplayer.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/15_dvbplayer.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -0,0 +1,169 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 06_nissl_dvbplayer.dpatch by Reinhard Nissl <rnissl@gmx.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: send proper I-frames to the device
+
+@DPATCH@
+--- ./dvbplayer.c
++++ ./dvbplayer.c
+@@ -358,6 +358,94 @@ void cDvbPlayer::Activate(bool On)
+ }
+ }
+
++static uchar *findStartCode(uchar *Data, int Length)
++{
++ uchar *limit = Data + Length;
++ Data += 6 + 3 + Data[6 + 2] + 3; // move to video payload and skip 00 00 01
++ while (Data < limit) {
++ // possible start codes that appear before/after picture data
++ // 00 00 01 B3: sequence header code
++ // 00 00 01 B8: group start code
++ // 00 00 01 00: picture start code
++ // 00 00 01 B7: sequence end code
++ if (0x01 == Data[-1] && (0xB3 == Data[0] || 0xB8 == Data[0] || 0x00 == Data[0] || 0xB7 == Data[0]) && 0x00 == Data[-2] && 0x00 == Data[-3])
++ return Data - 3;
++ Data++;
++ }
++
++ return 0;
++}
++
++static void fixIFrameHead(uchar *Data, int Length)
++{
++ uchar *p = findStartCode(Data, Length);
++ if (!p) {
++ esyslog("fixIframeHead: start code not found!\n");
++ return;
++ }
++
++ Data += 6 + 3 + Data[6 + 2]; // move to video payload
++ if (Data < p)
++ memset(Data, 0, p - Data); // zero preceeding bytes
++}
++
++static int fixIFrameTail(uchar *Data, int Length, bool StillImage)
++{
++ uchar *p = findStartCode(Data, Length);
++ if (!p) {
++ esyslog("fixIframeTail: start code not found!\n");
++ return Length;
++ }
++
++ if (StillImage) {
++ // need to append sequence end code
++ p[3] = 0xB7;
++ p += 4;
++ }
++
++ // is this PES packet required?
++ uchar *videoPayload = Data + 6 + 3 + Data[6 + 2];
++ if (videoPayload >= p)
++ return 0; // no
++
++ // adjust PES payload size
++ int payloadSize = (p - Data) - 6;
++ Data[4] = payloadSize >> 8;
++ Data[5] = payloadSize & 0xFF;
++
++ return payloadSize + 6;
++}
++
++#define IPACKS 2048 // originally defined in remux.c
++
++static void fixIFrame(uchar *Data, int &Length, bool StillImage)
++{
++ int originalLength = Length - IPACKS; // by design
++ int done = 0;
++
++ while (done < Length) {
++ if (0x00 != Data[0] || 0x00 != Data[1] || 0x01 != Data[2]) {
++ esyslog("fixIFrame: PES start code not found at offset %d (data length: %d)!", done, Length);
++ return;
++ }
++
++ int lenPES = 6 + Data[4] * 256 + Data[5];
++ if (0xE0 == (0xF0 & Data[ 3 ])) { // video packet
++ int todo = Length - done;
++ int bite = (lenPES < todo) ? lenPES : todo;
++ if (0 == done) // first packet
++ fixIFrameHead(Data, bite);
++ else if (done >= originalLength) { // last packet
++ Length = done + fixIFrameTail(Data, bite, StillImage);
++ return;
++ }
++ }
++
++ done += lenPES;
++ Data += lenPES;
++ }
++}
++
+ void cDvbPlayer::Action(void)
+ {
+ uchar *b = NULL;
+@@ -380,14 +468,15 @@ void cDvbPlayer::Action(void)
+
+ // Read the next frame from the file:
+
+- if (!readFrame && (replayFile >= 0 || readIndex >= 0)) {
+- if (playMode != pmStill) {
++ if (playMode != pmStill && playMode != pmPause) {
++ if (!readFrame && (replayFile >= 0 || readIndex >= 0)) {
+ if (!nonBlockingFileReader->Reading()) {
+ if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward)) {
+ uchar FileNumber;
+ int FileOffset;
+ int Index = index->GetNextIFrame(readIndex, playDir == pdForward, &FileNumber, &FileOffset, &Length, true);
+ if (Index >= 0) {
++ Length += IPACKS; // fixIFrame needs next video packet
+ if (!NextFile(FileNumber, FileOffset))
+ continue;
+ }
+@@ -428,6 +523,8 @@ void cDvbPlayer::Action(void)
+ }
+ int r = nonBlockingFileReader->Read(replayFile, b, Length);
+ if (r > 0) {
++ if (playMode == pmFast || (playMode == pmSlow && playDir == pdBackward))
++ fixIFrame(b, r, false);
+ readFrame = new cFrame(b, -r, ftUnknown, readIndex); // hands over b to the ringBuffer
+ b = NULL;
+ }
+@@ -438,16 +535,16 @@ void cDvbPlayer::Action(void)
+ break;
+ }
+ }
+- else
+- cCondWait::SleepMs(3); // this keeps the CPU load low
+- }
+
+- // Store the frame in the buffer:
++ // Store the frame in the buffer:
+
+- if (readFrame) {
+- if (ringBuffer->Put(readFrame))
+- readFrame = NULL;
++ if (readFrame) {
++ if (ringBuffer->Put(readFrame))
++ readFrame = NULL;
++ }
+ }
++ else
++ cCondWait::SleepMs(3); // this keeps the CPU load low
+
+ // Get the next frame from the buffer:
+
+@@ -659,11 +756,13 @@ void cDvbPlayer::Goto(int Index, bool St
+ int FileOffset, Length;
+ Index = index->GetNextIFrame(Index, false, &FileNumber, &FileOffset, &Length);
+ if (Index >= 0 && NextFile(FileNumber, FileOffset) && Still) {
++ Length += IPACKS; // fixIFrame needs next video packet
+ uchar b[MAXFRAMESIZE];
+ int r = ReadFrame(replayFile, b, Length, sizeof(b));
+ if (r > 0) {
+ if (playMode == pmPause)
+ DevicePlay();
++ fixIFrame(b, r, true);
+ DeviceStillPicture(b, r);
+ }
+ playMode = pmStill;
Property changes on: vdr/vdr/trunk/debian/patches/15_dvbplayer.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: vdr/vdr/trunk/debian/patches/16_dvbspu.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/16_dvbspu.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/16_dvbspu.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -0,0 +1,61 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 06_nissl_dvbspu.dpatch by Reinhard Nissl <rnissl@gmx.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: SPU fixes (vdr-dvd)
+
+@DPATCH@
+diff -urNad vdr-1.3.22/dvbspu.c /tmp/dpep.rB9LVD/vdr-1.3.22/dvbspu.c
+--- vdr-1.3.22/dvbspu.c 2005-02-28 15:56:44.000000000 +0000
++++ /tmp/dpep.rB9LVD/vdr-1.3.22/dvbspu.c 2005-02-28 15:56:45.000000000 +0000
+@@ -153,7 +153,7 @@
+ setMin(minsize[colorid].x1, xp);
+ setMin(minsize[colorid].y1, yp);
+ setMax(minsize[colorid].x2, xp + len - 1);
+- setMax(minsize[colorid].y2, yp + len - 1);
++ setMax(minsize[colorid].y2, yp);
+ }
+
+ static uint8_t getBits(uint8_t * &data, uint8_t & bitf)
+@@ -352,6 +352,20 @@
+ return size;
+ }
+
++static bool OsdMatchesArea(cOsd *osd, tArea &area)
++{
++ cBitmap *bmp = osd->GetBitmap(0);
++ if (!bmp)
++ return false;
++ if (bmp->Bpp() < area.bpp)
++ return false;
++ if (bmp->X0() > area.x1 || bmp->Y0() > area.y1)
++ return false;
++ if ((bmp->X0() + bmp->Width()) <= area.x2 || (bmp->Y0() + bmp->Height()) <= area.y2)
++ return false;
++ return true;
++}
++
+ void cDvbSpuDecoder::Draw(void)
+ {
+ if (!spubmp) {
+@@ -389,12 +403,16 @@
+ }
+
+ if (bg || fg) {
++ int x2 = areaSize.x2;
++ while ((x2 - areaSize.x1 + 1) & 0x03)
++ x2++;
++ tArea Area = { areaSize.x1, areaSize.y1, x2, areaSize.y2, (fg && bg) ? 4 : 2 };
++ if (osd && !OsdMatchesArea(osd, Area)) {
++ delete osd;
++ osd = NULL;
++ }
+ if (osd == NULL) {
+ osd = cOsdProvider::NewOsd(0, 0);
+- int x2 = areaSize.x2;
+- while ((x2 - areaSize.x1 + 1) & 0x03)
+- x2++;
+- tArea Area = { areaSize.x1, areaSize.y1, x2, areaSize.y2, (fg && bg) ? 4 : 2 };
+ osd->SetAreas(&Area, 1);
+ }
+
Property changes on: vdr/vdr/trunk/debian/patches/16_dvbspu.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: vdr/vdr/trunk/debian/patches/17_replay.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/17_replay.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/17_replay.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -0,0 +1,23 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 06_nissl_replay.dpatch by Reinhard Nissl <rnissl@gmx.de>
+##
+## All lines beginning with ## DP:' are a description of the patch.
+## DP: Replay optimisation
+
+@DPATCH@
+diff -urNad vdr-1.3.23/dvbplayer.c /tmp/dpep.OdxwwC/vdr-1.3.23/dvbplayer.c
+--- vdr-1.3.23/dvbplayer.c 2005-04-18 22:46:41.002332578 +0100
++++ /tmp/dpep.OdxwwC/vdr-1.3.23/dvbplayer.c 2005-04-18 22:46:41.411299437 +0100
+@@ -481,6 +481,12 @@
+ continue;
+ }
+ else {
++ // hit end of recording: signal end of file but don't change playMode
++ if (playDir == pdForward) {
++ readIndex = -1;
++ eof = true;
++ continue;
++ }
+ // hit begin of recording: wait for device buffers to drain
+ // before changing play mode:
+ if (!DeviceFlush(100))
Property changes on: vdr/vdr/trunk/debian/patches/17_replay.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -0,0 +1,845 @@
+#!/bin/sh /usr/share/dpatch/dpatch-run
+## opt-20_subtitles_and_ttxtsubs.dpatch by Rolf Ahrenberg <rahrenbe@cc.hut.fi>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Combined DVB subtitles (0.3.7) & ttxtsubs (0.0.5) patch.
+
+@DPATCH@
+diff -Nru vdr-1.3.23-vanilla/Makefile vdr-1.3.23-subtitles/Makefile
+--- vdr-1.3.23-vanilla/Makefile 2005-03-20 18:03:36.000000000 +0200
++++ vdr-1.3.23-subtitles/Makefile 2005-03-20 18:04:58.000000000 +0200
+@@ -40,6 +40,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
+
++OBJS += osdcontroller.o rcontroller.o dvbsub.o vdrttxtsubshooks.o
++
+ FIXFONT_ISO8859_1 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
+ OSDFONT_ISO8859_1 = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
+ SMLFONT_ISO8859_1 = -adobe-helvetica-medium-r-normal--18-*-100-100-p-*-iso8859-1
+diff -Nru vdr-1.3.23-vanilla/dvbplayer.c vdr-1.3.23-subtitles/dvbplayer.c
+--- vdr-1.3.23-vanilla/dvbplayer.c 2005-03-20 18:03:36.000000000 +0200
++++ vdr-1.3.23-subtitles/dvbplayer.c 2005-03-20 18:04:58.000000000 +0200
+@@ -14,6 +14,9 @@
+ #include "ringbuffer.h"
+ #include "thread.h"
+ #include "tools.h"
++#include "rcontroller.h"
++#include "dvbsub.h"
++#include "vdrttxtsubshooks.h"
+
+ // --- cBackTrace ----------------------------------------------------------
+
+@@ -304,6 +307,39 @@
+ firstPacket = true;
+ }
+
++static void StripExtendedPackets(uchar *b, int Length)
++{
++ for (int i = 0; i < Length - 6; i++) {
++ if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) {
++ uchar c = b[i + 3];
++ int l = b[i + 4] * 256 + b[i + 5] + 6;
++ switch (c) {
++ case 0xBD: // dolby
++ if (RecordingPatch::RecordingController.isExtendedPacket(b + i , l)) {
++ RecordingPatch::RecordingController.Receive( b + i, l );
++ // continue with deleting the data - otherwise it disturbs DVB replay
++ int n = l;
++ for (int j = i; j < Length && n--; j++)
++ b[j] = 0x00;
++ }
++ // EBU Teletext data, ETSI EN 300 472
++ else if (b[i + 8] == 0x24 && b[i + 45] >= 0x10 && b[i + 45] < 0x20) {
++ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData(&b[i], l);
++ // continue with deleting the data - otherwise it disturbs DVB replay
++ int n = l;
++ for (int j = i; j < Length && n--; j++)
++ b[j] = 0x00;
++ }
++ break;
++ default:
++ break;
++ }
++ if (l)
++ i += l - 1; // the loop increments, too!
++ }
++ }
++}
++
+ bool cDvbPlayer::NextFile(uchar FileNumber, int FileOffset)
+ {
+ if (FileNumber > 0)
+@@ -472,6 +508,7 @@
+ }
+ }
+ if (p) {
++ StripExtendedPackets(p, pc);
+ int w = PlayPes(p, pc, playMode != pmPlay);
+ if (w > 0) {
+ p += w;
+diff -Nru vdr-1.3.23-vanilla/dvbsub.c vdr-1.3.23-subtitles/dvbsub.c
+--- vdr-1.3.23-vanilla/dvbsub.c 1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.3.23-subtitles/dvbsub.c 2005-03-20 18:04:58.000000000 +0200
+@@ -0,0 +1,18 @@
++#include "dvbsub.h"
++
++cDvbSubtitlesRecording DvbSubtitlesRecording;
++
++cDvbSubtitlesRecording::cDvbSubtitlesRecording(){
++ query=0;
++}
++void cDvbSubtitlesRecording::Subscribe(iPidQuery* listener){
++ query = listener ;
++}
++
++int cDvbSubtitlesRecording::GetPidByChannel( int DevNr, const cChannel* Channel, int Language )
++{
++ if (query)
++ return query->GetPidByChannel( DevNr, Channel,Language );
++ else
++ return 0;
++}
+diff -Nru vdr-1.3.23-vanilla/dvbsub.h vdr-1.3.23-subtitles/dvbsub.h
+--- vdr-1.3.23-vanilla/dvbsub.h 1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.3.23-subtitles/dvbsub.h 2005-03-20 18:04:58.000000000 +0200
+@@ -0,0 +1,21 @@
++class cChannel;
++class cRecordControl;
++
++class iPidQuery
++{
++public:
++ virtual int GetPidByChannel( int DevNr, const cChannel* Channel, int Language ) = 0;
++};
++class cDvbSubtitlesRecording
++{
++public:
++ cDvbSubtitlesRecording();
++ void Subscribe(iPidQuery* listener);
++private:
++ friend class cRecordControl;
++ int GetPidByChannel( int DevNr, const cChannel* Channel, int Language );
++ iPidQuery* query;
++};
++
++extern cDvbSubtitlesRecording DvbSubtitlesRecording;
++
+diff -Nru vdr-1.3.23-vanilla/menu.c vdr-1.3.23-subtitles/menu.c
+--- vdr-1.3.23-vanilla/menu.c 2005-03-20 18:03:36.000000000 +0200
++++ vdr-1.3.23-subtitles/menu.c 2005-03-20 18:04:58.000000000 +0200
+@@ -28,6 +28,8 @@
+ #include "themes.h"
+ #include "timers.h"
+ #include "transfer.h"
++#include "vdrttxtsubshooks.h"
++#include "dvbsub.h"
+ #include "videodir.h"
+
+ #define MENUTIMEOUT 120 // seconds
+@@ -3045,8 +3047,11 @@
+ isyslog("record %s", fileName);
+ if (MakeDirs(fileName, true)) {
+ const cChannel *ch = timer->Channel();
+- recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids());
++ cTtxtSubsRecorderBase *subsRecorder = cVDRTtxtsubsHookListener::Hook()->NewTtxtSubsRecorder(device, ch);
++ int SubPids[3] = {DvbSubtitlesRecording.GetPidByChannel(device->DeviceNumber(), ch, 1), DvbSubtitlesRecording.GetPidByChannel(device->DeviceNumber(), ch, 2), 0};
++ recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), SubPids, subsRecorder);
+ if (device->AttachReceiver(recorder)) {
++ if (subsRecorder) subsRecorder->DeviceAttach();
+ Recording.WriteSummary();
+ cStatus::MsgRecording(device, Recording.Name());
+ if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
+diff -Nru vdr-1.3.23-vanilla/osd.c vdr-1.3.23-subtitles/osd.c
+--- vdr-1.3.23-vanilla/osd.c 2005-03-20 18:03:36.000000000 +0200
++++ vdr-1.3.23-subtitles/osd.c 2005-03-20 18:04:58.000000000 +0200
+@@ -15,6 +15,8 @@
+ #include <sys/stat.h>
+ #include <sys/unistd.h>
+ #include "tools.h"
++#include "osdcontroller.h"
++#include "vdrttxtsubshooks.h"
+
+ // --- cPalette --------------------------------------------------------------
+
+@@ -575,6 +577,7 @@
+ // --- cOsd ------------------------------------------------------------------
+
+ bool cOsd::isOpen = false;
++bool cOsd::niosd = false;
+
+ cOsd::cOsd(int Left, int Top)
+ {
+@@ -594,6 +597,9 @@
+ delete bitmaps[i];
+ delete savedRegion;
+ isOpen = false;
++ if (!niosd)
++ NonInteractiveOsdPatch::OsdController.Show();
++ cVDRTtxtsubsHookListener::Hook()->ShowOSD();
+ }
+
+ cBitmap *cOsd::GetBitmap(int Area)
+@@ -715,8 +721,13 @@
+ osdProvider = NULL;
+ }
+
+-cOsd *cOsdProvider::NewOsd(int Left, int Top)
++cOsd *cOsdProvider::NewOsd(int Left, int Top, bool dontHide)
+ {
++ if (!dontHide)
++ NonInteractiveOsdPatch::OsdController.Hide();
++ cOsd::niosd = dontHide;
++ // OSD_HOOK_2 - Information to Checkpatch.sh
++ cVDRTtxtsubsHookListener::Hook()->HideOSD();
+ if (cOsd::IsOpen())
+ esyslog("ERROR: attempt to open OSD while it is already open - using dummy OSD!");
+ else if (osdProvider)
+diff -Nru vdr-1.3.23-vanilla/osd.h vdr-1.3.23-subtitles/osd.h
+--- vdr-1.3.23-vanilla/osd.h 2005-03-20 18:03:36.000000000 +0200
++++ vdr-1.3.23-subtitles/osd.h 2005-03-20 18:04:58.000000000 +0200
+@@ -215,6 +215,8 @@
+ cBitmap *bitmaps[MAXOSDAREAS];
+ int numBitmaps;
+ int left, top, width, height;
++public:
++ static bool niosd;
+ protected:
+ cOsd(int Left, int Top);
+ ///< Initializes the OSD with the given coordinates.
+@@ -327,7 +329,7 @@
+ cOsdProvider(void);
+ //XXX maybe parameter to make this one "sticky"??? (frame-buffer etc.)
+ virtual ~cOsdProvider();
+- static cOsd *NewOsd(int Left, int Top);
++ static cOsd *NewOsd(int Left, int Top, bool dontHide = false);
+ ///< Returns a pointer to a newly created cOsd object, which will be located
+ ///< at the given coordinates. When the cOsd object is no longer needed, the
+ ///< caller must delete it. If the OSD is already in use, or there is no OSD
+diff -Nru vdr-1.3.23-vanilla/osdcontroller.c vdr-1.3.23-subtitles/osdcontroller.c
+--- vdr-1.3.23-vanilla/osdcontroller.c 1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.3.23-subtitles/osdcontroller.c 2005-03-20 18:04:58.000000000 +0200
+@@ -0,0 +1,132 @@
++#include "osdcontroller.h"
++#include "thread.h"
++
++namespace NonInteractiveOsdPatch
++{
++
++ class cListenerListObject : public cListObject
++ {
++ public:
++ cListenerListObject(int priority, cOsdListener* listener);
++ bool operator< (const cListObject &ListObject);
++
++ int iPriority;
++ cOsdListener* iListener;
++ };
++
++ cListenerListObject::cListenerListObject(int priority, cOsdListener* listener)
++ : cListObject(),iPriority(priority), iListener( listener )
++ {
++ }
++ bool cListenerListObject::operator< (const cListObject &ListObject)
++ {
++
++ return iPriority > ((cListenerListObject *)&ListObject)->iPriority;
++ }
++
++ cOsdController OsdController;
++
++ cOsdController::cOsdController()
++ : iShowing( false )
++ {
++ iMutex = new cMutex();
++ iListeners = new cList<cListenerListObject>;
++ }
++
++ cOsdController::~cOsdController()
++ {
++ delete iListeners;
++ delete iMutex;
++ }
++
++ bool cOsdController::Subscribe( int priority, cOsdListener* listener )
++ {
++
++ cMutexLock( iMutex );
++ if ( !listener )
++ return false;
++
++ for ( cListenerListObject* llo = iListeners->First();
++ llo; llo = iListeners->Next(llo))
++ {
++ // check for duplicates
++ if ( llo->iListener == listener )
++ return false;
++ }
++
++ cListenerListObject *lo = new cListenerListObject(priority, listener);
++ iListeners->Add( lo );
++ iListeners->Sort();
++
++ // Give osd to the new listener if it has higher priority
++ // than the current one
++ if ( iShowing && !iCurrent )
++ {
++ listener->Show();
++ iCurrent = lo;
++ }
++ else if ( iShowing && iCurrent && iCurrent->iPriority < priority )
++ {
++ iCurrent->iListener->Hide();
++ ShowHighest();
++
++ }
++
++ return true;
++ }
++
++ void cOsdController::Unsubscribe( cOsdListener* listener )
++ {
++ cMutexLock( iMutex );
++ if ( !listener )
++ return;
++
++ for ( cListenerListObject* llo = iListeners->First();
++ llo; llo = iListeners->Next(llo))
++ {
++
++ if ( llo->iListener == listener )
++ {
++ iListeners->Del( llo, true );
++ if ( iShowing && llo == iCurrent )
++ {
++ listener->Hide();
++ ShowHighest();
++ }
++ break;
++ }
++ }
++
++ }
++
++ void cOsdController::Show()
++ {
++ cMutexLock( iMutex );
++ iShowing = true;
++ ShowHighest();
++
++ }
++
++ void cOsdController::Hide()
++ {
++ cMutexLock( iMutex );
++ iShowing = false;
++ if ( iCurrent )
++ iCurrent->iListener->Hide();
++ iCurrent = NULL;
++ }
++
++ void cOsdController::ShowHighest()
++ {
++
++ cListenerListObject* llo = iListeners->First();
++
++ if ( llo )
++ llo->iListener->Show();
++
++ iCurrent = llo;
++
++ }
++
++
++}
+diff -Nru vdr-1.3.23-vanilla/osdcontroller.h vdr-1.3.23-subtitles/osdcontroller.h
+--- vdr-1.3.23-vanilla/osdcontroller.h 1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.3.23-subtitles/osdcontroller.h 2005-04-01 16:18:14.000000000 +0300
+@@ -0,0 +1,51 @@
++#ifndef __OSDCONTROLLER_H
++#define __OSDCONTROLLER_H
++
++#include "tools.h"
++
++
++#define MAX_OSD_LISTENERS 10
++
++class cOsdProvider;
++class cOsd;
++class cMutex;
++
++namespace NonInteractiveOsdPatch
++{
++
++ class cOsdListener
++ {
++
++ public:
++ virtual void Show() = 0;
++ virtual void Hide() = 0;
++
++ };
++
++ class cListenerListObject;
++
++ class cOsdController
++ {
++ public:
++ cOsdController();
++ ~cOsdController();
++ bool Subscribe( int priority, cOsdListener* listener );
++ void Unsubscribe( cOsdListener* listner );
++
++ private:
++ friend class ::cOsdProvider;
++ friend class ::cOsd;
++ void Show();
++ void Hide();
++ void ShowHighest();
++
++ bool iShowing;
++ cMutex* iMutex;
++ cListenerListObject* iCurrent;
++ cList<cListenerListObject>* iListeners;
++
++ };
++ extern cOsdController OsdController;
++
++}
++#endif
+diff -Nru vdr-1.3.23-vanilla/rcontroller.c vdr-1.3.23-subtitles/rcontroller.c
+--- vdr-1.3.23-vanilla/rcontroller.c 1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.3.23-subtitles/rcontroller.c 2005-03-20 18:04:58.000000000 +0200
+@@ -0,0 +1,82 @@
++#include <stdlib.h>
++#include "rcontroller.h"
++#include <stdio.h>
++#define PRIVATE_STREAM_1 0xBD
++#define PES_EXTENSION_MASK 0x01
++#define PES_EXTENSION2_MASK 0x81
++namespace RecordingPatch {
++
++ cRecordingController RecordingController;
++
++ // Returns the Data Identifier or 0 if not enough data
++ unsigned char GetDataIdentifier( unsigned char* Data, int Length )
++ {
++ if ( Length < 9 )
++ return 0;
++ int hlength = Data[8];
++ if ( Length < 9 + hlength )
++ return 0;
++ return Data[ 9 + hlength - 1 ];
++ }
++
++ cRecordingController::cRecordingController()
++ {
++ listeners = (iRecordingPlugin**)malloc( sizeof(iRecordingPlugin*)*256 );
++ for (int i=0; i < 256; i++)
++ listeners[i] = 0;
++ }
++
++ cRecordingController::~cRecordingController()
++ {
++ free (listeners);
++ }
++ void cRecordingController::Subscribe(unsigned char DataIdentifier, iRecordingPlugin* plugin)
++ {
++ if ( listeners[ DataIdentifier ] == 0 )
++ listeners[ DataIdentifier ] = plugin;
++ }
++ void cRecordingController::Unsubscribe(unsigned char DataIdentifier, iRecordingPlugin* plugin)
++ {
++
++ if ( listeners[ DataIdentifier ] != 0 && listeners[ DataIdentifier ] == plugin )
++ listeners[ DataIdentifier ] = 0;
++
++ }
++
++ bool cRecordingController::isExtendedPacket(unsigned char* Data, int Length)
++ {
++ if ( Length < 9 )
++ return false;
++ if ( Data[0] != 0x00 || Data[1] != 0x00 || Data[2] != 0x01 )
++ return false;
++ if ( Data[3] != PRIVATE_STREAM_1 )
++ return false;
++
++ if ( !(Data[7] & PES_EXTENSION_MASK) )
++ return false;
++
++ int hlength = Data[8];
++
++ if ( ( Data[ 9 + hlength - 3 ] & PES_EXTENSION2_MASK ) == 1
++ && Data[ 9 + hlength - 2 ] == 0x81)
++ return true;
++
++ return false;
++
++ }
++
++
++ void cRecordingController::Receive(unsigned char* Data, int Length)
++ {
++ if ( isExtendedPacket( Data, Length ) )
++ {
++ unsigned char DataIdentifier = GetDataIdentifier( Data, Length );
++ if ( listeners[ DataIdentifier ] != 0 )
++ listeners[ DataIdentifier ] -> Receive( DataIdentifier, Data, Length );
++ }
++ else
++ {
++ }
++ }
++
++} // namespace
+diff -Nru vdr-1.3.23-vanilla/rcontroller.h vdr-1.3.23-subtitles/rcontroller.h
+--- vdr-1.3.23-vanilla/rcontroller.h 1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.3.23-subtitles/rcontroller.h 2005-03-20 18:04:58.000000000 +0200
+@@ -0,0 +1,28 @@
++#ifndef __RECORDING_PATCH_OSD_CONTROLLER_H
++#define __RECORDING_PATCH_OSD_CONTROLLER_H
++
++class cDvbPlayer;
++namespace RecordingPatch {
++
++ class iRecordingPlugin
++ {
++ public:
++ virtual void Receive(unsigned char DataIdentifier, unsigned char* Data, int Length) = 0;
++ };
++
++ class cRecordingController
++ {
++ public:
++ cRecordingController();
++ ~cRecordingController();
++ void Subscribe(unsigned char DataIdentifier, iRecordingPlugin* plugin);
++ void Unsubscribe(unsigned char DataIdentifer, iRecordingPlugin* plugin);
++ bool isExtendedPacket(unsigned char* Data, int Length);
++ void Receive(unsigned char* Data, int Length);
++ private:
++ iRecordingPlugin** listeners;
++ };
++ extern cRecordingController RecordingController;
++
++}
++#endif
+diff -Nru vdr-1.3.23-vanilla/recorder.c vdr-1.3.23-subtitles/recorder.c
+--- vdr-1.3.23-vanilla/recorder.c 2005-03-20 18:03:36.000000000 +0200
++++ vdr-1.3.23-subtitles/recorder.c 2005-03-20 18:04:58.000000000 +0200
+@@ -10,6 +10,7 @@
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <unistd.h>
++#include <stdint.h>
+ #include "recorder.h"
+
+ #define RECORDERBUFSIZE MEGABYTE(5)
+@@ -23,6 +24,7 @@
+
+ class cFileWriter : public cThread {
+ private:
++ cTtxtSubsRecorderBase *ttxtSubsRecorder;
+ cRemux *remux;
+ cFileName *fileName;
+ cIndexFile *index;
+@@ -36,13 +38,14 @@
+ protected:
+ virtual void Action(void);
+ public:
+- cFileWriter(const char *FileName, cRemux *Remux);
++ cFileWriter(const char *FileName, cRemux *Remux, cTtxtSubsRecorderBase *tsr);
+ virtual ~cFileWriter();
+ };
+
+-cFileWriter::cFileWriter(const char *FileName, cRemux *Remux)
++cFileWriter::cFileWriter(const char *FileName, cRemux *Remux, cTtxtSubsRecorderBase *tsr)
+ :cThread("file writer")
+ {
++ ttxtSubsRecorder = tsr;
+ active = false;
+ fileName = NULL;
+ remux = Remux;
+@@ -67,6 +70,8 @@
+ Cancel(3);
+ delete index;
+ delete fileName;
++ if (ttxtSubsRecorder)
++ delete ttxtSubsRecorder;
+ }
+
+ bool cFileWriter::RunningLowOnDiskSpace(void)
+@@ -113,6 +118,16 @@
+ }
+ fileSize += Count;
+ remux->Del(Count);
++ // not sure if the pictureType test is needed, but it seems we can get
++ // incomplete pes packets from remux if we are not getting pictures?
++ if (ttxtSubsRecorder && pictureType != NO_PICTURE) {
++ uint8_t *subsp;
++ size_t len;
++ if (ttxtSubsRecorder->GetPacket(&subsp, &len)) {
++ safe_write(recordFile, subsp, len);
++ fileSize += len;
++ }
++ }
+ }
+ else
+ break;
+@@ -127,7 +142,7 @@
+ active = false;
+ }
+
+-cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids)
++cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, cTtxtSubsRecorderBase *tsr)
+ :cReceiver(Ca, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids)
+ ,cThread("recording")
+ {
+@@ -140,7 +155,7 @@
+ ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, TS_SIZE * 2, true, "Recorder");
+ ringBuffer->SetTimeouts(0, 100);
+ remux = new cRemux(VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids, true);
+- writer = new cFileWriter(FileName, remux);
++ writer = new cFileWriter(FileName, remux, tsr);
+ }
+
+ cRecorder::~cRecorder()
+diff -Nru vdr-1.3.23-vanilla/recorder.h vdr-1.3.23-subtitles/recorder.h
+--- vdr-1.3.23-vanilla/recorder.h 2005-03-20 18:03:36.000000000 +0200
++++ vdr-1.3.23-subtitles/recorder.h 2005-03-20 18:04:58.000000000 +0200
+@@ -15,6 +15,7 @@
+ #include "remux.h"
+ #include "ringbuffer.h"
+ #include "thread.h"
++#include "vdrttxtsubshooks.h"
+
+ class cFileWriter;
+
+@@ -29,7 +30,7 @@
+ virtual void Receive(uchar *Data, int Length);
+ virtual void Action(void);
+ public:
+- cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids);
++ cRecorder(const char *FileName, int Ca, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, cTtxtSubsRecorderBase *tsr);
+ // Creates a new recorder that requires conditional access Ca, has
+ // the given Priority and will record the given PIDs into the file FileName.
+ virtual ~cRecorder();
+diff -Nru vdr-1.3.23-vanilla/remux.c vdr-1.3.23-subtitles/remux.c
+--- vdr-1.3.23-vanilla/remux.c 2005-03-20 18:03:36.000000000 +0200
++++ vdr-1.3.23-subtitles/remux.c 2005-03-20 18:04:58.000000000 +0200
+@@ -391,6 +391,9 @@
+ //pts_dts flags
+ #define PTS_ONLY 0x80
+
++#define PES_EXTENSION 0x01
++#define PES_EXTENSION2 0x01
++
+ #define TS_SIZE 188
+ #define PID_MASK_HI 0x1F
+ #define CONT_CNT_MASK 0x0F
+@@ -435,6 +438,8 @@
+ int ccErrors;
+ int ccCounter;
+ cRepacker *repacker;
++ uint8_t dataIdentifier;
++ static uint8_t eHeadr[];
+ static uint8_t headr[];
+ void store(uint8_t *Data, int Count);
+ void reset_ipack(void);
+@@ -442,16 +447,17 @@
+ void write_ipack(const uint8_t *Data, int Count);
+ void instant_repack(const uint8_t *Buf, int Count);
+ public:
+- cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t AudioCid = 0x00, uint8_t SubStreamId = 0x00, cRepacker *Repacker = NULL);
++ cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t AudioCid = 0x00, uint8_t SubStreamId = 0x00, cRepacker *Repacker = NULL, uint8_t DataIdentifier = 0x00);
+ ~cTS2PES();
+ int Pid(void) { return pid; }
+ void ts_to_pes(const uint8_t *Buf); // don't need count (=188)
+ void Clear(void);
+ };
+
++uint8_t cTS2PES::eHeadr[] = { 0x01, 0x81 }; // extension header
+ uint8_t cTS2PES::headr[] = { 0x00, 0x00, 0x01 };
+
+-cTS2PES::cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t AudioCid, uint8_t SubStreamId, cRepacker *Repacker)
++cTS2PES::cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t AudioCid, uint8_t SubStreamId, cRepacker *Repacker, uint8_t DataIdentifier)
+ {
+ pid = Pid;
+ resultBuffer = ResultBuffer;
+@@ -467,6 +473,7 @@
+ tsErrors = 0;
+ ccErrors = 0;
+ ccCounter = -1;
++ dataIdentifier = DataIdentifier;
+
+ if (!(buf = MALLOC(uint8_t, size)))
+ esyslog("Not enough memory for ts_transform");
+@@ -522,10 +529,21 @@
+
+ switch (mpeg) {
+ case 2:
++ if ( dataIdentifier == 0 ) {
+ buf[6] = 0x80;
+ buf[7] = 0x00;
+ buf[8] = 0x00;
+ count = 9;
++ }
++ else {
++ buf[6] = 0x80;
++ buf[7] = 0x01; // pes_extension_flag == 1
++ buf[8] = 0x03; // pes_header_data_length == 3
++ buf[9] = 0x01; // pes_extension_flag_2=1
++ buf[10]= 0x81; // marker_bit=1, pes_extension_data_length=1
++ buf[11] = dataIdentifier;
++ count = 12;
++ }
+ break;
+ case 1:
+ buf[6] = 0x0F;
+@@ -667,12 +685,21 @@
+ case 7:
+ if (!done && mpeg == 2) {
+ flag2 = Buf[c++];
++ if ( dataIdentifier && (flag2 & PES_EXTENSION) ) {
++ esyslog("Error: cannot add extension to pes packet. Disabling.");
++ dataIdentifier = 0;
++ }
++ else {
++ flag2 |= PES_EXTENSION;
++ }
+ found++;
+ }
+ break;
+ case 8:
+ if (!done && mpeg == 2) {
+ hlength = Buf[c++];
++ if ( dataIdentifier )
++ hlength += 3;
+ found++;
+ }
+ break;
+@@ -709,6 +736,20 @@
+ return;
+ }
+
++ // Write header one byte at a time
++ // Remove from hlength size of our header (3)
++ if ( dataIdentifier ) {
++ while (c < Count && (found < (hlength + 9-3)) && found < plength+6) {
++ write_ipack(Buf + c, 1);
++ c++;
++ found++;
++ }
++ if (found == (hlength+9-3)) {
++ write_ipack(eHeadr, 2);
++ write_ipack(&dataIdentifier, 1);
++ }
++ }
++
+ while (c < Count && found < plength + 6) {
+ int l = Count - c;
+ if (l + found > plength + 6)
+@@ -812,13 +853,11 @@
+ while (*DPids && numTracks < MAXTRACKS && n < MAXDPIDS)
+ ts2pes[numTracks++] = new cTS2PES(*DPids++, resultBuffer, IPACKS, 0x00, 0x80 + n++, new cDolbyRepacker);
+ }
+- /* future...
+ if (SPids) {
+ int n = 0;
+ while (*SPids && numTracks < MAXTRACKS && n < MAXSPIDS)
+- ts2pes[numTracks++] = new cTS2PES(*SPids++, resultBuffer, IPACKS, 0x00, 0x28 + n++);
++ ts2pes[numTracks++] = new cTS2PES(*SPids++, resultBuffer, IPACKS, 0x00, 0x00, NULL, 0x28 + n++);
+ }
+- */
+ }
+
+ cRemux::~cRemux()
+diff -Nru vdr-1.3.23-vanilla/vdrttxtsubshooks.c vdr-1.3.23-subtitles/vdrttxtsubshooks.c
+--- vdr-1.3.23-vanilla/vdrttxtsubshooks.c 1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.3.23-subtitles/vdrttxtsubshooks.c 2005-03-20 18:04:58.000000000 +0200
+@@ -0,0 +1,44 @@
++
++#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)
++ { if(gListener) gListener->PlayerTeletextData(p, length); };
++ virtual cTtxtSubsRecorderBase *NewTtxtSubsRecorder(cDevice *dev, const cChannel *ch)
++ { if(gListener) return gListener->NewTtxtSubsRecorder(dev, ch); else return NULL; };
++};
++
++
++// ------ 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 -Nru vdr-1.3.23-vanilla/vdrttxtsubshooks.h vdr-1.3.23-subtitles/vdrttxtsubshooks.h
+--- vdr-1.3.23-vanilla/vdrttxtsubshooks.h 1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.3.23-subtitles/vdrttxtsubshooks.h 2005-03-20 18:04:58.000000000 +0200
+@@ -0,0 +1,36 @@
++
++#ifndef __VDRTTXTSUBSHOOKS_H
++#define __VDRTTXTSUBSHOOKS_H
++
++class cDevice;
++class cChannel;
++
++#define VDRTTXTSUBSHOOKS
++
++class cTtxtSubsRecorderBase {
++ public:
++ virtual ~cTtxtSubsRecorderBase() {};
++
++ // returns a PES packet if there is data to add to the recording
++ virtual uint8_t *GetPacket(uint8_t **buf, size_t *len) { return NULL; };
++ virtual void DeviceAttach(void) {};
++};
++
++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) {};
++ virtual cTtxtSubsRecorderBase *NewTtxtSubsRecorder(cDevice *dev, const cChannel *ch)
++ { return NULL; };
++
++ // used by VDR to call hook listeners
++ static cVDRTtxtsubsHookListener *Hook(void);
++};
++
++#endif
Property changes on: vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch
___________________________________________________________________
Name: svn:executable
+ *
Deleted: vdr/vdr/trunk/debian/patches/opt-21_ttxtsubs.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/opt-21_ttxtsubs.dpatch 2005-04-18 14:45:05 UTC (rev 478)
+++ vdr/vdr/trunk/debian/patches/opt-21_ttxtsubs.dpatch 2005-04-18 22:29:29 UTC (rev 479)
@@ -1,349 +0,0 @@
-#!/bin/sh /usr/share/dpatch/dpatch-run
-
-## ttxtsubs patch from ttxtsubs plugin 0.0.5
-## Ragnar Sundblad <ragge@nada.kth.se>
-## http://www.nada.kth.se/~ragge/vdr/ttxtsubs/
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: This patch is needed for the ttxtsubs plugin
-
-@DPATCH@
-diff -Nur vdr.orig/dvbplayer.c vdr/dvbplayer.c
---- vdr.orig/dvbplayer.c 2004-06-26 03:03:47.000000000 +0200
-+++ vdr/dvbplayer.c 2004-06-26 03:04:12.000000000 +0200
-@@ -14,6 +14,7 @@
- #include "ringbuffer.h"
- #include "thread.h"
- #include "tools.h"
-+#include "vdrttxtsubshooks.h"
-
- // --- cBackTrace ----------------------------------------------------------
-
-@@ -323,6 +324,12 @@
- int l = b[i + 4] * 256 + b[i + 5] + 6;
- switch (c) {
- case 0xBD: // dolby
-+#ifdef VDRTTXTSUBSHOOKS
-+ if (b[i + 8] == 0x24 && b[i + 45] >= 0x10 && b[i + 45] < 0x20) {
-+ break; // run these through the ring buffer to get somewhat correct
-+ // timing for the subtitles
-+ } else
-+#endif
- if (Except)
- PlayAudio(&b[i], l);
- // continue with deleting the data - otherwise it disturbs DVB replay
-@@ -349,6 +356,40 @@
- }
- }
-
-+#ifdef VDRTTXTSUBSHOOKS
-+static void StripTtxtPackets(uchar *b, int Length)
-+{
-+ for (int i = 0; i < Length - 6; i++) {
-+ if (b[i] == 0x00 && b[i + 1] == 0x00 && b[i + 2] == 0x01) {
-+ uchar c = b[i + 3];
-+ int l = b[i + 4] * 256 + b[i + 5] + 6;
-+ switch (c) {
-+ case 0xBD: // dolby
-+ {
-+ if (b[i + 8] == 0x24 && b[i + 45] >= 0x10 && b[i + 45] < 0x20) {
-+ // EBU Teletext data, ETSI EN 300 472
-+ cVDRTtxtsubsHookListener::Hook()->PlayerTeletextData(&b[i], l);
-+ }
-+ // continue with deleting the data - otherwise it disturbs DVB replay
-+ int n = l;
-+ for (int j = i; j < Length && n--; j++)
-+ b[j] = 0x00;
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+ if (l)
-+ i += l - 1; // the loop increments, too!
-+ }
-+ /*XXX
-+ else
-+ esyslog("ERROR: broken packet header");
-+ XXX*/
-+ }
-+}
-+#endif
-+
- bool cDvbPlayer::NextFile(uchar FileNumber, int FileOffset)
- {
- if (FileNumber > 0)
-@@ -524,6 +565,11 @@
- StripAudioPackets(p, pc, AudioTrack);
- }
- }
-+#ifdef VDRTTXTSUBSHOOKS
-+ // pick out the teletext packets here
-+ if(p)
-+ StripTtxtPackets((uchar *) p, pc);
-+#endif
- if (p) {
- int w = PlayVideo(p, pc);
- if (w > 0) {
-diff -Nur vdr.orig/Makefile vdr/Makefile
---- vdr.orig/Makefile 2004-06-26 03:03:47.000000000 +0200
-+++ vdr/Makefile 2004-06-26 03:04:12.000000000 +0200
-@@ -37,7 +37,8 @@
- dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o interface.o keys.o\
- lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o\
- receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sources.o\
-- spu.o status.o svdrp.o thread.o timers.o tools.o transfer.o vdr.o videodir.o
-+ spu.o status.o svdrp.o thread.o timers.o tools.o transfer.o vdr.o videodir.o\
-+ vdrttxtsubshooks.o
-
- OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
- FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
-diff -Nur vdr.orig/menu.c vdr/menu.c
---- vdr.orig/menu.c 2004-06-26 03:03:47.000000000 +0200
-+++ vdr/menu.c 2004-06-26 03:04:12.000000000 +0200
-@@ -4103,8 +4103,18 @@
- isyslog("record %s", fileName);
- if (MakeDirs(fileName, true)) {
- const cChannel *ch = timer->Channel();
-+#ifdef VDRTTXTSUBSHOOKS
-+ cTtxtSubsRecorderBase *subsRecorder = cVDRTtxtsubsHookListener::Hook()
-+ ->NewTtxtSubsRecorder(device, ch);
-+ recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2(), subsRecorder);
-+#else
- recorder = new cRecorder(fileName, ch->Ca(), timer->Priority(), ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2());
-+#endif
- if (device->AttachReceiver(recorder)) {
-+#ifdef VDRTTXTSUBSHOOKS
-+ if(subsRecorder)
-+ subsRecorder->DeviceAttach();
-+#endif
- Recording.WriteSummary();
- cStatus::MsgRecording(device, Recording.Name());
- if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
-diff -Nur vdr.orig/menu.h vdr/menu.h
---- vdr.orig/menu.h 2004-06-26 03:03:47.000000000 +0200
-+++ vdr/menu.h 2004-06-26 03:04:12.000000000 +0200
-@@ -14,6 +14,7 @@
- #include "device.h"
- #include "osd.h"
- #include "dvbplayer.h"
-+#include "vdrttxtsubshooks.h"
- #include "recorder.h"
- #include "recording.h"
- #include "theme.h"
-diff -Nur vdr.orig/osd.c vdr/osd.c
---- vdr.orig/osd.c 2004-06-26 03:03:47.000000000 +0200
-+++ vdr/osd.c 2004-06-26 03:04:12.000000000 +0200
-@@ -13,6 +13,7 @@
- #include "i18n.h"
- #include "status.h"
- #include "theme.h"
-+#include "vdrttxtsubshooks.h"
-
- // --- cOsd ------------------------------------------------------------------
-
-@@ -64,6 +65,10 @@
-
- cOsdBase *cOsd::OpenRaw(int x, int y)
- {
-+#ifdef VDRTTXTSUBSHOOKS
-+ // OSD_HOOK_2 - Information to Checkpatch.sh
-+ cVDRTtxtsubsHookListener::Hook()->HideOSD();
-+#endif
- #ifdef DEBUG_OSD
- return NULL;
- #else
-@@ -153,6 +158,9 @@
- delete osd;
- osd = NULL;
- #endif
-+#ifdef VDRTTXTSUBSHOOKS
-+ cVDRTtxtsubsHookListener::Hook()->ShowOSD();
-+#endif
- }
-
- void cOsd::Clear(void)
-diff -Nur vdr.orig/recorder.c vdr/recorder.c
---- vdr.orig/recorder.c 2004-06-26 03:03:47.000000000 +0200
-+++ vdr/recorder.c 2004-06-26 03:04:12.000000000 +0200
-@@ -10,6 +10,8 @@
- #include <stdarg.h>
- #include <stdio.h>
- #include <unistd.h>
-+#include <stdint.h>
-+#include "vdrttxtsubshooks.h"
- #include "recorder.h"
-
- // The size of the array used to buffer video data:
-@@ -23,7 +25,11 @@
- #define MINFREEDISKSPACE (512) // MB
- #define DISKCHECKINTERVAL 100 // seconds
-
-+#ifdef VDRTTXTSUBSHOOKS
-+cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2, cTtxtSubsRecorderBase *tsr)
-+#else
- cRecorder::cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2)
-+#endif
- :cReceiver(Ca, Priority, 5, VPid, APid1, APid2, DPid1, DPid2)
- {
- ringBuffer = NULL;
-@@ -34,6 +40,9 @@
- fileSize = 0;
- active = false;
- lastDiskSpaceCheck = time(NULL);
-+#ifdef VDRTTXTSUBSHOOKS
-+ ttxtSubsRecorder = tsr;
-+#endif
-
- // Make sure the disk is up and running:
-
-@@ -55,6 +64,10 @@
- cRecorder::~cRecorder()
- {
- Detach();
-+#ifdef VDRTTXTSUBSHOOKS
-+ if(ttxtSubsRecorder)
-+ delete ttxtSubsRecorder;
-+#endif
- delete index;
- delete fileName;
- delete remux;
-@@ -129,6 +142,19 @@
- break;
- }
- fileSize += Result;
-+#ifdef VDRTTXTSUBSHOOKS
-+ // not sure if the pictureType test is needed, but it seems we can get
-+ // incomplete pes packets from remux if we are not getting pictures?
-+ if (ttxtSubsRecorder && pictureType != NO_PICTURE) {
-+ uint8_t *subsp;
-+ size_t len;
-+ if(ttxtSubsRecorder->GetPacket(&subsp, &len)) {
-+ safe_write(recordFile, subsp, len);
-+ fileSize += len;
-+ // fprintf(stderr, "cRecorder::Action: Wrote ttxtsubs data len %d\n", len); // XXX
-+ }
-+ }
-+#endif
- }
- else
- break;
-diff -Nur vdr.orig/recorder.h vdr/recorder.h
---- vdr.orig/recorder.h 2004-06-26 00:32:34.000000000 +0200
-+++ vdr/recorder.h 2004-06-26 03:04:12.000000000 +0200
-@@ -15,6 +15,7 @@
- #include "remux.h"
- #include "ringbuffer.h"
- #include "thread.h"
-+#include "vdrttxtsubshooks.h"
-
- class cRecorder : public cReceiver, cThread {
- private:
-@@ -29,12 +30,19 @@
- time_t lastDiskSpaceCheck;
- bool RunningLowOnDiskSpace(void);
- bool NextFile(void);
-+#ifdef VDRTTXTSUBSHOOKS
-+ cTtxtSubsRecorderBase *ttxtSubsRecorder;
-+#endif
- protected:
- virtual void Activate(bool On);
- virtual void Receive(uchar *Data, int Length);
- virtual void Action(void);
- public:
-+#ifdef VDRTTXTSUBSHOOKS
-+ cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2, cTtxtSubsRecorderBase *tsr);
-+#else
- cRecorder(const char *FileName, int Ca, int Priority, int VPid, int APid1, int APid2, int DPid1, int DPid2);
-+#endif
- // Creates a new recorder that requires conditional access Ca, has
- // the given Priority and will record the given PIDs into the file FileName.
- virtual ~cRecorder();
-diff -Nur vdr.orig/vdrttxtsubshooks.c vdr/vdrttxtsubshooks.c
---- vdr.orig/vdrttxtsubshooks.c 1970-01-01 01:00:00.000000000 +0100
-+++ vdr/vdrttxtsubshooks.c 2004-03-01 23:53:17.000000000 +0100
-@@ -0,0 +1,44 @@
-+
-+#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)
-+ { if(gListener) gListener->PlayerTeletextData(p, length); };
-+ virtual cTtxtSubsRecorderBase *NewTtxtSubsRecorder(cDevice *dev, const cChannel *ch)
-+ { if(gListener) return gListener->NewTtxtSubsRecorder(dev, ch); else return NULL; };
-+};
-+
-+
-+// ------ 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 -Nur vdr.orig/vdrttxtsubshooks.h vdr/vdrttxtsubshooks.h
---- vdr.orig/vdrttxtsubshooks.h 1970-01-01 01:00:00.000000000 +0100
-+++ vdr/vdrttxtsubshooks.h 2004-03-01 23:53:17.000000000 +0100
-@@ -0,0 +1,36 @@
-+
-+#ifndef __VDRTTXTSUBSHOOKS_H
-+#define __VDRTTXTSUBSHOOKS_H
-+
-+class cDevice;
-+class cChannel;
-+
-+#define VDRTTXTSUBSHOOKS
-+
-+class cTtxtSubsRecorderBase {
-+ public:
-+ virtual ~cTtxtSubsRecorderBase() {};
-+
-+ // returns a PES packet if there is data to add to the recording
-+ virtual uint8_t *GetPacket(uint8_t **buf, size_t *len) { return NULL; };
-+ virtual void DeviceAttach(void) {};
-+};
-+
-+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) {};
-+ virtual cTtxtSubsRecorderBase *NewTtxtSubsRecorder(cDevice *dev, const cChannel *ch)
-+ { return NULL; };
-+
-+ // used by VDR to call hook listeners
-+ static cVDRTtxtsubsHookListener *Hook(void);
-+};
-+
-+#endif