diff -Nru vdr-1.4.7-vanilla/Makefile vdr-1.4.7-subtitles/Makefile --- vdr-1.4.7-vanilla/Makefile 2006-08-20 13:44:22.000000000 +0300 +++ vdr-1.4.7-subtitles/Makefile 2007-10-11 21:27:00.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.7-vanilla/dvbplayer.c vdr-1.4.7-subtitles/dvbplayer.c --- vdr-1.4.7-vanilla/dvbplayer.c 2007-04-28 17:55:22.000000000 +0300 +++ vdr-1.4.7-subtitles/dvbplayer.c 2007-10-11 21:27:00.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) @@ -497,6 +533,7 @@ } } if (p) { + StripExtendedPackets(p, pc); int w = PlayPes(p, pc, playMode != pmPlay); if (w > 0) { p += w; diff -Nru vdr-1.4.7-vanilla/dvbsub.c vdr-1.4.7-subtitles/dvbsub.c --- vdr-1.4.7-vanilla/dvbsub.c 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.7-subtitles/dvbsub.c 2007-10-11 21:27:00.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.7-vanilla/dvbsub.h vdr-1.4.7-subtitles/dvbsub.h --- vdr-1.4.7-vanilla/dvbsub.h 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.7-subtitles/dvbsub.h 2007-10-11 21:27:00.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.7-vanilla/menu.c vdr-1.4.7-subtitles/menu.c --- vdr-1.4.7-vanilla/menu.c 2006-12-02 13:12:02.000000000 +0200 +++ vdr-1.4.7-subtitles/menu.c 2007-10-11 21:27:00.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 @@ -3541,8 +3543,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.7-vanilla/osd.c vdr-1.4.7-subtitles/osd.c --- vdr-1.4.7-vanilla/osd.c 2007-02-17 18:05:52.000000000 +0200 +++ vdr-1.4.7-subtitles/osd.c 2007-10-11 21:27:00.000000000 +0300 @@ -14,6 +14,8 @@ #include <sys/stat.h> #include <sys/unistd.h> #include "tools.h" +#include "osdcontroller.h" +#include "vdrttxtsubshooks.h" // --- cPalette -------------------------------------------------------------- @@ -602,6 +604,7 @@ // --- cOsd ------------------------------------------------------------------ int cOsd::isOpen = 0; +bool cOsd::niosd = false; cOsd::cOsd(int Left, int Top) { @@ -621,6 +624,9 @@ delete bitmaps[i]; delete savedRegion; isOpen--; + if (!niosd) + NonInteractiveOsdPatch::OsdController.Show(); + cVDRTtxtsubsHookListener::Hook()->ShowOSD(); } cBitmap *cOsd::GetBitmap(int Area) @@ -744,8 +750,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.7-vanilla/osd.h vdr-1.4.7-subtitles/osd.h --- vdr-1.4.7-vanilla/osd.h 2006-02-26 16:45:05.000000000 +0200 +++ vdr-1.4.7-subtitles/osd.h 2007-10-11 21:27:00.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.7-vanilla/osdcontroller.c vdr-1.4.7-subtitles/osdcontroller.c --- vdr-1.4.7-vanilla/osdcontroller.c 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.7-subtitles/osdcontroller.c 2007-10-11 21:27:00.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.7-vanilla/osdcontroller.h vdr-1.4.7-subtitles/osdcontroller.h --- vdr-1.4.7-vanilla/osdcontroller.h 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.7-subtitles/osdcontroller.h 2007-10-11 21:27:00.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.7-vanilla/rcontroller.c vdr-1.4.7-subtitles/rcontroller.c --- vdr-1.4.7-vanilla/rcontroller.c 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.7-subtitles/rcontroller.c 2007-10-11 21:27:00.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.7-vanilla/rcontroller.h vdr-1.4.7-subtitles/rcontroller.h --- vdr-1.4.7-vanilla/rcontroller.h 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.7-subtitles/rcontroller.h 2007-10-11 21:27:00.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.7-vanilla/recorder.c vdr-1.4.7-subtitles/recorder.c --- vdr-1.4.7-vanilla/recorder.c 2006-01-08 13:01:25.000000000 +0200 +++ vdr-1.4.7-subtitles/recorder.c 2007-10-11 21:27:00.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.UseDolbyDigital ? 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.UseDolbyDigital ? DPids : NULL, SPids, true); - writer = new cFileWriter(FileName, remux); + writer = new cFileWriter(FileName, remux, tsr); } cRecorder::~cRecorder() diff -Nru vdr-1.4.7-vanilla/recorder.h vdr-1.4.7-subtitles/recorder.h --- vdr-1.4.7-vanilla/recorder.h 2005-08-13 14:31:18.000000000 +0300 +++ vdr-1.4.7-subtitles/recorder.h 2007-10-11 21:27:00.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.7-vanilla/remux.c vdr-1.4.7-subtitles/remux.c --- vdr-1.4.7-vanilla/remux.c 2006-12-01 16:46:25.000000000 +0200 +++ vdr-1.4.7-subtitles/remux.c 2007-10-11 21:27:34.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,22 @@ case 7: if (!done && (mpeg == 2 || mpeg1_required > 7)) { flag2 = Buf[c++]; + if (dataIdentifier) { + if (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 +1795,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 +1931,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.7-vanilla/vdr.c vdr-1.4.7-subtitles/vdr.c --- vdr-1.4.7-vanilla/vdr.c 2007-04-30 12:48:23.000000000 +0300 +++ vdr-1.4.7-subtitles/vdr.c 2007-10-11 21:27:00.000000000 +0300 @@ -851,7 +851,7 @@ DeletedRecordings.Update(); } // CAM control: - if (!Menu && !cOsd::IsOpen()) { + if (!Menu && !(cOsd::IsOpen() && !cOsd::niosd)) { Menu = CamControl(); if (Menu) LastCamMenu = 0; @@ -878,7 +878,7 @@ if (Menu) DELETE_MENU; else if (cControl::Control()) { - if (cOsd::IsOpen()) + if (cOsd::IsOpen() && !cOsd::niosd) cControl::Control()->Hide(); else WasOpen = false; @@ -969,7 +969,7 @@ } else cDevice::PrimaryDevice()->SetVolume(NORMALKEY(key) == kVolDn ? -VOLUMEDELTA : VOLUMEDELTA); - if (!Menu && !cOsd::IsOpen()) + if (!Menu && !(cOsd::IsOpen() && !cOsd::niosd)) Menu = cDisplayVolume::Create(); cDisplayVolume::Process(key); key = kNone; // nobody else needs to see these keys diff -Nru vdr-1.4.7-vanilla/vdrttxtsubshooks.c vdr-1.4.7-subtitles/vdrttxtsubshooks.c --- vdr-1.4.7-vanilla/vdrttxtsubshooks.c 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.7-subtitles/vdrttxtsubshooks.c 2007-10-11 21:27:00.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.7-vanilla/vdrttxtsubshooks.h vdr-1.4.7-subtitles/vdrttxtsubshooks.h --- vdr-1.4.7-vanilla/vdrttxtsubshooks.h 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.7-subtitles/vdrttxtsubshooks.h 2007-10-11 21:27:00.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