diff -a -U 2 -r a/device.c b/device.c
--- a/device.c	2025-07-24 13:44:14.000000000 +0200
+++ b/device.c	2025-08-03 22:16:48.112461446 +0200
@@ -1937,4 +1937,15 @@
 }
 
+cRecorder* cDevice::GetPreRecording(const cChannel *Channel)
+{
+  cMutexLock MutexLock(&mutexReceiver);
+  for (int i = 0; i < MAXRECEIVERS; i++) {
+      if (receiver[i])
+    	  if (receiver[i]->IsPreRecording(Channel))
+    		  return (cRecorder*)receiver[i];
+      }
+  return NULL;
+}
+
 // --- cTSBuffer -------------------------------------------------------------
 
diff -a -U 2 -r a/device.h b/device.h
--- a/device.h	2025-07-24 13:44:14.000000000 +0200
+++ b/device.h	2025-08-03 22:16:48.112461446 +0200
@@ -86,4 +86,5 @@
 class cPlayer;
 class cReceiver;
+class cRecorder;
 class cLiveSubtitle;
 
@@ -870,4 +871,6 @@
   bool AttachReceiver(cReceiver *Receiver);
        ///< Attaches the given receiver to this device.
+  cRecorder* GetPreRecording(const cChannel *Channel);
+       ///< Get precocious recording for the channel if there is one.
   void Detach(cReceiver *Receiver, bool ReleaseCam = true);
        ///< Detaches the given receiver from this device.
diff -a -U 2 -r a/dvbplayer.c b/dvbplayer.c
--- a/dvbplayer.c	2025-07-24 13:44:14.000000000 +0200
+++ b/dvbplayer.c	2025-08-03 22:37:18.837632671 +0200
@@ -254,5 +254,5 @@
   double framesPerSecond;
   bool isPesRecording;
-  bool pauseLive;
+  ReplayState replayState;
   bool eof;
   bool firstPacket;
@@ -261,4 +261,5 @@
   int trickSpeed;
   int readIndex;
+  int startIndex;
   bool readIndependent;
   cFrame *readFrame;
@@ -276,4 +277,6 @@
 public:
   cDvbPlayer(const char *FileName, bool PauseLive);
+  cDvbPlayer(const char *FileName, ReplayState newReplayState);
+  void Construct(const char *FileName, ReplayState newReplayState);
   virtual ~cDvbPlayer() override;
   void SetMarks(const cMarks *Marks);
@@ -303,4 +306,15 @@
 :cThread("dvbplayer")
 {
+  Construct(FileName, PauseLive? restPauseLive : restNormal);
+}
+
+cDvbPlayer::cDvbPlayer(const char *FileName, ReplayState newReplayState)
+:cThread("dvbplayer")
+{
+  Construct(FileName, newReplayState);
+}
+
+void cDvbPlayer::Construct(const char *FileName, ReplayState newReplayState)
+{  
   nonBlockingFileReader = NULL;
   ringBuffer = NULL;
@@ -310,5 +324,6 @@
   framesPerSecond = Recording.FramesPerSecond();
   isPesRecording = Recording.IsPesRecording();
-  pauseLive = PauseLive;
+  replayState = newReplayState;
+  bool reuse = (replayState == restReusePause || replayState == restReuseRewind);
   eof = false;
   firstPacket = true;
@@ -329,5 +344,5 @@
   ringBuffer = new cRingBufferFrame(PLAYERBUFSIZE);
   // Create the index file:
-  index = new cIndexFile(FileName, false, isPesRecording, pauseLive);
+  index = new cIndexFile(FileName, false, isPesRecording, replayState == restPauseLive);
   if (!index)
      esyslog("ERROR: can't allocate index");
@@ -336,6 +351,12 @@
      index = NULL;
      }
-  else if (PauseLive)
+  else if (reuse)
      framesPerSecond = cRecording(FileName).FramesPerSecond(); // the fps rate might have changed from the default
+  startIndex = 0;
+  if (replayState == restReuseRewind || replayState == restReusePause) {
+     int Current, Total;
+     GetIndex(Current, Total, false);
+     startIndex = max(Total - 1, 0);
+     }     
 }
 
@@ -487,6 +508,19 @@
   bool AtLastMark = false;
 
