summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2010-06-27 03:08:19 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-02 15:31:10 -0300
commitb192ca983746585e807259414f8d6f58cb28311f (patch)
tree8c95bdcebcf4217e3813d803ecf281af2d431e5f /drivers
parentc6dc725c8e0c3438587e18f918f6da16e7a23539 (diff)
downloadlinux-b192ca983746585e807259414f8d6f58cb28311f.tar.gz
V4L/DVB: gspca - main: Simplify image building
The image pointer and its length are now in the main structure instead
of in the frame buffer. They are updated on application vidioc_qbuf and
in the URB interrupt function when ending an image.

Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/cpia1.c15
-rw-r--r--drivers/media/video/gspca/gspca.c65
-rw-r--r--drivers/media/video/gspca/gspca.h5
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c12
-rw-r--r--drivers/media/video/gspca/ov519.c6
-rw-r--r--drivers/media/video/gspca/ov534.c7
-rw-r--r--drivers/media/video/gspca/pac7302.c24
-rw-r--r--drivers/media/video/gspca/pac7311.c24
-rw-r--r--drivers/media/video/gspca/sonixb.c6
-rw-r--r--drivers/media/video/gspca/vc032x.c13
10 files changed, 79 insertions, 98 deletions
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 58b696f455be..4b3ea3b4bbba 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -1760,22 +1760,23 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	    data[25] == sd->params.roi.colEnd &&
 	    data[26] == sd->params.roi.rowStart &&
 	    data[27] == sd->params.roi.rowEnd) {
-		struct gspca_frame *frame = gspca_get_i_frame(gspca_dev);
+		u8 *image;
 
 		atomic_set(&sd->cam_exposure, data[39] * 2);
 		atomic_set(&sd->fps, data[41]);
 
-		if (frame == NULL) {
+		image = gspca_dev->image;
+		if (image == NULL) {
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
 
 		/* Check for proper EOF for last frame */
-		if ((frame->data_end - frame->data) > 4 &&
-		    frame->data_end[-4] == 0xff &&
-		    frame->data_end[-3] == 0xff &&
-		    frame->data_end[-2] == 0xff &&
-		    frame->data_end[-1] == 0xff)
+		if (gspca_dev->image_len > 4 &&
+		    image[gspca_dev->image_len - 4] == 0xff &&
+		    image[gspca_dev->image_len - 3] == 0xff &&
+		    image[gspca_dev->image_len - 2] == 0xff &&
+		    image[gspca_dev->image_len - 1] == 0xff)
 			gspca_frame_add(gspca_dev, LAST_PACKET,
 						NULL, 0);
 
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 69b1058daeeb..8e822ed4435f 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -294,19 +294,6 @@ static inline int gspca_input_connect(struct gspca_dev *dev)
 }
 #endif
 
-/* get the current input frame buffer */
-struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
-{
-	struct gspca_frame *frame;
-
-	frame = gspca_dev->cur_frame;
-	if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
-				!= V4L2_BUF_FLAG_QUEUED)
-		return NULL;
-	return frame;
-}
-EXPORT_SYMBOL(gspca_get_i_frame);
-
 /*
  * fill a video frame from an URB and resubmit
  */
@@ -328,6 +315,8 @@ static void fill_frame(struct gspca_dev *gspca_dev,
 		urb->status = 0;
 		goto resubmit;
 	}
+	if (gspca_dev->image == NULL)
+		gspca_dev->last_packet_type = DISCARD_PACKET;
 	pkt_scan = gspca_dev->sd_desc->pkt_scan;
 	for (i = 0; i < urb->number_of_packets; i++) {
 
@@ -440,19 +429,16 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
 	PDEBUG(D_PACK, "add t:%d l:%d",	packet_type, len);
 
 	/* check the availability of the frame buffer */
-	frame = gspca_dev->cur_frame;
-	if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
-					!= V4L2_BUF_FLAG_QUEUED) {
-		gspca_dev->last_packet_type = DISCARD_PACKET;
+	if (gspca_dev->image == NULL)
 		return;
-	}
 
-	/* when start of a new frame, if the current frame buffer
-	 * is not queued, discard the whole frame */
 	if (packet_type == FIRST_PACKET) {
-		frame->data_end = frame->data;
+		i = gspca_dev->fr_i;
+		j = gspca_dev->fr_queue[i];
+		frame = &gspca_dev->frame[j];
 		frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());
 		frame->v4l2_buf.sequence = ++gspca_dev->sequence;
+		gspca_dev->image_len = 0;
 	} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
 		if (packet_type == LAST_PACKET)
 			gspca_dev->last_packet_type = packet_type;
