aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2010-06-27 02:08:19 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-02 14:31:10 -0400
commitb192ca983746585e807259414f8d6f58cb28311f (patch)
tree8c95bdcebcf4217e3813d803ecf281af2d431e5f /drivers
parentc6dc725c8e0c3438587e18f918f6da16e7a23539 (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/gspca/cpia1.c15
-rw-r--r--drivers/media/video/gspca/gspca.c65
-rw-r--r--drivers/media/video/gspca/gspca.h5
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c12
-rw-r--r--drivers/media/video/gspca/ov519.c6
-rw-r--r--drivers/media/video/gspca/ov534.c7
-rw-r--r--drivers/media/video/gspca/pac7302.c24
-rw-r--r--drivers/media/video/gspca/pac7311.c24
-rw-r--r--drivers/media/video/gspca/sonixb.c6
-rw-r--r--drivers/media/video/gspca/vc032x.c13
10 files changed, 79 insertions, 98 deletions
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 58b696f455be..4b3ea3b4bbba 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -1760,22 +1760,23 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1760 data[25] == sd->params.roi.colEnd && 1760 data[25] == sd->params.roi.colEnd &&
1761 data[26] == sd->params.roi.rowStart && 1761 data[26] == sd->params.roi.rowStart &&
1762 data[27] == sd->params.roi.rowEnd) { 1762 data[27] == sd->params.roi.rowEnd) {
1763 struct gspca_frame *frame = gspca_get_i_frame(gspca_dev); 1763 u8 *image;
1764 1764
1765 atomic_set(&sd->cam_exposure, data[39] * 2); 1765 atomic_set(&sd->cam_exposure, data[39] * 2);
1766 atomic_set(&sd->fps, data[41]); 1766 atomic_set(&sd->fps, data[41]);
1767 1767
1768 if (frame == NULL) { 1768 image = gspca_dev->image;
1769 if (image == NULL) {
1769 gspca_dev->last_packet_type = DISCARD_PACKET; 1770 gspca_dev->last_packet_type = DISCARD_PACKET;
1770 return; 1771 return;
1771 } 1772 }
1772 1773
1773 /* Check for proper EOF for last frame */ 1774 /* Check for proper EOF for last frame */
1774 if ((frame->data_end - frame->data) > 4 && 1775 if (gspca_dev->image_len > 4 &&
1775 frame->data_end[-4] == 0xff && 1776 image[gspca_dev->image_len - 4] == 0xff &&
1776 frame->data_end[-3] == 0xff && 1777 image[gspca_dev->image_len - 3] == 0xff &&
1777 frame->data_end[-2] == 0xff && 1778 image[gspca_dev->image_len - 2] == 0xff &&
1778 frame->data_end[-1] == 0xff) 1779 image[gspca_dev->image_len - 1] == 0xff)
1779 gspca_frame_add(gspca_dev, LAST_PACKET, 1780 gspca_frame_add(gspca_dev, LAST_PACKET,
1780 NULL, 0); 1781 NULL, 0);
1781 1782
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 69b1058daeeb..8e822ed4435f 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -294,19 +294,6 @@ static inline int gspca_input_connect(struct gspca_dev *dev)
294} 294}
295#endif 295#endif
296 296
297/* get the current input frame buffer */
298struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
299{
300 struct gspca_frame *frame;
301
302 frame = gspca_dev->cur_frame;
303 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
304 != V4L2_BUF_FLAG_QUEUED)
305 return NULL;
306 return frame;
307}
308EXPORT_SYMBOL(gspca_get_i_frame);
309
310/* 297/*
311 * fill a video frame from an URB and resubmit 298 * fill a video frame from an URB and resubmit
312 */ 299 */
@@ -328,6 +315,8 @@ static void fill_frame(struct gspca_dev *gspca_dev,
328 urb->status = 0; 315 urb->status = 0;
329 goto resubmit; 316 goto resubmit;
330 } 317 }
318 if (gspca_dev->image == NULL)
319 gspca_dev->last_packet_type = DISCARD_PACKET;
331 pkt_scan = gspca_dev->sd_desc->pkt_scan; 320 pkt_scan = gspca_dev->sd_desc->pkt_scan;
332 for (i = 0; i < urb->number_of_packets; i++) { 321 for (i = 0; i < urb->number_of_packets; i++) {
333 322
@@ -440,19 +429,16 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
440 PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); 429 PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
441 430
442 /* check the availability of the frame buffer */ 431 /* check the availability of the frame buffer */
443 frame = gspca_dev->cur_frame; 432 if (gspca_dev->image == NULL)
444 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
445 != V4L2_BUF_FLAG_QUEUED) {
446 gspca_dev->last_packet_type = DISCARD_PACKET;
447 return; 433 return;
448 }
449 434
450 /* when start of a new frame, if the current frame buffer
451 * is not queued, discard the whole frame */
452 if (packet_type == FIRST_PACKET) { 435 if (packet_type == FIRST_PACKET) {
453 frame->data_end = frame->data; 436 i = gspca_dev->fr_i;
437 j = gspca_dev->fr_queue[i];
438 frame = &gspca_dev->frame[j];
454 frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get()); 439 frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());
455 frame->v4l2_buf.sequence = ++gspca_dev->sequence; 440 frame->v4l2_buf.sequence = ++gspca_dev->sequence;
441 gspca_dev->image_len = 0;
456 } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { 442 } else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
457 if (packet_type == LAST_PACKET) 443 if (packet_type == LAST_PACKET)
458 gspca_dev->last_packet_type = packet_type; 444 gspca_dev->last_packet_type = packet_type;
@@ -461,26 +447,29 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
461 447
462 /* append the packet to the frame buffer */ 448 /* append the packet to the frame buffer */
463 if (len > 0) { 449 if (len > 0) {
464 if (frame->data_end - frame->data + len 450 if (gspca_dev->image_len + len > gspca_dev->frsz) {
465 > frame->v4l2_buf.length) { 451 PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d",
466 PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d", 452 gspca_dev->image_len + len,
467 frame->data_end - frame->data + len, 453 gspca_dev->frsz);
468 frame->v4l2_buf.length);
469 packet_type = DISCARD_PACKET; 454 packet_type = DISCARD_PACKET;
470 } else { 455 } else {
471 memcpy(frame->data_end, data, len); 456 memcpy(gspca_dev->image + gspca_dev->image_len,
472 frame->data_end += len; 457 data, len);
458 gspca_dev->image_len += len;
473 } 459 }
474 } 460 }
475 gspca_dev->last_packet_type = packet_type; 461 gspca_dev->last_packet_type = packet_type;
476 462
477 /* if last packet, wake up the application and advance in the queue */ 463 /* if last packet, wake up the application and advance in the queue */
478 if (packet_type == LAST_PACKET) { 464 if (packet_type == LAST_PACKET) {
479 frame->v4l2_buf.bytesused = frame->data_end - frame->data; 465 i = gspca_dev->fr_i;
466 j = gspca_dev->fr_queue[i];
467 frame = &gspca_dev->frame[j];
468 frame->v4l2_buf.bytesused = gspca_dev->image_len;
480 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; 469 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
481 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; 470 frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
482 wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ 471 wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
483 i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; 472 i = (i + 1) % gspca_dev->nframes;
484 gspca_dev->fr_i = i; 473 gspca_dev->fr_i = i;
485 PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", 474 PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d",
486 frame->v4l2_buf.bytesused, 475 frame->v4l2_buf.bytesused,
@@ -488,7 +477,13 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
488 i, 477 i,
489 gspca_dev->fr_o); 478 gspca_dev->fr_o);
490 j = gspca_dev->fr_queue[i]; 479 j = gspca_dev->fr_queue[i];
491 gspca_dev->cur_frame = &gspca_dev->frame[j]; 480 frame = &gspca_dev->frame[j];
481 if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
482 == V4L2_BUF_FLAG_QUEUED) {
483 gspca_dev->image = frame->data;
484 } else {
485 gspca_dev->image = NULL;
486 }
492 } 487 }
493} 488}
494EXPORT_SYMBOL(gspca_frame_add); 489EXPORT_SYMBOL(gspca_frame_add);
@@ -535,12 +530,12 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
535 frame->v4l2_buf.length = frsz; 530 frame->v4l2_buf.length = frsz;
536 frame->v4l2_buf.memory = gspca_dev->memory; 531 frame->v4l2_buf.memory = gspca_dev->memory;
537 frame->v4l2_buf.sequence = 0; 532 frame->v4l2_buf.sequence = 0;
538 frame->data = frame->data_end = 533 frame->data = gspca_dev->frbuf + i * frsz;
539 gspca_dev->frbuf + i * frsz;
540 frame->v4l2_buf.m.offset = i * frsz; 534 frame->v4l2_buf.m.offset = i * frsz;
541 } 535 }
542 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; 536 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
543 gspca_dev->cur_frame = &gspca_dev->frame[0]; 537 gspca_dev->image = NULL;
538 gspca_dev->image_len = 0;
544 gspca_dev->last_packet_type = DISCARD_PACKET; 539 gspca_dev->last_packet_type = DISCARD_PACKET;
545 gspca_dev->sequence = 0; 540 gspca_dev->sequence = 0;
546 return 0; 541 return 0;
@@ -1948,7 +1943,7 @@ static int vidioc_qbuf(struct file *file, void *priv,
1948 i = gspca_dev->fr_q; 1943 i = gspca_dev->fr_q;
1949 gspca_dev->fr_queue[i] = index; 1944 gspca_dev->fr_queue[i] = index;
1950 if (gspca_dev->fr_i == i) 1945 if (gspca_dev->fr_i == i)
1951 gspca_dev->cur_frame = frame; 1946 gspca_dev->image = frame->data;
1952 gspca_dev->fr_q = (i + 1) % gspca_dev->nframes; 1947 gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
1953 PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d", 1948 PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
1954 gspca_dev->fr_q, 1949 gspca_dev->fr_q,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index d181064653b7..453e43d66a83 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -147,7 +147,6 @@ enum gspca_packet_type {
147 147
148struct gspca_frame { 148struct gspca_frame {
149 __u8 *data; /* frame buffer */ 149 __u8 *data; /* frame buffer */
150 __u8 *data_end; /* end of frame while filling */
151 int vma_use_count; 150 int vma_use_count;
152 struct v4l2_buffer v4l2_buf; 151 struct v4l2_buffer v4l2_buf;
153}; 152};
@@ -176,8 +175,9 @@ struct gspca_dev {
176 175
177 __u8 *frbuf; /* buffer for nframes */ 176 __u8 *frbuf; /* buffer for nframes */
178 struct gspca_frame frame[GSPCA_MAX_FRAMES]; 177 struct gspca_frame frame[GSPCA_MAX_FRAMES];
179 struct gspca_frame *cur_frame; /* frame beeing filled */ 178 u8 *image; /* image beeing filled */
180 __u32 frsz; /* frame size */ 179 __u32 frsz; /* frame size */
180 u32 image_len; /* current length of image */
181 char nframes; /* number of frames */ 181 char nframes; /* number of frames */
182 char fr_i; /* frame being filled */ 182 char fr_i; /* frame being filled */
183 char fr_q; /* next frame to queue */ 183 char fr_q; /* next frame to queue */
@@ -226,7 +226,6 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
226 enum gspca_packet_type packet_type, 226 enum gspca_packet_type packet_type,
227 const u8 *data, 227 const u8 *data,
228 int len); 228 int len);
229struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
230#ifdef CONFIG_PM 229#ifdef CONFIG_PM
231int gspca_suspend(struct usb_interface *intf, pm_message_t message); 230int gspca_suspend(struct usb_interface *intf, pm_message_t message);
232int gspca_resume(struct usb_interface *intf); 231int gspca_resume(struct usb_interface *intf);
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 4294c75e3b11..0c4ad5a5642a 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -305,30 +305,28 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
305 sd->frame_count); 305 sd->frame_count);
306 306
307 } else { 307 } else {
308 struct gspca_frame *frame;
309 int cur_frame_len; 308 int cur_frame_len;
310 309
311 frame = gspca_get_i_frame(gspca_dev); 310 if (gspca_dev->image == NULL) {
312 if (frame == NULL) {
313 gspca_dev->last_packet_type = DISCARD_PACKET; 311 gspca_dev->last_packet_type = DISCARD_PACKET;
314 return; 312 return;
315 } 313 }
316 314
317 cur_frame_len = frame->data_end - frame->data; 315 cur_frame_len = gspca_dev->image_len;
318 /* Remove urb header */ 316 /* Remove urb header */
319 data += 4; 317 data += 4;
320 len -= 4; 318 len -= 4;
321 319
322 if (cur_frame_len + len <= frame->v4l2_buf.length) { 320 if (cur_frame_len + len <= gspca_dev->frsz) {
323 PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes", 321 PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
324 sd->frame_count, len); 322 sd->frame_count, len);
325 323
326 gspca_frame_add(gspca_dev, INTER_PACKET, 324 gspca_frame_add(gspca_dev, INTER_PACKET,
327 data, len); 325 data, len);
328 } else if (frame->v4l2_buf.length - cur_frame_len > 0) { 326 } else {
329 /* Add the remaining data up to frame size */ 327 /* Add the remaining data up to frame size */
330 gspca_frame_add(gspca_dev, INTER_PACKET, data, 328 gspca_frame_add(gspca_dev, INTER_PACKET, data,
331 frame->v4l2_buf.length - cur_frame_len); 329 gspca_dev->frsz - cur_frame_len);
332 } 330 }
333 } 331 }
334} 332}
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 2e7df66a84b9..2b2cbdbf03fe 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -4162,7 +4162,6 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
4162 int len) /* iso packet length */ 4162 int len) /* iso packet length */
4163{ 4163{
4164 struct sd *sd = (struct sd *) gspca_dev; 4164 struct sd *sd = (struct sd *) gspca_dev;
4165 struct gspca_frame *frame;
4166 4165
4167 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 4166 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
4168 4167
@@ -4172,9 +4171,8 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
4172 the sensor and bridge are still syncing, so drop it. */ 4171 the sensor and bridge are still syncing, so drop it. */
4173 if (sd->first_frame) { 4172 if (sd->first_frame) {
4174 sd->first_frame--; 4173 sd->first_frame--;
4175 frame = gspca_get_i_frame(gspca_dev); 4174 if (gspca_dev->image_len <
4176 if (!frame || (frame->data_end - frame->data) < 4175 sd->gspca_dev.width * sd->gspca_dev.height)
4177 (sd->gspca_dev.width * sd->gspca_dev.height))
4178 gspca_dev->last_packet_type = DISCARD_PACKET; 4176 gspca_dev->last_packet_type = DISCARD_PACKET;
4179 } 4177 }
4180 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 4178 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index dc1e4efe30fb..84c9b8dbded6 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -987,13 +987,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
987 data + 12, len - 12); 987 data + 12, len - 12);
988 /* If this packet is marked as EOF, end the frame */ 988 /* If this packet is marked as EOF, end the frame */
989 } else if (data[1] & UVC_STREAM_EOF) { 989 } else if (data[1] & UVC_STREAM_EOF) {
990 struct gspca_frame *frame;
991
992 sd->last_pts = 0; 990 sd->last_pts = 0;
993 frame = gspca_get_i_frame(gspca_dev); 991 if (gspca_dev->image == NULL)
994 if (frame == NULL)
995 goto discard; 992 goto discard;
996 if (frame->data_end - frame->data + (len - 12) != 993 if (gspca_dev->image_len + len - 12 !=
997 gspca_dev->width * gspca_dev->height * 2) { 994 gspca_dev->width * gspca_dev->height * 2) {
998 PDEBUG(D_PACK, "wrong sized frame"); 995 PDEBUG(D_PACK, "wrong sized frame");
999 goto discard; 996 goto discard;
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index bf47180a4e2f..88cc03bb3f94 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -804,7 +804,6 @@ static const unsigned char pac_jpeg_header2[] = {
804}; 804};
805 805
806static void pac_start_frame(struct gspca_dev *gspca_dev, 806static void pac_start_frame(struct gspca_dev *gspca_dev,
807 struct gspca_frame *frame,
808 __u16 lines, __u16 samples_per_line) 807 __u16 lines, __u16 samples_per_line)
809{ 808{
810 unsigned char tmpbuf[4]; 809 unsigned char tmpbuf[4];
@@ -829,15 +828,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
829 int len) /* iso packet length */ 828 int len) /* iso packet length */
830{ 829{
831 struct sd *sd = (struct sd *) gspca_dev; 830 struct sd *sd = (struct sd *) gspca_dev;
832 struct gspca_frame *frame; 831 u8 *image;
833 unsigned char *sof; 832 unsigned char *sof;
834 833
835 sof = pac_find_sof(&sd->sof_read, data, len); 834 sof = pac_find_sof(&sd->sof_read, data, len);
836 if (sof) { 835 if (sof) {
837 int n, lum_offset, footer_length; 836 int n, lum_offset, footer_length;
838 837
839 frame = gspca_get_i_frame(gspca_dev); 838 image = gspca_dev->image;
840 if (frame == NULL) { 839 if (image == NULL) {
841 gspca_dev->last_packet_type = DISCARD_PACKET; 840 gspca_dev->last_packet_type = DISCARD_PACKET;
842 return; 841 return;
843 } 842 }
@@ -852,16 +851,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
852 /* Finish decoding current frame */ 851 /* Finish decoding current frame */
853 n = (sof - data) - (footer_length + sizeof pac_sof_marker); 852 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
854 if (n < 0) { 853 if (n < 0) {
855 frame->data_end += n; 854 gspca_dev->image_len += n;
856 n = 0; 855 n = 0;
856 } else {
857 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
857 } 858 }
858 gspca_frame_add(gspca_dev, INTER_PACKET, 859 if (gspca_dev->last_packet_type != DISCARD_PACKET
859 data, n); 860 && image[gspca_dev->image_len - 2] == 0xff
860 if (gspca_dev->last_packet_type != DISCARD_PACKET && 861 && image[gspca_dev->image_len - 1] == 0xd9)
861 frame->data_end[-2] == 0xff && 862 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
862 frame->data_end[-1] == 0xd9)
863 gspca_frame_add(gspca_dev, LAST_PACKET,
864 NULL, 0);
865 863
866 n = sof - data; 864 n = sof - data;
867 len -= n; 865 len -= n;
@@ -877,7 +875,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
877 875
878 /* Start the new frame with the jpeg header */ 876 /* Start the new frame with the jpeg header */
879 /* The PAC7302 has the image rotated 90 degrees */ 877 /* The PAC7302 has the image rotated 90 degrees */
880 pac_start_frame(gspca_dev, frame, 878 pac_start_frame(gspca_dev,
881 gspca_dev->width, gspca_dev->height); 879 gspca_dev->width, gspca_dev->height);
882 } 880 }
883 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 881 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index c978599a69dd..5568c41a296c 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -599,7 +599,6 @@ static const unsigned char pac_jpeg_header2[] = {
599}; 599};
600 600
601static void pac_start_frame(struct gspca_dev *gspca_dev, 601static void pac_start_frame(struct gspca_dev *gspca_dev,
602 struct gspca_frame *frame,
603 __u16 lines, __u16 samples_per_line) 602 __u16 lines, __u16 samples_per_line)
604{ 603{
605 unsigned char tmpbuf[4]; 604 unsigned char tmpbuf[4];
@@ -624,15 +623,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
624 int len) /* iso packet length */ 623 int len) /* iso packet length */
625{ 624{
626 struct sd *sd = (struct sd *) gspca_dev; 625 struct sd *sd = (struct sd *) gspca_dev;
626 u8 *image;
627 unsigned char *sof; 627 unsigned char *sof;
628 struct gspca_frame *frame;
629 628
630 sof = pac_find_sof(&sd->sof_read, data, len); 629 sof = pac_find_sof(&sd->sof_read, data, len);
631 if (sof) { 630 if (sof) {
632 int n, lum_offset, footer_length; 631 int n, lum_offset, footer_length;
633 632
634 frame = gspca_get_i_frame(gspca_dev); 633 image = gspca_dev->image;
635 if (frame == NULL) { 634 if (image == NULL) {
636 gspca_dev->last_packet_type = DISCARD_PACKET; 635 gspca_dev->last_packet_type = DISCARD_PACKET;
637 return; 636 return;
638 } 637 }
@@ -647,16 +646,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
647 /* Finish decoding current frame */ 646 /* Finish decoding current frame */
648 n = (sof - data) - (footer_length + sizeof pac_sof_marker); 647 n = (sof - data) - (footer_length + sizeof pac_sof_marker);
649 if (n < 0) { 648 if (n < 0) {
650 frame->data_end += n; 649 gspca_dev->image_len += n;
651 n = 0; 650 n = 0;
651 } else {
652 gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
652 } 653 }
653 gspca_frame_add(gspca_dev, INTER_PACKET, 654 if (gspca_dev->last_packet_type != DISCARD_PACKET
654 data, n); 655 && image[gspca_dev->image_len - 2] == 0xff
655 if (gspca_dev->last_packet_type != DISCARD_PACKET && 656 && image[gspca_dev->image_len - 1] == 0xd9)
656 frame->data_end[-2] == 0xff && 657 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
657 frame->data_end[-1] == 0xd9)
658 gspca_frame_add(gspca_dev, LAST_PACKET,
659 NULL, 0);
660 658
661 n = sof - data; 659 n = sof - data;
662 len -= n; 660 len -= n;
@@ -671,7 +669,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
671 atomic_set(&sd->avg_lum, -1); 669 atomic_set(&sd->avg_lum, -1);
672 670
673 /* Start the new frame with the jpeg header */ 671 /* Start the new frame with the jpeg header */
674 pac_start_frame(gspca_dev, frame, 672 pac_start_frame(gspca_dev,
675 gspca_dev->height, gspca_dev->width); 673 gspca_dev->height, gspca_dev->width);
676 } 674 }
677 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 675 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 95354a339e3d..4989a2c779e5 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -1251,16 +1251,14 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1251 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { 1251 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1252 /* In raw mode we sometimes get some garbage after the frame 1252 /* In raw mode we sometimes get some garbage after the frame
1253 ignore this */ 1253 ignore this */
1254 struct gspca_frame *frame;
1255 int used; 1254 int used;
1256 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage; 1255 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1257 1256
1258 frame = gspca_get_i_frame(gspca_dev); 1257 if (gspca_dev->image == NULL) {
1259 if (frame == NULL) {
1260 gspca_dev->last_packet_type = DISCARD_PACKET; 1258 gspca_dev->last_packet_type = DISCARD_PACKET;
1261 return; 1259 return;
1262 } 1260 }
1263 used = frame->data_end - frame->data; 1261 used = gspca_dev->image_len;
1264 if (used + len > size) 1262 if (used + len > size)
1265 len = size - used; 1263 len = size - used;
1266 } 1264 }
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 732c3dfe46ff..0a7d1e0866d2 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -3726,17 +3726,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
3726 /* The vc0321 sends some additional data after sending the complete 3726 /* The vc0321 sends some additional data after sending the complete
3727 * frame, we ignore this. */ 3727 * frame, we ignore this. */
3728 if (sd->bridge == BRIDGE_VC0321) { 3728 if (sd->bridge == BRIDGE_VC0321) {
3729 struct gspca_frame *frame; 3729 int size, l;
3730 int l;
3731 3730
3732 frame = gspca_get_i_frame(gspca_dev); 3731 if (gspca_dev->image == NULL) {
3733 if (frame == NULL) {
3734 gspca_dev->last_packet_type = DISCARD_PACKET; 3732 gspca_dev->last_packet_type = DISCARD_PACKET;
3735 return; 3733 return;
3736 } 3734 }
3737 l = frame->data_end - frame->data; 3735 l = gspca_dev->image_len;
3738 if (len > frame->v4l2_buf.length - l) 3736 size = gspca_dev->frsz;
3739 len = frame->v4l2_buf.length - l; 3737 if (len > size - l)
3738 len = size - l;
3740 } 3739 }
3741 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 3740 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
3742} 3741}