mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	The list of recordings is now read in a separate thread
This commit is contained in:
		@@ -14,6 +14,8 @@ Carsten Koch <Carsten.Koch@icem.de>
 | 
			
		||||
 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 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>
 | 
			
		||||
 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
 | 
			
		||||
  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 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].
 | 
			
		||||
- The SVDRP command DELR no longer triggers a complete reload of the global Recordings
 | 
			
		||||
  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
 | 
			
		||||
 * 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"
 | 
			
		||||
@@ -1506,35 +1506,12 @@ cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus)
 | 
			
		||||
{
 | 
			
		||||
  base = Base ? strdup(Base) : NULL;
 | 
			
		||||
  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
 | 
			
		||||
  const char *LastReplayed = cReplayControl::LastReplayed();
 | 
			
		||||
  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);
 | 
			
		||||
  Set();
 | 
			
		||||
  if (Current() < 0)
 | 
			
		||||
     SetCurrent(First());
 | 
			
		||||
  else if (OpenSubMenus && Open(true))
 | 
			
		||||
  else if (OpenSubMenus && cReplayControl::LastReplayed() && Open(true))
 | 
			
		||||
     return;
 | 
			
		||||
  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 *recording = Recordings.GetByName(Item->FileName());
 | 
			
		||||
@@ -1716,6 +1732,9 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
 | 
			
		||||
       case kYellow: return Delete();
 | 
			
		||||
       case kBlue:   return Info();
 | 
			
		||||
       case k1...k9: return Commands(Key);
 | 
			
		||||
       case kNone:   if (Recordings.StateChanged(recordingsState))
 | 
			
		||||
                        Set(true);
 | 
			
		||||
                     break;
 | 
			
		||||
       default: break;
 | 
			
		||||
       }
 | 
			
		||||
     }
 | 
			
		||||
