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