1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2018 VLC authors and VideoLAN
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
21 #ifndef VLC_PLAYLIST_NEW_H
22 #define VLC_PLAYLIST_NEW_H
24 #include <vlc_common.h>
31 * \defgroup playlist VLC playlist
34 * A VLC playlist contains a list of "playlist items".
36 * Each playlist item contains exactly one media (input item). In the future,
37 * it might contain associated data.
39 * The API is intended to be simple, UI-friendly and allow for an
40 * implementation both correct (no race conditions) and performant for common
43 * UI frameworks typically use "list models" to provide a list of items to a
44 * list view component. A list model requires to implement functions to:
45 * - return the total number of items,
46 * - return the item at a given index.
48 * In addition, it must notify the view when changes occur when:
49 * - items are inserted (providing index and count),
50 * - items are removed (providing index and count),
51 * - items are moved (providing index, count, and target index),
52 * - items are updated (providing index and count),
53 * - the model is reset (the whole content should be considered changed).
55 * The API directly exposes what list models require.
57 * The core playlist may be modified from any thread, so it may not be used as
58 * a direct data source for a list model. In other word, the functions of a
59 * list model must not delegate the calls to the playlist. This would require
60 * locking the playlist individually for each call to get the count and
61 * retrieve each item (which is, in itself, not a good idea for UI
62 * responsiveness), and would not be sufficient to guarantee correctness: the
63 * playlist content could change between view calls so that a request to
64 * retrieve an item at a specific index could be invalid (which would break the
65 * list model expected behavior).
67 * As a consequence, the UI playlist should be considered as a remote
68 * out-of-sync view of the core playlist. This implies that the UI needs to
69 * keep a copy of the playlist content.
71 * Note that the copy must not limited to the list of playlist items (pointers)
72 * themselves, but also to the items content which is displayed and susceptible
73 * to change asynchronously (e.g. media metadata, like title or duration). The
74 * UI should never lock a media (input item) for rendering a playlist item;
75 * otherwise, the content could be changed (and exposed) before the list model
76 * notified the view of this change (which, again, would break the list model
79 * It is very important that the copy hold by the UI is only modified through
80 * the core playlist callbacks, to guarantee that the indexes notified are
81 * valid in the context of the list model. In other words, from the client, the
82 * playlist copy is a read-only "desynchronized" view of the core playlist.
84 * Moreover, the events triggered by the playlist must be kept in order until
85 * they are handled. The callbacks may be called from any thread, with lock
86 * held (in practice, the thread from which a change is requested). An UI will
87 * typically need to handle the events in the UI thread, so it will usually
88 * post the events in an even loop, to handle them from the UI thread. In that
89 * case, be careful to always post the events in the event loop, even if the
90 * current thread is already the UI thread, not to break the order of events.
92 * The playlist also handles the playback order and the repeat mode. It also
93 * manages a cursor to the "current" item, and expose whether a previous and
94 * next items (which depend on the playback order and repeat mode) are
97 * When a user requests to insert, move or remove items, or to set the current
98 * item, before the core playlist lock is successfully acquired, another client
99 * may have changed the list. Therefore, vlc_playlist_Request*() functions are
100 * exposed to resolve potential conflicts and apply the changes. The actual
101 * changes applied are notified through the callbacks
106 /* forward declarations */
107 typedef struct input_item_t input_item_t
;
108 typedef struct vlc_player_t vlc_player_t
;
111 typedef struct vlc_playlist vlc_playlist_t
;
112 typedef struct vlc_playlist_item vlc_playlist_item_t
;
113 typedef struct vlc_playlist_listener_id vlc_playlist_listener_id
;
115 enum vlc_playlist_playback_repeat
117 VLC_PLAYLIST_PLAYBACK_REPEAT_NONE
,
118 VLC_PLAYLIST_PLAYBACK_REPEAT_CURRENT
,
119 VLC_PLAYLIST_PLAYBACK_REPEAT_ALL
,
122 enum vlc_playlist_playback_order
124 VLC_PLAYLIST_PLAYBACK_ORDER_NORMAL
,
125 VLC_PLAYLIST_PLAYBACK_ORDER_RANDOM
,
128 enum vlc_playlist_sort_key
130 VLC_PLAYLIST_SORT_KEY_TITLE
,
131 VLC_PLAYLIST_SORT_KEY_DURATION
,
132 VLC_PLAYLIST_SORT_KEY_ARTIST
,
133 VLC_PLAYLIST_SORT_KEY_ALBUM
,
134 VLC_PLAYLIST_SORT_KEY_ALBUM_ARTIST
,
135 VLC_PLAYLIST_SORT_KEY_GENRE
,
136 VLC_PLAYLIST_SORT_KEY_DATE
,
137 VLC_PLAYLIST_SORT_KEY_TRACK_NUMBER
,
138 VLC_PLAYLIST_SORT_KEY_DISC_NUMBER
,
139 VLC_PLAYLIST_SORT_KEY_URL
,
140 VLC_PLAYLIST_SORT_KEY_RATING
,
143 enum vlc_playlist_sort_order
145 VLC_PLAYLIST_SORT_ORDER_ASCENDING
,
146 VLC_PLAYLIST_SORT_ORDER_DESCENDING
,
149 struct vlc_playlist_sort_criterion
151 enum vlc_playlist_sort_key key
;
152 enum vlc_playlist_sort_order order
;
156 * Playlist callbacks.
158 * A client may register a listener using vlc_playlist_AddListener() to listen
161 * All callbacks are called with the playlist locked (see vlc_playlist_Lock()).
163 struct vlc_playlist_callbacks
166 * Called when the whole content has changed (e.g. when the playlist has
167 * been cleared, shuffled or sorted).
169 * \param playlist the playlist
170 * \param items the whole new content of the playlist
171 * \param count the number of items
172 * \param userdata userdata provided to AddListener()
175 (*on_items_reset
)(vlc_playlist_t
*, vlc_playlist_item_t
*const items
[],
176 size_t count
, void *userdata
);
179 * Called when items have been added to the playlist.
181 * \param playlist the playlist
182 * \param index the index of the insertion
183 * \param items the array of added items
184 * \param count the number of items added
185 * \param userdata userdata provided to AddListener()
188 (*on_items_added
)(vlc_playlist_t
*playlist
, size_t index
,
189 vlc_playlist_item_t
*const items
[], size_t count
,
193 * Called when a slice of items have been moved.
195 * \param playlist the playlist
196 * \param index the index of the first moved item
197 * \param count the number of items moved
198 * \param target the new index of the moved slice
199 * \param userdata userdata provided to AddListener()
202 (*on_items_moved
)(vlc_playlist_t
*playlist
, size_t index
, size_t count
,
203 size_t target
, void *userdata
);
205 * Called when a slice of items have been removed from the playlist.
207 * \param playlist the playlist
208 * \param index the index of the first removed item
209 * \param count the number of items removed
210 * \param userdata userdata provided to AddListener()
213 (*on_items_removed
)(vlc_playlist_t
*playlist
, size_t index
, size_t count
,
217 * Called when an item has been updated via (pre-)parsing.
219 * \param playlist the playlist
220 * \param index the index of the first updated item
221 * \param items the array of updated items
222 * \param count the number of items updated
223 * \param userdata userdata provided to AddListener()
226 (*on_items_updated
)(vlc_playlist_t
*playlist
, size_t index
,
227 vlc_playlist_item_t
*const items
[], size_t count
,
231 * Called when the playback repeat mode has been changed.
233 * \param playlist the playlist
234 * \param repeat the new playback "repeat" mode
235 * \param userdata userdata provided to AddListener()
238 (*on_playback_repeat_changed
)(vlc_playlist_t
*playlist
,
239 enum vlc_playlist_playback_repeat repeat
,
243 * Called when the playback order mode has been changed.
245 * \param playlist the playlist
246 * \param rorder the new playback order
247 * \param userdata userdata provided to AddListener()
250 (*on_playback_order_changed
)(vlc_playlist_t
*playlist
,
251 enum vlc_playlist_playback_order order
,
255 * Called when the current item index has changed.
257 * Note that the current item index may have changed while the current item
258 * is still the same: it may have been moved.
260 * \param playlist the playlist
261 * \param index the new current index (-1 if there is no current item)
262 * \param userdata userdata provided to AddListener()
265 (*on_current_index_changed
)(vlc_playlist_t
*playlist
, ssize_t index
,
269 * Called when the "has previous item" property has changed.
271 * This is typically useful to update any "previous" button in the UI.
273 * \param playlist the playlist
274 * \param has_prev true if there is a previous item, false otherwise
275 * \param userdata userdata provided to AddListener()
278 (*on_has_prev_changed
)(vlc_playlist_t
*playlist
, bool has_prev
,
282 * Called when the "has next item" property has changed.
284 * This is typically useful to update any "next" button in the UI.
286 * \param playlist the playlist
287 * \param has_next true if there is a next item, false otherwise
288 * \param userdata userdata provided to AddListener()
291 (*on_has_next_changed
)(vlc_playlist_t
*playlist
,
292 bool has_next
, void *userdata
);
298 * Hold a playlist item.
300 * Increment the refcount of the playlist item.
303 vlc_playlist_item_Hold(vlc_playlist_item_t
*);
306 * Release a playlist item.
308 * Decrement the refcount of the playlist item, and destroy it if necessary.
311 vlc_playlist_item_Release(vlc_playlist_item_t
*);
314 * Return the media associated to the playlist item.
316 VLC_API input_item_t
*
317 vlc_playlist_item_GetMedia(vlc_playlist_item_t
*);
320 * Return a unique id for the playlist item instance.
323 vlc_playlist_item_GetId(vlc_playlist_item_t
*);
328 * Create a new playlist.
330 * \param parent a VLC object
331 * \return a pointer to a valid playlist instance, or NULL if an error occurred
333 VLC_API VLC_USED vlc_playlist_t
*
334 vlc_playlist_New(vlc_object_t
*parent
);
339 * All playlist items are released, and listeners are removed and destroyed.
342 vlc_playlist_Delete(vlc_playlist_t
*);
345 * Lock the playlist/player.
347 * The playlist and its player share the same lock, to avoid lock-order
350 * \warning Do not forget that the playlist and player lock are the same (or
351 * you could lock twice the same and deadlock).
353 * Almost all playlist functions must be called with lock held (check their
356 * The lock is not recursive.
359 vlc_playlist_Lock(vlc_playlist_t
*);
362 * Unlock the playlist/player.
365 vlc_playlist_Unlock(vlc_playlist_t
*);
368 * Add a playlist listener.
370 * Return an opaque listener identifier, to be passed to
371 * vlc_player_RemoveListener().
373 * If notify_current_state is true, the callbacks are called once with the
374 * current state of the playlist. This is useful because when a client
375 * registers to the playlist, it may already contain items. Calling callbacks
376 * is a convenient way to initialize the client automatically.
378 * \param playlist the playlist, locked
379 * \param cbs the callbacks (must be valid until the listener
381 * \param userdata userdata provided as a parameter in callbacks
382 * \param notify_current_state true to notify the current state immediately via
384 * \return a listener identifier, or NULL if an error occurred
386 VLC_API VLC_USED vlc_playlist_listener_id
*
387 vlc_playlist_AddListener(vlc_playlist_t
*playlist
,
388 const struct vlc_playlist_callbacks
*cbs
,
389 void *userdata
, bool notify_current_state
);
392 * Remove a player listener.
394 * \param playlist the playlist, locked
395 * \param id the listener identifier returned by
396 * vlc_playlist_AddListener()
399 vlc_playlist_RemoveListener(vlc_playlist_t
*, vlc_playlist_listener_id
*);
402 * Return the number of items.
404 * \param playlist the playlist, locked
407 vlc_playlist_Count(vlc_playlist_t
*playlist
);
410 * Return the item at a given index.
412 * The index must be in range (less than vlc_playlist_Count()).
414 * \param playlist the playlist, locked
415 * \param index the index
416 * \return the playlist item
418 VLC_API vlc_playlist_item_t
*
419 vlc_playlist_Get(vlc_playlist_t
*playlist
, size_t index
);
422 * Clear the playlist.
424 * \param playlist the playlist, locked
427 vlc_playlist_Clear(vlc_playlist_t
*playlist
);
430 * Insert a list of media at a given index.
432 * The index must be in range (less than or equal to vlc_playlist_Count()).
434 * \param playlist the playlist, locked
435 * \index index the index where the media are to be inserted
436 * \param media the array of media to insert
437 * \param count the number of media to insert
438 * \return VLC_SUCCESS on success, another value on error
441 vlc_playlist_Insert(vlc_playlist_t
*playlist
, size_t index
,
442 input_item_t
*const media
[], size_t count
);
445 * Insert a media at a given index.
447 * The index must be in range (less than or equal to vlc_playlist_Count()).
449 * \param playlist the playlist, locked
450 * \index index the index where the media is to be inserted
451 * \param media the media to insert
452 * \return VLC_SUCCESS on success, another value on error
455 vlc_playlist_InsertOne(vlc_playlist_t
*playlist
, size_t index
,
458 return vlc_playlist_Insert(playlist
, index
, &media
, 1);
462 * Add a list of media at the end of the playlist.
464 * \param playlist the playlist, locked
465 * \param media the array of media to append
466 * \param count the number of media to append
467 * \return VLC_SUCCESS on success, another value on error
470 vlc_playlist_Append(vlc_playlist_t
*playlist
, input_item_t
*const media
[],
473 size_t size
= vlc_playlist_Count(playlist
);
474 return vlc_playlist_Insert(playlist
, size
, media
, count
);
478 * Add a media at the end of the playlist.
480 * \param playlist the playlist, locked
481 * \param media the media to append
482 * \return VLC_SUCCESS on success, another value on error
485 vlc_playlist_AppendOne(vlc_playlist_t
*playlist
, input_item_t
*media
)
487 return vlc_playlist_Append(playlist
, &media
, 1);
491 * Move a slice of items to a given target index.
493 * The slice and the target must be in range (both index+count and target+count
494 * less than or equal to vlc_playlist_Count()).
496 * \param playlist the playlist, locked
497 * \param index the index of the first item to move
498 * \param count the number of items to move
499 * \param target the new index of the moved slice
502 vlc_playlist_Move(vlc_playlist_t
*playlist
, size_t index
, size_t count
,
506 * Move an item to a given target index.
508 * The index and the target must be in range (index less than, and target less
509 * than or equal to, vlc_playlist_Count()).
511 * \param playlist the playlist, locked
512 * \param index the index of the item to move
513 * \param target the new index of the moved item
516 vlc_playlist_MoveOne(vlc_playlist_t
*playlist
, size_t index
, size_t target
)
518 vlc_playlist_Move(playlist
, index
, 1, target
);
522 * Remove a slice of items at a given index.
524 * The slice must be in range (index+count less than or equal to
525 * vlc_playlist_Count()).
527 * \param playlist the playlist, locked
528 * \param index the index of the first item to remove
529 * \param count the number of items to remove
532 vlc_playlist_Remove(vlc_playlist_t
*playlist
, size_t index
, size_t count
);
535 * Remove an item at a given index.
537 * The index must be in range (less than vlc_playlist_Count()).
539 * \param playlist the playlist, locked
540 * \param index the index of the item to remove
543 vlc_playlist_RemoveOne(vlc_playlist_t
*playlist
, size_t index
)
545 vlc_playlist_Remove(playlist
, index
, 1);
549 * Insert a list of media at a given index (if in range), or append.
551 * Contrary to vlc_playlist_Insert(), the index need not be in range: if it is
552 * out of bounds, items will be appended.
554 * This is an helper to apply a desynchronized insert request, i.e. the
555 * playlist content may have changed since the request had been submitted.
556 * This is typically the case for user requests (e.g. from UI), because the
557 * playlist lock has to be acquired *after* the user requested the
560 * \param playlist the playlist, locked
561 * \index index the index where the media are to be inserted
562 * \param media the array of media to insert
563 * \param count the number of media to insert
564 * \return VLC_SUCCESS on success, another value on error
567 vlc_playlist_RequestInsert(vlc_playlist_t
*playlist
, size_t index
,
568 input_item_t
*const media
[], size_t count
);
571 * Move a slice of items by value.
573 * If the indices are known, use vlc_playlist_Move() instead.
575 * This is an helper to apply a desynchronized move request, i.e. the playlist
576 * content may have changed since the request had been submitted. This is
577 * typically the case for user requests (e.g. from UI), because the playlist
578 * lock has to be acquired *after* the user requested the change.
580 * For optimization purpose, it is possible to pass an `index_hint`, which is
581 * the expected index of the first item of the slice (as known by the client).
582 * Hopefully, the index should often match, since conflicts are expected to be
583 * rare. Pass -1 not to pass any hint.
585 * \param playlist the playlist, locked
586 * \param items the array of items to move
587 * \param count the number of items to move
588 * \param target the new index of the moved slice
589 * \param index_hint the expected index of the first item (-1 for none)
590 * \return VLC_SUCCESS on success, another value on error
593 vlc_playlist_RequestMove(vlc_playlist_t
*playlist
,
594 vlc_playlist_item_t
*const items
[], size_t count
,
595 size_t target
, ssize_t index_hint
);
598 * Remove a slice of items by value.
600 * If the indices are known, use vlc_playlist_Remove() instead.
602 * This is an helper to apply a desynchronized remove request, i.e. the
603 * playlist content may have changed since the request had been submitted.
604 * This is typically the case for user requests (e.g. from UI), because the
605 * playlist lock has to be acquired *after* the user requested the change.
607 * For optimization purpose, it is possible to pass an `index_hint`, which is
608 * the expected index of the first item of the slice (as known by the client).
609 * Hopefully, the index should often match, since conflicts are expected to be
610 * rare. Pass -1 not to pass any hint.
612 * \param playlist the playlist, locked
613 * \param items the array of items to remove
614 * \param count the number of items to remove
615 * \param index_hint the expected index of the first item (-1 for none)
616 * \return VLC_SUCCESS on success, another value on error
619 vlc_playlist_RequestRemove(vlc_playlist_t
*playlist
,
620 vlc_playlist_item_t
*const items
[], size_t count
,
624 * Shuffle the playlist.
626 * \param playlist the playlist, locked
629 vlc_playlist_Shuffle(vlc_playlist_t
*playlist
);
632 * Sort the playlist by a list of criteria.
634 * \param playlist the playlist, locked
635 * \param criteria the sort criteria (in order)
636 * \param count the number of criteria
637 * \return VLC_SUCCESS on success, another value on error
640 vlc_playlist_Sort(vlc_playlist_t
*playlist
,
641 const struct vlc_playlist_sort_criterion criteria
[],
645 * Return the index of a given item.
647 * \param playlist the playlist, locked
648 * \param item the item to locate
649 * \return the index of the item (-1 if not found)
652 vlc_playlist_IndexOf(vlc_playlist_t
*playlist
, const vlc_playlist_item_t
*item
);
655 * Return the index of a given media.
657 * \param playlist the playlist, locked
658 * \param media the media to locate
659 * \return the index of the playlist item containing the media (-1 if not found)
662 vlc_playlist_IndexOfMedia(vlc_playlist_t
*playlist
, const input_item_t
*media
);
665 * Return the index of a given item id.
667 * \param playlist the playlist, locked
668 * \param id the id to locate
669 * \return the index of the playlist item having the id (-1 if not found)
672 vlc_playlist_IndexOfId(vlc_playlist_t
*playlist
, uint64_t id
);
675 * Return the playback "repeat" mode.
677 * \param playlist the playlist, locked
678 * \return the playback "repeat" mode
680 VLC_API
enum vlc_playlist_playback_repeat
681 vlc_playlist_GetPlaybackRepeat(vlc_playlist_t
*playlist
);
684 * Return the playback order.
686 * \param playlist the playlist, locked
687 * \return the playback order
689 VLC_API
enum vlc_playlist_playback_order
690 vlc_playlist_GetPlaybackOrder(vlc_playlist_t
*);
693 * Change the playback "repeat" mode.
695 * \param playlist the playlist, locked
696 * \param repeat the new playback "repeat" mode
699 vlc_playlist_SetPlaybackRepeat(vlc_playlist_t
*playlist
,
700 enum vlc_playlist_playback_repeat repeat
);
703 * Change the playback order
705 * \param playlist the playlist, locked
706 * \param repeat the new playback order
709 vlc_playlist_SetPlaybackOrder(vlc_playlist_t
*playlist
,
710 enum vlc_playlist_playback_order order
);
713 * Return the index of the current item.
715 * \param playlist the playlist, locked
716 * \return the index of the current item, -1 if none.
719 vlc_playlist_GetCurrentIndex(vlc_playlist_t
*playlist
);
722 * Indicate whether a previous item is available.
724 * \param playlist the playlist, locked
725 * \retval true if a previous item is available
726 * \retval false if no previous item is available
729 vlc_playlist_HasPrev(vlc_playlist_t
*playlist
);
732 * Indicate whether a next item is available.
734 * \param playlist the playlist, locked
735 * \retval true if a next item is available
736 * \retval false if no next item is available
739 vlc_playlist_HasNext(vlc_playlist_t
*playlist
);
742 * Go to the previous item.
744 * Return VLC_EGENERIC if vlc_playlist_HasPrev() returns false.
746 * \param playlist the playlist, locked
747 * \return VLC_SUCCESS on success, another value on error
750 vlc_playlist_Prev(vlc_playlist_t
*playlist
);
753 * Go to the next item.
755 * Return VLC_EGENERIC if vlc_playlist_HasNext() returns false.
757 * \param playlist the playlist, locked
758 * \return VLC_SUCCESS on success, another value on error
761 vlc_playlist_Next(vlc_playlist_t
*playlist
);
764 * Go to a given index.
766 * the index must be -1 or in range (less than vlc_playlist_Count()).
768 * \param playlist the playlist, locked
769 * \param index the index to go to (-1 to none)
770 * \return VLC_SUCCESS on success, another value on error
773 vlc_playlist_GoTo(vlc_playlist_t
*playlist
, ssize_t index
);
776 * Go to a given item.
778 * If the index is known, use vlc_playlist_GoTo() instead.
780 * This is an helper to apply a desynchronized "go to" request, i.e. the
781 * playlist content may have changed since the request had been submitted.
782 * This is typically the case for user requests (e.g. from UI), because the
783 * playlist lock has to be acquired *after* the user requested the change.
785 * For optimization purpose, it is possible to pass an `index_hint`, which is
786 * the expected index of the first item of the slice (as known by the client).
787 * Hopefully, the index should often match, since conflicts are expected to be
788 * rare. Pass -1 not to pass any hint.
790 * \param playlist the playlist, locked
791 * \param item the item to go to (NULL for none)
792 * \param index_hint the expected index of the item (-1 for none)
793 * \return VLC_SUCCESS on success, another value on error
796 vlc_playlist_RequestGoTo(vlc_playlist_t
*playlist
, vlc_playlist_item_t
*item
,
800 * Return the player owned by the playlist.
802 * \param playlist the playlist (not necessarily locked)
805 VLC_API vlc_player_t
*
806 vlc_playlist_GetPlayer(vlc_playlist_t
*playlist
);
811 * \param playlist the playlist, locked
812 * \return VLC_SUCCESS on success, another value on error
815 vlc_playlist_Start(vlc_playlist_t
*playlist
);
820 * \param playlist the playlist, locked
821 * \return VLC_SUCCESS on success, another value on error
824 vlc_playlist_Stop(vlc_playlist_t
*playlist
);
829 * \param playlist the playlist, locked
830 * \return VLC_SUCCESS on success, another value on error
833 vlc_playlist_Pause(vlc_playlist_t
*playlist
);
838 * \param playlist the playlist, locked
839 * \return VLC_SUCCESS on success, another value on error
842 vlc_playlist_Resume(vlc_playlist_t
*playlist
);
845 * Go to the given index and plays the corresponding item.
847 * \param playlist the playlist, locked
848 * \param index the index to play at
849 * \return VLC_SUCCESS on success, another value on error
852 vlc_playlist_PlayAt(vlc_playlist_t
*playlist
, size_t index
)
854 int ret
= vlc_playlist_GoTo(playlist
, index
);
855 if (ret
!= VLC_SUCCESS
)
857 return vlc_playlist_Start(playlist
);
861 * Preparse a media, and expand it in the playlist on subitems added.
863 * \param playlist the playlist (not necessarily locked)
864 * \param libvlc the libvlc instance
865 * \param media the media to preparse
868 vlc_playlist_Preparse(vlc_playlist_t
*playlist
, input_item_t
*media
);
871 * Export the playlist to a file.
873 * \param filename the location where the exported file will be saved
874 * \param type the type of the playlist file to create (m3u, m3u8, xspf, ...)
875 * \return VLC_SUCCESS on success, another value on error
877 // XXX use vlc_memstream instead of filename?
879 vlc_playlist_Export(vlc_playlist_t
*playlist
, const char *filename
,