Mailing List archive

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

[vdr] Re: [PATCH] cDvbTuner - Rev. 2



Stefan Meyknecht wrote:
> Hi,
> 
> the attached patch solves the zapping problems on my system entirely. 
> 
> The effect Wolfgang Fritz observed (FE_HAS_LOCK status disappears 
> after frontend event) does not occur  on my system. Once the bit is 
> set it keeps until the next tuning request. So I have focused my 
> activities on changes I can test.
> 

What I seen is, that I get a short FE_HAS_LOCK event on channels which
can not get a lock at all (I had an invalid entry in my channels.conf).
This was interpreted as a valid lock by the original VDR lock detection.
I've changed this to accept a lock only if it is stable for more than
300ms. For "good" channels it has the same effect as your patch (adding
a delay). I've done some other changes too, but meanwhile I've messed up
the source file in a way that I can't produce a patch. I hope I find the
time today to clean this up and post a patch on the list.

At least my problem (VDR crashes at the beginning of a recording) seems
to be solved or at least much better with it.

Wolfgang

> To reduce delays I have introduced the cCondVar evLocked to signal 
> locked status and use poll() to wait for frontend event. It turned 
> out that it is necessary to insert a small delay (15ms) after 
> FE_HAS_LOCK status. Without, the tuning problems do reappear...
> 
> Now I am able to turn on EPG scanning over night without problems 
> except ...tadaaa... the first recording is interrupted  with "video 
> data stream broken" error. Maybe the 15ms delay is not enough, but it 
> is hard to test because you have to wait a long time before this 
> error occurs.
> 
> First of all I'm happy with this patch. The zapping problems are very 
> annoying. Maybe someone can explain why the delay after detection of 
> FE_HAS_LOCK status is necessary.
> 
> Stefan
> 
> 
> ------------------------------------------------------------------------
> 
> --- dvbdevice.c.orig	2004-06-19 11:33:42.000000000 +0200
> +++ dvbdevice.c	2004-07-29 18:59:20.000000000 +0200
> @@ -35,7 +35,6 @@ extern "C" {
>  
>  #define DO_REC_AND_PLAY_ON_PRIMARY_DEVICE 1
>  #define DO_MULTIPLE_RECORDINGS 1
> -//#define WAIT_FOR_LOCK_AFTER_TUNING 1
>  
>  #define DEV_VIDEO         "/dev/video"
>  #define DEV_DVB_ADAPTER   "/dev/dvb/adapter"
> @@ -80,6 +79,7 @@ private:
>    eTunerStatus tunerStatus;
>    cMutex mutex;
>    cCondVar newSet;
> +  cCondVar evLocked;
>    bool SetFrontend(void);
>    virtual void Action(void);
>  public:
> @@ -132,6 +132,8 @@ void cDvbTuner::Set(const cChannel *Chan
>       startTime = time(NULL);
>    channel = *Channel;
>    newSet.Broadcast();
> +  if (tunerStatus < tsLocked)
> +    evLocked.TimedWait(mutex, 6000);
>  }
>  
>  static unsigned int FrequencyToHz(unsigned int f)
> @@ -241,6 +243,15 @@ bool cDvbTuner::SetFrontend(void)
>           esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
>           return false;
>      }
> +  
> +  /* discard stale events */
> +  dvb_frontend_event event;
> +  while (1)
> +  {
> +    if (ioctl(fd_frontend, FE_GET_EVENT, &event) == -1)
> +      break;
> +  }
> +  
>    if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
>       esyslog("ERROR: frontend %d: %m", cardIndex);
>       return false;
> @@ -248,6 +259,7 @@ bool cDvbTuner::SetFrontend(void)
>    return true;
>  }
>  
> +
>  void cDvbTuner::Action(void)
>  {
>    active = true;
> @@ -256,19 +268,28 @@ void cDvbTuner::Action(void)
>          if (tunerStatus == tsSet)
>             tunerStatus = SetFrontend() ? tsTuned : tsIdle;
>          if (tunerStatus == tsTuned) {
> -           fe_status_t status = fe_status_t(0);
> -           CHECK(ioctl(fd_frontend, FE_READ_STATUS, &status));
> -           if (status & FE_HAS_LOCK)
> -              tunerStatus = tsLocked;
> +           pollfd pfd;
> +           pfd.fd = fd_frontend;
> +           pfd.events = POLLIN | POLLPRI;
> +           int rc = poll(&pfd, 1, 5000);
> +           if (rc == 0)
> +              isyslog("WARNING: frontend %d poll timed out!", cardIndex + 1);
> +           else if (rc == -1)
> +              esyslog("ERROR: frontend %d poll failed - errno %d!", cardIndex + 1, errno);
>             }
>          if (tunerStatus != tsIdle) {
>             dvb_frontend_event event;
> -           if (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) {
> +           while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) {
>                if (event.status & FE_REINIT) {
>                   tunerStatus = tsSet;
> -                 esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
> +                 esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex + 1);
>                   continue;
>                   }
> +              if ((tunerStatus == tsTuned) && (event.status & FE_HAS_LOCK)) {
> +                 tunerStatus = tsLocked;
> +                 usleep(15*1000);
> +                 evLocked.Broadcast();
> +                 }
>                }
>             }
>          if (ciHandler) {
> @@ -293,7 +314,8 @@ void cDvbTuner::Action(void)
>                tunerStatus = tsLocked;
>             }
>          // in the beginning we loop more often to let the CAM connection start up fast
> -        newSet.TimedWait(mutex, (ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
> +        if (tunerStatus != tsTuned)
> +           newSet.TimedWait(mutex, (ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
>          }
>  }
>  
> @@ -748,13 +770,10 @@ bool cDvbDevice::SetChannelDevice(const 
>       TurnOffLiveMode();
>  
>    dvbTuner->Set(Channel, DoTune, !EITScanner.UsesDevice(this)); //XXX 1.3: this is an ugly hack - find a cleaner solution//XXX
> -
> -#ifdef WAIT_FOR_LOCK_AFTER_TUNING
> -  //XXX TODO preliminary fix for the "Unknown picture type" error
> -  time_t t0 = time(NULL);
> -  while (!dvbTuner->Locked() && time(NULL) - t0 < 5)
> -        usleep(100);
> -#endif
> +  
> +  if (!dvbTuner->Locked())
> +    isyslog("WARNING: tuner is not locked on device %d!", CardIndex() + 1);
> +  
>    // PID settings:
>  
>    if (TurnOnLivePIDs) {






Home | Main Index | Thread Index