summaryrefslogtreecommitdiff
path: root/dvbdevice.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <kls (at) cadsoft (dot) de>2004-10-24 18:00:00 +0200
committerKlaus Schmidinger <kls (at) cadsoft (dot) de>2004-10-24 18:00:00 +0200
commit6f93a5f7819b3c7030a5b199e502bedd4eb7844c (patch)
tree3be72385cb6433514bf6232f83a6aaacea8a3e76 /dvbdevice.c
parentaf483c11aebd8146a978dba3d604bda0951e24ac (diff)
downloadvdr-patch-lnbsharing-6f93a5f7819b3c7030a5b199e502bedd4eb7844c.tar.gz
vdr-patch-lnbsharing-6f93a5f7819b3c7030a5b199e502bedd4eb7844c.tar.bz2
Version 1.3.14vdr-1.3.14
- Fixed detecting transponder lock in cDvbTuner (based on a patch from Stefan Meyknecht). - What was previously marked with WAIT_FOR_LOCK_AFTER_TUNING is now permanently active and uses a cCondVar to signal when a transponder is locked. - Added some missing 'const' to cChannel. - Added a sample setup for 'DisiCon-4 Single Cable Network' to 'diseqc.conf' (thanks to Oliver Endriss). - Fixed attaching a cPlayer to a cDevice, so that 'Operation not permitted' errors don't occur any more (thanks to Marco Schlüßler). - Fixed a case where the resultBuffer in cRemux ran full before getting a sync. - Removed the usleep() call from cDvbPlayer::Action() to make VDR run on NPTL systems (thanks to Alfred Zastrow). The NPTL check at startup has also been removed. - Taking the complete size of available data into account when deciding whether to clear the transfer buffer to avoid overflows (thanks to Reinhard Nissl). - Updated Romanian language texts and the iso8859-2 fonts (thanks to Lucian Muresan). - Now actually using the iso8859-15 fonts (thanks to Lucian Muresan). - Some minor code cleanups (thanks to Prakash K. Cheemplavam). - Fixed missing cleanup at program exit in case there is a problem with a plugin (thanks to Mattias Grönlund for pointing this out). - Increased the required free buffer space in the resultBuffer of cRemux to 2 * IPACKS to avoid a buffer overflow in case a cTS2PES writes one complete packet and then (within processing the same TS packet) wants to write another small packet. - Removed the signal handler and WakeUp() call from cThread (it is no longer needed). - Added some checks when canceling a thread and removed the usleep() in cThread::Start() (suggested by Ludwig Nussel). Also removed 'running' from cThread and using only childTid to indicate whether a thread is actually running. - Added cCondWait::Sleep() and using it to replace all usleep() calls (based on a suggestion by Werner Fink). - Only assigning events to timers if the related schedule has actually been modified. - When searching for the present event, the running status is now only taken into account if the event has been "seen" within the past 30 seconds. This avoids shortly seeing the wrong events in the channel display when switching to a channel that hasn't been tuned to in a while.
Diffstat (limited to 'dvbdevice.c')
-rw-r--r--dvbdevice.c75
1 files changed, 46 insertions, 29 deletions
diff --git a/dvbdevice.c b/dvbdevice.c
index 561b6c6..3f38a0a 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.97 2004/10/17 09:10:43 kls Exp $
+ * $Id: dvbdevice.c 1.100 2004/10/24 11:06:37 kls Exp $
*/
#include "dvbdevice.h"
@@ -35,7 +35,7 @@ extern "C" {
#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 @@ private:
bool useCa;
time_t startTime;
eTunerStatus tunerStatus;
+ cMutex mutex;
+ cCondVar locked;
cCondWait newSet;
bool SetFrontend(void);
virtual void Action(void);
@@ -86,7 +88,7 @@ public:
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 @@ void cDvbTuner::Set(const cChannel *Channel, bool Tune, bool UseCa)
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 @@ void cDvbTuner::Set(const cChannel *Channel, bool Tune, bool UseCa)
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 @@ void cDvbTuner::Action(void)
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) {
+ cMutexLock MutexLock(&mutex);
+ tunerStatus = tsLocked;
+ locked.Broadcast();
+ }
}
- }
}
if (ciHandler) {
if (ciHandler->Process() && useCa) {
@@ -293,7 +306,7 @@ void cDvbTuner::Action(void)
}
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);
}
}
@@ -735,25 +748,29 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
StartTransferMode = false;
#endif
- // XXX 1.3: use the same mechanism as below (!EITScanner.UsesDevice(this))
- if (EITScanner.Active()) {
- StartTransferMode = false;
- TurnOnLivePIDs = false;
- }
-
// Turn off live PIDs if necessary:
if (TurnOffLivePIDs)
TurnOffLiveMode();
+ // Set the tuner:
+
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 this channel switch was requested by the EITScanner we don't wait for
+ // a lock and don't set any live PIDs (the EITScanner will wait for the lock
+ // by itself before setting any filters):
+
+ 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) {
@@ -1058,7 +1075,7 @@ void cDvbDevice::StillPicture(const uchar *Data, int Length)
#define MIN_IFRAME 400000
for (int i = MIN_IFRAME / Length + 1; i > 0; i--) {
safe_write(fd_video, Data, Length);
- usleep(1); // allows the buffer to be displayed in case the progress display is active
+ cCondWait::SleepMs(1); // allows the buffer to be displayed in case the progress display is active
}
#endif
}