[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