<!DOCTYPE html><html><head><title></title><style type="text/css">p.MsoNormal,p.MsoNoSpacing{margin:0}</style></head><body><div>Hello everyone,<br></div><div><br></div><div>I recently added a generic metadata listener API into the new player. It's only used to get loudness measurements for now, cf. <a href="https://code.videolan.org/tguillem/vlc/-/commit/e8f17308146f446bc46f6a3b787aed2406ce8d31">https://code.videolan.org/tguillem/vlc/-/commit/e8f17308146f446bc46f6a3b787aed2406ce8d31</a><br></div><div>And I tried to port it to libvlc here: <a href="https://code.videolan.org/tguillem/vlc/-/commits/loudness-libvlc">https://code.videolan.org/tguillem/vlc/-/commits/loudness-libvlc</a><br></div><div><br></div><div>I received few valid critics with these 2 API (Core + LibVKC) from developers, and LibVLC users:<br></div><div>- LibVLC users don't like using a new kind a listener API (that is not the classical event manager)<br></div><div>- New kind of metadata will likely come from a filter. <br></div><div>- Other kind of metadata (like HDR) can come from es_format_t. We need to find a proper way to forward es_format_t change to LibVLC in that case.<br></div><div><br></div><div>So, maybe it is a good time to think about a proper filter API in LibVLC and Core. An API to manipulate filters of a given category (splitter, audio, meter, video, sub) from a specific output. This API will let users add, re-order, remove filters and also get notification from them (for the audio meter filter).<br></div><div><br></div><div>Note that aout and vout are not (yet?) exposed to libvlc, so the libVLC will only be able to handle filters by category on the media_player.<br></div><div><br></div><div>Here is my proposal for the Core API (in a form of a C header):<br></div><div><br></div><div>typedef struct vlc_filter_entry_t vlc_filter_entry_t;<br></div><div><br></div><div>/* All type of filters supported by VLC */<br></div><div>enum vlc_filter_type<br></div><div>{<br></div><div>    VLC_PLAYER_FILTER_AUDIO,<br></div><div>    /* Such filters are only useful if the user listen to events via<br></div><div>     * vlc_filter_entry_NewAudioMeter() */<br></div><div>    VLC_PLAYER_FILTER_AUDIO_METER,<br></div><div>    VLC_PLAYER_FILTER_VIDEO,<br></div><div>    VLC_PLAYER_FILTER_VIDEO_SPLITTER,<br></div><div>    VLC_PLAYER_FILTER_SUBTITLE,<br></div><div>    VLC_PLAYER_FILTER_SUBTITLE_SOURCE,<br></div><div>};<br></div><div><br></div><div>/* Listener, only used with audio_meter filters */<br></div><div>struct vlc_filter_audio_meter_listener<br></div><div>{<br></div><div>    union {<br></div><div>        /* Generic callback. For the loudness audio_meter, val1 will be a<br></div><div>         * int64_t date, val2 will be a pointer to the vlc_audio_loudness<br></div><div>         * struct */<br></div><div>        void (*on_values_changed)(vlc_value_t val1, val_value_t val2);<br></div><div>        /* Maybe add some other cb definition later depending on the need */<br></div><div>    };<br></div><div>};<br></div><div><br></div><div>/* Create a new filter entry<br></div><div>* The filter entry hold necessary informations to start a filter on the aout<br></div><div>* or the vout.<br></div><div>*/<br></div><div>VLC_API vlc_filter_entry_t *<br></div><div>vlc_filter_entry_New(enum vlc_filter_type type, const char *name, const char *option);<br></div><div><br></div><div>/* Create a new audio meter entry with a listener callback */<br></div><div>VLC_API vlc_filter_entry_t *<br></div><div>vlc_filter_entry_NewAudioMeter(const char *name,  const char *option, const struct vlc_filter_audio_meter_listener * cb, void *data);<br></div><div><br></div><div>/* Return the name of the filter entry */<br></div><div>VLC_API const char * vlc_filter_entry_GetName(vlc_filter_entry_t *fentry);<br></div><div><br></div><div>/* Return the option of the filter entry */<br></div><div>VLC_API const char * vlc_filter_entry_GetOption(vlc_filter_entry_t *fentry);<br></div><div><br></div><div>/* Release a filter entry. Filter entries are refcounted internally (by the filter_list and the filter entry creator */<br></div><div>VLC_API void vlc_filter_entry_Release(vlc_filter_entry_t *fentry);<br></div><div><br></div><div>/* Filter entry list, owned by vout and aout. There is one filter list per filter type */<br></div><div><br></div><div>typedef struct vlc_filter_list_t vlc_filter_list;<br></div><div><br></div><div>/* Lock the filter list, read and write operations need to be done locked */<br></div><div>void vlc_filter_list_Lock(vlc_filter_list_t *list);<br></div><div><br></div><div>/* Unlock the filter list, and commit the written changes if needed. To commit<br></div><div>* any changes, the list will change the corresponding filter option (like<br></div><div>* "video-splitter") on the corresponding vout/aout. */<br></div><div>void vlc_filter_list_Unlock(vlc_filter_list_t *list);<br></div><div><br></div><div>/* Return the number of filters */<br></div><div>size_t vlc_filter_list_GetCount(vlc_filter_list_t *list);<br></div><div><br></div><div>/* Get the filter entry at the specific index */<br></div><div>vlc_filter_entry_t * vlc_filter_list_GetFilterAt(vlc_filter_list_t *list, size_t index);<br></div><div><br></div><div>/* Add a new filter at a specific position or move a filter at the new<br></div><div>* position. */<br></div><div>void<br></div><div>vlc_filter_list_MoveFilterAt(vlc_filter_list_t *list, size_t index, vlc_filter_entry_t *filter);<br></div><div><br></div><div>/* Append a filter at the end of the list */<br></div><div>static inline void<br></div><div>vlc_filter_list_AppendFilter(vlc_filter_list_t *list, vlc_filter_entry_t *filter)<br></div><div>{<br></div><div>    vlc_filter_list_MoveFilterAt(list, vlc_filter_list_GetCount(list), filter);<br></div><div>}<br></div><div><br></div><div>/* Remove a filter from the list. */<br></div><div>void vlc_filter_list_RemoveFilter(vlc_filter_list_t *list, vlc_filter_entry_t *filter);<br></div><div><br></div><div>/* Get the filter list of the aout for the specific type */<br></div><div>vlc_filter_list_t *<br></div><div>aout_GetFilterList(aout_output_t *, enum vlc_filter_type type);<br></div><div><br></div><div>/* Get the filter list of the vout for the specific type */<br></div><div>vlc_filter_list_t *<br></div><div>vout_GetFilterList(vout_output_t *, enum vlc_filter_type type);<br></div><div><br></div><div>Comments are more than welcome!<br></div><div><br></div><div>Best,<br></div><div>Thomas<br></div></body></html>