staging: bcm2835-camera: Handle empty EOS buffers whilst streaming [Linux 5.2.1]

staging: bcm2835-camera: Handle empty EOS buffers whilst streaming [Linux 5.2.1]

This Linux kernel change "staging: bcm2835-camera: Handle empty EOS buffers whilst streaming" is included in the Linux 5.2.1 release. This change is authored by Dave Stevenson <dave.stevenson [at] raspberrypi.org> on Sat Jun 29 14:48:23 2019 +0200. The commit for this change in Linux stable tree is fa7314b (patch) which is from upstream commit a26be06. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream a26be06.

staging: bcm2835-camera: Handle empty EOS buffers whilst streaming

commit a26be06d6d96c10a9ab005e99d93fbb5d3babd98 upstream.

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>

There are 26 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 .../vc04_services/bcm2835-camera/bcm2835-camera.c   | 21 ++++++++++++---------
 .../vc04_services/bcm2835-camera/mmal-vchiq.c       |  5 +++--
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index bc6ff83..5e9187e 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -336,16 +336,13 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
        return;
    } else 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,
@@ -353,8 +350,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);
        }
    } else {
diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
index 0f7de34..29761f6 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
@@ -290,8 +290,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;

@@ -452,6 +450,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);

Leave a Reply

Your email address will not be published. Required fields are marked *