mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
The list of recordings is now read in a separate thread
This commit is contained in:
parent
83985eff47
commit
9e8aac3882
@ -14,6 +14,8 @@ Carsten Koch <Carsten.Koch@icem.de>
|
|||||||
for fixing the watchdog timer if the program hangs in OSD activities
|
for fixing the watchdog timer if the program hangs in OSD activities
|
||||||
for his support in keeping the Premiere World channels up to date in 'channels.conf'
|
for his support in keeping the Premiere World channels up to date in 'channels.conf'
|
||||||
for fixing converting summary.vdr files that would result in a very long 'short text'
|
for fixing converting summary.vdr files that would result in a very long 'short text'
|
||||||
|
for his help in testing and debugging reading the list of recordings in a
|
||||||
|
separate thread
|
||||||
|
|
||||||
Plamen Ganev <pganev@com-it.net>
|
Plamen Ganev <pganev@com-it.net>
|
||||||
for fixing the frequency offset for Hotbird channels
|
for fixing the frequency offset for Hotbird channels
|
||||||
|
19
HISTORY
19
HISTORY
@ -3807,7 +3807,7 @@ Video Disk Recorder Revision History
|
|||||||
- Implemented a hash for the channels to reduce the system load in the EIT scanning
|
- Implemented a hash for the channels to reduce the system load in the EIT scanning
|
||||||
thread (based on a patch by Georg Acher).
|
thread (based on a patch by Georg Acher).
|
||||||
|
|
||||||
2005-09-18: Version 1.3.33
|
2005-09-25: Version 1.3.33
|
||||||
|
|
||||||
- Fixed two errors in 'newplugin' (thanks to Alexander Rieger).
|
- Fixed two errors in 'newplugin' (thanks to Alexander Rieger).
|
||||||
- Fixed converting arbitrarily formatted summary.vdr files (thanks to Thomas Günther).
|
- Fixed converting arbitrarily formatted summary.vdr files (thanks to Thomas Günther).
|
||||||
@ -3824,3 +3824,20 @@ Video Disk Recorder Revision History
|
|||||||
- Removed obsolete 'shift' code in device.[hc].
|
- Removed obsolete 'shift' code in device.[hc].
|
||||||
- The SVDRP command DELR no longer triggers a complete reload of the global Recordings
|
- The SVDRP command DELR no longer triggers a complete reload of the global Recordings
|
||||||
list, but rather deletes that particular entry.
|
list, but rather deletes that particular entry.
|
||||||
|
- The list of recordings is now read in a separate thread, resulting in a faster
|
||||||
|
startup if there are a great many of recordings, or the disk(s) have to spin up.
|
||||||
|
If the Recordings menu is opened while the list of recordings is still being read,
|
||||||
|
the menu will be updated accordingly.
|
||||||
|
Plugins that access the global Recordings variable should lock the thread, either
|
||||||
|
by calling
|
||||||
|
|
||||||
|
Recordings.Lock();
|
||||||
|
...
|
||||||
|
Recordings.Unlock();
|
||||||
|
|
||||||
|
or by putting something like
|
||||||
|
|
||||||
|
cThreadLock RecordingsLock(&Recordings);
|
||||||
|
|
||||||
|
into the respective code block. Thanks to Carsten Koch for his help in testing
|
||||||
|
and debugging this.
|
||||||
|
74
menu.c
74
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 1.359 2005/09/03 11:42:27 kls Exp $
|
* $Id: menu.c 1.360 2005/09/25 09:45:01 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -1506,35 +1506,12 @@ cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus)
|
|||||||
{
|
{
|
||||||
base = Base ? strdup(Base) : NULL;
|
base = Base ? strdup(Base) : NULL;
|
||||||
level = Setup.RecordingDirs ? Level : -1;
|
level = Setup.RecordingDirs ? Level : -1;
|
||||||
|
Recordings.StateChanged(recordingsState); // just to get the current state
|
||||||
Display(); // this keeps the higher level menus from showing up briefly when pressing 'Back' during replay
|
Display(); // this keeps the higher level menus from showing up briefly when pressing 'Back' during replay
|
||||||
const char *LastReplayed = cReplayControl::LastReplayed();
|
Set();
|
||||||
cMenuRecordingItem *LastItem = NULL;
|
|
||||||
char *LastItemText = NULL;
|
|
||||||
if (!Base)
|
|
||||||
Recordings.Sort();
|
|
||||||
for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
|
|
||||||
if (!Base || (strstr(recording->Name(), Base) == recording->Name() && recording->Name()[strlen(Base)] == '~')) {
|
|
||||||
cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level);
|
|
||||||
if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) {
|
|
||||||
Add(Item);
|
|
||||||
LastItem = Item;
|
|
||||||
free(LastItemText);
|
|
||||||
LastItemText = strdup(LastItem->Text()); // must use a copy because of the counters!
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete Item;
|
|
||||||
if (LastItem) {
|
|
||||||
if (LastReplayed && strcmp(LastReplayed, recording->FileName()) == 0)
|
|
||||||
SetCurrent(LastItem);
|
|
||||||
if (LastItem->IsDirectory())
|
|
||||||
LastItem->IncrementCounter(recording->IsNew());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(LastItemText);
|
|
||||||
if (Current() < 0)
|
if (Current() < 0)
|
||||||
SetCurrent(First());
|
SetCurrent(First());
|
||||||
else if (OpenSubMenus && Open(true))
|
else if (OpenSubMenus && cReplayControl::LastReplayed() && Open(true))
|
||||||
return;
|
return;
|
||||||
SetHelpKeys();
|
SetHelpKeys();
|
||||||
}
|
}
|
||||||
@ -1570,6 +1547,45 @@ void cMenuRecordings::SetHelpKeys(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cMenuRecordings::Set(bool Refresh)
|
||||||
|
{
|
||||||
|
const char *CurrentRecording = cReplayControl::LastReplayed();
|
||||||
|
cMenuRecordingItem *LastItem = NULL;
|
||||||
|
char *LastItemText = NULL;
|
||||||
|
cThreadLock RecordingsLock(&Recordings);
|
||||||
|
if (Refresh) {
|
||||||
|
cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current());
|
||||||
|
if (ri) {
|
||||||
|
cRecording *Recording = GetRecording(ri);
|
||||||
|
if (Recording)
|
||||||
|
CurrentRecording = Recording->FileName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Clear();
|
||||||
|
Recordings.Sort();
|
||||||
|
for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
|
||||||
|
if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == '~')) {
|
||||||
|
cMenuRecordingItem *Item = new cMenuRecordingItem(recording, level);
|
||||||
|
if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) {
|
||||||
|
Add(Item);
|
||||||
|
LastItem = Item;
|
||||||
|
free(LastItemText);
|
||||||
|
LastItemText = strdup(LastItem->Text()); // must use a copy because of the counters!
|
||||||
|
}
|
||||||
|
else
|
||||||
|
delete Item;
|
||||||
|
if (LastItem) {
|
||||||
|
if (CurrentRecording && strcmp(CurrentRecording, recording->FileName()) == 0)
|
||||||
|
SetCurrent(LastItem);
|
||||||
|
if (LastItem->IsDirectory())
|
||||||
|
LastItem->IncrementCounter(recording->IsNew());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(LastItemText);
|
||||||
|
Display();
|
||||||
|
}
|
||||||
|
|
||||||
cRecording *cMenuRecordings::GetRecording(cMenuRecordingItem *Item)
|
cRecording *cMenuRecordings::GetRecording(cMenuRecordingItem *Item)
|
||||||
{
|
{
|
||||||
cRecording *recording = Recordings.GetByName(Item->FileName());
|
cRecording *recording = Recordings.GetByName(Item->FileName());
|
||||||
@ -1716,6 +1732,9 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
|
|||||||
case kYellow: return Delete();
|
case kYellow: return Delete();
|
||||||
case kBlue: return Info();
|
case kBlue: return Info();
|
||||||
case k1...k9: return Commands(Key);
|
case k1...k9: return Commands(Key);
|
||||||
|
case kNone: if (Recordings.StateChanged(recordingsState))
|
||||||
|
Set(true);
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2597,6 +2616,7 @@ static void SetTrackDescriptions(bool Live)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (cReplayControl::LastReplayed()) {
|
else if (cReplayControl::LastReplayed()) {
|
||||||
|
cThreadLock RecordingsLock(&Recordings);
|
||||||
cRecording *Recording = Recordings.GetByName(cReplayControl::LastReplayed());
|
cRecording *Recording = Recordings.GetByName(cReplayControl::LastReplayed());
|
||||||
if (Recording)
|
if (Recording)
|
||||||
Components = Recording->Info()->Components();
|
Components = Recording->Info()->Components();
|
||||||
|
4
menu.h
4
menu.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.h 1.73 2005/09/03 11:41:41 kls Exp $
|
* $Id: menu.h 1.74 2005/09/25 09:03:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MENU_H
|
#ifndef __MENU_H
|
||||||
@ -147,8 +147,10 @@ class cMenuRecordings : public cOsdMenu {
|
|||||||
private:
|
private:
|
||||||
char *base;
|
char *base;
|
||||||
int level;
|
int level;
|
||||||
|
int recordingsState;
|
||||||
static int helpKeys;
|
static int helpKeys;
|
||||||
void SetHelpKeys(void);
|
void SetHelpKeys(void);
|
||||||
|
void Set(bool Refresh = false);
|
||||||
cRecording *GetRecording(cMenuRecordingItem *Item);
|
cRecording *GetRecording(cMenuRecordingItem *Item);
|
||||||
bool Open(bool OpenSubMenus = false);
|
bool Open(bool OpenSubMenus = false);
|
||||||
eOSState Play(void);
|
eOSState Play(void);
|
||||||
|
96
recording.c
96
recording.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.c 1.114 2005/09/17 09:14:36 kls Exp $
|
* $Id: recording.c 1.115 2005/09/25 10:40:31 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
@ -60,17 +60,23 @@
|
|||||||
|
|
||||||
bool VfatFileSystem = false;
|
bool VfatFileSystem = false;
|
||||||
|
|
||||||
|
static cRecordings DeletedRecordings(true);
|
||||||
|
|
||||||
void RemoveDeletedRecordings(void)
|
void RemoveDeletedRecordings(void)
|
||||||
{
|
{
|
||||||
static time_t LastRemoveCheck = 0;
|
static time_t LastRemoveCheck = 0;
|
||||||
if (time(NULL) - LastRemoveCheck > REMOVECHECKDELTA) {
|
if (LastRemoveCheck == 0) {
|
||||||
|
DeletedRecordings.Update();
|
||||||
|
LastRemoveCheck = time(NULL) - REMOVECHECKDELTA * 9 / 10;
|
||||||
|
}
|
||||||
|
else if (time(NULL) - LastRemoveCheck > REMOVECHECKDELTA) {
|
||||||
// Make sure only one instance of VDR does this:
|
// Make sure only one instance of VDR does this:
|
||||||
cLockFile LockFile(VideoDirectory);
|
cLockFile LockFile(VideoDirectory);
|
||||||
if (!LockFile.Lock())
|
if (!LockFile.Lock())
|
||||||
return;
|
return;
|
||||||
// Remove the oldest file that has been "deleted":
|
// Remove the oldest file that has been "deleted":
|
||||||
cRecordings DeletedRecordings(true);
|
cThreadLock DeletedRecordingsLock(&DeletedRecordings);
|
||||||
if (DeletedRecordings.Load()) {
|
if (DeletedRecordings.Count()) {
|
||||||
cRecording *r = DeletedRecordings.First();
|
cRecording *r = DeletedRecordings.First();
|
||||||
cRecording *r0 = r;
|
cRecording *r0 = r;
|
||||||
while (r) {
|
while (r) {
|
||||||
@ -80,11 +86,14 @@ void RemoveDeletedRecordings(void)
|
|||||||
}
|
}
|
||||||
if (r0 && time(NULL) - r0->start > DELETEDLIFETIME * 3600) {
|
if (r0 && time(NULL) - r0->start > DELETEDLIFETIME * 3600) {
|
||||||
r0->Remove();
|
r0->Remove();
|
||||||
|
DeletedRecordings.Del(r0);
|
||||||
RemoveEmptyVideoDirectories();
|
RemoveEmptyVideoDirectories();
|
||||||
LastRemoveCheck += REMOVELATENCY;
|
LastRemoveCheck += REMOVELATENCY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
DeletedRecordings.Update();
|
||||||
LastRemoveCheck = time(NULL);
|
LastRemoveCheck = time(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,8 +113,8 @@ void AssertFreeDiskSpace(int Priority)
|
|||||||
return;
|
return;
|
||||||
// Remove the oldest file that has been "deleted":
|
// Remove the oldest file that has been "deleted":
|
||||||
isyslog("low disk space while recording, trying to remove a deleted recording...");
|
isyslog("low disk space while recording, trying to remove a deleted recording...");
|
||||||
cRecordings DeletedRecordings(true);
|
cThreadLock DeletedRecordingsLock(&DeletedRecordings);
|
||||||
if (DeletedRecordings.Load()) {
|
if (DeletedRecordings.Count()) {
|
||||||
cRecording *r = DeletedRecordings.First();
|
cRecording *r = DeletedRecordings.First();
|
||||||
cRecording *r0 = r;
|
cRecording *r0 = r;
|
||||||
while (r) {
|
while (r) {
|
||||||
@ -114,13 +123,20 @@ void AssertFreeDiskSpace(int Priority)
|
|||||||
r = DeletedRecordings.Next(r);
|
r = DeletedRecordings.Next(r);
|
||||||
}
|
}
|
||||||
if (r0 && r0->Remove()) {
|
if (r0 && r0->Remove()) {
|
||||||
|
DeletedRecordings.Del(r0);
|
||||||
LastFreeDiskCheck += REMOVELATENCY / Factor;
|
LastFreeDiskCheck += REMOVELATENCY / Factor;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// DeletedRecordings was empty, so to be absolutely sure there are no
|
||||||
|
// deleted recordings we need to double check:
|
||||||
|
DeletedRecordings.Update(true);
|
||||||
|
if (DeletedRecordings.Count())
|
||||||
|
return; // the next call will actually remove it
|
||||||
// No "deleted" files to remove, so let's see if we can delete a recording:
|
// No "deleted" files to remove, so let's see if we can delete a recording:
|
||||||
isyslog("...no deleted recording found, trying to delete an old recording...");
|
isyslog("...no deleted recording found, trying to delete an old recording...");
|
||||||
if (Recordings.Load()) {
|
cThreadLock RecordingsLock(&Recordings);
|
||||||
|
if (Recordings.Count()) {
|
||||||
cRecording *r = Recordings.First();
|
cRecording *r = Recordings.First();
|
||||||
cRecording *r0 = NULL;
|
cRecording *r0 = NULL;
|
||||||
while (r) {
|
while (r) {
|
||||||
@ -454,6 +470,7 @@ cRecording::cRecording(const char *FileName)
|
|||||||
name[p - FileName] = 0;
|
name[p - FileName] = 0;
|
||||||
name = ExchangeChars(name, false);
|
name = ExchangeChars(name, false);
|
||||||
}
|
}
|
||||||
|
GetResume();
|
||||||
// read an optional info file:
|
// read an optional info file:
|
||||||
char *InfoFileName = NULL;
|
char *InfoFileName = NULL;
|
||||||
asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX);
|
asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX);
|
||||||
@ -720,16 +737,38 @@ bool cRecording::Remove(void)
|
|||||||
cRecordings Recordings;
|
cRecordings Recordings;
|
||||||
|
|
||||||
cRecordings::cRecordings(bool Deleted)
|
cRecordings::cRecordings(bool Deleted)
|
||||||
|
:cThread("video directory scanner")
|
||||||
{
|
{
|
||||||
deleted = Deleted;
|
deleted = Deleted;
|
||||||
lastUpdate = 0;
|
lastUpdate = 0;
|
||||||
|
state = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRecordings::ScanVideoDir(const char *DirName)
|
cRecordings::~cRecordings()
|
||||||
|
{
|
||||||
|
Cancel(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cRecordings::Action(void)
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cRecordings::Refresh(bool Foreground)
|
||||||
|
{
|
||||||
|
lastUpdate = time(NULL); // doing this first to make sure we don't miss anything
|
||||||
|
Lock();
|
||||||
|
Clear();
|
||||||
|
ChangeState();
|
||||||
|
Unlock();
|
||||||
|
ScanVideoDir(VideoDirectory, Foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cRecordings::ScanVideoDir(const char *DirName, bool Foreground)
|
||||||
{
|
{
|
||||||
cReadDir d(DirName);
|
cReadDir d(DirName);
|
||||||
struct dirent *e;
|
struct dirent *e;
|
||||||
while ((e = d.Next()) != NULL) {
|
while ((Foreground || Running()) && (e = d.Next()) != NULL) {
|
||||||
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
||||||
char *buffer;
|
char *buffer;
|
||||||
asprintf(&buffer, "%s/%s", DirName, e->d_name);
|
asprintf(&buffer, "%s/%s", DirName, e->d_name);
|
||||||
@ -749,13 +788,17 @@ void cRecordings::ScanVideoDir(const char *DirName)
|
|||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
|
if (endswith(buffer, deleted ? DELEXT : RECEXT)) {
|
||||||
cRecording *r = new cRecording(buffer);
|
cRecording *r = new cRecording(buffer);
|
||||||
if (r->Name())
|
if (r->Name()) {
|
||||||
|
Lock();
|
||||||
Add(r);
|
Add(r);
|
||||||
|
ChangeState();
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
delete r;
|
delete r;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ScanVideoDir(buffer);
|
ScanVideoDir(buffer, Foreground);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(buffer);
|
free(buffer);
|
||||||
@ -763,18 +806,28 @@ void cRecordings::ScanVideoDir(const char *DirName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRecordings::NeedsUpdate(void)
|
bool cRecordings::StateChanged(int &State)
|
||||||
{
|
{
|
||||||
return lastUpdate <= LastModifiedTime(AddDirectory(VideoDirectory, ".update"));
|
int NewState = state;
|
||||||
|
bool Result = State != NewState;
|
||||||
|
State = state;
|
||||||
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRecordings::Load(void)
|
bool cRecordings::NeedsUpdate(void)
|
||||||
{
|
{
|
||||||
lastUpdate = time(NULL); // doing this first to make sure we don't miss anything
|
return lastUpdate < LastModifiedTime(AddDirectory(VideoDirectory, ".update"));
|
||||||
Clear();
|
}
|
||||||
ScanVideoDir(VideoDirectory);
|
|
||||||
Sort();
|
bool cRecordings::Update(bool Wait)
|
||||||
|
{
|
||||||
|
if (Wait) {
|
||||||
|
Refresh(true);
|
||||||
return Count() > 0;
|
return Count() > 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Start();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cRecording *cRecordings::GetByName(const char *FileName)
|
cRecording *cRecordings::GetByName(const char *FileName)
|
||||||
@ -788,18 +841,23 @@ cRecording *cRecordings::GetByName(const char *FileName)
|
|||||||
|
|
||||||
void cRecordings::AddByName(const char *FileName)
|
void cRecordings::AddByName(const char *FileName)
|
||||||
{
|
{
|
||||||
|
LOCK_THREAD;
|
||||||
cRecording *recording = GetByName(FileName);
|
cRecording *recording = GetByName(FileName);
|
||||||
if (!recording) {
|
if (!recording) {
|
||||||
recording = new cRecording(FileName);
|
recording = new cRecording(FileName);
|
||||||
Add(recording);
|
Add(recording);
|
||||||
|
ChangeState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRecordings::DelByName(const char *FileName)
|
void cRecordings::DelByName(const char *FileName)
|
||||||
{
|
{
|
||||||
|
LOCK_THREAD;
|
||||||
cRecording *recording = GetByName(FileName);
|
cRecording *recording = GetByName(FileName);
|
||||||
if (recording)
|
if (recording) {
|
||||||
Del(recording);
|
Del(recording);
|
||||||
|
ChangeState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cMark -----------------------------------------------------------------
|
// --- cMark -----------------------------------------------------------------
|
||||||
|
28
recording.h
28
recording.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.h 1.40 2005/09/03 13:04:41 kls Exp $
|
* $Id: recording.h 1.41 2005/09/25 10:07:40 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __RECORDING_H
|
#ifndef __RECORDING_H
|
||||||
@ -71,7 +71,7 @@ public:
|
|||||||
int lifetime;
|
int lifetime;
|
||||||
cRecording(cTimer *Timer, const cEvent *Event);
|
cRecording(cTimer *Timer, const cEvent *Event);
|
||||||
cRecording(const char *FileName);
|
cRecording(const char *FileName);
|
||||||
~cRecording();
|
virtual ~cRecording();
|
||||||
virtual int Compare(const cListObject &ListObject) const;
|
virtual int Compare(const cListObject &ListObject) const;
|
||||||
const char *Name(void) const { return name; }
|
const char *Name(void) const { return name; }
|
||||||
const char *FileName(void) const;
|
const char *FileName(void) const;
|
||||||
@ -90,16 +90,32 @@ public:
|
|||||||
// Returns false in case of error
|
// Returns false in case of error
|
||||||
};
|
};
|
||||||
|
|
||||||
class cRecordings : public cList<cRecording> {
|
class cRecordings : public cList<cRecording>, public cThread {
|
||||||
private:
|
private:
|
||||||
bool deleted;
|
bool deleted;
|
||||||
time_t lastUpdate;
|
time_t lastUpdate;
|
||||||
void ScanVideoDir(const char *DirName);
|
int state;
|
||||||
|
void Refresh(bool Foreground = false);
|
||||||
|
void ScanVideoDir(const char *DirName, bool Foreground = false);
|
||||||
|
protected:
|
||||||
|
void Action(void);
|
||||||
public:
|
public:
|
||||||
cRecordings(bool Deleted = false);
|
cRecordings(bool Deleted = false);
|
||||||
bool Load(void);
|
virtual ~cRecordings();
|
||||||
|
bool Load(void) { return Update(true); }
|
||||||
|
///< Loads the current list of recordings and returns true if there
|
||||||
|
///< is anything in it (for compatibility with older plugins - use
|
||||||
|
///< Update(true) instead).
|
||||||
|
bool Update(bool Wait = false);
|
||||||
|
///< Triggers an update of the list of recordings, which will run
|
||||||
|
///< as a separate thread if Wait is false. If Wait is true, the
|
||||||
|
///< function returns only after the update has completed.
|
||||||
|
///< Returns true if Wait is true and there is anyting in the list
|
||||||
|
///< of recordings, false otherwise.
|
||||||
void TriggerUpdate(void) { lastUpdate = 0; }
|
void TriggerUpdate(void) { lastUpdate = 0; }
|
||||||
bool NeedsUpdate(void);
|
bool NeedsUpdate(void);
|
||||||
|
void ChangeState(void) { state++; }
|
||||||
|
bool StateChanged(int &State);
|
||||||
cRecording *GetByName(const char *FileName);
|
cRecording *GetByName(const char *FileName);
|
||||||
void AddByName(const char *FileName);
|
void AddByName(const char *FileName);
|
||||||
void DelByName(const char *FileName);
|
void DelByName(const char *FileName);
|
||||||
@ -112,7 +128,7 @@ public:
|
|||||||
int position;
|
int position;
|
||||||
char *comment;
|
char *comment;
|
||||||
cMark(int Position = 0, const char *Comment = NULL);
|
cMark(int Position = 0, const char *Comment = NULL);
|
||||||
~cMark();
|
virtual ~cMark();
|
||||||
cString ToText(void);
|
cString ToText(void);
|
||||||
bool Parse(const char *s);
|
bool Parse(const char *s);
|
||||||
bool Save(FILE *f);
|
bool Save(FILE *f);
|
||||||
|
4
svdrp.c
4
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* graphical interface that sits on top of an SVDRP connection.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.c 1.81 2005/09/18 10:50:08 kls Exp $
|
* $Id: svdrp.c 1.82 2005/09/25 10:36:59 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "svdrp.h"
|
#include "svdrp.h"
|
||||||
@ -890,7 +890,7 @@ void cSVDRP::CmdLSTE(const char *Option)
|
|||||||
|
|
||||||
void cSVDRP::CmdLSTR(const char *Option)
|
void cSVDRP::CmdLSTR(const char *Option)
|
||||||
{
|
{
|
||||||
bool recordings = Recordings.Load();
|
bool recordings = Recordings.Update(true);
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
if (isnumber(Option)) {
|
if (isnumber(Option)) {
|
||||||
cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
|
cRecording *recording = Recordings.Get(strtol(Option, NULL, 10) - 1);
|
||||||
|
12
vdr.c
12
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/vdr
|
* The project's page is at http://www.cadsoft.de/vdr
|
||||||
*
|
*
|
||||||
* $Id: vdr.c 1.216 2005/09/04 08:57:15 kls Exp $
|
* $Id: vdr.c 1.217 2005/09/24 13:27:26 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -437,6 +437,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
||||||
|
|
||||||
|
// Recordings:
|
||||||
|
|
||||||
|
Recordings.Update();
|
||||||
|
|
||||||
// EPG data:
|
// EPG data:
|
||||||
|
|
||||||
if (EpgDataFileName) {
|
if (EpgDataFileName) {
|
||||||
@ -539,10 +543,6 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
cDevice::PrimaryDevice()->SetVolume(Setup.CurrentVolume, true);
|
cDevice::PrimaryDevice()->SetVolume(Setup.CurrentVolume, true);
|
||||||
|
|
||||||
// Recordings:
|
|
||||||
|
|
||||||
Recordings.Load();
|
|
||||||
|
|
||||||
// Signal handlers:
|
// Signal handlers:
|
||||||
|
|
||||||
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
||||||
@ -674,7 +674,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Menu && Recordings.NeedsUpdate())
|
if (!Menu && Recordings.NeedsUpdate())
|
||||||
Recordings.Load();
|
Recordings.Update();
|
||||||
// CAM control:
|
// CAM control:
|
||||||
if (!Menu && !cOsd::IsOpen()) {
|
if (!Menu && !cOsd::IsOpen()) {
|
||||||
Menu = CamControl();
|
Menu = CamControl();
|
||||||
|
Loading…
Reference in New Issue
Block a user