vlc | branch: master | Romain Vimont <[email protected]> | Tue Jul 7 12:33:50 2020 +0200| [287c9b3d0f54e871969c2af29fdf9961271bf78b] | committer: Alexandre Janniaux
opengl: attach samplers to filters 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. Co-authored-by: Alexandre Janniaux <[email protected]> Signed-off-by: Alexandre Janniaux <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=287c9b3d0f54e871969c2af29fdf9961271bf78b --- 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..02a2a076ac 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_NewFromTexture2D(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 6707adcd66..e670d88e4a 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; _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
