81153c9ff9dc61d42c3b4555fa8853963dd7dcb4
[oweals/openwrt.git] /
1 From 1da35962d95cdb8648cb85c4b6f3d3367be88601 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.org>
3 Date: Thu, 5 Jul 2018 16:17:03 +0100
4 Subject: [PATCH 254/703] staging: bcm2835-camera: Handle empty EOS buffers
5  whilst streaming
6
7 The change to mapping V4L2 to MMAL buffers 1:1 didn't handle
8 the condition we get with raw pixel buffers (eg YUV and RGB)
9 direct from the camera's stills port. That sends the pixel buffer
10 and then an empty buffer with the EOS flag set. The EOS buffer
11 wasn't handled and returned an error up the stack.
12
13 Handle the condition correctly by returning it to the component
14 if streaming, or returning with an error if stopping streaming.
15
16 Fixes: 9384167 "staging: bcm2835-camera: Remove V4L2/MMAL buffer remapping"
17
18 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
19 ---
20  .../bcm2835-camera/bcm2835-camera.c           | 21 +++++++++++--------
21  .../vc04_services/bcm2835-camera/mmal-vchiq.c |  5 +++--
22  2 files changed, 15 insertions(+), 11 deletions(-)
23
24 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
25 +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
26 @@ -339,16 +339,13 @@ static void buffer_cb(struct vchiq_mmal_
27  
28         if (length == 0) {
29                 /* stream ended */
30 -               if (buf) {
31 -                       /* this should only ever happen if the port is
32 -                        * disabled and there are buffers still queued
33 +               if (dev->capture.frame_count) {
34 +                       /* empty buffer whilst capturing - expected to be an
35 +                        * EOS, so grab another frame
36                          */
37 -                       vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
38 -                       pr_debug("Empty buffer");
39 -               } else if (dev->capture.frame_count) {
40 -                       /* grab another frame */
41                         if (is_capturing(dev)) {
42 -                               pr_debug("Grab another frame");
43 +                               v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
44 +                                        "Grab another frame");
45                                 vchiq_mmal_port_parameter_set(
46                                         instance,
47                                         dev->capture.camera_port,
48 @@ -356,8 +353,14 @@ static void buffer_cb(struct vchiq_mmal_
49                                         &dev->capture.frame_count,
50                                         sizeof(dev->capture.frame_count));
51                         }
52 +                       if (vchiq_mmal_submit_buffer(instance, port, buf))
53 +                               v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
54 +                                        "Failed to return EOS buffer");
55                 } else {
56 -                       /* signal frame completion */
57 +                       /* stopping streaming.
58 +                        * return buffer, and signal frame completion
59 +                        */
60 +                       vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
61                         complete(&dev->capture.frame_cmplt);
62                 }
63                 return;
64 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
65 +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c
66 @@ -332,8 +332,6 @@ static int bulk_receive(struct vchiq_mma
67  
68         /* store length */
69         msg_context->u.bulk.buffer_used = rd_len;
70 -       msg_context->u.bulk.mmal_flags =
71 -           msg->u.buffer_from_host.buffer_header.flags;
72         msg_context->u.bulk.dts = msg->u.buffer_from_host.buffer_header.dts;
73         msg_context->u.bulk.pts = msg->u.buffer_from_host.buffer_header.pts;
74  
75 @@ -461,6 +459,9 @@ static void buffer_to_host_cb(struct vch
76                 return;
77         }
78  
79 +       msg_context->u.bulk.mmal_flags =
80 +                               msg->u.buffer_from_host.buffer_header.flags;
81 +
82         if (msg->h.status != MMAL_MSG_STATUS_SUCCESS) {
83                 /* message reception had an error */
84                 pr_warn("error %d in reply\n", msg->h.status);