Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] [PATCH] cDvbTuner - Rev. 2
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.
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