[vlc-devel] [PATCH v4 12/20] opengl: add "draw" filter

Romain Vimont rom1v at videolabs.io
Tue Jul 7 12:33:55 CEST 2020


Implement a filter which just draws the input picture to the output.

This will be useful for "blend" filters which needs something to blend
with, even if they are used as the first filter.

Co-authored-by: Alexandre Janniaux <ajanni at videolabs.io>
---
 modules/video_output/caopengllayer.m      |   2 +
 modules/video_output/ios.m                |   2 +
 modules/video_output/macosx.m             |   2 +
 modules/video_output/opengl/Makefile.am   |   3 +
 modules/video_output/opengl/display.c     |   2 +
 modules/video_output/opengl/filter_draw.c | 180 ++++++++++++++++++++++
 modules/video_output/opengl/filter_draw.h |  36 +++++
 modules/video_output/win32/glwin32.c      |   2 +
 8 files changed, 229 insertions(+)
 create mode 100644 modules/video_output/opengl/filter_draw.c
 create mode 100644 modules/video_output/opengl/filter_draw.h

diff --git a/modules/video_output/caopengllayer.m b/modules/video_output/caopengllayer.m
index 16e8de1c36..7609f1aaf6 100644
--- a/modules/video_output/caopengllayer.m
+++ b/modules/video_output/caopengllayer.m
@@ -40,6 +40,7 @@
 #import <OpenGL/OpenGL.h>
 #import <dlfcn.h>               /* dlsym */
 
+#include "opengl/filter_draw.h"
 #include "opengl/renderer.h"
 #include "opengl/vout_helper.h"
 
@@ -59,6 +60,7 @@ vlc_module_begin()
     set_callback_display(Open, 0)
 
     add_opengl_submodule_renderer()
