[vlc-devel] [PATCHv2 05/18] vout: trigger filters commands
Thomas Guillem
thomas at gllm.fr
Wed May 31 10:01:25 CEST 2017
On Tue, May 30, 2017, at 21:37, Rémi Denis-Courmont wrote:
> Le tiistaina 30. toukokuuta 2017, 18.40.55 EEST Thomas Guillem a écrit :
> > The vout now duplicates every command variables of spawned filters in order
> > to trigger events directly from the vout.
> > ---
> > src/video_output/video_output.c | 91
> > +++++++++++++++++++++++++++++++++++++++- src/video_output/vout_internal.h |
> > 1 +
> > 2 files changed, 91 insertions(+), 1 deletion(-)
> >
> > diff --git a/src/video_output/video_output.c
> > b/src/video_output/video_output.c index 730b902b24..1f30797a5a 100644
> > --- a/src/video_output/video_output.c
> > +++ b/src/video_output/video_output.c
> > @@ -46,12 +46,15 @@
> > #include <vlc_spu.h>
> > #include <vlc_vout_osd.h>
> > #include <vlc_image.h>
> > +#include <vlc_plugin.h>
> >
> > #include <libvlc.h>
> > #include "vout_internal.h"
> > #include "interlacing.h"
> > #include "display.h"
> > #include "window.h"
> > +#include "../modules/modules.h"
> > +#include "../misc/variables.h"
> >
> > /**************************************************************************
> > *** * Local prototypes
> > @@ -140,6 +143,8 @@ static vout_thread_t *VoutCreate(vlc_object_t *object,
> >
> > vout_snapshot_Init(&vout->p->snapshot);
> >
> > + vlc_array_init(&vout->p->filter.callbacks);
> > +
> > /* Initialize locks */
> > vlc_mutex_init(&vout->p->filter.lock);
> > vlc_mutex_init(&vout->p->spu_lock);
> > @@ -649,6 +654,81 @@ int vout_HideWindowMouse(vout_thread_t *vout, bool
> > hide) }
> >
> > /* */
> > +struct filter_callback
> > +{
> > + filter_t *filter;
> > + char *name;
> > +};
> > +
> > +static int FilterProxyCallback(vlc_object_t *p_this, char const *psz_var,
> > + vlc_value_t oldval, vlc_value_t newval,
> > + void *p_data)
> > +{
> > + (void) p_this; (void) oldval;
> > + struct filter_callback *callback = p_data;
> > + var_Set(callback->filter, psz_var, newval);
> > + return 0;
> > +}
> > +
> > +static void ThreadDelFilterCallbacks(vout_thread_t *vout)
> > +{
> > + for (size_t i = 0; i < vlc_array_count(&vout->p->filter.callbacks);
> > ++i) + {
> > + struct filter_callback *callback =
> > + vlc_array_item_at_index(&vout->p->filter.callbacks, i);
> > + var_DelCallback(vout, callback->name, FilterProxyCallback,
> > callback); + var_Destroy(vout, callback->name);
> > + free(callback->name);
> > + free(callback);
> > + }
> > + vlc_array_clear(&vout->p->filter.callbacks);
> > +}
> > +
> > +static void ThreadAddFilterCallbacks(vout_thread_t *vout, filter_t *filter)
> > +{
> > + /* Duplicate every command variables from the filter to the vout, and
> > add a + * proxy callback to trigger filters events from the vout. */ +
> > + char **names = var_GetAllNames(VLC_OBJECT(filter));
> > + if (names == NULL)
> > + return;
> > +
> > + for (char **pname = names; *pname != NULL; pname++)
> > + {
> > + char *name = *pname;
> > + int var_type = var_Type(filter, name);
> > + if (!(var_type & VLC_VAR_ISCOMMAND))
> > + {
> > +#ifndef NDEBUG
> > + /* Make sure that each option is unique */
> > + for (size_t i = 0; i <
> > vlc_array_count(&vout->p->filter.callbacks); + ++i)
> > + {
> > + struct filter_callback *callback =
> > + vlc_array_item_at_index(&vout->p->filter.callbacks, i);
> > + assert(strcmp(callback->name, name) != 0);
> > + }
> > +#endif
> > + struct filter_callback *callback = malloc(sizeof(*callback));
> > + if (unlikely(callback == NULL))
> > + {
> > + free(name);
> > + continue;
> > + }
> > +
> > + callback->filter = filter;
> > + callback->name = name;
> > + vlc_array_append(&vout->p->filter.callbacks, callback);
> > +
> > + var_Create(vout, callback->name, var_type | VLC_VAR_DOINHERIT);
> > + var_AddCallback(vout, callback->name, FilterProxyCallback,
> > callback);
>
> Passing filter as opaque data would seem more logical and simpler. And if
> you
> assume that the set of variables does not change, you probably don´t even
> need
> the array: you can reiterate at deletion.
Ok, I'll simplify it.
>
> > + }
> > + else
> > + free(name);
> > + }
> > + free(names);
> > +}
> > +
> > static picture_t *VoutVideoFilterInteractiveNewPicture(filter_t *filter)
> > {
> > vout_thread_t *vout = filter->owner.sys;
> > @@ -702,6 +782,7 @@ static void ThreadChangeFilters(vout_thread_t *vout,
> > bool is_locked)
> > {
> > ThreadFilterFlush(vout, is_locked);
> > + ThreadDelFilterCallbacks(vout);
> >
> > vlc_array_t array_static;
> > vlc_array_t array_interactive;
> > @@ -770,10 +851,16 @@ static void ThreadChangeFilters(vout_thread_t *vout,
> > for (size_t i = 0; i < vlc_array_count(array); i++) {
> > vout_filter_t *e = vlc_array_item_at_index(array, i);
> > msg_Dbg(vout, "Adding '%s' as %s", e->name, a == 0 ? "static" :
> > "interactive"); - if (!filter_chain_AppendFilter(chain, e->name,
> > e->cfg, NULL, NULL)) { + filter_t *filter =
> > filter_chain_AppendFilter(chain, e->name, e->cfg, +
> > NULL, NULL);
> > + if (filter)
> > + ThreadAddFilterCallbacks(vout, filter);
> > + else
> > + {
> > msg_Err(vout, "Failed to add filter '%s'", e->name);
> > config_ChainDestroy(e->cfg);
> > }
> > +
> > free(e->name);
> > free(e);
> > }
> > @@ -1429,6 +1516,7 @@ static int ThreadStart(vout_thread_t *vout,
> > vout_display_state_t *state) video_format_Print(VLC_OBJECT(vout), "original
> > format", &vout->p->original); return VLC_SUCCESS;
> > error:
> > + ThreadDelFilterCallbacks(vout);
> > if (vout->p->filter.chain_interactive != NULL)
> > filter_chain_Delete(vout->p->filter.chain_interactive);
> > if (vout->p->filter.chain_static != NULL)
> > @@ -1454,6 +1542,7 @@ static void ThreadStop(vout_thread_t *vout,
> > vout_display_state_t *state) }
> >
> > /* Destroy the video filters2 */
> > + ThreadDelFilterCallbacks(vout);
> > filter_chain_Delete(vout->p->filter.chain_interactive);
> > filter_chain_Delete(vout->p->filter.chain_static);
> > video_format_Clean(&vout->p->filter.format);
> > diff --git a/src/video_output/vout_internal.h
> > b/src/video_output/vout_internal.h index 400bcb8b61..cb64544d3d 100644
> > --- a/src/video_output/vout_internal.h
> > +++ b/src/video_output/vout_internal.h
> > @@ -125,6 +125,7 @@ struct vout_thread_sys_t
> > struct filter_chain_t *chain_static;
> > struct filter_chain_t *chain_interactive;
> > bool has_deint;
> > + vlc_array_t callbacks;
> > } filter;
> >
> > /* */
>
>
> --
> 雷米‧德尼-库尔蒙
> https://www.remlab.net/
>
> _______________________________________________
> 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