/*****************************************************************************
* medialibrary.h: medialibrary module common declarations
*****************************************************************************
* Copyright © 2015-2016 VLC authors, VideoLAN and VideoLabs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef MEDIALIBRARY_H
#define MEDIALIBRARY_H
#include <medialibrary/IMediaLibrary.h>
#include <medialibrary/parser/IParserService.h>
#include <medialibrary/parser/IItem.h>
#include <medialibrary/parser/Parser.h>
#include <medialibrary/IMedia.h>
#include <medialibrary/ILabel.h>
#include <medialibrary/IThumbnailer.h>
#include <vlc_common.h>
#include <vlc_threads.h>
#include <vlc_input_item.h>
#include <vlc_input.h>
#include <vlc_media_library.h>
#include <vlc_cxx_helpers.hpp>
#include <vlc_preparser.h>
#include <cstdarg>
#include <type_traits>
#include "LazyPreparser.h"
struct vlc_event_t;
struct vlc_object_t;
struct vlc_preparser_t;
class Logger;
class EmbeddedThumbnail : public medialibrary::parser::IEmbeddedThumbnail
{
public:
EmbeddedThumbnail( input_attachment_t* a, vlc_fourcc_t fcc );
virtual ~EmbeddedThumbnail();
bool save(const std::string& path) override;
size_t size() const override;
std::string hash() const override;
std::string extension() const override;
private:
input_attachment_t* m_attachment;
vlc_fourcc_t m_fcc;
};
class MetadataExtractor : public medialibrary::parser::IParserService
{
private:
struct ParseContext
{
ParseContext( MetadataExtractor* mde, medialibrary::parser::IItem& item )
: status( medialibrary::parser::Status::Fatal )
, done( false )
, mde( mde )
, item( item )
{
}
medialibrary::parser::Status status;
bool done;
MetadataExtractor* mde;
medialibrary::parser::IItem& item;
};
public:
MetadataExtractor( vlc_object_t* parent );
virtual ~MetadataExtractor() = default;
// All methods are meant to be accessed through IParserService, not directly
// hence they are all private
private:
medialibrary::parser::Status run( medialibrary::parser::IItem& item ) override;
const char*name() const override;
medialibrary::parser::Step targetedStep() const override;
bool initialize( medialibrary::IMediaLibrary* ml ) override;
void onFlushing() override;
void onRestarted() override;
void stop() override;
void populateItem( medialibrary::parser::IItem& item, input_item_t* inputItem );
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( vlc_preparser_req *,
input_attachment_t *const *array,
size_t count, void *data );
private:
vlc::threads::condition_variable m_cond;
vlc::threads::mutex m_mutex;
ParseContext* m_currentCtx;
LazyPreparser m_parser;
};
class Thumbnailer : public medialibrary::IThumbnailer
{
struct ThumbnailerCtx
{
Thumbnailer* thumbnailer;
bool done;
bool error;
vlc_preparser_req *req;
};
public:
Thumbnailer(vlc_medialibrary_module_t* ml);
bool generate( const medialibrary::IMedia&, const std::string& mrl,
uint32_t desiredWidth, uint32_t desiredHeight,
float position, const std::string& dest ) override;
void stop() override;
private:
static void onThumbnailToFilesComplete(vlc_preparser_req *req, int status,
const bool *result_array,
size_t result_count, void *data);
private:
vlc::threads::mutex m_mutex;
vlc::threads::condition_variable m_cond;
ThumbnailerCtx* m_currentContext;
LazyPreparser m_thumbnailer;
};
class MediaLibrary : public medialibrary::IMediaLibraryCb
{
public:
static MediaLibrary* create( vlc_medialibrary_module_t* ml );
bool Init();
int Control( int query, va_list args );
int List( int query, const vlc_ml_query_params_t* params, va_list args );
void* Get( int query, va_list args );
private:
int controlMedia( int query, va_list args );
int getMeta( const medialibrary::IMedia& media, int meta, char** result );
int getMeta( const medialibrary::IMedia& media, vlc_ml_playback_states_all* result );
int setMeta( medialibrary::IMedia& media, int meta, const char* value );
int setMeta( medialibrary::IMedia& media, const vlc_ml_playback_states_all* values );
int filterListChildrenQuery( int query, int parentType );
int listAlbums( int listQuery, const medialibrary::QueryParameters* paramsPtr,
const char* pattern, uint32_t nbItems, uint32_t offset, va_list args );
int listArtists( int listQuery, const medialibrary::QueryParameters* paramsPtr,
const char* pattern, uint32_t nbItems, uint32_t offset, va_list args );
int listGenre( int listQuery, const medialibrary::QueryParameters* paramsPtr,
const char* pattern, uint32_t nbItems, uint32_t offset, va_list args );
int listGroup( int listQuery, const medialibrary::QueryParameters* paramsPtr,
medialibrary::IMedia::Type type, const char* pattern, uint32_t nbItems,
uint32_t offset, va_list args );
int listFolder( int listQuery, const medialibrary::QueryParameters* paramsPtr,
medialibrary::IMedia::Type type, const char* pattern, uint32_t nbItems,
uint32_t offset, va_list args );
int listPlaylist( int listQuery, const medialibrary::QueryParameters* paramsPtr,
const char* pattern, uint32_t nbItems, uint32_t offset, va_list args );
int listMedia( int listQuery, const medialibrary::QueryParameters* paramsPtr,
const char* pattern, uint32_t nbItems, uint32_t offset, va_list args );
medialibrary::PriorityAccess acquirePriorityAccess();
static medialibrary::IMedia::MetadataType metadataType( int meta );
static medialibrary::SortingCriteria sortingCriteria( int sort );
private:
MediaLibrary( vlc_medialibrary_module_t* vlc_ml, medialibrary::IMediaLibrary* ml );
vlc_medialibrary_module_t* m_vlc_ml;
std::unique_ptr<medialibrary::IMediaLibrary> m_ml;
vlc::threads::mutex m_mutex;
bool m_initialized = false; /* protected by m_mutex */
std::atomic_flag m_started = ATOMIC_FLAG_INIT;
// IMediaLibraryCb interface
public:
void onMediaAdded(std::vector<medialibrary::MediaPtr> media) override;
void onMediaModified(std::set<int64_t> media) override;
void onMediaDeleted(std::set<int64_t> mediaIds) override;
void onArtistsAdded(std::vector<medialibrary::ArtistPtr> artists) override;
void onArtistsModified(std::set<int64_t> artists) override;
void onArtistsDeleted(std::set<int64_t> artistsIds) override;
void onAlbumsAdded(std::vector<medialibrary::AlbumPtr> albums) override;
void onAlbumsModified(std::set<int64_t> albums) override;
void onAlbumsDeleted(std::set<int64_t> albumsIds) override;
void onPlaylistsAdded(std::vector<medialibrary::PlaylistPtr> playlists) override;
void onPlaylistsModified(std::set<int64_t> playlists) override;
void onPlaylistsDeleted(std::set<int64_t> playlistIds) override;
void onGenresAdded(std::vector<medialibrary::GenrePtr> genres) override;
void onGenresModified(std::set<int64_t> genres) override;
void onGenresDeleted(std::set<int64_t> genreIds) override;
void onMediaGroupsAdded( std::vector<medialibrary::MediaGroupPtr> mediaGroups ) override;
void onMediaGroupsModified( std::set<int64_t> mediaGroupsIds ) override;
void onMediaGroupsDeleted( std::set<int64_t> mediaGroupsIds ) override;
void onBookmarksAdded( std::vector<medialibrary::BookmarkPtr> bookmarks ) override;
void onBookmarksModified( std::set<int64_t> bookmarksIds ) override;
void onBookmarksDeleted( std::set<int64_t> bookmarksIds ) override;
void onFoldersAdded( std::vector<medialibrary::FolderPtr> folders ) override;
void onFoldersModified( std::set<int64_t> foldersIds ) override;
void onFoldersDeleted( std::set<int64_t> foldersIds ) override;
void onDiscoveryStarted() override;
void onDiscoveryProgress(const std::string& entryPoint) override;
void onDiscoveryCompleted() override;
void onDiscoveryFailed( const std::string& entryPoint ) override;
void onRootAdded(const std::string& entryPoint, bool success) override;
void onRootRemoved(const std::string& entryPoint, bool success) override;
void onRootBanned(const std::string& entryPoint, bool success) override;
void onRootUnbanned(const std::string& entryPoint, bool success) override;
void onParsingStatsUpdated(uint32_t done, uint32_t scheduled) override;
void onBackgroundTasksIdleChanged(bool isIdle) override;
void onMediaThumbnailReady(medialibrary::MediaPtr media,
medialibrary::ThumbnailSizeType sizeType,
bool success) override;
void onHistoryChanged( medialibrary::HistoryType historyType ) override;
void onRescanStarted() override;
// TODO Will be exposed once subscriptions are integrated.
void onSubscriptionsAdded( std::vector<medialibrary::SubscriptionPtr> ) override {}
void onSubscriptionsModified( std::set<int64_t> ) override {}
void onSubscriptionsDeleted( std::set<int64_t> ) override {}
void onSubscriptionNewMedia( std::set<int64_t> ) override {}
void onSubscriptionCacheUpdated( int64_t ) override {}
void onCacheIdleChanged( bool ) override {}
};
bool Convert( const medialibrary::IMedia* input, vlc_ml_media_t& output );
bool Convert( const medialibrary::IFile* input, vlc_ml_file_t& output );
bool Convert( const medialibrary::IMovie* input, vlc_ml_movie_t& output );
bool Convert( const medialibrary::IShowEpisode* input, vlc_ml_show_episode_t& output );
bool Convert( const medialibrary::IAlbum* input, vlc_ml_album_t& output );
bool Convert( const medialibrary::IArtist* input, vlc_ml_artist_t& output );
bool Convert( const medialibrary::IGenre* input, vlc_ml_genre_t& output );
bool Convert( const medialibrary::IShow* input, vlc_ml_show_t& output );
bool Convert( const medialibrary::ILabel* input, vlc_ml_label_t& output );
bool Convert( const medialibrary::IMediaGroup* input, vlc_ml_group_t& output );
bool Convert( const medialibrary::IPlaylist* input, vlc_ml_playlist_t& output );
bool Convert( const medialibrary::IFolder* input, vlc_ml_folder_t& output );
bool Convert( const medialibrary::IBookmark* input, vlc_ml_bookmark_t& output );
input_item_t* MediaToInputItem( const medialibrary::IMedia* media );
template <typename To, typename ItemType, typename From>
To* ml_convert_list( const std::vector<std::shared_ptr<From>>& input )
{
// This function uses duck typing and assumes all lists have a p_items member
static_assert( std::is_pointer<To>::value == false,
"Destination type must not be a pointer" );
// If decltype( To::p_items ) doesn't yield an array type, we can't deduce
// the items type. however if it does, we can ensure To and ItemType are coherent
static_assert( std::is_array<decltype(To::p_items)>::value == false ||
( std::is_same<typename std::remove_extent<decltype(To::p_items)>::type,
ItemType>::value ), "Invalid/mismatching list/item types" );
// Allocate the ml_*_list_t
auto list = vlc::wrap_cptr(
static_cast<To*>( calloc( 1, sizeof( To ) + input.size() * sizeof( ItemType ) ) ),
static_cast<void(*)(To*)>( &vlc_ml_release ) );
if ( unlikely( list == nullptr ) )
return nullptr;
list->i_nb_items = 0;
for ( auto i = 0u; i < input.size(); ++i )
{
if ( Convert( input[i].get(), list->p_items[i] ) == false )
return nullptr;
list->i_nb_items++;
}
return list.release();
}
template <typename T, typename Input>
T* CreateAndConvert( const Input* input )
{
if ( input == nullptr )
return nullptr;
auto res = vlc::wrap_cptr(
static_cast<T*>( calloc( 1, sizeof( T ) ) ),
static_cast<void(*)(T*)>( &vlc_ml_release ) );
if ( unlikely( res == nullptr ) )
return nullptr;
if ( Convert( input, *res ) == false )
return nullptr;
// Override the pf_relase that each Convert<T> helper will assign.
// The Convert function will use the ReleaseRef variant of the release function,
// as it converts in place, and doesn't have to free the allocated pointer.
// When CreateAndConvert is used, we heap-allocate an instance of T, and therefore
// we also need to release it.
return res.release();
}
#endif // MEDIALIBRARY_H
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|