diff options
author | Jochen Dolze <vdr@dolze.de> | 2010-04-08 17:00:31 +0200 |
---|---|---|
committer | Jochen Dolze <vdr@dolze.de> | 2010-04-08 17:00:31 +0200 |
commit | 0bb11d711bb02bad0cf4a8694522dff766aa1c54 (patch) | |
tree | 798e07e274d453b6faab28e7f12dd059797192c2 | |
parent | a1f19e122cca43e5c07079e99e3544301cf3a1c8 (diff) | |
download | vdr-plugin-markad-0bb11d711bb02bad0cf4a8694522dff766aa1c54.tar.gz vdr-plugin-markad-0bb11d711bb02bad0cf4a8694522dff766aa1c54.tar.bz2 |
Added plugin setup, plugin main menu
-rw-r--r-- | command/markad-standalone.cpp | 54 | ||||
-rw-r--r-- | command/markad-standalone.h | 3 | ||||
-rw-r--r-- | plugin/Makefile | 4 | ||||
-rw-r--r-- | plugin/markad.cpp | 27 | ||||
-rw-r--r-- | plugin/markad.h | 9 | ||||
-rw-r--r-- | plugin/menu.cpp | 226 | ||||
-rw-r--r-- | plugin/menu.h | 39 | ||||
-rw-r--r-- | plugin/po/de_DE.po | 52 | ||||
-rw-r--r-- | plugin/po/it_IT.po | 50 | ||||
-rw-r--r-- | plugin/setup.cpp | 69 | ||||
-rw-r--r-- | plugin/setup.h | 36 | ||||
-rw-r--r-- | plugin/status.cpp | 306 | ||||
-rw-r--r-- | plugin/status.h | 34 |
13 files changed, 779 insertions, 130 deletions
diff --git a/command/markad-standalone.cpp b/command/markad-standalone.cpp index 3eb2e05..0f13456 100644 --- a/command/markad-standalone.cpp +++ b/command/markad-standalone.cpp @@ -996,7 +996,8 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, bool BackupMarks, in int LogoWidth, int LogoHeight, bool DecodeVideo, bool DecodeAudio, bool IgnoreVideoInfo, bool IgnoreAudioInfo, const char *LogoDir, const char *MarkFileName, bool ASD, - bool noPid, bool OSD, const char *SVDRPHost, int SVDRPPort) + bool noPid, bool OSD, const char *SVDRPHost, int SVDRPPort, + bool Before) { directory=Directory; abort=false; @@ -1055,18 +1056,6 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, bool BackupMarks, in bIgnoreVideoInfo=true; } - if (!CheckTS(Directory)) - { - video_demux=NULL; - ac3_demux=NULL; - mp2_demux=NULL; - decoder=NULL; - video=NULL; - audio=NULL; - osd=NULL; - return; - } - if (!noPid) { CreatePidfile(Directory); @@ -1083,6 +1072,20 @@ cMarkAdStandalone::cMarkAdStandalone(const char *Directory, bool BackupMarks, in } } + if (Before) sleep(10); + + if (!CheckTS(Directory)) + { + video_demux=NULL; + ac3_demux=NULL; + mp2_demux=NULL; + decoder=NULL; + video=NULL; + audio=NULL; + osd=NULL; + return; + } + if (isTS) { if (!CheckPATPMT(Directory)) @@ -1321,13 +1324,7 @@ static void signal_handler(int sig) { case SIGTSTP: isyslog("paused by signal"); - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, SIGTSTP); - sigprocmask(SIG_UNBLOCK, &mask, NULL); - signal(SIGTSTP,SIG_DFL); - kill(getpid(),SIGTSTP); - signal(SIGTSTP,signal_handler); + kill(getpid(),SIGSTOP); break; case SIGCONT: isyslog("continued by signal"); @@ -1709,13 +1706,13 @@ int main(int argc, char *argv[]) } if (pid != 0) { - isyslog("forked to pid %d",pid); + tsyslog("forked to pid %d",pid); return 0; // initial program immediately returns } } if ( bFork ) { - isyslog("(forked) pid %d", getpid()); + tsyslog("(forked) pid %d", getpid()); if (chdir("/")==-1) { perror("chdir"); @@ -1784,8 +1781,6 @@ int main(int argc, char *argv[]) } } - if (bBefore) sleep(10); - // now do the work... struct stat statbuf; if (stat(recDir,&statbuf)==-1) @@ -1800,12 +1795,6 @@ int main(int argc, char *argv[]) return -1; } - cmasta = new cMarkAdStandalone(recDir,bBackupMarks, logoExtraction, logoWidth, logoHeight, - bDecodeVideo,bDecodeAudio,bIgnoreVideoInfo,bIgnoreAudioInfo, - logoDirectory,markFileName,bASD,bNoPid,bOSD,svdrphost, - svdrpport); - if (!cmasta) return -1; - // ignore some signals signal(SIGHUP, SIG_IGN); @@ -1818,6 +1807,11 @@ int main(int argc, char *argv[]) signal(SIGTSTP, signal_handler); signal(SIGCONT, signal_handler); + cmasta = new cMarkAdStandalone(recDir,bBackupMarks, logoExtraction, logoWidth, logoHeight, + bDecodeVideo,bDecodeAudio,bIgnoreVideoInfo,bIgnoreAudioInfo, + logoDirectory,markFileName,bASD,bNoPid,bOSD,svdrphost, + svdrpport,bBefore); + if (!cmasta) return -1; cmasta->Process(recDir); delete cmasta; diff --git a/command/markad-standalone.h b/command/markad-standalone.h index 1e4c821..5099ef1 100644 --- a/command/markad-standalone.h +++ b/command/markad-standalone.h @@ -228,7 +228,8 @@ public: int LogoWidth, int LogoHeight, bool DecodeVideo, bool DecodeAudio, bool IgnoreVideoInfo, bool IgnoreAudioInfo, const char *LogoDir, const char *MarkFileName, bool ASD, - bool noPid, bool OSD, const char *SVDRPHost, int SVDRPPort); + bool noPid, bool OSD, const char *SVDRPHost, int SVDRPPort, + bool Before); ~cMarkAdStandalone(); }; diff --git a/plugin/Makefile b/plugin/Makefile index 9f721a4..82cf02c 100644 --- a/plugin/Makefile +++ b/plugin/Makefile @@ -17,7 +17,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' ../version.h | awk '{ pr ### The C++ compiler and options: CXX ?= g++ -CXXFLAGS ?= -fPIC -g -O2 -Wall -Wextra -Woverloaded-virtual -Wno-parentheses +CXXFLAGS ?= -fPIC -g -O2 -pedantic -Wall -Wextra -Woverloaded-virtual -Wno-parentheses ### The directory environment: @@ -48,7 +48,7 @@ DEFINES += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE ### The object files (add further files here): -OBJS = $(PLUGIN).o status.o +OBJS = $(PLUGIN).o status.o menu.o setup.o ### The main target: diff --git a/plugin/markad.cpp b/plugin/markad.cpp index 4bf9a9c..68d5eed 100644 --- a/plugin/markad.cpp +++ b/plugin/markad.cpp @@ -17,6 +17,10 @@ cPluginMarkAd::cPluginMarkAd(void) statusMonitor=NULL; bindir=strdup(DEF_BINDIR); logodir=strdup(DEF_LOGODIR); + + setup.ProcessDuring=true; + setup.whileRecording=true; + setup.whilePlaying=true; } cPluginMarkAd::~cPluginMarkAd() @@ -95,7 +99,7 @@ bool cPluginMarkAd::Initialize(void) bool cPluginMarkAd::Start(void) { // Start any background activities the plugin shall perform. - statusMonitor = new cStatusMarkAd(bindir,logodir); + statusMonitor = new cStatusMarkAd(bindir,logodir,&setup); return true; } @@ -109,11 +113,6 @@ void cPluginMarkAd::Housekeeping(void) // Perform any cleanup or other regular tasks. } -const char *cPluginMarkAd::MainMenuEntry(void) -{ - return NULL; -} - void cPluginMarkAd::MainThreadHook(void) { // Perform actions in the context of the main program thread. @@ -137,19 +136,23 @@ time_t cPluginMarkAd::WakeupTime(void) cOsdObject *cPluginMarkAd::MainMenuAction(void) { // Perform the action when selected from the main VDR menu. - return NULL; + return new cMenuMarkAd(statusMonitor); } cMenuSetupPage *cPluginMarkAd::SetupMenu(void) { - // Return a setup menu in case the plugin supports one. - return NULL; + // Return the setup menu + return new cSetupMarkAd(&setup); } -bool cPluginMarkAd::SetupParse(const char *UNUSED(Name), const char *UNUSED(Value)) +bool cPluginMarkAd::SetupParse(const char *Name, const char *Value) { - // Parse your own setup parameters and store their values. - return false; + // Parse setup parameters and store their values. + if (!strcasecmp(Name,"Execution")) setup.ProcessDuring=atoi(Value); + else if (!strcasecmp(Name,"whileRecording")) setup.whileRecording=atoi(Value); + else if (!strcasecmp(Name,"whilePlaying")) setup.whilePlaying=atoi(Value); + else return false; + return true; } bool cPluginMarkAd::Service(const char *UNUSED(Id), void *UNUSED(Data)) diff --git a/plugin/markad.h b/plugin/markad.h index 4c45abd..fa52d68 100644 --- a/plugin/markad.h +++ b/plugin/markad.h @@ -13,12 +13,15 @@ #include "version.h" #include "status.h" +#include "menu.h" +#include "setup.h" #define DEF_BINDIR "/usr/bin" #define DEF_LOGODIR "/var/lib/markad" extern const char *VERSION; static const char *DESCRIPTION = trNOOP("Mark advertisements"); +static const char *MAINMENUENTRY = trNOOP("markad status"); class cPluginMarkAd : public cPlugin { @@ -27,6 +30,7 @@ private: cStatusMarkAd *statusMonitor; char *bindir; char *logodir; + struct setup setup; public: cPluginMarkAd(void); virtual ~cPluginMarkAd(); @@ -47,7 +51,10 @@ public: virtual void MainThreadHook(void); virtual cString Active(void); virtual time_t WakeupTime(void); - virtual const char *MainMenuEntry(void); + virtual const char *MainMenuEntry(void) + { + return tr(MAINMENUENTRY); + } virtual cOsdObject *MainMenuAction(void); virtual cMenuSetupPage *SetupMenu(void); virtual bool SetupParse(const char *Name, const char *Value); diff --git a/plugin/menu.cpp b/plugin/menu.cpp new file mode 100644 index 0000000..75fa300 --- /dev/null +++ b/plugin/menu.cpp @@ -0,0 +1,226 @@ +/* + * menu.cpp: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "menu.h" + +cOsdMarkAd::cOsdMarkAd(struct recs *Entry) +{ + entry=Entry; + + const char *status; + + switch (entry->Status) + { + case 'R': + status=tr("running"); + break; + case 'S': + status=tr("sleeping"); + break; + case 'D': + status=tr("inactive"); + break; + case 'Z': + status=tr("zombie"); + break; + case 'T': + status=tr("stopped"); + break; + default: + status=tr("unknown"); + break; + } + + char *buf=NULL; + if (asprintf(&buf,"%s\t %s",entry->Name,status)!=-1) + { + SetText(buf,true); + free(buf); + } + else + { + // fallback + SetText(entry->Name,true); + } +} + +cMenuMarkAd::cMenuMarkAd(cStatusMarkAd *Status):cOsdMenu(tr("markad status"),15) +{ + status=Status; + last=time(NULL); + + int width; + cSkinDisplayMenu *disp=DisplayMenu(); + if (disp) + { + width=disp->GetTextAreaWidth(); + } + else + { + width=Setup.OSDWidth; + } + + int AvgCharWidth = Setup.FontOsdSize * 3 / 5; // see skins.c + int tab=(width-10*AvgCharWidth)/AvgCharWidth; + SetCols(tab); + + if (write()) + { + cOsdMarkAd *osd=(cOsdMarkAd *) Get(Current()); + if ((osd) && (osd->Selectable())) + { + SetHelpText(osd->GetEntry()); + } + } + else + { + SetHelpText(NULL); + } +} + + +bool cMenuMarkAd::write() +{ + Clear(); + + bool header=false,first=true; + struct recs *Entry=NULL; + status->ResetActPos(); + do + { + status->GetNextActive(&Entry); + if ((Entry) && (Entry->Name)) + { + if (!header) + { + header=true; + Add(new cOsdItem(tr("Recording\t Status"),osUnknown,false)); + } + Add(new cOsdMarkAd(Entry),first); + first=false; + } + } + while (Entry); + + if (!header) + { + Add(new cOsdItem(tr("no running markad found"),osUnknown,false),true); + } + Display(); + return header; +} + +void cMenuMarkAd::SetHelpText(struct recs *Entry) +{ + if (!Entry) + { + SetHelp(NULL,NULL); + return; + } + + switch (Entry->Status) + { + case 'R': + case 'S': + SetHelp(tr("Pause"),NULL); + break; + + case 'D': + case 'Z': + SetHelp(NULL,NULL); + break; + case 'T': + SetHelp(NULL,tr("Continue")); + break; + default: + SetHelp(NULL,NULL); + break; + } +} + +eOSState cMenuMarkAd::ProcessKey(eKeys Key) +{ + cOsdMarkAd *osd; + + eOSState state=osUnknown; + switch (Key) + { + case kRed: + osd=(cOsdMarkAd *) Get(Current()); + if ((osd) && (osd->Selectable())) + { + struct recs *entry=osd->GetEntry(); + if ((entry) && (entry->Pid)) + { + dsyslog("sending TSTP to %i",entry->Pid); + kill(entry->Pid,SIGTSTP); + SetHelp(NULL,tr("Continue")); + } + } + break; + + case kGreen: + osd=(cOsdMarkAd *) Get(Current()); + if ((osd) && (osd->Selectable())) + { + struct recs *entry=osd->GetEntry(); + if ((entry) && (entry->Pid)) + { + dsyslog("sending CONT to %i",entry->Pid); + kill(entry->Pid,SIGCONT); + SetHelp(tr("Pause"),NULL); + } + } + break; + + case kUp: + CursorUp(); + osd=(cOsdMarkAd *) Get(Current()); + if ((osd) && (osd->Selectable())) + { + SetHelpText(osd->GetEntry()); + } + break; + + case kDown: + CursorDown(); + osd=(cOsdMarkAd *) Get(Current()); + if ((osd) && (osd->Selectable())) + { + SetHelpText(osd->GetEntry()); + } + break; + + case kOk: + state=osBack; + break; + + case kNone: + if (time(NULL)>(last+2)) + { + if (write()) + { + cOsdMarkAd *osd=(cOsdMarkAd *) Get(Current()); + if ((osd) && (osd->Selectable())) + { + SetHelpText(osd->GetEntry()); + } + } + else + { + SetHelpText(NULL); + } + last=time(NULL); + } + break; + + default: + state=cOsdMenu::ProcessKey(Key); + break; + } + return state; +} diff --git a/plugin/menu.h b/plugin/menu.h new file mode 100644 index 0000000..1557e19 --- /dev/null +++ b/plugin/menu.h @@ -0,0 +1,39 @@ +/* + * menu.h: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ +#ifndef __menu_h_ +#define __menu_h_ + +#include <signal.h> +#include <vdr/menu.h> +#include <vdr/font.h> +#include "status.h" + +class cOsdMarkAd : public cOsdItem +{ +private: + struct recs *entry; +public: + cOsdMarkAd(struct recs *Entry); + struct recs *GetEntry() + { + return entry; + } +}; + +class cMenuMarkAd : public cOsdMenu +{ +private: + cStatusMarkAd *status; + void SetHelpText(struct recs *Entry); + bool write(); + time_t last; +public: + cMenuMarkAd(cStatusMarkAd *Status); + eOSState ProcessKey(eKeys Key); +}; + +#endif diff --git a/plugin/po/de_DE.po b/plugin/po/de_DE.po index 7290603..847f107 100644 --- a/plugin/po/de_DE.po +++ b/plugin/po/de_DE.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr\n" "Report-Msgid-Bugs-To: <see README>\n" -"POT-Creation-Date: 2010-03-26 16:28+0100\n" +"POT-Creation-Date: 2010-04-08 11:24+0200\n" "PO-Revision-Date: 2009-08-27 14:18+0200\n" "Last-Translator: Jochen Dolze <vdr@dolze.de>\n" "Language-Team: <vdr@linuxtv.org>\n" @@ -13,7 +13,55 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" msgid "markad still running" -msgstr "markad läuft noch" +msgstr "MarkAd läuft noch" + +msgid "running" +msgstr "aktiv" + +msgid "sleeping" +msgstr "wartend" + +msgid "inactive" +msgstr "inaktiv" + +msgid "zombie" +msgstr "zombie" + +msgid "stopped" +msgstr "angehalten" + +msgid "unknown" +msgstr "unbekannt" + +msgid "markad status" +msgstr "MarkAd Status" + +msgid "Recording\t Status" +msgstr "Aufnahme\t Status" + +msgid "no running markad found" +msgstr "Kein aktives MarkAd gefunden" + +msgid "Pause" +msgstr "Pause" + +msgid "Continue" +msgstr "Weiter" + +msgid "after" +msgstr "danach" + +msgid "during" +msgstr "während" + +msgid "execution" +msgstr "Ausführung" + +msgid "while recording" +msgstr "während einer Aufnahme" + +msgid "while playing" +msgstr "während einer Wiedergabe" msgid "Mark advertisements" msgstr "Markiere Werbung" diff --git a/plugin/po/it_IT.po b/plugin/po/it_IT.po index b504784..e75b2bc 100644 --- a/plugin/po/it_IT.po +++ b/plugin/po/it_IT.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr\n" "Report-Msgid-Bugs-To: <see README>\n" -"POT-Creation-Date: 2010-03-26 16:28+0100\n" +"POT-Creation-Date: 2010-04-08 11:24+0200\n" "PO-Revision-Date: 2009-11-14 18:06+0100\n" "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" "Language-Team: <vdr@linuxtv.org>\n" @@ -18,5 +18,53 @@ msgstr "" msgid "markad still running" msgstr "" +msgid "running" +msgstr "" + +msgid "sleeping" +msgstr "" + +msgid "inactive" +msgstr "" + +msgid "zombie" +msgstr "" + +msgid "stopped" +msgstr "" + +msgid "unknown" +msgstr "" + +msgid "markad status" +msgstr "" + +msgid "Recording\t Status" +msgstr "" + +msgid "no running markad found" +msgstr "" + +msgid "Pause" +msgstr "" + +msgid "Continue" +msgstr "" + +msgid "after" +msgstr "" + +msgid "during" +msgstr "" + +msgid "execution" +msgstr "" + +msgid "while recording" +msgstr "" + +msgid "while playing" +msgstr "" + msgid "Mark advertisements" msgstr "Segna i marcatori della pubblicità" diff --git a/plugin/setup.cpp b/plugin/setup.cpp new file mode 100644 index 0000000..3b51a1f --- /dev/null +++ b/plugin/setup.cpp @@ -0,0 +1,69 @@ +/* + * setup.cpp: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ + +#include "setup.h" + +cSetupMarkAd::cSetupMarkAd(struct setup *Setup) +{ + setup=Setup; + + processduring=(int) setup->ProcessDuring; + whilerecording=setup->whileRecording; + whileplaying=setup->whilePlaying; + + processTexts[0]=tr("after"); + processTexts[1]=tr("during"); + + write(); +} + +void cSetupMarkAd::write(void) +{ + + Clear(); + Add(new cMenuEditStraItem(tr("execution"),&processduring,2,processTexts)); + if (!processduring) + { + Add(new cMenuEditBoolItem(tr("while recording"),&whilerecording)); + Add(new cMenuEditBoolItem(tr("while playing"),&whileplaying)); + } + Display(); +} + +eOSState cSetupMarkAd::ProcessKey(eKeys Key) +{ + + eOSState state=osUnknown; + switch (Key) + { + case kLeft: + state=cMenuSetupPage::ProcessKey(Key); + if (Current()==0) write(); + break; + + case kRight: + state=cMenuSetupPage::ProcessKey(Key); + if (Current()==0) write(); + break; + + default: + state=cMenuSetupPage::ProcessKey(Key); + break; + } + return state; +} + +void cSetupMarkAd::Store(void) +{ + SetupStore("Execution",processduring); + SetupStore("whileRecording",whilerecording); + SetupStore("whilePlaying",whileplaying); + + setup->ProcessDuring=(bool) processduring; + setup->whileRecording=(bool) whilerecording; + setup->whilePlaying=(bool) whileplaying; +} diff --git a/plugin/setup.h b/plugin/setup.h new file mode 100644 index 0000000..5421457 --- /dev/null +++ b/plugin/setup.h @@ -0,0 +1,36 @@ +/* + * setup.h: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + */ +#ifndef __setup_h_ +#define __setup_h_ + +#include <vdr/menuitems.h> +#include "status.h" + +struct setup +{ + bool ProcessDuring; + bool whileRecording; + bool whilePlaying; +}; + +class cSetupMarkAd : public cMenuSetupPage +{ +private: + const char *processTexts[2]; + struct setup *setup; + int processduring; + int whilerecording; + int whileplaying; + void write(void); +protected: + virtual void Store(void); +public: + cSetupMarkAd(struct setup *setup); + eOSState ProcessKey(eKeys Key); +}; + +#endif diff --git a/plugin/status.cpp b/plugin/status.cpp index 8cf4966..fe074ac 100644 --- a/plugin/status.cpp +++ b/plugin/status.cpp @@ -7,130 +7,280 @@ #include "status.h" -void cStatusMarkAd::Recording(const cDevice *Device, const char *UNUSED(Name), const char *FileName, bool On) +cStatusMarkAd::cStatusMarkAd(const char *BinDir, const char *LogoDir, struct setup *Setup) +{ + setup=Setup; + bindir=BinDir; + logodir=LogoDir; + actpos=0; + memset(&recs,0,sizeof(recs)); +} + +cStatusMarkAd::~cStatusMarkAd() +{ + for (int i=0; i<(MAXDEVICES*MAXRECEIVERS); i++) + { + Remove(i); + } +} + +int cStatusMarkAd::Recording() +{ + int cnt=0; + for (int i=0; i<cDevice::NumDevices(); i++) + { + cDevice *dev=cDevice::GetDevice(i); + if (dev) + { + if (dev->Receiving()) cnt++; + } + } + return cnt; +} + +bool cStatusMarkAd::Replaying() +{ + for (int i=0; i<cDevice::NumDevices(); i++) + { + cDevice *dev=cDevice::GetDevice(i); + if (dev) + { + if (dev->Replaying()) return true; + } + } + return false; +} + +void cStatusMarkAd::Replaying(const cControl *UNUSED(Control), const char *UNUSED(Name), + const char *UNUSED(FileName), bool On) +{ + if (setup->whilePlaying) return; + if (On) + { + Pause(NULL); + } + else + { + if (!Recording()) Continue(NULL); + } +} + +void cStatusMarkAd::Recording(const cDevice *UNUSED(Device), const char *Name, + const char *FileName, bool On) { - if (!Device) return; // just to be safe if (!FileName) return; // we cannot operate without a filename if (!bindir) return; // we cannot operate without bindir if (!logodir) return; // we dont want to operate without logodir if (On) { - // Start markad with (before) recording + // Start markad with recording cString cmd = cString::sprintf("\"%s\"/markad --online=2 -l \"%s\" before \"%s\"",bindir, logodir,FileName); if (SystemExec(cmd)!=-1) { - Add(FileName); + usleep(200000); + int pos=Add(FileName,Name); + if (getPid(pos) && getStatus(pos)) + { + if (!setup->ProcessDuring) + { + if (!setup->whileRecording) + { + Pause(NULL); + } + else + { + Pause(FileName); + } + } + } } } else { -#if 0 - // Start markad after recording - cString cmd = cString::sprintf("\"%s\"/markad -l \"%s\" after \"%s\"",bindir, - logodir,FileName); - if (SystemExec(cmd)!=-1) + if (!setup->ProcessDuring) { - Add(FileName); + if (!setup->whileRecording) + { + if (!setup->whilePlaying) + { + if (!Recording() && !Replaying()) Continue(NULL); + } + else + { + if (!Recording()) Continue(NULL); + } + } + else + { + Continue(FileName); + } } -#endif - // TODO: Start second pass? } +} +bool cStatusMarkAd::getStatus(int Position) +{ + if (Position<0) return false; + if (!recs[Position].Pid) return false; + int ret=0; + char procname[256]=""; + snprintf(procname,sizeof(procname),"/proc/%i/stat",recs[Position].Pid); + FILE *fstat=fopen(procname,"r"); + if (fstat) + { + // found a running markad + ret=fscanf(fstat,"%*d %*s %c",&recs[Position].Status); + fclose(fstat); + } + else + { + if (errno==ENOENT) + { + // no such file or directory -> markad done or crashed + // remove filename from list + Remove(Position); + } + } + return (ret==1); } -cStatusMarkAd::cStatusMarkAd(const char *BinDir, const char *LogoDir) +bool cStatusMarkAd::getPid(int Position) { - bindir=BinDir; - logodir=LogoDir; - memset(&recs,0,sizeof(recs)); + if (Position<0) return false; + if (!recs[Position].FileName) return false; + if (recs[Position].Pid) return true; + int ret=0; + char *buf; + if (asprintf(&buf,"%s/markad.pid",recs[Position].FileName)==-1) return false; + + FILE *fpid=fopen(buf,"r"); + if (fpid) + { + free(buf); + int pid; + ret=fscanf(fpid,"%i\n",&pid); + if (ret==1) recs[Position].Pid=pid; + fclose(fpid); + } + else + { + if (errno==ENOENT) + { + // no such file or directory -> markad done or crashed + // remove entry from list + Remove(Position); + } + free(buf); + } + return (ret==1); } -cStatusMarkAd::~cStatusMarkAd() +bool cStatusMarkAd::GetNextActive(struct recs **RecEntry) { - for (int i=0; i<(MAXDEVICES*MAXRECEIVERS); i++) + if (!RecEntry) return false; + *RecEntry=NULL; + + if (actpos>=(MAXDEVICES*MAXRECEIVERS)) return true; + + do { - if (recs[i]) free(recs[i]); + if ((recs[actpos].FileName) && (recs[actpos].Pid)) + { + if (getStatus(actpos)) + { + *RecEntry=&recs[actpos++]; + break; + } + } + actpos++; } + while (actpos<(MAXDEVICES*MAXRECEIVERS)); + + return true; } bool cStatusMarkAd::MarkAdRunning() { - bool running=false; + struct recs *tmpRecs=NULL; + ResetActPos(); + GetNextActive(&tmpRecs); + return (tmpRecs!=NULL); +} + +void cStatusMarkAd::Remove(int Position) +{ + if (recs[Position].FileName) + { + dsyslog("markad: removing %s at position %i",recs[Position].FileName,Position); + free(recs[Position].FileName); + recs[Position].FileName=NULL; + } + if (recs[Position].Name) + { + free(recs[Position].Name); + recs[Position].Name=NULL; + } + recs[Position].Status=0; + recs[Position].Pid=0; +} + +int cStatusMarkAd::Add(const char *FileName, const char *Name) +{ for (int i=0; i<(MAXDEVICES*MAXRECEIVERS); i++) { - if (recs[i]) + if (!recs[i].FileName) { - char *buf; - if (asprintf(&buf,"%s/markad.pid",recs[i])==-1) + dsyslog("markad: adding %s at position %i",FileName,i); + recs[i].FileName=strdup(FileName); + recs[i].Name=strdup(Name); + recs[i].Status=0; + recs[i].Pid=0; + return i; + } + } + return -1; +} + +void cStatusMarkAd::Pause(const char *FileName) +{ + for (int i=0; i<(MAXDEVICES*MAXRECEIVERS); i++) + { + if (FileName) + { + if ((recs[i].FileName) && (!strcmp(recs[i].FileName,FileName)) && (recs[i].Pid)) { - // this is crude, but if we fail to allocate memory something - // is going really wrong! - return false; + kill(recs[i].Pid,SIGTSTP); } - // check for running markad process - FILE *fpid=fopen(buf,"r"); - free(buf); - if (fpid) - { - int pid,ret; - ret=fscanf(fpid,"%i\n",&pid); - fclose(fpid); - if (ret==1) - { - char procname[256]=""; - snprintf(procname,sizeof(procname),"/proc/%i",pid); - struct stat statbuf; - if (stat(procname,&statbuf)==0) - { - // found a running markad - running=true; - } - else - { - if (errno==ENOENT) - { - // no such file or directory -> markad crashed? - // remove filename from list - free(recs[i]); - recs[i]=NULL; - } - else - { - // serious error? -> let vdr close - return false; - } - } - } - } - else + } + else + { + if (recs[i].Pid) { - if (errno==ENOENT) - { - // no such file or directory -> markad already finished - // remove filename from list - free(recs[i]); - recs[i]=NULL; - } - else - { - // serious error? -> let vdr close - return false; - } + kill(recs[i].Pid,SIGTSTP); } } } - return running; } -void cStatusMarkAd::Add(const char *FileName) +void cStatusMarkAd::Continue(const char *FileName) { for (int i=0; i<(MAXDEVICES*MAXRECEIVERS); i++) { - if (!recs[i]) + if (FileName) { - recs[i]=strdup(FileName); + if ((recs[i].FileName) && (!strcmp(recs[i].FileName,FileName)) && (recs[i].Pid)) + { + kill(recs[i].Pid,SIGCONT); + } + } + else + { + if (recs[i].Pid) + { + kill(recs[i].Pid,SIGCONT); + } } } } diff --git a/plugin/status.h b/plugin/status.h index fbdd7c7..83dd23f 100644 --- a/plugin/status.h +++ b/plugin/status.h @@ -7,24 +7,52 @@ #ifndef __status_h_ #define __status_h_ +#include <signal.h> #include <vdr/status.h> +#include "setup.h" #define UNUSED(v) UNUSED_ ## v __attribute__((unused)) +struct recs +{ + char *Name; + char *FileName; + pid_t Pid; + char Status; +}; + // --- cStatusMarkAd class cStatusMarkAd : public cStatus { private: - char *recs[MAXDEVICES*MAXRECEIVERS]; + struct recs recs[MAXDEVICES*MAXRECEIVERS]; + struct setup *setup; + const char *bindir; const char *logodir; - void Add(const char *FileName); + + int actpos; + + bool getPid(int Position); + bool getStatus(int Position); + int Recording(); + bool Replaying(); + int Add(const char *FileName, const char *Name); + void Remove(int Position); + void Pause(const char *FileName); + void Continue(const char *FileName); protected: virtual void Recording(const cDevice *Device, const char *Name, const char *FileName, bool On); + virtual void Replaying(const cControl *Control, const char *Name, const char *FileName, bool On); public: - cStatusMarkAd(const char *BinDir,const char *LogoDir); + cStatusMarkAd(const char *BinDir,const char *LogoDir, struct setup *Setup); ~cStatusMarkAd(); bool MarkAdRunning(void); + void ResetActPos(void) + { + actpos=0; + } + bool GetNextActive(struct recs **RecEntry); }; #endif |