V4L/DVB (11105): gspca - ov534: Adjust the packet scan function
- 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>
This commit is contained in:
parent
3481c19854
commit
84fbdf87ab
|
@ -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,
|
||||||
{
|
{
|
||||||
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;
|
/* Payloads are prefixed with a UVC-style header. We
|
||||||
len = min(remaining_len, 2048);
|
consider a frame to start when the FID toggles, or the PTS
|
||||||
remaining_len -= len;
|
changes. A frame ends when EOF is set, and we've received
|
||||||
next_data += len;
|
the correct number of bytes. */
|
||||||
|
|
||||||
/* Payloads are prefixed with a UVC-style header. We
|
/* Verify UVC header. Header length is always 12 */
|
||||||
consider a frame to start when the FID toggles, or the PTS
|
if (data[0] != 12 || len < 12) {
|
||||||
changes. A frame ends when EOF is set, and we've received
|
PDEBUG(D_PACK, "bad header");
|
||||||
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 */
|
|
||||||
if (data[1] & UVC_STREAM_ERR) {
|
|
||||||
PDEBUG(D_PACK, "payload error");
|
|
||||||
goto discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* 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;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
|
/* Check errors */
|
||||||
NULL, 0);
|
if (data[1] & UVC_STREAM_ERR) {
|
||||||
|
PDEBUG(D_PACK, "payload error");
|
||||||
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Done this payload */
|
/* Extract PTS and FID */
|
||||||
goto scan_next;
|
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);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
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) */
|
||||||
|
|
Loading…
Reference in New Issue