[vlc-devel] [PATCH] [WIP] RFC: add HDR/BT.2020 support (using libplacebo)

Niklas Haas vlc at haasn.xyz
Fri Oct 27 15:45:02 CEST 2017


On Fri, 27 Oct 2017 02:37:08 +0200, Niklas Haas <vlc at haasn.xyz> wrote:
> On Thu, 26 Oct 2017 20:01:07 +0300, Rémi Denis-Courmont <remi at remlab.net> wrote:
> > VLC has its own convenience wrapper for that. Obviously, that can´t be used 
> > for by an external library. But you can use a similar solution.
> > 
> 
> I've given the solution an attempt:
> https://github.com/haasn/libplacebo/commit/0e67eec23628f97089bb25724248e502694c57bb
> 
> This works on my end, but currently only has an implementation for
> systems with `uselocale`, which apparently Win32 does not belong to. On
> Win32, there are locale-invariant versions of printf which could be used
> to implement the same API, but I'm unable to produce this code. (BSD
> could also use the printf_l etc. wrappers, although BSD supports
> uselocale so it shouldn't be necessary)

I've also updated my patch in order to incorporate integration with the
build system + contrib/ (thanks to ePirat for the code), and make the
code optional (based on #ifdef HAVE_LIBPLACEB).

I've attached the new version.
-------------- next part --------------
>From 071cd2cec6131c389f2cab9f38e66fb50be25a0f Mon Sep 17 00:00:00 2001
From: Marvin Scholz <epirat07 at gmail.com>
Date: Tue, 10 Oct 2017 15:07:58 +0200
Subject: [PATCH] video_output: opengl: add basic support for libplacebo

This adds support for conversion between color spaces, in particular HDR
tone mapping and wide gamut -> standard gamut conversion.

Things that this patch does not yet address:

- It does not use libplacebo's scaling features. This is blocked by the
  fact that libplacebo does not currently support OpenGL (only Vulkan).

- It does not add support for BT.2020 YCbCr. This would be easy to
  implement in much the same way as the tone mapping support, by using
  pl_shader_decode_color, replacing the hard-coded matrices. This would
  also allow adding support for hue, saturation etc. controls.

- It does not hook up the pl_color_map_paramse options to the VLC GUI.
  This would have to be done to let users influence the subjective
  configuration options, as well as specify their display device's
  configuration.

Due to libplacebo being in a very early stage, we statically link it to
avoid forcing distros to package it yet, and also add it to contrib/
with a fixed commit (in case the API changes later on).

We also make libplacebo entirely optional, due to the short time-frame
in between adding support and the VLC 3.0 release, combined with the
lack of testing on all platforms.

Thanks to @ePirat for contributing the changes to the build system.

P.S.:

If everybody's happy with this patch, I will most likely end up tagging
a libplacebo release as v0.1 with a stable API version, so you can use
that tag instead of the commit hash.
---
 configure.ac                                   |  19 ++++
 contrib/src/libplacebo/rules.mak               |  26 +++++
 modules/video_output/Makefile.am               |  24 +++--
 modules/video_output/opengl/converter.h        |  23 +++++
 modules/video_output/opengl/fragment_shaders.c | 136 +++++++++++++++++++++++++
 modules/video_output/opengl/vout_helper.c      |  35 +++++++
 6 files changed, 257 insertions(+), 6 deletions(-)
 create mode 100644 contrib/src/libplacebo/rules.mak

diff --git a/configure.ac b/configure.ac
index f4e5aa9d30..f19ca02a4d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4082,6 +4082,25 @@ dnl Libnotify notification plugin
 dnl
 PKG_ENABLE_MODULES_VLC([NOTIFY], [], [libnotify gtk+-2.0], [libnotify notification], [auto])
 
+dnl
+dnl  libplacebo support
+dnl
+AC_ARG_ENABLE(libplacebo,
+  [  --disable-libplacebo       libplacebo support (default auto)])
+
+AS_IF([test "$enable_libplacebo" != "no"], [
+  PKG_CHECK_MODULES([LIBPLACEBO], [libplacebo], [
+    AC_DEFINE([HAVE_LIBPLACEBO], [1], [Define to 1 if libplacebo is enabled.])
+  ], [
+    enable_libplacebo="no"
+    AS_IF([test -n "${enable_libplacebo}"], [
+      AC_MSG_ERROR([${LIBPLACEBO_PKG_ERRORS}.])
+    ])
+  ])
+])
+AM_CONDITIONAL(HAVE_LIBPLACEBO, [test "$enable_libplacebo" != "no"])
+
+
 dnl
 dnl  Endianness check
 dnl
diff --git a/contrib/src/libplacebo/rules.mak b/contrib/src/libplacebo/rules.mak
new file mode 100644
index 0000000000..9012473ca8
--- /dev/null
+++ b/contrib/src/libplacebo/rules.mak
@@ -0,0 +1,26 @@
+# libplacebo
+
+PLACEBO_HASH=eb263b32ff7d82baf06e7ace4b1724fe8da5278b
+PLACEBO_SNAPURL := https://github.com/haasn/libplacebo/archive/$(PLACEBO_HASH).tar.gz
+PLACEBO_GITURL := https://github.com/haasn/libplacebo.git
+
+PLACEBOCONF := --prefix="$(PREFIX)" \
+	--libdir lib \
+	--default-library static
+
+$(TARBALLS)/libplacebo-$(PLACEBO_HASH).tar.xz:
+	$(call download_git,$(PLACEBO_GITURL),,$(PLACEBO_HASH))
+
+.sum-libplacebo: $(TARBALLS)/libplacebo-$(PLACEBO_HASH).tar.xz
+	$(call check_githash,$(PLACEBO_HASH))
+	touch $@
+
+libplacebo: libplacebo-$(PLACEBO_HASH).tar.xz .sum-libplacebo
+	$(UNPACK)
+	$(MOVE)
+
+.libplacebo: libplacebo
+	cd $< && rm -rf ./build
+	cd $< && $(HOSTVARS) meson $(PLACEBOCONF) build
+	cd $< && cd build && ninja install
+	touch $@
diff --git a/modules/video_output/Makefile.am b/modules/video_output/Makefile.am
index b77824944d..2785504d8c 100644
--- a/modules/video_output/Makefile.am
+++ b/modules/video_output/Makefile.am
@@ -8,6 +8,9 @@ OPENGL_COMMONSOURCES = video_output/opengl/vout_helper.c \
 	video_output/opengl/internal.h video_output/opengl/fragment_shaders.c \
 	video_output/opengl/converter_sw.c
 
+OPENGL_COMMONCLFAGS = $(LIBPLACEBO_CFLAGS)
+OPENGL_COMMONLIBS = $(LIBPLACEBO_LIBS)
+
 if HAVE_DECKLINK
 libdecklinkoutput_plugin_la_SOURCES = video_output/decklink.cpp
 libdecklinkoutput_plugin_la_CXXFLAGS = $(AM_CXXFLAGS) $(CPPFLAGS_decklinkoutput)
@@ -21,10 +24,14 @@ libglconv_cvpx_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
 
 if HAVE_OSX
 libvout_macosx_plugin_la_SOURCES = video_output/macosx.m $(OPENGL_COMMONSOURCES)
+libvout_macosx_plugin_la_CFLAGS = $(AM_CFLAGS) $(OPENGL_COMMONCLFAGS)
+libvout_macosx_plugin_la_LIBADD = $(OPENGL_COMMONLIBS)
 libvout_macosx_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)' \
 	-Wl,-framework,OpenGL,-framework,Cocoa
 
 libcaopengllayer_plugin_la_SOURCES = video_output/caopengllayer.m $(OPENGL_COMMONSOURCES)
