[vlc-devel] [PATCH 1/2] Fixing recents not updating with cli

Rémi Denis-Courmont remi at remlab.net
Wed Nov 20 21:15:36 CET 2013


Le vendredi 22 novembre 2013, 05:37:04 Gal Vinograd a écrit :
> Recents playlist is now updating with command line arguments
> ---
>  include/vlc_playlist.h           | 12 ++++++++++++
>  src/libvlccore.sym               |  2 ++
>  src/playlist/engine.c            | 13 +++++++++++++
>  src/playlist/item.c              |  6 ++++++
>  src/playlist/loadsave.c          | 37 ++++++++++++++++++++-----------------
> src/playlist/playlist_internal.h |  4 ----
>  src/playlist/tree.c              | 28 ++++++++++++++++++++++++++++
>  7 files changed, 81 insertions(+), 21 deletions(-)
> 
> diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h
> index 10108cb..2455a44 100644
> --- a/include/vlc_playlist.h
> +++ b/include/vlc_playlist.h
> @@ -173,6 +173,7 @@ struct playlist_t
>      playlist_item_t *     p_root;
>      playlist_item_t *     p_playing;
>      playlist_item_t *     p_media_library;
> +    playlist_item_t *     p_recents;
> 
>      //Phony ones, point to those above;
>      playlist_item_t *     p_root_category; /**< Root of category tree */
> @@ -262,6 +263,12 @@ VLC_API playlist_t * pl_Get( vlc_object_t * );
>  #define playlist_Prev(p) playlist_Control(p,PLAYLIST_SKIP, pl_Unlocked, -1)
> #define playlist_Skip(p,i) playlist_Control(p,PLAYLIST_SKIP, pl_Unlocked, 
> (i) )
> 
> +#define playlist_MLDump(p) playlist_PlaylistDump( p, p->p_media_library,
> "ml.xspf", _("Media Library") ) +#define playlist_RecentsDump(p)
> playlist_PlaylistDump( p, p->p_recents, "recents.xspf", _("Recents") )
> +
> +#define playlist_MLLoad(p) playlist_PlaylistLoad( p, p->p_media_library,
> "ml.xspf", _("Media Library") ) +#define playlist_RecentsLoad(p)
> playlist_PlaylistLoad( p, p->p_recents, "recents.xspf", _("Recents") )
> +
>  VLC_API void playlist_Lock( playlist_t * );
>  VLC_API void playlist_Unlock( playlist_t * );
>  VLC_API void playlist_AssertLocked( playlist_t * );
> @@ -321,6 +328,10 @@ VLC_API int playlist_Export( playlist_t *p_playlist,
> const char *psz_name, playl */
>  VLC_API int playlist_Import( playlist_t *p_playlist, const char *psz_file
> );
> 
> +VLC_API int playlist_PlaylistDump( playlist_t *p_playlist, playlist_item_t
> *p_node, char *psz_filename, char *psz_name );
> +VLC_API int
> playlist_PlaylistLoad( playlist_t *p_playlist, playlist_item_t *p_node,
> char *psz_filename, char *psz_name ); +
> +
>  /********************** Services discovery ***********************/
> 
>  /** Add a list of comma-separated service discovery modules */
> @@ -347,6 +358,7 @@ VLC_API int playlist_AddExt( playlist_t *, const char *,
> const char *, int, int, VLC_API int playlist_AddInput( playlist_t *,
> input_item_t *, int, int, bool, bool ); VLC_API playlist_item_t *
> playlist_NodeAddInput( playlist_t *, input_item_t *, playlist_item_t *,
> int, int, bool ); VLC_API int playlist_NodeAddCopy( playlist_t *,
> playlist_item_t *, playlist_item_t *, int );
> +VLC_API int
> playlist_NodeAppendOrMove( playlist_t *p_playlist, playlist_item_t *p_item,
> playlist_item_t *p_parent );

Why do you need to export this?

> 
>  /********************************** Item search *************************/
>  VLC_API playlist_item_t * playlist_ItemGetById(playlist_t *, int )
> VLC_USED; diff --git a/src/libvlccore.sym b/src/libvlccore.sym
> index 5efc67e..2d82546 100644
> --- a/src/libvlccore.sym
> +++ b/src/libvlccore.sym
> @@ -347,6 +347,8 @@ playlist_VolumeSet
>  playlist_VolumeUp
>  playlist_MuteSet
>  playlist_MuteGet
> +playlist_PlaylistLoad
> +playlist_PlaylistDump
>  pl_Get
>  resolve_xml_special_chars
>  sdp_AddAttribute
> diff --git a/src/playlist/engine.c b/src/playlist/engine.c
> index 8207c79..f492329 100644
> --- a/src/playlist/engine.c
> +++ b/src/playlist/engine.c
> @@ -260,6 +260,19 @@ static playlist_t *playlist_Create( vlc_object_t
> *p_parent )
> 
>      if( !p_playlist->p_playing ) return NULL;
> 
> +    /* Create currently playing items node */
> +    PL_LOCK;
> +    p_playlist->p_recents = playlist_NodeCreate(
> +        p_playlist, _( "Recents" ), p_playlist->p_root,
> +        PLAYLIST_END, PLAYLIST_RO_FLAG, NULL );
> +
> +
> +    PL_UNLOCK;
> +
> +    if( !p_playlist->p_recents ) return NULL;

Memory leaks.

> +
> +    playlist_RecentsLoad( p_playlist );
> +
>      /* Create media library node */
>      const bool b_ml = var_InheritBool( p_parent, "media-library");
>      if( b_ml )
> diff --git a/src/playlist/item.c b/src/playlist/item.c
> index e902063..ccce67f 100644
> --- a/src/playlist/item.c
> +++ b/src/playlist/item.c
> @@ -464,6 +464,9 @@ int playlist_AddInput( playlist_t* p_playlist,
> input_item_t *p_input, PL_UNLOCK_IF( !b_locked );
>          return VLC_ENOMEM;
>      }
> +
> +    playlist_NodeAppendOrMove( p_playlist, p_item, p_playlist->p_recents );
> +
>      AddItem( p_playlist, p_item,
>               b_playlist ? p_playlist->p_playing :
>                            p_playlist->p_media_library , i_mode, i_pos );
> @@ -471,6 +474,9 @@ int playlist_AddInput( playlist_t* p_playlist,
> input_item_t *p_input, GoAndPreparse( p_playlist, i_mode, p_item );
> 
>      PL_UNLOCK_IF( !b_locked );
> +
> +    playlist_RecentsDump( p_playlist );
> +
>      return VLC_SUCCESS;
>  }
> 
> diff --git a/src/playlist/loadsave.c b/src/playlist/loadsave.c
> index 85a3e9e..c49d1c7 100644
> --- a/src/playlist/loadsave.c
> +++ b/src/playlist/loadsave.c
> @@ -105,35 +105,37 @@ int playlist_Import( playlist_t *p_playlist, const
> char *psz_file ) static void input_item_subitem_tree_added( const
> vlc_event_t * p_event, void * user_data )
>  {
> -    playlist_t *p_playlist = user_data;
> +    playlist_item_t *p_node = user_data;
> +    playlist_t *p_playlist = p_node->p_playlist;
>      input_item_node_t *p_root =
>          p_event->u.input_item_subitem_tree_added.p_root;
> 
>      PL_LOCK;
> -    playlist_InsertInputItemTree ( p_playlist, p_playlist->p_media_library,
> +    playlist_InsertInputItemTree ( p_playlist, p_node,
>                                     p_root, 0, false );
>      PL_UNLOCK;
>  }
> 
> -int playlist_MLLoad( playlist_t *p_playlist )
> +int playlist_PlaylistLoad( playlist_t *p_playlist, playlist_item_t *p_node,
> char *psz_filename, char *psz_name ) {
>      input_item_t *p_input;
> 
>      char *psz_datadir = config_GetUserDir( VLC_DATA_DIR );
>      if( !psz_datadir ) /* XXX: This should never happen */
>      {
> -        msg_Err( p_playlist, "no data directory, cannot load media
> library") ; +        msg_Err( p_playlist, "no data directory, cannot load
> %s", psz_name ); return VLC_EGENERIC;
>      }
> 
>      char *psz_file;
> -    if( asprintf( &psz_file, "%s" DIR_SEP "ml.xspf", psz_datadir ) == -1 )
> +
> +    if( asprintf( &psz_file, "%s" DIR_SEP "%s", psz_datadir, psz_filename )
> == -1 ) psz_file = NULL;
>      free( psz_datadir );
>      if( psz_file == NULL )
>          return VLC_ENOMEM;
> 
> -    /* lousy check for media library file */
> +    /* lousy check for the file */
>      struct stat st;
>      if( vlc_stat( psz_file, &st ) )
>      {
> @@ -149,20 +151,20 @@ int playlist_MLLoad( playlist_t *p_playlist )
>      const char *const options[1] = { "meta-file", };
>      /* that option has to be cleaned in input_item_subitem_tree_added() */
>      /* vlc_gc_decref() in the same function */
> -    p_input = input_item_NewExt( psz_uri, _("Media Library"),
> +    p_input = input_item_NewExt( psz_uri, _(psz_name),
>                                   1, options, VLC_INPUT_OPTION_TRUSTED, -1

The string is doubly translated. This seems wrong.

> ); free( psz_uri );
>      if( p_input == NULL )
>          return VLC_EGENERIC;
> 
>      PL_LOCK;
> -    if( p_playlist->p_media_library->p_input )
> -        vlc_gc_decref( p_playlist->p_media_library->p_input );
> +    if( p_node->p_input )
> +        vlc_gc_decref( p_node->p_input );
> 
> -    p_playlist->p_media_library->p_input = p_input;
> +    p_node->p_input = p_input;
> 
>      vlc_event_attach( &p_input->event_manager,
> vlc_InputItemSubItemTreeAdded, -                       
> input_item_subitem_tree_added, p_playlist ); +                       
> input_item_subitem_tree_added, p_node );
> 
>      pl_priv(p_playlist)->b_doing_ml = true;
>      PL_UNLOCK;
> @@ -174,12 +176,12 @@ int playlist_MLLoad( playlist_t *p_playlist )
>      PL_UNLOCK;
> 
>      vlc_event_detach( &p_input->event_manager,
> vlc_InputItemSubItemTreeAdded, -                       
> input_item_subitem_tree_added, p_playlist ); +                       
> input_item_subitem_tree_added, p_node );
> 
>      return VLC_SUCCESS;
>  }
> 
> -int playlist_MLDump( playlist_t *p_playlist )
> +int playlist_PlaylistDump( playlist_t *p_playlist, playlist_item_t *p_node,
> char *psz_filename, char *psz_name ) {
>      char *psz_datadir;
> 
> @@ -187,11 +189,11 @@ int playlist_MLDump( playlist_t *p_playlist )
> 
>      if( !psz_datadir ) /* XXX: This should never happen */
>      {
> -        msg_Err( p_playlist, "no data directory, cannot save media
> library") ; +        msg_Err( p_playlist, "no data directory, cannot save"
> );
>          return VLC_EGENERIC;
>      }
> 
> -    char psz_dirname[ strlen( psz_datadir ) + sizeof( DIR_SEP "ml.xspf")];
> +    char psz_dirname[ strlen( psz_datadir ) + sizeof( DIR_SEP ) + strlen(
> psz_filename ) ]; strcpy( psz_dirname, psz_datadir );
>      free( psz_datadir );
>      if( config_CreateDir( (vlc_object_t *)p_playlist, psz_dirname ) )
> @@ -199,9 +201,10 @@ int playlist_MLDump( playlist_t *p_playlist )
>          return VLC_EGENERIC;
>      }
> 
> -    strcat( psz_dirname, DIR_SEP "ml.xspf" );
> +    strcat( psz_dirname, DIR_SEP );
> +    strcat( psz_dirname, psz_filename );
> 
> -    playlist_Export( p_playlist, psz_dirname, p_playlist->p_media_library,
> +    playlist_Export( p_playlist, psz_dirname, p_node,
>                       "export-xspf" );
> 
>      return VLC_SUCCESS;
> diff --git a/src/playlist/playlist_internal.h
> b/src/playlist/playlist_internal.h index 9b6c000..5e430d5 100644
> --- a/src/playlist/playlist_internal.h
> +++ b/src/playlist/playlist_internal.h
> @@ -112,10 +112,6 @@ playlist_item_t * get_current_status_node( playlist_t *
> p_playlist ); void set_current_status_item( playlist_t *, playlist_item_t *
> );
>  void set_current_status_node( playlist_t *, playlist_item_t * );
> 
> -/* Load/Save */
> -int playlist_MLLoad( playlist_t *p_playlist );
> -int playlist_MLDump( playlist_t *p_playlist );
> -
>  /**********************************************************************
>   * Item management
>   **********************************************************************/
> diff --git a/src/playlist/tree.c b/src/playlist/tree.c
> index eca12b1..a468c80 100644
> --- a/src/playlist/tree.c
> +++ b/src/playlist/tree.c
> @@ -226,6 +226,34 @@ int playlist_NodeInsert( playlist_t *p_playlist,
>  }
> 
>  /**
> + * Append item to a node or move an existing to the top
> + *
> + * \param p_playlist the playlist
> + * \param p_item the item to append or move
> + * \param p_parent the parent nove
> + * \return VLC_SUCCESS or an error
> + */
> +int playlist_NodeAppendOrMove( playlist_t *p_playlist,
> +                         playlist_item_t *p_item,
> +                         playlist_item_t *p_parent )
> +{

Missing PL_ASSERT_LOCKED?

> +    for ( int i = 0; i < p_parent->i_children; i++ )
> +    {
> +        if ( !strcmp( p_parent->pp_children[i]->p_input->psz_uri,
> p_item->p_input->psz_uri ) )

This is going to be slow if there are a lot of items...

> +        {
> +            playlist_item_t *old_item = p_parent->pp_children[i];
> +
> +            if ( playlist_NodeRemoveItem( p_playlist, old_item, p_parent )
> != NULL )
> +                return NULL;
> +
> +            return playlist_NodeInsert( p_playlist, old_item, p_parent, -1
> );
> +        }
> +    }
> +
> +    return playlist_NodeInsert( p_playlist, p_item, p_parent, -1 );
> +}
> +
> +/**
>   * Deletes an item from the children of a node
>   *
>   * \param p_playlist the playlist

Also did I miss the expiration code? We cannot keep all items ever played; the 
data set has to be limited somehow.

-- 
Rémi Denis-Courmont
http://www.remlab.net/




More information about the vlc-devel mailing list