[vlc-devel] [PATCH v3 03/22] opengl: add filters chain

Romain Vimont rom1v at videolabs.io
Mon Jul 6 12:46:56 CEST 2020


Create a component to manage the chain of filters.

For now, the renderer is the only filter.

Co-authored-by: Alexandre Janniaux <ajanni at videolabs.io>
---
 modules/video_output/opengl/Makefile.am   |  2 +
 modules/video_output/opengl/filter_priv.h |  3 +
 modules/video_output/opengl/filters.c     | 75 +++++++++++++++++++++++
 modules/video_output/opengl/filters.h     | 65 ++++++++++++++++++++
 modules/video_output/opengl/vout_helper.c | 26 ++++++--
 5 files changed, 167 insertions(+), 4 deletions(-)
 create mode 100644 modules/video_output/opengl/filters.c
 create mode 100644 modules/video_output/opengl/filters.h

diff --git a/modules/video_output/opengl/Makefile.am b/modules/video_output/opengl/Makefile.am
index 6f4141fb58..7cce4752e9 100644
--- a/modules/video_output/opengl/Makefile.am
+++ b/modules/video_output/opengl/Makefile.am
@@ -2,6 +2,8 @@ OPENGL_COMMONSOURCES = video_output/opengl/vout_helper.c \
        video_output/opengl/filter.c \
        video_output/opengl/filter.h \
        video_output/opengl/filter_priv.h \
+       video_output/opengl/filters.c \
+       video_output/opengl/filters.h \
        video_output/opengl/gl_api.c \
        video_output/opengl/gl_api.h \
        video_output/opengl/gl_common.h \
diff --git a/modules/video_output/opengl/filter_priv.h b/modules/video_output/opengl/filter_priv.h
index ffc54e0ca8..a1fe0b53b7 100644
--- a/modules/video_output/opengl/filter_priv.h
+++ b/modules/video_output/opengl/filter_priv.h
@@ -23,11 +23,14 @@
 #define VLC_GL_FILTER_PRIV_H
 
 #include <vlc_common.h>
+#include <vlc_list.h>
 
 #include "filter.h"
 
 struct vlc_gl_filter_priv {
     struct vlc_gl_filter filter;
+
+    struct vlc_list node; /**< node of vlc_gl_filters.list */
 };
 
 #define vlc_gl_filter_PRIV(filter) \
diff --git a/modules/video_output/opengl/filters.c b/modules/video_output/opengl/filters.c
new file mode 100644
index 0000000000..99a325f3b8
--- /dev/null
+++ b/modules/video_output/opengl/filters.c
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * filters.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 "filters.h"
+
+#include <vlc_common.h>
+#include <vlc_list.h>
+
+#include "filter_priv.h"
+
+struct vlc_gl_filters {
+    struct vlc_list list; /**< list of vlc_gl_filter.node */
+};
+
+struct vlc_gl_filters *
+vlc_gl_filters_New(void)
+{
+    struct vlc_gl_filters *filters = malloc(sizeof(*filters));
+    if (!filters)
+        return NULL;
+
+    vlc_list_init(&filters->list);
+    return filters;
+}
+
+void
+vlc_gl_filters_Delete(struct vlc_gl_filters *filters)
+{
+    free(filters);
+}
+
+void
+vlc_gl_filters_Append(struct vlc_gl_filters *filters,
+                      struct vlc_gl_filter *filter)
+{
+    struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
+    vlc_list_append(&priv->node, &filters->list);
+}
+
+int
+vlc_gl_filters_Draw(struct vlc_gl_filters *filters)
+{
+    struct vlc_gl_filter_priv *priv;
+    vlc_list_foreach(priv, &filters->list, node)
+    {
+        struct vlc_gl_filter *filter = &priv->filter;
+        int ret = filter->ops->draw(filter);
+        if (ret != VLC_SUCCESS)
+            return ret;
+    }
+
+    return VLC_SUCCESS;
+}
diff --git a/modules/video_output/opengl/filters.h b/modules/video_output/opengl/filters.h
new file mode 100644
index 0000000000..abe1b344a7
--- /dev/null
+++ b/modules/video_output/opengl/filters.h
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * filters.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_FILTERS_H
+#define VLC_GL_FILTERS_H
+
+#include <vlc_common.h>
+#include <vlc_list.h>
+
+#include "filter.h"
+
+struct vlc_gl_filters;
+
+/**
+ * Create a new OpenGL filter chain
+ */
+struct vlc_gl_filters *
+vlc_gl_filters_New(void);
+
+/**
+ * Delete the OpenGL filter chain
+ *
+ * \param filters the filter chain
+ */
+void
+vlc_gl_filters_Delete(struct vlc_gl_filters *filters);
+
+/**
+ * Append a filter to the filter chain
+ *
+ * \param filters the filter chain
+ * \param filter the filter to append
+ */
+void
+vlc_gl_filters_Append(struct vlc_gl_filters *filters,
+                      struct vlc_gl_filter *filter);
+
+/**
+ * Draw by executing all the filters
+ *
+ * \param filters the filter chain
+ * \return VLC_SUCCESS on success, another value on error
+ */
+int
+vlc_gl_filters_Draw(struct vlc_gl_filters *filters);
+
+#endif
diff --git a/modules/video_output/opengl/vout_helper.c b/modules/video_output/opengl/vout_helper.c
index 581df6b319..bf990a67d9 100644
--- a/modules/video_output/opengl/vout_helper.c
+++ b/modules/video_output/opengl/vout_helper.c
@@ -33,12 +33,14 @@
 #include <math.h>
 
 #include <vlc_common.h>
