[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