Improved pause handling

Message ID 4CF66D63.2040600@gmail.com
State New
Headers

Commit Message

Matti Lehtimäki Dec. 1, 2010, 3:44 p.m. UTC
  Hi,

Sometimes when you want to pause live video you are already recording 
the current channel. In such case it is not practical to start a new 
instant recording but it would be more practical to start replaying the 
recording already being made, jump to correct position in the recording 
and then pause. So I have implemented this for VDR-1.7.16 as a patch 
which adds two new options to "Pause kay handling" menu item to enable 
this behavior with or without confirmation.

Any improvements or suggestions are welcome.
  

Comments

Jan Willies Dec. 1, 2010, 4:07 p.m. UTC | #1
>
> Sometimes when you want to pause live video you are already recording the
> current channel. In such case it is not practical to start a new instant
> recording but it would be more practical to start replaying the recording
> already being made, jump to correct position in the recording and then
> pause. So I have implemented this for VDR-1.7.16 as a patch which adds two
> new options to "Pause kay handling" menu item to enable this behavior with
> or without confirmation.
>

I've always wondered myself why vdr behaves like that. Thanks for this
patch, hopefully it gets included.
  
Christopher Reimer Dec. 1, 2010, 6:22 p.m. UTC | #2
Thanks for this nice small patch.
  
JJussi Dec. 1, 2010, 7:24 p.m. UTC | #3
On 1.12.2010 17.44, Matti Lehtimäki wrote:
> Hi,
>
> Sometimes when you want to pause live video you are already recording 
> the current channel. In such case it is not practical to start a new 
> instant recording but it would be more practical to start replaying 
> the recording already being made, jump to correct position in the 
> recording and then pause. So I have implemented this for VDR-1.7.16 as 
> a patch which adds two new options to "Pause kay handling" menu item 
> to enable this behavior with or without confirmation.
>
> Any improvements or suggestions are welcome.
>
>
> _______________________________________________
> vdr mailing list
> vdr@linuxtv.org
> http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
Addition to that would be that (in same situation where there is 
recording ongoing) if user presses backward (<<) button or press "jump 
backward little" (1) or "jump backward big" (green) it would work as 
expected... Jumping to right place of recording.
  
Udo Richter Dec. 1, 2010, 7:43 p.m. UTC | #4
Am 01.12.2010 16:44, schrieb Matti Lehtimäki:
> Sometimes when you want to pause live video you are already recording
> the current channel. In such case it is not practical to start a new
> instant recording but it would be more practical to start replaying the
> recording already being made[...]
> 
> Any improvements or suggestions are welcome.

Nice idea, however I see one small drawback: Until now, a 'pause'
instant recording lasts 3 hours (or whatever was set up). With your
patch, this time shortens to the time of the recording, which might be
rather short, for example if the timer actually records the previous
show and overlaps for a few minutes.

This, together with the fact that this is probably unexpected by the
user, can lead to disaster: If he's time-shifting later on, he'll be
quite surprised that the recording has stopped minutes ago and the
in-between show is gone.

A probable solution would be to extend the ongoing recording to the
minimum time shift time, eg. Setup.InstantRecordTime.


However, I have no problem with the fact that the same show is recorded
twice. This doesn't cause too much system load, and with today's disk
sizes, it really doesn't hurt.


Cheers,

Udo
  
Matti Lehtimäki Dec. 2, 2010, 10:17 a.m. UTC | #5
2010/12/1 JJussi <vdr@jjussi.com>
> Addition to that would be that (in same situation where there is recording ongoing) if user presses backward (<<) button or press "jump backward little" (1) or "jump backward big" (green) it would work as expected... Jumping to right place of recording.

This is not possible easily since those buttons have different use
when watching live tv compared to watching a recording and therefore
normal usage would be changed too much. But you could do this even
with the current patch, you just have to press pause first and when
replay mode is enabled press the desired button.
  
Matti Lehtimäki Dec. 2, 2010, 10:55 a.m. UTC | #6
2010/12/1 Udo Richter <udo_richter@gmx.de>:
> Nice idea, however I see one small drawback: Until now, a 'pause'
> instant recording lasts 3 hours (or whatever was set up). With your
> patch, this time shortens to the time of the recording, which might be
> rather short, for example if the timer actually records the previous
> show and overlaps for a few minutes.

