Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: "Video datastream brocken" - origin (maybe) found



Johannes Stezenbach wrote:
> Wolfgang Fritz wrote:
> 
>>I've changed the FE_GET_EVENT handling in VDR to use poll() and in this
>>case I see short 0x1f-events (FE_HAS_LOCK bit set) of abt 100ms on
>>channels I can't tune to (I had a bogus entry in my channels.conf).
>>
>>The original VDR lock detection handles this as a valid lock, which is a
>>bit sloppy in my opinion, but I would like to know if an application has
>>to expect such "spikes" and do some filtering on frontend events?
> 
> 
> Hm, it seems with frontend hardware one has to expect the unexpected...
> Unless there is some really strange bug the 0x1f status is
> signalled by the frontend, so there isn't much we can do about it.
> 

This seems to be a problem with VDR only.

I patched szap to use poll() (patch attached) and I get the expected
results: when tuning, the fe_status bits are set "from right to left",
status 0x1f being the last event. If I zap from one channel to another
in interactive mode this is the case too.

VDR seems to "remember" the last state of the previous tuning. Example:
If I had tuned to a valid channel (last status = 0x1f) and then tune to
a bogus channel, I always get the events 0x00,0x1f immediately, then
after abt 100ms the usual 0x01, 0x03, ... which I expect. So the first
two events seem to be bogus. I cannot see why this happens, but it
definitely fools the VDR lock detection.
> 
>>Other question: There _seems_ to be some evidence that it is dangerous
>>if you set (change?) filters when the frontend is not locked. Could that
>>be possible?
> 
> 
> Generally it should not be a problem, except for the av7110 based
> cards which might crash if the video/audio decoder is fed with junk.
> (It seems that skystar2 users also have problems, but I don't know
> anything about skystar2 hardware, so I cannot comment. Does anyone
> have a FlexCopII/III data sheet?)
> 

I have disabled hardware filters on my Skystar2 and got no broken video
stream errors since. I'll re-enable hardware filters and check if that
makes a difference.

> 
> Johannes
> 
> 

--- szap.c.orig	2004-07-30 08:02:44.000000000 +0200
+++ szap.c	2004-07-30 08:37:44.000000000 +0200
@@ -188,6 +188,20 @@
 }
 
 
+time_t time_ms (void)
+{
+  static time_t start = 0;
+  time_t t; 
+  struct timeval tv;
+  
+  gettimeofday (&tv, NULL);
+  t = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+  if (start == 0) {
+    start = t;
+  }
+  return t - start;
+}
+
 static
 int check_frontend (int fe_fd, int dvr)
 {
@@ -195,10 +209,31 @@
    uint16_t snr, signal;
    uint32_t ber, uncorrected_blocks;
    int timeout = 0;
+   struct pollfd pd;
+   int pr;
+   time_t last, now;
+   struct dvb_frontend_event event;
+   
+   pd.fd = fe_fd;
+   pd.events = POLLIN | POLLPRI;
+   last = time_ms ();
 
    do {
-      if (ioctl(fe_fd, FE_READ_STATUS, &status) == -1)
-         perror("FE_READ_STATUS failed");
+      pr =  poll (&pd, 1, 1000);
+      now = time_ms ();
+      if (pr == 1) {
+	if (ioctl (fe_fd, FE_GET_EVENT, &event) == 0)
+	  status = event.status;
+      } 
+      else {
+	if (pr == 0) {
+	  if (ioctl(fe_fd, FE_READ_STATUS, &status) == -1)
+	    perror("FE_READ_STATUS failed");
+	} 
+	else {
+	  perror("poll failed");
+	}
+      }
       /* some frontends might not support all these ioctls, thus we
        * avoid printing errors */
       if (ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal) == -1)
@@ -210,8 +245,9 @@
       if (ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks) == -1)
          uncorrected_blocks = -2;
 
-      printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
-	      status, signal, snr, ber, uncorrected_blocks);
+      printf ("%8ld ms: status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
+	      now - last, status, signal, snr, ber, uncorrected_blocks);
+      last = now;
 
       if (status & FE_HAS_LOCK)
 	 printf("FE_HAS_LOCK");
@@ -220,7 +256,6 @@
       if (exit_after_tuning && ((status & FE_HAS_LOCK) || (++timeout >= 10)))
          break;
 
-      usleep(1000000);
    } while (1);
 
    return 0;

Home | Main Index | Thread Index