author | shihong.zheng <shihong.zheng@amlogic.com> | 2020-03-02 08:11:11 (GMT) |
---|---|---|
committer | Shihong Zheng <shihong.zheng@amlogic.com> | 2020-03-20 02:08:35 (GMT) |
commit | 0ae85c6c97ba25fa6a320bd6473cb6341e538f18 (patch) | |
tree | 6fd9aa6ecac8765d3ab9cc3b8fee4823b5df84aa | |
parent | b86297e6da7f4ddf28bfa7935be43d390702ec28 (diff) | |
download | media_modules-0ae85c6c97ba25fa6a320bd6473cb6341e538f18.zip media_modules-0ae85c6c97ba25fa6a320bd6473cb6341e538f18.tar.gz media_modules-0ae85c6c97ba25fa6a320bd6473cb6341e538f18.tar.bz2 |
mpeg12: improve mpeg12 buf use cnt. [1/1]
PD#OTT-8694
Problem:
mpeg12 mosaic and freeze.
Solution:
separate buf use cnt and reference pic count.
Verify:
ac-200
Change-Id: Ia9668e706e51cef8775e6b48137290c94fdf76bd
Signed-off-by: shihong.zheng <shihong.zheng@amlogic.com>
-rw-r--r-- | drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c index 4195ad9..a30fec7 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c @@ -215,6 +215,7 @@ struct vdec_mpeg12_hw_s { DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); struct vframe_s vfpool[VF_POOL_SIZE]; s32 vfbuf_use[DECODE_BUFFER_NUM_MAX]; + s32 ref_use[DECODE_BUFFER_NUM_MAX]; u32 frame_width; u32 frame_height; u32 frame_dur; @@ -500,7 +501,7 @@ static bool is_enough_free_buffer(struct vdec_mpeg12_hw_s *hw) int i; for (i = 0; i < hw->buf_num; i++) { - if (hw->vfbuf_use[i] == 0) + if ((hw->vfbuf_use[i] == 0) && (hw->ref_use[i] == 0)) break; } @@ -512,7 +513,8 @@ static int find_free_buffer(struct vdec_mpeg12_hw_s *hw) int i; for (i = 0; i < hw->buf_num; i++) { - if (hw->vfbuf_use[i] == 0) + if ((hw->vfbuf_use[i] == 0) && + (hw->ref_use[i] == 0)) break; } @@ -1601,10 +1603,10 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw, kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } else { - debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, - "%s, num: %d(%c), i: %d, pts: %d(%lld), dur: %d, type: %x\n", - __func__, hw->disp_num, GET_SLICE_TYPE(info), i, - vf->pts, vf->pts_us64, vf->duration, vf->type); + debug_print(DECODE_ID(hw), 0, + "%s, vf: %lx, num[%d]: %d(%c), dur: %d, type: %x, pts: %d(%lld)\n", + __func__, (ulong)vf, i, hw->disp_num, GET_SLICE_TYPE(info), + vf->duration, vf->type, vf->pts, vf->pts_us64); hw->disp_num++; if (i == 0) { struct vdec_s *vdec = hw_to_vdec(hw); @@ -1675,7 +1677,7 @@ static void force_interlace_check(struct vdec_mpeg12_hw_s *hw) static int update_reference(struct vdec_mpeg12_hw_s *hw, int index) { - hw->vfbuf_use[index]++; + hw->ref_use[index]++; if (hw->refs[1] == -1) { hw->refs[1] = index; /* @@ -1688,7 +1690,7 @@ static int update_reference(struct vdec_mpeg12_hw_s *hw, /* second pic do not output */ index = hw->buf_num; } else { - hw->vfbuf_use[hw->refs[0]]--; + hw->ref_use[hw->refs[0]]--; //old ref0 ununsed hw->refs[0] = hw->refs[1]; hw->refs[1] = index; index = hw->refs[0]; @@ -1971,8 +1973,14 @@ static void flush_output(struct vdec_mpeg12_hw_s *hw) if (hw->dec_num < 2) return; - if (index >= 0 && index < hw->buf_num) + if ((hw->refs[0] >= 0) && + (hw->refs[0] < hw->buf_num)) + hw->ref_use[hw->refs[0]] = 0; + + if (index >= 0 && index < hw->buf_num) { + hw->ref_use[index] = 0; prepare_display_buf(hw, &hw->pics[index]); + } } static int notify_v4l_eos(struct vdec_s *vdec) @@ -2165,19 +2173,42 @@ static struct vframe_s *vmpeg_vf_get(void *op_arg) return NULL; } +static int mpeg12_valid_vf_check(struct vframe_s *vf, struct vdec_mpeg12_hw_s *hw) +{ + int i; + + if (vf == NULL) + return 0; + + for (i = 0; i < VF_POOL_SIZE; i++) { + if (vf == &hw->vfpool[i]) + return 1; + } + return 0; +} + static void vmpeg_vf_put(struct vframe_s *vf, void *op_arg) { struct vdec_s *vdec = op_arg; struct vdec_mpeg12_hw_s *hw = (struct vdec_mpeg12_hw_s *)vdec->private; + if (!mpeg12_valid_vf_check(vf, hw)) { + debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR, + "invalid vf: %lx\n", (ulong)vf); + return ; + } hw->vfbuf_use[vf->index]--; + if (hw->vfbuf_use[vf->index] < 0) { + debug_print(DECODE_ID(hw), PRINT_FLAG_ERROR, + "warn: vf %lx, index %d putback repetitive\n", (ulong)vf, vf->index); + } hw->put_num++; + debug_print(DECODE_ID(hw), 0, + "%s: vf: %lx, index: %d, use: %d\n", __func__, (ulong)vf, + vf->index, hw->vfbuf_use[vf->index]); kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); - debug_print(DECODE_ID(hw), PRINT_FLAG_RUN_FLOW, - "%s: index %d, use %d\n", __func__, - vf->index, hw->vfbuf_use[vf->index]); } static int vmpeg_event_cb(int type, void *data, void *private_data) @@ -2382,7 +2413,8 @@ static void vmpeg2_dump_state(struct vdec_s *vdec) for (i = 0; i < hw->buf_num; i++) { debug_print(DECODE_ID(hw), 0, - "index %d, used %d\n", i, hw->vfbuf_use[i]); + "index %d, used %d, ref %d\n", i, + hw->vfbuf_use[i], hw->ref_use[i]); } if (vf_get_receiver(vdec->vf_provider_name)) { @@ -2396,13 +2428,13 @@ static void vmpeg2_dump_state(struct vdec_s *vdec) state); } debug_print(DECODE_ID(hw), 0, - "%s, newq(%d/%d), dispq(%d/%d) vf peek/get/put (%d/%d/%d),drop=%d, buffer_not_ready %d\n", + "%s, newq(%d/%d), dispq(%d/%d) vf pre/get/put (%d/%d/%d),drop=%d, buffer_not_ready %d\n", __func__, kfifo_len(&hw->newframe_q), VF_POOL_SIZE, kfifo_len(&hw->display_q), VF_POOL_SIZE, - hw->peek_num, + hw->disp_num, hw->get_num, hw->put_num, hw->drop_frame_count, @@ -2676,8 +2708,10 @@ static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw) kfifo_put(&hw->newframe_q, (const struct vframe_s *)vf); } - for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) + for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { hw->vfbuf_use[i] = 0; + hw->ref_use[i] = 0; + } if (hw->mm_blk_handle) { |