More changes for HDR with softhddrm

Monitor Type now required in Konfig
This commit is contained in:
jojo61 2021-03-17 14:24:52 +01:00
parent fde863adaf
commit a4fe3aa31c
5 changed files with 148 additions and 82 deletions

View File

@ -82,9 +82,9 @@ You have to adapt the Makefile. There are 3 possible Version that you can build:
softhddrm (DRM=1)
This is for INTEL cards and also uses Vaapi as decoder. It uses the DRM API for output and
runs without X Server. There are several commandline options to select the resolution and refresh rate.
I recommend to use libplacebo and set LIBPLCEBO_GL=1 in the Makefile.
I recommend to use libplacebo and set LIBPLACEBO_GL=1 in the Makefile.
Libplacebo API Version >= 107 is needed.
Libplacebo API Version >= 113 is needed.
Install:
@ -116,8 +116,10 @@ Beginners Guide for libplacebo:
Resolution setting. There is as small black line between the halfs to remaind you that Scaler Test
is activ.
Then you should set the Monitor Colorspace to "sRGB". This guarantees you the best colors on your screen.
Then you should set the Monitor Type to "sRGB". This guarantees you the best colors on your screen.
At the moment all calculations internaly are done in RGB space and all cards output also RGB.
If you use the softhddrm Version then you should set the Monitor Type to HD TV or UHD-HDR TV if you have
connected one of those.
If you are colorblind you could try to remedy this with the Colorblind Settings. Realy only needed
in rare cases.
@ -128,9 +130,17 @@ Beginners Guide for libplacebo:
The plugins searches the shaders in $ConfigDir/plugins/shaders for the shaders. One example shader is
provided in the shader subdirectory. Copy it to e.g.: /etc/vdr/plugins/shaders and then start
vdr -P 'softhdcuvid -S filmgrain.glsl ...'
I use KrigBilateral for UV scaling and then adaptive-sharpen for sharpening. This results in a perfect picture for me.
I use KrigBilateral for UV scaling and then adaptive-sharpen for sharpening. This results in a perfect
picture for me.
You can also use a custon LUT File. It is located in $ConfigDir/shaders/lut/lut.cube. If you provide there
a lut file it will be automaticly used. In the Mainmenue you can switch LUT on and off.
Konfig Guide for softhddrm Version
----------------------------------
You should set the Monitor Type to HD TV or UHD-HDR TV depending on your TV Set
With softhddrm and a HDR TV Set you can view HDR-HLG content. This is tested with Kernel 5.12 and a Intel NUC.
Setup: environment

52
hdr.c
View File

@ -335,17 +335,12 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
struct AVMasteringDisplayMetadata *md = NULL;
struct AVContentLightMetadata *ld = NULL;
if (render->hdr_metadata == -1) { // Metadata not supported
return;
}
// clean up FFMEPG stuff
if (trc == AVCOL_TRC_BT2020_10)
trc = AVCOL_TRC_ARIB_STD_B67;
if (trc == AVCOL_TRC_UNSPECIFIED)
trc = AVCOL_TRC_BT709;
if (color == AVCOL_PRI_UNSPECIFIED)
color = AVCOL_PRI_BT709;
if ((old_color == color && old_trc == trc && !sd1 && !sd2) || !render->hdr_metadata)
return; // nothing to do
@ -371,12 +366,15 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
Debug(3,"Update HDR to TRC %d color %d\n",trc,color);
if (trc == AVCOL_TRC_BT2020_10)
trc = AVCOL_TRC_ARIB_STD_B67;
old_color = color;
old_trc = trc;
if (VulkanTargetColorSpace != 3) { // no HDR TV
m_need_modeset = 1; // change in colorsettings
return;
}
if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
@ -392,7 +390,7 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
break;
case AVCOL_TRC_SMPTE2084: // 16
eotf = EOTF_ST2084;
break;
break;
default:
eotf = EOTF_TRADITIONAL_GAMMA_SDR;
break;
@ -467,24 +465,24 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
eotf);
ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id);
if (ret) {
printf("DRM: HDR metadata: failed blob create \n");
render->hdr_blob_id = 0;
return;
}
ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id);
if (ret) {
printf("DRM: HDR metadata: failed blob create \n");
render->hdr_blob_id = 0;
return;
}
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id,
render->hdr_metadata, render->hdr_blob_id);
if (ret) {
printf("DRM: HDR metadata: failed property set %d\n",ret);
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id,
render->hdr_metadata, render->hdr_blob_id);
if (ret) {
printf("DRM: HDR metadata: failed property set %d\n",ret);
if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
render->hdr_blob_id = 0;
return;
}
if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
render->hdr_blob_id = 0;
return;
}
m_need_modeset = 1;

