r3598 - in vdr/vdr/trunk/debian: . patches

Tobias Grimm tiber-guest at alioth.debian.org
Sat Nov 4 21:21:43 CET 2006


Author: tiber-guest
Date: 2006-11-04 21:21:43 +0100 (Sat, 04 Nov 2006)
New Revision: 3598

Added:
   vdr/vdr/trunk/debian/patches/opt-27_subtitles-ttxtsubs.dpatch
Removed:
   vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch
Modified:
   vdr/vdr/trunk/debian/changelog
   vdr/vdr/trunk/debian/patches/00list
Log:
* New upstream release
* Renamed and updated optional subtitles-ttxtsubs example patch


Modified: vdr/vdr/trunk/debian/changelog
===================================================================
--- vdr/vdr/trunk/debian/changelog	2006-11-04 14:57:25 UTC (rev 3597)
+++ vdr/vdr/trunk/debian/changelog	2006-11-04 20:21:43 UTC (rev 3598)
@@ -1,3 +1,10 @@
+vdr (1.4.4-1) UNRELEASED; urgency=low
+
+  * (NOT RELEASED YET) New upstream release
+  * Renamed and updated optional subtitles-ttxtsubs example patch
+
+ -- Tobias Grimm <tg at e-tobi.net>  Sat,  4 Nov 2006 21:19:39 +0100
+
 vdr (1.4.3-1) unstable; urgency=low
 
   * New upstream release

Modified: vdr/vdr/trunk/debian/patches/00list
===================================================================
--- vdr/vdr/trunk/debian/patches/00list	2006-11-04 14:57:25 UTC (rev 3597)
+++ vdr/vdr/trunk/debian/patches/00list	2006-11-04 20:21:43 UTC (rev 3598)
@@ -10,8 +10,8 @@
 15_dvbplayer
 16_channels.conf.terr-fix
 
-# Patch needed for DVB subtitles or ttxtsubs (does not work with AC3-patch)
-# opt-21_subtitles_and_ttxtsubs
+# The Jump patch allows automatic jumping over cutting marks.
+# opt-24_jumpplay
 
-# The Jump patch allows automatic jumping over cutting marks.
-# opt-24_jumpplay-0.9
+# Patch needed for the subtitles and the ttxtsubs plugin.
+# opt-27_subtitles-ttxtsubs

Deleted: vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch
===================================================================
--- vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch	2006-11-04 14:57:25 UTC (rev 3597)
+++ vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch	2006-11-04 20:21:43 UTC (rev 3598)
@@ -1,846 +0,0 @@
-#!/bin/sh /usr/share/dpatch/dpatch-run
-
-## opt-20_subtitles_and_ttxtsubs.dpatch by Rolf Ahrenberg <rahrenbe at 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.
-
- at 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