+#include <vlc_list.h>
 #include <vlc_subpicture.h>
 #include <vlc_opengl.h>
 #include <vlc_modules.h>
 #include <vlc_vout.h>
 #include <vlc_viewpoint.h>
 
+#include "filters.h"
 #include "gl_api.h"
 #include "gl_util.h"
 #include "vout_helper.h"
@@ -57,6 +59,8 @@ struct vout_display_opengl_t {
     struct vlc_gl_sampler *sampler;
     struct vlc_gl_renderer *renderer;
 
+    struct vlc_gl_filters *filters;
+
     struct vlc_gl_interop *sub_interop;
     struct vlc_gl_sub_renderer *sub_renderer;
 };
@@ -157,11 +161,24 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
 
     GL_ASSERT_NOERROR(vt);
 
+    vgl->filters = vlc_gl_filters_New();
+    if (!vgl->filters)
+    {
+        msg_Err(gl, "Could not create filters");
+        goto delete_renderer;
+    }
+
+    /* Retrieve the "super-class" (renderer "extends" filter) */
+    struct vlc_gl_filter *renderer_filter = vgl->renderer->filter;
+
+    /* The renderer is the only filter, for now */
+    vlc_gl_filters_Append(vgl->filters, renderer_filter);
+
     vgl->sub_interop = vlc_gl_interop_NewForSubpictures(gl, api);
     if (!vgl->sub_interop)
     {
         msg_Err(gl, "Could not create sub interop");
-        goto delete_renderer;
+        goto delete_filters;
     }
 
     vgl->sub_renderer =
@@ -193,6 +210,8 @@ delete_sub_renderer:
     vlc_gl_sub_renderer_Delete(vgl->sub_renderer);
 delete_sub_interop:
     vlc_gl_interop_Delete(vgl->sub_interop);
+delete_filters:
+    vlc_gl_filters_Delete(vgl->filters);
 delete_renderer:
     vlc_gl_renderer_Delete(vgl->renderer);
 delete_sampler:
@@ -218,6 +237,7 @@ void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
     vlc_gl_sub_renderer_Delete(vgl->sub_renderer);
     vlc_gl_interop_Delete(vgl->sub_interop);
 
+    vlc_gl_filters_Delete(vgl->filters);
     vlc_gl_renderer_Delete(vgl->renderer);
     vlc_gl_sampler_Delete(vgl->sampler);
     vlc_gl_interop_Delete(vgl->interop);
@@ -267,9 +287,7 @@ int vout_display_opengl_Display(vout_display_opengl_t *vgl)
        OpenGL providers can call vout_display_opengl_Display to force redraw.
        Currently, the OS X provider uses it to get a smooth window resizing */
 
-    /* Retrieve the "super-class" (renderer "extends" filter) */
-    struct vlc_gl_filter *renderer_filter = vgl->renderer->filter;
-    int ret = renderer_filter->ops->draw(renderer_filter);
+    int ret = vlc_gl_filters_Draw(vgl->filters);
     if (ret != VLC_SUCCESS)
         return ret;
 
-- 
2.27.0



More information about the vlc-devel mailing list