Add functionality to change MaxCLL (peak nits) and MaxFALL (avg nits) + HDR with HDMI limited bugfix (#740)
This commit is contained in:
11
MiSTer.ini
11
MiSTer.ini
@@ -137,6 +137,17 @@ video_saturation=100
|
||||
video_hue=0
|
||||
video_gain_offset=1,0,1,0,1,0
|
||||
|
||||
; These controls have been provided so you can tweak the HDR metadata values regarding
|
||||
; peak brightness and average brightness. The defaults are 1000/250 for peak and average
|
||||
; respectively.
|
||||
; Some displays will completely ignore the values in the HDR packet, some will make use of them.
|
||||
; The recommendation is to set hdr_max_nits to your display's peak luminance, while
|
||||
; setting hdr_avg_nits to at least hdr_max_nits/4.
|
||||
; Please note that setting a peak brightness far above your display's capability may result
|
||||
; in clipping in bright parts of the image.
|
||||
hdr_max_nits=1000
|
||||
hdr_avg_nits=250
|
||||
|
||||
; 1-10 (seconds) to display controller's button map upon first time key press
|
||||
; 0 - disable
|
||||
controller_info=6
|
||||
|
||||
4
cfg.cpp
4
cfg.cpp
@@ -115,6 +115,8 @@ static const ini_var_t ini_vars[] =
|
||||
{ "VIDEO_HUE", (void *)(&(cfg.video_hue)), UINT16, 0, 360},
|
||||
{ "VIDEO_GAIN_OFFSET", (void *)(&(cfg.video_gain_offset)), STRING, 0, sizeof(cfg.video_gain_offset)},
|
||||
{ "HDR", (void*)(&cfg.hdr), UINT8, 0, 2 },
|
||||
{ "HDR_MAX_NITS", (void*)(&(cfg.hdr_max_nits)), UINT16, 100, 10000},
|
||||
{ "HDR_AVG_NITS", (void*)(&(cfg.hdr_avg_nits)), UINT16, 100, 10000},
|
||||
{ "VGA_MODE", (void*)(&(cfg.vga_mode)), STRING, 0, sizeof(cfg.vga_mode) - 1 },
|
||||
{ "NTSC_MODE", (void *)(&(cfg.ntsc_mode)), UINT8, 0, 2},
|
||||
};
|
||||
@@ -450,6 +452,8 @@ void cfg_parse()
|
||||
cfg.wheel_force = 50;
|
||||
cfg.dvi_mode = 2;
|
||||
cfg.hdr = 0;
|
||||
cfg.hdr_max_nits = 1000;
|
||||
cfg.hdr_avg_nits = 250;
|
||||
cfg.video_brightness = 50;
|
||||
cfg.video_contrast = 50;
|
||||
cfg.video_saturation = 100;
|
||||
|
||||
2
cfg.h
2
cfg.h
@@ -86,6 +86,8 @@ typedef struct {
|
||||
uint16_t video_hue;
|
||||
char video_gain_offset[256];
|
||||
uint8_t hdr;
|
||||
uint16_t hdr_max_nits;
|
||||
uint16_t hdr_avg_nits;
|
||||
char vga_mode[16];
|
||||
char vga_mode_int;
|
||||
char ntsc_mode;
|
||||
|
||||
56
video.cpp
56
video.cpp
@@ -1174,25 +1174,10 @@ static void hdmi_config_set_csc()
|
||||
|
||||
if (!ypbpr)
|
||||
{
|
||||
|
||||
// select the base CSC
|
||||
int hdr = cfg.hdr;
|
||||
|
||||
mat4x4 coeffs = hdmi_full_coeffs;
|
||||
|
||||
if (hdr == 1)
|
||||
coeffs = hdmi_full_coeffs;
|
||||
else if (hdr == 2)
|
||||
coeffs = hdr_dcip3_coeffs;
|
||||
else
|
||||
{
|
||||
if (hdmi_limited_1)
|
||||
coeffs = hdmi_limited_1_coeffs;
|
||||
else if (hdmi_limited_2)
|
||||
coeffs = hdmi_limited_2_coeffs;
|
||||
else
|
||||
coeffs = hdmi_full_coeffs;
|
||||
}
|
||||
mat4x4 coeffs = hdr == 2 ? hdr_dcip3_coeffs : hdmi_full_coeffs;
|
||||
mat4x4 csc(coeffs);
|
||||
|
||||
// apply color controls
|
||||
@@ -1305,6 +1290,12 @@ static void hdmi_config_set_csc()
|
||||
// final compression
|
||||
csc.compress(2.0f);
|
||||
|
||||
// make sure to retain hdmi limited range
|
||||
if (hdmi_limited_1)
|
||||
csc = csc * mat4x4(hdmi_limited_1_coeffs);
|
||||
else if (hdmi_limited_2)
|
||||
csc = csc * mat4x4(hdmi_limited_2_coeffs);
|
||||
|
||||
// finally, apply a fixed multiplier to get it in
|
||||
// correct range for ADV7513 chip
|
||||
for (size_t i = 0; i < 12; i++)
|
||||
@@ -1532,6 +1523,13 @@ static void hdmi_config_init()
|
||||
|
||||
static void hdmi_config_set_hdr()
|
||||
{
|
||||
// Grab desired nits values
|
||||
uint8_t maxNitsLSB = cfg.hdr_max_nits & 0xFF;
|
||||
uint8_t maxNitsMSB = (cfg.hdr_max_nits >> 8) & 0xFF;
|
||||
|
||||
uint8_t avgNitsLSB = cfg.hdr_avg_nits & 0xFF;
|
||||
uint8_t avgNitsMSB = (cfg.hdr_avg_nits >> 8) & 0xFF;
|
||||
|
||||
// CTA-861-G: 6.9 Dynamic Range and Mastering InfoFrame
|
||||
// Uses BT2020 RGB primaries and white point chromacity
|
||||
// Max Lum: 1000cd/m2, Min Lum: 0cd/m2, MaxCLL: 1000cd/m2
|
||||
@@ -1543,7 +1541,7 @@ static void hdmi_config_set_hdr()
|
||||
0x87,
|
||||
0x01,
|
||||
0x1a,
|
||||
(cfg.hdr == 1 ? uint8_t(0x27) : uint8_t(0x28)),
|
||||
0x00, // Checksum, calculate later
|
||||
(cfg.hdr == 1 ? uint8_t(0x03) : uint8_t(0x02)),
|
||||
0x48,
|
||||
0x8a,
|
||||
@@ -1562,16 +1560,26 @@ static void hdmi_config_set_hdr()
|
||||
0x42,
|
||||
0x40,
|
||||
0x00,
|
||||
0xe8,
|
||||
0x03,
|
||||
0x32,
|
||||
maxNitsLSB,
|
||||
maxNitsMSB,
|
||||
0x01,
|
||||
0x00,
|
||||
0xe8,
|
||||
0x03,
|
||||
0xfa,
|
||||
0x00
|
||||
maxNitsLSB,
|
||||
maxNitsMSB,
|
||||
avgNitsLSB,
|
||||
avgNitsMSB
|
||||
};
|
||||
|
||||
// now we calculate the checksum for this packet (2s complement sum)
|
||||
uint16_t checksum = 0;
|
||||
for (uint i = 0; i < sizeof(hdr_data); i++)
|
||||
checksum += hdr_data[i];
|
||||
|
||||
checksum = checksum & 0xFF;
|
||||
checksum = ~checksum + 1;
|
||||
|
||||
hdr_data[3] = checksum;
|
||||
|
||||
if (cfg.hdr == 0)
|
||||
{
|
||||
hdmi_config_set_spare(1, false);
|
||||
|
||||
Reference in New Issue
Block a user