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/gspca.c | |
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/gspca.c')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 65 |
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 */ | ||
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, |