View File

@ -280,6 +280,7 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
switch (colorspace) {
case AVCOL_SPC_RGB:
case AVCOL_SPC_BT470BG:
m = &yuv_bt601.m[0][0];
c = &yuv_bt601.c[0];
Debug(3, "BT601 Colorspace used\n");
@ -339,8 +340,9 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
GLSL("color.rgb = max(color.rgb, 0.0); \n");
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
// GLSL("color.rgb = pow(color.rgb, vec3(2.4)); \n");
// GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(%f)) * vec3(1.0/%f)) + vec3(%f),bvec3(lessThan(vec3(0.5), color.rgb)));\n",HLG_C, HLG_A, HLG_B);
// GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(%f)) * vec3(1.0/%f)) + vec3(%f) , bvec3(lessThan(vec3(0.5), color.rgb)));\n",HLG_C, HLG_A, HLG_B);
GLSL("color.rgb = mix(vec3(4.0) * color.rgb * color.rgb,exp((color.rgb - vec3(0.55991073)) * vec3(1.0/0.17883277)) + vec3(0.28466892), bvec3(lessThan(vec3(0.5), color.rgb)));\n");
GLSL("color.rgb *= vec3(1.0/3.17955); \n"); // PL_COLOR_SDR_WHITE_HLG
GLSL("// color mapping \n");
GLSL("color.rgb = cms_matrix * color.rgb; \n");
#ifndef GAMMA
@ -348,6 +350,7 @@ static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace)
GLSL("color.rgb = max(color.rgb, 0.0); \n");
// GLSL("color.rgb = clamp(color.rgb, 0.0, 1.0); \n");
// GLSL("color.rgb = pow(color.rgb, vec3(1.0/2.4)); \n");
GLSL("color.rgb *= vec3(3.17955); \n"); // PL_COLOR_SDR_WHITE_HLG
GLSL("color.rgb = mix(vec3(0.5) * sqrt(color.rgb), vec3(0.17883277) * log(color.rgb - vec3(0.28466892)) + vec3(0.55991073), bvec3(lessThan(vec3(1.0), color.rgb))); \n");
#endif

View File