@@ -461,26 +447,29 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
 
 	/* append the packet to the frame buffer */
 	if (len > 0) {
-		if (frame->data_end - frame->data + len
-						 > frame->v4l2_buf.length) {
-			PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d",
-				frame->data_end - frame->data + len,
-				frame->v4l2_buf.length);
+		if (gspca_dev->image_len + len > gspca_dev->frsz) {
+			PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d",
+				gspca_dev->image_len + len,
+				gspca_dev->frsz);
 			packet_type = DISCARD_PACKET;
 		} else {
-			memcpy(frame->data_end, data, len);
-			frame->data_end += len;
+			memcpy(gspca_dev->image + gspca_dev->image_len,
+				data, len);
+			gspca_dev->image_len += len;
 		}
 	}
 	gspca_dev->last_packet_type = packet_type;
 
 	/* if last packet, wake up the application and advance in the queue */
 	if (packet_type == LAST_PACKET) {
-		frame->v4l2_buf.bytesused = frame->data_end - frame->data;
+		i = gspca_dev->fr_i;
+		j = gspca_dev->fr_queue[i];
+		frame = &gspca_dev->frame[j];
+		frame->v4l2_buf.bytesused = gspca_dev->image_len;
 		frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
 		frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
 		wake_up_interruptible(&gspca_dev->wq);	/* event = new frame */
-		i = (gspca_dev->fr_i + 1) % gspca_dev->nframes;
+		i = (i + 1) % gspca_dev->nframes;
 		gspca_dev->fr_i = i;
 		PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d",
 			frame->v4l2_buf.bytesused,
@@ -488,7 +477,13 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
 			i,
 			gspca_dev->fr_o);
 		j = gspca_dev->fr_queue[i];
-		gspca_dev->cur_frame = &gspca_dev->frame[j];
+		frame = &gspca_dev->frame[j];
+		if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
+					== V4L2_BUF_FLAG_QUEUED) {
+			gspca_dev->image = frame->data;
+		} else {
+			gspca_dev->image = NULL;
+		}
 	}
 }
 EXPORT_SYMBOL(gspca_frame_add);
@@ -535,12 +530,12 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
 		frame->v4l2_buf.length = frsz;
 		frame->v4l2_buf.memory = gspca_dev->memory;
 		frame->v4l2_buf.sequence = 0;
-		frame->data = frame->data_end =
-					gspca_dev->frbuf + i * frsz;
+		frame->data = gspca_dev->frbuf + i * frsz;
 		frame->v4l2_buf.m.offset = i * frsz;
 	}
 	gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
-	gspca_dev->cur_frame = &gspca_dev->frame[0];
+	gspca_dev->image = NULL;
+	gspca_dev->image_len = 0;
 	gspca_dev->last_packet_type = DISCARD_PACKET;
 	gspca_dev->sequence = 0;
 	return 0;
