dv: enable drop frame for dv [1/1]

PD#SWPL-13115

Problem:
Apk drop lots of frames before render
the first frame, in this case, omx_run
is false and no frames will render.
Decoder doesn't have free output buffer.

Solution:
Drop dv frames in video sync before render
the first frame if app want to drop.

Verify:
Verified on U212

Change-Id: I463619f658d7f78ad8d513e17ca78482e17b3a4e
Signed-off-by: yao liu <yao.liu@amlogic.com>
This commit is contained in:
yao liu
2019-08-26 09:58:21 -04:00
committed by Luke Go
parent e04a70e982
commit fc433996d7
4 changed files with 106 additions and 39 deletions

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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;*/

View File

@@ -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);