From f24e55dd1e8f95559791b87b83cc87efd698840c Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 13 Aug 2020 16:58:18 +0100 Subject: [PATCH 1/3] staging: vc04_services: codec: Fix incorrect buffer cleanup The allocated input and output buffers are initialised in buf_init and should only be cleared up in buf_cleanup. stop_streaming was (incorrectly) cleaning up the buffers to avoid an issue in videobuf2 that had been fixed by the orphaned buffer support. Remove the erroneous cleanup. Signed-off-by: Dave Stevenson --- .../bcm2835-codec/bcm2835-v4l2-codec.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c index 3fe81979aaa163..b6c5a66b4b4aa1 100644 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c @@ -2320,10 +2320,7 @@ static void bcm2835_codec_stop_streaming(struct vb2_queue *q) struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); struct vchiq_mmal_port *port = get_port_data(ctx, q->type); struct vb2_v4l2_buffer *vbuf; - struct vb2_v4l2_buffer *vb2; - struct v4l2_m2m_buffer *m2m; - struct m2m_mmal_buffer *buf; - int ret, i; + int ret; v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d - return buffers\n", __func__, q->type); @@ -2363,18 +2360,6 @@ static void bcm2835_codec_stop_streaming(struct vb2_queue *q) } } - /* - * Release the VCSM handle here as otherwise REQBUFS(0) aborts because - * someone is using the dmabuf before giving the driver a chance to do - * anything about it. - */ - for (i = 0; i < q->num_buffers; i++) { - vb2 = to_vb2_v4l2_buffer(q->bufs[i]); - m2m = container_of(vb2, struct v4l2_m2m_buffer, vb); - buf = container_of(m2m, struct m2m_mmal_buffer, m2m); - - bcm2835_codec_mmal_buf_cleanup(&buf->mmal); - } /* If both ports disabled, then disable the component */ if (!ctx->component->input[0].enabled && From dfda7fb3bfd189aa33441f2350cb99001147076d Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 13 Aug 2020 17:01:27 +0100 Subject: [PATCH 2/3] staging: vc04_service: codec: Allow start_streaming to update the buffernum start_streaming passes a count of how many buffers have been queued to videobuf2. Allow this value to update the number of buffers the VPU allocates on a port to avoid buffer recycling issues. Signed-off-by: Dave Stevenson --- .../bcm2835-codec/bcm2835-v4l2-codec.c | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c index b6c5a66b4b4aa1..427048c0ea31d3 100644 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c @@ -2268,6 +2268,7 @@ static int bcm2835_codec_start_streaming(struct vb2_queue *q, struct bcm2835_codec_ctx *ctx = vb2_get_drv_priv(q); struct bcm2835_codec_dev *dev = ctx->dev; struct bcm2835_codec_q_data *q_data = get_q_data(ctx, q->type); + struct vchiq_mmal_port *port = get_port_data(ctx, q->type); int ret; v4l2_dbg(1, debug, &ctx->dev->v4l2_dev, "%s: type: %d count %d\n", @@ -2283,6 +2284,20 @@ static int bcm2835_codec_start_streaming(struct vb2_queue *q, ctx->component_enabled = true; } + if (count < port->minimum_buffer.num) + count = port->minimum_buffer.num; + + if (port->current_buffer.num != count + 1) { + v4l2_dbg(2, debug, &ctx->dev->v4l2_dev, "%s: ctx:%p, buffer count changed %u to %u\n", + __func__, ctx, port->current_buffer.num, count + 1); + + port->current_buffer.num = count + 1; + ret = vchiq_mmal_port_set_format(dev->instance, port); + if (ret) + v4l2_err(&ctx->dev->v4l2_dev, "%s: Error updating buffer count, ret %d\n", + __func__, ret); + } + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { /* * Create the EOS buffer. @@ -2294,17 +2309,17 @@ static int bcm2835_codec_start_streaming(struct vb2_queue *q, &q_data->eos_buffer.mmal); q_data->eos_buffer_in_use = false; - ctx->component->input[0].cb_ctx = ctx; + port->cb_ctx = ctx; ret = vchiq_mmal_port_enable(dev->instance, - &ctx->component->input[0], + port, ip_buffer_cb); if (ret) v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling i/p port, ret %d\n", __func__, ret); } else { - ctx->component->output[0].cb_ctx = ctx; + port->cb_ctx = ctx; ret = vchiq_mmal_port_enable(dev->instance, - &ctx->component->output[0], + port, op_buffer_cb); if (ret) v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling o/p port, ret %d\n", From 20a6f32a1139ae0ae4a82b6a92a9effb8e0a9eb4 Mon Sep 17 00:00:00 2001 From: Dave Stevenson Date: Thu, 13 Aug 2020 17:04:53 +0100 Subject: [PATCH 3/3] staging: vc04_services: codec: Fix component enable/disable start_streaming enabled the VPU component if ctx->component_enabled was not set. stop_streaming disabled the VPU component if both ports were disabled. It didn't clear ctx->component_enabled. If seeking, this meant that the component never got re-enabled, and buffers never got processed afterwards. Signed-off-by: Dave Stevenson --- .../staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c index 427048c0ea31d3..14c47e2ea99552 100644 --- a/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c +++ b/drivers/staging/vc04_services/bcm2835-codec/bcm2835-v4l2-codec.c @@ -2377,13 +2377,15 @@ static void bcm2835_codec_stop_streaming(struct vb2_queue *q) /* If both ports disabled, then disable the component */ - if (!ctx->component->input[0].enabled && + if (ctx->component_enabled && + !ctx->component->input[0].enabled && !ctx->component->output[0].enabled) { ret = vchiq_mmal_component_disable(dev->instance, ctx->component); if (ret) v4l2_err(&ctx->dev->v4l2_dev, "%s: Failed enabling component, ret %d\n", __func__, ret); + ctx->component_enabled = false; } if (V4L2_TYPE_IS_OUTPUT(q->type))