[vlc-devel] [PATCH v2 2/6] opengl: add CreateOffscreen API

Romain Vimont rom1v at videolabs.io
Fri Feb 26 17:10:32 UTC 2021


From: Alexandre Janniaux <ajanni at videolabs.io>

This will allow offscreen OpenGL implementations, which will produce
picture_t.

Co-authored-by: Romain Vimont <rom1v at videolabs.io>
---
 include/vlc_opengl.h      | 26 ++++++++++++++++++-
 src/libvlccore.sym        |  1 +
 src/video_output/opengl.c | 54 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/include/vlc_opengl.h b/include/vlc_opengl.h
index a99c6ced64..798558e72a 100644
--- a/include/vlc_opengl.h
+++ b/include/vlc_opengl.h
@@ -24,6 +24,8 @@
 #ifndef VLC_GL_H
 #define VLC_GL_H 1
 
+#include <vlc_es.h>
+
 /**
  * \file
  * This file defines GL structures and functions.
@@ -37,6 +39,8 @@ struct vout_display_cfg;
  * A VLC GL context (and its underlying surface)
  */
 typedef struct vlc_gl_t vlc_gl_t;
+struct vlc_decoder_device;
+struct vlc_video_context;
 
 enum vlc_gl_api_type {
     VLC_OPENGL,
@@ -47,14 +51,24 @@ struct vlc_gl_t
 {
     struct vlc_object_t obj;
 
+    struct vlc_decoder_device *device;
     struct vout_window_t *surface;
     module_t *module;
     void *sys;
 
+    vlc_fourcc_t offscreen_chroma_out;
+    struct vlc_video_context *offscreen_vctx_out;
+    /* Flag to indicate if the OpenGL implementation produces upside-down
+     * pictures */
+    bool offscreen_vflip;
+
     int  (*make_current)(vlc_gl_t *);
     void (*release_current)(vlc_gl_t *);
     void (*resize)(vlc_gl_t *, unsigned, unsigned);
-    void (*swap)(vlc_gl_t *);
+    union {
+        void (*swap)(vlc_gl_t *);
+        picture_t *(*swap_offscreen)(vlc_gl_t *);
+    };
     void*(*get_proc_address)(vlc_gl_t *, const char *);
     void (*destroy)(vlc_gl_t *);
 
@@ -99,6 +113,11 @@ struct vlc_gl_t
  */
 VLC_API vlc_gl_t *vlc_gl_Create(const struct vout_display_cfg *cfg,
                                 unsigned flags, const char *name) VLC_USED;
+VLC_API vlc_gl_t *vlc_gl_CreateOffscreen(vlc_object_t *parent,
+                                         struct vlc_decoder_device *device,
+                                         unsigned width, unsigned height,
+                                         unsigned flags, const char *name);
+
 VLC_API void vlc_gl_Release(vlc_gl_t *);
 VLC_API void vlc_gl_Hold(vlc_gl_t *);
 
@@ -123,6 +142,11 @@ static inline void vlc_gl_Swap(vlc_gl_t *gl)
     gl->swap(gl);
 }
 
+static inline picture_t *vlc_gl_SwapOffscreen(vlc_gl_t *gl)
+{
+    return gl->swap_offscreen(gl);
+}
+
 static inline void *vlc_gl_GetProcAddress(vlc_gl_t *gl, const char *name)
 {
     return gl->get_proc_address(gl, name);
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 71267d5dfc..0c130543e5 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -695,6 +695,7 @@ vlc_queue_Enqueue
 vlc_queue_Dequeue
 vlc_queue_DequeueAll
 vlc_gl_Create
+vlc_gl_CreateOffscreen
 vlc_gl_Release
 vlc_gl_Hold
 vlc_gl_surface_Create
diff --git a/src/video_output/opengl.c b/src/video_output/opengl.c
index 8355c16135..cf0db8567f 100644
--- a/src/video_output/opengl.c
+++ b/src/video_output/opengl.c
@@ -28,6 +28,7 @@
 #include <vlc_common.h>
 #include <vlc_atomic.h>
 #include <vlc_opengl.h>
+#include <vlc_codec.h>
 #include <vlc_vout_display.h>
 #include "libvlc.h"
 #include <vlc_modules.h>
@@ -96,6 +97,59 @@ vlc_gl_t *vlc_gl_Create(const struct vout_display_cfg *restrict cfg,
     return &glpriv->gl;
 }
 
+vlc_gl_t *vlc_gl_CreateOffscreen(vlc_object_t *parent,
+                                 struct vlc_decoder_device *device,
+                                 unsigned width, unsigned height,
+                                 unsigned flags, const char *name)
+{
+    struct vlc_gl_priv_t *glpriv;
+    const char *type;
+
+    switch (flags /*& VLC_OPENGL_API_MASK*/)
+    {
+        case VLC_OPENGL:
+            type = "opengl offscreen";
+            break;
+        case VLC_OPENGL_ES2:
+            type = "opengl es2 offscreen";
+            break;
+        default:
+            return NULL;
+    }
+
+    glpriv = vlc_custom_create(parent, sizeof (*glpriv), "gl");
+    if (unlikely(glpriv == NULL))
+        return NULL;
+
+    vlc_gl_t *gl = &glpriv->gl;
+
+    gl->offscreen_chroma_out = VLC_CODEC_UNKNOWN;
+    gl->offscreen_vflip = false;
+    gl->offscreen_vctx_out = NULL;
+
+    gl->surface = NULL;
+    gl->device = device ? vlc_decoder_device_Hold(device) : NULL;
+    gl->module = vlc_module_load(gl, type, name, true, vlc_gl_start, gl, width,
+                                 height);
+    if (gl->module == NULL)
+    {
+        vlc_object_delete(gl);
+        return NULL;
+    }
+
+    /* The implementation must initialize the output chroma */
+    assert(gl->offscreen_chroma_out != VLC_CODEC_UNKNOWN);
+
+    vlc_atomic_rc_init(&glpriv->rc);
+
+    assert(gl->make_current);
+    assert(gl->release_current);
+    assert(gl->swap_offscreen);
+    assert(gl->get_proc_address);
+
+    return &glpriv->gl;
+}
+
 void vlc_gl_Hold(vlc_gl_t *gl)
 {
     struct vlc_gl_priv_t *glpriv = (struct vlc_gl_priv_t *)gl;
-- 
2.30.1



More information about the vlc-devel mailing list