diff options
-rw-r--r-- | Checkpatch.sh | 40 | ||||
-rw-r--r-- | HISTORY | 7 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | VDR.patch | 31 | ||||
-rw-r--r-- | VDR.upgrade-patch | 23 | ||||
-rw-r--r-- | siinfo.c | 49 | ||||
-rw-r--r-- | siinfo.h | 2 | ||||
-rw-r--r-- | ttxtsubs.c | 12 | ||||
-rw-r--r-- | ttxtsubsdisplay.c | 90 | ||||
-rw-r--r-- | ttxtsubsdisplay.h | 4 | ||||
-rw-r--r-- | ttxtsubsrecorder.c | 2 |
12 files changed, 205 insertions, 68 deletions
diff --git a/Checkpatch.sh b/Checkpatch.sh new file mode 100644 index 0000000..5549988 --- /dev/null +++ b/Checkpatch.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +DIR=`dirname $0` + +if [ ! -f "$DIR/../../../osd.c" ]; then + echo + echo + echo "Warning while building ttxtsubs plugin:" + echo $0: "Can not find VDR's osd.c so can not check for correct patch!" + echo + echo + exit 0; +fi + +grep vdrttxtsubshooks "$DIR/../../../osd.c" >> /dev/null; +if [ $? -ne 0 ]; then + echo + echo + echo "Error while building ttxtsubs plugin:" + echo "You have not patched your VDR - please read the README!" + echo + echo + exit 1; +fi + +grep OSD_HOOK_2 "$DIR/../../../osd.c" >> /dev/null; +if [ $? -ne 0 ]; then + echo + echo + echo "Error while building ttxtsubs plugin:" + echo " You have an older version of the VDR patch installed!" + echo " You need to upgrade it." + echo " Please do:" + echo " cd /path/to/vdr [ replace with your path ]" + echo " patch -b < PLUGINS/src/ttxtsubs/VDR.upgrade-patch" + echo " make" + echo + exit 1; +fi + @@ -1,6 +1,13 @@ VDR Plugin 'ttxtsubs' Revision History -------------------------------------- +2003-07-16: Version 0.0.3d +- IMORTANT! Needs and upgrade to the patch! See README! +- Improved the OSD hooks to be more compatible with other plugins +- Added a primitive Service Information caching mechanism to speed + up channel switching (will not refresh if channels are changed, + will be reset on VDR restart) + 2003-07-10: Version 0.0.3c - Fixed problems when used with more than one device (I hope) @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile,v 1.17 2003/05/02 04:11:20 ragge Exp $ +# $Id: Makefile,v 1.18 2003/07/16 04:01:44 ragge Exp $ # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -16,7 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri ### The C++ compiler and options: CXX ?= g++ -CXXFLAGS ?= -O2 -Wall -Woverloaded-virtual +CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual ### The directory environment: @@ -69,6 +69,7 @@ $(DEPFILE): Makefile ### Targets: all: libvdr-$(PLUGIN).so + @sh ./Checkpatch.sh libvdr-$(PLUGIN).so: $(OBJS) $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ @@ -87,4 +87,12 @@ Rebuild VDR: make make plugins + +NOTE: If you have installed an earlier version of the patch, you +need to upgrade it. If so, do this: + cd ..../vdr-1.2.1 + patch -b < PLUGINS/src/ttxtsubs-0.0.3/VDR.upgrade-patch + make + + Now you should be able to start VDR with "-P ttxtsubs". @@ -1,6 +1,6 @@ diff -upr ./DIST/vdr-1.2.1/Makefile ./Makefile --- ./DIST/vdr-1.2.1/Makefile 2003-01-06 13:28:09.000000000 +0100 -+++ ./Makefile 2003-06-20 04:05:11.000000000 +0200 ++++ ./Makefile 2003-07-16 05:39:36.000000000 +0200 @@ -36,7 +36,8 @@ OBJS = audio.o channels.o ci.o config.o dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o interface.o keys.o\ lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o\ @@ -13,7 +13,7 @@ diff -upr ./DIST/vdr-1.2.1/Makefile ./Makefile FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1 diff -upr ./DIST/vdr-1.2.1/dvbplayer.c ./dvbplayer.c --- ./DIST/vdr-1.2.1/dvbplayer.c 2003-05-24 11:04:26.000000000 +0200 -+++ ./dvbplayer.c 2003-06-20 04:05:11.000000000 +0200 ++++ ./dvbplayer.c 2003-07-16 05:39:36.000000000 +0200 @@ -14,6 +14,7 @@ #include "ringbuffer.h" #include "thread.h" @@ -90,7 +90,7 @@ diff -upr ./DIST/vdr-1.2.1/dvbplayer.c ./dvbplayer.c if (w > 0) { diff -upr ./DIST/vdr-1.2.1/menu.c ./menu.c --- ./DIST/vdr-1.2.1/menu.c 2003-06-07 14:31:57.000000000 +0200 -+++ ./menu.c 2003-06-20 04:05:11.000000000 +0200 ++++ ./menu.c 2003-07-16 05:39:36.000000000 +0200 @@ -2969,8 +2969,18 @@ cRecordControl::cRecordControl(cDevice * cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName); @@ -112,7 +112,7 @@ diff -upr ./DIST/vdr-1.2.1/menu.c ./menu.c if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo() diff -upr ./DIST/vdr-1.2.1/menu.h ./menu.h --- ./DIST/vdr-1.2.1/menu.h 2003-05-24 18:35:52.000000000 +0200 -+++ ./menu.h 2003-06-20 04:05:11.000000000 +0200 ++++ ./menu.h 2003-07-16 05:39:36.000000000 +0200 @@ -14,6 +14,7 @@ #include "device.h" #include "osd.h" @@ -123,7 +123,7 @@ diff -upr ./DIST/vdr-1.2.1/menu.h ./menu.h diff -upr ./DIST/vdr-1.2.1/osd.c ./osd.c --- ./DIST/vdr-1.2.1/osd.c 2003-06-04 18:13:00.000000000 +0200 -+++ ./osd.c 2003-06-20 04:05:11.000000000 +0200 ++++ ./osd.c 2003-07-16 05:43:06.000000000 +0200 @@ -12,6 +12,7 @@ #include "device.h" #include "i18n.h" @@ -132,17 +132,18 @@ diff -upr ./DIST/vdr-1.2.1/osd.c ./osd.c // --- cOsd ------------------------------------------------------------------ -@@ -96,6 +97,9 @@ void cOsd::Open(int w, int h) - d *= lineHeight; - int x = (720 - w + charWidth) / 2; //TODO PAL vs. NTSC??? - int y = (576 - Setup.OSDheight * lineHeight) / 2 + d; +@@ -62,6 +63,10 @@ void cOsd::SetColor(eDvbColor colorFg, e + + cOsdBase *cOsd::OpenRaw(int x, int y) + { +#ifdef VDRTTXTSUBSHOOKS ++ // OSD_HOOK_2 - Information to Checkpatch.sh + cVDRTtxtsubsHookListener::Hook()->HideOSD(); +#endif - //XXX - osd = OpenRaw(x, y); - //XXX TODO this should be transferred to the places where the individual windows are requested (there's too much detailed knowledge here!) -@@ -138,6 +142,9 @@ void cOsd::Close(void) + #ifdef DEBUG_OSD + return NULL; + #else +@@ -138,6 +143,9 @@ void cOsd::Close(void) delete osd; osd = NULL; #endif @@ -154,7 +155,7 @@ diff -upr ./DIST/vdr-1.2.1/osd.c ./osd.c void cOsd::Clear(void) diff -upr ./DIST/vdr-1.2.1/recorder.c ./recorder.c --- ./DIST/vdr-1.2.1/recorder.c 2003-05-16 15:33:04.000000000 +0200 -+++ ./recorder.c 2003-06-20 04:05:11.000000000 +0200 ++++ ./recorder.c 2003-07-16 05:39:36.000000000 +0200 @@ -10,6 +10,8 @@ #include <stdarg.h> #include <stdio.h> @@ -219,7 +220,7 @@ diff -upr ./DIST/vdr-1.2.1/recorder.c ./recorder.c break; diff -upr ./DIST/vdr-1.2.1/recorder.h ./recorder.h --- ./DIST/vdr-1.2.1/recorder.h 2002-06-08 11:35:03.000000000 +0200 -+++ ./recorder.h 2003-06-20 04:05:11.000000000 +0200 ++++ ./recorder.h 2003-07-16 05:39:36.000000000 +0200 @@ -15,6 +15,7 @@ #include "remux.h" #include "ringbuffer.h" diff --git a/VDR.upgrade-patch b/VDR.upgrade-patch new file mode 100644 index 0000000..1f4bd96 --- /dev/null +++ b/VDR.upgrade-patch @@ -0,0 +1,23 @@ +--- old-osd.c 2003-07-16 05:39:36.000000000 +0200 ++++ osd.c 2003-07-16 05:38:35.000000000 +0200 +@@ -63,6 +63,10 @@ void cOsd::SetColor(eDvbColor colorFg, e + + cOsdBase *cOsd::OpenRaw(int x, int y) + { ++#ifdef VDRTTXTSUBSHOOKS ++ // OSD_HOOK_2 - Information to Checkpatch.sh ++ cVDRTtxtsubsHookListener::Hook()->HideOSD(); ++#endif + #ifdef DEBUG_OSD + return NULL; + #else +@@ -97,9 +101,6 @@ void cOsd::Open(int w, int h) + d *= lineHeight; + int x = (720 - w + charWidth) / 2; //TODO PAL vs. NTSC??? + int y = (576 - Setup.OSDheight * lineHeight) / 2 + d; +-#ifdef VDRTTXTSUBSHOOKS +- cVDRTtxtsubsHookListener::Hook()->HideOSD(); +-#endif + //XXX + osd = OpenRaw(x, y); + //XXX TODO this should be transferred to the places where the individual windows are requested (there's too much detailed knowledge here!) @@ -14,6 +14,8 @@ #include <string.h> #include <errno.h> +#include <map> + #include <vdr/device.h> #include <vdr/dvbdevice.h> @@ -131,7 +133,7 @@ read_timeout(int fd, void *buf, size_t count, int timeout_ms) { if(ret < 0) return errno; if(ret == 0) { // timeout - fprintf(stderr, "ttxtsubs: read: timeout!\n"); + fprintf(stderr, "ttxtsubs: Service Information read: timeout!\n"); return -1; } @@ -429,36 +431,19 @@ static int FindTtxtInfoInPMT(int card_no, int pid, int vpid, struct ttxtinfo *in return ret; } -#if 0 -/* - * Get dvb device number from device index - * this is needed for those having cards which aren't dvb cards, like - * mpeg decoders. It will probably break if there are unused devices. - */ -int DeviceToCardNo(int device_no) -{ - int card_no = -1; - int i; - for(i = 0; i <= device_no; i++) { - cDevice *d = cDevice::GetDevice(i); - cDvbDevice *dd = dynamic_cast<cDvbDevice*>(d); - if(dd) - card_no++; - } +typedef std::map < int, struct ttxtinfo > cCache; - return card_no; -} -#endif +static cCache gCache; /* * find the ttxt_info in the PMT via the PAT, try first with the SID * and if that fails with the VPID * return <> 0 on error; */ -int GetTtxtInfo(int card_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info) +int GetTtxtInfo(int card_no, int channel, uint16_t sid, uint16_t vpid, struct ttxtinfo *info) { - int ret; + int ret = -1; char *patsects[256]; int numsects; int i; @@ -469,6 +454,14 @@ int GetTtxtInfo(int card_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info) memset((char *) info, 0, sizeof(*info)); + cCache::iterator iter; + iter = gCache.find(channel); + if(iter != gCache.end()) { + DupTtxtInfo(&iter->second, info); + ret = 0; + return ret; + } + for(retry = 0; retry <= 1 && !foundinfo; retry++) { // XXX retry two times due to flaky pat scanning with hw_sections=0 // printf("GetTtxtInfo A sid: %d, vpid: %d\n", sid, vpid); // XXXX @@ -537,10 +530,17 @@ int GetTtxtInfo(int card_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info) } } } + + FreeSects(patsects); } + if(foundinfo) { + struct ttxtinfo info2; + DupTtxtInfo(info, &info2); + gCache[channel] = info2; + } + bail: - FreeSects(patsects); return ret; } @@ -565,8 +565,7 @@ void DupTtxtInfo(struct ttxtinfo *in, struct ttxtinfo *out) out->p = (struct ttxtpidinfo *) malloc(sizeof(out->p[0]) * in->pidcount); for(i = 0; i < in->pidcount; i++) { - out->p[i].pid = in->p[i].pid; - out->p[i].pagecount = in->p[i].pagecount; + out->p[i] = in->p[i]; out->p[i].i = (struct ttxtpageinfo *) malloc(sizeof(out->p[0].i[0]) * in->p[i].pagecount); memcpy((void *) out->p[i].i, (void *) in->p[i].i, sizeof(out->p[0].i[0]) * in->p[i].pagecount); } @@ -30,7 +30,7 @@ struct ttxtinfo { * and if that fails with the VPID * return <> 0 on error; */ -int GetTtxtInfo(int card_no, uint16_t sid, uint16_t vpid, struct ttxtinfo *info); +int GetTtxtInfo(int card_no, int channel, uint16_t sid, uint16_t vpid, struct ttxtinfo *info); void FreeTtxtInfoData(struct ttxtinfo *info); void DupTtxtInfo(struct ttxtinfo *in, struct ttxtinfo *out); @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: ttxtsubs.c,v 1.17 2003/07/10 02:36:17 ragge Exp ragge $ + * $Id: ttxtsubs.c,v 1.19 2003/07/16 04:15:08 ragge Exp $ */ #include <vdr/plugin.h> @@ -18,7 +18,7 @@ #include "siinfo.h" #include "ttxtsubs.h" -static const char *VERSION = "0.0.3c"; +static const char *VERSION = "0.0.3d"; static const char *DESCRIPTION = "Teletext subtitles"; //static const char *MAINMENUENTRY = "Ttxtsubs"; @@ -218,7 +218,7 @@ void cPluginTtxtsubs::ChannelSwitch(const cDevice *Device, int ChannelNumber) struct ttxtinfo info; int pid, page; - if(GetTtxtInfo(Device->ActualDevice()->CardIndex(), c->Sid(), c->Vpid(), &info)) { + if(GetTtxtInfo(Device->ActualDevice()->CardIndex(), ChannelNumber, c->Sid(), c->Vpid(), &info)) { fprintf(stderr, "ttxtsubs: Error: GetTtxtInfo failed!\n"); } else { if(FindSubs(&info, mLanguage, mHearingImpaired, &pid, &page)) { @@ -269,12 +269,6 @@ void cPluginTtxtsubs::StartTtxtLive(const cDevice *Device, int pid, int page) { //dprint("cPluginTtxtsubs::StartTtxtLive\n"); - fprintf(stderr, "cPluginTtxtsubs::StartTtxtLive(%d, %d, %03x)\n", - Device->DeviceNumber(), pid, page); - fprintf(stderr, - "cPluginTtxtsubs::StartTtxtLive CurrChan: %d Prim:%d Card:%d MPG:%d HasProg:%d\n", - cDevice::CurrentChannel(), Device->IsPrimaryDevice(), Device->CardIndex(), - Device->HasDecoder(), const_cast < cDevice * >( Device )->HasProgramme()); #if 0 return; // XXX TEST - No live subs #endif diff --git a/ttxtsubsdisplay.c b/ttxtsubsdisplay.c index 817bdb4..60802d7 100644 --- a/ttxtsubsdisplay.c +++ b/ttxtsubsdisplay.c @@ -4,6 +4,7 @@ #include <string.h> #include <sys/time.h> #include <time.h> +#include <pthread.h> #include <vdr/osd.h> #include <vdr/osdbase.h> @@ -21,6 +22,49 @@ enum { }; +// -------------------- + +class cOSDSelfMemory { + public: + cOSDSelfMemory(void) : mActive(0) {} + ~cOSDSelfMemory() {} + + void SetActive(int a) + { + cMutexLock lock(&mLock); + mActive = a; + if(a) + mThr = pthread_self(); + } + int IsMe(void) + { + cMutexLock lock(&mLock); + pthread_t thr = pthread_self(); + if(mActive && pthread_equal(thr, mThr)) + return 1; + else + return 0; + } + + private: + cMutex mLock; + int mActive; + pthread_t mThr; +}; + +class cOSDSelfMemoryLock { + public: + cOSDSelfMemoryLock(cOSDSelfMemory *m) : mMem(m) { mMem->SetActive(1); } + ~cOSDSelfMemoryLock() { mMem->SetActive(0); } + + private: + cOSDSelfMemory *mMem; +}; + +static cOSDSelfMemory gSelfMem; + +// -------------------- + cTtxtSubsDisplay::cTtxtSubsDisplay(void) : mPageState(invalid), @@ -46,24 +90,36 @@ cTtxtSubsDisplay::~cTtxtSubsDisplay(void) void cTtxtSubsDisplay::SetPage(int Pageno) // Pageno is 0x000 to 0x799 { - Clear(); - mMag = (Pageno >> 8) & 0xF; mNo = Pageno & 0xFF; + + Clear(); } void cTtxtSubsDisplay::Hide(void) { + if(gSelfMem.IsMe()) { + //dprint("cTtxtSubsDisplay::Hide - Ignoring self induced hide!\n"); + return; + } + //dprint("cTtxtSubsDisplay::Hide\n"); - mDoDisplay = 0; + cMutexLock lock(&mOsdLock); ClearOSD(); + mDoDisplay = 0; } void cTtxtSubsDisplay::Show(void) { + if(gSelfMem.IsMe()) { + //dprint("cTtxtSubsDisplay::Show - Ignoring self induced show!\n"); + return; + } + //dprint("cTtxtSubsDisplay::Show\n"); + cMutexLock lock(&mOsdLock); mDoDisplay = 1; ShowOSD(); } @@ -179,8 +235,9 @@ void cTtxtSubsDisplay::TtxtData(const uint8_t *Data) //dump_hex("", page.data[packet], 40); } else { // packets with national characters information: X/28/0 format 1, X/28/1, X/28/4, M/29/0 M/29/4, - if(packet == 28 || packet == 29) - dprint("mag: %d, packet: %d, page: %02x, state: %d\n", page.mag, packet, page.no, mPageState); + if(packet == 28 || packet == 29) { + //dprint("mag: %d, packet: %d, page: %02x, state: %d\n", page.mag, packet, page.no, mPageState); + } //if(packet == 26) { // dprint("mag: %d, packet: %d, page: %02x, state: %d\n", page.mag, packet, page.no, mPageState); @@ -251,6 +308,7 @@ void cTtxtSubsDisplay::ShowOSD(void) char buf[TTXT_DISPLAYABLE_ROWS][41]; int doneWidthWorkaround = 0; + cOSDSelfMemoryLock selfmem(&gSelfMem); cMutexLock lock(&mOsdLock); if(!mDoDisplay) { @@ -274,13 +332,13 @@ void cTtxtSubsDisplay::ShowOSD(void) rowcount++; } -#if 0 +#if 1 mOsd = cOsd::OpenRaw(SCREENLEFT, SCREENTOP); #else mOsd = cDevice::PrimaryDevice()->NewOsd(SCREENLEFT, SCREENTOP); #endif if(mOsd == NULL) { - dprint("Error: cOsd::OpenRaw returned NULL!\n"); + //dprint("Error: cOsd::OpenRaw returned NULL!\n"); return; } @@ -297,12 +355,12 @@ void cTtxtSubsDisplay::ShowOSD(void) // XXX Width calculations doesn't work before we have created a window... if(!doneWidthWorkaround) { wind = mOsd->Create(0, y, 4, ROWH, 2); - w = mOsd->Width(buf[i]) + 2 * TEXTX; - mOsd->Clear(wind); - mOsd->Hide(wind); + mOsd->Fill(0, y, 4, y + ROWH, clrWhite, wind); + mOsd->Fill(0, y, 4, y + ROWH, clrBackground, wind); doneWidthWorkaround = 1; - } else - w = mOsd->Width(buf[i]) + 2 * TEXTX; + } + + w = mOsd->Width(buf[i]) + 2 * TEXTX; if(w % 4) w += 4 - (w % 4); @@ -322,11 +380,17 @@ void cTtxtSubsDisplay::ShowOSD(void) void cTtxtSubsDisplay::ClearOSD(void) { // dprint("\nClearOSD!\n"); + cOSDSelfMemoryLock selfmem(&gSelfMem); cMutexLock lock(&mOsdLock); + if(!mDoDisplay) { + //dprint("NOT clearing subtitles because of other OSD activities!\n"); + return; + } + if(mOsd) { - mOsd->Clear(ALL_WINDOWS); + //mOsd->Clear(ALL_WINDOWS); mOsd->Hide(ALL_WINDOWS); mOsd->Flush(); delete mOsd; diff --git a/ttxtsubsdisplay.h b/ttxtsubsdisplay.h index d515cd0..fa76860 100644 --- a/ttxtsubsdisplay.h +++ b/ttxtsubsdisplay.h @@ -16,13 +16,13 @@ class cTtxtSubsDisplay { void SetPage(int Pageno); // Pageno is 0x000 to 0x799 void Hide(void); void Show(void); - void Clear(void); void TtxtData(const uint8_t *); protected: + void Clear(void); void ShowOSD(); void ClearOSD(void); - + private: int mPageState; int mMag; diff --git a/ttxtsubsrecorder.c b/ttxtsubsrecorder.c index 19c7b6f..7cfb5c0 100644 --- a/ttxtsubsrecorder.c +++ b/ttxtsubsrecorder.c @@ -32,7 +32,7 @@ cTtxtSubsRecorder::cTtxtSubsRecorder(cDevice *dev, const cChannel *ch, char *lan struct ttxtpidinfo *pi = NULL; int pid, page; - if(GetTtxtInfo(dev->CardIndex(), ch->Sid(), ch->Vpid(), mTtxtinfo)) { + if(GetTtxtInfo(dev->CardIndex(), ch->Number(), ch->Sid(), ch->Vpid(), mTtxtinfo)) { fprintf(stderr, "cTtxtSubsRecorder::cTtxtSubsRecorder: GetTtxtSubtitleInfo error!\n"); } else { pi = FindSubs(mTtxtinfo, lang, HI, &pid, &page); |