dv: improve the dv process flow [1/1]

PD#SWPL-18116

Problem:
Under keeping frame case, dv toggle frame with wrong
mode, it may cause non-dv effect .

Solution:
Improve the toggle flow , pass the correct mode into
dv driver. Then using the last meta data

Verify:
Verified on u212

Change-Id: I456bb16e16810c166aba23d07a3296595032861e
Signed-off-by: Brian Zhu <brian.zhu@amlogic.com>
This commit is contained in:
Brian Zhu
2019-12-06 22:57:09 +08:00
committed by Chris KIM
parent cc9016c91e
commit 885d844b61
5 changed files with 56 additions and 71 deletions

View File

@@ -7114,11 +7114,11 @@ static void bypass_pps_path(u8 pps_state)
}
}
/* toggle mode: 0: not toggle; 1: toggle frame; 2: use keep frame */
/* pps_state 0: no change, 1: pps enable, 2: pps disable */
int dolby_vision_process(
struct vframe_s *rpt_vf,
struct vframe_s *vf,
u32 display_size,
u8 pps_state) /* 0: no change, 1: pps enable, 2: pps disable */
struct vframe_s *vf, u32 display_size,
u8 toggle_mode, u8 pps_state)
{
int src_chroma_format = 0;
u32 h_size = (display_size >> 16) & 0xffff;
@@ -7148,11 +7148,6 @@ int dolby_vision_process(
vf->compWidth : vf->width;
v_size = (vf->type & VIDTYPE_COMPRESS) ?
vf->compHeight : vf->height;
} else if (rpt_vf) {
h_size = (rpt_vf->type & VIDTYPE_COMPRESS) ?
rpt_vf->compWidth : rpt_vf->width;
v_size = (rpt_vf->type & VIDTYPE_COMPRESS) ?
rpt_vf->compHeight : rpt_vf->height;
} else {
h_size = 0;
v_size = 0;
@@ -7206,10 +7201,11 @@ int dolby_vision_process(
new_dovi_setting.video_height = 0xffff;
}
}
if (!vf && !sdr_delay) {
if ((!vf || (toggle_mode != 1)) && !sdr_delay) {
/* log to monitor if has dv toggles not needed */
/* !sdr_delay: except in transition from DV to SDR */
pr_dolby_dbg("NULL frame, hdr module %s, video %s\n",
pr_dolby_dbg("NULL/RPT frame %p, hdr module %s, video %s\n",
vf,
get_hdr_module_status(VD1_PATH)
== HDR_MODULE_ON ? "on" : "off",
get_video_enabled() ? "on" : "off");
@@ -7255,13 +7251,6 @@ int dolby_vision_process(
else if (video_status == 1)
video_turn_off = false;
if (video_turn_off &&
get_hdr_module_status(VD1_PATH)
!= HDR_MODULE_ON) {
vf = NULL;
/* rpt_vf = NULL; */
}
if (dolby_vision_mode != dolby_vision_target_mode)
format_changed = 1;
@@ -7280,21 +7269,15 @@ int dolby_vision_process(
if (sink_changed || policy_changed || format_changed ||
(video_status == 1) || (graphic_status & 2) ||
(dolby_vision_flags & FLAG_FORCE_HDMI_PKT)) {
u8 toggle_mode;
pr_dolby_dbg("sink %s, cap 0x%x, video %s, osd %s, vf %p, rpt_vf %p\n",
pr_dolby_dbg("sink %s, cap 0x%x, video %s, osd %s, vf %p, toggle mode %d\n",
current_sink_available ? "on" : "off",
current_hdr_cap,
video_turn_off ? "off" : "on",
is_graphics_output_off() ? "off" : "on",
vf, rpt_vf);
if (vf && (vf != rpt_vf))
toggle_mode = 1;
else
toggle_mode = 0;
if ((vf || rpt_vf) &&
vf, toggle_mode);
if (vf &&
!dolby_vision_parse_metadata(
vf ? vf : rpt_vf, toggle_mode, false, false)) {
vf, toggle_mode, false, false)) {
h_size = (display_size >> 16) & 0xffff;
v_size = display_size & 0xffff;
new_dovi_setting.video_width = h_size;
@@ -7303,7 +7286,7 @@ int dolby_vision_process(
}
}
if ((!vf && !rpt_vf && video_turn_off) ||
if ((!vf && video_turn_off) ||
(video_status == -1)) {
if (dolby_vision_policy_process(&mode, FORMAT_SDR)) {
pr_dolby_dbg("Fake SDR, mode->%d\n", mode);
@@ -7337,8 +7320,6 @@ int dolby_vision_process(
if (dolby_vision_status != BYPASS_PROCESS) {
if (vinfo && !is_meson_tvmode() &&
!force_stb_mode) {
if (!vf && rpt_vf)
rpt_vf = vf;
if (vf && is_hdr10plus_frame(vf)) {
/* disable dolby immediately */
pr_info("Dolby bypass: HDR10+: Switched to SDR first\n");
@@ -8237,6 +8218,7 @@ unsigned int dolby_vision_check_enable(void)
pr_info("dovi enable in uboot and mode is DV ST\n");
}
}
dolby_vision_target_mode = dolby_vision_mode;
} else
pr_info("dovi disable in uboot\n");
}

View File

@@ -2443,26 +2443,38 @@ static struct vframe_s *dvel_toggle_frame(
static void dolby_vision_proc(
struct video_layer_s *layer,
struct vpp_frame_par_s *cur_frame_par,
struct vframe_s *toggle_vf)
struct vpp_frame_par_s *cur_frame_par)
{
#ifdef OLD_DV_FLOW
static struct vframe_s *cur_dv_vf;
#endif
static u32 cur_frame_size;
struct vframe_s *disp_vf;
u8 toggle_mode;
if (is_dolby_vision_enable()) {
u32 frame_size = 0, h_size, v_size;
u8 pps_state = 0; /* pps no change */
/* TODO: check if need */
#ifdef OLD_DV_FLOW
/* force toggle when keeping frame after playing */
if (is_local_vf(layer->dispbuf) &&
!toggle_vf &&
!layer->new_frame &&
is_dolby_vision_video_on() &&
get_video_enabled()) {
toggle_vf = layer->dispbuf;
if (!dolby_vision_parse_metadata(
layer->dispbuf, 2, false, false))
dolby_vision_set_toggle_flag(1);
}
#endif
disp_vf = layer->dispbuf;
if (layer->new_frame)
toggle_mode = 1; /* new frame */
else if (!disp_vf || is_local_vf(disp_vf))
toggle_mode = 2; /* keep frame */
else
toggle_mode = 0; /* pasue frame */
if (cur_frame_par) {
if (layer->new_vpp_setting) {
@@ -2499,34 +2511,28 @@ static void dolby_vision_proc(
v_size /=
(cur_frame_par->vscale_skip_count + 1);
frame_size = (h_size << 16) | v_size;
} else if (toggle_vf) {
h_size = (toggle_vf->type & VIDTYPE_COMPRESS) ?
toggle_vf->compWidth : toggle_vf->width;
v_size = (toggle_vf->type & VIDTYPE_COMPRESS) ?
toggle_vf->compHeight : toggle_vf->height;
} else if (disp_vf) {
h_size = (disp_vf->type & VIDTYPE_COMPRESS) ?
disp_vf->compWidth : disp_vf->width;
v_size = (disp_vf->type & VIDTYPE_COMPRESS) ?
disp_vf->compHeight : disp_vf->height;
frame_size = (h_size << 16) | v_size;
}
if (is_local_vf(layer->dispbuf)) {
if (get_video_enabled())
toggle_vf = layer->dispbuf;
else
toggle_vf = NULL;
}
/* trigger dv process once when stop playing */
/* because toggle_vf is not sync with video off */
if (cur_dv_vf && !toggle_vf)
dolby_vision_set_toggle_flag(1);
#ifdef OLD_DV_FLOW
/* trigger dv process once when stop playing */
/* because disp_vf is not sync with video off */
if (cur_dv_vf && !disp_vf)
dolby_vision_set_toggle_flag(1);
cur_dv_vf = disp_vf;
#endif
if (cur_frame_size != frame_size) {
cur_frame_size = frame_size;
if (!toggle_vf && get_video_enabled())
toggle_vf = layer->dispbuf;
dolby_vision_set_toggle_flag(1);
}
cur_dv_vf = toggle_vf;
dolby_vision_process(
layer->dispbuf, toggle_vf,
frame_size, pps_state);
disp_vf, frame_size,
toggle_mode, pps_state);
dolby_vision_update_setting();
}
return;
@@ -2781,9 +2787,7 @@ static void pip_swap_frame(struct vframe_s *vf)
layer->new_vpp_setting = false;
}
static s32 pip_render_frame(
struct video_layer_s *layer,
struct vframe_s *toggle_vf)
static s32 pip_render_frame(struct video_layer_s *layer)
{
struct vpp_frame_par_s *frame_par;
u32 zoom_start_y, zoom_end_y;
@@ -2982,9 +2986,7 @@ static void primary_swap_frame(
ATRACE_COUNTER(__func__, 0);
}
static s32 primary_render_frame(
struct video_layer_s *layer,
struct vframe_s *toggle_vf)
static s32 primary_render_frame(struct video_layer_s *layer)
{
struct vpp_frame_par_s *frame_par;
bool force_setting = false;
@@ -3007,7 +3009,7 @@ static s32 primary_render_frame(
/* dolby vision process for each vsync */
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
dolby_vision_proc(layer, frame_par, toggle_vf);
dolby_vision_proc(layer, frame_par);
#endif
/* process cur frame for each vsync */
@@ -4327,11 +4329,8 @@ SET_FILTER:
}
/* filter setting management */
frame_par_di_set = primary_render_frame(
&vd_layer[0], vd_layer[0].dispbuf);
pip_render_frame(
&vd_layer[1], vd_layer[1].dispbuf);
frame_par_di_set = primary_render_frame(&vd_layer[0]);
pip_render_frame(&vd_layer[1]);
if ((cur_vd1_path_id != vd1_path_id ||
cur_vd2_path_id != vd2_path_id) &&
@@ -4357,6 +4356,10 @@ SET_FILTER:
else
vd_layer[0].enable_3d_mode = mode_3d_disable;
/* all frames has been renderred, so reset new frame flag */
vd_layer[0].new_frame = false;
vd_layer[1].new_frame = false;
if (cur_dispbuf && cur_dispbuf->process_fun &&
((vd1_path_id == VFM_PATH_AMVIDEO) ||
(vd1_path_id == VFM_PATH_DEF))) {

View File

@@ -4154,7 +4154,6 @@ s32 layer_swap_frame(
bool first_picture = false;
bool enable_layer = false;
bool frame_changed;
bool new_frame = false;
struct video_layer_s *layer = NULL;
struct disp_info_s *layer_info = NULL;
int ret = vppfilter_success;
@@ -4171,7 +4170,7 @@ s32 layer_swap_frame(
if (layer->dispbuf != vf) {
layer->new_vframe_count++;
new_frame = true;
layer->new_frame = true;
if (!layer->dispbuf ||
(layer->new_vframe_count == 1) ||
(is_local_vf(layer->dispbuf)))

View File

@@ -218,6 +218,7 @@ struct video_layer_s {
bool property_changed;
u8 force_config_cnt;
bool new_vpp_setting;
bool new_frame;
u32 vout_type;
bool bypass_pps;

View File

@@ -66,8 +66,8 @@ int dolby_vision_wait_metadata(struct vframe_s *vf);
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);
struct vframe_s *vf, u32 display_size,
u8 toggle_mode, u8 pps_state);
void dolby_vision_init_receiver(void *pdev);
void dolby_vision_vf_put(struct vframe_s *vf);
struct vframe_s *dolby_vision_vf_peek_el(struct vframe_s *vf);