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;