[mythtv] DisEqC and dvbchannel-v5.patch
Stuart Auchterlonie
stuarta at squashedfrog.net
Thu Sep 8 12:55:38 UTC 2005
On Thu, Sep 08, 2005 at 01:18:58PM +0100, Allan Stirling wrote:
> Stuart Auchterlonie wrote:
> >On Thu, Sep 08, 2005 at 12:04:10PM +0100, Allan Stirling wrote:
> >
> >>Daniel Kristjansson wrote:
> >>
> >>>Can you try the latest code?
> >>
> >>Err... Don't you mean to do something like this (Not a proper patch -
> >>There's some other non-related cruft in my dvbchannel.cpp) :
> >>
> >>@@ -689,11 +785,12 @@
> >>{
> >> fe_status_t status;
> >>
> >> usleep(2000); // yield for 2 ms
> >> ioctl(fd, FE_READ_STATUS, &status);
> >> VERBOSE(VB_CHANNEL, toString(status));
> >>-
> >>- return true;
> >>+ if (status&&FE_HAS_LOCK)
> >>+ return true;
> >>+ return false;
> >>}
> >
> >
> >This shouldn't be here as the comments on that function say not
> >to block and wait for lock as that is the job of the signal monitor.
> >
> >That said, it probably should have a select loop with a smallish
> >timeout instead.
> >
> Err... It's still not blocking?
True.
>
> >
> >>/** \fn handle_diseq(int, const DVBTuning&, DVBDiSEqC*, bool)
> >>@@ -725,7 +822,8 @@
> >> "Setting Frontend tuning parameters failed.");
> >> return false;
> >> }
> >>- wait_for_backend(fd_frontend);
> >>+ if (wait_for_backend(fd_frontend))
> >>+ havetuned=true;
> >> }
> >
> >
> >The way wait_for_backend is currently written havetuned would
> >always be set to true since wait for backend always returns true.
> >
> Uhuh. That'd be the first part of the patch, above ;)
>
> Well, this works, the original code... Doesn't. How does it exit from
> the loop when tuning was successful? havetuned is never set inside the loop.
This make sense.
I've done up a patch which similar to my previous eventlock stuff.
It converts wait_for_backend to use select with a timeout that is
passed to it (currently 500ms for dvb-t, 5s for dvb-s) and also
adds drain_dvb_events which removes any events already on the
frontend before we ask it to tune.
I've tested this with dvb-t and it works okay. See how this goes.
btw. It contains the second part of your patch as well.
Stuart
-------------- next part --------------
Index: mythtv/libs/libmythtv/dvbchannel.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/dvbchannel.cpp 2005-09-07 23:49:25.000000000 +0100
+++ mythtv/libs/libmythtv/dvbchannel.cpp 2005-09-08 13:41:00.000000000 +0100
@@ -42,6 +42,9 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/poll.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include "RingBuffer.h"
#include "recorderbase.h"
@@ -65,8 +68,9 @@
# define VSB_16 (QAM_AUTO+2)
#endif
-static bool wait_for_backend(int fd);
+static bool wait_for_backend(int fd, int timeout);
static bool handle_diseq(int fd, const DVBTuning&, DVBDiSEqC*, bool reset);
+static void drain_dvb_events(int fd);
/** \class DVBChannel
* \brief Provides interface to the tuning hardware when using DVB drivers
@@ -552,6 +556,9 @@
// We are now waiting for a new PMT to forward to Access Control (dvbcam).
SetPMT(NULL);
+ // Remove any events in queue before tuning.
+ drain_dvb_events(fd_frontend);
+
// Send DisEq commands to external hardware if we need to,
// and handle tuning the old way.
if (has_diseq)
@@ -577,7 +584,7 @@
"Setting Frontend tuning parameters failed.");
return false;
}
- wait_for_backend(fd_frontend);
+ wait_for_backend(fd_frontend, 500000);
prev_tuning.params = channel.tuning.params;
first_tune = false;
@@ -685,15 +692,29 @@
* We do not block until we have a lock, the signal
* monitor does that.
*/
-static bool wait_for_backend(int fd)
+static bool wait_for_backend(int fd, int timeout)
{
fe_status_t status;
+ fd_set fds;
+ struct timeval tv;
- usleep(2000); // yield for 2 ms
- ioctl(fd, FE_READ_STATUS, &status);
- VERBOSE(VB_CHANNEL, toString(status));
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ tv.tv_sec=timeout/1000;
+ tv.tv_usec=(timeout*1000) % 1000000;
- return true;
+ if (select(fd+1, &fds, NULL, NULL, &tv) > 0)
+ {
+ if(ioctl(fd, FE_READ_STATUS, &status) < 0)
+ {
+ VERBOSE(VB_CHANNEL, QString("failed to get status %1")
+ .arg(strerror(errno)));
+ return false;
+ }
+ VERBOSE(VB_CHANNEL, toString(status));
+ return true;
+ }
+ return false;
}
/** \fn handle_diseq(int, const DVBTuning&, DVBDiSEqC*, bool)
@@ -725,8 +746,15 @@
"Setting Frontend tuning parameters failed.");
return false;
}
- wait_for_backend(fd_frontend);
+ if (wait_for_backend(fd_frontend,50000000))
+ havetuned=true;
}
return havetuned;
}
+
+static void drain_dvb_events(int fd)
+{
+ struct dvb_frontend_event event;
+ while (ioctl(fd, FE_GET_EVENT, &event) == 0) { }
+}
More information about the mythtv-dev
mailing list