diff options
author | Jean-François Moine <moinejf@free.fr> | 2010-06-27 02:08:19 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-02 14:31:10 -0400 |
commit | b192ca983746585e807259414f8d6f58cb28311f (patch) | |
tree | 8c95bdcebcf4217e3813d803ecf281af2d431e5f /drivers/media/video/gspca | |
parent | c6dc725c8e0c3438587e18f918f6da16e7a23539 (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/media/video/gspca')
-rw-r--r-- | drivers/media/video/gspca/cpia1.c | 15 | ||||
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 65 | ||||
-rw-r--r-- | drivers/media/video/gspca/gspca.h | 5 | ||||
-rw-r--r-- | drivers/media/video/gspca/m5602/m5602_core.c | 12 | ||||
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 6 | ||||
-rw-r--r-- | drivers/media/video/gspca/ov534.c | 7 | ||||
-rw-r--r-- | drivers/media/video/gspca/pac7302.c | 24 | ||||
-rw-r--r-- | drivers/media/video/gspca/pac7311.c | 24 | ||||
-rw-r--r-- | drivers/media/video/gspca/sonixb.c | 6 | ||||
-rw-r--r-- | drivers/media/video/gspca/vc032x.c | 13 |
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 */ | ||
298 | struct 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 | } | ||
308 | EXPORT_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 | } |
494 | EXPORT_SYMBOL(gspca_frame_add); | 489 | EXPORT_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 | ||
148 | struct gspca_frame { | 148 | struct 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); |
229 | struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev); | ||
230 | #ifdef CONFIG_PM | 229 | #ifdef CONFIG_PM |
231 | int gspca_suspend(struct usb_interface *intf, pm_message_t message); | 230 | int gspca_suspend(struct usb_interface *intf, pm_message_t message); |
232 | int gspca_resume(struct usb_interface *intf); | 231 | int 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 | ||
806 | static void pac_start_frame(struct gspca_dev *gspca_dev, | 806 | static 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 | ||
601 | static void pac_start_frame(struct gspca_dev *gspca_dev, | 601 | static 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 | } |