[vlc-devel] [PATCH] opengl: add GUI options for libplacebo settings
Niklas Haas
vlc at haasn.xyz
Sun Dec 31 07:12:08 CET 2017
From: Niklas Haas <git at haasn.xyz>
This allows users to override the target colorspace, some of the
colorspace conversion options, the tone mapping settings, and some of
the dithering settings.
Settings which I decided to omit include:
- dither LUT size (limited by the shader embedding method)
- temporal dither (not currently possible)
- overrides for the source colorspace (shouldn't persist)
- target display's light type (unlikely to not be _DISPLAY)
- target display's HDR metadata (usually taken care of by the display)
---
modules/video_output/opengl/display.c | 169 +++++++++++++++++++++++++
modules/video_output/opengl/fragment_shaders.c | 32 ++++-
2 files changed, 194 insertions(+), 7 deletions(-)
diff --git a/modules/video_output/opengl/display.c b/modules/video_output/opengl/display.c
index 2ecdd0caaa..a42a4cc65a 100644
--- a/modules/video_output/opengl/display.c
+++ b/modules/video_output/opengl/display.c
@@ -42,6 +42,149 @@ static void Close (vlc_object_t *);
#define PROVIDER_LONGTEXT N_( \
"Extension through which to use the Open Graphics Library (OpenGL).")
+#ifdef HAVE_LIBPLACEBO
+
+#include <libplacebo/shaders/colorspace.h>
+
+#define RENDER_INTENT_TEXT N_("Rendering intent for color conversion")
+#define RENDER_INTENT_LONGTEXT N_("The algorithm used to convert between color spaces")
+
+static const int intent_values[] = {
+ PL_INTENT_PERCEPTUAL,
+ PL_INTENT_RELATIVE_COLORIMETRIC,
+ PL_INTENT_SATURATION,
+ PL_INTENT_ABSOLUTE_COLORIMETRIC,
+};
+
+static const char * const intent_text[] = {
+ "Perceptual",
+ "Relative colorimetric",
+ "Absolute colorimetric",
+ "Saturation",
+};
+
+#define PRIM_TEXT N_("Display primaries")
+#define PRIM_LONGTEXT N_("The primaries associated with the output display")
+
+static const int prim_values[] = {
+ PL_COLOR_PRIM_UNKNOWN,
+ PL_COLOR_PRIM_BT_601_525,
+ PL_COLOR_PRIM_BT_601_625,
+ PL_COLOR_PRIM_BT_709,
+ PL_COLOR_PRIM_BT_470M,
+ PL_COLOR_PRIM_BT_2020,
+ PL_COLOR_PRIM_APPLE,
+ PL_COLOR_PRIM_ADOBE,
+ PL_COLOR_PRIM_PRO_PHOTO,
+ PL_COLOR_PRIM_CIE_1931,
+ PL_COLOR_PRIM_DCI_P3,
+ PL_COLOR_PRIM_V_GAMUT,
+ PL_COLOR_PRIM_S_GAMUT,
+};
+
+static const char * const prim_text[] = {
+ "Unknown primaries",
+ "ITU-R Rec. BT.601 (525-line = NTSC, SMPTE-C)",
+ "ITU-R Rec. BT.601 (625-line = PAL, SECAM)",
+ "ITU-R Rec. BT.709 (HD), also sRGB",
+ "ITU-R Rec. BT.470 M",
+ "ITU-R Rec. BT.2020 (UltraHD)",
+ "Apple RGB",
+ "Adobe RGB (1998)",
+ "ProPhoto RGB (ROMM)",
+ "CIE 1931 RGB primaries",
+ "DCI-P3 (Digital Cinema)",
+ "Panasonic V-Gamut (VARICAM)",
+ "Sony S-Gamut",
+};
+
+#define TRC_TEXT N_("Display gamma / transfer function")
+#define TRC_LONGTEXT N_("The gamma/transfer function associated with the output display")
+
+static const int trc_values[] = {
+ PL_COLOR_TRC_UNKNOWN,
+ PL_COLOR_TRC_BT_1886,
+ PL_COLOR_TRC_SRGB,
+ PL_COLOR_TRC_LINEAR,
+ PL_COLOR_TRC_GAMMA18,
+ PL_COLOR_TRC_GAMMA22,
+ PL_COLOR_TRC_GAMMA28,
+ PL_COLOR_TRC_PRO_PHOTO,
+ PL_COLOR_TRC_PQ,
+ PL_COLOR_TRC_HLG,
+ PL_COLOR_TRC_V_LOG,
+ PL_COLOR_TRC_S_LOG1,
+ PL_COLOR_TRC_S_LOG2,
+};
+
+static const char * const trc_text[] = {
+ "Unknown gamma",
+ "ITU-R Rec. BT.1886 (CRT emulation + OOTF)",
+ "IEC 61966-2-4 sRGB (CRT emulation)",
+ "Linear light content",
+ "Pure power gamma 1.8",
+ "Pure power gamma 2.2",
+ "Pure power gamma 2.8",
+ "ProPhoto RGB (ROMM)",
+ "ITU-R BT.2100 PQ (perceptual quantizer), aka SMPTE ST2048",
+ "ITU-R BT.2100 HLG (hybrid log-gamma), aka ARIB STD-B67",
+ "Panasonic V-Log (VARICAM)",
+ "Sony S-Log1",
+ "Sony S-Log2",
+};
+
+#define TONEMAPPING_TEXT N_("Tone-mapping algorithm")
+#define TONEMAPPING_LONGTEXT N_("Algorithm to use when converting from wide gamut to standard gamut, or from HDR to SDR")
+
+static const int tone_values[] = {
+ PL_TONE_MAPPING_HABLE,
+ PL_TONE_MAPPING_MOBIUS,
+ PL_TONE_MAPPING_REINHARD,
+ PL_TONE_MAPPING_GAMMA,
+ PL_TONE_MAPPING_LINEAR,
+ PL_TONE_MAPPING_CLIP,
+};
+
+static const char * const tone_text[] = {
+ "Hable (filmic mapping, recommended)",
+ "Mobius (linear + knee)",
+ "Reinhard (simple non-linear)",
+ "Gamma-Power law",
+ "Linear stretch (peak to peak)",
+ "Hard clip out-of-gamut",
+};
+
+#define TONEMAP_PARAM_TEXT N_("Tone-mapping parameter")
+#define TONEMAP_PARAM_LONGTEXT N_("This parameter can be used to tune the tone-mapping curve. Specifics depend on the curve used")
+
+#define TONEMAP_DESAT_TEXT N_("Tone-mapping desaturation coefficient")
+#define TONEMAP_DESAT_LONGTEXT N_("How strongly to desaturate overbright colors towards white. 0.0 disables this behavior")
+
+#define TONEMAP_WARN_TEXT N_("Highlight clipped pixels")
+#define TONEMAP_WARN_LONGTEXT N_("Debugging tool to indicate which pixels were clipped as part of the tone mapping process")
+
+#define DITHER_TEXT N_("Dithering algorithm")
+#define DITHER_LONGTEXT N_("The algorithm to use when dithering to a lower bit depth")
+
+static const int dither_values[] = {
+ -1, // no dithering
+ PL_DITHER_BLUE_NOISE,
+ PL_DITHER_WHITE_NOISE,
+ PL_DITHER_ORDERED_LUT,
+};
+
+static const char * const dither_text[] = {
+ "Disabled",
+ "Blue noise",
+ "White noise",
+ "Bayer matrix (ordered dither)",
+};
+
+#define DEPTH_TEXT N_("Dither depth override (0 = framebuffer depth)")
+#define DEPTH_LONGTEXT N_("Overrides the detected framebuffer depth. Useful to dither to lower bit depths than otherwise required")
+
+#endif
+
vlc_module_begin ()
#if defined (USE_OPENGL_ES2)
# define API VLC_OPENGL_ES2
@@ -69,6 +212,32 @@ vlc_module_begin ()
GL_TEXT, PROVIDER_LONGTEXT, true)
#endif
add_glconv ()
+
+#ifdef HAVE_LIBPLACEBO
+ set_section(N_("Colorspace conversion"), NULL)
+ add_integer("rendering-intent", pl_color_map_default_params.intent,
+ RENDER_INTENT_TEXT, RENDER_INTENT_LONGTEXT, false)
+ change_integer_list(intent_values, intent_text)
+ add_integer("target-prim", PL_COLOR_PRIM_UNKNOWN, PRIM_TEXT, PRIM_LONGTEXT, false)
+ change_integer_list(prim_values, prim_text)
+ add_integer("target-trc", PL_COLOR_TRC_UNKNOWN, TRC_TEXT, TRC_LONGTEXT, false)
+ change_integer_list(trc_values, trc_text)
+
+ set_section(N_("Tone mapping"), NULL)
+ add_integer("tone-mapping", PL_TONE_MAPPING_HABLE,
+ TONEMAPPING_TEXT, TONEMAPPING_LONGTEXT, false)
+ change_integer_list(tone_values, tone_text)
+ add_float("tone-mapping-param", pl_color_map_default_params.tone_mapping_param,
+ TONEMAP_PARAM_TEXT, TONEMAP_PARAM_LONGTEXT, true)
+ add_float("tone-mapping-desat", pl_color_map_default_params.tone_mapping_desaturate,
+ TONEMAP_DESAT_TEXT, TONEMAP_DESAT_LONGTEXT, false)
+ add_bool("tone-mapping-warn", false, TONEMAP_WARN_TEXT, TONEMAP_WARN_LONGTEXT, false)
+
+ set_section(N_("Dithering"), NULL)
+ add_integer("dither-algo", pl_dither_default_params.method, DITHER_TEXT, DITHER_LONGTEXT, false)
+ change_integer_list(dither_values, dither_text)
+ add_integer_with_range("dither-depth", 0, 0, 16, DEPTH_TEXT, DEPTH_LONGTEXT, false)
+#endif
vlc_module_end ()
struct vout_display_sys_t
diff --git a/modules/video_output/opengl/fragment_shaders.c b/modules/video_output/opengl/fragment_shaders.c
index 251faccc9c..82850a339f 100644
--- a/modules/video_output/opengl/fragment_shaders.c
+++ b/modules/video_output/opengl/fragment_shaders.c
@@ -605,16 +605,34 @@ opengl_fragment_shader_init_impl(opengl_tex_converter_t *tc, GLenum tex_target,
#ifdef HAVE_LIBPLACEBO
if (tc->pl_sh) {
struct pl_shader *sh = tc->pl_sh;
- pl_shader_color_map(sh, &pl_color_map_default_params,
+ struct pl_color_map_params color_params = pl_color_map_default_params;
+ color_params.intent = var_InheritInteger(tc->gl, "rendering-intent");
+ color_params.tone_mapping_algo = var_InheritInteger(tc->gl, "tone-mapping");
+ color_params.tone_mapping_param = var_InheritFloat(tc->gl, "tone-mapping-param");
+ color_params.tone_mapping_desaturate = var_InheritFloat(tc->gl, "tone-mapping-desat");
+ color_params.gamut_warning = var_InheritBool(tc->gl, "tone-mapping-warn");
+
+ struct pl_color_space dst_space = pl_color_space_unknown;
+ dst_space.primaries = var_InheritInteger(tc->gl, "target-prim");
+ dst_space.transfer = var_InheritInteger(tc->gl, "target-trc");
+
+ pl_shader_color_map(sh, &color_params,
pl_color_space_from_video_format(&tc->fmt),
- pl_color_space_unknown, NULL, false);
+ dst_space, NULL, false);
struct pl_shader_obj *dither_state = NULL;
- const int out_bits = 8; // FIXME: query actual framebuffer depth?
- pl_shader_dither(sh, out_bits, &dither_state, &(struct pl_dither_params) {
- .method = PL_DITHER_BLUE_NOISE,
- .lut_size = 4, // avoid too large values, since this gets embedded
- });
+ int out_bits = 8; // FIXME: query actual framebuffer depth?
+ int override = var_InheritInteger(tc->gl, "dither-depth");
+ if (override)
+ out_bits = override;
+
+ int method = var_InheritInteger(tc->gl, "dither-algo");
+ if (method >= 0) {
+ pl_shader_dither(sh, out_bits, &dither_state, &(struct pl_dither_params) {
+ .method = method,
+ .lut_size = 4, // avoid too large values, since this gets embedded
+ });
+ }
const struct pl_shader_res *res = tc->pl_sh_res = pl_shader_finalize(sh);
pl_shader_obj_destroy(&dither_state);
--
2.15.1
More information about the vlc-devel
mailing list