summaryrefslogtreecommitdiff
path: root/dvbdevice.c
diff options
context:
space:
mode:
Diffstat (limited to 'dvbdevice.c')
-rw-r--r--dvbdevice.c55
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)