+libcaopengllayer_plugin_la_CFLAGS = $(AM_CFLAGS) $(OPENGL_COMMONCLFAGS)
+libcaopengllayer_plugin_la_LIBADD = $(OPENGL_COMMONLIBS)
 libcaopengllayer_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)' \
 	-Wl,-framework,OpenGL,-framework,Cocoa,-framework,QuartzCore
 
@@ -39,6 +46,8 @@ libglconv_cvpx_plugin_la_CFLAGS = $(AM_CFLAGS) -DUSE_OPENGL_ES2
 endif
 
 libvout_ios_plugin_la_SOURCES = video_output/ios.m $(OPENGL_COMMONSOURCES)
+libvout_ios_plugin_la_CFLAGS = $(AM_CFLAGS) $(OPENGL_COMMONCLFAGS)
+libvout_ios_plugin_la_LIBADD = $(OPENGL_COMMONLIBS)
 libvout_ios_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)' \
 	-Wl,-framework,OpenGLES,-framework,QuartzCore,-framework,UIKit
 if HAVE_IOS
@@ -50,16 +59,16 @@ endif
 
 ### OpenGL ###
 libgles2_plugin_la_SOURCES = $(OPENGL_COMMONSOURCES) video_output/opengl/display.c
-libgles2_plugin_la_CFLAGS = $(AM_CFLAGS) $(GLES2_CFLAGS) -DUSE_OPENGL_ES2
-libgles2_plugin_la_LIBADD = $(GLES2_LIBS) $(LIBM)
+libgles2_plugin_la_CFLAGS = $(AM_CFLAGS) $(GLES2_CFLAGS) -DUSE_OPENGL_ES2 $(OPENGL_COMMONCLFAGS)
+libgles2_plugin_la_LIBADD = $(GLES2_LIBS) $(LIBM) $(OPENGL_COMMONLIBS)
 libgles2_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
 
 EXTRA_LTLIBRARIES += libgles2_plugin.la
 vout_LTLIBRARIES += $(LTLIBgles2)
 
 libgl_plugin_la_SOURCES = $(OPENGL_COMMONSOURCES) video_output/opengl/display.c
