medialib: Add bookmark support

This commit is contained in:
Hugo Beauzée-Luyssen 2020-03-11 12:22:17 +01:00
parent 3e4307ef78
commit 7cbdb33cce
6 changed files with 188 additions and 16 deletions

View File

@ -305,6 +305,20 @@ typedef struct vlc_ml_entry_point_list_t
vlc_ml_entry_point_t p_items[];
} vlc_ml_entry_point_list_t;
typedef struct vlc_ml_bookmark_t
{
int64_t i_media_id; /**< The associated media ID */
int64_t i_time; /**< The bookmark time. The unit is arbitrary */
char* psz_name; /**< The bookmark name */
char* psz_description; /**< The bookmark description */
} vlc_ml_bookmark_t;
typedef struct vlc_ml_boomkmark_list_t
{
size_t i_nb_items;
vlc_ml_bookmark_t p_items[];
} vlc_ml_bookmark_list_t;
/* Opaque medialibrary pointer, to be used by any non-medialibrary module */
typedef struct vlc_medialibrary_t vlc_medialibrary_t;
/* "Private" medialibrary pointer, to be used by the core & medialibrary modules */
@ -404,6 +418,7 @@ enum vlc_ml_list_queries
/* 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* */
VLC_ML_LIST_MEDIA_BOOKMARKS, /**< arg1: media id; arg2 (out): vlc_ml_bookmark_list_t** */
/* Playlist specific listings */
VLC_ML_LIST_PLAYLIST_MEDIA, /**< arg1: playlist id; arg2 (out): vlc_ml_media_list_t** */
@ -465,6 +480,10 @@ enum vlc_ml_control
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) */
VLC_ML_MEDIA_SET_TYPE, /**< arg1: media id; arg2: vlc_ml_media_type_t */
VLC_ML_MEDIA_ADD_BOOKMARK, /**< arg1: media id; arg2: int64_t */
VLC_ML_MEDIA_REMOVE_BOOKMARK, /**< arg1: media id; arg2: int64_t */
VLC_ML_MEDIA_REMOVE_ALL_BOOKMARKS, /**< arg1: media id */
VLC_ML_MEDIA_UPDATE_BOOKMARK, /**< arg1: media id; arg2: int64_t; arg3: const char*; arg4: const char* */
};
/**
@ -541,6 +560,9 @@ enum vlc_ml_event_type
VLC_ML_EVENT_GENRE_ADDED,
VLC_ML_EVENT_GENRE_UPDATED,
VLC_ML_EVENT_GENRE_DELETED,
VLC_ML_EVENT_BOOKMARKS_ADDED,
VLC_ML_EVENT_BOOKMARKS_UPDATED,
VLC_ML_EVENT_BOOKMARKS_DELETED,
/**
* A discovery started.
* For each VLC_ML_EVENT_DISCOVERY_STARTED event, there will be
@ -704,6 +726,7 @@ typedef struct vlc_ml_event_t
const vlc_ml_album_t* p_album;
const vlc_ml_playlist_t* p_playlist;
const vlc_ml_genre_t* p_genre;
const vlc_ml_bookmark_t* p_bookmark;
} creation;
struct
{
@ -827,6 +850,8 @@ 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 );
VLC_API void vlc_ml_entry_point_list_release( vlc_ml_entry_point_list_t* p_list );
VLC_API void vlc_ml_playback_states_all_release( vlc_ml_playback_states_all* prefs );
VLC_API void vlc_ml_bookmark_release( vlc_ml_bookmark_t* p_bookmark );
VLC_API void vlc_ml_bookmark_list_release( vlc_ml_bookmark_list_t* p_list );
static inline vlc_ml_query_params_t vlc_ml_query_params_create()
{
@ -964,6 +989,49 @@ static inline int vlc_ml_media_set_type( vlc_medialibrary_t* p_ml, int64_t i_med
return vlc_ml_control( p_ml, VLC_ML_MEDIA_SET_TYPE, i_media_id, (int)i_type );
}
static inline vlc_ml_bookmark_list_t*
vlc_ml_list_media_bookmarks( vlc_medialibrary_t* p_ml, const vlc_ml_query_params_t* params,
int64_t i_media_id )
{
assert( p_ml != NULL );
vlc_ml_bookmark_list_t* res;
if ( vlc_ml_list( p_ml, VLC_ML_LIST_MEDIA_BOOKMARKS, params, i_media_id,
&res ) != VLC_SUCCESS )
return NULL;
return res;
}
static inline int
vlc_ml_media_add_bookmark( vlc_medialibrary_t* p_ml, int64_t i_media_id, int64_t i_time )
{
assert( p_ml != NULL );
return vlc_ml_control( p_ml, VLC_ML_MEDIA_ADD_BOOKMARK, i_media_id, i_time );
}
static inline int
vlc_ml_media_remove_bookmark( vlc_medialibrary_t* p_ml, int64_t i_media_id, int64_t i_time )
{
assert( p_ml != NULL );
return vlc_ml_control( p_ml, VLC_ML_MEDIA_REMOVE_BOOKMARK, i_media_id, i_time );
}
static inline int
vlc_ml_media_update_bookmark( vlc_medialibrary_t* p_ml, int64_t i_media_id,
int64_t i_time, const char* psz_name,
const char* psz_desc )
{
assert( p_ml != NULL );
return vlc_ml_control( p_ml, VLC_ML_MEDIA_UPDATE_BOOKMARK, i_media_id,
i_time, psz_name, psz_desc );
}
static inline int
vlc_ml_media_remove_all_bookmarks( vlc_medialibrary_t* p_ml, int64_t i_media_id )
{
assert( p_ml != NULL );
return vlc_ml_control( p_ml, VLC_ML_MEDIA_REMOVE_ALL_BOOKMARKS, i_media_id );
}
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*)vlc_ml_get( p_ml, VLC_ML_GET_MEDIA, i_media_id );
@ -1416,7 +1484,9 @@ static inline size_t vlc_ml_count_playlist_media( vlc_medialibrary_t* p_ml, cons
vlc_ml_genre_list_t*: vlc_ml_genre_list_release, \
vlc_ml_playlist_list_t*: vlc_ml_playlist_list_release, \
vlc_ml_entry_point_list_t*: vlc_ml_entry_point_list_release, \
vlc_ml_playback_states_all*: vlc_ml_playback_states_all_release \
vlc_ml_playback_states_all*: vlc_ml_playback_states_all_release, \
vlc_ml_bookmark_t*: vlc_ml_bookmark_release, \
vlc_ml_bookmark_list_t*: vlc_ml_bookmark_list_release \
)( OBJ )
#else
static inline void vlc_ml_release( vlc_ml_show_t* show ) { vlc_ml_show_release( show ); }
@ -1435,6 +1505,8 @@ static inline void vlc_ml_release( vlc_ml_genre_list_t* list ) { vlc_ml_genre_li
static inline void vlc_ml_release( vlc_ml_playlist_list_t* list ) { vlc_ml_playlist_list_release( list ); }
static inline void vlc_ml_release( vlc_ml_entry_point_list_t* list ) { vlc_ml_entry_point_list_release( list ); }
static inline void vlc_ml_release( vlc_ml_playback_states_all* prefs ) { vlc_ml_playback_states_all_release( prefs ); }
static inline void vlc_ml_release( vlc_ml_bookmark_t* bookmark ) { vlc_ml_bookmark_release( bookmark ); }
static inline void vlc_ml_release( vlc_ml_bookmark_list_t* list ) { vlc_ml_bookmark_list_release( list ); }
#endif
#endif /* VLC_MEDIA_LIBRARY_H */

