]> git.sesse.net Git - vlc/commitdiff
* src/playlist/playlist.c: when autodeleting an item, we don't need to skip
authorGildas Bazin <gbazin@videolan.org>
Wed, 13 Nov 2002 11:09:56 +0000 (11:09 +0000)
committerGildas Bazin <gbazin@videolan.org>
Wed, 13 Nov 2002 11:09:56 +0000 (11:09 +0000)
   to the next one.
* modules/demux/m3u.c: added .asx support and changed the autodetection of
   file type to just probe the file extension.

modules/demux/m3u.c
src/playlist/playlist.c

index 256361b88b13001992582be7f7a1d07bca23a4a7..29158f3aa3701fc868c76a89497432923f092bb0 100644 (file)
@@ -1,10 +1,11 @@
 /*****************************************************************************
- * m3u.c: a meta demux to parse m3u playlists
+ * m3u.c: a meta demux to parse m3u and asx playlists
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: m3u.c,v 1.1 2002/11/12 22:18:54 sigmunau Exp $
+ * $Id: m3u.c,v 1.2 2002/11/13 11:09:56 gbazin Exp $
  *
  * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no>
+ *          Gildas Bazin <gbazin@netcourrier.com>
  *
  * 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
 #include <sys/types.h>
 
 /*****************************************************************************
- * Constants
+ * Constants and structures
  *****************************************************************************/
+#define MAX_LINE 1024
+
+#define TYPE_M3U 1
+#define TYPE_ASX 2
+
+struct demux_sys_t
+{
+    int i_type;                                   /* playlist type (m3u/asx) */
+};
 
 /*****************************************************************************
  * Local prototypes
@@ -47,8 +57,8 @@ static int  Demux ( input_thread_t * );
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-vlc_module_begin();                                      
-    set_description( "m3u metademux" );                       
+vlc_module_begin();
+    set_description( "m3u/asx metademux" );
     set_capability( "demux", 10 );
     set_callbacks( Init, NULL );
 vlc_module_end();
@@ -58,11 +68,10 @@ vlc_module_end();
  *****************************************************************************/
 static int Init( vlc_object_t * p_this )
 {
-    input_thread_t *    p_input = (input_thread_t *)p_this;
-    byte_t *            p_peek;
-    int                 i_size, i_pos;
-    playlist_t *        p_playlist;
-    int                 b_first = 1;
+    input_thread_t *p_input = (input_thread_t *)p_this;
+    char           *psz_ext;
+    demux_sys_t    *p_m3u;
+    int            i_type = 0;
 
     /* Initialize access plug-in structures. */
     if( p_input->i_mtu == 0 )
@@ -74,67 +83,148 @@ static int Init( vlc_object_t * p_this )
     p_input->pf_demux = Demux;
     p_input->pf_rewind = NULL;
 
-    /* Have a peep at the show. */
-    if( input_Peek( p_input, &p_peek, 7 ) < 7 )
+    /* Check for m3u/asx file extension */
+    psz_ext = strrchr ( p_input->psz_name, '.' );
+    if( !strcasecmp( psz_ext, ".m3u") )
     {
-        /* Stream shorter than 7 bytes... */
-        msg_Err( p_input, "cannot peek()" );
-        return( -1 );
+        i_type = TYPE_M3U;
     }
-    
-#define MAX_LINE 1024
-    if( !strncmp( p_peek, "#EXTM3U", 7)
-        || ( p_input->psz_demux && !strncmp(p_input->psz_demux, "m3u", 3) ) )
+    else if( !strcasecmp( psz_ext, ".asx") )
+    {
+        i_type = TYPE_ASX;
+    }
+
+    if( !i_type )
+        return -1;
+
+    /* Allocate p_m3u */
+    if( !( p_m3u = malloc( sizeof( demux_sys_t ) ) ) )
     {
-        p_playlist =
-            (playlist_t *) vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
+        msg_Err( p_input, "out of memory" );
+        return -1;
+    }
+    p_input->p_demux_data = p_m3u;
+
+    p_m3u->i_type = i_type;
+
+    return 0;
+}
+
+static int Demux ( input_thread_t *p_input )
+{
+    data_packet_t *p_data;
+    char          *p_buf, psz_line[MAX_LINE], *psz_bol, eol_tok;
+    int           i_size, i_bufpos, i_linepos = 0;
+    playlist_t    *p_playlist;
+    vlc_bool_t    b_discard = VLC_FALSE;
+
+    demux_sys_t   *p_m3u = (demux_sys_t *)p_input->p_demux_data;
+
+    p_playlist = (playlist_t *) vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
                                                  FIND_ANYWHERE );
