diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-01-09 19:12:39 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-01-09 19:12:39 -0200 |
commit | 9c6ab876f808fd366f2946fe99e4d41019e41884 (patch) | |
tree | 05740bb6eeb7df57f7a31f612852853732fd3dc6 /linux/drivers/staging | |
parent | 6e36bcd7dca87490799165821dd3f00233fcf86a (diff) | |
download | mediapointer-dvb-s2-9c6ab876f808fd366f2946fe99e4d41019e41884.tar.gz mediapointer-dvb-s2-9c6ab876f808fd366f2946fe99e4d41019e41884.tar.bz2 |
tm6000: fix image hangs
From: Mauro Carvalho Chehab <mchehab@redhat.com>
A previous committed patch hanged image output. This patch corrects this issue.
It also warrants that buffer is updated for each frame0+frame1 frame set.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/staging')
-rw-r--r-- | linux/drivers/staging/tm6000/tm6000-cards.c | 2 | ||||
-rw-r--r-- | linux/drivers/staging/tm6000/tm6000-usb-isoc.h | 4 | ||||
-rw-r--r-- | linux/drivers/staging/tm6000/tm6000-video.c | 84 |
3 files changed, 42 insertions, 48 deletions
diff --git a/linux/drivers/staging/tm6000/tm6000-cards.c b/linux/drivers/staging/tm6000/tm6000-cards.c index d2ebcd6d7..d1fbaaa3d 100644 --- a/linux/drivers/staging/tm6000/tm6000-cards.c +++ b/linux/drivers/staging/tm6000/tm6000-cards.c @@ -435,6 +435,7 @@ static int tm6000_usb_probe(struct usb_interface *interface, } } +#if 0 if (interface->altsetting->desc.bAlternateSetting) { printk("selecting alt setting %d\n", interface->altsetting->desc.bAlternateSetting); @@ -444,6 +445,7 @@ static int tm6000_usb_probe(struct usb_interface *interface, if (rc<0) goto err; } +#endif printk("tm6000: New video device @ %s Mbps (%04x:%04x, ifnum %d)\n", speed, diff --git a/linux/drivers/staging/tm6000/tm6000-usb-isoc.h b/linux/drivers/staging/tm6000/tm6000-usb-isoc.h index 5dc8d4250..79a92168a 100644 --- a/linux/drivers/staging/tm6000/tm6000-usb-isoc.h +++ b/linux/drivers/staging/tm6000/tm6000-usb-isoc.h @@ -51,4 +51,8 @@ struct usb_isoc_ctl { /* Stores the number of received fields */ int nfields; + + /* Checks if a complete field were received */ + int last_line; + unsigned int fields:2; }; diff --git a/linux/drivers/staging/tm6000/tm6000-video.c b/linux/drivers/staging/tm6000/tm6000-video.c index 780cf9ee0..9d6618005 100644 --- a/linux/drivers/staging/tm6000/tm6000-video.c +++ b/linux/drivers/staging/tm6000/tm6000-video.c @@ -262,6 +262,22 @@ static int copy_packet (struct urb *urb, u32 header, u8 **ptr, u8 *endp, " line=%d, field=%d\n", size, block, line, field); + /* Checks if a complete set of frame0 + frame 1 were received */ + if (dev->isoc_ctl.last_line > line) { + if (dev->isoc_ctl.fields == 3) { + /* Announces that a new buffer were filled */ + buffer_filled(dev, dma_q, *buf); + dprintk(dev, V4L2_DEBUG_ISOC, + "new buffer filled\n"); + rc = get_next_buf(dma_q, buf); + + dev->isoc_ctl.fields = 0; + } else { + dev->isoc_ctl.fields |= 1 << field; + } + } + dev->isoc_ctl.last_line = line; + if ((last_line!=line)&&(last_line+1!=line) && (cmd != TM6000_URB_MSG_ERR) ) { if (cmd != TM6000_URB_MSG_VIDEO) { @@ -282,12 +298,6 @@ static int copy_packet (struct urb *urb, u32 header, u8 **ptr, u8 *endp, dev->isoc_ctl.nfields++; if (dev->isoc_ctl.nfields>=2) { dev->isoc_ctl.nfields=0; - - /* Announces that a new buffer were filled */ - buffer_filled (dev, dma_q, *buf); - dprintk(dev, V4L2_DEBUG_ISOC, - "new buffer filled\n"); - rc=get_next_buf (dma_q, buf); } } @@ -650,11 +660,17 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, int max_packets, int num_bufs) { struct tm6000_dmaqueue *dma_q = &dev->vidq; - int i; + int i, rc; int sb_size, pipe; struct urb *urb; int j, k; + dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %dx%d packets" + " of %d bytes each to handle %u size\n", + max_packets, num_bufs, + dev->max_isoc_in, dev->isoc_ctl.max_pkt_size); + + /* De-allocates all pending stuff */ tm6000_uninit_isoc(dev); @@ -708,6 +724,17 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, } memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); +#if 0 + /* Selects the selected interface/alternate setting */ + dprintk(dev, V4L2_DEBUG_ISOC, + "Selecting if 0, alt 1, interval %d\n", + dev->isoc_in->desc.bInterval); + + rc = usb_set_interface(dev->udev, 0, 1); + if (rc < 0) + return rc; +#endif + pipe=usb_rcvisocpipe(dev->udev, dev->isoc_in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); @@ -886,7 +913,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, struct tm6000_fh *fh = vq->priv_data; struct tm6000_buffer *buf = container_of(vb,struct tm6000_buffer,vb); struct tm6000_core *dev = fh->dev; - int rc=0, urbsize, urb_init=0, npackets=1; + int rc = 0, urb_init = 0; BUG_ON(NULL == fh->fmt); @@ -925,50 +952,11 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, urb_init=1; } - if (!dev->isoc_ctl.num_bufs) urb_init=1; if (urb_init) { - /* memory for video - Should be at least - Vres x Vres x 2 bytes/pixel by frame */ - urbsize=buf->vb.size; - - /* Need also one PTS */ - urbsize+=180; - - /* memory for audio - Should be at least - bitrate * 2 channels * 2 bytes / frame rate */ - if (dev->norm & V4L2_STD_525_60) { - urbsize+=(dev->audio_bitrate*4+29)/30; - } else { - urbsize+=(dev->audio_bitrate*4+24)/25; - } - - /* each audio frame seeems to have a frame number - with 2 bytes */ - urbsize+=2; - - /* Add 4 bytes by each 180 bytes frame */ - urbsize+=((urbsize+179)/180)*4; - - /* Round to an enough number of URBs */ - urbsize=(urbsize+dev->max_isoc_in-1)/dev->max_isoc_in; - - /* Avoids allocating big memory areas for URB */ - while ((urbsize*dev->max_isoc_in)/npackets>65535) { - npackets++; - } - urbsize/=(urbsize+npackets-1)/npackets; - - dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %dx%d packets" - " of %d bytes each to handle %lu size\n", - npackets,urbsize,dev->max_isoc_in,buf->vb.size); - - rc = tm6000_prepare_isoc(dev, urbsize, npackets); - + rc = tm6000_prepare_isoc(dev, 128, 1); if (rc<0) goto fail; } |