Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 241868
b: refs/heads/master
c: a4a3076
h: refs/heads/master
v: v3
  • Loading branch information
Jean-François Moine authored and Mauro Carvalho Chehab committed Mar 21, 2011
1 parent cd1039b commit 471475d
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 27 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f77f40c300c18c15e7aeb2f9eee510aa96d58fd
refs/heads/master: a4a3076ffcdbcf40358edc2068aa4d9103fe0a28
119 changes: 93 additions & 26 deletions trunk/drivers/media/video/gspca/sonixj.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ struct sd {
atomic_t avg_lum;
u32 exposure;

s8 short_mark;

u8 quality; /* image quality */
#define QUALITY_MIN 60
#define QUALITY_MAX 95
Expand Down Expand Up @@ -2787,39 +2789,104 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
int sof;

/* the image ends on a 64 bytes block starting with
* ff d9 ff ff 00 c4 c4 96
* and followed by various information including luminosity */
/* this block may be splitted between two packets */
/* a new image always starts in a new packet */
switch (gspca_dev->last_packet_type) {
case DISCARD_PACKET: /* restart image building */
sof = len - 64;
if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9)
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
return;
case LAST_PACKET: /* put the JPEG 422 header */
int i;

/*
* A frame ends on the marker
* ff ff 00 c4 c4 96 ..
* which is 62 bytes long and is followed by various information
* including statuses and luminosity.
*
* A marker may be splitted on two packets.
*
* The 6th byte of a marker contains the bits:
* 0x08: USB full
* 0xc0: frame sequence
* When the bit 'USB full' is set, the frame must be discarded;
* this is also the case when the 2 bytes before the marker are
* not the JPEG end of frame ('ff d9').
*/

/*fixme: assumption about the following code:
* - there can be only one marker in a packet
*/

/* skip the remaining bytes of a short marker */
i = sd->short_mark;
if (i != 0) {
sd->short_mark = 0;
if (i < 0 /* if 'ff' at end of previous packet */
&& data[0] == 0xff
&& data[1] == 0x00)
goto marker_found;
if (data[0] == 0xff && data[1] == 0xff) {
i = 0;
goto marker_found;
}
len -= i;
if (len <= 0)
return;
data += i;
}

/* search backwards if there is a marker in the packet */
for (i = len - 1; --i >= 0; ) {
if (data[i] != 0xff) {
i--;
continue;
}
if (data[i + 1] == 0xff) {

/* (there may be 'ff ff' inside a marker) */
if (i + 2 >= len || data[i + 2] == 0x00)
goto marker_found;
}
}

/* no marker found */
/* add the JPEG header if first fragment */
if (data[len - 1] == 0xff)
sd->short_mark = -1;
if (gspca_dev->last_packet_type == LAST_PACKET)
gspca_frame_add(gspca_dev, FIRST_PACKET,
sd->jpeg_hdr, JPEG_HDR_SZ);
break;
}
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
return;

/* marker found */
/* if some error, discard the frame */
marker_found:
if (i > 2) {
if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
gspca_dev->last_packet_type = DISCARD_PACKET;
}
} else if (i + 6 < len) {
if (data[i + 6] & 0x08) {
gspca_dev->last_packet_type = DISCARD_PACKET;
}
}

data = gspca_dev->image;
if (data == NULL)
return;
sof = gspca_dev->image_len - 64;
if (data[sof] != 0xff
|| data[sof + 1] != 0xd9)
gspca_frame_add(gspca_dev, LAST_PACKET, data, i);

/* if the marker is smaller than 62 bytes,
* memorize the number of bytes to skip in the next packet */
if (i + 62 > len) { /* no more usable data */
sd->short_mark = i + 62 - len;
return;
}

/* end of image found - remove the trailing data */
gspca_dev->image_len = sof + 2;
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
if (sd->ag_cnt >= 0)
set_lum(sd, data + sof + 2);
set_lum(sd, data + i);

/* if more data, start a new frame */
i += 62;
if (i < len) {
data += i;
len -= i;
gspca_frame_add(gspca_dev, FIRST_PACKET,
sd->jpeg_hdr, JPEG_HDR_SZ);
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
}
}

static int sd_set_jcomp(struct gspca_dev *gspca_dev,
Expand Down

0 comments on commit 471475d

Please sign in to comment.