V4L/DVB: gspca_ovfx2: drop first frames in stream if not synced
authorHans de Goede <hdegoede@redhat.com>
Sat, 8 May 2010 11:55:42 +0000 (08:55 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 2 Aug 2010 17:06:03 +0000 (14:06 -0300)
With the ovfx2 bridge sometimes the first few frames in a stream
would be no good, as the bridge and sensor are not in complete hsync /
vsync yet. This can easily be detected by checking the framesize. So if the
framesize is short and it is one of the 1ste 3 frames after an sd_start,
drop it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/gspca/ov519.c

index f36e11a0458d4ca7a248a68d4bc48b46daa5ce90..aa3de2f5a272b7ff49cf395b6db64e95264a6785 100644 (file)
@@ -90,6 +90,7 @@ struct sd {
 #define QUALITY_DEF 50
 
        __u8 stopped;           /* Streaming is temporarily paused */
+       __u8 first_frame;
 
        __u8 frame_rate;        /* current Framerate */
        __u8 clockdiv;          /* clockdiv override */
@@ -3961,6 +3962,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
        sd_reset_snapshot(gspca_dev);
        sd->snapshot_pressed = 0;
 
+       sd->first_frame = 3;
+
        ret = ov51x_restart(sd);
        if (ret < 0)
                goto out;
@@ -4153,13 +4156,25 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
                        u8 *data,                       /* isoc packet */
                        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);
+
        /* A short read signals EOF */
        if (len < OVFX2_BULK_SIZE) {
-               gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
+               /* If the frame is short, and it is one of the first ones
+                  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))
+                               gspca_dev->last_packet_type = DISCARD_PACKET;
+               }
+               gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
                gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
-               return;
        }
-       gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 }
 
 static void sd_pkt_scan(struct gspca_dev *gspca_dev,