-libgl_plugin_la_CFLAGS = $(AM_CFLAGS) $(GL_CFLAGS)
-libgl_plugin_la_LIBADD = $(GL_LIBS) $(LIBM)
+libgl_plugin_la_CFLAGS = $(AM_CFLAGS) $(GL_CFLAGS) $(OPENGL_COMMONCLFAGS)
+libgl_plugin_la_LIBADD = $(GL_LIBS) $(LIBM) $(OPENGL_COMMONLIBS)
 
 libglconv_vaapi_wl_plugin_la_SOURCES = video_output/opengl/converter_vaapi.c \
 	video_output/opengl/converter.h \
@@ -324,8 +333,11 @@ libglwin32_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) \
 libwgl_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) \
         -DMODULE_NAME_IS_wgl
 
-libglwin32_plugin_la_LIBADD = -lopengl32 -lgdi32 $(LIBCOM) -luuid
-libwgl_plugin_la_LIBADD = -lopengl32 -lgdi32
+libglwin32_plugin_la_LIBADD = -lopengl32 -lgdi32 $(LIBCOM) -luuid $(OPENGL_COMMONLIBS)
+libwgl_plugin_la_LIBADD = -lopengl32 -lgdi32 $(OPENGL_COMMONLIBS)
+
+libglwin32_plugin_la_CFLAGS = $(AM_CFLAGS) $(OPENGL_COMMONCLFAGS)
+libwgl_plugin_la_CFLAGS = $(AM_CFLAGS) $(OPENGL_COMMONCLFAGS)
 
 libglwin32_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
 libwgl_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
diff --git a/modules/video_output/opengl/converter.h b/modules/video_output/opengl/converter.h
index 3acbf6911d..efb423ae69 100644
--- a/modules/video_output/opengl/converter.h
+++ b/modules/video_output/opengl/converter.h
@@ -21,6 +21,10 @@
 #ifndef VLC_OPENGL_CONVERTER_H
 #define VLC_OPENGL_CONVERTER_H
 
