mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-22 10:31:08 +00:00
V4L/DVB: gspca - main: Simplify image building
The image pointer and its length are now in the main structure instead of in the frame buffer. They are updated on application vidioc_qbuf and in the URB interrupt function when ending an image. Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
c6dc725c8e
commit
b192ca9837
10 changed files with 79 additions and 98 deletions
|
@ -1760,22 +1760,23 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
data[25] == sd->params.roi.colEnd &&
|
data[25] == sd->params.roi.colEnd &&
|
||||||
data[26] == sd->params.roi.rowStart &&
|
data[26] == sd->params.roi.rowStart &&
|
||||||
data[27] == sd->params.roi.rowEnd) {
|
data[27] == sd->params.roi.rowEnd) {
|
||||||
struct gspca_frame *frame = gspca_get_i_frame(gspca_dev);
|
u8 *image;
|
||||||
|
|
||||||
atomic_set(&sd->cam_exposure, data[39] * 2);
|
atomic_set(&sd->cam_exposure, data[39] * 2);
|
||||||
atomic_set(&sd->fps, data[41]);
|
atomic_set(&sd->fps, data[41]);
|
||||||
|
|
||||||
if (frame == NULL) {
|
image = gspca_dev->image;
|
||||||
|
if (image == NULL) {
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for proper EOF for last frame */
|
/* Check for proper EOF for last frame */
|
||||||
if ((frame->data_end - frame->data) > 4 &&
|
if (gspca_dev->image_len > 4 &&
|
||||||
frame->data_end[-4] == 0xff &&
|
image[gspca_dev->image_len - 4] == 0xff &&
|
||||||
frame->data_end[-3] == 0xff &&
|
image[gspca_dev->image_len - 3] == 0xff &&
|
||||||
frame->data_end[-2] == 0xff &&
|
image[gspca_dev->image_len - 2] == 0xff &&
|
||||||
frame->data_end[-1] == 0xff)
|
image[gspca_dev->image_len - 1] == 0xff)
|
||||||
gspca_frame_add(gspca_dev, LAST_PACKET,
|
gspca_frame_add(gspca_dev, LAST_PACKET,
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
|
|
||||||
|
|
|
@ -294,19 +294,6 @@ static inline int gspca_input_connect(struct gspca_dev *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* get the current input frame buffer */
|
|
||||||
struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
|
|
||||||
{
|
|
||||||
struct gspca_frame *frame;
|
|
||||||
|
|
||||||
frame = gspca_dev->cur_frame;
|
|
||||||
if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
|
|
||||||
!= V4L2_BUF_FLAG_QUEUED)
|
|
||||||
return NULL;
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(gspca_get_i_frame);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fill a video frame from an URB and resubmit
|
* fill a video frame from an URB and resubmit
|
||||||
*/
|
*/
|
||||||
|
@ -328,6 +315,8 @@ static void fill_frame(struct gspca_dev *gspca_dev,
|
||||||
urb->status = 0;
|
urb->status = 0;
|
||||||
goto resubmit;
|
goto resubmit;
|
||||||
}
|
}
|
||||||
|
if (gspca_dev->image == NULL)
|
||||||
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
pkt_scan = gspca_dev->sd_desc->pkt_scan;
|
pkt_scan = gspca_dev->sd_desc->pkt_scan;
|
||||||
for (i = 0; i < urb->number_of_packets; i++) {
|
for (i = 0; i < urb->number_of_packets; i++) {
|
||||||
|
|
||||||
|
@ -440,19 +429,16 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
|
||||||
PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
|
PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
|
||||||
|
|
||||||
/* check the availability of the frame buffer */
|
/* check the availability of the frame buffer */
|
||||||
frame = gspca_dev->cur_frame;
|
if (gspca_dev->image == NULL)
|
||||||
if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
|
|
||||||
!= V4L2_BUF_FLAG_QUEUED) {
|
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* when start of a new frame, if the current frame buffer
|
|
||||||
* is not queued, discard the whole frame */
|
|
||||||
if (packet_type == FIRST_PACKET) {
|
if (packet_type == FIRST_PACKET) {
|
||||||
frame->data_end = frame->data;
|
i = gspca_dev->fr_i;
|
||||||
|
j = gspca_dev->fr_queue[i];
|
||||||
|
frame = &gspca_dev->frame[j];
|
||||||
frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());
|
frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());
|
||||||
frame->v4l2_buf.sequence = ++gspca_dev->sequence;
|
frame->v4l2_buf.sequence = ++gspca_dev->sequence;
|
||||||
|
gspca_dev->image_len = 0;
|
||||||
} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
|
} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
|
||||||
if (packet_type == LAST_PACKET)
|
if (packet_type == LAST_PACKET)
|
||||||
gspca_dev->last_packet_type = packet_type;
|
gspca_dev->last_packet_type = packet_type;
|
||||||
|
@ -461,26 +447,29 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
|
||||||
|
|
||||||
/* append the packet to the frame buffer */
|
/* append the packet to the frame buffer */
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
if (frame->data_end - frame->data + len
|
if (gspca_dev->image_len + len > gspca_dev->frsz) {
|
||||||
> frame->v4l2_buf.length) {
|
PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d",
|
||||||
PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d",
|
gspca_dev->image_len + len,
|
||||||
frame->data_end - frame->data + len,
|
gspca_dev->frsz);
|
||||||
frame->v4l2_buf.length);
|
|
||||||
packet_type = DISCARD_PACKET;
|
packet_type = DISCARD_PACKET;
|
||||||
} else {
|
} else {
|
||||||
memcpy(frame->data_end, data, len);
|
memcpy(gspca_dev->image + gspca_dev->image_len,
|
||||||
frame->data_end += len;
|
data, len);
|
||||||
|
gspca_dev->image_len += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gspca_dev->last_packet_type = packet_type;
|
gspca_dev->last_packet_type = packet_type;
|
||||||
|
|
||||||
/* if last packet, wake up the application and advance in the queue */
|
/* if last packet, wake up the application and advance in the queue */
|
||||||
if (packet_type == LAST_PACKET) {
|
if (packet_type == LAST_PACKET) {
|
||||||
frame->v4l2_buf.bytesused = frame->data_end - frame->data;
|
i = gspca_dev->fr_i;
|
||||||
|
j = gspca_dev->fr_queue[i];
|
||||||
|
frame = &gspca_dev->frame[j];
|
||||||
|
frame->v4l2_buf.bytesused = gspca_dev->image_len;
|
||||||
frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
|
frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
|
||||||
frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
|
frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
|
||||||
wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
|
wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
|
||||||
i = (gspca_dev->fr_i + 1) % gspca_dev->nframes;
|
i = (i + 1) % gspca_dev->nframes;
|
||||||
gspca_dev->fr_i = i;
|
gspca_dev->fr_i = i;
|
||||||
PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d",
|
PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d",
|
||||||
frame->v4l2_buf.bytesused,
|
frame->v4l2_buf.bytesused,
|
||||||
|
@ -488,7 +477,13 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
|
||||||
i,
|
i,
|
||||||
gspca_dev->fr_o);
|
gspca_dev->fr_o);
|
||||||
j = gspca_dev->fr_queue[i];
|
j = gspca_dev->fr_queue[i];
|
||||||
gspca_dev->cur_frame = &gspca_dev->frame[j];
|
frame = &gspca_dev->frame[j];
|
||||||
|
if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
|
||||||
|
== V4L2_BUF_FLAG_QUEUED) {
|
||||||
|
gspca_dev->image = frame->data;
|
||||||
|
} else {
|
||||||
|
gspca_dev->image = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(gspca_frame_add);
|
EXPORT_SYMBOL(gspca_frame_add);
|
||||||
|
@ -535,12 +530,12 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
|
||||||
frame->v4l2_buf.length = frsz;
|
frame->v4l2_buf.length = frsz;
|
||||||
frame->v4l2_buf.memory = gspca_dev->memory;
|
frame->v4l2_buf.memory = gspca_dev->memory;
|
||||||
frame->v4l2_buf.sequence = 0;
|
frame->v4l2_buf.sequence = 0;
|
||||||
frame->data = frame->data_end =
|
frame->data = gspca_dev->frbuf + i * frsz;
|
||||||
gspca_dev->frbuf + i * frsz;
|
|
||||||
frame->v4l2_buf.m.offset = i * frsz;
|
frame->v4l2_buf.m.offset = i * frsz;
|
||||||
}
|
}
|
||||||
gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
|
gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
|
||||||
gspca_dev->cur_frame = &gspca_dev->frame[0];
|
gspca_dev->image = NULL;
|
||||||
|
gspca_dev->image_len = 0;
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
gspca_dev->sequence = 0;
|
gspca_dev->sequence = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1948,7 +1943,7 @@ static int vidioc_qbuf(struct file *file, void *priv,
|
||||||
i = gspca_dev->fr_q;
|
i = gspca_dev->fr_q;
|
||||||
gspca_dev->fr_queue[i] = index;
|
gspca_dev->fr_queue[i] = index;
|
||||||
if (gspca_dev->fr_i == i)
|
if (gspca_dev->fr_i == i)
|
||||||
gspca_dev->cur_frame = frame;
|
gspca_dev->image = frame->data;
|
||||||
gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
|
gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
|
||||||
PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
|
PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
|
||||||
gspca_dev->fr_q,
|
gspca_dev->fr_q,
|
||||||
|
|
|
@ -147,7 +147,6 @@ enum gspca_packet_type {
|
||||||
|
|
||||||
struct gspca_frame {
|
struct gspca_frame {
|
||||||
__u8 *data; /* frame buffer */
|
__u8 *data; /* frame buffer */
|
||||||
__u8 *data_end; /* end of frame while filling */
|
|
||||||
int vma_use_count;
|
int vma_use_count;
|
||||||
struct v4l2_buffer v4l2_buf;
|
struct v4l2_buffer v4l2_buf;
|
||||||
};
|
};
|
||||||
|
@ -176,8 +175,9 @@ struct gspca_dev {
|
||||||
|
|
||||||
__u8 *frbuf; /* buffer for nframes */
|
__u8 *frbuf; /* buffer for nframes */
|
||||||
struct gspca_frame frame[GSPCA_MAX_FRAMES];
|
struct gspca_frame frame[GSPCA_MAX_FRAMES];
|
||||||
struct gspca_frame *cur_frame; /* frame beeing filled */
|
u8 *image; /* image beeing filled */
|
||||||
__u32 frsz; /* frame size */
|
__u32 frsz; /* frame size */
|
||||||
|
u32 image_len; /* current length of image */
|
||||||
char nframes; /* number of frames */
|
char nframes; /* number of frames */
|
||||||
char fr_i; /* frame being filled */
|
char fr_i; /* frame being filled */
|
||||||
char fr_q; /* next frame to queue */
|
char fr_q; /* next frame to queue */
|
||||||
|
@ -226,7 +226,6 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
|
||||||
enum gspca_packet_type packet_type,
|
enum gspca_packet_type packet_type,
|
||||||
const u8 *data,
|
const u8 *data,
|
||||||
int len);
|
int len);
|
||||||
struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
int gspca_suspend(struct usb_interface *intf, pm_message_t message);
|
int gspca_suspend(struct usb_interface *intf, pm_message_t message);
|
||||||
int gspca_resume(struct usb_interface *intf);
|
int gspca_resume(struct usb_interface *intf);
|
||||||
|
|
|
@ -305,30 +305,28 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
|
||||||
sd->frame_count);
|
sd->frame_count);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
struct gspca_frame *frame;
|
|
||||||
int cur_frame_len;
|
int cur_frame_len;
|
||||||
|
|
||||||
frame = gspca_get_i_frame(gspca_dev);
|
if (gspca_dev->image == NULL) {
|
||||||
if (frame == NULL) {
|
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frame_len = frame->data_end - frame->data;
|
cur_frame_len = gspca_dev->image_len;
|
||||||
/* Remove urb header */
|
/* Remove urb header */
|
||||||
data += 4;
|
data += 4;
|
||||||
len -= 4;
|
len -= 4;
|
||||||
|
|
||||||
if (cur_frame_len + len <= frame->v4l2_buf.length) {
|
if (cur_frame_len + len <= gspca_dev->frsz) {
|
||||||
PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
|
PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
|
||||||
sd->frame_count, len);
|
sd->frame_count, len);
|
||||||
|
|
||||||
gspca_frame_add(gspca_dev, INTER_PACKET,
|
gspca_frame_add(gspca_dev, INTER_PACKET,
|
||||||
data, len);
|
data, len);
|
||||||
} else if (frame->v4l2_buf.length - cur_frame_len > 0) {
|
} else {
|
||||||
/* Add the remaining data up to frame size */
|
/* Add the remaining data up to frame size */
|
||||||
gspca_frame_add(gspca_dev, INTER_PACKET, data,
|
gspca_frame_add(gspca_dev, INTER_PACKET, data,
|
||||||
frame->v4l2_buf.length - cur_frame_len);
|
gspca_dev->frsz - cur_frame_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4162,7 +4162,6 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
int len) /* iso packet length */
|
int len) /* iso packet length */
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
struct gspca_frame *frame;
|
|
||||||
|
|
||||||
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
||||||
|
|
||||||
|
@ -4172,9 +4171,8 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
the sensor and bridge are still syncing, so drop it. */
|
the sensor and bridge are still syncing, so drop it. */
|
||||||
if (sd->first_frame) {
|
if (sd->first_frame) {
|
||||||
sd->first_frame--;
|
sd->first_frame--;
|
||||||
frame = gspca_get_i_frame(gspca_dev);
|
if (gspca_dev->image_len <
|
||||||
if (!frame || (frame->data_end - frame->data) <
|
sd->gspca_dev.width * sd->gspca_dev.height)
|
||||||
(sd->gspca_dev.width * sd->gspca_dev.height))
|
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
}
|
}
|
||||||
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
|
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
|
||||||
|
|
|
@ -987,13 +987,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
data + 12, len - 12);
|
data + 12, len - 12);
|
||||||
/* If this packet is marked as EOF, end the frame */
|
/* If this packet is marked as EOF, end the frame */
|
||||||
} else if (data[1] & UVC_STREAM_EOF) {
|
} else if (data[1] & UVC_STREAM_EOF) {
|
||||||
struct gspca_frame *frame;
|
|
||||||
|
|
||||||
sd->last_pts = 0;
|
sd->last_pts = 0;
|
||||||
frame = gspca_get_i_frame(gspca_dev);
|
if (gspca_dev->image == NULL)
|
||||||
if (frame == NULL)
|
|
||||||
goto discard;
|
goto discard;
|
||||||
if (frame->data_end - frame->data + (len - 12) !=
|
if (gspca_dev->image_len + len - 12 !=
|
||||||
gspca_dev->width * gspca_dev->height * 2) {
|
gspca_dev->width * gspca_dev->height * 2) {
|
||||||
PDEBUG(D_PACK, "wrong sized frame");
|
PDEBUG(D_PACK, "wrong sized frame");
|
||||||
goto discard;
|
goto discard;
|
||||||
|
|
|
@ -804,7 +804,6 @@ static const unsigned char pac_jpeg_header2[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pac_start_frame(struct gspca_dev *gspca_dev,
|
static void pac_start_frame(struct gspca_dev *gspca_dev,
|
||||||
struct gspca_frame *frame,
|
|
||||||
__u16 lines, __u16 samples_per_line)
|
__u16 lines, __u16 samples_per_line)
|
||||||
{
|
{
|
||||||
unsigned char tmpbuf[4];
|
unsigned char tmpbuf[4];
|
||||||
|
@ -829,15 +828,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
int len) /* iso packet length */
|
int len) /* iso packet length */
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
struct gspca_frame *frame;
|
u8 *image;
|
||||||
unsigned char *sof;
|
unsigned char *sof;
|
||||||
|
|
||||||
sof = pac_find_sof(&sd->sof_read, data, len);
|
sof = pac_find_sof(&sd->sof_read, data, len);
|
||||||
if (sof) {
|
if (sof) {
|
||||||
int n, lum_offset, footer_length;
|
int n, lum_offset, footer_length;
|
||||||
|
|
||||||
frame = gspca_get_i_frame(gspca_dev);
|
image = gspca_dev->image;
|
||||||
if (frame == NULL) {
|
if (image == NULL) {
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -852,16 +851,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
/* Finish decoding current frame */
|
/* Finish decoding current frame */
|
||||||
n = (sof - data) - (footer_length + sizeof pac_sof_marker);
|
n = (sof - data) - (footer_length + sizeof pac_sof_marker);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
frame->data_end += n;
|
gspca_dev->image_len += n;
|
||||||
n = 0;
|
n = 0;
|
||||||
|
} else {
|
||||||
|
gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
|
||||||
}
|
}
|
||||||
gspca_frame_add(gspca_dev, INTER_PACKET,
|
if (gspca_dev->last_packet_type != DISCARD_PACKET
|
||||||
data, n);
|
&& image[gspca_dev->image_len - 2] == 0xff
|
||||||
if (gspca_dev->last_packet_type != DISCARD_PACKET &&
|
&& image[gspca_dev->image_len - 1] == 0xd9)
|
||||||
frame->data_end[-2] == 0xff &&
|
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
|
||||||
frame->data_end[-1] == 0xd9)
|
|
||||||
gspca_frame_add(gspca_dev, LAST_PACKET,
|
|
||||||
NULL, 0);
|
|
||||||
|
|
||||||
n = sof - data;
|
n = sof - data;
|
||||||
len -= n;
|
len -= n;
|
||||||
|
@ -877,7 +875,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
|
|
||||||
/* Start the new frame with the jpeg header */
|
/* Start the new frame with the jpeg header */
|
||||||
/* The PAC7302 has the image rotated 90 degrees */
|
/* The PAC7302 has the image rotated 90 degrees */
|
||||||
pac_start_frame(gspca_dev, frame,
|
pac_start_frame(gspca_dev,
|
||||||
gspca_dev->width, gspca_dev->height);
|
gspca_dev->width, gspca_dev->height);
|
||||||
}
|
}
|
||||||
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
||||||
|
|
|
@ -599,7 +599,6 @@ static const unsigned char pac_jpeg_header2[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pac_start_frame(struct gspca_dev *gspca_dev,
|
static void pac_start_frame(struct gspca_dev *gspca_dev,
|
||||||
struct gspca_frame *frame,
|
|
||||||
__u16 lines, __u16 samples_per_line)
|
__u16 lines, __u16 samples_per_line)
|
||||||
{
|
{
|
||||||
unsigned char tmpbuf[4];
|
unsigned char tmpbuf[4];
|
||||||
|
@ -624,15 +623,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
int len) /* iso packet length */
|
int len) /* iso packet length */
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
|
u8 *image;
|
||||||
unsigned char *sof;
|
unsigned char *sof;
|
||||||
struct gspca_frame *frame;
|
|
||||||
|
|
||||||
sof = pac_find_sof(&sd->sof_read, data, len);
|
sof = pac_find_sof(&sd->sof_read, data, len);
|
||||||
if (sof) {
|
if (sof) {
|
||||||
int n, lum_offset, footer_length;
|
int n, lum_offset, footer_length;
|
||||||
|
|
||||||
frame = gspca_get_i_frame(gspca_dev);
|
image = gspca_dev->image;
|
||||||
if (frame == NULL) {
|
if (image == NULL) {
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -647,16 +646,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
/* Finish decoding current frame */
|
/* Finish decoding current frame */
|
||||||
n = (sof - data) - (footer_length + sizeof pac_sof_marker);
|
n = (sof - data) - (footer_length + sizeof pac_sof_marker);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
frame->data_end += n;
|
gspca_dev->image_len += n;
|
||||||
n = 0;
|
n = 0;
|
||||||
|
} else {
|
||||||
|
gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
|
||||||
}
|
}
|
||||||
gspca_frame_add(gspca_dev, INTER_PACKET,
|
if (gspca_dev->last_packet_type != DISCARD_PACKET
|
||||||
data, n);
|
&& image[gspca_dev->image_len - 2] == 0xff
|
||||||
if (gspca_dev->last_packet_type != DISCARD_PACKET &&
|
&& image[gspca_dev->image_len - 1] == 0xd9)
|
||||||
frame->data_end[-2] == 0xff &&
|
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
|
||||||
frame->data_end[-1] == 0xd9)
|
|
||||||
gspca_frame_add(gspca_dev, LAST_PACKET,
|
|
||||||
NULL, 0);
|
|
||||||
|
|
||||||
n = sof - data;
|
n = sof - data;
|
||||||
len -= n;
|
len -= n;
|
||||||
|
@ -671,7 +669,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
atomic_set(&sd->avg_lum, -1);
|
atomic_set(&sd->avg_lum, -1);
|
||||||
|
|
||||||
/* Start the new frame with the jpeg header */
|
/* Start the new frame with the jpeg header */
|
||||||
pac_start_frame(gspca_dev, frame,
|
pac_start_frame(gspca_dev,
|
||||||
gspca_dev->height, gspca_dev->width);
|
gspca_dev->height, gspca_dev->width);
|
||||||
}
|
}
|
||||||
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
||||||
|
|
|
@ -1251,16 +1251,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
|
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
|
||||||
/* In raw mode we sometimes get some garbage after the frame
|
/* In raw mode we sometimes get some garbage after the frame
|
||||||
ignore this */
|
ignore this */
|
||||||
struct gspca_frame *frame;
|
|
||||||
int used;
|
int used;
|
||||||
int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
|
int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
|
||||||
|
|
||||||
frame = gspca_get_i_frame(gspca_dev);
|
if (gspca_dev->image == NULL) {
|
||||||
if (frame == NULL) {
|
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
used = frame->data_end - frame->data;
|
used = gspca_dev->image_len;
|
||||||
if (used + len > size)
|
if (used + len > size)
|
||||||
len = size - used;
|
len = size - used;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3726,17 +3726,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
/* The vc0321 sends some additional data after sending the complete
|
/* The vc0321 sends some additional data after sending the complete
|
||||||
* frame, we ignore this. */
|
* frame, we ignore this. */
|
||||||
if (sd->bridge == BRIDGE_VC0321) {
|
if (sd->bridge == BRIDGE_VC0321) {
|
||||||
struct gspca_frame *frame;
|
int size, l;
|
||||||
int l;
|
|
||||||
|
|
||||||
frame = gspca_get_i_frame(gspca_dev);
|
if (gspca_dev->image == NULL) {
|
||||||
if (frame == NULL) {
|
|
||||||
gspca_dev->last_packet_type = DISCARD_PACKET;
|
gspca_dev->last_packet_type = DISCARD_PACKET;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
l = frame->data_end - frame->data;
|
l = gspca_dev->image_len;
|
||||||
if (len > frame->v4l2_buf.length - l)
|
size = gspca_dev->frsz;
|
||||||
len = frame->v4l2_buf.length - l;
|
if (len > size - l)
|
||||||
|
len = size - l;
|
||||||
}
|
}
|
||||||
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue