Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
fa10c711 by Gabriel Lafond-Thenaille at 2026-01-07T08:09:14+00:00
medialibrary: Create LazyPreparser class

 * Add a new class LazePreparser to only create a `vlc_preparser_t` at
   the first request.

- - - - -
4bb4d5a1 by Gabriel Lafond-Thenaille at 2026-01-07T08:09:14+00:00
medialibrary: thumbnailer: Replace `vlc_preparser_t` by LazyPreparser

- - - - -
8962a2dc by Gabriel Lafond-Thenaille at 2026-01-07T08:09:14+00:00
medialibrary: metadata: Replace `input_item_Parse` calls

 * Use the `vlc_preparser` api insteed of the `input_item_Parse`.

 * Use a LazyPreparser to prevent useless preparser creation.

- - - - -
8a187726 by Gabriel Lafond-Thenaille at 2026-01-07T08:09:14+00:00
medialibrary: directory parsing: Replace `input_item_Parse` calls

 * Use the `vlc_preparser` api insteed of the `input_item_Parse`.

 * Use a LazyPreparser to prevent useless preparser creation.

- - - - -


8 changed files:

- + modules/misc/medialibrary/LazyPreparser.h
- modules/misc/medialibrary/MetadataExtractor.cpp
- modules/misc/medialibrary/Thumbnailer.cpp
- modules/misc/medialibrary/fs/directory.cpp
- modules/misc/medialibrary/fs/directory.h
- modules/misc/medialibrary/fs/fs.cpp
- modules/misc/medialibrary/fs/fs.h
- modules/misc/medialibrary/medialibrary.h


Changes:

