From 921c0113161663455f8d42fd066856dbc3df5234 Mon Sep 17 00:00:00 2001 From: "Yao.Liu" Date: Thu, 23 Nov 2017 10:50:28 +0800 Subject: [PATCH] media: video layer keep last frame [2/4] PD#152306: dont display frames which are dropped by apk PD#152104: video layer keep last frame Change-Id: I271ee268b8d768fe42cd60b57d1f10b12fac7fa6 Signed-off-by: Yao.Liu --- .../amlogic/media/deinterlace/deinterlace.c | 1 + .../video_processor/video_dev/amlvideo.c | 3 + .../video_processor/video_dev/amlvideo.h | 1 + drivers/amlogic/media/video_sink/video.c | 144 +++++++++++++++++- include/linux/amlogic/media/utils/amstream.h | 2 + include/linux/amlogic/media/vfm/vframe.h | 1 + 6 files changed, 145 insertions(+), 7 deletions(-) diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c index 52652c7c424c..91e857b7e804 100644 --- a/drivers/amlogic/media/deinterlace/deinterlace.c +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -4744,6 +4744,7 @@ static void vscale_skip_disable_post(struct di_buf_s *di_buf, vframe_t *disp_vf) disp_vf->height = di_buf_i->vframe->height; disp_vf->duration = di_buf_i->vframe->duration; disp_vf->pts = di_buf_i->vframe->pts; + disp_vf->omx_index = di_buf_i->vframe->omx_index; disp_vf->flag = di_buf_i->vframe->flag; disp_vf->canvas0Addr = di_post_idx[di_post_stru.canvas_id][0]; disp_vf->canvas1Addr = di_post_idx[di_post_stru.canvas_id][0]; diff --git a/drivers/amlogic/media/video_processor/video_dev/amlvideo.c b/drivers/amlogic/media/video_processor/video_dev/amlvideo.c index 66453e320d08..a9b4096e63f2 100644 --- a/drivers/amlogic/media/video_processor/video_dev/amlvideo.c +++ b/drivers/amlogic/media/video_processor/video_dev/amlvideo.c @@ -243,6 +243,7 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) dev->vf = NULL; dev->first_frame = 0; + dev->frame_num = 0; mutex_unlock(&dev->vfpMutex); } else if (type == VFRAME_EVENT_PROVIDER_QUREY_STATE) { amlvideo_vf_states(&states, dev); @@ -521,6 +522,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) mutex_unlock(&dev->vfpMutex); return -EAGAIN; } + dev->vf->omx_index = dev->frame_num; vfq_push(&dev->q_ready, dev->vf); p->index = 0; @@ -546,6 +548,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) p->timecode.type = dev->vf->width; p->timecode.flags = dev->vf->height; } + p->sequence = dev->frame_num++; vf_notify_receiver( dev->vf_provider_name, diff --git a/drivers/amlogic/media/video_processor/video_dev/amlvideo.h b/drivers/amlogic/media/video_processor/video_dev/amlvideo.h index 7f0bf727b89c..cc4c96af7654 100644 --- a/drivers/amlogic/media/video_processor/video_dev/amlvideo.h +++ b/drivers/amlogic/media/video_processor/video_dev/amlvideo.h @@ -79,6 +79,7 @@ struct vivi_dev { int inst; struct vframe_provider_s video_vf_prov; struct vframe_receiver_s video_vf_recv; + u32 frame_num; }; struct vivi_fh { diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 2e1096124146..8955746c0190 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -116,11 +116,23 @@ struct platform_resource_s { static int debugflags; static int output_fps; static u32 omx_pts; +static u32 omx_pts_set_index; +static bool omx_run; +static u32 omx_version = 2; static int omx_pts_interval_upper = 11000; static int omx_pts_interval_lower = -5500; +static int omx_pts_set_from_hwc_count; static int drop_frame_count; +#define OMX_MAX_COUNT_RESET_SYSTEMTIME 2 static int receive_frame_count; static int display_frame_count; +static int omx_need_drop_frame_num; +static bool omx_drop_done; + +/*----omx_info bit0: keep_last_frame, bit1~31: unused----*/ +static u32 omx_info = 0x1; + +static DEFINE_MUTEX(omx_mutex); #define DURATION_GCD 750 @@ -3645,6 +3657,8 @@ static inline bool vpts_expire(struct vframe_s *cur_vf, } else return false; } + if (omx_secret_mode && (!omx_run || !omx_drop_done)) + return false; if (next_vf->duration == 0) @@ -3700,6 +3714,17 @@ static inline bool vpts_expire(struct vframe_s *cur_vf, return false; } else if (omx_secret_mode == true) return true; + } else if (omx_run + && omx_secret_mode + && (omx_pts + omx_pts_interval_upper < next_vf->pts) + && (abs(omx_pts_set_index - next_vf->omx_index) <= 16) + && (omx_pts_set_index >= next_vf->omx_index)) { + pr_info("omx, omx_pts=%d omx_pts_set_index=%d pts=%d omx_index=%d\n", + omx_pts, + omx_pts_set_index, + next_vf->pts, + next_vf->omx_index); + return true; } #if 1 if (vsync_pts_inc_upint && (!freerun_mode)) { @@ -4334,6 +4359,26 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) /* pr_info("%s: %s\n", __func__, dev_id_s); */ #endif + if (omx_need_drop_frame_num > 0 && !omx_drop_done && omx_secret_mode) { + struct vframe_s *vf = NULL; + + while (1) { + vf = vf_peek(RECEIVER_NAME); + if (vf) { + if (omx_need_drop_frame_num >= vf->omx_index) { + //pr_info("vsync drop omx_index %d\n", + //vf->omx_index); + vf = vf_get(RECEIVER_NAME); + vf_put(vf, RECEIVER_NAME); + } else { + omx_drop_done = true; + break; + } + } else + break; + } + } + vf = video_vf_peek(); if ((vf) && ((vf->type & VIDTYPE_NO_VIDEO_ENABLE) == 0)) { if ((old_vmode != new_vmode) || (debug_flag == 8)) { @@ -4447,7 +4492,9 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) int diff = system_time - omx_pts; if ((diff - omx_pts_interval_upper) > 0 - || (diff - omx_pts_interval_lower) < 0) { + || (diff - omx_pts_interval_lower) < 0 + || (omx_pts_set_from_hwc_count < + OMX_MAX_COUNT_RESET_SYSTEMTIME)) { timestamp_pcrscr_enable(1); /*pr_info("system_time=%d, omx_pts=%d, diff=%d\n",*/ /*system_time, omx_pts, diff);*/ @@ -5943,6 +5990,11 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) drop_frame_count = 0; receive_frame_count = 0; display_frame_count = 0; + omx_run = false; + omx_pts_set_from_hwc_count = 0; + omx_need_drop_frame_num = 0; + omx_drop_done = false; + omx_pts_set_index = 0; #ifdef CONFIG_AM_VIDEO2 provider_name = (char *)data; if (strncmp(provider_name, "decoder", 7) == 0 @@ -6142,8 +6194,53 @@ static void _set_video_window(int *p) } } -/* - ******************************************************** +static void set_omx_pts(u32 *p) +{ + u32 tmp_pts = p[0]; + /*u32 vision = p[1];*/ + u32 set_from_hwc = p[2]; + u32 frame_num = p[3]; + u32 not_reset = p[4]; + + mutex_lock(&omx_mutex); + if (omx_pts_set_index < frame_num) + omx_pts_set_index = frame_num; + + if (not_reset == 0) + omx_pts = tmp_pts; + if (set_from_hwc == 1) { + if (!omx_run) { + omx_need_drop_frame_num = + frame_num > 0 ? frame_num-1 : 0; + if (omx_need_drop_frame_num == 0) + omx_drop_done = true; + pr_info("omx_need_drop_frame_num %d\n", + omx_need_drop_frame_num); + } + omx_run = true; + if (omx_pts_set_from_hwc_count < OMX_MAX_COUNT_RESET_SYSTEMTIME) + omx_pts_set_from_hwc_count++; + + } else if (set_from_hwc == 0 && !omx_run) { + struct vframe_s *vf = NULL; + + while (1) { + vf = vf_peek(RECEIVER_NAME); + if (vf) { + if (frame_num >= vf->omx_index) { + vf = vf_get(RECEIVER_NAME); + vf_put(vf, RECEIVER_NAME); + } else + break; + } else + break; + } + } + mutex_unlock(&omx_mutex); +} + + +/********************************************************* * /dev/amvideo APIs ******************************************************** */ @@ -6182,10 +6279,9 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg) switch (cmd) { case AMSTREAM_IOC_SET_OMX_VPTS:{ - u32 pts; - - get_user(pts, (u32 __user *)argp); - omx_pts = pts; + u32 pts[6]; + if (copy_from_user(pts, argp, sizeof(pts)) == 0) + set_omx_pts(pts); } break; @@ -6193,6 +6289,14 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg) put_user(omx_pts, (u32 __user *)argp); break; + case AMSTREAM_IOC_GET_OMX_VERSION: + put_user(omx_version, (u32 __user *)argp); + break; + + case AMSTREAM_IOC_GET_OMX_INFO: + put_user(omx_info, (u32 __user *)argp); + break; + case AMSTREAM_IOC_TRICKMODE: if (arg == TRICKMODE_I) trickmode_i = 1; @@ -6524,6 +6628,8 @@ static long amvideo_compat_ioctl(struct file *file, unsigned int cmd, ulong arg) switch (cmd) { case AMSTREAM_IOC_SET_OMX_VPTS: case AMSTREAM_IOC_GET_OMX_VPTS: + case AMSTREAM_IOC_GET_OMX_VERSION: + case AMSTREAM_IOC_GET_OMX_INFO: case AMSTREAM_IOC_TRICK_STAT: case AMSTREAM_IOC_GET_TRICK_VPTS: case AMSTREAM_IOC_GET_SYNC_ADISCON: @@ -8895,6 +9001,12 @@ static struct mconfig video_configs[] = { MC_PI32("cur_dev_idx", &cur_dev_idx), MC_PU32("new_frame_count", &new_frame_count), MC_PU32("omx_pts", &omx_pts), + MC_PU32("omx_pts_set_index", &omx_pts_set_index), + MC_PBOOL("omx_run", &omx_run), + MC_PU32("omx_version", &omx_version), + MC_PU32("omx_info", &omx_info), + MC_PI32("omx_need_drop_frame_num", &omx_need_drop_frame_num), + MC_PBOOL("omx_drop_done", &omx_drop_done), MC_PI32("omx_pts_interval_upper", &omx_pts_interval_upper), MC_PI32("omx_pts_interval_lower", &omx_pts_interval_lower), MC_PBOOL("bypass_pps", &bypass_pps), @@ -9271,6 +9383,24 @@ module_param(first_frame_toggled, uint, 0664); MODULE_PARM_DESC(omx_pts, "\n omx_pts\n"); module_param(omx_pts, uint, 0664); +MODULE_PARM_DESC(omx_run, "\n omx_run\n"); +module_param(omx_run, bool, 0664); + +MODULE_PARM_DESC(omx_pts_set_index, "\n omx_pts_set_index\n"); +module_param(omx_pts_set_index, uint, 0664); + +MODULE_PARM_DESC(omx_version, "\n omx_version\n"); +module_param(omx_version, uint, 0664); + +MODULE_PARM_DESC(omx_info, "\n omx_info\n"); +module_param(omx_info, uint, 0664); + +MODULE_PARM_DESC(omx_need_drop_frame_num, "\n omx_need_drop_frame_num\n"); +module_param(omx_need_drop_frame_num, int, 0664); + +MODULE_PARM_DESC(omx_drop_done, "\n omx_drop_done\n"); +module_param(omx_drop_done, bool, 0664); + MODULE_PARM_DESC(omx_pts_interval_upper, "\n omx_pts_interval\n"); module_param(omx_pts_interval_upper, int, 0664); diff --git a/include/linux/amlogic/media/utils/amstream.h b/include/linux/amlogic/media/utils/amstream.h index 58718dca5426..f1e931d7146c 100644 --- a/include/linux/amlogic/media/utils/amstream.h +++ b/include/linux/amlogic/media/utils/amstream.h @@ -161,6 +161,8 @@ #define AMSTREAM_IOC_SET_SUBTITLE_INFO _IOW((_A_M), 0xae, int) #define AMSTREAM_IOC_SET_OMX_VPTS _IOW((_A_M), 0xaf, int) #define AMSTREAM_IOC_GET_OMX_VPTS _IOW((_A_M), 0xb0, int) +#define AMSTREAM_IOC_GET_OMX_VERSION _IOW((_A_M), 0xb1, int) +#define AMSTREAM_IOC_GET_OMX_INFO _IOR((_A_M), 0xb2, unsigned int) #define AMSTREAM_IOC_GET_TRICK_VPTS _IOR((_A_M), 0xf0, int) #define AMSTREAM_IOC_DISABLE_SLOW_SYNC _IOW((_A_M), 0xf1, int) diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h index a0b9ab6235a6..9b760de36009 100644 --- a/include/linux/amlogic/media/vfm/vframe.h +++ b/include/linux/amlogic/media/vfm/vframe.h @@ -229,6 +229,7 @@ enum vframe_disp_mode_e { struct vframe_s { u32 index; u32 index_disp; + u32 omx_index; u32 type; u32 type_backup; u32 type_original;