]> git.sesse.net Git - vlc/blobdiff - modules/demux/playlist/m3u.c
Fix deletion of items when changing them to nodes
[vlc] / modules / demux / playlist / m3u.c
index 6848c81cf49d76846771d9a3dba882474ae43bf7..01233ad74fe423e3b9daeb59ec34eda021196d60 100644 (file)
@@ -4,8 +4,8 @@
  * Copyright (C) 2004 the VideoLAN team
  * $Id$
  *
- * Authors: Clément Stenac <zorglub@videolan.org>
- *          Sigmund Augdal <sigmunau@idi.ntnu.no>
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *          Sigmund Augdal Helberg <dnumgis@videolan.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
@@ -30,6 +30,7 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 #include <vlc/intf.h>
+#include "charset.h"
 
 #include <errno.h>                                                 /* ENOMEM */
 #include "playlist.h"
@@ -52,42 +53,21 @@ static void parseEXTINF( char *psz_string, char **ppsz_artist, char **ppsz_name,
 int E_(Import_M3U)( vlc_object_t *p_this )
 {
     demux_t *p_demux = (demux_t *)p_this;
-
     uint8_t *p_peek;
-    char    *psz_ext;
-
-    if( stream_Peek( p_demux->s , &p_peek, 7 ) < 7 )
-    {
-        return VLC_EGENERIC;
-    }
-    psz_ext = strrchr ( p_demux->psz_path, '.' );
+    CHECK_PEEK( p_peek, 8 );
 
-    if( !strncmp( (char *)p_peek, "#EXTM3U", 7 ) )
-    {
-        ;
-    }
-    else if( ( psz_ext && !strcasecmp( psz_ext, ".m3u") ) ||
-             ( psz_ext && !strcasecmp( psz_ext, ".ram") ) ||
-             ( psz_ext && !strcasecmp( psz_ext, ".rm") ) ||
-             /* A .ram file can contain a single rtsp link */
-             ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "m3u") ) )
+    if( POKE( p_peek, "#EXTM3U", 7 ) || POKE( p_peek, "RTSPtext", 8 ) ||
+        isExtension( p_demux, ".m3u" ) || isExtension( p_demux, ".vlc" ) ||
+        /* A .ram file can contain a single rtsp link */
+        isExtension( p_demux, ".ram" ) || isExtension( p_demux, ".rm" ) ||
+        isDemux( p_demux,  "m3u" ) )
     {
         ;
     }
     else
-    {
         return VLC_EGENERIC;
-    }
-    msg_Dbg( p_demux, "found valid M3U playlist file");
 
-    p_demux->pf_control = Control;
-    p_demux->pf_demux = Demux;
-    p_demux->p_sys = malloc( sizeof(demux_sys_t) );
-    if( p_demux->p_sys == NULL )
-    {
-        msg_Err( p_demux, "Out of memory" );
-        return VLC_ENOMEM;
-    }
+    STANDARD_DEMUX_INIT_MSG( "found valid M3U playlist" );
     p_demux->p_sys->psz_prefix = E_(FindPrefix)( p_demux );
 
     return VLC_SUCCESS;
@@ -106,34 +86,16 @@ void E_(Close_M3U)( vlc_object_t *p_this )
 
 static int Demux( demux_t *p_demux )
 {
-    playlist_t *p_playlist;
     char       *psz_line;
-
     char       *psz_name = NULL;
     char       *psz_artist = NULL;
     int        i_parsed_duration = 0;
     mtime_t    i_duration = -1;
-    char       **ppsz_options = NULL;
+    const char**ppsz_options = NULL;
     int        i_options = 0, i;
-
-    playlist_item_t *p_item, *p_current;
-
-    vlc_bool_t b_play;
-
     vlc_bool_t b_cleanup = VLC_FALSE;
 
-    p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
-                                                 FIND_PARENT );
-    if( !p_playlist )
-    {
-        msg_Err( p_demux, "can't find playlist" );
-        return -1;
-    }
-
-    b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
-
-    playlist_ItemToNode( p_playlist, p_current );
-    p_current->input.i_type = ITEM_TYPE_PLAYLIST;
+    INIT_PLAYLIST_STUFF;
 
     psz_line = stream_ReadLine( p_demux->s );
     while( psz_line )
