summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Stevenson <dave.stevenson@raspberrypi.org>2019-06-29 14:48:23 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-14 08:01:14 +0200
commitfa7314b8450f15ae448044594916506793cd7cd3 (patch)
treeccc81e6c2c3dc8313c0771551310c927a3cf2ac5
parentbc545258185e66cc5fa240aecf2833d64d648cd8 (diff)
downloadlinux-stable-fa7314b8450f15ae448044594916506793cd7cd3.tar.gz
linux-stable-fa7314b8450f15ae448044594916506793cd7cd3.tar.bz2
linux-stable-fa7314b8450f15ae448044594916506793cd7cd3.zip
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>
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c21
-rw-r--r--drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c5
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 bc6ff83ddb01..5e9187edeef4 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 0f7de34eb5db..29761f6c3b55 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);