Mailing List archive

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

[linux-dvb] Re: [PATCH] fix for stream corruption on budget /Nova-T cards



Dr. Werner Fink wrote:


Btw: Could it be that with this patch (DVB-fix3.patch) the TS frames
are doubled now[1]?
The driver could be picking up stale data from the previous buffer fill.
My experiments seem to indicate that on my cards the DMA pointer always fills the buffer completely before wrapping back to zero.

It has been suggested by others on the list that this is not the expected behaviour. Apparently it is expected that some hardware on the card will flip the frame sync signal after a certain number of packets have been received (so the buffer should never fill completely).

You could try the patch attached. It is entirely experimental, I did it just to try understand and debug the low level budget DMA code. It does a couple of things:
- Adds a couple of printk()'s saying where the DMA pointer got to on each IRQ. This spews _lots_ of debug, so you'd better stop syslog before trying it.

Here is some example output:
JB: wrap olddma 0x50004 - end (305 pkts), start - newdma 0x0000 (0 pkts)
JB: normal olddma 0x0000 - newdma 0xff90 (0xff90, 348 pkts)
JB: normal olddma 0xff90 - newdma 0x1ffdc (0x1004c, 349 pkts)
JB: normal olddma 0x1ffdc - newdma 0x2ff6c (0xff90, 348 pkts)
JB: normal olddma 0x2ff6c - newdma 0x3ffb8 (0x1004c, 349 pkts)
JB: normal olddma 0x3ffb8 - newdma 0x50004 (0x1004c, 349 pkts)
JB: wrap olddma 0x50004 - end (305 pkts), start - newdma 0x0000 (0 pkts)
JB: normal olddma 0x0000 - newdma 0xff90 (0xff90, 348 pkts)
JB: normal olddma 0xff90 - newdma 0x1ffdc (0x1004c, 349 pkts)
JB: normal olddma 0x1ffdc - newdma 0x2ff6c (0xff90, 348 pkts)
JB: normal olddma 0x2ff6c - newdma 0x3ffb8 (0x1004c, 349 pkts)
JB: normal olddma 0x3ffb8 - newdma 0x4ff48 (0xff90, 348 pkts)
JB: wrap olddma 0x4ff48 - end (306 pkts), start - newdma 0x0000 (0 pkts)
JB: normal olddma 0x0000 - newdma 0xff90 (0xff90, 348 pkts)
JB: normal olddma 0xff90 - newdma 0x1ffdc (0x1004c, 349 pkts)
JB: normal olddma 0x1ffdc - newdma 0x2ff6c (0xff90, 348 pkts)
JB: normal olddma 0x2ff6c - newdma 0x3ffb8 (0x1004c, 349 pkts)
JB: normal olddma 0x3ffb8 - newdma 0x4ff48 (0xff90, 348 pkts)

This says to me that the DMA always fills the buffer before starting again at the beginning. There doesn't seem to be any evidence of it automatically switching on a frame sync signal. Perhaps this hardware was only on older cards or needs a specific enable?


- Moves the check for valid PES frames from the vpeirq() to the demux code. This looks like a valid fix which might be worth applying to the driver. It catches some cases where there are some non-PES packets along with the data. This is shown by the occasional "Bad Packet" message being generated. This frequently occurs when changing channels, and occasionally during normal reception (even with no 'unc' errors from the frontend). Perhaps there is some padding or other data?

- Adds a hackish overwrite of the data when it reads it, to try to make sure it doesn't pick up stale data from the buffer. It is hackish because it shouldn't be writing to the "const char *buffer", which causes the compiler to generate a warning.

- It doubles the size of the DMA buffer (just in case it needed a few more packets before it decided to flip the buffer). It looked like the previous values were tuned to some magic numbers. Doesn't seem to have any positive or negative effect.

Jon


diff -Nurw dvb-kernel-cvs/linux/drivers/media/dvb/dvb-core/dvb_demux.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c
--- dvb-kernel-cvs/linux/drivers/media/dvb/dvb-core/dvb_demux.c	2003-09-11 17:35:55.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_demux.c	2003-09-11 19:48:20.000000000 +0100
@@ -393,7 +393,12 @@
 	spin_lock(&demux->lock);
 
 	while (count--) {
+                if (buf[0] == 0x47) {
 		dvb_dmx_swfilter_packet(demux, buf);
+		} else {
+                	printk("JB: Bad packet at 0x%04x\n", buf);
+  		}
+                buf[0] = 0x00;
 		buf += 188;
 	}
 
diff -Nurw dvb-kernel-cvs/linux/drivers/media/dvb/ttpci/budget-core.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c
--- dvb-kernel-cvs/linux/drivers/media/dvb/ttpci/budget-core.c	2003-09-06 13:05:25.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c	2003-09-11 20:07:53.000000000 +0100
@@ -80,16 +80,35 @@
 		return;
 
         if (newdma > olddma) { /* no wraparound, dump olddma..newdma */
+		printk("JB: normal olddma 0x%04x - newdma 0x%04x (0x%04x, %d pkts)\n",
+                	olddma, newdma, newdma-olddma , (newdma-olddma) / 188);
                	if(mem[olddma] == 0x47)
                         dvb_dmx_swfilter_packets(&budget->demux, 
         	                mem+olddma, (newdma-olddma) / 188);
+                else {
+                	printk("JB: Bad packet1 at 0x%04x\n", mem);
+		}
+                         
         } else { /* wraparound, dump olddma..buflen and 0..newdma */
+                //if ((TS_BUFLEN-olddma) / 188 != 327) {
+		  printk("JB: wrap olddma 0x%04x - end (%d pkts), start - newdma 0x%04x (%d pkts)\n",
+                	olddma, (TS_BUFLEN-olddma) / 188,
+                 	newdma, newdma / 188);
+                //}
                 if(mem[olddma] == 0x47)
 	                dvb_dmx_swfilter_packets(&budget->demux,
         	                mem+olddma, (TS_BUFLEN-olddma) / 188);
+                else {
+                	printk("JB: Bad packet2 at 0x%04x\n", mem);
+		}
+
                 if(mem[0] == 0x47)
                         dvb_dmx_swfilter_packets(&budget->demux,
                                 mem, newdma / 188);
+                else {
+                	printk("JB: Bad packet3 at 0x%04x\n", mem);
+		}
+                                
         }
 }
 
diff -Nurw dvb-kernel-cvs/linux/drivers/media/dvb/ttpci/budget.h dvb-kernel/linux/drivers/media/dvb/ttpci/budget.h
--- dvb-kernel-cvs/linux/drivers/media/dvb/ttpci/budget.h	2003-06-07 12:53:59.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget.h	2003-09-11 20:14:24.000000000 +0100
@@ -65,7 +65,8 @@
 	.ext = &budget_extension };
 
 #define TS_WIDTH  (4*188)
-#define TS_HEIGHT (1024/4)
+//JB was: #define TS_HEIGHT (1024/4)
+#define TS_HEIGHT (1024/2)
 #define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
 #define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE)
 

Home | Main Index | Thread Index