aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/gspca.c
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/media/video/gspca/gspca.c
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/media/video/gspca/gspca.c')
-rw-r--r--drivers/media/video/gspca/gspca.c65
1 files changed, 30 insertions, 35 deletions
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,