vpp: improve the csc and dv switch flow and policy [1/1]

PD#SWPL-13990

Problem:
There are some conflicts between csc and dv module switching.
Can not switch to SDR->DV when HDR core is working on SDR->SDR mode.

Solution:
1. Improve the switching policy. DV and csc will use same on.
2. add mute operation under dv mode.

Verify:
Verified on AC211

Change-Id: I4d59328fc34228a0ef5275d22643932c4dfe00b0
Signed-off-by: Brian Zhu <brian.zhu@amlogic.com>
This commit is contained in:
Brian Zhu
2019-09-12 03:39:26 +08:00
committed by Jianxin Pan
parent 87952ccbc7
commit 190492f6a9
8 changed files with 1315 additions and 444 deletions

View File

@@ -127,7 +127,7 @@ static ssize_t write_file_hdr_cfgosd(
hdr_set_cfg_osd_100(val);
pr_info("en_osd_lut_100: %d\n", phdr->hdr_cfg.en_osd_lut_100);
pr_info("HDR: en_osd_lut_100: %d\n", phdr->hdr_cfg.en_osd_lut_100);
return count;
}
@@ -337,12 +337,56 @@ static uint hdmi_csc_type = 0xffff;
module_param(hdmi_csc_type, uint, 0444);
MODULE_PARM_DESC(hdmi_csc_type, "\n current color space convert type\n");
/* 0: follow sink, 1: follow source, 2: debug, 0xff: bootup default value */
/* by default follow source to match default sdr_mode*/
static uint hdr_policy = 1;
static uint cur_hdr_policy = 0xff;
module_param(hdr_policy, uint, 0664);
MODULE_PARM_DESC(hdr_policy, "\n current hdr_policy\n");
/* when cur_hdr_policy == 2 && dovi disable */
/* enum output_format_e */
/* BT709 = 1, */
/* BT2020 = 2, */
/* BT2020_PQ = 3, */
/* BT2020_PQ_DYNAMIC = 4, */
/* BT2020_HLG = 5, */
/* BT2100_IPT = 6 */
/* BT2020 = 2: 2020 + gamma not support in hdmi now */
static uint force_output = 1; /* BT709 */
module_param(force_output, uint, 0664);
MODULE_PARM_DESC(force_output, "\n current force_output\n");
int get_hdr_policy(void)
{
int dv_policy = 0;
int dv_mode = 0;
if (is_dolby_vision_enable()) {
/* sync hdr_policy with dolby_vision_policy */
/* get current dolby_vision_mode */
dv_policy = get_dolby_vision_policy();
dv_mode = get_dolby_vision_mode();
if ((dv_policy != DOLBY_VISION_FORCE_OUTPUT_MODE) ||
(dv_mode != DOLBY_VISION_OUTPUT_MODE_BYPASS)) {
/* use dv policy when not force bypass */
return dv_policy;
}
}
return hdr_policy;
}
EXPORT_SYMBOL(get_hdr_policy);
enum output_format_e get_force_output(void)
{
return force_output;
}
EXPORT_SYMBOL(get_force_output);
static uint hdr_mode = 2; /* 0: hdr->hdr, 1:hdr->sdr, 2:auto */
module_param(hdr_mode, uint, 0664);
MODULE_PARM_DESC(hdr_mode, "\n set hdr_mode\n");
static uint cur_hdr_mode;
/* 0: hdr->hdr, 1:hdr->sdr, 2:hdr->hlg */
uint hdr_process_mode[VD_PATH_MAX];
uint cur_hdr_process_mode[VD_PATH_MAX] = {PROC_OFF, PROC_OFF};
@@ -418,18 +462,15 @@ module_param(hdr_flag, uint, 0664);
MODULE_PARM_DESC(hdr_flag, "\n set hdr_flag\n");
/* 0: off, 1: normal, 2: bypass */
static int video_process_status[VD_PATH_MAX];
static int video_process_status[VD_PATH_MAX] = {2, 2};
module_param_array(video_process_status, uint, &vd_path_max, 0664);
MODULE_PARM_DESC(video_process_status, "\n video_process_status\n");
int get_hdr_module_status(enum vd_path_e vd_path)
{
return video_process_status[vd_path];
}
EXPORT_SYMBOL(get_hdr_module_status);
void set_hdr_module_status(enum vd_path_e vd_path, int status)
{
video_process_status[vd_path] = status;
pr_csc(4, "video_process_status[VD%d] = %d",
vd_path + 1, status);
}
EXPORT_SYMBOL(set_hdr_module_status);
@@ -3714,8 +3755,8 @@ int signal_type_changed(struct vframe_s *vf,
u32 default_signal_type;
int change_flag = 0;
int i, j;
struct vframe_master_display_colour_s *p_cur;
struct vframe_master_display_colour_s *p_new;
struct vframe_master_display_colour_s *p_cur = NULL;
struct vframe_master_display_colour_s *p_new = NULL;
struct vframe_master_display_colour_s cus;
int ret;
@@ -3820,9 +3861,11 @@ int signal_type_changed(struct vframe_s *vf,
/*vf->signal_type, signal_type);*/
}
ret = hdr10_primaries_changed(p_new, p_cur);
if (ret)
change_flag |= SIG_PRI_INFO;
if (p_new && p_cur) {
ret = hdr10_primaries_changed(p_new, p_cur);
if (ret)
change_flag |= SIG_PRI_INFO;
}
if (change_flag & SIG_PRI_INFO) {
pr_csc(1, "vd%d Master_display_colour changed %x.\n",
vd_path + 1, ret);
@@ -6264,23 +6307,100 @@ static void hdr_support_process(struct vinfo_s *vinfo, enum vd_path_e vd_path)
sdr_process_mode[vd_path] = sdr_mode;
}
static int sink_support_dolby_vision(const struct vinfo_s *vinfo)
{
if (!vinfo || !vinfo->vout_device || !vinfo->vout_device->dv_info)
return 0;
if (vinfo->vout_device->dv_info->ieeeoui != 0x00d046)
return 0;
if (vinfo->vout_device->dv_info->block_flag != CORRECT)
return 0;
if (strstr(vinfo->name, "2160p60hz") ||
strstr(vinfo->name, "2160p50hz")) {
if (!vinfo->vout_device->dv_info->sup_2160p60hz)
return 0;
}
return 1;
}
static int sink_support_hdr(const struct vinfo_s *vinfo)
{
if (!vinfo)
return 0;
if (vinfo->hdr_info.hdr_support & HDR_SUPPORT)
return 1;
return 0;
}
static int sink_support_hlg(const struct vinfo_s *vinfo)
{
if (!vinfo)
return 0;
if (vinfo->hdr_info.hdr_support & HLG_SUPPORT)
return 1;
return 0;
}
static int sink_support_hdr10_plus(const struct vinfo_s *vinfo)
{
if ((vinfo->hdr_info.hdr10plus_info.ieeeoui
== 0x90848B) &&
(vinfo->hdr_info.hdr10plus_info.application_version
== 1))
return 1;
return 0;
}
bool is_vinfo_available(const struct vinfo_s *vinfo)
{
return strcmp(vinfo->name, "invalid") &&
strcmp(vinfo->name, "null") &&
strcmp(vinfo->name, "576cvbs") &&
strcmp(vinfo->name, "470cvbs");
}
EXPORT_SYMBOL(is_vinfo_available);
static enum hdr_type_e get_source_type(enum vd_path_e vd_path)
{
get_cur_vd_signal_type(vd_path);
if (vd_path == VD1_PATH &&
is_dolby_vision_enable() &&
get_dolby_vision_src_format()
== HDRTYPE_DOVI)
return HDRTYPE_DOVI;
if (((signal_transfer_characteristic == 14) ||
(signal_transfer_characteristic == 18)) &&
(signal_color_primaries == 9))
(signal_transfer_characteristic == 18)) &&
(signal_color_primaries == 9))
return HDRTYPE_HLG;
else if ((signal_transfer_characteristic == 0x30)
&& (signal_color_primaries == 9))
return HDRTYPE_HDR10PLUS;
else if ((signal_transfer_characteristic == 16)
|| (signal_color_primaries == 9))
else if ((signal_transfer_characteristic == 0x30) &&
(signal_color_primaries == 9)) {
if (sink_support_hdr10_plus(get_current_vinfo()))
return HDRTYPE_HDR10PLUS;
else
return HDRTYPE_HDR10;
} else if ((signal_transfer_characteristic == 16) ||
(signal_color_primaries == 9))
return HDRTYPE_HDR10;
else
return HDRTYPE_SDR;
}
int get_hdr_module_status(enum vd_path_e vd_path)
{
if (vd_path == VD1_PATH &&
is_dolby_vision_enable() &&
get_dolby_vision_policy()
== DOLBY_VISION_FOLLOW_SOURCE &&
get_source_type(VD1_PATH)
== HDRTYPE_SDR &&
sdr_process_mode[VD1_PATH]
== PROC_BYPASS)
return HDR_MODULE_BYPASS;
return video_process_status[vd_path];
}
EXPORT_SYMBOL(get_hdr_module_status);
static bool video_layer_wait_on[VD_PATH_MAX];
bool is_video_layer_on(enum vd_path_e vd_path)
{
@@ -6346,6 +6466,7 @@ static void hdr10_plus_metadata_update(struct vframe_s *vf,
static struct hdr10plus_para hdmitx_hdr10plus_params[VD_PATH_MAX];
static int hdr10_plus_pkt_update;
static bool hdr10_plus_pkt_on;
/* 0: no delay, 1:delay one frame, >1:delay one frame and repeat */
static uint hdr10_plus_pkt_delay = 1;
static struct hdr10plus_para cur_hdr10plus_params;
static struct master_display_info_s cur_send_info;
@@ -6418,8 +6539,8 @@ void send_hdr10_plus_pkt(enum vd_path_e vd_path)
else
hdr10_plus_pkt_update = HDRPLUS_PKT_IDLE;
pr_csc(2, "send_hdr10_plus_pkt update\n");
} else if ((hdr10_plus_pkt_update == HDRPLUS_PKT_REPEAT)
&& (get_hdr10_plus_pkt_delay() > 1)) {
} else if ((hdr10_plus_pkt_update == HDRPLUS_PKT_REPEAT) &&
(get_hdr10_plus_pkt_delay() > 1)) {
vdev->fresh_tx_hdr_pkt(
&cur_send_info);
vdev->fresh_tx_hdr10plus_pkt(
@@ -6918,6 +7039,59 @@ static void video_process(
}
}
static int current_hdr_cap[VD_PATH_MAX] = {-1, -1}; /* should set when probe */
static int current_sink_available[VD_PATH_MAX] = {-1, -1};
int is_sink_cap_changed(
const struct vinfo_s *vinfo,
int *p_current_hdr_cap,
int *p_current_sink_available)
{
int hdr_cap;
int sink_available;
int ret = 0;
if (is_vinfo_available(vinfo)) {
hdr_cap = (1 << 0) |
(sink_support_dolby_vision(vinfo) << 1) |
(sink_support_hdr10_plus(vinfo) << 2) |
(sink_support_hdr(vinfo) << 3) |
(sink_support_hlg(vinfo) << 3);
sink_available = 1;
} else {
hdr_cap = 0;
*p_current_hdr_cap = 0;
sink_available = 0;
}
if (*p_current_hdr_cap == -1) {
*p_current_hdr_cap = hdr_cap;
ret |= 4;
} else if (*p_current_hdr_cap != hdr_cap) {
*p_current_hdr_cap = hdr_cap;
ret |= 2;
}
if (*p_current_sink_available != sink_available) {
*p_current_sink_available = sink_available;
ret |= 1;
}
return ret;
}
EXPORT_SYMBOL(is_sink_cap_changed);
static bool video_on[VD_PATH_MAX];
int is_video_turn_on(bool *vd_on, enum vd_path_e vd_path)
{
int ret = 0;
if (vd_on[vd_path] != is_video_layer_on(vd_path)) {
vd_on[vd_path] = is_video_layer_on(vd_path);
ret = vd_on[vd_path] ? 1 : -1;
}
return ret;
}
EXPORT_SYMBOL(is_video_turn_on);
static int vpp_matrix_update(
struct vframe_s *vf, struct vinfo_s *vinfo, int flags,
enum vd_path_e vd_path)
@@ -6951,13 +7125,19 @@ static int vpp_matrix_update(
else
csc_type = get_csc_type();
if (video_process_status[vd_path] == HDR_MODULE_BYPASS) {
if (is_video_layer_on(vd_path) &&
(!is_dolby_vision_on() || (vd_path == VD2_PATH)))
if ((video_process_status[vd_path] == HDR_MODULE_BYPASS) &&
!(video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS)) {
if ((is_video_layer_on(vd_path) ||
video_layer_wait_on[vd_path]) &&
(!is_dolby_vision_on() ||
(vd_path == VD2_PATH))) {
video_process_status[vd_path] = HDR_MODULE_ON;
else
pr_csc(4,
"video_process_status[%s] = HDR_MODULE_ON\n",
vd_path == VD1_PATH ? "VD1" : "VD2");
} else {
return 2;
}
}
if (is_dolby_vision_on() && (vd_path == VD1_PATH))
@@ -6969,6 +7149,12 @@ static int vpp_matrix_update(
enum vd_path_e oth_path =
(vd_path == VD1_PATH) ? VD2_PATH : VD1_PATH;
if (get_hdr_policy() != cur_hdr_policy) {
pr_csc(4, "policy changed from %d to %d.\n",
cur_hdr_policy,
get_hdr_policy());
signal_change_flag |= SIG_HDR_MODE;
}
source_format[VD1_PATH] = get_source_type(VD1_PATH);
source_format[VD2_PATH] = get_source_type(VD2_PATH);
get_cur_vd_signal_type(vd_path);
@@ -7026,11 +7212,13 @@ static int vpp_matrix_update(
SIG_SRC_OUTPUT_CHG | SIG_HDR10_PLUS_MODE |
SIG_SRC_CHG | SIG_HDR_OOTF_CHG))) {
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) &&
(get_cpu_type() != MESON_CPU_MAJOR_ID_TL1))
(get_cpu_type() != MESON_CPU_MAJOR_ID_TL1)) {
video_post_process(csc_type, vinfo, vd_path);
else
cur_hdr_policy = get_hdr_policy();
} else {
video_process(vf, csc_type, signal_change_flag,
vinfo, p, vd_path);
}
}
/* eye protection mode */
@@ -7040,11 +7228,12 @@ static int vpp_matrix_update(
return 0;
}
static struct vframe_s last_vf_backup[VD_PATH_MAX];
static struct vframe_s *last_vf[VD_PATH_MAX];
static int last_vf_signal_type[VD_PATH_MAX];
static int null_vf_cnt[VD_PATH_MAX];
static int prev_hdr_support;
static int null_vf_cnt[VD_PATH_MAX] = {2, 2};
static int prev_color_fmt;
static bool dovi_on;
static unsigned int fg_vf_sw_dbg;
unsigned int null_vf_max = 2;
@@ -7057,9 +7246,12 @@ int amvecm_matrix_process(
{
struct vframe_s fake_vframe;
struct vinfo_s *vinfo = get_current_vinfo();
int toggle_frame;
int toggle_frame = 0;
int i;
int ret;
int sink_changed = 0;
bool cap_changed = false;
bool send_fake_frame = false;
if ((get_cpu_type() < MESON_CPU_MAJOR_ID_GXTVBB) ||
is_meson_gxl_package_905M2() || (csc_en == 0) ||
@@ -7083,15 +7275,43 @@ int amvecm_matrix_process(
CSC_ON);
}
if (is_dolby_vision_on() && vd_path == VD1_PATH) {
if ((video_process_status[vd_path] == HDR_MODULE_BYPASS)
&& (vf || vf_rpt))
return vpp_matrix_update(
vf ? vf : vf_rpt, vinfo, flags, vd_path);
else
return 0;
if (vd_path == VD1_PATH) {
if (is_dolby_vision_on()) {
dovi_on = true;
if ((video_process_status[vd_path]
== HDR_MODULE_BYPASS) &&
(vf || vf_rpt))
return vpp_matrix_update(
vf ? vf : vf_rpt,
vinfo, flags, vd_path);
else
return 0;
} else {
/* dv from on to off */
if (dovi_on) {
cap_changed = true;
dovi_on = false;
}
}
}
sink_changed = is_sink_cap_changed(vinfo,
&current_hdr_cap[vd_path],
&current_sink_available[vd_path]);
if (sink_changed) {
cap_changed = sink_changed & 0x02;
pr_csc(4, "sink %s, cap%s 0x%x, vd%d %s %p %p\n",
current_sink_available[vd_path] ? "on" : "off",
cap_changed ? " changed" : "",
current_hdr_cap[vd_path],
vd_path + 1,
is_video_layer_on(vd_path) ? "on" : "off",
vf, vf_rpt);
}
if (is_video_turn_on(video_on, vd_path) == 1)
cap_changed = true;
if ((vf != NULL) && (flags & CSC_FLAG_CHECK_OUTPUT)) {
ret = vpp_matrix_update(vf, vinfo, flags, vd_path);
if (ret == 1) {
@@ -7105,12 +7325,20 @@ int amvecm_matrix_process(
}
} else if ((vf != NULL) && (flags & CSC_FLAG_TOGGLE_FRAME)) {
if (is_video_layer_on(vd_path) ||
video_layer_wait_on[vd_path] ||
video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS) {
video_process_status[vd_path] = HDR_MODULE_ON;
if (video_process_status[vd_path] != HDR_MODULE_ON) {
video_process_status[vd_path] = HDR_MODULE_ON;
pr_csc(4,
"video_process_status[%s] = HDR_MODULE_ON\n",
vd_path == VD1_PATH ? "VD1" : "VD2");
}
vpp_matrix_update(vf, vinfo, flags, vd_path);
video_process_flags[vd_path] &=
~PROC_FLAG_FORCE_PROCESS;
last_vf[vd_path] = vf;
memcpy(&last_vf_backup[vd_path], vf,
sizeof(struct vframe_s));
last_vf[vd_path] = &last_vf_backup[vd_path];
last_vf_signal_type[vd_path] = vf->signal_type;
null_vf_cnt[vd_path] = 0;
pr_csc(2, "vd%d: process toggle frame(%p) %x\n",
@@ -7123,100 +7351,180 @@ int amvecm_matrix_process(
fg_vf_sw_dbg = 1;
/* debug vframe info backup */
dbg_vf = vf;
} else if ((vf_rpt != NULL) && is_video_layer_on(vd_path)) {
if (video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS) {
} else if (vf_rpt &&
(is_video_layer_on(vd_path) ||
video_layer_wait_on[vd_path])) {
if ((video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS) ||
cap_changed) {
if (video_process_status[vd_path] != HDR_MODULE_ON) {
video_process_status[vd_path] = HDR_MODULE_ON;
pr_csc(4,
"video_process_status[%s] = HDR_MODULE_ON\n",
vd_path == VD1_PATH ? "VD1" : "VD2");
}
vpp_matrix_update(vf_rpt, vinfo, flags, vd_path);
video_process_flags[vd_path] &=
~PROC_FLAG_FORCE_PROCESS;
pr_csc(2, "vd%d: rpt and process frame(%p)\n",
vd_path + 1, vf_rpt);
} else
pr_csc(4, "vd%d: rpt and process frame(%p)\n",
vd_path + 1, vf_rpt);
} else {
pr_csc(2, "vd%d: rpt frame(%p)\n", vd_path + 1, vf_rpt);
}
null_vf_cnt[vd_path] = 0;
fg_vf_sw_dbg = 2;
} else if ((last_vf[vd_path] != NULL) && is_video_layer_on(vd_path)) {
pr_csc(2, "vd%d: rpt frame local\n",
vd_path + 1);
} else if (last_vf[vd_path] &&
(is_video_layer_on(vd_path) ||
video_layer_wait_on[vd_path])) {
if (video_process_flags[vd_path] & PROC_FLAG_FORCE_PROCESS ||
cap_changed) {
vpp_matrix_update(
last_vf[vd_path], vinfo, flags, vd_path);
video_process_flags[vd_path] &=
~PROC_FLAG_FORCE_PROCESS;
pr_csc(4, "vd%d: rpt and process frame local(%p)\n",
vd_path + 1, last_vf[vd_path]);
} else {
pr_csc(2, "vd%d: rpt frame local\n",
vd_path + 1);
}
null_vf_cnt[vd_path] = 0;
fg_vf_sw_dbg = 3;
} else {
last_vf[vd_path] = NULL;
if (null_vf_cnt[vd_path] <= null_vf_max)
null_vf_cnt[vd_path]++;
/* handle change between TV support/not support HDR */
if (prev_hdr_support != vinfo->hdr_info.hdr_support) {
if ((vd_path == VD1_PATH) ||
((vd_path == VD2_PATH) &&
is_video_layer_on(VD2_PATH)))
if (cap_changed) {
if (is_video_layer_on(vd_path))
null_vf_cnt[vd_path] = 0;
prev_hdr_support = vinfo->hdr_info.hdr_support;
pr_csc(2, "vd%d: hdr_support changed\n",
vd_path + 1);
pr_csc(4, "vd%d: sink cap changed when idle\n",
vd_path + 1);
}
/* handle change between output mode*/
if (prev_color_fmt != vinfo->viu_color_fmt) {
if ((vd_path == VD1_PATH) ||
((vd_path == VD2_PATH) &&
is_video_layer_on(VD2_PATH)))
if (is_video_layer_on(vd_path))
null_vf_cnt[vd_path] = 0;
prev_color_fmt = vinfo->viu_color_fmt;
pr_csc(2, "vd%d: output color format changed\n",
vd_path + 1);
}
/* handle eye protect mode */
if ((cur_eye_protect_mode != wb_val[0])
&& (vd_path == VD1_PATH)) {
null_vf_cnt[vd_path] = 0;
pr_csc(2, "vd%d: eye_protect_mode changed\n",
vd_path + 1);
pr_csc(4, "vd%d: output color format changed\n",
vd_path + 1);
}
if (!is_video_layer_on(vd_path)
&& (video_process_status[vd_path] == HDR_MODULE_ON))
null_vf_cnt[vd_path] = toggle_frame = 1;
else if (csc_en & 0x10)
toggle_frame = null_vf_max;
else
toggle_frame = 0;
/* handle eye protect mode */
if ((cur_eye_protect_mode != wb_val[0]) &&
(vd_path == VD1_PATH) &&
is_video_layer_on(vd_path)) {
null_vf_cnt[vd_path] = 0;
pr_csc(4, "vd%d: eye_protect_mode changed\n",
vd_path + 1);
}
/* handle sdr_mode change */
if ((vinfo->hdr_info.hdr_support & 0xc) &&
((cpu_after_eq(MESON_CPU_MAJOR_ID_GXL)) &&
(vinfo->viu_color_fmt != COLOR_FMT_RGB444))) {
if (is_video_layer_on(vd_path) &&
(vinfo->hdr_info.hdr_support & 0x4) &&
((cpu_after_eq(MESON_CPU_MAJOR_ID_GXL)) &&
(vinfo->viu_color_fmt != COLOR_FMT_RGB444))) {
if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) {
if (hdr_mode != cur_hdr_mode) {
null_vf_cnt[vd_path] = toggle_frame;
cur_hdr_mode = hdr_mode;
pr_csc(2, "vd%d: hdr_mode changed\n",
vd_path + 1);
}
if (sdr_mode != cur_sdr_mode) {
null_vf_cnt[vd_path] = toggle_frame;
null_vf_cnt[vd_path] = 0;
cur_sdr_mode = sdr_mode;
pr_csc(2, "vd%d: sdr_mode changed\n",
vd_path + 1);
pr_csc(4, "vd%d: sdr_mode changed\n",
vd_path + 1);
}
} else if (((sdr_process_mode[vd_path] !=
PROC_SDR_TO_HDR)
&& (sdr_mode > 0))
|| ((sdr_process_mode[vd_path] > PROC_BYPASS) &&
(sdr_process_mode[vd_path] != PROC_OFF) &&
(sdr_mode == 0)))
null_vf_cnt[vd_path] = toggle_frame;
} else {
if (((sdr_process_mode[vd_path] !=
PROC_SDR_TO_HDR) &&
(sdr_mode > 0)) ||
((sdr_process_mode[vd_path]
> PROC_BYPASS) &&
(sdr_process_mode[vd_path]
!= PROC_OFF) &&
(sdr_mode == 0))) {
null_vf_cnt[vd_path] = 0;
pr_csc(4, "vd%d: sdr_mode changed\n",
vd_path + 1);
}
}
}
if (!is_dolby_vision_enable() &&
get_hdr_policy() != cur_hdr_policy) {
null_vf_cnt[vd_path] = 1;
toggle_frame = 1;
} else if (!is_video_layer_on(vd_path) &&
(video_process_status[vd_path]
== HDR_MODULE_ON)) {
null_vf_cnt[vd_path] = 1;
toggle_frame = 1;
} else if (csc_en & 0x10) {
toggle_frame = null_vf_max;
} else {
toggle_frame = 0;
}
if (null_vf_cnt[vd_path] == toggle_frame) {
pr_csc(8,
"vd%d: %d %d Fake SDR frame%s, dolby on=%d, dolby policy =%d\n",
vd_path + 1,
null_vf_cnt[vd_path],
toggle_frame,
is_video_layer_on(vd_path) ?
" " : ", video off",
is_dolby_vision_on(),
get_dolby_vision_policy());
video_process_status[vd_path] = HDR_MODULE_OFF;
if ((get_dolby_vision_policy() != 0) ||
(!is_dolby_vision_on())) {
/*send a faked vframe to switch matrix*/
/*from 2020 to 601 when video disabled */
if (null_vf_cnt[vd_path] == 0) {
/* video on */
video_process_flags[vd_path] |=
PROC_FLAG_FORCE_PROCESS;
return 0;
}
/* video off */
if (is_dolby_vision_enable()) {
/* dolby enable */
pr_csc(8,
"vd%d: %d %d Fake SDR frame%s, dolby on=%d, dolby policy =%d\n",
vd_path + 1,
null_vf_cnt[vd_path],
toggle_frame,
is_video_layer_on(vd_path) ?
" " : ", video off",
is_dolby_vision_on(),
get_dolby_vision_policy());
if (vd_path == VD2_PATH ||
(vd_path == VD1_PATH &&
(get_dolby_vision_policy() !=
DOLBY_VISION_FOLLOW_SINK ||
get_source_type(VD1_PATH) ==
HDRTYPE_HDR10PLUS ||
get_source_type(VD1_PATH)
== HDRTYPE_HLG))) {
/* and VD1 adaptive or VD2 */
/* or always hdr hdr+/hlg bypass */
/* faked vframe to switch matrix */
/* 2020 to 601 when video disabled */
/* and bypass hdr module for dv core*/
send_fake_frame = true;
video_process_status[vd_path] =
HDR_MODULE_OFF;
}
} else {
/* dolby disable */
pr_csc(8,
"vd%d: %d %d Fake SDR frame%s, policy =%d\n",
vd_path + 1,
null_vf_cnt[vd_path],
toggle_frame,
is_video_layer_on(vd_path) ?
" " : ", video off",
get_hdr_policy());
send_fake_frame = true;
if (get_hdr_policy() == 1) {
/* adaptive hdr */
/* faked vframe to switch matrix */
/* turn off hdr module */
video_process_status[vd_path] =
HDR_MODULE_OFF;
} else {
/* always hdr */
/* faked vframe to switch matrix */
/* hdr module to handle osd */
video_process_status[vd_path] =
HDR_MODULE_ON;
}
}
if (send_fake_frame) {
fake_vframe.source_type =
VFRAME_SOURCE_TYPE_OTHERS;
fake_vframe.signal_type = 0;
@@ -7225,23 +7533,25 @@ int amvecm_matrix_process(
fake_vframe.prop.
master_display_colour.present_flag
= 0x80000000;
if (null_vf_cnt[vd_path] == toggle_frame)
vpp_matrix_update(
&fake_vframe, vinfo,
CSC_FLAG_TOGGLE_FRAME, vd_path);
else if (null_vf_cnt[vd_path] == 0)
vpp_matrix_update(
&fake_vframe, vinfo,
CSC_FLAG_CHECK_OUTPUT, vd_path);
vpp_matrix_update(
&fake_vframe, vinfo,
CSC_FLAG_TOGGLE_FRAME, vd_path);
last_vf[vd_path] = NULL;
null_vf_cnt[vd_path] = null_vf_max + 1;
fg_vf_sw_dbg = 4;
dbg_vf = NULL;
video_process_status[vd_path] =
HDR_MODULE_BYPASS;
pr_csc(4,
"video_process_status[%s] = HDR_MODULE_BYPASS\n",
vd_path == VD1_PATH ? "VD1" : "VD2");
if ((vd_path == VD2_PATH) &&
(is_video_layer_on(VD1_PATH) ||
video_layer_wait_on[VD1_PATH]))
video_process_flags[VD1_PATH] |=
PROC_FLAG_FORCE_PROCESS;
}
last_vf[vd_path] = NULL;
null_vf_cnt[vd_path] = null_vf_max;
fg_vf_sw_dbg = 4;
dbg_vf = NULL;
video_process_status[vd_path] = HDR_MODULE_BYPASS;
}
if (null_vf_cnt[vd_path] <= null_vf_max)
null_vf_cnt[vd_path]++;
}
return 0;
}

View File

@@ -101,6 +101,12 @@ enum output_format_e {
#define HDR_SUPPORT (1 << 2)
#define HLG_SUPPORT (1 << 3)
bool is_vinfo_available(const struct vinfo_s *vinfo);
int is_sink_cap_changed(const struct vinfo_s *vinfo,
int *p_current_hdr_cap,
int *p_current_sink_available);
int is_video_turn_on(bool *vd_on, enum vd_path_e vd_path);
#define SIG_CS_CHG 0x01
#define SIG_SRC_CHG 0x02
#define SIG_PRI_INFO 0x04
@@ -132,6 +138,9 @@ extern int video_rgb_ogo_xvy_mtx;
extern int tx_op_color_primary;
extern uint cur_csc_type[VD_PATH_MAX];
int get_hdr_policy(void);
enum output_format_e get_force_output(void);
/* 0: hdr->hdr, 1:hdr->sdr, 2:hdr->hlg */
extern uint hdr_process_mode[VD_PATH_MAX];
extern uint cur_hdr_process_mode[VD_PATH_MAX];
@@ -158,6 +167,10 @@ extern int amvecm_hdr_dbg(u32 sel);
extern u32 get_video_enabled(void);
extern u32 get_videopip_enabled(void);
void set_video_mute(bool on);
int get_video_mute(void);
extern void get_hdr_source_type(void);
extern void get_cur_vd_signal_type(enum vd_path_e vd_path);
extern enum color_primary_e get_color_primary(void);

View File

@@ -23,12 +23,6 @@
#include "set_hdr2_v0.h"
#include "hdr/am_hdr10_plus.h"
/* 0: follow sink, 1: follow source */
static uint hdr_policy = 1;
module_param(hdr_policy, uint, 0664);
MODULE_PARM_DESC(hdr_policy, "\n hdr policy\n");
static uint cur_hdr_policy;
static enum output_format_e target_format[VD_PATH_MAX];
static enum hdr_type_e cur_source_format[VD_PATH_MAX];
static enum output_format_e output_format;
@@ -125,8 +119,10 @@ int hdr_policy_process(
int change_flag = 0;
enum vd_path_e oth_path =
(vd_path == VD1_PATH) ? VD2_PATH : VD1_PATH;
int cur_hdr_policy;
int dv_policy = 0;
int dv_mode = 0;
int dv_format = 0;
bool hdr10_plus_support =
(vinfo->hdr_info.hdr10plus_info.ieeeoui
== HDR_PLUS_IEEE_OUI) &&
@@ -135,37 +131,53 @@ int hdr_policy_process(
tx_hdr10_plus_support = hdr10_plus_support;
cur_hdr_policy = hdr_policy;
cur_hdr_policy = get_hdr_policy();
if (is_dolby_vision_enable()) {
/* sync hdr_policy with dolby_vision_policy */
/* get current dolby_vision_mode */
dv_policy = get_dolby_vision_policy();
dv_mode = get_dolby_vision_mode();
if ((dv_policy != DOLBY_VISION_FORCE_OUTPUT_MODE)
|| (dv_mode != DOLBY_VISION_OUTPUT_MODE_BYPASS)) {
/* use dv policy when not force bypass */
cur_hdr_policy = dv_policy;
}
dv_format = get_dolby_vision_src_format();
}
if ((get_hdr_module_status(vd_path) != HDR_MODULE_ON)
&& is_dolby_vision_enable()) {
if (get_hdr_module_status(vd_path) != HDR_MODULE_ON) {
/* hdr module off or bypass */
sdr_process_mode[vd_path] = PROC_BYPASS;
hdr_process_mode[vd_path] = PROC_BYPASS;
hlg_process_mode[vd_path] = PROC_BYPASS;
hdr10_plus_process_mode[vd_path] = PROC_BYPASS;
target_format[vd_path] = BT709;
} else if (cur_hdr_policy == 0) {
if ((vd_path == VD1_PATH)
&& (source_format[vd_path] == HDRTYPE_HLG)
&& (vinfo->hdr_info.hdr_support & HLG_SUPPORT)) {
if (vd_path == VD1_PATH &&
is_dolby_vision_enable() &&
!is_dolby_vision_on() &&
(source_format[vd_path]
== HDRTYPE_DOVI ||
source_format[vd_path]
== HDRTYPE_HDR10 ||
source_format[vd_path]
== HDRTYPE_SDR)) {
/* vd1 follow sink: dv handle sdr/hdr/dovi */
sdr_process_mode[vd_path] = PROC_BYPASS;
hdr_process_mode[vd_path] = PROC_BYPASS;
hlg_process_mode[vd_path] = PROC_BYPASS;
hdr10_plus_process_mode[vd_path] = PROC_BYPASS;
target_format[vd_path] = BT709;
set_hdr_module_status(vd_path, HDR_MODULE_OFF);
dolby_vision_set_toggle_flag(1);
} else if ((vd_path == VD1_PATH) &&
(source_format[vd_path]
== HDRTYPE_HLG) &&
(vinfo->hdr_info.hdr_support
& HLG_SUPPORT)) {
/* vd1 bypass hlg */
hlg_process_mode[vd_path] = PROC_BYPASS;
target_format[vd_path] = BT2020_HLG;
} else if ((vd_path == VD1_PATH)
&& (!is_video_layer_on(VD2_PATH))
&& (source_format[vd_path] == HDRTYPE_HDR10PLUS)
&& hdr10_plus_support) {
} else if ((vd_path == VD1_PATH) &&
(!is_video_layer_on(VD2_PATH)) &&
(source_format[vd_path]
== HDRTYPE_HDR10PLUS) &&
hdr10_plus_support) {
/* vd1 bypass hdr+ when vd2 off */
hdr10_plus_process_mode[vd_path] = PROC_BYPASS;
target_format[vd_path] = BT2020_PQ_DYNAMIC;
@@ -176,8 +188,8 @@ int hdr_policy_process(
sdr_process_mode[vd_path] = PROC_MATCH;
hdr10_plus_process_mode[vd_path] = PROC_MATCH;
target_format[vd_path] = BT2100_IPT;
} else if ((vd_path == VD2_PATH)
&& is_video_layer_on(VD1_PATH)) {
} else if ((vd_path == VD2_PATH) &&
is_video_layer_on(VD1_PATH)) {
/* vd1 on and vd2 follow vd1 output */
if (target_format[VD1_PATH] == BT2020_HLG) {
/* vd2 *->hlg when vd1 output hlg */
@@ -188,7 +200,8 @@ int hdr_policy_process(
PROC_HDRP_TO_HLG;
target_format[vd_path] = BT2020_HLG;
} else if ((target_format[VD1_PATH] == BT2020_PQ) ||
(target_format[VD1_PATH] == BT2020_PQ_DYNAMIC)) {
(target_format[VD1_PATH]
== BT2020_PQ_DYNAMIC)) {
/* vd2 *->hdr when vd1 output hdr/hdr+ */
sdr_process_mode[vd_path] = PROC_SDR_TO_HDR;
hdr_process_mode[vd_path] = PROC_BYPASS;
@@ -209,10 +222,10 @@ int hdr_policy_process(
else
target_format[vd_path] = BT709;
}
} else if ((vinfo->hdr_info.hdr_support & HDR_SUPPORT)
&& ((source_format[vd_path] != HDRTYPE_HLG)
|| ((source_format[vd_path] == HDRTYPE_HLG)
&& (hdr_flag & 0x10)))) {
} else if ((vinfo->hdr_info.hdr_support & HDR_SUPPORT) &&
((source_format[vd_path] != HDRTYPE_HLG) ||
((source_format[vd_path] == HDRTYPE_HLG) &&
(hdr_flag & 0x10)))) {
/* *->hdr */
sdr_process_mode[vd_path] = PROC_SDR_TO_HDR;
hdr_process_mode[vd_path] = PROC_BYPASS;
@@ -227,10 +240,11 @@ int hdr_policy_process(
hlg_process_mode[vd_path] = PROC_HLG_TO_SDR;
hdr10_plus_process_mode[vd_path] =
PROC_HDRP_TO_SDR;
#if 0
#ifdef AMCSC_DEBUG_TEST
if ((vinfo->hdr_info.colorimetry_support
& SINK_SUPPORTS_BT2020) &&
(source_format[vd_path] == HDRTYPE_HLG) &&
((source_format[vd_path] == HDRTYPE_HLG) ||
(source_format[vd_path] == HDRTYPE_HDR10)) &&
!is_video_layer_on(oth_path))
target_format[vd_path] = BT2020;
else
@@ -240,14 +254,28 @@ int hdr_policy_process(
#endif
}
} else if (cur_hdr_policy == 1) {
if ((vd_path == VD2_PATH) && is_dolby_vision_on()) {
if (vd_path == VD1_PATH &&
is_dolby_vision_enable() &&
!is_dolby_vision_on() &&
source_format[vd_path]
== HDRTYPE_DOVI) {
/* vd1 follow source: dv handle dovi */
sdr_process_mode[vd_path] = PROC_BYPASS;
hdr_process_mode[vd_path] = PROC_BYPASS;
hlg_process_mode[vd_path] = PROC_BYPASS;
hdr10_plus_process_mode[vd_path] = PROC_BYPASS;
target_format[vd_path] = BT709;
set_hdr_module_status(vd_path, HDR_MODULE_OFF);
dolby_vision_set_toggle_flag(1);
} else if ((vd_path == VD2_PATH) && is_dolby_vision_on()) {
/* VD2 with VD1 in DV mode */
hdr_process_mode[vd_path] = PROC_MATCH;
hlg_process_mode[vd_path] = PROC_MATCH;
sdr_process_mode[vd_path] = PROC_MATCH; /* *->ipt */
target_format[vd_path] = BT2100_IPT;
} else if ((vd_path == VD1_PATH)
|| ((vd_path == VD2_PATH) && !is_video_layer_on(VD1_PATH))) {
} else if ((vd_path == VD1_PATH) ||
((vd_path == VD2_PATH) &&
!is_video_layer_on(VD1_PATH))) {
/* VD1(with/without VD2) */
/* or VD2(without VD1) <= should switch to VD1 */
switch (source_format[vd_path]) {
@@ -314,7 +342,7 @@ int hdr_policy_process(
/* hlg->sdr */
hlg_process_mode[vd_path] =
PROC_HLG_TO_SDR;
#if 0
#ifdef AMCSC_DEBUG_TEST
if ((vinfo->hdr_info.colorimetry_support
& SINK_SUPPORTS_BT2020) &&
!is_video_layer_on(oth_path))
@@ -347,8 +375,17 @@ int hdr_policy_process(
/* hdr ->sdr */
hdr_process_mode[vd_path] =
PROC_HDR_TO_SDR;
#ifdef AMCSC_DEBUG_TEST
if ((vinfo->hdr_info.colorimetry_support
& SINK_SUPPORTS_BT2020) &&
!is_video_layer_on(oth_path))
target_format[vd_path] =
BT2020;
else
#else
target_format[vd_path] =
BT709;
#endif
}
break;
case HDRTYPE_HDR10PLUS:
@@ -376,7 +413,17 @@ int hdr_policy_process(
/* hdr+ *->sdr */
hdr10_plus_process_mode[vd_path] =
PROC_HDRP_TO_SDR;
target_format[vd_path] = BT709;
#ifdef AMCSC_DEBUG_TEST
if ((vinfo->hdr_info.colorimetry_support
& SINK_SUPPORTS_BT2020) &&
!is_video_layer_on(oth_path))
target_format[vd_path] =
BT2020;
else
#else
target_format[vd_path] =
BT709;
#endif
}
break;
default:
@@ -501,12 +548,182 @@ int hdr_policy_process(
}
}
}
} else if (cur_hdr_policy == 2) {
/* *->ipt */
hdr_process_mode[vd_path] = PROC_MATCH;
hlg_process_mode[vd_path] = PROC_MATCH;
sdr_process_mode[vd_path] = PROC_MATCH;
target_format[vd_path] = BT2100_IPT;
} else if (cur_hdr_policy == 2 &&
!is_dolby_vision_enable()) {
/* dv off, and policy == debug */
/* *->force_output */
if ((vd_path == VD1_PATH) ||
((vd_path == VD2_PATH) &&
!is_video_layer_on(VD1_PATH))) {
/* VD1 or VD2 without VD1 */
target_format[vd_path] = get_force_output();
switch (target_format[vd_path]) {
case BT709:
sdr_process_mode[vd_path] =
PROC_BYPASS;
hlg_process_mode[vd_path] =
PROC_HLG_TO_SDR;
hdr_process_mode[vd_path] =
PROC_HDR_TO_SDR;
hdr10_plus_process_mode[vd_path]
= PROC_HDRP_TO_SDR;
break;
case BT2020:
break;
case BT2020_PQ:
sdr_process_mode[vd_path] =
PROC_SDR_TO_HDR;
hlg_process_mode[vd_path] =
PROC_HLG_TO_HDR;
hdr_process_mode[vd_path] =
PROC_BYPASS;
hdr10_plus_process_mode[vd_path]
= PROC_HDRP_TO_HDR;
break;
case BT2020_PQ_DYNAMIC:
sdr_process_mode[vd_path] =
PROC_SDR_TO_HDR;
hlg_process_mode[vd_path] =
PROC_HLG_TO_HDR;
hdr_process_mode[vd_path] =
PROC_BYPASS;
hdr10_plus_process_mode[vd_path] =
PROC_BYPASS;
break;
case BT2020_HLG:
sdr_process_mode[vd_path] =
PROC_SDR_TO_HLG;
hlg_process_mode[vd_path] =
PROC_BYPASS;
hdr_process_mode[vd_path] =
PROC_HDR_TO_HLG;
hdr10_plus_process_mode[vd_path]
= PROC_HDRP_TO_HLG;
break;
case BT2100_IPT:
/* hdr module not handle dv output */
default:
break;
}
} else {
/* VD2 with VD1 on */
if (is_dolby_vision_on()) {
/* VD1 is dolby vision */
hdr_process_mode[vd_path] = PROC_MATCH;
hlg_process_mode[vd_path] = PROC_MATCH;
sdr_process_mode[vd_path] = PROC_MATCH;
target_format[vd_path] = BT2100_IPT;
} else {
oth_path = VD1_PATH;
switch (source_format[vd_path]) {
case HDRTYPE_SDR:
/* VD2 source SDR */
if ((target_format[oth_path] ==
BT2020_PQ) ||
(target_format[oth_path] ==
BT2020_PQ_DYNAMIC)) {
/* other layer output HDR */
/* sdr *->hdr */
sdr_process_mode[vd_path] =
PROC_SDR_TO_HDR;
target_format[vd_path] =
BT2020_PQ;
} else if (target_format[oth_path] ==
BT2020_HLG) {
/* other layer on and not sdr */
/* sdr *->hlg */
sdr_process_mode[vd_path] =
PROC_SDR_TO_HLG;
target_format[vd_path] =
BT2020_HLG;
} else {
/* sdr->sdr */
sdr_process_mode[vd_path] =
PROC_BYPASS;
target_format[vd_path] = BT709;
}
break;
case HDRTYPE_HLG:
/* VD2 source HLG */
if (target_format[oth_path]
== BT2020_HLG) {
/* hlg->hlg */
hlg_process_mode[vd_path] =
PROC_BYPASS;
target_format[vd_path] =
BT2020_HLG;
} else if ((target_format[oth_path] ==
BT2020_PQ) ||
(target_format[oth_path] ==
BT2020_PQ_DYNAMIC)) {
/* hlg->hdr */
hlg_process_mode[vd_path] =
PROC_HLG_TO_HDR;
target_format[vd_path] =
BT2020_PQ;
} else if (target_format[oth_path] ==
BT709) {
/* hlg->sdr */
hlg_process_mode[vd_path] =
PROC_HLG_TO_SDR;
target_format[vd_path] = BT709;
}
break;
case HDRTYPE_HDR10:
/* VD2 source HDR10 */
if ((target_format[oth_path] ==
BT2020_PQ) ||
(target_format[oth_path] ==
BT2020_PQ_DYNAMIC)) {
/* hdr->hdr */
hdr_process_mode[vd_path] =
PROC_BYPASS;
target_format[vd_path] =
BT2020_PQ;
} else if (target_format[oth_path]
== BT2020_HLG) {
/* hdr->hlg */
hdr_process_mode[vd_path] =
PROC_HDR_TO_HLG;
target_format[vd_path] =
BT2020_HLG;
} else {
/* hdr->sdr */
hdr_process_mode[vd_path] =
PROC_HDR_TO_SDR;
target_format[vd_path] = BT709;
}
break;
case HDRTYPE_HDR10PLUS:
/* VD2 source HDR10+ */
if ((target_format[oth_path] ==
BT2020_PQ) ||
(target_format[oth_path] ==
BT2020_PQ_DYNAMIC)) {
/* hdr->hdr */
hdr10_plus_process_mode[vd_path]
= PROC_HDRP_TO_HDR;
target_format[vd_path] =
BT2020_PQ;
} else if (target_format[oth_path]
== BT2020_HLG) {
/* hdr->hlg */
hdr_process_mode[vd_path] =
PROC_HDR_TO_HLG;
target_format[vd_path] =
BT2020_HLG;
} else {
/* hdr->sdr */
hdr10_plus_process_mode[vd_path]
= PROC_HDRP_TO_SDR;
target_format[vd_path] = BT709;
}
break;
default:
break;
}
}
}
}
/* update change flags */
@@ -515,7 +732,7 @@ int hdr_policy_process(
pr_csc(4, "am_vecm: vd%d: (%s) %s->%s.\n",
vd_path + 1,
policy_str[dv_policy],
input_str[get_dolby_vision_src_format()],
input_str[dv_format],
dv_output_str[dv_mode]);
} else {
if (cur_hdr10_plus_process_mode[vd_path]
@@ -545,19 +762,19 @@ int hdr_policy_process(
}
cur_source_format[vd_path] = source_format[vd_path];
if (is_dolby_vision_on()
&& (vd_path == VD2_PATH)
&& is_video_layer_on(VD2_PATH)
&& (target_format[vd_path] != BT2100_IPT)) {
if (is_dolby_vision_on() &&
(vd_path == VD2_PATH) &&
is_video_layer_on(VD2_PATH) &&
(target_format[vd_path] != BT2100_IPT)) {
pr_csc(4, "am_vecm: vd%d output mode not match to dolby %s.\n",
vd_path + 1,
output_str[target_format[vd_path]]);
change_flag |= SIG_OUTPUT_MODE_CHG;
} else if (!is_dolby_vision_on()
&& is_video_layer_on(VD1_PATH)
&& is_video_layer_on(VD2_PATH)
&& (target_format[vd_path]
!= target_format[oth_path])) {
} else if (!is_dolby_vision_on() &&
is_video_layer_on(VD1_PATH) &&
is_video_layer_on(VD2_PATH) &&
(target_format[vd_path]
!= target_format[oth_path])) {
pr_csc(4, "am_vecm: vd%d output mode not match %s %s.\n",
vd_path + 1,
output_str[target_format[vd_path]],
@@ -767,7 +984,22 @@ void video_post_process(
struct vinfo_s *vinfo,
enum vd_path_e vd_path)
{
switch (cur_source_format[vd_path]) {
enum hdr_type_e src_format = cur_source_format[vd_path];
if (get_hdr_module_status(vd_path) == HDR_MODULE_OFF) {
if (vd_path == VD1_PATH)
hdr_proc(VD1_HDR, HDR_BYPASS, vinfo);
else
hdr_proc(VD2_HDR, HDR_BYPASS, vinfo);
if (((vd_path == VD1_PATH) &&
!is_video_layer_on(VD2_PATH)) ||
((vd_path == VD2_PATH) &&
!is_video_layer_on(VD1_PATH)))
hdr_proc(OSD1_HDR, HDR_BYPASS, vinfo);
src_format = HDRTYPE_NONE;
}
switch (src_format) {
case HDRTYPE_SDR:
if (vd_path == VD2_PATH && is_dolby_vision_on()) {
hdr_proc(VD2_HDR, SDR_IPT, vinfo);

View File

@@ -2015,7 +2015,7 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel,
hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i];
if (i < HDR2_CGAIN_LUT_SIZE)
hdr_lut_param.cgain_lut[i] =
cgain_lut_bypass[i] - 1;
cgain_lut0[i] - 1;
}
hdr_lut_param.bitdepth = bit_depth;
hdr_lut_param.lut_on = LUT_ON;
@@ -2068,11 +2068,11 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel,
hdr_lut_param.eotf_lut[i] = eo_y_lut_sdr[i];
if (i < HDR2_CGAIN_LUT_SIZE)
hdr_lut_param.cgain_lut[i] =
cgain_lut_bypass[i] - 1;
cgain_lut0[i] - 1;
}
hdr_lut_param.lut_on = LUT_ON;
hdr_lut_param.bitdepth = bit_depth;
hdr_lut_param.cgain_en = LUT_OFF;
hdr_lut_param.cgain_en = LUT_ON;
} else if (hdr_process_select == HLG_SDR) {
for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) {
hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i];
@@ -2183,7 +2183,7 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel,
hdr_lut_param.eotf_lut[i] = eo_y_lut_pq[i];
if (i < HDR2_CGAIN_LUT_SIZE)
hdr_lut_param.cgain_lut[i] =
cgain_lut1[i] - 1;
cgain_lut0[i] - 1;
}
//pr_info("\t oo_gain = %lld of 512\n",
// hdr_lut_param.ogain_lut[0]);

View File

@@ -6122,13 +6122,6 @@ struct vframe_s *dolby_vision_toggle_frame(struct vframe_s *vf)
height_el - 1;
}
if (!get_video_enabled()) {
/* when video layer off */
/* not need to update setting */
dolby_vision_set_toggle_flag(0);
return NULL;
};
if (ret == 0) {
/* setting generated for this frame */
/* or DOVI in bypass mode */
@@ -6181,6 +6174,74 @@ static int dolby_vision_drop_frame(void)
return 0;
}
#endif
static bool video_mute_on;
MODULE_PARM_DESC(video_mute_on, "\n video_mute_on\n");
module_param(video_mute_on, bool, 0664);
/* 0: off, 1: vpp mute 2:dv mute */
static int video_mute_status;
void set_video_mute(bool on)
{
video_mute_on = on;
}
EXPORT_SYMBOL(set_video_mute);
int get_video_mute(void)
{
return video_mute_status;
}
EXPORT_SYMBOL(get_video_mute);
static void check_video_mute(void)
{
if (video_mute_on) {
if (is_dolby_vision_on()) {
/* core 3 black */
if (video_mute_status != VIDEO_MUTE_ON_DV) {
dolby_vision_set_toggle_flag(1);
pr_info("DOLBY: check_video_mute: VIDEO_MUTE_ON_DV\n");
}
video_mute_status = VIDEO_MUTE_ON_DV;
} else {
if (video_mute_status != VIDEO_MUTE_ON_VPP) {
/* vpp black */
VSYNC_WR_MPEG_REG(VPP_CLIP_MISC0,
(0x0 << 20) |
(0x200 << 10) |
0x200);
VSYNC_WR_MPEG_REG(VPP_CLIP_MISC1,
(0x0 << 20) |
(0x200 << 10) |
0x200);
pr_info("DOLBY: check_video_mute: VIDEO_MUTE_ON_VPP\n");
}
video_mute_status = VIDEO_MUTE_ON_VPP;
}
} else {
if (is_dolby_vision_on()) {
if (video_mute_status != VIDEO_MUTE_OFF) {
dolby_vision_set_toggle_flag(2);
pr_info("DOLBY: check_video_mute: VIDEO_MUTE_OFF dv on\n");
}
video_mute_status = VIDEO_MUTE_OFF;
} else {
if (video_mute_status != VIDEO_MUTE_OFF) {
VSYNC_WR_MPEG_REG(VPP_CLIP_MISC0,
(0x3ff << 20) |
(0x3ff << 10) |
0x3ff);
VSYNC_WR_MPEG_REG(VPP_CLIP_MISC1,
(0x0 << 20) |
(0x0 << 10) | 0x0);
pr_info("DOLBY: check_video_mute: VIDEO_MUTE_OFF dv off\n");
}
video_mute_status = VIDEO_MUTE_OFF;
}
}
}
/* patch for 4k2k bandwidth issue, skiw mali and vpu mif */
static void dmc_adjust_for_mali_vpu(unsigned int width,
unsigned int height, bool force_adjust)
@@ -7491,8 +7552,9 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
} else
vsync_toggle_frame(cur_dispbuf,
__LINE__);
if (is_dolby_vision_enable()
&& is_dolby_vision_video_on()) {
if (is_dolby_vision_enable() &&
is_dolby_vision_on() &&
get_video_enabled()) {
pause_vf = cur_dispbuf;
video_pause_global = 1;
} else {
@@ -7653,6 +7715,8 @@ SET_FILTER:
if (is_dolby_vision_enable()) {
u32 frame_size = 0, h_size, v_size;
u8 pps_state = 0; /* pps no change */
static struct vframe_s *cur_dv_vf;
static u32 cur_frame_size;
/* force toggle when keeping frame after playing */
if ((cur_dispbuf == &vf_local)
@@ -7663,22 +7727,8 @@ SET_FILTER:
dolby_vision_parse_metadata(
toggle_vf, 2, false, false);
dolby_vision_set_toggle_flag(1);
//pr_info("DOLBY: keep frame %p", toggle_vf);
/* pr_info("DOLBY: keep frame %p", toggle_vf); */
}
/* pause mode was moved to video display property */
#if 0
/* force toggle in pause mode */
if (cur_dispbuf
&& (cur_dispbuf != &vf_local)
&& !toggle_vf
&& is_dolby_vision_on()
&& !for_dolby_vision_certification()) {
toggle_vf = cur_dispbuf;
dolby_vision_parse_metadata(
cur_dispbuf, 0, false, false);
dolby_vision_set_toggle_flag(1);
}
#endif
if (cur_frame_par) {
if (frame_par_ready_to_set || frame_par_force_to_set) {
struct vppfilter_mode_s *vpp_filter =
@@ -7720,8 +7770,28 @@ SET_FILTER:
toggle_vf->compHeight : toggle_vf->height;
frame_size = (h_size << 16) | v_size;
}
dolby_vision_process((cur_dispbuf != &vf_local)
? cur_dispbuf : toggle_vf, frame_size, pps_state);
if (cur_dispbuf == &vf_local) {
if (get_video_enabled())
toggle_vf = cur_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);
if (cur_frame_size != frame_size) {
cur_frame_size = frame_size;
if (!toggle_vf && get_video_enabled())
toggle_vf = cur_dispbuf;
dolby_vision_set_toggle_flag(1);
}
cur_dv_vf = toggle_vf;
dolby_vision_process(
cur_dispbuf, toggle_vf,
frame_size, pps_state);
dolby_vision_update_setting();
}
#endif
@@ -8309,6 +8379,9 @@ SET_FILTER:
#if defined(PTS_LOGGING) || defined(PTS_TRACE_DEBUG)
pts_trace++;
#endif
check_video_mute();
vpp_misc_save = READ_VCBUS_REG(VPP_MISC + cur_dev->vpp_off);
vpp_misc_set = vpp_misc_save;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
@@ -13339,10 +13412,11 @@ int vout_notify_callback(struct notifier_block *block, unsigned long cmd,
spin_unlock_irqrestore(&lock, flags);
new_vmode = vinfo->mode;
#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
pr_info("vout_notify_callback: VOUT_EVENT_MODE_CHANGE");
/* make sure dolby policy process runs atleast once */
pr_info("DOLBY: vout_notify_callback: VOUT_EVENT_MODE_CHANGE\n");
/* force send hdmi pkt in dv code */
/* to workaround pkt cleaned during hotplug */
if (is_dolby_vision_enable())
dolby_vision_set_toggle_flag(1);
dolby_vision_set_toggle_flag(2);
#endif
break;
case VOUT_EVENT_OSD_PREBLEND_ENABLE:

View File

@@ -22,6 +22,7 @@
#define V2_4
#include <linux/types.h>
#include <linux/amlogic/media/vout/vinfo.h>
#define DOLBY_VISION_OUTPUT_MODE_IPT 0
#define DOLBY_VISION_OUTPUT_MODE_IPT_TUNNEL 1
@@ -47,6 +48,11 @@
/* else bypass Dolby Vision */
#define DOLBY_VISION_FORCE_OUTPUT_MODE 2
#define MUTE_TYPE_NONE 0
#define MUTE_TYPE_YUV 1
#define MUTE_TYPE_RGB 2
#define MUTE_TYPE_IPT 3
extern void enable_dolby_vision(int enable);
extern bool is_dolby_vision_enable(void);
extern bool is_dolby_vision_on(void);
@@ -58,8 +64,9 @@ 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);
extern int dolby_vision_process(struct vframe_s *vf, u32 display_size,
u8 pps_state);
int dolby_vision_process(
struct vframe_s *rpt_vf, 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);
@@ -104,7 +111,9 @@ extern bool is_dovi_frame(struct vframe_s *vf);
extern void update_graphic_width_height(unsigned int width,
unsigned int height);
extern int get_dolby_vision_policy(void);
void set_dolby_vision_policy(int policy);
extern int get_dolby_vision_src_format(void);
extern bool is_dolby_vision_el_disable(void);
extern bool is_dovi_dual_layer_frame(struct vframe_s *vf);
void dolby_vision_set_provider(char *prov_name);
#endif

View File

@@ -238,6 +238,13 @@ static inline int amvideo_notifier_call_chain(unsigned long val, void *v)
}
#endif
/* 0: off, 1: vpp mute 2:dv mute */
#define VIDEO_MUTE_OFF 0
#define VIDEO_MUTE_ON_VPP 1
#define VIDEO_MUTE_ON_DV 2
void set_video_mute(bool on);
int get_video_mute(void);
int query_video_status(int type, int *value);
u32 set_blackout_policy(int policy);
u32 get_blackout_policy(void);