]> git.sesse.net Git - vlc/blobdiff - modules/demux/playlist/asx.c
Force to specify options flags in input_item_New*.
[vlc] / modules / demux / playlist / asx.c
index e7f6ea213980e9d7704cb521c2ad04c3339920c4..030c3410cd6d40b848021df56d32bd323b5b1d7f 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#define _GNU_SOURCE
-#include <stdlib.h>                                      /* malloc(), free() */
-#include <ctype.h>                                              /* isspace() */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
 
-#include <vlc/vlc.h>
-#include <vlc/input.h>
+#include <vlc_common.h>
+#include <vlc_demux.h>
 
-#include <errno.h>                                                 /* ENOMEM */
-#include "charset.h"
+#include <ctype.h>
+#include <vlc_charset.h>
 #include "playlist.h"
 #include "vlc_meta.h"
 
@@ -44,7 +44,8 @@ struct demux_sys_t
     char    *psz_prefix;
     char    *psz_data;
     int64_t i_data_len;
-    vlc_bool_t b_utf8;
+    bool b_utf8;
+    bool b_skip_ads;
 };
 
 /*****************************************************************************
@@ -60,7 +61,7 @@ static int StoreString( demux_t *p_demux, char **ppsz_string,
     demux_sys_t *p_sys = p_demux->p_sys;
     unsigned len = psz_source_end - psz_source_start;
 
-    if( *ppsz_string ) free( *ppsz_string );
+    free( *ppsz_string );
 
     char *buf = *ppsz_string = malloc ((len * (1 + !p_sys->b_utf8)) + 1);
     if (buf == NULL)
@@ -93,23 +94,109 @@ static int StoreString( demux_t *p_demux, char **ppsz_string,
     return VLC_SUCCESS;
 }
 
+static char *SkipBlanks(char *s, size_t i_strlen )
+{
+    while( i_strlen > 0 ) {
+        switch( *s )
+        {
+            case ' ':
+            case '\t':
+            case '\r':
+            case '\n':
+                --i_strlen;
+                ++s;
+                break;
+            default:
+                i_strlen = 0;
+        }
+    }
+    return s;
+}
+
+static int ParseTime(char *s, size_t i_strlen)
+{
+    // need to parse hour:minutes:sec.fraction string
+    int result = 0;
+    int val;
+    const char *end = s + i_strlen;
+    // skip leading spaces if any
+    s = SkipBlanks(s, i_strlen);
+
+    val = 0;
+    while( (s < end) && isdigit(*s) )
+    {
+        int newval = val*10 + (*s - '0');
+        if( newval < val )
+        {
+            // overflow
+            val = 0;
+            break;
+        }
+        val = newval;
+        ++s;
+    }
+    result = val;
+    s = SkipBlanks(s, end-s);
+    if( *s == ':' )
+    {
+        ++s;
+        s = SkipBlanks(s, end-s);
+        result = result * 60;
+        val = 0;
+        while( (s < end) && isdigit(*s) )
+        {
+            int newval = val*10 + (*s - '0');
+            if( newval < val )
+            {
+                // overflow
+                val = 0;
+                break;
+            }
+            val = newval;
+            ++s;
+        }
+        result += val;
+        s = SkipBlanks(s, end-s);
+        if( *s == ':' )
+        {
+            ++s;
+            s = SkipBlanks(s, end-s);
+            result = result * 60;
+            val = 0;
+            while( (s < end) && isdigit(*s) )
+            {
+                int newval = val*10 + (*s - '0');
+                if( newval < val )
+                {
+                    // overflow
+                    val = 0;
+                    break;
+                }
+                val = newval;
+                ++s;
+            }
+            result += val;
+            // TODO: one day, we may need to parse fraction for sub-second resolution
+        }
+    }
+    return result;
+}
+
 /*****************************************************************************
  * Import_ASX: main import function
  *****************************************************************************/
