X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fcontrol%2Fmedia_list_player.c;h=a6d509869119c9eb33c94a04ca67d8ece623fa5d;hb=180fef5efbb7d0fed04bd79f5a72746ef4b37712;hp=5402400bc3d70d143050f2acb9a7c6c6abea3af7;hpb=efb6269f3e48faa2b2fb743d30533eb9fc6440cd;p=vlc diff --git a/src/control/media_list_player.c b/src/control/media_list_player.c index 5402400bc3..a6d5098691 100644 --- a/src/control/media_list_player.c +++ b/src/control/media_list_player.c @@ -21,6 +21,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include #include #include @@ -76,11 +80,10 @@ static inline void vlc_assert_locked(vlc_mutex_t *mutex) * Forward declaration */ -static void set_relative_playlist_position_and_play( - libvlc_media_list_player_t * p_mlp, - int i_relative_position, - libvlc_exception_t * p_e); -static void stop(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e); +static +int set_relative_playlist_position_and_play(libvlc_media_list_player_t *p_mlp, + int i_relative_position); +static void stop(libvlc_media_list_player_t * p_mlp); /* * Private functions @@ -93,7 +96,7 @@ static inline void lock(libvlc_media_list_player_t * p_mlp) { // Obtain an access to this structure vlc_mutex_lock(&p_mlp->object_lock); - + // Make sure no callback will occurs at the same time vlc_mutex_lock(&p_mlp->mp_callback_lock); } @@ -112,19 +115,19 @@ static inline void assert_locked(libvlc_media_list_player_t * p_mlp) static inline libvlc_event_manager_t * mlist_em(libvlc_media_list_player_t * p_mlp) { assert_locked(p_mlp); - return libvlc_media_list_event_manager(p_mlp->p_mlist, NULL); + return libvlc_media_list_event_manager(p_mlp->p_mlist); } static inline libvlc_event_manager_t * mplayer_em(libvlc_media_list_player_t * p_mlp) { assert_locked(p_mlp); - return libvlc_media_player_event_manager(p_mlp->p_mi, NULL); + return libvlc_media_player_event_manager(p_mlp->p_mi); } /************************************************************************** * get_next_path (private) * - * Returns the path to the next item in the list. + * Returns the path to the next item in the list. * If looping is specified and the current item is the last list item in * the list it will return the first item in the list. **************************************************************************/ @@ -140,15 +143,15 @@ get_next_path(libvlc_media_list_player_t * p_mlp, bool b_loop) if (!p_mlp->current_playing_item_path) { - if (!libvlc_media_list_count(p_mlp->p_mlist, NULL)) + if (!libvlc_media_list_count(p_mlp->p_mlist)) return NULL; return libvlc_media_list_path_with_root_index(0); } - + p_sublist_of_playing_item = libvlc_media_list_sublist_at_path( p_mlp->p_mlist, p_mlp->current_playing_item_path); - + /* If item just gained a sublist just play it */ if (p_sublist_of_playing_item) { @@ -168,7 +171,7 @@ get_next_path(libvlc_media_list_player_t * p_mlp, bool b_loop) ret[depth - 1]++; /* set to next element */ /* If this goes beyond the end of the list */ - while(ret[depth-1] >= libvlc_media_list_count(p_parent_of_playing_item, NULL)) + while(ret[depth-1] >= libvlc_media_list_count(p_parent_of_playing_item)) { depth--; if (depth <= 0) @@ -203,7 +206,7 @@ get_next_path(libvlc_media_list_player_t * p_mlp, bool b_loop) * Returns the path of the last descendant of a given item path. * Note: Due to the recursive nature of the function and the need to free * media list paths, paths passed in may be freed if they are replaced. - Recommended usage is to set return value to the same path that was + Recommended usage is to set return value to the same path that was passed to the function (i.e. item = find_last_item(list, item); ) **************************************************************************/ static libvlc_media_list_path_t @@ -214,7 +217,7 @@ find_last_item( libvlc_media_list_t * p_mlist, libvlc_media_list_path_t current_ if(p_sublist) { - int i_count = libvlc_media_list_count(p_sublist, NULL); + int i_count = libvlc_media_list_count(p_sublist); if(i_count > 0) { /* Add the last sublist item to the path. */ @@ -225,7 +228,7 @@ find_last_item( libvlc_media_list_t * p_mlist, libvlc_media_list_path_t current_ } libvlc_media_list_release(p_sublist); - } + } return last_item_path; } @@ -233,7 +236,7 @@ find_last_item( libvlc_media_list_t * p_mlist, libvlc_media_list_path_t current_ /************************************************************************** * get_previous_path (private) * - * Returns the path to the preceding item in the list. + * Returns the path to the preceding item in the list. * If looping is specified and the current item is the first list item in * the list it will return the last descendant of the last item in the list. **************************************************************************/ @@ -248,11 +251,11 @@ get_previous_path(libvlc_media_list_player_t * p_mlp, bool b_loop) if (!p_mlp->current_playing_item_path) { - if (!libvlc_media_list_count(p_mlp->p_mlist, NULL)) + if (!libvlc_media_list_count(p_mlp->p_mlist)) return NULL; return libvlc_media_list_path_with_root_index(0); } - + /* Try to catch parent element */ p_parent_of_playing_item = libvlc_media_list_parentlist_at_path( p_mlp->p_mlist, @@ -281,7 +284,7 @@ get_previous_path(libvlc_media_list_player_t * p_mlp, bool b_loop) // Is looping enabled? if(b_loop) { - int i_count = libvlc_media_list_count(p_parent_of_playing_item, NULL); + int i_count = libvlc_media_list_count(p_parent_of_playing_item); /* Set current play item to the last element in the list */ ret[0] = i_count - 1; @@ -324,16 +327,11 @@ media_player_reached_end(const libvlc_event_t * p_event, void * p_user_data) { VLC_UNUSED(p_event); libvlc_media_list_player_t * p_mlp = p_user_data; - libvlc_exception_t e; - libvlc_exception_init(&e); vlc_mutex_lock(&p_mlp->mp_callback_lock); if (!p_mlp->are_mp_callback_cancelled) - set_relative_playlist_position_and_play(p_mlp, 1, &e); + set_relative_playlist_position_and_play(p_mlp, 1); vlc_mutex_unlock(&p_mlp->mp_callback_lock); - - // There is no point in reporting an error from this callback - libvlc_exception_clear(&e); } /************************************************************************** @@ -342,21 +340,8 @@ media_player_reached_end(const libvlc_event_t * p_event, void * p_user_data) static void mlist_item_deleted(const libvlc_event_t * p_event, void * p_user_data) { - libvlc_media_list_player_t * p_mlp = p_user_data; - libvlc_media_list_t * p_emitting_mlist = p_event->p_obj; - libvlc_media_t * p_current_md = NULL; - - lock(p_mlp); - if (p_mlp->current_playing_item_path) - p_current_md = libvlc_media_list_item_at_path(p_mlp->p_mlist, p_mlp->current_playing_item_path); - - if (p_event->u.media_list_item_deleted.item == p_current_md && - p_emitting_mlist == p_mlp->p_mlist) - { - /* We are playing this item, let's stop */ - stop(p_mlp, NULL); - } - unlock(p_mlp); + // Nothing to do. For now. + (void)p_event; (void)p_user_data; } @@ -367,7 +352,7 @@ static void install_playlist_observer(libvlc_media_list_player_t * p_mlp) { assert_locked(p_mlp); - libvlc_event_attach(mlist_em(p_mlp), libvlc_MediaListItemDeleted, mlist_item_deleted, p_mlp, NULL); + libvlc_event_attach(mlist_em(p_mlp), libvlc_MediaListItemDeleted, mlist_item_deleted, p_mlp); } /************************************************************************** @@ -378,7 +363,7 @@ uninstall_playlist_observer(libvlc_media_list_player_t * p_mlp) { assert_locked(p_mlp); if (!p_mlp->p_mlist) return; - libvlc_event_detach(mlist_em(p_mlp), libvlc_MediaListItemDeleted, mlist_item_deleted, p_mlp, NULL); + libvlc_event_detach(mlist_em(p_mlp), libvlc_MediaListItemDeleted, mlist_item_deleted, p_mlp); } /************************************************************************** @@ -388,7 +373,7 @@ static void install_media_player_observer(libvlc_media_list_player_t * p_mlp) { assert_locked(p_mlp); - libvlc_event_attach_async(mplayer_em(p_mlp), libvlc_MediaPlayerEndReached, media_player_reached_end, p_mlp, NULL); + libvlc_event_attach_async(mplayer_em(p_mlp), libvlc_MediaPlayerEndReached, media_player_reached_end, p_mlp); } @@ -407,7 +392,7 @@ uninstall_media_player_observer(libvlc_media_list_player_t * p_mlp) // Allow callbacks to run, because detach() will wait until all callbacks are processed. // This is safe because only callbacks are allowed, and there execution will be cancelled. vlc_mutex_unlock(&p_mlp->mp_callback_lock); - libvlc_event_detach(mplayer_em(p_mlp), libvlc_MediaPlayerEndReached, media_player_reached_end, p_mlp, NULL); + libvlc_event_detach(mplayer_em(p_mlp), libvlc_MediaPlayerEndReached, media_player_reached_end, p_mlp); // Now, lock back the callback lock. No more callback will be present from this point. vlc_mutex_lock(&p_mlp->mp_callback_lock); @@ -441,15 +426,15 @@ set_current_playing_item(libvlc_media_list_player_t * p_mlp, libvlc_media_list_p p_md = libvlc_media_list_item_at_path(p_mlp->p_mlist, path); if (!p_md) return; - + /* Make sure media_player_reached_end() won't get called */ uninstall_media_player_observer(p_mlp); /* Create a new media_player if there is none */ if (!p_mlp->p_mi) - p_mlp->p_mi = libvlc_media_player_new_from_media(p_md, NULL); + p_mlp->p_mi = libvlc_media_player_new_from_media(p_md); - libvlc_media_player_set_media(p_mlp->p_mi, p_md, NULL); + libvlc_media_player_set_media(p_mlp->p_mi, p_md); install_media_player_observer(p_mlp); libvlc_media_release(p_md); /* for libvlc_media_list_item_at_index */ @@ -463,21 +448,29 @@ set_current_playing_item(libvlc_media_list_player_t * p_mlp, libvlc_media_list_p * new (Public) **************************************************************************/ libvlc_media_list_player_t * -libvlc_media_list_player_new(libvlc_instance_t * p_instance, libvlc_exception_t * p_e) +libvlc_media_list_player_new(libvlc_instance_t * p_instance) { - (void)p_e; libvlc_media_list_player_t * p_mlp; p_mlp = calloc( 1, sizeof(libvlc_media_list_player_t) ); - if (!p_mlp) + if (unlikely(p_mlp == NULL)) + { + libvlc_printerr("Not enough memory"); return NULL; + } + + p_mlp->p_event_manager = libvlc_event_manager_new(p_mlp, p_instance); + if (unlikely(p_mlp->p_event_manager == NULL)) + { + free (p_mlp); + return NULL; + } libvlc_retain(p_instance); p_mlp->p_libvlc_instance = p_instance; p_mlp->i_refcount = 1; vlc_mutex_init(&p_mlp->object_lock); vlc_mutex_init(&p_mlp->mp_callback_lock); - p_mlp->p_event_manager = libvlc_event_manager_new(p_mlp, p_instance, p_e); - libvlc_event_manager_register_event_type(p_mlp->p_event_manager, libvlc_MediaListPlayerNextItemSet, p_e); + libvlc_event_manager_register_event_type(p_mlp->p_event_manager, libvlc_MediaListPlayerNextItemSet); p_mlp->e_playback_mode = libvlc_playback_mode_default; return p_mlp; @@ -508,7 +501,7 @@ void libvlc_media_list_player_release(libvlc_media_list_player_t * p_mlp) { uninstall_media_player_observer(p_mlp); libvlc_media_player_release(p_mlp->p_mi); - } + } if (p_mlp->p_mlist) { uninstall_playlist_observer(p_mlp); @@ -520,7 +513,7 @@ void libvlc_media_list_player_release(libvlc_media_list_player_t * p_mlp) vlc_mutex_destroy(&p_mlp->mp_callback_lock); libvlc_event_manager_release(p_mlp->p_event_manager); - + free(p_mlp->current_playing_item_path); libvlc_release(p_mlp->p_libvlc_instance); free(p_mlp); @@ -538,10 +531,8 @@ libvlc_media_list_player_event_manager(libvlc_media_list_player_t * p_mlp) /************************************************************************** * set_media_player (Public) **************************************************************************/ -void libvlc_media_list_player_set_media_player(libvlc_media_list_player_t * p_mlp, libvlc_media_player_t * p_mi, libvlc_exception_t * p_e) +void libvlc_media_list_player_set_media_player(libvlc_media_list_player_t * p_mlp, libvlc_media_player_t * p_mi) { - VLC_UNUSED(p_e); - lock(p_mlp); if (p_mlp->p_mi) @@ -560,16 +551,11 @@ void libvlc_media_list_player_set_media_player(libvlc_media_list_player_t * p_ml /************************************************************************** * set_media_list (Public) **************************************************************************/ -void libvlc_media_list_player_set_media_list(libvlc_media_list_player_t * p_mlp, libvlc_media_list_t * p_mlist, libvlc_exception_t * p_e) +void libvlc_media_list_player_set_media_list(libvlc_media_list_player_t * p_mlp, libvlc_media_list_t * p_mlist) { - lock(p_mlp); + assert (p_mlist); - if (!p_mlist) - { - libvlc_exception_raise(p_e, "No media list provided"); - unlock(p_mlp); - return; - } + lock(p_mlp); if (p_mlp->p_mlist) { uninstall_playlist_observer(p_mlp); @@ -577,7 +563,7 @@ void libvlc_media_list_player_set_media_list(libvlc_media_list_player_t * p_mlp, } libvlc_media_list_retain(p_mlist); p_mlp->p_mlist = p_mlist; - + install_playlist_observer(p_mlp); unlock(p_mlp); @@ -586,16 +572,16 @@ void libvlc_media_list_player_set_media_list(libvlc_media_list_player_t * p_mlp, /************************************************************************** * Play (Public) **************************************************************************/ -void libvlc_media_list_player_play(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e) +void libvlc_media_list_player_play(libvlc_media_list_player_t * p_mlp) { lock(p_mlp); if (!p_mlp->current_playing_item_path) { - set_relative_playlist_position_and_play(p_mlp, 1, p_e); + set_relative_playlist_position_and_play(p_mlp, 1); unlock(p_mlp); return; /* Will set to play */ } - libvlc_media_player_play(p_mlp->p_mi, p_e); + libvlc_media_player_play(p_mlp->p_mi); unlock(p_mlp); } @@ -603,7 +589,7 @@ void libvlc_media_list_player_play(libvlc_media_list_player_t * p_mlp, libvlc_ex /************************************************************************** * Pause (Public) **************************************************************************/ -void libvlc_media_list_player_pause(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e) +void libvlc_media_list_player_pause(libvlc_media_list_player_t * p_mlp) { lock(p_mlp); if (!p_mlp->p_mi) @@ -611,7 +597,7 @@ void libvlc_media_list_player_pause(libvlc_media_list_player_t * p_mlp, libvlc_e unlock(p_mlp); return; } - libvlc_media_player_pause(p_mlp->p_mi, p_e); + libvlc_media_player_pause(p_mlp->p_mi); unlock(p_mlp); } @@ -619,9 +605,13 @@ void libvlc_media_list_player_pause(libvlc_media_list_player_t * p_mlp, libvlc_e * is_playing (Public) **************************************************************************/ int -libvlc_media_list_player_is_playing(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e) +libvlc_media_list_player_is_playing(libvlc_media_list_player_t * p_mlp) { - libvlc_state_t state = libvlc_media_player_get_state(p_mlp->p_mi, p_e); + if (!p_mlp->p_mi) + { + return libvlc_NothingSpecial; + } + libvlc_state_t state = libvlc_media_player_get_state(p_mlp->p_mi); return (state == libvlc_Opening) || (state == libvlc_Buffering) || (state == libvlc_Playing); } @@ -630,48 +620,48 @@ libvlc_media_list_player_is_playing(libvlc_media_list_player_t * p_mlp, libvlc_e * State (Public) **************************************************************************/ libvlc_state_t -libvlc_media_list_player_get_state(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e) +libvlc_media_list_player_get_state(libvlc_media_list_player_t * p_mlp) { if (!p_mlp->p_mi) return libvlc_Ended; - return libvlc_media_player_get_state(p_mlp->p_mi, p_e); + return libvlc_media_player_get_state(p_mlp->p_mi); } /************************************************************************** * Play item at index (Public) **************************************************************************/ -void libvlc_media_list_player_play_item_at_index(libvlc_media_list_player_t * p_mlp, int i_index, libvlc_exception_t * p_e) +int libvlc_media_list_player_play_item_at_index(libvlc_media_list_player_t * p_mlp, int i_index) { - VLC_UNUSED(p_e); - lock(p_mlp); set_current_playing_item(p_mlp, libvlc_media_list_path_with_root_index(i_index)); - libvlc_media_player_play(p_mlp->p_mi, p_e); + libvlc_media_player_play(p_mlp->p_mi); unlock(p_mlp); /* Send the next item event */ libvlc_event_t event; event.type = libvlc_MediaListPlayerNextItemSet; libvlc_event_send(p_mlp->p_event_manager, &event); + return 0; } /************************************************************************** * Play item (Public) **************************************************************************/ -void libvlc_media_list_player_play_item(libvlc_media_list_player_t * p_mlp, libvlc_media_t * p_md, libvlc_exception_t * p_e) +int libvlc_media_list_player_play_item(libvlc_media_list_player_t * p_mlp, libvlc_media_t * p_md) { lock(p_mlp); libvlc_media_list_path_t path = libvlc_media_list_path_of_item(p_mlp->p_mlist, p_md); if (!path) { - libvlc_exception_raise(p_e, "No such item in media list"); + libvlc_printerr("Item not found in media list"); unlock(p_mlp); - return; + return -1; } - + set_current_playing_item(p_mlp, path); - libvlc_media_player_play(p_mlp->p_mi, p_e); + libvlc_media_player_play(p_mlp->p_mi); unlock(p_mlp); + return 0; } /************************************************************************** @@ -679,15 +669,15 @@ void libvlc_media_list_player_play_item(libvlc_media_list_player_t * p_mlp, libv * * Lock must be held. **************************************************************************/ -static void stop(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e) +static void stop(libvlc_media_list_player_t * p_mlp) { assert_locked(p_mlp); - if (p_mlp->p_mi && p_mlp->current_playing_item_path) + if (p_mlp->p_mi) { /* We are not interested in getting media stop event now */ uninstall_media_player_observer(p_mlp); - libvlc_media_player_stop(p_mlp->p_mi, p_e); + libvlc_media_player_stop(p_mlp->p_mi); install_media_player_observer(p_mlp); } @@ -698,32 +688,30 @@ static void stop(libvlc_media_list_player_t * p_mlp, libvlc_exception_t * p_e) /************************************************************************** * Stop (Public) **************************************************************************/ -void libvlc_media_list_player_stop(libvlc_media_list_player_t * p_mlp, - libvlc_exception_t * p_e) +void libvlc_media_list_player_stop(libvlc_media_list_player_t * p_mlp) { lock(p_mlp); - stop(p_mlp, p_e); + stop(p_mlp); unlock(p_mlp); } /************************************************************************** * Set relative playlist position and play (Private) * - * Sets the currently played item to the given relative play item position + * Sets the currently played item to the given relative play item position * (based on the currently playing item) and then begins the new item playback. - * Lock must be held. + * Lock must be held. **************************************************************************/ -static void set_relative_playlist_position_and_play( - libvlc_media_list_player_t * p_mlp, - int i_relative_position, - libvlc_exception_t * p_e) +static int set_relative_playlist_position_and_play( + libvlc_media_list_player_t * p_mlp, + int i_relative_position) { assert_locked(p_mlp); if (!p_mlp->p_mlist) { - libvlc_exception_raise(p_e, "No media list"); - return; + libvlc_printerr("No media list"); + return -1; } libvlc_media_list_lock(p_mlp->p_mlist); @@ -733,7 +721,7 @@ static void set_relative_playlist_position_and_play( if(p_mlp->e_playback_mode != libvlc_playback_mode_repeat) { bool b_loop = (p_mlp->e_playback_mode == libvlc_playback_mode_loop); - + if(i_relative_position > 0) { do @@ -746,12 +734,12 @@ static void set_relative_playlist_position_and_play( } else if(i_relative_position < 0) { - do + do { path = get_previous_path(p_mlp, b_loop); set_current_playing_item(p_mlp, path); ++i_relative_position; - } + } while (i_relative_position < 0); } } @@ -768,11 +756,10 @@ static void set_relative_playlist_position_and_play( if (!path) { libvlc_media_list_unlock(p_mlp->p_mlist); - stop(p_mlp, p_e); - return; + return -1; } - libvlc_media_player_play(p_mlp->p_mi, p_e); + libvlc_media_player_play(p_mlp->p_mi); libvlc_media_list_unlock(p_mlp->p_mlist); @@ -783,40 +770,38 @@ static void set_relative_playlist_position_and_play( event.u.media_list_player_next_item_set.item = p_md; libvlc_event_send(p_mlp->p_event_manager, &event); libvlc_media_release(p_md); + return 0; } /************************************************************************** * Next (Public) **************************************************************************/ -void libvlc_media_list_player_next(libvlc_media_list_player_t * p_mlp, - libvlc_exception_t * p_e) +int libvlc_media_list_player_next(libvlc_media_list_player_t * p_mlp) { lock(p_mlp); - set_relative_playlist_position_and_play(p_mlp, 1, p_e); + int failure = set_relative_playlist_position_and_play(p_mlp, 1); unlock(p_mlp); + return failure; } /************************************************************************** * Previous (Public) **************************************************************************/ -void libvlc_media_list_player_previous(libvlc_media_list_player_t * p_mlp, - libvlc_exception_t * p_e) +int libvlc_media_list_player_previous(libvlc_media_list_player_t * p_mlp) { lock(p_mlp); - set_relative_playlist_position_and_play(p_mlp, -1, p_e); + int failure = set_relative_playlist_position_and_play(p_mlp, -1); unlock(p_mlp); + return failure; } /************************************************************************** * Set Playback Mode (Public) **************************************************************************/ -void libvlc_media_list_player_set_playback_mode( +void libvlc_media_list_player_set_playback_mode( libvlc_media_list_player_t * p_mlp, - libvlc_playback_mode_t e_mode, - libvlc_exception_t * p_e ) + libvlc_playback_mode_t e_mode ) { - VLC_UNUSED(p_e); - lock(p_mlp); p_mlp->e_playback_mode = e_mode; unlock(p_mlp);