Mailing List archive

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

[linux-dvb] Re: Possible bug in dvb_frontend.c [Was: "Video datastreambrocken" - 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.
> 

Up to now I thought this is a matter of VDR, but further tests showed
that this spurious event is really generated.

I patched dvb_frontend.c to get some more debug output and get the
following in my syslog if VDR tries to tune from a locked channel
to an invalid channel:

Aug  1 12:22:17 vdr vdr[1606]: SetChannelDevice: channel 0, LiveView=0
Aug  1 12:22:17 vdr kernel: dvb_frontend_ioctl: FE_SET_FRONTEND
Aug  1 12:22:17 vdr kernel: dvb_frontend_add_event: status 00
Aug  1 12:22:17 vdr kernel: dvb_frontend_thread (state=0002): adding event 1f
Aug  1 12:22:17 vdr kernel: dvb_frontend_add_event: status 1f
Aug  1 12:22:17 vdr vdr[1632]: Event on frontend 1 (channel ""): 00 dt =   21221 ms
Aug  1 12:22:17 vdr vdr[1632]: Event on frontend 1 (channel ""): 1f dt =       0 ms
Aug  1 12:22:17 vdr vdr[1632]: Frontend 1 (channel "") first lock
Aug  1 12:22:17 vdr kernel: dvb_frontend_get_event: status 00
Aug  1 12:22:17 vdr kernel: dvb_frontend_get_event: status 1f
Aug  1 12:22:18 vdr vdr[1632]: Event on frontend 1 (channel ""): 01 dt =     100 ms
Aug  1 12:22:18 vdr kernel: dvb_frontend_thread (state=0004): adding event 01
Aug  1 12:22:18 vdr kernel: dvb_frontend_add_event: status 01
Aug  1 12:22:18 vdr kernel: dvb_frontend_get_event: status 01
Aug  1 12:22:20 vdr vdr[1632]: Event on frontend 1 (channel ""): 03 dt =    2700 ms

What I find strange is that dvb_frontend_thread adds an FE event while it is in FSM state
FESTATE_RETUNE. If I understand the code correctly, nothing has happened to the hardware up to now
and the thus the FE state reflects the last state of the previous tuning. This does not make sense
to me. I attach a patch that resets the FE state to 0 and does not add an event if the FSM is in
state FESTATE_RETUNE. It removes the "spike" and otherwise seems to work as before.

dvb_frontend_debug.diff: Patch with additional debug printks
dvb_frontend.diff      : Patch without debug printks

Please comment.

Wolfgang
> 
>>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?)
> 
> 
> Johannes
> 
> 


--- dvb_frontend.orig.c	2004-08-01 12:32:44.000000000 +0200
+++ dvb_frontend.debug.c	2004-08-01 13:15:01.000000000 +0200
@@ -77,6 +77,7 @@
 static int do_frequency_bending = 0;
 
 #define dprintk if (dvb_frontend_debug) printk
+#define xdprintk printk
 
 #define MAX_EVENT 8
 
@@ -255,7 +256,7 @@
 	struct dvb_frontend_event *e;
 	int wp;
 
-	dprintk ("%s\n", __FUNCTION__);
+	xdprintk ("%s: status %02x\n", __FUNCTION__, status);
 
 	if (down_interruptible (&events->sem))
 		return;
@@ -322,7 +323,7 @@
 
 	memcpy (event, &events->events[events->eventr],
 		sizeof(struct dvb_frontend_event));
-
+	xdprintk ("%s: status %02x\n", __FUNCTION__, event->status);
 	events->eventr = (events->eventr + 1) % MAX_EVENT;
 
 	up (&events->sem);
@@ -520,10 +521,15 @@
 		}
 	    
 		// get the frontend status
-		dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s);
-		if (s != fe->status)
-			dvb_frontend_add_event (fe, s);
-
+		if (fe->state & FESTATE_RETUNE) {
+			s = 0;
+		} else {
+			dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s);
+			if (s != fe->status) {
+				xdprintk ("%s (state=%04x): adding event %02x\n", __FUNCTION__, fe->state, s); 
+				dvb_frontend_add_event (fe, s);
+			}
+		}
 		// if we're not tuned, and we have a lock, move to the TUNED state
 		if ((fe->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
 			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);
@@ -741,6 +747,7 @@
 		break;
 
 	case FE_SET_FRONTEND:
+	        xdprintk ("%s: FE_SET_FRONTEND\n", __FUNCTION__);
 		fe->state = FESTATE_RETUNE;
 	    
 		memcpy (&fe->parameters, parg,
--- dvb_frontend.orig.c	2004-08-01 12:32:44.000000000 +0200
+++ dvb_frontend.c	2004-08-01 13:13:27.000000000 +0200
@@ -520,10 +520,14 @@
 		}
 	    
 		// get the frontend status
-		dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s);
-		if (s != fe->status)
-			dvb_frontend_add_event (fe, s);
-
+		if (fe->state & FESTATE_RETUNE) {
+			s = 0;
+		} else {
+			dvb_frontend_internal_ioctl (&fe->frontend, FE_READ_STATUS, &s);
+			if (s != fe->status) {
+				dvb_frontend_add_event (fe, s);
+			}
+		}
 		// if we're not tuned, and we have a lock, move to the TUNED state
 		if ((fe->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) {
 			update_delay(&quality, &delay, fe->min_delay, s & FE_HAS_LOCK);

Home | Main Index | Thread Index