Mailing List archive

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

[vdr] Re: Latest status of FE_HAS_LOCK problem?



Klaus Schmidinger wrote:
> Yes, but which one?
> There seem to be several patches...
> Is it this one:
>
> http://www.linuxtv.org/mailinglists/vdr/2004/07-2004/msg00383.html

The attached patch is my latest version. But as I wrote in the other 
mail, with your section handler patch this is not necessary (at least 
on my system).

Stefan


diff -Nru vdr-1.3.12/dvbdevice.c vdr-1.3.12-sm01/dvbdevice.c
--- vdr-1.3.12/dvbdevice.c	2004-06-19 11:33:42.000000000 +0200
+++ vdr-1.3.12-sm01/dvbdevice.c	2004-10-10 23:48:13.000000000 +0200
@@ -6,7 +6,7 @@
  *
  * $Id: dvbdevice.c 1.93 2004/06/19 09:33:42 kls Exp $
  */
-
+#define __user
 #include "dvbdevice.h"
 #include <errno.h>
 extern "C" {
@@ -35,7 +35,6 @@
 
 #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 @@
   eTunerStatus tunerStatus;
   cMutex mutex;
   cCondVar newSet;
+  cCondVar evLocked;
   bool SetFrontend(void);
   virtual void Action(void);
 public:
@@ -132,6 +132,8 @@
      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 @@
          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 @@
   return true;
 }
 
+
 void cDvbTuner::Action(void)
 {
   active = true;
@@ -256,19 +268,29 @@
         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);
+           else if (rc == -1)
+              esyslog("ERROR: frontend %d poll failed - %m!", cardIndex);
            }
         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) {
+              dsyslog("Event on frontend %d (%-20.20s): %02x", cardIndex, channel.Name(), event.status);
               if (event.status & FE_REINIT) {
                  tunerStatus = tsSet;
                  esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
                  continue;
                  }
+              if ((tunerStatus == tsTuned) && (event.status & FE_HAS_LOCK)) {
+                 // usleep(30*1000);
+                 tunerStatus = tsLocked;
+                 evLocked.Broadcast();
+                 }
               }
            }
         if (ciHandler) {
@@ -293,7 +315,8 @@
               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);
         }
 }
 
@@ -709,6 +732,8 @@
 
 bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
 {
+  dsyslog("SetChannelDevice: Channel %s, LiveView %s", Channel->Name(), LiveView ? "true" : "false");
+  
   bool IsEncrypted = Channel->Ca() > CACONFBASE && !ciHandler; // only LL-firmware can do non-live CA channels
 
   bool DoTune = !dvbTuner->IsTunedTo(Channel);
@@ -737,7 +762,9 @@
 #endif
 
   // XXX 1.3: use the same mechanism as below (!EITScanner.UsesDevice(this))
-  if (EITScanner.Active()) {
+  // if (EITScanner.Active()) {
+   if (EITScanner.UsesDevice(this)) {
+     dsyslog("EITScanner is active");
      StartTransferMode = false;
      TurnOnLivePIDs = false;
      }
@@ -748,13 +775,12 @@
      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()) {
+     esyslog("ERROR: failed to tune to channel %d \"%s\"", Channel->Number(), Channel->Name());
+     return false;
+     }
+  
   // PID settings:
 
   if (TurnOnLivePIDs) {

Home | Main Index | Thread Index