VDR-1.3.37: retuning -- possibly a fix for VDSB

Message ID 43BA606B.5010703@cadsoft.de
State New
Headers

Commit Message

Klaus Schmidinger Jan. 3, 2006, 11:30 a.m. UTC
  Attached is a modified version of Reinhard's patch for
retuning after a timeout.

It has several macros for the various timeouts, depending
on what kind of DVB card is used:

#define DVBS_TUNE_TIMEOUT  2000 //ms
#define DVBS_LOCK_TIMEOUT  2000 //ms
#define DVBC_TUNE_TIMEOUT  5000 //ms
#define DVBC_LOCK_TIMEOUT  2000 //ms
#define DVBT_TUNE_TIMEOUT  9000 //ms
#define DVBT_LOCK_TIMEOUT  2000 //ms

Users with DVB-C and DVB-T cards should please test whether
the given values are ok (they are just guesses, since I don't
have such cards) and report in case they need other values.

Retuning is now done for all device types, not only if DiSEqC
commands are used.

Klaus
  

Comments

Thomas Rausch Jan. 3, 2006, 5:23 p.m. UTC | #1
After 6 hours I must say that my VDR did not bring yet back the error. 
So far otherwise always. I want to hope that it functions now. :)

In the LOG comes however repeatedly:

Jan  3 18:15:43 cat vdr[16675]: ERROR: frontend 0 lost lock
Jan  3 18:15:43 cat vdr[16675]: frontend 0 regained lock
Jan  3 18:16:03 cat vdr[16675]: ERROR: frontend 0 lost lock
Jan  3 18:16:03 cat vdr[16675]: frontend 0 regained lock
Jan  3 18:16:25 cat vdr[16675]: ERROR: frontend 0 lost lock
Jan  3 18:16:26 cat vdr[16675]: frontend 0 regained lock
Jan  3 18:16:45 cat vdr[16675]: ERROR: frontend 0 lost lock
Jan  3 18:16:45 cat vdr[16675]: frontend 0 regained lock
Jan  3 18:17:06 cat vdr[16675]: ERROR: frontend 0 lost lock
Jan  3 18:17:06 cat vdr[16675]: frontend 0 regained lock


My primary frontend is device 3.
  

Patch

--- dvbdevice.c	2005/11/26 13:23:11	1.138
+++ dvbdevice.c	2006/01/03 10:42:47
@@ -47,6 +40,13 @@ 
 #define DEV_DVB_AUDIO     "audio"
 #define DEV_DVB_CA        "ca"
 
+#define DVBS_TUNE_TIMEOUT  2000 //ms
+#define DVBS_LOCK_TIMEOUT  2000 //ms
+#define DVBC_TUNE_TIMEOUT  5000 //ms
+#define DVBC_LOCK_TIMEOUT  2000 //ms
+#define DVBT_TUNE_TIMEOUT  9000 //ms
+#define DVBT_LOCK_TIMEOUT  2000 //ms
+
 class cDvbName {
 private:
   char buffer[PATH_MAX];
@@ -73,6 +73,9 @@ 
   enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
   int fd_frontend;
   int cardIndex;
+  int tuneTimeout;
+  int lockTimeout;
+  time_t lastTimeoutReport;
   fe_type_t frontendType;
   cCiHandler *ciHandler;
   cChannel channel;
@@ -98,6 +101,9 @@ 
   cardIndex = CardIndex;
   frontendType = FrontendType;
   ciHandler = CiHandler;
+  tuneTimeout = 0;
+  lockTimeout = 0;
+  lastTimeoutReport = 0;
   diseqcCommands = NULL;
   tunerStatus = tsIdle;
   if (frontendType == FE_QPSK)
@@ -125,6 +131,7 @@ 
   if (Tune)
      tunerStatus = tsSet;
   channel = *Channel;
+  lastTimeoutReport = 0;
   newSet.Broadcast();
 }
 
@@ -245,6 +252,9 @@ 
          Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
          Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL;
          Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH());
+
+         tuneTimeout = DVBS_TUNE_TIMEOUT;
+         lockTimeout = DVBS_LOCK_TIMEOUT;
          }
          break;
     case FE_QAM: { // DVB-C
@@ -256,6 +266,9 @@ 
          Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL;
          Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH());
          Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation());
+
+         tuneTimeout = DVBC_TUNE_TIMEOUT;
+         lockTimeout = DVBC_LOCK_TIMEOUT;
          }
          break;
     case FE_OFDM: { // DVB-T
@@ -271,6 +284,9 @@ 
          Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(channel.Transmission());
          Frontend.u.ofdm.guard_interval = fe_guard_interval_t(channel.Guard());
          Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy());
+
+         tuneTimeout = DVBT_TUNE_TIMEOUT;
+         lockTimeout = DVBT_LOCK_TIMEOUT;
          }
          break;
     default:
@@ -286,6 +302,8 @@ 
 
 void cDvbTuner::Action(void)
 {
+  cTimeMs Timer;
+  bool LostLock = false;
   dvb_frontend_event event;
   while (Running()) {
         bool hasEvent = GetFrontendEvent(event, 1);
@@ -298,17 +316,41 @@ 
                if (hasEvent)
                   continue;
                tunerStatus = SetFrontend() ? tsTuned : tsIdle;
+               Timer.Set(tuneTimeout);
                continue;
           case tsTuned:
+               if (Timer.TimedOut()) {
+                  tunerStatus = tsSet;
+                  diseqcCommands = NULL;
+                  if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these
+                     esyslog("ERROR: frontend %d timed out while tuning", cardIndex);
+                     lastTimeoutReport = time(NULL);
+                     }
+                  continue;
+                  }
           case tsLocked:
                if (hasEvent) {
                   if (event.status & FE_REINIT) {
                      tunerStatus = tsSet;
-                     esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
+                     diseqcCommands = NULL;
+                     esyslog("ERROR: frontend %d was reinitialized", cardIndex);
+                     lastTimeoutReport = 0;
                      }
-                  if (event.status & FE_HAS_LOCK) {
+                  else if (event.status & FE_HAS_LOCK) {
+                     if (LostLock) {
+                        esyslog("frontend %d regained lock", cardIndex);
+                        LostLock = false;
+                        }
                      tunerStatus = tsLocked;
                      locked.Broadcast();
+                     lastTimeoutReport = 0;
+                     }
+                  else if (tunerStatus == tsLocked) {
+                     LostLock = true;
+                     esyslog("ERROR: frontend %d lost lock", cardIndex);
+                     tunerStatus = tsTuned;
+                     Timer.Set(lockTimeout);
+                     lastTimeoutReport = 0;
                      }
                   continue;
                   }