[vlc-devel] [PATCH 07/27] opengl: attach samplers to filters
Alexandre Janniaux
ajanni at videolabs.io
Mon Jun 29 17:11:12 CEST 2020
Hi,
It seems weird that we can create a sampler with or without
an interop, but that we cannot do the same with filter chains.
It can wait a latter patchset though since it's an additon and
not yet used.
Regards,
--
Alexandre Janniaux
Videolabs
On Thu, Jun 25, 2020 at 02:22:54PM +0200, Romain Vimont wrote:
> 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
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list