[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