[vlc-devel] [PATCH 03/18] libvlc: make the OpenGL host tell the rendering colorimetry it's using

Steve Lhomme robux4 at ycbcr.xyz
Tue Feb 4 16:25:58 CET 2020


We should adapt the tone mapping between the source and the output accordingly.

For now only basic sRGB rendering is supported.
---
 doc/libvlc/QtGL/qtvlcwidget.cpp   |  9 ++++++++-
 doc/libvlc/sdl_opengl_player.cpp  |  9 ++++++++-
 include/vlc/libvlc_media_player.h | 28 ++++++++++++++++------------
 modules/video_output/vgl.c        | 14 +++++++++-----
 4 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/doc/libvlc/QtGL/qtvlcwidget.cpp b/doc/libvlc/QtGL/qtvlcwidget.cpp
index 7c1eee7a43b..91ed826e43b 100644
--- a/doc/libvlc/QtGL/qtvlcwidget.cpp
+++ b/doc/libvlc/QtGL/qtvlcwidget.cpp
@@ -38,7 +38,8 @@ public:
     }
 
     /// this callback will create the surfaces and FBO used by VLC to perform its rendering
-    static void resizeRenderTextures(void* data, unsigned width, unsigned height)
+    static void resizeRenderTextures(void* data, unsigned width, unsigned height,
+                                     libvlc_video_output_cfg_t *render_cfg)
     {
        VLCVideo* that = static_cast<VLCVideo*>(data);
         if (width != that->m_width || height != that->m_height)
@@ -52,6 +53,12 @@ public:
         that->m_height = height;
 
         that->mBuffers[that->m_idx_render]->bind();
+
+        render_cfg->surface_format = GL_RGBA;
+        render_cfg->full_range = true;
+        render_cfg->colorspace = libvlc_video_colorspace_BT709;
+        render_cfg->primaries  = libvlc_video_primaries_BT709;
+        render_cfg->transfer   = libvlc_video_transfer_func_SRGB;
     }
 
     // This callback is called during initialisation.
diff --git a/doc/libvlc/sdl_opengl_player.cpp b/doc/libvlc/sdl_opengl_player.cpp
index 903f0fefb3c..386e78e8e4c 100644
--- a/doc/libvlc/sdl_opengl_player.cpp
+++ b/doc/libvlc/sdl_opengl_player.cpp
@@ -116,7 +116,8 @@ public:
     }
 
     /// this callback will create the surfaces and FBO used by VLC to perform its rendering
-    static void resize(void* data, unsigned width, unsigned height)
+    static void resize(void* data, unsigned width, unsigned height,
+                       libvlc_video_output_cfg_t *render_cfg)
     {
         VLCVideo* that = static_cast<VLCVideo*>(data);
         if (width != that->m_width || height != that->m_height)
@@ -148,6 +149,12 @@ public:
         that->m_height = height;
 
         glBindFramebuffer(GL_FRAMEBUFFER, that->m_fbo[that->m_idx_render]);
+
+        render_cfg->surface_format = GL_RGBA;
+        render_cfg->full_range = true;
+        render_cfg->colorspace = libvlc_video_colorspace_BT709;
+        render_cfg->primaries  = libvlc_video_primaries_BT709;
+        render_cfg->transfer   = libvlc_video_transfer_func_SRGB;
     }
 
     // This callback is called during initialisation.
diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index 70970f8c104..940059f044d 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -521,15 +521,29 @@ typedef bool (*libvlc_video_setup_cb)(void* opaque);
  */
 typedef void (*libvlc_video_cleanup_cb)(void* opaque);
 
+typedef struct
+{
+    int surface_format;  /** the rendering DXGI_FORMAT for \ref libvlc_video_direct3d_engine_d3d11,
+                          D3DFORMAT for \ref libvlc_video_direct3d_engine_d3d9,
+                          GL_RGBA or GL_RGB for \ref libvlc_video_engine_opengl and
+                          for \ref libvlc_video_engine_gles2 */
+    bool full_range;          /** video is full range or studio/limited range */
+    libvlc_video_color_space_t colorspace;              /** video color space */
+    libvlc_video_color_primaries_t primaries;       /** video color primaries */
+    libvlc_video_transfer_func_t transfer;        /** video transfer function */
+} libvlc_video_output_cfg_t;
+
 /**
  * Callback prototype called on video size changes
  *
  * \param opaque private pointer passed to the @a libvlc_video_set_output_callbacks() [IN]
  * \param width video width in pixel [IN]
  * \param height video height in pixel [IN]
+ * \param output configuration describing with how the rendering is setup [OUT]
  * \version LibVLC 4.0.0 or later
  */
