[vlc-devel] [PATCH 07/27] opengl: attach samplers to filters
Romain Vimont
rom1v at videolabs.io
Mon Jun 29 19:44:11 CEST 2020
On Mon, Jun 29, 2020 at 05:11:12PM +0200, Alexandre Janniaux wrote:
> 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.
A sampler with interop receives picture_t, while a "direct" sampler
receives textures. Its purpose is to transmit the result of a filter to
the next one, so there was no reason to expose it on the global filter
chain (which, currently, always receives receives picture_t,
imported via an interop).
Moreover, samplers are always created internally by the filter chain
itself (cf filters.c:GetSampler), they are not expected to be created by
the caller.
But depending on future needs, we could adapt it later if necessary.
>
> 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
> _______________________________________________
> 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