V4L/DVB: gspca - main: Simplify image building
authorJean-François Moine <moinejf@free.fr>
Sun, 27 Jun 2010 06:08:19 +0000 (03:08 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 2 Aug 2010 18:31:10 +0000 (15:31 -0300)
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>
drivers/media/video/gspca/cpia1.c
drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/gspca.h
drivers/media/video/gspca/m5602/m5602_core.c
drivers/media/video/gspca/ov519.c
drivers/media/video/gspca/ov534.c
drivers/media/video/gspca/pac7302.c
drivers/media/video/gspca/pac7311.c
drivers/media/video/gspca/sonixb.c
drivers/media/video/gspca/vc032x.c

index 58b696f455be0492c11172ce493a045b0f46d3fb..4b3ea3b4bbbaa90b33c103f09241fb5e53f31611 100644 (file)
@@ -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);
 
index 69b1058daeeb14cca2739f2e6bf1e99d60854b2f..8e822ed4435f7fe76f1fbe774438c857eb9654f5 100644 (file)
@@ -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,
index d181064653b7d48502e453c56a9cff2623110751..453e43d66a833731ba84db5e876c15338d151bf7 100644 (file)
@@ -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);
index 4294c75e3b11d3f23ae361290be87b7d674d9105..0c4ad5a5642ac0fca574476e8e95135a9788c981 100644 (file)
@@ -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);
                }
        }
 }
index 2e7df66a84b95acbbc489164ca7304641b6e158f..2b2cbdbf03fe9d005d237d81c5341b0da955a1bb 100644 (file)
@@ -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);
index dc1e4efe30fb9f40f8749215d5a99624e0cb7780..84c9b8dbded67d2139a2917f647bba3b15d5abf0 100644 (file)
@@ -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;
index bf47180a4e2fa322997f5a1fd464c0c73cdac4ec..88cc03bb3f940e7a6e0b6e9cc8243c74fa0671fe 100644 (file)
@@ -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);
index c978599a69dd4e2982dac2acbd107ab404ad92ef..5568c41a296c179d25b696cf0ec1cf6e5477e5f4 100644 (file)
@@ -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);
index 95354a339e3d3aabd100fd11d26dc893c7e9bee4..4989a2c779e567f1ac64d189cd82e9e2660c52be 100644 (file)
@@ -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;
        }
index 732c3dfe46fffeb57f7109c27ad08829c38a52b2..0a7d1e0866d20a98f5edd9c54903b1ee2f1721ef 100644 (file)
@@ -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);
 }