vmh264: fix dec reset during v4l2 playing. [1/1]
authorshihong.zheng <shihong.zheng@amlogic.com>
Mon, 3 Aug 2020 05:33:45 +0000 (13:33 +0800)
committershihong.zheng <shihong.zheng@amlogic.com>
Mon, 3 Aug 2020 05:33:53 +0000 (13:33 +0800)
PD#SWPL-29734

Problem:
fix h264 dec reset. h264 decode driver use
cap_pool.out to check buffer num, but it increase
both decoder and vpp get frame buffer.

Solution:
add new count var for dec. mapping a new seq index
for decoder buffer.

Verify:
u212

Change-Id: I9f1b30abbbaf5aeba8f281b4e2613fd3a610e0b3
Signed-off-by: shihong.zheng <shihong.zheng@amlogic.com>
drivers/amvdec_ports/aml_vcodec_dec.c
drivers/amvdec_ports/aml_vcodec_dec.h
drivers/amvdec_ports/aml_vcodec_drv.h
drivers/frame_provider/decoder/h264_multi/vmh264.c

index 1216adab7f08c7e0eb3b602529858c9c13ee1d11..b0c2721d1cf839748494908bea4befb734949b1f 100644 (file)
@@ -409,20 +409,19 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_
        dst_vb2_v4l2 = container_of(dst_buf, struct vb2_v4l2_buffer, vb2_buf);
        dst_buf_info = container_of(dst_vb2_v4l2, struct aml_video_dec_buf, vb);
 
+       pfb     = &dst_buf_info->frame_buffer;
+       pfb->buf_idx    = dst_buf->index;
+       pfb->num_planes = dst_buf->num_planes;
+       pfb->status             = FB_ST_NORMAL;
        if (dst_buf->num_planes == 1) {
-               pfb                     = &dst_buf_info->frame_buffer;
                pfb->m.mem[0].dma_addr  = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
                pfb->m.mem[0].addr      = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
                pfb->m.mem[0].size      = ctx->picinfo.y_len_sz + ctx->picinfo.c_len_sz;
                pfb->m.mem[0].offset    = ctx->picinfo.y_len_sz;
-               pfb->num_planes         = dst_buf->num_planes;
-               pfb->status             = FB_ST_NORMAL;
-
                v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
                        "idx: %u, 1 plane, y:(0x%lx, %d)\n", dst_buf->index,
                        pfb->m.mem[0].addr, pfb->m.mem[0].size);
        } else if (dst_buf->num_planes == 2) {
-               pfb                     = &dst_buf_info->frame_buffer;
                pfb->m.mem[0].dma_addr  = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
                pfb->m.mem[0].addr      = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
                pfb->m.mem[0].size      = ctx->picinfo.y_len_sz;
@@ -432,15 +431,11 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_
                pfb->m.mem[1].addr      = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[1].dma_addr);
                pfb->m.mem[1].size      = ctx->picinfo.c_len_sz;
                pfb->m.mem[1].offset    = ctx->picinfo.c_len_sz >> 1;
-               pfb->num_planes         = dst_buf->num_planes;
-               pfb->status             = FB_ST_NORMAL;
-
                v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
                        "idx: %u, 2 planes, y:(0x%lx, %d), c:(0x%lx, %d)\n", dst_buf->index,
                        pfb->m.mem[0].addr, pfb->m.mem[0].size,
                        pfb->m.mem[1].addr, pfb->m.mem[1].size);
        } else {
-               pfb                     = &dst_buf_info->frame_buffer;
                pfb->m.mem[0].dma_addr  = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
                pfb->m.mem[0].addr      = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[0].dma_addr);
                pfb->m.mem[0].size      = ctx->picinfo.y_len_sz;
@@ -455,8 +450,6 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_
                pfb->m.mem[2].addr      = dma_to_phys(v4l_get_dev_from_codec_mm(), pfb->m.mem[3].dma_addr);
                pfb->m.mem[2].size      = ctx->picinfo.c_len_sz >> 1;
                pfb->m.mem[2].offset    = 0;
