X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fplaylist%2Fengine.c;h=63c22f1cf94ea2f5cfbe5c0d782ddcd0a3b991be;hb=037a796b8ddfe6d52299d40301ab695f9c01228a;hp=61b610bc0a8bb67d5e6b67e80edac620d00ea8b1;hpb=7376fd3b29c4a2ae146b024f2b62148a2b21fa23;p=vlc diff --git a/src/playlist/engine.c b/src/playlist/engine.c index 61b610bc0a..63c22f1cf9 100644 --- a/src/playlist/engine.c +++ b/src/playlist/engine.c @@ -1,24 +1,24 @@ /***************************************************************************** * engine.c : Run the playlist and handle its control ***************************************************************************** - * Copyright (C) 1999-2008 the VideoLAN team + * Copyright (C) 1999-2008 VLC authors and VideoLAN * * Authors: Samuel Hocevar * Clément Stenac * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #ifdef HAVE_CONFIG_H @@ -45,16 +45,61 @@ static int RandomCallback( vlc_object_t *p_this, char const *psz_cmd, { (void)psz_cmd; (void)oldval; (void)newval; (void)a; playlist_t *p_playlist = (playlist_t*)p_this; + bool random = newval.b_bool; PL_LOCK; - pl_priv(p_playlist)->b_reset_currently_playing = true; - vlc_cond_signal( &pl_priv(p_playlist)->signal ); + if( !random ) { + pl_priv(p_playlist)->b_reset_currently_playing = true; + vlc_cond_signal( &pl_priv(p_playlist)->signal ); + } else { + /* Shuffle and sync the playlist on activation of random mode. + * This preserves the current playing item, so that the user + * can return to it if needed. (See #4472) + */ + playlist_private_t *p_sys = pl_priv(p_playlist); + playlist_item_t *p_new = p_sys->status.p_item; + ResetCurrentlyPlaying( p_playlist, NULL ); + if( p_new ) + ResyncCurrentIndex( p_playlist, p_new ); + } PL_UNLOCK; return VLC_SUCCESS; } +/** + * When there are one or more pending corks, playback should be paused. + * This is used for audio policy. + * \warning Always add and remove a cork with var_IncInteger() and var_DecInteger(). + * var_Get() and var_Set() are prone to race conditions. + */ +static int CorksCallback( vlc_object_t *obj, char const *var, + vlc_value_t old, vlc_value_t cur, void *dummy ) +{ + playlist_t *pl = (playlist_t *)obj; + + msg_Dbg( obj, "corks count: %"PRId64" -> %"PRId64, old.i_int, cur.i_int ); + if( !old.i_int == !cur.i_int ) + return VLC_SUCCESS; /* nothing to do */ + + if( cur.i_int ) + { + if( var_InheritBool( obj, "playlist-cork" ) ) + { + msg_Dbg( obj, "corked" ); + playlist_Pause( pl ); + } + else + msg_Dbg( obj, "not corked" ); + } + else + msg_Dbg( obj, "uncorked" ); + + (void) var; (void) dummy; + return VLC_SUCCESS; +} + static int RateCallback( vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p ) { @@ -152,19 +197,16 @@ static int VideoSplitterCallback( vlc_object_t *p_this, char const *psz_cmd, */ playlist_t * playlist_Create( vlc_object_t *p_parent ) { - static const char playlist_name[] = "playlist"; playlist_t *p_playlist; playlist_private_t *p; /* Allocate structure */ - p = vlc_custom_create( p_parent, sizeof( *p ), - VLC_OBJECT_GENERIC, playlist_name ); + p = vlc_custom_create( p_parent, sizeof( *p ), "playlist" ); if( !p ) return NULL; assert( offsetof( playlist_private_t, public_data ) == 0 ); p_playlist = &p->public_data; - vlc_object_attach( p_playlist, p_parent ); TAB_INIT( pl_priv(p_playlist)->i_sds, pl_priv(p_playlist)->pp_sds ); libvlc_priv(p_parent->p_libvlc)->p_playlist = p_playlist; @@ -172,6 +214,7 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) VariablesInit( p_playlist ); vlc_mutex_init( &p->lock ); vlc_cond_init( &p->signal ); + p->killed = false; /* Initialise data structures */ pl_priv(p_playlist)->i_last_playlist_id = 0; @@ -194,18 +237,14 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) var_InheritBool( p_parent, "auto-preparse" ); /* Fetcher */ - p->p_fetcher = playlist_fetcher_New( p_playlist ); + p->p_fetcher = playlist_fetcher_New( VLC_OBJECT(p_playlist) ); if( unlikely(p->p_fetcher == NULL) ) - { msg_Err( p_playlist, "cannot create fetcher" ); - p->p_preparser = NULL; - } - else - { /* Preparse */ - p->p_preparser = playlist_preparser_New( p_playlist, p->p_fetcher ); - if( unlikely(p->p_preparser == NULL) ) - msg_Err( p_playlist, "cannot create preparser" ); - } + /* Preparser */ + p->p_preparser = playlist_preparser_New( VLC_OBJECT(p_playlist), + p->p_fetcher ); + if( unlikely(p->p_preparser == NULL) ) + msg_Err( p_playlist, "cannot create preparser" ); /* Create the root node */ PL_LOCK; @@ -284,7 +323,6 @@ void playlist_Destroy( playlist_t *p_playlist ) /* Already cleared when deactivating (if activated anyway) */ assert( !p_sys->p_input ); - assert( !p_sys->p_input_resource ); vlc_cond_destroy( &p_sys->signal ); vlc_mutex_destroy( &p_sys->lock ); @@ -371,12 +409,6 @@ void set_current_status_node( playlist_t * p_playlist, pl_priv(p_playlist)->status.p_node = p_node; } -static input_thread_t *playlist_FindInput( vlc_object_t *object ) -{ - assert( object == VLC_OBJECT(pl_Get(object)) ); - return playlist_CurrentInput( (playlist_t *)object ); -} - static void VariablesInit( playlist_t *p_playlist ) { /* These variables control updates */ @@ -398,24 +430,26 @@ static void VariablesInit( playlist_t *p_playlist ) var_SetInteger( p_playlist, "activity", 0 ); /* Variables to control playback */ + var_Create( p_playlist, "playlist-autostart", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_playlist, "play-and-stop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_playlist, "play-and-exit", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_playlist, "random", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); + var_AddCallback( p_playlist, "random", RandomCallback, NULL ); var_Create( p_playlist, "repeat", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_playlist, "loop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); + var_Create( p_playlist, "corks", VLC_VAR_INTEGER ); + var_AddCallback( p_playlist, "corks", CorksCallback, NULL ); var_Create( p_playlist, "rate", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT ); - var_Create( p_playlist, "rate-slower", VLC_VAR_VOID ); - var_Create( p_playlist, "rate-faster", VLC_VAR_VOID ); var_AddCallback( p_playlist, "rate", RateCallback, NULL ); + var_Create( p_playlist, "rate-slower", VLC_VAR_VOID ); var_AddCallback( p_playlist, "rate-slower", RateOffsetCallback, NULL ); + var_Create( p_playlist, "rate-faster", VLC_VAR_VOID ); var_AddCallback( p_playlist, "rate-faster", RateOffsetCallback, NULL ); var_Create( p_playlist, "video-splitter", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_AddCallback( p_playlist, "video-splitter", VideoSplitterCallback, NULL ); - var_AddCallback( p_playlist, "random", RandomCallback, NULL ); - /* */ var_Create( p_playlist, "album-art", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); @@ -425,10 +459,8 @@ static void VariablesInit( playlist_t *p_playlist ) /* Audio output parameters */ var_Create( p_playlist, "mute", VLC_VAR_BOOL ); - var_Create( p_playlist, "volume", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT); - /* FIXME: horrible hack for audio output interface code */ - var_Create( p_playlist, "find-input-callback", VLC_VAR_ADDRESS ); - var_SetAddress( p_playlist, "find-input-callback", playlist_FindInput ); + var_Create( p_playlist, "volume", VLC_VAR_FLOAT ); + var_SetFloat( p_playlist, "volume", -1.f ); } playlist_item_t * playlist_CurrentPlayingItem( playlist_t * p_playlist )