Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Re: Bug in 'PauseLiveVideo'



Werner Fink was kind enough to forward this posting to me,
which apparently didn't reach me when it was originally sent.

Since I don't have the original posting here, this reply will
break the thread (which, according to the archive at linuxtv.org
consists only of the original posting, anyway), so please forgive
me for this. I'm quoting it in full to have the complete context.

> ----- Forwarded message from theNoad <theNoad@SoftHome.net> -----
> Return-Path: <vdr-bounce@linuxtv.org>
> From: theNoad <theNoad@SoftHome.net>
> To: vdr Mailingliste <vdr@linuxtv.org>
> Subject: [vdr] Bug in 'PauseLiveVideo'
> Date: Sun, 15 Jun 2003 00:37:09 +0200
> User-Agent: KMail/1.5.1
> MIME-Version: 1.0
> Content-Disposition: inline
> Content-Type: Multipart/Mixed; boundary="Boundary-00=_VO66+Kype+NtYLF"
> Message-Id: <200306150037.09569.theNoad@SoftHome.net>
> Sender: vdr-bounce@linuxtv.org
> Errors-To: vdr-bounce@linuxtv.org
> X-original-sender: theNoad@SoftHome.net
> Precedence: bulk
> Reply-To: vdr@linuxtv.org
> X-list: vdr
> 
> --Boundary-00=_VO66+Kype+NtYLF
> Content-Type: text/plain; charset="iso-8859-15"
> Content-Transfer-Encoding: quoted-printable
> Content-Disposition: inline
> 
> Hello,
> after playing with the ''PauseLiveVideo' function in vdr 1.2.1 today i've=20
> noticed the following bug:
> If you stop the live-view and call again the pause-function (on the same=20
> channel), sometimes vdr dies. If this happens, the last eintries in the log=
> =20
> are:
> Jun 14 22:35:57 linux vdr[15822]: already recording:=20
> '/video/@Tremors_2_-_Die_R=FCckkehr_der_Raketenw=FCrmer__/2003-06-14.22.35.=
> 10.01.rec'
> Jun 14 22:35:59 linux vdr[15822]: replay (null)
> 
> This happens only if the new start of the PauseLiveVideo is in the same min=
> ute=20
> as start before because the generated name for the timer is the same. You c=
> an =20
> find the code which caused this behavior in menu.c, cRecordControl=20
> constructor, after the comment "crude attempt to avoid duplicate recordings=
> :"
> 
> If you stop the live-view and call again the pause-function (on the same=20
> channel) at least 1 minute after the first call, vdr will create again a=20
> recording timer for this channel. Now you have 2 recordings for the same=20
> channel, as you can also see in the menu( my current record is 6 recordings=
> =20
> for the same channel). Next error: if you use the menu-function 'stop=20
> recording <instantId>' for one of these recordings, all of them will be=20
> stopped.
> 
> In my opinion the PausLiveVideo-function should reenter the current=20
> instant-recording of the channel if there is one. This could be done by=20
> checking the instantId of the cRecordControl-entries when PauseLiveVideo is=
> =20
> invoked. If you agree with this you can test the following patch.
> 
> Greetings
> 
> --Boundary-00=_VO66+Kype+NtYLF
> Content-Type: text/x-diff; charset="iso-8859-15";  name="plv.diff"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: attachment; filename="plv.diff"
> 
> diff -Nru vdr-1.2.1/include/vdr/menu.h vdr-1.2.1patch/include/vdr/menu.h
> --- vdr-1.2.1/include/vdr/menu.h        2003-06-14 10:40:42.000000000 +0200
> +++ vdr-1.2.1patch/include/vdr/menu.h   2003-06-14 15:44:45.000000000 +0200
> @@ -138,6 +138,7 @@
>    static bool PauseLiveVideo(void);
>    static const char *GetInstantId(const char *LastInstantId);
>    static cRecordControl *GetRecordControl(const char *FileName);
> +  static cRecordControl *GetRecordControlByInstantId(const char *InstantId);
>    static void Process(time_t t);
>    static bool Active(void);
>    static void Shutdown(void);
> diff -Nru vdr-1.2.1/menu.c vdr-1.2.1patch/menu.c
> --- vdr-1.2.1/menu.c    2003-06-14 10:40:42.000000000 +0200
> +++ vdr-1.2.1patch/menu.c       2003-06-15 00:10:21.000000000 +0200
> @@ -3115,12 +3115,35 @@
> 
>  bool cRecordControls::PauseLiveVideo(void)
>  {
> +  char *theInstantId = NULL;
> +  cTimer *timer = new cTimer(true, true);
> +  cDevice *device = cDevice::PrimaryDevice();//XXX
> +  asprintf(&theInstantId, cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->CardIndex() + 1);

This won't work reliably on systems with more than one device, since you can't
know which device the recording was started on.

> +  delete timer;
> +  cRecordControl *cRC = cRecordControls::GetRecordControlByInstantId(theInstantId);
> +  free(theInstantId);
> +
>    Interface->Open(Setup.OSDwidth, -1);
> -  Interface->Status(tr("Pausing live video..."));
> -  Interface->Flush();
> -  cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
> -  if (Start(NULL, true)) {
> -     sleep(2); // allow recorded file to fill up enough to start replaying
> +
> +  bool bStartOk = false;
> +  if (cRC != NULL){
> +     Interface->Status(tr("Resume live video..."));
> +     Interface->Flush();
> +     cReplayControl::SetRecording(cRC->FileName(), NULL);
> +     bStartOk = true;
> +  }
> +  else
> +  {
> +     Interface->Status(tr("Pausing live video..."));
> +     Interface->Flush();
> +     cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed()
> +     if (Start(NULL, true))
> +     {
> +        bStartOk = true;
> +        sleep(2); // allow recorded file to fill up enough to start replaying
> +     }
> +  }
> +  if (bStartOk) {
>       cReplayControl *rc = new cReplayControl;
>       cControl::Launch(rc);
>       cControl::Attach();
> @@ -3155,6 +3178,19 @@
>    return NULL;
>  }
> 
> +cRecordControl *cRecordControls::GetRecordControlByInstantId(const char *InstantId)
> +{
> +  if( InstantId == NULL )
> +    return NULL;
> +  dsyslog("GetRecordControlByInstantId instantId: '%s'", InstantId);
> +  for (int i = 0; i < MAXRECORDCONTROLS; i++) {
> +      dsyslog("GetRecordControlByInstantId %d instantId: '%s'",i, (RecordControls[i] != NULL ? RecordControls[i]->InstantId() : ""));
> +      if (RecordControls[i] && RecordControls[i]->InstantId() != NULL && strcmp(RecordControls[i]->InstantId(), InstantId) == 0)
> +         return RecordControls[i];
> +      }
> +  return NULL;
> +}
> +
>  void cRecordControls::Process(time_t t)
>  {
>    for (int i = 0; i < MAXRECORDCONTROLS; i++) {
> diff -Nru vdr-1.2.1/menu.h vdr-1.2.1patch/menu.h
> --- vdr-1.2.1/menu.h    2003-06-14 10:40:42.000000000 +0200
> +++ vdr-1.2.1patch/menu.h       2003-06-14 15:44:45.000000000 +0200
> @@ -138,6 +138,7 @@
>    static bool PauseLiveVideo(void);
>    static const char *GetInstantId(const char *LastInstantId);
>    static cRecordControl *GetRecordControl(const char *FileName);
> +  static cRecordControl *GetRecordControlByInstantId(const char *InstantId);
>    static void Process(time_t t);
>    static bool Active(void);
>    static void Shutdown(void);
> 
> --Boundary-00=_VO66+Kype+NtYLF--
> ----- End forwarded message -----

After giving this some thought I believe that the solution
could be a lot simpler:

--- menu.c      2003/08/03 09:38:37     1.264
+++ menu.c      2003/08/16 10:17:49
@@ -2997,6 +3001,8 @@
      else {
         Timers.Del(timer);
         Timers.Save();
+        if (!cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
+           cReplayControl::SetRecording(fileName, Recording.Name());
         }
      timer = NULL;
      return;

(note that the line numbers may be slightly off compared to version 1.2.2).

Please give this a try and let me know if it fixes the problem
for you.

Klaus


-- 
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe vdr" as subject.



Home | Main Index | Thread Index