[vlc-devel] [PATCH 4/4] medialibrary: Bump version & update API usages
Thomas Guillem
thomas at gllm.fr
Tue Jun 25 20:36:14 CEST 2019
On Tue, Jun 25, 2019, at 16:04, Hugo Beauzée-Luyssen wrote:
> - Multiple thumbnail can now be used
> - Discovery, thumbnailing & metadata extractions are now interruptible
> - An entry_point_added event has been added
>
> --
> Appologies for the big commit, but splitting it in multiple chunk would
> break incremental build
No version check in configure.ac ?
> ---
> contrib/src/medialibrary/rules.mak | 2 +-
I think we generally split contrib commits, even if it break incremental build on some build bot configuration.
Otherwise, OK for the set.
> include/vlc_media_library.h | 62 +++++++++++++----
> .../gui/qt/components/mediacenter/mlalbum.cpp | 2 +-
> .../qt/components/mediacenter/mlartist.cpp | 2 +-
> .../gui/qt/components/mediacenter/mlvideo.cpp | 13 ++--
> .../misc/medialibrary/MetadataExtractor.cpp | 30 ++++----
> modules/misc/medialibrary/Thumbnailer.cpp | 67 +++++++++---------
> modules/misc/medialibrary/entities.cpp | 68 ++++++++++++-------
> modules/misc/medialibrary/medialib.cpp | 31 +++++++--
> modules/misc/medialibrary/medialibrary.h | 39 +++++++++--
> src/misc/medialibrary.c | 12 +++-
> 11 files changed, 221 insertions(+), 107 deletions(-)
>
> diff --git a/contrib/src/medialibrary/rules.mak
> b/contrib/src/medialibrary/rules.mak
> index 799f9b6db5..e9d5359f97 100644
> --- a/contrib/src/medialibrary/rules.mak
> +++ b/contrib/src/medialibrary/rules.mak
> @@ -1,4 +1,4 @@
> -MEDIALIBRARY_HASH := 60073666abbd5f604dddbfd600968bac7f94cd5e
> +MEDIALIBRARY_HASH := d92baf8033c72f687d9853a483d27a70fd4e196e
> MEDIALIBRARY_VERSION := git-$(MEDIALIBRARY_HASH)
> MEDIALIBRARY_GITURL :=
> https://code.videolan.org/videolan/medialibrary.git
>
> diff --git a/include/vlc_media_library.h b/include/vlc_media_library.h
> index 6d2d39d0a0..e6205f31ca 100644
> --- a/include/vlc_media_library.h
> +++ b/include/vlc_media_library.h
> @@ -68,6 +68,24 @@ typedef enum vlc_ml_track_type_t
> VLC_ML_TRACK_TYPE_AUDIO,
> } vlc_ml_track_type_t;
>
> +typedef enum vlc_ml_thumbnail_size_t
> +{
> + VLC_ML_THUMBNAIL_SMALL,
> + VLC_ML_THUMBNAIL_BANNER,
> +
> + VLC_ML_THUMBNAIL_SIZE_COUNT
> +} vlc_ml_thumbnail_size_t;
> +
> +typedef struct vlc_ml_thumbnail_t
> +{
> + char* psz_mrl;
> + /**
> + * True if a thumbnail is available, or if thumbnail generation was
> + * attempted but failed
> + */
> + bool b_generated;
> +} vlc_ml_thumbnail_t;
> +
> typedef struct vlc_ml_movie_t
> {
> char* psz_summary;
> @@ -182,10 +200,8 @@ typedef struct vlc_ml_media_t
> time_t i_last_played_date;
> char* psz_title;
>
> - char* psz_artwork_mrl;
> - /* True if a thumbnail is available, or if thumbnail generation was
> - * attempted but failed */
> - bool b_artwork_generated;
> + vlc_ml_thumbnail_t thumbnails[VLC_ML_THUMBNAIL_SIZE_COUNT];
> +
> bool b_is_favorite;
>
> union
> @@ -209,7 +225,7 @@ typedef struct vlc_ml_artist_t
> int64_t i_id;
> char* psz_name;
> char* psz_shortbio;
> - char* psz_artwork_mrl;
> + vlc_ml_thumbnail_t thumbnails[VLC_ML_THUMBNAIL_SIZE_COUNT];
> char* psz_mb_id;
>
> unsigned int i_nb_album;
> @@ -226,7 +242,7 @@ typedef struct vlc_ml_album_t {
> int64_t i_id;
> char* psz_title;
> char* psz_summary;
> - char* psz_artwork_mrl;
> + vlc_ml_thumbnail_t thumbnails[VLC_ML_THUMBNAIL_SIZE_COUNT];
> char* psz_artist;
> int64_t i_artist_id;
>
> @@ -439,8 +455,8 @@ enum vlc_ml_control
> VLC_ML_MEDIA_INCREASE_PLAY_COUNT, /**< arg1: media id; can
> fail */
> VLC_ML_MEDIA_GET_MEDIA_PLAYBACK_PREF, /**< arg1: media id; arg2:
> vlc_ml_playback_pref; arg3: char**; */
> VLC_ML_MEDIA_SET_MEDIA_PLAYBACK_PREF, /**< arg1: media id; arg2:
> vlc_ml_playback_pref; arg3: const char*; */
> - VLC_ML_MEDIA_SET_THUMBNAIL, /**< arg1: media id; arg2:
> const char*; */
> - VLC_ML_MEDIA_GENERATE_THUMBNAIL, /**< arg1: media id; */
> + VLC_ML_MEDIA_SET_THUMBNAIL, /**< arg1: media id; arg2:
> const char*; arg3: vlc_ml_thumbnail_size_t */
> + VLC_ML_MEDIA_GENERATE_THUMBNAIL, /**< arg1: media id; arg2:
> vlc_ml_thumbnail_size_t; arg3: width; arg4: height; arg5: position */
> VLC_ML_MEDIA_ADD_EXTERNAL_MRL, /**< arg1: media id; arg2:
> const char*; arg3: type(vlc_ml_file_type_t) */
> };
>
> @@ -542,6 +558,16 @@ enum vlc_ml_event_type
> * vlc_ml_event_t::reload_completed::b_success
> */
> VLC_ML_EVENT_RELOAD_COMPLETED,
> + /**
> + * Sent when a new entry point gets added to the database.
> + * The entry point that was added is stored in
> + * vlc::ml_event_t::entry_point_added::psz_entry_point, and the
> success or failure
> + * state is stored in vlc_ml_event_t::entry_point_added::b_success
> + * If successful, this event won't be emited again for this entry
> point.
> + * In case of failure, this event will be fired again if the same
> entry point
> + * is queued for discovery again.
> + */
> + VLC_ML_EVENT_ENTRY_POINT_ADDED,
> /**
> * Sent when an entry point removal request has been processed.
> * The removed entry point is stored in
> @@ -615,6 +641,11 @@ typedef struct vlc_ml_event_t
> bool b_success;
> } reload_completed;
> struct
> + {
> + const char* psz_entry_point;
> + bool b_success;
> + } entry_point_added;
> + struct
> {
> const char* psz_entry_point;
> bool b_success;
> @@ -652,6 +683,7 @@ typedef struct vlc_ml_event_t
> struct
> {
> const vlc_ml_media_t* p_media;
> + vlc_ml_thumbnail_size_t i_size;
> bool b_success;
> } media_thumbnail_generated;
> };
> @@ -848,14 +880,20 @@ static inline int vlc_ml_media_set_playback_pref(
> vlc_medialibrary_t* p_ml, int6
> return vlc_ml_control( p_ml, VLC_ML_MEDIA_SET_MEDIA_PLAYBACK_PREF,
> i_media_id, i_pref, psz_value );
> }
>
> -static inline int vlc_ml_media_set_thumbnail( vlc_medialibrary_t*
> p_ml, int64_t i_media_id, const char* psz_mrl )
> +static inline int vlc_ml_media_set_thumbnail( vlc_medialibrary_t*
> p_ml, int64_t i_media_id,
> + const char* psz_mrl,
> vlc_ml_thumbnail_size_t sizeType )
> {
> - return vlc_ml_control( p_ml, VLC_ML_MEDIA_SET_THUMBNAIL,
> i_media_id, psz_mrl );
> + return vlc_ml_control( p_ml, VLC_ML_MEDIA_SET_THUMBNAIL,
> i_media_id, psz_mrl, sizeType );
> }
>
> -static inline int vlc_ml_media_generate_thumbnail( vlc_medialibrary_t*
> p_ml, int64_t i_media_id )
> +static inline int vlc_ml_media_generate_thumbnail( vlc_medialibrary_t*
> p_ml, int64_t i_media_id,
> +
> vlc_ml_thumbnail_size_t size_type,
> + uint32_t
> i_desired_width,
> + uint32_t
> i_desired_height,
> + float position )
> {
> - return vlc_ml_control( p_ml, VLC_ML_MEDIA_GENERATE_THUMBNAIL,
> i_media_id );
> + return vlc_ml_control( p_ml, VLC_ML_MEDIA_GENERATE_THUMBNAIL,
> i_media_id,
> + size_type, i_desired_width,
> i_desired_height, position );
> }
>
> static inline int vlc_ml_media_add_external_mrl( vlc_medialibrary_t*
> p_ml, int64_t i_media_id,
> diff --git a/modules/gui/qt/components/mediacenter/mlalbum.cpp
> b/modules/gui/qt/components/mediacenter/mlalbum.cpp
> index 271133f8f8..88df4f034a 100644
> --- a/modules/gui/qt/components/mediacenter/mlalbum.cpp
> +++ b/modules/gui/qt/components/mediacenter/mlalbum.cpp
> @@ -25,7 +25,7 @@ MLAlbum::MLAlbum(vlc_medialibrary_t* _ml, const
> vlc_ml_album_t *_data, QObject *
> , m_title ( QString::fromUtf8( _data->psz_title ) )
> , m_releaseYear ( _data->i_year )
> , m_shortSummary( QString::fromUtf8( _data->psz_summary ) )
> - , m_cover ( QString::fromUtf8( _data->psz_artwork_mrl ) )
> + , m_cover ( QString::fromUtf8(
> _data->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl ) )
> , m_mainArtist ( QString::fromUtf8( _data->psz_artist ) )
> , m_nbTracks ( _data->i_nb_tracks )
> {
> diff --git a/modules/gui/qt/components/mediacenter/mlartist.cpp
> b/modules/gui/qt/components/mediacenter/mlartist.cpp
> index bf4e2ee2a7..98a6b0b96b 100644
> --- a/modules/gui/qt/components/mediacenter/mlartist.cpp
> +++ b/modules/gui/qt/components/mediacenter/mlartist.cpp
> @@ -24,7 +24,7 @@ MLArtist::MLArtist(const vlc_ml_artist_t* _data,
> QObject *_parent)
> , m_id ( _data->i_id, VLC_ML_PARENT_ARTIST )
> , m_name ( QString::fromUtf8( _data->psz_name ) )
> , m_shortBio( QString::fromUtf8( _data->psz_shortbio ) )
> - , m_cover ( QString::fromUtf8( _data->psz_artwork_mrl ) )
> + , m_cover ( QString::fromUtf8(
> _data->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl ) )
> , m_nbAlbums( _data->i_nb_album )
> {
> assert( _data );
> diff --git a/modules/gui/qt/components/mediacenter/mlvideo.cpp
> b/modules/gui/qt/components/mediacenter/mlvideo.cpp
> index 84190f6ad7..4305327be0 100644
> --- a/modules/gui/qt/components/mediacenter/mlvideo.cpp
> +++ b/modules/gui/qt/components/mediacenter/mlvideo.cpp
> @@ -27,9 +27,9 @@ MLVideo::MLVideo(vlc_medialibrary_t* ml, const
> vlc_ml_media_t* data, QObject* pa
> , m_ml( ml )
> , m_id( data->i_id, VLC_ML_PARENT_UNKNOWN )
> , m_title( QString::fromUtf8( data->psz_title ) )
> - , m_thumbnail( QString::fromUtf8( data->psz_artwork_mrl ) )
> + , m_thumbnail( QString::fromUtf8(
> data->thumbnails[VLC_ML_THUMBNAIL_SMALL].psz_mrl ) )
> , m_playCount( data->i_playcount )
> - , m_thumbnailGenerated( data->b_artwork_generated )
> + , m_thumbnailGenerated(
> data->thumbnails[VLC_ML_THUMBNAIL_SMALL].b_generated )
> , m_ml_event_handle( nullptr, [this](vlc_ml_event_callback_t* cb )
> {
> assert( m_ml != nullptr );
> vlc_ml_event_unregister_callback( m_ml, cb );
> @@ -88,14 +88,16 @@ void MLVideo::onMlEvent( void* data, const
> vlc_ml_event_t* event )
>
> void MLVideo::onMlEvent( const vlc_ml_event_t* event )
> {
> - if ( event->i_type != VLC_ML_EVENT_MEDIA_THUMBNAIL_GENERATED )
> + if ( event->i_type != VLC_ML_EVENT_MEDIA_THUMBNAIL_GENERATED ||
> + event->media_thumbnail_generated.i_size !=
> VLC_ML_THUMBNAIL_SMALL )
> return;
> m_thumbnailGenerated = true;
> if ( event->media_thumbnail_generated.p_media->i_id != m_id.id )
> return;
> if ( event->media_thumbnail_generated.b_success == false )
> return;
> - auto thumbnailMrl =
> event->media_thumbnail_generated.p_media->psz_artwork_mrl;
> + auto thumbnailMrl = event->media_thumbnail_generated
> +
> .p_media->thumbnails[event->media_thumbnail_generated.i_size].psz_mrl;
> m_thumbnail = QString::fromUtf8( thumbnailMrl );
> vlc_ml_event_unregister_from_callback( m_ml,
> m_ml_event_handle.release() );
> emit onThumbnailChanged( m_thumbnail );
> @@ -116,7 +118,8 @@ QString MLVideo::getThumbnail()
> if ( m_thumbnailGenerated == false )
> {
> m_ml_event_handle.reset( vlc_ml_event_register_callback( m_ml,
> onMlEvent, this ) );
> - vlc_ml_media_generate_thumbnail( m_ml, m_id.id );
> + vlc_ml_media_generate_thumbnail( m_ml, m_id.id,
> VLC_ML_THUMBNAIL_SMALL,
> + 512, 320, .15 );
> }
>
> return m_thumbnail;
> diff --git a/modules/misc/medialibrary/MetadataExtractor.cpp
> b/modules/misc/medialibrary/MetadataExtractor.cpp
> index 7348ab3be3..0047b7b0fc 100644
> --- a/modules/misc/medialibrary/MetadataExtractor.cpp
> +++ b/modules/misc/medialibrary/MetadataExtractor.cpp
> @@ -31,12 +31,12 @@ MetadataExtractor::MetadataExtractor( vlc_object_t*
> parent )
>
> void MetadataExtractor::onParserEnded( ParseContext& ctx, int status )
> {
> - vlc::threads::mutex_locker lock( ctx.m_mutex );
> + 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.m_cond.signal();
> + ctx.mde->m_cond.signal();
> }
>
> void MetadataExtractor::populateItem( medialibrary::parser::IItem&
> item, input_item_t* inputItem )
> @@ -150,7 +150,7 @@ medialibrary::parser::Status
> MetadataExtractor::run( medialibrary::parser::IItem
> &MetadataExtractor::onParserEnded,
> &MetadataExtractor::onParserSubtreeAdded,
> };
> -
> + m_currentCtx = &ctx;
> ctx.inputItem->i_preparse_depth = 1;
> ctx.inputParser = {
> input_item_Parse( ctx.inputItem.get(), m_obj, &cbs,
> @@ -158,14 +158,17 @@ medialibrary::parser::Status
> MetadataExtractor::run( medialibrary::parser::IItem
> &input_item_parser_id_Release
> };
> if ( ctx.inputParser == nullptr )
> + {
> + m_currentCtx = nullptr;
> return medialibrary::parser::Status::Fatal;
> + }
>
> {
> - vlc::threads::mutex_locker lock( ctx.m_mutex );
> + vlc::threads::mutex_locker lock( m_mutex );
> auto deadline = vlc_tick_now() + VLC_TICK_FROM_SEC( 5 );
> - while ( ctx.needsProbing == false )
> + while ( ctx.needsProbing == false && ctx.inputParser !=
> nullptr )
> {
> - auto res = ctx.m_cond.timedwait( ctx.m_mutex, deadline );
> + auto res = m_cond.timedwait( m_mutex, deadline );
> if ( res != 0 )
> {
> msg_Dbg( m_obj, "Timed out while extracting %s
> metadata",
> @@ -173,9 +176,10 @@ medialibrary::parser::Status
> MetadataExtractor::run( medialibrary::parser::IItem
> break;
> }
> }
> + m_currentCtx = nullptr;
> }
>
> - if ( !ctx.success )
> + if ( !ctx.success || ctx.inputParser == nullptr )
> return medialibrary::parser::Status::Fatal;
>
> populateItem( item, ctx.inputItem.get() );
> @@ -188,11 +192,6 @@ const char* MetadataExtractor::name() const
> return "libvlccore extraction";
> }
>
> -uint8_t MetadataExtractor::nbThreads() const
> -{
> - return 1;
> -}
> -
> medialibrary::parser::Step MetadataExtractor::targetedStep() const
> {
> return medialibrary::parser::Step::MetadataExtraction;
> @@ -210,3 +209,10 @@ void MetadataExtractor::onFlushing()
> 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() );
> +}
> diff --git a/modules/misc/medialibrary/Thumbnailer.cpp
> b/modules/misc/medialibrary/Thumbnailer.cpp
> index 33d90732cd..c96dbc9769 100644
> --- a/modules/misc/medialibrary/Thumbnailer.cpp
> +++ b/modules/misc/medialibrary/Thumbnailer.cpp
> @@ -30,9 +30,8 @@
> #include <vlc_url.h>
> #include <vlc_cxx_helpers.hpp>
>
> -Thumbnailer::Thumbnailer( vlc_medialibrary_module_t* ml, std::string
> thumbnailsDir )
> +Thumbnailer::Thumbnailer( vlc_medialibrary_module_t* ml )
> : m_ml( ml )
> - , m_thumbnailDir( std::move( thumbnailsDir ) )
> , m_thumbnailer( nullptr, &vlc_thumbnailer_Release )
> {
> m_thumbnailer.reset( vlc_thumbnailer_Create( VLC_OBJECT( ml ) ) );
> @@ -40,71 +39,67 @@ Thumbnailer::Thumbnailer(
> vlc_medialibrary_module_t* ml, std::string thumbnailsD
> throw std::runtime_error( "Failed to instantiate a
> vlc_thumbnailer_t" );
> }
>
> -struct ThumbnailerCtx
> -{
> - ~ThumbnailerCtx()
> - {
> - if ( item != nullptr )
> - input_item_Release( item );
> - if ( thumbnail != nullptr )
> - picture_Release( thumbnail );
> - }
> - vlc::threads::condition_variable cond;
> - vlc::threads::mutex mutex;
> - input_item_t* item;
> - bool done;
> - picture_t* thumbnail;
> -};
> -
> -static void onThumbnailComplete( void* data, picture_t* thumbnail )
> +void Thumbnailer::onThumbnailComplete( void* data, picture_t* thumbnail )
> {
> ThumbnailerCtx* ctx = static_cast<ThumbnailerCtx*>( data );
>
> {
> - vlc::threads::mutex_locker lock( ctx->mutex );
> + vlc::threads::mutex_locker lock( ctx->thumbnailer->m_mutex );
> ctx->done = true;
> ctx->thumbnail = thumbnail ? picture_Hold( thumbnail ) : nullptr;
> + ctx->thumbnailer->m_currentContext = nullptr;
> }
> - ctx->cond.signal();
> + ctx->thumbnailer->m_cond.signal();
> }
>
> -bool Thumbnailer::generate( medialibrary::MediaPtr media, const
> std::string& mrl )
> +bool Thumbnailer::generate( const std::string& mrl, uint32_t
> desiredWidth,
> + uint32_t desiredHeight, float position,
> + const std::string& dest )
> {
> ThumbnailerCtx ctx{};
> - ctx.item = input_item_New( mrl.c_str(), media->title().c_str() );
> - if ( unlikely( ctx.item == nullptr ) )
> + auto item = vlc::wrap_cptr( input_item_New( mrl.c_str(), nullptr ),
> + &input_item_Release );
> + if ( unlikely( item == nullptr ) )
> return false;
>
> - input_item_AddOption( ctx.item, "no-hwdec",
> VLC_INPUT_OPTION_TRUSTED );
> + input_item_AddOption( item.get(), "no-hwdec",
> VLC_INPUT_OPTION_TRUSTED );
> ctx.done = false;
> {
> - vlc::threads::mutex_locker lock( ctx.mutex );
> - vlc_thumbnailer_RequestByPos( m_thumbnailer.get(), .3f,
> - VLC_THUMBNAILER_SEEK_FAST,
> ctx.item,
> + vlc::threads::mutex_locker lock( m_mutex );
> + m_currentContext = &ctx;
> + ctx.request = vlc_thumbnailer_RequestByPos(
> m_thumbnailer.get(), position,
> + VLC_THUMBNAILER_SEEK_FAST,
> item.get(),
> VLC_TICK_FROM_SEC( 3 ),
> &onThumbnailComplete, &ctx );
>
> while ( ctx.done == false )
> - ctx.cond.wait( ctx.mutex );
> + m_cond.wait( m_mutex );
> + m_currentContext = nullptr;
> }
> if ( ctx.thumbnail == nullptr )
> return false;
>
> block_t* block;
> if ( picture_Export( VLC_OBJECT( m_ml ), &block, nullptr,
> ctx.thumbnail,
> - VLC_CODEC_JPEG, 512, 320, true ) !=
> VLC_SUCCESS )
> + VLC_CODEC_JPEG, desiredWidth, desiredHeight,
> true ) != VLC_SUCCESS )
> return false;
> auto blockPtr = vlc::wrap_cptr( block, &block_Release );
>
> - std::string outputPath = m_thumbnailDir + std::to_string(
> media->id() ) + ".jpg";
> - auto f = vlc::wrap_cptr( vlc_fopen( outputPath.c_str(), "wb" ),
> &fclose );
> + auto f = vlc::wrap_cptr( vlc_fopen( dest.c_str(), "wb" ), &fclose
> );
> if ( f == nullptr )
> return false;
> if ( fwrite( block->p_buffer, block->i_buffer, 1, f.get() ) != 1 )
> return false;
> - auto thumbnailMrl = vlc::wrap_cptr( vlc_path2uri(
> outputPath.c_str(), nullptr ) );
> - if ( thumbnailMrl == nullptr )
> - return false;
> + return true;
> +}
>
> - return media->setThumbnail( thumbnailMrl.get() );
> +void Thumbnailer::stop()
> +{
> + vlc::threads::mutex_locker lock{ m_mutex };
> + if ( m_currentContext != nullptr )
> + {
> + vlc_thumbnailer_Cancel( m_thumbnailer.get(),
> m_currentContext->request );
> + m_currentContext->done = true;
> + m_cond.signal();
> + }
> }
> diff --git a/modules/misc/medialibrary/entities.cpp
> b/modules/misc/medialibrary/entities.cpp
> index ecbf9396cd..35975c8ab7 100644
> --- a/modules/misc/medialibrary/entities.cpp
> +++ b/modules/misc/medialibrary/entities.cpp
> @@ -50,6 +50,40 @@ static auto const strdup_helper = []( std::string
> const& src, char*& dst )
> return true;
> };
>
> +static_assert( static_cast<uint32_t>( VLC_ML_THUMBNAIL_SMALL ) ==
> + static_cast<uint32_t>(
> medialibrary::ThumbnailSizeType::Thumbnail ) &&
> + static_cast<uint32_t>( VLC_ML_THUMBNAIL_BANNER ) ==
> + static_cast<uint32_t>(
> medialibrary::ThumbnailSizeType::Banner ) &&
> + static_cast<uint32_t>( VLC_ML_THUMBNAIL_SIZE_COUNT ) ==
> + static_cast<uint32_t>(
> medialibrary::ThumbnailSizeType::Count ),
> + "Mismatched thumbnail sizes" );
> +
> +template <typename T>
> +static bool convertThumbnails( const T input, vlc_ml_thumbnail_t
> *output )
> +{
> + for ( auto i = 0u; i < VLC_ML_THUMBNAIL_SIZE_COUNT; ++i )
> + {
> + auto sizeType = static_cast<medialibrary::ThumbnailSizeType>(
> i );
> + if ( input->isThumbnailGenerated( sizeType ) == false )
> + {
> + output[i].psz_mrl = nullptr;
> + output[i].b_generated = false;
> + continue;
> + }
> + output[i].b_generated = true;
> + const auto thumbnailMrl = input->thumbnailMrl( sizeType );
> + if ( thumbnailMrl.empty() == false )
> + {
> + output[i].psz_mrl = strdup( thumbnailMrl.c_str() );
> + if ( output[i].psz_mrl == nullptr )
> + return false;
> + }
> + else
> + output[i].psz_mrl = nullptr;
> + }
> + return true;
> +}
> +
> bool Convert( const medialibrary::IAlbumTrack* input,
> vlc_ml_album_track_t& output )
> {
> output.i_artist_id = input->artistId();
> @@ -218,24 +252,8 @@ bool Convert( const medialibrary::IMedia* input,
> vlc_ml_media_t& output )
> if ( convertTracks( input, output ) == false )
> return false;
>
> - if ( input->isThumbnailGenerated() == true )
> - {
> - output.b_artwork_generated = true;
> - const auto& thumbnail = input->thumbnail();
> - if ( thumbnail.empty() == true )
> - output.psz_artwork_mrl = nullptr;
> - else
> - {
> - output.psz_artwork_mrl = strdup( thumbnail.c_str() );
> - if ( unlikely( output.psz_artwork_mrl == nullptr ) )
> - return false;
> - }
> - }
> - else
> - {
> - output.psz_artwork_mrl = nullptr;
> - output.b_artwork_generated = false;
> - }
> + if ( convertThumbnails( input, output.thumbnails ) == false )
> + return false;
>
> return true;
> }
> @@ -288,8 +306,10 @@ bool Convert( const medialibrary::IAlbum* input,
> vlc_ml_album_t& output )
> output.i_year = input->releaseYear();
>
> if( !strdup_helper( input->title(), output.psz_title ) ||
> - !strdup_helper( input->shortSummary(), output.psz_summary ) ||
> - !strdup_helper( input->thumbnailMrl(), output.psz_artwork_mrl ) )
> + !strdup_helper( input->shortSummary(), output.psz_summary ) )
> + return false;
> +
> + if ( convertThumbnails( input, output.thumbnails ) == false )
> return false;
>
> auto artist = input->albumArtist();
> @@ -337,10 +357,10 @@ bool Convert( const medialibrary::IArtist* input,
> vlc_ml_artist_t& output )
> return false;
>
> if( !strdup_helper( input->shortBio(), output.psz_shortbio ) ||
> - !strdup_helper( input->thumbnailMrl(), output.psz_artwork_mrl ) ||
> !strdup_helper( input->musicBrainzId(), output.psz_mb_id ) )
> return false;
> - return true;
> +
> + return convertThumbnails( input, output.thumbnails );
> }
>
> bool Convert( const medialibrary::IGenre* input, vlc_ml_genre_t&
> output )
> @@ -423,9 +443,9 @@ input_item_t* MediaToInputItem( const
> medialibrary::IMedia* media )
> VLC_TICK_FROM_MS( media->duration()
> ),
> ITEM_TYPE_FILE, ITEM_NET_UNKNOWN ),
> &input_item_Release );
> - if ( media->isThumbnailGenerated() == true )
> + if ( media->isThumbnailGenerated(
> medialibrary::ThumbnailSizeType::Thumbnail ) == true )
> {
> - auto thumbnail = media->thumbnail();
> + auto thumbnail = media->thumbnailMrl(
> medialibrary::ThumbnailSizeType::Thumbnail );
> if ( thumbnail.length() > 0 )
> input_item_SetArtworkURL( inputItem.get(),
> thumbnail.c_str() );
> }
> diff --git a/modules/misc/medialibrary/medialib.cpp
> b/modules/misc/medialibrary/medialib.cpp
> index c518bc9c4b..f19579d14f 100644
> --- a/modules/misc/medialibrary/medialib.cpp
> +++ b/modules/misc/medialibrary/medialib.cpp
> @@ -63,6 +63,10 @@ private:
> {
> msg_Dbg( m_obj, "%s", msg.c_str() );
> }
> + virtual void Verbose( const std::string& msg ) override
> + {
> + msg_Dbg( m_obj, "%s", msg.c_str() );
> + }
>
> private:
> vlc_object_t* m_obj;
> @@ -227,6 +231,15 @@ void MediaLibrary::onReloadCompleted( const
> std::string& entryPoint, bool succes
> m_vlc_ml->cbs->pf_send_event( m_vlc_ml, &ev );
> }
>
> +void MediaLibrary::onEntryPointAdded( const std::string& entryPoint,
> bool success )
> +{
> + vlc_ml_event_t ev;
> + ev.i_type = VLC_ML_EVENT_ENTRY_POINT_ADDED;
> + ev.entry_point_added.psz_entry_point = entryPoint.c_str();
> + ev.entry_point_added.b_success = success;
> + m_vlc_ml->cbs->pf_send_event( m_vlc_ml, &ev );
> +}
> +
> void MediaLibrary::onEntryPointRemoved( const std::string& entryPoint,
> bool success )
> {
> vlc_ml_event_t ev;
> @@ -270,11 +283,14 @@ void MediaLibrary::onBackgroundTasksIdleChanged(
> bool idle )
> m_vlc_ml->cbs->pf_send_event( m_vlc_ml, &ev );
> }
>
> -void MediaLibrary::onMediaThumbnailReady( medialibrary::MediaPtr
> media, bool success )
> +void MediaLibrary::onMediaThumbnailReady( medialibrary::MediaPtr media,
> +
> medialibrary::ThumbnailSizeType sizeType,
> + bool success )
> {
> vlc_ml_event_t ev;
> ev.i_type = VLC_ML_EVENT_MEDIA_THUMBNAIL_GENERATED;
> ev.media_thumbnail_generated.b_success = success;
> + ev.media_thumbnail_generated.i_size =
> static_cast<vlc_ml_thumbnail_size_t>( sizeType );
> auto mPtr = vlc::wrap_cptr<vlc_ml_media_t>(
> static_cast<vlc_ml_media_t*>( malloc( sizeof(
> vlc_ml_media_t ) ) ),
> vlc_ml_media_release );
> @@ -327,8 +343,7 @@ bool MediaLibrary::Start()
> ml->addParserService( std::make_shared<MetadataExtractor>(
> VLC_OBJECT( m_vlc_ml ) ) );
> try
> {
> - ml->addThumbnailer( std::make_shared<Thumbnailer>(
> - m_vlc_ml, std::move( thumbnailsDir ) )
> );
> + ml->addThumbnailer( std::make_shared<Thumbnailer>( m_vlc_ml )
> );
> }
> catch ( const std::runtime_error& ex )
> {
> @@ -966,12 +981,18 @@ int MediaLibrary::controlMedia( int query,
> va_list args )
> case VLC_ML_MEDIA_SET_THUMBNAIL:
> {
> auto mrl = va_arg( args, const char* );
> - m->setThumbnail( mrl );
> + auto sizeType = va_arg( args, int );
> + m->setThumbnail( mrl,
> static_cast<medialibrary::ThumbnailSizeType>( sizeType ) );
> return VLC_SUCCESS;
> }
> case VLC_ML_MEDIA_GENERATE_THUMBNAIL:
> {
> - auto res = m_ml->requestThumbnail( m );
> + auto sizeType = va_arg( args, int );
> + auto width = va_arg( args, uint32_t );
> + auto height = va_arg( args, uint32_t );
> + auto position = va_arg( args, double );
> + auto res = m->requestThumbnail(
> static_cast<medialibrary::ThumbnailSizeType>( sizeType ),
> + width, height, position );
> return res == true ? VLC_SUCCESS : VLC_EGENERIC;
> }
> case VLC_ML_MEDIA_ADD_EXTERNAL_MRL:
> diff --git a/modules/misc/medialibrary/medialibrary.h
> b/modules/misc/medialibrary/medialibrary.h
> index 42cda31c35..861a41c44a 100644
> --- a/modules/misc/medialibrary/medialibrary.h
> +++ b/modules/misc/medialibrary/medialibrary.h
> @@ -40,6 +40,7 @@
> struct vlc_event_t;
> struct vlc_object_t;
> struct vlc_thumbnailer_t;
> +struct vlc_thumbnailer_request_t;
>
> class Logger;
>
> @@ -58,8 +59,6 @@ private:
> {
> }
>
> - vlc::threads::condition_variable m_cond;
> - vlc::threads::mutex m_mutex;
> bool needsProbing;
> bool success;
> MetadataExtractor* mde;
> @@ -79,11 +78,11 @@ public:
> private:
> virtual medialibrary::parser::Status run(
> medialibrary::parser::IItem& item ) override;
> virtual const char*name() const override;
> - virtual uint8_t nbThreads() const override;
> virtual medialibrary::parser::Step targetedStep() const override;
> virtual bool initialize( medialibrary::IMediaLibrary* ml )
> override;
> virtual void onFlushing() override;
> virtual void onRestarted() override;
> + virtual void stop() override;
>
> void onParserEnded( ParseContext& ctx, int status );
> void addSubtree( ParseContext& ctx, input_item_node_t *root );
> @@ -94,18 +93,41 @@ private:
> void *user_data );
>
> private:
> + vlc::threads::condition_variable m_cond;
> + vlc::threads::mutex m_mutex;
> + ParseContext* m_currentCtx;
> vlc_object_t* m_obj;
> };
>
> class Thumbnailer : public medialibrary::IThumbnailer
> {
> + struct ThumbnailerCtx
> + {
> + ~ThumbnailerCtx()
> + {
> + if ( thumbnail != nullptr )
> + picture_Release( thumbnail );
> + }
> + Thumbnailer* thumbnailer;
> + bool done;
> + picture_t* thumbnail;
> + vlc_thumbnailer_request_t* request;
> + };
> public:
> - Thumbnailer( vlc_medialibrary_module_t* ml, std::string
> thumbnailsDir);
> - virtual bool generate( medialibrary::MediaPtr media, const
> std::string& mrl ) override;
> + Thumbnailer(vlc_medialibrary_module_t* ml);
> + virtual bool generate( const std::string& mrl, uint32_t
> desiredWidth,
> + uint32_t desiredHeight, float position,
> + const std::string& dest ) override;
> + virtual void stop() override;
> +
> +private:
> + static void onThumbnailComplete( void* data, picture_t* thumbnail
> );
>
> private:
> vlc_medialibrary_module_t* m_ml;
> - std::string m_thumbnailDir;
> + vlc::threads::mutex m_mutex;
> + vlc::threads::condition_variable m_cond;
> + ThumbnailerCtx* m_currentContext;
> std::unique_ptr<vlc_thumbnailer_t, void(*)(vlc_thumbnailer_t*)>
> m_thumbnailer;
> };
>
> @@ -162,12 +184,15 @@ public:
> virtual void onDiscoveryCompleted(const std::string& entryPoint,
> bool success) override;
> virtual void onReloadStarted(const std::string& entryPoint)
> override;
> virtual void onReloadCompleted(const std::string& entryPoint, bool
> success) override;
> + virtual void onEntryPointAdded(const std::string& entryPoint, bool
> success) override;
> virtual void onEntryPointRemoved(const std::string& entryPoint,
> bool success) override;
> virtual void onEntryPointBanned(const std::string& entryPoint,
> bool success) override;
> virtual void onEntryPointUnbanned(const std::string& entryPoint,
> bool success) override;
> virtual void onParsingStatsUpdated(uint32_t percent) override;
> virtual void onBackgroundTasksIdleChanged(bool isIdle) override;
> - virtual void onMediaThumbnailReady(medialibrary::MediaPtr media,
> bool success) override;
> + virtual void onMediaThumbnailReady(medialibrary::MediaPtr media,
> + medialibrary::ThumbnailSizeType
> sizeType,
> + bool success) override;
> };
>
> bool Convert( const medialibrary::IMedia* input, vlc_ml_media_t&
> output );
> diff --git a/src/misc/medialibrary.c b/src/misc/medialibrary.c
> index 436a5b226f..f100f29b81 100644
> --- a/src/misc/medialibrary.c
> +++ b/src/misc/medialibrary.c
> @@ -134,6 +134,12 @@ vlc_medialibrary_t* vlc_ml_instance_get(
> vlc_object_t* p_obj )
> return p_priv->p_media_library;
> }
>
> +static void vlc_ml_thumbnails_release( vlc_ml_thumbnail_t
> *p_thumbnails )
> +{
> + for ( int i = 0; i < VLC_ML_THUMBNAIL_SIZE_COUNT; ++i )
> + free( p_thumbnails[i].psz_mrl );
> +}
> +
> static void vlc_ml_show_release_inner( vlc_ml_show_t* p_show )
> {
> free( p_show->psz_artwork_mrl );
> @@ -169,7 +175,7 @@ static void vlc_ml_media_release_inner(
> vlc_ml_media_t* p_media )
> vlc_ml_file_list_release( p_media->p_files );
> vlc_ml_media_release_tracks_inner( p_media->p_tracks );
> free( p_media->psz_title );
> - free( p_media->psz_artwork_mrl );
> + vlc_ml_thumbnails_release( p_media->thumbnails );
> switch( p_media->i_subtype )
> {
> case VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK:
> @@ -189,7 +195,7 @@ static void vlc_ml_media_release_inner(
> vlc_ml_media_t* p_media )
>
> static void vlc_ml_artist_release_inner( vlc_ml_artist_t* p_artist )
> {
> - free( p_artist->psz_artwork_mrl );
> + vlc_ml_thumbnails_release( p_artist->thumbnails );
> free( p_artist->psz_name );
> free( p_artist->psz_shortbio );
> free( p_artist->psz_mb_id );
> @@ -205,8 +211,8 @@ void vlc_ml_artist_release( vlc_ml_artist_t* p_artist )
>
> static void vlc_ml_album_release_inner( vlc_ml_album_t* p_album )
> {
> + vlc_ml_thumbnails_release( p_album->thumbnails );
> free( p_album->psz_artist );
> - free( p_album->psz_artwork_mrl );
> free( p_album->psz_summary );
> free( p_album->psz_title );
> }
> --
> 2.20.1
>
> _______________________________________________
> 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