+#ifdef HAVE_LIBPLACEBO
+#include <libplacebo/shaders.h>
+#endif
+
 #include "vout_helper.h"
 #include <vlc_plugin.h>
 
@@ -64,9 +68,13 @@ typedef void (APIENTRY *PFNGLBUFFERSTORAGEPROC) (GLenum target, GLsizeiptr size,
 #   define PFNGLVERTEXATTRIBPOINTERPROC      typeof(glVertexAttribPointer)*
 #   define PFNGLENABLEVERTEXATTRIBARRAYPROC  typeof(glEnableVertexAttribArray)*
 #   define PFNGLUNIFORMMATRIX4FVPROC         typeof(glUniformMatrix4fv)*
+#   define PFNGLUNIFORMMATRIX3FVPROC         typeof(glUniformMatrix3fv)*
+#   define PFNGLUNIFORMMATRIX2FVPROC         typeof(glUniformMatrix2fv)*
 #   define PFNGLUNIFORM4FVPROC               typeof(glUniform4fv)*
 #   define PFNGLUNIFORM4FPROC                typeof(glUniform4f)*
+#   define PFNGLUNIFORM3FPROC                typeof(glUniform3f)*
 #   define PFNGLUNIFORM2FPROC                typeof(glUniform2f)*
+#   define PFNGLUNIFORM1FPROC                typeof(glUniform1f)*
 #   define PFNGLUNIFORM1IPROC                typeof(glUniform1i)*
 #   define PFNGLCREATESHADERPROC             typeof(glCreateShader)*
 #   define PFNGLSHADERSOURCEPROC             typeof(glShaderSource)*
@@ -144,9 +152,13 @@ typedef struct {
     PFNGLVERTEXATTRIBPOINTERPROC     VertexAttribPointer;
     PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
     PFNGLUNIFORMMATRIX4FVPROC        UniformMatrix4fv;
+    PFNGLUNIFORMMATRIX3FVPROC        UniformMatrix3fv;
+    PFNGLUNIFORMMATRIX2FVPROC        UniformMatrix2fv;
     PFNGLUNIFORM4FVPROC              Uniform4fv;
     PFNGLUNIFORM4FPROC               Uniform4f;
+    PFNGLUNIFORM3FPROC               Uniform3f;
     PFNGLUNIFORM2FPROC               Uniform2f;
+    PFNGLUNIFORM1FPROC               Uniform1f;
     PFNGLUNIFORM1IPROC               Uniform1i;
 
     /* Program commands */
@@ -190,6 +202,11 @@ struct opengl_tex_converter_t
     /* Pointer to object gl, set by the caller */
     vlc_gl_t *gl;
 
+#ifdef HAVE_LIBPLACEBO
+    /* libplacebo context, created by the caller (optional) */
+    struct pl_context *pl_ctx;
+#endif
+
     /* Function pointers to OpenGL functions, set by the caller */
     const opengl_vtable_t *vt;
 
@@ -244,10 +261,16 @@ struct opengl_tex_converter_t
         GLint TexSize[PICTURE_PLANE_MAX]; /* for GL_TEXTURE_RECTANGLE */
         GLint Coefficients;
         GLint FillColor;
+        GLint *pl_vars; /* for pl_sh_res */
     } uloc;
     bool yuv_color;
     GLfloat yuv_coefficients[16];
 
+#ifdef HAVE_LIBPLACEBO
+    struct pl_shader *pl_sh;
+    const struct pl_shader_res *pl_sh_res;
+#endif
+
     /* Private context */
     void *priv;
 
diff --git a/modules/video_output/opengl/fragment_shaders.c b/modules/video_output/opengl/fragment_shaders.c
index 5de7b95359..eb897ef25a 100644
--- a/modules/video_output/opengl/fragment_shaders.c
+++ b/modules/video_output/opengl/fragment_shaders.c
@@ -25,6 +25,11 @@
 #include <assert.h>
 #include <stdlib.h>
 
+#ifdef HAVE_LIBPLACEBO
+#include <libplacebo/shaders.h>
+#include <libplacebo/shaders/colorspace.h>
+#endif
+
 #include <vlc_common.h>
 #include <vlc_memstream.h>
 #include "internal.h"
@@ -314,6 +319,15 @@ tc_base_fetch_locations(opengl_tex_converter_t *tc, GLuint program)
     tc->uloc.FillColor = tc->vt->GetUniformLocation(program, "FillColor");
     if (tc->uloc.FillColor == -1)
         return VLC_EGENERIC;
+
+#ifdef HAVE_LIBPLACEBO
+    const struct pl_shader_res *res = tc->pl_sh_res;
+    for (int i = 0; res && i < res->num_variables; i++) {
+        struct pl_shader_var sv = res->variables[i];
+        tc->uloc.pl_vars[i] = tc->vt->GetUniformLocation(program, sv.var.name);
+    }
+#endif
+
     return VLC_SUCCESS;
 }
 
