diff options
Diffstat (limited to 'dvbdevice.c')
-rw-r--r-- | dvbdevice.c | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/dvbdevice.c b/dvbdevice.c index 3f38a0a..fb87ae4 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.100 2004/10/24 11:06:37 kls Exp $ + * $Id: dvbdevice.c 1.102 2004/10/30 14:53:30 kls Exp $ */ #include "dvbdevice.h" @@ -35,7 +35,6 @@ extern "C" { #define DO_REC_AND_PLAY_ON_PRIMARY_DEVICE 1 #define DO_MULTIPLE_RECORDINGS 1 -#define TUNER_LOCK_TIMEOUT 5000 // ms #define DEV_VIDEO "/dev/video" #define DEV_DVB_ADAPTER "/dev/dvb/adapter" @@ -81,6 +80,7 @@ private: cMutex mutex; cCondVar locked; cCondWait newSet; + bool GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs = 0); bool SetFrontend(void); virtual void Action(void); public: @@ -144,6 +144,36 @@ bool cDvbTuner::Locked(int TimeoutMs) return tunerStatus >= tsLocked; } +bool cDvbTuner::GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs) +{ + if (TimeoutMs) { + struct pollfd pfd; + pfd.fd = fd_frontend; + pfd.events = POLLIN | POLLPRI; + do { + int stat = poll(&pfd, 1, TimeoutMs); + if (stat == 1) + break; + if (stat < 0) { + if (errno == EINTR) + continue; + esyslog("ERROR: frontend %d poll failed: %m", cardIndex); + } + return false; + } while (0); + } + do { + int stat = ioctl(fd_frontend, FE_GET_EVENT, &Event); + if (stat == 0) + return true; + if (stat < 0) { + if (errno == EINTR) + continue; + } + } while (0); + return false; +} + static unsigned int FrequencyToHz(unsigned int f) { while (f && f < 1000000) @@ -260,18 +290,17 @@ bool cDvbTuner::SetFrontend(void) void cDvbTuner::Action(void) { + dvb_frontend_event event; active = true; while (active) { Lock(); if (tunerStatus == tsSet) { - dvb_frontend_event event; - while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) + while (GetFrontendEvent(event)) ; // discard stale events tunerStatus = SetFrontend() ? tsTuned : tsIdle; } if (tunerStatus != tsIdle) { - dvb_frontend_event event; - while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) { + while (GetFrontendEvent(event, 10)) { if (event.status & FE_REINIT) { tunerStatus = tsSet; esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex); @@ -306,7 +335,8 @@ void cDvbTuner::Action(void) } Unlock(); // in the beginning we loop more often to let the CAM connection start up fast - newSet.Wait((tunerStatus == tsTuned || ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000); + if (tunerStatus != tsTuned) + newSet.Wait((ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000); } } @@ -764,13 +794,6 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) if (EITScanner.UsesDevice(this)) return true; - // Wait for a lock: - - if (!dvbTuner->Locked(TUNER_LOCK_TIMEOUT)) { - esyslog("ERROR: no lock for channel %d on device %d", Channel->Number(), CardIndex() + 1); - return false; - } - // PID settings: if (TurnOnLivePIDs) { @@ -793,9 +816,9 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) return true; } -bool cDvbDevice::HasLock(void) +bool cDvbDevice::HasLock(int TimeoutMs) { - return dvbTuner ? dvbTuner->Locked() : false; + return dvbTuner ? dvbTuner->Locked(TimeoutMs) : false; } void cDvbDevice::SetVolumeDevice(int Volume) |