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