V4L/DVB (9552): gspca: Simplify the ISOC packet scanning in tv8532.
Jean-Francois Moine [Mon, 27 Oct 2008 07:43:49 +0000 (04:43 -0300)]
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>

drivers/media/video/gspca/tv8532.c

index f6a4733..3eac1cb 100644 (file)
@@ -30,10 +30,6 @@ MODULE_LICENSE("GPL");
 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 @@ static void setbrightness(struct gspca_dev *gspca_dev)
 /* -- 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 @@ static int sd_start(struct gspca_dev *gspca_dev)
        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 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
        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)