--- vdr-1.3.12-orig/cutter.h	2002-06-22 13:03:15.000000000 +0300
+++ vdr-1.3.12/cutter.h	2004-10-09 14:41:33.000000000 +0300
@@ -9,17 +9,19 @@
 
 #ifndef __CUTTER_H
 #define __CUTTER_H
 
 class cCuttingThread;
+class cMutex;
 
 class cCutter {
 private:
   static char *editedVersionName;
   static cCuttingThread *cuttingThread;
   static bool error;
   static bool ended;
+  static cMutex *cutterLock;
 public:
   static bool Start(const char *FileName);
   static void Stop(void);
   static bool Active(void);
   static bool Error(void);
--- vdr-1.3.12-orig/cutter.c	2004-06-13 19:04:08.000000000 +0300
+++ vdr-1.3.12/cutter.c	2004-10-27 11:48:11.846769576 +0300
@@ -176,17 +176,59 @@
      esyslog("no editing marks found!");
 }
 
 // --- cCutter ---------------------------------------------------------------
 
+#define WAIT_UNTIL_NEXT_CUT   (10*1000)
+
+#define CUTTER_QUEUE
+//#define CUTTER_AUTO_DELETE
+
+class cStringListObject : public cListObject {
+  public:
+    cStringListObject(const char *s) { str = strdup(s); }
+    ~cStringListObject() { free(str); }
+
+    const char *Value() { return str; }
+    operator const char * () { return str; }
+
+  private:  
+    char *str;
+};
+
 char *cCutter::editedVersionName = NULL;
 cCuttingThread *cCutter::cuttingThread = NULL;
 bool cCutter::error = false;
 bool cCutter::ended = false;
+cMutex *cCutter::cutterLock = new cMutex();
+
+static int /*cCutter::*/lastCuttingEndTime = 0;
+static cList<cStringListObject> /**cCutter::*/cutterQueue /*= new cList<cStringListObject>*/;
 
 bool cCutter::Start(const char *FileName)
 {
+  cMutexLock(cutterLock);
+
+#ifdef CUTTER_QUEUE
+  if(FileName) {
+    /* Add file to queue.
+     * If cutter is still active, next cutting will be started 
+     * when vdr.c:main calls cCutter::Active and previous cutting has 
+     * been stopped > 10 s before 
+     */
+    cutterQueue.Add(new cStringListObject(FileName));
+  }
+
+  if (cuttingThread) 
+    return true;
+
+  /* cut next file from queue */
+  if(!(cutterQueue.First()))
+    return false;
+  FileName = cutterQueue.First()->Value();
+#endif
+
   if (!cuttingThread) {
      error = false;
      ended = false;
      cRecording Recording(FileName);
      const char *evn = Recording.PrefixFileName('%');
@@ -205,18 +247,22 @@
         // XXX
         editedVersionName = strdup(evn);
         Recording.WriteSummary();
         Recordings.AddByName(editedVersionName);
         cuttingThread = new cCuttingThread(FileName, editedVersionName);
+
         return true;
         }
      }
+
   return false;
 }
 
 void cCutter::Stop(void)
 {
+  cMutexLock(cutterLock);
+
   bool Interrupted = cuttingThread && cuttingThread->Active();
   const char *Error = cuttingThread ? cuttingThread->Error() : NULL;
   delete cuttingThread;
   cuttingThread = NULL;
   if ((Interrupted || Error) && editedVersionName) {
@@ -224,37 +270,73 @@
         isyslog("editing process has been interrupted");
      if (Error)
         esyslog("ERROR: '%s' during editing process", Error);
      RemoveVideoFile(editedVersionName); //XXX what if this file is currently being replayed?
      Recordings.DelByName(editedVersionName);
+#ifdef CUTTER_QUEUE
+     cutterQueue.Del(cutterQueue.First());
+#endif
      }
+#ifdef CUTTER_QUEUE
+  lastCuttingEndTime = time_ms();
+#endif
 }
 
 bool cCutter::Active(void)
 {
+  cMutexLock(cutterLock);
+
   if (cuttingThread) {
      if (cuttingThread->Active())
         return true;
      error = cuttingThread->Error();
      Stop();
      if (!error)
         cRecordingUserCommand::InvokeCommand(RUC_EDITEDRECORDING, editedVersionName);
      free(editedVersionName);
      editedVersionName = NULL;
      ended = true;
+#ifdef CUTTER_AUTO_DELETE
+     /* Remove original (if cutting was successful) */
+     if(!error) {
+       cRecording *recording = Recordings.GetByName(*cutterQueue.First());
+       if (!recording) {
+	 esyslog("ERROR: Can't found '%s' after editing process", cutterQueue.First()->Value());
+       } else {
+	 if (recording->Delete()) 
+	   Recordings.Del(recording);
+	 else
+	   esyslog("ERROR: Can't delete '%s' after editing process", cutterQueue.First()->Value());
+       }
+     }
+    lastCuttingEndTime = time_ms();
+#endif
+#ifdef CUTTER_QUEUE
+     cutterQueue.Del(cutterQueue.First());
+#endif
      }
+#ifdef CUTTER_QUEUE
+  if(!cuttingThread && cutterQueue.First()) {
+    /* start next cutting from queue*/
+    if(time_ms() > lastCuttingEndTime + WAIT_UNTIL_NEXT_CUT)
+      Start(NULL);
+  }
+#endif
+
   return false;
 }
 
 bool cCutter::Error(void)
 {
+  cMutexLock(cutterLock);
   bool result = error;
   error = false;
   return result;
 }
 
 bool cCutter::Ended(void)
 {
+  cMutexLock(cutterLock);
   bool result = ended;
   ended = false;
   return result;
 }
--- vdr-1.3.12-orig/menu.c	2004-06-13 23:26:51.000000000 +0300
+++ vdr-1.3.12/menu.c	2004-10-01 21:00:42.000000000 +0300
@@ -3277,20 +3557,25 @@

 void cReplayControl::EditCut(void)
 {
   if (fileName) {
      Hide();
+#if 0
      if (!cCutter::Active()) {
+#else
+     if (!cCutter::Active() || Interface->Confirm(tr("Cutter already running - Add to cutting queue?"))) {
+#endif
         if (!marks.Count())
            Skins.Message(mtError, tr("No editing marks defined!"));
         else if (!cCutter::Start(fileName))
            Skins.Message(mtError, tr("Can't start editing process!"));
         else
            Skins.Message(mtInfo, tr("Editing process started"));
         }
-     else
+     else
         Skins.Message(mtError, tr("Editing process already active!"));
+
      ShowMode();
      }
 }

 void cReplayControl::EditTest(void)