-typedef void (*libvlc_video_update_output_cb)(void* opaque, unsigned width, unsigned height);
+typedef void (*libvlc_video_update_output_cb)(void* opaque, unsigned width, unsigned height,
+                                              libvlc_video_output_cfg_t *output );
 
 
 /**
@@ -612,7 +626,7 @@ typedef enum libvlc_video_engine_t {
  * \param engine the GPU engine to use
  * \param setup_cb callback called to initialize user data
  * \param cleanup_cb callback called to clean up user data
- * \param update_output_cb callback called to get the size of the video
+ * \param update_output_cb callback to get the rendering format of the host (cannot be NULL)
  * \param swap_cb callback called after rendering a video frame (cannot be NULL)
  * \param makeCurrent_cb callback called to enter/leave the opengl context (cannot be NULL for \ref libvlc_video_engine_opengl and for \ref libvlc_video_engine_gles2)
  * \param getProcAddress_cb opengl function loading callback (cannot be NULL for \ref libvlc_video_engine_opengl and for \ref libvlc_video_engine_gles2)
@@ -714,16 +728,6 @@ typedef struct
     void *device;   /** device used for rendering, IDirect3DDevice9* for D3D9 */
 } libvlc_video_direct3d_cfg_t;
 
-typedef struct
-{
-    int surface_format;  /** the rendering DXGI_FORMAT for \ref libvlc_video_direct3d_engine_d3d11,
-                          D3DFORMAT for \ref libvlc_video_direct3d_engine_d3d9 */
-    bool full_range;          /** video is full range or studio/limited range */
-    libvlc_video_color_space_t colorspace;              /** video color space */
-    libvlc_video_color_primaries_t primaries;       /** video color primaries */
-    libvlc_video_transfer_func_t transfer;        /** video transfer function */
-} libvlc_video_output_cfg_t;
-
 /** Update the rendering output setup.
  *
  * \param opaque private pointer set on the opaque parameter of @a libvlc_video_direct3d_device_setup_cb() [IN]
diff --git a/modules/video_output/vgl.c b/modules/video_output/vgl.c
index 9f550e53c13..22740aa6016 100644
--- a/modules/video_output/vgl.c
+++ b/modules/video_output/vgl.c
@@ -27,6 +27,7 @@
 #include <vlc_plugin.h>
 #include <vlc_vout_display.h>
 #include <vlc_opengl.h>
+#include "opengl/gl_common.h"
 
 #include <vlc/libvlc.h>
 #include <vlc/libvlc_picture.h>
@@ -80,12 +81,15 @@ static void Resize(vlc_gl_t * gl, unsigned w, unsigned h)
     if( sys->width == w && sys->height == h )
         return;
 
-    if( !sys->resizeCb )
-        return;
-
     MakeCurrent(gl);
-    sys->resizeCb(sys->opaque, w, h);
+    libvlc_video_output_cfg_t render_cfg;
+    sys->resizeCb(sys->opaque, h, w, &render_cfg);
     ReleaseCurrent(gl);
+    assert(render_cfg.surface_format == GL_RGBA);
+    assert(render_cfg.full_range == true);
+    assert(render_cfg.colorspace == libvlc_video_colorspace_BT709);
+    assert(render_cfg.primaries  == libvlc_video_primaries_BT709);
+    assert(render_cfg.transfer   == libvlc_video_transfer_func_SRGB);
     sys->width = w;
     sys->height = h;
 }
@@ -119,7 +123,7 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height)
     sys->opaque = var_InheritAddress(gl, "vout-cb-opaque");
     sys->setupCb = var_InheritAddress(gl, "vout-cb-setup");
     sys->cleanupCb = var_InheritAddress(gl, "vout-cb-cleanup");
-    sys->resizeCb = var_InheritAddress(gl, "vout-cb-update-output");
+    SET_CALLBACK_ADDR(sys->resizeCb, "vout-cb-update-output");
     SET_CALLBACK_ADDR(sys->swapCb, "vout-cb-swap");
     SET_CALLBACK_ADDR(sys->makeCurrentCb, "vout-cb-make-current");
     SET_CALLBACK_ADDR(sys->getProcAddressCb, "vout-cb-get-proc-address");
-- 
2.17.1



More information about the vlc-devel mailing list