summaryrefslogtreecommitdiff
authoryanan.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)
commitbbf7ffa0bb748d54292a65ebcd78ed70420b3880 (patch)
tree3eafca66bef563dfb0249d973c406b1721e977ee
parenteea63252c61ff162c0069d3a332e4c3fd998fada (diff)
downloadmedia_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>
Diffstat
-rw-r--r--drivers/frame_provider/decoder/avs2/vavs2.c2
-rw-r--r--drivers/frame_provider/decoder/h265/vh265.c30
-rw-r--r--drivers/frame_provider/decoder/mpeg12/vmpeg12_multi.c28
-rw-r--r--drivers/frame_provider/decoder/mpeg4/vmpeg4_multi.c33
-rw-r--r--drivers/frame_provider/decoder/utils/vdec.c2
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);