[vlc-commits] Add a new media library core API
Hugo Beauzée-Luyssen
git at videolan.org
Tue Jul 17 23:28:10 CEST 2018
vlc | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Mon Jun 18 15:19:39 2018 +0200| [b12fc4c9e7ae74b31a94e4432ff3593b3891b679] | committer: Hugo Beauzée-Luyssen
Add a new media library core API
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b12fc4c9e7ae74b31a94e4432ff3593b3891b679
---
include/vlc_media_library.h | 983 ++++++++++++++++++++++++++++++++++++++++++++
src/Makefile.am | 3 +-
src/libvlccore.sym | 16 +
src/misc/medialibrary.c | 258 ++++++++++++
4 files changed, 1259 insertions(+), 1 deletion(-)
diff --git a/include/vlc_media_library.h b/include/vlc_media_library.h
index 5ef7c621e8..244c37651f 100644
--- a/include/vlc_media_library.h
+++ b/include/vlc_media_library.h
@@ -28,12 +28,995 @@
#ifndef VLC_MEDIA_LIBRARY_H
# define VLC_MEDIA_LIBRARY_H
+#include <assert.h>
+
# ifdef __cplusplus
extern "C" {
# endif
+typedef enum vlc_ml_media_type_t
+{
+ VLC_ML_MEDIA_TYPE_UNKNOWN,
+ VLC_ML_MEDIA_TYPE_VIDEO,
+ VLC_ML_MEDIA_TYPE_AUDIO,
+ VLC_ML_MEDIA_TYPE_EXTERNAL,
+ VLC_ML_MEDIA_TYPE_STREAM,
+} vlc_ml_media_type_t;
+
+typedef enum vlc_ml_media_subtype_t
+{
+ VLC_ML_MEDIA_SUBTYPE_UNKNOWN,
+ VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE,
+ VLC_ML_MEDIA_SUBTYPE_MOVIE,
+ VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK,
+} vlc_ml_media_subtype_t;
+
+typedef enum vlc_ml_file_type_t
+{
+ VLC_ML_FILE_TYPE_UNKNOWN,
+ VLC_ML_FILE_TYPE_MAIN,
+ VLC_ML_FILE_TYPE_PART,
+ VLC_ML_FILE_TYPE_SOUNDTRACK,
+ VLC_ML_FILE_TYPE_SUBTITLE,
+ VLC_ML_FILE_TYPE_PLAYLIST,
+} vlc_ml_file_type_t;
+
+typedef enum vlc_ml_track_type_t
+{
+ VLC_ML_TRACK_TYPE_UNKNOWN,
+ VLC_ML_TRACK_TYPE_VIDEO,
+ VLC_ML_TRACK_TYPE_AUDIO,
+} vlc_ml_track_type_t;
+
+typedef struct vlc_ml_movie_t
+{
+ char* psz_summary;
+ char* psz_imdb_id;
+} vlc_ml_movie_t;
+
+typedef struct vlc_ml_show_episode_t
+{
+ char* psz_summary;
+ char* psz_tvdb_id;
+ uint32_t i_episode_nb;
+ uint32_t i_season_number;
+} vlc_ml_show_episode_t;
+
+typedef struct vlc_ml_show_t
+{
+ int64_t i_id;
+ char* psz_name;
+ char* psz_summary;
+ char* psz_artwork_mrl;
+ char* psz_tvdb_id;
+ unsigned int i_release_year;
+ uint32_t i_nb_episodes;
+ uint32_t i_nb_seasons;
+} vlc_ml_show_t;
+
+typedef struct vlc_ml_album_track_t
+{
+ int64_t i_artist_id;
+ int64_t i_album_id;
+ int64_t i_genre_id;
+
+ int i_track_nb;
+ int i_disc_nb;
+} vlc_ml_album_track_t;
+
+typedef struct vlc_ml_label_t
+{
+ int64_t i_id;
+ char* psz_name;
+} vlc_ml_label_t;
+
+typedef struct vlc_ml_label_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_label_t p_items[];
+} vlc_ml_label_list_t;
+
+typedef struct vlc_ml_file_t
+{
+ char* psz_mrl;
+ vlc_ml_file_type_t i_type;
+ bool b_external;
+} vlc_ml_file_t;
+
+typedef struct vlc_ml_file_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_file_t p_items[];
+} vlc_ml_file_list_t;
+
+typedef struct vlc_ml_media_track_t
+{
+ char* psz_codec;
+ char* psz_language;
+ char* psz_description;
+ vlc_ml_track_type_t i_type;
+ uint32_t i_bitrate;
+ union
+ {
+ struct
+ {
+ // Audio
+ uint32_t i_nbChannels;
+ uint32_t i_sampleRate;
+ } a;
+ struct
+ {
+ // Video
+ uint32_t i_height;
+ uint32_t i_width;
+ uint32_t i_sarNum;
+ uint32_t i_sarDen;
+ uint32_t i_fpsNum;
+ uint32_t i_fpsDen;
+ } v;
+ };
+} vlc_ml_media_track_t;
+
+typedef struct vlc_ml_media_track_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_media_track_t p_items[];
+} vlc_ml_media_track_list_t;
+
+typedef struct vlc_ml_media_t
+{
+ int64_t i_id;
+
+ vlc_ml_media_type_t i_type;
+ vlc_ml_media_subtype_t i_subtype;
+
+ vlc_ml_file_list_t* p_files;
+ vlc_ml_media_track_list_t* p_tracks;
+
+ int32_t i_year;
+ /* Duration in milliseconds */
+ int64_t i_duration;
+ uint32_t i_playcount;
+ time_t i_last_played_date;
+ char* psz_title;
+
+ char* psz_artwork_mrl;
+ bool b_is_favorite;
+
+ union
+ {
+ vlc_ml_show_episode_t show_episode;
+ vlc_ml_movie_t movie;
+ vlc_ml_album_track_t album_track;
+ };
+} vlc_ml_media_t;
+
+typedef struct vlc_ml_playlist_t
+{
+ int64_t i_id;
+ char* psz_name;
+ uint32_t i_creation_date;
+ char* psz_artwork_mrl;
+} vlc_ml_playlist_t;
+
+typedef struct vlc_ml_artist_t
+{
+ int64_t i_id;
+ char* psz_name;
+ char* psz_shortbio;
+ char* psz_artwork_mrl;
+ char* psz_mb_id;
+
+ unsigned int i_nb_album;
+ unsigned int i_nb_tracks;
+} vlc_ml_artist_t;
+
+typedef struct vlc_ml_artist_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_artist_t p_items[];
+} vlc_ml_artist_list_t;
+
+typedef struct vlc_ml_album_t {
+ int64_t i_id;
+ char* psz_title;
+ char* psz_summary;
+ char* psz_artwork_mrl;
+ char* psz_artist;
+ int64_t i_artist_id;
+
+ size_t i_nb_tracks;
+ unsigned int i_duration;
+ unsigned int i_year;
+} vlc_ml_album_t;
+
+typedef struct vlc_ml_genre_t
+{
+ int64_t i_id;
+ char* psz_name;
+ size_t i_nb_tracks;
+} vlc_ml_genre_t;
+
+typedef struct vlc_ml_media_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_media_t p_items[];
+} vlc_ml_media_list_t;
+
+typedef struct vlc_ml_album_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_album_t p_items[];
+} vlc_ml_album_list_t;
+
+typedef struct vlc_ml_show_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_show_t p_items[];
+} vlc_ml_show_list_t;
+
+typedef struct vlc_ml_genre_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_genre_t p_items[];
+} vlc_ml_genre_list_t;
+
+typedef struct vlc_ml_playlist_list_t
+{
+ size_t i_nb_items;
+ vlc_ml_playlist_t p_items[];
+} vlc_ml_playlist_list_t;
+
+typedef struct vlc_ml_entrypoint_t vlc_ml_entrypoint_t;
+struct vlc_ml_entrypoint_t
+{
+ char* psz_mrl; /**< This entrypoint's MRL. Will be NULL if b_present is false */
+ bool b_present; /**< The presence state for this entrypoint. */
+ bool b_banned; /**< Will be true if the user required this entrypoint to be excluded */
+};
+
+typedef struct vlc_medialibrary_t vlc_medialibrary_t;
+
+vlc_medialibrary_t* libvlc_MlCreate( libvlc_int_t* p_libvlc );
+void libvlc_MlRelease( vlc_medialibrary_t* p_ml );
+
+VLC_API vlc_medialibrary_t* vlc_ml_get( vlc_object_t* p_obj ) VLC_USED;
+#define vlc_ml_get(x) vlc_ml_get( VLC_OBJECT(x) )
+
+VLC_API void vlc_ml_entrypoints_release( vlc_ml_entrypoint_t* p_list, size_t i_nb_items );
+
+VLC_API void vlc_ml_show_release( vlc_ml_show_t* p_show );
+VLC_API void vlc_ml_artist_release( vlc_ml_artist_t* p_artist );
+VLC_API void vlc_ml_genre_release( vlc_ml_genre_t* p_genre );
+VLC_API void vlc_ml_media_release( vlc_ml_media_t* p_media );
+VLC_API void vlc_ml_album_release( vlc_ml_album_t* p_album );
+VLC_API void vlc_ml_playlist_release( vlc_ml_playlist_t* p_playlist );
+
+VLC_API void vlc_ml_label_list_release( vlc_ml_label_list_t* p_list );
+VLC_API void vlc_ml_file_list_release( vlc_ml_file_list_t* p_list );
+VLC_API void vlc_ml_artist_list_release( vlc_ml_artist_list_t* p_list );
+VLC_API void vlc_ml_media_list_release( vlc_ml_media_list_t* p_list );
+VLC_API void vlc_ml_album_list_release( vlc_ml_album_list_t* p_list );
+VLC_API void vlc_ml_show_list_release( vlc_ml_show_list_t* p_list );
+VLC_API void vlc_ml_genre_list_release( vlc_ml_genre_list_t* p_list );
+VLC_API void vlc_ml_playlist_list_release( vlc_ml_playlist_list_t* p_list );
+
+typedef enum vlc_ml_sorting_criteria_t
+{
+ /*
+ * Default depends on the entity type:
+ * - By track number (and disc number) for album tracks
+ * - Alphabetical order for others
+ */
+ VLC_ML_SORTING_DEFAULT,
+ VLC_ML_SORTING_ALPHA,
+ VLC_ML_SORTING_DURATION,
+ VLC_ML_SORTING_INSERTIONDATE,
+ VLC_ML_SORTING_LASTMODIFICATIONDATE,
+ VLC_ML_SORTING_RELEASEDATE,
+ VLC_ML_SORTING_FILESIZE,
+ VLC_ML_SORTING_ARTIST,
+ VLC_ML_SORTING_PLAYCOUNT,
+ VLC_ML_SORTING_ALBUM,
+ VLC_ML_SORTING_FILENAME,
+ VLC_ML_SORTING_TRACKNUMBER,
+} vlc_ml_sorting_criteria_t;
+
+typedef struct vlc_ml_query_params_t vlc_ml_query_params_t;
+struct vlc_ml_query_params_t
+{
+ const char* psz_pattern;
+ uint32_t i_nbResults;
+ uint32_t i_offset;
+ vlc_ml_sorting_criteria_t i_sort;
+ bool b_desc;
+};
+
+static inline vlc_ml_query_params_t vlc_ml_query_params_create()
+{
+ return (vlc_ml_query_params_t) {
+ .psz_pattern = NULL,
+ .i_nbResults = 0,
+ .i_offset = 0,
+ .i_sort = VLC_ML_SORTING_DEFAULT,
+ .b_desc = false
+ };
+}
+
+struct vlc_medialibrary_t
+{
+ struct vlc_common_members obj;
+
+ module_t *p_module;
+
+ void* p_sys;
+
+ int (*pf_control)( vlc_medialibrary_t* p_ml, int i_query, ... );
+ /**
+ * List some entities from the medialibrary.
+ *
+ * \param p_ml The medialibrary module instance.
+ * \param i_query The type search to be performed. \see vlc_ml_list enumeration
+ * \param p_params A pointer to a vlc_ml_query_params_t structure, or NULL for
+ * the default parameters (alphabetical ascending sort, no pagination)
+ *
+ * \return VLC_SUCCESS or an error code
+ *
+ * Refer to the individual list of vlc_ml_list requests for the additional
+ * per-query input/ouput parameters values & types
+ */
+ int (*pf_list)( vlc_medialibrary_t* p_ml, int i_query,
+ const vlc_ml_query_params_t* p_params, ... );
+
+ /**
+ * Get a specific entity by its id.
+ *
+ * \return The required entity, or a NULL pointer if couldn't be found.
+ *
+ * Refer to the list of queries for the specific return type
+ */
+ void* (*pf_get)( vlc_medialibrary_t* p_ml, int i_query, int64_t i_id );
+};
+
+enum vlc_ml_control
+{
+ /* Adds a folder to discover through the medialibrary */
+ VLC_ML_ADD_FOLDER, /**< arg1: mrl (const char*) res: can't fail */
+ VLC_ML_REMOVE_FOLDER, /**< arg1: mrl (const char*) res: can't fail */
+ VLC_ML_BAN_FOLDER, /**< arg1: mrl (const char*) res: can't fail */
+ VLC_ML_UNBAN_FOLDER, /**< arg1: mrl (const char*) res: can't fail */
+ VLC_ML_LIST_FOLDERS, /**< arg1: entrypoints (vlc_ml_entrypoint_t**); arg2: nb results(size_t*), res: can fail */
+
+ /* Pause/resume background operations, such as media discovery & media analysis */
+ VLC_ML_PAUSE_BACKGROUND, /**< no args; can't fail */
+ VLC_ML_RESUME_BACKGROUND, /**< no args; can't fail */
+
+ /* Misc operations */
+ VLC_ML_CLEAR_HISTORY, /**< no args; can't fail */
+
+ /* Create media */
+ VLC_ML_NEW_EXTERNAL_MEDIA, /**< arg1: const char*; arg2(out): vlc_ml_media_t** */
+ VLC_ML_NEW_STREAM, /**< arg1: const char*; arg2(out): vlc_ml_media_t** */
+
+ /* Media management */
+ 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_ADD_EXTERNAL_MRL, /**< arg1: media id; arg2: const char*; arg3: type(vlc_ml_file_type_t) */
+};
+
+/**
+ * User playback settings.
+ * All values/units are up to the caller and are not interpreted by the media
+ * library.
+ * All values are stored and returned as strings.
+ * When calling vlc_medialibrary_t::pf_control with vlc_ml_MEDIA_GET_MEDIA_PLAYBACK_PREF,
+ * the value will be returned stored in the provided char**. If the preference was
+ * not set yet, NULL will be returned.
+ * When setting a preference, NULL can be provided as a value to unset it.
+ */
+enum vlc_ml_playback_pref
+{
+ VLC_ML_PLAYBACK_PREF_RATING,
+ VLC_ML_PLAYBACK_PREF_PROGRESS,
+ VLC_ML_PLAYBACK_PREF_SPEED,
+ VLC_ML_PLAYBACK_PREF_TITLE,
+ VLC_ML_PLAYBACK_PREF_CHAPTER,
+ VLC_ML_PLAYBACK_PREF_PROGRAM,
+ VLC_ML_PLAYBACK_PREF_SEEN,
+ VLC_ML_PLAYBACK_PREF_VIDEO_TRACK,
+ VLC_ML_PLAYBACK_PREF_ASPECT_RATIO,
+ VLC_ML_PLAYBACK_PREF_ZOOM,
+ VLC_ML_PLAYBACK_PREF_CROP,
+ VLC_ML_PLAYBACK_PREF_DEINTERLACE,
+ VLC_ML_PLAYBACK_PREF_VIDEO_FILTER,
+ VLC_ML_PLAYBACK_PREF_AUDIO_TRACK,
+ VLC_ML_PLAYBACK_PREF_GAIN,
+ VLC_ML_PLAYBACK_PREF_AUDIO_DELAY,
+ VLC_ML_PLAYBACK_PREF_SUBTITLE_TRACK,
+ VLC_ML_PLAYBACK_PREF_SUBTITLE_DELAY,
+ VLC_ML_PLAYBACK_PREF_APP_SPECIFIC,
+};
+
+static inline void vlc_ml_add_folder( vlc_medialibrary_t* p_ml, const char* psz_folder )
+{
+ p_ml->pf_control( p_ml, VLC_ML_ADD_FOLDER, psz_folder );
+}
+
+static inline void vlc_ml_remove_folder( vlc_medialibrary_t* p_ml, const char* psz_folder )
+{
+ p_ml->pf_control( p_ml, VLC_ML_REMOVE_FOLDER, psz_folder );
+}
+
+static inline void vlc_ml_ban_folder( vlc_medialibrary_t* p_ml, const char* psz_folder )
+{
+ p_ml->pf_control( p_ml, VLC_ML_BAN_FOLDER, psz_folder );
+}
+
+static inline void vlc_ml_unban_folder( vlc_medialibrary_t* p_ml, const char* psz_folder )
+{
+ p_ml->pf_control( p_ml, VLC_ML_UNBAN_FOLDER, psz_folder );
+}
+
+static inline int vlc_ml_list_folder( vlc_medialibrary_t* p_ml,
+ vlc_ml_entrypoint_t** pp_entrypoints, size_t* p_nb_items )
+{
+ return p_ml->pf_control( p_ml, VLC_ML_LIST_FOLDERS, pp_entrypoints, p_nb_items );
+}
+
+static inline void vlc_ml_pause_background( vlc_medialibrary_t* p_ml )
+{
+ p_ml->pf_control( p_ml, VLC_ML_PAUSE_BACKGROUND );
+}
+
+static inline void vlc_ml_resume_background( vlc_medialibrary_t* p_ml )
+{
+ p_ml->pf_control( p_ml, VLC_ML_RESUME_BACKGROUND );
+}
+
+static inline void vlc_ml_clear_history( vlc_medialibrary_t* p_ml )
+{
+ p_ml->pf_control( p_ml, VLC_ML_CLEAR_HISTORY );
+}
+
+static inline vlc_ml_media_t* vlc_ml_new_external_media( vlc_medialibrary_t* p_ml, const char* psz_mrl )
+{
+ vlc_ml_media_t* res;
+ if ( p_ml->pf_control( p_ml, VLC_ML_NEW_EXTERNAL_MEDIA, psz_mrl, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline vlc_ml_media_t* vlc_ml_new_stream( vlc_medialibrary_t* p_ml, const char* psz_mrl )
+{
+ vlc_ml_media_t* res;
+ if ( p_ml->pf_control( p_ml, VLC_ML_NEW_STREAM, psz_mrl, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline int vlc_ml_media_increase_playcount( vlc_medialibrary_t* p_ml, int64_t i_media_id )
+{
+ return p_ml->pf_control( p_ml, VLC_ML_MEDIA_INCREASE_PLAY_COUNT, i_media_id );
+}
+
+static inline int vlc_ml_media_get_playback_pref( vlc_medialibrary_t* p_ml, int64_t i_media_id, int i_pref, char** ppsz_result )
+{
+ return p_ml->pf_control( p_ml, VLC_ML_MEDIA_GET_MEDIA_PLAYBACK_PREF, i_media_id, i_pref, ppsz_result );
+}
+
+static inline int vlc_ml_media_set_playback_pref( vlc_medialibrary_t* p_ml, int64_t i_media_id, int i_pref, const char* psz_value )
+{
+ return p_ml->pf_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 )
+{
+ return p_ml->pf_control( p_ml, VLC_ML_MEDIA_SET_THUMBNAIL, i_media_id, psz_mrl );
+}
+
+static inline int vlc_ml_media_add_external_mrl( vlc_medialibrary_t* p_ml, int64_t i_media_id,
+ const char* psz_mrl, int i_type )
+{
+ return p_ml->pf_control( p_ml, VLC_ML_MEDIA_ADD_EXTERNAL_MRL, i_media_id, psz_mrl, i_type );
+}
+
+enum vlc_ml_get_queries
+{
+ VLC_ML_GET_MEDIA, /**< arg1: Media ID; ret: vlc_ml_media_t* */
+ VLC_ML_GET_ALBUM, /**< arg1: Album ID; ret: vlc_ml_album_t* */
+ VLC_ML_GET_ARTIST, /**< arg1: Artist ID; ret: vlc_ml_artist_t* */
+ VLC_ML_GET_GENRE, /**< arg1: Genre ID; ret: vlc_ml_genre_t* */
+ VLC_ML_GET_SHOW, /**< arg1: Show ID; ret: vlc_ml_show_t* */
+ VLC_ML_GET_PLAYLIST, /**< arg1: Playlist ID; ret: vlc_ml_playlist_t* */
+};
+
+static inline vlc_ml_media_t* vlc_ml_get_media( vlc_medialibrary_t* p_ml, int64_t i_media_id )
+{
+ return (vlc_ml_media_t*)p_ml->pf_get( p_ml, VLC_ML_GET_MEDIA, i_media_id );
+}
+
+static inline vlc_ml_album_t* vlc_ml_get_album( vlc_medialibrary_t* p_ml, int64_t i_album_id )
+{
+ return (vlc_ml_album_t*)p_ml->pf_get( p_ml, VLC_ML_GET_ALBUM, i_album_id );
+}
+
+static inline vlc_ml_artist_t* vlc_ml_get_artist( vlc_medialibrary_t* p_ml, int64_t i_artist_id )
+{
+ return (vlc_ml_artist_t*)p_ml->pf_get( p_ml, VLC_ML_GET_ARTIST, i_artist_id );
+}
+
+static inline vlc_ml_genre_t* vlc_ml_get_genre( vlc_medialibrary_t* p_ml, int64_t i_genre_id )
+{
+ return (vlc_ml_genre_t*)p_ml->pf_get( p_ml, VLC_ML_GET_GENRE, i_genre_id );
+}
+
+static inline vlc_ml_show_t* vlc_ml_get_show( vlc_medialibrary_t* p_ml, int64_t i_show_id )
+{
+ return (vlc_ml_show_t*)p_ml->pf_get( p_ml, VLC_ML_GET_SHOW, i_show_id );
+}
+
+static inline vlc_ml_playlist_t* vlc_ml_get_playlist( vlc_medialibrary_t* p_ml, int64_t i_playlist_id )
+{
+ return (vlc_ml_playlist_t*)p_ml->pf_get( p_ml, VLC_ML_GET_PLAYLIST, i_playlist_id );
+}
+
+enum vlc_ml_list_queries
+{
+ /* General listing: */
+
+ VLC_ML_LIST_VIDEOS, /**< arg1 (out): vlc_ml_media_list_t** */
+ VLC_ML_COUNT_VIDEOS, /**< arg1 (out): size_t* */
+ VLC_ML_LIST_AUDIOS, /**< arg1 (out): vlc_ml_media_list_t** */
+ VLC_ML_COUNT_AUDIOS, /**< arg1 (out): size_t* */
+ VLC_ML_LIST_ALBUMS, /**< arg1 (out): vlc_ml_album_list_t** */
+ VLC_ML_COUNT_ALBUMS, /**< arg1 (out): size_t* */
+ VLC_ML_LIST_GENRES, /**< arg1 (out): vlc_ml_genre_list_t** */
+ VLC_ML_COUNT_GENRES, /**< arg1 (out): size_t* */
+ VLC_ML_LIST_ARTISTS, /**< arg1 bool: includeAll; arg2 (out): vlc_ml_genre_list_t** */
+ VLC_ML_COUNT_ARTISTS, /**< arg1 bool: includeAll; arg2 (out): size_t* */
+ VLC_ML_LIST_SHOWS, /**< arg1 (out): vlc_ml_show_list_t** */
+ VLC_ML_COUNT_SHOWS, /**< arg1 (out): size_t* */
+ VLC_ML_LIST_PLAYLISTS, /**< arg1 (out): vlc_ml_playlist_list_t** */
+ VLC_ML_COUNT_PLAYLISTS, /**< arg1 (out): size_t* */
+ VLC_ML_LIST_HISTORY, /**< arg1 (out): vlc_ml_media_list_t** */
+ VLC_ML_LIST_STREAM_HISTORY, /**< arg1 (out): vlc_ml_media_list_t** */
+
+ /* Album specific listings */
+ VLC_ML_LIST_ALBUM_TRACKS, /**< arg1: The album id. arg2 (out): vlc_ml_media_list_t** */
+ VLC_ML_COUNT_ALBUM_TRACKS, /**< arg1: The album id. arg2 (out): size_t* */
+ VLC_ML_LIST_ALBUM_ARTISTS, /**< arg1: The album id. arg2 (out): vlc_ml_album_list_t** */
+ VLC_ML_COUNT_ALBUM_ARTISTS, /**< arg1: The album id. arg2 (out): size_t* */
+
+ /* Artist specific listings */
+ VLC_ML_LIST_ARTIST_ALBUMS, /**< arg1: The artist id. arg2(out): vlc_ml_album_list_t** */
+ VLC_ML_COUNT_ARTIST_ALBUMS, /**< arg1: The artist id. arg2(out): size_t* */
+ VLC_ML_LIST_ARTIST_TRACKS, /**< arg1: The artist id. arg2(out): vlc_ml_media_list_t** */
+ VLC_ML_COUNT_ARTIST_TRACKS, /**< arg1: The artist id. arg2(out): size_t* */
+
+ /* Genre specific listings */
+ VLC_ML_LIST_GENRE_ARTISTS, /**< arg1: genre id; arg2 (out): vlc_ml_artist_list_t** */
+ VLC_ML_COUNT_GENRE_ARTISTS, /**< arg1: genre id; arg2 (out): size_t* */
+ VLC_ML_LIST_GENRE_TRACKS, /**< arg1: genre id; arg2 (out): vlc_ml_media_list_t** */
+ VLC_ML_COUNT_GENRE_TRACKS, /**< arg1: genre id; arg2 (out): size_t* */
+ VLC_ML_LIST_GENRE_ALBUMS, /**< arg1: genre id; arg2 (out): vlc_ml_album_list_t** */
+ VLC_ML_COUNT_GENRE_ALBUMS, /**< arg1: genre id; arg2 (out): size_t* */
+
+ /* Show specific listings */
+ VLC_ML_LIST_SHOW_EPISODES, /**< arg1: show id; arg2(out): vlc_ml_media_list_t** */
+ VLC_ML_COUNT_SHOW_EPISODES, /**< arg1: show id; arg2(out): size_t* */
+
+ /* Media specific listings */
+ VLC_ML_LIST_MEDIA_LABELS, /**< arg1: media id; arg2 (out): vlc_ml_label_list_t** */
+ VLC_ML_COUNT_MEDIA_LABELS, /**< arg1: media id; arg2 (out): size_t* */
+
+ /* Playlist specific listings */
+ VLC_ML_LIST_PLAYLIST_MEDIA, /**< arg1: playlist id; arg2 (out): vlc_ml_media_list_t** */
+ VLC_ML_COUNT_PLAYLIST_MEDIA, /**< arg1: playlist id; arg2 (out): size_t* */
+
+ /* Children entities listing */
+ VLC_ML_LIST_MEDIA_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): ml_media_list_t* */
+ VLC_ML_COUNT_MEDIA_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
+ VLC_ML_LIST_ARTISTS_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): ml_artist_list_t* */
+ VLC_ML_COUNT_ARTISTS_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
+ VLC_ML_LIST_ALBUMS_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): ml_album_list_t* */
+ VLC_ML_COUNT_ALBUMS_OF, /**< arg1: parent entity type; arg2: parent entity id; arg3(out): size_t* */
+};
+
+enum vlc_ml_parent_type
+{
+ VLC_ML_PARENT_ALBUM,
+ VLC_ML_PARENT_ARTIST,
+ VLC_ML_PARENT_SHOW,
+ VLC_ML_PARENT_GENRE,
+ VLC_ML_PARENT_PLAYLIST,
+};
+
+static inline vlc_ml_media_list_t* vlc_ml_list_media_of( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int i_parent_type, int64_t i_parent_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_MEDIA_OF, params, i_parent_type, i_parent_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_media_of( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int i_parent_type, int64_t i_parent_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_MEDIA_OF, params, i_parent_type, i_parent_id, &res ) )
+ return 0;
+ return res;
+}
+
+static inline vlc_ml_artist_list_t* vlc_ml_list_artist_of( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int i_parent_type, int64_t i_parent_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_artist_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_ARTISTS_OF, params, i_parent_type, i_parent_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_artists_of( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int i_parent_type, int64_t i_parent_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_ARTISTS_OF, params, i_parent_type, i_parent_id, &res ) )
+ return 0;
+ return res;
+}
+
+static inline vlc_ml_album_list_t* vlc_ml_list_albums_of( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int i_parent_type, int64_t i_parent_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_album_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_ALBUMS_OF, params, i_parent_type, i_parent_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_albums_of( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int i_parent_type, int64_t i_parent_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_ALBUMS_OF, params, i_parent_type, i_parent_id, &res ) )
+ return 0;
+ return res;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_album_tracks( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_album_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_ALBUM_TRACKS, params, i_album_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_album_tracks( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_album_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_ALBUM_TRACKS, params, i_album_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_album_artists( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_album_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_ALBUM_ARTISTS, params, i_album_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_album_artists( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_album_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_ALBUM_ARTISTS, params, i_album_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_album_list_t* vlc_ml_list_artist_albums( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_artist_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_album_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_ARTIST_ALBUMS, params, i_artist_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_artist_albums( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_artist_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_ARTIST_ALBUMS, params, i_artist_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_artist_tracks( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_artist_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_ARTIST_TRACKS, params, i_artist_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_artist_tracks( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_artist_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_ARTIST_TRACKS, params, i_artist_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_video_media( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_VIDEOS, params, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_video_media( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_VIDEOS, params, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_audio_media( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_AUDIOS, params, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_audio_media( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_AUDIOS, params, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_album_list_t* vlc_ml_list_albums( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_album_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_ALBUMS, params, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_albums( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_ALBUMS, params, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_genre_list_t* vlc_ml_list_genres( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_genre_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_GENRES, params, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_genres( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_GENRES, params, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+/**
+ * @brief vlc_ml_list_artists
+ * @param params Query parameters, or NULL for the default
+ * @param b_include_all True if you wish to fetch artists without at least one album.
+ * @return
+ */
+static inline vlc_ml_artist_list_t* vlc_ml_list_artists( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, bool b_include_all )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_artist_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_ARTISTS, params, (int)b_include_all, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_artists( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, bool includeAll )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_ARTISTS, params, includeAll, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_show_list_t* vlc_ml_list_shows( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_show_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_SHOWS, params, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_shows( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_SHOWS, params, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_genre_artists( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_genre_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_GENRE_ARTISTS, params, i_genre_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_genre_artists( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_genre_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_GENRE_ARTISTS, params, i_genre_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_genre_tracks( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_genre_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_GENRE_TRACKS, params, i_genre_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_genre_tracks( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_genre_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_GENRE_TRACKS, params, i_genre_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_album_list_t* vlc_ml_list_genre_albums( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_genre_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_album_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_GENRE_ALBUMS, params, i_genre_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_genre_albums( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_genre_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_GENRE_ALBUMS, params, i_genre_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_show_episodes( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_show_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_SHOW_EPISODES, params, i_show_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_show_episodes( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_show_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_COUNT_GENRE_ALBUMS, params, i_show_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_label_list_t* vlc_ml_list_media_labels( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_media_id )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_label_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_MEDIA_LABELS, params, i_media_id, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline size_t vlc_ml_count_media_labels( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params, int64_t i_media_id )
+{
+ vlc_assert( p_ml != NULL );
+ size_t count;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_MEDIA_LABELS, params, i_media_id, &count ) != VLC_SUCCESS )
+ return 0;
+ return count;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_history( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_HISTORY, params, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
+static inline vlc_ml_media_list_t* vlc_ml_list_stream_history( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params )
+{
+ vlc_assert( p_ml != NULL );
+ vlc_ml_media_list_t* res;
+ if ( p_ml->pf_list( p_ml, VLC_ML_LIST_STREAM_HISTORY, params, &res ) != VLC_SUCCESS )
+ return NULL;
+ return res;
+}
+
#ifdef __cplusplus
}
#endif /* C++ */
+#ifndef __cplusplus
+# define vlc_ml_release_obj( OBJ ) _Generic( ( OBJ ), \
+ vlc_ml_show_t*: vlc_ml_show_release, \
+ vlc_ml_artist_t*: vlc_ml_artist_release, \
+ vlc_ml_album_t*: vlc_ml_album_release, \
+ vlc_ml_genre_t*: vlc_ml_genre_release, \
+ vlc_ml_media_t*: vlc_ml_media_release, \
+ vlc_ml_playlist_t*: vlc_ml_playlist_release, \
+ vlc_ml_label_list_t*: vlc_ml_label_list_release, \
+ vlc_ml_file_list_t*: vlc_ml_file_list_release, \
+ vlc_ml_artist_list_t*: vlc_ml_artist_list_release, \
+ vlc_ml_media_list_t*: vlc_ml_media_list_release, \
+ vlc_ml_album_list_t*: vlc_ml_album_list_release, \
+ vlc_ml_show_list_t*: vlc_ml_show_list_release, \
+ vlc_ml_genre_list_t*: vlc_ml_genre_list_release, \
+ vlc_ml_playlist_list_t*: vlc_ml_playlist_list_release \
+ )( OBJ )
+#else
+static inline void vlc_ml_release_obj( vlc_ml_show_t* show ) { vlc_ml_show_release( show ); }
+static inline void vlc_ml_release_obj( vlc_ml_artist_t* artist ) { vlc_ml_artist_release( artist ); }
+static inline void vlc_ml_release_obj( vlc_ml_album_t* album ) { vlc_ml_album_release( album ); }
+static inline void vlc_ml_release_obj( vlc_ml_genre_t* genre ) { vlc_ml_genre_release( genre ); }
+static inline void vlc_ml_release_obj( vlc_ml_media_t* media ) { vlc_ml_media_release( media ); }
+static inline void vlc_ml_release_obj( vlc_ml_playlist_t* playlist ) { vlc_ml_playlist_release( playlist ); }
+static inline void vlc_ml_release_obj( vlc_ml_label_list_t* list ) { vlc_ml_label_list_release( list ); }
+static inline void vlc_ml_release_obj( vlc_ml_file_list_t* list ) { vlc_ml_file_list_release( list ); }
+static inline void vlc_ml_release_obj( vlc_ml_artist_list_t* list ) { vlc_ml_artist_list_release( list ); }
+static inline void vlc_ml_release_obj( vlc_ml_media_list_t* list ) { vlc_ml_media_list_release( list ); }
+static inline void vlc_ml_release_obj( vlc_ml_album_list_t* list ) { vlc_ml_album_list_release( list ); }
+static inline void vlc_ml_release_obj( vlc_ml_show_list_t* list ) { vlc_ml_show_list_release( list ); }
+static inline void vlc_ml_release_obj( vlc_ml_genre_list_t* list ) { vlc_ml_genre_list_release( list ); }
+static inline void vlc_ml_release_obj( vlc_ml_playlist_list_t* list ) { vlc_ml_playlist_list_release( list ); }
+#endif
+
#endif /* VLC_MEDIA_LIBRARY_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index 49ac01b26f..563da0c6de 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -357,7 +357,8 @@ libvlccore_la_SOURCES = \
misc/fingerprinter.c \
misc/text_style.c \
misc/subpicture.c \
- misc/subpicture.h
+ misc/subpicture.h \
+ misc/medialibrary.c
libvlccore_la_LIBADD = $(LIBS_libvlccore) \
../compat/libcompat.la \
$(LTLIBINTL) $(LTLIBICONV) \
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index dab796777a..118664d413 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -592,6 +592,22 @@ vlc_keystore_find
vlc_keystore_remove
vlc_keystore_store
vlc_keystore_release_entries
+vlc_ml_get
+vlc_ml_entrypoints_release
+vlc_ml_show_release
+vlc_ml_artist_release
+vlc_ml_genre_release
+vlc_ml_media_release
+vlc_ml_album_release
+vlc_ml_playlist_release
+vlc_ml_label_list_release
+vlc_ml_file_list_release
+vlc_ml_artist_list_release
+vlc_ml_media_list_release
+vlc_ml_album_list_release
+vlc_ml_show_list_release
+vlc_ml_genre_list_release
+vlc_ml_playlist_list_release
vlc_poll_i11e
vlc_read_i11e
vlc_readv_i11e
diff --git a/src/misc/medialibrary.c b/src/misc/medialibrary.c
new file mode 100644
index 0000000000..c844b3b4d8
--- /dev/null
+++ b/src/misc/medialibrary.c
@@ -0,0 +1,258 @@
+/*****************************************************************************
+ * medialib.cpp: medialibrary module
+ *****************************************************************************
+ * 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.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_media_library.h>
+#include <vlc_modules.h>
+#include <libvlc.h>
+
+#include <assert.h>
+
+void vlc_ml_entrypoints_release( vlc_ml_entrypoint_t* p_list, size_t i_nb_items )
+{
+ for ( size_t i = 0; i < i_nb_items; ++i )
+ {
+ free( p_list[i].psz_mrl );
+ }
+ free( p_list );
+}
+
+vlc_medialibrary_t* libvlc_MlCreate( libvlc_int_t* p_libvlc )
+{
+ vlc_medialibrary_t *p_ml = vlc_custom_create( VLC_OBJECT( p_libvlc ),
+ sizeof( *p_ml ), "medialibrary" );
+ if ( unlikely( p_ml == NULL ) )
+ return NULL;
+ p_ml->p_module = module_need( p_ml, "medialibrary", NULL, false );
+ if ( p_ml->p_module == NULL )
+ {
+ vlc_object_release( p_ml );
+ return NULL;
+ }
+ return p_ml;
+}
+
+void libvlc_MlRelease( vlc_medialibrary_t* p_ml )
+{
+ assert( p_ml != NULL );
+ module_unneed( p_ml, p_ml->p_module );
+ vlc_object_release( p_ml );
+}
+
+#undef vlc_ml_get
+vlc_medialibrary_t* vlc_ml_get( vlc_object_t* p_obj )
+{
+ libvlc_priv_t* p_priv = libvlc_priv( p_obj->obj.libvlc );
+ return p_priv->p_media_library;
+}
+
+static void vlc_ml_show_release_inner( vlc_ml_show_t* p_show )
+{
+ free( p_show->psz_artwork_mrl );
+ free( p_show->psz_name );
+ free( p_show->psz_summary );
+ free( p_show->psz_tvdb_id );
+}
+
+void vlc_ml_show_release( vlc_ml_show_t* p_show )
+{
+ if ( p_show == NULL )
+ return;
+ vlc_ml_show_release_inner( p_show );
+ free( p_show );
+}
+
+static void vlc_ml_media_release_tracks_inner( vlc_ml_media_track_list_t* p_tracks )
+{
+ if ( p_tracks == NULL )
+ return;
+ for ( size_t i = 0; i < p_tracks->i_nb_items; ++i )
+ {
+ vlc_ml_media_track_t* p_track = &p_tracks->p_items[i];
+ free( p_track->psz_codec );
+ free( p_track->psz_language );
+ free( p_track->psz_description );
+ }
+ free( p_tracks );
+}
+
+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 );
+ switch( p_media->i_subtype )
+ {
+ case VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK:
+ break;
+ case VLC_ML_MEDIA_SUBTYPE_SHOW_EPISODE:
+ free( p_media->show_episode.psz_summary );
+ free( p_media->show_episode.psz_tvdb_id );
+ break;
+ case VLC_ML_MEDIA_SUBTYPE_MOVIE:
+ free( p_media->movie.psz_summary );
+ free( p_media->movie.psz_imdb_id );
+ break;
+ default:
+ break;
+ }
+}
+
+static void vlc_ml_artist_release_inner( vlc_ml_artist_t* p_artist )
+{
+ free( p_artist->psz_artwork_mrl );
+ free( p_artist->psz_name );
+ free( p_artist->psz_shortbio );
+ free( p_artist->psz_mb_id );
+}
+
+void vlc_ml_artist_release( vlc_ml_artist_t* p_artist )
+{
+ if ( p_artist == NULL )
+ return;
+ vlc_ml_artist_release_inner( p_artist );
+ free( p_artist );
+}
+
+static void vlc_ml_album_release_inner( vlc_ml_album_t* p_album )
+{
+ free( p_album->psz_artist );
+ free( p_album->psz_artwork_mrl );
+ free( p_album->psz_summary );
+ free( p_album->psz_title );
+}
+
+void vlc_ml_album_release( vlc_ml_album_t* p_album )
+{
+ if ( p_album == NULL )
+ return;
+ vlc_ml_album_release_inner( p_album );
+ free( p_album );
+}
+
+void vlc_ml_genre_release( vlc_ml_genre_t* p_genre )
+{
+ if ( p_genre == NULL )
+ return;
+ free( p_genre->psz_name );
+ free( p_genre );
+}
+
+static void vlc_ml_playlist_release_inner( vlc_ml_playlist_t* p_playlist )
+{
+ free( p_playlist->psz_artwork_mrl );
+ free( p_playlist->psz_name );
+}
+
+void vlc_ml_playlist_release( vlc_ml_playlist_t* p_playlist )
+{
+ if ( p_playlist == NULL )
+ return;
+ vlc_ml_playlist_release_inner( p_playlist );
+ free( p_playlist );
+}
+
+/* Lists release */
+
+void vlc_ml_media_release( vlc_ml_media_t* p_media )
+{
+ if ( p_media == NULL )
+ return;
+ vlc_ml_media_release_inner( p_media );
+ free( p_media );
+}
+
+void vlc_ml_label_list_release( vlc_ml_label_list_t* p_list )
+{
+ if ( p_list == NULL )
+ return;
+ for ( size_t i = 0; i < p_list->i_nb_items; ++i )
+ free( p_list->p_items[i].psz_name );
+ free( p_list );
+}
+
+void vlc_ml_file_list_release( vlc_ml_file_list_t* p_list )
+{
+ if ( p_list == NULL )
+ return;
+ for ( size_t i = 0; i < p_list->i_nb_items; ++i )
+ free( p_list->p_items[i].psz_mrl );
+ free( p_list );
+}
+
+void vlc_ml_artist_list_release( vlc_ml_artist_list_t* p_list )
+{
+ if ( p_list == NULL )
+ return;
+ for ( size_t i = 0; i < p_list->i_nb_items; ++i )
+ vlc_ml_artist_release_inner( &p_list->p_items[i] );
+ free( p_list );
+}
+
+
+void vlc_ml_media_list_release( vlc_ml_media_list_t* p_list )
+{
+ if ( p_list == NULL )
+ return;
+ for ( size_t i = 0; i < p_list->i_nb_items; ++i )
+ vlc_ml_media_release_inner( &p_list->p_items[i] );
+ free( p_list );
+}
+
+void vlc_ml_album_list_release( vlc_ml_album_list_t* p_list )
+{
+ if ( p_list == NULL )
+ return;
+ for ( size_t i = 0; i < p_list->i_nb_items; ++i )
+ vlc_ml_album_release_inner( &p_list->p_items[i] );
+ free( p_list );
+}
+
+void vlc_ml_show_list_release( vlc_ml_show_list_t* p_list )
+{
+ if ( p_list == NULL )
+ return;
+ for ( size_t i = 0; i < p_list->i_nb_items; ++i )
+ vlc_ml_show_release_inner( &p_list->p_items[i] );
+ free( p_list );
+}
+
+void vlc_ml_genre_list_release( vlc_ml_genre_list_t* p_list )
+{
+ if ( p_list == NULL )
+ return;
+ for ( size_t i = 0; i < p_list->i_nb_items; ++i )
+ free( p_list->p_items[i].psz_name );
+ free( p_list );
+}
+
+void vlc_ml_playlist_list_release( vlc_ml_playlist_list_t* p_list )
+{
+ if ( p_list == NULL )
+ return;
+ for ( size_t i = 0; i < p_list->i_nb_items; ++i )
+ vlc_ml_playlist_release_inner( &p_list->p_items[i] );
+ free( p_list );
+}
More information about the vlc-commits
mailing list