VDR-1.3.37: retuning -- possibly a fix for VDSB
Commit Message
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
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.
@@ -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;
}