Commit f452c110 authored by Rafaël Carré's avatar Rafaël Carré

playlist_CreateNode(): add an argument to specify an input_item_t to be linked...

playlist_CreateNode(): add an argument to specify an input_item_t to be linked with the node, rather than creating a new input.
Setting that argument to NULL will make playlist_CreateNode() behave like previously.

That way we can create only one input per pair of node (for local playlist, media library, and service discovery)
Previous behaviour was to create 2 inputs with the same i_id member, but we would store both input in a binary search tree (sorted by i_id), and that kind of tree MUST NOT have 2 items with the same key, else we will get some bad memory corruption when the wrong input is removed from the tree (the other being left in the tree while the memory referred by it was freed).
Note that this breaks ABI
parent fbce9b96
...@@ -391,7 +391,7 @@ VLC_EXPORT(void, playlist_NodeDump, ( playlist_t *p_playlist, playlist_item_t *p ...@@ -391,7 +391,7 @@ VLC_EXPORT(void, playlist_NodeDump, ( playlist_t *p_playlist, playlist_item_t *p
VLC_EXPORT( int, playlist_NodeChildrenCount, (playlist_t *,playlist_item_t* ) ); VLC_EXPORT( int, playlist_NodeChildrenCount, (playlist_t *,playlist_item_t* ) );
/* Node management */ /* Node management */
VLC_EXPORT( playlist_item_t *, playlist_NodeCreate, ( playlist_t *, const char *, playlist_item_t * p_parent, int i_flags ) ); VLC_EXPORT( playlist_item_t *, playlist_NodeCreate, ( playlist_t *, const char *, playlist_item_t * p_parent, int i_flags, input_item_t * ) );
VLC_EXPORT( int, playlist_NodeAppend, (playlist_t *,playlist_item_t*,playlist_item_t *) ); VLC_EXPORT( int, playlist_NodeAppend, (playlist_t *,playlist_item_t*,playlist_item_t *) );
VLC_EXPORT( int, playlist_NodeInsert, (playlist_t *,playlist_item_t*,playlist_item_t *, int) ); VLC_EXPORT( int, playlist_NodeInsert, (playlist_t *,playlist_item_t*,playlist_item_t *, int) );
VLC_EXPORT( int, playlist_NodeRemoveItem, (playlist_t *,playlist_item_t*,playlist_item_t *) ); VLC_EXPORT( int, playlist_NodeRemoveItem, (playlist_t *,playlist_item_t*,playlist_item_t *) );
......
...@@ -476,7 +476,7 @@ static int ReadDir( playlist_t *p_playlist, const char *psz_name, ...@@ -476,7 +476,7 @@ static int ReadDir( playlist_t *p_playlist, const char *psz_name,
p_node = playlist_NodeCreate( p_playlist, entry, p_node = playlist_NodeCreate( p_playlist, entry,
p_parent_category, p_parent_category,
PLAYLIST_NO_REBUILD ); PLAYLIST_NO_REBUILD, NULL );
/* If we had the parent in category, the it is now node. /* If we had the parent in category, the it is now node.
* Else, we still don't have */ * Else, we still don't have */
......
...@@ -1373,12 +1373,12 @@ ...@@ -1373,12 +1373,12 @@
if( psz_name != NULL && psz_name != "" ) if( psz_name != NULL && psz_name != "" )
p_item = playlist_NodeCreate( p_playlist, psz_name, p_item = playlist_NodeCreate( p_playlist, psz_name,
p_playlist->p_local_category, 0 ); p_playlist->p_local_category, 0, NULL );
else if(! config_GetInt( p_playlist, "interact" ) ) else if(! config_GetInt( p_playlist, "interact" ) )
{ {
/* in case that the interaction is disabled, just give it a bogus name */ /* in case that the interaction is disabled, just give it a bogus name */
p_item = playlist_NodeCreate( p_playlist, _("Empty Folder"), p_item = playlist_NodeCreate( p_playlist, _("Empty Folder"),
p_playlist->p_local_category, 0 ); p_playlist->p_local_category, 0, NULL );
} }
if(! p_item ) if(! p_item )
......
...@@ -1605,7 +1605,7 @@ void Playlist::OnPopupAddNode( wxCommandEvent& event ) ...@@ -1605,7 +1605,7 @@ void Playlist::OnPopupAddNode( wxCommandEvent& event )
p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, VLC_TRUE ); p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id, VLC_TRUE );
playlist_NodeCreate( p_playlist, psz_name, p_item, 0 ); playlist_NodeCreate( p_playlist, psz_name, p_item, 0, NULL );
UnlockPlaylist( p_intf->p_sys, p_playlist ); UnlockPlaylist( p_intf->p_sys, p_playlist );
Rebuild( VLC_TRUE ); Rebuild( VLC_TRUE );
......
...@@ -180,7 +180,7 @@ playlist_item_t *UPnPHandler::AddDevice( Device *dev ) ...@@ -180,7 +180,7 @@ playlist_item_t *UPnPHandler::AddDevice( Device *dev )
*/ */
char *str = strdup( dev->getFriendlyName( ) ); char *str = strdup( dev->getFriendlyName( ) );
p_item = playlist_NodeCreate( p_playlist, str, p_sd->p_cat,0 ); p_item = playlist_NodeCreate( p_playlist, str, p_sd->p_cat, 0, NULL );
p_item->i_flags &= ~PLAYLIST_SKIP_FLAG; p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
msg_Dbg( p_sd, "device %s added", str ); msg_Dbg( p_sd, "device %s added", str );
free( str ); free( str );
...@@ -221,8 +221,8 @@ void UPnPHandler::AddContent( playlist_item_t *p_parent, ContentNode *node ) ...@@ -221,8 +221,8 @@ void UPnPHandler::AddContent( playlist_item_t *p_parent, ContentNode *node )
ContainerNode *conNode = (ContainerNode *)node; ContainerNode *conNode = (ContainerNode *)node;
char* p_name = strdup(title); /* See other comment on strdup */ char* p_name = strdup(title); /* See other comment on strdup */
playlist_item_t* p_node = playlist_NodeCreate( p_playlist, playlist_item_t* p_node = playlist_NodeCreate( p_playlist, p_name,
p_name, p_parent, 0 ); p_parent, 0, NULL );
free(p_name); free(p_name);
unsigned nContentNodes = conNode->getNContentNodes(); unsigned nContentNodes = conNode->getNContentNodes();
......
...@@ -853,7 +853,7 @@ void MediaServer::_buildPlaylist( Container* parent ) ...@@ -853,7 +853,7 @@ void MediaServer::_buildPlaylist( Container* parent )
playlist_item_t* parentNode = parent->getPlaylistNode(); playlist_item_t* parentNode = parent->getPlaylistNode();
char* title = strdup( container->getTitle() ); char* title = strdup( container->getTitle() );
playlist_item_t* node = playlist_NodeCreate( p_playlist, title, parentNode, 0 ); playlist_item_t* node = playlist_NodeCreate( p_playlist, title, parentNode, 0, NULL );
free( title ); free( title );
container->setPlaylistNode( node ); container->setPlaylistNode( node );
...@@ -916,7 +916,7 @@ bool MediaServerList::addServer( MediaServer* s ) ...@@ -916,7 +916,7 @@ bool MediaServerList::addServer( MediaServer* s )
char* name = strdup( s->getFriendlyName() ); char* name = strdup( s->getFriendlyName() );
playlist_item_t* node = playlist_NodeCreate( pl_Get( _cookie->serviceDiscovery ), playlist_item_t* node = playlist_NodeCreate( pl_Get( _cookie->serviceDiscovery ),
name, name,
_cookie->serviceDiscovery->p_sys->p_node_cat, 0 ); _cookie->serviceDiscovery->p_sys->p_node_cat, 0, NULL );
free( name ); free( name );
s->setPlaylistNode( node ); s->setPlaylistNode( node );
......
...@@ -100,18 +100,18 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) ...@@ -100,18 +100,18 @@ playlist_t * playlist_Create( vlc_object_t *p_parent )
var_CreateGetBool( p_playlist, "auto-preparse") ; var_CreateGetBool( p_playlist, "auto-preparse") ;
p_playlist->p_root_category = playlist_NodeCreate( p_playlist, NULL, NULL, p_playlist->p_root_category = playlist_NodeCreate( p_playlist, NULL, NULL,
0 ); 0, NULL );
p_playlist->p_root_onelevel = playlist_NodeCreate( p_playlist, NULL, NULL, p_playlist->p_root_onelevel = playlist_NodeCreate( p_playlist, NULL, NULL,
0 ); 0, p_playlist->p_root_category->p_input );
if( !p_playlist->p_root_category || !p_playlist->p_root_onelevel ) if( !p_playlist->p_root_category || !p_playlist->p_root_onelevel )
return NULL; return NULL;
/* Create playlist and media library */ /* Create playlist and media library */
p_playlist->p_local_category = playlist_NodeCreate( p_playlist, playlist_NodesPairCreate( p_playlist, _( "Playlist" ),
_( "Playlist" ),p_playlist->p_root_category, 0 ); &p_playlist->p_local_category,
p_playlist->p_local_onelevel = playlist_NodeCreate( p_playlist, &p_playlist->p_local_onelevel, VLC_FALSE );
_( "Playlist" ), p_playlist->p_root_onelevel, 0 );
p_playlist->p_local_category->i_flags |= PLAYLIST_RO_FLAG; p_playlist->p_local_category->i_flags |= PLAYLIST_RO_FLAG;
p_playlist->p_local_onelevel->i_flags |= PLAYLIST_RO_FLAG; p_playlist->p_local_onelevel->i_flags |= PLAYLIST_RO_FLAG;
...@@ -120,25 +120,17 @@ playlist_t * playlist_Create( vlc_object_t *p_parent ) ...@@ -120,25 +120,17 @@ playlist_t * playlist_Create( vlc_object_t *p_parent )
!p_playlist->p_local_onelevel->p_input ) !p_playlist->p_local_onelevel->p_input )
return NULL; return NULL;
/* Link the nodes together. Todo: actually create them from the same input*/
p_playlist->p_local_onelevel->p_input->i_id =
p_playlist->p_local_category->p_input->i_id;
if( config_GetInt( p_playlist, "media-library") ) if( config_GetInt( p_playlist, "media-library") )
{ {
p_playlist->p_ml_category = playlist_NodeCreate( p_playlist, playlist_NodesPairCreate( p_playlist, _( "Media Library" ),
_( "Media Library" ), p_playlist->p_root_category, 0 ); &p_playlist->p_ml_category,
p_playlist->p_ml_onelevel = playlist_NodeCreate( p_playlist, &p_playlist->p_ml_onelevel, VLC_FALSE );
_( "Media Library" ), p_playlist->p_root_onelevel, 0 );
if(!p_playlist->p_ml_category || !p_playlist->p_ml_onelevel) if(!p_playlist->p_ml_category || !p_playlist->p_ml_onelevel)
return NULL; return NULL;
p_playlist->p_ml_category->i_flags |= PLAYLIST_RO_FLAG; p_playlist->p_ml_category->i_flags |= PLAYLIST_RO_FLAG;
p_playlist->p_ml_onelevel->i_flags |= PLAYLIST_RO_FLAG; p_playlist->p_ml_onelevel->i_flags |= PLAYLIST_RO_FLAG;
p_playlist->p_ml_onelevel->p_input->i_id =
p_playlist->p_ml_category->p_input->i_id;
} }
else else
{ {
......
...@@ -207,7 +207,7 @@ static void playlist_sd_item_added( const vlc_event_t * p_event, void * user_dat ...@@ -207,7 +207,7 @@ static void playlist_sd_item_added( const vlc_event_t * p_event, void * user_dat
if( !p_cat ) if( !p_cat )
{ {
p_cat = playlist_NodeCreate( p_parent->p_playlist, psz_cat, p_cat = playlist_NodeCreate( p_parent->p_playlist, psz_cat,
p_parent, 0 ); p_parent, 0, NULL );
p_cat->i_flags &= ~PLAYLIST_SKIP_FLAG; p_cat->i_flags &= ~PLAYLIST_SKIP_FLAG;
} }
p_parent = p_cat; p_parent = p_cat;
......
...@@ -47,19 +47,24 @@ playlist_item_t *GetPrevItem( playlist_t *p_playlist, ...@@ -47,19 +47,24 @@ playlist_item_t *GetPrevItem( playlist_t *p_playlist,
* \paam psz_name the name of the node * \paam psz_name the name of the node
* \param p_parent the parent node to attach to or NULL if no attach * \param p_parent the parent node to attach to or NULL if no attach
* \param p_flags miscellaneous flags * \param p_flags miscellaneous flags
* \param p_input the input_item to attach to or NULL if it has to be created
* \return the new node * \return the new node
*/ */
playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist, playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist,
const char *psz_name, const char *psz_name,
playlist_item_t *p_parent, int i_flags ) playlist_item_t *p_parent, int i_flags,
input_item_t *p_input )
{ {
input_item_t *p_input; input_item_t *p_new_input;
playlist_item_t *p_item; playlist_item_t *p_item;
if( !psz_name ) psz_name = _("Undefined"); if( !psz_name ) psz_name = _("Undefined");
p_input = input_ItemNewWithType( VLC_OBJECT(p_playlist), NULL, psz_name,
0, NULL, -1, ITEM_TYPE_NODE ); if( !p_input )
p_item = playlist_ItemNewFromInput( VLC_OBJECT(p_playlist), p_input ); p_new_input = input_ItemNewWithType( VLC_OBJECT(p_playlist), NULL,
psz_name, 0, NULL, -1, ITEM_TYPE_NODE );
p_item = playlist_ItemNewFromInput( VLC_OBJECT(p_playlist),
p_input ? p_input : p_new_input );
if( p_item == NULL ) return NULL; if( p_item == NULL ) return NULL;
p_item->i_children = 0; p_item->i_children = 0;
...@@ -279,8 +284,7 @@ playlist_item_t *playlist_ChildSearchName( playlist_item_t *p_node, ...@@ -279,8 +284,7 @@ playlist_item_t *playlist_ChildSearchName( playlist_item_t *p_node,
/** /**
* Create a pair of nodes in the category and onelevel trees. * Create a pair of nodes in the category and onelevel trees.
* They share the same input ID. * They share the same input item.
* \todo really share the input item
* \param p_playlist the playlist * \param p_playlist the playlist
* \param psz_name the name of the nodes * \param psz_name the name of the nodes
* \param pp_node_cat pointer to return the node in category tree * \param pp_node_cat pointer to return the node in category tree
...@@ -293,10 +297,10 @@ void playlist_NodesPairCreate( playlist_t *p_playlist, const char *psz_name, ...@@ -293,10 +297,10 @@ void playlist_NodesPairCreate( playlist_t *p_playlist, const char *psz_name,
vlc_bool_t b_for_sd ) vlc_bool_t b_for_sd )
{ {
*pp_node_cat = playlist_NodeCreate( p_playlist, psz_name, *pp_node_cat = playlist_NodeCreate( p_playlist, psz_name,
p_playlist->p_root_category, 0 ); p_playlist->p_root_category, 0, NULL );
*pp_node_one = playlist_NodeCreate( p_playlist, psz_name, *pp_node_one = playlist_NodeCreate( p_playlist, psz_name,
p_playlist->p_root_onelevel, 0 ); p_playlist->p_root_onelevel, 0,
(*pp_node_one)->p_input->i_id = (*pp_node_cat)->p_input->i_id; (*pp_node_cat)->p_input );
if( b_for_sd ) if( b_for_sd )
{ {
(*pp_node_cat)->i_flags |= PLAYLIST_RO_FLAG; (*pp_node_cat)->i_flags |= PLAYLIST_RO_FLAG;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment