Re: [PATCH] tm6000: rewrite copy_streams

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, May 28, 2010 at 08:03:40PM +0200, stefan.ringel@xxxxxxxx wrote:
> From: Stefan Ringel <stefan.ringel@xxxxxxxx>
> 
> fusion function copy streams and copy_packets to new function copy_streams.
> 
> Signed-off-by: Stefan Ringel <stefan.ringel@xxxxxxxx>
> ---
>  drivers/staging/tm6000/tm6000-usb-isoc.h |    5 +-
>  drivers/staging/tm6000/tm6000-video.c    |  329 +++++++++++-------------------
>  2 files changed, 119 insertions(+), 215 deletions(-)
> 
> diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h
> index 5a5049a..138716a 100644
> --- a/drivers/staging/tm6000/tm6000-usb-isoc.h
> +++ b/drivers/staging/tm6000/tm6000-usb-isoc.h
> @@ -39,7 +39,7 @@ struct usb_isoc_ctl {
>  	int				pos, size, pktsize;
>  
>  		/* Last field: ODD or EVEN? */
> -	int				field;
> +	int				vfield;
>  
>  		/* Stores incomplete commands */
>  	u32				tmp_buf;
> @@ -47,7 +47,4 @@ struct usb_isoc_ctl {
>  
>  		/* Stores already requested buffers */
>  	struct tm6000_buffer    	*buf;
> -
> -		/* Stores the number of received fields */
> -	int				nfields;
>  };
> diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
> index 2a61cc3..058c6e9 100644
> --- a/drivers/staging/tm6000/tm6000-video.c
> +++ b/drivers/staging/tm6000/tm6000-video.c
> @@ -186,234 +186,145 @@ const char *tm6000_msg_type[] = {
>  /*
>   * Identify the tm5600/6000 buffer header type and properly handles
>   */
> -static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
> -			u8 *out_p, struct tm6000_buffer **buf)
> -{
> -	struct tm6000_dmaqueue  *dma_q = urb->context;
> -	struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
> -	u8 c;
> -	unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
> -	int rc = 0;
> -	/* FIXME: move to tm6000-isoc */
> -	static int last_line = -2, start_line = -2, last_field = -2;
> -
> -	/* FIXME: this is the hardcoded window size
> -	 */
> -	unsigned int linewidth = (*buf)->vb.width << 1;
> -
> -	if (!dev->isoc_ctl.cmd) {
> -		c = (header >> 24) & 0xff;
> -
> -		/* split the header fields */
> -		size  = ((header & 0x7e) << 1);
> -
> -		if (size > 0)
> -			size -= 4;
> -
> -		block = (header >> 7) & 0xf;
> -		field = (header >> 11) & 0x1;
> -		line  = (header >> 12) & 0x1ff;
> -		cmd   = (header >> 21) & 0x7;
> -
> -		/* Validates header fields */
> -		if(size > TM6000_URB_MSG_LEN)
> -			size = TM6000_URB_MSG_LEN;
> -
> -		if (cmd == TM6000_URB_MSG_VIDEO) {
> -			if ((block+1)*TM6000_URB_MSG_LEN>linewidth)
> -				cmd = TM6000_URB_MSG_ERR;
> -
> -			/* FIXME: Mounts the image as field0+field1
> -			 * It should, instead, check if the user selected
> -			 * entrelaced or non-entrelaced mode
> -			 */
> -			pos= ((line<<1)+field)*linewidth +
> -				block*TM6000_URB_MSG_LEN;
> -
> -			/* Don't allow to write out of the buffer */
> -			if (pos+TM6000_URB_MSG_LEN > (*buf)->vb.size) {
> -				dprintk(dev, V4L2_DEBUG_ISOC,
> -					"ERR: size=%d, num=%d, line=%d, "
> -					"field=%d\n",
> -					size, block, line, field);
> -
> -				cmd = TM6000_URB_MSG_ERR;
> -			}
> -		} else {
> -			pos=0;
> -		}
> -
> -		/* Prints debug info */
> -		dprintk(dev, V4L2_DEBUG_ISOC, "size=%d, num=%d, "
> -				" line=%d, field=%d\n",
> -				size, block, line, field);
> -
> -		if ((last_line!=line)&&(last_line+1!=line) &&
> -		    (cmd != TM6000_URB_MSG_ERR) )  {
> -			if (cmd != TM6000_URB_MSG_VIDEO)  {
> -				dprintk(dev, V4L2_DEBUG_ISOC,  "cmd=%d, "
> -					"size=%d, num=%d, line=%d, field=%d\n",
> -					cmd, size, block, line, field);
> -			}
> -			if (start_line<0)
> -				start_line=last_line;
> -			/* Prints debug info */
> -			dprintk(dev, V4L2_DEBUG_ISOC, "lines= %d-%d, "
> -					"field=%d\n",
> -					start_line, last_line, field);
> -
> -			if ((start_line<6 && last_line>200) &&
> -				(last_field != field) ) {
> -
> -				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");
> -					get_next_buf (dma_q, buf);
> -					if (!*buf)
> -						return rc;
> -					out_p = videobuf_to_vmalloc(&((*buf)->vb));
> -					if (!out_p)
> -						return rc;
> -
> -					pos = dev->isoc_ctl.pos = 0;
> -				}
> -			}
> -
> -			start_line=line;
> -			last_field=field;
> -		}
> -		if (cmd == TM6000_URB_MSG_VIDEO)
> -			last_line = line;
> -
> -		pktsize = TM6000_URB_MSG_LEN;
> -	} else {
> -		/* Continue the last copy */
> -		cmd = dev->isoc_ctl.cmd;
> -		size= dev->isoc_ctl.size;
> -		pos = dev->isoc_ctl.pos;
> -		pktsize = dev->isoc_ctl.pktsize;
> -	}
> -
> -	cpysize = (endp-(*ptr) > size) ? size : endp - *ptr;
> -
> -	if (cpysize) {
> -		/* handles each different URB message */
> -		switch(cmd) {
> -		case TM6000_URB_MSG_VIDEO:
> -			/* Fills video buffer */
> -			memcpy(&out_p[pos], *ptr, cpysize);
> -			break;
> -		case TM6000_URB_MSG_PTS:
> -			break;
> -		case TM6000_URB_MSG_AUDIO:
> -			/* Need some code to process audio */
> -			printk ("%ld: cmd=%s, size=%d\n", jiffies,
> -				tm6000_msg_type[cmd],size);
> -			break;
> -		case TM6000_URB_MSG_VBI:
> -			break;
> -		default:
> -			dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
> -						tm6000_msg_type[cmd],size);
> -		}
> -	}
> -	if (cpysize<size) {
> -		/* End of URB packet, but cmd processing is not
> -		 * complete. Preserve the state for a next packet
> -		 */
> -		dev->isoc_ctl.pos = pos+cpysize;
> -		dev->isoc_ctl.size= size-cpysize;
> -		dev->isoc_ctl.cmd = cmd;
> -		dev->isoc_ctl.pktsize = pktsize-cpysize;
> -		(*ptr)+=cpysize;
> -	} else {
> -		dev->isoc_ctl.cmd = 0;
> -		(*ptr)+=pktsize;
> -	}
> -
> -	return rc;
> -}
> -
>  static int copy_streams(u8 *data, unsigned long len,
>  			struct urb *urb)
>  {
>  	struct tm6000_dmaqueue  *dma_q = urb->context;
>  	struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
> -	u8 *ptr=data, *endp=data+len;
> +	u8 *ptr=data, *endp=data+len, c;
>  	unsigned long header=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);
> +	unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
> +	struct tm6000_buffer *vbuf;
> +	char *voutp = NULL;
> +	unsigned int linewidth;
>  
> -	if (!outp)
> +	/* get video buffer */
> +	get_next_buf (dma_q, &vbuf);
> +	if (!vbuf)
> +		return rc;
> +	voutp = videobuf_to_vmalloc(&vbuf->vb);
> +	if (!voutp)
>  		return 0;
>  
> -	for (ptr=data; ptr<endp;) {
> +	for (ptr = data; ptr < endp;) {
>  		if (!dev->isoc_ctl.cmd) {
> -			u8 *p=(u8 *)&dev->isoc_ctl.tmp_buf;
> -			/* FIXME: This seems very complex
> -			 * It just recovers up to 3 bytes of the header that
> -			 * might be at the previous packet
> -			 */
> -			if (dev->isoc_ctl.tmp_buf_len) {
> -				while (dev->isoc_ctl.tmp_buf_len) {
> -					if ( *(ptr+3-dev->isoc_ctl.tmp_buf_len) == 0x47) {
> -						break;
> -					}
> -					p++;
> -					dev->isoc_ctl.tmp_buf_len--;
> -				}
> -				if (dev->isoc_ctl.tmp_buf_len) {
> -					memcpy(&header, p,
> -						dev->isoc_ctl.tmp_buf_len);
> -					memcpy((u8 *)&header +
> +			/* Header */
> +			if (dev->isoc_ctl.tmp_buf_len > 0) {
> +				/* from last urb or packet */
> +				header = dev->isoc_ctl.tmp_buf;
> +				if (4 - dev->isoc_ctl.tmp_buf_len > 0)
> +					memcpy ((u8 *)&header +
>  						dev->isoc_ctl.tmp_buf_len,
>  						ptr,
>  						4 - dev->isoc_ctl.tmp_buf_len);
>  					ptr += 4 - dev->isoc_ctl.tmp_buf_len;
> -					goto HEADER;
>  				}

This brace has to be removed.
-  				}

> +				dev->isoc_ctl.tmp_buf_len = 0;
> +			} else {
> +				if (ptr + 3 >= endp) {
> +					/* have incomplete header */
> +					dev->isoc_ctl.tmp_buf_len = endp - ptr;
> +					memcpy (&dev->isoc_ctl.tmp_buf, ptr,
> +						dev->isoc_ctl.tmp_buf_len);
> +					return rc;
> +				}
> +				/* Seek for sync */
> +				for (; ptr < endp - 3; ptr++) {
> +					if (*(ptr + 3) == 0x47)
> +						break;
> +				}
> +				/* Get message header */
> +				header = *(unsigned long *)ptr;
> +				ptr += 4;
>  			}
> -			/* Seek for sync */
> -			for (;ptr<endp-3;ptr++) {
> -				if (*(ptr+3)==0x47)
> -					break;
> +			/* split the header fields */
> +			c = (header >> 24) & 0xff;
> +			size = ((header & 0x7e) << 1);
> +			if (size > 0)
> +				size -= 4;
> +			block = (header >> 7) & 0xf;
> +			field = (header >> 11) & 0x1;
> +			line  = (header >> 12) & 0x1ff;
> +			cmd   = (header >> 21) & 0x7;
> +			/* Validates haeder fields */
> +			if (size > TM6000_URB_MSG_LEN)
> +				size = TM6000_URB_MSG_LEN;
> +			pktsize = TM6000_URB_MSG_LEN;
> +			/* calculate position in buffer 
> +			 * and change the buffer
> +			 */
> +			switch (cmd) {
> +			case TM6000_URB_MSG_VIDEO:
> +				if ((dev->isoc_ctl.vfield != field) && 
> +					(field == 1) {

Missing closing parenthesis.
+					(field == 1)) {

> +					/* Announces that a new buffer 
> +					 * were filled 
> +					 */
> +					buffer_filled (dev, dma_q, vbuf);
> +					dprintk (dev, V4L2_DEBUG_ISOC,
> +							"new buffer filled\n");
> +					get_next_buf (dma_q, &vbuf);
> +					if (!vbuf)
> +						return rc;
> +					voutp = videobuf_to_vmalloc (&vbuf->vb);
> +					if (!voutp)
> +						return rc;
> +				}
> +				linewidth = vbuf->vb.width << 1;
> +				pos = ((line << 1) - field - 1) * linewidth +
> +					block * TM6000_URB_MSG_LEN;
> +				/* Don't allow to write out of the buffer */
> +				if (pos + size > vbuf->vb.size)
> +					cmd = TM6000_URB_MSG_ERR;
> +				dev->isoc_ctl.vfield = field;
> +				break;
> +			case TM6000_URB_MSG_AUDIO:
> +			case TM6000_URB_MSG_VBI:
> +			case TM6000_URB_MSG_PTS:
> +				break;
>  			}
> -
> -			if (ptr+3>=endp) {
> -				dev->isoc_ctl.tmp_buf_len=endp-ptr;
> -				memcpy (&dev->isoc_ctl.tmp_buf,ptr,
> -					dev->isoc_ctl.tmp_buf_len);
> -				dev->isoc_ctl.cmd=0;
> -				return rc;
> +		} else {
> +			/* Continue the last copy */
> +			cmd = dev->isoc_ctl.cmd;
> +			size = dev->isoc_ctl.size;
> +			pos = dev->isoc_ctl.pos;
> +			pktsize = dev->isoc_ctl-pktsize;

A typo: the dash has to be a dot.
+			pktsize = dev->isoc_ctl.pktsize;

> +		}
> +		cpysize = (endp - ptr > size) ? size : endp - ptr;
> +		if (cpysize) {
> +			/* copy data in different buffers */
> +			switch (cmd) {
> +			case TM6000_URB_MSG_VIDEO:
> +				/* Fills video buffer */
> +				if (vbuf)
> +					memcpy (&voutp[pos], ptr, cpysize);
> +				break;
> +			case TM6000_URB_MSG_AUDIO:
> +				/* Need some code to copy audio buffer */
> +				break;
> +			case TM6000_URB_MSG_VBI:
> +				/* Need some code to copy vbi buffer */
> +				break;
> +			case TM6000_URB_MSG_PTS:
> +				/* Need some code to copy pts */
> +				break;
>  			}
> -
> -			/* Get message header */
> -			header=*(unsigned long *)ptr;
> -			ptr+=4;
>  		}
> -HEADER:
> -		/* Copy or continue last copy */
> -		rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
> -		if (rc<0) {
> -			buf=NULL;
> -			printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
> -					jiffies);
> -			return rc;
> +		if (ptr + pktsize > endp) {
> +			/* End of URB packet, but cmd processing is not
> +			 * complete. Preserve the state for a next packet
> +			 */
> +			dev->isoc_ctl.pos = pos + cpysize;
> +			dev->isoc_ctl.size = size - cpysize;
> +			dev->isoc_ctl.cmd = cmd;
> +			dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
> +			ptr += end - ptr;

A typo: missing p
+			ptr += endp - ptr;


I've compiled and tested the patches from May 10th with the above fixes and
analog video working great on HVR-900H.

Regards
George
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux