V4L/DVB (11105): gspca - ov534: Adjust the packet scan function
authorJean-Francois Moine <moinejf@free.fr>
Thu, 19 Mar 2009 09:12:59 +0000 (06:12 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 30 Mar 2009 15:43:29 +0000 (12:43 -0300)
- change max payload size to 2040 bytes (was 2048)
- optimize

Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/gspca/ov534.c

index ea2245626d538c8d72184dd141901c1fdf009184..647c448f492fa79ac3d55f80ce8011507f260b65 100644 (file)
@@ -46,9 +46,9 @@ MODULE_LICENSE("GPL");
 /* specific webcam descriptor */
 struct sd {
        struct gspca_dev gspca_dev;     /* !! must be the first item */
-       __u32 last_fid;
        __u32 last_pts;
-       int frame_rate;
+       u16 last_fid;
+       u8 frame_rate;
 };
 
 /* V4L2 controls supported by the driver */
@@ -428,76 +428,75 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
 {
        struct sd *sd = (struct sd *) gspca_dev;
        __u32 this_pts;
-       int this_fid;
+       u16 this_fid;
        int remaining_len = len;
-       __u8 *next_data = data;
 
-scan_next:
-       if (remaining_len <= 0)
-               return;
-
-       data = next_data;
-       len = min(remaining_len, 2048);
-       remaining_len -= len;
-       next_data += len;
-
-       /* Payloads are prefixed with a UVC-style header.  We
-          consider a frame to start when the FID toggles, or the PTS
-          changes.  A frame ends when EOF is set, and we've received
-          the correct number of bytes. */
-
-       /* Verify UVC header.  Header length is always 12 */
-       if (data[0] != 12 || len < 12) {
-               PDEBUG(D_PACK, "bad header");
-               goto discard;
-       }
+       do {
+               len = min(remaining_len, 2040);         /*fixme: was 2048*/
 
-       /* Check errors */
-       if (data[1] & UVC_STREAM_ERR) {
-               PDEBUG(D_PACK, "payload error");
-               goto discard;
-       }
+               /* Payloads are prefixed with a UVC-style header.  We
+                  consider a frame to start when the FID toggles, or the PTS
+                  changes.  A frame ends when EOF is set, and we've received
+                  the correct number of bytes. */
 
-       /* Extract PTS and FID */
-       if (!(data[1] & UVC_STREAM_PTS)) {
-               PDEBUG(D_PACK, "PTS not present");
-               goto discard;
-       }
-       this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2];
-       this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
-
-       /* If PTS or FID has changed, start a new frame. */
-       if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
-               gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
-               sd->last_pts = this_pts;
-               sd->last_fid = this_fid;
-       }
-
-       /* Add the data from this payload */
-       gspca_frame_add(gspca_dev, INTER_PACKET, frame,
-                               data + 12, len - 12);
+               /* Verify UVC header.  Header length is always 12 */
+               if (data[0] != 12 || len < 12) {
+                       PDEBUG(D_PACK, "bad header");
+                       goto discard;
+               }
 
-       /* If this packet is marked as EOF, end the frame */
-       if (data[1] & UVC_STREAM_EOF) {
-               sd->last_pts = 0;
+               /* Check errors */
+               if (data[1] & UVC_STREAM_ERR) {
+                       PDEBUG(D_PACK, "payload error");
+                       goto discard;
+               }
 
-               if ((frame->data_end - frame->data) !=
-                   (gspca_dev->width * gspca_dev->height * 2)) {
-                       PDEBUG(D_PACK, "short frame");
+               /* Extract PTS and FID */
+               if (!(data[1] & UVC_STREAM_PTS)) {
+                       PDEBUG(D_PACK, "PTS not present");
                        goto discard;
                }
+               this_pts = (data[5] << 24) | (data[4] << 16)
+                                               | (data[3] << 8) | data[2];
+               this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
 
-               frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+               /* If PTS or FID has changed, start a new frame. */
+               if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
+                       gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
                                        NULL, 0);
+                       sd->last_pts = this_pts;
+                       sd->last_fid = this_fid;
+               }
+
+               /* Add the data from this payload */
+               gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+                                       data + 12, len - 12);
+
+               /* If this packet is marked as EOF, end the frame */
+               if (data[1] & UVC_STREAM_EOF) {
+                       sd->last_pts = 0;
+
+                       if (frame->data_end - frame->data !=
+                           gspca_dev->width * gspca_dev->height * 2) {
+                               PDEBUG(D_PACK, "short frame");
+                               goto discard;
+                       }
+
+                       frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+                                               NULL, 0);
                }
 
-       /* Done this payload */
-       goto scan_next;
+               /* Done this payload */
+               goto scan_next;
 
 discard:
-       /* Discard data until a new frame starts. */
-       gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
-       goto scan_next;
+               /* Discard data until a new frame starts. */
+               gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
+
+scan_next:
+               remaining_len -= len;
+               data += len;
+       } while (remaining_len > 0);
 }
 
 /* get stream parameters (framerate) */