@@ -1948,7 +1943,7 @@ static int vidioc_qbuf(struct file *file, void *priv,
 	i = gspca_dev->fr_q;
 	gspca_dev->fr_queue[i] = index;
 	if (gspca_dev->fr_i == i)
-		gspca_dev->cur_frame = frame;
+		gspca_dev->image = frame->data;
 	gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
 	PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
 		gspca_dev->fr_q,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index d181064653b7..453e43d66a83 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -147,7 +147,6 @@ enum gspca_packet_type {
 
 struct gspca_frame {
 	__u8 *data;			/* frame buffer */
-	__u8 *data_end;			/* end of frame while filling */
 	int vma_use_count;
 	struct v4l2_buffer v4l2_buf;
 };
@@ -176,8 +175,9 @@ struct gspca_dev {
 
 	__u8 *frbuf;				/* buffer for nframes */
 	struct gspca_frame frame[GSPCA_MAX_FRAMES];
-	struct gspca_frame *cur_frame;		/* frame beeing filled */
+	u8 *image;				/* image beeing filled */
 	__u32 frsz;				/* frame size */
+	u32 image_len;				/* current length of image */
 	char nframes;				/* number of frames */
 	char fr_i;				/* frame being filled */
 	char fr_q;				/* next frame to queue */
@@ -226,7 +226,6 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
 			enum gspca_packet_type packet_type,
 			const u8 *data,
 			int len);
-struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
 #ifdef CONFIG_PM
 int gspca_suspend(struct usb_interface *intf, pm_message_t message);
 int gspca_resume(struct usb_interface *intf);
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 4294c75e3b11..0c4ad5a5642a 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -305,30 +305,28 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
 		       sd->frame_count);
 
 	} else {
-		struct gspca_frame *frame;
 		int cur_frame_len;
 
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame == NULL) {
+		if (gspca_dev->image == NULL) {
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
 
-		cur_frame_len = frame->data_end - frame->data;
+		cur_frame_len = gspca_dev->image_len;
 		/* Remove urb header */
 		data += 4;
 		len -= 4;
 
-		if (cur_frame_len + len <= frame->v4l2_buf.length) {
+		if (cur_frame_len + len <= gspca_dev->frsz) {
 			PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
 			       sd->frame_count, len);
 
 			gspca_frame_add(gspca_dev, INTER_PACKET,
 					data, len);
-		} else if (frame->v4l2_buf.length - cur_frame_len > 0) {
+		} else {
 			/* Add the remaining data up to frame size */
 			gspca_frame_add(gspca_dev, INTER_PACKET, data,
-				    frame->v4l2_buf.length - cur_frame_len);
+				    gspca_dev->frsz - cur_frame_len);
 		}
 	}
 }
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 2e7df66a84b9..2b2cbdbf03fe 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -4162,7 +4162,6 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct gspca_frame *frame;
 
 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 
