From ab9b8df2dd262316c4d2acb754c26a0c72de6c43 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Tue, 23 Oct 2018 12:39:54 +0200 Subject: [PATCH] playlist: assign unique id to playlist items Playlist items are intended to be handled by index (with lock held) or by instance (vlc_playlist_item_t *). Some modules, like http, require to reference playlist items "remotely". To simplify their implementation, assign an id, unique within a playlist instance, to every items. Signed-off-by: Thomas Guillem --- include/vlc_playlist.h | 16 ++++++++++++++++ src/libvlccore.sym | 2 ++ src/playlist/content.c | 27 +++++++++++++++++++++------ src/playlist/item.c | 9 ++++++++- src/playlist/item.h | 3 ++- src/playlist/playlist.c | 1 + src/playlist/playlist.h | 1 + src/playlist/preparse.c | 9 ++++++--- src/playlist/test.c | 4 ++-- 9 files changed, 59 insertions(+), 13 deletions(-) diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 6cc5eaf4ec..4a49e59c09 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -316,6 +316,12 @@ vlc_playlist_item_Release(vlc_playlist_item_t *); VLC_API input_item_t * vlc_playlist_item_GetMedia(vlc_playlist_item_t *); +/** + * Return a unique id for the playlist item instance. + */ +VLC_API uint64_t +vlc_playlist_item_GetId(vlc_playlist_item_t *); + /* Playlist */ /** @@ -655,6 +661,16 @@ vlc_playlist_IndexOf(vlc_playlist_t *playlist, const vlc_playlist_item_t *item); VLC_API ssize_t vlc_playlist_IndexOfMedia(vlc_playlist_t *playlist, const input_item_t *media); +/** + * Return the index of a given item id. + * + * \param playlist the playlist, locked + * \param id the id to locate + * \return the index of the playlist item having the id (-1 if not found) + */ +VLC_API ssize_t +vlc_playlist_IndexOfId(vlc_playlist_t *playlist, uint64_t id); + /** * Return the playback "repeat" mode. * diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 19ec18d0c2..b7f9aa1e9e 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -936,6 +936,7 @@ vlc_player_vout_Snapshot vlc_playlist_item_Hold vlc_playlist_item_Release vlc_playlist_item_GetMedia +vlc_playlist_item_GetId vlc_playlist_New vlc_playlist_Delete vlc_playlist_Lock @@ -955,6 +956,7 @@ vlc_playlist_Shuffle vlc_playlist_Sort vlc_playlist_IndexOf vlc_playlist_IndexOfMedia +vlc_playlist_IndexOfId vlc_playlist_GetPlaybackRepeat vlc_playlist_GetPlaybackOrder vlc_playlist_SetPlaybackRepeat diff --git a/src/playlist/content.c b/src/playlist/content.c index 43b3800d9f..5f307a9a79 100644 --- a/src/playlist/content.c +++ b/src/playlist/content.c @@ -205,6 +205,18 @@ vlc_playlist_IndexOfMedia(vlc_playlist_t *playlist, const input_item_t *media) return -1; } +ssize_t +vlc_playlist_IndexOfId(vlc_playlist_t *playlist, uint64_t id) +{ + vlc_playlist_AssertLocked(playlist); + + playlist_item_vector_t *items = &playlist->items; + for (size_t i = 0; i < items->size; ++i) + if (items->data[i]->id == id) + return i; + return -1; +} + void vlc_playlist_Clear(vlc_playlist_t *playlist) { @@ -218,13 +230,15 @@ vlc_playlist_Clear(vlc_playlist_t *playlist) } static int -vlc_playlist_MediaToItems(input_item_t *const media[], size_t count, - vlc_playlist_item_t *items[]) +vlc_playlist_MediaToItems(vlc_playlist_t *playlist, input_item_t *const media[], + size_t count, vlc_playlist_item_t *items[]) { + vlc_playlist_AssertLocked(playlist); size_t i; for (i = 0; i < count; ++i) { - items[i] = vlc_playlist_item_New(media[i]); + uint64_t id = playlist->idgen++; + items[i] = vlc_playlist_item_New(media[i], id); if (unlikely(!items[i])) break; } @@ -250,7 +264,7 @@ vlc_playlist_Insert(vlc_playlist_t *playlist, size_t index, return VLC_ENOMEM; /* create playlist items in place */ - int ret = vlc_playlist_MediaToItems(media, count, + int ret = vlc_playlist_MediaToItems(playlist, media, count, &playlist->items.data[index]); if (ret != VLC_SUCCESS) { @@ -307,7 +321,8 @@ vlc_playlist_Replace(vlc_playlist_t *playlist, size_t index, vlc_playlist_AssertLocked(playlist); assert(index < playlist->items.size); - vlc_playlist_item_t *item = vlc_playlist_item_New(media); + uint64_t id = playlist->idgen++; + vlc_playlist_item_t *item = vlc_playlist_item_New(media, id); if (!item) return VLC_ENOMEM; @@ -347,7 +362,7 @@ vlc_playlist_Expand(vlc_playlist_t *playlist, size_t index, return VLC_ENOMEM; /* create playlist items in place */ - ret = vlc_playlist_MediaToItems(&media[1], count - 1, + ret = vlc_playlist_MediaToItems(playlist, &media[1], count - 1, &playlist->items.data[index + 1]); if (ret != VLC_SUCCESS) { diff --git a/src/playlist/item.c b/src/playlist/item.c index 3cf06f9b3a..e4a1060e93 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -28,13 +28,14 @@ #include vlc_playlist_item_t * -vlc_playlist_item_New(input_item_t *media) +vlc_playlist_item_New(input_item_t *media, uint64_t id) { vlc_playlist_item_t *item = malloc(sizeof(*item)); if (unlikely(!item)) return NULL; vlc_atomic_rc_init(&item->rc); + item->id = id; item->media = media; input_item_Hold(media); return item; @@ -61,3 +62,9 @@ vlc_playlist_item_GetMedia(vlc_playlist_item_t *item) { return item->media; } + +uint64_t +vlc_playlist_item_GetId(vlc_playlist_item_t *item) +{ + return item->id; +} diff --git a/src/playlist/item.h b/src/playlist/item.h index f55cc83e84..1c4f03add7 100644 --- a/src/playlist/item.h +++ b/src/playlist/item.h @@ -29,11 +29,12 @@ typedef struct input_item_t input_item_t; struct vlc_playlist_item { input_item_t *media; + uint64_t id; vlc_atomic_rc_t rc; }; /* _New() is private, it is called when inserting new media in the playlist */ vlc_playlist_item_t * -vlc_playlist_item_New(input_item_t *media); +vlc_playlist_item_New(input_item_t *media, uint64_t id); #endif diff --git a/src/playlist/playlist.c b/src/playlist/playlist.c index 618433c9e3..94e33c0e52 100644 --- a/src/playlist/playlist.c +++ b/src/playlist/playlist.c @@ -52,6 +52,7 @@ vlc_playlist_New(vlc_object_t *parent) vlc_list_init(&playlist->listeners); playlist->repeat = VLC_PLAYLIST_PLAYBACK_REPEAT_NONE; playlist->order = VLC_PLAYLIST_PLAYBACK_ORDER_NORMAL; + playlist->idgen = 0; return playlist; } diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h index 1090d2146b..da1e082fae 100644 --- a/src/playlist/playlist.h +++ b/src/playlist/playlist.h @@ -57,6 +57,7 @@ struct vlc_playlist struct vlc_list listeners; /**< list of vlc_playlist_listener_id.node */ enum vlc_playlist_playback_repeat repeat; enum vlc_playlist_playback_order order; + uint64_t idgen; }; static inline void diff --git a/src/playlist/preparse.c b/src/playlist/preparse.c index c636757ff5..c82ce2b675 100644 --- a/src/playlist/preparse.c +++ b/src/playlist/preparse.c @@ -32,14 +32,17 @@ typedef struct VLC_VECTOR(input_item_t *) media_vector_t; static void -vlc_playlist_CollectChildren(media_vector_t *dest, input_item_node_t *node) +vlc_playlist_CollectChildren(vlc_playlist_t *playlist, + media_vector_t *dest, + input_item_node_t *node) { + vlc_playlist_AssertLocked(playlist); for (int i = 0; i < node->i_children; ++i) { input_item_node_t *child = node->pp_children[i]; input_item_t *media = child->p_item; vlc_vector_push(dest, media); - vlc_playlist_CollectChildren(dest, child); + vlc_playlist_CollectChildren(playlist, dest, child); } } @@ -50,7 +53,7 @@ vlc_playlist_ExpandItem(vlc_playlist_t *playlist, size_t index, vlc_playlist_AssertLocked(playlist); media_vector_t flatten = VLC_VECTOR_INITIALIZER; - vlc_playlist_CollectChildren(&flatten, node); + vlc_playlist_CollectChildren(playlist, &flatten, node); int ret = vlc_playlist_Expand(playlist, index, flatten.data, flatten.size); vlc_vector_destroy(&flatten); diff --git a/src/playlist/test.c b/src/playlist/test.c index c2740cb156..aebcfdb9c8 100644 --- a/src/playlist/test.c +++ b/src/playlist/test.c @@ -1504,7 +1504,7 @@ test_request_remove_adapt(void) vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); - vlc_playlist_item_t *dummy = vlc_playlist_item_New(media[10]); + vlc_playlist_item_t *dummy = vlc_playlist_item_New(media[10], 0); assert(dummy); /* remove items in a wrong order at wrong position, as if the playlist had @@ -1702,7 +1702,7 @@ test_request_move_adapt(void) vlc_playlist_AddListener(playlist, &cbs, &ctx, false); assert(listener); - vlc_playlist_item_t *dummy = vlc_playlist_item_New(media[15]); + vlc_playlist_item_t *dummy = vlc_playlist_item_New(media[15], 0); assert(dummy); /* move items in a wrong order at wrong position, as if the playlist had