I also thought about this problem and I now might have a solution which
I'll try tonight. This would add a check if the time left in timer is longer
than the margin at stop defined in setup and would start replaying only if
this is true. Otherwise it would start a new instant recording as usual.

> This, together with the fact that this is probably unexpected by the
> user, can lead to disaster: If he's time-shifting later on, he'll be
> quite surprised that the recording has stopped minutes ago and the
> in-between show is gone.

This is one reason why I added this as optional feature.

> A probable solution would be to extend the ongoing recording to the
> minimum time shift time, eg. Setup.InstantRecordTime.

This is one possible solution and I will consider this also. This could be
another way of solving the problem if time left in the timer is too short.

> However, I have no problem with the fact that the same show is recorded
> twice. This doesn't cause too much system load, and with today's disk
> sizes, it really doesn't hurt.

This is quite true, but it seems some people like the new feature and I
would give it as an option.
  
Klaus Schmidinger Dec. 2, 2010, 11:10 a.m. UTC | #7
On 12/02/10 11:55, Matti Lehtimäki wrote:
> 2010/12/1 Udo Richter <udo_richter@gmx.de>:
>> Nice idea, however I see one small drawback: Until now, a 'pause'
>> instant recording lasts 3 hours (or whatever was set up). With your
>> patch, this time shortens to the time of the recording, which might be
>> rather short, for example if the timer actually records the previous
>> show and overlaps for a few minutes.
> 
> I also thought about this problem and I now might have a solution which
> I'll try tonight. This would add a check if the time left in timer is longer
> than the margin at stop defined in setup and would start replaying only if
> this is true. Otherwise it would start a new instant recording as usual.
> 
>> This, together with the fact that this is probably unexpected by the
>> user, can lead to disaster: If he's time-shifting later on, he'll be
>> quite surprised that the recording has stopped minutes ago and the
>> in-between show is gone.
> 
> This is one reason why I added this as optional feature.
> 
>> A probable solution would be to extend the ongoing recording to the
>> minimum time shift time, eg. Setup.InstantRecordTime.
> 
> This is one possible solution and I will consider this also. This could be
> another way of solving the problem if time left in the timer is too short.
> 
>> However, I have no problem with the fact that the same show is recorded
>> twice. This doesn't cause too much system load, and with today's disk
>> sizes, it really doesn't hurt.
> 
> This is quite true, but it seems some people like the new feature and I
> would give it as an option.

At any rate, it's not going to be included in the original VDR source.
It complicates things without having a real advantage.
As Udo already noted, with today's huge disks it doesn't matter if
a show is recorded twice. The benefit of keeping things simple outweighs
this by far.

Klaus
  

Patch

diff -Naur -x PLUGINS -x po vdr-1.7.16_orig/menu.c vdr-1.7.16_pause/menu.c
--- vdr-1.7.16_orig/menu.c	2010-06-06 12:56:16.000000000 +0300
+++ vdr-1.7.16_pause/menu.c	2010-11-30 21:09:07.000000000 +0200
@@ -3025,7 +3025,7 @@ 
 
 class cMenuSetupRecord : public cMenuSetupBase {
 private:
-  const char *pauseKeyHandlingTexts[3];
+  const char *pauseKeyHandlingTexts[5];
   const char *delTimeshiftRecTexts[3];
 public:
   cMenuSetupRecord(void);
@@ -3036,6 +3036,8 @@ 
   pauseKeyHandlingTexts[0] = tr("do not pause live video");
   pauseKeyHandlingTexts[1] = tr("confirm pause live video");
   pauseKeyHandlingTexts[2] = tr("pause live video");
+  pauseKeyHandlingTexts[3] = tr("confirm pause and switch to replay mode");
+  pauseKeyHandlingTexts[4] = tr("switch to replay mode");
   delTimeshiftRecTexts[0] = tr("no");
   delTimeshiftRecTexts[1] = tr("confirm");
   delTimeshiftRecTexts[2] = tr("yes");
@@ -3045,7 +3047,7 @@ 
   Add(new cMenuEditIntItem( tr("Setup.Recording$Primary limit"),             &data.PrimaryLimit, 0, MAXPRIORITY));
   Add(new cMenuEditIntItem( tr("Setup.Recording$Default priority"),          &data.DefaultPriority, 0, MAXPRIORITY));
   Add(new cMenuEditIntItem( tr("Setup.Recording$Default lifetime (d)"),      &data.DefaultLifetime, 0, MAXLIFETIME));
-  Add(new cMenuEditStraItem(tr("Setup.Recording$Pause key handling"),        &data.PauseKeyHandling, 3, pauseKeyHandlingTexts));
+  Add(new cMenuEditStraItem(tr("Setup.Recording$Pause key handling"),        &data.PauseKeyHandling, 5, pauseKeyHandlingTexts));
   Add(new cMenuEditIntItem( tr("Setup.Recording$Pause priority"),            &data.PausePriority, 0, MAXPRIORITY));
   Add(new cMenuEditIntItem( tr("Setup.Recording$Pause lifetime (d)"),        &data.PauseLifetime, 0, MAXLIFETIME));
   Add(new cMenuEditBoolItem(tr("Setup.Recording$Use episode name"),          &data.UseSubtitle));
@@ -4207,6 +4209,19 @@ 
      AssertFreeDiskSpace(Timer->Priority(), !Timer->Pending());
      Timer->SetPending(true);
      }