-               pfb->num_planes         = dst_buf->num_planes;
-               pfb->status             = FB_ST_NORMAL;
 
                v4l_dbg(ctx, V4L_DEBUG_CODEC_BUFMGR,
                        "idx: %u, 3 planes, y:(0x%lx, %d), u:(0x%lx, %d), v:(0x%lx, %d)\n",
@@ -473,6 +466,7 @@ int get_fb_from_queue(struct aml_vcodec_ctx *ctx, struct vdec_v4l2_buffer **out_
 
        info = container_of(pfb, struct aml_video_dec_buf, frame_buffer);
 
+       ctx->cap_pool.dec++;
        ctx->cap_pool.seq[ctx->cap_pool.out++] =
                (V4L_CAP_BUFF_IN_DEC << 16 | dst_buf->index);
        v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
@@ -2380,6 +2374,8 @@ static void vb2ops_vdec_stop_streaming(struct vb2_queue *q)
        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)
index 3406e9fe913848ca497f19341c77a39272e33993..3653ff0781545ef86025c6029f2e90aea56c91cd 100644 (file)
@@ -58,6 +58,7 @@ struct vdec_v4l2_buffer {
        } m;
        ulong   vf_handle;
        u32     status;
+       u32     buf_idx;
 };
 
 
index 1bc6211c866ca8e9da78d65dbcd5be0b311fb989..a828b421340dd013e208132ccfb5e88e88b8dfb8 100644 (file)
@@ -358,6 +358,7 @@ struct v4l_buff_pool {
         */
        u32 seq[V4L_CAP_BUFF_MAX];
        u32 in, out;
+       u32 dec, vpp;
 };
 
 enum aml_thread_type {
index 948b436db28c06b477941c86f1c91f4f1541a7ba..84c5f16c6e53b23d992b7371266804d0cbafafba 100644 (file)
@@ -896,6 +896,7 @@ struct vdec_h264_hw_s {
        int sidebind_channel_id;
        u32 low_latency_mode;
        int ip_field_error_count;
+       int buffer_wrap[BUFSPEC_POOL_SIZE];
 };
 
 static u32 again_threshold;
@@ -1688,6 +1689,7 @@ static void buf_spec_init(struct vdec_h264_hw_s *hw, bool buffer_reset_flag)
                for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
                        hw->buffer_spec[i].used = -1;
                        hw->buffer_spec[i].canvas_pos = -1;
+                       hw->buffer_wrap[i] = -1;
                }
        }
 
@@ -1909,8 +1911,9 @@ static int alloc_one_buf_spec_from_queue(struct vdec_h264_hw_s *hw, int idx)
 
        bs->cma_alloc_addr = (unsigned long)fb;
        dpb_print(DECODE_ID(hw), PRINT_FLAG_V4L_DETAIL,
-               "[%d] %s(), cma alloc addr: 0x%x\n",
-               ctx->id, __func__, bs->cma_alloc_addr);
+               "[%d] %s(), cma alloc addr: 0x%x, out %d dec %d\n",
+               ctx->id, __func__, bs->cma_alloc_addr,
+               ctx->cap_pool.out, ctx->cap_pool.dec);
 
        if (fb->num_planes == 1) {
                y_addr = fb->m.mem[0].addr;
@@ -2121,34 +2124,68 @@ static void config_decode_canvas_ex(struct vdec_h264_hw_s *hw, int i)
                7);
 }
 
