V4L/DVB (9552): gspca: Simplify the ISOC packet scanning in tv8532.

This patch
- makes unuseful the temporary buffers
- and also fixes the bad colors problem.

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index f6a4733..3eac1cb 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -30,10 +30,6 @@
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
 
-	__u32 buflen;			/* current length of tmpbuf */
-	__u8 tmpbuf[352 * 288 + 10 * 288];	/* no protection... */
-	__u8 tmpbuf2[352 * 288];		/* no protection... */
-
 	__u16 brightness;
 	__u16 contrast;
 
@@ -391,6 +387,8 @@
 /* -- start the camera -- */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
+	struct sd *sd = (struct sd *) gspca_dev;
+
 	reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
 	reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
 	tv_8532ReadRegisters(gspca_dev);
@@ -444,6 +442,7 @@
 	reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00);	/* 0x31 */
 
 	gspca_dev->empty_packet = 0;		/* check the empty packets */
+	sd->packet = 0;				/* ignore the first packets */
 
 	return 0;
 }
@@ -453,107 +452,36 @@
 	reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
 }
 
-static void tv8532_preprocess(struct gspca_dev *gspca_dev)
-{
-	struct sd *sd = (struct sd *) gspca_dev;
-/* we should received a whole frame with header and EOL marker
- * in sd->tmpbuf and return a GBRG pattern in sd->tmpbuf2
- * sequence 2bytes header the Alternate pixels bayer GB 4 bytes
- * Alternate pixels bayer RG 4 bytes EOL */
-	int width = gspca_dev->width;
-	int height = gspca_dev->height;
-	unsigned char *dst = sd->tmpbuf2;
-	unsigned char *data = sd->tmpbuf;
-	int i;
-
-	/* precompute where is the good bayer line */
-	if (((data[3] + data[width + 7]) >> 1)
-	    + (data[4] >> 2)
-	    + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1)
-	    + (data[3] >> 2)
-	    + (data[width + 5] >> 1))
-		data += 3;
-	else
-		data += 2;
-	for (i = 0; i < height / 2; i++) {
-		memcpy(dst, data, width);
-		data += width + 3;
-		dst += width;
-		memcpy(dst, data, width);
-		data += width + 7;
-		dst += width;
-	}
-}
-
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 			struct gspca_frame *frame,	/* target */
 			__u8 *data,			/* isoc packet */
 			int len)			/* iso packet length */
 {
 	struct sd *sd = (struct sd *) gspca_dev;
+	int packet_type0, packet_type1;
 
-	if (data[0] != 0x80) {
-		sd->packet++;
-		if (sd->buflen + len > sizeof sd->tmpbuf) {
-			if (gspca_dev->last_packet_type != DISCARD_PACKET) {
-				PDEBUG(D_PACK, "buffer overflow");
-				gspca_dev->last_packet_type = DISCARD_PACKET;
-			}
-			return;
-		}
-		memcpy(&sd->tmpbuf[sd->buflen], data, len);
-		sd->buflen += len;
-		return;
-	}
-
-	/* here we detect 0x80 */
-	/* counter is limited so we need few header for a frame :) */
-
-	/* header 0x80 0x80 0x80 0x80 0x80 */
-	/* packet  00   63  127  145  00   */
-	/* empty    1    0   0    1    1   */
-
-	/* update sequence */
-	if (sd->packet == 63 || sd->packet == 127)
-		gspca_dev->empty_packet = 0;
-
-	/* is there a frame start ? */
-	/* (each packet is 2 lines plus 10 bytes) */
-	if (sd->packet >= (gspca_dev->height >> 1) - 1) {
-		PDEBUG(D_PACK, "empty %d packet %d",
-			gspca_dev->empty_packet, sd->packet);
-		if (gspca_dev->empty_packet) {	/* start of frame */
-			if (gspca_dev->last_packet_type == FIRST_PACKET) {
-				tv8532_preprocess(gspca_dev);
-				frame = gspca_frame_add(gspca_dev,
-							LAST_PACKET,
-							frame, sd->tmpbuf2,
-							gspca_dev->height *
-							    gspca_dev->width);
-			}
-			gspca_frame_add(gspca_dev, FIRST_PACKET,
-					frame, data, 0);
-			memcpy(sd->tmpbuf, data, len);
-			sd->buflen = len;
-			sd->packet = 0;
-			return;
-		}
-		if (gspca_dev->last_packet_type != DISCARD_PACKET) {
-			PDEBUG(D_PACK,
-			       "Warning wrong TV8532 frame detection %d",
-			       sd->packet);
-			gspca_dev->last_packet_type = DISCARD_PACKET;
-		}
-		return;
-	}
-
+	packet_type0 = packet_type1 = INTER_PACKET;
 	if (gspca_dev->empty_packet) {
-		/* Drop packet frame corrupt */
-		PDEBUG(D_PACK, "DROP empty %d packet %d",
-			gspca_dev->empty_packet, sd->packet);
-		sd->packet = 0;
-		gspca_dev->last_packet_type = DISCARD_PACKET;
-	}
+		gspca_dev->empty_packet = 0;
+		sd->packet = gspca_dev->height / 2;
+		packet_type0 = FIRST_PACKET;
+	} else if (sd->packet == 0)
+		return;			/* 2 more lines in 352x288 ! */
+	sd->packet--;
+	if (sd->packet == 0)
+		packet_type1 = LAST_PACKET;
+
+	/* each packet contains:
+	 * - header 2 bytes
+	 * - RG line
+	 * - 4 bytes
+	 * - GB line
+	 * - 4 bytes
+	 */
+	gspca_frame_add(gspca_dev, packet_type0,
+			frame, data + 2, gspca_dev->width);
+	gspca_frame_add(gspca_dev, packet_type1,
+			frame, data + gspca_dev->width + 6, gspca_dev->width);
 }
 
 static void setcontrast(struct gspca_dev *gspca_dev)