=====================================
modules/misc/medialibrary/LazyPreparser.h
=====================================
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*****************************************************************************
+ * LazyPreparser.h: class to create a preparser at the first request
+ *****************************************************************************
+ * Copyright © 2025 Videolabs, VideoLAN and VLC authors
+ *
+ * Authors: Gabriel Lafond Thenaille <[email protected]>
+ *****************************************************************************/
+
+#ifndef LAZYPREPARSER_H
+#define LAZYPREPARSER_H
+
+#include <vlc_common.h>
+#include <vlc_preparser.h>
+
+class LazyPreparser
+{
+    public:
+        LazyPreparser(vlc_object_t *obj, const struct vlc_preparser_cfg cfg)
+            : m_obj(obj)
+            , m_cfg(cfg)
+            , m_preparser(nullptr, &vlc_preparser_Delete)
+        {
+            assert(obj != NULL);
+        }
+
+        vlc_preparser_t *instance()
+        {
+            vlc::threads::mutex_locker locker(m_mutex);
+
+            vlc_preparser_t *preparser = m_preparser.get();
+            if (preparser == nullptr) {
+                m_preparser.reset(vlc_preparser_New(m_obj, &m_cfg));
+                preparser = m_preparser.get();
+                if (preparser == nullptr) {
+                    msg_Warn(m_obj, "LazyPreparser: Failed to instantiate a 
vlc_preparser_t!");
+                } else {
+                    msg_Dbg(m_obj, "LazyPreparser: vlc_preparser_t created!");
+                }
+            }
+            return preparser;
+        }
+
+        vlc_preparser_t *get()
+        {
+            vlc::threads::mutex_locker locker(m_mutex);
+            return m_preparser.get();
+        }
+
+    private:
+        vlc::threads::mutex m_mutex;
+        vlc_object_t *m_obj;
+        const struct vlc_preparser_cfg m_cfg;
+        std::unique_ptr<vlc_preparser_t, void(*)(vlc_preparser_t*)> 
m_preparser;
+};
+
+#endif


=====================================
modules/misc/medialibrary/MetadataExtractor.cpp
=====================================
@@ -27,6 +27,7 @@
 #include <vlc_image.h>
 #include <vlc_hash.h>
 #include <vlc_fs.h>
+#include <vlc_preparser.h>
 
 EmbeddedThumbnail::EmbeddedThumbnail( input_attachment_t* a, vlc_fourcc_t fcc )
     : m_attachment( vlc_input_attachment_Hold( a ) )
@@ -88,19 +89,15 @@ std::string EmbeddedThumbnail::extension() const
 MetadataExtractor::MetadataExtractor( vlc_object_t* parent )
     : m_currentCtx( nullptr )
     , m_obj( parent )
+    , m_parser(parent, {
+        .types = VLC_PREPARSER_TYPE_PARSE | VLC_PREPARSER_OPTION_SUBITEMS,
+        .max_parser_threads = 1,
+        .max_thumbnailer_threads = 0,
+        .timeout = VLC_TICK_FROM_SEC(5),
+    })
 {
 }
 
-void MetadataExtractor::onParserEnded( ParseContext& ctx, int status )
-{
-    vlc::threads::mutex_locker lock( ctx.mde->m_mutex );
-
-    // We need to probe the item now, but not from the input thread
-    ctx.success = status == VLC_SUCCESS;
-    ctx.needsProbing = true;
-    ctx.mde->m_cond.signal();
-}
-
 void MetadataExtractor::populateItem( medialibrary::parser::IItem& item, 
input_item_t* inputItem )
 {
     vlc_mutex_locker lock( &inputItem->lock );
@@ -176,22 +173,45 @@ void MetadataExtractor::populateItem( 
medialibrary::parser::IItem& item, input_i
     }
 }
 
-void MetadataExtractor::onParserEnded( input_item_t *, int status, void *data )
+void MetadataExtractor::onParserEnded(vlc_preparser_req *req, int status, void 
*data)
 {
     auto* ctx = static_cast<ParseContext*>( data );
-    ctx->mde->onParserEnded( *ctx, status );
+
+    vlc::threads::mutex_locker lock( ctx->mde->m_mutex );
+    if (status == VLC_SUCCESS) {
+        if (ctx->item.fileType() == medialibrary::IFile::Type::Playlist
+                && ctx->item.nbLinkedItems() == 0) {
+            ctx->status =  medialibrary::parser::Status::Fatal;
+        } else {
+            ctx->mde->populateItem(ctx->item, vlc_preparser_req_GetItem(req));
+            ctx->status = medialibrary::parser::Status::Success;
+        }
+    } else {
+        ctx->status = medialibrary::parser::Status::Fatal;
+    }
+    ctx->done = true;
+    ctx->mde->m_currentCtx = nullptr;
+    ctx->mde->m_cond.broadcast();
+    vlc_preparser_req_Release(req);
 }
 
-void MetadataExtractor::onParserSubtreeAdded( input_item_t *,
+void MetadataExtractor::onParserSubtreeAdded( vlc_preparser_req *,
                                               input_item_node_t *subtree,
                                               void *data )
 {
     auto* ctx = static_cast<ParseContext*>( data );
-    ctx->mde->addSubtree( *ctx, subtree );
+
+    for ( auto i = 0; i < subtree->i_children; ++i )
+    {
+        auto it = subtree->pp_children[i]->p_item;
+        auto& subItem = ctx->item.createLinkedItem( it->psz_uri,
+                                                   
medialibrary::IFile::Type::Main, i );
+        ctx->mde->populateItem( subItem, it );
+    }
     input_item_node_Delete(subtree);
 }
 
-void MetadataExtractor::onAttachmentsAdded( input_item_t *,
+void MetadataExtractor::onAttachmentsAdded( vlc_preparser_req *,
                                             input_attachment_t *const *array,
                                             size_t count, void *data )
 {
@@ -206,77 +226,46 @@ void MetadataExtractor::onAttachmentsAdded( input_item_t 
*,
     }
 }
 
-void MetadataExtractor::addSubtree( ParseContext& ctx, input_item_node_t *root 
)
-{
-    for ( auto i = 0; i < root->i_children; ++i )
-    {
-        auto it = root->pp_children[i]->p_item;
-        auto& subItem = ctx.item.createLinkedItem( it->psz_uri,
-                                                   
medialibrary::IFile::Type::Main, i );
-        populateItem( subItem, it );
-    }
-}
-
 medialibrary::parser::Status MetadataExtractor::run( 
medialibrary::parser::IItem& item )
 {
     ParseContext ctx( this, item );
 
-    ctx.inputItem = {
-        input_item_New( item.mrl().c_str(), NULL ),
-        &input_item_Release
-    };
-    if ( ctx.inputItem == nullptr )
-        return medialibrary::parser::Status::Fatal;
-
-    static const input_item_parser_cbs_t cbs = {
-        &MetadataExtractor::onParserEnded,
-        &MetadataExtractor::onParserSubtreeAdded,
-        &MetadataExtractor::onAttachmentsAdded,
-    };
-
-    const struct input_item_parser_cfg cfg= {
-        .cbs = &cbs,
-        .cbs_data = std::addressof( ctx ),
-        .subitems = true,
-        .interact = false,
-    };
-    m_currentCtx = &ctx;
-    ctx.inputParser = {
-        input_item_Parse( m_obj, ctx.inputItem.get(), &cfg ),
-        &input_item_parser_id_Release
-    };
-    if ( ctx.inputParser == nullptr )
-    {
-        m_currentCtx = nullptr;
+    auto inputItem = vlc::wrap_cptr(input_item_New(item.mrl().c_str(), NULL),
+                                    &input_item_Release);
+    if (inputItem == nullptr)
         return medialibrary::parser::Status::Fatal;
-    }
 
     {
         vlc::threads::mutex_locker lock( m_mutex );
-        auto deadline = vlc_tick_now() + VLC_TICK_FROM_SEC( 5 );
-        while ( ctx.needsProbing == false && ctx.inputParser != nullptr )
+        m_currentCtx = &ctx;
+
+        int options = VLC_PREPARSER_TYPE_PARSE | VLC_PREPARSER_OPTION_SUBITEMS;
+
+        static const struct vlc_preparser_cbs cbs = {
+            .on_ended = onParserEnded,
+            .on_subtree_added = onParserSubtreeAdded,
+            .on_attachments_added = onAttachmentsAdded,
+        };
+
+        vlc_preparser_t *preparser = m_parser.instance();
+        if (preparser == nullptr) {
+            return medialibrary::parser::Status::Fatal;
+        }
+
+        vlc_preparser_req *req = vlc_preparser_Push(preparser,
+                                                   inputItem.get(), options,
+                                                   &cbs, &ctx);
+        if (req == nullptr)
         {
-            auto res = m_cond.timedwait( m_mutex, deadline );
-            if ( res != 0 )
-            {
-                msg_Dbg( m_obj, "Timed out while extracting %s metadata",
-                         item.mrl().c_str() );
-                break;
-            }
+            m_currentCtx = nullptr;
+            return medialibrary::parser::Status::Fatal;
         }
+        while (ctx.done == false)
+            m_cond.wait(m_mutex);
         m_currentCtx = nullptr;
     }
 
-    if ( !ctx.success || ctx.inputParser == nullptr )
-        return medialibrary::parser::Status::Fatal;
-
-    if ( item.fileType() == medialibrary::IFile::Type::Playlist &&
-         item.nbLinkedItems() == 0 )
-        return medialibrary::parser::Status::Fatal;
-
-    populateItem( item, ctx.inputItem.get() );
-
-    return medialibrary::parser::Status::Success;
+    return ctx.status;
 }
 
 const char* MetadataExtractor::name() const
@@ -304,7 +293,18 @@ void MetadataExtractor::onRestarted()
 
 void MetadataExtractor::stop()
 {
-    vlc::threads::mutex_locker lock{ m_mutex };
-    if ( m_currentCtx != nullptr )
-        input_item_parser_id_Interrupt( m_currentCtx->inputParser.get() );
+    vlc_preparser_t *preparser = m_parser.get();
+    if (preparser == nullptr) {
+        return;
+    }
+
+    /* vlc_preparser_Cancel can call the callback from this thread so the mutex
+     * must be unlock */
+    vlc_preparser_Cancel(preparser, nullptr);
+
+    vlc::threads::mutex_locker lock(m_mutex);
+    if (m_currentCtx != nullptr) {
+        while (m_currentCtx != nullptr && m_currentCtx->done == false)
+            m_cond.wait(m_mutex);
+    }
 }


=====================================
modules/misc/medialibrary/Thumbnailer.cpp
=====================================
@@ -34,19 +34,14 @@
 #include <stdexcept>
 
 Thumbnailer::Thumbnailer( vlc_medialibrary_module_t* ml )
-    : m_currentContext( nullptr )
-    , m_thumbnailer( nullptr, &vlc_preparser_Delete )
+    : m_currentContext(nullptr)
+    , m_thumbnailer(VLC_OBJECT(ml), {
+        .types = VLC_PREPARSER_TYPE_THUMBNAIL_TO_FILES,
+        .max_parser_threads = 0,
+        .max_thumbnailer_threads = 1,
+        .timeout = VLC_TICK_FROM_SEC( 3 ),
+    })
 {
-    const struct vlc_preparser_cfg cfg = []{
-        struct vlc_preparser_cfg cfg{};
-        cfg.types = VLC_PREPARSER_TYPE_THUMBNAIL_TO_FILES;
-        cfg.timeout = VLC_TICK_FROM_SEC( 3 );
-        cfg.max_thumbnailer_threads = 1;
-        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" );
 }
 
 void Thumbnailer::onThumbnailToFilesComplete(vlc_preparser_req *req, int ,
@@ -111,8 +106,13 @@ bool Thumbnailer::generate( const medialibrary::IMedia&, 
const std::string& mrl,
             .on_ended = onThumbnailToFilesComplete,
         };
 
+        vlc_preparser_t *thumbnailer = m_thumbnailer.instance();
+        if (thumbnailer == nullptr) {
+            return false;
+        }
+
         vlc_preparser_req *preparserReq;
-        preparserReq = 
vlc_preparser_GenerateThumbnailToFiles(m_thumbnailer.get(),
+        preparserReq = vlc_preparser_GenerateThumbnailToFiles(thumbnailer,
                                                               item.get(),
                                                               &thumb_arg,
                                                               &thumb_out, 1,
@@ -133,9 +133,16 @@ bool Thumbnailer::generate( const medialibrary::IMedia&, 
const std::string& mrl,
 
 void Thumbnailer::stop()
 {
-    vlc_preparser_Cancel(m_thumbnailer.get(), NULL);
+    vlc_preparser_t *thumbnailer = m_thumbnailer.get();
+    if (thumbnailer == nullptr) {
+        return;
+    }
+
+    /* vlc_preparser_Cancel can call the callback from this thread so the mutex
+     * must be unlock */
+    vlc_preparser_Cancel(thumbnailer, nullptr);
 
-    vlc::threads::mutex_locker lock{ m_mutex };
+    vlc::threads::mutex_locker lock(m_mutex);
     if ( m_currentContext != nullptr )
     {
         while (m_currentContext != nullptr && m_currentContext->done == false)


=====================================
modules/misc/medialibrary/fs/directory.cpp
=====================================
@@ -41,10 +41,6 @@
 #include <system_error>
 #include <vector>
 
-using InputItemPtr = ::vlc::vlc_shared_data_ptr<input_item_t,
-                                                &input_item_Hold,
-                                                &input_item_Release>;
-
 namespace vlc {
   namespace medialibrary {
 
@@ -114,7 +110,7 @@ struct metadata_request {
     vlc::threads::mutex lock;
     vlc::threads::condition_variable cond;
     /* results */
-    bool success;
+    int status;
     bool probe;
     std::vector<InputItemPtr> *children;
 };
@@ -124,17 +120,18 @@ struct metadata_request {
 
 extern "C" {
 
-static void onParserEnded( input_item_t *, int status, void *data )
+static void onParserEnded( vlc_preparser_req *preparser_req, int status, void 
*data )
 {
     auto req = static_cast<vlc::medialibrary::metadata_request*>( data );
 
     vlc::threads::mutex_locker lock( req->lock );
-    req->success = status == VLC_SUCCESS;
+    req->status = status;
     req->probe = true;
     req->cond.signal();
+    vlc_preparser_req_Release(preparser_req);
 }
 
-static void onParserSubtreeAdded( input_item_t *, input_item_node_t *subtree,
+static void onParserSubtreeAdded( vlc_preparser_req *, input_item_node_t 
*subtree,
                                   void *data )
 {
     auto req = static_cast<vlc::medialibrary::metadata_request*>( data );
@@ -155,44 +152,41 @@ static void onParserSubtreeAdded( input_item_t *, 
input_item_node_t *subtree,
 namespace vlc {
   namespace medialibrary {
 
-static bool request_metadata_sync( libvlc_int_t *libvlc, input_item_t *media,
-                                   std::vector<InputItemPtr> *out_children )
+bool
+SDDirectory::requestMetadataSync(input_item_t *media,
+                                 std::vector<InputItemPtr> *out_children) const
 {
     metadata_request req;
     req.children = out_children;
     req.probe = false;
-    auto deadline = vlc_tick_now() + VLC_TICK_FROM_SEC( 15 );
 
-    static const input_item_parser_cbs_t cbs = {
+    vlc::threads::mutex_locker lock( req.lock );
+
+    static const struct vlc_preparser_cbs cbs = {
         onParserEnded,
         onParserSubtreeAdded,
         nullptr,
     };
+    int options = VLC_PREPARSER_TYPE_PARSE | VLC_PREPARSER_OPTION_SUBITEMS;
 
-    const struct input_item_parser_cfg cfg= {
-        .cbs = &cbs,
-        .cbs_data = &req,
-        .subitems = true,
-        .interact = false,
-    };
-
-    auto inputParser = vlc::wrap_cptr( input_item_Parse( VLC_OBJECT( libvlc ), 
media, &cfg ),
-                                       &input_item_parser_id_Release );
-
-    if ( inputParser == nullptr )
+    vlc_preparser_t *preparser = m_fs.getPreparser().instance();
+    if (preparser == nullptr) {
         return false;
-
-    vlc::threads::mutex_locker lock( req.lock );
-    while ( req.probe == false )
-    {
-        auto res = req.cond.timedwait( req.lock, deadline );
-        if ( res != 0 )
-        {
+    }
+    vlc_preparser_req *preparser_req = vlc_preparser_Push(preparser,
+                                                          media, options,
+                                                          &cbs, &req);
+    if (preparser_req == nullptr) {
+        return false;
+    }
+    while (req.probe == false) {
+        req.cond.wait(req.lock);
+    }
+    if (req.status == VLC_ETIMEOUT) {
             throw medialibrary::fs::errors::System(
                 ETIMEDOUT, "Failed to browse directory: Operation timed out" );
-        }
     }
-    return req.success;
+    return req.status == VLC_SUCCESS;
 }
 
 void
@@ -208,7 +202,7 @@ SDDirectory::read() const
     input_item_AddOption( media.get(), "show-hiddenfiles", 
VLC_INPUT_OPTION_TRUSTED );
     input_item_AddOption( media.get(), "ignore-filetypes=''", 
VLC_INPUT_OPTION_TRUSTED );
     input_item_AddOption( media.get(), "sub-autodetect-fuzzy=2", 
VLC_INPUT_OPTION_TRUSTED );
-    auto status = request_metadata_sync( m_fs.libvlc(), media.get(), &children 
);
+    auto status = requestMetadataSync( media.get(), &children );
 
     if ( status == false )
         throw medialibrary::fs::errors::System(


=====================================
modules/misc/medialibrary/fs/directory.h
=====================================
@@ -31,6 +31,10 @@ namespace vlc {
 
 using namespace ::medialibrary::fs;
 
+using InputItemPtr = ::vlc::vlc_shared_data_ptr<input_item_t,
+                                                &input_item_Hold,
+                                                &input_item_Release>;
+
 class SDDirectory : public IDirectory
 {
 public:
@@ -43,6 +47,7 @@ public:
     bool contains( const std::string& file ) const override;
 
 private:
+    bool requestMetadataSync(input_item_t *media, std::vector<InputItemPtr> 
*out_children) const;
     void read() const;
     void addFile( std::string mrl, fs::IFile::LinkedFileType, std::string 
linkedWith ) const;
 


=====================================
modules/misc/medialibrary/fs/fs.cpp
=====================================
@@ -43,6 +43,12 @@ SDFileSystemFactory::SDFileSystemFactory(vlc_object_t 
*parent,
     : m_parent(parent)
     , m_scheme(scheme)
     , m_callbacks( nullptr )
+    , m_parser(parent, {
+        .types = VLC_PREPARSER_TYPE_PARSE,
+        .max_parser_threads = 1,
+        .max_thumbnailer_threads = 0,
+        .timeout = VLC_TICK_FROM_SEC(15),
+    })
 {
     m_isNetwork = strncasecmp( m_scheme.c_str(), "file://",
                                m_scheme.length() ) != 0;
@@ -133,6 +139,13 @@ SDFileSystemFactory::libvlc() const
     return vlc_object_instance(m_parent);
 }
 
+LazyPreparser&
+SDFileSystemFactory::getPreparser()
+{
+    vlc::threads::mutex_locker lock(m_mutex);
+    return m_parser;
+}
+
 void SDFileSystemFactory::onDeviceMounted(const std::string& uuid,
                                           const std::string& mountpoint,
                                           bool removable)


=====================================
modules/misc/medialibrary/fs/fs.h
=====================================
@@ -25,10 +25,14 @@
 #include <vector>
 #include <vlc_common.h>
 #include <vlc_threads.h>
+#include <vlc_preparser.h>
 #include <vlc_cxx_helpers.hpp>
+
 #include <medialibrary/filesystem/IFileSystemFactory.h>
 #include <medialibrary/IDeviceLister.h>
 
+#include "../LazyPreparser.h"
+
 struct libvlc_int_t;
 
 namespace medialibrary {
@@ -92,6 +96,9 @@ public:
     bool
     waitForDevice(const std::string& mrl, uint32_t timeout) const override;
 
+    LazyPreparser&
+    getPreparser();
+
 private:
     std::shared_ptr<fs::IDevice>
     deviceByUuid(const std::string& uuid);
@@ -110,6 +117,8 @@ private:
     mutable vlc::threads::condition_variable m_cond;
     std::vector<std::shared_ptr<IDevice>> m_devices;
     std::shared_ptr<IDeviceLister> m_deviceLister;
+
+    LazyPreparser m_parser;
 };
 
   } /* namespace medialibrary */


=====================================
modules/misc/medialibrary/medialibrary.h
=====================================
@@ -39,6 +39,8 @@
 #include <cstdarg>
 #include <type_traits>
 
+#include "LazyPreparser.h"
+
 struct vlc_event_t;
 struct vlc_object_t;
 struct vlc_preparser_t;
@@ -65,23 +67,16 @@ private:
     struct ParseContext
     {
         ParseContext( MetadataExtractor* mde, medialibrary::parser::IItem& 
item )
-            : needsProbing( false )
-            , success( false )
+            : status( medialibrary::parser::Status::Fatal )
+            , done( false )
             , mde( mde )
             , item( item )
-            , inputItem( nullptr, &input_item_Release )
-            , inputParser( nullptr, &input_item_parser_id_Release )
         {
         }
-
-        bool needsProbing;
-        bool success;
+        medialibrary::parser::Status status;
+        bool done;
         MetadataExtractor* mde;
         medialibrary::parser::IItem& item;
-        std::unique_ptr<input_item_t, decltype(&input_item_Release)> inputItem;
-        // Needs to be last to be destroyed first, otherwise a late callback
-        // could use some already destroyed fields
-        std::unique_ptr<input_item_parser_id_t, 
decltype(&input_item_parser_id_Release)> inputParser;
     };
 
 public:
@@ -99,14 +94,12 @@ private:
     void onRestarted() override;
     void stop() override;
 
-    void onParserEnded( ParseContext& ctx, int status );
-    void addSubtree( ParseContext& ctx, input_item_node_t *root );
     void populateItem( medialibrary::parser::IItem& item, input_item_t* 
inputItem );
 
-    static void onParserEnded( input_item_t *, int status, void *user_data );
-    static void onParserSubtreeAdded( input_item_t *, input_item_node_t 
*subtree,
+    static void onParserEnded(vlc_preparser_req *, int status, void 
*user_data);
+    static void onParserSubtreeAdded( vlc_preparser_req *, input_item_node_t 
*subtree,
                                       void *user_data );
-    static void onAttachmentsAdded( input_item_t *,
+    static void onAttachmentsAdded( vlc_preparser_req *,
                                     input_attachment_t *const *array,
                                     size_t count, void *data );
 
@@ -115,6 +108,7 @@ private:
     vlc::threads::mutex m_mutex;
     ParseContext* m_currentCtx;
     vlc_object_t* m_obj;
+    LazyPreparser m_parser;
 };
 
 class Thumbnailer : public medialibrary::IThumbnailer
@@ -142,7 +136,7 @@ private:
     vlc::threads::mutex m_mutex;
     vlc::threads::condition_variable m_cond;
     ThumbnailerCtx* m_currentContext;
-    std::unique_ptr<vlc_preparser_t, void(*)(vlc_preparser_t*)> m_thumbnailer;
+    LazyPreparser m_thumbnailer;
 };
 
 class MediaLibrary : public medialibrary::IMediaLibraryCb



View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/2ef92b2aefcab1b4aa14a8a54d7321b6e2ac60ac...8a18772682564dc9ae038ba6adb522ee4752c888

-- 
View it on GitLab: 
https://code.videolan.org/videolan/vlc/-/compare/2ef92b2aefcab1b4aa14a8a54d7321b6e2ac60ac...8a18772682564dc9ae038ba6adb522ee4752c888
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance
_______________________________________________
vlc-commits mailing list
[email protected]
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to