diff --git a/include/vlc_preparser.h b/include/vlc_preparser.h index 51548fb728..d62a8adf68 100644 --- a/include/vlc_preparser.h +++ b/include/vlc_preparser.h @@ -120,20 +120,39 @@ struct vlc_preparser_seek_arg } speed; }; +/** + * Preparser creation configuration + */ +struct vlc_preparser_cfg +{ + /** + * A combination of VLC_PREPARSER_TYPE_* flags, it is used to + * setup the executors for each domain. Its possible to select more than + * one type + */ + int types; + + /** + * The maximum number of threads used by the parser, 0 for default + * (1 thread) + */ + unsigned max_parser_threads; + + /** + * Timeout of the preparser and/or thumbnailer, 0 for no limits. + */ + vlc_tick_t timeout; +}; + /** * This function creates the preparser object and thread. * * @param obj the parent object - * @param max_threads the maximum number of threads used to parse, must be >= 1 - * @param timeout timeout of the preparser, 0 for no limits. - * @param types a combination of VLC_PREPARSER_TYPE_* flags, it is used to - * setup the executors for each domain. Its possible to select more than one - * types + * @param cfg a pointer to a valid confiuration struct * @return a valid preparser object or NULL in case of error */ VLC_API vlc_preparser_t *vlc_preparser_New( vlc_object_t *obj, - unsigned max_threads, - vlc_tick_t timeout, int types ); + const struct vlc_preparser_cfg *cfg ); /** * This function enqueues the provided item to be preparsed or fetched. diff --git a/lib/core.c b/lib/core.c index 768ea15d58..3d91448fd6 100644 --- a/lib/core.c +++ b/lib/core.c @@ -265,11 +265,14 @@ vlc_preparser_t *libvlc_get_preparser(libvlc_instance_t *instance) if (default_timeout < 0) default_timeout = 0; + const struct vlc_preparser_cfg cfg = { + .types = VLC_PREPARSER_TYPE_PARSE | VLC_PREPARSER_TYPE_FETCHMETA_ALL, + .max_parser_threads = max_threads, + .timeout = default_timeout, + }; + parser = instance->parser = - vlc_preparser_New(VLC_OBJECT(instance->p_libvlc_int), max_threads, - default_timeout, - VLC_PREPARSER_TYPE_PARSE | - VLC_PREPARSER_TYPE_FETCHMETA_ALL); + vlc_preparser_New(VLC_OBJECT(instance->p_libvlc_int), &cfg); } vlc_mutex_unlock(&instance->lazy_init_lock); @@ -283,9 +286,13 @@ vlc_preparser_t *libvlc_get_thumbnailer(libvlc_instance_t *instance) if (thumb == NULL) { + const struct vlc_preparser_cfg cfg = { + .types = VLC_PREPARSER_TYPE_THUMBNAIL, + .timeout = 0, + }; + thumb = instance->thumbnailer = - vlc_preparser_New(VLC_OBJECT(instance->p_libvlc_int), 1, 0, - VLC_PREPARSER_TYPE_THUMBNAIL); + vlc_preparser_New(VLC_OBJECT(instance->p_libvlc_int), &cfg); } vlc_mutex_unlock(&instance->lazy_init_lock); diff --git a/modules/gui/macosx/main/VLCMain.m b/modules/gui/macosx/main/VLCMain.m index 9983ed1d2d..8421bfa708 100644 --- a/modules/gui/macosx/main/VLCMain.m +++ b/modules/gui/macosx/main/VLCMain.m @@ -155,8 +155,12 @@ int OpenIntf (vlc_object_t *p_this) intf_thread_t *p_intf = (intf_thread_t*) p_this; p_interface_thread = p_intf; - p_network_preparser = vlc_preparser_New(p_this, 1, 0, - VLC_PREPARSER_TYPE_PARSE); + const struct vlc_preparser_cfg cfg = { + .types = VLC_PREPARSER_TYPE_PARSE, + .max_parser_threads = 1, + .timeout = 0, + }; + p_network_preparser = vlc_preparser_New(p_this, &cfg); if (p_network_preparser == nil) { retcode = VLC_ENOMEM; diff --git a/modules/gui/qt/maininterface/mainctx.cpp b/modules/gui/qt/maininterface/mainctx.cpp index 246469f0c1..bbc7e28f38 100644 --- a/modules/gui/qt/maininterface/mainctx.cpp +++ b/modules/gui/qt/maininterface/mainctx.cpp @@ -251,8 +251,14 @@ MainCtx::MainCtx(qt_intf_t *_p_intf) QMetaObject::invokeMethod(m_medialib, &MediaLib::reload, Qt::QueuedConnection); } - m_network_preparser = vlc_preparser_New(VLC_OBJECT(libvlc), 1, 0, - VLC_PREPARSER_TYPE_PARSE); + const struct vlc_preparser_cfg cfg = []{ + struct vlc_preparser_cfg cfg{}; + cfg.types = VLC_PREPARSER_TYPE_PARSE; + cfg.max_parser_threads = 1; + cfg.timeout = 0; + return cfg; + }(); + m_network_preparser = vlc_preparser_New(VLC_OBJECT(libvlc), &cfg); #ifdef UPDATE_CHECK /* Checking for VLC updates */ diff --git a/modules/gui/qt/player/player_controller.cpp b/modules/gui/qt/player/player_controller.cpp index a1b45d13ef..9f1de2b32b 100644 --- a/modules/gui/qt/player/player_controller.cpp +++ b/modules/gui/qt/player/player_controller.cpp @@ -1955,9 +1955,14 @@ void PlayerController::requestArtUpdate( input_item_t *p_item ) if (default_timeout < 0) default_timeout = 0; - d->m_preparser = vlc_preparser_New(VLC_OBJECT(d->p_intf), 1, - default_timeout, - VLC_PREPARSER_TYPE_FETCHMETA_ALL); + const struct vlc_preparser_cfg cfg = [default_timeout]{ + struct vlc_preparser_cfg cfg{}; + cfg.types = VLC_PREPARSER_TYPE_FETCHMETA_ALL; + cfg.max_parser_threads = 1; + cfg.timeout = default_timeout; + return cfg; + }(); + d->m_preparser = vlc_preparser_New(VLC_OBJECT(d->p_intf), &cfg); if (unlikely(d->m_preparser == nullptr)) return; } diff --git a/modules/misc/medialibrary/Thumbnailer.cpp b/modules/misc/medialibrary/Thumbnailer.cpp index 3eaa80bd0f..779c2d637b 100644 --- a/modules/misc/medialibrary/Thumbnailer.cpp +++ b/modules/misc/medialibrary/Thumbnailer.cpp @@ -37,9 +37,13 @@ Thumbnailer::Thumbnailer( vlc_medialibrary_module_t* ml ) , m_currentContext( nullptr ) , m_thumbnailer( nullptr, &vlc_preparser_Delete ) { - m_thumbnailer.reset( vlc_preparser_New( VLC_OBJECT( ml ), 1, - VLC_TICK_FROM_SEC( 3 ), - VLC_PREPARSER_TYPE_THUMBNAIL ) ); + const struct vlc_preparser_cfg cfg = []{ + struct vlc_preparser_cfg cfg{}; + cfg.types = VLC_PREPARSER_TYPE_THUMBNAIL; + cfg.timeout = VLC_TICK_FROM_SEC( 3 ); + return cfg; + }(); + m_thumbnailer.reset( vlc_preparser_New( VLC_OBJECT( ml ), &cfg ) ); if ( unlikely( m_thumbnailer == nullptr ) ) throw std::runtime_error( "Failed to instantiate a vlc_preparser_t" ); } diff --git a/src/playlist/playlist.c b/src/playlist/playlist.c index f741598749..faa7c94b99 100644 --- a/src/playlist/playlist.c +++ b/src/playlist/playlist.c @@ -40,10 +40,12 @@ vlc_playlist_New(vlc_object_t *parent, enum vlc_playlist_preparsing rec, if (rec != VLC_PLAYLIST_PREPARSING_DISABLED) { - playlist->parser = vlc_preparser_New(parent, preparse_max_threads, - preparse_timeout, - VLC_PREPARSER_TYPE_PARSE | - VLC_PREPARSER_TYPE_FETCHMETA_LOCAL); + const struct vlc_preparser_cfg cfg = { + .types = VLC_PREPARSER_TYPE_PARSE | VLC_PREPARSER_TYPE_FETCHMETA_LOCAL, + .max_parser_threads = preparse_max_threads, + .timeout = preparse_timeout, + }; + playlist->parser = vlc_preparser_New(parent, &cfg); if (playlist->parser == NULL) { free(playlist); diff --git a/src/preparser/preparser.c b/src/preparser/preparser.c index 6a4e39a9b5..6ed2ce926c 100644 --- a/src/preparser/preparser.c +++ b/src/preparser/preparser.c @@ -410,25 +410,30 @@ Interrupt(struct task *task) vlc_sem_post(&task->preparse_ended); } -vlc_preparser_t* vlc_preparser_New( vlc_object_t *parent, unsigned max_threads, - vlc_tick_t timeout, int request_type ) +vlc_preparser_t* vlc_preparser_New( vlc_object_t *parent, + const struct vlc_preparser_cfg *cfg ) { - assert(max_threads >= 1); - assert(timeout >= 0); + assert(cfg != NULL); + + assert(cfg->timeout >= 0); + + int request_type = cfg->types; assert(request_type & (VLC_PREPARSER_TYPE_FETCHMETA_ALL| VLC_PREPARSER_TYPE_PARSE| VLC_PREPARSER_TYPE_THUMBNAIL)); + unsigned parser_threads = cfg->max_parser_threads == 0 ? 1 : + cfg->max_parser_threads; vlc_preparser_t* preparser = malloc( sizeof *preparser ); if (!preparser) return NULL; - preparser->timeout = timeout; + preparser->timeout = cfg->timeout; preparser->owner = parent; if (request_type & VLC_PREPARSER_TYPE_PARSE) { - preparser->parser = vlc_executor_New(max_threads); + preparser->parser = vlc_executor_New(parser_threads); if (!preparser->parser) goto error_parser; } diff --git a/test/libvlc/media.c b/test/libvlc/media.c index 2a282855f4..1cc530c33b 100644 --- a/test/libvlc/media.c +++ b/test/libvlc/media.c @@ -253,9 +253,13 @@ static void test_input_metadata_timeout(libvlc_instance_t *vlc, int timeout, int options = VLC_PREPARSER_TYPE_PARSE | VLC_PREPARSER_TYPE_FETCHMETA_LOCAL; + const struct vlc_preparser_cfg cfg = { + .types = options, + .max_parser_threads = 1, + .timeout = VLC_TICK_FROM_MS(timeout), + }; vlc_preparser_t *parser = vlc_preparser_New(VLC_OBJECT(vlc->p_libvlc_int), - 1, VLC_TICK_FROM_MS(timeout), - options); + &cfg); assert(parser != NULL); vlc_preparser_req_id id = vlc_preparser_Push(parser, p_item, options, &cbs, &sem); assert(id != VLC_PREPARSER_REQ_ID_INVALID); diff --git a/test/src/preparser/thumbnail.c b/test/src/preparser/thumbnail.c index 0927e5b667..d4374e65b8 100644 --- a/test/src/preparser/thumbnail.c +++ b/test/src/preparser/thumbnail.c @@ -128,9 +128,13 @@ static void test_thumbnails( libvlc_instance_t* p_vlc ) ctx.test_idx = i; ctx.b_done = false; + const struct vlc_preparser_cfg cfg = { + .types = VLC_PREPARSER_TYPE_THUMBNAIL, + .timeout = test_params[i].i_timeout, + }; + vlc_preparser_t* p_thumbnailer = vlc_preparser_New( - VLC_OBJECT( p_vlc->p_libvlc_int ), 1, test_params[i].i_timeout, - VLC_PREPARSER_TYPE_THUMBNAIL ); + VLC_OBJECT( p_vlc->p_libvlc_int ), &cfg ); assert( p_thumbnailer != NULL ); @@ -194,9 +198,12 @@ static void thumbnailer_callback_cancel( input_item_t *item, int status, static void test_cancel_thumbnail( libvlc_instance_t* p_vlc ) { + const struct vlc_preparser_cfg cfg = { + .types = VLC_PREPARSER_TYPE_THUMBNAIL, + .timeout = VLC_TICK_INVALID, + }; vlc_preparser_t* p_thumbnailer = vlc_preparser_New( - VLC_OBJECT( p_vlc->p_libvlc_int ), 1, VLC_TICK_INVALID, - VLC_PREPARSER_TYPE_THUMBNAIL ); + VLC_OBJECT( p_vlc->p_libvlc_int ), &cfg ); assert( p_thumbnailer != NULL ); const char* psz_mrl = "mock://video_track_count=0;audio_track_count=1;"