diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c index 05de28747cf6..e56a5f4a729e 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c @@ -6062,7 +6062,7 @@ int dolby_vision_wait_metadata(struct vframe_s *vf) return ret; } -int dolby_vision_update_metadata(struct vframe_s *vf) +int dolby_vision_update_metadata(struct vframe_s *vf, bool drop_flag) { int ret = -1; @@ -6071,7 +6071,8 @@ int dolby_vision_update_metadata(struct vframe_s *vf) if (vf && dolby_vision_vf_check(vf)) { ret = dolby_vision_parse_metadata( vf, 1, false); - frame_count++; + if (!drop_flag) + frame_count++; } return ret; diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 1d99153f1e8a..c3f45443ce71 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -186,6 +186,9 @@ static u32 cur_disp_omx_index; #define DEBUG_FLAG_FFPLAY (1<<0) #define DEBUG_FLAG_CALC_PTS_INC (1<<1) +static bool dovi_drop_flag; +static int dovi_drop_frame_num; + #define RECEIVER_NAME "amvideo" static s32 amvideo_poll_major; @@ -5979,9 +5982,11 @@ struct vframe_s *dolby_vision_toggle_frame(struct vframe_s *vf) struct vframe_s *toggle_vf = NULL; int width_bl, width_el; int height_bl, height_el; - int ret = dolby_vision_update_metadata(vf); + int ret; - cur_dispbuf2 = dolby_vision_vf_peek_el(vf); + ret = dolby_vision_update_metadata(vf, false); + if (!is_dolby_vision_el_disable() || for_dolby_vision_certification()) + cur_dispbuf2 = dolby_vision_vf_peek_el(vf); if (cur_dispbuf2) { if (cur_dispbuf2->type & VIDTYPE_COMPRESS) { VSYNC_WR_MPEG_REG(VD2_AFBC_HEAD_BADDR, @@ -6056,6 +6061,30 @@ static int dolby_vision_need_wait(void) return 1; return 0; } + +/* 1: drop fail; 0: drop success*/ +static int dolby_vision_drop_frame(void) +{ + struct vframe_s *vf; + + if (dolby_vision_need_wait()) { + if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME) + pr_info("drop frame need wait!\n"); + return 1; + } + vf = video_vf_get(); + + if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME) + pr_info("drop vf %p, index %d\n", vf, vf->omx_index); + + dolby_vision_update_metadata(vf, true); + video_vf_put(vf); + + if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME) + pr_info("drop vf %p done\n", vf); + + return 0; +} #endif /* patch for 4k2k bandwidth issue, skiw mali and vpu mif */ static void dmc_adjust_for_mali_vpu(unsigned int width, @@ -6649,6 +6678,40 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) /* pr_info("%s: %s\n", __func__, dev_id_s); */ #endif +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + if (is_dolby_vision_enable() && dovi_drop_flag) { + struct vframe_s *vf = NULL; + unsigned int cnt = 10; + int max_drop_index; + + if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME) + pr_info("dovi_drop_frame_num %d, omx_run %d\n", + dovi_drop_frame_num, omx_run); + while (cnt--) { + vf = video_vf_peek(); + if (vf && is_dovi_frame(vf)) { + max_drop_index = omx_run ? + omx_need_drop_frame_num : dovi_drop_frame_num; + + if (max_drop_index >= vf->omx_index) { + if (dolby_vision_drop_frame() == 1) + break; + } else if (omx_run && + (vf->omx_index > + omx_need_drop_frame_num)) { + /* all drop done*/ + dovi_drop_flag = false; + omx_drop_done = true; + pr_info("dolby vision drop done\n"); + break; + } + } else { + break; + } + } + } +#endif + if (omx_need_drop_frame_num > 0 && !omx_drop_done && omx_secret_mode) { struct vframe_s *vf = NULL; @@ -6658,10 +6721,6 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (is_dolby_vision_enable() && vf && is_dovi_frame(vf)) { - pr_info("vsync_isr_in, ignore the omx %d frames drop for dv frame\n", - omx_need_drop_frame_num); - omx_need_drop_frame_num = 0; - omx_drop_done = true; break; } #endif @@ -7027,15 +7086,31 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) if (omx_continuous_drop_flag && !(debug_flag & DEBUG_FLAG_OMX_DISABLE_DROP_FRAME)) { - if (debug_flag & DEBUG_FLAG_OMX_DEBUG_DROP_FRAME) { - pr_info("drop omx_index %d, pts %d\n", - vf->omx_index, vf->pts); + if (is_dolby_vision_enable() && vf && + is_dovi_frame(vf)) { + if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME) + pr_info("dovi ignore continuous drop\n"); + /* if (omx_run) + * dolby_vision_drop_frame(); + */ + } else { + if (debug_flag & + DEBUG_FLAG_OMX_DEBUG_DROP_FRAME) { + pr_info("drop omx_index %d, pts %d\n", + vf->omx_index, vf->pts); + } + vf = vf_get(RECEIVER_NAME); + if (vf) { + vf_put(vf, RECEIVER_NAME); + video_drop_vf_cnt++; + if (debug_flag & + DEBUG_FLAG_PRINT_DROP_FRAME) + pr_info("drop frame: drop count %d\n", + video_drop_vf_cnt); + } + vf = video_vf_peek(); + continue; } - vf = vf_get(RECEIVER_NAME); - if (vf) - vf_put(vf, RECEIVER_NAME); - vf = video_vf_peek(); - continue; } if (vpts_expire(cur_dispbuf, vf, toggle_cnt) || show_nosync) { @@ -8818,6 +8893,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) omx_continuous_drop_count = 0; omx_continuous_drop_flag = false; cur_disp_omx_index = 0; + dovi_drop_flag = false; + dovi_drop_frame_num = 0; mutex_unlock(&omx_mutex); } else if (type == VFRAME_EVENT_PROVIDER_RESET) { video_vf_light_unreg_provider(1); @@ -8839,6 +8916,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data) omx_continuous_drop_count = 0; omx_continuous_drop_flag = false; cur_disp_omx_index = 0; + dovi_drop_flag = false; + dovi_drop_frame_num = 0; mutex_unlock(&omx_mutex); //init_hdr_info(); @@ -9282,21 +9361,18 @@ static void set_omx_pts(u32 *p) } else if (set_from_hwc == 0 && !omx_run) { struct vframe_s *vf = NULL; - u32 donot_drop = 0; -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - u32 dovi_dual_layer = 0; -#endif while (try_cnt--) { vf = vf_peek(RECEIVER_NAME); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (is_dolby_vision_enable() && vf && is_dovi_frame(vf)) { - pr_info("set_omx_pts ignore the omx %d frames drop for dv frame\n", - frame_num); - donot_drop = 1; - if (is_dovi_dual_layer_frame(vf)) - dovi_dual_layer = 1; + if (debug_flag & + DEBUG_FLAG_OMX_DV_DROP_FRAME) + pr_info("dovi will drop %d in vsync\n", + frame_num); + dovi_drop_flag = true; + dovi_drop_frame_num = frame_num; break; } #endif @@ -9312,17 +9388,6 @@ static void set_omx_pts(u32 *p) } else break; } - if (donot_drop && omx_pts_set_from_hwc_count > 0) { - pr_info("reset omx_run to true.\n"); - omx_run = true; - } -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - if (dovi_dual_layer) { - omx_run = true; - omx_drop_done = true; - pr_info("dolby dual layer donot drop.\n"); - } -#endif } mutex_unlock(&omx_mutex); } diff --git a/drivers/amlogic/media/video_sink/video_priv.h b/drivers/amlogic/media/video_sink/video_priv.h index 159be8968598..1486966eaceb 100644 --- a/drivers/amlogic/media/video_sink/video_priv.h +++ b/drivers/amlogic/media/video_sink/video_priv.h @@ -34,6 +34,8 @@ #define DEBUG_FLAG_FRAME_DETECT 0x800000 #define DEBUG_FLAG_OMX_DEBUG_DROP_FRAME 0x1000000 #define DEBUG_FLAG_OMX_DISABLE_DROP_FRAME 0x2000000 +#define DEBUG_FLAG_PRINT_DROP_FRAME 0x4000000 +#define DEBUG_FLAG_OMX_DV_DROP_FRAME 0x8000000 /*for video.c's static int debug_flag;*/ diff --git a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h index f00fac0a6e5c..b2d9b16ba518 100644 --- a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h +++ b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h @@ -64,9 +64,8 @@ extern void dolby_vision_set_toggle_flag(int flag); extern int dolby_vision_wait_metadata(struct vframe_s *vf); extern int dolby_vision_pop_metadata(void); int dolby_vision_update_metadata(struct vframe_s *vf, bool drop_flag); -int dolby_vision_process( - struct vframe_s *rpt_vf, struct vframe_s *vf, - u32 display_size, u8 pps_state); +extern int dolby_vision_process(struct vframe_s *vf, u32 display_size, + u8 pps_state); extern void dolby_vision_init_receiver(void *pdev); extern void dolby_vision_vf_put(struct vframe_s *vf); extern struct vframe_s *dolby_vision_vf_peek_el(struct vframe_s *vf);