-int E_(Import_ASX)( vlc_object_t *p_this )
+int Import_ASX( vlc_object_t *p_this )
 {
     demux_t *p_demux = (demux_t *)p_this;
-    uint8_t *p_peek, *p_peek_stop;
+    const uint8_t *p_peek;
     CHECK_PEEK( p_peek, 10 );
 
-    p_peek_stop = p_peek+6;
+    // skip over possible leading empty lines and empty spaces
+    p_peek = (uint8_t *)SkipBlanks((char *)p_peek, 6);
 
-    // skip over possible leading empty lines
-    while( (p_peek < p_peek_stop) && (*p_peek == '\n' || *p_peek == '\r')) ++p_peek;
-
-    if( POKE( p_peek, "<asx", 4 ) || isExtension( p_demux, ".asx" ) ||
-        isExtension( p_demux, ".wax" ) || isExtension( p_demux, ".wvx" ) ||
-        isDemux( p_demux, "asx-open" ) )
+    if( POKE( p_peek, "<asx", 4 ) || demux_IsPathExtension( p_demux, ".asx" ) ||
+        demux_IsPathExtension( p_demux, ".wax" ) || demux_IsPathExtension( p_demux, ".wvx" ) ||
+        demux_IsForced( p_demux, "asx-open" ) )
     {
         ;
     }
@@ -117,10 +204,11 @@ int E_(Import_ASX)( vlc_object_t *p_this )
         return VLC_EGENERIC;
 
     STANDARD_DEMUX_INIT_MSG( "found valid ASX playlist" );
-    p_demux->p_sys->psz_prefix = E_(FindPrefix)( p_demux );
+    p_demux->p_sys->psz_prefix = FindPrefix( p_demux );
     p_demux->p_sys->psz_data = NULL;
     p_demux->p_sys->i_data_len = -1;
-    p_demux->p_sys->b_utf8 = VLC_FALSE;
+    p_demux->p_sys->b_utf8 = false;
+    p_demux->p_sys->b_skip_ads = config_GetInt( p_demux, "playlist-skip-ads" );
 
     return VLC_SUCCESS;
 }
@@ -128,13 +216,13 @@ int E_(Import_ASX)( vlc_object_t *p_this )
 /*****************************************************************************
  * Deactivate: frees unused data
  *****************************************************************************/
-void E_(Close_ASX)( vlc_object_t *p_this )
+void Close_ASX( vlc_object_t *p_this )
 {
     demux_t *p_demux = (demux_t *)p_this;
     demux_sys_t *p_sys = p_demux->p_sys;
 
-    if( p_sys->psz_prefix ) free( p_sys->psz_prefix );
-    if( p_sys->psz_data ) free( p_sys->psz_data );
+    free( p_sys->psz_prefix );
+    free( p_sys->psz_data );
     free( p_sys );
 }
 
@@ -143,8 +231,7 @@ static int Demux( demux_t *p_demux )
     demux_sys_t *p_sys = p_demux->p_sys;
     char        *psz_parse = NULL;
     char        *psz_backup = NULL;
-    vlc_bool_t  b_entry = VLC_FALSE;
-    input_item_t *p_input;
+    bool  b_entry = false;
     INIT_PLAYLIST_STUFF;
 
     /* init txt */
@@ -153,21 +240,21 @@ static int Demux( demux_t *p_demux )
         int64_t i_pos = 0;
         p_sys->i_data_len = stream_Size( p_demux->s ) +1; /* This is a cheat to prevent unnecessary realloc */
         if( p_sys->i_data_len <= 0 && p_sys->i_data_len < 16384 ) p_sys->i_data_len = 1024;
-        p_sys->psz_data = malloc( p_sys->i_data_len * sizeof(char) +1);
-        
+        p_sys->psz_data = malloc( p_sys->i_data_len +1);
+
         /* load the complete file */
         for( ;; )
         {
             int i_read = stream_Read( p_demux->s, &p_sys->psz_data[i_pos], p_sys->i_data_len - i_pos );
-            p_sys->psz_data[i_read] = '\0';
-           
+            p_sys->psz_data[i_pos + i_read] = '\0';
+
             if( i_read < p_sys->i_data_len - i_pos ) break; /* Done */
-            
+
             i_pos += i_read;
             p_sys->i_data_len += 1024;
             p_sys->psz_data = realloc( p_sys->psz_data, p_sys->i_data_len * sizeof( char * ) +1 );
         }
-        if( p_sys->i_data_len <= 0 ) return VLC_EGENERIC;
+        if( p_sys->i_data_len <= 0 ) return -1;
     }
 
     psz_parse = p_sys->psz_data;
