mirror of
https://code.videolan.org/videolan/vlc
synced 2024-10-03 01:31:53 +02:00
fix #1410.
You can not change a playlist_item_t to be a node, when you previously registered events on it, using input_item_t sub items adding event, because the pointer will be destroyed. If you want to use nodes anyway, you have to explicitely create them. Note: we were lucky that xspf did work so far, because we were EXCLUSIVELY using invalid pointers, except for the 1st item being added to each playlist_item_t (it did happen before the conversion obviously).
This commit is contained in:
parent
981f85eb6b
commit
7b9e1799ee
@ -139,6 +139,7 @@ typedef struct vlc_event_t
|
||||
struct vlc_input_item_subitem_added
|
||||
{
|
||||
input_item_t * p_new_child;
|
||||
vlc_bool_t b_node;
|
||||
} input_item_subitem_added;
|
||||
struct vlc_input_item_duration_changed
|
||||
{
|
||||
|
@ -125,7 +125,8 @@ static inline void input_item_SetName( input_item_t *p_item, const char *psz_nam
|
||||
* It is not the input item's responsability to keep all the ref of
|
||||
* the input item children. */
|
||||
static inline void input_ItemAddSubItem( input_item_t *p_parent,
|
||||
input_item_t *p_child )
|
||||
input_item_t *p_child,
|
||||
vlc_bool_t b_node )
|
||||
{
|
||||
vlc_event_t event;
|
||||
|
||||
@ -134,6 +135,7 @@ static inline void input_ItemAddSubItem( input_item_t *p_parent,
|
||||
/* Notify interested third parties */
|
||||
event.type = vlc_InputItemSubItemAdded;
|
||||
event.u.input_item_subitem_added.p_new_child = p_child;
|
||||
event.u.input_item_subitem_added.b_node = b_node;
|
||||
vlc_event_send( &p_parent->event_manager, &event );
|
||||
}
|
||||
|
||||
|
@ -457,7 +457,7 @@ static int Demux( demux_t *p_demux )
|
||||
psz_string[i_strlen] = '\0';
|
||||
p_input = input_ItemNew( p_playlist, psz_string, psz_title_asx );
|
||||
input_ItemCopyOptions( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
free( psz_string );
|
||||
}
|
||||
else continue;
|
||||
@ -526,7 +526,7 @@ static int Demux( demux_t *p_demux )
|
||||
if( psz_copyright_entry ) input_item_SetCopyright( p_entry, psz_copyright_entry );
|
||||
if( psz_moreinfo_entry ) input_item_SetURL( p_entry, psz_moreinfo_entry );
|
||||
if( psz_abstract_entry ) input_item_SetDescription( p_entry, psz_abstract_entry );
|
||||
input_ItemAddSubItem( p_current_input, p_entry );
|
||||
input_ItemAddSubItem( p_current_input, p_entry, VLC_FALSE );
|
||||
vlc_gc_decref( p_entry );
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ static int Demux( demux_t *p_demux )
|
||||
if( psz_bitrate )
|
||||
msg_Err( p_playlist, "Unsupported meta bitrate" );
|
||||
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
FREENULL( psz_name );
|
||||
FREENULL( psz_mrl );
|
||||
|
@ -118,7 +118,7 @@ static int Demux( demux_t *p_demux )
|
||||
EnsureUTF8( ppsz_options[i] );
|
||||
input_ItemAddOption( p_input, ppsz_options[i] );
|
||||
}
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
while( i_options-- ) free( ppsz_options[i_options] );
|
||||
if( ppsz_options ) free( ppsz_options );
|
||||
|
@ -209,7 +209,7 @@ static int Demux( demux_t *p_demux )
|
||||
SADD_INFO( "gvp_version", psz_version );
|
||||
SADD_INFO( "docid", psz_docid );
|
||||
SADD_INFO( "description", psz_description );
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ static int Demux( demux_t *p_demux )
|
||||
snprintf( psz_url, len+1, "dvd://%s", p_demux->psz_path );
|
||||
|
||||
p_input = input_ItemNewExt( p_playlist, psz_url, psz_url, 0, NULL, -1 );
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
|
||||
HANDLE_PLAY_AND_RELEASE;
|
||||
|
@ -374,7 +374,7 @@ static vlc_bool_t parse_track_dict COMPLEX_INTERFACE
|
||||
|
||||
p_new_input = input_ItemNewExt( p_playlist, psz_uri,
|
||||
NULL, 0, NULL, -1 );
|
||||
input_ItemAddSubItem( p_input_item, p_new_input );
|
||||
input_ItemAddSubItem( p_input_item, p_new_input, VLC_FALSE );
|
||||
|
||||
/* add meta info */
|
||||
add_meta( p_new_input, p_track );
|
||||
|
@ -192,7 +192,7 @@ static int Demux( demux_t *p_demux )
|
||||
if ( psz_artist && *psz_artist )
|
||||
input_ItemAddInfo( p_input, _(VLC_META_INFO_CAT),
|
||||
_(VLC_META_ARTIST), "%s", psz_artist );
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
free( psz_mrl );
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ static int Demux( demux_t *p_demux )
|
||||
p_input = input_ItemNewExt( p_playlist, psz_mrl, psz_name,
|
||||
0, NULL, -1 );
|
||||
input_ItemCopyOptions( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
}
|
||||
else
|
||||
@ -221,7 +221,7 @@ static int Demux( demux_t *p_demux )
|
||||
{
|
||||
p_input = input_ItemNewExt( p_playlist, psz_mrl, psz_name,0, NULL, -1 );
|
||||
input_ItemCopyOptions( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
free( psz_mrl_orig );
|
||||
psz_mrl = NULL;
|
||||
|
@ -288,7 +288,7 @@ static int Demux( demux_t *p_demux )
|
||||
"%s bytes",
|
||||
psz_item_size );
|
||||
}
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
FREENULL( psz_item_name );
|
||||
FREENULL( psz_item_mrl );
|
||||
|
@ -356,13 +356,13 @@ static int Demux( demux_t *p_demux )
|
||||
p_input, "QuickTime Media Link", _(type), "%s", field ) ; }
|
||||
SADD_INFO( "href", psz_href );
|
||||
SADD_INFO( "mime type", psz_mimetype );
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
if( psz_qtnext )
|
||||
{
|
||||
p_input = input_ItemNewExt( p_sys->p_playlist,
|
||||
psz_qtnext, NULL, 0, NULL, -1 );
|
||||
input_ItemAddSubItem( p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
}
|
||||
}
|
||||
|
@ -404,7 +404,7 @@ static int Demux ( demux_t *p_demux )
|
||||
free( psz_option );
|
||||
}
|
||||
|
||||
input_ItemAddSubItem( p_current_input, p_child );
|
||||
input_ItemAddSubItem( p_current_input, p_child, VLC_FALSE );
|
||||
vlc_gc_decref( p_child );
|
||||
HANDLE_PLAY_AND_RELEASE
|
||||
return 0; /* Needed for correct operation of go back */
|
||||
|
@ -235,7 +235,7 @@ static int DemuxGenre( demux_t *p_demux )
|
||||
input_ItemCopyOptions( p_sys->p_current_input,
|
||||
p_input );
|
||||
free( psz_mrl );
|
||||
input_ItemAddSubItem( p_sys->p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_sys->p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
FREENULL( psz_name );
|
||||
}
|
||||
@ -423,7 +423,7 @@ static int DemuxStation( demux_t *p_demux )
|
||||
input_item_SetNowPlaying( p_input, psz_ct );
|
||||
if( psz_rt )
|
||||
input_item_SetRating( p_input, psz_rt );
|
||||
input_ItemAddSubItem( p_sys->p_current_input, p_input );
|
||||
input_ItemAddSubItem( p_sys->p_current_input, p_input, VLC_FALSE );
|
||||
vlc_gc_decref( p_input );
|
||||
FREENULL( psz_name );
|
||||
FREENULL( psz_mt );
|
||||
|
@ -126,8 +126,9 @@ int Demux( demux_t *p_demux )
|
||||
input_item_t *p_new_input = p_demux->p_sys->pp_tracklist[i];
|
||||
if( p_new_input )
|
||||
{
|
||||
input_ItemAddSubItem( p_current_input, p_new_input );
|
||||
input_ItemAddSubItem( p_current_input, p_new_input, VLC_FALSE );
|
||||
}
|
||||
vlc_gc_decref( p_new_input );
|
||||
}
|
||||
|
||||
HANDLE_PLAY_AND_RELEASE;
|
||||
@ -712,11 +713,11 @@ static vlc_bool_t parse_extension_node COMPLEX_INTERFACE
|
||||
msg_Warn( p_demux, "<node> requires \"title\" attribute" );
|
||||
return VLC_FALSE;
|
||||
}
|
||||
p_new_input = input_ItemNewWithType( VLC_OBJECT( p_playlist ), "vlc:skip",
|
||||
p_new_input = input_ItemNewWithType( VLC_OBJECT(p_playlist), "vlc:nop",
|
||||
psz_title, 0, NULL, -1, ITEM_TYPE_DIRECTORY );
|
||||
if( p_new_input )
|
||||
{
|
||||
input_ItemAddSubItem( p_input_item, p_new_input );
|
||||
input_ItemAddSubItem( p_input_item, p_new_input, VLC_TRUE );
|
||||
p_input_item = p_new_input;
|
||||
}
|
||||
free( psz_title );
|
||||
@ -891,8 +892,9 @@ static vlc_bool_t parse_extitem_node COMPLEX_INTERFACE
|
||||
p_new_input = p_demux->p_sys->pp_tracklist[ i_href ];
|
||||
if( p_new_input )
|
||||
{
|
||||
input_ItemAddSubItem( p_input_item, p_new_input );
|
||||
input_ItemAddSubItem( p_input_item, p_new_input, VLC_FALSE );
|
||||
p_demux->p_sys->pp_tracklist[i_href] = NULL;
|
||||
vlc_gc_decref( p_new_input );
|
||||
}
|
||||
|
||||
/* kludge for #1293 - XTAG sends ENDELEM for self closing tag */
|
||||
|
@ -743,7 +743,7 @@ int __vlclua_playlist_add_internal( vlc_object_t *p_this, lua_State *L,
|
||||
|
||||
/* Append item to playlist */
|
||||
if( p_parent ) /* Add to node */
|
||||
input_ItemAddSubItem( p_parent, p_input );
|
||||
input_ItemAddSubItem( p_parent, p_input, VLC_FALSE );
|
||||
else if( b_play ) /* Play */
|
||||
playlist_AddInput( p_playlist, p_input,
|
||||
PLAYLIST_APPEND | PLAYLIST_GO,
|
||||
|
@ -45,10 +45,11 @@ static void input_item_subitem_added( const vlc_event_t * p_event,
|
||||
input_item_t * p_parent, * p_child;
|
||||
playlist_item_t * p_child_in_category;
|
||||
playlist_item_t * p_item_in_category;
|
||||
vlc_bool_t b_play;
|
||||
vlc_bool_t b_play, b_node;
|
||||
|
||||
p_parent = p_event->p_obj;
|
||||
p_child = p_event->u.input_item_subitem_added.p_new_child;
|
||||
b_node = p_event->u.input_item_subitem_added.b_node;
|
||||
|
||||
PL_LOCK;
|
||||
b_play = var_CreateGetBool( p_playlist, "playlist-autostart" );
|
||||
@ -64,7 +65,6 @@ static void input_item_subitem_added( const vlc_event_t * p_event,
|
||||
|
||||
if( !p_child_in_category )
|
||||
{
|
||||
/* Then, transform to a node if needed */
|
||||
p_item_in_category = playlist_ItemFindFromInputAndRoot(
|
||||
p_playlist, p_parent->i_id,
|
||||
p_playlist->p_root_category,
|
||||
@ -78,18 +78,24 @@ static void input_item_subitem_added( const vlc_event_t * p_event,
|
||||
|
||||
b_play = b_play && p_item_in_category == p_playlist->status.p_item;
|
||||
|
||||
/* If this item is already a node don't transform it */
|
||||
if( p_item_in_category->i_children == -1 )
|
||||
{
|
||||
p_item_in_category = playlist_ItemToNode( p_playlist,
|
||||
p_item_in_category, VLC_TRUE );
|
||||
p_item_in_category->p_input->i_type = ITEM_TYPE_PLAYLIST;
|
||||
}
|
||||
|
||||
/* If you want to use vlc_input_item_subitem_added event,
|
||||
* you must explicitely create nodes */
|
||||
assert( p_item_in_category->i_children != -1 );
|
||||
|
||||
playlist_BothAddInput( p_playlist, p_child, p_item_in_category,
|
||||
PLAYLIST_APPEND | PLAYLIST_SPREPARSE , PLAYLIST_END,
|
||||
NULL, NULL, VLC_TRUE );
|
||||
|
||||
if( b_node )
|
||||
{
|
||||
playlist_item_t *p_pl_item, *p_new_pl_item;
|
||||
p_pl_item = playlist_ItemFindFromInputAndRoot( p_playlist,
|
||||
p_child->i_id, p_playlist->p_root_category, VLC_FALSE );
|
||||
p_new_pl_item = playlist_ItemToNode( p_playlist, p_pl_item,
|
||||
VLC_TRUE );
|
||||
p_new_pl_item->p_input->i_type = ITEM_TYPE_NODE;
|
||||
}
|
||||
|
||||
if( b_play )
|
||||
{
|
||||
playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
|
||||
@ -412,7 +418,6 @@ playlist_item_t * playlist_NodeAddInput( playlist_t *p_playlist,
|
||||
/**
|
||||
* Transform an item to a node. Return the node in the category tree, or NULL
|
||||
* if not found there
|
||||
* This function must be entered without the playlist lock
|
||||
*/
|
||||
playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist,
|
||||
playlist_item_t *p_item,
|
||||
|
@ -96,6 +96,7 @@ static void input_item_subitem_added( const vlc_event_t * p_event,
|
||||
{
|
||||
playlist_t *p_playlist = user_data;
|
||||
input_item_t *p_item = p_event->u.input_item_subitem_added.p_new_child;
|
||||
vlc_bool_t b_node = p_event->u.input_item_subitem_added.b_node;
|
||||
|
||||
/* The media library input has one and only one option: "meta-file"
|
||||
* So we remove that unneeded option. */
|
||||
@ -107,6 +108,15 @@ static void input_item_subitem_added( const vlc_event_t * p_event,
|
||||
|
||||
playlist_AddInput( p_playlist, p_item, PLAYLIST_APPEND, PLAYLIST_END,
|
||||
VLC_FALSE, VLC_FALSE );
|
||||
|
||||
if( b_node )
|
||||
{
|
||||
playlist_item_t *p_pl_item, *p_new_pl_item;
|
||||
p_pl_item = playlist_ItemFindFromInputAndRoot( p_playlist, p_item->i_id,
|
||||
p_playlist->p_root_category, VLC_FALSE );
|
||||
p_new_pl_item = playlist_ItemToNode( p_playlist, p_pl_item, VLC_FALSE );
|
||||
p_new_pl_item->p_input->i_type = ITEM_TYPE_NODE;
|
||||
}
|
||||
}
|
||||
|
||||
int playlist_MLLoad( playlist_t *p_playlist )
|
||||
|
Loading…
Reference in New Issue
Block a user