View File

@ -40,6 +40,7 @@
#include <medialibrary/IFolder.h>
#include <medialibrary/filesystem/IDevice.h>
#include <medialibrary/filesystem/Errors.h>
#include <medialibrary/IBookmark.h>
#include <algorithm>
@ -416,6 +417,16 @@ bool Convert( const medialibrary::IFolder* input, vlc_ml_entry_point_t& output )
return true;
}
bool Convert( const medialibrary::IBookmark* input, vlc_ml_bookmark_t& output )
{
if ( strdup_helper( input->name(), output.psz_name ) == false ||
strdup_helper( input->description(), output.psz_description ) == false )
return false;
output.i_media_id = input->mediaId();
output.i_time = input->time();
return true;
}
input_item_t* MediaToInputItem( const medialibrary::IMedia* media )
{
if ( media == nullptr )

View File

@ -39,6 +39,7 @@
#include <medialibrary/IMetadata.h>
#include <medialibrary/IShow.h>
#include <medialibrary/IPlaylist.h>
#include <medialibrary/IBookmark.h>
#include <sstream>
#include <initializer_list>
@ -82,6 +83,7 @@ void assignToEvent( vlc_ml_event_t* ev, vlc_ml_artist_t* a ) { ev->creation.p_
void assignToEvent( vlc_ml_event_t* ev, vlc_ml_album_t* a ) { ev->creation.p_album = a; }
void assignToEvent( vlc_ml_event_t* ev, vlc_ml_genre_t* g ) { ev->creation.p_genre = g; }
void assignToEvent( vlc_ml_event_t* ev, vlc_ml_playlist_t* p ) { ev->creation.p_playlist = p; }
void assignToEvent( vlc_ml_event_t* ev, vlc_ml_bookmark_t* b ) { ev->creation.p_bookmark = b; }
template <typename To, typename From>
void wrapEntityCreatedEventCallback( vlc_medialibrary_module_t* ml,
@ -217,19 +219,22 @@ void MediaLibrary::onMediaGroupsDeleted( std::set<int64_t> )
{
}
void MediaLibrary::onBookmarksAdded( std::vector<medialibrary::BookmarkPtr> )
void MediaLibrary::onBookmarksAdded( std::vector<medialibrary::BookmarkPtr> bookmarks )
{
wrapEntityCreatedEventCallback<vlc_ml_bookmark_t>( m_vlc_ml, bookmarks,
VLC_ML_EVENT_BOOKMARKS_ADDED );
}
void MediaLibrary::onBookmarksModified( std::set<int64_t> )
void MediaLibrary::onBookmarksModified( std::set<int64_t> bookmarkIds )
{
wrapEntityModifiedEventCallback( m_vlc_ml, bookmarkIds,
VLC_ML_EVENT_BOOKMARKS_UPDATED );
}
void MediaLibrary::onBookmarksDeleted( std::set<int64_t> )
void MediaLibrary::onBookmarksDeleted( std::set<int64_t> bookmarkIds )
{
wrapEntityDeletedEventCallback( m_vlc_ml, bookmarkIds,
VLC_ML_EVENT_BOOKMARKS_DELETED );
}
void MediaLibrary::onDiscoveryStarted( const std::string& entryPoint )
@ -594,6 +599,10 @@ int MediaLibrary::Control( int query, va_list args )
case VLC_ML_MEDIA_GENERATE_THUMBNAIL:
case VLC_ML_MEDIA_ADD_EXTERNAL_MRL:
case VLC_ML_MEDIA_SET_TYPE:
case VLC_ML_MEDIA_ADD_BOOKMARK:
case VLC_ML_MEDIA_REMOVE_BOOKMARK:
case VLC_ML_MEDIA_REMOVE_ALL_BOOKMARKS:
case VLC_ML_MEDIA_UPDATE_BOOKMARK:
return controlMedia( query, args );
default:
return VLC_EGENERIC;
@ -795,6 +804,7 @@ int MediaLibrary::List( int listQuery, const vlc_ml_query_params_t* params, va_l
case VLC_ML_LIST_MEDIA_LABELS:
case VLC_ML_COUNT_MEDIA_LABELS:
case VLC_ML_LIST_MEDIA_BOOKMARKS:
return listMedia( listQuery, paramsPtr, psz_pattern, nbItems, offset, args );
case VLC_ML_LIST_SHOWS:
@ -1232,6 +1242,43 @@ int MediaLibrary::controlMedia( int query, va_list args )
return VLC_EGENERIC;
return VLC_SUCCESS;
}
case VLC_ML_MEDIA_ADD_BOOKMARK:
{
auto time = va_arg( args, int64_t );
if ( m->addBookmark( time ) == nullptr )
return VLC_EGENERIC;
return VLC_EGENERIC;
}
case VLC_ML_MEDIA_REMOVE_BOOKMARK:
{
auto time = va_arg( args, int64_t );
if ( m->removeBookmark( time ) == false )
return VLC_EGENERIC;
return VLC_SUCCESS;
}
case VLC_ML_MEDIA_REMOVE_ALL_BOOKMARKS:
{
if ( m->removeAllBookmarks() == false )
return VLC_EGENERIC;
return VLC_SUCCESS;
}
case VLC_ML_MEDIA_UPDATE_BOOKMARK:
{
auto time = va_arg( args, int64_t );
auto name = va_arg( args, const char* );
auto desc = va_arg( args, const char* );
auto bookmark = m->bookmark( time );
if ( bookmark == nullptr )
return VLC_EGENERIC;
auto res = false;
if ( name != nullptr && desc != nullptr )
res = bookmark->setNameAndDescription( name, desc );
else if ( name != nullptr )
res = bookmark->setName( name );
else if ( desc != nullptr )
res = bookmark->setDescription( desc );
return res ? VLC_SUCCESS : VLC_EGENERIC;
}
default:
vlc_assert_unreachable();
}
@ -1584,26 +1631,42 @@ int MediaLibrary::listPlaylist( int listQuery, const medialibrary::QueryParamete
}
}
int MediaLibrary::listMedia( int listQuery, const medialibrary::QueryParameters *,
int MediaLibrary::listMedia( int listQuery, const medialibrary::QueryParameters *params,
const char *, uint32_t nbItems, uint32_t offset,
va_list args )
{
auto media = m_ml->media( va_arg( args, int64_t ) );
if ( media == nullptr )
return VLC_EGENERIC;
auto query = media->labels();
if ( query == nullptr )
return VLC_EGENERIC;
switch ( listQuery )
{
case VLC_ML_LIST_MEDIA_LABELS:
*va_arg( args, vlc_ml_label_list_t**) =
ml_convert_list<vlc_ml_label_list_t, vlc_ml_label_t>(
query->items( nbItems, offset ) );
return VLC_SUCCESS;
case VLC_ML_COUNT_MEDIA_LABELS:
*va_arg( args, size_t* ) = query->count();
{
auto query = media->labels();
if ( query == nullptr )
return VLC_EGENERIC;
switch ( listQuery )
{
case VLC_ML_LIST_MEDIA_LABELS:
*va_arg( args, vlc_ml_label_list_t**) =
ml_convert_list<vlc_ml_label_list_t, vlc_ml_label_t>(
query->items( nbItems, offset ) );
return VLC_SUCCESS;
case VLC_ML_COUNT_MEDIA_LABELS:
*va_arg( args, size_t* ) = query->count();
return VLC_SUCCESS;
default:
vlc_assert_unreachable();
}
}
case VLC_ML_LIST_MEDIA_BOOKMARKS:
{
*va_arg( args, vlc_ml_bookmark_list_t** ) =
ml_convert_list<vlc_ml_bookmark_list_t, vlc_ml_bookmark_t>(
media->bookmarks( params )->all() );
return VLC_SUCCESS;
}
default:
vlc_assert_unreachable();
}

View File

@ -220,6 +220,7 @@ 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::IPlaylist* input, vlc_ml_playlist_t& output );
bool Convert( const medialibrary::IFolder* input, vlc_ml_entry_point_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>

View File

@ -575,6 +575,8 @@ vlc_ml_show_list_release
vlc_ml_genre_list_release
vlc_ml_playlist_list_release
vlc_ml_entry_point_list_release
vlc_ml_bookmark_release
vlc_ml_bookmark_list_release
vlc_poll_i11e
vlc_read_i11e
vlc_readv_i11e

View File

@ -348,6 +348,29 @@ void vlc_ml_playback_states_all_release( vlc_ml_playback_states_all* prefs )
free( prefs->video_filter );
}
static void vlc_ml_bookmark_release_inner( vlc_ml_bookmark_t* bookmark )
{
free( bookmark->psz_name );
free( bookmark->psz_description );
}
void vlc_ml_bookmark_release( vlc_ml_bookmark_t* bookmark )
{
if ( bookmark == NULL )
return;
vlc_ml_bookmark_release_inner( bookmark );
free( bookmark );
}
void vlc_ml_bookmark_list_release( vlc_ml_bookmark_list_t* list )
{
if ( list == NULL )
return;
for ( size_t i = 0; i < list->i_nb_items; ++i )
vlc_ml_bookmark_release_inner( &list->p_items[i] );
free( list );
}
void* vlc_ml_get( vlc_medialibrary_t* p_ml, int i_query, ... )
{
assert( p_ml != NULL );