@ -63,7 +63,7 @@ extern void ToggleLUT();
/// vdr-plugin version number.
/// Makefile extracts the version number for generating the file name
/// for the distribution archive.
static const char *const VERSION = "3.4"
static const char *const VERSION = "3.4.1"
#ifdef GIT_REV
"-GIT" GIT_REV
#endif
@ -1109,10 +1109,11 @@ void cMenuSetupSoft::Create(void)
static const char *const resolution[RESOLUTIONS] = {
"576i", "720p", "fake 1080", "1080", "2160p"
};
#ifdef PLACEBO
static const char *const target_colorspace[] = {
"Monitor", "sRGB", "BT709", "HDR-HLG", "HDR10",
"default Monitor", "sRGB Monitor", "HD TV (BT.709)", "UHD-HDR TV (BT.2020)",
};
#ifdef PLACEBO
static const char *const target_colorblindness[] = {
"None", "Protanomaly", "Deuteranomaly", "Tritanomaly", "Monochromacy",
};
@ -1201,12 +1202,12 @@ void cMenuSetupSoft::Create(void)
Add(new cMenuEditIntItem(tr("Saturation (0..100)"), &Saturation, 0, 100, tr("min"), tr("max")));
Add(new cMenuEditIntItem(tr("Gamma (0..100)"), &Gamma, 0, 100, tr("min"), tr("max")));
Add(new cMenuEditIntItem(tr("Hue (-314..314) "), &Hue, -314, 314, tr("min"), tr("max")));
Add(new cMenuEditStraItem(tr("Monitor Colorspace"), &TargetColorSpace, 5, target_colorspace));
Add(new cMenuEditStraItem(tr("Color Blindness"), &ColorBlindness, 5, target_colorblindness));
Add(new cMenuEditIntItem(tr("Color Correction (-100..100) "), &ColorBlindnessFaktor, -100, 100, tr("min"),
tr("max")));
#endif
Add(new cMenuEditStraItem(tr("Monitor Type"), &TargetColorSpace, 4, target_colorspace));
for (i = 0; i < RESOLUTIONS; ++i) {
cString msg;

142
video.c
View File

@ -3469,18 +3469,39 @@ static void CuvidRenderFrame(CuvidDecoder * decoder, const AVCodecContext * vide
CuvidUpdateOutput(decoder);
}
color = frame->colorspace;
if (color == AVCOL_SPC_UNSPECIFIED) // if unknown
color = AVCOL_SPC_BT709;
if (color == AVCOL_SPC_RGB)
color = AVCOL_SPC_BT470BG; // fix ffmpeg libav failure
frame->colorspace = color;
// more libav fixes
if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED)
frame->color_primaries = AVCOL_PRI_BT709;
if (frame->color_trc == AVCOL_TRC_UNSPECIFIED)
frame->color_trc = AVCOL_TRC_BT709;
// printf("Orig colorspace %d Primaries %d TRC %d ------- ",frame->colorspace,frame->color_primaries,frame->color_trc);
// Fix libav colorspace failure
color = frame->colorspace;
if (color == AVCOL_SPC_UNSPECIFIED) // failure with RTL HD and all SD channels with vaapi
if (frame->width > 720)
color = AVCOL_SPC_BT709;
else
color = AVCOL_SPC_BT470BG;
if (color == AVCOL_SPC_RGB) // Cuvid decoder failure with SD channels
color = AVCOL_SPC_BT470BG;
frame->colorspace = color;
// Fix libav Color primaries failures
if (frame->color_primaries == AVCOL_PRI_UNSPECIFIED) // failure with RTL HD and all SD channels with vaapi
if (frame->width > 720)
frame->color_primaries = AVCOL_PRI_BT709;
else
frame->color_primaries = AVCOL_PRI_BT470BG;
if (frame->color_primaries == AVCOL_PRI_RESERVED0) // cuvid decoder failure with SD channels
frame->color_primaries = AVCOL_PRI_BT470BG;
// Fix libav Color TRC failures
if (frame->color_trc == AVCOL_TRC_UNSPECIFIED) // failure with RTL HD and all SD channels with vaapi
if (frame->width > 720)
frame->color_trc = AVCOL_TRC_BT709;
else
frame->color_trc = AVCOL_TRC_SMPTE170M;
if (frame->color_trc == AVCOL_TRC_RESERVED0) // cuvid decoder failure with SD channels
frame->color_trc = AVCOL_TRC_SMPTE170M;
// printf("Patched colorspace %d Primaries %d TRC %d\n",frame->colorspace,frame->color_primaries,frame->color_trc);
#ifdef RASPI
//
// Check image, format, size
@ -3751,7 +3772,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
float xcropf, ycropf;
GLint texLoc;
AVFrame *frame;
AVFrameSideData *sd,*sd1,*sd2;
AVFrameSideData *sd,*sd1=NULL,*sd2=NULL;
#ifdef PLACEBO
if (level) {
@ -3888,9 +3909,7 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
// Make sure this value is more or less legal
if (img->color.sig_peak < 1.0 || img->color.sig_peak > 50.0)
img->color.sig_peak = 0.0;
#ifdef USE_DRM
set_hdr_metadata(frame->color_primaries, frame->color_trc, sd1, sd2);
#endif
#if defined VAAPI || defined USE_DRM
render_params.peak_detect_params = NULL;
@ -3906,7 +3925,70 @@ static void CuvidMixVideo(CuvidDecoder * decoder, __attribute__((unused))
pl->shift_x = -0.5f;
break;
}
target->repr.sys = PL_COLOR_SYSTEM_RGB;
if (VideoStudioLevels)
target->repr.levels = PL_COLOR_LEVELS_PC;
else
target->repr.levels = PL_COLOR_LEVELS_TV;
target->repr.alpha = PL_ALPHA_UNKNOWN;
// target.repr.bits.sample_depth = 16;
// target.repr.bits.color_depth = 16;
// target.repr.bits.bit_shift =0;
#if USE_DRM
switch (VulkanTargetColorSpace) {
case 0: // Monitor
memcpy(&target->color, &pl_color_space_monitor, sizeof(struct pl_color_space));
break;
case 1: // sRGB
memcpy(&target->color, &pl_color_space_srgb, sizeof(struct pl_color_space));
break;
case 2: // HD TV
set_hdr_metadata(frame->color_primaries, frame->color_trc, sd1, sd2);
if (decoder->ColorSpace == AVCOL_SPC_BT470BG) {
target->color.primaries = PL_COLOR_PRIM_BT_601_625;
target->color.transfer = PL_COLOR_TRC_BT_1886;
target->color.light = PL_COLOR_LIGHT_DISPLAY;
} else {
memcpy(&target->color, &pl_color_space_bt709, sizeof(struct pl_color_space));
}
break;
case 3: // HDR TV
set_hdr_metadata(frame->color_primaries, frame->color_trc, sd1, sd2);
if (decoder->ColorSpace == AVCOL_SPC_BT2020_NCL) {
memcpy(&target->color, &pl_color_space_bt2020_hlg, sizeof(struct pl_color_space));
} else if (decoder->ColorSpace == AVCOL_SPC_BT470BG) {
target->color.primaries = PL_COLOR_PRIM_BT_601_625;
target->color.transfer = PL_COLOR_TRC_BT_1886;
target->color.light = PL_COLOR_LIGHT_DISPLAY;;
} else {
memcpy(&target->color, &pl_color_space_bt709, sizeof(struct pl_color_space));
}
break;
default:
memcpy(&target->color, &pl_color_space_monitor, sizeof(struct pl_color_space));
break;
}
#else
switch (VulkanTargetColorSpace) {
case 0: // Monitor
memcpy(&target->color, &pl_color_space_monitor, sizeof(struct pl_color_space));
break;
case 1: // sRGB
memcpy(&target->color, &pl_color_space_srgb, sizeof(struct pl_color_space));
break;
case 2: // HD TV
case 3: // UHD HDR TV
memcpy(&target->color, &pl_color_space_bt709, sizeof(struct pl_color_space));
break;
default:
memcpy(&target->color, &pl_color_space_monitor, sizeof(struct pl_color_space));
break;
}
#endif
//printf("sys %d prim %d trc %d light %d\n",img->repr.sys,img->color.primaries,img->color.transfer,img->color.light);
// Source crop
if (VideoScalerTest) { // right side defined scaler
@ -4258,37 +4340,9 @@ static void CuvidDisplayFrame(void)
VideoSurfaceModesChanged = 0;
}
target.repr.sys = PL_COLOR_SYSTEM_RGB;
if (VideoStudioLevels)
target.repr.levels = PL_COLOR_LEVELS_PC;
else
target.repr.levels = PL_COLOR_LEVELS_TV;
target.repr.alpha = PL_ALPHA_UNKNOWN;
// target.repr.bits.sample_depth = 16;
// target.repr.bits.color_depth = 16;
// target.repr.bits.bit_shift =0;
switch (VulkanTargetColorSpace) {
case 0:
memcpy(&target.color, &pl_color_space_monitor, sizeof(struct pl_color_space));
break;
case 1:
memcpy(&target.color, &pl_color_space_srgb, sizeof(struct pl_color_space));
break;
case 2:
memcpy(&target.color, &pl_color_space_bt709, sizeof(struct pl_color_space));
break;
case 3:
memcpy(&target.color, &pl_color_space_bt2020_hlg, sizeof(struct pl_color_space));
break;
case 4:
memcpy(&target.color, &pl_color_space_hdr10, sizeof(struct pl_color_space));
break;
default:
memcpy(&target.color, &pl_color_space_monitor, sizeof(struct pl_color_space));
break;
}
#ifdef GAMMA
// target.color.transfer = PL_COLOR_TRC_LINEAR;
#endif