+
+static int v4l_get_free_buffer_spec(struct vdec_h264_hw_s *hw)
+{
+       int i;
+
+       for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
+               if (hw->buffer_spec[i].cma_alloc_addr == 0)
+                       return i;
+       }
+
+       return -1;
+}
+
+static int v4l_find_buffer_spec_idx(struct vdec_h264_hw_s *hw, unsigned int v4l_indx)
+{
+       int i;
+
+       for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
+               if (hw->buffer_wrap[i] == v4l_indx)
+                       return i;
+       }
+       return -1;
+}
+
 static int v4l_get_free_buf_idx(struct vdec_s *vdec)
 {
        struct vdec_h264_hw_s *hw = (struct vdec_h264_hw_s *)vdec->private;
        struct aml_vcodec_ctx * v4l = hw->v4l2_ctx;
        struct v4l_buff_pool *pool = &v4l->cap_pool;
        struct buffer_spec_s *pic = NULL;
-       int i, idx = INVALID_IDX;
+       int i, rt, idx = INVALID_IDX;
        ulong flags;
+       u32 state, index;
 
        spin_lock_irqsave(&hw->bufspec_lock, flags);
        for (i = 0; i < pool->in; ++i) {
-               u32 state = (pool->seq[i] >> 16);
-               u32 index = (pool->seq[i] & 0xffff);
+               state = (pool->seq[i] >> 16);
+               index = (pool->seq[i] & 0xffff);
 
                switch (state) {
                case V4L_CAP_BUFF_IN_DEC:
-                       pic = &hw->buffer_spec[i];
-                       if ((pic->vf_ref == 0) &&
-                               (pic->used == 0) &&
-                               pic->cma_alloc_addr) {
-                               idx = i;
+                       rt = v4l_find_buffer_spec_idx(hw, index);
+                       if (rt >= 0) {
+                               pic = &hw->buffer_spec[rt];
+                               if ((pic->vf_ref == 0) &&
+                                       (pic->used == 0) &&
+                                       pic->cma_alloc_addr) {
+                                       idx = rt;
+                               }
                        }
                        break;
                case V4L_CAP_BUFF_IN_M2M:
-                       pic = &hw->buffer_spec[index];
-                       if (!alloc_one_buf_spec_from_queue(hw, index)) {
-                               config_decode_canvas(hw, index);
-                               idx = index;
+                       rt = v4l_get_free_buffer_spec(hw);
+                       if (rt >= 0) {
+                               pic = &hw->buffer_spec[rt];
+                               if (!alloc_one_buf_spec_from_queue(hw, rt)) {
+                                       struct vdec_v4l2_buffer *fb;
+                                       config_decode_canvas(hw, rt);
+                                       fb = (struct vdec_v4l2_buffer *)pic->cma_alloc_addr;
+                                       hw->buffer_wrap[rt] = fb->buf_idx;
+                                       idx = rt;
+                               }
                        }
                        break;
                default:
@@ -2165,6 +2202,10 @@ static int v4l_get_free_buf_idx(struct vdec_s *vdec)
 
        if (idx < 0) {
                dpb_print(DECODE_ID(hw), 0, "%s fail\n", __func__);
+               for (i = 0; i < BUFSPEC_POOL_SIZE; i++) {
+                       dpb_print(DECODE_ID(hw), 0, "%s, %d\n",
+                               __func__, hw->buffer_wrap[i]);
+               }
                vmh264_dump_state(vdec);
        }
 
@@ -2195,6 +2236,7 @@ int get_free_buf_idx(struct vdec_s *vdec)
                        hw->buffer_spec[i].used = 1;
                        hw->start_search_pos = i+1;
                        index = i;
+                       hw->buffer_wrap[i] = index;
                        break;
                }
        }
@@ -2210,6 +2252,7 @@ int get_free_buf_idx(struct vdec_s *vdec)
                                hw->buffer_spec[i].used = 1;
                                hw->start_search_pos = i+1;
                                index = i;
+                               hw->buffer_wrap[i] = index;
                                break;
                        }
                }
@@ -2476,7 +2519,7 @@ unsigned char have_free_buf_spec(struct vdec_s *vdec)
                        }
                }
 
-               if (v4l->cap_pool.out < hw->dpb.mDPB.size &&
+               if (v4l->cap_pool.dec < hw->dpb.mDPB.size &&
                        v4l2_m2m_num_dst_bufs_ready(v4l->m2m_ctx)
                        >= run_ready_min_buf_num)
                        return 1;
@@ -2573,7 +2616,9 @@ static int check_force_interlace(struct vdec_h264_hw_s *hw,
                         && (hw->frame_dur == 3840)) {
                bForceInterlace = 1;
        }
-
+       if (hw->is_used_v4l && (bForceInterlace == 0)) {
+               bForceInterlace = (frame->frame->mb_aff_frame_flag)?1:0;
+       }
        return bForceInterlace;
 }
 
@@ -6795,9 +6840,10 @@ static void dump_bufspec(struct vdec_h264_hw_s *hw,
                if (hw->buffer_spec[i].used == -1)
                        continue;
                dpb_print(DECODE_ID(hw), 0,
-                       "bufspec (%d): used %d adr 0x%x canvas(%d) vf_ref(%d) ",
+                       "bufspec (%d): used %d adr 0x%x(%lx) canvas(%d) vf_ref(%d) ",
                        i, hw->buffer_spec[i].used,
                        hw->buffer_spec[i].buf_adr,
+                       hw->buffer_spec[i].cma_alloc_addr,
                        hw->buffer_spec[i].canvas_pos,
                        hw->buffer_spec[i].vf_ref
                        );