v4l2: buffer not returned in DMABUF mode [1/1]
authorSong Zhao <song.zhao@amlogic.com>
Wed, 1 Apr 2020 20:48:10 +0000 (13:48 -0700)
committerHui Zhang <hui.zhang@amlogic.com>
Thu, 2 Apr 2020 06:14:06 +0000 (22:14 -0800)
PD#SWPL-23493

Problem:
aml_recycle_dma_buffers() is only called when aml_vdec_worker() is
schedule. If all buffers are queued into output port, application will
have no extra output buffer to trigfer aml_vdec_worker(). It will lead
to freed buffer inside input->vframe_block_free_list can not be returned
to application.  Thus, deadlock.

Solution:
Trigger aml_recycle_dma_buffers when capture buffer is dquened.

Verify:
U212

Change-Id: I8314bced72abc715ed371ce503976d4b447d9037
Signed-off-by: Song Zhao <song.zhao@amlogic.com>
drivers/amvdec_ports/aml_vcodec_adapt.c
drivers/amvdec_ports/aml_vcodec_dec.c
drivers/amvdec_ports/aml_vcodec_drv.h

index ab50642efae2cbb0513eb6f08ab5cf7e15d8699e..b87d0c882c19f0dc39ceef9af7ccbc7c949e79a8 100644 (file)
@@ -487,12 +487,10 @@ static void set_vdec_properity(struct vdec_s *vdec,
                        vdec->type = VDEC_TYPE_STREAM_PARSER;
                        vdec->port->type &= ~PORT_TYPE_FRAME;
                        vdec->port->type |= PORT_TYPE_ES;
-                       ada_ctx->ctx->is_stream_mode = true;
                } else if (aml_set_vdec_type == VDEC_TYPE_FRAME_BLOCK) {
                        vdec->type = VDEC_TYPE_FRAME_BLOCK;
                        vdec->port->type &= ~PORT_TYPE_ES;
                        vdec->port->type |= PORT_TYPE_FRAME;
-                       ada_ctx->ctx->is_stream_mode = false;
                }
        }
 
index 80f73beed6da9909574911a01b718b0c2dd3df5d..8856bf824eb4168c952db78d9036969c9ad53360 100644 (file)
@@ -1389,7 +1389,7 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv,
                        ATRACE_COUNTER("v4l2_dqin_eagain", 0);
                else
                        ATRACE_COUNTER("v4l2_dqin_ok", 0);
-       } else if (!V4L2_TYPE_IS_OUTPUT(buf->type)) {
+       } else {
                if (ret == -EAGAIN)
                        ATRACE_COUNTER("v4l2_dqout_eagain", 0);
        }
@@ -1400,6 +1400,9 @@ static int vidioc_vdec_dqbuf(struct file *file, void *priv,
                struct aml_video_dec_buf *aml_buf = NULL;
                struct file *file = NULL;
 
+               if (ctx->is_drm_mode && ctx->output_dma_mode)
+                       aml_recycle_dma_buffers(ctx);
+
                vq = v4l2_m2m_get_vq(ctx->m2m_ctx, buf->type);
                vb2_v4l2 = to_vb2_v4l2_buffer(vq->bufs[buf->index]);
                aml_buf = container_of(vb2_v4l2, struct aml_video_dec_buf, vb);
@@ -2095,6 +2098,12 @@ static void vb2ops_vdec_buf_queue(struct vb2_buffer *vb)
        src_mem.size    = vb->planes[0].bytesused;
        src_mem.model   = vb->memory;
 
+       if (vb->memory == VB2_MEMORY_DMABUF) {
+               v4l_dbg(ctx, V4L_DEBUG_CODEC_INPUT,
+                               "%s, output_dma_mode set", __func__);
+               ctx->output_dma_mode = true;
+       }
+
        if (vdec_if_probe(ctx, &src_mem, NULL)) {
                v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
 
index 3d204305445c0ca1dc5e9d3046163fca56fd5e21..f28dc5130a1aff886b47ffae1e1ba01751fc0aad 100644 (file)
@@ -462,7 +462,7 @@ struct aml_vcodec_ctx {
 
        bool                            has_receive_eos;
        bool                            is_drm_mode;
-       bool                            is_stream_mode;
+       bool                            output_dma_mode;
        bool                            is_stream_off;
        bool                            receive_cmd_stop;
        int                             reset_flag;