@@ -338,6 +352,40 @@ tc_base_prepare_shader(const opengl_tex_converter_t *tc,
             tc->vt->Uniform2f(tc->uloc.TexSize[i], tex_width[i],
                                tex_height[i]);
     }
+
+#ifdef HAVE_LIBPLACEBO
+    const struct pl_shader_res *res = tc->pl_sh_res;
+    for (int i = 0; res && i < res->num_variables; i++) {
+        GLint loc = tc->uloc.pl_vars[i];
+        if (loc == -1) // uniform optimized out
+            continue;
+
+        struct pl_shader_var sv = res->variables[i];
+        struct ra_var var = sv.var;
+
+        // libplacebo doesn't need anything else anyway
+        if (var.type != RA_VAR_FLOAT)
+            continue;
+        if (var.dim_m > 1 && var.dim_m != var.dim_v)
+            continue;
+
+        const float *f = sv.data;
+        switch (var.dim_m) {
+        case 4: tc->vt->UniformMatrix4fv(loc, 1, GL_FALSE, f); break;
+        case 3: tc->vt->UniformMatrix3fv(loc, 1, GL_FALSE, f); break;
+        case 2: tc->vt->UniformMatrix2fv(loc, 1, GL_FALSE, f); break;
+
+        case 1:
+            switch (var.dim_v) {
+            case 1: tc->vt->Uniform1f(loc, f[0]); break;
+            case 2: tc->vt->Uniform2f(loc, f[0], f[1]); break;
+            case 3: tc->vt->Uniform3f(loc, f[0], f[1], f[2]); break;
+            case 4: tc->vt->Uniform4f(loc, f[0], f[1], f[2], f[3]); break;
+            }
+            break;
+        }
+    }
+#endif
 }
 
 static int
@@ -411,6 +459,53 @@ xyz12_shader_init(opengl_tex_converter_t *tc)
     return fragment_shader;
 }
 
