From 6f93a5f7819b3c7030a5b199e502bedd4eb7844c Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 24 Oct 2004 18:00:00 +0200 Subject: =?UTF-8?q?Version=201.3.14=20-=20Fixed=20detecting=20transponder?= =?UTF-8?q?=20lock=20in=20cDvbTuner=20(based=20on=20a=20patch=20from=20Ste?= =?UTF-8?q?fan=20=20=20Meyknecht).=20-=20What=20was=20previously=20marked?= =?UTF-8?q?=20with=20WAIT=5FFOR=5FLOCK=5FAFTER=5FTUNING=20is=20now=20perma?= =?UTF-8?q?nently=20=20=20active=20and=20uses=20a=20cCondVar=20to=20signal?= =?UTF-8?q?=20when=20a=20transponder=20is=20locked.=20-=20Added=20some=20m?= =?UTF-8?q?issing=20'const'=20to=20cChannel.=20-=20Added=20a=20sample=20se?= =?UTF-8?q?tup=20for=20'DisiCon-4=20Single=20Cable=20Network'=20to=20'dise?= =?UTF-8?q?qc.conf'=20=20=20(thanks=20to=20Oliver=20Endriss).=20-=20Fixed?= =?UTF-8?q?=20attaching=20a=20cPlayer=20to=20a=20cDevice,=20so=20that=20'O?= =?UTF-8?q?peration=20not=20permitted'=20=20=20errors=20don't=20occur=20an?= =?UTF-8?q?y=20more=20(thanks=20to=20Marco=20Schl=C3=BC=C3=9Fler).=20-=20F?= =?UTF-8?q?ixed=20a=20case=20where=20the=20resultBuffer=20in=20cRemux=20ra?= =?UTF-8?q?n=20full=20before=20getting=20a=20sync.=20-=20Removed=20the=20u?= =?UTF-8?q?sleep()=20call=20from=20cDvbPlayer::Action()=20to=20make=20VDR?= =?UTF-8?q?=20run=20on=20NPTL=20=20=20systems=20(thanks=20to=20Alfred=20Za?= =?UTF-8?q?strow).=20The=20NPTL=20check=20at=20startup=20has=20also=20been?= =?UTF-8?q?=20=20=20removed.=20-=20Taking=20the=20complete=20size=20of=20a?= =?UTF-8?q?vailable=20data=20into=20account=20when=20deciding=20whether=20?= =?UTF-8?q?=20=20to=20clear=20the=20transfer=20buffer=20to=20avoid=20overf?= =?UTF-8?q?lows=20(thanks=20to=20Reinhard=20Nissl).=20-=20Updated=20Romani?= =?UTF-8?q?an=20language=20texts=20and=20the=20iso8859-2=20fonts=20(thanks?= =?UTF-8?q?=20to=20Lucian=20Muresan).=20-=20Now=20actually=20using=20the?= =?UTF-8?q?=20iso8859-15=20fonts=20(thanks=20to=20Lucian=20Muresan).=20-?= =?UTF-8?q?=20Some=20minor=20code=20cleanups=20(thanks=20to=20Prakash=20K.?= =?UTF-8?q?=20Cheemplavam).=20-=20Fixed=20missing=20cleanup=20at=20program?= =?UTF-8?q?=20exit=20in=20case=20there=20is=20a=20problem=20with=20a=20plu?= =?UTF-8?q?gin=20=20=20(thanks=20to=20Mattias=20Gr=C3=B6nlund=20for=20poin?= =?UTF-8?q?ting=20this=20out).=20-=20Increased=20the=20required=20free=20b?= =?UTF-8?q?uffer=20space=20in=20the=20resultBuffer=20of=20cRemux=20to=20?= =?UTF-8?q?=20=202=20*=20IPACKS=20to=20avoid=20a=20buffer=20overflow=20in?= =?UTF-8?q?=20case=20a=20cTS2PES=20writes=20one=20complete=20=20=20packet?= =?UTF-8?q?=20and=20then=20(within=20processing=20the=20same=20TS=20packet?= =?UTF-8?q?)=20wants=20to=20write=20another=20=20=20small=20packet.=20-=20?= =?UTF-8?q?Removed=20the=20signal=20handler=20and=20WakeUp()=20call=20from?= =?UTF-8?q?=20cThread=20(it=20is=20no=20longer=20=20=20needed).=20-=20Adde?= =?UTF-8?q?d=20some=20checks=20when=20canceling=20a=20thread=20and=20remov?= =?UTF-8?q?ed=20the=20usleep()=20in=20=20=20cThread::Start()=20(suggested?= =?UTF-8?q?=20by=20Ludwig=20Nussel).=20Also=20removed=20'running'=20from?= =?UTF-8?q?=20=20=20cThread=20and=20using=20only=20childTid=20to=20indicat?= =?UTF-8?q?e=20whether=20a=20thread=20is=20actually=20=20=20running.=20-?= =?UTF-8?q?=20Added=20cCondWait::Sleep()=20and=20using=20it=20to=20replace?= =?UTF-8?q?=20all=20usleep()=20calls=20(based=20=20=20on=20a=20suggestion?= =?UTF-8?q?=20by=20Werner=20Fink).=20-=20Only=20assigning=20events=20to=20?= =?UTF-8?q?timers=20if=20the=20related=20schedule=20has=20actually=20been?= =?UTF-8?q?=20=20=20modified.=20-=20When=20searching=20for=20the=20present?= =?UTF-8?q?=20event,=20the=20running=20status=20is=20now=20only=20taken=20?= =?UTF-8?q?=20=20into=20account=20if=20the=20event=20has=20been=20"seen"?= =?UTF-8?q?=20within=20the=20past=2030=20seconds.=20=20=20This=20avoids=20?= =?UTF-8?q?shortly=20seeing=20the=20wrong=20events=20in=20the=20channel=20?= =?UTF-8?q?display=20when=20=20=20switching=20to=20a=20channel=20that=20ha?= =?UTF-8?q?sn't=20been=20tuned=20to=20in=20a=20while.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvbdevice.c | 75 +++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 29 deletions(-) (limited to 'dvbdevice.c') 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 } -- cgit v1.2.3