[vlc-devel] [PATCH 07/27] opengl: attach samplers to filters
Romain Vimont
rom1v at videolabs.io
Thu Jun 25 14:22:54 CEST 2020
There must be one sampler per filter.
The first filter in the chain will receive a sampler created from an
interop; the remaining ones will receive a "direct" sampler.
---
modules/video_output/opengl/filter.c | 8 ++++
modules/video_output/opengl/filter_priv.h | 2 +
modules/video_output/opengl/filters.c | 55 ++++++++++++++++++++---
modules/video_output/opengl/filters.h | 20 +++++++--
modules/video_output/opengl/vout_helper.c | 19 ++------
5 files changed, 79 insertions(+), 25 deletions(-)
diff --git a/modules/video_output/opengl/filter.c b/modules/video_output/opengl/filter.c
index 110460e759..c4ba0bfb71 100644
--- a/modules/video_output/opengl/filter.c
+++ b/modules/video_output/opengl/filter.c
@@ -30,6 +30,8 @@
#include <vlc_common.h>
#include <vlc_modules.h>
+#include "sampler_priv.h"
+
#undef vlc_gl_filter_New
struct vlc_gl_filter *
vlc_gl_filter_New(vlc_object_t *parent, const struct vlc_gl_api *api)
@@ -38,6 +40,8 @@ vlc_gl_filter_New(vlc_object_t *parent, const struct vlc_gl_api *api)
if (!priv)
return NULL;
+ priv->sampler = NULL;
+
struct vlc_gl_filter *filter = &priv->filter;
filter->api = api;
filter->ops = NULL;
@@ -84,5 +88,9 @@ vlc_gl_filter_Delete(struct vlc_gl_filter *filter)
if (filter->module)
module_unneed(filter, filter->module);
+ struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
+ if (priv->sampler)
+ vlc_gl_sampler_Delete(priv->sampler);
+
vlc_object_delete(&filter->obj);
}
diff --git a/modules/video_output/opengl/filter_priv.h b/modules/video_output/opengl/filter_priv.h
index 376249a636..365ebd0fa9 100644
--- a/modules/video_output/opengl/filter_priv.h
+++ b/modules/video_output/opengl/filter_priv.h
@@ -26,9 +26,11 @@
#include <vlc_list.h>
#include "filter.h"
+#include "sampler.h"
struct vlc_gl_filter_priv {
struct vlc_gl_filter filter;
+ struct vlc_gl_sampler *sampler; /* owned */
struct vlc_list node; /**< node of vlc_gl_filters.list */
};
diff --git a/modules/video_output/opengl/filters.c b/modules/video_output/opengl/filters.c
index b1732e21a9..7f5ac551c5 100644
--- a/modules/video_output/opengl/filters.c
+++ b/modules/video_output/opengl/filters.c
@@ -30,16 +30,24 @@
#include "filter_priv.h"
#include "renderer.h"
+#include "sampler_priv.h"
struct vlc_gl_filters {
struct vlc_gl_t *gl;
const struct vlc_gl_api *api;
+ /**
+ * Interop to use for the sampler of the first filter of the chain,
+ * the one which uses the picture_t as input.
+ */
+ struct vlc_gl_interop *interop;
+
struct vlc_list list; /**< list of vlc_gl_filter.node */
};
struct vlc_gl_filters *
-vlc_gl_filters_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api)
+vlc_gl_filters_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api,
+ struct vlc_gl_interop *interop)
{
struct vlc_gl_filters *filters = malloc(sizeof(*filters));
if (!filters)
@@ -47,6 +55,7 @@ vlc_gl_filters_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api)
filters->gl = gl;
filters->api = api;
+ filters->interop = interop;
vlc_list_init(&filters->list);
return filters;
}
@@ -66,15 +75,35 @@ vlc_gl_filters_Delete(struct vlc_gl_filters *filters)
struct vlc_gl_filter *
vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
- const config_chain_t *config,
- struct vlc_gl_sampler *sampler)
+ const config_chain_t *config)
{
struct vlc_gl_filter *filter = vlc_gl_filter_New(filters->gl, filters->api);
if (!filter)
return NULL;
- int ret =
- vlc_gl_filter_LoadModule(filters->gl, name, filter, config, sampler);
+ struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
+
+ bool first_filter = vlc_list_is_empty(&filters->list);
+ if (first_filter)
+ priv->sampler = vlc_gl_sampler_NewFromInterop(filters->interop);
+ else
+ {
+ video_format_t fmt;
+ video_format_Init(&fmt, VLC_CODEC_RGBA);
+ // TODO set format width/height
+
+ priv->sampler =
+ vlc_gl_sampler_NewDirect(filters->gl, filters->api, &fmt);
+ }
+
+ if (!priv->sampler)
+ {
+ vlc_gl_filter_Delete(filter);
+ return NULL;
+ }
+
+ int ret = vlc_gl_filter_LoadModule(filters->gl, name, filter, config,
+ priv->sampler);
if (ret != VLC_SUCCESS)
{
/* Creation failed, do not call close() */
@@ -83,12 +112,26 @@ vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
return NULL;
}
- struct vlc_gl_filter_priv *priv = vlc_gl_filter_PRIV(filter);
vlc_list_append(&priv->node, &filters->list);
return filter;
}
+int
+vlc_gl_filters_UpdatePicture(struct vlc_gl_filters *filters,
+ picture_t *picture)
+{
+ assert(!vlc_list_is_empty(&filters->list));
+
+ struct vlc_gl_filter_priv *first_filter =
+ vlc_list_first_entry_or_null(&filters->list, struct vlc_gl_filter_priv,
+ node);
+
+ assert(first_filter);
+
+ return vlc_gl_sampler_UpdatePicture(first_filter->sampler, picture);
+}
+
int
vlc_gl_filters_Draw(struct vlc_gl_filters *filters)
{
diff --git a/modules/video_output/opengl/filters.h b/modules/video_output/opengl/filters.h
index a6d6c2a27c..26b89b407c 100644
--- a/modules/video_output/opengl/filters.h
+++ b/modules/video_output/opengl/filters.h
@@ -28,6 +28,7 @@
#include "filter.h"
#include "gl_api.h"
+#include "interop.h"
#include "sampler.h"
struct vlc_gl_filters;
@@ -37,9 +38,11 @@ struct vlc_gl_filters;
*
* \param gl the OpenGL context
* \param api the OpenGL api
+ * \param interop the interop to use for the sampler of the first filter
*/
struct vlc_gl_filters *
-vlc_gl_filters_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api);
+vlc_gl_filters_New(struct vlc_gl_t *gl, const struct vlc_gl_api *api,
+ struct vlc_gl_interop *interop);
/**
* Delete the OpenGL filter chain
@@ -57,13 +60,22 @@ vlc_gl_filters_Delete(struct vlc_gl_filters *filters);
* \param filters the filter chain
* \param name the module name
* \param config the module configuration
- * \param sampler the OpenGL sampler to use from the filter
* \return a weak reference to the filter (NULL on error)
*/
struct vlc_gl_filter *
vlc_gl_filters_Append(struct vlc_gl_filters *filters, const char *name,
- const config_chain_t *config,
- struct vlc_gl_sampler *sampler);
+ const config_chain_t *config);
+
+/**
+ * Update the input picture to pass to the first filter
+ *
+ * \param filters the filter chain
+ * \param picture the new input picture
+ * \return VLC_SUCCESS on success, another value on error
+ */
+int
+vlc_gl_filters_UpdatePicture(struct vlc_gl_filters *filters,
+ picture_t *picture);
/**
* Draw by executing all the filters
diff --git a/modules/video_output/opengl/vout_helper.c b/modules/video_output/opengl/vout_helper.c
index 726bff56bd..22ca7350ea 100644
--- a/modules/video_output/opengl/vout_helper.c
+++ b/modules/video_output/opengl/vout_helper.c
@@ -56,7 +56,6 @@ struct vout_display_opengl_t {
struct vlc_gl_api api;
struct vlc_gl_interop *interop;
- struct vlc_gl_sampler *sampler;
struct vlc_gl_renderer *renderer; /**< weak reference */
struct vlc_gl_filters *filters;
@@ -144,23 +143,16 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
goto free_vgl;
}
- vgl->sampler = vlc_gl_sampler_NewFromInterop(vgl->interop);
- if (!vgl->sampler)
- {
- msg_Err(gl, "Could not create sampler");
- goto delete_interop;
- }
-
- vgl->filters = vlc_gl_filters_New(gl, api);
+ vgl->filters = vlc_gl_filters_New(gl, api, vgl->interop);
if (!vgl->filters)
{
msg_Err(gl, "Could not create filters");
- goto delete_sampler;
+ goto delete_interop;
}
/* The renderer is the only filter, for now */
struct vlc_gl_filter *renderer_filter =
- vlc_gl_filters_Append(vgl->filters, "renderer", NULL, vgl->sampler);
+ vlc_gl_filters_Append(vgl->filters, "renderer", NULL);
if (!renderer_filter)
{
msg_Warn(gl, "Could not create renderer for %4.4s",
@@ -210,8 +202,6 @@ delete_sub_interop:
vlc_gl_interop_Delete(vgl->sub_interop);
delete_filters:
vlc_gl_filters_Delete(vgl->filters);
-delete_sampler:
- vlc_gl_sampler_Delete(vgl->sampler);
delete_interop:
vlc_gl_interop_Delete(vgl->interop);
free_vgl:
@@ -234,7 +224,6 @@ void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
vlc_gl_interop_Delete(vgl->sub_interop);
vlc_gl_filters_Delete(vgl->filters);
- vlc_gl_sampler_Delete(vgl->sampler);
vlc_gl_interop_Delete(vgl->interop);
GL_ASSERT_NOERROR(vt);
@@ -266,7 +255,7 @@ int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
{
GL_ASSERT_NOERROR(&vgl->api.vt);
- int ret = vlc_gl_sampler_UpdatePicture(vgl->sampler, picture);
+ int ret = vlc_gl_filters_UpdatePicture(vgl->filters, picture);
if (ret != VLC_SUCCESS)
return ret;
--
2.27.0
More information about the vlc-devel
mailing list