[mythtv] dvb zero length record

Tom Hughes tom at compton.nu
Sun May 22 23:08:21 UTC 2005


In message <7EF2F2C5-3D31-4F20-8D4E-F8F00A1DFCAD at cse.unsw.edu.au>
          William Uther <willu.mailingLists at cse.unsw.edu.au> wrote:

> On Fri, 20 May 2005 09:01:32 +0100, Tom Hughes <tom at compton.nu> wrote:
> 
> > None of those sounds like my case which was reported in the other
> > thread that somebody referred you to. Those look like this:
> 
> [snip]
> 
> > 2005-05-09 13:38:10.289 DVB#0 Recorder: Card opened successfully
> > (using PS mode).
> 
> [snip]
> 
> > I believe I now understand what is causing those ones, and I've been
> > running with a fix since last Sunday and haven't lost anything yet. I
> > was only loosing one or two a week though so I want to run it for
> > another week or two before pronouncing it fixed for sure.
> 
> Do you know if your fix is PS/TS specific?

It shouldn't be specific to either mode - the problem is in
tuning the card to the right channel. How the data is read once
tuning is complete is irrelevant.

> I'd be happy to help test that for you (in TS mode) if you want to
> post a patch...

The basic problem is that sometime betwen 2.6.8 and 2.6.11 the
way in which tuning is handled for DVB cards changed.

It used to be that when the FE_SET_FRONTEND ioctl was called the
tuning was done by the frontend driver for the card you were using
which (at least for the TwinHan DST cards I use) changed channel
synchronously and didn't return from the ioctl until it had either
retuned or had failed to tune.

So when Myth then did an FE_READ_STATUS to check for the FE_HAS_LOCK
flag a lock would mean that the card had successfully tuned to the
new channel.

What happens now is that the generic part of the DVB code does the
tuning using a kernel thread which will potentially supply several
different sets of tuning parameters to the frontend driver if some
of the fields were left at auto in the FE_SET_FRONTEND call.

What this means is that tuning now happens in the background, but
because FE_READ_STATUS interrogates the frontend directly it can
see a lock for the old channel if the kernel thread hasn't started
tuning yet. Myth may then read a PMT from that multiplex and fail
to find the service it is looking for.

The fix I am using is to use FE_GET_EVENT instead which gets events
from the background kernel thread so only reports a lock when tuning
is really complete. So far it seems to be working.

If FE_GET_EVENT fails with EOPNOTSUPP due to running on an older
kernel then my patch falls back to FE_READ_STATUS instead.

The patch is attached if you want to try it.

Tom

-- 
Tom Hughes (tom at compton.nu)
http://www.compton.nu/
-------------- next part --------------
Index: libs/libmythtv/dvbchannel.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbchannel.cpp,v
retrieving revision 1.34
diff -u -u -r1.34 dvbchannel.cpp
--- libs/libmythtv/dvbchannel.cpp	15 May 2005 16:39:29 -0000	1.34
+++ libs/libmythtv/dvbchannel.cpp	22 May 2005 23:01:33 -0000
@@ -922,21 +922,36 @@
             CHANNEL("Waiting for frontend event after tune.");
         }
 
-        fe_status_t stat;
+        struct dvb_frontend_event event;
         int timeout = 0;
         QString status = "Status: ";
 
         do {
-            if (ioctl(fd_frontend, FE_READ_STATUS, &stat) < 0)
-                perror("FE_READ_STATUS failed");
+            if (ioctl(fd_frontend, FE_GET_EVENT, &event) < 0)
+            {
+                if (errno == EOPNOTSUPP)
+                {
+                    if (ioctl(fd_frontend, FE_READ_STATUS, &event.status) < 0)
+                    {
+                        perror("FE_READ_STATUS failed");
+                        event.status = (fe_status_t)0;
+                    }
+                }
+                else 
+                {
+                    if (errno != EWOULDBLOCK && errno != EOVERFLOW)
+                        perror("FE_GET_EVENT failed");
+                    event.status = (fe_status_t)0;
+                }
+            }
             if (fd_frontend < 0)
                 return false;
             else if (!(timeout % (1000000/TUNER_INTERVAL)))
             {
-                uint16_t ss;
-                uint16_t snr;
-                uint32_t ber;
-                uint32_t ub;
+                uint16_t ss = 0;
+                uint16_t snr = 0;
+                uint32_t ber = 0;
+                uint32_t ub = 0;
                 ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &ss);
                 ioctl(fd_frontend, FE_READ_SNR, &snr);
                 ioctl(fd_frontend, FE_READ_BER, &ber);
@@ -945,7 +960,7 @@
                 GENERAL(msg);
             }
 
-            if (stat & FE_HAS_LOCK)
+            if (event.status & FE_HAS_LOCK)
             {
                 status += "LOCK.";
                 GENERAL(status);


More information about the mythtv-dev mailing list