+    add_opengl_submodule_draw()
 vlc_module_end()
 
 static void PictureRender   (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture,
diff --git a/modules/video_output/ios.m b/modules/video_output/ios.m
index 637a140146..ed87cd6045 100644
--- a/modules/video_output/ios.m
+++ b/modules/video_output/ios.m
@@ -45,6 +45,7 @@
 #import <vlc_vout_display.h>
 #import <vlc_opengl.h>
 #import <vlc_dialog.h>
+#import "opengl/filter_draw.h"
 #import "opengl/renderer.h"
 #import "opengl/vout_helper.h"
 
@@ -79,6 +80,7 @@ vlc_module_begin ()
     add_glopts()
 
     add_opengl_submodule_renderer()
+    add_opengl_submodule_draw()
 vlc_module_end ()
 
 @interface VLCOpenGLES2VideoView : UIView {
diff --git a/modules/video_output/macosx.m b/modules/video_output/macosx.m
index a714b59f6e..d5cd97b0fc 100644
--- a/modules/video_output/macosx.m
+++ b/modules/video_output/macosx.m
@@ -46,6 +46,7 @@
 #include <vlc_vout_display.h>
 #include <vlc_opengl.h>
 #include <vlc_dialog.h>
+#include "opengl/filter_draw.h"
 #include "opengl/renderer.h"
 #include "opengl/vout_helper.h"
 
@@ -81,6 +82,7 @@ vlc_module_begin ()
     add_glopts ()
 
     add_opengl_submodule_renderer()
+    add_opengl_submodule_draw()
 vlc_module_end ()
 
 /**
diff --git a/modules/video_output/opengl/Makefile.am b/modules/video_output/opengl/Makefile.am
index 7cce4752e9..9e08ec09fc 100644
--- a/modules/video_output/opengl/Makefile.am
+++ b/modules/video_output/opengl/Makefile.am
@@ -1,6 +1,9 @@
 OPENGL_COMMONSOURCES = video_output/opengl/vout_helper.c \
        video_output/opengl/filter.c \
        video_output/opengl/filter.h \
+       video_output/opengl/filter_draw.c \
+       video_output/opengl/filter_draw.h \
+       video_output/opengl/filter.h \
        video_output/opengl/filter_priv.h \
        video_output/opengl/filters.c \
        video_output/opengl/filters.h \
diff --git a/modules/video_output/opengl/display.c b/modules/video_output/opengl/display.c
index b7f6b44f15..e7f0cc41da 100644
--- a/modules/video_output/opengl/display.c
+++ b/modules/video_output/opengl/display.c
@@ -33,6 +33,7 @@
 #include <vlc_opengl.h>
 #include "vout_helper.h"
 
+#include "filter_draw.h"
 #include "renderer.h"
 
 /* Plugin callbacks */
@@ -70,6 +71,7 @@ vlc_module_begin ()
     add_glopts ()
 
     add_opengl_submodule_renderer()
+    add_opengl_submodule_draw()
 vlc_module_end ()
 
 struct vout_display_sys_t
diff --git a/modules/video_output/opengl/filter_draw.c b/modules/video_output/opengl/filter_draw.c
new file mode 100644
index 0000000000..9f92b074df
--- /dev/null
+++ b/modules/video_output/opengl/filter_draw.c
@@ -0,0 +1,180 @@
+/*****************************************************************************
+ * filter_draw.c
+ *****************************************************************************
+ * Copyright (C) 2020 VLC authors and VideoLAN
+ * Copyright (C) 2020 Videolabs
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_modules.h>
+#include <vlc_opengl.h>
+
+#include "filter_draw.h"
+
+#include "filter.h"
+#include "gl_api.h"
+#include "gl_common.h"
+#include "gl_util.h"
+
+struct sys {
+    GLuint program_id;
+    struct vlc_gl_sampler *sampler;
+
+    GLuint vbo;
+
+    struct {
+        GLint vertex_pos;
+    } loc;
+};
+
+static int
+Draw(struct vlc_gl_filter *filter)
+{
+    struct sys *sys = filter->sys;
+
+    const opengl_vtable_t *vt = &filter->api->vt;
+
+    vt->UseProgram(sys->program_id);
+
+    vlc_gl_sampler_Load(sys->sampler);
+
+    vt->BindBuffer(GL_ARRAY_BUFFER, sys->vbo);
+    vt->EnableVertexAttribArray(sys->loc.vertex_pos);
+    vt->VertexAttribPointer(sys->loc.vertex_pos, 2, GL_FLOAT, GL_FALSE, 0,
+                            (const void *) 0);
+
+    vt->Clear(GL_COLOR_BUFFER_BIT);
+    vt->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+    return VLC_SUCCESS;
+}
+
+static void
+Close(struct vlc_gl_filter *filter)
+{
+    struct sys *sys = filter->sys;
+
+    const opengl_vtable_t *vt = &filter->api->vt;
+    vt->DeleteProgram(sys->program_id);
+    vt->DeleteBuffers(1, &sys->vbo);
+
+    free(sys);
+}
+
+int
+vlc_gl_filter_draw_Open(struct vlc_gl_filter *filter,
+                        const config_chain_t *config,
+                        struct vlc_gl_tex_size *size_out,
+                        struct vlc_gl_sampler *sampler)
+{
+    (void) config;
+    (void) size_out;
+
+    struct sys *sys = filter->sys = malloc(sizeof(*sys));
+    if (!sys)
+        return VLC_EGENERIC;
+
+    sys->sampler = sampler;
+
+#ifdef USE_OPENGL_ES2
+# define SHADER_VERSION "#version 100\n"
+# define FRAGMENT_SHADER_PRECISION "precision highp float;\n"
+#else
+# define SHADER_VERSION "#version 120\n"
+# define FRAGMENT_SHADER_PRECISION
+#endif
+
+    static const char *const VERTEX_SHADER =
+        SHADER_VERSION
+        "attribute vec2 vertex_pos;\n"
+        "varying vec2 tex_coords;\n"
+        "void main() {\n"
+        "  gl_Position = vec4(vertex_pos, 0.0, 1.0);\n"
+        "  tex_coords = vec2((vertex_pos.x + 1.0) / 2.0,\n"
+        "                    (vertex_pos.y + 1.0) / 2.0);\n"
+        "}\n";
+
+    static const char *const FRAGMENT_SHADER_TEMPLATE =
+        SHADER_VERSION
+        "%s\n" /* extensions */
+        FRAGMENT_SHADER_PRECISION
+        "%s\n" /* vlc_texture definition */
+        "varying vec2 tex_coords;\n"
+        "void main() {\n"
+        "  gl_FragColor = vlc_texture(tex_coords);\n"
+        "}\n";
+
+    const char *extensions = sampler->shader.extensions
+                           ? sampler->shader.extensions : "";
+
+    char *fragment_shader;
+    int ret = asprintf(&fragment_shader, FRAGMENT_SHADER_TEMPLATE, extensions,
+                       sampler->shader.body);
+    if (ret < 0)
+        goto error;
+
+    const opengl_vtable_t *vt = &filter->api->vt;
+
+    GLuint program_id =
+        vlc_gl_BuildProgram(VLC_OBJECT(filter), vt,
+                            1, (const char **) &VERTEX_SHADER,
+                            1, (const char **) &fragment_shader);
+
+    free(fragment_shader);
+    if (!program_id)
+        goto error;
+
+    vlc_gl_sampler_FetchLocations(sampler, program_id);
+
+    sys->program_id = program_id;
+
+    sys->loc.vertex_pos = vt->GetAttribLocation(program_id, "vertex_pos");
+    if (sys->loc.vertex_pos == -1)
+        goto error;
+
+    vt->GenBuffers(1, &sys->vbo);
+
+    static const GLfloat vertex_pos[] = {
+        -1,  1,
+        -1, -1,
+         1,  1,
+         1, -1,
+    };
+
+    vt->BindBuffer(GL_ARRAY_BUFFER, sys->vbo);
+    vt->BufferData(GL_ARRAY_BUFFER, sizeof(vertex_pos), vertex_pos,
+                   GL_STATIC_DRAW);
+
+    vt->BindBuffer(GL_ARRAY_BUFFER, 0);
+
+    static const struct vlc_gl_filter_ops ops = {
+        .draw = Draw,
+        .close = Close,
+    };
+    filter->ops = &ops;
+
+    return VLC_SUCCESS;
+
+error:
+    free(sys);
+    return VLC_EGENERIC;
+}
diff --git a/modules/video_output/opengl/filter_draw.h b/modules/video_output/opengl/filter_draw.h
new file mode 100644
index 0000000000..d458eb9141
--- /dev/null
+++ b/modules/video_output/opengl/filter_draw.h
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * filter_draw.h
+ *****************************************************************************
+ * Copyright (C) 2020 VLC authors and VideoLAN
+ * Copyright (C) 2020 Videolabs
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_GL_FILTER_DRAW_H
+#define VLC_GL_FILTER_DRAW_H
+
+#include "filter.h"
+
+#define add_opengl_submodule_draw() \
+    add_submodule() \
+    add_shortcut("draw") \
+    set_shortname("draw") \
+    set_capability("opengl filter", 0) \
+    set_callback(vlc_gl_filter_draw_Open)
+
+vlc_gl_filter_open_fn vlc_gl_filter_draw_Open;
+
+#endif
diff --git a/modules/video_output/win32/glwin32.c b/modules/video_output/win32/glwin32.c
index c09f543d84..6170ecaa80 100644
--- a/modules/video_output/win32/glwin32.c
+++ b/modules/video_output/win32/glwin32.c
@@ -34,6 +34,7 @@
 #include <versionhelpers.h>
 
 #define GLEW_STATIC
+#include "../opengl/filter_draw.h"
 #include "../opengl/renderer.h"
 #include "../opengl/vout_helper.h"
 
@@ -56,6 +57,7 @@ vlc_module_begin()
     add_glopts()
 
     add_opengl_submodule_renderer()
+    add_opengl_submodule_draw()
 vlc_module_end()
 
 /*****************************************************************************
-- 
2.27.0



More information about the vlc-devel mailing list