#!/bin/sh /usr/share/dpatch/dpatch-run ## subtitles-ttxtsubs patch - for vdr-1.3.20 - subtitles-0.3.6/ttxtsubs-0.0.5 ## ## downloaded from http://www.saunalahti.fi/~rahrenbe/vdr/patches/ ## original filename vdr-1.3.20-subtitles-0.3.6-and-ttxtsubs-0.0.5.diff.gz ## ## integrated fix for ac3 playback from tbf at vdrportal.de ## (http://www.vdr-portal.de/board/thread.php?postid=168833#post168833) ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: This patch is needed for the subtitles and ttxtsubs plugin. @DPATCH@ diff -Nru vdr-1.3.20-vanilla/Makefile vdr-1.3.20-subtitles/Makefile --- vdr-1.3.20-vanilla/Makefile 2004-12-18 15:39:19.000000000 +0200 +++ vdr-1.3.20-subtitles/Makefile 2005-02-06 17:47:56.457728888 +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.20-vanilla/dvbplayer.c vdr-1.3.20-subtitles/dvbplayer.c --- vdr-1.3.20-vanilla/dvbplayer.c 2005-01-14 16:00:56.000000000 +0200 +++ vdr-1.3.20-subtitles/dvbplayer.c 2005-02-06 17:47:56.460728432 +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,36 @@ 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 ); + // EBU Teletext data, ETSI EN 300 472 + 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 +504,7 @@ } } if (p) { + StripExtendedPackets(p, pc); int w = PlayPes(p, pc, playMode != pmPlay); if (w > 0) { p += w; diff -Nru vdr-1.3.20-vanilla/dvbsub.c vdr-1.3.20-subtitles/dvbsub.c --- vdr-1.3.20-vanilla/dvbsub.c 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.3.20-subtitles/dvbsub.c 2005-02-06 17:47:56.461728280 +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.20-vanilla/dvbsub.h vdr-1.3.20-subtitles/dvbsub.h --- vdr-1.3.20-vanilla/dvbsub.h 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.3.20-subtitles/dvbsub.h 2005-02-06 17:47:56.462728128 +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.20-vanilla/menu.c vdr-1.3.20-subtitles/menu.c --- vdr-1.3.20-vanilla/menu.c 2005-02-06 13:33:13.000000000 +0200 +++ vdr-1.3.20-subtitles/menu.c 2005-02-06 17:47:56.470726912 +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 @@ -3018,8 +3020,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.20-vanilla/osd.c vdr-1.3.20-subtitles/osd.c --- vdr-1.3.20-vanilla/osd.c 2004-12-19 14:27:38.000000000 +0200 +++ vdr-1.3.20-subtitles/osd.c 2005-02-06 17:47:56.473726456 +0200 @@ -15,6 +15,8 @@ #include #include #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.20-vanilla/osd.h vdr-1.3.20-subtitles/osd.h --- vdr-1.3.20-vanilla/osd.h 2004-10-16 13:33:44.000000000 +0300 +++ vdr-1.3.20-subtitles/osd.h 2005-02-06 17:47:56.476726000 +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.20-vanilla/osdcontroller.c vdr-1.3.20-subtitles/osdcontroller.c --- vdr-1.3.20-vanilla/osdcontroller.c 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.3.20-subtitles/osdcontroller.c 2005-02-06 17:47:56.477725848 +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; + } + + 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.20-vanilla/osdcontroller.h vdr-1.3.20-subtitles/osdcontroller.h --- vdr-1.3.20-vanilla/osdcontroller.h 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.3.20-subtitles/osdcontroller.h 2005-02-06 17:47:56.478725696 +0200 @@ -0,0 +1,50 @@ +#ifndef __OSDCONTROLLER_H +#define __OSDCONTROLLER_H + +#include "tools.h" + + +#define MAX_OSD_LISTENERS 10 + +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* iListeners; + + }; + extern cOsdController OsdController; + +} +#endif diff -Nru vdr-1.3.20-vanilla/rcontroller.c vdr-1.3.20-subtitles/rcontroller.c --- vdr-1.3.20-vanilla/rcontroller.c 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.3.20-subtitles/rcontroller.c 2005-02-06 17:47:56.480725392 +0200 @@ -0,0 +1,82 @@ +#include +#include "rcontroller.h" +#include +#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.20-vanilla/rcontroller.h vdr-1.3.20-subtitles/rcontroller.h --- vdr-1.3.20-vanilla/rcontroller.h 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.3.20-subtitles/rcontroller.h 2005-02-06 17:47:56.481725240 +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.20-vanilla/recorder.c vdr-1.3.20-subtitles/recorder.c --- vdr-1.3.20-vanilla/recorder.c 2005-01-16 14:53:17.000000000 +0200 +++ vdr-1.3.20-subtitles/recorder.c 2005-02-06 17:47:56.483724936 +0200 @@ -10,6 +10,7 @@ #include #include #include +#include #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.20-vanilla/recorder.h vdr-1.3.20-subtitles/recorder.h --- vdr-1.3.20-vanilla/recorder.h 2005-01-15 18:35:53.000000000 +0200 +++ vdr-1.3.20-subtitles/recorder.h 2005-02-06 17:47:56.485724632 +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.20-vanilla/remux.c vdr-1.3.20-subtitles/remux.c --- vdr-1.3.20-vanilla/remux.c 2005-02-05 13:56:42.000000000 +0200 +++ vdr-1.3.20-subtitles/remux.c 2005-02-06 17:47:56.492723568 +0200 @@ -380,6 +380,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 @@ -424,6 +427,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); @@ -431,16 +436,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; @@ -456,6 +462,7 @@ tsErrors = 0; ccErrors = 0; ccCounter = -1; + dataIdentifier = DataIdentifier; if (!(buf = MALLOC(uint8_t, size))) esyslog("Not enough memory for ts_transform"); @@ -509,10 +516,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; @@ -654,12 +672,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; @@ -696,6 +723,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) @@ -799,13 +840,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.20-vanilla/vdrttxtsubshooks.c vdr-1.3.20-subtitles/vdrttxtsubshooks.c --- vdr-1.3.20-vanilla/vdrttxtsubshooks.c 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.3.20-subtitles/vdrttxtsubshooks.c 2005-02-06 17:47:56.494723264 +0200 @@ -0,0 +1,44 @@ + +#include +#include +#include + +#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.20-vanilla/vdrttxtsubshooks.h vdr-1.3.20-subtitles/vdrttxtsubshooks.h --- vdr-1.3.20-vanilla/vdrttxtsubshooks.h 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.3.20-subtitles/vdrttxtsubshooks.h 2005-02-06 17:47:56.495723112 +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