-  if (pauseLive)
-     Goto(0, true);
+  if (replayState == restPauseLive) {
+    Goto(0, true);
+    }
+  else if (replayState == restReuseRewind || replayState == restReusePause) {
+    readIndex = startIndex;
+    Goto(readIndex, true);
+    playMode = pmPlay;
+    if (replayState == restReuseRewind) {
+    	Backward();
+        }
+    else if (replayState == restReusePause) {
+    	Pause();
+        }
+    }
+  
   while (Running()) {
         if (WaitingForData)
@@ -1003,4 +1037,9 @@
 }
 
+cDvbPlayerControl::cDvbPlayerControl(const char *FileName, ReplayState replayState)
+:cControl(player = new cDvbPlayer(FileName, replayState))
+{
+}
+
 cDvbPlayerControl::~cDvbPlayerControl()
 {
diff -a -U 2 -r a/dvbplayer.h b/dvbplayer.h
--- a/dvbplayer.h	2025-07-24 13:44:14.000000000 +0200
+++ b/dvbplayer.h	2025-08-03 22:35:30.189884625 +0200
@@ -17,4 +17,12 @@
 class cDvbPlayer;
 
+enum ReplayState
+{
+	restNormal,
+	restPauseLive,
+	restReusePause,
+	restReuseRewind
+};
+
 class cDvbPlayerControl : public cControl {
 private:
@@ -26,4 +34,6 @@
        // file of the recording is long enough to allow the player to display
        // the first frame in still picture mode.
+  cDvbPlayerControl(const char *FileName, ReplayState replayState);
+       // Sets up a player for the given file. replayState represents the initial state.
   virtual ~cDvbPlayerControl() override;
   void SetMarks(const cMarks *Marks);
diff -a -U 2 -r a/menu.c b/menu.c
--- a/menu.c	2025-07-24 13:44:14.000000000 +0200
+++ b/menu.c	2025-08-03 22:16:48.116461437 +0200
@@ -5340,4 +5340,14 @@
 cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause)
 {
+  Construct(Device, Timers, Timer, Pause, NULL);
+}
+
+cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause, bool* reused)
+{
+  Construct(Device, Timers, Timer, Pause, reused);
+}
+
+void cRecordControl::Construct(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause, bool* reused)
+{
   const char *LastReplayed = cReplayControl::LastReplayed(); // must do this before locking schedules!
   // Whatever happens here, the timers will be modified in some way...
@@ -5368,4 +5378,5 @@
   timer->SetRecording(true);
   event = timer->Event();
+  if (reused != NULL) *reused = false;
 
   if (event || GetEvent())
@@ -5397,6 +5408,19 @@
      Recording.WriteInfo(); // we write this *before* attaching the recorder to the device, to make sure the info file is present when the recorder needs to update the fps value!
      const cChannel *ch = timer->Channel();
-     recorder = new cRecorder(fileName, ch, timer->Priority());
-     if (device->AttachReceiver(recorder)) {
+
+     if (!Timer) {
+        recorder = device->GetPreRecording(ch);
+        if (recorder != NULL) {
+           recorder->ActivatePreRecording(fileName, timer->Priority());
+           if (reused != NULL) *reused = true;
+           }
+        }
+
+     if (recorder == NULL) {
+        recorder = new cRecorder(fileName, ch, timer->Priority());
+        if (!device->AttachReceiver(recorder)) DELETENULL(recorder);
+        }
+
+     if (recorder != NULL) {
         cStatus::MsgRecording(device, Recording.Name(), Recording.FileName(), true);
         if (!Timer && !LastReplayed) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
@@ -5408,6 +5432,4 @@
         return;
         }
-     else
-        DELETENULL(recorder);
      }
   else
@@ -5489,5 +5511,5 @@
 int cRecordControls::state = 0;
 
-bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
+bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause, bool* reused)
 {
   static time_t LastNoDiskSpaceMessage = 0;
@@ -5527,5 +5549,5 @@
            for (int i = 0; i < MAXRECORDCONTROLS; i++) {
                if (!RecordControls[i]) {
-                  RecordControls[i] = new cRecordControl(device, Timers, Timer, Pause);
+                  RecordControls[i] = new cRecordControl(device, Timers, Timer, Pause, reused);
                   return RecordControls[i]->Process(time(NULL));
                   }
@@ -5551,4 +5573,9 @@
 }
 
+bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
+{
+  return Start(Timers, Timer, Pause, NULL);
+}
+
 void cRecordControls::Stop(const char *InstantId)
 {
@@ -5586,8 +5613,15 @@
 bool cRecordControls::PauseLiveVideo(void)
 {
+  return PauseLiveVideo(false);
+}
+
+bool cRecordControls::PauseLiveVideo(bool rewind)
+{
   Skins.Message(mtStatus, tr("Pausing live video..."));
+  bool reused = false;  
   cReplayControl::SetRecording(NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
-  if (Start(true)) {
-     cReplayControl *rc = new cReplayControl(true);
+  LOCK_TIMERS_WRITE;
+  if (Start(Timers, NULL, true, &reused)) {
+     cReplayControl *rc = new cReplayControl(rewind? restReuseRewind : reused? restReusePause : restPauseLive);
      cControl::Launch(rc);
      cControl::Attach();
@@ -5733,5 +5767,16 @@
 :cDvbPlayerControl(fileName, PauseLive)
 {
-  cDevice::PrimaryDevice()->SetKeepTracks(PauseLive);
+  Construct(PauseLive? restPauseLive : restNormal);
+}
+
+cReplayControl::cReplayControl(ReplayState replayState)
+:cDvbPlayerControl(fileName, replayState)
+{
+  Construct(replayState);
+}
+
+void cReplayControl::Construct(ReplayState replayState)
+{
+  cDevice::PrimaryDevice()->SetKeepTracks(replayState == restPauseLive);
   currentReplayControl = this;
   displayReplay = NULL;
diff -a -U 2 -r a/menu.h b/menu.h
--- a/menu.h	2025-07-24 13:44:14.000000000 +0200
+++ b/menu.h	2025-08-03 22:27:49.198950714 +0200
@@ -246,4 +246,6 @@
 public:
   cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer = NULL, bool Pause = false);
+  cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause, bool* reused);
+  void Construct(cDevice *Device, cTimers *Timers, cTimer *Timer, bool Pause, bool* reused);
   virtual ~cRecordControl();
   bool Process(time_t t);
@@ -261,8 +263,10 @@
 public:
   static bool Start(cTimers *Timers, cTimer *Timer, bool Pause = false);
+  static bool Start(cTimers *Timers, cTimer *Timer, bool Pause, bool* reused);
   static bool Start(bool Pause = false);
   static void Stop(const char *InstantId);
   static void Stop(cTimer *Timer);
   static bool PauseLiveVideo(void);
+  static bool PauseLiveVideo(bool rewind);
   static const char *GetInstantId(const char *LastInstantId);
   static cRecordControl *GetRecordControl(const char *FileName);
@@ -323,4 +327,6 @@
 public:
   cReplayControl(bool PauseLive = false);
+  cReplayControl(ReplayState replayState);
+  void Construct(ReplayState replayState);
   virtual ~cReplayControl() override;
   static void DelTimeshiftTimer(void);
diff -a -U 2 -r a/receiver.h b/receiver.h
--- a/receiver.h	2025-07-24 13:44:14.000000000 +0200
+++ b/receiver.h	2025-08-03 22:16:48.120461429 +0200
@@ -86,4 +86,8 @@
                ///< should repeatedly check whether it is still attached, and if
                ///< it isn't, delete it (or take any other appropriate measures).
+  virtual bool IsPreRecording(const cChannel *Channel) { return false; }
+               ///< prerecords given channel; may be turned into a disc recording.
+  virtual bool ActivatePreRecording(const char* fileName, int Priority) { return false; }
+  	  	  	   ///< turn prerecording into a disc recording
   };
 
diff -a -U 2 -r a/recorder.c b/recorder.c
--- a/recorder.c	2025-07-24 13:44:14.000000000 +0200
+++ b/recorder.c	2025-08-03 22:16:48.120461429 +0200
@@ -25,7 +25,17 @@
 :cReceiver(Channel, Priority)
 ,cThread("recording")
+,ringBuffer(NULL), frameDetector(NULL), fileName(NULL), recordingInfo(NULL), index(NULL), recordFile(NULL), recordingName(NULL)
+{
+  if (FileName != NULL) {
+     InitializeFile(FileName, Channel);
+     }
+}
+
+void cRecorder::InitializeFile(const char *FileName, const cChannel *Channel)
 {
   recordingName = strdup(FileName);
-  recordingInfo = new cRecordingInfo(recordingName);
+  if (recordingInfo == NULL) {
+     recordingInfo = new cRecordingInfo(recordingName);
+     }
   recordingInfo->Read();
   oldErrors = max(0, recordingInfo->Errors()); // in case this is a re-started recording
@@ -52,5 +62,7 @@
      Type = 0x06;
      }
-  frameDetector = new cFrameDetector(Pid, Type);
+  if (frameDetector == NULL) {
+     frameDetector = new cFrameDetector(Pid, Type);
+     }
   index = NULL;
   fileSize = 0;
diff -a -U 2 -r a/recorder.h b/recorder.h
--- a/recorder.h	2025-07-24 13:44:14.000000000 +0200
+++ b/recorder.h	2025-08-03 22:31:27.174447284 +0200
@@ -17,6 +17,6 @@
 #include "thread.h"
 
-class cRecorder : public cReceiver, cThread {
-private:
+class cRecorder : public cReceiver, protected cThread {
+protected:
   cRingBufferLinear *ringBuffer;
   cFrameDetector *frameDetector;
@@ -37,5 +37,4 @@
   bool NextFile(void);
   void HandleErrors(bool Force = false);
-protected:
   virtual void Activate(bool On) override;
        ///< If you override Activate() you need to call Detach() (which is a
@@ -45,4 +44,7 @@
   virtual void Receive(const uchar *Data, int Length) override;
   virtual void Action(void) override;
+  void InitializeFile(const char *FileName, const cChannel *Channel);
+       ///< Starts recording to file.
+       ///< Called in constructor if file name has been given.
 public:
   cRecorder(const char *FileName, const cChannel *Channel, int Priority);
diff -a -U 2 -r a/ringbuffer.c b/ringbuffer.c
--- a/ringbuffer.c	2025-07-24 13:44:14.000000000 +0200
+++ b/ringbuffer.c	2025-08-03 22:16:48.120461429 +0200
@@ -369,4 +369,23 @@
 }
 
+uchar *cRingBufferLinear::GetRest(int &Count)
+{
+  int Head = head;
+  if (getThreadTid <= 0)
+     getThreadTid = cThread::ThreadId();
+  int rest = Size() - tail;
+  int diff = Head - tail;
+  int cont = (diff >= 0) ? diff : Size() + diff - margin;
+  if (cont > rest)
+     cont = rest;
+  uchar *p = buffer + tail;
+  if (cont > 0) {
+     Count = gotten = cont;
+     return p;
+     }
+  WaitForGet();
+  return NULL;
+}
+
 void cRingBufferLinear::Del(int Count)
 {
diff -a -U 2 -r a/ringbuffer.h b/ringbuffer.h
--- a/ringbuffer.h	2025-07-24 13:44:14.000000000 +0200
+++ b/ringbuffer.h	2025-08-03 22:16:48.120461429 +0200
@@ -99,4 +99,10 @@
     ///< Returns a pointer to the data, and stores the number of bytes
     ///< actually available in Count. If the returned pointer is NULL, Count has no meaning.
+  uchar *GetRest(int &Count);
+  ///< Gets data from the ring buffer disregarding the margin.
+  ///< Might have to be called several times to get all data.
+  ///< The data will remain in the buffer until a call to Del() deletes it.
+  ///< Returns a pointer to the data, and stores the number of bytes
+  ///< actually available in Count. If the returned pointer is NULL, Count has no meaning.
   void Del(int Count);
     ///< Deletes at most Count bytes from the ring buffer.
diff -a -U 2 -r a/vdr.c b/vdr.c
--- a/vdr.c	2025-07-24 13:44:14.000000000 +0200
+++ b/vdr.c	2025-08-03 22:16:48.120461429 +0200
@@ -1361,4 +1361,15 @@
                break;
           // Pausing live video:
+          case kFastRew:
+               if (cOsd::IsOpen())
+                  break;
+               {
+               // test if there's a live buffer to rewind into...
+               LOCK_CHANNELS_READ;
+               if (cDevice::ActualDevice()->GetPreRecording(Channels->GetByNumber(cDevice::CurrentChannel())) == NULL) {
+                  break;
+                  }
+               }
+               // fall through to pause
           case kPlayPause:
           case kPause:
@@ -1367,5 +1378,5 @@
                   if (Setup.PauseKeyHandling) {
                      if (Setup.PauseKeyHandling > 1 || Interface->Confirm(tr("Pause live video?"))) {
-                        if (!cRecordControls::PauseLiveVideo())
+                        if (!cRecordControls::PauseLiveVideo(int(key) == kFastRew))
                            Skins.QueueMessage(mtError, tr("No free DVB device to record!"));
                         }
