diff options
author | Johannes Stezenbach <js@linuxtv.org> | 2005-05-16 21:54:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-17 07:59:24 -0700 |
commit | 7635acd2d927578495c692056d0e7dabd06afc89 (patch) | |
tree | 308c33b31f2c749f12c4ddc9a44211a816e3125b /drivers/media/dvb/b2c2/flexcop-usb.c | |
parent | 2add87a95068d6457d4e5824d0417d39007665a4 (diff) | |
download | linux-next-7635acd2d927578495c692056d0e7dabd06afc89.tar.gz |
[PATCH] dvb: flexcop: fix USB transfer handling
- driver receives many null TS packets (pid=0x1fff). They occupy the
limited USB bandwidth and this leads to loss of video packets. Enabling the
null packet filter fixes this.
- packets that flexcop sends to USB have a 2 byte header that has to be
removed.
- sometimes a TS packet is split between different urbs. These parts have
to be combined in a temporary buffer.
Signed-off-by: Vadim Catana <skystar@moldova.cc>
Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/dvb/b2c2/flexcop-usb.c')
-rw-r--r-- | drivers/media/dvb/b2c2/flexcop-usb.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 5fa68febf3a6..98470ce9a054 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c @@ -282,6 +282,51 @@ static int flexcop_usb_i2c_request(struct flexcop_device *fc, flexcop_access_op_ return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len); } +static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length) +{ + u8 *b; + int l; + + deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length); + + if (fc_usb->tmp_buffer_length > 0) { + memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length); + fc_usb->tmp_buffer_length += buffer_length; + b = fc_usb->tmp_buffer; + l = fc_usb->tmp_buffer_length; + } else { + b=buffer; + l=buffer_length; + } + + while (l >= 190) { + if (*b == 0xff) + switch (*(b+1) & 0x03) { + case 0x01: /* media packet */ + if ( *(b+2) == 0x47 ) + flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1); + else + deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) ); + + b += 190; + l -= 190; + break; + default: + deb_ts("wrong packet type\n"); + l = 0; + break; + } + else { + deb_ts("wrong header\n"); + l = 0; + } + } + + if (l>0) + memcpy(fc_usb->tmp_buffer, b, l); + fc_usb->tmp_buffer_length = l; +} + static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) { struct flexcop_usb *fc_usb = urb->context; @@ -297,7 +342,7 @@ static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) if (urb->iso_frame_desc[i].actual_length > 0) { deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length); - flexcop_pass_dmx_data(fc_usb->fc_dev, + flexcop_usb_process_frame(fc_usb, urb->transfer_buffer + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); } |