summaryrefslogtreecommitdiff
authorshihong.zheng <shihong.zheng@amlogic.com>2020-08-03 05:33:45 (GMT)
committer shihong.zheng <shihong.zheng@amlogic.com>2020-08-03 05:33:53 (GMT)
commitae26c44f67afb5bf64f50a84361e16f78cbac5ba (patch)
tree0a5bbc903f8d6a917896df4cbdd64190065657d6
parente5f885bf9b8946b06b0eecd58fa7c0664bea5af6 (diff)
downloadmedia_modules-ae26c44f67afb5bf64f50a84361e16f78cbac5ba.zip
media_modules-ae26c44f67afb5bf64f50a84361e16f78cbac5ba.tar.gz
media_modules-ae26c44f67afb5bf64f50a84361e16f78cbac5ba.tar.bz2
vmh264: fix dec reset during v4l2 playing. [1/1]
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>
Diffstat
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.c18
-rw-r--r--drivers/amvdec_ports/aml_vcodec_dec.h1
-rw-r--r--drivers/amvdec_ports/aml_vcodec_drv.h1
-rw-r--r--drivers/frame_provider/decoder/h264_multi/vmh264.c80
4 files changed, 72 insertions, 28 deletions
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.c b/drivers/amvdec_ports/aml_vcodec_dec.c
index 1216ada..b0c2721 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.c
+++ b/drivers/amvdec_ports/aml_vcodec_dec.c
@@ -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)
diff --git a/drivers/amvdec_ports/aml_vcodec_dec.h b/drivers/amvdec_ports/aml_vcodec_dec.h
index 3406e9f..3653ff0 100644
--- a/drivers/amvdec_ports/aml_vcodec_dec.h
+++ b/drivers/amvdec_ports/aml_vcodec_dec.h
@@ -58,6 +58,7 @@ struct vdec_v4l2_buffer {
} m;
ulong vf_handle;
u32 status;
+ u32 buf_idx;
};
diff --git a/drivers/amvdec_ports/aml_vcodec_drv.h b/drivers/amvdec_ports/aml_vcodec_drv.h
index 1bc6211..a828b42 100644
--- a/drivers/amvdec_ports/aml_vcodec_drv.h
+++ b/drivers/amvdec_ports/aml_vcodec_drv.h
@@ -358,6 +358,7 @@ struct v4l_buff_pool {
*/
u32 seq[V4L_CAP_BUFF_MAX];
u32 in, out;
+ u32 dec, vpp;
};
enum aml_thread_type {
diff --git a/drivers/frame_provider/decoder/h264_multi/vmh264.c b/drivers/frame_provider/decoder/h264_multi/vmh264.c
index 948b436..84c5f16 100644
--- a/drivers/frame_provider/decoder/h264_multi/vmh264.c
+++ b/drivers/frame_provider/decoder/h264_multi/vmh264.c
@@ -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
);