diff --git a/include/vlc_events.h b/include/vlc_events.h index 28fa302c5b1ab08a437a6d0c3ec75896bf3413ee..ec80b17414a81b5d72f374e98694592abd8340d4 100644 --- a/include/vlc_events.h +++ b/include/vlc_events.h @@ -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 { diff --git a/include/vlc_input.h b/include/vlc_input.h index 1873deaf3f23dbc4bf9d09a0b5272dc2dd2fd7b1..314543f276d1062c92b2c4c5b2e16c9523dc71fe 100644 --- a/include/vlc_input.h +++ b/include/vlc_input.h @@ -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 ); } diff --git a/modules/demux/playlist/asx.c b/modules/demux/playlist/asx.c index 7ff18acd6aeba601c92eeaac7d2a3e030d7079c7..18740d571dc986295ba77e8a5564f6cfdf3b9a4f 100644 --- a/modules/demux/playlist/asx.c +++ b/modules/demux/playlist/asx.c @@ -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 ); } diff --git a/modules/demux/playlist/b4s.c b/modules/demux/playlist/b4s.c index 7f0fe7639492740f190628a19ac034fc278bce3c..c2782656b09b4720ee522924668c18255498dd42 100644 --- a/modules/demux/playlist/b4s.c +++ b/modules/demux/playlist/b4s.c @@ -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 ); diff --git a/modules/demux/playlist/dvb.c b/modules/demux/playlist/dvb.c index 31fefceb638549ea4ba54fdebad31d27f8288457..5e3edb5ce18242b44c5bba029886a316d5769a34 100644 --- a/modules/demux/playlist/dvb.c +++ b/modules/demux/playlist/dvb.c @@ -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 ); diff --git a/modules/demux/playlist/gvp.c b/modules/demux/playlist/gvp.c index f9883e12485065cfd2c1a20f6942af4fe2e20db5..567d8f8f28c3a82c10d2b9a38097b728254b3061 100644 --- a/modules/demux/playlist/gvp.c +++ b/modules/demux/playlist/gvp.c @@ -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 ); } diff --git a/modules/demux/playlist/ifo.c b/modules/demux/playlist/ifo.c index 0cd978fe0ce301c3bd5262c65426bb8f7326f28b..87058231355c96a5447213646d1cbbfe09cc44c9 100644 --- a/modules/demux/playlist/ifo.c +++ b/modules/demux/playlist/ifo.c @@ -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; diff --git a/modules/demux/playlist/itml.c b/modules/demux/playlist/itml.c index fab553db779e9f6c33e4fc4ad32baf0a08a03dc1..bedd5555d515561351b6de226065313198270714 100644 --- a/modules/demux/playlist/itml.c +++ b/modules/demux/playlist/itml.c @@ -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 ); diff --git a/modules/demux/playlist/m3u.c b/modules/demux/playlist/m3u.c index 109600d950906f5d2ef3313b75c79afe728b1a6e..41c7a63bcc035f308a15fb0af5b6807a9e069c0b 100644 --- a/modules/demux/playlist/m3u.c +++ b/modules/demux/playlist/m3u.c @@ -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 ); } diff --git a/modules/demux/playlist/pls.c b/modules/demux/playlist/pls.c index ef7d059f96346e2163b75f589397e354d119ea90..fdde1b70d2abcf0ce374f7a49cfe72cc70eab62d 100644 --- a/modules/demux/playlist/pls.c +++ b/modules/demux/playlist/pls.c @@ -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; diff --git a/modules/demux/playlist/podcast.c b/modules/demux/playlist/podcast.c index 30ef2f493590ab511ae28e935bcdf6e07bdfe14a..c4fabb5ad1dd85f6721e59c6de8018494f9f5856 100644 --- a/modules/demux/playlist/podcast.c +++ b/modules/demux/playlist/podcast.c @@ -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 ); diff --git a/modules/demux/playlist/qtl.c b/modules/demux/playlist/qtl.c index 4ad9f5cf4c806d9e4bc4745578d997a3b2dc64d7..2a2ef6f3cd90b325e36a6c9859984e81dd8f774a 100644 --- a/modules/demux/playlist/qtl.c +++ b/modules/demux/playlist/qtl.c @@ -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 ); } } diff --git a/modules/demux/playlist/sgimb.c b/modules/demux/playlist/sgimb.c index 8a9ddd6369d71f1702f64eac4395f4d980feafb0..d574db93b35682baa6a68645241a676eb67ddd8d 100644 --- a/modules/demux/playlist/sgimb.c +++ b/modules/demux/playlist/sgimb.c @@ -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 */ diff --git a/modules/demux/playlist/shoutcast.c b/modules/demux/playlist/shoutcast.c index 9059da269db7caad7fcaa55bbcef1ab761d42d2d..72457a22178d15fe4935746066a713eb67cc20de 100644 --- a/modules/demux/playlist/shoutcast.c +++ b/modules/demux/playlist/shoutcast.c @@ -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 ); diff --git a/modules/demux/playlist/xspf.c b/modules/demux/playlist/xspf.c index 7b3e74737897342c00dbe2c58c79a9ef2652da3c..131e6cfb4414c369b8b0b61de522bc6d61fe4241 100644 --- a/modules/demux/playlist/xspf.c +++ b/modules/demux/playlist/xspf.c @@ -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, " 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 */ diff --git a/modules/misc/lua/vlc.c b/modules/misc/lua/vlc.c index cd0fac03b024269463b1f1c7cb18677b1260f133..4a7880111c3ee41bdb49a535a15509fcb0e1a6d4 100644 --- a/modules/misc/lua/vlc.c +++ b/modules/misc/lua/vlc.c @@ -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, diff --git a/src/playlist/item.c b/src/playlist/item.c index 0a288d2eb3c539346df09ad981d7bdbf4d3184e0..b4787b1ea1a25028351aea318c1409025715a74e 100644 --- a/src/playlist/item.c +++ b/src/playlist/item.c @@ -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, diff --git a/src/playlist/loadsave.c b/src/playlist/loadsave.c index bdd6b377def09f454f797eab8b6226876c4c69e9..14bb545610ae4940fd180706f62f91064218b60c 100644 --- a/src/playlist/loadsave.c +++ b/src/playlist/loadsave.c @@ -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 )