+#ifdef HAVE_LIBPLACEBO
+static struct pl_color_space pl_color_space_from_video_format(video_format_t fmt)
+{
+    static enum pl_color_primaries primaries[COLOR_PRIMARIES_MAX+1] = {
+        [COLOR_PRIMARIES_UNDEF]     = PL_COLOR_PRIM_UNKNOWN,
+        [COLOR_PRIMARIES_BT601_525] = PL_COLOR_PRIM_BT_601_525,
+        [COLOR_PRIMARIES_BT601_625] = PL_COLOR_PRIM_BT_601_625,
+        [COLOR_PRIMARIES_BT709]     = PL_COLOR_PRIM_BT_709,
+        [COLOR_PRIMARIES_BT2020]    = PL_COLOR_PRIM_BT_2020,
+        [COLOR_PRIMARIES_DCI_P3]    = PL_COLOR_PRIM_DCI_P3,
+        [COLOR_PRIMARIES_BT470_M]   = PL_COLOR_PRIM_BT_470M,
+    };
+
+    static enum pl_color_transfer transfers[TRANSFER_FUNC_MAX+1] = {
+        [TRANSFER_FUNC_UNDEF]        = PL_COLOR_TRC_UNKNOWN,
+        [TRANSFER_FUNC_LINEAR]       = PL_COLOR_TRC_LINEAR,
+        [TRANSFER_FUNC_SRGB]         = PL_COLOR_TRC_SRGB,
+        [TRANSFER_FUNC_SMPTE_ST2084] = PL_COLOR_TRC_PQ,
+        [TRANSFER_FUNC_HLG]          = PL_COLOR_TRC_HLG,
+        // these are all designed to be displayed on BT.1886 displays, so this
+        // is the correct way to handle them in libplacebo
+        [TRANSFER_FUNC_BT470_BG]    = PL_COLOR_TRC_BT_1886,
+        [TRANSFER_FUNC_BT470_M]     = PL_COLOR_TRC_BT_1886,
+        [TRANSFER_FUNC_BT709]       = PL_COLOR_TRC_BT_1886,
+        [TRANSFER_FUNC_SMPTE_240]   = PL_COLOR_TRC_BT_1886,
+    };
+
+    // Derive the signal peak from the mastering metadata / content light
+    // metadata if available.
+    float sig_peak = 0.0;
+    if (fmt.mastering.max_luminance) {
+        sig_peak = fmt.mastering.max_luminance / PL_COLOR_REF_WHITE;
+    } else if (fmt.lighting.MaxCLL) {
+        sig_peak = fmt.lighting.MaxCLL / PL_COLOR_REF_WHITE;
+    }
+
+    return (struct pl_color_space) {
+        .primaries = primaries[fmt.primaries],
+        .transfer  = transfers[fmt.transfer],
+        .light     = fmt.transfer == TRANSFER_FUNC_HLG
+                        ? PL_COLOR_LIGHT_SCENE_HLG
+                        : PL_COLOR_LIGHT_DISPLAY,
+        .sig_peak  = sig_peak,
+    };
+}
+#endif
+
 GLuint
 opengl_fragment_shader_init_impl(opengl_tex_converter_t *tc, GLenum tex_target,
                                  vlc_fourcc_t chroma, video_color_space_t yuv_space)
