vlc_common: move decoder_synchro_t to synchro.h
[vlc.git] / src / playlist / preparse.c
blob11f6faff415bcd7c5b34bac3f510e4b830b66ae8
1 /*****************************************************************************
2 * playlist/preparse.c
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 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
25 #include "preparse.h"
27 #include "content.h"
28 #include "item.h"
29 #include "playlist.h"
30 #include "notify.h"
31 #include "libvlc.h" /* for vlc_MetadataRequest() */
33 typedef struct VLC_VECTOR(input_item_t *) media_vector_t;
35 static void
36 vlc_playlist_CollectChildren(vlc_playlist_t *playlist,
37 media_vector_t *dest,
38 input_item_node_t *node)
40 vlc_playlist_AssertLocked(playlist);
41 for (int i = 0; i < node->i_children; ++i)
43 input_item_node_t *child = node->pp_children[i];
44 input_item_t *media = child->p_item;
45 vlc_vector_push(dest, media);
46 vlc_playlist_CollectChildren(playlist, dest, child);
50 int
51 vlc_playlist_ExpandItem(vlc_playlist_t *playlist, size_t index,
52 input_item_node_t *node)
54 vlc_playlist_AssertLocked(playlist);
56 media_vector_t flatten = VLC_VECTOR_INITIALIZER;
57 vlc_playlist_CollectChildren(playlist, &flatten, node);
59 int ret = vlc_playlist_Expand(playlist, index, flatten.data, flatten.size);
60 vlc_vector_destroy(&flatten);
62 return ret;
65 int
66 vlc_playlist_ExpandItemFromNode(vlc_playlist_t *playlist,
67 input_item_node_t *subitems)
69 vlc_playlist_AssertLocked(playlist);
70 input_item_t *media = subitems->p_item;
71 ssize_t index = vlc_playlist_IndexOfMedia(playlist, media);
72 if (index == -1)
73 return VLC_ENOITEM;
75 /* replace the item by its flatten subtree */
76 return vlc_playlist_ExpandItem(playlist, index, subitems);
79 static void
80 on_subtree_added(input_item_t *media, input_item_node_t *subtree,
81 void *userdata)
83 VLC_UNUSED(media); /* retrieved by subtree->p_item */
84 vlc_playlist_t *playlist = userdata;
86 vlc_playlist_Lock(playlist);
87 vlc_playlist_ExpandItemFromNode(playlist, subtree);
88 vlc_playlist_Unlock(playlist);
91 static void
92 on_preparse_ended(input_item_t *media,
93 enum input_item_preparse_status status, void *userdata)
95 VLC_UNUSED(media); /* retrieved by subtree->p_item */
96 vlc_playlist_t *playlist = userdata;
98 if (status != ITEM_PREPARSE_DONE)
99 return;
101 vlc_playlist_Lock(playlist);
102 ssize_t index = vlc_playlist_IndexOfMedia(playlist, media);
103 if (index != -1)
104 vlc_playlist_Notify(playlist, on_items_updated, index,
105 &playlist->items.data[index], 1);
106 vlc_playlist_Unlock(playlist);
109 static const input_preparser_callbacks_t input_preparser_callbacks = {
110 .on_preparse_ended = on_preparse_ended,
111 .on_subtree_added = on_subtree_added,
114 void
115 vlc_playlist_Preparse(vlc_playlist_t *playlist, input_item_t *input)
117 #ifdef TEST_PLAYLIST
118 VLC_UNUSED(playlist);
119 VLC_UNUSED(input);
120 VLC_UNUSED(input_preparser_callbacks);
121 #else
122 /* vlc_MetadataRequest is not exported */
123 vlc_MetadataRequest(playlist->libvlc, input,
124 META_REQUEST_OPTION_SCOPE_LOCAL |
125 META_REQUEST_OPTION_FETCH_LOCAL,
126 &input_preparser_callbacks, playlist, -1, NULL);
127 #endif
130 void
131 vlc_playlist_AutoPreparse(vlc_playlist_t *playlist, input_item_t *input)
133 if (playlist->auto_preparse && !input_item_IsPreparsed(input))
134 vlc_playlist_Preparse(playlist, input);