[mythtv] [PATCH] Remove use of deprecated DVB events.

Stuart Auchterlonie stuarta at squashedfrog.net
Thu Sep 1 17:20:14 UTC 2005


On Thu, Sep 01, 2005 at 05:46:19PM +0100, Mark Weaver wrote:
> >Hmmm, changing between channels on the same mplex the backend
> >gets stuck in select waiting for an event. This leads to the conclusion
> >that we are eating too many events. How or why I'm not sure at the
> >moment.
> >
> This is because there isn't an event if the frequency isn't changed. 
> The TuneXXX functions check if a tune is required and only call 
> FE_SET_FRONTEND if so.  Hence no event occurs on the same multiplex.
> 
> If you put the "if (havetuned==false) return true;" back in it shouldn't 
> do that.

Thanks Mark,

Have updated the previous patch from 5 mins ago to reflect this
new wisdom.

Version 3 of the patch is attached.


Please test.


Stuart

-------------- next part --------------
Index: libs/libmythtv/dvbchannel.cpp
===================================================================
--- libs/libmythtv/dvbchannel.cpp	(revision 115)
+++ libs/libmythtv/dvbchannel.cpp	(working copy)
@@ -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"
@@ -57,9 +60,6 @@
 #include "dvbdiseqc.h"
 #include "dvbcam.h"
 
-#define USE_BROKEN_DVB_DRIVER_HACK 1
-#define DVB_GET_EVENT_TIMEOUT 500 /* ms */
-
 #if (DVB_API_VERSION_MINOR <= 3 && DVB_API_VERSION_MINOR == 0)
 #    define FE_ATSC       (FE_OFDM+1)
 #    define FE_CAN_8VSB   0x200000
@@ -68,10 +68,7 @@
 #    define VSB_16        (QAM_AUTO+2)
 #endif
 
-bool flush_dvb_events(int fd, struct dvb_frontend_event &event);
-bool get_dvb_event(int fd, struct dvb_frontend_event &event,
-                   bool block = true, int timeout = -1);
-QString dvb_event_to_string(const struct dvb_frontend_event &event);
+QString dvb_status_to_string(const fe_status_t &status);
 
 /** \class DVBChannel
  *  \brief Provides interface to the tuning hardware when using DVB drivers
@@ -569,10 +566,15 @@
  *
  *  \param channel Info on transport to tune to
  *  \param all     If true frequency tuning is done even if not strictly needed.
+ *  \param timeout Time in ms to wait for tuning to succeed
  */
-bool DVBChannel::TuneTransport(const dvb_channel_t& channel, bool all, int)
+bool DVBChannel::TuneTransport(const dvb_channel_t& channel, bool all, int timeout)
 {
     DVBTuning tuning = channel.tuning;
+    fe_status_t status = (fe_status_t) 0;
+    fd_set fds;
+    struct timeval tv;
+    struct dvb_frontend_event event;
 
     if (fd_frontend < 0)
     {
@@ -592,17 +594,15 @@
         first_tune = false;
     }
 
-    while (true)
+    if (ioctl(fd_frontend, FE_READ_STATUS, &status) == 0 &&
+        !(status & FE_HAS_LOCK))
+        reset = true;
+
+    while(true)
     {
         if (tune)
         {
-            struct dvb_frontend_parameters old_params;
-            struct dvb_frontend_event event;
-            bool chk = flush_dvb_events(fd_frontend, event);
-            if (chk)
-                old_params = event.parameters;
-            else
-                chk = (0 == ioctl(fd_frontend, FE_GET_FRONTEND, &old_params));
+            while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) { }
 
             switch(info.type)
             {
@@ -625,27 +625,37 @@
                     break;
 #endif
             }
-            bool frequency_unchanged =
-                ((old_params.frequency + 500000) > tuning.params.frequency) &&
-                (old_params.frequency < (tuning.params.frequency + 500000));
-            if (!chk || !frequency_unchanged)
+        }
+    
+        tune = false;
+        reset = false;
+    
+        if (havetuned==false) return true;
+
+        FD_ZERO(&fds);
+        FD_SET(fd_frontend, &fds);
+        tv.tv_sec=0;
+        tv.tv_usec=timeout*1000;
+
+        if (select(fd_frontend+1, &fds, NULL, NULL, &tv) > 0)
+        {
+            if(ioctl(fd_frontend, FE_READ_STATUS, &status) < 0)
             {
-                CHANNEL("Waiting for event");
-                if (get_dvb_event(fd_frontend, event, DVB_GET_EVENT_TIMEOUT))
-                    CHANNEL(dvb_event_to_string(event));
+                CHANNEL(QString("failed to get status %1")
+                        .arg(strerror(errno)));
+                return false;
             }
-
-            if (havetuned == false)
+            CHANNEL(QString("Tune status=0x%1, %2")
+                .arg(status,2,16)
+                .arg(dvb_status_to_string(status)));
+            if (status & FE_HAS_LOCK)
+            {
+                CHANNEL("DVBChannel::TuneTransport() LOCK!");
                 return true;
-
-            tune = false;
-            reset = false;
-
-            CHANNEL("Waiting for frontend event after tune.");
+            }
         }
-
-        return true;
     }
