}
 
                /* capture type 0 = vbi start
-                  capture type 1 = video start
-                  capture type 2 = video in progress */
+                  capture type 1 = vbi in progress
+                  capture type 2 = video start
+                  capture type 3 = video in progress */
                len = actual_length;
                if (len >= 4) {
                        /* NOTE: headers are always 4 bytes and
                                len -= 4;
                        } else if (p[0] == 0x22 && p[1] == 0x5a) {
                                /* start video */
-                               dev->capture_type = 1;
+                               dev->capture_type = 2;
                                dev->top_field = !(p[2] & 1);
                                p += 4;
                                len -= 4;
                 * have no continuation header */
 
                if (dev->capture_type == 0) {
+                       dev->capture_type = 1;
+                       if (dev->top_field) { /* Brand new frame */
+                               if (vbi_buf != NULL)
+                                       finish_buffer(dev, vbi_buf);
+                               vbi_buf = get_next_buf(dev, vbi_dma_q);
+                               dev->usb_ctl.vbi_buf = vbi_buf;
+                               if (vbi_buf == NULL)
+                                       vbioutp = NULL;
+                               else
+                                       vbioutp =
+                                         videobuf_to_vmalloc(&vbi_buf->vb);
+                       }
+                       if (vbi_buf != NULL) {
+                               vbi_buf->top_field = dev->top_field;
+                               vbi_buf->pos = 0;
+                       }
+               }
+
+               if (dev->capture_type == 1) {
                        int vbi_size = dev->vbi_width * dev->vbi_height;
-                       if (dev->vbi_read >= vbi_size) {
-                               /* We've already read all the VBI data, so
-                                  treat the rest as video */
-                               em28xx_isocdbg("dev->vbi_read > vbi_size\n");
-                       } else if ((dev->vbi_read + len) < vbi_size) {
-                               /* This entire frame is VBI data */
-                               if (dev->vbi_read == 0 && dev->top_field) {
-                                       /* Brand new frame */
-                                       if (vbi_buf != NULL)
-                                               finish_buffer(dev, vbi_buf);
-                                       vbi_buf = get_next_buf(dev, vbi_dma_q);
-                                       dev->usb_ctl.vbi_buf = vbi_buf;
-                                       if (vbi_buf == NULL)
-                                               vbioutp = NULL;
-                                       else
-                                               vbioutp = videobuf_to_vmalloc(
-                                                       &vbi_buf->vb);
-                               }
-
-                               if (dev->vbi_read == 0) {
-                                       if (vbi_buf != NULL) {
-                                               vbi_buf->top_field
-                                                 = dev->top_field;
-                                               vbi_buf->pos = 0;
-                                       }
-                               }
-
-                               dev->vbi_read += len;
-                               em28xx_copy_vbi(dev, vbi_buf, p, vbioutp, len);
-                       } else {
-                               /* Some of this frame is VBI data and some is
-                                  video data */
-                               int vbi_data_len = vbi_size - dev->vbi_read;
-                               dev->vbi_read += vbi_data_len;
+                       int vbi_data_len = ((dev->vbi_read + len) > vbi_size) ?
+                                          (vbi_size - dev->vbi_read) : len;
+
+                       /* Copy VBI data */
+                       if (vbi_buf != NULL)
                                em28xx_copy_vbi(dev, vbi_buf, p, vbioutp,
                                                vbi_data_len);
-                               dev->capture_type = 1;
+                       dev->vbi_read += vbi_data_len;
+
+                       if (vbi_data_len < len) {
+                               /* Continue with copying video data */
+                               dev->capture_type = 2;
                                p += vbi_data_len;
                                len -= vbi_data_len;
                        }
                }
 
-               if (dev->capture_type == 1) {
-                       dev->capture_type = 2;
+               if (dev->capture_type == 2) {
+                       dev->capture_type = 3;
                        if (dev->progressive || dev->top_field) {
                                if (buf != NULL)
                                        finish_buffer(dev, buf);
                        }
                }
 
-               if (buf != NULL && dev->capture_type == 2 && len > 0)
+               if (buf != NULL && dev->capture_type == 3 && len > 0)
                        em28xx_copy_video(dev, buf, p, outp, len);
        }
        return rc;