Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] Re: Latest status of FE_HAS_LOCK problem?
Klaus Schmidinger wrote:
> Yes, but which one?
> There seem to be several patches...
> Is it this one:
>
> http://www.linuxtv.org/mailinglists/vdr/2004/07-2004/msg00383.html
The attached patch is my latest version. But as I wrote in the other
mail, with your section handler patch this is not necessary (at least
on my system).
Stefan
diff -Nru vdr-1.3.12/dvbdevice.c vdr-1.3.12-sm01/dvbdevice.c
--- vdr-1.3.12/dvbdevice.c 2004-06-19 11:33:42.000000000 +0200
+++ vdr-1.3.12-sm01/dvbdevice.c 2004-10-10 23:48:13.000000000 +0200
@@ -6,7 +6,7 @@
*
* $Id: dvbdevice.c 1.93 2004/06/19 09:33:42 kls Exp $
*/
-
+#define __user
#include "dvbdevice.h"
#include <errno.h>
extern "C" {
@@ -35,7 +35,6 @@
#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 @@
eTunerStatus tunerStatus;
cMutex mutex;
cCondVar newSet;
+ cCondVar evLocked;
bool SetFrontend(void);
virtual void Action(void);
public:
@@ -132,6 +132,8 @@
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 @@
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 @@
return true;
}
+
void cDvbTuner::Action(void)
{
active = true;
@@ -256,19 +268,29 @@
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);
+ else if (rc == -1)
+ esyslog("ERROR: frontend %d poll failed - %m!", cardIndex);
}
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) {
+ dsyslog("Event on frontend %d (%-20.20s): %02x", cardIndex, channel.Name(), event.status);
if (event.status & FE_REINIT) {
tunerStatus = tsSet;
esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
continue;
}
+ if ((tunerStatus == tsTuned) && (event.status & FE_HAS_LOCK)) {
+ // usleep(30*1000);
+ tunerStatus = tsLocked;
+ evLocked.Broadcast();
+ }
}
}
if (ciHandler) {
@@ -293,7 +315,8 @@
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);
}
}
@@ -709,6 +732,8 @@
bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
{
+ dsyslog("SetChannelDevice: Channel %s, LiveView %s", Channel->Name(), LiveView ? "true" : "false");
+
bool IsEncrypted = Channel->Ca() > CACONFBASE && !ciHandler; // only LL-firmware can do non-live CA channels
bool DoTune = !dvbTuner->IsTunedTo(Channel);
@@ -737,7 +762,9 @@
#endif
// XXX 1.3: use the same mechanism as below (!EITScanner.UsesDevice(this))
- if (EITScanner.Active()) {
+ // if (EITScanner.Active()) {
+ if (EITScanner.UsesDevice(this)) {
+ dsyslog("EITScanner is active");
StartTransferMode = false;
TurnOnLivePIDs = false;
}
@@ -748,13 +775,12 @@
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()) {
+ esyslog("ERROR: failed to tune to channel %d \"%s\"", Channel->Number(), Channel->Name());
+ return false;
+ }
+
// PID settings:
if (TurnOnLivePIDs) {
Home |
Main Index |
Thread Index