From e73912d2e71f70952f9de8d056c32e9fe1b4b2df Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sat, 23 Oct 2004 10:04:01 +0200 Subject: [PATCH] Fixed detecting transponder lock; removed WAIT_FOR_LOCK_AFTER_TUNING; added some missing 'const' to cChannel --- CONTRIBUTORS | 3 +++ HISTORY | 8 +++++++ channels.c | 16 +++++++------- channels.h | 8 +++---- config.h | 6 +++--- dvbdevice.c | 59 ++++++++++++++++++++++++++++++++-------------------- 6 files changed, 62 insertions(+), 38 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 0874cf44..47ce533b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1100,3 +1100,6 @@ Udo Richter Sven Kreiensen for his help in keeping 'channels.conf.terr' up to date + +Stefan Meyknecht + for a patch that fixed detecting transponder lock in cDvbTuner diff --git a/HISTORY b/HISTORY index 769791e4..31551a29 100644 --- a/HISTORY +++ b/HISTORY @@ -3036,3 +3036,11 @@ Video Disk Recorder Revision History - Removed the 'Log' parameter from the cChannel::Set... functions. Instead checking if the channel has a non-zero number. - Updated 'channels.conf.terr' for Hannover (thanks to Sven Kreiensen). + +2004-10-23: Version 1.3.14 + +- Fixed detecting transponder lock in cDvbTuner (based on a patch from Stefan + Meyknecht). +- What was previously marked with WAIT_FOR_LOCK_AFTER_TUNING is now permanently + active and uses a cCondVar to signal when a transponder is locked. +- Added some missing 'const' to cChannel. diff --git a/channels.c b/channels.c index ad3ca7fc..ad8156d1 100644 --- a/channels.c +++ b/channels.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.c 1.27 2004/10/17 12:20:56 kls Exp $ + * $Id: channels.c 1.28 2004/10/22 14:11:07 kls Exp $ */ #include "channels.h" @@ -503,7 +503,7 @@ static int PrintParameter(char *p, char Name, int Value) return Value >= 0 && Value != 999 ? sprintf(p, "%c%d", Name, Value) : 0; } -const char *cChannel::ParametersToString(void) +const char *cChannel::ParametersToString(void) const { char type = *cSource::ToString(source); if (isdigit(type)) @@ -563,14 +563,12 @@ bool cChannel::StringToParameters(const char *s) return true; } -const char *cChannel::ToText(cChannel *Channel) +const char *cChannel::ToText(const cChannel *Channel) { char buf[MaxChannelName * 2]; - char *s = Channel->name; - if (strchr(s, ':')) { - s = strcpy(buf, s); - strreplace(s, ':', '|'); - } + const char *s = Channel->name; + if (strchr(s, ':')) + s = strreplace(strcpy(buf, s), ':', '|'); free(buffer); if (Channel->groupSep) { if (Channel->number) @@ -602,7 +600,7 @@ const char *cChannel::ToText(cChannel *Channel) return buffer; } -const char *cChannel::ToText(void) +const char *cChannel::ToText(void) const { return ToText(this); } diff --git a/channels.h b/channels.h index 666e91b6..a2530f10 100644 --- a/channels.h +++ b/channels.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.h 1.19 2004/10/17 11:52:07 kls Exp $ + * $Id: channels.h 1.20 2004/10/22 14:09:47 kls Exp $ */ #ifndef __CHANNELS_H @@ -88,7 +88,7 @@ class cChannel : public cListObject { friend class cMenuEditChannel; private: static char *buffer; - static const char *ToText(cChannel *Channel); + static const char *ToText(const cChannel *Channel); enum { MaxChannelName = 64 }; // 63 chars + terminating 0! int __BeginData__; char name[MaxChannelName]; @@ -122,14 +122,14 @@ private: int modification; cLinkChannels *linkChannels; cChannel *refChannel; - const char *ParametersToString(void); + const char *ParametersToString(void) const; bool StringToParameters(const char *s); public: cChannel(void); cChannel(const cChannel &Channel); ~cChannel(); cChannel& operator= (const cChannel &Channel); - const char *ToText(void); + const char *ToText(void) const; bool Parse(const char *s, bool AllowNonUniqueID = false); bool Save(FILE *f); const char *Name(void) const { return name; } diff --git a/config.h b/config.h index 6a8c6983..c3372a8b 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.200 2004/08/08 13:44:17 kls Exp $ + * $Id: config.h 1.201 2004/10/22 13:29:38 kls Exp $ */ #ifndef __CONFIG_H @@ -20,8 +20,8 @@ #include "i18n.h" #include "tools.h" -#define VDRVERSION "1.3.13" -#define VDRVERSNUM 10313 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.3.14" +#define VDRVERSNUM 10314 // Version * 10000 + Major * 100 + Minor #define MAXPRIORITY 99 #define MAXLIFETIME 99 diff --git a/dvbdevice.c b/dvbdevice.c index 561b6c62..0ccd94a2 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 1.97 2004/10/17 09:10:43 kls Exp $ + * $Id: dvbdevice.c 1.98 2004/10/23 09:57:19 kls Exp $ */ #include "dvbdevice.h" @@ -35,7 +35,7 @@ extern "C" { #define DO_REC_AND_PLAY_ON_PRIMARY_DEVICE 1 #define DO_MULTIPLE_RECORDINGS 1 -//#define WAIT_FOR_LOCK_AFTER_TUNING 1 +#define TUNER_LOCK_TIMEOUT 5000 // ms #define DEV_VIDEO "/dev/video" #define DEV_DVB_ADAPTER "/dev/dvb/adapter" @@ -78,6 +78,8 @@ private: bool useCa; time_t startTime; eTunerStatus tunerStatus; + cMutex mutex; + cCondVar locked; cCondWait newSet; bool SetFrontend(void); virtual void Action(void); @@ -86,7 +88,7 @@ public: virtual ~cDvbTuner(); bool IsTunedTo(const cChannel *Channel) const; void Set(const cChannel *Channel, bool Tune, bool UseCa); - bool Locked(void) { return tunerStatus >= tsLocked; } + bool Locked(int TimeoutMs = 0); }; cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType, cCiHandler *CiHandler) @@ -125,7 +127,7 @@ void cDvbTuner::Set(const cChannel *Channel, bool Tune, bool UseCa) if (Tune) tunerStatus = tsSet; else if (tunerStatus == tsCam) - tunerStatus = tsTuned; + tunerStatus = tsLocked; useCa = UseCa; if (Channel->Ca() && tunerStatus != tsCam) startTime = time(NULL); @@ -134,6 +136,14 @@ void cDvbTuner::Set(const cChannel *Channel, bool Tune, bool UseCa) newSet.Signal(); } +bool cDvbTuner::Locked(int TimeoutMs) +{ + cMutexLock MutexLock(&mutex); + if (TimeoutMs && tunerStatus < tsLocked) + locked.TimedWait(mutex, TimeoutMs); + return tunerStatus >= tsLocked; +} + static unsigned int FrequencyToHz(unsigned int f) { while (f && f < 1000000) @@ -253,22 +263,25 @@ void cDvbTuner::Action(void) active = true; while (active) { Lock(); - if (tunerStatus == tsSet) + if (tunerStatus == tsSet) { + dvb_frontend_event event; + while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) + ; // discard stale events 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; } if (tunerStatus != tsIdle) { dvb_frontend_event event; - if (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) { - if (event.status & FE_REINIT) { - tunerStatus = tsSet; - esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex); + 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); + } + if (event.status & FE_HAS_LOCK) { + cMutexLock MutexLock(&mutex); + tunerStatus = tsLocked; + locked.Broadcast(); + } } - } } if (ciHandler) { if (ciHandler->Process() && useCa) { @@ -293,7 +306,7 @@ void cDvbTuner::Action(void) } Unlock(); // in the beginning we loop more often to let the CAM connection start up fast - newSet.Wait((ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000); + newSet.Wait((tunerStatus == tsTuned || ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000); } } @@ -746,14 +759,16 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) if (TurnOffLivePIDs) TurnOffLiveMode(); + // Set the tuner and wait for a lock: + 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(TUNER_LOCK_TIMEOUT)) { + if (Channel->Number()) // don't log raw transponders + esyslog("ERROR: no lock for channel %s on device %d", Channel->ToText(), CardIndex() + 1); + return false; + } + // PID settings: if (TurnOnLivePIDs) {