Commit 84fbdf87 authored by Jean-Francois Moine's avatar Jean-Francois Moine Committed by Mauro Carvalho Chehab

V4L/DVB (11105): gspca - ov534: Adjust the packet scan function

- change max payload size to 2040 bytes (was 2048)
- optimize
Signed-off-by: default avatarJean-Francois Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 3481c198
...@@ -46,9 +46,9 @@ MODULE_LICENSE("GPL"); ...@@ -46,9 +46,9 @@ MODULE_LICENSE("GPL");
/* specific webcam descriptor */ /* specific webcam descriptor */
struct sd { struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */ struct gspca_dev gspca_dev; /* !! must be the first item */
__u32 last_fid;
__u32 last_pts; __u32 last_pts;
int frame_rate; u16 last_fid;
u8 frame_rate;
}; };
/* V4L2 controls supported by the driver */ /* V4L2 controls supported by the driver */
...@@ -428,76 +428,75 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, ...@@ -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; struct sd *sd = (struct sd *) gspca_dev;
__u32 this_pts; __u32 this_pts;
int this_fid; u16 this_fid;
int remaining_len = len; int remaining_len = len;
__u8 *next_data = data;
scan_next: do {
if (remaining_len <= 0) len = min(remaining_len, 2040); /*fixme: was 2048*/
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;
}
/* Check errors */ /* Payloads are prefixed with a UVC-style header. We
if (data[1] & UVC_STREAM_ERR) { consider a frame to start when the FID toggles, or the PTS
PDEBUG(D_PACK, "payload error"); changes. A frame ends when EOF is set, and we've received
goto discard; the correct number of bytes. */
}
/* Extract PTS and FID */ /* Verify UVC header. Header length is always 12 */
if (!(data[1] & UVC_STREAM_PTS)) { if (data[0] != 12 || len < 12) {
PDEBUG(D_PACK, "PTS not present"); PDEBUG(D_PACK, "bad header");
goto discard; 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);
/* If this packet is marked as EOF, end the frame */ /* Check errors */
if (data[1] & UVC_STREAM_EOF) { if (data[1] & UVC_STREAM_ERR) {
sd->last_pts = 0; PDEBUG(D_PACK, "payload error");
goto discard;
}
if ((frame->data_end - frame->data) != /* Extract PTS and FID */
(gspca_dev->width * gspca_dev->height * 2)) { if (!(data[1] & UVC_STREAM_PTS)) {
PDEBUG(D_PACK, "short frame"); PDEBUG(D_PACK, "PTS not present");
goto discard; 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); 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 */ /* Done this payload */
goto scan_next; goto scan_next;
discard: discard:
/* Discard data until a new frame starts. */ /* Discard data until a new frame starts. */
gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
goto scan_next;
scan_next:
remaining_len -= len;
data += len;
} while (remaining_len > 0);
} }
/* get stream parameters (framerate) */ /* get stream parameters (framerate) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment