From b46475ecd9304aef278bd12c0731b4955789b698 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Sat, 29 Jun 2019 14:48:23 +0200 Subject: [PATCH] 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 Signed-off-by: Stefan Wahren Acked-by: Hans Verkuil Acked-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- .../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 a940935586869..455082867246d 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -342,16 +342,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, @@ -359,8 +356,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 b97e745e84c48..daa2b96565529 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c @@ -291,8 +291,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; @@ -453,6 +451,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);