]> git.sesse.net Git - vlc/blobdiff - modules/access_output/shout.c
compat: fix use of <ctype.h> functions
[vlc] / modules / access_output / shout.c
index 1a8bad822b1ee9e74f82bde253adcfcee183d4be..1c0579b125296395e898a9e22c75c6d369102500 100644 (file)
@@ -49,6 +49,7 @@
 #include <vlc_plugin.h>
 #include <vlc_sout.h>
 #include <vlc_block.h>
+#include <vlc_url.h>
 
 #include <shout/shout.h>
 
@@ -113,26 +114,25 @@ vlc_module_begin ()
     set_category( CAT_SOUT )
     set_subcategory( SUBCAT_SOUT_ACO )
     add_shortcut( "shout" )
-    add_string( SOUT_CFG_PREFIX "name", "VLC media player - Live stream", NULL,
+    add_string( SOUT_CFG_PREFIX "name", "VLC media player - Live stream",
                 NAME_TEXT, NAME_LONGTEXT, false )
-    add_string( SOUT_CFG_PREFIX "description",
-                 "Live stream from VLC media player", NULL,
+    add_string( SOUT_CFG_PREFIX "description", "Live stream from VLC media player",
                 DESCRIPTION_TEXT, DESCRIPTION_LONGTEXT, false )
-    add_bool(   SOUT_CFG_PREFIX "mp3", false, NULL,
+    add_bool(   SOUT_CFG_PREFIX "mp3", false,
                 MP3_TEXT, MP3_LONGTEXT, true )
-    add_string( SOUT_CFG_PREFIX "genre", "Alternative", NULL,
+    add_string( SOUT_CFG_PREFIX "genre", "Alternative",
                 GENRE_TEXT, GENRE_LONGTEXT, false )
-    add_string( SOUT_CFG_PREFIX "url", "http://www.videolan.org/vlc", NULL,
+    add_string( SOUT_CFG_PREFIX "url", "http://www.videolan.org/vlc",
                 URL_TEXT, URL_LONGTEXT, false )
-    add_string( SOUT_CFG_PREFIX "bitrate", "", NULL,
+    add_string( SOUT_CFG_PREFIX "bitrate", "",
                 BITRATE_TEXT, BITRATE_LONGTEXT, false )
-    add_string( SOUT_CFG_PREFIX "samplerate", "", NULL,
+    add_string( SOUT_CFG_PREFIX "samplerate", "",
                 SAMPLERATE_TEXT, SAMPLERATE_LONGTEXT, false )
-    add_string( SOUT_CFG_PREFIX "channels", "", NULL,
+    add_string( SOUT_CFG_PREFIX "channels", "",
                 CHANNELS_TEXT, CHANNELS_LONGTEXT, false )
-    add_string( SOUT_CFG_PREFIX "quality", "", NULL,
+    add_string( SOUT_CFG_PREFIX "quality", "",
                 QUALITY_TEXT, QUALITY_LONGTEXT, false )
-    add_bool(   SOUT_CFG_PREFIX "public", false, NULL,
+    add_bool(   SOUT_CFG_PREFIX "public", false,
                 PUBLIC_TEXT, PUBLIC_LONGTEXT, true )
     set_callbacks( Open, Close )
 vlc_module_end ()
@@ -167,20 +167,13 @@ static int Open( vlc_object_t *p_this )
     sout_access_out_sys_t *p_sys;
     shout_t *p_shout;
     long i_ret;
-    unsigned int i_port;
     char *psz_val;
 
-    char *psz_accessname;
-    char *psz_parser;
-    const char *psz_user;
-    const char *psz_pass;
-    const char *psz_host;
-    const char *psz_mount;
-    const char *psz_port;
     char *psz_name;
     char *psz_description;
     char *psz_genre;
     char *psz_url;
+    vlc_url_t url;
 
     config_ChainParse( p_access, SOUT_CFG_PREFIX, ppsz_sout_options, p_access->p_cfg );
 
@@ -191,31 +184,14 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
-    psz_accessname = psz_parser = strdup( p_access->psz_path );
-    if( !psz_parser )
-        return VLC_ENOMEM;
-
-    /* Parse connection data user:pwd@host:port/mountpoint */
-    psz_user = psz_parser;
-    while( psz_parser[0] && psz_parser[0] != ':' ) psz_parser++;
-    if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; }
-    psz_pass = psz_parser;
-    while( psz_parser[0] && psz_parser[0] != '@' ) psz_parser++;
-    if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; }
-    psz_host = psz_parser;
-    while( psz_parser[0] && psz_parser[0] != ':' ) psz_parser++;
-    if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; }
-    psz_port = psz_parser;
-    while( psz_parser[0] && psz_parser[0] != '/' ) psz_parser++;
-    if( psz_parser[0] ) { psz_parser[0] = 0; psz_parser++; }
-    psz_mount = psz_parser;
-
-    i_port = atoi( psz_port );
+    vlc_UrlParse( &url , p_access->psz_path, 0 );
+    if( url.i_port <= 0 )
+        url.i_port = 8000;
 
     p_sys = p_access->p_sys = malloc( sizeof( sout_access_out_sys_t ) );
     if( !p_sys )
     {
-        free( psz_accessname );
+        vlc_UrlClean( &url );
         return VLC_ENOMEM;
     }
 
@@ -226,12 +202,12 @@ static int Open( vlc_object_t *p_this )
 
     p_shout = p_sys->p_shout = shout_new();
     if( !p_shout
-         || shout_set_host( p_shout, psz_host ) != SHOUTERR_SUCCESS
+         || shout_set_host( p_shout, url.psz_host ) != SHOUTERR_SUCCESS
          || shout_set_protocol( p_shout, SHOUT_PROTOCOL_ICY ) != SHOUTERR_SUCCESS
-         || shout_set_port( p_shout, i_port ) != SHOUTERR_SUCCESS
-         || shout_set_password( p_shout, psz_pass ) != SHOUTERR_SUCCESS
-         || shout_set_mount( p_shout, psz_mount ) != SHOUTERR_SUCCESS
-         || shout_set_user( p_shout, psz_user ) != SHOUTERR_SUCCESS
+         || shout_set_port( p_shout, url.i_port ) != SHOUTERR_SUCCESS
+         || shout_set_password( p_shout, url.psz_password ) != SHOUTERR_SUCCESS
+         || shout_set_mount( p_shout, url.psz_path ) != SHOUTERR_SUCCESS
+         || shout_set_user( p_shout, url.psz_username ) != SHOUTERR_SUCCESS
          || shout_set_agent( p_shout, "VLC media player " VERSION ) != SHOUTERR_SUCCESS
          || shout_set_name( p_shout, psz_name ) != SHOUTERR_SUCCESS
          || shout_set_description( p_shout, psz_description ) != SHOUTERR_SUCCESS
@@ -241,14 +217,13 @@ static int Open( vlc_object_t *p_this )
       )
     {
         msg_Err( p_access, "failed to initialize shout streaming to %s:%i/%s",
-                 psz_host, i_port, psz_mount );
-        free( p_access->p_sys );
-        free( psz_accessname );
+                 url.psz_host, url.i_port, url.psz_path );
+
         free( psz_name );
         free( psz_description );
         free( psz_genre );
         free( psz_url );
-        return VLC_EGENERIC;
+        goto error;
     }
 
     free( psz_name );
@@ -256,17 +231,13 @@ static int Open( vlc_object_t *p_this )
     free( psz_genre );
     free( psz_url );
 
-    if( var_GetBool( p_access, SOUT_CFG_PREFIX "mp3" ) )
-        i_ret = shout_set_format( p_shout, SHOUT_FORMAT_MP3 );
-    else
-        i_ret = shout_set_format( p_shout, SHOUT_FORMAT_OGG );
+    i_ret = shout_set_format( p_shout, var_GetBool( p_access, SOUT_CFG_PREFIX "mp3" ) ?
+                                       SHOUT_FORMAT_MP3 : SHOUT_FORMAT_OGG );
 
     if( i_ret != SHOUTERR_SUCCESS )
     {
         msg_Err( p_access, "failed to set the shoutcast streaming format" );
-        free( p_access->p_sys );
-        free( psz_accessname );
-        return VLC_EGENERIC;
+        goto error;
     }
 
     /* Don't force bitrate to 0 but only use when specified. This will otherwise
@@ -275,13 +246,11 @@ static int Open( vlc_object_t *p_this )
     if( psz_val )
     {
         i_ret = shout_set_audio_info( p_shout, SHOUT_AI_BITRATE, psz_val );
+        free( psz_val );
         if( i_ret != SHOUTERR_SUCCESS )
         {
             msg_Err( p_access, "failed to set the information about the bitrate" );
-            free( psz_val );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
     else
@@ -300,13 +269,11 @@ static int Open( vlc_object_t *p_this )
     if( psz_val )
     {
         i_ret = shout_set_audio_info( p_shout, SHOUT_AI_SAMPLERATE, psz_val );
+        free( psz_val );
         if( i_ret != SHOUTERR_SUCCESS )
         {
             msg_Err( p_access, "failed to set the information about the samplerate" );
-            free( psz_val );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
 
@@ -314,13 +281,11 @@ static int Open( vlc_object_t *p_this )
     if( psz_val )
     {
         i_ret = shout_set_audio_info( p_shout, SHOUT_AI_CHANNELS, psz_val );
+        free( psz_val );
         if( i_ret != SHOUTERR_SUCCESS )
         {
             msg_Err( p_access, "failed to set the information about the number of channels" );
-            free( psz_val );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
 
@@ -328,13 +293,11 @@ static int Open( vlc_object_t *p_this )
     if( psz_val )
     {
         i_ret = shout_set_audio_info( p_shout, SHOUT_AI_QUALITY, psz_val );
+        free( psz_val );
         if( i_ret != SHOUTERR_SUCCESS )
         {
             msg_Err( p_access, "failed to set the information about Ogg Vorbis quality" );
-            free( psz_val );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
 
@@ -344,9 +307,7 @@ static int Open( vlc_object_t *p_this )
         if( i_ret != SHOUTERR_SUCCESS )
         {
             msg_Err( p_access, "failed to set the server status setting to public" );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
     }
 
@@ -367,9 +328,7 @@ static int Open( vlc_object_t *p_this )
         if( i_ret != SHOUTERR_SUCCESS )
         {
             msg_Err( p_access, "failed to set the protocol to 'icy'" );
-            free( p_access->p_sys );
-            free( psz_accessname );
-            return VLC_EGENERIC;
+            goto error;
         }
         i_ret = shout_open( p_shout );
         if( i_ret == SHOUTERR_SUCCESS )
@@ -393,9 +352,7 @@ static int Open( vlc_object_t *p_this )
             if( i_ret != SHOUTERR_SUCCESS )
             {
                 msg_Err( p_access, "failed to set the protocol to 'http'" );
-                free( p_access->p_sys );
-                free( psz_accessname );
-                return VLC_EGENERIC;
+                goto error;
             }
             i_ret = shout_open( p_shout );
             if( i_ret == SHOUTERR_SUCCESS )
@@ -424,10 +381,8 @@ static int Open( vlc_object_t *p_this )
     if( i_ret != SHOUTERR_CONNECTED )
     {
         msg_Err( p_access, "failed to open shout stream to %s:%i/%s: %s",
-                 psz_host, i_port, psz_mount, shout_get_error(p_shout) );
-        free( p_access->p_sys );
-        free( psz_accessname );
-        return VLC_EGENERIC;
+                 url.psz_host, url.i_port, url.psz_path, shout_get_error(p_shout) );
+        goto error;
     }
 
     p_access->pf_write = Write;
@@ -435,10 +390,17 @@ static int Open( vlc_object_t *p_this )
     p_access->pf_control = Control;
 
     msg_Dbg( p_access, "shout access output opened (%s@%s:%i/%s)",
-             psz_user, psz_host, i_port, psz_mount );
-    free( psz_accessname );
+             url.psz_username, url.psz_host, url.i_port, url.psz_path );
 
+    vlc_UrlClean( &url );
     return VLC_SUCCESS;
+
+error:
+    if( p_sys->p_shout )
+        shout_free( p_sys->p_shout );
+    vlc_UrlClean( &url );
+    free( p_sys );
+    return VLC_EGENERIC;
 }
 
 /*****************************************************************************
@@ -447,13 +409,15 @@ static int Open( vlc_object_t *p_this )
 static void Close( vlc_object_t * p_this )
 {
     sout_access_out_t *p_access = (sout_access_out_t*)p_this;
+    sout_access_out_sys_t *p_sys = p_access->p_sys;
 
-    if( p_access->p_sys && p_access->p_sys->p_shout )
+    if( p_sys->p_shout )
     {
-        shout_close( p_access->p_sys->p_shout );
+        shout_close( p_sys->p_shout );
+        shout_free( p_sys->p_shout );
         shout_shutdown();
     }
-    free( p_access->p_sys );
+    free( p_sys );
     msg_Dbg( p_access, "shout access output closed" );
 }
 
@@ -479,15 +443,15 @@ static int Control( sout_access_out_t *p_access, int i_query, va_list args )
  *****************************************************************************/
 static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
 {
+    sout_access_out_sys_t *p_sys = p_access->p_sys;
     size_t i_write = 0;
 
-    shout_sync( p_access->p_sys->p_shout );
+    shout_sync( p_sys->p_shout );
     while( p_buffer )
     {
         block_t *p_next = p_buffer->p_next;
 
-        if( shout_send( p_access->p_sys->p_shout,
-                        p_buffer->p_buffer, p_buffer->i_buffer )
+        if( shout_send( p_sys->p_shout, p_buffer->p_buffer, p_buffer->i_buffer )
              == SHOUTERR_SUCCESS )
         {
             i_write += p_buffer->i_buffer;
@@ -495,24 +459,24 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
         else
         {
             msg_Err( p_access, "cannot write to stream: %s",
-                     shout_get_error(p_access->p_sys->p_shout) );
+                     shout_get_error( p_sys->p_shout ) );
 
             /* The most common cause seems to be a server disconnect, resulting in a
                Socket Error which can only be fixed by closing and reconnecting.
                Since we already began with a working connection, the most feasable
                approach to get out of this error status is a (timed) reconnect approach. */
-            shout_close( p_access->p_sys->p_shout );
+            shout_close( p_sys->p_shout );
             msg_Warn( p_access, "server unavailable? trying to reconnect..." );
             /* Re-open the connection (protocol params have already been set) and re-sync */
-            if( shout_open( p_access->p_sys->p_shout ) == SHOUTERR_SUCCESS )
+            if( shout_open( p_sys->p_shout ) == SHOUTERR_SUCCESS )
             {
-                shout_sync( p_access->p_sys->p_shout );
+                shout_sync( p_sys->p_shout );
                 msg_Warn( p_access, "reconnected to server" );
             }
             else
             {
                 msg_Err( p_access, "failed to reconnect to server" );
-                block_ChainRelease (p_buffer);
+                block_ChainRelease( p_buffer );
                 return VLC_EGENERIC;
             }