-        p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
-        i_size = input_Peek( p_input, &p_peek, MAX_LINE );
-        while ( i_size > 0 ) {
-            i_pos = 0;
-            if ( *p_peek == '#' ) {/*line is comment or extended info,
-                                     ignored for now */
-                while ( *p_peek != '\n' && i_pos < i_size )
-                {
-                    
-                    i_pos++;
-                    p_peek++;
-                }
-                i_pos++;
-            }
-            else
+    if( !p_playlist )
+    {
+        msg_Err( p_input, "can't find playlist" );
+        return -1;
+    }
+
+    p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
+
+    /* Depending on wether we are dealing with an m3u/asf file, the end of
+     * line token will be different */
+    if( p_m3u->i_type == TYPE_ASX )
+        eol_tok = '>';
+    else  
+        eol_tok = '\n';
+
+    while( ( i_size = input_SplitBuffer( p_input, &p_data, MAX_LINE ) ) > 0 )
+    {
+        i_bufpos = 0; p_buf = p_data->p_payload_start;
+
+        while( i_size )
+        {
+            /* Build a line < MAX_LINE */
+            while( p_buf[i_bufpos] != eol_tok && i_size )
             {
-                byte_t *p_start = p_peek;
-                char *psz_entry;
-                while ( *p_peek != '\n' )
+                if( i_linepos == MAX_LINE || b_discard == VLC_TRUE )
                 {
-                    i_pos++;
-                    p_peek++;
+                    /* line is bigger than MAX_LINE, discard it */
+                    i_linepos = 0;
+                    b_discard = VLC_TRUE;
                 }
-                if ( i_pos ) /*ignore empty lines to */
+                else
                 {
-                    psz_entry = malloc( i_pos + 1 );
-                    memcpy( psz_entry, p_start, i_pos );
-                    psz_entry[i_pos] = '\0';
-                    playlist_Add( p_playlist, psz_entry,
-                                  PLAYLIST_APPEND ,
-                                  PLAYLIST_END );
-                    b_first = 0;
-                    free( psz_entry );
+                    psz_line[i_linepos] = p_buf[i_bufpos];
+                    i_linepos++;
                 }
-                i_pos++;
+
+                i_size--; i_bufpos++;
+            }
+
+            /* Check if we need more data */
+            if( !i_size ) continue;
+
+            i_size--; i_bufpos++;
+            b_discard = VLC_FALSE;
+
+            /* Check for empty line */
+            if( !i_linepos ) continue;
+
+            psz_line[i_linepos] = '\0';
+            psz_bol = psz_line;
+            i_linepos = 0;
+
+            /* Remove unnecessary tabs or spaces at the beginning of line */
+            while( *psz_bol == ' ' || *psz_bol == '\t' ||
+                   *psz_bol == '\n' || *psz_bol == '\r' )
+                psz_bol++;
+
+            if( p_m3u->i_type == TYPE_M3U )
+            {
+                /* Check for comment line */
+                if( *psz_bol == '#' )
+                    /*line is comment or extended info, ignored for now */
+                    continue;
+            }
+            else
+            {
+                /* We are dealing with ASX files.
+                 * We are looking for href html markups that begins with
+                 * "mms://" */
+                char *psz_eol;
+
+                while( *psz_bol && strncasecmp( psz_bol, "href",
+                                                sizeof("href") - 1 )  )
+                    psz_bol++;
+
+                if( !*psz_bol ) continue;
+
+                while( *psz_bol && strncasecmp( psz_bol, "mms://",
+                                               sizeof("mms://") - 1 )  )
+                    psz_bol++;
+
+                if( !*psz_bol ) continue;
+
+                psz_eol = strchr( psz_bol, '"');
+                if( !psz_eol )
+                  continue;
+
+                *psz_eol = '\0';
             }
-            p_input->p_current_data += i_pos;
-            i_size = input_Peek( p_input, &p_peek, MAX_LINE );
+
+            /*
+             * From now on, we know we've got a meaningful line
+             */
+            playlist_Add( p_playlist, psz_bol,
+                          PLAYLIST_APPEND, PLAYLIST_END );
+
+            continue;
         }
-        p_input->b_eof = VLC_TRUE;
-        return( 0 );
+
+        input_DeletePacket( p_input->p_method_data, p_data );
     }
-    return( -1 );
-}
 
-static int Demux ( input_thread_t *p_intput )
-{
+    vlc_object_release( p_playlist );
+
     return 0;
 }
index 6648c1aac3346caad60dd9b61e3eceec6924b137..eb23e387862b727166d5f1dddb11ff1b4dae1288 100644 (file)
@@ -2,7 +2,7 @@
  * playlist.c : Playlist management functions
  *****************************************************************************
  * Copyright (C) 1999-2001 VideoLAN
- * $Id: playlist.c,v 1.18 2002/11/12 21:20:36 gbazin Exp $
+ * $Id: playlist.c,v 1.19 2002/11/13 11:09:56 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *
@@ -307,7 +307,14 @@ static void RunThread ( playlist_t *p_playlist )
 
                 /* Check for autodeletion */
                 if( p_playlist->pp_items[p_playlist->i_index]->b_autodeletion )
+                {
                     playlist_Delete( p_playlist, p_playlist->i_index );
+                }
+                else
+                {
+                    /* Select the next playlist item */
+                    SkipItem( p_playlist, 1 );
+                }
 
                 /* Destroy input */
                 input_DestroyThread( p_input );
@@ -323,9 +330,6 @@ static void RunThread ( playlist_t *p_playlist )
             else if( p_playlist->p_input->b_error
                       || p_playlist->p_input->b_eof )
             {
-                /* Select the next playlist item */
-                SkipItem( p_playlist, 1 );
-
                 /* Release the playlist lock, because we may get stuck
                  * in input_StopThread() for some time. */
                 vlc_mutex_unlock( &p_playlist->object_lock );