author | yanan.wang <yanan.wang@amlogic.com> | 2020-03-19 11:39:31 (GMT) |
---|---|---|
committer | Zhi Zhou <zhi.zhou@amlogic.com> | 2020-04-08 02:20:07 (GMT) |
commit | bbf7ffa0bb748d54292a65ebcd78ed70420b3880 (patch) | |
tree | 3eafca66bef563dfb0249d973c406b1721e977ee | |
parent | eea63252c61ff162c0069d3a332e4c3fd998fada (diff) | |
download | media_modules-bbf7ffa0bb748d54292a65ebcd78ed70420b3880.zip media_modules-bbf7ffa0bb748d54292a65ebcd78ed70420b3880.tar.gz media_modules-bbf7ffa0bb748d54292a65ebcd78ed70420b3880.tar.bz2 |
decoder: fix ff/fb for mpeg4&mpeg12&h265 format is abnormal. [1/2]
PD#SWPL-23122
Problem:
when ff/fb for mpeg4&mpeg12&h265 on trick mode is abnormal.
Solution:
add mpeg4&mpeg12&h265 TRICKMODE_I function.
Verify:
u212
Change-Id: If378a1d0d85f7212316d6c15ceff6becd0130071
Signed-off-by: yanan.wang <yanan.wang@amlogic.com>
-rw-r--r-- | drivers/frame_provider/decoder/avs2/vavs2.c | 2 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/h265/vh265.c | 30 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c | 28 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c | 33 | ||||
-rw-r--r-- | drivers/frame_provider/decoder/utils/vdec.c | 2 |
5 files changed, 85 insertions, 10 deletions
diff --git a/drivers/frame_provider/decoder/avs2/vavs2.c b/drivers/frame_provider/decoder/avs2/vavs2.c index 938312e..e459cd7 100644 --- a/drivers/frame_provider/decoder/avs2/vavs2.c +++ b/drivers/frame_provider/decoder/avs2/vavs2.c @@ -6235,7 +6235,7 @@ static int vavs2_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) (struct AVS2Decoder_s *)vdec->private; if (i_only_flag & 0x100) return 0; - if (trickmode == TRICKMODE_I) + if (trickmode == TRICKMODE_I || trickmode == TRICKMODE_I_HEVC) dec->i_only = 0x3; else if (trickmode == TRICKMODE_NONE) dec->i_only = 0x0; diff --git a/drivers/frame_provider/decoder/h265/vh265.c b/drivers/frame_provider/decoder/h265/vh265.c index 9af3de7..f1a023f 100644 --- a/drivers/frame_provider/decoder/h265/vh265.c +++ b/drivers/frame_provider/decoder/h265/vh265.c @@ -537,6 +537,7 @@ void WRITE_VREG_DBG(unsigned adr, unsigned val) #undef WRITE_VREG #define WRITE_VREG WRITE_VREG_DBG #endif +extern u32 trickmode_i; static DEFINE_MUTEX(vh265_mutex); @@ -11088,6 +11089,32 @@ static void H265_DECODE_INIT(void) } #endif +int vh265_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + struct hevc_state_s *hevc = (struct hevc_state_s *)vdec->private; + hevc_print(hevc, 0, "[%s %d] trickmode:%lu\n", __func__, __LINE__, trickmode); + + if (trickmode == TRICKMODE_I) { + trickmode_i = 1; + i_only_flag = 0x1; + } else if (trickmode == TRICKMODE_NONE) { + trickmode_i = 0; + i_only_flag = 0x0; + } else if (trickmode == 0x02) { + trickmode_i = 0; + i_only_flag = 0x02; + } else if (trickmode == 0x03) { + trickmode_i = 1; + i_only_flag = 0x03; + } else if (trickmode == 0x07) { + trickmode_i = 1; + i_only_flag = 0x07; + } + //hevc_print(hevc, 0, "i_only_flag: %d trickmode_i:%d\n", i_only_flag, trickmode_i); + + return 0; +} + static void config_decode_mode(struct hevc_state_s *hevc) { #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION @@ -12867,6 +12894,7 @@ static int amvdec_h265_probe(struct platform_device *pdev) #ifdef MULTI_INSTANCE_SUPPORT pdata->private = hevc; pdata->dec_status = vh265_dec_status; + pdata->set_trickmode = vh265_set_trickmode; pdata->set_isreset = vh265_set_isreset; is_reset = 0; if (vh265_init(pdata) < 0) { @@ -13141,7 +13169,7 @@ static int ammvdec_h265_probe(struct platform_device *pdev) pdata->private = hevc; pdata->dec_status = vh265_dec_status; - /* pdata->set_trickmode = set_trickmode; */ + pdata->set_trickmode = vh265_set_trickmode; pdata->run_ready = run_ready; pdata->run = run; pdata->reset = reset; diff --git a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c index c52de4b..71a45d0 100644 --- a/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c +++ b/drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c @@ -319,6 +319,7 @@ struct vdec_mpeg12_hw_s { struct vdec_info gvs; struct vframe_qos_s vframe_qos; unsigned int res_ch_flag; + u32 i_only; }; static void vmpeg12_local_init(struct vdec_mpeg12_hw_s *hw); static int vmpeg12_hw_ctx_restore(struct vdec_mpeg12_hw_s *hw); @@ -1525,6 +1526,7 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw, struct vdec_s *vdec = hw_to_vdec(hw); struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; ulong nv_order = VIDTYPE_VIU_NV21; + bool pb_skip = false; #ifdef NV21 type = nv_order; @@ -1536,6 +1538,12 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw, nv_order = VIDTYPE_VIU_NV12; } + pb_skip = (hw->pics[hw->refs[0]].offset == + hw->pics[hw->refs[1]].offset); + if (hw->i_only) { + pb_skip = 1; + } + user_data_ready_notify(hw, pic->pts, pic->pts_valid); if (hw->frame_prog & PICINFO_PROG) { @@ -1616,7 +1624,7 @@ static int prepare_display_buf(struct vdec_mpeg12_hw_s *hw, vf->type_original = vf->type; if ((error_skip(hw, pic->buffer_info, vf)) || - ((hw->first_i_frame_ready == 0) && + (((hw->first_i_frame_ready == 0) || pb_skip) && ((PICINFO_TYPE_MASK & pic->buffer_info) != PICINFO_TYPE_I))) { hw->drop_frame_count++; @@ -3150,6 +3158,23 @@ static void reset(struct vdec_s *vdec) pr_info("ammvdec_mpeg12: reset.\n"); } +static int vmpeg12_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + struct vdec_mpeg12_hw_s *hw = + (struct vdec_mpeg12_hw_s *)vdec->private; + if (!hw) + return 0; + + if (trickmode == TRICKMODE_I) { + hw->i_only = 0x3; + //trickmode_i = 1; + } else if (trickmode == TRICKMODE_NONE) { + hw->i_only = 0x0; + //trickmode_i = 0; + } + return 0; +} + static int ammvdec_mpeg12_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; @@ -3174,6 +3199,7 @@ static int ammvdec_mpeg12_probe(struct platform_device *pdev) pdata->private = hw; pdata->dec_status = vmmpeg12_dec_status; + pdata->set_trickmode = vmpeg12_set_trickmode; pdata->run_ready = run_ready; pdata->run = run; pdata->reset = reset; diff --git a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c index 6b904e0..aa73613 100644 --- a/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c +++ b/drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c @@ -307,6 +307,7 @@ struct vdec_mpeg4_hw_s { bool v4l_params_parsed; u32 buf_num; u32 dynamic_buf_num_margin; + u32 i_only; }; static void vmpeg4_local_init(struct vdec_mpeg4_hw_s *hw); static int vmpeg4_hw_ctx_restore(struct vdec_mpeg4_hw_s *hw); @@ -616,6 +617,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, struct aml_vcodec_ctx * v4l2_ctx = hw->v4l2_ctx; ulong nv_order = VIDTYPE_VIU_NV21; int index = pic->index; + bool pb_skip = false; /* swap uv */ if (hw->is_used_v4l) { @@ -624,6 +626,9 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, nv_order = VIDTYPE_VIU_NV12; } + if (hw->i_only) + pb_skip = 1; + if (pic->pic_info & INTERLACE_FLAG) { if (kfifo_get(&hw->newframe_q, &vf) == 0) { mmpeg4_debug_print(DECODE_ID(hw), 0, @@ -662,7 +667,7 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, "field0: pts %d, pts64 %lld, w %d, h %d, dur %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) + if (((hw->first_i_frame_ready == 0) || pb_skip) && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; @@ -713,8 +718,8 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_TIMEINFO, "filed1: pts %d, pts64 %lld, w %d, h %d, dur: %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) && - (pic->pic_type != I_PICTURE)) { + if (((hw->first_i_frame_ready == 0) || pb_skip) + && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; kfifo_put(&hw->newframe_q, @@ -778,8 +783,8 @@ static int prepare_display_buf(struct vdec_mpeg4_hw_s * hw, "prog: pts %d, pts64 %lld, w %d, h %d, dur %d\n", vf->pts, vf->pts_us64, vf->width, vf->height, vf->duration); - if ((hw->first_i_frame_ready == 0) && - (pic->pic_type != I_PICTURE)) { + if (((hw->first_i_frame_ready == 0) || pb_skip) + && (pic->pic_type != I_PICTURE)) { hw->drop_frame_count++; hw->vfbuf_use[index]--; kfifo_put(&hw->newframe_q, @@ -2265,6 +2270,23 @@ static void reset(struct vdec_s *vdec) hw->ctx_valid = 0; } +static int vmpeg4_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) +{ + struct vdec_mpeg4_hw_s *hw = + (struct vdec_mpeg4_hw_s *)vdec->private; + if (!hw) + return 0; + + if (trickmode == TRICKMODE_I) { + hw->i_only = 0x3; + trickmode_i = 1; + } else if (trickmode == TRICKMODE_NONE) { + hw->i_only = 0x0; + trickmode_i = 0; + } + return 0; +} + static int ammvdec_mpeg4_probe(struct platform_device *pdev) { struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; @@ -2289,6 +2311,7 @@ static int ammvdec_mpeg4_probe(struct platform_device *pdev) pdata->private = hw; pdata->dec_status = dec_status; /* pdata->set_trickmode = set_trickmode; */ + pdata->set_trickmode = vmpeg4_set_trickmode; pdata->run_ready = run_ready; pdata->run = run; pdata->reset = reset; diff --git a/drivers/frame_provider/decoder/utils/vdec.c b/drivers/frame_provider/decoder/utils/vdec.c index 206527f..623244f 100644 --- a/drivers/frame_provider/decoder/utils/vdec.c +++ b/drivers/frame_provider/decoder/utils/vdec.c @@ -807,7 +807,6 @@ EXPORT_SYMBOL(vdec_status); int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) { int r; - if (vdec->set_trickmode) { r = vdec->set_trickmode(vdec, trickmode); @@ -816,7 +815,6 @@ int vdec_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) trickmode); return r; } - return -1; } EXPORT_SYMBOL(vdec_set_trickmode); |