@@ -171,7 +133,7 @@ static int Demux( demux_t *p_demux )
                                    sizeof("EXTVLCOPT:") -1 ) )
             {
                 /* VLC Option */
-                char *psz_option;
+                const char *psz_option;
                 psz_parse += sizeof("EXTVLCOPT:") -1;
                 if( !*psz_parse ) goto error;
 
@@ -181,6 +143,10 @@ static int Demux( demux_t *p_demux )
                                  psz_option );
             }
         }
+        else if( !strncasecmp( psz_parse, "RTSPtext", sizeof("RTSPtext") -1 ) )
+        {
+            ;/* special case to handle QuickTime RTSPtext redirect files */
+        }
         else if( *psz_parse )
         {
             char *psz_mrl;
@@ -198,28 +164,18 @@ static int Demux( demux_t *p_demux )
             EnsureUTF8( psz_name );
             EnsureUTF8( psz_mrl );
 
-            p_item = playlist_ItemNew( p_playlist, psz_mrl, psz_name );
             for( i = 0; i< i_options; i++ )
-            {
-                EnsureUTF8( ppsz_options[i] );
-                playlist_ItemAddOption( p_item, ppsz_options[i] );
-            }
-            p_item->input.i_duration = i_duration;
-            if ( psz_artist && *psz_artist )
-                vlc_input_item_AddInfo( &p_item->input, _("Meta-information"),
-                                        _("Artist"), "%s", psz_artist );
-            playlist_NodeAddItem( p_playlist, p_item,
-                                  p_current->pp_parents[0]->i_view,
-                                  p_current, PLAYLIST_APPEND,
-                                  PLAYLIST_END );
-
-            /* We need to declare the parents of the node as the
-             *                  * same of the parent's ones */
-            playlist_CopyParents( p_current, p_item );
-
-            vlc_input_item_CopyOptions( &p_current->input,
-                                        &p_item->input );
+                EnsureUTF8( (char*)ppsz_options[i] );
 
+            p_input = input_ItemNewExt( p_playlist, psz_mrl, psz_name,
+                                        i_options, ppsz_options, i_duration );
+            if ( psz_artist && *psz_artist )
+                vlc_input_item_AddInfo( p_input, _(VLC_META_INFO_CAT),
+                                        _(VLC_META_ARTIST), "%s", psz_artist );
+            msg_Dbg( p_demux, "Adding %s\n", p_input->psz_uri );
+            playlist_AddWhereverNeeded( p_playlist, p_input, p_current,
+                 p_item_in_category, (i_parent_id > 0 )? VLC_TRUE : VLC_FALSE,
+                 PLAYLIST_APPEND );
             free( psz_mrl );
         }
 
@@ -233,7 +189,7 @@ static int Demux( demux_t *p_demux )
         if( b_cleanup )
         {
             /* Cleanup state */
-            while( i_options-- ) free( ppsz_options[i_options] );
+            while( i_options-- ) free( (char*)ppsz_options[i_options] );
             if( ppsz_options ) free( ppsz_options );
             ppsz_options = NULL; i_options = 0;
             if( psz_name ) free( psz_name );
@@ -246,18 +202,7 @@ static int Demux( demux_t *p_demux )
             b_cleanup = VLC_FALSE;
         }
     }
-
-    /* Go back and play the playlist */
-    if( b_play && p_playlist->status.p_item &&
-        p_playlist->status.p_item->i_children > 0 )
-    {
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                          p_playlist->status.i_view,
-                          p_playlist->status.p_item,
-                          p_playlist->status.p_item->pp_children[0] );
-    }
-
-    vlc_object_release( p_playlist );
+    HANDLE_PLAY_AND_RELEASE;
     return VLC_SUCCESS;
 }
 
@@ -266,7 +211,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     return VLC_EGENERIC;
 }
 
-static void parseEXTINF(char *psz_string, char **ppsz_artist, 
+static void parseEXTINF(char *psz_string, char **ppsz_artist,
                         char **ppsz_name, int *pi_duration)
 {
     char *end = NULL;
@@ -305,7 +250,7 @@ static void parseEXTINF(char *psz_string, char **ppsz_artist,
         *ppsz_artist = psz_string;
         *ppsz_name = psz_item + 3;          /* points directly after ' - ' */
         return;
-    } 
+    }
 
     /* reaching this point means: 0.8.1- with artist or something without artist */
     if ( *psz_string == ',' )
@@ -314,7 +259,7 @@ static void parseEXTINF(char *psz_string, char **ppsz_artist,
         psz_string++;
         *ppsz_name = psz_string;
         return;
-    } 
+    }
 
     psz_item = psz_string;
     psz_string = strchr( psz_string, ',' );