@@ -184,7 +271,7 @@ static int Demux( demux_t *p_demux )
         char *psz_copyright_asx = NULL;
         char *psz_moreinfo_asx = NULL;
         char *psz_abstract_asx = NULL;
-        
+
         char *psz_base_entry = NULL;
         char *psz_title_entry = NULL;
         char *psz_artist_entry = NULL;
@@ -192,10 +279,15 @@ static int Demux( demux_t *p_demux )
         char *psz_moreinfo_entry = NULL;
         char *psz_abstract_entry = NULL;
         int i_entry_count = 0;
-    
+        bool b_skip_entry = false;
+
+        char *psz_href = NULL;
+        int i_starttime = 0;
+        int i_duration = 0;
+
         psz_parse = strcasestr( psz_parse, ">" );
 
-        while( ( psz_parse = strcasestr( psz_parse, "<" ) ) && psz_parse && *psz_parse )
+        while( psz_parse && ( psz_parse = strcasestr( psz_parse, "<" ) ) )
         {
             if( !strncasecmp( psz_parse, "<!--", 4 ) )
             {
@@ -206,8 +298,8 @@ static int Demux( demux_t *p_demux )
             }
             else if( !strncasecmp( psz_parse, "<PARAM ", 7 ) )
             {
-                vlc_bool_t b_encoding_flag = VLC_FALSE;
-                psz_parse+=7;
+                bool b_encoding_flag = false;
+                psz_parse = SkipBlanks(psz_parse+7, (unsigned)-1);
                 if( !strncasecmp( psz_parse, "name", 4 ) )
                 {
                     if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
@@ -218,7 +310,7 @@ static int Demux( demux_t *p_demux )
                             i_strlen = psz_parse-psz_backup;
                             if( i_strlen < 1 ) continue;
                             msg_Dbg( p_demux, "param name strlen: %d", i_strlen);
-                            psz_string = malloc( i_strlen *sizeof( char ) +1);
+                            psz_string = malloc( i_strlen 1);
                             memcpy( psz_string, psz_backup, i_strlen );
                             psz_string[i_strlen] = '\0';
                             msg_Dbg( p_demux, "param name: %s", psz_string);
@@ -240,11 +332,11 @@ static int Demux( demux_t *p_demux )
                             i_strlen = psz_parse-psz_backup;
                             if( i_strlen < 1 ) continue;
                             msg_Dbg( p_demux, "param value strlen: %d", i_strlen);
-                            psz_string = malloc( i_strlen *sizeof( char ) +1);
+                            psz_string = malloc( i_strlen +1);
                             memcpy( psz_string, psz_backup, i_strlen );
                             psz_string[i_strlen] = '\0';
                             msg_Dbg( p_demux, "param value: %s", psz_string);
-                            if( b_encoding_flag && !strcasecmp( psz_string, "utf-8" ) ) p_sys->b_utf8 = VLC_TRUE;
+                            if( b_encoding_flag && !strcasecmp( psz_string, "utf-8" ) ) p_sys->b_utf8 = true;
                             free( psz_string );
                         }
                         else continue;
@@ -273,7 +365,7 @@ static int Demux( demux_t *p_demux )
             }
             else if( !strncasecmp( psz_parse, "<BASE ", 6 ) )
             {
-                psz_parse+=6;
+                psz_parse = SkipBlanks(psz_parse+6, (unsigned)-1);
                 if( !strncasecmp( psz_parse, "HREF", 4 ) )
                 {
                     if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
@@ -323,7 +415,7 @@ static int Demux( demux_t *p_demux )
             }
             else if( !strncasecmp( psz_parse, "<MoreInfo ", 10 ) )
             {
-                psz_parse+=10;
+                psz_parse = SkipBlanks(psz_parse+10, (unsigned)-1);
                 if( !strncasecmp( psz_parse, "HREF", 4 ) )
                 {
                     if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
@@ -353,7 +445,7 @@ static int Demux( demux_t *p_demux )
             }
             else if( !strncasecmp( psz_parse, "<EntryRef ", 10 ) )
             {
-                psz_parse+=10;
+                psz_parse = SkipBlanks(psz_parse+10, (unsigned)-1);
                 if( !strncasecmp( psz_parse, "HREF", 4 ) )
                 {
                     if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
@@ -363,15 +455,14 @@ static int Demux( demux_t *p_demux )
                         {
                             i_strlen = psz_parse-psz_backup;
                             if( i_strlen < 1 ) continue;
-                            psz_string = malloc( i_strlen*sizeof( char ) +1);
+                            psz_string = malloc( i_strlen +1);
                             memcpy( psz_string, psz_backup, i_strlen );
                             psz_string[i_strlen] = '\0';
-                            p_input = input_ItemNew( p_playlist, psz_string, psz_title_asx );
-                            input_ItemCopyOptions( p_current->p_input, p_input );
-                            playlist_BothAddInput( p_playlist, p_input,
-                                                   p_item_in_category,
-                                                   PLAYLIST_APPEND,
-                                                   PLAYLIST_END );
+                            input_item_t *p_input;
+                            p_input = input_item_New( p_demux, psz_string, psz_title_asx );
+                            input_item_CopyOptions( p_current_input, p_input );
+                            input_item_AddSubItem( p_current_input, p_input );
+                            vlc_gc_decref( p_input );
                             free( psz_string );
                         }
                         else continue;
@@ -384,6 +475,12 @@ static int Demux( demux_t *p_demux )
             }
             else if( !strncasecmp( psz_parse, "</Entry>", 8 ) )
             {
+                input_item_t *p_entry = NULL;
+                char *psz_name = NULL;
+
+                char * ppsz_options[2];
+                int i_options = 0;
+
                 /* add a new entry */
                 psz_parse+=8;
                 if( !b_entry )
@@ -391,17 +488,81 @@ static int Demux( demux_t *p_demux )
                     msg_Err( p_demux, "end of entry without start?" );
                     continue;
                 }
-                /* cleanup entry */
-                FREENULL( psz_title_entry )
-                FREENULL( psz_base_entry )
-                FREENULL( psz_artist_entry )
-                FREENULL( psz_copyright_entry )
-                FREENULL( psz_moreinfo_entry )
-                FREENULL( psz_abstract_entry )
-                b_entry = VLC_FALSE;
+
+                if( !psz_href )
+                {
+                    msg_Err( p_demux, "entry without href?" );
+                    continue;
+                }
+
+                if( p_sys->b_skip_ads && b_skip_entry )
+                {
+                    char *psz_current_input_name = input_item_GetName( p_current_input );
+
+                    msg_Dbg( p_demux, "skipped entry %d %s (%s)",
+                             i_entry_count,
+                             ( psz_title_entry ? psz_title_entry : psz_current_input_name ), psz_href );
+                    free( psz_current_input_name );
+                }
+                else
+                {
+                    if( i_starttime || i_duration )
+                    {
+                        if( i_starttime )
+                        {
+                            if( asprintf(ppsz_options+i_options, ":start-time=%d", i_starttime) == -1 )
+                                *(ppsz_options+i_options) = NULL;
+                            else
+                                ++i_options;
+                        }
+                        if( i_duration )
+                        {
+                            if( asprintf(ppsz_options+i_options, ":stop-time=%d", i_starttime + i_duration) == -1 )
+                                *(ppsz_options+i_options) = NULL;
+                            else
+                                ++i_options;
+                        }
+                    }
+
+                    /* create the new entry */
+                    char *psz_current_input_name = input_item_GetName( p_current_input );
+                    if( asprintf( &psz_name, "%d %s", i_entry_count, ( psz_title_entry ? psz_title_entry : psz_current_input_name ) ) != -1 )
+                    {
+                        p_entry = input_item_NewExt( p_demux, psz_href, psz_name,
+                                                     i_options, (const char * const *)ppsz_options, VLC_INPUT_OPTION_TRUSTED, -1 );
+                        free( psz_name );
+                        input_item_CopyOptions( p_current_input, p_entry );
+                        while( i_options )
+                        {
+                            psz_name = ppsz_options[--i_options];
+                            free( psz_name );
+                        }
+                        psz_name = NULL;
+
+                        if( psz_title_entry ) input_item_SetTitle( p_entry, psz_title_entry );
+                        if( psz_artist_entry ) input_item_SetArtist( p_entry, psz_artist_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_item_AddSubItem( p_current_input, p_entry );
+                        vlc_gc_decref( p_entry );
+                    }
+                    free( psz_current_input_name );
+                }
+
+                /* cleanup entry */;
+                FREENULL( psz_href );
+                FREENULL( psz_title_entry );
+                FREENULL( psz_base_entry );
+                FREENULL( psz_artist_entry );
+                FREENULL( psz_copyright_entry );
+                FREENULL( psz_moreinfo_entry );
+                FREENULL( psz_abstract_entry );
+                b_entry = false;
             }
             else if( !strncasecmp( psz_parse, "<Entry", 6 ) )
             {
+                char *psz_clientskip;
                 psz_parse+=6;
                 if( b_entry )
                 {
@@ -409,49 +570,108 @@ static int Demux( demux_t *p_demux )
                     continue;
                 }
                 i_entry_count += 1;
-                b_entry = VLC_TRUE;
+                b_entry = true;
+                psz_clientskip = strcasestr( psz_parse, "clientskip=\"no\"" );
                 psz_parse = strcasestr( psz_parse, ">" );
+
+                /* If clientskip was enabled ... this is an ad */
+                b_skip_entry = (NULL != psz_clientskip) && (psz_clientskip < psz_parse);
+
+                // init entry details
+                FREENULL(psz_href);
+                i_starttime = 0;
+                i_duration = 0;
             }
             else if( !strncasecmp( psz_parse, "<Ref ", 5 ) )
             {
-                psz_parse+=5;
+                psz_parse = SkipBlanks(psz_parse+5, (unsigned)-1);
                 if( !b_entry )
                 {
                     msg_Err( p_demux, "A ref outside an entry section" );
                     continue;
                 }
-                
+
                 if( !strncasecmp( psz_parse, "HREF", 4 ) )
                 {
                     if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
                     {
                         psz_backup = ++psz_parse;
+                        psz_backup = SkipBlanks(psz_backup, (unsigned)-1);
                         if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
                         {
-                            input_item_t *p_entry = NULL;
-                            char *psz_name = NULL;
+                            char *psz_tmp;
                             i_strlen = psz_parse-psz_backup;
                             if( i_strlen < 1 ) continue;
-                            psz_string = malloc( i_strlen*sizeof( char ) +1);
-                            memcpy( psz_string, psz_backup, i_strlen );
-                            psz_string[i_strlen] = '\0';
 
-                            /* create the new entry */
-                            asprintf( &psz_name, "%d %s", i_entry_count, ( psz_title_entry ? psz_title_entry : p_current->p_input->psz_name ) );
-                            p_entry = input_ItemNew( p_playlist, psz_string, psz_name );
-                            FREENULL( psz_name );
-                            
-                            input_ItemCopyOptions( p_current->p_input, p_entry );
-                            p_entry->p_meta = vlc_meta_New();
-                            if( psz_title_entry ) vlc_meta_SetTitle( p_entry->p_meta, psz_title_entry );
-                            if( psz_artist_entry ) vlc_meta_SetArtist( p_entry->p_meta, psz_artist_entry );
-                            if( psz_copyright_entry ) vlc_meta_SetCopyright( p_entry->p_meta, psz_copyright_entry );
-                            if( psz_moreinfo_entry ) vlc_meta_SetURL( p_entry->p_meta, psz_moreinfo_entry );
-                            if( psz_abstract_entry ) vlc_meta_SetDescription( p_entry->p_meta, psz_abstract_entry );
-                            playlist_BothAddInput( p_playlist, p_entry,
-                                                 p_item_in_category,
-                                                 PLAYLIST_APPEND, PLAYLIST_END);
-                            free( psz_string );
+                            free( psz_href );
+                            psz_href = malloc( i_strlen +1);
+                            memcpy( psz_href, psz_backup, i_strlen );
+                            psz_href[i_strlen] = '\0';
+                            psz_tmp = psz_href + (i_strlen-1);
+                            while( psz_tmp >= psz_href &&
+                                 ( *psz_tmp == '\r' || *psz_tmp == '\n' ) )
+                            {
+                                *psz_tmp = '\0';
+                                psz_tmp++;
+                            }
+                        }
+                        else continue;
+                    }
+                    else continue;
+                }
+                if( ( psz_parse = strcasestr( psz_parse, ">" ) ) )
+                    psz_parse++;
+                else continue;
+            }
+            else if( !strncasecmp( psz_parse, "<starttime ", 11 ) )
+            {
+                psz_parse = SkipBlanks(psz_parse+11, (unsigned)-1);
+                if( !b_entry )
+                {
+                    msg_Err( p_demux, "starttime outside an entry section" );
+                    continue;
+                }
+
+                if( !strncasecmp( psz_parse, "value", 5 ) )
+                {
+                    if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
+                    {
+                        psz_backup = ++psz_parse;
+                        if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
+                        {
+                            i_strlen = psz_parse-psz_backup;
+                            if( i_strlen < 1 ) continue;
+
+                            i_starttime = ParseTime(psz_backup, i_strlen);
+                        }
+                        else continue;
+                    }
+                    else continue;
+                }
+                if( ( psz_parse = strcasestr( psz_parse, ">" ) ) )
+                    psz_parse++;
+                else continue;
+            }
+            else if( !strncasecmp( psz_parse, "<duration ", 11 ) )
+            {
+                psz_parse = SkipBlanks(psz_parse+5, (unsigned)-1);
+                if( !b_entry )
+                {
+                    msg_Err( p_demux, "duration outside an entry section" );
+                    continue;
+                }
+
+                if( !strncasecmp( psz_parse, "value", 5 ) )
+                {
+                    if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
+                    {
+                        psz_backup = ++psz_parse;
+                        if( ( psz_parse = strcasestr( psz_parse, "\"" ) ) )
+                        {
+                            i_strlen = psz_parse-psz_backup;
+                            if( i_strlen < 1 ) continue;
+
+                            i_duration = ParseTime(psz_backup, i_strlen);
                         }
                         else continue;
                     }
@@ -463,14 +683,11 @@ static int Demux( demux_t *p_demux )
             }
             else if( !strncasecmp( psz_parse, "</ASX", 5 ) )
             {
-                vlc_mutex_lock( &p_current->p_input->lock );
-                if( !p_current->p_input->p_meta ) p_current->p_input->p_meta = vlc_meta_New();
-                if( psz_title_asx ) vlc_meta_SetTitle( p_current->p_input->p_meta, psz_title_asx );
-                if( psz_artist_asx ) vlc_meta_SetArtist( p_current->p_input->p_meta, psz_artist_asx );
-                if( psz_copyright_asx ) vlc_meta_SetCopyright( p_current->p_input->p_meta, psz_copyright_asx );
-                if( psz_moreinfo_asx ) vlc_meta_SetURL( p_current->p_input->p_meta, psz_moreinfo_asx );
-                if( psz_abstract_asx ) vlc_meta_SetDescription( p_current->p_input->p_meta, psz_abstract_asx );
-                vlc_mutex_unlock( &p_current->p_input->lock );
+                if( psz_title_asx ) input_item_SetTitle( p_current_input, psz_title_asx );
+                if( psz_artist_asx ) input_item_SetArtist( p_current_input, psz_artist_asx );
+                if( psz_copyright_asx ) input_item_SetCopyright( p_current_input, psz_copyright_asx );
+                if( psz_moreinfo_asx ) input_item_SetURL( p_current_input, psz_moreinfo_asx );
+                if( psz_abstract_asx ) input_item_SetDescription( p_current_input, psz_abstract_asx );
                 FREENULL( psz_base_asx );
                 FREENULL( psz_title_asx );
                 FREENULL( psz_artist_asx );
@@ -486,17 +703,16 @@ static int Demux( demux_t *p_demux )
             PARAM
             EVENT
             REPEAT
-            DURATION
             ENDMARK
             STARTMARK
-            STARTTIME
 #endif
     }
     HANDLE_PLAY_AND_RELEASE;
-    return VLC_SUCCESS;
+    return 0; /* Needed for correct operation of go back */
 }
 
 static int Control( demux_t *p_demux, int i_query, va_list args )
 {
+    VLC_UNUSED(p_demux); VLC_UNUSED(i_query); VLC_UNUSED(args);
     return VLC_EGENERIC;
 }