--- cutter.c.orig	2008-06-21 20:49:47.000000000 +0300
+++ cutter.c	2008-06-23 18:00:10.000000000 +0300
@@ -183,18 +183,73 @@
 
 // --- cCutter ---------------------------------------------------------------
 
+#define WAIT_BEFORE_NEXT_CUT   (10*1000)  // 10 seconds
+
+#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 uint64_t /*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('%');
+
+     if(!(Recordings.GetByName(FileName))) {
+       // Should _not_ remove any cutted recordings 
+       // (original recording already deleted ?)
+       // so, just pop item from queue and return.
+       esyslog("can't cut non-existing recording %s", FileName);
+#ifdef CUTTER_QUEUE
+       cutterQueue.Del(cutterQueue.First());       
+       return true; // might be already queued recording
+#else
+       return false;
+#endif
+     }
      if (evn && RemoveVideoFile(evn) && MakeDirs(evn, true)) {
         // XXX this can be removed once RenameVideoFile() follows symlinks (see videodir.c)
         // remove a possible deleted recording with the same name to avoid symlink mixups:
@@ -220,6 +275,8 @@
 
 void cCutter::Stop(void)
 {
+  cMutexLock(cutterLock);
+
   bool Interrupted = cuttingThread && cuttingThread->Active();
   const char *Error = cuttingThread ? cuttingThread->Error() : NULL;
   delete cuttingThread;
@@ -231,11 +288,19 @@
         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 = cTimeMs::Now();
+#endif
 }
 
 bool cCutter::Active(void)
 {
+  cMutexLock(cutterLock);
+
   if (cuttingThread) {
      if (cuttingThread->Active())
         return true;
@@ -246,12 +311,42 @@
      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);
+           //cReplayControl::ClearLastReplayed(ri->FileName());
+           Recordings.DelByName(recording->FileName());
+	 } else {
+	   esyslog("ERROR: Can't delete '%s' after editing process", cutterQueue.First()->Value());
+	 }
+       }
+     }
+    lastCuttingEndTime = cTimeMs::Now();
+#endif
+#ifdef CUTTER_QUEUE
+     cutterQueue.Del(cutterQueue.First());
+#endif
      }
+#ifdef CUTTER_QUEUE
+  if(!cuttingThread && cutterQueue.First()) {
+    /* start next cutting from queue*/
+    if(cTimeMs::Now() > lastCuttingEndTime + WAIT_BEFORE_NEXT_CUT)
+      Start(NULL);
+  }
+#endif
+
   return false;
 }
 
 bool cCutter::Error(void)
 {
+  cMutexLock(cutterLock);
   bool result = error;
   error = false;
   return result;
@@ -259,6 +354,7 @@
 
 bool cCutter::Ended(void)
 {
+  cMutexLock(cutterLock);
   bool result = ended;
   ended = false;
   return result;
--- ../vdr-1.6.0-1.orig/cutter.h	2008-04-16 14:07:33.000000000 +0300
+++ cutter.h	2008-06-23 18:00:10.000000000 +0300
@@ -11,6 +11,7 @@
 #define __CUTTER_H
 
 class cCuttingThread;
+class cMutex;
 
 class cCutter {
 private:
@@ -18,6 +19,7 @@
   static cCuttingThread *cuttingThread;
   static bool error;
   static bool ended;
+  static cMutex *cutterLock;
 public:
   static bool Start(const char *FileName);
   static void Stop(void);
--- menu.c.orig	2008-06-21 20:50:35.000000000 +0300
+++ menu.c	2008-06-23 18:00:10.000000000 +0300
@@ -4570,7 +4570,11 @@
 {
   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))
