Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] Re: Fixed tuner lock detection
Klaus Schmidinger wrote:
> Attached is what I believe is the extract of all the suggested
> patches to fix problems with tuning of DVB cards.
>
> Those who have had problems in that area in the past, and had
> them fixed with (some combination of) the patches that were
> floating around lately should please try plain vanilla VDR 1.3.13
> with this patch (and nothing else), and let me know whether this
> still fixes their problems, or whether there is yet another thing
> that needs to be done.
>
> Note that the log message in case there is no lock may report
> a channel number of '0' - these are raw transponders which
> are found in the NIT. I'll probably check for 0 here, but at the moment
> it doesn't hurt.
>
> Klaus
>
>
> ------------------------------------------------------------------------
>
> --- dvbdevice.c 2004/10/17 09:10:43 1.97
> +++ dvbdevice.c 2004/10/22 14:55:10
> @@ -35,7 +35,7 @@
>
> #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 @@
> bool useCa;
> time_t startTime;
> eTunerStatus tunerStatus;
> + cMutex mutex;
> + cCondVar locked;
> cCondWait newSet;
> bool SetFrontend(void);
> virtual void Action(void);
> @@ -86,7 +88,7 @@
> 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 @@
> 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 @@
> 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 @@
> 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) {
Question 1: Are you sure the drivers always signal a valid lock on the
first "rising edge" of FE_HAS_LOCK? They didn't in the past (the "spike
problem").
Question 2: How is the case of a loss of lock handled (May occur e.g. in
bad weather conditions?). This case is not handled in
DvbTuner::Action(). Do we get a VDSB error and an emergency exit?
> + cMutexLock MutexLock(&mutex);
> + tunerStatus = tsLocked;
> + locked.Broadcast();
> + }
> }
> - }
> }
> if (ciHandler) {
> if (ciHandler->Process() && useCa) {
> @@ -293,7 +306,7 @@
> }
> 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,15 @@
> 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)) {
> + //XXX esyslog("ERROR: no lock for channel %s on device %d", Channel->ToText(), CardIndex() + 1);
> + return false;
> + }
> +
Fine! I am using a similar patch since quite some time now without problems.
> // PID settings:
>
> if (TurnOnLivePIDs) {
Home |
Main Index |
Thread Index