Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] Re: [PATCH] cDvbTuner - Rev. 2
Stefan Meyknecht wrote:
> Hi,
>
> the attached patch solves the zapping problems on my system entirely.
>
> The effect Wolfgang Fritz observed (FE_HAS_LOCK status disappears
> after frontend event) does not occur on my system. Once the bit is
> set it keeps until the next tuning request. So I have focused my
> activities on changes I can test.
>
What I seen is, that I get a short FE_HAS_LOCK event on channels which
can not get a lock at all (I had an invalid entry in my channels.conf).
This was interpreted as a valid lock by the original VDR lock detection.
I've changed this to accept a lock only if it is stable for more than
300ms. For "good" channels it has the same effect as your patch (adding
a delay). I've done some other changes too, but meanwhile I've messed up
the source file in a way that I can't produce a patch. I hope I find the
time today to clean this up and post a patch on the list.
At least my problem (VDR crashes at the beginning of a recording) seems
to be solved or at least much better with it.
Wolfgang
> To reduce delays I have introduced the cCondVar evLocked to signal
> locked status and use poll() to wait for frontend event. It turned
> out that it is necessary to insert a small delay (15ms) after
> FE_HAS_LOCK status. Without, the tuning problems do reappear...
>
> Now I am able to turn on EPG scanning over night without problems
> except ...tadaaa... the first recording is interrupted with "video
> data stream broken" error. Maybe the 15ms delay is not enough, but it
> is hard to test because you have to wait a long time before this
> error occurs.
>
> First of all I'm happy with this patch. The zapping problems are very
> annoying. Maybe someone can explain why the delay after detection of
> FE_HAS_LOCK status is necessary.
>
> Stefan
>
>
> ------------------------------------------------------------------------
>
> --- dvbdevice.c.orig 2004-06-19 11:33:42.000000000 +0200
> +++ dvbdevice.c 2004-07-29 18:59:20.000000000 +0200
> @@ -35,7 +35,6 @@ extern "C" {
>
> #define DO_REC_AND_PLAY_ON_PRIMARY_DEVICE 1
> #define DO_MULTIPLE_RECORDINGS 1
> -//#define WAIT_FOR_LOCK_AFTER_TUNING 1
>
> #define DEV_VIDEO "/dev/video"
> #define DEV_DVB_ADAPTER "/dev/dvb/adapter"
> @@ -80,6 +79,7 @@ private:
> eTunerStatus tunerStatus;
> cMutex mutex;
> cCondVar newSet;
> + cCondVar evLocked;
> bool SetFrontend(void);
> virtual void Action(void);
> public:
> @@ -132,6 +132,8 @@ void cDvbTuner::Set(const cChannel *Chan
> startTime = time(NULL);
> channel = *Channel;
> newSet.Broadcast();
> + if (tunerStatus < tsLocked)
> + evLocked.TimedWait(mutex, 6000);
> }
>
> static unsigned int FrequencyToHz(unsigned int f)
> @@ -241,6 +243,15 @@ bool cDvbTuner::SetFrontend(void)
> esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
> return false;
> }
> +
> + /* discard stale events */
> + dvb_frontend_event event;
> + while (1)
> + {
> + if (ioctl(fd_frontend, FE_GET_EVENT, &event) == -1)
> + break;
> + }
> +
> if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
> esyslog("ERROR: frontend %d: %m", cardIndex);
> return false;
> @@ -248,6 +259,7 @@ bool cDvbTuner::SetFrontend(void)
> return true;
> }
>
> +
> void cDvbTuner::Action(void)
> {
> active = true;
> @@ -256,19 +268,28 @@ void cDvbTuner::Action(void)
> if (tunerStatus == tsSet)
> 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;
> + pollfd pfd;
> + pfd.fd = fd_frontend;
> + pfd.events = POLLIN | POLLPRI;
> + int rc = poll(&pfd, 1, 5000);
> + if (rc == 0)
> + isyslog("WARNING: frontend %d poll timed out!", cardIndex + 1);
> + else if (rc == -1)
> + esyslog("ERROR: frontend %d poll failed - errno %d!", cardIndex + 1, errno);
> }
> if (tunerStatus != tsIdle) {
> dvb_frontend_event event;
> - if (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) {
> + 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);
> + esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex + 1);
> continue;
> }
> + if ((tunerStatus == tsTuned) && (event.status & FE_HAS_LOCK)) {
> + tunerStatus = tsLocked;
> + usleep(15*1000);
> + evLocked.Broadcast();
> + }
> }
> }
> if (ciHandler) {
> @@ -293,7 +314,8 @@ void cDvbTuner::Action(void)
> tunerStatus = tsLocked;
> }
> // in the beginning we loop more often to let the CAM connection start up fast
> - newSet.TimedWait(mutex, (ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
> + if (tunerStatus != tsTuned)
> + newSet.TimedWait(mutex, (ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
> }
> }
>
> @@ -748,13 +770,10 @@ bool cDvbDevice::SetChannelDevice(const
> TurnOffLiveMode();
>
> 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())
> + isyslog("WARNING: tuner is not locked on device %d!", CardIndex() + 1);
> +
> // PID settings:
>
> if (TurnOnLivePIDs) {
Home |
Main Index |
Thread Index