X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fplaylist%2Fengine.c;h=05ea3b11745ae36104250c64d71b05070f237217;hb=f658f93c23312ca6585ddaf06bc09cf84771187f;hp=aca7b59f6d5c2588dc3ee74184bbdcf9fe400bb0;hpb=84a5171fa314607b3047b3dcd7eb3f1aa5935024;p=vlc diff --git a/src/playlist/engine.c b/src/playlist/engine.c index aca7b59f6d..05ea3b1174 100644 --- a/src/playlist/engine.c +++ b/src/playlist/engine.c @@ -27,13 +27,14 @@ #include #include + #include #include #include #include +#include #include "playlist_internal.h" -#include "stream_output/stream_output.h" /* sout_DeleteInstance */ -#include /* for fabs() */ +#include "input/resource.h" /***************************************************************************** * Local prototypes @@ -83,18 +84,19 @@ static int CorksCallback( vlc_object_t *obj, char const *var, if( !old.i_int == !cur.i_int ) return VLC_SUCCESS; /* nothing to do */ + if( !var_InheritBool( obj, "playlist-cork" ) ) + return VLC_SUCCESS; + if( cur.i_int ) { - if( var_InheritBool( obj, "playlist-cork" ) ) - { - msg_Dbg( obj, "corked" ); - playlist_Pause( pl ); - } - else - msg_Dbg( obj, "not corked" ); + msg_Dbg( obj, "corked" ); + playlist_Pause( pl ); } else + { msg_Dbg( obj, "uncorked" ); + playlist_Resume( pl ); + } (void) var; (void) dummy; return VLC_SUCCESS; @@ -143,7 +145,7 @@ static int RateOffsetCallback( vlc_object_t *obj, char const *psz_cmd, if( !strcmp( psz_cmd, "rate-faster" ) ) { /* compensate for input rounding errors */ - float r = f_rate * 1.1; + float r = f_rate * 1.1f; for( size_t i = 0; i < i_rate_count; i++ ) if( r < pf_rate[i] ) { @@ -154,7 +156,7 @@ static int RateOffsetCallback( vlc_object_t *obj, char const *psz_cmd, else { /* compensate for input rounding errors */ - float r = f_rate * .9; + float r = f_rate * .9f; for( size_t i = 1; i < i_rate_count; i++ ) if( r <= pf_rate[i] ) { @@ -195,7 +197,7 @@ static int VideoSplitterCallback( vlc_object_t *p_this, char const *psz_cmd, * \param p_parent the vlc object that is to be the parent of this playlist * \return a pointer to the created playlist, or NULL on error */ -playlist_t * playlist_Create( vlc_object_t *p_parent ) +playlist_t *playlist_Create( vlc_object_t *p_parent ) { playlist_t *p_playlist; playlist_private_t *p; @@ -209,8 +211,6 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) p_playlist = &p->public_data; TAB_INIT( pl_priv(p_playlist)->i_sds, pl_priv(p_playlist)->pp_sds ); - libvlc_priv(p_parent->p_libvlc)->p_playlist = p_playlist; - VariablesInit( p_playlist ); vlc_mutex_init( &p->lock ); vlc_cond_init( &p->signal ); @@ -227,59 +227,30 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) p_playlist->i_current_index = 0; pl_priv(p_playlist)->b_reset_currently_playing = true; - pl_priv(p_playlist)->last_rebuild_date = 0; pl_priv(p_playlist)->b_tree = var_InheritBool( p_parent, "playlist-tree" ); - pl_priv(p_playlist)->b_doing_ml = false; - - pl_priv(p_playlist)->b_auto_preparse = - var_InheritBool( p_parent, "auto-preparse" ); - - /* Fetcher */ - p->p_fetcher = playlist_fetcher_New( VLC_OBJECT(p_playlist) ); - if( unlikely(p->p_fetcher == NULL) ) - msg_Err( p_playlist, "cannot create fetcher" ); - /* 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; - p_playlist->p_root = playlist_NodeCreate( p_playlist, NULL, NULL, - PLAYLIST_END, 0, NULL ); - PL_UNLOCK; - if( !p_playlist->p_root ) return NULL; + /* Create the root, playing items and meida library nodes */ + playlist_item_t *root, *playing, *ml; - /* Create currently playing items node */ PL_LOCK; - p_playlist->p_playing = playlist_NodeCreate( - p_playlist, _( "Playlist" ), p_playlist->p_root, - PLAYLIST_END, PLAYLIST_RO_FLAG, NULL ); - + root = playlist_NodeCreate( p_playlist, NULL, NULL, + PLAYLIST_END, 0, NULL ); + playing = playlist_NodeCreate( p_playlist, _( "Playlist" ), root, + PLAYLIST_END, PLAYLIST_RO_FLAG, NULL ); + if( var_InheritBool( p_parent, "media-library") ) + ml = playlist_NodeCreate( p_playlist, _( "Media Library" ), root, + PLAYLIST_END, PLAYLIST_RO_FLAG, NULL ); + else + ml = NULL; PL_UNLOCK; - if( !p_playlist->p_playing ) return NULL; - - /* Create media library node */ - const bool b_ml = var_InheritBool( p_parent, "media-library"); - if( b_ml ) - { - PL_LOCK; - p_playlist->p_media_library = playlist_NodeCreate( - p_playlist, _( "Media Library" ), p_playlist->p_root, - PLAYLIST_END, PLAYLIST_RO_FLAG, NULL ); - PL_UNLOCK; - - if(!p_playlist->p_media_library ) return NULL; - } - else - { - p_playlist->p_media_library = NULL; - } + if( unlikely(root == NULL || playing == NULL) ) + abort(); + p_playlist->p_root = root; + p_playlist->p_playing = playing; + p_playlist->p_media_library = ml; p_playlist->p_root_category = p_playlist->p_root; p_playlist->p_root_onelevel = p_playlist->p_root; p_playlist->p_local_category = p_playlist->p_playing; @@ -291,14 +262,48 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) pl_priv(p_playlist)->status.p_item = NULL; pl_priv(p_playlist)->status.p_node = p_playlist->p_playing; pl_priv(p_playlist)->request.b_request = false; - pl_priv(p_playlist)->status.i_status = PLAYLIST_STOPPED; - if(b_ml) - { - const bool b_auto_preparse = pl_priv(p_playlist)->b_auto_preparse; - pl_priv(p_playlist)->b_auto_preparse = false; + if (ml != NULL) playlist_MLLoad( p_playlist ); - pl_priv(p_playlist)->b_auto_preparse = b_auto_preparse; + + /* Preparser (and meta retriever) _after_ the Media Library*/ + if( var_InheritBool( p_parent, "auto-preparse" ) ) + { + p->p_preparser = playlist_preparser_New( VLC_OBJECT(p_playlist) ); + if( unlikely(p->p_preparser == NULL) ) + msg_Err( p_playlist, "cannot create preparser" ); + } + + /* Input resources */ + p->p_input_resource = input_resource_New( VLC_OBJECT( p_playlist ) ); + if( unlikely(p->p_input_resource == NULL) ) + abort(); + + /* Audio output (needed for volume and device controls). */ + audio_output_t *aout = input_resource_GetAout( p->p_input_resource ); + if( aout != NULL ) + input_resource_PutAout( p->p_input_resource, aout ); + + /* Initialize the shared HTTP cookie jar */ + vlc_value_t cookies; + cookies.p_address = vlc_http_cookies_new(); + if ( likely(cookies.p_address) ) + { + var_Create( p_playlist, "http-cookies", VLC_VAR_ADDRESS ); + var_SetChecked( p_playlist, "http-cookies", VLC_VAR_ADDRESS, cookies ); + } + + /* Thread */ + playlist_Activate (p_playlist); + + /* Add service discovery modules */ + char *mods = var_InheritString( p_playlist, "services-discovery" ); + if( mods != NULL ) + { + char *s = mods, *m; + while( (m = strsep( &s, " :," )) != NULL ) + playlist_ServicesDiscoveryAdd( p_playlist, m ); + free( mods ); } return p_playlist; @@ -315,14 +320,28 @@ void playlist_Destroy( playlist_t *p_playlist ) { playlist_private_t *p_sys = pl_priv(p_playlist); + /* Remove all services discovery */ + playlist_ServicesDiscoveryKillAll( p_playlist ); + msg_Dbg( p_playlist, "destroying" ); + + playlist_Deactivate( p_playlist ); if( p_sys->p_preparser ) playlist_preparser_Delete( p_sys->p_preparser ); - if( p_sys->p_fetcher ) - playlist_fetcher_Delete( p_sys->p_fetcher ); - /* Already cleared when deactivating (if activated anyway) */ - assert( !p_sys->p_input ); + /* Release input resources */ + assert( p_sys->p_input == NULL ); + input_resource_Release( p_sys->p_input_resource ); + + if( p_playlist->p_media_library != NULL ) + playlist_MLDump( p_playlist ); + + PL_LOCK; + /* Release the current node */ + set_current_status_node( p_playlist, NULL ); + /* Release the current item */ + set_current_status_item( p_playlist, NULL ); + PL_UNLOCK; vlc_cond_destroy( &p_sys->signal ); vlc_mutex_destroy( &p_sys->lock ); @@ -344,6 +363,13 @@ void playlist_Destroy( playlist_t *p_playlist ) ARRAY_RESET( p_playlist->items ); ARRAY_RESET( p_playlist->current ); + vlc_http_cookie_jar_t *cookies = var_GetAddress( p_playlist, "http-cookies" ); + if ( cookies ) + { + var_Destroy( p_playlist, "http-cookies" ); + vlc_http_cookies_destroy( cookies ); + } + vlc_object_release( p_playlist ); } @@ -423,15 +449,12 @@ static void VariablesInit( playlist_t *p_playlist ) var_Create( p_playlist, "playlist-item-append", VLC_VAR_ADDRESS ); - var_Create( p_playlist, "item-current", VLC_VAR_ADDRESS ); var_Create( p_playlist, "input-current", VLC_VAR_ADDRESS ); var_Create( p_playlist, "activity", VLC_VAR_VOID ); /* 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 ); @@ -451,10 +474,12 @@ static void VariablesInit( playlist_t *p_playlist ) /* */ var_Create( p_playlist, "album-art", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); + var_Create( p_playlist, "metadata-network-access", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); /* Variables to preserve video output parameters */ var_Create( p_playlist, "fullscreen", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); var_Create( p_playlist, "video-on-top", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); + var_Create( p_playlist, "video-wallpaper", VLC_VAR_BOOL | VLC_VAR_DOINHERIT ); /* Audio output parameters */ var_Create( p_playlist, "mute", VLC_VAR_BOOL ); @@ -471,8 +496,14 @@ playlist_item_t * playlist_CurrentPlayingItem( playlist_t * p_playlist ) int playlist_Status( playlist_t * p_playlist ) { + input_thread_t *p_input = pl_priv(p_playlist)->p_input; + PL_ASSERT_LOCKED; - return pl_priv(p_playlist)->status.i_status; + if( p_input == NULL ) + return PLAYLIST_STOPPED; + if( var_GetInteger( p_input, "state" ) == PAUSE_S ) + return PLAYLIST_PAUSED; + return PLAYLIST_RUNNING; }