[vlc-devel] [PATCH v2 13/22] opengl: add "draw" filter

Romain Vimont rom1v at videolabs.io
Wed Jul 1 12:30:14 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   |   2 +
 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, 228 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 8ddb9d121c..6f3b941e3e 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"
 
@@ -60,6 +61,7 @@ vlc_module_begin()
     add_opengl_param_gl_filter()
 
     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 9b2ba48004..5ef2763c5c 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"
 
@@ -80,6 +81,7 @@ vlc_module_begin ()
     add_opengl_param_gl_filter()
 
     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 ac85c941f0..b655937cca 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"
 
@@ -82,6 +83,7 @@ vlc_module_begin ()
     add_opengl_param_gl_filter()
 
     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 cce7f6dbfb..ce6509529b 100644
--- a/modules/video_output/opengl/Makefile.am
+++ b/modules/video_output/opengl/Makefile.am
@@ -1,6 +1,8 @@
 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.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 1807d2f66f..9b57246efc 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 */
@@ -71,6 +72,7 @@ vlc_module_begin ()
     add_opengl_param_gl_filter()
 
     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 2d46c5135e..f69dfba7e0 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"
 
@@ -57,6 +58,7 @@ vlc_module_begin()
     add_opengl_param_gl_filter()
 
     add_opengl_submodule_renderer()
+    add_opengl_submodule_draw()
 vlc_module_end()
 
 /*****************************************************************************
-- 
2.27.0



More information about the vlc-devel mailing list