From 6206e370766401bd93de591c6bbdf9ceb0f2f10f Mon Sep 17 00:00:00 2001 From: Maxime Chapelet Date: Fri, 25 Nov 2022 18:06:16 +0100 Subject: [PATCH] video : improve runtime video filter activation There was two issues with the former module matching routing : 1. the routine searched for only one module name match it would fail given multiple modules had the same module name and score as an example, if a video filter have the same module name and score as an opengl filter, the opengl filter would be ordered first and the capability match would fail 2. the routine only searched for module names given module names are defined at build time, multiple submodules in the same source file with the same capability and score would have matched the search To prevent this, the search walk through all modules trying to match with each module shortcuts until the capability is satisfied --- include/vlc_modules.h | 10 ++++++++ lib/video.c | 58 +++++++++++++++++++++++++++++-------------- src/libvlccore.sym | 1 + src/modules/modules.c | 12 +++++++++ 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/include/vlc_modules.h b/include/vlc_modules.h index d4fc733577..c0e79ed3c0 100644 --- a/include/vlc_modules.h +++ b/include/vlc_modules.h @@ -200,6 +200,16 @@ VLC_API bool module_provides(const module_t *m, const char *cap); */ VLC_API const char * module_get_object(const module_t *m) VLC_USED; + +/** + * Gets the shortcut names of a module. + * + * \param m the module + * \param n [OUT] pointer to the number of shortcuts + * \return the module name + */ +VLC_API const char **module_get_shortcuts(const module_t *m, size_t *n) VLC_USED; + /** * Gets the human-friendly name of a module. * diff --git a/lib/video.c b/lib/video.c index 2df8f5cc16..3d12c362d4 100644 --- a/lib/video.c +++ b/lib/video.c @@ -611,28 +611,50 @@ static int get_filter_str( vlc_object_t *p_parent, const char *psz_name, { char *psz_parser; char *psz_string; - const char *psz_filter_type; + const char *psz_filter_type = NULL; - module_t *p_obj = module_find( psz_name ); - if( !p_obj ) + size_t sz_modules, sz_shortcuts; + module_t **list = module_list_get (&sz_modules); + module_t *p_obj = NULL; + for (size_t i = 0; i < sz_modules; i++) { - msg_Err( p_parent, "Unable to find filter module \"%s\".", psz_name ); - return VLC_EGENERIC; - } + module_t *module = list[i]; + const char **shortcuts_list = module_get_shortcuts(module, &sz_shortcuts); + if ( shortcuts_list == NULL ) + continue; + + for (size_t i = 0; i < sz_shortcuts; i++) + { + const char *shortcut = shortcuts_list[i]; + if ( !strcmp( shortcut, psz_name ) ) + { + if( module_provides( module, "video filter" ) ) + { + psz_filter_type = "video-filter"; + } + else if( module_provides( module, "sub source" ) ) + { + psz_filter_type = "sub-source"; + } + else if( module_provides( module, "sub filter" ) ) + { + psz_filter_type = "sub-filter"; + } + } - if( module_provides( p_obj, "video filter" ) ) - { - psz_filter_type = "video-filter"; - } - else if( module_provides( p_obj, "sub source" ) ) - { - psz_filter_type = "sub-source"; - } - else if( module_provides( p_obj, "sub filter" ) ) - { - psz_filter_type = "sub-filter"; + if ( psz_filter_type ) + break; + } + + if ( psz_filter_type ) { + p_obj = module; + break; + } } - else + + module_list_free (list); + + if ( p_obj == NULL ) { msg_Err( p_parent, "Unknown video filter type." ); return VLC_EGENERIC; diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 4a89953ec1..c7dbea4296 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -264,6 +264,7 @@ module_config_get module_find module_get_capability module_get_help +module_get_shortcuts module_get_name module_get_object module_get_score diff --git a/src/modules/modules.c b/src/modules/modules.c index 22e7c70523..a4d714cfaf 100644 --- a/src/modules/modules.c +++ b/src/modules/modules.c @@ -54,6 +54,18 @@ const char *module_get_object( const module_t *m ) return m->pp_shortcuts[0]; } +const char **module_get_shortcuts(const module_t *m, size_t *n) +{ + assert (m != NULL); + assert (n != NULL); + *n = m->i_shortcuts; + + if (unlikely(m->i_shortcuts == 0)) + return NULL; + + return m->pp_shortcuts; +} + const char *module_get_name( const module_t *m, bool long_name ) { if( long_name && ( m->psz_longname != NULL) )