v4l2: do not reset pool fields on streamoff output port [1/1]
authorSong Zhao <song.zhao@amlogic.com>
Wed, 12 Aug 2020 06:22:29 +0000 (23:22 -0700)
committerHui Zhang <hui.zhang@amlogic.com>
Fri, 14 Aug 2020 07:26:55 +0000 (00:26 -0700)
PD#SWPL-30433

Problem:
a) Streamoff output port will reset cap_pool.in, it will cause decoding
error like "v4l_get_free_buf_idx fail"
b) Sometimes
application will not call dqueue of capture buffer to trigger
aml_recycle_dma_buffers().

Solution:
ONLY reset cap_pool filed on streamoff capture port.
Recycle DMA secure buffer after receiving vframe from VFM.

Verify:
U212 + RDK + DSTV seek

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

index 99406bc514e1dea7f8079b62d0c25f2a57ee6a69..eecd4f393f98e659c1a60893cdbf417fef1e5d3b 100644 (file)
@@ -194,6 +194,7 @@ extern bool dump_capture_frame;
 
 extern int dmabuf_fd_install_data(int fd, void* data, u32 size);
 extern bool is_v4l2_buf_file(struct file *file);
+static void aml_recycle_dma_buffers(struct aml_vcodec_ctx *ctx);
 
 static ulong aml_vcodec_ctx_lock(struct aml_vcodec_ctx *ctx)
 {
@@ -518,6 +519,7 @@ EXPORT_SYMBOL(put_fb_to_queue);
 void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *fb)
 {
        struct aml_video_dec_buf *dstbuf = NULL;
+       struct vb2_buffer *vb2_buf = NULL;
        struct vframe_s *vf = (struct vframe_s *)fb->vf_handle;
 
        v4l_dbg(ctx, V4L_DEBUG_CODEC_OUTPUT,
@@ -531,6 +533,11 @@ void trans_vframe_to_user(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer *f
                fb->m.mem[2].addr, fb->m.mem[2].size);
 
        dstbuf = container_of(fb, struct aml_video_dec_buf, frame_buffer);
+       vb2_buf = &dstbuf->vb.vb2_buf;
+
+       if (ctx->is_drm_mode && vb2_buf->memory == VB2_MEMORY_DMABUF)
+               aml_recycle_dma_buffers(ctx);
+
        if (dstbuf->frame_buffer.num_planes == 1) {
                vb2_set_plane_payload(&dstbuf->vb.vb2_buf, 0, fb->m.mem[0].bytes_used);
        } else if (dstbuf->frame_buffer.num_planes == 2) {
@@ -1406,9 +1413,6 @@ 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);
@@ -2374,13 +2378,13 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
                        /*v4l_dbg(ctx, V4L_DEBUG_CODEC_EXINFO, "idx: %d, state: %d\n",
                                q->bufs[i]->index, q->bufs[i]->state);*/
                }
-       }
 
-       ctx->buf_used_count = 0;
-       ctx->cap_pool.in = 0;
-       ctx->cap_pool.out = 0;
-       ctx->cap_pool.dec = 0;
-       ctx->cap_pool.vpp = 0;
+               ctx->buf_used_count = 0;
+               ctx->cap_pool.in = 0;
+               ctx->cap_pool.out = 0;
+               ctx->cap_pool.dec = 0;
+               ctx->cap_pool.vpp = 0;
+       }
 }
 
 static void m2mops_vdec_device_run(void *priv)