aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-09-03 16:47:27 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-09-03 18:36:31 -0300
commit8559e8da31f37e2916195f44bbe79a61008782df (patch)
treed70f31e3f222cd9b4259cd10efa1899b5aa63784
parent9d5c1251bfc10a0e864352f45e272331f65b3420 (diff)
V4L/DVB (8666): gspca: Bad scanning of frames in pac7311.
The previous change in packet scanning did not work, Also, autogain was no more treated at interrupt level. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/gspca/pac7311.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 034c00d6c0a..730b4a1aed9 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -702,8 +702,16 @@ static void do_autogain(struct gspca_dev *gspca_dev)
static void put_jpeg_head(struct gspca_dev *gspca_dev,
struct gspca_frame *frame)
{
+ struct sd *sd = (struct sd *) gspca_dev;
unsigned char tmpbuf[4];
+ if (sd->ag_cnt >= 0) {
+ if (--sd->ag_cnt < 0) {
+ sd->ag_cnt = AG_CNT_START;
+ atomic_set(&sd->avg_lum, sd->lum_sum / AG_CNT_START);
+ atomic_set(&sd->do_gain, 1);
+ }
+ }
gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
(__u8 *) pac7311_jpeg_header,
12);
@@ -727,7 +735,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
int i;
-#define INTER_FRAME 0x53
+#define INTER_FRAME 0x53 /* eof + inter frame + sof */
#define LUM_OFFSET 0x1e /* reverse offset / start of frame */
/*
@@ -746,11 +754,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
if (sd->tosof == 0) { /* if inside a frame */
/* check for 'ff ff ff xx' at start and at end of packet */
- /* (len is always >= 3) */
+ /* (len is always >= 3 and xx never ff) */
switch (sd->ffnb) {
case 1:
- if (data[0] != 0xff)
+ if (data[0] != 0xff) { /* can be '00' only */
+ __u8 ff;
+
+ sd->ffnb = 0;
+ ff = 0xff;
+ gspca_frame_add(gspca_dev, INTER_PACKET,
+ frame, &ff, 1);
break; /* keep 'ff 00' */
+ }
/* fall thru */
case 2:
case 3:
@@ -775,16 +790,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
} else { /* outside a frame */
- /*
- * get the luminosity
- * and go to the start of frame
- */
+ /* get the luminosity and go to the start of frame */
data += sd->tosof;
len -= sd->tosof;
if (sd->tosof > LUM_OFFSET)
sd->lum_sum += data[-LUM_OFFSET];
- put_jpeg_head(gspca_dev, frame);
sd->tosof = 0;
+ put_jpeg_head(gspca_dev, frame);
}
for (i = 0; i < len; i++) {
@@ -792,10 +804,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
continue;
switch (data[i + 1]) {
case 0xd9: /* end of frame */
- i += 2;
frame = gspca_frame_add(gspca_dev,
LAST_PACKET,
- frame, data, i);
+ frame, data, i + 2);
data += i + INTER_FRAME;
len -= i + INTER_FRAME;
i = 0;
@@ -816,6 +827,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
break;
}
}
+ gspca_frame_add(gspca_dev, INTER_PACKET,
+ frame, data, i);
}
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)