+  else if (Setup.PauseKeyHandling > 2 && Pause) { // PauseLiveVideo & do not start recording
+     cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
+     for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) {
+         if ((t->Channel() == channel) && t->Recording()) {
+            for (int i = 0; i < MAXRECORDCONTROLS; i++) {
+                if (RecordControls[i] && RecordControls[i]->Timer()->Channel() == t->Channel()) {
+                   cReplayControl::SetRecording(RecordControls[i]->FileName(), t->File());
+                   return true;
+                   }
+                }
+            }
+         }
+     }
   VideoDiskSpace(&FreeMB);
   if (FreeMB < MINFREEDISK) {
      if (!Timer || time(NULL) - LastNoDiskSpaceMessage > NODISKSPACEDELTA) {
@@ -4274,11 +4289,23 @@ 
 {
   Skins.Message(mtStatus, tr("Pausing live video..."));
   cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
+  cTimer * timer = NULL;
+  if (Setup.PauseKeyHandling > 2) {
+    for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) { // find timer of current recording
+      if ((t->Channel() == Channels.GetByNumber(cDevice::CurrentChannel())) && t->Recording())
+        timer = t;
+        }
+    }
   if (Start(NULL, true)) {
      sleep(2); // allow recorded file to fill up enough to start replaying
      cReplayControl *rc = new cReplayControl;
      cControl::Launch(rc);
      cControl::Attach();
+     if (timer) { // if already recording current channel before pause jump to correct position of recording
+        int Current, Total;
+        rc->GetIndex(Current, Total, true);
+        rc->Goto(SecondsToFrames((Total / rc->FramesPerSecond())-2), false);
+        }
      sleep(1); // allow device to replay some frames, so we have a picture
      Skins.Message(mtStatus, NULL);
      rc->ProcessKey(kPause); // pause, allowing replay mode display
diff -Naur -x PLUGINS -x po vdr-1.7.16_orig/vdr.c vdr-1.7.16_pause/vdr.c
--- vdr-1.7.16_orig/vdr.c	2010-04-05 13:06:16.000000000 +0300
+++ vdr-1.7.16_pause/vdr.c	2010-11-30 20:00:48.000000000 +0200
@@ -1074,7 +1074,7 @@ 
                if (!cControl::Control()) {
                   DELETE_MENU;
                   if (Setup.PauseKeyHandling) {
-                     if (Setup.PauseKeyHandling > 1 || Interface->Confirm(tr("Pause live video?"))) {
+                     if ((Setup.PauseKeyHandling == 2 || Setup.PauseKeyHandling == 4) || ((Setup.PauseKeyHandling == 1 || Setup.PauseKeyHandling == 3) && Interface->Confirm(tr("Pause live video?")))) {
                         if (!cRecordControls::PauseLiveVideo())
                            Skins.Message(mtError, tr("No free DVB device to record!"));
                         }