]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
staging: bcm2835-camera: Handle empty EOS buffers whilst streaming
authorDave Stevenson <dave.stevenson@raspberrypi.org>
Sat, 29 Jun 2019 12:48:23 +0000 (14:48 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 1 Jul 2019 07:09:38 +0000 (09:09 +0200)
The change to mapping V4L2 to MMAL buffers 1:1 didn't handle
the condition we get with raw pixel buffers (eg YUV and RGB)
direct from the camera's stills port. That sends the pixel buffer
and then an empty buffer with the EOS flag set. The EOS buffer
wasn't handled and returned an error up the stack.

Handle the condition correctly by returning it to the component
if streaming, or returning with an error if stopping streaming.

Fixes: 938416707071 ("staging: bcm2835-camera: Remove V4L2/MMAL buffer remapping")
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Acked-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c

index f2010655f58eb6c9afeac3b6dbe33657928144b0..8a8cd7ed28d9eb84a679fc1e48d93a29685a08da 100644 (file)
@@ -339,16 +339,13 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 
        if (length == 0) {
                /* stream ended */
-               if (buf) {
-                       /* this should only ever happen if the port is
-                        * disabled and there are buffers still queued
+               if (dev->capture.frame_count) {
+                       /* empty buffer whilst capturing - expected to be an
+                        * EOS, so grab another frame
                         */
-                       vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
-                       pr_debug("Empty buffer");
-               } else if (dev->capture.frame_count) {
-                       /* grab another frame */
                        if (is_capturing(dev)) {
-                               pr_debug("Grab another frame");
+                               v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+                                        "Grab another frame");
                                vchiq_mmal_port_parameter_set(
                                        instance,
                                        dev->capture.camera_port,
@@ -356,8 +353,14 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
                                        &dev->capture.frame_count,
                                        sizeof(dev->capture.frame_count));
                        }
+                       if (vchiq_mmal_submit_buffer(instance, port, buf))
+                               v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
+                                        "Failed to return EOS buffer");
                } else {
-                       /* signal frame completion */
+                       /* stopping streaming.
+                        * return buffer, and signal frame completion
+                        */
+                       vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
                        complete(&dev->capture.frame_cmplt);
                }
                return;
index 59eb812ae837cbce42d529cc5c592628301bfe38..d0f7b67676d5adfb0924ccc329a071c25711aef9 100644 (file)
@@ -332,8 +332,6 @@ static int bulk_receive(struct vchiq_mmal_instance *instance,
 
        /* store length */
        msg_context->u.bulk.buffer_used = rd_len;
-       msg_context->u.bulk.mmal_flags =
-           msg->u.buffer_from_host.buffer_header.flags;
        msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts;
        msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts;
 
@@ -461,6 +459,9 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance,
                return;
        }
 
+       msg_context->u.bulk.mmal_flags =
+                               msg->u.buffer_from_host.buffer_header.flags;
+
        if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) {
                /* message reception had an error */
                pr_warn("error %d in reply\n", msg->h.status);