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 <thomas@gllm.fr>
This commit is contained in:
Romain Vimont 2018-10-23 12:39:54 +02:00 committed by Thomas Guillem
parent f322ccbbcb
commit ab9b8df2dd
9 changed files with 59 additions and 13 deletions

View File

@ -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.
*

View File

@ -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

View File

@ -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)
{

View File

@ -28,13 +28,14 @@
#include <vlc_input_item.h>
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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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