fix #1410.
authorRafaël Carré <funman@videolan.org>
Sun, 30 Dec 2007 18:24:10 +0000 (18:24 +0000)
committerRafaël Carré <funman@videolan.org>
Sun, 30 Dec 2007 18:24:10 +0000 (18:24 +0000)
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).

18 files changed:
include/vlc_events.h
include/vlc_input.h
modules/demux/playlist/asx.c
modules/demux/playlist/b4s.c
modules/demux/playlist/dvb.c
modules/demux/playlist/gvp.c
modules/demux/playlist/ifo.c
modules/demux/playlist/itml.c
modules/demux/playlist/m3u.c
modules/demux/playlist/pls.c
modules/demux/playlist/podcast.c
modules/demux/playlist/qtl.c
modules/demux/playlist/sgimb.c
modules/demux/playlist/shoutcast.c
modules/demux/playlist/xspf.c
modules/misc/lua/vlc.c
src/playlist/item.c
src/playlist/loadsave.c

index 28fa302..ec80b17 100644 (file)
@@ -139,6 +139,7 @@ typedef struct vlc_event_t
         struct vlc_input_item_subitem_added
         {
             input_item_t * p_new_child;
         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
         {
         } input_item_subitem_added;
         struct vlc_input_item_duration_changed
         {
index 1873dea..314543f 100644 (file)
@@ -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,
  * 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;
 
 {
     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;
     /* 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 );
 }
 
     vlc_event_send( &p_parent->event_manager, &event );
 }
 
index 7ff18ac..18740d5 100644 (file)
@@ -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 );
                             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;
                             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 );
                     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 );
                 }
 
                     vlc_gc_decref( p_entry );
                 }
 
index 7f0fe76..c278265 100644 (file)
@@ -265,7 +265,7 @@ static int Demux( demux_t *p_demux )
                     if( psz_bitrate )
                         msg_Err( p_playlist, "Unsupported meta bitrate" );
 
                     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 );
                     vlc_gc_decref( p_input );
                     FREENULL( psz_name );
                     FREENULL( psz_mrl );
index 31fefce..5e3edb5 100644 (file)
@@ -118,7 +118,7 @@ static int Demux( demux_t *p_demux )
             EnsureUTF8( ppsz_options[i] );
             input_ItemAddOption( p_input, ppsz_options[i] );
         }
             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 );
         vlc_gc_decref( p_input );
         while( i_options-- ) free( ppsz_options[i_options] );
         if( ppsz_options ) free( ppsz_options );
index f9883e1..567d8f8 100644 (file)
@@ -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 );
         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 );
     }
 
         vlc_gc_decref( p_input );
     }
 
index 0cd978f..8705823 100644 (file)
@@ -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 );
     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;
     vlc_gc_decref( p_input );
 
     HANDLE_PLAY_AND_RELEASE;
index fab553d..bedd555 100644 (file)
@@ -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 );
 
             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 );
 
             /* add meta info */
             add_meta( p_new_input, p_track );
index 109600d..41c7a63 100644 (file)
@@ -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 );
             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 );
         }
             vlc_gc_decref( p_input );
             free( psz_mrl );
         }
index ef7d059..fdde1b7 100644 (file)
@@ -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 );
                 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
                 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 );
     {
         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;
         vlc_gc_decref( p_input );
         free( psz_mrl_orig );
         psz_mrl = NULL;
index 30ef2f4..c4fabb5 100644 (file)
@@ -288,7 +288,7 @@ static int Demux( demux_t *p_demux )
                                                 "%s bytes",
                                                 psz_item_size );
                     }
                                                 "%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 );
                     vlc_gc_decref( p_input );
                     FREENULL( psz_item_name );
                     FREENULL( psz_item_mrl );
index 4ad9f5c..2a2ef6f 100644 (file)
@@ -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 );
                     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 );
         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 );
         }
     }
             vlc_gc_decref( p_input );
         }
     }
index 8a9ddd6..d574db9 100644 (file)
@@ -404,7 +404,7 @@ static int Demux ( demux_t *p_demux )
         free( psz_option );
     }
 
         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 */
     vlc_gc_decref( p_child );
     HANDLE_PLAY_AND_RELEASE
     return 0; /* Needed for correct operation of go back */
index 9059da2..72457a2 100644 (file)
@@ -235,7 +235,7 @@ static int DemuxGenre( demux_t *p_demux )
                     input_ItemCopyOptions( p_sys->p_current_input,
                                                 p_input );
                     free( psz_mrl );
                     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 );
                 }
                     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_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 );
                     vlc_gc_decref( p_input );
                     FREENULL( psz_name );
                     FREENULL( psz_mt );
index 7b3e747..131e6cf 100644 (file)
@@ -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_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;
     }
 
     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;
         }
             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 )
         {
                                 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 );
             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 )
     {
     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;
         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 */
     }
 
     /* kludge for #1293 - XTAG sends ENDELEM for self closing tag */
index cd0fac0..4a78801 100644 (file)
@@ -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 */
 
                     /* 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,
                     else if( b_play ) /* Play */
                         playlist_AddInput( p_playlist, p_input,
                                            PLAYLIST_APPEND | PLAYLIST_GO,
index 0a288d2..b4787b1 100644 (file)
@@ -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;
     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;
 
     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" );
 
     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 )
     {
 
     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,
         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;
 
 
         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 );
 
         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,
         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
 /**
  * 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,
  */
 playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist,
                                       playlist_item_t *p_item,
index bdd6b37..14bb545 100644 (file)
@@ -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;
 {
     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. */
 
     /* 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 );
 
     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 )
 }
 
 int playlist_MLLoad( playlist_t *p_playlist )