+    return true;
 }
 
 /** \fn DVBChannel::GetTuningParams(DVBTuning& tuning) const
@@ -853,104 +863,15 @@
         ChannelBase::GetCachedPids(chanid, pid_cache);
 }
 
-bool flush_dvb_events(int fd, struct dvb_frontend_event &last_event)
+QString dvb_status_to_string(const fe_status_t &status)
 {
-    bool have_event = false;
-    do
-    {
-        if (0 == ioctl(fd, FE_GET_EVENT, &last_event))
-        {
-            VERBOSE(VB_CHANNEL, "DVBEvents: Flushing "
-                    <<dvb_event_to_string(last_event));
-            have_event = true;
-        }
-    } while (errno != EWOULDBLOCK);
-    return have_event;
-}
-
-bool get_dvb_event(int fd, struct dvb_frontend_event &event,
-                   bool block, int timeout)
-{
-    QTime timer;
-    timer.start();
-    
-    while ((timeout <= 0) || (timer.elapsed() < timeout))
-    {
-        if (0 == ioctl(fd, FE_GET_EVENT, &event))
-            return true;
-        int ret = errno;
-        
-        if (EWOULDBLOCK == ret)
-        {
-            if (!block)
-                return false;
-            usleep(50); // it would be nicer to use select...
-        }
-        else if (EOVERFLOW == ret)
-        {
-            VERBOSE(VB_IMPORTANT, "DVBEvents: Oops, we lost some events...");
-        }
-        else if (EBADF == ret)
-        {
-            VERBOSE(VB_IMPORTANT, 
-                    "DVBEvents: fd("<<fd<<") is a bad file descriptor" );
-            return false;
-        }
-        else if (EFAULT == ret)
-        {
-            VERBOSE(VB_IMPORTANT, "DVBEvents: &event is a bad pointer");
-            return false;
-        }
-        else
-        {
-            VERBOSE(VB_IMPORTANT, "DVBEvents: unknown error... "<<ret);
-            return false; // unknown error...
-        }
-    }
-
-#if USE_BROKEN_DVB_DRIVER_HACK
-    if (timer.elapsed() >= timeout)
-    {
-        VERBOSE(
-            VB_IMPORTANT, "\n"
-            "*****************************************************************"
-            "\n"
-            " WARNING!! MythTV timeout out waiting for a required DVB event!\n"
-            " Most likely you are using a broken driver and should upgrade to\n"
-            " to the latest DVB driver immediately. This bug in your driver\n"
-            " will result in lost recordings and reduced functionality, and\n"
-            " indicates a DVB driver unsuitable for production use.\n"
-            "*****************************************************************"
-            "\n");
-
-        fe_status_t tmp_stat;
-        if (ioctl(fd, FE_READ_STATUS, &tmp_stat))
-        {
-            if (tmp_stat & FE_HAS_LOCK)
-            {
-                VERBOSE(VB_IMPORTANT, "MythTV HACK for BROKEN DVB drivers "
-                        "appears to have worked. Please upgrade DVB drivers.");
-                return true;
-            }
-        }
-        VERBOSE(VB_IMPORTANT, "MythTV HACK for BROKEN DVB drivers "
-                "FAILED! Upgrade your DVB drivers.");
-    }
-#endif // USE_BROKEN_DVB_DRIVER_HACK
-
-    return false;
-}
-
-QString dvb_event_to_string(const struct dvb_frontend_event &event)
-{
     QString str("");
-    if (FE_HAS_SIGNAL  & event.status) str += "Signal,";
-    if (FE_HAS_CARRIER & event.status) str += "Carrier,";
-    if (FE_HAS_VITERBI & event.status) str += "FEC Stable,";
-    if (FE_HAS_SYNC    & event.status) str += "Sync,";
-    if (FE_HAS_LOCK    & event.status) str += "Lock,";
-    if (FE_TIMEDOUT    & event.status) str += "Timed Out,";
-    if (FE_REINIT      & event.status) str += "Reinit,";
-    return QString("Event Status(%1) frequency(%2 Hz)")
-        .arg(str).arg(event.parameters.frequency);
+    if (FE_HAS_SIGNAL  & status) str += "Signal,";
+    if (FE_HAS_CARRIER & status) str += "Carrier,";
+    if (FE_HAS_VITERBI & status) str += "FEC Stable,";
+    if (FE_HAS_SYNC    & status) str += "Sync,";
+    if (FE_HAS_LOCK    & status) str += "Lock,";
+    if (FE_TIMEDOUT    & status) str += "Timed Out,";
+    if (FE_REINIT      & status) str += "Reinit,";
+    return str;
 }


More information about the mythtv-dev mailing list