diff options
Diffstat (limited to 'patches/vdr-1.6.0-2-ttxtsubs.patch')
-rw-r--r-- | patches/vdr-1.6.0-2-ttxtsubs.patch | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/patches/vdr-1.6.0-2-ttxtsubs.patch b/patches/vdr-1.6.0-2-ttxtsubs.patch new file mode 100644 index 0000000..16bd1a1 --- /dev/null +++ b/patches/vdr-1.6.0-2-ttxtsubs.patch @@ -0,0 +1,296 @@ +diff --git a/Makefile b/Makefile +index b07b1df..fda1f40 100644 +--- a/Makefile ++++ b/Makefile +@@ -43,6 +43,8 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d + 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 += vdrttxtsubshooks.o ++ + ifndef NO_KBD + DEFINES += -DREMOTE_KBD + endif +diff --git a/dvbplayer.c b/dvbplayer.c +index 64fa559..18484fe 100644 +--- a/dvbplayer.c ++++ b/dvbplayer.c +@@ -14,6 +14,7 @@ + #include "ringbuffer.h" + #include "thread.h" + #include "tools.h" ++#include "vdrttxtsubshooks.h" + + // --- cBackTrace ------------------------------------------------------------ + +@@ -312,6 +313,32 @@ void cDvbPlayer::Empty(void) + 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 ++ // 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) +@@ -503,6 +530,7 @@ void cDvbPlayer::Action(void) + } + } + if (p) { ++ StripExtendedPackets(p, pc); + int w = PlayPes(p, pc, playMode != pmPlay); + if (w > 0) { + p += w; +diff --git a/menu.c b/menu.c +index b7eab45..b1f112a 100644 +--- a/menu.c ++++ b/menu.c +@@ -28,6 +28,7 @@ + #include "themes.h" + #include "timers.h" + #include "transfer.h" ++#include "vdrttxtsubshooks.h" + #include "videodir.h" + + #define MAXWAIT4EPGINFO 3 // seconds +@@ -3811,8 +3812,10 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause) + isyslog("record %s", fileName); + if (MakeDirs(fileName, true)) { + const cChannel *ch = timer->Channel(); +- recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids()); ++ cTtxtSubsRecorderBase *subsRecorder = cVDRTtxtsubsHookListener::Hook()->NewTtxtSubsRecorder(device, ch); ++ recorder = new cRecorder(fileName, ch->GetChannelID(), timer->Priority(), ch->Vpid(), ch->Apids(), ch->Dpids(), ch->Spids(), 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 --git a/osd.c b/osd.c +index 47a11b2..c32750b 100644 +--- a/osd.c ++++ b/osd.c +@@ -15,6 +15,7 @@ + #include <sys/stat.h> + #include <sys/unistd.h> + #include "tools.h" ++#include "vdrttxtsubshooks.h" + + // --- cPalette -------------------------------------------------------------- + +diff --git a/recorder.c b/recorder.c +index 7bcd0cc..a915140 100644 +--- a/recorder.c ++++ b/recorder.c +@@ -11,6 +11,7 @@ + #include <stdarg.h> + #include <stdio.h> + #include <unistd.h> ++#include <stdint.h> + #include "shutdown.h" + + #define RECORDERBUFSIZE MEGABYTE(5) +@@ -26,6 +27,7 @@ + + class cFileWriter : public cThread { + private: ++ cTtxtSubsRecorderBase *ttxtSubsRecorder; + cRemux *remux; + cFileName *fileName; + cIndexFile *index; +@@ -38,13 +40,14 @@ private: + 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; +@@ -67,6 +70,8 @@ cFileWriter::~cFileWriter() + Cancel(3); + delete index; + delete fileName; ++ if (ttxtSubsRecorder) ++ delete ttxtSubsRecorder; + } + + bool cFileWriter::RunningLowOnDiskSpace(void) +@@ -111,6 +116,16 @@ void cFileWriter::Action(void) + } + 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; +@@ -126,7 +141,7 @@ void cFileWriter::Action(void) + + // --- cRecorder ------------------------------------------------------------- + +-cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids) ++cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, cTtxtSubsRecorderBase *tsr) + :cReceiver(ChannelID, Priority, VPid, APids, Setup.UseDolbyDigital ? DPids : NULL, SPids) + ,cThread("recording") + { +@@ -137,7 +152,7 @@ cRecorder::cRecorder(const char *FileName, tChannelID ChannelID, int Priority, i + 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 --git a/recorder.h b/recorder.h +index 920d909..0211c97 100644 +--- a/recorder.h ++++ b/recorder.h +@@ -15,6 +15,7 @@ + #include "remux.h" + #include "ringbuffer.h" + #include "thread.h" ++#include "vdrttxtsubshooks.h" + + class cFileWriter; + +@@ -28,7 +29,7 @@ protected: + virtual void Receive(uchar *Data, int Length); + virtual void Action(void); + public: +- cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids); ++ cRecorder(const char *FileName, tChannelID ChannelID, int Priority, int VPid, const int *APids, const int *DPids, const int *SPids, cTtxtSubsRecorderBase *tsr); + // Creates a new recorder for the channel with the given ChannelID and + // the given Priority that will record the given PIDs into the file FileName. + virtual ~cRecorder(); +diff --git a/vdrttxtsubshooks.c b/vdrttxtsubshooks.c +new file mode 100644 +index 0000000..4c1836b +--- /dev/null ++++ b/vdrttxtsubshooks.c +@@ -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 --git a/vdrttxtsubshooks.h b/vdrttxtsubshooks.h +new file mode 100644 +index 0000000..cfcd6a5 +--- /dev/null ++++ b/vdrttxtsubshooks.h +@@ -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 |