playlist: update the randomizer on media change
[vlc.git] / src / playlist / player.c
blob6ca6ea0636a448c7f186ba9a6aa6127cf722b5ad
1 /*****************************************************************************
2 * playlist/player.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 "player.h"
27 #include "input/player.h"
28 #include "control.h"
29 #include "item.h"
30 #include "notify.h"
31 #include "playlist.h"
32 #include "preparse.h"
34 static void
35 player_on_current_media_changed(vlc_player_t *player, input_item_t *new_media,
36 void *userdata)
38 VLC_UNUSED(player);
39 vlc_playlist_t *playlist = userdata;
41 /* the playlist and the player share the lock */
42 vlc_playlist_AssertLocked(playlist);
44 input_item_t *media = playlist->current != -1
45 ? playlist->items.data[playlist->current]->media
46 : NULL;
47 if (new_media == media)
48 /* nothing to do */
49 return;
51 ssize_t index;
52 if (new_media)
54 index = vlc_playlist_IndexOfMedia(playlist, new_media);
55 if (index != -1)
57 vlc_playlist_item_t *item = playlist->items.data[index];
58 if (playlist->order == VLC_PLAYLIST_PLAYBACK_ORDER_RANDOM)
59 randomizer_Select(&playlist->randomizer, item);
62 else
63 index = -1;
65 struct vlc_playlist_state state;
66 vlc_playlist_state_Save(playlist, &state);
68 playlist->current = index;
69 playlist->has_prev = vlc_playlist_ComputeHasPrev(playlist);
70 playlist->has_next = vlc_playlist_ComputeHasNext(playlist);
72 vlc_playlist_state_NotifyChanges(playlist, &state);
75 static void
76 on_player_media_meta_changed(vlc_player_t *player, input_item_t *media,
77 void *userdata)
79 VLC_UNUSED(player);
80 vlc_playlist_t *playlist = userdata;
82 /* the playlist and the player share the lock */
83 vlc_playlist_AssertLocked(playlist);
85 vlc_playlist_NotifyMediaUpdated(playlist, media);
88 static void
89 on_player_media_length_changed(vlc_player_t *player, vlc_tick_t new_length,
90 void *userdata)
92 VLC_UNUSED(player);
93 VLC_UNUSED(new_length);
94 vlc_playlist_t *playlist = userdata;
96 /* the playlist and the player share the lock */
97 vlc_playlist_AssertLocked(playlist);
99 input_item_t *media = vlc_player_GetCurrentMedia(player);
100 assert(media);
102 vlc_playlist_NotifyMediaUpdated(playlist, media);
105 static void
106 on_player_media_subitems_changed(vlc_player_t *player, input_item_t *media,
107 input_item_node_t *subitems, void *userdata)
109 VLC_UNUSED(player);
110 VLC_UNUSED(media);
111 vlc_playlist_t *playlist = userdata;
112 vlc_playlist_ExpandItemFromNode(playlist, subitems);
115 static input_item_t *
116 player_get_next_media(vlc_player_t *player, void *userdata)
118 VLC_UNUSED(player);
119 vlc_playlist_t *playlist = userdata;
120 return vlc_playlist_GetNextMedia(playlist);
123 static const struct vlc_player_media_provider player_media_provider = {
124 .get_next = player_get_next_media,
127 static const struct vlc_player_cbs player_callbacks = {
128 .on_current_media_changed = player_on_current_media_changed,
129 .on_media_meta_changed = on_player_media_meta_changed,
130 .on_length_changed = on_player_media_length_changed,
131 .on_media_subitems_changed = on_player_media_subitems_changed,
134 bool
135 vlc_playlist_PlayerInit(vlc_playlist_t *playlist, vlc_object_t *parent)
137 playlist->player = vlc_player_New(parent, &player_media_provider, playlist);
138 if (unlikely(!playlist->player))
139 return false;
141 vlc_player_Lock(playlist->player);
142 /* the playlist and the player share the lock */
143 vlc_playlist_AssertLocked(playlist);
144 playlist->player_listener = vlc_player_AddListener(playlist->player,
145 &player_callbacks,
146 playlist);
147 vlc_player_Unlock(playlist->player);
148 if (unlikely(!playlist->player_listener))
150 vlc_player_Delete(playlist->player);
151 return false;
153 return true;
156 void
157 vlc_playlist_PlayerDestroy(vlc_playlist_t *playlist)
159 vlc_player_Lock(playlist->player);
160 vlc_player_RemoveListener(playlist->player, playlist->player_listener);
161 vlc_player_Unlock(playlist->player);
163 vlc_player_Delete(playlist->player);
166 vlc_player_t *
167 vlc_playlist_GetPlayer(vlc_playlist_t *playlist)
169 return playlist->player;
173 vlc_playlist_Start(vlc_playlist_t *playlist)
175 return vlc_player_Start(playlist->player);
178 void
179 vlc_playlist_Stop(vlc_playlist_t *playlist)
181 vlc_player_Stop(playlist->player);
184 void
185 vlc_playlist_Pause(vlc_playlist_t *playlist)
187 vlc_player_Pause(playlist->player);
190 void
191 vlc_playlist_Resume(vlc_playlist_t *playlist)
193 vlc_player_Resume(playlist->player);