@@ -462,6 +557,38 @@ opengl_fragment_shader_init_impl(opengl_tex_converter_t *tc, GLenum tex_target,
         ADDF("uniform %s Texture%u;"
              "varying vec2 TexCoord%u;", sampler, i, i);
 
+#ifdef HAVE_LIBPLACEBO
+    if (tc->pl_sh) {
+        struct pl_shader *sh = tc->pl_sh;
+        pl_shader_color_map(sh, &pl_color_map_default_params,
+                pl_color_space_from_video_format(tc->fmt),
+                pl_color_space_unknown, false);
+
+        const struct pl_shader_res *res = tc->pl_sh_res = pl_shader_finalize(sh);
+
+        FREENULL(tc->uloc.pl_vars);
+        tc->uloc.pl_vars = calloc(res->num_variables, sizeof(GLint));
+        for (int i = 0; i < res->num_variables; i++) {
+            struct pl_shader_var sv = res->variables[i];
+            ADDF("uniform %s %s;", ra_var_glsl_type_name(sv.var), sv.var.name);
+        }
+
+        // We can't handle these yet, but nothing we use requires them, either
+        assert(res->num_vertex_attribs == 0);
+        assert(res->num_descriptors == 0);
+
+        ADD(res->glsl);
+    }
+#else
+    if (tc->fmt.transfer == TRANSFER_FUNC_SMPTE_ST2084 ||
+        tc->fmt.primaries == COLOR_PRIMARIES_BT2020)
+    {
+        // no warning for HLG because it's more or less backwards-compatible
+        msg_Warn(tc->gl, "VLC needs to be built with support for libplacebo "
+                 "in order to display wide gamut or HDR signals correctly.");
+    }
+#endif
+
     if (tex_target == GL_TEXTURE_RECTANGLE)
     {
         for (unsigned i = 0; i < tc->tex_count; ++i)
@@ -532,6 +659,15 @@ opengl_fragment_shader_init_impl(opengl_tex_converter_t *tc, GLenum tex_target,
             ADDF("result = color%u + result;", color_idx);
     }
 
+#ifdef HAVE_LIBPLACEBO
+    if (tc->pl_sh_res) {
+        const struct pl_shader_res *res = tc->pl_sh_res;
+        assert(res->input  == PL_SHADER_SIG_COLOR);
+        assert(res->output == PL_SHADER_SIG_COLOR);
+        ADDF("result = %s(result);", res->name);
+    }
+#endif
+
     ADD("gl_FragColor = result * FillColor;"
         "}");
 
diff --git a/modules/video_output/opengl/vout_helper.c b/modules/video_output/opengl/vout_helper.c
index e2491546f1..556a9be728 100644
--- a/modules/video_output/opengl/vout_helper.c
+++ b/modules/video_output/opengl/vout_helper.c
@@ -566,7 +566,27 @@ opengl_deinit_program(vout_display_opengl_t *vgl, struct prgm *prgm)
     vlc_object_release(tc);
     if (prgm->id != 0)
         vgl->vt.DeleteProgram(prgm->id);
+
+#ifdef HAVE_LIBPLACEBO
+    FREENULL(tc->uloc.pl_vars);
+    pl_context_destroy(&tc->pl_ctx);
+#endif
+}
+
+#ifdef HAVE_LIBPLACEBO
+static void
+log_cb(void *priv, enum pl_log_level level, const char *msg)
+{
+    opengl_tex_converter_t *tc = priv;
+    switch (level) {
+    case PL_LOG_FATAL: // fall through
+    case PL_LOG_ERR:  msg_Err(tc->gl, "%s", msg); break;
+    case PL_LOG_WARN: msg_Warn(tc->gl,"%s", msg); break;
+    case PL_LOG_INFO: msg_Info(tc->gl,"%s", msg); break;
+    default: break;
+    }
 }
+#endif
 
 static int
 opengl_init_program(vout_display_opengl_t *vgl, struct prgm *prgm,
@@ -592,6 +612,17 @@ opengl_init_program(vout_display_opengl_t *vgl, struct prgm *prgm,
 #endif
     tc->fmt = *fmt;
 
+#ifdef HAVE_LIBPLACEBO
+    // create the main libplacebo context
+    tc->pl_ctx = pl_context_create(PL_API_VER, &(struct pl_context_params) {
+        .log_cb    = log_cb,
+        .log_priv  = tc,
+        .log_level = PL_LOG_INFO,
+    });
+    if (tc->pl_ctx)
+        tc->pl_sh = pl_shader_alloc(tc->pl_ctx, NULL, 0);
+#endif
+
     int ret;
     if (subpics)
     {
@@ -758,9 +789,13 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
     GET_PROC_ADDR(VertexAttribPointer);
     GET_PROC_ADDR(EnableVertexAttribArray);
     GET_PROC_ADDR(UniformMatrix4fv);
+    GET_PROC_ADDR(UniformMatrix3fv);
+    GET_PROC_ADDR(UniformMatrix2fv);
     GET_PROC_ADDR(Uniform4fv);
     GET_PROC_ADDR(Uniform4f);
+    GET_PROC_ADDR(Uniform3f);
     GET_PROC_ADDR(Uniform2f);
+    GET_PROC_ADDR(Uniform1f);
     GET_PROC_ADDR(Uniform1i);
 
     GET_PROC_ADDR(CreateProgram);
-- 
2.14.3



More information about the vlc-devel mailing list