提交 4b6ed9fd 编写于 作者: S Stefan Ringel 提交者: Mauro Carvalho Chehab

V4L/DVB: tm6000: bugfix video image

bugfix: Avoid loosing frames, causing image delays on some of the image lines.

[mchehab@redhat.com: Fix compilation breakage by merging with the patch fix]
Signed-off-by: NStefan Ringel <stefan.ringel@arcor.de>
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 3569417e
...@@ -339,14 +339,23 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp, ...@@ -339,14 +339,23 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
return rc; return rc;
} }
static int copy_streams(u8 *data, u8 *out_p, unsigned long len, static int copy_streams(u8 *data, unsigned long len,
struct urb *urb, struct tm6000_buffer **buf) struct urb *urb)
{ {
struct tm6000_dmaqueue *dma_q = urb->context; struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
u8 *ptr=data, *endp=data+len; u8 *ptr=data, *endp=data+len;
unsigned long header=0; unsigned long header=0;
int rc=0; int rc=0;
struct tm6000_buffer *buf;
char *outp = NULL;
get_next_buf(dma_q, &buf);
if (buf)
outp = videobuf_to_vmalloc(&buf->vb);
if (!outp)
return 0;
for (ptr=data; ptr<endp;) { for (ptr=data; ptr<endp;) {
if (!dev->isoc_ctl.cmd) { if (!dev->isoc_ctl.cmd) {
...@@ -394,14 +403,14 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len, ...@@ -394,14 +403,14 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len,
} }
HEADER: HEADER:
/* Copy or continue last copy */ /* Copy or continue last copy */
rc=copy_packet(urb,header,&ptr,endp,out_p,buf); rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
if (rc<0) { if (rc<0) {
buf=NULL; buf=NULL;
printk(KERN_ERR "tm6000: buffer underrun at %ld\n", printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
jiffies); jiffies);
return rc; return rc;
} }
if (!*buf) if (!buf)
return 0; return 0;
} }
...@@ -410,31 +419,40 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len, ...@@ -410,31 +419,40 @@ static int copy_streams(u8 *data, u8 *out_p, unsigned long len,
/* /*
* Identify the tm5600/6000 buffer header type and properly handles * Identify the tm5600/6000 buffer header type and properly handles
*/ */
static int copy_multiplexed(u8 *ptr, u8 *out_p, unsigned long len, static int copy_multiplexed(u8 *ptr, unsigned long len,
struct urb *urb, struct tm6000_buffer **buf) struct urb *urb)
{ {
struct tm6000_dmaqueue *dma_q = urb->context; struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
unsigned int pos=dev->isoc_ctl.pos,cpysize; unsigned int pos=dev->isoc_ctl.pos,cpysize;
int rc=1; int rc=1;
struct tm6000_buffer *buf;
char *outp = NULL;
get_next_buf(dma_q, &buf);
if (buf)
outp = videobuf_to_vmalloc(&buf->vb);
if (!outp)
return 0;
while (len>0) { while (len>0) {
cpysize=min(len,(*buf)->vb.size-pos); cpysize=min(len,buf->vb.size-pos);
//printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos); //printk("Copying %d bytes (max=%lu) from %p to %p[%u]\n",cpysize,(*buf)->vb.size,ptr,out_p,pos);
memcpy(&out_p[pos], ptr, cpysize); memcpy(&outp[pos], ptr, cpysize);
pos+=cpysize; pos+=cpysize;
ptr+=cpysize; ptr+=cpysize;
len-=cpysize; len-=cpysize;
if (pos >= (*buf)->vb.size) { if (pos >= buf->vb.size) {
pos=0; pos=0;
/* Announces that a new buffer were filled */ /* Announces that a new buffer were filled */
buffer_filled (dev, dma_q, *buf); buffer_filled (dev, dma_q, buf);
dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n"); dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n");
get_next_buf (dma_q, buf); get_next_buf (dma_q, &buf);
if (!*buf) if (!buf)
break; break;
out_p = videobuf_to_vmalloc(&((*buf)->vb)); outp = videobuf_to_vmalloc(&(buf->vb));
if (!out_p) if (!outp)
return rc; return rc;
pos = 0; pos = 0;
} }
...@@ -493,52 +511,36 @@ static inline int tm6000_isoc_copy(struct urb *urb) ...@@ -493,52 +511,36 @@ static inline int tm6000_isoc_copy(struct urb *urb)
struct tm6000_dmaqueue *dma_q = urb->context; struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq); struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
struct tm6000_buffer *buf; struct tm6000_buffer *buf;
int i, len=0, rc=1; int i, len=0, rc=1, status;
int size; char *p;
char *outp = NULL, *p;
unsigned long copied;
get_next_buf(dma_q, &buf);
if (buf)
outp = videobuf_to_vmalloc(&buf->vb);
if (!outp) if (urb->status < 0) {
return 0; print_err_status (dev, -1, urb->status);
size = buf->vb.size;
copied=0;
if (urb->status<0) {
print_err_status (dev,-1,urb->status);
return 0; return 0;
} }
for (i = 0; i < urb->number_of_packets; i++) { for (i = 0; i < urb->number_of_packets; i++) {
int status = urb->iso_frame_desc[i].status; status = urb->iso_frame_desc[i].status;
if (status<0) { if (status<0) {
print_err_status (dev,i,status); print_err_status (dev,i,status);
continue; continue;
} }
len=urb->iso_frame_desc[i].actual_length; len = urb->iso_frame_desc[i].actual_length;
// if (len>=TM6000_URB_MSG_LEN) { if (len > 0) {
p=urb->transfer_buffer + urb->iso_frame_desc[i].offset; p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
if (!urb->iso_frame_desc[i].status) { if (!urb->iso_frame_desc[i].status) {
if ((buf->fmt->fourcc)==V4L2_PIX_FMT_TM6000) { if ((dev->fourcc)==V4L2_PIX_FMT_TM6000) {
rc=copy_multiplexed(p, outp, len, urb, &buf); rc=copy_multiplexed(p, len, urb);
if (rc<=0) if (rc<=0)
return rc; return rc;
} else { } else {
copy_streams(p, outp, len, urb, &buf); copy_streams(p, len, urb);
}
} }
} }
copied += len;
if (copied >= size || !buf)
break;
// }
} }
return rc; return rc;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册