From b192ca983746585e807259414f8d6f58cb28311f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Fran=C3=A7ois=20Moine?= Date: Sun, 27 Jun 2010 03:08:19 -0300 Subject: [PATCH] V4L/DVB: gspca - main: Simplify image building MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/cpia1.c | 15 ++--- drivers/media/video/gspca/gspca.c | 65 +++++++++----------- drivers/media/video/gspca/gspca.h | 5 +- drivers/media/video/gspca/m5602/m5602_core.c | 12 ++-- drivers/media/video/gspca/ov519.c | 6 +- drivers/media/video/gspca/ov534.c | 7 +-- drivers/media/video/gspca/pac7302.c | 24 ++++---- drivers/media/video/gspca/pac7311.c | 24 ++++---- drivers/media/video/gspca/sonixb.c | 6 +- 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 58b696f455b..4b3ea3b4bbb 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, data[25] == sd->params.roi.colEnd && data[26] == sd->params.roi.rowStart && 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->fps, data[41]); - if (frame == NULL) { + image = gspca_dev->image; + if (image == NULL) { gspca_dev->last_packet_type = DISCARD_PACKET; return; } /* Check for proper EOF for last frame */ - if ((frame->data_end - frame->data) > 4 && - frame->data_end[-4] == 0xff && - frame->data_end[-3] == 0xff && - frame->data_end[-2] == 0xff && - frame->data_end[-1] == 0xff) + if (gspca_dev->image_len > 4 && + image[gspca_dev->image_len - 4] == 0xff && + image[gspca_dev->image_len - 3] == 0xff && + image[gspca_dev->image_len - 2] == 0xff && + image[gspca_dev->image_len - 1] == 0xff) gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 69b1058daee..8e822ed4435 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) } #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 */ @@ -328,6 +315,8 @@ static void fill_frame(struct gspca_dev *gspca_dev, urb->status = 0; goto resubmit; } + if (gspca_dev->image == NULL) + gspca_dev->last_packet_type = DISCARD_PACKET; pkt_scan = gspca_dev->sd_desc->pkt_scan; 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); /* check the availability of the frame buffer */ - frame = gspca_dev->cur_frame; - if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) - != V4L2_BUF_FLAG_QUEUED) { - gspca_dev->last_packet_type = DISCARD_PACKET; + if (gspca_dev->image == NULL) return; - } - /* when start of a new frame, if the current frame buffer - * is not queued, discard the whole frame */ 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.sequence = ++gspca_dev->sequence; + gspca_dev->image_len = 0; } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { if (packet_type == LAST_PACKET) 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 */ if (len > 0) { - if (frame->data_end - frame->data + len - > frame->v4l2_buf.length) { - PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d", - frame->data_end - frame->data + len, - frame->v4l2_buf.length); + if (gspca_dev->image_len + len > gspca_dev->frsz) { + PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d", + gspca_dev->image_len + len, + gspca_dev->frsz); packet_type = DISCARD_PACKET; } else { - memcpy(frame->data_end, data, len); - frame->data_end += len; + memcpy(gspca_dev->image + gspca_dev->image_len, + data, len); + gspca_dev->image_len += len; } } gspca_dev->last_packet_type = packet_type; /* if last packet, wake up the application and advance in the queue */ 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_DONE; 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; PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", frame->v4l2_buf.bytesused, @@ -488,7 +477,13 @@ void gspca_frame_add(struct gspca_dev *gspca_dev, i, gspca_dev->fr_o); 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); @@ -535,12 +530,12 @@ static int frame_alloc(struct gspca_dev *gspca_dev, frame->v4l2_buf.length = frsz; frame->v4l2_buf.memory = gspca_dev->memory; frame->v4l2_buf.sequence = 0; - frame->data = frame->data_end = - gspca_dev->frbuf + i * frsz; + frame->data = gspca_dev->frbuf + i * frsz; frame->v4l2_buf.m.offset = i * frsz; } 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->sequence = 0; return 0; @@ -1948,7 +1943,7 @@ static int vidioc_qbuf(struct file *file, void *priv, i = gspca_dev->fr_q; gspca_dev->fr_queue[i] = index; 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; PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d", gspca_dev->fr_q, diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index d181064653b..453e43d66a8 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -147,7 +147,6 @@ enum gspca_packet_type { struct gspca_frame { __u8 *data; /* frame buffer */ - __u8 *data_end; /* end of frame while filling */ int vma_use_count; struct v4l2_buffer v4l2_buf; }; @@ -176,8 +175,9 @@ struct gspca_dev { __u8 *frbuf; /* buffer for nframes */ 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 image_len; /* current length of image */ char nframes; /* number of frames */ char fr_i; /* frame being filled */ 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, const u8 *data, int len); -struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev); #ifdef CONFIG_PM int gspca_suspend(struct usb_interface *intf, pm_message_t message); 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 4294c75e3b1..0c4ad5a5642 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, sd->frame_count); } else { - struct gspca_frame *frame; int cur_frame_len; - frame = gspca_get_i_frame(gspca_dev); - if (frame == NULL) { + if (gspca_dev->image == NULL) { gspca_dev->last_packet_type = DISCARD_PACKET; return; } - cur_frame_len = frame->data_end - frame->data; + cur_frame_len = gspca_dev->image_len; /* Remove urb header */ data += 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", sd->frame_count, len); gspca_frame_add(gspca_dev, INTER_PACKET, data, len); - } else if (frame->v4l2_buf.length - cur_frame_len > 0) { + } else { /* Add the remaining data up to frame size */ gspca_frame_add(gspca_dev, INTER_PACKET, data, - frame->v4l2_buf.length - cur_frame_len); + gspca_dev->frsz - cur_frame_len); } } } diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 2e7df66a84b..2b2cbdbf03f 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, int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; - struct gspca_frame *frame; 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. */ if (sd->first_frame) { sd->first_frame--; - frame = gspca_get_i_frame(gspca_dev); - if (!frame || (frame->data_end - frame->data) < - (sd->gspca_dev.width * sd->gspca_dev.height)) + if (gspca_dev->image_len < + sd->gspca_dev.width * sd->gspca_dev.height) gspca_dev->last_packet_type = DISCARD_PACKET; } 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 dc1e4efe30f..84c9b8dbded 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, data + 12, len - 12); /* If this packet is marked as EOF, end the frame */ } else if (data[1] & UVC_STREAM_EOF) { - struct gspca_frame *frame; - sd->last_pts = 0; - frame = gspca_get_i_frame(gspca_dev); - if (frame == NULL) + if (gspca_dev->image == NULL) goto discard; - if (frame->data_end - frame->data + (len - 12) != + if (gspca_dev->image_len + len - 12 != gspca_dev->width * gspca_dev->height * 2) { PDEBUG(D_PACK, "wrong sized frame"); goto discard; diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index bf47180a4e2..88cc03bb3f9 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[] = { }; static void pac_start_frame(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, __u16 lines, __u16 samples_per_line) { unsigned char tmpbuf[4]; @@ -829,15 +828,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; - struct gspca_frame *frame; + u8 *image; unsigned char *sof; sof = pac_find_sof(&sd->sof_read, data, len); if (sof) { int n, lum_offset, footer_length; - frame = gspca_get_i_frame(gspca_dev); - if (frame == NULL) { + image = gspca_dev->image; + if (image == NULL) { gspca_dev->last_packet_type = DISCARD_PACKET; return; } @@ -852,16 +851,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* Finish decoding current frame */ n = (sof - data) - (footer_length + sizeof pac_sof_marker); if (n < 0) { - frame->data_end += n; + gspca_dev->image_len += n; n = 0; + } else { + gspca_frame_add(gspca_dev, INTER_PACKET, data, n); } - gspca_frame_add(gspca_dev, INTER_PACKET, - data, n); - if (gspca_dev->last_packet_type != DISCARD_PACKET && - frame->data_end[-2] == 0xff && - frame->data_end[-1] == 0xd9) - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); + if (gspca_dev->last_packet_type != DISCARD_PACKET + && image[gspca_dev->image_len - 2] == 0xff + && image[gspca_dev->image_len - 1] == 0xd9) + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); n = sof - data; len -= n; @@ -877,7 +875,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* Start the new frame with the jpeg header */ /* 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_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 c978599a69d..5568c41a296 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[] = { }; static void pac_start_frame(struct gspca_dev *gspca_dev, - struct gspca_frame *frame, __u16 lines, __u16 samples_per_line) { unsigned char tmpbuf[4]; @@ -624,15 +623,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; + u8 *image; unsigned char *sof; - struct gspca_frame *frame; sof = pac_find_sof(&sd->sof_read, data, len); if (sof) { int n, lum_offset, footer_length; - frame = gspca_get_i_frame(gspca_dev); - if (frame == NULL) { + image = gspca_dev->image; + if (image == NULL) { gspca_dev->last_packet_type = DISCARD_PACKET; return; } @@ -647,16 +646,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, /* Finish decoding current frame */ n = (sof - data) - (footer_length + sizeof pac_sof_marker); if (n < 0) { - frame->data_end += n; + gspca_dev->image_len += n; n = 0; + } else { + gspca_frame_add(gspca_dev, INTER_PACKET, data, n); } - gspca_frame_add(gspca_dev, INTER_PACKET, - data, n); - if (gspca_dev->last_packet_type != DISCARD_PACKET && - frame->data_end[-2] == 0xff && - frame->data_end[-1] == 0xd9) - gspca_frame_add(gspca_dev, LAST_PACKET, - NULL, 0); + if (gspca_dev->last_packet_type != DISCARD_PACKET + && image[gspca_dev->image_len - 2] == 0xff + && image[gspca_dev->image_len - 1] == 0xd9) + gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); n = sof - data; len -= n; @@ -671,7 +669,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, atomic_set(&sd->avg_lum, -1); /* 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_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 95354a339e3..4989a2c779e 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, if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) { /* In raw mode we sometimes get some garbage after the frame ignore this */ - struct gspca_frame *frame; int used; int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage; - frame = gspca_get_i_frame(gspca_dev); - if (frame == NULL) { + if (gspca_dev->image == NULL) { gspca_dev->last_packet_type = DISCARD_PACKET; return; } - used = frame->data_end - frame->data; + used = gspca_dev->image_len; if (used + len > size) len = size - used; } diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 732c3dfe46f..0a7d1e0866d 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, /* The vc0321 sends some additional data after sending the complete * frame, we ignore this. */ if (sd->bridge == BRIDGE_VC0321) { - struct gspca_frame *frame; - int l; + int size, l; - frame = gspca_get_i_frame(gspca_dev); - if (frame == NULL) { + if (gspca_dev->image == NULL) { gspca_dev->last_packet_type = DISCARD_PACKET; return; } - l = frame->data_end - frame->data; - if (len > frame->v4l2_buf.length - l) - len = frame->v4l2_buf.length - l; + l = gspca_dev->image_len; + size = gspca_dev->frsz; + if (len > size - l) + len = size - l; } gspca_frame_add(gspca_dev, INTER_PACKET, data, len); } -- 2.43.2