summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohann Friedrichs <johann.friedrichs@web.de>2022-01-30 18:03:42 +0100
committerJohann Friedrichs <johann.friedrichs@web.de>2022-01-30 18:11:37 +0100
commite101df04a2e19c49293965223e6d4bbf719ed78c (patch)
tree57622a1efeb6eb73c73c9be0befd1b98cc41d88f
parentad5448e5ad52d0084af3da9e57f9074df79b2db0 (diff)
downloadvdr-plugin-epgsearch-e101df04a2e19c49293965223e6d4bbf719ed78c.tar.gz
vdr-plugin-epgsearch-e101df04a2e19c49293965223e6d4bbf719ed78c.tar.bz2
Changed handling of finished recordings
Allow missing timer-Object (vdr > 2.5.x deletes non-VPS timers immediately after recording end) We now use the Recording-Filename to find Start- and Stoptimes
-rw-r--r--HISTORY10
-rw-r--r--HISTORY.DE52
-rw-r--r--menu_commands.c2
-rw-r--r--recdone.c14
-rw-r--r--recdone.h12
-rw-r--r--recdone_thread.c89
-rw-r--r--recstatus.c16
7 files changed, 127 insertions, 68 deletions
diff --git a/HISTORY b/HISTORY
index ff78347..3edad7f 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,16 @@
VDR Plugin 'epgsearch' Revision History
---------------------------------------
+2022-01-30
+new:
+- Allow missing timer-Object in Recording-Done-Processing
+ (vdr > 2.5.x compatibility)
+
+2021-12-10
+fixes:
+- Wrong device selection for conflict check
+- compareSubtitle supports more than 2 values
+
2021-05-24; Version 2.4.1
fixes:
- Fixed conflictcheck for encrypted channels with internal CAMs
diff --git a/HISTORY.DE b/HISTORY.DE
index 0b2e9be..8704979 100644
--- a/HISTORY.DE
+++ b/HISTORY.DE
@@ -1,27 +1,37 @@
VDR Plugin 'epgsearch' Revision History
---------------------------------------
--2021-05-24; Version 2.4.1
--fixes:
--- Fixed conflictcheck for encrypted channels with internal CAMs
--- Fixed compiling with gcc11
--- Updated deprecated calls to SetItemEvent
--- Temporally(?) added #define DISABLE_TEMPLATES_COLLIDING_WITH_STL for
--- compatibility with vdr 2.5.4
--
--2021-04-12
--neu:
--- Improved handling of remote timers
--- Replace auto_ptr with unique_ptr for c++11 (kfb77@vdr-portal.de)
--- Delay threads after pluginstart 10 secs (configurable)
--- Changed fgets to allow compiling with clang
--- Clarified "avoid repeats". Forced subtitle-comparison is named "yes" again
-- New option "allow empty"
--fixes:
--- Fixed several lock sequence errors
--- Fix utf-8 encoding in docs and manpages (kfb77 and seahawk1986@vdr-portal.de)
--- Fixed possible format overflow
--- Fixed displaying NAME in generated manpages thanks to etobi
+2022-01-30
+neu:
+- Allow missing timer-Object in Recording-Done-Processing
+ (vdr > 2.5.x compatibility)
+
+2021-12-10
+fixes:
+- Wrong device selection for conflict check
+- compareSubtitle supports more than 2 values
+
+2021-05-24; Version 2.4.1
+fixes:
+- Fixed conflictcheck for encrypted channels with internal CAMs
+- Fixed compiling with gcc11
+- Updated deprecated calls to SetItemEvent
+- Temporally(?) added #define DISABLE_TEMPLATES_COLLIDING_WITH_STL for
+- compatibility with vdr 2.5.4
+
+2021-04-12
+neu:
+- Improved handling of remote timers
+- Replace auto_ptr with unique_ptr for c++11 (kfb77@vdr-portal.de)
+- Delay threads after pluginstart 10 secs (configurable)
+- Changed fgets to allow compiling with clang
+- Clarified "avoid repeats". Forced subtitle-comparison is named "yes" again
+ New option "allow empty"
+fixes:
+- Fixed several lock sequence errors
+- Fix utf-8 encoding in docs and manpages (kfb77 and seahawk1986@vdr-portal.de)
+- Fixed possible format overflow
+- Fixed displaying NAME in generated manpages thanks to etobi
2018-04-16; Version 2.4.0
neu:
diff --git a/menu_commands.c b/menu_commands.c
index 99ca744..028bd99 100644
--- a/menu_commands.c
+++ b/menu_commands.c
@@ -182,7 +182,7 @@ eOSState cMenuSearchCommands::MarkAsRecorded(void)
return osContinue;
cTimer* dummyTimer = new cTimer(event);
cMutexLock RecsDoneLock(&RecsDone);
- RecsDone.Add(new cRecDone(dummyTimer, event, search));
+ RecsDone.Add(new cRecDone(dummyTimer, event, search, "Unused"));
RecsDone.Save();
delete dummyTimer;
return osBack;
diff --git a/recdone.c b/recdone.c
index 53780cd..ce63ffe 100644
--- a/recdone.c
+++ b/recdone.c
@@ -48,15 +48,20 @@ cRecDone::cRecDone()
buffer = NULL;
searchID = -1;
rawdescription = NULL;
+ fileName = NULL;
}
-cRecDone::cRecDone(const cTimer* Timer, const cEvent* Event, cSearchExt* Search)
+cRecDone::cRecDone(const cTimer* Timer, const cEvent* Event, cSearchExt* Search, const char* Name)
{
title = shortText = description = aux = rawdescription = NULL;
startTime = 0;
+ timerStart = 0;
+ timerStop = 0;
+ vpsused = false;
duration = 0;
searchID = Search ? Search->ID : -1;
buffer = NULL;
+ fileName = strdup(Name);
if (Event) {
if (Event->Title())
@@ -71,6 +76,9 @@ cRecDone::cRecDone(const cTimer* Timer, const cEvent* Event, cSearchExt* Search)
channelID = Timer->Channel()->GetChannelID();
if (!isempty(Timer->Aux()))
aux = strdup(Timer->Aux());
+ timerStart = Timer->StartTime();
+ timerStop = Timer->StopTime();
+ vpsused = Timer->HasFlags(tfVps) && Event->Vps();
} else {
channelID = tChannelID::InvalidID;
aux = NULL;
@@ -104,6 +112,10 @@ cRecDone::~cRecDone()
free(aux);
aux = NULL;
}
+ if (fileName) {
+ free(fileName);
+ fileName = NULL;
+ }
}
diff --git a/recdone.h b/recdone.h
index cfad67f..6cfa50b 100644
--- a/recdone.h
+++ b/recdone.h
@@ -38,17 +38,21 @@ public:
char *title; // Title of this event
char *shortText; // Short description of this event
char *description; // Description of this event
+ char *fileName; // Name used in MsgRecording
char *aux; // Aux info
- time_t startTime; // Start time of the timer
- int duration;
- int searchID; // ID of the search, that triggered this recording
+ time_t startTime; // Start time of the event
+ time_t timerStart; // Start time of the timer
+ time_t timerStop; // Stop time of the timer
+ bool vpsused;
+ int duration; // Duration of event
+ int searchID; // ID of the search, that triggered this recording
tChannelID channelID;
char* rawdescription;
static char *buffer;
cRecDone();
- cRecDone(const cTimer*, const cEvent* event, cSearchExt* search);
+ cRecDone(const cTimer*, const cEvent* event, cSearchExt* search, const char* name);
~cRecDone();
static bool Read(FILE *f);
diff --git a/recdone_thread.c b/recdone_thread.c
index 6b0e02b..97f0991 100644
--- a/recdone_thread.c
+++ b/recdone_thread.c
@@ -80,7 +80,7 @@ void cRecdoneThread::Action(void)
time_t now = time(NULL);
// remove timers that finished recording from TimersRecording
// incomplete recordings are kept for a while, perhaps they will be resumed
- LOCK_TIMERS_READ;
+ LOCK_TIMERS_READ; // must be done before TimersRecordingLock
while (m_fnames.size()) {
vector<string>::iterator it = m_fnames.begin();
const char *m_filename = (*it).c_str();
@@ -88,49 +88,72 @@ void cRecdoneThread::Action(void)
cMutexLock TimersRecordingLock(&TimersRecording);
cRecDoneTimerObj *tiR = TimersRecording.First();
while (tiR) {
- // check if timer still exists
+ // check if a timer still exists
+ // if we find a timer we take its values, else from recDone
bool found = false;
-
for (const cTimer *ti = Timers->First(); ti; ti = Timers->Next(ti))
if (ti == tiR->timer) {
found = true;
break;
}
- if (found && !tiR->timer->Recording()) {
- if (tiR->recDone) {
- cSearchExt* search = SearchExts.GetSearchFromID(tiR->recDone->searchID);
- if (!search) return;
- // check if recording has ended before timer end
+ if (!tiR->recDone) {
+ LogFile.Log(3, "recdone: this tiR has no recDone struct");
+ tiR = TimersRecording.Next(tiR);
+ continue;
+ }
+ if (found && tiR->timer->Recording()) {
+ LogFile.Log(3, "recdone: tiR for %s is recording",tiR->recDone->fileName);
+ tiR = TimersRecording.Next(tiR);
+ continue;
+ }
- bool complete = true;
+ LogFile.Log(2, "recdone: processing tiR for %s",tiR->recDone->fileName);
+ if (strcmp(tiR->recDone->fileName,m_filename) == 0) {
+ // we have the correct entry for the check
+ bool complete = true;
+ cSearchExt* search = SearchExts.GetSearchFromID(tiR->recDone->searchID);
+ int recFraction = 100;
+ time_t stopTime = found ? tiR->timer->StopTime() : tiR->recDone->timerStop;
+
+ if (tiR->lastBreak == -1 || !search) { // started too late or missing searchID
+ LogFile.Log(2, "started too late : '%s' or missing searchID %d", found?tiR->timer->File():m_filename, tiR->recDone->searchID);
+ tiR->lastBreak = 0; // triggers deletion
+ }
+ else {
+ // check if recording length is as expected
const cRecording *pRecording;
{
LOCK_RECORDINGS_READ;
pRecording = Recordings->GetByName(m_filename);
+ long timerLengthSecs = found ? tiR->timer->StopTime() - tiR->timer->StartTime() : tiR->recDone->timerStop - tiR->recDone->timerStart;
+ int recLen = 0;
+ if (pRecording && timerLengthSecs) {
+ recLen = RecLengthInSecs(pRecording);
+ recFraction = double(recLen) * 100 / timerLengthSecs;
+ }
}
- long timerLengthSecs = tiR->timer->StopTime() - tiR->timer->StartTime();
- int recFraction = 100;
- if (pRecording && timerLengthSecs) {
- int recLen = RecLengthInSecs(pRecording);
- recFraction = double(recLen) * 100 / timerLengthSecs;
- }
- bool vpsUsed = tiR->timer->HasFlags(tfVps) && tiR->timer->Event() && tiR->timer->Event()->Vps();
- if ((!vpsUsed && now < tiR->timer->StopTime()) || recFraction < (vpsUsed ? 90 : 98)) { // assure timer has reached its end or at least 98% were recorded
+ bool vpsUsed = found ? tiR->timer->HasFlags(tfVps) && tiR->timer->Event() && tiR->timer->Event()->Vps():tiR->recDone->vpsused;
+ if ((!vpsUsed && now < stopTime) || recFraction < (vpsUsed ? 90 : 98)) { // assure timer has reached its end or at least 98% were recorded
complete = false;
- LogFile.Log(1, "finished: '%s' (not complete! - recorded only %d%%); search timer: '%s'; VPS used: %s", tiR->timer->File(), recFraction, search->search, vpsUsed ? "Yes" : "No");
+ LogFile.Log(1, "finished: '%s' (not complete! - recorded only %d%%); search timer: '%s'; VPS used: %s", found?tiR->timer->File():m_filename, recFraction, search->search, vpsUsed ? "Yes" : "No");
+ dsyslog("epgsearch: finished: '%s' (not complete! - recorded only %d%%); search timer: '%s'; VPS used: %s", found?tiR->timer->File():m_filename, recFraction, search->search, vpsUsed ? "Yes" : "No");
} else {
- LogFile.Log(1, "finished: '%s'; search timer: '%s'; VPS used: %s", tiR->timer->File(), search->search, vpsUsed ? "Yes" : "No");
- if (recFraction < 100)
+ LogFile.Log(1, "finished: '%s' (complete); search timer: '%s'; VPS used: %s", found?tiR->timer->File():m_filename, search->search, vpsUsed ? "Yes" : "No");
+ if (recFraction < 100) {
LogFile.Log(2, "recorded %d%%'", recFraction);
+ dsyslog("epgsearch: finished: '%s' (complete) recorded %d%%", found?tiR->timer->File():m_filename, (recFraction<100) ? recFraction : 100);
+ }
+ else
+ dsyslog("epgsearch: finished: '%s' (complete)", found?tiR->timer->File():m_filename);
}
- if (complete) {
+ if (complete) { // add to epgsearchdone.data
RecsDone.Add(tiR->recDone);
LogFile.Log(1, "added rec done for '%s~%s';%s", tiR->recDone->title ? tiR->recDone->title : "unknown title",
tiR->recDone->shortText ? tiR->recDone->shortText : "unknown subtitle",
search->search);
RecsDone.Save();
- tiR->recDone = NULL; // prevent deletion
+ tiR->recDone = NULL; // prevent deletion (now in RecsDone)
tiR->lastBreak = 0;
// check for search timers to delete automatically
@@ -139,28 +162,24 @@ void cRecdoneThread::Action(void)
// trigger a search timer update (skip running events)
search->skipRunningEvents = true;
updateForced = 1;
- } else if (tiR->lastBreak == 0) // store first break
+ } else if (tiR->lastBreak == 0) // not complete: assure break is set
tiR->lastBreak = now;
}
- if (tiR->lastBreak == 0 || (now - tiR->lastBreak) > ALLOWED_BREAK_INSECS) {
- // remove finished recordings or those with an unallowed break
- if (tiR->recDone) delete tiR->recDone; // clean up
- cRecDoneTimerObj *tiRNext = TimersRecording.Next(tiR);
- TimersRecording.Del(tiR);
- tiR = tiRNext;
- continue;
+ } // handled only tiR with correct filename
+ // cleanup
+ if (!tiR->lastBreak || (now - tiR->lastBreak) > ALLOWED_BREAK_INSECS) {
+ // remove finished recordings or those with an unallowed break
+ if (tiR->recDone) { // if added to searchdone recDone is NULL
+ LogFile.Log(3, "recdone: remove tiR and recdone for %s", tiR->recDone->fileName);
+ delete tiR->recDone; // clean up
}
- break;
- }
- if (!found) {
- if (tiR->recDone) delete tiR->recDone; // clean up
cRecDoneTimerObj *tiRNext = TimersRecording.Next(tiR);
TimersRecording.Del(tiR);
tiR = tiRNext;
continue;
}
tiR = TimersRecording.Next(tiR);
- }
+ } // while tiR
m_fnames.erase(it);
} // while fnames
LogFile.Log(1, "recdone_thread ended");
diff --git a/recstatus.c b/recstatus.c
index 408f159..be07db4 100644
--- a/recstatus.c
+++ b/recstatus.c
@@ -47,12 +47,12 @@ void cRecStatusMonitor::Recording(const cDevice *Device, const char *Name, const
if (EPGSearchConfig.checkTimerConflOnRecording)
cConflictCheckThread::Init((cPluginEpgsearch*)cPluginManager::GetPlugin("epgsearch"), true);
- LOCK_TIMERS_READ;
+ LOCK_TIMERS_READ; // already set (thread is vdr-main)
for (const cTimer *ti = Timers->First(); ti; ti = Timers->Next(ti))
if (ti->Recording()) {
// check if this is a new entry
cRecDoneTimerObj *tiRFound = NULL;
- cMutexLock TimersRecordingLock(&TimersRecording);
+ cMutexLock TimersRecordingLock(&TimersRecording); // lock after TIMERS
for (cRecDoneTimerObj *tiR = TimersRecording.First(); tiR; tiR = TimersRecording.Next(tiR))
if (tiR->timer == ti) {
tiRFound = tiR;
@@ -61,7 +61,7 @@ void cRecStatusMonitor::Recording(const cDevice *Device, const char *Name, const
if (tiRFound) { // already handled, perhaps a resume
if (tiRFound->lastBreak > 0 && now - tiRFound->lastBreak <= ALLOWED_BREAK_INSECS) {
- LogFile.Log(1, "accepting resume of '%s' on device %d", Name, Device->CardIndex());
+ LogFile.Log(1, "assuming resume of '%s' on device %d", Name, Device->CardIndex());
tiRFound->lastBreak = 0;
}
continue;
@@ -70,8 +70,9 @@ void cRecStatusMonitor::Recording(const cDevice *Device, const char *Name, const
cRecDoneTimerObj* timerObj = new cRecDoneTimerObj(ti, Device->DeviceNumber());
TimersRecording.Add(timerObj);
+ // ignore if not avoid repeats and no auto-delete
cSearchExt* search = TriggeredFromSearchTimer(ti);
- if (!search || (search->avoidRepeats == 0 && search->delMode == 0)) // ignore if not avoid repeats and no auto-delete
+ if (!search || (search->avoidRepeats == 0 && search->delMode == 0))
continue;
bool vpsUsed = ti->HasFlags(tfVps) && ti->Event() && ti->Event()->Vps();
@@ -87,11 +88,14 @@ void cRecStatusMonitor::Recording(const cDevice *Device, const char *Name, const
continue;
}
time_t now = time(NULL);
+ timerObj->recDone = new cRecDone(ti, event, search, Filename);
+ LogFile.Log(3, "epgsearch: created recDone for %s",Filename);
if (vpsUsed || now < ti->StartTime() + 60) { // allow a delay of one minute
- timerObj->recDone = new cRecDone(ti, event, search);
return;
- } else
+ } else {
+ timerObj->lastBreak = -1; // mark as incomplete
LogFile.Log(1, "recording started too late! will be ignored");
+ }
}
}