Copied: vdr/vdr/trunk/debian/patches/opt-27_subtitles-ttxtsubs.dpatch (from rev 3425, vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch)
===================================================================
--- vdr/vdr/trunk/debian/patches/opt-21_subtitles_and_ttxtsubs.dpatch	2006-09-23 19:57:46 UTC (rev 3425)
+++ vdr/vdr/trunk/debian/patches/opt-27_subtitles-ttxtsubs.dpatch	2006-11-04 20:21:43 UTC (rev 3598)
@@ -0,0 +1,865 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## opt-27_subtitles-ttxtsubs.dpatch by Rolf Ahrenberg <Rolf.Ahrenberg AT sci.fi>
+## http://www.saunalahti.fi/~rahrenbe/vdr/patches/vdr-1.4.1-subtitles-0.4.0-and-ttxtsubs-0.0.5.diff.gz
+##
+## Thomas Günther <tom at toms-cafe.de>:
+##   - adapted to dd-record-option patch (UseDolbyDigital -> RecordDolbyDigital)
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: This patch is needed for the subtitles and ttxtsubs plugin.
+
+ at DPATCH@
+diff -Nru vdr-1.4.1-vanilla/Makefile vdr-1.4.1-subtitles/Makefile
+--- vdr-1.4.1-vanilla/Makefile	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/Makefile	2006-06-11 13:19:10.000000000 +0300
+@@ -39,6 +39,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.4.1-vanilla/dvbplayer.c vdr-1.4.1-subtitles/dvbplayer.c
+--- vdr-1.4.1-vanilla/dvbplayer.c	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/dvbplayer.c	2006-06-11 13:19:10.000000000 +0300
+@@ -14,6 +14,9 @@
+ #include "ringbuffer.h"
+ #include "thread.h"
+ #include "tools.h"
++#include "rcontroller.h"
++#include "dvbsub.h"
++#include "vdrttxtsubshooks.h"
+ 
+ // --- cBackTrace ------------------------------------------------------------
+ 
+@@ -312,6 +315,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)
+@@ -495,6 +531,7 @@
+                     }
+                  }
+               if (p) {
++                 StripExtendedPackets(p, pc);
+                  int w = PlayPes(p, pc, playMode != pmPlay);
+                  if (w > 0) {
+                     p += w;
+diff -Nru vdr-1.4.1-vanilla/dvbsub.c vdr-1.4.1-subtitles/dvbsub.c
+--- vdr-1.4.1-vanilla/dvbsub.c	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.4.1-subtitles/dvbsub.c	2006-06-11 13:19:10.000000000 +0300
+@@ -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.4.1-vanilla/dvbsub.h vdr-1.4.1-subtitles/dvbsub.h
+--- vdr-1.4.1-vanilla/dvbsub.h	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.4.1-subtitles/dvbsub.h	2006-06-11 13:19:10.000000000 +0300
+@@ -0,0 +1,22 @@
++class cChannel;
++class cRecordControl;
++
++class iPidQuery
++{
++public:
++  virtual ~iPidQuery() {};
++  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.4.1-vanilla/menu.c vdr-1.4.1-subtitles/menu.c
+--- vdr-1.4.1-vanilla/menu.c	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/menu.c	2006-06-11 13:19:10.000000000 +0300
+@@ -27,6 +27,8 @@
+ #include "themes.h"
+ #include "timers.h"
+ #include "transfer.h"
++#include "vdrttxtsubshooks.h"
++#include "dvbsub.h"
+ #include "videodir.h"
+ 
+ #define MAXWAIT4EPGINFO   3 // seconds
+@@ -3540,8 +3542,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.WriteInfo();
+         cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true);
+         if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
+diff -Nru vdr-1.4.1-vanilla/osd.c vdr-1.4.1-subtitles/osd.c
+--- vdr-1.4.1-vanilla/osd.c	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/osd.c	2006-06-11 13:19:10.000000000 +0300
+@@ -14,6 +14,8 @@
+ #include <sys/stat.h>
+ #include <sys/unistd.h>
+ #include "tools.h"
++#include "osdcontroller.h"
++#include "vdrttxtsubshooks.h"
+ 
+ // --- cPalette --------------------------------------------------------------
+ 
+@@ -594,6 +596,7 @@
+ // --- cOsd ------------------------------------------------------------------
+ 
+ int cOsd::isOpen = 0;
++bool cOsd::niosd  = false;
+ 
+ cOsd::cOsd(int Left, int Top)
+ {
+@@ -613,6 +616,9 @@
+       delete bitmaps[i];
+   delete savedRegion;
+   isOpen--;
++  if (!niosd)
++     NonInteractiveOsdPatch::OsdController.Show();
++  cVDRTtxtsubsHookListener::Hook()->ShowOSD();
+ }
+ 
+ cBitmap *cOsd::GetBitmap(int Area)
+@@ -736,8 +742,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.4.1-vanilla/osd.h vdr-1.4.1-subtitles/osd.h
+--- vdr-1.4.1-vanilla/osd.h	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/osd.h	2006-06-11 13:19:10.000000000 +0300
+@@ -222,6 +222,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.
+@@ -337,7 +339,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.4.1-vanilla/osdcontroller.c vdr-1.4.1-subtitles/osdcontroller.c
+--- vdr-1.4.1-vanilla/osdcontroller.c	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.4.1-subtitles/osdcontroller.c	2006-06-11 13:19:10.000000000 +0300
+@@ -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.4.1-vanilla/osdcontroller.h vdr-1.4.1-subtitles/osdcontroller.h
+--- vdr-1.4.1-vanilla/osdcontroller.h	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.4.1-subtitles/osdcontroller.h	2006-06-11 13:19:10.000000000 +0300
+@@ -0,0 +1,52 @@
++#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 ~cOsdListener() {};
++    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.4.1-vanilla/rcontroller.c vdr-1.4.1-subtitles/rcontroller.c
+--- vdr-1.4.1-vanilla/rcontroller.c	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.4.1-subtitles/rcontroller.c	2006-06-11 13:19:10.000000000 +0300
+@@ -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.4.1-vanilla/rcontroller.h vdr-1.4.1-subtitles/rcontroller.h
+--- vdr-1.4.1-vanilla/rcontroller.h	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.4.1-subtitles/rcontroller.h	2006-06-11 13:19:10.000000000 +0300
+@@ -0,0 +1,29 @@
++#ifndef __RECORDING_PATCH_OSD_CONTROLLER_H
++#define __RECORDING_PATCH_OSD_CONTROLLER_H
++
++class cDvbPlayer;
++namespace RecordingPatch {
++
++  class iRecordingPlugin
++  {
++  public:
++    virtual ~iRecordingPlugin() {};
++    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.4.1-vanilla/recorder.c vdr-1.4.1-subtitles/recorder.c
+--- vdr-1.4.1-vanilla/recorder.c	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/recorder.c	2006-06-11 13:19:10.000000000 +0300
+@@ -11,6 +11,7 @@
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <unistd.h>
++#include <stdint.h>
+ 
+ #define RECORDERBUFSIZE  MEGABYTE(5)
+ 
+@@ -23,6 +24,7 @@
+ 
+ class cFileWriter : public cThread {
+ private:
++  cTtxtSubsRecorderBase *ttxtSubsRecorder;
+   cRemux *remux;
+   cFileName *fileName;
+   cIndexFile *index;
+@@ -35,13 +37,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;
+   fileName = NULL;
+   remux = Remux;
+   index = NULL;
+@@ -64,6 +67,8 @@
+   Cancel(3);
+   delete index;
+   delete fileName;
++  if (ttxtSubsRecorder)
++     delete ttxtSubsRecorder;
+ }
+ 
+ bool cFileWriter::RunningLowOnDiskSpace(void)
+@@ -108,6 +113,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)) {
++                    recordFile->Write(subsp, len);
++                    fileSize += len;
++                    }
++                 }
+               }
+            else
+               break;
+@@ -121,7 +136,7 @@
+         }
+ }
+ 
+-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.RecordDolbyDigital ? DPids : NULL, SPids)
+ ,cThread("recording")
+ {
+@@ -132,7 +147,7 @@
+   ringBuffer = new cRingBufferLinear(RECORDERBUFSIZE, TS_SIZE * 2, true, "Recorder");
+   ringBuffer->SetTimeouts(0, 100);
+   remux = new cRemux(VPid, APids, Setup.RecordDolbyDigital ? DPids : NULL, SPids, true);
+-  writer = new cFileWriter(FileName, remux);
++  writer = new cFileWriter(FileName, remux, tsr);
+ }
+ 
+ cRecorder::~cRecorder()
+diff -Nru vdr-1.4.1-vanilla/recorder.h vdr-1.4.1-subtitles/recorder.h
+--- vdr-1.4.1-vanilla/recorder.h	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/recorder.h	2006-06-11 13:19:10.000000000 +0300
+@@ -15,6 +15,7 @@
+ #include "remux.h"
+ #include "ringbuffer.h"
+ #include "thread.h"
++#include "vdrttxtsubshooks.h"
+ 
+ class cFileWriter;
+ 
+@@ -28,7 +29,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.4.1-vanilla/remux.c vdr-1.4.1-subtitles/remux.c
+--- vdr-1.4.1-vanilla/remux.c	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/remux.c	2006-06-11 13:19:10.000000000 +0300
+@@ -1413,6 +1413,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
+@@ -1461,6 +1464,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);
+@@ -1468,16 +1473,18 @@
+   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 RewriteCid = 0x00, uint8_t SubStreamId = 0x00, cRepacker *Repacker = NULL);
++  cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t RewriteCid = 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 RewriteCid, uint8_t SubStreamId, cRepacker *Repacker)
++cTS2PES::cTS2PES(int Pid, cRingBufferLinear *ResultBuffer, int Size, uint8_t RewriteCid, uint8_t SubStreamId, cRepacker *Repacker, uint8_t DataIdentifier)
+ {
+   pid = Pid;
+   resultBuffer = ResultBuffer;
+@@ -1494,6 +1501,7 @@
+   tsErrors = 0;
+   ccErrors = 0;
+   ccCounter = -1;
++  dataIdentifier = DataIdentifier;
+ 
+   if (!(buf = MALLOC(uint8_t, size)))
+      esyslog("Not enough memory for ts_transform");
+@@ -1551,10 +1559,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;
+@@ -1717,12 +1736,21 @@
+           case 7:
+                   if (!done && (mpeg == 2 || mpeg1_required > 7)) {
+                      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 || mpeg1_required > 7)) {
+                      hlength = Buf[c++];
++                     if ( dataIdentifier )
++                        hlength += 3;
+                      found++;
+                      if (mpeg == 1 && hlength != 0x0F && (hlength & 0xF0) != 0x20 && (hlength & 0xF0) != 0x30)
+                         found = 0; // invalid MPEG1 header
+@@ -1766,6 +1794,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)
+@@ -1888,13 +1930,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.4.1-vanilla/vdr.c vdr-1.4.1-subtitles/vdr.c
+--- vdr-1.4.1-vanilla/vdr.c	2006-06-11 13:17:40.000000000 +0300
++++ vdr-1.4.1-subtitles/vdr.c	2006-06-11 13:19:10.000000000 +0300
+@@ -960,7 +960,7 @@
+                   }
+                else
+                   cDevice::PrimaryDevice()->SetVolume(NORMALKEY(key) == kVolDn ? -VOLUMEDELTA : VOLUMEDELTA);
+-               if (!Menu && !cOsd::IsOpen())
++               if (!Menu /*&& !cOsd::IsOpen()*/)
+                   Menu = cDisplayVolume::Create();
+                cDisplayVolume::Process(key);
+                key = kNone; // nobody else needs to see these keys
+diff -Nru vdr-1.4.1-vanilla/vdrttxtsubshooks.c vdr-1.4.1-subtitles/vdrttxtsubshooks.c
+--- vdr-1.4.1-vanilla/vdrttxtsubshooks.c	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.4.1-subtitles/vdrttxtsubshooks.c	2006-06-11 13:19:10.000000000 +0300
+@@ -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.4.1-vanilla/vdrttxtsubshooks.h vdr-1.4.1-subtitles/vdrttxtsubshooks.h
+--- vdr-1.4.1-vanilla/vdrttxtsubshooks.h	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.4.1-subtitles/vdrttxtsubshooks.h	2006-06-11 13:19:10.000000000 +0300
+@@ -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




More information about the pkg-vdr-dvb-changes mailing list