The DVB devices now retune (and, if applicable, resend the DiSEqC data) if the lock is lost

This commit is contained in:
Klaus Schmidinger 2006-01-01 12:22:18 +01:00
parent 0e6296699e
commit 06b2245bcd
3 changed files with 51 additions and 4 deletions

View File

@ -1012,6 +1012,8 @@ Reinhard Nissl <rnissl@gmx.de>
with post processing tools that choke on different ids with post processing tools that choke on different ids
for fixing cDvbPlayer::SkipFrames() to properly handle radio recordings for fixing cDvbPlayer::SkipFrames() to properly handle radio recordings
for improving TS/PES conversion to better handle lost TS packets for improving TS/PES conversion to better handle lost TS packets
for suggesting to make the DVB devices retune (and, if applicable, resend the
DiSEqC data) if the lock is lost
Richard Robson <richard_robson@beeb.net> Richard Robson <richard_robson@beeb.net>
for reporting freezing replay if a timer starts while in Transfer Mode from the for reporting freezing replay if a timer starts while in Transfer Mode from the

View File

@ -3963,7 +3963,7 @@ Video Disk Recorder Revision History
commands may now be executed at any time, and the message will be displayed commands may now be executed at any time, and the message will be displayed
(no more "pending message"). (no more "pending message").
2005-12-31: Version 1.3.38 2006-01-01: Version 1.3.38
- Fixed handling second audio and Dolby Digital PIDs for encrypted channels - Fixed handling second audio and Dolby Digital PIDs for encrypted channels
(was broken in version 1.3.37). (was broken in version 1.3.37).
@ -4051,3 +4051,5 @@ Video Disk Recorder Revision History
so that they can provide the full file name of the recording. Plugins that use so that they can provide the full file name of the recording. Plugins that use
these (or the related cStatus::Msg...() functions) need to be adapted these (or the related cStatus::Msg...() functions) need to be adapted
(suggested by Andreas Brugger). (suggested by Andreas Brugger).
- The DVB devices now retune (and, if applicable, resend the DiSEqC data) if
the lock is lost (based on a patch from Reinhard Nissl).

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: dvbdevice.c 1.143 2005/12/29 13:49:09 kls Exp $ * $Id: dvbdevice.c 1.144 2006/01/01 12:03:31 kls Exp $
*/ */
#include "dvbdevice.h" #include "dvbdevice.h"
@ -40,6 +40,13 @@
#define DEV_DVB_AUDIO "audio" #define DEV_DVB_AUDIO "audio"
#define DEV_DVB_CA "ca" #define DEV_DVB_CA "ca"
#define DVBS_TUNE_TIMEOUT 1000 //ms
#define DVBS_LOCK_TIMEOUT 1000 //ms
#define DVBC_TUNE_TIMEOUT 1000 //ms
#define DVBC_LOCK_TIMEOUT 1000 //ms
#define DVBT_TUNE_TIMEOUT 1000 //ms
#define DVBT_LOCK_TIMEOUT 1000 //ms
class cDvbName { class cDvbName {
private: private:
char buffer[PATH_MAX]; char buffer[PATH_MAX];
@ -66,6 +73,8 @@ private:
enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked }; enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
int fd_frontend; int fd_frontend;
int cardIndex; int cardIndex;
int tuneTimeout;
int lockTimeout;
fe_type_t frontendType; fe_type_t frontendType;
cCiHandler *ciHandler; cCiHandler *ciHandler;
cChannel channel; cChannel channel;
@ -238,6 +247,9 @@ bool cDvbTuner::SetFrontend(void)
Frontend.inversion = fe_spectral_inversion_t(channel.Inversion()); Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL; Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL;
Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH()); Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH());
tuneTimeout = DVBS_TUNE_TIMEOUT;
lockTimeout = DVBS_LOCK_TIMEOUT;
} }
break; break;
case FE_QAM: { // DVB-C case FE_QAM: { // DVB-C
@ -249,6 +261,9 @@ bool cDvbTuner::SetFrontend(void)
Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL; Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL;
Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH()); Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH());
Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation()); Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation());
tuneTimeout = DVBC_TUNE_TIMEOUT;
lockTimeout = DVBC_LOCK_TIMEOUT;
} }
break; break;
case FE_OFDM: { // DVB-T case FE_OFDM: { // DVB-T
@ -264,6 +279,9 @@ bool cDvbTuner::SetFrontend(void)
Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(channel.Transmission()); 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.guard_interval = fe_guard_interval_t(channel.Guard());
Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy()); Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy());
tuneTimeout = DVBT_TUNE_TIMEOUT;
lockTimeout = DVBT_LOCK_TIMEOUT;
} }
break; break;
default: default:
@ -279,6 +297,9 @@ bool cDvbTuner::SetFrontend(void)
void cDvbTuner::Action(void) void cDvbTuner::Action(void)
{ {
cTimeMs Timer;
bool LostLock = false;
time_t LastTimeoutReport = 0;
dvb_frontend_event event; dvb_frontend_event event;
while (Running()) { while (Running()) {
bool hasEvent = GetFrontendEvent(event, 1); bool hasEvent = GetFrontendEvent(event, 1);
@ -291,18 +312,40 @@ void cDvbTuner::Action(void)
if (hasEvent) if (hasEvent)
continue; continue;
tunerStatus = SetFrontend() ? tsTuned : tsIdle; tunerStatus = SetFrontend() ? tsTuned : tsIdle;
Timer.Set(tuneTimeout);
continue; continue;
case tsTuned: 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: case tsLocked:
if (hasEvent) { if (hasEvent) {
if (event.status & FE_REINIT) { if (event.status & FE_REINIT) {
tunerStatus = tsSet; tunerStatus = tsSet;
esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex); diseqcCommands = NULL;
esyslog("ERROR: frontend %d was reinitialized", cardIndex);
} }
if (event.status & FE_HAS_LOCK) { else if (event.status & FE_HAS_LOCK) {
if (LostLock) {
esyslog("frontend %d regained lock", cardIndex);
LostLock = false;
LastTimeoutReport = 0;
}
tunerStatus = tsLocked; tunerStatus = tsLocked;
locked.Broadcast(); locked.Broadcast();
} }
else if (tunerStatus == tsLocked) {
LostLock = true;
esyslog("ERROR: frontend %d lost lock", cardIndex);
tunerStatus = tsTuned;
Timer.Set(lockTimeout);
}
continue; continue;
} }
} }