@@ -2597,6 +2616,7 @@ static void SetTrackDescriptions(bool Live)
 | 
			
		||||
        }
 | 
			
		||||
     }
 | 
			
		||||
  else if (cReplayControl::LastReplayed()) {
 | 
			
		||||
     cThreadLock RecordingsLock(&Recordings);
 | 
			
		||||
     cRecording *Recording = Recordings.GetByName(cReplayControl::LastReplayed());
 | 
			
		||||
     if (Recording)
 | 
			
		||||
        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
 | 
			
		||||
 * 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
 | 
			
		||||
@@ -147,8 +147,10 @@ class cMenuRecordings : public cOsdMenu {
 | 
			
		||||
private:
 | 
			
		||||
  char *base;
 | 
			
		||||
  int level;
 | 
			
		||||
  int recordingsState;
 | 
			
		||||
  static int helpKeys;
 | 
			
		||||
  void SetHelpKeys(void);
 | 
			
		||||
  void Set(bool Refresh = false);
 | 
			
		||||
  cRecording *GetRecording(cMenuRecordingItem *Item);
 | 
			
		||||
  bool Open(bool OpenSubMenus = false);
 | 
			
		||||
  eOSState Play(void);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										98
									
								
								recording.c
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								recording.c
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * 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"
 | 
			
		||||
@@ -60,17 +60,23 @@
 | 
			
		||||
 | 
			
		||||
bool VfatFileSystem = false;
 | 
			
		||||
 | 
			
		||||
static cRecordings DeletedRecordings(true);
 | 
			
		||||
 | 
			
		||||
void RemoveDeletedRecordings(void)
 | 
			
		||||
{
 | 
			
		||||
  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:
 | 
			
		||||
     cLockFile LockFile(VideoDirectory);
 | 
			
		||||
     if (!LockFile.Lock())
 | 
			
		||||
        return;
 | 
			
		||||
     // Remove the oldest file that has been "deleted":
 | 
			
		||||
     cRecordings DeletedRecordings(true);
 | 
			
		||||
     if (DeletedRecordings.Load()) {
 | 
			
		||||
     cThreadLock DeletedRecordingsLock(&DeletedRecordings);
 | 
			
		||||
     if (DeletedRecordings.Count()) {
 | 
			
		||||
        cRecording *r = DeletedRecordings.First();
 | 
			
		||||
        cRecording *r0 = r;
 | 
			
		||||
        while (r) {
 | 
			
		||||
@@ -80,11 +86,14 @@ void RemoveDeletedRecordings(void)
 | 
			
		||||
              }
 | 
			
		||||
        if (r0 && time(NULL) - r0->start > DELETEDLIFETIME * 3600) {
 | 
			
		||||
           r0->Remove();
 | 
			
		||||
           DeletedRecordings.Del(r0);
 | 
			
		||||
           RemoveEmptyVideoDirectories();
 | 
			
		||||
           LastRemoveCheck += REMOVELATENCY;
 | 
			
		||||
           return;
 | 
			
		||||
           }
 | 
			
		||||
        }
 | 
			
		||||
     else
 | 
			
		||||
        DeletedRecordings.Update();
 | 
			
		||||
     LastRemoveCheck = time(NULL);
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
@@ -104,8 +113,8 @@ void AssertFreeDiskSpace(int Priority)
 | 
			
		||||
           return;
 | 
			
		||||
        // Remove the oldest file that has been "deleted":
 | 
			
		||||
        isyslog("low disk space while recording, trying to remove a deleted recording...");
 | 
			
		||||
        cRecordings DeletedRecordings(true);
 | 
			
		||||
        if (DeletedRecordings.Load()) {
 | 
			
		||||
        cThreadLock DeletedRecordingsLock(&DeletedRecordings);
 | 
			
		||||
        if (DeletedRecordings.Count()) {
 | 
			
		||||
           cRecording *r = DeletedRecordings.First();
 | 
			
		||||
           cRecording *r0 = r;
 | 
			
		||||
           while (r) {
 | 
			
		||||
@@ -114,13 +123,20 @@ void AssertFreeDiskSpace(int Priority)
 | 
			
		||||
                 r = DeletedRecordings.Next(r);
 | 
			
		||||
                 }
 | 
			
		||||
           if (r0 && r0->Remove()) {
 | 
			
		||||
              DeletedRecordings.Del(r0);
 | 
			
		||||
              LastFreeDiskCheck += REMOVELATENCY / Factor;
 | 
			
		||||
              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:
 | 
			
		||||
        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 *r0 = NULL;
 | 
			
		||||
           while (r) {
 | 
			
		||||
@@ -454,6 +470,7 @@ cRecording::cRecording(const char *FileName)
 | 
			
		||||
        name[p - FileName] = 0;
 | 
			
		||||
        name = ExchangeChars(name, false);
 | 
			
		||||
        }
 | 
			
		||||
     GetResume();
 | 
			
		||||
     // read an optional info file:
 | 
			
		||||
     char *InfoFileName = NULL;
 | 
			
		||||
     asprintf(&InfoFileName, "%s%s", fileName, INFOFILESUFFIX);
 | 
			
		||||
@@ -720,16 +737,38 @@ bool cRecording::Remove(void)
 | 
			
		||||
cRecordings Recordings;
 | 
			
		||||
 | 
			
		||||
cRecordings::cRecordings(bool Deleted)
 | 
			
		||||
:cThread("video directory scanner")
 | 
			
		||||
{
 | 
			
		||||
  deleted = Deleted;
 | 
			
		||||
  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);
 | 
			
		||||
  struct dirent *e;
 | 
			
		||||
  while ((e = d.Next()) != NULL) {
 | 
			
		||||
  while ((Foreground || Running()) && (e = d.Next()) != NULL) {
 | 
			
		||||
        if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
 | 
			
		||||
           char *buffer;
 | 
			
		||||
           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 (endswith(buffer, deleted ? DELEXT : RECEXT)) {
 | 
			
		||||
                    cRecording *r = new cRecording(buffer);
 | 
			
		||||
                    if (r->Name())
 | 
			
		||||
                    if (r->Name()) {
 | 
			
		||||
                       Lock();
 | 
			
		||||
                       Add(r);
 | 
			
		||||
                       ChangeState();
 | 
			
		||||
                       Unlock();
 | 
			
		||||
                       }
 | 
			
		||||
                    else
 | 
			
		||||
                       delete r;
 | 
			
		||||
                    }
 | 
			
		||||
                 else
 | 
			
		||||
                    ScanVideoDir(buffer);
 | 
			
		||||
                    ScanVideoDir(buffer, Foreground);
 | 
			
		||||
                 }
 | 
			
		||||
              }
 | 
			
		||||
           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
 | 
			
		||||
  Clear();
 | 
			
		||||
  ScanVideoDir(VideoDirectory);
 | 
			
		||||
  Sort();
 | 
			
		||||
  return Count() > 0;
 | 
			
		||||
  return lastUpdate < LastModifiedTime(AddDirectory(VideoDirectory, ".update"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cRecordings::Update(bool Wait)
 | 
			
		||||
{
 | 
			
		||||
  if (Wait) {
 | 
			
		||||
     Refresh(true);
 | 
			
		||||
     return Count() > 0;
 | 
			
		||||
     }
 | 
			
		||||
  else
 | 
			
		||||
     Start();
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cRecording *cRecordings::GetByName(const char *FileName)
 | 
			
		||||
@@ -788,18 +841,23 @@ cRecording *cRecordings::GetByName(const char *FileName)
 | 
			
		||||
 | 
			
		||||
void cRecordings::AddByName(const char *FileName)
 | 
			
		||||
{
 | 
			
		||||
  LOCK_THREAD;
 | 
			
		||||
  cRecording *recording = GetByName(FileName);
 | 
			
		||||
  if (!recording) {
 | 
			
		||||
     recording = new cRecording(FileName);
 | 
			
		||||
     Add(recording);
 | 
			
		||||
     ChangeState();
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cRecordings::DelByName(const char *FileName)
 | 
			
		||||
{
 | 
			
		||||
  LOCK_THREAD;
 | 
			
		||||
  cRecording *recording = GetByName(FileName);
 | 
			
		||||
  if (recording)
 | 
			
		||||
  if (recording) {
 | 
			
		||||
     Del(recording);
 | 
			
		||||
     ChangeState();
 | 
			
		||||
     }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// --- cMark -----------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								recording.h
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								recording.h
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * See the main source file 'vdr.c' for copyright information and
 | 
			
		||||
 * 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
 | 
			
		||||
@@ -71,7 +71,7 @@ public:
 | 
			
		||||
  int lifetime;
 | 
			
		||||
  cRecording(cTimer *Timer, const cEvent *Event);
 | 
			
		||||
  cRecording(const char *FileName);
 | 
			
		||||
  ~cRecording();
 | 
			
		||||
  virtual ~cRecording();
 | 
			
		||||
  virtual int Compare(const cListObject &ListObject) const;
 | 
			
		||||
  const char *Name(void) const { return name; }
 | 
			
		||||
  const char *FileName(void) const;
 | 
			
		||||
@@ -90,16 +90,32 @@ public:
 | 
			
		||||
       // Returns false in case of error
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
class cRecordings : public cList<cRecording> {
 | 
			
		||||
class cRecordings : public cList<cRecording>, public cThread {
 | 
			
		||||
private:
 | 
			
		||||
  bool deleted;
 | 
			
		||||
  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:
 | 
			
		||||
  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; }
 | 
			
		||||
  bool NeedsUpdate(void);
 | 
			
		||||
  void ChangeState(void) { state++; }
 | 
			
		||||
  bool StateChanged(int &State);
 | 
			
		||||
  cRecording *GetByName(const char *FileName);
 | 
			
		||||
  void AddByName(const char *FileName);
 | 
			
		||||
  void DelByName(const char *FileName);
 | 
			
		||||
@@ -112,7 +128,7 @@ public:
 | 
			
		||||
  int position;
 | 
			
		||||
  char *comment;
 | 
			
		||||
  cMark(int Position = 0, const char *Comment = NULL);
 | 
			
		||||
  ~cMark();
 | 
			
		||||
  virtual ~cMark();
 | 
			
		||||
  cString ToText(void);
 | 
			
		||||
  bool Parse(const char *s);
 | 
			
		||||
  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
 | 
			
		||||
 * 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"
 | 
			
		||||
@@ -890,7 +890,7 @@ void cSVDRP::CmdLSTE(const char *Option)
 | 
			
		||||
 | 
			
		||||
void cSVDRP::CmdLSTR(const char *Option)
 | 
			
		||||
{
 | 
			
		||||
  bool recordings = Recordings.Load();
 | 
			
		||||
  bool recordings = Recordings.Update(true);
 | 
			
		||||
  if (*Option) {
 | 
			
		||||
     if (isnumber(Option)) {
 | 
			
		||||
        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
 | 
			
		||||
 *
 | 
			
		||||
 * $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>
 | 
			
		||||
@@ -437,6 +437,10 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
  cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
 | 
			
		||||
 | 
			
		||||
  // Recordings:
 | 
			
		||||
 | 
			
		||||
  Recordings.Update();
 | 
			
		||||
 | 
			
		||||
  // EPG data:
 | 
			
		||||
 | 
			
		||||
  if (EpgDataFileName) {
 | 
			
		||||
@@ -539,10 +543,6 @@ int main(int argc, char *argv[])
 | 
			
		||||
  else
 | 
			
		||||
     cDevice::PrimaryDevice()->SetVolume(Setup.CurrentVolume, true);
 | 
			
		||||
 | 
			
		||||
  // Recordings:
 | 
			
		||||
 | 
			
		||||
  Recordings.Load();
 | 
			
		||||
 | 
			
		||||
  // Signal handlers:
 | 
			
		||||
 | 
			
		||||
  if (signal(SIGHUP,  SignalHandler) == SIG_IGN) signal(SIGHUP,  SIG_IGN);
 | 
			
		||||
@@ -674,7 +674,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
               }
 | 
			
		||||
           }
 | 
			
		||||
        if (!Menu && Recordings.NeedsUpdate())
 | 
			
		||||
           Recordings.Load();
 | 
			
		||||
           Recordings.Update();
 | 
			
		||||
        // CAM control:
 | 
			
		||||
        if (!Menu && !cOsd::IsOpen()) {
 | 
			
		||||
           Menu = CamControl();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user