@@ -4172,9 +4171,8 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
 		   the sensor and bridge are still syncing, so drop it. */
 		if (sd->first_frame) {
 			sd->first_frame--;
-			frame = gspca_get_i_frame(gspca_dev);
-			if (!frame || (frame->data_end - frame->data) <
-				  (sd->gspca_dev.width * sd->gspca_dev.height))
+			if (gspca_dev->image_len <
+				  sd->gspca_dev.width * sd->gspca_dev.height)
 				gspca_dev->last_packet_type = DISCARD_PACKET;
 		}
 		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index dc1e4efe30fb..84c9b8dbded6 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -987,13 +987,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 					data + 12, len - 12);
 		/* If this packet is marked as EOF, end the frame */
 		} else if (data[1] & UVC_STREAM_EOF) {
-			struct gspca_frame *frame;
-
 			sd->last_pts = 0;
-			frame = gspca_get_i_frame(gspca_dev);
-			if (frame == NULL)
+			if (gspca_dev->image == NULL)
 				goto discard;
-			if (frame->data_end - frame->data + (len - 12) !=
+			if (gspca_dev->image_len + len - 12 !=
 			    gspca_dev->width * gspca_dev->height * 2) {
 				PDEBUG(D_PACK, "wrong sized frame");
 				goto discard;
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index bf47180a4e2f..88cc03bb3f94 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -804,7 +804,6 @@ static const unsigned char pac_jpeg_header2[] = {
 };
 
 static void pac_start_frame(struct gspca_dev *gspca_dev,
-		struct gspca_frame *frame,
 		__u16 lines, __u16 samples_per_line)
 {
 	unsigned char tmpbuf[4];
@@ -829,15 +828,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	struct gspca_frame *frame;
+	u8 *image;
 	unsigned char *sof;
 
 	sof = pac_find_sof(&sd->sof_read, data, len);
 	if (sof) {
 		int n, lum_offset, footer_length;
 
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame == NULL) {
+		image = gspca_dev->image;
+		if (image == NULL) {
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
@@ -852,16 +851,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 		/* Finish decoding current frame */
 		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
 		if (n < 0) {
-			frame->data_end += n;
+			gspca_dev->image_len += n;
 			n = 0;
+		} else {
+			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
 		}
-		gspca_frame_add(gspca_dev, INTER_PACKET,
-					data, n);
-		if (gspca_dev->last_packet_type != DISCARD_PACKET &&
-				frame->data_end[-2] == 0xff &&
-				frame->data_end[-1] == 0xd9)
-			gspca_frame_add(gspca_dev, LAST_PACKET,
-						NULL, 0);
+		if (gspca_dev->last_packet_type != DISCARD_PACKET
+		 && image[gspca_dev->image_len - 2] == 0xff
+		 && image[gspca_dev->image_len - 1] == 0xd9)
+			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 
 		n = sof - data;
 		len -= n;
@@ -877,7 +875,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 
 		/* Start the new frame with the jpeg header */
 		/* The PAC7302 has the image rotated 90 degrees */
-		pac_start_frame(gspca_dev, frame,
+		pac_start_frame(gspca_dev,
 			gspca_dev->width, gspca_dev->height);
 	}
 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index c978599a69dd..5568c41a296c 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -599,7 +599,6 @@ static const unsigned char pac_jpeg_header2[] = {
 };
 
 static void pac_start_frame(struct gspca_dev *gspca_dev,
-		struct gspca_frame *frame,
 		__u16 lines, __u16 samples_per_line)
 {
 	unsigned char tmpbuf[4];
@@ -624,15 +623,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	u8 *image;
 	unsigned char *sof;
-	struct gspca_frame *frame;
 
 	sof = pac_find_sof(&sd->sof_read, data, len);
 	if (sof) {
 		int n, lum_offset, footer_length;
 
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame == NULL) {
+		image = gspca_dev->image;
+		if (image == NULL) {
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
@@ -647,16 +646,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 		/* Finish decoding current frame */
 		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
 		if (n < 0) {
-			frame->data_end += n;
+			gspca_dev->image_len += n;
 			n = 0;
+		} else {
+			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
 		}
-		gspca_frame_add(gspca_dev, INTER_PACKET,
-					data, n);
-		if (gspca_dev->last_packet_type != DISCARD_PACKET &&
-				frame->data_end[-2] == 0xff &&
-				frame->data_end[-1] == 0xd9)
-			gspca_frame_add(gspca_dev, LAST_PACKET,
-						NULL, 0);
+		if (gspca_dev->last_packet_type != DISCARD_PACKET
+		 && image[gspca_dev->image_len - 2] == 0xff
+		 && image[gspca_dev->image_len - 1] == 0xd9)
+			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 
 		n = sof - data;
 		len -= n;
@@ -671,7 +669,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			atomic_set(&sd->avg_lum, -1);
 
 		/* Start the new frame with the jpeg header */
-		pac_start_frame(gspca_dev, frame,
+		pac_start_frame(gspca_dev,
 			gspca_dev->height, gspca_dev->width);
 	}
 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 95354a339e3d..4989a2c779e5 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -1251,16 +1251,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
 		/* In raw mode we sometimes get some garbage after the frame
 		   ignore this */
-		struct gspca_frame *frame;
 		int used;
 		int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
 
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame == NULL) {
+		if (gspca_dev->image == NULL) {
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
-		used = frame->data_end - frame->data;
+		used = gspca_dev->image_len;
 		if (used + len > size)
 			len = size - used;
 	}
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 732c3dfe46ff..0a7d1e0866d2 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -3726,17 +3726,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 	/* The vc0321 sends some additional data after sending the complete
 	 * frame, we ignore this. */
 	if (sd->bridge == BRIDGE_VC0321) {
-		struct gspca_frame *frame;
-		int l;
+		int size, l;
 
-		frame = gspca_get_i_frame(gspca_dev);
-		if (frame == NULL) {
+		if (gspca_dev->image == NULL) {
 			gspca_dev->last_packet_type = DISCARD_PACKET;
 			return;
 		}
-		l = frame->data_end - frame->data;
-		if (len > frame->v4l2_buf.length - l)
-			len = frame->v4l2_buf.length - l;
+		l = gspca_dev->image_len;
+		size = gspca_dev->frsz;
+		if (len > size - l)
+			len = size - l;
 	}
 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }