[media] ngene: Strip dummy packets inserted by the driver
authorOliver Endriss <o.endriss@gmx.de>
Sun, 3 Jul 2011 17:04:46 +0000 (14:04 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 27 Jul 2011 20:55:44 +0000 (17:55 -0300)
As the CI requires a continuous data stream, the driver inserts dummy
packets when necessary. Do not pass these packets to userspace anymore.

Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/ngene/ngene-core.c
drivers/media/dvb/ngene/ngene-dvb.c
drivers/media/dvb/ngene/ngene.h

index df0f0bd00c07eda90abbbc1f12557b8d171416d7..f129a9303f80a364f0956fb17033169f8a11a659 100644 (file)
@@ -507,7 +507,7 @@ void FillTSBuffer(void *Buffer, int Length, u32 Flags)
 {
        u32 *ptr = Buffer;
 
-       memset(Buffer, 0xff, Length);
+       memset(Buffer, TS_FILLER, Length);
        while (Length > 0) {
                if (Flags & DF_SWAP32)
                        *ptr = 0x471FFF10;
index ba209cb3e0b178637baf6649f049d78f2930bfdd..fcb16a615aab002768f80b3e7d6c5cf66ac5f123 100644 (file)
@@ -118,6 +118,16 @@ static void swap_buffer(u32 *p, u32 len)
        }
 }
 
+/* start of filler packet */
+static u8 fill_ts[] = { 0x47, 0x1f, 0xff, 0x10, TS_FILLER };
+
+/* #define DEBUG_CI_XFER */
+#ifdef DEBUG_CI_XFER
+static u32 ok;
+static u32 overflow;
+static u32 stripped;
+#endif
+
 void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
 {
        struct ngene_channel *chan = priv;
@@ -126,21 +136,41 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
 
        if (flags & DF_SWAP32)
                swap_buffer(buf, len);
+
        if (dev->ci.en && chan->number == 2) {
-               if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
-                       dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len);
-                       wake_up_interruptible(&dev->tsin_rbuf.queue);
+               while (len >= 188) {
+                       if (memcmp(buf, fill_ts, sizeof fill_ts) != 0) {
+                               if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) {
+                                       dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188);
+                                       wake_up(&dev->tsin_rbuf.queue);
+#ifdef DEBUG_CI_XFER
+                                       ok++;
+#endif
+                               }
+#ifdef DEBUG_CI_XFER
+                               else
+                                       overflow++;
+#endif
+                       }
+#ifdef DEBUG_CI_XFER
+                       else
+                               stripped++;
+
+                       if (ok % 100 == 0 && overflow)
+                               printk(KERN_WARNING "%s: ok %u overflow %u dropped %u\n", __func__, ok, overflow, stripped);
+#endif
+                       buf += 188;
+                       len -= 188;
                }
-               return 0;
+               return NULL;
        }
+
        if (chan->users > 0)
                dvb_dmx_swfilter(&chan->demux, buf, len);
 
        return NULL;
 }
 
-u8 fill_ts[188] = { 0x47, 0x1f, 0xff, 0x10 };
-
 void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
 {
        struct ngene_channel *chan = priv;
index 90fa136850c4fc786cc4ea444cf8710ce0a535fe..5443dc0caea50e2067a68c5df66d6563d79f7f58 100644 (file)
@@ -789,6 +789,8 @@ struct ngene {
        u8                    uart_rbuf[UART_RBUF_LEN];
        int                   uart_rp, uart_wp;
 
+#define TS_FILLER  0x6f
+
        u8                   *tsout_buf;
 #define TSOUT_BUF_SIZE (512*188*8)
        struct dvb_ringbuffer tsout_rbuf;